linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support
@ 2019-02-21 15:44 Linus Walleij
  2019-02-21 15:44 ` [PATCH 01/30 v2] ARM: ixp4xx: Convert to MULTI_IRQ_HANDLER Linus Walleij
                   ` (30 more replies)
  0 siblings, 31 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa; +Cc: Linus Walleij

This modernizes the IXP4xx platform and adds initial Device Tree
Support. We migrate to MULTI_IRQ_HANDLER, bumps the IRQs to
offset 16, converts to SPARSE_IRQ, then we add proper subsystem
drivers in each subsystem for irqchip, GPIO and clocksource and
switch over to using these new drivers.

This patch set represents what I want to merge for v5.2 early
after the next merge window. I already have working ethernet
but that will be a bonus feature if we can get it in or will
be deferred to v5.3 so that it can be applied in isolation.

Major changes from v1:
- Added patches for moving NPE and queue manager down to
  drivers/soc/ixp4xx
- Added device tree bindings and code to probe NPE and queue
  manager from device tree

A working set of base patches that boots to prompt from
initramfs on NSLU2 and GW2358-4 and also includes the
series for ethernet support is provided on this branch:
https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git/log/?h=ixp4

Obviously I am looking for the IXP4xx maintainers to ACK
the patch set.


Linus Walleij (30):
  ARM: ixp4xx: Convert to MULTI_IRQ_HANDLER
  ARM: ixp4xx: Pass IRQ resource to beeper
  ARM: ixp4xx: Convert to SPARSE_IRQ
  irqchip: Add driver for IXP4xx
  gpio: ixp4xx: Add driver for the IXP4xx GPIO
  ARM: ixp4xx: Switch to use new IRQ+GPIO drivers
  clocksource/drivers/ixp4xx: Add driver
  ARM: ixp4xx: Switch to use new timer driver
  irqchip: ixp4xx: Add DT bindings
  irqchip: ixp4xx: Add OF initialization support
  clocksource/drivers/ixp4xx: Add DT bindings
  clocksource/drivers/ixp4xx: Add OF initialization support
  gpio: ixp4xx: Add DT bindings
  gpio: ixp4xx: Add OF probing support
  ARM: ixp4xx: Add DT bindings
  ARM: ixp4xx: Add device tree boot support
  ARM: dts: Add some initial IXP4xx device trees
  ARM: ixp4xx: Move NPE and QMGR to drivers/soc
  ARM: ixp4xx: Move IXP4xx QMGR and NPE headers
  ARM: ixp4xx: Turn the NPE into a platform device
  ARM: ixp4xx: Turn the QMGR into a platform device
  soc: ixp4xx: npe: Pass addresses as resources
  soc: ixp4xx: Uninline several functions
  soc: ixp4xx: Remove unused functions
  soc: ixp4xx: qmgr: Pass resources
  soc: ixp4xx: Add DT bindings for IXP4xx NPE
  soc: ixp4xx: npe: Add DT probe code
  soc: ixp4xx: qmgr: Add DT bindings for IXP4xx qmgr
  soc: ixp4xx: qmgr: Add DT probe code
  ARM: dts: Add queue manager and NPE to the IXP4xx DTSI

 .../devicetree/bindings/arm/intel-ixp4xx.yaml |  22 +
 ...ntel,ixp4xx-network-processing-engine.yaml |  44 ++
 .../bindings/gpio/intel,ixp4xx-gpio.txt       |  38 ++
 .../intel,ixp4xx-interrupt.yaml               |  57 +++
 .../misc/intel,ixp4xx-queue-manager.yaml      |  57 +++
 .../bindings/timer/intel,ixp4xx-timer.yaml    |  42 ++
 MAINTAINERS                                   |  17 +-
 arch/arm/Kconfig                              |   5 +-
 arch/arm/boot/dts/Makefile                    |   3 +
 .../boot/dts/intel-ixp42x-linksys-nslu2.dts   | 109 ++++
 arch/arm/boot/dts/intel-ixp42x.dtsi           |  25 +
 .../dts/intel-ixp43x-gateworks-gw2358.dts     |  94 ++++
 arch/arm/boot/dts/intel-ixp43x.dtsi           |  15 +
 arch/arm/boot/dts/intel-ixp45x-ixp46x.dtsi    |  34 ++
 arch/arm/boot/dts/intel-ixp4xx.dtsi           |  70 +++
 arch/arm/mach-ixp4xx/Kconfig                  |  27 +-
 arch/arm/mach-ixp4xx/Makefile                 |   5 +-
 arch/arm/mach-ixp4xx/avila-pci.c              |   2 +
 arch/arm/mach-ixp4xx/avila-setup.c            |   2 +
 arch/arm/mach-ixp4xx/common.c                 | 484 +++---------------
 arch/arm/mach-ixp4xx/coyote-pci.c             |   2 +
 arch/arm/mach-ixp4xx/coyote-setup.c           |   2 +
 arch/arm/mach-ixp4xx/dsmg600-pci.c            |   2 +
 arch/arm/mach-ixp4xx/dsmg600-setup.c          |   5 +-
 arch/arm/mach-ixp4xx/fsg-pci.c                |   2 +
 arch/arm/mach-ixp4xx/fsg-setup.c              |   2 +
 arch/arm/mach-ixp4xx/gateway7001-pci.c        |   2 +
 arch/arm/mach-ixp4xx/gateway7001-setup.c      |   2 +
 arch/arm/mach-ixp4xx/gtwx5715-pci.c           |   2 +
 arch/arm/mach-ixp4xx/gtwx5715-setup.c         |   2 +
 .../mach-ixp4xx/include/mach/entry-macro.S    |  41 --
 arch/arm/mach-ixp4xx/include/mach/irqs.h      |  75 ---
 .../mach-ixp4xx/include/mach/ixp4xx-regs.h    |  94 ----
 arch/arm/mach-ixp4xx/include/mach/qmgr.h      | 204 --------
 arch/arm/mach-ixp4xx/irqs.h                   |  68 +++
 arch/arm/mach-ixp4xx/ixdp425-pci.c            |   2 +
 arch/arm/mach-ixp4xx/ixdp425-setup.c          |   2 +
 arch/arm/mach-ixp4xx/ixdpg425-pci.c           |   2 +
 arch/arm/mach-ixp4xx/ixp4xx-of.c              |  60 +++
 arch/arm/mach-ixp4xx/nas100d-pci.c            |   2 +
 arch/arm/mach-ixp4xx/nas100d-setup.c          |   5 +-
 arch/arm/mach-ixp4xx/nslu2-pci.c              |   2 +
 arch/arm/mach-ixp4xx/nslu2-setup.c            |  12 +-
 arch/arm/mach-ixp4xx/wg302v2-pci.c            |   2 +
 arch/arm/mach-ixp4xx/wg302v2-setup.c          |   2 +
 drivers/clocksource/Kconfig                   |   7 +
 drivers/clocksource/Makefile                  |   1 +
 drivers/clocksource/timer-ixp4xx.c            | 284 ++++++++++
 drivers/crypto/ixp4xx_crypto.c                |   4 +-
 drivers/gpio/Kconfig                          |  12 +
 drivers/gpio/Makefile                         |   1 +
 drivers/gpio/gpio-ixp4xx.c                    | 474 +++++++++++++++++
 drivers/input/misc/ixp4xx-beeper.c            |  20 +-
 drivers/irqchip/Kconfig                       |   6 +
 drivers/irqchip/Makefile                      |   1 +
 drivers/irqchip/irq-ixp4xx.c                  | 407 +++++++++++++++
 drivers/net/ethernet/xscale/ixp4xx_eth.c      |  14 +-
 drivers/net/wan/ixp4xx_hss.c                  |   4 +-
 drivers/soc/Kconfig                           |   1 +
 drivers/soc/Makefile                          |   1 +
 drivers/soc/ixp4xx/Kconfig                    |  16 +
 drivers/soc/ixp4xx/Makefile                   |   2 +
 .../soc/ixp4xx/ixp4xx-npe.c                   |  66 ++-
 .../soc/ixp4xx/ixp4xx-qmgr.c                  | 186 +++++--
 drivers/watchdog/ixp4xx_wdt.c                 |   9 +
 include/linux/irqchip/irq-ixp4xx.h            |  12 +
 include/linux/platform_data/timer-ixp4xx.h    |  11 +
 .../mach => include/linux/soc/ixp4xx}/npe.h   |   2 -
 include/linux/soc/ixp4xx/qmgr.h               |  91 ++++
 69 files changed, 2467 insertions(+), 913 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/arm/intel-ixp4xx.yaml
 create mode 100644 Documentation/devicetree/bindings/firmware/intel,ixp4xx-network-processing-engine.yaml
 create mode 100644 Documentation/devicetree/bindings/gpio/intel,ixp4xx-gpio.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml
 create mode 100644 Documentation/devicetree/bindings/misc/intel,ixp4xx-queue-manager.yaml
 create mode 100644 Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml
 create mode 100644 arch/arm/boot/dts/intel-ixp42x-linksys-nslu2.dts
 create mode 100644 arch/arm/boot/dts/intel-ixp42x.dtsi
 create mode 100644 arch/arm/boot/dts/intel-ixp43x-gateworks-gw2358.dts
 create mode 100644 arch/arm/boot/dts/intel-ixp43x.dtsi
 create mode 100644 arch/arm/boot/dts/intel-ixp45x-ixp46x.dtsi
 create mode 100644 arch/arm/boot/dts/intel-ixp4xx.dtsi
 delete mode 100644 arch/arm/mach-ixp4xx/include/mach/entry-macro.S
 delete mode 100644 arch/arm/mach-ixp4xx/include/mach/irqs.h
 delete mode 100644 arch/arm/mach-ixp4xx/include/mach/qmgr.h
 create mode 100644 arch/arm/mach-ixp4xx/irqs.h
 create mode 100644 arch/arm/mach-ixp4xx/ixp4xx-of.c
 create mode 100644 drivers/clocksource/timer-ixp4xx.c
 create mode 100644 drivers/gpio/gpio-ixp4xx.c
 create mode 100644 drivers/irqchip/irq-ixp4xx.c
 create mode 100644 drivers/soc/ixp4xx/Kconfig
 create mode 100644 drivers/soc/ixp4xx/Makefile
 rename arch/arm/mach-ixp4xx/ixp4xx_npe.c => drivers/soc/ixp4xx/ixp4xx-npe.c (94%)
 rename arch/arm/mach-ixp4xx/ixp4xx_qmgr.c => drivers/soc/ixp4xx/ixp4xx-qmgr.c (66%)
 create mode 100644 include/linux/irqchip/irq-ixp4xx.h
 create mode 100644 include/linux/platform_data/timer-ixp4xx.h
 rename {arch/arm/mach-ixp4xx/include/mach => include/linux/soc/ixp4xx}/npe.h (95%)
 create mode 100644 include/linux/soc/ixp4xx/qmgr.h

-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 01/30 v2] ARM: ixp4xx: Convert to MULTI_IRQ_HANDLER
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 15:44 ` [PATCH 02/30 v2] ARM: ixp4xx: Pass IRQ resource to beeper Linus Walleij
                   ` (29 subsequent siblings)
  30 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa; +Cc: Linus Walleij

This rewrites the IXP4xx to use MULTI_IRQ_HANDLER and
create an irqdomain for the irqchip in the platform. We
convert the timer to request the interrupt like any other
driver in the process.

We bump all IRQs to 16+offset to avoid using IRQ 0 and
set NR_IRQS to 512 (the default for most systems).
This conveniently fits with the first 16 IRQs being
pre-allocated when using SPARSE_IRQ.

This is a prerequisite for SPARSE_IRQ and DT boot.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/Kconfig                              |   1 +
 arch/arm/mach-ixp4xx/common.c                 | 109 +++++++++++++-----
 .../mach-ixp4xx/include/mach/entry-macro.S    |  41 -------
 arch/arm/mach-ixp4xx/include/mach/irqs.h      |  95 ++++++++-------
 4 files changed, 126 insertions(+), 120 deletions(-)
 delete mode 100644 arch/arm/mach-ixp4xx/include/mach/entry-macro.S

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 664e918e2624..0bdcacd40591 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -431,6 +431,7 @@ config ARCH_IXP4XX
 	select CPU_XSCALE
 	select DMABOUNCE if PCI
 	select GENERIC_CLOCKEVENTS
+	select GENERIC_IRQ_MULTI_HANDLER
 	select GPIOLIB
 	select HAVE_PCI
 	select NEED_MACH_IO_H
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 846e033c56fa..58a1b851425e 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -31,12 +31,14 @@
 #include <linux/cpu.h>
 #include <linux/pci.h>
 #include <linux/sched_clock.h>
+#include <linux/bitops.h>
 #include <mach/udc.h>
 #include <mach/hardware.h>
 #include <mach/io.h>
 #include <linux/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/page.h>
+#include <asm/exception.h>
 #include <asm/irq.h>
 #include <asm/system_misc.h>
 #include <asm/mach/map.h>
@@ -54,6 +56,7 @@
 				       (IXP4XX_OST_RELOAD_MASK + 1) * HZ) * \
 			(IXP4XX_OST_RELOAD_MASK + 1)
 
+static struct irq_domain *ixp4xx_irqdomain;
 static void __init ixp4xx_clocksource_init(void);
 static void __init ixp4xx_clockevent_init(void);
 static struct clock_event_device clockevent_ixp4xx;
@@ -166,16 +169,17 @@ static int ixp4xx_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
 
 static int ixp4xx_set_irq_type(struct irq_data *d, unsigned int type)
 {
-	int line = irq2gpio[d->irq];
+	int line = irq2gpio[d->hwirq];
 	u32 int_style;
 	enum ixp4xx_irq_type irq_type;
 	volatile u32 *int_reg;
 
 	/*
 	 * Only for GPIO IRQs
+	 * all other IRQs are simply active low
 	 */
 	if (line < 0)
-		return -EINVAL;
+		return 0;
 
 	switch (type){
 	case IRQ_TYPE_EDGE_BOTH:
@@ -203,9 +207,9 @@ static int ixp4xx_set_irq_type(struct irq_data *d, unsigned int type)
 	}
 
 	if (irq_type == IXP4XX_IRQ_EDGE)
-		ixp4xx_irq_edge |= (1 << d->irq);
+		ixp4xx_irq_edge |= (1 << d->hwirq);
 	else
-		ixp4xx_irq_edge &= ~(1 << d->irq);
+		ixp4xx_irq_edge &= ~(1 << d->hwirq);
 
 	if (line >= 8) {	/* pins 8-15 */
 		line -= 8;
@@ -224,22 +228,22 @@ static int ixp4xx_set_irq_type(struct irq_data *d, unsigned int type)
 	*int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE));
 
 	/* Configure the line as an input */
-	gpio_line_config(irq2gpio[d->irq], IXP4XX_GPIO_IN);
+	gpio_line_config(irq2gpio[d->hwirq], IXP4XX_GPIO_IN);
 
 	return 0;
 }
 
 static void ixp4xx_irq_mask(struct irq_data *d)
 {
-	if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && d->irq >= 32)
-		*IXP4XX_ICMR2 &= ~(1 << (d->irq - 32));
+	if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && d->hwirq >= 32)
+		*IXP4XX_ICMR2 &= ~(1 << (d->hwirq - 32));
 	else
-		*IXP4XX_ICMR &= ~(1 << d->irq);
+		*IXP4XX_ICMR &= ~(1 << d->hwirq);
 }
 
 static void ixp4xx_irq_ack(struct irq_data *d)
 {
-	int line = (d->irq < 32) ? irq2gpio[d->irq] : -1;
+	int line = (d->hwirq < 32) ? irq2gpio[d->hwirq] : -1;
 
 	if (line >= 0)
 		*IXP4XX_GPIO_GPISR = (1 << line);
@@ -251,13 +255,13 @@ static void ixp4xx_irq_ack(struct irq_data *d)
  */
 static void ixp4xx_irq_unmask(struct irq_data *d)
 {
-	if (!(ixp4xx_irq_edge & (1 << d->irq)))
+	if (!(ixp4xx_irq_edge & (1 << d->hwirq)))
 		ixp4xx_irq_ack(d);
 
-	if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && d->irq >= 32)
-		*IXP4XX_ICMR2 |= (1 << (d->irq - 32));
+	if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && d->hwirq >= 32)
+		*IXP4XX_ICMR2 |= (1 << (d->hwirq - 32));
 	else
-		*IXP4XX_ICMR |= (1 << d->irq);
+		*IXP4XX_ICMR |= (1 << d->hwirq);
 }
 
 static struct irq_chip ixp4xx_irq_chip = {
@@ -268,9 +272,50 @@ static struct irq_chip ixp4xx_irq_chip = {
 	.irq_set_type	= ixp4xx_set_irq_type,
 };
 
+asmlinkage void __exception_irq_entry ixp4xx_handle_irq(struct pt_regs *regs)
+{
+	unsigned long status;
+	int i;
+
+	status = *IXP4XX_ICIP;
+
+	for_each_set_bit(i, &status, 32)
+		handle_domain_irq(ixp4xx_irqdomain, i, regs);
+
+	/*
+	 * IXP465/IXP435 has an upper IRQ status register
+	 */
+	if ((cpu_is_ixp46x() || cpu_is_ixp43x())) {
+		status = *IXP4XX_ICIP2;
+		for_each_set_bit(i, &status, 32)
+			handle_domain_irq(ixp4xx_irqdomain, i + 32, regs);
+	}
+}
+
+static int ixp4xx_irqdomain_map(struct irq_domain *d, unsigned int irq,
+				irq_hw_number_t hwirq)
+{
+	irq_set_chip_data(irq, &ixp4xx_irq_chip);
+	irq_set_chip_and_handler(irq, &ixp4xx_irq_chip, handle_level_irq);
+	irq_set_probe(irq);
+
+	return 0;
+}
+
+static void ixp4xx_irqdomain_unmap(struct irq_domain *d, unsigned int irq)
+{
+	irq_set_chip_and_handler(irq, NULL, NULL);
+	irq_set_chip_data(irq, NULL);
+}
+
+static const struct irq_domain_ops ixp4xx_irqdomain_ops = {
+	.map = ixp4xx_irqdomain_map,
+	.unmap = ixp4xx_irqdomain_unmap,
+};
+
 void __init ixp4xx_init_irq(void)
 {
-	int i = 0;
+	int nr_irqs;
 
 	/*
 	 * ixp4xx does not implement the XScale PWRMODE register
@@ -290,14 +335,21 @@ void __init ixp4xx_init_irq(void)
 
 		/* Disable upper 32 interrupts */
 		*IXP4XX_ICMR2 = 0x00;
+
+		nr_irqs = 64;
+	} else {
+		nr_irqs = 32;
 	}
 
-        /* Default to all level triggered */
-	for(i = 0; i < NR_IRQS; i++) {
-		irq_set_chip_and_handler(i, &ixp4xx_irq_chip,
-					 handle_level_irq);
-		irq_clear_status_flags(i, IRQ_NOREQUEST);
+	ixp4xx_irqdomain = irq_domain_add_simple(NULL, nr_irqs, IRQ_IXP4XX_BASE,
+						 &ixp4xx_irqdomain_ops,
+						 NULL);
+	if (!ixp4xx_irqdomain) {
+		pr_crit("can not add primary irqdomain\n");
+		return;
 	}
+
+	set_handle_irq(ixp4xx_handle_irq);
 }
 
 
@@ -319,13 +371,6 @@ static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static struct irqaction ixp4xx_timer_irq = {
-	.name		= "timer1",
-	.flags		= IRQF_TIMER | IRQF_IRQPOLL,
-	.handler	= ixp4xx_timer_interrupt,
-	.dev_id		= &clockevent_ixp4xx,
-};
-
 void __init ixp4xx_timer_init(void)
 {
 	/* Reset/disable counter */
@@ -337,9 +382,6 @@ void __init ixp4xx_timer_init(void)
 	/* Reset time-stamp counter */
 	*IXP4XX_OSTS = 0;
 
-	/* Connect the interrupt handler and enable the interrupt */
-	setup_irq(IRQ_IXP4XX_TIMER1, &ixp4xx_timer_irq);
-
 	ixp4xx_clocksource_init();
 	ixp4xx_clockevent_init();
 }
@@ -574,7 +616,16 @@ static struct clock_event_device clockevent_ixp4xx = {
 
 static void __init ixp4xx_clockevent_init(void)
 {
+	int ret;
+
 	clockevent_ixp4xx.cpumask = cpumask_of(0);
+	clockevent_ixp4xx.irq = IRQ_IXP4XX_TIMER1;
+	ret = request_irq(IRQ_IXP4XX_TIMER1, ixp4xx_timer_interrupt,
+			  IRQF_TIMER, "IXP4XX-TIMER1", &clockevent_ixp4xx);
+	if (ret) {
+		pr_crit("no timer IRQ\n");
+		return;
+	}
 	clockevents_config_and_register(&clockevent_ixp4xx, IXP4XX_TIMER_FREQ,
 					0xf, 0xfffffffe);
 }
diff --git a/arch/arm/mach-ixp4xx/include/mach/entry-macro.S b/arch/arm/mach-ixp4xx/include/mach/entry-macro.S
deleted file mode 100644
index 79adf83e2c3d..000000000000
--- a/arch/arm/mach-ixp4xx/include/mach/entry-macro.S
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * arch/arm/mach-ixp4xx/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for IXP4xx-based platforms
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-#include <mach/hardware.h>
-
-		.macro  get_irqnr_preamble, base, tmp
-		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		ldr	\irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP_OFFSET)
-		ldr	\irqstat, [\irqstat]		@ get interrupts
-		cmp	\irqstat, #0
-		beq	1001f				@ upper IRQ?
-		clz     \irqnr, \irqstat
-		mov     \base, #31
-		sub     \irqnr, \base, \irqnr
-		b	1002f				@ lower IRQ being
-							@ handled
-
-1001:
-		/*
-		 * IXP465/IXP435 has an upper IRQ status register
-		 */
-#if defined(CONFIG_CPU_IXP46X) || defined(CONFIG_CPU_IXP43X)
-		ldr	\irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP2_OFFSET)
-		ldr	\irqstat, [\irqstat]		@ get upper interrupts
-		mov	\irqnr, #63
-		clz	\irqstat, \irqstat
- 		cmp	\irqstat, #32
-		subne	\irqnr, \irqnr, \irqstat
-#endif
-1002:
-		.endm
-
-
diff --git a/arch/arm/mach-ixp4xx/include/mach/irqs.h b/arch/arm/mach-ixp4xx/include/mach/irqs.h
index 7e6d4cce7c27..dadcd4ddb0a9 100644
--- a/arch/arm/mach-ixp4xx/include/mach/irqs.h
+++ b/arch/arm/mach-ixp4xx/include/mach/irqs.h
@@ -15,60 +15,55 @@
 #ifndef _ARCH_IXP4XX_IRQS_H_
 #define _ARCH_IXP4XX_IRQS_H_
 
-#define IRQ_IXP4XX_NPEA		0
-#define IRQ_IXP4XX_NPEB		1
-#define IRQ_IXP4XX_NPEC		2
-#define IRQ_IXP4XX_QM1		3
-#define IRQ_IXP4XX_QM2		4
-#define IRQ_IXP4XX_TIMER1	5
-#define IRQ_IXP4XX_GPIO0	6
-#define IRQ_IXP4XX_GPIO1	7
-#define IRQ_IXP4XX_PCI_INT	8
-#define IRQ_IXP4XX_PCI_DMA1	9
-#define IRQ_IXP4XX_PCI_DMA2	10
-#define IRQ_IXP4XX_TIMER2	11
-#define IRQ_IXP4XX_USB		12
-#define IRQ_IXP4XX_UART2	13
-#define IRQ_IXP4XX_TIMESTAMP	14
-#define IRQ_IXP4XX_UART1	15
-#define IRQ_IXP4XX_WDOG		16
-#define IRQ_IXP4XX_AHB_PMU	17
-#define IRQ_IXP4XX_XSCALE_PMU	18
-#define IRQ_IXP4XX_GPIO2	19
-#define IRQ_IXP4XX_GPIO3	20
-#define IRQ_IXP4XX_GPIO4	21
-#define IRQ_IXP4XX_GPIO5	22
-#define IRQ_IXP4XX_GPIO6	23
-#define IRQ_IXP4XX_GPIO7	24
-#define IRQ_IXP4XX_GPIO8	25
-#define IRQ_IXP4XX_GPIO9	26
-#define IRQ_IXP4XX_GPIO10	27
-#define IRQ_IXP4XX_GPIO11	28
-#define IRQ_IXP4XX_GPIO12	29
-#define IRQ_IXP4XX_SW_INT1	30
-#define IRQ_IXP4XX_SW_INT2	31
-#define IRQ_IXP4XX_USB_HOST	32
-#define IRQ_IXP4XX_I2C		33
-#define IRQ_IXP4XX_SSP		34
-#define IRQ_IXP4XX_TSYNC	35
-#define IRQ_IXP4XX_EAU_DONE	36
-#define IRQ_IXP4XX_SHA_DONE	37
-#define IRQ_IXP4XX_SWCP_PE	58
-#define IRQ_IXP4XX_QM_PE	60
-#define IRQ_IXP4XX_MCU_ECC	61
-#define IRQ_IXP4XX_EXP_PE	62
+#define IRQ_IXP4XX_BASE		16
+
+#define IRQ_IXP4XX_NPEA		(IRQ_IXP4XX_BASE + 0)
+#define IRQ_IXP4XX_NPEB		(IRQ_IXP4XX_BASE + 1)
+#define IRQ_IXP4XX_NPEC		(IRQ_IXP4XX_BASE + 2)
+#define IRQ_IXP4XX_QM1		(IRQ_IXP4XX_BASE + 3)
+#define IRQ_IXP4XX_QM2		(IRQ_IXP4XX_BASE + 4)
+#define IRQ_IXP4XX_TIMER1	(IRQ_IXP4XX_BASE + 5)
+#define IRQ_IXP4XX_GPIO0	(IRQ_IXP4XX_BASE + 6)
+#define IRQ_IXP4XX_GPIO1	(IRQ_IXP4XX_BASE + 7)
+#define IRQ_IXP4XX_PCI_INT	(IRQ_IXP4XX_BASE + 8)
+#define IRQ_IXP4XX_PCI_DMA1	(IRQ_IXP4XX_BASE + 9)
+#define IRQ_IXP4XX_PCI_DMA2	(IRQ_IXP4XX_BASE + 10)
+#define IRQ_IXP4XX_TIMER2	(IRQ_IXP4XX_BASE + 11)
+#define IRQ_IXP4XX_USB		(IRQ_IXP4XX_BASE + 12)
+#define IRQ_IXP4XX_UART2	(IRQ_IXP4XX_BASE + 13)
+#define IRQ_IXP4XX_TIMESTAMP	(IRQ_IXP4XX_BASE + 14)
+#define IRQ_IXP4XX_UART1	(IRQ_IXP4XX_BASE + 15)
+#define IRQ_IXP4XX_WDOG		(IRQ_IXP4XX_BASE + 16)
+#define IRQ_IXP4XX_AHB_PMU	(IRQ_IXP4XX_BASE + 17)
+#define IRQ_IXP4XX_XSCALE_PMU	(IRQ_IXP4XX_BASE + 18)
+#define IRQ_IXP4XX_GPIO2	(IRQ_IXP4XX_BASE + 19)
+#define IRQ_IXP4XX_GPIO3	(IRQ_IXP4XX_BASE + 20)
+#define IRQ_IXP4XX_GPIO4	(IRQ_IXP4XX_BASE + 21)
+#define IRQ_IXP4XX_GPIO5	(IRQ_IXP4XX_BASE + 22)
+#define IRQ_IXP4XX_GPIO6	(IRQ_IXP4XX_BASE + 23)
+#define IRQ_IXP4XX_GPIO7	(IRQ_IXP4XX_BASE + 24)
+#define IRQ_IXP4XX_GPIO8	(IRQ_IXP4XX_BASE + 25)
+#define IRQ_IXP4XX_GPIO9	(IRQ_IXP4XX_BASE + 26)
+#define IRQ_IXP4XX_GPIO10	(IRQ_IXP4XX_BASE + 27)
+#define IRQ_IXP4XX_GPIO11	(IRQ_IXP4XX_BASE + 28)
+#define IRQ_IXP4XX_GPIO12	(IRQ_IXP4XX_BASE + 29)
+#define IRQ_IXP4XX_SW_INT1	(IRQ_IXP4XX_BASE + 30)
+#define IRQ_IXP4XX_SW_INT2	(IRQ_IXP4XX_BASE + 31)
+#define IRQ_IXP4XX_USB_HOST	(IRQ_IXP4XX_BASE + 32)
+#define IRQ_IXP4XX_I2C		(IRQ_IXP4XX_BASE + 33)
+#define IRQ_IXP4XX_SSP		(IRQ_IXP4XX_BASE + 34)
+#define IRQ_IXP4XX_TSYNC	(IRQ_IXP4XX_BASE + 35)
+#define IRQ_IXP4XX_EAU_DONE	(IRQ_IXP4XX_BASE + 36)
+#define IRQ_IXP4XX_SHA_DONE	(IRQ_IXP4XX_BASE + 37)
+#define IRQ_IXP4XX_SWCP_PE	(IRQ_IXP4XX_BASE + 58)
+#define IRQ_IXP4XX_QM_PE	(IRQ_IXP4XX_BASE + 60)
+#define IRQ_IXP4XX_MCU_ECC	(IRQ_IXP4XX_BASE + 61)
+#define IRQ_IXP4XX_EXP_PE	(IRQ_IXP4XX_BASE + 62)
 
 #define _IXP4XX_GPIO_IRQ(n)	(IRQ_IXP4XX_GPIO ## n)
 #define IXP4XX_GPIO_IRQ(n)	_IXP4XX_GPIO_IRQ(n)
 
