* [PATCH 1/6] ARM: sa1100: switch to MULTI_IRQ_HANDLER
2014-11-15 11:53 [PATCH 0/6] ARM: sa1100: Use MULTI_IRQ_HANDLER and IRQ domains Dmitry Eremin-Solenikov
@ 2014-11-15 11:53 ` Dmitry Eremin-Solenikov
2014-11-15 11:53 ` [PATCH 2/6] ARM: sa1100: drop entry-macro.S Dmitry Eremin-Solenikov
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Dmitry Eremin-Solenikov @ 2014-11-15 11:53 UTC (permalink / raw)
To: linux-arm-kernel
Add sa1100_handle_irq implementating handle_irq for sa1100 platform.
It is more or less a translation of old assembly code from assembler to
plain C. Also install this irq handler from sa1100_init_irq().
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
arch/arm/Kconfig | 1 +
arch/arm/mach-sa1100/irq.c | 20 ++++++++++++++++++++
2 files changed, 21 insertions(+)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 89c4b5c..2f3f132 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -703,6 +703,7 @@ config ARCH_SA1100
select GENERIC_CLOCKEVENTS
select HAVE_IDE
select ISA
+ select MULTI_IRQ_HANDLER
select NEED_MACH_MEMORY_H
select SPARSE_IRQ
help
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index 2124f1fc..9a3bdf1 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -20,6 +20,7 @@
#include <mach/hardware.h>
#include <mach/irqs.h>
#include <asm/mach/irq.h>
+#include <asm/exception.h>
#include "generic.h"
@@ -291,6 +292,23 @@ static int __init sa1100irq_init_devicefs(void)
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 = (ICIP);
+ icmr = (ICMR);
+ mask = icip & icmr;
+
+ if (mask == 0)
+ break;
+
+ handle_IRQ(ffs(mask) - 1, regs);
+ } while (1);
+}
+
void __init sa1100_init_irq(void)
{
unsigned int irq;
@@ -338,5 +356,7 @@ void __init sa1100_init_irq(void)
irq_set_chip(IRQ_GPIO11_27, &sa1100_normal_chip);
irq_set_chained_handler(IRQ_GPIO11_27, sa1100_high_gpio_handler);
+ set_handle_irq(sa1100_handle_irq);
+
sa1100_init_gpio();
}
--
2.1.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 2/6] ARM: sa1100: drop entry-macro.S
2014-11-15 11:53 [PATCH 0/6] ARM: sa1100: Use MULTI_IRQ_HANDLER and IRQ domains Dmitry Eremin-Solenikov
2014-11-15 11:53 ` [PATCH 1/6] ARM: sa1100: switch to MULTI_IRQ_HANDLER Dmitry Eremin-Solenikov
@ 2014-11-15 11:53 ` Dmitry Eremin-Solenikov
2014-11-15 11:53 ` [PATCH 3/6] ARM: sa1100: enable IRQ domains Dmitry Eremin-Solenikov
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Dmitry Eremin-Solenikov @ 2014-11-15 11:53 UTC (permalink / raw)
To: linux-arm-kernel
From: Dmitry Eremin-Solenikov <dmitry_eremin@mentor.com>
As mach-sa1100 was converted to MULTI_IRQ_HANDLER, drop now-unused
entry-macro.S file.
Signed-off-by: Dmitry Eremin-Solenikov <dmitry_eremin@mentor.com>
---
arch/arm/mach-sa1100/include/mach/entry-macro.S | 41 -------------------------
1 file changed, 41 deletions(-)
delete mode 100644 arch/arm/mach-sa1100/include/mach/entry-macro.S
diff --git a/arch/arm/mach-sa1100/include/mach/entry-macro.S b/arch/arm/mach-sa1100/include/mach/entry-macro.S
deleted file mode 100644
index 8cf7630..0000000
--- a/arch/arm/mach-sa1100/include/mach/entry-macro.S
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * arch/arm/mach-sa1100/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for SA1100-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.
- */
-
- .macro get_irqnr_preamble, base, tmp
- mov \base, #0xfa000000 @ ICIP = 0xfa050000
- add \base, \base, #0x00050000
- .endm
-
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
- ldr \irqstat, [\base] @ get irqs
- ldr \irqnr, [\base, #4] @ ICMR = 0xfa050004
- ands \irqstat, \irqstat, \irqnr
- mov \irqnr, #0
- beq 1001f
- tst \irqstat, #0xff
- moveq \irqstat, \irqstat, lsr #8
- addeq \irqnr, \irqnr, #8
- tsteq \irqstat, #0xff
- moveq \irqstat, \irqstat, lsr #8
- addeq \irqnr, \irqnr, #8
- tsteq \irqstat, #0xff
- moveq \irqstat, \irqstat, lsr #8
- addeq \irqnr, \irqnr, #8
- tst \irqstat, #0x0f
- moveq \irqstat, \irqstat, lsr #4
- addeq \irqnr, \irqnr, #4
- tst \irqstat, #0x03
- moveq \irqstat, \irqstat, lsr #2
- addeq \irqnr, \irqnr, #2
- tst \irqstat, #0x01
- addeqs \irqnr, \irqnr, #1
-1001:
- .endm
-
--
2.1.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 3/6] ARM: sa1100: enable IRQ domains
2014-11-15 11:53 [PATCH 0/6] ARM: sa1100: Use MULTI_IRQ_HANDLER and IRQ domains Dmitry Eremin-Solenikov
2014-11-15 11:53 ` [PATCH 1/6] ARM: sa1100: switch to MULTI_IRQ_HANDLER Dmitry Eremin-Solenikov
2014-11-15 11:53 ` [PATCH 2/6] ARM: sa1100: drop entry-macro.S Dmitry Eremin-Solenikov
@ 2014-11-15 11:53 ` Dmitry Eremin-Solenikov
2014-11-15 11:53 ` [PATCH 4/6] ARM: sa1100: introduce irqdomains support Dmitry Eremin-Solenikov
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Dmitry Eremin-Solenikov @ 2014-11-15 11:53 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
arch/arm/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2f3f132..622e364 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -702,6 +702,7 @@ config ARCH_SA1100
select CPU_SA1100
select GENERIC_CLOCKEVENTS
select HAVE_IDE
+ select IRQ_DOMAIN
select ISA
select MULTI_IRQ_HANDLER
select NEED_MACH_MEMORY_H
--
2.1.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 4/6] ARM: sa1100: introduce irqdomains support
2014-11-15 11:53 [PATCH 0/6] ARM: sa1100: Use MULTI_IRQ_HANDLER and IRQ domains Dmitry Eremin-Solenikov
` (2 preceding siblings ...)
2014-11-15 11:53 ` [PATCH 3/6] ARM: sa1100: enable IRQ domains Dmitry Eremin-Solenikov
@ 2014-11-15 11:53 ` Dmitry Eremin-Solenikov
2014-11-15 11:53 ` [PATCH 5/6] ARM: sa1100: merge IRQ 11 to "normal" irq domain Dmitry Eremin-Solenikov
2014-11-15 11:53 ` [PATCH 6/6] ARM: sa1100: switch to hwirq usage Dmitry Eremin-Solenikov
5 siblings, 0 replies; 7+ messages in thread
From: Dmitry Eremin-Solenikov @ 2014-11-15 11:53 UTC (permalink / raw)
To: linux-arm-kernel
Use irqdomains to manage both system and GPIO interrupts on SA1100 SoC
family. This opens path to further cleanup and unification in sa1100 IRQ
drivers.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
arch/arm/mach-sa1100/irq.c | 78 ++++++++++++++++++++++++++++++++++++----------
1 file changed, 61 insertions(+), 17 deletions(-)
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index 9a3bdf1..dbf7615 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -14,6 +14,7 @@
#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>
@@ -106,6 +107,23 @@ static struct irq_chip sa1100_low_gpio_chip = {
.irq_set_wake = sa1100_low_gpio_wake,
};
+static int sa1100_low_gpio_irqdomain_map(struct irq_domain *d,
+ unsigned int irq, irq_hw_number_t hwirq)
+{
+ irq_set_chip_and_handler(irq, &sa1100_low_gpio_chip,
+ handle_edge_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+
+ return 0;
+}
+
+static struct irq_domain_ops sa1100_low_gpio_irqdomain_ops = {
+ .map = sa1100_low_gpio_irqdomain_map,
+ .xlate = irq_domain_xlate_onetwocell,
+};
+
+static struct irq_domain *sa1100_low_gpio_irqdomain;
+
/*
* IRQ11 (GPIO11 through 27) handler. We enter here with the
* irq_controller_lock held, and IRQs disabled. Decode the IRQ
@@ -187,6 +205,23 @@ static struct irq_chip sa1100_high_gpio_chip = {
.irq_set_wake = sa1100_high_gpio_wake,
};
+static int sa1100_high_gpio_irqdomain_map(struct irq_domain *d,
+ unsigned int irq, irq_hw_number_t hwirq)
+{
+ irq_set_chip_and_handler(irq, &sa1100_high_gpio_chip,
+ handle_edge_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+
+ return 0;
+}
+
+static struct irq_domain_ops sa1100_high_gpio_irqdomain_ops = {
+ .map = sa1100_high_gpio_irqdomain_map,
+ .xlate = irq_domain_xlate_onetwocell,
+};
+
+static struct irq_domain *sa1100_high_gpio_irqdomain;
+
/*
* We don't need to ACK IRQs on the SA1100 unless they're GPIOs
* this is for internal IRQs i.e. from 11 to 31.
@@ -224,6 +259,23 @@ static struct irq_chip sa1100_normal_chip = {
.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");
@@ -311,8 +363,6 @@ sa1100_handle_irq(struct pt_regs *regs)
void __init sa1100_init_irq(void)
{
- unsigned int irq;
-
request_resource(&iomem_resource, &irq_resource);
/* disable all IRQs */
@@ -332,23 +382,17 @@ void __init sa1100_init_irq(void)
*/
ICCR = 1;
- for (irq = 0; irq <= 10; irq++) {
- irq_set_chip_and_handler(irq, &sa1100_low_gpio_chip,
- handle_edge_irq);
- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
- }
+ sa1100_low_gpio_irqdomain = irq_domain_add_legacy(NULL,
+ 11, 0, 0,
+ &sa1100_low_gpio_irqdomain_ops, NULL);
- for (irq = 12; irq <= 31; irq++) {
- irq_set_chip_and_handler(irq, &sa1100_normal_chip,
- handle_level_irq);
- set_irq_flags(irq, IRQF_VALID);
- }
+ sa1100_normal_irqdomain = irq_domain_add_legacy(NULL,
+ 20, 12, 12,
+ &sa1100_normal_irqdomain_ops, NULL);
- for (irq = 32; irq <= 48; irq++) {
- irq_set_chip_and_handler(irq, &sa1100_high_gpio_chip,
- handle_edge_irq);
- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
- }
+ sa1100_high_gpio_irqdomain = irq_domain_add_legacy(NULL,
+ 17, 32, 11,
+ &sa1100_high_gpio_irqdomain_ops, NULL);
/*
* Install handler for GPIO 11-27 edge detect interrupts
--
2.1.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 5/6] ARM: sa1100: merge IRQ 11 to "normal" irq domain
2014-11-15 11:53 [PATCH 0/6] ARM: sa1100: Use MULTI_IRQ_HANDLER and IRQ domains Dmitry Eremin-Solenikov
` (3 preceding siblings ...)
2014-11-15 11:53 ` [PATCH 4/6] ARM: sa1100: introduce irqdomains support Dmitry Eremin-Solenikov
@ 2014-11-15 11:53 ` Dmitry Eremin-Solenikov
2014-11-15 11:53 ` [PATCH 6/6] ARM: sa1100: switch to hwirq usage Dmitry Eremin-Solenikov
5 siblings, 0 replies; 7+ messages in thread
From: Dmitry Eremin-Solenikov @ 2014-11-15 11:53 UTC (permalink / raw)
To: linux-arm-kernel
IRQ 11 is a shared IRQ receiving IRQs from "high" GPIOs. It is still
handled by sa1100_normal_chip, so there is no point to exclude it from
"normal" irq domain. The IRQF_VALID flag set by domain map function will
be cleared by irq_set_chained_handler() internally.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
arch/arm/mach-sa1100/irq.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index dbf7615..36dd45e 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -387,7 +387,7 @@ void __init sa1100_init_irq(void)
&sa1100_low_gpio_irqdomain_ops, NULL);
sa1100_normal_irqdomain = irq_domain_add_legacy(NULL,
- 20, 12, 12,
+ 21, 11, 11,
&sa1100_normal_irqdomain_ops, NULL);
sa1100_high_gpio_irqdomain = irq_domain_add_legacy(NULL,
@@ -397,7 +397,6 @@ void __init sa1100_init_irq(void)
/*
* Install handler for GPIO 11-27 edge detect interrupts
*/
- irq_set_chip(IRQ_GPIO11_27, &sa1100_normal_chip);
irq_set_chained_handler(IRQ_GPIO11_27, sa1100_high_gpio_handler);
set_handle_irq(sa1100_handle_irq);
--
2.1.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH 6/6] ARM: sa1100: switch to hwirq usage
2014-11-15 11:53 [PATCH 0/6] ARM: sa1100: Use MULTI_IRQ_HANDLER and IRQ domains Dmitry Eremin-Solenikov
` (4 preceding siblings ...)
2014-11-15 11:53 ` [PATCH 5/6] ARM: sa1100: merge IRQ 11 to "normal" irq domain Dmitry Eremin-Solenikov
@ 2014-11-15 11:53 ` Dmitry Eremin-Solenikov
5 siblings, 0 replies; 7+ messages in thread
From: Dmitry Eremin-Solenikov @ 2014-11-15 11:53 UTC (permalink / raw)
To: linux-arm-kernel
Switch internally to using hardware irq numbers (hwirq). In case of GPIO
interrupts, hwirq is equal to GPIO number. In case of system interrupts,
hwirq is equal to interrupt number in the interrupt controller.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
arch/arm/mach-sa1100/irq.c | 37 ++++++++++++++-----------------------
1 file changed, 14 insertions(+), 23 deletions(-)
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index 36dd45e..c88d9c3 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -35,20 +35,11 @@ static int GPIO_IRQ_rising_edge;
static int GPIO_IRQ_falling_edge;
static int GPIO_IRQ_mask = (1 << 11) - 1;
-/*
- * To get the GPIO number from an IRQ number
- */
-#define GPIO_11_27_IRQ(i) ((i) - 21)
-#define GPIO11_27_MASK(irq) (1 << GPIO_11_27_IRQ(irq))
-
static int sa1100_gpio_type(struct irq_data *d, unsigned int type)
{
unsigned int mask;
- if (d->irq <= 10)
- mask = 1 << d->irq;
- else
- mask = GPIO11_27_MASK(d->irq);
+ mask = BIT(d->hwirq);
if (type == IRQ_TYPE_PROBE) {
if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask)
@@ -76,25 +67,25 @@ static int sa1100_gpio_type(struct irq_data *d, unsigned int type)
*/
static void sa1100_low_gpio_ack(struct irq_data *d)
{
- GEDR = (1 << d->irq);
+ GEDR = BIT(d->hwirq);
}
static void sa1100_low_gpio_mask(struct irq_data *d)
{
- ICMR &= ~(1 << d->irq);
+ ICMR &= ~BIT(d->hwirq);
}
static void sa1100_low_gpio_unmask(struct irq_data *d)
{
- ICMR |= 1 << d->irq;
+ ICMR |= BIT(d->hwirq);
}
static int sa1100_low_gpio_wake(struct irq_data *d, unsigned int on)
{
if (on)
- PWER |= 1 << d->irq;
+ PWER |= BIT(d->hwirq);
else
- PWER &= ~(1 << d->irq);
+ PWER &= ~BIT(d->hwirq);
return 0;
}
@@ -162,14 +153,14 @@ sa1100_high_gpio_handler(unsigned int irq, struct irq_desc *desc)
*/
static void sa1100_high_gpio_ack(struct irq_data *d)
{
- unsigned int mask = GPIO11_27_MASK(d->irq);
+ unsigned int mask = BIT(d->hwirq);
GEDR = mask;
}
static void sa1100_high_gpio_mask(struct irq_data *d)
{
- unsigned int mask = GPIO11_27_MASK(d->irq);
+ unsigned int mask = BIT(d->hwirq);
GPIO_IRQ_mask &= ~mask;
@@ -179,7 +170,7 @@ static void sa1100_high_gpio_mask(struct irq_data *d)
static void sa1100_high_gpio_unmask(struct irq_data *d)
{
- unsigned int mask = GPIO11_27_MASK(d->irq);
+ unsigned int mask = BIT(d->hwirq);
GPIO_IRQ_mask |= mask;
@@ -190,9 +181,9 @@ static void sa1100_high_gpio_unmask(struct irq_data *d)
static int sa1100_high_gpio_wake(struct irq_data *d, unsigned int on)
{
if (on)
- PWER |= GPIO11_27_MASK(d->irq);
+ PWER |= BIT(d->hwirq);
else
- PWER &= ~GPIO11_27_MASK(d->irq);
+ PWER &= ~BIT(d->hwirq);
return 0;
}
@@ -228,12 +219,12 @@ static struct irq_domain *sa1100_high_gpio_irqdomain;
*/
static void sa1100_mask_irq(struct irq_data *d)
{
- ICMR &= ~(1 << d->irq);
+ ICMR &= ~BIT(d->hwirq);
}
static void sa1100_unmask_irq(struct irq_data *d)
{
- ICMR |= (1 << d->irq);
+ ICMR |= BIT(d->hwirq);
}
/*
@@ -241,7 +232,7 @@ static void sa1100_unmask_irq(struct irq_data *d)
*/
static int sa1100_set_wake(struct irq_data *d, unsigned int on)
{
- if (d->irq == IRQ_RTCAlrm) {
+ if (d->hwirq == IRQ_RTCAlrm) {
if (on)
PWER |= PWER_RTC;
else
--
2.1.1
^ permalink raw reply related [flat|nested] 7+ messages in thread