From 09e52d17b72d3a4bf6951a90ccd8c97fae04e5cf Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Wed, 17 Aug 2022 15:04:00 +0200 Subject: hwmon: (pmbus) Use dev_err_probe() to filter -EPROBE_DEFER error messages devm_regulator_register() can return -EPROBE_DEFER, so better use dev_err_probe() instead of dev_err(), it is less verbose in such a case. It is also more informative, which can't hurt. Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/3adf1cea6e32e54c0f71f4604b4e98d992beaa71.1660741419.git.christophe.jaillet@wanadoo.fr Signed-off-by: Guenter Roeck --- drivers/hwmon/pmbus/pmbus_core.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index f10bac8860fc..75cf8e20fa4d 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -3016,11 +3016,10 @@ static int pmbus_regulator_register(struct pmbus_data *data) rdev = devm_regulator_register(dev, &info->reg_desc[i], &config); - if (IS_ERR(rdev)) { - dev_err(dev, "Failed to register %s regulator\n", - info->reg_desc[i].name); - return PTR_ERR(rdev); - } + if (IS_ERR(rdev)) + return dev_err_probe(dev, PTR_ERR(rdev), + "Failed to register %s regulator\n", + info->reg_desc[i].name); } return 0; -- cgit v1.2.3-59-g8ed1b From ed3590561f5d3343a1717396307d0942eda472ed Mon Sep 17 00:00:00 2001 From: Vincent Whitchurch Date: Tue, 16 Aug 2022 16:44:14 +0200 Subject: hwmon: (pmbus) Fix vout margin caching The code currently uses a zero margin to mean not cached, but this results in the cache being bypassed if the (low) margin is set to zero, leading to lots of unnecessary SMBus transactions in that case. Use a negative value instead. Fixes: 07fb76273db89d93 ("hwmon: (pmbus) Introduce and use cached vout margins") Signed-off-by: Vincent Whitchurch Link: https://lore.kernel.org/r/20220816144414.2358974-1-vincent.whitchurch@axis.com Signed-off-by: Guenter Roeck --- drivers/hwmon/pmbus/pmbus_core.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 75cf8e20fa4d..81d3f91dd204 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -2861,7 +2861,7 @@ static int pmbus_regulator_get_low_margin(struct i2c_client *client, int page) .data = -1, }; - if (!data->vout_low[page]) { + if (data->vout_low[page] < 0) { if (pmbus_check_word_register(client, page, PMBUS_MFR_VOUT_MIN)) s.data = _pmbus_read_word_data(client, page, 0xff, PMBUS_MFR_VOUT_MIN); @@ -2887,7 +2887,7 @@ static int pmbus_regulator_get_high_margin(struct i2c_client *client, int page) .data = -1, }; - if (!data->vout_high[page]) { + if (data->vout_high[page] < 0) { if (pmbus_check_word_register(client, page, PMBUS_MFR_VOUT_MAX)) s.data = _pmbus_read_word_data(client, page, 0xff, PMBUS_MFR_VOUT_MAX); @@ -3319,6 +3319,7 @@ int pmbus_do_probe(struct i2c_client *client, struct pmbus_driver_info *info) struct pmbus_data *data; size_t groups_num = 0; int ret; + int i; char *name; if (!info) @@ -3352,6 +3353,11 @@ int pmbus_do_probe(struct i2c_client *client, struct pmbus_driver_info *info) data->currpage = -1; data->currphase = -1; + for (i = 0; i < ARRAY_SIZE(data->vout_low); i++) { + data->vout_low[i] = -1; + data->vout_high[i] = -1; + } + ret = pmbus_init_common(client, data, info); if (ret < 0) return ret; -- cgit v1.2.3-59-g8ed1b From f233d2be38dbbb22299192292983037f01ab363c Mon Sep 17 00:00:00 2001 From: Armin Wolf Date: Tue, 30 Aug 2022 03:11:01 +0200 Subject: hwmon: (gpio-fan) Fix array out of bounds access The driver does not check if the cooling state passed to gpio_fan_set_cur_state() exceeds the maximum cooling state as stored in fan_data->num_speeds. Since the cooling state is later used as an array index in set_fan_speed(), an array out of bounds access can occur. This can be exploited by setting the state of the thermal cooling device to arbitrary values, causing for example a kernel oops when unavailable memory is accessed this way. Example kernel oops: [ 807.987276] Unable to handle kernel paging request at virtual address ffffff80d0588064 [ 807.987369] Mem abort info: [ 807.987398] ESR = 0x96000005 [ 807.987428] EC = 0x25: DABT (current EL), IL = 32 bits [ 807.987477] SET = 0, FnV = 0 [ 807.987507] EA = 0, S1PTW = 0 [ 807.987536] FSC = 0x05: level 1 translation fault [ 807.987570] Data abort info: [ 807.987763] ISV = 0, ISS = 0x00000005 [ 807.987801] CM = 0, WnR = 0 [ 807.987832] swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000001165000 [ 807.987872] [ffffff80d0588064] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000 [ 807.987961] Internal error: Oops: 96000005 [#1] PREEMPT SMP [ 807.987992] Modules linked in: cmac algif_hash aes_arm64 algif_skcipher af_alg bnep hci_uart btbcm bluetooth ecdh_generic ecc 8021q garp stp llc snd_soc_hdmi_codec brcmfmac vc4 brcmutil cec drm_kms_helper snd_soc_core cfg80211 snd_compress bcm2835_codec(C) snd_pcm_dmaengine syscopyarea bcm2835_isp(C) bcm2835_v4l2(C) sysfillrect v4l2_mem2mem bcm2835_mmal_vchiq(C) raspberrypi_hwmon sysimgblt videobuf2_dma_contig videobuf2_vmalloc fb_sys_fops videobuf2_memops rfkill videobuf2_v4l2 videobuf2_common i2c_bcm2835 snd_bcm2835(C) videodev snd_pcm snd_timer snd mc vc_sm_cma(C) gpio_fan uio_pdrv_genirq uio drm fuse drm_panel_orientation_quirks backlight ip_tables x_tables ipv6 [ 807.988508] CPU: 0 PID: 1321 Comm: bash Tainted: G C 5.15.56-v8+ #1575 [ 807.988548] Hardware name: Raspberry Pi 3 Model B Rev 1.2 (DT) [ 807.988574] pstate: 20000005 (nzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 807.988608] pc : set_fan_speed.part.5+0x34/0x80 [gpio_fan] [ 807.988654] lr : gpio_fan_set_cur_state+0x34/0x50 [gpio_fan] [ 807.988691] sp : ffffffc008cf3bd0 [ 807.988710] x29: ffffffc008cf3bd0 x28: ffffff80019edac0 x27: 0000000000000000 [ 807.988762] x26: 0000000000000000 x25: 0000000000000000 x24: ffffff800747c920 [ 807.988787] x23: 000000000000000a x22: ffffff800369f000 x21: 000000001999997c [ 807.988854] x20: ffffff800369f2e8 x19: ffffff8002ae8080 x18: 0000000000000000 [ 807.988877] x17: 0000000000000000 x16: 0000000000000000 x15: 000000559e271b70 [ 807.988938] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000 [ 807.988960] x11: 0000000000000000 x10: ffffffc008cf3c20 x9 : ffffffcfb60c741c [ 807.989018] x8 : 000000000000000a x7 : 00000000ffffffc9 x6 : 0000000000000009 [ 807.989040] x5 : 000000000000002a x4 : 0000000000000000 x3 : ffffff800369f2e8 [ 807.989062] x2 : 000000000000e780 x1 : 0000000000000001 x0 : ffffff80d0588060 [ 807.989084] Call trace: [ 807.989091] set_fan_speed.part.5+0x34/0x80 [gpio_fan] [ 807.989113] gpio_fan_set_cur_state+0x34/0x50 [gpio_fan] [ 807.989199] cur_state_store+0x84/0xd0 [ 807.989221] dev_attr_store+0x20/0x38 [ 807.989262] sysfs_kf_write+0x4c/0x60 [ 807.989282] kernfs_fop_write_iter+0x130/0x1c0 [ 807.989298] new_sync_write+0x10c/0x190 [ 807.989315] vfs_write+0x254/0x378 [ 807.989362] ksys_write+0x70/0xf8 [ 807.989379] __arm64_sys_write+0x24/0x30 [ 807.989424] invoke_syscall+0x4c/0x110 [ 807.989442] el0_svc_common.constprop.3+0xfc/0x120 [ 807.989458] do_el0_svc+0x2c/0x90 [ 807.989473] el0_svc+0x24/0x60 [ 807.989544] el0t_64_sync_handler+0x90/0xb8 [ 807.989558] el0t_64_sync+0x1a0/0x1a4 [ 807.989579] Code: b9403801 f9402800 7100003f 8b35cc00 (b9400416) [ 807.989627] ---[ end trace 8ded4c918658445b ]--- Fix this by checking the cooling state and return an error if it exceeds the maximum cooling state. Tested on a Raspberry Pi 3. Fixes: b5cf88e46bad ("(gpio-fan): Add thermal control hooks") Signed-off-by: Armin Wolf Link: https://lore.kernel.org/r/20220830011101.178843-1-W_Armin@gmx.de Signed-off-by: Guenter Roeck --- drivers/hwmon/gpio-fan.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c index befe989ca7b9..fbf3f5a4ecb6 100644 --- a/drivers/hwmon/gpio-fan.c +++ b/drivers/hwmon/gpio-fan.c @@ -391,6 +391,9 @@ static int gpio_fan_set_cur_state(struct thermal_cooling_device *cdev, if (!fan_data) return -EINVAL; + if (state >= fan_data->num_speed) + return -EINVAL; + set_fan_speed(fan_data, state); return 0; } -- cgit v1.2.3-59-g8ed1b From 1f05f65bddd6958d25b133f886da49c1d4bff3fa Mon Sep 17 00:00:00 2001 From: Alexandru Gagniuc Date: Mon, 5 Sep 2022 09:28:04 -0500 Subject: hwmon: (tps23861) fix byte order in resistance register The tps23861 registers are little-endian, and regmap_read_bulk() does not do byte order conversion. On BE machines, the bytes were swapped, and the interpretation of the resistance value was incorrect. To make it work on both big and little-endian machines, use le16_to_cpu() to convert the resitance register to host byte order. Signed-off-by: Alexandru Gagniuc Fixes: fff7b8ab22554 ("hwmon: add Texas Instruments TPS23861 driver") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220905142806.110598-1-mr.nuke.me@gmail.com Signed-off-by: Guenter Roeck --- drivers/hwmon/tps23861.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/tps23861.c b/drivers/hwmon/tps23861.c index 42762e87b014..f7c59ff7ae8e 100644 --- a/drivers/hwmon/tps23861.c +++ b/drivers/hwmon/tps23861.c @@ -493,18 +493,20 @@ static char *tps23861_port_poe_plus_status(struct tps23861_data *data, int port) static int tps23861_port_resistance(struct tps23861_data *data, int port) { - u16 regval; + unsigned int raw_val; + __le16 regval; regmap_bulk_read(data->regmap, PORT_1_RESISTANCE_LSB + PORT_N_RESISTANCE_LSB_OFFSET * (port - 1), ®val, 2); - switch (FIELD_GET(PORT_RESISTANCE_RSN_MASK, regval)) { + raw_val = le16_to_cpu(regval); + switch (FIELD_GET(PORT_RESISTANCE_RSN_MASK, raw_val)) { case PORT_RESISTANCE_RSN_OTHER: - return (FIELD_GET(PORT_RESISTANCE_MASK, regval) * RESISTANCE_LSB) / 10000; + return (FIELD_GET(PORT_RESISTANCE_MASK, raw_val) * RESISTANCE_LSB) / 10000; case PORT_RESISTANCE_RSN_LOW: - return (FIELD_GET(PORT_RESISTANCE_MASK, regval) * RESISTANCE_LSB_LOW) / 10000; + return (FIELD_GET(PORT_RESISTANCE_MASK, raw_val) * RESISTANCE_LSB_LOW) / 10000; case PORT_RESISTANCE_RSN_SHORT: case PORT_RESISTANCE_RSN_OPEN: default: -- cgit v1.2.3-59-g8ed1b From 81114fc3d27bf5b06b2137d2fd2b63da656a8b90 Mon Sep 17 00:00:00 2001 From: Eliav Farber Date: Thu, 8 Sep 2022 15:24:30 +0000 Subject: hwmon: (mr75203) fix VM sensor allocation when "intel,vm-map" not defined Bug - in case "intel,vm-map" is missing in device-tree ,'num' is set to 0, and no voltage channel infos are allocated. The reason num is set to 0 when "intel,vm-map" is missing is to set the entire pvt->vm_idx[] with incremental channel numbers, but it didn't take into consideration that same num is used later in devm_kcalloc(). If "intel,vm-map" does exist there is no need to set the unspecified channels with incremental numbers, because the unspecified channels can't be accessed in pvt_read_in() which is the only other place besides the probe functions that uses pvt->vm_idx[]. This change fixes the bug by moving the incremental channel numbers setting to be done only if "intel,vm-map" property is defined (starting loop from 0), and removing 'num = 0'. Fixes: 9d823351a337 ("hwmon: Add hardware monitoring driver for Moortec MR75203 PVT controller") Signed-off-by: Eliav Farber Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220908152449.35457-3-farbere@amazon.com Signed-off-by: Guenter Roeck --- drivers/hwmon/mr75203.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/mr75203.c b/drivers/hwmon/mr75203.c index 26278b0f17a9..8b72e8fe34c1 100644 --- a/drivers/hwmon/mr75203.c +++ b/drivers/hwmon/mr75203.c @@ -584,7 +584,12 @@ static int mr75203_probe(struct platform_device *pdev) ret = device_property_read_u8_array(dev, "intel,vm-map", pvt->vm_idx, vm_num); if (ret) { - num = 0; + /* + * 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; } else { for (i = 0; i < vm_num; i++) if (pvt->vm_idx[i] >= vm_num || @@ -594,13 +599,6 @@ static int mr75203_probe(struct platform_device *pdev) } } - /* - * Incase intel,vm-map property is not defined, we assume - * incremental channel numbers. - */ - for (i = num; i < vm_num; i++) - pvt->vm_idx[i] = i; - in_config = devm_kcalloc(dev, num + 1, sizeof(*in_config), GFP_KERNEL); if (!in_config) -- cgit v1.2.3-59-g8ed1b From bb9195bd6664d94d71647631593e09f705ff5edd Mon Sep 17 00:00:00 2001 From: Eliav Farber Date: Thu, 8 Sep 2022 15:24:31 +0000 Subject: hwmon: (mr75203) update pvt->v_num and vm_num to the actual number of used sensors This issue is relevant when "intel,vm-map" is set in device-tree, and defines a lower number of VMs than actually supported. This change is needed for all places that use pvt->v_num or vm_num later on in the code. Fixes: 9d823351a337 ("hwmon: Add hardware monitoring driver for Moortec MR75203 PVT controller") Signed-off-by: Eliav Farber Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220908152449.35457-4-farbere@amazon.com Signed-off-by: Guenter Roeck --- drivers/hwmon/mr75203.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/mr75203.c b/drivers/hwmon/mr75203.c index 8b72e8fe34c1..be02f32bf143 100644 --- a/drivers/hwmon/mr75203.c +++ b/drivers/hwmon/mr75203.c @@ -595,6 +595,8 @@ static int mr75203_probe(struct platform_device *pdev) if (pvt->vm_idx[i] >= vm_num || pvt->vm_idx[i] == 0xff) { num = i; + pvt->v_num = i; + vm_num = i; break; } } -- cgit v1.2.3-59-g8ed1b From 227a3a2fc31d8e4bb9c88d4804e19530af245b1b Mon Sep 17 00:00:00 2001 From: Eliav Farber Date: Thu, 8 Sep 2022 15:24:32 +0000 Subject: hwmon: (mr75203) fix voltage equation for negative source input According to Moortec Embedded Voltage Monitor (MEVM) series 3 data sheet, the minimum input signal is -100mv and maximum input signal is +1000mv. The equation used to convert the digital word to voltage uses mixed types (*val signed and n unsigned), and on 64 bit machines also has different size, since sizeof(u32) = 4 and sizeof(long) = 8. So when measuring a negative input, n will be small enough, such that PVT_N_CONST * n < PVT_R_CONST, and the result of (PVT_N_CONST * n - PVT_R_CONST) will overflow to a very big positive 32 bit number. Then when storing the result in *val it will be the same value just in 64 bit (instead of it representing a negative number which will what happen when sizeof(long) = 4). When -1023 <= (PVT_N_CONST * n - PVT_R_CONST) <= -1 dividing the number by 1024 should result of in 0, but because ">> 10" is used, and the sign bit is used to fill the vacated bit positions, it results in -1 (0xf...fffff) which is wrong. This change fixes the sign problem and supports negative values by casting n to long and replacing the shift right with div operation. Fixes: 9d823351a337 ("hwmon: Add hardware monitoring driver for Moortec MR75203 PVT controller") Signed-off-by: Eliav Farber Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220908152449.35457-5-farbere@amazon.com Signed-off-by: Guenter Roeck --- drivers/hwmon/mr75203.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/mr75203.c b/drivers/hwmon/mr75203.c index be02f32bf143..6d3b3c499ed8 100644 --- a/drivers/hwmon/mr75203.c +++ b/drivers/hwmon/mr75203.c @@ -201,8 +201,18 @@ static int pvt_read_in(struct device *dev, u32 attr, int channel, long *val) return ret; n &= SAMPLE_DATA_MSK; - /* Convert the N bitstream count into voltage */ - *val = (PVT_N_CONST * n - PVT_R_CONST) >> PVT_CONV_BITS; + /* + * Convert the N bitstream count into voltage. + * To support negative voltage calculation for 64bit machines + * n must be cast to long, since n and *val differ both in + * signedness and in size. + * Division is used instead of right shift, because for signed + * numbers, the sign bit is used to fill the vacated bit + * positions, and if the number is negative, 1 is used. + * BIT(x) may not be used instead of (1 << x) because it's + * unsigned. + */ + *val = (PVT_N_CONST * (long)n - PVT_R_CONST) / (1 << PVT_CONV_BITS); return 0; default: -- cgit v1.2.3-59-g8ed1b From 91a9e063cdcfca8fe642b078d6fae4ce49187975 Mon Sep 17 00:00:00 2001 From: Eliav Farber Date: Thu, 8 Sep 2022 15:24:33 +0000 Subject: hwmon: (mr75203) fix multi-channel voltage reading Fix voltage allocation and reading to support all channels in all VMs. Prior to this change allocation and reading were done only for the first channel in each VM. This change counts the total number of channels for allocation, and takes into account the channel offset when reading the sample data register. Fixes: 9d823351a337 ("hwmon: Add hardware monitoring driver for Moortec MR75203 PVT controller") Signed-off-by: Eliav Farber Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220908152449.35457-6-farbere@amazon.com Signed-off-by: Guenter Roeck --- drivers/hwmon/mr75203.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/mr75203.c b/drivers/hwmon/mr75203.c index 6d3b3c499ed8..812ae40e7d74 100644 --- a/drivers/hwmon/mr75203.c +++ b/drivers/hwmon/mr75203.c @@ -68,8 +68,9 @@ /* VM Individual Macro Register */ #define VM_COM_REG_SIZE 0x200 -#define VM_SDIF_DONE(n) (VM_COM_REG_SIZE + 0x34 + 0x200 * (n)) -#define VM_SDIF_DATA(n) (VM_COM_REG_SIZE + 0x40 + 0x200 * (n)) +#define VM_SDIF_DONE(vm) (VM_COM_REG_SIZE + 0x34 + 0x200 * (vm)) +#define VM_SDIF_DATA(vm, ch) \ + (VM_COM_REG_SIZE + 0x40 + 0x200 * (vm) + 0x4 * (ch)) /* SDA Slave Register */ #define IP_CTRL 0x00 @@ -115,6 +116,7 @@ struct pvt_device { u32 t_num; u32 p_num; u32 v_num; + u32 c_num; u32 ip_freq; u8 *vm_idx; }; @@ -178,14 +180,15 @@ static int pvt_read_in(struct device *dev, u32 attr, int channel, long *val) { struct pvt_device *pvt = dev_get_drvdata(dev); struct regmap *v_map = pvt->v_map; + u8 vm_idx, ch_idx; u32 n, stat; - u8 vm_idx; int ret; - if (channel >= pvt->v_num) + if (channel >= pvt->v_num * pvt->c_num) return -EINVAL; - vm_idx = pvt->vm_idx[channel]; + vm_idx = pvt->vm_idx[channel / pvt->c_num]; + ch_idx = channel % pvt->c_num; switch (attr) { case hwmon_in_input: @@ -196,7 +199,7 @@ static int pvt_read_in(struct device *dev, u32 attr, int channel, long *val) if (ret) return ret; - ret = regmap_read(v_map, VM_SDIF_DATA(vm_idx), &n); + ret = regmap_read(v_map, VM_SDIF_DATA(vm_idx, ch_idx), &n); if(ret < 0) return ret; @@ -499,8 +502,8 @@ static int pvt_reset_control_deassert(struct device *dev, struct pvt_device *pvt static int mr75203_probe(struct platform_device *pdev) { + u32 ts_num, vm_num, pd_num, ch_num, val, index, i; const struct hwmon_channel_info **pvt_info; - u32 ts_num, vm_num, pd_num, val, index, i; struct device *dev = &pdev->dev; u32 *temp_config, *in_config; struct device *hwmon_dev; @@ -541,9 +544,11 @@ static int mr75203_probe(struct platform_device *pdev) ts_num = (val & TS_NUM_MSK) >> TS_NUM_SFT; pd_num = (val & PD_NUM_MSK) >> PD_NUM_SFT; vm_num = (val & VM_NUM_MSK) >> VM_NUM_SFT; + ch_num = (val & CH_NUM_MSK) >> CH_NUM_SFT; 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++; @@ -580,7 +585,7 @@ static int mr75203_probe(struct platform_device *pdev) } if (vm_num) { - u32 num = vm_num; + u32 total_ch; ret = pvt_get_regmap(pdev, "vm", pvt); if (ret) @@ -604,20 +609,20 @@ static int mr75203_probe(struct platform_device *pdev) for (i = 0; i < vm_num; i++) if (pvt->vm_idx[i] >= vm_num || pvt->vm_idx[i] == 0xff) { - num = i; pvt->v_num = i; vm_num = i; break; } } - in_config = devm_kcalloc(dev, num + 1, + total_ch = ch_num * vm_num; + in_config = devm_kcalloc(dev, total_ch + 1, sizeof(*in_config), GFP_KERNEL); if (!in_config) return -ENOMEM; - memset32(in_config, HWMON_I_INPUT, num); - in_config[num] = 0; + memset32(in_config, HWMON_I_INPUT, total_ch); + in_config[total_ch] = 0; pvt_in.config = in_config; pvt_info[index++] = &pvt_in; -- cgit v1.2.3-59-g8ed1b From e43212e0f55dc2d6b15d6c174cc0a64b25fab5e7 Mon Sep 17 00:00:00 2001 From: Eliav Farber Date: Thu, 8 Sep 2022 15:24:34 +0000 Subject: hwmon: (mr75203) enable polling for all VM channels Configure ip-polling register to enable polling for all voltage monitor channels. This enables reading the voltage values for all inputs other than just input 0. Fixes: 9d823351a337 ("hwmon: Add hardware monitoring driver for Moortec MR75203 PVT controller") Signed-off-by: Eliav Farber Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220908152449.35457-7-farbere@amazon.com Signed-off-by: Guenter Roeck --- drivers/hwmon/mr75203.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/mr75203.c b/drivers/hwmon/mr75203.c index 812ae40e7d74..9259779cc2df 100644 --- a/drivers/hwmon/mr75203.c +++ b/drivers/hwmon/mr75203.c @@ -388,6 +388,19 @@ static int pvt_init(struct pvt_device *pvt) if (ret) return ret; + val = (BIT(pvt->c_num) - 1) | VM_CH_INIT | + IP_POLL << SDIF_ADDR_SFT | SDIF_WRN_W | SDIF_PROG; + ret = regmap_write(v_map, SDIF_W, val); + if (ret < 0) + return ret; + + ret = regmap_read_poll_timeout(v_map, SDIF_STAT, + val, !(val & SDIF_BUSY), + PVT_POLL_DELAY_US, + PVT_POLL_TIMEOUT_US); + if (ret) + return ret; + val = CFG1_VOL_MEAS_MODE | CFG1_PARALLEL_OUT | CFG1_14_BIT | IP_CFG << SDIF_ADDR_SFT | SDIF_WRN_W | SDIF_PROG; -- cgit v1.2.3-59-g8ed1b From 88700d1396bae72d9a4c23a48bbd98c1c2f53f3d Mon Sep 17 00:00:00 2001 From: Eugene Shalygin Date: Fri, 9 Sep 2022 17:56:53 +0200 Subject: hwmon: (asus-ec-sensors) autoload module via DMI data Replace autoloading data based on the ACPI EC device with the DMI records for motherboards models. The ACPI method created a bug that when this driver returns error from the probe function because of the unsupported motherboard model, the ACPI subsystem concludes that the EC device does not work properly. Fixes: 5cd29012028d ("hwmon: (asus-ec-sensors) introduce ec_board_info struct for board data") Bug: https://bugzilla.kernel.org/show_bug.cgi?id=216412 Bug: https://bugzilla.redhat.com/show_bug.cgi?id=2121844 Signed-off-by: Eugene Shalygin Link: https://lore.kernel.org/r/20220909155654.123398-2-eugene.shalygin@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Guenter Roeck --- drivers/hwmon/asus-ec-sensors.c | 408 ++++++++++++++++++++++------------------ 1 file changed, 222 insertions(+), 186 deletions(-) (limited to 'drivers/hwmon') diff --git a/drivers/hwmon/asus-ec-sensors.c b/drivers/hwmon/asus-ec-sensors.c index 61a4684fc020..81e688975c6a 100644 --- a/drivers/hwmon/asus-ec-sensors.c +++ b/drivers/hwmon/asus-ec-sensors.c @@ -266,9 +266,7 @@ static const struct ec_sensor_info sensors_family_intel_600[] = { #define SENSOR_SET_WATER_BLOCK \ (SENSOR_TEMP_WATER_BLOCK_IN | SENSOR_TEMP_WATER_BLOCK_OUT) - struct ec_board_info { - const char *board_names[MAX_IDENTICAL_BOARD_VARIATIONS]; unsigned long sensors; /* * Defines which mutex to use for guarding access to the state and the @@ -281,152 +279,194 @@ struct ec_board_info { enum board_family family; }; -static const struct ec_board_info board_info[] = { - { - .board_names = {"PRIME X470-PRO"}, - .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | - SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | - SENSOR_FAN_CPU_OPT | - SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, - .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, - .family = family_amd_400_series, - }, - { - .board_names = {"PRIME X570-PRO"}, - .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | - SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET, - .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, - .family = family_amd_500_series, - }, - { - .board_names = {"ProArt X570-CREATOR WIFI"}, - .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | - SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT | - SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, - }, - { - .board_names = {"Pro WS X570-ACE"}, - .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | - SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET | - SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, - .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, - .family = family_amd_500_series, - }, - { - .board_names = {"ROG CROSSHAIR VIII DARK HERO"}, - .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | - SENSOR_TEMP_T_SENSOR | - SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | - SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW | - SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, - .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, - .family = family_amd_500_series, - }, - { - .board_names = { - "ROG CROSSHAIR VIII FORMULA", - "ROG CROSSHAIR VIII HERO", - "ROG CROSSHAIR VIII HERO (WI-FI)", - }, - .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | - SENSOR_TEMP_T_SENSOR | - SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | - SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | - SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU | - SENSOR_IN_CPU_CORE, - .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, - .family = family_amd_500_series, - }, - { - .board_names = { - "ROG MAXIMUS XI HERO", - "ROG MAXIMUS XI HERO (WI-FI)", - }, - .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | - SENSOR_TEMP_T_SENSOR | - SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | - SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW, - .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, - .family = family_intel_300_series, - }, - { - .board_names = {"ROG CROSSHAIR VIII IMPACT"}, - .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | - SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | - SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | - SENSOR_IN_CPU_CORE, - .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, - .family = family_amd_500_series, - }, - { - .board_names = {"ROG STRIX B550-E GAMING"}, - .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | - SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | - SENSOR_FAN_CPU_OPT, - .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, - .family = family_amd_500_series, - }, - { - .board_names = {"ROG STRIX B550-I GAMING"}, - .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | - SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | - SENSOR_FAN_VRM_HS | SENSOR_CURR_CPU | - SENSOR_IN_CPU_CORE, - .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, - .family = family_amd_500_series, - }, - { - .board_names = {"ROG STRIX X570-E GAMING"}, - .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | - SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | - SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | - SENSOR_IN_CPU_CORE, - .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, - .family = family_amd_500_series, - }, - { - .board_names = {"ROG STRIX X570-E GAMING WIFI II"}, - .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | - SENSOR_TEMP_T_SENSOR | SENSOR_CURR_CPU | - SENSOR_IN_CPU_CORE, - .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, - .family = family_amd_500_series, - }, - { - .board_names = {"ROG STRIX X570-F GAMING"}, - .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | - SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET, - .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, - .family = family_amd_500_series, - }, - { - .board_names = {"ROG STRIX X570-I GAMING"}, - .sensors = SENSOR_TEMP_CHIPSET | SENSOR_TEMP_VRM | - SENSOR_TEMP_T_SENSOR | - SENSOR_FAN_VRM_HS | SENSOR_FAN_CHIPSET | - SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, - .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, - .family = family_amd_500_series, - }, - { - .board_names = {"ROG STRIX Z690-A GAMING WIFI D4"}, - .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM, - .mutex_path = ASUS_HW_ACCESS_MUTEX_RMTW_ASMX, - .family = family_intel_600_series, - }, - { - .board_names = {"ROG ZENITH II EXTREME"}, - .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_T_SENSOR | - SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | - SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | SENSOR_FAN_VRM_HS | - SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE | - SENSOR_SET_WATER_BLOCK | - SENSOR_TEMP_T_SENSOR_2 | SENSOR_TEMP_SENSOR_EXTRA_1 | - SENSOR_TEMP_SENSOR_EXTRA_2 | SENSOR_TEMP_SENSOR_EXTRA_3, - .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0, - .family = family_amd_500_series, - }, - {} +static const struct ec_board_info board_info_prime_x470_pro = { + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | + SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | + SENSOR_FAN_CPU_OPT | + SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, + .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, + .family = family_amd_400_series, +}; + +static const struct ec_board_info board_info_prime_x570_pro = { + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | + SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, +}; + +static const struct ec_board_info board_info_pro_art_x570_creator_wifi = { + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | + SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT | + SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, + .family = family_amd_500_series, +}; + +static const struct ec_board_info board_info_pro_ws_x570_ace = { + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | + SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET | + SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, +}; + +static const struct ec_board_info board_info_crosshair_viii_dark_hero = { + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | + SENSOR_TEMP_T_SENSOR | + SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | + SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW | + SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, +}; + +static const struct ec_board_info board_info_crosshair_viii_hero = { + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | + SENSOR_TEMP_T_SENSOR | + SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | + SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | + SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU | + SENSOR_IN_CPU_CORE, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, +}; + +static const struct ec_board_info board_info_maximus_xi_hero = { + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | + SENSOR_TEMP_T_SENSOR | + SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | + SENSOR_FAN_CPU_OPT | SENSOR_FAN_WATER_FLOW, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_intel_300_series, +}; + +static const struct ec_board_info board_info_crosshair_viii_impact = { + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | + SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | + SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | + SENSOR_IN_CPU_CORE, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, +}; + +static const struct ec_board_info board_info_strix_b550_e_gaming = { + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | + SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | + SENSOR_FAN_CPU_OPT, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, +}; + +static const struct ec_board_info board_info_strix_b550_i_gaming = { + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | + SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | + SENSOR_FAN_VRM_HS | SENSOR_CURR_CPU | + SENSOR_IN_CPU_CORE, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, +}; + +static const struct ec_board_info board_info_strix_x570_e_gaming = { + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | + SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM | + SENSOR_FAN_CHIPSET | SENSOR_CURR_CPU | + SENSOR_IN_CPU_CORE, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, +}; + +static const struct ec_board_info board_info_strix_x570_e_gaming_wifi_ii = { + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | + SENSOR_TEMP_T_SENSOR | SENSOR_CURR_CPU | + SENSOR_IN_CPU_CORE, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, +}; + +static const struct ec_board_info board_info_strix_x570_f_gaming = { + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | + SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CHIPSET, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, +}; + +static const struct ec_board_info board_info_strix_x570_i_gaming = { + .sensors = SENSOR_TEMP_CHIPSET | SENSOR_TEMP_VRM | + SENSOR_TEMP_T_SENSOR | + SENSOR_FAN_VRM_HS | SENSOR_FAN_CHIPSET | + SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE, + .mutex_path = ASUS_HW_ACCESS_MUTEX_ASMX, + .family = family_amd_500_series, +}; + +static const struct ec_board_info board_info_strix_z690_a_gaming_wifi_d4 = { + .sensors = SENSOR_TEMP_T_SENSOR | SENSOR_TEMP_VRM, + .mutex_path = ASUS_HW_ACCESS_MUTEX_RMTW_ASMX, + .family = family_intel_600_series, +}; + +static const struct ec_board_info board_info_zenith_ii_extreme = { + .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_T_SENSOR | + SENSOR_TEMP_VRM | SENSOR_SET_TEMP_WATER | + SENSOR_FAN_CPU_OPT | SENSOR_FAN_CHIPSET | SENSOR_FAN_VRM_HS | + SENSOR_FAN_WATER_FLOW | SENSOR_CURR_CPU | SENSOR_IN_CPU_CORE | + SENSOR_SET_WATER_BLOCK | + SENSOR_TEMP_T_SENSOR_2 | SENSOR_TEMP_SENSOR_EXTRA_1 | + SENSOR_TEMP_SENSOR_EXTRA_2 | SENSOR_TEMP_SENSOR_EXTRA_3, + .mutex_path = ASUS_HW_ACCESS_MUTEX_SB_PCI0_SBRG_SIO1_MUT0, + .family = family_amd_500_series, +}; + +#define DMI_EXACT_MATCH_ASUS_BOARD_NAME(name, board_info) \ + { \ + .matches = { \ + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, \ + "ASUSTeK COMPUTER INC."), \ + DMI_EXACT_MATCH(DMI_BOARD_NAME, name), \ + }, \ + .driver_data = (void *)board_info, \ + } + +static const struct dmi_system_id dmi_table[] = { + DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X470-PRO", + &board_info_prime_x470_pro), + DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X570-PRO", + &board_info_prime_x570_pro), + DMI_EXACT_MATCH_ASUS_BOARD_NAME("ProArt X570-CREATOR WIFI", + &board_info_pro_art_x570_creator_wifi), + DMI_EXACT_MATCH_ASUS_BOARD_NAME("Pro WS X570-ACE", + &board_info_pro_ws_x570_ace), + DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII DARK HERO", + &board_info_crosshair_viii_dark_hero), + DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII FORMULA", + &board_info_crosshair_viii_hero), + DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII HERO", + &board_info_crosshair_viii_hero), + DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII HERO (WI-FI)", + &board_info_crosshair_viii_hero), + DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG MAXIMUS XI HERO", + &board_info_maximus_xi_hero), + DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG MAXIMUS XI HERO (WI-FI)", + &board_info_maximus_xi_hero), + DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG CROSSHAIR VIII IMPACT", + &board_info_crosshair_viii_impact), + DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B550-E GAMING", + &board_info_strix_b550_e_gaming), + DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX B550-I GAMING", + &board_info_strix_b550_i_gaming), + DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-E GAMING", + &board_info_strix_x570_e_gaming), + DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-E GAMING WIFI II", + &board_info_strix_x570_e_gaming_wifi_ii), + DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-F GAMING", + &board_info_strix_x570_f_gaming), + DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX X570-I GAMING", + &board_info_strix_x570_i_gaming), + DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG STRIX Z690-A GAMING WIFI D4", + &board_info_strix_z690_a_gaming_wifi_d4), + DMI_EXACT_MATCH_ASUS_BOARD_NAME("ROG ZENITH II EXTREME", + &board_info_zenith_ii_extreme), + {}, }; struct ec_sensor { @@ -537,12 +577,12 @@ static int find_ec_sensor_index(const struct ec_sensors_data *ec, return -ENOENT; } -static int __init bank_compare(const void *a, const void *b) +static int bank_compare(const void *a, const void *b) { return *((const s8 *)a) - *((const s8 *)b); } -static void __init setup_sensor_data(struct ec_sensors_data *ec) +static void setup_sensor_data(struct ec_sensors_data *ec) { struct ec_sensor *s = ec->sensors; bool bank_found; @@ -574,7 +614,7 @@ static void __init setup_sensor_data(struct ec_sensors_data *ec) sort(ec->banks, ec->nr_banks, 1, bank_compare, NULL); } -static void __init fill_ec_registers(struct ec_sensors_data *ec) +static void fill_ec_registers(struct ec_sensors_data *ec) { const struct ec_sensor_info *si; unsigned int i, j, register_idx = 0; @@ -589,7 +629,7 @@ static void __init fill_ec_registers(struct ec_sensors_data *ec) } } -static int __init setup_lock_data(struct device *dev) +static int setup_lock_data(struct device *dev) { const char *mutex_path; int status; @@ -812,7 +852,7 @@ static umode_t asus_ec_hwmon_is_visible(const void *drvdata, return find_ec_sensor_index(state, type, channel) >= 0 ? S_IRUGO : 0; } -static int __init +static int asus_ec_hwmon_add_chan_info(struct hwmon_channel_info *asus_ec_hwmon_chan, struct device *dev, int num, enum hwmon_sensor_types type, u32 config) @@ -841,27 +881,15 @@ static struct hwmon_chip_info asus_ec_chip_info = { .ops = &asus_ec_hwmon_ops, }; -static const struct ec_board_info * __init get_board_info(void) +static const struct ec_board_info *get_board_info(void) { - const char *dmi_board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR); - const char *dmi_board_name = dmi_get_system_info(DMI_BOARD_NAME); - const struct ec_board_info *board; - - if (!dmi_board_vendor || !dmi_board_name || - strcasecmp(dmi_board_vendor, "ASUSTeK COMPUTER INC.")) - return NULL; - - for (board = board_info; board->sensors; board++) { - if (match_string(board->board_names, - MAX_IDENTICAL_BOARD_VARIATIONS, - dmi_board_name) >= 0) - return board; - } + const struct dmi_system_id *dmi_entry; - return NULL; + dmi_entry = dmi_first_match(dmi_table); + return dmi_entry ? dmi_entry->driver_data : NULL; } -static int __init asus_ec_probe(struct platform_device *pdev) +static int asus_ec_probe(struct platform_device *pdev) { const struct hwmon_channel_info **ptr_asus_ec_ci; int nr_count[hwmon_max] = { 0 }, nr_types = 0; @@ -970,29 +998,37 @@ static int __init asus_ec_probe(struct platform_device *pdev) return PTR_ERR_OR_ZERO(hwdev); } - -static const struct acpi_device_id acpi_ec_ids[] = { - /* Embedded Controller Device */ - { "PNP0C09", 0 }, - {} -}; +MODULE_DEVICE_TABLE(dmi, dmi_table); static struct platform_driver asus_ec_sensors_platform_driver = { .driver = { .name = "asus-ec-sensors", - .acpi_match_table = acpi_ec_ids, }, + .probe = asus_ec_probe, }; -MODULE_DEVICE_TABLE(acpi, acpi_ec_ids); -/* - * we use module_platform_driver_probe() rather than module_platform_driver() - * because the probe function (and its dependants) are marked with __init, which - * means we can't put it into the .probe member of the platform_driver struct - * above, and we can't mark the asus_ec_sensors_platform_driver object as __init - * because the object is referenced from the module exit code. - */ -module_platform_driver_probe(asus_ec_sensors_platform_driver, asus_ec_probe); +static struct platform_device *asus_ec_sensors_platform_device; + +static int __init asus_ec_init(void) +{ + asus_ec_sensors_platform_device = + platform_create_bundle(&asus_ec_sensors_platform_driver, + asus_ec_probe, NULL, 0, NULL, 0); + + if (IS_ERR(asus_ec_sensors_platform_device)) + return PTR_ERR(asus_ec_sensors_platform_device); + + return 0; +} + +static void __exit asus_ec_exit(void) +{ + platform_device_unregister(asus_ec_sensors_platform_device); + platform_driver_unregister(&asus_ec_sensors_platform_driver); +} + +module_init(asus_ec_init); +module_exit(asus_ec_exit); module_param_named(mutex_path, mutex_path_override, charp, 0); MODULE_PARM_DESC(mutex_path, -- cgit v1.2.3-59-g8ed1b