aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2013-08-21 10:28:23 -0400
committerWolfram Sang <wsa@the-dreams.de>2013-08-23 04:22:29 -0400
commit55e71edb81b2b45273e7b284cce13ff24bde846f (patch)
tree6a9a473f7865779bf4a5cf3036711f0356ebae75
parent687b81d083c082bc1e853032e3a2a54f8c251d27 (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.txt15
-rw-r--r--drivers/acpi/Kconfig6
-rw-r--r--drivers/acpi/Makefile1
-rw-r--r--drivers/acpi/acpi_i2c.c103
-rw-r--r--drivers/i2c/busses/i2c-designware-platdrv.c1
-rw-r--r--drivers/i2c/i2c-core.c91
-rw-r--r--include/linux/i2c.h6
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:
228I2C serial bus support 228I2C serial bus support
229~~~~~~~~~~~~~~~~~~~~~~ 229~~~~~~~~~~~~~~~~~~~~~~
230The slaves behind I2C bus controller only need to add the ACPI IDs like 230The slaves behind I2C bus controller only need to add the ACPI IDs like
231with the platform and SPI drivers. However the I2C bus controller driver 231with the platform and SPI drivers. The I2C core automatically enumerates
232needs to call acpi_i2c_register_devices() after it has added the adapter. 232any slave devices behind the controller device once the adapter is
233 233registered.
234An 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
244Below is an example of how to add ACPI support to the existing mpu3050 235Below is an example of how to add ACPI support to the existing mpu3050
245input driver: 236input 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
183config ACPI_I2C
184 def_tristate I2C
185 depends on I2C
186 help
187 ACPI I2C enumeration support.
188
189config ACPI_PROCESSOR 183config 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
73obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o 73obj-$(CONFIG_ACPI_EC_DEBUGFS) += ec_sys.o
74obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o 74obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
75obj-$(CONFIG_ACPI_BGRT) += bgrt.o 75obj-$(CONFIG_ACPI_BGRT) += bgrt.o
76obj-$(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
79processor-y := processor_driver.o processor_throttling.o 78processor-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
18ACPI_MODULE_NAME("i2c");
19
20static 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
44static 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 */
88void 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}
103EXPORT_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);
1058static void of_i2c_register_devices(struct i2c_adapter *adap) { } 1058static 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)
1064static 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
1088static 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 */
1132static 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
1148static inline void acpi_i2c_register_devices(struct i2c_adapter *adap) {}
1149#endif /* CONFIG_ACPI */
1150
1061static int i2c_do_add_adapter(struct i2c_driver *driver, 1151static 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)
1163exit_recovery: 1253exit_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)
568extern void acpi_i2c_register_devices(struct i2c_adapter *adap);
569#else
570static inline void acpi_i2c_register_devices(struct i2c_adapter *adap) {}
571#endif
572
573#endif /* _LINUX_I2C_H */ 567#endif /* _LINUX_I2C_H */