aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/i2c-core.c
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 /drivers/i2c/i2c-core.c
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>
Diffstat (limited to 'drivers/i2c/i2c-core.c')
-rw-r--r--drivers/i2c/i2c-core.c91
1 files changed, 91 insertions, 0 deletions
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);