/*
* PCI Tower specific code
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/pci.h>
#include <linux/serial_8250.h>
#include <asm /sni.h>
#include <asm /time.h>
#include <asm /irq_cpu.h>
#define PORT(_base,_irq) \
{ \
.iobase = _base, \
.irq = _irq, \
.uartclk = 1843200 , \
.iotype = UPIO_PORT, \
.flags = UPF_BOOT_AUTOCONF, \
}
static struct plat_serial8250_port pcit_data[] = {
PORT(0 x3f8, 0 ),
PORT(0 x2f8, 3 ),
{ },
};
static struct platform_device pcit_serial8250_device = {
.name = "serial8250" ,
.id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = pcit_data,
},
};
static struct plat_serial8250_port pcit_cplus_data[] = {
PORT(0 x3f8, 0 ),
PORT(0 x2f8, 3 ),
PORT(0 x3e8, 4 ),
PORT(0 x2e8, 3 ),
{ },
};
static struct platform_device pcit_cplus_serial8250_device = {
.name = "serial8250" ,
.id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = pcit_cplus_data,
},
};
static struct resource pcit_cmos_rsrc[] = {
{
.start = 0 x70,
.end = 0 x71,
.flags = IORESOURCE_IO
},
{
.start = 8 ,
.end = 8 ,
.flags = IORESOURCE_IRQ
}
};
static struct platform_device pcit_cmos_device = {
.name = "rtc_cmos" ,
.num_resources = ARRAY_SIZE(pcit_cmos_rsrc),
.resource = pcit_cmos_rsrc
};
static struct platform_device pcit_pcspeaker_pdev = {
.name = "pcspkr" ,
.id = -1 ,
};
static struct resource sni_io_resource = {
.start = 0 x00000000UL,
.end = 0 x03bfffffUL,
.name = "PCIT IO" ,
.flags = IORESOURCE_IO,
};
static struct resource pcit_io_resources[] = {
{
.start = 0 x00,
.end = 0 x1f,
.name = "dma1" ,
.flags = IORESOURCE_BUSY
}, {
.start = 0 x40,
.end = 0 x5f,
.name = "timer" ,
.flags = IORESOURCE_BUSY
}, {
.start = 0 x60,
.end = 0 x6f,
.name = "keyboard" ,
.flags = IORESOURCE_BUSY
}, {
.start = 0 x80,
.end = 0 x8f,
.name = "dma page reg" ,
.flags = IORESOURCE_BUSY
}, {
.start = 0 xc0,
.end = 0 xdf,
.name = "dma2" ,
.flags = IORESOURCE_BUSY
}, {
.start = 0 xcf8,
.end = 0 xcfb,
.name = "PCI config addr" ,
.flags = IORESOURCE_BUSY
}, {
.start = 0 xcfc,
.end = 0 xcff,
.name = "PCI config data" ,
.flags = IORESOURCE_BUSY
}
};
static void __init sni_pcit_resource_init(void )
{
int i;
/* request I/O space for devices used on all i[345]86 PCs */
for (i = 0 ; i < ARRAY_SIZE(pcit_io_resources); i++)
request_resource(&sni_io_resource, pcit_io_resources + i);
}
extern struct pci_ops sni_pcit_ops;
#ifdef CONFIG_PCI
static struct resource sni_mem_resource = {
.start = 0 x18000000UL,
.end = 0 x1fbfffffUL,
.name = "PCIT PCI MEM" ,
.flags = IORESOURCE_MEM
};
static struct pci_controller sni_pcit_controller = {
.pci_ops = &sni_pcit_ops,
.mem_resource = &sni_mem_resource,
.mem_offset = 0 x00000000UL,
.io_resource = &sni_io_resource,
.io_offset = 0 x00000000UL,
.io_map_base = SNI_PORT_BASE
};
#endif /* CONFIG_PCI */
static void enable_pcit_irq(struct irq_data *d)
{
u32 mask = 1 << (d->irq - SNI_PCIT_INT_START + 24 );
*(volatile u32 *)SNI_PCIT_INT_REG |= mask;
}
void disable_pcit_irq(struct irq_data *d)
{
u32 mask = 1 << (d->irq - SNI_PCIT_INT_START + 24 );
*(volatile u32 *)SNI_PCIT_INT_REG &= ~mask;
}
static struct irq_chip pcit_irq_type = {
.name = "PCIT" ,
.irq_mask = disable_pcit_irq,
.irq_unmask = enable_pcit_irq,
};
static void pcit_hwint1(void )
{
u32 pending = *(volatile u32 *)SNI_PCIT_INT_REG;
int irq;
clear_c0_status(IE_IRQ1);
irq = ffs((pending >> 16 ) & 0 x7f);
if (likely(irq > 0 ))
do_IRQ(irq + SNI_PCIT_INT_START - 1 );
set_c0_status(IE_IRQ1);
}
static void pcit_hwint0(void )
{
u32 pending = *(volatile u32 *)SNI_PCIT_INT_REG;
int irq;
clear_c0_status(IE_IRQ0);
irq = ffs((pending >> 16 ) & 0 x3f);
if (likely(irq > 0 ))
do_IRQ(irq + SNI_PCIT_INT_START - 1 );
set_c0_status(IE_IRQ0);
}
static void sni_pcit_hwint(void )
{
u32 pending = read_c0_cause() & read_c0_status();
if (pending & C_IRQ1)
pcit_hwint1();
else if (pending & C_IRQ2)
do_IRQ(MIPS_CPU_IRQ_BASE + 4 );
else if (pending & C_IRQ3)
do_IRQ(MIPS_CPU_IRQ_BASE + 5 );
else if (pending & C_IRQ5)
do_IRQ(MIPS_CPU_IRQ_BASE + 7 );
}
static void sni_pcit_hwint_cplus(void )
{
u32 pending = read_c0_cause() & read_c0_status();
if (pending & C_IRQ0)
pcit_hwint0();
else if (pending & C_IRQ1)
do_IRQ(MIPS_CPU_IRQ_BASE + 3 );
else if (pending & C_IRQ2)
do_IRQ(MIPS_CPU_IRQ_BASE + 4 );
else if (pending & C_IRQ3)
do_IRQ(MIPS_CPU_IRQ_BASE + 5 );
else if (pending & C_IRQ5)
do_IRQ(MIPS_CPU_IRQ_BASE + 7 );
}
void __init sni_pcit_irq_init(void )
{
int i;
mips_cpu_irq_init();
for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
irq_set_chip_and_handler(i, &pcit_irq_type, handle_level_irq);
*(volatile u32 *)SNI_PCIT_INT_REG = 0 ;
sni_hwint = sni_pcit_hwint;
change_c0_status(ST0_IM, IE_IRQ1);
if (request_irq(SNI_PCIT_INT_START + 6 , sni_isa_irq_handler, 0 , "ISA" ,
NULL))
pr_err("Failed to register ISA interrupt\n" );
}
void __init sni_pcit_cplus_irq_init(void )
{
int i;
mips_cpu_irq_init();
for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
irq_set_chip_and_handler(i, &pcit_irq_type, handle_level_irq);
*(volatile u32 *)SNI_PCIT_INT_REG = 0 x40000000;
sni_hwint = sni_pcit_hwint_cplus;
change_c0_status(ST0_IM, IE_IRQ0);
if (request_irq(MIPS_CPU_IRQ_BASE + 3 , sni_isa_irq_handler, 0 , "ISA" ,
NULL))
pr_err("Failed to register ISA interrupt\n" );
}
void __init sni_pcit_init(void )
{
ioport_resource.end = sni_io_resource.end;
#ifdef CONFIG_PCI
PCIBIOS_MIN_IO = 0 x9000;
register_pci_controller(&sni_pcit_controller);
#endif
sni_pcit_resource_init();
}
static int __init snirm_pcit_setup_devinit(void )
{
switch (sni_brd_type) {
case SNI_BRD_PCI_TOWER:
platform_device_register(&pcit_serial8250_device);
platform_device_register(&pcit_cmos_device);
platform_device_register(&pcit_pcspeaker_pdev);
break ;
case SNI_BRD_PCI_TOWER_CPLUS:
platform_device_register(&pcit_cplus_serial8250_device);
platform_device_register(&pcit_cmos_device);
platform_device_register(&pcit_pcspeaker_pdev);
break ;
}
return 0 ;
}
device_initcall(snirm_pcit_setup_devinit);
Messung V0.5 in Prozent C=96 H=92 G=93
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-08)
¤
*© Formatika GbR, Deutschland