-/*
- * Only first 32 sources are valid if running on IXP42x systems
- */
-#if defined(CONFIG_CPU_IXP46X) || defined(CONFIG_CPU_IXP43X)
-#define NR_IRQS			64
-#else
-#define NR_IRQS			32
-#endif
+#define NR_IRQS 512
 
 #define	XSCALE_PMU_IRQ		(IRQ_IXP4XX_XSCALE_PMU)
 
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 02/30 v2] ARM: ixp4xx: Pass IRQ resource to beeper
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
  2019-02-21 15:44 ` [PATCH 01/30 v2] ARM: ixp4xx: Convert to MULTI_IRQ_HANDLER Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 15:44 ` [PATCH 03/30 v2] ARM: ixp4xx: Convert to SPARSE_IRQ Linus Walleij
                   ` (28 subsequent siblings)
  30 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa; +Cc: Linus Walleij

All IXP4xx devices except the beeper passes the IRQ as a
resource, augment the NSLU2 beeper to do the same.

This is a prerequisite for SPARSE_IRQ.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/mach-ixp4xx/nslu2-setup.c | 10 +++++++++-
 drivers/input/misc/ixp4xx-beeper.c | 20 +++++++++++++++-----
 2 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c
index 341b263482ef..7c2b6604187e 100644
--- a/arch/arm/mach-ixp4xx/nslu2-setup.c
+++ b/arch/arm/mach-ixp4xx/nslu2-setup.c
@@ -125,10 +125,18 @@ static struct platform_device nslu2_i2c_gpio = {
 	},
 };
 
+static struct resource nslu2_beeper_resources[] = {
+	{
+		.start	= IRQ_IXP4XX_TIMER2,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
 static struct platform_device nslu2_beeper = {
 	.name			= "ixp4xx-beeper",
 	.id			= NSLU2_GPIO_BUZZ,
-	.num_resources		= 0,
+	.resource		= nslu2_beeper_resources,
+	.num_resources		= ARRAY_SIZE(nslu2_beeper_resources),
 };
 
 static struct resource nslu2_uart_resources[] = {
diff --git a/drivers/input/misc/ixp4xx-beeper.c b/drivers/input/misc/ixp4xx-beeper.c
index 1fe149f3def2..4776273fa10b 100644
--- a/drivers/input/misc/ixp4xx-beeper.c
+++ b/drivers/input/misc/ixp4xx-beeper.c
@@ -30,6 +30,8 @@ MODULE_ALIAS("platform:ixp4xx-beeper");
 
 static DEFINE_SPINLOCK(beep_lock);
 
+static int ixp4xx_timer2_irq;
+
 static void ixp4xx_spkr_control(unsigned int pin, unsigned int count)
 {
 	unsigned long flags;
@@ -90,6 +92,7 @@ static irqreturn_t ixp4xx_spkr_interrupt(int irq, void *dev_id)
 static int ixp4xx_spkr_probe(struct platform_device *dev)
 {
 	struct input_dev *input_dev;
+	int irq;
 	int err;
 
 	input_dev = input_allocate_device();
@@ -110,15 +113,22 @@ static int ixp4xx_spkr_probe(struct platform_device *dev)
 	input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
 	input_dev->event = ixp4xx_spkr_event;
 
+	irq = platform_get_irq(dev, 0);
+	if (irq < 0) {
+		err = irq;
+		goto err_free_device;
+	}
+
 	err = gpio_request(dev->id, "ixp4-beeper");
 	if (err)
 		goto err_free_device;
 
-	err = request_irq(IRQ_IXP4XX_TIMER2, &ixp4xx_spkr_interrupt,
+	err = request_irq(irq, &ixp4xx_spkr_interrupt,
 			  IRQF_NO_SUSPEND, "ixp4xx-beeper",
 			  (void *) dev->id);
 	if (err)
 		goto err_free_gpio;
+	ixp4xx_timer2_irq = irq;
 
 	err = input_register_device(input_dev);
 	if (err)
@@ -129,7 +139,7 @@ static int ixp4xx_spkr_probe(struct platform_device *dev)
 	return 0;
 
  err_free_irq:
-	free_irq(IRQ_IXP4XX_TIMER2, (void *)dev->id);
+	free_irq(irq, (void *)dev->id);
  err_free_gpio:
 	gpio_free(dev->id);
  err_free_device:
@@ -146,10 +156,10 @@ static int ixp4xx_spkr_remove(struct platform_device *dev)
 	input_unregister_device(input_dev);
 
 	/* turn the speaker off */
-	disable_irq(IRQ_IXP4XX_TIMER2);
+	disable_irq(ixp4xx_timer2_irq);
 	ixp4xx_spkr_control(pin, 0);
 
-	free_irq(IRQ_IXP4XX_TIMER2, (void *)dev->id);
+	free_irq(ixp4xx_timer2_irq, (void *)dev->id);
 	gpio_free(dev->id);
 
 	return 0;
@@ -161,7 +171,7 @@ static void ixp4xx_spkr_shutdown(struct platform_device *dev)
 	unsigned int pin = (unsigned int) input_get_drvdata(input_dev);
 
 	/* turn off the speaker */
-	disable_irq(IRQ_IXP4XX_TIMER2);
+	disable_irq(ixp4xx_timer2_irq);
 	ixp4xx_spkr_control(pin, 0);
 }
 
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 03/30 v2] ARM: ixp4xx: Convert to SPARSE_IRQ
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
  2019-02-21 15:44 ` [PATCH 01/30 v2] ARM: ixp4xx: Convert to MULTI_IRQ_HANDLER Linus Walleij
  2019-02-21 15:44 ` [PATCH 02/30 v2] ARM: ixp4xx: Pass IRQ resource to beeper Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 15:44 ` [PATCH 04/30 v2] irqchip: Add driver for IXP4xx Linus Walleij
                   ` (27 subsequent siblings)
  30 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa; +Cc: Linus Walleij

This localizes the <mach/irqs.h> header to the mach-ixp4xx
directory, removes NR_IRQS and switches IXP4xx over to using
SPARSE_IRQ.

This is a prerequisite for DT support.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/Kconfig                               | 1 +
 arch/arm/mach-ixp4xx/avila-pci.c               | 2 ++
 arch/arm/mach-ixp4xx/avila-setup.c             | 2 ++
 arch/arm/mach-ixp4xx/common.c                  | 2 ++
 arch/arm/mach-ixp4xx/coyote-pci.c              | 2 ++
 arch/arm/mach-ixp4xx/coyote-setup.c            | 2 ++
 arch/arm/mach-ixp4xx/dsmg600-pci.c             | 2 ++
 arch/arm/mach-ixp4xx/dsmg600-setup.c           | 2 ++
 arch/arm/mach-ixp4xx/fsg-pci.c                 | 2 ++
 arch/arm/mach-ixp4xx/fsg-setup.c               | 2 ++
 arch/arm/mach-ixp4xx/gateway7001-pci.c         | 2 ++
 arch/arm/mach-ixp4xx/gateway7001-setup.c       | 2 ++
 arch/arm/mach-ixp4xx/gtwx5715-pci.c            | 2 ++
 arch/arm/mach-ixp4xx/gtwx5715-setup.c          | 2 ++
 arch/arm/mach-ixp4xx/{include/mach => }/irqs.h | 2 --
 arch/arm/mach-ixp4xx/ixdp425-pci.c             | 2 ++
 arch/arm/mach-ixp4xx/ixdp425-setup.c           | 2 ++
 arch/arm/mach-ixp4xx/ixdpg425-pci.c            | 2 ++
 arch/arm/mach-ixp4xx/ixp4xx_qmgr.c             | 2 ++
 arch/arm/mach-ixp4xx/nas100d-pci.c             | 2 ++
 arch/arm/mach-ixp4xx/nas100d-setup.c           | 2 ++
 arch/arm/mach-ixp4xx/nslu2-pci.c               | 2 ++
 arch/arm/mach-ixp4xx/nslu2-setup.c             | 2 ++
 arch/arm/mach-ixp4xx/wg302v2-pci.c             | 2 ++
 arch/arm/mach-ixp4xx/wg302v2-setup.c           | 2 ++
 25 files changed, 47 insertions(+), 2 deletions(-)
 rename arch/arm/mach-ixp4xx/{include/mach => }/irqs.h (99%)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0bdcacd40591..de2a5647e85d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -435,6 +435,7 @@ config ARCH_IXP4XX
 	select GPIOLIB
 	select HAVE_PCI
 	select NEED_MACH_IO_H
+	select SPARSE_IRQ
 	select USB_EHCI_BIG_ENDIAN_DESC
 	select USB_EHCI_BIG_ENDIAN_MMIO
 	help
diff --git a/arch/arm/mach-ixp4xx/avila-pci.c b/arch/arm/mach-ixp4xx/avila-pci.c
index 548c7d43ade6..9c834f0f4231 100644
--- a/arch/arm/mach-ixp4xx/avila-pci.c
+++ b/arch/arm/mach-ixp4xx/avila-pci.c
@@ -27,6 +27,8 @@
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 
+#include "irqs.h"
+
 #define AVILA_MAX_DEV	4
 #define LOFT_MAX_DEV	6
 #define IRQ_LINES	4
diff --git a/arch/arm/mach-ixp4xx/avila-setup.c b/arch/arm/mach-ixp4xx/avila-setup.c
index 44cbbce6bda6..1981b33109cb 100644
--- a/arch/arm/mach-ixp4xx/avila-setup.c
+++ b/arch/arm/mach-ixp4xx/avila-setup.c
@@ -28,6 +28,8 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 
+#include "irqs.h"
+
 #define AVILA_SDA_PIN	7
 #define AVILA_SCL_PIN	6
 
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 58a1b851425e..aa8fd248c125 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -45,6 +45,8 @@
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
 
+#include "irqs.h"
+
 #define IXP4XX_TIMER_FREQ 66666000
 
 /*
diff --git a/arch/arm/mach-ixp4xx/coyote-pci.c b/arch/arm/mach-ixp4xx/coyote-pci.c
index 5d14ce2aee6d..a16c35d2bb96 100644
--- a/arch/arm/mach-ixp4xx/coyote-pci.c
+++ b/arch/arm/mach-ixp4xx/coyote-pci.c
@@ -23,6 +23,8 @@
 #include <asm/irq.h>
 #include <asm/mach/pci.h>
 
+#include "irqs.h"
+
 #define SLOT0_DEVID	14
 #define SLOT1_DEVID	15
 
diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c
index 7e40fe70933b..7ca43ca2816d 100644
--- a/arch/arm/mach-ixp4xx/coyote-setup.c
+++ b/arch/arm/mach-ixp4xx/coyote-setup.c
@@ -25,6 +25,8 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 
+#include "irqs.h"
+
 #define COYOTE_IDE_BASE_PHYS	IXP4XX_EXP_BUS_BASE(3)
 #define COYOTE_IDE_BASE_VIRT	0xFFFE1000
 #define COYOTE_IDE_REGION_SIZE	0x1000
diff --git a/arch/arm/mach-ixp4xx/dsmg600-pci.c b/arch/arm/mach-ixp4xx/dsmg600-pci.c
index 8dca76937723..6899023bd1b7 100644
--- a/arch/arm/mach-ixp4xx/dsmg600-pci.c
+++ b/arch/arm/mach-ixp4xx/dsmg600-pci.c
@@ -22,6 +22,8 @@
 #include <asm/mach/pci.h>
 #include <asm/mach-types.h>
 
+#include "irqs.h"
+
 #define MAX_DEV		4
 #define IRQ_LINES	3
 
diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c b/arch/arm/mach-ixp4xx/dsmg600-setup.c
index 397190f3a8da..0daaede8fb6d 100644
--- a/arch/arm/mach-ixp4xx/dsmg600-setup.c
+++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c
@@ -35,6 +35,8 @@
 #include <asm/mach/flash.h>
 #include <asm/mach/time.h>
 
+#include "irqs.h"
+
 #define DSMG600_SDA_PIN		5
 #define DSMG600_SCL_PIN		4
 
diff --git a/arch/arm/mach-ixp4xx/fsg-pci.c b/arch/arm/mach-ixp4xx/fsg-pci.c
index fd4a8625b4ae..6c08bb9d9807 100644
--- a/arch/arm/mach-ixp4xx/fsg-pci.c
+++ b/arch/arm/mach-ixp4xx/fsg-pci.c
@@ -22,6 +22,8 @@
 #include <asm/mach/pci.h>
 #include <asm/mach-types.h>
 
+#include "irqs.h"
+
 #define MAX_DEV		3
 #define IRQ_LINES	3
 
diff --git a/arch/arm/mach-ixp4xx/fsg-setup.c b/arch/arm/mach-ixp4xx/fsg-setup.c
index f0a152e365b1..648932d8d7a8 100644
--- a/arch/arm/mach-ixp4xx/fsg-setup.c
+++ b/arch/arm/mach-ixp4xx/fsg-setup.c
@@ -29,6 +29,8 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 
+#include "irqs.h"
+
 #define FSG_SDA_PIN		12
 #define FSG_SCL_PIN		13
 
diff --git a/arch/arm/mach-ixp4xx/gateway7001-pci.c b/arch/arm/mach-ixp4xx/gateway7001-pci.c
index d9d6cc089707..903c75330b76 100644
--- a/arch/arm/mach-ixp4xx/gateway7001-pci.c
+++ b/arch/arm/mach-ixp4xx/gateway7001-pci.c
@@ -27,6 +27,8 @@
 
 #include <asm/mach/pci.h>
 
+#include "irqs.h"
+
 void __init gateway7001_pci_preinit(void)
 {
 	irq_set_irq_type(IRQ_IXP4XX_GPIO10, IRQ_TYPE_LEVEL_LOW);
diff --git a/arch/arm/mach-ixp4xx/gateway7001-setup.c b/arch/arm/mach-ixp4xx/gateway7001-setup.c
index 1be6faf6da9a..678e7dfff0e5 100644
--- a/arch/arm/mach-ixp4xx/gateway7001-setup.c
+++ b/arch/arm/mach-ixp4xx/gateway7001-setup.c
@@ -28,6 +28,8 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 
+#include "irqs.h"
+
 static struct flash_platform_data gateway7001_flash_data = {
 	.map_name	= "cfi_probe",
 	.width		= 2,
diff --git a/arch/arm/mach-ixp4xx/gtwx5715-pci.c b/arch/arm/mach-ixp4xx/gtwx5715-pci.c
index 551d114c9e14..1223d160448f 100644
--- a/arch/arm/mach-ixp4xx/gtwx5715-pci.c
+++ b/arch/arm/mach-ixp4xx/gtwx5715-pci.c
@@ -30,6 +30,8 @@
 #include <mach/hardware.h>
 #include <asm/mach/pci.h>
 
+#include "irqs.h"
+
 #define SLOT0_DEVID	0
 #define SLOT1_DEVID	1
 #define INTA		10 /* slot 1 has INTA and INTB crossed */
diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
index 16a12994fb53..5dbdde8e2338 100644
--- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c
+++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c
@@ -36,6 +36,8 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 
+#include "irqs.h"
+
 /* GPIO 5,6,7 and 12 are hard wired to the Kendin KS8995M Switch
    and operate as an SPI type interface.  The details of the interface
    are available on Kendin/Micrel's web site. */
diff --git a/arch/arm/mach-ixp4xx/include/mach/irqs.h b/arch/arm/mach-ixp4xx/irqs.h
similarity index 99%
rename from arch/arm/mach-ixp4xx/include/mach/irqs.h
rename to arch/arm/mach-ixp4xx/irqs.h
index dadcd4ddb0a9..6b7f220cf9e0 100644
--- a/arch/arm/mach-ixp4xx/include/mach/irqs.h
+++ b/arch/arm/mach-ixp4xx/irqs.h
@@ -63,8 +63,6 @@
 #define _IXP4XX_GPIO_IRQ(n)	(IRQ_IXP4XX_GPIO ## n)
 #define IXP4XX_GPIO_IRQ(n)	_IXP4XX_GPIO_IRQ(n)
 
-#define NR_IRQS 512
-
 #define	XSCALE_PMU_IRQ		(IRQ_IXP4XX_XSCALE_PMU)
 
 #endif
diff --git a/arch/arm/mach-ixp4xx/ixdp425-pci.c b/arch/arm/mach-ixp4xx/ixdp425-pci.c
index 318424dd3c50..c1340465b2ea 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-pci.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-pci.c
@@ -24,6 +24,8 @@
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 
+#include "irqs.h"
+
 #define MAX_DEV		4
 #define IRQ_LINES	4
 
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
index 57d7df79d838..6f0f7ed18ea8 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -32,6 +32,8 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 
+#include "irqs.h"
+
 #define IXDP425_SDA_PIN		7
 #define IXDP425_SCL_PIN		6
 
diff --git a/arch/arm/mach-ixp4xx/ixdpg425-pci.c b/arch/arm/mach-ixp4xx/ixdpg425-pci.c
index 1f8717ba13dc..ac0e9bc6eb4d 100644
--- a/arch/arm/mach-ixp4xx/ixdpg425-pci.c
+++ b/arch/arm/mach-ixp4xx/ixdpg425-pci.c
@@ -23,6 +23,8 @@
 
 #include <asm/mach/pci.h>
 
+#include "irqs.h"
+
 void __init ixdpg425_pci_preinit(void)
 {
 	irq_set_irq_type(IRQ_IXP4XX_GPIO6, IRQ_TYPE_LEVEL_LOW);
diff --git a/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
index 9d1b6b7c394c..4c7c960e1b4c 100644
--- a/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
+++ b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
@@ -14,6 +14,8 @@
 #include <linux/module.h>
 #include <mach/qmgr.h>
 
+#include "irqs.h"
+
 static struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
 static struct resource *mem_res;
 static spinlock_t qmgr_lock;
diff --git a/arch/arm/mach-ixp4xx/nas100d-pci.c b/arch/arm/mach-ixp4xx/nas100d-pci.c
index 8f0eba0a6800..925ef805f966 100644
--- a/arch/arm/mach-ixp4xx/nas100d-pci.c
+++ b/arch/arm/mach-ixp4xx/nas100d-pci.c
@@ -21,6 +21,8 @@
 #include <asm/mach/pci.h>
 #include <asm/mach-types.h>
 
+#include "irqs.h"
+
 #define MAX_DEV		3
 #define IRQ_LINES	3
 
diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c
index 4138d6aa4c52..9d67f8de0772 100644
--- a/arch/arm/mach-ixp4xx/nas100d-setup.c
+++ b/arch/arm/mach-ixp4xx/nas100d-setup.c
@@ -34,6 +34,8 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 
+#include "irqs.h"
+
 #define NAS100D_SDA_PIN		5
 #define NAS100D_SCL_PIN		6
 
diff --git a/arch/arm/mach-ixp4xx/nslu2-pci.c b/arch/arm/mach-ixp4xx/nslu2-pci.c
index 032defe111aa..d69ee4066d20 100644
--- a/arch/arm/mach-ixp4xx/nslu2-pci.c
+++ b/arch/arm/mach-ixp4xx/nslu2-pci.c
@@ -21,6 +21,8 @@
 #include <asm/mach/pci.h>
 #include <asm/mach-types.h>
 
+#include "irqs.h"
+
 #define MAX_DEV		3
 #define IRQ_LINES	3
 
diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c
index 7c2b6604187e..ee1877fcfafe 100644
--- a/arch/arm/mach-ixp4xx/nslu2-setup.c
+++ b/arch/arm/mach-ixp4xx/nslu2-setup.c
@@ -32,6 +32,8 @@
 #include <asm/mach/flash.h>
 #include <asm/mach/time.h>
 
+#include "irqs.h"
+
 #define NSLU2_SDA_PIN		7
 #define NSLU2_SCL_PIN		6
 
diff --git a/arch/arm/mach-ixp4xx/wg302v2-pci.c b/arch/arm/mach-ixp4xx/wg302v2-pci.c
index c92e5b82af36..cf83f7e24179 100644
--- a/arch/arm/mach-ixp4xx/wg302v2-pci.c
+++ b/arch/arm/mach-ixp4xx/wg302v2-pci.c
@@ -27,6 +27,8 @@
 
 #include <asm/mach/pci.h>
 
+#include "irqs.h"
+
 void __init wg302v2_pci_preinit(void)
 {
 	irq_set_irq_type(IRQ_IXP4XX_GPIO8, IRQ_TYPE_LEVEL_LOW);
diff --git a/arch/arm/mach-ixp4xx/wg302v2-setup.c b/arch/arm/mach-ixp4xx/wg302v2-setup.c
index 90b3c604e8b6..8711e299229b 100644
--- a/arch/arm/mach-ixp4xx/wg302v2-setup.c
+++ b/arch/arm/mach-ixp4xx/wg302v2-setup.c
@@ -29,6 +29,8 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 
+#include "irqs.h"
+
 static struct flash_platform_data wg302v2_flash_data = {
 	.map_name	= "cfi_probe",
 	.width		= 2,
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 04/30 v2] irqchip: Add driver for IXP4xx
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (2 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 03/30 v2] ARM: ixp4xx: Convert to SPARSE_IRQ Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-22  9:51   ` Marc Zyngier
  2019-02-21 15:44 ` [PATCH 05/30 v2] gpio: ixp4xx: Add driver for the IXP4xx GPIO Linus Walleij
                   ` (26 subsequent siblings)
  30 siblings, 1 reply; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa
  Cc: Marc Zyngier, Linus Walleij, Thomas Gleixner, Jason Cooper

The IXP4xx (arch/arm/mach-ixp4xx) is an old Intel XScale
platform that has very wide deployment and use.

As part of modernizing the platform, we need to implement a
proper irqchip in the irqchip subsystem.

The IXP4xx irqchip is tightly jotted together with the GPIO
controller, and whereas in the past we would deal with this
complex logic by adding necessarily different code, we can
nowadays modernize it using a hierarchical irqchip.

The actual IXP4 irqchip is a simple active low level IRQ
controller, whereas the GPIO functionality resides in a
different memory area and adds edge trigger support for
the interrupts.

The interrupts from GPIO lines 0..12 are 1:1 mapped to
a fixed set of hardware IRQs on this IRQchip, so we
expect the child GPIO interrupt controller to go in and
allocate descriptors for these interrupts.

For the other interrupts, as we do not yet have DT
support for this platform, we create a linear irqdomain
and then go in and allocate the IRQs that the legacy
boards use. This code will be removed on the DT probe
path when we add DT support to the platform.

We add some translation code for supporting DT
translations for the fwnodes, but we leave most of that
for later.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Deny any other type than LEVEL_HIGH

irqchip maintainers: I am requesting an ACK for this once
you're happy with the driver, as I intend to merge all of
this IXP4xx rework through ARM SoC.
---
 MAINTAINERS                        |   2 +
 drivers/irqchip/Kconfig            |   6 +
 drivers/irqchip/Makefile           |   1 +
 drivers/irqchip/irq-ixp4xx.c       | 362 +++++++++++++++++++++++++++++
 include/linux/irqchip/irq-ixp4xx.h |  12 +
 5 files changed, 383 insertions(+)
 create mode 100644 drivers/irqchip/irq-ixp4xx.c
 create mode 100644 include/linux/irqchip/irq-ixp4xx.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 32d444476a90..0d48faa3e635 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1651,6 +1651,8 @@ M:	Krzysztof Halasa <khalasa@piap.pl>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 F:	arch/arm/mach-ixp4xx/
+F:	drivers/irqchip/irq-ixp4xx.c
+F:	include/linux/irqchip/irq-ixp4xx.h
 
 ARM/INTEL RESEARCH IMOTE/STARGATE 2 MACHINE SUPPORT
 M:	Jonathan Cameron <jic23@cam.ac.uk>
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 3d1e60779078..c7e09913826b 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -150,6 +150,12 @@ config IMGPDC_IRQ
 	select GENERIC_IRQ_CHIP
 	select IRQ_DOMAIN
 
+config IXP4XX_IRQ
+	bool
+	select IRQ_DOMAIN
+	select GENERIC_IRQ_MULTI_HANDLER
+	select SPARSE_IRQ
+
 config MADERA_IRQ
 	tristate
 
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index c93713d24b86..06139d612108 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_ATMEL_AIC5_IRQ)	+= irq-atmel-aic-common.o irq-atmel-aic5.o
 obj-$(CONFIG_I8259)			+= irq-i8259.o
 obj-$(CONFIG_IMGPDC_IRQ)		+= irq-imgpdc.o
 obj-$(CONFIG_IRQ_MIPS_CPU)		+= irq-mips-cpu.o
+obj-$(CONFIG_IXP4XX_IRQ)		+= irq-ixp4xx.o
 obj-$(CONFIG_SIRF_IRQ)			+= irq-sirfsoc.o
 obj-$(CONFIG_JCORE_AIC)			+= irq-jcore-aic.o
 obj-$(CONFIG_RDA_INTC)			+= irq-rda-intc.o
diff --git a/drivers/irqchip/irq-ixp4xx.c b/drivers/irqchip/irq-ixp4xx.c
new file mode 100644
index 000000000000..89c80ce047a7
--- /dev/null
+++ b/drivers/irqchip/irq-ixp4xx.c
@@ -0,0 +1,362 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * irqchip for the IXP4xx interrupt controller
+ * Copyright (C) 2019 Linus Walleij <linus.walleij@linaro.org>
+ *
+ * Based on arch/arm/mach-ixp4xx/common.c
+ * Copyright 2002 (C) Intel Corporation
+ * Copyright 2003-2004 (C) MontaVista, Software, Inc.
+ * Copyright (C) Deepak Saxena <dsaxena@plexity.net>
+ */
+#include <linux/bitops.h>
+#include <linux/gpio/driver.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/irq-ixp4xx.h>
+#include <linux/irqdomain.h>
+#include <linux/platform_device.h>
+#include <linux/cpu.h>
+
+#include <asm/exception.h>
+#include <asm/mach/irq.h>
+
+#define IXP4XX_ICPR	0x00 /* Interrupt Status */
+#define IXP4XX_ICMR	0x04 /* Interrupt Enable */
+#define IXP4XX_ICLR	0x08 /* Interrupt IRQ/FIQ Select */
+#define IXP4XX_ICIP	0x0C /* IRQ Status */
+#define IXP4XX_ICFP	0x10 /* FIQ Status */
+#define IXP4XX_ICHR	0x14 /* Interrupt Priority */
+#define IXP4XX_ICIH	0x18 /* IRQ Highest Pri Int */
+#define IXP4XX_ICFH	0x1C /* FIQ Highest Pri Int */
+
+/* IXP43x and IXP46x-only */
+#define	IXP4XX_ICPR2	0x20 /* Interrupt Status 2 */
+#define	IXP4XX_ICMR2	0x24 /* Interrupt Enable 2 */
+#define	IXP4XX_ICLR2	0x28 /* Interrupt IRQ/FIQ Select 2 */
+#define IXP4XX_ICIP2	0x2C /* IRQ Status */
+#define IXP4XX_ICFP2	0x30 /* FIQ Status */
+#define IXP4XX_ICEEN	0x34 /* Error High Pri Enable */
+
+/**
+ * struct ixp4xx_irq - state container for the Faraday IRQ controller
+ * @irqbase: IRQ controller memory base in virtual memory
+ * @is_356: if this is an IXP43x, IXP45x or IX46x SoC (with 64 IRQs)
+ * @irqchip: irqchip for this instance
+ * @domain: IRQ domain for this instance
+ */
+struct ixp4xx_irq {
+	void __iomem *irqbase;
+	bool is_356;
+	struct irq_chip irqchip;
+	struct irq_domain *domain;
+};
+
+/* Local static state container */
+static struct ixp4xx_irq ixirq;
+
+/* GPIO Clocks */
+#define IXP4XX_GPIO_CLK_0		14
+#define IXP4XX_GPIO_CLK_1		15
+
+static int ixp4xx_set_irq_type(struct irq_data *d, unsigned int type)
+{
+	/* All are level active high (asserted) here */
+	if (type != IRQ_TYPE_LEVEL_HIGH)
+		return -EINVAL;
+	return 0;
+}
+
+static void ixp4xx_irq_mask(struct irq_data *d)
+{
+	struct ixp4xx_irq *ixi = irq_data_get_irq_chip_data(d);
+	u32 val;
+
+	if (ixi->is_356 && d->hwirq >= 32) {
+		val = __raw_readl(ixi->irqbase + IXP4XX_ICMR2);
+		val &= ~BIT(d->hwirq - 32);
+		__raw_writel(val, ixi->irqbase + IXP4XX_ICMR2);
+	} else {
+		val = __raw_readl(ixi->irqbase + IXP4XX_ICMR);
+		val &= ~BIT(d->hwirq);
+		__raw_writel(val, ixi->irqbase + IXP4XX_ICMR);
+	}
+}
+
+/*
+ * Level triggered interrupts on GPIO lines can only be cleared when the
+ * interrupt condition disappears.
+ */
+static void ixp4xx_irq_unmask(struct irq_data *d)
+{
+	struct ixp4xx_irq *ixi = irq_data_get_irq_chip_data(d);
+	u32 val;
+
+	if (ixi->is_356 && d->hwirq >= 32) {
+		val = __raw_readl(ixi->irqbase + IXP4XX_ICMR2);
+		val |= BIT(d->hwirq - 32);
+		__raw_writel(val, ixi->irqbase + IXP4XX_ICMR2);
+	} else {
+		val = __raw_readl(ixi->irqbase + IXP4XX_ICMR);
+		val |= BIT(d->hwirq);
+		__raw_writel(val, ixi->irqbase + IXP4XX_ICMR);
+	}
+}
+
+asmlinkage void __exception_irq_entry ixp4xx_handle_irq(struct pt_regs *regs)
+{
+	struct ixp4xx_irq *ixi = &ixirq;
+	unsigned long status;
+	int i;
+
+	status = __raw_readl(ixi->irqbase + IXP4XX_ICIP);
+	for_each_set_bit(i, &status, 32)
+		handle_domain_irq(ixi->domain, i, regs);
+
+	/*
+	 * IXP465/IXP435 has an upper IRQ status register
+	 */
+	if (ixi->is_356) {
+		status = __raw_readl(ixi->irqbase + IXP4XX_ICIP2);
+		for_each_set_bit(i, &status, 32)
+			handle_domain_irq(ixi->domain, i + 32, regs);
+	}
+}
+
+static int ixp4xx_irq_domain_translate(struct irq_domain *domain,
+				       struct irq_fwspec *fwspec,
+				       unsigned long *hwirq,
+				       unsigned int *type)
+{
+	/* We support standard DT translation */
+	if (is_of_node(fwspec->fwnode) && fwspec->param_count == 2) {
+		*hwirq = fwspec->param[0];
+		*type = fwspec->param[1];
+		return 0;
+	}
+
+	if (is_fwnode_irqchip(fwspec->fwnode)) {
+		if (fwspec->param_count != 2)
+			return -EINVAL;
+		*hwirq = fwspec->param[0];
+		*type = fwspec->param[1];
+		WARN_ON(*type == IRQ_TYPE_NONE);
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int ixp4xx_irq_domain_alloc(struct irq_domain *d,
+				   unsigned int irq, unsigned int nr_irqs,
+				   void *data)
+{
+	struct ixp4xx_irq *ixi = d->host_data;
+	irq_hw_number_t hwirq;
+	unsigned int type = IRQ_TYPE_NONE;
+	struct irq_fwspec *fwspec = data;
+	int ret;
+	int i;
+
+	ret = ixp4xx_irq_domain_translate(d, fwspec, &hwirq, &type);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < nr_irqs; i++) {
+		/*
+		 * TODO: after converting IXP4xx to only device tree, set
+		 * handle_bad_irq as default handler and assume all consumers
+		 * call .set_type() as this is provided in the second cell in
+		 * the device tree phandle.
+		 */
+		irq_domain_set_info(d,
+				    irq + i,
+				    hwirq + i,
+				    &ixi->irqchip,
+				    ixi,
+				    handle_level_irq,
+				    NULL, NULL);
+		irq_set_probe(irq + i);
+	}
+
+	return 0;
+}
+
+/*
+ * This needs to be a hierarchical irqdomain to work well with the
+ * GPIO irqchip (which is lower in the hierarchy)
+ */
+static const struct irq_domain_ops ixp4xx_irqdomain_ops = {
+	.translate = ixp4xx_irq_domain_translate,
+	.alloc = ixp4xx_irq_domain_alloc,
+	.free = irq_domain_free_irqs_common,
+};
+
+/**
+ * ixp4xx_get_irq_domain() - retrieve the ixp4xx irq domain
+ *
+ * This function will go away when we transition to DT probing.
+ */
+struct irq_domain *ixp4xx_get_irq_domain(void)
+{
+	struct ixp4xx_irq *ixi = &ixirq;
+
+	return ixi->domain;
+}
+EXPORT_SYMBOL_GPL(ixp4xx_get_irq_domain);
+
+/*
+ * This is the Linux IRQ to hwirq mapping table. This goes away when
+ * we have DT support as all IRQ resources are defined in the device
+ * tree. It will register all the IRQs that are not used by the hierarchical
+ * GPIO IRQ chip. The "holes" inbetween these IRQs will be requested by
+ * the GPIO driver using . This is a step-gap solution.
+ */
+struct ixp4xx_irq_chunk {
+	int irq;
+	int hwirq;
+	int nr_irqs;
+};
+
+static const struct ixp4xx_irq_chunk ixp4xx_irq_chunks[] = {
+	{
+		.irq = 16,
+		.hwirq = 0,
+		.nr_irqs = 6,
+	},
+	{
+		.irq = 24,
+		.hwirq = 8,
+		.nr_irqs = 11,
+	},
+	{
+		.irq = 46,
+		.hwirq = 30,
+		.nr_irqs = 2,
+	},
+	/* Only on the 436 variants */
+	{
+		.irq = 48,
+		.hwirq = 32,
+		.nr_irqs = 10,
+	},
+};
+
+/**
+ * ixp4x_irq_setup() - Common setup code for the IXP4xx interrupt controller
+ * @ixi: State container
+ * @irqbase: Virtual memory base for the interrupt controller
+ * @fwnode: Corresponding fwnode abstraction for this controller
+ * @is_356: if this is an IXP43x, IXP45x or IXP46x SoC variant
+ */
+static int ixp4xx_irq_setup(struct ixp4xx_irq *ixi,
+			    void __iomem *irqbase,
+			    struct fwnode_handle *fwnode,
+			    bool is_356)
+{
+	int nr_irqs;
+
+	ixi->irqbase = irqbase;
+	ixi->is_356 = is_356;
+
+	/* Route all sources to IRQ instead of FIQ */
+	__raw_writel(0x0, ixi->irqbase + IXP4XX_ICLR);
+
+	/* Disable all interrupts */
+	__raw_writel(0x0, ixi->irqbase + IXP4XX_ICMR);
+
+	if (is_356) {
+		/* Route upper 32 sources to IRQ instead of FIQ */
+		__raw_writel(0x0, ixi->irqbase + IXP4XX_ICLR2);
+
+		/* Disable upper 32 interrupts */
+		__raw_writel(0x0, ixi->irqbase + IXP4XX_ICMR2);
+
+		nr_irqs = 64;
+	} else {
+		nr_irqs = 32;
+	}
+
+	ixi->irqchip.name = "IXP4xx";
+	ixi->irqchip.irq_mask = ixp4xx_irq_mask;
+	ixi->irqchip.irq_unmask	= ixp4xx_irq_unmask;
+	ixi->irqchip.irq_set_type = ixp4xx_set_irq_type;
+
+	ixi->domain = irq_domain_create_linear(fwnode, nr_irqs,
+					       &ixp4xx_irqdomain_ops,
+					       ixi);
+	if (!ixi->domain) {
+		pr_crit("IXP4XX: can not add primary irqdomain\n");
+		return -ENODEV;
+	}
+
+	set_handle_irq(ixp4xx_handle_irq);
+
+	return 0;
+}
+
+/**
+ * ixp4xx_irq_init() - Function to initialize the irqchip from boardfiles
+ * @irqbase: physical base for the irq controller
+ * @is_356: if this is an IXP43x, IXP45x or IXP46x SoC variant
+ */
+void __init ixp4xx_irq_init(resource_size_t irqbase,
+			    bool is_356)
+{
+	struct ixp4xx_irq *ixi = &ixirq;
+	void __iomem *base;
+	struct fwnode_handle *fwnode;
+	struct irq_fwspec fwspec;
+	int nr_chunks;
+	int ret;
+	int i;
+
+	base = ioremap(irqbase, 0x100);
+	if (!base) {
+		pr_crit("IXP4XX: could not ioremap interrupt controller\n");
+		return;
+	}
+	fwnode = irq_domain_alloc_fwnode(base);
+	if (!fwnode) {
+		pr_crit("IXP4XX: no domain handle\n");
+		return;
+	}
+	ret = ixp4xx_irq_setup(ixi, base, fwnode, is_356);
+	if (ret) {
+		pr_crit("IXP4XX: failed to set up irqchip\n");
+		irq_domain_free_fwnode(fwnode);
+	}
+
+	nr_chunks = ARRAY_SIZE(ixp4xx_irq_chunks);
+	if (!is_356)
+		nr_chunks--;
+
+	/*
+	 * After adding OF support, this is no longer needed: irqs
+	 * will be allocated for the respective fwnodes.
+	 */
+	for (i = 0; i < nr_chunks; i++) {
+		const struct ixp4xx_irq_chunk *chunk = &ixp4xx_irq_chunks[i];
+
+		pr_info("Allocate Linux IRQs %d..%d HW IRQs %d..%d\n",
+			chunk->irq, chunk->irq + chunk->nr_irqs - 1,
+			chunk->hwirq, chunk->hwirq + chunk->nr_irqs - 1);
+		fwspec.fwnode = fwnode;
+		fwspec.param[0] = chunk->hwirq;
+		fwspec.param[1] = IRQ_TYPE_LEVEL_HIGH;
+		fwspec.param_count = 2;
+		ret = __irq_domain_alloc_irqs(ixi->domain,
+					      chunk->irq,
+					      chunk->nr_irqs,
+					      NUMA_NO_NODE,
+					      &fwspec,
+					      false,
+					      NULL);
+		if (ret < 0) {
+			pr_crit("IXP4XX: can not allocate irqs in hierarchy %d\n",
+				ret);
+			return;
+		}
+	}
+}
+EXPORT_SYMBOL_GPL(ixp4xx_irq_init);
diff --git a/include/linux/irqchip/irq-ixp4xx.h b/include/linux/irqchip/irq-ixp4xx.h
new file mode 100644
index 000000000000..9395917d6936
--- /dev/null
+++ b/include/linux/irqchip/irq-ixp4xx.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __IRQ_IXP4XX_H
+#define __IRQ_IXP4XX_H
+
+#include <linux/ioport.h>
+struct irq_domain;
+
+void ixp4xx_irq_init(resource_size_t irqbase,
+		     bool is_356);
+struct irq_domain *ixp4xx_get_irq_domain(void);
+
+#endif /* __IRQ_IXP4XX_H */
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 05/30 v2] gpio: ixp4xx: Add driver for the IXP4xx GPIO
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (3 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 04/30 v2] irqchip: Add driver for IXP4xx Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 15:44 ` [PATCH 06/30 v2] ARM: ixp4xx: Switch to use new IRQ+GPIO drivers Linus Walleij
                   ` (25 subsequent siblings)
  30 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa
  Cc: Bartosz Golaszewski, Linus Walleij

This adds a driver for the IXP4xx GPIO block found in
the Intel XScale IXP4xx systems.

The GPIO part of this block is pretty straight-forward and
just uses the generic MMIO GPIO library.

The irqchip side of this driver is hierarchical where
the main irqchip will receive a processed level trigger
in response to the edge detector of the GPIO block,
so for this reason the v2 version of the irqdomain API
is used (as well as in the parent IXP4xx irqchip) and
masking, unmasking and setting up the type on IRQ
happens on several levels.

Currently this GPIO controller will grab the parent
irqdomain using a special function, but as the platform
move toward device tree probing, this will not be needed:
we can just look up the parent irqdomain from the device
tree.

Cc: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Fix comment style in header
- Fix register naming to be more intuitive
---
 MAINTAINERS                |   1 +
 drivers/gpio/Kconfig       |  12 +
 drivers/gpio/Makefile      |   1 +
 drivers/gpio/gpio-ixp4xx.c | 444 +++++++++++++++++++++++++++++++++++++
 4 files changed, 458 insertions(+)
 create mode 100644 drivers/gpio/gpio-ixp4xx.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 0d48faa3e635..6c161bd82238 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1651,6 +1651,7 @@ M:	Krzysztof Halasa <khalasa@piap.pl>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 F:	arch/arm/mach-ixp4xx/
+F:	drivers/gpio/gpio-ixp4xx.c
 F:	drivers/irqchip/irq-ixp4xx.c
 F:	include/linux/irqchip/irq-ixp4xx.h
 
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 699a8118c433..fe4a47e49a24 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -286,6 +286,18 @@ config GPIO_IOP
 
 	  If unsure, say N.
 
+config GPIO_IXP4XX
+	bool "Intel IXP4xx GPIO"
+	depends on ARCH_IXP4XX || COMPILE_TEST
+	select GPIO_GENERIC
+	select IRQ_DOMAIN
+	select IRQ_DOMAIN_HIERARCHY
+	help
+	  Say yes here to support the GPIO functionality of a number of Intel
+	  IXP4xx series of chips.
+
+	  If unsure, say N.
+
 config GPIO_LOONGSON
 	bool "Loongson-2/3 GPIO support"
 	depends on CPU_LOONGSON2 || CPU_LOONGSON3
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 0568bbe6fe68..cf66523b5eec 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -60,6 +60,7 @@ obj-$(CONFIG_GPIO_HLWD)		+= gpio-hlwd.o
 obj-$(CONFIG_HTC_EGPIO)		+= gpio-htc-egpio.o
 obj-$(CONFIG_GPIO_ICH)		+= gpio-ich.o
 obj-$(CONFIG_GPIO_IOP)		+= gpio-iop.o
