[PATCH v7] OMAP4:keypad: PM runtime

2010-12-14 Thread Shubhrajyoti D
From: Abraham Arce 

Enable Runtime PM functionality in OMAP4 driver based on the following 
assumptions
- Runtime PM selected by ARCH_OMAP2PLUS_TYPICAL && ARCH_OMAP2PLUS,
  which is the default OMAP2+ defconfig including OMAP4
- Runtime PM APIs handles Clock Framework APIs
- Do not do the keypadconfig if the irq request fails

A minimal pm runtime get/put approach is implemented in probe/remove calls
respectively based on:

- Keyboard controller in wakeup domain so it is always on and
  power impact may be minimal
- Cutting of clocks will prevent interrupts


Signed-off-by: Abraham Arce 
Cc: Kevin Hilman 
---
Updating the changelogs as per Kevin's suggestion

 drivers/input/keyboard/omap4-keypad.c |   11 +--
 1 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/input/keyboard/omap4-keypad.c 
b/drivers/input/keyboard/omap4-keypad.c
index 45bd097..36239e2 100644
--- a/drivers/input/keyboard/omap4-keypad.c
+++ b/drivers/input/keyboard/omap4-keypad.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -239,7 +240,8 @@ static int __devinit omap4_keypad_probe(struct 
platform_device *pdev)
matrix_keypad_build_keymap(pdata->keymap_data, row_shift,
input_dev->keycode, input_dev->keybit);
 
-   omap4_keypad_config(keypad_data);
+   pm_runtime_enable(&pdev->dev);
+   pm_runtime_get_sync(&pdev->dev);
 
error = request_irq(keypad_data->irq, omap4_keypad_interrupt,
 IRQF_TRIGGER_RISING,
@@ -255,8 +257,9 @@ static int __devinit omap4_keypad_probe(struct 
platform_device *pdev)
goto err_free_irq;
}
 
-
+   omap4_keypad_config(keypad_data);
platform_set_drvdata(pdev, keypad_data);
+
return 0;
 
 err_free_irq:
@@ -278,6 +281,10 @@ static int __devexit omap4_keypad_remove(struct 
platform_device *pdev)
struct resource *res;
 
free_irq(keypad_data->irq, keypad_data);
+
+   pm_runtime_put_sync(&pdev->dev);
+   pm_runtime_disable(&pdev->dev);
+
input_unregister_device(keypad_data->input);
 
iounmap(keypad_data->base);
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v7] OMAP4:keypad: PM runtime

2010-12-14 Thread Shubhrajyoti D
From: Abraham Arce 

Enable Runtime PM functionality in OMAP4 driver based on the following 
assumptions

A minimal pm runtime get/put approach is implemented in probe/remove calls
respectively.

- Keyboard controller in wakeup domain so it is always on and
  power impact may be minimal
- In OMAP4 the device control is at module/device level and ick/fclk level 
control is
  difficult so cutting of clocks will prevent interrupts.

Signed-off-by: Abraham Arce 
Cc: Kevin Hilman 
---
Updating the changelogs as per Kevin's suggestion
 drivers/input/keyboard/omap4-keypad.c |   10 +-
 1 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/drivers/input/keyboard/omap4-keypad.c 
b/drivers/input/keyboard/omap4-keypad.c
index 45bd097..3d35774 100644
--- a/drivers/input/keyboard/omap4-keypad.c
+++ b/drivers/input/keyboard/omap4-keypad.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -239,8 +240,11 @@ static int __devinit omap4_keypad_probe(struct 
platform_device *pdev)
matrix_keypad_build_keymap(pdata->keymap_data, row_shift,
input_dev->keycode, input_dev->keybit);
 
-   omap4_keypad_config(keypad_data);
+   pm_runtime_enable(&pdev->dev);
+   pm_runtime_get_sync(&pdev->dev);
 
+   omap4_keypad_config(keypad_data);
+   
error = request_irq(keypad_data->irq, omap4_keypad_interrupt,
 IRQF_TRIGGER_RISING,
 "omap4-keypad", keypad_data);
@@ -278,6 +282,10 @@ static int __devexit omap4_keypad_remove(struct 
platform_device *pdev)
struct resource *res;
 
free_irq(keypad_data->irq, keypad_data);
+
+   pm_runtime_put_sync(&pdev->dev);
+   pm_runtime_disable(&pdev->dev);
+
input_unregister_device(keypad_data->input);
 
iounmap(keypad_data->base);
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] omap: 4430sdp board support for the the GPIO keys

2010-08-31 Thread Shubhrajyoti D
omap 4430sdp board support for the GPIO keys.
The proximity sensor is connected to GPIO and is registered as a
GPIO key.
- Making the default state of the sensor off at bootup
- The init is called before platform_add_devices

Signed-off-by: Shubhrajyoti D 
---
 arch/arm/mach-omap2/board-4430sdp.c |   61 +++
 1 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-4430sdp.c 
b/arch/arm/mach-omap2/board-4430sdp.c
index 9447644..f31d68e 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -40,6 +41,8 @@
 #define ETH_KS8851_IRQ 34
 #define ETH_KS8851_POWER_ON48
 #define ETH_KS8851_QUART   138
+#define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO   184
+#define OMAP4_SFH7741_ENABLE_GPIO  188
 
 static struct gpio_led sdp4430_gpio_leds[] = {
{
@@ -77,11 +80,47 @@ static struct gpio_led sdp4430_gpio_leds[] = {
 
 };
 
+static struct gpio_keys_button sdp4430_gpio_keys[] = {
+   {
+   .desc   = "Proximity Sensor",
+   .type   = EV_SW,
+   .code   = SW_FRONT_PROXIMITY,
+   .gpio   = OMAP4_SFH7741_SENSOR_OUTPUT_GPIO,
+   .active_low = 0,
+   }
+};
+
 static struct gpio_led_platform_data sdp4430_led_data = {
.leds   = sdp4430_gpio_leds,
.num_leds   = ARRAY_SIZE(sdp4430_gpio_leds),
 };
 
+static int omap_prox_activate(struct device *dev)
+{
+   gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 1);
+   return 0;
+}
+
+static void omap_prox_deactivate(struct device *dev)
+{
+   gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 0);
+}
+
+static struct gpio_keys_platform_data sdp4430_gpio_keys_data = {
+   .buttons= sdp4430_gpio_keys,
+   .nbuttons   = ARRAY_SIZE(sdp4430_gpio_keys),
+   .enable = omap_prox_activate,
+   .disable= omap_prox_deactivate,
+};
+
+static struct platform_device sdp4430_gpio_keys_device = {
+   .name   = "gpio-keys",
+   .id = -1,
+   .dev= {
+   .platform_data  = &sdp4430_gpio_keys_data,
+   },
+};
+
 static struct platform_device sdp4430_leds_gpio = {
.name   = "leds-gpio",
.id = -1,
@@ -161,6 +200,7 @@ static struct platform_device sdp4430_lcd_device = {
 
 static struct platform_device *sdp4430_devices[] __initdata = {
&sdp4430_lcd_device,
+   &sdp4430_gpio_keys_device,
&sdp4430_leds_gpio,
 };
 
@@ -426,11 +466,32 @@ static int __init omap4_i2c_init(void)
omap_register_i2c_bus(4, 400, NULL, 0);
return 0;
 }
+
+static void __init omap_sfh7741prox_init(void)
+{
+   int  error;
+
+   error = gpio_request(OMAP4_SFH7741_ENABLE_GPIO, "sfh7741");
+   if (error < 0) {
+   pr_err("%s:failed to request GPIO %d, error %d\n",
+   __func__, OMAP4_SFH7741_ENABLE_GPIO, error);
+   return;
+   }
+
+   error = gpio_direction_output(OMAP4_SFH7741_ENABLE_GPIO , 0);
+   if (error < 0) {
+   pr_err("%s: GPIO configuration failed: GPIO %d,error %d\n",
+__func__, OMAP4_SFH7741_ENABLE_GPIO, error);
+   gpio_free(OMAP4_SFH7741_ENABLE_GPIO);
+   }
+}
+
 static void __init omap_4430sdp_init(void)
 {
int status;
 
omap4_i2c_init();
+   omap_sfh7741prox_init();
platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices));
omap_serial_init();
omap4_twl6030_hsmmc_init(mmc);
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] omap: 4430sdp board support for proximity sensor

2010-08-31 Thread Shubhrajyoti D
omap 4430sdp board support for the  proximity sensor via GPIO keys.
The proximity sensor is connected to GPIO and is registered as a
GPIO key.
- Making the default state of the sensor off at bootup
- The init is called before platform_add_devices

Signed-off-by: Shubhrajyoti D 
---
 arch/arm/mach-omap2/board-4430sdp.c |   61 +++
 1 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-4430sdp.c 
b/arch/arm/mach-omap2/board-4430sdp.c
index 9447644..f31d68e 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -40,6 +41,8 @@
 #define ETH_KS8851_IRQ 34
 #define ETH_KS8851_POWER_ON48
 #define ETH_KS8851_QUART   138
+#define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO   184
+#define OMAP4_SFH7741_ENABLE_GPIO  188
 
 static struct gpio_led sdp4430_gpio_leds[] = {
{
@@ -77,11 +80,47 @@ static struct gpio_led sdp4430_gpio_leds[] = {
 
 };
 
+static struct gpio_keys_button sdp4430_gpio_keys[] = {
+   {
+   .desc   = "Proximity Sensor",
+   .type   = EV_SW,
+   .code   = SW_FRONT_PROXIMITY,
+   .gpio   = OMAP4_SFH7741_SENSOR_OUTPUT_GPIO,
+   .active_low = 0,
+   }
+};
+
 static struct gpio_led_platform_data sdp4430_led_data = {
.leds   = sdp4430_gpio_leds,
.num_leds   = ARRAY_SIZE(sdp4430_gpio_leds),
 };
 
+static int omap_prox_activate(struct device *dev)
+{
+   gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 1);
+   return 0;
+}
+
+static void omap_prox_deactivate(struct device *dev)
+{
+   gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 0);
+}
+
+static struct gpio_keys_platform_data sdp4430_gpio_keys_data = {
+   .buttons= sdp4430_gpio_keys,
+   .nbuttons   = ARRAY_SIZE(sdp4430_gpio_keys),
+   .enable = omap_prox_activate,
+   .disable= omap_prox_deactivate,
+};
+
+static struct platform_device sdp4430_gpio_keys_device = {
+   .name   = "gpio-keys",
+   .id = -1,
+   .dev= {
+   .platform_data  = &sdp4430_gpio_keys_data,
+   },
+};
+
 static struct platform_device sdp4430_leds_gpio = {
.name   = "leds-gpio",
.id = -1,
@@ -161,6 +200,7 @@ static struct platform_device sdp4430_lcd_device = {
 
 static struct platform_device *sdp4430_devices[] __initdata = {
&sdp4430_lcd_device,
+   &sdp4430_gpio_keys_device,
&sdp4430_leds_gpio,
 };
 
@@ -426,11 +466,32 @@ static int __init omap4_i2c_init(void)
omap_register_i2c_bus(4, 400, NULL, 0);
return 0;
 }
+
+static void __init omap_sfh7741prox_init(void)
+{
+   int  error;
+
+   error = gpio_request(OMAP4_SFH7741_ENABLE_GPIO, "sfh7741");
+   if (error < 0) {
+   pr_err("%s:failed to request GPIO %d, error %d\n",
+   __func__, OMAP4_SFH7741_ENABLE_GPIO, error);
+   return;
+   }
+
+   error = gpio_direction_output(OMAP4_SFH7741_ENABLE_GPIO , 0);
+   if (error < 0) {
+   pr_err("%s: GPIO configuration failed: GPIO %d,error %d\n",
+__func__, OMAP4_SFH7741_ENABLE_GPIO, error);
+   gpio_free(OMAP4_SFH7741_ENABLE_GPIO);
+   }
+}
+
 static void __init omap_4430sdp_init(void)
 {
int status;
 
omap4_i2c_init();
+   omap_sfh7741prox_init();
platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices));
omap_serial_init();
omap4_twl6030_hsmmc_init(mmc);
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [RFC] Remove the debug print noise

2010-08-02 Thread Shubhrajyoti D
This patch intends to make the i2cdetect more readable.

Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 7674efb..3a97d2c 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -626,7 +626,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
if (r < 0)
return r;
if (r == 0) {
-   dev_err(dev->dev, "controller timed out\n");
+   dev_dbg(dev->dev, "controller timed out\n");
omap_i2c_init(dev);
return -ETIMEDOUT;
}
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH] hmc5843: Digital compass board file

2010-08-15 Thread Shubhrajyoti D
The  board file changes for the digital compass hmc5843.
The interface to the device is i2c.

Signed-off-by: Shubhrajyoti D 
---
 arch/arm/mach-omap2/board-4430sdp.c |8 +++-
 1 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/board-4430sdp.c 
b/arch/arm/mach-omap2/board-4430sdp.c
index 9447644..5b6a48d 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -412,6 +412,11 @@ static struct i2c_board_info __initdata 
sdp4430_i2c_3_boardinfo[] = {
I2C_BOARD_INFO("tmp105", 0x48),
},
 };
+static struct i2c_board_info __initdata sdp4430_i2c_4_boardinfo[] = {
+   {
+   I2C_BOARD_INFO("hmc5843", 0x1e),
+   },
+};
 static int __init omap4_i2c_init(void)
 {
/*
@@ -423,7 +428,8 @@ static int __init omap4_i2c_init(void)
omap_register_i2c_bus(2, 400, NULL, 0);
omap_register_i2c_bus(3, 400, sdp4430_i2c_3_boardinfo,
ARRAY_SIZE(sdp4430_i2c_3_boardinfo));
-   omap_register_i2c_bus(4, 400, NULL, 0);
+   omap_register_i2c_bus(4, 400, sdp4430_i2c_4_boardinfo,
+   ARRAY_SIZE(sdp4430_i2c_4_boardinfo));
return 0;
 }
 static void __init omap_4430sdp_init(void)
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH] Board support for the the GPIO keys

2010-08-19 Thread Shubhrajyoti D
Board support for the GPIO keys.
The proximity sensor is connected to GPIO and is registered as a 
GPIO key.

Signed-off-by: Shubhrajyoti D 
---
 arch/arm/mach-omap2/board-4430sdp.c |   56 +++
 1 files changed, 56 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-4430sdp.c 
b/arch/arm/mach-omap2/board-4430sdp.c
index 9447644..7f619bf 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -40,6 +41,10 @@
 #define ETH_KS8851_IRQ 34
 #define ETH_KS8851_POWER_ON48
 #define ETH_KS8851_QUART   138
+#define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO   184
+#define OMAP4_SFH7741_ENABLE_GPIO  188
+static int omap_prox_activate(struct device *dev);
+static void omap_prox_deactivate(struct device *dev);
 
 static struct gpio_led sdp4430_gpio_leds[] = {
{
@@ -76,11 +81,33 @@ static struct gpio_led sdp4430_gpio_leds[] = {
},
 
 };
+static struct gpio_keys_button sdp4430_gpio_keys[] = {
+   {
+   .desc   = "Proximity Sensor",
+   .type   = EV_SW,
+   .code   = SW_FRONT_PROXIMITY,
+   .gpio   = OMAP4_SFH7741_SENSOR_OUTPUT_GPIO,
+   .active_low = 0,
+   }
+};
 
 static struct gpio_led_platform_data sdp4430_led_data = {
.leds   = sdp4430_gpio_leds,
.num_leds   = ARRAY_SIZE(sdp4430_gpio_leds),
 };
+static struct gpio_keys_platform_data sdp4430_gpio_keys_data = {
+   .buttons= sdp4430_gpio_keys,
+   .nbuttons   = ARRAY_SIZE(sdp4430_gpio_keys),
+   .enable = omap_prox_activate,
+   .disable= omap_prox_deactivate,
+};
+static struct platform_device sdp4430_gpio_keys_device = {
+   .name   = "gpio-keys",
+   .id = -1,
+   .dev= {
+   .platform_data  = &sdp4430_gpio_keys_data,
+   },
+};
 
 static struct platform_device sdp4430_leds_gpio = {
.name   = "leds-gpio",
@@ -161,6 +188,7 @@ static struct platform_device sdp4430_lcd_device = {
 
 static struct platform_device *sdp4430_devices[] __initdata = {
&sdp4430_lcd_device,
+   &sdp4430_gpio_keys_device,
&sdp4430_leds_gpio,
 };
 
@@ -426,6 +454,33 @@ static int __init omap4_i2c_init(void)
omap_register_i2c_bus(4, 400, NULL, 0);
return 0;
 }
+static int  omap_prox_activate(struct device *dev)
+{
+   gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 1);
+   return 0;
+}
+static void omap_prox_deactivate(struct device *dev)
+{
+   gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 0);
+}
+static void omap_sfh7741prox_init(void)
+{
+   int  error;
+
+   error = gpio_request(OMAP4_SFH7741_ENABLE_GPIO, "sfh7741");
+   if (error < 0) {
+   pr_err("failed to request GPIO %d, error %d\n",
+   OMAP4_SFH7741_ENABLE_GPIO, error);
+   return;
+   }
+
+   error = gpio_direction_output(OMAP4_SFH7741_ENABLE_GPIO , 1);
+   if (error < 0) {
+   pr_err("%s: GPIO configuration failed: GPIO %d,error %d\n",\
+__func__, OMAP4_SFH7741_ENABLE_GPIO, error);
+   gpio_free(OMAP4_SFH7741_ENABLE_GPIO);
+   }
+}
 static void __init omap_4430sdp_init(void)
 {
int status;
@@ -448,6 +503,7 @@ static void __init omap_4430sdp_init(void)
spi_register_board_info(sdp4430_spi_board_info,
ARRAY_SIZE(sdp4430_spi_board_info));
}
+   omap_sfh7741prox_init();
 }
 
 static void __init omap_4430sdp_map_io(void)
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] Board changes for gpio-keys

2010-08-20 Thread Shubhrajyoti D

Signed-off-by: Shubhrajyoti D 
---
 arch/arm/mach-omap2/board-4430sdp.c |   64 +++
 1 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-4430sdp.c 
b/arch/arm/mach-omap2/board-4430sdp.c
index 9447644..699620d 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -40,6 +41,11 @@
 #define ETH_KS8851_IRQ 34
 #define ETH_KS8851_POWER_ON48
 #define ETH_KS8851_QUART   138
+#define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO   184
+#define OMAP4_SFH7741_ENABLE_GPIO  188
+
+static int omap_prox_activate(struct device *dev);
+static void omap_prox_deactivate(struct device *dev);
 
 static struct gpio_led sdp4430_gpio_leds[] = {
{
@@ -77,11 +83,36 @@ static struct gpio_led sdp4430_gpio_leds[] = {
 
 };
 
+static struct gpio_keys_button sdp4430_gpio_keys[] = {
+   {
+   .desc   = "Proximity Sensor",
+   .type   = EV_SW,
+   .code   = SW_FRONT_PROXIMITY,
+   .gpio   = OMAP4_SFH7741_SENSOR_OUTPUT_GPIO,
+   .active_low = 0,
+   }
+};
+
 static struct gpio_led_platform_data sdp4430_led_data = {
.leds   = sdp4430_gpio_leds,
.num_leds   = ARRAY_SIZE(sdp4430_gpio_leds),
 };
 
+static struct gpio_keys_platform_data sdp4430_gpio_keys_data = {
+   .buttons= sdp4430_gpio_keys,
+   .nbuttons   = ARRAY_SIZE(sdp4430_gpio_keys),
+   .enable = omap_prox_activate,
+   .disable= omap_prox_deactivate,
+};
+
+static struct platform_device sdp4430_gpio_keys_device = {
+   .name   = "gpio-keys",
+   .id = -1,
+   .dev= {
+   .platform_data  = &sdp4430_gpio_keys_data,
+   },
+};
+
 static struct platform_device sdp4430_leds_gpio = {
.name   = "leds-gpio",
.id = -1,
@@ -161,6 +192,7 @@ static struct platform_device sdp4430_lcd_device = {
 
 static struct platform_device *sdp4430_devices[] __initdata = {
&sdp4430_lcd_device,
+   &sdp4430_gpio_keys_device,
&sdp4430_leds_gpio,
 };
 
@@ -426,6 +458,37 @@ static int __init omap4_i2c_init(void)
omap_register_i2c_bus(4, 400, NULL, 0);
return 0;
 }
+
+static int  omap_prox_activate(struct device *dev)
+{
+   gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 1);
+   return 0;
+}
+
+static void omap_prox_deactivate(struct device *dev)
+{
+   gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 0);
+}
+
+static void omap_sfh7741prox_init(void)
+{
+   int  error;
+
+   error = gpio_request(OMAP4_SFH7741_ENABLE_GPIO, "sfh7741");
+   if (error < 0) {
+   pr_err("failed to request GPIO %d, error %d\n",
+   OMAP4_SFH7741_ENABLE_GPIO, error);
+   return;
+   }
+
+   error = gpio_direction_output(OMAP4_SFH7741_ENABLE_GPIO , 1);
+   if (error < 0) {
+   pr_err("%s: GPIO configuration failed: GPIO %d,error %d\n",
+__func__, OMAP4_SFH7741_ENABLE_GPIO, error);
+   gpio_free(OMAP4_SFH7741_ENABLE_GPIO);
+   }
+}
+
 static void __init omap_4430sdp_init(void)
 {
int status;
@@ -448,6 +511,7 @@ static void __init omap_4430sdp_init(void)
spi_register_board_info(sdp4430_spi_board_info,
ARRAY_SIZE(sdp4430_spi_board_info));
}
+   omap_sfh7741prox_init();
 }
 
 static void __init omap_4430sdp_map_io(void)
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] omap: 4430sdp board support for the the GPIO keys

2010-08-20 Thread Shubhrajyoti D
omap 4430sdp board support for the GPIO keys.
The proximity sensor is connected to GPIO and is registered as a
GPIO key.

Signed-off-by: Shubhrajyoti D 
---
 arch/arm/mach-omap2/board-4430sdp.c |   64 +++
 1 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-4430sdp.c 
b/arch/arm/mach-omap2/board-4430sdp.c
index 9447644..699620d 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -40,6 +41,11 @@
 #define ETH_KS8851_IRQ 34
 #define ETH_KS8851_POWER_ON48
 #define ETH_KS8851_QUART   138
+#define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO   184
+#define OMAP4_SFH7741_ENABLE_GPIO  188
+
+static int omap_prox_activate(struct device *dev);
+static void omap_prox_deactivate(struct device *dev);
 
 static struct gpio_led sdp4430_gpio_leds[] = {
{
@@ -77,11 +83,36 @@ static struct gpio_led sdp4430_gpio_leds[] = {
 
 };
 
+static struct gpio_keys_button sdp4430_gpio_keys[] = {
+   {
+   .desc   = "Proximity Sensor",
+   .type   = EV_SW,
+   .code   = SW_FRONT_PROXIMITY,
+   .gpio   = OMAP4_SFH7741_SENSOR_OUTPUT_GPIO,
+   .active_low = 0,
+   }
+};
+
 static struct gpio_led_platform_data sdp4430_led_data = {
.leds   = sdp4430_gpio_leds,
.num_leds   = ARRAY_SIZE(sdp4430_gpio_leds),
 };
 
+static struct gpio_keys_platform_data sdp4430_gpio_keys_data = {
+   .buttons= sdp4430_gpio_keys,
+   .nbuttons   = ARRAY_SIZE(sdp4430_gpio_keys),
+   .enable = omap_prox_activate,
+   .disable= omap_prox_deactivate,
+};
+
+static struct platform_device sdp4430_gpio_keys_device = {
+   .name   = "gpio-keys",
+   .id = -1,
+   .dev= {
+   .platform_data  = &sdp4430_gpio_keys_data,
+   },
+};
+
 static struct platform_device sdp4430_leds_gpio = {
.name   = "leds-gpio",
.id = -1,
@@ -161,6 +192,7 @@ static struct platform_device sdp4430_lcd_device = {
 
 static struct platform_device *sdp4430_devices[] __initdata = {
&sdp4430_lcd_device,
+   &sdp4430_gpio_keys_device,
&sdp4430_leds_gpio,
 };
 
@@ -426,6 +458,37 @@ static int __init omap4_i2c_init(void)
omap_register_i2c_bus(4, 400, NULL, 0);
return 0;
 }
+
+static int  omap_prox_activate(struct device *dev)
+{
+   gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 1);
+   return 0;
+}
+
+static void omap_prox_deactivate(struct device *dev)
+{
+   gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 0);
+}
+
+static void omap_sfh7741prox_init(void)
+{
+   int  error;
+
+   error = gpio_request(OMAP4_SFH7741_ENABLE_GPIO, "sfh7741");
+   if (error < 0) {
+   pr_err("failed to request GPIO %d, error %d\n",
+   OMAP4_SFH7741_ENABLE_GPIO, error);
+   return;
+   }
+
+   error = gpio_direction_output(OMAP4_SFH7741_ENABLE_GPIO , 1);
+   if (error < 0) {
+   pr_err("%s: GPIO configuration failed: GPIO %d,error %d\n",
+__func__, OMAP4_SFH7741_ENABLE_GPIO, error);
+   gpio_free(OMAP4_SFH7741_ENABLE_GPIO);
+   }
+}
+
 static void __init omap_4430sdp_init(void)
 {
int status;
@@ -448,6 +511,7 @@ static void __init omap_4430sdp_init(void)
spi_register_board_info(sdp4430_spi_board_info,
ARRAY_SIZE(sdp4430_spi_board_info));
}
+   omap_sfh7741prox_init();
 }
 
 static void __init omap_4430sdp_map_io(void)
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] omap: 4430sdp board support for the the GPIO keys

2010-08-20 Thread Shubhrajyoti D
omap 4430sdp board support for the GPIO keys.
The proximity sensor is connected to GPIO and is registered as a
GPIO key.

Signed-off-by: Shubhrajyoti D 
---
 arch/arm/mach-omap2/board-4430sdp.c |   64 +++
 1 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-4430sdp.c 
b/arch/arm/mach-omap2/board-4430sdp.c
index 9447644..699620d 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -40,6 +41,11 @@
 #define ETH_KS8851_IRQ 34
 #define ETH_KS8851_POWER_ON48
 #define ETH_KS8851_QUART   138
+#define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO   184
+#define OMAP4_SFH7741_ENABLE_GPIO  188
+
+static int omap_prox_activate(struct device *dev);
+static void omap_prox_deactivate(struct device *dev);
 
 static struct gpio_led sdp4430_gpio_leds[] = {
{
@@ -77,11 +83,36 @@ static struct gpio_led sdp4430_gpio_leds[] = {
 
 };
 
+static struct gpio_keys_button sdp4430_gpio_keys[] = {
+   {
+   .desc   = "Proximity Sensor",
+   .type   = EV_SW,
+   .code   = SW_FRONT_PROXIMITY,
+   .gpio   = OMAP4_SFH7741_SENSOR_OUTPUT_GPIO,
+   .active_low = 0,
+   }
+};
+
 static struct gpio_led_platform_data sdp4430_led_data = {
.leds   = sdp4430_gpio_leds,
.num_leds   = ARRAY_SIZE(sdp4430_gpio_leds),
 };
 
+static struct gpio_keys_platform_data sdp4430_gpio_keys_data = {
+   .buttons= sdp4430_gpio_keys,
+   .nbuttons   = ARRAY_SIZE(sdp4430_gpio_keys),
+   .enable = omap_prox_activate,
+   .disable= omap_prox_deactivate,
+};
+
+static struct platform_device sdp4430_gpio_keys_device = {
+   .name   = "gpio-keys",
+   .id = -1,
+   .dev= {
+   .platform_data  = &sdp4430_gpio_keys_data,
+   },
+};
+
 static struct platform_device sdp4430_leds_gpio = {
.name   = "leds-gpio",
.id = -1,
@@ -161,6 +192,7 @@ static struct platform_device sdp4430_lcd_device = {
 
 static struct platform_device *sdp4430_devices[] __initdata = {
&sdp4430_lcd_device,
+   &sdp4430_gpio_keys_device,
&sdp4430_leds_gpio,
 };
 
@@ -426,6 +458,37 @@ static int __init omap4_i2c_init(void)
omap_register_i2c_bus(4, 400, NULL, 0);
return 0;
 }
+
+static int omap_prox_activate(struct device *dev)
+{
+   gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 1);
+   return 0;
+}
+
+static void omap_prox_deactivate(struct device *dev)
+{
+   gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 0);
+}
+
+static void omap_sfh7741prox_init(void)
+{
+   int  error;
+
+   error = gpio_request(OMAP4_SFH7741_ENABLE_GPIO, "sfh7741");
+   if (error < 0) {
+   pr_err("failed to request GPIO %d, error %d\n",
+   OMAP4_SFH7741_ENABLE_GPIO, error);
+   return;
+   }
+
+   error = gpio_direction_output(OMAP4_SFH7741_ENABLE_GPIO , 1);
+   if (error < 0) {
+   pr_err("%s: GPIO configuration failed: GPIO %d,error %d\n",
+__func__, OMAP4_SFH7741_ENABLE_GPIO, error);
+   gpio_free(OMAP4_SFH7741_ENABLE_GPIO);
+   }
+}
+
 static void __init omap_4430sdp_init(void)
 {
int status;
@@ -448,6 +511,7 @@ static void __init omap_4430sdp_init(void)
spi_register_board_info(sdp4430_spi_board_info,
ARRAY_SIZE(sdp4430_spi_board_info));
}
+   omap_sfh7741prox_init();
 }
 
 static void __init omap_4430sdp_map_io(void)
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2] omap: 4430sdp board support for the the GPIO keys

2010-08-23 Thread Shubhrajyoti D
omap 4430sdp board support for the GPIO keys.
The proximity sensor is connected to GPIO and is registered as a
GPIO key.
- Making the default state of the sensor off at bootup

Signed-off-by: Shubhrajyoti D 
---
 arch/arm/mach-omap2/board-4430sdp.c |   61 +++
 1 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/board-4430sdp.c 
b/arch/arm/mach-omap2/board-4430sdp.c
index 9447644..85b0e0c 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -40,6 +41,8 @@
 #define ETH_KS8851_IRQ 34
 #define ETH_KS8851_POWER_ON48
 #define ETH_KS8851_QUART   138
+#define OMAP4_SFH7741_SENSOR_OUTPUT_GPIO   184
+#define OMAP4_SFH7741_ENABLE_GPIO  188
 
 static struct gpio_led sdp4430_gpio_leds[] = {
{
@@ -77,11 +80,47 @@ static struct gpio_led sdp4430_gpio_leds[] = {
 
 };
 
+static struct gpio_keys_button sdp4430_gpio_keys[] = {
+   {
+   .desc   = "Proximity Sensor",
+   .type   = EV_SW,
+   .code   = SW_FRONT_PROXIMITY,
+   .gpio   = OMAP4_SFH7741_SENSOR_OUTPUT_GPIO,
+   .active_low = 0,
+   }
+};
+
 static struct gpio_led_platform_data sdp4430_led_data = {
.leds   = sdp4430_gpio_leds,
.num_leds   = ARRAY_SIZE(sdp4430_gpio_leds),
 };
 
+static int omap_prox_activate(struct device *dev)
+{
+   gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 1);
+   return 0;
+}
+
+static void omap_prox_deactivate(struct device *dev)
+{
+   gpio_set_value(OMAP4_SFH7741_ENABLE_GPIO , 0);
+}
+
+static struct gpio_keys_platform_data sdp4430_gpio_keys_data = {
+   .buttons= sdp4430_gpio_keys,
+   .nbuttons   = ARRAY_SIZE(sdp4430_gpio_keys),
+   .enable = omap_prox_activate,
+   .disable= omap_prox_deactivate,
+};
+
+static struct platform_device sdp4430_gpio_keys_device = {
+   .name   = "gpio-keys",
+   .id = -1,
+   .dev= {
+   .platform_data  = &sdp4430_gpio_keys_data,
+   },
+};
+
 static struct platform_device sdp4430_leds_gpio = {
.name   = "leds-gpio",
.id = -1,
@@ -161,6 +200,7 @@ static struct platform_device sdp4430_lcd_device = {
 
 static struct platform_device *sdp4430_devices[] __initdata = {
&sdp4430_lcd_device,
+   &sdp4430_gpio_keys_device,
&sdp4430_leds_gpio,
 };
 
@@ -426,6 +466,26 @@ static int __init omap4_i2c_init(void)
omap_register_i2c_bus(4, 400, NULL, 0);
return 0;
 }
+
+static void __init omap_sfh7741prox_init(void)
+{
+   int  error;
+
+   error = gpio_request(OMAP4_SFH7741_ENABLE_GPIO, "sfh7741");
+   if (error < 0) {
+   pr_err("%s:failed to request GPIO %d, error %d\n",
+   __func__, OMAP4_SFH7741_ENABLE_GPIO, error);
+   return;
+   }
+
+   error = gpio_direction_output(OMAP4_SFH7741_ENABLE_GPIO , 0);
+   if (error < 0) {
+   pr_err("%s: GPIO configuration failed: GPIO %d,error %d\n",
+__func__, OMAP4_SFH7741_ENABLE_GPIO, error);
+   gpio_free(OMAP4_SFH7741_ENABLE_GPIO);
+   }
+}
+
 static void __init omap_4430sdp_init(void)
 {
int status;
@@ -448,6 +508,7 @@ static void __init omap_4430sdp_init(void)
spi_register_board_info(sdp4430_spi_board_info,
ARRAY_SIZE(sdp4430_spi_board_info));
}
+   omap_sfh7741prox_init();
 }
 
 static void __init omap_4430sdp_map_io(void)
-- 
1.7.0.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 03/13] I2C: OMAP: Remove reset at init

2012-06-18 Thread Shubhrajyoti D
The reset in the driver at init is not needed anymore as the
following patch has removed the HWMOD_INIT_NO_RESET flag.
6d3c55f [OMAP: hwmod: fix the i2c-reset timeout during bootup]

This patch does the following
-removes the reset from the probe and implements a omap_i2c_reset
 function to reset.
- Reset is removed from omap_i2c_init, which was called
 not only during probe, but also after time out and error handling.
 omap_i2c_reset is added in those places to effect the reset.

Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   38 +++---
 1 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 838a0ae..5da91b5 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -269,15 +269,9 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev 
*i2c_dev, int reg)
(i2c_dev->regs[reg] << i2c_dev->reg_shift));
 }
 
-static int omap_i2c_init(struct omap_i2c_dev *dev)
+static int omap_i2c_reset(struct omap_i2c_dev *dev)
 {
-   u16 psc = 0, scll = 0, sclh = 0, buf = 0;
-   u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
-   unsigned long fclk_rate = 1200;
unsigned long timeout;
-   unsigned long internal_clk = 0;
-   struct clk *fclk;
-
if (dev->rev >= OMAP_I2C_OMAP1_REV_2) {
/* Disable I2C controller before soft reset */
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG,
@@ -315,16 +309,18 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
 
omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG,
dev->syscstate);
-   /*
-* Enabling all wakup sources to stop I2C freezing on
-* WFI instruction.
-* REVISIT: Some wkup sources might not be needed.
-*/
-   dev->westate = OMAP_I2C_WE_ALL;
-   omap_i2c_write_reg(dev, OMAP_I2C_WE_REG,
-   dev->westate);
}
}
+}
+
+static int omap_i2c_init(struct omap_i2c_dev *dev)
+{
+   u16 psc = 0, scll = 0, sclh = 0, buf = 0;
+   u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0;
+   unsigned long fclk_rate = 1200;
+   unsigned long internal_clk = 0;
+   struct clk *fclk;
+
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
 
if (dev->flags & OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) {
@@ -433,6 +429,16 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
OMAP_I2C_IE_AL)  | ((dev->fifo_size) ?
(OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0);
omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
+   if (dev->rev >= OMAP_I2C_REV_ON_3430_3530) {
+   /*
+* Enabling all wakup sources to stop I2C freezing on
+* WFI instruction.
+* REVISIT: Some wkup sources might not be needed.
+*/
+   dev->westate = OMAP_I2C_WE_ALL;
+   omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
+   }
+
if (dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
dev->pscstate = psc;
dev->scllstate = scll;
@@ -541,6 +547,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
dev->buf_len = 0;
if (timeout == 0) {
dev_err(dev->dev, "controller timed out\n");
+   omap_i2c_reset(dev);
omap_i2c_init(dev);
return -ETIMEDOUT;
}
@@ -551,6 +558,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
/* We have an error */
if (dev->cmd_err & (OMAP_I2C_STAT_AL | OMAP_I2C_STAT_ROVR |
OMAP_I2C_STAT_XUDF)) {
+   omap_i2c_reset(dev);
omap_i2c_init(dev);
return -EIO;
}
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 04/13] I2C: OMAP: Recover from Bus Busy condition

2012-06-18 Thread Shubhrajyoti D
From: Vikram Pandita 

In case a peripheral is driving SDA bus low (ie. a start condition), provide
a constant clock output using the test mode of the OMAP I2C controller to
try and clear the bus. Soft reset I2C controller after attempting the bus clear
to ensure that controller is in a good state.

Based upon Vikram Pandita's patch from TI Android 3.0.
I acknowledge the contributions and suggestions of Jon and Hemant.

A couple differences from the original patch ...
1. Add a new function for bus clear
2. Ensure that the CON.I2C_EN bit is set when using the SYSTEST feature to
   output a permanent clock. This bit needs to be set and typically it would
   be set by the unidle function but this is not the case for all OMAP
   generations.
3. Program the SYSTEST setting only the bits we care about. However, restore
   SYSTEST registers to there original state as some OMAP generations do not
   implement perform a soft-reset.
4. Clear the CON register after performing the bus clear, so when we call the
   init function the controller is disabled and the init function will
   re-enable later.

Original patch can be found here:
http://git.omapzoom.org/?p=kernel/omap.git;a=commit;h=a2ab04192ba25e60f95ba1ff3af5601a2d7b5bd1

Signed-off-by: Vikram Pandita 
Signed-off-by: Jon Hunter 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   33 ++---
 1 files changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 5da91b5..7ab9fe1 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -148,16 +148,15 @@ enum {
 #define OMAP_I2C_SCLH_HSSCLH   8
 
 /* I2C System Test Register (OMAP_I2C_SYSTEST): */
-#ifdef DEBUG
 #define OMAP_I2C_SYSTEST_ST_EN (1 << 15)   /* System test enable */
 #define OMAP_I2C_SYSTEST_FREE  (1 << 14)   /* Free running mode */
 #define OMAP_I2C_SYSTEST_TMODE_MASK(3 << 12)   /* Test mode select */
-#define OMAP_I2C_SYSTEST_TMODE_SHIFT   (12)/* Test mode select */
+#define OMAP_I2C_SYSTEST_TMODE_TEST(2 << 12)   /* Test mode select */
+#define OMAP_I2C_SYSTEST_TMODE_LOOP(3 << 12)   /* Test mode select */
 #define OMAP_I2C_SYSTEST_SCL_I (1 << 3)/* SCL line sense in */
 #define OMAP_I2C_SYSTEST_SCL_O (1 << 2)/* SCL line drive out */
 #define OMAP_I2C_SYSTEST_SDA_I (1 << 1)/* SDA line sense in */
 #define OMAP_I2C_SYSTEST_SDA_O (1 << 0)/* SDA line drive out */
-#endif
 
 /* OCP_SYSCONFIG bit definitions */
 #define SYSC_CLOCKACTIVITY_MASK(0x3 << 8)
@@ -311,6 +310,7 @@ static int omap_i2c_reset(struct omap_i2c_dev *dev)
dev->syscstate);
}
}
+   return 0;
 }
 
 static int omap_i2c_init(struct omap_i2c_dev *dev)
