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 /drivers/i2c/i2c-core.c | |
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>
Diffstat (limited to 'drivers/i2c/i2c-core.c')
-rw-r--r-- | drivers/i2c/i2c-core.c | 91 |
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); | |||
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); |