lkml.org 
[lkml]   [2019]   [May]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 158/276] hwmon: (smsc47m1) Use request_muxed_region for Super-IO accesses
    Date
    [ Upstream commit d6410408ad2a798c4cc685252c1baa713be0ad69 ]

    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/smsc47m1.c | 28 +++++++++++++++++++---------
    1 file changed, 19 insertions(+), 9 deletions(-)

    diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
    index c7b6a425e2c02..5eeac9853d0ae 100644
    --- a/drivers/hwmon/smsc47m1.c
    +++ b/drivers/hwmon/smsc47m1.c
    @@ -73,16 +73,21 @@ superio_inb(int reg)
    /* logical device for fans is 0x0A */
    #define superio_select() superio_outb(0x07, 0x0A)

    -static inline 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_ACT 0x30
    @@ -531,8 +536,12 @@ static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data)
    {
    u8 val;
    unsigned short addr;
    + int err;
    +
    + err = superio_enter();
    + if (err)
    + return err;

    - superio_enter();
    val = force_id ? force_id : superio_inb(SUPERIO_REG_DEVID);

    /*
    @@ -608,13 +617,14 @@ static int __init smsc47m1_find(struct smsc47m1_sio_data *sio_data)
    static void smsc47m1_restore(const struct smsc47m1_sio_data *sio_data)
    {
    if ((sio_data->activate & 0x01) == 0) {
    - superio_enter();
    - superio_select();
    -
    - pr_info("Disabling device\n");
    - superio_outb(SUPERIO_REG_ACT, sio_data->activate);
    -
    - superio_exit();
    + if (!superio_enter()) {
    + superio_select();
    + pr_info("Disabling device\n");
    + superio_outb(SUPERIO_REG_ACT, sio_data->activate);
    + superio_exit();
    + } else {
    + pr_warn("Failed to disable device\n");
    + }
    }
    }

    --
    2.20.1


    \
     
     \ /
      Last update: 2019-05-30 06:09    [W:4.413 / U:0.156 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site