@@ -468,6 +468,31 @@ static int omap_i2c_wait_for_bb(struct omap_i2c_dev *dev)
 }
 
 /*
+ * Bus Clear
+ */
+static int omap_i2c_bus_clear(struct omap_i2c_dev *dev)
+{
+   u16 w;
+
+   /*
+* Per the I2C specification, if we are stuck in a bus busy state
+* we can attempt a bus clear to try and recover the bus by sending
+* at least 9 clock pulses on SCL. Put the I2C in a test mode so it
+* will output a continuous clock on SCL.
+*/
+   w = omap_i2c_read_reg(dev, OMAP_I2C_SYSTEST_REG);
+   omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+   omap_i2c_write_reg(dev, OMAP_I2C_SYSTEST_REG, (OMAP_I2C_SYSTEST_ST_EN
+  | OMAP_I2C_SYSTEST_TMODE_TEST));
+   msleep(1);
+   omap_i2c_write_reg(dev, OMAP_I2C_SYSTEST_REG, w);
+   omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
+   omap_i2c_reset(dev);
+   omap_i2c_init(dev);
+   return omap_i2c_wait_for_bb(dev);
+}
+
+/*
  * Low level master read/write transaction.
  */
 static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
@@ -594,6 +619,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg 
msgs[], int num)
 
r = omap_i2c_wait_for_bb(dev);
if (r < 0)
+   r = omap_i2c_bus_clear(dev);
+   if (r < 0)
goto out;
 
if (dev->set_mpu_wkup_lat != NULL)
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 02/13] I2C: OMAP: Remove the definition of SYSS_RESETDONE_MASK

2012-06-18 Thread Shubhrajyoti D
Remove the definition of SYSS_RESETDONE_MASK and use the
one in omap_hwmod.h.

Also fixes the warning
 CC  drivers/i2c/busses/i2c-omap.o
drivers/i2c/busses/i2c-omap.c:163: warning: "SYSS_RESETDONE_MASK" redefined

Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 9a54e88..838a0ae 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -159,9 +159,6 @@ enum {
 #define OMAP_I2C_SYSTEST_SDA_O (1 << 0)/* SDA line drive out */
 #endif
 
-/* OCP_SYSSTATUS bit definitions */
-#define SYSS_RESETDONE_MASK(1 << 0)
-
 /* OCP_SYSCONFIG bit definitions */
 #define SYSC_CLOCKACTIVITY_MASK(0x3 << 8)
 #define SYSC_SIDLEMODE_MASK(0x3 << 3)
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 07/13] I2C: OMAP: use devm_* functions

2012-06-18 Thread Shubhrajyoti D
The various devm_* functions allocate memory that is released when a driver
detaches. This patch uses devm_kzalloc, devm_request_and_ioremap for data
that is allocated in the probe function of a platform device and is only
freed in the remove function.

Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   33 +
 1 files changed, 9 insertions(+), 24 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 5c3a299..326b99c 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -975,7 +975,7 @@ omap_i2c_probe(struct platform_device *pdev)
 {
struct omap_i2c_dev *dev;
struct i2c_adapter  *adap;
-   struct resource *mem, *irq, *ioarea;
+   struct resource *mem, *irq;
struct omap_i2c_bus_platform_data *pdata = pdev->dev.platform_data;
struct device_node  *node = pdev->dev.of_node;
const struct of_device_id *match;
@@ -994,17 +994,16 @@ omap_i2c_probe(struct platform_device *pdev)
return -ENODEV;
}
 
-   ioarea = request_mem_region(mem->start, resource_size(mem),
-   pdev->name);
-   if (!ioarea) {
-   dev_err(&pdev->dev, "I2C region already claimed\n");
-   return -EBUSY;
+   dev = devm_kzalloc(&pdev->dev, sizeof(struct omap_i2c_dev), GFP_KERNEL);
+   if (!dev) {
+   dev_err(&pdev->dev, "Menory allocation failed\n");
+   return -ENOMEM;
}
 
-   dev = kzalloc(sizeof(struct omap_i2c_dev), GFP_KERNEL);
-   if (!dev) {
-   r = -ENOMEM;
-   goto err_release_region;
+   dev->base = devm_request_and_ioremap(&pdev->dev, mem);
+   if (!dev->base) {
+   dev_err(&pdev->dev, "I2C region already claimed\n");
+   return -ENOMEM;
}
 
match = of_match_device(of_match_ptr(omap_i2c_of_match), &pdev->dev);
@@ -1028,11 +1027,6 @@ omap_i2c_probe(struct platform_device *pdev)
 
dev->dev = &pdev->dev;
dev->irq = irq->start;
-   dev->base = ioremap(mem->start, resource_size(mem));
-   if (!dev->base) {
-   r = -ENOMEM;
-   goto err_free_mem;
-   }
 
platform_set_drvdata(pdev, dev);
 
@@ -1127,13 +1121,9 @@ err_free_irq:
 err_unuse_clocks:
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
pm_runtime_put(dev->dev);
-   iounmap(dev->base);
pm_runtime_disable(&pdev->dev);
 err_free_mem:
platform_set_drvdata(pdev, NULL);
-   kfree(dev);
-err_release_region:
-   release_mem_region(mem->start, resource_size(mem));
 
return r;
 }
@@ -1141,7 +1131,6 @@ err_release_region:
 static int __devexit omap_i2c_remove(struct platform_device *pdev)
 {
struct omap_i2c_dev *dev = platform_get_drvdata(pdev);
-   struct resource *mem;
int ret;
 
platform_set_drvdata(pdev, NULL);
@@ -1155,10 +1144,6 @@ static int __devexit omap_i2c_remove(struct 
platform_device *pdev)
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
-   iounmap(dev->base);
-   kfree(dev);
-   mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   release_mem_region(mem->start, resource_size(mem));
return 0;
 }
 
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 12/13] I2C: OMAP: add blank lines

2012-06-18 Thread Shubhrajyoti D
From: Felipe Balbi 

trivial patch to aid readability. No functional
changes.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 0e0ab8f..6a79089 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -818,6 +818,7 @@ complete:
dev_err(dev->dev, "Arbitration lost\n");
err |= OMAP_I2C_STAT_AL;
}
+
/*
 * ProDB0017052: Clear ARDY bit twice
 */
@@ -830,6 +831,7 @@ complete:
omap_i2c_complete_cmd(dev, err);
return IRQ_HANDLED;
}
+
if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) {
u8 num_bytes = 1;
 
@@ -876,6 +878,7 @@ complete:
stat & (OMAP_I2C_STAT_RRDY | 
OMAP_I2C_STAT_RDR));
continue;
}
+
if (stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)) {
u8 num_bytes = 1;
if (dev->fifo_size) {
@@ -923,10 +926,12 @@ complete:
stat & (OMAP_I2C_STAT_XRDY | 
OMAP_I2C_STAT_XDR));
continue;
}
+
if (stat & OMAP_I2C_STAT_ROVR) {
dev_err(dev->dev, "Receive overrun\n");
dev->cmd_err |= OMAP_I2C_STAT_ROVR;
}
+
if (stat & OMAP_I2C_STAT_XUDF) {
dev_err(dev->dev, "Transmit underflow\n");
dev->cmd_err |= OMAP_I2C_STAT_XUDF;
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 00/13] I2C cleanups

2012-06-18 Thread Shubhrajyoti D

The patch series does the following

- I2C register restore only if context if the context is lost
- Bus busy recovery mechanism.
- the reset is not done in init.
- Adds a patch to use devm_* functions
- Adds a pdata function pointer to do context save restore
- Split the omap_i2c_isr to increase readability
- Make the i2c use SET_RUNTIME_PM_OPS
- Use INIT_COMPLETION instead of init_completion
- Dropping a cleanup and taking few patchs Felipe's series as it may
 not be needed.

This applies on Wolfram's i2c-embedded/for-next branch.
 
Functional testing on omap4sdp and omap3sdp. 

Previous discurssions 
http://www.spinics.net/lists/linux-i2c/msg07748.html

This series mainly is the cleanups rebased on
i2c-embedded/for-next branch.


The following changes since commit 0f009a914b40be8786fa67b1f4345cacc263b48c:

  i2c: tegra: make all resource allocation through devm_* (2012-06-13 16:01:38 
+0200)

are available in the git repository at:
  git://gitorious.org/linus-tree/linus-tree.git for_next/i2c_omap

Felipe Balbi (4):
  I2C: OMAP: simplify num_bytes handling
  I2C: OMAP: decrease indentation level on data handling
  I2C: OMAP: add blank lines
  I2C: OMAP: simplify omap_i2c_ack_stat()

Jon Hunter (1):
  I2C: OMAP: Correct I2C revision for OMAP3

Shubhrajyoti D (7):
  I2C: OMAP: I2C register restore only if context is lost
  I2C: OMAP: Remove the definition of SYSS_RESETDONE_MASK
  I2C: OMAP: Remove reset at init
  I2C: OMAP: Optimise the remove code
  I2C: OMAP: use devm_* functions
  I2C: OMAP: Use SET_RUNTIME_PM_OPS
  I2C: OMAP: Do not initialise the completion everytime

Vikram Pandita (1):
  I2C: OMAP: Recover from Bus Busy condition

 arch/arm/plat-omap/i2c.c  |3 +
 drivers/i2c/busses/i2c-omap.c |  261 +++-
 include/linux/i2c-omap.h  |1 +
 3 files changed, 154 insertions(+), 111 deletions(-)
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 01/13] I2C: OMAP: I2C register restore only if context is lost

2012-06-18 Thread Shubhrajyoti D
 Currently i2c register restore is done always.
 Adding conditional restore.
 The i2c register restore is done only if the context is lost
 or in case of error to be on the safe side.

Cc: Kevin Hilman 
Signed-off-by: Shubhrajyoti D 
---
 arch/arm/plat-omap/i2c.c  |3 +++
 drivers/i2c/busses/i2c-omap.c |   35 ++-
 include/linux/i2c-omap.h  |1 +
 3 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index db071bc..4ccab07 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -179,6 +179,9 @@ static inline int omap2_i2c_add_bus(int bus_id)
 */
if (cpu_is_omap34xx())
pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
+
+   pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
+
pdev = omap_device_build(name, bus_id, oh, pdata,
sizeof(struct omap_i2c_bus_platform_data),
NULL, 0, 0);
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 9895fa7..9a54e88 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -43,6 +43,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* I2C controller revisions */
 #define OMAP_I2C_OMAP1_REV_2   0x20
@@ -185,6 +186,7 @@ struct omap_i2c_dev {
u32 latency;/* maximum mpu wkup latency */
void(*set_mpu_wkup_lat)(struct device *dev,
long latency);
+   int (*get_context_loss_count)(struct device *dev);
u32 speed;  /* Speed of bus in kHz */
u32 dtrev;  /* extra revision from DT */
u32 flags;
@@ -207,6 +209,7 @@ struct omap_i2c_dev {
u16 syscstate;
u16 westate;
u16 errata;
+   int dev_lost_count;
 };
 
 static const u8 reg_map_ip_v1[] = {
@@ -987,6 +990,7 @@ omap_i2c_probe(struct platform_device *pdev)
dev->speed = pdata->clkrate;
dev->flags = pdata->flags;
dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
+   dev->get_context_loss_count = pdata->get_context_loss_count;
dev->dtrev = pdata->rev;
}
 
@@ -1128,12 +1132,26 @@ omap_i2c_remove(struct platform_device *pdev)
 }
 
 #ifdef CONFIG_PM_RUNTIME
+static void omap_i2c_restore(struct omap_i2c_dev *dev)
+{
+   omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
+   omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
+   omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
+   omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
+   omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->bufstate);
+   omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
+   omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+
+}
 static int omap_i2c_runtime_suspend(struct device *dev)
 {
struct platform_device *pdev = to_platform_device(dev);
struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
u16 iv;
 
+   if (_dev->get_context_loss_count)
+   _dev->dev_lost_count = _dev->get_context_loss_count(dev);
+
_dev->iestate = omap_i2c_read_reg(_dev, OMAP_I2C_IE_REG);
 
omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, 0);
@@ -1154,16 +1172,15 @@ static int omap_i2c_runtime_resume(struct device *dev)
 {
struct platform_device *pdev = to_platform_device(dev);
struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
+   int loss_cnt;
+
+   if (!(_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE))
+   return 0;
 
-   if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
-   omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
-   omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
-   omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
-   omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
-   omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
-   omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
-   omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
-   omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+   if (_dev->get_context_loss_count) {
+   loss_cnt = _dev->get_context_loss_count(dev);
+   if (_dev->dev_lost_count != loss_cnt)
+   omap_i2c_restore(_dev);
}
 
/*
diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h
index 92a0dc7..c76cbc0 100644
--- a/include/linux/i2c

[PATCHv8 06/13] I2C: OMAP: Correct I2C revision for OMAP3

2012-06-18 Thread Shubhrajyoti D
From: Jon Hunter 

The OMAP3530 is based upon the same silicon as the OMAP3430 and so the I2C
revision is the same for 3430 and 3530. However, the OMAP3630 device has the
same I2C revision as OMAP4. Correct the revision definition to reflect this.

This patch is based on work done by Jon Hunter 
Changes from his patch
- Update OMAP_I2C_REV_ON_3430 also to reflect that it is same as 3530

Signed-off-by: Jon Hunter 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   10 +-
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 691550a..5c3a299 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -50,8 +50,8 @@
 
 /* I2C controller revisions present on specific hardware */
 #define OMAP_I2C_REV_ON_2430   0x36
-#define OMAP_I2C_REV_ON_3430   0x3C
-#define OMAP_I2C_REV_ON_3530_4430  0x40
+#define OMAP_I2C_REV_ON_3430_3530  0x3C
+#define OMAP_I2C_REV_ON_3630_4430  0x40
 
 /* timeout waiting for the controller to respond */
 #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))
@@ -298,7 +298,7 @@ static int omap_i2c_reset(struct omap_i2c_dev *dev)
omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG,
   SYSC_AUTOIDLE_MASK);
 
