Message ID | 20200623113301.631-2-daniel.baluta@oss.nxp.com |
---|---|
State | Superseded |
Headers | show |
Series | Introduce multi PM domains helpers | expand |
Hi Daniel, I love your patch! Perhaps something to improve: [auto build test WARNING on pm/linux-next] [also build test WARNING on shawnguo/for-next linux/master linus/master v5.8-rc2 next-20200623] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Daniel-Baluta/Introduce-multi-PM-domains-helpers/20200623-193706 base: https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next config: i386-tinyconfig (attached as .config) compiler: gcc-9 (Debian 9.3.0-13) 9.3.0 reproduce (this is a W=1 build): # save the attached .config to linux build tree make W=1 ARCH=i386 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): In file included from drivers/base/platform.c:23: >> include/linux/pm_domain.h:395:34: warning: no previous prototype for 'dev_multi_pm_attach' [-Wmissing-prototypes] 395 | struct dev_multi_pm_domain_data *dev_multi_pm_attach(struct device *dev) | ^~~~~~~~~~~~~~~~~~~ >> include/linux/pm_domain.h:416:6: warning: no previous prototype for 'dev_multi_pm_detach' [-Wmissing-prototypes] 416 | void dev_multi_pm_detach(struct dev_multi_pm_domain_data *mpd) {} | ^~~~~~~~~~~~~~~~~~~ drivers/base/platform.c:1352:20: warning: no previous prototype for 'early_platform_cleanup' [-Wmissing-prototypes] 1352 | void __weak __init early_platform_cleanup(void) { } | ^~~~~~~~~~~~~~~~~~~~~~ vim +/dev_multi_pm_attach +395 include/linux/pm_domain.h 394 > 395 struct dev_multi_pm_domain_data *dev_multi_pm_attach(struct device *dev) 396 { 397 return NULL; 398 } 399 400 static inline struct device *dev_pm_domain_attach_by_id(struct device *dev, 401 unsigned int index) 402 { 403 return NULL; 404 } 405 static inline struct device *dev_pm_domain_attach_by_name(struct device *dev, 406 const char *name) 407 { 408 return NULL; 409 } 410 static inline void dev_pm_domain_detach(struct device *dev, bool power_off) {} 411 static inline int dev_pm_domain_start(struct device *dev) 412 { 413 return 0; 414 } 415 > 416 void dev_multi_pm_detach(struct dev_multi_pm_domain_data *mpd) {} 417 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi Daniel, I love your patch! Yet something to improve: [auto build test ERROR on pm/linux-next] [also build test ERROR on shawnguo/for-next linux/master linus/master v5.8-rc2 next-20200623] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Daniel-Baluta/Introduce-multi-PM-domains-helpers/20200623-193706 base: https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next config: mips-omega2p_defconfig (attached as .config) compiler: mipsel-linux-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=mips If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): mipsel-linux-ld: drivers/base/power/clock_ops.o: in function `dev_multi_pm_attach': >> clock_ops.c:(.text+0x16c): multiple definition of `dev_multi_pm_attach'; drivers/base/platform.o:platform.c:(.text+0x3ec): first defined here mipsel-linux-ld: drivers/base/power/clock_ops.o: in function `dev_multi_pm_detach': >> clock_ops.c:(.text+0x174): multiple definition of `dev_multi_pm_detach'; drivers/base/platform.o:platform.c:(.text+0x3f4): first defined here mipsel-linux-ld: drivers/mmc/core/sdio_bus.o: in function `dev_multi_pm_attach': sdio_bus.c:(.text+0x388): multiple definition of `dev_multi_pm_attach'; drivers/base/platform.o:platform.c:(.text+0x3ec): first defined here mipsel-linux-ld: drivers/mmc/core/sdio_bus.o: in function `dev_multi_pm_detach': sdio_bus.c:(.text+0x390): multiple definition of `dev_multi_pm_detach'; drivers/base/platform.o:platform.c:(.text+0x3f4): first defined here --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi Daniel, I love your patch! Perhaps something to improve: [auto build test WARNING on pm/linux-next] [also build test WARNING on shawnguo/for-next linux/master linus/master v5.8-rc2 next-20200623] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Daniel-Baluta/Introduce-multi-PM-domains-helpers/20200623-193706 base: https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next config: i386-randconfig-s001-20200623 (attached as .config) compiler: gcc-9 (Debian 9.3.0-13) 9.3.0 reproduce: # apt-get install sparse # sparse version: v0.6.2-dirty # save the attached .config to linux build tree make W=1 C=1 ARCH=i386 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> sparse warnings: (new ones prefixed by >>) >> drivers/base/power/common.c:260:33: sparse: sparse: incorrect type in argument 2 (different base types) @@ expected unsigned int [usertype] size @@ got restricted gfp_t @@ >> drivers/base/power/common.c:260:33: sparse: expected unsigned int [usertype] size >> drivers/base/power/common.c:260:33: sparse: got restricted gfp_t >> drivers/base/power/common.c:260:45: sparse: sparse: incorrect type in argument 3 (different base types) @@ expected restricted gfp_t [usertype] gfp @@ got unsigned int @@ >> drivers/base/power/common.c:260:45: sparse: expected restricted gfp_t [usertype] gfp >> drivers/base/power/common.c:260:45: sparse: got unsigned int vim +260 drivers/base/power/common.c 231 232 /** 233 * dev_multi_pm_attach - power up device associated power domains 234 * @dev: The device used to lookup the PM domains 235 * 236 * Parse device's OF node to find all PM domains specifiers. For each power 237 * domain found, create a virtual device and associate it with the 238 * current power domain. 239 * 240 * This function should typically be invoked by a driver during the 241 * probe phase, in the case its device requires power management through 242 * multiple PM domains. 243 * 244 * Returns a pointer to @dev_multi_pm_domain_data if successfully attached PM 245 * domains, NULL when the device doesn't need a PM domain or when single 246 * power-domains exists for it, else an ERR_PTR() in case of 247 * failures. 248 */ 249 struct dev_multi_pm_domain_data *dev_multi_pm_attach(struct device *dev) 250 { 251 struct dev_multi_pm_domain_data *mpd, *retp; 252 int num_domains; 253 int i; 254 255 num_domains = of_count_phandle_with_args(dev->of_node, "power-domains", 256 "#power-domain-cells"); 257 if (num_domains < 2) 258 return NULL; 259 > 260 mpd = devm_kzalloc(dev, GFP_KERNEL, sizeof(*mpd)); 261 if (!mpd) 262 return ERR_PTR(-ENOMEM); 263 264 mpd->dev = dev; 265 mpd->num_domains = num_domains; 266 267 mpd->virt_devs = devm_kmalloc_array(dev, mpd->num_domains, 268 sizeof(*mpd->virt_devs), 269 GFP_KERNEL); 270 if (!mpd->virt_devs) 271 return ERR_PTR(-ENOMEM); 272 273 mpd->links = devm_kmalloc_array(dev, mpd->num_domains, 274 sizeof(*mpd->links), GFP_KERNEL); 275 if (!mpd->links) 276 return ERR_PTR(-ENOMEM); 277 278 for (i = 0; i < mpd->num_domains; i++) { 279 mpd->virt_devs[i] = dev_pm_domain_attach_by_id(dev, i); 280 if (IS_ERR(mpd->virt_devs[i])) { 281 retp = (struct dev_multi_pm_domain_data *) 282 mpd->virt_devs[i]; 283 goto exit_unroll_pm; 284 } 285 mpd->links[i] = device_link_add(dev, mpd->virt_devs[i], 286 DL_FLAG_STATELESS | 287 DL_FLAG_PM_RUNTIME | 288 DL_FLAG_RPM_ACTIVE); 289 if (!mpd->links[i]) { 290 retp = ERR_PTR(-ENOMEM); 291 dev_pm_domain_detach(mpd->virt_devs[i], false); 292 goto exit_unroll_pm; 293 } 294 } 295 return mpd; 296 297 exit_unroll_pm: 298 while (--i >= 0) { 299 device_link_del(mpd->links[i]); 300 dev_pm_domain_detach(mpd->virt_devs[i], false); 301 } 302 303 return retp; 304 } 305 EXPORT_SYMBOL(dev_multi_pm_attach); 306 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi Daniel, I love your patch! Perhaps something to improve: [auto build test WARNING on pm/linux-next] [also build test WARNING on shawnguo/for-next linux/master linus/master v5.8-rc2 next-20200623] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Daniel-Baluta/Introduce-multi-PM-domains-helpers/20200623-193706 base: https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git linux-next config: x86_64-randconfig-s022-20200623 (attached as .config) compiler: gcc-9 (Debian 9.3.0-13) 9.3.0 reproduce: # apt-get install sparse # sparse version: v0.6.2-dirty # save the attached .config to linux build tree make W=1 C=1 ARCH=x86_64 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> sparse warnings: (new ones prefixed by >>) >> drivers/base/power/common.c:260:33: sparse: sparse: incorrect type in argument 2 (different base types) @@ expected unsigned long [usertype] size @@ got restricted gfp_t @@ >> drivers/base/power/common.c:260:33: sparse: expected unsigned long [usertype] size drivers/base/power/common.c:260:33: sparse: got restricted gfp_t >> drivers/base/power/common.c:260:45: sparse: sparse: incorrect type in argument 3 (different base types) @@ expected restricted gfp_t [usertype] gfp @@ got unsigned long @@ drivers/base/power/common.c:260:45: sparse: expected restricted gfp_t [usertype] gfp >> drivers/base/power/common.c:260:45: sparse: got unsigned long vim +260 drivers/base/power/common.c 231 232 /** 233 * dev_multi_pm_attach - power up device associated power domains 234 * @dev: The device used to lookup the PM domains 235 * 236 * Parse device's OF node to find all PM domains specifiers. For each power 237 * domain found, create a virtual device and associate it with the 238 * current power domain. 239 * 240 * This function should typically be invoked by a driver during the 241 * probe phase, in the case its device requires power management through 242 * multiple PM domains. 243 * 244 * Returns a pointer to @dev_multi_pm_domain_data if successfully attached PM 245 * domains, NULL when the device doesn't need a PM domain or when single 246 * power-domains exists for it, else an ERR_PTR() in case of 247 * failures. 248 */ 249 struct dev_multi_pm_domain_data *dev_multi_pm_attach(struct device *dev) 250 { 251 struct dev_multi_pm_domain_data *mpd, *retp; 252 int num_domains; 253 int i; 254 255 num_domains = of_count_phandle_with_args(dev->of_node, "power-domains", 256 "#power-domain-cells"); 257 if (num_domains < 2) 258 return NULL; 259 > 260 mpd = devm_kzalloc(dev, GFP_KERNEL, sizeof(*mpd)); 261 if (!mpd) 262 return ERR_PTR(-ENOMEM); 263 264 mpd->dev = dev; 265 mpd->num_domains = num_domains; 266 267 mpd->virt_devs = devm_kmalloc_array(dev, mpd->num_domains, 268 sizeof(*mpd->virt_devs), 269 GFP_KERNEL); 270 if (!mpd->virt_devs) 271 return ERR_PTR(-ENOMEM); 272 273 mpd->links = devm_kmalloc_array(dev, mpd->num_domains, 274 sizeof(*mpd->links), GFP_KERNEL); 275 if (!mpd->links) 276 return ERR_PTR(-ENOMEM); 277 278 for (i = 0; i < mpd->num_domains; i++) { 279 mpd->virt_devs[i] = dev_pm_domain_attach_by_id(dev, i); 280 if (IS_ERR(mpd->virt_devs[i])) { 281 retp = (struct dev_multi_pm_domain_data *) 282 mpd->virt_devs[i]; 283 goto exit_unroll_pm; 284 } 285 mpd->links[i] = device_link_add(dev, mpd->virt_devs[i], 286 DL_FLAG_STATELESS | 287 DL_FLAG_PM_RUNTIME | 288 DL_FLAG_RPM_ACTIVE); 289 if (!mpd->links[i]) { 290 retp = ERR_PTR(-ENOMEM); 291 dev_pm_domain_detach(mpd->virt_devs[i], false); 292 goto exit_unroll_pm; 293 } 294 } 295 return mpd; 296 297 exit_unroll_pm: 298 while (--i >= 0) { 299 device_link_del(mpd->links[i]); 300 dev_pm_domain_detach(mpd->virt_devs[i], false); 301 } 302 303 return retp; 304 } 305 EXPORT_SYMBOL(dev_multi_pm_attach); 306 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c index bbddb267c2e6..6d1f142833b1 100644 --- a/drivers/base/power/common.c +++ b/drivers/base/power/common.c @@ -228,3 +228,96 @@ void dev_pm_domain_set(struct device *dev, struct dev_pm_domain *pd) device_pm_check_callbacks(dev); } EXPORT_SYMBOL_GPL(dev_pm_domain_set); + +/** + * dev_multi_pm_attach - power up device associated power domains + * @dev: The device used to lookup the PM domains + * + * Parse device's OF node to find all PM domains specifiers. For each power + * domain found, create a virtual device and associate it with the + * current power domain. + * + * This function should typically be invoked by a driver during the + * probe phase, in the case its device requires power management through + * multiple PM domains. + * + * Returns a pointer to @dev_multi_pm_domain_data if successfully attached PM + * domains, NULL when the device doesn't need a PM domain or when single + * power-domains exists for it, else an ERR_PTR() in case of + * failures. + */ +struct dev_multi_pm_domain_data *dev_multi_pm_attach(struct device *dev) +{ + struct dev_multi_pm_domain_data *mpd, *retp; + int num_domains; + int i; + + num_domains = of_count_phandle_with_args(dev->of_node, "power-domains", + "#power-domain-cells"); + if (num_domains < 2) + return NULL; + + mpd = devm_kzalloc(dev, GFP_KERNEL, sizeof(*mpd)); + if (!mpd) + return ERR_PTR(-ENOMEM); + + mpd->dev = dev; + mpd->num_domains = num_domains; + + mpd->virt_devs = devm_kmalloc_array(dev, mpd->num_domains, + sizeof(*mpd->virt_devs), + GFP_KERNEL); + if (!mpd->virt_devs) + return ERR_PTR(-ENOMEM); + + mpd->links = devm_kmalloc_array(dev, mpd->num_domains, + sizeof(*mpd->links), GFP_KERNEL); + if (!mpd->links) + return ERR_PTR(-ENOMEM); + + for (i = 0; i < mpd->num_domains; i++) { + mpd->virt_devs[i] = dev_pm_domain_attach_by_id(dev, i); + if (IS_ERR(mpd->virt_devs[i])) { + retp = (struct dev_multi_pm_domain_data *) + mpd->virt_devs[i]; + goto exit_unroll_pm; + } + mpd->links[i] = device_link_add(dev, mpd->virt_devs[i], + DL_FLAG_STATELESS | + DL_FLAG_PM_RUNTIME | + DL_FLAG_RPM_ACTIVE); + if (!mpd->links[i]) { + retp = ERR_PTR(-ENOMEM); + dev_pm_domain_detach(mpd->virt_devs[i], false); + goto exit_unroll_pm; + } + } + return mpd; + +exit_unroll_pm: + while (--i >= 0) { + device_link_del(mpd->links[i]); + dev_pm_domain_detach(mpd->virt_devs[i], false); + } + + return retp; +} +EXPORT_SYMBOL(dev_multi_pm_attach); + +/** + * dev_multi_pm_detach - Detach a device from its PM domains. + * Each multi power domain is attached to a virtual children device + * + * @mpd: multi power domains data, contains the association between + * virtul device and PM domain + */ +void dev_multi_pm_detach(struct dev_multi_pm_domain_data *mpd) +{ + int i; + + for (i = 0; i < mpd->num_domains; i++) { + device_link_del(mpd->links[i]); + dev_pm_domain_detach(mpd->virt_devs[i], false); + } +} +EXPORT_SYMBOL(dev_multi_pm_detach); diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index 9ec78ee53652..5bcb35150af2 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -183,6 +183,13 @@ struct generic_pm_domain_data { void *data; }; +struct dev_multi_pm_domain_data { + struct device *dev; /* parent device */ + struct device **virt_devs; /* virtual children links */ + struct device_link **links; /* links parent <-> virtual children */ + int num_domains; +}; + #ifdef CONFIG_PM_GENERIC_DOMAINS static inline struct generic_pm_domain_data *to_gpd_data(struct pm_domain_data *pdd) { @@ -369,18 +376,27 @@ struct generic_pm_domain *of_genpd_remove_last(struct device_node *np) #ifdef CONFIG_PM int dev_pm_domain_attach(struct device *dev, bool power_on); +struct dev_multi_pm_domain_data *dev_multi_pm_attach(struct device *dev); struct device *dev_pm_domain_attach_by_id(struct device *dev, unsigned int index); struct device *dev_pm_domain_attach_by_name(struct device *dev, const char *name); void dev_pm_domain_detach(struct device *dev, bool power_off); int dev_pm_domain_start(struct device *dev); +void dev_multi_pm_detach(struct dev_multi_pm_domain_data *mpd); void dev_pm_domain_set(struct device *dev, struct dev_pm_domain *pd); + #else static inline int dev_pm_domain_attach(struct device *dev, bool power_on) { return 0; } + +struct dev_multi_pm_domain_data *dev_multi_pm_attach(struct device *dev) +{ + return NULL; +} + static inline struct device *dev_pm_domain_attach_by_id(struct device *dev, unsigned int index) { @@ -396,6 +412,9 @@ static inline int dev_pm_domain_start(struct device *dev) { return 0; } + +void dev_multi_pm_detach(struct dev_multi_pm_domain_data *mpd) {} + static inline void dev_pm_domain_set(struct device *dev, struct dev_pm_domain *pd) {} #endif