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)  * PCIMT specific code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * License.  See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Copyright (C) 2006,2007 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/serial_8250.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <asm/sni.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <asm/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <asm/i8259.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <asm/irq_cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define cacheconf (*(volatile unsigned int *)PCIMT_CACHECONF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define invspace (*(volatile unsigned int *)PCIMT_INVSPACE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) static void __init sni_pcimt_sc_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	unsigned int scsiz, sc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	scsiz = cacheconf & 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	if (scsiz == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 		printk("Second level cache is deactivated.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	if (scsiz >= 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 		printk("Invalid second level cache size configured, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 		       "deactivating second level cache.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 		cacheconf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	sc_size = 128 << scsiz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	printk("%dkb second level cache detected, deactivating.\n", sc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	cacheconf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  * A bit more gossip about the iron we're running on ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) static inline void sni_pcimt_detect(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	char boardtype[80];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	unsigned char csmsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	char *p = boardtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	unsigned int asic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	csmsr = *(volatile unsigned char *)PCIMT_CSMSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	p += sprintf(p, "%s PCI", (csmsr & 0x80) ? "RM200" : "RM300");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	if ((csmsr & 0x80) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		p += sprintf(p, ", board revision %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 			     (csmsr & 0x20) ? "D" : "C");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	asic = csmsr & 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	asic = (csmsr & 0x08) ? asic : !asic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	p += sprintf(p, ", ASIC PCI Rev %s", asic ? "1.0" : "1.1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	printk("%s.\n", boardtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #define PORT(_base,_irq)				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	{						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		.iobase		= _base,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		.irq		= _irq,			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		.uartclk	= 1843200,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		.iotype		= UPIO_PORT,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		.flags		= UPF_BOOT_AUTOCONF,	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) static struct plat_serial8250_port pcimt_data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	PORT(0x3f8, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	PORT(0x2f8, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) static struct platform_device pcimt_serial8250_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	.name			= "serial8250",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	.id			= PLAT8250_DEV_PLATFORM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	.dev			= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		.platform_data	= pcimt_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) static struct resource pcimt_cmos_rsrc[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		.start = 0x70,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		.end   = 0x71,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		.flags = IORESOURCE_IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		.start = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		.end   = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		.flags = IORESOURCE_IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static struct platform_device pcimt_cmos_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	.name		= "rtc_cmos",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	.num_resources	= ARRAY_SIZE(pcimt_cmos_rsrc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	.resource	= pcimt_cmos_rsrc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static struct resource sni_io_resource = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	.start	= 0x00000000UL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	.end	= 0x03bfffffUL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	.name	= "PCIMT IO MEM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	.flags	= IORESOURCE_IO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static struct resource pcimt_io_resources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		.start	= 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		.end	= 0x1f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		.name	= "dma1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		.flags	= IORESOURCE_BUSY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		.start	=  0x40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		.end	= 0x5f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		.name	= "timer",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		.flags	= IORESOURCE_BUSY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		.start	=  0x60,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		.end	= 0x6f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		.name	= "keyboard",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		.flags	= IORESOURCE_BUSY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		.start	=  0x80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		.end	= 0x8f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		.name	= "dma page reg",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		.flags	= IORESOURCE_BUSY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		.start	=  0xc0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		.end	= 0xdf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		.name	= "dma2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		.flags	= IORESOURCE_BUSY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		.start	=  0xcfc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		.end	= 0xcff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		.name	= "PCI config data",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		.flags	= IORESOURCE_BUSY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	}
^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) static struct resource pcimt_mem_resources[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		 * this region should only be 4 bytes long,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		 * but it's 16MB on all RM300C I've checked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		.start	= 0x1a000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		.end	= 0x1affffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		.name	= "PCI INT ACK",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		.flags	= IORESOURCE_BUSY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static struct resource sni_mem_resource = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	.start	= 0x18000000UL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	.end	= 0x1fbfffffUL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	.name	= "PCIMT PCI MEM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	.flags	= IORESOURCE_MEM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static void __init sni_pcimt_resource_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	/* request I/O space for devices used on all i[345]86 PCs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	for (i = 0; i < ARRAY_SIZE(pcimt_io_resources); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		request_resource(&sni_io_resource, pcimt_io_resources + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	/* request MEM space for devices used on all i[345]86 PCs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	for (i = 0; i < ARRAY_SIZE(pcimt_mem_resources); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		request_resource(&sni_mem_resource, pcimt_mem_resources + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) extern struct pci_ops sni_pcimt_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) #ifdef CONFIG_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static struct pci_controller sni_controller = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	.pci_ops	= &sni_pcimt_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	.mem_resource	= &sni_mem_resource,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	.mem_offset	= 0x00000000UL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	.io_resource	= &sni_io_resource,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	.io_offset	= 0x00000000UL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	.io_map_base	= SNI_PORT_BASE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static void enable_pcimt_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	unsigned int mask = 1 << (d->irq - PCIMT_IRQ_INT2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	*(volatile u8 *) PCIMT_IRQSEL |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) void disable_pcimt_irq(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	unsigned int mask = ~(1 << (d->irq - PCIMT_IRQ_INT2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	*(volatile u8 *) PCIMT_IRQSEL &= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) static struct irq_chip pcimt_irq_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	.name = "PCIMT",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	.irq_mask = disable_pcimt_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	.irq_unmask = enable_pcimt_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)  * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)  * button interrupts.  Later ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static void pcimt_hwint0(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	panic("Received int0 but no handler yet ...");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)  * hwint 1 deals with EISA and SCSI interrupts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)  * The EISA_INT bit in CSITPEND is high active, all others are low active.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static void pcimt_hwint1(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	u8 pend = *(volatile char *)PCIMT_CSITPEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	if (pend & IT_EISA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		 * Note: ASIC PCI's builtin interrupt acknowledge feature is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		 * broken.  Using it may result in loss of some or all i8259
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		 * interrupts, so don't use PCIMT_INT_ACKNOWLEDGE ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		irq = i8259_irq();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		if (unlikely(irq < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		do_IRQ(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	if (!(pend & IT_SCSI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		flags = read_c0_status();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		clear_c0_status(ST0_IM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		do_IRQ(PCIMT_IRQ_SCSI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		write_c0_status(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)  * hwint 3 should deal with the PCI A - D interrupts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static void pcimt_hwint3(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	u8 pend = *(volatile char *)PCIMT_CSITPEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	pend &= (IT_INTA | IT_INTB | IT_INTC | IT_INTD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	pend ^= (IT_INTA | IT_INTB | IT_INTC | IT_INTD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	clear_c0_status(IE_IRQ3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	irq = PCIMT_IRQ_INT2 + ffs(pend) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	do_IRQ(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	set_c0_status(IE_IRQ3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static void sni_pcimt_hwint(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	u32 pending = read_c0_cause() & read_c0_status();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	if (pending & C_IRQ5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		do_IRQ(MIPS_CPU_IRQ_BASE + 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	else if (pending & C_IRQ4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		do_IRQ(MIPS_CPU_IRQ_BASE + 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	else if (pending & C_IRQ3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		pcimt_hwint3();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	else if (pending & C_IRQ1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		pcimt_hwint1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	else if (pending & C_IRQ0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		pcimt_hwint0();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) void __init sni_pcimt_irq_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	*(volatile u8 *) PCIMT_IRQSEL = IT_ETH | IT_EISA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	mips_cpu_irq_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	/* Actually we've got more interrupts to handle ...  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_SCSI; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		irq_set_chip_and_handler(i, &pcimt_irq_type, handle_level_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	sni_hwint = sni_pcimt_hwint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) void __init sni_pcimt_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	sni_pcimt_detect();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	sni_pcimt_sc_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	ioport_resource.end = sni_io_resource.end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) #ifdef CONFIG_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	PCIBIOS_MIN_IO = 0x9000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	register_pci_controller(&sni_controller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	sni_pcimt_resource_init();
^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 int __init snirm_pcimt_setup_devinit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	switch (sni_brd_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	case SNI_BRD_PCI_MTOWER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	case SNI_BRD_PCI_DESKTOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	case SNI_BRD_PCI_MTOWER_CPLUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		platform_device_register(&pcimt_serial8250_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		platform_device_register(&pcimt_cmos_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) device_initcall(snirm_pcimt_setup_devinit);