Skip to content

Commit

Permalink
ux500: rework device registration
Browse files Browse the repository at this point in the history
Change the Ux500 devices to be dynamically allocated and added by
calling functions instead of referencing structures, thereby allowing
5500 and other derivatives' support to be added without having to
duplicate structures, use fixup functions, or use compile-time macros.

Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
  • Loading branch information
Rabin Vincent authored and Linus Walleij committed Dec 8, 2010
1 parent 1bde668 commit fbf1ead
Show file tree
Hide file tree
Showing 15 changed files with 395 additions and 263 deletions.
2 changes: 1 addition & 1 deletion arch/arm/mach-ux500/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Makefile for the linux kernel, U8500 machine.
#

obj-y := clock.o cpu.o devices.o
obj-y := clock.o cpu.o devices.o devices-common.o
obj-$(CONFIG_UX500_SOC_DB5500) += cpu-db5500.o devices-db5500.o
obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o prcmu.o
obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o board-mop500-sdi.o
Expand Down
11 changes: 4 additions & 7 deletions arch/arm/mach-ux500/board-mop500-sdi.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <mach/devices.h>
#include <mach/hardware.h>

#include "devices-db8500.h"
#include "pins-db8500.h"
#include "board-mop500.h"

Expand Down Expand Up @@ -108,7 +109,7 @@ void mop500_sdi_tc35892_init(void)
gpio_direction_output(GPIO_SDMMC_1V8_3V_SEL, 1);
gpio_direction_output(GPIO_SDMMC_EN, 0);

amba_device_register(&u8500_sdi0_device, &iomem_resource);
db8500_add_sdi0(&mop500_sdi0_data);
}

/*
Expand Down Expand Up @@ -140,15 +141,11 @@ void mop500_sdi_init(void)
{
nmk_config_pins(mop500_sdi_pins, ARRAY_SIZE(mop500_sdi_pins));

u8500_sdi0_device.dev.platform_data = &mop500_sdi0_data;
u8500_sdi2_device.dev.platform_data = &mop500_sdi2_data;
u8500_sdi4_device.dev.platform_data = &mop500_sdi4_data;

if (!cpu_is_u8500ed()) {
nmk_config_pins(mop500_sdi2_pins, ARRAY_SIZE(mop500_sdi2_pins));
amba_device_register(&u8500_sdi2_device, &iomem_resource);
db8500_add_sdi2(&mop500_sdi2_data);
}

/* On-board eMMC */
amba_device_register(&u8500_sdi4_device, &iomem_resource);
db8500_add_sdi4(&mop500_sdi4_data);
}
46 changes: 23 additions & 23 deletions arch/arm/mach-ux500/board-mop500.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <mach/devices.h>
#include <mach/irqs.h>

#include "devices-db8500.h"
#include "pins-db8500.h"
#include "board-mop500.h"

Expand Down Expand Up @@ -192,12 +193,13 @@ U8500_I2C_CONTROLLER(1, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD);
U8500_I2C_CONTROLLER(2, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD);
U8500_I2C_CONTROLLER(3, 0xe, 1, 1, 100000, I2C_FREQ_MODE_STANDARD);

static struct amba_device *amba_devs[] __initdata = {
&ux500_uart0_device,
&ux500_uart1_device,
&ux500_uart2_device,
&u8500_ssp0_device,
};
static void __init mop500_i2c_init(void)
{
db8500_add_i2c0(&u8500_i2c0_data);
db8500_add_i2c1(&u8500_i2c1_data);
db8500_add_i2c2(&u8500_i2c2_data);
db8500_add_i2c3(&u8500_i2c3_data);
}

