* [PATCH v2 0/2] hwmon: npcm: add Arbel NPCM8XX support @ 2023-10-18 18:19 Tomer Maimon 2023-10-18 18:19 ` [PATCH v2 1/2] dt-bindings: hwmon: npcm: Add npcm845 compatible string Tomer Maimon 2023-10-18 18:19 ` [PATCH v2 2/2] hwmon: npcm750-pwm-fan: Add NPCM8xx support Tomer Maimon 0 siblings, 2 replies; 5+ messages in thread From: Tomer Maimon @ 2023-10-18 18:19 UTC (permalink / raw) To: linux, jdelvare, robh+dt, krzysztof.kozlowski+dt, avifishman70, tali.perry1, joel, andrew, venture, yuenn, benjaminfair, j.neuschaefer Cc: openbmc, linux-hwmon, linux-kernel, devicetree, Tomer Maimon This patch set adds Arbel NPCM8XX Pulse Width Modulation (PWM) and Fan tachometer (Fan) support to PWM FAN NPCM driver. The NPCM8XX supports up to 16 Fan tachometer inputs and up to 12 PWM outputs. The NPCM PWM FAN driver was tested on the NPCM845 evaluation board. Changes since version 1: - Add Rob Ack to the dt-binding commit. Tomer Maimon (2): dt-bindings: hwmon: npcm: Add npcm845 compatible string hwmon: npcm750-pwm-fan: Add NPCM8xx support .../bindings/hwmon/npcm750-pwm-fan.txt | 6 +- drivers/hwmon/npcm750-pwm-fan.c | 161 +++++++++++++++--- 2 files changed, 141 insertions(+), 26 deletions(-) -- 2.33.0 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 1/2] dt-bindings: hwmon: npcm: Add npcm845 compatible string 2023-10-18 18:19 [PATCH v2 0/2] hwmon: npcm: add Arbel NPCM8XX support Tomer Maimon @ 2023-10-18 18:19 ` Tomer Maimon 2023-10-28 16:20 ` Guenter Roeck 2023-10-18 18:19 ` [PATCH v2 2/2] hwmon: npcm750-pwm-fan: Add NPCM8xx support Tomer Maimon 1 sibling, 1 reply; 5+ messages in thread From: Tomer Maimon @ 2023-10-18 18:19 UTC (permalink / raw) To: linux, jdelvare, robh+dt, krzysztof.kozlowski+dt, avifishman70, tali.perry1, joel, andrew, venture, yuenn, benjaminfair, j.neuschaefer Cc: openbmc, linux-hwmon, linux-kernel, devicetree, Tomer Maimon, Rob Herring Add a compatible string for Nuvoton BMC NPCM845 Pulse Width Modulation (PWM) and Fan tach controller. Signed-off-by: Tomer Maimon <tmaimon77@gmail.com> Acked-by: Rob Herring <robh@kernel.org> --- Documentation/devicetree/bindings/hwmon/npcm750-pwm-fan.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/hwmon/npcm750-pwm-fan.txt b/Documentation/devicetree/bindings/hwmon/npcm750-pwm-fan.txt index 8523777f560c..18095ba87a5a 100644 --- a/Documentation/devicetree/bindings/hwmon/npcm750-pwm-fan.txt +++ b/Documentation/devicetree/bindings/hwmon/npcm750-pwm-fan.txt @@ -1,12 +1,16 @@ -Nuvoton NPCM7xx PWM and Fan Tacho controller device +Nuvoton NPCM PWM and Fan Tacho controller device The Nuvoton BMC NPCM7XX supports 8 Pulse-width modulation (PWM) controller outputs and 16 Fan tachometer controller inputs. +The Nuvoton BMC NPCM8XX supports 12 Pulse-width modulation (PWM) +controller outputs and 16 Fan tachometer controller inputs. + Required properties for pwm-fan node - #address-cells : should be 1. - #size-cells : should be 0. - compatible : "nuvoton,npcm750-pwm-fan" for Poleg NPCM7XX. + : "nuvoton,npcm845-pwm-fan" for Arbel NPCM8XX. - reg : specifies physical base address and size of the registers. - reg-names : must contain: * "pwm" for the PWM registers. -- 2.33.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v2 1/2] dt-bindings: hwmon: npcm: Add npcm845 compatible string 2023-10-18 18:19 ` [PATCH v2 1/2] dt-bindings: hwmon: npcm: Add npcm845 compatible string Tomer Maimon @ 2023-10-28 16:20 ` Guenter Roeck 0 siblings, 0 replies; 5+ messages in thread From: Guenter Roeck @ 2023-10-28 16:20 UTC (permalink / raw) To: Tomer Maimon Cc: jdelvare, robh+dt, krzysztof.kozlowski+dt, avifishman70, tali.perry1, joel, andrew, venture, yuenn, benjaminfair, j.neuschaefer, openbmc, linux-hwmon, linux-kernel, devicetree, Rob Herring On Wed, Oct 18, 2023 at 09:19:24PM +0300, Tomer Maimon wrote: > Add a compatible string for Nuvoton BMC NPCM845 Pulse Width Modulation (PWM) > and Fan tach controller. > > Signed-off-by: Tomer Maimon <tmaimon77@gmail.com> > Acked-by: Rob Herring <robh@kernel.org> Applied. Guenter ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2 2/2] hwmon: npcm750-pwm-fan: Add NPCM8xx support 2023-10-18 18:19 [PATCH v2 0/2] hwmon: npcm: add Arbel NPCM8XX support Tomer Maimon 2023-10-18 18:19 ` [PATCH v2 1/2] dt-bindings: hwmon: npcm: Add npcm845 compatible string Tomer Maimon @ 2023-10-18 18:19 ` Tomer Maimon 2023-10-25 19:51 ` Guenter Roeck 1 sibling, 1 reply; 5+ messages in thread From: Tomer Maimon @ 2023-10-18 18:19 UTC (permalink / raw) To: linux, jdelvare, robh+dt, krzysztof.kozlowski+dt, avifishman70, tali.perry1, joel, andrew, venture, yuenn, benjaminfair, j.neuschaefer Cc: openbmc, linux-hwmon, linux-kernel, devicetree, Tomer Maimon Adding Pulse Width Modulation (PWM) and fan tacho NPCM8xx support to NPCM PWM and fan tacho driver. NPCM8xx uses a different number of PWM devices. As part of adding NPCM8XX support: - Add NPCM8xx specific compatible string. - Add data to handle architecture-specific PWM and fan tacho parameters. Signed-off-by: Tomer Maimon <tmaimon77@gmail.com> --- drivers/hwmon/npcm750-pwm-fan.c | 161 +++++++++++++++++++++++++++----- 1 file changed, 136 insertions(+), 25 deletions(-) diff --git a/drivers/hwmon/npcm750-pwm-fan.c b/drivers/hwmon/npcm750-pwm-fan.c index 10ed3f4335d4..324de4482e71 100644 --- a/drivers/hwmon/npcm750-pwm-fan.c +++ b/drivers/hwmon/npcm750-pwm-fan.c @@ -45,11 +45,6 @@ #define NPCM7XX_PWM_CTRL_CH2_EN_BIT BIT(12) #define NPCM7XX_PWM_CTRL_CH3_EN_BIT BIT(16) -/* Define the maximum PWM channel number */ -#define NPCM7XX_PWM_MAX_CHN_NUM 8 -#define NPCM7XX_PWM_MAX_CHN_NUM_IN_A_MODULE 4 -#define NPCM7XX_PWM_MAX_MODULES 2 - /* Define the Counter Register, value = 100 for match 100% */ #define NPCM7XX_PWM_COUNTER_DEFAULT_NUM 255 #define NPCM7XX_PWM_CMR_DEFAULT_NUM 255 @@ -138,11 +133,9 @@ #define NPCM7XX_FAN_TCPCFG_CPASEL BIT(0) /* FAN General Definition */ -/* Define the maximum FAN channel number */ -#define NPCM7XX_FAN_MAX_MODULE 8 +/* Define the PWM and FAN in a module */ +#define NPCM7XX_PWM_MAX_CHN_NUM_IN_A_MODULE 4 #define NPCM7XX_FAN_MAX_CHN_NUM_IN_A_MODULE 2 -#define NPCM7XX_FAN_MAX_CHN_NUM 16 - /* * Get Fan Tach Timeout (base on clock 214843.75Hz, 1 cnt = 4.654us) * Timeout 94ms ~= 0x5000 @@ -171,6 +164,15 @@ #define FAN_PREPARE_TO_GET_FIRST_CAPTURE 0x01 #define FAN_ENOUGH_SAMPLE 0x02 +struct npcm_hwmon_info { + u32 pwm_max_modules; + u32 pwm_max_ch; + u32 fan_max_modules; + u32 fan_max_ch; + const struct hwmon_chip_info *hinfo; + const char *name; +}; + struct npcm7xx_fan_dev { u8 fan_st_flg; u8 fan_pls_per_rev; @@ -195,15 +197,16 @@ struct npcm7xx_pwm_fan_data { unsigned long fan_clk_freq; struct clk *pwm_clk; struct clk *fan_clk; - struct mutex pwm_lock[NPCM7XX_PWM_MAX_MODULES]; - spinlock_t fan_lock[NPCM7XX_FAN_MAX_MODULE]; - int fan_irq[NPCM7XX_FAN_MAX_MODULE]; - bool pwm_present[NPCM7XX_PWM_MAX_CHN_NUM]; - bool fan_present[NPCM7XX_FAN_MAX_CHN_NUM]; + struct mutex *pwm_lock; + spinlock_t *fan_lock; + int *fan_irq; + bool *pwm_present; + bool *fan_present; u32 input_clk_freq; struct timer_list fan_timer; - struct npcm7xx_fan_dev fan_dev[NPCM7XX_FAN_MAX_CHN_NUM]; - struct npcm7xx_cooling_device *cdev[NPCM7XX_PWM_MAX_CHN_NUM]; + struct npcm7xx_fan_dev *fan_dev; + struct npcm7xx_cooling_device **cdev; + const struct npcm_hwmon_info *info; u8 fan_select; }; @@ -333,7 +336,7 @@ static void npcm7xx_fan_polling(struct timer_list *t) * Polling two module per one round, * FAN01 & FAN89 / FAN23 & FAN1011 / FAN45 & FAN1213 / FAN67 & FAN1415 */ - for (i = data->fan_select; i < NPCM7XX_FAN_MAX_MODULE; + for (i = data->fan_select; i < data->info->fan_max_modules; i = i + 4) { /* clear the flag and reset the counter (TCNT) */ iowrite8(NPCM7XX_FAN_TICLR_CLEAR_ALL, @@ -659,6 +662,40 @@ static const struct hwmon_channel_info * const npcm7xx_info[] = { NULL }; +static const struct hwmon_channel_info * const npcm8xx_info[] = { + HWMON_CHANNEL_INFO(pwm, + HWMON_PWM_INPUT, + HWMON_PWM_INPUT, + HWMON_PWM_INPUT, + HWMON_PWM_INPUT, + HWMON_PWM_INPUT, + HWMON_PWM_INPUT, + HWMON_PWM_INPUT, + HWMON_PWM_INPUT, + HWMON_PWM_INPUT, + HWMON_PWM_INPUT, + HWMON_PWM_INPUT, + HWMON_PWM_INPUT), + HWMON_CHANNEL_INFO(fan, + HWMON_F_INPUT, + HWMON_F_INPUT, + HWMON_F_INPUT, + HWMON_F_INPUT, + HWMON_F_INPUT, + HWMON_F_INPUT, + HWMON_F_INPUT, + HWMON_F_INPUT, + HWMON_F_INPUT, + HWMON_F_INPUT, + HWMON_F_INPUT, + HWMON_F_INPUT, + HWMON_F_INPUT, + HWMON_F_INPUT, + HWMON_F_INPUT, + HWMON_F_INPUT), + NULL +}; + static const struct hwmon_ops npcm7xx_hwmon_ops = { .is_visible = npcm7xx_is_visible, .read = npcm7xx_read, @@ -670,6 +707,29 @@ static const struct hwmon_chip_info npcm7xx_chip_info = { .info = npcm7xx_info, }; +static const struct hwmon_chip_info npcm8xx_chip_info = { + .ops = &npcm7xx_hwmon_ops, + .info = npcm8xx_info, +}; + +static const struct npcm_hwmon_info npxm7xx_hwmon_info = { + .pwm_max_modules = 2, + .pwm_max_ch = NPCM7XX_PWM_MAX_CHN_NUM_IN_A_MODULE * 2, + .fan_max_modules = 8, + .fan_max_ch = NPCM7XX_FAN_MAX_CHN_NUM_IN_A_MODULE * 8, + .hinfo = &npcm7xx_chip_info, + .name = "npcm7xx_pwm_fan", +}; + +static const struct npcm_hwmon_info npxm8xx_hwmon_info = { + .pwm_max_modules = 3, + .pwm_max_ch = NPCM7XX_PWM_MAX_CHN_NUM_IN_A_MODULE * 3, + .fan_max_modules = 8, + .fan_max_ch = NPCM7XX_FAN_MAX_CHN_NUM_IN_A_MODULE * 8, + .hinfo = &npcm8xx_chip_info, + .name = "npcm8xx_pwm_fan", +}; + static u32 npcm7xx_pwm_init(struct npcm7xx_pwm_fan_data *data) { int m, ch; @@ -693,7 +753,7 @@ static u32 npcm7xx_pwm_init(struct npcm7xx_pwm_fan_data *data) /* Setting PWM Prescale Register value register to both modules */ prescale_val |= (prescale_val << NPCM7XX_PWM_PRESCALE_SHIFT_CH01); - for (m = 0; m < NPCM7XX_PWM_MAX_MODULES ; m++) { + for (m = 0; m < data->info->pwm_max_modules ; m++) { iowrite32(prescale_val, NPCM7XX_PWM_REG_PR(data->pwm_base, m)); iowrite32(NPCM7XX_PWM_PRESCALE2_DEFAULT, NPCM7XX_PWM_REG_CSR(data->pwm_base, m)); @@ -716,7 +776,7 @@ static void npcm7xx_fan_init(struct npcm7xx_pwm_fan_data *data) int i; u32 apb_clk_freq; - for (md = 0; md < NPCM7XX_FAN_MAX_MODULE; md++) { + for (md = 0; md < data->info->fan_max_modules; md++) { /* stop FAN0~7 clock */ iowrite8(NPCM7XX_FAN_TCKC_CLKX_NONE, NPCM7XX_FAN_REG_TCKC(data->fan_base, md)); @@ -905,6 +965,49 @@ static int npcm7xx_en_pwm_fan(struct device *dev, return 0; } +static int npcm_pwm_fan_alloc_data(struct device *dev, + struct npcm7xx_pwm_fan_data *data) +{ + data->pwm_lock = devm_kcalloc(dev, data->info->pwm_max_modules, + sizeof(*data->pwm_lock), GFP_KERNEL); + if (!data->pwm_lock) + return -ENOMEM; + + data->fan_lock = devm_kcalloc(dev, data->info->fan_max_modules, + sizeof(*data->fan_lock), GFP_KERNEL); + if (!data->fan_lock) + return -ENOMEM; + + data->fan_irq = devm_kcalloc(dev, data->info->fan_max_modules, + sizeof(*data->fan_irq), GFP_KERNEL); + if (!data->fan_irq) + return -ENOMEM; + + data->pwm_present = devm_kcalloc(dev, data->info->pwm_max_ch, + sizeof(*data->pwm_present), + GFP_KERNEL); + if (!data->pwm_present) + return -ENOMEM; + + data->fan_present = devm_kcalloc(dev, data->info->fan_max_ch, + sizeof(*data->fan_present), + GFP_KERNEL); + if (!data->fan_present) + return -ENOMEM; + + data->fan_dev = devm_kcalloc(dev, data->info->fan_max_ch, + sizeof(*data->fan_dev), GFP_KERNEL); + if (!data->fan_dev) + return -ENOMEM; + + data->cdev = devm_kcalloc(dev, data->info->pwm_max_ch, + sizeof(*data->cdev), GFP_KERNEL); + if (!data->cdev) + return -ENOMEM; + + return 0; +} + static int npcm7xx_pwm_fan_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -923,6 +1026,13 @@ static int npcm7xx_pwm_fan_probe(struct platform_device *pdev) if (!data) return -ENOMEM; + data->info = device_get_match_data(dev); + if (!data->info) + return -EINVAL; + + if (npcm_pwm_fan_alloc_data(dev, data)) + return -ENOMEM; + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwm"); if (!res) { dev_err(dev, "pwm resource not found\n"); @@ -960,10 +1070,10 @@ static int npcm7xx_pwm_fan_probe(struct platform_device *pdev) output_freq = npcm7xx_pwm_init(data); npcm7xx_fan_init(data); - for (cnt = 0; cnt < NPCM7XX_PWM_MAX_MODULES ; cnt++) + for (cnt = 0; cnt < data->info->pwm_max_modules ; cnt++) mutex_init(&data->pwm_lock[cnt]); - for (i = 0; i < NPCM7XX_FAN_MAX_MODULE; i++) { + for (i = 0; i < data->info->fan_max_modules; i++) { spin_lock_init(&data->fan_lock[i]); data->fan_irq[i] = platform_get_irq(pdev, i); @@ -988,15 +1098,15 @@ static int npcm7xx_pwm_fan_probe(struct platform_device *pdev) } } - hwmon = devm_hwmon_device_register_with_info(dev, "npcm7xx_pwm_fan", - data, &npcm7xx_chip_info, + hwmon = devm_hwmon_device_register_with_info(dev, data->info->name, + data, data->info->hinfo, NULL); if (IS_ERR(hwmon)) { dev_err(dev, "unable to register hwmon device\n"); return PTR_ERR(hwmon); } - for (i = 0; i < NPCM7XX_FAN_MAX_CHN_NUM; i++) { + for (i = 0; i < data->info->fan_max_ch; i++) { if (data->fan_present[i]) { /* fan timer initialization */ data->fan_timer.expires = jiffies + @@ -1015,7 +1125,8 @@ static int npcm7xx_pwm_fan_probe(struct platform_device *pdev) } static const struct of_device_id of_pwm_fan_match_table[] = { - { .compatible = "nuvoton,npcm750-pwm-fan", }, + { .compatible = "nuvoton,npcm750-pwm-fan", .data = &npxm7xx_hwmon_info}, + { .compatible = "nuvoton,npcm845-pwm-fan", .data = &npxm8xx_hwmon_info}, {}, }; MODULE_DEVICE_TABLE(of, of_pwm_fan_match_table); -- 2.33.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v2 2/2] hwmon: npcm750-pwm-fan: Add NPCM8xx support 2023-10-18 18:19 ` [PATCH v2 2/2] hwmon: npcm750-pwm-fan: Add NPCM8xx support Tomer Maimon @ 2023-10-25 19:51 ` Guenter Roeck 0 siblings, 0 replies; 5+ messages in thread From: Guenter Roeck @ 2023-10-25 19:51 UTC (permalink / raw) To: Tomer Maimon Cc: jdelvare, robh+dt, krzysztof.kozlowski+dt, avifishman70, tali.perry1, joel, andrew, venture, yuenn, benjaminfair, j.neuschaefer, openbmc, linux-hwmon, linux-kernel, devicetree On Wed, Oct 18, 2023 at 09:19:25PM +0300, Tomer Maimon wrote: > Adding Pulse Width Modulation (PWM) and fan tacho NPCM8xx support to > NPCM PWM and fan tacho driver. > NPCM8xx uses a different number of PWM devices. > > As part of adding NPCM8XX support: > - Add NPCM8xx specific compatible string. > - Add data to handle architecture-specific PWM and fan tacho parameters. > > Signed-off-by: Tomer Maimon <tmaimon77@gmail.com> > --- > drivers/hwmon/npcm750-pwm-fan.c | 161 +++++++++++++++++++++++++++----- > 1 file changed, 136 insertions(+), 25 deletions(-) > > diff --git a/drivers/hwmon/npcm750-pwm-fan.c b/drivers/hwmon/npcm750-pwm-fan.c > index 10ed3f4335d4..324de4482e71 100644 > --- a/drivers/hwmon/npcm750-pwm-fan.c > +++ b/drivers/hwmon/npcm750-pwm-fan.c > @@ -45,11 +45,6 @@ > #define NPCM7XX_PWM_CTRL_CH2_EN_BIT BIT(12) > #define NPCM7XX_PWM_CTRL_CH3_EN_BIT BIT(16) > > -/* Define the maximum PWM channel number */ > -#define NPCM7XX_PWM_MAX_CHN_NUM 8 > -#define NPCM7XX_PWM_MAX_CHN_NUM_IN_A_MODULE 4 > -#define NPCM7XX_PWM_MAX_MODULES 2 > - > /* Define the Counter Register, value = 100 for match 100% */ > #define NPCM7XX_PWM_COUNTER_DEFAULT_NUM 255 > #define NPCM7XX_PWM_CMR_DEFAULT_NUM 255 > @@ -138,11 +133,9 @@ > #define NPCM7XX_FAN_TCPCFG_CPASEL BIT(0) > > /* FAN General Definition */ > -/* Define the maximum FAN channel number */ > -#define NPCM7XX_FAN_MAX_MODULE 8 > +/* Define the PWM and FAN in a module */ > +#define NPCM7XX_PWM_MAX_CHN_NUM_IN_A_MODULE 4 > #define NPCM7XX_FAN_MAX_CHN_NUM_IN_A_MODULE 2 > -#define NPCM7XX_FAN_MAX_CHN_NUM 16 > - > /* > * Get Fan Tach Timeout (base on clock 214843.75Hz, 1 cnt = 4.654us) > * Timeout 94ms ~= 0x5000 > @@ -171,6 +164,15 @@ > #define FAN_PREPARE_TO_GET_FIRST_CAPTURE 0x01 > #define FAN_ENOUGH_SAMPLE 0x02 > > +struct npcm_hwmon_info { > + u32 pwm_max_modules; > + u32 pwm_max_ch; > + u32 fan_max_modules; > + u32 fan_max_ch; > + const struct hwmon_chip_info *hinfo; > + const char *name; > +}; > + > struct npcm7xx_fan_dev { > u8 fan_st_flg; > u8 fan_pls_per_rev; > @@ -195,15 +197,16 @@ struct npcm7xx_pwm_fan_data { > unsigned long fan_clk_freq; > struct clk *pwm_clk; > struct clk *fan_clk; > - struct mutex pwm_lock[NPCM7XX_PWM_MAX_MODULES]; > - spinlock_t fan_lock[NPCM7XX_FAN_MAX_MODULE]; > - int fan_irq[NPCM7XX_FAN_MAX_MODULE]; > - bool pwm_present[NPCM7XX_PWM_MAX_CHN_NUM]; > - bool fan_present[NPCM7XX_FAN_MAX_CHN_NUM]; I do not see the point of making this dynamic. Sure, there is an additional pwm channel on NPCM8xx, so just add another entry and handle (enable/disable) the additional channel with the is_visible function. As written there is a lot of churn, and I am sure the code is much larger than it was just to save a single pwm entry. > + struct mutex *pwm_lock; > + spinlock_t *fan_lock; > + int *fan_irq; > + bool *pwm_present; > + bool *fan_present; > u32 input_clk_freq; > struct timer_list fan_timer; > - struct npcm7xx_fan_dev fan_dev[NPCM7XX_FAN_MAX_CHN_NUM]; > - struct npcm7xx_cooling_device *cdev[NPCM7XX_PWM_MAX_CHN_NUM]; > + struct npcm7xx_fan_dev *fan_dev; > + struct npcm7xx_cooling_device **cdev; > + const struct npcm_hwmon_info *info; > u8 fan_select; > }; > > @@ -333,7 +336,7 @@ static void npcm7xx_fan_polling(struct timer_list *t) > * Polling two module per one round, > * FAN01 & FAN89 / FAN23 & FAN1011 / FAN45 & FAN1213 / FAN67 & FAN1415 > */ > - for (i = data->fan_select; i < NPCM7XX_FAN_MAX_MODULE; > + for (i = data->fan_select; i < data->info->fan_max_modules; > i = i + 4) { > /* clear the flag and reset the counter (TCNT) */ > iowrite8(NPCM7XX_FAN_TICLR_CLEAR_ALL, > @@ -659,6 +662,40 @@ static const struct hwmon_channel_info * const npcm7xx_info[] = { > NULL > }; > > +static const struct hwmon_channel_info * const npcm8xx_info[] = { > + HWMON_CHANNEL_INFO(pwm, > + HWMON_PWM_INPUT, > + HWMON_PWM_INPUT, > + HWMON_PWM_INPUT, > + HWMON_PWM_INPUT, > + HWMON_PWM_INPUT, > + HWMON_PWM_INPUT, > + HWMON_PWM_INPUT, > + HWMON_PWM_INPUT, > + HWMON_PWM_INPUT, > + HWMON_PWM_INPUT, > + HWMON_PWM_INPUT, > + HWMON_PWM_INPUT), > + HWMON_CHANNEL_INFO(fan, > + HWMON_F_INPUT, > + HWMON_F_INPUT, > + HWMON_F_INPUT, > + HWMON_F_INPUT, > + HWMON_F_INPUT, > + HWMON_F_INPUT, > + HWMON_F_INPUT, > + HWMON_F_INPUT, > + HWMON_F_INPUT, > + HWMON_F_INPUT, > + HWMON_F_INPUT, > + HWMON_F_INPUT, > + HWMON_F_INPUT, > + HWMON_F_INPUT, > + HWMON_F_INPUT, > + HWMON_F_INPUT), > + NULL > +}; This should be handled with the is_visible() function, not with separate data structures. > + > static const struct hwmon_ops npcm7xx_hwmon_ops = { > .is_visible = npcm7xx_is_visible, > .read = npcm7xx_read, > @@ -670,6 +707,29 @@ static const struct hwmon_chip_info npcm7xx_chip_info = { > .info = npcm7xx_info, > }; > > +static const struct hwmon_chip_info npcm8xx_chip_info = { > + .ops = &npcm7xx_hwmon_ops, > + .info = npcm8xx_info, > +}; > + > +static const struct npcm_hwmon_info npxm7xx_hwmon_info = { > + .pwm_max_modules = 2, > + .pwm_max_ch = NPCM7XX_PWM_MAX_CHN_NUM_IN_A_MODULE * 2, > + .fan_max_modules = 8, > + .fan_max_ch = NPCM7XX_FAN_MAX_CHN_NUM_IN_A_MODULE * 8, > + .hinfo = &npcm7xx_chip_info, > + .name = "npcm7xx_pwm_fan", > +}; > + > +static const struct npcm_hwmon_info npxm8xx_hwmon_info = { > + .pwm_max_modules = 3, > + .pwm_max_ch = NPCM7XX_PWM_MAX_CHN_NUM_IN_A_MODULE * 3, > + .fan_max_modules = 8, > + .fan_max_ch = NPCM7XX_FAN_MAX_CHN_NUM_IN_A_MODULE * 8, fan_max_modules and fan_max_ch do not change across chips, and pwm_max_ch is always NPCM7XX_PWM_MAX_CHN_NUM_IN_A_MODULE times the number of channels. This can all be dropped. Again, the only real difference is the number of pwm channels, and that can be handled in the _is_visible() function. > + .hinfo = &npcm8xx_chip_info, > + .name = "npcm8xx_pwm_fan", > +}; > + > static u32 npcm7xx_pwm_init(struct npcm7xx_pwm_fan_data *data) > { > int m, ch; > @@ -693,7 +753,7 @@ static u32 npcm7xx_pwm_init(struct npcm7xx_pwm_fan_data *data) > /* Setting PWM Prescale Register value register to both modules */ > prescale_val |= (prescale_val << NPCM7XX_PWM_PRESCALE_SHIFT_CH01); > > - for (m = 0; m < NPCM7XX_PWM_MAX_MODULES ; m++) { > + for (m = 0; m < data->info->pwm_max_modules ; m++) { > iowrite32(prescale_val, NPCM7XX_PWM_REG_PR(data->pwm_base, m)); > iowrite32(NPCM7XX_PWM_PRESCALE2_DEFAULT, > NPCM7XX_PWM_REG_CSR(data->pwm_base, m)); > @@ -716,7 +776,7 @@ static void npcm7xx_fan_init(struct npcm7xx_pwm_fan_data *data) > int i; > u32 apb_clk_freq; > > - for (md = 0; md < NPCM7XX_FAN_MAX_MODULE; md++) { > + for (md = 0; md < data->info->fan_max_modules; md++) { > /* stop FAN0~7 clock */ > iowrite8(NPCM7XX_FAN_TCKC_CLKX_NONE, > NPCM7XX_FAN_REG_TCKC(data->fan_base, md)); > @@ -905,6 +965,49 @@ static int npcm7xx_en_pwm_fan(struct device *dev, > return 0; > } > > +static int npcm_pwm_fan_alloc_data(struct device *dev, > + struct npcm7xx_pwm_fan_data *data) > +{ > + data->pwm_lock = devm_kcalloc(dev, data->info->pwm_max_modules, > + sizeof(*data->pwm_lock), GFP_KERNEL); > + if (!data->pwm_lock) > + return -ENOMEM; > + > + data->fan_lock = devm_kcalloc(dev, data->info->fan_max_modules, > + sizeof(*data->fan_lock), GFP_KERNEL); > + if (!data->fan_lock) > + return -ENOMEM; > + > + data->fan_irq = devm_kcalloc(dev, data->info->fan_max_modules, > + sizeof(*data->fan_irq), GFP_KERNEL); > + if (!data->fan_irq) > + return -ENOMEM; > + > + data->pwm_present = devm_kcalloc(dev, data->info->pwm_max_ch, > + sizeof(*data->pwm_present), > + GFP_KERNEL); > + if (!data->pwm_present) > + return -ENOMEM; > + > + data->fan_present = devm_kcalloc(dev, data->info->fan_max_ch, > + sizeof(*data->fan_present), > + GFP_KERNEL); > + if (!data->fan_present) > + return -ENOMEM; > + > + data->fan_dev = devm_kcalloc(dev, data->info->fan_max_ch, > + sizeof(*data->fan_dev), GFP_KERNEL); > + if (!data->fan_dev) > + return -ENOMEM; > + > + data->cdev = devm_kcalloc(dev, data->info->pwm_max_ch, > + sizeof(*data->cdev), GFP_KERNEL); > + if (!data->cdev) > + return -ENOMEM; > + > + return 0; > +} > + > static int npcm7xx_pwm_fan_probe(struct platform_device *pdev) > { > struct device *dev = &pdev->dev; > @@ -923,6 +1026,13 @@ static int npcm7xx_pwm_fan_probe(struct platform_device *pdev) > if (!data) > return -ENOMEM; > > + data->info = device_get_match_data(dev); > + if (!data->info) > + return -EINVAL; > + > + if (npcm_pwm_fan_alloc_data(dev, data)) > + return -ENOMEM; > + > res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwm"); > if (!res) { > dev_err(dev, "pwm resource not found\n"); > @@ -960,10 +1070,10 @@ static int npcm7xx_pwm_fan_probe(struct platform_device *pdev) > output_freq = npcm7xx_pwm_init(data); > npcm7xx_fan_init(data); > > - for (cnt = 0; cnt < NPCM7XX_PWM_MAX_MODULES ; cnt++) > + for (cnt = 0; cnt < data->info->pwm_max_modules ; cnt++) > mutex_init(&data->pwm_lock[cnt]); > > - for (i = 0; i < NPCM7XX_FAN_MAX_MODULE; i++) { > + for (i = 0; i < data->info->fan_max_modules; i++) { > spin_lock_init(&data->fan_lock[i]); > > data->fan_irq[i] = platform_get_irq(pdev, i); > @@ -988,15 +1098,15 @@ static int npcm7xx_pwm_fan_probe(struct platform_device *pdev) > } > } > > - hwmon = devm_hwmon_device_register_with_info(dev, "npcm7xx_pwm_fan", > - data, &npcm7xx_chip_info, > + hwmon = devm_hwmon_device_register_with_info(dev, data->info->name, > + data, data->info->hinfo, > NULL); > if (IS_ERR(hwmon)) { > dev_err(dev, "unable to register hwmon device\n"); > return PTR_ERR(hwmon); > } > > - for (i = 0; i < NPCM7XX_FAN_MAX_CHN_NUM; i++) { > + for (i = 0; i < data->info->fan_max_ch; i++) { > if (data->fan_present[i]) { > /* fan timer initialization */ > data->fan_timer.expires = jiffies + > @@ -1015,7 +1125,8 @@ static int npcm7xx_pwm_fan_probe(struct platform_device *pdev) > } > > static const struct of_device_id of_pwm_fan_match_table[] = { > - { .compatible = "nuvoton,npcm750-pwm-fan", }, > + { .compatible = "nuvoton,npcm750-pwm-fan", .data = &npxm7xx_hwmon_info}, > + { .compatible = "nuvoton,npcm845-pwm-fan", .data = &npxm8xx_hwmon_info}, > {}, > }; > MODULE_DEVICE_TABLE(of, of_pwm_fan_match_table); ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2023-10-28 16:20 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-10-18 18:19 [PATCH v2 0/2] hwmon: npcm: add Arbel NPCM8XX support Tomer Maimon 2023-10-18 18:19 ` [PATCH v2 1/2] dt-bindings: hwmon: npcm: Add npcm845 compatible string Tomer Maimon 2023-10-28 16:20 ` Guenter Roeck 2023-10-18 18:19 ` [PATCH v2 2/2] hwmon: npcm750-pwm-fan: Add NPCM8xx support Tomer Maimon 2023-10-25 19:51 ` Guenter Roeck
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).