mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 12:42:02 +00:00
Merge branch 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull i2c fixes from Wolfram Sang: "i2c has a bugfix and documentation improvements for you" * 'i2c/for-current' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: Documentation: i2c: mention ACPI method for instantiating devices Documentation: i2c: describe devicetree method for instantiating devices i2c: mv64xxx: refactor message start to ensure proper initialization
This commit is contained in:
commit
2d0ef4fb34
@ -8,8 +8,8 @@ reason, the kernel code must instantiate I2C devices explicitly. There are
|
||||
several ways to achieve this, depending on the context and requirements.
|
||||
|
||||
|
||||
Method 1: Declare the I2C devices by bus number
|
||||
-----------------------------------------------
|
||||
Method 1a: Declare the I2C devices by bus number
|
||||
------------------------------------------------
|
||||
|
||||
This method is appropriate when the I2C bus is a system bus as is the case
|
||||
for many embedded systems. On such systems, each I2C bus has a number
|
||||
@ -51,6 +51,43 @@ The devices will be automatically unbound and destroyed when the I2C bus
|
||||
they sit on goes away (if ever.)
|
||||
|
||||
|
||||
Method 1b: Declare the I2C devices via devicetree
|
||||
-------------------------------------------------
|
||||
|
||||
This method has the same implications as method 1a. The declaration of I2C
|
||||
devices is here done via devicetree as subnodes of the master controller.
|
||||
|
||||
Example:
|
||||
|
||||
i2c1: i2c@400a0000 {
|
||||
/* ... master properties skipped ... */
|
||||
clock-frequency = <100000>;
|
||||
|
||||
flash@50 {
|
||||
compatible = "atmel,24c256";
|
||||
reg = <0x50>;
|
||||
};
|
||||
|
||||
pca9532: gpio@60 {
|
||||
compatible = "nxp,pca9532";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
reg = <0x60>;
|
||||
};
|
||||
};
|
||||
|
||||
Here, two devices are attached to the bus using a speed of 100kHz. For
|
||||
additional properties which might be needed to set up the device, please refer
|
||||
to its devicetree documentation in Documentation/devicetree/bindings/.
|
||||
|
||||
|
||||
Method 1c: Declare the I2C devices via ACPI
|
||||
-------------------------------------------
|
||||
|
||||
ACPI can also describe I2C devices. There is special documentation for this
|
||||
which is currently located at Documentation/acpi/enumeration.txt.
|
||||
|
||||
|
||||
Method 2: Instantiate the devices explicitly
|
||||
--------------------------------------------
|
||||
|
||||
|
@ -97,7 +97,6 @@ enum {
|
||||
enum {
|
||||
MV64XXX_I2C_ACTION_INVALID,
|
||||
MV64XXX_I2C_ACTION_CONTINUE,
|
||||
MV64XXX_I2C_ACTION_OFFLOAD_SEND_START,
|
||||
MV64XXX_I2C_ACTION_SEND_START,
|
||||
MV64XXX_I2C_ACTION_SEND_RESTART,
|
||||
MV64XXX_I2C_ACTION_OFFLOAD_RESTART,
|
||||
@ -204,6 +203,9 @@ static int mv64xxx_i2c_offload_msg(struct mv64xxx_i2c_data *drv_data)
|
||||
unsigned long ctrl_reg;
|
||||
struct i2c_msg *msg = drv_data->msgs;
|
||||
|
||||
if (!drv_data->offload_enabled)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
drv_data->msg = msg;
|
||||
drv_data->byte_posn = 0;
|
||||
drv_data->bytes_left = msg->len;
|
||||
@ -433,8 +435,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
|
||||
|
||||
drv_data->msgs++;
|
||||
drv_data->num_msgs--;
|
||||
if (!(drv_data->offload_enabled &&
|
||||
mv64xxx_i2c_offload_msg(drv_data))) {
|
||||
if (mv64xxx_i2c_offload_msg(drv_data) < 0) {
|
||||
drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START;
|
||||
writel(drv_data->cntl_bits,
|
||||
drv_data->reg_base + drv_data->reg_offsets.control);
|
||||
@ -458,15 +459,14 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
|
||||
drv_data->reg_base + drv_data->reg_offsets.control);
|
||||
break;
|
||||
|
||||
case MV64XXX_I2C_ACTION_OFFLOAD_SEND_START:
|
||||
if (!mv64xxx_i2c_offload_msg(drv_data))
|
||||
break;
|
||||
else
|
||||
drv_data->action = MV64XXX_I2C_ACTION_SEND_START;
|
||||
/* FALLTHRU */
|
||||
case MV64XXX_I2C_ACTION_SEND_START:
|
||||
writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START,
|
||||
drv_data->reg_base + drv_data->reg_offsets.control);
|
||||
/* Can we offload this msg ? */
|
||||
if (mv64xxx_i2c_offload_msg(drv_data) < 0) {
|
||||
/* No, switch to standard path */
|
||||
mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs);
|
||||
writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START,
|
||||
drv_data->reg_base + drv_data->reg_offsets.control);
|
||||
}
|
||||
break;
|
||||
|
||||
case MV64XXX_I2C_ACTION_SEND_ADDR_1:
|
||||
@ -625,15 +625,10 @@ mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg,
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&drv_data->lock, flags);
|
||||
if (drv_data->offload_enabled) {
|
||||
drv_data->action = MV64XXX_I2C_ACTION_OFFLOAD_SEND_START;
|
||||
drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND;
|
||||
} else {
|
||||
mv64xxx_i2c_prepare_for_io(drv_data, msg);
|
||||
|
||||
drv_data->action = MV64XXX_I2C_ACTION_SEND_START;
|
||||
drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND;
|
||||
}
|
||||
drv_data->action = MV64XXX_I2C_ACTION_SEND_START;
|
||||
drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND;
|
||||
|
||||
drv_data->send_stop = is_last;
|
||||
drv_data->block = 1;
|
||||
mv64xxx_i2c_do_action(drv_data);
|
||||
|
Loading…
Reference in New Issue
Block a user