+obj-$(CONFIG_GPIO_IXP4XX)	+= gpio-ixp4xx.o
 obj-$(CONFIG_GPIO_IT87)		+= gpio-it87.o
 obj-$(CONFIG_GPIO_JANZ_TTL)	+= gpio-janz-ttl.o
 obj-$(CONFIG_GPIO_KEMPLD)	+= gpio-kempld.o
diff --git a/drivers/gpio/gpio-ixp4xx.c b/drivers/gpio/gpio-ixp4xx.c
new file mode 100644
index 000000000000..eaf317f73f75
--- /dev/null
+++ b/drivers/gpio/gpio-ixp4xx.c
@@ -0,0 +1,444 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// IXP4 GPIO driver
+// Copyright (C) 2019 Linus Walleij <linus.walleij@linaro.org>
+//
+// based on previous work and know-how from:
+// Deepak Saxena <dsaxena@plexity.net>
+
+#include <linux/gpio/driver.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip.h>
+#include <linux/platform_device.h>
+#include <linux/bitops.h>
+/* Include that go away with DT transition */
+#include <linux/irqchip/irq-ixp4xx.h>
+
+#include <asm/mach-types.h>
+
+#define IXP4XX_REG_GPOUT	0x00
+#define IXP4XX_REG_GPOE		0x04
+#define IXP4XX_REG_GPIN		0x08
+#define IXP4XX_REG_GPIS		0x0C
+#define IXP4XX_REG_GPIT1	0x10
+#define IXP4XX_REG_GPIT2	0x14
+#define IXP4XX_REG_GPCLK	0x18
+#define IXP4XX_REG_GPDBSEL	0x1C
+
+/*
+ * The hardware uses 3 bits to indicate interrupt "style".
+ * we clear and set these three bits accordingly. The lower 24
+ * bits in two registers (GPIT1 and GPIT2) are used to set up
+ * the style for 8 lines each for a total of 16 GPIO lines.
+ */
+#define IXP4XX_GPIO_STYLE_ACTIVE_HIGH	0x0
+#define IXP4XX_GPIO_STYLE_ACTIVE_LOW	0x1
+#define IXP4XX_GPIO_STYLE_RISING_EDGE	0x2
+#define IXP4XX_GPIO_STYLE_FALLING_EDGE	0x3
+#define IXP4XX_GPIO_STYLE_TRANSITIONAL	0x4
+#define IXP4XX_GPIO_STYLE_MASK		GENMASK(2, 0)
+#define IXP4XX_GPIO_STYLE_SIZE		3
+
+/**
+ * struct ixp4xx_gpio - IXP4 GPIO state container
+ * @dev: containing device for this instance
+ * @fwnode: the fwnode for this GPIO chip
+ * @gc: gpiochip for this instance
+ * @domain: irqdomain for this chip instance
+ * @base: remapped I/O-memory base
+ * @irq_edge: Each bit represents an IRQ: 1: edge-triggered,
+ * 0: level triggered
+ */
+struct ixp4xx_gpio {
+	struct device *dev;
+	struct fwnode_handle *fwnode;
+	struct gpio_chip gc;
+	struct irq_domain *domain;
+	void __iomem *base;
+	unsigned long long irq_edge;
+};
+
+/**
+ * struct ixp4xx_gpio_map - IXP4 GPIO to parent IRQ map
+ * @gpio_offset: offset of the IXP4 GPIO line
+ * @parent_hwirq: hwirq on the parent IRQ controller
+ */
+struct ixp4xx_gpio_map {
+	int gpio_offset;
+	int parent_hwirq;
+};
+
+/* GPIO lines 0..12 have corresponding IRQs, GPIOs 13..15 have no IRQs */
+const struct ixp4xx_gpio_map ixp4xx_gpiomap[] = {
+	{ .gpio_offset = 0, .parent_hwirq = 6 },
+	{ .gpio_offset = 1, .parent_hwirq = 7 },
+	{ .gpio_offset = 2, .parent_hwirq = 19 },
+	{ .gpio_offset = 3, .parent_hwirq = 20 },
+	{ .gpio_offset = 4, .parent_hwirq = 21 },
+	{ .gpio_offset = 5, .parent_hwirq = 22 },
+	{ .gpio_offset = 6, .parent_hwirq = 23 },
+	{ .gpio_offset = 7, .parent_hwirq = 24 },
+	{ .gpio_offset = 8, .parent_hwirq = 25 },
+	{ .gpio_offset = 9, .parent_hwirq = 26 },
+	{ .gpio_offset = 10, .parent_hwirq = 27 },
+	{ .gpio_offset = 11, .parent_hwirq = 28 },
+	{ .gpio_offset = 12, .parent_hwirq = 29 },
+};
+
+static void ixp4xx_gpio_irq_ack(struct irq_data *d)
+{
+	struct ixp4xx_gpio *g = irq_data_get_irq_chip_data(d);
+
+	__raw_writel(BIT(d->hwirq), g->base + IXP4XX_REG_GPIS);
+}
+
+static void ixp4xx_gpio_irq_unmask(struct irq_data *d)
+{
+	struct ixp4xx_gpio *g = irq_data_get_irq_chip_data(d);
+
+	/* ACK when unmasking if not edge-triggered */
+	if (!(g->irq_edge & BIT(d->hwirq)))
+		ixp4xx_gpio_irq_ack(d);
+
+	irq_chip_unmask_parent(d);
+}
+
+static int ixp4xx_gpio_irq_set_type(struct irq_data *d, unsigned int type)
+{
+	struct ixp4xx_gpio *g = irq_data_get_irq_chip_data(d);
+	int line = d->hwirq;
+	unsigned long flags;
+	u32 int_style;
+	u32 int_reg;
+	u32 val;
+
+	switch (type) {
+	case IRQ_TYPE_EDGE_BOTH:
+		irq_set_handler_locked(d, handle_edge_irq);
+		int_style = IXP4XX_GPIO_STYLE_TRANSITIONAL;
+		g->irq_edge |= BIT(d->hwirq);
+		break;
+	case IRQ_TYPE_EDGE_RISING:
+		irq_set_handler_locked(d, handle_edge_irq);
+		int_style = IXP4XX_GPIO_STYLE_RISING_EDGE;
+		g->irq_edge |= BIT(d->hwirq);
+		break;
+	case IRQ_TYPE_EDGE_FALLING:
+		irq_set_handler_locked(d, handle_edge_irq);
+		int_style = IXP4XX_GPIO_STYLE_FALLING_EDGE;
+		g->irq_edge |= BIT(d->hwirq);
+		break;
+	case IRQ_TYPE_LEVEL_HIGH:
+		irq_set_handler_locked(d, handle_level_irq);
+		int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH;
+		g->irq_edge &= ~BIT(d->hwirq);
+		break;
+	case IRQ_TYPE_LEVEL_LOW:
+		irq_set_handler_locked(d, handle_level_irq);
+		int_style = IXP4XX_GPIO_STYLE_ACTIVE_LOW;
+		g->irq_edge &= ~BIT(d->hwirq);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (line >= 8) {
+		/* pins 8-15 */
+		line -= 8;
+		int_reg = IXP4XX_REG_GPIT2;
+	} else {
+		/* pins 0-7 */
+		int_reg = IXP4XX_REG_GPIT1;
+	}
+
+	spin_lock_irqsave(&g->gc.bgpio_lock, flags);
+
+	/* Clear the style for the appropriate pin */
+	val = __raw_readl(g->base + int_reg);
+	val &= ~(IXP4XX_GPIO_STYLE_MASK << (line * IXP4XX_GPIO_STYLE_SIZE));
+	__raw_writel(val, g->base + int_reg);
+
+	__raw_writel(BIT(line), g->base + IXP4XX_REG_GPIS);
+
+	/* Set the new style */
+	val = __raw_readl(g->base + int_reg);
+	val |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE));
+	__raw_writel(val, g->base + int_reg);
+
+	/* Force-configure this line as an input */
+	val = __raw_readl(g->base + IXP4XX_REG_GPOE);
+	val |= BIT(d->hwirq);
+	__raw_writel(val, g->base + IXP4XX_REG_GPOE);
+
+	spin_unlock_irqrestore(&g->gc.bgpio_lock, flags);
+
+	/* This parent only accept level high (asserted) */
+	return irq_chip_set_type_parent(d, IRQ_TYPE_LEVEL_HIGH);
+}
+
+static struct irq_chip ixp4xx_gpio_irqchip = {
+	.name = "IXP4GPIO",
+	.irq_ack = ixp4xx_gpio_irq_ack,
+	.irq_mask = irq_chip_mask_parent,
+	.irq_unmask = ixp4xx_gpio_irq_unmask,
+	.irq_set_type = ixp4xx_gpio_irq_set_type,
+};
+
+static int ixp4xx_gpio_to_irq(struct gpio_chip *gc, unsigned int offset)
+{
+	struct ixp4xx_gpio *g = gpiochip_get_data(gc);
+	struct irq_fwspec fwspec;
+
+	fwspec.fwnode = g->fwnode;
+	fwspec.param_count = 2;
+	fwspec.param[0] = offset;
+	fwspec.param[1] = IRQ_TYPE_NONE;
+
+	return irq_create_fwspec_mapping(&fwspec);
+}
+
+static int ixp4xx_gpio_irq_domain_translate(struct irq_domain *domain,
+					    struct irq_fwspec *fwspec,
+					    unsigned long *hwirq,
+					    unsigned int *type)
+{
+
+	/* We support standard DT translation */
+	if (is_of_node(fwspec->fwnode) && fwspec->param_count == 2) {
+		*hwirq = fwspec->param[0];
+		*type = fwspec->param[1];
+		return 0;
+	}
+
+	/* This goes away when we transition to DT */
+	if (is_fwnode_irqchip(fwspec->fwnode)) {
+		if (fwspec->param_count != 2)
+			return -EINVAL;
+		*hwirq = fwspec->param[0];
+		*type = fwspec->param[1];
+		WARN_ON(*type == IRQ_TYPE_NONE);
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static int ixp4xx_gpio_irq_domain_alloc(struct irq_domain *d,
+					unsigned int irq, unsigned int nr_irqs,
+					void *data)
+{
+	struct ixp4xx_gpio *g = d->host_data;
+	irq_hw_number_t hwirq;
+	unsigned int type = IRQ_TYPE_NONE;
+	struct irq_fwspec *fwspec = data;
+	int ret;
+	int i;
+
+	ret = ixp4xx_gpio_irq_domain_translate(d, fwspec, &hwirq, &type);
+	if (ret)
+		return ret;
+
+	dev_dbg(g->dev, "allocate IRQ %d..%d, hwirq %lu..%lu\n",
+		irq, irq + nr_irqs - 1,
+		hwirq, hwirq + nr_irqs - 1);
+
+	for (i = 0; i < nr_irqs; i++) {
+		struct irq_fwspec parent_fwspec;
+		const struct ixp4xx_gpio_map *map;
+		int j;
+
+		/* Not all lines support IRQs */
+		for (j = 0; j < ARRAY_SIZE(ixp4xx_gpiomap); j++) {
+			map = &ixp4xx_gpiomap[j];
+			if (map->gpio_offset == hwirq)
+				break;
+		}
+		if (j == ARRAY_SIZE(ixp4xx_gpiomap)) {
+			dev_err(g->dev, "can't look up hwirq %lu\n", hwirq);
+			return -EINVAL;
+		}
+		dev_dbg(g->dev, "found parent hwirq %u\n", map->parent_hwirq);
+
+		/*
+		 * We set handle_bad_irq because the .set_type() should
+		 * always be invoked and set the right type of handler.
+		 */
+		irq_domain_set_info(d,
+				    irq + i,
+				    hwirq + i,
+				    &ixp4xx_gpio_irqchip,
+				    g,
+				    handle_bad_irq,
+				    NULL, NULL);
+		irq_set_probe(irq + i);
+
+		/*
+		 * Create a IRQ fwspec to send up to the parent irqdomain:
+		 * specify the hwirq we address on the parent and tie it
+		 * all together up the chain.
+		 */
+		parent_fwspec.fwnode = d->parent->fwnode;
+		parent_fwspec.param_count = 2;
+		parent_fwspec.param[0] = map->parent_hwirq;
+		/* This parent only handles asserted level IRQs */
+		parent_fwspec.param[1] = IRQ_TYPE_LEVEL_HIGH;
+		dev_dbg(g->dev, "alloc_irqs_parent for %d parent hwirq %d\n",
+			irq + i, map->parent_hwirq);
+		ret = irq_domain_alloc_irqs_parent(d, irq + i, 1,
+						   &parent_fwspec);
+		if (ret)
+			dev_err(g->dev,
+				"failed to allocate parent hwirq %d for hwirq %lu\n",
+				map->parent_hwirq, hwirq);
+	}
+
+	return 0;
+}
+
+static const struct irq_domain_ops ixp4xx_gpio_irqdomain_ops = {
+	.translate = ixp4xx_gpio_irq_domain_translate,
+	.alloc = ixp4xx_gpio_irq_domain_alloc,
+	.free = irq_domain_free_irqs_common,
+};
+
+static int ixp4xx_gpio_probe(struct platform_device *pdev)
+{
+	unsigned long flags;
+	struct device *dev = &pdev->dev;
+	struct irq_domain *parent;
+	struct resource *res;
+	struct ixp4xx_gpio *g;
+	int ret;
+	int i;
+
+	g = devm_kzalloc(dev, sizeof(*g), GFP_KERNEL);
+	if (!g)
+		return -ENOMEM;
+	g->dev = dev;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	g->base = devm_ioremap_resource(dev, res);
+	if (IS_ERR(g->base)) {
+		dev_err(dev, "ioremap error\n");
+		return PTR_ERR(g->base);
+	}
+
+	/*
+	 * Make sure GPIO 14 and 15 are NOT used as clocks but GPIO on
+	 * specific machines.
+	 */
+	if (machine_is_dsmg600() || machine_is_nas100d())
+		__raw_writel(0x0, g->base + IXP4XX_REG_GPCLK);
+
+	/*
+	 * This is a very special big-endian ARM issue: when the IXP4xx is
+	 * run in big endian mode, all registers in the machine are switched
+	 * around to the CPU-native endianness. As you see mostly in the
+	 * driver we use __raw_readl()/__raw_writel() to access the registers
+	 * in the appropriate order. With the GPIO library we need to specify
+	 * byte order explicitly, so this flag needs to be set when compiling
+	 * for big endian.
+	 */
+#if defined(CONFIG_CPU_BIG_ENDIAN)
+	flags = BGPIOF_BIG_ENDIAN_BYTE_ORDER;
+#else
+	flags = 0;
+#endif
+
+	/* Populate and register gpio chip */
+	ret = bgpio_init(&g->gc, dev, 4,
+			 g->base + IXP4XX_REG_GPIN,
+			 g->base + IXP4XX_REG_GPOUT,
+			 NULL,
+			 NULL,
+			 g->base + IXP4XX_REG_GPOE,
+			 flags);
+	if (ret) {
+		dev_err(dev, "unable to init generic GPIO\n");
+		return ret;
+	}
+	g->gc.to_irq = ixp4xx_gpio_to_irq;
+	g->gc.ngpio = 16;
+	g->gc.label = "IXP4XX_GPIO_CHIP";
+	/*
+	 * TODO: when we have migrated to device tree and all GPIOs
+	 * are fetched using phandles, set this to -1 to get rid of
+	 * the fixed gpiochip base.
+	 */
+	g->gc.base = 0;
+	g->gc.parent = &pdev->dev;
+	g->gc.owner = THIS_MODULE;
+
+	ret = devm_gpiochip_add_data(dev, &g->gc, g);
+	if (ret) {
+		dev_err(dev, "failed to add SoC gpiochip\n");
+		return ret;
+	}
+
+	/*
+	 * When we convert to device tree we will simply look up the
+	 * parent irqdomain using irq_find_host(parent) as parent comes
+	 * from IRQCHIP_DECLARE(), then use of_node_to_fwnode() to get
+	 * the fwnode. For now we need this boardfile style code.
+	 */
+	parent = ixp4xx_get_irq_domain();
+	g->fwnode = irq_domain_alloc_fwnode(g->base);
+	if (!g->fwnode) {
+		dev_err(dev, "no domain base\n");
+		return -ENODEV;
+	}
+	g->domain = irq_domain_create_hierarchy(parent,
+						IRQ_DOMAIN_FLAG_HIERARCHY,
+						ARRAY_SIZE(ixp4xx_gpiomap),
+						g->fwnode,
+						&ixp4xx_gpio_irqdomain_ops,
+						g);
+	if (!g->domain) {
+		irq_domain_free_fwnode(g->fwnode);
+		dev_err(dev, "no hierarchical irq domain\n");
+		return ret;
+	}
+
+	/*
+	 * After adding OF support, this is no longer needed: irqs
+	 * will be allocated for the respective fwnodes.
+	 */
+	for (i = 0; i < ARRAY_SIZE(ixp4xx_gpiomap); i++) {
+		const struct ixp4xx_gpio_map *map = &ixp4xx_gpiomap[i];
+		struct irq_fwspec fwspec;
+
+		fwspec.fwnode = g->fwnode;
+		/* This is the hwirq for the GPIO line side of things */
+		fwspec.param[0] = map->gpio_offset;
+		fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
+		fwspec.param_count = 2;
+		ret = __irq_domain_alloc_irqs(g->domain,
+					      -1, /* just pick something */
+					      1,
+					      NUMA_NO_NODE,
+					      &fwspec,
+					      false,
+					      NULL);
+		if (ret < 0) {
+			irq_domain_free_fwnode(g->fwnode);
+			dev_err(dev,
+				"can not allocate irq for GPIO line %d parent hwirq %d in hierarchy domain: %d\n",
+				map->gpio_offset, map->parent_hwirq, ret);
+			return ret;
+		}
+	}
+
+	platform_set_drvdata(pdev, g);
+	dev_info(dev, "IXP4 GPIO @%p registered\n", g->base);
+
+	return 0;
+}
+
+static struct platform_driver ixp4xx_gpio_driver = {
+	.driver = {
+		.name		= "ixp4xx-gpio",
+	},
+	.probe = ixp4xx_gpio_probe,
+};
+builtin_platform_driver(ixp4xx_gpio_driver);
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 06/30 v2] ARM: ixp4xx: Switch to use new IRQ+GPIO drivers
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (4 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 05/30 v2] gpio: ixp4xx: Add driver for the IXP4xx GPIO Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-22  9:51   ` Marc Zyngier
  2019-02-21 15:44 ` [PATCH 07/30 v2] clocksource/drivers/ixp4xx: Add driver Linus Walleij
                   ` (24 subsequent siblings)
  30 siblings, 1 reply; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa
  Cc: Marc Zyngier, Bartosz Golaszewski, Linus Walleij,
	Thomas Gleixner, Jason Cooper

This deletes the old irq+gpiochip combo from the IXP4xx
machine and switches it over to use the new drivers merged
in respective subsystem.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
IRQ+GPIO folks: here you see how I activate those new
drivers. Intended to be merged through ARM SoC.
---
 arch/arm/Kconfig                              |   3 +-
 arch/arm/mach-ixp4xx/common.c                 | 318 ++----------------
 arch/arm/mach-ixp4xx/dsmg600-setup.c          |   3 -
 .../mach-ixp4xx/include/mach/ixp4xx-regs.h    |  89 -----
 arch/arm/mach-ixp4xx/nas100d-setup.c          |   3 -
 5 files changed, 24 insertions(+), 392 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index de2a5647e85d..f6345594cef0 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -432,10 +432,11 @@ config ARCH_IXP4XX
 	select DMABOUNCE if PCI
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_IRQ_MULTI_HANDLER
+	select GPIO_IXP4XX
 	select GPIOLIB
 	select HAVE_PCI
+	select IXP4XX_IRQ
 	select NEED_MACH_IO_H
-	select SPARSE_IRQ
 	select USB_EHCI_BIG_ENDIAN_DESC
 	select USB_EHCI_BIG_ENDIAN_MMIO
 	help
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index aa8fd248c125..71683dfc48f9 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -27,11 +27,11 @@
 #include <linux/clockchips.h>
 #include <linux/io.h>
 #include <linux/export.h>
-#include <linux/gpio/driver.h>
 #include <linux/cpu.h>
 #include <linux/pci.h>
 #include <linux/sched_clock.h>
 #include <linux/bitops.h>
+#include <linux/irqchip/irq-ixp4xx.h>
 #include <mach/udc.h>
 #include <mach/hardware.h>
 #include <mach/io.h>
@@ -58,7 +58,6 @@
 				       (IXP4XX_OST_RELOAD_MASK + 1) * HZ) * \
 			(IXP4XX_OST_RELOAD_MASK + 1)
 
-static struct irq_domain *ixp4xx_irqdomain;
 static void __init ixp4xx_clocksource_init(void);
 static void __init ixp4xx_clockevent_init(void);
 static struct clock_event_device clockevent_ixp4xx;
@@ -95,266 +94,18 @@ void __init ixp4xx_map_io(void)
   	iotable_init(ixp4xx_io_desc, ARRAY_SIZE(ixp4xx_io_desc));
 }
 
-/*
- * GPIO-functions
- */
-/*
- * The following converted to the real HW bits the gpio_line_config
- */
-/* GPIO pin types */
-#define IXP4XX_GPIO_OUT 		0x1
-#define IXP4XX_GPIO_IN  		0x2
-
-/* GPIO signal types */
-#define IXP4XX_GPIO_LOW			0
-#define IXP4XX_GPIO_HIGH		1
-
-/* GPIO Clocks */
-#define IXP4XX_GPIO_CLK_0		14
-#define IXP4XX_GPIO_CLK_1		15
-
-static void gpio_line_config(u8 line, u32 direction)
-{
-	if (direction == IXP4XX_GPIO_IN)
-		*IXP4XX_GPIO_GPOER |= (1 << line);
-	else
-		*IXP4XX_GPIO_GPOER &= ~(1 << line);
-}
-
-static void gpio_line_get(u8 line, int *value)
-{
-	*value = (*IXP4XX_GPIO_GPINR >> line) & 0x1;
-}
-
-static void gpio_line_set(u8 line, int value)
-{
-	if (value == IXP4XX_GPIO_HIGH)
-	    *IXP4XX_GPIO_GPOUTR |= (1 << line);
-	else if (value == IXP4XX_GPIO_LOW)
-	    *IXP4XX_GPIO_GPOUTR &= ~(1 << line);
-}
-
-/*************************************************************************
- * IXP4xx chipset IRQ handling
- *
- * TODO: GPIO IRQs should be marked invalid until the user of the IRQ
- *       (be it PCI or something else) configures that GPIO line
- *       as an IRQ.
- **************************************************************************/
-enum ixp4xx_irq_type {
-	IXP4XX_IRQ_LEVEL, IXP4XX_IRQ_EDGE
-};
-
-/* Each bit represents an IRQ: 1: edge-triggered, 0: level triggered */
-static unsigned long long ixp4xx_irq_edge = 0;
-
-/*
- * IRQ -> GPIO mapping table
- */
-static signed char irq2gpio[32] = {
-	-1, -1, -1, -1, -1, -1,  0,  1,
-	-1, -1, -1, -1, -1, -1, -1, -1,
-	-1, -1, -1,  2,  3,  4,  5,  6,
-	 7,  8,  9, 10, 11, 12, -1, -1,
-};
-
-static int ixp4xx_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
-{
-	int irq;
-
-	for (irq = 0; irq < 32; irq++) {
-		if (irq2gpio[irq] == gpio)
-			return irq;
-	}
-	return -EINVAL;
-}
-
-static int ixp4xx_set_irq_type(struct irq_data *d, unsigned int type)
-{
-	int line = irq2gpio[d->hwirq];
-	u32 int_style;
-	enum ixp4xx_irq_type irq_type;
-	volatile u32 *int_reg;
-
-	/*
-	 * Only for GPIO IRQs
-	 * all other IRQs are simply active low
-	 */
-	if (line < 0)
-		return 0;
-
-	switch (type){
-	case IRQ_TYPE_EDGE_BOTH:
-		int_style = IXP4XX_GPIO_STYLE_TRANSITIONAL;
-		irq_type = IXP4XX_IRQ_EDGE;
-		break;
-	case IRQ_TYPE_EDGE_RISING:
-		int_style = IXP4XX_GPIO_STYLE_RISING_EDGE;
-		irq_type = IXP4XX_IRQ_EDGE;
-		break;
-	case IRQ_TYPE_EDGE_FALLING:
-		int_style = IXP4XX_GPIO_STYLE_FALLING_EDGE;
-		irq_type = IXP4XX_IRQ_EDGE;
-		break;
-	case IRQ_TYPE_LEVEL_HIGH:
-		int_style = IXP4XX_GPIO_STYLE_ACTIVE_HIGH;
-		irq_type = IXP4XX_IRQ_LEVEL;
-		break;
-	case IRQ_TYPE_LEVEL_LOW:
-		int_style = IXP4XX_GPIO_STYLE_ACTIVE_LOW;
-		irq_type = IXP4XX_IRQ_LEVEL;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	if (irq_type == IXP4XX_IRQ_EDGE)
-		ixp4xx_irq_edge |= (1 << d->hwirq);
-	else
-		ixp4xx_irq_edge &= ~(1 << d->hwirq);
-
-	if (line >= 8) {	/* pins 8-15 */
-		line -= 8;
-		int_reg = IXP4XX_GPIO_GPIT2R;
-	} else {		/* pins 0-7 */
-		int_reg = IXP4XX_GPIO_GPIT1R;
-	}
-
-	/* Clear the style for the appropriate pin */
-	*int_reg &= ~(IXP4XX_GPIO_STYLE_CLEAR <<
-	    		(line * IXP4XX_GPIO_STYLE_SIZE));
-
-	*IXP4XX_GPIO_GPISR = (1 << line);
-
-	/* Set the new style */
-	*int_reg |= (int_style << (line * IXP4XX_GPIO_STYLE_SIZE));
-
-	/* Configure the line as an input */
-	gpio_line_config(irq2gpio[d->hwirq], IXP4XX_GPIO_IN);
-
-	return 0;
-}
-
-static void ixp4xx_irq_mask(struct irq_data *d)
-{
-	if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && d->hwirq >= 32)
-		*IXP4XX_ICMR2 &= ~(1 << (d->hwirq - 32));
-	else
-		*IXP4XX_ICMR &= ~(1 << d->hwirq);
-}
-
-static void ixp4xx_irq_ack(struct irq_data *d)
-{
-	int line = (d->hwirq < 32) ? irq2gpio[d->hwirq] : -1;
-
-	if (line >= 0)
-		*IXP4XX_GPIO_GPISR = (1 << line);
-}
-
-/*
- * Level triggered interrupts on GPIO lines can only be cleared when the
- * interrupt condition disappears.
- */
-static void ixp4xx_irq_unmask(struct irq_data *d)
-{
-	if (!(ixp4xx_irq_edge & (1 << d->hwirq)))
-		ixp4xx_irq_ack(d);
-
-	if ((cpu_is_ixp46x() || cpu_is_ixp43x()) && d->hwirq >= 32)
-		*IXP4XX_ICMR2 |= (1 << (d->hwirq - 32));
-	else
-		*IXP4XX_ICMR |= (1 << d->hwirq);
-}
-
-static struct irq_chip ixp4xx_irq_chip = {
-	.name		= "IXP4xx",
-	.irq_ack	= ixp4xx_irq_ack,
-	.irq_mask	= ixp4xx_irq_mask,
-	.irq_unmask	= ixp4xx_irq_unmask,
-	.irq_set_type	= ixp4xx_set_irq_type,
-};
-
-asmlinkage void __exception_irq_entry ixp4xx_handle_irq(struct pt_regs *regs)
-{
-	unsigned long status;
-	int i;
-
-	status = *IXP4XX_ICIP;
-
-	for_each_set_bit(i, &status, 32)
-		handle_domain_irq(ixp4xx_irqdomain, i, regs);
-
-	/*
-	 * IXP465/IXP435 has an upper IRQ status register
-	 */
-	if ((cpu_is_ixp46x() || cpu_is_ixp43x())) {
-		status = *IXP4XX_ICIP2;
-		for_each_set_bit(i, &status, 32)
-			handle_domain_irq(ixp4xx_irqdomain, i + 32, regs);
-	}
-}
-
-static int ixp4xx_irqdomain_map(struct irq_domain *d, unsigned int irq,
-				irq_hw_number_t hwirq)
-{
-	irq_set_chip_data(irq, &ixp4xx_irq_chip);
-	irq_set_chip_and_handler(irq, &ixp4xx_irq_chip, handle_level_irq);
-	irq_set_probe(irq);
-
-	return 0;
-}
-
-static void ixp4xx_irqdomain_unmap(struct irq_domain *d, unsigned int irq)
-{
-	irq_set_chip_and_handler(irq, NULL, NULL);
-	irq_set_chip_data(irq, NULL);
-}
-
-static const struct irq_domain_ops ixp4xx_irqdomain_ops = {
-	.map = ixp4xx_irqdomain_map,
-	.unmap = ixp4xx_irqdomain_unmap,
-};
-
 void __init ixp4xx_init_irq(void)
 {
-	int nr_irqs;
-
 	/*
 	 * ixp4xx does not implement the XScale PWRMODE register
 	 * so it must not call cpu_do_idle().
 	 */
 	cpu_idle_poll_ctrl(true);
 
-	/* Route all sources to IRQ instead of FIQ */
-	*IXP4XX_ICLR = 0x0;
-
-	/* Disable all interrupt */
-	*IXP4XX_ICMR = 0x0; 
-
-	if (cpu_is_ixp46x() || cpu_is_ixp43x()) {
-		/* Route upper 32 sources to IRQ instead of FIQ */
-		*IXP4XX_ICLR2 = 0x00;
-
-		/* Disable upper 32 interrupts */
-		*IXP4XX_ICMR2 = 0x00;
-
-		nr_irqs = 64;
-	} else {
-		nr_irqs = 32;
-	}
-
-	ixp4xx_irqdomain = irq_domain_add_simple(NULL, nr_irqs, IRQ_IXP4XX_BASE,
-						 &ixp4xx_irqdomain_ops,
-						 NULL);
-	if (!ixp4xx_irqdomain) {
-		pr_crit("can not add primary irqdomain\n");
-		return;
-	}
-
-	set_handle_irq(ixp4xx_handle_irq);
+	ixp4xx_irq_init(IXP4XX_INTC_BASE_PHYS,
+			(cpu_is_ixp46x() || cpu_is_ixp43x()));
 }
 
-
 /*************************************************************************
  * IXP4xx timer tick
  * We use OS timer1 on the CPU for the timer tick and the timestamp 
@@ -408,6 +159,24 @@ static struct resource ixp4xx_udc_resources[] = {
 	},
 };
 
+static struct resource ixp4xx_gpio_resource[] = {
+	{
+		.start = IXP4XX_GPIO_BASE_PHYS,
+		.end = IXP4XX_GPIO_BASE_PHYS + 0xfff,
+		.flags = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device ixp4xx_gpio_device = {
+	.name           = "ixp4xx-gpio",
+	.id             = -1,
+	.dev = {
+		.coherent_dma_mask      = DMA_BIT_MASK(32),
+	},
+	.resource = ixp4xx_gpio_resource,
+	.num_resources  = ARRAY_SIZE(ixp4xx_gpio_resource),
+};
+
 /*
  * USB device controller. The IXP4xx uses the same controller as PXA25X,
  * so we just use the same device.
@@ -423,6 +192,7 @@ static struct platform_device ixp4xx_udc_device = {
 };
 
 static struct platform_device *ixp4xx_devices[] __initdata = {
+	&ixp4xx_gpio_device,
 	&ixp4xx_udc_device,
 };
 
@@ -457,56 +227,12 @@ static struct platform_device *ixp46x_devices[] __initdata = {
 unsigned long ixp4xx_exp_bus_size;
 EXPORT_SYMBOL(ixp4xx_exp_bus_size);
 
-static int ixp4xx_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
-{
-	gpio_line_config(gpio, IXP4XX_GPIO_IN);
-
-	return 0;
-}
-
-static int ixp4xx_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
-					int level)
-{
-	gpio_line_set(gpio, level);
-	gpio_line_config(gpio, IXP4XX_GPIO_OUT);
-
-	return 0;
-}
-
-static int ixp4xx_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
-{
-	int value;
-
-	gpio_line_get(gpio, &value);
-
-	return value;
-}
-
-static void ixp4xx_gpio_set_value(struct gpio_chip *chip, unsigned gpio,
-				  int value)
-{
-	gpio_line_set(gpio, value);
-}
-
-static struct gpio_chip ixp4xx_gpio_chip = {
-	.label			= "IXP4XX_GPIO_CHIP",
-	.direction_input	= ixp4xx_gpio_direction_input,
-	.direction_output	= ixp4xx_gpio_direction_output,
-	.get			= ixp4xx_gpio_get_value,
-	.set			= ixp4xx_gpio_set_value,
-	.to_irq			= ixp4xx_gpio_to_irq,
-	.base			= 0,
-	.ngpio			= 16,
-};
-
 void __init ixp4xx_sys_init(void)
 {
 	ixp4xx_exp_bus_size = SZ_16M;
 
 	platform_add_devices(ixp4xx_devices, ARRAY_SIZE(ixp4xx_devices));
 
-	gpiochip_add_data(&ixp4xx_gpio_chip, NULL);
-
 	if (cpu_is_ixp46x()) {
 		int region;
 
diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c b/arch/arm/mach-ixp4xx/dsmg600-setup.c
index 0daaede8fb6d..4d4c62fced71 100644
--- a/arch/arm/mach-ixp4xx/dsmg600-setup.c
+++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c
@@ -270,9 +270,6 @@ static void __init dsmg600_init(void)
 {
 	ixp4xx_sys_init();
 
-	/* Make sure that GPIO14 and GPIO15 are not used as clocks */
-	*IXP4XX_GPIO_GPCLKR = 0;
-
 	dsmg600_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
 	dsmg600_flash_resource.end =
 		IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
diff --git a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
index b7ddd27419c2..459abe2eb4b5 100644
--- a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
+++ b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
@@ -147,95 +147,6 @@
 #define IXP4XX_I2C_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x11000)
 #define IXP4XX_SSP_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x12000)
 
-/*
- * Constants to make it easy to access  Interrupt Controller registers
- */
-#define IXP4XX_ICPR_OFFSET	0x00 /* Interrupt Status */
-#define IXP4XX_ICMR_OFFSET	0x04 /* Interrupt Enable */
-#define IXP4XX_ICLR_OFFSET	0x08 /* Interrupt IRQ/FIQ Select */
-#define IXP4XX_ICIP_OFFSET      0x0C /* IRQ Status */
-#define IXP4XX_ICFP_OFFSET	0x10 /* FIQ Status */
-#define IXP4XX_ICHR_OFFSET	0x14 /* Interrupt Priority */
-#define IXP4XX_ICIH_OFFSET	0x18 /* IRQ Highest Pri Int */
-#define IXP4XX_ICFH_OFFSET	0x1C /* FIQ Highest Pri Int */
-
-/*
- * IXP465-only
- */
-#define	IXP4XX_ICPR2_OFFSET	0x20 /* Interrupt Status 2 */
-#define	IXP4XX_ICMR2_OFFSET	0x24 /* Interrupt Enable 2 */
-#define	IXP4XX_ICLR2_OFFSET	0x28 /* Interrupt IRQ/FIQ Select 2 */
-#define IXP4XX_ICIP2_OFFSET     0x2C /* IRQ Status */
-#define IXP4XX_ICFP2_OFFSET	0x30 /* FIQ Status */
-#define IXP4XX_ICEEN_OFFSET	0x34 /* Error High Pri Enable */
-
-
-/*
- * Interrupt Controller Register Definitions.
- */
-
-#define IXP4XX_INTC_REG(x) ((volatile u32 *)(IXP4XX_INTC_BASE_VIRT+(x)))
-
-#define IXP4XX_ICPR	IXP4XX_INTC_REG(IXP4XX_ICPR_OFFSET)
-#define IXP4XX_ICMR     IXP4XX_INTC_REG(IXP4XX_ICMR_OFFSET)
-#define IXP4XX_ICLR     IXP4XX_INTC_REG(IXP4XX_ICLR_OFFSET)
-#define IXP4XX_ICIP     IXP4XX_INTC_REG(IXP4XX_ICIP_OFFSET)
-#define IXP4XX_ICFP     IXP4XX_INTC_REG(IXP4XX_ICFP_OFFSET)
-#define IXP4XX_ICHR     IXP4XX_INTC_REG(IXP4XX_ICHR_OFFSET)
-#define IXP4XX_ICIH     IXP4XX_INTC_REG(IXP4XX_ICIH_OFFSET) 
-#define IXP4XX_ICFH     IXP4XX_INTC_REG(IXP4XX_ICFH_OFFSET)
-#define IXP4XX_ICPR2	IXP4XX_INTC_REG(IXP4XX_ICPR2_OFFSET)
-#define IXP4XX_ICMR2    IXP4XX_INTC_REG(IXP4XX_ICMR2_OFFSET)
-#define IXP4XX_ICLR2    IXP4XX_INTC_REG(IXP4XX_ICLR2_OFFSET)
-#define IXP4XX_ICIP2    IXP4XX_INTC_REG(IXP4XX_ICIP2_OFFSET)
-#define IXP4XX_ICFP2    IXP4XX_INTC_REG(IXP4XX_ICFP2_OFFSET)
-#define IXP4XX_ICEEN    IXP4XX_INTC_REG(IXP4XX_ICEEN_OFFSET)
-                                                                                
-/*
- * Constants to make it easy to access GPIO registers
- */
-#define IXP4XX_GPIO_GPOUTR_OFFSET       0x00
-#define IXP4XX_GPIO_GPOER_OFFSET        0x04
-#define IXP4XX_GPIO_GPINR_OFFSET        0x08
-#define IXP4XX_GPIO_GPISR_OFFSET        0x0C
-#define IXP4XX_GPIO_GPIT1R_OFFSET	0x10
-#define IXP4XX_GPIO_GPIT2R_OFFSET	0x14
-#define IXP4XX_GPIO_GPCLKR_OFFSET	0x18
-#define IXP4XX_GPIO_GPDBSELR_OFFSET	0x1C
-
-/* 
- * GPIO Register Definitions.
- * [Only perform 32bit reads/writes]
- */
-#define IXP4XX_GPIO_REG(x) ((volatile u32 *)(IXP4XX_GPIO_BASE_VIRT+(x)))
-
-#define IXP4XX_GPIO_GPOUTR	IXP4XX_GPIO_REG(IXP4XX_GPIO_GPOUTR_OFFSET)
-#define IXP4XX_GPIO_GPOER       IXP4XX_GPIO_REG(IXP4XX_GPIO_GPOER_OFFSET)
-#define IXP4XX_GPIO_GPINR       IXP4XX_GPIO_REG(IXP4XX_GPIO_GPINR_OFFSET)
-#define IXP4XX_GPIO_GPISR       IXP4XX_GPIO_REG(IXP4XX_GPIO_GPISR_OFFSET)
-#define IXP4XX_GPIO_GPIT1R      IXP4XX_GPIO_REG(IXP4XX_GPIO_GPIT1R_OFFSET)
-#define IXP4XX_GPIO_GPIT2R      IXP4XX_GPIO_REG(IXP4XX_GPIO_GPIT2R_OFFSET)
-#define IXP4XX_GPIO_GPCLKR      IXP4XX_GPIO_REG(IXP4XX_GPIO_GPCLKR_OFFSET)
-#define IXP4XX_GPIO_GPDBSELR    IXP4XX_GPIO_REG(IXP4XX_GPIO_GPDBSELR_OFFSET)
-
-/*
- * GPIO register bit definitions
- */
-
-/* Interrupt styles
- */
-#define IXP4XX_GPIO_STYLE_ACTIVE_HIGH	0x0
-#define IXP4XX_GPIO_STYLE_ACTIVE_LOW	0x1
-#define IXP4XX_GPIO_STYLE_RISING_EDGE	0x2
-#define IXP4XX_GPIO_STYLE_FALLING_EDGE	0x3
-#define IXP4XX_GPIO_STYLE_TRANSITIONAL	0x4
-
-/* 
- * Mask used to clear interrupt styles 
- */
-#define IXP4XX_GPIO_STYLE_CLEAR		0x7
-#define IXP4XX_GPIO_STYLE_SIZE		3
-
 /*
  * Constants to make it easy to access Timer Control/Status registers
  */
diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c
index 9d67f8de0772..c142cfa8c5d6 100644
--- a/arch/arm/mach-ixp4xx/nas100d-setup.c
+++ b/arch/arm/mach-ixp4xx/nas100d-setup.c
@@ -281,9 +281,6 @@ static void __init nas100d_init(void)
 
 	ixp4xx_sys_init();
 
-	/* gpio 14 and 15 are _not_ clocks */
-	*IXP4XX_GPIO_GPCLKR = 0;
-
 	nas100d_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
 	nas100d_flash_resource.end =
 		IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 07/30 v2] clocksource/drivers/ixp4xx: Add driver
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (5 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 06/30 v2] ARM: ixp4xx: Switch to use new IRQ+GPIO drivers Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 20:54   ` Daniel Lezcano
  2019-02-21 15:44 ` [PATCH 08/30 v2] ARM: ixp4xx: Switch to use new timer driver Linus Walleij
                   ` (23 subsequent siblings)
  30 siblings, 1 reply; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa
  Cc: Linus Walleij, Daniel Lezcano, Thomas Gleixner

This adds a new slightly rewritten timer driver for the
Intel IXP4xx clocksource, clockevent and delay timer.

Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
Clocksource/timer maintainers: I am requesting an ACK for
this once you're happy with the driver, as I intend to
merge all of this IXP4xx rework through ARM SoC.
---
 MAINTAINERS                                |   2 +
 drivers/clocksource/Kconfig                |   7 +
 drivers/clocksource/Makefile               |   1 +
 drivers/clocksource/timer-ixp4xx.c         | 249 +++++++++++++++++++++
 include/linux/platform_data/timer-ixp4xx.h |  11 +
 5 files changed, 270 insertions(+)
 create mode 100644 drivers/clocksource/timer-ixp4xx.c
 create mode 100644 include/linux/platform_data/timer-ixp4xx.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 6c161bd82238..a2fb67b75026 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1651,9 +1651,11 @@ M:	Krzysztof Halasa <khalasa@piap.pl>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 F:	arch/arm/mach-ixp4xx/
+F:	drivers/clocksource/timer-ixp4xx.c
 F:	drivers/gpio/gpio-ixp4xx.c
 F:	drivers/irqchip/irq-ixp4xx.c
 F:	include/linux/irqchip/irq-ixp4xx.h
+F:	include/linux/platform_data/timer-ixp4xx.h
 
 ARM/INTEL RESEARCH IMOTE/STARGATE 2 MACHINE SUPPORT
 M:	Jonathan Cameron <jic23@cam.ac.uk>
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a9e26f6a81a1..d290d6c6576d 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -69,6 +69,13 @@ config FTTMR010_TIMER
 	  Enables support for the Faraday Technology timer block
 	  FTTMR010.
 
+config IXP4XX_TIMER
+	bool "Intel XScale IXP4xx timer driver" if COMPILE_TEST
+	depends on HAS_IOMEM
+	select CLKSRC_MMIO
+	help
+	  Enables support for the Intel XScale IXP4xx SoC timer.
+
 config ROCKCHIP_TIMER
 	bool "Rockchip timer driver" if COMPILE_TEST
 	depends on ARM || ARM64
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index cdd210ff89ea..18158257ebb3 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_OMAP_DM_TIMER)	+= timer-ti-dm.o
 obj-$(CONFIG_DW_APB_TIMER)	+= dw_apb_timer.o
 obj-$(CONFIG_DW_APB_TIMER_OF)	+= dw_apb_timer_of.o
 obj-$(CONFIG_FTTMR010_TIMER)	+= timer-fttmr010.o
