Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Copyright 2001, 2007-2008 MontaVista Software Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Author: MontaVista Software, Inc. <source@mvista.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *  This program is free software; you can redistribute	 it and/or modify it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *  under  the terms of	 the GNU General  Public License as published by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *  Free Software Foundation;  either version 2 of the	License, or (at your
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *  option) any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *  THIS  SOFTWARE  IS PROVIDED	  ``AS	IS'' AND   ANY	EXPRESS OR IMPLIED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *  WARRANTIES,	  INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *  NO	EVENT  SHALL   THE AUTHOR  BE	 LIABLE FOR ANY	  DIRECT, INDIRECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  *  NOT LIMITED	  TO, PROCUREMENT OF  SUBSTITUTE GOODS	OR SERVICES; LOSS OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  *  USE, DATA,	OR PROFITS; OR	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *  ANY THEORY OF LIABILITY, WHETHER IN	 CONTRACT, STRICT LIABILITY, OR TORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  *  You should have received a copy of the  GNU General Public License along
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  *  with this program; if not, write  to the Free Software Foundation, Inc.,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  *  675 Mass Ave, Cambridge, MA 02139, USA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include <linux/syscore_ops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include <asm/irq_cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #include <asm/mach-au1x00/au1000.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include <asm/mach-au1x00/gpio-au1300.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) /* Interrupt Controller register offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define IC_CFG0RD	0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define IC_CFG0SET	0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define IC_CFG0CLR	0x44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define IC_CFG1RD	0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define IC_CFG1SET	0x48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define IC_CFG1CLR	0x4C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define IC_CFG2RD	0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define IC_CFG2SET	0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define IC_CFG2CLR	0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define IC_REQ0INT	0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define IC_SRCRD	0x58
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define IC_SRCSET	0x58
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define IC_SRCCLR	0x5C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define IC_REQ1INT	0x5C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define IC_ASSIGNRD	0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define IC_ASSIGNSET	0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define IC_ASSIGNCLR	0x64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define IC_WAKERD	0x68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define IC_WAKESET	0x68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define IC_WAKECLR	0x6C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define IC_MASKRD	0x70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #define IC_MASKSET	0x70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define IC_MASKCLR	0x74
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #define IC_RISINGRD	0x78
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #define IC_RISINGCLR	0x78
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #define IC_FALLINGRD	0x7C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #define IC_FALLINGCLR	0x7C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #define IC_TESTBIT	0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) /* per-processor fixed function irqs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) struct alchemy_irqmap {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	int irq;	/* linux IRQ number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	int type;	/* IRQ_TYPE_ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	int prio;	/* irq priority, 0 highest, 3 lowest */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	int internal;	/* GPIC: internal source (no ext. pin)? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) static int au1x_ic_settype(struct irq_data *d, unsigned int type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) static int au1300_gpic_settype(struct irq_data *d, unsigned int type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) /* NOTE on interrupt priorities: The original writers of this code said:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  * Because of the tight timing of SETUP token to reply transactions,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  * the USB devices-side packet complete interrupt (USB_DEV_REQ_INT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  * needs the highest priority.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) struct alchemy_irqmap au1000_irqmap[] __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	{ AU1000_UART0_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	{ AU1000_UART1_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	{ AU1000_UART2_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	{ AU1000_UART3_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	{ AU1000_SSI0_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	{ AU1000_SSI1_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	{ AU1000_DMA_INT_BASE,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	{ AU1000_DMA_INT_BASE+1,  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	{ AU1000_DMA_INT_BASE+2,  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	{ AU1000_DMA_INT_BASE+3,  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	{ AU1000_DMA_INT_BASE+4,  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	{ AU1000_DMA_INT_BASE+5,  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	{ AU1000_DMA_INT_BASE+6,  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	{ AU1000_DMA_INT_BASE+7,  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	{ AU1000_TOY_INT,	  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	{ AU1000_TOY_MATCH0_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	{ AU1000_TOY_MATCH1_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	{ AU1000_TOY_MATCH2_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	{ AU1000_RTC_INT,	  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	{ AU1000_RTC_MATCH0_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	{ AU1000_RTC_MATCH1_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	{ AU1000_RTC_MATCH2_INT,  IRQ_TYPE_EDGE_RISING, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	{ AU1000_IRDA_TX_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	{ AU1000_IRDA_RX_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	{ AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH,	0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	{ AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	{ AU1000_USB_HOST_INT,	  IRQ_TYPE_LEVEL_LOW,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	{ AU1000_ACSYNC_INT,	  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	{ AU1000_MAC0_DMA_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	{ AU1000_MAC1_DMA_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	{ AU1000_AC97C_INT,	  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	{ -1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct alchemy_irqmap au1500_irqmap[] __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	{ AU1500_UART0_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	{ AU1500_PCI_INTA,	  IRQ_TYPE_LEVEL_LOW,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	{ AU1500_PCI_INTB,	  IRQ_TYPE_LEVEL_LOW,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	{ AU1500_UART3_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	{ AU1500_PCI_INTC,	  IRQ_TYPE_LEVEL_LOW,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	{ AU1500_PCI_INTD,	  IRQ_TYPE_LEVEL_LOW,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	{ AU1500_DMA_INT_BASE,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	{ AU1500_DMA_INT_BASE+1,  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	{ AU1500_DMA_INT_BASE+2,  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	{ AU1500_DMA_INT_BASE+3,  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	{ AU1500_DMA_INT_BASE+4,  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	{ AU1500_DMA_INT_BASE+5,  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	{ AU1500_DMA_INT_BASE+6,  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	{ AU1500_DMA_INT_BASE+7,  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	{ AU1500_TOY_INT,	  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	{ AU1500_TOY_MATCH0_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	{ AU1500_TOY_MATCH1_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	{ AU1500_TOY_MATCH2_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	{ AU1500_RTC_INT,	  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	{ AU1500_RTC_MATCH0_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	{ AU1500_RTC_MATCH1_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	{ AU1500_RTC_MATCH2_INT,  IRQ_TYPE_EDGE_RISING, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	{ AU1500_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH,	0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	{ AU1500_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	{ AU1500_USB_HOST_INT,	  IRQ_TYPE_LEVEL_LOW,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	{ AU1500_ACSYNC_INT,	  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	{ AU1500_MAC0_DMA_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	{ AU1500_MAC1_DMA_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	{ AU1500_AC97C_INT,	  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	{ -1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct alchemy_irqmap au1100_irqmap[] __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	{ AU1100_UART0_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	{ AU1100_UART1_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	{ AU1100_SD_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	{ AU1100_UART3_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	{ AU1100_SSI0_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	{ AU1100_SSI1_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	{ AU1100_DMA_INT_BASE,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	{ AU1100_DMA_INT_BASE+1,  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	{ AU1100_DMA_INT_BASE+2,  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	{ AU1100_DMA_INT_BASE+3,  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	{ AU1100_DMA_INT_BASE+4,  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	{ AU1100_DMA_INT_BASE+5,  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	{ AU1100_DMA_INT_BASE+6,  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	{ AU1100_DMA_INT_BASE+7,  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	{ AU1100_TOY_INT,	  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	{ AU1100_TOY_MATCH0_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	{ AU1100_TOY_MATCH1_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	{ AU1100_TOY_MATCH2_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	{ AU1100_RTC_INT,	  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	{ AU1100_RTC_MATCH0_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	{ AU1100_RTC_MATCH1_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	{ AU1100_RTC_MATCH2_INT,  IRQ_TYPE_EDGE_RISING, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	{ AU1100_IRDA_TX_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	{ AU1100_IRDA_RX_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	{ AU1100_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH,	0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	{ AU1100_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	{ AU1100_USB_HOST_INT,	  IRQ_TYPE_LEVEL_LOW,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	{ AU1100_ACSYNC_INT,	  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	{ AU1100_MAC0_DMA_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	{ AU1100_LCD_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	{ AU1100_AC97C_INT,	  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	{ -1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct alchemy_irqmap au1550_irqmap[] __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	{ AU1550_UART0_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	{ AU1550_PCI_INTA,	  IRQ_TYPE_LEVEL_LOW,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	{ AU1550_PCI_INTB,	  IRQ_TYPE_LEVEL_LOW,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	{ AU1550_DDMA_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	{ AU1550_CRYPTO_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	{ AU1550_PCI_INTC,	  IRQ_TYPE_LEVEL_LOW,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	{ AU1550_PCI_INTD,	  IRQ_TYPE_LEVEL_LOW,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	{ AU1550_PCI_RST_INT,	  IRQ_TYPE_LEVEL_LOW,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	{ AU1550_UART1_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	{ AU1550_UART3_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	{ AU1550_PSC0_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	{ AU1550_PSC1_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	{ AU1550_PSC2_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	{ AU1550_PSC3_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	{ AU1550_TOY_INT,	  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	{ AU1550_TOY_MATCH0_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	{ AU1550_TOY_MATCH1_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	{ AU1550_TOY_MATCH2_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	{ AU1550_RTC_INT,	  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	{ AU1550_RTC_MATCH0_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	{ AU1550_RTC_MATCH1_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	{ AU1550_RTC_MATCH2_INT,  IRQ_TYPE_EDGE_RISING, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	{ AU1550_NAND_INT,	  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	{ AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH,	0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	{ AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	{ AU1550_USB_HOST_INT,	  IRQ_TYPE_LEVEL_LOW,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	{ AU1550_MAC0_DMA_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	{ AU1550_MAC1_DMA_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	{ -1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct alchemy_irqmap au1200_irqmap[] __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	{ AU1200_UART0_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	{ AU1200_SWT_INT,	  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	{ AU1200_SD_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	{ AU1200_DDMA_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	{ AU1200_MAE_BE_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	{ AU1200_UART1_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	{ AU1200_MAE_FE_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	{ AU1200_PSC0_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	{ AU1200_PSC1_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	{ AU1200_AES_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	{ AU1200_CAMERA_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	{ AU1200_TOY_INT,	  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	{ AU1200_TOY_MATCH0_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	{ AU1200_TOY_MATCH1_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	{ AU1200_TOY_MATCH2_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	{ AU1200_RTC_INT,	  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	{ AU1200_RTC_MATCH0_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	{ AU1200_RTC_MATCH1_INT,  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	{ AU1200_RTC_MATCH2_INT,  IRQ_TYPE_EDGE_RISING, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	{ AU1200_NAND_INT,	  IRQ_TYPE_EDGE_RISING, 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	{ AU1200_USB_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	{ AU1200_LCD_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	{ AU1200_MAE_BOTH_INT,	  IRQ_TYPE_LEVEL_HIGH,	1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	{ -1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static struct alchemy_irqmap au1300_irqmap[] __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	/* multifunction: gpio pin or device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	{ AU1300_UART1_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	{ AU1300_UART2_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	{ AU1300_UART3_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	{ AU1300_SD1_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	{ AU1300_SD2_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	{ AU1300_PSC0_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	{ AU1300_PSC1_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	{ AU1300_PSC2_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	{ AU1300_PSC3_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	{ AU1300_NAND_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	/* au1300 internal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	{ AU1300_DDMA_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	{ AU1300_MMU_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	{ AU1300_MPU_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	{ AU1300_GPU_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	{ AU1300_UDMA_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	{ AU1300_TOY_INT,	 IRQ_TYPE_EDGE_RISING,	1, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	{ AU1300_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING,	1, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	{ AU1300_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING,	1, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	{ AU1300_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING,	1, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	{ AU1300_RTC_INT,	 IRQ_TYPE_EDGE_RISING,	1, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	{ AU1300_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING,	1, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	{ AU1300_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING,	1, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	{ AU1300_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING,	0, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	{ AU1300_UART0_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	{ AU1300_SD0_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	{ AU1300_USB_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	{ AU1300_LCD_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	{ AU1300_BSA_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	{ AU1300_MPE_INT,	 IRQ_TYPE_EDGE_RISING,	1, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	{ AU1300_ITE_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	{ AU1300_AES_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	{ AU1300_CIM_INT,	 IRQ_TYPE_LEVEL_HIGH,	1, 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	{ -1, },	/* terminator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) /******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static void au1x_ic0_unmask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	__raw_writel(1 << bit, base + IC_MASKSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	__raw_writel(1 << bit, base + IC_WAKESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static void au1x_ic1_unmask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	__raw_writel(1 << bit, base + IC_MASKSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	__raw_writel(1 << bit, base + IC_WAKESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static void au1x_ic0_mask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	__raw_writel(1 << bit, base + IC_MASKCLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	__raw_writel(1 << bit, base + IC_WAKECLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static void au1x_ic1_mask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	__raw_writel(1 << bit, base + IC_MASKCLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	__raw_writel(1 << bit, base + IC_WAKECLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static void au1x_ic0_ack(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	 * This may assume that we don't get interrupts from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	 * both edges at once, or if we do, that we don't care.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	__raw_writel(1 << bit, base + IC_FALLINGCLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	__raw_writel(1 << bit, base + IC_RISINGCLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static void au1x_ic1_ack(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	 * This may assume that we don't get interrupts from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	 * both edges at once, or if we do, that we don't care.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	__raw_writel(1 << bit, base + IC_FALLINGCLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	__raw_writel(1 << bit, base + IC_RISINGCLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) static void au1x_ic0_maskack(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	__raw_writel(1 << bit, base + IC_WAKECLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	__raw_writel(1 << bit, base + IC_MASKCLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	__raw_writel(1 << bit, base + IC_RISINGCLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	__raw_writel(1 << bit, base + IC_FALLINGCLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) static void au1x_ic1_maskack(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	__raw_writel(1 << bit, base + IC_WAKECLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	__raw_writel(1 << bit, base + IC_MASKCLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	__raw_writel(1 << bit, base + IC_RISINGCLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	__raw_writel(1 << bit, base + IC_FALLINGCLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) static int au1x_ic1_setwake(struct irq_data *d, unsigned int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	int bit = d->irq - AU1000_INTC1_INT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	unsigned long wakemsk, flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	/* only GPIO 0-7 can act as wakeup source.  Fortunately these
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	 * are wired up identically on all supported variants.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	if ((bit < 0) || (bit > 7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	wakemsk = alchemy_rdsys(AU1000_SYS_WAKEMSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	if (on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		wakemsk |= 1 << bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		wakemsk &= ~(1 << bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	alchemy_wrsys(wakemsk, AU1000_SYS_WAKEMSK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)  * irq_chips for both ICs; this way the mask handlers can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)  * as short as possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static struct irq_chip au1x_ic0_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	.name		= "Alchemy-IC0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	.irq_ack	= au1x_ic0_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	.irq_mask	= au1x_ic0_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	.irq_mask_ack	= au1x_ic0_maskack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	.irq_unmask	= au1x_ic0_unmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	.irq_set_type	= au1x_ic_settype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) static struct irq_chip au1x_ic1_chip = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	.name		= "Alchemy-IC1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	.irq_ack	= au1x_ic1_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	.irq_mask	= au1x_ic1_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	.irq_mask_ack	= au1x_ic1_maskack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	.irq_unmask	= au1x_ic1_unmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	.irq_set_type	= au1x_ic_settype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	.irq_set_wake	= au1x_ic1_setwake,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	struct irq_chip *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	unsigned int bit, irq = d->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	irq_flow_handler_t handler = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	unsigned char *name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	if (irq >= AU1000_INTC1_INT_BASE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		bit = irq - AU1000_INTC1_INT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		chip = &au1x_ic1_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		bit = irq - AU1000_INTC0_INT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		chip = &au1x_ic0_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 		base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	if (bit > 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	switch (flow_type) {	/* cfgregs 2:1:0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	case IRQ_TYPE_EDGE_RISING:	/* 0:0:1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		__raw_writel(1 << bit, base + IC_CFG2CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 		__raw_writel(1 << bit, base + IC_CFG1CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		__raw_writel(1 << bit, base + IC_CFG0SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		handler = handle_edge_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		name = "riseedge";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	case IRQ_TYPE_EDGE_FALLING:	/* 0:1:0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 		__raw_writel(1 << bit, base + IC_CFG2CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		__raw_writel(1 << bit, base + IC_CFG1SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		__raw_writel(1 << bit, base + IC_CFG0CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		handler = handle_edge_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		name = "falledge";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	case IRQ_TYPE_EDGE_BOTH:	/* 0:1:1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		__raw_writel(1 << bit, base + IC_CFG2CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		__raw_writel(1 << bit, base + IC_CFG1SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		__raw_writel(1 << bit, base + IC_CFG0SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		handler = handle_edge_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		name = "bothedge";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	case IRQ_TYPE_LEVEL_HIGH:	/* 1:0:1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		__raw_writel(1 << bit, base + IC_CFG2SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		__raw_writel(1 << bit, base + IC_CFG1CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		__raw_writel(1 << bit, base + IC_CFG0SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		handler = handle_level_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 		name = "hilevel";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	case IRQ_TYPE_LEVEL_LOW:	/* 1:1:0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		__raw_writel(1 << bit, base + IC_CFG2SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		__raw_writel(1 << bit, base + IC_CFG1SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 		__raw_writel(1 << bit, base + IC_CFG0CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		handler = handle_level_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 		name = "lowlevel";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	case IRQ_TYPE_NONE:		/* 0:0:0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		__raw_writel(1 << bit, base + IC_CFG2CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		__raw_writel(1 << bit, base + IC_CFG1CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 		__raw_writel(1 << bit, base + IC_CFG0CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	irq_set_chip_handler_name_locked(d, chip, handler, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) /******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)  * au1300_gpic_chgcfg - change PIN configuration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)  * @gpio:	pin to change (0-based GPIO number from datasheet).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)  * @clr:	clear all bits set in 'clr'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)  * @set:	set these bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)  * modifies a pins' configuration register, bits set in @clr will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)  * be cleared in the register, bits in @set will be set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static inline void au1300_gpic_chgcfg(unsigned int gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 				      unsigned long clr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 				      unsigned long set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	void __iomem *r = AU1300_GPIC_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	unsigned long l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	r += gpio * 4;	/* offset into pin config array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	l = __raw_readl(r + AU1300_GPIC_PINCFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	l &= ~clr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	l |= set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	__raw_writel(l, r + AU1300_GPIC_PINCFG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)  * au1300_pinfunc_to_gpio - assign a pin as GPIO input (GPIO ctrl).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)  * @pin:	pin (0-based GPIO number from datasheet).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)  * Assigns a GPIO pin to the GPIO controller, so its level can either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)  * be read or set through the generic GPIO functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)  * If you need a GPOUT, use au1300_gpio_set_value(pin, 0/1).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)  * REVISIT: is this function really necessary?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) void au1300_pinfunc_to_gpio(enum au1300_multifunc_pins gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	au1300_gpio_direction_input(gpio + AU1300_GPIO_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) EXPORT_SYMBOL_GPL(au1300_pinfunc_to_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)  * au1300_pinfunc_to_dev - assign a pin to the device function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)  * @pin:	pin (0-based GPIO number from datasheet).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)  * Assigns a GPIO pin to its associated device function; the pin will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)  * driven by the device and not through GPIO functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) void au1300_pinfunc_to_dev(enum au1300_multifunc_pins gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	void __iomem *r = AU1300_GPIC_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	unsigned long bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	r += GPIC_GPIO_BANKOFF(gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	bit = GPIC_GPIO_TO_BIT(gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	__raw_writel(bit, r + AU1300_GPIC_DEVSEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) EXPORT_SYMBOL_GPL(au1300_pinfunc_to_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)  * au1300_set_irq_priority -  set internal priority of IRQ.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)  * @irq:	irq to set priority (linux irq number).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)  * @p:		priority (0 = highest, 3 = lowest).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) void au1300_set_irq_priority(unsigned int irq, int p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	irq -= ALCHEMY_GPIC_INT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	au1300_gpic_chgcfg(irq, GPIC_CFG_IL_MASK, GPIC_CFG_IL_SET(p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) EXPORT_SYMBOL_GPL(au1300_set_irq_priority);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)  * au1300_set_dbdma_gpio - assign a gpio to one of the DBDMA triggers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)  * @dchan:	dbdma trigger select (0, 1).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)  * @gpio:	pin to assign as trigger.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)  * DBDMA controller has 2 external trigger sources; this function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)  * assigns a GPIO to the selected trigger.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) void au1300_set_dbdma_gpio(int dchan, unsigned int gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	unsigned long r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	if ((dchan >= 0) && (dchan <= 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 		r = __raw_readl(AU1300_GPIC_ADDR + AU1300_GPIC_DMASEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 		r &= ~(0xff << (8 * dchan));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 		r |= (gpio & 0x7f) << (8 * dchan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 		__raw_writel(r, AU1300_GPIC_ADDR + AU1300_GPIC_DMASEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 		wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) static inline void gpic_pin_set_idlewake(unsigned int gpio, int allow)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	au1300_gpic_chgcfg(gpio, GPIC_CFG_IDLEWAKE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 			   allow ? GPIC_CFG_IDLEWAKE : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) static void au1300_gpic_mask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	void __iomem *r = AU1300_GPIC_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	unsigned long bit, irq = d->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	irq -= ALCHEMY_GPIC_INT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	r += GPIC_GPIO_BANKOFF(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	bit = GPIC_GPIO_TO_BIT(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	__raw_writel(bit, r + AU1300_GPIC_IDIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	gpic_pin_set_idlewake(irq, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) static void au1300_gpic_unmask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	void __iomem *r = AU1300_GPIC_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	unsigned long bit, irq = d->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	irq -= ALCHEMY_GPIC_INT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	gpic_pin_set_idlewake(irq, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	r += GPIC_GPIO_BANKOFF(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	bit = GPIC_GPIO_TO_BIT(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	__raw_writel(bit, r + AU1300_GPIC_IEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) static void au1300_gpic_maskack(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	void __iomem *r = AU1300_GPIC_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	unsigned long bit, irq = d->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	irq -= ALCHEMY_GPIC_INT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	r += GPIC_GPIO_BANKOFF(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	bit = GPIC_GPIO_TO_BIT(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	__raw_writel(bit, r + AU1300_GPIC_IPEND);	/* ack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	__raw_writel(bit, r + AU1300_GPIC_IDIS);	/* mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	gpic_pin_set_idlewake(irq, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) static void au1300_gpic_ack(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	void __iomem *r = AU1300_GPIC_ADDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	unsigned long bit, irq = d->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	irq -= ALCHEMY_GPIC_INT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	r += GPIC_GPIO_BANKOFF(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	bit = GPIC_GPIO_TO_BIT(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	__raw_writel(bit, r + AU1300_GPIC_IPEND);	/* ack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) static struct irq_chip au1300_gpic = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	.name		= "GPIOINT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	.irq_ack	= au1300_gpic_ack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	.irq_mask	= au1300_gpic_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	.irq_mask_ack	= au1300_gpic_maskack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	.irq_unmask	= au1300_gpic_unmask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	.irq_set_type	= au1300_gpic_settype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) static int au1300_gpic_settype(struct irq_data *d, unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	unsigned long s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 	unsigned char *name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 	irq_flow_handler_t hdl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	case IRQ_TYPE_LEVEL_HIGH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 		s = GPIC_CFG_IC_LEVEL_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 		name = "high";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 		hdl = handle_level_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	case IRQ_TYPE_LEVEL_LOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 		s = GPIC_CFG_IC_LEVEL_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 		name = "low";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 		hdl = handle_level_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	case IRQ_TYPE_EDGE_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 		s = GPIC_CFG_IC_EDGE_RISE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 		name = "posedge";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 		hdl = handle_edge_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	case IRQ_TYPE_EDGE_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 		s = GPIC_CFG_IC_EDGE_FALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 		name = "negedge";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 		hdl = handle_edge_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	case IRQ_TYPE_EDGE_BOTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 		s = GPIC_CFG_IC_EDGE_BOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 		name = "bothedge";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 		hdl = handle_edge_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	case IRQ_TYPE_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 		s = GPIC_CFG_IC_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 		name = "disabled";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 		hdl = handle_level_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	irq_set_chip_handler_name_locked(d, &au1300_gpic, hdl, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	au1300_gpic_chgcfg(d->irq - ALCHEMY_GPIC_INT_BASE, GPIC_CFG_IC_MASK, s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) /******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) static inline void ic_init(void __iomem *base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	/* initialize interrupt controller to a safe state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	__raw_writel(0xffffffff, base + IC_CFG0CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	__raw_writel(0xffffffff, base + IC_CFG1CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	__raw_writel(0xffffffff, base + IC_CFG2CLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	__raw_writel(0xffffffff, base + IC_MASKCLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 	__raw_writel(0xffffffff, base + IC_ASSIGNCLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	__raw_writel(0xffffffff, base + IC_WAKECLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	__raw_writel(0xffffffff, base + IC_SRCSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	__raw_writel(0xffffffff, base + IC_FALLINGCLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	__raw_writel(0xffffffff, base + IC_RISINGCLR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 	__raw_writel(0x00000000, base + IC_TESTBIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) static unsigned long alchemy_gpic_pmdata[ALCHEMY_GPIC_INT_NUM + 6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) static inline void alchemy_ic_suspend_one(void __iomem *base, unsigned long *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	d[0] = __raw_readl(base + IC_CFG0RD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	d[1] = __raw_readl(base + IC_CFG1RD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	d[2] = __raw_readl(base + IC_CFG2RD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	d[3] = __raw_readl(base + IC_SRCRD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 	d[4] = __raw_readl(base + IC_ASSIGNRD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	d[5] = __raw_readl(base + IC_WAKERD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 	d[6] = __raw_readl(base + IC_MASKRD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	ic_init(base);		/* shut it up too while at it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) static inline void alchemy_ic_resume_one(void __iomem *base, unsigned long *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	ic_init(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	__raw_writel(d[0], base + IC_CFG0SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	__raw_writel(d[1], base + IC_CFG1SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 	__raw_writel(d[2], base + IC_CFG2SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 	__raw_writel(d[3], base + IC_SRCSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 	__raw_writel(d[4], base + IC_ASSIGNSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 	__raw_writel(d[5], base + IC_WAKESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	__raw_writel(d[6], base + IC_MASKSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) static int alchemy_ic_suspend(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 	alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 			       alchemy_gpic_pmdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 	alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 			       &alchemy_gpic_pmdata[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) static void alchemy_ic_resume(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 	alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 			      &alchemy_gpic_pmdata[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 	alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 			      alchemy_gpic_pmdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) static int alchemy_gpic_suspend(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1300_GPIC_PHYS_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 	/* save 4 interrupt mask status registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 	alchemy_gpic_pmdata[0] = __raw_readl(base + AU1300_GPIC_IEN + 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 	alchemy_gpic_pmdata[1] = __raw_readl(base + AU1300_GPIC_IEN + 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 	alchemy_gpic_pmdata[2] = __raw_readl(base + AU1300_GPIC_IEN + 0x8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 	alchemy_gpic_pmdata[3] = __raw_readl(base + AU1300_GPIC_IEN + 0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 	/* save misc register(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 	alchemy_gpic_pmdata[4] = __raw_readl(base + AU1300_GPIC_DMASEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 	/* molto silenzioso */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 	__raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 	__raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 	__raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 	__raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 	/* save pin/int-type configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 	base += AU1300_GPIC_PINCFG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 	for (i = 0; i < ALCHEMY_GPIC_INT_NUM; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 		alchemy_gpic_pmdata[i + 5] = __raw_readl(base + (i << 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) static void alchemy_gpic_resume(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1300_GPIC_PHYS_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 	/* disable all first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 	__raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 	__raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 	__raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 	__raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 	/* restore pin/int-type configurations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 	base += AU1300_GPIC_PINCFG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 	for (i = 0; i < ALCHEMY_GPIC_INT_NUM; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 		__raw_writel(alchemy_gpic_pmdata[i + 5], base + (i << 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 	/* restore misc register(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 	base = (void __iomem *)KSEG1ADDR(AU1300_GPIC_PHYS_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 	__raw_writel(alchemy_gpic_pmdata[4], base + AU1300_GPIC_DMASEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 	/* finally restore masks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 	__raw_writel(alchemy_gpic_pmdata[0], base + AU1300_GPIC_IEN + 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 	__raw_writel(alchemy_gpic_pmdata[1], base + AU1300_GPIC_IEN + 0x4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 	__raw_writel(alchemy_gpic_pmdata[2], base + AU1300_GPIC_IEN + 0x8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 	__raw_writel(alchemy_gpic_pmdata[3], base + AU1300_GPIC_IEN + 0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 	wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) static struct syscore_ops alchemy_ic_pmops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 	.suspend	= alchemy_ic_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 	.resume		= alchemy_ic_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) static struct syscore_ops alchemy_gpic_pmops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 	.suspend	= alchemy_gpic_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 	.resume		= alchemy_gpic_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) /******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) /* create chained handlers for the 4 IC requests to the MIPS IRQ ctrl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) #define DISP(name, base, addr)						      \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) static void au1000_##name##_dispatch(struct irq_desc *d)		      \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) {									      \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 	unsigned long r = __raw_readl((void __iomem *)KSEG1ADDR(addr));	      \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 	if (likely(r))							      \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 		generic_handle_irq(base + __ffs(r));			      \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 	else								      \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 		spurious_interrupt();					      \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) DISP(ic0r0, AU1000_INTC0_INT_BASE, AU1000_IC0_PHYS_ADDR + IC_REQ0INT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) DISP(ic0r1, AU1000_INTC0_INT_BASE, AU1000_IC0_PHYS_ADDR + IC_REQ1INT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) DISP(ic1r0, AU1000_INTC1_INT_BASE, AU1000_IC1_PHYS_ADDR + IC_REQ0INT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) DISP(ic1r1, AU1000_INTC1_INT_BASE, AU1000_IC1_PHYS_ADDR + IC_REQ1INT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) static void alchemy_gpic_dispatch(struct irq_desc *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 	int i = __raw_readl(AU1300_GPIC_ADDR + AU1300_GPIC_PRIENC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 	generic_handle_irq(ALCHEMY_GPIC_INT_BASE + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) /******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) static void __init au1000_init_irq(struct alchemy_irqmap *map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 	unsigned int bit, irq_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 	void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 	ic_init((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 	ic_init((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) 	register_syscore_ops(&alchemy_ic_pmops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) 	mips_cpu_irq_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 	/* register all 64 possible IC0+IC1 irq sources as type "none".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) 	 * Use set_irq_type() to set edge/level behaviour at runtime.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) 	for (irq_nr = AU1000_INTC0_INT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) 	     (irq_nr < AU1000_INTC0_INT_BASE + 32); irq_nr++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) 		au1x_ic_settype(irq_get_irq_data(irq_nr), IRQ_TYPE_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) 	for (irq_nr = AU1000_INTC1_INT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) 	     (irq_nr < AU1000_INTC1_INT_BASE + 32); irq_nr++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) 		au1x_ic_settype(irq_get_irq_data(irq_nr), IRQ_TYPE_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) 	 * Initialize IC0, which is fixed per processor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) 	while (map->irq != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) 		irq_nr = map->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) 		if (irq_nr >= AU1000_INTC1_INT_BASE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) 			bit = irq_nr - AU1000_INTC1_INT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) 			base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) 			bit = irq_nr - AU1000_INTC0_INT_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) 			base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) 		if (map->prio == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) 			__raw_writel(1 << bit, base + IC_ASSIGNSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) 		au1x_ic_settype(irq_get_irq_data(irq_nr), map->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) 		++map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) 	irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 2, au1000_ic0r0_dispatch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 	irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 3, au1000_ic0r1_dispatch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) 	irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 4, au1000_ic1r0_dispatch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) 	irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 5, au1000_ic1r1_dispatch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) static void __init alchemy_gpic_init_irq(const struct alchemy_irqmap *dints)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) 	void __iomem *bank_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) 	register_syscore_ops(&alchemy_gpic_pmops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) 	mips_cpu_irq_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) 	/* disable & ack all possible interrupt sources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) 	for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) 		bank_base = AU1300_GPIC_ADDR + (i * 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) 		__raw_writel(~0UL, bank_base + AU1300_GPIC_IDIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) 		wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) 		__raw_writel(~0UL, bank_base + AU1300_GPIC_IPEND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) 		wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) 	/* register an irq_chip for them, with 2nd highest priority */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) 	for (i = ALCHEMY_GPIC_INT_BASE; i <= ALCHEMY_GPIC_INT_LAST; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) 		au1300_set_irq_priority(i, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) 		au1300_gpic_settype(irq_get_irq_data(i), IRQ_TYPE_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) 	/* setup known on-chip sources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) 	while ((i = dints->irq) != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) 		au1300_gpic_settype(irq_get_irq_data(i), dints->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) 		au1300_set_irq_priority(i, dints->prio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) 		if (dints->internal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) 			au1300_pinfunc_to_dev(i - ALCHEMY_GPIC_INT_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) 		dints++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) 	irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 2, alchemy_gpic_dispatch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) 	irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 3, alchemy_gpic_dispatch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) 	irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 4, alchemy_gpic_dispatch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) 	irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 5, alchemy_gpic_dispatch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) /******************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) void __init arch_init_irq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) 	switch (alchemy_get_cputype()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) 	case ALCHEMY_CPU_AU1000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) 		au1000_init_irq(au1000_irqmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) 	case ALCHEMY_CPU_AU1500:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) 		au1000_init_irq(au1500_irqmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) 	case ALCHEMY_CPU_AU1100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) 		au1000_init_irq(au1100_irqmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) 	case ALCHEMY_CPU_AU1550:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) 		au1000_init_irq(au1550_irqmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) 	case ALCHEMY_CPU_AU1200:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) 		au1000_init_irq(au1200_irqmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) 	case ALCHEMY_CPU_AU1300:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) 		alchemy_gpic_init_irq(au1300_irqmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) 		pr_err("unknown Alchemy IRQ core\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) asmlinkage void plat_irq_dispatch(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) 	unsigned long r = (read_c0_status() & read_c0_cause()) >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) 	do_IRQ(MIPS_CPU_IRQ_BASE + __ffs(r & 0xff));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }