linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 2/5] ARM: sa1100: use sa11x0_sc_set_wake() in irq driver
  2015-01-15 10:09 [PATCH 1/5] ARM: sa1100: add platform functions to handle PWER settings Dmitry Eremin-Solenikov
@ 2015-01-15 10:09 ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 6+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-01-15 10:09 UTC (permalink / raw)
  To: linux-arm-kernel

Use new function controlling PWER register in IRQ driver.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 arch/arm/mach-sa1100/irq.c | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index 65aebfa..7a5aa56 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -40,19 +40,9 @@ static void sa1100_unmask_irq(struct irq_data *d)
 	ICMR |= BIT(d->hwirq);
 }
 
-/*
- * Apart form GPIOs, only the RTC alarm can be a wakeup event.
- */
 static int sa1100_set_wake(struct irq_data *d, unsigned int on)
 {
-	if (BIT(d->hwirq) == IC_RTCAlrm) {
-		if (on)
-			PWER |= PWER_RTC;
-		else
-			PWER &= ~PWER_RTC;
-		return 0;
-	}
-	return -EINVAL;
+	return sa11x0_sc_set_wake(d->hwirq, on);
 }
 
 static struct irq_chip sa1100_normal_chip = {
-- 
2.1.4

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

* [PATCH 1/5] ARM: sa1100: add platform functions to handle PWER settings
@ 2015-04-28  4:19 Dmitry Eremin-Solenikov
  2015-04-28  4:19 ` [PATCH 2/5] ARM: sa1100: use sa11x0_sc_set_wake() in irq driver Dmitry Eremin-Solenikov
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-28  4:19 UTC (permalink / raw)
  To: linux-arm-kernel

PWER settings logically belongs neither to GPIO nor to system IRQ code.
Add special functions to handle PWER (for GPIO and for system IRQs)
from platform code.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 arch/arm/mach-sa1100/generic.c | 24 ++++++++++++++++++++++++
 include/soc/sa1100/pwer.h      | 15 +++++++++++++++
 2 files changed, 39 insertions(+)
 create mode 100644 include/soc/sa1100/pwer.h

diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 40e0d86..c651f6e 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -23,6 +23,8 @@
 
 #include <video/sa1100fb.h>
 
+#include <soc/sa1100/pwer.h>
+
 #include <asm/div64.h>
 #include <asm/mach/map.h>
 #include <asm/mach/flash.h>
@@ -416,3 +418,25 @@ void sa1110_mb_enable(void)
 	local_irq_restore(flags);
 }
 
+int sa11x0_gpio_set_wake(unsigned int gpio, unsigned int on)
+{
+	if (on)
+		PWER |= BIT(gpio);
+	else
+		PWER &= ~BIT(gpio);
+
+	return 0;
+}
+
+int sa11x0_sc_set_wake(unsigned int irq, unsigned int on)
+{
+	if (BIT(irq) != IC_RTCAlrm)
+		return -EINVAL;
+
+	if (on)
+		PWER |= PWER_RTC;
+	else
+		PWER &= ~PWER_RTC;
+
+	return 0;
+}
diff --git a/include/soc/sa1100/pwer.h b/include/soc/sa1100/pwer.h
new file mode 100644
index 0000000..15a545b
--- /dev/null
+++ b/include/soc/sa1100/pwer.h
@@ -0,0 +1,15 @@
+#ifndef SOC_SA1100_PWER_H
+#define SOC_SA1100_PWER_H
+
+/*
+ * Copyright (C) 2015, Dmitry Eremin-Solenikov
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+int sa11x0_gpio_set_wake(unsigned int gpio, unsigned int on);
+int sa11x0_sc_set_wake(unsigned int irq, unsigned int on);
+
+#endif
-- 
2.1.4

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

* [PATCH 2/5] ARM: sa1100: use sa11x0_sc_set_wake() in irq driver
  2015-04-28  4:19 [PATCH 1/5] ARM: sa1100: add platform functions to handle PWER settings Dmitry Eremin-Solenikov
@ 2015-04-28  4:19 ` Dmitry Eremin-Solenikov
  2015-04-28  4:19 ` [PATCH 3/5] ARM: sa1100: use ioremapped memory to access SC registers Dmitry Eremin-Solenikov
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-28  4:19 UTC (permalink / raw)
  To: linux-arm-kernel

Use new function controlling PWER register in IRQ driver.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 arch/arm/mach-sa1100/irq.c | 14 +++-----------
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index 65aebfa..6afaa33 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -18,6 +18,8 @@
 #include <linux/ioport.h>
 #include <linux/syscore_ops.h>
 
+#include <soc/sa1100/pwer.h>
+
 #include <mach/hardware.h>
 #include <mach/irqs.h>
 #include <asm/mach/irq.h>
@@ -40,19 +42,9 @@ static void sa1100_unmask_irq(struct irq_data *d)
 	ICMR |= BIT(d->hwirq);
 }
 
-/*
- * Apart form GPIOs, only the RTC alarm can be a wakeup event.
- */
 static int sa1100_set_wake(struct irq_data *d, unsigned int on)
 {
-	if (BIT(d->hwirq) == IC_RTCAlrm) {
-		if (on)
-			PWER |= PWER_RTC;
-		else
-			PWER &= ~PWER_RTC;
-		return 0;
-	}
-	return -EINVAL;
+	return sa11x0_sc_set_wake(d->hwirq, on);
 }
 
 static struct irq_chip sa1100_normal_chip = {
-- 
2.1.4

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

* [PATCH 3/5] ARM: sa1100: use ioremapped memory to access SC registers
  2015-04-28  4:19 [PATCH 1/5] ARM: sa1100: add platform functions to handle PWER settings Dmitry Eremin-Solenikov
  2015-04-28  4:19 ` [PATCH 2/5] ARM: sa1100: use sa11x0_sc_set_wake() in irq driver Dmitry Eremin-Solenikov
@ 2015-04-28  4:19 ` Dmitry Eremin-Solenikov
  2015-04-28  4:19 ` [PATCH 4/5] ARM: sa1100: move irq driver to drivers/irqchip/ Dmitry Eremin-Solenikov
  2015-04-28  4:19 ` [PATCH 5/5] ARM: sa1100: properly split irqchip driver Dmitry Eremin-Solenikov
  3 siblings, 0 replies; 6+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-28  4:19 UTC (permalink / raw)
  To: linux-arm-kernel

Use ioremap() and readl/writel_relaxed() to access IRQ controller
registers.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 arch/arm/mach-sa1100/irq.c | 52 ++++++++++++++++++++++++++++++----------------
 1 file changed, 34 insertions(+), 18 deletions(-)

diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index 6afaa33..08f929e 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -20,13 +20,19 @@
 
 #include <soc/sa1100/pwer.h>
 
-#include <mach/hardware.h>
 #include <mach/irqs.h>
-#include <asm/mach/irq.h>
 #include <asm/exception.h>
 
 #include "generic.h"
 
+#define ICIP	0x00  /* IC IRQ Pending reg. */
+#define ICMR	0x04  /* IC Mask Reg.        */
+#define ICLR	0x08  /* IC Level Reg.       */
+#define ICCR	0x0C  /* IC Control Reg.     */
+#define ICFP	0x10  /* IC FIQ Pending reg. */
+#define ICPR	0x20  /* IC Pending Reg.     */
+
+static void __iomem *iobase;
 
 /*
  * We don't need to ACK IRQs on the SA1100 unless they're GPIOs
@@ -34,12 +40,20 @@
  */
 static void sa1100_mask_irq(struct irq_data *d)
 {
-	ICMR &= ~BIT(d->hwirq);
+	u32 reg;
+
+	reg = readl_relaxed(iobase + ICMR);
+	reg &= ~BIT(d->hwirq);
+	writel_relaxed(reg, iobase + ICMR);
 }
 
 static void sa1100_unmask_irq(struct irq_data *d)
 {
-	ICMR |= BIT(d->hwirq);
+	u32 reg;
+
+	reg = readl_relaxed(iobase + ICMR);
+	reg |= BIT(d->hwirq);
+	writel_relaxed(reg, iobase + ICMR);
 }
 
 static int sa1100_set_wake(struct irq_data *d, unsigned int on)
@@ -87,16 +101,14 @@ static int sa1100irq_suspend(void)
 	struct sa1100irq_state *st = &sa1100irq_state;
 
 	st->saved = 1;
-	st->icmr = ICMR;
-	st->iclr = ICLR;
-	st->iccr = ICCR;
+	st->icmr = readl_relaxed(iobase + ICMR);
+	st->iclr = readl_relaxed(iobase + ICLR);
+	st->iccr = readl_relaxed(iobase + ICCR);
 
 	/*
 	 * Disable all GPIO-based interrupts.
 	 */
-	ICMR &= ~(IC_GPIO11_27|IC_GPIO10|IC_GPIO9|IC_GPIO8|IC_GPIO7|
-		  IC_GPIO6|IC_GPIO5|IC_GPIO4|IC_GPIO3|IC_GPIO2|
-		  IC_GPIO1|IC_GPIO0);
+	writel_relaxed(st->icmr & 0xfffff000, iobase + ICMR);
 
 	return 0;
 }
@@ -106,10 +118,10 @@ static void sa1100irq_resume(void)
 	struct sa1100irq_state *st = &sa1100irq_state;
 
 	if (st->saved) {
-		ICCR = st->iccr;
-		ICLR = st->iclr;
+		writel_relaxed(st->iccr, iobase + ICCR);
+		writel_relaxed(st->iclr, iobase + ICLR);
 
-		ICMR = st->icmr;
+		writel_relaxed(st->icmr, iobase + ICMR);
 	}
 }
 
@@ -132,8 +144,8 @@ sa1100_handle_irq(struct pt_regs *regs)
 	uint32_t icip, icmr, mask;
 
 	do {
-		icip = (ICIP);
-		icmr = (ICMR);
+		icip = readl_relaxed(iobase + ICIP);
+		icmr = readl_relaxed(iobase + ICMR);
 		mask = icip & icmr;
 
 		if (mask == 0)
@@ -148,17 +160,21 @@ void __init sa1100_init_irq(void)
 {
 	request_resource(&iomem_resource, &irq_resource);
 
+	iobase = ioremap(irq_resource.start, SZ_64K);
+	if (WARN_ON(!iobase))
+		return;
+
 	/* disable all IRQs */
-	ICMR = 0;
+	writel_relaxed(0, iobase + ICMR);
 
 	/* all IRQs are IRQ, not FIQ */
-	ICLR = 0;
+	writel_relaxed(0, iobase + ICLR);
 
 	/*
 	 * Whatever the doc says, this has to be set for the wait-on-irq
 	 * instruction to work... on a SA1100 rev 9 at least.
 	 */
-	ICCR = 1;
+	writel_relaxed(1, iobase + ICCR);
 
 	sa1100_normal_irqdomain = irq_domain_add_simple(NULL,
 			32, IRQ_GPIO0_SC,
-- 
2.1.4

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

* [PATCH 4/5] ARM: sa1100: move irq driver to drivers/irqchip/
  2015-04-28  4:19 [PATCH 1/5] ARM: sa1100: add platform functions to handle PWER settings Dmitry Eremin-Solenikov
  2015-04-28  4:19 ` [PATCH 2/5] ARM: sa1100: use sa11x0_sc_set_wake() in irq driver Dmitry Eremin-Solenikov
  2015-04-28  4:19 ` [PATCH 3/5] ARM: sa1100: use ioremapped memory to access SC registers Dmitry Eremin-Solenikov
@ 2015-04-28  4:19 ` Dmitry Eremin-Solenikov
  2015-04-28  4:19 ` [PATCH 5/5] ARM: sa1100: properly split irqchip driver Dmitry Eremin-Solenikov
  3 siblings, 0 replies; 6+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-28  4:19 UTC (permalink / raw)
  To: linux-arm-kernel

Move current sa11x0 IRQ driver to the irqchip subsystem. The driver is
not yet modified to be a proper part of irqchip subsystem, it will be a
next step.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 arch/arm/mach-sa1100/Makefile |   2 +-
 arch/arm/mach-sa1100/irq.c    | 186 ------------------------------------------
 drivers/irqchip/Makefile      |   1 +
 drivers/irqchip/irq-sa11x0.c  | 186 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 188 insertions(+), 187 deletions(-)
 delete mode 100644 arch/arm/mach-sa1100/irq.c
 create mode 100644 drivers/irqchip/irq-sa11x0.c

diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile
index 61ff91e..ebc4d58 100644
--- a/arch/arm/mach-sa1100/Makefile
+++ b/arch/arm/mach-sa1100/Makefile
@@ -3,7 +3,7 @@
 #
 
 # Common support
-obj-y := clock.o generic.o irq.o #nmi-oopser.o
+obj-y := clock.o generic.o #nmi-oopser.o
 
 # Specific board support
 obj-$(CONFIG_SA1100_ASSABET)		+= assabet.o
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
deleted file mode 100644
index 08f929e..0000000
--- a/arch/arm/mach-sa1100/irq.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * linux/arch/arm/mach-sa1100/irq.c
- *
- * Copyright (C) 1999-2001 Nicolas Pitre
- *
- * Generic IRQ handling for the SA11x0, GPIO 11-27 IRQ demultiplexing.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/irqdomain.h>
-#include <linux/ioport.h>
-#include <linux/syscore_ops.h>
-
-#include <soc/sa1100/pwer.h>
-
-#include <mach/irqs.h>
-#include <asm/exception.h>
-
-#include "generic.h"
-
-#define ICIP	0x00  /* IC IRQ Pending reg. */
-#define ICMR	0x04  /* IC Mask Reg.        */
-#define ICLR	0x08  /* IC Level Reg.       */
-#define ICCR	0x0C  /* IC Control Reg.     */
-#define ICFP	0x10  /* IC FIQ Pending reg. */
-#define ICPR	0x20  /* IC Pending Reg.     */
-
-static void __iomem *iobase;
-
-/*
- * We don't need to ACK IRQs on the SA1100 unless they're GPIOs
- * this is for internal IRQs i.e. from IRQ LCD to RTCAlrm.
- */
-static void sa1100_mask_irq(struct irq_data *d)
-{
-	u32 reg;
-
-	reg = readl_relaxed(iobase + ICMR);
-	reg &= ~BIT(d->hwirq);
-	writel_relaxed(reg, iobase + ICMR);
-}
-
-static void sa1100_unmask_irq(struct irq_data *d)
-{
-	u32 reg;
-
-	reg = readl_relaxed(iobase + ICMR);
-	reg |= BIT(d->hwirq);
-	writel_relaxed(reg, iobase + ICMR);
-}
-
-static int sa1100_set_wake(struct irq_data *d, unsigned int on)
-{
-	return sa11x0_sc_set_wake(d->hwirq, on);
-}
-
-static struct irq_chip sa1100_normal_chip = {
-	.name		= "SC",
-	.irq_ack	= sa1100_mask_irq,
-	.irq_mask	= sa1100_mask_irq,
-	.irq_unmask	= sa1100_unmask_irq,
-	.irq_set_wake	= sa1100_set_wake,
-};
-
-static int sa1100_normal_irqdomain_map(struct irq_domain *d,
-		unsigned int irq, irq_hw_number_t hwirq)
-{
-	irq_set_chip_and_handler(irq, &sa1100_normal_chip,
-				 handle_level_irq);
-	set_irq_flags(irq, IRQF_VALID);
-
-	return 0;
-}
-
-static struct irq_domain_ops sa1100_normal_irqdomain_ops = {
-	.map = sa1100_normal_irqdomain_map,
-	.xlate = irq_domain_xlate_onetwocell,
-};
-
-static struct irq_domain *sa1100_normal_irqdomain;
-
-static struct resource irq_resource =
-	DEFINE_RES_MEM_NAMED(0x90050000, SZ_64K, "irqs");
-
-static struct sa1100irq_state {
-	unsigned int	saved;
-	unsigned int	icmr;
-	unsigned int	iclr;
-	unsigned int	iccr;
-} sa1100irq_state;
-
-static int sa1100irq_suspend(void)
-{
-	struct sa1100irq_state *st = &sa1100irq_state;
-
-	st->saved = 1;
-	st->icmr = readl_relaxed(iobase + ICMR);
-	st->iclr = readl_relaxed(iobase + ICLR);
-	st->iccr = readl_relaxed(iobase + ICCR);
-
-	/*
-	 * Disable all GPIO-based interrupts.
-	 */
-	writel_relaxed(st->icmr & 0xfffff000, iobase + ICMR);
-
-	return 0;
-}
-
-static void sa1100irq_resume(void)
-{
-	struct sa1100irq_state *st = &sa1100irq_state;
-
-	if (st->saved) {
-		writel_relaxed(st->iccr, iobase + ICCR);
-		writel_relaxed(st->iclr, iobase + ICLR);
-
-		writel_relaxed(st->icmr, iobase + ICMR);
-	}
-}
-
-static struct syscore_ops sa1100irq_syscore_ops = {
-	.suspend	= sa1100irq_suspend,
-	.resume		= sa1100irq_resume,
-};
-
-static int __init sa1100irq_init_devicefs(void)
-{
-	register_syscore_ops(&sa1100irq_syscore_ops);
-	return 0;
-}
-
-device_initcall(sa1100irq_init_devicefs);
-
-static asmlinkage void __exception_irq_entry
-sa1100_handle_irq(struct pt_regs *regs)
-{
-	uint32_t icip, icmr, mask;
-
-	do {
-		icip = readl_relaxed(iobase + ICIP);
-		icmr = readl_relaxed(iobase + ICMR);
-		mask = icip & icmr;
-
-		if (mask == 0)
-			break;
-
-		handle_domain_irq(sa1100_normal_irqdomain,
-				ffs(mask) - 1, regs);
-	} while (1);
-}
-
-void __init sa1100_init_irq(void)
-{
-	request_resource(&iomem_resource, &irq_resource);
-
-	iobase = ioremap(irq_resource.start, SZ_64K);
-	if (WARN_ON(!iobase))
-		return;
-
-	/* disable all IRQs */
-	writel_relaxed(0, iobase + ICMR);
-
-	/* all IRQs are IRQ, not FIQ */
-	writel_relaxed(0, iobase + ICLR);
-
-	/*
-	 * Whatever the doc says, this has to be set for the wait-on-irq
-	 * instruction to work... on a SA1100 rev 9 at least.
-	 */
-	writel_relaxed(1, iobase + ICCR);
-
-	sa1100_normal_irqdomain = irq_domain_add_simple(NULL,
-			32, IRQ_GPIO0_SC,
-			&sa1100_normal_irqdomain_ops, NULL);
-
-	set_handle_irq(sa1100_handle_irq);
-
-	sa1100_init_gpio();
-}
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index dda4927..49f372a 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -47,3 +47,4 @@ obj-$(CONFIG_KEYSTONE_IRQ)		+= irq-keystone.o
 obj-$(CONFIG_MIPS_GIC)			+= irq-mips-gic.o
 obj-$(CONFIG_ARCH_MEDIATEK)		+= irq-mtk-sysirq.o
 obj-$(CONFIG_ARCH_DIGICOLOR)		+= irq-digicolor.o
+obj-$(CONFIG_ARCH_SA1100)		+= irq-sa11x0.o
diff --git a/drivers/irqchip/irq-sa11x0.c b/drivers/irqchip/irq-sa11x0.c
new file mode 100644
index 0000000..a5e1a54
--- /dev/null
+++ b/drivers/irqchip/irq-sa11x0.c
@@ -0,0 +1,186 @@
+/*
+ * drivers/irqchip/irq-sa11x0.c
+ *
+ * Copyright (C) 1999-2001 Nicolas Pitre
+ *
+ * Generic IRQ handling for the SA11x0.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/ioport.h>
+#include <linux/syscore_ops.h>
+
+#include <soc/sa1100/pwer.h>
+
+#include <mach/irqs.h>
+#include <asm/exception.h>
+
+#include "../../arch/arm/mach-sa1100/generic.h"
+
+#define ICIP	0x00  /* IC IRQ Pending reg. */
+#define ICMR	0x04  /* IC Mask Reg.        */
+#define ICLR	0x08  /* IC Level Reg.       */
+#define ICCR	0x0C  /* IC Control Reg.     */
+#define ICFP	0x10  /* IC FIQ Pending reg. */
+#define ICPR	0x20  /* IC Pending Reg.     */
+
+static void __iomem *iobase;
+
+/*
+ * We don't need to ACK IRQs on the SA1100 unless they're GPIOs
+ * this is for internal IRQs i.e. from IRQ LCD to RTCAlrm.
+ */
+static void sa1100_mask_irq(struct irq_data *d)
+{
+	u32 reg;
+
+	reg = readl_relaxed(iobase + ICMR);
+	reg &= ~BIT(d->hwirq);
+	writel_relaxed(reg, iobase + ICMR);
+}
+
+static void sa1100_unmask_irq(struct irq_data *d)
+{
+	u32 reg;
+
+	reg = readl_relaxed(iobase + ICMR);
+	reg |= BIT(d->hwirq);
+	writel_relaxed(reg, iobase + ICMR);
+}
+
+static int sa1100_set_wake(struct irq_data *d, unsigned int on)
+{
+	return sa11x0_sc_set_wake(d->hwirq, on);
+}
+
+static struct irq_chip sa1100_normal_chip = {
+	.name		= "SC",
+	.irq_ack	= sa1100_mask_irq,
+	.irq_mask	= sa1100_mask_irq,
+	.irq_unmask	= sa1100_unmask_irq,
+	.irq_set_wake	= sa1100_set_wake,
+};
+
+static int sa1100_normal_irqdomain_map(struct irq_domain *d,
+		unsigned int irq, irq_hw_number_t hwirq)
+{
+	irq_set_chip_and_handler(irq, &sa1100_normal_chip,
+				 handle_level_irq);
+	set_irq_flags(irq, IRQF_VALID);
+
+	return 0;
+}
+
+static struct irq_domain_ops sa1100_normal_irqdomain_ops = {
+	.map = sa1100_normal_irqdomain_map,
+	.xlate = irq_domain_xlate_onetwocell,
+};
+
+static struct irq_domain *sa1100_normal_irqdomain;
+
+static struct resource irq_resource =
+	DEFINE_RES_MEM_NAMED(0x90050000, SZ_64K, "irqs");
+
+static struct sa1100irq_state {
+	unsigned int	saved;
+	unsigned int	icmr;
+	unsigned int	iclr;
+	unsigned int	iccr;
+} sa1100irq_state;
+
+static int sa1100irq_suspend(void)
+{
+	struct sa1100irq_state *st = &sa1100irq_state;
+
+	st->saved = 1;
+	st->icmr = readl_relaxed(iobase + ICMR);
+	st->iclr = readl_relaxed(iobase + ICLR);
+	st->iccr = readl_relaxed(iobase + ICCR);
+
+	/*
+	 * Disable all GPIO-based interrupts.
+	 */
+	writel_relaxed(st->icmr & 0xfffff000, iobase + ICMR);
+
+	return 0;
+}
+
+static void sa1100irq_resume(void)
+{
+	struct sa1100irq_state *st = &sa1100irq_state;
+
+	if (st->saved) {
+		writel_relaxed(st->iccr, iobase + ICCR);
+		writel_relaxed(st->iclr, iobase + ICLR);
+
+		writel_relaxed(st->icmr, iobase + ICMR);
+	}
+}
+
+static struct syscore_ops sa1100irq_syscore_ops = {
+	.suspend	= sa1100irq_suspend,
+	.resume		= sa1100irq_resume,
+};
+
+static int __init sa1100irq_init_devicefs(void)
+{
+	register_syscore_ops(&sa1100irq_syscore_ops);
+	return 0;
+}
+
+device_initcall(sa1100irq_init_devicefs);
+
+static asmlinkage void __exception_irq_entry
+sa1100_handle_irq(struct pt_regs *regs)
+{
+	uint32_t icip, icmr, mask;
+
+	do {
+		icip = readl_relaxed(iobase + ICIP);
+		icmr = readl_relaxed(iobase + ICMR);
+		mask = icip & icmr;
+
+		if (mask == 0)
+			break;
+
+		handle_domain_irq(sa1100_normal_irqdomain,
+				ffs(mask) - 1, regs);
+	} while (1);
+}
+
+void __init sa1100_init_irq(void)
+{
+	request_resource(&iomem_resource, &irq_resource);
+
+	iobase = ioremap(irq_resource.start, SZ_64K);
+	if (WARN_ON(!iobase))
+		return;
+
+	/* disable all IRQs */
+	writel_relaxed(0, iobase + ICMR);
+
+	/* all IRQs are IRQ, not FIQ */
+	writel_relaxed(0, iobase + ICLR);
+
+	/*
+	 * Whatever the doc says, this has to be set for the wait-on-irq
+	 * instruction to work... on a SA1100 rev 9 at least.
+	 */
+	writel_relaxed(1, iobase + ICCR);
+
+	sa1100_normal_irqdomain = irq_domain_add_simple(NULL,
+			32, IRQ_GPIO0_SC,
+			&sa1100_normal_irqdomain_ops, NULL);
+
+	set_handle_irq(sa1100_handle_irq);
+
+	sa1100_init_gpio();
+}
-- 
2.1.4

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

* [PATCH 5/5] ARM: sa1100: properly split irqchip driver
  2015-04-28  4:19 [PATCH 1/5] ARM: sa1100: add platform functions to handle PWER settings Dmitry Eremin-Solenikov
                   ` (2 preceding siblings ...)
  2015-04-28  4:19 ` [PATCH 4/5] ARM: sa1100: move irq driver to drivers/irqchip/ Dmitry Eremin-Solenikov
@ 2015-04-28  4:19 ` Dmitry Eremin-Solenikov
  3 siblings, 0 replies; 6+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-04-28  4:19 UTC (permalink / raw)
  To: linux-arm-kernel

Finally properly split the irq driver into generic init code and irqchip
driver.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 arch/arm/mach-sa1100/generic.c     | 13 +++++++++++++
 drivers/irqchip/irq-sa11x0.c       | 18 ++++--------------
 include/linux/irqchip/irq-sa11x0.h | 16 ++++++++++++++++
 3 files changed, 33 insertions(+), 14 deletions(-)
 create mode 100644 include/linux/irqchip/irq-sa11x0.h

diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index c651f6e..345e63f 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -20,6 +20,7 @@
 #include <linux/ioport.h>
 #include <linux/platform_device.h>
 #include <linux/reboot.h>
+#include <linux/irqchip/irq-sa11x0.h>
 
 #include <video/sa1100fb.h>
 
@@ -377,6 +378,18 @@ void __init sa1100_timer_init(void)
 	pxa_timer_nodt_init(IRQ_OST0, io_p2v(0x90000000), 3686400);
 }
 