-   } else if (dev->rev >= OMAP_I2C_REV_ON_3430) {
+   } else if (dev->rev >= OMAP_I2C_REV_ON_3430_3530) {
dev->syscstate = SYSC_AUTOIDLE_MASK;
dev->syscstate |= SYSC_ENAWAKEUP_MASK;
dev->syscstate |= (SYSC_IDLEMODE_SMART <<
@@ -1055,7 +1055,7 @@ omap_i2c_probe(struct platform_device *pdev)
if (dev->flags & OMAP_I2C_FLAG_APPLY_ERRATA_I207)
dev->errata |= I2C_OMAP_ERRATA_I207;
 
-   if (dev->rev <= OMAP_I2C_REV_ON_3430)
+   if (dev->rev <= OMAP_I2C_REV_ON_3430_3530)
dev->errata |= I2C_OMAP_ERRATA_I462;
 
if (!(dev->flags & OMAP_I2C_FLAG_NO_FIFO)) {
@@ -1073,7 +1073,7 @@ omap_i2c_probe(struct platform_device *pdev)
 
dev->fifo_size = (dev->fifo_size / 2);
 
-   if (dev->rev >= OMAP_I2C_REV_ON_3530_4430)
+   if (dev->rev >= OMAP_I2C_REV_ON_3630_4430)
dev->b_hw = 0; /* Disable hardware fixes */
else
dev->b_hw = 1; /* Enable hardware fixes */
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 13/13] I2C: OMAP: simplify omap_i2c_ack_stat()

2012-06-18 Thread Shubhrajyoti D
From: Felipe Balbi 

stat & BIT(1) is the same as BIT(1), so let's
simplify things a bit by removing "stat &" from
all omap_i2c_ack_stat() calls.

Signed-off-by: Felipe Balbi 
Reviewed-by : Santosh Shilimkar 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   19 ++-
 1 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 6a79089..bac6305 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -763,7 +763,7 @@ static int errata_omap3_i462(struct omap_i2c_dev *dev, u16 
*stat, int *err)
 
while (--timeout && !(*stat & OMAP_I2C_STAT_XUDF)) {
if (*stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
-   omap_i2c_ack_stat(dev, *stat & (OMAP_I2C_STAT_XRDY |
+   omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
OMAP_I2C_STAT_XDR));
return -ETIMEDOUT;
}
@@ -824,10 +824,11 @@ complete:
 */
if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK |
OMAP_I2C_STAT_AL)) {
-   omap_i2c_ack_stat(dev, stat &
-   (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
-   OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR |
-   OMAP_I2C_STAT_ARDY));
+   omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY |
+   OMAP_I2C_STAT_RDR |
+   OMAP_I2C_STAT_XRDY |
+   OMAP_I2C_STAT_XDR |
+   OMAP_I2C_STAT_ARDY));
omap_i2c_complete_cmd(dev, err);
return IRQ_HANDLED;
}
@@ -874,8 +875,8 @@ complete:
}
}
}
-   omap_i2c_ack_stat(dev,
-   stat & (OMAP_I2C_STAT_RRDY | 
OMAP_I2C_STAT_RDR));
+   omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY |
+   OMAP_I2C_STAT_RDR));
continue;
}
 
@@ -922,8 +923,8 @@ complete:
 
omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
}
-   omap_i2c_ack_stat(dev,
-   stat & (OMAP_I2C_STAT_XRDY | 
OMAP_I2C_STAT_XDR));
+   omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
+   OMAP_I2C_STAT_XDR));
continue;
}
 
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 11/13] I2C: OMAP: decrease indentation level on data handling

2012-06-18 Thread Shubhrajyoti D
From: Felipe Balbi 

trivial patch, no functional changes.

Signed-off-by: Felipe Balbi 
Reviewed-by : Santosh Shilimkar 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   63 -
 1 files changed, 31 insertions(+), 32 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 080193a..0e0ab8f 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -845,22 +845,7 @@ complete:
>> 8) & 0x3F;
}
while (num_bytes--) {
-   w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
-   if (dev->buf_len) {
-   *dev->buf++ = w;
-   dev->buf_len--;
-   /*
-* Data reg in 2430, omap3 and
-* omap4 is 8 bit wide
-*/
-   if (dev->flags &
-OMAP_I2C_FLAG_16BIT_DATA_REG) {
-   if (dev->buf_len) {
-   *dev->buf++ = w >> 8;
-   dev->buf_len--;
-   }
-   }
-   } else {
+   if (!dev->buf_len) {
if (stat & OMAP_I2C_STAT_RRDY)
dev_err(dev->dev,
"RRDY IRQ while no data"
@@ -871,6 +856,21 @@ complete:
" requested\n");
break;
}
+
+   w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
+   *dev->buf++ = w;
+   dev->buf_len--;
+   /*
+* Data reg in 2430, omap3 and
+* omap4 is 8 bit wide
+*/
+   if (dev->flags &
+   OMAP_I2C_FLAG_16BIT_DATA_REG) {
+   if (dev->buf_len) {
+   *dev->buf++ = w >> 8;
+   dev->buf_len--;
+   }
+   }
}
omap_i2c_ack_stat(dev,
stat & (OMAP_I2C_STAT_RRDY | 
OMAP_I2C_STAT_RDR));
@@ -887,22 +887,7 @@ complete:
& 0x3F;
}
while (num_bytes--) {
-   w = 0;
-   if (dev->buf_len) {
-   w = *dev->buf++;
-   dev->buf_len--;
-   /*
-* Data reg in 2430, omap3 and
-* omap4 is 8 bit wide
-*/
-   if (dev->flags &
-OMAP_I2C_FLAG_16BIT_DATA_REG) {
-   if (dev->buf_len) {
-   w |= *dev->buf++ << 8;
-   dev->buf_len--;
-   }
-   }
-   } else {
+   if (!dev->buf_len) {
if (stat & OMAP_I2C_STAT_XRDY)
dev_err(dev->dev,
"XRDY IRQ while no "
@@ -914,6 +899,20 @@ complete:
break;
}
 
+   w = *dev->buf++;
+   dev->buf_len--;
+   /*
+* Data reg in 2430, omap3 and
+* omap4 is 8 bit wide
+*/
+   if (dev->flags &
+ 

[PATCHv8 08/13] I2C: OMAP: Use SET_RUNTIME_PM_OPS

2012-06-18 Thread Shubhrajyoti D
Use SET_RUNTIME_PM_OPS macro to set runtime functions.

Acked-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |8 +---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 326b99c..6f8e7d9 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1147,6 +1147,7 @@ static int __devexit omap_i2c_remove(struct 
platform_device *pdev)
return 0;
 }
 
+#ifdef CONFIG_PM
 #ifdef CONFIG_PM_RUNTIME
 static void omap_i2c_restore(struct omap_i2c_dev *dev)
 {
@@ -1208,15 +1209,16 @@ static int omap_i2c_runtime_resume(struct device *dev)
 
return 0;
 }
+#endif /* CONFIG_PM_RUNTIME */
 
 static struct dev_pm_ops omap_i2c_pm_ops = {
-   .runtime_suspend = omap_i2c_runtime_suspend,
-   .runtime_resume = omap_i2c_runtime_resume,
+   SET_RUNTIME_PM_OPS(omap_i2c_runtime_suspend,
+  omap_i2c_runtime_resume, NULL)
 };
 #define OMAP_I2C_PM_OPS (&omap_i2c_pm_ops)
 #else
 #define OMAP_I2C_PM_OPS NULL
-#endif
+#endif /* CONFIG_PM */
 
 static struct platform_driver omap_i2c_driver = {
.probe  = omap_i2c_probe,
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 10/13] I2C: OMAP: simplify num_bytes handling

2012-06-18 Thread Shubhrajyoti D
From: Felipe Balbi 

trivial patch, no functional changes

Signed-off-by: Felipe Balbi 
Reviewed-by : Santosh Shilimkar 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |6 ++
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index e24eb1f..080193a 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -844,8 +844,7 @@ complete:
OMAP_I2C_BUFSTAT_REG)
>> 8) & 0x3F;
}
-   while (num_bytes) {
-   num_bytes--;
+   while (num_bytes--) {
w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
if (dev->buf_len) {
*dev->buf++ = w;
@@ -887,8 +886,7 @@ complete:
OMAP_I2C_BUFSTAT_REG)
& 0x3F;
}
-   while (num_bytes) {
-   num_bytes--;
+   while (num_bytes--) {
w = 0;
if (dev->buf_len) {
w = *dev->buf++;
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 05/13] I2C: OMAP: Optimise the remove code

2012-06-18 Thread Shubhrajyoti D
The omap_i2c_remove function may not be needed after
device exit so the memory could be freed.

Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 7ab9fe1..691550a 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1138,8 +1138,7 @@ err_release_region:
return r;
 }
 
-static int
-omap_i2c_remove(struct platform_device *pdev)
+static int __devexit omap_i2c_remove(struct platform_device *pdev)
 {
struct omap_i2c_dev *dev = platform_get_drvdata(pdev);
struct resource *mem;
@@ -1236,7 +1235,7 @@ static struct dev_pm_ops omap_i2c_pm_ops = {
 
 static struct platform_driver omap_i2c_driver = {
.probe  = omap_i2c_probe,
-   .remove = omap_i2c_remove,
+   .remove = __devexit_p(omap_i2c_remove),
.driver = {
.name   = "omap_i2c",
.owner  = THIS_MODULE,
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv8 09/13] I2C: OMAP: Do not initialise the completion everytime

2012-06-18 Thread Shubhrajyoti D
Use INIT_COMPLETION instead of init_completion in transfer.

Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 6f8e7d9..e24eb1f 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -521,7 +521,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
w |= OMAP_I2C_BUF_RXFIF_CLR | OMAP_I2C_BUF_TXFIF_CLR;
omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, w);
 
-   init_completion(&dev->cmd_complete);
+   INIT_COMPLETION(dev->cmd_complete);
dev->cmd_err = 0;
 
w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT;
@@ -1029,6 +1029,7 @@ omap_i2c_probe(struct platform_device *pdev)
dev->irq = irq->start;
 
platform_set_drvdata(pdev, dev);
+   init_completion(&dev->cmd_complete);
 
dev->reg_shift = (dev->flags >> OMAP_I2C_FLAG_BUS_SHIFT__SHIFT) & 3;
 
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 5/8] I2C: OMAP: Do not initialise the completion everytime

2012-06-21 Thread Shubhrajyoti D
Use INIT_COMPLETION instead of init_completion in transfer.

Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index ccb2fc4..2a50094 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -493,7 +493,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
w |= OMAP_I2C_BUF_RXFIF_CLR | OMAP_I2C_BUF_TXFIF_CLR;
omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, w);
 
-   init_completion(&dev->cmd_complete);
+   INIT_COMPLETION(dev->cmd_complete);
dev->cmd_err = 0;
 
w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT;
@@ -997,6 +997,7 @@ omap_i2c_probe(struct platform_device *pdev)
dev->irq = irq->start;
 
platform_set_drvdata(pdev, dev);
+   init_completion(&dev->cmd_complete);
 
dev->reg_shift = (dev->flags >> OMAP_I2C_FLAG_BUS_SHIFT__SHIFT) & 3;
 
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 6/8] I2C: OMAP: Remove the definition of SYSS_RESETDONE_MASK

2012-06-21 Thread Shubhrajyoti D
Remove the definition of SYSS_RESETDONE_MASK and use the
one in omap_hwmod.h.

Also fixes the warning
 CC  drivers/i2c/busses/i2c-omap.o
drivers/i2c/busses/i2c-omap.c:163: warning: "SYSS_RESETDONE_MASK" redefined

Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 2a50094..cbf7ecd 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -159,9 +159,6 @@ enum {
 #define OMAP_I2C_SYSTEST_SDA_O (1 << 0)/* SDA line drive out */
 #endif
 
-/* OCP_SYSSTATUS bit definitions */
-#define SYSS_RESETDONE_MASK(1 << 0)
-
 /* OCP_SYSCONFIG bit definitions */
 #define SYSC_CLOCKACTIVITY_MASK(0x3 << 8)
 #define SYSC_SIDLEMODE_MASK(0x3 << 3)
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 4/8] I2C: OMAP: Use SET_RUNTIME_PM_OPS

2012-06-21 Thread Shubhrajyoti D
Use SET_RUNTIME_PM_OPS macro to set runtime functions.

Acked-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |8 +---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 328a022..ccb2fc4 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1115,6 +1115,7 @@ static int __devexit omap_i2c_remove(struct 
platform_device *pdev)
return 0;
 }
 
+#ifdef CONFIG_PM
 #ifdef CONFIG_PM_RUNTIME
 static void omap_i2c_restore(struct omap_i2c_dev *dev)
 {
@@ -1176,15 +1177,16 @@ static int omap_i2c_runtime_resume(struct device *dev)
 
return 0;
 }
+#endif /* CONFIG_PM_RUNTIME */
 
 static struct dev_pm_ops omap_i2c_pm_ops = {
-   .runtime_suspend = omap_i2c_runtime_suspend,
-   .runtime_resume = omap_i2c_runtime_resume,
+   SET_RUNTIME_PM_OPS(omap_i2c_runtime_suspend,
+  omap_i2c_runtime_resume, NULL)
 };
 #define OMAP_I2C_PM_OPS (&omap_i2c_pm_ops)
 #else
 #define OMAP_I2C_PM_OPS NULL
-#endif
+#endif /* CONFIG_PM */
 
 static struct platform_driver omap_i2c_driver = {
.probe  = omap_i2c_probe,
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 7/8] I2C: OMAP: Correct I2C revision for OMAP3

2012-06-21 Thread Shubhrajyoti D
From: Jon Hunter 

The OMAP3530 is based upon the same silicon as the OMAP3430 and so the I2C
revision is the same for 3430 and 3530. However, the OMAP3630 device has the
same I2C revision as OMAP4. Correct the revision definition to reflect this.

This patch is based on work done by Jon Hunter 
Changes from his patch
- Update OMAP_I2C_REV_ON_3430 also to reflect that it is same as 3530

Signed-off-by: Jon Hunter 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   10 +-
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index cbf7ecd..a492d93 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -50,8 +50,8 @@
 
 /* I2C controller revisions present on specific hardware */
 #define OMAP_I2C_REV_ON_2430   0x36
-#define OMAP_I2C_REV_ON_3430   0x3C
-#define OMAP_I2C_REV_ON_3530_4430  0x40
+#define OMAP_I2C_REV_ON_3430_3530  0x3C
+#define OMAP_I2C_REV_ON_3630_4430  0x40
 
 /* timeout waiting for the controller to respond */
 #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))
@@ -305,7 +305,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG,
   SYSC_AUTOIDLE_MASK);
 
-   } else if (dev->rev >= OMAP_I2C_REV_ON_3430) {
+   } else if (dev->rev >= OMAP_I2C_REV_ON_3430_3530) {
dev->syscstate = SYSC_AUTOIDLE_MASK;
dev->syscstate |= SYSC_ENAWAKEUP_MASK;
dev->syscstate |= (SYSC_IDLEMODE_SMART <<
@@ -1015,7 +1015,7 @@ omap_i2c_probe(struct platform_device *pdev)
if (dev->flags & OMAP_I2C_FLAG_APPLY_ERRATA_I207)
dev->errata |= I2C_OMAP_ERRATA_I207;
 
-   if (dev->rev <= OMAP_I2C_REV_ON_3430)
+   if (dev->rev <= OMAP_I2C_REV_ON_3430_3530)
dev->errata |= I2C_OMAP_ERRATA_I462;
 
if (!(dev->flags & OMAP_I2C_FLAG_NO_FIFO)) {
@@ -1033,7 +1033,7 @@ omap_i2c_probe(struct platform_device *pdev)
 
dev->fifo_size = (dev->fifo_size / 2);
 
-   if (dev->rev >= OMAP_I2C_REV_ON_3530_4430)
+   if (dev->rev >= OMAP_I2C_REV_ON_3630_4430)
dev->b_hw = 0; /* Disable hardware fixes */
else
dev->b_hw = 1; /* Enable hardware fixes */
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 3/8] I2C: OMAP: use devm_* functions

2012-06-21 Thread Shubhrajyoti D
The various devm_* functions allocate memory that is released when a driver
detaches. This patch uses devm_kzalloc, devm_request_and_ioremap for data
that is allocated in the probe function of a platform device and is only
freed in the remove function.

Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   33 +
 1 files changed, 9 insertions(+), 24 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index d704f64..328a022 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -943,7 +943,7 @@ omap_i2c_probe(struct platform_device *pdev)
 {
struct omap_i2c_dev *dev;
struct i2c_adapter  *adap;
-   struct resource *mem, *irq, *ioarea;
+   struct resource *mem, *irq;
struct omap_i2c_bus_platform_data *pdata = pdev->dev.platform_data;
struct device_node  *node = pdev->dev.of_node;
const struct of_device_id *match;
@@ -962,17 +962,16 @@ omap_i2c_probe(struct platform_device *pdev)
return -ENODEV;
}
 
-   ioarea = request_mem_region(mem->start, resource_size(mem),
-   pdev->name);
-   if (!ioarea) {
-   dev_err(&pdev->dev, "I2C region already claimed\n");
-   return -EBUSY;
+   dev = devm_kzalloc(&pdev->dev, sizeof(struct omap_i2c_dev), GFP_KERNEL);
+   if (!dev) {
+   dev_err(&pdev->dev, "Menory allocation failed\n");
+   return -ENOMEM;
}
 
-   dev = kzalloc(sizeof(struct omap_i2c_dev), GFP_KERNEL);
-   if (!dev) {
-   r = -ENOMEM;
-   goto err_release_region;
+   dev->base = devm_request_and_ioremap(&pdev->dev, mem);
+   if (!dev->base) {
+   dev_err(&pdev->dev, "I2C region already claimed\n");
+   return -ENOMEM;
}
 
match = of_match_device(of_match_ptr(omap_i2c_of_match), &pdev->dev);
@@ -996,11 +995,6 @@ omap_i2c_probe(struct platform_device *pdev)
 
dev->dev = &pdev->dev;
dev->irq = irq->start;
-   dev->base = ioremap(mem->start, resource_size(mem));
-   if (!dev->base) {
-   r = -ENOMEM;
-   goto err_free_mem;
-   }
 
platform_set_drvdata(pdev, dev);
 
@@ -1095,13 +1089,9 @@ err_free_irq:
 err_unuse_clocks:
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
pm_runtime_put(dev->dev);
-   iounmap(dev->base);
pm_runtime_disable(&pdev->dev);
 err_free_mem:
platform_set_drvdata(pdev, NULL);
-   kfree(dev);
-err_release_region:
-   release_mem_region(mem->start, resource_size(mem));
 
return r;
 }
@@ -1109,7 +1099,6 @@ err_release_region:
 static int __devexit omap_i2c_remove(struct platform_device *pdev)
 {
struct omap_i2c_dev *dev = platform_get_drvdata(pdev);
-   struct resource *mem;
int ret;
 
platform_set_drvdata(pdev, NULL);
@@ -1123,10 +1112,6 @@ static int __devexit omap_i2c_remove(struct 
platform_device *pdev)
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
-   iounmap(dev->base);
-   kfree(dev);
-   mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   release_mem_region(mem->start, resource_size(mem));
return 0;
 }
 
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 0/8] I2C cleanups

2012-06-21 Thread Shubhrajyoti D
The patch series does the following

- I2C register restore only if context if the context is lost
- Bus busy recovery mechanism.
- Adds a patch to use devm_* functions
- Adds a pdata function pointer to do context save restore
- Split the omap_i2c_isr to increase readability
- Make the i2c use SET_RUNTIME_PM_OPS
- Use INIT_COMPLETION instead of init_completion
- the reset patch is dropped will try to rework it as per the 
 review comments recieved.

This applies on Wolfram's i2c-embedded/for-next branch.

Functional testing on omap4430 , 4460 panda and omap3sdp.

Previous discurssions
http://www.spinics.net/lists/linux-i2c/msg07748.html

This series mainly is the cleanups rebased on
i2c-embedded/for-next branch.


The following changes since commit 0f009a914b40be8786fa67b1f4345cacc263b48c:

  i2c: tegra: make all resource allocation through devm_* (2012-06-13 16:01:38 
+0200)

are available in the git repository at:
  git://gitorious.org/linus-tree/linus-tree.git for_next/i2c_minimal_cleanup

Jon Hunter (1):
  I2C: OMAP: Correct I2C revision for OMAP3

Shubhrajyoti D (6):
  I2C: OMAP: I2C register restore only if context is lost
  I2C: OMAP: Optimise the remove code
  I2C: OMAP: use devm_* functions
  I2C: OMAP: Use SET_RUNTIME_PM_OPS
  I2C: OMAP: Do not initialise the completion everytime
  I2C: OMAP: Remove the definition of SYSS_RESETDONE_MASK

Vikram Pandita (1):
  I2C: OMAP: Recover from Bus Busy condition

 arch/arm/plat-omap/i2c.c  |3 +
 drivers/i2c/busses/i2c-omap.c |  128 
 include/linux/i2c-omap.h  |1 +
 3 files changed, 81 insertions(+), 51 deletions(-)

-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 1/8] I2C: OMAP: I2C register restore only if context is lost

2012-06-21 Thread Shubhrajyoti D
 Currently i2c register restore is done always.
 Adding conditional restore.
 The i2c register restore is done only if the context is lost
 or in case of error to be on the safe side.

Cc: Kevin Hilman 
Signed-off-by: Shubhrajyoti D 
---
 arch/arm/plat-omap/i2c.c  |3 +++
 drivers/i2c/busses/i2c-omap.c |   35 ++-
 include/linux/i2c-omap.h  |1 +
 3 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index db071bc..4ccab07 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -179,6 +179,9 @@ static inline int omap2_i2c_add_bus(int bus_id)
 */
if (cpu_is_omap34xx())
pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
+
+   pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
+
pdev = omap_device_build(name, bus_id, oh, pdata,
sizeof(struct omap_i2c_bus_platform_data),
NULL, 0, 0);
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 9895fa7..9a54e88 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -43,6 +43,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* I2C controller revisions */
 #define OMAP_I2C_OMAP1_REV_2   0x20
@@ -185,6 +186,7 @@ struct omap_i2c_dev {
u32 latency;/* maximum mpu wkup latency */
void(*set_mpu_wkup_lat)(struct device *dev,
long latency);
+   int (*get_context_loss_count)(struct device *dev);
u32 speed;  /* Speed of bus in kHz */
u32 dtrev;  /* extra revision from DT */
u32 flags;
@@ -207,6 +209,7 @@ struct omap_i2c_dev {
u16 syscstate;
u16 westate;
u16 errata;
+   int dev_lost_count;
 };
 
 static const u8 reg_map_ip_v1[] = {
@@ -987,6 +990,7 @@ omap_i2c_probe(struct platform_device *pdev)
dev->speed = pdata->clkrate;
dev->flags = pdata->flags;
dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
+   dev->get_context_loss_count = pdata->get_context_loss_count;
dev->dtrev = pdata->rev;
}
 
@@ -1128,12 +1132,26 @@ omap_i2c_remove(struct platform_device *pdev)
 }
 
 #ifdef CONFIG_PM_RUNTIME
+static void omap_i2c_restore(struct omap_i2c_dev *dev)
+{
+   omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
+   omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
+   omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
+   omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
+   omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->bufstate);
+   omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
+   omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+
+}
 static int omap_i2c_runtime_suspend(struct device *dev)
 {
struct platform_device *pdev = to_platform_device(dev);
struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
u16 iv;
 
+   if (_dev->get_context_loss_count)
+   _dev->dev_lost_count = _dev->get_context_loss_count(dev);
+
_dev->iestate = omap_i2c_read_reg(_dev, OMAP_I2C_IE_REG);
 
omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, 0);
@@ -1154,16 +1172,15 @@ static int omap_i2c_runtime_resume(struct device *dev)
 {
struct platform_device *pdev = to_platform_device(dev);
struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
+   int loss_cnt;
+
+   if (!(_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE))
+   return 0;
 
-   if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
-   omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
-   omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
-   omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
-   omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
-   omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
-   omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
-   omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
-   omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+   if (_dev->get_context_loss_count) {
+   loss_cnt = _dev->get_context_loss_count(dev);
+   if (_dev->dev_lost_count != loss_cnt)
+   omap_i2c_restore(_dev);
}
 
/*
diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h
index 92a0dc7..c76cbc0 100644
--- a/include/linux/i2c

[PATCHv9 2/8] I2C: OMAP: Optimise the remove code

2012-06-21 Thread Shubhrajyoti D
The omap_i2c_remove function may not be needed after
device exit so the memory could be freed.

Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 9a54e88..d704f64 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1106,8 +1106,7 @@ err_release_region:
return r;
 }
 
-static int
-omap_i2c_remove(struct platform_device *pdev)
+static int __devexit omap_i2c_remove(struct platform_device *pdev)
 {
struct omap_i2c_dev *dev = platform_get_drvdata(pdev);
struct resource *mem;
@@ -1204,7 +1203,7 @@ static struct dev_pm_ops omap_i2c_pm_ops = {
 
 static struct platform_driver omap_i2c_driver = {
.probe  = omap_i2c_probe,
-   .remove = omap_i2c_remove,
+   .remove = __devexit_p(omap_i2c_remove),
.driver = {
.name   = "omap_i2c",
.owner  = THIS_MODULE,
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 8/8] I2C: OMAP: Recover from Bus Busy condition

2012-06-21 Thread Shubhrajyoti D
From: Vikram Pandita 

In case a peripheral is driving SDA bus low (ie. a start condition), provide
a constant clock output using the test mode of the OMAP I2C controller to
try and clear the bus. Soft reset I2C controller after attempting the bus clear
to ensure that controller is in a good state.

Based upon Vikram Pandita's patch from TI Android 3.0.
I acknowledge the contributions and suggestions of Jon and Hemant.

A couple differences from the original patch ...
1. Add a new function for bus clear
2. Ensure that the CON.I2C_EN bit is set when using the SYSTEST feature to
   output a permanent clock. This bit needs to be set and typically it would
   be set by the unidle function but this is not the case for all OMAP
   generations.
3. Program the SYSTEST setting only the bits we care about. However, restore
   SYSTEST registers to there original state as some OMAP generations do not
   implement perform a soft-reset.
4. Clear the CON register after performing the bus clear, so when we call the
   init function the controller is disabled and the init function will
   re-enable later.

Original patch can be found here:
http://git.omapzoom.org/?p=kernel/omap.git;a=commit;h=a2ab04192ba25e60f95ba1ff3af5601a2d7b5bd1

Signed-off-by: Vikram Pandita 
Signed-off-by: Jon Hunter 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   31 ---
 1 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index a492d93..23c8e78 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -148,16 +148,15 @@ enum {
 #define OMAP_I2C_SCLH_HSSCLH   8
 
 /* I2C System Test Register (OMAP_I2C_SYSTEST): */
-#ifdef DEBUG
 #define OMAP_I2C_SYSTEST_ST_EN (1 << 15)   /* System test enable */
 #define OMAP_I2C_SYSTEST_FREE  (1 << 14)   /* Free running mode */
 #define OMAP_I2C_SYSTEST_TMODE_MASK(3 << 12)   /* Test mode select */
-#define OMAP_I2C_SYSTEST_TMODE_SHIFT   (12)/* Test mode select */
+#define OMAP_I2C_SYSTEST_TMODE_TEST(2 << 12)   /* Test mode select */
+#define OMAP_I2C_SYSTEST_TMODE_LOOP(3 << 12)   /* Test mode select */
 #define OMAP_I2C_SYSTEST_SCL_I (1 << 3)/* SCL line sense in */
 #define OMAP_I2C_SYSTEST_SCL_O (1 << 2)/* SCL line drive out */
 #define OMAP_I2C_SYSTEST_SDA_I (1 << 1)/* SDA line sense in */
 #define OMAP_I2C_SYSTEST_SDA_O (1 << 0)/* SDA line drive out */
-#endif
 
 /* OCP_SYSCONFIG bit definitions */
 #define SYSC_CLOCKACTIVITY_MASK(0x3 << 8)
@@ -460,6 +459,29 @@ static int omap_i2c_wait_for_bb(struct omap_i2c_dev *dev)
 
return 0;
 }
