linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 0/6] GPIO & Hierarchy IRQ support for HiFive Unleashed
@ 2019-12-10 11:11 Yash Shah
  2019-12-10 11:11 ` [PATCH v4 1/6] genirq: introduce irq_domain_translate_onecell Yash Shah
                   ` (7 more replies)
  0 siblings, 8 replies; 16+ messages in thread
From: Yash Shah @ 2019-12-10 11:11 UTC (permalink / raw)
  To: linus.walleij, bgolaszewski, robh+dt, mark.rutland, palmer,
	paul.walmsley
  Cc: aou, tglx, jason, maz, bmeng.cn, atish.patra, sagar.kadam,
	linux-gpio, devicetree, linux-riscv, linux-kernel, sachin.ghadi,
	Yash Shah

This patch series adds GPIO drivers, DT documentation and DT nodes for
HiFive Unleashed board. The gpio patches are mostly based on Wesley's patch.
The patchset also adds hierarchy irq domain support as it is required by this
gpio driver. It also includes the irqdomain patch to introduce
irq_domain_translate_onecell() and irq-nvic driver patch to use this newly
introduced function.

This patchset is based on Linux 5.4-rc6 and tested on HiFive Unleashed board

Changes:
v4 vs v3:
- Rename the DT yaml document to more standard naming (sifive,gpio.yaml)
- Drop "clock-names" property from yaml document
- Add "minItems" to "interrupts" node in yaml

v3 vs v2:
- Include patch for irq-nvic driver to use irq_domain_translate_onecell
- Remove unnecessary inclusion of header files
- Use a single prefix for all symbols in this driver
- Rename the "enabled" field of struct sifive_gpio to "irq_state"
- Remove unused variables and locking from probe()
- Other minor changes

v2 vs v1:
- Add patch to introduce irq_domain_translate_onecell() and use it in
  the sifive PLIC driver
- Drop the usage of own locks, instead use internal bgpio_locks
- Consistently use regmap for register access throughout the gpio code
- Convert the GPIO DT documentation into a json schema
- Other minor changes based upon feedback received on v1

v1 vs RFC:
Incorporated below changes as suggested by Linus Walleij on RFC version of this
patchset[0]
- Dropped PWM patches as they are already merged.
- Include "GPIO_GENERIC" and "REGMAP_MMIO" in Kconfig select option
- Remove unwanted inclusion of header files
- Use regmap MMIO instead of customised sifive_assign_bit()
- Use GPIOLIB_GENERIC and bgpio_init() to set up the accessors
- Use hierarchical irqdomain

[0] https://lore.kernel.org/linux-riscv/20181010123519.RVexDppaPFpIWl7QU_hpP8tc5qqWPJgeuLYn0FaGbeQ@z/

Yash Shah (6):
  genirq: introduce irq_domain_translate_onecell
  irqchip: nvic: Use irq_domain_translate_onecell instead of custom func
  irqchip: sifive: Support hierarchy irq domain
  gpio: sifive: Add DT documentation for SiFive GPIO
  gpio: sifive: Add GPIO driver for SiFive SoCs
  riscv: dts: Add DT support for SiFive FU540 GPIO driver

 .../devicetree/bindings/gpio/sifive,gpio.yaml      |  68 ++++++
 arch/riscv/boot/dts/sifive/fu540-c000.dtsi         |  15 +-
 .../riscv/boot/dts/sifive/hifive-unleashed-a00.dts |   4 +
 drivers/gpio/Kconfig                               |   9 +
 drivers/gpio/Makefile                              |   1 +
 drivers/gpio/gpio-sifive.c                         | 252 +++++++++++++++++++++
 drivers/irqchip/Kconfig                            |   1 +
 drivers/irqchip/irq-nvic.c                         |  15 +-
 drivers/irqchip/irq-sifive-plic.c                  |  30 ++-
 include/linux/irqdomain.h                          |   5 +
 kernel/irq/irqdomain.c                             |  17 ++
 11 files changed, 399 insertions(+), 18 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/gpio/sifive,gpio.yaml
 create mode 100644 drivers/gpio/gpio-sifive.c

-- 
2.7.4


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

* [PATCH v4 1/6] genirq: introduce irq_domain_translate_onecell
  2019-12-10 11:11 [PATCH v4 0/6] GPIO & Hierarchy IRQ support for HiFive Unleashed Yash Shah
@ 2019-12-10 11:11 ` Yash Shah
  2020-01-24 19:11   ` [tip: irq/core] genirq: Introduce irq_domain_translate_onecell tip-bot2 for Yash Shah
  2019-12-10 11:11 ` [PATCH v4 2/6] irqchip: nvic: Use irq_domain_translate_onecell instead of custom func Yash Shah
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 16+ messages in thread
From: Yash Shah @ 2019-12-10 11:11 UTC (permalink / raw)
  To: linus.walleij, bgolaszewski, robh+dt, mark.rutland, palmer,
	paul.walmsley
  Cc: aou, tglx, jason, maz, bmeng.cn, atish.patra, sagar.kadam,
	linux-gpio, devicetree, linux-riscv, linux-kernel, sachin.ghadi,
	Yash Shah

Add a new function irq_domain_translate_onecell() that is to be used as
the translate function in struct irq_domain_ops.

Signed-off-by: Yash Shah <yash.shah@sifive.com>
---
 include/linux/irqdomain.h |  5 +++++
 kernel/irq/irqdomain.c    | 17 +++++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 583e7ab..cad9eb8 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -426,6 +426,11 @@ int irq_domain_translate_twocell(struct irq_domain *d,
 				 unsigned long *out_hwirq,
 				 unsigned int *out_type);
 
+int irq_domain_translate_onecell(struct irq_domain *d,
+				 struct irq_fwspec *fwspec,
+				 unsigned long *out_hwirq,
+				 unsigned int *out_type);
+
 /* IPI functions */
 int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest);
 int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest);
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 132672b..cf57d87d 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -987,6 +987,23 @@ const struct irq_domain_ops irq_domain_simple_ops = {
 EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
 
 /**
+ * irq_domain_translate_onecell() - Generic translate for direct one cell
+ * bindings
+ */
+int irq_domain_translate_onecell(struct irq_domain *d,
+				 struct irq_fwspec *fwspec,
+				 unsigned long *out_hwirq,
+				 unsigned int *out_type)
+{
+	if (WARN_ON(fwspec->param_count < 1))
+		return -EINVAL;
+	*out_hwirq = fwspec->param[0];
+	*out_type = IRQ_TYPE_NONE;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(irq_domain_translate_onecell);
+
+/**
  * irq_domain_translate_twocell() - Generic translate for direct two cell
  * bindings
  *
-- 
2.7.4


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

* [PATCH v4 2/6] irqchip: nvic: Use irq_domain_translate_onecell instead of custom func
  2019-12-10 11:11 [PATCH v4 0/6] GPIO & Hierarchy IRQ support for HiFive Unleashed Yash Shah
  2019-12-10 11:11 ` [PATCH v4 1/6] genirq: introduce irq_domain_translate_onecell Yash Shah
@ 2019-12-10 11:11 ` Yash Shah
  2020-01-24 19:11   ` [tip: irq/core] irqchip/nvic: " tip-bot2 for Yash Shah
  2019-12-10 11:11 ` [PATCH v4 3/6] irqchip: sifive: Support hierarchy irq domain Yash Shah
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 16+ messages in thread
From: Yash Shah @ 2019-12-10 11:11 UTC (permalink / raw)
  To: linus.walleij, bgolaszewski, robh+dt, mark.rutland, palmer,
	paul.walmsley
  Cc: aou, tglx, jason, maz, bmeng.cn, atish.patra, sagar.kadam,
	linux-gpio, devicetree, linux-riscv, linux-kernel, sachin.ghadi,
	Yash Shah

Make use of newly introduced irq_domain_translate_onecell() instead of
custom made function.

Signed-off-by: Yash Shah <yash.shah@sifive.com>
---
 drivers/irqchip/irq-nvic.c | 15 ++-------------
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/drivers/irqchip/irq-nvic.c b/drivers/irqchip/irq-nvic.c
index a166d30..f747e22 100644
--- a/drivers/irqchip/irq-nvic.c
+++ b/drivers/irqchip/irq-nvic.c
@@ -45,17 +45,6 @@ nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs)
 	handle_IRQ(irq, regs);
 }
 
-static int nvic_irq_domain_translate(struct irq_domain *d,
-				     struct irq_fwspec *fwspec,
-				     unsigned long *hwirq, unsigned int *type)
-{
-	if (WARN_ON(fwspec->param_count < 1))
-		return -EINVAL;
-	*hwirq = fwspec->param[0];
-	*type = IRQ_TYPE_NONE;
-	return 0;
-}
-
 static int nvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
 				unsigned int nr_irqs, void *arg)
 {
@@ -64,7 +53,7 @@ static int nvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
 	unsigned int type = IRQ_TYPE_NONE;
 	struct irq_fwspec *fwspec = arg;
 
-	ret = nvic_irq_domain_translate(domain, fwspec, &hwirq, &type);
+	ret = irq_domain_translate_onecell(domain, fwspec, &hwirq, &type);
 	if (ret)
 		return ret;
 
@@ -75,7 +64,7 @@ static int nvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
 }
 
 static const struct irq_domain_ops nvic_irq_domain_ops = {
-	.translate = nvic_irq_domain_translate,
+	.translate = irq_domain_translate_onecell,
 	.alloc = nvic_irq_domain_alloc,
 	.free = irq_domain_free_irqs_top,
 };
-- 
2.7.4


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

* [PATCH v4 3/6] irqchip: sifive: Support hierarchy irq domain
  2019-12-10 11:11 [PATCH v4 0/6] GPIO & Hierarchy IRQ support for HiFive Unleashed Yash Shah
  2019-12-10 11:11 ` [PATCH v4 1/6] genirq: introduce irq_domain_translate_onecell Yash Shah
  2019-12-10 11:11 ` [PATCH v4 2/6] irqchip: nvic: Use irq_domain_translate_onecell instead of custom func Yash Shah
@ 2019-12-10 11:11 ` Yash Shah
  2020-01-24 19:11   ` [tip: irq/core] irqchip/sifive-plic: Support irq domain hierarchy tip-bot2 for Yash Shah
  2019-12-10 11:11 ` [PATCH v4 4/6] gpio: sifive: Add DT documentation for SiFive GPIO Yash Shah
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 16+ messages in thread
From: Yash Shah @ 2019-12-10 11:11 UTC (permalink / raw)
  To: linus.walleij, bgolaszewski, robh+dt, mark.rutland, palmer,
	paul.walmsley
  Cc: aou, tglx, jason, maz, bmeng.cn, atish.patra, sagar.kadam,
	linux-gpio, devicetree, linux-riscv, linux-kernel, sachin.ghadi,
	Yash Shah

