RE: [PATCH v6 2/8] clk: clock-wizard: Add the clockwizard to clk directory

2020-11-03 Thread Shubhrajyoti Datta
Hi Stephen,

Thanks for the review.

> -Original Message-
> From: Stephen Boyd 
> Sent: Tuesday, September 22, 2020 2:52 AM
> To: Shubhrajyoti Datta ; linux-...@vger.kernel.org
> Cc: devicet...@vger.kernel.org; linux-kernel@vger.kernel.org;
> de...@driverdev.osuosl.org; robh...@kernel.org;
> gre...@linuxfoundation.org; mturque...@baylibre.com; Shubhrajyoti
> Datta 
> Subject: Re: [PATCH v6 2/8] clk: clock-wizard: Add the clockwizard to clk
> directory
> 
> Quoting Stephen Boyd (2020-09-21 14:19:59)
> > Quoting Shubhrajyoti Datta (2020-08-28 06:39:50)
> > > Add clocking wizard driver to clk.
> > >
> > > Signed-off-by: Shubhrajyoti Datta 
> > > ---
> >
> > Can this be combined with patch #6?
> 
> Sorry, I meant patch #8.
Did not get the comment.
Do you want to split the makefile and the driver parts of the patch.
Or the whole of the patch to be merged.

Or do you want the staging patch merged with  here?

[PATCH v6 8/8] staging: clocking-wizard: Delete the driver from the staging




RE: [PATCH v6 5/8] clk: clock-wizard: Add support for fractional support

2020-09-24 Thread Shubhrajyoti Datta
Hi ,
Thanks for the review.

> -Original Message-
> From: Stephen Boyd 
> Sent: Tuesday, September 22, 2020 2:48 AM
> To: Shubhrajyoti Datta ; linux-...@vger.kernel.org
> Cc: devicet...@vger.kernel.org; linux-kernel@vger.kernel.org;
> de...@driverdev.osuosl.org; robh...@kernel.org;
> gre...@linuxfoundation.org; mturque...@baylibre.com; Shubhrajyoti
> Datta 
> Subject: Re: [PATCH v6 5/8] clk: clock-wizard: Add support for fractional
> support
> 
> Quoting Shubhrajyoti Datta (2020-08-28 06:39:53)
> > Currently the set rate granularity is to integral divisors.
> > Add support for the fractional divisors.
> > Only the first output0 is fractional in the hardware.
> >
> > Signed-off-by: Shubhrajyoti Datta 
> 
> Getting closer.
> 
> > diff --git a/drivers/clk/clk-xlnx-clock-wizard.c
> > b/drivers/clk/clk-xlnx-clock-wizard.c
> > index 8dfcec8..1af59a4 100644
> > --- a/drivers/clk/clk-xlnx-clock-wizard.c
> > +++ b/drivers/clk/clk-xlnx-clock-wizard.c
> > @@ -185,6 +191,134 @@ static const struct clk_ops
> clk_wzrd_clk_divider_ops = {
> > .recalc_rate = clk_wzrd_recalc_rate,  };
> >
> > +static unsigned long clk_wzrd_recalc_ratef(struct clk_hw *hw,
> > +  unsigned long parent_rate)
> > +{
> > +   unsigned int val;
> > +   u32 div, frac;
> > +   struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
> > +   void __iomem *div_addr = divider->base + divider->offset;
> > +
> > +   val = readl(div_addr);
> > +   div = val & div_mask(divider->width);
> > +   frac = (val >> WZRD_CLKOUT_FRAC_SHIFT) &
> > + WZRD_CLKOUT_FRAC_MASK;
> > +
> > +   return ((parent_rate * 1000) / ((div * 1000) + frac));
> 
> Please remove extra parenthesis. And is this mult_frac()?
> 
Will fix
> > +}
> > +
> > +static int clk_wzrd_dynamic_reconfig_f(struct clk_hw *hw, unsigned long
> rate,
> > +  unsigned long parent_rate) {
> > +   int err;
> > +   u32 value, pre;
> > +   unsigned long rate_div, f, clockout0_div;
> > +   struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
> > +   void __iomem *div_addr = divider->base + divider->offset;
> > +
> > +   rate_div = ((parent_rate * 1000) / rate);
> > +   clockout0_div = rate_div / 1000;
> > +
> > +   pre = DIV_ROUND_CLOSEST((parent_rate * 1000), rate);
> > +   f = (u32)(pre - (clockout0_div * 1000));
> > +   f = f & WZRD_CLKOUT_FRAC_MASK;
> > +
> > +   value = ((f << WZRD_CLKOUT_DIVIDE_WIDTH) | (clockout0_div &
> > +   WZRD_CLKOUT_DIVIDE_MASK));
> 
> Please split this to multiple lines.
Will fix
> 
> > +
> > +   /* Set divisor and clear phase offset */
> > +   writel(value, div_addr);
> > +   writel(0x0, div_addr + WZRD_DR_DIV_TO_PHASE_OFFSET);
> > +
> > +   /* Check status register */
> > +   err= readl_poll_timeout(divider->base +
> WZRD_DR_STATUS_REG_OFFSET, value,
> > +   value & WZRD_DR_LOCK_BIT_MASK,
> > +   WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
> > +   if (err)
> > +   return err;
> > +
> > +   /* Initiate reconfiguration */
> > +   writel(WZRD_DR_BEGIN_DYNA_RECONF,
> > +  divider->base + WZRD_DR_INIT_REG_OFFSET);
> > +
> > +   /* Check status register */
> > +   err= readl_poll_timeout(divider->base +
> WZRD_DR_STATUS_REG_OFFSET, value,
> > +   value & WZRD_DR_LOCK_BIT_MASK,
> > +   WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
> > +
> > +   return err;
> 
> Just return readl_poll_timeout() please.
Will fix
> 
> > +}
> > +
> > +static long clk_wzrd_round_rate_f(struct clk_hw *hw, unsigned long
> rate,
> > + unsigned long *prate) {
> > +   return rate;
> 
> Can every rate be supported? This function is supposed to tell the clk
> framework what rate will be achieved if we call clk_set_rate() with 'rate'
> passed to this function. Almost always returning 'rate' is not the case.
> 

We can support rate upto 3 decimal places to prevent truncation here we are 
Returning rate.
> >
> > +
> > +static const struct clk_ops clk_wzrd_clk_divider_ops_f = {
> > +   .round_rate = clk_wzrd_round_rate_f,
> > +   .set_rate = clk_wzrd_dynamic_r

[PATCH v6 5/8] clk: clock-wizard: Add support for fractional support

2020-08-28 Thread Shubhrajyoti Datta
Currently the set rate granularity is to integral divisors.
Add support for the fractional divisors.
Only the first output0 is fractional in the hardware.

Signed-off-by: Shubhrajyoti Datta 
---
v6:
remove unnecessary typecast
remove unnecessary locks
use polled timeout

 drivers/clk/clk-xlnx-clock-wizard.c | 166 +---
 1 file changed, 153 insertions(+), 13 deletions(-)

diff --git a/drivers/clk/clk-xlnx-clock-wizard.c 
b/drivers/clk/clk-xlnx-clock-wizard.c
index 8dfcec8..1af59a4 100644
--- a/drivers/clk/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/clk-xlnx-clock-wizard.c
@@ -29,20 +29,25 @@
 
 #define WZRD_CLKFBOUT_MULT_SHIFT   8
 #define WZRD_CLKFBOUT_MULT_MASK(0xff << 
WZRD_CLKFBOUT_MULT_SHIFT)
+#define WZRD_CLKFBOUT_FRAC_SHIFT   16
+#define WZRD_CLKFBOUT_FRAC_MASK(0x3ff << 
WZRD_CLKFBOUT_FRAC_SHIFT)
 #define WZRD_DIVCLK_DIVIDE_SHIFT   0
 #define WZRD_DIVCLK_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
 #define WZRD_CLKOUT_DIVIDE_SHIFT   0
 #define WZRD_CLKOUT_DIVIDE_WIDTH   8
 #define WZRD_CLKOUT_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
+#define WZRD_CLKOUT_FRAC_SHIFT 8
+#define WZRD_CLKOUT_FRAC_MASK  0x3ff
 
 #define WZRD_DR_MAX_INT_DIV_VALUE  255
-#define WZRD_DR_NUM_RETRIES1
 #define WZRD_DR_STATUS_REG_OFFSET  0x04
 #define WZRD_DR_LOCK_BIT_MASK  0x0001
 #define WZRD_DR_INIT_REG_OFFSET0x25C
 #define WZRD_DR_DIV_TO_PHASE_OFFSET4
 #define WZRD_DR_BEGIN_DYNA_RECONF  0x03
 
+#define WZRD_USEC_POLL 10
+#define WZRD_TIMEOUT_POLL  1000
 /* Get the mask from width */
 #define div_mask(width)((1 << (width)) - 1)
 
@@ -52,6 +57,7 @@
 enum clk_wzrd_int_clks {
wzrd_clk_mul,
wzrd_clk_mul_div,
+   wzrd_clk_mul_frac,
wzrd_clk_int_max
 };
 
@@ -185,6 +191,134 @@ static const struct clk_ops clk_wzrd_clk_divider_ops = {
.recalc_rate = clk_wzrd_recalc_rate,
 };
 
+static unsigned long clk_wzrd_recalc_ratef(struct clk_hw *hw,
+  unsigned long parent_rate)
+{
+   unsigned int val;
+   u32 div, frac;
+   struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
+   void __iomem *div_addr = divider->base + divider->offset;
+
+   val = readl(div_addr);
+   div = val & div_mask(divider->width);
+   frac = (val >> WZRD_CLKOUT_FRAC_SHIFT) & WZRD_CLKOUT_FRAC_MASK;
+
+   return ((parent_rate * 1000) / ((div * 1000) + frac));
+}
+
+static int clk_wzrd_dynamic_reconfig_f(struct clk_hw *hw, unsigned long rate,
+  unsigned long parent_rate)
+{
+   int err;
+   u32 value, pre;
+   unsigned long rate_div, f, clockout0_div;
+   struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
+   void __iomem *div_addr = divider->base + divider->offset;
+
+   rate_div = ((parent_rate * 1000) / rate);
+   clockout0_div = rate_div / 1000;
+
+   pre = DIV_ROUND_CLOSEST((parent_rate * 1000), rate);
+   f = (u32)(pre - (clockout0_div * 1000));
+   f = f & WZRD_CLKOUT_FRAC_MASK;
+
+   value = ((f << WZRD_CLKOUT_DIVIDE_WIDTH) | (clockout0_div &
+   WZRD_CLKOUT_DIVIDE_MASK));
+
+   /* Set divisor and clear phase offset */
+   writel(value, div_addr);
+   writel(0x0, div_addr + WZRD_DR_DIV_TO_PHASE_OFFSET);
+
+   /* Check status register */
+   err= readl_poll_timeout(divider->base + WZRD_DR_STATUS_REG_OFFSET, 
value,
+   value & WZRD_DR_LOCK_BIT_MASK,
+   WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
+   if (err)
+   return err;
+
+   /* Initiate reconfiguration */
+   writel(WZRD_DR_BEGIN_DYNA_RECONF,
+  divider->base + WZRD_DR_INIT_REG_OFFSET);
+
+   /* Check status register */
+   err= readl_poll_timeout(divider->base + WZRD_DR_STATUS_REG_OFFSET, 
value,
+   value & WZRD_DR_LOCK_BIT_MASK,
+   WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
+
+   return err;
+}
+
+static long clk_wzrd_round_rate_f(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+   return rate;
+}
+
+static const struct clk_ops clk_wzrd_clk_divider_ops_f = {
+   .round_rate = clk_wzrd_round_rate_f,
+   .set_rate = clk_wzrd_dynamic_reconfig_f,
+   .recalc_rate = clk_wzrd_recalc_ratef,
+};
+
+static struct clk *clk_wzrd_register_divf(struct device *dev,
+ const char *name,
+ const char *parent_name,
+ unsigned long flags,
+ void __iomem *base, u16 offset,
+   

[PATCH v6 3/8] clk: clock-wizard: Fix kernel-doc warning

2020-08-28 Thread Shubhrajyoti Datta
Update description for the clocking wizard structure

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/clk/clk-xlnx-clock-wizard.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk-xlnx-clock-wizard.c 
b/drivers/clk/clk-xlnx-clock-wizard.c
index b31524a..d6577c8 100644
--- a/drivers/clk/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/clk-xlnx-clock-wizard.c
@@ -40,7 +40,8 @@ enum clk_wzrd_int_clks {
 };
 
 /**
- * struct clk_wzrd:
+ * struct clk_wzrd - Clock wizard private data structure
+ *
  * @clk_data:  Clock data
  * @nb:Notifier block
  * @base:  Memory base
-- 
2.1.1



[PATCH v6 4/8] clk: clock-wizard: Add support for dynamic reconfiguration

2020-08-28 Thread Shubhrajyoti Datta
The patch adds support for dynamic reconfiguration of clock output rate.
Output clocks are registered as dividers and set rate callback function
is used for dynamic reconfiguration.

Based on the initial work from Chirag.

Signed-off-by: Chirag Parekh 
Signed-off-by: Shubhrajyoti Datta 
---
v6:
Remove the typecast.
use min for capping frequency.
use polled timeout

 drivers/clk/clk-xlnx-clock-wizard.c | 185 ++--
 1 file changed, 179 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/clk-xlnx-clock-wizard.c 
b/drivers/clk/clk-xlnx-clock-wizard.c
index d6577c8..8dfcec8 100644
--- a/drivers/clk/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/clk-xlnx-clock-wizard.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define WZRD_NUM_OUTPUTS   7
 #define WZRD_ACLK_MAX_FREQ 25000UL
@@ -31,8 +32,23 @@
 #define WZRD_DIVCLK_DIVIDE_SHIFT   0
 #define WZRD_DIVCLK_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
 #define WZRD_CLKOUT_DIVIDE_SHIFT   0
+#define WZRD_CLKOUT_DIVIDE_WIDTH   8
 #define WZRD_CLKOUT_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
 
+#define WZRD_DR_MAX_INT_DIV_VALUE  255
+#define WZRD_DR_NUM_RETRIES1
+#define WZRD_DR_STATUS_REG_OFFSET  0x04
+#define WZRD_DR_LOCK_BIT_MASK  0x0001
+#define WZRD_DR_INIT_REG_OFFSET0x25C
+#define WZRD_DR_DIV_TO_PHASE_OFFSET4
+#define WZRD_DR_BEGIN_DYNA_RECONF  0x03
+
+/* Get the mask from width */
+#define div_mask(width)((1 << (width)) - 1)
+
+/* Extract divider instance from clock hardware instance */
+#define to_clk_wzrd_divider(_hw) container_of(_hw, struct clk_wzrd_divider, hw)
+
 enum clk_wzrd_int_clks {
wzrd_clk_mul,
wzrd_clk_mul_div,
@@ -64,6 +80,29 @@ struct clk_wzrd {
bool suspended;
 };
 
+/**
+ * struct clk_wzrd_divider - clock divider specific to clk_wzrd
+ *
+ * @hw:handle between common and hardware-specific interfaces
+ * @base:  base address of register containing the divider
+ * @offset:offset address of register containing the divider
+ * @shift: shift to the divider bit field
+ * @width: width of the divider bit field
+ * @flags: clk_wzrd divider flags
+ * @table: array of value/divider pairs, last entry should have div = 0
+ * @lock:  register lock
+ */
+struct clk_wzrd_divider {
+   struct clk_hw hw;
+   void __iomem *base;
+   u16 offset;
+   u8 shift;
+   u8 width;
+   u8 flags;
+   const struct clk_div_table *table;
+   spinlock_t *lock;  /* divider lock */
+};
+
 #define to_clk_wzrd(_nb) container_of(_nb, struct clk_wzrd, nb)
 
 /* maximum frequencies for input/output clocks per speed grade */
@@ -73,6 +112,136 @@ static const unsigned long clk_wzrd_max_freq[] = {
106600UL
 };
 
+/* spin lock variable for clk_wzrd */
+static DEFINE_SPINLOCK(clkwzrd_lock);
+
+static unsigned long clk_wzrd_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+   struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
+   void __iomem *div_addr = divider->base + divider->offset;
+   unsigned int val;
+
+   val = readl(div_addr) >> divider->shift;
+   val &= div_mask(divider->width);
+
+   return divider_recalc_rate(hw, parent_rate, val, divider->table,
+   divider->flags, divider->width);
+}
+
+static int clk_wzrd_dynamic_reconfig(struct clk_hw *hw, unsigned long rate,
+unsigned long parent_rate)
+{
+   int err = 0;
+   u32 value;
+   struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
+   void __iomem *div_addr = divider->base + divider->offset;
+
+   value = DIV_ROUND_CLOSEST(parent_rate, rate);
+
+   /* Cap the value to max */
+   min(value, (u32)WZRD_DR_MAX_INT_DIV_VALUE);
+
+   /* Set divisor and clear phase offset */
+   writel(value, div_addr);
+   writel(0x00, div_addr + WZRD_DR_DIV_TO_PHASE_OFFSET);
+
+   /* Check status register */
+   err = readl_poll_timeout(divider->base + WZRD_DR_STATUS_REG_OFFSET, 
value,
+   value & WZRD_DR_LOCK_BIT_MASK,
+   WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
+   if (err)
+   return err;
+
+   /* Initiate reconfiguration */
+   writel(WZRD_DR_BEGIN_DYNA_RECONF,
+  divider->base + WZRD_DR_INIT_REG_OFFSET);
+
+   /* Check status register */
+   err = readl_poll_timeout(divider->base + WZRD_DR_STATUS_REG_OFFSET, 
value,
+   value & WZRD_DR_LOCK_BIT_MASK,
+   WZRD_USEC_POLL, WZRD_TIMEOUT_POLL);
+
+   return err;
+}
+
+static long clk_wzrd_round_rate(struct clk_hw *hw, unsigned long rate,
+   u

[PATCH v6 2/8] clk: clock-wizard: Add the clockwizard to clk directory

2020-08-28 Thread Shubhrajyoti Datta
Add clocking wizard driver to clk.

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/clk/Kconfig |   9 +
 drivers/clk/Makefile|   1 +
 drivers/clk/clk-xlnx-clock-wizard.c | 338 
 3 files changed, 348 insertions(+)
 create mode 100644 drivers/clk/clk-xlnx-clock-wizard.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 4026fac..a0e29dd 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -359,6 +359,15 @@ config COMMON_CLK_FIXED_MMIO
help
  Support for Memory Mapped IO Fixed clocks
 
+config COMMON_CLK_XLNX_CLKWZRD
+   tristate "Xilinx Clocking Wizard"
+   depends on COMMON_CLK && OF
+   help
+ Support for the Xilinx Clocking Wizard IP core clock generator.
+ Adds support for clocking wizard and compatible.
+ This driver supports the Xilinx clocking wizard programmable clock
+ synthesizer. The number of output is configurable in the design.
+
 source "drivers/clk/actions/Kconfig"
 source "drivers/clk/analogbits/Kconfig"
 source "drivers/clk/baikal-t1/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index da8fcf1..1ad6414 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -69,6 +69,7 @@ obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
 obj-$(CONFIG_COMMON_CLK_VC5)   += clk-versaclock5.o
 obj-$(CONFIG_COMMON_CLK_WM831X)+= clk-wm831x.o
 obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o
+obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD)  += clk-xlnx-clock-wizard.o
 
 # please keep this section sorted lexicographically by directory path name
 obj-y  += actions/
diff --git a/drivers/clk/clk-xlnx-clock-wizard.c 
b/drivers/clk/clk-xlnx-clock-wizard.c
new file mode 100644
index 000..b31524a
--- /dev/null
+++ b/drivers/clk/clk-xlnx-clock-wizard.c
@@ -0,0 +1,338 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx 'Clocking Wizard' driver
+ *
+ *  Copyright (C) 2013 - 2020 Xilinx
+ *
+ *  Sören Brinkmann 
+ *  Shubhrajyoti Datta 
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define WZRD_NUM_OUTPUTS   7
+#define WZRD_ACLK_MAX_FREQ 25000UL
+
+#define WZRD_CLK_CFG_REG(n)(0x200 + 4 * (n))
+
+#define WZRD_CLKOUT0_FRAC_EN   BIT(18)
+#define WZRD_CLKFBOUT_FRAC_EN  BIT(26)
+
+#define WZRD_CLKFBOUT_MULT_SHIFT   8
+#define WZRD_CLKFBOUT_MULT_MASK(0xff << 
WZRD_CLKFBOUT_MULT_SHIFT)
+#define WZRD_DIVCLK_DIVIDE_SHIFT   0
+#define WZRD_DIVCLK_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
+#define WZRD_CLKOUT_DIVIDE_SHIFT   0
+#define WZRD_CLKOUT_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
+
+enum clk_wzrd_int_clks {
+   wzrd_clk_mul,
+   wzrd_clk_mul_div,
+   wzrd_clk_int_max
+};
+
+/**
+ * struct clk_wzrd:
+ * @clk_data:  Clock data
+ * @nb:Notifier block
+ * @base:  Memory base
+ * @clk_in1:   Handle to input clock 'clk_in1'
+ * @axi_clk:   Handle to input clock 's_axi_aclk'
+ * @clks_internal: Internal clocks
+ * @clkout:Output clocks
+ * @speed_grade:   Speed grade of the device
+ * @suspended: Flag indicating power state of the device
+ */
+struct clk_wzrd {
+   struct clk_onecell_data clk_data;
+   struct notifier_block nb;
+   void __iomem *base;
+   struct clk *clk_in1;
+   struct clk *axi_clk;
+   struct clk *clks_internal[wzrd_clk_int_max];
+   struct clk *clkout[WZRD_NUM_OUTPUTS];
+   unsigned int speed_grade;
+   bool suspended;
+};
+
+#define to_clk_wzrd(_nb) container_of(_nb, struct clk_wzrd, nb)
+
+/* maximum frequencies for input/output clocks per speed grade */
+static const unsigned long clk_wzrd_max_freq[] = {
+   8UL,
+   93300UL,
+   106600UL
+};
+
+static int clk_wzrd_clk_notifier(struct notifier_block *nb, unsigned long 
event,
+void *data)
+{
+   unsigned long max;
+   struct clk_notifier_data *ndata = data;
+   struct clk_wzrd *clk_wzrd = to_clk_wzrd(nb);
+
+   if (clk_wzrd->suspended)
+   return NOTIFY_OK;
+
+   if (ndata->clk == clk_wzrd->clk_in1)
+   max = clk_wzrd_max_freq[clk_wzrd->speed_grade - 1];
+   else if (ndata->clk == clk_wzrd->axi_clk)
+   max = WZRD_ACLK_MAX_FREQ;
+   else
+   return NOTIFY_DONE; /* should never happen */
+
+   switch (event) {
+   case PRE_RATE_CHANGE:
+   if (ndata->new_rate > max)
+   return NOTIFY_BAD;
+   return NOTIFY_OK;
+   case POST_RATE_CHANGE:
+   case ABORT_RATE_CHANGE:
+   default:
+   return NOTIFY_DONE;
+   }
+}
+
+static int __maybe_unused clk_w

[PATCH v6 7/8] clk: clock-wizard: Update the fixed factor divisors

2020-08-28 Thread Shubhrajyoti Datta
Update the fixed factor clock registration to register the divisors.

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/clk/clk-xlnx-clock-wizard.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/clk-xlnx-clock-wizard.c 
b/drivers/clk/clk-xlnx-clock-wizard.c
index ded4cdd..fd69eb0 100644
--- a/drivers/clk/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/clk-xlnx-clock-wizard.c
@@ -440,9 +440,11 @@ static int clk_wzrd_probe(struct platform_device *pdev)
u32 reg, reg_f, mult;
unsigned long rate;
const char *clk_name;
+   void __iomem *ctrl_reg;
struct clk_wzrd *clk_wzrd;
struct resource *mem;
int outputs;
+   unsigned long flags = 0;
struct device_node *np = pdev->dev.of_node;
 
clk_wzrd = devm_kzalloc(>dev, sizeof(*clk_wzrd), GFP_KERNEL);
@@ -514,16 +516,17 @@ static int clk_wzrd_probe(struct platform_device *pdev)
}
 
outputs = of_property_count_strings(np, "clock-output-names");
-   /* register div */
-   reg = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(0)) &
-   WZRD_DIVCLK_DIVIDE_MASK) >> WZRD_DIVCLK_DIVIDE_SHIFT;
+   if (outputs == 1)
+   flags = CLK_SET_RATE_PARENT;
clk_name = kasprintf(GFP_KERNEL, "%s_mul_div", dev_name(>dev));
if (!clk_name) {
ret = -ENOMEM;
goto err_rm_int_clk;
}
 
-   clk_wzrd->clks_internal[wzrd_clk_mul_div] = clk_register_fixed_factor
+   ctrl_reg = clk_wzrd->base + WZRD_CLK_CFG_REG(0);
+   /* register div */
+   clk_wzrd->clks_internal[wzrd_clk_mul_div] = clk_register_divider
(>dev, clk_name,
 __clk_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]),
flags, ctrl_reg, 0, 8, CLK_DIVIDER_ONE_BASED |
@@ -548,7 +551,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
if (!i)
clk_wzrd->clkout[i] = clk_wzrd_register_divf
(>dev, clkout_name,
-   clk_name, 0,
+   clk_name, flags,
clk_wzrd->base, (WZRD_CLK_CFG_REG(2) + i * 12),
WZRD_CLKOUT_DIVIDE_SHIFT,
WZRD_CLKOUT_DIVIDE_WIDTH,
-- 
2.1.1



[PATCH v6 1/8] dt-bindings: add documentation of xilinx clocking wizard

2020-08-28 Thread Shubhrajyoti Datta
Add the devicetree binding for the xilinx clocking wizard.

Signed-off-by: Shubhrajyoti Datta 
---
v6:
Fix a yaml warning

 .../bindings/clock/xlnx,clocking-wizard.yaml   | 71 ++
 1 file changed, 71 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml

diff --git a/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml 
b/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml
new file mode 100644
index 000..ca63593
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/xlnx,clocking-wizard.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Xilinx clocking wizard
+
+maintainers:
+  - Shubhrajyoti Datta 
+
+description: |
+  The clocking wizard is a soft ip clocking block of Xilinx versal. It
+  reads required input clock frequencies from the devicetree and acts as clock
+  clock output.
+
+select: false
+
+properties:
+  compatible:
+items:
+  - enum:
+  - xlnx,clocking-wizard
+  - xlnx,clocking-wizard-6.0
+
+  "#clock-cells":
+const: 1
+
+  clocks:
+description: List of clock specifiers which are external input
+  clocks to the given clock controller.
+items:
+  - description: clock input
+  - description: axi clock
+
+  clock-names:
+items:
+  - const: clk_in1
+  - const: s_axi_aclk
+
+  speed-grade:
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+  - enum: [1, 2, 3]
+description:
+  Speed grade of the device.
+maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - clocks
+  - clock-names
+  - speed-grade
+
+additionalProperties: false
+
+examples:
+  - |
+clock-generator@4004 {
+#clock-cells = <1>;
+reg = <0x4004 0x1000>;
+compatible = "xlnx,clk-wizard-1.0";
+speed-grade = <1>;
+clock-names = "clk_in1", "s_axi_aclk";
+clocks = < 15>, < 15>;
+clock-output-names = "clk_out1", "clk_out2",
+"clk_out3", "clk_out4", "clk_out5",
+"clk_out6", "clk_out7";
+};
+...
-- 
2.1.1



[PATCH v6 6/8] clk: clock-wizard: Remove the hardcoding of the clock outputs

2020-08-28 Thread Shubhrajyoti Datta
The number of output clocks are configurable in the hardware.
Currently the driver registers the maximum number of outputs.
Fix the same by registering only the outputs that are there.

Signed-off-by: Shubhrajyoti Datta 
---
v4:
Assign output in this patch

 drivers/clk/clk-xlnx-clock-wizard.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/clk-xlnx-clock-wizard.c 
b/drivers/clk/clk-xlnx-clock-wizard.c
index 1af59a4..ded4cdd 100644
--- a/drivers/clk/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/clk-xlnx-clock-wizard.c
@@ -442,6 +442,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
const char *clk_name;
struct clk_wzrd *clk_wzrd;
struct resource *mem;
+   int outputs;
struct device_node *np = pdev->dev.of_node;
 
clk_wzrd = devm_kzalloc(>dev, sizeof(*clk_wzrd), GFP_KERNEL);
@@ -512,6 +513,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
goto err_disable_clk;
}
 
+   outputs = of_property_count_strings(np, "clock-output-names");
/* register div */
reg = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(0)) &
WZRD_DIVCLK_DIVIDE_MASK) >> WZRD_DIVCLK_DIVIDE_SHIFT;
@@ -533,7 +535,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
}
 