+/*
+ * Bus Clear
+ */
+static int omap_i2c_bus_clear(struct omap_i2c_dev *dev)
+{
+   u16 w;
+
+   /*
+* Per the I2C specification, if we are stuck in a bus busy state
+* we can attempt a bus clear to try and recover the bus by sending
+* at least 9 clock pulses on SCL. Put the I2C in a test mode so it
+* will output a continuous clock on SCL.
+*/
+   w = omap_i2c_read_reg(dev, OMAP_I2C_SYSTEST_REG);
+   omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+   omap_i2c_write_reg(dev, OMAP_I2C_SYSTEST_REG, (OMAP_I2C_SYSTEST_ST_EN
+  | OMAP_I2C_SYSTEST_TMODE_TEST));
+   msleep(1);
+   omap_i2c_write_reg(dev, OMAP_I2C_SYSTEST_REG, w);
+   omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
+   omap_i2c_init(dev);
+   return omap_i2c_wait_for_bb(dev);
+}
 
 /*
  * Low level master read/write transaction.
@@ -586,6 +608,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg 
msgs[], int num)
 
r = omap_i2c_wait_for_bb(dev);
if (r < 0)
+   r = omap_i2c_bus_clear(dev);
+   if (r < 0)
goto out;
 
if (dev->set_mpu_wkup_lat != NULL)
@@ -654,6 +678,7 @@ static inline void i2c_omap_errata_i207(struct omap_i2c_dev 
*dev, u16 stat)
 
}
}
+   return 0;
 }
 
 /* rev1 devices are apparently only on some 15xx */
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 3/7] I2C: OMAP: Use SET_RUNTIME_PM_OPS

2012-06-25 Thread Shubhrajyoti D
Use SET_RUNTIME_PM_OPS macro to set runtime functions.

Acked-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |8 +---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index d704f64..c771c28 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1130,6 +1130,7 @@ static int __devexit omap_i2c_remove(struct 
platform_device *pdev)
return 0;
 }
 
+#ifdef CONFIG_PM
 #ifdef CONFIG_PM_RUNTIME
 static void omap_i2c_restore(struct omap_i2c_dev *dev)
 {
@@ -1191,15 +1192,16 @@ static int omap_i2c_runtime_resume(struct device *dev)
 
return 0;
 }
+#endif /* CONFIG_PM_RUNTIME */
 
 static struct dev_pm_ops omap_i2c_pm_ops = {
-   .runtime_suspend = omap_i2c_runtime_suspend,
-   .runtime_resume = omap_i2c_runtime_resume,
+   SET_RUNTIME_PM_OPS(omap_i2c_runtime_suspend,
+  omap_i2c_runtime_resume, NULL)
 };
 #define OMAP_I2C_PM_OPS (&omap_i2c_pm_ops)
 #else
 #define OMAP_I2C_PM_OPS NULL
-#endif
+#endif /* CONFIG_PM */
 
 static struct platform_driver omap_i2c_driver = {
.probe  = omap_i2c_probe,
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv9 0/7] I2C cleanups

2012-06-25 Thread Shubhrajyoti D
The patch series does the following

- I2C register restore only if context if the context is lost
- Bus busy recovery mechanism.
- Adds a pdata function pointer to do context save restore
- Split the omap_i2c_isr to increase readability
- Make the i2c use SET_RUNTIME_PM_OPS
- Use INIT_COMPLETION instead of init_completion
- the reset patch is dropped will try to rework it as per the 
 review comments recieved.

This applies on Wolfram's i2c-embedded/for-next branch.

Functional testing on omap4430 , 4460 panda and omap3sdp.

Previous discurssions
http://www.spinics.net/lists/linux-i2c/msg07748.html

This series mainly is the cleanups rebased on
i2c-embedded/for-next branch.

Jon Hunter (1):
  I2C: OMAP: Correct I2C revision for OMAP3

Shubhrajyoti D (5):
  I2C: OMAP: I2C register restore only if context is lost
  I2C: OMAP: Optimise the remove code
  I2C: OMAP: Use SET_RUNTIME_PM_OPS
  I2C: OMAP: Do not initialise the completion everytime
  I2C: OMAP: Remove the definition of SYSS_RESETDONE_MASK

Vikram Pandita (1):
  I2C: OMAP: Recover from Bus Busy condition

 arch/arm/plat-omap/i2c.c  |3 +
 drivers/i2c/busses/i2c-omap.c |   95 +
 include/linux/i2c-omap.h  |1 +
 3 files changed, 72 insertions(+), 27 deletions(-)

-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 7/7] I2C: OMAP: Recover from Bus Busy condition

2012-06-25 Thread Shubhrajyoti D
From: Vikram Pandita 

In case a peripheral is driving SDA bus low (ie. a start condition), provide
a constant clock output using the test mode of the OMAP I2C controller to
try and clear the bus. Soft reset I2C controller after attempting the bus clear
to ensure that controller is in a good state.

Based upon Vikram Pandita's patch from TI Android 3.0.
I acknowledge the contributions and suggestions of Jon and Hemant.

A couple differences from the original patch ...
1. Add a new function for bus clear
2. Ensure that the CON.I2C_EN bit is set when using the SYSTEST feature to
   output a permanent clock. This bit needs to be set and typically it would
   be set by the unidle function but this is not the case for all OMAP
   generations.
3. Program the SYSTEST setting only the bits we care about. However, restore
   SYSTEST registers to there original state as some OMAP generations do not
   implement perform a soft-reset.
4. Clear the CON register after performing the bus clear, so when we call the
   init function the controller is disabled and the init function will
   re-enable later.

Original patch can be found here:
http://git.omapzoom.org/?p=kernel/omap.git;a=commit;h=a2ab04192ba25e60f95ba1ff3af5601a2d7b5bd1

Signed-off-by: Vikram Pandita 
Signed-off-by: Jon Hunter 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   31 ---
 1 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 0557b0d..421dcd7 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -148,16 +148,15 @@ enum {
 #define OMAP_I2C_SCLH_HSSCLH   8
 
 /* I2C System Test Register (OMAP_I2C_SYSTEST): */
-#ifdef DEBUG
 #define OMAP_I2C_SYSTEST_ST_EN (1 << 15)   /* System test enable */
 #define OMAP_I2C_SYSTEST_FREE  (1 << 14)   /* Free running mode */
 #define OMAP_I2C_SYSTEST_TMODE_MASK(3 << 12)   /* Test mode select */
-#define OMAP_I2C_SYSTEST_TMODE_SHIFT   (12)/* Test mode select */
+#define OMAP_I2C_SYSTEST_TMODE_TEST(2 << 12)   /* Test mode select */
+#define OMAP_I2C_SYSTEST_TMODE_LOOP(3 << 12)   /* Test mode select */
 #define OMAP_I2C_SYSTEST_SCL_I (1 << 3)/* SCL line sense in */
 #define OMAP_I2C_SYSTEST_SCL_O (1 << 2)/* SCL line drive out */
 #define OMAP_I2C_SYSTEST_SDA_I (1 << 1)/* SDA line sense in */
 #define OMAP_I2C_SYSTEST_SDA_O (1 << 0)/* SDA line drive out */
-#endif
 
 /* OCP_SYSCONFIG bit definitions */
 #define SYSC_CLOCKACTIVITY_MASK(0x3 << 8)
@@ -460,6 +459,29 @@ static int omap_i2c_wait_for_bb(struct omap_i2c_dev *dev)
 
return 0;
 }
+/*
+ * Bus Clear
+ */
+static int omap_i2c_bus_clear(struct omap_i2c_dev *dev)
+{
+   u16 w;
+
+   /*
+* Per the I2C specification, if we are stuck in a bus busy state
+* we can attempt a bus clear to try and recover the bus by sending
+* at least 9 clock pulses on SCL. Put the I2C in a test mode so it
+* will output a continuous clock on SCL.
+*/
+   w = omap_i2c_read_reg(dev, OMAP_I2C_SYSTEST_REG);
+   omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+   omap_i2c_write_reg(dev, OMAP_I2C_SYSTEST_REG, (OMAP_I2C_SYSTEST_ST_EN
+  | OMAP_I2C_SYSTEST_TMODE_TEST));
+   msleep(1);
+   omap_i2c_write_reg(dev, OMAP_I2C_SYSTEST_REG, w);
+   omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
+   omap_i2c_init(dev);
+   return omap_i2c_wait_for_bb(dev);
+}
 
 /*
  * Low level master read/write transaction.
@@ -586,6 +608,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg 
msgs[], int num)
 
r = omap_i2c_wait_for_bb(dev);
if (r < 0)
+   r = omap_i2c_bus_clear(dev);
+   if (r < 0)
goto out;
 
if (dev->set_mpu_wkup_lat != NULL)
@@ -654,6 +678,7 @@ static inline void i2c_omap_errata_i207(struct omap_i2c_dev 
*dev, u16 stat)
 
}
}
+   return 0;
 }
 
 /* rev1 devices are apparently only on some 15xx */
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 6/7] I2C: OMAP: Correct I2C revision for OMAP3

2012-06-25 Thread Shubhrajyoti D
From: Jon Hunter 

The OMAP3530 is based upon the same silicon as the OMAP3430 and so the I2C
revision is the same for 3430 and 3530. However, the OMAP3630 device has the
same I2C revision as OMAP4. Correct the revision definition to reflect this.

This patch is based on work done by Jon Hunter 
Changes from his patch
- Update OMAP_I2C_REV_ON_3430 also to reflect that it is same as 3530

Signed-off-by: Jon Hunter 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   10 +-
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 8344ad030..0557b0d 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -50,8 +50,8 @@
 
 /* I2C controller revisions present on specific hardware */
 #define OMAP_I2C_REV_ON_2430   0x36
-#define OMAP_I2C_REV_ON_3430   0x3C
-#define OMAP_I2C_REV_ON_3530_4430  0x40
+#define OMAP_I2C_REV_ON_3430_3530  0x3C
+#define OMAP_I2C_REV_ON_3630_4430  0x40
 
 /* timeout waiting for the controller to respond */
 #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))
@@ -305,7 +305,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG,
   SYSC_AUTOIDLE_MASK);
 
-   } else if (dev->rev >= OMAP_I2C_REV_ON_3430) {
+   } else if (dev->rev >= OMAP_I2C_REV_ON_3430_3530) {
dev->syscstate = SYSC_AUTOIDLE_MASK;
dev->syscstate |= SYSC_ENAWAKEUP_MASK;
dev->syscstate |= (SYSC_IDLEMODE_SMART <<
@@ -1021,7 +1021,7 @@ omap_i2c_probe(struct platform_device *pdev)
if (dev->flags & OMAP_I2C_FLAG_APPLY_ERRATA_I207)
dev->errata |= I2C_OMAP_ERRATA_I207;
 
-   if (dev->rev <= OMAP_I2C_REV_ON_3430)
+   if (dev->rev <= OMAP_I2C_REV_ON_3430_3530)
dev->errata |= I2C_OMAP_ERRATA_I462;
 
if (!(dev->flags & OMAP_I2C_FLAG_NO_FIFO)) {
@@ -1039,7 +1039,7 @@ omap_i2c_probe(struct platform_device *pdev)
 
dev->fifo_size = (dev->fifo_size / 2);
 
-   if (dev->rev >= OMAP_I2C_REV_ON_3530_4430)
+   if (dev->rev >= OMAP_I2C_REV_ON_3630_4430)
dev->b_hw = 0; /* Disable hardware fixes */
else
dev->b_hw = 1; /* Enable hardware fixes */
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 1/7] I2C: OMAP: I2C register restore only if context is lost

2012-06-25 Thread Shubhrajyoti D
 Currently i2c register restore is done always.
 Adding conditional restore.
 The i2c register restore is done only if the context is lost
 or in case of error to be on the safe side.

Cc: Kevin Hilman 
Signed-off-by: Shubhrajyoti D 
---
 arch/arm/plat-omap/i2c.c  |3 +++
 drivers/i2c/busses/i2c-omap.c |   35 ++-
 include/linux/i2c-omap.h  |1 +
 3 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index db071bc..4ccab07 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -179,6 +179,9 @@ static inline int omap2_i2c_add_bus(int bus_id)
 */
if (cpu_is_omap34xx())
pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
+
+   pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
+
pdev = omap_device_build(name, bus_id, oh, pdata,
sizeof(struct omap_i2c_bus_platform_data),
NULL, 0, 0);
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 9895fa7..9a54e88 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -43,6 +43,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* I2C controller revisions */
 #define OMAP_I2C_OMAP1_REV_2   0x20
@@ -185,6 +186,7 @@ struct omap_i2c_dev {
u32 latency;/* maximum mpu wkup latency */
void(*set_mpu_wkup_lat)(struct device *dev,
long latency);
+   int (*get_context_loss_count)(struct device *dev);
u32 speed;  /* Speed of bus in kHz */
u32 dtrev;  /* extra revision from DT */
u32 flags;
@@ -207,6 +209,7 @@ struct omap_i2c_dev {
u16 syscstate;
u16 westate;
u16 errata;
+   int dev_lost_count;
 };
 
 static const u8 reg_map_ip_v1[] = {
@@ -987,6 +990,7 @@ omap_i2c_probe(struct platform_device *pdev)
dev->speed = pdata->clkrate;
dev->flags = pdata->flags;
dev->set_mpu_wkup_lat = pdata->set_mpu_wkup_lat;
+   dev->get_context_loss_count = pdata->get_context_loss_count;
dev->dtrev = pdata->rev;
}
 
@@ -1128,12 +1132,26 @@ omap_i2c_remove(struct platform_device *pdev)
 }
 
 #ifdef CONFIG_PM_RUNTIME
+static void omap_i2c_restore(struct omap_i2c_dev *dev)
+{
+   omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
+   omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate);
+   omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev->scllstate);
+   omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev->sclhstate);
+   omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, dev->bufstate);
+   omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
+   omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+
+}
 static int omap_i2c_runtime_suspend(struct device *dev)
 {
struct platform_device *pdev = to_platform_device(dev);
struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
u16 iv;
 
+   if (_dev->get_context_loss_count)
+   _dev->dev_lost_count = _dev->get_context_loss_count(dev);
+
_dev->iestate = omap_i2c_read_reg(_dev, OMAP_I2C_IE_REG);
 
omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, 0);
@@ -1154,16 +1172,15 @@ static int omap_i2c_runtime_resume(struct device *dev)
 {
struct platform_device *pdev = to_platform_device(dev);
struct omap_i2c_dev *_dev = platform_get_drvdata(pdev);
+   int loss_cnt;
+
+   if (!(_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE))
+   return 0;
 
-   if (_dev->flags & OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) {
-   omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0);
-   omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev->pscstate);
-   omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev->scllstate);
-   omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev->sclhstate);
-   omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev->bufstate);
-   omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev->syscstate);
-   omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev->westate);
-   omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+   if (_dev->get_context_loss_count) {
+   loss_cnt = _dev->get_context_loss_count(dev);
+   if (_dev->dev_lost_count != loss_cnt)
+   omap_i2c_restore(_dev);
}
 
/*
diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h
index 92a0dc7..c76cbc0 100644
--- a/include/linux/i2c

[PATCHv10 5/7] I2C: OMAP: Remove the definition of SYSS_RESETDONE_MASK

2012-06-25 Thread Shubhrajyoti D
Remove the definition of SYSS_RESETDONE_MASK and use the
one in omap_hwmod.h.

Also fixes the warning
 CC  drivers/i2c/busses/i2c-omap.o
drivers/i2c/busses/i2c-omap.c:163: warning: "SYSS_RESETDONE_MASK" redefined

Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index f1109f4..8344ad030 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -159,9 +159,6 @@ enum {
 #define OMAP_I2C_SYSTEST_SDA_O (1 << 0)/* SDA line drive out */
 #endif
 
-/* OCP_SYSSTATUS bit definitions */
-#define SYSS_RESETDONE_MASK(1 << 0)
-
 /* OCP_SYSCONFIG bit definitions */
 #define SYSC_CLOCKACTIVITY_MASK(0x3 << 8)
 #define SYSC_SIDLEMODE_MASK(0x3 << 3)
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 2/7] I2C: OMAP: Optimise the remove code

2012-06-25 Thread Shubhrajyoti D
The omap_i2c_remove function may not be needed after
device exit so the memory could be freed.

Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 9a54e88..d704f64 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1106,8 +1106,7 @@ err_release_region:
return r;
 }
 
-static int
-omap_i2c_remove(struct platform_device *pdev)
+static int __devexit omap_i2c_remove(struct platform_device *pdev)
 {
struct omap_i2c_dev *dev = platform_get_drvdata(pdev);
struct resource *mem;
@@ -1204,7 +1203,7 @@ static struct dev_pm_ops omap_i2c_pm_ops = {
 
 static struct platform_driver omap_i2c_driver = {
.probe  = omap_i2c_probe,
-   .remove = omap_i2c_remove,
+   .remove = __devexit_p(omap_i2c_remove),
.driver = {
.name   = "omap_i2c",
.owner  = THIS_MODULE,
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv10 4/7] I2C: OMAP: Do not initialise the completion everytime

2012-06-25 Thread Shubhrajyoti D
Use INIT_COMPLETION instead of init_completion in transfer.

Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index c771c28..f1109f4 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -493,7 +493,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
w |= OMAP_I2C_BUF_RXFIF_CLR | OMAP_I2C_BUF_TXFIF_CLR;
omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, w);
 
-   init_completion(&dev->cmd_complete);
+   INIT_COMPLETION(dev->cmd_complete);
dev->cmd_err = 0;
 
w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT;
@@ -1003,6 +1003,7 @@ omap_i2c_probe(struct platform_device *pdev)
}
 
platform_set_drvdata(pdev, dev);
+   init_completion(&dev->cmd_complete);
 
dev->reg_shift = (dev->flags >> OMAP_I2C_FLAG_BUS_SHIFT__SHIFT) & 3;
 
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv11 6/6] i2c: omap: Recover from Bus Busy condition

2012-06-28 Thread Shubhrajyoti D
From: Vikram Pandita 

In case a peripheral is driving SDA bus low (ie. a start condition), provide
a constant clock output using the test mode of the OMAP I2C controller to
try and clear the bus. Soft reset I2C controller after attempting the bus clear
to ensure that controller is in a good state.

Based upon Vikram Pandita's patch from TI Android 3.0.
I acknowledge the contributions and suggestions of Jon and Hemant.

A couple differences from the original patch ...
1. Add a new function for bus clear
2. Ensure that the CON.I2C_EN bit is set when using the SYSTEST feature to
   output a permanent clock. This bit needs to be set and typically it would
   be set by the unidle function but this is not the case for all OMAP
   generations.
3. Program the SYSTEST setting only the bits we care about. However, restore
   SYSTEST registers to there original state as some OMAP generations do not
   implement perform a soft-reset.
4. Clear the CON register after performing the bus clear, so when we call the
   init function the controller is disabled and the init function will
   re-enable later.

Original patch can be found here:
http://git.omapzoom.org/?p=kernel/omap.git;a=commit;h=a2ab04192ba25e60f95ba1ff3af5601a2d7b5bd1

Signed-off-by: Vikram Pandita 
Signed-off-by: Jon Hunter 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   30 +++---
 1 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 5058dfc..2500f19 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -148,16 +148,15 @@ enum {
 #define OMAP_I2C_SCLH_HSSCLH   8
 
 /* I2C System Test Register (OMAP_I2C_SYSTEST): */
-#ifdef DEBUG
 #define OMAP_I2C_SYSTEST_ST_EN (1 << 15)   /* System test enable */
 #define OMAP_I2C_SYSTEST_FREE  (1 << 14)   /* Free running mode */
 #define OMAP_I2C_SYSTEST_TMODE_MASK(3 << 12)   /* Test mode select */
-#define OMAP_I2C_SYSTEST_TMODE_SHIFT   (12)/* Test mode select */
+#define OMAP_I2C_SYSTEST_TMODE_TEST(2 << 12)   /* Test mode select */
+#define OMAP_I2C_SYSTEST_TMODE_LOOP(3 << 12)   /* Test mode select */
 #define OMAP_I2C_SYSTEST_SCL_I (1 << 3)/* SCL line sense in */
 #define OMAP_I2C_SYSTEST_SCL_O (1 << 2)/* SCL line drive out */
 #define OMAP_I2C_SYSTEST_SDA_I (1 << 1)/* SDA line sense in */
 #define OMAP_I2C_SYSTEST_SDA_O (1 << 0)/* SDA line drive out */
-#endif
 
 /* OCP_SYSCONFIG bit definitions */
 #define SYSC_CLOCKACTIVITY_MASK(0x3 << 8)
@@ -458,6 +457,29 @@ static int omap_i2c_wait_for_bb(struct omap_i2c_dev *dev)
 
return 0;
 }
+/*
+ * Bus Clear
+ */
+static int omap_i2c_bus_clear(struct omap_i2c_dev *dev)
+{
+   u16 w;
+
+   /*
+* Per the I2C specification, if we are stuck in a bus busy state
+* we can attempt a bus clear to try and recover the bus by sending
+* at least 9 clock pulses on SCL. Put the I2C in a test mode so it
+* will output a continuous clock on SCL.
+*/
+   w = omap_i2c_read_reg(dev, OMAP_I2C_SYSTEST_REG);
+   omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
+   omap_i2c_write_reg(dev, OMAP_I2C_SYSTEST_REG, (OMAP_I2C_SYSTEST_ST_EN
+  | OMAP_I2C_SYSTEST_TMODE_TEST));
+   msleep(1);
+   omap_i2c_write_reg(dev, OMAP_I2C_SYSTEST_REG, w);
+   omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
+   omap_i2c_init(dev);
+   return omap_i2c_wait_for_bb(dev);
+}
 
 /*
  * Low level master read/write transaction.
@@ -584,6 +606,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg 
msgs[], int num)
 
r = omap_i2c_wait_for_bb(dev);
if (r < 0)
+   r = omap_i2c_bus_clear(dev);
+   if (r < 0)
goto out;
 
if (dev->set_mpu_wkup_lat != NULL)
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv11 0/6] I2C cleanups

2012-06-28 Thread Shubhrajyoti D
This is a minimal cleanup series.

The patch series does the following

- Bus busy recovery mechanism.
- Make the i2c use SET_RUNTIME_PM_OPS
- Use INIT_COMPLETION instead of init_completion
- the reset patch is dropped will try to rework it as per the 
 review comments recieved.


This applies on Wolfram's i2c-embedded/for-next branch.

Functional testing on omap4430 , 4460 panda and omap3sdp.
 

The following changes since commit 0f009a914b40be8786fa67b1f4345cacc263b48c:

  i2c: tegra: make all resource allocation through devm_* (2012-06-13 16:01:38 
+0200)

are available in the git repository at:
  git://gitorious.org/linus-tree/linus-tree.git for_next/omap/minimal_cleanup

Jon Hunter (1):
  i2c: omap: Correct I2C revision for OMAP3

Shubhrajyoti D (4):
  i2c: omap: Optimise the remove code
  i2c: omap: Use SET_RUNTIME_PM_OPS
  i2c: omap: Do not initialise the completion everytime
  i2c: omap: Remove the definition of SYSS_RESETDONE_MASK

Vikram Pandita (1):
  i2c: omap: Recover from Bus Busy condition

 drivers/i2c/busses/i2c-omap.c |   60 
 1 files changed, 42 insertions(+), 18 deletions(-)

-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv11 1/6] i2c: omap: Optimise the remove code

2012-06-28 Thread Shubhrajyoti D
The omap_i2c_remove function may not be needed after
device exit so the memory could be freed.

Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 9895fa7..b086076 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1102,8 +1102,7 @@ err_release_region:
return r;
 }
 
-static int
-omap_i2c_remove(struct platform_device *pdev)
+static int __devexit omap_i2c_remove(struct platform_device *pdev)
 {
struct omap_i2c_dev *dev = platform_get_drvdata(pdev);
struct resource *mem;
@@ -1187,7 +1186,7 @@ static struct dev_pm_ops omap_i2c_pm_ops = {
 
 static struct platform_driver omap_i2c_driver = {
.probe  = omap_i2c_probe,
-   .remove = omap_i2c_remove,
+   .remove = __devexit_p(omap_i2c_remove),
.driver = {
.name   = "omap_i2c",
.owner  = THIS_MODULE,
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv11 5/6] i2c: omap: Correct I2C revision for OMAP3

2012-06-28 Thread Shubhrajyoti D
From: Jon Hunter 

The OMAP3530 is based upon the same silicon as the OMAP3430 and so the I2C
revision is the same for 3430 and 3530. However, the OMAP3630 device has the
same I2C revision as OMAP4. Correct the revision definition to reflect this.

This patch is based on work done by Jon Hunter 
Changes from his patch
- Update OMAP_I2C_REV_ON_3430 also to reflect that it is same as 3530

Reviewed-by: Felipe Balbi 
Signed-off-by: Jon Hunter 
Signed-off-by: Shubhrajyoti D 
---
- Add Felipe's Reviewed by tag

 drivers/i2c/busses/i2c-omap.c |   10 +-
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 4bbf288..5058dfc 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -50,8 +50,8 @@
 
 /* I2C controller revisions present on specific hardware */
 #define OMAP_I2C_REV_ON_2430   0x36
-#define OMAP_I2C_REV_ON_3430   0x3C
-#define OMAP_I2C_REV_ON_3530_4430  0x40
+#define OMAP_I2C_REV_ON_3430_3530  0x3C
+#define OMAP_I2C_REV_ON_3630_4430  0x40
 
 /* timeout waiting for the controller to respond */
 #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))
@@ -303,7 +303,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG,
   SYSC_AUTOIDLE_MASK);
 
