Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * PCI Tower specific code
0003  *
0004  * This file is subject to the terms and conditions of the GNU General Public
0005  * License.  See the file "COPYING" in the main directory of this archive
0006  * for more details.
0007  *
0008  * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
0009  */
0010 
0011 #include <linux/init.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/irq.h>
0014 #include <linux/pci.h>
0015 #include <linux/serial_8250.h>
0016 
0017 #include <asm/sni.h>
0018 #include <asm/time.h>
0019 #include <asm/irq_cpu.h>
0020 
0021 
0022 #define PORT(_base,_irq)                \
0023     {                       \
0024         .iobase     = _base,        \
0025         .irq        = _irq,         \
0026         .uartclk    = 1843200,      \
0027         .iotype     = UPIO_PORT,        \
0028         .flags      = UPF_BOOT_AUTOCONF,    \
0029     }
0030 
0031 static struct plat_serial8250_port pcit_data[] = {
0032     PORT(0x3f8, 0),
0033     PORT(0x2f8, 3),
0034     { },
0035 };
0036 
0037 static struct platform_device pcit_serial8250_device = {
0038     .name           = "serial8250",
0039     .id         = PLAT8250_DEV_PLATFORM,
0040     .dev            = {
0041         .platform_data  = pcit_data,
0042     },
0043 };
0044 
0045 static struct plat_serial8250_port pcit_cplus_data[] = {
0046     PORT(0x3f8, 0),
0047     PORT(0x2f8, 3),
0048     PORT(0x3e8, 4),
0049     PORT(0x2e8, 3),
0050     { },
0051 };
0052 
0053 static struct platform_device pcit_cplus_serial8250_device = {
0054     .name           = "serial8250",
0055     .id         = PLAT8250_DEV_PLATFORM,
0056     .dev            = {
0057         .platform_data  = pcit_cplus_data,
0058     },
0059 };
0060 
0061 static struct resource pcit_cmos_rsrc[] = {
0062     {
0063         .start = 0x70,
0064         .end   = 0x71,
0065         .flags = IORESOURCE_IO
0066     },
0067     {
0068         .start = 8,
0069         .end   = 8,
0070         .flags = IORESOURCE_IRQ
0071     }
0072 };
0073 
0074 static struct platform_device pcit_cmos_device = {
0075     .name       = "rtc_cmos",
0076     .num_resources  = ARRAY_SIZE(pcit_cmos_rsrc),
0077     .resource   = pcit_cmos_rsrc
0078 };
0079 
0080 static struct platform_device pcit_pcspeaker_pdev = {
0081     .name       = "pcspkr",
0082     .id     = -1,
0083 };
0084 
0085 static struct resource sni_io_resource = {
0086     .start  = 0x00000000UL,
0087     .end    = 0x03bfffffUL,
0088     .name   = "PCIT IO",
0089     .flags  = IORESOURCE_IO,
0090 };
0091 
0092 static struct resource pcit_io_resources[] = {
0093     {
0094         .start  = 0x00,
0095         .end    = 0x1f,
0096         .name   = "dma1",
0097         .flags  = IORESOURCE_BUSY
0098     }, {
0099         .start  =  0x40,
0100         .end    = 0x5f,
0101         .name   = "timer",
0102         .flags  = IORESOURCE_BUSY
0103     }, {
0104         .start  =  0x60,
0105         .end    = 0x6f,
0106         .name   = "keyboard",
0107         .flags  = IORESOURCE_BUSY
0108     }, {
0109         .start  =  0x80,
0110         .end    = 0x8f,
0111         .name   = "dma page reg",
0112         .flags  = IORESOURCE_BUSY
0113     }, {
0114         .start  =  0xc0,
0115         .end    = 0xdf,
0116         .name   = "dma2",
0117         .flags  = IORESOURCE_BUSY
0118     }, {
0119         .start  =  0xcf8,
0120         .end    = 0xcfb,
0121         .name   = "PCI config addr",
0122         .flags  = IORESOURCE_BUSY
0123     }, {
0124         .start  =  0xcfc,
0125         .end    = 0xcff,
0126         .name   = "PCI config data",
0127         .flags  = IORESOURCE_BUSY
0128     }
0129 };
0130 
0131 static void __init sni_pcit_resource_init(void)
0132 {
0133     int i;
0134 
0135     /* request I/O space for devices used on all i[345]86 PCs */
0136     for (i = 0; i < ARRAY_SIZE(pcit_io_resources); i++)
0137         request_resource(&sni_io_resource, pcit_io_resources + i);
0138 }
0139 
0140 
0141 extern struct pci_ops sni_pcit_ops;
0142 
0143 #ifdef CONFIG_PCI
0144 static struct resource sni_mem_resource = {
0145     .start  = 0x18000000UL,
0146     .end    = 0x1fbfffffUL,
0147     .name   = "PCIT PCI MEM",
0148     .flags  = IORESOURCE_MEM
0149 };
0150 
0151 static struct pci_controller sni_pcit_controller = {
0152     .pci_ops    = &sni_pcit_ops,
0153     .mem_resource   = &sni_mem_resource,
0154     .mem_offset = 0x00000000UL,
0155     .io_resource    = &sni_io_resource,
0156     .io_offset  = 0x00000000UL,
0157     .io_map_base    = SNI_PORT_BASE
0158 };
0159 #endif /* CONFIG_PCI */
0160 
0161 static void enable_pcit_irq(struct irq_data *d)
0162 {
0163     u32 mask = 1 << (d->irq - SNI_PCIT_INT_START + 24);
0164 
0165     *(volatile u32 *)SNI_PCIT_INT_REG |= mask;
0166 }
0167 
0168 void disable_pcit_irq(struct irq_data *d)
0169 {
0170     u32 mask = 1 << (d->irq - SNI_PCIT_INT_START + 24);
0171 
0172     *(volatile u32 *)SNI_PCIT_INT_REG &= ~mask;
0173 }
0174 
0175 static struct irq_chip pcit_irq_type = {
0176     .name = "PCIT",
0177     .irq_mask = disable_pcit_irq,
0178     .irq_unmask = enable_pcit_irq,
0179 };
0180 
0181 static void pcit_hwint1(void)
0182 {
0183     u32 pending = *(volatile u32 *)SNI_PCIT_INT_REG;
0184     int irq;
0185 
0186     clear_c0_status(IE_IRQ1);
0187     irq = ffs((pending >> 16) & 0x7f);
0188 
0189     if (likely(irq > 0))
0190         do_IRQ(irq + SNI_PCIT_INT_START - 1);
0191     set_c0_status(IE_IRQ1);
0192 }
0193 
0194 static void pcit_hwint0(void)
0195 {
0196     u32 pending = *(volatile u32 *)SNI_PCIT_INT_REG;
0197     int irq;
0198 
0199     clear_c0_status(IE_IRQ0);
0200     irq = ffs((pending >> 16) & 0x3f);
0201 
0202     if (likely(irq > 0))
0203         do_IRQ(irq + SNI_PCIT_INT_START - 1);
0204     set_c0_status(IE_IRQ0);
0205 }
0206 
0207 static void sni_pcit_hwint(void)
0208 {
0209     u32 pending = read_c0_cause() & read_c0_status();
0210 
0211     if (pending & C_IRQ1)
0212         pcit_hwint1();
0213     else if (pending & C_IRQ2)
0214         do_IRQ(MIPS_CPU_IRQ_BASE + 4);
0215     else if (pending & C_IRQ3)
0216         do_IRQ(MIPS_CPU_IRQ_BASE + 5);
0217     else if (pending & C_IRQ5)
0218         do_IRQ(MIPS_CPU_IRQ_BASE + 7);
0219 }
0220 
0221 static void sni_pcit_hwint_cplus(void)
0222 {
0223     u32 pending = read_c0_cause() & read_c0_status();
0224 
0225     if (pending & C_IRQ0)
0226         pcit_hwint0();
0227     else if (pending & C_IRQ1)
0228         do_IRQ(MIPS_CPU_IRQ_BASE + 3);
0229     else if (pending & C_IRQ2)
0230         do_IRQ(MIPS_CPU_IRQ_BASE + 4);
0231     else if (pending & C_IRQ3)
0232         do_IRQ(MIPS_CPU_IRQ_BASE + 5);
0233     else if (pending & C_IRQ5)
0234         do_IRQ(MIPS_CPU_IRQ_BASE + 7);
0235 }
0236 
0237 void __init sni_pcit_irq_init(void)
0238 {
0239     int i;
0240 
0241     mips_cpu_irq_init();
0242     for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
0243         irq_set_chip_and_handler(i, &pcit_irq_type, handle_level_irq);
0244     *(volatile u32 *)SNI_PCIT_INT_REG = 0;
0245     sni_hwint = sni_pcit_hwint;
0246     change_c0_status(ST0_IM, IE_IRQ1);
0247     if (request_irq(SNI_PCIT_INT_START + 6, sni_isa_irq_handler, 0, "ISA",
0248             NULL))
0249         pr_err("Failed to register ISA interrupt\n");
0250 }
0251 
0252 void __init sni_pcit_cplus_irq_init(void)
0253 {
0254     int i;
0255 
0256     mips_cpu_irq_init();
0257     for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
0258         irq_set_chip_and_handler(i, &pcit_irq_type, handle_level_irq);
0259     *(volatile u32 *)SNI_PCIT_INT_REG = 0x40000000;
0260     sni_hwint = sni_pcit_hwint_cplus;
0261     change_c0_status(ST0_IM, IE_IRQ0);
0262     if (request_irq(MIPS_CPU_IRQ_BASE + 3, sni_isa_irq_handler, 0, "ISA",
0263             NULL))
0264         pr_err("Failed to register ISA interrupt\n");
0265 }
0266 
0267 void __init sni_pcit_init(void)
0268 {
0269     ioport_resource.end = sni_io_resource.end;
0270 #ifdef CONFIG_PCI
0271     PCIBIOS_MIN_IO = 0x9000;
0272     register_pci_controller(&sni_pcit_controller);
0273 #endif
0274     sni_pcit_resource_init();
0275 }
0276 
0277 static int __init snirm_pcit_setup_devinit(void)
0278 {
0279     switch (sni_brd_type) {
0280     case SNI_BRD_PCI_TOWER:
0281         platform_device_register(&pcit_serial8250_device);
0282         platform_device_register(&pcit_cmos_device);
0283         platform_device_register(&pcit_pcspeaker_pdev);
0284         break;
0285 
0286     case SNI_BRD_PCI_TOWER_CPLUS:
0287         platform_device_register(&pcit_cplus_serial8250_device);
0288         platform_device_register(&pcit_cmos_device);
0289         platform_device_register(&pcit_pcspeaker_pdev);
0290         break;
0291     }
0292     return 0;
0293 }
0294 
0295 device_initcall(snirm_pcit_setup_devinit);