Add support for hierarchy irq domains. This is needed as pre-requisite for
gpio-sifive driver.

Signed-off-by: Yash Shah <yash.shah@sifive.com>
---
 drivers/irqchip/Kconfig           |  1 +
 drivers/irqchip/irq-sifive-plic.c | 30 ++++++++++++++++++++++++++----
 2 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index ccbb897..a398552 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -488,6 +488,7 @@ endmenu
 config SIFIVE_PLIC
 	bool "SiFive Platform-Level Interrupt Controller"
 	depends on RISCV
+	select IRQ_DOMAIN_HIERARCHY
 	help
 	   This enables support for the PLIC chip found in SiFive (and
 	   potentially other) RISC-V systems.  The PLIC controls devices
diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index 7d0a12f..1592ef2 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -154,15 +154,37 @@ static struct irq_chip plic_chip = {
 static int plic_irqdomain_map(struct irq_domain *d, unsigned int irq,
 			      irq_hw_number_t hwirq)
 {
-	irq_set_chip_and_handler(irq, &plic_chip, handle_fasteoi_irq);
-	irq_set_chip_data(irq, NULL);
+	irq_domain_set_info(d, irq, hwirq, &plic_chip, d->host_data,
+			    handle_fasteoi_irq, NULL, NULL);
 	irq_set_noprobe(irq);
 	return 0;
 }
 
+static int plic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
+				 unsigned int nr_irqs, void *arg)
+{
+	int i, ret;
+	irq_hw_number_t hwirq;
+	unsigned int type;
+	struct irq_fwspec *fwspec = arg;
+
+	ret = irq_domain_translate_onecell(domain, fwspec, &hwirq, &type);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < nr_irqs; i++) {
+		ret = plic_irqdomain_map(domain, virq + i, hwirq + i);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 static const struct irq_domain_ops plic_irqdomain_ops = {
-	.map		= plic_irqdomain_map,
-	.xlate		= irq_domain_xlate_onecell,
+	.translate	= irq_domain_translate_onecell,
+	.alloc		= plic_irq_domain_alloc,
+	.free		= irq_domain_free_irqs_top,
 };
 
 static struct irq_domain *plic_irqdomain;
-- 
2.7.4


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

* [PATCH v4 4/6] gpio: sifive: Add DT documentation for SiFive GPIO
  2019-12-10 11:11 [PATCH v4 0/6] GPIO & Hierarchy IRQ support for HiFive Unleashed Yash Shah
                   ` (2 preceding siblings ...)
  2019-12-10 11:11 ` [PATCH v4 3/6] irqchip: sifive: Support hierarchy irq domain Yash Shah
@ 2019-12-10 11:11 ` Yash Shah
  2019-12-18 20:51   ` Rob Herring
  2020-01-24 19:11   ` [tip: irq/core] gpio/sifive: " tip-bot2 for Yash Shah
  2019-12-10 11:11 ` [PATCH v4 5/6] gpio: sifive: Add GPIO driver for SiFive SoCs Yash Shah
                   ` (3 subsequent siblings)
  7 siblings, 2 replies; 16+ messages in thread
From: Yash Shah @ 2019-12-10 11:11 UTC (permalink / raw)
  To: linus.walleij, bgolaszewski, robh+dt, mark.rutland, palmer,
	paul.walmsley
  Cc: aou, tglx, jason, maz, bmeng.cn, atish.patra, sagar.kadam,
	linux-gpio, devicetree, linux-riscv, linux-kernel, sachin.ghadi,
	Yash Shah

DT json-schema for GPIO controller added.

Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Wesley W. Terpstra <wesley@sifive.com>
[Atish: Compatible string update]
Signed-off-by: Atish Patra <atish.patra@wdc.com>
Signed-off-by: Yash Shah <yash.shah@sifive.com>
---
 .../devicetree/bindings/gpio/sifive,gpio.yaml      | 68 ++++++++++++++++++++++
 1 file changed, 68 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/sifive,gpio.yaml

diff --git a/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml b/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml
new file mode 100644
index 0000000..418e838
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/sifive,gpio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SiFive GPIO controller
+
+maintainers:
+  - Yash Shah <yash.shah@sifive.com>
+  - Paul Walmsley <paul.walmsley@sifive.com>
+
+properties:
+  compatible:
+    items:
+      - const: sifive,fu540-c000-gpio
+      - const: sifive,gpio0
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    description:
+      interrupt mapping one per GPIO. Maximum 16 GPIOs.
+    minItems: 1
+    maxItems: 16
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 2
+
+  clocks:
+    maxItems: 1
+
+  "#gpio-cells":
+    const: 2
+
+  gpio-controller: true
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-controller
+  - "#interrupt-cells"
+  - clocks
+  - "#gpio-cells"
+  - gpio-controller
+
+additionalProperties: false
+
+examples:
+  - |
+      #include <dt-bindings/clock/sifive-fu540-prci.h>
+      gpio@10060000 {
+        compatible = "sifive,fu540-c000-gpio", "sifive,gpio0";
+        interrupt-parent = <&plic>;
+        interrupts = <7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22>;
+        reg = <0x0 0x10060000 0x0 0x1000>;
+        clocks = <&tlclk PRCI_CLK_TLCLK>;
+        gpio-controller;
+        #gpio-cells = <2>;
+        interrupt-controller;
+        #interrupt-cells = <2>;
+      };
+
+...
-- 
2.7.4


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

* [PATCH v4 5/6] gpio: sifive: Add GPIO driver for SiFive SoCs
  2019-12-10 11:11 [PATCH v4 0/6] GPIO & Hierarchy IRQ support for HiFive Unleashed Yash Shah
                   ` (3 preceding siblings ...)
  2019-12-10 11:11 ` [PATCH v4 4/6] gpio: sifive: Add DT documentation for SiFive GPIO Yash Shah
@ 2019-12-10 11:11 ` Yash Shah
  2020-01-24 19:11   ` [tip: irq/core] gpio/sifive: " tip-bot2 for Yash Shah
  2019-12-10 11:11 ` [PATCH v4 6/6] riscv: dts: Add DT support for SiFive FU540 GPIO driver Yash Shah
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 16+ messages in thread
From: Yash Shah @ 2019-12-10 11:11 UTC (permalink / raw)
  To: linus.walleij, bgolaszewski, robh+dt, mark.rutland, palmer,
	paul.walmsley
  Cc: aou, tglx, jason, maz, bmeng.cn, atish.patra, sagar.kadam,
	linux-gpio, devicetree, linux-riscv, linux-kernel, sachin.ghadi,
	Yash Shah

Adds the GPIO driver for SiFive RISC-V SoCs.

Reviewed-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Wesley W. Terpstra <wesley@sifive.com>
[Atish: Various fixes and code cleanup]
Signed-off-by: Atish Patra <atish.patra@wdc.com>
Signed-off-by: Yash Shah <yash.shah@sifive.com>
---
 drivers/gpio/Kconfig       |   9 ++
 drivers/gpio/Makefile      |   1 +
 drivers/gpio/gpio-sifive.c | 252 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 262 insertions(+)
 create mode 100644 drivers/gpio/gpio-sifive.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 38e096e..05e8a41 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -453,6 +453,15 @@ config GPIO_SAMA5D2_PIOBU
 	  The difference from regular GPIOs is that they
 	  maintain their value during backup/self-refresh.
 
+config GPIO_SIFIVE
+	bool "SiFive GPIO support"
+	depends on OF_GPIO
+	select GPIO_GENERIC
+	select GPIOLIB_IRQCHIP
+	select REGMAP_MMIO
+	help
+	  Say yes here to support the GPIO device on SiFive SoCs.
+
 config GPIO_SIOX
 	tristate "SIOX GPIO support"
 	depends on SIOX
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index d2fd19c..bf7984e 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -121,6 +121,7 @@ obj-$(CONFIG_ARCH_SA1100)		+= gpio-sa1100.o
 obj-$(CONFIG_GPIO_SAMA5D2_PIOBU)	+= gpio-sama5d2-piobu.o
 obj-$(CONFIG_GPIO_SCH311X)		+= gpio-sch311x.o
 obj-$(CONFIG_GPIO_SCH)			+= gpio-sch.o
+obj-$(CONFIG_GPIO_SIFIVE)		+= gpio-sifive.o
 obj-$(CONFIG_GPIO_SIOX)			+= gpio-siox.o
 obj-$(CONFIG_GPIO_SODAVILLE)		+= gpio-sodaville.o
 obj-$(CONFIG_GPIO_SPEAR_SPICS)		+= gpio-spear-spics.o
diff --git a/drivers/gpio/gpio-sifive.c b/drivers/gpio/gpio-sifive.c
new file mode 100644
index 0000000..147a1bd
--- /dev/null
+++ b/drivers/gpio/gpio-sifive.c
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 SiFive
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/of_irq.h>
+#include <linux/gpio/driver.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/regmap.h>
+
+#define SIFIVE_GPIO_INPUT_VAL	0x00
+#define SIFIVE_GPIO_INPUT_EN	0x04
+#define SIFIVE_GPIO_OUTPUT_EN	0x08
+#define SIFIVE_GPIO_OUTPUT_VAL	0x0C
+#define SIFIVE_GPIO_RISE_IE	0x18
+#define SIFIVE_GPIO_RISE_IP	0x1C
+#define SIFIVE_GPIO_FALL_IE	0x20
+#define SIFIVE_GPIO_FALL_IP	0x24
+#define SIFIVE_GPIO_HIGH_IE	0x28
+#define SIFIVE_GPIO_HIGH_IP	0x2C
+#define SIFIVE_GPIO_LOW_IE	0x30
+#define SIFIVE_GPIO_LOW_IP	0x34
+#define SIFIVE_GPIO_OUTPUT_XOR	0x40
+
+#define SIFIVE_GPIO_MAX		32
+#define SIFIVE_GPIO_IRQ_OFFSET	7
+
+struct sifive_gpio {
+	void __iomem		*base;
+	struct gpio_chip	gc;
+	struct regmap		*regs;
+	u32			irq_state;
+	unsigned int		trigger[SIFIVE_GPIO_MAX];
+	unsigned int		irq_parent[SIFIVE_GPIO_MAX];
+};
+
+static void sifive_gpio_set_ie(struct sifive_gpio *chip, unsigned int offset)
+{
+	unsigned long flags;
+	unsigned int trigger;
+
+	spin_lock_irqsave(&chip->gc.bgpio_lock, flags);
+	trigger = (chip->irq_state & BIT(offset)) ? chip->trigger[offset] : 0;
+	regmap_update_bits(chip->regs, SIFIVE_GPIO_RISE_IE, BIT(offset),
+			   (trigger & IRQ_TYPE_EDGE_RISING) ? BIT(offset) : 0);
+	regmap_update_bits(chip->regs, SIFIVE_GPIO_FALL_IE, BIT(offset),
+			   (trigger & IRQ_TYPE_EDGE_FALLING) ? BIT(offset) : 0);
+	regmap_update_bits(chip->regs, SIFIVE_GPIO_HIGH_IE, BIT(offset),
+			   (trigger & IRQ_TYPE_LEVEL_HIGH) ? BIT(offset) : 0);
+	regmap_update_bits(chip->regs, SIFIVE_GPIO_LOW_IE, BIT(offset),
+			   (trigger & IRQ_TYPE_LEVEL_LOW) ? BIT(offset) : 0);
+	spin_unlock_irqrestore(&chip->gc.bgpio_lock, flags);
+}
+
+static int sifive_gpio_irq_set_type(struct irq_data *d, unsigned int trigger)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct sifive_gpio *chip = gpiochip_get_data(gc);
+	int offset = irqd_to_hwirq(d);
+
+	if (offset < 0 || offset >= gc->ngpio)
+		return -EINVAL;
+
+	chip->trigger[offset] = trigger;
+	sifive_gpio_set_ie(chip, offset);
+	return 0;
+}
+
+static void sifive_gpio_irq_enable(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct sifive_gpio *chip = gpiochip_get_data(gc);
+	int offset = irqd_to_hwirq(d) % SIFIVE_GPIO_MAX;
+	u32 bit = BIT(offset);
+	unsigned long flags;
+
+	irq_chip_enable_parent(d);
+
+	/* Switch to input */
+	gc->direction_input(gc, offset);
+
+	spin_lock_irqsave(&gc->bgpio_lock, flags);
+	/* Clear any sticky pending interrupts */
+	regmap_write(chip->regs, SIFIVE_GPIO_RISE_IP, bit);
+	regmap_write(chip->regs, SIFIVE_GPIO_FALL_IP, bit);
+	regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IP, bit);
+	regmap_write(chip->regs, SIFIVE_GPIO_LOW_IP, bit);
+	spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+
+	/* Enable interrupts */
+	assign_bit(offset, (unsigned long *)&chip->irq_state, 1);
+	sifive_gpio_set_ie(chip, offset);
+}
+
+static void sifive_gpio_irq_disable(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct sifive_gpio *chip = gpiochip_get_data(gc);
+	int offset = irqd_to_hwirq(d) % SIFIVE_GPIO_MAX;
+
+	assign_bit(offset, (unsigned long *)&chip->irq_state, 0);
+	sifive_gpio_set_ie(chip, offset);
+	irq_chip_disable_parent(d);
+}
+
+static void sifive_gpio_irq_eoi(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct sifive_gpio *chip = gpiochip_get_data(gc);
+	int offset = irqd_to_hwirq(d) % SIFIVE_GPIO_MAX;
+	u32 bit = BIT(offset);
+	unsigned long flags;
+
+	spin_lock_irqsave(&gc->bgpio_lock, flags);
+	/* Clear all pending interrupts */
+	regmap_write(chip->regs, SIFIVE_GPIO_RISE_IP, bit);
+	regmap_write(chip->regs, SIFIVE_GPIO_FALL_IP, bit);
+	regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IP, bit);
+	regmap_write(chip->regs, SIFIVE_GPIO_LOW_IP, bit);
+	spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+
+	irq_chip_eoi_parent(d);
+}
+
+static struct irq_chip sifive_gpio_irqchip = {
+	.name		= "sifive-gpio",
+	.irq_set_type	= sifive_gpio_irq_set_type,
+	.irq_mask	= irq_chip_mask_parent,
+	.irq_unmask	= irq_chip_unmask_parent,
+	.irq_enable	= sifive_gpio_irq_enable,
+	.irq_disable	= sifive_gpio_irq_disable,
+	.irq_eoi	= sifive_gpio_irq_eoi,
+};
+
+static int sifive_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
+					     unsigned int child,
+					     unsigned int child_type,
+					     unsigned int *parent,
+					     unsigned int *parent_type)
+{
+	*parent_type = IRQ_TYPE_NONE;
+	*parent = child + SIFIVE_GPIO_IRQ_OFFSET;
+	return 0;
+}
+
+static const struct regmap_config sifive_gpio_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.disable_locking = true,
+};
+
+static int sifive_gpio_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = pdev->dev.of_node;
+	struct device_node *irq_parent;
+	struct irq_domain *parent;
+	struct gpio_irq_chip *girq;
+	struct sifive_gpio *chip;
+	int ret, ngpio;
+
+	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	chip->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(chip->base)) {
+		dev_err(dev, "failed to allocate device memory\n");
+		return PTR_ERR(chip->base);
+	}
+
+	chip->regs = devm_regmap_init_mmio(dev, chip->base,
+					   &sifive_gpio_regmap_config);
+	if (IS_ERR(chip->regs))
+		return PTR_ERR(chip->regs);
+
+	ngpio = of_irq_count(node);
+	if (ngpio >= SIFIVE_GPIO_MAX) {
+		dev_err(dev, "Too many GPIO interrupts (max=%d)\n",
+			SIFIVE_GPIO_MAX);
+		return -ENXIO;
+	}
+
+	irq_parent = of_irq_find_parent(node);
+	if (!irq_parent) {
+		dev_err(dev, "no IRQ parent node\n");
+		return -ENODEV;
+	}
+	parent = irq_find_host(irq_parent);
+	if (!parent) {
+		dev_err(dev, "no IRQ parent domain\n");
+		return -ENODEV;
+	}
+
+	ret = bgpio_init(&chip->gc, dev, 4,
+			 chip->base + SIFIVE_GPIO_INPUT_VAL,
+			 chip->base + SIFIVE_GPIO_OUTPUT_VAL,
+			 NULL,
+			 chip->base + SIFIVE_GPIO_OUTPUT_EN,
+			 chip->base + SIFIVE_GPIO_INPUT_EN,
+			 0);
+	if (ret) {
+		dev_err(dev, "unable to init generic GPIO\n");
+		return ret;
+	}
+
+	/* Disable all GPIO interrupts before enabling parent interrupts */
+	regmap_write(chip->regs, SIFIVE_GPIO_RISE_IE, 0);
+	regmap_write(chip->regs, SIFIVE_GPIO_FALL_IE, 0);
+	regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IE, 0);
+	regmap_write(chip->regs, SIFIVE_GPIO_LOW_IE, 0);
+	chip->irq_state = 0;
+
+	chip->gc.base = -1;
+	chip->gc.ngpio = ngpio;
+	chip->gc.label = dev_name(dev);
+	chip->gc.parent = dev;
+	chip->gc.owner = THIS_MODULE;
+	girq = &chip->gc.irq;
+	girq->chip = &sifive_gpio_irqchip;
+	girq->fwnode = of_node_to_fwnode(node);
+	girq->parent_domain = parent;
+	girq->child_to_parent_hwirq = sifive_gpio_child_to_parent_hwirq;
+	girq->handler = handle_bad_irq;
+	girq->default_type = IRQ_TYPE_NONE;
+
+	platform_set_drvdata(pdev, chip);
+	return gpiochip_add_data(&chip->gc, chip);
+}
+
+static const struct of_device_id sifive_gpio_match[] = {
+	{ .compatible = "sifive,gpio0" },
+	{ .compatible = "sifive,fu540-c000-gpio" },
+	{ },
+};
+
+static struct platform_driver sifive_gpio_driver = {
+	.probe		= sifive_gpio_probe,
+	.driver = {
+		.name	= "sifive_gpio",
+		.of_match_table = of_match_ptr(sifive_gpio_match),
+	},
+};
+builtin_platform_driver(sifive_gpio_driver)
-- 
2.7.4


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

