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 */ |