+obj-$(CONFIG_IXP4XX_TIMER)	+= timer-ixp4xx.o
 obj-$(CONFIG_ROCKCHIP_TIMER)      += timer-rockchip.o
 obj-$(CONFIG_CLKSRC_NOMADIK_MTU)	+= nomadik-mtu.o
 obj-$(CONFIG_CLKSRC_DBX500_PRCMU)	+= clksrc-dbx500-prcmu.o
diff --git a/drivers/clocksource/timer-ixp4xx.c b/drivers/clocksource/timer-ixp4xx.c
new file mode 100644
index 000000000000..fa78f80792db
--- /dev/null
+++ b/drivers/clocksource/timer-ixp4xx.c
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IXP4 timer driver
+ * Copyright (C) 2019 Linus Walleij <linus.walleij@linaro.org>
+ *
+ * Based on arch/arm/mach-ixp4xx/common.c
+ * Copyright 2002 (C) Intel Corporation
+ * Copyright 2003-2004 (C) MontaVista, Software, Inc.
+ * Copyright (C) Deepak Saxena <dsaxena@plexity.net>
+ */
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/sched_clock.h>
+#include <linux/slab.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+/* Goes away with OF conversion */
+#include <linux/platform_data/timer-ixp4xx.h>
+
+/*
+ * Constants to make it easy to access Timer Control/Status registers
+ */
+#define IXP4XX_OSTS_OFFSET	0x00  /* Continuous Timestamp */
+#define IXP4XX_OST1_OFFSET	0x04  /* Timer 1 Timestamp */
+#define IXP4XX_OSRT1_OFFSET	0x08  /* Timer 1 Reload */
+#define IXP4XX_OST2_OFFSET	0x0C  /* Timer 2 Timestamp */
+#define IXP4XX_OSRT2_OFFSET	0x10  /* Timer 2 Reload */
+#define IXP4XX_OSWT_OFFSET	0x14  /* Watchdog Timer */
+#define IXP4XX_OSWE_OFFSET	0x18  /* Watchdog Enable */
+#define IXP4XX_OSWK_OFFSET	0x1C  /* Watchdog Key */
+#define IXP4XX_OSST_OFFSET	0x20  /* Timer Status */
+
+/*
+ * Timer register values and bit definitions
+ */
+#define IXP4XX_OST_ENABLE		0x00000001
+#define IXP4XX_OST_ONE_SHOT		0x00000002
+/* Low order bits of reload value ignored */
+#define IXP4XX_OST_RELOAD_MASK		0x00000003
+#define IXP4XX_OST_DISABLED		0x00000000
+#define IXP4XX_OSST_TIMER_1_PEND	0x00000001
+#define IXP4XX_OSST_TIMER_2_PEND	0x00000002
+#define IXP4XX_OSST_TIMER_TS_PEND	0x00000004
+#define IXP4XX_OSST_TIMER_WDOG_PEND	0x00000008
+#define IXP4XX_OSST_TIMER_WARM_RESET	0x00000010
+
+#define	IXP4XX_WDT_KEY			0x0000482E
+#define	IXP4XX_WDT_RESET_ENABLE		0x00000001
+#define	IXP4XX_WDT_IRQ_ENABLE		0x00000002
+#define	IXP4XX_WDT_COUNT_ENABLE		0x00000004
+
+struct ixp4xx_timer {
+	void __iomem *base;
+	unsigned int tick_rate;
+	u32 latch;
+	struct clock_event_device clkevt;
+#ifdef CONFIG_ARM
+	struct delay_timer delay_timer;
+#endif
+};
+
+/*
+ * A local singleton used by sched_clock and delay timer reads, which are
+ * fast and stateless
+ */
+static struct ixp4xx_timer *local_ixp4xx_timer;
+
+static inline struct ixp4xx_timer *
+to_ixp4xx_timer(struct clock_event_device *evt)
+{
+	return container_of(evt, struct ixp4xx_timer, clkevt);
+}
+
+static u64 notrace ixp4xx_read_sched_clock(void)
+{
+	return __raw_readl(local_ixp4xx_timer->base + IXP4XX_OSTS_OFFSET);
+}
+
+static u64 ixp4xx_clocksource_read(struct clocksource *c)
+{
+	return __raw_readl(local_ixp4xx_timer->base + IXP4XX_OSTS_OFFSET);
+}
+
+static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id)
+{
+	struct ixp4xx_timer *tmr = dev_id;
+	struct clock_event_device *evt = &tmr->clkevt;
+
+	/* Clear Pending Interrupt */
+	__raw_writel(IXP4XX_OSST_TIMER_1_PEND,
+		     tmr->base + IXP4XX_OSST_OFFSET);
+
+	evt->event_handler(evt);
+
+	return IRQ_HANDLED;
+}
+
+static int ixp4xx_set_next_event(unsigned long cycles,
+				 struct clock_event_device *evt)
+{
+	struct ixp4xx_timer *tmr = to_ixp4xx_timer(evt);
+	u32 val;
+
+	val = __raw_readl(tmr->base + IXP4XX_OSRT1_OFFSET);
+	/* Keep enable/oneshot bits */
+	val &= IXP4XX_OST_RELOAD_MASK;
+	__raw_writel((cycles & ~IXP4XX_OST_RELOAD_MASK) | val,
+		     tmr->base + IXP4XX_OSRT1_OFFSET);
+
+	return 0;
+}
+
+static int ixp4xx_shutdown(struct clock_event_device *evt)
+{
+	struct ixp4xx_timer *tmr = to_ixp4xx_timer(evt);
+	u32 val;
+
+	val = __raw_readl(tmr->base + IXP4XX_OSRT1_OFFSET);
+	val &= ~IXP4XX_OST_ENABLE;
+	__raw_writel(val, tmr->base + IXP4XX_OSRT1_OFFSET);
+
+	return 0;
+}
+
+static int ixp4xx_set_oneshot(struct clock_event_device *evt)
+{
+	struct ixp4xx_timer *tmr = to_ixp4xx_timer(evt);
+
+	__raw_writel(IXP4XX_OST_ENABLE | IXP4XX_OST_ONE_SHOT,
+		     tmr->base + IXP4XX_OSRT1_OFFSET);
+
+	return 0;
+}
+
+static int ixp4xx_set_periodic(struct clock_event_device *evt)
+{
+	struct ixp4xx_timer *tmr = to_ixp4xx_timer(evt);
+	u32 val;
+
+	val = tmr->latch & ~IXP4XX_OST_RELOAD_MASK;
+	val |= IXP4XX_OST_ENABLE;
+	__raw_writel(val, tmr->base + IXP4XX_OSRT1_OFFSET);
+
+	return 0;
+}
+
+static int ixp4xx_resume(struct clock_event_device *evt)
+{
+	struct ixp4xx_timer *tmr = to_ixp4xx_timer(evt);
+	u32 val;
+
+	val = __raw_readl(tmr->base + IXP4XX_OSRT1_OFFSET);
+	val |= IXP4XX_OST_ENABLE;
+	__raw_writel(val, tmr->base + IXP4XX_OSRT1_OFFSET);
+
+	return 0;
+}
+
+/*
+ * IXP4xx timer tick
+ * We use OS timer1 on the CPU for the timer tick and the timestamp
+ * counter as a source of real clock ticks to account for missed jiffies.
+ */
+static __init int ixp4xx_timer_register(void __iomem *base,
+					int timer_irq,
+					unsigned int timer_freq)
+{
+	struct ixp4xx_timer *tmr;
+	int ret;
+
+	tmr = kzalloc(sizeof(*tmr), GFP_KERNEL);
+	if (!tmr)
+		return -ENOMEM;
+	tmr->base = base;
+	tmr->tick_rate = timer_freq;
+
+	/*
+	 * The timer register doesn't allow to specify the two least
+	 * significant bits of the timeout value and assumes them being zero.
+	 * So make sure the latch is the best value with the two least
+	 * significant bits unset.
+	 */
+	tmr->latch = DIV_ROUND_CLOSEST(timer_freq,
+				       (IXP4XX_OST_RELOAD_MASK + 1) * HZ)
+		* (IXP4XX_OST_RELOAD_MASK + 1);
+
+	local_ixp4xx_timer = tmr;
+
+	/* Reset/disable counter */
+	__raw_writel(0, tmr->base + IXP4XX_OSRT1_OFFSET);
+
+	/* Clear any pending interrupt on timer 1 */
+	__raw_writel(IXP4XX_OSST_TIMER_1_PEND,
+		     tmr->base + IXP4XX_OSST_OFFSET);
+
+	/* Reset time-stamp counter */
+	__raw_writel(0, tmr->base + IXP4XX_OSTS_OFFSET);
+
+	clocksource_mmio_init(NULL, "OSTS", timer_freq, 200, 32,
+			      ixp4xx_clocksource_read);
+
+	tmr->clkevt.name = "ixp4xx timer1";
+	tmr->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+	tmr->clkevt.rating = 200;
+	tmr->clkevt.set_state_shutdown = ixp4xx_shutdown;
+	tmr->clkevt.set_state_periodic = ixp4xx_set_periodic;
+	tmr->clkevt.set_state_oneshot = ixp4xx_set_oneshot;
+	tmr->clkevt.tick_resume = ixp4xx_resume;
+	tmr->clkevt.set_next_event = ixp4xx_set_next_event;
+	tmr->clkevt.cpumask = cpumask_of(0);
+	tmr->clkevt.irq = timer_irq;
+	ret = request_irq(timer_irq, ixp4xx_timer_interrupt,
+			  IRQF_TIMER, "IXP4XX-TIMER1", tmr);
+	if (ret) {
+		pr_crit("no timer IRQ\n");
+		return -ENODEV;
+	}
+	clockevents_config_and_register(&tmr->clkevt, timer_freq,
+					0xf, 0xfffffffe);
+
+#ifdef CONFIG_ARM
+	sched_clock_register(ixp4xx_read_sched_clock, 32, timer_freq);
+#endif
+
+	return 0;
+}
+
+/**
+ * ixp4xx_timer_setup() - Timer setup function to be called from boardfiles
+ * @timerbase: physical base of timer block
+ * @timer_irq: Linux IRQ number for the timer
+ * @timer_freq: Fixed frequency of the timer
+ */
+void __init ixp4xx_timer_setup(resource_size_t timerbase,
+			       int timer_irq,
+			       unsigned int timer_freq)
+{
+	void __iomem *base;
+
+	base = ioremap(timerbase, 0x100);
+	if (!base) {
+		pr_crit("IXP4xx: can't remap timer\n");
+		return;
+	}
+	ixp4xx_timer_register(base, timer_irq, timer_freq);
+}
+EXPORT_SYMBOL_GPL(ixp4xx_timer_setup);
diff --git a/include/linux/platform_data/timer-ixp4xx.h b/include/linux/platform_data/timer-ixp4xx.h
new file mode 100644
index 000000000000..ee92ae7edaed
--- /dev/null
+++ b/include/linux/platform_data/timer-ixp4xx.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __TIMER_IXP4XX_H
+#define __TIMER_IXP4XX_H
+
+#include <linux/ioport.h>
+
+void __init ixp4xx_timer_setup(resource_size_t timerbase,
+			       int timer_irq,
+			       unsigned int timer_freq);
+
+#endif
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 08/30 v2] ARM: ixp4xx: Switch to use new timer driver
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (6 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 07/30 v2] clocksource/drivers/ixp4xx: Add driver Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-22  8:38   ` Daniel Lezcano
  2019-02-21 15:44 ` [PATCH 09/30 v2] irqchip: ixp4xx: Add DT bindings Linus Walleij
                   ` (22 subsequent siblings)
  30 siblings, 1 reply; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa
  Cc: Linus Walleij, Daniel Lezcano, Thomas Gleixner

This augments the IXP4xx to select and use the new
timer driver in drivers/clocksource and removes the old
code in the machine.

Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
Clocksource/timer maintainers: here you see how I activate
this new driver. Intended to be merged through ARM SoC.
---
 arch/arm/Kconfig              |   2 +-
 arch/arm/mach-ixp4xx/common.c | 153 +---------------------------------
 2 files changed, 5 insertions(+), 150 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f6345594cef0..9f70d7e032d6 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -427,7 +427,6 @@ config ARCH_IXP4XX
 	depends on MMU
 	select ARCH_HAS_DMA_SET_COHERENT_MASK
 	select ARCH_SUPPORTS_BIG_ENDIAN
-	select CLKSRC_MMIO
 	select CPU_XSCALE
 	select DMABOUNCE if PCI
 	select GENERIC_CLOCKEVENTS
@@ -436,6 +435,7 @@ config ARCH_IXP4XX
 	select GPIOLIB
 	select HAVE_PCI
 	select IXP4XX_IRQ
+	select IXP4XX_TIMER
 	select NEED_MACH_IO_H
 	select USB_EHCI_BIG_ENDIAN_DESC
 	select USB_EHCI_BIG_ENDIAN_MMIO
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 71683dfc48f9..fc4c9b21ca96 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -22,9 +22,6 @@
 #include <linux/serial_core.h>
 #include <linux/interrupt.h>
 #include <linux/bitops.h>
-#include <linux/time.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
 #include <linux/io.h>
 #include <linux/export.h>
 #include <linux/cpu.h>
@@ -32,6 +29,7 @@
 #include <linux/sched_clock.h>
 #include <linux/bitops.h>
 #include <linux/irqchip/irq-ixp4xx.h>
+#include <linux/platform_data/timer-ixp4xx.h>
 #include <mach/udc.h>
 #include <mach/hardware.h>
 #include <mach/io.h>
@@ -49,19 +47,6 @@
 
 #define IXP4XX_TIMER_FREQ 66666000
 
-/*
- * The timer register doesn't allow to specify the two least significant bits of
- * the timeout value and assumes them being zero. So make sure IXP4XX_LATCH is
- * the best value with the two least significant bits unset.
- */
-#define IXP4XX_LATCH DIV_ROUND_CLOSEST(IXP4XX_TIMER_FREQ, \
-				       (IXP4XX_OST_RELOAD_MASK + 1) * HZ) * \
-			(IXP4XX_OST_RELOAD_MASK + 1)
-
-static void __init ixp4xx_clocksource_init(void);
-static void __init ixp4xx_clockevent_init(void);
-static struct clock_event_device clockevent_ixp4xx;
-
 /*************************************************************************
  * IXP4xx chipset I/O mapping
  *************************************************************************/
@@ -106,37 +91,11 @@ void __init ixp4xx_init_irq(void)
 			(cpu_is_ixp46x() || cpu_is_ixp43x()));
 }
 
-/*************************************************************************
- * IXP4xx timer tick
- * We use OS timer1 on the CPU for the timer tick and the timestamp 
- * counter as a source of real clock ticks to account for missed jiffies.
- *************************************************************************/
-
-static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id)
-{
-	struct clock_event_device *evt = dev_id;
-
-	/* Clear Pending Interrupt by writing '1' to it */
-	*IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
-
-	evt->event_handler(evt);
-
-	return IRQ_HANDLED;
-}
-
 void __init ixp4xx_timer_init(void)
 {
-	/* Reset/disable counter */
-	*IXP4XX_OSRT1 = 0;
-
-	/* Clear Pending Interrupt by writing '1' to it */
-	*IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
-
-	/* Reset time-stamp counter */
-	*IXP4XX_OSTS = 0;
-
-	ixp4xx_clocksource_init();
-	ixp4xx_clockevent_init();
+	return ixp4xx_timer_setup(IXP4XX_TIMER_BASE_PHYS,
+				  IRQ_IXP4XX_TIMER1,
+				  IXP4XX_TIMER_FREQ);
 }
 
 static struct pxa2xx_udc_mach_info ixp4xx_udc_info;
@@ -251,112 +210,8 @@ void __init ixp4xx_sys_init(void)
 			ixp4xx_exp_bus_size >> 20);
 }
 
-/*
- * sched_clock()
- */
-static u64 notrace ixp4xx_read_sched_clock(void)
-{
-	return *IXP4XX_OSTS;
-}
-
-/*
- * clocksource
- */
-
-static u64 ixp4xx_clocksource_read(struct clocksource *c)
-{
-	return *IXP4XX_OSTS;
-}
-
 unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ;
 EXPORT_SYMBOL(ixp4xx_timer_freq);
-static void __init ixp4xx_clocksource_init(void)
-{
-	sched_clock_register(ixp4xx_read_sched_clock, 32, ixp4xx_timer_freq);
-
-	clocksource_mmio_init(NULL, "OSTS", ixp4xx_timer_freq, 200, 32,
-			ixp4xx_clocksource_read);
-}
-
-/*
- * clockevents
- */
-static int ixp4xx_set_next_event(unsigned long evt,
-				 struct clock_event_device *unused)
-{
-	unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK;
-
-	*IXP4XX_OSRT1 = (evt & ~IXP4XX_OST_RELOAD_MASK) | opts;
-
-	return 0;
-}
-
-static int ixp4xx_shutdown(struct clock_event_device *evt)
-{
-	unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK;
-	unsigned long osrt = *IXP4XX_OSRT1 & ~IXP4XX_OST_RELOAD_MASK;
-
-	opts &= ~IXP4XX_OST_ENABLE;
-	*IXP4XX_OSRT1 = osrt | opts;
-	return 0;
-}
-
-static int ixp4xx_set_oneshot(struct clock_event_device *evt)
-{
-	unsigned long opts = IXP4XX_OST_ENABLE | IXP4XX_OST_ONE_SHOT;
-	unsigned long osrt = 0;
-
-	/* period set by 'set next_event' */
-	*IXP4XX_OSRT1 = osrt | opts;
-	return 0;
-}
-
-static int ixp4xx_set_periodic(struct clock_event_device *evt)
-{
-	unsigned long opts = IXP4XX_OST_ENABLE;
-	unsigned long osrt = IXP4XX_LATCH & ~IXP4XX_OST_RELOAD_MASK;
-
-	*IXP4XX_OSRT1 = osrt | opts;
-	return 0;
-}
-
-static int ixp4xx_resume(struct clock_event_device *evt)
-{
-	unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK;
-	unsigned long osrt = *IXP4XX_OSRT1 & ~IXP4XX_OST_RELOAD_MASK;
-
-	opts |= IXP4XX_OST_ENABLE;
-	*IXP4XX_OSRT1 = osrt | opts;
-	return 0;
-}
-
-static struct clock_event_device clockevent_ixp4xx = {
-	.name			= "ixp4xx timer1",
-	.features		= CLOCK_EVT_FEAT_PERIODIC |
-				  CLOCK_EVT_FEAT_ONESHOT,
-	.rating			= 200,
-	.set_state_shutdown	= ixp4xx_shutdown,
-	.set_state_periodic	= ixp4xx_set_periodic,
-	.set_state_oneshot	= ixp4xx_set_oneshot,
-	.tick_resume		= ixp4xx_resume,
-	.set_next_event		= ixp4xx_set_next_event,
-};
-
-static void __init ixp4xx_clockevent_init(void)
-{
-	int ret;
-
-	clockevent_ixp4xx.cpumask = cpumask_of(0);
-	clockevent_ixp4xx.irq = IRQ_IXP4XX_TIMER1;
-	ret = request_irq(IRQ_IXP4XX_TIMER1, ixp4xx_timer_interrupt,
-			  IRQF_TIMER, "IXP4XX-TIMER1", &clockevent_ixp4xx);
-	if (ret) {
-		pr_crit("no timer IRQ\n");
-		return;
-	}
-	clockevents_config_and_register(&clockevent_ixp4xx, IXP4XX_TIMER_FREQ,
-					0xf, 0xfffffffe);
-}
 
 void ixp4xx_restart(enum reboot_mode mode, const char *cmd)
 {
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 09/30 v2] irqchip: ixp4xx: Add DT bindings
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (7 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 08/30 v2] ARM: ixp4xx: Switch to use new timer driver Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 21:39   ` Rob Herring
  2019-02-21 15:44 ` [PATCH 10/30 v2] irqchip: ixp4xx: Add OF initialization support Linus Walleij
                   ` (21 subsequent siblings)
  30 siblings, 1 reply; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa
  Cc: Marc Zyngier, devicetree, Linus Walleij, Thomas Gleixner, Jason Cooper

This adds device tree bindings for the IXP4xx interrupt
controller. It's a standard 2-cell controller.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: devicetree@vger.kernel.org
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Converted to use JSON yaml schema, why not.
- Not keeping Rob's ACK because I think he wants to take
  a second look.
---
 .../intel,ixp4xx-interrupt.yaml               | 57 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 58 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml

diff --git a/Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml b/Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml
new file mode 100644
index 000000000000..f32c08f270d6
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2018 Linaro Ltd.
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/interrupt/intel-ixp4xx-interrupt.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Intel IXP4xx XScale Networking Processors Interrupt Controller
+
+maintainers:
+  - Linus Walleij <linus.walleij@linaro.org>
+
+description: |
+  This interrupt controller is found in the Intel IXP4xx processors.
+  Some processors have 32 interrupts, some have up to 64 interrupts.
+  The exact number of interrupts is determined from the compatible
+  string.
+
+  The distinct IXP4xx families with different interrupt controller
+  variations are IXP42x, IXP43x, IXP45x and IXP46x. Those four
+  families were the only ones to reach the developer and consumer
+  market.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+        - enum:
+          - intel,ixp42x-interrupt
+          - intel,ixp43x-interrupt
+          - intel,ixp45x-interrupt
+          - intel,ixp46x-interrupt
+
+  reg:
+    description: The register bank for the interrupt controller.
+
+  interrupt-controller: true
+
+  '#interrupt-cells':
+    const: 2
+    description: The number of cells to define the interrupts.
+      with two cells specified in interrupt-controller/interrupts.txt
+
+required:
+  - compatible
+  - reg
+  - interrupt-controller
+  - '#interrupt-cells'
+
+examples:
+  - |
+    intcon: interrupt-controller@c8003000 {
+        compatible = "intel,ixp43x-interrupt";
+        reg = <0xc8003000 0x100>;
+        interrupt-controller;
+        #interrupt-cells = <2>;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index a2fb67b75026..79f01af59a63 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1650,6 +1650,7 @@ M:	Imre Kaloz <kaloz@openwrt.org>
 M:	Krzysztof Halasa <khalasa@piap.pl>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
+F:	Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml
 F:	arch/arm/mach-ixp4xx/
 F:	drivers/clocksource/timer-ixp4xx.c
 F:	drivers/gpio/gpio-ixp4xx.c
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 10/30 v2] irqchip: ixp4xx: Add OF initialization support
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (8 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 09/30 v2] irqchip: ixp4xx: Add DT bindings Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-22  9:53   ` Marc Zyngier
  2019-02-21 15:44 ` [PATCH 11/30 v2] clocksource/drivers/ixp4xx: Add DT bindings Linus Walleij
                   ` (20 subsequent siblings)
  30 siblings, 1 reply; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa
  Cc: Marc Zyngier, Linus Walleij, Thomas Gleixner, Jason Cooper

This adds support for probing and settin up the IXP4xx
irqchip from device tree.

Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Jason Cooper <jason@lakedaemon.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
irqchip maintainers: I am requesting an ACK for this once
you're happy with the driver, as I intend to merge all of
this IXP4xx rework through ARM SoC.
---
 drivers/irqchip/irq-ixp4xx.c | 45 ++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/drivers/irqchip/irq-ixp4xx.c b/drivers/irqchip/irq-ixp4xx.c
index 89c80ce047a7..1ea7561fddb7 100644
--- a/drivers/irqchip/irq-ixp4xx.c
+++ b/drivers/irqchip/irq-ixp4xx.c
@@ -15,6 +15,9 @@
 #include <linux/irqchip.h>
 #include <linux/irqchip/irq-ixp4xx.h>
 #include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 #include <linux/platform_device.h>
 #include <linux/cpu.h>
 
@@ -360,3 +363,45 @@ void __init ixp4xx_irq_init(resource_size_t irqbase,
 	}
 }
 EXPORT_SYMBOL_GPL(ixp4xx_irq_init);
+
+#ifdef CONFIG_OF
+int __init ixp4xx_of_init_irq(struct device_node *np,
+			      struct device_node *parent)
+{
+	struct ixp4xx_irq *ixi = &ixirq;
+	void __iomem *base;
+	struct fwnode_handle *fwnode;
+	bool is_356;
+	int ret;
+
+	base = of_iomap(np, 0);
+	if (!base) {
+		pr_crit("IXP4XX: could not ioremap interrupt controller\n");
+		return -ENODEV;
+	}
+	fwnode = of_node_to_fwnode(np);
+	if (!fwnode) {
+		pr_crit("IXP4XX: no domain handle\n");
+		return -ENODEV;
+	}
+
+	/* These chip variants have 64 interrupts */
+	is_356 = of_device_is_compatible(np, "intel,ixp43x-interrupt") ||
+		of_device_is_compatible(np, "intel,ixp45x-interrupt") ||
+		of_device_is_compatible(np, "intel,ixp46x-interrupt");
+
+	ret = ixp4xx_irq_setup(ixi, base, fwnode, is_356);
+	if (ret)
+		pr_crit("IXP4XX: failed to set up irqchip\n");
+
+	return ret;
+}
+IRQCHIP_DECLARE(ixp42x, "intel,ixp42x-interrupt",
+		ixp4xx_of_init_irq);
+IRQCHIP_DECLARE(ixp43x, "intel,ixp43x-interrupt",
+		ixp4xx_of_init_irq);
+IRQCHIP_DECLARE(ixp45x, "intel,ixp45x-interrupt",
+		ixp4xx_of_init_irq);
+IRQCHIP_DECLARE(ixp46x, "intel,ixp46x-interrupt",
+		ixp4xx_of_init_irq);
+#endif
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 11/30 v2] clocksource/drivers/ixp4xx: Add DT bindings
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (9 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 10/30 v2] irqchip: ixp4xx: Add OF initialization support Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 21:40   ` Rob Herring
  2019-02-21 15:44 ` [PATCH 12/30 v2] clocksource/drivers/ixp4xx: Add OF initialization support Linus Walleij
                   ` (19 subsequent siblings)
  30 siblings, 1 reply; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa
  Cc: devicetree, Linus Walleij, Daniel Lezcano, Thomas Gleixner

This adds device tree bindings for the Intel IXP4xx
timers.

Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: devicetree@vger.kernel.org
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Switch to JSON YAML schema, why not.
- Not collecting any review tags as this changed a bit.
---
 .../bindings/timer/intel,ixp4xx-timer.yaml    | 42 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 43 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml

diff --git a/Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml b/Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml
new file mode 100644
index 000000000000..a36a0746c056
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2018 Linaro Ltd.
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/timer/intel-ixp4xx-timer.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Intel IXP4xx XScale Networking Processors Timers
+
+maintainers:
+  - Linus Walleij <linus.walleij@linaro.org>
+
+description: This timer is found in the Intel IXP4xx processors.
+
+properties:
+  compatible:
+    items:
+      - const: intel,ixp4xx-timer
+
+  reg:
+    description: Should contain registers location and length
+
+  interrupts:
+    minItems: 1
+    maxItems: 2
+    items:
+      - description: Timer 1 interrupt
+      - description: Timer 2 interrupt
+
+required:
+  - compatible
+  - reg
+  - interrupts
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    timer@c8005000 {
+        compatible = "intel,ixp4xx-timer";
+        reg = <0xc8005000 0x100>;
+        interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
+    };
diff --git a/MAINTAINERS b/MAINTAINERS
index 79f01af59a63..bd04142b1026 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1651,6 +1651,7 @@ M:	Krzysztof Halasa <khalasa@piap.pl>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
 F:	Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml
+F:	Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml
 F:	arch/arm/mach-ixp4xx/
 F:	drivers/clocksource/timer-ixp4xx.c
 F:	drivers/gpio/gpio-ixp4xx.c
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 12/30 v2] clocksource/drivers/ixp4xx: Add OF initialization support
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (10 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 11/30 v2] clocksource/drivers/ixp4xx: Add DT bindings Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 15:44 ` [PATCH 13/30 v2] gpio: ixp4xx: Add DT bindings Linus Walleij
                   ` (18 subsequent siblings)
  30 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa
  Cc: Linus Walleij, Daniel Lezcano, Thomas Gleixner

