diff options
author | Jamie Lenehan <lenehan@twibble.org> | 2006-09-27 15:05:39 +0900 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2006-09-27 15:05:39 +0900 |
commit | a09749dd86e9e93de10f12ab4ce4e90815b5650a (patch) | |
tree | 013d7deabb31dea70063a2acdc50ee86fb3c7b9a /arch/sh/drivers/pci | |
parent | b7e108ee63624176af85b97d4d80bef6fe099395 (diff) |
sh: Titan board support.
Add support for the titan board.
Signed-off-by: Jamie Lenehan <lenehan@twibble.org>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/drivers/pci')
-rw-r--r-- | arch/sh/drivers/pci/Makefile | 1 | ||||
-rw-r--r-- | arch/sh/drivers/pci/ops-titan.c | 84 | ||||
-rw-r--r-- | arch/sh/drivers/pci/pci.c | 58 |
3 files changed, 131 insertions, 12 deletions
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile index 365bc16a4a8..86d6d0660d4 100644 --- a/arch/sh/drivers/pci/Makefile +++ b/arch/sh/drivers/pci/Makefile @@ -14,3 +14,4 @@ obj-$(CONFIG_SH_SECUREEDGE5410) += ops-snapgear.o obj-$(CONFIG_SH_BIGSUR) += ops-bigsur.o obj-$(CONFIG_SH_RTS7751R2D) += ops-rts7751r2d.o fixups-rts7751r2d.o obj-$(CONFIG_SH_SH03) += ops-sh03.o fixups-sh03.o +obj-$(CONFIG_SH_TITAN) += ops-titan.o diff --git a/arch/sh/drivers/pci/ops-titan.c b/arch/sh/drivers/pci/ops-titan.c new file mode 100644 index 00000000000..f76e4e963ac --- /dev/null +++ b/arch/sh/drivers/pci/ops-titan.c @@ -0,0 +1,84 @@ +/* + * arch/sh/drivers/pci/ops-titan.c + * + * Ported to new API by Paul Mundt <lethal@linux-sh.org> + * + * Modified from ops-snapgear.c written by David McCullough + * Highly leveraged from pci-bigsur.c, written by Dustin McIntire. + * + * May be copied or modified under the terms of the GNU General Public + * License. See linux/COPYING for more information. + * + * PCI initialization for the Titan boards + */ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <asm/io.h> +#include <asm/titan.h> +#include "pci-sh7751.h" + +int __init pcibios_map_platform_irq(u8 slot, u8 pin) +{ + int irq = -1; + + switch (slot) { + case 0: irq = TITAN_IRQ_WAN; break; /* eth0 (WAN) */ + case 1: irq = TITAN_IRQ_LAN; break; /* eth1 (LAN) */ + case 2: irq = TITAN_IRQ_MPCIA; break; /* mPCI A */ + case 3: irq = TITAN_IRQ_MPCIB; break; /* mPCI B */ + case 4: irq = TITAN_IRQ_USB; break; /* USB */ + default: + printk(KERN_INFO "PCI: Bad IRQ mapping request for slot %d\n", slot); + return -1; + } + + printk("PCI: Mapping TITAN IRQ for slot %d, pin %c to irq %d\n", + slot, pin - 1 + 'A', irq); + + return irq; +} + +static struct resource sh7751_io_resource = { + .name = "SH7751_IO", + .start = SH7751_PCI_IO_BASE, + .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, + .flags = IORESOURCE_IO +}; + +static struct resource sh7751_mem_resource = { + .name = "SH7751_mem", + .start = SH7751_PCI_MEMORY_BASE, + .end = SH7751_PCI_MEMORY_BASE + SH7751_PCI_MEM_SIZE - 1, + .flags = IORESOURCE_MEM +}; + +extern struct pci_ops sh7751_pci_ops; + +struct pci_channel board_pci_channels[] = { + { &sh7751_pci_ops, &sh7751_io_resource, &sh7751_mem_resource, 0, 0xff }, + { NULL, NULL, NULL, 0, 0 }, +}; +EXPORT_SYMBOL(board_pci_channels); + +static struct sh7751_pci_address_map sh7751_pci_map = { + .window0 = { + .base = SH7751_CS2_BASE_ADDR, + .size = SH7751_MEM_REGION_SIZE*2, /* cs2 and cs3 */ + }, + + .window1 = { + .base = SH7751_CS2_BASE_ADDR, + .size = SH7751_MEM_REGION_SIZE*2, + }, + + .flags = SH7751_PCIC_NO_RESET, +}; + +int __init pcibios_init_platform(void) +{ + return sh7751_pcic_init(&sh7751_pci_map); +} diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 3d546ba329c..1f5e23e8b16 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -1,21 +1,25 @@ -/* arch/sh/kernel/pci.c - * $Id: pci.c,v 1.1 2003/08/24 19:15:45 lethal Exp $ +/* + * arch/sh/drivers/pci/pci.c * * Copyright (c) 2002 M. R. Brown <mrbrown@linux-sh.org> - * - * + * Copyright (c) 2004, 2005 Paul Mundt <lethal@linux-sh.org> + * * These functions are collected here to reduce duplication of common * code amongst the many platform-specific PCI support code files. - * + * * These routines require the following board-specific routines: * void pcibios_fixup_irqs(); * * See include/asm-sh/pci.h for more information. + * + * 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. */ - #include <linux/kernel.h> #include <linux/pci.h> #include <linux/init.h> +#include <asm/io.h> static int __init pcibios_init(void) { @@ -26,9 +30,8 @@ static int __init pcibios_init(void) #ifdef CONFIG_PCI_AUTO /* assign resources */ busno = 0; - for (p = board_pci_channels; p->pci_ops != NULL; p++) { + for (p = board_pci_channels; p->pci_ops != NULL; p++) busno = pciauto_assign_resources(busno, p) + 1; - } #endif /* scan the buses */ @@ -61,13 +64,17 @@ pcibios_update_resource(struct pci_dev *dev, struct resource *root, new |= PCI_ROM_ADDRESS_ENABLE; reg = dev->rom_base_reg; } else { - /* Somebody might have asked allocation of a non-standard resource */ + /* + * Somebody might have asked allocation of a non-standard + * resource + */ return; } - + pci_write_config_dword(dev, reg, new); pci_read_config_dword(dev, reg, &check); - if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) { + if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? + PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) { printk(KERN_ERR "PCI: Error while updating region " "%s/%d (%08x != %08x)\n", pci_name(dev), resource, new, check); @@ -145,7 +152,8 @@ void pcibios_set_master(struct pci_dev *dev) lat = pcibios_max_latency; else return; - printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat); + printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", + pci_name(dev), lat); pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); } @@ -153,3 +161,29 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq) { pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); } + +void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) +{ + unsigned long start = pci_resource_start(dev, bar); + unsigned long len = pci_resource_len(dev, bar); + unsigned long flags = pci_resource_flags(dev, bar); + + if (!len || !start) + return NULL; + if (maxlen && len > maxlen) + len = maxlen; + if (flags & IORESOURCE_IO) + return ioport_map(start, len); + if (flags & IORESOURCE_MEM) + return ioremap(start, len); + + return NULL; +} + +void pci_iounmap(struct pci_dev *dev, void __iomem *addr) +{ + iounmap(addr); +} + +EXPORT_SYMBOL(pci_iomap); +EXPORT_SYMBOL(pci_iounmap); |