diff options
| -rw-r--r-- | drivers/hwmon/f71882fg.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 537841ef44b9..75afb3b0e076 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c | |||
| @@ -111,7 +111,7 @@ static struct platform_device *f71882fg_pdev; | |||
| 111 | /* Super-I/O Function prototypes */ | 111 | /* Super-I/O Function prototypes */ |
| 112 | static inline int superio_inb(int base, int reg); | 112 | static inline int superio_inb(int base, int reg); |
| 113 | static inline int superio_inw(int base, int reg); | 113 | static inline int superio_inw(int base, int reg); |
| 114 | static inline void superio_enter(int base); | 114 | static inline int superio_enter(int base); |
| 115 | static inline void superio_select(int base, int ld); | 115 | static inline void superio_select(int base, int ld); |
| 116 | static inline void superio_exit(int base); | 116 | static inline void superio_exit(int base); |
| 117 | 117 | ||
| @@ -861,11 +861,20 @@ static int superio_inw(int base, int reg) | |||
| 861 | return val; | 861 | return val; |
| 862 | } | 862 | } |
| 863 | 863 | ||
| 864 | static inline void superio_enter(int base) | 864 | static inline int superio_enter(int base) |
| 865 | { | 865 | { |
| 866 | /* Don't step on other drivers' I/O space by accident */ | ||
| 867 | if (!request_muxed_region(base, 2, DRVNAME)) { | ||
| 868 | printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n", | ||
| 869 | base); | ||
| 870 | return -EBUSY; | ||
| 871 | } | ||
| 872 | |||
| 866 | /* according to the datasheet the key must be send twice! */ | 873 | /* according to the datasheet the key must be send twice! */ |
| 867 | outb(SIO_UNLOCK_KEY, base); | 874 | outb(SIO_UNLOCK_KEY, base); |
| 868 | outb(SIO_UNLOCK_KEY, base); | 875 | outb(SIO_UNLOCK_KEY, base); |
| 876 | |||
| 877 | return 0; | ||
| 869 | } | 878 | } |
| 870 | 879 | ||
| 871 | static inline void superio_select(int base, int ld) | 880 | static inline void superio_select(int base, int ld) |
| @@ -877,6 +886,7 @@ static inline void superio_select(int base, int ld) | |||
| 877 | static inline void superio_exit(int base) | 886 | static inline void superio_exit(int base) |
| 878 | { | 887 | { |
| 879 | outb(SIO_LOCK_KEY, base); | 888 | outb(SIO_LOCK_KEY, base); |
| 889 | release_region(base, 2); | ||
| 880 | } | 890 | } |
| 881 | 891 | ||
| 882 | static inline int fan_from_reg(u16 reg) | 892 | static inline int fan_from_reg(u16 reg) |
| @@ -2175,21 +2185,15 @@ static int f71882fg_remove(struct platform_device *pdev) | |||
| 2175 | static int __init f71882fg_find(int sioaddr, unsigned short *address, | 2185 | static int __init f71882fg_find(int sioaddr, unsigned short *address, |
| 2176 | struct f71882fg_sio_data *sio_data) | 2186 | struct f71882fg_sio_data *sio_data) |
| 2177 | { | 2187 | { |
| 2178 | int err = -ENODEV; | ||
| 2179 | u16 devid; | 2188 | u16 devid; |
| 2180 | 2189 | int err = superio_enter(sioaddr); | |
| 2181 | /* Don't step on other drivers' I/O space by accident */ | 2190 | if (err) |
| 2182 | if (!request_region(sioaddr, 2, DRVNAME)) { | 2191 | return err; |
| 2183 | printk(KERN_ERR DRVNAME ": I/O address 0x%04x already in use\n", | ||
| 2184 | (int)sioaddr); | ||
| 2185 | return -EBUSY; | ||
| 2186 | } | ||
| 2187 | |||
| 2188 | superio_enter(sioaddr); | ||
| 2189 | 2192 | ||
| 2190 | devid = superio_inw(sioaddr, SIO_REG_MANID); | 2193 | devid = superio_inw(sioaddr, SIO_REG_MANID); |
| 2191 | if (devid != SIO_FINTEK_ID) { | 2194 | if (devid != SIO_FINTEK_ID) { |
| 2192 | pr_debug(DRVNAME ": Not a Fintek device\n"); | 2195 | pr_debug(DRVNAME ": Not a Fintek device\n"); |
| 2196 | err = -ENODEV; | ||
| 2193 | goto exit; | 2197 | goto exit; |
| 2194 | } | 2198 | } |
| 2195 | 2199 | ||
| @@ -2213,6 +2217,7 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
| 2213 | default: | 2217 | default: |
| 2214 | printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n", | 2218 | printk(KERN_INFO DRVNAME ": Unsupported Fintek device: %04x\n", |
| 2215 | (unsigned int)devid); | 2219 | (unsigned int)devid); |
| 2220 | err = -ENODEV; | ||
| 2216 | goto exit; | 2221 | goto exit; |
| 2217 | } | 2222 | } |
| 2218 | 2223 | ||
| @@ -2223,12 +2228,14 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
| 2223 | 2228 | ||
| 2224 | if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { | 2229 | if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { |
| 2225 | printk(KERN_WARNING DRVNAME ": Device not activated\n"); | 2230 | printk(KERN_WARNING DRVNAME ": Device not activated\n"); |
| 2231 | err = -ENODEV; | ||
| 2226 | goto exit; | 2232 | goto exit; |
| 2227 | } | 2233 | } |
| 2228 | 2234 | ||
| 2229 | *address = superio_inw(sioaddr, SIO_REG_ADDR); | 2235 | *address = superio_inw(sioaddr, SIO_REG_ADDR); |
| 2230 | if (*address == 0) { | 2236 | if (*address == 0) { |
| 2231 | printk(KERN_WARNING DRVNAME ": Base address not set\n"); | 2237 | printk(KERN_WARNING DRVNAME ": Base address not set\n"); |
| 2238 | err = -ENODEV; | ||
| 2232 | goto exit; | 2239 | goto exit; |
| 2233 | } | 2240 | } |
| 2234 | *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ | 2241 | *address &= ~(REGION_LENGTH - 1); /* Ignore 3 LSB */ |
| @@ -2239,7 +2246,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
| 2239 | (int)superio_inb(sioaddr, SIO_REG_DEVREV)); | 2246 | (int)superio_inb(sioaddr, SIO_REG_DEVREV)); |
| 2240 | exit: | 2247 | exit: |
| 2241 | superio_exit(sioaddr); | 2248 | superio_exit(sioaddr); |
| 2242 | release_region(sioaddr, 2); | ||
| 2243 | return err; | 2249 | return err; |
| 2244 | } | 2250 | } |
| 2245 | 2251 | ||
