diff options
-rw-r--r-- | drivers/i2c/i2c-boardinfo.c | 12 | ||||
-rw-r--r-- | drivers/i2c/i2c-core.c | 30 | ||||
-rw-r--r-- | include/linux/i2c.h | 4 |
3 files changed, 46 insertions, 0 deletions
diff --git a/drivers/i2c/i2c-boardinfo.c b/drivers/i2c/i2c-boardinfo.c index 0e285c68b2ff..31186ead5a40 100644 --- a/drivers/i2c/i2c-boardinfo.c +++ b/drivers/i2c/i2c-boardinfo.c @@ -90,6 +90,18 @@ int i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsig } } + if (info->resources) { + devinfo->board_info.resources = + kmemdup(info->resources, + info->num_resources * + sizeof(*info->resources), + GFP_KERNEL); + if (!devinfo->board_info.resources) { + status = -ENOMEM; + break; + } + } + list_add_tail(&devinfo->list, &__i2c_board_list); } diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index bf7892e3b0c8..679a31fcb6d6 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -1278,6 +1278,32 @@ static void i2c_dev_set_name(struct i2c_adapter *adap, i2c_encode_flags_to_addr(client)); } +static int i2c_dev_irq_from_resources(const struct resource *resources, + unsigned int num_resources) +{ + struct irq_data *irqd; + int i; + + for (i = 0; i < num_resources; i++) { + const struct resource *r = &resources[i]; + + if (resource_type(r) != IORESOURCE_IRQ) + continue; + + if (r->flags & IORESOURCE_BITS) { + irqd = irq_get_irq_data(r->start); + if (!irqd) + break; + + irqd_set_trigger_type(irqd, r->flags & IORESOURCE_BITS); + } + + return r->start; + } + + return 0; +} + /** * i2c_new_device - instantiate an i2c device * @adap: the adapter managing the device @@ -1313,7 +1339,11 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) client->flags = info->flags; client->addr = info->addr; + client->irq = info->irq; + if (!client->irq) + client->irq = i2c_dev_irq_from_resources(info->resources, + info->num_resources); strlcpy(client->name, info->type, sizeof(client->name)); diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 6366989d1001..c5bd8b8daf97 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -304,6 +304,8 @@ static inline int i2c_slave_event(struct i2c_client *client, * @of_node: pointer to OpenFirmware device node * @fwnode: device node supplied by the platform firmware * @properties: additional device properties for the device + * @resources: resources associated with the device + * @num_resources: number of resources in the @resources array * @irq: stored in i2c_client.irq * * I2C doesn't actually support hardware probing, although controllers and @@ -326,6 +328,8 @@ struct i2c_board_info { struct device_node *of_node; struct fwnode_handle *fwnode; const struct property_entry *properties; + const struct resource *resources; + unsigned int num_resources; int irq; }; |