diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-02-15 19:17:51 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-02-15 19:17:51 -0500 |
| commit | 2d0ef4fb34b0462d84a2d87292144b9dad79c8d0 (patch) | |
| tree | 76e98a2ba1cae8baf1ce8e96f64b16aa98a41f2d | |
| parent | 5a667a0c02f3d24eb82a44074d24524c17e1ad34 (diff) | |
| parent | fde1e418ab2c4269035f7f576e678b6ad3117d7d (diff) | |
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
| -rw-r--r-- | Documentation/i2c/instantiating-devices | 41 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-mv64xxx.c | 33 |
2 files changed, 53 insertions, 21 deletions
diff --git a/Documentation/i2c/instantiating-devices b/Documentation/i2c/instantiating-devices index c70e7a7638d1..0d85ac1935b7 100644 --- a/Documentation/i2c/instantiating-devices +++ b/Documentation/i2c/instantiating-devices | |||
| @@ -8,8 +8,8 @@ reason, the kernel code must instantiate I2C devices explicitly. There are | |||
| 8 | several ways to achieve this, depending on the context and requirements. | 8 | several ways to achieve this, depending on the context and requirements. |
| 9 | 9 | ||
| 10 | 10 | ||
| 11 | Method 1: Declare the I2C devices by bus number | 11 | Method 1a: Declare the I2C devices by bus number |
| 12 | ----------------------------------------------- | 12 | ------------------------------------------------ |
| 13 | 13 | ||
| 14 | This method is appropriate when the I2C bus is a system bus as is the case | 14 | This method is appropriate when the I2C bus is a system bus as is the case |
| 15 | for many embedded systems. On such systems, each I2C bus has a number | 15 | 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 | they sit on goes away (if ever.) | 51 | they sit on goes away (if ever.) |
| 52 | 52 | ||
| 53 | 53 | ||
| 54 | Method 1b: Declare the I2C devices via devicetree | ||
| 55 | ------------------------------------------------- | ||
| 56 | |||
| 57 | This method has the same implications as method 1a. The declaration of I2C | ||
| 58 | devices is here done via devicetree as subnodes of the master controller. | ||
| 59 | |||
| 60 | Example: | ||
| 61 | |||
| 62 | i2c1: i2c@400a0000 { | ||
| 63 | /* ... master properties skipped ... */ | ||
| 64 | clock-frequency = <100000>; | ||
| 65 | |||
| 66 | flash@50 { | ||
| 67 | compatible = "atmel,24c256"; | ||
| 68 | reg = <0x50>; | ||
| 69 | }; | ||
| 70 | |||
| 71 | pca9532: gpio@60 { | ||
| 72 | compatible = "nxp,pca9532"; | ||
| 73 | gpio-controller; | ||
| 74 | #gpio-cells = <2>; | ||
| 75 | reg = <0x60>; | ||
| 76 | }; | ||
| 77 | }; | ||
| 78 | |||
| 79 | Here, two devices are attached to the bus using a speed of 100kHz. For | ||
| 80 | additional properties which might be needed to set up the device, please refer | ||
| 81 | to its devicetree documentation in Documentation/devicetree/bindings/. | ||
| 82 | |||
| 83 | |||
| 84 | Method 1c: Declare the I2C devices via ACPI | ||
| 85 | ------------------------------------------- | ||
| 86 | |||
| 87 | ACPI can also describe I2C devices. There is special documentation for this | ||
| 88 | which is currently located at Documentation/acpi/enumeration.txt. | ||
| 89 | |||
| 90 | |||
| 54 | Method 2: Instantiate the devices explicitly | 91 | Method 2: Instantiate the devices explicitly |
| 55 | -------------------------------------------- | 92 | -------------------------------------------- |
| 56 | 93 | ||
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index b8c5187b9ee0..d52d84937ad3 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c | |||
| @@ -97,7 +97,6 @@ enum { | |||
| 97 | enum { | 97 | enum { |
| 98 | MV64XXX_I2C_ACTION_INVALID, | 98 | MV64XXX_I2C_ACTION_INVALID, |
| 99 | MV64XXX_I2C_ACTION_CONTINUE, | 99 | MV64XXX_I2C_ACTION_CONTINUE, |
| 100 | MV64XXX_I2C_ACTION_OFFLOAD_SEND_START, | ||
| 101 | MV64XXX_I2C_ACTION_SEND_START, | 100 | MV64XXX_I2C_ACTION_SEND_START, |
| 102 | MV64XXX_I2C_ACTION_SEND_RESTART, | 101 | MV64XXX_I2C_ACTION_SEND_RESTART, |
| 103 | MV64XXX_I2C_ACTION_OFFLOAD_RESTART, | 102 | MV64XXX_I2C_ACTION_OFFLOAD_RESTART, |
| @@ -204,6 +203,9 @@ static int mv64xxx_i2c_offload_msg(struct mv64xxx_i2c_data *drv_data) | |||
| 204 | unsigned long ctrl_reg; | 203 | unsigned long ctrl_reg; |
| 205 | struct i2c_msg *msg = drv_data->msgs; | 204 | struct i2c_msg *msg = drv_data->msgs; |
| 206 | 205 | ||
| 206 | if (!drv_data->offload_enabled) | ||
| 207 | return -EOPNOTSUPP; | ||
| 208 | |||
| 207 | drv_data->msg = msg; | 209 | drv_data->msg = msg; |
| 208 | drv_data->byte_posn = 0; | 210 | drv_data->byte_posn = 0; |
| 209 | drv_data->bytes_left = msg->len; | 211 | drv_data->bytes_left = msg->len; |
| @@ -433,8 +435,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) | |||
| 433 | 435 | ||
| 434 | drv_data->msgs++; | 436 | drv_data->msgs++; |
| 435 | drv_data->num_msgs--; | 437 | drv_data->num_msgs--; |
| 436 | if (!(drv_data->offload_enabled && | 438 | if (mv64xxx_i2c_offload_msg(drv_data) < 0) { |
| 437 | mv64xxx_i2c_offload_msg(drv_data))) { | ||
| 438 | drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START; | 439 | drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START; |
| 439 | writel(drv_data->cntl_bits, | 440 | writel(drv_data->cntl_bits, |
| 440 | drv_data->reg_base + drv_data->reg_offsets.control); | 441 | drv_data->reg_base + drv_data->reg_offsets.control); |
| @@ -458,15 +459,14 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data) | |||
| 458 | drv_data->reg_base + drv_data->reg_offsets.control); | 459 | drv_data->reg_base + drv_data->reg_offsets.control); |
| 459 | break; | 460 | break; |
| 460 | 461 | ||
| 461 | case MV64XXX_I2C_ACTION_OFFLOAD_SEND_START: | ||
| 462 | if (!mv64xxx_i2c_offload_msg(drv_data)) | ||
| 463 | break; | ||
| 464 | else | ||
| 465 | drv_data->action = MV64XXX_I2C_ACTION_SEND_START; | ||
| 466 | /* FALLTHRU */ | ||
| 467 | case MV64XXX_I2C_ACTION_SEND_START: | 462 | case MV64XXX_I2C_ACTION_SEND_START: |
| 468 | writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START, | 463 | /* Can we offload this msg ? */ |
| 469 | drv_data->reg_base + drv_data->reg_offsets.control); | 464 | if (mv64xxx_i2c_offload_msg(drv_data) < 0) { |
| 465 | /* No, switch to standard path */ | ||
| 466 | mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs); | ||
| 467 | writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START, | ||
| 468 | drv_data->reg_base + drv_data->reg_offsets.control); | ||
| 469 | } | ||
| 470 | break; | 470 | break; |
| 471 | 471 | ||
| 472 | case MV64XXX_I2C_ACTION_SEND_ADDR_1: | 472 | 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 | unsigned long flags; | 625 | unsigned long flags; |
| 626 | 626 | ||
| 627 | spin_lock_irqsave(&drv_data->lock, flags); | 627 | spin_lock_irqsave(&drv_data->lock, flags); |
| 628 | if (drv_data->offload_enabled) { | ||
| 629 | drv_data->action = MV64XXX_I2C_ACTION_OFFLOAD_SEND_START; | ||
| 630 | drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND; | ||
| 631 | } else { | ||
| 632 | mv64xxx_i2c_prepare_for_io(drv_data, msg); | ||
| 633 | 628 | ||
| 634 | drv_data->action = MV64XXX_I2C_ACTION_SEND_START; | 629 | drv_data->action = MV64XXX_I2C_ACTION_SEND_START; |
| 635 | drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND; | 630 | drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND; |
| 636 | } | 631 | |
| 637 | drv_data->send_stop = is_last; | 632 | drv_data->send_stop = is_last; |
| 638 | drv_data->block = 1; | 633 | drv_data->block = 1; |
| 639 | mv64xxx_i2c_do_action(drv_data); | 634 | mv64xxx_i2c_do_action(drv_data); |