* [PATCH v4 6/6] riscv: dts: Add DT support for SiFive FU540 GPIO driver
  2019-12-10 11:11 [PATCH v4 0/6] GPIO & Hierarchy IRQ support for HiFive Unleashed Yash Shah
                   ` (4 preceding siblings ...)
  2019-12-10 11:11 ` [PATCH v4 5/6] gpio: sifive: Add GPIO driver for SiFive SoCs Yash Shah
@ 2019-12-10 11:11 ` Yash Shah
  2020-01-20  9:09 ` [PATCH v4 0/6] GPIO & Hierarchy IRQ support for HiFive Unleashed Marc Zyngier
  2020-01-29 15:00 ` Palmer Dabbelt
  7 siblings, 0 replies; 16+ messages in thread
From: Yash Shah @ 2019-12-10 11:11 UTC (permalink / raw)
  To: linus.walleij, bgolaszewski, robh+dt, mark.rutland, palmer,
	paul.walmsley
  Cc: aou, tglx, jason, maz, bmeng.cn, atish.patra, sagar.kadam,
	linux-gpio, devicetree, linux-riscv, linux-kernel, sachin.ghadi,
	Yash Shah

Add the gpio DT node in SiFive FU540 soc-specific DT file.
Enable the gpio node in HiFive Unleashed board-specific DT file.

Signed-off-by: Yash Shah <yash.shah@sifive.com>
---
 arch/riscv/boot/dts/sifive/fu540-c000.dtsi          | 15 ++++++++++++++-
 arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts |  4 ++++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/boot/dts/sifive/fu540-c000.dtsi b/arch/riscv/boot/dts/sifive/fu540-c000.dtsi
index afa43c7..96dca93 100644
--- a/arch/riscv/boot/dts/sifive/fu540-c000.dtsi
+++ b/arch/riscv/boot/dts/sifive/fu540-c000.dtsi
@@ -246,6 +246,19 @@
 			#pwm-cells = <3>;
 			status = "disabled";
 		};
-
+		gpio: gpio@10060000 {
+			compatible = "sifive,fu540-c000-gpio", "sifive,gpio0";
+			interrupt-parent = <&plic0>;
+			interrupts = <7>, <8>, <9>, <10>, <11>, <12>, <13>,
+				     <14>, <15>, <16>, <17>, <18>, <19>, <20>,
+				     <21>, <22>;
+			reg = <0x0 0x10060000 0x0 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			clocks = <&prci PRCI_CLK_TLCLK>;
+			status = "disabled";
+		};
 	};
 };
diff --git a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
index 88cfcb9..609198c 100644
--- a/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
+++ b/arch/riscv/boot/dts/sifive/hifive-unleashed-a00.dts
@@ -94,3 +94,7 @@
 &pwm1 {
 	status = "okay";
 };
+
+&gpio {
+	status = "okay";
+};
-- 
2.7.4


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

* Re: [PATCH v4 4/6] gpio: sifive: Add DT documentation for SiFive GPIO
  2019-12-10 11:11 ` [PATCH v4 4/6] gpio: sifive: Add DT documentation for SiFive GPIO Yash Shah
