Re: [RFT PATCH 1/2] i2c: tegra: update CONFIG_LOAD for new conifiguration

2015-07-16 Thread Laxman Dewangan

Wolfram,

On Thursday 09 July 2015 02:06 AM, Stephen Warren wrote:

On 06/30/2015 04:54 AM, Laxman Dewangan wrote:

Once the new configuration is set on the conifg register of
I2C controller, it is require to update the CONFIG_LOAD register
to transfer the new SW configuration to actual HW internal
registers that would be used in the actual logic.


Can you please review this series?

Thanks,
Laxman

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


Re: [RFT PATCH 1/2] i2c: tegra: update CONFIG_LOAD for new conifiguration

2015-07-08 Thread Laxman Dewangan


On Thursday 09 July 2015 02:06 AM, Stephen Warren wrote:

On 06/30/2015 04:54 AM, Laxman Dewangan wrote:



Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
Signed-off-by: Chaitanya Bandi ban...@nvidia.com


I'm not sure why Chaitanya's S-o-b is there and listed last if he's 
not the patch author. If he wrote the patch, he should be the git 
author and his S-o-b should be first. If he didn't and you simply 
based this patch on work by Chaitanya, then his S-o-b probably 
shouldn't be present, and yours would be last since you're submitting 
the patch.


The patch I created is based on Chaitanya's work, edited on his work to 
match with mainline.





---
Stephen/Andrew,
I need help on testing this on other platform. I tested this on T210.


I'm puzzled how this was tested on T210, since it isn't supported 
upstream yet.


We tested this as:
- K318 kernel release + i2c subsystem from linux-next in downstream boards.
- Chrome-OS team on smaug with their tree.



The series,
Tested-by: Stephen Warren swar...@nvidia.com


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


[RFT PATCH 1/2] i2c: tegra: update CONFIG_LOAD for new conifiguration

2015-06-30 Thread Laxman Dewangan
Once the new configuration is set on the conifg register of
I2C controller, it is require to update the CONFIG_LOAD register
to transfer the new SW configuration to actual HW internal
registers that would be used in the actual logic.

It is like, SW is programming only shadow registers through
regular configuration and when these load_config bit fields
are set to 1, it causes the regular/shadows registers
configuration transferred to the HW internal active registers.
So SW has to set these bit fields at the end of all regular
registers configuration. And these config_load bits are HW
auto-clear bits. HW clears these bit fields once the register
configuration is moved to HW internal active registers. So SW
has to wait until these bits are auto-cleared before going
for any further programming

This mechanism is supported on T124 and after this SoCs.

This is based on change done by
Chaitanya Bandi ban...@nvidia.com

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
Signed-off-by: Chaitanya Bandi ban...@nvidia.com
---
Stephen/Andrew,
I need help on testing this on other platform. I tested this on T210.

 drivers/i2c/busses/i2c-tegra.c | 35 +++
 1 file changed, 35 insertions(+)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 1bcd75e..53f816b 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -100,6 +100,12 @@
 #define I2C_HEADER_CONTINUE_XFER   (115)
 #define I2C_HEADER_MASTER_ADDR_SHIFT   12
 #define I2C_HEADER_SLAVE_ADDR_SHIFT1
+
+#define I2C_CONFIG_LOAD0x08C
+#define I2C_MSTR_CONFIG_LOAD   (1  0)
+#define I2C_SLV_CONFIG_LOAD(1  1)
+#define I2C_TIMEOUT_CONFIG_LOAD(1  2)
+
 /*
  * msg_end_type: The bus control which need to be send at end of transfer.
  * @MSG_END_STOP: Send stop pulse at end of transfer.
@@ -121,6 +127,8 @@ enum msg_end_type {
  * @has_single_clk_source: The i2c controller has single clock source. Tegra30
  * and earlier Socs has two clock sources i.e. div-clk and
  * fast-clk.
+ * @has_config_load_reg: Has the config load register to load the new
+ * configuration.
  * @clk_divisor_hs_mode: Clock divisor in HS mode.
  * @clk_divisor_std_fast_mode: Clock divisor in standard/fast mode. It is
  * applicable if there is no fast clock source i.e. single clock
@@ -131,6 +139,7 @@ struct tegra_i2c_hw_feature {
bool has_continue_xfer_support;
bool has_per_pkt_xfer_complete_irq;
bool has_single_clk_source;
+   bool has_config_load_reg;
int clk_divisor_hs_mode;
int clk_divisor_std_fast_mode;
 };
@@ -410,6 +419,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
u32 val;
int err = 0;
u32 clk_divisor;
+   unsigned long timeout = jiffies + HZ;
 
err = tegra_i2c_clock_enable(i2c_dev);
if (err  0) {
@@ -451,6 +461,18 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
if (tegra_i2c_flush_fifos(i2c_dev))
err = -ETIMEDOUT;
 
+   if (i2c_dev-hw-has_config_load_reg) {
+   i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, I2C_CONFIG_LOAD);
+   while (i2c_readl(i2c_dev, I2C_CONFIG_LOAD) != 0) {
+   if (time_after(jiffies, timeout)) {
+   dev_warn(i2c_dev-dev,
+   timeout waiting for config load\n);
+   return -ETIMEDOUT;
+   }
+   msleep(1);
+   }
+   }
+
tegra_i2c_clock_disable(i2c_dev);
 
if (i2c_dev-irq_disabled) {
@@ -675,6 +697,7 @@ static const struct tegra_i2c_hw_feature tegra20_i2c_hw = {
.has_single_clk_source = false,
.clk_divisor_hs_mode = 3,
.clk_divisor_std_fast_mode = 0,
+   .has_config_load_reg = false,
 };
 
 static const struct tegra_i2c_hw_feature tegra30_i2c_hw = {
@@ -683,6 +706,7 @@ static const struct tegra_i2c_hw_feature tegra30_i2c_hw = {
.has_single_clk_source = false,
.clk_divisor_hs_mode = 3,
.clk_divisor_std_fast_mode = 0,
+   .has_config_load_reg = false,
 };
 
 static const struct tegra_i2c_hw_feature tegra114_i2c_hw = {
@@ -691,10 +715,21 @@ static const struct tegra_i2c_hw_feature tegra114_i2c_hw 
= {
.has_single_clk_source = true,
.clk_divisor_hs_mode = 1,
.clk_divisor_std_fast_mode = 0x19,
+   .has_config_load_reg = false,
+};
+
+static const struct tegra_i2c_hw_feature tegra124_i2c_hw = {
+   .has_continue_xfer_support = true,
+   .has_per_pkt_xfer_complete_irq = true,
+   .has_single_clk_source = true,
+   .clk_divisor_hs_mode = 1,
+   .clk_divisor_std_fast_mode = 0x19,
+   .has_config_load_reg = true,
 };
 
 /* Match table for of_platform binding */
 static const

[RFT PATCH 2/2] i2c: tegra: add support for fast plus (FM+) mode clock rate

2015-06-30 Thread Laxman Dewangan
Tegra I2C controller required to configure the clock divisor
register inside controller to different value based on the clock
speed. The recommended clock divisor for the I2C controller for
standard/fast mode is 0x19 and for fast-mode plus is 0x10.

Add support to configure clock divisor register of I2C controller
based on bus clock rate.

This clock divisor is supported form T114 onwards.

This is based on change done by
Chaitanya Bandi ban...@nvidia.com

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
Signed-off-by: Chaitanya Bandi ban...@nvidia.com
---
Stephen/Andrew,
I need help on testing this on other platform. I tested this on T210.

 drivers/i2c/busses/i2c-tegra.c | 17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 53f816b..6a77a93 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -142,6 +142,7 @@ struct tegra_i2c_hw_feature {
bool has_config_load_reg;
int clk_divisor_hs_mode;
int clk_divisor_std_fast_mode;
+   u16 clk_divisor_fast_plus_mode;
 };
 
 /**
@@ -181,6 +182,7 @@ struct tegra_i2c_dev {
size_t msg_buf_remaining;
int msg_read;
u32 bus_clk_rate;
+   u16 clk_divisor_non_hs_mode;
bool is_suspended;
 };
 
@@ -441,7 +443,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 
/* Make sure clock divisor programmed correctly */
clk_divisor = i2c_dev-hw-clk_divisor_hs_mode;
-   clk_divisor |= i2c_dev-hw-clk_divisor_std_fast_mode 
+   clk_divisor |= i2c_dev-clk_divisor_non_hs_mode 
I2C_CLK_DIVISOR_STD_FAST_MODE_SHIFT;
i2c_writel(i2c_dev, clk_divisor, I2C_CLK_DIVISOR);
 
@@ -697,6 +699,7 @@ static const struct tegra_i2c_hw_feature tegra20_i2c_hw = {
.has_single_clk_source = false,
.clk_divisor_hs_mode = 3,
.clk_divisor_std_fast_mode = 0,
+   .clk_divisor_fast_plus_mode = 0,
.has_config_load_reg = false,
 };
 
@@ -706,6 +709,7 @@ static const struct tegra_i2c_hw_feature tegra30_i2c_hw = {
.has_single_clk_source = false,
.clk_divisor_hs_mode = 3,
.clk_divisor_std_fast_mode = 0,
+   .clk_divisor_fast_plus_mode = 0,
.has_config_load_reg = false,
 };
 
@@ -715,6 +719,7 @@ static const struct tegra_i2c_hw_feature tegra114_i2c_hw = {
.has_single_clk_source = true,
.clk_divisor_hs_mode = 1,
.clk_divisor_std_fast_mode = 0x19,
+   .clk_divisor_fast_plus_mode = 0x10,
.has_config_load_reg = false,
 };
 
@@ -724,6 +729,7 @@ static const struct tegra_i2c_hw_feature tegra124_i2c_hw = {
.has_single_clk_source = true,
.clk_divisor_hs_mode = 1,
.clk_divisor_std_fast_mode = 0x19,
+   .clk_divisor_fast_plus_mode = 0x10,
.has_config_load_reg = true,
 };
 
@@ -821,7 +827,14 @@ static int tegra_i2c_probe(struct platform_device *pdev)
}
}
 
-   clk_multiplier *= (i2c_dev-hw-clk_divisor_std_fast_mode + 1);
+   i2c_dev-clk_divisor_non_hs_mode =
+   i2c_dev-hw-clk_divisor_std_fast_mode;
+   if (i2c_dev-hw-clk_divisor_fast_plus_mode 
+   (i2c_dev-bus_clk_rate == 100))
+   i2c_dev-clk_divisor_non_hs_mode =
+   i2c_dev-hw-clk_divisor_fast_plus_mode;
+
+   clk_multiplier *= (i2c_dev-clk_divisor_non_hs_mode + 1);
ret = clk_set_rate(i2c_dev-div_clk,
   i2c_dev-bus_clk_rate * clk_multiplier);
if (ret) {
-- 
2.1.4

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


Re: [PATCH] i2c-mux-pca954x: allow downstream bus numbers to be specified in the dts

2014-04-17 Thread Laxman Dewangan

On Thursday 17 April 2014 09:16 PM, Laurent Pinchart wrote:

+   u32 fixed_bus_numbers[PCA954X_MAX_NCHANS] = { 0 };
  int ret;

  if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
@@ -214,6 +215,17 @@ static int pca954x_probe(struct i2c_client *client,
  if (ret  0)
  return ret;
  }
+
+   /* Get fixed bus numbers */
+   ret = of_property_read_u32_array(np, fixed-bus-numbers,
+   fixed_bus_numbers, chips[id-driver_data].nchans);
+   if (ret == -EINVAL)
+   ret = 0;/* missing dtb node is not an error
*/ +   if (ret  0) {
+   dev_err(client-dev, fixed-bus-numbers: 
+   invalid format\n);
+   return ret;
+   }
  }



Hi Frank,
Why not you use aliases on DTS instead of changing driver?
You can alias the bus number with the child node name. On the following, 
the bus will be registerd as 6, 7, 8 and 9.

i2c-core already support this.

aliases {
i2c6 = pca9546_i2c0;
i2c7 = pca9546_i2c1;
i2c8 = pca9546_i2c2;
i2c9 = pca9546_i2c3;
};


---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
--
To unsubscribe from this list: send the line unsubscribe linux-i2c in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] i2c: tegra: remove warning dump if timeout happen in transfer

2013-02-14 Thread Laxman Dewangan
If timeout error occurs in the i2c transfer then it was dumping warning
of call stack.

Remove the warning dump as there is may be possibility that some slave
devices are busy and not responding the i2c communication.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
The patch is generated based on discussion happen between Stephena and
Wolfram on the patch:
 i2c: add bcm2835 driver

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

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index ae2e027..36704e3 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -587,7 +587,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
ret = wait_for_completion_timeout(i2c_dev-msg_complete, 
TEGRA_I2C_TIMEOUT);
tegra_i2c_mask_irq(i2c_dev, int_mask);
 
