Commit 2d0ef4fb authored by Linus Torvalds's avatar Linus Torvalds

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
parents 5a667a0c fde1e418
...@@ -8,8 +8,8 @@ reason, the kernel code must instantiate I2C devices explicitly. There are ...@@ -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. 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 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 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 ...@@ -51,6 +51,43 @@ The devices will be automatically unbound and destroyed when the I2C bus
they sit on goes away (if ever.) 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 Method 2: Instantiate the devices explicitly
-------------------------------------------- --------------------------------------------
......
...@@ -97,7 +97,6 @@ enum { ...@@ -97,7 +97,6 @@ enum {
enum { enum {
MV64XXX_I2C_ACTION_INVALID, MV64XXX_I2C_ACTION_INVALID,
MV64XXX_I2C_ACTION_CONTINUE, MV64XXX_I2C_ACTION_CONTINUE,
MV64XXX_I2C_ACTION_OFFLOAD_SEND_START,
MV64XXX_I2C_ACTION_SEND_START, MV64XXX_I2C_ACTION_SEND_START,
MV64XXX_I2C_ACTION_SEND_RESTART, MV64XXX_I2C_ACTION_SEND_RESTART,
MV64XXX_I2C_ACTION_OFFLOAD_RESTART, MV64XXX_I2C_ACTION_OFFLOAD_RESTART,
...@@ -204,6 +203,9 @@ static int mv64xxx_i2c_offload_msg(struct mv64xxx_i2c_data *drv_data) ...@@ -204,6 +203,9 @@ static int mv64xxx_i2c_offload_msg(struct mv64xxx_i2c_data *drv_data)
unsigned long ctrl_reg; unsigned long ctrl_reg;
struct i2c_msg *msg = drv_data->msgs; struct i2c_msg *msg = drv_data->msgs;
if (!drv_data->offload_enabled)
return -EOPNOTSUPP;
drv_data->msg = msg; drv_data->msg = msg;
drv_data->byte_posn = 0; drv_data->byte_posn = 0;
drv_data->bytes_left = msg->len; drv_data->bytes_left = msg->len;
...@@ -433,8 +435,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) ...@@ -433,8 +435,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
drv_data->msgs++; drv_data->msgs++;
drv_data->num_msgs--; drv_data->num_msgs--;
if (!(drv_data->offload_enabled && if (mv64xxx_i2c_offload_msg(drv_data) < 0) {
mv64xxx_i2c_offload_msg(drv_data))) {
drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START; drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START;
writel(drv_data->cntl_bits, writel(drv_data->cntl_bits,
drv_data->reg_base + drv_data->reg_offsets.control); drv_data->reg_base + drv_data->reg_offsets.control);
...@@ -458,15 +459,14 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) ...@@ -458,15 +459,14 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
drv_data->reg_base + drv_data->reg_offsets.control); drv_data->reg_base + drv_data->reg_offsets.control);
break; 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: case MV64XXX_I2C_ACTION_SEND_START:
writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START, /* Can we offload this msg ? */
drv_data->reg_base + drv_data->reg_offsets.control); 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; break;
case MV64XXX_I2C_ACTION_SEND_ADDR_1: 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, ...@@ -625,15 +625,10 @@ mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg,
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&drv_data->lock, 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->action = MV64XXX_I2C_ACTION_SEND_START;
drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND; drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND;
}
drv_data->send_stop = is_last; drv_data->send_stop = is_last;
drv_data->block = 1; drv_data->block = 1;
mv64xxx_i2c_do_action(drv_data); mv64xxx_i2c_do_action(drv_data);
......
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