Message ID | 20220816082757.11990-9-farbere@amazon.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Variety of fixes and new features for mr75203 driver | expand |
Hi Eliav, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on groeck-staging/hwmon-next] [also build test WARNING on linus/master v6.0-rc1 next-20220816] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Eliav-Farber/Variety-of-fixes-and-new-features-for-mr75203-driver/20220816-183655 base: https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next config: powerpc-randconfig-r024-20220815 (https://download.01.org/0day-ci/archive/20220817/202208170047.kXOyBIXA-lkp@intel.com/config) compiler: clang version 16.0.0 (https://github.com/llvm/llvm-project aed5e3bea138ce581d682158eb61c27b3cfdd6ec) 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 # install powerpc cross compiling tool for clang build # apt-get install binutils-powerpc-linux-gnu # https://github.com/intel-lab-lkp/linux/commit/75e49737eb6188733096da72eb4692cfed872101 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Eliav-Farber/Variety-of-fixes-and-new-features-for-mr75203-driver/20220816-183655 git checkout 75e49737eb6188733096da72eb4692cfed872101 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=powerpc SHELL=/bin/bash drivers/hwmon/ If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): In file included from include/linux/iopoll.h:14: In file included from include/linux/io.h:13: In file included from arch/powerpc/include/asm/io.h:640: arch/powerpc/include/asm/io-defs.h:43:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] DEF_PCI_AC_NORET(insb, (unsigned long p, void *b, unsigned long c), ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/io.h:637:3: note: expanded from macro 'DEF_PCI_AC_NORET' __do_##name al; \ ^~~~~~~~~~~~~~ <scratch space>:178:1: note: expanded from here __do_insb ^ arch/powerpc/include/asm/io.h:577:56: note: expanded from macro '__do_insb' #define __do_insb(p, b, n) readsb((PCI_IO_ADDR)_IO_BASE+(p), (b), (n)) ~~~~~~~~~~~~~~~~~~~~~^ In file included from drivers/hwmon/mr75203.c:19: In file included from include/linux/regmap.h:20: In file included from include/linux/iopoll.h:14: In file included from include/linux/io.h:13: In file included from arch/powerpc/include/asm/io.h:640: arch/powerpc/include/asm/io-defs.h:45:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] DEF_PCI_AC_NORET(insw, (unsigned long p, void *b, unsigned long c), ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/io.h:637:3: note: expanded from macro 'DEF_PCI_AC_NORET' __do_##name al; \ ^~~~~~~~~~~~~~ <scratch space>:180:1: note: expanded from here __do_insw ^ arch/powerpc/include/asm/io.h:578:56: note: expanded from macro '__do_insw' #define __do_insw(p, b, n) readsw((PCI_IO_ADDR)_IO_BASE+(p), (b), (n)) ~~~~~~~~~~~~~~~~~~~~~^ In file included from drivers/hwmon/mr75203.c:19: In file included from include/linux/regmap.h:20: In file included from include/linux/iopoll.h:14: In file included from include/linux/io.h:13: In file included from arch/powerpc/include/asm/io.h:640: arch/powerpc/include/asm/io-defs.h:47:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] DEF_PCI_AC_NORET(insl, (unsigned long p, void *b, unsigned long c), ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/io.h:637:3: note: expanded from macro 'DEF_PCI_AC_NORET' __do_##name al; \ ^~~~~~~~~~~~~~ <scratch space>:182:1: note: expanded from here __do_insl ^ arch/powerpc/include/asm/io.h:579:56: note: expanded from macro '__do_insl' #define __do_insl(p, b, n) readsl((PCI_IO_ADDR)_IO_BASE+(p), (b), (n)) ~~~~~~~~~~~~~~~~~~~~~^ In file included from drivers/hwmon/mr75203.c:19: In file included from include/linux/regmap.h:20: In file included from include/linux/iopoll.h:14: In file included from include/linux/io.h:13: In file included from arch/powerpc/include/asm/io.h:640: arch/powerpc/include/asm/io-defs.h:49:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] DEF_PCI_AC_NORET(outsb, (unsigned long p, const void *b, unsigned long c), ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/io.h:637:3: note: expanded from macro 'DEF_PCI_AC_NORET' __do_##name al; \ ^~~~~~~~~~~~~~ <scratch space>:184:1: note: expanded from here __do_outsb ^ arch/powerpc/include/asm/io.h:580:58: note: expanded from macro '__do_outsb' #define __do_outsb(p, b, n) writesb((PCI_IO_ADDR)_IO_BASE+(p),(b),(n)) ~~~~~~~~~~~~~~~~~~~~~^ In file included from drivers/hwmon/mr75203.c:19: In file included from include/linux/regmap.h:20: In file included from include/linux/iopoll.h:14: In file included from include/linux/io.h:13: In file included from arch/powerpc/include/asm/io.h:640: arch/powerpc/include/asm/io-defs.h:51:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] DEF_PCI_AC_NORET(outsw, (unsigned long p, const void *b, unsigned long c), ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/io.h:637:3: note: expanded from macro 'DEF_PCI_AC_NORET' __do_##name al; \ ^~~~~~~~~~~~~~ <scratch space>:186:1: note: expanded from here __do_outsw ^ arch/powerpc/include/asm/io.h:581:58: note: expanded from macro '__do_outsw' #define __do_outsw(p, b, n) writesw((PCI_IO_ADDR)_IO_BASE+(p),(b),(n)) ~~~~~~~~~~~~~~~~~~~~~^ In file included from drivers/hwmon/mr75203.c:19: In file included from include/linux/regmap.h:20: In file included from include/linux/iopoll.h:14: In file included from include/linux/io.h:13: In file included from arch/powerpc/include/asm/io.h:640: arch/powerpc/include/asm/io-defs.h:53:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic] DEF_PCI_AC_NORET(outsl, (unsigned long p, const void *b, unsigned long c), ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/powerpc/include/asm/io.h:637:3: note: expanded from macro 'DEF_PCI_AC_NORET' __do_##name al; \ ^~~~~~~~~~~~~~ <scratch space>:188:1: note: expanded from here __do_outsl ^ arch/powerpc/include/asm/io.h:582:58: note: expanded from macro '__do_outsl' #define __do_outsl(p, b, n) writesl((PCI_IO_ADDR)_IO_BASE+(p),(b),(n)) ~~~~~~~~~~~~~~~~~~~~~^ >> drivers/hwmon/mr75203.c:604:13: warning: variable length array used [-Wvla] u8 vm_idx[vm_num]; ^~~~~~ drivers/hwmon/mr75203.c:605:19: warning: variable length array used [-Wvla] u8 vm_active_ch[vm_num]; ^~~~~~ 8 warnings generated. Kconfig warnings: (for reference only) WARNING: unmet direct dependencies detected for HOTPLUG_CPU Depends on [n]: SMP [=y] && (PPC_PSERIES [=n] || PPC_PMAC [=n] || PPC_POWERNV [=n] || FSL_SOC_BOOKE [=n]) Selected by [y]: - PM_SLEEP_SMP [=y] && SMP [=y] && (ARCH_SUSPEND_POSSIBLE [=y] || ARCH_HIBERNATION_POSSIBLE [=y]) && PM_SLEEP [=y] vim +604 drivers/hwmon/mr75203.c 514 515 static int mr75203_probe(struct platform_device *pdev) 516 { 517 const struct hwmon_channel_info **pvt_info; 518 u32 ts_num, vm_num, pd_num, ch_num, val, index, i, j, k; 519 struct device *dev = &pdev->dev; 520 u32 *temp_config, *in_config; 521 struct device *hwmon_dev; 522 struct pvt_device *pvt; 523 int ret; 524 525 pvt = devm_kzalloc(dev, sizeof(*pvt), GFP_KERNEL); 526 if (!pvt) 527 return -ENOMEM; 528 529 ret = pvt_get_regmap(pdev, "common", pvt); 530 if (ret) 531 return ret; 532 533 pvt->clk = devm_clk_get(dev, NULL); 534 if (IS_ERR(pvt->clk)) 535 return dev_err_probe(dev, PTR_ERR(pvt->clk), "failed to get clock\n"); 536 537 ret = pvt_clk_enable(dev, pvt); 538 if (ret) { 539 dev_err(dev, "failed to enable clock\n"); 540 return ret; 541 } 542 543 if (of_property_read_bool(dev->of_node, "reset-control-skip")) { 544 dev_info(dev, "skipping reset-control\n"); 545 } else { 546 pvt->rst = devm_reset_control_get_exclusive(dev, NULL); 547 if (IS_ERR(pvt->rst)) 548 return dev_err_probe(dev, PTR_ERR(pvt->rst), 549 "failed to get reset control\n"); 550 551 ret = pvt_reset_control_deassert(dev, pvt); 552 if (ret) 553 return dev_err_probe(dev, ret, 554 "cannot deassert reset control\n"); 555 } 556 557 ret = regmap_read(pvt->c_map, PVT_IP_CONFIG, &val); 558 if(ret < 0) 559 return ret; 560 561 ts_num = (val & TS_NUM_MSK) >> TS_NUM_SFT; 562 pd_num = (val & PD_NUM_MSK) >> PD_NUM_SFT; 563 vm_num = (val & VM_NUM_MSK) >> VM_NUM_SFT; 564 ch_num = (val & CH_NUM_MSK) >> CH_NUM_SFT; 565 pvt->t_num = ts_num; 566 pvt->p_num = pd_num; 567 pvt->v_num = vm_num; 568 val = 0; 569 if (ts_num) 570 val++; 571 if (vm_num) 572 val++; 573 if (!val) 574 return -ENODEV; 575 576 pvt_info = devm_kcalloc(dev, val + 2, sizeof(*pvt_info), GFP_KERNEL); 577 if (!pvt_info) 578 return -ENOMEM; 579 pvt_info[0] = HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ); 580 index = 1; 581 582 if (ts_num) { 583 ret = pvt_get_regmap(pdev, "ts", pvt); 584 if (ret) 585 return ret; 586 587 temp_config = devm_kcalloc(dev, ts_num + 1, 588 sizeof(*temp_config), GFP_KERNEL); 589 if (!temp_config) 590 return -ENOMEM; 591 592 memset32(temp_config, HWMON_T_INPUT, ts_num); 593 pvt_temp.config = temp_config; 594 pvt_info[index++] = &pvt_temp; 595 } 596 597 if (pd_num) { 598 ret = pvt_get_regmap(pdev, "pd", pvt); 599 if (ret) 600 return ret; 601 } 602 603 if (vm_num) { > 604 u8 vm_idx[vm_num]; 605 u8 vm_active_ch[vm_num]; 606 607 ret = pvt_get_regmap(pdev, "vm", pvt); 608 if (ret) 609 return ret; 610 611 ret = device_property_read_u8_array(dev, "intel,vm-map", vm_idx, 612 vm_num); 613 if (ret) { 614 /* 615 * Incase intel,vm-map property is not defined, we 616 * assume incremental channel numbers. 617 */ 618 for (i = 0; i < vm_num; i++) 619 vm_idx[i] = i; 620 } else { 621 for (i = 0; i < vm_num; i++) 622 if (vm_idx[i] >= vm_num || vm_idx[i] == 0xff) 623 break; 624 625 vm_num = i; 626 pvt->v_num = i; 627 } 628 629 ret = device_property_read_u8_array(dev, "vm-active-channels", 630 vm_active_ch, vm_num); 631 if (ret) { 632 /* 633 * Incase vm-active-channels property is not defined, 634 * we assume each VM sensor has all of its channels 635 * active. 636 */ 637 for (i = 0; i < vm_num; i++) 638 vm_active_ch[i] = ch_num; 639 640 pvt->vm_ch_max = ch_num; 641 pvt->vm_ch_total = ch_num * vm_num; 642 } else { 643 for (i = 0; i < vm_num; i++) { 644 if (vm_active_ch[i] > ch_num) { 645 dev_err(dev, 646 "invalid active channels: %u\n", 647 vm_active_ch[i]); 648 return -EINVAL; 649 } 650 651 pvt->vm_ch_total += vm_active_ch[i]; 652 653 if (vm_active_ch[i] > pvt->vm_ch_max) 654 pvt->vm_ch_max = vm_active_ch[i]; 655 } 656 } 657 658 /* 659 * Map between the channel-number to VM-index and channel-index. 660 * Example - 3 VMs, vm_active_ch = [05 02 04]: 661 * vm_map = [0 0 0 0 0 1 1 2 2 2 2] 662 * ch_map = [0 1 2 3 4 0 1 0 1 2 3] 663 */ 664 pvt->vd = devm_kcalloc(dev, pvt->vm_ch_total, sizeof(*pvt->vd), 665 GFP_KERNEL); 666 if (!pvt->vd) 667 return -ENOMEM; 668 669 k = 0; 670 for (i = 0; i < vm_num; i++) 671 for (j = 0; j < vm_active_ch[i]; j++) { 672 pvt->vd[k].vm_map = vm_idx[i]; 673 pvt->vd[k].ch_map = j; 674 k++; 675 } 676 677 in_config = devm_kcalloc(dev, pvt->vm_ch_total + 1, 678 sizeof(*in_config), GFP_KERNEL); 679 if (!in_config) 680 return -ENOMEM; 681 682 memset32(in_config, HWMON_I_INPUT, pvt->vm_ch_total); 683 in_config[pvt->vm_ch_total] = 0; 684 pvt_in.config = in_config; 685 686 pvt_info[index++] = &pvt_in; 687 } 688 689 ret = pvt_init(pvt); 690 if (ret) { 691 dev_err(dev, "failed to init pvt: %d\n", ret); 692 return ret; 693 } 694 695 pvt_chip_info.info = pvt_info; 696 hwmon_dev = devm_hwmon_device_register_with_info(dev, "pvt", 697 pvt, 698 &pvt_chip_info, 699 NULL); 700 701 return PTR_ERR_OR_ZERO(hwmon_dev); 702 } 703
Hi Eliav, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on groeck-staging/hwmon-next] [also build test WARNING on linus/master v6.0-rc1 next-20220816] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Eliav-Farber/Variety-of-fixes-and-new-features-for-mr75203-driver/20220816-183655 base: https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next config: powerpc-randconfig-s031-20220816 (https://download.01.org/0day-ci/archive/20220817/202208170228.YsVOxCg7-lkp@intel.com/config) compiler: powerpc-linux-gcc (GCC) 12.1.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # apt-get install sparse # sparse version: v0.6.4-39-gce1a6720-dirty # https://github.com/intel-lab-lkp/linux/commit/75e49737eb6188733096da72eb4692cfed872101 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Eliav-Farber/Variety-of-fixes-and-new-features-for-mr75203-driver/20220816-183655 git checkout 75e49737eb6188733096da72eb4692cfed872101 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=powerpc SHELL=/bin/bash drivers/hwmon/ If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot <lkp@intel.com> sparse warnings: (new ones prefixed by >>) >> drivers/hwmon/mr75203.c:604:27: sparse: sparse: Variable length array is used. drivers/hwmon/mr75203.c:605:33: sparse: sparse: Variable length array is used. vim +604 drivers/hwmon/mr75203.c 514 515 static int mr75203_probe(struct platform_device *pdev) 516 { 517 const struct hwmon_channel_info **pvt_info; 518 u32 ts_num, vm_num, pd_num, ch_num, val, index, i, j, k; 519 struct device *dev = &pdev->dev; 520 u32 *temp_config, *in_config; 521 struct device *hwmon_dev; 522 struct pvt_device *pvt; 523 int ret; 524 525 pvt = devm_kzalloc(dev, sizeof(*pvt), GFP_KERNEL); 526 if (!pvt) 527 return -ENOMEM; 528 529 ret = pvt_get_regmap(pdev, "common", pvt); 530 if (ret) 531 return ret; 532 533 pvt->clk = devm_clk_get(dev, NULL); 534 if (IS_ERR(pvt->clk)) 535 return dev_err_probe(dev, PTR_ERR(pvt->clk), "failed to get clock\n"); 536 537 ret = pvt_clk_enable(dev, pvt); 538 if (ret) { 539 dev_err(dev, "failed to enable clock\n"); 540 return ret; 541 } 542 543 if (of_property_read_bool(dev->of_node, "reset-control-skip")) { 544 dev_info(dev, "skipping reset-control\n"); 545 } else { 546 pvt->rst = devm_reset_control_get_exclusive(dev, NULL); 547 if (IS_ERR(pvt->rst)) 548 return dev_err_probe(dev, PTR_ERR(pvt->rst), 549 "failed to get reset control\n"); 550 551 ret = pvt_reset_control_deassert(dev, pvt); 552 if (ret) 553 return dev_err_probe(dev, ret, 554 "cannot deassert reset control\n"); 555 } 556 557 ret = regmap_read(pvt->c_map, PVT_IP_CONFIG, &val); 558 if(ret < 0) 559 return ret; 560 561 ts_num = (val & TS_NUM_MSK) >> TS_NUM_SFT; 562 pd_num = (val & PD_NUM_MSK) >> PD_NUM_SFT; 563 vm_num = (val & VM_NUM_MSK) >> VM_NUM_SFT; 564 ch_num = (val & CH_NUM_MSK) >> CH_NUM_SFT; 565 pvt->t_num = ts_num; 566 pvt->p_num = pd_num; 567 pvt->v_num = vm_num; 568 val = 0; 569 if (ts_num) 570 val++; 571 if (vm_num) 572 val++; 573 if (!val) 574 return -ENODEV; 575 576 pvt_info = devm_kcalloc(dev, val + 2, sizeof(*pvt_info), GFP_KERNEL); 577 if (!pvt_info) 578 return -ENOMEM; 579 pvt_info[0] = HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ); 580 index = 1; 581 582 if (ts_num) { 583 ret = pvt_get_regmap(pdev, "ts", pvt); 584 if (ret) 585 return ret; 586 587 temp_config = devm_kcalloc(dev, ts_num + 1, 588 sizeof(*temp_config), GFP_KERNEL); 589 if (!temp_config) 590 return -ENOMEM; 591 592 memset32(temp_config, HWMON_T_INPUT, ts_num); 593 pvt_temp.config = temp_config; 594 pvt_info[index++] = &pvt_temp; 595 } 596 597 if (pd_num) { 598 ret = pvt_get_regmap(pdev, "pd", pvt); 599 if (ret) 600 return ret; 601 } 602 603 if (vm_num) { > 604 u8 vm_idx[vm_num]; 605 u8 vm_active_ch[vm_num]; 606 607 ret = pvt_get_regmap(pdev, "vm", pvt); 608 if (ret) 609 return ret; 610 611 ret = device_property_read_u8_array(dev, "intel,vm-map", vm_idx, 612 vm_num); 613 if (ret) { 614 /* 615 * Incase intel,vm-map property is not defined, we 616 * assume incremental channel numbers. 617 */ 618 for (i = 0; i < vm_num; i++) 619 vm_idx[i] = i; 620 } else { 621 for (i = 0; i < vm_num; i++) 622 if (vm_idx[i] >= vm_num || vm_idx[i] == 0xff) 623 break; 624 625 vm_num = i; 626 pvt->v_num = i; 627 } 628 629 ret = device_property_read_u8_array(dev, "vm-active-channels", 630 vm_active_ch, vm_num); 631 if (ret) { 632 /* 633 * Incase vm-active-channels property is not defined, 634 * we assume each VM sensor has all of its channels 635 * active. 636 */ 637 for (i = 0; i < vm_num; i++) 638 vm_active_ch[i] = ch_num; 639 640 pvt->vm_ch_max = ch_num; 641 pvt->vm_ch_total = ch_num * vm_num; 642 } else { 643 for (i = 0; i < vm_num; i++) { 644 if (vm_active_ch[i] > ch_num) { 645 dev_err(dev, 646 "invalid active channels: %u\n", 647 vm_active_ch[i]); 648 return -EINVAL; 649 } 650 651 pvt->vm_ch_total += vm_active_ch[i]; 652 653 if (vm_active_ch[i] > pvt->vm_ch_max) 654 pvt->vm_ch_max = vm_active_ch[i]; 655 } 656 } 657 658 /* 659 * Map between the channel-number to VM-index and channel-index. 660 * Example - 3 VMs, vm_active_ch = [05 02 04]: 661 * vm_map = [0 0 0 0 0 1 1 2 2 2 2] 662 * ch_map = [0 1 2 3 4 0 1 0 1 2 3] 663 */ 664 pvt->vd = devm_kcalloc(dev, pvt->vm_ch_total, sizeof(*pvt->vd), 665 GFP_KERNEL); 666 if (!pvt->vd) 667 return -ENOMEM; 668 669 k = 0; 670 for (i = 0; i < vm_num; i++) 671 for (j = 0; j < vm_active_ch[i]; j++) { 672 pvt->vd[k].vm_map = vm_idx[i]; 673 pvt->vd[k].ch_map = j; 674 k++; 675 } 676 677 in_config = devm_kcalloc(dev, pvt->vm_ch_total + 1, 678 sizeof(*in_config), GFP_KERNEL); 679 if (!in_config) 680 return -ENOMEM; 681 682 memset32(in_config, HWMON_I_INPUT, pvt->vm_ch_total); 683 in_config[pvt->vm_ch_total] = 0; 684 pvt_in.config = in_config; 685 686 pvt_info[index++] = &pvt_in; 687 } 688 689 ret = pvt_init(pvt); 690 if (ret) { 691 dev_err(dev, "failed to init pvt: %d\n", ret); 692 return ret; 693 } 694 695 pvt_chip_info.info = pvt_info; 696 hwmon_dev = devm_hwmon_device_register_with_info(dev, "pvt", 697 pvt, 698 &pvt_chip_info, 699 NULL); 700 701 return PTR_ERR_OR_ZERO(hwmon_dev); 702 } 703
Hi Eliav, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on groeck-staging/hwmon-next] [also build test WARNING on linus/master v6.0-rc1 next-20220816] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Eliav-Farber/Variety-of-fixes-and-new-features-for-mr75203-driver/20220816-183655 base: https://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git hwmon-next config: microblaze-randconfig-r013-20220815 (https://download.01.org/0day-ci/archive/20220817/202208170350.3yIFIWEk-lkp@intel.com/config) compiler: microblaze-linux-gcc (GCC) 12.1.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 # https://github.com/intel-lab-lkp/linux/commit/75e49737eb6188733096da72eb4692cfed872101 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Eliav-Farber/Variety-of-fixes-and-new-features-for-mr75203-driver/20220816-183655 git checkout 75e49737eb6188733096da72eb4692cfed872101 # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=microblaze SHELL=/bin/bash drivers/hwmon/ If you fix the issue, kindly add following tag where applicable Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): drivers/hwmon/mr75203.c: In function 'mr75203_probe': >> drivers/hwmon/mr75203.c:604:17: warning: ISO C90 forbids variable length array 'vm_idx' [-Wvla] 604 | u8 vm_idx[vm_num]; | ^~ >> drivers/hwmon/mr75203.c:605:17: warning: ISO C90 forbids variable length array 'vm_active_ch' [-Wvla] 605 | u8 vm_active_ch[vm_num]; | ^~ vim +/vm_idx +604 drivers/hwmon/mr75203.c 514 515 static int mr75203_probe(struct platform_device *pdev) 516 { 517 const struct hwmon_channel_info **pvt_info; 518 u32 ts_num, vm_num, pd_num, ch_num, val, index, i, j, k; 519 struct device *dev = &pdev->dev; 520 u32 *temp_config, *in_config; 521 struct device *hwmon_dev; 522 struct pvt_device *pvt; 523 int ret; 524 525 pvt = devm_kzalloc(dev, sizeof(*pvt), GFP_KERNEL); 526 if (!pvt) 527 return -ENOMEM; 528 529 ret = pvt_get_regmap(pdev, "common", pvt); 530 if (ret) 531 return ret; 532 533 pvt->clk = devm_clk_get(dev, NULL); 534 if (IS_ERR(pvt->clk)) 535 return dev_err_probe(dev, PTR_ERR(pvt->clk), "failed to get clock\n"); 536 537 ret = pvt_clk_enable(dev, pvt); 538 if (ret) { 539 dev_err(dev, "failed to enable clock\n"); 540 return ret; 541 } 542 543 if (of_property_read_bool(dev->of_node, "reset-control-skip")) { 544 dev_info(dev, "skipping reset-control\n"); 545 } else { 546 pvt->rst = devm_reset_control_get_exclusive(dev, NULL); 547 if (IS_ERR(pvt->rst)) 548 return dev_err_probe(dev, PTR_ERR(pvt->rst), 549 "failed to get reset control\n"); 550 551 ret = pvt_reset_control_deassert(dev, pvt); 552 if (ret) 553 return dev_err_probe(dev, ret, 554 "cannot deassert reset control\n"); 555 } 556 557 ret = regmap_read(pvt->c_map, PVT_IP_CONFIG, &val); 558 if(ret < 0) 559 return ret; 560 561 ts_num = (val & TS_NUM_MSK) >> TS_NUM_SFT; 562 pd_num = (val & PD_NUM_MSK) >> PD_NUM_SFT; 563 vm_num = (val & VM_NUM_MSK) >> VM_NUM_SFT; 564 ch_num = (val & CH_NUM_MSK) >> CH_NUM_SFT; 565 pvt->t_num = ts_num; 566 pvt->p_num = pd_num; 567 pvt->v_num = vm_num; 568 val = 0; 569 if (ts_num) 570 val++; 571 if (vm_num) 572 val++; 573 if (!val) 574 return -ENODEV; 575 576 pvt_info = devm_kcalloc(dev, val + 2, sizeof(*pvt_info), GFP_KERNEL); 577 if (!pvt_info) 578 return -ENOMEM; 579 pvt_info[0] = HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ); 580 index = 1; 581 582 if (ts_num) { 583 ret = pvt_get_regmap(pdev, "ts", pvt); 584 if (ret) 585 return ret; 586 587 temp_config = devm_kcalloc(dev, ts_num + 1, 588 sizeof(*temp_config), GFP_KERNEL); 589 if (!temp_config) 590 return -ENOMEM; 591 592 memset32(temp_config, HWMON_T_INPUT, ts_num); 593 pvt_temp.config = temp_config; 594 pvt_info[index++] = &pvt_temp; 595 } 596 597 if (pd_num) { 598 ret = pvt_get_regmap(pdev, "pd", pvt); 599 if (ret) 600 return ret; 601 } 602 603 if (vm_num) { > 604 u8 vm_idx[vm_num]; > 605 u8 vm_active_ch[vm_num]; 606 607 ret = pvt_get_regmap(pdev, "vm", pvt); 608 if (ret) 609 return ret; 610 611 ret = device_property_read_u8_array(dev, "intel,vm-map", vm_idx, 612 vm_num); 613 if (ret) { 614 /* 615 * Incase intel,vm-map property is not defined, we 616 * assume incremental channel numbers. 617 */ 618 for (i = 0; i < vm_num; i++) 619 vm_idx[i] = i; 620 } else { 621 for (i = 0; i < vm_num; i++) 622 if (vm_idx[i] >= vm_num || vm_idx[i] == 0xff) 623 break; 624 625 vm_num = i; 626 pvt->v_num = i; 627 } 628 629 ret = device_property_read_u8_array(dev, "vm-active-channels", 630 vm_active_ch, vm_num); 631 if (ret) { 632 /* 633 * Incase vm-active-channels property is not defined, 634 * we assume each VM sensor has all of its channels 635 * active. 636 */ 637 for (i = 0; i < vm_num; i++) 638 vm_active_ch[i] = ch_num; 639 640 pvt->vm_ch_max = ch_num; 641 pvt->vm_ch_total = ch_num * vm_num; 642 } else { 643 for (i = 0; i < vm_num; i++) { 644 if (vm_active_ch[i] > ch_num) { 645 dev_err(dev, 646 "invalid active channels: %u\n", 647 vm_active_ch[i]); 648 return -EINVAL; 649 } 650 651 pvt->vm_ch_total += vm_active_ch[i]; 652 653 if (vm_active_ch[i] > pvt->vm_ch_max) 654 pvt->vm_ch_max = vm_active_ch[i]; 655 } 656 } 657 658 /* 659 * Map between the channel-number to VM-index and channel-index. 660 * Example - 3 VMs, vm_active_ch = [05 02 04]: 661 * vm_map = [0 0 0 0 0 1 1 2 2 2 2] 662 * ch_map = [0 1 2 3 4 0 1 0 1 2 3] 663 */ 664 pvt->vd = devm_kcalloc(dev, pvt->vm_ch_total, sizeof(*pvt->vd), 665 GFP_KERNEL); 666 if (!pvt->vd) 667 return -ENOMEM; 668 669 k = 0; 670 for (i = 0; i < vm_num; i++) 671 for (j = 0; j < vm_active_ch[i]; j++) { 672 pvt->vd[k].vm_map = vm_idx[i]; 673 pvt->vd[k].ch_map = j; 674 k++; 675 } 676 677 in_config = devm_kcalloc(dev, pvt->vm_ch_total + 1, 678 sizeof(*in_config), GFP_KERNEL); 679 if (!in_config) 680 return -ENOMEM; 681 682 memset32(in_config, HWMON_I_INPUT, pvt->vm_ch_total); 683 in_config[pvt->vm_ch_total] = 0; 684 pvt_in.config = in_config; 685 686 pvt_info[index++] = &pvt_in; 687 } 688 689 ret = pvt_init(pvt); 690 if (ret) { 691 dev_err(dev, "failed to init pvt: %d\n", ret); 692 return ret; 693 } 694 695 pvt_chip_info.info = pvt_info; 696 hwmon_dev = devm_hwmon_device_register_with_info(dev, "pvt", 697 pvt, 698 &pvt_chip_info, 699 NULL); 700 701 return PTR_ERR_OR_ZERO(hwmon_dev); 702 } 703
diff --git a/drivers/hwmon/mr75203.c b/drivers/hwmon/mr75203.c index 4419e481d47c..9b45fd089fcf 100644 --- a/drivers/hwmon/mr75203.c +++ b/drivers/hwmon/mr75203.c @@ -107,6 +107,11 @@ #define PVT_N_CONST 90 #define PVT_R_CONST 245805 +struct voltage_device { + u8 vm_map; + u8 ch_map; +}; + struct pvt_device { struct regmap *c_map; struct regmap *t_map; @@ -114,12 +119,13 @@ struct pvt_device { struct regmap *v_map; struct clk *clk; struct reset_control *rst; + struct voltage_device *vd; u32 t_num; u32 p_num; u32 v_num; - u32 c_num; u32 ip_freq; - u8 *vm_idx; + u8 vm_ch_max; + u8 vm_ch_total; }; static umode_t pvt_is_visible(const void *data, enum hwmon_sensor_types type, @@ -186,11 +192,11 @@ static int pvt_read_in(struct device *dev, u32 attr, int channel, long *val) u8 ch_idx; int ret; - if (channel >= pvt->v_num * pvt->c_num) + if (channel >= pvt->vm_ch_total) return -EINVAL; - vm_idx = pvt->vm_idx[channel / pvt->c_num]; - ch_idx = channel % pvt->c_num; + vm_idx = pvt->vd[channel].vm_map; + ch_idx = pvt->vd[channel].ch_map; switch (attr) { case hwmon_in_input: @@ -390,7 +396,7 @@ static int pvt_init(struct pvt_device *pvt) if (ret) return ret; - val = GENMASK(pvt->c_num - 1, 0) | VM_CH_INIT | + val = GENMASK(pvt->vm_ch_max - 1, 0) | VM_CH_INIT | IP_POLL << SDIF_ADDR_SFT | SDIF_WRN_W | SDIF_PROG; ret = regmap_write(v_map, SDIF_W, val); @@ -519,7 +525,7 @@ static int pvt_reset_control_deassert(struct device *dev, struct pvt_device *pvt static int mr75203_probe(struct platform_device *pdev) { const struct hwmon_channel_info **pvt_info; - u32 ts_num, vm_num, pd_num, ch_num, val, index, i; + u32 ts_num, vm_num, pd_num, ch_num, val, index, i, j, k; struct device *dev = &pdev->dev; u32 *temp_config, *in_config; struct device *hwmon_dev; @@ -569,7 +575,6 @@ static int mr75203_probe(struct platform_device *pdev) pvt->t_num = ts_num; pvt->p_num = pd_num; pvt->v_num = vm_num; - pvt->c_num = ch_num; val = 0; if (ts_num) val++; @@ -606,43 +611,86 @@ static int mr75203_probe(struct platform_device *pdev) } if (vm_num) { - u32 total_ch = ch_num * vm_num; + u8 vm_idx[vm_num]; + u8 vm_active_ch[vm_num]; ret = pvt_get_regmap(pdev, "vm", pvt); if (ret) return ret; - pvt->vm_idx = devm_kcalloc(dev, vm_num, sizeof(*pvt->vm_idx), - GFP_KERNEL); - if (!pvt->vm_idx) - return -ENOMEM; - - ret = device_property_read_u8_array(dev, "intel,vm-map", - pvt->vm_idx, vm_num); + ret = device_property_read_u8_array(dev, "intel,vm-map", vm_idx, + vm_num); if (ret) { /* * Incase intel,vm-map property is not defined, we * assume incremental channel numbers. */ for (i = 0; i < vm_num; i++) - pvt->vm_idx[i] = i; + vm_idx[i] = i; } else { for (i = 0; i < vm_num; i++) - if (pvt->vm_idx[i] >= vm_num || - pvt->vm_idx[i] == 0xff) + if (vm_idx[i] >= vm_num || vm_idx[i] == 0xff) break; vm_num = i; pvt->v_num = i; } - in_config = devm_kcalloc(dev, total_ch + 1, + ret = device_property_read_u8_array(dev, "vm-active-channels", + vm_active_ch, vm_num); + if (ret) { + /* + * Incase vm-active-channels property is not defined, + * we assume each VM sensor has all of its channels + * active. + */ + for (i = 0; i < vm_num; i++) + vm_active_ch[i] = ch_num; + + pvt->vm_ch_max = ch_num; + pvt->vm_ch_total = ch_num * vm_num; + } else { + for (i = 0; i < vm_num; i++) { + if (vm_active_ch[i] > ch_num) { + dev_err(dev, + "invalid active channels: %u\n", + vm_active_ch[i]); + return -EINVAL; + } + + pvt->vm_ch_total += vm_active_ch[i]; + + if (vm_active_ch[i] > pvt->vm_ch_max) + pvt->vm_ch_max = vm_active_ch[i]; + } + } + + /* + * Map between the channel-number to VM-index and channel-index. + * Example - 3 VMs, vm_active_ch = [05 02 04]: + * vm_map = [0 0 0 0 0 1 1 2 2 2 2] + * ch_map = [0 1 2 3 4 0 1 0 1 2 3] + */ + pvt->vd = devm_kcalloc(dev, pvt->vm_ch_total, sizeof(*pvt->vd), + GFP_KERNEL); + if (!pvt->vd) + return -ENOMEM; + + k = 0; + for (i = 0; i < vm_num; i++) + for (j = 0; j < vm_active_ch[i]; j++) { + pvt->vd[k].vm_map = vm_idx[i]; + pvt->vd[k].ch_map = j; + k++; + } + + in_config = devm_kcalloc(dev, pvt->vm_ch_total + 1, sizeof(*in_config), GFP_KERNEL); if (!in_config) return -ENOMEM; - memset32(in_config, HWMON_I_INPUT, total_ch); - in_config[total_ch] = 0; + memset32(in_config, HWMON_I_INPUT, pvt->vm_ch_total); + in_config[pvt->vm_ch_total] = 0; pvt_in.config = in_config; pvt_info[index++] = &pvt_in;
Add active channel support per VM, which is useful when not all VM channels are used. Number of active channel is read from device-tree. When absent in device-tree, all channels are assumed to be used. Setting number of active channels to 0, means that entire VM sesnor is not used (this can partially replace the "intel,vm-map" functionality). Signed-off-by: Eliav Farber <farbere@amazon.com> --- drivers/hwmon/mr75203.c | 92 +++++++++++++++++++++++++++++++---------- 1 file changed, 70 insertions(+), 22 deletions(-)