aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWolfram Sang <wsa@the-dreams.de>2017-04-16 16:03:54 -0400
committerWolfram Sang <wsa@the-dreams.de>2017-04-16 16:03:54 -0400
commitc99a30d8c4d5e26e69fe3c01c4caf7b6f309e026 (patch)
tree54dfe072975276817214734bc224398b2c514609
parent879bce228526c500bff3ed8ffec7bf89d98a9e11 (diff)
parentd1d84bb95364ed604015c2b788caaf3dbca0262f (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.c62
-rw-r--r--include/linux/i2c.h10
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,
414static struct notifier_block i2c_acpi_notifier = { 421static 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 */
441struct 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}
472EXPORT_SYMBOL_GPL(i2c_acpi_new_device);
417#else /* CONFIG_ACPI */ 473#else /* CONFIG_ACPI */
418static inline void i2c_acpi_register_devices(struct i2c_adapter *adap) { } 474static inline void i2c_acpi_register_devices(struct i2c_adapter *adap) { }
419extern struct notifier_block i2c_acpi_notifier; 475extern 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)
826u32 i2c_acpi_find_bus_speed(struct device *dev); 829u32 i2c_acpi_find_bus_speed(struct device *dev);
830struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
831 struct i2c_board_info *info);
827#else 832#else
828static inline u32 i2c_acpi_find_bus_speed(struct device *dev) 833static inline u32 i2c_acpi_find_bus_speed(struct device *dev)
829{ 834{
830 return 0; 835 return 0;
831} 836}
837static 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 */