@ 2019-12-18 20:51   ` Rob Herring
  2020-01-24 19:11   ` [tip: irq/core] gpio/sifive: " tip-bot2 for Yash Shah
  1 sibling, 0 replies; 16+ messages in thread
From: Rob Herring @ 2019-12-18 20:51 UTC (permalink / raw)
  To: Yash Shah
  Cc: linus.walleij, bgolaszewski, robh+dt, mark.rutland, palmer,
	paul.walmsley, aou, tglx, jason, maz, bmeng.cn, atish.patra,
	sagar.kadam, linux-gpio, devicetree, linux-riscv, linux-kernel,
	sachin.ghadi, Yash Shah

On Tue, 10 Dec 2019 16:41:12 +0530, Yash Shah wrote:
> DT json-schema for GPIO controller added.
> 
> Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
> Signed-off-by: Wesley W. Terpstra <wesley@sifive.com>
> [Atish: Compatible string update]
> Signed-off-by: Atish Patra <atish.patra@wdc.com>
> Signed-off-by: Yash Shah <yash.shah@sifive.com>
> ---
>  .../devicetree/bindings/gpio/sifive,gpio.yaml      | 68 ++++++++++++++++++++++
>  1 file changed, 68 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/gpio/sifive,gpio.yaml
> 

Reviewed-by: Rob Herring <robh@kernel.org>

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

* Re: [PATCH v4 0/6] GPIO & Hierarchy IRQ support for HiFive Unleashed
  2019-12-10 11:11 [PATCH v4 0/6] GPIO & Hierarchy IRQ support for HiFive Unleashed Yash Shah
                   ` (5 preceding siblings ...)
  2019-12-10 11:11 ` [PATCH v4 6/6] riscv: dts: Add DT support for SiFive FU540 GPIO driver Yash Shah
@ 2020-01-20  9:09 ` Marc Zyngier
  2020-01-21  8:53   ` Yash Shah
  2020-01-29 15:00 ` Palmer Dabbelt
  7 siblings, 1 reply; 16+ messages in thread
From: Marc Zyngier @ 2020-01-20  9:09 UTC (permalink / raw)
  To: Yash Shah
  Cc: linus.walleij, bgolaszewski, robh+dt, mark.rutland, palmer,
	paul.walmsley, aou, tglx, jason, bmeng.cn, atish.patra,
	sagar.kadam, linux-gpio, devicetree, linux-riscv, linux-kernel,
	sachin.ghadi

On 2019-12-10 12:11, Yash Shah wrote:
> This patch series adds GPIO drivers, DT documentation and DT nodes for
> HiFive Unleashed board. The gpio patches are mostly based on Wesley's 
> patch.
> The patchset also adds hierarchy irq domain support as it is required 
> by this
> gpio driver. It also includes the irqdomain patch to introduce
> irq_domain_translate_onecell() and irq-nvic driver patch to use this 
> newly
> introduced function.
> 
> This patchset is based on Linux 5.4-rc6 and tested on HiFive Unleashed 
> board
> 
> Changes:
> v4 vs v3:
> - Rename the DT yaml document to more standard naming 
> (sifive,gpio.yaml)
> - Drop "clock-names" property from yaml document
> - Add "minItems" to "interrupts" node in yaml
> 
> v3 vs v2:
> - Include patch for irq-nvic driver to use irq_domain_translate_onecell
> - Remove unnecessary inclusion of header files
> - Use a single prefix for all symbols in this driver
> - Rename the "enabled" field of struct sifive_gpio to "irq_state"
> - Remove unused variables and locking from probe()
> - Other minor changes
> 
> v2 vs v1:
> - Add patch to introduce irq_domain_translate_onecell() and use it in
>   the sifive PLIC driver
> - Drop the usage of own locks, instead use internal bgpio_locks
> - Consistently use regmap for register access throughout the gpio code
> - Convert the GPIO DT documentation into a json schema
> - Other minor changes based upon feedback received on v1
> 
> v1 vs RFC:
> Incorporated below changes as suggested by Linus Walleij on RFC version 
> of this
> patchset[0]
> - Dropped PWM patches as they are already merged.
> - Include "GPIO_GENERIC" and "REGMAP_MMIO" in Kconfig select option
> - Remove unwanted inclusion of header files
> - Use regmap MMIO instead of customised sifive_assign_bit()
> - Use GPIOLIB_GENERIC and bgpio_init() to set up the accessors
> - Use hierarchical irqdomain
> 
> [0]
> https://lore.kernel.org/linux-riscv/20181010123519.RVexDppaPFpIWl7QU_hpP8tc5qqWPJgeuLYn0FaGbeQ@z/
> 
> Yash Shah (6):
>   genirq: introduce irq_domain_translate_onecell
>   irqchip: nvic: Use irq_domain_translate_onecell instead of custom 
> func
>   irqchip: sifive: Support hierarchy irq domain
>   gpio: sifive: Add DT documentation for SiFive GPIO
>   gpio: sifive: Add GPIO driver for SiFive SoCs
>   riscv: dts: Add DT support for SiFive FU540 GPIO driver

I've queued the first 5 patches. The last one should go via the
corresponding platform tree.

Thanks,

         M.
-- 
Jazz is not dead. It just smells funny...

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

* RE: [PATCH v4 0/6] GPIO & Hierarchy IRQ support for HiFive Unleashed
  2020-01-20  9:09 ` [PATCH v4 0/6] GPIO & Hierarchy IRQ support for HiFive Unleashed Marc Zyngier
