From bfb6df24facfde7ec6191edbba798777efb3c375 Mon Sep 17 00:00:00 2001 From: "Mark M. Hoffman" Date: Sun, 27 Jan 2008 18:14:46 +0100 Subject: i2c: Constify client address data This patch allows much of the I2C client address data to move from initdata into text. Signed-off-by: Mark M. Hoffman Signed-off-by: Jean Delvare --- include/linux/i2c.h | 100 ++++++++++++++++++++++------------------------------ 1 file changed, 43 insertions(+), 57 deletions(-) (limited to 'include/linux/i2c.h') diff --git a/include/linux/i2c.h b/include/linux/i2c.h index a100c9f8eb7c..37c14b08d61a 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -357,10 +357,10 @@ static inline void i2c_set_adapdata (struct i2c_adapter *dev, void *data) * command line */ struct i2c_client_address_data { - unsigned short *normal_i2c; - unsigned short *probe; - unsigned short *ignore; - unsigned short **forces; + const unsigned short *normal_i2c; + const unsigned short *probe; + const unsigned short *ignore; + const unsigned short * const *forces; }; /* Internal numbers to terminate lists */ @@ -405,7 +405,7 @@ extern void i2c_clients_command(struct i2c_adapter *adap, * specific address (unless a 'force' matched); */ extern int i2c_probe(struct i2c_adapter *adapter, - struct i2c_client_address_data *address_data, + const struct i2c_client_address_data *address_data, int (*found_proc) (struct i2c_adapter *, int, int)); extern struct i2c_adapter* i2c_get_adapter(int id); @@ -598,104 +598,93 @@ I2C_CLIENT_MODULE_PARM(probe, "List of adapter,address pairs to scan " \ "additionally"); \ I2C_CLIENT_MODULE_PARM(ignore, "List of adapter,address pairs not to " \ "scan"); \ -static struct i2c_client_address_data addr_data = { \ +const static struct i2c_client_address_data addr_data = { \ .normal_i2c = normal_i2c, \ .probe = probe, \ .ignore = ignore, \ .forces = forces, \ } +#define I2C_CLIENT_FORCE_TEXT \ + "List of adapter,address pairs to boldly assume to be present" + /* These are the ones you want to use in your own drivers. Pick the one which matches the number of devices the driver differenciates between. */ -#define I2C_CLIENT_INSMOD \ - I2C_CLIENT_MODULE_PARM(force, \ - "List of adapter,address pairs to boldly assume " \ - "to be present"); \ - static unsigned short *forces[] = { \ - force, \ - NULL \ - }; \ +#define I2C_CLIENT_INSMOD \ +I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ +static const unsigned short * const forces[] = { force, NULL }; \ I2C_CLIENT_INSMOD_COMMON #define I2C_CLIENT_INSMOD_1(chip1) \ enum chips { any_chip, chip1 }; \ -I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to " \ - "boldly assume to be present"); \ +I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ -static unsigned short *forces[] = { force, force_##chip1, NULL }; \ +static const unsigned short * const forces[] = { force, \ + force_##chip1, NULL }; \ I2C_CLIENT_INSMOD_COMMON #define I2C_CLIENT_INSMOD_2(chip1, chip2) \ enum chips { any_chip, chip1, chip2 }; \ -I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to " \ - "boldly assume to be present"); \ +I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ -static unsigned short *forces[] = { force, force_##chip1, \ - force_##chip2, NULL }; \ +static const unsigned short * const forces[] = { force, \ + force_##chip1, force_##chip2, NULL }; \ I2C_CLIENT_INSMOD_COMMON #define I2C_CLIENT_INSMOD_3(chip1, chip2, chip3) \ enum chips { any_chip, chip1, chip2, chip3 }; \ -I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to " \ - "boldly assume to be present"); \ +I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ -static unsigned short *forces[] = { force, force_##chip1, \ - force_##chip2, force_##chip3, \ - NULL }; \ +static const unsigned short * const forces[] = { force, \ + force_##chip1, force_##chip2, force_##chip3, NULL }; \ I2C_CLIENT_INSMOD_COMMON #define I2C_CLIENT_INSMOD_4(chip1, chip2, chip3, chip4) \ enum chips { any_chip, chip1, chip2, chip3, chip4 }; \ -I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to " \ - "boldly assume to be present"); \ +I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ I2C_CLIENT_MODULE_PARM_FORCE(chip4); \ -static unsigned short *forces[] = { force, force_##chip1, \ - force_##chip2, force_##chip3, \ - force_##chip4, NULL}; \ +static const unsigned short * const forces[] = { force, \ + force_##chip1, force_##chip2, force_##chip3, \ + force_##chip4, NULL}; \ I2C_CLIENT_INSMOD_COMMON #define I2C_CLIENT_INSMOD_5(chip1, chip2, chip3, chip4, chip5) \ enum chips { any_chip, chip1, chip2, chip3, chip4, chip5 }; \ -I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to " \ - "boldly assume to be present"); \ +I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ I2C_CLIENT_MODULE_PARM_FORCE(chip4); \ I2C_CLIENT_MODULE_PARM_FORCE(chip5); \ -static unsigned short *forces[] = { force, force_##chip1, \ - force_##chip2, force_##chip3, \ - force_##chip4, force_##chip5, \ - NULL }; \ +static const unsigned short * const forces[] = { force, \ + force_##chip1, force_##chip2, force_##chip3, \ + force_##chip4, force_##chip5, NULL }; \ I2C_CLIENT_INSMOD_COMMON #define I2C_CLIENT_INSMOD_6(chip1, chip2, chip3, chip4, chip5, chip6) \ enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6 }; \ -I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to " \ - "boldly assume to be present"); \ +I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ I2C_CLIENT_MODULE_PARM_FORCE(chip4); \ I2C_CLIENT_MODULE_PARM_FORCE(chip5); \ I2C_CLIENT_MODULE_PARM_FORCE(chip6); \ -static unsigned short *forces[] = { force, force_##chip1, \ - force_##chip2, force_##chip3, \ - force_##chip4, force_##chip5, \ - force_##chip6, NULL }; \ +static const unsigned short * const forces[] = { force, \ + force_##chip1, force_##chip2, force_##chip3, \ + force_##chip4, force_##chip5, force_##chip6, NULL }; \ I2C_CLIENT_INSMOD_COMMON #define I2C_CLIENT_INSMOD_7(chip1, chip2, chip3, chip4, chip5, chip6, chip7) \ enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \ chip7 }; \ -I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to " \ - "boldly assume to be present"); \ +I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ @@ -703,18 +692,16 @@ I2C_CLIENT_MODULE_PARM_FORCE(chip4); \ I2C_CLIENT_MODULE_PARM_FORCE(chip5); \ I2C_CLIENT_MODULE_PARM_FORCE(chip6); \ I2C_CLIENT_MODULE_PARM_FORCE(chip7); \ -static unsigned short *forces[] = { force, force_##chip1, \ - force_##chip2, force_##chip3, \ - force_##chip4, force_##chip5, \ - force_##chip6, force_##chip7, \ - NULL }; \ +static const unsigned short * const forces[] = { force, \ + force_##chip1, force_##chip2, force_##chip3, \ + force_##chip4, force_##chip5, force_##chip6, \ + force_##chip7, NULL }; \ I2C_CLIENT_INSMOD_COMMON #define I2C_CLIENT_INSMOD_8(chip1, chip2, chip3, chip4, chip5, chip6, chip7, chip8) \ enum chips { any_chip, chip1, chip2, chip3, chip4, chip5, chip6, \ chip7, chip8 }; \ -I2C_CLIENT_MODULE_PARM(force, "List of adapter,address pairs to " \ - "boldly assume to be present"); \ +I2C_CLIENT_MODULE_PARM(force, I2C_CLIENT_FORCE_TEXT); \ I2C_CLIENT_MODULE_PARM_FORCE(chip1); \ I2C_CLIENT_MODULE_PARM_FORCE(chip2); \ I2C_CLIENT_MODULE_PARM_FORCE(chip3); \ @@ -723,11 +710,10 @@ I2C_CLIENT_MODULE_PARM_FORCE(chip5); \ I2C_CLIENT_MODULE_PARM_FORCE(chip6); \ I2C_CLIENT_MODULE_PARM_FORCE(chip7); \ I2C_CLIENT_MODULE_PARM_FORCE(chip8); \ -static unsigned short *forces[] = { force, force_##chip1, \ - force_##chip2, force_##chip3, \ - force_##chip4, force_##chip5, \ - force_##chip6, force_##chip7, \ - force_##chip8, NULL }; \ +static const unsigned short * const forces[] = { force, \ + force_##chip1, force_##chip2, force_##chip3, \ + force_##chip4, force_##chip5, force_##chip6, \ + force_##chip7, force_##chip8, NULL }; \ I2C_CLIENT_INSMOD_COMMON #endif /* __KERNEL__ */ #endif /* _LINUX_I2C_H */ -- cgit v1.2.3 From bdc511f438f6ca40307e06edda00331e6ac0f813 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 27 Jan 2008 18:14:48 +0100 Subject: i2c: Use the driver model reference counting Don't implement our own reference counting mechanism for i2c clients when the driver model already has one. Signed-off-by: Jean Delvare Cc: David Brownell --- include/linux/i2c.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/linux/i2c.h') diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 37c14b08d61a..f7cd2f370c39 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -155,7 +155,6 @@ struct i2c_driver { * generic enough to hide second-sourcing and compatible revisions. * @adapter: manages the bus segment hosting this I2C device * @driver: device's driver, hence pointer to access routines - * @usage_count: counts current number of users of this client * @dev: Driver model device node for the slave. * @irq: indicates the IRQ generated by this device (if any) * @driver_name: Identifies new-style driver used with this device; also @@ -175,8 +174,6 @@ struct i2c_client { char name[I2C_NAME_SIZE]; struct i2c_adapter *adapter; /* the adapter we sit on */ struct i2c_driver *driver; /* and our access routines */ - int usage_count; /* How many accesses currently */ - /* to the client */ struct device dev; /* the device structure */ int irq; /* irq issued by device (or -1) */ char driver_name[KOBJ_NAME_LEN]; -- cgit v1.2.3 From e48d33193d94175f012c3ed606a1d1e574ed726a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 27 Jan 2008 18:14:48 +0100 Subject: i2c: Change prototypes of refcounting functions Use more standard prototypes for i2c_use_client() and i2c_release_client(). The former now returns a pointer to the client, and the latter no longer returns anything. This matches what all other subsystems do. Signed-off-by: Jean Delvare Cc: David Brownell --- include/linux/i2c.h | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'include/linux/i2c.h') diff --git a/include/linux/i2c.h b/include/linux/i2c.h index f7cd2f370c39..78a305bed8eb 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -386,11 +386,8 @@ static inline int i2c_add_driver(struct i2c_driver *driver) extern int i2c_attach_client(struct i2c_client *); extern int i2c_detach_client(struct i2c_client *); -/* Should be used to make sure that client-struct is valid and that it - is okay to access the i2c-client. - returns -ENODEV if client has gone in the meantime */ -extern int i2c_use_client(struct i2c_client *); -extern int i2c_release_client(struct i2c_client *); +extern struct i2c_client *i2c_use_client(struct i2c_client *client); +extern void i2c_release_client(struct i2c_client *client); /* call the i2c_client->command() of all attached clients with * the given arguments */ -- cgit v1.2.3 From 87c6c22945e5d68eb96dd1e5cb26185253cd5b9d Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 27 Jan 2008 18:14:48 +0100 Subject: i2c: Drop redundant i2c_adapter.list i2c_adapter.list is superfluous, this list duplicates the one maintained by the driver core. Drop it. Signed-off-by: Jean Delvare Acked-by: David Brownell --- include/linux/i2c.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux/i2c.h') diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 78a305bed8eb..5fa7e180501d 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -317,7 +317,6 @@ struct i2c_adapter { int nr; struct list_head clients; - struct list_head list; char name[48]; struct completion dev_released; }; -- cgit v1.2.3 From 026526f5afcd421dce110f53e4c4e2b9e78753c2 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 27 Jan 2008 18:14:49 +0100 Subject: i2c: Drop redundant i2c_driver.list i2c_driver.list is superfluous, this list duplicates the one maintained by the driver core. Drop it. Signed-off-by: Jean Delvare Acked-by: David Brownell --- include/linux/i2c.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux/i2c.h') diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 5fa7e180501d..0fc59efd80e4 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -140,7 +140,6 @@ struct i2c_driver { int (*command)(struct i2c_client *client,unsigned int cmd, void *arg); struct device_driver driver; - struct list_head list; }; #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver) -- cgit v1.2.3 From 9b766b814d6a5f31ca1e9da1ebc08164b9352941 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sun, 27 Jan 2008 18:14:51 +0100 Subject: i2c: Stop using the redundant client list The i2c_adapter.clients list of i2c_client nodes duplicates driver model state. This patch starts removing that list, letting us remove most existing users of those i2c-core lists. * The core I2C code now iterates over the driver model's list instead of the i2c-internal one in some places where it's safe: - Passing a command/ioctl to each client, a mechanims used almost exclusively by DVB adapters; - Device address checking, in both i2c-core and i2c-dev. * Provide i2c_verify_client() to use with driver model iterators. * Flag the relevant i2c_adapter and i2c_client fields as deprecated, to help prevent new users from appearing. For the moment the list needs to stick around, since some issues show up when deleting devices created by legacy I2C drivers. (They don't follow standard driver model rules. Removing those devices can cause self-deadlocks.) Signed-off-by: David Brownell Signed-off-by: Jean Delvare --- include/linux/i2c.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'include/linux/i2c.h') diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 0fc59efd80e4..731928ae972c 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -158,7 +158,7 @@ struct i2c_driver { * @irq: indicates the IRQ generated by this device (if any) * @driver_name: Identifies new-style driver used with this device; also * used as the module name for hotplug/coldplug modprobe support. - * @list: list of active/busy clients + * @list: list of active/busy clients (DEPRECATED) * @released: used to synchronize client releases & detaches and references * * An i2c_client identifies a single device (i.e. chip) connected to an @@ -176,11 +176,13 @@ struct i2c_client { struct device dev; /* the device structure */ int irq; /* irq issued by device (or -1) */ char driver_name[KOBJ_NAME_LEN]; - struct list_head list; + struct list_head list; /* DEPRECATED */ struct completion released; }; #define to_i2c_client(d) container_of(d, struct i2c_client, dev) +extern struct i2c_client *i2c_verify_client(struct device *dev); + static inline struct i2c_client *kobj_to_i2c_client(struct kobject *kobj) { struct device * const dev = container_of(kobj, struct device, kobj); @@ -315,7 +317,7 @@ struct i2c_adapter { struct device dev; /* the adapter device */ int nr; - struct list_head clients; + struct list_head clients; /* DEPRECATED */ char name[48]; struct completion dev_released; }; -- cgit v1.2.3 From e9f1373b643887f63878d1169b310c9acc534cd5 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Sun, 27 Jan 2008 18:14:52 +0100 Subject: i2c: Add i2c_new_dummy() utility This adds a i2c_new_dummy() primitive to help work with devices that consume multiple addresses, which include many I2C eeproms and at least one RTC. Signed-off-by: David Brownell Signed-off-by: Jean Delvare --- include/linux/i2c.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux/i2c.h') diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 731928ae972c..76014f8f3c60 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -259,6 +259,12 @@ i2c_new_probed_device(struct i2c_adapter *adap, struct i2c_board_info *info, unsigned short const *addr_list); +/* For devices that use several addresses, use i2c_new_dummy() to make + * client handles for the extra addresses. + */ +extern struct i2c_client * +i2c_new_dummy(struct i2c_adapter *adap, u16 address, const char *type); + extern void i2c_unregister_device(struct i2c_client *); /* Mainboard arch_initcall() code should register all its I2C devices. -- cgit v1.2.3