This adds support for setting up the IXP4xx timer driver from
device tree.

Cc: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/clocksource/timer-ixp4xx.c | 35 ++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/drivers/clocksource/timer-ixp4xx.c b/drivers/clocksource/timer-ixp4xx.c
index fa78f80792db..404445bc11ea 100644
--- a/drivers/clocksource/timer-ixp4xx.c
+++ b/drivers/clocksource/timer-ixp4xx.c
@@ -16,6 +16,8 @@
 #include <linux/slab.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
 /* Goes away with OF conversion */
 #include <linux/platform_data/timer-ixp4xx.h>
 
@@ -247,3 +249,36 @@ void __init ixp4xx_timer_setup(resource_size_t timerbase,
 	ixp4xx_timer_register(base, timer_irq, timer_freq);
 }
 EXPORT_SYMBOL_GPL(ixp4xx_timer_setup);
+
+#ifdef CONFIG_OF
+static __init int ixp4xx_of_timer_init(struct device_node *np)
+{
+	void __iomem *base;
+	int irq;
+	int ret;
+
+	base = of_iomap(np, 0);
+	if (!base) {
+		pr_crit("IXP4xx: can't remap timer\n");
+		return -ENODEV;
+	}
+
+	irq = irq_of_parse_and_map(np, 0);
+	if (irq <= 0) {
+		pr_err("Can't parse IRQ\n");
+		ret = -EINVAL;
+		goto out_unmap;
+	}
+
+	/* TODO: get some fixed clocks into the device tree */
+	ret = ixp4xx_timer_register(base, irq, 66666000);
+	if (ret)
+		goto out_unmap;
+	return 0;
+
+out_unmap:
+	iounmap(base);
+	return ret;
+}
+TIMER_OF_DECLARE(ixp4xx, "intel,ixp4xx-timer", ixp4xx_of_timer_init);
+#endif
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 13/30 v2] gpio: ixp4xx: Add DT bindings
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (11 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 12/30 v2] clocksource/drivers/ixp4xx: Add OF initialization support Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 15:44 ` [PATCH 14/30 v2] gpio: ixp4xx: Add OF probing support Linus Walleij
                   ` (17 subsequent siblings)
  30 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa
  Cc: devicetree, Linus Walleij, Rob Herring, Bartosz Golaszewski

This adds DT bindings for the IXP4xx GPIO controller.

Cc: devicetree@vger.kernel.org
Reviewed-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Collect Bartosz and Rob's review tags.
---
 .../bindings/gpio/intel,ixp4xx-gpio.txt       | 38 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 39 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/gpio/intel,ixp4xx-gpio.txt

diff --git a/Documentation/devicetree/bindings/gpio/intel,ixp4xx-gpio.txt b/Documentation/devicetree/bindings/gpio/intel,ixp4xx-gpio.txt
new file mode 100644
index 000000000000..8dc41ed99685
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/intel,ixp4xx-gpio.txt
@@ -0,0 +1,38 @@
+Intel IXP4xx XScale Networking Processors GPIO
+
+This GPIO controller is found in the Intel IXP4xx processors.
+It supports 16 GPIO lines.
+
+The interrupt portions of the GPIO controller is hierarchical:
+the synchronous edge detector is part of the GPIO block, but the
+actual enabling/disabling of the interrupt line is done in the
+main IXP4xx interrupt controller which has a 1:1 mapping for
+the first 12 GPIO lines to 12 system interrupts.
+
+The remaining 4 GPIO lines can not be used for receiving
+interrupts.
+
+The interrupt parent of this GPIO controller must be the
+IXP4xx interrupt controller.
+
+Required properties:
+
+- compatible : Should be
+  "intel,ixp4xx-gpio"
+- reg : Should contain registers location and length
+- gpio-controller : marks this as a GPIO controller
+- #gpio-cells : Should be 2, see gpio/gpio.txt
+- interrupt-controller : marks this as an interrupt controller
+- #interrupt-cells : a standard two-cell interrupt, see
+  interrupt-controller/interrupts.txt
+
+Example:
+
+gpio0: gpio@c8004000 {
+	compatible = "intel,ixp4xx-gpio";
+	reg = <0xc8004000 0x1000>;
+	gpio-controller;
+	#gpio-cells = <2>;
+	interrupt-controller;
+	#interrupt-cells = <2>;
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index bd04142b1026..b44ee076d57c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1650,6 +1650,7 @@ M:	Imre Kaloz <kaloz@openwrt.org>
 M:	Krzysztof Halasa <khalasa@piap.pl>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
+F:	Documentation/devicetree/bindings/gpio/intel,ixp4xx-gpio.txt
 F:	Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml
 F:	Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml
 F:	arch/arm/mach-ixp4xx/
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 14/30 v2] gpio: ixp4xx: Add OF probing support
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (12 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 13/30 v2] gpio: ixp4xx: Add DT bindings Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 15:44 ` [PATCH 15/30 v2] ARM: ixp4xx: Add DT bindings Linus Walleij
                   ` (16 subsequent siblings)
  30 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa
  Cc: Bartosz Golaszewski, Linus Walleij

This adds device tree probe and registration support for
the IXP4xx GPIO driver.

Cc: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
Bartosz: looking for your ACK on this, it'd be good if
the other GPIO maintainer is aligned with my ideas here.
I intend to merge this through the ARM SoC tree.
---
 drivers/gpio/gpio-ixp4xx.c | 84 ++++++++++++++++++++++++++------------
 1 file changed, 57 insertions(+), 27 deletions(-)

diff --git a/drivers/gpio/gpio-ixp4xx.c b/drivers/gpio/gpio-ixp4xx.c
index eaf317f73f75..4b1cf7ea858d 100644
--- a/drivers/gpio/gpio-ixp4xx.c
+++ b/drivers/gpio/gpio-ixp4xx.c
@@ -11,6 +11,7 @@
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
 #include <linux/irqchip.h>
+#include <linux/of_irq.h>
 #include <linux/platform_device.h>
 #include <linux/bitops.h>
 /* Include that go away with DT transition */
