diff options
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/busses/Kconfig | 11 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-ali1535.c | 4 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-amd756-s4882.c | 13 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-frodo.c | 85 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-isa.c | 2 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-ite.c | 4 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-ixp4xx.c | 1 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-piix4.c | 4 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-pxa.c | 2 | ||||
| -rw-r--r-- | drivers/i2c/busses/scx200_acb.c | 283 | ||||
| -rw-r--r-- | drivers/i2c/chips/ds1374.c | 11 | ||||
| -rw-r--r-- | drivers/i2c/chips/eeprom.c | 9 | ||||
| -rw-r--r-- | drivers/i2c/chips/isp1301_omap.c | 2 | ||||
| -rw-r--r-- | drivers/i2c/chips/m41t00.c | 11 | ||||
| -rw-r--r-- | drivers/i2c/chips/max6875.c | 10 | ||||
| -rw-r--r-- | drivers/i2c/chips/pcf8591.c | 13 | ||||
| -rw-r--r-- | drivers/i2c/chips/tps65010.c | 45 | ||||
| -rw-r--r-- | drivers/i2c/i2c-core.c | 81 |
18 files changed, 250 insertions, 341 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index ff92735c7c85..089c6f5b24de 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
| @@ -168,12 +168,14 @@ config I2C_PIIX4 | |||
| 168 | help | 168 | help |
| 169 | If you say yes to this option, support will be included for the Intel | 169 | If you say yes to this option, support will be included for the Intel |
| 170 | PIIX4 family of mainboard I2C interfaces. Specifically, the following | 170 | PIIX4 family of mainboard I2C interfaces. Specifically, the following |
| 171 | versions of the chipset are supported: | 171 | versions of the chipset are supported (note that Serverworks is part |
| 172 | of Broadcom): | ||
| 172 | Intel PIIX4 | 173 | Intel PIIX4 |
| 173 | Intel 440MX | 174 | Intel 440MX |
| 174 | Serverworks OSB4 | 175 | Serverworks OSB4 |
| 175 | Serverworks CSB5 | 176 | Serverworks CSB5 |
| 176 | Serverworks CSB6 | 177 | Serverworks CSB6 |
| 178 | Serverworks HT-1000 | ||
| 177 | SMSC Victory66 | 179 | SMSC Victory66 |
| 178 | 180 | ||
| 179 | This driver can also be built as a module. If so, the module | 181 | This driver can also be built as a module. If so, the module |
| @@ -389,10 +391,11 @@ config SCx200_I2C_SDA | |||
| 389 | also be specified with a module parameter. | 391 | also be specified with a module parameter. |
| 390 | 392 | ||
| 391 | config SCx200_ACB | 393 | config SCx200_ACB |
| 392 | tristate "NatSemi SCx200 ACCESS.bus" | 394 | tristate "Geode ACCESS.bus support" |
| 393 | depends on I2C && PCI | 395 | depends on X86_32 && I2C && PCI |
| 394 | help | 396 | help |
| 395 | Enable the use of the ACCESS.bus controllers of a SCx200 processor. | 397 | Enable the use of the ACCESS.bus controllers on the Geode SCx200 and |
| 398 | SC1100 processors and the CS5535 and CS5536 Geode companion devices. | ||
| 396 | 399 | ||
| 397 | If you don't know what to do here, say N. | 400 | If you don't know what to do here, say N. |
| 398 | 401 | ||
diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index 3eb47890db40..d3ef46aeeb3c 100644 --- a/drivers/i2c/busses/i2c-ali1535.c +++ b/drivers/i2c/busses/i2c-ali1535.c | |||
| @@ -63,7 +63,6 @@ | |||
| 63 | #include <linux/i2c.h> | 63 | #include <linux/i2c.h> |
| 64 | #include <linux/init.h> | 64 | #include <linux/init.h> |
| 65 | #include <asm/io.h> | 65 | #include <asm/io.h> |
| 66 | #include <asm/semaphore.h> | ||
| 67 | 66 | ||
| 68 | 67 | ||
| 69 | /* ALI1535 SMBus address offsets */ | 68 | /* ALI1535 SMBus address offsets */ |
| @@ -136,7 +135,6 @@ | |||
| 136 | 135 | ||
| 137 | static struct pci_driver ali1535_driver; | 136 | static struct pci_driver ali1535_driver; |
| 138 | static unsigned short ali1535_smba; | 137 | static unsigned short ali1535_smba; |
| 139 | static DECLARE_MUTEX(i2c_ali1535_sem); | ||
| 140 | 138 | ||
| 141 | /* Detect whether a ALI1535 can be found, and initialize it, where necessary. | 139 | /* Detect whether a ALI1535 can be found, and initialize it, where necessary. |
| 142 | Note the differences between kernels with the old PCI BIOS interface and | 140 | Note the differences between kernels with the old PCI BIOS interface and |
| @@ -345,7 +343,6 @@ static s32 ali1535_access(struct i2c_adapter *adap, u16 addr, | |||
| 345 | int timeout; | 343 | int timeout; |
| 346 | s32 result = 0; | 344 | s32 result = 0; |
| 347 | 345 | ||
| 348 | down(&i2c_ali1535_sem); | ||
| 349 | /* make sure SMBus is idle */ | 346 | /* make sure SMBus is idle */ |
| 350 | temp = inb_p(SMBHSTSTS); | 347 | temp = inb_p(SMBHSTSTS); |
| 351 | for (timeout = 0; | 348 | for (timeout = 0; |
| @@ -460,7 +457,6 @@ static s32 ali1535_access(struct i2c_adapter *adap, u16 addr, | |||
| 460 | break; | 457 | break; |
| 461 | } | 458 | } |
| 462 | EXIT: | 459 | EXIT: |
| 463 | up(&i2c_ali1535_sem); | ||
| 464 | return result; | 460 | return result; |
| 465 | } | 461 | } |
| 466 | 462 | ||
diff --git a/drivers/i2c/busses/i2c-amd756-s4882.c b/drivers/i2c/busses/i2c-amd756-s4882.c index 56c7d987590f..08e915730caf 100644 --- a/drivers/i2c/busses/i2c-amd756-s4882.c +++ b/drivers/i2c/busses/i2c-amd756-s4882.c | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
| 39 | #include <linux/init.h> | 39 | #include <linux/init.h> |
| 40 | #include <linux/i2c.h> | 40 | #include <linux/i2c.h> |
| 41 | #include <linux/mutex.h> | ||
| 41 | 42 | ||
| 42 | extern struct i2c_adapter amd756_smbus; | 43 | extern struct i2c_adapter amd756_smbus; |
| 43 | 44 | ||
| @@ -45,7 +46,7 @@ static struct i2c_adapter *s4882_adapter; | |||
| 45 | static struct i2c_algorithm *s4882_algo; | 46 | static struct i2c_algorithm *s4882_algo; |
| 46 | 47 | ||
| 47 | /* Wrapper access functions for multiplexed SMBus */ | 48 | /* Wrapper access functions for multiplexed SMBus */ |
| 48 | static struct semaphore amd756_lock; | 49 | static DEFINE_MUTEX(amd756_lock); |
| 49 | 50 | ||
| 50 | static s32 amd756_access_virt0(struct i2c_adapter * adap, u16 addr, | 51 | static s32 amd756_access_virt0(struct i2c_adapter * adap, u16 addr, |
| 51 | unsigned short flags, char read_write, | 52 | unsigned short flags, char read_write, |
| @@ -59,12 +60,12 @@ static s32 amd756_access_virt0(struct i2c_adapter * adap, u16 addr, | |||
| 59 | || addr == 0x18) | 60 | || addr == 0x18) |
| 60 | return -1; | 61 | return -1; |
| 61 | 62 | ||
| 62 | down(&amd756_lock); | 63 | mutex_lock(&amd756_lock); |
| 63 | 64 | ||
| 64 | error = amd756_smbus.algo->smbus_xfer(adap, addr, flags, read_write, | 65 | error = amd756_smbus.algo->smbus_xfer(adap, addr, flags, read_write, |
| 65 | command, size, data); | 66 | command, size, data); |
| 66 | 67 | ||
| 67 | up(&amd756_lock); | 68 | mutex_unlock(&amd756_lock); |
| 68 | 69 | ||
| 69 | return error; | 70 | return error; |
| 70 | } | 71 | } |
| @@ -87,7 +88,7 @@ static inline s32 amd756_access_channel(struct i2c_adapter * adap, u16 addr, | |||
| 87 | if (addr != 0x4c && (addr & 0xfc) != 0x50 && (addr & 0xfc) != 0x30) | 88 | if (addr != 0x4c && (addr & 0xfc) != 0x50 && (addr & 0xfc) != 0x30) |
| 88 | return -1; | 89 | return -1; |
| 89 | 90 | ||
| 90 | down(&amd756_lock); | 91 | mutex_lock(&amd756_lock); |
| 91 | 92 | ||
| 92 | if (last_channels != channels) { | 93 | if (last_channels != channels) { |
| 93 | union i2c_smbus_data mplxdata; | 94 | union i2c_smbus_data mplxdata; |
| @@ -105,7 +106,7 @@ static inline s32 amd756_access_channel(struct i2c_adapter * adap, u16 addr, | |||
| 105 | command, size, data); | 106 | command, size, data); |
| 106 | 107 | ||
| 107 | UNLOCK: | 108 | UNLOCK: |
| 108 | up(&amd756_lock); | 109 | mutex_unlock(&amd756_lock); |
| 109 | return error; | 110 | return error; |
| 110 | } | 111 | } |
| 111 | 112 | ||
| @@ -166,8 +167,6 @@ static int __init amd756_s4882_init(void) | |||
| 166 | } | 167 | } |
| 167 | 168 | ||
| 168 | printk(KERN_INFO "Enabling SMBus multiplexing for Tyan S4882\n"); | 169 | printk(KERN_INFO "Enabling SMBus multiplexing for Tyan S4882\n"); |
| 169 | init_MUTEX(&amd756_lock); | ||
| 170 | |||
| 171 | /* Define the 5 virtual adapters and algorithms structures */ | 170 | /* Define the 5 virtual adapters and algorithms structures */ |
| 172 | if (!(s4882_adapter = kzalloc(5 * sizeof(struct i2c_adapter), | 171 | if (!(s4882_adapter = kzalloc(5 * sizeof(struct i2c_adapter), |
| 173 | GFP_KERNEL))) { | 172 | GFP_KERNEL))) { |
diff --git a/drivers/i2c/busses/i2c-frodo.c b/drivers/i2c/busses/i2c-frodo.c deleted file mode 100644 index b6f52f5a4138..000000000000 --- a/drivers/i2c/busses/i2c-frodo.c +++ /dev/null | |||
| @@ -1,85 +0,0 @@ | |||
| 1 | |||
| 2 | /* | ||
| 3 | * linux/drivers/i2c/i2c-frodo.c | ||
| 4 | * | ||
| 5 | * Author: Abraham van der Merwe <abraham@2d3d.co.za> | ||
| 6 | * | ||
| 7 | * An I2C adapter driver for the 2d3D, Inc. StrongARM SA-1110 | ||
| 8 | * Development board (Frodo). | ||
| 9 | * | ||
| 10 | * This source code is free software; you can redistribute it and/or | ||
| 11 | * modify it under the terms of the GNU General Public License | ||
| 12 | * version 2 as published by the Free Software Foundation. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/init.h> | ||
| 18 | #include <linux/delay.h> | ||
| 19 | #include <linux/i2c.h> | ||
| 20 | #include <linux/i2c-algo-bit.h> | ||
| 21 | #include <asm/hardware.h> | ||
| 22 | |||
| 23 | |||
| 24 | static void frodo_setsda (void *data,int state) | ||
| 25 | { | ||
| 26 | if (state) | ||
| 27 | FRODO_CPLD_I2C |= FRODO_I2C_SDA_OUT; | ||
| 28 | else | ||
| 29 | FRODO_CPLD_I2C &= ~FRODO_I2C_SDA_OUT; | ||
| 30 | } | ||
| 31 | |||
| 32 | static void frodo_setscl (void *data,int state) | ||
| 33 | { | ||
| 34 | if (state) | ||
| 35 | FRODO_CPLD_I2C |= FRODO_I2C_SCL_OUT; | ||
| 36 | else | ||
| 37 | FRODO_CPLD_I2C &= ~FRODO_I2C_SCL_OUT; | ||
| 38 | } | ||
| 39 | |||
| 40 | static int frodo_getsda (void *data) | ||
| 41 | { | ||
| 42 | return ((FRODO_CPLD_I2C & FRODO_I2C_SDA_IN) != 0); | ||
| 43 | } | ||
| 44 | |||
| 45 | static int frodo_getscl (void *data) | ||
| 46 | { | ||
| 47 | return ((FRODO_CPLD_I2C & FRODO_I2C_SCL_IN) != 0); | ||
| 48 | } | ||
| 49 | |||
| 50 | static struct i2c_algo_bit_data bit_frodo_data = { | ||
| 51 | .setsda = frodo_setsda, | ||
| 52 | .setscl = frodo_setscl, | ||
| 53 | .getsda = frodo_getsda, | ||
| 54 | .getscl = frodo_getscl, | ||
| 55 | .udelay = 80, | ||
| 56 | .mdelay = 80, | ||
| 57 | .timeout = HZ | ||
| 58 | }; | ||
| 59 | |||
| 60 | static struct i2c_adapter frodo_ops = { | ||
| 61 | .owner = THIS_MODULE, | ||
| 62 | .id = I2C_HW_B_FRODO, | ||
| 63 | .algo_data = &bit_frodo_data, | ||
| 64 | .dev = { | ||
| 65 | .name = "Frodo adapter driver", | ||
| 66 | }, | ||
| 67 | }; | ||
| 68 | |||
| 69 | static int __init i2c_frodo_init (void) | ||
| 70 | { | ||
| 71 | return i2c_bit_add_bus(&frodo_ops); | ||
| 72 | } | ||
| 73 | |||
| 74 | static void __exit i2c_frodo_exit (void) | ||
| 75 | { | ||
| 76 | i2c_bit_del_bus(&frodo_ops); | ||
| 77 | } | ||
| 78 | |||
| 79 | MODULE_AUTHOR ("Abraham van der Merwe <abraham@2d3d.co.za>"); | ||
| 80 | MODULE_DESCRIPTION ("I2C-Bus adapter routines for Frodo"); | ||
| 81 | MODULE_LICENSE ("GPL"); | ||
| 82 | |||
| 83 | module_init (i2c_frodo_init); | ||
| 84 | module_exit (i2c_frodo_exit); | ||
| 85 | |||
diff --git a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c index 4344ae6b1fcb..c3e1d3e888d7 100644 --- a/drivers/i2c/busses/i2c-isa.c +++ b/drivers/i2c/busses/i2c-isa.c | |||
| @@ -125,7 +125,7 @@ int i2c_isa_del_driver(struct i2c_driver *driver) | |||
| 125 | 125 | ||
| 126 | static int __init i2c_isa_init(void) | 126 | static int __init i2c_isa_init(void) |
| 127 | { | 127 | { |
| 128 | init_MUTEX(&isa_adapter.clist_lock); | 128 | mutex_init(&isa_adapter.clist_lock); |
| 129 | INIT_LIST_HEAD(&isa_adapter.clients); | 129 | INIT_LIST_HEAD(&isa_adapter.clients); |
| 130 | 130 | ||
| 131 | isa_adapter.nr = ANY_I2C_ISA_BUS; | 131 | isa_adapter.nr = ANY_I2C_ISA_BUS; |
diff --git a/drivers/i2c/busses/i2c-ite.c b/drivers/i2c/busses/i2c-ite.c index 5f5d2944808b..d82e6dae8407 100644 --- a/drivers/i2c/busses/i2c-ite.c +++ b/drivers/i2c/busses/i2c-ite.c | |||
| @@ -200,9 +200,7 @@ static struct i2c_adapter iic_ite_ops = { | |||
| 200 | .owner = THIS_MODULE, | 200 | .owner = THIS_MODULE, |
| 201 | .id = I2C_HW_I_IIC, | 201 | .id = I2C_HW_I_IIC, |
| 202 | .algo_data = &iic_ite_data, | 202 | .algo_data = &iic_ite_data, |
| 203 | .dev = { | 203 | .name = "ITE IIC adapter", |
| 204 | .name = "ITE IIC adapter", | ||
| 205 | }, | ||
| 206 | }; | 204 | }; |
| 207 | 205 | ||
| 208 | /* Called when the module is loaded. This function starts the | 206 | /* Called when the module is loaded. This function starts the |
diff --git a/drivers/i2c/busses/i2c-ixp4xx.c b/drivers/i2c/busses/i2c-ixp4xx.c index e422d8b2d4d6..2ed07112d683 100644 --- a/drivers/i2c/busses/i2c-ixp4xx.c +++ b/drivers/i2c/busses/i2c-ixp4xx.c | |||
| @@ -126,6 +126,7 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev) | |||
| 126 | drv_data->algo_data.timeout = 100; | 126 | drv_data->algo_data.timeout = 100; |
| 127 | 127 | ||
| 128 | drv_data->adapter.id = I2C_HW_B_IXP4XX; | 128 | drv_data->adapter.id = I2C_HW_B_IXP4XX; |
| 129 | drv_data->adapter.class = I2C_CLASS_HWMON; | ||
| 129 | strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name, | 130 | strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name, |
| 130 | I2C_NAME_SIZE); | 131 | I2C_NAME_SIZE); |
| 131 | drv_data->adapter.algo_data = &drv_data->algo_data; | 132 | drv_data->adapter.algo_data = &drv_data->algo_data; |
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 692f47345481..d9c7c00e71f9 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | /* | 22 | /* |
| 23 | Supports: | 23 | Supports: |
| 24 | Intel PIIX4, 440MX | 24 | Intel PIIX4, 440MX |
| 25 | Serverworks OSB4, CSB5, CSB6 | 25 | Serverworks OSB4, CSB5, CSB6, HT-1000 |
| 26 | SMSC Victory66 | 26 | SMSC Victory66 |
| 27 | 27 | ||
| 28 | Note: we assume there can only be one device, with one SMBus interface. | 28 | Note: we assume there can only be one device, with one SMBus interface. |
| @@ -419,6 +419,8 @@ static struct pci_device_id piix4_ids[] = { | |||
| 419 | .driver_data = 0 }, | 419 | .driver_data = 0 }, |
| 420 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6), | 420 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6), |
| 421 | .driver_data = 0 }, | 421 | .driver_data = 0 }, |
| 422 | { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000SB), | ||
| 423 | .driver_data = 0 }, | ||
| 422 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3), | 424 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3), |
| 423 | .driver_data = 3 }, | 425 | .driver_data = 3 }, |
| 424 | { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3), | 426 | { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3), |
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 7579f4b256a8..5155010b455e 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c | |||
| @@ -647,7 +647,7 @@ static inline void i2c_pxa_start_message(struct pxa_i2c *i2c) | |||
| 647 | } | 647 | } |
| 648 | 648 | ||
| 649 | /* | 649 | /* |
| 650 | * We are protected by the adapter bus semaphore. | 650 | * We are protected by the adapter bus mutex. |
| 651 | */ | 651 | */ |
| 652 | static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num) | 652 | static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num) |
| 653 | { | 653 | { |
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index d3478e084522..8bd305e47f0d 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c | |||
| @@ -1,27 +1,26 @@ | |||
| 1 | /* linux/drivers/i2c/scx200_acb.c | 1 | /* |
| 2 | |||
| 3 | Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> | 2 | Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> |
| 4 | 3 | ||
| 5 | National Semiconductor SCx200 ACCESS.bus support | 4 | National Semiconductor SCx200 ACCESS.bus support |
| 6 | 5 | Also supports the AMD CS5535 and AMD CS5536 | |
| 6 | |||
| 7 | Based on i2c-keywest.c which is: | 7 | Based on i2c-keywest.c which is: |
| 8 | Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org> | 8 | Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org> |
| 9 | Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com> | 9 | Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com> |
| 10 | 10 | ||
| 11 | This program is free software; you can redistribute it and/or | 11 | This program is free software; you can redistribute it and/or |
| 12 | modify it under the terms of the GNU General Public License as | 12 | modify it under the terms of the GNU General Public License as |
| 13 | published by the Free Software Foundation; either version 2 of the | 13 | published by the Free Software Foundation; either version 2 of the |
| 14 | License, or (at your option) any later version. | 14 | License, or (at your option) any later version. |
| 15 | 15 | ||
| 16 | This program is distributed in the hope that it will be useful, | 16 | This program is distributed in the hope that it will be useful, |
| 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 19 | General Public License for more details. | 19 | General Public License for more details. |
| 20 | 20 | ||
| 21 | You should have received a copy of the GNU General Public License | 21 | You should have received a copy of the GNU General Public License |
| 22 | along with this program; if not, write to the Free Software | 22 | along with this program; if not, write to the Free Software |
| 23 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 23 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 24 | |||
| 25 | */ | 24 | */ |
| 26 | 25 | ||
| 27 | #include <linux/module.h> | 26 | #include <linux/module.h> |
| @@ -32,7 +31,9 @@ | |||
| 32 | #include <linux/smp_lock.h> | 31 | #include <linux/smp_lock.h> |
| 33 | #include <linux/pci.h> | 32 | #include <linux/pci.h> |
| 34 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
| 34 | #include <linux/mutex.h> | ||
| 35 | #include <asm/io.h> | 35 | #include <asm/io.h> |
| 36 | #include <asm/msr.h> | ||
| 36 | 37 | ||
| 37 | #include <linux/scx200.h> | 38 | #include <linux/scx200.h> |
| 38 | 39 | ||
| @@ -47,16 +48,7 @@ static int base[MAX_DEVICES] = { 0x820, 0x840 }; | |||
| 47 | module_param_array(base, int, NULL, 0); | 48 | module_param_array(base, int, NULL, 0); |
| 48 | MODULE_PARM_DESC(base, "Base addresses for the ACCESS.bus controllers"); | 49 | MODULE_PARM_DESC(base, "Base addresses for the ACCESS.bus controllers"); |
| 49 | 50 | ||
| 50 | #ifdef DEBUG | 51 | #define POLL_TIMEOUT (HZ/5) |
| 51 | #define DBG(x...) printk(KERN_DEBUG NAME ": " x) | ||
| 52 | #else | ||
| 53 | #define DBG(x...) | ||
| 54 | #endif | ||
| 55 | |||
| 56 | /* The hardware supports interrupt driven mode too, but I haven't | ||
| 57 | implemented that. */ | ||
| 58 | #define POLLED_MODE 1 | ||
| 59 | #define POLL_TIMEOUT (HZ) | ||
| 60 | 52 | ||
| 61 | enum scx200_acb_state { | 53 | enum scx200_acb_state { |
| 62 | state_idle, | 54 | state_idle, |
| @@ -79,12 +71,11 @@ static const char *scx200_acb_state_name[] = { | |||
| 79 | }; | 71 | }; |
| 80 | 72 | ||
| 81 | /* Physical interface */ | 73 | /* Physical interface */ |
| 82 | struct scx200_acb_iface | 74 | struct scx200_acb_iface { |
| 83 | { | ||
| 84 | struct scx200_acb_iface *next; | 75 | struct scx200_acb_iface *next; |
| 85 | struct i2c_adapter adapter; | 76 | struct i2c_adapter adapter; |
| 86 | unsigned base; | 77 | unsigned base; |
| 87 | struct semaphore sem; | 78 | struct mutex mutex; |
| 88 | 79 | ||
| 89 | /* State machine data */ | 80 | /* State machine data */ |
| 90 | enum scx200_acb_state state; | 81 | enum scx200_acb_state state; |
| @@ -100,7 +91,7 @@ struct scx200_acb_iface | |||
| 100 | #define ACBSDA (iface->base + 0) | 91 | #define ACBSDA (iface->base + 0) |
| 101 | #define ACBST (iface->base + 1) | 92 | #define ACBST (iface->base + 1) |
| 102 | #define ACBST_SDAST 0x40 /* SDA Status */ | 93 | #define ACBST_SDAST 0x40 /* SDA Status */ |
| 103 | #define ACBST_BER 0x20 | 94 | #define ACBST_BER 0x20 |
| 104 | #define ACBST_NEGACK 0x10 /* Negative Acknowledge */ | 95 | #define ACBST_NEGACK 0x10 /* Negative Acknowledge */ |
| 105 | #define ACBST_STASTR 0x08 /* Stall After Start */ | 96 | #define ACBST_STASTR 0x08 /* Stall After Start */ |
| 106 | #define ACBST_MASTER 0x02 | 97 | #define ACBST_MASTER 0x02 |
| @@ -109,9 +100,9 @@ struct scx200_acb_iface | |||
| 109 | #define ACBCTL1 (iface->base + 3) | 100 | #define ACBCTL1 (iface->base + 3) |
| 110 | #define ACBCTL1_STASTRE 0x80 | 101 | #define ACBCTL1_STASTRE 0x80 |
| 111 | #define ACBCTL1_NMINTE 0x40 | 102 | #define ACBCTL1_NMINTE 0x40 |
| 112 | #define ACBCTL1_ACK 0x10 | 103 | #define ACBCTL1_ACK 0x10 |
| 113 | #define ACBCTL1_STOP 0x02 | 104 | #define ACBCTL1_STOP 0x02 |
| 114 | #define ACBCTL1_START 0x01 | 105 | #define ACBCTL1_START 0x01 |
| 115 | #define ACBADDR (iface->base + 4) | 106 | #define ACBADDR (iface->base + 4) |
| 116 | #define ACBCTL2 (iface->base + 5) | 107 | #define ACBCTL2 (iface->base + 5) |
| 117 | #define ACBCTL2_ENABLE 0x01 | 108 | #define ACBCTL2_ENABLE 0x01 |
| @@ -122,8 +113,8 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status) | |||
| 122 | { | 113 | { |
| 123 | const char *errmsg; | 114 | const char *errmsg; |
| 124 | 115 | ||
| 125 | DBG("state %s, status = 0x%02x\n", | 116 | dev_dbg(&iface->adapter.dev, "state %s, status = 0x%02x\n", |
| 126 | scx200_acb_state_name[iface->state], status); | 117 | scx200_acb_state_name[iface->state], status); |
| 127 | 118 | ||
| 128 | if (status & ACBST_BER) { | 119 | if (status & ACBST_BER) { |
| 129 | errmsg = "bus error"; | 120 | errmsg = "bus error"; |
| @@ -133,8 +124,17 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status) | |||
| 133 | errmsg = "not master"; | 124 | errmsg = "not master"; |
| 134 | goto error; | 125 | goto error; |
| 135 | } | 126 | } |
| 136 | if (status & ACBST_NEGACK) | 127 | if (status & ACBST_NEGACK) { |
| 137 | goto negack; | 128 | dev_dbg(&iface->adapter.dev, "negative ack in state %s\n", |
| 129 | scx200_acb_state_name[iface->state]); | ||
| 130 | |||
| 131 | iface->state = state_idle; | ||
| 132 | iface->result = -ENXIO; | ||
| 133 | |||
| 134 | outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1); | ||
| 135 | outb(ACBST_STASTR | ACBST_NEGACK, ACBST); | ||
| 136 | return; | ||
| 137 | } | ||
| 138 | 138 | ||
| 139 | switch (iface->state) { | 139 | switch (iface->state) { |
| 140 | case state_idle: | 140 | case state_idle: |
| @@ -160,10 +160,10 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status) | |||
| 160 | case state_repeat_start: | 160 | case state_repeat_start: |
| 161 | outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1); | 161 | outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1); |
| 162 | /* fallthrough */ | 162 | /* fallthrough */ |
| 163 | 163 | ||
| 164 | case state_quick: | 164 | case state_quick: |
| 165 | if (iface->address_byte & 1) { | 165 | if (iface->address_byte & 1) { |
| 166 | if (iface->len == 1) | 166 | if (iface->len == 1) |
| 167 | outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1); | 167 | outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1); |
| 168 | else | 168 | else |
| 169 | outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1); | 169 | outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1); |
| @@ -202,26 +202,15 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status) | |||
| 202 | outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1); | 202 | outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1); |
| 203 | break; | 203 | break; |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | outb(*iface->ptr++, ACBSDA); | 206 | outb(*iface->ptr++, ACBSDA); |
| 207 | --iface->len; | 207 | --iface->len; |
| 208 | 208 | ||
| 209 | break; | 209 | break; |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | return; | 212 | return; |
| 213 | 213 | ||
| 214 | negack: | ||
| 215 | DBG("negative acknowledge in state %s\n", | ||
| 216 | scx200_acb_state_name[iface->state]); | ||
| 217 | |||
| 218 | iface->state = state_idle; | ||
| 219 | iface->result = -ENXIO; | ||
| 220 | |||
| 221 | outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1); | ||
| 222 | outb(ACBST_STASTR | ACBST_NEGACK, ACBST); | ||
| 223 | return; | ||
| 224 | |||
| 225 | error: | 214 | error: |
| 226 | dev_err(&iface->adapter.dev, "%s in state %s\n", errmsg, | 215 | dev_err(&iface->adapter.dev, "%s in state %s\n", errmsg, |
| 227 | scx200_acb_state_name[iface->state]); | 216 | scx200_acb_state_name[iface->state]); |
| @@ -231,20 +220,9 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status) | |||
| 231 | iface->needs_reset = 1; | 220 | iface->needs_reset = 1; |
| 232 | } | 221 | } |
| 233 | 222 | ||
| 234 | static void scx200_acb_timeout(struct scx200_acb_iface *iface) | ||
| 235 | { | ||
| 236 | dev_err(&iface->adapter.dev, "timeout in state %s\n", | ||
| 237 | scx200_acb_state_name[iface->state]); | ||
| 238 | |||
| 239 | iface->state = state_idle; | ||
| 240 | iface->result = -EIO; | ||
| 241 | iface->needs_reset = 1; | ||
| 242 | } | ||
| 243 | |||
| 244 | #ifdef POLLED_MODE | ||
| 245 | static void scx200_acb_poll(struct scx200_acb_iface *iface) | 223 | static void scx200_acb_poll(struct scx200_acb_iface *iface) |
| 246 | { | 224 | { |
| 247 | u8 status = 0; | 225 | u8 status; |
| 248 | unsigned long timeout; | 226 | unsigned long timeout; |
| 249 | 227 | ||
| 250 | timeout = jiffies + POLL_TIMEOUT; | 228 | timeout = jiffies + POLL_TIMEOUT; |
| @@ -254,17 +232,21 @@ static void scx200_acb_poll(struct scx200_acb_iface *iface) | |||
| 254 | scx200_acb_machine(iface, status); | 232 | scx200_acb_machine(iface, status); |
| 255 | return; | 233 | return; |
| 256 | } | 234 | } |
| 257 | msleep(10); | 235 | yield(); |
| 258 | } | 236 | } |
| 259 | 237 | ||
| 260 | scx200_acb_timeout(iface); | 238 | dev_err(&iface->adapter.dev, "timeout in state %s\n", |
| 239 | scx200_acb_state_name[iface->state]); | ||
| 240 | |||
| 241 | iface->state = state_idle; | ||
| 242 | iface->result = -EIO; | ||
| 243 | iface->needs_reset = 1; | ||
| 261 | } | 244 | } |
| 262 | #endif /* POLLED_MODE */ | ||
| 263 | 245 | ||
| 264 | static void scx200_acb_reset(struct scx200_acb_iface *iface) | 246 | static void scx200_acb_reset(struct scx200_acb_iface *iface) |
| 265 | { | 247 | { |
| 266 | /* Disable the ACCESS.bus device and Configure the SCL | 248 | /* Disable the ACCESS.bus device and Configure the SCL |
| 267 | frequency: 16 clock cycles */ | 249 | frequency: 16 clock cycles */ |
| 268 | outb(0x70, ACBCTL2); | 250 | outb(0x70, ACBCTL2); |
| 269 | /* Polling mode */ | 251 | /* Polling mode */ |
| 270 | outb(0, ACBCTL1); | 252 | outb(0, ACBCTL1); |
| @@ -283,9 +265,9 @@ static void scx200_acb_reset(struct scx200_acb_iface *iface) | |||
| 283 | } | 265 | } |
| 284 | 266 | ||
| 285 | static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter, | 267 | static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter, |
| 286 | u16 address, unsigned short flags, | 268 | u16 address, unsigned short flags, |
| 287 | char rw, u8 command, int size, | 269 | char rw, u8 command, int size, |
| 288 | union i2c_smbus_data *data) | 270 | union i2c_smbus_data *data) |
| 289 | { | 271 | { |
| 290 | struct scx200_acb_iface *iface = i2c_get_adapdata(adapter); | 272 | struct scx200_acb_iface *iface = i2c_get_adapdata(adapter); |
| 291 | int len; | 273 | int len; |
| @@ -295,53 +277,47 @@ static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter, | |||
| 295 | 277 | ||
| 296 | switch (size) { | 278 | switch (size) { |
| 297 | case I2C_SMBUS_QUICK: | 279 | case I2C_SMBUS_QUICK: |
| 298 | len = 0; | 280 | len = 0; |
| 299 | buffer = NULL; | 281 | buffer = NULL; |
| 300 | break; | 282 | break; |
| 283 | |||
| 301 | case I2C_SMBUS_BYTE: | 284 | case I2C_SMBUS_BYTE: |
| 302 | if (rw == I2C_SMBUS_READ) { | 285 | len = 1; |
| 303 | len = 1; | 286 | buffer = rw ? &data->byte : &command; |
| 304 | buffer = &data->byte; | 287 | break; |
| 305 | } else { | 288 | |
| 306 | len = 1; | ||
| 307 | buffer = &command; | ||
| 308 | } | ||
| 309 | break; | ||
| 310 | case I2C_SMBUS_BYTE_DATA: | 289 | case I2C_SMBUS_BYTE_DATA: |
| 311 | len = 1; | 290 | len = 1; |
| 312 | buffer = &data->byte; | 291 | buffer = &data->byte; |
| 313 | break; | 292 | break; |
| 293 | |||
| 314 | case I2C_SMBUS_WORD_DATA: | 294 | case I2C_SMBUS_WORD_DATA: |
| 315 | len = 2; | 295 | len = 2; |
| 316 | cur_word = cpu_to_le16(data->word); | 296 | cur_word = cpu_to_le16(data->word); |
| 317 | buffer = (u8 *)&cur_word; | 297 | buffer = (u8 *)&cur_word; |
| 318 | break; | 298 | break; |
| 299 | |||
| 319 | case I2C_SMBUS_BLOCK_DATA: | 300 | case I2C_SMBUS_BLOCK_DATA: |
| 320 | len = data->block[0]; | 301 | len = data->block[0]; |
| 321 | buffer = &data->block[1]; | 302 | buffer = &data->block[1]; |
| 322 | break; | 303 | break; |
| 304 | |||
| 323 | default: | 305 | default: |
| 324 | return -EINVAL; | 306 | return -EINVAL; |
| 325 | } | 307 | } |
| 326 | 308 | ||
| 327 | DBG("size=%d, address=0x%x, command=0x%x, len=%d, read=%d\n", | 309 | dev_dbg(&adapter->dev, |
| 328 | size, address, command, len, rw == I2C_SMBUS_READ); | 310 | "size=%d, address=0x%x, command=0x%x, len=%d, read=%d\n", |
| 311 | size, address, command, len, rw); | ||
| 329 | 312 | ||
| 330 | if (!len && rw == I2C_SMBUS_READ) { | 313 | if (!len && rw == I2C_SMBUS_READ) { |
| 331 | dev_warn(&adapter->dev, "zero length read\n"); | 314 | dev_dbg(&adapter->dev, "zero length read\n"); |
| 332 | return -EINVAL; | 315 | return -EINVAL; |
| 333 | } | 316 | } |
| 334 | 317 | ||
| 335 | if (len && !buffer) { | 318 | mutex_lock(&iface->mutex); |
| 336 | dev_warn(&adapter->dev, "nonzero length but no buffer\n"); | ||
| 337 | return -EFAULT; | ||
| 338 | } | ||
| 339 | |||
| 340 | down(&iface->sem); | ||
| 341 | 319 | ||
| 342 | iface->address_byte = address<<1; | 320 | iface->address_byte = (address << 1) | rw; |
| 343 | if (rw == I2C_SMBUS_READ) | ||
| 344 | iface->address_byte |= 1; | ||
| 345 | iface->command = command; | 321 | iface->command = command; |
| 346 | iface->ptr = buffer; | 322 | iface->ptr = buffer; |
| 347 | iface->len = len; | 323 | iface->len = len; |
| @@ -355,25 +331,21 @@ static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter, | |||
| 355 | else | 331 | else |
| 356 | iface->state = state_address; | 332 | iface->state = state_address; |
| 357 | 333 | ||
| 358 | #ifdef POLLED_MODE | ||
| 359 | while (iface->state != state_idle) | 334 | while (iface->state != state_idle) |
| 360 | scx200_acb_poll(iface); | 335 | scx200_acb_poll(iface); |
| 361 | #else /* POLLED_MODE */ | ||
| 362 | #error Interrupt driven mode not implemented | ||
| 363 | #endif /* POLLED_MODE */ | ||
| 364 | 336 | ||
| 365 | if (iface->needs_reset) | 337 | if (iface->needs_reset) |
| 366 | scx200_acb_reset(iface); | 338 | scx200_acb_reset(iface); |
| 367 | 339 | ||
| 368 | rc = iface->result; | 340 | rc = iface->result; |
| 369 | 341 | ||
| 370 | up(&iface->sem); | 342 | mutex_unlock(&iface->mutex); |
| 371 | 343 | ||
| 372 | if (rc == 0 && size == I2C_SMBUS_WORD_DATA && rw == I2C_SMBUS_READ) | 344 | if (rc == 0 && size == I2C_SMBUS_WORD_DATA && rw == I2C_SMBUS_READ) |
| 373 | data->word = le16_to_cpu(cur_word); | 345 | data->word = le16_to_cpu(cur_word); |
| 374 | 346 | ||
| 375 | #ifdef DEBUG | 347 | #ifdef DEBUG |
| 376 | DBG(": transfer done, result: %d", rc); | 348 | dev_dbg(&adapter->dev, "transfer done, result: %d", rc); |
| 377 | if (buffer) { | 349 | if (buffer) { |
| 378 | int i; | 350 | int i; |
| 379 | printk(" data:"); | 351 | printk(" data:"); |
| @@ -400,17 +372,18 @@ static struct i2c_algorithm scx200_acb_algorithm = { | |||
| 400 | }; | 372 | }; |
| 401 | 373 | ||
| 402 | static struct scx200_acb_iface *scx200_acb_list; | 374 | static struct scx200_acb_iface *scx200_acb_list; |
| 375 | static DECLARE_MUTEX(scx200_acb_list_mutex); | ||
| 403 | 376 | ||
| 404 | static int scx200_acb_probe(struct scx200_acb_iface *iface) | 377 | static int scx200_acb_probe(struct scx200_acb_iface *iface) |
| 405 | { | 378 | { |
| 406 | u8 val; | 379 | u8 val; |
| 407 | 380 | ||
| 408 | /* Disable the ACCESS.bus device and Configure the SCL | 381 | /* Disable the ACCESS.bus device and Configure the SCL |
| 409 | frequency: 16 clock cycles */ | 382 | frequency: 16 clock cycles */ |
| 410 | outb(0x70, ACBCTL2); | 383 | outb(0x70, ACBCTL2); |
| 411 | 384 | ||
| 412 | if (inb(ACBCTL2) != 0x70) { | 385 | if (inb(ACBCTL2) != 0x70) { |
| 413 | DBG("ACBCTL2 readback failed\n"); | 386 | pr_debug(NAME ": ACBCTL2 readback failed\n"); |
| 414 | return -ENXIO; | 387 | return -ENXIO; |
| 415 | } | 388 | } |
| 416 | 389 | ||
| @@ -418,7 +391,8 @@ static int scx200_acb_probe(struct scx200_acb_iface *iface) | |||
| 418 | 391 | ||
| 419 | val = inb(ACBCTL1); | 392 | val = inb(ACBCTL1); |
| 420 | if (val) { | 393 | if (val) { |
| 421 | DBG("disabled, but ACBCTL1=0x%02x\n", val); | 394 | pr_debug(NAME ": disabled, but ACBCTL1=0x%02x\n", |
| 395 | val); | ||
| 422 | return -ENXIO; | 396 | return -ENXIO; |
| 423 | } | 397 | } |
| 424 | 398 | ||
| @@ -428,18 +402,19 @@ static int scx200_acb_probe(struct scx200_acb_iface *iface) | |||
| 428 | 402 | ||
| 429 | val = inb(ACBCTL1); | 403 | val = inb(ACBCTL1); |
| 430 | if ((val & ACBCTL1_NMINTE) != ACBCTL1_NMINTE) { | 404 | if ((val & ACBCTL1_NMINTE) != ACBCTL1_NMINTE) { |
| 431 | DBG("enabled, but NMINTE won't be set, ACBCTL1=0x%02x\n", val); | 405 | pr_debug(NAME ": enabled, but NMINTE won't be set, " |
| 406 | "ACBCTL1=0x%02x\n", val); | ||
| 432 | return -ENXIO; | 407 | return -ENXIO; |
| 433 | } | 408 | } |
| 434 | 409 | ||
| 435 | return 0; | 410 | return 0; |
| 436 | } | 411 | } |
| 437 | 412 | ||
| 438 | static int __init scx200_acb_create(int base, int index) | 413 | static int __init scx200_acb_create(const char *text, int base, int index) |
| 439 | { | 414 | { |
| 440 | struct scx200_acb_iface *iface; | 415 | struct scx200_acb_iface *iface; |
| 441 | struct i2c_adapter *adapter; | 416 | struct i2c_adapter *adapter; |
| 442 | int rc = 0; | 417 | int rc; |
| 443 | char description[64]; | 418 | char description[64]; |
| 444 | 419 | ||
| 445 | iface = kzalloc(sizeof(*iface), GFP_KERNEL); | 420 | iface = kzalloc(sizeof(*iface), GFP_KERNEL); |
| @@ -451,50 +426,51 @@ static int __init scx200_acb_create(int base, int index) | |||
| 451 | 426 | ||
| 452 | adapter = &iface->adapter; | 427 | adapter = &iface->adapter; |
| 453 | i2c_set_adapdata(adapter, iface); | 428 | i2c_set_adapdata(adapter, iface); |
| 454 | snprintf(adapter->name, I2C_NAME_SIZE, "SCx200 ACB%d", index); | 429 | snprintf(adapter->name, I2C_NAME_SIZE, "%s ACB%d", text, index); |
| 455 | adapter->owner = THIS_MODULE; | 430 | adapter->owner = THIS_MODULE; |
| 456 | adapter->id = I2C_HW_SMBUS_SCX200; | 431 | adapter->id = I2C_HW_SMBUS_SCX200; |
| 457 | adapter->algo = &scx200_acb_algorithm; | 432 | adapter->algo = &scx200_acb_algorithm; |
| 458 | adapter->class = I2C_CLASS_HWMON; | 433 | adapter->class = I2C_CLASS_HWMON; |
| 459 | 434 | ||
| 460 | init_MUTEX(&iface->sem); | 435 | mutex_init(&iface->mutex); |
| 436 | |||
| 437 | snprintf(description, sizeof(description), "%s ACCESS.bus [%s]", | ||
| 438 | text, adapter->name); | ||
| 461 | 439 | ||
| 462 | snprintf(description, sizeof(description), "NatSemi SCx200 ACCESS.bus [%s]", adapter->name); | ||
| 463 | if (request_region(base, 8, description) == 0) { | 440 | if (request_region(base, 8, description) == 0) { |
| 464 | dev_err(&adapter->dev, "can't allocate io 0x%x-0x%x\n", | 441 | printk(KERN_ERR NAME ": can't allocate io 0x%x-0x%x\n", |
| 465 | base, base + 8-1); | 442 | base, base + 8-1); |
| 466 | rc = -EBUSY; | 443 | rc = -EBUSY; |
| 467 | goto errout; | 444 | goto errout_free; |
| 468 | } | 445 | } |
| 469 | iface->base = base; | 446 | iface->base = base; |
| 470 | 447 | ||
| 471 | rc = scx200_acb_probe(iface); | 448 | rc = scx200_acb_probe(iface); |
| 472 | if (rc) { | 449 | if (rc) { |
| 473 | dev_warn(&adapter->dev, "probe failed\n"); | 450 | printk(KERN_WARNING NAME ": probe failed\n"); |
| 474 | goto errout; | 451 | goto errout_release; |
| 475 | } | 452 | } |
| 476 | 453 | ||
| 477 | scx200_acb_reset(iface); | 454 | scx200_acb_reset(iface); |
| 478 | 455 | ||
| 479 | if (i2c_add_adapter(adapter) < 0) { | 456 | if (i2c_add_adapter(adapter) < 0) { |
| 480 | dev_err(&adapter->dev, "failed to register\n"); | 457 | printk(KERN_ERR NAME ": failed to register\n"); |
| 481 | rc = -ENODEV; | 458 | rc = -ENODEV; |
| 482 | goto errout; | 459 | goto errout_release; |
| 483 | } | 460 | } |
| 484 | 461 | ||
| 485 | lock_kernel(); | 462 | down(&scx200_acb_list_mutex); |
| 486 | iface->next = scx200_acb_list; | 463 | iface->next = scx200_acb_list; |
| 487 | scx200_acb_list = iface; | 464 | scx200_acb_list = iface; |
| 488 | unlock_kernel(); | 465 | up(&scx200_acb_list_mutex); |
| 489 | 466 | ||
| 490 | return 0; | 467 | return 0; |
| 491 | 468 | ||
| 469 | errout_release: | ||
| 470 | release_region(iface->base, 8); | ||
| 471 | errout_free: | ||
| 472 | kfree(iface); | ||
| 492 | errout: | 473 | errout: |
| 493 | if (iface) { | ||
| 494 | if (iface->base) | ||
| 495 | release_region(iface->base, 8); | ||
| 496 | kfree(iface); | ||
| 497 | } | ||
| 498 | return rc; | 474 | return rc; |
| 499 | } | 475 | } |
| 500 | 476 | ||
| @@ -504,50 +480,69 @@ static struct pci_device_id scx200[] = { | |||
| 504 | { }, | 480 | { }, |
| 505 | }; | 481 | }; |
| 506 | 482 | ||
| 483 | static struct pci_device_id divil_pci[] = { | ||
| 484 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, | ||
| 485 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, | ||
| 486 | { } /* NULL entry */ | ||
| 487 | }; | ||
| 488 | |||
| 489 | #define MSR_LBAR_SMB 0x5140000B | ||
| 490 | |||
| 491 | static int scx200_add_cs553x(void) | ||
| 492 | { | ||
| 493 | u32 low, hi; | ||
| 494 | u32 smb_base; | ||
| 495 | |||
| 496 | /* Grab & reserve the SMB I/O range */ | ||
| 497 | rdmsr(MSR_LBAR_SMB, low, hi); | ||
| 498 | |||
| 499 | /* Check the IO mask and whether SMB is enabled */ | ||
| 500 | if (hi != 0x0000F001) { | ||
| 501 | printk(KERN_WARNING NAME ": SMBus not enabled\n"); | ||
| 502 | return -ENODEV; | ||
| 503 | } | ||
| 504 | |||
| 505 | /* SMBus IO size is 8 bytes */ | ||
| 506 | smb_base = low & 0x0000FFF8; | ||
| 507 | |||
| 508 | return scx200_acb_create("CS5535", smb_base, 0); | ||
| 509 | } | ||
| 510 | |||
| 507 | static int __init scx200_acb_init(void) | 511 | static int __init scx200_acb_init(void) |
| 508 | { | 512 | { |
| 509 | int i; | 513 | int i; |
| 510 | int rc; | 514 | int rc = -ENODEV; |
| 511 | 515 | ||
| 512 | pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n"); | 516 | pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n"); |
| 513 | 517 | ||
| 514 | /* Verify that this really is a SCx200 processor */ | 518 | /* Verify that this really is a SCx200 processor */ |
| 515 | if (pci_dev_present(scx200) == 0) | 519 | if (pci_dev_present(scx200)) { |
| 516 | return -ENODEV; | 520 | for (i = 0; i < MAX_DEVICES; ++i) { |
| 521 | if (base[i] > 0) | ||
| 522 | rc = scx200_acb_create("SCx200", base[i], i); | ||
| 523 | } | ||
| 524 | } else if (pci_dev_present(divil_pci)) | ||
| 525 | rc = scx200_add_cs553x(); | ||
| 517 | 526 | ||
| 518 | rc = -ENXIO; | ||
| 519 | for (i = 0; i < MAX_DEVICES; ++i) { | ||
| 520 | if (base[i] > 0) | ||
| 521 | rc = scx200_acb_create(base[i], i); | ||
| 522 | } | ||
| 523 | if (scx200_acb_list) | ||
| 524 | return 0; | ||
| 525 | return rc; | 527 | return rc; |
| 526 | } | 528 | } |
| 527 | 529 | ||
| 528 | static void __exit scx200_acb_cleanup(void) | 530 | static void __exit scx200_acb_cleanup(void) |
| 529 | { | 531 | { |
| 530 | struct scx200_acb_iface *iface; | 532 | struct scx200_acb_iface *iface; |
| 531 | lock_kernel(); | 533 | |
| 534 | down(&scx200_acb_list_mutex); | ||
| 532 | while ((iface = scx200_acb_list) != NULL) { | 535 | while ((iface = scx200_acb_list) != NULL) { |
| 533 | scx200_acb_list = iface->next; | 536 | scx200_acb_list = iface->next; |
| 534 | unlock_kernel(); | 537 | up(&scx200_acb_list_mutex); |
| 535 | 538 | ||
| 536 | i2c_del_adapter(&iface->adapter); | 539 | i2c_del_adapter(&iface->adapter); |
| 537 | release_region(iface->base, 8); | 540 | release_region(iface->base, 8); |
| 538 | kfree(iface); | 541 | kfree(iface); |
| 539 | lock_kernel(); | 542 | down(&scx200_acb_list_mutex); |
| 540 | } | 543 | } |
| 541 | unlock_kernel(); | 544 | up(&scx200_acb_list_mutex); |
| 542 | } | 545 | } |
| 543 | 546 | ||
| 544 | module_init(scx200_acb_init); | 547 | module_init(scx200_acb_init); |
| 545 | module_exit(scx200_acb_cleanup); | 548 | module_exit(scx200_acb_cleanup); |
| 546 | |||
| 547 | /* | ||
| 548 | Local variables: | ||
| 549 | compile-command: "make -k -C ../.. SUBDIRS=drivers/i2c modules" | ||
| 550 | c-basic-offset: 8 | ||
| 551 | End: | ||
| 552 | */ | ||
| 553 | |||
diff --git a/drivers/i2c/chips/ds1374.c b/drivers/i2c/chips/ds1374.c index 0710b9da9d54..03d09ed5ec2c 100644 --- a/drivers/i2c/chips/ds1374.c +++ b/drivers/i2c/chips/ds1374.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
| 27 | #include <linux/rtc.h> | 27 | #include <linux/rtc.h> |
| 28 | #include <linux/bcd.h> | 28 | #include <linux/bcd.h> |
| 29 | #include <linux/mutex.h> | ||
| 29 | 30 | ||
| 30 | #define DS1374_REG_TOD0 0x00 | 31 | #define DS1374_REG_TOD0 0x00 |
| 31 | #define DS1374_REG_TOD1 0x01 | 32 | #define DS1374_REG_TOD1 0x01 |
| @@ -41,7 +42,7 @@ | |||
| 41 | 42 | ||
| 42 | #define DS1374_DRV_NAME "ds1374" | 43 | #define DS1374_DRV_NAME "ds1374" |
| 43 | 44 | ||
| 44 | static DECLARE_MUTEX(ds1374_mutex); | 45 | static DEFINE_MUTEX(ds1374_mutex); |
| 45 | 46 | ||
| 46 | static struct i2c_driver ds1374_driver; | 47 | static struct i2c_driver ds1374_driver; |
| 47 | static struct i2c_client *save_client; | 48 | static struct i2c_client *save_client; |
| @@ -114,7 +115,7 @@ ulong ds1374_get_rtc_time(void) | |||
| 114 | ulong t1, t2; | 115 | ulong t1, t2; |
| 115 | int limit = 10; /* arbitrary retry limit */ | 116 | int limit = 10; /* arbitrary retry limit */ |
| 116 | 117 | ||
| 117 | down(&ds1374_mutex); | 118 | mutex_lock(&ds1374_mutex); |
| 118 | 119 | ||
| 119 | /* | 120 | /* |
| 120 | * Since the reads are being performed one byte at a time using | 121 | * Since the reads are being performed one byte at a time using |
| @@ -127,7 +128,7 @@ ulong ds1374_get_rtc_time(void) | |||
| 127 | t2 = ds1374_read_rtc(); | 128 | t2 = ds1374_read_rtc(); |
| 128 | } while (t1 != t2 && limit--); | 129 | } while (t1 != t2 && limit--); |
| 129 | 130 | ||
| 130 | up(&ds1374_mutex); | 131 | mutex_unlock(&ds1374_mutex); |
| 131 | 132 | ||
| 132 | if (t1 != t2) { | 133 | if (t1 != t2) { |
| 133 | dev_warn(&save_client->dev, | 134 | dev_warn(&save_client->dev, |
| @@ -145,7 +146,7 @@ static void ds1374_set_tlet(ulong arg) | |||
| 145 | 146 | ||
| 146 | t1 = *(ulong *) arg; | 147 | t1 = *(ulong *) arg; |
| 147 | 148 | ||
| 148 | down(&ds1374_mutex); | 149 | mutex_lock(&ds1374_mutex); |
| 149 | 150 | ||
| 150 | /* | 151 | /* |
| 151 | * Since the writes are being performed one byte at a time using | 152 | * Since the writes are being performed one byte at a time using |
| @@ -158,7 +159,7 @@ static void ds1374_set_tlet(ulong arg) | |||
| 158 | t2 = ds1374_read_rtc(); | 159 | t2 = ds1374_read_rtc(); |
| 159 | } while (t1 != t2 && limit--); | 160 | } while (t1 != t2 && limit--); |
| 160 | 161 | ||
| 161 | up(&ds1374_mutex); | 162 | mutex_unlock(&ds1374_mutex); |
| 162 | 163 | ||
| 163 | if (t1 != t2) | 164 | if (t1 != t2) |
| 164 | dev_warn(&save_client->dev, | 165 | dev_warn(&save_client->dev, |
diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c index 41116b7947f6..13c108269a6d 100644 --- a/drivers/i2c/chips/eeprom.c +++ b/drivers/i2c/chips/eeprom.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
| 34 | #include <linux/jiffies.h> | 34 | #include <linux/jiffies.h> |
| 35 | #include <linux/i2c.h> | 35 | #include <linux/i2c.h> |
| 36 | #include <linux/mutex.h> | ||
| 36 | 37 | ||
| 37 | /* Addresses to scan */ | 38 | /* Addresses to scan */ |
| 38 | static unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54, | 39 | static unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54, |
| @@ -54,7 +55,7 @@ enum eeprom_nature { | |||
| 54 | /* Each client has this additional data */ | 55 | /* Each client has this additional data */ |
| 55 | struct eeprom_data { | 56 | struct eeprom_data { |
| 56 | struct i2c_client client; | 57 | struct i2c_client client; |
| 57 | struct semaphore update_lock; | 58 | struct mutex update_lock; |
| 58 | u8 valid; /* bitfield, bit!=0 if slice is valid */ | 59 | u8 valid; /* bitfield, bit!=0 if slice is valid */ |
| 59 | unsigned long last_updated[8]; /* In jiffies, 8 slices */ | 60 | unsigned long last_updated[8]; /* In jiffies, 8 slices */ |
| 60 | u8 data[EEPROM_SIZE]; /* Register values */ | 61 | u8 data[EEPROM_SIZE]; /* Register values */ |
| @@ -81,7 +82,7 @@ static void eeprom_update_client(struct i2c_client *client, u8 slice) | |||
| 81 | struct eeprom_data *data = i2c_get_clientdata(client); | 82 | struct eeprom_data *data = i2c_get_clientdata(client); |
| 82 | int i, j; | 83 | int i, j; |
| 83 | 84 | ||
| 84 | down(&data->update_lock); | 85 | mutex_lock(&data->update_lock); |
| 85 | 86 | ||
| 86 | if (!(data->valid & (1 << slice)) || | 87 | if (!(data->valid & (1 << slice)) || |
| 87 | time_after(jiffies, data->last_updated[slice] + 300 * HZ)) { | 88 | time_after(jiffies, data->last_updated[slice] + 300 * HZ)) { |
| @@ -107,7 +108,7 @@ static void eeprom_update_client(struct i2c_client *client, u8 slice) | |||
| 107 | data->valid |= (1 << slice); | 108 | data->valid |= (1 << slice); |
| 108 | } | 109 | } |
| 109 | exit: | 110 | exit: |
| 110 | up(&data->update_lock); | 111 | mutex_unlock(&data->update_lock); |
| 111 | } | 112 | } |
| 112 | 113 | ||
| 113 | static ssize_t eeprom_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | 114 | static ssize_t eeprom_read(struct kobject *kobj, char *buf, loff_t off, size_t count) |
| @@ -187,7 +188,7 @@ static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 187 | /* Fill in the remaining client fields */ | 188 | /* Fill in the remaining client fields */ |
| 188 | strlcpy(new_client->name, "eeprom", I2C_NAME_SIZE); | 189 | strlcpy(new_client->name, "eeprom", I2C_NAME_SIZE); |
| 189 | data->valid = 0; | 190 | data->valid = 0; |
| 190 | init_MUTEX(&data->update_lock); | 191 | mutex_init(&data->update_lock); |
| 191 | data->nature = UNKNOWN; | 192 | data->nature = UNKNOWN; |
| 192 | 193 | ||
| 193 | /* Tell the I2C layer a new client has arrived */ | 194 | /* Tell the I2C layer a new client has arrived */ |
diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c index 1251c7fc18d5..e6f1ab7b913c 100644 --- a/drivers/i2c/chips/isp1301_omap.c +++ b/drivers/i2c/chips/isp1301_omap.c | |||
| @@ -1635,8 +1635,6 @@ static struct i2c_driver isp1301_driver = { | |||
| 1635 | .driver = { | 1635 | .driver = { |
| 1636 | .name = "isp1301_omap", | 1636 | .name = "isp1301_omap", |
| 1637 | }, | 1637 | }, |
| 1638 | .id = 1301, /* FIXME "official", i2c-ids.h */ | ||
| 1639 | .class = I2C_CLASS_HWMON, | ||
| 1640 | .attach_adapter = isp1301_scan_bus, | 1638 | .attach_adapter = isp1301_scan_bus, |
| 1641 | .detach_client = isp1301_detach_client, | 1639 | .detach_client = isp1301_detach_client, |
| 1642 | }; | 1640 | }; |
diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c index 2dc3d48375fc..b5aabe7cf792 100644 --- a/drivers/i2c/chips/m41t00.c +++ b/drivers/i2c/chips/m41t00.c | |||
| @@ -24,13 +24,14 @@ | |||
| 24 | #include <linux/i2c.h> | 24 | #include <linux/i2c.h> |
| 25 | #include <linux/rtc.h> | 25 | #include <linux/rtc.h> |
| 26 | #include <linux/bcd.h> | 26 | #include <linux/bcd.h> |
| 27 | #include <linux/mutex.h> | ||
| 27 | 28 | ||
| 28 | #include <asm/time.h> | 29 | #include <asm/time.h> |
| 29 | #include <asm/rtc.h> | 30 | #include <asm/rtc.h> |
| 30 | 31 | ||
| 31 | #define M41T00_DRV_NAME "m41t00" | 32 | #define M41T00_DRV_NAME "m41t00" |
| 32 | 33 | ||
| 33 | static DECLARE_MUTEX(m41t00_mutex); | 34 | static DEFINE_MUTEX(m41t00_mutex); |
| 34 | 35 | ||
| 35 | static struct i2c_driver m41t00_driver; | 36 | static struct i2c_driver m41t00_driver; |
| 36 | static struct i2c_client *save_client; | 37 | static struct i2c_client *save_client; |
| @@ -54,7 +55,7 @@ m41t00_get_rtc_time(void) | |||
| 54 | sec = min = hour = day = mon = year = 0; | 55 | sec = min = hour = day = mon = year = 0; |
| 55 | sec1 = min1 = hour1 = day1 = mon1 = year1 = 0; | 56 | sec1 = min1 = hour1 = day1 = mon1 = year1 = 0; |
| 56 | 57 | ||
| 57 | down(&m41t00_mutex); | 58 | mutex_lock(&m41t00_mutex); |
| 58 | do { | 59 | do { |
| 59 | if (((sec = i2c_smbus_read_byte_data(save_client, 0)) >= 0) | 60 | if (((sec = i2c_smbus_read_byte_data(save_client, 0)) >= 0) |
| 60 | && ((min = i2c_smbus_read_byte_data(save_client, 1)) | 61 | && ((min = i2c_smbus_read_byte_data(save_client, 1)) |
| @@ -80,7 +81,7 @@ m41t00_get_rtc_time(void) | |||
| 80 | mon1 = mon; | 81 | mon1 = mon; |
| 81 | year1 = year; | 82 | year1 = year; |
| 82 | } while (--limit > 0); | 83 | } while (--limit > 0); |
| 83 | up(&m41t00_mutex); | 84 | mutex_unlock(&m41t00_mutex); |
| 84 | 85 | ||
| 85 | if (limit == 0) { | 86 | if (limit == 0) { |
| 86 | dev_warn(&save_client->dev, | 87 | dev_warn(&save_client->dev, |
| @@ -125,7 +126,7 @@ m41t00_set_tlet(ulong arg) | |||
| 125 | BIN_TO_BCD(tm.tm_mday); | 126 | BIN_TO_BCD(tm.tm_mday); |
| 126 | BIN_TO_BCD(tm.tm_year); | 127 | BIN_TO_BCD(tm.tm_year); |
| 127 | 128 | ||
| 128 | down(&m41t00_mutex); | 129 | mutex_lock(&m41t00_mutex); |
| 129 | if ((i2c_smbus_write_byte_data(save_client, 0, tm.tm_sec & 0x7f) < 0) | 130 | if ((i2c_smbus_write_byte_data(save_client, 0, tm.tm_sec & 0x7f) < 0) |
| 130 | || (i2c_smbus_write_byte_data(save_client, 1, tm.tm_min & 0x7f) | 131 | || (i2c_smbus_write_byte_data(save_client, 1, tm.tm_min & 0x7f) |
| 131 | < 0) | 132 | < 0) |
| @@ -140,7 +141,7 @@ m41t00_set_tlet(ulong arg) | |||
| 140 | 141 | ||
| 141 | dev_warn(&save_client->dev,"m41t00: can't write to rtc chip\n"); | 142 | dev_warn(&save_client->dev,"m41t00: can't write to rtc chip\n"); |
| 142 | 143 | ||
| 143 | up(&m41t00_mutex); | 144 | mutex_unlock(&m41t00_mutex); |
| 144 | return; | 145 | return; |
| 145 | } | 146 | } |
| 146 | 147 | ||
diff --git a/drivers/i2c/chips/max6875.c b/drivers/i2c/chips/max6875.c index 6d3ff584155e..88d2ddee4490 100644 --- a/drivers/i2c/chips/max6875.c +++ b/drivers/i2c/chips/max6875.c | |||
| @@ -31,7 +31,7 @@ | |||
| 31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
| 32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
| 33 | #include <linux/i2c.h> | 33 | #include <linux/i2c.h> |
| 34 | #include <asm/semaphore.h> | 34 | #include <linux/mutex.h> |
| 35 | 35 | ||
| 36 | /* Do not scan - the MAX6875 access method will write to some EEPROM chips */ | 36 | /* Do not scan - the MAX6875 access method will write to some EEPROM chips */ |
| 37 | static unsigned short normal_i2c[] = {I2C_CLIENT_END}; | 37 | static unsigned short normal_i2c[] = {I2C_CLIENT_END}; |
| @@ -54,7 +54,7 @@ I2C_CLIENT_INSMOD_1(max6875); | |||
| 54 | /* Each client has this additional data */ | 54 | /* Each client has this additional data */ |
| 55 | struct max6875_data { | 55 | struct max6875_data { |
| 56 | struct i2c_client client; | 56 | struct i2c_client client; |
| 57 | struct semaphore update_lock; | 57 | struct mutex update_lock; |
| 58 | 58 | ||
| 59 | u32 valid; | 59 | u32 valid; |
| 60 | u8 data[USER_EEPROM_SIZE]; | 60 | u8 data[USER_EEPROM_SIZE]; |
| @@ -83,7 +83,7 @@ static void max6875_update_slice(struct i2c_client *client, int slice) | |||
| 83 | if (slice >= USER_EEPROM_SLICES) | 83 | if (slice >= USER_EEPROM_SLICES) |
| 84 | return; | 84 | return; |
| 85 | 85 | ||
| 86 | down(&data->update_lock); | 86 | mutex_lock(&data->update_lock); |
| 87 | 87 | ||
| 88 | buf = &data->data[slice << SLICE_BITS]; | 88 | buf = &data->data[slice << SLICE_BITS]; |
| 89 | 89 | ||
| @@ -122,7 +122,7 @@ static void max6875_update_slice(struct i2c_client *client, int slice) | |||
| 122 | data->valid |= (1 << slice); | 122 | data->valid |= (1 << slice); |
| 123 | } | 123 | } |
| 124 | exit_up: | 124 | exit_up: |
| 125 | up(&data->update_lock); | 125 | mutex_unlock(&data->update_lock); |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | static ssize_t max6875_read(struct kobject *kobj, char *buf, loff_t off, | 128 | static ssize_t max6875_read(struct kobject *kobj, char *buf, loff_t off, |
| @@ -196,7 +196,7 @@ static int max6875_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 196 | real_client->driver = &max6875_driver; | 196 | real_client->driver = &max6875_driver; |
| 197 | real_client->flags = 0; | 197 | real_client->flags = 0; |
| 198 | strlcpy(real_client->name, "max6875", I2C_NAME_SIZE); | 198 | strlcpy(real_client->name, "max6875", I2C_NAME_SIZE); |
| 199 | init_MUTEX(&data->update_lock); | 199 | mutex_init(&data->update_lock); |
| 200 | 200 | ||
| 201 | /* Init fake client data */ | 201 | /* Init fake client data */ |
| 202 | /* set the client data to the i2c_client so that it will get freed */ | 202 | /* set the client data to the i2c_client so that it will get freed */ |
diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c index 36cff09c678d..925a6b371fd2 100644 --- a/drivers/i2c/chips/pcf8591.c +++ b/drivers/i2c/chips/pcf8591.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
| 25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
| 26 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
| 27 | #include <linux/mutex.h> | ||
| 27 | 28 | ||
| 28 | /* Addresses to scan */ | 29 | /* Addresses to scan */ |
| 29 | static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, | 30 | static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c, |
| @@ -74,7 +75,7 @@ MODULE_PARM_DESC(input_mode, | |||
| 74 | 75 | ||
| 75 | struct pcf8591_data { | 76 | struct pcf8591_data { |
| 76 | struct i2c_client client; | 77 | struct i2c_client client; |
| 77 | struct semaphore update_lock; | 78 | struct mutex update_lock; |
| 78 | 79 | ||
| 79 | u8 control; | 80 | u8 control; |
| 80 | u8 aout; | 81 | u8 aout; |
| @@ -144,13 +145,13 @@ static ssize_t set_out0_enable(struct device *dev, struct device_attribute *attr | |||
| 144 | struct pcf8591_data *data = i2c_get_clientdata(client); | 145 | struct pcf8591_data *data = i2c_get_clientdata(client); |
| 145 | unsigned long val = simple_strtoul(buf, NULL, 10); | 146 | unsigned long val = simple_strtoul(buf, NULL, 10); |
| 146 | 147 | ||
| 147 | down(&data->update_lock); | 148 | mutex_lock(&data->update_lock); |
| 148 | if (val) | 149 | if (val) |
| 149 | data->control |= PCF8591_CONTROL_AOEF; | 150 | data->control |= PCF8591_CONTROL_AOEF; |
| 150 | else | 151 | else |
| 151 | data->control &= ~PCF8591_CONTROL_AOEF; | 152 | data->control &= ~PCF8591_CONTROL_AOEF; |
| 152 | i2c_smbus_write_byte(client, data->control); | 153 | i2c_smbus_write_byte(client, data->control); |
| 153 | up(&data->update_lock); | 154 | mutex_unlock(&data->update_lock); |
| 154 | return count; | 155 | return count; |
| 155 | } | 156 | } |
| 156 | 157 | ||
| @@ -200,7 +201,7 @@ static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 200 | /* Fill in the remaining client fields and put it into the global | 201 | /* Fill in the remaining client fields and put it into the global |
| 201 | list */ | 202 | list */ |
| 202 | strlcpy(new_client->name, "pcf8591", I2C_NAME_SIZE); | 203 | strlcpy(new_client->name, "pcf8591", I2C_NAME_SIZE); |
| 203 | init_MUTEX(&data->update_lock); | 204 | mutex_init(&data->update_lock); |
| 204 | 205 | ||
| 205 | /* Tell the I2C layer a new client has arrived */ | 206 | /* Tell the I2C layer a new client has arrived */ |
| 206 | if ((err = i2c_attach_client(new_client))) | 207 | if ((err = i2c_attach_client(new_client))) |
| @@ -265,7 +266,7 @@ static int pcf8591_read_channel(struct device *dev, int channel) | |||
| 265 | struct i2c_client *client = to_i2c_client(dev); | 266 | struct i2c_client *client = to_i2c_client(dev); |
| 266 | struct pcf8591_data *data = i2c_get_clientdata(client); | 267 | struct pcf8591_data *data = i2c_get_clientdata(client); |
| 267 | 268 | ||
| 268 | down(&data->update_lock); | 269 | mutex_lock(&data->update_lock); |
| 269 | 270 | ||
| 270 | if ((data->control & PCF8591_CONTROL_AICH_MASK) != channel) { | 271 | if ((data->control & PCF8591_CONTROL_AICH_MASK) != channel) { |
| 271 | data->control = (data->control & ~PCF8591_CONTROL_AICH_MASK) | 272 | data->control = (data->control & ~PCF8591_CONTROL_AICH_MASK) |
| @@ -278,7 +279,7 @@ static int pcf8591_read_channel(struct device *dev, int channel) | |||
| 278 | } | 279 | } |
| 279 | value = i2c_smbus_read_byte(client); | 280 | value = i2c_smbus_read_byte(client); |
| 280 | 281 | ||
| 281 | up(&data->update_lock); | 282 | mutex_unlock(&data->update_lock); |
| 282 | 283 | ||
| 283 | if ((channel == 2 && input_mode == 2) || | 284 | if ((channel == 2 && input_mode == 2) || |
| 284 | (channel != 3 && (input_mode == 1 || input_mode == 3))) | 285 | (channel != 3 && (input_mode == 1 || input_mode == 3))) |
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c index 1af3dfbb8086..179b1e022d80 100644 --- a/drivers/i2c/chips/tps65010.c +++ b/drivers/i2c/chips/tps65010.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <linux/suspend.h> | 32 | #include <linux/suspend.h> |
| 33 | #include <linux/debugfs.h> | 33 | #include <linux/debugfs.h> |
| 34 | #include <linux/seq_file.h> | 34 | #include <linux/seq_file.h> |
| 35 | #include <linux/mutex.h> | ||
| 35 | 36 | ||
| 36 | #include <asm/irq.h> | 37 | #include <asm/irq.h> |
| 37 | #include <asm/mach-types.h> | 38 | #include <asm/mach-types.h> |
| @@ -81,7 +82,7 @@ enum tps_model { | |||
| 81 | 82 | ||
| 82 | struct tps65010 { | 83 | struct tps65010 { |
| 83 | struct i2c_client client; | 84 | struct i2c_client client; |
| 84 | struct semaphore lock; | 85 | struct mutex lock; |
| 85 | int irq; | 86 | int irq; |
| 86 | struct work_struct work; | 87 | struct work_struct work; |
| 87 | struct dentry *file; | 88 | struct dentry *file; |
| @@ -218,7 +219,7 @@ static int dbg_show(struct seq_file *s, void *_) | |||
| 218 | seq_printf(s, "driver %s\nversion %s\nchip %s\n\n", | 219 | seq_printf(s, "driver %s\nversion %s\nchip %s\n\n", |
| 219 | DRIVER_NAME, DRIVER_VERSION, chip); | 220 | DRIVER_NAME, DRIVER_VERSION, chip); |
| 220 | 221 | ||
| 221 | down(&tps->lock); | 222 | mutex_lock(&tps->lock); |
| 222 | 223 | ||
| 223 | /* FIXME how can we tell whether a battery is present? | 224 | /* FIXME how can we tell whether a battery is present? |
| 224 | * likely involves a charge gauging chip (like BQ26501). | 225 | * likely involves a charge gauging chip (like BQ26501). |
| @@ -300,7 +301,7 @@ static int dbg_show(struct seq_file *s, void *_) | |||
| 300 | (v2 & (1 << (4 + i))) ? "rising" : "falling"); | 301 | (v2 & (1 << (4 + i))) ? "rising" : "falling"); |
| 301 | } | 302 | } |
| 302 | 303 | ||
| 303 | up(&tps->lock); | 304 | mutex_unlock(&tps->lock); |
| 304 | return 0; | 305 | return 0; |
| 305 | } | 306 | } |
| 306 | 307 | ||
| @@ -416,7 +417,7 @@ static void tps65010_work(void *_tps) | |||
| 416 | { | 417 | { |
| 417 | struct tps65010 *tps = _tps; | 418 | struct tps65010 *tps = _tps; |
| 418 | 419 | ||
| 419 | down(&tps->lock); | 420 | mutex_lock(&tps->lock); |
| 420 | 421 | ||
| 421 | tps65010_interrupt(tps); | 422 | tps65010_interrupt(tps); |
| 422 | 423 | ||
| @@ -444,7 +445,7 @@ static void tps65010_work(void *_tps) | |||
| 444 | if (test_and_clear_bit(FLAG_IRQ_ENABLE, &tps->flags)) | 445 | if (test_and_clear_bit(FLAG_IRQ_ENABLE, &tps->flags)) |
| 445 | enable_irq(tps->irq); | 446 | enable_irq(tps->irq); |
| 446 | 447 | ||
| 447 | up(&tps->lock); | 448 | mutex_unlock(&tps->lock); |
| 448 | } | 449 | } |
| 449 | 450 | ||
| 450 | static irqreturn_t tps65010_irq(int irq, void *_tps, struct pt_regs *regs) | 451 | static irqreturn_t tps65010_irq(int irq, void *_tps, struct pt_regs *regs) |
| @@ -505,7 +506,7 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind) | |||
| 505 | if (!tps) | 506 | if (!tps) |
| 506 | return 0; | 507 | return 0; |
| 507 | 508 | ||
| 508 | init_MUTEX(&tps->lock); | 509 | mutex_init(&tps->lock); |
| 509 | INIT_WORK(&tps->work, tps65010_work, tps); | 510 | INIT_WORK(&tps->work, tps65010_work, tps); |
| 510 | tps->irq = -1; | 511 | tps->irq = -1; |
| 511 | tps->client.addr = address; | 512 | tps->client.addr = address; |
| @@ -695,7 +696,7 @@ int tps65010_set_gpio_out_value(unsigned gpio, unsigned value) | |||
| 695 | if ((gpio < GPIO1) || (gpio > GPIO4)) | 696 | if ((gpio < GPIO1) || (gpio > GPIO4)) |
| 696 | return -EINVAL; | 697 | return -EINVAL; |
| 697 | 698 | ||
| 698 | down(&the_tps->lock); | 699 | mutex_lock(&the_tps->lock); |
| 699 | 700 | ||
| 700 | defgpio = i2c_smbus_read_byte_data(&the_tps->client, TPS_DEFGPIO); | 701 | defgpio = i2c_smbus_read_byte_data(&the_tps->client, TPS_DEFGPIO); |
| 701 | 702 | ||
| @@ -720,7 +721,7 @@ int tps65010_set_gpio_out_value(unsigned gpio, unsigned value) | |||
| 720 | gpio, value ? "high" : "low", | 721 | gpio, value ? "high" : "low", |
| 721 | i2c_smbus_read_byte_data(&the_tps->client, TPS_DEFGPIO)); | 722 | i2c_smbus_read_byte_data(&the_tps->client, TPS_DEFGPIO)); |
| 722 | 723 | ||
| 723 | up(&the_tps->lock); | 724 | mutex_unlock(&the_tps->lock); |
| 724 | return status; | 725 | return status; |
| 725 | } | 726 | } |
| 726 | EXPORT_SYMBOL(tps65010_set_gpio_out_value); | 727 | EXPORT_SYMBOL(tps65010_set_gpio_out_value); |
| @@ -745,7 +746,7 @@ int tps65010_set_led(unsigned led, unsigned mode) | |||
| 745 | led = LED2; | 746 | led = LED2; |
| 746 | } | 747 | } |
| 747 | 748 | ||
| 748 | down(&the_tps->lock); | 749 | mutex_lock(&the_tps->lock); |
| 749 | 750 | ||
| 750 | pr_debug("%s: led%i_on 0x%02x\n", DRIVER_NAME, led, | 751 | pr_debug("%s: led%i_on 0x%02x\n", DRIVER_NAME, led, |
| 751 | i2c_smbus_read_byte_data(&the_tps->client, | 752 | i2c_smbus_read_byte_data(&the_tps->client, |
| @@ -771,7 +772,7 @@ int tps65010_set_led(unsigned led, unsigned mode) | |||
| 771 | default: | 772 | default: |
| 772 | printk(KERN_ERR "%s: Wrong mode parameter for set_led()\n", | 773 | printk(KERN_ERR "%s: Wrong mode parameter for set_led()\n", |
| 773 | DRIVER_NAME); | 774 | DRIVER_NAME); |
| 774 | up(&the_tps->lock); | 775 | mutex_unlock(&the_tps->lock); |
| 775 | return -EINVAL; | 776 | return -EINVAL; |
| 776 | } | 777 | } |
| 777 | 778 | ||
| @@ -781,7 +782,7 @@ int tps65010_set_led(unsigned led, unsigned mode) | |||
| 781 | if (status != 0) { | 782 | if (status != 0) { |
| 782 | printk(KERN_ERR "%s: Failed to write led%i_on register\n", | 783 | printk(KERN_ERR "%s: Failed to write led%i_on register\n", |
| 783 | DRIVER_NAME, led); | 784 | DRIVER_NAME, led); |
| 784 | up(&the_tps->lock); | 785 | mutex_unlock(&the_tps->lock); |
| 785 | return status; | 786 | return status; |
| 786 | } | 787 | } |
| 787 | 788 | ||
| @@ -794,7 +795,7 @@ int tps65010_set_led(unsigned led, unsigned mode) | |||
| 794 | if (status != 0) { | 795 | if (status != 0) { |
| 795 | printk(KERN_ERR "%s: Failed to write led%i_per register\n", | 796 | printk(KERN_ERR "%s: Failed to write led%i_per register\n", |
| 796 | DRIVER_NAME, led); | 797 | DRIVER_NAME, led); |
| 797 | up(&the_tps->lock); | 798 | mutex_unlock(&the_tps->lock); |
| 798 | return status; | 799 | return status; |
| 799 | } | 800 | } |
| 800 | 801 | ||
| @@ -802,7 +803,7 @@ int tps65010_set_led(unsigned led, unsigned mode) | |||
| 802 | i2c_smbus_read_byte_data(&the_tps->client, | 803 | i2c_smbus_read_byte_data(&the_tps->client, |
| 803 | TPS_LED1_PER + offs)); | 804 | TPS_LED1_PER + offs)); |
| 804 | 805 | ||
| 805 | up(&the_tps->lock); | 806 | mutex_unlock(&the_tps->lock); |
| 806 | 807 | ||
| 807 | return status; | 808 | return status; |
| 808 | } | 809 | } |
| @@ -820,7 +821,7 @@ int tps65010_set_vib(unsigned value) | |||
| 820 | if (!the_tps) | 821 | if (!the_tps) |
| 821 | return -ENODEV; | 822 | return -ENODEV; |
| 822 | 823 | ||
| 823 | down(&the_tps->lock); | 824 | mutex_lock(&the_tps->lock); |
| 824 | 825 | ||
| 825 | vdcdc2 = i2c_smbus_read_byte_data(&the_tps->client, TPS_VDCDC2); | 826 | vdcdc2 = i2c_smbus_read_byte_data(&the_tps->client, TPS_VDCDC2); |
| 826 | vdcdc2 &= ~(1 << 1); | 827 | vdcdc2 &= ~(1 << 1); |
| @@ -831,7 +832,7 @@ int tps65010_set_vib(unsigned value) | |||
| 831 | 832 | ||
| 832 | pr_debug("%s: vibrator %s\n", DRIVER_NAME, value ? "on" : "off"); | 833 | pr_debug("%s: vibrator %s\n", DRIVER_NAME, value ? "on" : "off"); |
| 833 | 834 | ||
| 834 | up(&the_tps->lock); | 835 | mutex_unlock(&the_tps->lock); |
| 835 | return status; | 836 | return status; |
| 836 | } | 837 | } |
| 837 | EXPORT_SYMBOL(tps65010_set_vib); | 838 | EXPORT_SYMBOL(tps65010_set_vib); |
| @@ -848,7 +849,7 @@ int tps65010_set_low_pwr(unsigned mode) | |||
| 848 | if (!the_tps) | 849 | if (!the_tps) |
| 849 | return -ENODEV; | 850 | return -ENODEV; |
| 850 | 851 | ||
| 851 | down(&the_tps->lock); | 852 | mutex_lock(&the_tps->lock); |
| 852 | 853 | ||
| 853 | pr_debug("%s: %s low_pwr, vdcdc1 0x%02x\n", DRIVER_NAME, | 854 | pr_debug("%s: %s low_pwr, vdcdc1 0x%02x\n", DRIVER_NAME, |
| 854 | mode ? "enable" : "disable", | 855 | mode ? "enable" : "disable", |
| @@ -876,7 +877,7 @@ int tps65010_set_low_pwr(unsigned mode) | |||
| 876 | pr_debug("%s: vdcdc1 0x%02x\n", DRIVER_NAME, | 877 | pr_debug("%s: vdcdc1 0x%02x\n", DRIVER_NAME, |
| 877 | i2c_smbus_read_byte_data(&the_tps->client, TPS_VDCDC1)); | 878 | i2c_smbus_read_byte_data(&the_tps->client, TPS_VDCDC1)); |
| 878 | 879 | ||
| 879 | up(&the_tps->lock); | 880 | mutex_unlock(&the_tps->lock); |
| 880 | 881 | ||
| 881 | return status; | 882 | return status; |
| 882 | } | 883 | } |
| @@ -894,7 +895,7 @@ int tps65010_config_vregs1(unsigned value) | |||
| 894 | if (!the_tps) | 895 | if (!the_tps) |
| 895 | return -ENODEV; | 896 | return -ENODEV; |
| 896 | 897 | ||
| 897 | down(&the_tps->lock); | 898 | mutex_lock(&the_tps->lock); |
| 898 | 899 | ||
| 899 | pr_debug("%s: vregs1 0x%02x\n", DRIVER_NAME, | 900 | pr_debug("%s: vregs1 0x%02x\n", DRIVER_NAME, |
| 900 | i2c_smbus_read_byte_data(&the_tps->client, TPS_VREGS1)); | 901 | i2c_smbus_read_byte_data(&the_tps->client, TPS_VREGS1)); |
| @@ -909,7 +910,7 @@ int tps65010_config_vregs1(unsigned value) | |||
| 909 | pr_debug("%s: vregs1 0x%02x\n", DRIVER_NAME, | 910 | pr_debug("%s: vregs1 0x%02x\n", DRIVER_NAME, |
| 910 | i2c_smbus_read_byte_data(&the_tps->client, TPS_VREGS1)); | 911 | i2c_smbus_read_byte_data(&the_tps->client, TPS_VREGS1)); |
| 911 | 912 | ||
| 912 | up(&the_tps->lock); | 913 | mutex_unlock(&the_tps->lock); |
| 913 | 914 | ||
| 914 | return status; | 915 | return status; |
| 915 | } | 916 | } |
| @@ -931,7 +932,7 @@ int tps65013_set_low_pwr(unsigned mode) | |||
| 931 | if (!the_tps || the_tps->por) | 932 | if (!the_tps || the_tps->por) |
| 932 | return -ENODEV; | 933 | return -ENODEV; |
| 933 | 934 | ||
| 934 | down(&the_tps->lock); | 935 | mutex_lock(&the_tps->lock); |
| 935 | 936 | ||
| 936 | pr_debug("%s: %s low_pwr, chgconfig 0x%02x vdcdc1 0x%02x\n", | 937 | pr_debug("%s: %s low_pwr, chgconfig 0x%02x vdcdc1 0x%02x\n", |
| 937 | DRIVER_NAME, | 938 | DRIVER_NAME, |
| @@ -959,7 +960,7 @@ int tps65013_set_low_pwr(unsigned mode) | |||
| 959 | if (status != 0) { | 960 | if (status != 0) { |
| 960 | printk(KERN_ERR "%s: Failed to write chconfig register\n", | 961 | printk(KERN_ERR "%s: Failed to write chconfig register\n", |
| 961 | DRIVER_NAME); | 962 | DRIVER_NAME); |
| 962 | up(&the_tps->lock); | 963 | mutex_unlock(&the_tps->lock); |
| 963 | return status; | 964 | return status; |
| 964 | } | 965 | } |
| 965 | 966 | ||
| @@ -977,7 +978,7 @@ int tps65013_set_low_pwr(unsigned mode) | |||
| 977 | pr_debug("%s: vdcdc1 0x%02x\n", DRIVER_NAME, | 978 | pr_debug("%s: vdcdc1 0x%02x\n", DRIVER_NAME, |
| 978 | i2c_smbus_read_byte_data(&the_tps->client, TPS_VDCDC1)); | 979 | i2c_smbus_read_byte_data(&the_tps->client, TPS_VDCDC1)); |
| 979 | 980 | ||
| 980 | up(&the_tps->lock); | 981 | mutex_unlock(&the_tps->lock); |
| 981 | 982 | ||
| 982 | return status; | 983 | return status; |
| 983 | } | 984 | } |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 1a2c9ab5d9e3..45e2cdf54736 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
| @@ -31,12 +31,13 @@ | |||
| 31 | #include <linux/idr.h> | 31 | #include <linux/idr.h> |
| 32 | #include <linux/seq_file.h> | 32 | #include <linux/seq_file.h> |
| 33 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
| 34 | #include <linux/mutex.h> | ||
| 34 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
| 35 | 36 | ||
| 36 | 37 | ||
| 37 | static LIST_HEAD(adapters); | 38 | static LIST_HEAD(adapters); |
| 38 | static LIST_HEAD(drivers); | 39 | static LIST_HEAD(drivers); |
| 39 | static DECLARE_MUTEX(core_lists); | 40 | static DEFINE_MUTEX(core_lists); |
| 40 | static DEFINE_IDR(i2c_adapter_idr); | 41 | static DEFINE_IDR(i2c_adapter_idr); |
| 41 | 42 | ||
| 42 | /* match always succeeds, as we want the probe() to tell if we really accept this match */ | 43 | /* match always succeeds, as we want the probe() to tell if we really accept this match */ |
| @@ -153,7 +154,7 @@ int i2c_add_adapter(struct i2c_adapter *adap) | |||
| 153 | struct list_head *item; | 154 | struct list_head *item; |
| 154 | struct i2c_driver *driver; | 155 | struct i2c_driver *driver; |
| 155 | 156 | ||
| 156 | down(&core_lists); | 157 | mutex_lock(&core_lists); |
| 157 | 158 | ||
| 158 | if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0) { | 159 | if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0) { |
| 159 | res = -ENOMEM; | 160 | res = -ENOMEM; |
| @@ -168,8 +169,8 @@ int i2c_add_adapter(struct i2c_adapter *adap) | |||
| 168 | } | 169 | } |
| 169 | 170 | ||
| 170 | adap->nr = id & MAX_ID_MASK; | 171 | adap->nr = id & MAX_ID_MASK; |
| 171 | init_MUTEX(&adap->bus_lock); | 172 | mutex_init(&adap->bus_lock); |
| 172 | init_MUTEX(&adap->clist_lock); | 173 | mutex_init(&adap->clist_lock); |
| 173 | list_add_tail(&adap->list,&adapters); | 174 | list_add_tail(&adap->list,&adapters); |
| 174 | INIT_LIST_HEAD(&adap->clients); | 175 | INIT_LIST_HEAD(&adap->clients); |
| 175 | 176 | ||
| @@ -203,7 +204,7 @@ int i2c_add_adapter(struct i2c_adapter *adap) | |||
| 203 | } | 204 | } |
| 204 | 205 | ||
| 205 | out_unlock: | 206 | out_unlock: |
| 206 | up(&core_lists); | 207 | mutex_unlock(&core_lists); |
| 207 | return res; | 208 | return res; |
| 208 | } | 209 | } |
| 209 | 210 | ||
| @@ -216,7 +217,7 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
| 216 | struct i2c_client *client; | 217 | struct i2c_client *client; |
| 217 | int res = 0; | 218 | int res = 0; |
| 218 | 219 | ||
| 219 | down(&core_lists); | 220 | mutex_lock(&core_lists); |
| 220 | 221 | ||
| 221 | /* First make sure that this adapter was ever added */ | 222 | /* First make sure that this adapter was ever added */ |
| 222 | list_for_each_entry(adap_from_list, &adapters, list) { | 223 | list_for_each_entry(adap_from_list, &adapters, list) { |
| @@ -272,7 +273,7 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
| 272 | dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name); | 273 | dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name); |
| 273 | 274 | ||
| 274 | out_unlock: | 275 | out_unlock: |
| 275 | up(&core_lists); | 276 | mutex_unlock(&core_lists); |
| 276 | return res; | 277 | return res; |
| 277 | } | 278 | } |
| 278 | 279 | ||
| @@ -287,9 +288,7 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) | |||
| 287 | { | 288 | { |
| 288 | struct list_head *item; | 289 | struct list_head *item; |
| 289 | struct i2c_adapter *adapter; | 290 | struct i2c_adapter *adapter; |
| 290 | int res = 0; | 291 | int res; |
| 291 | |||
| 292 | down(&core_lists); | ||
| 293 | 292 | ||
| 294 | /* add the driver to the list of i2c drivers in the driver core */ | 293 | /* add the driver to the list of i2c drivers in the driver core */ |
| 295 | driver->driver.owner = owner; | 294 | driver->driver.owner = owner; |
| @@ -297,8 +296,10 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) | |||
| 297 | 296 | ||
| 298 | res = driver_register(&driver->driver); | 297 | res = driver_register(&driver->driver); |
| 299 | if (res) | 298 | if (res) |
| 300 | goto out_unlock; | 299 | return res; |
| 301 | 300 | ||
| 301 | mutex_lock(&core_lists); | ||
| 302 | |||
| 302 | list_add_tail(&driver->list,&drivers); | 303 | list_add_tail(&driver->list,&drivers); |
| 303 | pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); | 304 | pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); |
| 304 | 305 | ||
| @@ -310,9 +311,8 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) | |||
| 310 | } | 311 | } |
| 311 | } | 312 | } |
| 312 | 313 | ||
| 313 | out_unlock: | 314 | mutex_unlock(&core_lists); |
| 314 | up(&core_lists); | 315 | return 0; |
| 315 | return res; | ||
| 316 | } | 316 | } |
| 317 | EXPORT_SYMBOL(i2c_register_driver); | 317 | EXPORT_SYMBOL(i2c_register_driver); |
| 318 | 318 | ||
| @@ -324,7 +324,7 @@ int i2c_del_driver(struct i2c_driver *driver) | |||
| 324 | 324 | ||
| 325 | int res = 0; | 325 | int res = 0; |
| 326 | 326 | ||
| 327 | down(&core_lists); | 327 | mutex_lock(&core_lists); |
| 328 | 328 | ||
| 329 | /* Have a look at each adapter, if clients of this driver are still | 329 | /* Have a look at each adapter, if clients of this driver are still |
| 330 | * attached. If so, detach them to be able to kill the driver | 330 | * attached. If so, detach them to be able to kill the driver |
| @@ -363,7 +363,7 @@ int i2c_del_driver(struct i2c_driver *driver) | |||
| 363 | pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name); | 363 | pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name); |
| 364 | 364 | ||
| 365 | out_unlock: | 365 | out_unlock: |
| 366 | up(&core_lists); | 366 | mutex_unlock(&core_lists); |
| 367 | return 0; | 367 | return 0; |
| 368 | } | 368 | } |
| 369 | 369 | ||
| @@ -384,9 +384,9 @@ int i2c_check_addr(struct i2c_adapter *adapter, int addr) | |||
| 384 | { | 384 | { |
| 385 | int rval; | 385 | int rval; |
| 386 | 386 | ||
| 387 | down(&adapter->clist_lock); | 387 | mutex_lock(&adapter->clist_lock); |
| 388 | rval = __i2c_check_addr(adapter, addr); | 388 | rval = __i2c_check_addr(adapter, addr); |
| 389 | up(&adapter->clist_lock); | 389 | mutex_unlock(&adapter->clist_lock); |
| 390 | 390 | ||
| 391 | return rval; | 391 | return rval; |
| 392 | } | 392 | } |
| @@ -395,13 +395,13 @@ int i2c_attach_client(struct i2c_client *client) | |||
| 395 | { | 395 | { |
| 396 | struct i2c_adapter *adapter = client->adapter; | 396 | struct i2c_adapter *adapter = client->adapter; |
| 397 | 397 | ||
| 398 | down(&adapter->clist_lock); | 398 | mutex_lock(&adapter->clist_lock); |
| 399 | if (__i2c_check_addr(client->adapter, client->addr)) { | 399 | if (__i2c_check_addr(client->adapter, client->addr)) { |
| 400 | up(&adapter->clist_lock); | 400 | mutex_unlock(&adapter->clist_lock); |
| 401 | return -EBUSY; | 401 | return -EBUSY; |
| 402 | } | 402 | } |
| 403 | list_add_tail(&client->list,&adapter->clients); | 403 | list_add_tail(&client->list,&adapter->clients); |
| 404 | up(&adapter->clist_lock); | 404 | mutex_unlock(&adapter->clist_lock); |
| 405 | 405 | ||
| 406 | if (adapter->client_register) { | 406 | if (adapter->client_register) { |
| 407 | if (adapter->client_register(client)) { | 407 | if (adapter->client_register(client)) { |
| @@ -450,12 +450,12 @@ int i2c_detach_client(struct i2c_client *client) | |||
| 450 | } | 450 | } |
| 451 | } | 451 | } |
| 452 | 452 | ||
| 453 | down(&adapter->clist_lock); | 453 | mutex_lock(&adapter->clist_lock); |
| 454 | list_del(&client->list); | 454 | list_del(&client->list); |
| 455 | init_completion(&client->released); | 455 | init_completion(&client->released); |
| 456 | device_remove_file(&client->dev, &dev_attr_client_name); | 456 | device_remove_file(&client->dev, &dev_attr_client_name); |
| 457 | device_unregister(&client->dev); | 457 | device_unregister(&client->dev); |
| 458 | up(&adapter->clist_lock); | 458 | mutex_unlock(&adapter->clist_lock); |
| 459 | wait_for_completion(&client->released); | 459 | wait_for_completion(&client->released); |
| 460 | 460 | ||
| 461 | out: | 461 | out: |
| @@ -513,19 +513,19 @@ void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg) | |||
| 513 | struct list_head *item; | 513 | struct list_head *item; |
| 514 | struct i2c_client *client; | 514 | struct i2c_client *client; |
| 515 | 515 | ||
| 516 | down(&adap->clist_lock); | 516 | mutex_lock(&adap->clist_lock); |
| 517 | list_for_each(item,&adap->clients) { | 517 | list_for_each(item,&adap->clients) { |
| 518 | client = list_entry(item, struct i2c_client, list); | 518 | client = list_entry(item, struct i2c_client, list); |
| 519 | if (!try_module_get(client->driver->driver.owner)) | 519 | if (!try_module_get(client->driver->driver.owner)) |
| 520 | continue; | 520 | continue; |
| 521 | if (NULL != client->driver->command) { | 521 | if (NULL != client->driver->command) { |
| 522 | up(&adap->clist_lock); | 522 | mutex_unlock(&adap->clist_lock); |
| 523 | client->driver->command(client,cmd,arg); | 523 | client->driver->command(client,cmd,arg); |
| 524 | down(&adap->clist_lock); | 524 | mutex_lock(&adap->clist_lock); |
| 525 | } | 525 | } |
| 526 | module_put(client->driver->driver.owner); | 526 | module_put(client->driver->driver.owner); |
| 527 | } | 527 | } |
| 528 | up(&adap->clist_lock); | 528 | mutex_unlock(&adap->clist_lock); |
| 529 | } | 529 | } |
| 530 | 530 | ||
| 531 | static int __init i2c_init(void) | 531 | static int __init i2c_init(void) |
| @@ -569,9 +569,9 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num) | |||
| 569 | } | 569 | } |
| 570 | #endif | 570 | #endif |
| 571 | 571 | ||
| 572 | down(&adap->bus_lock); | 572 | mutex_lock(&adap->bus_lock); |
| 573 | ret = adap->algo->master_xfer(adap,msgs,num); | 573 | ret = adap->algo->master_xfer(adap,msgs,num); |
| 574 | up(&adap->bus_lock); | 574 | mutex_unlock(&adap->bus_lock); |
| 575 | 575 | ||
| 576 | return ret; | 576 | return ret; |
| 577 | } else { | 577 | } else { |
| @@ -779,12 +779,12 @@ struct i2c_adapter* i2c_get_adapter(int id) | |||
| 779 | { | 779 | { |
| 780 | struct i2c_adapter *adapter; | 780 | struct i2c_adapter *adapter; |
| 781 | 781 | ||
| 782 | down(&core_lists); | 782 | mutex_lock(&core_lists); |
| 783 | adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id); | 783 | adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id); |
| 784 | if (adapter && !try_module_get(adapter->owner)) | 784 | if (adapter && !try_module_get(adapter->owner)) |
| 785 | adapter = NULL; | 785 | adapter = NULL; |
| 786 | 786 | ||
| 787 | up(&core_lists); | 787 | mutex_unlock(&core_lists); |
| 788 | return adapter; | 788 | return adapter; |
| 789 | } | 789 | } |
| 790 | 790 | ||
| @@ -919,12 +919,11 @@ s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command, | |||
| 919 | u8 length, u8 *values) | 919 | u8 length, u8 *values) |
| 920 | { | 920 | { |
| 921 | union i2c_smbus_data data; | 921 | union i2c_smbus_data data; |
| 922 | int i; | 922 | |
| 923 | if (length > I2C_SMBUS_BLOCK_MAX) | 923 | if (length > I2C_SMBUS_BLOCK_MAX) |
| 924 | length = I2C_SMBUS_BLOCK_MAX; | 924 | length = I2C_SMBUS_BLOCK_MAX; |
| 925 | for (i = 1; i <= length; i++) | ||
| 926 | data.block[i] = values[i-1]; | ||
| 927 | data.block[0] = length; | 925 | data.block[0] = length; |
| 926 | memcpy(&data.block[1], values, length); | ||
| 928 | return i2c_smbus_xfer(client->adapter,client->addr,client->flags, | 927 | return i2c_smbus_xfer(client->adapter,client->addr,client->flags, |
| 929 | I2C_SMBUS_WRITE,command, | 928 | I2C_SMBUS_WRITE,command, |
| 930 | I2C_SMBUS_BLOCK_DATA,&data); | 929 | I2C_SMBUS_BLOCK_DATA,&data); |
| @@ -934,16 +933,14 @@ s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command, | |||
| 934 | s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *values) | 933 | s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *values) |
| 935 | { | 934 | { |
| 936 | union i2c_smbus_data data; | 935 | union i2c_smbus_data data; |
| 937 | int i; | 936 | |
| 938 | if (i2c_smbus_xfer(client->adapter,client->addr,client->flags, | 937 | if (i2c_smbus_xfer(client->adapter,client->addr,client->flags, |
| 939 | I2C_SMBUS_READ,command, | 938 | I2C_SMBUS_READ,command, |
| 940 | I2C_SMBUS_I2C_BLOCK_DATA,&data)) | 939 | I2C_SMBUS_I2C_BLOCK_DATA,&data)) |
| 941 | return -1; | 940 | return -1; |
| 942 | else { | 941 | |
| 943 | for (i = 1; i <= data.block[0]; i++) | 942 | memcpy(values, &data.block[1], data.block[0]); |
| 944 | values[i-1] = data.block[i]; | 943 | return data.block[0]; |
| 945 | return data.block[0]; | ||
| 946 | } | ||
| 947 | } | 944 | } |
| 948 | 945 | ||
| 949 | s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command, | 946 | s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command, |
| @@ -1118,10 +1115,10 @@ s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags, | |||
| 1118 | flags &= I2C_M_TEN | I2C_CLIENT_PEC; | 1115 | flags &= I2C_M_TEN | I2C_CLIENT_PEC; |
| 1119 | 1116 | ||
| 1120 | if (adapter->algo->smbus_xfer) { | 1117 | if (adapter->algo->smbus_xfer) { |
| 1121 | down(&adapter->bus_lock); | 1118 | mutex_lock(&adapter->bus_lock); |
| 1122 | res = adapter->algo->smbus_xfer(adapter,addr,flags,read_write, | 1119 | res = adapter->algo->smbus_xfer(adapter,addr,flags,read_write, |
| 1123 | command,size,data); | 1120 | command,size,data); |
| 1124 | up(&adapter->bus_lock); | 1121 | mutex_unlock(&adapter->bus_lock); |
| 1125 | } else | 1122 | } else |
| 1126 | res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write, | 1123 | res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write, |
| 1127 | command,size,data); | 1124 | command,size,data); |
