diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-23 18:51:32 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-23 18:51:32 -0500 |
commit | b6585dedac232ca79fe978d97a95fdaa6da24f66 (patch) | |
tree | 4d2d78300bb9bcfb40cb35450f78dd3af82c78d3 /drivers/i2c | |
parent | a3ea9b584ed2acdeae817f0dc91a5880e0828a05 (diff) | |
parent | ded2b66615613093eeb83b81499bc270de8fc499 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/i2c-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/i2c-2.6: (36 commits)
[PATCH] hwmon: add required idr locking
[PATCH] I2C: hwmon: Rename register parameters
[PATCH] I2C: Drop unneeded i2c-dev.h includes
[PATCH] I2C: i2c-ixp4xx: Add hwmon class
[PATCH] I2C: i2c-piix4: Add Broadcom HT-1000 support
[PATCH] I2C: i2c-amd756-s4882: Improve static mutex initialization
[PATCH] I2C: i2c-ali1535: Drop redundant mutex
[PATCH] i2c: Cleanup isp1301_omap
[PATCH] i2c: Fix i2c-ite name initialization
[PATCH] i2c: Drop the i2c-frodo bus driver
[PATCH] i2c: Optimize core_lists mutex usage
[PATCH] w83781d: Don't reset the chip by default
[PATCH] w83781d: Document the alarm and beep bits
[PATCH] w83627ehf: Refactor the sysfs interface
[PATCH] hwmon: Support the Pentium M VID code
[PATCH] hwmon: Add support for the Winbond W83687THF
[PATCH] hwmon: f71805f semaphore to mutex conversions
[PATCH] hwmon: Semaphore to mutex conversions
[PATCH] i2c: Semaphore to mutex conversions, part 3
[PATCH] i2c: Semaphore to mutex conversions, part 2
...
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); |