diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2006-01-07 09:40:05 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2006-01-07 09:40:05 -0500 |
commit | 123656d4cc8c946f578ebd18c2050f5251720428 (patch) | |
tree | 3d5432eff034a3b9cfdc98b37e245abe5695342d /drivers/i2c | |
parent | a62c80e559809e6c7851ec04d30575e85ad6f6ed (diff) | |
parent | 0aec63e67c69545ca757a73a66f5dcf05fa484bf (diff) |
Merge with Linus' kernel.
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/busses/i2c-i801.c | 6 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-ibm_iic.c | 1 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-isa.c | 10 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-mv64xxx.c | 33 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-nforce2.c | 2 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-parport.h | 12 | ||||
-rw-r--r-- | drivers/i2c/chips/ds1337.c | 43 | ||||
-rw-r--r-- | drivers/i2c/chips/ds1374.c | 6 | ||||
-rw-r--r-- | drivers/i2c/chips/eeprom.c | 6 | ||||
-rw-r--r-- | drivers/i2c/chips/isp1301_omap.c | 6 | ||||
-rw-r--r-- | drivers/i2c/chips/m41t00.c | 6 | ||||
-rw-r--r-- | drivers/i2c/chips/max6875.c | 6 | ||||
-rw-r--r-- | drivers/i2c/chips/pca9539.c | 6 | ||||
-rw-r--r-- | drivers/i2c/chips/pcf8574.c | 6 | ||||
-rw-r--r-- | drivers/i2c/chips/pcf8591.c | 6 | ||||
-rw-r--r-- | drivers/i2c/chips/rtc8564.c | 43 | ||||
-rw-r--r-- | drivers/i2c/chips/tps65010.c | 6 | ||||
-rw-r--r-- | drivers/i2c/chips/x1205.c | 6 | ||||
-rw-r--r-- | drivers/i2c/i2c-core.c | 70 | ||||
-rw-r--r-- | drivers/i2c/i2c-dev.c | 63 |
20 files changed, 165 insertions, 178 deletions
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index ac3eafa8aac0..1c752ddc10e2 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
@@ -468,8 +468,7 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr, | |||
468 | return -1; | 468 | return -1; |
469 | } | 469 | } |
470 | 470 | ||
471 | if (hwpec) | 471 | outb_p(hwpec, SMBAUXCTL); /* enable/disable hardware PEC */ |
472 | outb_p(1, SMBAUXCTL); /* enable hardware PEC */ | ||
473 | 472 | ||
474 | if(block) | 473 | if(block) |
475 | ret = i801_block_transaction(data, read_write, size, hwpec); | 474 | ret = i801_block_transaction(data, read_write, size, hwpec); |
@@ -478,9 +477,6 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr, | |||
478 | ret = i801_transaction(); | 477 | ret = i801_transaction(); |
479 | } | 478 | } |
480 | 479 | ||
481 | if (hwpec) | ||
482 | outb_p(0, SMBAUXCTL); /* disable hardware PEC */ | ||
483 | |||
484 | if(block) | 480 | if(block) |
485 | return ret; | 481 | return ret; |
486 | if(ret) | 482 | if(ret) |
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index 1a587253d716..87fae937e666 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c | |||
@@ -725,6 +725,7 @@ static int __devinit iic_probe(struct ocp_device *ocp){ | |||
725 | strcpy(adap->name, "IBM IIC"); | 725 | strcpy(adap->name, "IBM IIC"); |
726 | i2c_set_adapdata(adap, dev); | 726 | i2c_set_adapdata(adap, dev); |
727 | adap->id = I2C_HW_OCP; | 727 | adap->id = I2C_HW_OCP; |
728 | adap->class = I2C_CLASS_HWMON; | ||
728 | adap->algo = &iic_algo; | 729 | adap->algo = &iic_algo; |
729 | adap->client_register = NULL; | 730 | adap->client_register = NULL; |
730 | adap->client_unregister = NULL; | 731 | adap->client_unregister = NULL; |
diff --git a/drivers/i2c/busses/i2c-isa.c b/drivers/i2c/busses/i2c-isa.c index 03672c9ca409..9f2ffef4d812 100644 --- a/drivers/i2c/busses/i2c-isa.c +++ b/drivers/i2c/busses/i2c-isa.c | |||
@@ -92,15 +92,13 @@ int i2c_isa_add_driver(struct i2c_driver *driver) | |||
92 | int res; | 92 | int res; |
93 | 93 | ||
94 | /* Add the driver to the list of i2c drivers in the driver core */ | 94 | /* Add the driver to the list of i2c drivers in the driver core */ |
95 | driver->driver.name = driver->name; | ||
96 | driver->driver.owner = driver->owner; | ||
97 | driver->driver.bus = &i2c_bus_type; | 95 | driver->driver.bus = &i2c_bus_type; |
98 | driver->driver.probe = i2c_isa_device_probe; | 96 | driver->driver.probe = i2c_isa_device_probe; |
99 | driver->driver.remove = i2c_isa_device_remove; | 97 | driver->driver.remove = i2c_isa_device_remove; |
100 | res = driver_register(&driver->driver); | 98 | res = driver_register(&driver->driver); |
101 | if (res) | 99 | if (res) |
102 | return res; | 100 | return res; |
103 | dev_dbg(&isa_adapter.dev, "Driver %s registered\n", driver->name); | 101 | dev_dbg(&isa_adapter.dev, "Driver %s registered\n", driver->driver.name); |
104 | 102 | ||
105 | /* Now look for clients */ | 103 | /* Now look for clients */ |
106 | driver->attach_adapter(&isa_adapter); | 104 | driver->attach_adapter(&isa_adapter); |
@@ -124,14 +122,14 @@ int i2c_isa_del_driver(struct i2c_driver *driver) | |||
124 | if ((res = driver->detach_client(client))) { | 122 | if ((res = driver->detach_client(client))) { |
125 | dev_err(&isa_adapter.dev, "Failed, driver " | 123 | dev_err(&isa_adapter.dev, "Failed, driver " |
126 | "%s not unregistered!\n", | 124 | "%s not unregistered!\n", |
127 | driver->name); | 125 | driver->driver.name); |
128 | return res; | 126 | return res; |
129 | } | 127 | } |
130 | } | 128 | } |
131 | 129 | ||
132 | /* Get the driver off the core list */ | 130 | /* Get the driver off the core list */ |
133 | driver_unregister(&driver->driver); | 131 | driver_unregister(&driver->driver); |
134 | dev_dbg(&isa_adapter.dev, "Driver %s unregistered\n", driver->name); | 132 | dev_dbg(&isa_adapter.dev, "Driver %s unregistered\n", driver->driver.name); |
135 | 133 | ||
136 | return 0; | 134 | return 0; |
137 | } | 135 | } |
@@ -176,7 +174,7 @@ static void __exit i2c_isa_exit(void) | |||
176 | list_for_each_safe(item, _n, &isa_adapter.clients) { | 174 | list_for_each_safe(item, _n, &isa_adapter.clients) { |
177 | client = list_entry(item, struct i2c_client, list); | 175 | client = list_entry(item, struct i2c_client, list); |
178 | dev_err(&isa_adapter.dev, "Driver %s still has an active " | 176 | dev_err(&isa_adapter.dev, "Driver %s still has an active " |
179 | "ISA client at 0x%x\n", client->driver->name, | 177 | "ISA client at 0x%x\n", client->driver->driver.name, |
180 | client->addr); | 178 | client->addr); |
181 | } | 179 | } |
182 | if (client != NULL) | 180 | if (client != NULL) |
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index 81031eb51056..22781d84f79f 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * drivers/i2c/busses/i2c-mv64xxx.c | ||
3 | * | ||
4 | * Driver for the i2c controller on the Marvell line of host bridges for MIPS | 2 | * Driver for the i2c controller on the Marvell line of host bridges for MIPS |
5 | * and PPC (e.g, gt642[46]0, mv643[46]0, mv644[46]0). | 3 | * and PPC (e.g, gt642[46]0, mv643[46]0, mv644[46]0). |
6 | * | 4 | * |
@@ -65,7 +63,6 @@ enum { | |||
65 | MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK, | 63 | MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK, |
66 | MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK, | 64 | MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK, |
67 | MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA, | 65 | MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA, |
68 | MV64XXX_I2C_STATE_ABORTING, | ||
69 | }; | 66 | }; |
70 | 67 | ||
71 | /* Driver actions */ | 68 | /* Driver actions */ |
@@ -85,6 +82,7 @@ struct mv64xxx_i2c_data { | |||
85 | int irq; | 82 | int irq; |
86 | u32 state; | 83 | u32 state; |
87 | u32 action; | 84 | u32 action; |
85 | u32 aborting; | ||
88 | u32 cntl_bits; | 86 | u32 cntl_bits; |
89 | void __iomem *reg_base; | 87 | void __iomem *reg_base; |
90 | u32 reg_base_p; | 88 | u32 reg_base_p; |
@@ -122,12 +120,6 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status) | |||
122 | return; | 120 | return; |
123 | } | 121 | } |
124 | 122 | ||
125 | if (drv_data->state == MV64XXX_I2C_STATE_ABORTING) { | ||
126 | drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP; | ||
127 | drv_data->state = MV64XXX_I2C_STATE_IDLE; | ||
128 | return; | ||
129 | } | ||
130 | |||
131 | /* The status from the ctlr [mostly] tells us what to do next */ | 123 | /* The status from the ctlr [mostly] tells us what to do next */ |
132 | switch (status) { | 124 | switch (status) { |
133 | /* Start condition interrupt */ | 125 | /* Start condition interrupt */ |
@@ -148,14 +140,16 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status) | |||
148 | /* FALLTHRU */ | 140 | /* FALLTHRU */ |
149 | case MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_ACK: /* 0xd0 */ | 141 | case MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_ACK: /* 0xd0 */ |
150 | case MV64XXX_I2C_STATUS_MAST_WR_ACK: /* 0x28 */ | 142 | case MV64XXX_I2C_STATUS_MAST_WR_ACK: /* 0x28 */ |
151 | if (drv_data->bytes_left > 0) { | 143 | if ((drv_data->bytes_left == 0) |
144 | || (drv_data->aborting | ||
145 | && (drv_data->byte_posn != 0))) { | ||
146 | drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP; | ||
147 | drv_data->state = MV64XXX_I2C_STATE_IDLE; | ||
148 | } else { | ||
152 | drv_data->action = MV64XXX_I2C_ACTION_SEND_DATA; | 149 | drv_data->action = MV64XXX_I2C_ACTION_SEND_DATA; |
153 | drv_data->state = | 150 | drv_data->state = |
154 | MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK; | 151 | MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK; |
155 | drv_data->bytes_left--; | 152 | drv_data->bytes_left--; |
156 | } else { | ||
157 | drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP; | ||
158 | drv_data->state = MV64XXX_I2C_STATE_IDLE; | ||
159 | } | 153 | } |
160 | break; | 154 | break; |
161 | 155 | ||
@@ -184,7 +178,7 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status) | |||
184 | } | 178 | } |
185 | drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA; | 179 | drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA; |
186 | 180 | ||
187 | if (drv_data->bytes_left == 1) | 181 | if ((drv_data->bytes_left == 1) || drv_data->aborting) |
188 | drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_ACK; | 182 | drv_data->cntl_bits &= ~MV64XXX_I2C_REG_CONTROL_ACK; |
189 | break; | 183 | break; |
190 | 184 | ||
@@ -320,6 +314,7 @@ mv64xxx_i2c_prepare_for_io(struct mv64xxx_i2c_data *drv_data, | |||
320 | drv_data->msg = msg; | 314 | drv_data->msg = msg; |
321 | drv_data->byte_posn = 0; | 315 | drv_data->byte_posn = 0; |
322 | drv_data->bytes_left = msg->len; | 316 | drv_data->bytes_left = msg->len; |
317 | drv_data->aborting = 0; | ||
323 | drv_data->rc = 0; | 318 | drv_data->rc = 0; |
324 | drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK | | 319 | drv_data->cntl_bits = MV64XXX_I2C_REG_CONTROL_ACK | |
325 | MV64XXX_I2C_REG_CONTROL_INTEN | MV64XXX_I2C_REG_CONTROL_TWSIEN; | 320 | MV64XXX_I2C_REG_CONTROL_INTEN | MV64XXX_I2C_REG_CONTROL_TWSIEN; |
@@ -359,17 +354,19 @@ mv64xxx_i2c_wait_for_completion(struct mv64xxx_i2c_data *drv_data) | |||
359 | } | 354 | } |
360 | 355 | ||
361 | if (abort && drv_data->block) { | 356 | if (abort && drv_data->block) { |
362 | drv_data->state = MV64XXX_I2C_STATE_ABORTING; | 357 | drv_data->aborting = 1; |
363 | spin_unlock_irqrestore(&drv_data->lock, flags); | 358 | spin_unlock_irqrestore(&drv_data->lock, flags); |
364 | 359 | ||
365 | time_left = wait_event_timeout(drv_data->waitq, | 360 | time_left = wait_event_timeout(drv_data->waitq, |
366 | !drv_data->block, | 361 | !drv_data->block, |
367 | msecs_to_jiffies(drv_data->adapter.timeout)); | 362 | msecs_to_jiffies(drv_data->adapter.timeout)); |
368 | 363 | ||
369 | if (time_left <= 0) { | 364 | if ((time_left <= 0) && drv_data->block) { |
370 | drv_data->state = MV64XXX_I2C_STATE_IDLE; | 365 | drv_data->state = MV64XXX_I2C_STATE_IDLE; |
371 | dev_err(&drv_data->adapter.dev, | 366 | dev_err(&drv_data->adapter.dev, |
372 | "mv64xxx: I2C bus locked\n"); | 367 | "mv64xxx: I2C bus locked, block: %d, " |
368 | "time_left: %d\n", drv_data->block, | ||
369 | (int)time_left); | ||
373 | } | 370 | } |
374 | } else | 371 | } else |
375 | spin_unlock_irqrestore(&drv_data->lock, flags); | 372 | spin_unlock_irqrestore(&drv_data->lock, flags); |
@@ -510,7 +507,7 @@ mv64xxx_i2c_probe(struct platform_device *pd) | |||
510 | goto exit_kfree; | 507 | goto exit_kfree; |
511 | } | 508 | } |
512 | 509 | ||
513 | strncpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter", | 510 | strlcpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter", |
514 | I2C_NAME_SIZE); | 511 | I2C_NAME_SIZE); |
515 | 512 | ||
516 | init_waitqueue_head(&drv_data->waitq); | 513 | init_waitqueue_head(&drv_data->waitq); |
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index 4d18e6e5f159..2d80eb26f688 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c | |||
@@ -30,6 +30,7 @@ | |||
30 | nForce3 Pro150 MCP 00D4 | 30 | nForce3 Pro150 MCP 00D4 |
31 | nForce3 250Gb MCP 00E4 | 31 | nForce3 250Gb MCP 00E4 |
32 | nForce4 MCP 0052 | 32 | nForce4 MCP 0052 |
33 | nForce4 MCP-04 0034 | ||
33 | 34 | ||
34 | This driver supports the 2 SMBuses that are included in the MCP of the | 35 | This driver supports the 2 SMBuses that are included in the MCP of the |
35 | nForce2/3/4 chipsets. | 36 | nForce2/3/4 chipsets. |
@@ -257,6 +258,7 @@ static struct pci_device_id nforce2_ids[] = { | |||
257 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS) }, | 258 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS) }, |
258 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS) }, | 259 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS) }, |
259 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS) }, | 260 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS) }, |
261 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS) }, | ||
260 | { 0 } | 262 | { 0 } |
261 | }; | 263 | }; |
262 | 264 | ||
diff --git a/drivers/i2c/busses/i2c-parport.h b/drivers/i2c/busses/i2c-parport.h index f63a53779281..d702e5e0388d 100644 --- a/drivers/i2c/busses/i2c-parport.h +++ b/drivers/i2c/busses/i2c-parport.h | |||
@@ -80,6 +80,14 @@ static struct adapter_parm adapter_parm[] = { | |||
80 | .setscl = { 0x01, DATA, 1 }, | 80 | .setscl = { 0x01, DATA, 1 }, |
81 | .getsda = { 0x10, STAT, 1 }, | 81 | .getsda = { 0x10, STAT, 1 }, |
82 | }, | 82 | }, |
83 | /* type 6: Barco LPT->DVI (K5800236) adapter */ | ||
84 | { | ||
85 | .setsda = { 0x02, DATA, 1 }, | ||
86 | .setscl = { 0x01, DATA, 1 }, | ||
87 | .getsda = { 0x20, STAT, 0 }, | ||
88 | .getscl = { 0x40, STAT, 0 }, | ||
89 | .init = { 0xfc, DATA, 0 }, | ||
90 | }, | ||
83 | }; | 91 | }; |
84 | 92 | ||
85 | static int type; | 93 | static int type; |
@@ -91,4 +99,6 @@ MODULE_PARM_DESC(type, | |||
91 | " 2 = Velleman K8000 adapter\n" | 99 | " 2 = Velleman K8000 adapter\n" |
92 | " 3 = ELV adapter\n" | 100 | " 3 = ELV adapter\n" |
93 | " 4 = ADM1032 evaluation board\n" | 101 | " 4 = ADM1032 evaluation board\n" |
94 | " 5 = ADM1025, ADM1030 and ADM1031 evaluation boards\n"); | 102 | " 5 = ADM1025, ADM1030 and ADM1031 evaluation boards\n" |
103 | " 6 = Barco LPT->DVI (K5800236) adapter\n" | ||
104 | ); | ||
diff --git a/drivers/i2c/chips/ds1337.c b/drivers/i2c/chips/ds1337.c index 02682fb794c8..93d483b8b770 100644 --- a/drivers/i2c/chips/ds1337.c +++ b/drivers/i2c/chips/ds1337.c | |||
@@ -52,9 +52,9 @@ static int ds1337_command(struct i2c_client *client, unsigned int cmd, | |||
52 | * Driver data (common to all clients) | 52 | * Driver data (common to all clients) |
53 | */ | 53 | */ |
54 | static struct i2c_driver ds1337_driver = { | 54 | static struct i2c_driver ds1337_driver = { |
55 | .owner = THIS_MODULE, | 55 | .driver = { |
56 | .name = "ds1337", | 56 | .name = "ds1337", |
57 | .flags = I2C_DF_NOTIFY, | 57 | }, |
58 | .attach_adapter = ds1337_attach_adapter, | 58 | .attach_adapter = ds1337_attach_adapter, |
59 | .detach_client = ds1337_detach_client, | 59 | .detach_client = ds1337_detach_client, |
60 | .command = ds1337_command, | 60 | .command = ds1337_command, |
@@ -337,13 +337,38 @@ exit: | |||
337 | 337 | ||
338 | static void ds1337_init_client(struct i2c_client *client) | 338 | static void ds1337_init_client(struct i2c_client *client) |
339 | { | 339 | { |
340 | s32 val; | 340 | u8 status, control; |
341 | 341 | ||
342 | /* Ensure that device is set in 24-hour mode */ | 342 | /* On some boards, the RTC isn't configured by boot firmware. |
343 | val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR); | 343 | * Handle that case by starting/configuring the RTC now. |
344 | if ((val >= 0) && (val & (1 << 6))) | 344 | */ |
345 | i2c_smbus_write_byte_data(client, DS1337_REG_HOUR, | 345 | status = i2c_smbus_read_byte_data(client, DS1337_REG_STATUS); |
346 | val & 0x3f); | 346 | control = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL); |
347 | |||
348 | if ((status & 0x80) || (control & 0x80)) { | ||
349 | /* RTC not running */ | ||
350 | u8 buf[16]; | ||
351 | struct i2c_msg msg[1]; | ||
352 | |||
353 | dev_dbg(&client->dev, "%s: RTC not running!\n", __FUNCTION__); | ||
354 | |||
355 | /* Initialize all, including STATUS and CONTROL to zero */ | ||
356 | memset(buf, 0, sizeof(buf)); | ||
357 | msg[0].addr = client->addr; | ||
358 | msg[0].flags = 0; | ||
359 | msg[0].len = sizeof(buf); | ||
360 | msg[0].buf = &buf[0]; | ||
361 | |||
362 | i2c_transfer(client->adapter, msg, 1); | ||
363 | } else { | ||
364 | /* Running: ensure that device is set in 24-hour mode */ | ||
365 | s32 val; | ||
366 | |||
367 | val = i2c_smbus_read_byte_data(client, DS1337_REG_HOUR); | ||
368 | if ((val >= 0) && (val & (1 << 6))) | ||
369 | i2c_smbus_write_byte_data(client, DS1337_REG_HOUR, | ||
370 | val & 0x3f); | ||
371 | } | ||
347 | } | 372 | } |
348 | 373 | ||
349 | static int ds1337_detach_client(struct i2c_client *client) | 374 | static int ds1337_detach_client(struct i2c_client *client) |
diff --git a/drivers/i2c/chips/ds1374.c b/drivers/i2c/chips/ds1374.c index da488b735abf..0710b9da9d54 100644 --- a/drivers/i2c/chips/ds1374.c +++ b/drivers/i2c/chips/ds1374.c | |||
@@ -232,10 +232,10 @@ static int ds1374_detach(struct i2c_client *client) | |||
232 | } | 232 | } |
233 | 233 | ||
234 | static struct i2c_driver ds1374_driver = { | 234 | static struct i2c_driver ds1374_driver = { |
235 | .owner = THIS_MODULE, | 235 | .driver = { |
236 | .name = DS1374_DRV_NAME, | 236 | .name = DS1374_DRV_NAME, |
237 | }, | ||
237 | .id = I2C_DRIVERID_DS1374, | 238 | .id = I2C_DRIVERID_DS1374, |
238 | .flags = I2C_DF_NOTIFY, | ||
239 | .attach_adapter = ds1374_attach, | 239 | .attach_adapter = ds1374_attach, |
240 | .detach_client = ds1374_detach, | 240 | .detach_client = ds1374_detach, |
241 | }; | 241 | }; |
diff --git a/drivers/i2c/chips/eeprom.c b/drivers/i2c/chips/eeprom.c index 4baf573fa04f..41116b7947f6 100644 --- a/drivers/i2c/chips/eeprom.c +++ b/drivers/i2c/chips/eeprom.c | |||
@@ -68,10 +68,10 @@ static int eeprom_detach_client(struct i2c_client *client); | |||
68 | 68 | ||
69 | /* This is the driver that will be inserted */ | 69 | /* This is the driver that will be inserted */ |
70 | static struct i2c_driver eeprom_driver = { | 70 | static struct i2c_driver eeprom_driver = { |
71 | .owner = THIS_MODULE, | 71 | .driver = { |
72 | .name = "eeprom", | 72 | .name = "eeprom", |
73 | }, | ||
73 | .id = I2C_DRIVERID_EEPROM, | 74 | .id = I2C_DRIVERID_EEPROM, |
74 | .flags = I2C_DF_NOTIFY, | ||
75 | .attach_adapter = eeprom_attach_adapter, | 75 | .attach_adapter = eeprom_attach_adapter, |
76 | .detach_client = eeprom_detach_client, | 76 | .detach_client = eeprom_detach_client, |
77 | }; | 77 | }; |
diff --git a/drivers/i2c/chips/isp1301_omap.c b/drivers/i2c/chips/isp1301_omap.c index d2a100d77839..1251c7fc18d5 100644 --- a/drivers/i2c/chips/isp1301_omap.c +++ b/drivers/i2c/chips/isp1301_omap.c | |||
@@ -1632,11 +1632,11 @@ static int isp1301_scan_bus(struct i2c_adapter *bus) | |||
1632 | } | 1632 | } |
1633 | 1633 | ||
1634 | static struct i2c_driver isp1301_driver = { | 1634 | static struct i2c_driver isp1301_driver = { |
1635 | .owner = THIS_MODULE, | 1635 | .driver = { |
1636 | .name = "isp1301_omap", | 1636 | .name = "isp1301_omap", |
1637 | }, | ||
1637 | .id = 1301, /* FIXME "official", i2c-ids.h */ | 1638 | .id = 1301, /* FIXME "official", i2c-ids.h */ |
1638 | .class = I2C_CLASS_HWMON, | 1639 | .class = I2C_CLASS_HWMON, |
1639 | .flags = I2C_DF_NOTIFY, | ||
1640 | .attach_adapter = isp1301_scan_bus, | 1640 | .attach_adapter = isp1301_scan_bus, |
1641 | .detach_client = isp1301_detach_client, | 1641 | .detach_client = isp1301_detach_client, |
1642 | }; | 1642 | }; |
diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c index 3df309ae44a6..2dc3d48375fc 100644 --- a/drivers/i2c/chips/m41t00.c +++ b/drivers/i2c/chips/m41t00.c | |||
@@ -211,10 +211,10 @@ m41t00_detach(struct i2c_client *client) | |||
211 | } | 211 | } |
212 | 212 | ||
213 | static struct i2c_driver m41t00_driver = { | 213 | static struct i2c_driver m41t00_driver = { |
214 | .owner = THIS_MODULE, | 214 | .driver = { |
215 | .name = M41T00_DRV_NAME, | 215 | .name = M41T00_DRV_NAME, |
216 | }, | ||
216 | .id = I2C_DRIVERID_STM41T00, | 217 | .id = I2C_DRIVERID_STM41T00, |
217 | .flags = I2C_DF_NOTIFY, | ||
218 | .attach_adapter = m41t00_attach, | 218 | .attach_adapter = m41t00_attach, |
219 | .detach_client = m41t00_detach, | 219 | .detach_client = m41t00_detach, |
220 | }; | 220 | }; |
diff --git a/drivers/i2c/chips/max6875.c b/drivers/i2c/chips/max6875.c index b376a006883c..6d3ff584155e 100644 --- a/drivers/i2c/chips/max6875.c +++ b/drivers/i2c/chips/max6875.c | |||
@@ -67,9 +67,9 @@ static int max6875_detach_client(struct i2c_client *client); | |||
67 | 67 | ||
68 | /* This is the driver that will be inserted */ | 68 | /* This is the driver that will be inserted */ |
69 | static struct i2c_driver max6875_driver = { | 69 | static struct i2c_driver max6875_driver = { |
70 | .owner = THIS_MODULE, | 70 | .driver = { |
71 | .name = "max6875", | 71 | .name = "max6875", |
72 | .flags = I2C_DF_NOTIFY, | 72 | }, |
73 | .attach_adapter = max6875_attach_adapter, | 73 | .attach_adapter = max6875_attach_adapter, |
74 | .detach_client = max6875_detach_client, | 74 | .detach_client = max6875_detach_client, |
75 | }; | 75 | }; |
diff --git a/drivers/i2c/chips/pca9539.c b/drivers/i2c/chips/pca9539.c index 59a930346229..54b6e6a4beed 100644 --- a/drivers/i2c/chips/pca9539.c +++ b/drivers/i2c/chips/pca9539.c | |||
@@ -38,9 +38,9 @@ static int pca9539_detach_client(struct i2c_client *client); | |||
38 | 38 | ||
39 | /* This is the driver that will be inserted */ | 39 | /* This is the driver that will be inserted */ |
40 | static struct i2c_driver pca9539_driver = { | 40 | static struct i2c_driver pca9539_driver = { |
41 | .owner = THIS_MODULE, | 41 | .driver = { |
42 | .name = "pca9539", | 42 | .name = "pca9539", |
43 | .flags = I2C_DF_NOTIFY, | 43 | }, |
44 | .attach_adapter = pca9539_attach_adapter, | 44 | .attach_adapter = pca9539_attach_adapter, |
45 | .detach_client = pca9539_detach_client, | 45 | .detach_client = pca9539_detach_client, |
46 | }; | 46 | }; |
diff --git a/drivers/i2c/chips/pcf8574.c b/drivers/i2c/chips/pcf8574.c index c323c2de236c..c3e6449c4481 100644 --- a/drivers/i2c/chips/pcf8574.c +++ b/drivers/i2c/chips/pcf8574.c | |||
@@ -65,10 +65,10 @@ static void pcf8574_init_client(struct i2c_client *client); | |||
65 | 65 | ||
66 | /* This is the driver that will be inserted */ | 66 | /* This is the driver that will be inserted */ |
67 | static struct i2c_driver pcf8574_driver = { | 67 | static struct i2c_driver pcf8574_driver = { |
68 | .owner = THIS_MODULE, | 68 | .driver = { |
69 | .name = "pcf8574", | 69 | .name = "pcf8574", |
70 | }, | ||
70 | .id = I2C_DRIVERID_PCF8574, | 71 | .id = I2C_DRIVERID_PCF8574, |
71 | .flags = I2C_DF_NOTIFY, | ||
72 | .attach_adapter = pcf8574_attach_adapter, | 72 | .attach_adapter = pcf8574_attach_adapter, |
73 | .detach_client = pcf8574_detach_client, | 73 | .detach_client = pcf8574_detach_client, |
74 | }; | 74 | }; |
diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/i2c/chips/pcf8591.c index ce420a67560b..36cff09c678d 100644 --- a/drivers/i2c/chips/pcf8591.c +++ b/drivers/i2c/chips/pcf8591.c | |||
@@ -88,10 +88,10 @@ static int pcf8591_read_channel(struct device *dev, int channel); | |||
88 | 88 | ||
89 | /* This is the driver that will be inserted */ | 89 | /* This is the driver that will be inserted */ |
90 | static struct i2c_driver pcf8591_driver = { | 90 | static struct i2c_driver pcf8591_driver = { |
91 | .owner = THIS_MODULE, | 91 | .driver = { |
92 | .name = "pcf8591", | 92 | .name = "pcf8591", |
93 | }, | ||
93 | .id = I2C_DRIVERID_PCF8591, | 94 | .id = I2C_DRIVERID_PCF8591, |
94 | .flags = I2C_DF_NOTIFY, | ||
95 | .attach_adapter = pcf8591_attach_adapter, | 95 | .attach_adapter = pcf8591_attach_adapter, |
96 | .detach_client = pcf8591_detach_client, | 96 | .detach_client = pcf8591_detach_client, |
97 | }; | 97 | }; |
diff --git a/drivers/i2c/chips/rtc8564.c b/drivers/i2c/chips/rtc8564.c index 916cdc1af23c..ceaa6b0bdfd6 100644 --- a/drivers/i2c/chips/rtc8564.c +++ b/drivers/i2c/chips/rtc8564.c | |||
@@ -14,6 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/bcd.h> | ||
17 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
19 | #include <linux/string.h> | 20 | #include <linux/string.h> |
@@ -52,9 +53,6 @@ static inline u8 _rtc8564_ctrl2(struct i2c_client *client) | |||
52 | #define CTRL1(c) _rtc8564_ctrl1(c) | 53 | #define CTRL1(c) _rtc8564_ctrl1(c) |
53 | #define CTRL2(c) _rtc8564_ctrl2(c) | 54 | #define CTRL2(c) _rtc8564_ctrl2(c) |
54 | 55 | ||
55 | #define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10) | ||
56 | #define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10) | ||
57 | |||
58 | static int debug;; | 56 | static int debug;; |
59 | module_param(debug, int, S_IRUGO | S_IWUSR); | 57 | module_param(debug, int, S_IRUGO | S_IWUSR); |
60 | 58 | ||
@@ -157,7 +155,6 @@ static int rtc8564_attach(struct i2c_adapter *adap, int addr, int kind) | |||
157 | 155 | ||
158 | strlcpy(new_client->name, "RTC8564", I2C_NAME_SIZE); | 156 | strlcpy(new_client->name, "RTC8564", I2C_NAME_SIZE); |
159 | i2c_set_clientdata(new_client, d); | 157 | i2c_set_clientdata(new_client, d); |
160 | new_client->flags = I2C_CLIENT_ALLOW_USE; | ||
161 | new_client->addr = addr; | 158 | new_client->addr = addr; |
162 | new_client->adapter = adap; | 159 | new_client->adapter = adap; |
163 | new_client->driver = &rtc8564_driver; | 160 | new_client->driver = &rtc8564_driver; |
@@ -224,16 +221,16 @@ static int rtc8564_get_datetime(struct i2c_client *client, struct rtc_tm *dt) | |||
224 | return ret; | 221 | return ret; |
225 | 222 | ||
226 | /* century stored in minute alarm reg */ | 223 | /* century stored in minute alarm reg */ |
227 | dt->year = BCD_TO_BIN(buf[RTC8564_REG_YEAR]); | 224 | dt->year = BCD2BIN(buf[RTC8564_REG_YEAR]); |
228 | dt->year += 100 * BCD_TO_BIN(buf[RTC8564_REG_AL_MIN] & 0x3f); | 225 | dt->year += 100 * BCD2BIN(buf[RTC8564_REG_AL_MIN] & 0x3f); |
229 | dt->mday = BCD_TO_BIN(buf[RTC8564_REG_DAY] & 0x3f); | 226 | dt->mday = BCD2BIN(buf[RTC8564_REG_DAY] & 0x3f); |
230 | dt->wday = BCD_TO_BIN(buf[RTC8564_REG_WDAY] & 7); | 227 | dt->wday = BCD2BIN(buf[RTC8564_REG_WDAY] & 7); |
231 | dt->mon = BCD_TO_BIN(buf[RTC8564_REG_MON_CENT] & 0x1f); | 228 | dt->mon = BCD2BIN(buf[RTC8564_REG_MON_CENT] & 0x1f); |
232 | 229 | ||
233 | dt->secs = BCD_TO_BIN(buf[RTC8564_REG_SEC] & 0x7f); | 230 | dt->secs = BCD2BIN(buf[RTC8564_REG_SEC] & 0x7f); |
234 | dt->vl = (buf[RTC8564_REG_SEC] & 0x80) == 0x80; | 231 | dt->vl = (buf[RTC8564_REG_SEC] & 0x80) == 0x80; |
235 | dt->mins = BCD_TO_BIN(buf[RTC8564_REG_MIN] & 0x7f); | 232 | dt->mins = BCD2BIN(buf[RTC8564_REG_MIN] & 0x7f); |
236 | dt->hours = BCD_TO_BIN(buf[RTC8564_REG_HR] & 0x3f); | 233 | dt->hours = BCD2BIN(buf[RTC8564_REG_HR] & 0x3f); |
237 | 234 | ||
238 | _DBGRTCTM(2, *dt); | 235 | _DBGRTCTM(2, *dt); |
239 | 236 | ||
@@ -255,18 +252,18 @@ rtc8564_set_datetime(struct i2c_client *client, struct rtc_tm *dt, int datetoo) | |||
255 | 252 | ||
256 | buf[RTC8564_REG_CTRL1] = CTRL1(client) | RTC8564_CTRL1_STOP; | 253 | buf[RTC8564_REG_CTRL1] = CTRL1(client) | RTC8564_CTRL1_STOP; |
257 | buf[RTC8564_REG_CTRL2] = CTRL2(client); | 254 | buf[RTC8564_REG_CTRL2] = CTRL2(client); |
258 | buf[RTC8564_REG_SEC] = BIN_TO_BCD(dt->secs); | 255 | buf[RTC8564_REG_SEC] = BIN2BCD(dt->secs); |
259 | buf[RTC8564_REG_MIN] = BIN_TO_BCD(dt->mins); | 256 | buf[RTC8564_REG_MIN] = BIN2BCD(dt->mins); |
260 | buf[RTC8564_REG_HR] = BIN_TO_BCD(dt->hours); | 257 | buf[RTC8564_REG_HR] = BIN2BCD(dt->hours); |
261 | 258 | ||
262 | if (datetoo) { | 259 | if (datetoo) { |
263 | len += 5; | 260 | len += 5; |
264 | buf[RTC8564_REG_DAY] = BIN_TO_BCD(dt->mday); | 261 | buf[RTC8564_REG_DAY] = BIN2BCD(dt->mday); |
265 | buf[RTC8564_REG_WDAY] = BIN_TO_BCD(dt->wday); | 262 | buf[RTC8564_REG_WDAY] = BIN2BCD(dt->wday); |
266 | buf[RTC8564_REG_MON_CENT] = BIN_TO_BCD(dt->mon) & 0x1f; | 263 | buf[RTC8564_REG_MON_CENT] = BIN2BCD(dt->mon) & 0x1f; |
267 | /* century stored in minute alarm reg */ | 264 | /* century stored in minute alarm reg */ |
268 | buf[RTC8564_REG_YEAR] = BIN_TO_BCD(dt->year % 100); | 265 | buf[RTC8564_REG_YEAR] = BIN2BCD(dt->year % 100); |
269 | buf[RTC8564_REG_AL_MIN] = BIN_TO_BCD(dt->year / 100); | 266 | buf[RTC8564_REG_AL_MIN] = BIN2BCD(dt->year / 100); |
270 | } | 267 | } |
271 | 268 | ||
272 | ret = rtc8564_write(client, 0, buf, len); | 269 | ret = rtc8564_write(client, 0, buf, len); |
@@ -361,10 +358,10 @@ rtc8564_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
361 | } | 358 | } |
362 | 359 | ||
363 | static struct i2c_driver rtc8564_driver = { | 360 | static struct i2c_driver rtc8564_driver = { |
364 | .owner = THIS_MODULE, | 361 | .driver = { |
365 | .name = "RTC8564", | 362 | .name = "RTC8564", |
363 | }, | ||
366 | .id = I2C_DRIVERID_RTC8564, | 364 | .id = I2C_DRIVERID_RTC8564, |
367 | .flags = I2C_DF_NOTIFY, | ||
368 | .attach_adapter = rtc8564_probe, | 365 | .attach_adapter = rtc8564_probe, |
369 | .detach_client = rtc8564_detach, | 366 | .detach_client = rtc8564_detach, |
370 | .command = rtc8564_command | 367 | .command = rtc8564_command |
diff --git a/drivers/i2c/chips/tps65010.c b/drivers/i2c/chips/tps65010.c index 280dd7a45db6..e70b3db69edd 100644 --- a/drivers/i2c/chips/tps65010.c +++ b/drivers/i2c/chips/tps65010.c | |||
@@ -637,9 +637,9 @@ static int __init tps65010_scan_bus(struct i2c_adapter *bus) | |||
637 | } | 637 | } |
638 | 638 | ||
639 | static struct i2c_driver tps65010_driver = { | 639 | static struct i2c_driver tps65010_driver = { |
640 | .owner = THIS_MODULE, | 640 | .driver = { |
641 | .name = "tps65010", | 641 | .name = "tps65010", |
642 | .flags = I2C_DF_NOTIFY, | 642 | }, |
643 | .attach_adapter = tps65010_scan_bus, | 643 | .attach_adapter = tps65010_scan_bus, |
644 | .detach_client = __exit_p(tps65010_detach_client), | 644 | .detach_client = __exit_p(tps65010_detach_client), |
645 | }; | 645 | }; |
diff --git a/drivers/i2c/chips/x1205.c b/drivers/i2c/chips/x1205.c index 7da366cdc18c..245fffa92dbd 100644 --- a/drivers/i2c/chips/x1205.c +++ b/drivers/i2c/chips/x1205.c | |||
@@ -105,9 +105,9 @@ static int x1205_command(struct i2c_client *client, unsigned int cmd, | |||
105 | void *arg); | 105 | void *arg); |
106 | 106 | ||
107 | static struct i2c_driver x1205_driver = { | 107 | static struct i2c_driver x1205_driver = { |
108 | .owner = THIS_MODULE, | 108 | .driver = { |
109 | .name = "x1205", | 109 | .name = "x1205", |
110 | .flags = I2C_DF_NOTIFY, | 110 | }, |
111 | .attach_adapter = &x1205_attach, | 111 | .attach_adapter = &x1205_attach, |
112 | .detach_client = &x1205_detach, | 112 | .detach_client = &x1205_detach, |
113 | }; | 113 | }; |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 82ea1b7ec914..52b77477df57 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -197,7 +197,7 @@ int i2c_add_adapter(struct i2c_adapter *adap) | |||
197 | /* inform drivers of new adapters */ | 197 | /* inform drivers of new adapters */ |
198 | list_for_each(item,&drivers) { | 198 | list_for_each(item,&drivers) { |
199 | driver = list_entry(item, struct i2c_driver, list); | 199 | driver = list_entry(item, struct i2c_driver, list); |
200 | if (driver->flags & I2C_DF_NOTIFY) | 200 | if (driver->attach_adapter) |
201 | /* We ignore the return code; if it fails, too bad */ | 201 | /* We ignore the return code; if it fails, too bad */ |
202 | driver->attach_adapter(adap); | 202 | driver->attach_adapter(adap); |
203 | } | 203 | } |
@@ -235,7 +235,8 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
235 | if (driver->detach_adapter) | 235 | if (driver->detach_adapter) |
236 | if ((res = driver->detach_adapter(adap))) { | 236 | if ((res = driver->detach_adapter(adap))) { |
237 | dev_err(&adap->dev, "detach_adapter failed " | 237 | dev_err(&adap->dev, "detach_adapter failed " |
238 | "for driver [%s]\n", driver->name); | 238 | "for driver [%s]\n", |
239 | driver->driver.name); | ||
239 | goto out_unlock; | 240 | goto out_unlock; |
240 | } | 241 | } |
241 | } | 242 | } |
@@ -245,10 +246,6 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
245 | list_for_each_safe(item, _n, &adap->clients) { | 246 | list_for_each_safe(item, _n, &adap->clients) { |
246 | client = list_entry(item, struct i2c_client, list); | 247 | client = list_entry(item, struct i2c_client, list); |
247 | 248 | ||
248 | /* detaching devices is unconditional of the set notify | ||
249 | * flag, as _all_ clients that reside on the adapter | ||
250 | * must be deleted, as this would cause invalid states. | ||
251 | */ | ||
252 | if ((res=client->driver->detach_client(client))) { | 249 | if ((res=client->driver->detach_client(client))) { |
253 | dev_err(&adap->dev, "detach_client failed for client " | 250 | dev_err(&adap->dev, "detach_client failed for client " |
254 | "[%s] at address 0x%02x\n", client->name, | 251 | "[%s] at address 0x%02x\n", client->name, |
@@ -286,7 +283,7 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
286 | * chips. | 283 | * chips. |
287 | */ | 284 | */ |
288 | 285 | ||
289 | int i2c_add_driver(struct i2c_driver *driver) | 286 | int i2c_register_driver(struct module *owner, struct i2c_driver *driver) |
290 | { | 287 | { |
291 | struct list_head *item; | 288 | struct list_head *item; |
292 | struct i2c_adapter *adapter; | 289 | struct i2c_adapter *adapter; |
@@ -295,8 +292,7 @@ int i2c_add_driver(struct i2c_driver *driver) | |||
295 | down(&core_lists); | 292 | down(&core_lists); |
296 | 293 | ||
297 | /* add the driver to the list of i2c drivers in the driver core */ | 294 | /* add the driver to the list of i2c drivers in the driver core */ |
298 | driver->driver.owner = driver->owner; | 295 | driver->driver.owner = owner; |
299 | driver->driver.name = driver->name; | ||
300 | driver->driver.bus = &i2c_bus_type; | 296 | driver->driver.bus = &i2c_bus_type; |
301 | driver->driver.probe = i2c_device_probe; | 297 | driver->driver.probe = i2c_device_probe; |
302 | driver->driver.remove = i2c_device_remove; | 298 | driver->driver.remove = i2c_device_remove; |
@@ -306,10 +302,10 @@ int i2c_add_driver(struct i2c_driver *driver) | |||
306 | goto out_unlock; | 302 | goto out_unlock; |
307 | 303 | ||
308 | list_add_tail(&driver->list,&drivers); | 304 | list_add_tail(&driver->list,&drivers); |
309 | pr_debug("i2c-core: driver [%s] registered\n", driver->name); | 305 | pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name); |
310 | 306 | ||
311 | /* now look for instances of driver on our adapters */ | 307 | /* now look for instances of driver on our adapters */ |
312 | if (driver->flags & I2C_DF_NOTIFY) { | 308 | if (driver->attach_adapter) { |
313 | list_for_each(item,&adapters) { | 309 | list_for_each(item,&adapters) { |
314 | adapter = list_entry(item, struct i2c_adapter, list); | 310 | adapter = list_entry(item, struct i2c_adapter, list); |
315 | driver->attach_adapter(adapter); | 311 | driver->attach_adapter(adapter); |
@@ -320,6 +316,7 @@ int i2c_add_driver(struct i2c_driver *driver) | |||
320 | up(&core_lists); | 316 | up(&core_lists); |
321 | return res; | 317 | return res; |
322 | } | 318 | } |
319 | EXPORT_SYMBOL(i2c_register_driver); | ||
323 | 320 | ||
324 | int i2c_del_driver(struct i2c_driver *driver) | 321 | int i2c_del_driver(struct i2c_driver *driver) |
325 | { | 322 | { |
@@ -334,17 +331,14 @@ int i2c_del_driver(struct i2c_driver *driver) | |||
334 | /* Have a look at each adapter, if clients of this driver are still | 331 | /* Have a look at each adapter, if clients of this driver are still |
335 | * attached. If so, detach them to be able to kill the driver | 332 | * attached. If so, detach them to be able to kill the driver |
336 | * afterwards. | 333 | * afterwards. |
337 | * | ||
338 | * Removing clients does not depend on the notify flag, else | ||
339 | * invalid operation might (will!) result, when using stale client | ||
340 | * pointers. | ||
341 | */ | 334 | */ |
342 | list_for_each(item1,&adapters) { | 335 | list_for_each(item1,&adapters) { |
343 | adap = list_entry(item1, struct i2c_adapter, list); | 336 | adap = list_entry(item1, struct i2c_adapter, list); |
344 | if (driver->detach_adapter) { | 337 | if (driver->detach_adapter) { |
345 | if ((res = driver->detach_adapter(adap))) { | 338 | if ((res = driver->detach_adapter(adap))) { |
346 | dev_err(&adap->dev, "detach_adapter failed " | 339 | dev_err(&adap->dev, "detach_adapter failed " |
347 | "for driver [%s]\n", driver->name); | 340 | "for driver [%s]\n", |
341 | driver->driver.name); | ||
348 | goto out_unlock; | 342 | goto out_unlock; |
349 | } | 343 | } |
350 | } else { | 344 | } else { |
@@ -368,7 +362,7 @@ int i2c_del_driver(struct i2c_driver *driver) | |||
368 | 362 | ||
369 | driver_unregister(&driver->driver); | 363 | driver_unregister(&driver->driver); |
370 | list_del(&driver->list); | 364 | list_del(&driver->list); |
371 | pr_debug("i2c-core: driver [%s] unregistered\n", driver->name); | 365 | pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name); |
372 | 366 | ||
373 | out_unlock: | 367 | out_unlock: |
374 | up(&core_lists); | 368 | up(&core_lists); |
@@ -419,8 +413,7 @@ int i2c_attach_client(struct i2c_client *client) | |||
419 | } | 413 | } |
420 | } | 414 | } |
421 | 415 | ||
422 | if (client->flags & I2C_CLIENT_ALLOW_USE) | 416 | client->usage_count = 0; |
423 | client->usage_count = 0; | ||
424 | 417 | ||
425 | client->dev.parent = &client->adapter->dev; | 418 | client->dev.parent = &client->adapter->dev; |
426 | client->dev.driver = &client->driver->driver; | 419 | client->dev.driver = &client->driver->driver; |
@@ -443,8 +436,7 @@ int i2c_detach_client(struct i2c_client *client) | |||
443 | struct i2c_adapter *adapter = client->adapter; | 436 | struct i2c_adapter *adapter = client->adapter; |
444 | int res = 0; | 437 | int res = 0; |
445 | 438 | ||
446 | if ((client->flags & I2C_CLIENT_ALLOW_USE) | 439 | if (client->usage_count > 0) { |
447 | && (client->usage_count > 0)) { | ||
448 | dev_warn(&client->dev, "Client [%s] still busy, " | 440 | dev_warn(&client->dev, "Client [%s] still busy, " |
449 | "can't detach\n", client->name); | 441 | "can't detach\n", client->name); |
450 | return -EBUSY; | 442 | return -EBUSY; |
@@ -475,10 +467,10 @@ int i2c_detach_client(struct i2c_client *client) | |||
475 | static int i2c_inc_use_client(struct i2c_client *client) | 467 | static int i2c_inc_use_client(struct i2c_client *client) |
476 | { | 468 | { |
477 | 469 | ||
478 | if (!try_module_get(client->driver->owner)) | 470 | if (!try_module_get(client->driver->driver.owner)) |
479 | return -ENODEV; | 471 | return -ENODEV; |
480 | if (!try_module_get(client->adapter->owner)) { | 472 | if (!try_module_get(client->adapter->owner)) { |
481 | module_put(client->driver->owner); | 473 | module_put(client->driver->driver.owner); |
482 | return -ENODEV; | 474 | return -ENODEV; |
483 | } | 475 | } |
484 | 476 | ||
@@ -487,7 +479,7 @@ static int i2c_inc_use_client(struct i2c_client *client) | |||
487 | 479 | ||
488 | static void i2c_dec_use_client(struct i2c_client *client) | 480 | static void i2c_dec_use_client(struct i2c_client *client) |
489 | { | 481 | { |
490 | module_put(client->driver->owner); | 482 | module_put(client->driver->driver.owner); |
491 | module_put(client->adapter->owner); | 483 | module_put(client->adapter->owner); |
492 | } | 484 | } |
493 | 485 | ||
@@ -499,33 +491,20 @@ int i2c_use_client(struct i2c_client *client) | |||
499 | if (ret) | 491 | if (ret) |
500 | return ret; | 492 | return ret; |
501 | 493 | ||
502 | if (client->flags & I2C_CLIENT_ALLOW_USE) { | 494 | client->usage_count++; |
503 | if (client->flags & I2C_CLIENT_ALLOW_MULTIPLE_USE) | ||
504 | client->usage_count++; | ||
505 | else if (client->usage_count > 0) | ||
506 | goto busy; | ||
507 | else | ||
508 | client->usage_count++; | ||
509 | } | ||
510 | 495 | ||
511 | return 0; | 496 | return 0; |
512 | busy: | ||
513 | i2c_dec_use_client(client); | ||
514 | return -EBUSY; | ||
515 | } | 497 | } |
516 | 498 | ||
517 | int i2c_release_client(struct i2c_client *client) | 499 | int i2c_release_client(struct i2c_client *client) |
518 | { | 500 | { |
519 | if(client->flags & I2C_CLIENT_ALLOW_USE) { | 501 | if (!client->usage_count) { |
520 | if(client->usage_count>0) | 502 | pr_debug("i2c-core: %s used one too many times\n", |
521 | client->usage_count--; | 503 | __FUNCTION__); |
522 | else { | 504 | return -EPERM; |
523 | pr_debug("i2c-core: %s used one too many times\n", | ||
524 | __FUNCTION__); | ||
525 | return -EPERM; | ||
526 | } | ||
527 | } | 505 | } |
528 | 506 | ||
507 | client->usage_count--; | ||
529 | i2c_dec_use_client(client); | 508 | i2c_dec_use_client(client); |
530 | 509 | ||
531 | return 0; | 510 | return 0; |
@@ -539,14 +518,14 @@ void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg) | |||
539 | down(&adap->clist_lock); | 518 | down(&adap->clist_lock); |
540 | list_for_each(item,&adap->clients) { | 519 | list_for_each(item,&adap->clients) { |
541 | client = list_entry(item, struct i2c_client, list); | 520 | client = list_entry(item, struct i2c_client, list); |
542 | if (!try_module_get(client->driver->owner)) | 521 | if (!try_module_get(client->driver->driver.owner)) |
543 | continue; | 522 | continue; |
544 | if (NULL != client->driver->command) { | 523 | if (NULL != client->driver->command) { |
545 | up(&adap->clist_lock); | 524 | up(&adap->clist_lock); |
546 | client->driver->command(client,cmd,arg); | 525 | client->driver->command(client,cmd,arg); |
547 | down(&adap->clist_lock); | 526 | down(&adap->clist_lock); |
548 | } | 527 | } |
549 | module_put(client->driver->owner); | 528 | module_put(client->driver->driver.owner); |
550 | } | 529 | } |
551 | up(&adap->clist_lock); | 530 | up(&adap->clist_lock); |
552 | } | 531 | } |
@@ -1147,7 +1126,6 @@ EXPORT_SYMBOL_GPL(i2c_bus_type); | |||
1147 | 1126 | ||
1148 | EXPORT_SYMBOL(i2c_add_adapter); | 1127 | EXPORT_SYMBOL(i2c_add_adapter); |
1149 | EXPORT_SYMBOL(i2c_del_adapter); | 1128 | EXPORT_SYMBOL(i2c_del_adapter); |
1150 | EXPORT_SYMBOL(i2c_add_driver); | ||
1151 | EXPORT_SYMBOL(i2c_del_driver); | 1129 | EXPORT_SYMBOL(i2c_del_driver); |
1152 | EXPORT_SYMBOL(i2c_attach_client); | 1130 | EXPORT_SYMBOL(i2c_attach_client); |
1153 | EXPORT_SYMBOL(i2c_detach_client); | 1131 | EXPORT_SYMBOL(i2c_detach_client); |
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index 8af0bd1424d2..ed7eed388bae 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c | |||
@@ -42,8 +42,7 @@ static struct i2c_client i2cdev_client_template; | |||
42 | struct i2c_dev { | 42 | struct i2c_dev { |
43 | int minor; | 43 | int minor; |
44 | struct i2c_adapter *adap; | 44 | struct i2c_adapter *adap; |
45 | struct class_device class_dev; | 45 | struct class_device *class_dev; |
46 | struct completion released; /* FIXME, we need a class_device_unregister() */ | ||
47 | }; | 46 | }; |
48 | #define to_i2c_dev(d) container_of(d, struct i2c_dev, class_dev) | 47 | #define to_i2c_dev(d) container_of(d, struct i2c_dev, class_dev) |
49 | 48 | ||
@@ -105,7 +104,10 @@ static void return_i2c_dev(struct i2c_dev *i2c_dev) | |||
105 | 104 | ||
106 | static ssize_t show_adapter_name(struct class_device *class_dev, char *buf) | 105 | static ssize_t show_adapter_name(struct class_device *class_dev, char *buf) |
107 | { | 106 | { |
108 | struct i2c_dev *i2c_dev = to_i2c_dev(class_dev); | 107 | struct i2c_dev *i2c_dev = i2c_dev_get_by_minor(MINOR(class_dev->devt)); |
108 | |||
109 | if (!i2c_dev) | ||
110 | return -ENODEV; | ||
109 | return sprintf(buf, "%s\n", i2c_dev->adap->name); | 111 | return sprintf(buf, "%s\n", i2c_dev->adap->name); |
110 | } | 112 | } |
111 | static CLASS_DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); | 113 | static CLASS_DEVICE_ATTR(name, S_IRUGO, show_adapter_name, NULL); |
@@ -408,21 +410,12 @@ static struct file_operations i2cdev_fops = { | |||
408 | .release = i2cdev_release, | 410 | .release = i2cdev_release, |
409 | }; | 411 | }; |
410 | 412 | ||
411 | static void release_i2c_dev(struct class_device *dev) | 413 | static struct class *i2c_dev_class; |
412 | { | ||
413 | struct i2c_dev *i2c_dev = to_i2c_dev(dev); | ||
414 | complete(&i2c_dev->released); | ||
415 | } | ||
416 | |||
417 | static struct class i2c_dev_class = { | ||
418 | .name = "i2c-dev", | ||
419 | .release = &release_i2c_dev, | ||
420 | }; | ||
421 | 414 | ||
422 | static int i2cdev_attach_adapter(struct i2c_adapter *adap) | 415 | static int i2cdev_attach_adapter(struct i2c_adapter *adap) |
423 | { | 416 | { |
424 | struct i2c_dev *i2c_dev; | 417 | struct i2c_dev *i2c_dev; |
425 | int retval; | 418 | struct device *dev; |
426 | 419 | ||
427 | i2c_dev = get_free_i2c_dev(adap); | 420 | i2c_dev = get_free_i2c_dev(adap); |
428 | if (IS_ERR(i2c_dev)) | 421 | if (IS_ERR(i2c_dev)) |
@@ -434,21 +427,20 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap) | |||
434 | /* register this i2c device with the driver core */ | 427 | /* register this i2c device with the driver core */ |
435 | i2c_dev->adap = adap; | 428 | i2c_dev->adap = adap; |
436 | if (adap->dev.parent == &platform_bus) | 429 | if (adap->dev.parent == &platform_bus) |
437 | i2c_dev->class_dev.dev = &adap->dev; | 430 | dev = &adap->dev; |
438 | else | 431 | else |
439 | i2c_dev->class_dev.dev = adap->dev.parent; | 432 | dev = adap->dev.parent; |
440 | i2c_dev->class_dev.class = &i2c_dev_class; | 433 | i2c_dev->class_dev = class_device_create(i2c_dev_class, NULL, |
441 | i2c_dev->class_dev.devt = MKDEV(I2C_MAJOR, i2c_dev->minor); | 434 | MKDEV(I2C_MAJOR, i2c_dev->minor), |
442 | snprintf(i2c_dev->class_dev.class_id, BUS_ID_SIZE, "i2c-%d", i2c_dev->minor); | 435 | dev, "i2c-%d", i2c_dev->minor); |
443 | retval = class_device_register(&i2c_dev->class_dev); | 436 | if (!i2c_dev->class_dev) |
444 | if (retval) | ||
445 | goto error; | 437 | goto error; |
446 | class_device_create_file(&i2c_dev->class_dev, &class_device_attr_name); | 438 | class_device_create_file(i2c_dev->class_dev, &class_device_attr_name); |
447 | return 0; | 439 | return 0; |
448 | error: | 440 | error: |
449 | return_i2c_dev(i2c_dev); | 441 | return_i2c_dev(i2c_dev); |
450 | kfree(i2c_dev); | 442 | kfree(i2c_dev); |
451 | return retval; | 443 | return -ENODEV; |
452 | } | 444 | } |
453 | 445 | ||
454 | static int i2cdev_detach_adapter(struct i2c_adapter *adap) | 446 | static int i2cdev_detach_adapter(struct i2c_adapter *adap) |
@@ -459,10 +451,8 @@ static int i2cdev_detach_adapter(struct i2c_adapter *adap) | |||
459 | if (!i2c_dev) | 451 | if (!i2c_dev) |
460 | return -ENODEV; | 452 | return -ENODEV; |
461 | 453 | ||
462 | init_completion(&i2c_dev->released); | ||
463 | return_i2c_dev(i2c_dev); | 454 | return_i2c_dev(i2c_dev); |
464 | class_device_unregister(&i2c_dev->class_dev); | 455 | class_device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, i2c_dev->minor)); |
465 | wait_for_completion(&i2c_dev->released); | ||
466 | kfree(i2c_dev); | 456 | kfree(i2c_dev); |
467 | 457 | ||
468 | pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name); | 458 | pr_debug("i2c-dev: adapter [%s] unregistered\n", adap->name); |
@@ -474,21 +464,14 @@ static int i2cdev_detach_client(struct i2c_client *client) | |||
474 | return 0; | 464 | return 0; |
475 | } | 465 | } |
476 | 466 | ||
477 | static int i2cdev_command(struct i2c_client *client, unsigned int cmd, | ||
478 | void *arg) | ||
479 | { | ||
480 | return -1; | ||
481 | } | ||
482 | |||
483 | static struct i2c_driver i2cdev_driver = { | 467 | static struct i2c_driver i2cdev_driver = { |
484 | .owner = THIS_MODULE, | 468 | .driver = { |
485 | .name = "dev_driver", | 469 | .name = "dev_driver", |
470 | }, | ||
486 | .id = I2C_DRIVERID_I2CDEV, | 471 | .id = I2C_DRIVERID_I2CDEV, |
487 | .flags = I2C_DF_NOTIFY, | ||
488 | .attach_adapter = i2cdev_attach_adapter, | 472 | .attach_adapter = i2cdev_attach_adapter, |
489 | .detach_adapter = i2cdev_detach_adapter, | 473 | .detach_adapter = i2cdev_detach_adapter, |
490 | .detach_client = i2cdev_detach_client, | 474 | .detach_client = i2cdev_detach_client, |
491 | .command = i2cdev_command, | ||
492 | }; | 475 | }; |
493 | 476 | ||
494 | static struct i2c_client i2cdev_client_template = { | 477 | static struct i2c_client i2cdev_client_template = { |
@@ -507,8 +490,8 @@ static int __init i2c_dev_init(void) | |||
507 | if (res) | 490 | if (res) |
508 | goto out; | 491 | goto out; |
509 | 492 | ||
510 | res = class_register(&i2c_dev_class); | 493 | i2c_dev_class = class_create(THIS_MODULE, "i2c-dev"); |
511 | if (res) | 494 | if (IS_ERR(i2c_dev_class)) |
512 | goto out_unreg_chrdev; | 495 | goto out_unreg_chrdev; |
513 | 496 | ||
514 | res = i2c_add_driver(&i2cdev_driver); | 497 | res = i2c_add_driver(&i2cdev_driver); |
@@ -518,7 +501,7 @@ static int __init i2c_dev_init(void) | |||
518 | return 0; | 501 | return 0; |
519 | 502 | ||
520 | out_unreg_class: | 503 | out_unreg_class: |
521 | class_unregister(&i2c_dev_class); | 504 | class_destroy(i2c_dev_class); |
522 | out_unreg_chrdev: | 505 | out_unreg_chrdev: |
523 | unregister_chrdev(I2C_MAJOR, "i2c"); | 506 | unregister_chrdev(I2C_MAJOR, "i2c"); |
524 | out: | 507 | out: |
@@ -529,7 +512,7 @@ out: | |||
529 | static void __exit i2c_dev_exit(void) | 512 | static void __exit i2c_dev_exit(void) |
530 | { | 513 | { |
531 | i2c_del_driver(&i2cdev_driver); | 514 | i2c_del_driver(&i2cdev_driver); |
532 | class_unregister(&i2c_dev_class); | 515 | class_destroy(i2c_dev_class); |
533 | unregister_chrdev(I2C_MAJOR,"i2c"); | 516 | unregister_chrdev(I2C_MAJOR,"i2c"); |
534 | } | 517 | } |
535 | 518 | ||