+static struct resource irq_resource =
+	DEFINE_RES_MEM_NAMED(0x90050000, SZ_64K, "irqs");
+
+void __init sa1100_init_irq(void)
+{
+	request_resource(&iomem_resource, &irq_resource);
+
+	sa11x0_init_irq_nodt(IRQ_GPIO0_SC, irq_resource.start);
+
+	sa1100_init_gpio();
+}
+
 /*
  * Disable the memory bus request/grant signals on the SA1110 to
  * ensure that we don't receive spurious memory requests.  We set
diff --git a/drivers/irqchip/irq-sa11x0.c b/drivers/irqchip/irq-sa11x0.c
index a5e1a54..76b8c1d 100644
--- a/drivers/irqchip/irq-sa11x0.c
+++ b/drivers/irqchip/irq-sa11x0.c
@@ -15,16 +15,13 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
-#include <linux/ioport.h>
 #include <linux/syscore_ops.h>
+#include <linux/irqchip/irq-sa11x0.h>
 
 #include <soc/sa1100/pwer.h>
 
-#include <mach/irqs.h>
 #include <asm/exception.h>
 
-#include "../../arch/arm/mach-sa1100/generic.h"
-
 #define ICIP	0x00  /* IC IRQ Pending reg. */
 #define ICMR	0x04  /* IC Mask Reg.        */
 #define ICLR	0x08  /* IC Level Reg.       */
