Commit 5c6fb005 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging

* 'i2c-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging:
  i2c: New macro to initialize i2c address lists on the fly
  i2c: Don't advertise i2c functions when not available
  i2c: Use rwsem instead of mutex for board info
  i2c: Add a sysfs interface to instantiate devices
  i2c: Limit core locking to the necessary sections
  i2c: Kill the redundant client list
  i2c: Kill is_newstyle_driver
  i2c: Merge i2c_attach_client into i2c_new_device
  i2c: Drop i2c_probe function
  i2c: Get rid of the legacy binding model
  i2c: Kill client_register and client_unregister methods
parents 31583d6a c7036673
...@@ -368,16 +368,6 @@ Who: Krzysztof Piotr Oledzki <ole@ans.pl> ...@@ -368,16 +368,6 @@ Who: Krzysztof Piotr Oledzki <ole@ans.pl>
--------------------------- ---------------------------
What: i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client(),
i2c_adapter->client_register(), i2c_adapter->client_unregister
When: 2.6.30
Check: i2c_attach_client i2c_detach_client
Why: Deprecated by the new (standard) device driver binding model. Use
i2c_driver->probe() and ->remove() instead.
Who: Jean Delvare <khali@linux-fr.org>
---------------------------
What: fscher and fscpos drivers What: fscher and fscpos drivers
When: June 2009 When: June 2009
Why: Deprecated by the new fschmd driver. Why: Deprecated by the new fschmd driver.
......
...@@ -165,3 +165,47 @@ was done there. Two significant differences are: ...@@ -165,3 +165,47 @@ was done there. Two significant differences are:
Once again, method 3 should be avoided wherever possible. Explicit device Once again, method 3 should be avoided wherever possible. Explicit device
instantiation (methods 1 and 2) is much preferred for it is safer and instantiation (methods 1 and 2) is much preferred for it is safer and
faster. faster.
Method 4: Instantiate from user-space
-------------------------------------
In general, the kernel should know which I2C devices are connected and
what addresses they live at. However, in certain cases, it does not, so a
sysfs interface was added to let the user provide the information. This
interface is made of 2 attribute files which are created in every I2C bus
directory: new_device and delete_device. Both files are write only and you
must write the right parameters to them in order to properly instantiate,
respectively delete, an I2C device.
File new_device takes 2 parameters: the name of the I2C device (a string)
and the address of the I2C device (a number, typically expressed in
hexadecimal starting with 0x, but can also be expressed in decimal.)
File delete_device takes a single parameter: the address of the I2C
device. As no two devices can live at the same address on a given I2C
segment, the address is sufficient to uniquely identify the device to be
deleted.
Example:
# echo eeprom 0x50 > /sys/class/i2c-adapter/i2c-3/new_device
While this interface should only be used when in-kernel device declaration
can't be done, there is a variety of cases where it can be helpful:
* The I2C driver usually detects devices (method 3 above) but the bus
segment your device lives on doesn't have the proper class bit set and
thus detection doesn't trigger.
* The I2C driver usually detects devices, but your device lives at an
unexpected address.
* The I2C driver usually detects devices, but your device is not detected,
either because the detection routine is too strict, or because your
device is not officially supported yet but you know it is compatible.
* You are developing a driver on a test board, where you soldered the I2C
device yourself.
This interface is a replacement for the force_* module parameters some I2C
drivers implement. Being implemented in i2c-core rather than in each
device driver individually, it is much more efficient, and also has the
advantage that you do not have to reload the driver to change a setting.
You can also instantiate the device before the driver is loaded or even
available, and you don't need to know what driver the device needs.
...@@ -126,19 +126,9 @@ different) configuration information, as do drivers handling chip variants ...@@ -126,19 +126,9 @@ different) configuration information, as do drivers handling chip variants
that can't be distinguished by protocol probing, or which need some board that can't be distinguished by protocol probing, or which need some board
specific information to operate correctly. specific information to operate correctly.
Accordingly, the I2C stack now has two models for associating I2C devices
with their drivers: the original "legacy" model, and a newer one that's
fully compatible with the Linux 2.6 driver model. These models do not mix,
since the "legacy" model requires drivers to create "i2c_client" device
objects after SMBus style probing, while the Linux driver model expects
drivers to be given such device objects in their probe() routines.
The legacy model is deprecated now and will soon be removed, so we no Device/Driver Binding
longer document it here. ---------------------
Standard Driver Model Binding ("New Style")
-------------------------------------------
System infrastructure, typically board-specific initialization code or System infrastructure, typically board-specific initialization code or
boot firmware, reports what I2C devices exist. For example, there may be boot firmware, reports what I2C devices exist. For example, there may be
...@@ -201,7 +191,7 @@ a given I2C bus. This is for example the case of hardware monitoring ...@@ -201,7 +191,7 @@ a given I2C bus. This is for example the case of hardware monitoring
devices on a PC's SMBus. In that case, you may want to let your driver devices on a PC's SMBus. In that case, you may want to let your driver
detect supported devices automatically. This is how the legacy model detect supported devices automatically. This is how the legacy model
was working, and is now available as an extension to the standard was working, and is now available as an extension to the standard
driver model (so that we can finally get rid of the legacy model.) driver model.
You simply have to define a detect callback which will attempt to You simply have to define a detect callback which will attempt to
identify supported devices (returning 0 for supported ones and -ENODEV identify supported devices (returning 0 for supported ones and -ENODEV
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/rwsem.h>
#include "i2c-core.h" #include "i2c-core.h"
...@@ -25,7 +26,7 @@ ...@@ -25,7 +26,7 @@
/* These symbols are exported ONLY FOR the i2c core. /* These symbols are exported ONLY FOR the i2c core.
* No other users will be supported. * No other users will be supported.
*/ */
DEFINE_MUTEX(__i2c_board_lock); DECLARE_RWSEM(__i2c_board_lock);
EXPORT_SYMBOL_GPL(__i2c_board_lock); EXPORT_SYMBOL_GPL(__i2c_board_lock);
LIST_HEAD(__i2c_board_list); LIST_HEAD(__i2c_board_list);
...@@ -63,7 +64,7 @@ i2c_register_board_info(int busnum, ...@@ -63,7 +64,7 @@ i2c_register_board_info(int busnum,
{ {
int status; int status;
mutex_lock(&__i2c_board_lock); down_write(&__i2c_board_lock);
/* dynamic bus numbers will be assigned after the last static one */ /* dynamic bus numbers will be assigned after the last static one */
if (busnum >= __i2c_first_dynamic_bus_num) if (busnum >= __i2c_first_dynamic_bus_num)
...@@ -84,7 +85,7 @@ i2c_register_board_info(int busnum, ...@@ -84,7 +85,7 @@ i2c_register_board_info(int busnum,
list_add_tail(&devinfo->list, &__i2c_board_list); list_add_tail(&devinfo->list, &__i2c_board_list);
} }
mutex_unlock(&__i2c_board_lock); up_write(&__i2c_board_lock);
return status; return status;
} }
This diff is collapsed.
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <linux/rwsem.h>
struct i2c_devinfo { struct i2c_devinfo {
struct list_head list; struct list_head list;
int busnum; int busnum;
...@@ -25,7 +27,7 @@ struct i2c_devinfo { ...@@ -25,7 +27,7 @@ struct i2c_devinfo {
/* board_lock protects board_list and first_dynamic_bus_num. /* board_lock protects board_list and first_dynamic_bus_num.
* only i2c core components are allowed to use these symbols. * only i2c core components are allowed to use these symbols.
*/ */
extern struct mutex __i2c_board_lock; extern struct rw_semaphore __i2c_board_lock;
extern struct list_head __i2c_board_list; extern struct list_head __i2c_board_list;
extern int __i2c_first_dynamic_bus_num; extern int __i2c_first_dynamic_bus_num;
...@@ -47,6 +47,7 @@ struct i2c_driver; ...@@ -47,6 +47,7 @@ struct i2c_driver;
union i2c_smbus_data; union i2c_smbus_data;
struct i2c_board_info; struct i2c_board_info;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
/* /*
* The master routines are the ones normally used to transmit data to devices * The master routines are the ones normally used to transmit data to devices
* on a bus (or read from them). Apart from two basic transfer functions to * on a bus (or read from them). Apart from two basic transfer functions to
...@@ -93,6 +94,7 @@ extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, ...@@ -93,6 +94,7 @@ extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client,
extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client,
u8 command, u8 length, u8 command, u8 length,
const u8 *values); const u8 *values);
#endif /* I2C */
/** /**
* struct i2c_driver - represent an I2C device driver * struct i2c_driver - represent an I2C device driver
...@@ -100,9 +102,8 @@ extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, ...@@ -100,9 +102,8 @@ extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client,
* @class: What kind of i2c device we instantiate (for detect) * @class: What kind of i2c device we instantiate (for detect)
* @attach_adapter: Callback for bus addition (for legacy drivers) * @attach_adapter: Callback for bus addition (for legacy drivers)
* @detach_adapter: Callback for bus removal (for legacy drivers) * @detach_adapter: Callback for bus removal (for legacy drivers)
* @detach_client: Callback for device removal (for legacy drivers) * @probe: Callback for device binding
* @probe: Callback for device binding (new-style drivers) * @remove: Callback for device unbinding
* @remove: Callback for device unbinding (new-style drivers)
* @shutdown: Callback for device shutdown * @shutdown: Callback for device shutdown
* @suspend: Callback for device suspend * @suspend: Callback for device suspend
* @resume: Callback for device resume * @resume: Callback for device resume
...@@ -137,26 +138,14 @@ struct i2c_driver { ...@@ -137,26 +138,14 @@ struct i2c_driver {
int id; int id;
unsigned int class; unsigned int class;
/* Notifies the driver that a new bus has appeared. This routine /* Notifies the driver that a new bus has appeared or is about to be
* can be used by the driver to test if the bus meets its conditions * removed. You should avoid using this if you can, it will probably
* & seek for the presence of the chip(s) it supports. If found, it * be removed in a near future.
* registers the client(s) that are on the bus to the i2c admin. via
* i2c_attach_client. (LEGACY I2C DRIVERS ONLY)
*/ */
int (*attach_adapter)(struct i2c_adapter *); int (*attach_adapter)(struct i2c_adapter *);
int (*detach_adapter)(struct i2c_adapter *); int (*detach_adapter)(struct i2c_adapter *);
/* tells the driver that a client is about to be deleted & gives it /* Standard driver model interfaces */
* the chance to remove its private data. Also, if the client struct
* has been dynamically allocated by the driver in the function above,
* it must be freed here. (LEGACY I2C DRIVERS ONLY)
*/
int (*detach_client)(struct i2c_client *) __deprecated;
/* Standard driver model interfaces, for "new style" i2c drivers.
* With the driver model, device enumeration is NEVER done by drivers;
* it's done by infrastructure. (NEW STYLE DRIVERS ONLY)
*/
int (*probe)(struct i2c_client *, const struct i2c_device_id *); int (*probe)(struct i2c_client *, const struct i2c_device_id *);
int (*remove)(struct i2c_client *); int (*remove)(struct i2c_client *);
...@@ -191,9 +180,8 @@ struct i2c_driver { ...@@ -191,9 +180,8 @@ struct i2c_driver {
* @driver: device's driver, hence pointer to access routines * @driver: device's driver, hence pointer to access routines
* @dev: Driver model device node for the slave. * @dev: Driver model device node for the slave.
* @irq: indicates the IRQ generated by this device (if any) * @irq: indicates the IRQ generated by this device (if any)
* @list: list of active/busy clients (DEPRECATED) * @detected: member of an i2c_driver.clients list or i2c-core's
* @detected: member of an i2c_driver.clients list * userspace_devices list
* @released: used to synchronize client releases & detaches and references
* *
* An i2c_client identifies a single device (i.e. chip) connected to an * An i2c_client identifies a single device (i.e. chip) connected to an
* i2c bus. The behaviour exposed to Linux is defined by the driver * i2c bus. The behaviour exposed to Linux is defined by the driver
...@@ -209,9 +197,7 @@ struct i2c_client { ...@@ -209,9 +197,7 @@ struct i2c_client {
struct i2c_driver *driver; /* and our access routines */ struct i2c_driver *driver; /* and our access routines */
struct device dev; /* the device structure */ struct device dev; /* the device structure */
int irq; /* irq issued by device */ int irq; /* irq issued by device */
struct list_head list; /* DEPRECATED */
struct list_head detected; struct list_head detected;
struct completion released;
}; };
#define to_i2c_client(d) container_of(d, struct i2c_client, dev) #define to_i2c_client(d) container_of(d, struct i2c_client, dev)
...@@ -248,11 +234,10 @@ static inline void i2c_set_clientdata(struct i2c_client *dev, void *data) ...@@ -248,11 +234,10 @@ static inline void i2c_set_clientdata(struct i2c_client *dev, void *data)
* that, such as chip type, configuration, associated IRQ, and so on. * that, such as chip type, configuration, associated IRQ, and so on.
* *
* i2c_board_info is used to build tables of information listing I2C devices * i2c_board_info is used to build tables of information listing I2C devices
* that are present. This information is used to grow the driver model tree * that are present. This information is used to grow the driver model tree.
* for "new style" I2C drivers. For mainboards this is done statically using * For mainboards this is done statically using i2c_register_board_info();
* i2c_register_board_info(); bus numbers identify adapters that aren't * bus numbers identify adapters that aren't yet available. For add-on boards,
* yet available. For add-on boards, i2c_new_device() does this dynamically * i2c_new_device() does this dynamically with the adapter already known.
* with the adapter already known.
*/ */
struct i2c_board_info { struct i2c_board_info {
char type[I2C_NAME_SIZE]; char type[I2C_NAME_SIZE];
...@@ -277,6 +262,7 @@ struct i2c_board_info { ...@@ -277,6 +262,7 @@ struct i2c_board_info {
.type = dev_type, .addr = (dev_addr) .type = dev_type, .addr = (dev_addr)
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
/* Add-on boards should register/unregister their devices; e.g. a board /* Add-on boards should register/unregister their devices; e.g. a board
* with integrated I2C, a config eeprom, sensors, and a codec that's * with integrated I2C, a config eeprom, sensors, and a codec that's
* used in conjunction with the primary hardware. * used in conjunction with the primary hardware.
...@@ -300,6 +286,7 @@ extern struct i2c_client * ...@@ -300,6 +286,7 @@ extern struct i2c_client *
i2c_new_dummy(struct i2c_adapter *adap, u16 address); i2c_new_dummy(struct i2c_adapter *adap, u16 address);
extern void i2c_unregister_device(struct i2c_client *); extern void i2c_unregister_device(struct i2c_client *);
#endif /* I2C */
/* Mainboard arch_initcall() code should register all its I2C devices. /* Mainboard arch_initcall() code should register all its I2C devices.
* This is done at arch_initcall time, before declaring any i2c adapters. * This is done at arch_initcall time, before declaring any i2c adapters.
...@@ -316,7 +303,7 @@ i2c_register_board_info(int busnum, struct i2c_board_info const *info, ...@@ -316,7 +303,7 @@ i2c_register_board_info(int busnum, struct i2c_board_info const *info,
{ {
return 0; return 0;
} }
#endif #endif /* I2C_BOARDINFO */
/* /*
* The following structs are for those who like to implement new bus drivers: * The following structs are for those who like to implement new bus drivers:
...@@ -352,21 +339,15 @@ struct i2c_adapter { ...@@ -352,21 +339,15 @@ struct i2c_adapter {
const struct i2c_algorithm *algo; /* the algorithm to access the bus */ const struct i2c_algorithm *algo; /* the algorithm to access the bus */
void *algo_data; void *algo_data;
/* --- administration stuff. */
int (*client_register)(struct i2c_client *) __deprecated;
int (*client_unregister)(struct i2c_client *) __deprecated;
/* data fields that are valid for all devices */ /* data fields that are valid for all devices */
u8 level; /* nesting level for lockdep */ u8 level; /* nesting level for lockdep */
struct mutex bus_lock; struct mutex bus_lock;
struct mutex clist_lock;
int timeout; /* in jiffies */ int timeout; /* in jiffies */
int retries; int retries;
struct device dev; /* the adapter device */ struct device dev; /* the adapter device */
int nr; int nr;
struct list_head clients; /* DEPRECATED */
char name[48]; char name[48];
struct completion dev_released; struct completion dev_released;
}; };
...@@ -412,11 +393,16 @@ struct i2c_client_address_data { ...@@ -412,11 +393,16 @@ struct i2c_client_address_data {
/* The numbers to use to set I2C bus address */ /* The numbers to use to set I2C bus address */
#define ANY_I2C_BUS 0xffff #define ANY_I2C_BUS 0xffff
/* Construct an I2C_CLIENT_END-terminated array of i2c addresses */
#define I2C_ADDRS(addr, addrs...) \
((const unsigned short []){ addr, ## addrs, I2C_CLIENT_END })
/* ----- functions exported by i2c.o */ /* ----- functions exported by i2c.o */
/* administration... /* administration...
*/ */
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
extern int i2c_add_adapter(struct i2c_adapter *); extern int i2c_add_adapter(struct i2c_adapter *);
extern int i2c_del_adapter(struct i2c_adapter *); extern int i2c_del_adapter(struct i2c_adapter *);
extern int i2c_add_numbered_adapter(struct i2c_adapter *); extern int i2c_add_numbered_adapter(struct i2c_adapter *);
...@@ -429,11 +415,6 @@ static inline int i2c_add_driver(struct i2c_driver *driver) ...@@ -429,11 +415,6 @@ static inline int i2c_add_driver(struct i2c_driver *driver)
return i2c_register_driver(THIS_MODULE, driver); return i2c_register_driver(THIS_MODULE, driver);
} }
/* These are deprecated, your driver should use the standard .probe()
* and .remove() methods instead. */
extern int __deprecated i2c_attach_client(struct i2c_client *);
extern int __deprecated i2c_detach_client(struct i2c_client *);
extern struct i2c_client *i2c_use_client(struct i2c_client *client); extern struct i2c_client *i2c_use_client(struct i2c_client *client);
extern void i2c_release_client(struct i2c_client *client); extern void i2c_release_client(struct i2c_client *client);
...@@ -442,14 +423,6 @@ extern void i2c_release_client(struct i2c_client *client); ...@@ -442,14 +423,6 @@ extern void i2c_release_client(struct i2c_client *client);
extern void i2c_clients_command(struct i2c_adapter *adap, extern void i2c_clients_command(struct i2c_adapter *adap,
unsigned int cmd, void *arg); unsigned int cmd, void *arg);
/* Detect function. It iterates over all possible addresses itself.
* It will only call found_proc if some client is connected at the
* specific address (unless a 'force' matched);
*/
extern int i2c_probe(struct i2c_adapter *adapter,
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); extern struct i2c_adapter *i2c_get_adapter(int id);
extern void i2c_put_adapter(struct i2c_adapter *adap); extern void i2c_put_adapter(struct i2c_adapter *adap);
...@@ -471,6 +444,7 @@ static inline int i2c_adapter_id(struct i2c_adapter *adap) ...@@ -471,6 +444,7 @@ static inline int i2c_adapter_id(struct i2c_adapter *adap)
{ {
return adap->nr; return adap->nr;
} }
#endif /* I2C */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment