From: John Crispin <blogic@openwrt.org>
To: Sergey Ryazanov <ryazanov.s.a@gmail.com>,
Ralf Baechle <ralf@linux-mips.org>
Cc: Linux MIPS <linux-mips@linux-mips.org>
Subject: Re: [PATCH v2 04/13] MIPS: ath25: add interrupts handling routines
Date: Wed, 22 Oct 2014 10:26:46 +0200 [thread overview]
Message-ID: <54476A46.4050006@openwrt.org> (raw)
In-Reply-To: <1413932631-12866-5-git-send-email-ryazanov.s.a@gmail.com>
few comments inline ....
On 22/10/2014 01:03, Sergey Ryazanov wrote:
> Add interrupts initialization and handling routines, also add AHB bus
> error interrupt handlers for both SoCs families.
>
> Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
> ---
>
> Changes since RFC:
> - add all interrupts
> - use dynamic IRQ numbers allocation
>
> Changes since v1:
> - rename MIPS machine ar231x -> ath25
>
> arch/mips/ath25/ar2315.c | 108 +++++++++++++++++++++++++
> arch/mips/ath25/ar2315.h | 2 +
> arch/mips/ath25/ar5312.c | 103 +++++++++++++++++++++++
> arch/mips/ath25/ar5312.h | 2 +
> arch/mips/ath25/board.c | 10 +++
> arch/mips/ath25/devices.h | 2 +
> arch/mips/include/asm/mach-ath25/ar2315_regs.h | 23 ++++++
> arch/mips/include/asm/mach-ath25/ar5312_regs.h | 23 ++++++
> arch/mips/include/asm/mach-ath25/ath25.h | 2 +
> 9 files changed, 275 insertions(+)
>
> diff --git a/arch/mips/ath25/ar2315.c b/arch/mips/ath25/ar2315.c
> index 4eee362..e1a338b 100644
> --- a/arch/mips/ath25/ar2315.c
> +++ b/arch/mips/ath25/ar2315.c
> @@ -27,6 +27,114 @@
> #include "devices.h"
> #include "ar2315.h"
>
> +static unsigned ar2315_misc_irq_base;
> +
> +static irqreturn_t ar2315_ahb_err_handler(int cpl, void *dev_id)
> +{
> + ath25_write_reg(AR2315_AHB_ERR0, AR2315_AHB_ERROR_DET);
> + ath25_read_reg(AR2315_AHB_ERR1);
> +
> + pr_emerg("AHB fatal error\n");
> + machine_restart("AHB error"); /* Catastrophic failure */
> +
> + return IRQ_HANDLED;
> +}
> +
> +static struct irqaction ar2315_ahb_err_interrupt = {
> + .handler = ar2315_ahb_err_handler,
> + .name = "ar2315-ahb-error",
> +};
> +
> +static void ar2315_misc_irq_handler(unsigned irq, struct irq_desc *desc)
> +{
> + u32 pending = ath25_read_reg(AR2315_ISR) & ath25_read_reg(AR2315_IMR);
> + unsigned base = ar2315_misc_irq_base;
> +
> + if (pending & AR2315_ISR_SPI)
> + generic_handle_irq(base + AR2315_MISC_IRQ_SPI);
> + else if (pending & AR2315_ISR_TIMER)
> + generic_handle_irq(base + AR2315_MISC_IRQ_TIMER);
> + else if (pending & AR2315_ISR_AHB)
> + generic_handle_irq(base + AR2315_MISC_IRQ_AHB);
> + else if (pending & AR2315_ISR_GPIO) {
> + ath25_write_reg(AR2315_ISR, AR2315_ISR_GPIO);
> + generic_handle_irq(base + AR2315_MISC_IRQ_GPIO);
> + } else if (pending & AR2315_ISR_UART0)
> + generic_handle_irq(base + AR2315_MISC_IRQ_UART0);
> + else if (pending & AR2315_ISR_WD) {
> + ath25_write_reg(AR2315_ISR, AR2315_ISR_WD);
> + generic_handle_irq(base + AR2315_MISC_IRQ_WATCHDOG);
> + } else
> + spurious_interrupt();
> +}
> +
> +static void ar2315_misc_irq_unmask(struct irq_data *d)
> +{
> + u32 imr = ath25_read_reg(AR2315_IMR);
> +
> + imr |= 1 << (d->irq - ar2315_misc_irq_base);
> + ath25_write_reg(AR2315_IMR, imr);
> +}
> +
> +static void ar2315_misc_irq_mask(struct irq_data *d)
> +{
> + u32 imr = ath25_read_reg(AR2315_IMR);
> +
> + imr &= ~(1 << (d->irq - ar2315_misc_irq_base));
> + ath25_write_reg(AR2315_IMR, imr);
> +}
> +
> +static struct irq_chip ar2315_misc_irq_chip = {
> + .name = "ar2315-misc",
> + .irq_unmask = ar2315_misc_irq_unmask,
> + .irq_mask = ar2315_misc_irq_mask,
> +};
> +
> +/*
> + * Called when an interrupt is received, this function
> + * determines exactly which interrupt it was, and it
> + * invokes the appropriate handler.
> + *
> + * Implicitly, we also define interrupt priority by
> + * choosing which to dispatch first.
> + */
> +static void ar2315_irq_dispatch(void)
> +{
> + u32 pending = read_c0_status() & read_c0_cause();
> +
> + if (pending & CAUSEF_IP3)
> + do_IRQ(AR2315_IRQ_WLAN0);
> + else if (pending & CAUSEF_IP2)
> + do_IRQ(AR2315_IRQ_MISC);
> + else if (pending & CAUSEF_IP7)
> + do_IRQ(ATH25_IRQ_CPU_CLOCK);
> + else
> + spurious_interrupt();
> +}
> +
> +void __init ar2315_arch_init_irq(void)
> +{
> + unsigned i;
> + int res;
> +
> + ath25_irq_dispatch = ar2315_irq_dispatch;
> +
> + res = irq_alloc_descs(-1, 0, AR2315_MISC_IRQ_COUNT, 0);
> + if (res < 0)
> + pr_emerg("Failed to allocate misc IRQ numbers\n");
> + ar2315_misc_irq_base = res;
> +
> + for (i = 0; i < AR2315_MISC_IRQ_COUNT; i++) {
> + unsigned irq = ar2315_misc_irq_base + i;
> +
> + irq_set_chip_and_handler(irq, &ar2315_misc_irq_chip,
> + handle_level_irq);
> + }
> + setup_irq(ar2315_misc_irq_base + AR2315_MISC_IRQ_AHB,
> + &ar2315_ahb_err_interrupt);
> + irq_set_chained_handler(AR2315_IRQ_MISC, ar2315_misc_irq_handler);
> +}
> +
you should use irq_doamin here with a xlate function. this is just a 3
liner. look at arch/mips/ralink/irq.c
> static void ar2315_restart(char *command)
> {
> void (*mips_reset_vec)(void) = (void *)0xbfc00000;
> diff --git a/arch/mips/ath25/ar2315.h b/arch/mips/ath25/ar2315.h
> index 98d32b2..2a57858 100644
> --- a/arch/mips/ath25/ar2315.h
> +++ b/arch/mips/ath25/ar2315.h
> @@ -3,12 +3,14 @@
>
> #ifdef CONFIG_SOC_AR2315
>
> +void ar2315_arch_init_irq(void);
> void ar2315_plat_time_init(void);
> void ar2315_plat_mem_setup(void);
> void ar2315_prom_init(void);
>
> #else
>
> +static inline void ar2315_arch_init_irq(void) {}
> static inline void ar2315_plat_time_init(void) {}
> static inline void ar2315_plat_mem_setup(void) {}
> static inline void ar2315_prom_init(void) {}
> diff --git a/arch/mips/ath25/ar5312.c b/arch/mips/ath25/ar5312.c
> index 80d7ed7..e9c7f71 100644
> --- a/arch/mips/ath25/ar5312.c
> +++ b/arch/mips/ath25/ar5312.c
> @@ -27,6 +27,109 @@
> #include "devices.h"
> #include "ar5312.h"
>
> +static unsigned ar5312_misc_irq_base;
> +
> +static irqreturn_t ar5312_ahb_err_handler(int cpl, void *dev_id)
> +{
> + u32 proc1 = ath25_read_reg(AR5312_PROC1);
> + u32 proc_addr = ath25_read_reg(AR5312_PROCADDR); /* clears error */
> + u32 dma1 = ath25_read_reg(AR5312_DMA1);
> + u32 dma_addr = ath25_read_reg(AR5312_DMAADDR); /* clears error */
> +
> + pr_emerg("AHB interrupt: PROCADDR=0x%8.8x PROC1=0x%8.8x DMAADDR=0x%8.8x DMA1=0x%8.8x\n",
> + proc_addr, proc1, dma_addr, dma1);
> +
> + machine_restart("AHB error"); /* Catastrophic failure */
> + return IRQ_HANDLED;
> +}
> +
> +static struct irqaction ar5312_ahb_err_interrupt = {
> + .handler = ar5312_ahb_err_handler,
> + .name = "ar5312-ahb-error",
> +};
> +
> +static void ar5312_misc_irq_handler(unsigned irq, struct irq_desc *desc)
> +{
> + u32 pending = ath25_read_reg(AR5312_ISR) & ath25_read_reg(AR5312_IMR);
> + unsigned base = ar5312_misc_irq_base;
> +
> + if (pending & AR5312_ISR_TIMER) {
> + generic_handle_irq(base + AR5312_MISC_IRQ_TIMER);
> + (void)ath25_read_reg(AR5312_TIMER);
> + } else if (pending & AR5312_ISR_AHBPROC)
> + generic_handle_irq(base + AR5312_MISC_IRQ_AHB_PROC);
> + else if (pending & AR5312_ISR_UART0)
> + generic_handle_irq(base + AR5312_MISC_IRQ_UART0);
> + else if (pending & AR5312_ISR_WD)
> + generic_handle_irq(base + AR5312_MISC_IRQ_WATCHDOG);
> + else
> + spurious_interrupt();
> +}
> +
> +/* Enable the specified AR5312_MISC_IRQ interrupt */
> +static void ar5312_misc_irq_unmask(struct irq_data *d)
> +{
> + u32 imr = ath25_read_reg(AR5312_IMR);
> +
> + imr |= 1 << (d->irq - ar5312_misc_irq_base);
> + ath25_write_reg(AR5312_IMR, imr);
> +}
> +
> +/* Disable the specified AR5312_MISC_IRQ interrupt */
> +static void ar5312_misc_irq_mask(struct irq_data *d)
> +{
> + u32 imr = ath25_read_reg(AR5312_IMR);
> +
> + imr &= ~(1 << (d->irq - ar5312_misc_irq_base));
> + ath25_write_reg(AR5312_IMR, imr);
> + ath25_read_reg(AR5312_IMR); /* flush write buffer */
> +}
> +
> +static struct irq_chip ar5312_misc_irq_chip = {
> + .name = "ar5312-misc",
> + .irq_unmask = ar5312_misc_irq_unmask,
> + .irq_mask = ar5312_misc_irq_mask,
> +};
> +
> +static void ar5312_irq_dispatch(void)
> +{
> + u32 pending = read_c0_status() & read_c0_cause();
> +
> + if (pending & CAUSEF_IP2)
> + do_IRQ(AR5312_IRQ_WLAN0);
> + else if (pending & CAUSEF_IP5)
> + do_IRQ(AR5312_IRQ_WLAN1);
> + else if (pending & CAUSEF_IP6)
> + do_IRQ(AR5312_IRQ_MISC);
> + else if (pending & CAUSEF_IP7)
> + do_IRQ(ATH25_IRQ_CPU_CLOCK);
> + else
> + spurious_interrupt();
> +}
> +
> +void __init ar5312_arch_init_irq(void)
> +{
> + unsigned i;
> + int res;
> +
> + ath25_irq_dispatch = ar5312_irq_dispatch;
> +
> + res = irq_alloc_descs(-1, 0, AR5312_MISC_IRQ_COUNT, 0);
> + if (res < 0)
> + pr_emerg("Failed to allocate misc IRQ numbers\n");
> + ar5312_misc_irq_base = res;
> +
> + for (i = 0; i < AR5312_MISC_IRQ_COUNT; i++) {
> + unsigned irq = ar5312_misc_irq_base + i;
> +
> + irq_set_chip_and_handler(irq, &ar5312_misc_irq_chip,
> + handle_level_irq);
> + }
> + setup_irq(ar5312_misc_irq_base + AR5312_MISC_IRQ_AHB_PROC,
> + &ar5312_ahb_err_interrupt);
> + irq_set_chained_handler(AR5312_IRQ_MISC, ar5312_misc_irq_handler);
> +}
same here, irq_domain is the current best practice
> +
> static void ar5312_restart(char *command)
> {
> /* reset the system */
> diff --git a/arch/mips/ath25/ar5312.h b/arch/mips/ath25/ar5312.h
> index 339b28e..b60ad38 100644
> --- a/arch/mips/ath25/ar5312.h
> +++ b/arch/mips/ath25/ar5312.h
> @@ -3,12 +3,14 @@
>
> #ifdef CONFIG_SOC_AR5312
>
> +void ar5312_arch_init_irq(void);
> void ar5312_plat_time_init(void);
> void ar5312_plat_mem_setup(void);
> void ar5312_prom_init(void);
>
> #else
>
> +static inline void ar5312_arch_init_irq(void) {}
> static inline void ar5312_plat_time_init(void) {}
> static inline void ar5312_plat_mem_setup(void) {}
> static inline void ar5312_prom_init(void) {}
> diff --git a/arch/mips/ath25/board.c b/arch/mips/ath25/board.c
> index a6b8c26..68447d3 100644
> --- a/arch/mips/ath25/board.c
> +++ b/arch/mips/ath25/board.c
> @@ -16,9 +16,12 @@
> #include <asm/bootinfo.h>
> #include <asm/time.h>
>
> +#include "devices.h"
> #include "ar5312.h"
> #include "ar2315.h"
>
> +void (*ath25_irq_dispatch)(void);
> +
> static void ath25_halt(void)
> {
> local_irq_disable();
> @@ -42,6 +45,7 @@ void __init plat_mem_setup(void)
>
> asmlinkage void plat_irq_dispatch(void)
> {
> + ath25_irq_dispatch();
> }
>
> void __init plat_time_init(void)
> @@ -61,5 +65,11 @@ void __init arch_init_irq(void)
> {
> clear_c0_status(ST0_IM);
> mips_cpu_irq_init();
> +
> + /* Initialize interrupt controllers */
> + if (is_ar5312())
> + ar5312_arch_init_irq();
> + else
> + ar2315_arch_init_irq();
> }
>
> diff --git a/arch/mips/ath25/devices.h b/arch/mips/ath25/devices.h
> index edda636..bbf2988 100644
> --- a/arch/mips/ath25/devices.h
> +++ b/arch/mips/ath25/devices.h
> @@ -3,6 +3,8 @@
>
> #include <linux/cpu.h>
>
> +extern void (*ath25_irq_dispatch)(void);
> +
> static inline bool is_ar2315(void)
> {
> return (current_cpu_data.cputype == CPU_4KEC);
> diff --git a/arch/mips/include/asm/mach-ath25/ar2315_regs.h b/arch/mips/include/asm/mach-ath25/ar2315_regs.h
> index ff9a4a8..e680abc 100644
> --- a/arch/mips/include/asm/mach-ath25/ar2315_regs.h
> +++ b/arch/mips/include/asm/mach-ath25/ar2315_regs.h
> @@ -15,6 +15,29 @@
> #define __ASM_MACH_ATH25_AR2315_REGS_H
>
> /*
> + * IRQs
> + */
> +#define AR2315_IRQ_MISC (MIPS_CPU_IRQ_BASE + 2) /* C0_CAUSE: 0x0400 */
> +#define AR2315_IRQ_WLAN0 (MIPS_CPU_IRQ_BASE + 3) /* C0_CAUSE: 0x0800 */
> +#define AR2315_IRQ_ENET0 (MIPS_CPU_IRQ_BASE + 4) /* C0_CAUSE: 0x1000 */
> +#define AR2315_IRQ_LCBUS_PCI (MIPS_CPU_IRQ_BASE + 5) /* C0_CAUSE: 0x2000 */
> +#define AR2315_IRQ_WLAN0_POLL (MIPS_CPU_IRQ_BASE + 6) /* C0_CAUSE: 0x4000 */
> +
> +/*
> + * Miscellaneous interrupts, which share IP2.
> + */
> +#define AR2315_MISC_IRQ_UART0 0
> +#define AR2315_MISC_IRQ_I2C_RSVD 1
> +#define AR2315_MISC_IRQ_SPI 2
> +#define AR2315_MISC_IRQ_AHB 3
> +#define AR2315_MISC_IRQ_APB 4
> +#define AR2315_MISC_IRQ_TIMER 5
> +#define AR2315_MISC_IRQ_GPIO 6
> +#define AR2315_MISC_IRQ_WATCHDOG 7
> +#define AR2315_MISC_IRQ_IR_RSVD 8
> +#define AR2315_MISC_IRQ_COUNT 9
> +
> +/*
> * Address map
> */
> #define AR2315_SPI_READ 0x08000000 /* SPI flash */
> diff --git a/arch/mips/include/asm/mach-ath25/ar5312_regs.h b/arch/mips/include/asm/mach-ath25/ar5312_regs.h
> index 76856d8..afcd0b2 100644
> --- a/arch/mips/include/asm/mach-ath25/ar5312_regs.h
> +++ b/arch/mips/include/asm/mach-ath25/ar5312_regs.h
> @@ -12,6 +12,29 @@
> #define __ASM_MACH_ATH25_AR5312_REGS_H
>
> /*
> + * IRQs
> + */
> +#define AR5312_IRQ_WLAN0 (MIPS_CPU_IRQ_BASE + 2) /* C0_CAUSE: 0x0400 */
> +#define AR5312_IRQ_ENET0 (MIPS_CPU_IRQ_BASE + 3) /* C0_CAUSE: 0x0800 */
> +#define AR5312_IRQ_ENET1 (MIPS_CPU_IRQ_BASE + 4) /* C0_CAUSE: 0x1000 */
> +#define AR5312_IRQ_WLAN1 (MIPS_CPU_IRQ_BASE + 5) /* C0_CAUSE: 0x2000 */
> +#define AR5312_IRQ_MISC (MIPS_CPU_IRQ_BASE + 6) /* C0_CAUSE: 0x4000 */
> +
> +/*
> + * Miscellaneous interrupts, which share IP6.
> + */
> +#define AR5312_MISC_IRQ_TIMER 0
> +#define AR5312_MISC_IRQ_AHB_PROC 1
> +#define AR5312_MISC_IRQ_AHB_DMA 2
> +#define AR5312_MISC_IRQ_GPIO 3
> +#define AR5312_MISC_IRQ_UART0 4
> +#define AR5312_MISC_IRQ_UART0_DMA 5
> +#define AR5312_MISC_IRQ_WATCHDOG 6
> +#define AR5312_MISC_IRQ_LOCAL 7
> +#define AR5312_MISC_IRQ_SPI 8
> +#define AR5312_MISC_IRQ_COUNT 9
> +
> +/*
> * Address Map
> *
> * The AR5312 supports 2 enet MACS, even though many reference boards only
> diff --git a/arch/mips/include/asm/mach-ath25/ath25.h b/arch/mips/include/asm/mach-ath25/ath25.h
> index bd66ce7..caf0794 100644
> --- a/arch/mips/include/asm/mach-ath25/ath25.h
> +++ b/arch/mips/include/asm/mach-ath25/ath25.h
> @@ -3,6 +3,8 @@
>
> #include <linux/io.h>
>
> +#define ATH25_IRQ_CPU_CLOCK (MIPS_CPU_IRQ_BASE + 7) /* C0_CAUSE: 0x8000 */
> +
> #define ATH25_REG_MS(_val, _field) (((_val) & _field##_M) >> _field##_S)
>
> static inline u32 ath25_read_reg(u32 reg)
>
next prev parent reply other threads:[~2014-10-22 8:26 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-21 23:03 [PATCH v2 00/13] MIPS: support for the Atheros AR231X SoCs Sergey Ryazanov
2014-10-21 23:03 ` [PATCH v2 01/13] MIPS: ath25: add common parts Sergey Ryazanov
2014-10-21 23:36 ` John Crispin
2014-10-22 12:40 ` Sergey Ryazanov
2014-10-22 8:31 ` John Crispin
2014-10-22 13:06 ` Sergey Ryazanov
2014-10-22 13:09 ` John Crispin
2014-10-21 23:03 ` [PATCH v2 02/13] MIPS: ath25: add basic AR5312 SoC support Sergey Ryazanov
2014-10-21 23:48 ` John Crispin
2014-10-22 0:03 ` John Crispin
2014-10-22 14:11 ` Sergey Ryazanov
2014-10-21 23:03 ` [PATCH v2 03/13] MIPS: ath25: add basic AR2315 " Sergey Ryazanov
2014-10-21 23:03 ` [PATCH v2 04/13] MIPS: ath25: add interrupts handling routines Sergey Ryazanov
2014-10-22 8:26 ` John Crispin [this message]
2014-10-22 14:51 ` Sergey Ryazanov
2014-10-22 8:49 ` John Crispin
2014-10-21 23:03 ` [PATCH v2 05/13] MIPS: ath25: add early printk support Sergey Ryazanov
2014-10-21 23:03 ` [PATCH v2 06/13] MIPS: ath25: add UART support Sergey Ryazanov
2014-10-21 23:03 ` [PATCH v2 07/13] MIPS: ath25: add board configuration detection Sergey Ryazanov
2014-10-21 23:03 ` [PATCH v2 08/13] MIPS: ath25: add SoC type detection Sergey Ryazanov
2014-10-21 23:03 ` [PATCH v2 09/13] MIPS: ath25: register various chip devices Sergey Ryazanov
2014-10-22 8:39 ` John Crispin
2014-10-22 15:22 ` Sergey Ryazanov
2014-10-21 23:03 ` [PATCH v2 10/13] MIPS: ath25: add AR2315 PCI host controller driver Sergey Ryazanov
2014-10-22 8:47 ` John Crispin
2014-10-22 15:25 ` Sergey Ryazanov
2014-10-21 23:03 ` [PATCH v2 11/13] ath5k: revert AHB bus support removing Sergey Ryazanov
2014-10-22 12:18 ` Bob Copeland
2014-10-22 12:37 ` Sergey Ryazanov
2014-10-27 18:04 ` John W. Linville
2014-10-28 7:08 ` Sergey Ryazanov
2014-10-28 13:48 ` John W. Linville
2014-10-21 23:03 ` [PATCH v2 12/13] ath5k: update dependencies Sergey Ryazanov
2014-10-27 18:05 ` John W. Linville
2014-10-21 23:03 ` [PATCH v2 13/13] MIPS: ath25: add Wireless device support Sergey Ryazanov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=54476A46.4050006@openwrt.org \
--to=blogic@openwrt.org \
--cc=linux-mips@linux-mips.org \
--cc=ralf@linux-mips.org \
--cc=ryazanov.s.a@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.