-   } else if (dev->rev >= OMAP_I2C_REV_ON_3430) {
+   } else if (dev->rev >= OMAP_I2C_REV_ON_3430_3530) {
dev->syscstate = SYSC_AUTOIDLE_MASK;
dev->syscstate |= SYSC_ENAWAKEUP_MASK;
dev->syscstate |= (SYSC_IDLEMODE_SMART <<
@@ -1018,7 +1018,7 @@ omap_i2c_probe(struct platform_device *pdev)
if (dev->flags & OMAP_I2C_FLAG_APPLY_ERRATA_I207)
dev->errata |= I2C_OMAP_ERRATA_I207;
 
-   if (dev->rev <= OMAP_I2C_REV_ON_3430)
+   if (dev->rev <= OMAP_I2C_REV_ON_3430_3530)
dev->errata |= I2C_OMAP_ERRATA_I462;
 
if (!(dev->flags & OMAP_I2C_FLAG_NO_FIFO)) {
@@ -1036,7 +1036,7 @@ omap_i2c_probe(struct platform_device *pdev)
 
dev->fifo_size = (dev->fifo_size / 2);
 
-   if (dev->rev >= OMAP_I2C_REV_ON_3530_4430)
+   if (dev->rev >= OMAP_I2C_REV_ON_3630_4430)
dev->b_hw = 0; /* Disable hardware fixes */
else
dev->b_hw = 1; /* Enable hardware fixes */
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv11 3/6] i2c: omap: Do not initialise the completion everytime

2012-06-28 Thread Shubhrajyoti D
Use INIT_COMPLETION instead of init_completion in transfer.

Reviewed-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
- Add Felipe's reviewed-by tag

 drivers/i2c/busses/i2c-omap.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index b9915bb..6d05f18 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -490,7 +490,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
w |= OMAP_I2C_BUF_RXFIF_CLR | OMAP_I2C_BUF_TXFIF_CLR;
omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, w);
 
-   init_completion(&dev->cmd_complete);
+   INIT_COMPLETION(dev->cmd_complete);
dev->cmd_err = 0;
 
w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT;
@@ -999,6 +999,7 @@ omap_i2c_probe(struct platform_device *pdev)
}
 
platform_set_drvdata(pdev, dev);
+   init_completion(&dev->cmd_complete);
 
dev->reg_shift = (dev->flags >> OMAP_I2C_FLAG_BUS_SHIFT__SHIFT) & 3;
 
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv11 2/6] i2c: omap: Use SET_RUNTIME_PM_OPS

2012-06-28 Thread Shubhrajyoti D
Use SET_RUNTIME_PM_OPS macro to set runtime functions.

Acked-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |8 +---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index b086076..b9915bb 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1126,6 +1126,7 @@ static int __devexit omap_i2c_remove(struct 
platform_device *pdev)
return 0;
 }
 
+#ifdef CONFIG_PM
 #ifdef CONFIG_PM_RUNTIME
 static int omap_i2c_runtime_suspend(struct device *dev)
 {
@@ -1174,15 +1175,16 @@ static int omap_i2c_runtime_resume(struct device *dev)
 
return 0;
 }
+#endif /* CONFIG_PM_RUNTIME */
 
 static struct dev_pm_ops omap_i2c_pm_ops = {
-   .runtime_suspend = omap_i2c_runtime_suspend,
-   .runtime_resume = omap_i2c_runtime_resume,
+   SET_RUNTIME_PM_OPS(omap_i2c_runtime_suspend,
+  omap_i2c_runtime_resume, NULL)
 };
 #define OMAP_I2C_PM_OPS (&omap_i2c_pm_ops)
 #else
 #define OMAP_I2C_PM_OPS NULL
-#endif
+#endif /* CONFIG_PM */
 
 static struct platform_driver omap_i2c_driver = {
.probe  = omap_i2c_probe,
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv11 4/6] i2c: omap: Remove the definition of SYSS_RESETDONE_MASK

2012-06-28 Thread Shubhrajyoti D
Remove the definition of SYSS_RESETDONE_MASK and use the
one in omap_hwmod.h.

Reviewed-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
- Add Felipe's reviewed by tag

 drivers/i2c/busses/i2c-omap.c |4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 6d05f18..4bbf288 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -43,6 +43,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* I2C controller revisions */
 #define OMAP_I2C_OMAP1_REV_2   0x20
@@ -158,9 +159,6 @@ enum {
 #define OMAP_I2C_SYSTEST_SDA_O (1 << 0)/* SDA line drive out */
 #endif
 
-/* OCP_SYSSTATUS bit definitions */
-#define SYSS_RESETDONE_MASK(1 << 0)
-
 /* OCP_SYSCONFIG bit definitions */
 #define SYSC_CLOCKACTIVITY_MASK(0x3 << 8)
 #define SYSC_SIDLEMODE_MASK(0x3 << 3)
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] I2C: OMAP: fix runtime PM get/put balance on error

2012-06-29 Thread Shubhrajyoti D
ensure pm_runtime_put() is called, on pm_runtime_get_sync()
failure.

Without this, after a failed call, the runtime PM usecount will have
been incremented, but not decremented causing the usecount to never
reach zero after a failure. Thanks to Kevin for educating about it. 
While at it also fix a missing pm_runtime_disable in the probe error
path.

Cc: Kevin Hilman 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |7 +++
 1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 2500f19..c8e5c76 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1113,10 +1113,10 @@ err_free_irq:
free_irq(dev->irq, dev);
 err_unuse_clocks:
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
+err_free_mem:
pm_runtime_put(dev->dev);
iounmap(dev->base);
pm_runtime_disable(&pdev->dev);
-err_free_mem:
platform_set_drvdata(pdev, NULL);
kfree(dev);
 err_release_region:
@@ -1136,10 +1136,9 @@ static int __devexit omap_i2c_remove(struct 
platform_device *pdev)
free_irq(dev->irq, dev);
i2c_del_adapter(&dev->adapter);
ret = pm_runtime_get_sync(&pdev->dev);
-   if (IS_ERR_VALUE(ret))
-   return ret;
+   if (!IS_ERR_VALUE(ret))
+   omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
 
-   omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
iounmap(dev->base);
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 02/17] i2c: omap: simplify num_bytes handling

2012-06-29 Thread Shubhrajyoti D
From: Felipe Balbi 

trivial patch, no functional changes

If the fifo is disabled or fifo_size is 0 the num_bytes
is set to 1. Else it is set to fifo_size or in case of a
draining interrupt the remaining bytes in the buff stat.
So the zero check is redundant and can be safely optimised.

Signed-off-by: Felipe Balbi 
Reviewed-by : Santosh Shilimkar 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |6 ++
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 7ad4efd..1df2bc9 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -831,8 +831,7 @@ complete:
OMAP_I2C_BUFSTAT_REG)
>> 8) & 0x3F;
}
-   while (num_bytes) {
-   num_bytes--;
+   while (num_bytes--) {
w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
if (dev->buf_len) {
*dev->buf++ = w;
@@ -874,8 +873,7 @@ complete:
OMAP_I2C_BUFSTAT_REG)
& 0x3F;
}
-   while (num_bytes) {
-   num_bytes--;
+   while (num_bytes--) {
w = 0;
if (dev->buf_len) {
w = *dev->buf++;
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 10/17] i2c: omap: ack IRQ in parts

2012-06-29 Thread Shubhrajyoti D
From: Felipe Balbi 

According to flow diagrams on OMAP TRMs,
we should ACK the IRQ as they happen.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   28 
 1 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index e4b83af..6e4c2be 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -869,21 +869,19 @@ omap_i2c_isr(int this_irq, void *dev_id)
}
 
 complete:
-   /*
-* Ack the stat in one go, but [R/X]DR and [R/X]RDY should be
-* acked after the data operation is complete.
-* Ref: TRM SWPU114Q Figure 18-31
-*/
-   omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat &
-   ~(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
-   OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
-
-   if (stat & OMAP_I2C_STAT_NACK)
+   if (stat & OMAP_I2C_STAT_NACK) {
err |= OMAP_I2C_STAT_NACK;
+   omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
+   omap_i2c_complete_cmd(dev, err);
+   return IRQ_HANDLED;
+   }
 
if (stat & OMAP_I2C_STAT_AL) {
dev_err(dev->dev, "Arbitration lost\n");
err |= OMAP_I2C_STAT_AL;
+   omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
+   omap_i2c_complete_cmd(dev, err);
+   return IRQ_HANDLED;
}
 
/*
@@ -964,12 +962,18 @@ complete:
 
if (stat & OMAP_I2C_STAT_ROVR) {
dev_err(dev->dev, "Receive overrun\n");
-   dev->cmd_err |= OMAP_I2C_STAT_ROVR;
+   err |= OMAP_I2C_STAT_ROVR;
+   omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ROVR);
+   omap_i2c_complete_cmd(dev, err);
+   return IRQ_HANDLED;
}
 
if (stat & OMAP_I2C_STAT_XUDF) {
dev_err(dev->dev, "Transmit underflow\n");
-   dev->cmd_err |= OMAP_I2C_STAT_XUDF;
+   err |= OMAP_I2C_STAT_XUDF;
+   omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XUDF);
+   omap_i2c_complete_cmd(dev, err);
+   return IRQ_HANDLED;
}
} while (stat);
 
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 17/17] i2c: omap: get rid of the "complete" label

2012-06-29 Thread Shubhrajyoti D
From: Felipe Balbi 

we can ack stat and complete the command from
the errata handling itself.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   16 +---
 1 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index ac3bdae..bd8d282 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -794,6 +794,17 @@ static int errata_omap3_i462(struct omap_i2c_dev *dev)
if (stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
OMAP_I2C_STAT_XDR));
+   if (stat & OMAP_I2C_STAT_NACK) {
+   dev->cmd_err |= OMAP_I2C_STAT_NACK;
+   omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
+   }
+
+   if (stat & OMAP_I2C_STAT_AL) {
+   dev_err(dev->dev, "Arbitration lost\n");
+   dev->cmd_err |= OMAP_I2C_STAT_AL;
+   omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
+   }
+
return -EIO;
}
 
@@ -895,7 +906,6 @@ omap_i2c_isr(int this_irq, void *dev_id)
goto out;
}
 
-complete:
if (stat & OMAP_I2C_STAT_NACK) {
err |= OMAP_I2C_STAT_NACK;
omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
@@ -962,7 +972,7 @@ complete:
ret = omap_i2c_transmit_data(dev, num_bytes, true);
stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
if (ret < 0)
-   goto complete;
+   goto out;
 
omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XDR);
continue;
@@ -978,7 +988,7 @@ complete:
ret = omap_i2c_transmit_data(dev, num_bytes, false);
stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
if (ret < 0)
-   goto complete;
+   goto out;
 
omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XRDY);
continue;
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 15/17] i2c: omap: simplify IRQ exit path

2012-06-29 Thread Shubhrajyoti D
From: Felipe Balbi 

instead of having multiple return points, use
a goto statement to make that clearer.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   20 
 1 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 2cd3b9a..1196417 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -873,24 +873,21 @@ omap_i2c_isr(int this_irq, void *dev_id)
dev_dbg(dev->dev, "IRQ (ISR = 0x%04x)\n", stat);
if (count++ == 100) {
dev_warn(dev->dev, "Too much work in one IRQ\n");
-   omap_i2c_complete_cmd(dev, err);
-   return IRQ_HANDLED;
+   goto out;
}
 
 complete:
if (stat & OMAP_I2C_STAT_NACK) {
err |= OMAP_I2C_STAT_NACK;
omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
-   omap_i2c_complete_cmd(dev, err);
-   return IRQ_HANDLED;
+   goto out;
}
 
if (stat & OMAP_I2C_STAT_AL) {
dev_err(dev->dev, "Arbitration lost\n");
err |= OMAP_I2C_STAT_AL;
omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
-   omap_i2c_complete_cmd(dev, err);
-   return IRQ_HANDLED;
+   goto out;
}
 
/*
@@ -903,8 +900,7 @@ complete:
OMAP_I2C_STAT_XRDY |
OMAP_I2C_STAT_XDR |
OMAP_I2C_STAT_ARDY));
-   omap_i2c_complete_cmd(dev, err);
-   return IRQ_HANDLED;
+   goto out;
}
 
if (stat & OMAP_I2C_STAT_RDR) {
@@ -973,19 +969,19 @@ complete:
dev_err(dev->dev, "Receive overrun\n");
err |= OMAP_I2C_STAT_ROVR;
omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ROVR);
-   omap_i2c_complete_cmd(dev, err);
-   return IRQ_HANDLED;
+   goto out;
}
 
if (stat & OMAP_I2C_STAT_XUDF) {
dev_err(dev->dev, "Transmit underflow\n");
err |= OMAP_I2C_STAT_XUDF;
omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XUDF);
-   omap_i2c_complete_cmd(dev, err);
-   return IRQ_HANDLED;
+   goto out;
}
} while (stat);
 
+out:
+   omap_i2c_complete_cmd(dev, err);
return IRQ_HANDLED;
 }
 
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 05/17] i2c: omap: simplify omap_i2c_ack_stat()

2012-06-29 Thread Shubhrajyoti D
From: Felipe Balbi 

stat & BIT(1) is the same as BIT(1), so let's
simplify things a bit by removing "stat &" from
all omap_i2c_ack_stat() calls.

Code snippet (extremely simplified):

if (stat & NACK) {
...
omap_i2c_ack_stat(dev, stat & NACK);
}

if (stat & RDR) {
...
omap_i2c_ack_stat(dev, stat & RDR);
}

and so on. The tricky place is only WRT errata handling, for example:

if (*stat & (NACK | AL)) {
omap_i2c_ack_stat(dev, *stat & (XRDY | XDR));
...
}

but in this case, the errata says we must clear XRDY and XDR if that
errata triggers, so if they just got enabled or not, it doesn't matter.

Another tricky place is RDR | RRDY (likewise for XDR | XRDY):

if (stat & (RDR | RRDY)) {
...
omap_i2c_ack_stat(dev, stat & (RDR | RRDY));
}

again here there will be no issues because those IRQs never fire
simultaneously and one will only after after we have handled the
previous, that's because the same FIFO is used anyway and we won't shift
data into FIFO until we tell the IP "hey, I'm done with the FIFO, you
can shift more data"

Signed-off-by: Felipe Balbi 
Reviewed-by : Santosh Shilimkar 
Signed-off-by: Shubhrajyoti D 
---

- Added the explaination from the discurssion to the commit logs
as per Wolfram's suggestion.

 drivers/i2c/busses/i2c-omap.c |   19 ++-
 1 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 7be661e..359ee08 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -750,7 +750,7 @@ static int errata_omap3_i462(struct omap_i2c_dev *dev, u16 
*stat, int *err)
 
while (--timeout && !(*stat & OMAP_I2C_STAT_XUDF)) {
if (*stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
-   omap_i2c_ack_stat(dev, *stat & (OMAP_I2C_STAT_XRDY |
+   omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
OMAP_I2C_STAT_XDR));
return -ETIMEDOUT;
}
@@ -811,10 +811,11 @@ complete:
 */
if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK |
OMAP_I2C_STAT_AL)) {
-   omap_i2c_ack_stat(dev, stat &
-   (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
-   OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR |
-   OMAP_I2C_STAT_ARDY));
+   omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY |
+   OMAP_I2C_STAT_RDR |
+   OMAP_I2C_STAT_XRDY |
+   OMAP_I2C_STAT_XDR |
+   OMAP_I2C_STAT_ARDY));
omap_i2c_complete_cmd(dev, err);
return IRQ_HANDLED;
}
@@ -861,8 +862,8 @@ complete:
}
}
}
-   omap_i2c_ack_stat(dev,
-   stat & (OMAP_I2C_STAT_RRDY | 
OMAP_I2C_STAT_RDR));
+   omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY |
+   OMAP_I2C_STAT_RDR));
continue;
}
 
@@ -909,8 +910,8 @@ complete:
 
omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
}
-   omap_i2c_ack_stat(dev,
-   stat & (OMAP_I2C_STAT_XRDY | 
OMAP_I2C_STAT_XDR));
+   omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
+   OMAP_I2C_STAT_XDR));
continue;
}
 
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 03/17] i2c: omap: decrease indentation level on data handling

2012-06-29 Thread Shubhrajyoti D
From: Felipe Balbi 

The patch intends to decrease the indentation level on the
data handling
by using the fact that else of if (dev->buf_len) is same as
if (!dev->buf_len)

if (dev->buf_len) {
aaa;
} else {
bbb;
break;
}

to

if (!dev->buf_len) {
bbb;
break;
}
aaa;

Hence no functional changes.

Signed-off-by: Felipe Balbi 
Reviewed-by : Santosh Shilimkar 
Signed-off-by: Shubhrajyoti D 
---
- Changelogs updated.
 drivers/i2c/busses/i2c-omap.c |   63 -
 1 files changed, 31 insertions(+), 32 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 1df2bc9..f67e998 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -832,22 +832,7 @@ complete:
>> 8) & 0x3F;
}
while (num_bytes--) {
-   w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
-   if (dev->buf_len) {
-   *dev->buf++ = w;
-   dev->buf_len--;
-   /*
-* Data reg in 2430, omap3 and
-* omap4 is 8 bit wide
-*/
-   if (dev->flags &
-OMAP_I2C_FLAG_16BIT_DATA_REG) {
-   if (dev->buf_len) {
-   *dev->buf++ = w >> 8;
-   dev->buf_len--;
-   }
-   }
-   } else {
+   if (!dev->buf_len) {
if (stat & OMAP_I2C_STAT_RRDY)
dev_err(dev->dev,
"RRDY IRQ while no data"
@@ -858,6 +843,21 @@ complete:
" requested\n");
break;
}
+
+   w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
+   *dev->buf++ = w;
+   dev->buf_len--;
+   /*
+* Data reg in 2430, omap3 and
+* omap4 is 8 bit wide
+*/
+   if (dev->flags &
+   OMAP_I2C_FLAG_16BIT_DATA_REG) {
+   if (dev->buf_len) {
+   *dev->buf++ = w >> 8;
+   dev->buf_len--;
+   }
+   }
}
omap_i2c_ack_stat(dev,
stat & (OMAP_I2C_STAT_RRDY | 
OMAP_I2C_STAT_RDR));
@@ -874,22 +874,7 @@ complete:
& 0x3F;
}
while (num_bytes--) {
-   w = 0;
-   if (dev->buf_len) {
-   w = *dev->buf++;
-   dev->buf_len--;
-   /*
-* Data reg in 2430, omap3 and
-* omap4 is 8 bit wide
-*/
-   if (dev->flags &
-OMAP_I2C_FLAG_16BIT_DATA_REG) {
-   if (dev->buf_len) {
-   w |= *dev->buf++ << 8;
-   dev->buf_len--;
-   }
-   }
-   } else {
+   if (!dev->buf_len) {
if (stat & OMAP_I2C_STAT_XRDY)
dev_err(dev->dev,
"XRDY IRQ while no "
@@ -901,6 +886,20 @@ complete:
break;
}
 
+   w = *dev->buf++;
+  

[PATCHv3 12/17] i2c: omap: bus: add a receiver flag

2012-06-29 Thread Shubhrajyoti D
From: Felipe Balbi 

that way we can ignore TX IRQs while in receiver
mode and ignore RX IRQs while in transmitter mode.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |9 +
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 9f04976..00d5adc 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -196,6 +196,7 @@ struct omap_i2c_dev {
 */
u8  rev;
unsignedb_hw:1; /* bad h/w fixes */
+   unsignedreceiver:1; /* true when we're in receiver 
mode */
u16 iestate;/* Saved interrupt register */
u16 pscstate;
u16 scllstate;
@@ -512,6 +513,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
 
INIT_COMPLETION(dev->cmd_complete);
dev->cmd_err = 0;
+   dev->receiver = !!(msg->flags & I2C_M_RD);
 
w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT;
 
@@ -856,6 +858,13 @@ omap_i2c_isr(int this_irq, void *dev_id)
stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
stat &= bits;
 
+   /* If we're in receiver mode, ignore XDR/XRDY */
+   if (dev->receiver) {
+   stat &= ~(OMAP_I2C_STAT_XDR | OMAP_I2C_STAT_XRDY);
+   } else {
+   stat &= ~(OMAP_I2C_STAT_RDR | OMAP_I2C_STAT_RRDY);
+   }
+
if (!stat) {
/* my work here is done */
return IRQ_HANDLED;
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 11/17] i2c: omap: switch to platform_get_irq()

2012-06-29 Thread Shubhrajyoti D
From: Felipe Balbi 

that's a nice helper from drivers core which
will give us the exact IRQ number, instead
of a pointer to an IRQ resource.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   12 +++-
 1 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 6e4c2be..9f04976 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1016,11 +1016,12 @@ omap_i2c_probe(struct platform_device *pdev)
 {
struct omap_i2c_dev *dev;
struct i2c_adapter  *adap;
-   struct resource *mem, *irq;
+   struct resource *mem;
struct omap_i2c_bus_platform_data *pdata = pdev->dev.platform_data;
struct device_node  *node = pdev->dev.of_node;
const struct of_device_id *match;
irq_handler_t isr;
+   int irq;
int r;
 
/* NOTE: driver uses the static register mapping */
@@ -1029,10 +1030,11 @@ omap_i2c_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "no mem resource?\n");
return -ENODEV;
}
-   irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-   if (!irq) {
+
+   irq = platform_get_irq(pdev, 0);
+   if (irq < 0) {
dev_err(&pdev->dev, "no irq resource?\n");
-   return -ENODEV;
+   return irq;
}
 
dev = devm_kzalloc(&pdev->dev, sizeof(struct omap_i2c_dev), GFP_KERNEL);
@@ -1066,7 +1068,7 @@ omap_i2c_probe(struct platform_device *pdev)
}
 
dev->dev = &pdev->dev;
-   dev->irq = irq->start;
+   dev->irq = irq;
 
platform_set_drvdata(pdev, dev);
init_completion(&dev->cmd_complete);
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 14/17] i2c: omap: always return IRQ_HANDLED

2012-06-29 Thread Shubhrajyoti D
From: Felipe Balbi 

otherwise we could get our IRQ line disabled due
to many spurious IRQs.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index c48977c..2cd3b9a 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -986,7 +986,7 @@ complete:
}
} while (stat);
 
-   return count ? IRQ_HANDLED : IRQ_NONE;
+   return IRQ_HANDLED;
 }
 
 static const struct i2c_algorithm omap_i2c_algo = {
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 09/17] i2c: omap: switch over to do {} while loop

2012-06-29 Thread Shubhrajyoti D
From: Felipe Balbi 

this will make sure that we execute at least once.
No functional changes otherwise.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   20 ++--
 1 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index d57b75d..e4b83af 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -846,20 +846,28 @@ omap_i2c_isr(int this_irq, void *dev_id)
struct omap_i2c_dev *dev = dev_id;
u16 bits;
u16 stat;
-   int err, count = 0;
+   int err = 0, count = 0;
 
if (pm_runtime_suspended(dev->dev))
return IRQ_NONE;
 
-   bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
-   while ((stat = (omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG))) & bits) {
+   do {
+   bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
+   stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
+   stat &= bits;
+
+   if (!stat) {
+   /* my work here is done */
+   return IRQ_HANDLED;
+   }
+
dev_dbg(dev->dev, "IRQ (ISR = 0x%04x)\n", stat);
if (count++ == 100) {
dev_warn(dev->dev, "Too much work in one IRQ\n");
-   break;
+   omap_i2c_complete_cmd(dev, err);
+   return IRQ_HANDLED;
}
 
-   err = 0;
 complete:
/*
 * Ack the stat in one go, but [R/X]DR and [R/X]RDY should be
@@ -963,7 +971,7 @@ complete:
dev_err(dev->dev, "Transmit underflow\n");
dev->cmd_err |= OMAP_I2C_STAT_XUDF;
}
-   }
+   } while (stat);
 
return count ? IRQ_HANDLED : IRQ_NONE;
 }
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 04/17] i2c: omap: add blank lines

2012-06-29 Thread Shubhrajyoti D
From: Felipe Balbi 

trivial patch to aid readability. No functional
changes.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index f67e998..7be661e 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -805,6 +805,7 @@ complete:
dev_err(dev->dev, "Arbitration lost\n");
err |= OMAP_I2C_STAT_AL;
}
+
/*
 * ProDB0017052: Clear ARDY bit twice
 */
@@ -817,6 +818,7 @@ complete:
omap_i2c_complete_cmd(dev, err);
return IRQ_HANDLED;
}
+
if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) {
u8 num_bytes = 1;
 
@@ -863,6 +865,7 @@ complete:
stat & (OMAP_I2C_STAT_RRDY | 
OMAP_I2C_STAT_RDR));
continue;
}
+
if (stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)) {
u8 num_bytes = 1;
if (dev->fifo_size) {
@@ -910,10 +913,12 @@ complete:
stat & (OMAP_I2C_STAT_XRDY | 
OMAP_I2C_STAT_XDR));
continue;
}
+
if (stat & OMAP_I2C_STAT_ROVR) {
dev_err(dev->dev, "Receive overrun\n");
dev->cmd_err |= OMAP_I2C_STAT_ROVR;
}
+
if (stat & OMAP_I2C_STAT_XUDF) {
dev_err(dev->dev, "Transmit underflow\n");
dev->cmd_err |= OMAP_I2C_STAT_XUDF;
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 08/17] i2c: omap: re-factor receive/transmit data loop

2012-06-29 Thread Shubhrajyoti D
From: Felipe Balbi 

re-factor the common parts to a separate function,
so that code is easier to read and understand.

No functional changes.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |  204 
 1 files changed, 82 insertions(+), 122 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 870452d..d57b75d 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -771,12 +771,81 @@ static int errata_omap3_i462(struct omap_i2c_dev *dev)
return 0;
 }
 
+static void omap_i2c_receive_data(struct omap_i2c_dev *dev, u8 num_bytes,
+   bool is_rdr)
+{
+   u16 w;
+
+   while (num_bytes--) {
+   if (!dev->buf_len) {
+   dev_err(dev->dev, "%s without data",
+   is_rdr ? "RDR" : "RRDY");
+   break;
+   }
+
+   w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
+   *dev->buf++ = w;
+   dev->buf_len--;
+
+   /*
+* Data reg in 2430, omap3 and
+* omap4 is 8 bit wide
+*/
+   if (dev->flags & OMAP_I2C_FLAG_16BIT_DATA_REG) {
+   if (dev->buf_len) {
+   *dev->buf++ = w >> 8;
+   dev->buf_len--;
+   }
+   }
+   }
+}
+
+static int omap_i2c_transmit_data(struct omap_i2c_dev *dev, u8 num_bytes,
+   bool is_xdr)
+{
+   u16 w;
+
+   while (num_bytes--) {
+   if (!dev->buf_len) {
+   dev_err(dev->dev, "%s without data",
+   is_xdr ? "XDR" : "XRDY");
+   break;
+   }
+
+   w = *dev->buf++;
+   dev->buf_len--;
+
+   /*
+* Data reg in 2430, omap3 and
+* omap4 is 8 bit wide
+*/
+   if (dev->flags & OMAP_I2C_FLAG_16BIT_DATA_REG) {
+   if (dev->buf_len) {
+   w |= *dev->buf++ << 8;
+   dev->buf_len--;
+   }
+   }
+
+   if (dev->errata & I2C_OMAP_ERRATA_I462) {
+   int ret;
+
+   ret = errata_omap3_i462(dev);
+   if (ret < 0)
+   return ret;
+   }
+
+   omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
+   }
+
+   return 0;
+}
+
 static irqreturn_t
 omap_i2c_isr(int this_irq, void *dev_id)
 {
struct omap_i2c_dev *dev = dev_id;
u16 bits;
-   u16 stat, w;
+   u16 stat;
int err, count = 0;
 
if (pm_runtime_suspended(dev->dev))
@@ -831,30 +900,7 @@ complete:
OMAP_I2C_BUFSTAT_REG) >> 8)
& 0x3F;
 
