diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-10 14:58:25 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-10 14:58:25 -0500 |
commit | d55fc37856244c929965c190c8e9dcb49e2c07aa (patch) | |
tree | ccb348340a6f0aac546b06487ea6a1d1d35490f6 /drivers/i2c/i2c-core.c | |
parent | 42d4ebb42a17754d2e8344dc1aa486119671d0eb (diff) | |
parent | 75ecc64ef5a1f310fc80f732ad8cfb7e1bdc59d5 (diff) |
Merge branch 'i2c/for-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c updates from Wolfram Sang:
- New drivers: UniPhier (with and without FIFO)
- some drivers got some bigger rework: ismt, designware, img-scb (rcar
had to be reverted because issues were showing up just lately)
- ACPI: reworked the device scanning and added support for muxes
... and quite a lot of driver bugfixes and cleanups this time. All
files touched outside of the i2c realm have proper acks.
* 'i2c/for-4.4' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: (70 commits)
i2c: rcar: Revert the latest refactoring series
i2c: pnx: remove superfluous assignment
MAINTAINERS: i2c: drop i2c-pnx maintainer
MAINTAINERS: i2c: mark also subdirectories as maintained
i2c: cadence: enable driver for ARM64
i2c: i801: Document Intel DNV and Broxton
i2c: at91: manage unexpected RXRDY flag when starting a transfer
i2c: pnx: Use setup_timer instead of open coding it
i2c: add ACPI support for I2C mux ports
acpi: add acpi_preset_companion() stub
i2c: pxa: Add support for pxa910/988 & new configuration features
i2c: au1550: Convert to devm_kzalloc and devm_ioremap_resource
i2c-dev: Fix I2C_SLAVE ioctl comment
i2c-dev: Fix typo in ioctl name reference
i2c: sirf: tune the divider to make i2c bus freq more accurate
i2c: imx: Use -ENXIO as error in the NACK case
i2c: i801: Add support for Intel Broxton
i2c: i801: Add support for Intel DNV
i2c: mediatek: add i2c resume support
i2c: imx: implement bus recovery
...
Diffstat (limited to 'drivers/i2c/i2c-core.c')
-rw-r--r-- | drivers/i2c/i2c-core.c | 82 |
1 files changed, 59 insertions, 23 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index a59c3111f7fb..040af5cc8143 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -99,27 +99,40 @@ struct gsb_buffer { | |||
99 | }; | 99 | }; |
100 | } __packed; | 100 | } __packed; |
101 | 101 | ||
102 | static int acpi_i2c_add_resource(struct acpi_resource *ares, void *data) | 102 | struct acpi_i2c_lookup { |
103 | struct i2c_board_info *info; | ||
104 | acpi_handle adapter_handle; | ||
105 | acpi_handle device_handle; | ||
106 | }; | ||
107 | |||
108 | static int acpi_i2c_find_address(struct acpi_resource *ares, void *data) | ||
103 | { | 109 | { |
104 | struct i2c_board_info *info = data; | 110 | struct acpi_i2c_lookup *lookup = data; |
111 | struct i2c_board_info *info = lookup->info; | ||
112 | struct acpi_resource_i2c_serialbus *sb; | ||
113 | acpi_handle adapter_handle; | ||
114 | acpi_status status; | ||
105 | 115 | ||
106 | if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) { | 116 | if (info->addr || ares->type != ACPI_RESOURCE_TYPE_SERIAL_BUS) |
107 | struct acpi_resource_i2c_serialbus *sb; | 117 | return 1; |
108 | 118 | ||
109 | sb = &ares->data.i2c_serial_bus; | 119 | sb = &ares->data.i2c_serial_bus; |
110 | if (!info->addr && sb->type == ACPI_RESOURCE_SERIAL_TYPE_I2C) { | 120 | if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C) |
111 | info->addr = sb->slave_address; | 121 | return 1; |
112 | if (sb->access_mode == ACPI_I2C_10BIT_MODE) | ||
113 | info->flags |= I2C_CLIENT_TEN; | ||
114 | } | ||
115 | } else if (!info->irq) { | ||
116 | struct resource r; | ||
117 | 122 | ||
118 | if (acpi_dev_resource_interrupt(ares, 0, &r)) | 123 | /* |
119 | info->irq = r.start; | 124 | * Extract the ResourceSource and make sure that the handle matches |
125 | * with the I2C adapter handle. | ||
126 | */ | ||
127 | status = acpi_get_handle(lookup->device_handle, | ||
128 | sb->resource_source.string_ptr, | ||
129 | &adapter_handle); | ||
130 | if (ACPI_SUCCESS(status) && adapter_handle == lookup->adapter_handle) { | ||
131 | info->addr = sb->slave_address; | ||
132 | if (sb->access_mode == ACPI_I2C_10BIT_MODE) | ||
133 | info->flags |= I2C_CLIENT_TEN; | ||
120 | } | 134 | } |
121 | 135 | ||
122 | /* Tell the ACPI core to skip this resource */ | ||
123 | return 1; | 136 | return 1; |
124 | } | 137 | } |
125 | 138 | ||
@@ -128,6 +141,8 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level, | |||
128 | { | 141 | { |
129 | struct i2c_adapter *adapter = data; | 142 | struct i2c_adapter *adapter = data; |
130 | struct list_head resource_list; | 143 | struct list_head resource_list; |
144 | struct acpi_i2c_lookup lookup; | ||
145 | struct resource_entry *entry; | ||
131 | struct i2c_board_info info; | 146 | struct i2c_board_info info; |
132 | struct acpi_device *adev; | 147 | struct acpi_device *adev; |
133 | int ret; | 148 | int ret; |
@@ -140,14 +155,37 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level, | |||
140 | memset(&info, 0, sizeof(info)); | 155 | memset(&info, 0, sizeof(info)); |
141 | info.fwnode = acpi_fwnode_handle(adev); | 156 | info.fwnode = acpi_fwnode_handle(adev); |
142 | 157 | ||
158 | memset(&lookup, 0, sizeof(lookup)); | ||
159 | lookup.adapter_handle = ACPI_HANDLE(&adapter->dev); | ||
160 | lookup.device_handle = handle; | ||
161 | lookup.info = &info; | ||
162 | |||
163 | /* | ||
164 | * Look up for I2cSerialBus resource with ResourceSource that | ||
165 | * matches with this adapter. | ||
166 | */ | ||
143 | INIT_LIST_HEAD(&resource_list); | 167 | INIT_LIST_HEAD(&resource_list); |
144 | ret = acpi_dev_get_resources(adev, &resource_list, | 168 | ret = acpi_dev_get_resources(adev, &resource_list, |
145 | acpi_i2c_add_resource, &info); | 169 | acpi_i2c_find_address, &lookup); |
146 | acpi_dev_free_resource_list(&resource_list); | 170 | acpi_dev_free_resource_list(&resource_list); |
147 | 171 | ||
148 | if (ret < 0 || !info.addr) | 172 | if (ret < 0 || !info.addr) |
149 | return AE_OK; | 173 | return AE_OK; |
150 | 174 | ||
175 | /* Then fill IRQ number if any */ | ||
176 | ret = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); | ||
177 | if (ret < 0) | ||
178 | return AE_OK; | ||
179 | |||
180 | resource_list_for_each_entry(entry, &resource_list) { | ||
181 | if (resource_type(entry->res) == IORESOURCE_IRQ) { | ||
182 | info.irq = entry->res->start; | ||
183 | break; | ||
184 | } | ||
185 | } | ||
186 | |||
187 | acpi_dev_free_resource_list(&resource_list); | ||
188 | |||
151 | adev->power.flags.ignore_parent = true; | 189 | adev->power.flags.ignore_parent = true; |
152 | strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type)); | 190 | strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type)); |
153 | if (!i2c_new_device(adapter, &info)) { | 191 | if (!i2c_new_device(adapter, &info)) { |
@@ -160,6 +198,8 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level, | |||
160 | return AE_OK; | 198 | return AE_OK; |
161 | } | 199 | } |
162 | 200 | ||
201 | #define ACPI_I2C_MAX_SCAN_DEPTH 32 | ||
202 | |||
163 | /** | 203 | /** |
164 | * acpi_i2c_register_devices - enumerate I2C slave devices behind adapter | 204 | * acpi_i2c_register_devices - enumerate I2C slave devices behind adapter |
165 | * @adap: pointer to adapter | 205 | * @adap: pointer to adapter |
@@ -170,17 +210,13 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level, | |||
170 | */ | 210 | */ |
171 | static void acpi_i2c_register_devices(struct i2c_adapter *adap) | 211 | static void acpi_i2c_register_devices(struct i2c_adapter *adap) |
172 | { | 212 | { |
173 | acpi_handle handle; | ||
174 | acpi_status status; | 213 | acpi_status status; |
175 | 214 | ||
176 | if (!adap->dev.parent) | 215 | if (!has_acpi_companion(&adap->dev)) |
177 | return; | ||
178 | |||
179 | handle = ACPI_HANDLE(adap->dev.parent); | ||
180 | if (!handle) | ||
181 | return; | 216 | return; |
182 | 217 | ||
183 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, | 218 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, |
219 | ACPI_I2C_MAX_SCAN_DEPTH, | ||
184 | acpi_i2c_add_device, NULL, | 220 | acpi_i2c_add_device, NULL, |
185 | adap, NULL); | 221 | adap, NULL); |
186 | if (ACPI_FAILURE(status)) | 222 | if (ACPI_FAILURE(status)) |