linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 3/5] ARM: sa1100: use ioremapped memory to access SC registers
  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
  2015-01-24 17:48   ` Thomas Gleixner
  0 siblings, 1 reply; 10+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-01-15 10:09 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 | 63 +++++++++++++++++++++++++++++++++-------------
 1 file changed, 45 insertions(+), 18 deletions(-)

diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index 7a5aa56..66464fd 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -18,13 +18,20 @@
 #include <linux/ioport.h>
 #include <linux/syscore_ops.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;
+static DEFINE_RAW_SPINLOCK(lock);
 
 /*
  * We don't need to ACK IRQs on the SA1100 unless they're GPIOs
@@ -32,12 +39,30 @@
  */
 static void sa1100_mask_irq(struct irq_data *d)
 {
-	ICMR &= ~BIT(d->hwirq);
+	u32 reg;
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&lock, flags);
+
+	reg = readl_relaxed(iobase + ICMR);
+	reg &= ~BIT(d->hwirq);
+	writel_relaxed(reg, iobase + ICMR);
+
+	raw_spin_unlock_irqrestore(&lock, flags);
 }
 
 static void sa1100_unmask_irq(struct irq_data *d)
 {
-	ICMR |= BIT(d->hwirq);
+	u32 reg;
+	unsigned long flags;
+
+	raw_spin_lock_irqsave(&lock, flags);
+
+	reg = readl_relaxed(iobase + ICMR);
+	reg |= BIT(d->hwirq);
+	writel_relaxed(reg, iobase + ICMR);
+
+	raw_spin_unlock_irqrestore(&lock, flags);
 }
 
 static int sa1100_set_wake(struct irq_data *d, unsigned int on)
@@ -85,16 +110,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;
 }
@@ -104,10 +127,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);
 	}
 }
 
@@ -130,8 +153,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)
@@ -146,17 +169,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] 10+ messages in thread

* [PATCH 3/5] ARM: sa1100: use ioremapped memory to access SC registers
  2015-01-15 10:09 ` [PATCH 3/5] ARM: sa1100: use ioremapped memory to access SC registers Dmitry Eremin-Solenikov
@ 2015-01-24 17:48   ` Thomas Gleixner
  2015-01-24 17:50     ` Dmitry Eremin-Solenikov
  0 siblings, 1 reply; 10+ messages in thread
From: Thomas Gleixner @ 2015-01-24 17:48 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, 15 Jan 2015, Dmitry Eremin-Solenikov wrote:
>  static void sa1100_mask_irq(struct irq_data *d)
>  {
> -	ICMR &= ~BIT(d->hwirq);
> +	u32 reg;
> +	unsigned long flags;
> +
> +	raw_spin_lock_irqsave(&lock, flags);

What's the exact point of that lock? And how is it related to the
$subject of the patch?

Thanks,

	tglx

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

* [PATCH 3/5] ARM: sa1100: use ioremapped memory to access SC registers
  2015-01-24 17:48   ` Thomas Gleixner
@ 2015-01-24 17:50     ` Dmitry Eremin-Solenikov
  2015-01-24 19:24       ` Thomas Gleixner
  0 siblings, 1 reply; 10+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-01-24 17:50 UTC (permalink / raw)
  To: linux-arm-kernel

2015-01-24 20:48 GMT+03:00 Thomas Gleixner <tglx@linutronix.de>:
> On Thu, 15 Jan 2015, Dmitry Eremin-Solenikov wrote:
>>  static void sa1100_mask_irq(struct irq_data *d)
>>  {
>> -     ICMR &= ~BIT(d->hwirq);
>> +     u32 reg;
>> +     unsigned long flags;
>> +
>> +     raw_spin_lock_irqsave(&lock, flags);
>
> What's the exact point of that lock? And how is it related to the
> $subject of the patch?

It is needed to protect ICMR register during RMW cycle, isn't it?
I might have missed locks around ack/mask/unmask calls from irq
core. If so, I can happily drop this spinlock.

-- 
With best wishes
Dmitry

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

* [PATCH 3/5] ARM: sa1100: use ioremapped memory to access SC registers
  2015-01-24 17:50     ` Dmitry Eremin-Solenikov
@ 2015-01-24 19:24       ` Thomas Gleixner
  2015-01-24 19:25         ` Dmitry Eremin-Solenikov
  0 siblings, 1 reply; 10+ messages in thread
From: Thomas Gleixner @ 2015-01-24 19:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, 24 Jan 2015, Dmitry Eremin-Solenikov wrote:

> 2015-01-24 20:48 GMT+03:00 Thomas Gleixner <tglx@linutronix.de>:
> > On Thu, 15 Jan 2015, Dmitry Eremin-Solenikov wrote:
> >>  static void sa1100_mask_irq(struct irq_data *d)
> >>  {
> >> -     ICMR &= ~BIT(d->hwirq);
> >> +     u32 reg;
> >> +     unsigned long flags;
> >> +
> >> +     raw_spin_lock_irqsave(&lock, flags);
> >
> > What's the exact point of that lock? And how is it related to the
> > $subject of the patch?
> 
> It is needed to protect ICMR register during RMW cycle, isn't it?

The original code has no protection for the RMW either.

And there is a simple reason for this. These functions are guaranteed
to be called with interrupts disabled and this is a uniprocessor
machine and it will never grow SMP support. So interrupts disabled is
serialization enough.

Thanks,

	tglx

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

* [PATCH 3/5] ARM: sa1100: use ioremapped memory to access SC registers
  2015-01-24 19:24       ` Thomas Gleixner
@ 2015-01-24 19:25         ` Dmitry Eremin-Solenikov
  0 siblings, 0 replies; 10+ messages in thread
From: Dmitry Eremin-Solenikov @ 2015-01-24 19:25 UTC (permalink / raw)
  To: linux-arm-kernel

2015-01-24 22:24 GMT+03:00 Thomas Gleixner <tglx@linutronix.de>:
> On Sat, 24 Jan 2015, Dmitry Eremin-Solenikov wrote:
>
>> 2015-01-24 20:48 GMT+03:00 Thomas Gleixner <tglx@linutronix.de>:
>> > On Thu, 15 Jan 2015, Dmitry Eremin-Solenikov wrote:
>> >>  static void sa1100_mask_irq(struct irq_data *d)
>> >>  {
>> >> -     ICMR &= ~BIT(d->hwirq);
>> >> +     u32 reg;
>> >> +     unsigned long flags;
>> >> +
>> >> +     raw_spin_lock_irqsave(&lock, flags);
>> >
>> > What's the exact point of that lock? And how is it related to the
>> > $subject of the patch?
>>
>> It is needed to protect ICMR register during RMW cycle, isn't it?
>
> The original code has no protection for the RMW either.
>
> And there is a simple reason for this. These functions are guaranteed
> to be called with interrupts disabled and this is a uniprocessor
> machine and it will never grow SMP support. So interrupts disabled is
> serialization enough.

OK, thanks for pointing. I'll update the patchset in a few days.

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 10+ 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; 10+ 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] 10+ 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; 10+ 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] 10+ 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; 10+ 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] 10+ 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; 10+ 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] 10+ 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; 10+ 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] 10+ messages in thread

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

Thread overview: 10+ 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 3/5] ARM: sa1100: use ioremapped memory to access SC registers Dmitry Eremin-Solenikov
2015-01-24 17:48   ` Thomas Gleixner
2015-01-24 17:50     ` Dmitry Eremin-Solenikov
2015-01-24 19:24       ` Thomas Gleixner
2015-01-24 19:25         ` 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).