@@ -86,9 +83,6 @@ static struct irq_domain_ops sa1100_normal_irqdomain_ops = {
 
 static struct irq_domain *sa1100_normal_irqdomain;
 
-static struct resource irq_resource =
-	DEFINE_RES_MEM_NAMED(0x90050000, SZ_64K, "irqs");
-
 static struct sa1100irq_state {
 	unsigned int	saved;
 	unsigned int	icmr;
@@ -156,11 +150,9 @@ sa1100_handle_irq(struct pt_regs *regs)
 	} while (1);
 }
 
-void __init sa1100_init_irq(void)
+void __init sa11x0_init_irq_nodt(int irq_start, resource_size_t io_start)
 {
-	request_resource(&iomem_resource, &irq_resource);
-
-	iobase = ioremap(irq_resource.start, SZ_64K);
+	iobase = ioremap(io_start, SZ_64K);
 	if (WARN_ON(!iobase))
 		return;
 
@@ -177,10 +169,8 @@ void __init sa1100_init_irq(void)
 	writel_relaxed(1, iobase + ICCR);
 
 	sa1100_normal_irqdomain = irq_domain_add_simple(NULL,
-			32, IRQ_GPIO0_SC,
+			32, irq_start,
 			&sa1100_normal_irqdomain_ops, NULL);
 
 	set_handle_irq(sa1100_handle_irq);
-
-	sa1100_init_gpio();
 }
