Re: [PATCH V2 2/3] gpio: xilinx: Add interrupt support

2020-07-24 Thread Robert Hancock

On 2020-07-23 12:03 p.m., Andy Shevchenko wrote:

+/**
+ * xgpio_xlate - Translate gpio_spec to the GPIO number and flags
+ * @gc: Pointer to gpio_chip device structure.
+ * @gpiospec:  gpio specifier as found in the device tree
+ * @flags: A flags pointer based on binding
+ *
+ * Return:
+ * irq number otherwise -EINVAL
+ */
+static int xgpio_xlate(struct gpio_chip *gc,
+  const struct of_phandle_args *gpiospec, u32 *flags)
+{
+   if (gc->of_gpio_n_cells < 2) {
+   WARN_ON(1);
+   return -EINVAL;
+   }
+
+   if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
+   return -EINVAL;
+
+   if (gpiospec->args[0] >= gc->ngpio)
+   return -EINVAL;
+
+   if (flags)
+   *flags = gpiospec->args[1];
+
+   return gpiospec->args[0];
+}


This looks like a very standart xlate function for GPIO. Why do you
need to open-code it?


Indeed, this seems the same as the of_gpio_simple_xlate callback which 
is used if no xlate callback is specified, so I'm not sure why this is 
necessary?




...


+/**
+ * xgpio_irq_ack - Acknowledge a child GPIO interrupt.



+ * This currently does nothing, but irq_ack is unconditionally called by
+ * handle_edge_irq and therefore must be defined.


This should go after parameter description(s).


+ * @irq_data: per irq and chip data passed down to chip functions
+ */


...


  /**
+ * xgpio_irq_mask - Write the specified signal of the GPIO device.
+ * @irq_data: per irq and chip data passed down to chip functions


In all comments irq -> IRQ.


+ */
+static void xgpio_irq_mask(struct irq_data *irq_data)
+{
+   unsigned long flags;
+   struct xgpio_instance *chip = irq_data_get_irq_chip_data(irq_data);
+   int irq_offset = irqd_to_hwirq(irq_data);
+   int index = xgpio_index(chip, irq_offset);
+   int offset = xgpio_offset(chip, irq_offset);
+
+   spin_lock_irqsave(>gpio_lock, flags);
+



+   chip->irq_enable[index] &= ~BIT(offset);


If you convert your data structure to use bitmaps (and respective API) like

#define XILINX_NGPIOS  64
...
   DECLARE_BITMAP(irq_enable, XILINX_NGPIOS);
...

it will make code better to read and understand. For example, here it
will be just
__clear_bit(offset, chip->irq_enable);


+   dev_dbg(chip->gc.parent, "Disable %d irq, irq_enable_mask 0x%x\n",
+   irq_offset, chip->irq_enable[index]);


Under spin lock?! Hmm...


+   if (!chip->irq_enable[index]) {
+   /* Disable per channel interrupt */
+   u32 temp = xgpio_readreg(chip->regs + XGPIO_IPIER_OFFSET);
+
+   temp &= ~BIT(index);
+   xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, temp);
+   }
+   spin_unlock_irqrestore(>gpio_lock, flags);
+}


...


