* [PATCH v2] ARM: sa1100: improve irq handling
@ 2014-11-25 19:09 Dmitry Eremin-Solenikov
2014-11-25 19:09 ` [PATCH v2 1/8] ARM: sa1100: switch to MULTI_IRQ_HANDLER Dmitry Eremin-Solenikov
` (8 more replies)
0 siblings, 9 replies; 10+ messages in thread
From: Dmitry Eremin-Solenikov @ 2014-11-25 19:09 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
This patch series makes sa1100 platform use MULTI_IRQ_HANDLER and irq
domains to handle interrupts on StrongARM platform. Also virtual irq
numbers are changed to start from 1 rather than 0. It doesn't change
the way how Linux programs the hardware, only software interfaces are
changed.
Changes since v1:
- Start IRQs from 1, freeing IRQ 0
- Merge identical functions in the last patch
- Other minor changes.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 1/8] ARM: sa1100: switch to MULTI_IRQ_HANDLER
2014-11-25 19:09 [PATCH v2] ARM: sa1100: improve irq handling Dmitry Eremin-Solenikov
@ 2014-11-25 19:09 ` Dmitry Eremin-Solenikov
2014-11-25 19:09 ` [PATCH v2 2/8] ARM: sa1100: drop entry-macro.S Dmitry Eremin-Solenikov
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Dmitry Eremin-Solenikov @ 2014-11-25 19:09 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..4a1bd5e 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 + IRQ_GPIO0, 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.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 2/8] ARM: sa1100: drop entry-macro.S
2014-11-25 19:09 [PATCH v2] ARM: sa1100: improve irq handling Dmitry Eremin-Solenikov
2014-11-25 19:09 ` [PATCH v2 1/8] ARM: sa1100: switch to MULTI_IRQ_HANDLER Dmitry Eremin-Solenikov
@ 2014-11-25 19:09 ` Dmitry Eremin-Solenikov
2014-11-25 19:09 ` [PATCH v2 3/8] ARM: sa1100: replace irq numbers with names in irq driver Dmitry Eremin-Solenikov
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Dmitry Eremin-Solenikov @ 2014-11-25 19:09 UTC (permalink / raw)
To: linux-arm-kernel
As mach-sa1100 was converted to MULTI_IRQ_HANDLER, drop now-unused
entry-macro.S file.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.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.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 3/8] ARM: sa1100: replace irq numbers with names in irq driver
2014-11-25 19:09 [PATCH v2] ARM: sa1100: improve irq handling Dmitry Eremin-Solenikov
2014-11-25 19:09 ` [PATCH v2 1/8] ARM: sa1100: switch to MULTI_IRQ_HANDLER Dmitry Eremin-Solenikov
2014-11-25 19:09 ` [PATCH v2 2/8] ARM: sa1100: drop entry-macro.S Dmitry Eremin-Solenikov
@ 2014-11-25 19:09 ` Dmitry Eremin-Solenikov
2014-11-25 19:09 ` [PATCH v2 4/8] ARM: sa1100: shift IRQs by one Dmitry Eremin-Solenikov
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Dmitry Eremin-Solenikov @ 2014-11-25 19:09 UTC (permalink / raw)
To: linux-arm-kernel
In preparation for further changes replace direct IRQ numbers with
pre-defined names. This imposes no real code changes.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
arch/arm/mach-sa1100/irq.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index 4a1bd5e..0b29d27 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -37,14 +37,14 @@ 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 GPIO_11_27_IRQ(i) ((i) + 11 - IRQ_GPIO11)
#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)
+ if (d->irq <= IRQ_GPIO10)
mask = 1 << d->irq;
else
mask = GPIO11_27_MASK(d->irq);
@@ -71,7 +71,7 @@ static int sa1100_gpio_type(struct irq_data *d, unsigned int type)
}
/*
- * GPIO IRQs must be acknowledged. This is for IRQs from 0 to 10.
+ * GPIO IRQs must be acknowledged. This is for IRQs from GPIO0 to 10.
*/
static void sa1100_low_gpio_ack(struct irq_data *d)
{
@@ -189,7 +189,7 @@ static struct irq_chip sa1100_high_gpio_chip = {
/*
* 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.
+ * this is for internal IRQs i.e. from IRQ LCD to RTCAlrm.
*/
static void sa1100_mask_irq(struct irq_data *d)
{
@@ -332,19 +332,19 @@ void __init sa1100_init_irq(void)
*/
ICCR = 1;
- for (irq = 0; irq <= 10; irq++) {
+ for (irq = IRQ_GPIO0; irq <= IRQ_GPIO10; irq++) {
irq_set_chip_and_handler(irq, &sa1100_low_gpio_chip,
handle_edge_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
- for (irq = 12; irq <= 31; irq++) {
+ for (irq = IRQ_LCD; irq <= IRQ_RTCAlrm; irq++) {
irq_set_chip_and_handler(irq, &sa1100_normal_chip,
handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
- for (irq = 32; irq <= 48; irq++) {
+ for (irq = IRQ_GPIO11; irq <= IRQ_GPIO27; irq++) {
irq_set_chip_and_handler(irq, &sa1100_high_gpio_chip,
handle_edge_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
--
2.1.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 4/8] ARM: sa1100: shift IRQs by one
2014-11-25 19:09 [PATCH v2] ARM: sa1100: improve irq handling Dmitry Eremin-Solenikov
` (2 preceding siblings ...)
2014-11-25 19:09 ` [PATCH v2 3/8] ARM: sa1100: replace irq numbers with names in irq driver Dmitry Eremin-Solenikov
@ 2014-11-25 19:09 ` Dmitry Eremin-Solenikov
2014-11-25 19:09 ` [PATCH v2 5/8] ARM: sa1100: introduce irqdomains support Dmitry Eremin-Solenikov
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Dmitry Eremin-Solenikov @ 2014-11-25 19:09 UTC (permalink / raw)
To: linux-arm-kernel
As IRQ0 should not be used (especially in when using irq domains), shift all
virtual IRQ numbers by one.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
arch/arm/mach-sa1100/include/mach/irqs.h | 102 +++++++++++++++----------------
1 file changed, 51 insertions(+), 51 deletions(-)
diff --git a/arch/arm/mach-sa1100/include/mach/irqs.h b/arch/arm/mach-sa1100/include/mach/irqs.h
index 3790298..de09834 100644
--- a/arch/arm/mach-sa1100/include/mach/irqs.h
+++ b/arch/arm/mach-sa1100/include/mach/irqs.h
@@ -8,56 +8,56 @@
* 2001/11/14 RMK Cleaned up and standardised a lot of the IRQs.
*/
-#define IRQ_GPIO0 0
-#define IRQ_GPIO1 1
-#define IRQ_GPIO2 2
-#define IRQ_GPIO3 3
-#define IRQ_GPIO4 4
-#define IRQ_GPIO5 5
-#define IRQ_GPIO6 6
-#define IRQ_GPIO7 7
-#define IRQ_GPIO8 8
-#define IRQ_GPIO9 9
-#define IRQ_GPIO10 10
-#define IRQ_GPIO11_27 11
-#define IRQ_LCD 12 /* LCD controller */
-#define IRQ_Ser0UDC 13 /* Ser. port 0 UDC */
-#define IRQ_Ser1SDLC 14 /* Ser. port 1 SDLC */
-#define IRQ_Ser1UART 15 /* Ser. port 1 UART */
-#define IRQ_Ser2ICP 16 /* Ser. port 2 ICP */
-#define IRQ_Ser3UART 17 /* Ser. port 3 UART */
-#define IRQ_Ser4MCP 18 /* Ser. port 4 MCP */
-#define IRQ_Ser4SSP 19 /* Ser. port 4 SSP */
-#define IRQ_DMA0 20 /* DMA controller channel 0 */
-#define IRQ_DMA1 21 /* DMA controller channel 1 */
-#define IRQ_DMA2 22 /* DMA controller channel 2 */
-#define IRQ_DMA3 23 /* DMA controller channel 3 */
-#define IRQ_DMA4 24 /* DMA controller channel 4 */
-#define IRQ_DMA5 25 /* DMA controller channel 5 */
-#define IRQ_OST0 26 /* OS Timer match 0 */
-#define IRQ_OST1 27 /* OS Timer match 1 */
-#define IRQ_OST2 28 /* OS Timer match 2 */
-#define IRQ_OST3 29 /* OS Timer match 3 */
-#define IRQ_RTC1Hz 30 /* RTC 1 Hz clock */
-#define IRQ_RTCAlrm 31 /* RTC Alarm */
+#define IRQ_GPIO0 1
+#define IRQ_GPIO1 2
+#define IRQ_GPIO2 3
+#define IRQ_GPIO3 4
+#define IRQ_GPIO4 5
+#define IRQ_GPIO5 6
+#define IRQ_GPIO6 7
+#define IRQ_GPIO7 8
+#define IRQ_GPIO8 9
+#define IRQ_GPIO9 10
+#define IRQ_GPIO10 11
+#define IRQ_GPIO11_27 12
+#define IRQ_LCD 13 /* LCD controller */
+#define IRQ_Ser0UDC 14 /* Ser. port 0 UDC */
+#define IRQ_Ser1SDLC 15 /* Ser. port 1 SDLC */
+#define IRQ_Ser1UART 16 /* Ser. port 1 UART */
+#define IRQ_Ser2ICP 17 /* Ser. port 2 ICP */
+#define IRQ_Ser3UART 18 /* Ser. port 3 UART */
+#define IRQ_Ser4MCP 19 /* Ser. port 4 MCP */
+#define IRQ_Ser4SSP 20 /* Ser. port 4 SSP */
+#define IRQ_DMA0 21 /* DMA controller channel 0 */
+#define IRQ_DMA1 22 /* DMA controller channel 1 */
+#define IRQ_DMA2 23 /* DMA controller channel 2 */
+#define IRQ_DMA3 24 /* DMA controller channel 3 */
+#define IRQ_DMA4 25 /* DMA controller channel 4 */
+#define IRQ_DMA5 26 /* DMA controller channel 5 */
+#define IRQ_OST0 27 /* OS Timer match 0 */
+#define IRQ_OST1 28 /* OS Timer match 1 */
+#define IRQ_OST2 29 /* OS Timer match 2 */
+#define IRQ_OST3 30 /* OS Timer match 3 */
+#define IRQ_RTC1Hz 31 /* RTC 1 Hz clock */
+#define IRQ_RTCAlrm 32 /* RTC Alarm */
-#define IRQ_GPIO11 32
-#define IRQ_GPIO12 33
-#define IRQ_GPIO13 34
-#define IRQ_GPIO14 35
-#define IRQ_GPIO15 36
-#define IRQ_GPIO16 37
-#define IRQ_GPIO17 38
-#define IRQ_GPIO18 39
-#define IRQ_GPIO19 40
-#define IRQ_GPIO20 41
-#define IRQ_GPIO21 42
-#define IRQ_GPIO22 43
-#define IRQ_GPIO23 44
-#define IRQ_GPIO24 45
-#define IRQ_GPIO25 46
-#define IRQ_GPIO26 47
-#define IRQ_GPIO27 48
+#define IRQ_GPIO11 33
+#define IRQ_GPIO12 34
+#define IRQ_GPIO13 35
+#define IRQ_GPIO14 36
+#define IRQ_GPIO15 37
+#define IRQ_GPIO16 38
+#define IRQ_GPIO17 39
+#define IRQ_GPIO18 40
+#define IRQ_GPIO19 41
+#define IRQ_GPIO20 42
+#define IRQ_GPIO21 43
+#define IRQ_GPIO22 44
+#define IRQ_GPIO23 45
+#define IRQ_GPIO24 46
+#define IRQ_GPIO25 47
+#define IRQ_GPIO26 48
+#define IRQ_GPIO27 49
/*
* The next 16 interrupts are for board specific purposes. Since
@@ -65,8 +65,8 @@
* these. If you need more, increase IRQ_BOARD_END, but keep it
* within sensible limits. IRQs 49 to 64 are available.
*/
-#define IRQ_BOARD_START 49
-#define IRQ_BOARD_END 65
+#define IRQ_BOARD_START 50
+#define IRQ_BOARD_END 66
/*
* Figure out the MAX IRQ number.
--
2.1.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 5/8] ARM: sa1100: introduce irqdomains support
2014-11-25 19:09 [PATCH v2] ARM: sa1100: improve irq handling Dmitry Eremin-Solenikov
` (3 preceding siblings ...)
2014-11-25 19:09 ` [PATCH v2 4/8] ARM: sa1100: shift IRQs by one Dmitry Eremin-Solenikov
@ 2014-11-25 19:09 ` Dmitry Eremin-Solenikov
2014-11-25 19:09 ` [PATCH v2 6/8] ARM: sa1100: merge GPIO multiplexer IRQ to "normal" irq domain Dmitry Eremin-Solenikov
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Dmitry Eremin-Solenikov @ 2014-11-25 19:09 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/Kconfig | 1 +
arch/arm/mach-sa1100/irq.c | 78 ++++++++++++++++++++++++++++++++++++----------
2 files changed, 62 insertions(+), 17 deletions(-)
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
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index 0b29d27..2d8be03 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 IRQ LCD to RTCAlrm.
@@ -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 = IRQ_GPIO0; irq <= IRQ_GPIO10; 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, IRQ_GPIO0, 0,
+ &sa1100_low_gpio_irqdomain_ops, NULL);
- for (irq = IRQ_LCD; irq <= IRQ_RTCAlrm; 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, IRQ_LCD, 12,
+ &sa1100_normal_irqdomain_ops, NULL);
- for (irq = IRQ_GPIO11; irq <= IRQ_GPIO27; 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, IRQ_GPIO11, 11,
+ &sa1100_high_gpio_irqdomain_ops, NULL);
/*
* Install handler for GPIO 11-27 edge detect interrupts
--
2.1.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 6/8] ARM: sa1100: merge GPIO multiplexer IRQ to "normal" irq domain
2014-11-25 19:09 [PATCH v2] ARM: sa1100: improve irq handling Dmitry Eremin-Solenikov
` (4 preceding siblings ...)
2014-11-25 19:09 ` [PATCH v2 5/8] ARM: sa1100: introduce irqdomains support Dmitry Eremin-Solenikov
@ 2014-11-25 19:09 ` Dmitry Eremin-Solenikov
2014-11-25 19:09 ` [PATCH v2 7/8] ARM: sa1100: switch to hwirq usage Dmitry Eremin-Solenikov
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Dmitry Eremin-Solenikov @ 2014-11-25 19:09 UTC (permalink / raw)
To: linux-arm-kernel
IRQ_GPIO11_27 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 2d8be03..14a7633e 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, IRQ_LCD, 12,
+ 21, IRQ_GPIO11_27, 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.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 7/8] ARM: sa1100: switch to hwirq usage
2014-11-25 19:09 [PATCH v2] ARM: sa1100: improve irq handling Dmitry Eremin-Solenikov
` (5 preceding siblings ...)
2014-11-25 19:09 ` [PATCH v2 6/8] ARM: sa1100: merge GPIO multiplexer IRQ to "normal" irq domain Dmitry Eremin-Solenikov
@ 2014-11-25 19:09 ` Dmitry Eremin-Solenikov
2014-11-25 19:09 ` [PATCH v2 8/8] ARM: sa1100: reorder IRQ handling code Dmitry Eremin-Solenikov
2014-11-26 12:47 ` [PATCH v2] ARM: sa1100: improve irq handling Linus Walleij
8 siblings, 0 replies; 10+ messages in thread
From: Dmitry Eremin-Solenikov @ 2014-11-25 19:09 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 14a7633e..981db98 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) + 11 - IRQ_GPIO11)
-#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 <= IRQ_GPIO10)
- 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 (BIT(d->hwirq) == IC_RTCAlrm) {
if (on)
PWER |= PWER_RTC;
else
--
2.1.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 8/8] ARM: sa1100: reorder IRQ handling code
2014-11-25 19:09 [PATCH v2] ARM: sa1100: improve irq handling Dmitry Eremin-Solenikov
` (6 preceding siblings ...)
2014-11-25 19:09 ` [PATCH v2 7/8] ARM: sa1100: switch to hwirq usage Dmitry Eremin-Solenikov
@ 2014-11-25 19:09 ` Dmitry Eremin-Solenikov
2014-11-26 12:47 ` [PATCH v2] ARM: sa1100: improve irq handling Linus Walleij
8 siblings, 0 replies; 10+ messages in thread
From: Dmitry Eremin-Solenikov @ 2014-11-25 19:09 UTC (permalink / raw)
To: linux-arm-kernel
This patch just reorders functions/data inside sa1100 irq driver to be
able to merge functions that have the same code after converting to
irqdomains and hwirq. No real code changes.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
arch/arm/mach-sa1100/irq.c | 155 +++++++++++++++++++--------------------------
1 file changed, 66 insertions(+), 89 deletions(-)
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index 981db98..63e2901 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -27,6 +27,60 @@
/*
+ * 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)
+{
+ ICMR &= ~BIT(d->hwirq);
+}
+
+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;
+}
+
+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;
+
+/*
* SA1100 GPIO edge detection for IRQs:
* IRQs are generated on Falling-Edge, Rising-Edge, or both.
* Use this instead of directly setting GRER/GFER.
@@ -63,24 +117,14 @@ static int sa1100_gpio_type(struct irq_data *d, unsigned int type)
}
/*
- * GPIO IRQs must be acknowledged. This is for IRQs from GPIO0 to 10.
+ * GPIO IRQs must be acknowledged.
*/
-static void sa1100_low_gpio_ack(struct irq_data *d)
+static void sa1100_gpio_ack(struct irq_data *d)
{
GEDR = BIT(d->hwirq);
}
-static void sa1100_low_gpio_mask(struct irq_data *d)
-{
- ICMR &= ~BIT(d->hwirq);
-}
-
-static void sa1100_low_gpio_unmask(struct irq_data *d)
-{
- ICMR |= BIT(d->hwirq);
-}
-
-static int sa1100_low_gpio_wake(struct irq_data *d, unsigned int on)
+static int sa1100_gpio_wake(struct irq_data *d, unsigned int on)
{
if (on)
PWER |= BIT(d->hwirq);
@@ -89,13 +133,16 @@ static int sa1100_low_gpio_wake(struct irq_data *d, unsigned int on)
return 0;
}
+/*
+ * This is for IRQs from 0 to 10.
+ */
static struct irq_chip sa1100_low_gpio_chip = {
.name = "GPIO-l",
- .irq_ack = sa1100_low_gpio_ack,
- .irq_mask = sa1100_low_gpio_mask,
- .irq_unmask = sa1100_low_gpio_unmask,
+ .irq_ack = sa1100_gpio_ack,
+ .irq_mask = sa1100_mask_irq,
+ .irq_unmask = sa1100_unmask_irq,
.irq_set_type = sa1100_gpio_type,
- .irq_set_wake = sa1100_low_gpio_wake,
+ .irq_set_wake = sa1100_gpio_wake,
};
static int sa1100_low_gpio_irqdomain_map(struct irq_domain *d,
@@ -151,13 +198,6 @@ sa1100_high_gpio_handler(unsigned int irq, struct irq_desc *desc)
* In addition, the IRQs are all collected up into one bit in the
* interrupt controller registers.
*/
-static void sa1100_high_gpio_ack(struct irq_data *d)
-{
- unsigned int mask = BIT(d->hwirq);
-
- GEDR = mask;
-}
-
static void sa1100_high_gpio_mask(struct irq_data *d)
{
unsigned int mask = BIT(d->hwirq);
@@ -178,22 +218,13 @@ static void sa1100_high_gpio_unmask(struct irq_data *d)
GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
}
-static int sa1100_high_gpio_wake(struct irq_data *d, unsigned int on)
-{
- if (on)
- PWER |= BIT(d->hwirq);
- else
- PWER &= ~BIT(d->hwirq);
- return 0;
-}
-
static struct irq_chip sa1100_high_gpio_chip = {
.name = "GPIO-h",
- .irq_ack = sa1100_high_gpio_ack,
+ .irq_ack = sa1100_gpio_ack,
.irq_mask = sa1100_high_gpio_mask,
.irq_unmask = sa1100_high_gpio_unmask,
.irq_set_type = sa1100_gpio_type,
- .irq_set_wake = sa1100_high_gpio_wake,
+ .irq_set_wake = sa1100_gpio_wake,
};
static int sa1100_high_gpio_irqdomain_map(struct irq_domain *d,
@@ -213,60 +244,6 @@ static struct irq_domain_ops sa1100_high_gpio_irqdomain_ops = {
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 IRQ LCD to RTCAlrm.
- */
-static void sa1100_mask_irq(struct irq_data *d)
-{
- ICMR &= ~BIT(d->hwirq);
-}
-
-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;
-}
-
-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");
--
2.1.3
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2] ARM: sa1100: improve irq handling
2014-11-25 19:09 [PATCH v2] ARM: sa1100: improve irq handling Dmitry Eremin-Solenikov
` (7 preceding siblings ...)
2014-11-25 19:09 ` [PATCH v2 8/8] ARM: sa1100: reorder IRQ handling code Dmitry Eremin-Solenikov
@ 2014-11-26 12:47 ` Linus Walleij
8 siblings, 0 replies; 10+ messages in thread
From: Linus Walleij @ 2014-11-26 12:47 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Nov 25, 2014 at 8:09 PM, Dmitry Eremin-Solenikov
<dbaryshkov@gmail.com> wrote:
> This patch series makes sa1100 platform use MULTI_IRQ_HANDLER and irq
> domains to handle interrupts on StrongARM platform. Also virtual irq
> numbers are changed to start from 1 rather than 0. It doesn't change
> the way how Linux programs the hardware, only software interfaces are
> changed.
>
> Changes since v1:
> - Start IRQs from 1, freeing IRQ 0
> - Merge identical functions in the last patch
> - Other minor changes.
Applied all patches and tested on h3600 on top of v3.18-rc6.
Works like a charm.
Tested-by: Linus Walleij <linus.walleij@linaro.org>
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2014-11-26 12:47 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-11-25 19:09 [PATCH v2] ARM: sa1100: improve irq handling Dmitry Eremin-Solenikov
2014-11-25 19:09 ` [PATCH v2 1/8] ARM: sa1100: switch to MULTI_IRQ_HANDLER Dmitry Eremin-Solenikov
2014-11-25 19:09 ` [PATCH v2 2/8] ARM: sa1100: drop entry-macro.S Dmitry Eremin-Solenikov
2014-11-25 19:09 ` [PATCH v2 3/8] ARM: sa1100: replace irq numbers with names in irq driver Dmitry Eremin-Solenikov
2014-11-25 19:09 ` [PATCH v2 4/8] ARM: sa1100: shift IRQs by one Dmitry Eremin-Solenikov
2014-11-25 19:09 ` [PATCH v2 5/8] ARM: sa1100: introduce irqdomains support Dmitry Eremin-Solenikov
2014-11-25 19:09 ` [PATCH v2 6/8] ARM: sa1100: merge GPIO multiplexer IRQ to "normal" irq domain Dmitry Eremin-Solenikov
2014-11-25 19:09 ` [PATCH v2 7/8] ARM: sa1100: switch to hwirq usage Dmitry Eremin-Solenikov
2014-11-25 19:09 ` [PATCH v2 8/8] ARM: sa1100: reorder IRQ handling code Dmitry Eremin-Solenikov
2014-11-26 12:47 ` [PATCH v2] ARM: sa1100: improve irq handling Linus Walleij
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).