Re: [PATCH 3/4] gpio: ptxpmb-ext-cpld: Add driver for Juniper's PTXPMB extended CPLD

2016-10-21 Thread Linus Walleij
On Fri, Oct 7, 2016 at 5:19 PM, Pantelis Antoniou
 wrote:

> From: Guenter Roeck 
>
> This IP block is present in the PTXPMB extended CPLD present on
> Junipers PTX series of routers and provides SIB connector status pins
> as GPIO pins for use with other drivers.
>
> Signed-off-by: Guenter Roeck 
> Signed-off-by: JawaharBalaji Thirumalaisamy 
> [Ported from Juniper kernel]
> Signed-off-by: Pantelis Antoniou 

This driver has pretty much the same issues as the two others
I reviewed yesterday. Please address the same comments
and repost and I will look at it again!

Yours,
Linus Walleij


[PATCH 3/4] gpio: ptxpmb-ext-cpld: Add driver for Juniper's PTXPMB extended CPLD

2016-10-07 Thread Pantelis Antoniou
From: Guenter Roeck 

This IP block is present in the PTXPMB extended CPLD present on
Junipers PTX series of routers and provides SIB connector status pins
as GPIO pins for use with other drivers.

Signed-off-by: Guenter Roeck 
Signed-off-by: JawaharBalaji Thirumalaisamy 
[Ported from Juniper kernel]
Signed-off-by: Pantelis Antoniou 
---
 drivers/gpio/Kconfig|  11 +
 drivers/gpio/Makefile   |   1 +
 drivers/gpio/gpio-ptxpmb-ext-cpld.c | 430 
 3 files changed, 442 insertions(+)
 create mode 100644 drivers/gpio/gpio-ptxpmb-ext-cpld.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index c25dbe9..281029b 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -371,6 +371,17 @@ config GPIO_PTXPMB_CPLD
  This driver can also be built as a module.  If so, the module
  will be called gpio-ptxpmb-cpld.
 
+config GPIO_PTXPMB_EXT_CPLD
+   tristate "PTXPMB Extended CPLD GPIO"
+   depends on MFD_JUNIPER_EXT_CPLD
+   default y if MFD_JUNIPER_EXT_CPLD
+   help
+ This driver exports various bits on the Juniper Control Board
+ Extended CPLD as GPIO pins to userspace.
+
+ This driver can also be built as a module.  If so, the module
+ will be called gpio-ptxpmb-ext-cpld.
+
 config GPIO_PXA
bool "PXA GPIO support"
depends on ARCH_PXA || ARCH_MMP
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 6691d8c..ec890c7 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -91,6 +91,7 @@ obj-$(CONFIG_GPIO_PCH)+= gpio-pch.o
 obj-$(CONFIG_GPIO_PISOSR)  += gpio-pisosr.o
 obj-$(CONFIG_GPIO_PL061)   += gpio-pl061.o
 obj-$(CONFIG_GPIO_PTXPMB_CPLD) += gpio-ptxpmb-cpld.o
+obj-$(CONFIG_GPIO_PTXPMB_EXT_CPLD) += gpio-ptxpmb-ext-cpld.o
 obj-$(CONFIG_GPIO_PXA) += gpio-pxa.o
 obj-$(CONFIG_GPIO_RC5T583) += gpio-rc5t583.o
 obj-$(CONFIG_GPIO_RDC321X) += gpio-rdc321x.o
diff --git a/drivers/gpio/gpio-ptxpmb-ext-cpld.c 
b/drivers/gpio/gpio-ptxpmb-ext-cpld.c
new file mode 100644
index 000..0152f0b
--- /dev/null
+++ b/drivers/gpio/gpio-ptxpmb-ext-cpld.c
@@ -0,0 +1,430 @@
+/*
+ * Copyright (C) 2012 Juniper networks
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#define EXT_CPLD_NGPIO 32  /*  0..15: SIB presence bits*/
+   /* 16..31: SIB interrupt status */
+
+/**
+ * struct ext_cpld_gpio - GPIO private data structure.
+ * @base: PCI base address of Memory mapped I/O register.
+ * @dev: Pointer to device structure.
+ * @gpio: Data for GPIO infrastructure.
+ */
+struct ext_cpld_gpio {
+   void __iomem *base;
+   struct device *dev;
+   struct gpio_chip gpio;
+   struct mutex irq_lock;
+   struct mutex work_lock;
+   struct irq_domain *domain;
+   int irq;
+   u8 irq_type[EXT_CPLD_NGPIO];
+   u16 sib_presence_cache;
+   u16 sib_presence_irq_enabled;
+   u16 sib_irq_status_cache;
+   u16 sib_irq_enabled;
+   struct delayed_work work;
+};
+
+static int ext_cpld_gpio_get(struct gpio_chip *gpio, unsigned int nr)
+{
+   struct ext_cpld_gpio *chip = container_of(gpio,
+ struct ext_cpld_gpio, gpio);
+   struct pmb_boot_cpld_ext *cpld = chip->base;
+   u16 *addr = nr < 16 ? >sib_presence : >sib_irq_status;
+   u16 val;
+
+   val = ioread16(addr);
+   if (nr < 16)
+   chip->sib_presence_cache = val;
+   else
+   chip->sib_irq_status_cache = val;
+
+   return !!(val & (1 << (nr & 15)));
+}
+
+static int ext_cpld_gpio_direction_input(struct gpio_chip *gpio,
+unsigned int nr)
+{
+   /* all pins are input pins */
+   return 0;
+}
+
+static int ext_cpld_gpio_to_irq(struct gpio_chip *gpio, unsigned int offset)
+{
+   struct ext_cpld_gpio *chip = container_of(gpio,
+ struct ext_cpld_gpio, gpio);
+
+   return irq_create_mapping(chip->domain, offset);
+}
+
+static void ext_cpld_irq_mask(struct irq_data *data)
+{
+   struct ext_cpld_gpio *chip = irq_data_get_irq_chip_data(data);
+   struct pmb_boot_cpld_ext *cpld = chip->base;
+   u16 *addr = data->hwirq < 16 ?
+