1 From 396bccc5f60d886c07ad9d5e00347909367632f3 Mon Sep 17 00:00:00 2001
2 From: Guenter Roeck <linux@roeck-us.net>
3 Date: Thu, 4 Apr 2019 11:28:37 -0700
4 Subject: hwmon: (smsc47m1) Use request_muxed_region for Super-IO accesses
6 [ Upstream commit d6410408ad2a798c4cc685252c1baa713be0ad69 ]
8 Super-IO accesses may fail on a system with no or unmapped LPC bus.
10 Also, other drivers may attempt to access the LPC bus at the same time,
11 resulting in undefined behavior.
13 Use request_muxed_region() to ensure that IO access on the requested
14 address space is supported, and to ensure that access by multiple drivers
17 Fixes: 8d5d45fb1468 ("I2C: Move hwmon drivers (2/3)")
18 Reported-by: Kefeng Wang <wangkefeng.wang@huawei.com>
19 Reported-by: John Garry <john.garry@huawei.com>
20 Cc: John Garry <john.garry@huawei.com>
21 Acked-by: John Garry <john.garry@huawei.com>
22 Signed-off-by: Guenter Roeck <linux@roeck-us.net>
23 Signed-off-by: Sasha Levin <sashal@kernel.org>
25 drivers/hwmon/smsc47m1.c | 28 +++++++++++++++++++---------
26 1 file changed, 19 insertions(+), 9 deletions(-)
28 diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
29 index 5d323186d2c10..d24df0c50bea4 100644
30 --- a/drivers/hwmon/smsc47m1.c
31 +++ b/drivers/hwmon/smsc47m1.c
32 @@ -73,16 +73,21 @@ superio_inb(int reg)
33 /* logical device for fans is 0x0A */
34 #define superio_select() superio_outb(0x07, 0x0A)
40 + if (!request_muxed_region(REG, 2, DRVNAME))
51 + release_region(REG, 2);
54 #define SUPERIO_REG_ACT 0x30
55 @@ -531,8 +536,12 @@ static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data)
61 + err = superio_enter();
66 val = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);
69 @@ -608,13 +617,14 @@ static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data)
70 static void smsc47m1_restore(const struct smsc47m1_sio_data *sio_data)
72 if ((sio_data->activate & 0x01) == 0) {
76 - pr_info("Disabling device\n");
77 - superio_outb(SUPERIO_REG_ACT, sio_data->activate);
80 + if (!superio_enter()) {
82 + pr_info("Disabling device\n");
83 + superio_outb(SUPERIO_REG_ACT, sio_data->activate);
86 + pr_warn("Failed to disable device\n");