* [PATCH 1/5] ARM: sa1100: add platform functions to handle PWER settings
@ 2015-01-15 10:09 Dmitry Eremin-Solenikov
2015-01-21 10:05 ` Linus Walleij
0 siblings, 1 reply; 8+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-01-15 10:09 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 | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 40e0d86..022e451 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -416,3 +416,24 @@ 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;
+}
--
2.1.4
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 1/5] ARM: sa1100: add platform functions to handle PWER settings
2015-01-15 10:09 [PATCH 1/5] ARM: sa1100: add platform functions to handle PWER settings Dmitry Eremin-Solenikov
@ 2015-01-21 10:05 ` Linus Walleij
2015-01-21 13:37 ` Dmitry Eremin-Solenikov
0 siblings, 1 reply; 8+ messages in thread
From: Linus Walleij @ 2015-01-21 10:05 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Jan 15, 2015 at 11:09 AM, Dmitry Eremin-Solenikov
<dbaryshkov@gmail.com> wrote:
> 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>
> diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
(...)
> +int sa11x0_gpio_set_wake(unsigned int gpio, unsigned int on)
(...)
> +int sa11x0_sc_set_wake(unsigned int irq, unsigned int on)
Why are these two functions not added to any .h file?
Did you miss to commit something or are there compile
warnings about this?
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/5] ARM: sa1100: add platform functions to handle PWER settings
2015-01-21 10:05 ` Linus Walleij
@ 2015-01-21 13:37 ` Dmitry Eremin-Solenikov
0 siblings, 0 replies; 8+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-01-21 13:37 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
2015-01-21 13:05 GMT+03:00 Linus Walleij <linus.walleij@linaro.org>:
>
> On Thu, Jan 15, 2015 at 11:09 AM, Dmitry Eremin-Solenikov
> <dbaryshkov@gmail.com> wrote:
>
> > 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>
>
> > diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
> (...)
> > +int sa11x0_gpio_set_wake(unsigned int gpio, unsigned int on)
> (...)
> > +int sa11x0_sc_set_wake(unsigned int irq, unsigned int on)
>
> Why are these two functions not added to any .h file?
>
> Did you miss to commit something or are there compile
> warnings about this?
I thought quite a while about adding them to any header. In the end I ended
adding them to the irqchip header file. PWER handling is (a bit) related to IRQ
handling. The only other user of those functions would be a gpio (or pinctrl
if it ends that way) driver.
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 8+ 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; 8+ 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] 8+ 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; 8+ 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] 8+ 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; 8+ 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] 8+ 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; 8+ 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] 8+ 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; 8+ 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] 8+ messages in thread
end of thread, other threads:[~2015-04-28 4:19 UTC | newest]
Thread overview: 8+ 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-21 10:05 ` Linus Walleij
2015-01-21 13:37 ` 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).