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 @@
# 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
#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.
*/
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
......
......@@ -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));
}
......
......@@ -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);
......
......@@ -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
......
......@@ -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