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:
@@ -15,6 +15,7 @@
|
|||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/property.h>
|
||||||
#include <linux/rwsem.h>
|
#include <linux/rwsem.h>
|
||||||
#include <linux/slab.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
|
* 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.
|
* 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)
|
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->busnum = busnum;
|
||||||
devinfo->board_info = *info;
|
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);
|
list_add_tail(&devinfo->list, &__i2c_board_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -74,7 +74,6 @@
|
|||||||
static DEFINE_MUTEX(core_lock);
|
static DEFINE_MUTEX(core_lock);
|
||||||
static DEFINE_IDR(i2c_adapter_idr);
|
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 int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
|
||||||
|
|
||||||
static struct static_key i2c_trace_msg = STATIC_KEY_INIT_FALSE;
|
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);
|
EXPORT_SYMBOL_GPL(i2c_bus_type);
|
||||||
|
|
||||||
static struct device_type i2c_client_type = {
|
struct device_type i2c_client_type = {
|
||||||
.groups = i2c_dev_groups,
|
.groups = i2c_dev_groups,
|
||||||
.uevent = i2c_device_uevent,
|
.uevent = i2c_device_uevent,
|
||||||
.release = i2c_client_dev_release,
|
.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));
|
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
|
* i2c_new_device - instantiate an i2c device
|
||||||
* @adap: the adapter managing the 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->flags = info->flags;
|
||||||
client->addr = info->addr;
|
client->addr = info->addr;
|
||||||
|
|
||||||
client->irq = info->irq;
|
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));
|
strlcpy(client->name, info->type, sizeof(client->name));
|
||||||
|
|
||||||
|
@@ -38,6 +38,7 @@
|
|||||||
|
|
||||||
extern struct bus_type i2c_bus_type;
|
extern struct bus_type i2c_bus_type;
|
||||||
extern struct device_type i2c_adapter_type;
|
extern struct device_type i2c_adapter_type;
|
||||||
|
extern struct device_type i2c_client_type;
|
||||||
|
|
||||||
/* --- General options ------------------------------------------------ */
|
/* --- General options ------------------------------------------------ */
|
||||||
|
|
||||||
@@ -303,6 +304,8 @@ static inline int i2c_slave_event(struct i2c_client *client,
|
|||||||
* @of_node: pointer to OpenFirmware device node
|
* @of_node: pointer to OpenFirmware device node
|
||||||
* @fwnode: device node supplied by the platform firmware
|
* @fwnode: device node supplied by the platform firmware
|
||||||
* @properties: additional device properties for the device
|
* @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
|
* @irq: stored in i2c_client.irq
|
||||||
*
|
*
|
||||||
* I2C doesn't actually support hardware probing, although controllers and
|
* I2C doesn't actually support hardware probing, although controllers and
|
||||||
@@ -325,6 +328,8 @@ struct i2c_board_info {
|
|||||||
struct device_node *of_node;
|
struct device_node *of_node;
|
||||||
struct fwnode_handle *fwnode;
|
struct fwnode_handle *fwnode;
|
||||||
const struct property_entry *properties;
|
const struct property_entry *properties;
|
||||||
|
const struct resource *resources;
|
||||||
|
unsigned int num_resources;
|
||||||
int irq;
|
int irq;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user