Commit 4f00f1c2 authored by Russell King's avatar Russell King

[ARM] Convert platform devices to use platform_device

Since struct platform_device now has the ability to pass resources,
defined by the platform to the device driver, we can now use this
to handle platform specific devices.  One such instance is the
StrongARM SA1111 companion chip, which can appear in various address
spaces, and connected to different IRQ lines depending on how many
cups of coffee the hardware designer had, the direction of the wind
outside the designers office that day.

We also convert some of the other StrongARM peripheral on-chip
devices to use struct platform_device.

ARM also provides a platform_add_devices() function which can be
used by platform code to bulk-register a tabular set of platform
devices.
parent 9ae27c57
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Makefile for the linux kernel. # Makefile for the linux kernel.
# #
obj-y += platform.o
obj-$(CONFIG_SA1111) += sa1111.o sa1111-pcibuf.o sa1111-pcipool.o obj-$(CONFIG_SA1111) += sa1111.o sa1111-pcibuf.o sa1111-pcipool.o
obj-$(CONFIG_PCI_HOST_PLX90X0) += plx90x0.o obj-$(CONFIG_PCI_HOST_PLX90X0) += plx90x0.o
obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.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 @@ ...@@ -42,7 +42,7 @@
*/ */
struct sa1111 { struct sa1111 {
struct device *dev; struct device *dev;
struct resource res; unsigned long phys;
int irq; int irq;
spinlock_t lock; spinlock_t lock;
void *base; void *base;
...@@ -60,7 +60,6 @@ static struct sa1111_dev usb_dev = { ...@@ -60,7 +60,6 @@ static struct sa1111_dev usb_dev = {
}, },
.skpcr_mask = SKPCR_UCLKEN, .skpcr_mask = SKPCR_UCLKEN,
.devid = SA1111_DEVID_USB, .devid = SA1111_DEVID_USB,
.dma_mask = 0xffffffffLL,
.irq = { .irq = {
IRQ_USBPWR, IRQ_USBPWR,
IRQ_HCIM, IRQ_HCIM,
...@@ -470,6 +469,17 @@ static void sa1111_wake(struct sa1111 *sachip) ...@@ -470,6 +469,17 @@ static void sa1111_wake(struct sa1111 *sachip)
#ifdef CONFIG_ARCH_SA1100 #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. * Configure the SA1111 shared memory controller.
*/ */
...@@ -483,26 +493,43 @@ sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac, ...@@ -483,26 +493,43 @@ sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac,
smcr |= SMCR_CLAT; smcr |= SMCR_CLAT;
sa1111_writel(smcr, sachip->base + SA1111_SMCR); 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 #endif
static void 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), snprintf(sadev->dev.bus_id, sizeof(sadev->dev.bus_id),
"%4.4x", offset); "%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.parent = sachip->dev;
sadev->dev.bus = &sa1111_bus_type; sadev->dev.bus = &sa1111_bus_type;
sadev->dev.dma_mask = &sadev->dma_mask; sadev->res.start = sachip->phys + offset;
sadev->res.start = sachip->res.start + offset;
sadev->res.end = sadev->res.start + 511; sadev->res.end = sadev->res.start + 511;
sadev->res.name = sadev->dev.name; sadev->res.name = sadev->dev.name;
sadev->res.flags = IORESOURCE_MEM; sadev->res.flags = IORESOURCE_MEM;
sadev->mapbase = sachip->base + offset; 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", printk("SA1111: failed to allocate resource for %s\n",
sadev->res.name); sadev->res.name);
return; return;
...@@ -524,7 +551,7 @@ sa1111_init_one_child(struct sa1111 *sachip, struct sa1111_dev *sadev, unsigned ...@@ -524,7 +551,7 @@ sa1111_init_one_child(struct sa1111 *sachip, struct sa1111_dev *sadev, unsigned
* %0 successful. * %0 successful.
*/ */
static int __init 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; struct sa1111 *sachip;
unsigned long id; unsigned long id;
...@@ -542,24 +569,17 @@ __sa1111_probe(struct device *me, unsigned long phys_addr, int irq) ...@@ -542,24 +569,17 @@ __sa1111_probe(struct device *me, unsigned long phys_addr, int irq)
sachip->dev = me; sachip->dev = me;
dev_set_drvdata(sachip->dev, sachip); dev_set_drvdata(sachip->dev, sachip);
sachip->res.name = me->name; sachip->phys = mem->start;
sachip->res.start = phys_addr;
sachip->res.end = phys_addr + 0x2000;
sachip->irq = irq; sachip->irq = irq;
if (request_resource(&iomem_resource, &sachip->res)) {
ret = -EBUSY;
goto out;
}
/* /*
* Map the whole region. This also maps the * Map the whole region. This also maps the
* registers for our children. * registers for our children.
*/ */
sachip->base = ioremap(phys_addr, PAGE_SIZE * 2); sachip->base = ioremap(mem->start, PAGE_SIZE * 2);
if (!sachip->base) { if (!sachip->base) {
ret = -ENOMEM; ret = -ENOMEM;
goto release; goto out;
} }
/* /*
...@@ -611,9 +631,11 @@ __sa1111_probe(struct device *me, unsigned long phys_addr, int irq) ...@@ -611,9 +631,11 @@ __sa1111_probe(struct device *me, unsigned long phys_addr, int irq)
* The interrupt controller must be initialised before any * The interrupt controller must be initialised before any
* other device to ensure that the interrupts are available. * other device to ensure that the interrupts are available.
*/ */
if (irq != NO_IRQ) {
int_dev.irq[0] = 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); sa1111_init_irq(&int_dev);
}
g_sa1111 = sachip; g_sa1111 = sachip;
...@@ -626,14 +648,12 @@ __sa1111_probe(struct device *me, unsigned long phys_addr, int irq) ...@@ -626,14 +648,12 @@ __sa1111_probe(struct device *me, unsigned long phys_addr, int irq)
for (i = 0; i < ARRAY_SIZE(devs); i++) for (i = 0; i < ARRAY_SIZE(devs); i++)
if (has_devs & (1 << 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; return 0;
unmap: unmap:
iounmap(sachip->base); iounmap(sachip->base);
release:
release_resource(&sachip->res);
out: out:
kfree(sachip); kfree(sachip);
return ret; return ret;
...@@ -649,7 +669,6 @@ static void __sa1111_remove(struct sa1111 *sachip) ...@@ -649,7 +669,6 @@ static void __sa1111_remove(struct sa1111 *sachip)
} }
iounmap(sachip->base); iounmap(sachip->base);
release_resource(&sachip->res);
kfree(sachip); kfree(sachip);
} }
...@@ -874,7 +893,17 @@ static int sa1111_resume(struct device *dev, u32 level) ...@@ -874,7 +893,17 @@ static int sa1111_resume(struct device *dev, u32 level)
static int sa1111_probe(struct device *dev) 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) static int sa1111_remove(struct device *dev)
...@@ -903,7 +932,7 @@ 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 = { static struct device_driver sa1111_device_driver = {
.name = "sa1111", .name = "sa1111",
.bus = &system_bus_type, .bus = &platform_bus_type,
.probe = sa1111_probe, .probe = sa1111_probe,
.remove = sa1111_remove, .remove = sa1111_remove,
.suspend = sa1111_suspend, .suspend = sa1111_suspend,
...@@ -921,29 +950,6 @@ static int sa1111_driver_init(void) ...@@ -921,29 +950,6 @@ static int sa1111_driver_init(void)
arch_initcall(sa1111_driver_init); 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 * Get the parent device driver (us) structure
* from a child function device * from a child function device
......
...@@ -88,9 +88,36 @@ static void __init lubbock_init_irq(void) ...@@ -88,9 +88,36 @@ static void __init lubbock_init_irq(void)
set_irq_type(IRQ_GPIO(0), IRQT_FALLING); 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) 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); subsys_initcall(lubbock_init);
......
...@@ -27,6 +27,36 @@ ...@@ -27,6 +27,36 @@
#include "generic.h" #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) static int __init adsbitsy_init(void)
{ {
int ret; int ret;
...@@ -50,7 +80,7 @@ static int __init adsbitsy_init(void) ...@@ -50,7 +80,7 @@ static int __init adsbitsy_init(void)
/* /*
* Probe for SA1111. * Probe for SA1111.
*/ */
ret = sa1111_init(0x18000000, IRQ_GPIO0); ret = platform_add_devices(devices, ARRAY_SIZE(devices));
if (ret < 0) if (ret < 0)
return ret; return ret;
......
...@@ -35,6 +35,36 @@ ...@@ -35,6 +35,36 @@
#include "generic.h" #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) static int __init badge4_sa1111_init(void)
{ {
/* /*
...@@ -46,7 +76,7 @@ static int __init badge4_sa1111_init(void) ...@@ -46,7 +76,7 @@ static int __init badge4_sa1111_init(void)
/* /*
* Probe for SA1111. * Probe for SA1111.
*/ */
return sa1111_init(BADGE4_SA1111_BASE, BADGE4_IRQ_GPIO_SA1111); return platform_add_devices(devices, ARRAY_SIZE(devices));
} }
......
...@@ -16,11 +16,13 @@ ...@@ -16,11 +16,13 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/pm.h> #include <linux/pm.h>
#include <linux/cpufreq.h> #include <linux/cpufreq.h>
#include <linux/ioport.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/mach/map.h> #include <asm/mach/map.h>
#include <asm/irq.h>
#include "generic.h" #include "generic.h"
...@@ -128,13 +130,88 @@ static void sa1100_power_off(void) ...@@ -128,13 +130,88 @@ static void sa1100_power_off(void)
PMCR = PMCR_SF; 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) static int __init sa1100_init(void)
{ {
pm_power_off = sa1100_power_off; 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_backlight_power)(int on);
void (*sa1100fb_lcd_power)(int on); void (*sa1100fb_lcd_power)(int on);
......
...@@ -24,6 +24,36 @@ ...@@ -24,6 +24,36 @@
#include "generic.h" #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) static int __init graphicsmaster_init(void)
{ {
int ret; int ret;
...@@ -40,7 +70,7 @@ static int __init graphicsmaster_init(void) ...@@ -40,7 +70,7 @@ static int __init graphicsmaster_init(void)
/* /*
* Probe for SA1111. * Probe for SA1111.
*/ */
ret = sa1111_init(0x18000000, ADS_EXT_IRQ(0)); ret = platform_add_devices(devices, ARRAY_SIZE(devices));
if (ret < 0) if (ret < 0)
return ret; return ret;
......
...@@ -24,6 +24,36 @@ ...@@ -24,6 +24,36 @@
#define JORTUCR_VAL 0x20000400 #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) static int __init jornada720_init(void)
{ {
int ret = -ENODEV; int ret = -ENODEV;
...@@ -43,7 +73,7 @@ static int __init jornada720_init(void) ...@@ -43,7 +73,7 @@ static int __init jornada720_init(void)
PPSR &= ~(PPC_LDD3 | PPC_LDD4); PPSR &= ~(PPC_LDD3 | PPC_LDD4);
PPDR |= 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; return ret;
} }
......
...@@ -79,33 +79,6 @@ neponset_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *reg ...@@ -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) static void neponset_set_mctrl(struct uart_port *port, u_int mctrl)
{ {
u_int mdm_ctl0 = MDM_CTL_0; u_int mdm_ctl0 = MDM_CTL_0;
...@@ -164,6 +137,42 @@ static struct sa1100_port_fns neponset_port_fns __initdata = { ...@@ -164,6 +137,42 @@ static struct sa1100_port_fns neponset_port_fns __initdata = {
.get_mctrl = neponset_get_mctrl, .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. * LDM power management.
*/ */
...@@ -201,27 +210,63 @@ static int neponset_resume(struct device *dev, u32 level) ...@@ -201,27 +210,63 @@ static int neponset_resume(struct device *dev, u32 level)
static struct device_driver neponset_device_driver = { static struct device_driver neponset_device_driver = {
.name = "neponset", .name = "neponset",
.bus = &system_bus_type, .bus = &platform_bus_type,
.probe = neponset_probe,
.suspend = neponset_suspend, .suspend = neponset_suspend,
.resume = neponset_resume, .resume = neponset_resume,
}; };
static struct sys_device neponset_device = { static struct resource neponset_resources[] = {
.name = "NEPONSET", [0] = {
.start = 0x10000000,
.end = 0x17ffffff,
.flags = IORESOURCE_MEM,
},
};
static struct platform_device neponset_device = {
.name = "neponset",
.id = 0, .id = 0,
.root = NULL,
.dev = { .dev = {
.name = "Neponset", .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) static int __init neponset_init(void)
{ {
int ret;
driver_register(&neponset_device_driver); driver_register(&neponset_device_driver);
/* /*
...@@ -248,29 +293,7 @@ static int __init neponset_init(void) ...@@ -248,29 +293,7 @@ static int __init neponset_init(void)
return -ENODEV; return -ENODEV;
} }
ret = sys_device_register(&neponset_device); return platform_add_devices(devices, ARRAY_SIZE(devices));
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);
} }
subsys_initcall(neponset_init); subsys_initcall(neponset_init);
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/device.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
...@@ -18,6 +19,35 @@ ...@@ -18,6 +19,35 @@
#include "generic.h" #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) static int __init pfs168_init(void)
{ {
...@@ -32,10 +62,7 @@ static int __init pfs168_init(void) ...@@ -32,10 +62,7 @@ static int __init pfs168_init(void)
*/ */
sa1110_mb_disable(); sa1110_mb_disable();
/* return platform_add_devices(devices, ARRAY_SIZE(devices));
* Probe for SA1111.
*/
return sa1111_init(0x40000000, IRQ_GPIO25);
} }
arch_initcall(pfs168_init); arch_initcall(pfs168_init);
......
...@@ -373,6 +373,36 @@ static void system3_backlight_power(int on) ...@@ -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) static int __init system3_init(void)
{ {
int ret = 0; int ret = 0;
...@@ -405,7 +435,7 @@ static int __init system3_init(void) ...@@ -405,7 +435,7 @@ static int __init system3_init(void)
/* /*
* Probe for a SA1111. * Probe for a SA1111.
*/ */
ret = sa1111_init(PT_SA1111_BASE, IRQ_SYSTEM3_SA1111); ret = platform_add_devices(devices, ARRAY_SIZE(devices));
if (ret < 0) { if (ret < 0) {
printk( KERN_WARNING"PT Digital Board: no SA1111 found!\n" ); printk( KERN_WARNING"PT Digital Board: no SA1111 found!\n" );
goto DONE; goto DONE;
......
...@@ -30,6 +30,31 @@ static void xp860_power_off(void) ...@@ -30,6 +30,31 @@ static void xp860_power_off(void)
while(1); 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 * 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 * because this machine doesn't appear to use the DMA features. If this is
...@@ -39,19 +64,7 @@ static int __init xp860_init(void) ...@@ -39,19 +64,7 @@ static int __init xp860_init(void)
{ {
pm_power_off = xp860_power_off; pm_power_off = xp860_power_off;
/* return platform_add_devices(devices, ARRAY_SIZE(devices));
* Probe for SA1111.
*/
ret = sa1111_probe(0x40000000);
if (ret < 0)
return ret;
/*
* We found it. Wake the chip up.
*/
sa1111_wake();
return 0;
} }
arch_initcall(xp860_init); arch_initcall(xp860_init);
......
...@@ -1753,25 +1753,7 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(void) ...@@ -1753,25 +1753,7 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(void)
return fbi; return fbi;
} }
static struct device_driver sa1100fb_driver = { static int __init sa1100fb_probe(struct device *dev)
.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)
{ {
struct sa1100fb_info *fbi; struct sa1100fb_info *fbi;
int ret; int ret;
...@@ -1779,16 +1761,11 @@ int __init sa1100fb_init(void) ...@@ -1779,16 +1761,11 @@ int __init sa1100fb_init(void)
if (!request_mem_region(0xb0100000, 0x10000, "LCD")) if (!request_mem_region(0xb0100000, 0x10000, "LCD"))
return -EBUSY; return -EBUSY;
driver_register(&sa1100fb_driver);
sys_device_register(&sa1100fb_dev);
fbi = sa1100fb_init_fbinfo(); fbi = sa1100fb_init_fbinfo();
ret = -ENOMEM; ret = -ENOMEM;
if (!fbi) if (!fbi)
goto failed; goto failed;
dev_set_drvdata(&sa1100fb_dev.dev, fbi);
/* Initialize video memory */ /* Initialize video memory */
ret = sa1100fb_map_video_memory(fbi); ret = sa1100fb_map_video_memory(fbi);
if (ret) if (ret)
...@@ -1822,6 +1799,8 @@ int __init sa1100fb_init(void) ...@@ -1822,6 +1799,8 @@ int __init sa1100fb_init(void)
*/ */
sa1100fb_check_var(&fbi->fb.var, &fbi->fb); sa1100fb_check_var(&fbi->fb.var, &fbi->fb);
dev_set_drvdata(dev, fbi);
ret = register_framebuffer(&fbi->fb); ret = register_framebuffer(&fbi->fb);
if (ret < 0) if (ret < 0)
goto failed; goto failed;
...@@ -1839,14 +1818,26 @@ int __init sa1100fb_init(void) ...@@ -1839,14 +1818,26 @@ int __init sa1100fb_init(void)
return 0; return 0;
failed: failed:
sys_device_unregister(&sa1100fb_dev); dev_set_drvdata(dev, NULL);
driver_unregister(&sa1100fb_driver);
if (fbi) if (fbi)
kfree(fbi); kfree(fbi);
release_mem_region(0xb0100000, 0x10000); release_mem_region(0xb0100000, 0x10000);
return ret; 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) int __init sa1100fb_setup(char *options)
{ {
#if 0 #if 0
......
...@@ -15,4 +15,13 @@ ...@@ -15,4 +15,13 @@
#include <asm/arch/hardware.h> #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 #endif
...@@ -385,6 +385,8 @@ struct platform_device { ...@@ -385,6 +385,8 @@ struct platform_device {
struct resource * resource; struct resource * resource;
}; };
#define to_platform_device(x) container_of((x), struct platform_device, dev)
extern int platform_device_register(struct platform_device *); extern int platform_device_register(struct platform_device *);
extern void platform_device_unregister(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