@ 2020-01-21  8:53   ` Yash Shah
  0 siblings, 0 replies; 16+ messages in thread
From: Yash Shah @ 2020-01-21  8:53 UTC (permalink / raw)
  To: Marc Zyngier, Paul Walmsley ( Sifive)
  Cc: linus.walleij, bgolaszewski, robh+dt, mark.rutland, palmer, aou,
	tglx, jason, bmeng.cn, atish.patra, Sagar Kadam, linux-gpio,
	devicetree, linux-riscv, linux-kernel, Sachin Ghadi

> -----Original Message-----
> From: Marc Zyngier <maz@kernel.org>
> Sent: 20 January 2020 14:40
> To: Yash Shah <yash.shah@sifive.com>
> Cc: linus.walleij@linaro.org; bgolaszewski@baylibre.com;
> robh+dt@kernel.org; mark.rutland@arm.com; palmer@dabbelt.com; Paul
> Walmsley ( Sifive) <paul.walmsley@sifive.com>; aou@eecs.berkeley.edu;
> tglx@linutronix.de; jason@lakedaemon.net; bmeng.cn@gmail.com;
> atish.patra@wdc.com; Sagar Kadam <sagar.kadam@sifive.com>; linux-
> gpio@vger.kernel.org; devicetree@vger.kernel.org; linux-
> riscv@lists.infradead.org; linux-kernel@vger.kernel.org; Sachin Ghadi
> <sachin.ghadi@sifive.com>
> Subject: Re: [PATCH v4 0/6] GPIO & Hierarchy IRQ support for HiFive
> Unleashed
> 
> On 2019-12-10 12:11, Yash Shah wrote:
> > This patch series adds GPIO drivers, DT documentation and DT nodes for
> > HiFive Unleashed board. The gpio patches are mostly based on Wesley's
> > patch.
> > The patchset also adds hierarchy irq domain support as it is required
> > by this gpio driver. It also includes the irqdomain patch to introduce
> > irq_domain_translate_onecell() and irq-nvic driver patch to use this
> > newly introduced function.
> >
> > This patchset is based on Linux 5.4-rc6 and tested on HiFive Unleashed
> > board
> >
> > Changes:
> > v4 vs v3:
> > - Rename the DT yaml document to more standard naming
> > (sifive,gpio.yaml)
> > - Drop "clock-names" property from yaml document
> > - Add "minItems" to "interrupts" node in yaml
> >
> > v3 vs v2:
> > - Include patch for irq-nvic driver to use
> > irq_domain_translate_onecell
> > - Remove unnecessary inclusion of header files
> > - Use a single prefix for all symbols in this driver
> > - Rename the "enabled" field of struct sifive_gpio to "irq_state"
> > - Remove unused variables and locking from probe()
> > - Other minor changes
> >
> > v2 vs v1:
> > - Add patch to introduce irq_domain_translate_onecell() and use it in
> >   the sifive PLIC driver
> > - Drop the usage of own locks, instead use internal bgpio_locks
> > - Consistently use regmap for register access throughout the gpio code
> > - Convert the GPIO DT documentation into a json schema
> > - Other minor changes based upon feedback received on v1
> >
> > v1 vs RFC:
> > Incorporated below changes as suggested by Linus Walleij on RFC
> > version of this patchset[0]
> > - Dropped PWM patches as they are already merged.
> > - Include "GPIO_GENERIC" and "REGMAP_MMIO" in Kconfig select option
> > - Remove unwanted inclusion of header files
> > - Use regmap MMIO instead of customised sifive_assign_bit()
> > - Use GPIOLIB_GENERIC and bgpio_init() to set up the accessors
> > - Use hierarchical irqdomain
> >
> > [0]
> > https://lore.kernel.org/linux-
> riscv/20181010123519.RVexDppaPFpIWl7QU_h
> > pP8tc5qqWPJgeuLYn0FaGbeQ@z/
> >
> > Yash Shah (6):
> >   genirq: introduce irq_domain_translate_onecell
> >   irqchip: nvic: Use irq_domain_translate_onecell instead of custom
> > func
> >   irqchip: sifive: Support hierarchy irq domain
> >   gpio: sifive: Add DT documentation for SiFive GPIO
> >   gpio: sifive: Add GPIO driver for SiFive SoCs
> >   riscv: dts: Add DT support for SiFive FU540 GPIO driver
> 
> I've queued the first 5 patches. The last one should go via the corresponding
> platform tree.

Thanks.
@Paul, Are you going to merge the last patch (DT support for GPIO) or you want me to rebase and send it separately?

- Yash

> 
> Thanks,
> 
>          M.
> --
> Jazz is not dead. It just smells funny...

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

* [tip: irq/core] gpio/sifive: Add GPIO driver for SiFive SoCs
  2019-12-10 11:11 ` [PATCH v4 5/6] gpio: sifive: Add GPIO driver for SiFive SoCs Yash Shah
