]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.4/hwmon-smsc47m1-use-request_muxed_region-for-super-io.patch
drop rdma-cma-consider-scope_id-while-binding-to-ipv6-ll-.patch from 4.4, 4.9, and...
[thirdparty/kernel/stable-queue.git] / queue-4.4 / hwmon-smsc47m1-use-request_muxed_region-for-super-io.patch
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
5
6 [ Upstream commit d6410408ad2a798c4cc685252c1baa713be0ad69 ]
7
8 Super-IO accesses may fail on a system with no or unmapped LPC bus.
9
10 Also, other drivers may attempt to access the LPC bus at the same time,
11 resulting in undefined behavior.
12
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
15 is synchronized.
16
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>
24 ---
25 drivers/hwmon/smsc47m1.c | 28 +++++++++++++++++++---------
26 1 file changed, 19 insertions(+), 9 deletions(-)
27
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)
35
36 -static inline void
37 +static inline int
38 superio_enter(void)
39 {
40 + if (!request_muxed_region(REG, 2, DRVNAME))
41 + return -EBUSY;
42 +
43 outb(0x55, REG);
44 + return 0;
45 }
46
47 static inline void
48 superio_exit(void)
49 {
50 outb(0xAA, REG);
51 + release_region(REG, 2);
52 }
53
54 #define SUPERIO_REG_ACT 0x30
55 @@ -531,8 +536,12 @@ static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data)
56 {
57 u8 val;
58 unsigned short addr;
59 + int err;
60 +
61 + err = superio_enter();
62 + if (err)
63 + return err;
64
65 - superio_enter();
66 val = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);
67
68 /*
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)
71 {
72 if ((sio_data->activate & 0x01) == 0) {
73 - superio_enter();
74 - superio_select();
75 -
76 - pr_info("Disabling device\n");
77 - superio_outb(SUPERIO_REG_ACT, sio_data->activate);
78 -
79 - superio_exit();
80 + if (!superio_enter()) {
81 + superio_select();
82 + pr_info("Disabling device\n");
83 + superio_outb(SUPERIO_REG_ACT, sio_data->activate);
84 + superio_exit();
85 + } else {
86 + pr_warn("Failed to disable device\n");
87 + }
88 }
89 }
90
91 --
92 2.20.1
93