162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * linux/arch/sh/boards/renesas/rts7751r2d/irq.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2007  Magnus Damm
662306a36Sopenharmony_ci * Copyright (C) 2000  Kazumoto Kojima
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * Renesas Technology Sales RTS7751R2D Support, R2D-PLUS and R2D-1.
962306a36Sopenharmony_ci *
1062306a36Sopenharmony_ci * Modified for RTS7751R2D by
1162306a36Sopenharmony_ci * Atom Create Engineering Co., Ltd. 2002.
1262306a36Sopenharmony_ci */
1362306a36Sopenharmony_ci#include <linux/init.h>
1462306a36Sopenharmony_ci#include <linux/irq.h>
1562306a36Sopenharmony_ci#include <linux/interrupt.h>
1662306a36Sopenharmony_ci#include <linux/io.h>
1762306a36Sopenharmony_ci#include <mach/r2d.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#define R2D_NR_IRL 13
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_cienum {
2262306a36Sopenharmony_ci	UNUSED = 0,
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	/* board specific interrupt sources (R2D-1 and R2D-PLUS) */
2562306a36Sopenharmony_ci	EXT,              /* EXT_INT0-3 */
2662306a36Sopenharmony_ci	RTC_T, RTC_A,     /* Real Time Clock */
2762306a36Sopenharmony_ci	AX88796,          /* Ethernet controller (R2D-1 board) */
2862306a36Sopenharmony_ci	KEY,              /* Key input (R2D-PLUS board) */
2962306a36Sopenharmony_ci	SDCARD,           /* SD Card */
3062306a36Sopenharmony_ci	CF_CD, CF_IDE,    /* CF Card Detect + CF IDE */
3162306a36Sopenharmony_ci	SM501,            /* SM501 aka Voyager */
3262306a36Sopenharmony_ci	PCI_INTD_RTL8139, /* Ethernet controller */
3362306a36Sopenharmony_ci	PCI_INTC_PCI1520, /* Cardbus/PCMCIA bridge */
3462306a36Sopenharmony_ci	PCI_INTB_RTL8139, /* Ethernet controller with HUB (R2D-PLUS board) */
3562306a36Sopenharmony_ci	PCI_INTB_SLOT,    /* PCI Slot 3.3v (R2D-1 board) */
3662306a36Sopenharmony_ci	PCI_INTA_SLOT,    /* PCI Slot 3.3v */
3762306a36Sopenharmony_ci	TP,               /* Touch Panel */
3862306a36Sopenharmony_ci};
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci#ifdef CONFIG_RTS7751R2D_1
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci/* Vectors for R2D-1 */
4362306a36Sopenharmony_cistatic struct intc_vect vectors_r2d_1[] __initdata = {
4462306a36Sopenharmony_ci	INTC_IRQ(EXT, IRQ_EXT),
4562306a36Sopenharmony_ci	INTC_IRQ(RTC_T, IRQ_RTC_T), INTC_IRQ(RTC_A, IRQ_RTC_A),
4662306a36Sopenharmony_ci	INTC_IRQ(AX88796, IRQ_AX88796), INTC_IRQ(SDCARD, IRQ_SDCARD),
4762306a36Sopenharmony_ci	INTC_IRQ(CF_CD, IRQ_CF_CD), INTC_IRQ(CF_IDE, IRQ_CF_IDE), /* ng */
4862306a36Sopenharmony_ci	INTC_IRQ(SM501, IRQ_VOYAGER),
4962306a36Sopenharmony_ci	INTC_IRQ(PCI_INTD_RTL8139, IRQ_PCI_INTD),
5062306a36Sopenharmony_ci	INTC_IRQ(PCI_INTC_PCI1520, IRQ_PCI_INTC),
5162306a36Sopenharmony_ci	INTC_IRQ(PCI_INTB_SLOT, IRQ_PCI_INTB),
5262306a36Sopenharmony_ci	INTC_IRQ(PCI_INTA_SLOT, IRQ_PCI_INTA),
5362306a36Sopenharmony_ci	INTC_IRQ(TP, IRQ_TP),
5462306a36Sopenharmony_ci};
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci/* IRLMSK mask register layout for R2D-1 */
5762306a36Sopenharmony_cistatic struct intc_mask_reg mask_registers_r2d_1[] __initdata = {
5862306a36Sopenharmony_ci	{ 0xa4000000, 0, 16, /* IRLMSK */
5962306a36Sopenharmony_ci	  { TP, PCI_INTA_SLOT, PCI_INTB_SLOT,
6062306a36Sopenharmony_ci	    PCI_INTC_PCI1520, PCI_INTD_RTL8139,
6162306a36Sopenharmony_ci	    SM501, CF_IDE, CF_CD, SDCARD, AX88796,
6262306a36Sopenharmony_ci	    RTC_A, RTC_T, 0, 0, 0, EXT } },
6362306a36Sopenharmony_ci};
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci/* IRLn to IRQ table for R2D-1 */
6662306a36Sopenharmony_cistatic unsigned char irl2irq_r2d_1[R2D_NR_IRL] __initdata = {
6762306a36Sopenharmony_ci	IRQ_PCI_INTD, IRQ_CF_IDE, IRQ_CF_CD, IRQ_PCI_INTC,
6862306a36Sopenharmony_ci	IRQ_VOYAGER, IRQ_AX88796, IRQ_RTC_A, IRQ_RTC_T,
6962306a36Sopenharmony_ci	IRQ_SDCARD, IRQ_PCI_INTA, IRQ_PCI_INTB, IRQ_EXT,
7062306a36Sopenharmony_ci	IRQ_TP,
7162306a36Sopenharmony_ci};
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_cistatic DECLARE_INTC_DESC(intc_desc_r2d_1, "r2d-1", vectors_r2d_1,
7462306a36Sopenharmony_ci			 NULL, mask_registers_r2d_1, NULL, NULL);
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci#endif /* CONFIG_RTS7751R2D_1 */
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci#ifdef CONFIG_RTS7751R2D_PLUS
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci/* Vectors for R2D-PLUS */
8162306a36Sopenharmony_cistatic struct intc_vect vectors_r2d_plus[] __initdata = {
8262306a36Sopenharmony_ci	INTC_IRQ(EXT, IRQ_EXT),
8362306a36Sopenharmony_ci	INTC_IRQ(RTC_T, IRQ_RTC_T), INTC_IRQ(RTC_A, IRQ_RTC_A),
8462306a36Sopenharmony_ci	INTC_IRQ(KEY, IRQ_KEY), INTC_IRQ(SDCARD, IRQ_SDCARD),
8562306a36Sopenharmony_ci	INTC_IRQ(CF_CD, IRQ_CF_CD), INTC_IRQ(CF_IDE, IRQ_CF_IDE),
8662306a36Sopenharmony_ci	INTC_IRQ(SM501, IRQ_VOYAGER),
8762306a36Sopenharmony_ci	INTC_IRQ(PCI_INTD_RTL8139, IRQ_PCI_INTD),
8862306a36Sopenharmony_ci	INTC_IRQ(PCI_INTC_PCI1520, IRQ_PCI_INTC),
8962306a36Sopenharmony_ci	INTC_IRQ(PCI_INTB_RTL8139, IRQ_PCI_INTB),
9062306a36Sopenharmony_ci	INTC_IRQ(PCI_INTA_SLOT, IRQ_PCI_INTA),
9162306a36Sopenharmony_ci	INTC_IRQ(TP, IRQ_TP),
9262306a36Sopenharmony_ci};
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci/* IRLMSK mask register layout for R2D-PLUS */
9562306a36Sopenharmony_cistatic struct intc_mask_reg mask_registers_r2d_plus[] __initdata = {
9662306a36Sopenharmony_ci	{ 0xa4000000, 0, 16, /* IRLMSK */
9762306a36Sopenharmony_ci	  { TP, PCI_INTA_SLOT, PCI_INTB_RTL8139,
9862306a36Sopenharmony_ci	    PCI_INTC_PCI1520, PCI_INTD_RTL8139,
9962306a36Sopenharmony_ci	    SM501, CF_IDE, CF_CD, SDCARD, KEY,
10062306a36Sopenharmony_ci	    RTC_A, RTC_T, 0, 0, 0, EXT } },
10162306a36Sopenharmony_ci};
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci/* IRLn to IRQ table for R2D-PLUS */
10462306a36Sopenharmony_cistatic unsigned char irl2irq_r2d_plus[R2D_NR_IRL] __initdata = {
10562306a36Sopenharmony_ci	IRQ_PCI_INTD, IRQ_CF_IDE, IRQ_CF_CD, IRQ_PCI_INTC,
10662306a36Sopenharmony_ci	IRQ_VOYAGER, IRQ_KEY, IRQ_RTC_A, IRQ_RTC_T,
10762306a36Sopenharmony_ci	IRQ_SDCARD, IRQ_PCI_INTA, IRQ_PCI_INTB, IRQ_EXT,
10862306a36Sopenharmony_ci	IRQ_TP,
10962306a36Sopenharmony_ci};
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_cistatic DECLARE_INTC_DESC(intc_desc_r2d_plus, "r2d-plus", vectors_r2d_plus,
11262306a36Sopenharmony_ci			 NULL, mask_registers_r2d_plus, NULL, NULL);
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci#endif /* CONFIG_RTS7751R2D_PLUS */
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_cistatic unsigned char irl2irq[R2D_NR_IRL];
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ciint rts7751r2d_irq_demux(int irq)
11962306a36Sopenharmony_ci{
12062306a36Sopenharmony_ci	if (irq >= R2D_NR_IRL + 16 || irq < 16 || !irl2irq[irq - 16])
12162306a36Sopenharmony_ci		return irq;
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci	return irl2irq[irq - 16];
12462306a36Sopenharmony_ci}
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci/*
12762306a36Sopenharmony_ci * Initialize IRQ setting
12862306a36Sopenharmony_ci */
12962306a36Sopenharmony_civoid __init init_rts7751r2d_IRQ(void)
13062306a36Sopenharmony_ci{
13162306a36Sopenharmony_ci	struct intc_desc *d;
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci	switch (__raw_readw(PA_VERREG) & 0xf0) {
13462306a36Sopenharmony_ci#ifdef CONFIG_RTS7751R2D_PLUS
13562306a36Sopenharmony_ci	case 0x10:
13662306a36Sopenharmony_ci		printk(KERN_INFO "Using R2D-PLUS interrupt controller.\n");
13762306a36Sopenharmony_ci		d = &intc_desc_r2d_plus;
13862306a36Sopenharmony_ci		memcpy(irl2irq, irl2irq_r2d_plus, R2D_NR_IRL);
13962306a36Sopenharmony_ci		break;
14062306a36Sopenharmony_ci#endif
14162306a36Sopenharmony_ci#ifdef CONFIG_RTS7751R2D_1
14262306a36Sopenharmony_ci	case 0x00: /* according to manual */
14362306a36Sopenharmony_ci	case 0x30: /* in reality */
14462306a36Sopenharmony_ci		printk(KERN_INFO "Using R2D-1 interrupt controller.\n");
14562306a36Sopenharmony_ci		d = &intc_desc_r2d_1;
14662306a36Sopenharmony_ci		memcpy(irl2irq, irl2irq_r2d_1, R2D_NR_IRL);
14762306a36Sopenharmony_ci		break;
14862306a36Sopenharmony_ci#endif
14962306a36Sopenharmony_ci	default:
15062306a36Sopenharmony_ci		printk(KERN_INFO "Unknown R2D interrupt controller 0x%04x\n",
15162306a36Sopenharmony_ci		       __raw_readw(PA_VERREG));
15262306a36Sopenharmony_ci		return;
15362306a36Sopenharmony_ci	}
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci	register_intc_controller(d);
15662306a36Sopenharmony_ci}
157