diff options
author | Wolfram Sang <wsa@the-dreams.de> | 2017-04-16 16:03:54 -0400 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2017-04-16 16:03:54 -0400 |
commit | c99a30d8c4d5e26e69fe3c01c4caf7b6f309e026 (patch) | |
tree | 54dfe072975276817214734bc224398b2c514609 | |
parent | 879bce228526c500bff3ed8ffec7bf89d98a9e11 (diff) | |
parent | d1d84bb95364ed604015c2b788caaf3dbca0262f (diff) |
Merge branch 'i2c/for-INT33FE' into i2c/for-4.12
Pull in the immutable branch with I2C ACPI core extensions to support
the INT33FE driver.
-rw-r--r-- | drivers/i2c/i2c-core.c | 62 | ||||
-rw-r--r-- | include/linux/i2c.h | 10 |
2 files changed, 69 insertions, 3 deletions
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index d2402bbf6729..7a065c4260f3 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -112,6 +112,8 @@ struct i2c_acpi_lookup { | |||
112 | acpi_handle adapter_handle; | 112 | acpi_handle adapter_handle; |
113 | acpi_handle device_handle; | 113 | acpi_handle device_handle; |
114 | acpi_handle search_handle; | 114 | acpi_handle search_handle; |
115 | int n; | ||
116 | int index; | ||
115 | u32 speed; | 117 | u32 speed; |
116 | u32 min_speed; | 118 | u32 min_speed; |
117 | }; | 119 | }; |
@@ -130,6 +132,9 @@ static int i2c_acpi_fill_info(struct acpi_resource *ares, void *data) | |||
130 | if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C) | 132 | if (sb->type != ACPI_RESOURCE_SERIAL_TYPE_I2C) |
131 | return 1; | 133 | return 1; |
132 | 134 | ||
135 | if (lookup->index != -1 && lookup->n++ != lookup->index) | ||
136 | return 1; | ||
137 | |||
133 | status = acpi_get_handle(lookup->device_handle, | 138 | status = acpi_get_handle(lookup->device_handle, |
134 | sb->resource_source.string_ptr, | 139 | sb->resource_source.string_ptr, |
135 | &lookup->adapter_handle); | 140 | &lookup->adapter_handle); |
@@ -182,6 +187,7 @@ static int i2c_acpi_get_info(struct acpi_device *adev, | |||
182 | 187 | ||
183 | memset(&lookup, 0, sizeof(lookup)); | 188 | memset(&lookup, 0, sizeof(lookup)); |
184 | lookup.info = info; | 189 | lookup.info = info; |
190 | lookup.index = -1; | ||
185 | 191 | ||
186 | ret = i2c_acpi_do_lookup(adev, &lookup); | 192 | ret = i2c_acpi_do_lookup(adev, &lookup); |
187 | if (ret) | 193 | if (ret) |
@@ -328,6 +334,7 @@ u32 i2c_acpi_find_bus_speed(struct device *dev) | |||
328 | lookup.search_handle = ACPI_HANDLE(dev); | 334 | lookup.search_handle = ACPI_HANDLE(dev); |
329 | lookup.min_speed = UINT_MAX; | 335 | lookup.min_speed = UINT_MAX; |
330 | lookup.info = &dummy; | 336 | lookup.info = &dummy; |
337 | lookup.index = -1; | ||
331 | 338 | ||
332 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | 339 | status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, |
333 | I2C_ACPI_MAX_SCAN_DEPTH, | 340 | I2C_ACPI_MAX_SCAN_DEPTH, |
@@ -414,6 +421,55 @@ static int i2c_acpi_notify(struct notifier_block *nb, unsigned long value, | |||
414 | static struct notifier_block i2c_acpi_notifier = { | 421 | static struct notifier_block i2c_acpi_notifier = { |
415 | .notifier_call = i2c_acpi_notify, | 422 | .notifier_call = i2c_acpi_notify, |
416 | }; | 423 | }; |
424 | |||
425 | /** | ||
426 | * i2c_acpi_new_device - Create i2c-client for the Nth I2cSerialBus resource | ||
427 | * @dev: Device owning the ACPI resources to get the client from | ||
428 | * @index: Index of ACPI resource to get | ||
429 | * @info: describes the I2C device; note this is modified (addr gets set) | ||
430 | * Context: can sleep | ||
431 | * | ||
432 | * By default the i2c subsys creates an i2c-client for the first I2cSerialBus | ||
433 | * resource of an acpi_device, but some acpi_devices have multiple I2cSerialBus | ||
434 | * resources, in that case this function can be used to create an i2c-client | ||
435 | * for other I2cSerialBus resources in the Current Resource Settings table. | ||
436 | * | ||
437 | * Also see i2c_new_device, which this function calls to create the i2c-client. | ||
438 | * | ||
439 | * Returns a pointer to the new i2c-client, or NULL if the adapter is not found. | ||
440 | */ | ||
441 | struct i2c_client *i2c_acpi_new_device(struct device *dev, int index, | ||
442 | struct i2c_board_info *info) | ||
443 | { | ||
444 | struct i2c_acpi_lookup lookup; | ||
445 | struct i2c_adapter *adapter; | ||
446 | struct acpi_device *adev; | ||
447 | LIST_HEAD(resource_list); | ||
448 | int ret; | ||
449 | |||
450 | adev = ACPI_COMPANION(dev); | ||
451 | if (!adev) | ||
452 | return NULL; | ||
453 | |||
454 | memset(&lookup, 0, sizeof(lookup)); | ||
455 | lookup.info = info; | ||
456 | lookup.device_handle = acpi_device_handle(adev); | ||
457 | lookup.index = index; | ||
458 | |||
459 | ret = acpi_dev_get_resources(adev, &resource_list, | ||
460 | i2c_acpi_fill_info, &lookup); | ||
461 | acpi_dev_free_resource_list(&resource_list); | ||
462 | |||
463 | if (ret < 0 || !info->addr) | ||
464 | return NULL; | ||
465 | |||
466 | adapter = i2c_acpi_find_adapter_by_handle(lookup.adapter_handle); | ||
467 | if (!adapter) | ||
468 | return NULL; | ||
469 | |||
470 | return i2c_new_device(adapter, info); | ||
471 | } | ||
472 | EXPORT_SYMBOL_GPL(i2c_acpi_new_device); | ||
417 | #else /* CONFIG_ACPI */ | 473 | #else /* CONFIG_ACPI */ |
418 | static inline void i2c_acpi_register_devices(struct i2c_adapter *adap) { } | 474 | static inline void i2c_acpi_register_devices(struct i2c_adapter *adap) { } |
419 | extern struct notifier_block i2c_acpi_notifier; | 475 | extern struct notifier_block i2c_acpi_notifier; |
@@ -929,7 +985,9 @@ static int i2c_device_probe(struct device *dev) | |||
929 | if (!client) | 985 | if (!client) |
930 | return 0; | 986 | return 0; |
931 | 987 | ||
932 | if (!client->irq) { | 988 | driver = to_i2c_driver(dev->driver); |
989 | |||
990 | if (!client->irq && !driver->disable_i2c_core_irq_mapping) { | ||
933 | int irq = -ENOENT; | 991 | int irq = -ENOENT; |
934 | 992 | ||
935 | if (client->flags & I2C_CLIENT_HOST_NOTIFY) { | 993 | if (client->flags & I2C_CLIENT_HOST_NOTIFY) { |
@@ -951,8 +1009,6 @@ static int i2c_device_probe(struct device *dev) | |||
951 | client->irq = irq; | 1009 | client->irq = irq; |
952 | } | 1010 | } |
953 | 1011 | ||
954 | driver = to_i2c_driver(dev->driver); | ||
955 | |||
956 | /* | 1012 | /* |
957 | * An I2C ID table is not mandatory, if and only if, a suitable Device | 1013 | * An I2C ID table is not mandatory, if and only if, a suitable Device |
958 | * Tree match table entry is supplied for the probing device. | 1014 | * Tree match table entry is supplied for the probing device. |
diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 6b183521c616..3a57e3dc9bec 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h | |||
@@ -149,6 +149,7 @@ enum i2c_alert_protocol { | |||
149 | * @detect: Callback for device detection | 149 | * @detect: Callback for device detection |
150 | * @address_list: The I2C addresses to probe (for detect) | 150 | * @address_list: The I2C addresses to probe (for detect) |
151 | * @clients: List of detected clients we created (for i2c-core use only) | 151 | * @clients: List of detected clients we created (for i2c-core use only) |
152 | * @disable_i2c_core_irq_mapping: Tell the i2c-core to not do irq-mapping | ||
152 | * | 153 | * |
153 | * The driver.owner field should be set to the module owner of this driver. | 154 | * The driver.owner field should be set to the module owner of this driver. |
154 | * The driver.name field should be set to the name of this driver. | 155 | * The driver.name field should be set to the name of this driver. |
@@ -212,6 +213,8 @@ struct i2c_driver { | |||
212 | int (*detect)(struct i2c_client *, struct i2c_board_info *); | 213 | int (*detect)(struct i2c_client *, struct i2c_board_info *); |
213 | const unsigned short *address_list; | 214 | const unsigned short *address_list; |
214 | struct list_head clients; | 215 | struct list_head clients; |
216 | |||
217 | bool disable_i2c_core_irq_mapping; | ||
215 | }; | 218 | }; |
216 | #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver) | 219 | #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver) |
217 | 220 | ||
@@ -824,11 +827,18 @@ static inline const struct of_device_id | |||
824 | 827 | ||
825 | #if IS_ENABLED(CONFIG_ACPI) | 828 | #if IS_ENABLED(CONFIG_ACPI) |
826 | u32 i2c_acpi_find_bus_speed(struct device *dev); | 829 | u32 i2c_acpi_find_bus_speed(struct device *dev); |
830 | struct i2c_client *i2c_acpi_new_device(struct device *dev, int index, | ||
831 | struct i2c_board_info *info); | ||
827 | #else | 832 | #else |
828 | static inline u32 i2c_acpi_find_bus_speed(struct device *dev) | 833 | static inline u32 i2c_acpi_find_bus_speed(struct device *dev) |
829 | { | 834 | { |
830 | return 0; | 835 | return 0; |
831 | } | 836 | } |
837 | static inline struct i2c_client *i2c_acpi_new_device(struct device *dev, | ||
838 | int index, struct i2c_board_info *info) | ||
839 | { | ||
840 | return NULL; | ||
841 | } | ||
832 | #endif /* CONFIG_ACPI */ | 842 | #endif /* CONFIG_ACPI */ |
833 | 843 | ||
834 | #endif /* _LINUX_I2C_H */ | 844 | #endif /* _LINUX_I2C_H */ |