-   if (WARN_ON(ret == 0)) {
+   if (ret == 0) {
dev_err(i2c_dev-dev, i2c transfer timed out\n);
 
tegra_i2c_init(i2c_dev);
-- 
1.7.1.1

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


[PATCH] i2c: tegra: remove warning dump if timeout happen in transfer

2013-02-14 Thread Laxman Dewangan
If timeout error occurs in the i2c transfer then it was dumping warning
of call stack.

Remove the warning dump as there is may be possibility that some slave
devices are busy and not responding the i2c communication.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
The patch is generated based on discussion happen between Stephena and
Wolfram on the patch:
 i2c: add bcm2835 driver

resending patch as Wolfram's email id has been changed.

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

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index ae2e027..36704e3 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -587,7 +587,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
ret = wait_for_completion_timeout(i2c_dev-msg_complete, 
TEGRA_I2C_TIMEOUT);
tegra_i2c_mask_irq(i2c_dev, int_mask);
 
-   if (WARN_ON(ret == 0)) {
+   if (ret == 0) {
dev_err(i2c_dev-dev, i2c transfer timed out\n);
 
tegra_i2c_init(i2c_dev);
-- 
1.7.1.1

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


[PATCH RESEND] i2c: tegra: add support for Tegra114 SoC

2013-01-21 Thread Laxman Dewangan
NVIDIA's Tegra114 has following enhanced feature in i2c controller:
- Enable/disable control for per packet transfer complete interrupt.
  Earlier SoCs could not disable this.
- Single clock source for standard/fast and HS mode clock speed.
  The clock divisor for fast/standard mode is added into the i2c
  controller to meet the HS and standard/fast mode of clock speed
  from single source.

Add support for the above feature to make it functional on T114 SOCs.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
Reviewed-by: Stephen Warren swar...@nvidia.com
---
Just resending if this is missed in long holiday.
Adding reviewed-by: Stephen as he has already given his score.

 drivers/i2c/busses/i2c-tegra.c |   77 ---
 1 files changed, 63 insertions(+), 14 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 7b38877..2dadb96 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -71,6 +71,8 @@
 #define I2C_INT_TX_FIFO_DATA_REQ   (11)
 #define I2C_INT_RX_FIFO_DATA_REQ   (10)
 #define I2C_CLK_DIVISOR0x06c
+#define I2C_CLK_DIVISOR_STD_FAST_MODE_SHIFT16
+#define I2C_CLK_MULTIPLIER_STD_FAST_MODE   8
 
 #define DVC_CTRL_REG1  0x000
 #define DVC_CTRL_REG1_INTR_EN  (110)
@@ -117,10 +119,23 @@ enum msg_end_type {
 /**
  * struct tegra_i2c_hw_feature : Different HW support on Tegra
  * @has_continue_xfer_support: Continue transfer supports.
+ * @has_per_pkt_xfer_complete_irq: Has enable/disable capability for transfer
+ * complete interrupt per packet basis.
+ * @has_single_clk_source: The i2c controller has single clock source. Tegra30
+ * and earlier Socs has two clock sources i.e. div-clk and
+ * fast-clk.
+ * @clk_divisor_hs_mode: Clock divisor in HS mode.
+ * @clk_divisor_std_fast_mode: Clock divisor in standard/fast mode. It is
+ * applicable if there is no fast clock source i.e. single clock
+ * source.
  */
 
 struct tegra_i2c_hw_feature {
bool has_continue_xfer_support;
+   bool has_per_pkt_xfer_complete_irq;
+   bool has_single_clk_source;
+   int clk_divisor_hs_mode;
+   int clk_divisor_std_fast_mode;
 };
 
 /**
@@ -366,11 +381,13 @@ static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev)
 static inline int tegra_i2c_clock_enable(struct tegra_i2c_dev *i2c_dev)
 {
int ret;
-   ret = clk_prepare_enable(i2c_dev-fast_clk);
-   if (ret  0) {
-   dev_err(i2c_dev-dev,
-   Enabling fast clk failed, err %d\n, ret);
-   return ret;
+   if (!i2c_dev-hw-has_single_clk_source) {
+   ret = clk_prepare_enable(i2c_dev-fast_clk);
+   if (ret  0) {
+   dev_err(i2c_dev-dev,
+   Enabling fast clk failed, err %d\n, ret);
+   return ret;
+   }
}
ret = clk_prepare_enable(i2c_dev-div_clk);
if (ret  0) {
@@ -384,13 +401,16 @@ static inline int tegra_i2c_clock_enable(struct 
tegra_i2c_dev *i2c_dev)
 static inline void tegra_i2c_clock_disable(struct tegra_i2c_dev *i2c_dev)
 {
clk_disable_unprepare(i2c_dev-div_clk);
-   clk_disable_unprepare(i2c_dev-fast_clk);
+   if (!i2c_dev-hw-has_single_clk_source)
+   clk_disable_unprepare(i2c_dev-fast_clk);
 }
 
 static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 {
u32 val;
int err = 0;
+   int clk_multiplier = I2C_CLK_MULTIPLIER_STD_FAST_MODE;
+   u32 clk_divisor;
 
tegra_i2c_clock_enable(i2c_dev);
 
@@ -405,7 +425,15 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
(0x2  I2C_CNFG_DEBOUNCE_CNT_SHIFT);
i2c_writel(i2c_dev, val, I2C_CNFG);
i2c_writel(i2c_dev, 0, I2C_INT_MASK);
-   clk_set_rate(i2c_dev-div_clk, i2c_dev-bus_clk_rate * 8);
+
+   clk_multiplier *= (i2c_dev-hw-clk_divisor_std_fast_mode + 1);
+   clk_set_rate(i2c_dev-div_clk, i2c_dev-bus_clk_rate * clk_multiplier);
+
+   /* Make sure clock divisor programmed correctly */
+   clk_divisor = i2c_dev-hw-clk_divisor_hs_mode;
+   clk_divisor |= i2c_dev-hw-clk_divisor_std_fast_mode 
+   I2C_CLK_DIVISOR_STD_FAST_MODE_SHIFT;
+   i2c_writel(i2c_dev, clk_divisor, I2C_CLK_DIVISOR);
 
if (!i2c_dev-is_dvc) {
u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG);
@@ -547,6 +575,8 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
tegra_i2c_fill_tx_fifo(i2c_dev);
 
int_mask = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST;
+   if (i2c_dev-hw-has_per_pkt_xfer_complete_irq)
+   int_mask |= I2C_INT_PACKET_XFER_COMPLETE;
if (msg-flags  I2C_M_RD)
int_mask |= I2C_INT_RX_FIFO_DATA_REQ;
else if (i2c_dev

[PATCH] i2c: tegra: add support for Tegra114 SoC

2013-01-05 Thread Laxman Dewangan
NVIDIA's Tegra114 has following enhanced feature in i2c controller:
- Enable/disable control for per packet transfer complete interrupt.
  Earlier SoCs could not disable this.
- Single clock source for standard/fast and HS mode clock speed.
  The clock divisor for fast/standard mode is added into the i2c
  controller to meet the HS and standard/fast mode of clock speed
  from single source.

Add support for the above feature to make it functional on T114 SOCs.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
 drivers/i2c/busses/i2c-tegra.c |   77 ---
 1 files changed, 63 insertions(+), 14 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 7b38877..2dadb96 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -71,6 +71,8 @@
 #define I2C_INT_TX_FIFO_DATA_REQ   (11)
 #define I2C_INT_RX_FIFO_DATA_REQ   (10)
 #define I2C_CLK_DIVISOR0x06c
+#define I2C_CLK_DIVISOR_STD_FAST_MODE_SHIFT16
+#define I2C_CLK_MULTIPLIER_STD_FAST_MODE   8
 
 #define DVC_CTRL_REG1  0x000
 #define DVC_CTRL_REG1_INTR_EN  (110)
@@ -117,10 +119,23 @@ enum msg_end_type {
 /**
  * struct tegra_i2c_hw_feature : Different HW support on Tegra
  * @has_continue_xfer_support: Continue transfer supports.
+ * @has_per_pkt_xfer_complete_irq: Has enable/disable capability for transfer
+ * complete interrupt per packet basis.
+ * @has_single_clk_source: The i2c controller has single clock source. Tegra30
+ * and earlier Socs has two clock sources i.e. div-clk and
+ * fast-clk.
+ * @clk_divisor_hs_mode: Clock divisor in HS mode.
+ * @clk_divisor_std_fast_mode: Clock divisor in standard/fast mode. It is
+ * applicable if there is no fast clock source i.e. single clock
+ * source.
  */
 
 struct tegra_i2c_hw_feature {
bool has_continue_xfer_support;
+   bool has_per_pkt_xfer_complete_irq;
+   bool has_single_clk_source;
+   int clk_divisor_hs_mode;
+   int clk_divisor_std_fast_mode;
 };
 
 /**
@@ -366,11 +381,13 @@ static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev)
 static inline int tegra_i2c_clock_enable(struct tegra_i2c_dev *i2c_dev)
 {
int ret;
-   ret = clk_prepare_enable(i2c_dev-fast_clk);
-   if (ret  0) {
-   dev_err(i2c_dev-dev,
-   Enabling fast clk failed, err %d\n, ret);
-   return ret;
+   if (!i2c_dev-hw-has_single_clk_source) {
+   ret = clk_prepare_enable(i2c_dev-fast_clk);
+   if (ret  0) {
+   dev_err(i2c_dev-dev,
+   Enabling fast clk failed, err %d\n, ret);
+   return ret;
+   }
}
ret = clk_prepare_enable(i2c_dev-div_clk);
if (ret  0) {
@@ -384,13 +401,16 @@ static inline int tegra_i2c_clock_enable(struct 
tegra_i2c_dev *i2c_dev)
 static inline void tegra_i2c_clock_disable(struct tegra_i2c_dev *i2c_dev)
 {
clk_disable_unprepare(i2c_dev-div_clk);
-   clk_disable_unprepare(i2c_dev-fast_clk);
+   if (!i2c_dev-hw-has_single_clk_source)
+   clk_disable_unprepare(i2c_dev-fast_clk);
 }
 
 static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 {
u32 val;
int err = 0;
+   int clk_multiplier = I2C_CLK_MULTIPLIER_STD_FAST_MODE;
+   u32 clk_divisor;
 
tegra_i2c_clock_enable(i2c_dev);
 
@@ -405,7 +425,15 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
(0x2  I2C_CNFG_DEBOUNCE_CNT_SHIFT);
i2c_writel(i2c_dev, val, I2C_CNFG);
i2c_writel(i2c_dev, 0, I2C_INT_MASK);
-   clk_set_rate(i2c_dev-div_clk, i2c_dev-bus_clk_rate * 8);
+
+   clk_multiplier *= (i2c_dev-hw-clk_divisor_std_fast_mode + 1);
+   clk_set_rate(i2c_dev-div_clk, i2c_dev-bus_clk_rate * clk_multiplier);
+
+   /* Make sure clock divisor programmed correctly */
+   clk_divisor = i2c_dev-hw-clk_divisor_hs_mode;
+   clk_divisor |= i2c_dev-hw-clk_divisor_std_fast_mode 
+   I2C_CLK_DIVISOR_STD_FAST_MODE_SHIFT;
+   i2c_writel(i2c_dev, clk_divisor, I2C_CLK_DIVISOR);
 
if (!i2c_dev-is_dvc) {
u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG);
@@ -547,6 +575,8 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
tegra_i2c_fill_tx_fifo(i2c_dev);
 
int_mask = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST;
+   if (i2c_dev-hw-has_per_pkt_xfer_complete_irq)
+   int_mask |= I2C_INT_PACKET_XFER_COMPLETE;
if (msg-flags  I2C_M_RD)
int_mask |= I2C_INT_RX_FIFO_DATA_REQ;
else if (i2c_dev-msg_buf_remaining)
@@ -634,15 +664,32 @@ static const struct i2c_algorithm tegra_i2c_algo = {
 
 static const struct tegra_i2c_hw_feature tegra20_i2c_hw

[PATCH REPOST] i2c: tegra: set irq name as device name

2012-11-01 Thread Laxman Dewangan
When watching the irqs name of tegra i2c, all instances
irq name shows as tegra_i2c.

Passing the device name properly to have the irq names with
instance like tegra-i2c.0, tegra-i2c.1 etc.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
Acked-by: Jean Delvare kh...@linux-fr.org
---
Reposting patch in case of it missed.

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

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index f981ac4..dcea77b 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -742,7 +742,7 @@ static int __devinit tegra_i2c_probe(struct platform_device 
*pdev)
}
 
ret = devm_request_irq(pdev-dev, i2c_dev-irq,
-   tegra_i2c_isr, 0, pdev-name, i2c_dev);
+   tegra_i2c_isr, 0, dev_name(pdev-dev), i2c_dev);
if (ret) {
dev_err(pdev-dev, Failed to request irq %i\n, i2c_dev-irq);
return ret;
-- 
1.7.1.1

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


[PATCH] i2c: tegra: set irq name as device name

2012-10-12 Thread Laxman Dewangan
When watching the irqs name of tegra i2c, all instances
irq name shows as tegra_i2c.

Passing the device name properly to have the irq names with
instance like tegra-i2c.0, tegra-i2c.1 etc.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
 drivers/i2c/busses/i2c-tegra.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index f981ac4..dcea77b 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -742,7 +742,7 @@ static int __devinit tegra_i2c_probe(struct platform_device 
*pdev)
}
 
ret = devm_request_irq(pdev-dev, i2c_dev-irq,
-   tegra_i2c_isr, 0, pdev-name, i2c_dev);
+   tegra_i2c_isr, 0, dev_name(pdev-dev), i2c_dev);
if (ret) {
dev_err(pdev-dev, Failed to request irq %i\n, i2c_dev-irq);
return ret;
-- 
1.7.1.1

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


Re: [PATCH V2 1/2] i2c: tegra: I2_M_NOSTART functionality not supported in Tegra20

2012-08-20 Thread Laxman Dewangan

On Monday 20 August 2012 10:45 PM, Stephen Warren wrote:

On 08/18/2012 01:17 PM, Laxman Dewangan wrote:

Tegra20 i2c controller does not support the continue transfer
which implements the I2C_M_NOSTART functionality of i2c
protocol mangling.
Removing the I2C_M_NOSTART functionality support for Tegra20.

Thanks, applied the series to Tegra's for-3.7/drivers-i2c branch.

Note that I had to fix up patch 1 to remove const on the tegra*_i2c_hw
variable declarations to avoid compiler warnings when assigning pointers
into tegra_i2c_of_match[].data.

Thanks for correction but
I did not get this warning and when saw the structure, it is declared as 
const type only..

struct of_device_id
{
charname[32];
chartype[32];
charcompatible[128];
#ifdef __KERNEL__
const void *data;
#else
kernel_ulong_t data;
#endif
};


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


[PATCH V2] i2c: tegra: protect suspend/resume callbacks with CONFIG_PM_SLEEP

2012-08-18 Thread Laxman Dewangan
The CONFIG_PM doesn't actually enable any of the PM callbacks, it
only allows to enable CONFIG_PM_SLEEP and CONFIG_PM_RUNTIME.
This means if CONFIG_PM is used to protect system sleep callbacks
then it may end up unreferenced if only runtime PM is enabled.
Hence protecting sleep callbacks with CONFIG_PM_SLEEP.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
This patch will remove the compilation warning if CONFIG_PM_SLEEP
is not enabled.

Change from V1 -V2:
provide more details in description as per Mark's response.

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

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 66eb53f..9a08c57 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -712,7 +712,7 @@ static int __devexit tegra_i2c_remove(struct 
platform_device *pdev)
return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int tegra_i2c_suspend(struct device *dev)
 {
struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
-- 
1.7.1.1

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


Re: [PATCH REBASE 1/2] i2c: tegra: I2_M_NOSTART functionality not supported in Tegra20

2012-08-18 Thread Laxman Dewangan

Thanks for review.

On Saturday 18 August 2012 06:17 PM, Wolfram Sang wrote:

* PGP Signed by an unknown key

On Sat, Aug 18, 2012 at 12:32:34AM +0530, Laxman Dewangan wrote:

+   bool has_continue_xfer_support;

I wonder if it makes sense to carry a pointer here to the
tegra_i2c_hw_feature in use instead of copying all entries by hand,
since they might get more and more.



Ok, we can store the hw pointer in device structure. I will send the new 
patch.



  };

  static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val, unsigned long 
reg)
@@ -563,7 +574,17 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
if (i2c_dev-is_suspended)
return -EBUSY;

-   clk_prepare_enable(i2c_dev-div_clk);
+   /* Support I2C_M_NOSTART only if HW support continue xfer. */
+   for (i = 0; i  num - 1; i++) {
+   if ((msgs[i + 1].flags  I2C_M_NOSTART)
+   !i2c_dev-has_continue_xfer_support) {
+   dev_err(i2c_dev-dev,
+   mesg %d have illegal flag\n, i + 1);
+   return -EINVAL;
+   }
+   }

Drivers are requested to explicitly check for features of the I2C bus
(like M_NOSTART) before using them, so I'd skip this extra check.



Ok, I kept this as part of flag checking so illegal flag should not be 
passed. I will remove this on next version patch.



+
+   clk_prepare_enable(i2c_dev-clk);

 From a glimpse, this change looks unrelated at least. Even wrong, no?



It was already there, just before above check. Due to insertion of 
check, this code shifted, otherwise it is not a new code.


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


[PATCH V2 1/2] i2c: tegra: I2_M_NOSTART functionality not supported in Tegra20

2012-08-18 Thread Laxman Dewangan
Tegra20 i2c controller does not support the continue transfer
which implements the I2C_M_NOSTART functionality of i2c
protocol mangling.
Removing the I2C_M_NOSTART functionality support for Tegra20.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
Changes from V1:
- make the hw feature structure as part of tegra device structure in
  place of copying the member.
- Remove check for extra M_NOSTART flag if it is not supported in xfer function.

Please note that this should go on tegra common clock source tree to avoid 
conflicts.

 drivers/i2c/busses/i2c-tegra.c |   61 ++-
 1 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 7149625..2f74236 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -27,6 +27,7 @@
 #include linux/slab.h
 #include linux/i2c-tegra.h
 #include linux/of_i2c.h
+#include linux/of_device.h
 #include linux/module.h
 
 #include asm/unaligned.h
@@ -114,8 +115,18 @@ enum msg_end_type {
 };
 
 /**
+ * struct tegra_i2c_hw_feature : Different HW support on Tegra
+ * @has_continue_xfer_support: Continue transfer supports.
+ */
+
+struct tegra_i2c_hw_feature {
+   bool has_continue_xfer_support;
+};
+
+/**
  * struct tegra_i2c_dev- per device i2c context
  * @dev: device reference for power management
+ * @hw: Tegra i2c hw feature.
  * @adapter: core i2c layer adapter information
  * @div_clk: clock reference for div clock of i2c controller.
  * @fast_clk: clock reference for fast clock of i2c controller.
@@ -133,6 +144,7 @@ enum msg_end_type {
  */
 struct tegra_i2c_dev {
struct device *dev;
+   const struct tegra_i2c_hw_feature *hw;
struct i2c_adapter adapter;
struct clk *div_clk;
struct clk *fast_clk;
@@ -582,8 +594,13 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
 
 static u32 tegra_i2c_func(struct i2c_adapter *adap)
 {
-   return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
-   I2C_FUNC_PROTOCOL_MANGLING | I2C_FUNC_NOSTART;
+   struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
+   u32 ret = I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
+   I2C_FUNC_PROTOCOL_MANGLING;
+
+   if (i2c_dev-hw-has_continue_xfer_support)
+   ret |= I2C_FUNC_NOSTART;
+   return ret;
 }
 
 static const struct i2c_algorithm tegra_i2c_algo = {
@@ -591,6 +608,25 @@ static const struct i2c_algorithm tegra_i2c_algo = {
.functionality  = tegra_i2c_func,
 };
 
+static const struct tegra_i2c_hw_feature tegra20_i2c_hw = {
+   .has_continue_xfer_support = false,
+};
+
+static const struct tegra_i2c_hw_feature tegra30_i2c_hw = {
+   .has_continue_xfer_support = true,
+};
+
+#if defined(CONFIG_OF)
+/* Match table for of_platform binding */
+static const struct of_device_id tegra_i2c_of_match[] __devinitconst = {
+   { .compatible = nvidia,tegra30-i2c, .data = tegra30_i2c_hw, },
+   { .compatible = nvidia,tegra20-i2c, .data = tegra20_i2c_hw, },
+   { .compatible = nvidia,tegra20-i2c-dvc, .data = tegra20_i2c_hw, },
+   {},
+};
+MODULE_DEVICE_TABLE(of, tegra_i2c_of_match);
+#endif
+
 static int __devinit tegra_i2c_probe(struct platform_device *pdev)
 {
struct tegra_i2c_dev *i2c_dev;
@@ -659,11 +695,18 @@ static int __devinit tegra_i2c_probe(struct 
platform_device *pdev)
i2c_dev-bus_clk_rate = be32_to_cpup(prop);
}
 
-   if (pdev-dev.of_node)
+   i2c_dev-hw = tegra20_i2c_hw;
+
+   if (pdev-dev.of_node) {
+   const struct of_device_id *match;
+   match = of_match_device(of_match_ptr(tegra_i2c_of_match),
+   pdev-dev);
+   i2c_dev-hw = match-data;
i2c_dev-is_dvc = of_device_is_compatible(pdev-dev.of_node,
nvidia,tegra20-i2c-dvc);
-   else if (pdev-id == 3)
+   } else if (pdev-id == 3) {
i2c_dev-is_dvc = 1;
+   }
init_completion(i2c_dev-msg_complete);
 
platform_set_drvdata(pdev, i2c_dev);
@@ -751,16 +794,6 @@ static SIMPLE_DEV_PM_OPS(tegra_i2c_pm, tegra_i2c_suspend, 
tegra_i2c_resume);
 #define TEGRA_I2C_PM   NULL
 #endif
 
-#if defined(CONFIG_OF)
-/* Match table for of_platform binding */
-static const struct of_device_id tegra_i2c_of_match[] __devinitconst = {
-   { .compatible = nvidia,tegra20-i2c, },
-   { .compatible = nvidia,tegra20-i2c-dvc, },
-   {},
-};
-MODULE_DEVICE_TABLE(of, tegra_i2c_of_match);
-#endif
-
 static struct platform_driver tegra_i2c_driver = {
.probe   = tegra_i2c_probe,
.remove  = __devexit_p(tegra_i2c_remove),
-- 
1.7.1.1

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

[PATCH V2 2/2] i2c: tegra: dynamically control fast clk

2012-08-18 Thread Laxman Dewangan
Tegra I2C driver enables the fast clock during initialization
and does not disable till driver removed.
Enable this clock before transfer and disable after transfer done.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
Reviewed-by: Wolfram Sang w.s...@pengutronix.de
---

Changes from V1:
- Rebased again on patch 1.

 drivers/i2c/busses/i2c-tegra.c |   35 ---
 1 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 2f74236..20c35fa 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -363,12 +363,36 @@ static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev)
dvc_writel(i2c_dev, val, DVC_CTRL_REG1);
 }
 
+static inline int tegra_i2c_clock_enable(struct tegra_i2c_dev *i2c_dev)
+{
+   int ret;
+   ret = clk_prepare_enable(i2c_dev-fast_clk);
+   if (ret  0) {
+   dev_err(i2c_dev-dev,
+   Enabling fast clk failed, err %d\n, ret);
+   return ret;
+   }
+   ret = clk_prepare_enable(i2c_dev-div_clk);
+   if (ret  0) {
+   dev_err(i2c_dev-dev,
+   Enabling div clk failed, err %d\n, ret);
+   clk_disable_unprepare(i2c_dev-fast_clk);
+   }
+   return ret;
+}
+
+static inline void tegra_i2c_clock_disable(struct tegra_i2c_dev *i2c_dev)
+{
+   clk_disable_unprepare(i2c_dev-div_clk);
+   clk_disable_unprepare(i2c_dev-fast_clk);
+}
+
 static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 {
u32 val;
int err = 0;
 
-   clk_prepare_enable(i2c_dev-div_clk);
+   tegra_i2c_clock_enable(i2c_dev);
 
tegra_periph_reset_assert(i2c_dev-div_clk);
udelay(2);
@@ -399,7 +423,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
if (tegra_i2c_flush_fifos(i2c_dev))
err = -ETIMEDOUT;
 
-   clk_disable_unprepare(i2c_dev-div_clk);
+   tegra_i2c_clock_disable(i2c_dev);
 
if (i2c_dev-irq_disabled) {
i2c_dev-irq_disabled = 0;
@@ -575,7 +599,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
if (i2c_dev-is_suspended)
return -EBUSY;
 
-   clk_prepare_enable(i2c_dev-div_clk);
+   tegra_i2c_clock_enable(i2c_dev);
for (i = 0; i  num; i++) {
enum msg_end_type end_type = MSG_END_STOP;
if (i  (num - 1)) {
@@ -588,7 +612,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
if (ret)
break;
}
-   clk_disable_unprepare(i2c_dev-div_clk);
+   tegra_i2c_clock_disable(i2c_dev);
return ret ?: i;
 }
 
@@ -724,8 +748,6 @@ static int __devinit tegra_i2c_probe(struct platform_device 
*pdev)
return ret;
}
 
-   clk_prepare_enable(i2c_dev-fast_clk);
-
i2c_set_adapdata(i2c_dev-adapter, i2c_dev);
i2c_dev-adapter.owner = THIS_MODULE;
i2c_dev-adapter.class = I2C_CLASS_HWMON;
@@ -739,7 +761,6 @@ static int __devinit tegra_i2c_probe(struct platform_device 
*pdev)
ret = i2c_add_numbered_adapter(i2c_dev-adapter);
if (ret) {
dev_err(pdev-dev, Failed to add I2C adapter\n);
-   clk_disable_unprepare(i2c_dev-fast_clk);
return ret;
}
 
-- 
1.7.1.1

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


[PATCH] i2c: tegra: dynamically control fast clk

2012-08-17 Thread Laxman Dewangan
Tegra I2C driver enables the fast clock during initialization
and does not disable till driver removed.
Enable this clock before transfer and disable after transfer done.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
This patch is on top of the clock chnages which is in Tegra sub system and
based on 
 i2c: tegra: I2_M_NOSTART functionality not supported in Tegra20
So recommend to go on tegra sub-system.

 drivers/i2c/busses/i2c-tegra.c |   35 ---
 1 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 554f713..24f7cee 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -362,12 +362,36 @@ static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev)
dvc_writel(i2c_dev, val, DVC_CTRL_REG1);
 }
 
+static inline int tegra_i2c_clock_enable(struct tegra_i2c_dev *i2c_dev)
+{
+   int ret;
+   ret = clk_prepare_enable(i2c_dev-fast_clk);
+   if (ret  0) {
+   dev_err(i2c_dev-dev,
+   Enabling fast clk failed, err %d\n, ret);
+   return ret;
+   }
+   ret = clk_prepare_enable(i2c_dev-div_clk);
+   if (ret  0) {
+   dev_err(i2c_dev-dev,
+   Enabling div clk failed, err %d\n, ret);
+   clk_disable_unprepare(i2c_dev-fast_clk);
+   }
+   return ret;
+}
+
+static inline void tegra_i2c_clock_disable(struct tegra_i2c_dev *i2c_dev)
+{
+   clk_disable_unprepare(i2c_dev-div_clk);
+   clk_disable_unprepare(i2c_dev-fast_clk);
+}
+
 static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 {
u32 val;
int err = 0;
 
-   clk_prepare_enable(i2c_dev-div_clk);
+   tegra_i2c_clock_enable(i2c_dev);
 
tegra_periph_reset_assert(i2c_dev-div_clk);
udelay(2);
@@ -398,7 +422,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
if (tegra_i2c_flush_fifos(i2c_dev))
err = -ETIMEDOUT;
 
-   clk_disable_unprepare(i2c_dev-div_clk);
+   tegra_i2c_clock_disable(i2c_dev);
 
if (i2c_dev-irq_disabled) {
i2c_dev-irq_disabled = 0;
@@ -584,7 +608,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
}
}
 
-   clk_prepare_enable(i2c_dev-clk);
+   tegra_i2c_clock_enable(i2c_dev);
for (i = 0; i  num; i++) {
enum msg_end_type end_type = MSG_END_STOP;
if (i  (num - 1)) {
@@ -597,7 +621,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
if (ret)
break;
}
-   clk_disable_unprepare(i2c_dev-div_clk);
+   tegra_i2c_clock_disable(i2c_dev);
return ret ?: i;
 }
 
@@ -734,8 +758,6 @@ static int __devinit tegra_i2c_probe(struct platform_device 
*pdev)
return ret;
}
 
-   clk_prepare_enable(i2c_dev-fast_clk);
-
i2c_set_adapdata(i2c_dev-adapter, i2c_dev);
i2c_dev-adapter.owner = THIS_MODULE;
i2c_dev-adapter.class = I2C_CLASS_HWMON;
@@ -749,7 +771,6 @@ static int __devinit tegra_i2c_probe(struct platform_device 
*pdev)
ret = i2c_add_numbered_adapter(i2c_dev-adapter);
if (ret) {
dev_err(pdev-dev, Failed to add I2C adapter\n);
-   clk_disable_unprepare(i2c_dev-fast_clk);
return ret;
}
 
-- 
1.7.1.1

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


Re: [PATCH] i2c: tegra: dynamically control fast clk

2012-08-17 Thread Laxman Dewangan

On Saturday 18 August 2012 12:11 AM, Stephen Warren wrote:

On 08/17/2012 01:48 AM, Laxman Dewangan wrote:

Tegra I2C driver enables the fast clock during initialization
and does not disable till driver removed.
Enable this clock before transfer and disable after transfer done.

Signed-off-by: Laxman Dewanganldewan...@nvidia.com
---
This patch is on top of the clock chnages which is in Tegra sub system and
based on
  i2c: tegra: I2_M_NOSTART functionality not supported in Tegra20
So recommend to go on tegra sub-system.

What exactly is this patch based on? I checked out Tegra's
for-3.7/drivers-i2c, cherry-picked the M_NOSTART patch you mentioned,
and attempted to apply this patch. It doesn't apply. Same if I don't
cherry-pick the M_NOSTART patch, and same for next-20120816 with/without
the M_NOSTART patch.


Then It seems I need to create the patch again and send it.  The 
M_NOSTART patch was on tot before clock related change and that is the 
reason it is not applying.
Should I re-send these two patches together as 1/2 and 2/2 to maintain 
sequence?

I can create based on your clock tree.


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


[PATCH REBASE 1/2] i2c: tegra: I2_M_NOSTART functionality not supported in Tegra20

2012-08-17 Thread Laxman Dewangan
Tegra20 i2c controller does not support the continue transfer
which implements the I2C_M_NOSTART functionality of i2c
protocol mangling.
Removing the I2C_M_NOSTART functionality for Tegra20.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
This is rebased on linux-next-20120816.

 drivers/i2c/busses/i2c-tegra.c |   73 +++
 1 files changed, 58 insertions(+), 15 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 7149625..554f713 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -27,6 +27,7 @@
 #include linux/slab.h
 #include linux/i2c-tegra.h
 #include linux/of_i2c.h
+#include linux/of_device.h
 #include linux/module.h
 
 #include asm/unaligned.h
@@ -114,6 +115,15 @@ enum msg_end_type {
 };
 
 /**
+ * struct tegra_i2c_hw_feature : Different HW support on Tegra
+ * @has_continue_xfer_support: Continue transfer supports.
+ */
+
+struct tegra_i2c_hw_feature {
+   bool has_continue_xfer_support;
+};
+
+/**
  * struct tegra_i2c_dev- per device i2c context
  * @dev: device reference for power management
  * @adapter: core i2c layer adapter information
@@ -148,6 +158,7 @@ struct tegra_i2c_dev {
int msg_read;
unsigned long bus_clk_rate;
bool is_suspended;
+   bool has_continue_xfer_support;
 };
 
 static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val, unsigned long 
reg)
@@ -563,7 +574,17 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
if (i2c_dev-is_suspended)
return -EBUSY;
 
-   clk_prepare_enable(i2c_dev-div_clk);
+   /* Support I2C_M_NOSTART only if HW support continue xfer. */
+   for (i = 0; i  num - 1; i++) {
+   if ((msgs[i + 1].flags  I2C_M_NOSTART) 
+   !i2c_dev-has_continue_xfer_support) {
+   dev_err(i2c_dev-dev,
+   mesg %d have illegal flag\n, i + 1);
+   return -EINVAL;
+   }
+   }
+
+   clk_prepare_enable(i2c_dev-clk);
for (i = 0; i  num; i++) {
enum msg_end_type end_type = MSG_END_STOP;
if (i  (num - 1)) {
@@ -582,8 +603,13 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
 
 static u32 tegra_i2c_func(struct i2c_adapter *adap)
 {
-   return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
-   I2C_FUNC_PROTOCOL_MANGLING | I2C_FUNC_NOSTART;
+   struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
+   u32 ret = I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
+   I2C_FUNC_PROTOCOL_MANGLING;
+
+   if (i2c_dev-has_continue_xfer_support)
+   ret |= I2C_FUNC_NOSTART;
+   return ret;
 }
 
 static const struct i2c_algorithm tegra_i2c_algo = {
@@ -591,6 +617,25 @@ static const struct i2c_algorithm tegra_i2c_algo = {
.functionality  = tegra_i2c_func,
 };
 
+static struct tegra_i2c_hw_feature tegra20_i2c_hw = {
+   .has_continue_xfer_support = false,
+};
+
+static struct tegra_i2c_hw_feature tegra30_i2c_hw = {
+   .has_continue_xfer_support = true,
+};
+
+#if defined(CONFIG_OF)
+/* Match table for of_platform binding */
+static const struct of_device_id tegra_i2c_of_match[] __devinitconst = {
+   { .compatible = nvidia,tegra30-i2c, .data = tegra30_i2c_hw, },
+   { .compatible = nvidia,tegra20-i2c, .data = tegra20_i2c_hw, },
+   { .compatible = nvidia,tegra20-i2c-dvc, .data = tegra20_i2c_hw, },
+   {},
+};
+MODULE_DEVICE_TABLE(of, tegra_i2c_of_match);
+#endif
+
 static int __devinit tegra_i2c_probe(struct platform_device *pdev)
 {
struct tegra_i2c_dev *i2c_dev;
@@ -600,6 +645,7 @@ static int __devinit tegra_i2c_probe(struct platform_device 
*pdev)
struct clk *fast_clk;
const unsigned int *prop;
void __iomem *base;
+   const struct tegra_i2c_hw_feature *hw = tegra20_i2c_hw;
int irq;
int ret = 0;
 
@@ -659,11 +705,18 @@ static int __devinit tegra_i2c_probe(struct 
platform_device *pdev)
i2c_dev-bus_clk_rate = be32_to_cpup(prop);
}
 
-   if (pdev-dev.of_node)
+   if (pdev-dev.of_node) {
+   const struct of_device_id *match;
+   match = of_match_device(of_match_ptr(tegra_i2c_of_match),
+   pdev-dev);
+   hw = match-data;
i2c_dev-is_dvc = of_device_is_compatible(pdev-dev.of_node,
nvidia,tegra20-i2c-dvc);
-   else if (pdev-id == 3)
+   } else if (pdev-id == 3) {
i2c_dev-is_dvc = 1;
+   }
+
+   i2c_dev-has_continue_xfer_support = hw-has_continue_xfer_support;
init_completion(i2c_dev-msg_complete);
 
platform_set_drvdata(pdev, i2c_dev);
@@ -751,16 +804,6 @@ static SIMPLE_DEV_PM_OPS(tegra_i2c_pm

[PATCH REBASE 2/2] i2c: tegra: dynamically control fast clk

2012-08-17 Thread Laxman Dewangan
Tegra I2C driver enables the fast clock during initialization
and does not disable till driver removed.
Enable this clock before transfer and disable after transfer done.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
This is rebased on linux-next-20120816.

 drivers/i2c/busses/i2c-tegra.c |   35 ---
 1 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 554f713..24f7cee 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -362,12 +362,36 @@ static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev)
dvc_writel(i2c_dev, val, DVC_CTRL_REG1);
 }
 
+static inline int tegra_i2c_clock_enable(struct tegra_i2c_dev *i2c_dev)
+{
+   int ret;
+   ret = clk_prepare_enable(i2c_dev-fast_clk);
+   if (ret  0) {
+   dev_err(i2c_dev-dev,
+   Enabling fast clk failed, err %d\n, ret);
+   return ret;
+   }
+   ret = clk_prepare_enable(i2c_dev-div_clk);
+   if (ret  0) {
+   dev_err(i2c_dev-dev,
+   Enabling div clk failed, err %d\n, ret);
+   clk_disable_unprepare(i2c_dev-fast_clk);
+   }
+   return ret;
+}
+
+static inline void tegra_i2c_clock_disable(struct tegra_i2c_dev *i2c_dev)
+{
+   clk_disable_unprepare(i2c_dev-div_clk);
+   clk_disable_unprepare(i2c_dev-fast_clk);
+}
+
 static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 {
u32 val;
int err = 0;
 
-   clk_prepare_enable(i2c_dev-div_clk);
+   tegra_i2c_clock_enable(i2c_dev);
 
tegra_periph_reset_assert(i2c_dev-div_clk);
udelay(2);
@@ -398,7 +422,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
if (tegra_i2c_flush_fifos(i2c_dev))
err = -ETIMEDOUT;
 
-   clk_disable_unprepare(i2c_dev-div_clk);
+   tegra_i2c_clock_disable(i2c_dev);
 
if (i2c_dev-irq_disabled) {
i2c_dev-irq_disabled = 0;
@@ -584,7 +608,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
}
}
 
-   clk_prepare_enable(i2c_dev-clk);
+   tegra_i2c_clock_enable(i2c_dev);
for (i = 0; i  num; i++) {
enum msg_end_type end_type = MSG_END_STOP;
if (i  (num - 1)) {
@@ -597,7 +621,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
if (ret)
break;
}
-   clk_disable_unprepare(i2c_dev-div_clk);
+   tegra_i2c_clock_disable(i2c_dev);
return ret ?: i;
 }
 
@@ -734,8 +758,6 @@ static int __devinit tegra_i2c_probe(struct platform_device 
*pdev)
return ret;
}
 
-   clk_prepare_enable(i2c_dev-fast_clk);
-
i2c_set_adapdata(i2c_dev-adapter, i2c_dev);
i2c_dev-adapter.owner = THIS_MODULE;
i2c_dev-adapter.class = I2C_CLASS_HWMON;
@@ -749,7 +771,6 @@ static int __devinit tegra_i2c_probe(struct platform_device 
*pdev)
ret = i2c_add_numbered_adapter(i2c_dev-adapter);
if (ret) {
dev_err(pdev-dev, Failed to add I2C adapter\n);
-   clk_disable_unprepare(i2c_dev-fast_clk);
return ret;
}
 
-- 
1.7.1.1

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


Re: [PATCH] i2c: tegra: I2_M_NOSTART functionality not supported in Tegra20

2012-08-16 Thread Laxman Dewangan

On Tuesday 14 August 2012 10:19 PM, Stephen Warren wrote:

On 08/14/2012 03:19 AM, Laxman Dewangan wrote:

Tegra20 i2c controller does not support the continue transfer
which implements the I2C_M_NOSTART functionality of i2c
protocol mangling.
Removing the I2C_M_NOSTART functionality for Tegra20.

Signed-off-by: Laxman Dewanganldewan...@nvidia.com
Reported-by: Stephen Warrenswar...@nvidia.com

Tested-by: Stephen Warrenswar...@wwwdotorg.org

Note that if I take Laxman's I2C driver clock patches through the Tegra
tree, and Wolfram takes this patch through the I2C tree, there will be a
very slight conflict, since adjacent lines are touched. However, the
resolution is simple and obvious, so I think that's fine.


Stephen/Wolfram,
I have 2 more change to implement runtime PM and dynamic clock control 
for fast clock which I have planned for 3.7.
I think it will be better if this also goes on same tree where the clock 
related change are available to avoid the merge conflict.


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


[PATCH 1/4] ARM: tegra: clock: add i2c fast clock entry in clock table

2012-08-08 Thread Laxman Dewangan
Tegra's i2c controller require two clock sources named as
div-clk and fast-clk for proper operation.
Currently, the entry of fast-clk is missing in tegra30
clock table and it is incorrectly named in the tegra20
clock table.
Adds aliases to enable lookups for fast-clk to succeed.
A later patch will remove the incorrectly named clock,
once the driver is modified to use the new name.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
 arch/arm/mach-tegra/tegra20_clocks_data.c |4 
 arch/arm/mach-tegra/tegra30_clocks_data.c |5 +
 2 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-tegra/tegra20_clocks_data.c 
b/arch/arm/mach-tegra/tegra20_clocks_data.c
index b5c518e..7312ecd 100644
--- a/arch/arm/mach-tegra/tegra20_clocks_data.c
+++ b/arch/arm/mach-tegra/tegra20_clocks_data.c
@@ -1028,6 +1028,10 @@ static struct clk_duplicate tegra_clk_duplicates[] = {
CLK_DUPLICATE(cop,tegra-avp,cop),
CLK_DUPLICATE(vde,tegra-aes,vde),
CLK_DUPLICATE(cclk,   NULL,   cpu),
+   CLK_DUPLICATE(pll_p_out3, tegra-i2c.0, fast-clk),
+   CLK_DUPLICATE(pll_p_out3, tegra-i2c.1, fast-clk),
+   CLK_DUPLICATE(pll_p_out3, tegra-i2c.2, fast-clk),
+   CLK_DUPLICATE(pll_p_out3, tegra-i2c.3, fast-clk),
 };
 
 #define CLK(dev, con, ck)  \
diff --git a/arch/arm/mach-tegra/tegra30_clocks_data.c 
b/arch/arm/mach-tegra/tegra30_clocks_data.c
index c924240..eae85b7 100644
--- a/arch/arm/mach-tegra/tegra30_clocks_data.c
+++ b/arch/arm/mach-tegra/tegra30_clocks_data.c
@@ -1287,6 +1287,11 @@ struct clk_duplicate tegra_clk_duplicates[] = {
CLK_DUPLICATE(dam1, NULL, dam1),
CLK_DUPLICATE(dam2, NULL, dam2),
CLK_DUPLICATE(spdif_in, NULL, spdif_in),
+   CLK_DUPLICATE(pll_p_out3, tegra-i2c.0, fast-clk),
+   CLK_DUPLICATE(pll_p_out3, tegra-i2c.1, fast-clk),
+   CLK_DUPLICATE(pll_p_out3, tegra-i2c.2, fast-clk),
+   CLK_DUPLICATE(pll_p_out3, tegra-i2c.3, fast-clk),
+   CLK_DUPLICATE(pll_p_out3, tegra-i2c.4, fast-clk),
 };
 
 struct clk *tegra_ptr_clks[] = {
-- 
1.7.1.1

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


[PATCH 0/4] i2c: tegra: required clock support for controller

2012-08-08 Thread Laxman Dewangan
The Tegra's i2c controller required two clock sources for proper
operation named as div-clk and fast-clk.

Adding support to make sure that driver will get these clocks and 
enable before any transfer and disable after transfer completed.

Patch 1 add the entry of fast clock in clock table.
Patch 2 modify i2c driver to get the div and fast clock.
Patch 3 name the connection of the clock entry.
Patch 4 removes non-required entry from tegra20 clock table.

Laxman Dewangan (4):
  ARM: tegra: clock: add i2c fast clock entry in clock table
  i2c: tegra: pass proper name for getting clock
  ARM: tegra: clock: add connection name in i2c clock entry
  ARM: tegra: clock: remove unused clock entry for i2c

 arch/arm/mach-tegra/tegra20_clocks_data.c |   20 +---
 arch/arm/mach-tegra/tegra30_clocks_data.c |   15 ++---
 drivers/i2c/busses/i2c-tegra.c|   46 ++--
 3 files changed, 41 insertions(+), 40 deletions(-)

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


[PATCH 3/4] ARM: tegra: clock: add connection name in i2c clock entry

2012-08-08 Thread Laxman Dewangan
Add connection name div-clk for the i2c clock entry.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
 arch/arm/mach-tegra/tegra20_clocks_data.c |8 
 arch/arm/mach-tegra/tegra30_clocks_data.c |   10 +-
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-tegra/tegra20_clocks_data.c 
b/arch/arm/mach-tegra/tegra20_clocks_data.c
index 7312ecd..c1318c2 100644
--- a/arch/arm/mach-tegra/tegra20_clocks_data.c
+++ b/arch/arm/mach-tegra/tegra20_clocks_data.c
@@ -889,10 +889,10 @@ PERIPH_CLK(la,la,   NULL,   
76, 0x1f8,  2600,  mux_pllp_pllc_pllm_clkm, MUX
 PERIPH_CLK(owr,tegra_w1, NULL,   71, 0x1cc,  
2600,  mux_pllp_pllc_pllm_clkm, MUX | DIV_U71);
 PERIPH_CLK(nor,nor,  NULL,   42, 0x1d0,  
9200,  mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* requires min voltage 
*/
 PERIPH_CLK(mipi,   mipi, NULL,   50, 0x174,  
6000,  mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* scales with voltage 
*/
-PERIPH_CLK(i2c1,   tegra-i2c.0,  NULL,   12, 0x124,  
2600,  mux_pllp_pllc_pllm_clkm, MUX | DIV_U16);
-PERIPH_CLK(i2c2,   tegra-i2c.1,  NULL,   54, 0x198,  
2600,  mux_pllp_pllc_pllm_clkm, MUX | DIV_U16);
-PERIPH_CLK(i2c3,   tegra-i2c.2,  NULL,   67, 0x1b8,  
2600,  mux_pllp_pllc_pllm_clkm, MUX | DIV_U16);
-PERIPH_CLK(dvc,tegra-i2c.3,  NULL,   47, 0x128,  
2600,  mux_pllp_pllc_pllm_clkm, MUX | DIV_U16);
+PERIPH_CLK(i2c1,   tegra-i2c.0,  div-clk, 12,  0x124,  
2600,  mux_pllp_pllc_pllm_clkm, MUX | DIV_U16);
+PERIPH_CLK(i2c2,   tegra-i2c.1,  div-clk, 54,  0x198,  
2600,  mux_pllp_pllc_pllm_clkm, MUX | DIV_U16);
+PERIPH_CLK(i2c3,   tegra-i2c.2,  div-clk, 67,  0x1b8,  
2600,  mux_pllp_pllc_pllm_clkm, MUX | DIV_U16);
+PERIPH_CLK(dvc,tegra-i2c.3,  div-clk, 47,  0x128,  
2600,  mux_pllp_pllc_pllm_clkm, MUX | DIV_U16);
 PERIPH_CLK(i2c1_i2c,   tegra-i2c.0,  i2c,  0,  0,  
7200,  mux_pllp_out3,   0);
 PERIPH_CLK(i2c2_i2c,   tegra-i2c.1,  i2c,  0,  0,  
7200,  mux_pllp_out3,   0);
 PERIPH_CLK(i2c3_i2c,   tegra-i2c.2,  i2c,  0,  0,  
7200,  mux_pllp_out3,   0);
diff --git a/arch/arm/mach-tegra/tegra30_clocks_data.c 
b/arch/arm/mach-tegra/tegra30_clocks_data.c
index eae85b7..45da437 100644
--- a/arch/arm/mach-tegra/tegra30_clocks_data.c
+++ b/arch/arm/mach-tegra/tegra30_clocks_data.c
@@ -1070,11 +1070,11 @@ PERIPH_CLK(la,  la,   NULL,   
76, 0x1f8,  2600,  mux_pllp_pllc_pllm_clkm, MUX
 PERIPH_CLK(owr,tegra_w1, NULL,   71, 0x1cc,  
2600,  mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB);
 PERIPH_CLK(nor,nor,  NULL,   42, 0x1d0,  
12700, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71); /* requires min voltage 
*/
 PERIPH_CLK(mipi,   mipi, NULL,   50, 0x174,  
6000,  mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | PERIPH_ON_APB); /* 
scales with voltage */
-PERIPH_CLK(i2c1,   tegra-i2c.0,  NULL,   12, 0x124,  
2600,  mux_pllp_clkm,   MUX | DIV_U16 | PERIPH_ON_APB);
-PERIPH_CLK(i2c2,   tegra-i2c.1,  NULL,   54, 0x198,  
2600,  mux_pllp_clkm,   MUX | DIV_U16 | PERIPH_ON_APB);
-PERIPH_CLK(i2c3,   tegra-i2c.2,  NULL,   67, 0x1b8,  
2600,  mux_pllp_clkm,   MUX | DIV_U16 | PERIPH_ON_APB);
-PERIPH_CLK(i2c4,   tegra-i2c.3,  NULL,   103,0x3c4,  
2600,  mux_pllp_clkm,   MUX | DIV_U16 | PERIPH_ON_APB);
-PERIPH_CLK(i2c5,   tegra-i2c.4,  NULL,   47, 0x128,  
2600,  mux_pllp_clkm,   MUX | DIV_U16 | PERIPH_ON_APB);
+PERIPH_CLK(i2c1,   tegra-i2c.0,  div-clk, 12,  0x124,  
2600,  mux_pllp_clkm,   MUX | DIV_U16 | PERIPH_ON_APB);
+PERIPH_CLK(i2c2,   tegra-i2c.1,  div-clk, 54,  0x198,  
2600,  mux_pllp_clkm,   MUX | DIV_U16 | PERIPH_ON_APB);
+PERIPH_CLK(i2c3,   tegra-i2c.2,  div-clk, 67,  0x1b8,  
2600,  mux_pllp_clkm,   MUX | DIV_U16 | PERIPH_ON_APB);
+PERIPH_CLK(i2c4,   tegra-i2c.3,  div-clk, 103, 0x3c4,  
2600,  mux_pllp_clkm,   MUX | DIV_U16 | PERIPH_ON_APB);
+PERIPH_CLK(i2c5,   tegra-i2c.4,  div-clk, 47,  0x128,  
2600,  mux_pllp_clkm,   MUX | DIV_U16 | PERIPH_ON_APB);
 PERIPH_CLK(uarta,  tegra-uart.0, NULL,   6,  0x178,  
8, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71 | DIV_U71_UART | 
PERIPH_ON_APB);
 PERIPH_CLK(uartb,  tegra-uart.1, NULL,   7,  0x17c,  
8

[PATCH 4/4] ARM: tegra: clock: remove unused clock entry for i2c

2012-08-08 Thread Laxman Dewangan
Tegra20 clock table have the entry for clock (tegra_i2c.x, i2c)
which is no more require as driver acquire clock with name of
div-clk and fast-clk.
Remove these entries from table.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
 arch/arm/mach-tegra/tegra20_clocks_data.c |8 
 1 files changed, 0 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-tegra/tegra20_clocks_data.c 
b/arch/arm/mach-tegra/tegra20_clocks_data.c
index c1318c2..6516beb 100644
--- a/arch/arm/mach-tegra/tegra20_clocks_data.c
+++ b/arch/arm/mach-tegra/tegra20_clocks_data.c
@@ -893,10 +893,6 @@ PERIPH_CLK(i2c1,   tegra-i2c.0,  div-clk, 12,  
0x124,  2600,  mux_pllp_pllc_
 PERIPH_CLK(i2c2,   tegra-i2c.1,  div-clk, 54,  0x198,  
2600,  mux_pllp_pllc_pllm_clkm, MUX | DIV_U16);
 PERIPH_CLK(i2c3,   tegra-i2c.2,  div-clk, 67,  0x1b8,  
2600,  mux_pllp_pllc_pllm_clkm, MUX | DIV_U16);
 PERIPH_CLK(dvc,tegra-i2c.3,  div-clk, 47,  0x128,  
2600,  mux_pllp_pllc_pllm_clkm, MUX | DIV_U16);
-PERIPH_CLK(i2c1_i2c,   tegra-i2c.0,  i2c,  0,  0,  
7200,  mux_pllp_out3,   0);
-PERIPH_CLK(i2c2_i2c,   tegra-i2c.1,  i2c,  0,  0,  
7200,  mux_pllp_out3,   0);
-PERIPH_CLK(i2c3_i2c,   tegra-i2c.2,  i2c,  0,  0,  
7200,  mux_pllp_out3,   0);
-PERIPH_CLK(dvc_i2c,tegra-i2c.3,  i2c,  0,  0,  
7200,  mux_pllp_out3,   0);
 PERIPH_CLK(uarta,  tegra-uart.0, NULL,   6,  0x178,  
6, mux_pllp_pllc_pllm_clkm, MUX);
 PERIPH_CLK(uartb,  tegra-uart.1, NULL,   7,  0x17c,  
6, mux_pllp_pllc_pllm_clkm, MUX);
 PERIPH_CLK(uartc,  tegra-uart.2, NULL,   55, 0x1a0,  
6, mux_pllp_pllc_pllm_clkm, MUX);
@@ -962,10 +958,6 @@ static struct clk *tegra_list_clks[] = {
tegra_i2c2,
tegra_i2c3,
tegra_dvc,
-   tegra_i2c1_i2c,
-   tegra_i2c2_i2c,
-   tegra_i2c3_i2c,
-   tegra_dvc_i2c,
tegra_uarta,
tegra_uartb,
tegra_uartc,
-- 
1.7.1.1

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


[PATCH 2/4] i2c: tegra: pass proper name for getting clock

2012-08-08 Thread Laxman Dewangan
Tegra's i2c controller require two clock sources named as
div_clk and fast_clk.
This change make sure that driver pass the correct clock's
name when it acquires clock handle. Also change the
variable name to reflect the correct clock handles.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
 drivers/i2c/busses/i2c-tegra.c |   46 
 1 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 66eb53f..7149625 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -117,8 +117,8 @@ enum msg_end_type {
  * struct tegra_i2c_dev- per device i2c context
  * @dev: device reference for power management
  * @adapter: core i2c layer adapter information
- * @clk: clock reference for i2c controller
- * @i2c_clk: clock reference for i2c bus
+ * @div_clk: clock reference for div clock of i2c controller.
+ * @fast_clk: clock reference for fast clock of i2c controller.
  * @base: ioremapped registers cookie
  * @cont_id: i2c controller id, used for for packet header
  * @irq: irq number of transfer complete interrupt
@@ -134,8 +134,8 @@ enum msg_end_type {
 struct tegra_i2c_dev {
struct device *dev;
struct i2c_adapter adapter;
-   struct clk *clk;
-   struct clk *i2c_clk;
+   struct clk *div_clk;
+   struct clk *fast_clk;
void __iomem *base;
int cont_id;
int irq;
@@ -356,11 +356,11 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
u32 val;
int err = 0;
 
-   clk_prepare_enable(i2c_dev-clk);
+   clk_prepare_enable(i2c_dev-div_clk);
 
-   tegra_periph_reset_assert(i2c_dev-clk);
+   tegra_periph_reset_assert(i2c_dev-div_clk);
udelay(2);
-   tegra_periph_reset_deassert(i2c_dev-clk);
+   tegra_periph_reset_deassert(i2c_dev-div_clk);
 
if (i2c_dev-is_dvc)
tegra_dvc_init(i2c_dev);
@@ -369,7 +369,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
(0x2  I2C_CNFG_DEBOUNCE_CNT_SHIFT);
i2c_writel(i2c_dev, val, I2C_CNFG);
i2c_writel(i2c_dev, 0, I2C_INT_MASK);
-   clk_set_rate(i2c_dev-clk, i2c_dev-bus_clk_rate * 8);
+   clk_set_rate(i2c_dev-div_clk, i2c_dev-bus_clk_rate * 8);
 
if (!i2c_dev-is_dvc) {
u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG);
@@ -387,7 +387,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
if (tegra_i2c_flush_fifos(i2c_dev))
err = -ETIMEDOUT;
 
-   clk_disable_unprepare(i2c_dev-clk);
+   clk_disable_unprepare(i2c_dev-div_clk);
 
if (i2c_dev-irq_disabled) {
i2c_dev-irq_disabled = 0;
@@ -563,7 +563,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
if (i2c_dev-is_suspended)
return -EBUSY;
 
-   clk_prepare_enable(i2c_dev-clk);
+   clk_prepare_enable(i2c_dev-div_clk);
for (i = 0; i  num; i++) {
enum msg_end_type end_type = MSG_END_STOP;
if (i  (num - 1)) {
@@ -576,7 +576,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
if (ret)
break;
}
-   clk_disable_unprepare(i2c_dev-clk);
+   clk_disable_unprepare(i2c_dev-div_clk);
return ret ?: i;
 }
 
@@ -596,8 +596,8 @@ static int __devinit tegra_i2c_probe(struct platform_device 
*pdev)
struct tegra_i2c_dev *i2c_dev;
struct tegra_i2c_platform_data *pdata = pdev-dev.platform_data;
struct resource *res;
-   struct clk *clk;
-   struct clk *i2c_clk;
+   struct clk *div_clk;
+   struct clk *fast_clk;
const unsigned int *prop;
void __iomem *base;
int irq;
@@ -622,16 +622,16 @@ static int __devinit tegra_i2c_probe(struct 
platform_device *pdev)
}
irq = res-start;
 
-   clk = devm_clk_get(pdev-dev, NULL);
-   if (IS_ERR(clk)) {
+   div_clk = devm_clk_get(pdev-dev, div-clk);
+   if (IS_ERR(div_clk)) {
dev_err(pdev-dev, missing controller clock);
-   return PTR_ERR(clk);
+   return PTR_ERR(div_clk);
}
 
-   i2c_clk = devm_clk_get(pdev-dev, i2c);
-   if (IS_ERR(i2c_clk)) {
+   fast_clk = devm_clk_get(pdev-dev, fast-clk);
+   if (IS_ERR(fast_clk)) {
dev_err(pdev-dev, missing bus clock);
-   return PTR_ERR(i2c_clk);
+   return PTR_ERR(fast_clk);
}
 
i2c_dev = devm_kzalloc(pdev-dev, sizeof(*i2c_dev), GFP_KERNEL);
@@ -641,8 +641,8 @@ static int __devinit tegra_i2c_probe(struct platform_device 
*pdev)
}
 
i2c_dev-base = base;
-   i2c_dev-clk = clk;
-   i2c_dev-i2c_clk = i2c_clk;
+   i2c_dev-div_clk = div_clk;
+   i2c_dev-fast_clk = fast_clk;
i2c_dev-adapter.algo = tegra_i2c_algo;
i2c_dev-irq = irq

Re: [PATCH 0/4] i2c: tegra: required clock support for controller

2012-08-08 Thread Laxman Dewangan

On Wednesday 08 August 2012 01:21 PM, Laxman Dewangan wrote:

The Tegra's i2c controller required two clock sources for proper
operation named as div-clk and fast-clk.

Adding support to make sure that driver will get these clocks and
enable before any transfer and disable after transfer completed.

Patch 1 add the entry of fast clock in clock table.
Patch 2 modify i2c driver to get the div and fast clock.
Patch 3 name the connection of the clock entry.
Patch 4 removes non-required entry from tegra20 clock table.


Hi Wolfram/Stephen,
This patch series very much depends on the common clock changes happens 
on Tegra tree and I think it should go in Tegra common clock tree.


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


[PATCH] i2c: tegra: Fix ifdefs for suspend mode

2012-07-30 Thread Laxman Dewangan
CONFIG_PM covers runtime only PM.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
This patch will remove the compilation warning if CONFIG_PM_SLEEP
is not enabled.

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

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 66eb53f..9a08c57 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -712,7 +712,7 @@ static int __devexit tegra_i2c_remove(struct 
platform_device *pdev)
return 0;
 }
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 static int tegra_i2c_suspend(struct device *dev)
 {
struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
-- 
1.7.1.1

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


Re: [PATCH 0/7] PM / I2C: Convert platform I2C drivers to PM handling based on struct dev_pm_ops

2012-07-12 Thread Laxman Dewangan

On Thursday 12 July 2012 12:51 AM, Rafael J. Wysocki wrote:

[7/7] i2c-tegra: Use struct dev_pm_ops for power management



I did not get the 7/7 on my inbox and hence responding  here.
Looked change from link
https://lkml.org/lkml/2012/7/11/467

This is same as which I sent some days ago:
https://lkml.org/lkml/2012/7/10/275

I am fine with the change:

Acked-by: Laxman Dewangan ldewan...@nvidia.com
--
To unsubscribe from this list: send the line unsubscribe linux-i2c in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 5/5] i2c: tegra: convert normal suspend/resume to *_noirq

2012-07-12 Thread Laxman Dewangan

On Thursday 12 July 2012 04:05 PM, Wolfram Sang wrote:

* PGP Signed by an unknown key

On Tue, Jul 10, 2012 at 04:50:44PM +0530, Laxman Dewangan wrote:

To provide the late suspend and early resume for i2c
driver, convert the suspend/resume as
suspend-  suspend_noirq
resume -  resume_noirq

Signed-off-by: Laxman Dewanganldewan...@nvidia.com

Applied to next on top of Rafael's patches. Please have a look if I did
the fixup right.

Thanks for taking care.
Can you please point me your git path so that I can verify it?

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


Re: [PATCH 5/5] i2c: tegra: convert normal suspend/resume to *_noirq

2012-07-12 Thread Laxman Dewangan

On Thursday 12 July 2012 05:28 PM, Wolfram Sang wrote:

* PGP Signed by an unknown key



Can you please point me your git path so that I can verify it?

git://git.pengutronix.de/git/wsa/linux.git i2c-embedded/for-next

or

http://git.pengutronix.de/?p=wsa/linux.git;a=shortlog;h=refs/heads/i2c-embedded/for-next



The change is fine.  No issue here.

Thanks,
Laxman

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


[PATCH 0/5] i2c: tegra: Code cleanups and suspend/resume related changes

2012-07-10 Thread Laxman Dewangan
This patch series does:
- Code cleanups like removing unused variables, using already define function
- Use clock_disable_unprepare in place of clock_disable()
- Use dev_pm_ops for suspend/resume inplace of legacy suspend/resume callbacks.
- Convert suspend/resume to _noirq version to support late suspend/early resume.

Laxman Dewangan (5):
  i2c: tegra: remove unused member variable
  i2c: tegra: use clk_disable_unprepare in place of clk_disable
  i2c: tegra: use of_match_ptr() for match_table initialization
  i2c: tegra: Use struct dev_pm_ops for power management
  i2c: tegra: convert normal suspend/resume to *_noirq

 drivers/i2c/busses/i2c-tegra.c |   27 +++
 1 files changed, 15 insertions(+), 12 deletions(-)

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


[PATCH 5/5] i2c: tegra: convert normal suspend/resume to *_noirq

2012-07-10 Thread Laxman Dewangan
To provide the late suspend and early resume for i2c
driver, convert the suspend/resume as
suspend- suspend_noirq
resume - resume_noirq

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
 drivers/i2c/busses/i2c-tegra.c |8 
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 5f0572d..99e6ae5 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -713,7 +713,7 @@ static int __devexit tegra_i2c_remove(struct 
platform_device *pdev)
 }
 
 #ifdef CONFIG_PM
-static int tegra_i2c_suspend(struct device *dev)
+static int tegra_i2c_suspend_noirq(struct device *dev)
 {
struct platform_device *pdev = to_platform_device(dev);
struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
@@ -725,7 +725,7 @@ static int tegra_i2c_suspend(struct device *dev)
return 0;
 }
 
-static int tegra_i2c_resume(struct device *dev)
+static int tegra_i2c_resume_noirq(struct device *dev)
 {
struct platform_device *pdev = to_platform_device(dev);
struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
@@ -748,8 +748,8 @@ static int tegra_i2c_resume(struct device *dev)
 }
 
 static const struct dev_pm_ops tegra_i2c_dev_pm_ops = {
-   .suspend = tegra_i2c_suspend,
-   .resume = tegra_i2c_resume,
+   .suspend_noirq = tegra_i2c_suspend_noirq,
+   .resume_noirq = tegra_i2c_resume_noirq,
 };
 #define TEGRA_I2C_DEV_PM_OPS (tegra_i2c_dev_pm_ops)
 #else
-- 
1.7.1.1

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


[PATCH 4/5] i2c: tegra: Use struct dev_pm_ops for power management

2012-07-10 Thread Laxman Dewangan
Make the tegra i2c driver define its PM callbacks through
struct dev_pm_ops objects rather than by using legacy PM hooks
in struct platform_driver.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
 drivers/i2c/busses/i2c-tegra.c |   19 +--
 1 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 0792674..5f0572d 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -713,8 +713,9 @@ static int __devexit tegra_i2c_remove(struct 
platform_device *pdev)
 }
 
 #ifdef CONFIG_PM
-static int tegra_i2c_suspend(struct platform_device *pdev, pm_message_t state)
+static int tegra_i2c_suspend(struct device *dev)
 {
+   struct platform_device *pdev = to_platform_device(dev);
struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
 
i2c_lock_adapter(i2c_dev-adapter);
@@ -724,8 +725,9 @@ static int tegra_i2c_suspend(struct platform_device *pdev, 
pm_message_t state)
return 0;
 }
 
-static int tegra_i2c_resume(struct platform_device *pdev)
+static int tegra_i2c_resume(struct device *dev)
 {
+   struct platform_device *pdev = to_platform_device(dev);
struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
int ret;
 
@@ -744,6 +746,14 @@ static int tegra_i2c_resume(struct platform_device *pdev)
 
return 0;
 }
+
+static const struct dev_pm_ops tegra_i2c_dev_pm_ops = {
+   .suspend = tegra_i2c_suspend,
+   .resume = tegra_i2c_resume,
+};
+#define TEGRA_I2C_DEV_PM_OPS (tegra_i2c_dev_pm_ops)
+#else
+#define TEGRA_I2C_DEV_PM_OPS NULL
 #endif
 
 #if defined(CONFIG_OF)
@@ -759,14 +769,11 @@ MODULE_DEVICE_TABLE(of, tegra_i2c_of_match);
 static struct platform_driver tegra_i2c_driver = {
.probe   = tegra_i2c_probe,
.remove  = __devexit_p(tegra_i2c_remove),
-#ifdef CONFIG_PM
-   .suspend = tegra_i2c_suspend,
-   .resume  = tegra_i2c_resume,
-#endif
.driver  = {
.name  = tegra-i2c,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(tegra_i2c_of_match),
+   .pm = TEGRA_I2C_DEV_PM_OPS,
},
 };
 
-- 
1.7.1.1

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


[PATCH 1/5] i2c: tegra: remove unused member variable

2012-07-10 Thread Laxman Dewangan
Remove unused member variable iomem of the
i2c device structure.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
This patch is resend of earlier patch
 i2c: tegra: remove unused member variable.
and sending it as part fo series.

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

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index f15cd49..00cdc10 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -119,7 +119,6 @@ enum msg_end_type {
  * @adapter: core i2c layer adapter information
  * @clk: clock reference for i2c controller
  * @i2c_clk: clock reference for i2c bus
- * @iomem: memory resource for registers
  * @base: ioremapped registers cookie
  * @cont_id: i2c controller id, used for for packet header
  * @irq: irq number of transfer complete interrupt
@@ -137,7 +136,6 @@ struct tegra_i2c_dev {
struct i2c_adapter adapter;
struct clk *clk;
struct clk *i2c_clk;
-   struct resource *iomem;
void __iomem *base;
int cont_id;
int irq;
-- 
1.7.1.1

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


[PATCH 2/5] i2c: tegra: use clk_disable_unprepare in place of clk_disable

2012-07-10 Thread Laxman Dewangan
Use clk_disable_unprepare() inplace of clk_disable().
This was missed as part of moving clock enable/disable to
prepare/unprepare for using the common clock framework.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
This is already discussed in patch
[PATCH] i2c: tegra: use clk_disable_unprepare in place of clk_disable
for applying in Wolfram Tree. Resending this as patch series.

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

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 00cdc10..d071cf0 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -696,7 +696,7 @@ static int __devinit tegra_i2c_probe(struct platform_device 
*pdev)
ret = i2c_add_numbered_adapter(i2c_dev-adapter);
if (ret) {
dev_err(pdev-dev, Failed to add I2C adapter\n);
-   clk_disable(i2c_dev-i2c_clk);
+   clk_disable_unprepare(i2c_dev-i2c_clk);
return ret;
}
 
-- 
1.7.1.1

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


[PATCH 3/5] i2c: tegra: use of_match_ptr() for match_table initialization

2012-07-10 Thread Laxman Dewangan
In place of defining match_table for non-DT based as NULL,
use of_match_ptr() for initialzing the of_match_table.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
 drivers/i2c/busses/i2c-tegra.c |4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index d071cf0..0792674 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -754,8 +754,6 @@ static const struct of_device_id tegra_i2c_of_match[] 
__devinitconst = {
{},
 };
 MODULE_DEVICE_TABLE(of, tegra_i2c_of_match);
-#else
-#define tegra_i2c_of_match NULL
 #endif
 
 static struct platform_driver tegra_i2c_driver = {
@@ -768,7 +766,7 @@ static struct platform_driver tegra_i2c_driver = {
.driver  = {
.name  = tegra-i2c,
.owner = THIS_MODULE,
-   .of_match_table = tegra_i2c_of_match,
+   .of_match_table = of_match_ptr(tegra_i2c_of_match),
},
 };
 
-- 
1.7.1.1

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


[PATCH V2 1/5] i2c: tegra: remove unused member variable

2012-07-10 Thread Laxman Dewangan
Remove unused member variable iomem of the
i2c device structure.

This variable becomes unused when converted all allocation
to devm_* in following change:
i2c: tegra: make all resource allocation through devm_*

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
This patch is resend of earlier patch
 i2c: tegra: remove unused member variable.
and sending it as part fo series.

Changes from V1:
Adding more details in description why this variable becomes unused.
No change in code.

Remaining patches of this series will be still same, version V1.
If require, I will resend the series with new version.


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

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index f15cd49..00cdc10 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -119,7 +119,6 @@ enum msg_end_type {
  * @adapter: core i2c layer adapter information
  * @clk: clock reference for i2c controller
  * @i2c_clk: clock reference for i2c bus
- * @iomem: memory resource for registers
  * @base: ioremapped registers cookie
  * @cont_id: i2c controller id, used for for packet header
  * @irq: irq number of transfer complete interrupt
@@ -137,7 +136,6 @@ struct tegra_i2c_dev {
struct i2c_adapter adapter;
struct clk *clk;
struct clk *i2c_clk;
-   struct resource *iomem;
void __iomem *base;
int cont_id;
int irq;
-- 
1.7.1.1

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


Re: [PATCH] i2c: tegra: use clk_disable_unprepare in place of clk_disable

2012-06-27 Thread Laxman Dewangan

On Tuesday 26 June 2012 09:58 PM, Stephen Warren wrote:

On 06/26/2012 12:27 AM, Laxman Dewangan wrote:

On Monday 25 June 2012 09:25 PM, Stephen Warren wrote:

On 06/25/2012 03:46 AM, Laxman Dewangan wrote:

Stephen,

On Wednesday 20 June 2012 09:57 PM, Stephen Warren wrote:

On 06/20/2012 10:26 AM, Stephen Warren wrote:

On 06/20/2012 06:56 AM, Laxman Dewangan wrote:

Use clk_disable_unprepare() inplace of clk_disable().
This was missed as part of moving clock enable/disable to
prepare/unprepare for using the common clock framework.

...

I see no reason not to take the second patch in the series through the
I2C tree though.

Uggh. Ignore that paragraph - the other patch was sent separately
not as
a series.

so are you taking care of this patch or do I need to send the patch
based on your tree in place of linux-next?

Yes, this patch should be applied through the Tegra tree, since it will
be a dependency of the common clock framework switchover there, which I
hope to take place this kernel cycle.

I did just attempt to apply this patch to the for-3.6/common-clk branch,
but it doesn't apply:-( Could you please rebase and resend. Thanks.

Looked at your common_clk branch and the related code is not there.
The clk_disable() in the particular case is introduced by change
i2c: tegra: make all resource allocation through devm_*
which is not in your branch.

Then later Prashant post the change as
i2c: tegra: Add clk_prepare/clk_unprepare
and it does not accounted for the above patch.

So none of your local tree will have this issue.

OK. In that case, it's best if this patch goes through the I2C tree
since that's where the code is that it's modifying. This might not be
optimal for runtime git bisection depending on the order Linus ends up
merging things, but it's probably as good as we can do without
inter-twining the I2C and Tegra trees a lot.



Then it can go Wolfram's tree along with other patch
 i2c: tegra: remove unused member variable.

as some of previous i2c patches are in his tree.
--
To unsubscribe from this list: send the line unsubscribe linux-i2c in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] i2c: tegra: use clk_disable_unprepare in place of clk_disable

2012-06-26 Thread Laxman Dewangan

On Monday 25 June 2012 09:25 PM, Stephen Warren wrote:

On 06/25/2012 03:46 AM, Laxman Dewangan wrote:

Stephen,

On Wednesday 20 June 2012 09:57 PM, Stephen Warren wrote:

On 06/20/2012 10:26 AM, Stephen Warren wrote:

On 06/20/2012 06:56 AM, Laxman Dewangan wrote:

Use clk_disable_unprepare() inplace of clk_disable().
This was missed as part of moving clock enable/disable to
prepare/unprepare for using the common clock framework.

...

I see no reason not to take the second patch in the series through the
I2C tree though.

Uggh. Ignore that paragraph - the other patch was sent separately not as
a series.

so are you taking care of this patch or do I need to send the patch
based on your tree in place of linux-next?

Yes, this patch should be applied through the Tegra tree, since it will
be a dependency of the common clock framework switchover there, which I
hope to take place this kernel cycle.

I did just attempt to apply this patch to the for-3.6/common-clk branch,
but it doesn't apply:-( Could you please rebase and resend. Thanks.


Looked at your common_clk branch and the related code is not there.
The clk_disable() in the particular case is introduced by change
i2c: tegra: make all resource allocation through devm_*
which is not in your branch.

Then later Prashant post the change as
i2c: tegra: Add clk_prepare/clk_unprepare
and it does not accounted for the above patch.

So none of your local tree will have this issue.

You need to pull some of the change from Wofram's tree to you commn-clk 
to fix the issue.

Suggest to pull the change
i2c: tegra: make all resource allocation through devm_*
i2c: tegra: support for I2C_M_NOSTART functionality
i2c: tegra: add PROTOCOL_MANGLING as supported functionality.
i2c: tegra: make sure register writes completes





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


[PATCH] i2c: tegra: use clk_disable_unprepare in place of clk_disable

2012-06-20 Thread Laxman Dewangan
Use clk_disable_unprepare() inplace of clk_disable().
This was missed as part of moving clock enable/disable to
prepare/unprepare for using the common clock framework.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
 drivers/i2c/busses/i2c-tegra.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 00cdc10..d071cf0 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -696,7 +696,7 @@ static int __devinit tegra_i2c_probe(struct platform_device 
*pdev)
ret = i2c_add_numbered_adapter(i2c_dev-adapter);
if (ret) {
dev_err(pdev-dev, Failed to add I2C adapter\n);
-   clk_disable(i2c_dev-i2c_clk);
+   clk_disable_unprepare(i2c_dev-i2c_clk);
return ret;
}
 
-- 
1.7.1.1

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


Re: [PATCH V3 1/4] i2c: tegra: make sure register writes completes

2012-06-14 Thread Laxman Dewangan

On Wednesday 13 June 2012 09:25 PM, Stephen Warren wrote:

On 06/13/2012 04:12 AM, Laxman Dewangan wrote:
@@ -165,6 +165,10 @@ static void i2c_writel(struct tegra_i2c_dev 
*i2c_dev, u32 val,

unsigned long reg)
  {
writel(val, i2c_dev-base + tegra_i2c_reg_addr(i2c_dev, reg));
+
+   /* Read back register to make sure that register writes completed */
+   if (reg != I2C_TX_FIFO)
+   readl(i2c_dev-base + tegra_i2c_reg_addr(i2c_dev, reg));

I guess that's fine, but it sure does seem rather heavy-weight. Don't
you only need to do the readback if you just wrote to the IRQ status or
mask registers, rather than if you wrote to /any/ register other than
the FIFO?


That's what my second patch but based on your earlier review comment, I 
did for every register.


I think it will not matter much as we dont write all register with every 
transaction, only during initialization.
Then for each transfer we write manly on Tx fifo and interrupt 
mask/status register and hence not too much overweight.


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


[PATCH v3 0/4] i2c: tegra: Bug fixes, cleanups and M_NOSTART support

2012-06-13 Thread Laxman Dewangan
This patch series having the:
- Handling of late register write due to Tegra PPSB design.
- support for I2C_M_NOSTART
- Use devm_* for all allocation.

Changes from V1:
- Using the readback for mask/unmask of irq also.

Changes from V2:
- Read back is done whenever write happen in i2c register other than TX FIFO.


Laxman Dewangan (4):
  i2c: tegra: make sure register writes completes
  i2c: tegra: add PROTOCOL_MANGLING as supported functionality.
  i2c: tegra: support for I2C_M_NOSTART functionality
  i2c: tegra: make all resource allocation through devm_*

 drivers/i2c/busses/i2c-tegra.c |  110 ++--
 1 files changed, 60 insertions(+), 50 deletions(-)

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


[PATCH V3 3/4] i2c: tegra: support for I2C_M_NOSTART functionality

2012-06-13 Thread Laxman Dewangan
Adding support for functionality I2C_M_NOSTART.
When multiple message transfer request made through i2c
and if any message is flagged with I2C_M_NOSTART then
it will not send the start/repeat-start and address of
that message i.e. sends data directly.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
This is rebased of earlier patch on same support.
At this time using the new flag I2C_FUNC_NOSTART.

Changes form V1:
- Rebased on linux-next.

Changes from V2:
- Rebased based on Wolfram's tree.


 drivers/i2c/busses/i2c-tegra.c |   31 ++-
 1 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 68433ae..c4593a2 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -97,8 +97,21 @@
 #define I2C_HEADER_10BIT_ADDR  (118)
 #define I2C_HEADER_IE_ENABLE   (117)
 #define I2C_HEADER_REPEAT_START(116)
+#define I2C_HEADER_CONTINUE_XFER   (115)
 #define I2C_HEADER_MASTER_ADDR_SHIFT   12
 #define I2C_HEADER_SLAVE_ADDR_SHIFT1
+/*
+ * msg_end_type: The bus control which need to be send at end of transfer.
+ * @MSG_END_STOP: Send stop pulse at end of transfer.
+ * @MSG_END_REPEAT_START: Send repeat start at end of transfer.
+ * @MSG_END_CONTINUE: The following on message is coming and so do not send
+ * stop or repeat start.
+ */
+enum msg_end_type {
+   MSG_END_STOP,
+   MSG_END_REPEAT_START,
+   MSG_END_CONTINUE,
+};
 
 /**
  * struct tegra_i2c_dev- per device i2c context
@@ -453,7 +466,7 @@ err:
 }
 
 static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
-   struct i2c_msg *msg, int stop)
+   struct i2c_msg *msg, enum msg_end_type end_state)
 {
u32 packet_header;
u32 int_mask;
@@ -480,7 +493,9 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
 
packet_header = I2C_HEADER_IE_ENABLE;
-   if (!stop)
+   if (end_state == MSG_END_CONTINUE)
+   packet_header |= I2C_HEADER_CONTINUE_XFER;
+   else if (end_state == MSG_END_REPEAT_START)
packet_header |= I2C_HEADER_REPEAT_START;
if (msg-flags  I2C_M_TEN) {
packet_header |= msg-addr;
@@ -552,8 +567,14 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
 
clk_enable(i2c_dev-clk);
for (i = 0; i  num; i++) {
-   int stop = (i == (num - 1)) ? 1  : 0;
-   ret = tegra_i2c_xfer_msg(i2c_dev, msgs[i], stop);
+   enum msg_end_type end_type = MSG_END_STOP;
+   if (i  (num - 1)) {
+   if (msgs[i + 1].flags  I2C_M_NOSTART)
+   end_type = MSG_END_CONTINUE;
+   else
+   end_type = MSG_END_REPEAT_START;
+   }
+   ret = tegra_i2c_xfer_msg(i2c_dev, msgs[i], end_type);
if (ret)
break;
}
@@ -564,7 +585,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
 static u32 tegra_i2c_func(struct i2c_adapter *adap)
 {
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
-   I2C_FUNC_PROTOCOL_MANGLING;
+   I2C_FUNC_PROTOCOL_MANGLING | I2C_FUNC_NOSTART;
 }
 
 static const struct i2c_algorithm tegra_i2c_algo = {
-- 
1.7.1.1

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


[PATCH V3 1/4] i2c: tegra: make sure register writes completes

2012-06-13 Thread Laxman Dewangan
The Tegra PPSB (an peripheral bus) queues writes transactions.
In order to guarantee that writes have completed before a
certain time, a read transaction to a register on the same
bus must be executed.
This is necessary in situations such as when clearing an
interrupt status or enable, so that when returning from an
interrupt handler, the HW has already de-asserted its
interrupt status output, which will avoid spurious interrupts.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
Changes from V1:
- Using the readback for mask/unmask of irq also.

Changes from V2:
- Read back is done whenever write happen in i2c register other than TX FIFO.

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

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 8b2e555..785f7f7 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -165,6 +165,10 @@ static void i2c_writel(struct tegra_i2c_dev *i2c_dev, u32 
val,
unsigned long reg)
 {
writel(val, i2c_dev-base + tegra_i2c_reg_addr(i2c_dev, reg));
+
+   /* Read back register to make sure that register writes completed */
+   if (reg != I2C_TX_FIFO)
+   readl(i2c_dev-base + tegra_i2c_reg_addr(i2c_dev, reg));
 }
 
 static u32 i2c_readl(struct tegra_i2c_dev *i2c_dev, unsigned long reg)
-- 
1.7.1.1

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


[PATCH V3 2/4] i2c: tegra: add PROTOCOL_MANGLING as supported functionality.

2012-06-13 Thread Laxman Dewangan
The Tegra i2c driver supports the I2C_M_IGNORE_NAK and hence
returning I2C_FUNC_PROTOCOL_MANGLING as supported functionality.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
No Changes from V1 and V2.

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

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 785f7f7..68433ae 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -563,7 +563,8 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
 
 static u32 tegra_i2c_func(struct i2c_adapter *adap)
 {
-   return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR;
+   return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
+   I2C_FUNC_PROTOCOL_MANGLING;
 }
 
 static const struct i2c_algorithm tegra_i2c_algo = {
-- 
1.7.1.1

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


[PATCH V3 4/4] i2c: tegra: make all resource allocation through devm_*

2012-06-13 Thread Laxman Dewangan
Use the devm_* for the memory region allocation, interrupt request,
clock handler request.
By doing this, it does not require to explicitly free it and hence
saving some code.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
This is rebased of earlier similar patch and sending as
part of this series.

Changes form V1:
- Rebased on linux-next.

Changes from V2:
- Rebased based on Wolfram's tree.

 drivers/i2c/busses/i2c-tegra.c |   62 +++-
 1 files changed, 17 insertions(+), 45 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index c4593a2..9f4e22c 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -598,7 +598,6 @@ static int __devinit tegra_i2c_probe(struct platform_device 
*pdev)
struct tegra_i2c_dev *i2c_dev;
struct tegra_i2c_platform_data *pdata = pdev-dev.platform_data;
struct resource *res;
-   struct resource *iomem;
struct clk *clk;
struct clk *i2c_clk;
const unsigned int *prop;
@@ -611,50 +610,41 @@ static int __devinit tegra_i2c_probe(struct 
platform_device *pdev)
dev_err(pdev-dev, no mem resource\n);
return -EINVAL;
}
-   iomem = request_mem_region(res-start, resource_size(res), pdev-name);
-   if (!iomem) {
-   dev_err(pdev-dev, I2C region already claimed\n);
-   return -EBUSY;
-   }
 
-   base = ioremap(iomem-start, resource_size(iomem));
+   base = devm_request_and_ioremap(pdev-dev, res);
if (!base) {
-   dev_err(pdev-dev, Cannot ioremap I2C region\n);
-   return -ENOMEM;
+   dev_err(pdev-dev, Cannot request/ioremap I2C registers\n);
+   return -EADDRNOTAVAIL;
}
 
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res) {
dev_err(pdev-dev, no irq resource\n);
-   ret = -EINVAL;
-   goto err_iounmap;
+   return -EINVAL;
}
irq = res-start;
 
-   clk = clk_get(pdev-dev, NULL);
+   clk = devm_clk_get(pdev-dev, NULL);
if (IS_ERR(clk)) {
dev_err(pdev-dev, missing controller clock);
-   ret = PTR_ERR(clk);
-   goto err_release_region;
+   return PTR_ERR(clk);
}
 
-   i2c_clk = clk_get(pdev-dev, i2c);
+   i2c_clk = devm_clk_get(pdev-dev, i2c);
if (IS_ERR(i2c_clk)) {
dev_err(pdev-dev, missing bus clock);
-   ret = PTR_ERR(i2c_clk);
-   goto err_clk_put;
+   return PTR_ERR(i2c_clk);
}
 
-   i2c_dev = kzalloc(sizeof(struct tegra_i2c_dev), GFP_KERNEL);
+   i2c_dev = devm_kzalloc(pdev-dev, sizeof(*i2c_dev), GFP_KERNEL);
if (!i2c_dev) {
-   ret = -ENOMEM;
-   goto err_i2c_clk_put;
+   dev_err(pdev-dev, Could not allocate struct tegra_i2c_dev);
+   return -ENOMEM;
}
 
i2c_dev-base = base;
i2c_dev-clk = clk;
i2c_dev-i2c_clk = i2c_clk;
-   i2c_dev-iomem = iomem;
i2c_dev-adapter.algo = tegra_i2c_algo;
i2c_dev-irq = irq;
i2c_dev-cont_id = pdev-id;
@@ -683,13 +673,14 @@ static int __devinit tegra_i2c_probe(struct 
platform_device *pdev)
ret = tegra_i2c_init(i2c_dev);
if (ret) {
dev_err(pdev-dev, Failed to initialize i2c controller);
-   goto err_free;
+   return ret;
}
 
-   ret = request_irq(i2c_dev-irq, tegra_i2c_isr, 0, pdev-name, i2c_dev);
+   ret = devm_request_irq(pdev-dev, i2c_dev-irq,
+   tegra_i2c_isr, 0, pdev-name, i2c_dev);
if (ret) {
dev_err(pdev-dev, Failed to request irq %i\n, i2c_dev-irq);
-   goto err_free;
+   return ret;
}
 
clk_enable(i2c_dev-i2c_clk);
@@ -707,38 +698,19 @@ static int __devinit tegra_i2c_probe(struct 
platform_device *pdev)
ret = i2c_add_numbered_adapter(i2c_dev-adapter);
if (ret) {
dev_err(pdev-dev, Failed to add I2C adapter\n);
-   goto err_free_irq;
+   clk_disable(i2c_dev-i2c_clk);
+   return ret;
}
 
of_i2c_register_devices(i2c_dev-adapter);
 
return 0;
-err_free_irq:
-   free_irq(i2c_dev-irq, i2c_dev);
-err_free:
-   kfree(i2c_dev);
-err_i2c_clk_put:
-   clk_put(i2c_clk);
-err_clk_put:
-   clk_put(clk);
-err_release_region:
-   release_mem_region(iomem-start, resource_size(iomem));
-err_iounmap:
-   iounmap(base);
-   return ret;
 }
 
 static int __devexit tegra_i2c_remove(struct platform_device *pdev)
 {
struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
i2c_del_adapter(i2c_dev-adapter);
-   free_irq(i2c_dev-irq, i2c_dev);
-   clk_put(i2c_dev-i2c_clk);
-   clk_put(i2c_dev-clk

Re: [PATCH 1/4] i2c: tegra: make sure register writes completes

2012-06-12 Thread Laxman Dewangan

On Tuesday 12 June 2012 01:24 PM, Wolfram Sang wrote:

* PGP Signed by an unknown key

On Tue, Jun 05, 2012 at 06:39:57PM +0530, Laxman Dewangan wrote:

@@ -430,6 +430,13 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
if (i2c_dev-is_dvc)
dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);

+   /*
+* Register write get queued in the PPSB bus and write can
+* happen later. Read back register to make sure that register
+* write is completed.
+*/
+   i2c_readl(i2c_dev, I2C_INT_STATUS);

Does it make sense to put the read into i2c_writel?

We can not put in i2c_writel() as we also do fifo write using this and 
writing and reading back fifo can drainout the fifo.

hence putting this here seems more appropriate.

+
if (status  I2C_INT_PACKET_XFER_COMPLETE) {
BUG_ON(i2c_dev-msg_buf_remaining);
complete(i2c_dev-msg_complete);
@@ -444,6 +451,9 @@ err:
if (i2c_dev-is_dvc)
dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);

+   /* Read back register to make sure that register writes completed */
+   i2c_readl(i2c_dev, I2C_INT_STATUS);
+
complete(i2c_dev-msg_complete);
return IRQ_HANDLED;
  }
@@ -505,6 +515,9 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
ret = wait_for_completion_timeout(i2c_dev-msg_complete, 
TEGRA_I2C_TIMEOUT);
tegra_i2c_mask_irq(i2c_dev, int_mask);

+   /* Read back register to make sure that register writes completed */
+   i2c_readl(i2c_dev, I2C_INT_MASK);
+

It definately makes sense to put this read into tegra_i2c_mask_irq()?

Ok, fine with me. I put the read back logic inside mask_irq() and 
unmask_irq().

Will send the fix in next patch.

if (WARN_ON(ret == 0)) {
dev_err(i2c_dev-dev, i2c transfer timed out\n);

Regards,

Wolfram



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


[PATCH v2 0/4] i2c: tegra: Bug fixes, cleanups and M_NOSTART support

2012-06-12 Thread Laxman Dewangan
This patch series having the:
- Handling of late register write due to Tegra PPSB design.
- support for I2C_M_NOSTART
- Use devm_* for all allocation.

Changes from V1:
Taking care of review comment from Wolfram in patch 1/4.

Laxman Dewangan (4):
  i2c: tegra: make sure register writes completes
  i2c: tegra: add PROTOCOL_MANGLING as supported functionality.
  i2c: tegra: support for I2C_M_NOSTART functionality
  i2c: tegra: make all resource allocation through devm_*

 drivers/i2c/busses/i2c-tegra.c |  110 ++--
 1 files changed, 60 insertions(+), 50 deletions(-)

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


[PATCH V2 3/4] i2c: tegra: support for I2C_M_NOSTART functionality

2012-06-12 Thread Laxman Dewangan
Adding support for functionality I2C_M_NOSTART.
When multiple message transfer request made through i2c
and if any message is flagged with I2C_M_NOSTART then
it will not send the start/repeat-start and address of
that message i.e. sends data directly.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
This is rebased of earlier patch on same support.
At this time using the new flag I2C_FUNC_NOSTART.

No change from V1.

 drivers/i2c/busses/i2c-tegra.c |   31 ++-
 1 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index f906487..b093b66 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -97,8 +97,21 @@
 #define I2C_HEADER_10BIT_ADDR  (118)
 #define I2C_HEADER_IE_ENABLE   (117)
 #define I2C_HEADER_REPEAT_START(116)
+#define I2C_HEADER_CONTINUE_XFER   (115)
 #define I2C_HEADER_MASTER_ADDR_SHIFT   12
 #define I2C_HEADER_SLAVE_ADDR_SHIFT1
+/*
+ * msg_end_type: The bus control which need to be send at end of transfer.
+ * @MSG_END_STOP: Send stop pulse at end of transfer.
+ * @MSG_END_REPEAT_START: Send repeat start at end of transfer.
+ * @MSG_END_CONTINUE: The following on message is coming and so do not send
+ * stop or repeat start.
+ */
+enum msg_end_type {
+   MSG_END_STOP,
+   MSG_END_REPEAT_START,
+   MSG_END_CONTINUE,
+};
 
 /**
  * struct tegra_i2c_dev- per device i2c context
@@ -465,7 +478,7 @@ err:
 }
 
 static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
-   struct i2c_msg *msg, int stop)
+   struct i2c_msg *msg, enum msg_end_type end_state)
 {
u32 packet_header;
u32 int_mask;
@@ -492,7 +505,9 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
 
packet_header = I2C_HEADER_IE_ENABLE;
-   if (!stop)
+   if (end_state == MSG_END_CONTINUE)
+   packet_header |= I2C_HEADER_CONTINUE_XFER;
+   else if (end_state == MSG_END_REPEAT_START)
packet_header |= I2C_HEADER_REPEAT_START;
if (msg-flags  I2C_M_TEN) {
packet_header |= msg-addr;
@@ -564,8 +579,14 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
 
clk_prepare_enable(i2c_dev-clk);
for (i = 0; i  num; i++) {
-   int stop = (i == (num - 1)) ? 1  : 0;
-   ret = tegra_i2c_xfer_msg(i2c_dev, msgs[i], stop);
+   enum msg_end_type end_type = MSG_END_STOP;
+   if (i  (num - 1)) {
+   if (msgs[i + 1].flags  I2C_M_NOSTART)
+   end_type = MSG_END_CONTINUE;
+   else
+   end_type = MSG_END_REPEAT_START;
+   }
+   ret = tegra_i2c_xfer_msg(i2c_dev, msgs[i], end_type);
if (ret)
break;
}
@@ -576,7 +597,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
 static u32 tegra_i2c_func(struct i2c_adapter *adap)
 {
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
-   I2C_FUNC_PROTOCOL_MANGLING;
+   I2C_FUNC_PROTOCOL_MANGLING | I2C_FUNC_NOSTART;
 }
 
 static const struct i2c_algorithm tegra_i2c_algo = {
-- 
1.7.1.1

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


[PATCH V2 4/4] i2c: tegra: make all resource allocation through devm_*

2012-06-12 Thread Laxman Dewangan
Use the devm_* for the memory region allocation, interrupt request,
clock handler request.
By doing this, it does not require to explicitly free it and hence
saving some code.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
This is rebased of earlier similar patch and sending as
part of this series.
No change from V1.

 drivers/i2c/busses/i2c-tegra.c |   62 +++-
 1 files changed, 17 insertions(+), 45 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index b093b66..2ace6ac 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -610,7 +610,6 @@ static int __devinit tegra_i2c_probe(struct platform_device 
*pdev)
struct tegra_i2c_dev *i2c_dev;
struct tegra_i2c_platform_data *pdata = pdev-dev.platform_data;
struct resource *res;
-   struct resource *iomem;
struct clk *clk;
struct clk *i2c_clk;
const unsigned int *prop;
@@ -623,50 +622,41 @@ static int __devinit tegra_i2c_probe(struct 
platform_device *pdev)
dev_err(pdev-dev, no mem resource\n);
return -EINVAL;
}
-   iomem = request_mem_region(res-start, resource_size(res), pdev-name);
-   if (!iomem) {
-   dev_err(pdev-dev, I2C region already claimed\n);
-   return -EBUSY;
-   }
 
-   base = ioremap(iomem-start, resource_size(iomem));
+   base = devm_request_and_ioremap(pdev-dev, res);
if (!base) {
-   dev_err(pdev-dev, Cannot ioremap I2C region\n);
-   return -ENOMEM;
+   dev_err(pdev-dev, Cannot request/ioremap I2C registers\n);
+   return -EADDRNOTAVAIL;
}
 
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res) {
dev_err(pdev-dev, no irq resource\n);
-   ret = -EINVAL;
-   goto err_iounmap;
+   return -EINVAL;
}
irq = res-start;
 
-   clk = clk_get(pdev-dev, NULL);
+   clk = devm_clk_get(pdev-dev, NULL);
if (IS_ERR(clk)) {
dev_err(pdev-dev, missing controller clock);
-   ret = PTR_ERR(clk);
-   goto err_release_region;
+   return PTR_ERR(clk);
}
 
-   i2c_clk = clk_get(pdev-dev, i2c);
+   i2c_clk = devm_clk_get(pdev-dev, i2c);
if (IS_ERR(i2c_clk)) {
dev_err(pdev-dev, missing bus clock);
-   ret = PTR_ERR(i2c_clk);
-   goto err_clk_put;
+   return PTR_ERR(i2c_clk);
}
 
-   i2c_dev = kzalloc(sizeof(struct tegra_i2c_dev), GFP_KERNEL);
+   i2c_dev = devm_kzalloc(pdev-dev, sizeof(*i2c_dev), GFP_KERNEL);
if (!i2c_dev) {
-   ret = -ENOMEM;
-   goto err_i2c_clk_put;
+   dev_err(pdev-dev, Could not allocate struct tegra_i2c_dev);
+   return -ENOMEM;
}
 
i2c_dev-base = base;
i2c_dev-clk = clk;
i2c_dev-i2c_clk = i2c_clk;
-   i2c_dev-iomem = iomem;
i2c_dev-adapter.algo = tegra_i2c_algo;
i2c_dev-irq = irq;
i2c_dev-cont_id = pdev-id;
@@ -695,13 +685,14 @@ static int __devinit tegra_i2c_probe(struct 
platform_device *pdev)
ret = tegra_i2c_init(i2c_dev);
if (ret) {
dev_err(pdev-dev, Failed to initialize i2c controller);
-   goto err_free;
+   return ret;
}
 
-   ret = request_irq(i2c_dev-irq, tegra_i2c_isr, 0, pdev-name, i2c_dev);
+   ret = devm_request_irq(pdev-dev, i2c_dev-irq,
+   tegra_i2c_isr, 0, pdev-name, i2c_dev);
if (ret) {
dev_err(pdev-dev, Failed to request irq %i\n, i2c_dev-irq);
-   goto err_free;
+   return ret;
}
 
clk_prepare_enable(i2c_dev-i2c_clk);
@@ -719,38 +710,19 @@ static int __devinit tegra_i2c_probe(struct 
platform_device *pdev)
ret = i2c_add_numbered_adapter(i2c_dev-adapter);
if (ret) {
dev_err(pdev-dev, Failed to add I2C adapter\n);
-   goto err_free_irq;
+   clk_disable(i2c_dev-i2c_clk);
+   return ret;
}
 
of_i2c_register_devices(i2c_dev-adapter);
 
return 0;
-err_free_irq:
-   free_irq(i2c_dev-irq, i2c_dev);
-err_free:
-   kfree(i2c_dev);
-err_i2c_clk_put:
-   clk_put(i2c_clk);
-err_clk_put:
-   clk_put(clk);
-err_release_region:
-   release_mem_region(iomem-start, resource_size(iomem));
-err_iounmap:
-   iounmap(base);
-   return ret;
 }
 
 static int __devexit tegra_i2c_remove(struct platform_device *pdev)
 {
struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
i2c_del_adapter(i2c_dev-adapter);
-   free_irq(i2c_dev-irq, i2c_dev);
-   clk_put(i2c_dev-i2c_clk);
-   clk_put(i2c_dev-clk);
-   release_mem_region(i2c_dev-iomem-start,
-   resource_size

[PATCH V2 2/4] i2c: tegra: add PROTOCOL_MANGLING as supported functionality.

2012-06-12 Thread Laxman Dewangan
The Tegra i2c driver supports the I2C_M_IGNORE_NAK and hence
returning I2C_FUNC_PROTOCOL_MANGLING as supported functionality.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
No change from V1,

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

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 753519a..f906487 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -575,7 +575,8 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
 
 static u32 tegra_i2c_func(struct i2c_adapter *adap)
 {
-   return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR;
+   return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
+   I2C_FUNC_PROTOCOL_MANGLING;
 }
 
 static const struct i2c_algorithm tegra_i2c_algo = {
-- 
1.7.1.1

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


[PATCH V2 1/4] i2c: tegra: make sure register writes completes

2012-06-12 Thread Laxman Dewangan
The Tegra PPSB (an peripheral bus) queues writes transactions.
In order to guarantee that writes have completed before a
certain time, a read transaction to a register on the same
bus must be executed.
This is necessary in situations such as when clearing an
interrupt status or enable, so that when returning from an
interrupt handler, the HW has already de-asserted its
interrupt status output, which will avoid spurious interrupts.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
changes from V1:
Taken care of Wolfram's review comment.

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

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 3da7ee3..753519a 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -189,6 +189,9 @@ static void tegra_i2c_mask_irq(struct tegra_i2c_dev 
*i2c_dev, u32 mask)
u32 int_mask = i2c_readl(i2c_dev, I2C_INT_MASK);
int_mask = ~mask;
i2c_writel(i2c_dev, int_mask, I2C_INT_MASK);
+
+   /* Read back register to make sure that register writes completed */
+   i2c_readl(i2c_dev, I2C_INT_MASK);
 }
 
 static void tegra_i2c_unmask_irq(struct tegra_i2c_dev *i2c_dev, u32 mask)
@@ -196,6 +199,9 @@ static void tegra_i2c_unmask_irq(struct tegra_i2c_dev 
*i2c_dev, u32 mask)
u32 int_mask = i2c_readl(i2c_dev, I2C_INT_MASK);
int_mask |= mask;
i2c_writel(i2c_dev, int_mask, I2C_INT_MASK);
+
+   /* Read back register to make sure that register writes completed */
+   i2c_readl(i2c_dev, I2C_INT_MASK);
 }
 
 static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
@@ -430,6 +436,13 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
if (i2c_dev-is_dvc)
dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);
 
+   /*
+* Register write get queued in the PPSB bus and write can
+* happen later. Read back register to make sure that register
+* write is completed.
+*/
+   i2c_readl(i2c_dev, I2C_INT_STATUS);
+
if (status  I2C_INT_PACKET_XFER_COMPLETE) {
BUG_ON(i2c_dev-msg_buf_remaining);
complete(i2c_dev-msg_complete);
@@ -444,6 +457,9 @@ err:
if (i2c_dev-is_dvc)
dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);
 
+   /* Read back register to make sure that register writes completed */
+   i2c_readl(i2c_dev, I2C_INT_STATUS);
+
complete(i2c_dev-msg_complete);
return IRQ_HANDLED;
 }
-- 
1.7.1.1

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


[PATCH 3/4] i2c: tegra: support for I2C_M_NOSTART functionality

2012-06-05 Thread Laxman Dewangan
Adding support for functionality I2C_M_NOSTART.
When multiple message transfer request made through i2c
and if any message is flagged with I2C_M_NOSTART then
it will not send the start/repeat-start and address of
that message i.e. sends data directly.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
This is rebased of earlier patch on same support.
At this time using the new flag I2C_FUNC_NOSTART.

 drivers/i2c/busses/i2c-tegra.c |   31 ++-
 1 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 36d8725..4cc9594 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -97,8 +97,21 @@
 #define I2C_HEADER_10BIT_ADDR  (118)
 #define I2C_HEADER_IE_ENABLE   (117)
 #define I2C_HEADER_REPEAT_START(116)
+#define I2C_HEADER_CONTINUE_XFER   (115)
 #define I2C_HEADER_MASTER_ADDR_SHIFT   12
 #define I2C_HEADER_SLAVE_ADDR_SHIFT1
+/*
+ * msg_end_type: The bus control which need to be send at end of transfer.
+ * @MSG_END_STOP: Send stop pulse at end of transfer.
+ * @MSG_END_REPEAT_START: Send repeat start at end of transfer.
+ * @MSG_END_CONTINUE: The following on message is coming and so do not send
+ * stop or repeat start.
+ */
+enum msg_end_type {
+   MSG_END_STOP,
+   MSG_END_REPEAT_START,
+   MSG_END_CONTINUE,
+};
 
 /**
  * struct tegra_i2c_dev- per device i2c context
@@ -459,7 +472,7 @@ err:
 }
 
 static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
-   struct i2c_msg *msg, int stop)
+   struct i2c_msg *msg, enum msg_end_type end_state)
 {
u32 packet_header;
u32 int_mask;
@@ -486,7 +499,9 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
 
packet_header = I2C_HEADER_IE_ENABLE;
-   if (!stop)
+   if (end_state == MSG_END_CONTINUE)
+   packet_header |= I2C_HEADER_CONTINUE_XFER;
+   else if (end_state == MSG_END_REPEAT_START)
packet_header |= I2C_HEADER_REPEAT_START;
if (msg-flags  I2C_M_TEN) {
packet_header |= msg-addr;
@@ -561,8 +576,14 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
 
clk_enable(i2c_dev-clk);
for (i = 0; i  num; i++) {
-   int stop = (i == (num - 1)) ? 1  : 0;
-   ret = tegra_i2c_xfer_msg(i2c_dev, msgs[i], stop);
+   enum msg_end_type end_type = MSG_END_STOP;
+   if (i  (num - 1)) {
+   if (msgs[i + 1].flags  I2C_M_NOSTART)
+   end_type = MSG_END_CONTINUE;
+   else
+   end_type = MSG_END_REPEAT_START;
+   }
+   ret = tegra_i2c_xfer_msg(i2c_dev, msgs[i], end_type);
if (ret)
break;
}
@@ -573,7 +594,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
 static u32 tegra_i2c_func(struct i2c_adapter *adap)
 {
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
-   I2C_FUNC_PROTOCOL_MANGLING;
+   I2C_FUNC_PROTOCOL_MANGLING | I2C_FUNC_NOSTART;
 }
 
 static const struct i2c_algorithm tegra_i2c_algo = {
-- 
1.7.1.1

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


[PATCH 4/4] i2c: tegra: make all resource allocation through devm_*

2012-06-05 Thread Laxman Dewangan
Use the devm_* for the memory region allocation, interrupt request,
clock handler request.
By doing this, it does not require to explicitly free it and hence
saving some code.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
This is rebased of earlier similar patch and sending as
part of this series.

 drivers/i2c/busses/i2c-tegra.c |   62 +++-
 1 files changed, 17 insertions(+), 45 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 4cc9594..6745631 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -607,7 +607,6 @@ static int __devinit tegra_i2c_probe(struct platform_device 
*pdev)
struct tegra_i2c_dev *i2c_dev;
struct tegra_i2c_platform_data *pdata = pdev-dev.platform_data;
struct resource *res;
-   struct resource *iomem;
struct clk *clk;
struct clk *i2c_clk;
const unsigned int *prop;
@@ -620,50 +619,41 @@ static int __devinit tegra_i2c_probe(struct 
platform_device *pdev)
dev_err(pdev-dev, no mem resource\n);
return -EINVAL;
}
-   iomem = request_mem_region(res-start, resource_size(res), pdev-name);
-   if (!iomem) {
-   dev_err(pdev-dev, I2C region already claimed\n);
-   return -EBUSY;
-   }
 
-   base = ioremap(iomem-start, resource_size(iomem));
+   base = devm_request_and_ioremap(pdev-dev, res);
if (!base) {
-   dev_err(pdev-dev, Cannot ioremap I2C region\n);
-   return -ENOMEM;
+   dev_err(pdev-dev, Cannot request/ioremap I2C registers\n);
+   return -EADDRNOTAVAIL;
}
 
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res) {
dev_err(pdev-dev, no irq resource\n);
-   ret = -EINVAL;
-   goto err_iounmap;
+   return -EINVAL;
}
irq = res-start;
 
-   clk = clk_get(pdev-dev, NULL);
+   clk = devm_clk_get(pdev-dev, NULL);
if (IS_ERR(clk)) {
dev_err(pdev-dev, missing controller clock);
-   ret = PTR_ERR(clk);
-   goto err_release_region;
+   return PTR_ERR(clk);
}
 
-   i2c_clk = clk_get(pdev-dev, i2c);
+   i2c_clk = devm_clk_get(pdev-dev, i2c);
if (IS_ERR(i2c_clk)) {
dev_err(pdev-dev, missing bus clock);
-   ret = PTR_ERR(i2c_clk);
-   goto err_clk_put;
+   return PTR_ERR(i2c_clk);
}
 
-   i2c_dev = kzalloc(sizeof(struct tegra_i2c_dev), GFP_KERNEL);
+   i2c_dev = devm_kzalloc(pdev-dev, sizeof(*i2c_dev), GFP_KERNEL);
if (!i2c_dev) {
-   ret = -ENOMEM;
-   goto err_i2c_clk_put;
+   dev_err(pdev-dev, Could not allocate struct tegra_i2c_dev);
+   return -ENOMEM;
}
 
i2c_dev-base = base;
i2c_dev-clk = clk;
i2c_dev-i2c_clk = i2c_clk;
-   i2c_dev-iomem = iomem;
i2c_dev-adapter.algo = tegra_i2c_algo;
i2c_dev-irq = irq;
i2c_dev-cont_id = pdev-id;
@@ -692,13 +682,14 @@ static int __devinit tegra_i2c_probe(struct 
platform_device *pdev)
ret = tegra_i2c_init(i2c_dev);
if (ret) {
dev_err(pdev-dev, Failed to initialize i2c controller);
-   goto err_free;
+   return ret;
}
 
-   ret = request_irq(i2c_dev-irq, tegra_i2c_isr, 0, pdev-name, i2c_dev);
+   ret = devm_request_irq(pdev-dev, i2c_dev-irq,
+   tegra_i2c_isr, 0, pdev-name, i2c_dev);
if (ret) {
dev_err(pdev-dev, Failed to request irq %i\n, i2c_dev-irq);
-   goto err_free;
+   return ret;
}
 
clk_enable(i2c_dev-i2c_clk);
@@ -716,38 +707,19 @@ static int __devinit tegra_i2c_probe(struct 
platform_device *pdev)
ret = i2c_add_numbered_adapter(i2c_dev-adapter);
if (ret) {
dev_err(pdev-dev, Failed to add I2C adapter\n);
-   goto err_free_irq;
+   clk_disable(i2c_dev-i2c_clk);
+   return ret;
}
 
of_i2c_register_devices(i2c_dev-adapter);
 
return 0;
-err_free_irq:
-   free_irq(i2c_dev-irq, i2c_dev);
-err_free:
-   kfree(i2c_dev);
-err_i2c_clk_put:
-   clk_put(i2c_clk);
-err_clk_put:
-   clk_put(clk);
-err_release_region:
-   release_mem_region(iomem-start, resource_size(iomem));
-err_iounmap:
-   iounmap(base);
-   return ret;
 }
 
 static int __devexit tegra_i2c_remove(struct platform_device *pdev)
 {
struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
i2c_del_adapter(i2c_dev-adapter);
-   free_irq(i2c_dev-irq, i2c_dev);
-   clk_put(i2c_dev-i2c_clk);
-   clk_put(i2c_dev-clk);
-   release_mem_region(i2c_dev-iomem-start,
-   resource_size(i2c_dev-iomem

Re: [PATCH 0/4] i2c: tegra: Bug fixes, cleanups and M_NOSTART support

2012-06-05 Thread Laxman Dewangan

On Tuesday 05 June 2012 09:44 PM, Stephen Warren wrote:

On 06/05/2012 07:09 AM, Laxman Dewangan wrote:

This patch series having the:
- Handling of late register write due to Tegra PPSB design.
- support for I2C_M_NOSTART
- Use devm_* for all allocation.

The series,

Acked-by: Stephen Warrenswar...@wwwdotorg.org

Note that patch 4 touches context adjacent to Prashant's i2c: tegra:
Add clk_prepare/clk_unprepare patch, which I hope to take through the
Tegra tree since it's a requirement for the Tegra common clock
conversion. I don't think this will cause any significant conflict, but
perhaps it's worth resolving it explicitly.

Wolfram, perhaps we should put these 4 patches and Prashan'ts into their
own topic branch so that you can merge it into the I2C tree, and I can
merge it into the Tegra tree too? Or, I can take everything through
Tegra if you want, and ack it.

Laxman, do you expect any more I2C-related changes this kernel cycle?

I have two more changes in plan:
-I2c controller require two clock source and the fixes towards that. 
This can go on Tegra tree as changes are require in 
mach-tegra/tegra30_clock.c, tegra20_clock.c files also.


- Run time PM support but can be done later.







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


Re: [PATCH V1 1/2] i2c: tegra: fix 10bit address configuration

2012-05-03 Thread Laxman Dewangan

On Thursday 03 May 2012 01:48 PM, Wolfram Sang wrote:

* PGP Signed by an unknown key

On Thu, May 03, 2012 at 11:43:14AM +0530, Laxman Dewangan wrote:

On Tuesday 24 April 2012 02:28 PM, Jean Delvare wrote:

On Tue, 24 Apr 2012 12:49:35 +0530, Laxman Dewangan wrote:

The slave address of device to be configured in packet
header as follows:
 7 bit address: PacketHeader3[7:1]
 10 bit address: PacketHeader3[9:0]

Fixing the code to make packet header3 properly.

Signed-off-by: Laxman Dewanganldewan...@nvidia.com
---


Looks good.

Acked-by: Jean Delvarekh...@linux-fr.org


Can it be apply? This is independent of other change in this series
which is under discussion/review.

Applied to next. Or do you need it in 3.4?


I dont need it on 3.4. It is fine to apply for next only.


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


Re: [PATCH 01/11] dma: imx-sdma: make channel0 operations atomic

2012-04-27 Thread Laxman Dewangan

On Friday 27 April 2012 05:03 PM, Russell King - ARM Linux wrote:

On Fri, Apr 27, 2012 at 07:26:56PM +0800, Richard Zhao wrote:

Sure, I mean, can you doc in include/linux/dmaengine.h that
dmaengine_prep_xxx may sleep?

Incorrect.  They may _not_ sleep.


But I have seen that we are using the kzalloc in the dmaengine_prep_xxx 
and kzalloc is sleeping call.

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


[PATCH V1 1/2] i2c: tegra: fix 10bit address configuration

2012-04-24 Thread Laxman Dewangan
The slave address of device to be configured in packet
header as follows:
7 bit address: PacketHeader3[7:1]
10 bit address: PacketHeader3[9:0]

Fixing the code to make packet header3 properly.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
 drivers/i2c/busses/i2c-tegra.c |   11 +++
 1 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 55e5ea6..18067b3 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -476,12 +476,15 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev 
*i2c_dev,
packet_header = msg-len - 1;
i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
 
-   packet_header = msg-addr  I2C_HEADER_SLAVE_ADDR_SHIFT;
-   packet_header |= I2C_HEADER_IE_ENABLE;
+   packet_header = I2C_HEADER_IE_ENABLE;
if (!stop)
packet_header |= I2C_HEADER_REPEAT_START;
-   if (msg-flags  I2C_M_TEN)
+   if (msg-flags  I2C_M_TEN) {
+   packet_header |= msg-addr;
packet_header |= I2C_HEADER_10BIT_ADDR;
+   } else {
+   packet_header |= msg-addr  I2C_HEADER_SLAVE_ADDR_SHIFT;
+   }
if (msg-flags  I2C_M_IGNORE_NAK)
packet_header |= I2C_HEADER_CONT_ON_NAK;
if (msg-flags  I2C_M_RD)
@@ -557,7 +560,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
 
 static u32 tegra_i2c_func(struct i2c_adapter *adap)
 {
-   return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+   return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR;
 }
 
 static const struct i2c_algorithm tegra_i2c_algo = {
-- 
1.7.1.1

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


[PATCH V1 2/2] i2c: tegra: support for I2C_M_NOSTART protocol mangling

2012-04-24 Thread Laxman Dewangan
Adding support for protocol mangling I2C_M_NOSTART.
When multiple message transfer request made through i2c
and if any message is flagged with I2C_M_NOSTART then
it will not send the start/repeat start/address of that
message i.e. send the data directly.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
 drivers/i2c/busses/i2c-tegra.c |   32 +++-
 1 files changed, 27 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 18067b3..a50e4c4 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -97,8 +97,21 @@
 #define I2C_HEADER_10BIT_ADDR  (118)
 #define I2C_HEADER_IE_ENABLE   (117)
 #define I2C_HEADER_REPEAT_START(116)
+#define I2C_HEADER_CONTINUE_XFER   (115)
 #define I2C_HEADER_MASTER_ADDR_SHIFT   12
 #define I2C_HEADER_SLAVE_ADDR_SHIFT1
+/*
+ * msg_end_type: The bus control which need to be send at end of transfer.
+ * @MSG_END_STOP: Send stop pulse at end of transfer.
+ * @MSG_END_REPEAT_START: Send repeat start at end of transfer.
+ * @MSG_END_CONTINUE: The following on message is coming and so do not send
+ * stop or repeat start.
+ */
+enum msg_end_type {
+   MSG_END_STOP,
+   MSG_END_REPEAT_START,
+   MSG_END_CONTINUE,
+};
 
 /**
  * struct tegra_i2c_dev- per device i2c context
@@ -450,7 +463,7 @@ err:
 }
 
 static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
-   struct i2c_msg *msg, int stop)
+   struct i2c_msg *msg, enum msg_end_type end_state)
 {
u32 packet_header;
u32 int_mask;
@@ -477,7 +490,9 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
 
packet_header = I2C_HEADER_IE_ENABLE;
-   if (!stop)
+   if (end_state == MSG_END_CONTINUE)
+   packet_header |= I2C_HEADER_CONTINUE_XFER;
+   else if (end_state == MSG_END_REPEAT_START)
packet_header |= I2C_HEADER_REPEAT_START;
if (msg-flags  I2C_M_TEN) {
packet_header |= msg-addr;
@@ -549,8 +564,14 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
 
clk_enable(i2c_dev-clk);
for (i = 0; i  num; i++) {
-   int stop = (i == (num - 1)) ? 1  : 0;
-   ret = tegra_i2c_xfer_msg(i2c_dev, msgs[i], stop);
+   enum msg_end_type end_type = MSG_END_STOP;
+   if (i  (num - 1)) {
+   if (msgs[i + 1].flags  I2C_M_NOSTART)
+   end_type = MSG_END_CONTINUE;
+   else
+   end_type = MSG_END_REPEAT_START;
+   }
+   ret = tegra_i2c_xfer_msg(i2c_dev, msgs[i], end_type);
if (ret)
break;
}
@@ -560,7 +581,8 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct 
i2c_msg msgs[],
 
 static u32 tegra_i2c_func(struct i2c_adapter *adap)
 {
-   return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR;
+   return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
+   I2C_FUNC_PROTOCOL_MANGLING;
 }
 
 static const struct i2c_algorithm tegra_i2c_algo = {
-- 
1.7.1.1

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


[PATCH V1] i2c: gpio: Use open drain support from gpio driver

2012-03-07 Thread Laxman Dewangan
The gpio core driver (gpio library) supports the open
drain pin handling. Therefore, it is not require it
to handle in the i2c-gpio driver, just require
to pass the OPEN_DRAIN type flag when requesting the gpio.

Remove the handling of open drain pin in the i2c-gpio driver.

Signed-off-by: Laxman Dewangan ldewan...@nvidia.com
---
 drivers/i2c/busses/i2c-gpio.c |   78 ++--
 1 files changed, 27 insertions(+), 51 deletions(-)

diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index 69fbfae..662a747 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -16,22 +16,7 @@
 #include linux/platform_device.h
 #include linux/gpio.h
 
-/* Toggle SDA by changing the direction of the pin */
-static void i2c_gpio_setsda_dir(void *data, int state)
-{
-   struct i2c_gpio_platform_data *pdata = data;
-
-   if (state)
-   gpio_direction_input(pdata-sda_pin);
-   else
-   gpio_direction_output(pdata-sda_pin, 0);
-}
-
-/*
- * Toggle SDA by changing the output value of the pin. This is only
- * valid for pins configured as open drain (i.e. setting the value
- * high effectively turns off the output driver.)
- */
+/* Toggle SDA by setting value, gpio library take care of open drain pins.*/
 static void i2c_gpio_setsda_val(void *data, int state)
 {
struct i2c_gpio_platform_data *pdata = data;
@@ -39,23 +24,7 @@ static void i2c_gpio_setsda_val(void *data, int state)
gpio_set_value(pdata-sda_pin, state);
 }
 
-/* Toggle SCL by changing the direction of the pin. */
-static void i2c_gpio_setscl_dir(void *data, int state)
-{
-   struct i2c_gpio_platform_data *pdata = data;
-
-   if (state)
-   gpio_direction_input(pdata-scl_pin);
-   else
-   gpio_direction_output(pdata-scl_pin, 0);
-}
-
-/*
- * Toggle SCL by changing the output value of the pin. This is used
- * for pins that are configured as open drain and for output-only
- * pins. The latter case will break the i2c protocol, but it will
- * often work in practice.
- */
+ /* Toggle SCL by setting value, gpio library take care of open drain pins.*/
 static void i2c_gpio_setscl_val(void *data, int state)
 {
struct i2c_gpio_platform_data *pdata = data;
@@ -83,6 +52,8 @@ static int __devinit i2c_gpio_probe(struct platform_device 
*pdev)
struct i2c_algo_bit_data *bit_data;
struct i2c_adapter *adap;
int ret;
+   unsigned long sda_gpio_flags;
+   unsigned long scl_gpio_flags;
 
pdata = pdev-dev.platform_data;
if (!pdata)
@@ -96,28 +67,33 @@ static int __devinit i2c_gpio_probe(struct platform_device 
*pdev)
if (!bit_data)
goto err_alloc_bit_data;
 
-   ret = gpio_request(pdata-sda_pin, sda);
-   if (ret)
+   /* Initially, SCL and SDA pin should be HIGH */
+   sda_gpio_flags = GPIOF_OUT_INIT_HIGH;
+   scl_gpio_flags = GPIOF_OUT_INIT_HIGH;
+
+   if (pdata-sda_is_open_drain)
+   sda_gpio_flags |= GPIOF_OPEN_DRAIN;
+
+   if (pdata-scl_is_open_drain  !pdata-scl_is_output_only)
+   scl_gpio_flags |= GPIOF_OPEN_DRAIN;
+
+
+
+   ret = gpio_request_one(pdata-sda_pin, sda_gpio_flags, sda);
+   if (ret) {
+   pr_err(%s(): Error in requesting sda gpio%d, ret %d\n,
+   __func__, pdata-sda_pin, ret);
goto err_request_sda;
-   ret = gpio_request(pdata-scl_pin, scl);
-   if (ret)
+   }
+   ret = gpio_request_one(pdata-scl_pin, scl_gpio_flags, scl);
+   if (ret) {
+   pr_err(%s(): Error in requesting scl gpio%d, ret %d\n,
+   __func__, pdata-scl_pin, ret);
goto err_request_scl;
-
-   if (pdata-sda_is_open_drain) {
-   gpio_direction_output(pdata-sda_pin, 1);
-   bit_data-setsda = i2c_gpio_setsda_val;
-   } else {
-   gpio_direction_input(pdata-sda_pin);
-   bit_data-setsda = i2c_gpio_setsda_dir;
}
 
-   if (pdata-scl_is_open_drain || pdata-scl_is_output_only) {
-   gpio_direction_output(pdata-scl_pin, 1);
-   bit_data-setscl = i2c_gpio_setscl_val;
-   } else {
-   gpio_direction_input(pdata-scl_pin);
-   bit_data-setscl = i2c_gpio_setscl_dir;
-   }
+   bit_data-setsda = i2c_gpio_setsda_val;
+   bit_data-setscl = i2c_gpio_setscl_val;
 
if (!pdata-scl_is_output_only)
bit_data-getscl = i2c_gpio_getscl;
-- 
1.7.1.1

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


Re: [PATCH V1] i2c: gpio: Use open drain support from gpio driver

2012-03-07 Thread Laxman Dewangan

The open drain support is already available from next-20120306.
I was waiting for the change to be in tree before sending this patch.
Hope I am not missing anything here.


On Wednesday 07 March 2012 11:14 PM, Mark Brown wrote:

* PGP Signed by an unknown key

On Wed, Mar 07, 2012 at 06:39:22PM +0100, Wolfram Sang wrote:

On Wed, Mar 07, 2012 at 05:31:57PM +, Mark Brown wrote:

Reviwed-by: Mark Brownbroo...@opensource.wolfsonmicro.com

Typo ;)

Not at all, it's a direct demonstration of the quick review I did!  :P

* Unknown Key
* 0x6E30FDDD


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


Re: [PATCH 2/2] i2c/designware: Provide optional i2c bus recovery function

2012-02-29 Thread Laxman Dewangan

On Tuesday 28 February 2012 06:53 PM, viresh kumar wrote:


This patch also adds in generic bus recovery routines gpio or scl line based
which can be used by bus controller. In addition controller driver may provide
its own version of the bus recovery routine.

Signed-off-by: Viresh Kumarviresh.ku...@st.com
---
  drivers/i2c/i2c-core.c |   56 
  include/linux/i2c.h|   22 ++
  2 files changed, 78 insertions(+), 0 deletions(-)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index e9c1893..c9f0daf 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -26,7 +26,9 @@

  #includelinux/module.h
  #includelinux/kernel.h
+#includelinux/delay.h
  #includelinux/errno.h
+#includelinux/gpio.h
  #includelinux/slab.h
  #includelinux/i2c.h
  #includelinux/init.h
@@ -103,6 +105,47 @@ static int i2c_device_uevent(struct device *dev,
struct kobj_uevent_env *env)
  #define i2c_device_uevent NULL
  #endif/* CONFIG_HOTPLUG */

+/* i2c bus recovery routines */
+static int i2c_gpio_recover_bus(struct i2c_adapter *adap)
+{
+   int tmp, val = 1;
+   unsigned long delay = 100;
+
+   tmp = gpio_request_one(adap-scl_gpio, GPIOF_DIR_OUT |
+   GPIOF_INIT_LOW, i2c-bus-recover);


Should rename tmp to ret or status. tmp does not looks appropriate.


+   if (tmp  0) {
+   dev_warn(adap-dev, gpio request one fail: %d\n,
+   adap-scl_gpio);
+   return tmp;
+   }
+
+   delay /= adap-clock_rate * 2;

Here delay is turning as micor sec and function used as the nano sec.

+
+   for (tmp = 0; tmp  adap-clock_cnt * 2; tmp++, val = !val) {
+   ndelay(delay);

should be udelay()?

+   gpio_set_value(adap-scl_gpio, val);


I think it should check for the sda line for coming out of the loop. 
There may be possibility that we may not need 9 clock pulses.



+   }
+
+   gpio_free(adap-clock_cnt);
+
+   return 0;
+}
+
+static int i2c_scl_recover_bus(struct i2c_adapter *adap)
+{
+   int i, val = 0;
+   unsigned long delay = 100;
+
+   delay /= adap-clock_rate * 2;
+
+   for (i = 0; i  adap-clock_cnt * 2; i++, val = !val) {
+   adap-set_scl(adap, val);
+   ndelay(delay);

udelay()??

+   }
+
+   return 0;
+}
+
  static int i2c_device_probe(struct device *dev)
  {
struct i2c_client   *client = i2c_verify_client(dev);
@@ -861,6 +904,19 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
 Failed to create compatibility class link\n);
  #endif

+   /* bus recovery specific initialization */
+   if (!adap-recover_bus) {
+   if (!adap-clock_cnt || !adap-clock_rate)
+   goto warn_no_recovery;
+   else if (adap-is_gpio_recovery)
+   adap-recover_bus = i2c_gpio_recover_bus;
+   else if (adap-set_scl)
+   adap-recover_bus = i2c_scl_recover_bus;
+
+warn_no_recovery:

Always generated warning..

+   dev_warn(adap-dev, doesn't have recovery method\n);
+   }
+
/* create pre-declared device nodes */
if (adap-nr  __i2c_first_dynamic_bus_num)
i2c_scan_static_board_info(adap);
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 8e25a91..b2a6d97 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -388,6 +388,28 @@ struct i2c_adapter {

struct mutex userspace_clients_lock;
struct list_head userspace_clients;
+
+   /*
+* bus recovery specific fields: Either pass driver's recover_bus()
+* routine, or pass it NULL to use generic ones. There are two type of
+* generic one's available:
+*  - controlling scl line as gpio, pass is_gpio_recovery as true
+*  and valid scl_gpio number
+*  - controlling scl line directly via controller, pass
+*  is_gpio_recovery as false and valid set_scl routine's pointer
+*
+* Both schemes require valid values of
+*  - clock_cnt: total number of dummy clocks to be generated
+*  - clock_rate: rate of dummy clock
+*
+* scl_gpio.
+*/
+   int (*recover_bus)(struct i2c_adapter *);
+   void (*set_scl)(struct i2c_adapter *, int val);
+   bool is_gpio_recovery;
+   u8 scl_gpio;

gpio can be more than 256. better to use int.
Take scl_gpio_flag and use in the gpio_request_one.

+   u8 clock_cnt;
+   u32 clock_rate; /* In KHz */
  };
  #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev)


--
viresh



---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is 

Re: [PATCH 2/2] i2c/designware: Provide optional i2c bus recovery function

2012-02-29 Thread Laxman Dewangan

On Wednesday 29 February 2012 05:28 PM, Viresh Kumar wrote:



+   if (tmp   0) {
+   dev_warn(adap-dev, gpio request one fail: %d\n,
+   adap-scl_gpio);
+   return tmp;
+   }
+
+   delay /= adap-clock_rate * 2;

Here delay is turning as micor sec and function used as the nano sec.

clock_rate is in KHz, mentioned in comment of clock_rate.
Makes sense now or am i missing something?



Oops, my bad.. better to name the variable as clock_rate_khz kind of to 
avoid the error when we use in our driver.






I think it should check for the sda line for coming out of the loop.
There may be possibility that we may not need 9 clock pulses.


I asked this in another mail, how to be sure that it will work.



We observed that sometimes it does not require 9 clocks. So you can poll 
for given amount of clock time. Once the device who was holding the SDA 
line to low, release the bus, it can comeout from the loop. Not sure 
this is as per specs or not but this was our observations.





---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
--
To unsubscribe from this list: send the line unsubscribe linux-i2c in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] i2c/designware: Provide optional i2c bus recovery function

2012-02-26 Thread Laxman Dewangan

On Monday 27 February 2012 12:51 PM, Shubhrajyoti Datta wrote:

On Fri, Feb 24, 2012 at 5:01 PM, Viresh Kumarviresh.ku...@st.com  wrote:

From: Vincenzo Frascinovincenzo.frasc...@st.com

Add optional i2c_recover_bus() function to the Synopsys DesignWare I2C adapter
driver that performs i2c bus recovery after timeout. The scope of this routine
is to define i2c bus recovery procedure as specified in the i2c protocol Rev. 03
section 3.16 titled Bus clear.

What do you do in the function ?

Could we have it in the driver file itself?

I think bus recovery mechanism is to send  extra clock on SCL line by 
toggling the pin (using gpio apis) and keep watching of sda line whether 
it becomes high or not.
We can put this algorithms in the some common file (i2c/algos/) and so 
if any i2c bus driver want to use, they can use it.
Little background: I am working on tegra i2c controller and we have 
similar logic in tegra-i2c driver which we want to upstream.
If similar function is in common place, we can use this and need not to 
duplicating it on every bus driver.



---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
--
To unsubscribe from this list: send the line unsubscribe linux-i2c in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] i2c: tegra: Remove unnecessary clk_get

2012-02-15 Thread Laxman Dewangan

On Thursday 16 February 2012 12:13 AM, Stephen Warren wrote:


This appears to apply to modules lfsr, dsi, csi, i2c1/2/3, uart1/2/3/4/5,
but apparently not the DVC I2C controller according to the TRM. Laxman,
can you confirm that the DVC I2C controller doesn't take a clock from
pll_p_out3?



DVC i2C is also require this 2nd clock.


P.S. this patch I posted is in our downstream 2.6.39 and 3.1 kernels.
Given this thread, I assume it should be reverted there...



Yes, I have pushed the change in our downstream tree K3.1 and it is 
under testing/promotion..



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


RE: [PATCH] i2c: tegra: Add delay before reset the controller

2011-12-23 Thread Laxman Dewangan
 -Original Message-
 From: Alok Chauhan
 
 Hi,
 
 (Adding Laxman Dewangan)
 
 This change causes problems systems with some models of i2c TPMs, since the
 first transaction to them will always time out (TPM quirk), and the delay
 means that the tpm will have time to go back to sleep and thus timeout even
 on the retry. So you'll never make progress.
 Working on this.
 
 -Alok
 
 
 -Original Message-
 From: Olof Johansson [mailto:o...@lixom.net]
 Sent: Friday, December 23, 2011 2:48 AM
 To: Alok Chauhan
 Cc: kh...@linux-fr.org; ben-li...@fluff.org; Stephen Warren;
 bo...@secretlab.ca; paul.gortma...@windriver.com; linux-i2c@vger.kernel.org;
 linux-ker...@vger.kernel.org; linux-te...@vger.kernel.org; dgr...@google.com
 Subject: Re: [PATCH] i2c: tegra: Add delay before reset the controller
 
 Hi,
 
 (Adding linux-tegra and Dylan Reid who was debugging this before)
 
 On Thu, Dec 22, 2011 at 2:41 AM, Alok Chauhan al...@nvidia.com wrote:
  From: Alok Chauhan al...@nvidia.com
 
  In NACK error condition, I2C controller violates clock-to-data setup
  time before stop. In Software, because of this reset of controller is
  happening before I2C controller could complete STOP condition.
 
  Added worst case delay of 1 ms (assuming lowest clock frequency will
  be 1 KHZ) before reset the controller in case of NACK error.
 
 This change causes problems systems with some models of i2c TPMs, since the
 first transaction to them will always time out (TPM quirk), and the delay
 means that the tpm will have time to go back to sleep and thus timeout even on
 the retry. So you'll never make progress.
 
 In other words: this patch will break some systems and thus shouldn't be
 applied.
 
I think the  delay should be calculated based on speed. So if it is 100KHz, then
delay is 10mcro second for 1 bit. We should wait for 2 bit (ack clock to be 
complete and
stop pulse to be transmitted).
This patch will make sure that i2c driver will not break the specs i.e. in case 
of NACK error, the stop
signal should be completed by i2c controller before resetting controller.
I will prefer of having the udelay(2*100/speed).

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