@ 2020-01-24 19:11   ` tip-bot2 for Yash Shah
  0 siblings, 0 replies; 16+ messages in thread
From: tip-bot2 for Yash Shah @ 2020-01-24 19:11 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Wesley W. Terpstra, Atish Patra, Yash Shah, Marc Zyngier,
	Bartosz Golaszewski, Linus Walleij, x86, LKML

The following commit has been merged into the irq/core branch of tip:

Commit-ID:     96868dce644d002383f6d5eb575a6ce3c8779f39
Gitweb:        https://git.kernel.org/tip/96868dce644d002383f6d5eb575a6ce3c8779f39
Author:        Yash Shah <yash.shah@sifive.com>
AuthorDate:    Tue, 10 Dec 2019 16:41:13 +05:30
Committer:     Marc Zyngier <maz@kernel.org>
CommitterDate: Mon, 20 Jan 2020 19:10:03 

gpio/sifive: Add GPIO driver for SiFive SoCs

Adds the GPIO driver for SiFive RISC-V SoCs.

Signed-off-by: Wesley W. Terpstra <wesley@sifive.com>
[Atish: Various fixes and code cleanup]
Signed-off-by: Atish Patra <atish.patra@wdc.com>
Signed-off-by: Yash Shah <yash.shah@sifive.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Reviewed-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/1575976274-13487-6-git-send-email-yash.shah@sifive.com
---
 drivers/gpio/Kconfig       |   9 +-
 drivers/gpio/Makefile      |   1 +-
 drivers/gpio/gpio-sifive.c | 252 ++++++++++++++++++++++++++++++++++++-
 3 files changed, 262 insertions(+)
 create mode 100644 drivers/gpio/gpio-sifive.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 6ab25fe..809dd54 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -479,6 +479,15 @@ config GPIO_SAMA5D2_PIOBU
 	  The difference from regular GPIOs is that they
 	  maintain their value during backup/self-refresh.
 
+config GPIO_SIFIVE
+	bool "SiFive GPIO support"
+	depends on OF_GPIO && IRQ_DOMAIN_HIERARCHY
+	select GPIO_GENERIC
+	select GPIOLIB_IRQCHIP
+	select REGMAP_MMIO
+	help
+	  Say yes here to support the GPIO device on SiFive SoCs.
+
 config GPIO_SIOX
 	tristate "SIOX GPIO support"
 	depends on SIOX
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 34eb8b2..11eeeeb 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -124,6 +124,7 @@ obj-$(CONFIG_ARCH_SA1100)		+= gpio-sa1100.o
 obj-$(CONFIG_GPIO_SAMA5D2_PIOBU)	+= gpio-sama5d2-piobu.o
 obj-$(CONFIG_GPIO_SCH311X)		+= gpio-sch311x.o
 obj-$(CONFIG_GPIO_SCH)			+= gpio-sch.o
+obj-$(CONFIG_GPIO_SIFIVE)		+= gpio-sifive.o
 obj-$(CONFIG_GPIO_SIOX)			+= gpio-siox.o
 obj-$(CONFIG_GPIO_SODAVILLE)		+= gpio-sodaville.o
 obj-$(CONFIG_GPIO_SPEAR_SPICS)		+= gpio-spear-spics.o
diff --git a/drivers/gpio/gpio-sifive.c b/drivers/gpio/gpio-sifive.c
new file mode 100644
index 0000000..147a1bd
--- /dev/null
+++ b/drivers/gpio/gpio-sifive.c
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 SiFive
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/of_irq.h>
+#include <linux/gpio/driver.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/regmap.h>
+
+#define SIFIVE_GPIO_INPUT_VAL	0x00
+#define SIFIVE_GPIO_INPUT_EN	0x04
+#define SIFIVE_GPIO_OUTPUT_EN	0x08
+#define SIFIVE_GPIO_OUTPUT_VAL	0x0C
+#define SIFIVE_GPIO_RISE_IE	0x18
+#define SIFIVE_GPIO_RISE_IP	0x1C
+#define SIFIVE_GPIO_FALL_IE	0x20
+#define SIFIVE_GPIO_FALL_IP	0x24
+#define SIFIVE_GPIO_HIGH_IE	0x28
+#define SIFIVE_GPIO_HIGH_IP	0x2C
+#define SIFIVE_GPIO_LOW_IE	0x30
+#define SIFIVE_GPIO_LOW_IP	0x34
+#define SIFIVE_GPIO_OUTPUT_XOR	0x40
+
+#define SIFIVE_GPIO_MAX		32
+#define SIFIVE_GPIO_IRQ_OFFSET	7
+
+struct sifive_gpio {
+	void __iomem		*base;
+	struct gpio_chip	gc;
+	struct regmap		*regs;
+	u32			irq_state;
+	unsigned int		trigger[SIFIVE_GPIO_MAX];
+	unsigned int		irq_parent[SIFIVE_GPIO_MAX];
+};
+
+static void sifive_gpio_set_ie(struct sifive_gpio *chip, unsigned int offset)
+{
+	unsigned long flags;
+	unsigned int trigger;
+
+	spin_lock_irqsave(&chip->gc.bgpio_lock, flags);
+	trigger = (chip->irq_state & BIT(offset)) ? chip->trigger[offset] : 0;
+	regmap_update_bits(chip->regs, SIFIVE_GPIO_RISE_IE, BIT(offset),
+			   (trigger & IRQ_TYPE_EDGE_RISING) ? BIT(offset) : 0);
+	regmap_update_bits(chip->regs, SIFIVE_GPIO_FALL_IE, BIT(offset),
+			   (trigger & IRQ_TYPE_EDGE_FALLING) ? BIT(offset) : 0);
+	regmap_update_bits(chip->regs, SIFIVE_GPIO_HIGH_IE, BIT(offset),
+			   (trigger & IRQ_TYPE_LEVEL_HIGH) ? BIT(offset) : 0);
+	regmap_update_bits(chip->regs, SIFIVE_GPIO_LOW_IE, BIT(offset),
+			   (trigger & IRQ_TYPE_LEVEL_LOW) ? BIT(offset) : 0);
+	spin_unlock_irqrestore(&chip->gc.bgpio_lock, flags);
+}
+
+static int sifive_gpio_irq_set_type(struct irq_data *d, unsigned int trigger)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct sifive_gpio *chip = gpiochip_get_data(gc);
+	int offset = irqd_to_hwirq(d);
+
+	if (offset < 0 || offset >= gc->ngpio)
+		return -EINVAL;
+
+	chip->trigger[offset] = trigger;
+	sifive_gpio_set_ie(chip, offset);
+	return 0;
+}
+
+static void sifive_gpio_irq_enable(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct sifive_gpio *chip = gpiochip_get_data(gc);
+	int offset = irqd_to_hwirq(d) % SIFIVE_GPIO_MAX;
+	u32 bit = BIT(offset);
+	unsigned long flags;
+
+	irq_chip_enable_parent(d);
+
+	/* Switch to input */
+	gc->direction_input(gc, offset);
+
+	spin_lock_irqsave(&gc->bgpio_lock, flags);
+	/* Clear any sticky pending interrupts */
+	regmap_write(chip->regs, SIFIVE_GPIO_RISE_IP, bit);
+	regmap_write(chip->regs, SIFIVE_GPIO_FALL_IP, bit);
+	regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IP, bit);
+	regmap_write(chip->regs, SIFIVE_GPIO_LOW_IP, bit);
+	spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+
+	/* Enable interrupts */
+	assign_bit(offset, (unsigned long *)&chip->irq_state, 1);
+	sifive_gpio_set_ie(chip, offset);
+}
+
+static void sifive_gpio_irq_disable(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct sifive_gpio *chip = gpiochip_get_data(gc);
+	int offset = irqd_to_hwirq(d) % SIFIVE_GPIO_MAX;
+
+	assign_bit(offset, (unsigned long *)&chip->irq_state, 0);
+	sifive_gpio_set_ie(chip, offset);
+	irq_chip_disable_parent(d);
+}
+
+static void sifive_gpio_irq_eoi(struct irq_data *d)
+{
+	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+	struct sifive_gpio *chip = gpiochip_get_data(gc);
+	int offset = irqd_to_hwirq(d) % SIFIVE_GPIO_MAX;
+	u32 bit = BIT(offset);
+	unsigned long flags;
+
+	spin_lock_irqsave(&gc->bgpio_lock, flags);
+	/* Clear all pending interrupts */
+	regmap_write(chip->regs, SIFIVE_GPIO_RISE_IP, bit);
+	regmap_write(chip->regs, SIFIVE_GPIO_FALL_IP, bit);
+	regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IP, bit);
+	regmap_write(chip->regs, SIFIVE_GPIO_LOW_IP, bit);
+	spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+
+	irq_chip_eoi_parent(d);
+}
+
+static struct irq_chip sifive_gpio_irqchip = {
+	.name		= "sifive-gpio",
+	.irq_set_type	= sifive_gpio_irq_set_type,
+	.irq_mask	= irq_chip_mask_parent,
+	.irq_unmask	= irq_chip_unmask_parent,
+	.irq_enable	= sifive_gpio_irq_enable,
+	.irq_disable	= sifive_gpio_irq_disable,
+	.irq_eoi	= sifive_gpio_irq_eoi,
+};
+
+static int sifive_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
+					     unsigned int child,
+					     unsigned int child_type,
+					     unsigned int *parent,
+					     unsigned int *parent_type)
+{
+	*parent_type = IRQ_TYPE_NONE;
+	*parent = child + SIFIVE_GPIO_IRQ_OFFSET;
+	return 0;
+}
+
+static const struct regmap_config sifive_gpio_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.disable_locking = true,
+};
+
+static int sifive_gpio_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *node = pdev->dev.of_node;
+	struct device_node *irq_parent;
+	struct irq_domain *parent;
+	struct gpio_irq_chip *girq;
+	struct sifive_gpio *chip;
+	int ret, ngpio;
+
+	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	chip->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(chip->base)) {
+		dev_err(dev, "failed to allocate device memory\n");
+		return PTR_ERR(chip->base);
+	}
+
+	chip->regs = devm_regmap_init_mmio(dev, chip->base,
+					   &sifive_gpio_regmap_config);
+	if (IS_ERR(chip->regs))
+		return PTR_ERR(chip->regs);
+
+	ngpio = of_irq_count(node);
+	if (ngpio >= SIFIVE_GPIO_MAX) {
+		dev_err(dev, "Too many GPIO interrupts (max=%d)\n",
+			SIFIVE_GPIO_MAX);
+		return -ENXIO;
+	}
+
+	irq_parent = of_irq_find_parent(node);
+	if (!irq_parent) {
+		dev_err(dev, "no IRQ parent node\n");
+		return -ENODEV;
+	}
+	parent = irq_find_host(irq_parent);
+	if (!parent) {
+		dev_err(dev, "no IRQ parent domain\n");
+		return -ENODEV;
+	}
+
+	ret = bgpio_init(&chip->gc, dev, 4,
+			 chip->base + SIFIVE_GPIO_INPUT_VAL,
+			 chip->base + SIFIVE_GPIO_OUTPUT_VAL,
+			 NULL,
+			 chip->base + SIFIVE_GPIO_OUTPUT_EN,
+			 chip->base + SIFIVE_GPIO_INPUT_EN,
+			 0);
+	if (ret) {
+		dev_err(dev, "unable to init generic GPIO\n");
+		return ret;
+	}
+
+	/* Disable all GPIO interrupts before enabling parent interrupts */
+	regmap_write(chip->regs, SIFIVE_GPIO_RISE_IE, 0);
+	regmap_write(chip->regs, SIFIVE_GPIO_FALL_IE, 0);
+	regmap_write(chip->regs, SIFIVE_GPIO_HIGH_IE, 0);
+	regmap_write(chip->regs, SIFIVE_GPIO_LOW_IE, 0);
+	chip->irq_state = 0;
+
+	chip->gc.base = -1;
+	chip->gc.ngpio = ngpio;
+	chip->gc.label = dev_name(dev);
+	chip->gc.parent = dev;
+	chip->gc.owner = THIS_MODULE;
+	girq = &chip->gc.irq;
+	girq->chip = &sifive_gpio_irqchip;
+	girq->fwnode = of_node_to_fwnode(node);
+	girq->parent_domain = parent;
+	girq->child_to_parent_hwirq = sifive_gpio_child_to_parent_hwirq;
+	girq->handler = handle_bad_irq;
+	girq->default_type = IRQ_TYPE_NONE;
+
+	platform_set_drvdata(pdev, chip);
+	return gpiochip_add_data(&chip->gc, chip);
+}
+
+static const struct of_device_id sifive_gpio_match[] = {
+	{ .compatible = "sifive,gpio0" },
+	{ .compatible = "sifive,fu540-c000-gpio" },
+	{ },
+};
+
+static struct platform_driver sifive_gpio_driver = {
+	.probe		= sifive_gpio_probe,
+	.driver = {
+		.name	= "sifive_gpio",
+		.of_match_table = of_match_ptr(sifive_gpio_match),
+	},
+};
+builtin_platform_driver(sifive_gpio_driver)

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

* [tip: irq/core] irqchip/sifive-plic: Support irq domain hierarchy
  2019-12-10 11:11 ` [PATCH v4 3/6] irqchip: sifive: Support hierarchy irq domain Yash Shah