-   while (num_bytes--) {
-   if (!dev->buf_len) {
-   dev_err(dev->dev,
-   "RDR IRQ while no data"
-   " requested\n");
-   break;
-   }
-
-   w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
-   *dev->buf++ = w;
-   dev->buf_len--;
-
-   /*
-* Data reg in 2430, omap3 and
-* omap4 is 8 bit wide
-*/
-   if (dev->flags &
-   OMAP_I2C_FLAG_16BIT_DATA_REG) {
-   if (dev->buf_len) {
-   *dev->buf++ = w >> 8;
-   dev->buf_len--;
-   }
-   }
-   }
+   omap_i2c_receive_data(dev, num_bytes, true);
 
if (dev->errata & I2C_OMAP_ERRATA_I207)
i2c_omap_errata_i207(dev, stat);
@@ -869,79 +915,24 @@ complete:
if (dev->fifo_size)
num_bytes = dev->fifo_size;
 
-   while (num_bytes--) {
-   if (!dev->buf_len) {
-   

[PATCHv3 01/17] i2c: omap: switch to devm_* API

2012-06-29 Thread Shubhrajyoti D
From: Felipe Balbi 

that helps deleting some boiler plate code
and lets driver-core manage our resources
for us.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   40 +++-
 1 files changed, 11 insertions(+), 29 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index feb15dd..7ad4efd 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -962,7 +962,7 @@ omap_i2c_probe(struct platform_device *pdev)
 {
struct omap_i2c_dev *dev;
struct i2c_adapter  *adap;
-   struct resource *mem, *irq, *ioarea;
+   struct resource *mem, *irq;
struct omap_i2c_bus_platform_data *pdata = pdev->dev.platform_data;
struct device_node  *node = pdev->dev.of_node;
const struct of_device_id *match;
@@ -981,17 +981,16 @@ omap_i2c_probe(struct platform_device *pdev)
return -ENODEV;
}
 
-   ioarea = request_mem_region(mem->start, resource_size(mem),
-   pdev->name);
-   if (!ioarea) {
-   dev_err(&pdev->dev, "I2C region already claimed\n");
-   return -EBUSY;
+   dev = devm_kzalloc(&pdev->dev, sizeof(struct omap_i2c_dev), GFP_KERNEL);
+   if (!dev) {
+   dev_err(&pdev->dev, "Menory allocation failed\n");
+   return -ENOMEM;
}
 
-   dev = kzalloc(sizeof(struct omap_i2c_dev), GFP_KERNEL);
-   if (!dev) {
-   r = -ENOMEM;
-   goto err_release_region;
+   dev->base = devm_request_and_ioremap(&pdev->dev, mem);
+   if (!dev->base) {
+   dev_err(&pdev->dev, "I2C region already claimed\n");
+   return -ENOMEM;
}
 
match = of_match_device(of_match_ptr(omap_i2c_of_match), &pdev->dev);
@@ -1014,11 +1013,6 @@ omap_i2c_probe(struct platform_device *pdev)
 
dev->dev = &pdev->dev;
dev->irq = irq->start;
-   dev->base = ioremap(mem->start, resource_size(mem));
-   if (!dev->base) {
-   r = -ENOMEM;
-   goto err_free_mem;
-   }
 
platform_set_drvdata(pdev, dev);
init_completion(&dev->cmd_complete);
@@ -1076,7 +1070,7 @@ omap_i2c_probe(struct platform_device *pdev)
 
isr = (dev->rev < OMAP_I2C_OMAP1_REV_2) ? omap_i2c_omap1_isr :
   omap_i2c_isr;
-   r = request_irq(dev->irq, isr, IRQF_NO_SUSPEND, pdev->name, dev);
+   r = devm_request_irq(&pdev->dev, dev->irq, isr, IRQF_NO_SUSPEND, 
pdev->name, dev);
 
if (r) {
dev_err(dev->dev, "failure requesting irq %i\n", dev->irq);
@@ -1100,7 +1094,7 @@ omap_i2c_probe(struct platform_device *pdev)
r = i2c_add_numbered_adapter(adap);
if (r) {
dev_err(dev->dev, "failure adding adapter\n");
-   goto err_free_irq;
+   goto err_unuse_clocks;
}
 
of_i2c_register_devices(adap);
@@ -1109,18 +1103,12 @@ omap_i2c_probe(struct platform_device *pdev)
 
return 0;
 
-err_free_irq:
-   free_irq(dev->irq, dev);
 err_unuse_clocks:
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
 err_free_mem:
pm_runtime_put(dev->dev);
-   iounmap(dev->base);
pm_runtime_disable(&pdev->dev);
platform_set_drvdata(pdev, NULL);
-   kfree(dev);
-err_release_region:
-   release_mem_region(mem->start, resource_size(mem));
 
return r;
 }
@@ -1128,12 +1116,10 @@ err_release_region:
 static int __devexit omap_i2c_remove(struct platform_device *pdev)
 {
struct omap_i2c_dev *dev = platform_get_drvdata(pdev);
-   struct resource *mem;
int ret;
 
platform_set_drvdata(pdev, NULL);
 
-   free_irq(dev->irq, dev);
i2c_del_adapter(&dev->adapter);
ret = pm_runtime_get_sync(&pdev->dev);
if (!IS_ERR_VALUE(ret))
@@ -1141,10 +1127,6 @@ static int __devexit omap_i2c_remove(struct 
platform_device *pdev)
 
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
-   iounmap(dev->base);
-   kfree(dev);
-   mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   release_mem_region(mem->start, resource_size(mem));
return 0;
 }
 
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 13/17] i2c: omap: simplify errata check

2012-06-29 Thread Shubhrajyoti D
From: Felipe Balbi 

omap_i2c_dev is allocated with kzalloc(),
so we need not initialize b_hw to zero.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 00d5adc..c48977c 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1119,9 +1119,7 @@ omap_i2c_probe(struct platform_device *pdev)
 
dev->fifo_size = (dev->fifo_size / 2);
 
-   if (dev->rev >= OMAP_I2C_REV_ON_3630_4430)
-   dev->b_hw = 0; /* Disable hardware fixes */
-   else
+   if (dev->rev < OMAP_I2C_REV_ON_3630_4430)
dev->b_hw = 1; /* Enable hardware fixes */
 
/* calculate wakeup latency constraint for MPU */
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 07/17] i2c: omap: improve i462 errata handling

2012-06-29 Thread Shubhrajyoti D
From: Felipe Balbi 

Make it not depend on ISR's local variables
in order to make it easier to re-factor the
transmit data loop.
Also since we are waiting for XUDF just before
writing data lets not flag the underflow.
This is anyways going to go once we write
the data.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   43 
 1 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 45bd731..870452d 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -744,27 +744,30 @@ omap_i2c_omap1_isr(int this_irq, void *dev_id)
  * data to DATA_REG. Otherwise some data bytes can be lost while transferring
  * them from the memory to the I2C interface.
  */
-static int errata_omap3_i462(struct omap_i2c_dev *dev, u16 *stat, int *err)
+static int errata_omap3_i462(struct omap_i2c_dev *dev)
 {
unsigned long timeout = 1;
+   u16 stat;
 
-   while (--timeout && !(*stat & OMAP_I2C_STAT_XUDF)) {
-   if (*stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
+   do {
+   stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
+   if (stat & OMAP_I2C_STAT_XUDF)
+   break;
+
+   if (stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
OMAP_I2C_STAT_XDR));
-   return -ETIMEDOUT;
+   return -EIO;
}
 
cpu_relax();
-   *stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
-   }
+   } while (--timeout);
 
if (!timeout) {
dev_err(dev->dev, "timeout waiting on XUDF bit\n");
return 0;
}
 
-   *err |= OMAP_I2C_STAT_XUDF;
return 0;
 }
 
@@ -926,9 +929,16 @@ complete:
}
}
 
-   if ((dev->errata & I2C_OMAP_ERRATA_I462) &&
-   errata_omap3_i462(dev, &stat, &err))
-   goto complete;
+   if (dev->errata & I2C_OMAP_ERRATA_I462) {
+   int ret;
+
+   ret = errata_omap3_i462(dev);
+   stat = omap_i2c_read_reg(dev,
+   OMAP_I2C_STAT_REG);
+
+   if (ret < 0)
+   goto complete;
+   }
 
omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
}
@@ -966,9 +976,16 @@ complete:
}
}
 
-   if ((dev->errata & I2C_OMAP_ERRATA_I462) &&
-   errata_omap3_i462(dev, &stat, &err))
-   goto complete;
+   if (dev->errata & I2C_OMAP_ERRATA_I462) {
+   int ret;
+
+   ret = errata_omap3_i462(dev);
+   stat = omap_i2c_read_reg(dev,
+   OMAP_I2C_STAT_REG);
+
+   if (ret < 0)
+   goto complete;
+   }
 
omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
}
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 16/17] i2c: omap: resize fifos before each message

2012-06-29 Thread Shubhrajyoti D
From: Felipe Balbi 

This patch will try to avoid the usage of
draining feature by reconfiguring the FIFO
the start condition of each message based
on the message's size.

By doing that, we will be better utilizing
the FIFO when doing big transfers.

While at that also drop the now uneeded
check for dev->buf_len as we always know
the amount of data to be transmitted.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   83 +
 1 files changed, 51 insertions(+), 32 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 1196417..ac3bdae 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -190,6 +190,7 @@ struct omap_i2c_dev {
u8  *regs;
size_t  buf_len;
struct i2c_adapter  adapter;
+   u8  threshold;
u8  fifo_size;  /* use as flag and value
 * fifo_size==0 implies no fifo
 * if set, should be trsh+1
@@ -415,13 +416,6 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
 
-   if (dev->fifo_size) {
-   /* Note: setup required fifo size - 1. RTRSH and XTRSH */
-   buf = (dev->fifo_size - 1) << 8 | OMAP_I2C_BUF_RXFIF_CLR |
-   (dev->fifo_size - 1) | OMAP_I2C_BUF_TXFIF_CLR;
-   omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
-   }
-
/* Take the I2C module out of reset: */
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
 
@@ -482,6 +476,45 @@ static int omap_i2c_bus_clear(struct omap_i2c_dev *dev)
return omap_i2c_wait_for_bb(dev);
 }
 
+static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx)
+{
+   u16 buf;
+
+   if (dev->flags & OMAP_I2C_FLAG_NO_FIFO)
+   return;
+
+   /*
+* Set up notification threshold based on message size. We're doing
+* this to try and avoid draining feature as much as possible. Whenever
+* we have big messages to transfer (bigger than our total fifo size)
+* then we might use draining feature to transfer the remaining bytes.
+*/
+
+   dev->threshold = clamp(size, (u8) 1, dev->fifo_size);
+
+   buf = omap_i2c_read_reg(dev, OMAP_I2C_BUF_REG);
+
+   if (is_rx) {
+   /* Clear RX Threshold */
+   buf &= ~(0x3f << 8);
+   buf |= ((dev->threshold - 1) << 8) | OMAP_I2C_BUF_RXFIF_CLR;
+   } else {
+   /* Clear TX Threshold */
+   buf &= ~0x3f;
+   buf |= (dev->threshold - 1) | OMAP_I2C_BUF_TXFIF_CLR;
+   }
+
+   omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
+
+   if (dev->rev < OMAP_I2C_REV_ON_3630_4430)
+   dev->b_hw = 1; /* Enable hardware fixes */
+
+   /* calculate wakeup latency constraint for MPU */
+   if (dev->set_mpu_wkup_lat != NULL)
+   dev->latency = (100 * dev->threshold) /
+   (1000 * dev->speed / 8);
+}
+
 /*
  * Low level master read/write transaction.
  */
@@ -498,6 +531,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
if (msg->len == 0)
return -EINVAL;
 
+   dev->receiver = !!(msg->flags & I2C_M_RD);
+   omap_i2c_resize_fifo(dev, msg->len, dev->receiver);
+
omap_i2c_write_reg(dev, OMAP_I2C_SA_REG, msg->addr);
 
/* REVISIT: Could the STB bit of I2C_CON be used with probing? */
@@ -513,7 +549,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
 
INIT_COMPLETION(dev->cmd_complete);
dev->cmd_err = 0;
-   dev->receiver = !!(msg->flags & I2C_M_RD);
 
w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT;
 
@@ -779,12 +814,6 @@ static void omap_i2c_receive_data(struct omap_i2c_dev 
*dev, u8 num_bytes,
u16 w;
 
while (num_bytes--) {
-   if (!dev->buf_len) {
-   dev_err(dev->dev, "%s without data",
-   is_rdr ? "RDR" : "RRDY");
-   break;
-   }
-
w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
*dev->buf++ = w;
dev->buf_len--;
@@ -794,10 +823,8 @@ static void omap_i2c_receive_data(struct omap_i2c_dev 
*dev, u8 num_bytes,
 * omap4 is 8 bit wide
 */
if (dev->flags & OMAP_I2C_FLAG_16BIT_DATA_REG) {
-   if (dev->buf_len) {
-   

[PATCHv3 00/17] I2C Big cleanup

2012-06-29 Thread Shubhrajyoti D
I have dropped a few patches from the series and also
tested every single patch on my pandaboard.

There's still lots of work to be done on the i2c-omap.c
driver but it's now easier to read, IMO.

Changes since v1:
   - removed tabification on patch 6/17
   - removed dev_err() which was introduced on patch 09/17
Changes since v2:
- do not set full fifo depth in the RDR interrupt.
- some changelog updates.
- rebase to the Wolfram's tree.

Tested on omap4sdp and 3430sdp.
Functional testing.
Also did suspend resume.
For omap3 the per domain seems to be OK.

This applies on Wolfram's i2c-embedded/for-next branch
plus the below series
http://www.spinics.net/lists/linux-omap/msg72901.html


are available in the git repository at:
  git://gitorious.org/linus-tree/linus-tree.git for_next/omap/big_cleanup



Felipe Balbi (17):
  i2c: omap: switch to devm_* API
  i2c: omap: simplify num_bytes handling
  i2c: omap: decrease indentation level on data handling
  i2c: omap: add blank lines
  i2c: omap: simplify omap_i2c_ack_stat()
  i2c: omap: split out [XR]DR and [XR]RDY
  i2c: omap: improve i462 errata handling
  i2c: omap: re-factor receive/transmit data loop
  i2c: omap: switch over to do {} while loop
  i2c: omap: ack IRQ in parts
  i2c: omap: switch to platform_get_irq()
  i2c: omap: bus: add a receiver flag
  i2c: omap: simplify errata check
  i2c: omap: always return IRQ_HANDLED
  i2c: omap: simplify IRQ exit path
  i2c: omap: resize fifos before each message
  i2c: omap: get rid of the "complete" label

 drivers/i2c/busses/i2c-omap.c |  394 -
 1 files changed, 232 insertions(+), 162 deletions(-)

-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv3 06/17] i2c: omap: split out [XR]DR and [XR]RDY

2012-06-29 Thread Shubhrajyoti D
From: Felipe Balbi 

While they do pretty much the same thing, there
are a few peculiarities. Specially WRT erratas,
it's best to split those out and re-factor the
read/write loop to another function which both
cases call.

This last part will be done on another patch.

While at that, also avoid an unncessary register
read since dev->fifo_len will always contain the
correct amount of data to be transferred.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |  126 ++--
 1 files changed, 94 insertions(+), 32 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 359ee08..45bd731 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -820,36 +820,64 @@ complete:
return IRQ_HANDLED;
}
 
-   if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) {
+   if (stat & OMAP_I2C_STAT_RDR) {
u8 num_bytes = 1;
 
+   if (dev->fifo_size)
+   num_bytes = (omap_i2c_read_reg(dev,
+   OMAP_I2C_BUFSTAT_REG) >> 8)
+   & 0x3F;
+
+   while (num_bytes--) {
+   if (!dev->buf_len) {
+   dev_err(dev->dev,
+   "RDR IRQ while no data"
+   " requested\n");
+   break;
+   }
+
+   w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
+   *dev->buf++ = w;
+   dev->buf_len--;
+
+   /*
+* Data reg in 2430, omap3 and
+* omap4 is 8 bit wide
+*/
+   if (dev->flags &
+   OMAP_I2C_FLAG_16BIT_DATA_REG) {
+   if (dev->buf_len) {
+   *dev->buf++ = w >> 8;
+   dev->buf_len--;
+   }
+   }
+   }
+
if (dev->errata & I2C_OMAP_ERRATA_I207)
i2c_omap_errata_i207(dev, stat);
 
-   if (dev->fifo_size) {
-   if (stat & OMAP_I2C_STAT_RRDY)
-   num_bytes = dev->fifo_size;
-   else/* read RXSTAT on RDR interrupt */
-   num_bytes = (omap_i2c_read_reg(dev,
-   OMAP_I2C_BUFSTAT_REG)
-   >> 8) & 0x3F;
-   }
+   omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR);
+   continue;
+   }
+
+   if (stat & OMAP_I2C_STAT_RRDY) {
+   u8 num_bytes = 1;
+
+   if (dev->fifo_size)
+   num_bytes = dev->fifo_size;
+
while (num_bytes--) {
if (!dev->buf_len) {
-   if (stat & OMAP_I2C_STAT_RRDY)
-   dev_err(dev->dev,
+   dev_err(dev->dev,
"RRDY IRQ while no data"
-   " requested\n");
-   if (stat & OMAP_I2C_STAT_RDR)
-   dev_err(dev->dev,
-   "RDR IRQ while no data"
-   " requested\n");
+   " requested\n");
break;
}
 
w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
*dev->buf++ = w;
dev->buf_len--;
+
/*
 * Data reg in 2430, omap3 and
 * omap4 is 8 bit wide
@@ -862,36 +890,70 @@ complete:
}
}
   

[RFC PATCH 0/3] I2C: Report the actual transferred bytes

2012-06-29 Thread Shubhrajyoti D
Currently the I2C core reports only a negative number on errors.
However some of the users in case of errors want to re-transfer only
the remaining bytes.

The patch series tries to add a actual field to the msg which
can be checked by the user.

Also a patch to implement the actual bytes transferred in case of
i2c-omap.


Felipe Balbi (1):
  i2c: omap: implement handling for 'actual' bytes transferred

Shubhrajyoti D (2):
  i2c: add 'actual' field to struct i2c_msg
  i2c: inititalise the actual transferred to zero

 drivers/i2c/busses/i2c-omap.c |5 +
 drivers/i2c/i2c-core.c|4 ++--
 include/linux/i2c.h   |1 +
 3 files changed, 8 insertions(+), 2 deletions(-)

-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH 3/3] i2c: inititalise the actual transferred to zero

2012-06-29 Thread Shubhrajyoti D
In i2c_smbus_xfer_emulated initialise the actual bytes
to zero.

Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/i2c-core.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index a6ad32b..fa7f799 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -1949,8 +1949,8 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter 
*adapter, u16 addr,
unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX+3];
unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX+2];
int num = read_write == I2C_SMBUS_READ ? 2 : 1;
-   struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 },
- { addr, flags | I2C_M_RD, 0, msgbuf1 }
+   struct i2c_msg msg[2] = { { addr, flags, 1, 0, msgbuf0 },
+ { addr, flags | I2C_M_RD, 0, 0, msgbuf1 }
};
int i;
u8 partial_pec = 0;
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH 1/3] i2c: add 'actual' field to struct i2c_msg

2012-06-29 Thread Shubhrajyoti D
In case of a NACK, it's wise to tell our clients
drivers about how many bytes were actually transferred.

Support this by adding an extra field to the struct
i2c_msg which gets incremented the amount of bytes
actually transferred.

Signed-off-by: Shubhrajyoti D 
Signed-off-by: Felipe Balbi 
---
 include/linux/i2c.h |1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index ddfa041..0cb6b83 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -547,6 +547,7 @@ struct i2c_msg {
 #define I2C_M_NO_RD_ACK0x0800  /* if 
I2C_FUNC_PROTOCOL_MANGLING */
 #define I2C_M_RECV_LEN 0x0400  /* length will be first received byte */
__u16 len;  /* msg length   */
+   __u16 actual;   /* actual bytes transferred */
__u8 *buf;  /* pointer to msg data  */
 };
 
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH 2/3] i2c: omap: implement handling for 'actual' bytes transferred

2012-06-29 Thread Shubhrajyoti D
From: Felipe Balbi 

this is important in cases where client driver
wants to know how many bytes were actually
transferred.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 266bba7..fc726a6 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -189,6 +189,7 @@ struct omap_i2c_dev {
u8  *buf;
u8  *regs;
size_t  buf_len;
+   u16 actual;
struct i2c_adapter  adapter;
u8  threshold;
u8  fifo_size;  /* use as flag and value
@@ -601,6 +602,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
omap_i2c_init(dev);
return -ETIMEDOUT;
}
+   msg->actual = dev->actual;
 
if (likely(!dev->cmd_err))
return 0;
@@ -828,6 +830,7 @@ static void omap_i2c_receive_data(struct omap_i2c_dev *dev, 
u8 num_bytes,
w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
*dev->buf++ = w;
dev->buf_len--;
+   dev->actual++;
 
/*
 * Data reg in 2430, omap3 and
@@ -848,6 +851,7 @@ static int omap_i2c_transmit_data(struct omap_i2c_dev *dev, 
u8 num_bytes,
while (num_bytes--) {
w = *dev->buf++;
dev->buf_len--;
+   dev->actual++;
 
/*
 * Data reg in 2430, omap3 and
@@ -908,6 +912,7 @@ omap_i2c_isr(int this_irq, void *dev_id)
 
if (stat & OMAP_I2C_STAT_NACK) {
err |= OMAP_I2C_STAT_NACK;
+   dev->actual--;
omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
goto out;
}
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv4 18/18] i2c: omap: remove redundant status read

2012-07-03 Thread Shubhrajyoti D
Remove the redundant read of the status register.

Signed-off-by: Shubhrajyoti D 
---
v4:Patch addition(fixes a review comment)

 drivers/i2c/busses/i2c-omap.c |2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 8940eb3..b1a32f8 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -965,7 +965,6 @@ omap_i2c_isr(int this_irq, void *dev_id)
num_bytes = dev->buf_len;
 
ret = omap_i2c_transmit_data(dev, num_bytes, true);
-   stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
if (ret < 0)
goto out;
 
@@ -981,7 +980,6 @@ omap_i2c_isr(int this_irq, void *dev_id)
num_bytes = dev->threshold;
 
ret = omap_i2c_transmit_data(dev, num_bytes, false);
-   stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
if (ret < 0)
goto out;
 
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv4 17/18] i2c: omap: get rid of the "complete" label

2012-07-03 Thread Shubhrajyoti D
From: Felipe Balbi 

we can ack stat and complete the command from
the errata handling itself.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   16 +---
 1 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index f64916f..8940eb3 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -794,6 +794,17 @@ static int errata_omap3_i462(struct omap_i2c_dev *dev)
if (stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
OMAP_I2C_STAT_XDR));
+   if (stat & OMAP_I2C_STAT_NACK) {
+   dev->cmd_err |= OMAP_I2C_STAT_NACK;
+   omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
+   }
+
+   if (stat & OMAP_I2C_STAT_AL) {
+   dev_err(dev->dev, "Arbitration lost\n");
+   dev->cmd_err |= OMAP_I2C_STAT_AL;
+   omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
+   }
+
return -EIO;
}
 
@@ -894,7 +905,6 @@ omap_i2c_isr(int this_irq, void *dev_id)
goto out;
}
 
-complete:
if (stat & OMAP_I2C_STAT_NACK) {
err |= OMAP_I2C_STAT_NACK;
omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
@@ -957,7 +967,7 @@ complete:
ret = omap_i2c_transmit_data(dev, num_bytes, true);
stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
if (ret < 0)
-   goto complete;
+   goto out;
 
omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XDR);
continue;
@@ -973,7 +983,7 @@ complete:
ret = omap_i2c_transmit_data(dev, num_bytes, false);
stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
if (ret < 0)
-   goto complete;
+   goto out;
 
omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XRDY);
continue;
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv4 10/18] i2c: omap: ack IRQ in parts

2012-07-03 Thread Shubhrajyoti D
From: Felipe Balbi 

According to flow diagrams on OMAP TRMs,
we should ACK the IRQ as they happen.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   28 
 1 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 6c8f135..30db822 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -869,21 +869,19 @@ omap_i2c_isr(int this_irq, void *dev_id)
}
 
 complete:
-   /*
-* Ack the stat in one go, but [R/X]DR and [R/X]RDY should be
-* acked after the data operation is complete.
-* Ref: TRM SWPU114Q Figure 18-31
-*/
-   omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat &
-   ~(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
-   OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
-
-   if (stat & OMAP_I2C_STAT_NACK)
+   if (stat & OMAP_I2C_STAT_NACK) {
err |= OMAP_I2C_STAT_NACK;
+   omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
+   omap_i2c_complete_cmd(dev, err);
+   return IRQ_HANDLED;
+   }
 
if (stat & OMAP_I2C_STAT_AL) {
dev_err(dev->dev, "Arbitration lost\n");
err |= OMAP_I2C_STAT_AL;
+   omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
+   omap_i2c_complete_cmd(dev, err);
+   return IRQ_HANDLED;
}
 
/*
@@ -960,12 +958,18 @@ complete:
 
if (stat & OMAP_I2C_STAT_ROVR) {
dev_err(dev->dev, "Receive overrun\n");
-   dev->cmd_err |= OMAP_I2C_STAT_ROVR;
+   err |= OMAP_I2C_STAT_ROVR;
+   omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ROVR);
+   omap_i2c_complete_cmd(dev, err);
+   return IRQ_HANDLED;
}
 
if (stat & OMAP_I2C_STAT_XUDF) {
dev_err(dev->dev, "Transmit underflow\n");
-   dev->cmd_err |= OMAP_I2C_STAT_XUDF;
+   err |= OMAP_I2C_STAT_XUDF;
+   omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XUDF);
+   omap_i2c_complete_cmd(dev, err);
+   return IRQ_HANDLED;
}
} while (stat);
 
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv4 02/18] i2c: omap: simplify num_bytes handling

2012-07-03 Thread Shubhrajyoti D
From: Felipe Balbi 

trivial patch, no functional changes

If the fifo is disabled or fifo_size is 0 the num_bytes
is set to 1. Else it is set to fifo_size or in case of a
draining interrupt the remaining bytes in the buff stat.
So the zero check is redundant and can be safely optimised.

Signed-off-by: Felipe Balbi 
Reviewed-by : Santosh Shilimkar 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |6 ++
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 0946be5..440e41f 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -831,8 +831,7 @@ complete:
OMAP_I2C_BUFSTAT_REG)
>> 8) & 0x3F;
}
-   while (num_bytes) {
-   num_bytes--;
+   while (num_bytes--) {
w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
if (dev->buf_len) {
*dev->buf++ = w;
@@ -874,8 +873,7 @@ complete:
OMAP_I2C_BUFSTAT_REG)
& 0x3F;
}
-   while (num_bytes) {
-   num_bytes--;
+   while (num_bytes--) {
w = 0;
if (dev->buf_len) {
w = *dev->buf++;
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv4 07/18] i2c: omap: improve i462 errata handling

2012-07-03 Thread Shubhrajyoti D
From: Felipe Balbi 

Make it not depend on ISR's local variables
in order to make it easier to re-factor the
transmit data loop.
Also since we are waiting for XUDF just before
writing data lets not service the underflow.
This is anyways going to go once we write
the data.

Signed-off-by: Felipe Balbi 
[Avoid flagging the XUDF]
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   43 
 1 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 5c2460d..1715c35 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -744,27 +744,30 @@ omap_i2c_omap1_isr(int this_irq, void *dev_id)
  * data to DATA_REG. Otherwise some data bytes can be lost while transferring
  * them from the memory to the I2C interface.
  */
-static int errata_omap3_i462(struct omap_i2c_dev *dev, u16 *stat, int *err)
+static int errata_omap3_i462(struct omap_i2c_dev *dev)
 {
unsigned long timeout = 1;
+   u16 stat;
 
-   while (--timeout && !(*stat & OMAP_I2C_STAT_XUDF)) {
-   if (*stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
+   do {
+   stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
+   if (stat & OMAP_I2C_STAT_XUDF)
+   break;
+
+   if (stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
OMAP_I2C_STAT_XDR));
-   return -ETIMEDOUT;
+   return -EIO;
}
 
cpu_relax();
-   *stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
-   }
+   } while (--timeout);
 
if (!timeout) {
dev_err(dev->dev, "timeout waiting on XUDF bit\n");
return 0;
}
 
-   *err |= OMAP_I2C_STAT_XUDF;
return 0;
 }
 
@@ -922,9 +925,16 @@ complete:
}
}
 
-   if ((dev->errata & I2C_OMAP_ERRATA_I462) &&
-   errata_omap3_i462(dev, &stat, &err))
-   goto complete;
+   if (dev->errata & I2C_OMAP_ERRATA_I462) {
+   int ret;
+
+   ret = errata_omap3_i462(dev);
+   stat = omap_i2c_read_reg(dev,
+   OMAP_I2C_STAT_REG);
+
+   if (ret < 0)
+   goto complete;
+   }
 
omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
}
@@ -962,9 +972,16 @@ complete:
}
}
 
