diff options
author | Mika Westerberg <mika.westerberg@linux.intel.com> | 2013-08-21 10:28:23 -0400 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2013-08-23 04:22:29 -0400 |
commit | 55e71edb81b2b45273e7b284cce13ff24bde846f (patch) | |
tree | 6a9a473f7865779bf4a5cf3036711f0356ebae75 | |
parent | 687b81d083c082bc1e853032e3a2a54f8c251d27 (diff) |
i2c: move ACPI helpers into the core
This follows what has already been done for the DeviceTree helpers. Move
the ACPI helpers from drivers/acpi/acpi_i2c.c to the I2C core and update
documentation accordingly.
This also solves a problem reported by Jerry Snitselaar that we can't build
the ACPI I2C helpers as a module.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
-rw-r--r-- | Documentation/acpi/enumeration.txt | 15 | ||||
-rw-r--r-- | drivers/acpi/Kconfig | 6 | ||||
-rw-r--r-- | drivers/acpi/Makefile | 1 | ||||
-rw-r--r-- | drivers/acpi/acpi_i2c.c | 103 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-designware-platdrv.c | 1 | ||||
-rw-r--r-- | drivers/i2c/i2c-core.c | 91 | ||||
-rw-r--r-- | include/linux/i2c.h | 6 |
7 files changed, 94 insertions, 129 deletions
diff --git a/Documentation/acpi/enumeration.txt b/Documentation/acpi/enumeration.txt index 958266efcc20..d977778b5e67 100644 --- a/Documentation/acpi/enumeration.txt +++ b/Documentation/acpi/enumeration.txt | |||
@@ -228,18 +228,9 @@ ACPI handle like: | |||
228 | I2C serial bus support | 228 | I2C serial bus support |
229 | ~~~~~~~~~~~~~~~~~~~~~~ | 229 | ~~~~~~~~~~~~~~~~~~~~~~ |
230 | The slaves behind I2C bus controller only need to add the ACPI IDs like | 230 | The slaves behind I2C bus controller only need to add the ACPI IDs like |
231 | with the platform and SPI drivers. However the I2C bus controller driver | 231 | with the platform and SPI drivers. The I2C core automatically enumerates |
232 | needs to call acpi_i2c_register_devices() after it has added the adapter. | 232 | any slave devices behind the controller device once the adapter is |
233 | 233 | registered. | |
234 | An I2C bus (controller) driver does: | ||
235 | |||
236 | ... | ||
237 | ret = i2c_add_numbered_adapter(adapter); | ||
238 | if (ret) | ||
239 | /* handle error */ | ||
240 | |||
241 | /* Enumerate the slave devices behind this bus via ACPI */ | ||
242 | acpi_i2c_register_devices(adapter); | ||
243 | 234 | ||
244 | Below is an example of how to add ACPI support to the existing mpu3050 | 235 | Below is an example of how to add ACPI support to the existing mpu3050 |
245 | input driver: | 236 | input driver: |
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 100bd724f648..4e0162fa5d36 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -180,12 +180,6 @@ config ACPI_DOCK | |||
180 | This driver supports ACPI-controlled docking stations and removable | 180 | This driver supports ACPI-controlled docking stations and removable |
181 | drive bays such as the IBM Ultrabay and the Dell Module Bay. | 181 | drive bays such as the IBM Ultrabay and the Dell Module Bay. |
182 | 182 | ||
183 | config ACPI_I2C | ||
184 | def_tristate I2C | ||
185 | depends on I2C | ||
186 | help | ||
187 | ACPI I2C enumeration support. | ||
188 | |||
189 | config ACPI_PROCESSOR | 183 | config ACPI_PROCESSOR |
190 | tristate "Processor" | 184 | tristate "Processor" |
191 | select THERMAL | 185 | select THERMAL |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 81dbeb83bb45..cdaf68b58b00 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -73,7 +73,6 @@ obj-$(CONFIG_ACPI_HED) += hed.o | |||
73 | obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o | 73 | obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o |
74 | obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o | 74 | obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o |
75 | obj-$(CONFIG_ACPI_BGRT) += bgrt.o | 75 | obj-$(CONFIG_ACPI_BGRT) += bgrt.o |
76 | obj-$(CONFIG_ACPI_I2C) += acpi_i2c.o | ||
77 | 76 | ||
78 | # processor has its own "processor." module_param namespace | 77 | # processor has its own "processor." module_param namespace |
79 | processor-y := processor_driver.o processor_throttling.o | 78 | processor-y := processor_driver.o processor_throttling.o |
diff --git a/drivers/acpi/acpi_i2c.c b/drivers/acpi/acpi_i2c.c deleted file mode 100644 index a82c7626aa9b..000000000000 --- a/drivers/acpi/acpi_i2c.c +++ /dev/null | |||
@@ -1,103 +0,0 @@ | |||
1 | /* | ||
2 | * ACPI I2C enumeration support | ||
3 | * | ||
4 | * Copyright (C) 2012, Intel Corporation | ||
5 | * Author: Mika Westerberg <mika.westerberg@linux.intel.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/acpi.h> | ||
13 | #include <linux/device.h> | ||
14 | #include <linux/export.h> | ||
15 | #include <linux/i2c.h> | ||
16 | #include <linux/ioport.h> | ||
17 | |||
18 | ACPI_MODULE_NAME("i2c"); | ||
19 | |||
20 | static int acpi_i2c_add_resource(struct acpi_resource *ares, void *data) | ||
21 | { | ||
22 | struct i2c_board_info *info = data; | ||
23 | |||
24 | if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) { | ||
25 | struct acpi_resource_i2c_serialbus *sb; | ||
26 | |||
27 | sb = &ares->data.i2c_serial_bus; | ||
28 | if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) { | ||
29 | info->addr = sb->slave_address; | ||
30 | if (sb->access_mode == ACPI_I2C_10BIT_MODE) | ||
31 | info->flags |= I2C_CLIENT_TEN; | ||
32 | } | ||
33 | } else if (info->irq < 0) { | ||
34 | struct resource r; | ||
35 | |||
36 | if (acpi_dev_resource_interrupt(ares, 0, &r)) | ||
37 | info->irq = r.start; | ||
38 | } | ||
39 | |||
40 | /* Tell the ACPI core to skip this resource */ | ||
41 | return 1; | ||
42 | } | ||
43 | |||
44 | static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level, | ||
45 | void *data, void **return_value) | ||
46 | { | ||
47 | struct i2c_adapter *adapter = data; | ||
48 | struct list_head resource_list; | ||
49 | struct i2c_board_info info; | ||
50 | struct acpi_device *adev; | ||
51 | int ret; | ||
52 | |||
53 | if (acpi_bus_get_device(handle, &adev)) | ||
54 | return AE_OK; | ||
55 | if (acpi_bus_get_status(adev) || !adev->status.present) | ||
56 | return AE_OK; | ||
57 | |||
58 | memset(&info, 0, sizeof(info)); | ||
59 | info.acpi_node.handle = handle; | ||
60 | info.irq = -1; | ||
61 | |||
62 | INIT_LIST_HEAD(&resource_list); | ||
63 | ret = acpi_dev_get_resources(adev, &resource_list, | ||
64 | acpi_i2c_add_resource, &info); | ||
65 | acpi_dev_free_resource_list(&resource_list); | ||
66 | |||
67 | if (ret < 0 || !info.addr) | ||
68 | return AE_OK; | ||
69 | |||
70 | strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type)); | ||
71 | if (!i2c_new_device(adapter, &info)) { | ||
72 | dev_err(&adapter->dev, | ||
73 | "failed to add I2C device %s from ACPI\n", | ||
74 | dev_name(&adev->dev)); | ||
75 | } | ||
76 | |||
77 | return AE_OK; | ||
78 | } | ||
79 | |||
80 | /** | ||
81 | * acpi_i2c_register_devices - enumerate I2C slave devices behind adapter | ||
82 | * @adapter: pointer to adapter | ||
83 | * | ||
84 | * Enumerate all I2C slave devices behind this adapter by walking the ACPI | ||
85 | * namespace. When a device is found it will be added to the Linux device | ||
86 | * model and bound to the corresponding ACPI handle. | ||
87 | */ | ||
88 | void acpi_i2c_register_devices(struct i2c_adapter *adapter) | ||
89 | { | ||
90 | acpi_handle handle; | ||
91 | acpi_status status; | ||
92 | |||
93 | handle = ACPI_HANDLE(adapter->dev.parent); | ||
94 | if (!handle) | ||
95 | return; | ||
96 | |||
97 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, | ||
98 | acpi_i2c_add_device, NULL, | ||
99 | adapter, NULL); | ||
100 | if (ACPI_FAILURE(status)) | ||
101 | dev_warn(&adapter->dev, "failed to enumerate I2C slaves\n"); | ||
102 | } | ||
103 | EXPORT_SYMBOL_GPL(acpi_i2c_register_devices); | ||
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index ded77c3bd59c..6e99d9f56dee 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c | |||
@@ -171,7 +171,6 @@ static int dw_i2c_probe(struct platform_device *pdev) | |||
171 | dev_err(&pdev->dev, "failure adding adapter\n"); | 171 | dev_err(&pdev->dev, "failure adding adapter\n"); |
172 | return r; | 172 | return r; |
173 | } | 173 | } |
174 | acpi_i2c_register_devices(adap); | ||
175 | 174 | ||
176 | pm_runtime_set_autosuspend_delay(&pdev->dev, 1000); | 175 | pm_runtime_set_autosuspend_delay(&pdev->dev, 1000); |
177 | pm_runtime_use_autosuspend(&pdev->dev); | 176 | pm_runtime_use_autosuspend(&pdev->dev); |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index e874b052b4f8..29d3f045a2bf 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -1058,6 +1058,96 @@ EXPORT_SYMBOL(of_find_i2c_adapter_by_node); | |||
1058 | static void of_i2c_register_devices(struct i2c_adapter *adap) { } | 1058 | static void of_i2c_register_devices(struct i2c_adapter *adap) { } |
1059 | #endif /* CONFIG_OF */ | 1059 | #endif /* CONFIG_OF */ |
1060 | 1060 | ||
1061 | /* ACPI support code */ | ||
1062 | |||
1063 | #if IS_ENABLED(CONFIG_ACPI) | ||
1064 | static int acpi_i2c_add_resource(struct acpi_resource *ares, void *data) | ||
1065 | { | ||
1066 | struct i2c_board_info *info = data; | ||
1067 | |||
1068 | if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) { | ||
1069 | struct acpi_resource_i2c_serialbus *sb; | ||
1070 | |||
1071 | sb = &ares->data.i2c_serial_bus; | ||
1072 | if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) { | ||
1073 | info->addr = sb->slave_address; | ||
1074 | if (sb->access_mode == ACPI_I2C_10BIT_MODE) | ||
1075 | info->flags |= I2C_CLIENT_TEN; | ||
1076 | } | ||
1077 | } else if (info->irq < 0) { | ||
1078 | struct resource r; | ||
1079 | |||
1080 | if (acpi_dev_resource_interrupt(ares, 0, &r)) | ||
1081 | info->irq = r.start; | ||
1082 | } | ||
1083 | |||
1084 | /* Tell the ACPI core to skip this resource */ | ||
1085 | return 1; | ||
1086 | } | ||
1087 | |||
1088 | static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level, | ||
1089 | void *data, void **return_value) | ||
1090 | { | ||
1091 | struct i2c_adapter *adapter = data; | ||
1092 | struct list_head resource_list; | ||
1093 | struct i2c_board_info info; | ||
1094 | struct acpi_device *adev; | ||
1095 | int ret; | ||
1096 | |||
1097 | if (acpi_bus_get_device(handle, &adev)) | ||
1098 | return AE_OK; | ||
1099 | if (acpi_bus_get_status(adev) || !adev->status.present) | ||
1100 | return AE_OK; | ||
1101 | |||
1102 | memset(&info, 0, sizeof(info)); | ||
1103 | info.acpi_node.handle = handle; | ||
1104 | info.irq = -1; | ||
1105 | |||
1106 | INIT_LIST_HEAD(&resource_list); | ||
1107 | ret = acpi_dev_get_resources(adev, &resource_list, | ||
1108 | acpi_i2c_add_resource, &info); | ||
1109 | acpi_dev_free_resource_list(&resource_list); | ||
1110 | |||
1111 | if (ret < 0 || !info.addr) | ||
1112 | return AE_OK; | ||
1113 | |||
1114 | strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type)); | ||
1115 | if (!i2c_new_device(adapter, &info)) { | ||
1116 | dev_err(&adapter->dev, | ||
1117 | "failed to add I2C device %s from ACPI\n", | ||
1118 | dev_name(&adev->dev)); | ||
1119 | } | ||
1120 | |||
1121 | return AE_OK; | ||
1122 | } | ||
1123 | |||
1124 | /** | ||
1125 | * acpi_i2c_register_devices - enumerate I2C slave devices behind adapter | ||
1126 | * @adap: pointer to adapter | ||
1127 | * | ||
1128 | * Enumerate all I2C slave devices behind this adapter by walking the ACPI | ||
1129 | * namespace. When a device is found it will be added to the Linux device | ||
1130 | * model and bound to the corresponding ACPI handle. | ||
1131 | */ | ||
1132 | static void acpi_i2c_register_devices(struct i2c_adapter *adap) | ||
1133 | { | ||
1134 | acpi_handle handle; | ||
1135 | acpi_status status; | ||
1136 | |||
1137 | handle = ACPI_HANDLE(adap->dev.parent); | ||
1138 | if (!handle) | ||
1139 | return; | ||
1140 | |||
1141 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, | ||
1142 | acpi_i2c_add_device, NULL, | ||
1143 | adap, NULL); | ||
1144 | if (ACPI_FAILURE(status)) | ||
1145 | dev_warn(&adap->dev, "failed to enumerate I2C slaves\n"); | ||
1146 | } | ||
1147 | #else | ||
1148 | static inline void acpi_i2c_register_devices(struct i2c_adapter *adap) {} | ||
1149 | #endif /* CONFIG_ACPI */ | ||
1150 | |||
1061 | static int i2c_do_add_adapter(struct i2c_driver *driver, | 1151 | static int i2c_do_add_adapter(struct i2c_driver *driver, |
1062 | struct i2c_adapter *adap) | 1152 | struct i2c_adapter *adap) |
1063 | { | 1153 | { |
@@ -1163,6 +1253,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap) | |||
1163 | exit_recovery: | 1253 | exit_recovery: |
1164 | /* create pre-declared device nodes */ | 1254 | /* create pre-declared device nodes */ |
1165 | of_i2c_register_devices(adap); | 1255 | of_i2c_register_devices(adap); |
1256 | acpi_i2c_register_devices(adap); | ||
1166 | 1257 | ||
1167 | if (adap->nr < __i2c_first_dynamic_bus_num) | 1258 | if (adap->nr < __i2c_first_dynamic_bus_num) |
1168 | i2c_scan_static_board_info(adap); | 1259 | i2c_scan_static_board_info(adap); |
diff --git a/include/linux/i2c.h b/include/linux/i2c.h index ed53696e31a6..2ab11dc38077 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h | |||
@@ -564,10 +564,4 @@ static inline struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node | |||
564 | } | 564 | } |
565 | #endif /* CONFIG_OF */ | 565 | #endif /* CONFIG_OF */ |
566 | 566 | ||
567 | #if IS_ENABLED(CONFIG_ACPI_I2C) | ||
568 | extern void acpi_i2c_register_devices(struct i2c_adapter *adap); | ||
569 | #else | ||
570 | static inline void acpi_i2c_register_devices(struct i2c_adapter *adap) {} | ||
571 | #endif | ||
572 | |||
573 | #endif /* _LINUX_I2C_H */ | 567 | #endif /* _LINUX_I2C_H */ |