static const unsigned int ux500_keymap[] = {
KEY(2, 5, KEY_END),
Expand Down Expand Up @@ -308,36 +310,34 @@ static struct ske_keypad_platform_data ske_keypad_board = {

/* add any platform devices here - TODO */
static struct platform_device *platform_devs[] __initdata = {
&u8500_i2c0_device,
&ux500_i2c1_device,
&ux500_i2c2_device,
&ux500_i2c3_device,
&ux500_ske_keypad_device,
};

static void __init u8500_init_machine(void)
static void __init mop500_spi_init(void)
{
int i;
db8500_add_ssp0(&ssp0_platform_data);
}

static void __init mop500_uart_init(void)
{
db8500_add_uart0();
db8500_add_uart1();
db8500_add_uart2();
}

static void __init u8500_init_machine(void)
{
u8500_init_devices();

nmk_config_pins(mop500_pins, ARRAY_SIZE(mop500_pins));

u8500_i2c0_device.dev.platform_data = &u8500_i2c0_data;
ux500_i2c1_device.dev.platform_data = &u8500_i2c1_data;
ux500_i2c2_device.dev.platform_data = &u8500_i2c2_data;
ux500_i2c3_device.dev.platform_data = &u8500_i2c3_data;
ux500_ske_keypad_device.dev.platform_data = &ske_keypad_board;

u8500_ssp0_device.dev.platform_data = &ssp0_platform_data;

/* Register the active AMBA devices on this board */
for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
amba_device_register(amba_devs[i], &iomem_resource);

platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));

mop500_i2c_init();
mop500_sdi_init();
mop500_spi_init();
mop500_uart_init();

/* If HW is early drop (ED) or V1.0 then use SPI to access AB8500 */
if (cpu_is_u8500ed() || cpu_is_u8500v10())
Expand Down
16 changes: 10 additions & 6 deletions arch/arm/mach-ux500/board-u5500.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <linux/platform_device.h>
#include <linux/amba/bus.h>
#include <linux/gpio.h>
#include <linux/irq.h>

#include <asm/mach/arch.h>
#include <asm/mach-types.h>
Expand All @@ -17,17 +18,20 @@
#include <mach/devices.h>
#include <mach/setup.h>

static struct amba_device *amba_board_devs[] __initdata = {
&ux500_uart0_device,
&ux500_uart1_device,
&ux500_uart2_device,
};
#include "devices-db5500.h"

static void __init u5500_uart_init(void)
{
db5500_add_uart0();
db5500_add_uart1();
db5500_add_uart2();
}

static void __init u5500_init_machine(void)
{
u5500_init_devices();

amba_add_devices(amba_board_devs, ARRAY_SIZE(amba_board_devs));
u5500_uart_init();
}

MACHINE_START(U8500, "ST-Ericsson U5500 Platform")
Expand Down
5 changes: 4 additions & 1 deletion arch/arm/mach-ux500/cpu-db5500.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <linux/platform_device.h>
#include <linux/amba/bus.h>
#include <linux/io.h>
#include <linux/irq.h>

#include <asm/mach/map.h>

Expand All @@ -16,6 +17,8 @@
#include <mach/setup.h>
#include <mach/irqs.h>

#include "devices-db5500.h"

static struct map_desc u5500_io_desc[] __initdata = {
__IO_DEV_DESC(U5500_GPIO0_BASE, SZ_4K),
__IO_DEV_DESC(U5500_GPIO1_BASE, SZ_4K),
Expand Down Expand Up @@ -132,7 +135,7 @@ void __init u5500_map_io(void)

void __init u5500_init_devices(void)
{
ux500_init_devices();
db5500_add_rtc();

platform_add_devices(u5500_platform_devs,
ARRAY_SIZE(u5500_platform_devs));
Expand Down
7 changes: 4 additions & 3 deletions arch/arm/mach-ux500/cpu-db8500.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include <mach/setup.h>
#include <mach/devices.h>

#include "devices-db8500.h"

static struct platform_device *platform_devs[] __initdata = {
&u8500_gpio_devs[0],
&u8500_gpio_devs[1],
Expand Down Expand Up @@ -152,12 +154,11 @@ void __init u8500_init_devices(void)
else
pr_warning("ASIC: UNKNOWN SILICON VERSION!\n");

ux500_init_devices();

if (cpu_is_u8500ed())
dma40_u8500ed_fixup();

/* Register the platform devices */
db8500_add_rtc();

platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));

return ;
Expand Down
10 changes: 0 additions & 10 deletions arch/arm/mach-ux500/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*/

#include <linux/platform_device.h>
#include <linux/amba/bus.h>
#include <linux/io.h>
#include <linux/clk.h>

Expand Down Expand Up @@ -45,20 +44,11 @@ static struct map_desc ux500_io_desc[] __initdata = {
__IO_DEV_DESC(UX500_BACKUPRAM0_BASE, SZ_8K),
};

static struct amba_device *ux500_amba_devs[] __initdata = {
&ux500_pl031_device,
};

void __init ux500_map_io(void)
{
iotable_init(ux500_io_desc, ARRAY_SIZE(ux500_io_desc));
}

void __init ux500_init_devices(void)
{
amba_add_devices(ux500_amba_devs, ARRAY_SIZE(ux500_amba_devs));
}

void __init ux500_init_irq(void)
{
gic_dist_init(0, __io_address(UX500_GIC_DIST_BASE), 29);
Expand Down
107 changes: 107 additions & 0 deletions arch/arm/mach-ux500/devices-common.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Copyright (C) ST-Ericsson SA 2010
*
* Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
* License terms: GNU General Public License (GPL), version 2.
*/

#include <linux/kernel.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/amba/bus.h>

#include <mach/hardware.h>

#include "devices-common.h"

struct amba_device *
dbx500_add_amba_device(const char *name, resource_size_t base,
int irq, void *pdata, unsigned int periphid)
{
struct amba_device *dev;
int ret;

dev = kzalloc(sizeof *dev, GFP_KERNEL);
if (!dev)
return ERR_PTR(-ENOMEM);

dev->dev.init_name = name;

dev->res.start = base;
dev->res.end = base + SZ_4K - 1;
dev->res.flags = IORESOURCE_MEM;

dev->dma_mask = DMA_BIT_MASK(32);
dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);

dev->irq[0] = irq;
dev->irq[1] = NO_IRQ;

dev->periphid = periphid;

dev->dev.platform_data = pdata;

ret = amba_device_register(dev, &iomem_resource);
if (ret) {
kfree(dev);
return ERR_PTR(ret);
}

return dev;
}

static struct platform_device *
dbx500_add_platform_device(const char *name, int id, void *pdata,
struct resource *res, int resnum)
{
struct platform_device *dev;
int ret;

dev = platform_device_alloc(name, id);
if (!dev)
return ERR_PTR(-ENOMEM);

dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
dev->dev.dma_mask = &dev->dev.coherent_dma_mask;

ret = platform_device_add_resources(dev, res, resnum);
if (ret)
goto out_free;

dev->dev.platform_data = pdata;

ret = platform_device_add(dev);
if (ret)
goto out_free;

return dev;

out_free:
platform_device_put(dev);
return ERR_PTR(ret);
}

struct platform_device *
dbx500_add_platform_device_4k1irq(const char *name, int id,
resource_size_t base,
int irq, void *pdata)
{
struct resource resources[] = {
[0] = {
.start = base,
.end = base + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = irq,
.end = irq,
.flags = IORESOURCE_IRQ,
}
};

return dbx500_add_platform_device(name, id, pdata, resources,
ARRAY_SIZE(resources));
}
Loading

0 comments on commit fbf1ead

Please sign in to comment.