-   if ((dev->errata & I2C_OMAP_ERRATA_I462) &&
-   errata_omap3_i462(dev, &stat, &err))
-   goto complete;
+   if (dev->errata & I2C_OMAP_ERRATA_I462) {
+   int ret;
+
+   ret = errata_omap3_i462(dev);
+   stat = omap_i2c_read_reg(dev,
+   OMAP_I2C_STAT_REG);
+
+   if (ret < 0)
+   goto complete;
+   }
 
omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
}
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv4 05/18] i2c: omap: simplify omap_i2c_ack_stat()

2012-07-03 Thread Shubhrajyoti D
From: Felipe Balbi 

stat & BIT(1) is the same as BIT(1), so let's
simplify things a bit by removing "stat &" from
all omap_i2c_ack_stat() calls.

Code snippet (extremely simplified):

if (stat & NACK) {
...
omap_i2c_ack_stat(dev, stat & NACK);
}

if (stat & RDR) {
...
omap_i2c_ack_stat(dev, stat & RDR);
}

and so on. The tricky place is only WRT errata handling, for example:

if (*stat & (NACK | AL)) {
omap_i2c_ack_stat(dev, *stat & (XRDY | XDR));
...
}

but in this case, the errata says we must clear XRDY and XDR if that
errata triggers, so if they just got enabled or not, it doesn't matter.

Another tricky place is RDR | RRDY (likewise for XDR | XRDY):

if (stat & (RDR | RRDY)) {
...
omap_i2c_ack_stat(dev, stat & (RDR | RRDY));
}

again here there will be no issues because those IRQs never fire
simultaneously and one will only after after we have handled the
previous, that's because the same FIFO is used anyway and we won't shift
data into FIFO until we tell the IP "hey, I'm done with the FIFO, you
can shift more data"

Signed-off-by: Felipe Balbi 
Reviewed-by : Santosh Shilimkar 
[Added the explaination from the discurssion to the commit logs]
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   19 ++-
 1 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 31c4e55..1c1ee7a 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -750,7 +750,7 @@ static int errata_omap3_i462(struct omap_i2c_dev *dev, u16 
*stat, int *err)
 
while (--timeout && !(*stat & OMAP_I2C_STAT_XUDF)) {
if (*stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
-   omap_i2c_ack_stat(dev, *stat & (OMAP_I2C_STAT_XRDY |
+   omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
OMAP_I2C_STAT_XDR));
return -ETIMEDOUT;
}
@@ -811,10 +811,11 @@ complete:
 */
if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK |
OMAP_I2C_STAT_AL)) {
-   omap_i2c_ack_stat(dev, stat &
-   (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
-   OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR |
-   OMAP_I2C_STAT_ARDY));
+   omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY |
+   OMAP_I2C_STAT_RDR |
+   OMAP_I2C_STAT_XRDY |
+   OMAP_I2C_STAT_XDR |
+   OMAP_I2C_STAT_ARDY));
omap_i2c_complete_cmd(dev, err);
return IRQ_HANDLED;
}
@@ -861,8 +862,8 @@ complete:
}
}
}
-   omap_i2c_ack_stat(dev,
-   stat & (OMAP_I2C_STAT_RRDY | 
OMAP_I2C_STAT_RDR));
+   omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY |
+   OMAP_I2C_STAT_RDR));
continue;
}
 
@@ -909,8 +910,8 @@ complete:
 
omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
}
-   omap_i2c_ack_stat(dev,
-   stat & (OMAP_I2C_STAT_XRDY | 
OMAP_I2C_STAT_XDR));
+   omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
+   OMAP_I2C_STAT_XDR));
continue;
}
 
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv4 04/18] i2c: omap: add blank lines

2012-07-03 Thread Shubhrajyoti D
From: Felipe Balbi 

trivial patch to aid readability. No functional
changes.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |5 +
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 0da00ac..31c4e55 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -805,6 +805,7 @@ complete:
dev_err(dev->dev, "Arbitration lost\n");
err |= OMAP_I2C_STAT_AL;
}
+
/*
 * ProDB0017052: Clear ARDY bit twice
 */
@@ -817,6 +818,7 @@ complete:
omap_i2c_complete_cmd(dev, err);
return IRQ_HANDLED;
}
+
if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) {
u8 num_bytes = 1;
 
@@ -863,6 +865,7 @@ complete:
stat & (OMAP_I2C_STAT_RRDY | 
OMAP_I2C_STAT_RDR));
continue;
}
+
if (stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)) {
u8 num_bytes = 1;
if (dev->fifo_size) {
@@ -910,10 +913,12 @@ complete:
stat & (OMAP_I2C_STAT_XRDY | 
OMAP_I2C_STAT_XDR));
continue;
}
+
if (stat & OMAP_I2C_STAT_ROVR) {
dev_err(dev->dev, "Receive overrun\n");
dev->cmd_err |= OMAP_I2C_STAT_ROVR;
}
+
if (stat & OMAP_I2C_STAT_XUDF) {
dev_err(dev->dev, "Transmit underflow\n");
dev->cmd_err |= OMAP_I2C_STAT_XUDF;
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv4 00/18] I2C OMAP big cleanup

2012-07-03 Thread Shubhrajyoti D
Changes since v1:
   - removed tabification on patch 6/17
   - removed dev_err() which was introduced on patch 09/17
Changes since v2:
- do not set full fifo depth in the RDR interrupt.
- some changelog updates.
- rebase to the Wolfram's tree.
Changes since v3:
- Remove a redundant read of status register
- Read the dev->buf_len variable instead of the register
as the information of the remaining bytes is there.

Tested on omap4sdp and 3430sdp.
Functional testing.
Also did suspend resume.
(with omap_fixes_a_3.5rc' of git://git.pwsan.com/linux-2.6 into lkml_master
for 32ktimer fix)

This applies on Wolfram's i2c-embedded/for-next branch
plus the below series
http://www.spinics.net/lists/linux-omap/msg72901.html

Previous disscurssion 
http://www.spinics.net/lists/linux-omap/msg72997.html

are available in the git repository at:
  git://gitorious.org/linus-tree/linus-tree.git for_next/omap/big_cleanup

Felipe Balbi (17):
  i2c: omap: switch to devm_* API
  i2c: omap: simplify num_bytes handling
  i2c: omap: decrease indentation level on data handling
  i2c: omap: add blank lines
  i2c: omap: simplify omap_i2c_ack_stat()
  i2c: omap: split out [XR]DR and [XR]RDY
  i2c: omap: improve i462 errata handling
  i2c: omap: re-factor receive/transmit data loop
  i2c: omap: switch over to do {} while loop
  i2c: omap: ack IRQ in parts
  i2c: omap: switch to platform_get_irq()
  i2c: omap: bus: add a receiver flag
  i2c: omap: simplify errata check
  i2c: omap: always return IRQ_HANDLED
  i2c: omap: simplify IRQ exit path
  i2c: omap: resize fifos before each message
  i2c: omap: get rid of the "complete" label

Shubhrajyoti D (1):
  i2c: omap: remove redundant status read

 drivers/i2c/busses/i2c-omap.c |  392 -
 1 files changed, 228 insertions(+), 164 deletions(-)

-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv4 13/18] i2c: omap: simplify errata check

2012-07-03 Thread Shubhrajyoti D
From: Felipe Balbi 

omap_i2c_dev is allocated with kzalloc(),
so we need not initialize b_hw to zero.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 0fda3b7..7e3502e 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1114,9 +1114,7 @@ omap_i2c_probe(struct platform_device *pdev)
 
dev->fifo_size = (dev->fifo_size / 2);
 
-   if (dev->rev >= OMAP_I2C_REV_ON_3630_4430)
-   dev->b_hw = 0; /* Disable hardware fixes */
-   else
+   if (dev->rev < OMAP_I2C_REV_ON_3630_4430)
dev->b_hw = 1; /* Enable hardware fixes */
 
/* calculate wakeup latency constraint for MPU */
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv4 03/18] i2c: omap: decrease indentation level on data handling

2012-07-03 Thread Shubhrajyoti D
From: Felipe Balbi 

The patch intends to decrease the indentation level on the
data handling
by using the fact that else of if (dev->buf_len) is same as
if (!dev->buf_len)

if (dev->buf_len) {
aaa;
} else {
bbb;
break;
}

to

if (!dev->buf_len) {
bbb;
break;
}
aaa;

Hence no functional changes.

Signed-off-by: Felipe Balbi 
Reviewed-by : Santosh Shilimkar 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   63 -
 1 files changed, 31 insertions(+), 32 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 440e41f..0da00ac 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -832,22 +832,7 @@ complete:
>> 8) & 0x3F;
}
while (num_bytes--) {
-   w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
-   if (dev->buf_len) {
-   *dev->buf++ = w;
-   dev->buf_len--;
-   /*
-* Data reg in 2430, omap3 and
-* omap4 is 8 bit wide
-*/
-   if (dev->flags &
-OMAP_I2C_FLAG_16BIT_DATA_REG) {
-   if (dev->buf_len) {
-   *dev->buf++ = w >> 8;
-   dev->buf_len--;
-   }
-   }
-   } else {
+   if (!dev->buf_len) {
if (stat & OMAP_I2C_STAT_RRDY)
dev_err(dev->dev,
"RRDY IRQ while no data"
@@ -858,6 +843,21 @@ complete:
" requested\n");
break;
}
+
+   w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
+   *dev->buf++ = w;
+   dev->buf_len--;
+   /*
+* Data reg in 2430, omap3 and
+* omap4 is 8 bit wide
+*/
+   if (dev->flags &
+   OMAP_I2C_FLAG_16BIT_DATA_REG) {
+   if (dev->buf_len) {
+   *dev->buf++ = w >> 8;
+   dev->buf_len--;
+   }
+   }
}
omap_i2c_ack_stat(dev,
stat & (OMAP_I2C_STAT_RRDY | 
OMAP_I2C_STAT_RDR));
@@ -874,22 +874,7 @@ complete:
& 0x3F;
}
while (num_bytes--) {
-   w = 0;
-   if (dev->buf_len) {
-   w = *dev->buf++;
-   dev->buf_len--;
-   /*
-* Data reg in 2430, omap3 and
-* omap4 is 8 bit wide
-*/
-   if (dev->flags &
-OMAP_I2C_FLAG_16BIT_DATA_REG) {
-   if (dev->buf_len) {
-   w |= *dev->buf++ << 8;
-   dev->buf_len--;
-   }
-   }
-   } else {
+   if (!dev->buf_len) {
if (stat & OMAP_I2C_STAT_XRDY)
dev_err(dev->dev,
"XRDY IRQ while no "
@@ -901,6 +886,20 @@ complete:
break;
}
 
+   w = *dev->buf++;
+  

[PATCHv4 14/18] i2c: omap: always return IRQ_HANDLED

2012-07-03 Thread Shubhrajyoti D
From: Felipe Balbi 

otherwise we could get our IRQ line disabled due
to many spurious IRQs.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 7e3502e..81c1c1b 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -981,7 +981,7 @@ complete:
}
} while (stat);
 
-   return count ? IRQ_HANDLED : IRQ_NONE;
+   return IRQ_HANDLED;
 }
 
 static const struct i2c_algorithm omap_i2c_algo = {
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv4 16/18] i2c: omap: resize fifos before each message

2012-07-03 Thread Shubhrajyoti D
From: Felipe Balbi 

This patch will try to avoid the usage of
draining feature by reconfiguring the FIFO
the start condition of each message based
on the message's size.

By doing that, we will be better utilizing
the FIFO when doing big transfers.

While at that also drop the now uneeded
check for dev->buf_len as we always know
the amount of data to be transmitted.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   83 +
 1 files changed, 51 insertions(+), 32 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 5e3fb4c..f64916f 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -190,6 +190,7 @@ struct omap_i2c_dev {
u8  *regs;
size_t  buf_len;
struct i2c_adapter  adapter;
+   u8  threshold;
u8  fifo_size;  /* use as flag and value
 * fifo_size==0 implies no fifo
 * if set, should be trsh+1
@@ -415,13 +416,6 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll);
omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh);
 
-   if (dev->fifo_size) {
-   /* Note: setup required fifo size - 1. RTRSH and XTRSH */
-   buf = (dev->fifo_size - 1) << 8 | OMAP_I2C_BUF_RXFIF_CLR |
-   (dev->fifo_size - 1) | OMAP_I2C_BUF_TXFIF_CLR;
-   omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
-   }
-
/* Take the I2C module out of reset: */
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
 
@@ -482,6 +476,45 @@ static int omap_i2c_bus_clear(struct omap_i2c_dev *dev)
return omap_i2c_wait_for_bb(dev);
 }
 
+static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx)
+{
+   u16 buf;
+
+   if (dev->flags & OMAP_I2C_FLAG_NO_FIFO)
+   return;
+
+   /*
+* Set up notification threshold based on message size. We're doing
+* this to try and avoid draining feature as much as possible. Whenever
+* we have big messages to transfer (bigger than our total fifo size)
+* then we might use draining feature to transfer the remaining bytes.
+*/
+
+   dev->threshold = clamp(size, (u8) 1, dev->fifo_size);
+
+   buf = omap_i2c_read_reg(dev, OMAP_I2C_BUF_REG);
+
+   if (is_rx) {
+   /* Clear RX Threshold */
+   buf &= ~(0x3f << 8);
+   buf |= ((dev->threshold - 1) << 8) | OMAP_I2C_BUF_RXFIF_CLR;
+   } else {
+   /* Clear TX Threshold */
+   buf &= ~0x3f;
+   buf |= (dev->threshold - 1) | OMAP_I2C_BUF_TXFIF_CLR;
+   }
+
+   omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf);
+
+   if (dev->rev < OMAP_I2C_REV_ON_3630_4430)
+   dev->b_hw = 1; /* Enable hardware fixes */
+
+   /* calculate wakeup latency constraint for MPU */
+   if (dev->set_mpu_wkup_lat != NULL)
+   dev->latency = (100 * dev->threshold) /
+   (1000 * dev->speed / 8);
+}
+
 /*
  * Low level master read/write transaction.
  */
@@ -498,6 +531,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
if (msg->len == 0)
return -EINVAL;
 
+   dev->receiver = !!(msg->flags & I2C_M_RD);
+   omap_i2c_resize_fifo(dev, msg->len, dev->receiver);
+
omap_i2c_write_reg(dev, OMAP_I2C_SA_REG, msg->addr);
 
/* REVISIT: Could the STB bit of I2C_CON be used with probing? */
@@ -513,7 +549,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
 
INIT_COMPLETION(dev->cmd_complete);
dev->cmd_err = 0;
-   dev->receiver = !!(msg->flags & I2C_M_RD);
 
w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT;
 