+   for (index = 0; index < num_channels; index++) {
+   if ((status & BIT(index))) {


If gpio_width is the same among banks, you can use for_each_set_bit()
here as well.

...


+   for_each_set_bit(bit, _events, 32) {
+   generic_handle_irq(irq_find_mapping
+   (chip->gc.irq.domain, offset + bit));


Strange indentation. Maybe a temporary variable helps?

...


+   chip->irq = platform_get_irq_optional(pdev, 0);
+   if (chip->irq <= 0) {
+   dev_info(>dev, "GPIO IRQ not set\n");


Why do you need an optional variant if you print an error anyway?


+   } else {



...


+   chip->gc.irq.parents = (unsigned int *)>irq;
+   chip->gc.irq.num_parents = 1;


Current pattern is to use devm_kcalloc() for it (Linus has plans to
simplify this in the future and this will help him to find what
patterns are being used)



--
Robert Hancock
Senior Hardware Designer
SED Systems, a division of Calian Ltd.
Email: hanc...@sedsystems.ca


Re: [PATCH V2 2/3] gpio: xilinx: Add interrupt support

2020-07-24 Thread Andy Shevchenko
On Fri, Jul 24, 2020 at 8:15 PM Srinivas Neeli  wrote:

...

> > > +#include 
> >
> > Not sure I see a user of it.
> >
> > ...
> we are using chained_irq_enter() and chained_irq_exit()
> APIs , so need "chained_irq.h"

I see.  But gpio/driver.h does it for you.

...

> > > +   for (index = 0; index < num_channels; index++) {
> > > +   if ((status & BIT(index))) {
> >
> > If gpio_width is the same among banks, you can use for_each_set_bit()
> > here as well.
> >
> > ...
> gpio_wdith vary depends on design. We can configure gpio pins for each bank.

I see.

...

> > > +   chip->irq = platform_get_irq_optional(pdev, 0);
> > > +   if (chip->irq <= 0) {
> > > +   dev_info(>dev, "GPIO IRQ not set\n");
> >
> > Why do you need an optional variant if you print an error anyway?
>
> Here intention is just printing a debug message to user.

Debug message should be debug, and not info. But in any case, I would
rather drop it, or use platform_get_irq() b/c now you have a code
controversy.

...

> > > +   chip->gc.irq.parents = (unsigned int *)>irq;
> > > +   chip->gc.irq.num_parents = 1;
> >
> > Current pattern is to use devm_kcalloc() for it (Linus has plans to
> > simplify this in the future and this will help him to find what
> > patterns are being used)
>
> I didn't get this , Could you please explain more.

  girq->num_parents = 1;
  girq->parents = devm_kcalloc(dev, girq->num_parents, ...);
   if (!girq->parents)
 return -ENOMEM;

girq->parents[0] = chip->irq;

Also, use temporary variable for IRQ chip structure:
 girq = >gc.irq;


-- 
With Best Regards,
Andy Shevchenko


RE: [PATCH V2 2/3] gpio: xilinx: Add interrupt support

2020-07-24 Thread Srinivas Neeli
Hi Andy Shevchenko,

Thanks for the review.

Accepted comments will address in V3 and Added few comments in inline.

> -Original Message-
> From: Andy Shevchenko 
> Sent: Thursday, July 23, 2020 11:33 PM
> To: Srinivas Neeli 
> Cc: Linus Walleij ; Bartosz Golaszewski
> ; Michal Simek ;
> Shubhrajyoti Datta ; Srinivas Goud
> ; open list:GPIO SUBSYSTEM  g...@vger.kernel.org>; linux-arm Mailing List  ker...@lists.infradead.org>; Linux Kernel Mailing List  ker...@vger.kernel.org>; git 
> Subject: Re: [PATCH V2 2/3] gpio: xilinx: Add interrupt support
> 
> On Thu, Jul 23, 2020 at 5:08 PM Srinivas Neeli 
> wrote:
> >
> > Adds interrupt support to the Xilinx GPIO driver so that rising and
> > falling edge line events can be supported. Since interrupt support is
> > an optional feature in the Xilinx IP, the driver continues to support
> > devices which have no interrupt provided.
> 
> ...
> 
> > +#include 
> 
> Not sure I see a user of it.
> 
> ...
we are using chained_irq_enter() and chained_irq_exit()
APIs , so need "chained_irq.h"
> 
> > +/**
> > + * xgpio_xlate - Translate gpio_spec to the GPIO number and flags
> > + * @gc: Pointer to gpio_chip device structure.
> > + * @gpiospec:  gpio specifier as found in the device tree
> > + * @flags: A flags pointer based on binding
> > + *
> > + * Return:
> > + * irq number otherwise -EINVAL
> > + */
> > +static int xgpio_xlate(struct gpio_chip *gc,
> > +  const struct of_phandle_args *gpiospec, u32
> > +*flags) {
> > +   if (gc->of_gpio_n_cells < 2) {
> > +   WARN_ON(1);
> > +   return -EINVAL;
> > +   }
> > +
> > +   if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
> > +   return -EINVAL;
> > +
> > +   if (gpiospec->args[0] >= gc->ngpio)
> > +   return -EINVAL;
> > +
> > +   if (flags)
> > +   *flags = gpiospec->args[1];
> > +
> > +   return gpiospec->args[0];
> > +}
> 
> This looks like a very standart xlate function for GPIO. Why do you need to
> open-code it?
> 
> ...
> 
> > +/**
> > + * xgpio_irq_ack - Acknowledge a child GPIO interrupt.
> 
> > + * This currently does nothing, but irq_ack is unconditionally called
> > + by
> > + * handle_edge_irq and therefore must be defined.
> 
> This should go after parameter description(s).
> 
> > + * @irq_data: per irq and chip data passed down to chip functions */
> 
> ...
> 
> >  /**
> > + * xgpio_irq_mask - Write the specified signal of the GPIO device.
> > + * @irq_data: per irq and chip data passed down to chip functions
> 
> In all comments irq -> IRQ.
> 
> > + */
> > +static void xgpio_irq_mask(struct irq_data *irq_data)
> > +{
> > +   unsigned long flags;
> > +   struct xgpio_instance *chip = irq_data_get_irq_chip_data(irq_data);
> > +   int irq_offset = irqd_to_hwirq(irq_data);
> > +   int index = xgpio_index(chip, irq_offset);
> > +   int offset = xgpio_offset(chip, irq_offset);
> > +
> > +   spin_lock_irqsave(>gpio_lock, flags);
> > +
> 
> > +   chip->irq_enable[index] &= ~BIT(offset);
> 
> If you convert your data structure to use bitmaps (and respective API) like
> 
> #define XILINX_NGPIOS  64
> ...
>   DECLARE_BITMAP(irq_enable, XILINX_NGPIOS);
> ...
> 
> it will make code better to read and understand. For example, here it
> will be just
> __clear_bit(offset, chip->irq_enable);
> 
> > +   dev_dbg(chip->gc.parent, "Disable %d irq, irq_enable_mask 0x%x\n",
> > +   irq_offset, chip->irq_enable[index]);
> 
> Under spin lock?! Hmm...
> 
> > +   if (!chip->irq_enable[index]) {
> > +   /* Disable per channel interrupt */
> > +   u32 temp = xgpio_readreg(chip->regs + XGPIO_IPIER_OFFSET);
> > +
> > +   temp &= ~BIT(index);
> > +   xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, temp);
> > +   }
> > +   spin_unlock_irqrestore(>gpio_lock, flags);
> > +}
> 
> ...
> 
> > +   for (index = 0; index < num_channels; index++) {
> > +   if ((status & BIT(index))) {
> 
> If gpio_width is the same among banks, you can use for_each_set_bit()
> here as well.
> 
> ...
gpio_wdith vary depends on design. We can configure gpio pins for each bank.

> 
> > +   for_each_set_bit(bit, _events, 32

RE: [PATCH V2 2/3] gpio: xilinx: Add interrupt support

2020-07-24 Thread Srinivas Neeli
Hi Linus,

Thanks for the review

> -Original Message-
> From: Linus Walleij 
> Sent: Friday, July 24, 2020 2:52 PM
> To: kernel test robot 
> Cc: Srinivas Neeli ; Bartosz Golaszewski
> ; Michal Simek ;
> Shubhrajyoti Datta ; Srinivas Goud
> ; kbuild-...@lists.01.org; open list:GPIO SUBSYSTEM
> ; Linux ARM  ker...@lists.infradead.org>; linux-kernel@vger.kernel.org; git
> 
> Subject: Re: [PATCH V2 2/3] gpio: xilinx: Add interrupt support
> 
> On Fri, Jul 24, 2020 at 6:12 AM kernel test robot  wrote:
> 
> >drivers/gpio/gpio-xilinx.c: In function 'xgpio_probe':
> >drivers/gpio/gpio-xilinx.c:638:10: error: 'struct gpio_chip' has no 
> > member
> named 'of_gpio_n_cells'
> >  638 |  chip->gc.of_gpio_n_cells = cells;
> >  |  ^
> > >> drivers/gpio/gpio-xilinx.c:639:10: error: 'struct gpio_chip' has no
> member named 'of_xlate'
> >  639 |  chip->gc.of_xlate = xgpio_xlate;
> >  |  ^
> 
> This is probably because your driver needs:
> 
> depends on OF_GPIO
> 
> in KConfig
> 
I will address in v3.

> Yours,
> Linus Walleij


Re: [PATCH V2 2/3] gpio: xilinx: Add interrupt support

2020-07-24 Thread Linus Walleij
On Fri, Jul 24, 2020 at 6:12 AM kernel test robot  wrote:

>drivers/gpio/gpio-xilinx.c: In function 'xgpio_probe':
>drivers/gpio/gpio-xilinx.c:638:10: error: 'struct gpio_chip' has no member 
> named 'of_gpio_n_cells'
>  638 |  chip->gc.of_gpio_n_cells = cells;
>  |  ^
> >> drivers/gpio/gpio-xilinx.c:639:10: error: 'struct gpio_chip' has no member 
> >> named 'of_xlate'
>  639 |  chip->gc.of_xlate = xgpio_xlate;
>  |  ^

This is probably because your driver needs:

depends on OF_GPIO

in KConfig

Yours,
Linus Walleij


Re: [PATCH V2 2/3] gpio: xilinx: Add interrupt support

2020-07-23 Thread kernel test robot
Hi Srinivas,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on gpio/for-next]
[also build test ERROR on linus/master v5.8-rc6 next-20200723]
[cannot apply to xlnx/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Srinivas-Neeli/gpio-xilinx-Update-on-xilinx-gpio-driver/20200723-220826
base:   https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git 
for-next
config: x86_64-randconfig-a003-20200723 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-14) 9.3.0
reproduce (this is a W=1 build):
# save the attached .config to linux build tree
make W=1 ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All errors (new ones prefixed by >>):

   drivers/gpio/gpio-xilinx.c: In function 'xgpio_xlate':
>> drivers/gpio/gpio-xilinx.c:325:8: error: 'struct gpio_chip' has no member 
>> named 'of_gpio_n_cells'
 325 |  if (gc->of_gpio_n_cells < 2) {
 |^~
   In file included from arch/x86/include/asm/bug.h:92,
from include/linux/bug.h:5,
from include/linux/thread_info.h:12,
from arch/x86/include/asm/preempt.h:7,
from include/linux/preempt.h:78,
from include/linux/spinlock.h:51,
from include/linux/seqlock.h:36,
from include/linux/time.h:6,
from include/linux/stat.h:19,
from include/linux/module.h:13,
from drivers/gpio/gpio-xilinx.c:11:
   drivers/gpio/gpio-xilinx.c:330:39: error: 'struct gpio_chip' has no member 
named 'of_gpio_n_cells'
 330 |  if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
 |   ^~
   include/asm-generic/bug.h:118:25: note: in definition of macro 'WARN_ON'
 118 |  int __ret_warn_on = !!(condition);\
 | ^
   drivers/gpio/gpio-xilinx.c: In function 'xgpio_probe':
   drivers/gpio/gpio-xilinx.c:638:10: error: 'struct gpio_chip' has no member 
named 'of_gpio_n_cells'
 638 |  chip->gc.of_gpio_n_cells = cells;
 |  ^
>> drivers/gpio/gpio-xilinx.c:639:10: error: 'struct gpio_chip' has no member 
>> named 'of_xlate'
 639 |  chip->gc.of_xlate = xgpio_xlate;
 |  ^

vim +325 drivers/gpio/gpio-xilinx.c

   312  
   313  /**
   314   * xgpio_xlate - Translate gpio_spec to the GPIO number and flags
   315   * @gc: Pointer to gpio_chip device structure.
   316   * @gpiospec:  gpio specifier as found in the device tree
   317   * @flags: A flags pointer based on binding
   318   *
   319   * Return:
   320   * irq number otherwise -EINVAL
   321   */
   322  static int xgpio_xlate(struct gpio_chip *gc,
   323 const struct of_phandle_args *gpiospec, u32 
*flags)
   324  {
 > 325  if (gc->of_gpio_n_cells < 2) {
   326  WARN_ON(1);
   327  return -EINVAL;
   328  }
   329  
   330  if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
   331  return -EINVAL;
   332  
   333  if (gpiospec->args[0] >= gc->ngpio)
   334  return -EINVAL;
   335  
   336  if (flags)
   337  *flags = gpiospec->args[1];
   338  
   339  return gpiospec->args[0];
   340  }
   341  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip


Re: [PATCH V2 2/3] gpio: xilinx: Add interrupt support

2020-07-23 Thread Andy Shevchenko
On Thu, Jul 23, 2020 at 5:08 PM Srinivas Neeli
 wrote:
>
> Adds interrupt support to the Xilinx GPIO driver so that rising and
> falling edge line events can be supported. Since interrupt support is
> an optional feature in the Xilinx IP, the driver continues to support
> devices which have no interrupt provided.

...

> +#include 

Not sure I see a user of it.

...

> +/**
> + * xgpio_xlate - Translate gpio_spec to the GPIO number and flags
> + * @gc: Pointer to gpio_chip device structure.
> + * @gpiospec:  gpio specifier as found in the device tree
> + * @flags: A flags pointer based on binding
> + *
> + * Return:
> + * irq number otherwise -EINVAL
> + */
> +static int xgpio_xlate(struct gpio_chip *gc,
> +  const struct of_phandle_args *gpiospec, u32 *flags)
> +{
> +   if (gc->of_gpio_n_cells < 2) {
> +   WARN_ON(1);
> +   return -EINVAL;
> +   }
> +
> +   if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells))
> +   return -EINVAL;
> +
> +   if (gpiospec->args[0] >= gc->ngpio)
> +   return -EINVAL;
> +
> +   if (flags)
> +   *flags = gpiospec->args[1];
> +
> +   return gpiospec->args[0];
> +}

This looks like a very standart xlate function for GPIO. Why do you
need to open-code it?

...

> +/**
> + * xgpio_irq_ack - Acknowledge a child GPIO interrupt.

> + * This currently does nothing, but irq_ack is unconditionally called by
> + * handle_edge_irq and therefore must be defined.

This should go after parameter description(s).

> + * @irq_data: per irq and chip data passed down to chip functions
> + */

...

>  /**
> + * xgpio_irq_mask - Write the specified signal of the GPIO device.
> + * @irq_data: per irq and chip data passed down to chip functions

In all comments irq -> IRQ.

> + */
> +static void xgpio_irq_mask(struct irq_data *irq_data)
> +{
> +   unsigned long flags;
> +   struct xgpio_instance *chip = irq_data_get_irq_chip_data(irq_data);
> +   int irq_offset = irqd_to_hwirq(irq_data);
> +   int index = xgpio_index(chip, irq_offset);
> +   int offset = xgpio_offset(chip, irq_offset);
> +
> +   spin_lock_irqsave(>gpio_lock, flags);
> +

> +   chip->irq_enable[index] &= ~BIT(offset);

If you convert your data structure to use bitmaps (and respective API) like

#define XILINX_NGPIOS  64
...
  DECLARE_BITMAP(irq_enable, XILINX_NGPIOS);
...

it will make code better to read and understand. For example, here it
will be just
__clear_bit(offset, chip->irq_enable);

> +   dev_dbg(chip->gc.parent, "Disable %d irq, irq_enable_mask 0x%x\n",
> +   irq_offset, chip->irq_enable[index]);

Under spin lock?! Hmm...

> +   if (!chip->irq_enable[index]) {
> +   /* Disable per channel interrupt */
> +   u32 temp = xgpio_readreg(chip->regs + XGPIO_IPIER_OFFSET);
> +
> +   temp &= ~BIT(index);
> +   xgpio_writereg(chip->regs + XGPIO_IPIER_OFFSET, temp);
> +   }
> +   spin_unlock_irqrestore(>gpio_lock, flags);
> +}

...

> +   for (index = 0; index < num_channels; index++) {
> +   if ((status & BIT(index))) {

If gpio_width is the same among banks, you can use for_each_set_bit()
here as well.

...

> +   for_each_set_bit(bit, _events, 32) {
> +   generic_handle_irq(irq_find_mapping
> +   (chip->gc.irq.domain, offset + bit));

Strange indentation. Maybe a temporary variable helps?

...

> +   chip->irq = platform_get_irq_optional(pdev, 0);
> +   if (chip->irq <= 0) {
> +   dev_info(>dev, "GPIO IRQ not set\n");

Why do you need an optional variant if you print an error anyway?

> +   } else {


...

> +   chip->gc.irq.parents = (unsigned int *)>irq;
> +   chip->gc.irq.num_parents = 1;

Current pattern is to use devm_kcalloc() for it (Linus has plans to
simplify this in the future and this will help him to find what
patterns are being used)

-- 
With Best Regards,
Andy Shevchenko