diff --git a/include/linux/irqchip/irq-sa11x0.h b/include/linux/irqchip/irq-sa11x0.h
new file mode 100644
index 0000000..2f66eca
--- /dev/null
+++ b/include/linux/irqchip/irq-sa11x0.h
@@ -0,0 +1,16 @@
+/*
+ * Generic IRQ handling for the SA11x0.
+ *
+ * Copyright (C) 1999-2001 Nicolas Pitre
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __INCLUDE_LINUX_IRQCHIP_IRQ_SA11x0_H
+#define __INCLUDE_LINUX_IRQCHIP_IRQ_SA11x0_H
+
+void __init sa11x0_init_irq_nodt(int irq_start, resource_size_t io_start);
+
+#endif
-- 
2.1.4

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

end of thread, other threads:[~2015-04-28  4:19 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-04-28  4:19 [PATCH 1/5] ARM: sa1100: add platform functions to handle PWER settings Dmitry Eremin-Solenikov
2015-04-28  4:19 ` [PATCH 2/5] ARM: sa1100: use sa11x0_sc_set_wake() in irq driver Dmitry Eremin-Solenikov
2015-04-28  4:19 ` [PATCH 3/5] ARM: sa1100: use ioremapped memory to access SC registers Dmitry Eremin-Solenikov
2015-04-28  4:19 ` [PATCH 4/5] ARM: sa1100: move irq driver to drivers/irqchip/ Dmitry Eremin-Solenikov
2015-04-28  4:19 ` [PATCH 5/5] ARM: sa1100: properly split irqchip driver Dmitry Eremin-Solenikov
  -- strict thread matches above, loose matches on Subject: below --
2015-01-15 10:09 [PATCH 1/5] ARM: sa1100: add platform functions to handle PWER settings Dmitry Eremin-Solenikov
2015-01-15 10:09 ` [PATCH 2/5] ARM: sa1100: use sa11x0_sc_set_wake() in irq driver Dmitry Eremin-Solenikov

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