@ 2020-01-24 19:11   ` tip-bot2 for Yash Shah
  0 siblings, 0 replies; 16+ messages in thread
From: tip-bot2 for Yash Shah @ 2020-01-24 19:11 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Yash Shah, Marc Zyngier, x86, LKML

The following commit has been merged into the irq/core branch of tip:

Commit-ID:     466008f984358231f4608a0a4171b0e6e8251de8
Gitweb:        https://git.kernel.org/tip/466008f984358231f4608a0a4171b0e6e8251de8
Author:        Yash Shah <yash.shah@sifive.com>
AuthorDate:    Tue, 10 Dec 2019 16:41:11 +05:30
Committer:     Marc Zyngier <maz@kernel.org>
CommitterDate: Mon, 20 Jan 2020 09:24:56 

irqchip/sifive-plic: Support irq domain hierarchy

Add support for hierarchical irq domains. This is needed as
pre-requisite for gpio-sifive driver.

Signed-off-by: Yash Shah <yash.shah@sifive.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/1575976274-13487-4-git-send-email-yash.shah@sifive.com
---
 drivers/irqchip/Kconfig           |  1 +-
 drivers/irqchip/irq-sifive-plic.c | 30 ++++++++++++++++++++++++++----
 2 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 697e6a8..bb89dfc 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -490,6 +490,7 @@ config TI_SCI_INTA_IRQCHIP
 config SIFIVE_PLIC
 	bool "SiFive Platform-Level Interrupt Controller"
 	depends on RISCV
+	select IRQ_DOMAIN_HIERARCHY
 	help
 	   This enables support for the PLIC chip found in SiFive (and
 	   potentially other) RISC-V systems.  The PLIC controls devices
diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c
index 8df547d..0332f60 100644
--- a/drivers/irqchip/irq-sifive-plic.c
+++ b/drivers/irqchip/irq-sifive-plic.c
@@ -154,15 +154,37 @@ static struct irq_chip plic_chip = {
 static int plic_irqdomain_map(struct irq_domain *d, unsigned int irq,
 			      irq_hw_number_t hwirq)
 {
-	irq_set_chip_and_handler(irq, &plic_chip, handle_fasteoi_irq);
-	irq_set_chip_data(irq, NULL);
+	irq_domain_set_info(d, irq, hwirq, &plic_chip, d->host_data,
+			    handle_fasteoi_irq, NULL, NULL);
 	irq_set_noprobe(irq);
 	return 0;
 }
 
+static int plic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
+				 unsigned int nr_irqs, void *arg)
+{
+	int i, ret;
+	irq_hw_number_t hwirq;
+	unsigned int type;
+	struct irq_fwspec *fwspec = arg;
+
+	ret = irq_domain_translate_onecell(domain, fwspec, &hwirq, &type);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < nr_irqs; i++) {
+		ret = plic_irqdomain_map(domain, virq + i, hwirq + i);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 static const struct irq_domain_ops plic_irqdomain_ops = {
-	.map		= plic_irqdomain_map,
-	.xlate		= irq_domain_xlate_onecell,
+	.translate	= irq_domain_translate_onecell,
+	.alloc		= plic_irq_domain_alloc,
+	.free		= irq_domain_free_irqs_top,
 };
 
 static struct irq_domain *plic_irqdomain;

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

* [tip: irq/core] gpio/sifive: Add DT documentation for SiFive GPIO
  2019-12-10 11:11 ` [PATCH v4 4/6] gpio: sifive: Add DT documentation for SiFive GPIO Yash Shah
  2019-12-18 20:51   ` Rob Herring
@ 2020-01-24 19:11   ` tip-bot2 for Yash Shah
  1 sibling, 0 replies; 16+ messages in thread
From: tip-bot2 for Yash Shah @ 2020-01-24 19:11 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Wesley W. Terpstra, Atish Patra, Yash Shah, Marc Zyngier,
	Linus Walleij, Rob Herring, x86, LKML

The following commit has been merged into the irq/core branch of tip:

Commit-ID:     7875f8242494f8e4c8a75f2aeab4a6fb742599bd
Gitweb:        https://git.kernel.org/tip/7875f8242494f8e4c8a75f2aeab4a6fb742599bd
Author:        Yash Shah <yash.shah@sifive.com>
AuthorDate:    Tue, 10 Dec 2019 16:41:12 +05:30
Committer:     Marc Zyngier <maz@kernel.org>
CommitterDate: Mon, 20 Jan 2020 09:26:05 

gpio/sifive: Add DT documentation for SiFive GPIO

DT json-schema for GPIO controller added.

Signed-off-by: Wesley W. Terpstra <wesley@sifive.com>
[Atish: Compatible string update]
Signed-off-by: Atish Patra <atish.patra@wdc.com>
Signed-off-by: Yash Shah <yash.shah@sifive.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Rob Herring <robh@kernel.org>
Link: https://lore.kernel.org/r/1575976274-13487-5-git-send-email-yash.shah@sifive.com
---
 Documentation/devicetree/bindings/gpio/sifive,gpio.yaml | 68 ++++++++-
 1 file changed, 68 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/sifive,gpio.yaml

diff --git a/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml b/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml
new file mode 100644
index 0000000..418e838
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/sifive,gpio.yaml
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/gpio/sifive,gpio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SiFive GPIO controller
+
+maintainers:
+  - Yash Shah <yash.shah@sifive.com>
+  - Paul Walmsley <paul.walmsley@sifive.com>
+
+properties:
+  compatible:
+    items:
+      - const: sifive,fu540-c000-gpio
+      - const: sifive,gpio0
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    description:
+      interrupt mapping one per GPIO. Maximum 16 GPIOs.
+    minItems: 1
+    maxItems: 16
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 2
+
+  clocks:
+    maxItems: 1
+
+  "#gpio-cells":
+    const: 2
+
+  gpio-controller: true
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - interrupt-controller
+  - "#interrupt-cells"
+  - clocks
+  - "#gpio-cells"
+  - gpio-controller
+
+additionalProperties: false
+
+examples:
+  - |
+      #include <dt-bindings/clock/sifive-fu540-prci.h>
+      gpio@10060000 {
+        compatible = "sifive,fu540-c000-gpio", "sifive,gpio0";
+        interrupt-parent = <&plic>;
+        interrupts = <7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22>;
+        reg = <0x0 0x10060000 0x0 0x1000>;
+        clocks = <&tlclk PRCI_CLK_TLCLK>;
+        gpio-controller;
+        #gpio-cells = <2>;
+        interrupt-controller;
+        #interrupt-cells = <2>;
+      };
+
+...

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

* [tip: irq/core] irqchip/nvic: Use irq_domain_translate_onecell instead of custom func
  2019-12-10 11:11 ` [PATCH v4 2/6] irqchip: nvic: Use irq_domain_translate_onecell instead of custom func Yash Shah
@ 2020-01-24 19:11   ` tip-bot2 for Yash Shah
  0 siblings, 0 replies; 16+ messages in thread
From: tip-bot2 for Yash Shah @ 2020-01-24 19:11 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Yash Shah, Marc Zyngier, x86, LKML

The following commit has been merged into the irq/core branch of tip:

Commit-ID:     459c3bc8c497d6b665c2efd15ee7df0f4e19452a
Gitweb:        https://git.kernel.org/tip/459c3bc8c497d6b665c2efd15ee7df0f4e19452a
Author:        Yash Shah <yash.shah@sifive.com>
AuthorDate:    Tue, 10 Dec 2019 16:41:10 +05:30
Committer:     Marc Zyngier <maz@kernel.org>
CommitterDate: Mon, 20 Jan 2020 09:24:47 

irqchip/nvic: Use irq_domain_translate_onecell instead of custom func

Make use of newly introduced irq_domain_translate_onecell() instead of
custom made function.

Signed-off-by: Yash Shah <yash.shah@sifive.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/1575976274-13487-3-git-send-email-yash.shah@sifive.com
---
 drivers/irqchip/irq-nvic.c | 15 ++-------------
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/drivers/irqchip/irq-nvic.c b/drivers/irqchip/irq-nvic.c
index a166d30..f747e22 100644
--- a/drivers/irqchip/irq-nvic.c
+++ b/drivers/irqchip/irq-nvic.c
@@ -45,17 +45,6 @@ nvic_handle_irq(irq_hw_number_t hwirq, struct pt_regs *regs)
 	handle_IRQ(irq, regs);
 }
 
