Commit 3f3bdf8e authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://bk.arm.linux.org.uk/linux-2.5-rmk

into home.transmeta.com:/home/torvalds/v2.5/linux
parents fbf47415 8698cff8
......@@ -2,7 +2,7 @@
# Makefile for the linux kernel.
#
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
#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;
}
......@@ -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.
*/
if (irq != NO_IRQ) {
int_dev.irq[0] = irq;
sa1111_init_one_child(sachip, &int_dev, SA1111_INTC);
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
......
......@@ -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)
{
......
......@@ -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
......
/*
* 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
/*
* 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
/*
* 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);
}
}
}
......@@ -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)
......
......@@ -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);
......
......@@ -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;
......
......@@ -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));
}
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
......@@ -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);
......@@ -230,6 +233,22 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle,
return ret;
}
/*
* 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.
*/
......
......@@ -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
......
......@@ -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
......
......@@ -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
......@@ -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 *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment