diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2003-06-04 05:28:21 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2003-06-04 05:28:21 -0700 |
| commit | 9be2217a8d55e94046e47d5668e984036cd44c75 (patch) | |
| tree | 75d73319815eca67d2ae0c3d99a418dc2ce75f08 | |
| parent | 29907881db8546d1d88aeb17e4c4efb236067bfd (diff) | |
| parent | 3f3bdf8eddb5cf781a558bd1185fe8ab7786ab03 (diff) | |
Merge bk://kernel.bkbits.net/gregkh/linux/pci-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
25 files changed, 628 insertions, 311 deletions
diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index e7d2d17552ac..0a3495af6bbf 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -2,7 +2,7 @@ # Makefile for the linux kernel. # -obj-$(CONFIG_SA1111) += sa1111.o sa1111-pcibuf.o sa1111-pcipool.o - +obj-y += platform.o +obj-$(CONFIG_SA1111) += sa1111.o sa1111-pcibuf.o sa1111-pcipool.o obj-$(CONFIG_PCI_HOST_PLX90X0) += plx90x0.o obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o diff --git a/arch/arm/common/platform.c b/arch/arm/common/platform.c new file mode 100644 index 000000000000..12e858099f93 --- /dev/null +++ b/arch/arm/common/platform.c @@ -0,0 +1,35 @@ +#include <linux/ioport.h> +#include <linux/device.h> +#include <linux/init.h> + +int __init platform_add_device(struct platform_device *dev) +{ + int i; + + for (i = 0; i < dev->num_resources; i++) { + struct resource *r = &dev->resource[i]; + + r->name = dev->dev.name; + + if (r->flags & IORESOURCE_MEM && + request_resource(&iomem_resource, r)) { + printk(KERN_ERR + "%s%d: failed to claim resource %d\n", + dev->name, dev->id, i); + break; + } + } + if (i == dev->num_resources) + platform_device_register(dev); + return 0; +} + +int __init platform_add_devices(struct platform_device **devs, int num) +{ + int i; + + for (i = 0; i < num; i++) + platform_add_device(devs[i]); + + return 0; +} diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index f91856235184..c8ad1d53014a 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -42,7 +42,7 @@ */ struct sa1111 { struct device *dev; - struct resource res; + unsigned long phys; int irq; spinlock_t lock; void *base; @@ -60,7 +60,6 @@ static struct sa1111_dev usb_dev = { }, .skpcr_mask = SKPCR_UCLKEN, .devid = SA1111_DEVID_USB, - .dma_mask = 0xffffffffLL, .irq = { IRQ_USBPWR, IRQ_HCIM, @@ -470,6 +469,17 @@ static void sa1111_wake(struct sa1111 *sachip) #ifdef CONFIG_ARCH_SA1100 +static u32 sa1111_dma_mask[] = { + ~0, + ~(1 << 20), + ~(1 << 23), + ~(1 << 24), + ~(1 << 25), + ~(1 << 20), + ~(1 << 20), + 0, +}; + /* * Configure the SA1111 shared memory controller. */ @@ -483,26 +493,43 @@ sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac, smcr |= SMCR_CLAT; sa1111_writel(smcr, sachip->base + SA1111_SMCR); + + /* + * Now clear the bits in the DMA mask to work around the SA1111 + * DMA erratum (Intel StrongARM SA-1111 Microprocessor Companion + * Chip Specification Update, June 2000, Erratum #7). + */ + if (sachip->dev->dma_mask) + *sachip->dev->dma_mask &= sa1111_dma_mask[drac >> 2]; } #endif static void -sa1111_init_one_child(struct sa1111 *sachip, struct sa1111_dev *sadev, unsigned int offset) +sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, + struct sa1111_dev *sadev, unsigned int offset) { snprintf(sadev->dev.bus_id, sizeof(sadev->dev.bus_id), "%4.4x", offset); + /* + * If the parent device has a DMA mask associated with it, + * propagate it down to the children. + */ + if (sachip->dev->dma_mask) { + sadev->dma_mask = *sachip->dev->dma_mask; + sadev->dev.dma_mask = &sadev->dma_mask; + } + sadev->dev.parent = sachip->dev; sadev->dev.bus = &sa1111_bus_type; - sadev->dev.dma_mask = &sadev->dma_mask; - sadev->res.start = sachip->res.start + offset; + sadev->res.start = sachip->phys + offset; sadev->res.end = sadev->res.start + 511; sadev->res.name = sadev->dev.name; sadev->res.flags = IORESOURCE_MEM; sadev->mapbase = sachip->base + offset; - if (request_resource(&sachip->res, &sadev->res)) { + if (request_resource(parent, &sadev->res)) { printk("SA1111: failed to allocate resource for %s\n", sadev->res.name); return; @@ -524,7 +551,7 @@ sa1111_init_one_child(struct sa1111 *sachip, struct sa1111_dev *sadev, unsigned * %0 successful. */ static int __init -__sa1111_probe(struct device *me, unsigned long phys_addr, int irq) +__sa1111_probe(struct device *me, struct resource *mem, int irq) { struct sa1111 *sachip; unsigned long id; @@ -542,24 +569,17 @@ __sa1111_probe(struct device *me, unsigned long phys_addr, int irq) sachip->dev = me; dev_set_drvdata(sachip->dev, sachip); - sachip->res.name = me->name; - sachip->res.start = phys_addr; - sachip->res.end = phys_addr + 0x2000; + sachip->phys = mem->start; sachip->irq = irq; - if (request_resource(&iomem_resource, &sachip->res)) { - ret = -EBUSY; - goto out; - } - /* * Map the whole region. This also maps the * registers for our children. */ - sachip->base = ioremap(phys_addr, PAGE_SIZE * 2); + sachip->base = ioremap(mem->start, PAGE_SIZE * 2); if (!sachip->base) { ret = -ENOMEM; - goto release; + goto out; } /* @@ -611,9 +631,11 @@ __sa1111_probe(struct device *me, unsigned long phys_addr, int irq) * The interrupt controller must be initialised before any * other device to ensure that the interrupts are available. */ - int_dev.irq[0] = irq; - sa1111_init_one_child(sachip, &int_dev, SA1111_INTC); - sa1111_init_irq(&int_dev); + if (irq != NO_IRQ) { + int_dev.irq[0] = irq; + sa1111_init_one_child(sachip, mem, &int_dev, SA1111_INTC); + sa1111_init_irq(&int_dev); + } g_sa1111 = sachip; @@ -626,14 +648,12 @@ __sa1111_probe(struct device *me, unsigned long phys_addr, int irq) for (i = 0; i < ARRAY_SIZE(devs); i++) if (has_devs & (1 << i)) - sa1111_init_one_child(sachip, devs[i], dev_offset[i]); + sa1111_init_one_child(sachip, mem, devs[i], dev_offset[i]); return 0; unmap: iounmap(sachip->base); - release: - release_resource(&sachip->res); out: kfree(sachip); return ret; @@ -649,7 +669,6 @@ static void __sa1111_remove(struct sa1111 *sachip) } iounmap(sachip->base); - release_resource(&sachip->res); kfree(sachip); } @@ -874,7 +893,17 @@ static int sa1111_resume(struct device *dev, u32 level) static int sa1111_probe(struct device *dev) { - return -ENODEV; + struct platform_device *pdev = to_platform_device(dev); + struct resource *mem = NULL, *irq = NULL; + int i; + + for (i = 0; i < pdev->num_resources; i++) { + if (pdev->resource[i].flags & IORESOURCE_MEM) + mem = &pdev->resource[i]; + if (pdev->resource[i].flags & IORESOURCE_IRQ) + irq = &pdev->resource[i]; + } + return __sa1111_probe(dev, mem, irq ? irq->start : NO_IRQ); } static int sa1111_remove(struct device *dev) @@ -903,7 +932,7 @@ static int sa1111_remove(struct device *dev) */ static struct device_driver sa1111_device_driver = { .name = "sa1111", - .bus = &system_bus_type, + .bus = &platform_bus_type, .probe = sa1111_probe, .remove = sa1111_remove, .suspend = sa1111_suspend, @@ -921,29 +950,6 @@ static int sa1111_driver_init(void) arch_initcall(sa1111_driver_init); -static struct sys_device sa1111_device = { - .name = "SA1111", - .id = 0, - .root = NULL, - .dev = { - .name = "Intel Corporation SA1111", - .driver = &sa1111_device_driver, - }, -}; - -int sa1111_init(unsigned long phys, unsigned int irq) -{ - int ret; - - snprintf(sa1111_device.dev.bus_id, sizeof(sa1111_device.dev.bus_id), "%8.8lx", phys); - - ret = sys_device_register(&sa1111_device); - if (ret) - printk("sa1111 device_register failed: %d\n", ret); - - return __sa1111_probe(&sa1111_device.dev, phys, irq); -} - /* * Get the parent device driver (us) structure * from a child function device diff --git a/arch/arm/mach-footbridge/isa-irq.c b/arch/arm/mach-footbridge/isa-irq.c index 4320bcb23085..b21016070ea3 100644 --- a/arch/arm/mach-footbridge/isa-irq.c +++ b/arch/arm/mach-footbridge/isa-irq.c @@ -84,10 +84,6 @@ static struct irqchip isa_hi_chip = { .unmask = isa_unmask_pic_hi_irq, }; -static void no_action(int irq, void *dev_id, struct pt_regs *regs) -{ -} - static void isa_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { diff --git a/arch/arm/mach-integrator/Makefile b/arch/arm/mach-integrator/Makefile index 8cc51265ad6c..43d79d56cd68 100644 --- a/arch/arm/mach-integrator/Makefile +++ b/arch/arm/mach-integrator/Makefile @@ -4,10 +4,7 @@ # Object file lists. -obj-y := arch.o irq.o mm.o time.o -obj-m := -obj-n := -obj- := +obj-y := core.o time.o obj-$(CONFIG_LEDS) += leds.o obj-$(CONFIG_PCI) += pci_v3.o pci.o diff --git a/arch/arm/mach-integrator/arch.c b/arch/arm/mach-integrator/arch.c deleted file mode 100644 index 0a1fd15cf64a..000000000000 --- a/arch/arm/mach-integrator/arch.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * linux/arch/arm/mach-integrator/arch.c - * - * Copyright (C) 2000 Deep Blue Solutions Ltd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include <linux/config.h> -#include <linux/types.h> -#include <linux/init.h> - -#include <asm/hardware.h> -#include <asm/irq.h> -#include <asm/setup.h> -#include <asm/mach-types.h> - -#include <asm/mach/arch.h> - -extern void integrator_map_io(void); -extern void integrator_init_irq(void); - -MACHINE_START(INTEGRATOR, "ARM-Integrator") - MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") - BOOT_MEM(0x00000000, 0x16000000, 0xf1600000) - BOOT_PARAMS(0x00000100) - MAPIO(integrator_map_io) - INITIRQ(integrator_init_irq) -MACHINE_END diff --git a/arch/arm/mach-integrator/mm.c b/arch/arm/mach-integrator/core.c index 773f53a13286..88dd84ad01dd 100644 --- a/arch/arm/mach-integrator/mm.c +++ b/arch/arm/mach-integrator/core.c @@ -1,9 +1,6 @@ /* - * linux/arch/arm/mach-integrator/mm.c + * linux/arch/arm/mach-integrator/arch.c * - * Extra MM routines for the ARM Integrator board - * - * Copyright (C) 1999,2000 Arm Limited * Copyright (C) 2000 Deep Blue Solutions Ltd * * This program is free software; you can redistribute it and/or modify @@ -20,14 +17,35 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <linux/config.h> +#include <linux/types.h> #include <linux/kernel.h> #include <linux/init.h> +#include <linux/list.h> +#include <linux/device.h> +#include <linux/slab.h> +#include <linux/string.h> #include <asm/hardware.h> #include <asm/io.h> - +#include <asm/irq.h> +#include <asm/setup.h> +#include <asm/mach-types.h> + +#include <asm/mach/arch.h> +#include <asm/mach/irq.h> #include <asm/mach/map.h> +/* + * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx + * is the (PA >> 12). + * + * Setup a VA for the Integrator interrupt controller (for header #0, + * just for now). + */ +#define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE) +#define VA_CMIC_BASE IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_IC_OFFSET + /* * Logical Physical * e8000000 40000000 PCI memory PHYS_PCI_MEM_BASE (max 512M) @@ -64,7 +82,54 @@ static struct map_desc integrator_io_desc[] __initdata = { { PCI_IO_VADDR, PHYS_PCI_IO_BASE, SZ_64K, MT_DEVICE } }; -void __init integrator_map_io(void) +static void __init integrator_map_io(void) { iotable_init(integrator_io_desc, ARRAY_SIZE(integrator_io_desc)); } + +#define ALLPCI ( (1 << IRQ_PCIINT0) | (1 << IRQ_PCIINT1) | (1 << IRQ_PCIINT2) | (1 << IRQ_PCIINT3) ) + +static void sc_mask_irq(unsigned int irq) +{ + writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_CLEAR); +} + +static void sc_unmask_irq(unsigned int irq) +{ + writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_SET); +} + +static struct irqchip sc_chip = { + .ack = sc_mask_irq, + .mask = sc_mask_irq, + .unmask = sc_unmask_irq, +}; + +static void __init integrator_init_irq(void) +{ + unsigned int i; + + /* Disable all interrupts initially. */ + /* Do the core module ones */ + writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); + + /* do the header card stuff next */ + writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); + writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); + + for (i = 0; i < NR_IRQS; i++) { + if (((1 << i) && INTEGRATOR_SC_VALID_INT) != 0) { + set_irq_chip(i, &sc_chip); + set_irq_handler(i, do_level_IRQ); + set_irq_flags(i, IRQF_VALID | IRQF_PROBE); + } + } +} + +MACHINE_START(INTEGRATOR, "ARM-Integrator") + MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") + BOOT_MEM(0x00000000, 0x16000000, 0xf1600000) + BOOT_PARAMS(0x00000100) + MAPIO(integrator_map_io) + INITIRQ(integrator_init_irq) +MACHINE_END diff --git a/arch/arm/mach-integrator/irq.c b/arch/arm/mach-integrator/irq.c deleted file mode 100644 index 496301c4c69e..000000000000 --- a/arch/arm/mach-integrator/irq.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * linux/arch/arm/mach-integrator/irq.c - * - * Copyright (C) 1999 ARM Limited - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include <linux/init.h> -#include <linux/list.h> - -#include <asm/hardware.h> -#include <asm/irq.h> -#include <asm/io.h> - -#include <asm/mach/irq.h> - -/* - * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx - * is the (PA >> 12). - * - * Setup a VA for the Integrator interrupt controller (for header #0, - * just for now). - */ -#define VA_IC_BASE IO_ADDRESS(INTEGRATOR_IC_BASE) -#define VA_CMIC_BASE IO_ADDRESS(INTEGRATOR_HDR_BASE) + INTEGRATOR_HDR_IC_OFFSET - -#define ALLPCI ( (1 << IRQ_PCIINT0) | (1 << IRQ_PCIINT1) | (1 << IRQ_PCIINT2) | (1 << IRQ_PCIINT3) ) - -static void sc_mask_irq(unsigned int irq) -{ - __raw_writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_CLEAR); -} - -static void sc_unmask_irq(unsigned int irq) -{ - __raw_writel(1 << irq, VA_IC_BASE + IRQ_ENABLE_SET); -} - -static struct irqchip sc_chip = { - .ack = sc_mask_irq, - .mask = sc_mask_irq, - .unmask = sc_unmask_irq, -}; - -void __init integrator_init_irq(void) -{ - unsigned int i; - - /* Disable all interrupts initially. */ - /* Do the core module ones */ - __raw_writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); - - /* do the header card stuff next */ - __raw_writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); - __raw_writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); - - for (i = 0; i < NR_IRQS; i++) { - if (((1 << i) && INTEGRATOR_SC_VALID_INT) != 0) { - set_irq_chip(i, &sc_chip); - set_irq_handler(i, do_level_IRQ); - set_irq_flags(i, IRQF_VALID | IRQF_PROBE); - } - } -} diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index 46dd55038145..162ee9541044 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c @@ -441,7 +441,7 @@ v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) return 1; } -static void v3_irq(int irq, void *devid, struct pt_regs *regs) +static irqreturn_t v3_irq(int irq, void *devid, struct pt_regs *regs) { #ifdef CONFIG_DEBUG_LL unsigned long pc = instruction_pointer(regs); @@ -469,6 +469,7 @@ static void v3_irq(int irq, void *devid, struct pt_regs *regs) printascii(buf); } #endif + return IRQ_HANDLED; } int __init pci_v3_setup(int nr, struct pci_sys_data *sys) diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index e69ec2a5b739..894b6d7d8db9 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -88,9 +88,36 @@ static void __init lubbock_init_irq(void) set_irq_type(IRQ_GPIO(0), IRQT_FALLING); } +static struct resource sa1111_resources[] = { + [0] = { + .start = 0x10000000, + .end = 0x10001fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = LUBBOCK_SA1111_IRQ, + .end = LUBBOCK_SA1111_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sa1111_device = { + .name = "sa1111", + .id = 0, + .dev = { + .name = "Intel Corporation SA1111", + }, + .num_resources = ARRAY_SIZE(sa1111_resources), + .resource = sa1111_resources, +}; + +static struct platform_device *devices[] __initdata = { + &sa1111_device, +}; + static int __init lubbock_init(void) { - return sa1111_init(0x10000000, LUBBOCK_SA1111_IRQ); + return platform_add_devices(devices, ARRAY_SIZE(devices)); } subsys_initcall(lubbock_init); diff --git a/arch/arm/mach-sa1100/adsbitsy.c b/arch/arm/mach-sa1100/adsbitsy.c index d677abeea697..586b56467fe2 100644 --- a/arch/arm/mach-sa1100/adsbitsy.c +++ b/arch/arm/mach-sa1100/adsbitsy.c @@ -27,6 +27,36 @@ #include "generic.h" +static struct resource sa1111_resources[] = { + [0] = { + .start = 0x18000000, + .end = 0x18001fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_GPIO0, + .end = IRQ_GPIO0, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 sa1111_dmamask = 0xffffffffUL; + +static struct platform_device sa1111_device = { + .name = "sa1111", + .id = 0, + .dev = { + .name = "Intel Corporation SA1111", + .dma_mask = &sa1111_dmamask, + }, + .num_resources = ARRAY_SIZE(sa1111_resources), + .resource = sa1111_resources, +}; + +static struct platform_device *devices[] __initdata = { + &sa1111_device, +}; + static int __init adsbitsy_init(void) { int ret; @@ -50,7 +80,7 @@ static int __init adsbitsy_init(void) /* * Probe for SA1111. */ - ret = sa1111_init(0x18000000, IRQ_GPIO0); + ret = platform_add_devices(devices, ARRAY_SIZE(devices)); if (ret < 0) return ret; diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c index 951e6affbba0..a5d4a4d9758a 100644 --- a/arch/arm/mach-sa1100/badge4.c +++ b/arch/arm/mach-sa1100/badge4.c @@ -35,6 +35,36 @@ #include "generic.h" +static struct resource sa1111_resources[] = { + [0] = { + .start = BADGE4_SA1111_BASE, + .end = BADGE4_SA1111_BASE + 0x00001fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = BADGE4_IRQ_GPIO_SA1111, + .end = BADGE4_IRQ_GPIO_SA1111, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 sa1111_dmamask = 0xffffffffUL; + +static struct platform_device sa1111_device = { + .name = "sa1111", + .id = 0, + .dev = { + .name = "Intel Corporation SA1111", + .dma_mask = &sa1111_dmamask; + }, + .num_resources = ARRAY_SIZE(sa1111_resources), + .resource = sa1111_resources, +}; + +static struct platform_device *devices[] __initdata = { + &sa1111_device, +}; + static int __init badge4_sa1111_init(void) { /* @@ -46,7 +76,7 @@ static int __init badge4_sa1111_init(void) /* * Probe for SA1111. */ - return sa1111_init(BADGE4_SA1111_BASE, BADGE4_IRQ_GPIO_SA1111); + return platform_add_devices(devices, ARRAY_SIZE(devices)); } diff --git a/arch/arm/mach-sa1100/dma.c b/arch/arm/mach-sa1100/dma.c index 8366f546a0d8..be0e4427bec7 100644 --- a/arch/arm/mach-sa1100/dma.c +++ b/arch/arm/mach-sa1100/dma.c @@ -42,7 +42,7 @@ static sa1100_dma_t dma_chan[SA1100_DMA_CHANNELS]; static spinlock_t dma_list_lock; -static void dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) { dma_regs_t *dma_regs = dev_id; sa1100_dma_t *dma = dma_chan + (((u_int)dma_regs >> 5) & 7); @@ -60,6 +60,7 @@ static void dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs) if (status & DCSR_DONEB) dma->callback(dma->data); } + return IRQ_HANDLED; } diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index 7af13269ddf0..3b6652427633 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -16,11 +16,13 @@ #include <linux/delay.h> #include <linux/pm.h> #include <linux/cpufreq.h> +#include <linux/ioport.h> #include <asm/hardware.h> #include <asm/system.h> #include <asm/pgtable.h> #include <asm/mach/map.h> +#include <asm/irq.h> #include "generic.h" @@ -128,13 +130,88 @@ static void sa1100_power_off(void) PMCR = PMCR_SF; } +static struct resource sa11x0udc_resources[] = { + [0] = { + .start = 0x80000000, + .end = 0x8000ffff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device sa11x0udc_device = { + .name = "sa11x0-udc", + .id = 0, + .dev = { + .name = "Intel Corporation SA11x0 [UDC]", + }, + .num_resources = ARRAY_SIZE(sa11x0udc_resources), + .resource = sa11x0udc_resources, +}; + +static struct resource sa11x0mcp_resources[] = { + [0] = { + .start = 0x80060000, + .end = 0x8006ffff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device sa11x0mcp_device = { + .name = "sa11x0-mcp", + .id = 0, + .dev = { + .name = "Intel Corporation SA11x0 [MCP]", + }, + .num_resources = ARRAY_SIZE(sa11x0mcp_resources), + .resource = sa11x0mcp_resources, +}; + +static struct resource sa11x0fb_resources[] = { + [0] = { + .start = 0xb0100000, + .end = 0xb010ffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_LCD, + .end = IRQ_LCD, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device sa11x0fb_device = { + .name = "sa11x0-fb", + .id = 0, + .dev = { + .name = "Intel Corporation SA11x0 [LCD]", + }, + .num_resources = ARRAY_SIZE(sa11x0fb_resources), + .resource = sa11x0fb_resources, +}; + +static struct platform_device sa11x0pcmcia_device = { + .name = "sa11x0-pcmcia", + .id = 0, + .dev = { + .name = "Intel Corporation SA11x0 [PCMCIA]", + }, +}; + +static struct platform_device *sa11x0_devices[] __initdata = { + &sa11x0udc_device, + &sa11x0mcp_device, + &sa11x0pcmcia_device, + &sa11x0fb_device, +}; + static int __init sa1100_init(void) { pm_power_off = sa1100_power_off; - return 0; + + return platform_add_devices(sa11x0_devices, ARRAY_SIZE(sa11x0_devices)); } -core_initcall(sa1100_init); +arch_initcall(sa1100_init); void (*sa1100fb_backlight_power)(int on); void (*sa1100fb_lcd_power)(int on); diff --git a/arch/arm/mach-sa1100/graphicsmaster.c b/arch/arm/mach-sa1100/graphicsmaster.c index db88613a49ce..94c827b72b71 100644 --- a/arch/arm/mach-sa1100/graphicsmaster.c +++ b/arch/arm/mach-sa1100/graphicsmaster.c @@ -24,6 +24,36 @@ #include "generic.h" +static struct resource sa1111_resources[] = { + [0] = { + .start = 0x18000000, + .end = 0x18001fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = ADS_EXT_IRQ(0), + .end = ADS_EXT_IRQ(0), + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 sa1111_dmamask = 0xffffffffUL; + +static struct platform_device sa1111_device = { + .name = "sa1111", + .id = 0, + .dev = { + .name = "Intel Corporation SA1111", + .dma_mask = &sa1111_dmamask, + }, + .num_resources = ARRAY_SIZE(sa1111_resources), + .resource = sa1111_resources, +}; + +static struct platform_device *devices[] __initdata = { + &sa1111_device, +}; + static int __init graphicsmaster_init(void) { int ret; @@ -40,7 +70,7 @@ static int __init graphicsmaster_init(void) /* * Probe for SA1111. */ - ret = sa1111_init(0x18000000, ADS_EXT_IRQ(0)); + ret = platform_add_devices(devices, ARRAY_SIZE(devices)); if (ret < 0) return ret; diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c index 7fabd6b89ad6..25bddcac9520 100644 --- a/arch/arm/mach-sa1100/jornada720.c +++ b/arch/arm/mach-sa1100/jornada720.c @@ -24,6 +24,36 @@ #define JORTUCR_VAL 0x20000400 +static struct resource sa1111_resources[] = { + [0] = { + .start = 0x40000000, + .end = 0x40001fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_GPIO1, + .end = IRQ_GPIO1, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 sa1111_dmamask = 0xffffffffUL; + +static struct platform_device sa1111_device = { + .name = "sa1111", + .id = 0, + .dev = { + .name = "Intel Corporation SA1111", + .dma_mask = &sa1111_dmamask, + }, + .num_resources = ARRAY_SIZE(sa1111_resources), + .resource = sa1111_resources, +}; + +static struct platform_device *devices[] __initdata = { + &sa1111_device, +}; + static int __init jornada720_init(void) { int ret = -ENODEV; @@ -43,7 +73,7 @@ static int __init jornada720_init(void) PPSR &= ~(PPC_LDD3 | PPC_LDD4); PPDR |= PPC_LDD3 | PPC_LDD4; - ret = sa1111_init(0x40000000, IRQ_GPIO1); + ret = platform_add_devices(devices, ARRAY_SIZE(devices)); } return ret; } diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index 1d6362864fab..7a26337b4c3f 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -79,33 +79,6 @@ neponset_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *reg } } -static inline void __init neponset_init_irq(void) -{ - /* - * Install handler for GPIO25. - */ - set_irq_type(IRQ_GPIO25, IRQT_RISING); - set_irq_chained_handler(IRQ_GPIO25, neponset_irq_handler); - - /* - * We would set IRQ_GPIO25 to be a wake-up IRQ, but - * unfortunately something on the Neponset activates - * this IRQ on sleep (ethernet?) - */ -#if 0 - enable_irq_wake(IRQ_GPIO25); -#endif - - /* - * Setup other Neponset IRQs. SA1111 will be done by the - * generic SA1111 code. - */ - set_irq_handler(IRQ_NEPONSET_SMC9196, do_simple_IRQ); - set_irq_flags(IRQ_NEPONSET_SMC9196, IRQF_VALID | IRQF_PROBE); - set_irq_handler(IRQ_NEPONSET_USAR, do_simple_IRQ); - set_irq_flags(IRQ_NEPONSET_USAR, IRQF_VALID | IRQF_PROBE); -} - static void neponset_set_mctrl(struct uart_port *port, u_int mctrl) { u_int mdm_ctl0 = MDM_CTL_0; @@ -164,6 +137,42 @@ static struct sa1100_port_fns neponset_port_fns __initdata = { .get_mctrl = neponset_get_mctrl, }; +static int neponset_probe(struct device *dev) +{ + sa1100_register_uart_fns(&neponset_port_fns); + + /* + * Install handler for GPIO25. + */ + set_irq_type(IRQ_GPIO25, IRQT_RISING); + set_irq_chained_handler(IRQ_GPIO25, neponset_irq_handler); + + /* + * We would set IRQ_GPIO25 to be a wake-up IRQ, but + * unfortunately something on the Neponset activates + * this IRQ on sleep (ethernet?) + */ +#if 0 + enable_irq_wake(IRQ_GPIO25); +#endif + + /* + * Setup other Neponset IRQs. SA1111 will be done by the + * generic SA1111 code. + */ + set_irq_handler(IRQ_NEPONSET_SMC9196, do_simple_IRQ); + set_irq_flags(IRQ_NEPONSET_SMC9196, IRQF_VALID | IRQF_PROBE); + set_irq_handler(IRQ_NEPONSET_USAR, do_simple_IRQ); + set_irq_flags(IRQ_NEPONSET_USAR, IRQF_VALID | IRQF_PROBE); + + /* + * Disable GPIO 0/1 drivers so the buttons work on the module. + */ + NCR_0 = NCR_GP01_OFF; + + return 0; +} + /* * LDM power management. */ @@ -201,27 +210,63 @@ static int neponset_resume(struct device *dev, u32 level) static struct device_driver neponset_device_driver = { .name = "neponset", - .bus = &system_bus_type, + .bus = &platform_bus_type, + .probe = neponset_probe, .suspend = neponset_suspend, .resume = neponset_resume, }; -static struct sys_device neponset_device = { - .name = "NEPONSET", +static struct resource neponset_resources[] = { + [0] = { + .start = 0x10000000, + .end = 0x17ffffff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device neponset_device = { + .name = "neponset", .id = 0, - .root = NULL, .dev = { .name = "Neponset", - .bus_id = "neponset", - .bus = &system_bus_type, - .driver = &neponset_device_driver, + }, + .num_resources = ARRAY_SIZE(neponset_resources), + .resource = neponset_resources, +}; + +static struct resource sa1111_resources[] = { + [0] = { + .start = 0x40000000, + .end = 0x40001fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_NEPONSET_SA1111, + .end = IRQ_NEPONSET_SA1111, + .flags = IORESOURCE_IRQ, }, }; +static u64 sa1111_dmamask = 0xffffffffUL; + +static struct platform_device sa1111_device = { + .name = "sa1111", + .id = 0, + .dev = { + .name = "Intel Corporation SA1111", + .dma_mask = &sa1111_dmamask, + }, + .num_resources = ARRAY_SIZE(sa1111_resources), + .resource = sa1111_resources, +}; + +static struct platform_device *devices[] __initdata = { + &neponset_device, + &sa1111_device, +}; + static int __init neponset_init(void) { - int ret; - driver_register(&neponset_device_driver); /* @@ -248,29 +293,7 @@ static int __init neponset_init(void) return -ENODEV; } - ret = sys_device_register(&neponset_device); - if (ret) - return ret; - - sa1100_register_uart_fns(&neponset_port_fns); - - neponset_init_irq(); - - /* - * Disable GPIO 0/1 drivers so the buttons work on the module. - */ - NCR_0 = NCR_GP01_OFF; - - /* - * Neponset has SA1111 connected to CS4. We know that after - * reset the chip will be configured for variable latency IO. - */ - /* FIXME: setup MSC2 */ - - /* - * Probe and initialise the SA1111. - */ - return sa1111_init(0x40000000, IRQ_NEPONSET_SA1111); + return platform_add_devices(devices, ARRAY_SIZE(devices)); } subsys_initcall(neponset_init); diff --git a/arch/arm/mach-sa1100/pfs168.c b/arch/arm/mach-sa1100/pfs168.c index d17c1a79e785..8a811c939b2c 100644 --- a/arch/arm/mach-sa1100/pfs168.c +++ b/arch/arm/mach-sa1100/pfs168.c @@ -7,6 +7,7 @@ #include <linux/tty.h> #include <linux/errno.h> #include <linux/ioport.h> +#include <linux/device.h> #include <asm/hardware.h> #include <asm/mach-types.h> @@ -18,6 +19,35 @@ #include "generic.h" +static struct resource sa1111_resources[] = { + [0] = { + .start = 0x40000000, + .end = 0x40001fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_GPIO25, + .end = IRQ_GPIO25, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 sa1111_dmamask = 0xffffffffUL; + +static struct platform_device sa1111_device = { + .name = "sa1111", + .id = 0, + .dev = { + .name = "Intel Corporation SA1111", + .dma_mask = &sa1111_dmamask, + }, + .num_resources = ARRAY_SIZE(sa1111_resources), + .resource = sa1111_resources, +}; + +static struct platform_device *devices[] __initdata = { + &sa1111_device, +}; static int __init pfs168_init(void) { @@ -32,10 +62,7 @@ static int __init pfs168_init(void) */ sa1110_mb_disable(); - /* - * Probe for SA1111. - */ - return sa1111_init(0x40000000, IRQ_GPIO25); + return platform_add_devices(devices, ARRAY_SIZE(devices)); } arch_initcall(pfs168_init); diff --git a/arch/arm/mach-sa1100/system3.c b/arch/arm/mach-sa1100/system3.c index a7177a023a79..264d73dbe108 100644 --- a/arch/arm/mach-sa1100/system3.c +++ b/arch/arm/mach-sa1100/system3.c @@ -373,6 +373,36 @@ static void system3_backlight_power(int on) } } +static struct resource sa1111_resources[] = { + [0] = { + .start = PT_SA1111_BASE, + .end = PT_SA1111_BASE + 0x00001fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_SYSTEM3_SA1111, + .end = IRQ_SYSTEM3_SA1111, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 sa1111_dmamask = 0xffffffffUL; + +static struct platform_device sa1111_device = { + .name = "sa1111", + .id = 0, + .dev = { + .name = "Intel Corporation SA1111", + .dma_mask = &sa1111_dmamask, + }, + .num_resources = ARRAY_SIZE(sa1111_resources), + .resource = sa1111_resources, +}; + +static struct platform_device *devices[] __initdata = { + &sa1111_device, +}; + static int __init system3_init(void) { int ret = 0; @@ -405,7 +435,7 @@ static int __init system3_init(void) /* * Probe for a SA1111. */ - ret = sa1111_init(PT_SA1111_BASE, IRQ_SYSTEM3_SA1111); + ret = platform_add_devices(devices, ARRAY_SIZE(devices)); if (ret < 0) { printk( KERN_WARNING"PT Digital Board: no SA1111 found!\n" ); goto DONE; diff --git a/arch/arm/mach-sa1100/xp860.c b/arch/arm/mach-sa1100/xp860.c index 35fc6b833a72..4caf6f19e6a8 100644 --- a/arch/arm/mach-sa1100/xp860.c +++ b/arch/arm/mach-sa1100/xp860.c @@ -30,6 +30,31 @@ static void xp860_power_off(void) while(1); } +static struct resource sa1111_resources[] = { + [0] = { + .start = 0x40000000, + .end = 0x40001fff, + .flags = IORESOURCE_MEM, + }, +}; + +static u64 sa1111_dmamask = 0xffffffffUL; + +static struct platform_device sa1111_device = { + .name = "sa1111", + .id = 0, + .dev = { + .name = "Intel Corporation SA1111", + .dma_mask = &sa1111_dmamask, + }, + .num_resources = ARRAY_SIZE(sa1111_resources), + .resource = sa1111_resources, +}; + +static struct platform_device *devices[] __initdata = { + &sa1111_device, +}; + /* * Note: I replaced the sa1111_init() without the full SA1111 initialisation * because this machine doesn't appear to use the DMA features. If this is @@ -39,19 +64,7 @@ static int __init xp860_init(void) { pm_power_off = xp860_power_off; - /* - * Probe for SA1111. - */ - ret = sa1111_probe(0x40000000); - if (ret < 0) - return ret; - - /* - * We found it. Wake the chip up. - */ - sa1111_wake(); - - return 0; + return platform_add_devices(devices, ARRAY_SIZE(devices)); } arch_initcall(xp860_init); diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c index 9905eadd83f1..7c572275f4fd 100644 --- a/arch/arm/mm/consistent.c +++ b/arch/arm/mm/consistent.c @@ -10,7 +10,7 @@ * DMA uncached mapping support. */ #include <linux/config.h> -#include <linux/types.h> +#include <linux/module.h> #include <linux/mm.h> #include <linux/slab.h> #include <linux/string.h> @@ -145,6 +145,7 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle, struct vm_region *c; unsigned long order, flags; void *ret = NULL; + int res; if (!consistent_pte) { printk(KERN_ERR "consistent_alloc: not initialised\n"); @@ -177,14 +178,19 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle, if (!c) goto no_remap; - spin_lock_irqsave(&consistent_lock, flags); - vm_region_dump(&consistent_head, "before alloc"); - /* * Attempt to allocate a virtual address in the * consistent mapping region. */ - if (!vm_region_alloc(&consistent_head, c, size)) { + spin_lock_irqsave(&consistent_lock, flags); + vm_region_dump(&consistent_head, "before alloc"); + + res = vm_region_alloc(&consistent_head, c, size); + + vm_region_dump(&consistent_head, "after alloc"); + spin_unlock_irqrestore(&consistent_lock, flags); + + if (!res) { pte_t *pte = consistent_pte + CONSISTENT_OFFSET(c->vm_start); struct page *end = page + (1 << order); pgprot_t prot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | @@ -218,9 +224,6 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle, ret = (void *)c->vm_start; } - vm_region_dump(&consistent_head, "after alloc"); - spin_unlock_irqrestore(&consistent_lock, flags); - no_remap: if (ret == NULL) { kfree(c); @@ -231,6 +234,22 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle, } /* + * Since we have the DMA mask available to us here, we could try to do + * a normal allocation, and only fall back to a "DMA" allocation if the + * resulting bus address does not satisfy the dma_mask requirements. + */ +void * +dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, int gfp) +{ + if (dev == NULL || *dev->dma_mask != 0xffffffff) + gfp |= GFP_DMA; + + return consistent_alloc(gfp, size, handle, 0); +} + +EXPORT_SYMBOL(dma_alloc_coherent); + +/* * free a page as defined by the above mapping. */ void consistent_free(void *vaddr, size_t size, dma_addr_t handle) diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c index c0ca4d0807d2..1631abc4cfe3 100644 --- a/drivers/video/sa1100fb.c +++ b/drivers/video/sa1100fb.c @@ -1753,25 +1753,7 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(void) return fbi; } -static struct device_driver sa1100fb_driver = { - .name = "sa1100fb", - .bus = &system_bus_type, - .suspend = sa1100fb_suspend, - .resume = sa1100fb_resume, -}; - -static struct sys_device sa1100fb_dev = { - .name = "LCD", - .id = 0, - .root = NULL, - .dev = { - .name = "Intel Corporation SA11x0 [LCD]", - .bus_id = "b0100000", - .driver = &sa1100fb_driver, - }, -}; - -int __init sa1100fb_init(void) +static int __init sa1100fb_probe(struct device *dev) { struct sa1100fb_info *fbi; int ret; @@ -1779,16 +1761,11 @@ int __init sa1100fb_init(void) if (!request_mem_region(0xb0100000, 0x10000, "LCD")) return -EBUSY; - driver_register(&sa1100fb_driver); - sys_device_register(&sa1100fb_dev); - fbi = sa1100fb_init_fbinfo(); ret = -ENOMEM; if (!fbi) goto failed; - dev_set_drvdata(&sa1100fb_dev.dev, fbi); - /* Initialize video memory */ ret = sa1100fb_map_video_memory(fbi); if (ret) @@ -1822,6 +1799,8 @@ int __init sa1100fb_init(void) */ sa1100fb_check_var(&fbi->fb.var, &fbi->fb); + dev_set_drvdata(dev, fbi); + ret = register_framebuffer(&fbi->fb); if (ret < 0) goto failed; @@ -1839,14 +1818,26 @@ int __init sa1100fb_init(void) return 0; failed: - sys_device_unregister(&sa1100fb_dev); - driver_unregister(&sa1100fb_driver); + dev_set_drvdata(dev, NULL); if (fbi) kfree(fbi); release_mem_region(0xb0100000, 0x10000); return ret; } +static struct device_driver sa1100fb_driver = { + .name = "sa11x0-fb", + .bus = &platform_bus_type, + .probe = sa1100fb_probe, + .suspend = sa1100fb_suspend, + .resume = sa1100fb_resume, +}; + +int __init sa1100fb_init(void) +{ + return driver_register(&sa1100fb_driver); +} + int __init sa1100fb_setup(char *options) { #if 0 diff --git a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h index 542f5cff343b..1a0443794320 100644 --- a/include/asm-arm/dma-mapping.h +++ b/include/asm-arm/dma-mapping.h @@ -42,12 +42,12 @@ extern struct bus_type sa1111_bus_type; /* * Return whether the given device DMA address mask can be supported * properly. For example, if your device can only drive the low 24-bits - * during PCI bus mastering, then you would pass 0x00ffffff as the mask + * during bus mastering, then you would pass 0x00ffffff as the mask * to this function. */ static inline int dma_supported(struct device *dev, u64 mask) { - return 1; + return dev->dma_mask && *dev->dma_mask != 0; } static inline int dma_set_mask(struct device *dev, u64 dma_mask) @@ -81,14 +81,8 @@ static inline int dma_is_consistent(dma_addr_t handle) * return the CPU-viewed address, and sets @handle to be the * device-viewed address. */ -static inline void * -dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, int gfp) -{ - if (dev == NULL || dmadev_is_sa1111(dev) || *dev->dma_mask != 0xffffffff) - gfp |= GFP_DMA; - - return consistent_alloc(gfp, size, handle, 0); -} +extern void * +dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, int gfp); /** * dma_free_coherent - free memory allocated by dma_alloc_coherent diff --git a/include/asm-arm/hardware.h b/include/asm-arm/hardware.h index 1fd1a5b6504b..0712491cfdc4 100644 --- a/include/asm-arm/hardware.h +++ b/include/asm-arm/hardware.h @@ -15,4 +15,13 @@ #include <asm/arch/hardware.h> +#ifndef __ASSEMBLY__ + +struct platform_device; + +extern int platform_add_devices(struct platform_device *, int); +extern int platform_add_device(struct platform_device *); + +#endif + #endif diff --git a/include/linux/device.h b/include/linux/device.h index 8e3f1919d974..577ac546e48d 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -385,6 +385,8 @@ struct platform_device { struct resource * resource; }; +#define to_platform_device(x) container_of((x), struct platform_device, dev) + extern int platform_device_register(struct platform_device *); extern void platform_device_unregister(struct platform_device *); |