/* register div per output */
-   for (i = WZRD_NUM_OUTPUTS - 1; i >= 0 ; i--) {
+   for (i = outputs - 1; i >= 0 ; i--) {
const char *clkout_name;
 
if (of_property_read_string_index(np, "clock-output-names", i,
@@ -564,7 +566,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
if (IS_ERR(clk_wzrd->clkout[i])) {
int j;
 
-   for (j = i + 1; j < WZRD_NUM_OUTPUTS; j++)
+   for (j = i + 1; j < outputs; j++)
clk_unregister(clk_wzrd->clkout[j]);
dev_err(>dev,
"unable to register divider clock\n");
-- 
2.1.1



[PATCH v6 8/8] staging: clocking-wizard: Delete the driver from the staging

2020-08-28 Thread Shubhrajyoti Datta
Delete the driver from the staging as it is in drivers/clk.

Signed-off-by: Shubhrajyoti Datta 
Acked-by: Greg Kroah-Hartman 
---
 drivers/staging/Kconfig|   2 -
 drivers/staging/Makefile   |   1 -
 drivers/staging/clocking-wizard/Kconfig|  10 -
 drivers/staging/clocking-wizard/Makefile   |   2 -
 drivers/staging/clocking-wizard/TODO   |  12 -
 .../clocking-wizard/clk-xlnx-clock-wizard.c| 333 -
 drivers/staging/clocking-wizard/dt-binding.txt |  30 --
 7 files changed, 390 deletions(-)
 delete mode 100644 drivers/staging/clocking-wizard/Kconfig
 delete mode 100644 drivers/staging/clocking-wizard/Makefile
 delete mode 100644 drivers/staging/clocking-wizard/TODO
 delete mode 100644 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
 delete mode 100644 drivers/staging/clocking-wizard/dt-binding.txt

diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index e6c831c..bae49c6 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -76,8 +76,6 @@ source "drivers/staging/gs_fpgaboot/Kconfig"
 
 source "drivers/staging/unisys/Kconfig"
 
-source "drivers/staging/clocking-wizard/Kconfig"
-
 source "drivers/staging/fbtft/Kconfig"
 
 source "drivers/staging/fsl-dpaa2/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index a3b1fd0..f5a3e57 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -28,7 +28,6 @@ obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/
 obj-$(CONFIG_GOLDFISH) += goldfish/
 obj-$(CONFIG_GS_FPGABOOT)  += gs_fpgaboot/
 obj-$(CONFIG_UNISYSSPAR)   += unisys/
-obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD)  += clocking-wizard/
 obj-$(CONFIG_FB_TFT)   += fbtft/
 obj-$(CONFIG_FSL_DPAA2)+= fsl-dpaa2/
 obj-$(CONFIG_MOST) += most/
diff --git a/drivers/staging/clocking-wizard/Kconfig 
b/drivers/staging/clocking-wizard/Kconfig
deleted file mode 100644
index 69cf514..000
--- a/drivers/staging/clocking-wizard/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Xilinx Clocking Wizard Driver
-#
-
-config COMMON_CLK_XLNX_CLKWZRD
-   tristate "Xilinx Clocking Wizard"
-   depends on COMMON_CLK && OF && IOMEM
-   help
- Support for the Xilinx Clocking Wizard IP core clock generator.
diff --git a/drivers/staging/clocking-wizard/Makefile 
b/drivers/staging/clocking-wizard/Makefile
deleted file mode 100644
index b1f9152..000
--- a/drivers/staging/clocking-wizard/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD)  += clk-xlnx-clock-wizard.o
diff --git a/drivers/staging/clocking-wizard/TODO 
b/drivers/staging/clocking-wizard/TODO
deleted file mode 100644
index ebe99db..000
--- a/drivers/staging/clocking-wizard/TODO
+++ /dev/null
@@ -1,12 +0,0 @@
-TODO:
-   - support for fractional multiplier
-   - support for fractional divider (output 0 only)
-   - support for set_rate() operations (may benefit from Stephen Boyd's
- refactoring of the clk primitives: https://lkml.org/lkml/2014/9/5/766)
-   - review arithmetic
- - overflow after multiplication?
- - maximize accuracy before divisions
-
-Patches to:
-   Greg Kroah-Hartman 
-   Sören Brinkmann 
diff --git a/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c 
b/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
deleted file mode 100644
index e52a64b..000
--- a/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
+++ /dev/null
@@ -1,333 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Xilinx 'Clocking Wizard' driver
- *
- *  Copyright (C) 2013 - 2014 Xilinx
- *
- *  Sören Brinkmann 
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#define WZRD_NUM_OUTPUTS   7
-#define WZRD_ACLK_MAX_FREQ 25000UL
-
-#define WZRD_CLK_CFG_REG(n)(0x200 + 4 * (n))
-
-#define WZRD_CLKOUT0_FRAC_EN   BIT(18)
-#define WZRD_CLKFBOUT_FRAC_EN  BIT(26)
-
-#define WZRD_CLKFBOUT_MULT_SHIFT   8
-#define WZRD_CLKFBOUT_MULT_MASK(0xff << 
WZRD_CLKFBOUT_MULT_SHIFT)
-#define WZRD_DIVCLK_DIVIDE_SHIFT   0
-#define WZRD_DIVCLK_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
-#define WZRD_CLKOUT_DIVIDE_SHIFT   0
-#define WZRD_CLKOUT_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
-
-enum clk_wzrd_int_clks {
-   wzrd_clk_mul,
-   wzrd_clk_mul_div,
-   wzrd_clk_int_max
-};
-
-/**
- * struct clk_wzrd:
- * @clk_data:  Clock data
- * @nb:Notifier block
- * @base:  Memory base
- * @clk_in1:   Handle to input clock 'clk_in1'
- * @axi_clk:   Handle to input clock 's_axi_aclk'
- * @clks_internal: Internal clocks
- * @clkout:  

[PATCH v6 0/8] clk: clk-wizard: clock-wizard: Driver updates

2020-08-28 Thread Shubhrajyoti Datta
In the thread [1] Greg suggested that we move the driver
to the clk from the staging.
Add patches to address the concerns regarding the fractional and
set rate support in the TODO.

The patch set does the following
- Trivial fixes for kernel doc.
- Move the driver to the clk folder
- Add capability to set rate.
- Add fractional support.
- Add support for configurable outputs.
- Make the output names unique so that multiple instances
do not crib.

Changes in the v3:
Added the cover-letter.
Add patches for rate setting and fractional support
Add patches for warning.
Remove the driver from staging as suggested

v4:
Reorder the patches.
Merge the CLK_IS_BASIC patch.
Add the yaml form of binding document

v5:
Fix a mismerge

v6:
Fix the yaml warning
use poll timedout

[1] https://spinics.net/lists/linux-driver-devel/msg117326.html

Shubhrajyoti Datta (8):
  dt-bindings: add documentation of xilinx clocking wizard
  clk: clock-wizard: Add the clockwizard to clk directory
  clk: clock-wizard: Fix kernel-doc warning
  clk: clock-wizard: Add support for dynamic reconfiguration
  clk: clock-wizard: Add support for fractional support
  clk: clock-wizard: Remove the hardcoding of the clock outputs
  clk: clock-wizard: Update the fixed factor divisors
  staging: clocking-wizard: Delete the driver from the staging

 .../bindings/clock/xlnx,clocking-wizard.yaml   |  71 +++
 drivers/clk/Kconfig|   9 +
 drivers/clk/Makefile   |   1 +
 drivers/clk/clk-xlnx-clock-wizard.c| 657 +
 drivers/staging/Kconfig|   2 -
 drivers/staging/Makefile   |   1 -
 drivers/staging/clocking-wizard/Kconfig|  10 -
 drivers/staging/clocking-wizard/Makefile   |   2 -
 drivers/staging/clocking-wizard/TODO   |  12 -
 .../clocking-wizard/clk-xlnx-clock-wizard.c| 333 ---
 drivers/staging/clocking-wizard/dt-binding.txt |  30 -
 11 files changed, 738 insertions(+), 390 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml
 create mode 100644 drivers/clk/clk-xlnx-clock-wizard.c
 delete mode 100644 drivers/staging/clocking-wizard/Kconfig
 delete mode 100644 drivers/staging/clocking-wizard/Makefile
 delete mode 100644 drivers/staging/clocking-wizard/TODO
 delete mode 100644 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
 delete mode 100644 drivers/staging/clocking-wizard/dt-binding.txt

-- 
2.1.1



Re: [PATCH V2 3/3] MAINTAINERS: add fragment for xilinx GPIO drivers

2020-07-24 Thread Shubhrajyoti Datta
On Thu, Jul 23, 2020 at 7:37 PM Srinivas Neeli
 wrote:
>
> Added entry for xilinx GPIO drivers.
>
> Signed-off-by: Srinivas Neeli 
> ---
Acked-by: : Shubhrajyoti Datta 


[PATCH v5 5/8] clk: clock-wizard: Add support for fractional support

2020-06-26 Thread Shubhrajyoti Datta
Currently the set rate granularity is to integral divisors.
Add support for the fractional divisors.
Only the first output0 is fractional in the hardware.

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/clk/clk-xlnx-clock-wizard.c | 190 +---
 1 file changed, 178 insertions(+), 12 deletions(-)

diff --git a/drivers/clk/clk-xlnx-clock-wizard.c 
b/drivers/clk/clk-xlnx-clock-wizard.c
index aaffb04..1cf381c 100644
--- a/drivers/clk/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/clk-xlnx-clock-wizard.c
@@ -28,11 +28,15 @@
 
 #define WZRD_CLKFBOUT_MULT_SHIFT   8
 #define WZRD_CLKFBOUT_MULT_MASK(0xff << 
WZRD_CLKFBOUT_MULT_SHIFT)
+#define WZRD_CLKFBOUT_FRAC_SHIFT   16
+#define WZRD_CLKFBOUT_FRAC_MASK(0x3ff << 
WZRD_CLKFBOUT_FRAC_SHIFT)
 #define WZRD_DIVCLK_DIVIDE_SHIFT   0
 #define WZRD_DIVCLK_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
 #define WZRD_CLKOUT_DIVIDE_SHIFT   0
 #define WZRD_CLKOUT_DIVIDE_WIDTH   8
 #define WZRD_CLKOUT_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
+#define WZRD_CLKOUT_FRAC_SHIFT 8
+#define WZRD_CLKOUT_FRAC_MASK  0x3ff
 
 #define WZRD_DR_MAX_INT_DIV_VALUE  255
 #define WZRD_DR_NUM_RETRIES1
@@ -51,6 +55,7 @@
 enum clk_wzrd_int_clks {
wzrd_clk_mul,
wzrd_clk_mul_div,
+   wzrd_clk_mul_frac,
wzrd_clk_int_max
 };
 
@@ -212,6 +217,161 @@ static const struct clk_ops clk_wzrd_clk_divider_ops = {
.recalc_rate = clk_wzrd_recalc_rate,
 };
 
+static unsigned long clk_wzrd_recalc_ratef(struct clk_hw *hw,
+  unsigned long parent_rate)
+{
+   unsigned int val;
+   u32 div, frac;
+   struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
+   void __iomem *div_addr =
+   (void __iomem *)((u64)divider->base + divider->offset);
+
+   val = readl(div_addr);
+   div = val & div_mask(divider->width);
+   frac = (val >> WZRD_CLKOUT_FRAC_SHIFT) & WZRD_CLKOUT_FRAC_MASK;
+
+   return ((parent_rate * 1000) / ((div * 1000) + frac));
+}
+
+static int clk_wzrd_dynamic_reconfig_f(struct clk_hw *hw, unsigned long rate,
+  unsigned long parent_rate)
+{
+   int err = 0;
+   u16 retries;
+   u32 value, pre;
+   unsigned long flags = 0;
+   unsigned long rate_div, f, clockout0_div;
+   struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
+   void __iomem *div_addr =
+   (void __iomem *)((u64)divider->base + divider->offset);
+
+   if (divider->lock)
+   spin_lock_irqsave(divider->lock, flags);
+   else
+   __acquire(divider->lock);
+
+   rate_div = ((parent_rate * 1000) / rate);
+   clockout0_div = rate_div / 1000;
+
+   pre = DIV_ROUND_CLOSEST((parent_rate * 1000), rate);
+   f = (u32)(pre - (clockout0_div * 1000));
+   f = f & WZRD_CLKOUT_FRAC_MASK;
+
+   value = ((f << WZRD_CLKOUT_DIVIDE_WIDTH) | (clockout0_div &
+   WZRD_CLKOUT_DIVIDE_MASK));
+
+   /* Set divisor and clear phase offset */
+   writel(value, div_addr);
+   writel(0x0, div_addr + WZRD_DR_DIV_TO_PHASE_OFFSET);
+
+   /* Check status register */
+   retries = WZRD_DR_NUM_RETRIES;
+   while (retries--) {
+   if (readl(divider->base + WZRD_DR_STATUS_REG_OFFSET) &
+   WZRD_DR_LOCK_BIT_MASK)
+   break;
+   }
+
+   if (!retries) {
+   err = -ETIMEDOUT;
+   goto err_reconfig;
+   }
+
+   /* Initiate reconfiguration */
+   writel(WZRD_DR_BEGIN_DYNA_RECONF,
+  divider->base + WZRD_DR_INIT_REG_OFFSET);
+
+   /* Check status register */
+   retries = WZRD_DR_NUM_RETRIES;
+   while (retries--) {
+   if (readl(divider->base + WZRD_DR_STATUS_REG_OFFSET) &
+   WZRD_DR_LOCK_BIT_MASK)
+   break;
+   }
+
+   if (!retries)
+   err = -ETIMEDOUT;
+
+err_reconfig:
+   if (divider->lock)
+   spin_unlock_irqrestore(divider->lock, flags);
+   else
+   __release(divider->lock);
+
+   return err;
+}
+
+static long clk_wzrd_round_rate_f(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+   return rate;
+}
+
+static const struct clk_ops clk_wzrd_clk_divider_ops_f = {
+   .round_rate = clk_wzrd_round_rate_f,
+   .set_rate = clk_wzrd_dynamic_reconfig_f,
+   .recalc_rate = clk_wzrd_recalc_ratef,
+};
+
+static struct clk *clk_wzrd_register_divf(struct device *dev,
+ const char *name,
+ 

[PATCH v5 4/8] clk: clock-wizard: Add support for dynamic reconfiguration

2020-06-26 Thread Shubhrajyoti Datta
The patch adds support for dynamic reconfiguration of clock output rate.
Output clocks are registered as dividers and set rate callback function
is used for dynamic reconfiguration.

Based on the initial work from Chirag.

Signed-off-by: Chirag Parekh 
Signed-off-by: Shubhrajyoti Datta 
---
 drivers/clk/clk-xlnx-clock-wizard.c | 212 +++-
 1 file changed, 206 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/clk-xlnx-clock-wizard.c 
b/drivers/clk/clk-xlnx-clock-wizard.c
index d6577c8..aaffb04 100644
--- a/drivers/clk/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/clk-xlnx-clock-wizard.c
@@ -31,8 +31,23 @@
 #define WZRD_DIVCLK_DIVIDE_SHIFT   0
 #define WZRD_DIVCLK_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
 #define WZRD_CLKOUT_DIVIDE_SHIFT   0
+#define WZRD_CLKOUT_DIVIDE_WIDTH   8
 #define WZRD_CLKOUT_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
 
+#define WZRD_DR_MAX_INT_DIV_VALUE  255
+#define WZRD_DR_NUM_RETRIES1
+#define WZRD_DR_STATUS_REG_OFFSET  0x04
+#define WZRD_DR_LOCK_BIT_MASK  0x0001
+#define WZRD_DR_INIT_REG_OFFSET0x25C
+#define WZRD_DR_DIV_TO_PHASE_OFFSET4
+#define WZRD_DR_BEGIN_DYNA_RECONF  0x03
+
+/* Get the mask from width */
+#define div_mask(width)((1 << (width)) - 1)
+
+/* Extract divider instance from clock hardware instance */
+#define to_clk_wzrd_divider(_hw) container_of(_hw, struct clk_wzrd_divider, hw)
+
 enum clk_wzrd_int_clks {
wzrd_clk_mul,
wzrd_clk_mul_div,
@@ -64,6 +79,29 @@ struct clk_wzrd {
bool suspended;
 };
 
+/**
+ * struct clk_wzrd_divider - clock divider specific to clk_wzrd
+ *
+ * @hw:handle between common and hardware-specific interfaces
+ * @base:  base address of register containing the divider
+ * @offset:offset address of register containing the divider
+ * @shift: shift to the divider bit field
+ * @width: width of the divider bit field
+ * @flags: clk_wzrd divider flags
+ * @table: array of value/divider pairs, last entry should have div = 0
+ * @lock:  register lock
+ */
+struct clk_wzrd_divider {
+   struct clk_hw hw;
+   void __iomem *base;
+   u16 offset;
+   u8 shift;
+   u8 width;
+   u8 flags;
+   const struct clk_div_table *table;
+   spinlock_t *lock;  /* divider lock */
+};
+
 #define to_clk_wzrd(_nb) container_of(_nb, struct clk_wzrd, nb)
 
 /* maximum frequencies for input/output clocks per speed grade */
@@ -73,6 +111,164 @@ static const unsigned long clk_wzrd_max_freq[] = {
106600UL
 };
 
+/* spin lock variable for clk_wzrd */
+static DEFINE_SPINLOCK(clkwzrd_lock);
+
+static unsigned long clk_wzrd_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+   struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
+   void __iomem *div_addr =
+   (void __iomem *)((u64)divider->base + divider->offset);
+   unsigned int val;
+
+   val = readl(div_addr) >> divider->shift;
+   val &= div_mask(divider->width);
+
+   return divider_recalc_rate(hw, parent_rate, val, divider->table,
+   divider->flags, divider->width);
+}
+
+static int clk_wzrd_dynamic_reconfig(struct clk_hw *hw, unsigned long rate,
+unsigned long parent_rate)
+{
+   int err = 0;
+   u16 retries;
+   u32 value;
+   unsigned long flags = 0;
+   struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
+   void __iomem *div_addr =
+   (void __iomem *)((u64)divider->base + divider->offset);
+
+   if (divider->lock)
+   spin_lock_irqsave(divider->lock, flags);
+   else
+   __acquire(divider->lock);
+
+   value = DIV_ROUND_CLOSEST(parent_rate, rate);
+
+   /* Cap the value to max */
+   if (value > WZRD_DR_MAX_INT_DIV_VALUE)
+   value = WZRD_DR_MAX_INT_DIV_VALUE;
+
+   /* Set divisor and clear phase offset */
+   writel(value, div_addr);
+   writel(0x00, div_addr + WZRD_DR_DIV_TO_PHASE_OFFSET);
+
+   /* Check status register */
+   retries = WZRD_DR_NUM_RETRIES;
+   while (retries--) {
+   if (readl(divider->base + WZRD_DR_STATUS_REG_OFFSET) &
+   WZRD_DR_LOCK_BIT_MASK)
+   break;
+   }
+
+   if (retries == 0) {
+   err = -ETIMEDOUT;
+   goto err_reconfig;
+   }
+
+   /* Initiate reconfiguration */
+   writel(WZRD_DR_BEGIN_DYNA_RECONF,
+  divider->base + WZRD_DR_INIT_REG_OFFSET);
+
+   /* Check status register */
+   retries = WZRD_DR_NUM_RETRIES;
+   while (ret

[PATCH v5 7/8] clk: clock-wizard: Update the fixed factor divisors

2020-06-26 Thread Shubhrajyoti Datta
Update the fixed factor clock registration to register the divisors.

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/clk/clk-xlnx-clock-wizard.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/clk-xlnx-clock-wizard.c 
b/drivers/clk/clk-xlnx-clock-wizard.c
index 0c57ca0..5f53bfd0 100644
--- a/drivers/clk/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/clk-xlnx-clock-wizard.c
@@ -493,9 +493,11 @@ static int clk_wzrd_probe(struct platform_device *pdev)
u32 reg, reg_f, mult;
unsigned long rate;
const char *clk_name;
+   void __iomem *ctrl_reg;
struct clk_wzrd *clk_wzrd;
struct resource *mem;
int outputs;
+   unsigned long flags = 0;
struct device_node *np = pdev->dev.of_node;
 
clk_wzrd = devm_kzalloc(>dev, sizeof(*clk_wzrd), GFP_KERNEL);
@@ -567,16 +569,17 @@ static int clk_wzrd_probe(struct platform_device *pdev)
}
 
outputs = of_property_count_strings(np, "clock-output-names");
-   /* register div */
-   reg = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(0)) &
-   WZRD_DIVCLK_DIVIDE_MASK) >> WZRD_DIVCLK_DIVIDE_SHIFT;
+   if (outputs == 1)
+   flags = CLK_SET_RATE_PARENT;
clk_name = kasprintf(GFP_KERNEL, "%s_mul_div", dev_name(>dev));
if (!clk_name) {
ret = -ENOMEM;
goto err_rm_int_clk;
}
 
-   clk_wzrd->clks_internal[wzrd_clk_mul_div] = clk_register_fixed_factor
+   ctrl_reg = clk_wzrd->base + WZRD_CLK_CFG_REG(0);
+   /* register div */
+   clk_wzrd->clks_internal[wzrd_clk_mul_div] = clk_register_divider
(>dev, clk_name,
 __clk_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]),
flags, ctrl_reg, 0, 8, CLK_DIVIDER_ONE_BASED |
@@ -601,7 +604,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
if (!i)
clk_wzrd->clkout[i] = clk_wzrd_register_divf
(>dev, clkout_name,
-   clk_name, 0,
+   clk_name, flags,
clk_wzrd->base, (WZRD_CLK_CFG_REG(2) + i * 12),
WZRD_CLKOUT_DIVIDE_SHIFT,
WZRD_CLKOUT_DIVIDE_WIDTH,
-- 
2.1.1



[PATCH v5 6/8] clk: clock-wizard: Remove the hardcoding of the clock outputs

2020-06-26 Thread Shubhrajyoti Datta
The number of output clocks are configurable in the hardware.
Currently the driver registers the maximum number of outputs.
Fix the same by registering only the outputs that are there.

Signed-off-by: Shubhrajyoti Datta 
---
v4:
Assign output in this patch

 drivers/clk/clk-xlnx-clock-wizard.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/clk-xlnx-clock-wizard.c 
b/drivers/clk/clk-xlnx-clock-wizard.c
index 1cf381c..0c57ca0 100644
--- a/drivers/clk/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/clk-xlnx-clock-wizard.c
@@ -495,6 +495,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
const char *clk_name;
struct clk_wzrd *clk_wzrd;
struct resource *mem;
+   int outputs;
struct device_node *np = pdev->dev.of_node;
 
clk_wzrd = devm_kzalloc(>dev, sizeof(*clk_wzrd), GFP_KERNEL);
@@ -565,6 +566,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
goto err_disable_clk;
}
 
+   outputs = of_property_count_strings(np, "clock-output-names");
/* register div */
reg = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(0)) &
WZRD_DIVCLK_DIVIDE_MASK) >> WZRD_DIVCLK_DIVIDE_SHIFT;
@@ -586,7 +588,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
}
 