@@ -306,6 +307,7 @@ static int ixp4xx_gpio_probe(struct platform_device *pdev)
 {
 	unsigned long flags;
 	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
 	struct irq_domain *parent;
 	struct resource *res;
 	struct ixp4xx_gpio *g;
@@ -382,11 +384,27 @@ static int ixp4xx_gpio_probe(struct platform_device *pdev)
 	 * from IRQCHIP_DECLARE(), then use of_node_to_fwnode() to get
 	 * the fwnode. For now we need this boardfile style code.
 	 */
-	parent = ixp4xx_get_irq_domain();
-	g->fwnode = irq_domain_alloc_fwnode(g->base);
-	if (!g->fwnode) {
-		dev_err(dev, "no domain base\n");
-		return -ENODEV;
+	if (np) {
+		struct device_node *irq_parent;
+
+		irq_parent = of_irq_find_parent(np);
+		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;
+		}
+		g->fwnode = of_node_to_fwnode(np);
+	} else {
+		parent = ixp4xx_get_irq_domain();
+		g->fwnode = irq_domain_alloc_fwnode(g->base);
+		if (!g->fwnode) {
+			dev_err(dev, "no domain base\n");
+			return -ENODEV;
+		}
 	}
 	g->domain = irq_domain_create_hierarchy(parent,
 						IRQ_DOMAIN_FLAG_HIERARCHY,
@@ -404,28 +422,31 @@ static int ixp4xx_gpio_probe(struct platform_device *pdev)
 	 * After adding OF support, this is no longer needed: irqs
 	 * will be allocated for the respective fwnodes.
 	 */
-	for (i = 0; i < ARRAY_SIZE(ixp4xx_gpiomap); i++) {
-		const struct ixp4xx_gpio_map *map = &ixp4xx_gpiomap[i];
-		struct irq_fwspec fwspec;
-
-		fwspec.fwnode = g->fwnode;
-		/* This is the hwirq for the GPIO line side of things */
-		fwspec.param[0] = map->gpio_offset;
-		fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
-		fwspec.param_count = 2;
-		ret = __irq_domain_alloc_irqs(g->domain,
-					      -1, /* just pick something */
-					      1,
-					      NUMA_NO_NODE,
-					      &fwspec,
-					      false,
-					      NULL);
-		if (ret < 0) {
-			irq_domain_free_fwnode(g->fwnode);
-			dev_err(dev,
-				"can not allocate irq for GPIO line %d parent hwirq %d in hierarchy domain: %d\n",
-				map->gpio_offset, map->parent_hwirq, ret);
-			return ret;
+	if (!np) {
+		for (i = 0; i < ARRAY_SIZE(ixp4xx_gpiomap); i++) {
+			const struct ixp4xx_gpio_map *map = &ixp4xx_gpiomap[i];
+			struct irq_fwspec fwspec;
+
+			fwspec.fwnode = g->fwnode;
+			/* This is the hwirq for the GPIO line side of things */
+			fwspec.param[0] = map->gpio_offset;
+			fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
+			fwspec.param_count = 2;
+			ret = __irq_domain_alloc_irqs(g->domain,
+						      -1, /* just pick something */
+						      1,
+						      NUMA_NO_NODE,
+						      &fwspec,
+						      false,
+						      NULL);
+			if (ret < 0) {
+				irq_domain_free_fwnode(g->fwnode);
+				dev_err(dev,
+					"can not allocate irq for GPIO line %d parent hwirq %d in hierarchy domain: %d\n",
+					map->gpio_offset, map->parent_hwirq,
+					ret);
+				return ret;
+			}
 		}
 	}
 
@@ -435,9 +456,18 @@ static int ixp4xx_gpio_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct of_device_id ixp4xx_gpio_of_match[] = {
+	{
+		.compatible = "intel,ixp4xx-gpio",
+	},
+	{},
+};
+
+
 static struct platform_driver ixp4xx_gpio_driver = {
 	.driver = {
 		.name		= "ixp4xx-gpio",
+		.of_match_table = of_match_ptr(ixp4xx_gpio_of_match),
 	},
 	.probe = ixp4xx_gpio_probe,
 };
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 15/30 v2] ARM: ixp4xx: Add DT bindings
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (13 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 14/30 v2] gpio: ixp4xx: Add OF probing support Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 15:44 ` [PATCH 16/30 v2] ARM: ixp4xx: Add device tree boot support Linus Walleij
                   ` (15 subsequent siblings)
  30 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa
  Cc: devicetree, Linus Walleij, Rob Herring

This adds initial device tree bindings for the IXP4xx machines.
This time I tried something wild and crazy and try to make proper
JSON-style YAML bindings for the top level.

Cc: devicetree@vger.kernel.org
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Fix up the GW2358 compatible string.
---
 .../devicetree/bindings/arm/intel-ixp4xx.yaml | 22 +++++++++++++++++++
 MAINTAINERS                                   |  1 +
 2 files changed, 23 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/arm/intel-ixp4xx.yaml

diff --git a/Documentation/devicetree/bindings/arm/intel-ixp4xx.yaml b/Documentation/devicetree/bindings/arm/intel-ixp4xx.yaml
new file mode 100644
index 000000000000..f4f7451e5e8a
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/intel-ixp4xx.yaml
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/intel-ixp4xx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Intel IXP4xx Device Tree Bindings
+
+maintainers:
+  - Linus Walleij <linus.walleij@linaro.org>
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - linksys,nslu2
+          - const: intel,ixp42x
+      - items:
+          - enum:
+              - gateworks,gw2358
+          - const: intel,ixp43x
diff --git a/MAINTAINERS b/MAINTAINERS
index b44ee076d57c..20d02e1e60a8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1650,6 +1650,7 @@ M:	Imre Kaloz <kaloz@openwrt.org>
 M:	Krzysztof Halasa <khalasa@piap.pl>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
+F:	Documentation/devicetree/bindings/arm/intel-ixp4xx.yaml
 F:	Documentation/devicetree/bindings/gpio/intel,ixp4xx-gpio.txt
 F:	Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml
 F:	Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 16/30 v2] ARM: ixp4xx: Add device tree boot support
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (14 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 15/30 v2] ARM: ixp4xx: Add DT bindings Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 15:44 ` [PATCH 17/30 v2] ARM: dts: Add some initial IXP4xx device trees Linus Walleij
                   ` (14 subsequent siblings)
  30 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa; +Cc: Linus Walleij

This adds a minimal support for booting IXP4xx systems
from device tree.

We have to add hacks to the QMGR, NPE and notably also
ethernet and watchdog drivers so that they don't crash
the platform: these drivers are unconditionally starting
to grab regions of statically remapped IO space with no
concern of the device model or other platforms.

We will go in and properly fix these drivers as we go
along but for now this hack gets us to a place where we
can start working on proper device tree support for these
platforms.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog v1->v2:
- Remap the external bus registers since the feature
  checks for different hardware using
  ixp4xx_read_feature_bits() to determine the system
  configuration needs this static map. We can eventually
  move this to syscon but only if we first move all
  boards to device tree.
---
 arch/arm/mach-ixp4xx/Kconfig             | 14 ++++++
 arch/arm/mach-ixp4xx/Makefile            |  3 ++
 arch/arm/mach-ixp4xx/ixp4xx-of.c         | 60 ++++++++++++++++++++++++
 arch/arm/mach-ixp4xx/ixp4xx_npe.c        |  5 ++
 arch/arm/mach-ixp4xx/ixp4xx_qmgr.c       |  5 ++
 drivers/net/ethernet/xscale/ixp4xx_eth.c | 10 ++++
 drivers/watchdog/ixp4xx_wdt.c            |  9 ++++
 7 files changed, 106 insertions(+)
 create mode 100644 arch/arm/mach-ixp4xx/ixp4xx-of.c

diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index fea008123eb1..0973270f4863 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -4,6 +4,20 @@ menu "Intel IXP4xx Implementation Options"
 
 comment "IXP4xx Platforms"
 
+config MACH_IXP4XX_OF
+	bool
+	prompt "Devce Tree IXP4xx boards"
+	default y
+	select ARM_APPENDED_DTB # Old Redboot bootloaders deployed
+	select I2C
+	select I2C_IOP3XX
+	select PCI
+	select SERIAL_OF_PLATFORM
+	select TIMER_OF
+	select USE_OF
+	help
+	  Say 'Y' here to support Device Tree-based IXP4xx platforms.
+
 config MACH_NSLU2
 	bool
 	prompt "Linksys NSLU2"
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
index f09994500a34..5f63b3012826 100644
--- a/arch/arm/mach-ixp4xx/Makefile
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -6,6 +6,9 @@
 obj-pci-y	:=
 obj-pci-n	:=
 
+# Device tree platform
+obj-pci-$(CONFIG_MACH_IXP4XX_OF)	+= ixp4xx-of.o
+
 obj-pci-$(CONFIG_ARCH_IXDP4XX)		+= ixdp425-pci.o
 obj-pci-$(CONFIG_MACH_AVILA)		+= avila-pci.o
 obj-pci-$(CONFIG_MACH_IXDPG425)		+= ixdpg425-pci.o
diff --git a/arch/arm/mach-ixp4xx/ixp4xx-of.c b/arch/arm/mach-ixp4xx/ixp4xx-of.c
new file mode 100644
index 000000000000..7449b8319c8a
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/ixp4xx-of.c
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IXP4xx Device Tree boot support
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/ixp4xx-regs.h>
+
+static struct map_desc ixp4xx_of_io_desc[] __initdata = {
+	/*
+	 * This is needed for runtime system configuration checks,
+	 * such as reading if hardware so-and-so is present. This
+	 * could eventually be converted into a syscon once all boards
+	 * are converted to device tree.
+	 */
+	{
+		.virtual = IXP4XX_EXP_CFG_BASE_VIRT,
+		.pfn = __phys_to_pfn(IXP4XX_EXP_CFG_BASE_PHYS),
+		.length = SZ_4K,
+		.type = MT_DEVICE,
+	},
+#ifdef CONFIG_DEBUG_UART_8250
+	/* This is needed for LL-debug/earlyprintk/debug-macro.S */
+	{
+		.virtual = CONFIG_DEBUG_UART_VIRT,
+		.pfn = __phys_to_pfn(CONFIG_DEBUG_UART_PHYS),
+		.length = SZ_4K,
+		.type = MT_DEVICE,
+	},
+#endif
+};
+
+static void __init ixp4xx_of_map_io(void)
+{
+	iotable_init(ixp4xx_of_io_desc, ARRAY_SIZE(ixp4xx_of_io_desc));
+}
+
+/*
+ * We handle 4 differen SoC families. These compatible strings are enough
+ * to provide the core so that different boards can add their more detailed
+ * specifics.
+ */
+static const char *ixp4xx_of_board_compat[] = {
+	"intel,ixp42x",
+	"intel,ixp43x",
+	"intel,ixp45x",
+	"intel,ixp46x",
+	NULL,
+};
+
+DT_MACHINE_START(IXP4XX_DT, "IXP4xx (Device Tree)")
+	.map_io		= ixp4xx_of_map_io,
+	.dt_compat	= ixp4xx_of_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-ixp4xx/ixp4xx_npe.c b/arch/arm/mach-ixp4xx/ixp4xx_npe.c
index d4eb09a62863..e0ce22cd9bfc 100644
--- a/arch/arm/mach-ixp4xx/ixp4xx_npe.c
+++ b/arch/arm/mach-ixp4xx/ixp4xx_npe.c
@@ -20,6 +20,7 @@
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <mach/npe.h>
 
 #define DEBUG_MSG			0
@@ -688,6 +689,10 @@ static int __init npe_init_module(void)
 
 	int i, found = 0;
 
+	/* This driver does not work with device tree */
+	if (of_have_populated_dt())
+		return -ENODEV;
+
 	for (i = 0; i < NPE_COUNT; i++) {
 		struct npe *npe = &npe_tab[i];
 		if (!(ixp4xx_read_feature_bits() &
diff --git a/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
index 4c7c960e1b4c..2665347a2c6f 100644
--- a/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
+++ b/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
@@ -12,6 +12,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <mach/qmgr.h>
 
 #include "irqs.h"
@@ -289,6 +290,10 @@ static int qmgr_init(void)
 	int i, err;
 	irq_handler_t handler1, handler2;
 
+	/* This driver does not work with device tree */
+	if (of_have_populated_dt())
+		return -ENODEV;
+
 	mem_res = request_mem_region(IXP4XX_QMGR_BASE_PHYS,
 				     IXP4XX_QMGR_REGION_SIZE,
 				     "IXP4xx Queue Manager");
diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c
index aee55c03def0..7ad3c3b56a77 100644
--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
+++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
@@ -31,6 +31,7 @@
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/net_tstamp.h>
+#include <linux/of.h>
 #include <linux/phy.h>
 #include <linux/platform_device.h>
 #include <linux/ptp_classify.h>
@@ -1497,6 +1498,15 @@ static struct platform_driver ixp4xx_eth_driver = {
 static int __init eth_init_module(void)
 {
 	int err;
+
+	/*
+	 * FIXME: we bail out on device tree boot but this really needs
+	 * to be fixed in a nicer way: this registers the MDIO bus before
+	 * even matching the driver infrastructure, we should only probe
+	 * detected hardware.
+	 */
+	if (of_have_populated_dt())
+		return -ENODEV;
 	if ((err = ixp4xx_mdio_register()))
 		return err;
 	return platform_driver_register(&ixp4xx_eth_driver);
diff --git a/drivers/watchdog/ixp4xx_wdt.c b/drivers/watchdog/ixp4xx_wdt.c
index f20cc53ff719..a80449bb36f0 100644
--- a/drivers/watchdog/ixp4xx_wdt.c
+++ b/drivers/watchdog/ixp4xx_wdt.c
@@ -21,6 +21,7 @@
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/miscdevice.h>
+#include <linux/of.h>
 #include <linux/watchdog.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
@@ -176,6 +177,14 @@ static int __init ixp4xx_wdt_init(void)
 {
 	int ret;
 
+	/*
+	 * FIXME: we bail out on device tree boot but this really needs
+	 * to be fixed in a nicer way: this registers the MDIO bus before
+	 * even matching the driver infrastructure, we should only probe
+	 * detected hardware.
+	 */
+	if (of_have_populated_dt())
+		return -ENODEV;
 	if (!(read_cpuid_id() & 0xf) && !cpu_is_ixp46x()) {
 		pr_err("Rev. A0 IXP42x CPU detected - watchdog disabled\n");
 
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 17/30 v2] ARM: dts: Add some initial IXP4xx device trees
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (15 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 16/30 v2] ARM: ixp4xx: Add device tree boot support Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 15:44 ` [PATCH 18/30 v2] ARM: ixp4xx: Move NPE and QMGR to drivers/soc Linus Walleij
                   ` (13 subsequent siblings)
  30 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa; +Cc: Linus Walleij

This adds a device tree for the IXP4xx-based Linksys
NSLU2 and Gateworks GW2358 which encompass the Gateworks
Cambria family.

These will be the first IXP4xx device tree platforms.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
ChangeLog RFC->v2:
- Take out of RFC
- Use ISC license on the files, *BSD likes this license
---
 arch/arm/boot/dts/Makefile                    |   3 +
 .../boot/dts/intel-ixp42x-linksys-nslu2.dts   | 109 ++++++++++++++++++
 arch/arm/boot/dts/intel-ixp42x.dtsi           |  25 ++++
 .../dts/intel-ixp43x-gateworks-gw2358.dts     |  94 +++++++++++++++
 arch/arm/boot/dts/intel-ixp43x.dtsi           |  15 +++
 arch/arm/boot/dts/intel-ixp45x-ixp46x.dtsi    |  34 ++++++
 arch/arm/boot/dts/intel-ixp4xx.dtsi           |  58 ++++++++++
 7 files changed, 338 insertions(+)
 create mode 100644 arch/arm/boot/dts/intel-ixp42x-linksys-nslu2.dts
 create mode 100644 arch/arm/boot/dts/intel-ixp42x.dtsi
 create mode 100644 arch/arm/boot/dts/intel-ixp43x-gateworks-gw2358.dts
 create mode 100644 arch/arm/boot/dts/intel-ixp43x.dtsi
 create mode 100644 arch/arm/boot/dts/intel-ixp45x-ixp46x.dtsi
 create mode 100644 arch/arm/boot/dts/intel-ixp4xx.dtsi

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index bd40148a15b2..272d39317a1b 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -227,6 +227,9 @@ dtb-$(CONFIG_ARCH_HIX5HD2) += \
 dtb-$(CONFIG_ARCH_INTEGRATOR) += \
 	integratorap.dtb \
 	integratorcp.dtb
+dtb-$(CONFIG_ARCH_IXP4XX) += \
+	intel-ixp42x-linksys-nslu2.dtb \
+	intel-ixp43x-gateworks-gw2358.dtb
 dtb-$(CONFIG_ARCH_KEYSTONE) += \
 	keystone-k2hk-evm.dtb \
 	keystone-k2l-evm.dtb \
diff --git a/arch/arm/boot/dts/intel-ixp42x-linksys-nslu2.dts b/arch/arm/boot/dts/intel-ixp42x-linksys-nslu2.dts
new file mode 100644
index 000000000000..8fcd95805ff4
--- /dev/null
+++ b/arch/arm/boot/dts/intel-ixp42x-linksys-nslu2.dts
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: ISC
+/*
+ * Device Tree file for Linksys NSLU2
+ */
+
+/dts-v1/;
+
+#include "intel-ixp42x.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+	model = "Linksys NSLU2 (Network Storage Link for USB 2.0 Disk Drives)";
+	compatible = "linksys,nslu2", "intel,ixp42x";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	memory@0 {
+		/* 32 MB SDRAM */
+		device_type = "memory";
+		reg = <0x00000000 0x2000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200n8 root=/dev/mtdblock2 rw rootfstype=squashfs,jffs2 rootwait";
+		stdout-path = "uart0:115200n8";
+	};
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		led-status {
+			label = "nslu2:red:status";
+			gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+			linux,default-trigger = "heartbeat";
+		};
+		led-ready {
+			label = "nslu2:green:ready";
+			gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
+			default-state = "on";
+		};
+		led-disk-1 {
+			label = "nslu2:green:disk-1";
+			gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
+			default-state = "off";
+		};
+		led-disk-2 {
+			label = "nslu2:green:disk-2";
+			gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
+			default-state = "off";
+		};
+	};
+
+	gpio_keys {
+		compatible = "gpio-keys";
+
+		button-power {
+			wakeup-source;
+			linux,code = <KEY_POWER>;
+			label = "power";
+			gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>;
+		};
+		button-reset {
+			wakeup-source;
+			linux,code = <KEY_ESC>;
+			label = "reset";
+			gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+		};
+	};
+
+	i2c {
+		compatible = "i2c-gpio";
+		sda-gpios = <&gpio0 7 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+		scl-gpios = <&gpio0 6 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		rtc@6f {
+			compatible = "xicor,x1205";
+			reg = <0x6f>;
+		};
+	};
+
+	gpio-poweroff {
+		compatible = "gpio-poweroff";
+		gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;
+		timeout-ms = <5000>;
+	};
+
+	/* The first 16MB region on the expansion bus */
+	flash@50000000 {
+		compatible = "intel,ixp4xx-flash", "cfi-flash";
+		bank-width = <2>;
+		/*
+		 * 8 MB of Flash in 0x20000 byte blocks
+		 * mapped in at 0x50000000
+		 */
+		reg = <0x50000000 0x800000>;
+
+		partitions {
+			compatible = "redboot-fis";
+			/* Eraseblock at 0x7e0000 */
+			fis-index-block = <0x3f>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/intel-ixp42x.dtsi b/arch/arm/boot/dts/intel-ixp42x.dtsi
new file mode 100644
index 000000000000..a9622ca850cc
--- /dev/null
+++ b/arch/arm/boot/dts/intel-ixp42x.dtsi
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: ISC
+/*
+ * Device Tree file for Intel XScale Network Processors
+ * in the IXP 42x series. This series has 32 interrupts.
+ */
+#include "intel-ixp4xx.dtsi"
+
+/ {
+	soc {
+		interrupt-controller@c8003000 {
+			compatible = "intel,ixp42x-interrupt";
+		};
+
+		/*
+		 * This is the USB Device Mode (UDC) controller, which is used
+		 * to present the IXP4xx as a device on a USB bus.
+		 */
+		usb@c800b000 {
+			compatible = "intel,ixp4xx-udc";
+			reg = <0xc800b000 0x1000>;
+			interrupts = <12 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/intel-ixp43x-gateworks-gw2358.dts b/arch/arm/boot/dts/intel-ixp43x-gateworks-gw2358.dts
new file mode 100644
index 000000000000..ba1163a1e1e7
--- /dev/null
+++ b/arch/arm/boot/dts/intel-ixp43x-gateworks-gw2358.dts
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: ISC
+/*
+ * Device Tree file for Gateworks IXP43x-based Cambria GW2358
+ */
+
+/dts-v1/;
+
+#include "intel-ixp43x.dtsi"
+
+/ {
+	model = "Gateworks Cambria GW2358";
+	compatible = "gateworks,gw2358", "intel,ixp43x";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	memory@0 {
+		/* 128 MB SDRAM */
+		device_type = "memory";
+		reg = <0x00000000 0x8000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200n8 root=/dev/mtdblock2 rw rootfstype=squashfs,jffs2 rootwait";
+		stdout-path = "uart0:115200n8";
+	};
+
+	aliases {
+		serial0 = &uart0;
+	};
+
+	leds {
+		compatible = "gpio-leds";
+		led-user {
+			label = "gw2358:green:LED";
+			gpios = <&pld1 0 GPIO_ACTIVE_LOW>;
+			default-state = "on";
+			linux,default-trigger = "heartbeat";
+		};
+	};
+
+
+	i2c {
+		compatible = "i2c-gpio";
+		sda-gpios = <&gpio0 7 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+		scl-gpios = <&gpio0 6 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		hwmon@28 {
+			compatible = "adi,ad7418";
+			reg = <0x28>;
+		};
+		rtc: ds1672@68 {
+			compatible = "dallas,ds1672";
+			reg = <0x68>;
+		};
+		eeprom@51 {
+			compatible = "atmel,24c08";
+			reg = <0x51>;
+			pagesize = <16>;
+			size = <1024>;
+			read-only;
+		};
+		pld0: pld@56 {
+			compatible = "gateworks,pld-gpio";
+			reg = <0x56>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+		/* This PLD just handles the LED and user button */
+		pld1: pld@57 {
+			compatible = "gateworks,pld-gpio";
+			reg = <0x57>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+	};
+
+	flash@50000000 {
+		compatible = "intel,ixp4xx-flash", "cfi-flash";
+		bank-width = <2>;
+		/*
+		 * 32 MB of Flash in 0x20000 byte blocks
+		 * mapped in at 0x50000000
+		 */
+		reg = <0x50000000 0x2000000>;
+
+		partitions {
+			compatible = "redboot-fis";
+			/* Eraseblock at 0x1fe0000 */
+			fis-index-block = <0xff>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/intel-ixp43x.dtsi b/arch/arm/boot/dts/intel-ixp43x.dtsi
new file mode 100644
index 000000000000..494fb2ff57a0
--- /dev/null
+++ b/arch/arm/boot/dts/intel-ixp43x.dtsi
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: ISC
+/*
+ * Device Tree file for Intel XScale Network Processors
+ * in the IXP 43x series. This series has 64 interrupts and adds a few more
+ * peripherals over the 42x series.
+ */
+#include "intel-ixp4xx.dtsi"
+
+/ {
+	soc {
+		interrupt-controller@c8003000 {
+			compatible = "intel,ixp43x-interrupt";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/intel-ixp45x-ixp46x.dtsi b/arch/arm/boot/dts/intel-ixp45x-ixp46x.dtsi
new file mode 100644
index 000000000000..f8cd506659dc
--- /dev/null
+++ b/arch/arm/boot/dts/intel-ixp45x-ixp46x.dtsi
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: ISC
+/*
+ * Device Tree file for Intel XScale Network Processors
+ * in the IXP45x and IXP46x series. This series has 64 interrupts and adds a
+ * few more peripherals over the 42x and 43x series so this extends the
+ * basic IXP4xx DTSI.
+ */
+#include "intel-ixp4xx.dtsi"
+
+/ {
+	soc {
+		interrupt-controller@c8003000 {
+			compatible = "intel,ixp43x-interrupt";
+		};
+
+		/*
+		 * This is the USB Device Mode (UDC) controller, which is used
+		 * to present the IXP4xx as a device on a USB bus.
+		 */
+		usb@c800b000 {
+			compatible = "intel,ixp4xx-udc";
+			reg = <0xc800b000 0x1000>;
+			interrupts = <12 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+
+		i2c@c8011000 {
+			compatible = "intel,ixp4xx-i2c";
+			reg = <0xc8011000 0x18>;
+			interrupts = <33 IRQ_TYPE_LEVEL_HIGH>;
+			status = "disabled";
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/intel-ixp4xx.dtsi b/arch/arm/boot/dts/intel-ixp4xx.dtsi
new file mode 100644
index 000000000000..9edd49509af8
--- /dev/null
+++ b/arch/arm/boot/dts/intel-ixp4xx.dtsi
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: ISC
+/*
+ * Device Tree file for Intel XScale Network Processors
+ * in the IXP 4xx series.
+ */
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+		compatible = "simple-bus";
+		interrupt-parent = <&intcon>;
+
+		uart0: serial@c8000000 {
+			compatible = "intel,xscale-uart";
+			reg = <0xc8000000 0x1000>;
+			/*
+			 * The reg-offset and reg-shift is a side effect
+			 * of running the platform in big endian mode.
+			 */
+			reg-offset = <3>;
+			reg-shift = <2>;
+			interrupts = <15 IRQ_TYPE_LEVEL_HIGH>;
+			clock-frequency = <14745600>;
+			no-loopback-test;
+		};
+
+		gpio0: gpio@c8004000 {
+			compatible = "intel,ixp4xx-gpio";
+			reg = <0xc8004000 0x1000>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		intcon: interrupt-controller@c8003000 {
+			/*
+			 * Note: no compatible string. The subvariant of the
+			 * chip needs to define what version it is. The
+			 * location of the interrupt controller is fixed in
+			 * memory across all variants.
+			 */
+			reg = <0xc8003000 0x100>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		timer@c8005000 {
+			compatible = "intel,ixp4xx-timer";
+			reg = <0xc8005000 0x100>;
+			interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
+		};
+	};
+};
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 18/30 v2] ARM: ixp4xx: Move NPE and QMGR to drivers/soc
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (16 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 17/30 v2] ARM: dts: Add some initial IXP4xx device trees Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 15:44 ` [PATCH 19/30 v2] ARM: ixp4xx: Move IXP4xx QMGR and NPE headers Linus Walleij
                   ` (12 subsequent siblings)
  30 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa; +Cc: Linus Walleij

The Network Processing Engine and Queue Manager are
versatile firmware components used by several IXP4xx
drivers.

Drivers are relying on getting access to these components
using <mach/*> headers which does not work with
multiplatform. We need to find a better place for the
drivers to live.

Let's first move them to drivers/soc and the start to
refactor a bit by passing resources and moving headers.

This patch introduce static IRQ assignments but that
will be fixed by later patches in this series.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 MAINTAINERS                                      |  4 ++--
 arch/arm/mach-ixp4xx/Kconfig                     | 13 -------------
 arch/arm/mach-ixp4xx/Makefile                    |  2 --
 drivers/soc/Kconfig                              |  1 +
 drivers/soc/Makefile                             |  1 +
 drivers/soc/ixp4xx/Kconfig                       | 16 ++++++++++++++++
 drivers/soc/ixp4xx/Makefile                      |  2 ++
 .../soc/ixp4xx/ixp4xx-npe.c                      |  0
 .../soc/ixp4xx/ixp4xx-qmgr.c                     |  5 ++++-
 9 files changed, 26 insertions(+), 18 deletions(-)
 create mode 100644 drivers/soc/ixp4xx/Kconfig
 create mode 100644 drivers/soc/ixp4xx/Makefile
 rename arch/arm/mach-ixp4xx/ixp4xx_npe.c => drivers/soc/ixp4xx/ixp4xx-npe.c (100%)
 rename arch/arm/mach-ixp4xx/ixp4xx_qmgr.c => drivers/soc/ixp4xx/ixp4xx-qmgr.c (98%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 20d02e1e60a8..2c4057a7c9b4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7723,8 +7723,8 @@ M:	Krzysztof Halasa <khalasa@piap.pl>
 S:	Maintained
 F:	arch/arm/mach-ixp4xx/include/mach/qmgr.h
 F:	arch/arm/mach-ixp4xx/include/mach/npe.h
-F:	arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
-F:	arch/arm/mach-ixp4xx/ixp4xx_npe.c
+F:	drivers/soc/ixp4xx/ixp4xx-qmgr.c
+F:	drivers/soc/ixp4xx/ixp4xx-npe.c
 F:	drivers/net/ethernet/xscale/ixp4xx_eth.c
 F:	drivers/net/wan/ixp4xx_hss.c
 
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index 0973270f4863..83afb80d38a8 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -236,19 +236,6 @@ config IXP4XX_INDIRECT_PCI
 	  need to use the indirect method instead. If you don't know
 	  what you need, leave this option unselected.
 
-config IXP4XX_QMGR
-	tristate "IXP4xx Queue Manager support"
-	help
-	  This driver supports IXP4xx built-in hardware queue manager
-	  and is automatically selected by Ethernet and HSS drivers.
-
-config IXP4XX_NPE
-	tristate "IXP4xx Network Processor Engine support"
-	select FW_LOADER
-	help
-	  This driver supports IXP4xx built-in network coprocessors
-	  and is automatically selected by Ethernet and HSS drivers.
-
 endmenu
 
 endif
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
index 5f63b3012826..1fa4e6605782 100644
--- a/arch/arm/mach-ixp4xx/Makefile
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -43,5 +43,3 @@ obj-$(CONFIG_MACH_GORAMO_MLR)	+= goramo_mlr.o
 obj-$(CONFIG_MACH_ARCOM_VULCAN)	+= vulcan-setup.o
 
 obj-$(CONFIG_PCI)		+= $(obj-pci-$(CONFIG_PCI)) common-pci.o
-obj-$(CONFIG_IXP4XX_QMGR)	+= ixp4xx_qmgr.o
-obj-$(CONFIG_IXP4XX_NPE)	+= ixp4xx_npe.o
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig
index c07b4a85253f..ae9bf20b26fa 100644
--- a/drivers/soc/Kconfig
+++ b/drivers/soc/Kconfig
@@ -6,6 +6,7 @@ source "drivers/soc/atmel/Kconfig"
 source "drivers/soc/bcm/Kconfig"
 source "drivers/soc/fsl/Kconfig"
 source "drivers/soc/imx/Kconfig"
+source "drivers/soc/ixp4xx/Kconfig"
 source "drivers/soc/mediatek/Kconfig"
 source "drivers/soc/qcom/Kconfig"
 source "drivers/soc/renesas/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile
index 90b686e586c6..c7c1a139ad8d 100644
--- a/drivers/soc/Makefile
+++ b/drivers/soc/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_MACH_DOVE)		+= dove/
 obj-y				+= fsl/
 obj-$(CONFIG_ARCH_GEMINI)	+= gemini/
 obj-$(CONFIG_ARCH_MXC)		+= imx/
+obj-$(CONFIG_ARCH_IXP4XX)	+= ixp4xx/
 obj-$(CONFIG_SOC_XWAY)		+= lantiq/
 obj-y				+= mediatek/
 obj-y				+= amlogic/
diff --git a/drivers/soc/ixp4xx/Kconfig b/drivers/soc/ixp4xx/Kconfig
new file mode 100644
index 000000000000..de6becdc78a2
--- /dev/null
+++ b/drivers/soc/ixp4xx/Kconfig
@@ -0,0 +1,16 @@
+menu "IXP4xx SoC drivers"
+
+config IXP4XX_QMGR
+	tristate "IXP4xx Queue Manager support"
+	help
+	  This driver supports IXP4xx built-in hardware queue manager
+	  and is automatically selected by Ethernet and HSS drivers.
+
+config IXP4XX_NPE
+	tristate "IXP4xx Network Processor Engine support"
+	select FW_LOADER
+	help
+	  This driver supports IXP4xx built-in network coprocessors
+	  and is automatically selected by Ethernet and HSS drivers.
+
+endmenu
diff --git a/drivers/soc/ixp4xx/Makefile b/drivers/soc/ixp4xx/Makefile
new file mode 100644
index 000000000000..d20d99e6df65
--- /dev/null
+++ b/drivers/soc/ixp4xx/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_IXP4XX_QMGR)	+= ixp4xx-qmgr.o
+obj-$(CONFIG_IXP4XX_NPE)	+= ixp4xx-npe.o
diff --git a/arch/arm/mach-ixp4xx/ixp4xx_npe.c b/drivers/soc/ixp4xx/ixp4xx-npe.c
similarity index 100%
rename from arch/arm/mach-ixp4xx/ixp4xx_npe.c
rename to drivers/soc/ixp4xx/ixp4xx-npe.c
diff --git a/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c b/drivers/soc/ixp4xx/ixp4xx-qmgr.c
similarity index 98%
rename from arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
rename to drivers/soc/ixp4xx/ixp4xx-qmgr.c
index 2665347a2c6f..2e6d33534afe 100644
--- a/arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
+++ b/drivers/soc/ixp4xx/ixp4xx-qmgr.c
@@ -15,7 +15,10 @@
 #include <linux/of.h>
 #include <mach/qmgr.h>
 
-#include "irqs.h"
+/* FIXME: get rid of these static assigments */
+#define IRQ_IXP4XX_BASE		16
+#define IRQ_IXP4XX_QM1		(IRQ_IXP4XX_BASE + 3)
+#define IRQ_IXP4XX_QM2		(IRQ_IXP4XX_BASE + 4)
 
 static struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
 static struct resource *mem_res;
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 19/30 v2] ARM: ixp4xx: Move IXP4xx QMGR and NPE headers
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (17 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 18/30 v2] ARM: ixp4xx: Move NPE and QMGR to drivers/soc Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 15:44 ` [PATCH 20/30 v2] ARM: ixp4xx: Turn the NPE into a platform device Linus Walleij
                   ` (11 subsequent siblings)
  30 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa; +Cc: Linus Walleij

This moves the IXP4xx Queue Manager and Network Processing
Engine headers out of the <mack/*> include path as that is
incompatible with multiplatform.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 MAINTAINERS                                                   | 4 ++--
 drivers/crypto/ixp4xx_crypto.c                                | 4 ++--
 drivers/net/ethernet/xscale/ixp4xx_eth.c                      | 4 ++--
 drivers/net/wan/ixp4xx_hss.c                                  | 4 ++--
 drivers/soc/ixp4xx/ixp4xx-npe.c                               | 2 +-
 drivers/soc/ixp4xx/ixp4xx-qmgr.c                              | 2 +-
 .../include/mach => include/linux/soc/ixp4xx}/npe.h           | 0
 .../include/mach => include/linux/soc/ixp4xx}/qmgr.h          | 0
 8 files changed, 10 insertions(+), 10 deletions(-)
 rename {arch/arm/mach-ixp4xx/include/mach => include/linux/soc/ixp4xx}/npe.h (100%)
 rename {arch/arm/mach-ixp4xx/include/mach => include/linux/soc/ixp4xx}/qmgr.h (100%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 2c4057a7c9b4..1eb9dbcefdc4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7721,8 +7721,8 @@ F:	Documentation/media/v4l-drivers/ipu3.rst
 INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT
 M:	Krzysztof Halasa <khalasa@piap.pl>
 S:	Maintained
-F:	arch/arm/mach-ixp4xx/include/mach/qmgr.h
-F:	arch/arm/mach-ixp4xx/include/mach/npe.h
+F:	include/linux/soc/ixp4xx/qmgr.h
+F:	include/linux/soc/ixp4xx/npe.h
 F:	drivers/soc/ixp4xx/ixp4xx-qmgr.c
 F:	drivers/soc/ixp4xx/ixp4xx-npe.c
 F:	drivers/net/ethernet/xscale/ixp4xx_eth.c
diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c
index 19fba998b86b..97f2a5dc7cc6 100644
--- a/drivers/crypto/ixp4xx_crypto.c
+++ b/drivers/crypto/ixp4xx_crypto.c
@@ -30,8 +30,8 @@
 #include <crypto/authenc.h>
 #include <crypto/scatterwalk.h>
 
-#include <mach/npe.h>
-#include <mach/qmgr.h>
+#include <linux/soc/ixp4xx/npe.h>
+#include <linux/soc/ixp4xx/qmgr.h>
 
 #define MAX_KEYLEN 32
 
diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c
index 7ad3c3b56a77..abf59f30f18b 100644
--- a/drivers/net/ethernet/xscale/ixp4xx_eth.c
+++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c
@@ -38,8 +38,8 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <mach/ixp46x_ts.h>
-#include <mach/npe.h>
-#include <mach/qmgr.h>
+#include <linux/soc/ixp4xx/npe.h>
+#include <linux/soc/ixp4xx/qmgr.h>
 
 #define DEBUG_DESC		0
 #define DEBUG_RX		0
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c
index 6a505c26a3e7..791af08ed822 100644
--- a/drivers/net/wan/ixp4xx_hss.c
+++ b/drivers/net/wan/ixp4xx_hss.c
@@ -22,8 +22,8 @@
 #include <linux/platform_device.h>
 #include <linux/poll.h>
 #include <linux/slab.h>
-#include <mach/npe.h>
-#include <mach/qmgr.h>
+#include <linux/soc/ixp4xx/npe.h>
+#include <linux/soc/ixp4xx/qmgr.h>
 
 #define DEBUG_DESC		0
 #define DEBUG_RX		0
diff --git a/drivers/soc/ixp4xx/ixp4xx-npe.c b/drivers/soc/ixp4xx/ixp4xx-npe.c
index e0ce22cd9bfc..1f6e01369d54 100644
--- a/drivers/soc/ixp4xx/ixp4xx-npe.c
+++ b/drivers/soc/ixp4xx/ixp4xx-npe.c
@@ -21,7 +21,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
-#include <mach/npe.h>
+#include <linux/soc/ixp4xx/npe.h>
 
 #define DEBUG_MSG			0
 #define DEBUG_FW			0
diff --git a/drivers/soc/ixp4xx/ixp4xx-qmgr.c b/drivers/soc/ixp4xx/ixp4xx-qmgr.c
index 2e6d33534afe..1bed048924bb 100644
--- a/drivers/soc/ixp4xx/ixp4xx-qmgr.c
+++ b/drivers/soc/ixp4xx/ixp4xx-qmgr.c
@@ -13,7 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
-#include <mach/qmgr.h>
+#include <linux/soc/ixp4xx/qmgr.h>
 
 /* FIXME: get rid of these static assigments */
 #define IRQ_IXP4XX_BASE		16
diff --git a/arch/arm/mach-ixp4xx/include/mach/npe.h b/include/linux/soc/ixp4xx/npe.h
similarity index 100%
rename from arch/arm/mach-ixp4xx/include/mach/npe.h
rename to include/linux/soc/ixp4xx/npe.h
diff --git a/arch/arm/mach-ixp4xx/include/mach/qmgr.h b/include/linux/soc/ixp4xx/qmgr.h
similarity index 100%
rename from arch/arm/mach-ixp4xx/include/mach/qmgr.h
rename to include/linux/soc/ixp4xx/qmgr.h
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 20/30 v2] ARM: ixp4xx: Turn the NPE into a platform device
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (18 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 19/30 v2] ARM: ixp4xx: Move IXP4xx QMGR and NPE headers Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 15:44 ` [PATCH 21/30 v2] ARM: ixp4xx: Turn the QMGR " Linus Walleij
                   ` (10 subsequent siblings)
  30 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa; +Cc: Linus Walleij

Instead of registering everything related to the NPE
unconditionally in the module_init() call (which will
never work with multiplatform) create a platform device
and probe the NPE like any other device.

Put the device first in the list of devices added for
the platform so it is there when the dependent network
and crypto drivers probe later on.

This probe() path will not be taken unconditionally on
device tree boots, so remove the DT guard.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/mach-ixp4xx/common.c   |  6 ++++++
 drivers/soc/ixp4xx/ixp4xx-npe.c | 23 +++++++++++++----------
 2 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index fc4c9b21ca96..e7789d06c39b 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -150,7 +150,13 @@ static struct platform_device ixp4xx_udc_device = {
 	},
 };
 
+static struct platform_device ixp4xx_npe_device = {
+	.name           = "ixp4xx-npe",
+	.id             = -1,
+};
+
 static struct platform_device *ixp4xx_devices[] __initdata = {
+	&ixp4xx_npe_device,
 	&ixp4xx_gpio_device,
 	&ixp4xx_udc_device,
 };
diff --git a/drivers/soc/ixp4xx/ixp4xx-npe.c b/drivers/soc/ixp4xx/ixp4xx-npe.c
index 1f6e01369d54..e3294457b5de 100644
--- a/drivers/soc/ixp4xx/ixp4xx-npe.c
+++ b/drivers/soc/ixp4xx/ixp4xx-npe.c
@@ -21,6 +21,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/platform_device.h>
 #include <linux/soc/ixp4xx/npe.h>
 
 #define DEBUG_MSG			0
@@ -683,16 +684,10 @@ void npe_release(struct npe *npe)
 	module_put(THIS_MODULE);
 }
 
-
-static int __init npe_init_module(void)
+static int ixp4xx_npe_probe(struct platform_device *pdev)
 {
-
 	int i, found = 0;
 
-	/* This driver does not work with device tree */
-	if (of_have_populated_dt())
-		return -ENODEV;
-
 	for (i = 0; i < NPE_COUNT; i++) {
 		struct npe *npe = &npe_tab[i];
 		if (!(ixp4xx_read_feature_bits() &
@@ -717,7 +712,7 @@ static int __init npe_init_module(void)
 	return 0;
 }
 
-static void __exit npe_cleanup_module(void)
+static int ixp4xx_npe_remove(struct platform_device *pdev)
 {
 	int i;
 
@@ -726,10 +721,18 @@ static void __exit npe_cleanup_module(void)
 			npe_reset(&npe_tab[i]);
 			release_resource(npe_tab[i].mem_res);
 		}
+
+	return 0;
 }
 
-module_init(npe_init_module);
-module_exit(npe_cleanup_module);
+static struct platform_driver ixp4xx_npe_driver = {
+	.driver = {
+		.name           = "ixp4xx-npe",
+	},
+	.probe = ixp4xx_npe_probe,
+	.remove = ixp4xx_npe_remove,
+};
+module_platform_driver(ixp4xx_npe_driver);
 
 MODULE_AUTHOR("Krzysztof Halasa");
 MODULE_LICENSE("GPL v2");
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 21/30 v2] ARM: ixp4xx: Turn the QMGR into a platform device
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (19 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 20/30 v2] ARM: ixp4xx: Turn the NPE into a platform device Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 15:44 ` [PATCH 22/30 v2] soc: ixp4xx: npe: Pass addresses as resources Linus Walleij
                   ` (9 subsequent siblings)
  30 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa; +Cc: Linus Walleij

Instead of registering everything related to the QMGR
unconditionally in the module_init() call (which will
never work with multiplatform) create a platform device
and probe the QMGR like any other device.

Put the device second in the list of devices added for
the platform so it is there when the dependent network
and crypto drivers probe later on.

This probe() path will not be taken unconditionally on
device tree boots, so remove the DT guard.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/mach-ixp4xx/common.c    |  6 ++++++
 drivers/soc/ixp4xx/ixp4xx-qmgr.c | 21 +++++++++++++--------
 2 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index e7789d06c39b..cdcd6d6b6d3d 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -155,8 +155,14 @@ static struct platform_device ixp4xx_npe_device = {
 	.id             = -1,
 };
 
+static struct platform_device ixp4xx_qmgr_device = {
+	.name           = "ixp4xx-qmgr",
+	.id             = -1,
+};
+
 static struct platform_device *ixp4xx_devices[] __initdata = {
 	&ixp4xx_npe_device,
+	&ixp4xx_qmgr_device,
 	&ixp4xx_gpio_device,
 	&ixp4xx_udc_device,
 };
diff --git a/drivers/soc/ixp4xx/ixp4xx-qmgr.c b/drivers/soc/ixp4xx/ixp4xx-qmgr.c
index 1bed048924bb..133914e99aeb 100644
--- a/drivers/soc/ixp4xx/ixp4xx-qmgr.c
+++ b/drivers/soc/ixp4xx/ixp4xx-qmgr.c
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/platform_device.h>
 #include <linux/soc/ixp4xx/qmgr.h>
 
 /* FIXME: get rid of these static assigments */
@@ -288,15 +289,11 @@ void qmgr_release_queue(unsigned int queue)
 	module_put(THIS_MODULE);
 }
 
-static int qmgr_init(void)
+static int ixp4xx_qmgr_probe(struct platform_device *pdev)
 {
 	int i, err;
 	irq_handler_t handler1, handler2;
 
-	/* This driver does not work with device tree */
-	if (of_have_populated_dt())
-		return -ENODEV;
-
 	mem_res = request_mem_region(IXP4XX_QMGR_BASE_PHYS,
 				     IXP4XX_QMGR_REGION_SIZE,
 				     "IXP4xx Queue Manager");
@@ -355,17 +352,25 @@ static int qmgr_init(void)
 	return err;
 }
 
-static void qmgr_remove(void)
+static int ixp4xx_qmgr_remove(struct platform_device *pdev)
 {
 	free_irq(IRQ_IXP4XX_QM1, NULL);
 	free_irq(IRQ_IXP4XX_QM2, NULL);
 	synchronize_irq(IRQ_IXP4XX_QM1);
 	synchronize_irq(IRQ_IXP4XX_QM2);
 	release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
+
+	return 0;
 }
 
-module_init(qmgr_init);
-module_exit(qmgr_remove);
+static struct platform_driver ixp4xx_qmgr_driver = {
+	.driver = {
+		.name           = "ixp4xx-qmgr",
+	},
+	.probe = ixp4xx_qmgr_probe,
+	.remove = ixp4xx_qmgr_remove,
+};
+module_platform_driver(ixp4xx_qmgr_driver);
 
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Krzysztof Halasa");
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 22/30 v2] soc: ixp4xx: npe: Pass addresses as resources
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (20 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 21/30 v2] ARM: ixp4xx: Turn the QMGR " Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 15:44 ` [PATCH 23/30 v2] soc: ixp4xx: Uninline several functions Linus Walleij
                   ` (8 subsequent siblings)
  30 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa; +Cc: Linus Walleij

Instead of using hardcoded base addresses implicitly
obtained through <linux/io.h>, pass the physical base
for the three NPE blocks as memory resources and remap
these in the driver.

Drop the memory request region business, this will
anyways be done by devm_* remapping functions.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/mach-ixp4xx/common.c                 | 21 +++++++++++
 .../mach-ixp4xx/include/mach/ixp4xx-regs.h    |  3 --
 drivers/soc/ixp4xx/ixp4xx-npe.c               | 36 ++++++++++---------
 include/linux/soc/ixp4xx/npe.h                |  2 --
 4 files changed, 41 insertions(+), 21 deletions(-)

diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index cdcd6d6b6d3d..07c3cb312a92 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -150,9 +150,30 @@ static struct platform_device ixp4xx_udc_device = {
 	},
 };
 
+static struct resource ixp4xx_npe_resources[] = {
+	{
+		.start = IXP4XX_NPEA_BASE_PHYS,
+		.end = IXP4XX_NPEA_BASE_PHYS + 0xfff,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IXP4XX_NPEB_BASE_PHYS,
+		.end = IXP4XX_NPEB_BASE_PHYS + 0xfff,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IXP4XX_NPEC_BASE_PHYS,
+		.end = IXP4XX_NPEC_BASE_PHYS + 0xfff,
+		.flags = IORESOURCE_MEM,
+	},
+
+};
+
 static struct platform_device ixp4xx_npe_device = {
 	.name           = "ixp4xx-npe",
 	.id             = -1,
+	.num_resources  = ARRAY_SIZE(ixp4xx_npe_resources),
+	.resource       = ixp4xx_npe_resources,
 };
 
 static struct platform_device ixp4xx_qmgr_device = {
diff --git a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
index 459abe2eb4b5..f5d5b258c3f7 100644
--- a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
+++ b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
@@ -132,9 +132,6 @@
 #define IXP4XX_INTC_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x3000)
 #define IXP4XX_GPIO_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x4000)
 #define IXP4XX_TIMER_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x5000)
-#define IXP4XX_NPEA_BASE_VIRT   	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x6000)
-#define IXP4XX_NPEB_BASE_VIRT   	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x7000)
-#define IXP4XX_NPEC_BASE_VIRT   	(IXP4XX_PERIPHERAL_BASE_VIRT + 0x8000)
 #define IXP4XX_EthB_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0x9000)
 #define IXP4XX_EthC_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0xA000)
 #define IXP4XX_USB_BASE_VIRT		(IXP4XX_PERIPHERAL_BASE_VIRT + 0xB000)
diff --git a/drivers/soc/ixp4xx/ixp4xx-npe.c b/drivers/soc/ixp4xx/ixp4xx-npe.c
index e3294457b5de..d2dd916816d4 100644
--- a/drivers/soc/ixp4xx/ixp4xx-npe.c
+++ b/drivers/soc/ixp4xx/ixp4xx-npe.c
@@ -155,16 +155,10 @@ static struct {
 static struct npe npe_tab[NPE_COUNT] = {
 	{
 		.id	= 0,
-		.regs	= (struct npe_regs __iomem *)IXP4XX_NPEA_BASE_VIRT,
-		.regs_phys = IXP4XX_NPEA_BASE_PHYS,
 	}, {
 		.id	= 1,
-		.regs	= (struct npe_regs __iomem *)IXP4XX_NPEB_BASE_VIRT,
-		.regs_phys = IXP4XX_NPEB_BASE_PHYS,
 	}, {
 		.id	= 2,
-		.regs	= (struct npe_regs __iomem *)IXP4XX_NPEC_BASE_VIRT,
-		.regs_phys = IXP4XX_NPEC_BASE_PHYS,
 	}
 };
 
@@ -687,23 +681,34 @@ void npe_release(struct npe *npe)
 static int ixp4xx_npe_probe(struct platform_device *pdev)
 {
 	int i, found = 0;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
 
 	for (i = 0; i < NPE_COUNT; i++) {
 		struct npe *npe = &npe_tab[i];
+
+		res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+		if (!res)
+			return -ENODEV;
+
 		if (!(ixp4xx_read_feature_bits() &
-		      (IXP4XX_FEATURE_RESET_NPEA << i)))
+		      (IXP4XX_FEATURE_RESET_NPEA << i))) {
+			dev_info(dev, "NPE%d at 0x%08x-0x%08x not available\n",
+				 i, res->start, res->end);
 			continue; /* NPE already disabled or not present */
-		if (!(npe->mem_res = request_mem_region(npe->regs_phys,
-							REGS_SIZE,
-							npe_name(npe)))) {
-			print_npe(KERN_ERR, npe,
-				  "failed to request memory region\n");
-			continue;
 		}
+		npe->regs = devm_ioremap_resource(dev, res);
+		if (!npe->regs)
+			return -ENOMEM;
 
-		if (npe_reset(npe))
+		if (npe_reset(npe)) {
+			dev_info(dev, "NPE%d at 0x%08x-0x%08x does not reset\n",
+				 i, res->start, res->end);
 			continue;
+		}
 		npe->valid = 1;
+		dev_info(dev, "NPE%d at 0x%08x-0x%08x registered\n",
+			 i, res->start, res->end);
 		found++;
 	}
 
@@ -717,9 +722,8 @@ static int ixp4xx_npe_remove(struct platform_device *pdev)
 	int i;
 
 	for (i = 0; i < NPE_COUNT; i++)
-		if (npe_tab[i].mem_res) {
+		if (npe_tab[i].regs) {
 			npe_reset(&npe_tab[i]);
-			release_resource(npe_tab[i].mem_res);
 		}
 
 	return 0;
diff --git a/include/linux/soc/ixp4xx/npe.h b/include/linux/soc/ixp4xx/npe.h
index 3a980845e557..2a91f465d456 100644
--- a/include/linux/soc/ixp4xx/npe.h
+++ b/include/linux/soc/ixp4xx/npe.h
@@ -16,9 +16,7 @@ struct npe_regs {
 };
 
 struct npe {
-	struct resource *mem_res;
 	struct npe_regs __iomem *regs;
-	u32 regs_phys;
 	int id;
 	int valid;
 };
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 23/30 v2] soc: ixp4xx: Uninline several functions
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (21 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 22/30 v2] soc: ixp4xx: npe: Pass addresses as resources Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 15:44 ` [PATCH 24/30 v2] soc: ixp4xx: Remove unused functions Linus Walleij
                   ` (7 subsequent siblings)
  30 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa; +Cc: Linus Walleij

These inline functions immediately exploit the static ioremaps
for the queue manager memory region. This does not work with
multiplatform where everything need to be dynamically remapped,
so get rid of these inlines and create new exports for those
used by other drivers.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/soc/ixp4xx/ixp4xx-qmgr.c | 117 ++++++++++++++++++++++++++++
 include/linux/soc/ixp4xx/qmgr.h  | 127 ++-----------------------------
 2 files changed, 124 insertions(+), 120 deletions(-)

diff --git a/drivers/soc/ixp4xx/ixp4xx-qmgr.c b/drivers/soc/ixp4xx/ixp4xx-qmgr.c
index 133914e99aeb..412a346136d8 100644
--- a/drivers/soc/ixp4xx/ixp4xx-qmgr.c
+++ b/drivers/soc/ixp4xx/ixp4xx-qmgr.c
@@ -32,6 +32,117 @@ static void *irq_pdevs[QUEUES];
 char qmgr_queue_descs[QUEUES][32];
 #endif
 
+void qmgr_put_entry(unsigned int queue, u32 val)
+{
+#if DEBUG_QMGR
+	BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
+
+	printk(KERN_DEBUG "Queue %s(%i) put %X\n",
+	       qmgr_queue_descs[queue], queue, val);
+#endif
+	__raw_writel(val, &qmgr_regs->acc[queue][0]);
+}
+
+u32 qmgr_get_entry(unsigned int queue)
+{
+	u32 val;
+	val = __raw_readl(&qmgr_regs->acc[queue][0]);
+#if DEBUG_QMGR
+	BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
+
+	printk(KERN_DEBUG "Queue %s(%i) get %X\n",
+	       qmgr_queue_descs[queue], queue, val);
+#endif
+	return val;
+}
+
+static int __qmgr_get_stat1(unsigned int queue)
+{
+	return (__raw_readl(&qmgr_regs->stat1[queue >> 3])
+		>> ((queue & 7) << 2)) & 0xF;
+}
+
+static int __qmgr_get_stat2(unsigned int queue)
+{
+	BUG_ON(queue >= HALF_QUEUES);
+	return (__raw_readl(&qmgr_regs->stat2[queue >> 4])
+		>> ((queue & 0xF) << 1)) & 0x3;
+}
+
+/**
+ * qmgr_stat_empty() - checks if a hardware queue is empty
+ * @queue:	queue number
+ *
+ * Returns non-zero value if the queue is empty.
+ */
+int qmgr_stat_empty(unsigned int queue)
+{
+	BUG_ON(queue >= HALF_QUEUES);
+	return __qmgr_get_stat1(queue) & QUEUE_STAT1_EMPTY;
+}
+
+/**
+ * qmgr_stat_below_low_watermark() - checks if a queue is below low watermark
+ * @queue:	queue number
+ *
+ * Returns non-zero value if the queue is below low watermark.
+ */
+int qmgr_stat_below_low_watermark(unsigned int queue)
+{
+	if (queue >= HALF_QUEUES)
+		return (__raw_readl(&qmgr_regs->statne_h) >>
+			(queue - HALF_QUEUES)) & 0x01;
+	return __qmgr_get_stat1(queue) & QUEUE_STAT1_NEARLY_EMPTY;
+}
+
+/**
+ * qmgr_stat_above_high_watermark() - checks if a queue is above high watermark
+ * @queue:	queue number
+ *
+ * Returns non-zero value if the queue is above high watermark
+ */
+static int qmgr_stat_above_high_watermark(unsigned int queue)
+{
+	BUG_ON(queue >= HALF_QUEUES);
+	return __qmgr_get_stat1(queue) & QUEUE_STAT1_NEARLY_FULL;
+}
+
+/**
+ * qmgr_stat_full() - checks if a hardware queue is full
+ * @queue:	queue number
+ *
+ * Returns non-zero value if the queue is full.
+ */
+int qmgr_stat_full(unsigned int queue)
+{
+	if (queue >= HALF_QUEUES)
+		return (__raw_readl(&qmgr_regs->statf_h) >>
+			(queue - HALF_QUEUES)) & 0x01;
+	return __qmgr_get_stat1(queue) & QUEUE_STAT1_FULL;
+}
+
+/**
+ * qmgr_stat_underflow() - checks if a hardware queue experienced underflow
+ * @queue:	queue number
+ *
+ * Returns non-zero value if the queue experienced underflow.
+ */
+static int qmgr_stat_underflow(unsigned int queue)
+{
+	return __qmgr_get_stat2(queue) & QUEUE_STAT2_UNDERFLOW;
+}
+
+/**
+ * qmgr_stat_overflow() - checks if a hardware queue experienced overflow
+ * @queue:	queue number
+ *
+ * Returns non-zero value if the queue experienced overflow.
+ */
+int qmgr_stat_overflow(unsigned int queue)
+{
+	return __qmgr_get_stat2(queue) & QUEUE_STAT2_OVERFLOW;
+}
+
 void qmgr_set_irq(unsigned int queue, int src,
 		  void (*handler)(void *pdev), void *pdev)
 {
@@ -375,6 +486,12 @@ module_platform_driver(ixp4xx_qmgr_driver);
 MODULE_LICENSE("GPL v2");
 MODULE_AUTHOR("Krzysztof Halasa");
 
+EXPORT_SYMBOL(qmgr_put_entry);
+EXPORT_SYMBOL(qmgr_get_entry);
+EXPORT_SYMBOL(qmgr_stat_empty);
+EXPORT_SYMBOL(qmgr_stat_below_low_watermark);
+EXPORT_SYMBOL(qmgr_stat_full);
+EXPORT_SYMBOL(qmgr_stat_overflow);
 EXPORT_SYMBOL(qmgr_set_irq);
 EXPORT_SYMBOL(qmgr_enable_irq);
 EXPORT_SYMBOL(qmgr_disable_irq);
diff --git a/include/linux/soc/ixp4xx/qmgr.h b/include/linux/soc/ixp4xx/qmgr.h
index 4de8da536dbb..bed8ee94fa57 100644
--- a/include/linux/soc/ixp4xx/qmgr.h
+++ b/include/linux/soc/ixp4xx/qmgr.h
@@ -57,6 +57,13 @@ struct qmgr_regs {
 	u32 sram[2048];		/* 0x2000 - 0x3FFF - config and buffer */
 };
 
+void qmgr_put_entry(unsigned int queue, u32 val);
+u32 qmgr_get_entry(unsigned int queue);
+int qmgr_stat_empty(unsigned int queue);
+int qmgr_stat_below_low_watermark(unsigned int queue);
+int qmgr_stat_full(unsigned int queue);
+int qmgr_stat_overflow(unsigned int queue);
+void qmgr_release_queue(unsigned int queue);
 void qmgr_set_irq(unsigned int queue, int src,
 		  void (*handler)(void *pdev), void *pdev);
 void qmgr_enable_irq(unsigned int queue);
@@ -81,124 +88,4 @@ int __qmgr_request_queue(unsigned int queue, unsigned int len /* dwords */,
 			     nearly_full_watermark)
 #endif
 
-void qmgr_release_queue(unsigned int queue);
-
-
-static inline void qmgr_put_entry(unsigned int queue, u32 val)
-{
-	struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
-#if DEBUG_QMGR
-	BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
-
-	printk(KERN_DEBUG "Queue %s(%i) put %X\n",
-	       qmgr_queue_descs[queue], queue, val);
-#endif
-	__raw_writel(val, &qmgr_regs->acc[queue][0]);
-}
-
-static inline u32 qmgr_get_entry(unsigned int queue)
-{
-	u32 val;
-	const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
-	val = __raw_readl(&qmgr_regs->acc[queue][0]);
-#if DEBUG_QMGR
-	BUG_ON(!qmgr_queue_descs[queue]); /* not yet requested */
-
-	printk(KERN_DEBUG "Queue %s(%i) get %X\n",
-	       qmgr_queue_descs[queue], queue, val);
-#endif
-	return val;
-}
-
-static inline int __qmgr_get_stat1(unsigned int queue)
-{
-	const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
-	return (__raw_readl(&qmgr_regs->stat1[queue >> 3])
-		>> ((queue & 7) << 2)) & 0xF;
-}
-
-static inline int __qmgr_get_stat2(unsigned int queue)
-{
-	const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
-	BUG_ON(queue >= HALF_QUEUES);
-	return (__raw_readl(&qmgr_regs->stat2[queue >> 4])
-		>> ((queue & 0xF) << 1)) & 0x3;
-}
-
-/**
- * qmgr_stat_empty() - checks if a hardware queue is empty
- * @queue:	queue number
- *
- * Returns non-zero value if the queue is empty.
- */
-static inline int qmgr_stat_empty(unsigned int queue)
-{
-	BUG_ON(queue >= HALF_QUEUES);
-	return __qmgr_get_stat1(queue) & QUEUE_STAT1_EMPTY;
-}
-
-/**
- * qmgr_stat_below_low_watermark() - checks if a queue is below low watermark
- * @queue:	queue number
- *
- * Returns non-zero value if the queue is below low watermark.
- */
-static inline int qmgr_stat_below_low_watermark(unsigned int queue)
-{
-	const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
-	if (queue >= HALF_QUEUES)
-		return (__raw_readl(&qmgr_regs->statne_h) >>
-			(queue - HALF_QUEUES)) & 0x01;
-	return __qmgr_get_stat1(queue) & QUEUE_STAT1_NEARLY_EMPTY;
-}
-
-/**
- * qmgr_stat_above_high_watermark() - checks if a queue is above high watermark
- * @queue:	queue number
- *
- * Returns non-zero value if the queue is above high watermark
- */
-static inline int qmgr_stat_above_high_watermark(unsigned int queue)
-{
-	BUG_ON(queue >= HALF_QUEUES);
-	return __qmgr_get_stat1(queue) & QUEUE_STAT1_NEARLY_FULL;
-}
-
-/**
- * qmgr_stat_full() - checks if a hardware queue is full
- * @queue:	queue number
- *
- * Returns non-zero value if the queue is full.
- */
-static inline int qmgr_stat_full(unsigned int queue)
-{
-	const struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
-	if (queue >= HALF_QUEUES)
-		return (__raw_readl(&qmgr_regs->statf_h) >>
-			(queue - HALF_QUEUES)) & 0x01;
-	return __qmgr_get_stat1(queue) & QUEUE_STAT1_FULL;
-}
-
-/**
- * qmgr_stat_underflow() - checks if a hardware queue experienced underflow
- * @queue:	queue number
- *
- * Returns non-zero value if the queue experienced underflow.
- */
-static inline int qmgr_stat_underflow(unsigned int queue)
-{
-	return __qmgr_get_stat2(queue) & QUEUE_STAT2_UNDERFLOW;
-}
-
-/**
- * qmgr_stat_overflow() - checks if a hardware queue experienced overflow
- * @queue:	queue number
- *
- * Returns non-zero value if the queue experienced overflow.
- */
-static inline int qmgr_stat_overflow(unsigned int queue)
-{
-	return __qmgr_get_stat2(queue) & QUEUE_STAT2_OVERFLOW;
-}
-
 #endif
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 24/30 v2] soc: ixp4xx: Remove unused functions
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (22 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 23/30 v2] soc: ixp4xx: Uninline several functions Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 15:44 ` [PATCH 25/30 v2] soc: ixp4xx: qmgr: Pass resources Linus Walleij
                   ` (6 subsequent siblings)
  30 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa; +Cc: Linus Walleij

These former inlines turn out to be unused in the kernel.
If they are needed in the future, they can be resurrected
by reverting or studying this commit.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/soc/ixp4xx/ixp4xx-qmgr.c | 23 -----------------------
 1 file changed, 23 deletions(-)

diff --git a/drivers/soc/ixp4xx/ixp4xx-qmgr.c b/drivers/soc/ixp4xx/ixp4xx-qmgr.c
index 412a346136d8..f3775346e007 100644
--- a/drivers/soc/ixp4xx/ixp4xx-qmgr.c
+++ b/drivers/soc/ixp4xx/ixp4xx-qmgr.c
@@ -95,18 +95,6 @@ int qmgr_stat_below_low_watermark(unsigned int queue)
 	return __qmgr_get_stat1(queue) & QUEUE_STAT1_NEARLY_EMPTY;
 }
 
-/**
- * qmgr_stat_above_high_watermark() - checks if a queue is above high watermark
- * @queue:	queue number
- *
- * Returns non-zero value if the queue is above high watermark
- */
-static int qmgr_stat_above_high_watermark(unsigned int queue)
-{
-	BUG_ON(queue >= HALF_QUEUES);
-	return __qmgr_get_stat1(queue) & QUEUE_STAT1_NEARLY_FULL;
-}
-
 /**
  * qmgr_stat_full() - checks if a hardware queue is full
  * @queue:	queue number
@@ -121,17 +109,6 @@ int qmgr_stat_full(unsigned int queue)
 	return __qmgr_get_stat1(queue) & QUEUE_STAT1_FULL;
 }
 
-/**
- * qmgr_stat_underflow() - checks if a hardware queue experienced underflow
- * @queue:	queue number
- *
- * Returns non-zero value if the queue experienced underflow.
- */
-static int qmgr_stat_underflow(unsigned int queue)
-{
-	return __qmgr_get_stat2(queue) & QUEUE_STAT2_UNDERFLOW;
-}
-
 /**
  * qmgr_stat_overflow() - checks if a hardware queue experienced overflow
  * @queue:	queue number
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 25/30 v2] soc: ixp4xx: qmgr: Pass resources
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (23 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 24/30 v2] soc: ixp4xx: Remove unused functions Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 15:44 ` [PATCH 26/30 v2] soc: ixp4xx: Add DT bindings for IXP4xx NPE Linus Walleij
                   ` (5 subsequent siblings)
  30 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa; +Cc: Linus Walleij

Instead of using hardcoded base address implicitly
obtained through <linux/io.h>, pass the physical base
for the QMGR block as a memory resource and remap
it in the driver.

Also pass the two IRQs as resources and obtain them
in the driver.

Use devm_* accessors and simplify the error path in the
process. Drop memory region request as this is done by
the devm_ioremap* functions.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/mach-ixp4xx/common.c                 | 25 +++++--
 .../mach-ixp4xx/include/mach/ixp4xx-regs.h    |  2 -
 drivers/soc/ixp4xx/ixp4xx-qmgr.c              | 71 +++++++++----------
 3 files changed, 55 insertions(+), 43 deletions(-)

diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 07c3cb312a92..cc5f15679d29 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -66,11 +66,6 @@ static struct map_desc ixp4xx_io_desc[] __initdata = {
 		.pfn		= __phys_to_pfn(IXP4XX_PCI_CFG_BASE_PHYS),
 		.length		= IXP4XX_PCI_CFG_REGION_SIZE,
 		.type		= MT_DEVICE
-	}, {	/* Queue Manager */
-		.virtual	= (unsigned long)IXP4XX_QMGR_BASE_VIRT,
-		.pfn		= __phys_to_pfn(IXP4XX_QMGR_BASE_PHYS),
-		.length		= IXP4XX_QMGR_REGION_SIZE,
-		.type		= MT_DEVICE
 	},
 };
 
@@ -176,9 +171,29 @@ static struct platform_device ixp4xx_npe_device = {
 	.resource       = ixp4xx_npe_resources,
 };
 
+static struct resource ixp4xx_qmgr_resources[] = {
+	{
+		.start = IXP4XX_QMGR_BASE_PHYS,
+		.end = IXP4XX_QMGR_BASE_PHYS + 0x3fff,
+		.flags = IORESOURCE_MEM,
+	},
+	{
+		.start = IRQ_IXP4XX_QM1,
+		.end = IRQ_IXP4XX_QM1,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.start = IRQ_IXP4XX_QM2,
+		.end = IRQ_IXP4XX_QM2,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
 static struct platform_device ixp4xx_qmgr_device = {
 	.name           = "ixp4xx-qmgr",
 	.id             = -1,
+	.num_resources  = ARRAY_SIZE(ixp4xx_qmgr_resources),
+	.resource       = ixp4xx_qmgr_resources,
 };
 
 static struct platform_device *ixp4xx_devices[] __initdata = {
diff --git a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
index f5d5b258c3f7..588b76651085 100644
--- a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
+++ b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h
@@ -43,8 +43,6 @@
  * Queue Manager
  */
 #define IXP4XX_QMGR_BASE_PHYS		0x60000000
-#define IXP4XX_QMGR_BASE_VIRT		IOMEM(0xFEF15000)
-#define IXP4XX_QMGR_REGION_SIZE		0x00004000
 
 /*
  * Peripheral space, including debug UART. Must be section-aligned so that
diff --git a/drivers/soc/ixp4xx/ixp4xx-qmgr.c b/drivers/soc/ixp4xx/ixp4xx-qmgr.c
index f3775346e007..64572f2d6ff0 100644
--- a/drivers/soc/ixp4xx/ixp4xx-qmgr.c
+++ b/drivers/soc/ixp4xx/ixp4xx-qmgr.c
@@ -16,13 +16,9 @@
 #include <linux/platform_device.h>
 #include <linux/soc/ixp4xx/qmgr.h>
 
-/* FIXME: get rid of these static assigments */
-#define IRQ_IXP4XX_BASE		16
-#define IRQ_IXP4XX_QM1		(IRQ_IXP4XX_BASE + 3)
-#define IRQ_IXP4XX_QM2		(IRQ_IXP4XX_BASE + 4)
-
-static struct qmgr_regs __iomem *qmgr_regs = IXP4XX_QMGR_BASE_VIRT;
-static struct resource *mem_res;
+static struct qmgr_regs __iomem *qmgr_regs;
+static int qmgr_irq_1;
+static int qmgr_irq_2;
 static spinlock_t qmgr_lock;
 static u32 used_sram_bitmap[4]; /* 128 16-dword pages */
 static void (*irq_handlers[QUEUES])(void *pdev);
@@ -190,7 +186,7 @@ static irqreturn_t qmgr_irq2_a0(int irq, void *pdev)
 
 static irqreturn_t qmgr_irq(int irq, void *pdev)
 {
-	int i, half = (irq == IRQ_IXP4XX_QM1 ? 0 : 1);
+	int i, half = (irq == qmgr_irq_1 ? 0 : 1);
 	u32 req_bitmap = __raw_readl(&qmgr_regs->irqstat[half]);
 
 	if (!req_bitmap)
@@ -381,12 +377,25 @@ static int ixp4xx_qmgr_probe(struct platform_device *pdev)
 {
 	int i, err;
 	irq_handler_t handler1, handler2;
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	int irq1, irq2;
 
-	mem_res = request_mem_region(IXP4XX_QMGR_BASE_PHYS,
-				     IXP4XX_QMGR_REGION_SIZE,
-				     "IXP4xx Queue Manager");
-	if (mem_res == NULL)
-		return -EBUSY;
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+	qmgr_regs = devm_ioremap_resource(dev, res);
+	if (!qmgr_regs)
+		return -ENOMEM;
+
+	irq1 = platform_get_irq(pdev, 0);
+	if (irq1 <= 0)
+		return irq1 ? irq1 : -EINVAL;
+	qmgr_irq_1 = irq1;
+	irq2 = platform_get_irq(pdev, 1);
+	if (irq2 <= 0)
+		return irq2 ? irq2 : -EINVAL;
+	qmgr_irq_2 = irq2;
 
 	/* reset qmgr registers */
 	for (i = 0; i < 4; i++) {
@@ -411,43 +420,33 @@ static int ixp4xx_qmgr_probe(struct platform_device *pdev)
 	} else
 		handler1 = handler2 = qmgr_irq;
 
-	err = request_irq(IRQ_IXP4XX_QM1, handler1, 0, "IXP4xx Queue Manager",
-			  NULL);
+	err = devm_request_irq(dev, irq1, handler1, 0, "IXP4xx Queue Manager",
+			       NULL);
 	if (err) {
-		printk(KERN_ERR "qmgr: failed to request IRQ%i (%i)\n",
-		       IRQ_IXP4XX_QM1, err);
-		goto error_irq;
+		dev_err(dev, "failed to request IRQ%i (%i)\n",
+			irq1, err);
+		return err;
 	}
 
-	err = request_irq(IRQ_IXP4XX_QM2, handler2, 0, "IXP4xx Queue Manager",
-			  NULL);
+	err = devm_request_irq(dev, irq2, handler2, 0, "IXP4xx Queue Manager",
+			       NULL);
 	if (err) {
-		printk(KERN_ERR "qmgr: failed to request IRQ%i (%i)\n",
-		       IRQ_IXP4XX_QM2, err);
-		goto error_irq2;
+		dev_err(dev, "failed to request IRQ%i (%i)\n",
+			irq2, err);
+		return err;
 	}
 
 	used_sram_bitmap[0] = 0xF; /* 4 first pages reserved for config */
 	spin_lock_init(&qmgr_lock);
 
-	printk(KERN_INFO "IXP4xx Queue Manager initialized.\n");
+	dev_info(dev, "IXP4xx Queue Manager initialized.\n");
 	return 0;
-
-error_irq2:
-	free_irq(IRQ_IXP4XX_QM1, NULL);
-error_irq:
-	release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
-	return err;
 }
 
 static int ixp4xx_qmgr_remove(struct platform_device *pdev)
 {
-	free_irq(IRQ_IXP4XX_QM1, NULL);
-	free_irq(IRQ_IXP4XX_QM2, NULL);
-	synchronize_irq(IRQ_IXP4XX_QM1);
-	synchronize_irq(IRQ_IXP4XX_QM2);
-	release_mem_region(IXP4XX_QMGR_BASE_PHYS, IXP4XX_QMGR_REGION_SIZE);
-
+	synchronize_irq(qmgr_irq_1);
+	synchronize_irq(qmgr_irq_2);
 	return 0;
 }
 
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 26/30 v2] soc: ixp4xx: Add DT bindings for IXP4xx NPE
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (24 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 25/30 v2] soc: ixp4xx: qmgr: Pass resources Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 21:48   ` Rob Herring
  2019-02-21 15:44 ` [PATCH 27/30 v2] soc: ixp4xx: npe: Add DT probe code Linus Walleij
                   ` (4 subsequent siblings)
  30 siblings, 1 reply; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa; +Cc: devicetree, Linus Walleij

This adds DT bindings for the Intel IXP4xx Network Processing
Engine (NPE). These are three firmware-executing units found in
the IXP4xx SoC. These bindings use YAML.

Cc: devicetree@vger.kernel.org
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 ...ntel,ixp4xx-network-processing-engine.yaml | 44 +++++++++++++++++++
 1 file changed, 44 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/firmware/intel,ixp4xx-network-processing-engine.yaml

diff --git a/Documentation/devicetree/bindings/firmware/intel,ixp4xx-network-processing-engine.yaml b/Documentation/devicetree/bindings/firmware/intel,ixp4xx-network-processing-engine.yaml
new file mode 100644
index 000000000000..8cb136c376fb
--- /dev/null
+++ b/Documentation/devicetree/bindings/firmware/intel,ixp4xx-network-processing-engine.yaml
@@ -0,0 +1,44 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2019 Linaro Ltd.
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/firmware/intel-ixp4xx-network-processing-engine.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Intel IXP4xx Network Processing Engine
+
+maintainers:
+  - Linus Walleij <linus.walleij@linaro.org>
+
+description: |
+  On the IXP4xx SoCs, the Network Processing Engine (NPE) is a small
+  processor that can load a firmware to perform offloading of networking
+  and crypto tasks. It also manages the MDIO bus to the ethernet PHYs
+  on the IXP4xx platform. All IXP4xx platforms have three NPEs at
+  consecutive memory locations. They are all included in the same
+  device node since they are not independent of each other.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: intel,ixp4xx-network-processing-engine
+
+  reg:
+    minItems: 3
+    maxItems: 3
+    items:
+      - description: NPE0 register range
+      - description: NPE1 register range
+      - description: NPE2 register range
+
+required:
+  - compatible
+  - reg
+
+examples:
+  - |
+    npe@c8006000 {
+         compatible = "intel,ixp4xx-network-processing-engine";
+         reg = <0xc8006000 0x1000>, <0xc8007000 0x1000>, <0xc8008000 0x1000>;
+    };
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 27/30 v2] soc: ixp4xx: npe: Add DT probe code
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (25 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 26/30 v2] soc: ixp4xx: Add DT bindings for IXP4xx NPE Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 15:44 ` [PATCH 28/30 v2] soc: ixp4xx: qmgr: Add DT bindings for IXP4xx qmgr Linus Walleij
                   ` (3 subsequent siblings)
  30 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa; +Cc: Linus Walleij

This makes the NPE driver able to probe from the device tree.
It only needs to get three memory resources and the plaform
device provide these, so all is pretty simple.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/soc/ixp4xx/ixp4xx-npe.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/soc/ixp4xx/ixp4xx-npe.c b/drivers/soc/ixp4xx/ixp4xx-npe.c
index d2dd916816d4..15979d4376ab 100644
--- a/drivers/soc/ixp4xx/ixp4xx-npe.c
+++ b/drivers/soc/ixp4xx/ixp4xx-npe.c
@@ -729,9 +729,17 @@ static int ixp4xx_npe_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct of_device_id ixp4xx_npe_of_match[] = {
+	{
+		.compatible = "intel,ixp4xx-network-processing-engine",
+        },
+	{},
+};
+
 static struct platform_driver ixp4xx_npe_driver = {
 	.driver = {
 		.name           = "ixp4xx-npe",
+		.of_match_table = of_match_ptr(ixp4xx_npe_of_match),
 	},
 	.probe = ixp4xx_npe_probe,
 	.remove = ixp4xx_npe_remove,
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 28/30 v2] soc: ixp4xx: qmgr: Add DT bindings for IXP4xx qmgr
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (26 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 27/30 v2] soc: ixp4xx: npe: Add DT probe code Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 22:00   ` Rob Herring
  2019-02-21 15:44 ` [PATCH 29/30 v2] soc: ixp4xx: qmgr: Add DT probe code Linus Walleij
                   ` (2 subsequent siblings)
  30 siblings, 1 reply; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa; +Cc: devicetree, Linus Walleij

This adds device tree bindings for the Intel IXP4xx AHB
Queue Manager.

Cc: devicetree@vger.kernel.org
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 .../misc/intel,ixp4xx-queue-manager.yaml      | 57 +++++++++++++++++++
 1 file changed, 57 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/misc/intel,ixp4xx-queue-manager.yaml

diff --git a/Documentation/devicetree/bindings/misc/intel,ixp4xx-queue-manager.yaml b/Documentation/devicetree/bindings/misc/intel,ixp4xx-queue-manager.yaml
new file mode 100644
index 000000000000..c324860bede5
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/intel,ixp4xx-queue-manager.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2019 Linaro Ltd.
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/misc/intel-ixp4xx-ahb-queue-manager.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Intel IXP4xx AHB Queue Manager
+
+maintainers:
+  - Linus Walleij <linus.walleij@linaro.org>
+
+description: |
+  The IXP4xx AHB Queue Manager maintains queues as circular buffers in
+  an 8KB embedded SRAM along with hardware pointers. It is used by both
+  the XScale processor and the NPEs (Network Processing Units) in the
+  IXP4xx for accelerating queues, especially for networking. Clients pick
+  queues from the queue manager with foo-queue = <&qmgr N> where the
+  &qmgr is a phandle to the queue manager and N is the queue resource
+  number. The queue resources available and their specific purpose
+  on a certain IXP4xx system will vary.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - const: intel,ixp4xx-ahb-queue-manager
+
+  reg:
+    items:
+      - description: Queue Manager MMIO range
+
+  interrupts:
+    minItems: 2
+    maxItems: 2
+    items:
+      - description: Interrupt for queues 0-31
+      - description: Interrupt for queues 32-63
+
+  '#queue-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    qmgr: queue-manager@60000000 {
+         compatible = "intel,ixp4xx-ahb-queue-manager";
+         reg = <0x60000000 0x4000>;
+         interrupts = <3 IRQ_TYPE_LEVEL_HIGH>, <4 IRQ_TYPE_LEVEL_HIGH>;
+         #queue-cells = <1>;
+    };
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 29/30 v2] soc: ixp4xx: qmgr: Add DT probe code
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (27 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 28/30 v2] soc: ixp4xx: qmgr: Add DT bindings for IXP4xx qmgr Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-02-21 15:44 ` [PATCH 30/30 v2] ARM: dts: Add queue manager and NPE to the IXP4xx DTSI Linus Walleij
  2019-03-18  7:16 ` [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Krzysztof Hałasa
  30 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa; +Cc: Linus Walleij

This makes the queue manager driver able to probe from the device
tree. It only needs to get a memory resource and two interrupts
and the platform device provides these as resources, so all is
pretty simple.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/soc/ixp4xx/ixp4xx-qmgr.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/soc/ixp4xx/ixp4xx-qmgr.c b/drivers/soc/ixp4xx/ixp4xx-qmgr.c
index 64572f2d6ff0..13a8a13c9b01 100644
--- a/drivers/soc/ixp4xx/ixp4xx-qmgr.c
+++ b/drivers/soc/ixp4xx/ixp4xx-qmgr.c
@@ -450,9 +450,17 @@ static int ixp4xx_qmgr_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct of_device_id ixp4xx_qmgr_of_match[] = {
+	{
+		.compatible = "intel,ixp4xx-ahb-queue-manager",
+        },
+	{},
+};
+
 static struct platform_driver ixp4xx_qmgr_driver = {
 	.driver = {
 		.name           = "ixp4xx-qmgr",
+		.of_match_table = of_match_ptr(ixp4xx_qmgr_of_match),
 	},
 	.probe = ixp4xx_qmgr_probe,
 	.remove = ixp4xx_qmgr_remove,
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 30/30 v2] ARM: dts: Add queue manager and NPE to the IXP4xx DTSI
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (28 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 29/30 v2] soc: ixp4xx: qmgr: Add DT probe code Linus Walleij
@ 2019-02-21 15:44 ` Linus Walleij
  2019-03-18  7:16 ` [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Krzysztof Hałasa
  30 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-21 15:44 UTC (permalink / raw)
  To: linux-arm-kernel, Imre Kaloz, Krzysztof Halasa; +Cc: Linus Walleij

The AHB queue manager and Network Processing Engines are
present on all IXP4xx SoCs, so we add them to the overarching
device tree include.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/boot/dts/intel-ixp4xx.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm/boot/dts/intel-ixp4xx.dtsi b/arch/arm/boot/dts/intel-ixp4xx.dtsi
index 9edd49509af8..96a5a02f7ba9 100644
--- a/arch/arm/boot/dts/intel-ixp4xx.dtsi
+++ b/arch/arm/boot/dts/intel-ixp4xx.dtsi
@@ -14,6 +14,13 @@
 		compatible = "simple-bus";
 		interrupt-parent = <&intcon>;
 
+		qmgr: queue-manager@60000000 {
+			compatible = "intel,ixp4xx-ahb-queue-manager";
+			reg = <0x60000000 0x4000>;
+			#queue-cells = <1>;
+			interrupts = <3 IRQ_TYPE_LEVEL_HIGH>, <4 IRQ_TYPE_LEVEL_HIGH>;
+		};
+
 		uart0: serial@c8000000 {
 			compatible = "intel,xscale-uart";
 			reg = <0xc8000000 0x1000>;
@@ -54,5 +61,10 @@
 			reg = <0xc8005000 0x100>;
 			interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
 		};
+
+		npe@c8006000 {
+			compatible = "intel,ixp4xx-network-processing-engine";
+			reg = <0xc8006000 0x1000>, <0xc8007000 0x1000>, <0xc8008000 0x1000>;
+		};
 	};
 };
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 07/30 v2] clocksource/drivers/ixp4xx: Add driver
  2019-02-21 15:44 ` [PATCH 07/30 v2] clocksource/drivers/ixp4xx: Add driver Linus Walleij
@ 2019-02-21 20:54   ` Daniel Lezcano
  2019-03-03  9:35     ` Linus Walleij
  0 siblings, 1 reply; 45+ messages in thread
From: Daniel Lezcano @ 2019-02-21 20:54 UTC (permalink / raw)
  To: Linus Walleij, linux-arm-kernel, Imre Kaloz, Krzysztof Halasa
  Cc: Thomas Gleixner

On 21/02/2019 16:44, Linus Walleij wrote:
> This adds a new slightly rewritten timer driver for the
> Intel IXP4xx clocksource, clockevent and delay timer.
> 
> Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> Clocksource/timer maintainers: I am requesting an ACK for
> this once you're happy with the driver, as I intend to
> merge all of this IXP4xx rework through ARM SoC.
> ---

Hi Linus,

a couple of questions:

 - why __raw_write|read ?

 - can you consider using the timer_of API ?

>  MAINTAINERS                                |   2 +
>  drivers/clocksource/Kconfig                |   7 +
>  drivers/clocksource/Makefile               |   1 +
>  drivers/clocksource/timer-ixp4xx.c         | 249 +++++++++++++++++++++
>  include/linux/platform_data/timer-ixp4xx.h |  11 +
>  5 files changed, 270 insertions(+)
>  create mode 100644 drivers/clocksource/timer-ixp4xx.c
>  create mode 100644 include/linux/platform_data/timer-ixp4xx.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 6c161bd82238..a2fb67b75026 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1651,9 +1651,11 @@ M:	Krzysztof Halasa <khalasa@piap.pl>
>  L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
>  S:	Maintained
>  F:	arch/arm/mach-ixp4xx/
> +F:	drivers/clocksource/timer-ixp4xx.c
>  F:	drivers/gpio/gpio-ixp4xx.c
>  F:	drivers/irqchip/irq-ixp4xx.c
>  F:	include/linux/irqchip/irq-ixp4xx.h
> +F:	include/linux/platform_data/timer-ixp4xx.h
>  
>  ARM/INTEL RESEARCH IMOTE/STARGATE 2 MACHINE SUPPORT
>  M:	Jonathan Cameron <jic23@cam.ac.uk>
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index a9e26f6a81a1..d290d6c6576d 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -69,6 +69,13 @@ config FTTMR010_TIMER
>  	  Enables support for the Faraday Technology timer block
>  	  FTTMR010.
>  
> +config IXP4XX_TIMER
> +	bool "Intel XScale IXP4xx timer driver" if COMPILE_TEST
> +	depends on HAS_IOMEM
> +	select CLKSRC_MMIO
> +	help
> +	  Enables support for the Intel XScale IXP4xx SoC timer.
> +
>  config ROCKCHIP_TIMER
>  	bool "Rockchip timer driver" if COMPILE_TEST
>  	depends on ARM || ARM64
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index cdd210ff89ea..18158257ebb3 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -20,6 +20,7 @@ obj-$(CONFIG_OMAP_DM_TIMER)	+= timer-ti-dm.o
>  obj-$(CONFIG_DW_APB_TIMER)	+= dw_apb_timer.o
>  obj-$(CONFIG_DW_APB_TIMER_OF)	+= dw_apb_timer_of.o
>  obj-$(CONFIG_FTTMR010_TIMER)	+= timer-fttmr010.o
> +obj-$(CONFIG_IXP4XX_TIMER)	+= timer-ixp4xx.o
>  obj-$(CONFIG_ROCKCHIP_TIMER)      += timer-rockchip.o
>  obj-$(CONFIG_CLKSRC_NOMADIK_MTU)	+= nomadik-mtu.o
>  obj-$(CONFIG_CLKSRC_DBX500_PRCMU)	+= clksrc-dbx500-prcmu.o
> diff --git a/drivers/clocksource/timer-ixp4xx.c b/drivers/clocksource/timer-ixp4xx.c
> new file mode 100644
> index 000000000000..fa78f80792db
> --- /dev/null
> +++ b/drivers/clocksource/timer-ixp4xx.c
> @@ -0,0 +1,249 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * IXP4 timer driver
> + * Copyright (C) 2019 Linus Walleij <linus.walleij@linaro.org>
> + *
> + * Based on arch/arm/mach-ixp4xx/common.c
> + * Copyright 2002 (C) Intel Corporation
> + * Copyright 2003-2004 (C) MontaVista, Software, Inc.
> + * Copyright (C) Deepak Saxena <dsaxena@plexity.net>
> + */
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/clockchips.h>
> +#include <linux/clocksource.h>
> +#include <linux/sched_clock.h>
> +#include <linux/slab.h>
> +#include <linux/bitops.h>
> +#include <linux/delay.h>
> +/* Goes away with OF conversion */
> +#include <linux/platform_data/timer-ixp4xx.h>
> +
> +/*
> + * Constants to make it easy to access Timer Control/Status registers
> + */
> +#define IXP4XX_OSTS_OFFSET	0x00  /* Continuous Timestamp */
> +#define IXP4XX_OST1_OFFSET	0x04  /* Timer 1 Timestamp */
> +#define IXP4XX_OSRT1_OFFSET	0x08  /* Timer 1 Reload */
> +#define IXP4XX_OST2_OFFSET	0x0C  /* Timer 2 Timestamp */
> +#define IXP4XX_OSRT2_OFFSET	0x10  /* Timer 2 Reload */
> +#define IXP4XX_OSWT_OFFSET	0x14  /* Watchdog Timer */
> +#define IXP4XX_OSWE_OFFSET	0x18  /* Watchdog Enable */
> +#define IXP4XX_OSWK_OFFSET	0x1C  /* Watchdog Key */
> +#define IXP4XX_OSST_OFFSET	0x20  /* Timer Status */
> +
> +/*
> + * Timer register values and bit definitions
> + */
> +#define IXP4XX_OST_ENABLE		0x00000001
> +#define IXP4XX_OST_ONE_SHOT		0x00000002
> +/* Low order bits of reload value ignored */
> +#define IXP4XX_OST_RELOAD_MASK		0x00000003
> +#define IXP4XX_OST_DISABLED		0x00000000
> +#define IXP4XX_OSST_TIMER_1_PEND	0x00000001
> +#define IXP4XX_OSST_TIMER_2_PEND	0x00000002
> +#define IXP4XX_OSST_TIMER_TS_PEND	0x00000004
> +#define IXP4XX_OSST_TIMER_WDOG_PEND	0x00000008
> +#define IXP4XX_OSST_TIMER_WARM_RESET	0x00000010
> +
> +#define	IXP4XX_WDT_KEY			0x0000482E
> +#define	IXP4XX_WDT_RESET_ENABLE		0x00000001
> +#define	IXP4XX_WDT_IRQ_ENABLE		0x00000002
> +#define	IXP4XX_WDT_COUNT_ENABLE		0x00000004
> +
> +struct ixp4xx_timer {
> +	void __iomem *base;
> +	unsigned int tick_rate;
> +	u32 latch;
> +	struct clock_event_device clkevt;
> +#ifdef CONFIG_ARM
> +	struct delay_timer delay_timer;
> +#endif
> +};
> +
> +/*
> + * A local singleton used by sched_clock and delay timer reads, which are
> + * fast and stateless
> + */
> +static struct ixp4xx_timer *local_ixp4xx_timer;
> +
> +static inline struct ixp4xx_timer *
> +to_ixp4xx_timer(struct clock_event_device *evt)
> +{
> +	return container_of(evt, struct ixp4xx_timer, clkevt);
> +}
> +
> +static u64 notrace ixp4xx_read_sched_clock(void)
> +{
> +	return __raw_readl(local_ixp4xx_timer->base + IXP4XX_OSTS_OFFSET);
> +}
> +
> +static u64 ixp4xx_clocksource_read(struct clocksource *c)
> +{
> +	return __raw_readl(local_ixp4xx_timer->base + IXP4XX_OSTS_OFFSET);
> +}
> +
> +static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id)
> +{
> +	struct ixp4xx_timer *tmr = dev_id;
> +	struct clock_event_device *evt = &tmr->clkevt;
> +
> +	/* Clear Pending Interrupt */
> +	__raw_writel(IXP4XX_OSST_TIMER_1_PEND,
> +		     tmr->base + IXP4XX_OSST_OFFSET);
> +
> +	evt->event_handler(evt);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int ixp4xx_set_next_event(unsigned long cycles,
> +				 struct clock_event_device *evt)
> +{
> +	struct ixp4xx_timer *tmr = to_ixp4xx_timer(evt);
> +	u32 val;
> +
> +	val = __raw_readl(tmr->base + IXP4XX_OSRT1_OFFSET);
> +	/* Keep enable/oneshot bits */
> +	val &= IXP4XX_OST_RELOAD_MASK;
> +	__raw_writel((cycles & ~IXP4XX_OST_RELOAD_MASK) | val,
> +		     tmr->base + IXP4XX_OSRT1_OFFSET);
> +
> +	return 0;
> +}
> +
> +static int ixp4xx_shutdown(struct clock_event_device *evt)
> +{
> +	struct ixp4xx_timer *tmr = to_ixp4xx_timer(evt);
> +	u32 val;
> +
> +	val = __raw_readl(tmr->base + IXP4XX_OSRT1_OFFSET);
> +	val &= ~IXP4XX_OST_ENABLE;
> +	__raw_writel(val, tmr->base + IXP4XX_OSRT1_OFFSET);
> +
> +	return 0;
> +}
> +
> +static int ixp4xx_set_oneshot(struct clock_event_device *evt)
> +{
> +	struct ixp4xx_timer *tmr = to_ixp4xx_timer(evt);
> +
> +	__raw_writel(IXP4XX_OST_ENABLE | IXP4XX_OST_ONE_SHOT,
> +		     tmr->base + IXP4XX_OSRT1_OFFSET);
> +
> +	return 0;
> +}
> +
> +static int ixp4xx_set_periodic(struct clock_event_device *evt)
> +{
> +	struct ixp4xx_timer *tmr = to_ixp4xx_timer(evt);
> +	u32 val;
> +
> +	val = tmr->latch & ~IXP4XX_OST_RELOAD_MASK;
> +	val |= IXP4XX_OST_ENABLE;
> +	__raw_writel(val, tmr->base + IXP4XX_OSRT1_OFFSET);
> +
> +	return 0;
> +}
> +
> +static int ixp4xx_resume(struct clock_event_device *evt)
> +{
> +	struct ixp4xx_timer *tmr = to_ixp4xx_timer(evt);
> +	u32 val;
> +
> +	val = __raw_readl(tmr->base + IXP4XX_OSRT1_OFFSET);
> +	val |= IXP4XX_OST_ENABLE;
> +	__raw_writel(val, tmr->base + IXP4XX_OSRT1_OFFSET);
> +
> +	return 0;
> +}
> +
> +/*
> + * IXP4xx timer tick
> + * We use OS timer1 on the CPU for the timer tick and the timestamp
> + * counter as a source of real clock ticks to account for missed jiffies.
> + */
> +static __init int ixp4xx_timer_register(void __iomem *base,
> +					int timer_irq,
> +					unsigned int timer_freq)
> +{
> +	struct ixp4xx_timer *tmr;
> +	int ret;
> +
> +	tmr = kzalloc(sizeof(*tmr), GFP_KERNEL);
> +	if (!tmr)
> +		return -ENOMEM;
> +	tmr->base = base;
> +	tmr->tick_rate = timer_freq;
> +
> +	/*
> +	 * The timer register doesn't allow to specify the two least
> +	 * significant bits of the timeout value and assumes them being zero.
> +	 * So make sure the latch is the best value with the two least
> +	 * significant bits unset.
> +	 */
> +	tmr->latch = DIV_ROUND_CLOSEST(timer_freq,
> +				       (IXP4XX_OST_RELOAD_MASK + 1) * HZ)
> +		* (IXP4XX_OST_RELOAD_MASK + 1);
> +
> +	local_ixp4xx_timer = tmr;
> +
> +	/* Reset/disable counter */
> +	__raw_writel(0, tmr->base + IXP4XX_OSRT1_OFFSET);
> +
> +	/* Clear any pending interrupt on timer 1 */
> +	__raw_writel(IXP4XX_OSST_TIMER_1_PEND,
> +		     tmr->base + IXP4XX_OSST_OFFSET);
> +
> +	/* Reset time-stamp counter */
> +	__raw_writel(0, tmr->base + IXP4XX_OSTS_OFFSET);
> +
> +	clocksource_mmio_init(NULL, "OSTS", timer_freq, 200, 32,
> +			      ixp4xx_clocksource_read);
> +
> +	tmr->clkevt.name = "ixp4xx timer1";
> +	tmr->clkevt.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
> +	tmr->clkevt.rating = 200;
> +	tmr->clkevt.set_state_shutdown = ixp4xx_shutdown;
> +	tmr->clkevt.set_state_periodic = ixp4xx_set_periodic;
> +	tmr->clkevt.set_state_oneshot = ixp4xx_set_oneshot;
> +	tmr->clkevt.tick_resume = ixp4xx_resume;
> +	tmr->clkevt.set_next_event = ixp4xx_set_next_event;
> +	tmr->clkevt.cpumask = cpumask_of(0);
> +	tmr->clkevt.irq = timer_irq;
> +	ret = request_irq(timer_irq, ixp4xx_timer_interrupt,
> +			  IRQF_TIMER, "IXP4XX-TIMER1", tmr);
> +	if (ret) {
> +		pr_crit("no timer IRQ\n");
> +		return -ENODEV;
> +	}
> +	clockevents_config_and_register(&tmr->clkevt, timer_freq,
> +					0xf, 0xfffffffe);
> +
> +#ifdef CONFIG_ARM
> +	sched_clock_register(ixp4xx_read_sched_clock, 32, timer_freq);
> +#endif
> +
> +	return 0;
> +}
> +
> +/**
> + * ixp4xx_timer_setup() - Timer setup function to be called from boardfiles
> + * @timerbase: physical base of timer block
> + * @timer_irq: Linux IRQ number for the timer
> + * @timer_freq: Fixed frequency of the timer
> + */
> +void __init ixp4xx_timer_setup(resource_size_t timerbase,
> +			       int timer_irq,
> +			       unsigned int timer_freq)
> +{
> +	void __iomem *base;
> +
> +	base = ioremap(timerbase, 0x100);
> +	if (!base) {
> +		pr_crit("IXP4xx: can't remap timer\n");
> +		return;
> +	}
> +	ixp4xx_timer_register(base, timer_irq, timer_freq);
> +}
> +EXPORT_SYMBOL_GPL(ixp4xx_timer_setup);
> diff --git a/include/linux/platform_data/timer-ixp4xx.h b/include/linux/platform_data/timer-ixp4xx.h
> new file mode 100644
> index 000000000000..ee92ae7edaed
> --- /dev/null
> +++ b/include/linux/platform_data/timer-ixp4xx.h
> @@ -0,0 +1,11 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __TIMER_IXP4XX_H
> +#define __TIMER_IXP4XX_H
> +
> +#include <linux/ioport.h>
> +
> +void __init ixp4xx_timer_setup(resource_size_t timerbase,
> +			       int timer_irq,
> +			       unsigned int timer_freq);
> +
> +#endif
> 


-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 09/30 v2] irqchip: ixp4xx: Add DT bindings
  2019-02-21 15:44 ` [PATCH 09/30 v2] irqchip: ixp4xx: Add DT bindings Linus Walleij
@ 2019-02-21 21:39   ` Rob Herring
  0 siblings, 0 replies; 45+ messages in thread
From: Rob Herring @ 2019-02-21 21:39 UTC (permalink / raw)
  To: Linus Walleij
  Cc: devicetree, Jason Cooper, Marc Zyngier, Krzysztof Halasa,
	Thomas Gleixner, Imre Kaloz,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE

On Thu, Feb 21, 2019 at 9:45 AM Linus Walleij <linus.walleij@linaro.org> wrote:
>
> This adds device tree bindings for the IXP4xx interrupt
> controller. It's a standard 2-cell controller.
>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Jason Cooper <jason@lakedaemon.net>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> ChangeLog v1->v2:
> - Converted to use JSON yaml schema, why not.
> - Not keeping Rob's ACK because I think he wants to take
>   a second look.
> ---
>  .../intel,ixp4xx-interrupt.yaml               | 57 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  2 files changed, 58 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml
>
> diff --git a/Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml b/Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml
> new file mode 100644
> index 000000000000..f32c08f270d6
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interrupt-controller/intel,ixp4xx-interrupt.yaml
> @@ -0,0 +1,57 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +# Copyright 2018 Linaro Ltd.
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/interrupt/intel-ixp4xx-interrupt.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: Intel IXP4xx XScale Networking Processors Interrupt Controller
> +
> +maintainers:
> +  - Linus Walleij <linus.walleij@linaro.org>
> +
> +description: |
> +  This interrupt controller is found in the Intel IXP4xx processors.
> +  Some processors have 32 interrupts, some have up to 64 interrupts.
> +  The exact number of interrupts is determined from the compatible
> +  string.
> +
> +  The distinct IXP4xx families with different interrupt controller
> +  variations are IXP42x, IXP43x, IXP45x and IXP46x. Those four
> +  families were the only ones to reach the developer and consumer
> +  market.
> +
> +properties:
> +  compatible:
> +    oneOf:

You can drop oneOf since there is only 1.

> +      - items:
> +        - enum:
> +          - intel,ixp42x-interrupt
> +          - intel,ixp43x-interrupt
> +          - intel,ixp45x-interrupt
> +          - intel,ixp46x-interrupt
> +
> +  reg:
> +    description: The register bank for the interrupt controller.

No need to define what reg is here. Just 'maxItems: 1' is sufficient.

> +
> +  interrupt-controller: true
> +
> +  '#interrupt-cells':
> +    const: 2
> +    description: The number of cells to define the interrupts.
> +      with two cells specified in interrupt-controller/interrupts.txt

I'd drop description here, but I prefer things terse. I guess this
does define the format of the cells.

With the other changes,

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

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 11/30 v2] clocksource/drivers/ixp4xx: Add DT bindings
  2019-02-21 15:44 ` [PATCH 11/30 v2] clocksource/drivers/ixp4xx: Add DT bindings Linus Walleij
@ 2019-02-21 21:40   ` Rob Herring
  0 siblings, 0 replies; 45+ messages in thread
From: Rob Herring @ 2019-02-21 21:40 UTC (permalink / raw)
  To: Linus Walleij
  Cc: devicetree, Daniel Lezcano, Krzysztof Halasa, Thomas Gleixner,
	Imre Kaloz,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE

On Thu, Feb 21, 2019 at 9:45 AM Linus Walleij <linus.walleij@linaro.org> wrote:
>
> This adds device tree bindings for the Intel IXP4xx
> timers.
>
> Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> ChangeLog v1->v2:
> - Switch to JSON YAML schema, why not.
> - Not collecting any review tags as this changed a bit.
> ---
>  .../bindings/timer/intel,ixp4xx-timer.yaml    | 42 +++++++++++++++++++
>  MAINTAINERS                                   |  1 +
>  2 files changed, 43 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/timer/intel,ixp4xx-timer.yaml

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

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 26/30 v2] soc: ixp4xx: Add DT bindings for IXP4xx NPE
  2019-02-21 15:44 ` [PATCH 26/30 v2] soc: ixp4xx: Add DT bindings for IXP4xx NPE Linus Walleij
@ 2019-02-21 21:48   ` Rob Herring
  2019-02-22 10:37     ` Linus Walleij
  0 siblings, 1 reply; 45+ messages in thread
From: Rob Herring @ 2019-02-21 21:48 UTC (permalink / raw)
  To: Linus Walleij
  Cc: devicetree, Imre Kaloz, Krzysztof Halasa,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE

On Thu, Feb 21, 2019 at 9:46 AM Linus Walleij <linus.walleij@linaro.org> wrote:
>
> This adds DT bindings for the Intel IXP4xx Network Processing
> Engine (NPE). These are three firmware-executing units found in
> the IXP4xx SoC. These bindings use YAML.
>
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  ...ntel,ixp4xx-network-processing-engine.yaml | 44 +++++++++++++++++++
>  1 file changed, 44 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/firmware/intel,ixp4xx-network-processing-engine.yaml
>
> diff --git a/Documentation/devicetree/bindings/firmware/intel,ixp4xx-network-processing-engine.yaml b/Documentation/devicetree/bindings/firmware/intel,ixp4xx-network-processing-engine.yaml
> new file mode 100644
> index 000000000000..8cb136c376fb
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/firmware/intel,ixp4xx-network-processing-engine.yaml
> @@ -0,0 +1,44 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +# Copyright 2019 Linaro Ltd.
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/firmware/intel-ixp4xx-network-processing-engine.yaml#"

firmware? firmware/ is for things like psci, optee, etc. I'm not sure
this fits as it has some sort of h/w interface. Wouldn't networking be
a better fit?

> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: Intel IXP4xx Network Processing Engine
> +
> +maintainers:
> +  - Linus Walleij <linus.walleij@linaro.org>
> +
> +description: |
> +  On the IXP4xx SoCs, the Network Processing Engine (NPE) is a small
> +  processor that can load a firmware to perform offloading of networking
> +  and crypto tasks. It also manages the MDIO bus to the ethernet PHYs
> +  on the IXP4xx platform. All IXP4xx platforms have three NPEs at
> +  consecutive memory locations. They are all included in the same
> +  device node since they are not independent of each other.
> +
> +properties:
> +  compatible:
> +    oneOf:

oneOf can be dropped.

> +      - items:
> +          - const: intel,ixp4xx-network-processing-engine
> +
> +  reg:
> +    minItems: 3
> +    maxItems: 3

These 2 lines can be dropped. If not specified, they are automatically
added based on how many 'items'.

> +    items:
> +      - description: NPE0 register range
> +      - description: NPE1 register range
> +      - description: NPE2 register range
> +
> +required:
> +  - compatible
> +  - reg
> +
> +examples:
> +  - |
> +    npe@c8006000 {
> +         compatible = "intel,ixp4xx-network-processing-engine";
> +         reg = <0xc8006000 0x1000>, <0xc8007000 0x1000>, <0xc8008000 0x1000>;
> +    };
> --
> 2.20.1
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 28/30 v2] soc: ixp4xx: qmgr: Add DT bindings for IXP4xx qmgr
  2019-02-21 15:44 ` [PATCH 28/30 v2] soc: ixp4xx: qmgr: Add DT bindings for IXP4xx qmgr Linus Walleij
@ 2019-02-21 22:00   ` Rob Herring
  0 siblings, 0 replies; 45+ messages in thread
From: Rob Herring @ 2019-02-21 22:00 UTC (permalink / raw)
  To: Linus Walleij
  Cc: devicetree, Imre Kaloz, Krzysztof Halasa,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE

On Thu, Feb 21, 2019 at 9:46 AM Linus Walleij <linus.walleij@linaro.org> wrote:
>
> This adds device tree bindings for the Intel IXP4xx AHB
> Queue Manager.
>
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
>  .../misc/intel,ixp4xx-queue-manager.yaml      | 57 +++++++++++++++++++
>  1 file changed, 57 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/misc/intel,ixp4xx-queue-manager.yaml
>
> diff --git a/Documentation/devicetree/bindings/misc/intel,ixp4xx-queue-manager.yaml b/Documentation/devicetree/bindings/misc/intel,ixp4xx-queue-manager.yaml
> new file mode 100644
> index 000000000000..c324860bede5
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/misc/intel,ixp4xx-queue-manager.yaml
> @@ -0,0 +1,57 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +# Copyright 2019 Linaro Ltd.
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/misc/intel-ixp4xx-ahb-queue-manager.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: Intel IXP4xx AHB Queue Manager
> +
> +maintainers:
> +  - Linus Walleij <linus.walleij@linaro.org>
> +
> +description: |
> +  The IXP4xx AHB Queue Manager maintains queues as circular buffers in
> +  an 8KB embedded SRAM along with hardware pointers. It is used by both
> +  the XScale processor and the NPEs (Network Processing Units) in the
> +  IXP4xx for accelerating queues, especially for networking. Clients pick
> +  queues from the queue manager with foo-queue = <&qmgr N> where the
> +  &qmgr is a phandle to the queue manager and N is the queue resource
> +  number. The queue resources available and their specific purpose
> +  on a certain IXP4xx system will vary.
> +
> +properties:
> +  compatible:
> +    oneOf:

oneOf can be dropped.

> +      - items:
> +          - const: intel,ixp4xx-ahb-queue-manager
> +
> +  reg:
> +    items:
> +      - description: Queue Manager MMIO range

Just do 'maxItems: 1'.

Then again, maybe consistency is better. If there's only 1 register
range, there's not much point in describing it and I don't want a
bunch of free-form copy-n-paste of descriptions. It's only if there's
more than one that we need to define what each one is. In any case, I
should get a meta-schema in place to enforce something. And this could
easily be scripted to change the format how we end up wanting it to
look like.

> +
> +  interrupts:
> +    minItems: 2
> +    maxItems: 2

Can drop these 2.

> +    items:
> +      - description: Interrupt for queues 0-31
> +      - description: Interrupt for queues 32-63
> +
> +  '#queue-cells':
> +    const: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - interrupts

#queue-cells not required?

> +
> +examples:
> +  - |
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +
> +    qmgr: queue-manager@60000000 {
> +         compatible = "intel,ixp4xx-ahb-queue-manager";
> +         reg = <0x60000000 0x4000>;
> +         interrupts = <3 IRQ_TYPE_LEVEL_HIGH>, <4 IRQ_TYPE_LEVEL_HIGH>;
> +         #queue-cells = <1>;
> +    };
> --
> 2.20.1
>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 08/30 v2] ARM: ixp4xx: Switch to use new timer driver
  2019-02-21 15:44 ` [PATCH 08/30 v2] ARM: ixp4xx: Switch to use new timer driver Linus Walleij
@ 2019-02-22  8:38   ` Daniel Lezcano
  0 siblings, 0 replies; 45+ messages in thread
From: Daniel Lezcano @ 2019-02-22  8:38 UTC (permalink / raw)
  To: Linus Walleij, linux-arm-kernel, Imre Kaloz, Krzysztof Halasa
  Cc: Thomas Gleixner

On 21/02/2019 16:44, Linus Walleij wrote:
> This augments the IXP4xx to select and use the new
> timer driver in drivers/clocksource and removes the old
> code in the machine.
> 
> Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> Clocksource/timer maintainers: here you see how I activate
> this new driver. Intended to be merged through ARM SoC.
> ---

Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>



>  arch/arm/Kconfig              |   2 +-
>  arch/arm/mach-ixp4xx/common.c | 153 +---------------------------------
>  2 files changed, 5 insertions(+), 150 deletions(-)
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index f6345594cef0..9f70d7e032d6 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -427,7 +427,6 @@ config ARCH_IXP4XX
>  	depends on MMU
>  	select ARCH_HAS_DMA_SET_COHERENT_MASK
>  	select ARCH_SUPPORTS_BIG_ENDIAN
> -	select CLKSRC_MMIO
>  	select CPU_XSCALE
>  	select DMABOUNCE if PCI
>  	select GENERIC_CLOCKEVENTS
> @@ -436,6 +435,7 @@ config ARCH_IXP4XX
>  	select GPIOLIB
>  	select HAVE_PCI
>  	select IXP4XX_IRQ
> +	select IXP4XX_TIMER
>  	select NEED_MACH_IO_H
>  	select USB_EHCI_BIG_ENDIAN_DESC
>  	select USB_EHCI_BIG_ENDIAN_MMIO
> diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
> index 71683dfc48f9..fc4c9b21ca96 100644
> --- a/arch/arm/mach-ixp4xx/common.c
> +++ b/arch/arm/mach-ixp4xx/common.c
> @@ -22,9 +22,6 @@
>  #include <linux/serial_core.h>
>  #include <linux/interrupt.h>
>  #include <linux/bitops.h>
> -#include <linux/time.h>
> -#include <linux/clocksource.h>
> -#include <linux/clockchips.h>
>  #include <linux/io.h>
>  #include <linux/export.h>
>  #include <linux/cpu.h>
> @@ -32,6 +29,7 @@
>  #include <linux/sched_clock.h>
>  #include <linux/bitops.h>
>  #include <linux/irqchip/irq-ixp4xx.h>
> +#include <linux/platform_data/timer-ixp4xx.h>
>  #include <mach/udc.h>
>  #include <mach/hardware.h>
>  #include <mach/io.h>
> @@ -49,19 +47,6 @@
>  
>  #define IXP4XX_TIMER_FREQ 66666000
>  
> -/*
> - * The timer register doesn't allow to specify the two least significant bits of
> - * the timeout value and assumes them being zero. So make sure IXP4XX_LATCH is
> - * the best value with the two least significant bits unset.
> - */
> -#define IXP4XX_LATCH DIV_ROUND_CLOSEST(IXP4XX_TIMER_FREQ, \
> -				       (IXP4XX_OST_RELOAD_MASK + 1) * HZ) * \
> -			(IXP4XX_OST_RELOAD_MASK + 1)
> -
> -static void __init ixp4xx_clocksource_init(void);
> -static void __init ixp4xx_clockevent_init(void);
> -static struct clock_event_device clockevent_ixp4xx;
> -
>  /*************************************************************************
>   * IXP4xx chipset I/O mapping
>   *************************************************************************/
> @@ -106,37 +91,11 @@ void __init ixp4xx_init_irq(void)
>  			(cpu_is_ixp46x() || cpu_is_ixp43x()));
>  }
>  
> -/*************************************************************************
> - * IXP4xx timer tick
> - * We use OS timer1 on the CPU for the timer tick and the timestamp 
> - * counter as a source of real clock ticks to account for missed jiffies.
> - *************************************************************************/
> -
> -static irqreturn_t ixp4xx_timer_interrupt(int irq, void *dev_id)
> -{
> -	struct clock_event_device *evt = dev_id;
> -
> -	/* Clear Pending Interrupt by writing '1' to it */
> -	*IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
> -
> -	evt->event_handler(evt);
> -
> -	return IRQ_HANDLED;
> -}
> -
>  void __init ixp4xx_timer_init(void)
>  {
> -	/* Reset/disable counter */
> -	*IXP4XX_OSRT1 = 0;
> -
> -	/* Clear Pending Interrupt by writing '1' to it */
> -	*IXP4XX_OSST = IXP4XX_OSST_TIMER_1_PEND;
> -
> -	/* Reset time-stamp counter */
> -	*IXP4XX_OSTS = 0;
> -
> -	ixp4xx_clocksource_init();
> -	ixp4xx_clockevent_init();
> +	return ixp4xx_timer_setup(IXP4XX_TIMER_BASE_PHYS,
> +				  IRQ_IXP4XX_TIMER1,
> +				  IXP4XX_TIMER_FREQ);
>  }
>  
>  static struct pxa2xx_udc_mach_info ixp4xx_udc_info;
> @@ -251,112 +210,8 @@ void __init ixp4xx_sys_init(void)
>  			ixp4xx_exp_bus_size >> 20);
>  }
>  
> -/*
> - * sched_clock()
> - */
> -static u64 notrace ixp4xx_read_sched_clock(void)
> -{
> -	return *IXP4XX_OSTS;
> -}
> -
> -/*
> - * clocksource
> - */
> -
> -static u64 ixp4xx_clocksource_read(struct clocksource *c)
> -{
> -	return *IXP4XX_OSTS;
> -}
> -
>  unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ;
>  EXPORT_SYMBOL(ixp4xx_timer_freq);
> -static void __init ixp4xx_clocksource_init(void)
> -{
> -	sched_clock_register(ixp4xx_read_sched_clock, 32, ixp4xx_timer_freq);
> -
> -	clocksource_mmio_init(NULL, "OSTS", ixp4xx_timer_freq, 200, 32,
> -			ixp4xx_clocksource_read);
> -}
> -
> -/*
> - * clockevents
> - */
> -static int ixp4xx_set_next_event(unsigned long evt,
> -				 struct clock_event_device *unused)
> -{
> -	unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK;
> -
> -	*IXP4XX_OSRT1 = (evt & ~IXP4XX_OST_RELOAD_MASK) | opts;
> -
> -	return 0;
> -}
> -
> -static int ixp4xx_shutdown(struct clock_event_device *evt)
> -{
> -	unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK;
> -	unsigned long osrt = *IXP4XX_OSRT1 & ~IXP4XX_OST_RELOAD_MASK;
> -
> -	opts &= ~IXP4XX_OST_ENABLE;
> -	*IXP4XX_OSRT1 = osrt | opts;
> -	return 0;
> -}
> -
> -static int ixp4xx_set_oneshot(struct clock_event_device *evt)
> -{
> -	unsigned long opts = IXP4XX_OST_ENABLE | IXP4XX_OST_ONE_SHOT;
> -	unsigned long osrt = 0;
> -
> -	/* period set by 'set next_event' */
> -	*IXP4XX_OSRT1 = osrt | opts;
> -	return 0;
> -}
> -
> -static int ixp4xx_set_periodic(struct clock_event_device *evt)
> -{
> -	unsigned long opts = IXP4XX_OST_ENABLE;
> -	unsigned long osrt = IXP4XX_LATCH & ~IXP4XX_OST_RELOAD_MASK;
> -
> -	*IXP4XX_OSRT1 = osrt | opts;
> -	return 0;
> -}
> -
> -static int ixp4xx_resume(struct clock_event_device *evt)
> -{
> -	unsigned long opts = *IXP4XX_OSRT1 & IXP4XX_OST_RELOAD_MASK;
> -	unsigned long osrt = *IXP4XX_OSRT1 & ~IXP4XX_OST_RELOAD_MASK;
> -
> -	opts |= IXP4XX_OST_ENABLE;
> -	*IXP4XX_OSRT1 = osrt | opts;
> -	return 0;
> -}
> -
> -static struct clock_event_device clockevent_ixp4xx = {
> -	.name			= "ixp4xx timer1",
> -	.features		= CLOCK_EVT_FEAT_PERIODIC |
> -				  CLOCK_EVT_FEAT_ONESHOT,
> -	.rating			= 200,
> -	.set_state_shutdown	= ixp4xx_shutdown,
> -	.set_state_periodic	= ixp4xx_set_periodic,
> -	.set_state_oneshot	= ixp4xx_set_oneshot,
> -	.tick_resume		= ixp4xx_resume,
> -	.set_next_event		= ixp4xx_set_next_event,
> -};
> -
> -static void __init ixp4xx_clockevent_init(void)
> -{
> -	int ret;
> -
> -	clockevent_ixp4xx.cpumask = cpumask_of(0);
> -	clockevent_ixp4xx.irq = IRQ_IXP4XX_TIMER1;
> -	ret = request_irq(IRQ_IXP4XX_TIMER1, ixp4xx_timer_interrupt,
> -			  IRQF_TIMER, "IXP4XX-TIMER1", &clockevent_ixp4xx);
> -	if (ret) {
> -		pr_crit("no timer IRQ\n");
> -		return;
> -	}
> -	clockevents_config_and_register(&clockevent_ixp4xx, IXP4XX_TIMER_FREQ,
> -					0xf, 0xfffffffe);
> -}
>  
>  void ixp4xx_restart(enum reboot_mode mode, const char *cmd)
>  {
> 


-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 04/30 v2] irqchip: Add driver for IXP4xx
  2019-02-21 15:44 ` [PATCH 04/30 v2] irqchip: Add driver for IXP4xx Linus Walleij
@ 2019-02-22  9:51   ` Marc Zyngier
  0 siblings, 0 replies; 45+ messages in thread
From: Marc Zyngier @ 2019-02-22  9:51 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Thomas Gleixner, Imre Kaloz, Krzysztof Halasa, Jason Cooper,
	linux-arm-kernel

On Thu, 21 Feb 2019 16:44:32 +0100
Linus Walleij <linus.walleij@linaro.org> wrote:

> The IXP4xx (arch/arm/mach-ixp4xx) is an old Intel XScale
> platform that has very wide deployment and use.
> 
> As part of modernizing the platform, we need to implement a
> proper irqchip in the irqchip subsystem.
> 
> The IXP4xx irqchip is tightly jotted together with the GPIO
> controller, and whereas in the past we would deal with this
> complex logic by adding necessarily different code, we can
> nowadays modernize it using a hierarchical irqchip.
> 
> The actual IXP4 irqchip is a simple active low level IRQ
> controller, whereas the GPIO functionality resides in a
> different memory area and adds edge trigger support for
> the interrupts.
> 
> The interrupts from GPIO lines 0..12 are 1:1 mapped to
> a fixed set of hardware IRQs on this IRQchip, so we
> expect the child GPIO interrupt controller to go in and
> allocate descriptors for these interrupts.
> 
> For the other interrupts, as we do not yet have DT
> support for this platform, we create a linear irqdomain
> and then go in and allocate the IRQs that the legacy
> boards use. This code will be removed on the DT probe
> path when we add DT support to the platform.
> 
> We add some translation code for supporting DT
> translations for the fwnodes, but we leave most of that
> for later.
> 
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Jason Cooper <jason@lakedaemon.net>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

Thanks for doing this work!

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Without deviation from the norm, progress is not possible.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 06/30 v2] ARM: ixp4xx: Switch to use new IRQ+GPIO drivers
  2019-02-21 15:44 ` [PATCH 06/30 v2] ARM: ixp4xx: Switch to use new IRQ+GPIO drivers Linus Walleij
@ 2019-02-22  9:51   ` Marc Zyngier
  0 siblings, 0 replies; 45+ messages in thread
From: Marc Zyngier @ 2019-02-22  9:51 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Jason Cooper, Bartosz Golaszewski, Krzysztof Halasa,
	Thomas Gleixner, Imre Kaloz, linux-arm-kernel

On Thu, 21 Feb 2019 16:44:34 +0100
Linus Walleij <linus.walleij@linaro.org> wrote:

> This deletes the old irq+gpiochip combo from the IXP4xx
> machine and switches it over to use the new drivers merged
> in respective subsystem.
> 
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Jason Cooper <jason@lakedaemon.net>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Without deviation from the norm, progress is not possible.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 10/30 v2] irqchip: ixp4xx: Add OF initialization support
  2019-02-21 15:44 ` [PATCH 10/30 v2] irqchip: ixp4xx: Add OF initialization support Linus Walleij
@ 2019-02-22  9:53   ` Marc Zyngier
  0 siblings, 0 replies; 45+ messages in thread
From: Marc Zyngier @ 2019-02-22  9:53 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Thomas Gleixner, Imre Kaloz, Krzysztof Halasa, Jason Cooper,
	linux-arm-kernel

On Thu, 21 Feb 2019 16:44:38 +0100
Linus Walleij <linus.walleij@linaro.org> wrote:

> This adds support for probing and settin up the IXP4xx
> irqchip from device tree.
> 
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> Cc: Jason Cooper <jason@lakedaemon.net>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> ---
> irqchip maintainers: I am requesting an ACK for this once
> you're happy with the driver, as I intend to merge all of
> this IXP4xx rework through ARM SoC.
> ---
>  drivers/irqchip/irq-ixp4xx.c | 45 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 45 insertions(+)
> 
> diff --git a/drivers/irqchip/irq-ixp4xx.c b/drivers/irqchip/irq-ixp4xx.c
> index 89c80ce047a7..1ea7561fddb7 100644
> --- a/drivers/irqchip/irq-ixp4xx.c
> +++ b/drivers/irqchip/irq-ixp4xx.c
> @@ -15,6 +15,9 @@
>  #include <linux/irqchip.h>
>  #include <linux/irqchip/irq-ixp4xx.h>
>  #include <linux/irqdomain.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
>  #include <linux/platform_device.h>
>  #include <linux/cpu.h>
>  
> @@ -360,3 +363,45 @@ void __init ixp4xx_irq_init(resource_size_t irqbase,
>  	}
>  }
>  EXPORT_SYMBOL_GPL(ixp4xx_irq_init);
> +
> +#ifdef CONFIG_OF
> +int __init ixp4xx_of_init_irq(struct device_node *np,
> +			      struct device_node *parent)
> +{
> +	struct ixp4xx_irq *ixi = &ixirq;
> +	void __iomem *base;
> +	struct fwnode_handle *fwnode;
> +	bool is_356;
> +	int ret;
> +
> +	base = of_iomap(np, 0);
> +	if (!base) {
> +		pr_crit("IXP4XX: could not ioremap interrupt controller\n");
> +		return -ENODEV;
> +	}
> +	fwnode = of_node_to_fwnode(np);
> +	if (!fwnode) {
> +		pr_crit("IXP4XX: no domain handle\n");
> +		return -ENODEV;
> +	}

For this to happen, np would have to be NULL. I don't think that's
possible at all, as you managed to get here. So I think you can safely
drop this check.

> +
> +	/* These chip variants have 64 interrupts */
> +	is_356 = of_device_is_compatible(np, "intel,ixp43x-interrupt") ||
> +		of_device_is_compatible(np, "intel,ixp45x-interrupt") ||
> +		of_device_is_compatible(np, "intel,ixp46x-interrupt");
> +
> +	ret = ixp4xx_irq_setup(ixi, base, fwnode, is_356);
> +	if (ret)
> +		pr_crit("IXP4XX: failed to set up irqchip\n");
> +
> +	return ret;
> +}
> +IRQCHIP_DECLARE(ixp42x, "intel,ixp42x-interrupt",
> +		ixp4xx_of_init_irq);
> +IRQCHIP_DECLARE(ixp43x, "intel,ixp43x-interrupt",
> +		ixp4xx_of_init_irq);
> +IRQCHIP_DECLARE(ixp45x, "intel,ixp45x-interrupt",
> +		ixp4xx_of_init_irq);
> +IRQCHIP_DECLARE(ixp46x, "intel,ixp46x-interrupt",
> +		ixp4xx_of_init_irq);
> +#endif


With the above fixed:

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Without deviation from the norm, progress is not possible.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 26/30 v2] soc: ixp4xx: Add DT bindings for IXP4xx NPE
  2019-02-21 21:48   ` Rob Herring
@ 2019-02-22 10:37     ` Linus Walleij
  0 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-02-22 10:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Imre Kaloz, Krzysztof Halasa,
	moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE

On Thu, Feb 21, 2019 at 10:48 PM Rob Herring <robh@kernel.org> wrote:

> > +$id: "http://devicetree.org/schemas/firmware/intel-ixp4xx-network-processing-engine.yaml#"
>
> firmware? firmware/ is for things like psci, optee, etc. I'm not sure
> this fits as it has some sort of h/w interface. Wouldn't networking be
> a better fit?

You would think so, but the NPE, despite being named something
with "network" and primarily intended for that is also used for e.g.
crypto acceleration which is generic and can as well be used for
disk encryption. Intel names it a "hardware multi-threaded
processor engine".

Each unit has quite elaborate microcode and is clearly containing
its own CPU somekindof, it clearly has a Harvard architecture.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 07/30 v2] clocksource/drivers/ixp4xx: Add driver
  2019-02-21 20:54   ` Daniel Lezcano
@ 2019-03-03  9:35     ` Linus Walleij
  0 siblings, 0 replies; 45+ messages in thread
From: Linus Walleij @ 2019-03-03  9:35 UTC (permalink / raw)
  To: Daniel Lezcano; +Cc: Thomas Gleixner, Imre Kaloz, Krzysztof Halasa, Linux ARM

On Thu, Feb 21, 2019 at 9:54 PM Daniel Lezcano
<daniel.lezcano@linaro.org> wrote:
>
> On 21/02/2019 16:44, Linus Walleij wrote:
> > This adds a new slightly rewritten timer driver for the
> > Intel IXP4xx clocksource, clockevent and delay timer.
> >
> > Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
> > ---
> > Clocksource/timer maintainers: I am requesting an ACK for
> > this once you're happy with the driver, as I intend to
> > merge all of this IXP4xx rework through ARM SoC.
> > ---
>
> Hi Linus,
>
> a couple of questions:
>
>  - why __raw_write|read ?

That is an excellent question! It was answered in another mail
about the irqchip driver:

https://marc.info/?l=linux-arm-kernel&m=154991876024540&w=2

Quoting myself:

---------
So, IIUC (Krzysztof can confirm) IXP4xx works like this that when the
CPU is brought up in LE mode, all bytes on the address bus are
swizzled so that the access can always use the CPU native
endianness.

Isn't it crazy :D

This means __raw_writel() will always do the right thing, because
that uses native endianness, and that is why it is used quite a lot
in IXP4xx drivers.

If you want full control you need to define local helpers for
everything that change behaviour at compile-time such as:

static void foo_writel(u32 val, __iomem void *addr)
{
#if defined(CONFIG_CPU_BIG_ENDIAN)
   iowrite32be(val, addr);
#else
    writel(val, addr);
#endif
}

Which will have the same effect as __raw_writel().

So that is why we use the (ugly) macro __raw_writel() a lot
in IXP4xx drivers.
---------

>  - can you consider using the timer_of API ?

Yes that is added in a later patch. We are transitioning a machine
from boardfile to DT and later on the non-DT path will be deleted.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support
  2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
                   ` (29 preceding siblings ...)
  2019-02-21 15:44 ` [PATCH 30/30 v2] ARM: dts: Add queue manager and NPE to the IXP4xx DTSI Linus Walleij
@ 2019-03-18  7:16 ` Krzysztof Hałasa
  2019-03-18 22:16   ` Linus Walleij
  30 siblings, 1 reply; 45+ messages in thread
From: Krzysztof Hałasa @ 2019-03-18  7:16 UTC (permalink / raw)
  To: Linus Walleij; +Cc: Imre Kaloz, linux-arm-kernel

Hi Linus,

given your recent work and apparent interest on IXP4xx, I wonder if
you would like to become the maintainer of Linux support for this arch.
I have stopped using IXP4xx years ago, and I can't dedicate much time
to it at the moment. I'm sure it would be much better with you as the
maintainer.

What do you think?
-- 
Krzysztof Halasa

Industrial Research Institute for Automation and Measurements PIAP
Al. Jerozolimskie 202, 02-486 Warsaw, Poland

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support
  2019-03-18  7:16 ` [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Krzysztof Hałasa
@ 2019-03-18 22:16   ` Linus Walleij
  2019-04-02 12:12     ` Krzysztof Hałasa
  0 siblings, 1 reply; 45+ messages in thread
From: Linus Walleij @ 2019-03-18 22:16 UTC (permalink / raw)
  To: Krzysztof Hałasa; +Cc: Imre Kaloz, Linux ARM

On Mon, Mar 18, 2019 at 8:16 AM Krzysztof Hałasa <khalasa@piap.pl> wrote:

> given your recent work and apparent interest on IXP4xx, I wonder if
> you would like to become the maintainer of Linux support for this arch.
> I have stopped using IXP4xx years ago, and I can't dedicate much time
> to it at the moment. I'm sure it would be much better with you as the
> maintainer.
>
> What do you think?

OK I will append a patch adding me as maintainer when I respin.
Then you can resign later if you think I do an OK job :D

I think Imre will back me up for the OpenWrt parts, they have
a bunch of boards they need to keep supporting, so the plan
is to build this out step by step.

Yours,
Linus Walleij

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support
  2019-03-18 22:16   ` Linus Walleij
@ 2019-04-02 12:12     ` Krzysztof Hałasa
  0 siblings, 0 replies; 45+ messages in thread
From: Krzysztof Hałasa @ 2019-04-02 12:12 UTC (permalink / raw)
  To: Linus Walleij; +Cc: Imre Kaloz, Linux ARM

Linus Walleij <linus.walleij@linaro.org> writes:

> OK I will append a patch adding me as maintainer when I respin.
> Then you can resign later if you think I do an OK job :D
>
> I think Imre will back me up for the OpenWrt parts, they have
> a bunch of boards they need to keep supporting, so the plan
> is to build this out step by step.

Very well. I'm sure you will do great.
-- 
Krzysztof Halasa

Industrial Research Institute for Automation and Measurements PIAP
Al. Jerozolimskie 202, 02-486 Warsaw, Poland

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, other threads:[~2019-04-02 12:12 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-21 15:44 [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Linus Walleij
2019-02-21 15:44 ` [PATCH 01/30 v2] ARM: ixp4xx: Convert to MULTI_IRQ_HANDLER Linus Walleij
2019-02-21 15:44 ` [PATCH 02/30 v2] ARM: ixp4xx: Pass IRQ resource to beeper Linus Walleij
2019-02-21 15:44 ` [PATCH 03/30 v2] ARM: ixp4xx: Convert to SPARSE_IRQ Linus Walleij
2019-02-21 15:44 ` [PATCH 04/30 v2] irqchip: Add driver for IXP4xx Linus Walleij
2019-02-22  9:51   ` Marc Zyngier
2019-02-21 15:44 ` [PATCH 05/30 v2] gpio: ixp4xx: Add driver for the IXP4xx GPIO Linus Walleij
2019-02-21 15:44 ` [PATCH 06/30 v2] ARM: ixp4xx: Switch to use new IRQ+GPIO drivers Linus Walleij
2019-02-22  9:51   ` Marc Zyngier
2019-02-21 15:44 ` [PATCH 07/30 v2] clocksource/drivers/ixp4xx: Add driver Linus Walleij
2019-02-21 20:54   ` Daniel Lezcano
2019-03-03  9:35     ` Linus Walleij
2019-02-21 15:44 ` [PATCH 08/30 v2] ARM: ixp4xx: Switch to use new timer driver Linus Walleij
2019-02-22  8:38   ` Daniel Lezcano
2019-02-21 15:44 ` [PATCH 09/30 v2] irqchip: ixp4xx: Add DT bindings Linus Walleij
2019-02-21 21:39   ` Rob Herring
2019-02-21 15:44 ` [PATCH 10/30 v2] irqchip: ixp4xx: Add OF initialization support Linus Walleij
2019-02-22  9:53   ` Marc Zyngier
2019-02-21 15:44 ` [PATCH 11/30 v2] clocksource/drivers/ixp4xx: Add DT bindings Linus Walleij
2019-02-21 21:40   ` Rob Herring
2019-02-21 15:44 ` [PATCH 12/30 v2] clocksource/drivers/ixp4xx: Add OF initialization support Linus Walleij
2019-02-21 15:44 ` [PATCH 13/30 v2] gpio: ixp4xx: Add DT bindings Linus Walleij
2019-02-21 15:44 ` [PATCH 14/30 v2] gpio: ixp4xx: Add OF probing support Linus Walleij
2019-02-21 15:44 ` [PATCH 15/30 v2] ARM: ixp4xx: Add DT bindings Linus Walleij
2019-02-21 15:44 ` [PATCH 16/30 v2] ARM: ixp4xx: Add device tree boot support Linus Walleij
2019-02-21 15:44 ` [PATCH 17/30 v2] ARM: dts: Add some initial IXP4xx device trees Linus Walleij
2019-02-21 15:44 ` [PATCH 18/30 v2] ARM: ixp4xx: Move NPE and QMGR to drivers/soc Linus Walleij
2019-02-21 15:44 ` [PATCH 19/30 v2] ARM: ixp4xx: Move IXP4xx QMGR and NPE headers Linus Walleij
2019-02-21 15:44 ` [PATCH 20/30 v2] ARM: ixp4xx: Turn the NPE into a platform device Linus Walleij
2019-02-21 15:44 ` [PATCH 21/30 v2] ARM: ixp4xx: Turn the QMGR " Linus Walleij
2019-02-21 15:44 ` [PATCH 22/30 v2] soc: ixp4xx: npe: Pass addresses as resources Linus Walleij
2019-02-21 15:44 ` [PATCH 23/30 v2] soc: ixp4xx: Uninline several functions Linus Walleij
2019-02-21 15:44 ` [PATCH 24/30 v2] soc: ixp4xx: Remove unused functions Linus Walleij
2019-02-21 15:44 ` [PATCH 25/30 v2] soc: ixp4xx: qmgr: Pass resources Linus Walleij
2019-02-21 15:44 ` [PATCH 26/30 v2] soc: ixp4xx: Add DT bindings for IXP4xx NPE Linus Walleij
2019-02-21 21:48   ` Rob Herring
2019-02-22 10:37     ` Linus Walleij
2019-02-21 15:44 ` [PATCH 27/30 v2] soc: ixp4xx: npe: Add DT probe code Linus Walleij
2019-02-21 15:44 ` [PATCH 28/30 v2] soc: ixp4xx: qmgr: Add DT bindings for IXP4xx qmgr Linus Walleij
2019-02-21 22:00   ` Rob Herring
2019-02-21 15:44 ` [PATCH 29/30 v2] soc: ixp4xx: qmgr: Add DT probe code Linus Walleij
2019-02-21 15:44 ` [PATCH 30/30 v2] ARM: dts: Add queue manager and NPE to the IXP4xx DTSI Linus Walleij
2019-03-18  7:16 ` [PATCH 00/30 v2] ARM: ixp4xx: Modernize and DT support Krzysztof Hałasa
2019-03-18 22:16   ` Linus Walleij
2019-04-02 12:12     ` Krzysztof Hałasa

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).