-static int nvic_irq_domain_translate(struct irq_domain *d,
-				     struct irq_fwspec *fwspec,
-				     unsigned long *hwirq, unsigned int *type)
-{
-	if (WARN_ON(fwspec->param_count < 1))
-		return -EINVAL;
-	*hwirq = fwspec->param[0];
-	*type = IRQ_TYPE_NONE;
-	return 0;
-}
-
 static int nvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
 				unsigned int nr_irqs, void *arg)
 {
@@ -64,7 +53,7 @@ static int nvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
 	unsigned int type = IRQ_TYPE_NONE;
 	struct irq_fwspec *fwspec = arg;
 
-	ret = nvic_irq_domain_translate(domain, fwspec, &hwirq, &type);
+	ret = irq_domain_translate_onecell(domain, fwspec, &hwirq, &type);
 	if (ret)
 		return ret;
 
@@ -75,7 +64,7 @@ static int nvic_irq_domain_alloc(struct irq_domain *domain, unsigned int virq,
 }
 
 static const struct irq_domain_ops nvic_irq_domain_ops = {
-	.translate = nvic_irq_domain_translate,
+	.translate = irq_domain_translate_onecell,
 	.alloc = nvic_irq_domain_alloc,
 	.free = irq_domain_free_irqs_top,
 };

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

* [tip: irq/core] genirq: Introduce irq_domain_translate_onecell
  2019-12-10 11:11 ` [PATCH v4 1/6] genirq: introduce irq_domain_translate_onecell Yash Shah
@ 2020-01-24 19:11   ` tip-bot2 for Yash Shah
  0 siblings, 0 replies; 16+ messages in thread
From: tip-bot2 for Yash Shah @ 2020-01-24 19:11 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: Yash Shah, Marc Zyngier, x86, LKML

The following commit has been merged into the irq/core branch of tip:

Commit-ID:     b01ecceaf2c0c4b3f2d24aa0adcf096ab1648253
Gitweb:        https://git.kernel.org/tip/b01ecceaf2c0c4b3f2d24aa0adcf096ab1648253
Author:        Yash Shah <yash.shah@sifive.com>
AuthorDate:    Tue, 10 Dec 2019 16:41:09 +05:30
Committer:     Marc Zyngier <maz@kernel.org>
CommitterDate: Mon, 20 Jan 2020 09:19:33 

genirq: Introduce irq_domain_translate_onecell

Add a new function irq_domain_translate_onecell() that is to be used as
the translate function in struct irq_domain_ops.

Signed-off-by: Yash Shah <yash.shah@sifive.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/1575976274-13487-2-git-send-email-yash.shah@sifive.com
---
 include/linux/irqdomain.h |  5 +++++
 kernel/irq/irqdomain.c    | 17 +++++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index 3c340db..698749f 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -427,6 +427,11 @@ int irq_domain_translate_twocell(struct irq_domain *d,
 				 unsigned long *out_hwirq,
 				 unsigned int *out_type);
 
+int irq_domain_translate_onecell(struct irq_domain *d,
+				 struct irq_fwspec *fwspec,
+				 unsigned long *out_hwirq,
+				 unsigned int *out_type);
+
 /* IPI functions */
 int irq_reserve_ipi(struct irq_domain *domain, const struct cpumask *dest);
 int irq_destroy_ipi(unsigned int irq, const struct cpumask *dest);
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index dd822fd..7a8808c 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -987,6 +987,23 @@ const struct irq_domain_ops irq_domain_simple_ops = {
 EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
 
 /**
+ * irq_domain_translate_onecell() - Generic translate for direct one cell
+ * bindings
+ */
+int irq_domain_translate_onecell(struct irq_domain *d,
+				 struct irq_fwspec *fwspec,
+				 unsigned long *out_hwirq,
+				 unsigned int *out_type)
+{
+	if (WARN_ON(fwspec->param_count < 1))
+		return -EINVAL;
+	*out_hwirq = fwspec->param[0];
+	*out_type = IRQ_TYPE_NONE;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(irq_domain_translate_onecell);
+
+/**
  * irq_domain_translate_twocell() - Generic translate for direct two cell
  * bindings
  *

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

* Re: [PATCH v4 0/6] GPIO & Hierarchy IRQ support for HiFive Unleashed
  2019-12-10 11:11 [PATCH v4 0/6] GPIO & Hierarchy IRQ support for HiFive Unleashed Yash Shah
                   ` (6 preceding siblings ...)
  2020-01-20  9:09 ` [PATCH v4 0/6] GPIO & Hierarchy IRQ support for HiFive Unleashed Marc Zyngier
@ 2020-01-29 15:00 ` Palmer Dabbelt
  7 siblings, 0 replies; 16+ messages in thread
From: Palmer Dabbelt @ 2020-01-29 15:00 UTC (permalink / raw)
  To: maz
  Cc: yash.shah, linus.walleij, bgolaszewski, robh+dt, mark.rutland,
	Paul Walmsley, aou, tglx, jason, bmeng.cn, Atish Patra,
	sagar.kadam, linux-gpio, devicetree, linux-riscv, linux-kernel,
	sachin.ghadi

On Mon, 20 Jan 2020 09:09:51 GMT (+0000), maz@kernel.org wrote:
> On 2019-12-10 12:11, Yash Shah wrote:
>> This patch series adds GPIO drivers, DT documentation and DT nodes for
>> HiFive Unleashed board. The gpio patches are mostly based on Wesley's
>> patch.
>> The patchset also adds hierarchy irq domain support as it is required
>> by this
>> gpio driver. It also includes the irqdomain patch to introduce
>> irq_domain_translate_onecell() and irq-nvic driver patch to use this
>> newly
>> introduced function.
>>
>> This patchset is based on Linux 5.4-rc6 and tested on HiFive Unleashed
>> board
>>
>> Changes:
>> v4 vs v3:
>> - Rename the DT yaml document to more standard naming
>> (sifive,gpio.yaml)
>> - Drop "clock-names" property from yaml document
>> - Add "minItems" to "interrupts" node in yaml
>>
>> v3 vs v2:
>> - Include patch for irq-nvic driver to use irq_domain_translate_onecell
>> - Remove unnecessary inclusion of header files
>> - Use a single prefix for all symbols in this driver
>> - Rename the "enabled" field of struct sifive_gpio to "irq_state"
>> - Remove unused variables and locking from probe()
>> - Other minor changes
>>
>> v2 vs v1:
>> - Add patch to introduce irq_domain_translate_onecell() and use it in
>>   the sifive PLIC driver
>> - Drop the usage of own locks, instead use internal bgpio_locks
>> - Consistently use regmap for register access throughout the gpio code
>> - Convert the GPIO DT documentation into a json schema
>> - Other minor changes based upon feedback received on v1
>>
>> v1 vs RFC:
>> Incorporated below changes as suggested by Linus Walleij on RFC version
>> of this
>> patchset[0]
>> - Dropped PWM patches as they are already merged.
>> - Include "GPIO_GENERIC" and "REGMAP_MMIO" in Kconfig select option
>> - Remove unwanted inclusion of header files
>> - Use regmap MMIO instead of customised sifive_assign_bit()
>> - Use GPIOLIB_GENERIC and bgpio_init() to set up the accessors
>> - Use hierarchical irqdomain
>>
>> [0]
>> https://lore.kernel.org/linux-riscv/20181010123519.RVexDppaPFpIWl7QU_hpP8tc5qqWPJgeuLYn0FaGbeQ@z/
>>
>> Yash Shah (6):
>>   genirq: introduce irq_domain_translate_onecell
>>   irqchip: nvic: Use irq_domain_translate_onecell instead of custom
>> func
>>   irqchip: sifive: Support hierarchy irq domain
>>   gpio: sifive: Add DT documentation for SiFive GPIO
>>   gpio: sifive: Add GPIO driver for SiFive SoCs
>>   riscv: dts: Add DT support for SiFive FU540 GPIO driver
>
> I've queued the first 5 patches. The last one should go via the
> corresponding platform tree.

Thanks, I'd missed this one.

>
> Thanks,
>
>          M.

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

end of thread, other threads:[~2020-01-29 15:00 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-10 11:11 [PATCH v4 0/6] GPIO & Hierarchy IRQ support for HiFive Unleashed Yash Shah
2019-12-10 11:11 ` [PATCH v4 1/6] genirq: introduce irq_domain_translate_onecell Yash Shah
2020-01-24 19:11   ` [tip: irq/core] genirq: Introduce irq_domain_translate_onecell tip-bot2 for Yash Shah
2019-12-10 11:11 ` [PATCH v4 2/6] irqchip: nvic: Use irq_domain_translate_onecell instead of custom func Yash Shah
2020-01-24 19:11   ` [tip: irq/core] irqchip/nvic: " tip-bot2 for Yash Shah
2019-12-10 11:11 ` [PATCH v4 3/6] irqchip: sifive: Support hierarchy irq domain Yash Shah
2020-01-24 19:11   ` [tip: irq/core] irqchip/sifive-plic: Support irq domain hierarchy tip-bot2 for Yash Shah
2019-12-10 11:11 ` [PATCH v4 4/6] gpio: sifive: Add DT documentation for SiFive GPIO Yash Shah
2019-12-18 20:51   ` Rob Herring
2020-01-24 19:11   ` [tip: irq/core] gpio/sifive: " tip-bot2 for Yash Shah
2019-12-10 11:11 ` [PATCH v4 5/6] gpio: sifive: Add GPIO driver for SiFive SoCs Yash Shah
2020-01-24 19:11   ` [tip: irq/core] gpio/sifive: " tip-bot2 for Yash Shah
2019-12-10 11:11 ` [PATCH v4 6/6] riscv: dts: Add DT support for SiFive FU540 GPIO driver Yash Shah
2020-01-20  9:09 ` [PATCH v4 0/6] GPIO & Hierarchy IRQ support for HiFive Unleashed Marc Zyngier
2020-01-21  8:53   ` Yash Shah
2020-01-29 15:00 ` Palmer Dabbelt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).