/* register div per output */
-   for (i = WZRD_NUM_OUTPUTS - 1; i >= 0 ; i--) {
+   for (i = outputs - 1; i >= 0 ; i--) {
const char *clkout_name;
 
if (of_property_read_string_index(np, "clock-output-names", i,
@@ -617,7 +619,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
if (IS_ERR(clk_wzrd->clkout[i])) {
int j;
 
-   for (j = i + 1; j < WZRD_NUM_OUTPUTS; j++)
+   for (j = i + 1; j < outputs; j++)
clk_unregister(clk_wzrd->clkout[j]);
dev_err(>dev,
"unable to register divider clock\n");
-- 
2.1.1



[PATCH v5 3/8] clk: clock-wizard: Fix kernel-doc warning

2020-06-26 Thread Shubhrajyoti Datta
Update description for the clocking wizard structure

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/clk/clk-xlnx-clock-wizard.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk-xlnx-clock-wizard.c 
b/drivers/clk/clk-xlnx-clock-wizard.c
index b31524a..d6577c8 100644
--- a/drivers/clk/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/clk-xlnx-clock-wizard.c
@@ -40,7 +40,8 @@ enum clk_wzrd_int_clks {
 };
 
 /**
- * struct clk_wzrd:
+ * struct clk_wzrd - Clock wizard private data structure
+ *
  * @clk_data:  Clock data
  * @nb:Notifier block
  * @base:  Memory base
-- 
2.1.1



[PATCH v5 8/8] staging: clocking-wizard: Delete the driver from the staging

2020-06-26 Thread Shubhrajyoti Datta
Delete the driver from the staging as it is in drivers/clk.

Signed-off-by: Shubhrajyoti Datta 
Acked-by: Greg Kroah-Hartman 
---
 drivers/staging/Kconfig|   2 -
 drivers/staging/Makefile   |   1 -
 drivers/staging/clocking-wizard/Kconfig|  10 -
 drivers/staging/clocking-wizard/Makefile   |   2 -
 drivers/staging/clocking-wizard/TODO   |  12 -
 .../clocking-wizard/clk-xlnx-clock-wizard.c| 333 -
 drivers/staging/clocking-wizard/dt-binding.txt |  30 --
 7 files changed, 390 deletions(-)
 delete mode 100644 drivers/staging/clocking-wizard/Kconfig
 delete mode 100644 drivers/staging/clocking-wizard/Makefile
 delete mode 100644 drivers/staging/clocking-wizard/TODO
 delete mode 100644 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
 delete mode 100644 drivers/staging/clocking-wizard/dt-binding.txt

diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 4ec5528..cdb5422 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -78,8 +78,6 @@ source "drivers/staging/gs_fpgaboot/Kconfig"
 
 source "drivers/staging/unisys/Kconfig"
 
-source "drivers/staging/clocking-wizard/Kconfig"
-
 source "drivers/staging/fbtft/Kconfig"
 
 source "drivers/staging/fsl-dpaa2/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 4d34198..14570e5 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -29,7 +29,6 @@ obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/
 obj-$(CONFIG_GOLDFISH) += goldfish/
 obj-$(CONFIG_GS_FPGABOOT)  += gs_fpgaboot/
 obj-$(CONFIG_UNISYSSPAR)   += unisys/
-obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD)  += clocking-wizard/
 obj-$(CONFIG_FB_TFT)   += fbtft/
 obj-$(CONFIG_FSL_DPAA2)+= fsl-dpaa2/
 obj-$(CONFIG_WILC1000) += wilc1000/
diff --git a/drivers/staging/clocking-wizard/Kconfig 
b/drivers/staging/clocking-wizard/Kconfig
deleted file mode 100644
index 04be22d..000
--- a/drivers/staging/clocking-wizard/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Xilinx Clocking Wizard Driver
-#
-
-config COMMON_CLK_XLNX_CLKWZRD
-   tristate "Xilinx Clocking Wizard"
-   depends on COMMON_CLK && OF
-   help
- Support for the Xilinx Clocking Wizard IP core clock generator.
diff --git a/drivers/staging/clocking-wizard/Makefile 
b/drivers/staging/clocking-wizard/Makefile
deleted file mode 100644
index b1f9152..000
--- a/drivers/staging/clocking-wizard/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD)  += clk-xlnx-clock-wizard.o
diff --git a/drivers/staging/clocking-wizard/TODO 
b/drivers/staging/clocking-wizard/TODO
deleted file mode 100644
index ebe99db..000
--- a/drivers/staging/clocking-wizard/TODO
+++ /dev/null
@@ -1,12 +0,0 @@
-TODO:
-   - support for fractional multiplier
-   - support for fractional divider (output 0 only)
-   - support for set_rate() operations (may benefit from Stephen Boyd's
- refactoring of the clk primitives: https://lkml.org/lkml/2014/9/5/766)
-   - review arithmetic
- - overflow after multiplication?
- - maximize accuracy before divisions
-
-Patches to:
-   Greg Kroah-Hartman 
-   Sören Brinkmann 
diff --git a/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c 
b/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
deleted file mode 100644
index e52a64b..000
--- a/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
+++ /dev/null
@@ -1,333 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Xilinx 'Clocking Wizard' driver
- *
- *  Copyright (C) 2013 - 2014 Xilinx
- *
- *  Sören Brinkmann 
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#define WZRD_NUM_OUTPUTS   7
-#define WZRD_ACLK_MAX_FREQ 25000UL
-
-#define WZRD_CLK_CFG_REG(n)(0x200 + 4 * (n))
-
-#define WZRD_CLKOUT0_FRAC_EN   BIT(18)
-#define WZRD_CLKFBOUT_FRAC_EN  BIT(26)
-
-#define WZRD_CLKFBOUT_MULT_SHIFT   8
-#define WZRD_CLKFBOUT_MULT_MASK(0xff << 
WZRD_CLKFBOUT_MULT_SHIFT)
-#define WZRD_DIVCLK_DIVIDE_SHIFT   0
-#define WZRD_DIVCLK_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
-#define WZRD_CLKOUT_DIVIDE_SHIFT   0
-#define WZRD_CLKOUT_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
-
-enum clk_wzrd_int_clks {
-   wzrd_clk_mul,
-   wzrd_clk_mul_div,
-   wzrd_clk_int_max
-};
-
-/**
- * struct clk_wzrd:
- * @clk_data:  Clock data
- * @nb:Notifier block
- * @base:  Memory base
- * @clk_in1:   Handle to input clock 'clk_in1'
- * @axi_clk:   Handle to input clock 's_axi_aclk'
- * @clks_internal: Internal clocks
- * @clkout:Output

[PATCH v5 2/8] clk: clock-wizard: Add the clockwizard to clk directory

2020-06-26 Thread Shubhrajyoti Datta
Add clocking wizard driver to clk.

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/clk/Kconfig |   9 +
 drivers/clk/Makefile|   1 +
 drivers/clk/clk-xlnx-clock-wizard.c | 338 
 3 files changed, 348 insertions(+)
 create mode 100644 drivers/clk/clk-xlnx-clock-wizard.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 69934c0..5f66076 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -360,6 +360,15 @@ config COMMON_CLK_FIXED_MMIO
help
  Support for Memory Mapped IO Fixed clocks
 
+config COMMON_CLK_XLNX_CLKWZRD
+   tristate "Xilinx Clocking Wizard"
+   depends on COMMON_CLK && OF
+   help
+ Support for the Xilinx Clocking Wizard IP core clock generator.
+ Adds support for clocking wizard and compatible.
+ This driver supports the Xilinx clocking wizard programmable clock
+ synthesizer. The number of output is configurable in the design.
+
 source "drivers/clk/actions/Kconfig"
 source "drivers/clk/analogbits/Kconfig"
 source "drivers/clk/baikal-t1/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index ca9af11..f41287859 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -68,6 +68,7 @@ obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
 obj-$(CONFIG_COMMON_CLK_VC5)   += clk-versaclock5.o
 obj-$(CONFIG_COMMON_CLK_WM831X)+= clk-wm831x.o
 obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o
+obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD)  += clk-xlnx-clock-wizard.o
 
 # please keep this section sorted lexicographically by directory path name
 obj-y  += actions/
diff --git a/drivers/clk/clk-xlnx-clock-wizard.c 
b/drivers/clk/clk-xlnx-clock-wizard.c
new file mode 100644
index 000..b31524a
--- /dev/null
+++ b/drivers/clk/clk-xlnx-clock-wizard.c
@@ -0,0 +1,338 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx 'Clocking Wizard' driver
+ *
+ *  Copyright (C) 2013 - 2020 Xilinx
+ *
+ *  Sören Brinkmann 
+ *  Shubhrajyoti Datta 
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define WZRD_NUM_OUTPUTS   7
+#define WZRD_ACLK_MAX_FREQ 25000UL
+
+#define WZRD_CLK_CFG_REG(n)(0x200 + 4 * (n))
+
+#define WZRD_CLKOUT0_FRAC_EN   BIT(18)
+#define WZRD_CLKFBOUT_FRAC_EN  BIT(26)
+
+#define WZRD_CLKFBOUT_MULT_SHIFT   8
+#define WZRD_CLKFBOUT_MULT_MASK(0xff << 
WZRD_CLKFBOUT_MULT_SHIFT)
+#define WZRD_DIVCLK_DIVIDE_SHIFT   0
+#define WZRD_DIVCLK_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
+#define WZRD_CLKOUT_DIVIDE_SHIFT   0
+#define WZRD_CLKOUT_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
+
+enum clk_wzrd_int_clks {
+   wzrd_clk_mul,
+   wzrd_clk_mul_div,
+   wzrd_clk_int_max
+};
+
+/**
+ * struct clk_wzrd:
+ * @clk_data:  Clock data
+ * @nb:Notifier block
+ * @base:  Memory base
+ * @clk_in1:   Handle to input clock 'clk_in1'
+ * @axi_clk:   Handle to input clock 's_axi_aclk'
+ * @clks_internal: Internal clocks
+ * @clkout:Output clocks
+ * @speed_grade:   Speed grade of the device
+ * @suspended: Flag indicating power state of the device
+ */
+struct clk_wzrd {
+   struct clk_onecell_data clk_data;
+   struct notifier_block nb;
+   void __iomem *base;
+   struct clk *clk_in1;
+   struct clk *axi_clk;
+   struct clk *clks_internal[wzrd_clk_int_max];
+   struct clk *clkout[WZRD_NUM_OUTPUTS];
+   unsigned int speed_grade;
+   bool suspended;
+};
+
+#define to_clk_wzrd(_nb) container_of(_nb, struct clk_wzrd, nb)
+
+/* maximum frequencies for input/output clocks per speed grade */
+static const unsigned long clk_wzrd_max_freq[] = {
+   8UL,
+   93300UL,
+   106600UL
+};
+
+static int clk_wzrd_clk_notifier(struct notifier_block *nb, unsigned long 
event,
+void *data)
+{
+   unsigned long max;
+   struct clk_notifier_data *ndata = data;
+   struct clk_wzrd *clk_wzrd = to_clk_wzrd(nb);
+
+   if (clk_wzrd->suspended)
+   return NOTIFY_OK;
+
+   if (ndata->clk == clk_wzrd->clk_in1)
+   max = clk_wzrd_max_freq[clk_wzrd->speed_grade - 1];
+   else if (ndata->clk == clk_wzrd->axi_clk)
+   max = WZRD_ACLK_MAX_FREQ;
+   else
+   return NOTIFY_DONE; /* should never happen */
+
+   switch (event) {
+   case PRE_RATE_CHANGE:
+   if (ndata->new_rate > max)
+   return NOTIFY_BAD;
+   return NOTIFY_OK;
+   case POST_RATE_CHANGE:
+   case ABORT_RATE_CHANGE:
+   default:
+   return NOTIFY_DONE;
+   }
+}
+
+static int __maybe_unused clk_w

[PATCH v4 0/8] clk: clockwizard: Driver updates

2020-06-26 Thread Shubhrajyoti Datta
Greg suggested that we move the driver
to the clk from the staging.
Add patches to address the concerns regarding the fractional and
set rate support in the TODO.

The patch set does the following
- Trivial fixes for kernel doc.
- Move the driver to the clk folder
- Add capability to set rate.
- Add fractional support.
- Add support for configurable outputs.

Changes in the v3:
Added the cover-letter.
Add patches for rate setting and fractional support
Add patches for warning.
Remove the driver from staging as suggested

v4:
Reorder the patches.
Merge the CLK_IS_BASIC patch.
Add the yaml form of binding document

v5:
Fix a mismerge

Shubhrajyoti Datta (8):
  dt-bindings: add documentation of xilinx clocking wizard
  clk: clock-wizard: Add the clockwizard to clk directory
  clk: clock-wizard: Fix kernel-doc warning
  clk: clock-wizard: Add support for dynamic reconfiguration
  clk: clock-wizard: Add support for fractional support
  clk: clock-wizard: Remove the hardcoding of the clock outputs
  clk: clock-wizard: Update the fixed factor divisors
  staging: clocking-wizard: Delete the driver from the staging

 .../bindings/clock/xlnx,clocking-wizard.yaml   |  71 +++
 drivers/clk/Kconfig|   9 +
 drivers/clk/Makefile   |   1 +
 drivers/clk/clk-xlnx-clock-wizard.c| 710 +
 drivers/staging/Kconfig|   2 -
 drivers/staging/Makefile   |   1 -
 drivers/staging/clocking-wizard/Kconfig|  10 -
 drivers/staging/clocking-wizard/Makefile   |   2 -
 drivers/staging/clocking-wizard/TODO   |  12 -
 .../clocking-wizard/clk-xlnx-clock-wizard.c| 333 --
 drivers/staging/clocking-wizard/dt-binding.txt |  30 -
 11 files changed, 791 insertions(+), 390 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml
 create mode 100644 drivers/clk/clk-xlnx-clock-wizard.c
 delete mode 100644 drivers/staging/clocking-wizard/Kconfig
 delete mode 100644 drivers/staging/clocking-wizard/Makefile
 delete mode 100644 drivers/staging/clocking-wizard/TODO
 delete mode 100644 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
 delete mode 100644 drivers/staging/clocking-wizard/dt-binding.txt

-- 
2.1.1



[PATCH v5 1/8] dt-bindings: add documentation of xilinx clocking wizard

2020-06-26 Thread Shubhrajyoti Datta
Add the devicetree binding for the xilinx clocking wizard.

Signed-off-by: Shubhrajyoti Datta 
---
v4:
change to yaml format

 .../bindings/clock/xlnx,clocking-wizard.yaml   | 71 ++
 1 file changed, 71 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml

diff --git a/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml 
b/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml
new file mode 100644
index 000..5a8e991
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/xlnx,clocking-wiz.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Xilinx clocking wizard
+
+maintainers:
+  - Shubhrajyoti Datta 
+
+description: |
+  The clocking wizard is a soft ip clocking block of Xilinx versal. It
+  reads required input clock frequencies from the devicetree and acts as clock
+  clock output.
+
+select: false
+
+properties:
+  compatible:
+items:
+  - enum:
+  - xlnx,clocking-wizard
+  - xlnx,clocking-wizard-6.0
+
+  "#clock-cells":
+const: 1
+
+  clocks:
+description: List of clock specifiers which are external input
+  clocks to the given clock controller.
+items:
+  - description: clock input
+  - description: axi clock
+
+  clock-names:
+items:
+  - const: clk_in1
+  - const: s_axi_aclk
+
+  speed-grade:
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+  - enum: [1, 2, 3]
+description:
+  Speed grade of the device.
+maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - clocks
+  - clock-names
+  - speed-grade
+
+additionalProperties: false
+
+examples:
+  - |
+clock-generator@4004 {
+#clock-cells = <1>;
+reg = <0x4004 0x1000>;
+compatible = "xlnx,clk-wizard-1.0";
+speed-grade = <1>;
+clock-names = "clk_in1", "s_axi_aclk";
+clocks = < 15>, < 15>;
+clock-output-names = "clk_out1", "clk_out2",
+"clk_out3", "clk_out4", "clk_out5",
+"clk_out6", "clk_out7";
+};
+...
-- 
2.1.1



[PATCH v4 5/8] clk: clock-wizard: Add support for fractional support

2020-06-26 Thread Shubhrajyoti Datta
Currently the set rate granularity is to integral divisors.
Add support for the fractional divisors.
Only the first output0 is fractional in the hardware.

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/clk/clk-xlnx-clock-wizard.c | 192 +---
 1 file changed, 179 insertions(+), 13 deletions(-)

diff --git a/drivers/clk/clk-xlnx-clock-wizard.c 
b/drivers/clk/clk-xlnx-clock-wizard.c
index 4b563f3..8a7f9bb 100644
--- a/drivers/clk/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/clk-xlnx-clock-wizard.c
@@ -28,11 +28,15 @@
 
 #define WZRD_CLKFBOUT_MULT_SHIFT   8
 #define WZRD_CLKFBOUT_MULT_MASK(0xff << 
WZRD_CLKFBOUT_MULT_SHIFT)
+#define WZRD_CLKFBOUT_FRAC_SHIFT   16
+#define WZRD_CLKFBOUT_FRAC_MASK(0x3ff << 
WZRD_CLKFBOUT_FRAC_SHIFT)
 #define WZRD_DIVCLK_DIVIDE_SHIFT   0
 #define WZRD_DIVCLK_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
 #define WZRD_CLKOUT_DIVIDE_SHIFT   0
 #define WZRD_CLKOUT_DIVIDE_WIDTH   8
 #define WZRD_CLKOUT_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
+#define WZRD_CLKOUT_FRAC_SHIFT 8
+#define WZRD_CLKOUT_FRAC_MASK  0x3ff
 
 #define WZRD_DR_MAX_INT_DIV_VALUE  255
 #define WZRD_DR_NUM_RETRIES1
@@ -51,6 +55,7 @@
 enum clk_wzrd_int_clks {
wzrd_clk_mul,
wzrd_clk_mul_div,
+   wzrd_clk_mul_frac,
wzrd_clk_int_max
 };
 
@@ -212,6 +217,161 @@ static const struct clk_ops clk_wzrd_clk_divider_ops = {
.recalc_rate = clk_wzrd_recalc_rate,
 };
 
+static unsigned long clk_wzrd_recalc_ratef(struct clk_hw *hw,
+  unsigned long parent_rate)
+{
+   unsigned int val;
+   u32 div, frac;
+   struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
+   void __iomem *div_addr =
+   (void __iomem *)((u64)divider->base + divider->offset);
+
+   val = readl(div_addr);
+   div = val & div_mask(divider->width);
+   frac = (val >> WZRD_CLKOUT_FRAC_SHIFT) & WZRD_CLKOUT_FRAC_MASK;
+
+   return ((parent_rate * 1000) / ((div * 1000) + frac));
+}
+
+static int clk_wzrd_dynamic_reconfig_f(struct clk_hw *hw, unsigned long rate,
+  unsigned long parent_rate)
+{
+   int err = 0;
+   u16 retries;
+   u32 value, pre;
+   unsigned long flags = 0;
+   unsigned long rate_div, f, clockout0_div;
+   struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
+   void __iomem *div_addr =
+   (void __iomem *)((u64)divider->base + divider->offset);
+
+   if (divider->lock)
+   spin_lock_irqsave(divider->lock, flags);
+   else
+   __acquire(divider->lock);
+
+   rate_div = ((parent_rate * 1000) / rate);
+   clockout0_div = rate_div / 1000;
+
+   pre = DIV_ROUND_CLOSEST((parent_rate * 1000), rate);
+   f = (u32)(pre - (clockout0_div * 1000));
+   f = f & WZRD_CLKOUT_FRAC_MASK;
+
+   value = ((f << WZRD_CLKOUT_DIVIDE_WIDTH) | (clockout0_div &
+   WZRD_CLKOUT_DIVIDE_MASK));
+
+   /* Set divisor and clear phase offset */
+   writel(value, div_addr);
+   writel(0x0, div_addr + WZRD_DR_DIV_TO_PHASE_OFFSET);
+
+   /* Check status register */
+   retries = WZRD_DR_NUM_RETRIES;
+   while (retries--) {
+   if (readl(divider->base + WZRD_DR_STATUS_REG_OFFSET) &
+   WZRD_DR_LOCK_BIT_MASK)
+   break;
+   }
+
+   if (!retries) {
+   err = -ETIMEDOUT;
+   goto err_reconfig;
+   }
+
+   /* Initiate reconfiguration */
+   writel(WZRD_DR_BEGIN_DYNA_RECONF,
+  divider->base + WZRD_DR_INIT_REG_OFFSET);
+
+   /* Check status register */
+   retries = WZRD_DR_NUM_RETRIES;
+   while (retries--) {
+   if (readl(divider->base + WZRD_DR_STATUS_REG_OFFSET) &
+   WZRD_DR_LOCK_BIT_MASK)
+   break;
+   }
+
+   if (!retries)
+   err = -ETIMEDOUT;
+
+err_reconfig:
+   if (divider->lock)
+   spin_unlock_irqrestore(divider->lock, flags);
+   else
+   __release(divider->lock);
+
+   return err;
+}
+
+static long clk_wzrd_round_rate_f(struct clk_hw *hw, unsigned long rate,
+ unsigned long *prate)
+{
+   return rate;
+}
+
+static const struct clk_ops clk_wzrd_clk_divider_ops_f = {
+   .round_rate = clk_wzrd_round_rate_f,
+   .set_rate = clk_wzrd_dynamic_reconfig_f,
+   .recalc_rate = clk_wzrd_recalc_ratef,
+};
+
+static struct clk *clk_wzrd_register_divf(struct device *dev,
+ const char *name,
+ 

[PATCH v4 4/8] clk: clock-wizard: Add support for dynamic reconfiguration

2020-06-26 Thread Shubhrajyoti Datta
The patch adds support for dynamic reconfiguration of clock output rate.
Output clocks are registered as dividers and set rate callback function
is used for dynamic reconfiguration.

Based on the initial work from Chirag.

Signed-off-by: Chirag Parekh 
Signed-off-by: Shubhrajyoti Datta 
---

 drivers/clk/clk-xlnx-clock-wizard.c | 212 +++-
 1 file changed, 206 insertions(+), 6 deletions(-)

diff --git a/drivers/clk/clk-xlnx-clock-wizard.c 
b/drivers/clk/clk-xlnx-clock-wizard.c
index d6577c8..4b563f3 100644
--- a/drivers/clk/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/clk-xlnx-clock-wizard.c
@@ -31,8 +31,23 @@
 #define WZRD_DIVCLK_DIVIDE_SHIFT   0
 #define WZRD_DIVCLK_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
 #define WZRD_CLKOUT_DIVIDE_SHIFT   0
+#define WZRD_CLKOUT_DIVIDE_WIDTH   8
 #define WZRD_CLKOUT_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
 
+#define WZRD_DR_MAX_INT_DIV_VALUE  255
+#define WZRD_DR_NUM_RETRIES1
+#define WZRD_DR_STATUS_REG_OFFSET  0x04
+#define WZRD_DR_LOCK_BIT_MASK  0x0001
+#define WZRD_DR_INIT_REG_OFFSET0x25C
+#define WZRD_DR_DIV_TO_PHASE_OFFSET4
+#define WZRD_DR_BEGIN_DYNA_RECONF  0x03
+
+/* Get the mask from width */
+#define div_mask(width)((1 << (width)) - 1)
+
+/* Extract divider instance from clock hardware instance */
+#define to_clk_wzrd_divider(_hw) container_of(_hw, struct clk_wzrd_divider, hw)
+
 enum clk_wzrd_int_clks {
wzrd_clk_mul,
wzrd_clk_mul_div,
@@ -64,6 +79,29 @@ struct clk_wzrd {
bool suspended;
 };
 
+/**
+ * struct clk_wzrd_divider - clock divider specific to clk_wzrd
+ *
+ * @hw:handle between common and hardware-specific interfaces
+ * @base:  base address of register containing the divider
+ * @offset:offset address of register containing the divider
+ * @shift: shift to the divider bit field
+ * @width: width of the divider bit field
+ * @flags: clk_wzrd divider flags
+ * @table: array of value/divider pairs, last entry should have div = 0
+ * @lock:  register lock
+ */
+struct clk_wzrd_divider {
+   struct clk_hw hw;
+   void __iomem *base;
+   u16 offset;
+   u8 shift;
+   u8 width;
+   u8 flags;
+   const struct clk_div_table *table;
+   spinlock_t *lock;  /* divider lock */
+};
+
 #define to_clk_wzrd(_nb) container_of(_nb, struct clk_wzrd, nb)
 
 /* maximum frequencies for input/output clocks per speed grade */
@@ -73,6 +111,164 @@ static const unsigned long clk_wzrd_max_freq[] = {
106600UL
 };
 
+/* spin lock variable for clk_wzrd */
+static DEFINE_SPINLOCK(clkwzrd_lock);
+
+static unsigned long clk_wzrd_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+   struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
+   void __iomem *div_addr =
+   (void __iomem *)((u64)divider->base + divider->offset);
+   unsigned int val;
+
+   val = readl(div_addr) >> divider->shift;
+   val &= div_mask(divider->width);
+
+   return divider_recalc_rate(hw, parent_rate, val, divider->table,
+   divider->flags);
+}
+
+static int clk_wzrd_dynamic_reconfig(struct clk_hw *hw, unsigned long rate,
+unsigned long parent_rate)
+{
+   int err = 0;
+   u16 retries;
+   u32 value;
+   unsigned long flags = 0;
+   struct clk_wzrd_divider *divider = to_clk_wzrd_divider(hw);
+   void __iomem *div_addr =
+   (void __iomem *)((u64)divider->base + divider->offset);
+
+   if (divider->lock)
+   spin_lock_irqsave(divider->lock, flags);
+   else
+   __acquire(divider->lock);
+
+   value = DIV_ROUND_CLOSEST(parent_rate, rate);
+
+   /* Cap the value to max */
+   if (value > WZRD_DR_MAX_INT_DIV_VALUE)
+   value = WZRD_DR_MAX_INT_DIV_VALUE;
+
+   /* Set divisor and clear phase offset */
+   writel(value, div_addr);
+   writel(0x00, div_addr + WZRD_DR_DIV_TO_PHASE_OFFSET);
+
+   /* Check status register */
+   retries = WZRD_DR_NUM_RETRIES;
+   while (retries--) {
+   if (readl(divider->base + WZRD_DR_STATUS_REG_OFFSET) &
+   WZRD_DR_LOCK_BIT_MASK)
+   break;
+   }
+
+   if (retries == 0) {
+   err = -ETIMEDOUT;
+   goto err_reconfig;
+   }
+
+   /* Initiate reconfiguration */
+   writel(WZRD_DR_BEGIN_DYNA_RECONF,
+  divider->base + WZRD_DR_INIT_REG_OFFSET);
+
+   /* Check status register */
+   retries = WZRD_DR_NUM_RETRIES;
+   while (retries--) {
+   if (readl(divider->base + WZRD_DR_STATUS_REG_OFFSET) &a

[PATCH v4 3/8] clk: clock-wizard: Fix kernel-doc warning

2020-06-26 Thread Shubhrajyoti Datta
Update description for the clocking wizard structure

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/clk/clk-xlnx-clock-wizard.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk-xlnx-clock-wizard.c 
b/drivers/clk/clk-xlnx-clock-wizard.c
index b31524a..d6577c8 100644
--- a/drivers/clk/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/clk-xlnx-clock-wizard.c
@@ -40,7 +40,8 @@ enum clk_wzrd_int_clks {
 };
 
 /**
- * struct clk_wzrd:
+ * struct clk_wzrd - Clock wizard private data structure
+ *
  * @clk_data:  Clock data
  * @nb:Notifier block
  * @base:  Memory base
-- 
2.1.1



[PATCH v4 1/8] dt-bindings: add documentation of xilinx clocking wizard

2020-06-26 Thread Shubhrajyoti Datta
Add the devicetree binding for the xilinx clocking wizard.

Signed-off-by: Shubhrajyoti Datta 
---
v4:
Move to yaml format

 .../bindings/clock/xlnx,clocking-wizard.yaml   | 71 ++
 1 file changed, 71 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml

diff --git a/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml 
b/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml
new file mode 100644
index 000..5a8e991
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/xlnx,clocking-wiz.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Xilinx clocking wizard
+
+maintainers:
+  - Shubhrajyoti Datta 
+
+description: |
+  The clocking wizard is a soft ip clocking block of Xilinx versal. It
+  reads required input clock frequencies from the devicetree and acts as clock
+  clock output.
+
+select: false
+
+properties:
+  compatible:
+items:
+  - enum:
+  - xlnx,clocking-wizard
+  - xlnx,clocking-wizard-6.0
+
+  "#clock-cells":
+const: 1
+
+  clocks:
+description: List of clock specifiers which are external input
+  clocks to the given clock controller.
+items:
+  - description: clock input
+  - description: axi clock
+
+  clock-names:
+items:
+  - const: clk_in1
+  - const: s_axi_aclk
+
+  speed-grade:
+allOf:
+  - $ref: /schemas/types.yaml#/definitions/uint32
+  - enum: [1, 2, 3]
+description:
+  Speed grade of the device.
+maxItems: 1
+
+required:
+  - compatible
+  - "#clock-cells"
+  - clocks
+  - clock-names
+  - speed-grade
+
+additionalProperties: false
+
+examples:
+  - |
+clock-generator@4004 {
+#clock-cells = <1>;
+reg = <0x4004 0x1000>;
+compatible = "xlnx,clk-wizard-1.0";
+speed-grade = <1>;
+clock-names = "clk_in1", "s_axi_aclk";
+clocks = < 15>, < 15>;
+clock-output-names = "clk_out1", "clk_out2",
+"clk_out3", "clk_out4", "clk_out5",
+"clk_out6", "clk_out7";
+};
+...
-- 
2.1.1



[PATCH v4 7/8] clk: clock-wizard: Update the fixed factor divisors

2020-06-26 Thread Shubhrajyoti Datta
Update the fixed factor clock registration to register the divisors.

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/clk/clk-xlnx-clock-wizard.c | 13 -
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/clk/clk-xlnx-clock-wizard.c 
b/drivers/clk/clk-xlnx-clock-wizard.c
index 28bbaa0..333ada78 100644
--- a/drivers/clk/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/clk-xlnx-clock-wizard.c
@@ -493,9 +493,11 @@ static int clk_wzrd_probe(struct platform_device *pdev)
u32 reg, reg_f, mult;
unsigned long rate;
const char *clk_name;
+   void __iomem *ctrl_reg;
struct clk_wzrd *clk_wzrd;
struct resource *mem;
int outputs;
+   unsigned long flags = 0;
struct device_node *np = pdev->dev.of_node;
 
clk_wzrd = devm_kzalloc(>dev, sizeof(*clk_wzrd), GFP_KERNEL);
@@ -567,16 +569,17 @@ static int clk_wzrd_probe(struct platform_device *pdev)
}
 
outputs = of_property_count_strings(np, "clock-output-names");
-   /* register div */
-   reg = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(0)) &
-   WZRD_DIVCLK_DIVIDE_MASK) >> WZRD_DIVCLK_DIVIDE_SHIFT;
+   if (outputs == 1)
+   flags = CLK_SET_RATE_PARENT;
clk_name = kasprintf(GFP_KERNEL, "%s_mul_div", dev_name(>dev));
if (!clk_name) {
ret = -ENOMEM;
goto err_rm_int_clk;
}
 
-   clk_wzrd->clks_internal[wzrd_clk_mul_div] = clk_register_fixed_factor
+   ctrl_reg = clk_wzrd->base + WZRD_CLK_CFG_REG(0);
+   /* register div */
+   clk_wzrd->clks_internal[wzrd_clk_mul_div] = clk_register_divider
(>dev, clk_name,
 __clk_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]),
flags, ctrl_reg, 0, 8, CLK_DIVIDER_ONE_BASED |
@@ -601,7 +604,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
if (!i)
clk_wzrd->clkout[i] = clk_wzrd_register_divf
(>dev, clkout_name,
-   clk_name, 0,
+   clk_name, flags,
clk_wzrd->base, (WZRD_CLK_CFG_REG(2) + i * 12),
WZRD_CLKOUT_DIVIDE_SHIFT,
WZRD_CLKOUT_DIVIDE_WIDTH,
-- 
2.1.1



[PATCH v4 0/8] clk: clockwizard: Driver updates

2020-06-26 Thread Shubhrajyoti Datta
Greg suggested that we move the driver
to the clk from the staging.
Add patches to address the concerns regarding the fractional and
set rate support in the TODO.

The patch set does the following
- Trivial fixes for kernel doc.
- Move the driver to the clk folder
- Add capability to set rate.
- Add fractional support.
- Add support for configurable outputs.

Changes in the v3:
Added the cover-letter.
Add patches for rate setting and fractional support
Add patches for warning.
Remove the driver from staging as suggested

v4:
Reorder the patches.
Merge the CLK_IS_BASIC patch.
Add the yaml form of binding document


Shubhrajyoti Datta (8):
  dt-bindings: add documentation of xilinx clocking wizard
  clk: clock-wizard: Add the clockwizard to clk directory
  clk: clock-wizard: Fix kernel-doc warning
  clk: clock-wizard: Add support for dynamic reconfiguration
  clk: clock-wizard: Add support for fractional support
  clk: clock-wizard: Remove the hardcoding of the clock outputs
  clk: clock-wizard: Update the fixed factor divisors
  staging: clocking-wizard: Delete the driver from the staging

 .../bindings/clock/xlnx,clocking-wizard.yaml   |  71 +++
 drivers/clk/Kconfig|   9 +
 drivers/clk/Makefile   |   1 +
 drivers/clk/clk-xlnx-clock-wizard.c| 710 +
 drivers/staging/Kconfig|   2 -
 drivers/staging/Makefile   |   1 -
 drivers/staging/clocking-wizard/Kconfig|  10 -
 drivers/staging/clocking-wizard/Makefile   |   2 -
 drivers/staging/clocking-wizard/TODO   |  12 -
 .../clocking-wizard/clk-xlnx-clock-wizard.c| 333 --
 drivers/staging/clocking-wizard/dt-binding.txt |  30 -
 11 files changed, 791 insertions(+), 390 deletions(-)
 create mode 100644 
Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml
 create mode 100644 drivers/clk/clk-xlnx-clock-wizard.c
 delete mode 100644 drivers/staging/clocking-wizard/Kconfig
 delete mode 100644 drivers/staging/clocking-wizard/Makefile
 delete mode 100644 drivers/staging/clocking-wizard/TODO
 delete mode 100644 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
 delete mode 100644 drivers/staging/clocking-wizard/dt-binding.txt

-- 
2.1.1



[PATCH v4 6/8] clk: clock-wizard: Remove the hardcoding of the clock outputs

2020-06-26 Thread Shubhrajyoti Datta
The number of output clocks are configurable in the hardware.
Currently the driver registers the maximum number of outputs.
Fix the same by registering only the outputs that are there.

Signed-off-by: Shubhrajyoti Datta 
---
v4:
Assign output in this patch

 drivers/clk/clk-xlnx-clock-wizard.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/clk-xlnx-clock-wizard.c 
b/drivers/clk/clk-xlnx-clock-wizard.c
index 8a7f9bb..28bbaa0 100644
--- a/drivers/clk/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/clk-xlnx-clock-wizard.c
@@ -495,6 +495,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
const char *clk_name;
struct clk_wzrd *clk_wzrd;
struct resource *mem;
+   int outputs;
struct device_node *np = pdev->dev.of_node;
 
clk_wzrd = devm_kzalloc(>dev, sizeof(*clk_wzrd), GFP_KERNEL);
@@ -565,6 +566,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
goto err_disable_clk;
}
 
+   outputs = of_property_count_strings(np, "clock-output-names");
/* register div */
reg = (readl(clk_wzrd->base + WZRD_CLK_CFG_REG(0)) &
WZRD_DIVCLK_DIVIDE_MASK) >> WZRD_DIVCLK_DIVIDE_SHIFT;
@@ -586,7 +588,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
}
 
/* register div per output */
-   for (i = WZRD_NUM_OUTPUTS - 1; i >= 0 ; i--) {
+   for (i = outputs - 1; i >= 0 ; i--) {
const char *clkout_name;
 
if (of_property_read_string_index(np, "clock-output-names", i,
@@ -617,7 +619,7 @@ static int clk_wzrd_probe(struct platform_device *pdev)
if (IS_ERR(clk_wzrd->clkout[i])) {
int j;
 
-   for (j = i + 1; j < WZRD_NUM_OUTPUTS; j++)
+   for (j = i + 1; j < outputs; j++)
clk_unregister(clk_wzrd->clkout[j]);
dev_err(>dev,
"unable to register divider clock\n");
-- 
2.1.1



[PATCH v4 8/8] staging: clocking-wizard: Delete the driver from the staging

2020-06-26 Thread Shubhrajyoti Datta
Delete the driver from the staging as it is in drivers/clk.

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/staging/Kconfig|   2 -
 drivers/staging/Makefile   |   1 -
 drivers/staging/clocking-wizard/Kconfig|  10 -
 drivers/staging/clocking-wizard/Makefile   |   2 -
 drivers/staging/clocking-wizard/TODO   |  12 -
 .../clocking-wizard/clk-xlnx-clock-wizard.c| 333 -
 drivers/staging/clocking-wizard/dt-binding.txt |  30 --
 7 files changed, 390 deletions(-)
 delete mode 100644 drivers/staging/clocking-wizard/Kconfig
 delete mode 100644 drivers/staging/clocking-wizard/Makefile
 delete mode 100644 drivers/staging/clocking-wizard/TODO
 delete mode 100644 drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
 delete mode 100644 drivers/staging/clocking-wizard/dt-binding.txt

diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 4ec5528..cdb5422 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -78,8 +78,6 @@ source "drivers/staging/gs_fpgaboot/Kconfig"
 
 source "drivers/staging/unisys/Kconfig"
 
-source "drivers/staging/clocking-wizard/Kconfig"
-
 source "drivers/staging/fbtft/Kconfig"
 
 source "drivers/staging/fsl-dpaa2/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 4d34198..14570e5 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -29,7 +29,6 @@ obj-$(CONFIG_FIREWIRE_SERIAL) += fwserial/
 obj-$(CONFIG_GOLDFISH) += goldfish/
 obj-$(CONFIG_GS_FPGABOOT)  += gs_fpgaboot/
 obj-$(CONFIG_UNISYSSPAR)   += unisys/
-obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD)  += clocking-wizard/
 obj-$(CONFIG_FB_TFT)   += fbtft/
 obj-$(CONFIG_FSL_DPAA2)+= fsl-dpaa2/
 obj-$(CONFIG_WILC1000) += wilc1000/
diff --git a/drivers/staging/clocking-wizard/Kconfig 
b/drivers/staging/clocking-wizard/Kconfig
deleted file mode 100644
index 04be22d..000
--- a/drivers/staging/clocking-wizard/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Xilinx Clocking Wizard Driver
-#
-
-config COMMON_CLK_XLNX_CLKWZRD
-   tristate "Xilinx Clocking Wizard"
-   depends on COMMON_CLK && OF
-   help
- Support for the Xilinx Clocking Wizard IP core clock generator.
diff --git a/drivers/staging/clocking-wizard/Makefile 
b/drivers/staging/clocking-wizard/Makefile
deleted file mode 100644
index b1f9152..000
--- a/drivers/staging/clocking-wizard/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD)  += clk-xlnx-clock-wizard.o
diff --git a/drivers/staging/clocking-wizard/TODO 
b/drivers/staging/clocking-wizard/TODO
deleted file mode 100644
index ebe99db..000
--- a/drivers/staging/clocking-wizard/TODO
+++ /dev/null
@@ -1,12 +0,0 @@
-TODO:
-   - support for fractional multiplier
-   - support for fractional divider (output 0 only)
-   - support for set_rate() operations (may benefit from Stephen Boyd's
- refactoring of the clk primitives: https://lkml.org/lkml/2014/9/5/766)
-   - review arithmetic
- - overflow after multiplication?
- - maximize accuracy before divisions
-
-Patches to:
-   Greg Kroah-Hartman 
-   Sören Brinkmann 
diff --git a/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c 
b/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
deleted file mode 100644
index e52a64b..000
--- a/drivers/staging/clocking-wizard/clk-xlnx-clock-wizard.c
+++ /dev/null
@@ -1,333 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Xilinx 'Clocking Wizard' driver
- *
- *  Copyright (C) 2013 - 2014 Xilinx
- *
- *  Sören Brinkmann 
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#define WZRD_NUM_OUTPUTS   7
-#define WZRD_ACLK_MAX_FREQ 25000UL
-
-#define WZRD_CLK_CFG_REG(n)(0x200 + 4 * (n))
-
-#define WZRD_CLKOUT0_FRAC_EN   BIT(18)
-#define WZRD_CLKFBOUT_FRAC_EN  BIT(26)
-
-#define WZRD_CLKFBOUT_MULT_SHIFT   8
-#define WZRD_CLKFBOUT_MULT_MASK(0xff << 
WZRD_CLKFBOUT_MULT_SHIFT)
-#define WZRD_DIVCLK_DIVIDE_SHIFT   0
-#define WZRD_DIVCLK_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
-#define WZRD_CLKOUT_DIVIDE_SHIFT   0
-#define WZRD_CLKOUT_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
-
-enum clk_wzrd_int_clks {
-   wzrd_clk_mul,
-   wzrd_clk_mul_div,
-   wzrd_clk_int_max
-};
-
-/**
- * struct clk_wzrd:
- * @clk_data:  Clock data
- * @nb:Notifier block
- * @base:  Memory base
- * @clk_in1:   Handle to input clock 'clk_in1'
- * @axi_clk:   Handle to input clock 's_axi_aclk'
- * @clks_internal: Internal clocks
- * @clkout:Output clocks
- * @speed_grad

[PATCH v4 2/8] clk: clock-wizard: Add the clockwizard to clk directory

2020-06-26 Thread Shubhrajyoti Datta
Add clocking wizard driver to clk.

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/clk/Kconfig |   9 +
 drivers/clk/Makefile|   1 +
 drivers/clk/clk-xlnx-clock-wizard.c | 338 
 3 files changed, 348 insertions(+)
 create mode 100644 drivers/clk/clk-xlnx-clock-wizard.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 69934c0..5f66076 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -360,6 +360,15 @@ config COMMON_CLK_FIXED_MMIO
help
  Support for Memory Mapped IO Fixed clocks
 
+config COMMON_CLK_XLNX_CLKWZRD
+   tristate "Xilinx Clocking Wizard"
+   depends on COMMON_CLK && OF
+   help
+ Support for the Xilinx Clocking Wizard IP core clock generator.
+ Adds support for clocking wizard and compatible.
+ This driver supports the Xilinx clocking wizard programmable clock
+ synthesizer. The number of output is configurable in the design.
+
 source "drivers/clk/actions/Kconfig"
 source "drivers/clk/analogbits/Kconfig"
 source "drivers/clk/baikal-t1/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index ca9af11..f41287859 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -68,6 +68,7 @@ obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
 obj-$(CONFIG_COMMON_CLK_VC5)   += clk-versaclock5.o
 obj-$(CONFIG_COMMON_CLK_WM831X)+= clk-wm831x.o
 obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o
+obj-$(CONFIG_COMMON_CLK_XLNX_CLKWZRD)  += clk-xlnx-clock-wizard.o
 
 # please keep this section sorted lexicographically by directory path name
 obj-y  += actions/
diff --git a/drivers/clk/clk-xlnx-clock-wizard.c 
b/drivers/clk/clk-xlnx-clock-wizard.c
new file mode 100644
index 000..b31524a
--- /dev/null
+++ b/drivers/clk/clk-xlnx-clock-wizard.c
@@ -0,0 +1,338 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx 'Clocking Wizard' driver
+ *
+ *  Copyright (C) 2013 - 2020 Xilinx
+ *
+ *  Sören Brinkmann 
+ *  Shubhrajyoti Datta 
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define WZRD_NUM_OUTPUTS   7
+#define WZRD_ACLK_MAX_FREQ 25000UL
+
+#define WZRD_CLK_CFG_REG(n)(0x200 + 4 * (n))
+
+#define WZRD_CLKOUT0_FRAC_EN   BIT(18)
+#define WZRD_CLKFBOUT_FRAC_EN  BIT(26)
+
+#define WZRD_CLKFBOUT_MULT_SHIFT   8
+#define WZRD_CLKFBOUT_MULT_MASK(0xff << 
WZRD_CLKFBOUT_MULT_SHIFT)
+#define WZRD_DIVCLK_DIVIDE_SHIFT   0
+#define WZRD_DIVCLK_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
+#define WZRD_CLKOUT_DIVIDE_SHIFT   0
+#define WZRD_CLKOUT_DIVIDE_MASK(0xff << 
WZRD_DIVCLK_DIVIDE_SHIFT)
+
+enum clk_wzrd_int_clks {
+   wzrd_clk_mul,
+   wzrd_clk_mul_div,
+   wzrd_clk_int_max
+};
+
+/**
+ * struct clk_wzrd:
+ * @clk_data:  Clock data
+ * @nb:Notifier block
+ * @base:  Memory base
+ * @clk_in1:   Handle to input clock 'clk_in1'
+ * @axi_clk:   Handle to input clock 's_axi_aclk'
+ * @clks_internal: Internal clocks
+ * @clkout:Output clocks
+ * @speed_grade:   Speed grade of the device
+ * @suspended: Flag indicating power state of the device
+ */
+struct clk_wzrd {
+   struct clk_onecell_data clk_data;
+   struct notifier_block nb;
+   void __iomem *base;
+   struct clk *clk_in1;
+   struct clk *axi_clk;
+   struct clk *clks_internal[wzrd_clk_int_max];
+   struct clk *clkout[WZRD_NUM_OUTPUTS];
+   unsigned int speed_grade;
+   bool suspended;
+};
+
+#define to_clk_wzrd(_nb) container_of(_nb, struct clk_wzrd, nb)
+
+/* maximum frequencies for input/output clocks per speed grade */
+static const unsigned long clk_wzrd_max_freq[] = {
+   8UL,
+   93300UL,
+   106600UL
+};
+
+static int clk_wzrd_clk_notifier(struct notifier_block *nb, unsigned long 
event,
+void *data)
+{
+   unsigned long max;
+   struct clk_notifier_data *ndata = data;
+   struct clk_wzrd *clk_wzrd = to_clk_wzrd(nb);
+
+   if (clk_wzrd->suspended)
+   return NOTIFY_OK;
+
+   if (ndata->clk == clk_wzrd->clk_in1)
+   max = clk_wzrd_max_freq[clk_wzrd->speed_grade - 1];
+   else if (ndata->clk == clk_wzrd->axi_clk)
+   max = WZRD_ACLK_MAX_FREQ;
+   else
+   return NOTIFY_DONE; /* should never happen */
+
+   switch (event) {
+   case PRE_RATE_CHANGE:
+   if (ndata->new_rate > max)
+   return NOTIFY_BAD;
+   return NOTIFY_OK;
+   case POST_RATE_CHANGE:
+   case ABORT_RATE_CHANGE:
+   default:
+   return NOTIFY_DONE;
+   }
+}
+
+static int __maybe_unused clk_w

[RFC PATCHv2 1/3] dt-bindings: misc: Add dt bindings for flex noc Performance Monitor

2019-09-25 Thread Shubhrajyoti Datta
Add dt bindings for flexnoc Performance Monitor.
The flexnoc counters for read and write response and requests are
supported.

Signed-off-by: Shubhrajyoti Datta 
---
 .../devicetree/bindings/misc/xlnx,flexnoc.txt  | 24 ++
 1 file changed, 24 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/misc/xlnx,flexnoc.txt

diff --git a/Documentation/devicetree/bindings/misc/xlnx,flexnoc.txt 
b/Documentation/devicetree/bindings/misc/xlnx,flexnoc.txt
new file mode 100644
index 000..6b533bc
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/xlnx,flexnoc.txt
@@ -0,0 +1,24 @@
+* Xilinx Flexnoc Performance Monitor driver
+
+The FlexNoc Performance Monitor has counters for monitoring
+the read and the write transaction counter.
+
+Required properties:
+- compatible: "xlnx,flexnoc-pm-2.7"
+- reg : Address and length of register sets for each device in
+   "reg-names"
+- reg-names : The names of the register addresses corresponding to the
+   registers filled in "reg"
+   - funnel: base address of the funnel registers
+   - baselpd: base address of the LPD PM registers
+   - basefpd: base address FPD PM registers
+
+Example:
+
+performance-monitor@f092 {
+   compatible = "xlnx,flexnoc-pm-2.7";
+   reg-names = "funnel", "baselpd", "basefpd";
+   reg = <0x0 0xf092 0x0 0x1000>,
+   <0x0 0xf098 0x0 0x9000>,
+   <0x0 0xf0b8 0x0 0x9000>;
+};
--
2.1.1

This email and any attachments are intended for the sole use of the named 
recipient(s) and contain(s) confidential information that may be proprietary, 
privileged or copyrighted under applicable law. If you are not the intended 
recipient, do not read, copy, or forward this email message or any attachments. 
Delete this email message and any attachments immediately.


[RFC PATCHv2 3/3] Documentation: short descriptions for Flexnoc Performance Monitor driver

2019-09-25 Thread Shubhrajyoti Datta
Add short documentation for FlexNoc Performance Monitor driver.

Signed-off-by: Shubhrajyoti Datta 
---
v2:
patch added

 Documentation/misc-devices/xilinx_flex.txt | 66 ++
 1 file changed, 66 insertions(+)
 create mode 100644 Documentation/misc-devices/xilinx_flex.txt

diff --git a/Documentation/misc-devices/xilinx_flex.txt 
b/Documentation/misc-devices/xilinx_flex.txt
new file mode 100644
index 000..c075934
--- /dev/null
+++ b/Documentation/misc-devices/xilinx_flex.txt
@@ -0,0 +1,66 @@
+Kernel driver xilinx_flex
+
+
+Supported chips:
+Versal SOC
+
+Author:
+   Shubhrajyoti Datta 
+
+Description
+---
+
+Versal uses the Arteris FlexNoC interconnect instead of the ARM NIC. FlexNoC
+provides the capability to integrate performance counters in the interconnect.
+It has configurable probe points to monitor the packet and forwards it to
+observer for logging. It supports read and write transaction counts for
+request and response.
+
+Features:
+---> Run-time programmable selection of packet probe points.
+---> Recording of traffic and link statistics.
+---> Separate read and write response and request count.
+
+SYSFS:
+
+counteridfpd
+   RW - shows the counter number selected for the FPD Flexnoc.
+
+counterfpd_rdreq
+   RO - shows the read request count for the FPD counters.
+
+counterfpdsrc
+   WO - sets the source of the FPD counter.
+
+counterfpd_wrrsp
+   RO - shows the write response count for the FPD counters.
+
+counterfpd_rdrsp
+   RO - shows the read response count for the FPD counters.
+
+counterfpd_wrreq
+   RO - shows the write request count for the FPD counters.
+
+counterfpdport
+   WO - sets the port number selected for the FPD Flexnoc.
+
+counteridlpd
+   RW - shows the counter number selected for the LPD Flexnoc.
+
+counterlpdport
+   WO - sets the port number selected for the LPD Flexnoc.
+
+counterlpd_rdreq
+   RO - shows the read request count for the LPD counters.
+
+counterlpd_wrreq
+   RO - shows the write request count for the LPD counters.
+
+counterlpd_wrrsp
+   RO - shows the write response count for the LPD counters.
+
+counterlpdsrc
+   WO - sets the source of the LPD counter.
+
+counterlpd_rdrsp
+   RO - shows the read response count for the LPD counters.
--
2.1.1

This email and any attachments are intended for the sole use of the named 
recipient(s) and contain(s) confidential information that may be proprietary, 
privileged or copyrighted under applicable law. If you are not the intended 
recipient, do not read, copy, or forward this email message or any attachments. 
Delete this email message and any attachments immediately.


[RFC PATCHv2 2/3] misc: xilinx_flex: Add support for the flex noc Performance Monitor

2019-09-25 Thread Shubhrajyoti Datta
Add support for the FlexNoc Performance Monitor.
Adds support for various port setting and monitoring
the packets transactions. It supports LPD and FPD monitoring
counters for read and write transaction requests and responses.

Signed-off-by: Shubhrajyoti Datta 
---
v2:
Add a mutex to prevent race

---
 drivers/misc/Kconfig  |   9 +
 drivers/misc/Makefile |   1 +
 drivers/misc/xilinx_flex_pm.c | 653 ++
 3 files changed, 663 insertions(+)
 create mode 100644 drivers/misc/xilinx_flex_pm.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index c55b637..1e9a6fa 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -454,6 +454,15 @@ config XILINX_SDFEC

  If unsure, say N.

+config XILINX_FLEX_PM
+   tristate "Xilinx Flexnoc Performance Monitor"
+   help
+ This option enables support for the Xilinx Flex Noc Performance 
Monitor driver.
+ It monitors the read and write transactions. It has counters for the 
LPD and
+ FPD domains.
+
+ If unsure, say N
+
 config MISC_RTSX
tristate
default MISC_RTSX_PCI || MISC_RTSX_USB
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index c1860d3..1f1c34d 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -57,3 +57,4 @@ obj-y += cardreader/
 obj-$(CONFIG_PVPANIC)  += pvpanic.o
 obj-$(CONFIG_HABANA_AI)+= habanalabs/
 obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o
+obj-$(CONFIG_XILINX_FLEX_PM)   += xilinx_flex_pm.o
diff --git a/drivers/misc/xilinx_flex_pm.c b/drivers/misc/xilinx_flex_pm.c
new file mode 100644
index 000..e7684d1
--- /dev/null
+++ b/drivers/misc/xilinx_flex_pm.c
@@ -0,0 +1,653 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Flex Noc Performance Monitor driver.
+ * Copyright (c) 2019 Xilinx Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define to_xflex_dev_info(n)   ((struct xflex_dev_info *)dev_get_drvdata(n))
+
+#define FPM_LAR_OFFSET 0xFB0
+#define FPM_UNLOCK 0xC5ACCE55
+
+#define FPM_RD_REQ_OFFSET  0x1000
+#define FPM_RD_RES_OFFSET  0x2000
+#define FPM_WR_REQ_OFFSET  0x3000
+#define FPM_WR_RES_OFFSET  0x4000
+
+#define FPM_PORT_SEL_OFFSET0x134
+#define FPM_MAIN_CTRL_OFFSET   0x008
+#define FPM_SRC_SEL_OFFSET 0x138
+#define FPM_STATPERIOD 0x24
+#define FPM_CFGCTRL0x0C
+#define FPM_LPD0x4210002
+#define FPM_FPD0x420c003
+
+#define FPM_VAL0x300
+#define FPM_SRC0x200
+#define FPM_WRRSP_L0x7
+#define FPM_WRREQ_L0x6
+#define FPM_RDRSP_L0x5
+#define FPM_RDREQ_L0x4
+#define FPM_PROBE_SHIFT16
+#define FPM_COUNTER_OFFSET 0x14
+#define FPM_GLOBALEN   BIT(0)
+#define FPM_STATEN BIT(3)
+#define FPM_STATCOND_DUMP  BIT(5)
+#define FPM_NUM_COUNTERS   4
+#define FPM_MAINCTL_DIS0
+
+#define FPM_SRC_OFF0x0
+#define FPM_SRC_CYCLE  0x1
+#define FPM_SRC_IDLE   0x2
+#define FPM_SRC_XFER   0x3
+#define FPM_SRC_BUSY   0x4
+#define FPM_SRC_WAIT   0x5
+#define FPM_SRC_PACKET 0x6
+
+/* Port values */
+#define FPM_PORT_LPD_AFIFS_AXI 0x0
+#define FPM_PORT_LPD_OCM   0x1
+#define FPM_PORT_LPD_OCMEXT0x2
+#define FPM_PORT_PMC_RPU_AXI0  0x3
+
+#define FPM_PORT_FPDAXI0x1
+#define FPM_PORT_PROTXPPU  0x2
+
+/**
+ * struct xflex_dev_info - Global Driver structure
+ * @dev: Device structure
+ * @baselpd: Iomapped LPD base address
+ * @basefpd: Iomapped FPD base address
+ * @funnel: Iomapped funnel register base address
+ * @counterid_lpd: LPD counter id
+ * @counterid_fpd: FPD counter id
+ */
+struct xflex_dev_info {
+   struct device *dev;
+   void __iomem *baselpd;
+   void __iomem *basefpd;
+   void __iomem *funnel;
+   u32 counterid_fpd;
+   u32 counterid_lpd;
+   struct mutex mutex; /* avoid parallel access to device */
+};
+
+/**
+ * enum xflex_sysfs_cmd_codes - sysfs command codes
+ * @XFLEX_GET_COUNTER_FPD: get the FPD counter value
+ * @XFLEX_SET_COUNTER_FPD: set the FPD counter value
+ * @XFLEX_GET_COUNTER_FPD_RDREQ: get the FPD read request count
+ * @XFLEX_GET_COUNTER_FPD_RDRSP: get the FPD read response count
+ * @XFLEX_GET_COUNTER_FPD_WRREQ: get the FPD write request count
+ * @XFLEX_GET_COUNTER_FPD_WRRSP: get the FPD write response count
+ * @XFLEX_GET_COUNTER_LPD_RDREQ: get th

[RFC PATCH 2/2] misc: xilinx_flex: Add support for the flex noc Performance Monitor

2019-09-25 Thread Shubhrajyoti Datta
Add support for the FlexNoc Performance Monitor.
Adds support for various port setting and monitoring
the packets transactions. It supports LPD and FPD monitoring
counters for read and write transaction requests and responses.

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/misc/Kconfig  |   9 +
 drivers/misc/Makefile |   1 +
 drivers/misc/xilinx_flex_pm.c | 644 ++
 3 files changed, 654 insertions(+)
 create mode 100644 drivers/misc/xilinx_flex_pm.c

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index c55b637..1e9a6fa 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -454,6 +454,15 @@ config XILINX_SDFEC

  If unsure, say N.

+config XILINX_FLEX_PM
+   tristate "Xilinx Flexnoc Performance Monitor"
+   help
+ This option enables support for the Xilinx Flex Noc Performance 
Monitor driver.
+ It monitors the read and write transactions. It has counters for the 
LPD and
+ FPD domains.
+
+ If unsure, say N
+
 config MISC_RTSX
tristate
default MISC_RTSX_PCI || MISC_RTSX_USB
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index c1860d3..1f1c34d 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -57,3 +57,4 @@ obj-y += cardreader/
 obj-$(CONFIG_PVPANIC)  += pvpanic.o
 obj-$(CONFIG_HABANA_AI)+= habanalabs/
 obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o
+obj-$(CONFIG_XILINX_FLEX_PM)   += xilinx_flex_pm.o
diff --git a/drivers/misc/xilinx_flex_pm.c b/drivers/misc/xilinx_flex_pm.c
new file mode 100644
index 000..891ab3a
--- /dev/null
+++ b/drivers/misc/xilinx_flex_pm.c
@@ -0,0 +1,644 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Xilinx Flex Noc Performance Monitor driver.
+ * Copyright (c) 2019 Xilinx Inc.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Macro */
+#define to_xflex_dev_info(n)   ((struct xflex_dev_info *)dev_get_drvdata(n))
+
+#define FPM_LAR_OFFSET 0xFB0
+#define FPM_UNLOCK 0xC5ACCE55
+
+#define FPM_RD_REQ_OFFSET  0x1000
+#define FPM_RD_RES_OFFSET  0x2000
+#define FPM_WR_REQ_OFFSET  0x3000
+#define FPM_WR_RES_OFFSET  0x4000
+
+#define FPM_PORT_SEL_OFFSET0x134
+#define FPM_MAIN_CTRL_OFFSET   0x008
+#define FPM_SRC_SEL_OFFSET 0x138
+#define FPM_STATPERIOD 0x24
+#define FPM_CFGCTRL0x0C
+#define FPM_LPD0x4210002
+#define FPM_FPD0x420c003
+
+#define FPM_VAL0x300
+#define FPM_SRC0x200
+#define FPM_WRRSP_L0x7
+#define FPM_WRREQ_L0x6
+#define FPM_RDRSP_L0x5
+#define FPM_RDREQ_L0x4
+#define FPM_PROBE_SHIFT16
+#define FPM_COUNTER_OFFSET 0x14
+#define FPM_GLOBALEN   BIT(0)
+#define FPM_STATEN BIT(3)
+#define FPM_STATCOND_DUMP  BIT(5)
+#define FPM_NUM_COUNTERS   4
+#define FPM_MAINCTL_DIS0
+
+#define FPM_SRC_OFF0x0
+#define FPM_SRC_CYCLE  0x1
+#define FPM_SRC_IDLE   0x2
+#define FPM_SRC_XFER   0x3
+#define FPM_SRC_BUSY   0x4
+#define FPM_SRC_WAIT   0x5
+#define FPM_SRC_PACKET 0x6
+
+/*Port values */
+#define FPM_PORT_LPD_AFIFS_AXI 0x0
+#define FPM_PORT_LPD_OCM   0x1
+#define FPM_PORT_LPD_OCMEXT0x2
+#define FPM_PORT_PMC_RPU_AXI0  0x3
+
+#define FPM_PORT_FPDAXI0x1
+#define FPM_PORT_PROTXPPU  0x2
+
+/**
+ * struct xflex_dev_info - Global Driver structure
+ * @dev: Device structure
+ * @baselpd: Iomapped LPD base address
+ * @basefpd: Iomapped FPD base address
+ * @funnel: Iomapped funnel register base address
+ * @counterid_lpd: LPD counter id
+ * @counterid_fpd: FPD counter id
+ */
+struct xflex_dev_info {
+   struct device *dev;
+   void __iomem *baselpd;
+   void __iomem *basefpd;
+   void __iomem *funnel;
+   u32 counterid_fpd;
+   u32 counterid_lpd;
+};
+
+/**
+ * enum xflex_sysfs_cmd_codes - sysfs command codes
+ * @XFLEX_GET_COUNTER_FPD: get the FPD counter value
+ * @XFLEX_SET_COUNTER_FPD: set the FPD counter value
+ * @XFLEX_GET_COUNTER_FPD_RDREQ: get the FPD read request count
+ * @XFLEX_GET_COUNTER_FPD_RDRSP: get the FPD read response count
+ * @XFLEX_GET_COUNTER_FPD_WRREQ: get the FPD write request count
+ * @XFLEX_GET_COUNTER_FPD_WRRSP: get the FPD write response count
+ * @XFLEX_GET_COUNTER_LPD_RDREQ: get the LPD read request count
+ * @XFLEX_GET_COUNTER_LPD_RDRSP: get the LPD read resp

[RFC PATCH 1/2] dt-bindings: misc: Add dt bindings for flex noc Performance Monitor

2019-09-25 Thread Shubhrajyoti Datta
Add dt bindings for flexnoc Performance Monitor.
The flexnoc counters for read and write response and requests are
supported.

Signed-off-by: Shubhrajyoti Datta 
---
 .../devicetree/bindings/misc/xlnx,flexnoc.txt  | 24 ++
 1 file changed, 24 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/misc/xlnx,flexnoc.txt

diff --git a/Documentation/devicetree/bindings/misc/xlnx,flexnoc.txt 
b/Documentation/devicetree/bindings/misc/xlnx,flexnoc.txt
new file mode 100644
index 000..6b533bc
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/xlnx,flexnoc.txt
@@ -0,0 +1,24 @@
+* Xilinx Flexnoc Performance Monitor driver
+
+The FlexNoc Performance Monitor has counters for monitoring
+the read and the write transaction counter.
+
+Required properties:
+- compatible: "xlnx,flexnoc-pm-2.7"
+- reg : Address and length of register sets for each device in
+   "reg-names"
+- reg-names : The names of the register addresses corresponding to the
+   registers filled in "reg"
+   - funnel: base address of the funnel registers
+   - baselpd: base address of the LPD PM registers
+   - basefpd: base address FPD PM registers
+
+Example:
+
+performance-monitor@f092 {
+   compatible = "xlnx,flexnoc-pm-2.7";
+   reg-names = "funnel", "baselpd", "basefpd";
+   reg = <0x0 0xf092 0x0 0x1000>,
+   <0x0 0xf098 0x0 0x9000>,
+   <0x0 0xf0b8 0x0 0x9000>;
+};
--
2.1.1

This email and any attachments are intended for the sole use of the named 
recipient(s) and contain(s) confidential information that may be proprietary, 
privileged or copyrighted under applicable law. If you are not the intended 
recipient, do not read, copy, or forward this email message or any attachments. 
Delete this email message and any attachments immediately.


Re: [PATCH] serial-uartlite: Fix null-ptr-deref in ulite_exit

2019-05-16 Thread Shubhrajyoti Datta
Hi YueHaibing,
Thanks for the patch.

On Thu, May 16, 2019 at 9:42 AM YueHaibing  wrote:
>
> If ulite_probe is not called or failed to registed
s/registed/register
> uart_register_driver, unload the module will call
> uart_unregister_driver, which will tigger NULL
s/tigger/trigger
> pointer dereference like this:
>
> BUG: KASAN: null-ptr-deref in tty_unregister_driver+0x19/0x100
> Read of size 4 at addr 0034 by task syz-executor.0/4246
>
> CPU: 0 PID: 4246 Comm: syz-executor.0 Tainted: G C5.1.0+ #26
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 
> 04/01/2014
> Call Trace:
>  dump_stack+0xa9/0x10e
>  ? tty_unregister_driver+0x19/0x100
>  ? tty_unregister_driver+0x19/0x100
>  __kasan_report+0x171/0x18d
>  ? tty_unregister_driver+0x19/0x100
>  kasan_report+0xe/0x20
>  tty_unregister_driver+0x19/0x100
>  uart_unregister_driver+0x30/0xc0
>  __x64_sys_delete_module+0x244/0x330
>  ? __ia32_sys_delete_module+0x330/0x330
>  ? __x64_sys_clock_gettime+0xe3/0x160
>  ? trace_hardirqs_on_thunk+0x1a/0x1c
>  ? trace_hardirqs_off_caller+0x3e/0x130
>  ? lockdep_hardirqs_off+0xb5/0x100
>  ? mark_held_locks+0x1a/0x90
>  ? do_syscall_64+0x14/0x2a0
>  do_syscall_64+0x72/0x2a0
>  entry_SYSCALL_64_after_hwframe+0x49/0xbe
>
> This patch fix this by moving uart_unregister_driver
> to ulite_remove.
>
Reviewed-by: Shubhrajyoti Datta 
> Reported-by: Hulk Robot 
> Fixes: 415b43bdb008 ("tty: serial: uartlite: Move uart register to probe")
> Signed-off-by: YueHaibing 
> ---
>  drivers/tty/serial/uartlite.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c
> index b8b912b..2e49fb6 100644
> --- a/drivers/tty/serial/uartlite.c
> +++ b/drivers/tty/serial/uartlite.c
> @@ -867,6 +867,7 @@ static int ulite_remove(struct platform_device *pdev)
> pm_runtime_disable(>dev);
> pm_runtime_set_suspended(>dev);
> pm_runtime_dont_use_autosuspend(>dev);
> +   uart_unregister_driver(_uart_driver);
> return rc;
>  }
>
> @@ -897,7 +898,6 @@ static int __init ulite_init(void)
>  static void __exit ulite_exit(void)
>  {
> platform_driver_unregister(_platform_driver);
> -   uart_unregister_driver(_uart_driver);
>  }
>
>  module_init(ulite_init);
> --
> 1.8.3.1
>
>


Re: Re: [PATCH] i2c: cadence: try reset when master receive error interrupts

2019-02-17 Thread Shubhrajyoti Datta
On Mon, Feb 18, 2019 at 12:48 PM sxau...@163.com  wrote:
>
> Hi , Shubhrajyoti
>
> >Hi ,
> >On Sat, Feb 16, 2019 at 1:21 PM sxau...@163.com  wrote:
> >>
> >> >Hi Sxauwsk,
> >> >
> >> >On Wed, Jan 30, 2019 at 3:13 PM sxauwsk  wrote:
> >> >>
> >> >> When the adapter receive error interrupts, such as NACK, arbitration 
> >> >> lost,
> >> >> cdns_i2c_master_xfer return to the caller directly instead of resuming
> >> >> the adapter which resulted in the adapter being out of control.
> >> >>
> >> >> So when driver detect err_status then try to repair and fix it.
> >> >>
> >> >> Signed-off-by: sxauwsk 
> >> >> ---
> >> >>  drivers/i2c/busses/i2c-cadence.c | 12 +++-
> >> >>  1 file changed, 7 insertions(+), 5 deletions(-)
> >> >>
> >> >> diff --git a/drivers/i2c/busses/i2c-cadence.c 
> >> >> b/drivers/i2c/busses/i2c-cadence.c
> >> >> index b13605718291..e10048d7524a 100644
> >> >> --- a/drivers/i2c/busses/i2c-cadence.c
> >> >> +++ b/drivers/i2c/busses/i2c-cadence.c
> >> >> @@ -548,10 +548,6 @@ static int cdns_i2c_process_msg(struct cdns_i2c 
> >> >> *id, struct i2c_msg *msg,
> >> >> cdns_i2c_writereg(CDNS_I2C_IXR_ALL_INTR_MASK,
> >> >>   CDNS_I2C_IDR_OFFSET);
> >> >>
> >> >> -   /* If it is bus arbitration error, try again */
> >> >> -   if (id->err_status & CDNS_I2C_IXR_ARB_LOST)
> >> >> -   return -EAGAIN;
> >> >> -
> >> >> return 0;
> >> >>  }
> >> >>
> >> >> @@ -617,13 +613,19 @@ static int cdns_i2c_master_xfer(struct 
> >> >> i2c_adapter *adap, struct i2c_msg *msgs,
> >> >> id->bus_hold_flag = 0;
> >> >>
> >> >> ret = cdns_i2c_process_msg(id, msgs, adap);
> >> >> -   if (ret)
> >> >> +   if (!ret)
> >> >> goto out;
> >> >>
> >> >In case  the Arbitration error happend  the cdns_i2c_process_msg would 
> >> >return 0
> >> >and we will miss the check  below.
> >> >
> >> >Am I missing something ?
> >> >
> >> >> /* Report the other error interrupts to application */
> >> >> if (id->err_status) {
> >> >> cdns_i2c_master_reset(adap);
> >> >>
> >> >> +   /* If it is bus arbitration error, try again */
> >> >> +   if (id->err_status & CDNS_I2C_IXR_ARB_LOST) {
> >> >> +   ret = -EAGAIN;
> >> >> +   goto out;
> >> >> +   }
> >> >> +
> >> >> if (id->err_status & CDNS_I2C_IXR_NACK) {
> >> >> ret = -ENXIO;
> >> >> goto out;
> >> >> --
> >> >> 2.19.2
> >> >>
> >> >>
> >>
> >> In cdns_i2c_process_msg process, when detect arbitration lost error return 
> >> -EAGAIN to  cdns_i2c_master_xfer,  not return 0
> >> that mean cdns_i2c_process_msg  just go out ignore error check and  
> >> problem occur, So we should do something when arbitration error detect.
> >
> >Arbitration lost is fine how about other errors like NACK.
>
> >> >> ret = cdns_i2c_process_msg(id, msgs, adap);
> >> >> -   if (ret)
> >> >> +   if (!ret)
> >> >> goto out;
>
> Yes, you're right,  This place I should't make any change,  perfect solution!
>
> >> >>
> >> >> -   /* If it is bus arbitration error, try again */
> >> >> -   if (id->err_status & CDNS_I2C_IXR_ARB_LOST)
> >> >> -   return -EAGAIN;
> >> >> -
> >> >> return 0;
> >> >>  }
>
>
> >> >> /* Report the other error interrupts to application */
> >> >> if (id->err_status) {
> >> >> cdns_i2c_master_reset(adap);
> >> >>
> >> >> +   /* If it is bus arbitration error, try again */
> >> >> +   if (id->err_status & CDNS_I2C_IXR_ARB_LOST) {
> >> >> +   ret = -EAGAIN;
> >> >> +   goto out;
> >> >> +   }
> >> >> +
>
> Maybe Just remove Arbitration lost Detect part from  cdns_i2c_process_msg 
> function,  then add to cdns_i2c_master_xfer,  Do you think?

I agree.
>
>
>
>


Re: [PATCH] i2c: cadence: try reset when master receive error interrupts

2019-02-17 Thread Shubhrajyoti Datta
Hi ,
On Sat, Feb 16, 2019 at 1:21 PM sxau...@163.com  wrote:
>
> >Hi Sxauwsk,
> >
> >On Wed, Jan 30, 2019 at 3:13 PM sxauwsk  wrote:
> >>
> >> When the adapter receive error interrupts, such as NACK, arbitration lost,
> >> cdns_i2c_master_xfer return to the caller directly instead of resuming
> >> the adapter which resulted in the adapter being out of control.
> >>
> >> So when driver detect err_status then try to repair and fix it.
> >>
> >> Signed-off-by: sxauwsk 
> >> ---
> >>  drivers/i2c/busses/i2c-cadence.c | 12 +++-
> >>  1 file changed, 7 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/drivers/i2c/busses/i2c-cadence.c 
> >> b/drivers/i2c/busses/i2c-cadence.c
> >> index b13605718291..e10048d7524a 100644
> >> --- a/drivers/i2c/busses/i2c-cadence.c
> >> +++ b/drivers/i2c/busses/i2c-cadence.c
> >> @@ -548,10 +548,6 @@ static int cdns_i2c_process_msg(struct cdns_i2c *id, 
> >> struct i2c_msg *msg,
> >> cdns_i2c_writereg(CDNS_I2C_IXR_ALL_INTR_MASK,
> >>   CDNS_I2C_IDR_OFFSET);
> >>
> >> -   /* If it is bus arbitration error, try again */
> >> -   if (id->err_status & CDNS_I2C_IXR_ARB_LOST)
> >> -   return -EAGAIN;
> >> -
> >> return 0;
> >>  }
> >>
> >> @@ -617,13 +613,19 @@ static int cdns_i2c_master_xfer(struct i2c_adapter 
> >> *adap, struct i2c_msg *msgs,
> >> id->bus_hold_flag = 0;
> >>
> >> ret = cdns_i2c_process_msg(id, msgs, adap);
> >> -   if (ret)
> >> +   if (!ret)
> >> goto out;
> >>
> >In case  the Arbitration error happend  the cdns_i2c_process_msg would 
> >return 0
> >and we will miss the check  below.
> >
> >Am I missing something ?
> >
> >> /* Report the other error interrupts to application */
> >> if (id->err_status) {
> >> cdns_i2c_master_reset(adap);
> >>
> >> +   /* If it is bus arbitration error, try again */
> >> +   if (id->err_status & CDNS_I2C_IXR_ARB_LOST) {
> >> +   ret = -EAGAIN;
> >> +   goto out;
> >> +   }
> >> +
> >> if (id->err_status & CDNS_I2C_IXR_NACK) {
> >> ret = -ENXIO;
> >> goto out;
> >> --
> >> 2.19.2
> >>
> >>
>
> In cdns_i2c_process_msg process, when detect arbitration lost error return 
> -EAGAIN to  cdns_i2c_master_xfer,  not return 0
> that mean cdns_i2c_process_msg  just go out ignore error check and  problem 
> occur, So we should do something when arbitration error detect.

Arbitration lost is fine how about other errors like NACK.


Re: [PATCH] i2c: cadence: try reset when master receive error interrupts

2019-02-15 Thread Shubhrajyoti Datta
Hi Sxauwsk,

On Wed, Jan 30, 2019 at 3:13 PM sxauwsk  wrote:
>
> When the adapter receive error interrupts, such as NACK, arbitration lost,
> cdns_i2c_master_xfer return to the caller directly instead of resuming
> the adapter which resulted in the adapter being out of control.
>
> So when driver detect err_status then try to repair and fix it.
>
> Signed-off-by: sxauwsk 
> ---
>  drivers/i2c/busses/i2c-cadence.c | 12 +++-
>  1 file changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-cadence.c 
> b/drivers/i2c/busses/i2c-cadence.c
> index b13605718291..e10048d7524a 100644
> --- a/drivers/i2c/busses/i2c-cadence.c
> +++ b/drivers/i2c/busses/i2c-cadence.c
> @@ -548,10 +548,6 @@ static int cdns_i2c_process_msg(struct cdns_i2c *id, 
> struct i2c_msg *msg,
> cdns_i2c_writereg(CDNS_I2C_IXR_ALL_INTR_MASK,
>   CDNS_I2C_IDR_OFFSET);
>
> -   /* If it is bus arbitration error, try again */
> -   if (id->err_status & CDNS_I2C_IXR_ARB_LOST)
> -   return -EAGAIN;
> -
> return 0;
>  }
>
> @@ -617,13 +613,19 @@ static int cdns_i2c_master_xfer(struct i2c_adapter 
> *adap, struct i2c_msg *msgs,
> id->bus_hold_flag = 0;
>
> ret = cdns_i2c_process_msg(id, msgs, adap);
> -   if (ret)
> +   if (!ret)
> goto out;
>
In case  the Arbitration error happend  the cdns_i2c_process_msg would return 0
and we will miss the check  below.

Am I missing something ?

> /* Report the other error interrupts to application */
> if (id->err_status) {
> cdns_i2c_master_reset(adap);
>
> +   /* If it is bus arbitration error, try again */
> +   if (id->err_status & CDNS_I2C_IXR_ARB_LOST) {
> +   ret = -EAGAIN;
> +   goto out;
> +   }
> +
> if (id->err_status & CDNS_I2C_IXR_NACK) {
> ret = -ENXIO;
> goto out;
> --
> 2.19.2
>
>


Re: [PATCH] gpio: zynq: properly support runtime PM for GPIO used as interrupts

2019-02-11 Thread Shubhrajyoti Datta
Hi Thomas,

Thanks for the patch.

On Fri, Feb 8, 2019 at 4:13 PM Thomas Petazzoni
 wrote:
>
> The Zynq GPIO driver currently implements runtime PM by:
>
>  - Enabling runtime PM support in ->probe() and letting the runtime PM
>reference counter drop to zero at the end of ->probe().
>
>  - Increasing the runtime PM reference counter in ->request() and
>decreasing it in ->free().
>
> However, the latter is not sufficient: when a GPIO is used as an
> interrupt, ->request() and ->free() are not called. Due to this, the
> runtime PM counter remains to zero when the only GPIOs in use are used
> as interrupts, causing them to simply not work.
>
> To address this problem, this commit implement the
> ->irq_request_resources() and ->irq_release_resources() hooks,
> ensuring that the runtime PM counter is properly
> incremented/decremented. Since we override the default hooks, we keep
> the existing behavior by making sure they call gpiochip_reqres_irq() /
> gpiochip_relres_irq() respectively.
>
> Signed-off-by: Thomas Petazzoni 
> ---
Reviewed-by: Shubhrajyoti Datta 
>


Re: [PATCH 2/8] gpio: zynq: Wakeup gpio controller when it is used as IRQ controller

2019-01-20 Thread Shubhrajyoti Datta
On Fri, Jan 11, 2019 at 8:26 PM Linus Walleij  wrote:
>
> On Fri, Jan 11, 2019 at 1:54 PM Thomas Petazzoni
>  wrote:
> > On Fri, 11 Jan 2019 10:54:20 +0100, Linus Walleij wrote:
> >
> > > My stance is that the driver is responsible of enabling and managing
> > > runtime PM for its hardware block(s).
> > >
> > > Runtime PM in the core should only be added if the core needs to
> > > be aware about it, such as is the case when e.g. a block device
> > > needs to drain its write buffer before going to runtime sleep.
> > >
> > > I fail so see why the GPIO core need to be aware about this.
> >
> > In this very same thread at
> > https://www.spinics.net/lists/arm-kernel/msg600515.html,  you kind of

I was not abloe to open the link could you please let me  know if I am
missing something?


Re: [PATCH] i2c: xiic: Make the start and the byte count write atomic

2018-09-06 Thread Shubhrajyoti Datta
Hi,

On Tue, Sep 4, 2018 at 9:41 PM Wolfram Sang  wrote:
>
> On Mon, Sep 03, 2018 at 03:11:11PM +0530, shubhrajyoti.da...@gmail.com wrote:
> > From: Shubhrajyoti Datta 
> >
> > Disable interrupts while configuring the transfer and enable them back.
> >
> > We have below as the programming sequence
> > 1. start and slave address
> > 2. byte count and stop
> >
> > In some customer platform there was a lot of interrupts between 1 and 2
> > and after slave address (around 7 clock cyles) if 2 is not executed
> > then the transaction is nacked.
> >
> > To fix this case make the 2 writes atomic.
> >
> > Signed-off-by: Shubhrajyoti Datta 
> > Signed-off-by: Michal Simek 
>
> I assume simply changing the order of the register writes won't fix it?
No that is not possible.
>
> I also assume this is stable material?
>
Yes let me know if you want me to resend with the stable tag?


Re: [PATCH] i2c: xiic: Make the start and the byte count write atomic

2018-09-06 Thread Shubhrajyoti Datta
Hi,

On Tue, Sep 4, 2018 at 9:41 PM Wolfram Sang  wrote:
>
> On Mon, Sep 03, 2018 at 03:11:11PM +0530, shubhrajyoti.da...@gmail.com wrote:
> > From: Shubhrajyoti Datta 
> >
> > Disable interrupts while configuring the transfer and enable them back.
> >
> > We have below as the programming sequence
> > 1. start and slave address
> > 2. byte count and stop
> >
> > In some customer platform there was a lot of interrupts between 1 and 2
> > and after slave address (around 7 clock cyles) if 2 is not executed
> > then the transaction is nacked.
> >
> > To fix this case make the 2 writes atomic.
> >
> > Signed-off-by: Shubhrajyoti Datta 
> > Signed-off-by: Michal Simek 
>
> I assume simply changing the order of the register writes won't fix it?
No that is not possible.
>
> I also assume this is stable material?
>
Yes let me know if you want me to resend with the stable tag?


Re: [PATCH v3 2/4] drivers: firmware: xilinx: Add ZynqMP firmware driver

2018-01-29 Thread Shubhrajyoti Datta
Hi,

Thanks for the patch.
A few questions below.


On Thu, Jan 25, 2018 at 4:51 AM, Jolly Shah  wrote:
> This patch is adding communication layer with firmware.
> Firmware driver provides an interface to firmware APIs.
> Interface APIs can be used by any driver to communicate to
> PMUFW(Platform Management Unit). All requests go through ATF.
>
> Signed-off-by: Jolly Shah 
> Signed-off-by: Rajan Vaja 
> ---

>

> +/**
> + * zynqmp_pm_clock_enable - Enable the clock for given id
> + * @clock_id:  ID of the clock to be enabled

Does it enable all the parents also if they are disabled?

> + *
> + * This function is used by master to enable the clock
> + * including peripherals and PLL clocks.
> + *
> + * Return: Returns status, either success or error+reason.
> + */
> +static int zynqmp_pm_clock_enable(u32 clock_id)
> +{
> +   return invoke_pm_fn(PM_CLOCK_ENABLE, clock_id, 0, 0, 0, NULL);
> +}
> +
> +/**
> + * zynqmp_pm_clock_disable - Disable the clock for given id
> + * @clock_id:  ID of the clock to be disable
> + *
> + * This function is used by master to disable the clock
> + * including peripherals and PLL clocks.
> + *
> + * Return: Returns status, either success or error+reason.
> + */
> +static int zynqmp_pm_clock_disable(u32 clock_id)
> +{
> +   return invoke_pm_fn(PM_CLOCK_DISABLE, clock_id, 0, 0, 0, NULL);
> +}
> +
> +/**
> + * zynqmp_pm_clock_getstate - Get the clock state for given id
> + * @clock_id:  ID of the clock to be queried
> + * @state: 1/0 (Enabled/Disabled)
> + *
> + * This function is used by master to get the state of clock
> + * including peripherals and PLL clocks.
> + *
> + * Return: Returns status, either success or error+reason.
> + */
> +static int zynqmp_pm_clock_getstate(u32 clock_id, u32 *state)
> +{
> +   u32 ret_payload[PAYLOAD_ARG_CNT];
> +   int ret;
> +
> +   ret = invoke_pm_fn(PM_CLOCK_GETSTATE, clock_id, 0, 0, 0, ret_payload);
> +   *state = ret_payload[1];
> +
> +   return ret;
> +}
> +
> +/**
> + * zynqmp_pm_clock_setdivider - Set the clock divider for given id
> + * @clock_id:  ID of the clock
> + * @div_type:  TYPE_DIV1: div1
> + * TYPE_DIV2: div2
div type didnt see in the signature.



> + * @divider:   divider value.
> + *
> + * This function is used by master to set divider for any clock
> + * to achieve desired rate.
> + *
> + * Return: Returns status, either success or error+reason.
> + */
> +static int zynqmp_pm_clock_setdivider(u32 clock_id, u32 divider)
> +{
> +   return invoke_pm_fn(PM_CLOCK_SETDIVIDER, clock_id, divider, 0, 0, 
> NULL);
> +}
> +
> +/**
> + * zynqmp_pm_clock_getdivider - Get the clock divider for given id
> + * @clock_id:  ID of the clock
> + * @div_type:  TYPE_DIV1: div1
> + * TYPE_DIV2: div2
didnt see this  below.

> + * @divider:   divider value.
> + *
> + * This function is used by master to get divider values
> + * for any clock.
> + *
> + * Return: Returns status, either success or error+reason.
> + */
> +static int zynqmp_pm_clock_getdivider(u32 clock_id, u32 *divider)
> +{
> +   u32 ret_payload[PAYLOAD_ARG_CNT];
> +   int ret;
> +
> +   ret = invoke_pm_fn(PM_CLOCK_GETDIVIDER, clock_id, 0, 0, 0, 
> ret_payload);
> +   *divider = ret_payload[1];
> +
> +   return ret;
> +}
> +
> +/**
> + * zynqmp_pm_clock_setrate - Set the clock rate for given id
> + * @clock_id:  ID of the clock
> + * @rate:  rate value in hz
> + *
> + * This function is used by master to set rate for any clock.
> + *
> + * Return: Returns status, either success or error+reason.
> + */
So this can set rate only 4G max ?

> +static int zynqmp_pm_clock_setrate(u32 clock_id, u32 rate)
> +{
> +   return invoke_pm_fn(PM_CLOCK_SETRATE, clock_id, rate, 0, 0, NULL);
> +}
> +
> +/**
> + * zynqmp_pm_clock_getrate - Get the clock rate for given id
> + * @clock_id:  ID of the clock
> + * @rate:  rate value in hz
> + *
> + * This function is used by master to get rate
> + * for any clock.
> + *
> + * Return: Returns status, either success or error+reason.
> + */
Same question here?

> +static int zynqmp_pm_clock_getrate(u32 clock_id, u32 *rate)
> +{
> +   u32 ret_payload[PAYLOAD_ARG_CNT];
> +   int ret;
> +
> +   ret = invoke_pm_fn(PM_CLOCK_GETRATE, clock_id, 0, 0, 0, ret_payload);
> +   *rate = ret_payload[1];
> +
> +   return ret;
> +}
> +
Also  what is the difference between set rate and set divider?


Re: [PATCH v3 2/4] drivers: firmware: xilinx: Add ZynqMP firmware driver

2018-01-29 Thread Shubhrajyoti Datta
Hi,

Thanks for the patch.
A few questions below.


On Thu, Jan 25, 2018 at 4:51 AM, Jolly Shah  wrote:
> This patch is adding communication layer with firmware.
> Firmware driver provides an interface to firmware APIs.
> Interface APIs can be used by any driver to communicate to
> PMUFW(Platform Management Unit). All requests go through ATF.
>
> Signed-off-by: Jolly Shah 
> Signed-off-by: Rajan Vaja 
> ---

>

> +/**
> + * zynqmp_pm_clock_enable - Enable the clock for given id
> + * @clock_id:  ID of the clock to be enabled

Does it enable all the parents also if they are disabled?

> + *
> + * This function is used by master to enable the clock
> + * including peripherals and PLL clocks.
> + *
> + * Return: Returns status, either success or error+reason.
> + */
> +static int zynqmp_pm_clock_enable(u32 clock_id)
> +{
> +   return invoke_pm_fn(PM_CLOCK_ENABLE, clock_id, 0, 0, 0, NULL);
> +}
> +
> +/**
> + * zynqmp_pm_clock_disable - Disable the clock for given id
> + * @clock_id:  ID of the clock to be disable
> + *
> + * This function is used by master to disable the clock
> + * including peripherals and PLL clocks.
> + *
> + * Return: Returns status, either success or error+reason.
> + */
> +static int zynqmp_pm_clock_disable(u32 clock_id)
> +{
> +   return invoke_pm_fn(PM_CLOCK_DISABLE, clock_id, 0, 0, 0, NULL);
> +}
> +
> +/**
> + * zynqmp_pm_clock_getstate - Get the clock state for given id
> + * @clock_id:  ID of the clock to be queried
> + * @state: 1/0 (Enabled/Disabled)
> + *
> + * This function is used by master to get the state of clock
> + * including peripherals and PLL clocks.
> + *
> + * Return: Returns status, either success or error+reason.
> + */
> +static int zynqmp_pm_clock_getstate(u32 clock_id, u32 *state)
> +{
> +   u32 ret_payload[PAYLOAD_ARG_CNT];
> +   int ret;
> +
> +   ret = invoke_pm_fn(PM_CLOCK_GETSTATE, clock_id, 0, 0, 0, ret_payload);
> +   *state = ret_payload[1];
> +
> +   return ret;
> +}
> +
> +/**
> + * zynqmp_pm_clock_setdivider - Set the clock divider for given id
> + * @clock_id:  ID of the clock
> + * @div_type:  TYPE_DIV1: div1
> + * TYPE_DIV2: div2
div type didnt see in the signature.



> + * @divider:   divider value.
> + *
> + * This function is used by master to set divider for any clock
> + * to achieve desired rate.
> + *
> + * Return: Returns status, either success or error+reason.
> + */
> +static int zynqmp_pm_clock_setdivider(u32 clock_id, u32 divider)
> +{
> +   return invoke_pm_fn(PM_CLOCK_SETDIVIDER, clock_id, divider, 0, 0, 
> NULL);
> +}
> +
> +/**
> + * zynqmp_pm_clock_getdivider - Get the clock divider for given id
> + * @clock_id:  ID of the clock
> + * @div_type:  TYPE_DIV1: div1
> + * TYPE_DIV2: div2
didnt see this  below.

> + * @divider:   divider value.
> + *
> + * This function is used by master to get divider values
> + * for any clock.
> + *
> + * Return: Returns status, either success or error+reason.
> + */
> +static int zynqmp_pm_clock_getdivider(u32 clock_id, u32 *divider)
> +{
> +   u32 ret_payload[PAYLOAD_ARG_CNT];
> +   int ret;
> +
> +   ret = invoke_pm_fn(PM_CLOCK_GETDIVIDER, clock_id, 0, 0, 0, 
> ret_payload);
> +   *divider = ret_payload[1];
> +
> +   return ret;
> +}
> +
> +/**
> + * zynqmp_pm_clock_setrate - Set the clock rate for given id
> + * @clock_id:  ID of the clock
> + * @rate:  rate value in hz
> + *
> + * This function is used by master to set rate for any clock.
> + *
> + * Return: Returns status, either success or error+reason.
> + */
So this can set rate only 4G max ?

> +static int zynqmp_pm_clock_setrate(u32 clock_id, u32 rate)
> +{
> +   return invoke_pm_fn(PM_CLOCK_SETRATE, clock_id, rate, 0, 0, NULL);
> +}
> +
> +/**
> + * zynqmp_pm_clock_getrate - Get the clock rate for given id
> + * @clock_id:  ID of the clock
> + * @rate:  rate value in hz
> + *
> + * This function is used by master to get rate
> + * for any clock.
> + *
> + * Return: Returns status, either success or error+reason.
> + */
Same question here?

> +static int zynqmp_pm_clock_getrate(u32 clock_id, u32 *rate)
> +{
> +   u32 ret_payload[PAYLOAD_ARG_CNT];
> +   int ret;
> +
> +   ret = invoke_pm_fn(PM_CLOCK_GETRATE, clock_id, 0, 0, 0, ret_payload);
> +   *rate = ret_payload[1];
> +
> +   return ret;
> +}
> +
Also  what is the difference between set rate and set divider?


[PATCHv2] tty: xilinx_uartps: move to arch_initcall for earlier console

2017-09-20 Thread Shubhrajyoti Datta
move to arch_initcall to get the console up really early, it is
quite helpful for spotting early boot problems.

Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.da...@xilinx.com>
---
 drivers/tty/serial/xilinx_uartps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c 
b/drivers/tty/serial/xilinx_uartps.c
index fde55dc..96fda91 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -1673,7 +1673,7 @@ static void __exit cdns_uart_exit(void)
uart_unregister_driver(_uart_uart_driver);
 }
 
-module_init(cdns_uart_init);
+arch_initcall(cdns_uart_init);
 module_exit(cdns_uart_exit);
 
 MODULE_DESCRIPTION("Driver for Cadence UART");
-- 
2.1.1



[PATCHv2] tty: xilinx_uartps: move to arch_initcall for earlier console

2017-09-20 Thread Shubhrajyoti Datta
move to arch_initcall to get the console up really early, it is
quite helpful for spotting early boot problems.

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/tty/serial/xilinx_uartps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c 
b/drivers/tty/serial/xilinx_uartps.c
index fde55dc..96fda91 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -1673,7 +1673,7 @@ static void __exit cdns_uart_exit(void)
uart_unregister_driver(_uart_uart_driver);
 }
 
-module_init(cdns_uart_init);
+arch_initcall(cdns_uart_init);
 module_exit(cdns_uart_exit);
 
 MODULE_DESCRIPTION("Driver for Cadence UART");
-- 
2.1.1



Re: [PATCH] tty: xilinx_uartps: move to arch_initcall for earlier console

2017-09-07 Thread Shubhrajyoti Datta
...
>>
>> I *guess* it is to get the console up really early, simply becaus it is
>> quite helpful for spotting early boot problems.
>
>
> ok. It means no concern about the move to arch_initcall.
> Shubhrajyoti: Please send v2 with changelog.

Will do thanks for the review.

>
> Thanks,
> Michal


Re: [PATCH] tty: xilinx_uartps: move to arch_initcall for earlier console

2017-09-07 Thread Shubhrajyoti Datta
...
>>
>> I *guess* it is to get the console up really early, simply becaus it is
>> quite helpful for spotting early boot problems.
>
>
> ok. It means no concern about the move to arch_initcall.
> Shubhrajyoti: Please send v2 with changelog.

Will do thanks for the review.

>
> Thanks,
> Michal


[PATCH] tty: xilinx_uartps: move to arch_initcall for earlier console

2017-08-23 Thread Shubhrajyoti Datta
Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.da...@xilinx.com>
---
 drivers/tty/serial/xilinx_uartps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c 
b/drivers/tty/serial/xilinx_uartps.c
index ff1b115..a239343 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -1647,7 +1647,7 @@ static void __exit cdns_uart_exit(void)
uart_unregister_driver(_uart_uart_driver);
 }
 
-module_init(cdns_uart_init);
+arch_initcall(cdns_uart_init);
 module_exit(cdns_uart_exit);
 
 MODULE_DESCRIPTION("Driver for Cadence UART");
-- 
2.1.1



[PATCH] tty: xilinx_uartps: move to arch_initcall for earlier console

2017-08-23 Thread Shubhrajyoti Datta
Signed-off-by: Shubhrajyoti Datta 
---
 drivers/tty/serial/xilinx_uartps.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/xilinx_uartps.c 
b/drivers/tty/serial/xilinx_uartps.c
index ff1b115..a239343 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -1647,7 +1647,7 @@ static void __exit cdns_uart_exit(void)
uart_unregister_driver(_uart_uart_driver);
 }
 
-module_init(cdns_uart_init);
+arch_initcall(cdns_uart_init);
 module_exit(cdns_uart_exit);
 
 MODULE_DESCRIPTION("Driver for Cadence UART");
-- 
2.1.1



Re: i2c: xiic: Strange clk_prepare_enable() in xiic_i2c_remove()

2016-12-16 Thread Shubhrajyoti Datta
On Sat, Dec 17, 2016 at 3:24 AM, Alexey Khoroshilov
<khoroshi...@ispras.ru> wrote:
> Dear Shubhrajyoti,
>
> Looking at 36ecbcab84d0 ("i2c: xiic: Implement power management")
> it is not clear why clk_prepare_enable(i2c->clk) is required in
> xiic_i2c_remove()?

834 ret = clk_prepare_enable(i2c->clk);
835 if (ret) {
836 dev_err(>dev, "Unable to enable clock.\n");
837 return ret;
838 }
839 xiic_deinit(i2c);
840 clk_disable_unprepare(i2c->clk);

so it is enabled and disabled after xiic_deinit.

>
> It is enabled in xiic_i2c_probe() and disabled/enabled in
> cdns_i2c_runtime_suspend()/cdns_i2c_runtime_resume().
>
> Could you please clarify the point.
>
> --
> Alexey Khoroshilov
> Linux Verification Center, ISPRAS
> web: http://linuxtesting.org
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: i2c: xiic: Strange clk_prepare_enable() in xiic_i2c_remove()

2016-12-16 Thread Shubhrajyoti Datta
On Sat, Dec 17, 2016 at 3:24 AM, Alexey Khoroshilov
 wrote:
> Dear Shubhrajyoti,
>
> Looking at 36ecbcab84d0 ("i2c: xiic: Implement power management")
> it is not clear why clk_prepare_enable(i2c->clk) is required in
> xiic_i2c_remove()?

834 ret = clk_prepare_enable(i2c->clk);
835 if (ret) {
836 dev_err(>dev, "Unable to enable clock.\n");
837 return ret;
838 }
839 xiic_deinit(i2c);
840 clk_disable_unprepare(i2c->clk);

so it is enabled and disabled after xiic_deinit.

>
> It is enabled in xiic_i2c_probe() and disabled/enabled in
> cdns_i2c_runtime_suspend()/cdns_i2c_runtime_resume().
>
> Could you please clarify the point.
>
> --
> Alexey Khoroshilov
> Linux Verification Center, ISPRAS
> web: http://linuxtesting.org
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Re: Reset implementation for Zynq

2016-11-08 Thread Shubhrajyoti Datta
Hi Iztok,



On Tue, Nov 8, 2016 at 3:10 PM,  <iztok.je...@redpitaya.com> wrote:
> Hi Shubhrajyoti,
>
> By lockup state, I mean an undefined/unhandled state of the HW logic state
> machine,
> or something similar in the software driver.
> Based on symptoms I assume it is a HW lockup.
> In practice asking the driver for a new I2C transfer would result in
> nothing happening on the I2C bus (signals remain in hi-Z state).
> Driver or userspace tool reports a transfer error, but I did not copy it.
> And I did not check the state of the driver.
>
> To enter this mode it was enough to connect an oscilloscope probe to the SDA
> signal.
> The capacitance of the probe causes a deep voltage fall, which is quickly
> corrected by the pullup.
> I did not time the glitch, and the shape was partially defined by an I2C
> level shifter.
> The issue can be repeated with about 80% probability.
>
> There are two ways to get back to a working state:
> 1. create a longer zero pulse (about 50ms manual grounding) on SDA
> 2. reset the HW, this was done with a patched driver.
Thanks  for the explaination.
May be recovery mechanism  implementation could be considered.


>
> Regards,
> Iztok Jeras
>
>


Re: Re: Reset implementation for Zynq

2016-11-08 Thread Shubhrajyoti Datta
Hi Iztok,



On Tue, Nov 8, 2016 at 3:10 PM,   wrote:
> Hi Shubhrajyoti,
>
> By lockup state, I mean an undefined/unhandled state of the HW logic state
> machine,
> or something similar in the software driver.
> Based on symptoms I assume it is a HW lockup.
> In practice asking the driver for a new I2C transfer would result in
> nothing happening on the I2C bus (signals remain in hi-Z state).
> Driver or userspace tool reports a transfer error, but I did not copy it.
> And I did not check the state of the driver.
>
> To enter this mode it was enough to connect an oscilloscope probe to the SDA
> signal.
> The capacitance of the probe causes a deep voltage fall, which is quickly
> corrected by the pullup.
> I did not time the glitch, and the shape was partially defined by an I2C
> level shifter.
> The issue can be repeated with about 80% probability.
>
> There are two ways to get back to a working state:
> 1. create a longer zero pulse (about 50ms manual grounding) on SDA
> 2. reset the HW, this was done with a patched driver.
Thanks  for the explaination.
May be recovery mechanism  implementation could be considered.


>
> Regards,
> Iztok Jeras
>
>


Re: Reset implementation for Zynq

2016-11-07 Thread Shubhrajyoti Datta
On Fri, Oct 21, 2016 at 10:34 PM, Moritz Fischer
 wrote:
> Iztok,
>
> On Fri, Oct 21, 2016 at 03:08:47AM -0700, iztok.je...@redpitaya.com wrote:
>> Hi Moritz,
>>
>> I was looking at your reset implementation for Zynq:
>> https://github.com/Xilinx/linux-xlnx/blob/629041605b93343ad2e8971ceaac3edcef0b043b/drivers/reset/reset-zynq.c
>> I went through related mailing list posts (including earlier versions of the 
>> patch) so I kind of understand what to change in the device tree.
>
> Please look at the upstream kernel sources and use the mailing list
> (lkml) if you want to report bugs. Xilinx' vendor tree might or might
> not be up to date.
>
>> I would like to use this driver to reset the Zynq I2C controller, since we 
>> have trouble with it getting into a lock up state.

Can you explain what you are facing and what is meant by lockup state.


Re: Reset implementation for Zynq

2016-11-07 Thread Shubhrajyoti Datta
On Fri, Oct 21, 2016 at 10:34 PM, Moritz Fischer
 wrote:
> Iztok,
>
> On Fri, Oct 21, 2016 at 03:08:47AM -0700, iztok.je...@redpitaya.com wrote:
>> Hi Moritz,
>>
>> I was looking at your reset implementation for Zynq:
>> https://github.com/Xilinx/linux-xlnx/blob/629041605b93343ad2e8971ceaac3edcef0b043b/drivers/reset/reset-zynq.c
>> I went through related mailing list posts (including earlier versions of the 
>> patch) so I kind of understand what to change in the device tree.
>
> Please look at the upstream kernel sources and use the mailing list
> (lkml) if you want to report bugs. Xilinx' vendor tree might or might
> not be up to date.
>
>> I would like to use this driver to reset the Zynq I2C controller, since we 
>> have trouble with it getting into a lock up state.

Can you explain what you are facing and what is meant by lockup state.


Re: [PATCH] gpio: Added zynq specific check for special pins on bank zero

2016-09-21 Thread Shubhrajyoti Datta
On Tue, Sep 20, 2016 at 2:02 PM, Nava kishore Manne
 wrote:
> From: Nava kishore Manne 
>
> This patch adds zynq specific check for bank 0 pins 7 and 8
> are special and cannot be used as inputs

Is there any such pins for zynqmp?

>
> Signed-off-by: Nava kishore Manne 
> ---
>  drivers/gpio/gpio-zynq.c | 17 +++--
>  1 file changed, 15 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c
> index e72794e..eae9d24 100644
> --- a/drivers/gpio/gpio-zynq.c
> +++ b/drivers/gpio/gpio-zynq.c
> @@ -96,6 +96,10 @@
>  /* GPIO upper 16 bit mask */
>  #define ZYNQ_GPIO_UPPER_MASK 0x
>
> +/* For GPIO quirks */
> +#define ZYNQ_GPIO  BIT(0)
> +#define ZYNQMP_GPIOBIT(1)

if not can we remove ZYNQMP_GPIO?


Re: [PATCH] gpio: Added zynq specific check for special pins on bank zero

2016-09-21 Thread Shubhrajyoti Datta
On Tue, Sep 20, 2016 at 2:02 PM, Nava kishore Manne
 wrote:
> From: Nava kishore Manne 
>
> This patch adds zynq specific check for bank 0 pins 7 and 8
> are special and cannot be used as inputs

Is there any such pins for zynqmp?

>
> Signed-off-by: Nava kishore Manne 
> ---
>  drivers/gpio/gpio-zynq.c | 17 +++--
>  1 file changed, 15 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c
> index e72794e..eae9d24 100644
> --- a/drivers/gpio/gpio-zynq.c
> +++ b/drivers/gpio/gpio-zynq.c
> @@ -96,6 +96,10 @@
>  /* GPIO upper 16 bit mask */
>  #define ZYNQ_GPIO_UPPER_MASK 0x
>
> +/* For GPIO quirks */
> +#define ZYNQ_GPIO  BIT(0)
> +#define ZYNQMP_GPIOBIT(1)

if not can we remove ZYNQMP_GPIO?


Re: [PATCH v4] Axi-usb: Add support for 64-bit addressing.

2016-06-03 Thread Shubhrajyoti Datta
On Tue, May 31, 2016 at 10:45 AM, Nava kishore Manne
<nava.ma...@xilinx.com> wrote:
> Hi Shubhrajyoti,
>
>
> Thanks for the review...
>
>> >  /**
>> > + * xudc_write64 - write 64bit value to device registers
>> > + * @ep: pointer to the usb device endpoint structure.
>> > + * @offset: register offset
>> > + * @val: data to be written
>> > + **/
>> > +static void xudc_write64(struct xusb_ep *ep, u32 offset, u64 val) {
>> > +   struct xusb_udc *udc = ep->udc;
>> > +
>> > +   udc->write_fn(udc->addr, offset, lower_32_bits(val));
>> > +   udc->write_fn(udc->addr, offset+0x04, upper_32_bits(val));
>>
>> can we move this to a single 64 bit write?
>
> Initially I sent the patches with writeq() ,lo_hi_writeq()  later we decided 
> to replace with write_fun().
> The reason for this is lo_hi_writeq() always assumes a little-endian 
> register, so it's broken if anyone builds this device with big-endian 
> registers.
> So replaced the 64bit calls with write_fun() as suggested by Arnd Bergmann. 
> Hope it clears your query.
> Please refer to the below thread
>
> http://lkml.iu.edu/hypermail/linux/kernel/1604.2/02046.html

missed that discurssion.

thanks
>
>
> Regards,
> Navakishore.
>


Re: [PATCH v4] Axi-usb: Add support for 64-bit addressing.

2016-06-03 Thread Shubhrajyoti Datta
On Tue, May 31, 2016 at 10:45 AM, Nava kishore Manne
 wrote:
> Hi Shubhrajyoti,
>
>
> Thanks for the review...
>
>> >  /**
>> > + * xudc_write64 - write 64bit value to device registers
>> > + * @ep: pointer to the usb device endpoint structure.
>> > + * @offset: register offset
>> > + * @val: data to be written
>> > + **/
>> > +static void xudc_write64(struct xusb_ep *ep, u32 offset, u64 val) {
>> > +   struct xusb_udc *udc = ep->udc;
>> > +
>> > +   udc->write_fn(udc->addr, offset, lower_32_bits(val));
>> > +   udc->write_fn(udc->addr, offset+0x04, upper_32_bits(val));
>>
>> can we move this to a single 64 bit write?
>
> Initially I sent the patches with writeq() ,lo_hi_writeq()  later we decided 
> to replace with write_fun().
> The reason for this is lo_hi_writeq() always assumes a little-endian 
> register, so it's broken if anyone builds this device with big-endian 
> registers.
> So replaced the 64bit calls with write_fun() as suggested by Arnd Bergmann. 
> Hope it clears your query.
> Please refer to the below thread
>
> http://lkml.iu.edu/hypermail/linux/kernel/1604.2/02046.html

missed that discurssion.

thanks
>
>
> Regards,
> Navakishore.
>


Re: [PATCH v4] Axi-usb: Add support for 64-bit addressing.

2016-05-30 Thread Shubhrajyoti Datta
On Mon, May 30, 2016 at 10:16 PM, Nava kishore Manne
 wrote:
> This patch updates the driver to support 64-bit DMA addressing.
>
> Signed-off-by: Nava kishore Manne 
> ---
> Changes for v4:
> -Used boolen property insted of addrwith property in the DT
>  as suggested by Arnd Bergmann.
> -Adopt the DT relevant changes into the driver.
>
> Changes for v3:
> -Added new compatable string for 5.00 IP version as suggested 
> by
>  Arnd Bergmann.
> -Used write_fn() insted of lo_hi_writeq() as suggested by
>  Arnd Bergmann.
>
> Changes for v2:
> -Added dma-ranges property in device tree as suggested by 
> Arnd Bergmann.
> -Modified the driver code based on the xlnx,addrwidth.
>
>  .../devicetree/bindings/usb/udc-xilinx.txt |  5 ++-
>  drivers/usb/gadget/udc/udc-xilinx.c| 52 
> +-
>  2 files changed, 54 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/usb/udc-xilinx.txt 
> b/Documentation/devicetree/bindings/usb/udc-xilinx.txt
> index 47b4e39..d08d972 100644
> --- a/Documentation/devicetree/bindings/usb/udc-xilinx.txt
> +++ b/Documentation/devicetree/bindings/usb/udc-xilinx.txt
> @@ -1,12 +1,14 @@
>  Xilinx USB2 device controller
>
>  Required properties:
> -- compatible   : Should be "xlnx,usb2-device-4.00.a"
> +- compatible   : Should be "xlnx,usb2-device-4.00.a" or
> + "xlnx,usb2-device-5.00"
>  - reg  : Physical base address and size of the USB2
>   device registers map.
>  - interrupts   : Should contain single irq line of USB2 device
>   controller
>  - xlnx,has-builtin-dma : if DMA is included
> +- xlnx,has-64bit-dma   : if DMA is included 64-bit addressing support.
>
>  Example:
> axi-usb2-device@42e0 {
> @@ -14,5 +16,6 @@ Example:
>  interrupts = <0x0 0x39 0x1>;
>  reg = <0x42e0 0x1>;
>  xlnx,has-builtin-dma;
> +   xlnx,has-64bit-dma;
>  };
>
> diff --git a/drivers/usb/gadget/udc/udc-xilinx.c 
> b/drivers/usb/gadget/udc/udc-xilinx.c
> index 1cbb0ac..6fb80c6 100644
> --- a/drivers/usb/gadget/udc/udc-xilinx.c
> +++ b/drivers/usb/gadget/udc/udc-xilinx.c
> @@ -47,6 +47,15 @@
>  #define XUSB_DMA_LENGTH_OFFSET 0x0210  /* DMA Length Register */
>  #define XUSB_DMA_STATUS_OFFSET 0x0214  /* DMA Status Register */
>
> +/* DMA source Address Reg for LSB */
> +#define XUSB_DMA_DSAR_ADDR_OFFSET_LSB   0x0308
> +/* DMA source Address Reg for MSB */
> +#define XUSB_DMA_DSAR_ADDR_OFFSET_MSB   0x030C
> +/* DMA destination Addr Reg LSB */
> +#define XUSB_DMA_DDAR_ADDR_OFFSET_LSB   0x0310
> +/* DMA destination Addr Reg MSB */
> +#define XUSB_DMA_DDAR_ADDR_OFFSET_MSB   0x0314
> +
>  /* Endpoint Configuration Space offsets */
>  #define XUSB_EP_CFGSTATUS_OFFSET   0x00/* Endpoint Config Status  */
>  #define XUSB_EP_BUF0COUNT_OFFSET   0x08/* Buffer 0 Count */
> @@ -169,6 +178,7 @@ struct xusb_ep {
>   * @setup: usb_ctrlrequest structure for control requests
>   * @req: pointer to dummy request for get status command
>   * @dev: pointer to device structure in gadget
> + * @is_extend_dma: flag indiacting whether the dma is 64-bit support or not.
>   * @usb_state: device in suspended state or not
>   * @remote_wkp: remote wakeup enabled by host
>   * @setupseqtx: tx status
> @@ -186,6 +196,7 @@ struct xusb_udc {
> struct usb_ctrlrequest setup;
> struct xusb_req *req;
> struct device *dev;
> +   bool is_extend_dma;
> u32 usb_state;
> u32 remote_wkp;
> u32 setupseqtx;
> @@ -215,6 +226,20 @@ static const struct usb_endpoint_descriptor 
> config_bulk_out_desc = {
>  };
>
>  /**
> + * xudc_write64 - write 64bit value to device registers
> + * @ep: pointer to the usb device endpoint structure.
> + * @offset: register offset
> + * @val: data to be written
> + **/
> +static void xudc_write64(struct xusb_ep *ep, u32 offset, u64 val)
> +{
> +   struct xusb_udc *udc = ep->udc;
> +
> +   udc->write_fn(udc->addr, offset, lower_32_bits(val));
> +   udc->write_fn(udc->addr, offset+0x04, upper_32_bits(val));

can we move this to a single 64 bit write?
> +}
> +
> +/**


Re: [PATCH v4] Axi-usb: Add support for 64-bit addressing.

2016-05-30 Thread Shubhrajyoti Datta
On Mon, May 30, 2016 at 10:16 PM, Nava kishore Manne
 wrote:
> This patch updates the driver to support 64-bit DMA addressing.
>
> Signed-off-by: Nava kishore Manne 
> ---
> Changes for v4:
> -Used boolen property insted of addrwith property in the DT
>  as suggested by Arnd Bergmann.
> -Adopt the DT relevant changes into the driver.
>
> Changes for v3:
> -Added new compatable string for 5.00 IP version as suggested 
> by
>  Arnd Bergmann.
> -Used write_fn() insted of lo_hi_writeq() as suggested by
>  Arnd Bergmann.
>
> Changes for v2:
> -Added dma-ranges property in device tree as suggested by 
> Arnd Bergmann.
> -Modified the driver code based on the xlnx,addrwidth.
>
>  .../devicetree/bindings/usb/udc-xilinx.txt |  5 ++-
>  drivers/usb/gadget/udc/udc-xilinx.c| 52 
> +-
>  2 files changed, 54 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/usb/udc-xilinx.txt 
> b/Documentation/devicetree/bindings/usb/udc-xilinx.txt
> index 47b4e39..d08d972 100644
> --- a/Documentation/devicetree/bindings/usb/udc-xilinx.txt
> +++ b/Documentation/devicetree/bindings/usb/udc-xilinx.txt
> @@ -1,12 +1,14 @@
>  Xilinx USB2 device controller
>
>  Required properties:
> -- compatible   : Should be "xlnx,usb2-device-4.00.a"
> +- compatible   : Should be "xlnx,usb2-device-4.00.a" or
> + "xlnx,usb2-device-5.00"
>  - reg  : Physical base address and size of the USB2
>   device registers map.
>  - interrupts   : Should contain single irq line of USB2 device
>   controller
>  - xlnx,has-builtin-dma : if DMA is included
> +- xlnx,has-64bit-dma   : if DMA is included 64-bit addressing support.
>
>  Example:
> axi-usb2-device@42e0 {
> @@ -14,5 +16,6 @@ Example:
>  interrupts = <0x0 0x39 0x1>;
>  reg = <0x42e0 0x1>;
>  xlnx,has-builtin-dma;
> +   xlnx,has-64bit-dma;
>  };
>
> diff --git a/drivers/usb/gadget/udc/udc-xilinx.c 
> b/drivers/usb/gadget/udc/udc-xilinx.c
> index 1cbb0ac..6fb80c6 100644
> --- a/drivers/usb/gadget/udc/udc-xilinx.c
> +++ b/drivers/usb/gadget/udc/udc-xilinx.c
> @@ -47,6 +47,15 @@
>  #define XUSB_DMA_LENGTH_OFFSET 0x0210  /* DMA Length Register */
>  #define XUSB_DMA_STATUS_OFFSET 0x0214  /* DMA Status Register */
>
> +/* DMA source Address Reg for LSB */
> +#define XUSB_DMA_DSAR_ADDR_OFFSET_LSB   0x0308
> +/* DMA source Address Reg for MSB */
> +#define XUSB_DMA_DSAR_ADDR_OFFSET_MSB   0x030C
> +/* DMA destination Addr Reg LSB */
> +#define XUSB_DMA_DDAR_ADDR_OFFSET_LSB   0x0310
> +/* DMA destination Addr Reg MSB */
> +#define XUSB_DMA_DDAR_ADDR_OFFSET_MSB   0x0314
> +
>  /* Endpoint Configuration Space offsets */
>  #define XUSB_EP_CFGSTATUS_OFFSET   0x00/* Endpoint Config Status  */
>  #define XUSB_EP_BUF0COUNT_OFFSET   0x08/* Buffer 0 Count */
> @@ -169,6 +178,7 @@ struct xusb_ep {
>   * @setup: usb_ctrlrequest structure for control requests
>   * @req: pointer to dummy request for get status command
>   * @dev: pointer to device structure in gadget
> + * @is_extend_dma: flag indiacting whether the dma is 64-bit support or not.
>   * @usb_state: device in suspended state or not
>   * @remote_wkp: remote wakeup enabled by host
>   * @setupseqtx: tx status
> @@ -186,6 +196,7 @@ struct xusb_udc {
> struct usb_ctrlrequest setup;
> struct xusb_req *req;
> struct device *dev;
> +   bool is_extend_dma;
> u32 usb_state;
> u32 remote_wkp;
> u32 setupseqtx;
> @@ -215,6 +226,20 @@ static const struct usb_endpoint_descriptor 
> config_bulk_out_desc = {
>  };
>
>  /**
> + * xudc_write64 - write 64bit value to device registers
> + * @ep: pointer to the usb device endpoint structure.
> + * @offset: register offset
> + * @val: data to be written
> + **/
> +static void xudc_write64(struct xusb_ep *ep, u32 offset, u64 val)
> +{
> +   struct xusb_udc *udc = ep->udc;
> +
> +   udc->write_fn(udc->addr, offset, lower_32_bits(val));
> +   udc->write_fn(udc->addr, offset+0x04, upper_32_bits(val));

can we move this to a single 64 bit write?
> +}
> +
> +/**


Re: [PATCH v9 2/2] dmaengine: Add Xilinx zynqmp dma engine driver support

2016-05-30 Thread Shubhrajyoti Datta
> + */
> +static void zynqmp_dma_update_desc_to_ctrlr(struct zynqmp_dma_chan *chan,
> + struct zynqmp_dma_desc_sw *desc)
> +{
> +   dma_addr_t addr;
> +
> +   addr = desc->src_p;
> +   writel(addr, chan->regs + ZYNQMP_DMA_SRC_START_LSB);
> +   writel(upper_32_bits(addr), chan->regs + ZYNQMP_DMA_SRC_START_MSB);
Can we combine the two writes to a 64bit write.
It may be helpful on 64-bit systems.


> +   addr = desc->dst_p;
> +   writel(addr, chan->regs + ZYNQMP_DMA_DST_START_LSB);
> +   writel(upper_32_bits(addr), chan->regs + ZYNQMP_DMA_DST_START_MSB);
> +}


Re: [PATCH v9 2/2] dmaengine: Add Xilinx zynqmp dma engine driver support

2016-05-30 Thread Shubhrajyoti Datta
> + */
> +static void zynqmp_dma_update_desc_to_ctrlr(struct zynqmp_dma_chan *chan,
> + struct zynqmp_dma_desc_sw *desc)
> +{
> +   dma_addr_t addr;
> +
> +   addr = desc->src_p;
> +   writel(addr, chan->regs + ZYNQMP_DMA_SRC_START_LSB);
> +   writel(upper_32_bits(addr), chan->regs + ZYNQMP_DMA_SRC_START_MSB);
Can we combine the two writes to a 64bit write.
It may be helpful on 64-bit systems.


> +   addr = desc->dst_p;
> +   writel(addr, chan->regs + ZYNQMP_DMA_DST_START_LSB);
> +   writel(upper_32_bits(addr), chan->regs + ZYNQMP_DMA_DST_START_MSB);
> +}


[PATCH] spi: zynqmp: disable clocks in error paths

2016-05-04 Thread Shubhrajyoti Datta
The if pclk enable fails the refclk is not disabled.
Fix the same.

Signed-off-by: Shubhrajyoti Datta <shubh...@xilinx.com>
---
 drivers/spi/spi-zynqmp-gqspi.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/spi/spi-zynqmp-gqspi.c b/drivers/spi/spi-zynqmp-gqspi.c
index aab9b49..18aeace 100644
--- a/drivers/spi/spi-zynqmp-gqspi.c
+++ b/drivers/spi/spi-zynqmp-gqspi.c
@@ -360,7 +360,7 @@ static int zynqmp_prepare_transfer_hardware(struct 
spi_master *master)
 
ret = clk_enable(xqspi->refclk);
if (ret)
-   goto clk_err;
+   return ret;
 
ret = clk_enable(xqspi->pclk);
if (ret)
@@ -369,6 +369,7 @@ static int zynqmp_prepare_transfer_hardware(struct 
spi_master *master)
zynqmp_gqspi_write(xqspi, GQSPI_EN_OFST, GQSPI_EN_MASK);
return 0;
 clk_err:
+   clk_disable(xqspi->refclk);
return ret;
 }
 
-- 
1.7.1



[PATCH] spi: zynqmp: disable clocks in error paths

2016-05-04 Thread Shubhrajyoti Datta
The if pclk enable fails the refclk is not disabled.
Fix the same.

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/spi/spi-zynqmp-gqspi.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/spi/spi-zynqmp-gqspi.c b/drivers/spi/spi-zynqmp-gqspi.c
index aab9b49..18aeace 100644
--- a/drivers/spi/spi-zynqmp-gqspi.c
+++ b/drivers/spi/spi-zynqmp-gqspi.c
@@ -360,7 +360,7 @@ static int zynqmp_prepare_transfer_hardware(struct 
spi_master *master)
 
ret = clk_enable(xqspi->refclk);
if (ret)
-   goto clk_err;
+   return ret;
 
ret = clk_enable(xqspi->pclk);
if (ret)
@@ -369,6 +369,7 @@ static int zynqmp_prepare_transfer_hardware(struct 
spi_master *master)
zynqmp_gqspi_write(xqspi, GQSPI_EN_OFST, GQSPI_EN_MASK);
return 0;
 clk_err:
+   clk_disable(xqspi->refclk);
return ret;
 }
 
-- 
1.7.1



Re: [PATCH v2 2/2] dmaengine: vdma: Add clock support

2016-04-20 Thread Shubhrajyoti Datta
On Wed, Apr 20, 2016 at 5:13 PM, Kedareswara rao Appana
<appana.durga@xilinx.com> wrote:
> Added basic clock support. The clocks are requested at probe
> and released at remove.
>
> Signed-off-by: Kedareswara rao Appana <appa...@xilinx.com>


Reviewed-by: Shubhrajyoti Datta  <shubh...@xilinx.com>


Re: [PATCH v2 2/2] dmaengine: vdma: Add clock support

2016-04-20 Thread Shubhrajyoti Datta
On Wed, Apr 20, 2016 at 5:13 PM, Kedareswara rao Appana
 wrote:
> Added basic clock support. The clocks are requested at probe
> and released at remove.
>
> Signed-off-by: Kedareswara rao Appana 


Reviewed-by: Shubhrajyoti Datta  


Re: [PATCH 1/2] Documentation: DT: vdma: Add clock support for vdma

2016-04-20 Thread Shubhrajyoti Datta
On Wed, Apr 20, 2016 at 12:49 PM, Kedareswara rao Appana
 wrote:
> This patch updates the binding doc with clock description
> for vdma.
>
> Signed-off-by: Kedareswara rao Appana 
> ---
>  Documentation/devicetree/bindings/dma/xilinx/xilinx_vdma.txt | 6 ++
>  1 file changed, 6 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/dma/xilinx/xilinx_vdma.txt 
> b/Documentation/devicetree/bindings/dma/xilinx/xilinx_vdma.txt
> index fcc2b65..e1c9019 100644
> --- a/Documentation/devicetree/bindings/dma/xilinx/xilinx_vdma.txt
> +++ b/Documentation/devicetree/bindings/dma/xilinx/xilinx_vdma.txt
> @@ -21,6 +21,10 @@ Required properties:
>  - dma-channel child node: Should have at least one channel and can have up to
> two channels per device. This node specifies the properties of each
> DMA channel (see child node properties below).
> +- clocks: Input clock specifier. Refer to common clock bindings.
> +- clock-names: List of input clocks "axi_clk", "tx_clk", "txs_clk" (list of 
> input
> +  cloks may vary based on the ip configuration. see clock 
> bindings
> +  for more info).
>
>  Required properties for VDMA:
>  - xlnx,num-fstores: Should be the number of framebuffers as configured in 
> h/w.
> @@ -60,6 +64,8 @@ axi_vdma_0: axivdma@4003 {
> xlnx,num-fstores = <0x8>;
> xlnx,flush-fsync = <0x1>;
> xlnx,addrwidth = <0x20>;
> +   clocks = < 0>, < 1>, < 2>;
> +   clock-names = "axi_clk", "tx_clk", "txs_clk";

the module has
s_axi_lite_aclk Clock I AXI VDMA AXI4-Lite interface clock
 m_axi_mm2s_aclk Clock I AXI VDMA MM2S clock
 m_axi_s2mm_aclk Clock I AXI VDMA S2MM clock
 m_axis_mm2s_aclk Clock I AXI VDMA MM2S AXIS clock
 s_axis_s2mm_aclk Clock I AXI VDMA S2MM AXIS clock

I think a partial support is not wrong.
however  we should keep the names same as the TRM.


> dma-channel@4003 {
> compatible = "xlnx,axi-vdma-mm2s-channel";
> interrupts = < 0 54 4 >;
> --
> 2.1.2
>
>
> ___
> linux-arm-kernel mailing list
> linux-arm-ker...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


Re: [PATCH 1/2] Documentation: DT: vdma: Add clock support for vdma

2016-04-20 Thread Shubhrajyoti Datta
On Wed, Apr 20, 2016 at 12:49 PM, Kedareswara rao Appana
 wrote:
> This patch updates the binding doc with clock description
> for vdma.
>
> Signed-off-by: Kedareswara rao Appana 
> ---
>  Documentation/devicetree/bindings/dma/xilinx/xilinx_vdma.txt | 6 ++
>  1 file changed, 6 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/dma/xilinx/xilinx_vdma.txt 
> b/Documentation/devicetree/bindings/dma/xilinx/xilinx_vdma.txt
> index fcc2b65..e1c9019 100644
> --- a/Documentation/devicetree/bindings/dma/xilinx/xilinx_vdma.txt
> +++ b/Documentation/devicetree/bindings/dma/xilinx/xilinx_vdma.txt
> @@ -21,6 +21,10 @@ Required properties:
>  - dma-channel child node: Should have at least one channel and can have up to
> two channels per device. This node specifies the properties of each
> DMA channel (see child node properties below).
> +- clocks: Input clock specifier. Refer to common clock bindings.
> +- clock-names: List of input clocks "axi_clk", "tx_clk", "txs_clk" (list of 
> input
> +  cloks may vary based on the ip configuration. see clock 
> bindings
> +  for more info).
>
>  Required properties for VDMA:
>  - xlnx,num-fstores: Should be the number of framebuffers as configured in 
> h/w.
> @@ -60,6 +64,8 @@ axi_vdma_0: axivdma@4003 {
> xlnx,num-fstores = <0x8>;
> xlnx,flush-fsync = <0x1>;
> xlnx,addrwidth = <0x20>;
> +   clocks = < 0>, < 1>, < 2>;
> +   clock-names = "axi_clk", "tx_clk", "txs_clk";

the module has
s_axi_lite_aclk Clock I AXI VDMA AXI4-Lite interface clock
 m_axi_mm2s_aclk Clock I AXI VDMA MM2S clock
 m_axi_s2mm_aclk Clock I AXI VDMA S2MM clock
 m_axis_mm2s_aclk Clock I AXI VDMA MM2S AXIS clock
 s_axis_s2mm_aclk Clock I AXI VDMA S2MM AXIS clock

I think a partial support is not wrong.
however  we should keep the names same as the TRM.


> dma-channel@4003 {
> compatible = "xlnx,axi-vdma-mm2s-channel";
> interrupts = < 0 54 4 >;
> --
> 2.1.2
>
>
> ___
> linux-arm-kernel mailing list
> linux-arm-ker...@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


Re: [PATCH] spi: cadence: mark pm functions __maybe_unused

2016-04-17 Thread Shubhrajyoti Datta
On Sun, Apr 17, 2016 at 2:09 AM, Arnd Bergmann <a...@arndb.de> wrote:
> The newly added runtime PM support for the cadence spi driver
> causes harmless warnings when PM is disabled:
>
> drivers/spi/spi-cadence.c:681:12: warning: 'cnds_runtime_suspend' defined but 
> not used
> drivers/spi/spi-cadence.c:652:12: warning: 'cnds_runtime_resume' defined but 
> not used
>
> This adds __maybe_unused annotations to the respective functions
> to shut up the warnings, while leaving the code in place for
> compile testing and avoiding ugly #ifdefs.

Thanks for the patch.
Feel free to add my ack.
Acked-by: Shubhrajyoti Datta <shubh...@xilinx.com>

>
> Signed-off-by: Arnd Bergmann <a...@arndb.de>
> Fixes: d36ccd9f7ea4 ("spi: cadence: Runtime pm adaptation")
> ---


Re: [PATCH] spi: cadence: mark pm functions __maybe_unused

2016-04-17 Thread Shubhrajyoti Datta
On Sun, Apr 17, 2016 at 2:09 AM, Arnd Bergmann  wrote:
> The newly added runtime PM support for the cadence spi driver
> causes harmless warnings when PM is disabled:
>
> drivers/spi/spi-cadence.c:681:12: warning: 'cnds_runtime_suspend' defined but 
> not used
> drivers/spi/spi-cadence.c:652:12: warning: 'cnds_runtime_resume' defined but 
> not used
>
> This adds __maybe_unused annotations to the respective functions
> to shut up the warnings, while leaving the code in place for
> compile testing and avoiding ugly #ifdefs.

Thanks for the patch.
Feel free to add my ack.
Acked-by: Shubhrajyoti Datta 

>
> Signed-off-by: Arnd Bergmann 
> Fixes: d36ccd9f7ea4 ("spi: cadence: Runtime pm adaptation")
> ---


[PATCH] spi: cadence: Fix some checkpatch warnings

2016-04-06 Thread Shubhrajyoti Datta
No functional change.
Fixing some style related issues

CHECK: multiple assignments should be avoided
+   new_ctrl_reg = ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR);

CHECK: Alignment should match open parenthesis
+static void cdns_spi_config_clock_freq(struct spi_device *spi,
+ struct spi_transfer *transfer)

CHECK: Please use a blank line after function/struct/union/enum declarations
+}
+static int cdns_prepare_message(struct spi_master *master,

Signed-off-by: Shubhrajyoti Datta <shubh...@xilinx.com>
---
 drivers/spi/spi-cadence.c |6 --
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index 07481e1..8a0bd62 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -209,7 +209,8 @@ static void cdns_spi_config_clock_mode(struct spi_device 
*spi)
struct cdns_spi *xspi = spi_master_get_devdata(spi->master);
u32 ctrl_reg, new_ctrl_reg;
 
-   new_ctrl_reg = ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR);
+   new_ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR);
+   ctrl_reg = new_ctrl_reg;
 
/* Set the SPI clock phase and clock polarity */
new_ctrl_reg &= ~(CDNS_SPI_CR_CPHA | CDNS_SPI_CR_CPOL);
@@ -246,7 +247,7 @@ static void cdns_spi_config_clock_mode(struct spi_device 
*spi)
  * controller.
  */
 static void cdns_spi_config_clock_freq(struct spi_device *spi,
- struct spi_transfer *transfer)
+  struct spi_transfer *transfer)
 {
struct cdns_spi *xspi = spi_master_get_devdata(spi->master);
u32 ctrl_reg, baud_rate_val;
@@ -380,6 +381,7 @@ static irqreturn_t cdns_spi_irq(int irq, void *dev_id)
 
return status;
 }
+
 static int cdns_prepare_message(struct spi_master *master,
struct spi_message *msg)
 {
-- 
1.7.1



[PATCH] spi: cadence: Fix some checkpatch warnings

2016-04-06 Thread Shubhrajyoti Datta
No functional change.
Fixing some style related issues

CHECK: multiple assignments should be avoided
+   new_ctrl_reg = ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR);

CHECK: Alignment should match open parenthesis
+static void cdns_spi_config_clock_freq(struct spi_device *spi,
+ struct spi_transfer *transfer)

CHECK: Please use a blank line after function/struct/union/enum declarations
+}
+static int cdns_prepare_message(struct spi_master *master,

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/spi/spi-cadence.c |6 --
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index 07481e1..8a0bd62 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -209,7 +209,8 @@ static void cdns_spi_config_clock_mode(struct spi_device 
*spi)
struct cdns_spi *xspi = spi_master_get_devdata(spi->master);
u32 ctrl_reg, new_ctrl_reg;
 
-   new_ctrl_reg = ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR);
+   new_ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR);
+   ctrl_reg = new_ctrl_reg;
 
/* Set the SPI clock phase and clock polarity */
new_ctrl_reg &= ~(CDNS_SPI_CR_CPHA | CDNS_SPI_CR_CPOL);
@@ -246,7 +247,7 @@ static void cdns_spi_config_clock_mode(struct spi_device 
*spi)
  * controller.
  */
 static void cdns_spi_config_clock_freq(struct spi_device *spi,
- struct spi_transfer *transfer)
+  struct spi_transfer *transfer)
 {
struct cdns_spi *xspi = spi_master_get_devdata(spi->master);
u32 ctrl_reg, baud_rate_val;
@@ -380,6 +381,7 @@ static irqreturn_t cdns_spi_irq(int irq, void *dev_id)
 
return status;
 }
+
 static int cdns_prepare_message(struct spi_master *master,
struct spi_message *msg)
 {
-- 
1.7.1



[PATCH 4/7] spi: cadance: Fix the Documentation

2016-04-05 Thread Shubhrajyoti Datta
cdns_spi_chipselect has parameter is_high however the comment
describes it as is_on.
Also fixes the below warning.
drivers/spi/spi-cadence.c:182: warning: No description found for
parameter 'is_high'
drivers/spi/spi-cadence.c:182: warning: Excess function parameter 'is_on'
description in 'cdns_spi_chipselect'

Signed-off-by: Shubhrajyoti Datta <shubh...@xilinx.com>
---
 drivers/spi/spi-cadence.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index 2915b25..8a6fee9 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -169,7 +169,7 @@ static void cdns_spi_init_hw(struct cdns_spi *xspi)
 /**
  * cdns_spi_chipselect - Select or deselect the chip select line
  * @spi:   Pointer to the spi_device structure
- * @is_on: Select(0) or deselect (1) the chip select line
+ * @is_high:   Select(0) or deselect (1) the chip select line
  */
 static void cdns_spi_chipselect(struct spi_device *spi, bool is_high)
 {
-- 
1.7.1



[PATCH 1/7] spi: cadence: Fix a check patch warning

2016-04-05 Thread Shubhrajyoti Datta
CHECK: Comparison to NULL could be written "!master"
+   if (master == NULL)

Signed-off-by: Shubhrajyoti Datta <shubh...@xilinx.com>
---
 drivers/spi/spi-cadence.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index 121a413..3acaac3 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -481,7 +481,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
u32 num_cs;
 
master = spi_alloc_master(>dev, sizeof(*xspi));
-   if (master == NULL)
+   if (!master)
return -ENOMEM;
 
xspi = spi_master_get_devdata(master);
-- 
1.7.1



[PATCH 6/7] spi: cadence: Remove the clock enable and disable from suspend and resume

2016-04-05 Thread Shubhrajyoti Datta
Now that the clocks are enabled and disabled per transaction
, remove the clock enable and disable from resume and suspend
hooks.

Signed-off-by: Shubhrajyoti Datta <shubh...@xilinx.com>
---
 drivers/spi/spi-cadence.c |   19 ---
 1 files changed, 0 insertions(+), 19 deletions(-)

diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index 3b94063..d0cdd18 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -621,14 +621,9 @@ static int __maybe_unused cdns_spi_suspend(struct device 
*dev)
 {
struct platform_device *pdev = to_platform_device(dev);
struct spi_master *master = platform_get_drvdata(pdev);
-   struct cdns_spi *xspi = spi_master_get_devdata(master);
 
spi_master_suspend(master);
 
-   clk_disable_unprepare(xspi->ref_clk);
-
-   clk_disable_unprepare(xspi->pclk);
-
return 0;
 }
 
@@ -644,21 +639,7 @@ static int __maybe_unused cdns_spi_resume(struct device 
*dev)
 {
struct platform_device *pdev = to_platform_device(dev);
struct spi_master *master = platform_get_drvdata(pdev);
-   struct cdns_spi *xspi = spi_master_get_devdata(master);
-   int ret = 0;
-
-   ret = clk_prepare_enable(xspi->pclk);
-   if (ret) {
-   dev_err(dev, "Cannot enable APB clock.\n");
-   return ret;
-   }
 
-   ret = clk_prepare_enable(xspi->ref_clk);
-   if (ret) {
-   dev_err(dev, "Cannot enable device clock.\n");
-   clk_disable(xspi->pclk);
-   return ret;
-   }
spi_master_resume(master);
 
return 0;
-- 
1.7.1



[PATCH 6/7] spi: cadence: Remove the clock enable and disable from suspend and resume

2016-04-05 Thread Shubhrajyoti Datta
Now that the clocks are enabled and disabled per transaction
, remove the clock enable and disable from resume and suspend
hooks.

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/spi/spi-cadence.c |   19 ---
 1 files changed, 0 insertions(+), 19 deletions(-)

diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index 3b94063..d0cdd18 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -621,14 +621,9 @@ static int __maybe_unused cdns_spi_suspend(struct device 
*dev)
 {
struct platform_device *pdev = to_platform_device(dev);
struct spi_master *master = platform_get_drvdata(pdev);
-   struct cdns_spi *xspi = spi_master_get_devdata(master);
 
spi_master_suspend(master);
 
-   clk_disable_unprepare(xspi->ref_clk);
-
-   clk_disable_unprepare(xspi->pclk);
-
return 0;
 }
 
@@ -644,21 +639,7 @@ static int __maybe_unused cdns_spi_resume(struct device 
*dev)
 {
struct platform_device *pdev = to_platform_device(dev);
struct spi_master *master = platform_get_drvdata(pdev);
-   struct cdns_spi *xspi = spi_master_get_devdata(master);
-   int ret = 0;
-
-   ret = clk_prepare_enable(xspi->pclk);
-   if (ret) {
-   dev_err(dev, "Cannot enable APB clock.\n");
-   return ret;
-   }
 
-   ret = clk_prepare_enable(xspi->ref_clk);
-   if (ret) {
-   dev_err(dev, "Cannot enable device clock.\n");
-   clk_disable(xspi->pclk);
-   return ret;
-   }
spi_master_resume(master);
 
return 0;
-- 
1.7.1



[PATCH 4/7] spi: cadance: Fix the Documentation

2016-04-05 Thread Shubhrajyoti Datta
cdns_spi_chipselect has parameter is_high however the comment
describes it as is_on.
Also fixes the below warning.
drivers/spi/spi-cadence.c:182: warning: No description found for
parameter 'is_high'
drivers/spi/spi-cadence.c:182: warning: Excess function parameter 'is_on'
description in 'cdns_spi_chipselect'

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/spi/spi-cadence.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index 2915b25..8a6fee9 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -169,7 +169,7 @@ static void cdns_spi_init_hw(struct cdns_spi *xspi)
 /**
  * cdns_spi_chipselect - Select or deselect the chip select line
  * @spi:   Pointer to the spi_device structure
- * @is_on: Select(0) or deselect (1) the chip select line
+ * @is_high:   Select(0) or deselect (1) the chip select line
  */
 static void cdns_spi_chipselect(struct spi_device *spi, bool is_high)
 {
-- 
1.7.1



[PATCH 1/7] spi: cadence: Fix a check patch warning

2016-04-05 Thread Shubhrajyoti Datta
CHECK: Comparison to NULL could be written "!master"
+   if (master == NULL)

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/spi/spi-cadence.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index 121a413..3acaac3 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -481,7 +481,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
u32 num_cs;
 
master = spi_alloc_master(>dev, sizeof(*xspi));
-   if (master == NULL)
+   if (!master)
return -ENOMEM;
 
xspi = spi_master_get_devdata(master);
-- 
1.7.1



[PATCH 3/7] spi: cadence: Fix probe error handling

2016-04-05 Thread Shubhrajyoti Datta
The clock disabling is missed out in some
error cases at probe. Fix the same.

Signed-off-by: Shubhrajyoti Datta <shubh...@xilinx.com>
---
 drivers/spi/spi-cadence.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index 97a3bf6..2915b25 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -527,7 +527,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
if (irq <= 0) {
ret = -ENXIO;
dev_err(>dev, "irq number is invalid\n");
-   goto remove_master;
+   goto clk_dis_all;
}
 
ret = devm_request_irq(>dev, irq, cdns_spi_irq,
@@ -535,7 +535,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
if (ret != 0) {
ret = -ENXIO;
dev_err(>dev, "request_irq failed\n");
-   goto remove_master;
+   goto clk_dis_all;
}
 
master->prepare_transfer_hardware = cdns_prepare_transfer_hardware;
-- 
1.7.1



[PATCH 3/7] spi: cadence: Fix probe error handling

2016-04-05 Thread Shubhrajyoti Datta
The clock disabling is missed out in some
error cases at probe. Fix the same.

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/spi/spi-cadence.c |4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index 97a3bf6..2915b25 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -527,7 +527,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
if (irq <= 0) {
ret = -ENXIO;
dev_err(>dev, "irq number is invalid\n");
-   goto remove_master;
+   goto clk_dis_all;
}
 
ret = devm_request_irq(>dev, irq, cdns_spi_irq,
@@ -535,7 +535,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
if (ret != 0) {
ret = -ENXIO;
dev_err(>dev, "request_irq failed\n");
-   goto remove_master;
+   goto clk_dis_all;
}
 
master->prepare_transfer_hardware = cdns_prepare_transfer_hardware;
-- 
1.7.1



[PATCH 5/7] spi: cadence: Runtime pm adaptation

2016-04-05 Thread Shubhrajyoti Datta
Currently the clocks are enabled at probe and disabled
at remove. This patch moves the clock enable to the
start of transaction and disables at the end.

Signed-off-by: Shubhrajyoti Datta <shubh...@xilinx.com>
---
 drivers/spi/spi-cadence.c |   70 +++-
 1 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index 8a6fee9..3b94063 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /* Name of this driver */
@@ -37,6 +38,7 @@
 #define CDNS_SPI_SICR  0x24 /* Slave Idle Count Register, RW */
 #define CDNS_SPI_THLD  0x28 /* Transmit FIFO Watermark Register,RW */
 
+#define SPI_AUTOSUSPEND_TIMEOUT3000
 /*
  * SPI Configuration Register bit Masks
  *
@@ -509,6 +511,11 @@ static int cdns_spi_probe(struct platform_device *pdev)
goto clk_dis_apb;
}
 
+   pm_runtime_enable(>dev);
+   pm_runtime_use_autosuspend(>dev);
+   pm_runtime_set_autosuspend_delay(>dev, SPI_AUTOSUSPEND_TIMEOUT);
+   pm_runtime_set_active(>dev);
+
ret = of_property_read_u32(pdev->dev.of_node, "num-cs", _cs);
if (ret < 0)
master->num_chipselect = CDNS_SPI_DEFAULT_NUM_CS;
@@ -523,6 +530,9 @@ static int cdns_spi_probe(struct platform_device *pdev)
/* SPI controller initializations */
cdns_spi_init_hw(xspi);
 
+   pm_runtime_mark_last_busy(>dev);
+   pm_runtime_put_autosuspend(>dev);
+
irq = platform_get_irq(pdev, 0);
if (irq <= 0) {
ret = -ENXIO;
@@ -543,6 +553,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
master->transfer_one = cdns_transfer_one;
master->unprepare_transfer_hardware = cdns_unprepare_transfer_hardware;
master->set_cs = cdns_spi_chipselect;
+   master->auto_runtime_pm = true;
master->mode_bits = SPI_CPOL | SPI_CPHA;
 
/* Set to default valid value */
@@ -560,6 +571,8 @@ static int cdns_spi_probe(struct platform_device *pdev)
return ret;
 
 clk_dis_all:
+   pm_runtime_set_suspended(>dev);
+   pm_runtime_disable(>dev);
clk_disable_unprepare(xspi->ref_clk);
 clk_dis_apb:
clk_disable_unprepare(xspi->pclk);
@@ -587,6 +600,8 @@ static int cdns_spi_remove(struct platform_device *pdev)
 
clk_disable_unprepare(xspi->ref_clk);
clk_disable_unprepare(xspi->pclk);
+   pm_runtime_set_suspended(>dev);
+   pm_runtime_disable(>dev);
 
spi_unregister_master(master);
 
@@ -649,8 +664,59 @@ static int __maybe_unused cdns_spi_resume(struct device 
*dev)
return 0;
 }
 
-static SIMPLE_DEV_PM_OPS(cdns_spi_dev_pm_ops, cdns_spi_suspend,
-cdns_spi_resume);
+/**
+ * cdns_spi_runtime_resume - Runtime resume method for the SPI driver
+ * @dev:   Address of the platform_device structure
+ *
+ * This function enables the clocks
+ *
+ * Return: 0 on success and error value on error
+ */
+static int cnds_runtime_resume(struct device *dev)
+{
+   struct spi_master *master = dev_get_drvdata(dev);
+   struct cdns_spi *xspi = spi_master_get_devdata(master);
+   int ret;
+
+   ret = clk_prepare_enable(xspi->pclk);
+   if (ret) {
+   dev_err(dev, "Cannot enable APB clock.\n");
+   return ret;
+   }
+
+   ret = clk_prepare_enable(xspi->ref_clk);
+   if (ret) {
+   dev_err(dev, "Cannot enable device clock.\n");
+   clk_disable(xspi->pclk);
+   return ret;
+   }
+   return 0;
+}
+
+/**
+ * cdns_spi_runtime_suspend - Runtime suspend method for the SPI driver
+ * @dev:   Address of the platform_device structure
+ *
+ * This function disables the clocks
+ *
+ * Return: Always 0
+ */
+static int cnds_runtime_suspend(struct device *dev)
+{
+   struct spi_master *master = dev_get_drvdata(dev);
+   struct cdns_spi *xspi = spi_master_get_devdata(master);
+
+   clk_disable_unprepare(xspi->ref_clk);
+   clk_disable_unprepare(xspi->pclk);
+
+   return 0;
+}
+
+static const struct dev_pm_ops cdns_spi_dev_pm_ops = {
+   SET_RUNTIME_PM_OPS(cnds_runtime_suspend,
+  cnds_runtime_resume, NULL)
+   SET_SYSTEM_SLEEP_PM_OPS(cdns_spi_suspend, cdns_spi_resume)
+};
 
 static const struct of_device_id cdns_spi_of_match[] = {
{ .compatible = "xlnx,zynq-spi-r1p6" },
-- 
1.7.1



[PATCH 7/7] spi: cadence: Return the error code for cdns_spi_suspend and cdns_spi_resume

2016-04-05 Thread Shubhrajyoti Datta
Return the error code for cdns_spi_suspend and cdns_spi_resume.
Also fixes a comment where which claims that the error code is
returned.

Signed-off-by: Shubhrajyoti Datta <shubh...@xilinx.com>
---
 drivers/spi/spi-cadence.c |   10 +++---
 1 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index d0cdd18..07481e1 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -615,16 +615,14 @@ static int cdns_spi_remove(struct platform_device *pdev)
  * This function disables the SPI controller and
  * changes the driver state to "suspend"
  *
- * Return: Always 0
+ * Return: 0 on success and error value on error
  */
 static int __maybe_unused cdns_spi_suspend(struct device *dev)
 {
struct platform_device *pdev = to_platform_device(dev);
struct spi_master *master = platform_get_drvdata(pdev);
 
-   spi_master_suspend(master);
-
-   return 0;
+   return spi_master_suspend(master);
 }
 
 /**
@@ -640,9 +638,7 @@ static int __maybe_unused cdns_spi_resume(struct device 
*dev)
struct platform_device *pdev = to_platform_device(dev);
struct spi_master *master = platform_get_drvdata(pdev);
 
-   spi_master_resume(master);
-
-   return 0;
+   return spi_master_resume(master);
 }
 
 /**
-- 
1.7.1



[PATCH 2/7] spi: cadence: Remove _MASK and _OFFSET suffix

2016-04-05 Thread Shubhrajyoti Datta
Remove the _MASK and _OFFSET from the macros.
It improves readability, removes some checkpatch
error for exceeding 80 chars  and also prevents some
linebreaks.

Signed-off-by: Shubhrajyoti Datta <shubh...@xilinx.com>
---
 drivers/spi/spi-cadence.c |  161 +
 1 files changed, 74 insertions(+), 87 deletions(-)

diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index 3acaac3..97a3bf6 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -25,17 +25,17 @@
 #define CDNS_SPI_NAME  "cdns-spi"
 
 /* Register offset definitions */
-#define CDNS_SPI_CR_OFFSET 0x00 /* Configuration  Register, RW */
-#define CDNS_SPI_ISR_OFFSET0x04 /* Interrupt Status Register, RO */
-#define CDNS_SPI_IER_OFFSET0x08 /* Interrupt Enable Register, WO */
-#define CDNS_SPI_IDR_OFFSET0x0c /* Interrupt Disable Register, WO */
-#define CDNS_SPI_IMR_OFFSET0x10 /* Interrupt Enabled Mask Register, RO */
-#define CDNS_SPI_ER_OFFSET 0x14 /* Enable/Disable Register, RW */
-#define CDNS_SPI_DR_OFFSET 0x18 /* Delay Register, RW */
-#define CDNS_SPI_TXD_OFFSET0x1C /* Data Transmit Register, WO */
-#define CDNS_SPI_RXD_OFFSET0x20 /* Data Receive Register, RO */
-#define CDNS_SPI_SICR_OFFSET   0x24 /* Slave Idle Count Register, RW */
-#define CDNS_SPI_THLD_OFFSET   0x28 /* Transmit FIFO Watermark Register,RW */
+#define CDNS_SPI_CR0x00 /* Configuration  Register, RW */
+#define CDNS_SPI_ISR   0x04 /* Interrupt Status Register, RO */
+#define CDNS_SPI_IER   0x08 /* Interrupt Enable Register, WO */
+#define CDNS_SPI_IDR   0x0c /* Interrupt Disable Register, WO */
+#define CDNS_SPI_IMR   0x10 /* Interrupt Enabled Mask Register, RO */
+#define CDNS_SPI_ER0x14 /* Enable/Disable Register, RW */
+#define CDNS_SPI_DR0x18 /* Delay Register, RW */
+#define CDNS_SPI_TXD   0x1C /* Data Transmit Register, WO */
+#define CDNS_SPI_RXD   0x20 /* Data Receive Register, RO */
+#define CDNS_SPI_SICR  0x24 /* Slave Idle Count Register, RW */
+#define CDNS_SPI_THLD  0x28 /* Transmit FIFO Watermark Register,RW */
 
 /*
  * SPI Configuration Register bit Masks
@@ -43,20 +43,20 @@
  * This register contains various control bits that affect the operation
  * of the SPI controller
  */
-#define CDNS_SPI_CR_MANSTRT_MASK   0x0001 /* Manual TX Start */
-#define CDNS_SPI_CR_CPHA_MASK  0x0004 /* Clock Phase Control */
-#define CDNS_SPI_CR_CPOL_MASK  0x0002 /* Clock Polarity Control */
-#define CDNS_SPI_CR_SSCTRL_MASK0x3C00 /* Slave Select Mask 
*/
-#define CDNS_SPI_CR_PERI_SEL_MASK  0x0200 /* Peripheral Select Decode 
*/
-#define CDNS_SPI_CR_BAUD_DIV_MASK  0x0038 /* Baud Rate Divisor Mask */
-#define CDNS_SPI_CR_MSTREN_MASK0x0001 /* Master Enable 
Mask */
-#define CDNS_SPI_CR_MANSTRTEN_MASK 0x8000 /* Manual TX Enable Mask */
-#define CDNS_SPI_CR_SSFORCE_MASK   0x4000 /* Manual SS Enable Mask */
-#define CDNS_SPI_CR_BAUD_DIV_4_MASK0x0008 /* Default Baud Div Mask */
-#define CDNS_SPI_CR_DEFAULT_MASK   (CDNS_SPI_CR_MSTREN_MASK | \
-   CDNS_SPI_CR_SSCTRL_MASK | \
-   CDNS_SPI_CR_SSFORCE_MASK | \
-   CDNS_SPI_CR_BAUD_DIV_4_MASK)
+#define CDNS_SPI_CR_MANSTRT0x0001 /* Manual TX Start */
+#define CDNS_SPI_CR_CPHA   0x0004 /* Clock Phase Control */
+#define CDNS_SPI_CR_CPOL   0x0002 /* Clock Polarity Control */
+#define CDNS_SPI_CR_SSCTRL 0x3C00 /* Slave Select Mask */
+#define CDNS_SPI_CR_PERI_SEL   0x0200 /* Peripheral Select Decode */
+#define CDNS_SPI_CR_BAUD_DIV   0x0038 /* Baud Rate Divisor Mask */
+#define CDNS_SPI_CR_MSTREN 0x0001 /* Master Enable Mask */
+#define CDNS_SPI_CR_MANSTRTEN  0x8000 /* Manual TX Enable Mask */
+#define CDNS_SPI_CR_SSFORCE0x4000 /* Manual SS Enable Mask */
+#define CDNS_SPI_CR_BAUD_DIV_4 0x0008 /* Default Baud Div Mask */
+#define CDNS_SPI_CR_DEFAULT(CDNS_SPI_CR_MSTREN | \
+   CDNS_SPI_CR_SSCTRL | \
+   CDNS_SPI_CR_SSFORCE | \
+   CDNS_SPI_CR_BAUD_DIV_4)
 
 /*
  * SPI Configuration Register - Baud rate and slave select
@@ -77,21 +77,21 @@
  * All the four interrupt registers (Status/Mask/Enable/Disable) have the same
  * bit definitions.
  */
-#define CDNS_SPI_IXR_TXOW_MASK 0x0004 /* SPI TX FIFO Overwater */
-#define CDNS_SPI_IXR_MODF_MASK 0x0002 /* SPI Mode Fault */
-#define CDNS_SPI_IXR_RXNEMTY_MASK 0x0010 /* SPI RX FIFO Not Empty */
-#define CDNS_SPI_IXR_DEFAULT_MASK  (CDNS_SPI_IXR_TXOW_MASK | \
-   CDNS_SPI_IXR_MODF_MASK)
-#define CDNS_SPI_IXR_TXFULL_MASK   0x0008 /* SPI TX Full */
-#define CDNS_SPI_IXR_ALL_MASK  0x000

[PATCH 5/7] spi: cadence: Runtime pm adaptation

2016-04-05 Thread Shubhrajyoti Datta
Currently the clocks are enabled at probe and disabled
at remove. This patch moves the clock enable to the
start of transaction and disables at the end.

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/spi/spi-cadence.c |   70 +++-
 1 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index 8a6fee9..3b94063 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 /* Name of this driver */
@@ -37,6 +38,7 @@
 #define CDNS_SPI_SICR  0x24 /* Slave Idle Count Register, RW */
 #define CDNS_SPI_THLD  0x28 /* Transmit FIFO Watermark Register,RW */
 
+#define SPI_AUTOSUSPEND_TIMEOUT3000
 /*
  * SPI Configuration Register bit Masks
  *
@@ -509,6 +511,11 @@ static int cdns_spi_probe(struct platform_device *pdev)
goto clk_dis_apb;
}
 
+   pm_runtime_enable(>dev);
+   pm_runtime_use_autosuspend(>dev);
+   pm_runtime_set_autosuspend_delay(>dev, SPI_AUTOSUSPEND_TIMEOUT);
+   pm_runtime_set_active(>dev);
+
ret = of_property_read_u32(pdev->dev.of_node, "num-cs", _cs);
if (ret < 0)
master->num_chipselect = CDNS_SPI_DEFAULT_NUM_CS;
@@ -523,6 +530,9 @@ static int cdns_spi_probe(struct platform_device *pdev)
/* SPI controller initializations */
cdns_spi_init_hw(xspi);
 
+   pm_runtime_mark_last_busy(>dev);
+   pm_runtime_put_autosuspend(>dev);
+
irq = platform_get_irq(pdev, 0);
if (irq <= 0) {
ret = -ENXIO;
@@ -543,6 +553,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
master->transfer_one = cdns_transfer_one;
master->unprepare_transfer_hardware = cdns_unprepare_transfer_hardware;
master->set_cs = cdns_spi_chipselect;
+   master->auto_runtime_pm = true;
master->mode_bits = SPI_CPOL | SPI_CPHA;
 
/* Set to default valid value */
@@ -560,6 +571,8 @@ static int cdns_spi_probe(struct platform_device *pdev)
return ret;
 
 clk_dis_all:
+   pm_runtime_set_suspended(>dev);
+   pm_runtime_disable(>dev);
clk_disable_unprepare(xspi->ref_clk);
 clk_dis_apb:
clk_disable_unprepare(xspi->pclk);
@@ -587,6 +600,8 @@ static int cdns_spi_remove(struct platform_device *pdev)
 
clk_disable_unprepare(xspi->ref_clk);
clk_disable_unprepare(xspi->pclk);
+   pm_runtime_set_suspended(>dev);
+   pm_runtime_disable(>dev);
 
spi_unregister_master(master);
 
@@ -649,8 +664,59 @@ static int __maybe_unused cdns_spi_resume(struct device 
*dev)
return 0;
 }
 
-static SIMPLE_DEV_PM_OPS(cdns_spi_dev_pm_ops, cdns_spi_suspend,
-cdns_spi_resume);
+/**
+ * cdns_spi_runtime_resume - Runtime resume method for the SPI driver
+ * @dev:   Address of the platform_device structure
+ *
+ * This function enables the clocks
+ *
+ * Return: 0 on success and error value on error
+ */
+static int cnds_runtime_resume(struct device *dev)
+{
+   struct spi_master *master = dev_get_drvdata(dev);
+   struct cdns_spi *xspi = spi_master_get_devdata(master);
+   int ret;
+
+   ret = clk_prepare_enable(xspi->pclk);
+   if (ret) {
+   dev_err(dev, "Cannot enable APB clock.\n");
+   return ret;
+   }
+
+   ret = clk_prepare_enable(xspi->ref_clk);
+   if (ret) {
+   dev_err(dev, "Cannot enable device clock.\n");
+   clk_disable(xspi->pclk);
+   return ret;
+   }
+   return 0;
+}
+
+/**
+ * cdns_spi_runtime_suspend - Runtime suspend method for the SPI driver
+ * @dev:   Address of the platform_device structure
+ *
+ * This function disables the clocks
+ *
+ * Return: Always 0
+ */
+static int cnds_runtime_suspend(struct device *dev)
+{
+   struct spi_master *master = dev_get_drvdata(dev);
+   struct cdns_spi *xspi = spi_master_get_devdata(master);
+
+   clk_disable_unprepare(xspi->ref_clk);
+   clk_disable_unprepare(xspi->pclk);
+
+   return 0;
+}
+
+static const struct dev_pm_ops cdns_spi_dev_pm_ops = {
+   SET_RUNTIME_PM_OPS(cnds_runtime_suspend,
+  cnds_runtime_resume, NULL)
+   SET_SYSTEM_SLEEP_PM_OPS(cdns_spi_suspend, cdns_spi_resume)
+};
 
 static const struct of_device_id cdns_spi_of_match[] = {
{ .compatible = "xlnx,zynq-spi-r1p6" },
-- 
1.7.1



[PATCH 7/7] spi: cadence: Return the error code for cdns_spi_suspend and cdns_spi_resume

2016-04-05 Thread Shubhrajyoti Datta
Return the error code for cdns_spi_suspend and cdns_spi_resume.
Also fixes a comment where which claims that the error code is
returned.

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/spi/spi-cadence.c |   10 +++---
 1 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index d0cdd18..07481e1 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -615,16 +615,14 @@ static int cdns_spi_remove(struct platform_device *pdev)
  * This function disables the SPI controller and
  * changes the driver state to "suspend"
  *
- * Return: Always 0
+ * Return: 0 on success and error value on error
  */
 static int __maybe_unused cdns_spi_suspend(struct device *dev)
 {
struct platform_device *pdev = to_platform_device(dev);
struct spi_master *master = platform_get_drvdata(pdev);
 
-   spi_master_suspend(master);
-
-   return 0;
+   return spi_master_suspend(master);
 }
 
 /**
@@ -640,9 +638,7 @@ static int __maybe_unused cdns_spi_resume(struct device 
*dev)
struct platform_device *pdev = to_platform_device(dev);
struct spi_master *master = platform_get_drvdata(pdev);
 
-   spi_master_resume(master);
-
-   return 0;
+   return spi_master_resume(master);
 }
 
 /**
-- 
1.7.1



[PATCH 2/7] spi: cadence: Remove _MASK and _OFFSET suffix

2016-04-05 Thread Shubhrajyoti Datta
Remove the _MASK and _OFFSET from the macros.
It improves readability, removes some checkpatch
error for exceeding 80 chars  and also prevents some
linebreaks.

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/spi/spi-cadence.c |  161 +
 1 files changed, 74 insertions(+), 87 deletions(-)

diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c
index 3acaac3..97a3bf6 100644
--- a/drivers/spi/spi-cadence.c
+++ b/drivers/spi/spi-cadence.c
@@ -25,17 +25,17 @@
 #define CDNS_SPI_NAME  "cdns-spi"
 
 /* Register offset definitions */
-#define CDNS_SPI_CR_OFFSET 0x00 /* Configuration  Register, RW */
-#define CDNS_SPI_ISR_OFFSET0x04 /* Interrupt Status Register, RO */
-#define CDNS_SPI_IER_OFFSET0x08 /* Interrupt Enable Register, WO */
-#define CDNS_SPI_IDR_OFFSET0x0c /* Interrupt Disable Register, WO */
-#define CDNS_SPI_IMR_OFFSET0x10 /* Interrupt Enabled Mask Register, RO */
-#define CDNS_SPI_ER_OFFSET 0x14 /* Enable/Disable Register, RW */
-#define CDNS_SPI_DR_OFFSET 0x18 /* Delay Register, RW */
-#define CDNS_SPI_TXD_OFFSET0x1C /* Data Transmit Register, WO */
-#define CDNS_SPI_RXD_OFFSET0x20 /* Data Receive Register, RO */
-#define CDNS_SPI_SICR_OFFSET   0x24 /* Slave Idle Count Register, RW */
-#define CDNS_SPI_THLD_OFFSET   0x28 /* Transmit FIFO Watermark Register,RW */
+#define CDNS_SPI_CR0x00 /* Configuration  Register, RW */
+#define CDNS_SPI_ISR   0x04 /* Interrupt Status Register, RO */
+#define CDNS_SPI_IER   0x08 /* Interrupt Enable Register, WO */
+#define CDNS_SPI_IDR   0x0c /* Interrupt Disable Register, WO */
+#define CDNS_SPI_IMR   0x10 /* Interrupt Enabled Mask Register, RO */
+#define CDNS_SPI_ER0x14 /* Enable/Disable Register, RW */
+#define CDNS_SPI_DR0x18 /* Delay Register, RW */
+#define CDNS_SPI_TXD   0x1C /* Data Transmit Register, WO */
+#define CDNS_SPI_RXD   0x20 /* Data Receive Register, RO */
+#define CDNS_SPI_SICR  0x24 /* Slave Idle Count Register, RW */
+#define CDNS_SPI_THLD  0x28 /* Transmit FIFO Watermark Register,RW */
 
 /*
  * SPI Configuration Register bit Masks
@@ -43,20 +43,20 @@
  * This register contains various control bits that affect the operation
  * of the SPI controller
  */
-#define CDNS_SPI_CR_MANSTRT_MASK   0x0001 /* Manual TX Start */
-#define CDNS_SPI_CR_CPHA_MASK  0x0004 /* Clock Phase Control */
-#define CDNS_SPI_CR_CPOL_MASK  0x0002 /* Clock Polarity Control */
-#define CDNS_SPI_CR_SSCTRL_MASK0x3C00 /* Slave Select Mask 
*/
-#define CDNS_SPI_CR_PERI_SEL_MASK  0x0200 /* Peripheral Select Decode 
*/
-#define CDNS_SPI_CR_BAUD_DIV_MASK  0x0038 /* Baud Rate Divisor Mask */
-#define CDNS_SPI_CR_MSTREN_MASK0x0001 /* Master Enable 
Mask */
-#define CDNS_SPI_CR_MANSTRTEN_MASK 0x8000 /* Manual TX Enable Mask */
-#define CDNS_SPI_CR_SSFORCE_MASK   0x4000 /* Manual SS Enable Mask */
-#define CDNS_SPI_CR_BAUD_DIV_4_MASK0x0008 /* Default Baud Div Mask */
-#define CDNS_SPI_CR_DEFAULT_MASK   (CDNS_SPI_CR_MSTREN_MASK | \
-   CDNS_SPI_CR_SSCTRL_MASK | \
-   CDNS_SPI_CR_SSFORCE_MASK | \
-   CDNS_SPI_CR_BAUD_DIV_4_MASK)
+#define CDNS_SPI_CR_MANSTRT0x0001 /* Manual TX Start */
+#define CDNS_SPI_CR_CPHA   0x0004 /* Clock Phase Control */
+#define CDNS_SPI_CR_CPOL   0x0002 /* Clock Polarity Control */
+#define CDNS_SPI_CR_SSCTRL 0x3C00 /* Slave Select Mask */
+#define CDNS_SPI_CR_PERI_SEL   0x0200 /* Peripheral Select Decode */
+#define CDNS_SPI_CR_BAUD_DIV   0x0038 /* Baud Rate Divisor Mask */
+#define CDNS_SPI_CR_MSTREN 0x0001 /* Master Enable Mask */
+#define CDNS_SPI_CR_MANSTRTEN  0x8000 /* Manual TX Enable Mask */
+#define CDNS_SPI_CR_SSFORCE0x4000 /* Manual SS Enable Mask */
+#define CDNS_SPI_CR_BAUD_DIV_4 0x0008 /* Default Baud Div Mask */
+#define CDNS_SPI_CR_DEFAULT(CDNS_SPI_CR_MSTREN | \
+   CDNS_SPI_CR_SSCTRL | \
+   CDNS_SPI_CR_SSFORCE | \
+   CDNS_SPI_CR_BAUD_DIV_4)
 
 /*
  * SPI Configuration Register - Baud rate and slave select
@@ -77,21 +77,21 @@
  * All the four interrupt registers (Status/Mask/Enable/Disable) have the same
  * bit definitions.
  */
-#define CDNS_SPI_IXR_TXOW_MASK 0x0004 /* SPI TX FIFO Overwater */
-#define CDNS_SPI_IXR_MODF_MASK 0x0002 /* SPI Mode Fault */
-#define CDNS_SPI_IXR_RXNEMTY_MASK 0x0010 /* SPI RX FIFO Not Empty */
-#define CDNS_SPI_IXR_DEFAULT_MASK  (CDNS_SPI_IXR_TXOW_MASK | \
-   CDNS_SPI_IXR_MODF_MASK)
-#define CDNS_SPI_IXR_TXFULL_MASK   0x0008 /* SPI TX Full */
-#define CDNS_SPI_IXR_ALL_MASK  0x007F /* SPI all interrupts *

[PATCH] gpio: zynq: Fix the error path

2016-04-04 Thread Shubhrajyoti Datta
pm_runtime_disable is called only in remove it is missed
out in the error path.
Fix the same.

Signed-off-by: Shubhrajyoti Datta <shubh...@xilinx.com>
---
 drivers/gpio/gpio-zynq.c |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c
index 66d3d24..75c6355 100644
--- a/drivers/gpio/gpio-zynq.c
+++ b/drivers/gpio/gpio-zynq.c
@@ -713,7 +713,7 @@ static int zynq_gpio_probe(struct platform_device *pdev)
pm_runtime_enable(>dev);
ret = pm_runtime_get_sync(>dev);
if (ret < 0)
-   return ret;
+   goto err_pm_dis;
 
/* report a bug if gpio chip registration fails */
ret = gpiochip_add_data(chip, gpio);
@@ -745,6 +745,8 @@ err_rm_gpiochip:
gpiochip_remove(chip);
 err_pm_put:
pm_runtime_put(>dev);
+err_pm_dis:
+   pm_runtime_disable(>dev);
 
return ret;
 }
-- 
1.7.1



[PATCH] gpio: zynq: Fix the error path

2016-04-04 Thread Shubhrajyoti Datta
pm_runtime_disable is called only in remove it is missed
out in the error path.
Fix the same.

Signed-off-by: Shubhrajyoti Datta 
---
 drivers/gpio/gpio-zynq.c |4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c
index 66d3d24..75c6355 100644
--- a/drivers/gpio/gpio-zynq.c
+++ b/drivers/gpio/gpio-zynq.c
@@ -713,7 +713,7 @@ static int zynq_gpio_probe(struct platform_device *pdev)
pm_runtime_enable(>dev);
ret = pm_runtime_get_sync(>dev);
if (ret < 0)
-   return ret;
+   goto err_pm_dis;
 
/* report a bug if gpio chip registration fails */
ret = gpiochip_add_data(chip, gpio);
@@ -745,6 +745,8 @@ err_rm_gpiochip:
gpiochip_remove(chip);
 err_pm_put:
pm_runtime_put(>dev);
+err_pm_dis:
+   pm_runtime_disable(>dev);
 
return ret;
 }
-- 
1.7.1



Re: [PATCH 1/3] spi: spi-xilinx: Remove ISR race condition

2015-12-03 Thread Shubhrajyoti Datta
>
>>
>> =
>> spi: xilinx - minimize iomem reads
>>
>> If this IP core is accessed through bridges like PCI-e, reads are rather
>> costly. Doing many reads or read-modify-writes is thus long and strenuous
>> on the CPU (active waiting).
>>
>> The transfer workflow of this driver allows some assumptions to be made 
>> and
>> exploited to minimize reads as much as possible.
>>
>> These two assumptions are made:
>> - since we are in control of the CR register, cache it so we don't have 
>> to
>>   read it all the time to modify it.
>
> Makes sense.

I have made an attempt at it can you check if you get any performance
improvemets
on your setup.

http://www.spinics.net/lists/linux-spi/msg05963.html


Thanks,
Shubhrajyoti
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/3] spi: spi-xilinx: Remove ISR race condition

2015-12-03 Thread Shubhrajyoti Datta
>
>>
>> =
>> spi: xilinx - minimize iomem reads
>>
>> If this IP core is accessed through bridges like PCI-e, reads are rather
>> costly. Doing many reads or read-modify-writes is thus long and strenuous
>> on the CPU (active waiting).
>>
>> The transfer workflow of this driver allows some assumptions to be made 
>> and
>> exploited to minimize reads as much as possible.
>>
>> These two assumptions are made:
>> - since we are in control of the CR register, cache it so we don't have 
>> to
>>   read it all the time to modify it.
>
> Makes sense.

I have made an attempt at it can you check if you get any performance
improvemets
on your setup.

http://www.spinics.net/lists/linux-spi/msg05963.html


Thanks,
Shubhrajyoti
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] i2c: cadence: Move to sensible power management

2015-11-23 Thread Shubhrajyoti Datta
On Tue, Nov 24, 2015 at 12:17 AM, Sören Brinkmann
 wrote:
> On Sat, 2015-11-21 at 07:00PM +0530, Shubhrajyoti Datta wrote:
>> On Thu, Oct 29, 2015 at 8:27 PM, Shubhrajyoti Datta
>>  wrote:
>> > On Wed, Oct 28, 2015 at 9:48 PM, Sören Brinkmann
>> >  wrote:
>> >> Hi Shubhrajyoti,
>> >>
>> >>
>> >> On Wed, 2015-10-28 at 12:56PM +0530, Shubhrajyoti Datta wrote:
>> >>> Currently the clocks are enabled at probe and disabled at remove.
>> >>> Which keeps the clocks enabled even if no transaction is going on.
>> >>> This patch enables the clocks at the start of transfer and disables
>> >>> after it.
>> >>>
>> >>> Also adapts to runtime pm.
>> >>> Remove xi2c->suspended and use pm runtime status instead.
>> >>>
>> >>> converts dev pm to const to silence a checkpatch warning.
>> >>>
>> >>> Signed-off-by: Shubhrajyoti Datta 
>> >>
>> >> To me, this looks all good. Just one small concern below.
>> >
>> > Thanks for the review.
>> Soren ,
>> Do are you ok with the change or do you want me to resend without the
>> suspended flag change.
>
> I'm always for removing code that is not needed. If things are tested
> and well and work without throwing any warnings I'm OK with it.

It should be also having a suspended book-keeping in the driver is not
needed the pm does that for us.

I will spilt the patch and resend.

Thanks,

>
> Sören
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] i2c: cadence: Move to sensible power management

2015-11-23 Thread Shubhrajyoti Datta
On Tue, Nov 24, 2015 at 12:17 AM, Sören Brinkmann
<soren.brinkm...@xilinx.com> wrote:
> On Sat, 2015-11-21 at 07:00PM +0530, Shubhrajyoti Datta wrote:
>> On Thu, Oct 29, 2015 at 8:27 PM, Shubhrajyoti Datta
>> <shubhrajyoti.da...@gmail.com> wrote:
>> > On Wed, Oct 28, 2015 at 9:48 PM, Sören Brinkmann
>> > <soren.brinkm...@xilinx.com> wrote:
>> >> Hi Shubhrajyoti,
>> >>
>> >>
>> >> On Wed, 2015-10-28 at 12:56PM +0530, Shubhrajyoti Datta wrote:
>> >>> Currently the clocks are enabled at probe and disabled at remove.
>> >>> Which keeps the clocks enabled even if no transaction is going on.
>> >>> This patch enables the clocks at the start of transfer and disables
>> >>> after it.
>> >>>
>> >>> Also adapts to runtime pm.
>> >>> Remove xi2c->suspended and use pm runtime status instead.
>> >>>
>> >>> converts dev pm to const to silence a checkpatch warning.
>> >>>
>> >>> Signed-off-by: Shubhrajyoti Datta <shubh...@xilinx.com>
>> >>
>> >> To me, this looks all good. Just one small concern below.
>> >
>> > Thanks for the review.
>> Soren ,
>> Do are you ok with the change or do you want me to resend without the
>> suspended flag change.
>
> I'm always for removing code that is not needed. If things are tested
> and well and work without throwing any warnings I'm OK with it.

It should be also having a suspended book-keeping in the driver is not
needed the pm does that for us.

I will spilt the patch and resend.

Thanks,

>
> Sören
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] i2c: cadence: Move to sensible power management

2015-11-21 Thread Shubhrajyoti Datta
On Thu, Oct 29, 2015 at 8:27 PM, Shubhrajyoti Datta
 wrote:
> On Wed, Oct 28, 2015 at 9:48 PM, Sören Brinkmann
>  wrote:
>> Hi Shubhrajyoti,
>>
>>
>> On Wed, 2015-10-28 at 12:56PM +0530, Shubhrajyoti Datta wrote:
>>> Currently the clocks are enabled at probe and disabled at remove.
>>> Which keeps the clocks enabled even if no transaction is going on.
>>> This patch enables the clocks at the start of transfer and disables
>>> after it.
>>>
>>> Also adapts to runtime pm.
>>> Remove xi2c->suspended and use pm runtime status instead.
>>>
>>> converts dev pm to const to silence a checkpatch warning.
>>>
>>> Signed-off-by: Shubhrajyoti Datta 
>>
>> To me, this looks all good. Just one small concern below.
>
> Thanks for the review.
Soren ,
Do are you ok with the change or do you want me to resend without the
suspended flag change.

<>
>>
>> There might have been a reason to store this flag here. Did you test
>> this with lockdep and CONFIG_DEBUG_ATOMIC_SLEEP? Just to make sure that
>> nothing that can sleep is called from atomic context.
> Done now.
>
>
> Essentially this is a flag is set in suspend routine. and checked in
> the isr I use
> pm_runtime_suspended(id->dev) instead.
>
>>
>> Sören
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to majord...@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at  http://www.tux.org/lkml/
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] i2c: cadence: Move to sensible power management

2015-11-21 Thread Shubhrajyoti Datta
On Thu, Oct 29, 2015 at 8:27 PM, Shubhrajyoti Datta
<shubhrajyoti.da...@gmail.com> wrote:
> On Wed, Oct 28, 2015 at 9:48 PM, Sören Brinkmann
> <soren.brinkm...@xilinx.com> wrote:
>> Hi Shubhrajyoti,
>>
>>
>> On Wed, 2015-10-28 at 12:56PM +0530, Shubhrajyoti Datta wrote:
>>> Currently the clocks are enabled at probe and disabled at remove.
>>> Which keeps the clocks enabled even if no transaction is going on.
>>> This patch enables the clocks at the start of transfer and disables
>>> after it.
>>>
>>> Also adapts to runtime pm.
>>> Remove xi2c->suspended and use pm runtime status instead.
>>>
>>> converts dev pm to const to silence a checkpatch warning.
>>>
>>> Signed-off-by: Shubhrajyoti Datta <shubh...@xilinx.com>
>>
>> To me, this looks all good. Just one small concern below.
>
> Thanks for the review.
Soren ,
Do are you ok with the change or do you want me to resend without the
suspended flag change.

<>
>>
>> There might have been a reason to store this flag here. Did you test
>> this with lockdep and CONFIG_DEBUG_ATOMIC_SLEEP? Just to make sure that
>> nothing that can sleep is called from atomic context.
> Done now.
>
>
> Essentially this is a flag is set in suspend routine. and checked in
> the isr I use
> pm_runtime_suspended(id->dev) instead.
>
>>
>> Sören
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to majord...@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at  http://www.tux.org/lkml/
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] i2c: cadence: Move to sensible power management

2015-10-29 Thread Shubhrajyoti Datta
On Wed, Oct 28, 2015 at 9:48 PM, Sören Brinkmann
 wrote:
> Hi Shubhrajyoti,
>
>
> On Wed, 2015-10-28 at 12:56PM +0530, Shubhrajyoti Datta wrote:
>> Currently the clocks are enabled at probe and disabled at remove.
>> Which keeps the clocks enabled even if no transaction is going on.
>> This patch enables the clocks at the start of transfer and disables
>> after it.
>>
>> Also adapts to runtime pm.
>> Remove xi2c->suspended and use pm runtime status instead.
>>
>> converts dev pm to const to silence a checkpatch warning.
>>
>> Signed-off-by: Shubhrajyoti Datta 
>
> To me, this looks all good. Just one small concern below.

Thanks for the review.

>
>> ---
>> changes since v2
>> update the cc list
>>
>>  drivers/i2c/busses/i2c-cadence.c |   73 
>> --
>>  1 files changed, 46 insertions(+), 27 deletions(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-cadence.c 
>> b/drivers/i2c/busses/i2c-cadence.c
>> index 84deed6..6b08d16 100644
>> --- a/drivers/i2c/busses/i2c-cadence.c
>> +++ b/drivers/i2c/busses/i2c-cadence.c
>> @@ -18,6 +18,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>
>>  /* Register offsets for the I2C device. */
>>  #define CDNS_I2C_CR_OFFSET   0x00 /* Control Register, RW */
>> @@ -96,6 +97,8 @@
>>CDNS_I2C_IXR_COMP)
>>
>>  #define CDNS_I2C_TIMEOUT msecs_to_jiffies(1000)
>> +/* timeout for pm runtime autosuspend */
>> +#define CNDS_I2C_PM_TIMEOUT  1000/* ms */
>>
>>  #define CDNS_I2C_FIFO_DEPTH  16
>>  /* FIFO depth at which the DATA interrupt occurs */
>> @@ -128,7 +131,6 @@
>>   * @xfer_done:   Transfer complete status
>>   * @p_send_buf:  Pointer to transmit buffer
>>   * @p_recv_buf:  Pointer to receive buffer
>> - * @suspended:   Flag holding the device's PM status
>>   * @send_count:  Number of bytes still expected to send
>>   * @recv_count:  Number of bytes still expected to receive
>>   * @curr_recv_count: Number of bytes to be received in current transfer
>> @@ -141,6 +143,7 @@
>>   * @quirks:  flag for broken hold bit usage in r1p10
>>   */
>>  struct cdns_i2c {
>> + struct device   *dev;
>>   void __iomem *membase;
>>   struct i2c_adapter adap;
>>   struct i2c_msg *p_msg;
>> @@ -148,7 +151,6 @@ struct cdns_i2c {
>>   struct completion xfer_done;
>>   unsigned char *p_send_buf;
>>   unsigned char *p_recv_buf;
>> - u8 suspended;
>
> There might have been a reason to store this flag here. Did you test
> this with lockdep and CONFIG_DEBUG_ATOMIC_SLEEP? Just to make sure that
> nothing that can sleep is called from atomic context.
Done now.


Essentially this is a flag is set in suspend routine. and checked in
the isr I use
pm_runtime_suspended(id->dev) instead.

>
> Sören
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v2] i2c: cadence: Move to sensible power management

2015-10-29 Thread Shubhrajyoti Datta
On Wed, Oct 28, 2015 at 9:48 PM, Sören Brinkmann
<soren.brinkm...@xilinx.com> wrote:
> Hi Shubhrajyoti,
>
>
> On Wed, 2015-10-28 at 12:56PM +0530, Shubhrajyoti Datta wrote:
>> Currently the clocks are enabled at probe and disabled at remove.
>> Which keeps the clocks enabled even if no transaction is going on.
>> This patch enables the clocks at the start of transfer and disables
>> after it.
>>
>> Also adapts to runtime pm.
>> Remove xi2c->suspended and use pm runtime status instead.
>>
>> converts dev pm to const to silence a checkpatch warning.
>>
>> Signed-off-by: Shubhrajyoti Datta <shubh...@xilinx.com>
>
> To me, this looks all good. Just one small concern below.

Thanks for the review.

>
>> ---
>> changes since v2
>> update the cc list
>>
>>  drivers/i2c/busses/i2c-cadence.c |   73 
>> --
>>  1 files changed, 46 insertions(+), 27 deletions(-)
>>
>> diff --git a/drivers/i2c/busses/i2c-cadence.c 
>> b/drivers/i2c/busses/i2c-cadence.c
>> index 84deed6..6b08d16 100644
>> --- a/drivers/i2c/busses/i2c-cadence.c
>> +++ b/drivers/i2c/busses/i2c-cadence.c
>> @@ -18,6 +18,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>
>>  /* Register offsets for the I2C device. */
>>  #define CDNS_I2C_CR_OFFSET   0x00 /* Control Register, RW */
>> @@ -96,6 +97,8 @@
>>CDNS_I2C_IXR_COMP)
>>
>>  #define CDNS_I2C_TIMEOUT msecs_to_jiffies(1000)
>> +/* timeout for pm runtime autosuspend */
>> +#define CNDS_I2C_PM_TIMEOUT  1000/* ms */
>>
>>  #define CDNS_I2C_FIFO_DEPTH  16
>>  /* FIFO depth at which the DATA interrupt occurs */
>> @@ -128,7 +131,6 @@
>>   * @xfer_done:   Transfer complete status
>>   * @p_send_buf:  Pointer to transmit buffer
>>   * @p_recv_buf:  Pointer to receive buffer
>> - * @suspended:   Flag holding the device's PM status
>>   * @send_count:  Number of bytes still expected to send
>>   * @recv_count:  Number of bytes still expected to receive
>>   * @curr_recv_count: Number of bytes to be received in current transfer
>> @@ -141,6 +143,7 @@
>>   * @quirks:  flag for broken hold bit usage in r1p10
>>   */
>>  struct cdns_i2c {
>> + struct device   *dev;
>>   void __iomem *membase;
>>   struct i2c_adapter adap;
>>   struct i2c_msg *p_msg;
>> @@ -148,7 +151,6 @@ struct cdns_i2c {
>>   struct completion xfer_done;
>>   unsigned char *p_send_buf;
>>   unsigned char *p_recv_buf;
>> - u8 suspended;
>
> There might have been a reason to store this flag here. Did you test
> this with lockdep and CONFIG_DEBUG_ATOMIC_SLEEP? Just to make sure that
> nothing that can sleep is called from atomic context.
Done now.


Essentially this is a flag is set in suspend routine. and checked in
the isr I use
pm_runtime_suspended(id->dev) instead.

>
> Sören
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCHv2] i2c: cadence: Enable power management

2015-10-28 Thread Shubhrajyoti Datta
Currently the clocks are enabled at probe and disabled at remove.
This patch enables the clocks at the start of transfer and disables
after it.

Also adapts to runtime pm.
Remove xi2c->suspended and use pm runtime status instead.

converts dev pm to const to silence a checkpatch warning.

Signed-off-by: Shubhrajyoti Datta 
---
changes since v1:
update the cc list.

 drivers/i2c/busses/i2c-cadence.c |   74 --
 1 files changed, 47 insertions(+), 27 deletions(-)

diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c
index f5227c5..ba3c67c 100644
--- a/drivers/i2c/busses/i2c-cadence.c
+++ b/drivers/i2c/busses/i2c-cadence.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* Register offsets for the I2C device. */
 #define CDNS_I2C_CR_OFFSET 0x00 /* Control Register, RW */
@@ -98,6 +99,8 @@
 CDNS_I2C_IXR_COMP)
 
 #define CDNS_I2C_TIMEOUT   msecs_to_jiffies(1000)
+/* timeout for pm runtime autosuspend */
+#define CNDS_I2C_PM_TIMEOUT1000/* ms */
 
 #define CDNS_I2C_FIFO_DEPTH16
 /* FIFO depth at which the DATA interrupt occurs */
@@ -130,7 +133,6 @@
  * @xfer_done: Transfer complete status
  * @p_send_buf:Pointer to transmit buffer
  * @p_recv_buf:Pointer to receive buffer
- * @suspended: Flag holding the device's PM status
  * @send_count:Number of bytes still expected to send
  * @recv_count:Number of bytes still expected to receive
  * @curr_recv_count:   Number of bytes to be received in current transfer
@@ -143,6 +145,7 @@
  * @quirks:flag for broken hold bit usage in r1p10
  */
 struct cdns_i2c {
+   struct device   *dev;
void __iomem *membase;
struct i2c_adapter adap;
struct i2c_msg *p_msg;
@@ -150,7 +153,6 @@ struct cdns_i2c {
struct completion xfer_done;
unsigned char *p_send_buf;
unsigned char *p_recv_buf;
-   u8 suspended;
unsigned int send_count;
unsigned int recv_count;
unsigned int curr_recv_count;
@@ -623,10 +625,16 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, 
struct i2c_msg *msgs,
u32 reg;
struct cdns_i2c *id = adap->algo_data;
bool hold_quirk;
+
+   ret = pm_runtime_get_sync(id->dev);
+   if (ret < 0)
+   return ret;
/* Check if the bus is free */
if (msgs->len)
-   if (cdns_i2c_readreg(CDNS_I2C_SR_OFFSET) & CDNS_I2C_SR_BA)
-   return -EAGAIN;
+   if (cdns_i2c_readreg(CDNS_I2C_SR_OFFSET) & CDNS_I2C_SR_BA) {
+   ret = -EAGAIN;
+   goto out;
+   }
 
hold_quirk = !!(id->quirks & CDNS_I2C_BROKEN_HOLD_BIT);
/*
@@ -645,7 +653,8 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, 
struct i2c_msg *msgs,
if (msgs[count].flags & I2C_M_RD) {
dev_warn(adap->dev.parent,
 "Can't do repeated start after a 
receive message\n");
-   return -EOPNOTSUPP;
+   ret = -EOPNOTSUPP;
+   goto out;
}
}
id->bus_hold_flag = 1;
@@ -663,20 +672,26 @@ static int cdns_i2c_master_xfer(struct i2c_adapter *adap, 
struct i2c_msg *msgs,
 
ret = cdns_i2c_process_msg(id, msgs, adap);
if (ret)
-   return ret;
+   goto out;
 
/* Report the other error interrupts to application */
if (id->err_status) {
cdns_i2c_master_reset(adap);
 
-   if (id->err_status & CDNS_I2C_IXR_NACK)
-   return -ENXIO;
-
-   return -EIO;
+   if (id->err_status & CDNS_I2C_IXR_NACK) {
+   ret = -ENXIO;
+   goto out;
+   }
+   ret = -EIO;
+   goto out;
}
}
 
-   return num;
+   ret = num;
+out:
+   pm_runtime_mark_last_busy(id->dev);
+   pm_runtime_put_autosuspend(id->dev);
+   return ret;
 }
 
 /**
@@ -815,7 +830,7 @@ static int cdns_i2c_clk_notifier_cb(struct notifier_block 
*nb, unsigned long
struct clk_notifier_data *ndata = data;
struct cdns_i2c *id = to_cdns_i2c(nb);
 
-   if (id->suspended)
+   if (pm_runtime_suspended(id->dev))
return NOTIFY_OK;
 
switch (event) {
@@ -863,14 +878,12 @@ static int cdns_i2c_clk_notifier_cb(struct notifier_block 
*nb, unsigned long
  *
  * Return: 0 always
  

  1   2   3   4   >