| From 056e4008ea95bfc4da7d8efab09fe2d779d9329f Mon Sep 17 00:00:00 2001 |
| From: Guenter Roeck <linux@roeck-us.net> |
| Date: Thu, 4 Apr 2019 11:22:42 -0700 |
| Subject: hwmon: (smsc47b397) Use request_muxed_region for Super-IO accesses |
| |
| [ Upstream commit 8c0826756744c0ac1df600a5e4cca1a341b13101 ] |
| |
| Super-IO accesses may fail on a system with no or unmapped LPC bus. |
| |
| Also, other drivers may attempt to access the LPC bus at the same time, |
| resulting in undefined behavior. |
| |
| Use request_muxed_region() to ensure that IO access on the requested |
| address space is supported, and to ensure that access by multiple drivers |
| is synchronized. |
| |
| Fixes: 8d5d45fb1468 ("I2C: Move hwmon drivers (2/3)") |
| Reported-by: Kefeng Wang <wangkefeng.wang@huawei.com> |
| Reported-by: John Garry <john.garry@huawei.com> |
| Cc: John Garry <john.garry@huawei.com> |
| Acked-by: John Garry <john.garry@huawei.com> |
| Signed-off-by: Guenter Roeck <linux@roeck-us.net> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/hwmon/smsc47b397.c | 13 +++++++++++-- |
| 1 file changed, 11 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c |
| index 6bd2007565603..cbdb5c4991ae3 100644 |
| --- a/drivers/hwmon/smsc47b397.c |
| +++ b/drivers/hwmon/smsc47b397.c |
| @@ -72,14 +72,19 @@ static inline void superio_select(int ld) |
| superio_outb(0x07, ld); |
| } |
| |
| -static inline void superio_enter(void) |
| +static inline int superio_enter(void) |
| { |
| + if (!request_muxed_region(REG, 2, DRVNAME)) |
| + return -EBUSY; |
| + |
| outb(0x55, REG); |
| + return 0; |
| } |
| |
| static inline void superio_exit(void) |
| { |
| outb(0xAA, REG); |
| + release_region(REG, 2); |
| } |
| |
| #define SUPERIO_REG_DEVID 0x20 |
| @@ -300,8 +305,12 @@ static int __init smsc47b397_find(void) |
| u8 id, rev; |
| char *name; |
| unsigned short addr; |
| + int err; |
| + |
| + err = superio_enter(); |
| + if (err) |
| + return err; |
| |
| - superio_enter(); |
| id = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID); |
| |
| switch (id) { |
| -- |
| 2.20.1 |
| |