summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/i2c/i2c-boardinfo.c12
-rw-r--r--drivers/i2c/i2c-core.c30
-rw-r--r--include/linux/i2c.h4
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;
};