@@ -779,12 +814,6 @@ static void omap_i2c_receive_data(struct omap_i2c_dev 
*dev, u8 num_bytes,
u16 w;
 
while (num_bytes--) {
-   if (!dev->buf_len) {
-   dev_err(dev->dev, "%s without data",
-   is_rdr ? "RDR" : "RRDY");
-   break;
-   }
-
w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
*dev->buf++ = w;
dev->buf_len--;
@@ -794,10 +823,8 @@ static void omap_i2c_receive_data(struct omap_i2c_dev 
*dev, u8 num_bytes,
 * omap4 is 8 bit wide
 */
if (dev->flags & OMAP_I2C_FLAG_16BIT_DATA_REG) {
-   if (dev->buf_len) {
-   

[PATCHv4 15/18] i2c: omap: simplify IRQ exit path

2012-07-03 Thread Shubhrajyoti D
From: Felipe Balbi 

instead of having multiple return points, use
a goto statement to make that clearer.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   20 
 1 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 81c1c1b..5e3fb4c 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -872,24 +872,21 @@ omap_i2c_isr(int this_irq, void *dev_id)
dev_dbg(dev->dev, "IRQ (ISR = 0x%04x)\n", stat);
if (count++ == 100) {
dev_warn(dev->dev, "Too much work in one IRQ\n");
-   omap_i2c_complete_cmd(dev, err);
-   return IRQ_HANDLED;
+   goto out;
}
 
 complete:
if (stat & OMAP_I2C_STAT_NACK) {
err |= OMAP_I2C_STAT_NACK;
omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
-   omap_i2c_complete_cmd(dev, err);
-   return IRQ_HANDLED;
+   goto out;
}
 
if (stat & OMAP_I2C_STAT_AL) {
dev_err(dev->dev, "Arbitration lost\n");
err |= OMAP_I2C_STAT_AL;
omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
-   omap_i2c_complete_cmd(dev, err);
-   return IRQ_HANDLED;
+   goto out;
}
 
/*
@@ -902,8 +899,7 @@ complete:
OMAP_I2C_STAT_XRDY |
OMAP_I2C_STAT_XDR |
OMAP_I2C_STAT_ARDY));
-   omap_i2c_complete_cmd(dev, err);
-   return IRQ_HANDLED;
+   goto out;
}
 
if (stat & OMAP_I2C_STAT_RDR) {
@@ -968,19 +964,19 @@ complete:
dev_err(dev->dev, "Receive overrun\n");
err |= OMAP_I2C_STAT_ROVR;
omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ROVR);
-   omap_i2c_complete_cmd(dev, err);
-   return IRQ_HANDLED;
+   goto out;
}
 
if (stat & OMAP_I2C_STAT_XUDF) {
dev_err(dev->dev, "Transmit underflow\n");
err |= OMAP_I2C_STAT_XUDF;
omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XUDF);
-   omap_i2c_complete_cmd(dev, err);
-   return IRQ_HANDLED;
+   goto out;
}
} while (stat);
 
+out:
+   omap_i2c_complete_cmd(dev, err);
return IRQ_HANDLED;
 }
 
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv4 11/18] i2c: omap: switch to platform_get_irq()

2012-07-03 Thread Shubhrajyoti D
From: Felipe Balbi 

that's a nice helper from drivers core which
will give us the exact IRQ number, instead
of a pointer to an IRQ resource.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   12 +++-
 1 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 30db822..46d099e 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1012,11 +1012,12 @@ omap_i2c_probe(struct platform_device *pdev)
 {
struct omap_i2c_dev *dev;
struct i2c_adapter  *adap;
-   struct resource *mem, *irq;
+   struct resource *mem;
struct omap_i2c_bus_platform_data *pdata = pdev->dev.platform_data;
struct device_node  *node = pdev->dev.of_node;
const struct of_device_id *match;
irq_handler_t isr;
+   int irq;
int r;
 
/* NOTE: driver uses the static register mapping */
@@ -1025,10 +1026,11 @@ omap_i2c_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "no mem resource?\n");
return -ENODEV;
}
-   irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-   if (!irq) {
+
+   irq = platform_get_irq(pdev, 0);
+   if (irq < 0) {
dev_err(&pdev->dev, "no irq resource?\n");
-   return -ENODEV;
+   return irq;
}
 
dev = devm_kzalloc(&pdev->dev, sizeof(struct omap_i2c_dev), GFP_KERNEL);
@@ -1062,7 +1064,7 @@ omap_i2c_probe(struct platform_device *pdev)
}
 
dev->dev = &pdev->dev;
-   dev->irq = irq->start;
+   dev->irq = irq;
 
platform_set_drvdata(pdev, dev);
init_completion(&dev->cmd_complete);
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv4 12/18] i2c: omap: bus: add a receiver flag

2012-07-03 Thread Shubhrajyoti D
From: Felipe Balbi 

that way we can ignore TX IRQs while in receiver
mode and ignore RX IRQs while in transmitter mode.

Signed-off-by: Felipe Balbi 
[Trivial formatting changes]
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |8 
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 46d099e..0fda3b7 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -196,6 +196,7 @@ struct omap_i2c_dev {
 */
u8  rev;
unsignedb_hw:1; /* bad h/w fixes */
+   unsignedreceiver:1; /* true when we're in receiver 
mode */
u16 iestate;/* Saved interrupt register */
u16 pscstate;
u16 scllstate;
@@ -512,6 +513,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
 
INIT_COMPLETION(dev->cmd_complete);
dev->cmd_err = 0;
+   dev->receiver = !!(msg->flags & I2C_M_RD);
 
w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT;
 
@@ -856,6 +858,12 @@ omap_i2c_isr(int this_irq, void *dev_id)
stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
stat &= bits;
 
+   /* If we're in receiver mode, ignore XDR/XRDY */
+   if (dev->receiver)
+   stat &= ~(OMAP_I2C_STAT_XDR | OMAP_I2C_STAT_XRDY);
+   else
+   stat &= ~(OMAP_I2C_STAT_RDR | OMAP_I2C_STAT_RRDY);
+
if (!stat) {
/* my work here is done */
return IRQ_HANDLED;
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv4 06/18] i2c: omap: split out [XR]DR and [XR]RDY

2012-07-03 Thread Shubhrajyoti D
From: Felipe Balbi 

While they do pretty much the same thing, there
are a few peculiarities. Specially WRT erratas,
it's best to split those out and re-factor the
read/write loop to another function which both
cases call.

This last part will be done on another patch.

While at that, also avoid an unncessary register
read since dev->fifo_len will always contain the
correct amount of data to be transferred.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
v4: use dev->buf_len as it is in sync with the remaining
bytes avoids a reg read thereby.

 drivers/i2c/busses/i2c-omap.c |  126 ++---
 1 files changed, 92 insertions(+), 34 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 1c1ee7a..5c2460d 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -820,36 +820,62 @@ complete:
return IRQ_HANDLED;
}
 
-   if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) {
+   if (stat & OMAP_I2C_STAT_RDR) {
u8 num_bytes = 1;
 
+   if (dev->fifo_size)
+   num_bytes = dev->buf_len;
+
+   while (num_bytes--) {
+   if (!dev->buf_len) {
+   dev_err(dev->dev,
+   "RDR IRQ while no data"
+   " requested\n");
+   break;
+   }
+
+   w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
+   *dev->buf++ = w;
+   dev->buf_len--;
+
+   /*
+* Data reg in 2430, omap3 and
+* omap4 is 8 bit wide
+*/
+   if (dev->flags &
+   OMAP_I2C_FLAG_16BIT_DATA_REG) {
+   if (dev->buf_len) {
+   *dev->buf++ = w >> 8;
+   dev->buf_len--;
+   }
+   }
+   }
+
if (dev->errata & I2C_OMAP_ERRATA_I207)
i2c_omap_errata_i207(dev, stat);
 
-   if (dev->fifo_size) {
-   if (stat & OMAP_I2C_STAT_RRDY)
-   num_bytes = dev->fifo_size;
-   else/* read RXSTAT on RDR interrupt */
-   num_bytes = (omap_i2c_read_reg(dev,
-   OMAP_I2C_BUFSTAT_REG)
-   >> 8) & 0x3F;
-   }
+   omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR);
+   continue;
+   }
+
+   if (stat & OMAP_I2C_STAT_RRDY) {
+   u8 num_bytes = 1;
+
+   if (dev->fifo_size)
+   num_bytes = dev->fifo_size;
+
while (num_bytes--) {
if (!dev->buf_len) {
-   if (stat & OMAP_I2C_STAT_RRDY)
-   dev_err(dev->dev,
+   dev_err(dev->dev,
"RRDY IRQ while no data"
-   " requested\n");
-   if (stat & OMAP_I2C_STAT_RDR)
-   dev_err(dev->dev,
-   "RDR IRQ while no data"
-   " requested\n");
+   " requested\n");
break;
}
 
w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
*dev->buf++ = w;
dev->buf_len--;
+
/*
 * Data reg in 2430, omap3 and
 * omap4 is 8 bit wide
@@ -862,36 +888,68 @@ complete:
}
}
}
-   omap_i2c_ack_stat(dev, (

[PATCHv4 09/18] i2c: omap: switch over to do {} while loop

2012-07-03 Thread Shubhrajyoti D
From: Felipe Balbi 

this will make sure that we execute at least once.
No functional changes otherwise.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   20 ++--
 1 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index dca6d3e..6c8f135 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -846,20 +846,28 @@ omap_i2c_isr(int this_irq, void *dev_id)
struct omap_i2c_dev *dev = dev_id;
u16 bits;
u16 stat;
-   int err, count = 0;
+   int err = 0, count = 0;
 
if (pm_runtime_suspended(dev->dev))
return IRQ_NONE;
 
-   bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
-   while ((stat = (omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG))) & bits) {
+   do {
+   bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
+   stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
+   stat &= bits;
+
+   if (!stat) {
+   /* my work here is done */
+   return IRQ_HANDLED;
+   }
+
dev_dbg(dev->dev, "IRQ (ISR = 0x%04x)\n", stat);
if (count++ == 100) {
dev_warn(dev->dev, "Too much work in one IRQ\n");
-   break;
+   omap_i2c_complete_cmd(dev, err);
+   return IRQ_HANDLED;
}
 
-   err = 0;
 complete:
/*
 * Ack the stat in one go, but [R/X]DR and [R/X]RDY should be
@@ -959,7 +967,7 @@ complete:
dev_err(dev->dev, "Transmit underflow\n");
dev->cmd_err |= OMAP_I2C_STAT_XUDF;
}
-   }
+   } while (stat);
 
return count ? IRQ_HANDLED : IRQ_NONE;
 }
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv4 01/18] i2c: omap: switch to devm_* API

2012-07-03 Thread Shubhrajyoti D
From: Felipe Balbi 

that helps deleting some boiler plate code
and lets driver-core manage our resources
for us.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   41 -
 1 files changed, 12 insertions(+), 29 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 2500f19..0946be5 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -962,7 +962,7 @@ omap_i2c_probe(struct platform_device *pdev)
 {
struct omap_i2c_dev *dev;
struct i2c_adapter  *adap;
-   struct resource *mem, *irq, *ioarea;
+   struct resource *mem, *irq;
struct omap_i2c_bus_platform_data *pdata = pdev->dev.platform_data;
struct device_node  *node = pdev->dev.of_node;
const struct of_device_id *match;
@@ -981,17 +981,16 @@ omap_i2c_probe(struct platform_device *pdev)
return -ENODEV;
}
 
-   ioarea = request_mem_region(mem->start, resource_size(mem),
-   pdev->name);
-   if (!ioarea) {
-   dev_err(&pdev->dev, "I2C region already claimed\n");
-   return -EBUSY;
+   dev = devm_kzalloc(&pdev->dev, sizeof(struct omap_i2c_dev), GFP_KERNEL);
+   if (!dev) {
+   dev_err(&pdev->dev, "Menory allocation failed\n");
+   return -ENOMEM;
}
 
-   dev = kzalloc(sizeof(struct omap_i2c_dev), GFP_KERNEL);
-   if (!dev) {
-   r = -ENOMEM;
-   goto err_release_region;
+   dev->base = devm_request_and_ioremap(&pdev->dev, mem);
+   if (!dev->base) {
+   dev_err(&pdev->dev, "I2C region already claimed\n");
+   return -ENOMEM;
}
 
match = of_match_device(of_match_ptr(omap_i2c_of_match), &pdev->dev);
@@ -1014,11 +1013,6 @@ omap_i2c_probe(struct platform_device *pdev)
 
dev->dev = &pdev->dev;
dev->irq = irq->start;
-   dev->base = ioremap(mem->start, resource_size(mem));
-   if (!dev->base) {
-   r = -ENOMEM;
-   goto err_free_mem;
-   }
 
platform_set_drvdata(pdev, dev);
init_completion(&dev->cmd_complete);
@@ -1076,7 +1070,8 @@ omap_i2c_probe(struct platform_device *pdev)
 
isr = (dev->rev < OMAP_I2C_OMAP1_REV_2) ? omap_i2c_omap1_isr :
   omap_i2c_isr;
-   r = request_irq(dev->irq, isr, IRQF_NO_SUSPEND, pdev->name, dev);
+   r = devm_request_irq(&pdev->dev, dev->irq, isr, IRQF_NO_SUSPEND,
+pdev->name, dev);
 
if (r) {
dev_err(dev->dev, "failure requesting irq %i\n", dev->irq);
@@ -1100,7 +1095,7 @@ omap_i2c_probe(struct platform_device *pdev)
r = i2c_add_numbered_adapter(adap);
if (r) {
dev_err(dev->dev, "failure adding adapter\n");
-   goto err_free_irq;
+   goto err_unuse_clocks;
}
 
of_i2c_register_devices(adap);
@@ -1109,18 +1104,12 @@ omap_i2c_probe(struct platform_device *pdev)
 
return 0;
 
-err_free_irq:
-   free_irq(dev->irq, dev);
 err_unuse_clocks:
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
pm_runtime_put(dev->dev);
-   iounmap(dev->base);
pm_runtime_disable(&pdev->dev);
 err_free_mem:
platform_set_drvdata(pdev, NULL);
-   kfree(dev);
-err_release_region:
-   release_mem_region(mem->start, resource_size(mem));
 
return r;
 }
@@ -1128,12 +1117,10 @@ err_release_region:
 static int __devexit omap_i2c_remove(struct platform_device *pdev)
 {
struct omap_i2c_dev *dev = platform_get_drvdata(pdev);
-   struct resource *mem;
int ret;
 
platform_set_drvdata(pdev, NULL);
 
-   free_irq(dev->irq, dev);
i2c_del_adapter(&dev->adapter);
ret = pm_runtime_get_sync(&pdev->dev);
if (IS_ERR_VALUE(ret))
@@ -1142,10 +1129,6 @@ static int __devexit omap_i2c_remove(struct 
platform_device *pdev)
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
pm_runtime_put(&pdev->dev);
pm_runtime_disable(&pdev->dev);
-   iounmap(dev->base);
-   kfree(dev);
-   mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   release_mem_region(mem->start, resource_size(mem));
return 0;
 }
 
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv4 08/18] i2c: omap: re-factor receive/transmit data loop

2012-07-03 Thread Shubhrajyoti D
From: Felipe Balbi 

re-factor the common parts to a separate function,
so that code is easier to read and understand.

No functional changes.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |  204 
 1 files changed, 82 insertions(+), 122 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 1715c35..dca6d3e 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -771,12 +771,81 @@ static int errata_omap3_i462(struct omap_i2c_dev *dev)
return 0;
 }
 
+static void omap_i2c_receive_data(struct omap_i2c_dev *dev, u8 num_bytes,
+   bool is_rdr)
+{
+   u16 w;
+
+   while (num_bytes--) {
+   if (!dev->buf_len) {
+   dev_err(dev->dev, "%s without data",
+   is_rdr ? "RDR" : "RRDY");
+   break;
+   }
+
+   w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
+   *dev->buf++ = w;
+   dev->buf_len--;
+
+   /*
+* Data reg in 2430, omap3 and
+* omap4 is 8 bit wide
+*/
+   if (dev->flags & OMAP_I2C_FLAG_16BIT_DATA_REG) {
+   if (dev->buf_len) {
+   *dev->buf++ = w >> 8;
+   dev->buf_len--;
+   }
+   }
+   }
+}
+
+static int omap_i2c_transmit_data(struct omap_i2c_dev *dev, u8 num_bytes,
+   bool is_xdr)
+{
+   u16 w;
+
+   while (num_bytes--) {
+   if (!dev->buf_len) {
+   dev_err(dev->dev, "%s without data",
+   is_xdr ? "XDR" : "XRDY");
+   break;
+   }
+
+   w = *dev->buf++;
+   dev->buf_len--;
+
+   /*
+* Data reg in 2430, omap3 and
+* omap4 is 8 bit wide
+*/
+   if (dev->flags & OMAP_I2C_FLAG_16BIT_DATA_REG) {
+   if (dev->buf_len) {
+   w |= *dev->buf++ << 8;
+   dev->buf_len--;
+   }
+   }
+
+   if (dev->errata & I2C_OMAP_ERRATA_I462) {
+   int ret;
+
+   ret = errata_omap3_i462(dev);
+   if (ret < 0)
+   return ret;
+   }
+
+   omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
+   }
+
+   return 0;
+}
+
 static irqreturn_t
 omap_i2c_isr(int this_irq, void *dev_id)
 {
struct omap_i2c_dev *dev = dev_id;
u16 bits;
-   u16 stat, w;
+   u16 stat;
int err, count = 0;
 
if (pm_runtime_suspended(dev->dev))
@@ -829,30 +898,7 @@ complete:
if (dev->fifo_size)
num_bytes = dev->buf_len;
 
-   while (num_bytes--) {
-   if (!dev->buf_len) {
-   dev_err(dev->dev,
-   "RDR IRQ while no data"
-   " requested\n");
-   break;
-   }
-
-   w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
-   *dev->buf++ = w;
-   dev->buf_len--;
-
-   /*
-* Data reg in 2430, omap3 and
-* omap4 is 8 bit wide
-*/
-   if (dev->flags &
-   OMAP_I2C_FLAG_16BIT_DATA_REG) {
-   if (dev->buf_len) {
-   *dev->buf++ = w >> 8;
-   dev->buf_len--;
-   }
-   }
-   }
+   omap_i2c_receive_data(dev, num_bytes, true);
 
if (dev->errata & I2C_OMAP_ERRATA_I207)
i2c_omap_errata_i207(dev, stat);
@@ -867,77 +913,22 @@ complete:
if (dev->fifo_size)
num_bytes = dev->fifo_size;
 
-   while (num_bytes--) {
-   if (!dev->buf_len) {
-   

[PATCH RFC] spi: omap2-mcspi: Fix the dma_unmap warning

2012-07-05 Thread Shubhrajyoti D
The dma_map and dma_unmap should have same parameter
passed otherwise we get the below warn.

ks8851 spi1.0: DMA-API: device driver tries to free DMA memory it has not 
allocated [device address=0x9f22]

[2.066925] Modules linked in:
[2.070312]
[2.071929] [] (unwind_backtrace+0x0/0x130) from [] 
(warn_slowpath_common+0x4c/0x64)
[2.081909] [] (warn_slowpath_common+0x4c/0x64) from [] 
(warn_slowpath_fmt+0x30/0x40)
[2.091949] [] (warn_slowpath_fmt+0x30/0x40) from [] 
(check_unmap+0x6d0/0x7b0)
[2.101348] [] (check_unmap+0x6d0/0x7b0) from [] 
(debug_dma_unmap_page+0x64/0x70)
[2.111053] [] (debug_dma_unmap_page+0x64/0x70) from [] 
(omap2_mcspi_txrx_dma+0x2d8/0x4fc)
[2.121582] [] (omap2_mcspi_txrx_dma+0x2d8/0x4fc) from 
[] (omap2_mcspi_work.clone.4+0xf0/0x290)
[2.132537] [] (omap2_mcspi_work.clone.4+0xf0/0x290) from 
[] (omap2_mcspi_transfer_one_message+0x288/0x438)
[2.144592] [] (omap2_mcspi_transfer_one_message+0x288/0x438) from 
[] (spi_pump_messages+0x100/0x160)
[2.156127] [] (spi_pump_messages+0x100/0x160) from [] 
(kthread_worker_fn+0xac/0x180)
[2.166168] [] (kthread_worker_fn+0xac/0x180) from [] 
(kthread+0x90/0x9c)
[2.175140] [] (kthread+0x90/0x9c) from [] 
(kernel_thread_exit+0x0/0x8)
[2.183898] ---[ end trace d1830ce6e44292f2 ]---

Fix the warn by changing the unmap parameter to the one used while doing
dma_map.

Reported-by: Russell King 
Signed-off-by: Shubhrajyoti D 
---
 drivers/spi/spi-omap2-mcspi.c |6 --
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index 0c73dd4..37ccdb7 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -388,7 +388,8 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct 
spi_transfer *xfer)
 
if (tx != NULL) {
wait_for_completion(&mcspi_dma->dma_tx_completion);
-   dma_unmap_single(&spi->dev, xfer->tx_dma, count, DMA_TO_DEVICE);
+   dma_unmap_single(mcspi->dev, xfer->tx_dma, count,
+DMA_TO_DEVICE);
 
/* for TX_ONLY mode, be sure all words have shifted out */
if (rx == NULL) {
@@ -403,7 +404,8 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct 
spi_transfer *xfer)
 
if (rx != NULL) {
wait_for_completion(&mcspi_dma->dma_rx_completion);
-   dma_unmap_single(&spi->dev, xfer->rx_dma, count, 
DMA_FROM_DEVICE);
+   dma_unmap_single(mcspi->dev, xfer->rx_dma, count,
+DMA_FROM_DEVICE);
omap2_mcspi_set_enable(spi, 0);
 
if (l & OMAP2_MCSPI_CHCONF_TURBO) {
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv5 13/18] i2c: omap: simplify errata check

2012-07-19 Thread Shubhrajyoti D
From: Felipe Balbi 

omap_i2c_dev is allocated with kzalloc(),
so we need not initialize b_hw to zero.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index d732865..19f6048 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -1092,9 +1092,7 @@ omap_i2c_probe(struct platform_device *pdev)
 
dev->fifo_size = (dev->fifo_size / 2);
 
-   if (dev->rev >= OMAP_I2C_REV_ON_3630_4430)
-   dev->b_hw = 0; /* Disable hardware fixes */
-   else
+   if (dev->rev < OMAP_I2C_REV_ON_3630_4430)
dev->b_hw = 1; /* Enable hardware fixes */
 
/* calculate wakeup latency constraint for MPU */
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv5 08/18] i2c: omap: re-factor receive/transmit data loop

2012-07-19 Thread Shubhrajyoti D
From: Felipe Balbi 

re-factor the common parts to a separate function,
so that code is easier to read and understand.

No functional changes.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |  204 
 1 files changed, 82 insertions(+), 122 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 6f98812..700f018 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -749,12 +749,81 @@ static int errata_omap3_i462(struct omap_i2c_dev *dev)
return 0;
 }
 
+static void omap_i2c_receive_data(struct omap_i2c_dev *dev, u8 num_bytes,
+   bool is_rdr)
+{
+   u16 w;
+
+   while (num_bytes--) {
+   if (!dev->buf_len) {
+   dev_err(dev->dev, "%s without data",
+   is_rdr ? "RDR" : "RRDY");
+   break;
+   }
+
+   w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
+   *dev->buf++ = w;
+   dev->buf_len--;
+
+   /*
+* Data reg in 2430, omap3 and
+* omap4 is 8 bit wide
+*/
+   if (dev->flags & OMAP_I2C_FLAG_16BIT_DATA_REG) {
+   if (dev->buf_len) {
+   *dev->buf++ = w >> 8;
+   dev->buf_len--;
+   }
+   }
+   }
+}
+
+static int omap_i2c_transmit_data(struct omap_i2c_dev *dev, u8 num_bytes,
+   bool is_xdr)
+{
+   u16 w;
+
+   while (num_bytes--) {
+   if (!dev->buf_len) {
+   dev_err(dev->dev, "%s without data",
+   is_xdr ? "XDR" : "XRDY");
+   break;
+   }
+
+   w = *dev->buf++;
+   dev->buf_len--;
+
+   /*
+* Data reg in 2430, omap3 and
+* omap4 is 8 bit wide
+*/
+   if (dev->flags & OMAP_I2C_FLAG_16BIT_DATA_REG) {
+   if (dev->buf_len) {
+   w |= *dev->buf++ << 8;
+   dev->buf_len--;
+   }
+   }
+
+   if (dev->errata & I2C_OMAP_ERRATA_I462) {
+   int ret;
+
+   ret = errata_omap3_i462(dev);
+   if (ret < 0)
+   return ret;
+   }
+
+   omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
+   }
+
+   return 0;
+}
+
 static irqreturn_t
 omap_i2c_isr(int this_irq, void *dev_id)
 {
struct omap_i2c_dev *dev = dev_id;
u16 bits;
-   u16 stat, w;
+   u16 stat;
int err, count = 0;
 
if (pm_runtime_suspended(dev->dev))
@@ -807,30 +876,7 @@ complete:
if (dev->fifo_size)
num_bytes = dev->buf_len;
 
-   while (num_bytes--) {
-   if (!dev->buf_len) {
-   dev_err(dev->dev,
-   "RDR IRQ while no data"
-   " requested\n");
-   break;
-   }
-
-   w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
-   *dev->buf++ = w;
-   dev->buf_len--;
-
-   /*
-* Data reg in 2430, omap3 and
-* omap4 is 8 bit wide
-*/
-   if (dev->flags &
-   OMAP_I2C_FLAG_16BIT_DATA_REG) {
-   if (dev->buf_len) {
-   *dev->buf++ = w >> 8;
-   dev->buf_len--;
-   }
-   }
-   }
+   omap_i2c_receive_data(dev, num_bytes, true);
 
if (dev->errata & I2C_OMAP_ERRATA_I207)
i2c_omap_errata_i207(dev, stat);
@@ -845,77 +891,22 @@ complete:
if (dev->fifo_size)
num_bytes = dev->fifo_size;
 
-   while (num_bytes--) {
-   if (!dev->buf_len) {
-   

[PATCHv5 05/18] i2c: omap: simplify omap_i2c_ack_stat()

2012-07-19 Thread Shubhrajyoti D
From: Felipe Balbi 

stat & BIT(1) is the same as BIT(1), so let's
simplify things a bit by removing "stat &" from
all omap_i2c_ack_stat() calls.

Code snippet (extremely simplified):

if (stat & NACK) {
...
omap_i2c_ack_stat(dev, stat & NACK);
}

if (stat & RDR) {
...
omap_i2c_ack_stat(dev, stat & RDR);
}

and so on. The tricky place is only WRT errata handling, for example:

if (*stat & (NACK | AL)) {
omap_i2c_ack_stat(dev, *stat & (XRDY | XDR));
...
}

but in this case, the errata says we must clear XRDY and XDR if that
errata triggers, so if they just got enabled or not, it doesn't matter.

Another tricky place is RDR | RRDY (likewise for XDR | XRDY):

if (stat & (RDR | RRDY)) {
...
omap_i2c_ack_stat(dev, stat & (RDR | RRDY));
}

again here there will be no issues because those IRQs never fire
simultaneously and one will only after after we have handled the
previous, that's because the same FIFO is used anyway and we won't shift
data into FIFO until we tell the IP "hey, I'm done with the FIFO, you
can shift more data"

Signed-off-by: Felipe Balbi 
Reviewed-by : Santosh Shilimkar 
[Added the explaination from the discurssion to the commit logs]
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   19 ++-
 1 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 323d52e..940ba64 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -728,7 +728,7 @@ static int errata_omap3_i462(struct omap_i2c_dev *dev, u16 
*stat, int *err)
 
while (--timeout && !(*stat & OMAP_I2C_STAT_XUDF)) {
if (*stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
-   omap_i2c_ack_stat(dev, *stat & (OMAP_I2C_STAT_XRDY |
+   omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
OMAP_I2C_STAT_XDR));
return -ETIMEDOUT;
}
@@ -789,10 +789,11 @@ complete:
 */
if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK |
OMAP_I2C_STAT_AL)) {
-   omap_i2c_ack_stat(dev, stat &
-   (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
-   OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR |
-   OMAP_I2C_STAT_ARDY));
+   omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY |
+   OMAP_I2C_STAT_RDR |
+   OMAP_I2C_STAT_XRDY |
+   OMAP_I2C_STAT_XDR |
+   OMAP_I2C_STAT_ARDY));
omap_i2c_complete_cmd(dev, err);
return IRQ_HANDLED;
}
@@ -839,8 +840,8 @@ complete:
}
}
}
-   omap_i2c_ack_stat(dev,
-   stat & (OMAP_I2C_STAT_RRDY | 
OMAP_I2C_STAT_RDR));
+   omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY |
+   OMAP_I2C_STAT_RDR));
continue;
}
 
@@ -887,8 +888,8 @@ complete:
 
omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
}
-   omap_i2c_ack_stat(dev,
-   stat & (OMAP_I2C_STAT_XRDY | 
OMAP_I2C_STAT_XDR));
+   omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
+   OMAP_I2C_STAT_XDR));
continue;
}
 
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv5 14/18] i2c: omap: always return IRQ_HANDLED

2012-07-19 Thread Shubhrajyoti D
From: Felipe Balbi 

otherwise we could get our IRQ line disabled due
to many spurious IRQs.

Signed-off-by: Felipe Balbi 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 19f6048..6847a98 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -959,7 +959,7 @@ complete:
}
} while (stat);
 
-   return count ? IRQ_HANDLED : IRQ_NONE;
+   return IRQ_HANDLED;
 }
 
 static const struct i2c_algorithm omap_i2c_algo = {
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv5 02/18] i2c: omap: simplify num_bytes handling

2012-07-19 Thread Shubhrajyoti D
From: Felipe Balbi 

trivial patch, no functional changes

If the fifo is disabled or fifo_size is 0 the num_bytes
is set to 1. Else it is set to fifo_size or in case of a
draining interrupt the remaining bytes in the buff stat.
So the zero check is redundant and can be safely optimised.

Signed-off-by: Felipe Balbi 
Reviewed-by : Santosh Shilimkar 
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |6 ++
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 788c16c..520f3ea 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -809,8 +809,7 @@ complete:
OMAP_I2C_BUFSTAT_REG)
>> 8) & 0x3F;
}
-   while (num_bytes) {
-   num_bytes--;
+   while (num_bytes--) {
w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG);
if (dev->buf_len) {
*dev->buf++ = w;
@@ -852,8 +851,7 @@ complete:
OMAP_I2C_BUFSTAT_REG)
& 0x3F;
}
-   while (num_bytes) {
-   num_bytes--;
+   while (num_bytes--) {
w = 0;
if (dev->buf_len) {
w = *dev->buf++;
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv5 12/18] i2c: omap: bus: add a receiver flag

2012-07-19 Thread Shubhrajyoti D
From: Felipe Balbi 

that way we can ignore TX IRQs while in receiver
mode and ignore RX IRQs while in transmitter mode.

Signed-off-by: Felipe Balbi 
[Trivial formatting changes]
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |8 
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 71047dd..d732865 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -199,6 +199,7 @@ struct omap_i2c_dev {
 */
u8  rev;
unsignedb_hw:1; /* bad h/w fixes */
+   unsignedreceiver:1; /* true when we're in receiver 
mode */
u16 iestate;/* Saved interrupt register */
u16 pscstate;
u16 scllstate;
@@ -492,6 +493,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
 
INIT_COMPLETION(dev->cmd_complete);
dev->cmd_err = 0;
+   dev->receiver = !!(msg->flags & I2C_M_RD);
 
w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT;
 
@@ -834,6 +836,12 @@ omap_i2c_isr(int this_irq, void *dev_id)
stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
stat &= bits;
 
+   /* If we're in receiver mode, ignore XDR/XRDY */
+   if (dev->receiver)
+   stat &= ~(OMAP_I2C_STAT_XDR | OMAP_I2C_STAT_XRDY);
+   else
+   stat &= ~(OMAP_I2C_STAT_RDR | OMAP_I2C_STAT_RRDY);
+
if (!stat) {
/* my work here is done */
return IRQ_HANDLED;
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv5 10/18] i2c: omap: ack IRQ in parts

2012-07-19 Thread Shubhrajyoti D
From: Felipe Balbi 

According to flow diagrams on OMAP TRMs,
we should ACK the IRQ as they happen.

Signed-off-by: Felipe Balbi 
[ack the stat OMAP_I2C_STAT_AL in case of arbitration lost]
Signed-off-by: Shubhrajyoti D 
---
v5 - ack the OMAP_I2C_STAT_AL.

 drivers/i2c/busses/i2c-omap.c |   28 
 1 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 78fc274..62ad126 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -847,21 +847,19 @@ omap_i2c_isr(int this_irq, void *dev_id)
}
 
 complete:
-   /*
-* Ack the stat in one go, but [R/X]DR and [R/X]RDY should be
-* acked after the data operation is complete.
-* Ref: TRM SWPU114Q Figure 18-31
-*/
-   omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat &
-   ~(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
-   OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
-
-   if (stat & OMAP_I2C_STAT_NACK)
+   if (stat & OMAP_I2C_STAT_NACK) {
err |= OMAP_I2C_STAT_NACK;
+   omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK);
+   omap_i2c_complete_cmd(dev, err);
+   return IRQ_HANDLED;
+   }
 
if (stat & OMAP_I2C_STAT_AL) {
dev_err(dev->dev, "Arbitration lost\n");
err |= OMAP_I2C_STAT_AL;
+   omap_i2c_ack_stat(dev, OMAP_I2C_STAT_AL);
+   omap_i2c_complete_cmd(dev, err);
+   return IRQ_HANDLED;
}
 
/*
@@ -938,12 +936,18 @@ complete:
 
if (stat & OMAP_I2C_STAT_ROVR) {
dev_err(dev->dev, "Receive overrun\n");
-   dev->cmd_err |= OMAP_I2C_STAT_ROVR;
+   err |= OMAP_I2C_STAT_ROVR;
+   omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ROVR);
+   omap_i2c_complete_cmd(dev, err);
+   return IRQ_HANDLED;
}
 
if (stat & OMAP_I2C_STAT_XUDF) {
dev_err(dev->dev, "Transmit underflow\n");
-   dev->cmd_err |= OMAP_I2C_STAT_XUDF;
+   err |= OMAP_I2C_STAT_XUDF;
+   omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XUDF);
+   omap_i2c_complete_cmd(dev, err);
+   return IRQ_HANDLED;
}
} while (stat);
 
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCHv5 07/18] i2c: omap: improve i462 errata handling

2012-07-19 Thread Shubhrajyoti D
From: Felipe Balbi 

Make it not depend on ISR's local variables
in order to make it easier to re-factor the
transmit data loop.
Also since we are waiting for XUDF(Transmitter underflow) just before
writing data lets not flag the underflow.
This is anyways going to go once we write
the data.

Signed-off-by: Felipe Balbi 
[Avoid flagging the XUDF]
Signed-off-by: Shubhrajyoti D 
---
 drivers/i2c/busses/i2c-omap.c |   43 
 1 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 5f6d9c5..6f98812 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -722,27 +722,30 @@ omap_i2c_omap1_isr(int this_irq, void *dev_id)
  * data to DATA_REG. Otherwise some data bytes can be lost while transferring
  * them from the memory to the I2C interface.
  */
-static int errata_omap3_i462(struct omap_i2c_dev *dev, u16 *stat, int *err)
+static int errata_omap3_i462(struct omap_i2c_dev *dev)
 {
unsigned long timeout = 1;
+   u16 stat;
 
-   while (--timeout && !(*stat & OMAP_I2C_STAT_XUDF)) {
-   if (*stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
+   do {
+   stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
+   if (stat & OMAP_I2C_STAT_XUDF)
+   break;
+
+   if (stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
OMAP_I2C_STAT_XDR));
-   return -ETIMEDOUT;
+   return -EIO;
}
 
cpu_relax();
-   *stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
-   }
+   } while (--timeout);
 
if (!timeout) {
dev_err(dev->dev, "timeout waiting on XUDF bit\n");
return 0;
}
 
-   *err |= OMAP_I2C_STAT_XUDF;
return 0;
 }
 
@@ -900,9 +903,16 @@ complete:
}
}
 
-   if ((dev->errata & I2C_OMAP_ERRATA_I462) &&
-   errata_omap3_i462(dev, &stat, &err))
-   goto complete;
+   if (dev->errata & I2C_OMAP_ERRATA_I462) {
+   int ret;
+
+   ret = errata_omap3_i462(dev);
+   stat = omap_i2c_read_reg(dev,
+   OMAP_I2C_STAT_REG);
+
+   if (ret < 0)
+   goto complete;
+   }
 
omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
}
@@ -940,9 +950,16 @@ complete:
}
}
 
-   if ((dev->errata & I2C_OMAP_ERRATA_I462) &&
-   errata_omap3_i462(dev, &stat, &err))
-   goto complete;
+   if (dev->errata & I2C_OMAP_ERRATA_I462) {
+   int ret;
+
+   ret = errata_omap3_i462(dev);
+   stat = omap_i2c_read_reg(dev,
+   OMAP_I2C_STAT_REG);
+
+   if (ret < 0)
+   goto complete;
+   }
 
omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
}
-- 
1.7.5.4

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


  1   2   3   4   5   6   >