Merge branch 'ib/4.11-rc3-i2c-irq-resources' into next
Bring in changes to i2c to better manage device properties and to allow specifying client interrupt through a resource structure.
This commit is contained in:
commit
165fe9c9cd
3 changed files with 61 additions and 2 deletions
|
@ -15,6 +15,7 @@
|
|||
#include <linux/export.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/rwsem.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
|
@ -55,6 +56,7 @@ EXPORT_SYMBOL_GPL(__i2c_first_dynamic_bus_num);
|
|||
*
|
||||
* The board info passed can safely be __initdata, but be careful of embedded
|
||||
* pointers (for platform_data, functions, etc) since that won't be copied.
|
||||
* Device properties are deep-copied though.
|
||||
*/
|
||||
int i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned len)
|
||||
{
|
||||
|
@ -78,6 +80,28 @@ int i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsig
|
|||
|
||||
devinfo->busnum = busnum;
|
||||
devinfo->board_info = *info;
|
||||
|
||||
if (info->properties) {
|
||||
devinfo->board_info.properties =
|
||||
property_entries_dup(info->properties);
|
||||
if (IS_ERR(devinfo->board_info.properties)) {
|
||||
status = PTR_ERR(devinfo->board_info.properties);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,6 @@
|
|||
static DEFINE_MUTEX(core_lock);
|
||||
static DEFINE_IDR(i2c_adapter_idr);
|
||||
|
||||
static struct device_type i2c_client_type;
|
||||
static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
|
||||
|
||||
static struct static_key i2c_trace_msg = STATIC_KEY_INIT_FALSE;
|
||||
|
@ -1097,11 +1096,12 @@ struct bus_type i2c_bus_type = {
|
|||
};
|
||||
EXPORT_SYMBOL_GPL(i2c_bus_type);
|
||||
|
||||
static struct device_type i2c_client_type = {
|
||||
struct device_type i2c_client_type = {
|
||||
.groups = i2c_dev_groups,
|
||||
.uevent = i2c_device_uevent,
|
||||
.release = i2c_client_dev_release,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(i2c_client_type);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -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));
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
extern struct bus_type i2c_bus_type;
|
||||
extern struct device_type i2c_adapter_type;
|
||||
extern struct device_type i2c_client_type;
|
||||
|
||||
/* --- General options ------------------------------------------------ */
|
||||
|
||||
|
@ -303,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
|
||||
|
@ -325,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;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue