diff options
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/Makefile | 1 | ||||
-rw-r--r-- | drivers/i2c/busses/Kconfig | 3 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-i801.c | 4 | ||||
-rw-r--r-- | drivers/i2c/i2c-boardinfo.c | 2 | ||||
-rw-r--r-- | drivers/i2c/i2c-core.c | 28 | ||||
-rw-r--r-- | drivers/i2c/i2c-dev.c | 60 |
6 files changed, 66 insertions, 32 deletions
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 23ac61e2db39..beee6b2d361d 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile | |||
@@ -10,3 +10,4 @@ obj-$(CONFIG_I2C_MUX) += i2c-mux.o | |||
10 | obj-y += algos/ busses/ muxes/ | 10 | obj-y += algos/ busses/ muxes/ |
11 | 11 | ||
12 | ccflags-$(CONFIG_I2C_DEBUG_CORE) := -DDEBUG | 12 | ccflags-$(CONFIG_I2C_DEBUG_CORE) := -DDEBUG |
13 | CFLAGS_i2c-core.o := -Wno-deprecated-declarations | ||
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 230601e8853f..ad415e6ec5a1 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -98,8 +98,9 @@ config I2C_I801 | |||
98 | EP80579 (Tolapai) | 98 | EP80579 (Tolapai) |
99 | ICH10 | 99 | ICH10 |
100 | 5/3400 Series (PCH) | 100 | 5/3400 Series (PCH) |
101 | Cougar Point (PCH) | 101 | 6 Series (PCH) |
102 | Patsburg (PCH) | 102 | Patsburg (PCH) |
103 | DH89xxCC (PCH) | ||
103 | 104 | ||
104 | This driver can also be built as a module. If so, the module | 105 | This driver can also be built as a module. If so, the module |
105 | will be called i2c-i801. | 106 | will be called i2c-i801. |
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 7979aef7ee7b..ed2e0c5ea37c 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
@@ -44,11 +44,12 @@ | |||
44 | ICH10 0x3a30 32 hard yes yes yes | 44 | ICH10 0x3a30 32 hard yes yes yes |
45 | ICH10 0x3a60 32 hard yes yes yes | 45 | ICH10 0x3a60 32 hard yes yes yes |
46 | 5/3400 Series (PCH) 0x3b30 32 hard yes yes yes | 46 | 5/3400 Series (PCH) 0x3b30 32 hard yes yes yes |
47 | Cougar Point (PCH) 0x1c22 32 hard yes yes yes | 47 | 6 Series (PCH) 0x1c22 32 hard yes yes yes |
48 | Patsburg (PCH) 0x1d22 32 hard yes yes yes | 48 | Patsburg (PCH) 0x1d22 32 hard yes yes yes |
49 | Patsburg (PCH) IDF 0x1d70 32 hard yes yes yes | 49 | Patsburg (PCH) IDF 0x1d70 32 hard yes yes yes |
50 | Patsburg (PCH) IDF 0x1d71 32 hard yes yes yes | 50 | Patsburg (PCH) IDF 0x1d71 32 hard yes yes yes |
51 | Patsburg (PCH) IDF 0x1d72 32 hard yes yes yes | 51 | Patsburg (PCH) IDF 0x1d72 32 hard yes yes yes |
52 | DH89xxCC (PCH) 0x2330 32 hard yes yes yes | ||
52 | 53 | ||
53 | Features supported by this driver: | 54 | Features supported by this driver: |
54 | Software PEC no | 55 | Software PEC no |
@@ -621,6 +622,7 @@ static const struct pci_device_id i801_ids[] = { | |||
621 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0) }, | 622 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0) }, |
622 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1) }, | 623 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1) }, |
623 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2) }, | 624 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2) }, |
625 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS) }, | ||
624 | { 0, } | 626 | { 0, } |
625 | }; | 627 | }; |
626 | 628 | ||
diff --git a/drivers/i2c/i2c-boardinfo.c b/drivers/i2c/i2c-boardinfo.c index 7e6a63b57165..3ca2e012e789 100644 --- a/drivers/i2c/i2c-boardinfo.c +++ b/drivers/i2c/i2c-boardinfo.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * i2c-boardinfo.h - collect pre-declarations of I2C devices | 2 | * i2c-boardinfo.c - collect pre-declarations of I2C devices |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License as published by | 5 | * it under the terms of the GNU General Public License as published by |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 045ba6efea48..e5f76a0372fd 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -797,6 +797,9 @@ static int i2c_do_add_adapter(struct i2c_driver *driver, | |||
797 | 797 | ||
798 | /* Let legacy drivers scan this bus for matching devices */ | 798 | /* Let legacy drivers scan this bus for matching devices */ |
799 | if (driver->attach_adapter) { | 799 | if (driver->attach_adapter) { |
800 | dev_warn(&adap->dev, "attach_adapter method is deprecated\n"); | ||
801 | dev_warn(&adap->dev, "Please use another way to instantiate " | ||
802 | "your i2c_client\n"); | ||
800 | /* We ignore the return code; if it fails, too bad */ | 803 | /* We ignore the return code; if it fails, too bad */ |
801 | driver->attach_adapter(adap); | 804 | driver->attach_adapter(adap); |
802 | } | 805 | } |
@@ -981,6 +984,7 @@ static int i2c_do_del_adapter(struct i2c_driver *driver, | |||
981 | 984 | ||
982 | if (!driver->detach_adapter) | 985 | if (!driver->detach_adapter) |
983 | return 0; | 986 | return 0; |
987 | dev_warn(&adapter->dev, "detach_adapter method is deprecated\n"); | ||
984 | res = driver->detach_adapter(adapter); | 988 | res = driver->detach_adapter(adapter); |
985 | if (res) | 989 | if (res) |
986 | dev_err(&adapter->dev, "detach_adapter failed (%d) " | 990 | dev_err(&adapter->dev, "detach_adapter failed (%d) " |
@@ -1091,6 +1095,18 @@ EXPORT_SYMBOL(i2c_del_adapter); | |||
1091 | 1095 | ||
1092 | /* ------------------------------------------------------------------------- */ | 1096 | /* ------------------------------------------------------------------------- */ |
1093 | 1097 | ||
1098 | int i2c_for_each_dev(void *data, int (*fn)(struct device *, void *)) | ||
1099 | { | ||
1100 | int res; | ||
1101 | |||
1102 | mutex_lock(&core_lock); | ||
1103 | res = bus_for_each_dev(&i2c_bus_type, NULL, data, fn); | ||
1104 | mutex_unlock(&core_lock); | ||
1105 | |||
1106 | return res; | ||
1107 | } | ||
1108 | EXPORT_SYMBOL_GPL(i2c_for_each_dev); | ||
1109 | |||
1094 | static int __process_new_driver(struct device *dev, void *data) | 1110 | static int __process_new_driver(struct device *dev, void *data) |
1095 | { | 1111 | { |
1096 | if (dev->type != &i2c_adapter_type) | 1112 | if (dev->type != &i2c_adapter_type) |
@@ -1134,9 +1150,7 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver) | |||
1134 | 1150 | ||
1135 | INIT_LIST_HEAD(&driver->clients); | 1151 | INIT_LIST_HEAD(&driver->clients); |
1136 | /* Walk the adapters that are already present */ | 1152 | /* Walk the adapters that are already present */ |
1137 | mutex_lock(&core_lock); | 1153 | i2c_for_each_dev(driver, __process_new_driver); |
1138 | bus_for_each_dev(&i2c_bus_type, NULL, driver, __process_new_driver); | ||
1139 | mutex_unlock(&core_lock); | ||
1140 | 1154 | ||
1141 | return 0; | 1155 | return 0; |
1142 | } | 1156 | } |
@@ -1156,9 +1170,7 @@ static int __process_removed_driver(struct device *dev, void *data) | |||
1156 | */ | 1170 | */ |
1157 | void i2c_del_driver(struct i2c_driver *driver) | 1171 | void i2c_del_driver(struct i2c_driver *driver) |
1158 | { | 1172 | { |
1159 | mutex_lock(&core_lock); | 1173 | i2c_for_each_dev(driver, __process_removed_driver); |
1160 | bus_for_each_dev(&i2c_bus_type, NULL, driver, __process_removed_driver); | ||
1161 | mutex_unlock(&core_lock); | ||
1162 | 1174 | ||
1163 | driver_unregister(&driver->driver); | 1175 | driver_unregister(&driver->driver); |
1164 | pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name); | 1176 | pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name); |
@@ -1581,12 +1593,12 @@ i2c_new_probed_device(struct i2c_adapter *adap, | |||
1581 | } | 1593 | } |
1582 | EXPORT_SYMBOL_GPL(i2c_new_probed_device); | 1594 | EXPORT_SYMBOL_GPL(i2c_new_probed_device); |
1583 | 1595 | ||
1584 | struct i2c_adapter *i2c_get_adapter(int id) | 1596 | struct i2c_adapter *i2c_get_adapter(int nr) |
1585 | { | 1597 | { |
1586 | struct i2c_adapter *adapter; | 1598 | struct i2c_adapter *adapter; |
1587 | 1599 | ||
1588 | mutex_lock(&core_lock); | 1600 | mutex_lock(&core_lock); |
1589 | adapter = idr_find(&i2c_adapter_idr, id); | 1601 | adapter = idr_find(&i2c_adapter_idr, nr); |
1590 | if (adapter && !try_module_get(adapter->owner)) | 1602 | if (adapter && !try_module_get(adapter->owner)) |
1591 | adapter = NULL; | 1603 | adapter = NULL; |
1592 | 1604 | ||
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index cec0f3ba97f8..c90ce50b619f 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c | |||
@@ -28,6 +28,8 @@ | |||
28 | 28 | ||
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/device.h> | ||
32 | #include <linux/notifier.h> | ||
31 | #include <linux/fs.h> | 33 | #include <linux/fs.h> |
32 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
33 | #include <linux/init.h> | 35 | #include <linux/init.h> |
@@ -37,16 +39,13 @@ | |||
37 | #include <linux/jiffies.h> | 39 | #include <linux/jiffies.h> |
38 | #include <linux/uaccess.h> | 40 | #include <linux/uaccess.h> |
39 | 41 | ||
40 | static struct i2c_driver i2cdev_driver; | ||
41 | |||
42 | /* | 42 | /* |
43 | * An i2c_dev represents an i2c_adapter ... an I2C or SMBus master, not a | 43 | * An i2c_dev represents an i2c_adapter ... an I2C or SMBus master, not a |
44 | * slave (i2c_client) with which messages will be exchanged. It's coupled | 44 | * slave (i2c_client) with which messages will be exchanged. It's coupled |
45 | * with a character special file which is accessed by user mode drivers. | 45 | * with a character special file which is accessed by user mode drivers. |
46 | * | 46 | * |
47 | * The list of i2c_dev structures is parallel to the i2c_adapter lists | 47 | * The list of i2c_dev structures is parallel to the i2c_adapter lists |
48 | * maintained by the driver model, and is updated using notifications | 48 | * maintained by the driver model, and is updated using bus notifications. |
49 | * delivered to the i2cdev_driver. | ||
50 | */ | 49 | */ |
51 | struct i2c_dev { | 50 | struct i2c_dev { |
52 | struct list_head list; | 51 | struct list_head list; |
@@ -491,7 +490,6 @@ static int i2cdev_open(struct inode *inode, struct file *file) | |||
491 | return -ENOMEM; | 490 | return -ENOMEM; |
492 | } | 491 | } |
493 | snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr); | 492 | snprintf(client->name, I2C_NAME_SIZE, "i2c-dev %d", adap->nr); |
494 | client->driver = &i2cdev_driver; | ||
495 | 493 | ||
496 | client->adapter = adap; | 494 | client->adapter = adap; |
497 | file->private_data = client; | 495 | file->private_data = client; |
@@ -522,19 +520,18 @@ static const struct file_operations i2cdev_fops = { | |||
522 | 520 | ||
523 | /* ------------------------------------------------------------------------- */ | 521 | /* ------------------------------------------------------------------------- */ |
524 | 522 | ||
525 | /* | ||
526 | * The legacy "i2cdev_driver" is used primarily to get notifications when | ||
527 | * I2C adapters are added or removed, so that each one gets an i2c_dev | ||
528 | * and is thus made available to userspace driver code. | ||
529 | */ | ||
530 | |||
531 | static struct class *i2c_dev_class; | 523 | static struct class *i2c_dev_class; |
532 | 524 | ||
533 | static int i2cdev_attach_adapter(struct i2c_adapter *adap) | 525 | static int i2cdev_attach_adapter(struct device *dev, void *dummy) |
534 | { | 526 | { |
527 | struct i2c_adapter *adap; | ||
535 | struct i2c_dev *i2c_dev; | 528 | struct i2c_dev *i2c_dev; |
536 | int res; | 529 | int res; |
537 | 530 | ||
531 | if (dev->type != &i2c_adapter_type) | ||
532 | return 0; | ||
533 | adap = to_i2c_adapter(dev); | ||
534 | |||
538 | i2c_dev = get_free_i2c_dev(adap); | 535 | i2c_dev = get_free_i2c_dev(adap); |
539 | if (IS_ERR(i2c_dev)) | 536 | if (IS_ERR(i2c_dev)) |
540 | return PTR_ERR(i2c_dev); | 537 | return PTR_ERR(i2c_dev); |
@@ -561,10 +558,15 @@ error: | |||
561 | return res; | 558 | return res; |
562 | } | 559 | } |
563 | 560 | ||
564 | static int i2cdev_detach_adapter(struct i2c_adapter *adap) | 561 | static int i2cdev_detach_adapter(struct device *dev, void *dummy) |
565 | { | 562 | { |
563 | struct i2c_adapter *adap; | ||
566 | struct i2c_dev *i2c_dev; | 564 | struct i2c_dev *i2c_dev; |
567 | 565 | ||
566 | if (dev->type != &i2c_adapter_type) | ||
567 | return 0; | ||
568 | adap = to_i2c_adapter(dev); | ||
569 | |||
568 | i2c_dev = i2c_dev_get_by_minor(adap->nr); | 570 | i2c_dev = i2c_dev_get_by_minor(adap->nr); |
569 | if (!i2c_dev) /* attach_adapter must have failed */ | 571 | if (!i2c_dev) /* attach_adapter must have failed */ |
570 | return 0; | 572 | return 0; |
@@ -577,12 +579,23 @@ static int i2cdev_detach_adapter(struct i2c_adapter *adap) | |||
577 | return 0; | 579 | return 0; |
578 | } | 580 | } |
579 | 581 | ||
580 | static struct i2c_driver i2cdev_driver = { | 582 | int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action, |
581 | .driver = { | 583 | void *data) |
582 | .name = "dev_driver", | 584 | { |
583 | }, | 585 | struct device *dev = data; |
584 | .attach_adapter = i2cdev_attach_adapter, | 586 | |
585 | .detach_adapter = i2cdev_detach_adapter, | 587 | switch (action) { |
588 | case BUS_NOTIFY_ADD_DEVICE: | ||
589 | return i2cdev_attach_adapter(dev, NULL); | ||
590 | case BUS_NOTIFY_DEL_DEVICE: | ||
591 | return i2cdev_detach_adapter(dev, NULL); | ||
592 | } | ||
593 | |||
594 | return 0; | ||
595 | } | ||
596 | |||
597 | static struct notifier_block i2cdev_notifier = { | ||
598 | .notifier_call = i2cdev_notifier_call, | ||
586 | }; | 599 | }; |
587 | 600 | ||
588 | /* ------------------------------------------------------------------------- */ | 601 | /* ------------------------------------------------------------------------- */ |
@@ -607,10 +620,14 @@ static int __init i2c_dev_init(void) | |||
607 | goto out_unreg_chrdev; | 620 | goto out_unreg_chrdev; |
608 | } | 621 | } |
609 | 622 | ||
610 | res = i2c_add_driver(&i2cdev_driver); | 623 | /* Keep track of adapters which will be added or removed later */ |
624 | res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier); | ||
611 | if (res) | 625 | if (res) |
612 | goto out_unreg_class; | 626 | goto out_unreg_class; |
613 | 627 | ||
628 | /* Bind to already existing adapters right away */ | ||
629 | i2c_for_each_dev(NULL, i2cdev_attach_adapter); | ||
630 | |||
614 | return 0; | 631 | return 0; |
615 | 632 | ||
616 | out_unreg_class: | 633 | out_unreg_class: |
@@ -624,7 +641,8 @@ out: | |||
624 | 641 | ||
625 | static void __exit i2c_dev_exit(void) | 642 | static void __exit i2c_dev_exit(void) |
626 | { | 643 | { |
627 | i2c_del_driver(&i2cdev_driver); | 644 | bus_unregister_notifier(&i2c_bus_type, &i2cdev_notifier); |
645 | i2c_for_each_dev(NULL, i2cdev_detach_adapter); | ||
628 | class_destroy(i2c_dev_class); | 646 | class_destroy(i2c_dev_class); |
629 | unregister_chrdev(I2C_MAJOR, "i2c"); | 647 | unregister_chrdev(I2C_MAJOR, "i2c"); |
630 | } | 648 | } |