linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v7 00/34] Improvements for Tegra I2C driver
@ 2020-09-08 22:39 Dmitry Osipenko
  2020-09-08 22:39 ` [PATCH v7 01/34] i2c: tegra: Make tegra_i2c_flush_fifos() usable in atomic transfer Dmitry Osipenko
                   ` (35 more replies)
  0 siblings, 36 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

Hello!

This series performs refactoring of the Tegra I2C driver code and hardens
the atomic-transfer mode.

Changelog:

v7: - Reworked the "Clean up probe function" patch by moving out all
      variable renamings into the "Clean up variable names" patch.
      This results in a nicer diff, which was asked by Andy Shevchenko.

    - Squashed "Improve coding style of tegra_i2c_wait_for_config_load()"
      patch into "Factor out register polling into separate function" in
      order avoid unnecessary ping-pong changes, which was asked by
      Andy Shevchenko.

    - Added more indentation improvements, it should be ideal now.

    - I haven't changed order of the "Clean up variable types" patch,
      which was suggested by Andy Shevchenko, because I already moved
      that patch multiple times and we decided to sort patches starting
      with more important cleanups and down to less important. The type
      changes are more important than shuffling code around, IMO.

v6: - Added new patch that adds missing RPM puts, thanks to Andy Shevchenko
      for the suggestion.

    - Improved commit messages by extending them with more a more detailed
      explanation of the changes.

    - Added clarifying comment to the "Use reset_control_reset()" change,
      which was asked by Andy Shevchenko.

    - Refactored the "Clean up probe function" patch by moving the
      dev_err_probe() change into the "Use clk-bulk helpers" patch,
      which was suggested by Andy Shevchenko.

    - Improved ordering of the patches like it was suggested by
      Andy Shevchenko.

    - Added Andy Shevchenko to suggested-by of the "Use clk-bulk helpers"
      patch.

    - Improved "Remove i2c_dev.clk_divisor_non_hs_mode member" patch by
      making the case-switch to use "fast plus mode" timing if clock rate
      is out-of-range. Just to make it more consistent.

    - The "Improve tegra_i2c_dev structure" patch is squashed into
     "Improve formatting of variables" and "Clean up types/names" patches.

    - All variable-renaming changes are squashed into a single "Clean up
      variable names" patch.

    - Made extra minor improvement to various patches, like more comments
      and indentations improved.

v5: - Dropped the "Factor out runtime PM and hardware initialization"
      patch, like it was suggested by Michał Mirosław. Instead a less
      invasive "Factor out hardware initialization into separate function"
      patch added, it doesn't touch the RPM initialization.

    - The "Remove outdated barrier()" patch now removes outdated comments.

    - Updated commit description of the "Remove "dma" variable" patch,
      saying that the transfer mode may be changed by a callee. This was
      suggested by Michał Mirosław.

    - Reworked the "Clean up and improve comments" patch. Couple more
      comments are corrected and reworded now.

    - Added r-b's from Michał Mirosław.

    - New patches:

        i2c: tegra: Mask interrupt in tegra_i2c_issue_bus_clear()
        i2c: tegra: Remove redundant check in tegra_i2c_issue_bus_clear()
        i2c: tegra: Don't fall back to PIO mode if DMA configuration fails
        i2c: tegra: Clean up variable types
        i2c: tegra: Improve tegra_i2c_dev structure

v4: - Reordered patches in the fixes/features/cleanups order like it was
      suggested by Andy Shevchenko.

    - Now using clk-bulk API, which was suggested by Andy Shevchenko.

    - Reworked "Make tegra_i2c_flush_fifos() usable in atomic transfer"
      patch to use iopoll API, which was suggested by Andy Shevchenko.

    - Separated "Clean up probe function" into several smaller patches.

    - Squashed "Add missing newline before returns" patch into
      "Clean up whitespaces, newlines and indentation".

    - The "Drop '_timeout' from wait/poll function names" is renamed to
      "Rename wait/poll functions".

    - The "Use reset_control_reset()" is changed to not fail tegra_i2c_init(),
      but only emit warning. This should be more friendly behaviour in oppose
      to having a non-bootable machine if reset-control fails.

    - New patches:

        i2c: tegra: Remove error message used for devm_request_irq() failure
        i2c: tegra: Use devm_platform_get_and_ioremap_resource()
        i2c: tegra: Use platform_get_irq()
        i2c: tegra: Use clk-bulk helpers
        i2c: tegra: Remove bogus barrier()
        i2c: tegra: Factor out register polling into separate function
        i2c: tegra: Consolidate error handling in tegra_i2c_xfer_msg()
        i2c: tegra: Clean up and improve comments
        i2c: tegra: Rename couple "ret" variables to "err"

v3: - Optimized "Make tegra_i2c_flush_fifos() usable in atomic transfer"
      patch by pre-checking FIFO state before starting to poll using
      ktime API, which may be expensive under some circumstances.

    - The "Clean up messages in the code" patch now makes all messages
      to use proper capitalization of abbreviations. Thanks to Andy Shevchenko
      and Michał Mirosław for the suggestion.

    - The "Remove unnecessary whitespaces and newlines" patch is transformed
      into "Clean up whitespaces and newlines", it now also adds missing
      newlines and spaces.

    - Reworked the "Clean up probe function" patch in accordance to
      suggestion from Michał Mirosław by factoring out only parts of
      the code that make error unwinding cleaner.

    - Added r-b from Michał Mirosław.

    - Added more patches:

        i2c: tegra: Reorder location of functions in the code
        i2c: tegra: Factor out packet header setup from tegra_i2c_xfer_msg()
        i2c: tegra: Remove "dma" variable
        i2c: tegra: Initialization div-clk rate unconditionally
        i2c: tegra: Remove i2c_dev.clk_divisor_non_hs_mode member

v2: - Cleaned more messages in the "Clean up messages in the code" patch.

    - The error code of reset_control_reset() is checked now.

    - Added these new patches to clean up couple more things:

        i2c: tegra: Check errors for both positive and negative values
        i2c: tegra: Improve coding style of tegra_i2c_wait_for_config_load()
        i2c: tegra: Remove unnecessary whitespaces and newlines
        i2c: tegra: Rename variable in tegra_i2c_issue_bus_clear()
        i2c: tegra: Improve driver module description

Dmitry Osipenko (34):
  i2c: tegra: Make tegra_i2c_flush_fifos() usable in atomic transfer
  i2c: tegra: Add missing pm_runtime_put()
  i2c: tegra: Handle potential error of tegra_i2c_flush_fifos()
  i2c: tegra: Mask interrupt in tegra_i2c_issue_bus_clear()
  i2c: tegra: Initialize div-clk rate unconditionally
  i2c: tegra: Remove i2c_dev.clk_divisor_non_hs_mode member
  i2c: tegra: Runtime PM always available on Tegra
  i2c: tegra: Remove error message used for devm_request_irq() failure
  i2c: tegra: Use reset_control_reset()
  i2c: tegra: Use devm_platform_get_and_ioremap_resource()
  i2c: tegra: Use platform_get_irq()
  i2c: tegra: Use clk-bulk helpers
  i2c: tegra: Move out all device-tree parsing into tegra_i2c_parse_dt()
  i2c: tegra: Clean up probe function
  i2c: tegra: Reorder location of functions in the code
  i2c: tegra: Clean up variable types
  i2c: tegra: Remove outdated barrier()
  i2c: tegra: Remove likely/unlikely from the code
  i2c: tegra: Remove redundant check in tegra_i2c_issue_bus_clear()
  i2c: tegra: Remove "dma" variable from tegra_i2c_xfer_msg()
  i2c: tegra: Don't fall back to PIO mode if DMA configuration fails
  i2c: tegra: Rename wait/poll functions
  i2c: tegra: Factor out error recovery from tegra_i2c_xfer_msg()
  i2c: tegra: Factor out packet header setup from tegra_i2c_xfer_msg()
  i2c: tegra: Factor out register polling into separate function
  i2c: tegra: Factor out hardware initialization into separate function
  i2c: tegra: Check errors for both positive and negative values
  i2c: tegra: Consolidate error handling in tegra_i2c_xfer_msg()
  i2c: tegra: Improve formatting of variables
  i2c: tegra: Clean up variable names
  i2c: tegra: Clean up printk messages
  i2c: tegra: Clean up and improve comments
  i2c: tegra: Clean up whitespaces, newlines and indentation
  i2c: tegra: Improve driver module description

 drivers/i2c/busses/i2c-tegra.c | 1435 ++++++++++++++++----------------
 1 file changed, 701 insertions(+), 734 deletions(-)

-- 
2.27.0


^ permalink raw reply	[flat|nested] 146+ messages in thread

* [PATCH v7 01/34] i2c: tegra: Make tegra_i2c_flush_fifos() usable in atomic transfer
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 11:10   ` Thierry Reding
  2020-09-21 10:18   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 02/34] i2c: tegra: Add missing pm_runtime_put() Dmitry Osipenko
                   ` (34 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

The tegra_i2c_flush_fifos() shouldn't sleep in atomic transfer and jiffies
are not updating if interrupts are disabled. Let's switch to use iopoll
API helpers for register-polling. The iopoll API provides helpers for both
atomic and non-atomic cases.

Note that this patch doesn't fix any known problem because normally FIFO
is flushed at the time of starting a new transfer.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 00d3e4d7a01e..ab88cdd70376 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -470,9 +470,9 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev)
 
 static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
 {
-	unsigned long timeout = jiffies + HZ;
-	unsigned int offset;
-	u32 mask, val;
+	u32 mask, val, offset, reg_offset;
+	void __iomem *addr;
+	int err;
 
 	if (i2c_dev->hw->has_mst_fifo) {
 		mask = I2C_MST_FIFO_CONTROL_TX_FLUSH |
@@ -488,12 +488,19 @@ static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
 	val |= mask;
 	i2c_writel(i2c_dev, val, offset);
 
-	while (i2c_readl(i2c_dev, offset) & mask) {
-		if (time_after(jiffies, timeout)) {
-			dev_warn(i2c_dev->dev, "timeout waiting for fifo flush\n");
-			return -ETIMEDOUT;
-		}
-		usleep_range(1000, 2000);
+	reg_offset = tegra_i2c_reg_addr(i2c_dev, offset);
+	addr = i2c_dev->base + reg_offset;
+
+	if (i2c_dev->is_curr_atomic_xfer)
+		err = readl_relaxed_poll_timeout_atomic(addr, val, !(val & mask),
+							1000, 1000000);
+	else
+		err = readl_relaxed_poll_timeout(addr, val, !(val & mask),
+						 1000, 1000000);
+
+	if (err) {
+		dev_err(i2c_dev->dev, "failed to flush FIFO\n");
+		return err;
 	}
 	return 0;
 }
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 02/34] i2c: tegra: Add missing pm_runtime_put()
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
  2020-09-08 22:39 ` [PATCH v7 01/34] i2c: tegra: Make tegra_i2c_flush_fifos() usable in atomic transfer Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 11:12   ` Thierry Reding
  2020-09-21 10:18   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 03/34] i2c: tegra: Handle potential error of tegra_i2c_flush_fifos() Dmitry Osipenko
                   ` (33 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

The pm_runtime_get_sync() always bumps refcount regardless of whether it
succeeds or fails. Hence driver is responsible for restoring of the RPM
refcounting. This patch adds missing RPM puts which restore refcounting
in a case of pm_runtime_get_sync() error.

Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index ab88cdd70376..4e7d0eec0dd3 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -1375,6 +1375,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
 	ret = pm_runtime_get_sync(i2c_dev->dev);
 	if (ret < 0) {
 		dev_err(i2c_dev->dev, "runtime resume failed %d\n", ret);
+		pm_runtime_put_noidle(i2c_dev->dev);
 		return ret;
 	}
 
@@ -1786,7 +1787,7 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 		ret = pm_runtime_get_sync(i2c_dev->dev);
 		if (ret < 0) {
 			dev_err(&pdev->dev, "runtime resume failed\n");
-			goto disable_rpm;
+			goto put_rpm;
 		}
 	}
 
@@ -1851,7 +1852,6 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 	else
 		tegra_i2c_runtime_suspend(&pdev->dev);
 
-disable_rpm:
 	if (pm_runtime_enabled(&pdev->dev))
 		pm_runtime_disable(&pdev->dev);
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 03/34] i2c: tegra: Handle potential error of tegra_i2c_flush_fifos()
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
  2020-09-08 22:39 ` [PATCH v7 01/34] i2c: tegra: Make tegra_i2c_flush_fifos() usable in atomic transfer Dmitry Osipenko
  2020-09-08 22:39 ` [PATCH v7 02/34] i2c: tegra: Add missing pm_runtime_put() Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 11:13   ` Thierry Reding
  2020-09-21 10:18   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 04/34] i2c: tegra: Mask interrupt in tegra_i2c_issue_bus_clear() Dmitry Osipenko
                   ` (32 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

Technically the tegra_i2c_flush_fifos() may fail and transfer should be
aborted in this case, but this shouldn't ever happen in practice unless
there is a bug somewhere in the driver. Let's add the error check just
for completeness.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 4e7d0eec0dd3..88d6e7bb14a2 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -1177,7 +1177,9 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 	bool dma;
 	u16 xfer_time = 100;
 
-	tegra_i2c_flush_fifos(i2c_dev);
+	err = tegra_i2c_flush_fifos(i2c_dev);
+	if (err)
+		return err;
 
 	i2c_dev->msg_buf = msg->buf;
 	i2c_dev->msg_buf_remaining = msg->len;
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 04/34] i2c: tegra: Mask interrupt in tegra_i2c_issue_bus_clear()
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (2 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 03/34] i2c: tegra: Handle potential error of tegra_i2c_flush_fifos() Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 11:18   ` Thierry Reding
  2020-09-21 10:18   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 05/34] i2c: tegra: Initialize div-clk rate unconditionally Dmitry Osipenko
                   ` (31 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

The tegra_i2c_issue_bus_clear() may fail and in this case BUS_CLR_DONE
stays unmasked. Hence let's mask it for consistency. This patch doesn't
fix any known problems.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 88d6e7bb14a2..1d1ce266255a 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -1149,6 +1149,8 @@ static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap)
 
 	time_left = tegra_i2c_wait_completion_timeout(
 			i2c_dev, &i2c_dev->msg_complete, 50);
+	tegra_i2c_mask_irq(i2c_dev, I2C_INT_BUS_CLR_DONE);
+
 	if (time_left == 0) {
 		dev_err(i2c_dev->dev, "timed out for bus clear\n");
 		return -ETIMEDOUT;
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 05/34] i2c: tegra: Initialize div-clk rate unconditionally
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (3 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 04/34] i2c: tegra: Mask interrupt in tegra_i2c_issue_bus_clear() Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 11:20   ` Thierry Reding
  2020-09-21 10:18   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 06/34] i2c: tegra: Remove i2c_dev.clk_divisor_non_hs_mode member Dmitry Osipenko
                   ` (30 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

It doesn't make sense to conditionalize the div-clk rate changes because
rate is fixed and it won't ever change once it's set at the driver's probe
time. All further changes are NO-OPs because CCF caches rate and skips
rate-change if rate is unchanged.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 34 ++++++++++++++++------------------
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 1d1ce266255a..720a75439e91 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -293,7 +293,7 @@ struct tegra_i2c_dev {
 	bool is_curr_atomic_xfer;
 };
 
-static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit);
+static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev);
 
 static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val,
 		       unsigned long reg)
@@ -691,7 +691,7 @@ static int __maybe_unused tegra_i2c_runtime_resume(struct device *dev)
 	 * domain ON.
 	 */
 	if (i2c_dev->is_vi) {
-		ret = tegra_i2c_init(i2c_dev, true);
+		ret = tegra_i2c_init(i2c_dev);
 		if (ret)
 			goto disable_div_clk;
 	}
@@ -778,7 +778,7 @@ static void tegra_i2c_vi_init(struct tegra_i2c_dev *i2c_dev)
 	i2c_writel(i2c_dev, 0x0, I2C_TLOW_SEXT);
 }
 
-static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit)
+static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 {
 	u32 val;
 	int err;
@@ -836,16 +836,14 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit)
 	if (i2c_dev->hw->has_interface_timing_reg && tsu_thd)
 		i2c_writel(i2c_dev, tsu_thd, I2C_INTERFACE_TIMING_1);
 
-	if (!clk_reinit) {
-		clk_multiplier = (tlow + thigh + 2);
-		clk_multiplier *= (i2c_dev->clk_divisor_non_hs_mode + 1);
-		err = clk_set_rate(i2c_dev->div_clk,
-				   i2c_dev->bus_clk_rate * clk_multiplier);
-		if (err) {
-			dev_err(i2c_dev->dev,
-				"failed changing clock rate: %d\n", err);
-			return err;
-		}
+	clk_multiplier  = tlow + thigh + 2;
+	clk_multiplier *= i2c_dev->clk_divisor_non_hs_mode + 1;
+
+	err = clk_set_rate(i2c_dev->div_clk,
+			   i2c_dev->bus_clk_rate * clk_multiplier);
+	if (err) {
+		dev_err(i2c_dev->dev, "failed to set div-clk rate: %d\n", err);
+		return err;
 	}
 
 	if (!i2c_dev->is_dvc && !i2c_dev->is_vi) {
@@ -1319,7 +1317,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 
 		if (!time_left && !completion_done(&i2c_dev->dma_complete)) {
 			dev_err(i2c_dev->dev, "DMA transfer timeout\n");
-			tegra_i2c_init(i2c_dev, true);
+			tegra_i2c_init(i2c_dev);
 			return -ETIMEDOUT;
 		}
 
@@ -1340,7 +1338,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 
 	if (time_left == 0) {
 		dev_err(i2c_dev->dev, "i2c transfer timed out\n");
-		tegra_i2c_init(i2c_dev, true);
+		tegra_i2c_init(i2c_dev);
 		return -ETIMEDOUT;
 	}
 
@@ -1352,7 +1350,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 	if (likely(i2c_dev->msg_err == I2C_ERR_NONE))
 		return 0;
 
-	tegra_i2c_init(i2c_dev, true);
+	tegra_i2c_init(i2c_dev);
 	/* start recovery upon arbitration loss in single master mode */
 	if (i2c_dev->msg_err == I2C_ERR_ARBITRATION_LOST) {
 		if (!i2c_dev->is_multimaster_mode)
@@ -1811,7 +1809,7 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 	if (ret < 0)
 		goto disable_div_clk;
 
-	ret = tegra_i2c_init(i2c_dev, false);
+	ret = tegra_i2c_init(i2c_dev);
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to initialize i2c controller\n");
 		goto release_dma;
@@ -1918,7 +1916,7 @@ static int __maybe_unused tegra_i2c_resume(struct device *dev)
 	if (err)
 		return err;
 
-	err = tegra_i2c_init(i2c_dev, false);
+	err = tegra_i2c_init(i2c_dev);
 	if (err)
 		return err;
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 06/34] i2c: tegra: Remove i2c_dev.clk_divisor_non_hs_mode member
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (4 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 05/34] i2c: tegra: Initialize div-clk rate unconditionally Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 11:25   ` Thierry Reding
  2020-09-21 10:18   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 07/34] i2c: tegra: Runtime PM always available on Tegra Dmitry Osipenko
                   ` (29 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

The "non_hs_mode" divisor value is fixed, thus there is no need to have
the variable i2c_dev.clk_divisor_non_hs_mode struct member. Let's remove
it and move the mode selection into tegra_i2c_init() where it can be
united with the timing selection.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 46 ++++++++++++++++------------------
 1 file changed, 21 insertions(+), 25 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 720a75439e91..85ed0e02d48c 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -250,7 +250,6 @@ struct tegra_i2c_hw_feature {
  * @msg_buf_remaining: size of unsent data in the message buffer
  * @msg_read: identifies read transfers
  * @bus_clk_rate: current I2C bus clock rate
- * @clk_divisor_non_hs_mode: clock divider for non-high-speed modes
  * @is_multimaster_mode: track if I2C controller is in multi-master mode
  * @tx_dma_chan: DMA transmit channel
  * @rx_dma_chan: DMA receive channel
@@ -281,7 +280,6 @@ struct tegra_i2c_dev {
 	size_t msg_buf_remaining;
 	int msg_read;
 	u32 bus_clk_rate;
-	u16 clk_divisor_non_hs_mode;
 	bool is_multimaster_mode;
 	struct dma_chan *tx_dma_chan;
 	struct dma_chan *rx_dma_chan;
@@ -783,6 +781,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 	u32 val;
 	int err;
 	u32 clk_divisor, clk_multiplier;
+	u32 non_hs_mode;
 	u32 tsu_thd;
 	u8 tlow, thigh;
 
@@ -805,24 +804,33 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 	if (i2c_dev->is_vi)
 		tegra_i2c_vi_init(i2c_dev);
 
-	/* Make sure clock divisor programmed correctly */
-	clk_divisor = FIELD_PREP(I2C_CLK_DIVISOR_HSMODE,
-				 i2c_dev->hw->clk_divisor_hs_mode) |
-		      FIELD_PREP(I2C_CLK_DIVISOR_STD_FAST_MODE,
-				 i2c_dev->clk_divisor_non_hs_mode);
-	i2c_writel(i2c_dev, clk_divisor, I2C_CLK_DIVISOR);
-
-	if (i2c_dev->bus_clk_rate > I2C_MAX_STANDARD_MODE_FREQ &&
-	    i2c_dev->bus_clk_rate <= I2C_MAX_FAST_MODE_PLUS_FREQ) {
+	switch (i2c_dev->bus_clk_rate) {
+	case I2C_MAX_STANDARD_MODE_FREQ + 1 ... I2C_MAX_FAST_MODE_PLUS_FREQ:
+	default:
 		tlow = i2c_dev->hw->tlow_fast_fastplus_mode;
 		thigh = i2c_dev->hw->thigh_fast_fastplus_mode;
 		tsu_thd = i2c_dev->hw->setup_hold_time_fast_fast_plus_mode;
-	} else {
+
+		if (i2c_dev->bus_clk_rate > I2C_MAX_FAST_MODE_FREQ)
+			non_hs_mode = i2c_dev->hw->clk_divisor_fast_plus_mode;
+		else
+			non_hs_mode = i2c_dev->hw->clk_divisor_fast_mode;
+		break;
+
+	case 0 ... I2C_MAX_STANDARD_MODE_FREQ:
 		tlow = i2c_dev->hw->tlow_std_mode;
 		thigh = i2c_dev->hw->thigh_std_mode;
 		tsu_thd = i2c_dev->hw->setup_hold_time_std_mode;
+		non_hs_mode = i2c_dev->hw->clk_divisor_std_mode;
+		break;
 	}
 
+	/* Make sure clock divisor programmed correctly */
+	clk_divisor = FIELD_PREP(I2C_CLK_DIVISOR_HSMODE,
+				 i2c_dev->hw->clk_divisor_hs_mode) |
+		      FIELD_PREP(I2C_CLK_DIVISOR_STD_FAST_MODE, non_hs_mode);
+	i2c_writel(i2c_dev, clk_divisor, I2C_CLK_DIVISOR);
+
 	if (i2c_dev->hw->has_interface_timing_reg) {
 		val = FIELD_PREP(I2C_INTERFACE_TIMING_THIGH, thigh) |
 		      FIELD_PREP(I2C_INTERFACE_TIMING_TLOW, tlow);
@@ -837,7 +845,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 		i2c_writel(i2c_dev, tsu_thd, I2C_INTERFACE_TIMING_1);
 
 	clk_multiplier  = tlow + thigh + 2;
-	clk_multiplier *= i2c_dev->clk_divisor_non_hs_mode + 1;
+	clk_multiplier *= non_hs_mode + 1;
 
 	err = clk_set_rate(i2c_dev->div_clk,
 			   i2c_dev->bus_clk_rate * clk_multiplier);
@@ -1751,18 +1759,6 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 		goto unprepare_fast_clk;
 	}
 
-	if (i2c_dev->bus_clk_rate > I2C_MAX_FAST_MODE_FREQ &&
-	    i2c_dev->bus_clk_rate <= I2C_MAX_FAST_MODE_PLUS_FREQ)
-		i2c_dev->clk_divisor_non_hs_mode =
-				i2c_dev->hw->clk_divisor_fast_plus_mode;
-	else if (i2c_dev->bus_clk_rate > I2C_MAX_STANDARD_MODE_FREQ &&
-		 i2c_dev->bus_clk_rate <= I2C_MAX_FAST_MODE_FREQ)
-		i2c_dev->clk_divisor_non_hs_mode =
-				i2c_dev->hw->clk_divisor_fast_mode;
-	else
-		i2c_dev->clk_divisor_non_hs_mode =
-				i2c_dev->hw->clk_divisor_std_mode;
-
 	ret = clk_prepare(i2c_dev->div_clk);
 	if (ret < 0) {
 		dev_err(i2c_dev->dev, "Clock prepare failed %d\n", ret);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 07/34] i2c: tegra: Runtime PM always available on Tegra
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (5 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 06/34] i2c: tegra: Remove i2c_dev.clk_divisor_non_hs_mode member Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 11:26   ` Thierry Reding
  2020-09-21 10:18   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 08/34] i2c: tegra: Remove error message used for devm_request_irq() failure Dmitry Osipenko
                   ` (28 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

The runtime PM is guaranteed to be always available on Tegra after commit
40b2bb1b132a ("ARM: tegra: enforce PM requirement"). Hence let's remove
all the RPM-availability checking and handling from the code.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 29 ++++++-----------------------
 1 file changed, 6 insertions(+), 23 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 85ed0e02d48c..a52c72135390 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -1775,18 +1775,10 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 	if (!i2c_dev->is_vi)
 		pm_runtime_irq_safe(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
-	if (!pm_runtime_enabled(&pdev->dev)) {
-		ret = tegra_i2c_runtime_resume(&pdev->dev);
-		if (ret < 0) {
-			dev_err(&pdev->dev, "runtime resume failed\n");
-			goto unprepare_div_clk;
-		}
-	} else {
-		ret = pm_runtime_get_sync(i2c_dev->dev);
-		if (ret < 0) {
-			dev_err(&pdev->dev, "runtime resume failed\n");
-			goto put_rpm;
-		}
+	ret = pm_runtime_get_sync(i2c_dev->dev);
+	if (ret < 0) {
+		dev_err(dev, "runtime resume failed\n");
+		goto put_rpm;
 	}
 
 	if (i2c_dev->is_multimaster_mode) {
@@ -1845,15 +1837,8 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 		clk_disable(i2c_dev->div_clk);
 
 put_rpm:
-	if (pm_runtime_enabled(&pdev->dev))
-		pm_runtime_put_sync(&pdev->dev);
-	else
-		tegra_i2c_runtime_suspend(&pdev->dev);
-
-	if (pm_runtime_enabled(&pdev->dev))
-		pm_runtime_disable(&pdev->dev);
-
-unprepare_div_clk:
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
 	clk_unprepare(i2c_dev->div_clk);
 
 unprepare_slow_clk:
@@ -1875,8 +1860,6 @@ static int tegra_i2c_remove(struct platform_device *pdev)
 		clk_disable(i2c_dev->div_clk);
 
 	pm_runtime_disable(&pdev->dev);
-	if (!pm_runtime_status_suspended(&pdev->dev))
-		tegra_i2c_runtime_suspend(&pdev->dev);
 
 	clk_unprepare(i2c_dev->div_clk);
 	clk_unprepare(i2c_dev->slow_clk);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 08/34] i2c: tegra: Remove error message used for devm_request_irq() failure
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (6 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 07/34] i2c: tegra: Runtime PM always available on Tegra Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 11:28   ` Thierry Reding
  2020-09-21 10:18   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 09/34] i2c: tegra: Use reset_control_reset() Dmitry Osipenko
                   ` (27 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

The error message prints number of vIRQ, which isn't a useful information.
In practice devm_request_irq() never fails, hence let's remove the bogus
message in order to make code cleaner.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index a52c72135390..b813c0976c10 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -1807,10 +1807,8 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 
 	ret = devm_request_irq(&pdev->dev, i2c_dev->irq, tegra_i2c_isr,
 			       IRQF_NO_SUSPEND, dev_name(&pdev->dev), i2c_dev);
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to request irq %i\n", i2c_dev->irq);
+	if (ret)
 		goto release_dma;
-	}
 
 	i2c_set_adapdata(&i2c_dev->adapter, i2c_dev);
 	i2c_dev->adapter.owner = THIS_MODULE;
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 09/34] i2c: tegra: Use reset_control_reset()
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (7 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 08/34] i2c: tegra: Remove error message used for devm_request_irq() failure Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 12:36   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 10/34] i2c: tegra: Use devm_platform_get_and_ioremap_resource() Dmitry Osipenko
                   ` (26 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

Use a single reset_control_reset() instead of assert/deasset couple in
order to make code cleaner a tad. Note that the reset_control_reset()
uses 1 microsecond delay instead of 2 that was used previously, but this
shouldn't matter because one microsecond is a default reset time for most
of Tegra peripherals and TRM doesn't mention anything special in regards
to I2C controller's reset propagation time.

In addition don't ignore potential error of the reset control by emitting
a noisy warning if it fails, which will indicate an existence of a severe
problem, while still allow machine to boot up.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index b813c0976c10..90ba2f5327c5 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -785,9 +785,16 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 	u32 tsu_thd;
 	u8 tlow, thigh;
 
-	reset_control_assert(i2c_dev->rst);
-	udelay(2);
-	reset_control_deassert(i2c_dev->rst);
+	/*
+	 * The reset shouldn't ever fail in practice. The failure will be a
+	 * sign of a severe problem that needs to be resolved. Still we don't
+	 * want to fail the initialization completely because this may break
+	 * kernel boot up since voltage regulators use I2C. Hence, we will
+	 * emit a noisy warning on error, which won't stay unnoticed and
+	 * won't hose machine entirely.
+	 */
+	err = reset_control_reset(i2c_dev->rst);
+	WARN_ON_ONCE(err);
 
 	if (i2c_dev->is_dvc)
 		tegra_dvc_init(i2c_dev);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 10/34] i2c: tegra: Use devm_platform_get_and_ioremap_resource()
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (8 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 09/34] i2c: tegra: Use reset_control_reset() Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 11:31   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 11/34] i2c: tegra: Use platform_get_irq() Dmitry Osipenko
                   ` (25 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

Driver now uses devm_platform_get_and_ioremap_resource() which replaces
the typical boilerplate code and makes code cleaner.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 90ba2f5327c5..c2bbdf92b11f 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -1678,12 +1678,12 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 	int irq;
 	int ret;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	base_phys = res->start;
-	base = devm_ioremap_resource(&pdev->dev, res);
+	base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
 	if (IS_ERR(base))
 		return PTR_ERR(base);
 
+	base_phys = res->start;
+
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!res) {
 		dev_err(&pdev->dev, "no irq resource\n");
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 11/34] i2c: tegra: Use platform_get_irq()
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (9 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 10/34] i2c: tegra: Use devm_platform_get_and_ioremap_resource() Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 11:31   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 12/34] i2c: tegra: Use clk-bulk helpers Dmitry Osipenko
                   ` (24 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

Use common helper for retrieval of the interrupt number in order to make
code cleaner. Note that platform_get_irq() prints error message by itself.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index c2bbdf92b11f..505b5d37077d 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -1684,12 +1684,9 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 
 	base_phys = res->start;
 
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (!res) {
-		dev_err(&pdev->dev, "no irq resource\n");
-		return -EINVAL;
-	}
-	irq = res->start;
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
 
 	div_clk = devm_clk_get(&pdev->dev, "div-clk");
 	if (IS_ERR(div_clk)) {
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 12/34] i2c: tegra: Use clk-bulk helpers
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (10 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 11/34] i2c: tegra: Use platform_get_irq() Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 11:38   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 13/34] i2c: tegra: Move out all device-tree parsing into tegra_i2c_parse_dt() Dmitry Osipenko
                   ` (23 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

Use clk-bulk helpers and factor out clocks initialization into separate
function in order to make code cleaner.

The clocks initialization now performed after reset-control initialization
in order to avoid a noisy -PROBE_DEFER errors on T186+ from the clk-bulk
helper which doesn't silence this error code. Hence reset_control_get()
now may return -EPROBE_DEFER on newer Tegra SoCs because they use BPMP
driver that provides reset controls and BPMP doesn't come up early during
boot. Previously rst was protected by the clocks retrieval and now this
patch makes dev_err_probe() to be used for the rst error handling.

Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 187 ++++++++++++---------------------
 1 file changed, 67 insertions(+), 120 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 505b5d37077d..c6a29a8069d9 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -165,9 +165,6 @@ enum msg_end_type {
  * @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 have 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.
@@ -208,7 +205,6 @@ enum msg_end_type {
 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_mode;
@@ -236,7 +232,8 @@ struct tegra_i2c_hw_feature {
  * @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
+ * @clocks: array of I2C controller clocks
+ * @nclocks: number of clocks in the array
  * @rst: reset control for the I2C controller
  * @base: ioremapped registers cookie
  * @base_phys: physical base address of the I2C controller
@@ -265,8 +262,8 @@ struct tegra_i2c_dev {
 	const struct tegra_i2c_hw_feature *hw;
 	struct i2c_adapter adapter;
 	struct clk *div_clk;
-	struct clk *fast_clk;
-	struct clk *slow_clk;
+	struct clk_bulk_data *clocks;
+	unsigned int nclocks;
 	struct reset_control *rst;
 	void __iomem *base;
 	phys_addr_t base_phys;
@@ -662,25 +659,9 @@ static int __maybe_unused tegra_i2c_runtime_resume(struct device *dev)
 	if (ret)
 		return ret;
 
-	ret = clk_enable(i2c_dev->fast_clk);
-	if (ret < 0) {
-		dev_err(i2c_dev->dev,
-			"Enabling fast clk failed, err %d\n", ret);
+	ret = clk_bulk_enable(i2c_dev->nclocks, i2c_dev->clocks);
+	if (ret)
 		return ret;
-	}
-
-	ret = clk_enable(i2c_dev->slow_clk);
-	if (ret < 0) {
-		dev_err(dev, "failed to enable slow clock: %d\n", ret);
-		goto disable_fast_clk;
-	}
-
-	ret = clk_enable(i2c_dev->div_clk);
-	if (ret < 0) {
-		dev_err(i2c_dev->dev,
-			"Enabling div clk failed, err %d\n", ret);
-		goto disable_slow_clk;
-	}
 
 	/*
 	 * VI I2C device is attached to VE power domain which goes through
@@ -691,17 +672,14 @@ static int __maybe_unused tegra_i2c_runtime_resume(struct device *dev)
 	if (i2c_dev->is_vi) {
 		ret = tegra_i2c_init(i2c_dev);
 		if (ret)
-			goto disable_div_clk;
+			goto disable_clocks;
 	}
 
 	return 0;
 
-disable_div_clk:
-	clk_disable(i2c_dev->div_clk);
-disable_slow_clk:
-	clk_disable(i2c_dev->slow_clk);
-disable_fast_clk:
-	clk_disable(i2c_dev->fast_clk);
+disable_clocks:
+	clk_bulk_disable(i2c_dev->nclocks, i2c_dev->clocks);
+
 	return ret;
 }
 
@@ -709,9 +687,7 @@ static int __maybe_unused tegra_i2c_runtime_suspend(struct device *dev)
 {
 	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
 
-	clk_disable(i2c_dev->div_clk);
-	clk_disable(i2c_dev->slow_clk);
-	clk_disable(i2c_dev->fast_clk);
+	clk_bulk_disable(i2c_dev->nclocks, i2c_dev->clocks);
 
 	return pinctrl_pm_select_idle_state(i2c_dev->dev);
 }
@@ -1479,7 +1455,6 @@ static struct i2c_bus_recovery_info tegra_i2c_recovery_info = {
 static const struct tegra_i2c_hw_feature tegra20_i2c_hw = {
 	.has_continue_xfer_support = false,
 	.has_per_pkt_xfer_complete_irq = false,
-	.has_single_clk_source = false,
 	.clk_divisor_hs_mode = 3,
 	.clk_divisor_std_mode = 0,
 	.clk_divisor_fast_mode = 0,
@@ -1504,7 +1479,6 @@ static const struct tegra_i2c_hw_feature tegra20_i2c_hw = {
 static const struct tegra_i2c_hw_feature tegra30_i2c_hw = {
 	.has_continue_xfer_support = true,
 	.has_per_pkt_xfer_complete_irq = false,
-	.has_single_clk_source = false,
 	.clk_divisor_hs_mode = 3,
 	.clk_divisor_std_mode = 0,
 	.clk_divisor_fast_mode = 0,
@@ -1529,7 +1503,6 @@ static const struct tegra_i2c_hw_feature tegra30_i2c_hw = {
 static const struct tegra_i2c_hw_feature tegra114_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_mode = 0x19,
 	.clk_divisor_fast_mode = 0x19,
@@ -1554,7 +1527,6 @@ static const struct tegra_i2c_hw_feature tegra114_i2c_hw = {
 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_mode = 0x19,
 	.clk_divisor_fast_mode = 0x19,
@@ -1579,7 +1551,6 @@ static const struct tegra_i2c_hw_feature tegra124_i2c_hw = {
 static const struct tegra_i2c_hw_feature tegra210_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_mode = 0x19,
 	.clk_divisor_fast_mode = 0x19,
@@ -1604,7 +1575,6 @@ static const struct tegra_i2c_hw_feature tegra210_i2c_hw = {
 static const struct tegra_i2c_hw_feature tegra186_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_mode = 0x16,
 	.clk_divisor_fast_mode = 0x19,
@@ -1629,7 +1599,6 @@ static const struct tegra_i2c_hw_feature tegra186_i2c_hw = {
 static const struct tegra_i2c_hw_feature tegra194_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_mode = 0x4f,
 	.clk_divisor_fast_mode = 0x3c,
@@ -1666,13 +1635,58 @@ static const struct of_device_id tegra_i2c_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, tegra_i2c_of_match);
 
+static int tegra_i2c_init_clocks(struct tegra_i2c_dev *i2c_dev)
+{
+	unsigned int i;
+	int err;
+
+	err = devm_clk_bulk_get_all(i2c_dev->dev, &i2c_dev->clocks);
+	if (err < 0)
+		return err;
+
+	i2c_dev->nclocks = err;
+
+	err = clk_bulk_prepare(i2c_dev->nclocks, i2c_dev->clocks);
+	if (err)
+		return err;
+
+	for (i = 0; i < i2c_dev->nclocks; i++) {
+		if (!strcmp(i2c_dev->clocks[i].id, "div-clk")) {
+			i2c_dev->div_clk = i2c_dev->clocks[i].clk;
+			break;
+		}
+	}
+
+	if (!i2c_dev->is_multimaster_mode)
+		return 0;
+
+	err = clk_enable(i2c_dev->div_clk);
+	if (err) {
+		dev_err(i2c_dev->dev, "failed to enable div-clk: %d\n", err);
+		goto unprepare_clocks;
+	}
+
+	return 0;
+
+unprepare_clocks:
+	clk_bulk_unprepare(i2c_dev->nclocks, i2c_dev->clocks);
+
+	return err;
+}
+
+static void tegra_i2c_release_clocks(struct tegra_i2c_dev *i2c_dev)
+{
+	if (i2c_dev->is_multimaster_mode)
+		clk_disable(i2c_dev->div_clk);
+
+	clk_bulk_unprepare(i2c_dev->nclocks, i2c_dev->clocks);
+}
+
 static int tegra_i2c_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct tegra_i2c_dev *i2c_dev;
 	struct resource *res;
-	struct clk *div_clk;
-	struct clk *fast_clk;
 	void __iomem *base;
 	phys_addr_t base_phys;
 	int irq;
@@ -1688,21 +1702,12 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 	if (irq < 0)
 		return irq;
 
-	div_clk = devm_clk_get(&pdev->dev, "div-clk");
-	if (IS_ERR(div_clk)) {
-		if (PTR_ERR(div_clk) != -EPROBE_DEFER)
-			dev_err(&pdev->dev, "missing controller clock\n");
-
-		return PTR_ERR(div_clk);
-	}
-
 	i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL);
 	if (!i2c_dev)
 		return -ENOMEM;
 
 	i2c_dev->base = base;
 	i2c_dev->base_phys = base_phys;
-	i2c_dev->div_clk = div_clk;
 	i2c_dev->adapter.algo = &tegra_i2c_algo;
 	i2c_dev->adapter.retries = 1;
 	i2c_dev->adapter.timeout = 6 * HZ;
@@ -1712,12 +1717,17 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 
 	i2c_dev->rst = devm_reset_control_get_exclusive(&pdev->dev, "i2c");
 	if (IS_ERR(i2c_dev->rst)) {
-		dev_err(&pdev->dev, "missing controller reset\n");
+		dev_err_probe(&pdev->dev, PTR_ERR(i2c_dev->rst),
+			      "failed to get reset control\n");
 		return PTR_ERR(i2c_dev->rst);
 	}
 
 	tegra_i2c_parse_dt(i2c_dev);
 
+	ret = tegra_i2c_init_clocks(i2c_dev);
+	if (ret)
+		return ret;
+
 	i2c_dev->hw = of_device_get_match_data(&pdev->dev);
 	i2c_dev->is_dvc = of_device_is_compatible(pdev->dev.of_node,
 						  "nvidia,tegra20-i2c-dvc");
@@ -1729,46 +1739,8 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 	init_completion(&i2c_dev->msg_complete);
 	init_completion(&i2c_dev->dma_complete);
 
-	if (!i2c_dev->hw->has_single_clk_source) {
-		fast_clk = devm_clk_get(&pdev->dev, "fast-clk");
-		if (IS_ERR(fast_clk)) {
-			dev_err(&pdev->dev, "missing fast clock\n");
-			return PTR_ERR(fast_clk);
-		}
-		i2c_dev->fast_clk = fast_clk;
-	}
-
-	if (i2c_dev->is_vi) {
-		i2c_dev->slow_clk = devm_clk_get(dev, "slow");
-		if (IS_ERR(i2c_dev->slow_clk)) {
-			if (PTR_ERR(i2c_dev->slow_clk) != -EPROBE_DEFER)
-				dev_err(dev, "failed to get slow clock: %ld\n",
-					PTR_ERR(i2c_dev->slow_clk));
-
-			return PTR_ERR(i2c_dev->slow_clk);
-		}
-	}
-
 	platform_set_drvdata(pdev, i2c_dev);
 
-	ret = clk_prepare(i2c_dev->fast_clk);
-	if (ret < 0) {
-		dev_err(i2c_dev->dev, "Clock prepare failed %d\n", ret);
-		return ret;
-	}
-
-	ret = clk_prepare(i2c_dev->slow_clk);
-	if (ret < 0) {
-		dev_err(dev, "failed to prepare slow clock: %d\n", ret);
-		goto unprepare_fast_clk;
-	}
-
-	ret = clk_prepare(i2c_dev->div_clk);
-	if (ret < 0) {
-		dev_err(i2c_dev->dev, "Clock prepare failed %d\n", ret);
-		goto unprepare_slow_clk;
-	}
-
 	/*
 	 * VI I2C is in VE power domain which is not always on and not
 	 * an IRQ safe. So, IRQ safe device can't be attached to a non-IRQ
@@ -1785,21 +1757,12 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 		goto put_rpm;
 	}
 
-	if (i2c_dev->is_multimaster_mode) {
-		ret = clk_enable(i2c_dev->div_clk);
-		if (ret < 0) {
-			dev_err(i2c_dev->dev, "div_clk enable failed %d\n",
-				ret);
-			goto put_rpm;
-		}
-	}
-
 	if (i2c_dev->hw->supports_bus_clear)
 		i2c_dev->adapter.bus_recovery_info = &tegra_i2c_recovery_info;
 
 	ret = tegra_i2c_init_dma(i2c_dev);
 	if (ret < 0)
-		goto disable_div_clk;
+		goto put_rpm;
 
 	ret = tegra_i2c_init(i2c_dev);
 	if (ret) {
@@ -1834,20 +1797,10 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 release_dma:
 	tegra_i2c_release_dma(i2c_dev);
 
-disable_div_clk:
-	if (i2c_dev->is_multimaster_mode)
-		clk_disable(i2c_dev->div_clk);
-
 put_rpm:
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
-	clk_unprepare(i2c_dev->div_clk);
-
-unprepare_slow_clk:
-	clk_unprepare(i2c_dev->slow_clk);
-
-unprepare_fast_clk:
-	clk_unprepare(i2c_dev->fast_clk);
+	tegra_i2c_release_clocks(i2c_dev);
 
 	return ret;
 }
@@ -1858,16 +1811,10 @@ static int tegra_i2c_remove(struct platform_device *pdev)
 
 	i2c_del_adapter(&i2c_dev->adapter);
 
-	if (i2c_dev->is_multimaster_mode)
-		clk_disable(i2c_dev->div_clk);
-
 	pm_runtime_disable(&pdev->dev);
 
-	clk_unprepare(i2c_dev->div_clk);
-	clk_unprepare(i2c_dev->slow_clk);
-	clk_unprepare(i2c_dev->fast_clk);
-
 	tegra_i2c_release_dma(i2c_dev);
+	tegra_i2c_release_clocks(i2c_dev);
 	return 0;
 }
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 13/34] i2c: tegra: Move out all device-tree parsing into tegra_i2c_parse_dt()
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (11 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 12/34] i2c: tegra: Use clk-bulk helpers Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 11:35   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 14/34] i2c: tegra: Clean up probe function Dmitry Osipenko
                   ` (22 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

Move out code related to device-tree parsing from the probe function into
tegra_i2c_parse_dt() in order to make code more consistent.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index c6a29a8069d9..79d1cefdc901 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -1428,6 +1428,12 @@ static void tegra_i2c_parse_dt(struct tegra_i2c_dev *i2c_dev)
 
 	multi_mode = of_property_read_bool(np, "multi-master");
 	i2c_dev->is_multimaster_mode = multi_mode;
+
+	if (of_device_is_compatible(np, "nvidia,tegra20-i2c-dvc"))
+		i2c_dev->is_dvc = true;
+
+	if (of_device_is_compatible(np, "nvidia,tegra210-i2c-vi"))
+		i2c_dev->is_vi = true;
 }
 
 static const struct i2c_algorithm tegra_i2c_algo = {
@@ -1729,10 +1735,6 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 		return ret;
 
 	i2c_dev->hw = of_device_get_match_data(&pdev->dev);
-	i2c_dev->is_dvc = of_device_is_compatible(pdev->dev.of_node,
-						  "nvidia,tegra20-i2c-dvc");
-	i2c_dev->is_vi = of_device_is_compatible(dev->of_node,
-						 "nvidia,tegra210-i2c-vi");
 	i2c_dev->adapter.quirks = i2c_dev->hw->quirks;
 	i2c_dev->dma_buf_size = i2c_dev->adapter.quirks->max_write_len +
 				I2C_PACKET_HEADER_SIZE;
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 14/34] i2c: tegra: Clean up probe function
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (12 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 13/34] i2c: tegra: Move out all device-tree parsing into tegra_i2c_parse_dt() Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 12:37   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 15/34] i2c: tegra: Reorder location of functions in the code Dmitry Osipenko
                   ` (21 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

The driver's probe function code is a bit difficult to read. This patch
reorders code of the probe function, forming groups of code that are easy
to work with. The probe tear-down order now matches the driver-removal
order.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 100 ++++++++++++++++-----------------
 1 file changed, 49 insertions(+), 51 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 79d1cefdc901..7c91bbb3f95c 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -440,6 +440,9 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev)
 
 	i2c_dev->tx_dma_chan = chan;
 
+	i2c_dev->dma_buf_size = i2c_dev->hw->quirks->max_write_len +
+				I2C_PACKET_HEADER_SIZE;
+
 	dma_buf = dma_alloc_coherent(i2c_dev->dev, i2c_dev->dma_buf_size,
 				     &dma_phys, GFP_KERNEL | __GFP_NOWARN);
 	if (!dma_buf) {
@@ -1693,34 +1696,42 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct tegra_i2c_dev *i2c_dev;
 	struct resource *res;
-	void __iomem *base;
-	phys_addr_t base_phys;
-	int irq;
 	int ret;
 
-	base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
-	if (IS_ERR(base))
-		return PTR_ERR(base);
-
-	base_phys = res->start;
-
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
-		return irq;
-
 	i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL);
 	if (!i2c_dev)
 		return -ENOMEM;
 
-	i2c_dev->base = base;
-	i2c_dev->base_phys = base_phys;
-	i2c_dev->adapter.algo = &tegra_i2c_algo;
-	i2c_dev->adapter.retries = 1;
-	i2c_dev->adapter.timeout = 6 * HZ;
-	i2c_dev->irq = irq;
+	platform_set_drvdata(pdev, i2c_dev);
+
+	init_completion(&i2c_dev->msg_complete);
+	init_completion(&i2c_dev->dma_complete);
+
+	i2c_dev->hw = of_device_get_match_data(&pdev->dev);
 	i2c_dev->cont_id = pdev->id;
 	i2c_dev->dev = &pdev->dev;
 
+	i2c_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+	if (IS_ERR(i2c_dev->base))
+		return PTR_ERR(i2c_dev->base);
+
+	i2c_dev->base_phys = res->start;
+
+	ret = platform_get_irq(pdev, 0);
+	if (ret < 0)
+		return ret;
+
+	i2c_dev->irq = ret;
+
+	/* interrupt will be enabled during of transfer time */
+	irq_set_status_flags(i2c_dev->irq, IRQ_NOAUTOEN);
+
+	ret = devm_request_irq(&pdev->dev, i2c_dev->irq, tegra_i2c_isr,
+			       IRQF_NO_SUSPEND, dev_name(&pdev->dev),
+			       i2c_dev);
+	if (ret)
+		return ret;
+
 	i2c_dev->rst = devm_reset_control_get_exclusive(&pdev->dev, "i2c");
 	if (IS_ERR(i2c_dev->rst)) {
 		dev_err_probe(&pdev->dev, PTR_ERR(i2c_dev->rst),
@@ -1734,14 +1745,9 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 	if (ret)
 		return ret;
 
-	i2c_dev->hw = of_device_get_match_data(&pdev->dev);
-	i2c_dev->adapter.quirks = i2c_dev->hw->quirks;
-	i2c_dev->dma_buf_size = i2c_dev->adapter.quirks->max_write_len +
-				I2C_PACKET_HEADER_SIZE;
-	init_completion(&i2c_dev->msg_complete);
-	init_completion(&i2c_dev->dma_complete);
-
-	platform_set_drvdata(pdev, i2c_dev);
+	ret = tegra_i2c_init_dma(i2c_dev);
+	if (ret)
+		goto release_clocks;
 
 	/*
 	 * VI I2C is in VE power domain which is not always on and not
@@ -1759,49 +1765,41 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 		goto put_rpm;
 	}
 
-	if (i2c_dev->hw->supports_bus_clear)
-		i2c_dev->adapter.bus_recovery_info = &tegra_i2c_recovery_info;
-
-	ret = tegra_i2c_init_dma(i2c_dev);
-	if (ret < 0)
-		goto put_rpm;
-
 	ret = tegra_i2c_init(i2c_dev);
-	if (ret) {
-		dev_err(&pdev->dev, "Failed to initialize i2c controller\n");
-		goto release_dma;
-	}
-
-	irq_set_status_flags(i2c_dev->irq, IRQ_NOAUTOEN);
-
-	ret = devm_request_irq(&pdev->dev, i2c_dev->irq, tegra_i2c_isr,
-			       IRQF_NO_SUSPEND, dev_name(&pdev->dev), i2c_dev);
 	if (ret)
-		goto release_dma;
+		goto put_rpm;
 
 	i2c_set_adapdata(&i2c_dev->adapter, i2c_dev);
+	i2c_dev->adapter.dev.of_node = pdev->dev.of_node;
+	i2c_dev->adapter.dev.parent = &pdev->dev;
+	i2c_dev->adapter.retries = 1;
+	i2c_dev->adapter.timeout = 6 * HZ;
+	i2c_dev->adapter.quirks = i2c_dev->hw->quirks;
 	i2c_dev->adapter.owner = THIS_MODULE;
 	i2c_dev->adapter.class = I2C_CLASS_DEPRECATED;
+	i2c_dev->adapter.algo = &tegra_i2c_algo;
+	i2c_dev->adapter.nr = pdev->id;
+
+	if (i2c_dev->hw->supports_bus_clear)
+		i2c_dev->adapter.bus_recovery_info = &tegra_i2c_recovery_info;
+
 	strlcpy(i2c_dev->adapter.name, dev_name(&pdev->dev),
 		sizeof(i2c_dev->adapter.name));
-	i2c_dev->adapter.dev.parent = &pdev->dev;
-	i2c_dev->adapter.nr = pdev->id;
-	i2c_dev->adapter.dev.of_node = pdev->dev.of_node;
 
 	ret = i2c_add_numbered_adapter(&i2c_dev->adapter);
 	if (ret)
-		goto release_dma;
+		goto put_rpm;
 
 	pm_runtime_put(&pdev->dev);
 
 	return 0;
 
-release_dma:
-	tegra_i2c_release_dma(i2c_dev);
-
 put_rpm:
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
+
+	tegra_i2c_release_dma(i2c_dev);
+release_clocks:
 	tegra_i2c_release_clocks(i2c_dev);
 
 	return ret;
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 15/34] i2c: tegra: Reorder location of functions in the code
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (13 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 14/34] i2c: tegra: Clean up probe function Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 12:38   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 16/34] i2c: tegra: Clean up variable types Dmitry Osipenko
                   ` (20 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

Reorder location of functions in the code in order to have definition
of functions closer to the place of the invocation. This change makes
easier to navigate around the code and removes the need to have a
prototype for tegra_i2c_init().

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 486 ++++++++++++++++-----------------
 1 file changed, 242 insertions(+), 244 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 7c91bbb3f95c..5a0bb5b3876c 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -288,8 +288,6 @@ struct tegra_i2c_dev {
 	bool is_curr_atomic_xfer;
 };
 
-static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev);
-
 static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val,
 		       unsigned long reg)
 {
@@ -466,6 +464,56 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev)
 	return err;
 }
 
+/*
+ * One of the Tegra I2C blocks is inside the DVC (Digital Voltage Controller)
+ * block.  This block is identical to the rest of the I2C blocks, except that
+ * it only supports master mode, it has registers moved around, and it needs
+ * some extra init to get it into I2C mode.  The register moves are handled
+ * by i2c_readl and i2c_writel
+ */
+static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev)
+{
+	u32 val;
+
+	val = dvc_readl(i2c_dev, DVC_CTRL_REG3);
+	val |= DVC_CTRL_REG3_SW_PROG;
+	val |= DVC_CTRL_REG3_I2C_DONE_INTR_EN;
+	dvc_writel(i2c_dev, val, DVC_CTRL_REG3);
+
+	val = dvc_readl(i2c_dev, DVC_CTRL_REG1);
+	val |= DVC_CTRL_REG1_INTR_EN;
+	dvc_writel(i2c_dev, val, DVC_CTRL_REG1);
+}
+
+static void tegra_i2c_vi_init(struct tegra_i2c_dev *i2c_dev)
+{
+	u32 value;
+
+	value = FIELD_PREP(I2C_INTERFACE_TIMING_THIGH, 2) |
+		FIELD_PREP(I2C_INTERFACE_TIMING_TLOW, 4);
+	i2c_writel(i2c_dev, value, I2C_INTERFACE_TIMING_0);
+
+	value = FIELD_PREP(I2C_INTERFACE_TIMING_TBUF, 4) |
+		FIELD_PREP(I2C_INTERFACE_TIMING_TSU_STO, 7) |
+		FIELD_PREP(I2C_INTERFACE_TIMING_THD_STA, 4) |
+		FIELD_PREP(I2C_INTERFACE_TIMING_TSU_STA, 4);
+	i2c_writel(i2c_dev, value, I2C_INTERFACE_TIMING_1);
+
+	value = FIELD_PREP(I2C_HS_INTERFACE_TIMING_THIGH, 3) |
+		FIELD_PREP(I2C_HS_INTERFACE_TIMING_TLOW, 8);
+	i2c_writel(i2c_dev, value, I2C_HS_INTERFACE_TIMING_0);
+
+	value = FIELD_PREP(I2C_HS_INTERFACE_TIMING_TSU_STO, 11) |
+		FIELD_PREP(I2C_HS_INTERFACE_TIMING_THD_STA, 11) |
+		FIELD_PREP(I2C_HS_INTERFACE_TIMING_TSU_STA, 11);
+	i2c_writel(i2c_dev, value, I2C_HS_INTERFACE_TIMING_1);
+
+	value = FIELD_PREP(I2C_BC_SCLK_THRESHOLD, 9) | I2C_BC_STOP_COND;
+	i2c_writel(i2c_dev, value, I2C_BUS_CLEAR_CNFG);
+
+	i2c_writel(i2c_dev, 0x0, I2C_TLOW_SEXT);
+}
+
 static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
 {
 	u32 mask, val, offset, reg_offset;
@@ -503,198 +551,6 @@ static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
 	return 0;
 }
 
-static int tegra_i2c_empty_rx_fifo(struct tegra_i2c_dev *i2c_dev)
-{
-	u32 val;
-	int rx_fifo_avail;
-	u8 *buf = i2c_dev->msg_buf;
-	size_t buf_remaining = i2c_dev->msg_buf_remaining;
-	int words_to_transfer;
-
-	/*
-	 * Catch overflow due to message fully sent
-	 * before the check for RX FIFO availability.
-	 */
-	if (WARN_ON_ONCE(!(i2c_dev->msg_buf_remaining)))
-		return -EINVAL;
-
-	if (i2c_dev->hw->has_mst_fifo) {
-		val = i2c_readl(i2c_dev, I2C_MST_FIFO_STATUS);
-		rx_fifo_avail = FIELD_GET(I2C_MST_FIFO_STATUS_RX, val);
-	} else {
-		val = i2c_readl(i2c_dev, I2C_FIFO_STATUS);
-		rx_fifo_avail = FIELD_GET(I2C_FIFO_STATUS_RX, val);
-	}
-
-	/* Rounds down to not include partial word at the end of buf */
-	words_to_transfer = buf_remaining / BYTES_PER_FIFO_WORD;
-	if (words_to_transfer > rx_fifo_avail)
-		words_to_transfer = rx_fifo_avail;
-
-	i2c_readsl(i2c_dev, buf, I2C_RX_FIFO, words_to_transfer);
-
-	buf += words_to_transfer * BYTES_PER_FIFO_WORD;
-	buf_remaining -= words_to_transfer * BYTES_PER_FIFO_WORD;
-	rx_fifo_avail -= words_to_transfer;
-
-	/*
-	 * If there is a partial word at the end of buf, handle it manually to
-	 * prevent overwriting past the end of buf
-	 */
-	if (rx_fifo_avail > 0 && buf_remaining > 0) {
-		/*
-		 * buf_remaining > 3 check not needed as rx_fifo_avail == 0
-		 * when (words_to_transfer was > rx_fifo_avail) earlier
-		 * in this function.
-		 */
-		val = i2c_readl(i2c_dev, I2C_RX_FIFO);
-		val = cpu_to_le32(val);
-		memcpy(buf, &val, buf_remaining);
-		buf_remaining = 0;
-		rx_fifo_avail--;
-	}
-
-	/* RX FIFO must be drained, otherwise it's an Overflow case. */
-	if (WARN_ON_ONCE(rx_fifo_avail))
-		return -EINVAL;
-
-	i2c_dev->msg_buf_remaining = buf_remaining;
-	i2c_dev->msg_buf = buf;
-
-	return 0;
-}
-
-static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
-{
-	u32 val;
-	int tx_fifo_avail;
-	u8 *buf = i2c_dev->msg_buf;
-	size_t buf_remaining = i2c_dev->msg_buf_remaining;
-	int words_to_transfer;
-
-	if (i2c_dev->hw->has_mst_fifo) {
-		val = i2c_readl(i2c_dev, I2C_MST_FIFO_STATUS);
-		tx_fifo_avail = FIELD_GET(I2C_MST_FIFO_STATUS_TX, val);
-	} else {
-		val = i2c_readl(i2c_dev, I2C_FIFO_STATUS);
-		tx_fifo_avail = FIELD_GET(I2C_FIFO_STATUS_TX, val);
-	}
-
-	/* Rounds down to not include partial word at the end of buf */
-	words_to_transfer = buf_remaining / BYTES_PER_FIFO_WORD;
-
-	/* It's very common to have < 4 bytes, so optimize that case. */
-	if (words_to_transfer) {
-		if (words_to_transfer > tx_fifo_avail)
-			words_to_transfer = tx_fifo_avail;
-
-		/*
-		 * Update state before writing to FIFO.  If this casues us
-		 * to finish writing all bytes (AKA buf_remaining goes to 0) we
-		 * have a potential for an interrupt (PACKET_XFER_COMPLETE is
-		 * not maskable).  We need to make sure that the isr sees
-		 * buf_remaining as 0 and doesn't call us back re-entrantly.
-		 */
-		buf_remaining -= words_to_transfer * BYTES_PER_FIFO_WORD;
-		tx_fifo_avail -= words_to_transfer;
-		i2c_dev->msg_buf_remaining = buf_remaining;
-		i2c_dev->msg_buf = buf +
-			words_to_transfer * BYTES_PER_FIFO_WORD;
-		barrier();
-
-		i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
-
-		buf += words_to_transfer * BYTES_PER_FIFO_WORD;
-	}
-
-	/*
-	 * If there is a partial word at the end of buf, handle it manually to
-	 * prevent reading past the end of buf, which could cross a page
-	 * boundary and fault.
-	 */
-	if (tx_fifo_avail > 0 && buf_remaining > 0) {
-		/*
-		 * buf_remaining > 3 check not needed as tx_fifo_avail == 0
-		 * when (words_to_transfer was > tx_fifo_avail) earlier
-		 * in this function for non-zero words_to_transfer.
-		 */
-		memcpy(&val, buf, buf_remaining);
-		val = le32_to_cpu(val);
-
-		/* Again update before writing to FIFO to make sure isr sees. */
-		i2c_dev->msg_buf_remaining = 0;
-		i2c_dev->msg_buf = NULL;
-		barrier();
-
-		i2c_writel(i2c_dev, val, I2C_TX_FIFO);
-	}
-
-	return 0;
-}
-
-/*
- * One of the Tegra I2C blocks is inside the DVC (Digital Voltage Controller)
- * block.  This block is identical to the rest of the I2C blocks, except that
- * it only supports master mode, it has registers moved around, and it needs
- * some extra init to get it into I2C mode.  The register moves are handled
- * by i2c_readl and i2c_writel
- */
-static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev)
-{
-	u32 val;
-
-	val = dvc_readl(i2c_dev, DVC_CTRL_REG3);
-	val |= DVC_CTRL_REG3_SW_PROG;
-	val |= DVC_CTRL_REG3_I2C_DONE_INTR_EN;
-	dvc_writel(i2c_dev, val, DVC_CTRL_REG3);
-
-	val = dvc_readl(i2c_dev, DVC_CTRL_REG1);
-	val |= DVC_CTRL_REG1_INTR_EN;
-	dvc_writel(i2c_dev, val, DVC_CTRL_REG1);
-}
-
-static int __maybe_unused tegra_i2c_runtime_resume(struct device *dev)
-{
-	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
-	int ret;
-
-	ret = pinctrl_pm_select_default_state(i2c_dev->dev);
-	if (ret)
-		return ret;
-
-	ret = clk_bulk_enable(i2c_dev->nclocks, i2c_dev->clocks);
-	if (ret)
-		return ret;
-
-	/*
-	 * VI I2C device is attached to VE power domain which goes through
-	 * power ON/OFF during PM runtime resume/suspend. So, controller
-	 * should go through reset and need to re-initialize after power
-	 * domain ON.
-	 */
-	if (i2c_dev->is_vi) {
-		ret = tegra_i2c_init(i2c_dev);
-		if (ret)
-			goto disable_clocks;
-	}
-
-	return 0;
-
-disable_clocks:
-	clk_bulk_disable(i2c_dev->nclocks, i2c_dev->clocks);
-
-	return ret;
-}
-
-static int __maybe_unused tegra_i2c_runtime_suspend(struct device *dev)
-{
-	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
-
-	clk_bulk_disable(i2c_dev->nclocks, i2c_dev->clocks);
-
-	return pinctrl_pm_select_idle_state(i2c_dev->dev);
-}
-
 static int tegra_i2c_wait_for_config_load(struct tegra_i2c_dev *i2c_dev)
 {
 	unsigned long reg_offset;
@@ -726,35 +582,6 @@ static int tegra_i2c_wait_for_config_load(struct tegra_i2c_dev *i2c_dev)
 	return 0;
 }
 
-static void tegra_i2c_vi_init(struct tegra_i2c_dev *i2c_dev)
-{
-	u32 value;
-
-	value = FIELD_PREP(I2C_INTERFACE_TIMING_THIGH, 2) |
-		FIELD_PREP(I2C_INTERFACE_TIMING_TLOW, 4);
-	i2c_writel(i2c_dev, value, I2C_INTERFACE_TIMING_0);
-
-	value = FIELD_PREP(I2C_INTERFACE_TIMING_TBUF, 4) |
-		FIELD_PREP(I2C_INTERFACE_TIMING_TSU_STO, 7) |
-		FIELD_PREP(I2C_INTERFACE_TIMING_THD_STA, 4) |
-		FIELD_PREP(I2C_INTERFACE_TIMING_TSU_STA, 4);
-	i2c_writel(i2c_dev, value, I2C_INTERFACE_TIMING_1);
-
-	value = FIELD_PREP(I2C_HS_INTERFACE_TIMING_THIGH, 3) |
-		FIELD_PREP(I2C_HS_INTERFACE_TIMING_TLOW, 8);
-	i2c_writel(i2c_dev, value, I2C_HS_INTERFACE_TIMING_0);
-
-	value = FIELD_PREP(I2C_HS_INTERFACE_TIMING_TSU_STO, 11) |
-		FIELD_PREP(I2C_HS_INTERFACE_TIMING_THD_STA, 11) |
-		FIELD_PREP(I2C_HS_INTERFACE_TIMING_TSU_STA, 11);
-	i2c_writel(i2c_dev, value, I2C_HS_INTERFACE_TIMING_1);
-
-	value = FIELD_PREP(I2C_BC_SCLK_THRESHOLD, 9) | I2C_BC_STOP_COND;
-	i2c_writel(i2c_dev, value, I2C_BUS_CLEAR_CNFG);
-
-	i2c_writel(i2c_dev, 0x0, I2C_TLOW_SEXT);
-}
-
 static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 {
 	u32 val;
@@ -882,6 +709,135 @@ static int tegra_i2c_disable_packet_mode(struct tegra_i2c_dev *i2c_dev)
 	return tegra_i2c_wait_for_config_load(i2c_dev);
 }
 
+static int tegra_i2c_empty_rx_fifo(struct tegra_i2c_dev *i2c_dev)
+{
+	u32 val;
+	int rx_fifo_avail;
+	u8 *buf = i2c_dev->msg_buf;
+	size_t buf_remaining = i2c_dev->msg_buf_remaining;
+	int words_to_transfer;
+
+	/*
+	 * Catch overflow due to message fully sent
+	 * before the check for RX FIFO availability.
+	 */
+	if (WARN_ON_ONCE(!(i2c_dev->msg_buf_remaining)))
+		return -EINVAL;
+
+	if (i2c_dev->hw->has_mst_fifo) {
+		val = i2c_readl(i2c_dev, I2C_MST_FIFO_STATUS);
+		rx_fifo_avail = FIELD_GET(I2C_MST_FIFO_STATUS_RX, val);
+	} else {
+		val = i2c_readl(i2c_dev, I2C_FIFO_STATUS);
+		rx_fifo_avail = FIELD_GET(I2C_FIFO_STATUS_RX, val);
+	}
+
+	/* Rounds down to not include partial word at the end of buf */
+	words_to_transfer = buf_remaining / BYTES_PER_FIFO_WORD;
+	if (words_to_transfer > rx_fifo_avail)
+		words_to_transfer = rx_fifo_avail;
+
+	i2c_readsl(i2c_dev, buf, I2C_RX_FIFO, words_to_transfer);
+
+	buf += words_to_transfer * BYTES_PER_FIFO_WORD;
+	buf_remaining -= words_to_transfer * BYTES_PER_FIFO_WORD;
+	rx_fifo_avail -= words_to_transfer;
+
+	/*
+	 * If there is a partial word at the end of buf, handle it manually to
+	 * prevent overwriting past the end of buf
+	 */
+	if (rx_fifo_avail > 0 && buf_remaining > 0) {
+		/*
+		 * buf_remaining > 3 check not needed as rx_fifo_avail == 0
+		 * when (words_to_transfer was > rx_fifo_avail) earlier
+		 * in this function.
+		 */
+		val = i2c_readl(i2c_dev, I2C_RX_FIFO);
+		val = cpu_to_le32(val);
+		memcpy(buf, &val, buf_remaining);
+		buf_remaining = 0;
+		rx_fifo_avail--;
+	}
+
+	/* RX FIFO must be drained, otherwise it's an Overflow case. */
+	if (WARN_ON_ONCE(rx_fifo_avail))
+		return -EINVAL;
+
+	i2c_dev->msg_buf_remaining = buf_remaining;
+	i2c_dev->msg_buf = buf;
+
+	return 0;
+}
+
+static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
+{
+	u32 val;
+	int tx_fifo_avail;
+	u8 *buf = i2c_dev->msg_buf;
+	size_t buf_remaining = i2c_dev->msg_buf_remaining;
+	int words_to_transfer;
+
+	if (i2c_dev->hw->has_mst_fifo) {
+		val = i2c_readl(i2c_dev, I2C_MST_FIFO_STATUS);
+		tx_fifo_avail = FIELD_GET(I2C_MST_FIFO_STATUS_TX, val);
+	} else {
+		val = i2c_readl(i2c_dev, I2C_FIFO_STATUS);
+		tx_fifo_avail = FIELD_GET(I2C_FIFO_STATUS_TX, val);
+	}
+
+	/* Rounds down to not include partial word at the end of buf */
+	words_to_transfer = buf_remaining / BYTES_PER_FIFO_WORD;
+
+	/* It's very common to have < 4 bytes, so optimize that case. */
+	if (words_to_transfer) {
+		if (words_to_transfer > tx_fifo_avail)
+			words_to_transfer = tx_fifo_avail;
+
+		/*
+		 * Update state before writing to FIFO.  If this casues us
+		 * to finish writing all bytes (AKA buf_remaining goes to 0) we
+		 * have a potential for an interrupt (PACKET_XFER_COMPLETE is
+		 * not maskable).  We need to make sure that the isr sees
+		 * buf_remaining as 0 and doesn't call us back re-entrantly.
+		 */
+		buf_remaining -= words_to_transfer * BYTES_PER_FIFO_WORD;
+		tx_fifo_avail -= words_to_transfer;
+		i2c_dev->msg_buf_remaining = buf_remaining;
+		i2c_dev->msg_buf = buf +
+			words_to_transfer * BYTES_PER_FIFO_WORD;
+		barrier();
+
+		i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
+
+		buf += words_to_transfer * BYTES_PER_FIFO_WORD;
+	}
+
+	/*
+	 * If there is a partial word at the end of buf, handle it manually to
+	 * prevent reading past the end of buf, which could cross a page
+	 * boundary and fault.
+	 */
+	if (tx_fifo_avail > 0 && buf_remaining > 0) {
+		/*
+		 * buf_remaining > 3 check not needed as tx_fifo_avail == 0
+		 * when (words_to_transfer was > tx_fifo_avail) earlier
+		 * in this function for non-zero words_to_transfer.
+		 */
+		memcpy(&val, buf, buf_remaining);
+		val = le32_to_cpu(val);
+
+		/* Again update before writing to FIFO to make sure isr sees. */
+		i2c_dev->msg_buf_remaining = 0;
+		i2c_dev->msg_buf = NULL;
+		barrier();
+
+		i2c_writel(i2c_dev, val, I2C_TX_FIFO);
+	}
+
+	return 0;
+}
+
 static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
 {
 	u32 status;
@@ -1418,27 +1374,6 @@ static u32 tegra_i2c_func(struct i2c_adapter *adap)
 	return ret;
 }
 
-static void tegra_i2c_parse_dt(struct tegra_i2c_dev *i2c_dev)
-{
-	struct device_node *np = i2c_dev->dev->of_node;
-	int ret;
-	bool multi_mode;
-
-	ret = of_property_read_u32(np, "clock-frequency",
-				   &i2c_dev->bus_clk_rate);
-	if (ret)
-		i2c_dev->bus_clk_rate = I2C_MAX_STANDARD_MODE_FREQ; /* default clock rate */
-
-	multi_mode = of_property_read_bool(np, "multi-master");
-	i2c_dev->is_multimaster_mode = multi_mode;
-
-	if (of_device_is_compatible(np, "nvidia,tegra20-i2c-dvc"))
-		i2c_dev->is_dvc = true;
-
-	if (of_device_is_compatible(np, "nvidia,tegra210-i2c-vi"))
-		i2c_dev->is_vi = true;
-}
-
 static const struct i2c_algorithm tegra_i2c_algo = {
 	.master_xfer		= tegra_i2c_xfer,
 	.master_xfer_atomic	= tegra_i2c_xfer_atomic,
@@ -1644,6 +1579,27 @@ static const struct of_device_id tegra_i2c_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, tegra_i2c_of_match);
 
+static void tegra_i2c_parse_dt(struct tegra_i2c_dev *i2c_dev)
+{
+	struct device_node *np = i2c_dev->dev->of_node;
+	int ret;
+	bool multi_mode;
+
+	ret = of_property_read_u32(np, "clock-frequency",
+				   &i2c_dev->bus_clk_rate);
+	if (ret)
+		i2c_dev->bus_clk_rate = I2C_MAX_STANDARD_MODE_FREQ; /* default clock rate */
+
+	multi_mode = of_property_read_bool(np, "multi-master");
+	i2c_dev->is_multimaster_mode = multi_mode;
+
+	if (of_device_is_compatible(np, "nvidia,tegra20-i2c-dvc"))
+		i2c_dev->is_dvc = true;
+
+	if (of_device_is_compatible(np, "nvidia,tegra210-i2c-vi"))
+		i2c_dev->is_vi = true;
+}
+
 static int tegra_i2c_init_clocks(struct tegra_i2c_dev *i2c_dev)
 {
 	unsigned int i;
@@ -1818,6 +1774,48 @@ static int tegra_i2c_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static int __maybe_unused tegra_i2c_runtime_resume(struct device *dev)
+{
+	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
+	int ret;
+
+	ret = pinctrl_pm_select_default_state(i2c_dev->dev);
+	if (ret)
+		return ret;
+
+	ret = clk_bulk_enable(i2c_dev->nclocks, i2c_dev->clocks);
+	if (ret)
+		return ret;
+
+	/*
+	 * VI I2C device is attached to VE power domain which goes through
+	 * power ON/OFF during PM runtime resume/suspend. So, controller
+	 * should go through reset and need to re-initialize after power
+	 * domain ON.
+	 */
+	if (i2c_dev->is_vi) {
+		ret = tegra_i2c_init(i2c_dev);
+		if (ret)
+			goto disable_clocks;
+	}
+
+	return 0;
+
+disable_clocks:
+	clk_bulk_disable(i2c_dev->nclocks, i2c_dev->clocks);
+
+	return ret;
+}
+
+static int __maybe_unused tegra_i2c_runtime_suspend(struct device *dev)
+{
+	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
+
+	clk_bulk_disable(i2c_dev->nclocks, i2c_dev->clocks);
+
+	return pinctrl_pm_select_idle_state(i2c_dev->dev);
+}
+
 static int __maybe_unused tegra_i2c_suspend(struct device *dev)
 {
 	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 16/34] i2c: tegra: Clean up variable types
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (14 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 15/34] i2c: tegra: Reorder location of functions in the code Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 12:39   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 17/34] i2c: tegra: Remove outdated barrier() Dmitry Osipenko
                   ` (19 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

Don't use signed types for unsigned values and use consistent types
for sibling variables.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 38 +++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 5a0bb5b3876c..71e82a68c942 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -206,20 +206,20 @@ struct tegra_i2c_hw_feature {
 	bool has_continue_xfer_support;
 	bool has_per_pkt_xfer_complete_irq;
 	bool has_config_load_reg;
-	int clk_divisor_hs_mode;
-	int clk_divisor_std_mode;
-	int clk_divisor_fast_mode;
-	u16 clk_divisor_fast_plus_mode;
+	u32 clk_divisor_hs_mode;
+	u32 clk_divisor_std_mode;
+	u32 clk_divisor_fast_mode;
+	u32 clk_divisor_fast_plus_mode;
 	bool has_multi_master_mode;
 	bool has_slcg_override_reg;
 	bool has_mst_fifo;
 	const struct i2c_adapter_quirks *quirks;
 	bool supports_bus_clear;
 	bool has_apb_dma;
-	u8 tlow_std_mode;
-	u8 thigh_std_mode;
-	u8 tlow_fast_fastplus_mode;
-	u8 thigh_fast_fastplus_mode;
+	u32 tlow_std_mode;
+	u32 thigh_std_mode;
+	u32 tlow_fast_fastplus_mode;
+	u32 thigh_fast_fastplus_mode;
 	u32 setup_hold_time_std_mode;
 	u32 setup_hold_time_fast_fast_plus_mode;
 	u32 setup_hold_time_hs_mode;
@@ -267,15 +267,15 @@ struct tegra_i2c_dev {
 	struct reset_control *rst;
 	void __iomem *base;
 	phys_addr_t base_phys;
-	int cont_id;
-	int irq;
-	int is_dvc;
+	unsigned int cont_id;
+	unsigned int irq;
+	bool is_dvc;
 	bool is_vi;
 	struct completion msg_complete;
 	int msg_err;
 	u8 *msg_buf;
 	size_t msg_buf_remaining;
-	int msg_read;
+	bool msg_read;
 	u32 bus_clk_rate;
 	bool is_multimaster_mode;
 	struct dma_chan *tx_dma_chan;
@@ -329,13 +329,13 @@ static u32 i2c_readl(struct tegra_i2c_dev *i2c_dev, unsigned long reg)
 }
 
 static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, void *data,
-			unsigned long reg, int len)
+			unsigned long reg, unsigned int len)
 {
 	writesl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len);
 }
 
 static void i2c_readsl(struct tegra_i2c_dev *i2c_dev, void *data,
-		       unsigned long reg, int len)
+		       unsigned long reg, unsigned int len)
 {
 	readsl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len);
 }
@@ -712,10 +712,10 @@ static int tegra_i2c_disable_packet_mode(struct tegra_i2c_dev *i2c_dev)
 static int tegra_i2c_empty_rx_fifo(struct tegra_i2c_dev *i2c_dev)
 {
 	u32 val;
-	int rx_fifo_avail;
+	unsigned int rx_fifo_avail;
 	u8 *buf = i2c_dev->msg_buf;
 	size_t buf_remaining = i2c_dev->msg_buf_remaining;
-	int words_to_transfer;
+	unsigned int words_to_transfer;
 
 	/*
 	 * Catch overflow due to message fully sent
@@ -773,10 +773,10 @@ static int tegra_i2c_empty_rx_fifo(struct tegra_i2c_dev *i2c_dev)
 static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
 {
 	u32 val;
-	int tx_fifo_avail;
+	unsigned int tx_fifo_avail;
 	u8 *buf = i2c_dev->msg_buf;
 	size_t buf_remaining = i2c_dev->msg_buf_remaining;
-	int words_to_transfer;
+	unsigned int words_to_transfer;
 
 	if (i2c_dev->hw->has_mst_fifo) {
 		val = i2c_readl(i2c_dev, I2C_MST_FIFO_STATUS);
@@ -1134,7 +1134,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 	i2c_dev->msg_buf = msg->buf;
 	i2c_dev->msg_buf_remaining = msg->len;
 	i2c_dev->msg_err = I2C_ERR_NONE;
-	i2c_dev->msg_read = (msg->flags & I2C_M_RD);
+	i2c_dev->msg_read = !!(msg->flags & I2C_M_RD);
 	reinit_completion(&i2c_dev->msg_complete);
 
 	if (i2c_dev->msg_read)
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 17/34] i2c: tegra: Remove outdated barrier()
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (15 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 16/34] i2c: tegra: Clean up variable types Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 12:39   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 18/34] i2c: tegra: Remove likely/unlikely from the code Dmitry Osipenko
                   ` (18 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

The barrier() was intended to reduce possibility of racing with the
interrupt handler, but driver's code evolved significantly and today's
driver enables interrupt only when it waits for completion notification.
Hence barrier() has no good use anymore, let's remove it.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 71e82a68c942..ab83d1de6c94 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -795,18 +795,17 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
 			words_to_transfer = tx_fifo_avail;
 
 		/*
-		 * Update state before writing to FIFO.  If this casues us
-		 * to finish writing all bytes (AKA buf_remaining goes to 0) we
-		 * have a potential for an interrupt (PACKET_XFER_COMPLETE is
-		 * not maskable).  We need to make sure that the isr sees
-		 * buf_remaining as 0 and doesn't call us back re-entrantly.
+		 * Update state before writing to FIFO.  Note that this may
+		 * cause us to finish writing all bytes (AKA buf_remaining
+		 * goes to 0), hence we have a potential for an interrupt
+		 * (PACKET_XFER_COMPLETE is not maskable), but GIC interrupt
+		 * is disabled at this point.
 		 */
 		buf_remaining -= words_to_transfer * BYTES_PER_FIFO_WORD;
 		tx_fifo_avail -= words_to_transfer;
 		i2c_dev->msg_buf_remaining = buf_remaining;
 		i2c_dev->msg_buf = buf +
 			words_to_transfer * BYTES_PER_FIFO_WORD;
-		barrier();
 
 		i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
 
@@ -827,10 +826,8 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
 		memcpy(&val, buf, buf_remaining);
 		val = le32_to_cpu(val);
 
-		/* Again update before writing to FIFO to make sure isr sees. */
 		i2c_dev->msg_buf_remaining = 0;
 		i2c_dev->msg_buf = NULL;
-		barrier();
 
 		i2c_writel(i2c_dev, val, I2C_TX_FIFO);
 	}
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 18/34] i2c: tegra: Remove likely/unlikely from the code
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (16 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 17/34] i2c: tegra: Remove outdated barrier() Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 12:41   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 19/34] i2c: tegra: Remove redundant check in tegra_i2c_issue_bus_clear() Dmitry Osipenko
                   ` (17 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

The likely/unlikely annotations should be used only in a hot paths of
performance-critical code. The I2C driver doesn't have such paths, and
thus, there is no justification for usage of likely/unlikely annotations
in the code. Hence remove them.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index ab83d1de6c94..fd0d51ec447f 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -852,7 +852,7 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
 		goto err;
 	}
 
-	if (unlikely(status & status_err)) {
+	if (status & status_err) {
 		tegra_i2c_disable_packet_mode(i2c_dev);
 		if (status & I2C_INT_NO_ACK)
 			i2c_dev->msg_err |= I2C_ERR_NO_ACK;
@@ -1294,7 +1294,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 		i2c_dev->msg_err);
 
 	i2c_dev->is_curr_dma_xfer = false;
-	if (likely(i2c_dev->msg_err == I2C_ERR_NONE))
+	if (i2c_dev->msg_err == I2C_ERR_NONE)
 		return 0;
 
 	tegra_i2c_init(i2c_dev);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 19/34] i2c: tegra: Remove redundant check in tegra_i2c_issue_bus_clear()
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (17 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 18/34] i2c: tegra: Remove likely/unlikely from the code Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 12:42   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 20/34] i2c: tegra: Remove "dma" variable from tegra_i2c_xfer_msg() Dmitry Osipenko
                   ` (16 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

The tegra_i2c_wait_for_config_load() checks for 'has_config_load_reg' by
itself, hence there is no need to duplicate the check.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index fd0d51ec447f..18968302457f 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -1082,11 +1082,10 @@ static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap)
 	reg = FIELD_PREP(I2C_BC_SCLK_THRESHOLD, 9) | I2C_BC_STOP_COND |
 	      I2C_BC_TERMINATE;
 	i2c_writel(i2c_dev, reg, I2C_BUS_CLEAR_CNFG);
-	if (i2c_dev->hw->has_config_load_reg) {
-		err = tegra_i2c_wait_for_config_load(i2c_dev);
-		if (err)
-			return err;
-	}
+
+	err = tegra_i2c_wait_for_config_load(i2c_dev);
+	if (err)
+		return err;
 
 	reg |= I2C_BC_ENABLE;
 	i2c_writel(i2c_dev, reg, I2C_BUS_CLEAR_CNFG);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 20/34] i2c: tegra: Remove "dma" variable from tegra_i2c_xfer_msg()
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (18 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 19/34] i2c: tegra: Remove redundant check in tegra_i2c_issue_bus_clear() Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 11:44   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 21/34] i2c: tegra: Don't fall back to PIO mode if DMA configuration fails Dmitry Osipenko
                   ` (15 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

The "dma" variable of tegra_i2c_xfer_msg() function doesn't bring much in
regards to readability and generation of the code.

Besides readability, it's also not very nice that the is_curr_dma_xfer
is initialized in tegra_i2c_xfer_msg() and then could be overridden by
tegra_i2c_config_fifo_trig(). In a result, the "dma" variable creates
slight confusion since it's not instantly obvious why it's set after
tegra_i2c_config_fifo_trig().

Hence should be better to have the variable removed. This makes code
more consistent.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 18968302457f..76d3a05b10fc 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -1120,7 +1120,6 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 	size_t xfer_size;
 	u32 *buffer = NULL;
 	int err = 0;
-	bool dma;
 	u16 xfer_time = 100;
 
 	err = tegra_i2c_flush_fifos(i2c_dev);
@@ -1143,7 +1142,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 				    i2c_dev->dma_buf &&
 				    !i2c_dev->is_curr_atomic_xfer;
 	tegra_i2c_config_fifo_trig(i2c_dev, xfer_size);
-	dma = i2c_dev->is_curr_dma_xfer;
+
 	/*
 	 * Transfer time in mSec = Total bits / transfer rate
 	 * Total bits = 9 bits per byte (including ACK bit) + Start & stop bits
@@ -1153,7 +1152,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 
 	int_mask = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST;
 	tegra_i2c_unmask_irq(i2c_dev, int_mask);
-	if (dma) {
+	if (i2c_dev->is_curr_dma_xfer) {
 		if (i2c_dev->msg_read) {
 			dma_sync_single_for_device(i2c_dev->dev,
 						   i2c_dev->dma_phys,
@@ -1181,13 +1180,13 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 				   PACKET_HEADER0_PROTOCOL_I2C) |
 			FIELD_PREP(PACKET_HEADER0_CONT_ID, i2c_dev->cont_id) |
 			FIELD_PREP(PACKET_HEADER0_PACKET_ID, 1);
-	if (dma && !i2c_dev->msg_read)
+	if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
 		*buffer++ = packet_header;
 	else
 		i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
 
 	packet_header = msg->len - 1;
-	if (dma && !i2c_dev->msg_read)
+	if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
 		*buffer++ = packet_header;
 	else
 		i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
@@ -1207,13 +1206,13 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 		packet_header |= I2C_HEADER_CONT_ON_NAK;
 	if (msg->flags & I2C_M_RD)
 		packet_header |= I2C_HEADER_READ;
-	if (dma && !i2c_dev->msg_read)
+	if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
 		*buffer++ = packet_header;
 	else
 		i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
 
 	if (!i2c_dev->msg_read) {
-		if (dma) {
+		if (i2c_dev->is_curr_dma_xfer) {
 			memcpy(buffer, msg->buf, msg->len);
 			dma_sync_single_for_device(i2c_dev->dev,
 						   i2c_dev->dma_phys,
@@ -1233,7 +1232,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 
 	if (i2c_dev->hw->has_per_pkt_xfer_complete_irq)
 		int_mask |= I2C_INT_PACKET_XFER_COMPLETE;
-	if (!dma) {
+	if (!i2c_dev->is_curr_dma_xfer) {
 		if (msg->flags & I2C_M_RD)
 			int_mask |= I2C_INT_RX_FIFO_DATA_REQ;
 		else if (i2c_dev->msg_buf_remaining)
@@ -1244,7 +1243,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 	dev_dbg(i2c_dev->dev, "unmasked irq: %02x\n",
 		i2c_readl(i2c_dev, I2C_INT_MASK));
 
-	if (dma) {
+	if (i2c_dev->is_curr_dma_xfer) {
 		time_left = tegra_i2c_wait_completion_timeout(
 				i2c_dev, &i2c_dev->dma_complete, xfer_time);
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 21/34] i2c: tegra: Don't fall back to PIO mode if DMA configuration fails
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (19 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 20/34] i2c: tegra: Remove "dma" variable from tegra_i2c_xfer_msg() Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 11:47   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 22/34] i2c: tegra: Rename wait/poll functions Dmitry Osipenko
                   ` (14 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

The DMA code path has been tested well enough and the DMA configuration
performed by tegra_i2c_config_fifo_trig() shouldn't ever fail in practice.
Hence let's remove the obscure transfer-mode switching in order to have a
cleaner and simpler code. Now I2C transfer will be failed if DMA
configuration fails.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 76d3a05b10fc..574b59a8b2a2 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -940,8 +940,7 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static void tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev,
-				       size_t len)
+static int tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev, size_t len)
 {
 	u32 val, reg;
 	u8 dma_burst;
@@ -992,12 +991,10 @@ static void tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev,
 		if (ret < 0) {
 			dev_err(i2c_dev->dev, "DMA slave config failed: %d\n",
 				ret);
-			dev_err(i2c_dev->dev, "falling back to PIO\n");
-			tegra_i2c_release_dma(i2c_dev);
-			i2c_dev->is_curr_dma_xfer = false;
-		} else {
-			goto out;
+			return ret;
 		}
+
+		goto out;
 	}
 
 	if (i2c_dev->hw->has_mst_fifo)
@@ -1008,6 +1005,8 @@ static void tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev,
 		      I2C_FIFO_CONTROL_RX_TRIG(1);
 out:
 	i2c_writel(i2c_dev, val, reg);
+
+	return 0;
 }
 
 static unsigned long
@@ -1141,7 +1140,10 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 	i2c_dev->is_curr_dma_xfer = (xfer_size > I2C_PIO_MODE_PREFERRED_LEN) &&
 				    i2c_dev->dma_buf &&
 				    !i2c_dev->is_curr_atomic_xfer;
-	tegra_i2c_config_fifo_trig(i2c_dev, xfer_size);
+
+	err = tegra_i2c_config_fifo_trig(i2c_dev, xfer_size);
+	if (err)
+		return err;
 
 	/*
 	 * Transfer time in mSec = Total bits / transfer rate
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 22/34] i2c: tegra: Rename wait/poll functions
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (20 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 21/34] i2c: tegra: Don't fall back to PIO mode if DMA configuration fails Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 11:48   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 23/34] i2c: tegra: Factor out error recovery from tegra_i2c_xfer_msg() Dmitry Osipenko
                   ` (13 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

Drop '_timeout' postfix from the wait/poll completion function names in
order to make the names shorter, making code cleaner a tad.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 32 ++++++++++++++------------------
 1 file changed, 14 insertions(+), 18 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 574b59a8b2a2..102d26c01dff 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -1009,10 +1009,9 @@ static int tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev, size_t len)
 	return 0;
 }
 
-static unsigned long
-tegra_i2c_poll_completion_timeout(struct tegra_i2c_dev *i2c_dev,
-				  struct completion *complete,
-				  unsigned int timeout_ms)
+static unsigned long tegra_i2c_poll_completion(struct tegra_i2c_dev *i2c_dev,
+					       struct completion *complete,
+					       unsigned int timeout_ms)
 {
 	ktime_t ktime = ktime_get();
 	ktime_t ktimeout = ktime_add_ms(ktime, timeout_ms);
@@ -1036,16 +1035,14 @@ tegra_i2c_poll_completion_timeout(struct tegra_i2c_dev *i2c_dev,
 	return 0;
 }
 
-static unsigned long
-tegra_i2c_wait_completion_timeout(struct tegra_i2c_dev *i2c_dev,
-				  struct completion *complete,
-				  unsigned int timeout_ms)
+static unsigned long tegra_i2c_wait_completion(struct tegra_i2c_dev *i2c_dev,
+					       struct completion *complete,
+					       unsigned int timeout_ms)
 {
 	unsigned long ret;
 
 	if (i2c_dev->is_curr_atomic_xfer) {
-		ret = tegra_i2c_poll_completion_timeout(i2c_dev, complete,
-							timeout_ms);
+		ret = tegra_i2c_poll_completion(i2c_dev, complete, timeout_ms);
 	} else {
 		enable_irq(i2c_dev->irq);
 		ret = wait_for_completion_timeout(complete,
@@ -1063,8 +1060,7 @@ tegra_i2c_wait_completion_timeout(struct tegra_i2c_dev *i2c_dev,
 		 * needs to be checked after timeout.
 		 */
 		if (ret == 0)
-			ret = tegra_i2c_poll_completion_timeout(i2c_dev,
-								complete, 0);
+			ret = tegra_i2c_poll_completion(i2c_dev, complete, 0);
 	}
 
 	return ret;
@@ -1090,8 +1086,7 @@ static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap)
 	i2c_writel(i2c_dev, reg, I2C_BUS_CLEAR_CNFG);
 	tegra_i2c_unmask_irq(i2c_dev, I2C_INT_BUS_CLR_DONE);
 
-	time_left = tegra_i2c_wait_completion_timeout(
-			i2c_dev, &i2c_dev->msg_complete, 50);
+	time_left = tegra_i2c_wait_completion(i2c_dev, &i2c_dev->msg_complete, 50);
 	tegra_i2c_mask_irq(i2c_dev, I2C_INT_BUS_CLR_DONE);
 
 	if (time_left == 0) {
@@ -1246,8 +1241,9 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 		i2c_readl(i2c_dev, I2C_INT_MASK));
 
 	if (i2c_dev->is_curr_dma_xfer) {
-		time_left = tegra_i2c_wait_completion_timeout(
-				i2c_dev, &i2c_dev->dma_complete, xfer_time);
+		time_left = tegra_i2c_wait_completion(i2c_dev,
+						      &i2c_dev->dma_complete,
+						      xfer_time);
 
 		/*
 		 * Synchronize DMA first, since dmaengine_terminate_sync()
@@ -1278,8 +1274,8 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 		}
 	}
 
-	time_left = tegra_i2c_wait_completion_timeout(
-			i2c_dev, &i2c_dev->msg_complete, xfer_time);
+	time_left = tegra_i2c_wait_completion(i2c_dev, &i2c_dev->msg_complete,
+					      xfer_time);
 
 	tegra_i2c_mask_irq(i2c_dev, int_mask);
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 23/34] i2c: tegra: Factor out error recovery from tegra_i2c_xfer_msg()
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (21 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 22/34] i2c: tegra: Rename wait/poll functions Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 11:49   ` Thierry Reding
  2020-09-21 10:20   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 24/34] i2c: tegra: Factor out packet header setup " Dmitry Osipenko
                   ` (12 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

Factor out error recovery code from tegra_i2c_xfer_msg() in order to
make this function easier to read and follow.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 46 ++++++++++++++++++++++------------
 1 file changed, 30 insertions(+), 16 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 102d26c01dff..1ec2490d06ac 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -1104,6 +1104,32 @@ static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap)
 	return -EAGAIN;
 }
 
+static int tegra_i2c_error_recover(struct tegra_i2c_dev *i2c_dev,
+				   struct i2c_msg *msg)
+{
+	if (i2c_dev->msg_err == I2C_ERR_NONE)
+		return 0;
+
+	tegra_i2c_init(i2c_dev);
+
+	/* start recovery upon arbitration loss in single master mode */
+	if (i2c_dev->msg_err == I2C_ERR_ARBITRATION_LOST) {
+		if (!i2c_dev->is_multimaster_mode)
+			return i2c_recover_bus(&i2c_dev->adapter);
+
+		return -EAGAIN;
+	}
+
+	if (i2c_dev->msg_err == I2C_ERR_NO_ACK) {
+		if (msg->flags & I2C_M_IGNORE_NAK)
+			return 0;
+
+		return -EREMOTEIO;
+	}
+
+	return -EIO;
+}
+
 static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 			      struct i2c_msg *msg,
 			      enum msg_end_type end_state)
@@ -1290,24 +1316,12 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 		i2c_dev->msg_err);
 
 	i2c_dev->is_curr_dma_xfer = false;
-	if (i2c_dev->msg_err == I2C_ERR_NONE)
-		return 0;
 
-	tegra_i2c_init(i2c_dev);
-	/* start recovery upon arbitration loss in single master mode */
-	if (i2c_dev->msg_err == I2C_ERR_ARBITRATION_LOST) {
-		if (!i2c_dev->is_multimaster_mode)
-			return i2c_recover_bus(&i2c_dev->adapter);
-		return -EAGAIN;
-	}
-
-	if (i2c_dev->msg_err == I2C_ERR_NO_ACK) {
-		if (msg->flags & I2C_M_IGNORE_NAK)
-			return 0;
-		return -EREMOTEIO;
-	}
+	err = tegra_i2c_error_recover(i2c_dev, msg);
+	if (err)
+		return err;
 
-	return -EIO;
+	return 0;
 }
 
 static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 24/34] i2c: tegra: Factor out packet header setup from tegra_i2c_xfer_msg()
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (22 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 23/34] i2c: tegra: Factor out error recovery from tegra_i2c_xfer_msg() Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 11:51   ` Thierry Reding
  2020-09-21 10:20   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 25/34] i2c: tegra: Factor out register polling into separate function Dmitry Osipenko
                   ` (11 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

The code related to packet header setting up is a bit messy and makes
tegra_i2c_xfer_msg() more difficult to read than it could be. Let's
factor the packet header setup from tegra_i2c_xfer_msg() into separate
function in order to make code easier to read and follow.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 92 ++++++++++++++++++++--------------
 1 file changed, 53 insertions(+), 39 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 1ec2490d06ac..405b87e28a98 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -1104,6 +1104,57 @@ static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap)
 	return -EAGAIN;
 }
 
+static void tegra_i2c_push_packet_header(struct tegra_i2c_dev *i2c_dev,
+					 struct i2c_msg *msg,
+					 enum msg_end_type end_state)
+{
+	u32 *dma_buf = i2c_dev->dma_buf;
+	u32 packet_header;
+
+	packet_header = FIELD_PREP(PACKET_HEADER0_HEADER_SIZE, 0) |
+			FIELD_PREP(PACKET_HEADER0_PROTOCOL,
+				   PACKET_HEADER0_PROTOCOL_I2C) |
+			FIELD_PREP(PACKET_HEADER0_CONT_ID, i2c_dev->cont_id) |
+			FIELD_PREP(PACKET_HEADER0_PACKET_ID, 1);
+
+	if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
+		*dma_buf++ = packet_header;
+	else
+		i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
+
+	packet_header = msg->len - 1;
+
+	if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
+		*dma_buf++ = packet_header;
+	else
+		i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
+
+	packet_header = I2C_HEADER_IE_ENABLE;
+
+	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;
+		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)
+		packet_header |= I2C_HEADER_READ;
+
+	if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
+		*dma_buf++ = packet_header;
+	else
+		i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
+}
+
 static int tegra_i2c_error_recover(struct tegra_i2c_dev *i2c_dev,
 				   struct i2c_msg *msg)
 {
@@ -1134,11 +1185,9 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 			      struct i2c_msg *msg,
 			      enum msg_end_type end_state)
 {
-	u32 packet_header;
 	u32 int_mask;
 	unsigned long time_left;
 	size_t xfer_size;
-	u32 *buffer = NULL;
 	int err = 0;
 	u16 xfer_time = 100;
 
@@ -1194,49 +1243,14 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 						i2c_dev->dma_phys,
 						xfer_size,
 						DMA_TO_DEVICE);
-			buffer = i2c_dev->dma_buf;
 		}
 	}
 
-	packet_header = FIELD_PREP(PACKET_HEADER0_HEADER_SIZE, 0) |
-			FIELD_PREP(PACKET_HEADER0_PROTOCOL,
-				   PACKET_HEADER0_PROTOCOL_I2C) |
-			FIELD_PREP(PACKET_HEADER0_CONT_ID, i2c_dev->cont_id) |
-			FIELD_PREP(PACKET_HEADER0_PACKET_ID, 1);
-	if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
-		*buffer++ = packet_header;
-	else
-		i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
-
-	packet_header = msg->len - 1;
-	if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
-		*buffer++ = packet_header;
-	else
-		i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
-
-	packet_header = I2C_HEADER_IE_ENABLE;
-	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;
-		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)
-		packet_header |= I2C_HEADER_READ;
-	if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
-		*buffer++ = packet_header;
-	else
-		i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
+	tegra_i2c_push_packet_header(i2c_dev, msg, end_state);
 
 	if (!i2c_dev->msg_read) {
 		if (i2c_dev->is_curr_dma_xfer) {
-			memcpy(buffer, msg->buf, msg->len);
+			memcpy(i2c_dev->dma_buf, msg->buf, msg->len);
 			dma_sync_single_for_device(i2c_dev->dev,
 						   i2c_dev->dma_phys,
 						   xfer_size,
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 25/34] i2c: tegra: Factor out register polling into separate function
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (23 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 24/34] i2c: tegra: Factor out packet header setup " Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 11:58   ` Thierry Reding
  2020-09-21 10:20   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 26/34] i2c: tegra: Factor out hardware initialization " Dmitry Osipenko
                   ` (10 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

Factor out register polling into a separate function in order to remove
boilerplate code and make code cleaner.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 57 +++++++++++++++-------------------
 1 file changed, 25 insertions(+), 32 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 405b87e28a98..e071de9ce106 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -514,10 +514,24 @@ static void tegra_i2c_vi_init(struct tegra_i2c_dev *i2c_dev)
 	i2c_writel(i2c_dev, 0x0, I2C_TLOW_SEXT);
 }
 
+static int tegra_i2c_poll_register(struct tegra_i2c_dev *i2c_dev,
+				   u32 reg, u32 mask, u32 delay_us,
+				   u32 timeout_us)
+{
+	void __iomem *addr = i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg);
+	u32 val;
+
+	if (!i2c_dev->is_curr_atomic_xfer)
+		return readl_relaxed_poll_timeout(addr, val, !(val & mask),
+						  delay_us, timeout_us);
+
+	return readl_relaxed_poll_timeout_atomic(addr, val, !(val & mask),
+						 delay_us, timeout_us);
+}
+
 static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
 {
-	u32 mask, val, offset, reg_offset;
-	void __iomem *addr;
+	u32 mask, val, offset;
 	int err;
 
 	if (i2c_dev->hw->has_mst_fifo) {
@@ -534,16 +548,7 @@ static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
 	val |= mask;
 	i2c_writel(i2c_dev, val, offset);
 
-	reg_offset = tegra_i2c_reg_addr(i2c_dev, offset);
-	addr = i2c_dev->base + reg_offset;
-
-	if (i2c_dev->is_curr_atomic_xfer)
-		err = readl_relaxed_poll_timeout_atomic(addr, val, !(val & mask),
-							1000, 1000000);
-	else
-		err = readl_relaxed_poll_timeout(addr, val, !(val & mask),
-						 1000, 1000000);
-
+	err = tegra_i2c_poll_register(i2c_dev, offset, mask, 1000, 1000000);
 	if (err) {
 		dev_err(i2c_dev->dev, "failed to flush FIFO\n");
 		return err;
@@ -553,30 +558,18 @@ static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
 
 static int tegra_i2c_wait_for_config_load(struct tegra_i2c_dev *i2c_dev)
 {
-	unsigned long reg_offset;
-	void __iomem *addr;
-	u32 val;
 	int err;
 
-	if (i2c_dev->hw->has_config_load_reg) {
-		reg_offset = tegra_i2c_reg_addr(i2c_dev, I2C_CONFIG_LOAD);
-		addr = i2c_dev->base + reg_offset;
-		i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, I2C_CONFIG_LOAD);
+	if (!i2c_dev->hw->has_config_load_reg)
+		return 0;
 
-		if (i2c_dev->is_curr_atomic_xfer)
-			err = readl_relaxed_poll_timeout_atomic(
-						addr, val, val == 0, 1000,
-						I2C_CONFIG_LOAD_TIMEOUT);
-		else
-			err = readl_relaxed_poll_timeout(
-						addr, val, val == 0, 1000,
-						I2C_CONFIG_LOAD_TIMEOUT);
+	i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, I2C_CONFIG_LOAD);
 
-		if (err) {
-			dev_warn(i2c_dev->dev,
-				 "timeout waiting for config load\n");
-			return err;
-		}
+	err = tegra_i2c_poll_register(i2c_dev, I2C_CONFIG_LOAD, 0xffffffff,
+				      1000, I2C_CONFIG_LOAD_TIMEOUT);
+	if (err) {
+		dev_warn(i2c_dev->dev, "timeout waiting for config load\n");
+		return err;
 	}
 
 	return 0;
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 26/34] i2c: tegra: Factor out hardware initialization into separate function
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (24 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 25/34] i2c: tegra: Factor out register polling into separate function Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 12:06   ` Thierry Reding
  2020-09-21 10:20   ` Thierry Reding
  2020-09-08 22:39 ` [PATCH v7 27/34] i2c: tegra: Check errors for both positive and negative values Dmitry Osipenko
                   ` (9 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

Factor out hardware initialization into a separate function from the probe
function. The only place where runtime PM needs to be resumed during probe
is the place of hardware initialization, hence it makes sense to factor
out it in order to have a bit cleaner error handling in tegra_i2c_probe().

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 32 +++++++++++++++++++-------------
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index e071de9ce106..2f39366b6d55 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -1661,9 +1661,23 @@ static void tegra_i2c_release_clocks(struct tegra_i2c_dev *i2c_dev)
 	clk_bulk_unprepare(i2c_dev->nclocks, i2c_dev->clocks);
 }
 
+static int tegra_i2c_init_hardware(struct tegra_i2c_dev *i2c_dev)
+{
+	int ret;
+
+	ret = pm_runtime_get_sync(i2c_dev->dev);
+	if (ret < 0)
+		dev_err(i2c_dev->dev, "runtime resume failed: %d\n", ret);
+	else
+		ret = tegra_i2c_init(i2c_dev);
+
+	pm_runtime_put(i2c_dev->dev);
+
+	return ret;
+}
+
 static int tegra_i2c_probe(struct platform_device *pdev)
 {
-	struct device *dev = &pdev->dev;
 	struct tegra_i2c_dev *i2c_dev;
 	struct resource *res;
 	int ret;
@@ -1729,15 +1743,10 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 	if (!i2c_dev->is_vi)
 		pm_runtime_irq_safe(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
-	ret = pm_runtime_get_sync(i2c_dev->dev);
-	if (ret < 0) {
-		dev_err(dev, "runtime resume failed\n");
-		goto put_rpm;
-	}
 
-	ret = tegra_i2c_init(i2c_dev);
+	ret = tegra_i2c_init_hardware(i2c_dev);
 	if (ret)
-		goto put_rpm;
+		goto release_rpm;
 
 	i2c_set_adapdata(&i2c_dev->adapter, i2c_dev);
 	i2c_dev->adapter.dev.of_node = pdev->dev.of_node;
@@ -1758,14 +1767,11 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 
 	ret = i2c_add_numbered_adapter(&i2c_dev->adapter);
 	if (ret)
-		goto put_rpm;
-
-	pm_runtime_put(&pdev->dev);
+		goto release_rpm;
 
 	return 0;
 
-put_rpm:
-	pm_runtime_put_sync(&pdev->dev);
+release_rpm:
 	pm_runtime_disable(&pdev->dev);
 
 	tegra_i2c_release_dma(i2c_dev);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 27/34] i2c: tegra: Check errors for both positive and negative values
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (25 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 26/34] i2c: tegra: Factor out hardware initialization " Dmitry Osipenko
@ 2020-09-08 22:39 ` Dmitry Osipenko
  2020-09-17 12:09   ` Thierry Reding
  2020-09-21 10:20   ` Thierry Reding
  2020-09-08 22:40 ` [PATCH v7 28/34] i2c: tegra: Consolidate error handling in tegra_i2c_xfer_msg() Dmitry Osipenko
                   ` (8 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:39 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

The driver's code is inconsistent in regards to the error values checking.
The correct way should be to check both positive and negative values.
This patch cleans up the error-checks in the code. Note that the
pm_runtime_get_sync() could return positive value on success, hence only
relevant parts of the code are changed by this patch.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 2f39366b6d55..fe672cfebe12 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -981,7 +981,7 @@ static int tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev, size_t len)
 
 		slv_config.device_fc = true;
 		ret = dmaengine_slave_config(chan, &slv_config);
-		if (ret < 0) {
+		if (ret) {
 			dev_err(i2c_dev->dev, "DMA slave config failed: %d\n",
 				ret);
 			return ret;
@@ -1224,7 +1224,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 						   xfer_size,
 						   DMA_FROM_DEVICE);
 			err = tegra_i2c_dma_submit(i2c_dev, xfer_size);
-			if (err < 0) {
+			if (err) {
 				dev_err(i2c_dev->dev,
 					"starting RX DMA failed, err %d\n",
 					err);
@@ -1249,7 +1249,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 						   xfer_size,
 						   DMA_TO_DEVICE);
 			err = tegra_i2c_dma_submit(i2c_dev, xfer_size);
-			if (err < 0) {
+			if (err) {
 				dev_err(i2c_dev->dev,
 					"starting TX DMA failed, err %d\n",
 					err);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 28/34] i2c: tegra: Consolidate error handling in tegra_i2c_xfer_msg()
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (26 preceding siblings ...)
  2020-09-08 22:39 ` [PATCH v7 27/34] i2c: tegra: Check errors for both positive and negative values Dmitry Osipenko
@ 2020-09-08 22:40 ` Dmitry Osipenko
  2020-09-17 12:12   ` Thierry Reding
  2020-09-21 10:20   ` Thierry Reding
  2020-09-08 22:40 ` [PATCH v7 29/34] i2c: tegra: Improve formatting of variables Dmitry Osipenko
                   ` (7 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:40 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

Consolidate error handling in tegra_i2c_xfer_msg() into a common code
path in order to make code cleaner.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index fe672cfebe12..ac40c87f1c21 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -1293,8 +1293,8 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 
 		if (!time_left && !completion_done(&i2c_dev->dma_complete)) {
 			dev_err(i2c_dev->dev, "DMA transfer timeout\n");
-			tegra_i2c_init(i2c_dev);
-			return -ETIMEDOUT;
+			err = -ETIMEDOUT;
+			goto reset_hardware;
 		}
 
 		if (i2c_dev->msg_read && i2c_dev->msg_err == I2C_ERR_NONE) {
@@ -1314,8 +1314,8 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 
 	if (time_left == 0) {
 		dev_err(i2c_dev->dev, "i2c transfer timed out\n");
-		tegra_i2c_init(i2c_dev);
-		return -ETIMEDOUT;
+		err = -ETIMEDOUT;
+		goto reset_hardware;
 	}
 
 	dev_dbg(i2c_dev->dev, "transfer complete: %lu %d %d\n",
@@ -1329,6 +1329,11 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 		return err;
 
 	return 0;
+
+reset_hardware:
+	tegra_i2c_init(i2c_dev);
+
+	return err;
 }
 
 static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 29/34] i2c: tegra: Improve formatting of variables
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (27 preceding siblings ...)
  2020-09-08 22:40 ` [PATCH v7 28/34] i2c: tegra: Consolidate error handling in tegra_i2c_xfer_msg() Dmitry Osipenko
@ 2020-09-08 22:40 ` Dmitry Osipenko
  2020-09-17 12:16   ` Thierry Reding
  2020-09-21 10:20   ` Thierry Reding
  2020-09-08 22:40 ` [PATCH v7 30/34] i2c: tegra: Clean up variable names Dmitry Osipenko
                   ` (6 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:40 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

Reorder definition of variables in the code to have them sorted by length
and grouped logically, also replace "unsigned long" with "u32". Do this in
order to make code easier to read.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 97 ++++++++++++++++------------------
 1 file changed, 45 insertions(+), 52 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index ac40c87f1c21..2376f502d299 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -259,42 +259,48 @@ struct tegra_i2c_hw_feature {
  */
 struct tegra_i2c_dev {
 	struct device *dev;
-	const struct tegra_i2c_hw_feature *hw;
 	struct i2c_adapter adapter;
-	struct clk *div_clk;
-	struct clk_bulk_data *clocks;
-	unsigned int nclocks;
+
+	const struct tegra_i2c_hw_feature *hw;
 	struct reset_control *rst;
-	void __iomem *base;
-	phys_addr_t base_phys;
 	unsigned int cont_id;
 	unsigned int irq;
-	bool is_dvc;
-	bool is_vi;
+
+	phys_addr_t base_phys;
+	void __iomem *base;
+
+	struct clk_bulk_data *clocks;
+	unsigned int nclocks;
+
+	struct clk *div_clk;
+	u32 bus_clk_rate;
+
 	struct completion msg_complete;
+	size_t msg_buf_remaining;
 	int msg_err;
 	u8 *msg_buf;
-	size_t msg_buf_remaining;
-	bool msg_read;
-	u32 bus_clk_rate;
-	bool is_multimaster_mode;
+
+	struct completion dma_complete;
 	struct dma_chan *tx_dma_chan;
 	struct dma_chan *rx_dma_chan;
+	unsigned int dma_buf_size;
 	dma_addr_t dma_phys;
 	u32 *dma_buf;
-	unsigned int dma_buf_size;
-	bool is_curr_dma_xfer;
-	struct completion dma_complete;
+
+	bool is_multimaster_mode;
 	bool is_curr_atomic_xfer;
+	bool is_curr_dma_xfer;
+	bool msg_read;
+	bool is_dvc;
+	bool is_vi;
 };
 
-static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val,
-		       unsigned long reg)
+static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val, u32 reg)
 {
 	writel_relaxed(val, i2c_dev->base + reg);
 }
 
-static u32 dvc_readl(struct tegra_i2c_dev *i2c_dev, unsigned long reg)
+static u32 dvc_readl(struct tegra_i2c_dev *i2c_dev, u32 reg)
 {
 	return readl_relaxed(i2c_dev->base + reg);
 }
@@ -303,8 +309,7 @@ static u32 dvc_readl(struct tegra_i2c_dev *i2c_dev, unsigned long reg)
  * i2c_writel and i2c_readl will offset the register if necessary to talk
  * to the I2C block inside the DVC block
  */
-static unsigned long tegra_i2c_reg_addr(struct tegra_i2c_dev *i2c_dev,
-					unsigned long reg)
+static u32 tegra_i2c_reg_addr(struct tegra_i2c_dev *i2c_dev, u32 reg)
 {
 	if (i2c_dev->is_dvc)
 		reg += (reg >= I2C_TX_FIFO) ? 0x10 : 0x40;
@@ -313,8 +318,7 @@ static unsigned long tegra_i2c_reg_addr(struct tegra_i2c_dev *i2c_dev,
 	return reg;
 }
 
-static void i2c_writel(struct tegra_i2c_dev *i2c_dev, u32 val,
-		       unsigned long reg)
+static void i2c_writel(struct tegra_i2c_dev *i2c_dev, u32 val, u32 reg)
 {
 	writel_relaxed(val, i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
 
@@ -323,19 +327,19 @@ static void i2c_writel(struct tegra_i2c_dev *i2c_dev, u32 val,
 		readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
 }
 
-static u32 i2c_readl(struct tegra_i2c_dev *i2c_dev, unsigned long reg)
+static u32 i2c_readl(struct tegra_i2c_dev *i2c_dev, u32 reg)
 {
 	return readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
 }
 
 static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, void *data,
-			unsigned long reg, unsigned int len)
+			u32 reg, unsigned int len)
 {
 	writesl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len);
 }
 
 static void i2c_readsl(struct tegra_i2c_dev *i2c_dev, void *data,
-		       unsigned long reg, unsigned int len)
+		       u32 reg, unsigned int len)
 {
 	readsl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len);
 }
@@ -410,8 +414,8 @@ static void tegra_i2c_release_dma(struct tegra_i2c_dev *i2c_dev)
 static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev)
 {
 	struct dma_chan *chan;
-	u32 *dma_buf;
 	dma_addr_t dma_phys;
+	u32 *dma_buf;
 	int err;
 
 	if (!i2c_dev->hw->has_apb_dma || i2c_dev->is_vi)
@@ -577,12 +581,8 @@ static int tegra_i2c_wait_for_config_load(struct tegra_i2c_dev *i2c_dev)
 
 static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 {
-	u32 val;
+	u32 val, clk_divisor, clk_multiplier, tsu_thd, tlow, thigh, non_hs_mode;
 	int err;
-	u32 clk_divisor, clk_multiplier;
-	u32 non_hs_mode;
-	u32 tsu_thd;
-	u8 tlow, thigh;
 
 	/*
 	 * The reset shouldn't ever fail in practice. The failure will be a
@@ -704,11 +704,10 @@ static int tegra_i2c_disable_packet_mode(struct tegra_i2c_dev *i2c_dev)
 
 static int tegra_i2c_empty_rx_fifo(struct tegra_i2c_dev *i2c_dev)
 {
-	u32 val;
-	unsigned int rx_fifo_avail;
-	u8 *buf = i2c_dev->msg_buf;
 	size_t buf_remaining = i2c_dev->msg_buf_remaining;
-	unsigned int words_to_transfer;
+	unsigned int words_to_transfer, rx_fifo_avail;
+	u8 *buf = i2c_dev->msg_buf;
+	u32 val;
 
 	/*
 	 * Catch overflow due to message fully sent
@@ -765,11 +764,10 @@ static int tegra_i2c_empty_rx_fifo(struct tegra_i2c_dev *i2c_dev)
 
 static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
 {
-	u32 val;
-	unsigned int tx_fifo_avail;
-	u8 *buf = i2c_dev->msg_buf;
 	size_t buf_remaining = i2c_dev->msg_buf_remaining;
-	unsigned int words_to_transfer;
+	unsigned int words_to_transfer, tx_fifo_avail;
+	u8 *buf = i2c_dev->msg_buf;
+	u32 val;
 
 	if (i2c_dev->hw->has_mst_fifo) {
 		val = i2c_readl(i2c_dev, I2C_MST_FIFO_STATUS);
@@ -830,9 +828,9 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
 
 static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
 {
-	u32 status;
 	const u32 status_err = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST;
 	struct tegra_i2c_dev *i2c_dev = dev_id;
+	u32 status;
 
 	status = i2c_readl(i2c_dev, I2C_INT_STATUS);
 
@@ -935,12 +933,10 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
 
 static int tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev, size_t len)
 {
-	u32 val, reg;
-	u8 dma_burst;
 	struct dma_slave_config slv_config = {0};
+	u32 val, reg, dma_burst, reg_offset;
 	struct dma_chan *chan;
 	int ret;
-	unsigned long reg_offset;
 
 	if (i2c_dev->hw->has_mst_fifo)
 		reg = I2C_MST_FIFO_CONTROL;
@@ -1062,9 +1058,8 @@ static unsigned long tegra_i2c_wait_completion(struct tegra_i2c_dev *i2c_dev,
 static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap)
 {
 	struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
+	u32 reg, time_left;
 	int err;
-	unsigned long time_left;
-	u32 reg;
 
 	reinit_completion(&i2c_dev->msg_complete);
 	reg = FIELD_PREP(I2C_BC_SCLK_THRESHOLD, 9) | I2C_BC_STOP_COND |
@@ -1178,11 +1173,10 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 			      struct i2c_msg *msg,
 			      enum msg_end_type end_state)
 {
-	u32 int_mask;
-	unsigned long time_left;
+	unsigned long time_left, xfer_time = 100;
 	size_t xfer_size;
-	int err = 0;
-	u16 xfer_time = 100;
+	u32 int_mask;
+	int err;
 
 	err = tegra_i2c_flush_fifos(i2c_dev);
 	if (err)
@@ -1340,8 +1334,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
 			  int num)
 {
 	struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
-	int i;
-	int ret;
+	int i, ret;
 
 	ret = pm_runtime_get_sync(i2c_dev->dev);
 	if (ret < 0) {
@@ -1601,8 +1594,8 @@ MODULE_DEVICE_TABLE(of, tegra_i2c_of_match);
 static void tegra_i2c_parse_dt(struct tegra_i2c_dev *i2c_dev)
 {
 	struct device_node *np = i2c_dev->dev->of_node;
-	int ret;
 	bool multi_mode;
+	int ret;
 
 	ret = of_property_read_u32(np, "clock-frequency",
 				   &i2c_dev->bus_clk_rate);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 30/34] i2c: tegra: Clean up variable names
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (28 preceding siblings ...)
  2020-09-08 22:40 ` [PATCH v7 29/34] i2c: tegra: Improve formatting of variables Dmitry Osipenko
@ 2020-09-08 22:40 ` Dmitry Osipenko
  2020-09-17 12:21   ` Thierry Reding
  2020-09-21 10:20   ` Thierry Reding
  2020-09-08 22:40 ` [PATCH v7 31/34] i2c: tegra: Clean up printk messages Dmitry Osipenko
                   ` (5 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:40 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

Rename "ret" variables to "err" in order to make code a bit more
expressive, emphasizing that the returned value is an error code.
Same vice versa, where appropriate.

Rename variable "reg" to "val" in order to better reflect the actual
usage of the variable in the code and to make naming consistent with
the rest of the code.

Use briefer names for a few members of the tegra_i2c_dev structure in
order to improve readability of the code.

All dev/&pdev->dev are replaced with i2c_dev->dev in order to have uniform
code style across the driver.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 173 ++++++++++++++++-----------------
 1 file changed, 86 insertions(+), 87 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 2376f502d299..fbdb206f0161 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -247,15 +247,15 @@ struct tegra_i2c_hw_feature {
  * @msg_buf_remaining: size of unsent data in the message buffer
  * @msg_read: identifies read transfers
  * @bus_clk_rate: current I2C bus clock rate
- * @is_multimaster_mode: track if I2C controller is in multi-master mode
+ * @multimaster_mode: indicates that I2C controller is in multi-master mode
  * @tx_dma_chan: DMA transmit channel
  * @rx_dma_chan: DMA receive channel
  * @dma_phys: handle to DMA resources
  * @dma_buf: pointer to allocated DMA buffer
  * @dma_buf_size: DMA buffer size
- * @is_curr_dma_xfer: indicates active DMA transfer
+ * @dma_mode: indicates active DMA transfer
  * @dma_complete: DMA completion notifier
- * @is_curr_atomic_xfer: indicates active atomic transfer
+ * @atomic_mode: indicates active atomic transfer
  */
 struct tegra_i2c_dev {
 	struct device *dev;
@@ -287,9 +287,9 @@ struct tegra_i2c_dev {
 	dma_addr_t dma_phys;
 	u32 *dma_buf;
 
-	bool is_multimaster_mode;
-	bool is_curr_atomic_xfer;
-	bool is_curr_dma_xfer;
+	bool multimaster_mode;
+	bool atomic_mode;
+	bool dma_mode;
 	bool msg_read;
 	bool is_dvc;
 	bool is_vi;
@@ -525,7 +525,7 @@ static int tegra_i2c_poll_register(struct tegra_i2c_dev *i2c_dev,
 	void __iomem *addr = i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg);
 	u32 val;
 
-	if (!i2c_dev->is_curr_atomic_xfer)
+	if (!i2c_dev->atomic_mode)
 		return readl_relaxed_poll_timeout(addr, val, !(val & mask),
 						  delay_us, timeout_us);
 
@@ -673,7 +673,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 	if (err)
 		return err;
 
-	if (i2c_dev->is_multimaster_mode && i2c_dev->hw->has_slcg_override_reg)
+	if (i2c_dev->multimaster_mode && i2c_dev->hw->has_slcg_override_reg)
 		i2c_writel(i2c_dev, I2C_MST_CORE_CLKEN_OVR, I2C_CLKEN_OVERRIDE);
 
 	err = tegra_i2c_wait_for_config_load(i2c_dev);
@@ -859,7 +859,7 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
 	if (i2c_dev->hw->supports_bus_clear && (status & I2C_INT_BUS_CLR_DONE))
 		goto err;
 
-	if (!i2c_dev->is_curr_dma_xfer) {
+	if (!i2c_dev->dma_mode) {
 		if (i2c_dev->msg_read && (status & I2C_INT_RX_FIFO_DATA_REQ)) {
 			if (tegra_i2c_empty_rx_fifo(i2c_dev)) {
 				/*
@@ -893,7 +893,7 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
 	 * so forcing msg_buf_remaining to 0 in DMA mode.
 	 */
 	if (status & I2C_INT_PACKET_XFER_COMPLETE) {
-		if (i2c_dev->is_curr_dma_xfer)
+		if (i2c_dev->dma_mode)
 			i2c_dev->msg_buf_remaining = 0;
 		/*
 		 * Underflow error condition: XFER_COMPLETE before message
@@ -917,7 +917,7 @@ 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);
 
-	if (i2c_dev->is_curr_dma_xfer) {
+	if (i2c_dev->dma_mode) {
 		if (i2c_dev->msg_read)
 			dmaengine_terminate_async(i2c_dev->rx_dma_chan);
 		else
@@ -936,14 +936,14 @@ static int tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev, size_t len)
 	struct dma_slave_config slv_config = {0};
 	u32 val, reg, dma_burst, reg_offset;
 	struct dma_chan *chan;
-	int ret;
+	int err;
 
 	if (i2c_dev->hw->has_mst_fifo)
 		reg = I2C_MST_FIFO_CONTROL;
 	else
 		reg = I2C_FIFO_CONTROL;
 
-	if (i2c_dev->is_curr_dma_xfer) {
+	if (i2c_dev->dma_mode) {
 		if (len & 0xF)
 			dma_burst = 1;
 		else if (len & 0x10)
@@ -976,11 +976,11 @@ static int tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev, size_t len)
 		}
 
 		slv_config.device_fc = true;
-		ret = dmaengine_slave_config(chan, &slv_config);
-		if (ret) {
+		err = dmaengine_slave_config(chan, &slv_config);
+		if (err) {
 			dev_err(i2c_dev->dev, "DMA slave config failed: %d\n",
-				ret);
-			return ret;
+				err);
+			return err;
 		}
 
 		goto out;
@@ -1030,7 +1030,7 @@ static unsigned long tegra_i2c_wait_completion(struct tegra_i2c_dev *i2c_dev,
 {
 	unsigned long ret;
 
-	if (i2c_dev->is_curr_atomic_xfer) {
+	if (i2c_dev->atomic_mode) {
 		ret = tegra_i2c_poll_completion(i2c_dev, complete, timeout_ms);
 	} else {
 		enable_irq(i2c_dev->irq);
@@ -1058,20 +1058,20 @@ static unsigned long tegra_i2c_wait_completion(struct tegra_i2c_dev *i2c_dev,
 static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap)
 {
 	struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
-	u32 reg, time_left;
+	u32 val, time_left;
 	int err;
 
 	reinit_completion(&i2c_dev->msg_complete);
-	reg = FIELD_PREP(I2C_BC_SCLK_THRESHOLD, 9) | I2C_BC_STOP_COND |
+	val = FIELD_PREP(I2C_BC_SCLK_THRESHOLD, 9) | I2C_BC_STOP_COND |
 	      I2C_BC_TERMINATE;
-	i2c_writel(i2c_dev, reg, I2C_BUS_CLEAR_CNFG);
+	i2c_writel(i2c_dev, val, I2C_BUS_CLEAR_CNFG);
 
 	err = tegra_i2c_wait_for_config_load(i2c_dev);
 	if (err)
 		return err;
 
-	reg |= I2C_BC_ENABLE;
-	i2c_writel(i2c_dev, reg, I2C_BUS_CLEAR_CNFG);
+	val |= I2C_BC_ENABLE;
+	i2c_writel(i2c_dev, val, I2C_BUS_CLEAR_CNFG);
 	tegra_i2c_unmask_irq(i2c_dev, I2C_INT_BUS_CLR_DONE);
 
 	time_left = tegra_i2c_wait_completion(i2c_dev, &i2c_dev->msg_complete, 50);
@@ -1082,8 +1082,8 @@ static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap)
 		return -ETIMEDOUT;
 	}
 
-	reg = i2c_readl(i2c_dev, I2C_BUS_CLEAR_STATUS);
-	if (!(reg & I2C_BC_STATUS)) {
+	val = i2c_readl(i2c_dev, I2C_BUS_CLEAR_STATUS);
+	if (!(val & I2C_BC_STATUS)) {
 		dev_err(i2c_dev->dev,
 			"un-recovered arbitration lost\n");
 		return -EIO;
@@ -1105,14 +1105,14 @@ static void tegra_i2c_push_packet_header(struct tegra_i2c_dev *i2c_dev,
 			FIELD_PREP(PACKET_HEADER0_CONT_ID, i2c_dev->cont_id) |
 			FIELD_PREP(PACKET_HEADER0_PACKET_ID, 1);
 
-	if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
+	if (i2c_dev->dma_mode && !i2c_dev->msg_read)
 		*dma_buf++ = packet_header;
 	else
 		i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
 
 	packet_header = msg->len - 1;
 
-	if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
+	if (i2c_dev->dma_mode && !i2c_dev->msg_read)
 		*dma_buf++ = packet_header;
 	else
 		i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
@@ -1137,7 +1137,7 @@ static void tegra_i2c_push_packet_header(struct tegra_i2c_dev *i2c_dev,
 	if (msg->flags & I2C_M_RD)
 		packet_header |= I2C_HEADER_READ;
 
-	if (i2c_dev->is_curr_dma_xfer && !i2c_dev->msg_read)
+	if (i2c_dev->dma_mode && !i2c_dev->msg_read)
 		*dma_buf++ = packet_header;
 	else
 		i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
@@ -1153,7 +1153,7 @@ static int tegra_i2c_error_recover(struct tegra_i2c_dev *i2c_dev,
 
 	/* start recovery upon arbitration loss in single master mode */
 	if (i2c_dev->msg_err == I2C_ERR_ARBITRATION_LOST) {
-		if (!i2c_dev->is_multimaster_mode)
+		if (!i2c_dev->multimaster_mode)
 			return i2c_recover_bus(&i2c_dev->adapter);
 
 		return -EAGAIN;
@@ -1194,9 +1194,8 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 		xfer_size = msg->len + I2C_PACKET_HEADER_SIZE;
 
 	xfer_size = ALIGN(xfer_size, BYTES_PER_FIFO_WORD);
-	i2c_dev->is_curr_dma_xfer = (xfer_size > I2C_PIO_MODE_PREFERRED_LEN) &&
-				    i2c_dev->dma_buf &&
-				    !i2c_dev->is_curr_atomic_xfer;
+	i2c_dev->dma_mode = (xfer_size > I2C_PIO_MODE_PREFERRED_LEN) &&
+			    i2c_dev->dma_buf && !i2c_dev->atomic_mode;
 
 	err = tegra_i2c_config_fifo_trig(i2c_dev, xfer_size);
 	if (err)
@@ -1211,7 +1210,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 
 	int_mask = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST;
 	tegra_i2c_unmask_irq(i2c_dev, int_mask);
-	if (i2c_dev->is_curr_dma_xfer) {
+	if (i2c_dev->dma_mode) {
 		if (i2c_dev->msg_read) {
 			dma_sync_single_for_device(i2c_dev->dev,
 						   i2c_dev->dma_phys,
@@ -1236,7 +1235,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 	tegra_i2c_push_packet_header(i2c_dev, msg, end_state);
 
 	if (!i2c_dev->msg_read) {
-		if (i2c_dev->is_curr_dma_xfer) {
+		if (i2c_dev->dma_mode) {
 			memcpy(i2c_dev->dma_buf, msg->buf, msg->len);
 			dma_sync_single_for_device(i2c_dev->dev,
 						   i2c_dev->dma_phys,
@@ -1256,7 +1255,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 
 	if (i2c_dev->hw->has_per_pkt_xfer_complete_irq)
 		int_mask |= I2C_INT_PACKET_XFER_COMPLETE;
-	if (!i2c_dev->is_curr_dma_xfer) {
+	if (!i2c_dev->dma_mode) {
 		if (msg->flags & I2C_M_RD)
 			int_mask |= I2C_INT_RX_FIFO_DATA_REQ;
 		else if (i2c_dev->msg_buf_remaining)
@@ -1267,7 +1266,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 	dev_dbg(i2c_dev->dev, "unmasked irq: %02x\n",
 		i2c_readl(i2c_dev, I2C_INT_MASK));
 
-	if (i2c_dev->is_curr_dma_xfer) {
+	if (i2c_dev->dma_mode) {
 		time_left = tegra_i2c_wait_completion(i2c_dev,
 						      &i2c_dev->dma_complete,
 						      xfer_time);
@@ -1316,7 +1315,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 		time_left, completion_done(&i2c_dev->msg_complete),
 		i2c_dev->msg_err);
 
-	i2c_dev->is_curr_dma_xfer = false;
+	i2c_dev->dma_mode = false;
 
 	err = tegra_i2c_error_recover(i2c_dev, msg);
 	if (err)
@@ -1368,9 +1367,9 @@ static int tegra_i2c_xfer_atomic(struct i2c_adapter *adap,
 	struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
 	int ret;
 
-	i2c_dev->is_curr_atomic_xfer = true;
+	i2c_dev->atomic_mode = true;
 	ret = tegra_i2c_xfer(adap, msgs, num);
-	i2c_dev->is_curr_atomic_xfer = false;
+	i2c_dev->atomic_mode = false;
 
 	return ret;
 }
@@ -1595,15 +1594,15 @@ static void tegra_i2c_parse_dt(struct tegra_i2c_dev *i2c_dev)
 {
 	struct device_node *np = i2c_dev->dev->of_node;
 	bool multi_mode;
-	int ret;
+	int err;
 
-	ret = of_property_read_u32(np, "clock-frequency",
+	err = of_property_read_u32(np, "clock-frequency",
 				   &i2c_dev->bus_clk_rate);
-	if (ret)
+	if (err)
 		i2c_dev->bus_clk_rate = I2C_MAX_STANDARD_MODE_FREQ; /* default clock rate */
 
 	multi_mode = of_property_read_bool(np, "multi-master");
-	i2c_dev->is_multimaster_mode = multi_mode;
+	i2c_dev->multimaster_mode = multi_mode;
 
 	if (of_device_is_compatible(np, "nvidia,tegra20-i2c-dvc"))
 		i2c_dev->is_dvc = true;
@@ -1634,7 +1633,7 @@ static int tegra_i2c_init_clocks(struct tegra_i2c_dev *i2c_dev)
 		}
 	}
 
-	if (!i2c_dev->is_multimaster_mode)
+	if (!i2c_dev->multimaster_mode)
 		return 0;
 
 	err = clk_enable(i2c_dev->div_clk);
@@ -1653,7 +1652,7 @@ static int tegra_i2c_init_clocks(struct tegra_i2c_dev *i2c_dev)
 
 static void tegra_i2c_release_clocks(struct tegra_i2c_dev *i2c_dev)
 {
-	if (i2c_dev->is_multimaster_mode)
+	if (i2c_dev->multimaster_mode)
 		clk_disable(i2c_dev->div_clk);
 
 	clk_bulk_unprepare(i2c_dev->nclocks, i2c_dev->clocks);
@@ -1678,7 +1677,7 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 {
 	struct tegra_i2c_dev *i2c_dev;
 	struct resource *res;
-	int ret;
+	int err;
 
 	i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL);
 	if (!i2c_dev)
@@ -1699,36 +1698,36 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 
 	i2c_dev->base_phys = res->start;
 
-	ret = platform_get_irq(pdev, 0);
-	if (ret < 0)
-		return ret;
+	err = platform_get_irq(pdev, 0);
+	if (err < 0)
+		return err;
 
-	i2c_dev->irq = ret;
+	i2c_dev->irq = err;
 
 	/* interrupt will be enabled during of transfer time */
 	irq_set_status_flags(i2c_dev->irq, IRQ_NOAUTOEN);
 
-	ret = devm_request_irq(&pdev->dev, i2c_dev->irq, tegra_i2c_isr,
-			       IRQF_NO_SUSPEND, dev_name(&pdev->dev),
+	err = devm_request_irq(i2c_dev->dev, i2c_dev->irq, tegra_i2c_isr,
+			       IRQF_NO_SUSPEND, dev_name(i2c_dev->dev),
 			       i2c_dev);
-	if (ret)
-		return ret;
+	if (err)
+		return err;
 
-	i2c_dev->rst = devm_reset_control_get_exclusive(&pdev->dev, "i2c");
+	i2c_dev->rst = devm_reset_control_get_exclusive(i2c_dev->dev, "i2c");
 	if (IS_ERR(i2c_dev->rst)) {
-		dev_err_probe(&pdev->dev, PTR_ERR(i2c_dev->rst),
+		dev_err_probe(i2c_dev->dev, PTR_ERR(i2c_dev->rst),
 			      "failed to get reset control\n");
 		return PTR_ERR(i2c_dev->rst);
 	}
 
 	tegra_i2c_parse_dt(i2c_dev);
 
-	ret = tegra_i2c_init_clocks(i2c_dev);
-	if (ret)
-		return ret;
+	err = tegra_i2c_init_clocks(i2c_dev);
+	if (err)
+		return err;
 
-	ret = tegra_i2c_init_dma(i2c_dev);
-	if (ret)
+	err = tegra_i2c_init_dma(i2c_dev);
+	if (err)
 		goto release_clocks;
 
 	/*
@@ -1739,16 +1738,16 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 	 * not be used for atomic transfers.
 	 */
 	if (!i2c_dev->is_vi)
-		pm_runtime_irq_safe(&pdev->dev);
-	pm_runtime_enable(&pdev->dev);
+		pm_runtime_irq_safe(i2c_dev->dev);
+	pm_runtime_enable(i2c_dev->dev);
 
-	ret = tegra_i2c_init_hardware(i2c_dev);
-	if (ret)
+	err = tegra_i2c_init_hardware(i2c_dev);
+	if (err)
 		goto release_rpm;
 
 	i2c_set_adapdata(&i2c_dev->adapter, i2c_dev);
-	i2c_dev->adapter.dev.of_node = pdev->dev.of_node;
-	i2c_dev->adapter.dev.parent = &pdev->dev;
+	i2c_dev->adapter.dev.of_node = i2c_dev->dev->of_node;
+	i2c_dev->adapter.dev.parent = i2c_dev->dev;
 	i2c_dev->adapter.retries = 1;
 	i2c_dev->adapter.timeout = 6 * HZ;
 	i2c_dev->adapter.quirks = i2c_dev->hw->quirks;
@@ -1760,23 +1759,23 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 	if (i2c_dev->hw->supports_bus_clear)
 		i2c_dev->adapter.bus_recovery_info = &tegra_i2c_recovery_info;
 
-	strlcpy(i2c_dev->adapter.name, dev_name(&pdev->dev),
+	strlcpy(i2c_dev->adapter.name, dev_name(i2c_dev->dev),
 		sizeof(i2c_dev->adapter.name));
 
-	ret = i2c_add_numbered_adapter(&i2c_dev->adapter);
-	if (ret)
+	err = i2c_add_numbered_adapter(&i2c_dev->adapter);
+	if (err)
 		goto release_rpm;
 
 	return 0;
 
 release_rpm:
-	pm_runtime_disable(&pdev->dev);
+	pm_runtime_disable(i2c_dev->dev);
 
 	tegra_i2c_release_dma(i2c_dev);
 release_clocks:
 	tegra_i2c_release_clocks(i2c_dev);
 
-	return ret;
+	return err;
 }
 
 static int tegra_i2c_remove(struct platform_device *pdev)
@@ -1785,7 +1784,7 @@ static int tegra_i2c_remove(struct platform_device *pdev)
 
 	i2c_del_adapter(&i2c_dev->adapter);
 
-	pm_runtime_disable(&pdev->dev);
+	pm_runtime_disable(i2c_dev->dev);
 
 	tegra_i2c_release_dma(i2c_dev);
 	tegra_i2c_release_clocks(i2c_dev);
@@ -1795,15 +1794,15 @@ static int tegra_i2c_remove(struct platform_device *pdev)
 static int __maybe_unused tegra_i2c_runtime_resume(struct device *dev)
 {
 	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
-	int ret;
+	int err;
 
-	ret = pinctrl_pm_select_default_state(i2c_dev->dev);
-	if (ret)
-		return ret;
+	err = pinctrl_pm_select_default_state(dev);
+	if (err)
+		return err;
 
-	ret = clk_bulk_enable(i2c_dev->nclocks, i2c_dev->clocks);
-	if (ret)
-		return ret;
+	err = clk_bulk_enable(i2c_dev->nclocks, i2c_dev->clocks);
+	if (err)
+		return err;
 
 	/*
 	 * VI I2C device is attached to VE power domain which goes through
@@ -1812,8 +1811,8 @@ static int __maybe_unused tegra_i2c_runtime_resume(struct device *dev)
 	 * domain ON.
 	 */
 	if (i2c_dev->is_vi) {
-		ret = tegra_i2c_init(i2c_dev);
-		if (ret)
+		err = tegra_i2c_init(i2c_dev);
+		if (err)
 			goto disable_clocks;
 	}
 
@@ -1822,7 +1821,7 @@ static int __maybe_unused tegra_i2c_runtime_resume(struct device *dev)
 disable_clocks:
 	clk_bulk_disable(i2c_dev->nclocks, i2c_dev->clocks);
 
-	return ret;
+	return err;
 }
 
 static int __maybe_unused tegra_i2c_runtime_suspend(struct device *dev)
@@ -1831,20 +1830,20 @@ static int __maybe_unused tegra_i2c_runtime_suspend(struct device *dev)
 
 	clk_bulk_disable(i2c_dev->nclocks, i2c_dev->clocks);
 
-	return pinctrl_pm_select_idle_state(i2c_dev->dev);
+	return pinctrl_pm_select_idle_state(dev);
 }
 
 static int __maybe_unused tegra_i2c_suspend(struct device *dev)
 {
 	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
-	int err = 0;
+	int ret = 0;
 
 	i2c_mark_adapter_suspended(&i2c_dev->adapter);
 
 	if (!pm_runtime_status_suspended(dev))
-		err = tegra_i2c_runtime_suspend(dev);
+		ret = tegra_i2c_runtime_suspend(dev);
 
-	return err;
+	return ret;
 }
 
 static int __maybe_unused tegra_i2c_resume(struct device *dev)
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 31/34] i2c: tegra: Clean up printk messages
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (29 preceding siblings ...)
  2020-09-08 22:40 ` [PATCH v7 30/34] i2c: tegra: Clean up variable names Dmitry Osipenko
@ 2020-09-08 22:40 ` Dmitry Osipenko
  2020-09-17 12:22   ` Thierry Reding
  2020-09-21 10:20   ` Thierry Reding
  2020-09-08 22:40 ` [PATCH v7 32/34] i2c: tegra: Clean up and improve comments Dmitry Osipenko
                   ` (4 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:40 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

This patch unifies style of all messages in the driver by starting them
with a lowercase letter and using consistent capitalization and wording
for all messages.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 37 +++++++++++++---------------------
 1 file changed, 14 insertions(+), 23 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index fbdb206f0161..558b1f2934a0 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -381,7 +381,8 @@ static int tegra_i2c_dma_submit(struct tegra_i2c_dev *i2c_dev, size_t len)
 					       len, dir, DMA_PREP_INTERRUPT |
 					       DMA_CTRL_ACK);
 	if (!dma_desc) {
-		dev_err(i2c_dev->dev, "failed to get DMA descriptor\n");
+		dev_err(i2c_dev->dev, "failed to get %s DMA descriptor\n",
+			i2c_dev->msg_read ? "RX" : "TX");
 		return -EINVAL;
 	}
 
@@ -422,7 +423,7 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev)
 		return 0;
 
 	if (!IS_ENABLED(CONFIG_TEGRA20_APB_DMA)) {
-		dev_dbg(i2c_dev->dev, "Support for APB DMA not enabled!\n");
+		dev_dbg(i2c_dev->dev, "DMA support not enabled\n");
 		return 0;
 	}
 
@@ -448,7 +449,7 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev)
 	dma_buf = dma_alloc_coherent(i2c_dev->dev, i2c_dev->dma_buf_size,
 				     &dma_phys, GFP_KERNEL | __GFP_NOWARN);
 	if (!dma_buf) {
-		dev_err(i2c_dev->dev, "failed to allocate the DMA buffer\n");
+		dev_err(i2c_dev->dev, "failed to allocate DMA buffer\n");
 		err = -ENOMEM;
 		goto err_out;
 	}
@@ -572,7 +573,7 @@ static int tegra_i2c_wait_for_config_load(struct tegra_i2c_dev *i2c_dev)
 	err = tegra_i2c_poll_register(i2c_dev, I2C_CONFIG_LOAD, 0xffffffff,
 				      1000, I2C_CONFIG_LOAD_TIMEOUT);
 	if (err) {
-		dev_warn(i2c_dev->dev, "timeout waiting for config load\n");
+		dev_err(i2c_dev->dev, "failed to load config\n");
 		return err;
 	}
 
@@ -835,7 +836,7 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
 	status = i2c_readl(i2c_dev, I2C_INT_STATUS);
 
 	if (status == 0) {
-		dev_warn(i2c_dev->dev, "irq status 0 %08x %08x %08x\n",
+		dev_warn(i2c_dev->dev, "IRQ status 0 %08x %08x %08x\n",
 			 i2c_readl(i2c_dev, I2C_PACKET_TRANSFER_STATUS),
 			 i2c_readl(i2c_dev, I2C_STATUS),
 			 i2c_readl(i2c_dev, I2C_CNFG));
@@ -978,8 +979,7 @@ static int tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev, size_t len)
 		slv_config.device_fc = true;
 		err = dmaengine_slave_config(chan, &slv_config);
 		if (err) {
-			dev_err(i2c_dev->dev, "DMA slave config failed: %d\n",
-				err);
+			dev_err(i2c_dev->dev, "DMA config failed: %d\n", err);
 			return err;
 		}
 
@@ -1078,14 +1078,13 @@ static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap)
 	tegra_i2c_mask_irq(i2c_dev, I2C_INT_BUS_CLR_DONE);
 
 	if (time_left == 0) {
-		dev_err(i2c_dev->dev, "timed out for bus clear\n");
+		dev_err(i2c_dev->dev, "failed to clear bus\n");
 		return -ETIMEDOUT;
 	}
 
 	val = i2c_readl(i2c_dev, I2C_BUS_CLEAR_STATUS);
 	if (!(val & I2C_BC_STATUS)) {
-		dev_err(i2c_dev->dev,
-			"un-recovered arbitration lost\n");
+		dev_err(i2c_dev->dev, "un-recovered arbitration lost\n");
 		return -EIO;
 	}
 
@@ -1217,12 +1216,8 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 						   xfer_size,
 						   DMA_FROM_DEVICE);
 			err = tegra_i2c_dma_submit(i2c_dev, xfer_size);
-			if (err) {
-				dev_err(i2c_dev->dev,
-					"starting RX DMA failed, err %d\n",
-					err);
+			if (err)
 				return err;
-			}
 
 		} else {
 			dma_sync_single_for_cpu(i2c_dev->dev,
@@ -1242,12 +1237,8 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 						   xfer_size,
 						   DMA_TO_DEVICE);
 			err = tegra_i2c_dma_submit(i2c_dev, xfer_size);
-			if (err) {
-				dev_err(i2c_dev->dev,
-					"starting TX DMA failed, err %d\n",
-					err);
+			if (err)
 				return err;
-			}
 		} else {
 			tegra_i2c_fill_tx_fifo(i2c_dev);
 		}
@@ -1263,7 +1254,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 	}
 
 	tegra_i2c_unmask_irq(i2c_dev, int_mask);
-	dev_dbg(i2c_dev->dev, "unmasked irq: %02x\n",
+	dev_dbg(i2c_dev->dev, "unmasked IRQ: %02x\n",
 		i2c_readl(i2c_dev, I2C_INT_MASK));
 
 	if (i2c_dev->dma_mode) {
@@ -1285,7 +1276,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 					 i2c_dev->tx_dma_chan);
 
 		if (!time_left && !completion_done(&i2c_dev->dma_complete)) {
-			dev_err(i2c_dev->dev, "DMA transfer timeout\n");
+			dev_err(i2c_dev->dev, "DMA transfer timed out\n");
 			err = -ETIMEDOUT;
 			goto reset_hardware;
 		}
@@ -1306,7 +1297,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 	tegra_i2c_mask_irq(i2c_dev, int_mask);
 
 	if (time_left == 0) {
-		dev_err(i2c_dev->dev, "i2c transfer timed out\n");
+		dev_err(i2c_dev->dev, "I2C transfer timed out\n");
 		err = -ETIMEDOUT;
 		goto reset_hardware;
 	}
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 32/34] i2c: tegra: Clean up and improve comments
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (30 preceding siblings ...)
  2020-09-08 22:40 ` [PATCH v7 31/34] i2c: tegra: Clean up printk messages Dmitry Osipenko
@ 2020-09-08 22:40 ` Dmitry Osipenko
  2020-09-17 12:32   ` Thierry Reding
  2020-09-21 10:20   ` Thierry Reding
  2020-09-08 22:40 ` [PATCH v7 33/34] i2c: tegra: Clean up whitespaces, newlines and indentation Dmitry Osipenko
                   ` (3 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:40 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

Make all comments to be consistent in regards to capitalization and
punctuation, correct spelling and grammar errors, improve wording.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 88 ++++++++++++++++++----------------
 1 file changed, 47 insertions(+), 41 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 558b1f2934a0..31fbc6181dd5 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -136,7 +136,7 @@
 /* configuration load timeout in microseconds */
 #define I2C_CONFIG_LOAD_TIMEOUT			1000000
 
-/* Packet header size in bytes */
+/* packet header size in bytes */
 #define I2C_PACKET_HEADER_SIZE			12
 
 /*
@@ -148,11 +148,10 @@
 #define I2C_PIO_MODE_PREFERRED_LEN		32
 
 /*
- * 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.
+ * msg_end_type: The bus control which needs to be sent at end of transfer.
+ * @MSG_END_STOP: Send stop pulse.
+ * @MSG_END_REPEAT_START: Send repeat-start.
+ * @MSG_END_CONTINUE: Don't send stop or repeat-start.
  */
 enum msg_end_type {
 	MSG_END_STOP,
@@ -161,10 +160,10 @@ 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 : per hardware generation features
+ * @has_continue_xfer_support: Continue-transfer supported.
  * @has_per_pkt_xfer_complete_irq: Has enable/disable capability for transfer
- *		complete interrupt per packet basis.
+ *		completion interrupt on per packet basis.
  * @has_config_load_reg: Has the config load register to load the new
  *		configuration.
  * @clk_divisor_hs_mode: Clock divisor in HS mode.
@@ -184,7 +183,7 @@ enum msg_end_type {
  * @has_mst_fifo: The I2C controller contains the new MST FIFO interface that
  *		provides additional features and allows for longer messages to
  *		be transferred in one go.
- * @quirks: i2c adapter quirks for limiting write/read transfer size and not
+ * @quirks: I2C adapter quirks for limiting write/read transfer size and not
  *		allowing 0 length transfers.
  * @supports_bus_clear: Bus Clear support to recover from bus hang during
  *		SDA stuck low from device for some unknown reasons.
@@ -245,7 +244,7 @@ struct tegra_i2c_hw_feature {
  * @msg_err: error code for completed message
  * @msg_buf: pointer to current message data
  * @msg_buf_remaining: size of unsent data in the message buffer
- * @msg_read: identifies read transfers
+ * @msg_read: indicates read direction of a transfer
  * @bus_clk_rate: current I2C bus clock rate
  * @multimaster_mode: indicates that I2C controller is in multi-master mode
  * @tx_dma_chan: DMA transmit channel
@@ -306,8 +305,8 @@ static u32 dvc_readl(struct tegra_i2c_dev *i2c_dev, u32 reg)
 }
 
 /*
- * i2c_writel and i2c_readl will offset the register if necessary to talk
- * to the I2C block inside the DVC block
+ * If necessary, i2c_writel() and i2c_readl() will offset the register
+ * in order to talk to the I2C block inside the DVC block.
  */
 static u32 tegra_i2c_reg_addr(struct tegra_i2c_dev *i2c_dev, u32 reg)
 {
@@ -322,7 +321,7 @@ static void i2c_writel(struct tegra_i2c_dev *i2c_dev, u32 val, u32 reg)
 {
 	writel_relaxed(val, i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
 
-	/* Read back register to make sure that register writes completed */
+	/* read back register to make sure that register writes completed */
 	if (reg != I2C_TX_FIFO)
 		readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
 }
@@ -474,7 +473,7 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev)
  * block.  This block is identical to the rest of the I2C blocks, except that
  * it only supports master mode, it has registers moved around, and it needs
  * some extra init to get it into I2C mode.  The register moves are handled
- * by i2c_readl and i2c_writel
+ * by i2c_readl() and i2c_writel().
  */
 static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev)
 {
@@ -632,7 +631,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 		break;
 	}
 
-	/* Make sure clock divisor programmed correctly */
+	/* make sure clock divisor programmed correctly */
 	clk_divisor = FIELD_PREP(I2C_CLK_DIVISOR_HSMODE,
 				 i2c_dev->hw->clk_divisor_hs_mode) |
 		      FIELD_PREP(I2C_CLK_DIVISOR_STD_FAST_MODE, non_hs_mode);
@@ -645,8 +644,8 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 	}
 
 	/*
-	 * configure setup and hold times only when tsu_thd is non-zero.
-	 * otherwise, preserve the chip default values
+	 * Configure setup and hold times only when tsu_thd is non-zero.
+	 * Otherwise, preserve the chip default values.
 	 */
 	if (i2c_dev->hw->has_interface_timing_reg && tsu_thd)
 		i2c_writel(i2c_dev, tsu_thd, I2C_INTERFACE_TIMING_1);
@@ -690,7 +689,7 @@ static int tegra_i2c_disable_packet_mode(struct tegra_i2c_dev *i2c_dev)
 
 	/*
 	 * NACK interrupt is generated before the I2C controller generates
-	 * the STOP condition on the bus. So wait for 2 clock periods
+	 * the STOP condition on the bus.  So, wait for 2 clock periods
 	 * before disabling the controller so that the STOP condition has
 	 * been delivered properly.
 	 */
@@ -711,8 +710,8 @@ static int tegra_i2c_empty_rx_fifo(struct tegra_i2c_dev *i2c_dev)
 	u32 val;
 
 	/*
-	 * Catch overflow due to message fully sent
-	 * before the check for RX FIFO availability.
+	 * Catch overflow due to message fully sent before the check for
+	 * RX FIFO availability.
 	 */
 	if (WARN_ON_ONCE(!(i2c_dev->msg_buf_remaining)))
 		return -EINVAL;
@@ -725,7 +724,7 @@ static int tegra_i2c_empty_rx_fifo(struct tegra_i2c_dev *i2c_dev)
 		rx_fifo_avail = FIELD_GET(I2C_FIFO_STATUS_RX, val);
 	}
 
-	/* Rounds down to not include partial word at the end of buf */
+	/* round down to exclude partial word at the end of buffer */
 	words_to_transfer = buf_remaining / BYTES_PER_FIFO_WORD;
 	if (words_to_transfer > rx_fifo_avail)
 		words_to_transfer = rx_fifo_avail;
@@ -737,8 +736,8 @@ static int tegra_i2c_empty_rx_fifo(struct tegra_i2c_dev *i2c_dev)
 	rx_fifo_avail -= words_to_transfer;
 
 	/*
-	 * If there is a partial word at the end of buf, handle it manually to
-	 * prevent overwriting past the end of buf
+	 * If there is a partial word at the end of buffer, handle it
+	 * manually to prevent overwriting past the end of buffer.
 	 */
 	if (rx_fifo_avail > 0 && buf_remaining > 0) {
 		/*
@@ -778,10 +777,15 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
 		tx_fifo_avail = FIELD_GET(I2C_FIFO_STATUS_TX, val);
 	}
 
-	/* Rounds down to not include partial word at the end of buf */
+	/* round down to exclude partial word at the end of buffer */
 	words_to_transfer = buf_remaining / BYTES_PER_FIFO_WORD;
 
-	/* It's very common to have < 4 bytes, so optimize that case. */
+	/*
+	 * This hunk pushes 4 bytes at a time into the TX FIFO.
+	 *
+	 * It's very common to have < 4 bytes, hence there is no word
+	 * to push if we have less than 4 bytes to transfer.
+	 */
 	if (words_to_transfer) {
 		if (words_to_transfer > tx_fifo_avail)
 			words_to_transfer = tx_fifo_avail;
@@ -805,8 +809,8 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
 	}
 
 	/*
-	 * If there is a partial word at the end of buf, handle it manually to
-	 * prevent reading past the end of buf, which could cross a page
+	 * If there is a partial word at the end of buffer, handle it manually
+	 * to prevent reading past the end of buffer, which could cross a page
 	 * boundary and fault.
 	 */
 	if (tx_fifo_avail > 0 && buf_remaining > 0) {
@@ -854,7 +858,7 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
 	}
 
 	/*
-	 * I2C transfer is terminated during the bus clear so skip
+	 * I2C transfer is terminated during the bus clear, so skip
 	 * processing the other interrupts.
 	 */
 	if (i2c_dev->hw->supports_bus_clear && (status & I2C_INT_BUS_CLR_DONE))
@@ -890,7 +894,8 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
 	 * During message read XFER_COMPLETE interrupt is triggered prior to
 	 * DMA completion and during message write XFER_COMPLETE interrupt is
 	 * triggered after DMA completion.
-	 * PACKETS_XFER_COMPLETE indicates completion of all bytes of transfer.
+	 *
+	 * PACKETS_XFER_COMPLETE indicates completion of all bytes of transfer,
 	 * so forcing msg_buf_remaining to 0 in DMA mode.
 	 */
 	if (status & I2C_INT_PACKET_XFER_COMPLETE) {
@@ -908,7 +913,7 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
 	}
 	goto done;
 err:
-	/* An error occurred, mask all interrupts */
+	/* mask all interrupts on error */
 	tegra_i2c_mask_irq(i2c_dev, I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST |
 		I2C_INT_PACKET_XFER_COMPLETE | I2C_INT_TX_FIFO_DATA_REQ |
 		I2C_INT_RX_FIFO_DATA_REQ);
@@ -1337,6 +1342,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
 		enum msg_end_type end_type = MSG_END_STOP;
 
 		if (i < (num - 1)) {
+			/* check whether follow up message is coming */
 			if (msgs[i + 1].flags & I2C_M_NOSTART)
 				end_type = MSG_END_CONTINUE;
 			else
@@ -1566,7 +1572,6 @@ static const struct tegra_i2c_hw_feature tegra194_i2c_hw = {
 	.has_interface_timing_reg = true,
 };
 
-/* Match table for of_platform binding */
 static const struct of_device_id tegra_i2c_of_match[] = {
 	{ .compatible = "nvidia,tegra194-i2c", .data = &tegra194_i2c_hw, },
 	{ .compatible = "nvidia,tegra186-i2c", .data = &tegra186_i2c_hw, },
@@ -1590,7 +1595,7 @@ static void tegra_i2c_parse_dt(struct tegra_i2c_dev *i2c_dev)
 	err = of_property_read_u32(np, "clock-frequency",
 				   &i2c_dev->bus_clk_rate);
 	if (err)
-		i2c_dev->bus_clk_rate = I2C_MAX_STANDARD_MODE_FREQ; /* default clock rate */
+		i2c_dev->bus_clk_rate = I2C_MAX_STANDARD_MODE_FREQ;
 
 	multi_mode = of_property_read_bool(np, "multi-master");
 	i2c_dev->multimaster_mode = multi_mode;
@@ -1722,11 +1727,13 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 		goto release_clocks;
 
 	/*
-	 * VI I2C is in VE power domain which is not always on and not
-	 * an IRQ safe. So, IRQ safe device can't be attached to a non-IRQ
-	 * safe domain as it prevents powering off the PM domain.
-	 * Also, VI I2C device don't need to use runtime IRQ safe as it will
-	 * not be used for atomic transfers.
+	 * VI I2C is in VE power domain which is not always ON and not
+	 * IRQ-safe.  Thus, IRQ-safe device shouldn't be attached to a
+	 * non IRQ-safe domain because this prevents powering off the power
+	 * domain.
+	 *
+	 * VI I2C device shouldn't be marked as IRQ-safe because VI I2C won't
+	 * be used for atomic transfers.
 	 */
 	if (!i2c_dev->is_vi)
 		pm_runtime_irq_safe(i2c_dev->dev);
@@ -1797,9 +1804,8 @@ static int __maybe_unused tegra_i2c_runtime_resume(struct device *dev)
 
 	/*
 	 * VI I2C device is attached to VE power domain which goes through
-	 * power ON/OFF during PM runtime resume/suspend. So, controller
-	 * should go through reset and need to re-initialize after power
-	 * domain ON.
+	 * power ON/OFF during of runtime PM resume/suspend, meaning that
+	 * controller needs to be re-initialized after power ON.
 	 */
 	if (i2c_dev->is_vi) {
 		err = tegra_i2c_init(i2c_dev);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 33/34] i2c: tegra: Clean up whitespaces, newlines and indentation
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (31 preceding siblings ...)
  2020-09-08 22:40 ` [PATCH v7 32/34] i2c: tegra: Clean up and improve comments Dmitry Osipenko
@ 2020-09-08 22:40 ` Dmitry Osipenko
  2020-09-17 12:35   ` Thierry Reding
  2020-09-21 10:20   ` Thierry Reding
  2020-09-08 22:40 ` [PATCH v7 34/34] i2c: tegra: Improve driver module description Dmitry Osipenko
                   ` (2 subsequent siblings)
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:40 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

Some places in the code are missing newlines or have unnecessary
whitespaces and newlines. This creates inconsistency of the code and
hurts readability. This patch removes the unnecessary and adds necessary
whitespaces / newlines, clears indentation of the code.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 72 +++++++++++++++++++++-------------
 1 file changed, 45 insertions(+), 27 deletions(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 31fbc6181dd5..087f98010963 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -314,6 +314,7 @@ static u32 tegra_i2c_reg_addr(struct tegra_i2c_dev *i2c_dev, u32 reg)
 		reg += (reg >= I2C_TX_FIFO) ? 0x10 : 0x40;
 	else if (i2c_dev->is_vi)
 		reg = 0xc00 + (reg << 2);
+
 	return reg;
 }
 
@@ -373,9 +374,12 @@ static int tegra_i2c_dma_submit(struct tegra_i2c_dev *i2c_dev, size_t len)
 	struct dma_chan *chan;
 
 	dev_dbg(i2c_dev->dev, "starting DMA for length: %zu\n", len);
+
 	reinit_completion(&i2c_dev->dma_complete);
+
 	dir = i2c_dev->msg_read ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV;
 	chan = i2c_dev->msg_read ? i2c_dev->rx_dma_chan : i2c_dev->tx_dma_chan;
+
 	dma_desc = dmaengine_prep_slave_single(chan, i2c_dev->dma_phys,
 					       len, dir, DMA_PREP_INTERRUPT |
 					       DMA_CTRL_ACK);
@@ -387,8 +391,10 @@ static int tegra_i2c_dma_submit(struct tegra_i2c_dev *i2c_dev, size_t len)
 
 	dma_desc->callback = tegra_i2c_dma_complete;
 	dma_desc->callback_param = i2c_dev;
+
 	dmaengine_submit(dma_desc);
 	dma_async_issue_pending(chan);
+
 	return 0;
 }
 
@@ -455,6 +461,7 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev)
 
 	i2c_dev->dma_buf = dma_buf;
 	i2c_dev->dma_phys = dma_phys;
+
 	return 0;
 
 err_out:
@@ -557,6 +564,7 @@ static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
 		dev_err(i2c_dev->dev, "failed to flush FIFO\n");
 		return err;
 	}
+
 	return 0;
 }
 
@@ -650,8 +658,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
 	if (i2c_dev->hw->has_interface_timing_reg && tsu_thd)
 		i2c_writel(i2c_dev, tsu_thd, I2C_INTERFACE_TIMING_1);
 
-	clk_multiplier  = tlow + thigh + 2;
-	clk_multiplier *= non_hs_mode + 1;
+	clk_multiplier = (tlow + thigh + 2) * (non_hs_mode + 1);
 
 	err = clk_set_rate(i2c_dev->div_clk,
 			   i2c_dev->bus_clk_rate * clk_multiplier);
@@ -799,9 +806,9 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
 		 */
 		buf_remaining -= words_to_transfer * BYTES_PER_FIFO_WORD;
 		tx_fifo_avail -= words_to_transfer;
+
 		i2c_dev->msg_buf_remaining = buf_remaining;
-		i2c_dev->msg_buf = buf +
-			words_to_transfer * BYTES_PER_FIFO_WORD;
+		i2c_dev->msg_buf = buf + words_to_transfer * BYTES_PER_FIFO_WORD;
 
 		i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
 
@@ -914,12 +921,18 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
 	goto done;
 err:
 	/* mask all interrupts on error */
-	tegra_i2c_mask_irq(i2c_dev, I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST |
-		I2C_INT_PACKET_XFER_COMPLETE | I2C_INT_TX_FIFO_DATA_REQ |
-		I2C_INT_RX_FIFO_DATA_REQ);
+	tegra_i2c_mask_irq(i2c_dev,
+			   I2C_INT_NO_ACK |
+			   I2C_INT_ARBITRATION_LOST |
+			   I2C_INT_PACKET_XFER_COMPLETE |
+			   I2C_INT_TX_FIFO_DATA_REQ |
+			   I2C_INT_RX_FIFO_DATA_REQ);
+
 	if (i2c_dev->hw->supports_bus_clear)
 		tegra_i2c_mask_irq(i2c_dev, I2C_INT_BUS_CLR_DONE);
+
 	i2c_writel(i2c_dev, status, I2C_INT_STATUS);
+
 	if (i2c_dev->is_dvc)
 		dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);
 
@@ -960,6 +973,7 @@ static int tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev, size_t len)
 		if (i2c_dev->msg_read) {
 			chan = i2c_dev->rx_dma_chan;
 			reg_offset = tegra_i2c_reg_addr(i2c_dev, I2C_RX_FIFO);
+
 			slv_config.src_addr = i2c_dev->base_phys + reg_offset;
 			slv_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 			slv_config.src_maxburst = dma_burst;
@@ -971,6 +985,7 @@ static int tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev, size_t len)
 		} else {
 			chan = i2c_dev->tx_dma_chan;
 			reg_offset = tegra_i2c_reg_addr(i2c_dev, I2C_TX_FIFO);
+
 			slv_config.dst_addr = i2c_dev->base_phys + reg_offset;
 			slv_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 			slv_config.dst_maxburst = dma_burst;
@@ -1067,6 +1082,7 @@ static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap)
 	int err;
 
 	reinit_completion(&i2c_dev->msg_complete);
+
 	val = FIELD_PREP(I2C_BC_SCLK_THRESHOLD, 9) | I2C_BC_STOP_COND |
 	      I2C_BC_TERMINATE;
 	i2c_writel(i2c_dev, val, I2C_BUS_CLEAR_CNFG);
@@ -1198,7 +1214,8 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 		xfer_size = msg->len + I2C_PACKET_HEADER_SIZE;
 
 	xfer_size = ALIGN(xfer_size, BYTES_PER_FIFO_WORD);
-	i2c_dev->dma_mode = (xfer_size > I2C_PIO_MODE_PREFERRED_LEN) &&
+
+	i2c_dev->dma_mode = xfer_size > I2C_PIO_MODE_PREFERRED_LEN &&
 			    i2c_dev->dma_buf && !i2c_dev->atomic_mode;
 
 	err = tegra_i2c_config_fifo_trig(i2c_dev, xfer_size);
@@ -1210,25 +1227,24 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 	 * Total bits = 9 bits per byte (including ACK bit) + Start & stop bits
 	 */
 	xfer_time += DIV_ROUND_CLOSEST(((xfer_size * 9) + 2) * MSEC_PER_SEC,
-					i2c_dev->bus_clk_rate);
+				       i2c_dev->bus_clk_rate);
 
 	int_mask = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST;
 	tegra_i2c_unmask_irq(i2c_dev, int_mask);
+
 	if (i2c_dev->dma_mode) {
 		if (i2c_dev->msg_read) {
 			dma_sync_single_for_device(i2c_dev->dev,
 						   i2c_dev->dma_phys,
-						   xfer_size,
-						   DMA_FROM_DEVICE);
+						   xfer_size, DMA_FROM_DEVICE);
+
 			err = tegra_i2c_dma_submit(i2c_dev, xfer_size);
 			if (err)
 				return err;
-
 		} else {
 			dma_sync_single_for_cpu(i2c_dev->dev,
 						i2c_dev->dma_phys,
-						xfer_size,
-						DMA_TO_DEVICE);
+						xfer_size, DMA_TO_DEVICE);
 		}
 	}
 
@@ -1237,10 +1253,11 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 	if (!i2c_dev->msg_read) {
 		if (i2c_dev->dma_mode) {
 			memcpy(i2c_dev->dma_buf, msg->buf, msg->len);
+
 			dma_sync_single_for_device(i2c_dev->dev,
 						   i2c_dev->dma_phys,
-						   xfer_size,
-						   DMA_TO_DEVICE);
+						   xfer_size, DMA_TO_DEVICE);
+
 			err = tegra_i2c_dma_submit(i2c_dev, xfer_size);
 			if (err)
 				return err;
@@ -1251,6 +1268,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 
 	if (i2c_dev->hw->has_per_pkt_xfer_complete_irq)
 		int_mask |= I2C_INT_PACKET_XFER_COMPLETE;
+
 	if (!i2c_dev->dma_mode) {
 		if (msg->flags & I2C_M_RD)
 			int_mask |= I2C_INT_RX_FIFO_DATA_REQ;
@@ -1289,10 +1307,9 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
 		if (i2c_dev->msg_read && i2c_dev->msg_err == I2C_ERR_NONE) {
 			dma_sync_single_for_cpu(i2c_dev->dev,
 						i2c_dev->dma_phys,
-						xfer_size,
-						DMA_FROM_DEVICE);
-			memcpy(i2c_dev->msg_buf, i2c_dev->dma_buf,
-			       msg->len);
+						xfer_size, DMA_FROM_DEVICE);
+
+			memcpy(i2c_dev->msg_buf, i2c_dev->dma_buf, msg->len);
 		}
 	}
 
@@ -1379,6 +1396,7 @@ static u32 tegra_i2c_func(struct i2c_adapter *adap)
 
 	if (i2c_dev->hw->has_continue_xfer_support)
 		ret |= I2C_FUNC_NOSTART;
+
 	return ret;
 }
 
@@ -1737,6 +1755,7 @@ static int tegra_i2c_probe(struct platform_device *pdev)
 	 */
 	if (!i2c_dev->is_vi)
 		pm_runtime_irq_safe(i2c_dev->dev);
+
 	pm_runtime_enable(i2c_dev->dev);
 
 	err = tegra_i2c_init_hardware(i2c_dev);
@@ -1781,11 +1800,11 @@ static int tegra_i2c_remove(struct platform_device *pdev)
 	struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
 
 	i2c_del_adapter(&i2c_dev->adapter);
-
 	pm_runtime_disable(i2c_dev->dev);
 
 	tegra_i2c_release_dma(i2c_dev);
 	tegra_i2c_release_clocks(i2c_dev);
+
 	return 0;
 }
 
@@ -1883,15 +1902,14 @@ static const struct dev_pm_ops tegra_i2c_pm = {
 };
 
 static struct platform_driver tegra_i2c_driver = {
-	.probe   = tegra_i2c_probe,
-	.remove  = tegra_i2c_remove,
-	.driver  = {
-		.name  = "tegra-i2c",
+	.probe = tegra_i2c_probe,
+	.remove = tegra_i2c_remove,
+	.driver = {
+		.name = "tegra-i2c",
 		.of_match_table = tegra_i2c_of_match,
-		.pm    = &tegra_i2c_pm,
+		.pm = &tegra_i2c_pm,
 	},
 };
-
 module_platform_driver(tegra_i2c_driver);
 
 MODULE_DESCRIPTION("nVidia Tegra2 I2C Bus Controller driver");
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* [PATCH v7 34/34] i2c: tegra: Improve driver module description
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (32 preceding siblings ...)
  2020-09-08 22:40 ` [PATCH v7 33/34] i2c: tegra: Clean up whitespaces, newlines and indentation Dmitry Osipenko
@ 2020-09-08 22:40 ` Dmitry Osipenko
  2020-09-17 12:35   ` Thierry Reding
  2020-09-21 10:20   ` Thierry Reding
  2020-09-09  9:11 ` [PATCH v7 00/34] Improvements for Tegra I2C driver Andy Shevchenko
  2020-09-21 10:18 ` Thierry Reding
  35 siblings, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-08 22:40 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko
  Cc: linux-i2c, linux-tegra, linux-kernel

Use proper spelling of "NVIDIA" and don't designate driver as Tegra2-only
since newer SoC generations are supported as well.

Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/i2c/busses/i2c-tegra.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 087f98010963..1b56d63bdd3c 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -1912,6 +1912,6 @@ static struct platform_driver tegra_i2c_driver = {
 };
 module_platform_driver(tegra_i2c_driver);
 
-MODULE_DESCRIPTION("nVidia Tegra2 I2C Bus Controller driver");
+MODULE_DESCRIPTION("NVIDIA Tegra I2C Bus Controller driver");
 MODULE_AUTHOR("Colin Cross");
 MODULE_LICENSE("GPL v2");
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 00/34] Improvements for Tegra I2C driver
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (33 preceding siblings ...)
  2020-09-08 22:40 ` [PATCH v7 34/34] i2c: tegra: Improve driver module description Dmitry Osipenko
@ 2020-09-09  9:11 ` Andy Shevchenko
  2020-09-09 15:36   ` Dmitry Osipenko
  2020-09-21 10:18 ` Thierry Reding
  35 siblings, 1 reply; 146+ messages in thread
From: Andy Shevchenko @ 2020-09-09  9:11 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, linux-i2c, linux-tegra,
	Linux Kernel Mailing List

On Wed, Sep 9, 2020 at 1:40 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>
> Hello!
>
> This series performs refactoring of the Tegra I2C driver code and hardens
> the atomic-transfer mode.

I think there is still room for improvement, but let not block it, FWIW,
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>

> Changelog:
>
> v7: - Reworked the "Clean up probe function" patch by moving out all
>       variable renamings into the "Clean up variable names" patch.
>       This results in a nicer diff, which was asked by Andy Shevchenko.
>
>     - Squashed "Improve coding style of tegra_i2c_wait_for_config_load()"
>       patch into "Factor out register polling into separate function" in
>       order avoid unnecessary ping-pong changes, which was asked by
>       Andy Shevchenko.
>
>     - Added more indentation improvements, it should be ideal now.
>
>     - I haven't changed order of the "Clean up variable types" patch,
>       which was suggested by Andy Shevchenko, because I already moved
>       that patch multiple times and we decided to sort patches starting
>       with more important cleanups and down to less important. The type
>       changes are more important than shuffling code around, IMO.
>
> v6: - Added new patch that adds missing RPM puts, thanks to Andy Shevchenko
>       for the suggestion.
>
>     - Improved commit messages by extending them with more a more detailed
>       explanation of the changes.
>
>     - Added clarifying comment to the "Use reset_control_reset()" change,
>       which was asked by Andy Shevchenko.
>
>     - Refactored the "Clean up probe function" patch by moving the
>       dev_err_probe() change into the "Use clk-bulk helpers" patch,
>       which was suggested by Andy Shevchenko.
>
>     - Improved ordering of the patches like it was suggested by
>       Andy Shevchenko.
>
>     - Added Andy Shevchenko to suggested-by of the "Use clk-bulk helpers"
>       patch.
>
>     - Improved "Remove i2c_dev.clk_divisor_non_hs_mode member" patch by
>       making the case-switch to use "fast plus mode" timing if clock rate
>       is out-of-range. Just to make it more consistent.
>
>     - The "Improve tegra_i2c_dev structure" patch is squashed into
>      "Improve formatting of variables" and "Clean up types/names" patches.
>
>     - All variable-renaming changes are squashed into a single "Clean up
>       variable names" patch.
>
>     - Made extra minor improvement to various patches, like more comments
>       and indentations improved.
>
> v5: - Dropped the "Factor out runtime PM and hardware initialization"
>       patch, like it was suggested by Michał Mirosław. Instead a less
>       invasive "Factor out hardware initialization into separate function"
>       patch added, it doesn't touch the RPM initialization.
>
>     - The "Remove outdated barrier()" patch now removes outdated comments.
>
>     - Updated commit description of the "Remove "dma" variable" patch,
>       saying that the transfer mode may be changed by a callee. This was
>       suggested by Michał Mirosław.
>
>     - Reworked the "Clean up and improve comments" patch. Couple more
>       comments are corrected and reworded now.
>
>     - Added r-b's from Michał Mirosław.
>
>     - New patches:
>
>         i2c: tegra: Mask interrupt in tegra_i2c_issue_bus_clear()
>         i2c: tegra: Remove redundant check in tegra_i2c_issue_bus_clear()
>         i2c: tegra: Don't fall back to PIO mode if DMA configuration fails
>         i2c: tegra: Clean up variable types
>         i2c: tegra: Improve tegra_i2c_dev structure
>
> v4: - Reordered patches in the fixes/features/cleanups order like it was
>       suggested by Andy Shevchenko.
>
>     - Now using clk-bulk API, which was suggested by Andy Shevchenko.
>
>     - Reworked "Make tegra_i2c_flush_fifos() usable in atomic transfer"
>       patch to use iopoll API, which was suggested by Andy Shevchenko.
>
>     - Separated "Clean up probe function" into several smaller patches.
>
>     - Squashed "Add missing newline before returns" patch into
>       "Clean up whitespaces, newlines and indentation".
>
>     - The "Drop '_timeout' from wait/poll function names" is renamed to
>       "Rename wait/poll functions".
>
>     - The "Use reset_control_reset()" is changed to not fail tegra_i2c_init(),
>       but only emit warning. This should be more friendly behaviour in oppose
>       to having a non-bootable machine if reset-control fails.
>
>     - New patches:
>
>         i2c: tegra: Remove error message used for devm_request_irq() failure
>         i2c: tegra: Use devm_platform_get_and_ioremap_resource()
>         i2c: tegra: Use platform_get_irq()
>         i2c: tegra: Use clk-bulk helpers
>         i2c: tegra: Remove bogus barrier()
>         i2c: tegra: Factor out register polling into separate function
>         i2c: tegra: Consolidate error handling in tegra_i2c_xfer_msg()
>         i2c: tegra: Clean up and improve comments
>         i2c: tegra: Rename couple "ret" variables to "err"
>
> v3: - Optimized "Make tegra_i2c_flush_fifos() usable in atomic transfer"
>       patch by pre-checking FIFO state before starting to poll using
>       ktime API, which may be expensive under some circumstances.
>
>     - The "Clean up messages in the code" patch now makes all messages
>       to use proper capitalization of abbreviations. Thanks to Andy Shevchenko
>       and Michał Mirosław for the suggestion.
>
>     - The "Remove unnecessary whitespaces and newlines" patch is transformed
>       into "Clean up whitespaces and newlines", it now also adds missing
>       newlines and spaces.
>
>     - Reworked the "Clean up probe function" patch in accordance to
>       suggestion from Michał Mirosław by factoring out only parts of
>       the code that make error unwinding cleaner.
>
>     - Added r-b from Michał Mirosław.
>
>     - Added more patches:
>
>         i2c: tegra: Reorder location of functions in the code
>         i2c: tegra: Factor out packet header setup from tegra_i2c_xfer_msg()
>         i2c: tegra: Remove "dma" variable
>         i2c: tegra: Initialization div-clk rate unconditionally
>         i2c: tegra: Remove i2c_dev.clk_divisor_non_hs_mode member
>
> v2: - Cleaned more messages in the "Clean up messages in the code" patch.
>
>     - The error code of reset_control_reset() is checked now.
>
>     - Added these new patches to clean up couple more things:
>
>         i2c: tegra: Check errors for both positive and negative values
>         i2c: tegra: Improve coding style of tegra_i2c_wait_for_config_load()
>         i2c: tegra: Remove unnecessary whitespaces and newlines
>         i2c: tegra: Rename variable in tegra_i2c_issue_bus_clear()
>         i2c: tegra: Improve driver module description
>
> Dmitry Osipenko (34):
>   i2c: tegra: Make tegra_i2c_flush_fifos() usable in atomic transfer
>   i2c: tegra: Add missing pm_runtime_put()
>   i2c: tegra: Handle potential error of tegra_i2c_flush_fifos()
>   i2c: tegra: Mask interrupt in tegra_i2c_issue_bus_clear()
>   i2c: tegra: Initialize div-clk rate unconditionally
>   i2c: tegra: Remove i2c_dev.clk_divisor_non_hs_mode member
>   i2c: tegra: Runtime PM always available on Tegra
>   i2c: tegra: Remove error message used for devm_request_irq() failure
>   i2c: tegra: Use reset_control_reset()
>   i2c: tegra: Use devm_platform_get_and_ioremap_resource()
>   i2c: tegra: Use platform_get_irq()
>   i2c: tegra: Use clk-bulk helpers
>   i2c: tegra: Move out all device-tree parsing into tegra_i2c_parse_dt()
>   i2c: tegra: Clean up probe function
>   i2c: tegra: Reorder location of functions in the code
>   i2c: tegra: Clean up variable types
>   i2c: tegra: Remove outdated barrier()
>   i2c: tegra: Remove likely/unlikely from the code
>   i2c: tegra: Remove redundant check in tegra_i2c_issue_bus_clear()
>   i2c: tegra: Remove "dma" variable from tegra_i2c_xfer_msg()
>   i2c: tegra: Don't fall back to PIO mode if DMA configuration fails
>   i2c: tegra: Rename wait/poll functions
>   i2c: tegra: Factor out error recovery from tegra_i2c_xfer_msg()
>   i2c: tegra: Factor out packet header setup from tegra_i2c_xfer_msg()
>   i2c: tegra: Factor out register polling into separate function
>   i2c: tegra: Factor out hardware initialization into separate function
>   i2c: tegra: Check errors for both positive and negative values
>   i2c: tegra: Consolidate error handling in tegra_i2c_xfer_msg()
>   i2c: tegra: Improve formatting of variables
>   i2c: tegra: Clean up variable names
>   i2c: tegra: Clean up printk messages
>   i2c: tegra: Clean up and improve comments
>   i2c: tegra: Clean up whitespaces, newlines and indentation
>   i2c: tegra: Improve driver module description
>
>  drivers/i2c/busses/i2c-tegra.c | 1435 ++++++++++++++++----------------
>  1 file changed, 701 insertions(+), 734 deletions(-)
>
> --
> 2.27.0
>


-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 00/34] Improvements for Tegra I2C driver
  2020-09-09  9:11 ` [PATCH v7 00/34] Improvements for Tegra I2C driver Andy Shevchenko
@ 2020-09-09 15:36   ` Dmitry Osipenko
  2020-09-09 15:49     ` Wolfram Sang
  0 siblings, 1 reply; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-09 15:36 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, linux-i2c, linux-tegra,
	Linux Kernel Mailing List

09.09.2020 12:11, Andy Shevchenko пишет:
> On Wed, Sep 9, 2020 at 1:40 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>>
>> Hello!
>>
>> This series performs refactoring of the Tegra I2C driver code and hardens
>> the atomic-transfer mode.
> 
> I think there is still room for improvement, but let not block it, FWIW,
> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>

Thank you and Michał for helping with the review! Very appreciate this!

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 00/34] Improvements for Tegra I2C driver
  2020-09-09 15:36   ` Dmitry Osipenko
@ 2020-09-09 15:49     ` Wolfram Sang
  2020-09-09 17:39       ` Dmitry Osipenko
  2020-09-17 12:44       ` Thierry Reding
  0 siblings, 2 replies; 146+ messages in thread
From: Wolfram Sang @ 2020-09-09 15:49 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Andy Shevchenko, Thierry Reding, Jonathan Hunter,
	Laxman Dewangan, Michał Mirosław, linux-i2c,
	linux-tegra, Linux Kernel Mailing List

[-- Attachment #1: Type: text/plain, Size: 786 bytes --]

On Wed, Sep 09, 2020 at 06:36:50PM +0300, Dmitry Osipenko wrote:
> 09.09.2020 12:11, Andy Shevchenko пишет:
> > On Wed, Sep 9, 2020 at 1:40 AM Dmitry Osipenko <digetx@gmail.com> wrote:
> >>
> >> Hello!
> >>
> >> This series performs refactoring of the Tegra I2C driver code and hardens
> >> the atomic-transfer mode.
> > 
> > I think there is still room for improvement, but let not block it, FWIW,
> > Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
> 
> Thank you and Michał for helping with the review! Very appreciate this!

Yes, thanks everyone so far!

Is there some internal testfarm where this should be regression tested?
Otherwise, I'd trust Dmitry, Andy, and Michał here and would apply it
this week after some generic high-level review.


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 00/34] Improvements for Tegra I2C driver
  2020-09-09 15:49     ` Wolfram Sang
@ 2020-09-09 17:39       ` Dmitry Osipenko
  2020-09-17 12:44       ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-09 17:39 UTC (permalink / raw)
  To: Wolfram Sang, Andy Shevchenko, Thierry Reding, Jonathan Hunter,
	Laxman Dewangan, Michał Mirosław, linux-i2c,
	linux-tegra, Linux Kernel Mailing List

09.09.2020 18:49, Wolfram Sang пишет:
> On Wed, Sep 09, 2020 at 06:36:50PM +0300, Dmitry Osipenko wrote:
>> 09.09.2020 12:11, Andy Shevchenko пишет:
>>> On Wed, Sep 9, 2020 at 1:40 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>>>>
>>>> Hello!
>>>>
>>>> This series performs refactoring of the Tegra I2C driver code and hardens
>>>> the atomic-transfer mode.
>>>
>>> I think there is still room for improvement, but let not block it, FWIW,
>>> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
>>
>> Thank you and Michał for helping with the review! Very appreciate this!
> 
> Yes, thanks everyone so far!
> 
> Is there some internal testfarm where this should be regression tested?
> Otherwise, I'd trust Dmitry, Andy, and Michał here and would apply it
> this week after some generic high-level review.
> 

Thierry and Jon, would be awesome if you could give this series a test
on T210+. Thanks in advance!

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 01/34] i2c: tegra: Make tegra_i2c_flush_fifos() usable in atomic transfer
  2020-09-08 22:39 ` [PATCH v7 01/34] i2c: tegra: Make tegra_i2c_flush_fifos() usable in atomic transfer Dmitry Osipenko
@ 2020-09-17 11:10   ` Thierry Reding
  2020-09-17 14:57     ` Dmitry Osipenko
  2020-09-21 10:18   ` Thierry Reding
  1 sibling, 1 reply; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 11:10 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2282 bytes --]

On Wed, Sep 09, 2020 at 01:39:33AM +0300, Dmitry Osipenko wrote:
> The tegra_i2c_flush_fifos() shouldn't sleep in atomic transfer and jiffies
> are not updating if interrupts are disabled. Let's switch to use iopoll
> API helpers for register-polling. The iopoll API provides helpers for both
> atomic and non-atomic cases.
> 
> Note that this patch doesn't fix any known problem because normally FIFO
> is flushed at the time of starting a new transfer.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 25 ++++++++++++++++---------
>  1 file changed, 16 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> index 00d3e4d7a01e..ab88cdd70376 100644
> --- a/drivers/i2c/busses/i2c-tegra.c
> +++ b/drivers/i2c/busses/i2c-tegra.c
> @@ -470,9 +470,9 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev)
>  
>  static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
>  {
> -	unsigned long timeout = jiffies + HZ;
> -	unsigned int offset;
> -	u32 mask, val;
> +	u32 mask, val, offset, reg_offset;

Is there are reason why we need reg_offset? Seems to me like we could
simplify this, see below.

> +	void __iomem *addr;
> +	int err;
>  
>  	if (i2c_dev->hw->has_mst_fifo) {
>  		mask = I2C_MST_FIFO_CONTROL_TX_FLUSH |
> @@ -488,12 +488,19 @@ static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
>  	val |= mask;
>  	i2c_writel(i2c_dev, val, offset);
>  
> -	while (i2c_readl(i2c_dev, offset) & mask) {
> -		if (time_after(jiffies, timeout)) {
> -			dev_warn(i2c_dev->dev, "timeout waiting for fifo flush\n");
> -			return -ETIMEDOUT;
> -		}
> -		usleep_range(1000, 2000);
> +	reg_offset = tegra_i2c_reg_addr(i2c_dev, offset);
> +	addr = i2c_dev->base + reg_offset;

Why not just:

	offset = tegra_i2c_reg_offset(i2c_dev, offset);
	addr = i2c_dev->base + offset;

or even just:

	addr = i2c_dev->base + tegra_i2c_reg_offset(i2c_dev, offset);

? That makes the patch much smaller because you don't have to rewrite
the whole variable declaration block and just add the "addr" and "err"
variables while removing "timeout".

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 02/34] i2c: tegra: Add missing pm_runtime_put()
  2020-09-08 22:39 ` [PATCH v7 02/34] i2c: tegra: Add missing pm_runtime_put() Dmitry Osipenko
@ 2020-09-17 11:12   ` Thierry Reding
  2020-09-21 10:18   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 11:12 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 610 bytes --]

On Wed, Sep 09, 2020 at 01:39:34AM +0300, Dmitry Osipenko wrote:
> The pm_runtime_get_sync() always bumps refcount regardless of whether it
> succeeds or fails. Hence driver is responsible for restoring of the RPM
> refcounting. This patch adds missing RPM puts which restore refcounting
> in a case of pm_runtime_get_sync() error.
> 
> Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 03/34] i2c: tegra: Handle potential error of tegra_i2c_flush_fifos()
  2020-09-08 22:39 ` [PATCH v7 03/34] i2c: tegra: Handle potential error of tegra_i2c_flush_fifos() Dmitry Osipenko
@ 2020-09-17 11:13   ` Thierry Reding
  2020-09-21 10:18   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 11:13 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1135 bytes --]

On Wed, Sep 09, 2020 at 01:39:35AM +0300, Dmitry Osipenko wrote:
> Technically the tegra_i2c_flush_fifos() may fail and transfer should be
> aborted in this case, but this shouldn't ever happen in practice unless
> there is a bug somewhere in the driver. Let's add the error check just
> for completeness.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)

Reviewed-by: Thierry Reding <treding@nvidia.com>

> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> index 4e7d0eec0dd3..88d6e7bb14a2 100644
> --- a/drivers/i2c/busses/i2c-tegra.c
> +++ b/drivers/i2c/busses/i2c-tegra.c
> @@ -1177,7 +1177,9 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
>  	bool dma;
>  	u16 xfer_time = 100;
>  
> -	tegra_i2c_flush_fifos(i2c_dev);
> +	err = tegra_i2c_flush_fifos(i2c_dev);
> +	if (err)
> +		return err;
>  
>  	i2c_dev->msg_buf = msg->buf;
>  	i2c_dev->msg_buf_remaining = msg->len;
> -- 
> 2.27.0
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 04/34] i2c: tegra: Mask interrupt in tegra_i2c_issue_bus_clear()
  2020-09-08 22:39 ` [PATCH v7 04/34] i2c: tegra: Mask interrupt in tegra_i2c_issue_bus_clear() Dmitry Osipenko
@ 2020-09-17 11:18   ` Thierry Reding
  2020-09-21 10:18   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 11:18 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 436 bytes --]

On Wed, Sep 09, 2020 at 01:39:36AM +0300, Dmitry Osipenko wrote:
> The tegra_i2c_issue_bus_clear() may fail and in this case BUS_CLR_DONE
> stays unmasked. Hence let's mask it for consistency. This patch doesn't
> fix any known problems.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 2 ++
>  1 file changed, 2 insertions(+)

Reviewed-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 05/34] i2c: tegra: Initialize div-clk rate unconditionally
  2020-09-08 22:39 ` [PATCH v7 05/34] i2c: tegra: Initialize div-clk rate unconditionally Dmitry Osipenko
@ 2020-09-17 11:20   ` Thierry Reding
  2020-09-21 10:18   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 11:20 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 633 bytes --]

On Wed, Sep 09, 2020 at 01:39:37AM +0300, Dmitry Osipenko wrote:
> It doesn't make sense to conditionalize the div-clk rate changes because
> rate is fixed and it won't ever change once it's set at the driver's probe
> time. All further changes are NO-OPs because CCF caches rate and skips
> rate-change if rate is unchanged.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 34 ++++++++++++++++------------------
>  1 file changed, 16 insertions(+), 18 deletions(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 06/34] i2c: tegra: Remove i2c_dev.clk_divisor_non_hs_mode member
  2020-09-08 22:39 ` [PATCH v7 06/34] i2c: tegra: Remove i2c_dev.clk_divisor_non_hs_mode member Dmitry Osipenko
@ 2020-09-17 11:25   ` Thierry Reding
  2020-09-17 15:27     ` Dmitry Osipenko
  2020-09-21 10:18   ` Thierry Reding
  1 sibling, 1 reply; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 11:25 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2555 bytes --]

On Wed, Sep 09, 2020 at 01:39:38AM +0300, Dmitry Osipenko wrote:
> The "non_hs_mode" divisor value is fixed, thus there is no need to have
> the variable i2c_dev.clk_divisor_non_hs_mode struct member. Let's remove
> it and move the mode selection into tegra_i2c_init() where it can be
> united with the timing selection.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 46 ++++++++++++++++------------------
>  1 file changed, 21 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> index 720a75439e91..85ed0e02d48c 100644
> --- a/drivers/i2c/busses/i2c-tegra.c
> +++ b/drivers/i2c/busses/i2c-tegra.c
> @@ -250,7 +250,6 @@ struct tegra_i2c_hw_feature {
>   * @msg_buf_remaining: size of unsent data in the message buffer
>   * @msg_read: identifies read transfers
>   * @bus_clk_rate: current I2C bus clock rate
> - * @clk_divisor_non_hs_mode: clock divider for non-high-speed modes
>   * @is_multimaster_mode: track if I2C controller is in multi-master mode
>   * @tx_dma_chan: DMA transmit channel
>   * @rx_dma_chan: DMA receive channel
> @@ -281,7 +280,6 @@ struct tegra_i2c_dev {
>  	size_t msg_buf_remaining;
>  	int msg_read;
>  	u32 bus_clk_rate;
> -	u16 clk_divisor_non_hs_mode;
>  	bool is_multimaster_mode;
>  	struct dma_chan *tx_dma_chan;
>  	struct dma_chan *rx_dma_chan;
> @@ -783,6 +781,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
>  	u32 val;
>  	int err;
>  	u32 clk_divisor, clk_multiplier;
> +	u32 non_hs_mode;
>  	u32 tsu_thd;
>  	u8 tlow, thigh;
>  
> @@ -805,24 +804,33 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
>  	if (i2c_dev->is_vi)
>  		tegra_i2c_vi_init(i2c_dev);
>  
> -	/* Make sure clock divisor programmed correctly */
> -	clk_divisor = FIELD_PREP(I2C_CLK_DIVISOR_HSMODE,
> -				 i2c_dev->hw->clk_divisor_hs_mode) |
> -		      FIELD_PREP(I2C_CLK_DIVISOR_STD_FAST_MODE,
> -				 i2c_dev->clk_divisor_non_hs_mode);
> -	i2c_writel(i2c_dev, clk_divisor, I2C_CLK_DIVISOR);
> -
> -	if (i2c_dev->bus_clk_rate > I2C_MAX_STANDARD_MODE_FREQ &&
> -	    i2c_dev->bus_clk_rate <= I2C_MAX_FAST_MODE_PLUS_FREQ) {
> +	switch (i2c_dev->bus_clk_rate) {
> +	case I2C_MAX_STANDARD_MODE_FREQ + 1 ... I2C_MAX_FAST_MODE_PLUS_FREQ:

Is there are particular reason for switching the simple conditional to a
switch here? The old variant looks much easier to understand to me.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 07/34] i2c: tegra: Runtime PM always available on Tegra
  2020-09-08 22:39 ` [PATCH v7 07/34] i2c: tegra: Runtime PM always available on Tegra Dmitry Osipenko
@ 2020-09-17 11:26   ` Thierry Reding
  2020-09-21 10:18   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 11:26 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 582 bytes --]

On Wed, Sep 09, 2020 at 01:39:39AM +0300, Dmitry Osipenko wrote:
> The runtime PM is guaranteed to be always available on Tegra after commit
> 40b2bb1b132a ("ARM: tegra: enforce PM requirement"). Hence let's remove
> all the RPM-availability checking and handling from the code.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 29 ++++++-----------------------
>  1 file changed, 6 insertions(+), 23 deletions(-)

Reviewed-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 08/34] i2c: tegra: Remove error message used for devm_request_irq() failure
  2020-09-08 22:39 ` [PATCH v7 08/34] i2c: tegra: Remove error message used for devm_request_irq() failure Dmitry Osipenko
@ 2020-09-17 11:28   ` Thierry Reding
  2020-09-17 14:59     ` Dmitry Osipenko
  2020-09-21 10:18   ` Thierry Reding
  1 sibling, 1 reply; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 11:28 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1509 bytes --]

On Wed, Sep 09, 2020 at 01:39:40AM +0300, Dmitry Osipenko wrote:
> The error message prints number of vIRQ, which isn't a useful information.
> In practice devm_request_irq() never fails, hence let's remove the bogus
> message in order to make code cleaner.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)

I think I have seen this fail occasionally when something's wrong in the
IRQ code, or when we are not properly configuring the IRQ in device tree
for example.

So I'd prefer if this error message stayed here. I agree that it's not a
terribly useful error message, so perhaps adding the error code to it
would make it more helpful?

Thierry

> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> index a52c72135390..b813c0976c10 100644
> --- a/drivers/i2c/busses/i2c-tegra.c
> +++ b/drivers/i2c/busses/i2c-tegra.c
> @@ -1807,10 +1807,8 @@ static int tegra_i2c_probe(struct platform_device *pdev)
>  
>  	ret = devm_request_irq(&pdev->dev, i2c_dev->irq, tegra_i2c_isr,
>  			       IRQF_NO_SUSPEND, dev_name(&pdev->dev), i2c_dev);
> -	if (ret) {
> -		dev_err(&pdev->dev, "Failed to request irq %i\n", i2c_dev->irq);
> +	if (ret)
>  		goto release_dma;
> -	}
>  
>  	i2c_set_adapdata(&i2c_dev->adapter, i2c_dev);
>  	i2c_dev->adapter.owner = THIS_MODULE;
> -- 
> 2.27.0
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 11/34] i2c: tegra: Use platform_get_irq()
  2020-09-08 22:39 ` [PATCH v7 11/34] i2c: tegra: Use platform_get_irq() Dmitry Osipenko
@ 2020-09-17 11:31   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 11:31 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 494 bytes --]

On Wed, Sep 09, 2020 at 01:39:43AM +0300, Dmitry Osipenko wrote:
> Use common helper for retrieval of the interrupt number in order to make
> code cleaner. Note that platform_get_irq() prints error message by itself.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 9 +++------
>  1 file changed, 3 insertions(+), 6 deletions(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 10/34] i2c: tegra: Use devm_platform_get_and_ioremap_resource()
  2020-09-08 22:39 ` [PATCH v7 10/34] i2c: tegra: Use devm_platform_get_and_ioremap_resource() Dmitry Osipenko
@ 2020-09-17 11:31   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 11:31 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 468 bytes --]

On Wed, Sep 09, 2020 at 01:39:42AM +0300, Dmitry Osipenko wrote:
> Driver now uses devm_platform_get_and_ioremap_resource() which replaces
> the typical boilerplate code and makes code cleaner.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 13/34] i2c: tegra: Move out all device-tree parsing into tegra_i2c_parse_dt()
  2020-09-08 22:39 ` [PATCH v7 13/34] i2c: tegra: Move out all device-tree parsing into tegra_i2c_parse_dt() Dmitry Osipenko
@ 2020-09-17 11:35   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 11:35 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 482 bytes --]

On Wed, Sep 09, 2020 at 01:39:45AM +0300, Dmitry Osipenko wrote:
> Move out code related to device-tree parsing from the probe function into
> tegra_i2c_parse_dt() in order to make code more consistent.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 12/34] i2c: tegra: Use clk-bulk helpers
  2020-09-08 22:39 ` [PATCH v7 12/34] i2c: tegra: Use clk-bulk helpers Dmitry Osipenko
@ 2020-09-17 11:38   ` Thierry Reding
  2020-09-17 13:54     ` Andy Shevchenko
  2020-09-17 15:01     ` Dmitry Osipenko
  2020-09-21 10:19   ` Thierry Reding
  1 sibling, 2 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 11:38 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1371 bytes --]

On Wed, Sep 09, 2020 at 01:39:44AM +0300, Dmitry Osipenko wrote:
> Use clk-bulk helpers and factor out clocks initialization into separate
> function in order to make code cleaner.
> 
> The clocks initialization now performed after reset-control initialization
> in order to avoid a noisy -PROBE_DEFER errors on T186+ from the clk-bulk
> helper which doesn't silence this error code. Hence reset_control_get()
> now may return -EPROBE_DEFER on newer Tegra SoCs because they use BPMP
> driver that provides reset controls and BPMP doesn't come up early during
> boot. Previously rst was protected by the clocks retrieval and now this
> patch makes dev_err_probe() to be used for the rst error handling.
> 
> Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 187 ++++++++++++---------------------
>  1 file changed, 67 insertions(+), 120 deletions(-)

This is tempting from a diffstat point of view, but the downside is that
we can now no longer validate that all of the necessary clocks are given
in device tree.

Previously the driver would fail to probe the I2C controller if any of
the expected clocks were not defined in device tree, but now it's just
going to continue without it and not give any indication as to what's
wrong.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 20/34] i2c: tegra: Remove "dma" variable from tegra_i2c_xfer_msg()
  2020-09-08 22:39 ` [PATCH v7 20/34] i2c: tegra: Remove "dma" variable from tegra_i2c_xfer_msg() Dmitry Osipenko
@ 2020-09-17 11:44   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 11:44 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 846 bytes --]

On Wed, Sep 09, 2020 at 01:39:52AM +0300, Dmitry Osipenko wrote:
> The "dma" variable of tegra_i2c_xfer_msg() function doesn't bring much in
> regards to readability and generation of the code.
> 
> Besides readability, it's also not very nice that the is_curr_dma_xfer
> is initialized in tegra_i2c_xfer_msg() and then could be overridden by
> tegra_i2c_config_fifo_trig(). In a result, the "dma" variable creates
> slight confusion since it's not instantly obvious why it's set after
> tegra_i2c_config_fifo_trig().
> 
> Hence should be better to have the variable removed. This makes code
> more consistent.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 17 ++++++++---------
>  1 file changed, 8 insertions(+), 9 deletions(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 21/34] i2c: tegra: Don't fall back to PIO mode if DMA configuration fails
  2020-09-08 22:39 ` [PATCH v7 21/34] i2c: tegra: Don't fall back to PIO mode if DMA configuration fails Dmitry Osipenko
@ 2020-09-17 11:47   ` Thierry Reding
  2020-09-17 15:03     ` Dmitry Osipenko
  2020-09-21 10:19   ` Thierry Reding
  1 sibling, 1 reply; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 11:47 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 879 bytes --]

On Wed, Sep 09, 2020 at 01:39:53AM +0300, Dmitry Osipenko wrote:
> The DMA code path has been tested well enough and the DMA configuration
> performed by tegra_i2c_config_fifo_trig() shouldn't ever fail in practice.
> Hence let's remove the obscure transfer-mode switching in order to have a
> cleaner and simpler code. Now I2C transfer will be failed if DMA
> configuration fails.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 18 ++++++++++--------
>  1 file changed, 10 insertions(+), 8 deletions(-)

I'm not sure that's a good idea. It's always possible that the DMA setup
is going to break because of something that's not related to the I2C
driver itself. Having the system completely break instead of falling
back to PIO mode seems like it would only complicate troubleshooting any
such issues.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 22/34] i2c: tegra: Rename wait/poll functions
  2020-09-08 22:39 ` [PATCH v7 22/34] i2c: tegra: Rename wait/poll functions Dmitry Osipenko
@ 2020-09-17 11:48   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 11:48 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 572 bytes --]

On Wed, Sep 09, 2020 at 01:39:54AM +0300, Dmitry Osipenko wrote:
> Drop '_timeout' postfix from the wait/poll completion function names in
> order to make the names shorter, making code cleaner a tad.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 32 ++++++++++++++------------------
>  1 file changed, 14 insertions(+), 18 deletions(-)

Not sure this is really worth it, but I don't feel strongly, so:

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 23/34] i2c: tegra: Factor out error recovery from tegra_i2c_xfer_msg()
  2020-09-08 22:39 ` [PATCH v7 23/34] i2c: tegra: Factor out error recovery from tegra_i2c_xfer_msg() Dmitry Osipenko
@ 2020-09-17 11:49   ` Thierry Reding
  2020-09-21 10:20   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 11:49 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 489 bytes --]

On Wed, Sep 09, 2020 at 01:39:55AM +0300, Dmitry Osipenko wrote:
> Factor out error recovery code from tegra_i2c_xfer_msg() in order to
> make this function easier to read and follow.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 46 ++++++++++++++++++++++------------
>  1 file changed, 30 insertions(+), 16 deletions(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 24/34] i2c: tegra: Factor out packet header setup from tegra_i2c_xfer_msg()
  2020-09-08 22:39 ` [PATCH v7 24/34] i2c: tegra: Factor out packet header setup " Dmitry Osipenko
@ 2020-09-17 11:51   ` Thierry Reding
  2020-09-21 10:20   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 11:51 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 647 bytes --]

On Wed, Sep 09, 2020 at 01:39:56AM +0300, Dmitry Osipenko wrote:
> The code related to packet header setting up is a bit messy and makes
> tegra_i2c_xfer_msg() more difficult to read than it could be. Let's
> factor the packet header setup from tegra_i2c_xfer_msg() into separate
> function in order to make code easier to read and follow.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 92 ++++++++++++++++++++--------------
>  1 file changed, 53 insertions(+), 39 deletions(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 25/34] i2c: tegra: Factor out register polling into separate function
  2020-09-08 22:39 ` [PATCH v7 25/34] i2c: tegra: Factor out register polling into separate function Dmitry Osipenko
@ 2020-09-17 11:58   ` Thierry Reding
  2020-09-17 15:05     ` Dmitry Osipenko
  2020-09-21 10:20   ` Thierry Reding
  1 sibling, 1 reply; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 11:58 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 3649 bytes --]

On Wed, Sep 09, 2020 at 01:39:57AM +0300, Dmitry Osipenko wrote:
> Factor out register polling into a separate function in order to remove
> boilerplate code and make code cleaner.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 57 +++++++++++++++-------------------
>  1 file changed, 25 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> index 405b87e28a98..e071de9ce106 100644
> --- a/drivers/i2c/busses/i2c-tegra.c
> +++ b/drivers/i2c/busses/i2c-tegra.c
> @@ -514,10 +514,24 @@ static void tegra_i2c_vi_init(struct tegra_i2c_dev *i2c_dev)
>  	i2c_writel(i2c_dev, 0x0, I2C_TLOW_SEXT);
>  }
>  
> +static int tegra_i2c_poll_register(struct tegra_i2c_dev *i2c_dev,
> +				   u32 reg, u32 mask, u32 delay_us,
> +				   u32 timeout_us)
> +{
> +	void __iomem *addr = i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg);
> +	u32 val;
> +
> +	if (!i2c_dev->is_curr_atomic_xfer)
> +		return readl_relaxed_poll_timeout(addr, val, !(val & mask),
> +						  delay_us, timeout_us);
> +
> +	return readl_relaxed_poll_timeout_atomic(addr, val, !(val & mask),
> +						 delay_us, timeout_us);
> +}
> +
>  static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
>  {
> -	u32 mask, val, offset, reg_offset;
> -	void __iomem *addr;
> +	u32 mask, val, offset;
>  	int err;
>  
>  	if (i2c_dev->hw->has_mst_fifo) {
> @@ -534,16 +548,7 @@ static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
>  	val |= mask;
>  	i2c_writel(i2c_dev, val, offset);
>  
> -	reg_offset = tegra_i2c_reg_addr(i2c_dev, offset);
> -	addr = i2c_dev->base + reg_offset;
> -
> -	if (i2c_dev->is_curr_atomic_xfer)
> -		err = readl_relaxed_poll_timeout_atomic(addr, val, !(val & mask),
> -							1000, 1000000);
> -	else
> -		err = readl_relaxed_poll_timeout(addr, val, !(val & mask),
> -						 1000, 1000000);
> -
> +	err = tegra_i2c_poll_register(i2c_dev, offset, mask, 1000, 1000000);
>  	if (err) {
>  		dev_err(i2c_dev->dev, "failed to flush FIFO\n");
>  		return err;
> @@ -553,30 +558,18 @@ static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
>  
>  static int tegra_i2c_wait_for_config_load(struct tegra_i2c_dev *i2c_dev)
>  {
> -	unsigned long reg_offset;
> -	void __iomem *addr;
> -	u32 val;
>  	int err;
>  
> -	if (i2c_dev->hw->has_config_load_reg) {
> -		reg_offset = tegra_i2c_reg_addr(i2c_dev, I2C_CONFIG_LOAD);
> -		addr = i2c_dev->base + reg_offset;
> -		i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, I2C_CONFIG_LOAD);
> +	if (!i2c_dev->hw->has_config_load_reg)
> +		return 0;
>  
> -		if (i2c_dev->is_curr_atomic_xfer)
> -			err = readl_relaxed_poll_timeout_atomic(
> -						addr, val, val == 0, 1000,
> -						I2C_CONFIG_LOAD_TIMEOUT);
> -		else
> -			err = readl_relaxed_poll_timeout(
> -						addr, val, val == 0, 1000,
> -						I2C_CONFIG_LOAD_TIMEOUT);
> +	i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, I2C_CONFIG_LOAD);
>  
> -		if (err) {
> -			dev_warn(i2c_dev->dev,
> -				 "timeout waiting for config load\n");
> -			return err;
> -		}
> +	err = tegra_i2c_poll_register(i2c_dev, I2C_CONFIG_LOAD, 0xffffffff,
> +				      1000, I2C_CONFIG_LOAD_TIMEOUT);
> +	if (err) {
> +		dev_warn(i2c_dev->dev, "timeout waiting for config load\n");
> +		return err;
>  	}

The deindentation in this hunk is messing up the diffstat in my opinion.
It would probably be worth splitting that into a separate patch to make
it more evident that this patch actually removes boilerplate.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 26/34] i2c: tegra: Factor out hardware initialization into separate function
  2020-09-08 22:39 ` [PATCH v7 26/34] i2c: tegra: Factor out hardware initialization " Dmitry Osipenko
@ 2020-09-17 12:06   ` Thierry Reding
  2020-09-21 10:20   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 12:06 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 727 bytes --]

On Wed, Sep 09, 2020 at 01:39:58AM +0300, Dmitry Osipenko wrote:
> Factor out hardware initialization into a separate function from the probe
> function. The only place where runtime PM needs to be resumed during probe
> is the place of hardware initialization, hence it makes sense to factor
> out it in order to have a bit cleaner error handling in tegra_i2c_probe().
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 32 +++++++++++++++++++-------------
>  1 file changed, 19 insertions(+), 13 deletions(-)

Not really sure this is worth it, but since I don't feel strongly, I'll
leave this up to Wolfram to decide:

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 27/34] i2c: tegra: Check errors for both positive and negative values
  2020-09-08 22:39 ` [PATCH v7 27/34] i2c: tegra: Check errors for both positive and negative values Dmitry Osipenko
@ 2020-09-17 12:09   ` Thierry Reding
  2020-09-17 13:50     ` Andy Shevchenko
  2020-09-21 10:20   ` Thierry Reding
  1 sibling, 1 reply; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 12:09 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1011 bytes --]

On Wed, Sep 09, 2020 at 01:39:59AM +0300, Dmitry Osipenko wrote:
> The driver's code is inconsistent in regards to the error values checking.
> The correct way should be to check both positive and negative values.
> This patch cleans up the error-checks in the code. Note that the
> pm_runtime_get_sync() could return positive value on success, hence only
> relevant parts of the code are changed by this patch.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)

Why? All of these functions "return 0 on success or a negative error
code on failure", don't they?

I would actually argue that all of the other checks are wrong. As you
mention yourself, some functions may decide to return positive values on
success to convey some extra information, so making this just check for
non-zero carries a risk of its own.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 28/34] i2c: tegra: Consolidate error handling in tegra_i2c_xfer_msg()
  2020-09-08 22:40 ` [PATCH v7 28/34] i2c: tegra: Consolidate error handling in tegra_i2c_xfer_msg() Dmitry Osipenko
@ 2020-09-17 12:12   ` Thierry Reding
  2020-09-21 10:20   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 12:12 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 669 bytes --]

On Wed, Sep 09, 2020 at 01:40:00AM +0300, Dmitry Osipenko wrote:
> Consolidate error handling in tegra_i2c_xfer_msg() into a common code
> path in order to make code cleaner.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 13 +++++++++----
>  1 file changed, 9 insertions(+), 4 deletions(-)

I'm really not sure this is cleaner. You've got a net positive diffstat
and you add goto. That's not always bad, but in this case there is no
need for any complicated error unwinding, so I don't think this is any
better than the previous code.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 29/34] i2c: tegra: Improve formatting of variables
  2020-09-08 22:40 ` [PATCH v7 29/34] i2c: tegra: Improve formatting of variables Dmitry Osipenko
@ 2020-09-17 12:16   ` Thierry Reding
  2020-09-17 15:13     ` Dmitry Osipenko
  2020-09-21 10:20   ` Thierry Reding
  1 sibling, 1 reply; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 12:16 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2490 bytes --]

On Wed, Sep 09, 2020 at 01:40:01AM +0300, Dmitry Osipenko wrote:
> Reorder definition of variables in the code to have them sorted by length
> and grouped logically, also replace "unsigned long" with "u32". Do this in
> order to make code easier to read.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 97 ++++++++++++++++------------------
>  1 file changed, 45 insertions(+), 52 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> index ac40c87f1c21..2376f502d299 100644
> --- a/drivers/i2c/busses/i2c-tegra.c
> +++ b/drivers/i2c/busses/i2c-tegra.c
> @@ -259,42 +259,48 @@ struct tegra_i2c_hw_feature {
>   */
>  struct tegra_i2c_dev {
>  	struct device *dev;
> -	const struct tegra_i2c_hw_feature *hw;
>  	struct i2c_adapter adapter;
> -	struct clk *div_clk;
> -	struct clk_bulk_data *clocks;
> -	unsigned int nclocks;
> +
> +	const struct tegra_i2c_hw_feature *hw;
>  	struct reset_control *rst;
> -	void __iomem *base;
> -	phys_addr_t base_phys;
>  	unsigned int cont_id;
>  	unsigned int irq;
> -	bool is_dvc;
> -	bool is_vi;
> +
> +	phys_addr_t base_phys;
> +	void __iomem *base;
> +
> +	struct clk_bulk_data *clocks;
> +	unsigned int nclocks;
> +
> +	struct clk *div_clk;
> +	u32 bus_clk_rate;
> +
>  	struct completion msg_complete;
> +	size_t msg_buf_remaining;
>  	int msg_err;
>  	u8 *msg_buf;
> -	size_t msg_buf_remaining;
> -	bool msg_read;
> -	u32 bus_clk_rate;
> -	bool is_multimaster_mode;
> +
> +	struct completion dma_complete;
>  	struct dma_chan *tx_dma_chan;
>  	struct dma_chan *rx_dma_chan;
> +	unsigned int dma_buf_size;
>  	dma_addr_t dma_phys;
>  	u32 *dma_buf;
> -	unsigned int dma_buf_size;
> -	bool is_curr_dma_xfer;
> -	struct completion dma_complete;
> +
> +	bool is_multimaster_mode;
>  	bool is_curr_atomic_xfer;
> +	bool is_curr_dma_xfer;
> +	bool msg_read;
> +	bool is_dvc;
> +	bool is_vi;
>  };
>  
> -static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val,
> -		       unsigned long reg)
> +static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val, u32 reg)

I actually prefer unsigned long/int over u32 for offsets because it
makes it clearer that this is not in fact a 32-bit value that we're
writing into a register. This is especially true for these register
accessors where the "offset" is called "reg" and may be easily
mistaken for a register value.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 30/34] i2c: tegra: Clean up variable names
  2020-09-08 22:40 ` [PATCH v7 30/34] i2c: tegra: Clean up variable names Dmitry Osipenko
@ 2020-09-17 12:21   ` Thierry Reding
  2020-09-17 15:43     ` Dmitry Osipenko
  2020-09-21 10:20   ` Thierry Reding
  1 sibling, 1 reply; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 12:21 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1814 bytes --]

On Wed, Sep 09, 2020 at 01:40:02AM +0300, Dmitry Osipenko wrote:
> Rename "ret" variables to "err" in order to make code a bit more
> expressive, emphasizing that the returned value is an error code.
> Same vice versa, where appropriate.
> 
> Rename variable "reg" to "val" in order to better reflect the actual
> usage of the variable in the code and to make naming consistent with
> the rest of the code.
> 
> Use briefer names for a few members of the tegra_i2c_dev structure in
> order to improve readability of the code.
> 
> All dev/&pdev->dev are replaced with i2c_dev->dev in order to have uniform
> code style across the driver.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 173 ++++++++++++++++-----------------
>  1 file changed, 86 insertions(+), 87 deletions(-)

That's indeed a nice improvement. One thing did spring out at me,
though.

> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
[...]
> @@ -1831,20 +1830,20 @@ static int __maybe_unused tegra_i2c_runtime_suspend(struct device *dev)
>  
>  	clk_bulk_disable(i2c_dev->nclocks, i2c_dev->clocks);
>  
> -	return pinctrl_pm_select_idle_state(i2c_dev->dev);
> +	return pinctrl_pm_select_idle_state(dev);
>  }
>  
>  static int __maybe_unused tegra_i2c_suspend(struct device *dev)
>  {
>  	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
> -	int err = 0;
> +	int ret = 0;
>  
>  	i2c_mark_adapter_suspended(&i2c_dev->adapter);
>  
>  	if (!pm_runtime_status_suspended(dev))
> -		err = tegra_i2c_runtime_suspend(dev);
> +		ret = tegra_i2c_runtime_suspend(dev);
>  
> -	return err;
> +	return ret;
>  }

Isn't this exactly the opposite of what the commit message says (and the
rest of the patch does)?

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 31/34] i2c: tegra: Clean up printk messages
  2020-09-08 22:40 ` [PATCH v7 31/34] i2c: tegra: Clean up printk messages Dmitry Osipenko
@ 2020-09-17 12:22   ` Thierry Reding
  2020-09-21 10:20   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 12:22 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 539 bytes --]

On Wed, Sep 09, 2020 at 01:40:03AM +0300, Dmitry Osipenko wrote:
> This patch unifies style of all messages in the driver by starting them
> with a lowercase letter and using consistent capitalization and wording
> for all messages.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 37 +++++++++++++---------------------
>  1 file changed, 14 insertions(+), 23 deletions(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 32/34] i2c: tegra: Clean up and improve comments
  2020-09-08 22:40 ` [PATCH v7 32/34] i2c: tegra: Clean up and improve comments Dmitry Osipenko
@ 2020-09-17 12:32   ` Thierry Reding
  2020-09-17 15:02     ` Dmitry Osipenko
  2020-09-21 10:20   ` Thierry Reding
  1 sibling, 1 reply; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 12:32 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 3963 bytes --]

On Wed, Sep 09, 2020 at 01:40:04AM +0300, Dmitry Osipenko wrote:
> Make all comments to be consistent in regards to capitalization and
> punctuation, correct spelling and grammar errors, improve wording.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 88 ++++++++++++++++++----------------
>  1 file changed, 47 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> index 558b1f2934a0..31fbc6181dd5 100644
> --- a/drivers/i2c/busses/i2c-tegra.c
> +++ b/drivers/i2c/busses/i2c-tegra.c
> @@ -136,7 +136,7 @@
>  /* configuration load timeout in microseconds */
>  #define I2C_CONFIG_LOAD_TIMEOUT			1000000
>  
> -/* Packet header size in bytes */
> +/* packet header size in bytes */
>  #define I2C_PACKET_HEADER_SIZE			12
>  
>  /*
> @@ -148,11 +148,10 @@
>  #define I2C_PIO_MODE_PREFERRED_LEN		32
>  
>  /*
> - * 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.
> + * msg_end_type: The bus control which needs to be sent at end of transfer.
> + * @MSG_END_STOP: Send stop pulse.
> + * @MSG_END_REPEAT_START: Send repeat-start.
> + * @MSG_END_CONTINUE: Don't send stop or repeat-start.
>   */
>  enum msg_end_type {
>  	MSG_END_STOP,
> @@ -161,10 +160,10 @@ 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 : per hardware generation features

I think that space before ':' can go away. Although that's preexisting,
so could also be a separate patch, I guess.

> + * @has_continue_xfer_support: Continue-transfer supported.

This isn't a proper sentence, so I don't think it should have a
full-stop. And it shouldn't start with an uppercase letter, either.

>   * @has_per_pkt_xfer_complete_irq: Has enable/disable capability for transfer
> - *		complete interrupt per packet basis.
> + *		completion interrupt on per packet basis.
>   * @has_config_load_reg: Has the config load register to load the new
>   *		configuration.
>   * @clk_divisor_hs_mode: Clock divisor in HS mode.
> @@ -184,7 +183,7 @@ enum msg_end_type {
>   * @has_mst_fifo: The I2C controller contains the new MST FIFO interface that
>   *		provides additional features and allows for longer messages to
>   *		be transferred in one go.
> - * @quirks: i2c adapter quirks for limiting write/read transfer size and not
> + * @quirks: I2C adapter quirks for limiting write/read transfer size and not
>   *		allowing 0 length transfers.
>   * @supports_bus_clear: Bus Clear support to recover from bus hang during
>   *		SDA stuck low from device for some unknown reasons.
> @@ -245,7 +244,7 @@ struct tegra_i2c_hw_feature {
>   * @msg_err: error code for completed message
>   * @msg_buf: pointer to current message data
>   * @msg_buf_remaining: size of unsent data in the message buffer
> - * @msg_read: identifies read transfers
> + * @msg_read: indicates read direction of a transfer

Hm... "read" is the "direction". Perhaps "indicates the direction of a
transfer"? Or perhaps "indicates that the transfer is a read access"?

[...]
> @@ -1797,9 +1804,8 @@ static int __maybe_unused tegra_i2c_runtime_resume(struct device *dev)
>  
>  	/*
>  	 * VI I2C device is attached to VE power domain which goes through
> -	 * power ON/OFF during PM runtime resume/suspend. So, controller
> -	 * should go through reset and need to re-initialize after power
> -	 * domain ON.
> +	 * power ON/OFF during of runtime PM resume/suspend, meaning that

s/during of runtime PM/during runtime PM/

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 33/34] i2c: tegra: Clean up whitespaces, newlines and indentation
  2020-09-08 22:40 ` [PATCH v7 33/34] i2c: tegra: Clean up whitespaces, newlines and indentation Dmitry Osipenko
@ 2020-09-17 12:35   ` Thierry Reding
  2020-09-21 10:20   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 12:35 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 4139 bytes --]

On Wed, Sep 09, 2020 at 01:40:05AM +0300, Dmitry Osipenko wrote:
> Some places in the code are missing newlines or have unnecessary
> whitespaces and newlines. This creates inconsistency of the code and
> hurts readability. This patch removes the unnecessary and adds necessary
> whitespaces / newlines, clears indentation of the code.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 72 +++++++++++++++++++++-------------
>  1 file changed, 45 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> index 31fbc6181dd5..087f98010963 100644
> --- a/drivers/i2c/busses/i2c-tegra.c
> +++ b/drivers/i2c/busses/i2c-tegra.c
> @@ -314,6 +314,7 @@ static u32 tegra_i2c_reg_addr(struct tegra_i2c_dev *i2c_dev, u32 reg)
>  		reg += (reg >= I2C_TX_FIFO) ? 0x10 : 0x40;
>  	else if (i2c_dev->is_vi)
>  		reg = 0xc00 + (reg << 2);
> +
>  	return reg;
>  }
>  
> @@ -373,9 +374,12 @@ static int tegra_i2c_dma_submit(struct tegra_i2c_dev *i2c_dev, size_t len)
>  	struct dma_chan *chan;
>  
>  	dev_dbg(i2c_dev->dev, "starting DMA for length: %zu\n", len);
> +
>  	reinit_completion(&i2c_dev->dma_complete);
> +
>  	dir = i2c_dev->msg_read ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV;
>  	chan = i2c_dev->msg_read ? i2c_dev->rx_dma_chan : i2c_dev->tx_dma_chan;
> +
>  	dma_desc = dmaengine_prep_slave_single(chan, i2c_dev->dma_phys,
>  					       len, dir, DMA_PREP_INTERRUPT |
>  					       DMA_CTRL_ACK);
> @@ -387,8 +391,10 @@ static int tegra_i2c_dma_submit(struct tegra_i2c_dev *i2c_dev, size_t len)
>  
>  	dma_desc->callback = tegra_i2c_dma_complete;
>  	dma_desc->callback_param = i2c_dev;
> +
>  	dmaengine_submit(dma_desc);
>  	dma_async_issue_pending(chan);
> +
>  	return 0;
>  }
>  
> @@ -455,6 +461,7 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev)
>  
>  	i2c_dev->dma_buf = dma_buf;
>  	i2c_dev->dma_phys = dma_phys;
> +
>  	return 0;
>  
>  err_out:
> @@ -557,6 +564,7 @@ static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
>  		dev_err(i2c_dev->dev, "failed to flush FIFO\n");
>  		return err;
>  	}
> +
>  	return 0;
>  }
>  
> @@ -650,8 +658,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
>  	if (i2c_dev->hw->has_interface_timing_reg && tsu_thd)
>  		i2c_writel(i2c_dev, tsu_thd, I2C_INTERFACE_TIMING_1);
>  
> -	clk_multiplier  = tlow + thigh + 2;
> -	clk_multiplier *= non_hs_mode + 1;
> +	clk_multiplier = (tlow + thigh + 2) * (non_hs_mode + 1);
>  
>  	err = clk_set_rate(i2c_dev->div_clk,
>  			   i2c_dev->bus_clk_rate * clk_multiplier);
> @@ -799,9 +806,9 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
>  		 */
>  		buf_remaining -= words_to_transfer * BYTES_PER_FIFO_WORD;
>  		tx_fifo_avail -= words_to_transfer;
> +
>  		i2c_dev->msg_buf_remaining = buf_remaining;
> -		i2c_dev->msg_buf = buf +
> -			words_to_transfer * BYTES_PER_FIFO_WORD;
> +		i2c_dev->msg_buf = buf + words_to_transfer * BYTES_PER_FIFO_WORD;
>  
>  		i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
>  
> @@ -914,12 +921,18 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
>  	goto done;
>  err:
>  	/* mask all interrupts on error */
> -	tegra_i2c_mask_irq(i2c_dev, I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST |
> -		I2C_INT_PACKET_XFER_COMPLETE | I2C_INT_TX_FIFO_DATA_REQ |
> -		I2C_INT_RX_FIFO_DATA_REQ);
> +	tegra_i2c_mask_irq(i2c_dev,
> +			   I2C_INT_NO_ACK |
> +			   I2C_INT_ARBITRATION_LOST |
> +			   I2C_INT_PACKET_XFER_COMPLETE |
> +			   I2C_INT_TX_FIFO_DATA_REQ |
> +			   I2C_INT_RX_FIFO_DATA_REQ);

This now seems inconsistent with the choice in other places in this
driver where we wrap only when necessary. I think it would be more
consistent to align the subsequent lines with the parameters on the
first line. Or alternatively assign to a local variable and pass that to
tegra_i2c_mask_irq().

But the above is fine with me as well:

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 34/34] i2c: tegra: Improve driver module description
  2020-09-08 22:40 ` [PATCH v7 34/34] i2c: tegra: Improve driver module description Dmitry Osipenko
@ 2020-09-17 12:35   ` Thierry Reding
  2020-09-21 10:20   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 12:35 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 462 bytes --]

On Wed, Sep 09, 2020 at 01:40:06AM +0300, Dmitry Osipenko wrote:
> Use proper spelling of "NVIDIA" and don't designate driver as Tegra2-only
> since newer SoC generations are supported as well.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 09/34] i2c: tegra: Use reset_control_reset()
  2020-09-08 22:39 ` [PATCH v7 09/34] i2c: tegra: Use reset_control_reset() Dmitry Osipenko
@ 2020-09-17 12:36   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 12:36 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 977 bytes --]

On Wed, Sep 09, 2020 at 01:39:41AM +0300, Dmitry Osipenko wrote:
> Use a single reset_control_reset() instead of assert/deasset couple in
> order to make code cleaner a tad. Note that the reset_control_reset()
> uses 1 microsecond delay instead of 2 that was used previously, but this
> shouldn't matter because one microsecond is a default reset time for most
> of Tegra peripherals and TRM doesn't mention anything special in regards
> to I2C controller's reset propagation time.
> 
> In addition don't ignore potential error of the reset control by emitting
> a noisy warning if it fails, which will indicate an existence of a severe
> problem, while still allow machine to boot up.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 13 ++++++++++---
>  1 file changed, 10 insertions(+), 3 deletions(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 14/34] i2c: tegra: Clean up probe function
  2020-09-08 22:39 ` [PATCH v7 14/34] i2c: tegra: Clean up probe function Dmitry Osipenko
@ 2020-09-17 12:37   ` Thierry Reding
  2020-09-17 13:46     ` Andy Shevchenko
  2020-09-17 15:02     ` Dmitry Osipenko
  2020-09-21 10:19   ` Thierry Reding
  1 sibling, 2 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 12:37 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2990 bytes --]

On Wed, Sep 09, 2020 at 01:39:46AM +0300, Dmitry Osipenko wrote:
> The driver's probe function code is a bit difficult to read. This patch
> reorders code of the probe function, forming groups of code that are easy
> to work with. The probe tear-down order now matches the driver-removal
> order.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 100 ++++++++++++++++-----------------
>  1 file changed, 49 insertions(+), 51 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> index 79d1cefdc901..7c91bbb3f95c 100644
> --- a/drivers/i2c/busses/i2c-tegra.c
> +++ b/drivers/i2c/busses/i2c-tegra.c
> @@ -440,6 +440,9 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev)
>  
>  	i2c_dev->tx_dma_chan = chan;
>  
> +	i2c_dev->dma_buf_size = i2c_dev->hw->quirks->max_write_len +
> +				I2C_PACKET_HEADER_SIZE;
> +
>  	dma_buf = dma_alloc_coherent(i2c_dev->dev, i2c_dev->dma_buf_size,
>  				     &dma_phys, GFP_KERNEL | __GFP_NOWARN);
>  	if (!dma_buf) {
> @@ -1693,34 +1696,42 @@ static int tegra_i2c_probe(struct platform_device *pdev)
>  	struct device *dev = &pdev->dev;
>  	struct tegra_i2c_dev *i2c_dev;
>  	struct resource *res;
> -	void __iomem *base;
> -	phys_addr_t base_phys;
> -	int irq;
>  	int ret;
>  
> -	base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
> -	if (IS_ERR(base))
> -		return PTR_ERR(base);
> -
> -	base_phys = res->start;
> -
> -	irq = platform_get_irq(pdev, 0);
> -	if (irq < 0)
> -		return irq;
> -
>  	i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL);
>  	if (!i2c_dev)
>  		return -ENOMEM;
>  
> -	i2c_dev->base = base;
> -	i2c_dev->base_phys = base_phys;
> -	i2c_dev->adapter.algo = &tegra_i2c_algo;
> -	i2c_dev->adapter.retries = 1;
> -	i2c_dev->adapter.timeout = 6 * HZ;
> -	i2c_dev->irq = irq;
> +	platform_set_drvdata(pdev, i2c_dev);
> +
> +	init_completion(&i2c_dev->msg_complete);
> +	init_completion(&i2c_dev->dma_complete);
> +
> +	i2c_dev->hw = of_device_get_match_data(&pdev->dev);
>  	i2c_dev->cont_id = pdev->id;
>  	i2c_dev->dev = &pdev->dev;
>  
> +	i2c_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
> +	if (IS_ERR(i2c_dev->base))
> +		return PTR_ERR(i2c_dev->base);
> +
> +	i2c_dev->base_phys = res->start;
> +
> +	ret = platform_get_irq(pdev, 0);
> +	if (ret < 0)
> +		return ret;
> +
> +	i2c_dev->irq = ret;
> +
> +	/* interrupt will be enabled during of transfer time */
> +	irq_set_status_flags(i2c_dev->irq, IRQ_NOAUTOEN);
> +
> +	ret = devm_request_irq(&pdev->dev, i2c_dev->irq, tegra_i2c_isr,
> +			       IRQF_NO_SUSPEND, dev_name(&pdev->dev),
> +			       i2c_dev);
> +	if (ret)
> +		return ret;

Is it safe to install the interrupt handler at this point? What if,
perhaps because some bootloader didn't properly quiesce the I2C
controller, an interrupt triggers immediately after this?

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 15/34] i2c: tegra: Reorder location of functions in the code
  2020-09-08 22:39 ` [PATCH v7 15/34] i2c: tegra: Reorder location of functions in the code Dmitry Osipenko
@ 2020-09-17 12:38   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 12:38 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 620 bytes --]

On Wed, Sep 09, 2020 at 01:39:47AM +0300, Dmitry Osipenko wrote:
> Reorder location of functions in the code in order to have definition
> of functions closer to the place of the invocation. This change makes
> easier to navigate around the code and removes the need to have a
> prototype for tegra_i2c_init().
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 486 ++++++++++++++++-----------------
>  1 file changed, 242 insertions(+), 244 deletions(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 16/34] i2c: tegra: Clean up variable types
  2020-09-08 22:39 ` [PATCH v7 16/34] i2c: tegra: Clean up variable types Dmitry Osipenko
@ 2020-09-17 12:39   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 12:39 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 405 bytes --]

On Wed, Sep 09, 2020 at 01:39:48AM +0300, Dmitry Osipenko wrote:
> Don't use signed types for unsigned values and use consistent types
> for sibling variables.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 38 +++++++++++++++++-----------------
>  1 file changed, 19 insertions(+), 19 deletions(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 17/34] i2c: tegra: Remove outdated barrier()
  2020-09-08 22:39 ` [PATCH v7 17/34] i2c: tegra: Remove outdated barrier() Dmitry Osipenko
@ 2020-09-17 12:39   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 12:39 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 627 bytes --]

On Wed, Sep 09, 2020 at 01:39:49AM +0300, Dmitry Osipenko wrote:
> The barrier() was intended to reduce possibility of racing with the
> interrupt handler, but driver's code evolved significantly and today's
> driver enables interrupt only when it waits for completion notification.
> Hence barrier() has no good use anymore, let's remove it.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 13 +++++--------
>  1 file changed, 5 insertions(+), 8 deletions(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 18/34] i2c: tegra: Remove likely/unlikely from the code
  2020-09-08 22:39 ` [PATCH v7 18/34] i2c: tegra: Remove likely/unlikely from the code Dmitry Osipenko
@ 2020-09-17 12:41   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 12:41 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1277 bytes --]

On Wed, Sep 09, 2020 at 01:39:50AM +0300, Dmitry Osipenko wrote:
> The likely/unlikely annotations should be used only in a hot paths of
> performance-critical code. The I2C driver doesn't have such paths, and
> thus, there is no justification for usage of likely/unlikely annotations
> in the code. Hence remove them.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> index ab83d1de6c94..fd0d51ec447f 100644
> --- a/drivers/i2c/busses/i2c-tegra.c
> +++ b/drivers/i2c/busses/i2c-tegra.c
> @@ -852,7 +852,7 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
>  		goto err;
>  	}
>  
> -	if (unlikely(status & status_err)) {
> +	if (status & status_err) {
>  		tegra_i2c_disable_packet_mode(i2c_dev);
>  		if (status & I2C_INT_NO_ACK)
>  			i2c_dev->msg_err |= I2C_ERR_NO_ACK;

At least this one is an interrupt handler, so it's kind of performance
critical. That said, it probably doesn't make a huge difference, so I
don't have any objection:

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 19/34] i2c: tegra: Remove redundant check in tegra_i2c_issue_bus_clear()
  2020-09-08 22:39 ` [PATCH v7 19/34] i2c: tegra: Remove redundant check in tegra_i2c_issue_bus_clear() Dmitry Osipenko
@ 2020-09-17 12:42   ` Thierry Reding
  2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 12:42 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 414 bytes --]

On Wed, Sep 09, 2020 at 01:39:51AM +0300, Dmitry Osipenko wrote:
> The tegra_i2c_wait_for_config_load() checks for 'has_config_load_reg' by
> itself, hence there is no need to duplicate the check.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 9 ++++-----
>  1 file changed, 4 insertions(+), 5 deletions(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 00/34] Improvements for Tegra I2C driver
  2020-09-09 15:49     ` Wolfram Sang
  2020-09-09 17:39       ` Dmitry Osipenko
@ 2020-09-17 12:44       ` Thierry Reding
  2020-09-21  9:12         ` Wolfram Sang
  1 sibling, 1 reply; 146+ messages in thread
From: Thierry Reding @ 2020-09-17 12:44 UTC (permalink / raw)
  To: Wolfram Sang, Dmitry Osipenko, Andy Shevchenko, Jonathan Hunter,
	Laxman Dewangan, Michał Mirosław, linux-i2c,
	linux-tegra, Linux Kernel Mailing List

[-- Attachment #1: Type: text/plain, Size: 1117 bytes --]

On Wed, Sep 09, 2020 at 05:49:02PM +0200, Wolfram Sang wrote:
> On Wed, Sep 09, 2020 at 06:36:50PM +0300, Dmitry Osipenko wrote:
> > 09.09.2020 12:11, Andy Shevchenko пишет:
> > > On Wed, Sep 9, 2020 at 1:40 AM Dmitry Osipenko <digetx@gmail.com> wrote:
> > >>
> > >> Hello!
> > >>
> > >> This series performs refactoring of the Tegra I2C driver code and hardens
> > >> the atomic-transfer mode.
> > > 
> > > I think there is still room for improvement, but let not block it, FWIW,
> > > Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
> > 
> > Thank you and Michał for helping with the review! Very appreciate this!
> 
> Yes, thanks everyone so far!
> 
> Is there some internal testfarm where this should be regression tested?
> Otherwise, I'd trust Dmitry, Andy, and Michał here and would apply it
> this week after some generic high-level review.

I'll queue this for a run on the test farm. I had a couple of minor
comments, but after going through the full series I'm pretty happy
overall with the result, so I'll go over my comments again and will
reevaluate.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 14/34] i2c: tegra: Clean up probe function
  2020-09-17 12:37   ` Thierry Reding
@ 2020-09-17 13:46     ` Andy Shevchenko
  2020-09-21 11:15       ` Thierry Reding
  2020-09-17 15:02     ` Dmitry Osipenko
  1 sibling, 1 reply; 146+ messages in thread
From: Andy Shevchenko @ 2020-09-17 13:46 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Dmitry Osipenko, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, linux-i2c, linux-tegra,
	Linux Kernel Mailing List

On Thu, Sep 17, 2020 at 3:37 PM Thierry Reding <thierry.reding@gmail.com> wrote:
> On Wed, Sep 09, 2020 at 01:39:46AM +0300, Dmitry Osipenko wrote:

...

> > +     ret = devm_request_irq(&pdev->dev, i2c_dev->irq, tegra_i2c_isr,
> > +                            IRQF_NO_SUSPEND, dev_name(&pdev->dev),
> > +                            i2c_dev);
> > +     if (ret)
> > +             return ret;
>
> Is it safe to install the interrupt handler at this point? What if,
> perhaps because some bootloader didn't properly quiesce the I2C
> controller, an interrupt triggers immediately after this?

It\s easy to check with debug shared IRQ, but here IRQ is not shared...
So, with a hack into the code and enabled debug it will be achievable to test.

And you probably meant that IRQ triggers *before* the handler is in place?

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 27/34] i2c: tegra: Check errors for both positive and negative values
  2020-09-17 12:09   ` Thierry Reding
@ 2020-09-17 13:50     ` Andy Shevchenko
  2020-09-21 11:24       ` Thierry Reding
  0 siblings, 1 reply; 146+ messages in thread
From: Andy Shevchenko @ 2020-09-17 13:50 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Dmitry Osipenko, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, linux-i2c, linux-tegra,
	Linux Kernel Mailing List

On Thu, Sep 17, 2020 at 3:09 PM Thierry Reding <thierry.reding@gmail.com> wrote:
> On Wed, Sep 09, 2020 at 01:39:59AM +0300, Dmitry Osipenko wrote:

> Why? All of these functions "return 0 on success or a negative error
> code on failure", don't they?

And what is the point of having ' < 0' in all those cases?

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 12/34] i2c: tegra: Use clk-bulk helpers
  2020-09-17 11:38   ` Thierry Reding
@ 2020-09-17 13:54     ` Andy Shevchenko
  2020-09-21 11:01       ` Thierry Reding
  2020-09-17 15:01     ` Dmitry Osipenko
  1 sibling, 1 reply; 146+ messages in thread
From: Andy Shevchenko @ 2020-09-17 13:54 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Dmitry Osipenko, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, linux-i2c, linux-tegra,
	Linux Kernel Mailing List

On Thu, Sep 17, 2020 at 2:38 PM Thierry Reding <thierry.reding@gmail.com> wrote:
> On Wed, Sep 09, 2020 at 01:39:44AM +0300, Dmitry Osipenko wrote:
> > Use clk-bulk helpers and factor out clocks initialization into separate
> > function in order to make code cleaner.
> >
> > The clocks initialization now performed after reset-control initialization
> > in order to avoid a noisy -PROBE_DEFER errors on T186+ from the clk-bulk
> > helper which doesn't silence this error code. Hence reset_control_get()
> > now may return -EPROBE_DEFER on newer Tegra SoCs because they use BPMP
> > driver that provides reset controls and BPMP doesn't come up early during
> > boot. Previously rst was protected by the clocks retrieval and now this
> > patch makes dev_err_probe() to be used for the rst error handling.
> >
> > Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
> > Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> > ---
> >  drivers/i2c/busses/i2c-tegra.c | 187 ++++++++++++---------------------
> >  1 file changed, 67 insertions(+), 120 deletions(-)
>
> This is tempting from a diffstat point of view, but the downside is that
> we can now no longer validate that all of the necessary clocks are given
> in device tree.
>
> Previously the driver would fail to probe the I2C controller if any of
> the expected clocks were not defined in device tree, but now it's just
> going to continue without it and not give any indication as to what's
> wrong.

You may print an error in the error path as previously. Since both
clocks are mandatory (as far as I understood the code) user will need
to check DT in any case.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 01/34] i2c: tegra: Make tegra_i2c_flush_fifos() usable in atomic transfer
  2020-09-17 11:10   ` Thierry Reding
@ 2020-09-17 14:57     ` Dmitry Osipenko
  0 siblings, 0 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-17 14:57 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

17.09.2020 14:10, Thierry Reding пишет:
> On Wed, Sep 09, 2020 at 01:39:33AM +0300, Dmitry Osipenko wrote:
>> The tegra_i2c_flush_fifos() shouldn't sleep in atomic transfer and jiffies
>> are not updating if interrupts are disabled. Let's switch to use iopoll
>> API helpers for register-polling. The iopoll API provides helpers for both
>> atomic and non-atomic cases.
>>
>> Note that this patch doesn't fix any known problem because normally FIFO
>> is flushed at the time of starting a new transfer.
>>
>> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  drivers/i2c/busses/i2c-tegra.c | 25 ++++++++++++++++---------
>>  1 file changed, 16 insertions(+), 9 deletions(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
>> index 00d3e4d7a01e..ab88cdd70376 100644
>> --- a/drivers/i2c/busses/i2c-tegra.c
>> +++ b/drivers/i2c/busses/i2c-tegra.c
>> @@ -470,9 +470,9 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev)
>>  
>>  static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
>>  {
>> -	unsigned long timeout = jiffies + HZ;
>> -	unsigned int offset;
>> -	u32 mask, val;
>> +	u32 mask, val, offset, reg_offset;
> 
> Is there are reason why we need reg_offset? Seems to me like we could
> simplify this, see below.

The reason is that this patch addresses potential problem, hence it's
not a cleanup change and it should be kept minimal.

>> +	void __iomem *addr;
>> +	int err;
>>  
>>  	if (i2c_dev->hw->has_mst_fifo) {
>>  		mask = I2C_MST_FIFO_CONTROL_TX_FLUSH |
>> @@ -488,12 +488,19 @@ static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
>>  	val |= mask;
>>  	i2c_writel(i2c_dev, val, offset);
>>  
>> -	while (i2c_readl(i2c_dev, offset) & mask) {
>> -		if (time_after(jiffies, timeout)) {
>> -			dev_warn(i2c_dev->dev, "timeout waiting for fifo flush\n");
>> -			return -ETIMEDOUT;
>> -		}
>> -		usleep_range(1000, 2000);
>> +	reg_offset = tegra_i2c_reg_addr(i2c_dev, offset);
>> +	addr = i2c_dev->base + reg_offset;
> 
> Why not just:
> 
> 	offset = tegra_i2c_reg_offset(i2c_dev, offset);
> 	addr = i2c_dev->base + offset;
> 
> or even just:
> 
> 	addr = i2c_dev->base + tegra_i2c_reg_offset(i2c_dev, offset);
> 
> ? That makes the patch much smaller because you don't have to rewrite
> the whole variable declaration block and just add the "addr" and "err"
> variables while removing "timeout".

There is a further "cleanup" patch named "Factor out register polling
into separate function" that already implements yours suggestion.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 08/34] i2c: tegra: Remove error message used for devm_request_irq() failure
  2020-09-17 11:28   ` Thierry Reding
@ 2020-09-17 14:59     ` Dmitry Osipenko
  2020-09-21 10:57       ` Thierry Reding
  0 siblings, 1 reply; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-17 14:59 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

17.09.2020 14:28, Thierry Reding пишет:
> On Wed, Sep 09, 2020 at 01:39:40AM +0300, Dmitry Osipenko wrote:
>> The error message prints number of vIRQ, which isn't a useful information.
>> In practice devm_request_irq() never fails, hence let's remove the bogus
>> message in order to make code cleaner.
>>
>> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  drivers/i2c/busses/i2c-tegra.c | 4 +---
>>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> I think I have seen this fail occasionally when something's wrong in the
> IRQ code, or when we are not properly configuring the IRQ in device tree
> for example.
> 
> So I'd prefer if this error message stayed here. I agree that it's not a
> terribly useful error message, so perhaps adding the error code to it
> would make it more helpful?

We have dtbs_check nowadays and I assume you only saw a such problem
during of hardware bring-up, correct?

Realistically, this error should never happen "randomly" and even if it
will happen, then you will still know that I2C driver failed because
driver-core will tell you about that.

Hence there is no much value in the error message, it should be more
practical to remove it in order to keep the code cleaner.

>> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
>> index a52c72135390..b813c0976c10 100644
>> --- a/drivers/i2c/busses/i2c-tegra.c
>> +++ b/drivers/i2c/busses/i2c-tegra.c
>> @@ -1807,10 +1807,8 @@ static int tegra_i2c_probe(struct platform_device *pdev)
>>  
>>  	ret = devm_request_irq(&pdev->dev, i2c_dev->irq, tegra_i2c_isr,
>>  			       IRQF_NO_SUSPEND, dev_name(&pdev->dev), i2c_dev);
>> -	if (ret) {
>> -		dev_err(&pdev->dev, "Failed to request irq %i\n", i2c_dev->irq);
>> +	if (ret)
>>  		goto release_dma;
>> -	}
>>  
>>  	i2c_set_adapdata(&i2c_dev->adapter, i2c_dev);
>>  	i2c_dev->adapter.owner = THIS_MODULE;
>> -- 
>> 2.27.0
>>


^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 12/34] i2c: tegra: Use clk-bulk helpers
  2020-09-17 11:38   ` Thierry Reding
  2020-09-17 13:54     ` Andy Shevchenko
@ 2020-09-17 15:01     ` Dmitry Osipenko
  2020-09-21 11:08       ` Thierry Reding
  2020-09-21 11:12       ` Thierry Reding
  1 sibling, 2 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-17 15:01 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

17.09.2020 14:38, Thierry Reding пишет:
> On Wed, Sep 09, 2020 at 01:39:44AM +0300, Dmitry Osipenko wrote:
>> Use clk-bulk helpers and factor out clocks initialization into separate
>> function in order to make code cleaner.
>>
>> The clocks initialization now performed after reset-control initialization
>> in order to avoid a noisy -PROBE_DEFER errors on T186+ from the clk-bulk
>> helper which doesn't silence this error code. Hence reset_control_get()
>> now may return -EPROBE_DEFER on newer Tegra SoCs because they use BPMP
>> driver that provides reset controls and BPMP doesn't come up early during
>> boot. Previously rst was protected by the clocks retrieval and now this
>> patch makes dev_err_probe() to be used for the rst error handling.
>>
>> Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  drivers/i2c/busses/i2c-tegra.c | 187 ++++++++++++---------------------
>>  1 file changed, 67 insertions(+), 120 deletions(-)
> 
> This is tempting from a diffstat point of view, but the downside is that
> we can now no longer validate that all of the necessary clocks are given
> in device tree.
> 
> Previously the driver would fail to probe the I2C controller if any of
> the expected clocks were not defined in device tree, but now it's just
> going to continue without it and not give any indication as to what's
> wrong.

The clocks can't be missed randomly in a device-tree because they are a
part of the core tegra.dtsi

The tegra-i2c DT binding isn't converted to YAML, but once it will be,
then the dtbs_check will tell you about such obvious problems like a
missing mandatory property.

Even if clock is missing, then you won't miss this problem since I2C
shouldn't work in that case.

There is a Qualcomm I2C driver that already uses clk_bulk_get_all() and
doesn't worry about "accidentally" missing clocks.

It's still possible to add the clk-num checking, but it should be
unpractical. We could always add it later on if there will be a real
incident. Do you agree?

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 32/34] i2c: tegra: Clean up and improve comments
  2020-09-17 12:32   ` Thierry Reding
@ 2020-09-17 15:02     ` Dmitry Osipenko
  2020-09-17 15:17       ` Dmitry Osipenko
  0 siblings, 1 reply; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-17 15:02 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

17.09.2020 15:32, Thierry Reding пишет:
...
>>  /**
>> - * struct tegra_i2c_hw_feature : Different HW support on Tegra
>> - * @has_continue_xfer_support: Continue transfer supports.
>> + * struct tegra_i2c_hw_feature : per hardware generation features
> 
> I think that space before ':' can go away. Although that's preexisting,
> so could also be a separate patch, I guess.

I haven't even noticed that!

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 14/34] i2c: tegra: Clean up probe function
  2020-09-17 12:37   ` Thierry Reding
  2020-09-17 13:46     ` Andy Shevchenko
@ 2020-09-17 15:02     ` Dmitry Osipenko
  2020-09-21 11:17       ` Thierry Reding
  1 sibling, 1 reply; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-17 15:02 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

17.09.2020 15:37, Thierry Reding пишет:
...
>> +	/* interrupt will be enabled during of transfer time */
>> +	irq_set_status_flags(i2c_dev->irq, IRQ_NOAUTOEN);
                                           ^^^^^^^^^^^^

>> +	ret = devm_request_irq(&pdev->dev, i2c_dev->irq, tegra_i2c_isr,
>> +			       IRQF_NO_SUSPEND, dev_name(&pdev->dev),
>> +			       i2c_dev);
>> +	if (ret)
>> +		return ret;
> 
> Is it safe to install the interrupt handler at this point? What if,
> perhaps because some bootloader didn't properly quiesce the I2C
> controller, an interrupt triggers immediately after this?

This is why we're using the IRQ_NOAUTOEN flag above :)

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 21/34] i2c: tegra: Don't fall back to PIO mode if DMA configuration fails
  2020-09-17 11:47   ` Thierry Reding
@ 2020-09-17 15:03     ` Dmitry Osipenko
  2020-09-21 11:21       ` Thierry Reding
  0 siblings, 1 reply; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-17 15:03 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

17.09.2020 14:47, Thierry Reding пишет:
> On Wed, Sep 09, 2020 at 01:39:53AM +0300, Dmitry Osipenko wrote:
>> The DMA code path has been tested well enough and the DMA configuration
>> performed by tegra_i2c_config_fifo_trig() shouldn't ever fail in practice.
>> Hence let's remove the obscure transfer-mode switching in order to have a
>> cleaner and simpler code. Now I2C transfer will be failed if DMA
>> configuration fails.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  drivers/i2c/busses/i2c-tegra.c | 18 ++++++++++--------
>>  1 file changed, 10 insertions(+), 8 deletions(-)
> 
> I'm not sure that's a good idea. It's always possible that the DMA setup
> is going to break because of something that's not related to the I2C
> driver itself. Having the system completely break instead of falling
> back to PIO mode seems like it would only complicate troubleshooting any
> such issues.

That code has zero test coverage because this problem never happens in
practice, hence it should be better to have it removed. We may consider
re-adding it back if there will be a real-world incident, okay?

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 25/34] i2c: tegra: Factor out register polling into separate function
  2020-09-17 11:58   ` Thierry Reding
@ 2020-09-17 15:05     ` Dmitry Osipenko
  2020-09-21 11:22       ` Thierry Reding
  0 siblings, 1 reply; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-17 15:05 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

17.09.2020 14:58, Thierry Reding пишет:
> On Wed, Sep 09, 2020 at 01:39:57AM +0300, Dmitry Osipenko wrote:
>> Factor out register polling into a separate function in order to remove
>> boilerplate code and make code cleaner.
>>
>> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  drivers/i2c/busses/i2c-tegra.c | 57 +++++++++++++++-------------------
>>  1 file changed, 25 insertions(+), 32 deletions(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
>> index 405b87e28a98..e071de9ce106 100644
>> --- a/drivers/i2c/busses/i2c-tegra.c
>> +++ b/drivers/i2c/busses/i2c-tegra.c
>> @@ -514,10 +514,24 @@ static void tegra_i2c_vi_init(struct tegra_i2c_dev *i2c_dev)
>>  	i2c_writel(i2c_dev, 0x0, I2C_TLOW_SEXT);
>>  }
>>  
>> +static int tegra_i2c_poll_register(struct tegra_i2c_dev *i2c_dev,
>> +				   u32 reg, u32 mask, u32 delay_us,
>> +				   u32 timeout_us)
>> +{
>> +	void __iomem *addr = i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg);
>> +	u32 val;
>> +
>> +	if (!i2c_dev->is_curr_atomic_xfer)
>> +		return readl_relaxed_poll_timeout(addr, val, !(val & mask),
>> +						  delay_us, timeout_us);
>> +
>> +	return readl_relaxed_poll_timeout_atomic(addr, val, !(val & mask),
>> +						 delay_us, timeout_us);
>> +}
>> +
>>  static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
>>  {
>> -	u32 mask, val, offset, reg_offset;
>> -	void __iomem *addr;
>> +	u32 mask, val, offset;
>>  	int err;
>>  
>>  	if (i2c_dev->hw->has_mst_fifo) {
>> @@ -534,16 +548,7 @@ static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
>>  	val |= mask;
>>  	i2c_writel(i2c_dev, val, offset);
>>  
>> -	reg_offset = tegra_i2c_reg_addr(i2c_dev, offset);
>> -	addr = i2c_dev->base + reg_offset;
>> -
>> -	if (i2c_dev->is_curr_atomic_xfer)
>> -		err = readl_relaxed_poll_timeout_atomic(addr, val, !(val & mask),
>> -							1000, 1000000);
>> -	else
>> -		err = readl_relaxed_poll_timeout(addr, val, !(val & mask),
>> -						 1000, 1000000);
>> -
>> +	err = tegra_i2c_poll_register(i2c_dev, offset, mask, 1000, 1000000);
>>  	if (err) {
>>  		dev_err(i2c_dev->dev, "failed to flush FIFO\n");
>>  		return err;
>> @@ -553,30 +558,18 @@ static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
>>  
>>  static int tegra_i2c_wait_for_config_load(struct tegra_i2c_dev *i2c_dev)
>>  {
>> -	unsigned long reg_offset;
>> -	void __iomem *addr;
>> -	u32 val;
>>  	int err;
>>  
>> -	if (i2c_dev->hw->has_config_load_reg) {
>> -		reg_offset = tegra_i2c_reg_addr(i2c_dev, I2C_CONFIG_LOAD);
>> -		addr = i2c_dev->base + reg_offset;
>> -		i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, I2C_CONFIG_LOAD);
>> +	if (!i2c_dev->hw->has_config_load_reg)
>> +		return 0;
>>  
>> -		if (i2c_dev->is_curr_atomic_xfer)
>> -			err = readl_relaxed_poll_timeout_atomic(
>> -						addr, val, val == 0, 1000,
>> -						I2C_CONFIG_LOAD_TIMEOUT);
>> -		else
>> -			err = readl_relaxed_poll_timeout(
>> -						addr, val, val == 0, 1000,
>> -						I2C_CONFIG_LOAD_TIMEOUT);
>> +	i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, I2C_CONFIG_LOAD);
>>  
>> -		if (err) {
>> -			dev_warn(i2c_dev->dev,
>> -				 "timeout waiting for config load\n");
>> -			return err;
>> -		}
>> +	err = tegra_i2c_poll_register(i2c_dev, I2C_CONFIG_LOAD, 0xffffffff,
>> +				      1000, I2C_CONFIG_LOAD_TIMEOUT);
>> +	if (err) {
>> +		dev_warn(i2c_dev->dev, "timeout waiting for config load\n");
>> +		return err;
>>  	}
> 
> The deindentation in this hunk is messing up the diffstat in my opinion.
> It would probably be worth splitting that into a separate patch to make
> it more evident that this patch actually removes boilerplate.

This is intentional and it's mentioned in the v7 changelog.

Previously there was another patch that did what you're suggesting, but
Andy Shevchenko objected that it was causing a "ping-pong" code changes
where one patch did a change and then next patch changes the changed
code again.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 29/34] i2c: tegra: Improve formatting of variables
  2020-09-17 12:16   ` Thierry Reding
@ 2020-09-17 15:13     ` Dmitry Osipenko
  2020-09-21 11:28       ` Thierry Reding
  0 siblings, 1 reply; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-17 15:13 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

17.09.2020 15:16, Thierry Reding пишет:
> On Wed, Sep 09, 2020 at 01:40:01AM +0300, Dmitry Osipenko wrote:
>> Reorder definition of variables in the code to have them sorted by length
>> and grouped logically, also replace "unsigned long" with "u32". Do this in
>> order to make code easier to read.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  drivers/i2c/busses/i2c-tegra.c | 97 ++++++++++++++++------------------
>>  1 file changed, 45 insertions(+), 52 deletions(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
>> index ac40c87f1c21..2376f502d299 100644
>> --- a/drivers/i2c/busses/i2c-tegra.c
>> +++ b/drivers/i2c/busses/i2c-tegra.c
>> @@ -259,42 +259,48 @@ struct tegra_i2c_hw_feature {
>>   */
>>  struct tegra_i2c_dev {
>>  	struct device *dev;
>> -	const struct tegra_i2c_hw_feature *hw;
>>  	struct i2c_adapter adapter;
>> -	struct clk *div_clk;
>> -	struct clk_bulk_data *clocks;
>> -	unsigned int nclocks;
>> +
>> +	const struct tegra_i2c_hw_feature *hw;
>>  	struct reset_control *rst;
>> -	void __iomem *base;
>> -	phys_addr_t base_phys;
>>  	unsigned int cont_id;
>>  	unsigned int irq;
>> -	bool is_dvc;
>> -	bool is_vi;
>> +
>> +	phys_addr_t base_phys;
>> +	void __iomem *base;
>> +
>> +	struct clk_bulk_data *clocks;
>> +	unsigned int nclocks;
>> +
>> +	struct clk *div_clk;
>> +	u32 bus_clk_rate;
>> +
>>  	struct completion msg_complete;
>> +	size_t msg_buf_remaining;
>>  	int msg_err;
>>  	u8 *msg_buf;
>> -	size_t msg_buf_remaining;
>> -	bool msg_read;
>> -	u32 bus_clk_rate;
>> -	bool is_multimaster_mode;
>> +
>> +	struct completion dma_complete;
>>  	struct dma_chan *tx_dma_chan;
>>  	struct dma_chan *rx_dma_chan;
>> +	unsigned int dma_buf_size;
>>  	dma_addr_t dma_phys;
>>  	u32 *dma_buf;
>> -	unsigned int dma_buf_size;
>> -	bool is_curr_dma_xfer;
>> -	struct completion dma_complete;
>> +
>> +	bool is_multimaster_mode;
>>  	bool is_curr_atomic_xfer;
>> +	bool is_curr_dma_xfer;
>> +	bool msg_read;
>> +	bool is_dvc;
>> +	bool is_vi;
>>  };
>>  
>> -static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val,
>> -		       unsigned long reg)
>> +static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val, u32 reg)
> 
> I actually prefer unsigned long/int over u32 for offsets because it
> makes it clearer that this is not in fact a 32-bit value that we're
> writing into a register. This is especially true for these register
> accessors where the "offset" is called "reg" and may be easily
> mistaken for a register value.

That is a bit questionable, at least it definitely won't save me from a
mistake :)

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 32/34] i2c: tegra: Clean up and improve comments
  2020-09-17 15:02     ` Dmitry Osipenko
@ 2020-09-17 15:17       ` Dmitry Osipenko
  2020-09-21 11:43         ` Thierry Reding
  0 siblings, 1 reply; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-17 15:17 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

17.09.2020 18:02, Dmitry Osipenko пишет:
> 17.09.2020 15:32, Thierry Reding пишет:
> ...
>>>  /**
>>> - * struct tegra_i2c_hw_feature : Different HW support on Tegra
>>> - * @has_continue_xfer_support: Continue transfer supports.
>>> + * struct tegra_i2c_hw_feature : per hardware generation features
>>
>> I think that space before ':' can go away. Although that's preexisting,
>> so could also be a separate patch, I guess.
> 
> I haven't even noticed that!
> 

Wait, that ':' is used only for the struct description, hence it
actually looks natural in the code.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 06/34] i2c: tegra: Remove i2c_dev.clk_divisor_non_hs_mode member
  2020-09-17 11:25   ` Thierry Reding
@ 2020-09-17 15:27     ` Dmitry Osipenko
  2020-09-21 10:49       ` Thierry Reding
  0 siblings, 1 reply; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-17 15:27 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

17.09.2020 14:25, Thierry Reding пишет:
> On Wed, Sep 09, 2020 at 01:39:38AM +0300, Dmitry Osipenko wrote:
>> The "non_hs_mode" divisor value is fixed, thus there is no need to have
>> the variable i2c_dev.clk_divisor_non_hs_mode struct member. Let's remove
>> it and move the mode selection into tegra_i2c_init() where it can be
>> united with the timing selection.
>>
>> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  drivers/i2c/busses/i2c-tegra.c | 46 ++++++++++++++++------------------
>>  1 file changed, 21 insertions(+), 25 deletions(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
>> index 720a75439e91..85ed0e02d48c 100644
>> --- a/drivers/i2c/busses/i2c-tegra.c
>> +++ b/drivers/i2c/busses/i2c-tegra.c
>> @@ -250,7 +250,6 @@ struct tegra_i2c_hw_feature {
>>   * @msg_buf_remaining: size of unsent data in the message buffer
>>   * @msg_read: identifies read transfers
>>   * @bus_clk_rate: current I2C bus clock rate
>> - * @clk_divisor_non_hs_mode: clock divider for non-high-speed modes
>>   * @is_multimaster_mode: track if I2C controller is in multi-master mode
>>   * @tx_dma_chan: DMA transmit channel
>>   * @rx_dma_chan: DMA receive channel
>> @@ -281,7 +280,6 @@ struct tegra_i2c_dev {
>>  	size_t msg_buf_remaining;
>>  	int msg_read;
>>  	u32 bus_clk_rate;
>> -	u16 clk_divisor_non_hs_mode;
>>  	bool is_multimaster_mode;
>>  	struct dma_chan *tx_dma_chan;
>>  	struct dma_chan *rx_dma_chan;
>> @@ -783,6 +781,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
>>  	u32 val;
>>  	int err;
>>  	u32 clk_divisor, clk_multiplier;
>> +	u32 non_hs_mode;
>>  	u32 tsu_thd;
>>  	u8 tlow, thigh;
>>  
>> @@ -805,24 +804,33 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
>>  	if (i2c_dev->is_vi)
>>  		tegra_i2c_vi_init(i2c_dev);
>>  
>> -	/* Make sure clock divisor programmed correctly */
>> -	clk_divisor = FIELD_PREP(I2C_CLK_DIVISOR_HSMODE,
>> -				 i2c_dev->hw->clk_divisor_hs_mode) |
>> -		      FIELD_PREP(I2C_CLK_DIVISOR_STD_FAST_MODE,
>> -				 i2c_dev->clk_divisor_non_hs_mode);
>> -	i2c_writel(i2c_dev, clk_divisor, I2C_CLK_DIVISOR);
>> -
>> -	if (i2c_dev->bus_clk_rate > I2C_MAX_STANDARD_MODE_FREQ &&
>> -	    i2c_dev->bus_clk_rate <= I2C_MAX_FAST_MODE_PLUS_FREQ) {
>> +	switch (i2c_dev->bus_clk_rate) {
>> +	case I2C_MAX_STANDARD_MODE_FREQ + 1 ... I2C_MAX_FAST_MODE_PLUS_FREQ:
> 
> Is there are particular reason for switching the simple conditional to a
> switch here? The old variant looks much easier to understand to me.

The reason is make it readable :) For me it's too difficult to read > <=
&& { } + no proper indentation.

The switches are more suitable for ranges, IMO. Especially when there
are multiple ranges, and there could be more ranges in the future in
this code.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 30/34] i2c: tegra: Clean up variable names
  2020-09-17 12:21   ` Thierry Reding
@ 2020-09-17 15:43     ` Dmitry Osipenko
  2020-09-21 11:40       ` Thierry Reding
  0 siblings, 1 reply; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-17 15:43 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

17.09.2020 15:21, Thierry Reding пишет:
> On Wed, Sep 09, 2020 at 01:40:02AM +0300, Dmitry Osipenko wrote:
>> Rename "ret" variables to "err" in order to make code a bit more
>> expressive, emphasizing that the returned value is an error code.
>> Same vice versa, where appropriate.
>>
>> Rename variable "reg" to "val" in order to better reflect the actual
>> usage of the variable in the code and to make naming consistent with
>> the rest of the code.
>>
>> Use briefer names for a few members of the tegra_i2c_dev structure in
>> order to improve readability of the code.
>>
>> All dev/&pdev->dev are replaced with i2c_dev->dev in order to have uniform
>> code style across the driver.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  drivers/i2c/busses/i2c-tegra.c | 173 ++++++++++++++++-----------------
>>  1 file changed, 86 insertions(+), 87 deletions(-)
> 
> That's indeed a nice improvement. One thing did spring out at me,
> though.
> 
>> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> [...]
>> @@ -1831,20 +1830,20 @@ static int __maybe_unused tegra_i2c_runtime_suspend(struct device *dev)
>>  
>>  	clk_bulk_disable(i2c_dev->nclocks, i2c_dev->clocks);
>>  
>> -	return pinctrl_pm_select_idle_state(i2c_dev->dev);
>> +	return pinctrl_pm_select_idle_state(dev);
>>  }
>>  
>>  static int __maybe_unused tegra_i2c_suspend(struct device *dev)
>>  {
>>  	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
>> -	int err = 0;
>> +	int ret = 0;
>>  
>>  	i2c_mark_adapter_suspended(&i2c_dev->adapter);
>>  
>>  	if (!pm_runtime_status_suspended(dev))
>> -		err = tegra_i2c_runtime_suspend(dev);
>> +		ret = tegra_i2c_runtime_suspend(dev);
>>  
>> -	return err;
>> +	return ret;
>>  }
> 
> Isn't this exactly the opposite of what the commit message says (and the
> rest of the patch does)?

This change makes it to be consistent with the rest of the code. You may
notice that "Factor out hardware initialization into separate function"
made a similar change.

The reason I'm doing this is that the "err" suggests that code returns a
error failure code, while it could be a success too and you don't know
for sure by looking only at the part of code. Hence it's cleaner to use
"err" when error code is returned.

It is possible (and maybe even better) to rewrite this function as:

static int __maybe_unused tegra_i2c_suspend(struct device *dev)
{
	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);

	i2c_mark_adapter_suspended(&i2c_dev->adapter);

	if (!pm_runtime_status_suspended(dev)) {
		int err = tegra_i2c_runtime_suspend(dev);
		if (err)
			return err;
	}

	return 0;
}

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 00/34] Improvements for Tegra I2C driver
  2020-09-17 12:44       ` Thierry Reding
@ 2020-09-21  9:12         ` Wolfram Sang
  0 siblings, 0 replies; 146+ messages in thread
From: Wolfram Sang @ 2020-09-21  9:12 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Dmitry Osipenko, Andy Shevchenko, Jonathan Hunter,
	Laxman Dewangan, Michał Mirosław, linux-i2c,
	linux-tegra, Linux Kernel Mailing List

[-- Attachment #1: Type: text/plain, Size: 1345 bytes --]

On Thu, Sep 17, 2020 at 02:44:18PM +0200, Thierry Reding wrote:
> On Wed, Sep 09, 2020 at 05:49:02PM +0200, Wolfram Sang wrote:
> > On Wed, Sep 09, 2020 at 06:36:50PM +0300, Dmitry Osipenko wrote:
> > > 09.09.2020 12:11, Andy Shevchenko пишет:
> > > > On Wed, Sep 9, 2020 at 1:40 AM Dmitry Osipenko <digetx@gmail.com> wrote:
> > > >>
> > > >> Hello!
> > > >>
> > > >> This series performs refactoring of the Tegra I2C driver code and hardens
> > > >> the atomic-transfer mode.
> > > > 
> > > > I think there is still room for improvement, but let not block it, FWIW,
> > > > Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
> > > 
> > > Thank you and Michał for helping with the review! Very appreciate this!
> > 
> > Yes, thanks everyone so far!
> > 
> > Is there some internal testfarm where this should be regression tested?
> > Otherwise, I'd trust Dmitry, Andy, and Michał here and would apply it
> > this week after some generic high-level review.
> 
> I'll queue this for a run on the test farm. I had a couple of minor
> comments, but after going through the full series I'm pretty happy
> overall with the result, so I'll go over my comments again and will
> reevaluate.

Cool, thanks! You guys just let me know if v7 is fine please. Otherwise
I will surely notice if a v8 hits the list ;)


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 00/34] Improvements for Tegra I2C driver
  2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
                   ` (34 preceding siblings ...)
  2020-09-09  9:11 ` [PATCH v7 00/34] Improvements for Tegra I2C driver Andy Shevchenko
@ 2020-09-21 10:18 ` Thierry Reding
  2020-09-21 10:42   ` Thierry Reding
  35 siblings, 1 reply; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:18 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:32 +0300, Dmitry Osipenko wrote:
> Hello!
> 
> This series performs refactoring of the Tegra I2C driver code and hardens
> the atomic-transfer mode.
> 
> Changelog:
> 
> v7: - Reworked the "Clean up probe function" patch by moving out all
>       variable renamings into the "Clean up variable names" patch.
>       This results in a nicer diff, which was asked by Andy Shevchenko.
> 
>     - Squashed "Improve coding style of tegra_i2c_wait_for_config_load()"
>       patch into "Factor out register polling into separate function" in
>       order avoid unnecessary ping-pong changes, which was asked by
>       Andy Shevchenko.
> 
>     - Added more indentation improvements, it should be ideal now.
> 
>     - I haven't changed order of the "Clean up variable types" patch,
>       which was suggested by Andy Shevchenko, because I already moved
>       that patch multiple times and we decided to sort patches starting
>       with more important cleanups and down to less important. The type
>       changes are more important than shuffling code around, IMO.
> 
> v6: - Added new patch that adds missing RPM puts, thanks to Andy Shevchenko
>       for the suggestion.
> 
>     - Improved commit messages by extending them with more a more detailed
>       explanation of the changes.
> 
>     - Added clarifying comment to the "Use reset_control_reset()" change,
>       which was asked by Andy Shevchenko.
> 
>     - Refactored the "Clean up probe function" patch by moving the
>       dev_err_probe() change into the "Use clk-bulk helpers" patch,
>       which was suggested by Andy Shevchenko.
> 
>     - Improved ordering of the patches like it was suggested by
>       Andy Shevchenko.
> 
>     - Added Andy Shevchenko to suggested-by of the "Use clk-bulk helpers"
>       patch.
> 
>     - Improved "Remove i2c_dev.clk_divisor_non_hs_mode member" patch by
>       making the case-switch to use "fast plus mode" timing if clock rate
>       is out-of-range. Just to make it more consistent.
> 
>     - The "Improve tegra_i2c_dev structure" patch is squashed into
>      "Improve formatting of variables" and "Clean up types/names" patches.
> 
>     - All variable-renaming changes are squashed into a single "Clean up
>       variable names" patch.
> 
>     - Made extra minor improvement to various patches, like more comments
>       and indentations improved.
> 
> v5: - Dropped the "Factor out runtime PM and hardware initialization"
>       patch, like it was suggested by Michał Mirosław. Instead a less
>       invasive "Factor out hardware initialization into separate function"
>       patch added, it doesn't touch the RPM initialization.
> 
>     - The "Remove outdated barrier()" patch now removes outdated comments.
> 
>     - Updated commit description of the "Remove "dma" variable" patch,
>       saying that the transfer mode may be changed by a callee. This was
>       suggested by Michał Mirosław.
> 
>     - Reworked the "Clean up and improve comments" patch. Couple more
>       comments are corrected and reworded now.
> 
>     - Added r-b's from Michał Mirosław.
> 
>     - New patches:
> 
>         i2c: tegra: Mask interrupt in tegra_i2c_issue_bus_clear()
>         i2c: tegra: Remove redundant check in tegra_i2c_issue_bus_clear()
>         i2c: tegra: Don't fall back to PIO mode if DMA configuration fails
>         i2c: tegra: Clean up variable types
>         i2c: tegra: Improve tegra_i2c_dev structure
> 
> v4: - Reordered patches in the fixes/features/cleanups order like it was
>       suggested by Andy Shevchenko.
> 
>     - Now using clk-bulk API, which was suggested by Andy Shevchenko.
> 
>     - Reworked "Make tegra_i2c_flush_fifos() usable in atomic transfer"
>       patch to use iopoll API, which was suggested by Andy Shevchenko.
> 
>     - Separated "Clean up probe function" into several smaller patches.
> 
>     - Squashed "Add missing newline before returns" patch into
>       "Clean up whitespaces, newlines and indentation".
> 
>     - The "Drop '_timeout' from wait/poll function names" is renamed to
>       "Rename wait/poll functions".
> 
>     - The "Use reset_control_reset()" is changed to not fail tegra_i2c_init(),
>       but only emit warning. This should be more friendly behaviour in oppose
>       to having a non-bootable machine if reset-control fails.
> 
>     - New patches:
> 
>         i2c: tegra: Remove error message used for devm_request_irq() failure
>         i2c: tegra: Use devm_platform_get_and_ioremap_resource()
>         i2c: tegra: Use platform_get_irq()
>         i2c: tegra: Use clk-bulk helpers
>         i2c: tegra: Remove bogus barrier()
>         i2c: tegra: Factor out register polling into separate function
>         i2c: tegra: Consolidate error handling in tegra_i2c_xfer_msg()
>         i2c: tegra: Clean up and improve comments
>         i2c: tegra: Rename couple "ret" variables to "err"
> 
> v3: - Optimized "Make tegra_i2c_flush_fifos() usable in atomic transfer"
>       patch by pre-checking FIFO state before starting to poll using
>       ktime API, which may be expensive under some circumstances.
> 
>     - The "Clean up messages in the code" patch now makes all messages
>       to use proper capitalization of abbreviations. Thanks to Andy Shevchenko
>       and Michał Mirosław for the suggestion.
> 
>     - The "Remove unnecessary whitespaces and newlines" patch is transformed
>       into "Clean up whitespaces and newlines", it now also adds missing
>       newlines and spaces.
> 
>     - Reworked the "Clean up probe function" patch in accordance to
>       suggestion from Michał Mirosław by factoring out only parts of
>       the code that make error unwinding cleaner.
> 
>     - Added r-b from Michał Mirosław.
> 
>     - Added more patches:
> 
>         i2c: tegra: Reorder location of functions in the code
>         i2c: tegra: Factor out packet header setup from tegra_i2c_xfer_msg()
>         i2c: tegra: Remove "dma" variable
>         i2c: tegra: Initialization div-clk rate unconditionally
>         i2c: tegra: Remove i2c_dev.clk_divisor_non_hs_mode member
> 
> v2: - Cleaned more messages in the "Clean up messages in the code" patch.
> 
>     - The error code of reset_control_reset() is checked now.
> 
>     - Added these new patches to clean up couple more things:
> 
>         i2c: tegra: Check errors for both positive and negative values
>         i2c: tegra: Improve coding style of tegra_i2c_wait_for_config_load()
>         i2c: tegra: Remove unnecessary whitespaces and newlines
>         i2c: tegra: Rename variable in tegra_i2c_issue_bus_clear()
>         i2c: tegra: Improve driver module description
> 
> Dmitry Osipenko (34):
>   i2c: tegra: Make tegra_i2c_flush_fifos() usable in atomic transfer
>   i2c: tegra: Add missing pm_runtime_put()
>   i2c: tegra: Handle potential error of tegra_i2c_flush_fifos()
>   i2c: tegra: Mask interrupt in tegra_i2c_issue_bus_clear()
>   i2c: tegra: Initialize div-clk rate unconditionally
>   i2c: tegra: Remove i2c_dev.clk_divisor_non_hs_mode member
>   i2c: tegra: Runtime PM always available on Tegra
>   i2c: tegra: Remove error message used for devm_request_irq() failure
>   i2c: tegra: Use reset_control_reset()
>   i2c: tegra: Use devm_platform_get_and_ioremap_resource()
>   i2c: tegra: Use platform_get_irq()
>   i2c: tegra: Use clk-bulk helpers
>   i2c: tegra: Move out all device-tree parsing into tegra_i2c_parse_dt()
>   i2c: tegra: Clean up probe function
>   i2c: tegra: Reorder location of functions in the code
>   i2c: tegra: Clean up variable types
>   i2c: tegra: Remove outdated barrier()
>   i2c: tegra: Remove likely/unlikely from the code
>   i2c: tegra: Remove redundant check in tegra_i2c_issue_bus_clear()
>   i2c: tegra: Remove "dma" variable from tegra_i2c_xfer_msg()
>   i2c: tegra: Don't fall back to PIO mode if DMA configuration fails
>   i2c: tegra: Rename wait/poll functions
>   i2c: tegra: Factor out error recovery from tegra_i2c_xfer_msg()
>   i2c: tegra: Factor out packet header setup from tegra_i2c_xfer_msg()
>   i2c: tegra: Factor out register polling into separate function
>   i2c: tegra: Factor out hardware initialization into separate function
>   i2c: tegra: Check errors for both positive and negative values
>   i2c: tegra: Consolidate error handling in tegra_i2c_xfer_msg()
>   i2c: tegra: Improve formatting of variables
>   i2c: tegra: Clean up variable names
>   i2c: tegra: Clean up printk messages
>   i2c: tegra: Clean up and improve comments
>   i2c: tegra: Clean up whitespaces, newlines and indentation
>   i2c: tegra: Improve driver module description
> 
>  drivers/i2c/busses/i2c-tegra.c | 1435 ++++++++++++++++----------------
>  1 file changed, 701 insertions(+), 734 deletions(-)
> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>

Test results:
  14 builds: 14 pass, 0 fail
   9 boots:  9 pass, 0 fail
  47 tests:  47 pass, 0 fail

Boards tested: tegra20-ventana, tegra30-cardhu-a04, tegra124-jetson-tk1,
               tegra186-p2771-0000, tegra194-p2972-0000

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 01/34] i2c: tegra: Make tegra_i2c_flush_fifos() usable in atomic transfer
  2020-09-08 22:39 ` [PATCH v7 01/34] i2c: tegra: Make tegra_i2c_flush_fifos() usable in atomic transfer Dmitry Osipenko
  2020-09-17 11:10   ` Thierry Reding
@ 2020-09-21 10:18   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:18 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:33 +0300, Dmitry Osipenko wrote:
> The tegra_i2c_flush_fifos() shouldn't sleep in atomic transfer and jiffies
> are not updating if interrupts are disabled. Let's switch to use iopoll
> API helpers for register-polling. The iopoll API provides helpers for both
> atomic and non-atomic cases.
> 
> Note that this patch doesn't fix any known problem because normally FIFO
> is flushed at the time of starting a new transfer.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 25 ++++++++++++++++---------
>  1 file changed, 16 insertions(+), 9 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 02/34] i2c: tegra: Add missing pm_runtime_put()
  2020-09-08 22:39 ` [PATCH v7 02/34] i2c: tegra: Add missing pm_runtime_put() Dmitry Osipenko
  2020-09-17 11:12   ` Thierry Reding
@ 2020-09-21 10:18   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:18 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:34 +0300, Dmitry Osipenko wrote:
> The pm_runtime_get_sync() always bumps refcount regardless of whether it
> succeeds or fails. Hence driver is responsible for restoring of the RPM
> refcounting. This patch adds missing RPM puts which restore refcounting
> in a case of pm_runtime_get_sync() error.
> 
> Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Reviewed-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 03/34] i2c: tegra: Handle potential error of tegra_i2c_flush_fifos()
  2020-09-08 22:39 ` [PATCH v7 03/34] i2c: tegra: Handle potential error of tegra_i2c_flush_fifos() Dmitry Osipenko
  2020-09-17 11:13   ` Thierry Reding
@ 2020-09-21 10:18   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:18 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:35 +0300, Dmitry Osipenko wrote:
> Technically the tegra_i2c_flush_fifos() may fail and transfer should be
> aborted in this case, but this shouldn't ever happen in practice unless
> there is a bug somewhere in the driver. Let's add the error check just
> for completeness.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Reviewed-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 04/34] i2c: tegra: Mask interrupt in tegra_i2c_issue_bus_clear()
  2020-09-08 22:39 ` [PATCH v7 04/34] i2c: tegra: Mask interrupt in tegra_i2c_issue_bus_clear() Dmitry Osipenko
  2020-09-17 11:18   ` Thierry Reding
@ 2020-09-21 10:18   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:18 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:36 +0300, Dmitry Osipenko wrote:
> The tegra_i2c_issue_bus_clear() may fail and in this case BUS_CLR_DONE
> stays unmasked. Hence let's mask it for consistency. This patch doesn't
> fix any known problems.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Reviewed-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 2 ++
>  1 file changed, 2 insertions(+)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 05/34] i2c: tegra: Initialize div-clk rate unconditionally
  2020-09-08 22:39 ` [PATCH v7 05/34] i2c: tegra: Initialize div-clk rate unconditionally Dmitry Osipenko
  2020-09-17 11:20   ` Thierry Reding
@ 2020-09-21 10:18   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:18 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:37 +0300, Dmitry Osipenko wrote:
> It doesn't make sense to conditionalize the div-clk rate changes because
> rate is fixed and it won't ever change once it's set at the driver's probe
> time. All further changes are NO-OPs because CCF caches rate and skips
> rate-change if rate is unchanged.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Acked-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 34 ++++++++++++++++------------------
>  1 file changed, 16 insertions(+), 18 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 06/34] i2c: tegra: Remove i2c_dev.clk_divisor_non_hs_mode member
  2020-09-08 22:39 ` [PATCH v7 06/34] i2c: tegra: Remove i2c_dev.clk_divisor_non_hs_mode member Dmitry Osipenko
  2020-09-17 11:25   ` Thierry Reding
@ 2020-09-21 10:18   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:18 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:38 +0300, Dmitry Osipenko wrote:
> The "non_hs_mode" divisor value is fixed, thus there is no need to have
> the variable i2c_dev.clk_divisor_non_hs_mode struct member. Let's remove
> it and move the mode selection into tegra_i2c_init() where it can be
> united with the timing selection.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 46 ++++++++++++++++------------------
>  1 file changed, 21 insertions(+), 25 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 07/34] i2c: tegra: Runtime PM always available on Tegra
  2020-09-08 22:39 ` [PATCH v7 07/34] i2c: tegra: Runtime PM always available on Tegra Dmitry Osipenko
  2020-09-17 11:26   ` Thierry Reding
@ 2020-09-21 10:18   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:18 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:39 +0300, Dmitry Osipenko wrote:
> The runtime PM is guaranteed to be always available on Tegra after commit
> 40b2bb1b132a ("ARM: tegra: enforce PM requirement"). Hence let's remove
> all the RPM-availability checking and handling from the code.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Reviewed-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 29 ++++++-----------------------
>  1 file changed, 6 insertions(+), 23 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 08/34] i2c: tegra: Remove error message used for devm_request_irq() failure
  2020-09-08 22:39 ` [PATCH v7 08/34] i2c: tegra: Remove error message used for devm_request_irq() failure Dmitry Osipenko
  2020-09-17 11:28   ` Thierry Reding
@ 2020-09-21 10:18   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:18 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:40 +0300, Dmitry Osipenko wrote:
> The error message prints number of vIRQ, which isn't a useful information.
> In practice devm_request_irq() never fails, hence let's remove the bogus
> message in order to make code cleaner.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 09/34] i2c: tegra: Use reset_control_reset()
  2020-09-08 22:39 ` [PATCH v7 09/34] i2c: tegra: Use reset_control_reset() Dmitry Osipenko
  2020-09-17 12:36   ` Thierry Reding
@ 2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:19 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:41 +0300, Dmitry Osipenko wrote:
> Use a single reset_control_reset() instead of assert/deasset couple in
> order to make code cleaner a tad. Note that the reset_control_reset()
> uses 1 microsecond delay instead of 2 that was used previously, but this
> shouldn't matter because one microsecond is a default reset time for most
> of Tegra peripherals and TRM doesn't mention anything special in regards
> to I2C controller's reset propagation time.
> 
> In addition don't ignore potential error of the reset control by emitting
> a noisy warning if it fails, which will indicate an existence of a severe
> problem, while still allow machine to boot up.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Acked-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 13 ++++++++++---
>  1 file changed, 10 insertions(+), 3 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 10/34] i2c: tegra: Use devm_platform_get_and_ioremap_resource()
  2020-09-08 22:39 ` [PATCH v7 10/34] i2c: tegra: Use devm_platform_get_and_ioremap_resource() Dmitry Osipenko
  2020-09-17 11:31   ` Thierry Reding
@ 2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:19 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:42 +0300, Dmitry Osipenko wrote:
> Driver now uses devm_platform_get_and_ioremap_resource() which replaces
> the typical boilerplate code and makes code cleaner.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Acked-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 11/34] i2c: tegra: Use platform_get_irq()
  2020-09-08 22:39 ` [PATCH v7 11/34] i2c: tegra: Use platform_get_irq() Dmitry Osipenko
  2020-09-17 11:31   ` Thierry Reding
@ 2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:19 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:43 +0300, Dmitry Osipenko wrote:
> Use common helper for retrieval of the interrupt number in order to make
> code cleaner. Note that platform_get_irq() prints error message by itself.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Acked-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 9 +++------
>  1 file changed, 3 insertions(+), 6 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 12/34] i2c: tegra: Use clk-bulk helpers
  2020-09-08 22:39 ` [PATCH v7 12/34] i2c: tegra: Use clk-bulk helpers Dmitry Osipenko
  2020-09-17 11:38   ` Thierry Reding
@ 2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:19 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:44 +0300, Dmitry Osipenko wrote:
> Use clk-bulk helpers and factor out clocks initialization into separate
> function in order to make code cleaner.
> 
> The clocks initialization now performed after reset-control initialization
> in order to avoid a noisy -PROBE_DEFER errors on T186+ from the clk-bulk
> helper which doesn't silence this error code. Hence reset_control_get()
> now may return -EPROBE_DEFER on newer Tegra SoCs because they use BPMP
> driver that provides reset controls and BPMP doesn't come up early during
> boot. Previously rst was protected by the clocks retrieval and now this
> patch makes dev_err_probe() to be used for the rst error handling.
> 
> Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 187 ++++++++++++---------------------
>  1 file changed, 67 insertions(+), 120 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 13/34] i2c: tegra: Move out all device-tree parsing into tegra_i2c_parse_dt()
  2020-09-08 22:39 ` [PATCH v7 13/34] i2c: tegra: Move out all device-tree parsing into tegra_i2c_parse_dt() Dmitry Osipenko
  2020-09-17 11:35   ` Thierry Reding
@ 2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:19 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:45 +0300, Dmitry Osipenko wrote:
> Move out code related to device-tree parsing from the probe function into
> tegra_i2c_parse_dt() in order to make code more consistent.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Acked-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 14/34] i2c: tegra: Clean up probe function
  2020-09-08 22:39 ` [PATCH v7 14/34] i2c: tegra: Clean up probe function Dmitry Osipenko
  2020-09-17 12:37   ` Thierry Reding
@ 2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:19 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:46 +0300, Dmitry Osipenko wrote:
> The driver's probe function code is a bit difficult to read. This patch
> reorders code of the probe function, forming groups of code that are easy
> to work with. The probe tear-down order now matches the driver-removal
> order.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 100 ++++++++++++++++-----------------
>  1 file changed, 49 insertions(+), 51 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 15/34] i2c: tegra: Reorder location of functions in the code
  2020-09-08 22:39 ` [PATCH v7 15/34] i2c: tegra: Reorder location of functions in the code Dmitry Osipenko
  2020-09-17 12:38   ` Thierry Reding
@ 2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:19 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:47 +0300, Dmitry Osipenko wrote:
> Reorder location of functions in the code in order to have definition
> of functions closer to the place of the invocation. This change makes
> easier to navigate around the code and removes the need to have a
> prototype for tegra_i2c_init().
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Acked-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 486 ++++++++++++++++-----------------
>  1 file changed, 242 insertions(+), 244 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 16/34] i2c: tegra: Clean up variable types
  2020-09-08 22:39 ` [PATCH v7 16/34] i2c: tegra: Clean up variable types Dmitry Osipenko
  2020-09-17 12:39   ` Thierry Reding
@ 2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:19 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:48 +0300, Dmitry Osipenko wrote:
> Don't use signed types for unsigned values and use consistent types
> for sibling variables.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Acked-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 38 +++++++++++++++++-----------------
>  1 file changed, 19 insertions(+), 19 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 17/34] i2c: tegra: Remove outdated barrier()
  2020-09-08 22:39 ` [PATCH v7 17/34] i2c: tegra: Remove outdated barrier() Dmitry Osipenko
  2020-09-17 12:39   ` Thierry Reding
@ 2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:19 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:49 +0300, Dmitry Osipenko wrote:
> The barrier() was intended to reduce possibility of racing with the
> interrupt handler, but driver's code evolved significantly and today's
> driver enables interrupt only when it waits for completion notification.
> Hence barrier() has no good use anymore, let's remove it.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Acked-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 13 +++++--------
>  1 file changed, 5 insertions(+), 8 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 18/34] i2c: tegra: Remove likely/unlikely from the code
  2020-09-08 22:39 ` [PATCH v7 18/34] i2c: tegra: Remove likely/unlikely from the code Dmitry Osipenko
  2020-09-17 12:41   ` Thierry Reding
@ 2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:19 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:50 +0300, Dmitry Osipenko wrote:
> The likely/unlikely annotations should be used only in a hot paths of
> performance-critical code. The I2C driver doesn't have such paths, and
> thus, there is no justification for usage of likely/unlikely annotations
> in the code. Hence remove them.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Acked-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 19/34] i2c: tegra: Remove redundant check in tegra_i2c_issue_bus_clear()
  2020-09-08 22:39 ` [PATCH v7 19/34] i2c: tegra: Remove redundant check in tegra_i2c_issue_bus_clear() Dmitry Osipenko
  2020-09-17 12:42   ` Thierry Reding
@ 2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:19 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:51 +0300, Dmitry Osipenko wrote:
> The tegra_i2c_wait_for_config_load() checks for 'has_config_load_reg' by
> itself, hence there is no need to duplicate the check.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Acked-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 9 ++++-----
>  1 file changed, 4 insertions(+), 5 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 20/34] i2c: tegra: Remove "dma" variable from tegra_i2c_xfer_msg()
  2020-09-08 22:39 ` [PATCH v7 20/34] i2c: tegra: Remove "dma" variable from tegra_i2c_xfer_msg() Dmitry Osipenko
  2020-09-17 11:44   ` Thierry Reding
@ 2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:19 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:52 +0300, Dmitry Osipenko wrote:
> The "dma" variable of tegra_i2c_xfer_msg() function doesn't bring much in
> regards to readability and generation of the code.
> 
> Besides readability, it's also not very nice that the is_curr_dma_xfer
> is initialized in tegra_i2c_xfer_msg() and then could be overridden by
> tegra_i2c_config_fifo_trig(). In a result, the "dma" variable creates
> slight confusion since it's not instantly obvious why it's set after
> tegra_i2c_config_fifo_trig().
> 
> Hence should be better to have the variable removed. This makes code
> more consistent.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Acked-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 17 ++++++++---------
>  1 file changed, 8 insertions(+), 9 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 21/34] i2c: tegra: Don't fall back to PIO mode if DMA configuration fails
  2020-09-08 22:39 ` [PATCH v7 21/34] i2c: tegra: Don't fall back to PIO mode if DMA configuration fails Dmitry Osipenko
  2020-09-17 11:47   ` Thierry Reding
@ 2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:19 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:53 +0300, Dmitry Osipenko wrote:
> The DMA code path has been tested well enough and the DMA configuration
> performed by tegra_i2c_config_fifo_trig() shouldn't ever fail in practice.
> Hence let's remove the obscure transfer-mode switching in order to have a
> cleaner and simpler code. Now I2C transfer will be failed if DMA
> configuration fails.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 18 ++++++++++--------
>  1 file changed, 10 insertions(+), 8 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 22/34] i2c: tegra: Rename wait/poll functions
  2020-09-08 22:39 ` [PATCH v7 22/34] i2c: tegra: Rename wait/poll functions Dmitry Osipenko
  2020-09-17 11:48   ` Thierry Reding
@ 2020-09-21 10:19   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:19 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:54 +0300, Dmitry Osipenko wrote:
> Drop '_timeout' postfix from the wait/poll completion function names in
> order to make the names shorter, making code cleaner a tad.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Acked-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 32 ++++++++++++++------------------
>  1 file changed, 14 insertions(+), 18 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 23/34] i2c: tegra: Factor out error recovery from tegra_i2c_xfer_msg()
  2020-09-08 22:39 ` [PATCH v7 23/34] i2c: tegra: Factor out error recovery from tegra_i2c_xfer_msg() Dmitry Osipenko
  2020-09-17 11:49   ` Thierry Reding
@ 2020-09-21 10:20   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:20 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:55 +0300, Dmitry Osipenko wrote:
> Factor out error recovery code from tegra_i2c_xfer_msg() in order to
> make this function easier to read and follow.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Acked-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 46 ++++++++++++++++++++++------------
>  1 file changed, 30 insertions(+), 16 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 24/34] i2c: tegra: Factor out packet header setup from tegra_i2c_xfer_msg()
  2020-09-08 22:39 ` [PATCH v7 24/34] i2c: tegra: Factor out packet header setup " Dmitry Osipenko
  2020-09-17 11:51   ` Thierry Reding
@ 2020-09-21 10:20   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:20 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:56 +0300, Dmitry Osipenko wrote:
> The code related to packet header setting up is a bit messy and makes
> tegra_i2c_xfer_msg() more difficult to read than it could be. Let's
> factor the packet header setup from tegra_i2c_xfer_msg() into separate
> function in order to make code easier to read and follow.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Acked-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 92 ++++++++++++++++++++--------------
>  1 file changed, 53 insertions(+), 39 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 25/34] i2c: tegra: Factor out register polling into separate function
  2020-09-08 22:39 ` [PATCH v7 25/34] i2c: tegra: Factor out register polling into separate function Dmitry Osipenko
  2020-09-17 11:58   ` Thierry Reding
@ 2020-09-21 10:20   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:20 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:57 +0300, Dmitry Osipenko wrote:
> Factor out register polling into a separate function in order to remove
> boilerplate code and make code cleaner.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 57 +++++++++++++++-------------------
>  1 file changed, 25 insertions(+), 32 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 26/34] i2c: tegra: Factor out hardware initialization into separate function
  2020-09-08 22:39 ` [PATCH v7 26/34] i2c: tegra: Factor out hardware initialization " Dmitry Osipenko
  2020-09-17 12:06   ` Thierry Reding
@ 2020-09-21 10:20   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:20 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:58 +0300, Dmitry Osipenko wrote:
> Factor out hardware initialization into a separate function from the probe
> function. The only place where runtime PM needs to be resumed during probe
> is the place of hardware initialization, hence it makes sense to factor
> out it in order to have a bit cleaner error handling in tegra_i2c_probe().
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Acked-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 32 +++++++++++++++++++-------------
>  1 file changed, 19 insertions(+), 13 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 27/34] i2c: tegra: Check errors for both positive and negative values
  2020-09-08 22:39 ` [PATCH v7 27/34] i2c: tegra: Check errors for both positive and negative values Dmitry Osipenko
  2020-09-17 12:09   ` Thierry Reding
@ 2020-09-21 10:20   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:20 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:39:59 +0300, Dmitry Osipenko wrote:
> The driver's code is inconsistent in regards to the error values checking.
> The correct way should be to check both positive and negative values.
> This patch cleans up the error-checks in the code. Note that the
> pm_runtime_get_sync() could return positive value on success, hence only
> relevant parts of the code are changed by this patch.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 28/34] i2c: tegra: Consolidate error handling in tegra_i2c_xfer_msg()
  2020-09-08 22:40 ` [PATCH v7 28/34] i2c: tegra: Consolidate error handling in tegra_i2c_xfer_msg() Dmitry Osipenko
  2020-09-17 12:12   ` Thierry Reding
@ 2020-09-21 10:20   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:20 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:40:00 +0300, Dmitry Osipenko wrote:
> Consolidate error handling in tegra_i2c_xfer_msg() into a common code
> path in order to make code cleaner.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 13 +++++++++----
>  1 file changed, 9 insertions(+), 4 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 29/34] i2c: tegra: Improve formatting of variables
  2020-09-08 22:40 ` [PATCH v7 29/34] i2c: tegra: Improve formatting of variables Dmitry Osipenko
  2020-09-17 12:16   ` Thierry Reding
@ 2020-09-21 10:20   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:20 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:40:01 +0300, Dmitry Osipenko wrote:
> Reorder definition of variables in the code to have them sorted by length
> and grouped logically, also replace "unsigned long" with "u32". Do this in
> order to make code easier to read.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 97 ++++++++++++++++------------------
>  1 file changed, 45 insertions(+), 52 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 30/34] i2c: tegra: Clean up variable names
  2020-09-08 22:40 ` [PATCH v7 30/34] i2c: tegra: Clean up variable names Dmitry Osipenko
  2020-09-17 12:21   ` Thierry Reding
@ 2020-09-21 10:20   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:20 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:40:02 +0300, Dmitry Osipenko wrote:
> Rename "ret" variables to "err" in order to make code a bit more
> expressive, emphasizing that the returned value is an error code.
> Same vice versa, where appropriate.
> 
> Rename variable "reg" to "val" in order to better reflect the actual
> usage of the variable in the code and to make naming consistent with
> the rest of the code.
> 
> Use briefer names for a few members of the tegra_i2c_dev structure in
> order to improve readability of the code.
> 
> All dev/&pdev->dev are replaced with i2c_dev->dev in order to have uniform
> code style across the driver.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 173 ++++++++++++++++-----------------
>  1 file changed, 86 insertions(+), 87 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 31/34] i2c: tegra: Clean up printk messages
  2020-09-08 22:40 ` [PATCH v7 31/34] i2c: tegra: Clean up printk messages Dmitry Osipenko
  2020-09-17 12:22   ` Thierry Reding
@ 2020-09-21 10:20   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:20 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:40:03 +0300, Dmitry Osipenko wrote:
> This patch unifies style of all messages in the driver by starting them
> with a lowercase letter and using consistent capitalization and wording
> for all messages.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Acked-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 37 +++++++++++++---------------------
>  1 file changed, 14 insertions(+), 23 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 32/34] i2c: tegra: Clean up and improve comments
  2020-09-08 22:40 ` [PATCH v7 32/34] i2c: tegra: Clean up and improve comments Dmitry Osipenko
  2020-09-17 12:32   ` Thierry Reding
@ 2020-09-21 10:20   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:20 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:40:04 +0300, Dmitry Osipenko wrote:
> Make all comments to be consistent in regards to capitalization and
> punctuation, correct spelling and grammar errors, improve wording.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 88 ++++++++++++++++++----------------
>  1 file changed, 47 insertions(+), 41 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 33/34] i2c: tegra: Clean up whitespaces, newlines and indentation
  2020-09-08 22:40 ` [PATCH v7 33/34] i2c: tegra: Clean up whitespaces, newlines and indentation Dmitry Osipenko
  2020-09-17 12:35   ` Thierry Reding
@ 2020-09-21 10:20   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:20 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:40:05 +0300, Dmitry Osipenko wrote:
> Some places in the code are missing newlines or have unnecessary
> whitespaces and newlines. This creates inconsistency of the code and
> hurts readability. This patch removes the unnecessary and adds necessary
> whitespaces / newlines, clears indentation of the code.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Acked-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 72 +++++++++++++++++++++-------------
>  1 file changed, 45 insertions(+), 27 deletions(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 34/34] i2c: tegra: Improve driver module description
  2020-09-08 22:40 ` [PATCH v7 34/34] i2c: tegra: Improve driver module description Dmitry Osipenko
  2020-09-17 12:35   ` Thierry Reding
@ 2020-09-21 10:20   ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:20 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

On Wed, 09 Sep 2020 01:40:06 +0300, Dmitry Osipenko wrote:
> Use proper spelling of "NVIDIA" and don't designate driver as Tegra2-only
> since newer SoC generations are supported as well.
> 
> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> Acked-by: Thierry Reding <treding@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Tested-by: Thierry Reding <treding@nvidia.com>

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 00/34] Improvements for Tegra I2C driver
  2020-09-21 10:18 ` Thierry Reding
@ 2020-09-21 10:42   ` Thierry Reding
  0 siblings, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:42 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Dmitry Osipenko, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 10218 bytes --]

On Mon, Sep 21, 2020 at 10:18:27AM +0000, Thierry Reding wrote:
> On Wed, 09 Sep 2020 01:39:32 +0300, Dmitry Osipenko wrote:
> > Hello!
> > 
> > This series performs refactoring of the Tegra I2C driver code and hardens
> > the atomic-transfer mode.
> > 
> > Changelog:
> > 
> > v7: - Reworked the "Clean up probe function" patch by moving out all
> >       variable renamings into the "Clean up variable names" patch.
> >       This results in a nicer diff, which was asked by Andy Shevchenko.
> > 
> >     - Squashed "Improve coding style of tegra_i2c_wait_for_config_load()"
> >       patch into "Factor out register polling into separate function" in
> >       order avoid unnecessary ping-pong changes, which was asked by
> >       Andy Shevchenko.
> > 
> >     - Added more indentation improvements, it should be ideal now.
> > 
> >     - I haven't changed order of the "Clean up variable types" patch,
> >       which was suggested by Andy Shevchenko, because I already moved
> >       that patch multiple times and we decided to sort patches starting
> >       with more important cleanups and down to less important. The type
> >       changes are more important than shuffling code around, IMO.
> > 
> > v6: - Added new patch that adds missing RPM puts, thanks to Andy Shevchenko
> >       for the suggestion.
> > 
> >     - Improved commit messages by extending them with more a more detailed
> >       explanation of the changes.
> > 
> >     - Added clarifying comment to the "Use reset_control_reset()" change,
> >       which was asked by Andy Shevchenko.
> > 
> >     - Refactored the "Clean up probe function" patch by moving the
> >       dev_err_probe() change into the "Use clk-bulk helpers" patch,
> >       which was suggested by Andy Shevchenko.
> > 
> >     - Improved ordering of the patches like it was suggested by
> >       Andy Shevchenko.
> > 
> >     - Added Andy Shevchenko to suggested-by of the "Use clk-bulk helpers"
> >       patch.
> > 
> >     - Improved "Remove i2c_dev.clk_divisor_non_hs_mode member" patch by
> >       making the case-switch to use "fast plus mode" timing if clock rate
> >       is out-of-range. Just to make it more consistent.
> > 
> >     - The "Improve tegra_i2c_dev structure" patch is squashed into
> >      "Improve formatting of variables" and "Clean up types/names" patches.
> > 
> >     - All variable-renaming changes are squashed into a single "Clean up
> >       variable names" patch.
> > 
> >     - Made extra minor improvement to various patches, like more comments
> >       and indentations improved.
> > 
> > v5: - Dropped the "Factor out runtime PM and hardware initialization"
> >       patch, like it was suggested by Michał Mirosław. Instead a less
> >       invasive "Factor out hardware initialization into separate function"
> >       patch added, it doesn't touch the RPM initialization.
> > 
> >     - The "Remove outdated barrier()" patch now removes outdated comments.
> > 
> >     - Updated commit description of the "Remove "dma" variable" patch,
> >       saying that the transfer mode may be changed by a callee. This was
> >       suggested by Michał Mirosław.
> > 
> >     - Reworked the "Clean up and improve comments" patch. Couple more
> >       comments are corrected and reworded now.
> > 
> >     - Added r-b's from Michał Mirosław.
> > 
> >     - New patches:
> > 
> >         i2c: tegra: Mask interrupt in tegra_i2c_issue_bus_clear()
> >         i2c: tegra: Remove redundant check in tegra_i2c_issue_bus_clear()
> >         i2c: tegra: Don't fall back to PIO mode if DMA configuration fails
> >         i2c: tegra: Clean up variable types
> >         i2c: tegra: Improve tegra_i2c_dev structure
> > 
> > v4: - Reordered patches in the fixes/features/cleanups order like it was
> >       suggested by Andy Shevchenko.
> > 
> >     - Now using clk-bulk API, which was suggested by Andy Shevchenko.
> > 
> >     - Reworked "Make tegra_i2c_flush_fifos() usable in atomic transfer"
> >       patch to use iopoll API, which was suggested by Andy Shevchenko.
> > 
> >     - Separated "Clean up probe function" into several smaller patches.
> > 
> >     - Squashed "Add missing newline before returns" patch into
> >       "Clean up whitespaces, newlines and indentation".
> > 
> >     - The "Drop '_timeout' from wait/poll function names" is renamed to
> >       "Rename wait/poll functions".
> > 
> >     - The "Use reset_control_reset()" is changed to not fail tegra_i2c_init(),
> >       but only emit warning. This should be more friendly behaviour in oppose
> >       to having a non-bootable machine if reset-control fails.
> > 
> >     - New patches:
> > 
> >         i2c: tegra: Remove error message used for devm_request_irq() failure
> >         i2c: tegra: Use devm_platform_get_and_ioremap_resource()
> >         i2c: tegra: Use platform_get_irq()
> >         i2c: tegra: Use clk-bulk helpers
> >         i2c: tegra: Remove bogus barrier()
> >         i2c: tegra: Factor out register polling into separate function
> >         i2c: tegra: Consolidate error handling in tegra_i2c_xfer_msg()
> >         i2c: tegra: Clean up and improve comments
> >         i2c: tegra: Rename couple "ret" variables to "err"
> > 
> > v3: - Optimized "Make tegra_i2c_flush_fifos() usable in atomic transfer"
> >       patch by pre-checking FIFO state before starting to poll using
> >       ktime API, which may be expensive under some circumstances.
> > 
> >     - The "Clean up messages in the code" patch now makes all messages
> >       to use proper capitalization of abbreviations. Thanks to Andy Shevchenko
> >       and Michał Mirosław for the suggestion.
> > 
> >     - The "Remove unnecessary whitespaces and newlines" patch is transformed
> >       into "Clean up whitespaces and newlines", it now also adds missing
> >       newlines and spaces.
> > 
> >     - Reworked the "Clean up probe function" patch in accordance to
> >       suggestion from Michał Mirosław by factoring out only parts of
> >       the code that make error unwinding cleaner.
> > 
> >     - Added r-b from Michał Mirosław.
> > 
> >     - Added more patches:
> > 
> >         i2c: tegra: Reorder location of functions in the code
> >         i2c: tegra: Factor out packet header setup from tegra_i2c_xfer_msg()
> >         i2c: tegra: Remove "dma" variable
> >         i2c: tegra: Initialization div-clk rate unconditionally
> >         i2c: tegra: Remove i2c_dev.clk_divisor_non_hs_mode member
> > 
> > v2: - Cleaned more messages in the "Clean up messages in the code" patch.
> > 
> >     - The error code of reset_control_reset() is checked now.
> > 
> >     - Added these new patches to clean up couple more things:
> > 
> >         i2c: tegra: Check errors for both positive and negative values
> >         i2c: tegra: Improve coding style of tegra_i2c_wait_for_config_load()
> >         i2c: tegra: Remove unnecessary whitespaces and newlines
> >         i2c: tegra: Rename variable in tegra_i2c_issue_bus_clear()
> >         i2c: tegra: Improve driver module description
> > 
> > Dmitry Osipenko (34):
> >   i2c: tegra: Make tegra_i2c_flush_fifos() usable in atomic transfer
> >   i2c: tegra: Add missing pm_runtime_put()
> >   i2c: tegra: Handle potential error of tegra_i2c_flush_fifos()
> >   i2c: tegra: Mask interrupt in tegra_i2c_issue_bus_clear()
> >   i2c: tegra: Initialize div-clk rate unconditionally
> >   i2c: tegra: Remove i2c_dev.clk_divisor_non_hs_mode member
> >   i2c: tegra: Runtime PM always available on Tegra
> >   i2c: tegra: Remove error message used for devm_request_irq() failure
> >   i2c: tegra: Use reset_control_reset()
> >   i2c: tegra: Use devm_platform_get_and_ioremap_resource()
> >   i2c: tegra: Use platform_get_irq()
> >   i2c: tegra: Use clk-bulk helpers
> >   i2c: tegra: Move out all device-tree parsing into tegra_i2c_parse_dt()
> >   i2c: tegra: Clean up probe function
> >   i2c: tegra: Reorder location of functions in the code
> >   i2c: tegra: Clean up variable types
> >   i2c: tegra: Remove outdated barrier()
> >   i2c: tegra: Remove likely/unlikely from the code
> >   i2c: tegra: Remove redundant check in tegra_i2c_issue_bus_clear()
> >   i2c: tegra: Remove "dma" variable from tegra_i2c_xfer_msg()
> >   i2c: tegra: Don't fall back to PIO mode if DMA configuration fails
> >   i2c: tegra: Rename wait/poll functions
> >   i2c: tegra: Factor out error recovery from tegra_i2c_xfer_msg()
> >   i2c: tegra: Factor out packet header setup from tegra_i2c_xfer_msg()
> >   i2c: tegra: Factor out register polling into separate function
> >   i2c: tegra: Factor out hardware initialization into separate function
> >   i2c: tegra: Check errors for both positive and negative values
> >   i2c: tegra: Consolidate error handling in tegra_i2c_xfer_msg()
> >   i2c: tegra: Improve formatting of variables
> >   i2c: tegra: Clean up variable names
> >   i2c: tegra: Clean up printk messages
> >   i2c: tegra: Clean up and improve comments
> >   i2c: tegra: Clean up whitespaces, newlines and indentation
> >   i2c: tegra: Improve driver module description
> > 
> >  drivers/i2c/busses/i2c-tegra.c | 1435 ++++++++++++++++----------------
> >  1 file changed, 701 insertions(+), 734 deletions(-)
> > Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>

Hm... not sure how this ended up here. My reporting script is parsing
the mailbox from patchwork, so perhaps this is patchwork injecting any
stored tags into the mailbox?

> Test results:
>   14 builds: 14 pass, 0 fail
>    9 boots:  9 pass, 0 fail
>   47 tests:  47 pass, 0 fail
> 
> Boards tested: tegra20-ventana, tegra30-cardhu-a04, tegra124-jetson-tk1,
>                tegra186-p2771-0000, tegra194-p2972-0000

Looks like something went wrong here. Some additional boards were
tested, but the reporting script seems to have failed to retrieve
some of the logs and then decided not to include the boards here.

Anyway, I don't see any failures with this set of patches applied
so I think it's all good.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 06/34] i2c: tegra: Remove i2c_dev.clk_divisor_non_hs_mode member
  2020-09-17 15:27     ` Dmitry Osipenko
@ 2020-09-21 10:49       ` Thierry Reding
  0 siblings, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:49 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 3244 bytes --]

On Thu, Sep 17, 2020 at 06:27:28PM +0300, Dmitry Osipenko wrote:
> 17.09.2020 14:25, Thierry Reding пишет:
> > On Wed, Sep 09, 2020 at 01:39:38AM +0300, Dmitry Osipenko wrote:
> >> The "non_hs_mode" divisor value is fixed, thus there is no need to have
> >> the variable i2c_dev.clk_divisor_non_hs_mode struct member. Let's remove
> >> it and move the mode selection into tegra_i2c_init() where it can be
> >> united with the timing selection.
> >>
> >> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> >>  drivers/i2c/busses/i2c-tegra.c | 46 ++++++++++++++++------------------
> >>  1 file changed, 21 insertions(+), 25 deletions(-)
> >>
> >> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> >> index 720a75439e91..85ed0e02d48c 100644
> >> --- a/drivers/i2c/busses/i2c-tegra.c
> >> +++ b/drivers/i2c/busses/i2c-tegra.c
> >> @@ -250,7 +250,6 @@ struct tegra_i2c_hw_feature {
> >>   * @msg_buf_remaining: size of unsent data in the message buffer
> >>   * @msg_read: identifies read transfers
> >>   * @bus_clk_rate: current I2C bus clock rate
> >> - * @clk_divisor_non_hs_mode: clock divider for non-high-speed modes
> >>   * @is_multimaster_mode: track if I2C controller is in multi-master mode
> >>   * @tx_dma_chan: DMA transmit channel
> >>   * @rx_dma_chan: DMA receive channel
> >> @@ -281,7 +280,6 @@ struct tegra_i2c_dev {
> >>  	size_t msg_buf_remaining;
> >>  	int msg_read;
> >>  	u32 bus_clk_rate;
> >> -	u16 clk_divisor_non_hs_mode;
> >>  	bool is_multimaster_mode;
> >>  	struct dma_chan *tx_dma_chan;
> >>  	struct dma_chan *rx_dma_chan;
> >> @@ -783,6 +781,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
> >>  	u32 val;
> >>  	int err;
> >>  	u32 clk_divisor, clk_multiplier;
> >> +	u32 non_hs_mode;
> >>  	u32 tsu_thd;
> >>  	u8 tlow, thigh;
> >>  
> >> @@ -805,24 +804,33 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
> >>  	if (i2c_dev->is_vi)
> >>  		tegra_i2c_vi_init(i2c_dev);
> >>  
> >> -	/* Make sure clock divisor programmed correctly */
> >> -	clk_divisor = FIELD_PREP(I2C_CLK_DIVISOR_HSMODE,
> >> -				 i2c_dev->hw->clk_divisor_hs_mode) |
> >> -		      FIELD_PREP(I2C_CLK_DIVISOR_STD_FAST_MODE,
> >> -				 i2c_dev->clk_divisor_non_hs_mode);
> >> -	i2c_writel(i2c_dev, clk_divisor, I2C_CLK_DIVISOR);
> >> -
> >> -	if (i2c_dev->bus_clk_rate > I2C_MAX_STANDARD_MODE_FREQ &&
> >> -	    i2c_dev->bus_clk_rate <= I2C_MAX_FAST_MODE_PLUS_FREQ) {
> >> +	switch (i2c_dev->bus_clk_rate) {
> >> +	case I2C_MAX_STANDARD_MODE_FREQ + 1 ... I2C_MAX_FAST_MODE_PLUS_FREQ:
> > 
> > Is there are particular reason for switching the simple conditional to a
> > switch here? The old variant looks much easier to understand to me.
> 
> The reason is make it readable :) For me it's too difficult to read > <=
> && { } + no proper indentation.

Guess this is very subjective then... It would've been nice to avoid the
+ 1 and instead use the correct enumeration value. I think that would've
made it a little bit easier on the eye.

But anyway, no reason to hold up this patch set:

Reviewed-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 08/34] i2c: tegra: Remove error message used for devm_request_irq() failure
  2020-09-17 14:59     ` Dmitry Osipenko
@ 2020-09-21 10:57       ` Thierry Reding
  0 siblings, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 10:57 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2654 bytes --]

On Thu, Sep 17, 2020 at 05:59:28PM +0300, Dmitry Osipenko wrote:
> 17.09.2020 14:28, Thierry Reding пишет:
> > On Wed, Sep 09, 2020 at 01:39:40AM +0300, Dmitry Osipenko wrote:
> >> The error message prints number of vIRQ, which isn't a useful information.
> >> In practice devm_request_irq() never fails, hence let's remove the bogus
> >> message in order to make code cleaner.
> >>
> >> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> >>  drivers/i2c/busses/i2c-tegra.c | 4 +---
> >>  1 file changed, 1 insertion(+), 3 deletions(-)
> > 
> > I think I have seen this fail occasionally when something's wrong in the
> > IRQ code, or when we are not properly configuring the IRQ in device tree
> > for example.
> > 
> > So I'd prefer if this error message stayed here. I agree that it's not a
> > terribly useful error message, so perhaps adding the error code to it
> > would make it more helpful?
> 
> We have dtbs_check nowadays and I assume you only saw a such problem
> during of hardware bring-up, correct?

dtbs_check is far from perfect, especially since only a handful of
bindings have been converted for Tegra. It's also not going to catch any
functional issues. You could still have a valid combination of flags
passed via DTB and still the interrupt allocation could fail because it
just so happens that the particular combination wasn't valid in that
particular setup.

> Realistically, this error should never happen "randomly" and even if it
> will happen, then you will still know that I2C driver failed because
> driver-core will tell you about that.

And yes, this is the type of error that you typically get during
bring-up and it does obviously go away once you've fixed it and then
tends not to come back. But that's exactly what happens with most errors
and having error messages helps in finding what went wrong.

If we drop the error message, then I may notice that the I2C driver
didn't probe correctly. But in order to find out why it didn't, I have
to go and add error messages to narrow down where I need to look. The
whole point of having error messages in the code is to avoid having to
go in and modify the code in order to troubleshoot.

In the interest of moving this along I'm fine with this for now. But I
suspect that we'll run into an issue with this eventually and that we'll
have to add an error message here again. If that happens we can always
reintroduce one, and perhaps at that time do a better job of making it
actually useful.

Reviewed-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 12/34] i2c: tegra: Use clk-bulk helpers
  2020-09-17 13:54     ` Andy Shevchenko
@ 2020-09-21 11:01       ` Thierry Reding
  2020-09-21 11:15         ` Andy Shevchenko
  0 siblings, 1 reply; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 11:01 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Dmitry Osipenko, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, linux-i2c, linux-tegra,
	Linux Kernel Mailing List

[-- Attachment #1: Type: text/plain, Size: 2337 bytes --]

On Thu, Sep 17, 2020 at 04:54:28PM +0300, Andy Shevchenko wrote:
> On Thu, Sep 17, 2020 at 2:38 PM Thierry Reding <thierry.reding@gmail.com> wrote:
> > On Wed, Sep 09, 2020 at 01:39:44AM +0300, Dmitry Osipenko wrote:
> > > Use clk-bulk helpers and factor out clocks initialization into separate
> > > function in order to make code cleaner.
> > >
> > > The clocks initialization now performed after reset-control initialization
> > > in order to avoid a noisy -PROBE_DEFER errors on T186+ from the clk-bulk
> > > helper which doesn't silence this error code. Hence reset_control_get()
> > > now may return -EPROBE_DEFER on newer Tegra SoCs because they use BPMP
> > > driver that provides reset controls and BPMP doesn't come up early during
> > > boot. Previously rst was protected by the clocks retrieval and now this
> > > patch makes dev_err_probe() to be used for the rst error handling.
> > >
> > > Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
> > > Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> > > ---
> > >  drivers/i2c/busses/i2c-tegra.c | 187 ++++++++++++---------------------
> > >  1 file changed, 67 insertions(+), 120 deletions(-)
> >
> > This is tempting from a diffstat point of view, but the downside is that
> > we can now no longer validate that all of the necessary clocks are given
> > in device tree.
> >
> > Previously the driver would fail to probe the I2C controller if any of
> > the expected clocks were not defined in device tree, but now it's just
> > going to continue without it and not give any indication as to what's
> > wrong.
> 
> You may print an error in the error path as previously. Since both
> clocks are mandatory (as far as I understood the code) user will need
> to check DT in any case.

The problem is that the number of required clocks depends on the variant
of the IP block that's implemented. Some require just one clock and
others require two or three. With this patch the driver is just going to
pick whatever clocks are given in device tree, but it removes any
possibility of detecting whether the device trees contain the correct
clocks. So we may very well run into a situation where the driver now
successfully probes but then malfunctions because one or more of the
clocks were not specified in device tree.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 12/34] i2c: tegra: Use clk-bulk helpers
  2020-09-17 15:01     ` Dmitry Osipenko
@ 2020-09-21 11:08       ` Thierry Reding
  2020-09-21 11:12       ` Thierry Reding
  1 sibling, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 11:08 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 3205 bytes --]

On Thu, Sep 17, 2020 at 06:01:56PM +0300, Dmitry Osipenko wrote:
> 17.09.2020 14:38, Thierry Reding пишет:
> > On Wed, Sep 09, 2020 at 01:39:44AM +0300, Dmitry Osipenko wrote:
> >> Use clk-bulk helpers and factor out clocks initialization into separate
> >> function in order to make code cleaner.
> >>
> >> The clocks initialization now performed after reset-control initialization
> >> in order to avoid a noisy -PROBE_DEFER errors on T186+ from the clk-bulk
> >> helper which doesn't silence this error code. Hence reset_control_get()
> >> now may return -EPROBE_DEFER on newer Tegra SoCs because they use BPMP
> >> driver that provides reset controls and BPMP doesn't come up early during
> >> boot. Previously rst was protected by the clocks retrieval and now this
> >> patch makes dev_err_probe() to be used for the rst error handling.
> >>
> >> Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> >>  drivers/i2c/busses/i2c-tegra.c | 187 ++++++++++++---------------------
> >>  1 file changed, 67 insertions(+), 120 deletions(-)
> > 
> > This is tempting from a diffstat point of view, but the downside is that
> > we can now no longer validate that all of the necessary clocks are given
> > in device tree.
> > 
> > Previously the driver would fail to probe the I2C controller if any of
> > the expected clocks were not defined in device tree, but now it's just
> > going to continue without it and not give any indication as to what's
> > wrong.
> 
> The clocks can't be missed randomly in a device-tree because they are a
> part of the core tegra.dtsi

You can easily generate a device-tree without using the core DTS
includes.

> The tegra-i2c DT binding isn't converted to YAML, but once it will be,
> then the dtbs_check will tell you about such obvious problems like a
> missing mandatory property.

Once that has happened, yes, I think we may be able to simplify the
driver. But before that happens I don't think we should throw away our
only line of defense against broken device trees.

> Even if clock is missing, then you won't miss this problem since I2C
> shouldn't work in that case.

But the whole point of this error handling here is so that we can make
it easier to find the cause of an error. I2C malfunctioning can be
subtle. You could have some EEPROM on I2C that you normally don't touch,
but then at some point you try to access it from userspace and you read
garbage and then you need to start looking why this is happening. The
whole point of error messages is so that you can easily find the root
cause.

> There is a Qualcomm I2C driver that already uses clk_bulk_get_all() and
> doesn't worry about "accidentally" missing clocks.

Just because one particular driver doesn't care doesn't mean everybody
else should stop caring.

> It's still possible to add the clk-num checking, but it should be
> unpractical. We could always add it later on if there will be a real
> incident. Do you agree?

If there's an incident it's already too late. The whole point of error
checking here is to avoid any accidental breakage.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 12/34] i2c: tegra: Use clk-bulk helpers
  2020-09-17 15:01     ` Dmitry Osipenko
  2020-09-21 11:08       ` Thierry Reding
@ 2020-09-21 11:12       ` Thierry Reding
  2020-09-21 14:44         ` Dmitry Osipenko
  1 sibling, 1 reply; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 11:12 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 563 bytes --]

On Thu, Sep 17, 2020 at 06:01:56PM +0300, Dmitry Osipenko wrote:
[...]
> It's still possible to add the clk-num checking, but it should be
> unpractical. We could always add it later on if there will be a real
> incident. Do you agree?

There's also clk_bulk_get(), which allows you to specify the number of
clocks and their consumer IDs that you want to request. That seems like
it would allow us to both avoid the repetitive calls to clk APIs and at
the same time allows us to specify exactly which clocks we need. Would
that not work as a compromise?

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 12/34] i2c: tegra: Use clk-bulk helpers
  2020-09-21 11:01       ` Thierry Reding
@ 2020-09-21 11:15         ` Andy Shevchenko
  2020-09-21 11:53           ` Thierry Reding
  0 siblings, 1 reply; 146+ messages in thread
From: Andy Shevchenko @ 2020-09-21 11:15 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Dmitry Osipenko, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, linux-i2c, linux-tegra,
	Linux Kernel Mailing List

On Mon, Sep 21, 2020 at 2:02 PM Thierry Reding <thierry.reding@gmail.com> wrote:
> On Thu, Sep 17, 2020 at 04:54:28PM +0300, Andy Shevchenko wrote:
> > On Thu, Sep 17, 2020 at 2:38 PM Thierry Reding <thierry.reding@gmail.com> wrote:
> > > On Wed, Sep 09, 2020 at 01:39:44AM +0300, Dmitry Osipenko wrote:

...

> > > This is tempting from a diffstat point of view, but the downside is that
> > > we can now no longer validate that all of the necessary clocks are given
> > > in device tree.
> > >
> > > Previously the driver would fail to probe the I2C controller if any of
> > > the expected clocks were not defined in device tree, but now it's just
> > > going to continue without it and not give any indication as to what's
> > > wrong.
> >
> > You may print an error in the error path as previously. Since both
> > clocks are mandatory (as far as I understood the code) user will need
> > to check DT in any case.
>
> The problem is that the number of required clocks depends on the variant
> of the IP block that's implemented. Some require just one clock and
> others require two or three. With this patch the driver is just going to
> pick whatever clocks are given in device tree, but it removes any
> possibility of detecting whether the device trees contain the correct
> clocks. So we may very well run into a situation where the driver now
> successfully probes but then malfunctions because one or more of the
> clocks were not specified in device tree.
>
> Thierry

I still failed to get this. Are you suggesting that CCF bulk
operations are fundamentally broken?

In the above case one may add more checks. AFAICS is_vi won't be
removed, so can be easily checked.
Basically that for-loop for div_clk is questionable. I agree on that.


-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 14/34] i2c: tegra: Clean up probe function
  2020-09-17 13:46     ` Andy Shevchenko
@ 2020-09-21 11:15       ` Thierry Reding
  0 siblings, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 11:15 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Dmitry Osipenko, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, linux-i2c, linux-tegra,
	Linux Kernel Mailing List

[-- Attachment #1: Type: text/plain, Size: 1493 bytes --]

On Thu, Sep 17, 2020 at 04:46:45PM +0300, Andy Shevchenko wrote:
> On Thu, Sep 17, 2020 at 3:37 PM Thierry Reding <thierry.reding@gmail.com> wrote:
> > On Wed, Sep 09, 2020 at 01:39:46AM +0300, Dmitry Osipenko wrote:
> 
> ...
> 
> > > +     ret = devm_request_irq(&pdev->dev, i2c_dev->irq, tegra_i2c_isr,
> > > +                            IRQF_NO_SUSPEND, dev_name(&pdev->dev),
> > > +                            i2c_dev);
> > > +     if (ret)
> > > +             return ret;
> >
> > Is it safe to install the interrupt handler at this point? What if,
> > perhaps because some bootloader didn't properly quiesce the I2C
> > controller, an interrupt triggers immediately after this?
> 
> It\s easy to check with debug shared IRQ, but here IRQ is not shared...
> So, with a hack into the code and enabled debug it will be achievable to test.
> 
> And you probably meant that IRQ triggers *before* the handler is in place?

It shouldn't be possible for the interrupt to trigger before the handler
is in place, because requesting the IRQ here is what will unmask the IRQ
at the parent.

I'm more concerned that the hardware may be in some state where it
already has a pending interrupt and therefore unmasking (as part of the
request here) is going to immediately trigger an interrupt. If we
haven't set up i2c_dev completely at this point this may cause issues
because the interrupt handler will now have to deal with a partially
initialized structure.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 14/34] i2c: tegra: Clean up probe function
  2020-09-17 15:02     ` Dmitry Osipenko
@ 2020-09-21 11:17       ` Thierry Reding
  0 siblings, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 11:17 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 863 bytes --]

On Thu, Sep 17, 2020 at 06:02:26PM +0300, Dmitry Osipenko wrote:
> 17.09.2020 15:37, Thierry Reding пишет:
> ...
> >> +	/* interrupt will be enabled during of transfer time */
> >> +	irq_set_status_flags(i2c_dev->irq, IRQ_NOAUTOEN);
>                                            ^^^^^^^^^^^^
> 
> >> +	ret = devm_request_irq(&pdev->dev, i2c_dev->irq, tegra_i2c_isr,
> >> +			       IRQF_NO_SUSPEND, dev_name(&pdev->dev),
> >> +			       i2c_dev);
> >> +	if (ret)
> >> +		return ret;
> > 
> > Is it safe to install the interrupt handler at this point? What if,
> > perhaps because some bootloader didn't properly quiesce the I2C
> > controller, an interrupt triggers immediately after this?
> 
> This is why we're using the IRQ_NOAUTOEN flag above :)

Ah, I missed that. Seems fine then:

Reviewed-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 21/34] i2c: tegra: Don't fall back to PIO mode if DMA configuration fails
  2020-09-17 15:03     ` Dmitry Osipenko
@ 2020-09-21 11:21       ` Thierry Reding
  0 siblings, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 11:21 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1629 bytes --]

On Thu, Sep 17, 2020 at 06:03:04PM +0300, Dmitry Osipenko wrote:
> 17.09.2020 14:47, Thierry Reding пишет:
> > On Wed, Sep 09, 2020 at 01:39:53AM +0300, Dmitry Osipenko wrote:
> >> The DMA code path has been tested well enough and the DMA configuration
> >> performed by tegra_i2c_config_fifo_trig() shouldn't ever fail in practice.
> >> Hence let's remove the obscure transfer-mode switching in order to have a
> >> cleaner and simpler code. Now I2C transfer will be failed if DMA
> >> configuration fails.
> >>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> >>  drivers/i2c/busses/i2c-tegra.c | 18 ++++++++++--------
> >>  1 file changed, 10 insertions(+), 8 deletions(-)
> > 
> > I'm not sure that's a good idea. It's always possible that the DMA setup
> > is going to break because of something that's not related to the I2C
> > driver itself. Having the system completely break instead of falling
> > back to PIO mode seems like it would only complicate troubleshooting any
> > such issues.
> 
> That code has zero test coverage because this problem never happens in
> practice, hence it should be better to have it removed. We may consider
> re-adding it back if there will be a real-world incident, okay?

Again, I think throwing out fallbacks and error messages out the window
just because they "don't happen in practice" is misguided. Just because
they don't *usually* happen doesn't mean they can't happen. And in case
they do happen we absolutely do want some way of dealing with it rather
than just have the driver stop working without any explanation.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 25/34] i2c: tegra: Factor out register polling into separate function
  2020-09-17 15:05     ` Dmitry Osipenko
@ 2020-09-21 11:22       ` Thierry Reding
  0 siblings, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 11:22 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 4438 bytes --]

On Thu, Sep 17, 2020 at 06:05:41PM +0300, Dmitry Osipenko wrote:
> 17.09.2020 14:58, Thierry Reding пишет:
> > On Wed, Sep 09, 2020 at 01:39:57AM +0300, Dmitry Osipenko wrote:
> >> Factor out register polling into a separate function in order to remove
> >> boilerplate code and make code cleaner.
> >>
> >> Reviewed-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> >>  drivers/i2c/busses/i2c-tegra.c | 57 +++++++++++++++-------------------
> >>  1 file changed, 25 insertions(+), 32 deletions(-)
> >>
> >> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> >> index 405b87e28a98..e071de9ce106 100644
> >> --- a/drivers/i2c/busses/i2c-tegra.c
> >> +++ b/drivers/i2c/busses/i2c-tegra.c
> >> @@ -514,10 +514,24 @@ static void tegra_i2c_vi_init(struct tegra_i2c_dev *i2c_dev)
> >>  	i2c_writel(i2c_dev, 0x0, I2C_TLOW_SEXT);
> >>  }
> >>  
> >> +static int tegra_i2c_poll_register(struct tegra_i2c_dev *i2c_dev,
> >> +				   u32 reg, u32 mask, u32 delay_us,
> >> +				   u32 timeout_us)
> >> +{
> >> +	void __iomem *addr = i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg);
> >> +	u32 val;
> >> +
> >> +	if (!i2c_dev->is_curr_atomic_xfer)
> >> +		return readl_relaxed_poll_timeout(addr, val, !(val & mask),
> >> +						  delay_us, timeout_us);
> >> +
> >> +	return readl_relaxed_poll_timeout_atomic(addr, val, !(val & mask),
> >> +						 delay_us, timeout_us);
> >> +}
> >> +
> >>  static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
> >>  {
> >> -	u32 mask, val, offset, reg_offset;
> >> -	void __iomem *addr;
> >> +	u32 mask, val, offset;
> >>  	int err;
> >>  
> >>  	if (i2c_dev->hw->has_mst_fifo) {
> >> @@ -534,16 +548,7 @@ static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
> >>  	val |= mask;
> >>  	i2c_writel(i2c_dev, val, offset);
> >>  
> >> -	reg_offset = tegra_i2c_reg_addr(i2c_dev, offset);
> >> -	addr = i2c_dev->base + reg_offset;
> >> -
> >> -	if (i2c_dev->is_curr_atomic_xfer)
> >> -		err = readl_relaxed_poll_timeout_atomic(addr, val, !(val & mask),
> >> -							1000, 1000000);
> >> -	else
> >> -		err = readl_relaxed_poll_timeout(addr, val, !(val & mask),
> >> -						 1000, 1000000);
> >> -
> >> +	err = tegra_i2c_poll_register(i2c_dev, offset, mask, 1000, 1000000);
> >>  	if (err) {
> >>  		dev_err(i2c_dev->dev, "failed to flush FIFO\n");
> >>  		return err;
> >> @@ -553,30 +558,18 @@ static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
> >>  
> >>  static int tegra_i2c_wait_for_config_load(struct tegra_i2c_dev *i2c_dev)
> >>  {
> >> -	unsigned long reg_offset;
> >> -	void __iomem *addr;
> >> -	u32 val;
> >>  	int err;
> >>  
> >> -	if (i2c_dev->hw->has_config_load_reg) {
> >> -		reg_offset = tegra_i2c_reg_addr(i2c_dev, I2C_CONFIG_LOAD);
> >> -		addr = i2c_dev->base + reg_offset;
> >> -		i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, I2C_CONFIG_LOAD);
> >> +	if (!i2c_dev->hw->has_config_load_reg)
> >> +		return 0;
> >>  
> >> -		if (i2c_dev->is_curr_atomic_xfer)
> >> -			err = readl_relaxed_poll_timeout_atomic(
> >> -						addr, val, val == 0, 1000,
> >> -						I2C_CONFIG_LOAD_TIMEOUT);
> >> -		else
> >> -			err = readl_relaxed_poll_timeout(
> >> -						addr, val, val == 0, 1000,
> >> -						I2C_CONFIG_LOAD_TIMEOUT);
> >> +	i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, I2C_CONFIG_LOAD);
> >>  
> >> -		if (err) {
> >> -			dev_warn(i2c_dev->dev,
> >> -				 "timeout waiting for config load\n");
> >> -			return err;
> >> -		}
> >> +	err = tegra_i2c_poll_register(i2c_dev, I2C_CONFIG_LOAD, 0xffffffff,
> >> +				      1000, I2C_CONFIG_LOAD_TIMEOUT);
> >> +	if (err) {
> >> +		dev_warn(i2c_dev->dev, "timeout waiting for config load\n");
> >> +		return err;
> >>  	}
> > 
> > The deindentation in this hunk is messing up the diffstat in my opinion.
> > It would probably be worth splitting that into a separate patch to make
> > it more evident that this patch actually removes boilerplate.
> 
> This is intentional and it's mentioned in the v7 changelog.
> 
> Previously there was another patch that did what you're suggesting, but
> Andy Shevchenko objected that it was causing a "ping-pong" code changes
> where one patch did a change and then next patch changes the changed
> code again.

Hm... alright then:

Reviewed-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 27/34] i2c: tegra: Check errors for both positive and negative values
  2020-09-17 13:50     ` Andy Shevchenko
@ 2020-09-21 11:24       ` Thierry Reding
  2020-09-21 14:13         ` Dmitry Osipenko
  0 siblings, 1 reply; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 11:24 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Dmitry Osipenko, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, linux-i2c, linux-tegra,
	Linux Kernel Mailing List

[-- Attachment #1: Type: text/plain, Size: 631 bytes --]

On Thu, Sep 17, 2020 at 04:50:06PM +0300, Andy Shevchenko wrote:
> On Thu, Sep 17, 2020 at 3:09 PM Thierry Reding <thierry.reding@gmail.com> wrote:
> > On Wed, Sep 09, 2020 at 01:39:59AM +0300, Dmitry Osipenko wrote:
> 
> > Why? All of these functions "return 0 on success or a negative error
> > code on failure", don't they?
> 
> And what is the point of having ' < 0' in all those cases?

It's explicitly checking for the documented error cases. And you'll
occasionally have a function that can return non-zero on success.
Testing for < 0 is the safest way to check for failure in the majority
of cases.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 29/34] i2c: tegra: Improve formatting of variables
  2020-09-17 15:13     ` Dmitry Osipenko
@ 2020-09-21 11:28       ` Thierry Reding
  0 siblings, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 11:28 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 3468 bytes --]

On Thu, Sep 17, 2020 at 06:13:36PM +0300, Dmitry Osipenko wrote:
> 17.09.2020 15:16, Thierry Reding пишет:
> > On Wed, Sep 09, 2020 at 01:40:01AM +0300, Dmitry Osipenko wrote:
> >> Reorder definition of variables in the code to have them sorted by length
> >> and grouped logically, also replace "unsigned long" with "u32". Do this in
> >> order to make code easier to read.
> >>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> >>  drivers/i2c/busses/i2c-tegra.c | 97 ++++++++++++++++------------------
> >>  1 file changed, 45 insertions(+), 52 deletions(-)
> >>
> >> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> >> index ac40c87f1c21..2376f502d299 100644
> >> --- a/drivers/i2c/busses/i2c-tegra.c
> >> +++ b/drivers/i2c/busses/i2c-tegra.c
> >> @@ -259,42 +259,48 @@ struct tegra_i2c_hw_feature {
> >>   */
> >>  struct tegra_i2c_dev {
> >>  	struct device *dev;
> >> -	const struct tegra_i2c_hw_feature *hw;
> >>  	struct i2c_adapter adapter;
> >> -	struct clk *div_clk;
> >> -	struct clk_bulk_data *clocks;
> >> -	unsigned int nclocks;
> >> +
> >> +	const struct tegra_i2c_hw_feature *hw;
> >>  	struct reset_control *rst;
> >> -	void __iomem *base;
> >> -	phys_addr_t base_phys;
> >>  	unsigned int cont_id;
> >>  	unsigned int irq;
> >> -	bool is_dvc;
> >> -	bool is_vi;
> >> +
> >> +	phys_addr_t base_phys;
> >> +	void __iomem *base;
> >> +
> >> +	struct clk_bulk_data *clocks;
> >> +	unsigned int nclocks;
> >> +
> >> +	struct clk *div_clk;
> >> +	u32 bus_clk_rate;
> >> +
> >>  	struct completion msg_complete;
> >> +	size_t msg_buf_remaining;
> >>  	int msg_err;
> >>  	u8 *msg_buf;
> >> -	size_t msg_buf_remaining;
> >> -	bool msg_read;
> >> -	u32 bus_clk_rate;
> >> -	bool is_multimaster_mode;
> >> +
> >> +	struct completion dma_complete;
> >>  	struct dma_chan *tx_dma_chan;
> >>  	struct dma_chan *rx_dma_chan;
> >> +	unsigned int dma_buf_size;
> >>  	dma_addr_t dma_phys;
> >>  	u32 *dma_buf;
> >> -	unsigned int dma_buf_size;
> >> -	bool is_curr_dma_xfer;
> >> -	struct completion dma_complete;
> >> +
> >> +	bool is_multimaster_mode;
> >>  	bool is_curr_atomic_xfer;
> >> +	bool is_curr_dma_xfer;
> >> +	bool msg_read;
> >> +	bool is_dvc;
> >> +	bool is_vi;
> >>  };
> >>  
> >> -static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val,
> >> -		       unsigned long reg)
> >> +static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val, u32 reg)
> > 
> > I actually prefer unsigned long/int over u32 for offsets because it
> > makes it clearer that this is not in fact a 32-bit value that we're
> > writing into a register. This is especially true for these register
> > accessors where the "offset" is called "reg" and may be easily
> > mistaken for a register value.
> 
> That is a bit questionable, at least it definitely won't save me from a
> mistake :)

There's obviously no way of guaranteeing that nobody makes a mistake.
But especially with accessors the value and offset parameters are
inconsistently ordered, so any help we can provide at the API level
may help avoid mistakes. If you only look at the prototype, having two
u32 parameters doesn't give you *any* clue about what they are. But a
32-bit accessor that takes a u32 and an unsigned int is pretty obviously
expecting the 32-bit value in the u32 parameter and then the unsigned
int must obviously be the offset.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 30/34] i2c: tegra: Clean up variable names
  2020-09-17 15:43     ` Dmitry Osipenko
@ 2020-09-21 11:40       ` Thierry Reding
  2020-09-21 15:18         ` Dmitry Osipenko
  0 siblings, 1 reply; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 11:40 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2940 bytes --]

On Thu, Sep 17, 2020 at 06:43:28PM +0300, Dmitry Osipenko wrote:
> 17.09.2020 15:21, Thierry Reding пишет:
> > On Wed, Sep 09, 2020 at 01:40:02AM +0300, Dmitry Osipenko wrote:
> >> Rename "ret" variables to "err" in order to make code a bit more
> >> expressive, emphasizing that the returned value is an error code.
> >> Same vice versa, where appropriate.
> >>
> >> Rename variable "reg" to "val" in order to better reflect the actual
> >> usage of the variable in the code and to make naming consistent with
> >> the rest of the code.
> >>
> >> Use briefer names for a few members of the tegra_i2c_dev structure in
> >> order to improve readability of the code.
> >>
> >> All dev/&pdev->dev are replaced with i2c_dev->dev in order to have uniform
> >> code style across the driver.
> >>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> >>  drivers/i2c/busses/i2c-tegra.c | 173 ++++++++++++++++-----------------
> >>  1 file changed, 86 insertions(+), 87 deletions(-)
> > 
> > That's indeed a nice improvement. One thing did spring out at me,
> > though.
> > 
> >> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> > [...]
> >> @@ -1831,20 +1830,20 @@ static int __maybe_unused tegra_i2c_runtime_suspend(struct device *dev)
> >>  
> >>  	clk_bulk_disable(i2c_dev->nclocks, i2c_dev->clocks);
> >>  
> >> -	return pinctrl_pm_select_idle_state(i2c_dev->dev);
> >> +	return pinctrl_pm_select_idle_state(dev);
> >>  }
> >>  
> >>  static int __maybe_unused tegra_i2c_suspend(struct device *dev)
> >>  {
> >>  	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
> >> -	int err = 0;
> >> +	int ret = 0;
> >>  
> >>  	i2c_mark_adapter_suspended(&i2c_dev->adapter);
> >>  
> >>  	if (!pm_runtime_status_suspended(dev))
> >> -		err = tegra_i2c_runtime_suspend(dev);
> >> +		ret = tegra_i2c_runtime_suspend(dev);
> >>  
> >> -	return err;
> >> +	return ret;
> >>  }
> > 
> > Isn't this exactly the opposite of what the commit message says (and the
> > rest of the patch does)?
> 
> This change makes it to be consistent with the rest of the code. You may
> notice that "Factor out hardware initialization into separate function"
> made a similar change.
> 
> The reason I'm doing this is that the "err" suggests that code returns a
> error failure code, while it could be a success too and you don't know
> for sure by looking only at the part of code. Hence it's cleaner to use
> "err" when error code is returned.

I don't follow that reasoning. Every error code obviously also has a
value for success. Otherwise, what's the point of even having a function
if all it can do is fail. Success has to be an option for code to be any
useful at all, right?

The "err" variable here transports the error code and if that error code
happens to be 0 (meaning success), why does that no longer qualify as an
error code?

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 32/34] i2c: tegra: Clean up and improve comments
  2020-09-17 15:17       ` Dmitry Osipenko
@ 2020-09-21 11:43         ` Thierry Reding
  2020-09-21 11:44           ` Thierry Reding
  0 siblings, 1 reply; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 11:43 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 886 bytes --]

On Thu, Sep 17, 2020 at 06:17:39PM +0300, Dmitry Osipenko wrote:
> 17.09.2020 18:02, Dmitry Osipenko пишет:
> > 17.09.2020 15:32, Thierry Reding пишет:
> > ...
> >>>  /**
> >>> - * struct tegra_i2c_hw_feature : Different HW support on Tegra
> >>> - * @has_continue_xfer_support: Continue transfer supports.
> >>> + * struct tegra_i2c_hw_feature : per hardware generation features
> >>
> >> I think that space before ':' can go away. Although that's preexisting,
> >> so could also be a separate patch, I guess.
> > 
> > I haven't even noticed that!
> > 
> 
> Wait, that ':' is used only for the struct description, hence it
> actually looks natural in the code.

What makes the struct description different from the field descriptions?
A description list is basically:

  <term>: <description>

And it doesn't matter what exactly <term> is.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 32/34] i2c: tegra: Clean up and improve comments
  2020-09-21 11:43         ` Thierry Reding
@ 2020-09-21 11:44           ` Thierry Reding
  0 siblings, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 11:44 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1133 bytes --]

On Mon, Sep 21, 2020 at 01:43:20PM +0200, Thierry Reding wrote:
> On Thu, Sep 17, 2020 at 06:17:39PM +0300, Dmitry Osipenko wrote:
> > 17.09.2020 18:02, Dmitry Osipenko пишет:
> > > 17.09.2020 15:32, Thierry Reding пишет:
> > > ...
> > >>>  /**
> > >>> - * struct tegra_i2c_hw_feature : Different HW support on Tegra
> > >>> - * @has_continue_xfer_support: Continue transfer supports.
> > >>> + * struct tegra_i2c_hw_feature : per hardware generation features
> > >>
> > >> I think that space before ':' can go away. Although that's preexisting,
> > >> so could also be a separate patch, I guess.
> > > 
> > > I haven't even noticed that!
> > > 
> > 
> > Wait, that ':' is used only for the struct description, hence it
> > actually looks natural in the code.
> 
> What makes the struct description different from the field descriptions?
> A description list is basically:
> 
>   <term>: <description>
> 
> And it doesn't matter what exactly <term> is.

Anyway, like I said, this is preexisting, so we can always fix that up
in another patch:

Reviewed-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 12/34] i2c: tegra: Use clk-bulk helpers
  2020-09-21 11:15         ` Andy Shevchenko
@ 2020-09-21 11:53           ` Thierry Reding
  0 siblings, 0 replies; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 11:53 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Dmitry Osipenko, Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, linux-i2c, linux-tegra,
	Linux Kernel Mailing List

[-- Attachment #1: Type: text/plain, Size: 3155 bytes --]

On Mon, Sep 21, 2020 at 02:15:09PM +0300, Andy Shevchenko wrote:
> On Mon, Sep 21, 2020 at 2:02 PM Thierry Reding <thierry.reding@gmail.com> wrote:
> > On Thu, Sep 17, 2020 at 04:54:28PM +0300, Andy Shevchenko wrote:
> > > On Thu, Sep 17, 2020 at 2:38 PM Thierry Reding <thierry.reding@gmail.com> wrote:
> > > > On Wed, Sep 09, 2020 at 01:39:44AM +0300, Dmitry Osipenko wrote:
> 
> ...
> 
> > > > This is tempting from a diffstat point of view, but the downside is that
> > > > we can now no longer validate that all of the necessary clocks are given
> > > > in device tree.
> > > >
> > > > Previously the driver would fail to probe the I2C controller if any of
> > > > the expected clocks were not defined in device tree, but now it's just
> > > > going to continue without it and not give any indication as to what's
> > > > wrong.
> > >
> > > You may print an error in the error path as previously. Since both
> > > clocks are mandatory (as far as I understood the code) user will need
> > > to check DT in any case.
> >
> > The problem is that the number of required clocks depends on the variant
> > of the IP block that's implemented. Some require just one clock and
> > others require two or three. With this patch the driver is just going to
> > pick whatever clocks are given in device tree, but it removes any
> > possibility of detecting whether the device trees contain the correct
> > clocks. So we may very well run into a situation where the driver now
> > successfully probes but then malfunctions because one or more of the
> > clocks were not specified in device tree.
> >
> > Thierry
> 
> I still failed to get this. Are you suggesting that CCF bulk
> operations are fundamentally broken?

No, I'm not suggesting that. All I'm saying is the way that they are
used here is causing the driver to behave differently that it was
before.

Taking for example the VI I2C controller instantiation. That requires
the "slow" clock to be specified. Previously if the VI I2C device tree
node didn't have that "slow" clock specified, the I2C driver probe would
exit with an error code. After this change it will simply not see the
"slow" clock and then just continue without it as if it was optional.

In other words, after this patch we have no way of saying which clocks
are required and which are optional. They all become optional, basically
and the driver would attempt to continue (and most likely hang) if no
clocks at all had been specified in device tree.

> In the above case one may add more checks. AFAICS is_vi won't be
> removed, so can be easily checked.
> Basically that for-loop for div_clk is questionable. I agree on that.

But we need that one to find which of the clocks is the divider clock so
that we can call clk_set_rate() on it later on. It's a bit odd that we'd
just continue even if we didn't find the divider clock. I think the CCF
does handle this transparently and will just no-op all the calls for
NULL clocks, but it still means that we won't be running the I2C bus at
the right frequency if the divider clock was not specified in device
tree.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 27/34] i2c: tegra: Check errors for both positive and negative values
  2020-09-21 11:24       ` Thierry Reding
@ 2020-09-21 14:13         ` Dmitry Osipenko
  0 siblings, 0 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-21 14:13 UTC (permalink / raw)
  To: Thierry Reding, Andy Shevchenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, linux-i2c, linux-tegra,
	Linux Kernel Mailing List

21.09.2020 14:24, Thierry Reding пишет:
> On Thu, Sep 17, 2020 at 04:50:06PM +0300, Andy Shevchenko wrote:
>> On Thu, Sep 17, 2020 at 3:09 PM Thierry Reding <thierry.reding@gmail.com> wrote:
>>> On Wed, Sep 09, 2020 at 01:39:59AM +0300, Dmitry Osipenko wrote:
>>
>>> Why? All of these functions "return 0 on success or a negative error
>>> code on failure", don't they?
>>
>> And what is the point of having ' < 0' in all those cases?
> 
> It's explicitly checking for the documented error cases. And you'll
> occasionally have a function that can return non-zero on success.
> Testing for < 0 is the safest way to check for failure in the majority
> of cases.

If you're testing only for negative errors, then it means that you will
miss wrong positive errors, potentially setting machine on fire :) This
is not an often problem for kernel, but this is a problem that I
experienced with userspace more than one time.

Anyways, this patch also makes the errors checking consistent across the
whole driver and it makes the code look cleaner, so I'll prefer to keep
this patch as-is.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 12/34] i2c: tegra: Use clk-bulk helpers
  2020-09-21 11:12       ` Thierry Reding
@ 2020-09-21 14:44         ` Dmitry Osipenko
  0 siblings, 0 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-21 14:44 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

21.09.2020 14:12, Thierry Reding пишет:
> On Thu, Sep 17, 2020 at 06:01:56PM +0300, Dmitry Osipenko wrote:
> [...]
>> It's still possible to add the clk-num checking, but it should be
>> unpractical. We could always add it later on if there will be a real
>> incident. Do you agree?
> 
> There's also clk_bulk_get(), which allows you to specify the number of
> clocks and their consumer IDs that you want to request. That seems like
> it would allow us to both avoid the repetitive calls to clk APIs and at
> the same time allows us to specify exactly which clocks we need. Would
> that not work as a compromise?

I'll change to use clk_bulk_get(), thanks.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 30/34] i2c: tegra: Clean up variable names
  2020-09-21 11:40       ` Thierry Reding
@ 2020-09-21 15:18         ` Dmitry Osipenko
  2020-09-21 15:50           ` Thierry Reding
  0 siblings, 1 reply; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-21 15:18 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

21.09.2020 14:40, Thierry Reding пишет:
> On Thu, Sep 17, 2020 at 06:43:28PM +0300, Dmitry Osipenko wrote:
>> 17.09.2020 15:21, Thierry Reding пишет:
>>> On Wed, Sep 09, 2020 at 01:40:02AM +0300, Dmitry Osipenko wrote:
>>>> Rename "ret" variables to "err" in order to make code a bit more
>>>> expressive, emphasizing that the returned value is an error code.
>>>> Same vice versa, where appropriate.
>>>>
>>>> Rename variable "reg" to "val" in order to better reflect the actual
>>>> usage of the variable in the code and to make naming consistent with
>>>> the rest of the code.
>>>>
>>>> Use briefer names for a few members of the tegra_i2c_dev structure in
>>>> order to improve readability of the code.
>>>>
>>>> All dev/&pdev->dev are replaced with i2c_dev->dev in order to have uniform
>>>> code style across the driver.
>>>>
>>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>>>> ---
>>>>  drivers/i2c/busses/i2c-tegra.c | 173 ++++++++++++++++-----------------
>>>>  1 file changed, 86 insertions(+), 87 deletions(-)
>>>
>>> That's indeed a nice improvement. One thing did spring out at me,
>>> though.
>>>
>>>> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
>>> [...]
>>>> @@ -1831,20 +1830,20 @@ static int __maybe_unused tegra_i2c_runtime_suspend(struct device *dev)
>>>>  
>>>>  	clk_bulk_disable(i2c_dev->nclocks, i2c_dev->clocks);
>>>>  
>>>> -	return pinctrl_pm_select_idle_state(i2c_dev->dev);
>>>> +	return pinctrl_pm_select_idle_state(dev);
>>>>  }
>>>>  
>>>>  static int __maybe_unused tegra_i2c_suspend(struct device *dev)
>>>>  {
>>>>  	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
>>>> -	int err = 0;
>>>> +	int ret = 0;
>>>>  
>>>>  	i2c_mark_adapter_suspended(&i2c_dev->adapter);
>>>>  
>>>>  	if (!pm_runtime_status_suspended(dev))
>>>> -		err = tegra_i2c_runtime_suspend(dev);
>>>> +		ret = tegra_i2c_runtime_suspend(dev);
>>>>  
>>>> -	return err;
>>>> +	return ret;
>>>>  }
>>>
>>> Isn't this exactly the opposite of what the commit message says (and the
>>> rest of the patch does)?
>>
>> This change makes it to be consistent with the rest of the code. You may
>> notice that "Factor out hardware initialization into separate function"
>> made a similar change.
>>
>> The reason I'm doing this is that the "err" suggests that code returns a
>> error failure code, while it could be a success too and you don't know
>> for sure by looking only at the part of code. Hence it's cleaner to use
>> "err" when error code is returned.
> 
> I don't follow that reasoning. Every error code obviously also has a
> value for success. Otherwise, what's the point of even having a function
> if all it can do is fail. Success has to be an option for code to be any
> useful at all, right?
> 
> The "err" variable here transports the error code and if that error code
> happens to be 0 (meaning success), why does that no longer qualify as an
> error code?

If you're naming variable as "err", then this implies to me that it will
contain a error code if error variable is returned directly. Error
shouldn't relate to a success. In practice nobody pays much attention to
variable naming, so usually there is a need to check what code actually
does anyways. I don't care much about this and just wanting to make a
minor improvement while at it.

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 30/34] i2c: tegra: Clean up variable names
  2020-09-21 15:18         ` Dmitry Osipenko
@ 2020-09-21 15:50           ` Thierry Reding
  2020-09-21 16:05             ` Dmitry Osipenko
  0 siblings, 1 reply; 146+ messages in thread
From: Thierry Reding @ 2020-09-21 15:50 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 5417 bytes --]

On Mon, Sep 21, 2020 at 06:18:59PM +0300, Dmitry Osipenko wrote:
> 21.09.2020 14:40, Thierry Reding пишет:
> > On Thu, Sep 17, 2020 at 06:43:28PM +0300, Dmitry Osipenko wrote:
> >> 17.09.2020 15:21, Thierry Reding пишет:
> >>> On Wed, Sep 09, 2020 at 01:40:02AM +0300, Dmitry Osipenko wrote:
> >>>> Rename "ret" variables to "err" in order to make code a bit more
> >>>> expressive, emphasizing that the returned value is an error code.
> >>>> Same vice versa, where appropriate.
> >>>>
> >>>> Rename variable "reg" to "val" in order to better reflect the actual
> >>>> usage of the variable in the code and to make naming consistent with
> >>>> the rest of the code.
> >>>>
> >>>> Use briefer names for a few members of the tegra_i2c_dev structure in
> >>>> order to improve readability of the code.
> >>>>
> >>>> All dev/&pdev->dev are replaced with i2c_dev->dev in order to have uniform
> >>>> code style across the driver.
> >>>>
> >>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >>>> ---
> >>>>  drivers/i2c/busses/i2c-tegra.c | 173 ++++++++++++++++-----------------
> >>>>  1 file changed, 86 insertions(+), 87 deletions(-)
> >>>
> >>> That's indeed a nice improvement. One thing did spring out at me,
> >>> though.
> >>>
> >>>> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> >>> [...]
> >>>> @@ -1831,20 +1830,20 @@ static int __maybe_unused tegra_i2c_runtime_suspend(struct device *dev)
> >>>>  
> >>>>  	clk_bulk_disable(i2c_dev->nclocks, i2c_dev->clocks);
> >>>>  
> >>>> -	return pinctrl_pm_select_idle_state(i2c_dev->dev);
> >>>> +	return pinctrl_pm_select_idle_state(dev);
> >>>>  }
> >>>>  
> >>>>  static int __maybe_unused tegra_i2c_suspend(struct device *dev)
> >>>>  {
> >>>>  	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
> >>>> -	int err = 0;
> >>>> +	int ret = 0;
> >>>>  
> >>>>  	i2c_mark_adapter_suspended(&i2c_dev->adapter);
> >>>>  
> >>>>  	if (!pm_runtime_status_suspended(dev))
> >>>> -		err = tegra_i2c_runtime_suspend(dev);
> >>>> +		ret = tegra_i2c_runtime_suspend(dev);
> >>>>  
> >>>> -	return err;
> >>>> +	return ret;
> >>>>  }
> >>>
> >>> Isn't this exactly the opposite of what the commit message says (and the
> >>> rest of the patch does)?
> >>
> >> This change makes it to be consistent with the rest of the code. You may
> >> notice that "Factor out hardware initialization into separate function"
> >> made a similar change.
> >>
> >> The reason I'm doing this is that the "err" suggests that code returns a
> >> error failure code, while it could be a success too and you don't know
> >> for sure by looking only at the part of code. Hence it's cleaner to use
> >> "err" when error code is returned.
> > 
> > I don't follow that reasoning. Every error code obviously also has a
> > value for success. Otherwise, what's the point of even having a function
> > if all it can do is fail. Success has to be an option for code to be any
> > useful at all, right?
> > 
> > The "err" variable here transports the error code and if that error code
> > happens to be 0 (meaning success), why does that no longer qualify as an
> > error code?
> 
> If you're naming variable as "err", then this implies to me that it will
> contain a error code if error variable is returned directly. Error
> shouldn't relate to a success. In practice nobody pays much attention to
> variable naming, so usually there is a need to check what code actually
> does anyways. I don't care much about this and just wanting to make a
> minor improvement while at it.

Oh... I think I get what you're trying to do here now. You're saying
that we may be storing a positive success result in this variable and
therefore it would be wrong to call it "error", right?

And I always thought I was pedantic... =)

The way I see it, any success value can still be considered an error
code. Typically you either propagate the value immediately for errors or
you just ignore it on success. In that case, keeping it in a variable a
bit beyond the assignment isn't a big issue. What matters is that you
don't use it. There are some exceptions where this can look weird, such
as:

	err = platform_get_irq(pdev, 0);
	if (err < 0)
		return err;

	chip->irq = err;

Although I think that's still okay and can be useful for example if
chip->irq is an unsigned int, and hence you can't do:

	chip->irq = platform_get_irq(pdev, 0);
	if (chip->irq < 0)
		return chip->irq;

My main gripe with variables named "ret" or "retval" is that I often see
them not used as return value at all. Or the other extreme is that every
variable is at some point a return value if it stores the result of a
function call. So I think "ret" is just fundamentally a bad choice. But
I also realize that that's very subjective.

Anyway, I would personally lean towards calling all these "err" instead
of "ret", but I think consistency trumps personal preference, so I would
not object to "ret" generally. But I think it's a bit extreme to use err
everywhere else and use "ret" only when we don't immediately return the
error code because I think that's just too subtle of a difference to
make up for the inconsistency.

On the other hand, we've spent way too much time discussing this, so
just pick whatever you want:

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 146+ messages in thread

* Re: [PATCH v7 30/34] i2c: tegra: Clean up variable names
  2020-09-21 15:50           ` Thierry Reding
@ 2020-09-21 16:05             ` Dmitry Osipenko
  0 siblings, 0 replies; 146+ messages in thread
From: Dmitry Osipenko @ 2020-09-21 16:05 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Laxman Dewangan, Wolfram Sang,
	Michał Mirosław, Andy Shevchenko, linux-i2c,
	linux-tegra, linux-kernel

21.09.2020 18:50, Thierry Reding пишет:
> On Mon, Sep 21, 2020 at 06:18:59PM +0300, Dmitry Osipenko wrote:
>> 21.09.2020 14:40, Thierry Reding пишет:
>>> On Thu, Sep 17, 2020 at 06:43:28PM +0300, Dmitry Osipenko wrote:
>>>> 17.09.2020 15:21, Thierry Reding пишет:
>>>>> On Wed, Sep 09, 2020 at 01:40:02AM +0300, Dmitry Osipenko wrote:
>>>>>> Rename "ret" variables to "err" in order to make code a bit more
>>>>>> expressive, emphasizing that the returned value is an error code.
>>>>>> Same vice versa, where appropriate.
>>>>>>
>>>>>> Rename variable "reg" to "val" in order to better reflect the actual
>>>>>> usage of the variable in the code and to make naming consistent with
>>>>>> the rest of the code.
>>>>>>
>>>>>> Use briefer names for a few members of the tegra_i2c_dev structure in
>>>>>> order to improve readability of the code.
>>>>>>
>>>>>> All dev/&pdev->dev are replaced with i2c_dev->dev in order to have uniform
>>>>>> code style across the driver.
>>>>>>
>>>>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>>>>>> ---
>>>>>>  drivers/i2c/busses/i2c-tegra.c | 173 ++++++++++++++++-----------------
>>>>>>  1 file changed, 86 insertions(+), 87 deletions(-)
>>>>>
>>>>> That's indeed a nice improvement. One thing did spring out at me,
>>>>> though.
>>>>>
>>>>>> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
>>>>> [...]
>>>>>> @@ -1831,20 +1830,20 @@ static int __maybe_unused tegra_i2c_runtime_suspend(struct device *dev)
>>>>>>  
>>>>>>  	clk_bulk_disable(i2c_dev->nclocks, i2c_dev->clocks);
>>>>>>  
>>>>>> -	return pinctrl_pm_select_idle_state(i2c_dev->dev);
>>>>>> +	return pinctrl_pm_select_idle_state(dev);
>>>>>>  }
>>>>>>  
>>>>>>  static int __maybe_unused tegra_i2c_suspend(struct device *dev)
>>>>>>  {
>>>>>>  	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
>>>>>> -	int err = 0;
>>>>>> +	int ret = 0;
>>>>>>  
>>>>>>  	i2c_mark_adapter_suspended(&i2c_dev->adapter);
>>>>>>  
>>>>>>  	if (!pm_runtime_status_suspended(dev))
>>>>>> -		err = tegra_i2c_runtime_suspend(dev);
>>>>>> +		ret = tegra_i2c_runtime_suspend(dev);
>>>>>>  
>>>>>> -	return err;
>>>>>> +	return ret;
>>>>>>  }
>>>>>
>>>>> Isn't this exactly the opposite of what the commit message says (and the
>>>>> rest of the patch does)?
>>>>
>>>> This change makes it to be consistent with the rest of the code. You may
>>>> notice that "Factor out hardware initialization into separate function"
>>>> made a similar change.
>>>>
>>>> The reason I'm doing this is that the "err" suggests that code returns a
>>>> error failure code, while it could be a success too and you don't know
>>>> for sure by looking only at the part of code. Hence it's cleaner to use
>>>> "err" when error code is returned.
>>>
>>> I don't follow that reasoning. Every error code obviously also has a
>>> value for success. Otherwise, what's the point of even having a function
>>> if all it can do is fail. Success has to be an option for code to be any
>>> useful at all, right?
>>>
>>> The "err" variable here transports the error code and if that error code
>>> happens to be 0 (meaning success), why does that no longer qualify as an
>>> error code?
>>
>> If you're naming variable as "err", then this implies to me that it will
>> contain a error code if error variable is returned directly. Error
>> shouldn't relate to a success. In practice nobody pays much attention to
>> variable naming, so usually there is a need to check what code actually
>> does anyways. I don't care much about this and just wanting to make a
>> minor improvement while at it.
> 
> Oh... I think I get what you're trying to do here now. You're saying
> that we may be storing a positive success result in this variable and
> therefore it would be wrong to call it "error", right?
> 
> And I always thought I was pedantic... =)
> 
> The way I see it, any success value can still be considered an error
> code. Typically you either propagate the value immediately for errors or
> you just ignore it on success. In that case, keeping it in a variable a
> bit beyond the assignment isn't a big issue. What matters is that you
> don't use it. There are some exceptions where this can look weird, such
> as:
> 
> 	err = platform_get_irq(pdev, 0);
> 	if (err < 0)
> 		return err;
> 
> 	chip->irq = err;
> 
> Although I think that's still okay and can be useful for example if
> chip->irq is an unsigned int, and hence you can't do:
> 
> 	chip->irq = platform_get_irq(pdev, 0);
> 	if (chip->irq < 0)
> 		return chip->irq;
> 
> My main gripe with variables named "ret" or "retval" is that I often see
> them not used as return value at all. Or the other extreme is that every
> variable is at some point a return value if it stores the result of a
> function call. So I think "ret" is just fundamentally a bad choice. But
> I also realize that that's very subjective.
> 
> Anyway, I would personally lean towards calling all these "err" instead
> of "ret", but I think consistency trumps personal preference, so I would
> not object to "ret" generally. But I think it's a bit extreme to use err
> everywhere else and use "ret" only when we don't immediately return the
> error code because I think that's just too subtle of a difference to
> make up for the inconsistency.
> 
> On the other hand, we've spent way too much time discussing this, so
> just pick whatever you want:
> 
> Acked-by: Thierry Reding <treding@nvidia.com>
> 

Thanks, I'll change it to make tegra_i2c_suspend() to use the same style
as tegra_i2c_resume() uses, which should be the best option in this case.

^ permalink raw reply	[flat|nested] 146+ messages in thread

end of thread, other threads:[~2020-09-21 16:05 UTC | newest]

Thread overview: 146+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-08 22:39 [PATCH v7 00/34] Improvements for Tegra I2C driver Dmitry Osipenko
2020-09-08 22:39 ` [PATCH v7 01/34] i2c: tegra: Make tegra_i2c_flush_fifos() usable in atomic transfer Dmitry Osipenko
2020-09-17 11:10   ` Thierry Reding
2020-09-17 14:57     ` Dmitry Osipenko
2020-09-21 10:18   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 02/34] i2c: tegra: Add missing pm_runtime_put() Dmitry Osipenko
2020-09-17 11:12   ` Thierry Reding
2020-09-21 10:18   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 03/34] i2c: tegra: Handle potential error of tegra_i2c_flush_fifos() Dmitry Osipenko
2020-09-17 11:13   ` Thierry Reding
2020-09-21 10:18   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 04/34] i2c: tegra: Mask interrupt in tegra_i2c_issue_bus_clear() Dmitry Osipenko
2020-09-17 11:18   ` Thierry Reding
2020-09-21 10:18   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 05/34] i2c: tegra: Initialize div-clk rate unconditionally Dmitry Osipenko
2020-09-17 11:20   ` Thierry Reding
2020-09-21 10:18   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 06/34] i2c: tegra: Remove i2c_dev.clk_divisor_non_hs_mode member Dmitry Osipenko
2020-09-17 11:25   ` Thierry Reding
2020-09-17 15:27     ` Dmitry Osipenko
2020-09-21 10:49       ` Thierry Reding
2020-09-21 10:18   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 07/34] i2c: tegra: Runtime PM always available on Tegra Dmitry Osipenko
2020-09-17 11:26   ` Thierry Reding
2020-09-21 10:18   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 08/34] i2c: tegra: Remove error message used for devm_request_irq() failure Dmitry Osipenko
2020-09-17 11:28   ` Thierry Reding
2020-09-17 14:59     ` Dmitry Osipenko
2020-09-21 10:57       ` Thierry Reding
2020-09-21 10:18   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 09/34] i2c: tegra: Use reset_control_reset() Dmitry Osipenko
2020-09-17 12:36   ` Thierry Reding
2020-09-21 10:19   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 10/34] i2c: tegra: Use devm_platform_get_and_ioremap_resource() Dmitry Osipenko
2020-09-17 11:31   ` Thierry Reding
2020-09-21 10:19   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 11/34] i2c: tegra: Use platform_get_irq() Dmitry Osipenko
2020-09-17 11:31   ` Thierry Reding
2020-09-21 10:19   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 12/34] i2c: tegra: Use clk-bulk helpers Dmitry Osipenko
2020-09-17 11:38   ` Thierry Reding
2020-09-17 13:54     ` Andy Shevchenko
2020-09-21 11:01       ` Thierry Reding
2020-09-21 11:15         ` Andy Shevchenko
2020-09-21 11:53           ` Thierry Reding
2020-09-17 15:01     ` Dmitry Osipenko
2020-09-21 11:08       ` Thierry Reding
2020-09-21 11:12       ` Thierry Reding
2020-09-21 14:44         ` Dmitry Osipenko
2020-09-21 10:19   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 13/34] i2c: tegra: Move out all device-tree parsing into tegra_i2c_parse_dt() Dmitry Osipenko
2020-09-17 11:35   ` Thierry Reding
2020-09-21 10:19   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 14/34] i2c: tegra: Clean up probe function Dmitry Osipenko
2020-09-17 12:37   ` Thierry Reding
2020-09-17 13:46     ` Andy Shevchenko
2020-09-21 11:15       ` Thierry Reding
2020-09-17 15:02     ` Dmitry Osipenko
2020-09-21 11:17       ` Thierry Reding
2020-09-21 10:19   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 15/34] i2c: tegra: Reorder location of functions in the code Dmitry Osipenko
2020-09-17 12:38   ` Thierry Reding
2020-09-21 10:19   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 16/34] i2c: tegra: Clean up variable types Dmitry Osipenko
2020-09-17 12:39   ` Thierry Reding
2020-09-21 10:19   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 17/34] i2c: tegra: Remove outdated barrier() Dmitry Osipenko
2020-09-17 12:39   ` Thierry Reding
2020-09-21 10:19   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 18/34] i2c: tegra: Remove likely/unlikely from the code Dmitry Osipenko
2020-09-17 12:41   ` Thierry Reding
2020-09-21 10:19   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 19/34] i2c: tegra: Remove redundant check in tegra_i2c_issue_bus_clear() Dmitry Osipenko
2020-09-17 12:42   ` Thierry Reding
2020-09-21 10:19   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 20/34] i2c: tegra: Remove "dma" variable from tegra_i2c_xfer_msg() Dmitry Osipenko
2020-09-17 11:44   ` Thierry Reding
2020-09-21 10:19   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 21/34] i2c: tegra: Don't fall back to PIO mode if DMA configuration fails Dmitry Osipenko
2020-09-17 11:47   ` Thierry Reding
2020-09-17 15:03     ` Dmitry Osipenko
2020-09-21 11:21       ` Thierry Reding
2020-09-21 10:19   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 22/34] i2c: tegra: Rename wait/poll functions Dmitry Osipenko
2020-09-17 11:48   ` Thierry Reding
2020-09-21 10:19   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 23/34] i2c: tegra: Factor out error recovery from tegra_i2c_xfer_msg() Dmitry Osipenko
2020-09-17 11:49   ` Thierry Reding
2020-09-21 10:20   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 24/34] i2c: tegra: Factor out packet header setup " Dmitry Osipenko
2020-09-17 11:51   ` Thierry Reding
2020-09-21 10:20   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 25/34] i2c: tegra: Factor out register polling into separate function Dmitry Osipenko
2020-09-17 11:58   ` Thierry Reding
2020-09-17 15:05     ` Dmitry Osipenko
2020-09-21 11:22       ` Thierry Reding
2020-09-21 10:20   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 26/34] i2c: tegra: Factor out hardware initialization " Dmitry Osipenko
2020-09-17 12:06   ` Thierry Reding
2020-09-21 10:20   ` Thierry Reding
2020-09-08 22:39 ` [PATCH v7 27/34] i2c: tegra: Check errors for both positive and negative values Dmitry Osipenko
2020-09-17 12:09   ` Thierry Reding
2020-09-17 13:50     ` Andy Shevchenko
2020-09-21 11:24       ` Thierry Reding
2020-09-21 14:13         ` Dmitry Osipenko
2020-09-21 10:20   ` Thierry Reding
2020-09-08 22:40 ` [PATCH v7 28/34] i2c: tegra: Consolidate error handling in tegra_i2c_xfer_msg() Dmitry Osipenko
2020-09-17 12:12   ` Thierry Reding
2020-09-21 10:20   ` Thierry Reding
2020-09-08 22:40 ` [PATCH v7 29/34] i2c: tegra: Improve formatting of variables Dmitry Osipenko
2020-09-17 12:16   ` Thierry Reding
2020-09-17 15:13     ` Dmitry Osipenko
2020-09-21 11:28       ` Thierry Reding
2020-09-21 10:20   ` Thierry Reding
2020-09-08 22:40 ` [PATCH v7 30/34] i2c: tegra: Clean up variable names Dmitry Osipenko
2020-09-17 12:21   ` Thierry Reding
2020-09-17 15:43     ` Dmitry Osipenko
2020-09-21 11:40       ` Thierry Reding
2020-09-21 15:18         ` Dmitry Osipenko
2020-09-21 15:50           ` Thierry Reding
2020-09-21 16:05             ` Dmitry Osipenko
2020-09-21 10:20   ` Thierry Reding
2020-09-08 22:40 ` [PATCH v7 31/34] i2c: tegra: Clean up printk messages Dmitry Osipenko
2020-09-17 12:22   ` Thierry Reding
2020-09-21 10:20   ` Thierry Reding
2020-09-08 22:40 ` [PATCH v7 32/34] i2c: tegra: Clean up and improve comments Dmitry Osipenko
2020-09-17 12:32   ` Thierry Reding
2020-09-17 15:02     ` Dmitry Osipenko
2020-09-17 15:17       ` Dmitry Osipenko
2020-09-21 11:43         ` Thierry Reding
2020-09-21 11:44           ` Thierry Reding
2020-09-21 10:20   ` Thierry Reding
2020-09-08 22:40 ` [PATCH v7 33/34] i2c: tegra: Clean up whitespaces, newlines and indentation Dmitry Osipenko
2020-09-17 12:35   ` Thierry Reding
2020-09-21 10:20   ` Thierry Reding
2020-09-08 22:40 ` [PATCH v7 34/34] i2c: tegra: Improve driver module description Dmitry Osipenko
2020-09-17 12:35   ` Thierry Reding
2020-09-21 10:20   ` Thierry Reding
2020-09-09  9:11 ` [PATCH v7 00/34] Improvements for Tegra I2C driver Andy Shevchenko
2020-09-09 15:36   ` Dmitry Osipenko
2020-09-09 15:49     ` Wolfram Sang
2020-09-09 17:39       ` Dmitry Osipenko
2020-09-17 12:44       ` Thierry Reding
2020-09-21  9:12         ` Wolfram Sang
2020-09-21 10:18 ` Thierry Reding
2020-09-21 10:42   ` Thierry Reding

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).