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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox