* [PATCH 0/6] ux500: Export SoC information and some platform clean-up @ 2012-02-01 9:23 Lee Jones 2012-02-01 9:23 ` [PATCH 1/6] mach-ux500: pass parent pointer to each platform device Lee Jones ` (5 more replies) 0 siblings, 6 replies; 13+ messages in thread From: Lee Jones @ 2012-02-01 9:23 UTC (permalink / raw) To: linux-arm-kernel This patch-set satisfies 4 objectives: 1. Ensures each platform device can specify a suitable parent 2. Provides a bus for SoC devices as a means to export information 3. Allows ux500 to make use of the new SoC bus 4. Cleans up unnecessary complexity from ux500 code --- Documentation/ABI/testing/sysfs-devices-soc | 58 ++++++++ arch/arm/mach-ux500/Kconfig | 1 + arch/arm/mach-ux500/board-mop500-sdi.c | 31 ++-- arch/arm/mach-ux500/board-mop500.c | 74 ++++++---- arch/arm/mach-ux500/board-mop500.h | 8 +- arch/arm/mach-ux500/board-u5500-sdi.c | 4 +- arch/arm/mach-ux500/board-u5500.c | 27 ++-- arch/arm/mach-ux500/cpu-db5500.c | 36 ++++- arch/arm/mach-ux500/cpu-db8500.c | 44 +++++- arch/arm/mach-ux500/cpu.c | 75 ++++++++++ arch/arm/mach-ux500/devices-common.c | 79 ++-------- arch/arm/mach-ux500/devices-common.h | 83 ++++++----- arch/arm/mach-ux500/devices-db5500.h | 116 +++++++++------ arch/arm/mach-ux500/devices-db8500.h | 176 +++++++++++++---------- arch/arm/mach-ux500/dma-db5500.c | 3 +- arch/arm/mach-ux500/include/mach/db8500-regs.h | 3 + arch/arm/mach-ux500/include/mach/setup.h | 10 +- arch/arm/mach-ux500/include/mach/usb.h | 4 +- arch/arm/mach-ux500/usb.c | 7 +- drivers/base/Kconfig | 3 + drivers/base/Makefile | 1 + drivers/base/soc.c | 186 ++++++++++++++++++++++++ include/linux/syssoc.h | 74 ++++++++++ 23 files changed, 799 insertions(+), 304 deletions(-) ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/6] mach-ux500: pass parent pointer to each platform device 2012-02-01 9:23 [PATCH 0/6] ux500: Export SoC information and some platform clean-up Lee Jones @ 2012-02-01 9:23 ` Lee Jones 2012-02-01 9:23 ` [PATCH 2/6] drivers/base: add bus for System-on-Chip devices Lee Jones ` (4 subsequent siblings) 5 siblings, 0 replies; 13+ messages in thread From: Lee Jones @ 2012-02-01 9:23 UTC (permalink / raw) To: linux-arm-kernel This patch provides a means for any device within ux500 platform code to allocate its own parent. This is particularly prudent with the introduction of /sys/devices/socX, as a device can now proclaim to be integral part of an SoC, rather than a more generic platform device. Latter patches make good use of this functionality. Signed-off-by: Lee Jones <lee.jones@linaro.org> --- arch/arm/mach-ux500/board-mop500-sdi.c | 31 +++--- arch/arm/mach-ux500/board-mop500.c | 62 ++++++----- arch/arm/mach-ux500/board-mop500.h | 8 +- arch/arm/mach-ux500/board-u5500-sdi.c | 4 +- arch/arm/mach-ux500/board-u5500.c | 23 +++-- arch/arm/mach-ux500/cpu-db5500.c | 18 ++-- arch/arm/mach-ux500/cpu-db8500.c | 15 ++-- arch/arm/mach-ux500/devices-common.c | 13 ++- arch/arm/mach-ux500/devices-common.h | 39 ++++--- arch/arm/mach-ux500/devices-db5500.h | 116 ++++++++++++--------- arch/arm/mach-ux500/devices-db8500.h | 166 +++++++++++++++++------------- arch/arm/mach-ux500/dma-db5500.c | 3 +- arch/arm/mach-ux500/include/mach/setup.h | 8 +- arch/arm/mach-ux500/include/mach/usb.h | 4 +- arch/arm/mach-ux500/usb.c | 4 +- 15 files changed, 289 insertions(+), 225 deletions(-) diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index 23be34b..163c083 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c @@ -104,7 +104,7 @@ static struct mmci_platform_data mop500_sdi0_data = { #endif }; -static void sdi0_configure(void) +static void sdi0_configure(struct device *parent) { int ret; @@ -123,15 +123,15 @@ static void sdi0_configure(void) gpio_direction_output(sdi0_en, 1); /* Add the device, force v2 to subrevision 1 */ - db8500_add_sdi0(&mop500_sdi0_data, U8500_SDI_V2_PERIPHID); + db8500_add_sdi0(parent, &mop500_sdi0_data, U8500_SDI_V2_PERIPHID); } -void mop500_sdi_tc35892_init(void) +void mop500_sdi_tc35892_init(struct device *parent) { mop500_sdi0_data.gpio_cd = GPIO_SDMMC_CD; sdi0_en = GPIO_SDMMC_EN; sdi0_vsel = GPIO_SDMMC_1V8_3V_SEL; - sdi0_configure(); + sdi0_configure(parent); } /* @@ -246,12 +246,13 @@ static struct mmci_platform_data mop500_sdi4_data = { #endif }; -void __init mop500_sdi_init(void) +void __init mop500_sdi_init(struct device *parent) { /* PoP:ed eMMC */ - db8500_add_sdi2(&mop500_sdi2_data, U8500_SDI_V2_PERIPHID); + db8500_add_sdi2(parent, &mop500_sdi2_data, U8500_SDI_V2_PERIPHID); /* On-board eMMC */ - db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID); + db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID); + /* * On boards with the TC35892 GPIO expander, sdi0 will finally * be added when the TC35892 initializes and calls @@ -259,29 +260,29 @@ void __init mop500_sdi_init(void) */ } -void __init snowball_sdi_init(void) +void __init snowball_sdi_init(struct device *parent) { /* On-board eMMC */ - db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID); + db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID); /* External Micro SD slot */ mop500_sdi0_data.gpio_cd = SNOWBALL_SDMMC_CD_GPIO; mop500_sdi0_data.cd_invert = true; sdi0_en = SNOWBALL_SDMMC_EN_GPIO; sdi0_vsel = SNOWBALL_SDMMC_1V8_3V_GPIO; - sdi0_configure(); + sdi0_configure(parent); } -void __init hrefv60_sdi_init(void) +void __init hrefv60_sdi_init(struct device *parent) { /* PoP:ed eMMC */ - db8500_add_sdi2(&mop500_sdi2_data, U8500_SDI_V2_PERIPHID); + db8500_add_sdi2(parent, &mop500_sdi2_data, U8500_SDI_V2_PERIPHID); /* On-board eMMC */ - db8500_add_sdi4(&mop500_sdi4_data, U8500_SDI_V2_PERIPHID); + db8500_add_sdi4(parent, &mop500_sdi4_data, U8500_SDI_V2_PERIPHID); /* External Micro SD slot */ mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO; sdi0_en = HREFV60_SDMMC_EN_GPIO; sdi0_vsel = HREFV60_SDMMC_1V8_3V_GPIO; - sdi0_configure(); + sdi0_configure(parent); /* WLAN SDIO channel */ - db8500_add_sdi1(&mop500_sdi1_data, U8500_SDI_V2_PERIPHID); + db8500_add_sdi1(parent, &mop500_sdi1_data, U8500_SDI_V2_PERIPHID); } diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 5c00712..f9ce2a1 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -226,7 +226,12 @@ static struct tps6105x_platform_data mop500_tps61052_data = { static void mop500_tc35892_init(struct tc3589x *tc3589x, unsigned int base) { - mop500_sdi_tc35892_init(); + struct device *parent = NULL; +#if 0 + /* FIXME: Is the sdi actually part of tc3589x? */ + parent = tc3589x->dev; +#endif + mop500_sdi_tc35892_init(parent); } static struct tc3589x_gpio_platform_data mop500_tc35892_gpio_data = { @@ -353,12 +358,12 @@ U8500_I2C_CONTROLLER(1, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST); U8500_I2C_CONTROLLER(2, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST); U8500_I2C_CONTROLLER(3, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST); -static void __init mop500_i2c_init(void) +static void __init mop500_i2c_init(struct device *parent) { - db8500_add_i2c0(&u8500_i2c0_data); - db8500_add_i2c1(&u8500_i2c1_data); - db8500_add_i2c2(&u8500_i2c2_data); - db8500_add_i2c3(&u8500_i2c3_data); + db8500_add_i2c0(parent, &u8500_i2c0_data); + db8500_add_i2c1(parent, &u8500_i2c1_data); + db8500_add_i2c2(parent, &u8500_i2c2_data); + db8500_add_i2c3(parent, &u8500_i2c3_data); } static struct gpio_keys_button mop500_gpio_keys[] = { @@ -451,9 +456,9 @@ static struct pl022_ssp_controller ssp0_platform_data = { .num_chipselect = 5, }; -static void __init mop500_spi_init(void) +static void __init mop500_spi_init(struct device *parent) { - db8500_add_ssp0(&ssp0_platform_data); + db8500_add_ssp0(parent, &ssp0_platform_data); } #ifdef CONFIG_STE_DMA40 @@ -587,11 +592,11 @@ static struct amba_pl011_data uart2_plat = { #endif }; -static void __init mop500_uart_init(void) +static void __init mop500_uart_init(struct device *parent) { - db8500_add_uart0(&uart0_plat); - db8500_add_uart1(&uart1_plat); - db8500_add_uart2(&uart2_plat); + db8500_add_uart0(parent, &uart0_plat); + db8500_add_uart1(parent, &uart1_plat); + db8500_add_uart2(parent, &uart2_plat); } static struct platform_device *snowball_platform_devs[] __initdata = { @@ -603,21 +608,22 @@ static struct platform_device *snowball_platform_devs[] __initdata = { static void __init mop500_init_machine(void) { + struct device *parent = NULL; int i2c0_devs; mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR; - u8500_init_devices(); + parent = u8500_init_devices(); mop500_pins_init(); platform_add_devices(mop500_platform_devs, ARRAY_SIZE(mop500_platform_devs)); - mop500_i2c_init(); - mop500_sdi_init(); - mop500_spi_init(); - mop500_uart_init(); + mop500_i2c_init(parent); + mop500_sdi_init(parent); + mop500_spi_init(parent); + mop500_uart_init(parent); i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices); @@ -631,19 +637,20 @@ static void __init mop500_init_machine(void) static void __init snowball_init_machine(void) { + struct device *parent = NULL; int i2c0_devs; - u8500_init_devices(); + parent = u8500_init_devices(); snowball_pins_init(); platform_add_devices(snowball_platform_devs, ARRAY_SIZE(snowball_platform_devs)); - mop500_i2c_init(); - snowball_sdi_init(); - mop500_spi_init(); - mop500_uart_init(); + mop500_i2c_init(parent); + snowball_sdi_init(parent); + mop500_spi_init(parent); + mop500_uart_init(parent); i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices); i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs); @@ -656,6 +663,7 @@ static void __init snowball_init_machine(void) static void __init hrefv60_init_machine(void) { + struct device *parent = NULL; int i2c0_devs; /* @@ -665,17 +673,17 @@ static void __init hrefv60_init_machine(void) */ mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO; - u8500_init_devices(); + parent = u8500_init_devices(); hrefv60_pins_init(); platform_add_devices(mop500_platform_devs, ARRAY_SIZE(mop500_platform_devs)); - mop500_i2c_init(); - hrefv60_sdi_init(); - mop500_spi_init(); - mop500_uart_init(); + mop500_i2c_init(parent); + hrefv60_sdi_init(parent); + mop500_spi_init(parent); + mop500_uart_init(parent); i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices); diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h index f926d3d..3d594c2 100644 --- a/arch/arm/mach-ux500/board-mop500.h +++ b/arch/arm/mach-ux500/board-mop500.h @@ -75,10 +75,10 @@ struct i2c_board_info; -extern void mop500_sdi_init(void); -extern void snowball_sdi_init(void); -extern void hrefv60_sdi_init(void); -extern void mop500_sdi_tc35892_init(void); +extern void mop500_sdi_init(struct device *parent); +extern void snowball_sdi_init(struct device *parent); +extern void hrefv60_sdi_init(struct device *parent); +extern void mop500_sdi_tc35892_init(struct device *parent); void __init mop500_u8500uib_init(void); void __init mop500_stuib_init(void); void __init mop500_pins_init(void); diff --git a/arch/arm/mach-ux500/board-u5500-sdi.c b/arch/arm/mach-ux500/board-u5500-sdi.c index 63c3f80..836112e 100644 --- a/arch/arm/mach-ux500/board-u5500-sdi.c +++ b/arch/arm/mach-ux500/board-u5500-sdi.c @@ -66,9 +66,9 @@ static struct mmci_platform_data u5500_sdi0_data = { #endif }; -void __init u5500_sdi_init(void) +void __init u5500_sdi_init(struct device *parent) { nmk_config_pins(u5500_sdi_pins, ARRAY_SIZE(u5500_sdi_pins)); - db5500_add_sdi0(&u5500_sdi0_data); + db5500_add_sdi0(parent, &u5500_sdi0_data); } diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c index 9de9e9c..d7a9596 100644 --- a/arch/arm/mach-ux500/board-u5500.c +++ b/arch/arm/mach-ux500/board-u5500.c @@ -97,9 +97,9 @@ static struct i2c_board_info __initdata u5500_i2c2_devices[] = { }, }; -static void __init u5500_i2c_init(void) +static void __init u5500_i2c_init(struct device *parent) { - db5500_add_i2c2(&u5500_i2c2_data); + db5500_add_i2c2(parent, &u5500_i2c2_data); i2c_register_board_info(2, ARRAY_AND_SIZE(u5500_i2c2_devices)); } @@ -126,20 +126,23 @@ static struct platform_device *u5500_platform_devices[] __initdata = { &ab5500_device, }; -static void __init u5500_uart_init(void) +static void __init u5500_uart_init(struct device *parent) { - db5500_add_uart0(NULL); - db5500_add_uart1(NULL); - db5500_add_uart2(NULL); + db5500_add_uart0(parent, NULL); + db5500_add_uart1(parent, NULL); + db5500_add_uart2(parent, NULL); } static void __init u5500_init_machine(void) { - u5500_init_devices(); + struct device *parent = NULL; + + parent = u5500_init_devices(); nmk_config_pins(u5500_pins, ARRAY_SIZE(u5500_pins)); - u5500_i2c_init(); - u5500_sdi_init(); - u5500_uart_init(); + + u5500_i2c_init(parent); + u5500_sdi_init(parent); + u5500_uart_init(parent); platform_add_devices(u5500_platform_devices, ARRAY_SIZE(u5500_platform_devices)); diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c index 18aa5c0..c402fd6 100644 --- a/arch/arm/mach-ux500/cpu-db5500.c +++ b/arch/arm/mach-ux500/cpu-db5500.c @@ -147,13 +147,13 @@ static resource_size_t __initdata db5500_gpio_base[] = { U5500_GPIOBANK7_BASE, }; -static void __init db5500_add_gpios(void) +static void __init db5500_add_gpios(struct device *parent) { struct nmk_gpio_platform_data pdata = { /* No custom data yet */ }; - dbx500_add_gpios(ARRAY_AND_SIZE(db5500_gpio_base), + dbx500_add_gpios(parent, ARRAY_AND_SIZE(db5500_gpio_base), IRQ_DB5500_GPIO0, &pdata); } @@ -212,14 +212,18 @@ static int usb_db5500_tx_dma_cfg[] = { DB5500_DMA_DEV38_USB_OTG_OEP_8 }; -void __init u5500_init_devices(void) +struct device* __init u5500_init_devices(void) { - db5500_add_gpios(); + /* FIXME: First parameter to be a real parent. */ + db5500_add_gpios(NULL); db5500_pmu_init(); - db5500_dma_init(); - db5500_add_rtc(); - db5500_add_usb(usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg); + db5500_dma_init(NULL); + db5500_add_rtc(NULL); + db5500_add_usb(NULL, usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg); platform_add_devices(db5500_platform_devs, ARRAY_SIZE(db5500_platform_devs)); + + /* FIXME: Return value to be a real parent. */ + return NULL; } diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 7176ee7..1e8a2cb 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -132,13 +132,13 @@ static resource_size_t __initdata db8500_gpio_base[] = { U8500_GPIOBANK8_BASE, }; -static void __init db8500_add_gpios(void) +static void __init db8500_add_gpios(struct device *parent) { struct nmk_gpio_platform_data pdata = { .supports_sleepmode = true, }; - dbx500_add_gpios(ARRAY_AND_SIZE(db8500_gpio_base), + dbx500_add_gpios(parent, ARRAY_AND_SIZE(db8500_gpio_base), IRQ_DB8500_GPIO0, &pdata); } @@ -167,14 +167,15 @@ static int usb_db8500_tx_dma_cfg[] = { /* * This function is called from the board init */ -void __init u8500_init_devices(void) +struct device* __init u8500_init_devices(void) { - db8500_add_rtc(); - db8500_add_gpios(); - db8500_add_usb(usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); + db8500_add_rtc(NULL); + db8500_add_gpios(NULL); + db8500_add_usb(NULL, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); platform_device_register_simple("cpufreq-u8500", -1, NULL, 0); platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); - return ; + /* FIXME: Return value to be a real parent. */ + return NULL; } diff --git a/arch/arm/mach-ux500/devices-common.c b/arch/arm/mach-ux500/devices-common.c index c563e54..96be248 100644 --- a/arch/arm/mach-ux500/devices-common.c +++ b/arch/arm/mach-ux500/devices-common.c @@ -20,8 +20,9 @@ #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) +dbx500_add_amba_device(struct device *parent, const char *name, + resource_size_t base, int irq, void *pdata, + unsigned int periphid) { struct amba_device *dev; int ret; @@ -109,7 +110,7 @@ dbx500_add_platform_device_4k1irq(const char *name, int id, } static struct platform_device * -dbx500_add_gpio(int id, resource_size_t addr, int irq, +dbx500_add_gpio(struct device *parent, int id, resource_size_t addr, int irq, struct nmk_gpio_platform_data *pdata) { struct resource resources[] = { @@ -130,8 +131,8 @@ dbx500_add_gpio(int id, resource_size_t addr, int irq, pdata, sizeof(*pdata)); } -void dbx500_add_gpios(resource_size_t *base, int num, int irq, - struct nmk_gpio_platform_data *pdata) +void dbx500_add_gpios(struct device *parent, resource_size_t *base, int num, + int irq, struct nmk_gpio_platform_data *pdata) { int first = 0; int i; @@ -141,6 +142,6 @@ void dbx500_add_gpios(resource_size_t *base, int num, int irq, pdata->first_irq = NOMADIK_GPIO_TO_IRQ(first); pdata->num_gpio = 32; - dbx500_add_gpio(i, base[i], irq, pdata); + dbx500_add_gpio(parent, i, base[i], irq, pdata); } } diff --git a/arch/arm/mach-ux500/devices-common.h b/arch/arm/mach-ux500/devices-common.h index 7825705..f8adff8 100644 --- a/arch/arm/mach-ux500/devices-common.h +++ b/arch/arm/mach-ux500/devices-common.h @@ -9,7 +9,7 @@ #define __DEVICES_COMMON_H extern struct amba_device * -dbx500_add_amba_device(const char *name, resource_size_t base, +dbx500_add_amba_device(struct device *parent, const char *name, resource_size_t base, int irq, void *pdata, unsigned int periphid); extern struct platform_device * @@ -20,43 +20,46 @@ dbx500_add_platform_device_4k1irq(const char *name, int id, struct spi_master_cntlr; static inline struct amba_device * -dbx500_add_msp_spi(const char *name, resource_size_t base, int irq, +dbx500_add_msp_spi(struct device *parent, const char *name, + resource_size_t base, int irq, struct spi_master_cntlr *pdata) { - return dbx500_add_amba_device(name, base, irq, pdata, 0); + return dbx500_add_amba_device(parent, name, base, irq, + pdata, 0); } static inline struct amba_device * -dbx500_add_spi(const char *name, resource_size_t base, int irq, - struct spi_master_cntlr *pdata, +dbx500_add_spi(struct device *parent, const char *name, resource_size_t base, + int irq, struct spi_master_cntlr *pdata, u32 periphid) { - return dbx500_add_amba_device(name, base, irq, pdata, periphid); + return dbx500_add_amba_device(parent, name, base, irq, + pdata, periphid); } struct mmci_platform_data; static inline struct amba_device * -dbx500_add_sdi(const char *name, resource_size_t base, int irq, - struct mmci_platform_data *pdata, - u32 periphid) +dbx500_add_sdi(struct device *parent, const char *name, resource_size_t base, + int irq, struct mmci_platform_data *pdata, u32 periphid) { - return dbx500_add_amba_device(name, base, irq, pdata, periphid); + return dbx500_add_amba_device(parent, name, base, irq, + pdata, periphid); } struct amba_pl011_data; static inline struct amba_device * -dbx500_add_uart(const char *name, resource_size_t base, int irq, - struct amba_pl011_data *pdata) +dbx500_add_uart(struct device *parent, const char *name, resource_size_t base, + int irq, struct amba_pl011_data *pdata) { - return dbx500_add_amba_device(name, base, irq, pdata, 0); + return dbx500_add_amba_device(parent, name, base, irq, pdata, 0); } struct nmk_i2c_controller; static inline struct platform_device * -dbx500_add_i2c(int id, resource_size_t base, int irq, +dbx500_add_i2c(struct device *parent, int id, resource_size_t base, int irq, struct nmk_i2c_controller *pdata) { return dbx500_add_platform_device_4k1irq("nmk-i2c", id, base, irq, @@ -74,14 +77,14 @@ dbx500_add_msp_i2s(int id, resource_size_t base, int irq, } static inline struct amba_device * -dbx500_add_rtc(resource_size_t base, int irq) +dbx500_add_rtc(struct device *parent, resource_size_t base, int irq) { - return dbx500_add_amba_device("rtc-pl031", base, irq, NULL, 0); + return dbx500_add_amba_device(parent, "rtc-pl031", base, irq, NULL, 0); } struct nmk_gpio_platform_data; -void dbx500_add_gpios(resource_size_t *base, int num, int irq, - struct nmk_gpio_platform_data *pdata); +void dbx500_add_gpios(struct device *parent, resource_size_t *base, int num, + int irq, struct nmk_gpio_platform_data *pdata); #endif diff --git a/arch/arm/mach-ux500/devices-db5500.h b/arch/arm/mach-ux500/devices-db5500.h index 0c4bccd..e709555 100644 --- a/arch/arm/mach-ux500/devices-db5500.h +++ b/arch/arm/mach-ux500/devices-db5500.h @@ -10,70 +10,90 @@ #include "devices-common.h" -#define db5500_add_i2c1(pdata) \ - dbx500_add_i2c(1, U5500_I2C1_BASE, IRQ_DB5500_I2C1, pdata) -#define db5500_add_i2c2(pdata) \ - dbx500_add_i2c(2, U5500_I2C2_BASE, IRQ_DB5500_I2C2, pdata) -#define db5500_add_i2c3(pdata) \ - dbx500_add_i2c(3, U5500_I2C3_BASE, IRQ_DB5500_I2C3, pdata) +#define db5500_add_i2c1(parent, pdata) \ + dbx500_add_i2c(parent, 1, U5500_I2C1_BASE, IRQ_DB5500_I2C1, pdata) +#define db5500_add_i2c2(parent, pdata) \ + dbx500_add_i2c(parent, 2, U5500_I2C2_BASE, IRQ_DB5500_I2C2, pdata) +#define db5500_add_i2c3(parent, pdata) \ + dbx500_add_i2c(parent, 3, U5500_I2C3_BASE, IRQ_DB5500_I2C3, pdata) -#define db5500_add_msp0_i2s(pdata) \ - dbx500_add_msp_i2s(0, U5500_MSP0_BASE, IRQ_DB5500_MSP0, pdata) -#define db5500_add_msp1_i2s(pdata) \ - dbx500_add_msp_i2s(1, U5500_MSP1_BASE, IRQ_DB5500_MSP1, pdata) -#define db5500_add_msp2_i2s(pdata) \ - dbx500_add_msp_i2s(2, U5500_MSP2_BASE, IRQ_DB5500_MSP2, pdata) +#define db5500_add_msp0_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp0", U5500_MSP0_BASE, \ + IRQ_DB5500_MSP0, pdata) +#define db5500_add_msp1_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp1", U5500_MSP1_BASE, \ + IRQ_DB5500_MSP1, pdata) +#define db5500_add_msp2_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp2", U5500_MSP2_BASE, \ + IRQ_DB5500_MSP2, pdata) -#define db5500_add_msp0_spi(pdata) \ - dbx500_add_msp_spi("msp0", U5500_MSP0_BASE, IRQ_DB5500_MSP0, pdata) -#define db5500_add_msp1_spi(pdata) \ - dbx500_add_msp_spi("msp1", U5500_MSP1_BASE, IRQ_DB5500_MSP1, pdata) -#define db5500_add_msp2_spi(pdata) \ - dbx500_add_msp_spi("msp2", U5500_MSP2_BASE, IRQ_DB5500_MSP2, pdata) +#define db5500_add_msp0_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp0", U5500_MSP0_BASE, \ + IRQ_DB5500_MSP0, pdata) +#define db5500_add_msp1_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp1", U5500_MSP1_BASE, \ + IRQ_DB5500_MSP1, pdata) +#define db5500_add_msp2_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp2", U5500_MSP2_BASE, \ + IRQ_DB5500_MSP2, pdata) -#define db5500_add_rtc() \ - dbx500_add_rtc(U5500_RTC_BASE, IRQ_DB5500_RTC); +#define db5500_add_rtc(parent) \ + dbx500_add_rtc(parent, U5500_RTC_BASE, IRQ_DB5500_RTC); -#define db5500_add_usb(rx_cfg, tx_cfg) \ - ux500_add_usb(U5500_USBOTG_BASE, IRQ_DB5500_USBOTG, rx_cfg, tx_cfg) +#define db5500_add_usb(parent, rx_cfg, tx_cfg) \ + ux500_add_usb(parent, U5500_USBOTG_BASE, \ + IRQ_DB5500_USBOTG, rx_cfg, tx_cfg) -#define db5500_add_sdi0(pdata) \ - dbx500_add_sdi("sdi0", U5500_SDI0_BASE, IRQ_DB5500_SDMMC0, pdata, \ +#define db5500_add_sdi0(parent, pdata) \ + dbx500_add_sdi(parent, "sdi0", U5500_SDI0_BASE, \ + IRQ_DB5500_SDMMC0, pdata, \ 0x10480180) -#define db5500_add_sdi1(pdata) \ - dbx500_add_sdi("sdi1", U5500_SDI1_BASE, IRQ_DB5500_SDMMC1, pdata, \ +#define db5500_add_sdi1(parent, pdata) \ + dbx500_add_sdi(parent, "sdi1", U5500_SDI1_BASE, \ + IRQ_DB5500_SDMMC1, pdata, \ 0x10480180) -#define db5500_add_sdi2(pdata) \ - dbx500_add_sdi("sdi2", U5500_SDI2_BASE, IRQ_DB5500_SDMMC2, pdata \ +#define db5500_add_sdi2(parent, pdata) \ + dbx500_add_sdi(parent, "sdi2", U5500_SDI2_BASE, \ + IRQ_DB5500_SDMMC2, pdata \ 0x10480180) -#define db5500_add_sdi3(pdata) \ - dbx500_add_sdi("sdi3", U5500_SDI3_BASE, IRQ_DB5500_SDMMC3, pdata \ +#define db5500_add_sdi3(parent, pdata) \ + dbx500_add_sdi(parent, "sdi3", U5500_SDI3_BASE, \ + IRQ_DB5500_SDMMC3, pdata \ 0x10480180) -#define db5500_add_sdi4(pdata) \ - dbx500_add_sdi("sdi4", U5500_SDI4_BASE, IRQ_DB5500_SDMMC4, pdata \ +#define db5500_add_sdi4(parent, pdata) \ + dbx500_add_sdi(parent, "sdi4", U5500_SDI4_BASE, \ + IRQ_DB5500_SDMMC4, pdata \ 0x10480180) /* This one has a bad peripheral ID in the U5500 silicon */ -#define db5500_add_spi0(pdata) \ - dbx500_add_spi("spi0", U5500_SPI0_BASE, IRQ_DB5500_SPI0, pdata, \ +#define db5500_add_spi0(parent, pdata) \ + dbx500_add_spi(parent, "spi0", U5500_SPI0_BASE, \ + IRQ_DB5500_SPI0, pdata, \ 0x10080023) -#define db5500_add_spi1(pdata) \ - dbx500_add_spi("spi1", U5500_SPI1_BASE, IRQ_DB5500_SPI1, pdata, \ +#define db5500_add_spi1(parent, pdata) \ + dbx500_add_spi(parent, "spi1", U5500_SPI1_BASE, \ + IRQ_DB5500_SPI1, pdata, \ 0x10080023) -#define db5500_add_spi2(pdata) \ - dbx500_add_spi("spi2", U5500_SPI2_BASE, IRQ_DB5500_SPI2, pdata \ +#define db5500_add_spi2(parent, pdata) \ + dbx500_add_spi(parent, "spi2", U5500_SPI2_BASE, \ + IRQ_DB5500_SPI2, pdata \ 0x10080023) -#define db5500_add_spi3(pdata) \ - dbx500_add_spi("spi3", U5500_SPI3_BASE, IRQ_DB5500_SPI3, pdata \ +#define db5500_add_spi3(parent, pdata) \ + dbx500_add_spi(parent, "spi3", U5500_SPI3_BASE, \ + IRQ_DB5500_SPI3, pdata \ 0x10080023) -#define db5500_add_uart0(plat) \ - dbx500_add_uart("uart0", U5500_UART0_BASE, IRQ_DB5500_UART0, plat) -#define db5500_add_uart1(plat) \ - dbx500_add_uart("uart1", U5500_UART1_BASE, IRQ_DB5500_UART1, plat) -#define db5500_add_uart2(plat) \ - dbx500_add_uart("uart2", U5500_UART2_BASE, IRQ_DB5500_UART2, plat) -#define db5500_add_uart3(plat) \ - dbx500_add_uart("uart3", U5500_UART3_BASE, IRQ_DB5500_UART3, plat) +#define db5500_add_uart0(parent, plat) \ + dbx500_add_uart(parent, "uart0", U5500_UART0_BASE, \ + IRQ_DB5500_UART0, plat) +#define db5500_add_uart1(parent, plat) \ + dbx500_add_uart(parent, "uart1", U5500_UART1_BASE, \ + IRQ_DB5500_UART1, plat) +#define db5500_add_uart2(parent, plat) \ + dbx500_add_uart(parent, "uart2", U5500_UART2_BASE, \ + IRQ_DB5500_UART2, plat) +#define db5500_add_uart3(parent, plat) \ + dbx500_add_uart(parent, "uart3", U5500_UART3_BASE, \ + IRQ_DB5500_UART3, plat) #endif diff --git a/arch/arm/mach-ux500/devices-db8500.h b/arch/arm/mach-ux500/devices-db8500.h index cbd4a9a..9bd08ad 100644 --- a/arch/arm/mach-ux500/devices-db8500.h +++ b/arch/arm/mach-ux500/devices-db8500.h @@ -14,7 +14,9 @@ struct ske_keypad_platform_data; struct pl022_ssp_controller; static inline struct platform_device * -db8500_add_ske_keypad(struct ske_keypad_platform_data *pdata) +db8500_add_ske_keypad(struct device *parent, + struct ske_keypad_platform_data *pdata, + size_t size) { return dbx500_add_platform_device_4k1irq("nmk-ske-keypad", -1, U8500_SKE_BASE, @@ -22,80 +24,100 @@ db8500_add_ske_keypad(struct ske_keypad_platform_data *pdata) } static inline struct amba_device * -db8500_add_ssp(const char *name, resource_size_t base, int irq, - struct pl022_ssp_controller *pdata) +db8500_add_ssp(struct device *parent, const char *name, resource_size_t base, + int irq, struct pl022_ssp_controller *pdata) { - return dbx500_add_amba_device(name, base, irq, pdata, 0); + return dbx500_add_amba_device(parent, name, base, irq, pdata, 0); } -#define db8500_add_i2c0(pdata) \ - dbx500_add_i2c(0, U8500_I2C0_BASE, IRQ_DB8500_I2C0, pdata) -#define db8500_add_i2c1(pdata) \ - dbx500_add_i2c(1, U8500_I2C1_BASE, IRQ_DB8500_I2C1, pdata) -#define db8500_add_i2c2(pdata) \ - dbx500_add_i2c(2, U8500_I2C2_BASE, IRQ_DB8500_I2C2, pdata) -#define db8500_add_i2c3(pdata) \ - dbx500_add_i2c(3, U8500_I2C3_BASE, IRQ_DB8500_I2C3, pdata) -#define db8500_add_i2c4(pdata) \ - dbx500_add_i2c(4, U8500_I2C4_BASE, IRQ_DB8500_I2C4, pdata) - -#define db8500_add_msp0_i2s(pdata) \ - dbx500_add_msp_i2s(0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata) -#define db8500_add_msp1_i2s(pdata) \ - dbx500_add_msp_i2s(1, U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata) -#define db8500_add_msp2_i2s(pdata) \ - dbx500_add_msp_i2s(2, U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata) -#define db8500_add_msp3_i2s(pdata) \ - dbx500_add_msp_i2s(3, U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata) - -#define db8500_add_msp0_spi(pdata) \ - dbx500_add_msp_spi("msp0", U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata) -#define db8500_add_msp1_spi(pdata) \ - dbx500_add_msp_spi("msp1", U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata) -#define db8500_add_msp2_spi(pdata) \ - dbx500_add_msp_spi("msp2", U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata) -#define db8500_add_msp3_spi(pdata) \ - dbx500_add_msp_spi("msp3", U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata) - -#define db8500_add_rtc() \ - dbx500_add_rtc(U8500_RTC_BASE, IRQ_DB8500_RTC); - -#define db8500_add_usb(rx_cfg, tx_cfg) \ - ux500_add_usb(U8500_USBOTG_BASE, IRQ_DB8500_USBOTG, rx_cfg, tx_cfg) - -#define db8500_add_sdi0(pdata, pid) \ - dbx500_add_sdi("sdi0", U8500_SDI0_BASE, IRQ_DB8500_SDMMC0, pdata, pid) -#define db8500_add_sdi1(pdata, pid) \ - dbx500_add_sdi("sdi1", U8500_SDI1_BASE, IRQ_DB8500_SDMMC1, pdata, pid) -#define db8500_add_sdi2(pdata, pid) \ - dbx500_add_sdi("sdi2", U8500_SDI2_BASE, IRQ_DB8500_SDMMC2, pdata, pid) -#define db8500_add_sdi3(pdata, pid) \ - dbx500_add_sdi("sdi3", U8500_SDI3_BASE, IRQ_DB8500_SDMMC3, pdata, pid) -#define db8500_add_sdi4(pdata, pid) \ - dbx500_add_sdi("sdi4", U8500_SDI4_BASE, IRQ_DB8500_SDMMC4, pdata, pid) -#define db8500_add_sdi5(pdata, pid) \ - dbx500_add_sdi("sdi5", U8500_SDI5_BASE, IRQ_DB8500_SDMMC5, pdata, pid) - -#define db8500_add_ssp0(pdata) \ - db8500_add_ssp("ssp0", U8500_SSP0_BASE, IRQ_DB8500_SSP0, pdata) -#define db8500_add_ssp1(pdata) \ - db8500_add_ssp("ssp1", U8500_SSP1_BASE, IRQ_DB8500_SSP1, pdata) - -#define db8500_add_spi0(pdata) \ - dbx500_add_spi("spi0", U8500_SPI0_BASE, IRQ_DB8500_SPI0, pdata, 0) -#define db8500_add_spi1(pdata) \ - dbx500_add_spi("spi1", U8500_SPI1_BASE, IRQ_DB8500_SPI1, pdata, 0) -#define db8500_add_spi2(pdata) \ - dbx500_add_spi("spi2", U8500_SPI2_BASE, IRQ_DB8500_SPI2, pdata, 0) -#define db8500_add_spi3(pdata) \ - dbx500_add_spi("spi3", U8500_SPI3_BASE, IRQ_DB8500_SPI3, pdata, 0) - -#define db8500_add_uart0(pdata) \ - dbx500_add_uart("uart0", U8500_UART0_BASE, IRQ_DB8500_UART0, pdata) -#define db8500_add_uart1(pdata) \ - dbx500_add_uart("uart1", U8500_UART1_BASE, IRQ_DB8500_UART1, pdata) -#define db8500_add_uart2(pdata) \ - dbx500_add_uart("uart2", U8500_UART2_BASE, IRQ_DB8500_UART2, pdata) +#define db8500_add_i2c0(parent, pdata) \ + dbx500_add_i2c(parent, 0, U8500_I2C0_BASE, IRQ_DB8500_I2C0, pdata) +#define db8500_add_i2c1(parent, pdata) \ + dbx500_add_i2c(parent, 1, U8500_I2C1_BASE, IRQ_DB8500_I2C1, pdata) +#define db8500_add_i2c2(parent, pdata) \ + dbx500_add_i2c(parent, 2, U8500_I2C2_BASE, IRQ_DB8500_I2C2, pdata) +#define db8500_add_i2c3(parent, pdata) \ + dbx500_add_i2c(parent, 3, U8500_I2C3_BASE, IRQ_DB8500_I2C3, pdata) +#define db8500_add_i2c4(parent, pdata) \ + dbx500_add_i2c(parent, 4, U8500_I2C4_BASE, IRQ_DB8500_I2C4, pdata) + +#define db8500_add_msp0_i2s(parent, pdata) \ + dbx500_add_msp_i2s(parent, 0, U8500_MSP0_BASE, IRQ_DB8500_MSP0, pdata) +#define db8500_add_msp1_i2s(parent, pdata) \ + dbx500_add_msp_i2s(parent, 1, U8500_MSP1_BASE, IRQ_DB8500_MSP1, pdata) +#define db8500_add_msp2_i2s(parent, pdata) \ + dbx500_add_msp_i2s(parent, 2, U8500_MSP2_BASE, IRQ_DB8500_MSP2, pdata) +#define db8500_add_msp3_i2s(parent, pdata) \ + dbx500_add_msp_i2s(parent, 3, U8500_MSP3_BASE, IRQ_DB8500_MSP1, pdata) + +#define db8500_add_msp0_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp0", U8500_MSP0_BASE, \ + IRQ_DB8500_MSP0, pdata) +#define db8500_add_msp1_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp1", U8500_MSP1_BASE, \ + IRQ_DB8500_MSP1, pdata) +#define db8500_add_msp2_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp2", U8500_MSP2_BASE, \ + IRQ_DB8500_MSP2, pdata) +#define db8500_add_msp3_spi(parent, pdata) \ + dbx500_add_msp_spi(parent, "msp3", U8500_MSP3_BASE, \ + IRQ_DB8500_MSP1, pdata) + +#define db8500_add_rtc(parent) \ + dbx500_add_rtc(parent, U8500_RTC_BASE, IRQ_DB8500_RTC); + +#define db8500_add_usb(parent, rx_cfg, tx_cfg) \ + ux500_add_usb(parent, U8500_USBOTG_BASE, \ + IRQ_DB8500_USBOTG, rx_cfg, tx_cfg) + +#define db8500_add_sdi0(parent, pdata, pid) \ + dbx500_add_sdi(parent, "sdi0", U8500_SDI0_BASE, \ + IRQ_DB8500_SDMMC0, pdata, pid) +#define db8500_add_sdi1(parent, pdata, pid) \ + dbx500_add_sdi(parent, "sdi1", U8500_SDI1_BASE, \ + IRQ_DB8500_SDMMC1, pdata, pid) +#define db8500_add_sdi2(parent, pdata, pid) \ + dbx500_add_sdi(parent, "sdi2", U8500_SDI2_BASE, \ + IRQ_DB8500_SDMMC2, pdata, pid) +#define db8500_add_sdi3(parent, pdata, pid) \ + dbx500_add_sdi(parent, "sdi3", U8500_SDI3_BASE, \ + IRQ_DB8500_SDMMC3, pdata, pid) +#define db8500_add_sdi4(parent, pdata, pid) \ + dbx500_add_sdi(parent, "sdi4", U8500_SDI4_BASE, \ + IRQ_DB8500_SDMMC4, pdata, pid) +#define db8500_add_sdi5(parent, pdata, pid) \ + dbx500_add_sdi(parent, "sdi5", U8500_SDI5_BASE, \ + IRQ_DB8500_SDMMC5, pdata, pid) + +#define db8500_add_ssp0(parent, pdata) \ + db8500_add_ssp(parent, "ssp0", U8500_SSP0_BASE, \ + IRQ_DB8500_SSP0, pdata) +#define db8500_add_ssp1(parent, pdata) \ + db8500_add_ssp(parent, "ssp1", U8500_SSP1_BASE, \ + IRQ_DB8500_SSP1, pdata) + +#define db8500_add_spi0(parent, pdata) \ + dbx500_add_spi(parent, "spi0", U8500_SPI0_BASE, \ + IRQ_DB8500_SPI0, pdata, 0) +#define db8500_add_spi1(parent, pdata) \ + dbx500_add_spi(parent, "spi1", U8500_SPI1_BASE, \ + IRQ_DB8500_SPI1, pdata, 0) +#define db8500_add_spi2(parent, pdata) \ + dbx500_add_spi(parent, "spi2", U8500_SPI2_BASE, \ + IRQ_DB8500_SPI2, pdata, 0) +#define db8500_add_spi3(parent, pdata) \ + dbx500_add_spi(parent, "spi3", U8500_SPI3_BASE, \ + IRQ_DB8500_SPI3, pdata, 0) + +#define db8500_add_uart0(parent, pdata) \ + dbx500_add_uart(parent, "uart0", U8500_UART0_BASE, \ + IRQ_DB8500_UART0, pdata) +#define db8500_add_uart1(parent, pdata) \ + dbx500_add_uart(parent, "uart1", U8500_UART1_BASE, \ + IRQ_DB8500_UART1, pdata) +#define db8500_add_uart2(parent, pdata) \ + dbx500_add_uart(parent, "uart2", U8500_UART2_BASE, \ + IRQ_DB8500_UART2, pdata) #endif diff --git a/arch/arm/mach-ux500/dma-db5500.c b/arch/arm/mach-ux500/dma-db5500.c index 1cfab68..41e9470 100644 --- a/arch/arm/mach-ux500/dma-db5500.c +++ b/arch/arm/mach-ux500/dma-db5500.c @@ -125,10 +125,11 @@ static struct platform_device dma40_device = { .resource = dma40_resources }; -void __init db5500_dma_init(void) +void __init db5500_dma_init(struct device *parent) { int ret; + dma40_device.dev.parent = parent; ret = platform_device_register(&dma40_device); if (ret) dev_err(&dma40_device.dev, "unable to register device: %d\n", ret); diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h index a7d363f..e46b8b1 100644 --- a/arch/arm/mach-ux500/include/mach/setup.h +++ b/arch/arm/mach-ux500/include/mach/setup.h @@ -18,14 +18,14 @@ void __init ux500_map_io(void); extern void __init u5500_map_io(void); extern void __init u8500_map_io(void); -extern void __init u5500_init_devices(void); -extern void __init u8500_init_devices(void); +extern struct device * __init u5500_init_devices(void); +extern struct device * __init u8500_init_devices(void); extern void __init ux500_init_irq(void); -extern void __init u5500_sdi_init(void); +extern void __init u5500_sdi_init(struct device *parent); -extern void __init db5500_dma_init(void); +extern void __init db5500_dma_init(struct device *parent); /* We re-use nomadik_timer for this platform */ extern void nmdk_timer_init(void); diff --git a/arch/arm/mach-ux500/include/mach/usb.h b/arch/arm/mach-ux500/include/mach/usb.h index d3739d4..4c1cc50 100644 --- a/arch/arm/mach-ux500/include/mach/usb.h +++ b/arch/arm/mach-ux500/include/mach/usb.h @@ -20,6 +20,6 @@ struct ux500_musb_board_data { bool (*dma_filter)(struct dma_chan *chan, void *filter_param); }; -void ux500_add_usb(resource_size_t base, int irq, int *dma_rx_cfg, - int *dma_tx_cfg); +void ux500_add_usb(struct device *parent, resource_size_t base, + int irq, int *dma_rx_cfg, int *dma_tx_cfg); #endif diff --git a/arch/arm/mach-ux500/usb.c b/arch/arm/mach-ux500/usb.c index 0a01cbd..bef6a31 100644 --- a/arch/arm/mach-ux500/usb.c +++ b/arch/arm/mach-ux500/usb.c @@ -146,8 +146,8 @@ static inline void ux500_usb_dma_update_tx_ch_config(int *dst_dev_type) musb_dma_tx_ch[idx].dst_dev_type = dst_dev_type[idx]; } -void ux500_add_usb(resource_size_t base, int irq, int *dma_rx_cfg, - int *dma_tx_cfg) +void ux500_add_usb(struct device *parent, resource_size_t base, int irq, + int *dma_rx_cfg, int *dma_tx_cfg) { ux500_musb_device.resource[0].start = base; ux500_musb_device.resource[0].end = base + SZ_64K - 1; -- 1.7.5.4 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 2/6] drivers/base: add bus for System-on-Chip devices 2012-02-01 9:23 [PATCH 0/6] ux500: Export SoC information and some platform clean-up Lee Jones 2012-02-01 9:23 ` [PATCH 1/6] mach-ux500: pass parent pointer to each platform device Lee Jones @ 2012-02-01 9:23 ` Lee Jones 2012-02-01 15:52 ` Jamie Iles 2012-02-01 9:23 ` [PATCH 3/6] Documentation: add information for new sysfs soc bus functionality Lee Jones ` (3 subsequent siblings) 5 siblings, 1 reply; 13+ messages in thread From: Lee Jones @ 2012-02-01 9:23 UTC (permalink / raw) To: linux-arm-kernel Traditionally, any System-on-Chip based platform creates a flat list of platform_devices directly under /sys/devices/platform. In order to give these some better structure, this introduces a new bus type for soc_devices that are registered with the new soc_device_register() function. All devices that are on the same chip should then be registered as child devices of the soc device. The soc bus also exports a few standardised device attributes which allow user space to query the specific type of soc. Signed-off-by: Lee Jones <lee.jones@linaro.org> --- drivers/base/Kconfig | 3 + drivers/base/Makefile | 1 + drivers/base/soc.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/syssoc.h | 74 +++++++++++++++++++ 4 files changed, 264 insertions(+), 0 deletions(-) create mode 100644 drivers/base/soc.c create mode 100644 include/linux/syssoc.h diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index 7be9f79..9aa618a 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig @@ -176,6 +176,9 @@ config GENERIC_CPU_DEVICES bool default n +config SOC_BUS + bool + source "drivers/base/regmap/Kconfig" config DMA_SHARED_BUFFER diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 2c8272d..4f302a6 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_MODULES) += module.o endif obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o obj-$(CONFIG_REGMAP) += regmap/ +obj-$(CONFIG_SOC_BUS) += soc.o ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG diff --git a/drivers/base/soc.c b/drivers/base/soc.c new file mode 100644 index 0000000..29abf6d --- /dev/null +++ b/drivers/base/soc.c @@ -0,0 +1,186 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * + * Author: Lee Jones <lee.jones@linaro.org> for ST-Ericsson. + * License terms: GNU General Public License (GPL), version 2 + */ + +#include <linux/sysfs.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/stat.h> +#include <linux/slab.h> +#include <linux/idr.h> +#include <linux/spinlock.h> +#include <linux/sys_soc.h> +#include <linux/err.h> + +static struct ida soc_ida; +static spinlock_t soc_lock; + +/* Required: soc_info_get needs to see the DEVICE_ATTR's, which */ +/* in turn need to know about the function's existence. */ +static ssize_t soc_info_get(struct device *dev, + struct device_attribute *attr, + char *buf); + +struct soc_device { + struct device dev; + const struct soc_device_attribute *attr; +}; + +static struct bus_type soc_bus_type = { + .name = "soc", +}; + +static DEVICE_ATTR(machine, S_IRUGO, soc_info_get, NULL); +static DEVICE_ATTR(family, S_IRUGO, soc_info_get, NULL); +static DEVICE_ATTR(soc_id, S_IRUGO, soc_info_get, NULL); +static DEVICE_ATTR(revision, S_IRUGO, soc_info_get, NULL); + +struct device *soc_device_to_device(struct soc_device *soc_dev) +{ + return &soc_dev->dev; +} + +static mode_t soc_attribute_mode(struct kobject *kobj, + struct attribute *attr, + int index) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); + + if ((attr == &dev_attr_machine.attr) + && (soc_dev->attr->machine != NULL)) + return attr->mode; + if ((attr == &dev_attr_family.attr) + && (soc_dev->attr->family != NULL)) + return attr->mode; + if ((attr == &dev_attr_revision.attr) + && (soc_dev->attr->revision != NULL)) + return attr->mode; + if ((attr == &dev_attr_soc_id.attr) + && (soc_dev->attr->soc_id != NULL)) + return attr->mode; + + /* Unknown or unfilled attribute. */ + return 0; +} + +static ssize_t soc_info_get(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); + + if (attr == &dev_attr_machine) + return sprintf(buf, "%s\n", soc_dev->attr->machine); + if (attr == &dev_attr_family) + return sprintf(buf, "%s\n", soc_dev->attr->family); + if (attr == &dev_attr_revision) + return sprintf(buf, "%s\n", soc_dev->attr->revision); + if (attr == &dev_attr_soc_id) + return sprintf(buf, "%s\n", soc_dev->attr->soc_id); + + return -EINVAL; + +} + +static struct attribute *soc_attr[] = { + &dev_attr_machine.attr, + &dev_attr_family.attr, + &dev_attr_soc_id.attr, + &dev_attr_revision.attr, + NULL, +}; + +static const struct attribute_group soc_attr_group = { + .attrs = soc_attr, + .is_visible = soc_attribute_mode, +}; + +static const struct attribute_group *soc_attr_groups[] = { + &soc_attr_group, + NULL, +}; + +static void soc_release(struct device *dev) +{ + struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); + + kfree(soc_dev); +} + +struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr) +{ + struct soc_device *soc_dev; + int ret; + + soc_dev = kzalloc(sizeof(*soc_dev), GFP_KERNEL); + if (!soc_dev) { + ret = -ENOMEM; + goto out1; + } + + /* Fetch a unique (reclaimable) SOC ID. */ + do { + if (!ida_pre_get(&soc_ida, GFP_KERNEL)) { + ret = -ENOMEM; + goto out2; + } + + spin_lock(&soc_lock); + ret = ida_get_new(&soc_ida, &soc_dev->id); + spin_unlock(&soc_lock); + + } while (ret == -EAGAIN); + + if (ret) + goto out2; + + soc_dev->attr = soc_dev_attr; + soc_dev->dev.bus = &soc_bus_type; + soc_dev->dev.groups = soc_attr_groups; + soc_dev->dev.release = soc_release; + + dev_set_name(&soc_dev->dev, "soc%d", soc_dev->id); + + ret = device_register(&soc_dev->dev); + if (ret) + goto out3; + + return soc_dev; + +out3: + ida_remove(&soc_ida, soc_dev->id); +out2: + kfree(soc_dev); +out1: + return ERR_PTR(ret); +} + +/* Ensure soc_dev->attr is freed prior to calling soc_device_unregister. */ +void soc_device_unregister(struct soc_device *soc_dev) +{ + ida_remove(&soc_ida, soc_dev->id); + + device_unregister(&soc_dev->dev); +} + +static int __init soc_bus_register(void) +{ + spin_lock_init(&soc_lock); + + ida_init(&soc_ida); + + return bus_register(&soc_bus_type); +} +core_initcall(soc_bus_register); + +static void __exit soc_bus_unregister(void) +{ + ida_destroy(&soc_ida); + + bus_unregister(&soc_bus_type); +} +module_exit(soc_bus_unregister); diff --git a/include/linux/syssoc.h b/include/linux/syssoc.h new file mode 100644 index 0000000..340685c --- /dev/null +++ b/include/linux/syssoc.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) ST-Ericsson SA 2011 + * Author: Lee Jones <lee.jones@linaro.org> for ST-Ericsson. + * License terms: GNU General Public License (GPL), version 2 + */ + +#ifndef __SOC_BUS_H +#define __SOC_BUS_H + +#include <linux/device.h> + +struct soc_device_attribute { + const char *machine; + const char *family; + const char *revision; + const char *soc_id; +}; + +/** + * soc_device_register - register SoC as a device + * @soc_plat_dev_attr: Attributes passed from platform to be attributed to a SoC + * + * soc_device_register is passed a selection of predefined attributes. Each + * detail a particular piece of information pertaining to the System-on-Chip + * (SoC) which the code is currently executing on. It is the caller's + * responsibility to allocate memory and populate this structure prior to passing + * as well as freeing on failure. + * + * More information surrounding the attributes can be found in: + * 'Documentation/ABI/testing/sysfs-devices-soc'. + * + * Each SoC in the system should call this function once. It will be subsequently + * allocated a SoC ID (in order of appearance - so the first SoC on the system + * may not necessarily be soc0 in sysfs) and registered. + * + * If successful, soc_device_register will return a populated soc_device + * (definition located in 'drivers/base/soc.c'), which the calling code can then + * use as a parent after passing it through soc_device_to_device. + * + */ +struct soc_device *soc_device_register( + const struct soc_device_attribute *soc_plat_dev_attr); + +/** + * soc_device_unregister - unregister SoC device + * @dev: SoC device to be unregistered + * + * soc_device_unregister only requires the soc_device which was obtained from + * soc_device_register. In current architectures this is an unused function call + * as SoCs are presently non-removable. + */ +void soc_device_unregister(struct soc_device *soc_dev); + +/** + * soc_device_to_device - helper function to fetch struct device + * @soc: Previously registered SoC device container + * + * Up until the existence of this driver, SoC devices were registered as "grab bag" + * platform_devices. Now, once a SoC registers itself with this driver, it will be + * provided a soc_device. This has the potential to act as a parent for all SoC + * devices and provides a sane bus for SoC devices to be hooked up to. + * + * When soc_device_to_device is provided with the soc_device returned by + * soc_device_register a suitable parent device will be passed back. This may be + * used as a suitable parent for all devices located on the current (calling) SoC. + * + * This function provides a simple way to extract the parent pointer from + * soc_device. No reference counter is incremented during the process, so it is + * considered safe to call it as many times as required without unnecessary + * overhead. + */ +struct device *soc_device_to_device(struct soc_device *soc); + +#endif /* __SOC_BUS_H */ -- 1.7.5.4 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 2/6] drivers/base: add bus for System-on-Chip devices 2012-02-01 9:23 ` [PATCH 2/6] drivers/base: add bus for System-on-Chip devices Lee Jones @ 2012-02-01 15:52 ` Jamie Iles 2012-02-01 16:55 ` Arnd Bergmann 0 siblings, 1 reply; 13+ messages in thread From: Jamie Iles @ 2012-02-01 15:52 UTC (permalink / raw) To: linux-arm-kernel Hi Lee, I'm not able to give this a full testing, but it looks good to me, I have one really minor nit, but I'll look forward to integrating this into picoxcell as soon as I get chance! Jamie On 1 February 2012 04:23, Lee Jones <lee.jones@linaro.org> wrote: > diff --git a/drivers/base/soc.c b/drivers/base/soc.c > new file mode 100644 > index 0000000..29abf6d > --- /dev/null > +++ b/drivers/base/soc.c > @@ -0,0 +1,186 @@ > +/* > + * Copyright (C) ST-Ericsson SA 2011 > + * > + * Author: Lee Jones <lee.jones@linaro.org> for ST-Ericsson. > + * License terms: ?GNU General Public License (GPL), version 2 > + */ > + > +#include <linux/sysfs.h> > +#include <linux/module.h> > +#include <linux/init.h> > +#include <linux/stat.h> > +#include <linux/slab.h> > +#include <linux/idr.h> > +#include <linux/spinlock.h> > +#include <linux/sys_soc.h> > +#include <linux/err.h> > + > +static struct ida soc_ida; > +static spinlock_t soc_lock; Use DEFINE_IDR() and DEFINE_SPINLOCK() rather than initialising them at runtime? Jamie ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/6] drivers/base: add bus for System-on-Chip devices 2012-02-01 15:52 ` Jamie Iles @ 2012-02-01 16:55 ` Arnd Bergmann 0 siblings, 0 replies; 13+ messages in thread From: Arnd Bergmann @ 2012-02-01 16:55 UTC (permalink / raw) To: linux-arm-kernel On Wednesday 01 February 2012, Jamie Iles wrote: > > +static struct ida soc_ida; > > +static spinlock_t soc_lock; > > Use DEFINE_IDR() and DEFINE_SPINLOCK() rather than initialising them at runtime? > Good point! "static DEFINE_{IDR,SPINLOCK}()" even, in case that wasn't clear. Arnd ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 3/6] Documentation: add information for new sysfs soc bus functionality 2012-02-01 9:23 [PATCH 0/6] ux500: Export SoC information and some platform clean-up Lee Jones 2012-02-01 9:23 ` [PATCH 1/6] mach-ux500: pass parent pointer to each platform device Lee Jones 2012-02-01 9:23 ` [PATCH 2/6] drivers/base: add bus for System-on-Chip devices Lee Jones @ 2012-02-01 9:23 ` Lee Jones 2012-02-01 9:23 ` [PATCH 4/6] mach-ux500: export System-on-Chip information ux500 via sysfs Lee Jones ` (2 subsequent siblings) 5 siblings, 0 replies; 13+ messages in thread From: Lee Jones @ 2012-02-01 9:23 UTC (permalink / raw) To: linux-arm-kernel This change applies the required documentation for each new attribute recenty added by the new System-On-Chip (SoC) information export bus driver. Signed-off-by: Lee Jones <lee.jones@linaro.org> --- Documentation/ABI/testing/sysfs-devices-soc | 58 +++++++++++++++++++++++++++ 1 files changed, 58 insertions(+), 0 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-devices-soc diff --git a/Documentation/ABI/testing/sysfs-devices-soc b/Documentation/ABI/testing/sysfs-devices-soc new file mode 100644 index 0000000..6d9cc25 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-devices-soc @@ -0,0 +1,58 @@ +What: /sys/devices/socX +Date: January 2012 +contact: Lee Jones <lee.jones@linaro.org> +Description: + The /sys/devices/ directory contains a sub-directory for each + System-on-Chip (SoC) device on a running platform. Information + regarding each SoC can be obtained by reading sysfs files. This + functionality is only available if implemented by the platform. + + The directory created for each SoC will also house information + about devices which are commonly contained in /sys/devices/platform. + It has been agreed that if an SoC device exists, its supported + devices would be better suited to appear as children of that SoC. + +What: /sys/devices/socX/machine +Date: January 2012 +contact: Lee Jones <lee.jones@linaro.org> +Description: + Read-only attribute common to all SoCs. Contains the SoC machine + name (e.g. Ux500). + +What: /sys/devices/socX/family +Date: January 2012 +contact: Lee Jones <lee.jones@linaro.org> +Description: + Read-only attribute common to all SoCs. Contains SoC family name + (e.g. DB8500). + +What: /sys/devices/socX/soc_id +Date: January 2012 +contact: Lee Jones <lee.jones@linaro.org> +Description: + Read-only attribute supported by most SoCs. In the case of + ST-Ericsson's chips this contains the SoC serial number. + +What: /sys/devices/socX/revision +Date: January 2012 +contact: Lee Jones <lee.jones@linaro.org> +Description: + Read-only attribute supported by most SoCs. Contains the SoC's + manufacturing revision number. + +What: /sys/devices/socX/process +Date: January 2012 +contact: Lee Jones <lee.jones@linaro.org> +Description: + Read-only attribute supported ST-Ericsson's silicon. Contains the + the process by which the silicon chip was manufactured. + +What: /sys/bus/soc +Date: January 2012 +contact: Lee Jones <lee.jones@linaro.org> +Description: + The /sys/bus/soc/ directory contains the usual sub-folders + expected under most buses. /sys/bus/soc/devices is of particular + interest, as it contains a symlink for each SoC device found on + the system. Each symlink points back into the aforementioned + /sys/devices/socX devices. -- 1.7.5.4 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 4/6] mach-ux500: export System-on-Chip information ux500 via sysfs 2012-02-01 9:23 [PATCH 0/6] ux500: Export SoC information and some platform clean-up Lee Jones ` (2 preceding siblings ...) 2012-02-01 9:23 ` [PATCH 3/6] Documentation: add information for new sysfs soc bus functionality Lee Jones @ 2012-02-01 9:23 ` Lee Jones 2012-02-01 9:23 ` [PATCH 5/6] mach-ux500: move top level platform devices in sysfs to /sys/devices/socX Lee Jones 2012-02-01 9:23 ` [PATCH 6/6] mach-ux500: remove intermediary add_platform_device* functions Lee Jones 5 siblings, 0 replies; 13+ messages in thread From: Lee Jones @ 2012-02-01 9:23 UTC (permalink / raw) To: linux-arm-kernel Here we make use of the new System-On-Chip bus driver to export vital SoC information out to userspace via sysfs. This patch provides a data structure of strings to populate the base nodes found in: /sys/devices/soc[0|1|2|...]/[family|machine|revision|soc_id]. It also adds one more node as requested by ST-Ericsson. 'process' depicts the way in which the silicon was manufactured. Signed-off-by: Lee Jones <lee.jones@linaro.org> --- arch/arm/mach-ux500/Kconfig | 1 + arch/arm/mach-ux500/cpu-db5500.c | 30 +++++++--- arch/arm/mach-ux500/cpu-db8500.c | 33 +++++++++-- arch/arm/mach-ux500/cpu.c | 75 ++++++++++++++++++++++++ arch/arm/mach-ux500/include/mach/db8500-regs.h | 3 + arch/arm/mach-ux500/include/mach/setup.h | 2 + 6 files changed, 130 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index a3e0c86..ce8bac2 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -27,6 +27,7 @@ config MACH_U8500 bool "U8500 Development platform" depends on UX500_SOC_DB8500 select TPS6105X + select SOC_BUS help Include support for the mop500 development platform. diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c index c402fd6..8f8acfd 100644 --- a/arch/arm/mach-ux500/cpu-db5500.c +++ b/arch/arm/mach-ux500/cpu-db5500.c @@ -212,18 +212,32 @@ static int usb_db5500_tx_dma_cfg[] = { DB5500_DMA_DEV38_USB_OTG_OEP_8 }; -struct device* __init u5500_init_devices(void) +static const char *db5500_read_soc_id(void) { - /* FIXME: First parameter to be a real parent. */ - db5500_add_gpios(NULL); + return kasprintf(GFP_KERNEL, "u5500 currently unsupported\n"); +} + +static struct device * __init db5500_soc_device_init(void) +{ + const char *soc_id = db5500_read_soc_id(); + + return ux500_soc_device_init(soc_id); +} + +struct device * __init u5500_init_devices(void) +{ + struct device *parent; + + parent = db5500_soc_device_init(); + + db5500_add_gpios(parent); db5500_pmu_init(); - db5500_dma_init(NULL); - db5500_add_rtc(NULL); - db5500_add_usb(NULL, usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg); + db5500_dma_init(parent); + db5500_add_rtc(parent); + db5500_add_usb(parent, usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg); platform_add_devices(db5500_platform_devs, ARRAY_SIZE(db5500_platform_devs)); - /* FIXME: Return value to be a real parent. */ - return NULL; + return parent; } diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 1e8a2cb..afcde3d 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -24,6 +24,7 @@ #include <mach/setup.h> #include <mach/devices.h> #include <mach/usb.h> +#include <mach/db8500-regs.h> #include "devices-db8500.h" #include "ste-dma40-db8500.h" @@ -164,18 +165,38 @@ static int usb_db8500_tx_dma_cfg[] = { DB8500_DMA_DEV39_USB_OTG_OEP_8 }; +static const char *db8500_read_soc_id(void) +{ + void __iomem *uid = __io_address(U8500_BB_UID_BASE); + + return kasprintf(GFP_KERNEL, "%08x%08x%08x%08x%08x", + readl((u32 *)uid+1), + readl((u32 *)uid+1), readl((u32 *)uid+2), + readl((u32 *)uid+3), readl((u32 *)uid+4)); +} + +static struct device * __init db8500_soc_device_init(void) +{ + const char *soc_id = db8500_read_soc_id(); + + return ux500_soc_device_init(soc_id); +} + /* * This function is called from the board init */ -struct device* __init u8500_init_devices(void) +struct device * __init u8500_init_devices(void) { - db8500_add_rtc(NULL); - db8500_add_gpios(NULL); - db8500_add_usb(NULL, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); + struct device *parent; + + parent = db8500_soc_device_init(); + + db8500_add_rtc(parent); + db8500_add_gpios(parent); + db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); platform_device_register_simple("cpufreq-u8500", -1, NULL, 0); platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); - /* FIXME: Return value to be a real parent. */ - return NULL; + return parent; } diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index f418574..055fb6e 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c @@ -2,6 +2,7 @@ * Copyright (C) ST-Ericsson SA 2010 * * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson + * Author: Lee Jones <lee.jones@linaro.org> for ST-Ericsson * License terms: GNU General Public License (GPL) version 2 */ @@ -11,6 +12,10 @@ #include <linux/mfd/db8500-prcmu.h> #include <linux/mfd/db5500-prcmu.h> #include <linux/clksrc-dbx500-prcmu.h> +#include <linux/sys_soc.h> +#include <linux/err.h> +#include <linux/slab.h> +#include <linux/stat.h> #include <asm/hardware/gic.h> #include <asm/mach/map.h> @@ -50,3 +55,73 @@ void __init ux500_init_irq(void) db8500_prcmu_early_init(); clk_init(); } + +static const char * __init ux500_get_machine(void) +{ + return kasprintf(GFP_KERNEL, "DB%4x", dbx500_partnumber()); +} + +static const char * __init ux500_get_family(void) +{ + return kasprintf(GFP_KERNEL, "ux500"); +} + +static const char * __init ux500_get_revision(void) +{ + unsigned int rev = dbx500_revision(); + + if (rev == 0x01) + return kasprintf(GFP_KERNEL, "%s", "ED"); + else if (rev >= 0xA0) + return kasprintf(GFP_KERNEL, "%d.%d", + (rev >> 4) - 0xA + 1, rev & 0xf); + + return kasprintf(GFP_KERNEL, "%s", "Unknown"); +} + +static ssize_t ux500_get_process(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + if (dbx500_id.process == 0x00) + return sprintf(buf, "Standard\n"); + + return sprintf(buf, "%02xnm\n", dbx500_id.process); +} + +static void __init soc_info_populate(struct soc_device_attribute *soc_dev_attr, + const char *soc_id) +{ + soc_dev_attr->soc_id = soc_id; + soc_dev_attr->machine = ux500_get_machine(); + soc_dev_attr->family = ux500_get_family(); + soc_dev_attr->revision = ux500_get_revision(); +} + +struct device_attribute ux500_soc_attr = + __ATTR(process, S_IRUGO, ux500_get_process, NULL); + +struct device * __init ux500_soc_device_init(const char *soc_id) +{ + struct device *parent; + struct soc_device *soc_dev; + struct soc_device_attribute *soc_dev_attr; + + soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + if (!soc_dev_attr) + return ERR_PTR(-ENOMEM); + + soc_info_populate(soc_dev_attr, soc_id); + + soc_dev = soc_device_register(soc_dev_attr); + if (IS_ERR_OR_NULL(soc_dev)) { + kfree(soc_dev_attr); + return NULL; + } + + parent = soc_device_to_device(soc_dev); + if (!IS_ERR_OR_NULL(parent)) + device_create_file(parent, &ux500_soc_attr); + + return parent; +} diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h index 80e10f5..9ec20b9 100644 --- a/arch/arm/mach-ux500/include/mach/db8500-regs.h +++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h @@ -161,4 +161,7 @@ #define U8500_MODEM_BASE 0xe000000 #define U8500_APE_BASE 0x6000000 +/* SoC identification number information */ +#define U8500_BB_UID_BASE (U8500_BACKUPRAM1_BASE + 0xFC0) + #endif diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h index e46b8b1..74b43bb 100644 --- a/arch/arm/mach-ux500/include/mach/setup.h +++ b/arch/arm/mach-ux500/include/mach/setup.h @@ -27,6 +27,8 @@ extern void __init u5500_sdi_init(struct device *parent); extern void __init db5500_dma_init(struct device *parent); +extern struct device *ux500_soc_device_init(const char *soc_id); + /* We re-use nomadik_timer for this platform */ extern void nmdk_timer_init(void); -- 1.7.5.4 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 5/6] mach-ux500: move top level platform devices in sysfs to /sys/devices/socX 2012-02-01 9:23 [PATCH 0/6] ux500: Export SoC information and some platform clean-up Lee Jones ` (3 preceding siblings ...) 2012-02-01 9:23 ` [PATCH 4/6] mach-ux500: export System-on-Chip information ux500 via sysfs Lee Jones @ 2012-02-01 9:23 ` Lee Jones 2012-02-01 9:23 ` [PATCH 6/6] mach-ux500: remove intermediary add_platform_device* functions Lee Jones 5 siblings, 0 replies; 13+ messages in thread From: Lee Jones @ 2012-02-01 9:23 UTC (permalink / raw) To: linux-arm-kernel At the request of Arnd Bergmann this patch moves all SoC platform devices found in sysfs from /sys/devices/platform to /sys/devices/soc<SoCNum>/. It is believed as the devices are SoC specific and a /sys/devices/soc node has recently become available, that this would be a more appropriate place to display the data. Signed-off-by: Lee Jones <lee.jones@linaro.org> --- arch/arm/mach-ux500/board-mop500.c | 12 ++++++++++++ arch/arm/mach-ux500/board-u5500.c | 4 ++++ arch/arm/mach-ux500/cpu-db5500.c | 4 ++++ arch/arm/mach-ux500/cpu-db8500.c | 8 +++++++- arch/arm/mach-ux500/devices-common.c | 13 ++++++++++--- arch/arm/mach-ux500/usb.c | 3 +++ 6 files changed, 40 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index f9ce2a1..04afcdf 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -610,6 +610,7 @@ static void __init mop500_init_machine(void) { struct device *parent = NULL; int i2c0_devs; + int i; mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR; @@ -617,6 +618,9 @@ static void __init mop500_init_machine(void) mop500_pins_init(); + for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++) + mop500_platform_devs[i]->dev.parent = parent; + platform_add_devices(mop500_platform_devs, ARRAY_SIZE(mop500_platform_devs)); @@ -639,11 +643,15 @@ static void __init snowball_init_machine(void) { struct device *parent = NULL; int i2c0_devs; + int i; parent = u8500_init_devices(); snowball_pins_init(); + for (i = 0; i < ARRAY_SIZE(snowball_platform_devs); i++) + snowball_platform_devs[i]->dev.parent = parent; + platform_add_devices(snowball_platform_devs, ARRAY_SIZE(snowball_platform_devs)); @@ -665,6 +673,7 @@ static void __init hrefv60_init_machine(void) { struct device *parent = NULL; int i2c0_devs; + int i; /* * The HREFv60 board removed a GPIO expander and routed @@ -677,6 +686,9 @@ static void __init hrefv60_init_machine(void) hrefv60_pins_init(); + for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++) + mop500_platform_devs[i]->dev.parent = parent; + platform_add_devices(mop500_platform_devs, ARRAY_SIZE(mop500_platform_devs)); diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c index d7a9596..0ff4be7 100644 --- a/arch/arm/mach-ux500/board-u5500.c +++ b/arch/arm/mach-ux500/board-u5500.c @@ -136,6 +136,7 @@ static void __init u5500_uart_init(struct device *parent) static void __init u5500_init_machine(void) { struct device *parent = NULL; + int i; parent = u5500_init_devices(); nmk_config_pins(u5500_pins, ARRAY_SIZE(u5500_pins)); @@ -144,6 +145,9 @@ static void __init u5500_init_machine(void) u5500_sdi_init(parent); u5500_uart_init(parent); + for (i = 0; i < ARRAY_SIZE(u5500_platform_devices); i++) + u5500_platform_devices[i]->dev.parent = parent; + platform_add_devices(u5500_platform_devices, ARRAY_SIZE(u5500_platform_devices)); } diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c index 8f8acfd..bca47f3 100644 --- a/arch/arm/mach-ux500/cpu-db5500.c +++ b/arch/arm/mach-ux500/cpu-db5500.c @@ -227,6 +227,7 @@ static struct device * __init db5500_soc_device_init(void) struct device * __init u5500_init_devices(void) { struct device *parent; + int i; parent = db5500_soc_device_init(); @@ -236,6 +237,9 @@ struct device * __init u5500_init_devices(void) db5500_add_rtc(parent); db5500_add_usb(parent, usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg); + for (i = 0; i < ARRAY_SIZE(db5500_platform_devs); i++) + db5500_platform_devs[i]->dev.parent = parent; + platform_add_devices(db5500_platform_devs, ARRAY_SIZE(db5500_platform_devs)); diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index afcde3d..9bd8163 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -188,6 +188,7 @@ static struct device * __init db8500_soc_device_init(void) struct device * __init u8500_init_devices(void) { struct device *parent; + int i; parent = db8500_soc_device_init(); @@ -195,7 +196,12 @@ struct device * __init u8500_init_devices(void) db8500_add_gpios(parent); db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); - platform_device_register_simple("cpufreq-u8500", -1, NULL, 0); + platform_device_register_data(parent, + "cpufreq-u8500", -1, NULL, 0); + + for (i = 0; i < ARRAY_SIZE(platform_devs); i++) + platform_devs[i]->dev.parent = parent; + platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); return parent; diff --git a/arch/arm/mach-ux500/devices-common.c b/arch/arm/mach-ux500/devices-common.c index 96be248..96effbd 100644 --- a/arch/arm/mach-ux500/devices-common.c +++ b/arch/arm/mach-ux500/devices-common.c @@ -47,6 +47,8 @@ dbx500_add_amba_device(struct device *parent, const char *name, dev->dev.platform_data = pdata; + dev->dev.parent = parent; + ret = amba_device_register(dev, &iomem_resource); if (ret) { kfree(dev); @@ -126,9 +128,14 @@ dbx500_add_gpio(struct device *parent, int id, resource_size_t addr, int irq, } }; - return platform_device_register_resndata(NULL, "gpio", id, - resources, ARRAY_SIZE(resources), - pdata, sizeof(*pdata)); + return platform_device_register_resndata( + parent, + "gpio", + id, + resources, + ARRAY_SIZE(resources), + pdata, + sizeof(*pdata)); } void dbx500_add_gpios(struct device *parent, resource_size_t *base, int num, diff --git a/arch/arm/mach-ux500/usb.c b/arch/arm/mach-ux500/usb.c index bef6a31..cdae63e 100644 --- a/arch/arm/mach-ux500/usb.c +++ b/arch/arm/mach-ux500/usb.c @@ -7,6 +7,7 @@ #include <linux/platform_device.h> #include <linux/usb/musb.h> #include <linux/dma-mapping.h> + #include <plat/ste_dma40.h> #include <mach/hardware.h> #include <mach/usb.h> @@ -157,5 +158,7 @@ void ux500_add_usb(struct device *parent, resource_size_t base, int irq, ux500_usb_dma_update_rx_ch_config(dma_rx_cfg); ux500_usb_dma_update_tx_ch_config(dma_tx_cfg); + ux500_musb_device.dev.parent = parent; + platform_device_register(&ux500_musb_device); } -- 1.7.5.4 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 6/6] mach-ux500: remove intermediary add_platform_device* functions 2012-02-01 9:23 [PATCH 0/6] ux500: Export SoC information and some platform clean-up Lee Jones ` (4 preceding siblings ...) 2012-02-01 9:23 ` [PATCH 5/6] mach-ux500: move top level platform devices in sysfs to /sys/devices/socX Lee Jones @ 2012-02-01 9:23 ` Lee Jones 5 siblings, 0 replies; 13+ messages in thread From: Lee Jones @ 2012-02-01 9:23 UTC (permalink / raw) To: linux-arm-kernel These are no longer required since a 'parent' pointer is now passed to each registering device. Signed-off-by: Lee Jones <lee.jones@linaro.org> --- arch/arm/mach-ux500/devices-common.c | 53 ---------------------------------- arch/arm/mach-ux500/devices-common.h | 46 ++++++++++++++++------------- arch/arm/mach-ux500/devices-db8500.h | 10 ++++-- 3 files changed, 33 insertions(+), 76 deletions(-) diff --git a/arch/arm/mach-ux500/devices-common.c b/arch/arm/mach-ux500/devices-common.c index 96effbd..c3bc094 100644 --- a/arch/arm/mach-ux500/devices-common.c +++ b/arch/arm/mach-ux500/devices-common.c @@ -59,59 +59,6 @@ dbx500_add_amba_device(struct device *parent, const char *name, } 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)); -} - -static struct platform_device * dbx500_add_gpio(struct device *parent, int id, resource_size_t addr, int irq, struct nmk_gpio_platform_data *pdata) { diff --git a/arch/arm/mach-ux500/devices-common.h b/arch/arm/mach-ux500/devices-common.h index f8adff8..39c74ec 100644 --- a/arch/arm/mach-ux500/devices-common.h +++ b/arch/arm/mach-ux500/devices-common.h @@ -8,14 +8,15 @@ #ifndef __DEVICES_COMMON_H #define __DEVICES_COMMON_H -extern struct amba_device * -dbx500_add_amba_device(struct device *parent, const char *name, resource_size_t base, - int irq, void *pdata, unsigned int periphid); +#include <linux/platform_device.h> +#include <linux/dma-mapping.h> +#include <linux/sys_soc.h> +#include <plat/i2c.h> -extern struct platform_device * -dbx500_add_platform_device_4k1irq(const char *name, int id, - resource_size_t base, - int irq, void *pdata); +extern struct amba_device * +dbx500_add_amba_device(struct device *parent, const char *name, + resource_size_t base, int irq, void *pdata, + unsigned int periphid); struct spi_master_cntlr; @@ -60,20 +61,25 @@ struct nmk_i2c_controller; static inline struct platform_device * dbx500_add_i2c(struct device *parent, int id, resource_size_t base, int irq, - struct nmk_i2c_controller *pdata) -{ - return dbx500_add_platform_device_4k1irq("nmk-i2c", id, base, irq, - pdata); -} - -struct msp_i2s_platform_data; - -static inline struct platform_device * -dbx500_add_msp_i2s(int id, resource_size_t base, int irq, - struct msp_i2s_platform_data *pdata) + struct nmk_i2c_controller *data) { - return dbx500_add_platform_device_4k1irq("MSP_I2S", id, base, irq, - pdata); + struct resource res[] = { + DEFINE_RES_MEM(base, SZ_4K), + DEFINE_RES_IRQ(irq), + }; + + struct platform_device_info pdevinfo = { + .parent = parent, + .name = "nmk-i2c", + .id = id, + .res = res, + .num_res = ARRAY_SIZE(res), + .data = data, + .size_data = sizeof(*data), + .dma_mask = DMA_BIT_MASK(32), + }; + + return platform_device_register_full(&pdevinfo); } static inline struct amba_device * diff --git a/arch/arm/mach-ux500/devices-db8500.h b/arch/arm/mach-ux500/devices-db8500.h index 9bd08ad..9fd93e9 100644 --- a/arch/arm/mach-ux500/devices-db8500.h +++ b/arch/arm/mach-ux500/devices-db8500.h @@ -18,9 +18,13 @@ db8500_add_ske_keypad(struct device *parent, struct ske_keypad_platform_data *pdata, size_t size) { - return dbx500_add_platform_device_4k1irq("nmk-ske-keypad", -1, - U8500_SKE_BASE, - IRQ_DB8500_KB, pdata); + struct resource resources[] = { + DEFINE_RES_MEM(U8500_SKE_BASE, SZ_4K), + DEFINE_RES_IRQ(IRQ_DB8500_KB), + }; + + return platform_device_register_resndata(parent, "nmk-ske-keypad", -1, + resources, 2, pdata, size); } static inline struct amba_device * -- 1.7.5.4 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 0/6] ux500: Export SoC information and some platform clean-up @ 2012-02-06 19:22 Lee Jones 2012-02-06 19:22 ` [PATCH 4/6] mach-ux500: export System-on-Chip information ux500 via sysfs Lee Jones 0 siblings, 1 reply; 13+ messages in thread From: Lee Jones @ 2012-02-06 19:22 UTC (permalink / raw) To: linux-arm-kernel This patch-set satisfies 4 objectives: 1. Ensures each platform device can specify a suitable parent 2. Provides a bus for SoC devices as a means to export information 3. Allows ux500 to make use of the new SoC bus 4. Cleans up unnecessary complexity from ux500 code --- Documentation/ABI/testing/sysfs-devices-soc | 58 ++++++++ arch/arm/mach-ux500/Kconfig | 1 + arch/arm/mach-ux500/board-mop500-sdi.c | 31 ++-- arch/arm/mach-ux500/board-mop500.c | 74 ++++++---- arch/arm/mach-ux500/board-mop500.h | 8 +- arch/arm/mach-ux500/board-u5500-sdi.c | 4 +- arch/arm/mach-ux500/board-u5500.c | 27 ++-- arch/arm/mach-ux500/cpu-db5500.c | 36 ++++- arch/arm/mach-ux500/cpu-db8500.c | 44 +++++- arch/arm/mach-ux500/cpu.c | 75 ++++++++++ arch/arm/mach-ux500/devices-common.c | 79 ++-------- arch/arm/mach-ux500/devices-common.h | 83 ++++++----- arch/arm/mach-ux500/devices-db5500.h | 116 +++++++++------ arch/arm/mach-ux500/devices-db8500.h | 176 +++++++++++++---------- arch/arm/mach-ux500/dma-db5500.c | 3 +- arch/arm/mach-ux500/include/mach/db8500-regs.h | 3 + arch/arm/mach-ux500/include/mach/setup.h | 10 +- arch/arm/mach-ux500/include/mach/usb.h | 4 +- arch/arm/mach-ux500/usb.c | 7 +- drivers/base/Kconfig | 3 + drivers/base/Makefile | 1 + drivers/base/soc.c | 186 ++++++++++++++++++++++++ include/linux/syssoc.h | 74 ++++++++++ 23 files changed, 799 insertions(+), 304 deletions(-) ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 4/6] mach-ux500: export System-on-Chip information ux500 via sysfs 2012-02-06 19:22 [PATCH 0/6] ux500: Export SoC information and some platform clean-up Lee Jones @ 2012-02-06 19:22 ` Lee Jones 0 siblings, 0 replies; 13+ messages in thread From: Lee Jones @ 2012-02-06 19:22 UTC (permalink / raw) To: linux-arm-kernel Here we make use of the new System-On-Chip bus driver to export vital SoC information out to userspace via sysfs. This patch provides a data structure of strings to populate the base nodes found in: /sys/devices/soc[0|1|2|...]/[family|machine|revision|soc_id]. It also adds one more node as requested by ST-Ericsson. 'process' depicts the way in which the silicon was manufactured. Signed-off-by: Lee Jones <lee.jones@linaro.org> --- arch/arm/mach-ux500/Kconfig | 1 + arch/arm/mach-ux500/cpu-db5500.c | 30 +++++++--- arch/arm/mach-ux500/cpu-db8500.c | 33 +++++++++-- arch/arm/mach-ux500/cpu.c | 75 ++++++++++++++++++++++++ arch/arm/mach-ux500/include/mach/db8500-regs.h | 3 + arch/arm/mach-ux500/include/mach/setup.h | 2 + 6 files changed, 130 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index a3e0c86..ce8bac2 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -27,6 +27,7 @@ config MACH_U8500 bool "U8500 Development platform" depends on UX500_SOC_DB8500 select TPS6105X + select SOC_BUS help Include support for the mop500 development platform. diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c index c402fd6..8f8acfd 100644 --- a/arch/arm/mach-ux500/cpu-db5500.c +++ b/arch/arm/mach-ux500/cpu-db5500.c @@ -212,18 +212,32 @@ static int usb_db5500_tx_dma_cfg[] = { DB5500_DMA_DEV38_USB_OTG_OEP_8 }; -struct device* __init u5500_init_devices(void) +static const char *db5500_read_soc_id(void) { - /* FIXME: First parameter to be a real parent. */ - db5500_add_gpios(NULL); + return kasprintf(GFP_KERNEL, "u5500 currently unsupported\n"); +} + +static struct device * __init db5500_soc_device_init(void) +{ + const char *soc_id = db5500_read_soc_id(); + + return ux500_soc_device_init(soc_id); +} + +struct device * __init u5500_init_devices(void) +{ + struct device *parent; + + parent = db5500_soc_device_init(); + + db5500_add_gpios(parent); db5500_pmu_init(); - db5500_dma_init(NULL); - db5500_add_rtc(NULL); - db5500_add_usb(NULL, usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg); + db5500_dma_init(parent); + db5500_add_rtc(parent); + db5500_add_usb(parent, usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg); platform_add_devices(db5500_platform_devs, ARRAY_SIZE(db5500_platform_devs)); - /* FIXME: Return value to be a real parent. */ - return NULL; + return parent; } diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 1e8a2cb..afcde3d 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -24,6 +24,7 @@ #include <mach/setup.h> #include <mach/devices.h> #include <mach/usb.h> +#include <mach/db8500-regs.h> #include "devices-db8500.h" #include "ste-dma40-db8500.h" @@ -164,18 +165,38 @@ static int usb_db8500_tx_dma_cfg[] = { DB8500_DMA_DEV39_USB_OTG_OEP_8 }; +static const char *db8500_read_soc_id(void) +{ + void __iomem *uid = __io_address(U8500_BB_UID_BASE); + + return kasprintf(GFP_KERNEL, "%08x%08x%08x%08x%08x", + readl((u32 *)uid+1), + readl((u32 *)uid+1), readl((u32 *)uid+2), + readl((u32 *)uid+3), readl((u32 *)uid+4)); +} + +static struct device * __init db8500_soc_device_init(void) +{ + const char *soc_id = db8500_read_soc_id(); + + return ux500_soc_device_init(soc_id); +} + /* * This function is called from the board init */ -struct device* __init u8500_init_devices(void) +struct device * __init u8500_init_devices(void) { - db8500_add_rtc(NULL); - db8500_add_gpios(NULL); - db8500_add_usb(NULL, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); + struct device *parent; + + parent = db8500_soc_device_init(); + + db8500_add_rtc(parent); + db8500_add_gpios(parent); + db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); platform_device_register_simple("cpufreq-u8500", -1, NULL, 0); platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); - /* FIXME: Return value to be a real parent. */ - return NULL; + return parent; } diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index f418574..055fb6e 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c @@ -2,6 +2,7 @@ * Copyright (C) ST-Ericsson SA 2010 * * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson + * Author: Lee Jones <lee.jones@linaro.org> for ST-Ericsson * License terms: GNU General Public License (GPL) version 2 */ @@ -11,6 +12,10 @@ #include <linux/mfd/db8500-prcmu.h> #include <linux/mfd/db5500-prcmu.h> #include <linux/clksrc-dbx500-prcmu.h> +#include <linux/sys_soc.h> +#include <linux/err.h> +#include <linux/slab.h> +#include <linux/stat.h> #include <asm/hardware/gic.h> #include <asm/mach/map.h> @@ -50,3 +55,73 @@ void __init ux500_init_irq(void) db8500_prcmu_early_init(); clk_init(); } + +static const char * __init ux500_get_machine(void) +{ + return kasprintf(GFP_KERNEL, "DB%4x", dbx500_partnumber()); +} + +static const char * __init ux500_get_family(void) +{ + return kasprintf(GFP_KERNEL, "ux500"); +} + +static const char * __init ux500_get_revision(void) +{ + unsigned int rev = dbx500_revision(); + + if (rev == 0x01) + return kasprintf(GFP_KERNEL, "%s", "ED"); + else if (rev >= 0xA0) + return kasprintf(GFP_KERNEL, "%d.%d", + (rev >> 4) - 0xA + 1, rev & 0xf); + + return kasprintf(GFP_KERNEL, "%s", "Unknown"); +} + +static ssize_t ux500_get_process(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + if (dbx500_id.process == 0x00) + return sprintf(buf, "Standard\n"); + + return sprintf(buf, "%02xnm\n", dbx500_id.process); +} + +static void __init soc_info_populate(struct soc_device_attribute *soc_dev_attr, + const char *soc_id) +{ + soc_dev_attr->soc_id = soc_id; + soc_dev_attr->machine = ux500_get_machine(); + soc_dev_attr->family = ux500_get_family(); + soc_dev_attr->revision = ux500_get_revision(); +} + +struct device_attribute ux500_soc_attr = + __ATTR(process, S_IRUGO, ux500_get_process, NULL); + +struct device * __init ux500_soc_device_init(const char *soc_id) +{ + struct device *parent; + struct soc_device *soc_dev; + struct soc_device_attribute *soc_dev_attr; + + soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + if (!soc_dev_attr) + return ERR_PTR(-ENOMEM); + + soc_info_populate(soc_dev_attr, soc_id); + + soc_dev = soc_device_register(soc_dev_attr); + if (IS_ERR_OR_NULL(soc_dev)) { + kfree(soc_dev_attr); + return NULL; + } + + parent = soc_device_to_device(soc_dev); + if (!IS_ERR_OR_NULL(parent)) + device_create_file(parent, &ux500_soc_attr); + + return parent; +} diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h index 80e10f5..9ec20b9 100644 --- a/arch/arm/mach-ux500/include/mach/db8500-regs.h +++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h @@ -161,4 +161,7 @@ #define U8500_MODEM_BASE 0xe000000 #define U8500_APE_BASE 0x6000000 +/* SoC identification number information */ +#define U8500_BB_UID_BASE (U8500_BACKUPRAM1_BASE + 0xFC0) + #endif diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h index e46b8b1..74b43bb 100644 --- a/arch/arm/mach-ux500/include/mach/setup.h +++ b/arch/arm/mach-ux500/include/mach/setup.h @@ -27,6 +27,8 @@ extern void __init u5500_sdi_init(struct device *parent); extern void __init db5500_dma_init(struct device *parent); +extern struct device *ux500_soc_device_init(const char *soc_id); + /* We re-use nomadik_timer for this platform */ extern void nmdk_timer_init(void); -- 1.7.5.4 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 0/6] ux500: Export SoC information and some platform clean-up @ 2012-01-21 17:08 Lee Jones 2012-01-21 17:08 ` [PATCH 4/6] mach-ux500: export System-on-Chip information ux500 via sysfs Lee Jones 0 siblings, 1 reply; 13+ messages in thread From: Lee Jones @ 2012-01-21 17:08 UTC (permalink / raw) To: linux-arm-kernel This patch-set satisfies 4 objectives: 1. Ensures each platform device can specify a suitable parent 2. Provides a bus for SoC devices as a means to export information 3. Allows ux500 to make use of the new SoC bus 4. Cleans up unnecessary complexity from ux500 code Documentation/ABI/testing/sysfs-devices-soc | 58 ++++++++ arch/arm/mach-ux500/Kconfig | 1 + arch/arm/mach-ux500/board-mop500-sdi.c | 31 ++-- arch/arm/mach-ux500/board-mop500.c | 74 ++++++---- arch/arm/mach-ux500/board-mop500.h | 8 +- arch/arm/mach-ux500/board-u5500-sdi.c | 4 +- arch/arm/mach-ux500/board-u5500.c | 27 +++-- arch/arm/mach-ux500/cpu-db5500.c | 36 ++++- arch/arm/mach-ux500/cpu-db8500.c | 44 +++++- arch/arm/mach-ux500/cpu.c | 75 ++++++++++ arch/arm/mach-ux500/devices-common.c | 79 +++-------- arch/arm/mach-ux500/devices-common.h | 83 ++++++----- arch/arm/mach-ux500/devices-db5500.h | 116 +++++++++------ arch/arm/mach-ux500/devices-db8500.h | 176 +++++++++++++---------- arch/arm/mach-ux500/dma-db5500.c | 3 +- arch/arm/mach-ux500/include/mach/db8500-regs.h | 3 + arch/arm/mach-ux500/include/mach/setup.h | 10 +- arch/arm/mach-ux500/include/mach/usb.h | 4 +- arch/arm/mach-ux500/usb.c | 7 +- drivers/base/Kconfig | 3 + drivers/base/Makefile | 1 + drivers/base/soc.c | 185 ++++++++++++++++++++++++ include/linux/sys_soc.h | 37 +++++ 23 files changed, 761 insertions(+), 304 deletions(-) ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 4/6] mach-ux500: export System-on-Chip information ux500 via sysfs 2012-01-21 17:08 [PATCH 0/6] ux500: Export SoC information and some platform clean-up Lee Jones @ 2012-01-21 17:08 ` Lee Jones 0 siblings, 0 replies; 13+ messages in thread From: Lee Jones @ 2012-01-21 17:08 UTC (permalink / raw) To: linux-arm-kernel Here we make use of the new System-On-Chip bus driver to export vital SoC information out to userspace via sysfs. This patch provides a data structure of strings to populate the base nodes found in: /sys/devices/soc[0|1|2|...]/[family|machine|revision|soc_id]. It also adds one more node as requested by ST-Ericsson. 'process' depicts the way in which the silicon was manufactured. Signed-off-by: Lee Jones <lee.jones@linaro.org> --- arch/arm/mach-ux500/Kconfig | 1 + arch/arm/mach-ux500/cpu-db5500.c | 30 +++++++--- arch/arm/mach-ux500/cpu-db8500.c | 33 +++++++++-- arch/arm/mach-ux500/cpu.c | 75 ++++++++++++++++++++++++ arch/arm/mach-ux500/include/mach/db8500-regs.h | 3 + arch/arm/mach-ux500/include/mach/setup.h | 2 + 6 files changed, 130 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index a3e0c86..ce8bac2 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -27,6 +27,7 @@ config MACH_U8500 bool "U8500 Development platform" depends on UX500_SOC_DB8500 select TPS6105X + select SOC_BUS help Include support for the mop500 development platform. diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c index c402fd6..8f8acfd 100644 --- a/arch/arm/mach-ux500/cpu-db5500.c +++ b/arch/arm/mach-ux500/cpu-db5500.c @@ -212,18 +212,32 @@ static int usb_db5500_tx_dma_cfg[] = { DB5500_DMA_DEV38_USB_OTG_OEP_8 }; -struct device* __init u5500_init_devices(void) +static const char *db5500_read_soc_id(void) { - /* FIXME: First parameter to be a real parent. */ - db5500_add_gpios(NULL); + return kasprintf(GFP_KERNEL, "u5500 currently unsupported\n"); +} + +static struct device * __init db5500_soc_device_init(void) +{ + const char *soc_id = db5500_read_soc_id(); + + return ux500_soc_device_init(soc_id); +} + +struct device * __init u5500_init_devices(void) +{ + struct device *parent; + + parent = db5500_soc_device_init(); + + db5500_add_gpios(parent); db5500_pmu_init(); - db5500_dma_init(NULL); - db5500_add_rtc(NULL); - db5500_add_usb(NULL, usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg); + db5500_dma_init(parent); + db5500_add_rtc(parent); + db5500_add_usb(parent, usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg); platform_add_devices(db5500_platform_devs, ARRAY_SIZE(db5500_platform_devs)); - /* FIXME: Return value to be a real parent. */ - return NULL; + return parent; } diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 1e8a2cb..afcde3d 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -24,6 +24,7 @@ #include <mach/setup.h> #include <mach/devices.h> #include <mach/usb.h> +#include <mach/db8500-regs.h> #include "devices-db8500.h" #include "ste-dma40-db8500.h" @@ -164,18 +165,38 @@ static int usb_db8500_tx_dma_cfg[] = { DB8500_DMA_DEV39_USB_OTG_OEP_8 }; +static const char *db8500_read_soc_id(void) +{ + void __iomem *uid = __io_address(U8500_BB_UID_BASE); + + return kasprintf(GFP_KERNEL, "%08x%08x%08x%08x%08x", + readl((u32 *)uid+1), + readl((u32 *)uid+1), readl((u32 *)uid+2), + readl((u32 *)uid+3), readl((u32 *)uid+4)); +} + +static struct device * __init db8500_soc_device_init(void) +{ + const char *soc_id = db8500_read_soc_id(); + + return ux500_soc_device_init(soc_id); +} + /* * This function is called from the board init */ -struct device* __init u8500_init_devices(void) +struct device * __init u8500_init_devices(void) { - db8500_add_rtc(NULL); - db8500_add_gpios(NULL); - db8500_add_usb(NULL, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); + struct device *parent; + + parent = db8500_soc_device_init(); + + db8500_add_rtc(parent); + db8500_add_gpios(parent); + db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); platform_device_register_simple("cpufreq-u8500", -1, NULL, 0); platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); - /* FIXME: Return value to be a real parent. */ - return NULL; + return parent; } diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index f418574..055fb6e 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c @@ -2,6 +2,7 @@ * Copyright (C) ST-Ericsson SA 2010 * * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson + * Author: Lee Jones <lee.jones@linaro.org> for ST-Ericsson * License terms: GNU General Public License (GPL) version 2 */ @@ -11,6 +12,10 @@ #include <linux/mfd/db8500-prcmu.h> #include <linux/mfd/db5500-prcmu.h> #include <linux/clksrc-dbx500-prcmu.h> +#include <linux/sys_soc.h> +#include <linux/err.h> +#include <linux/slab.h> +#include <linux/stat.h> #include <asm/hardware/gic.h> #include <asm/mach/map.h> @@ -50,3 +55,73 @@ void __init ux500_init_irq(void) db8500_prcmu_early_init(); clk_init(); } + +static const char * __init ux500_get_machine(void) +{ + return kasprintf(GFP_KERNEL, "DB%4x", dbx500_partnumber()); +} + +static const char * __init ux500_get_family(void) +{ + return kasprintf(GFP_KERNEL, "ux500"); +} + +static const char * __init ux500_get_revision(void) +{ + unsigned int rev = dbx500_revision(); + + if (rev == 0x01) + return kasprintf(GFP_KERNEL, "%s", "ED"); + else if (rev >= 0xA0) + return kasprintf(GFP_KERNEL, "%d.%d", + (rev >> 4) - 0xA + 1, rev & 0xf); + + return kasprintf(GFP_KERNEL, "%s", "Unknown"); +} + +static ssize_t ux500_get_process(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + if (dbx500_id.process == 0x00) + return sprintf(buf, "Standard\n"); + + return sprintf(buf, "%02xnm\n", dbx500_id.process); +} + +static void __init soc_info_populate(struct soc_device_attribute *soc_dev_attr, + const char *soc_id) +{ + soc_dev_attr->soc_id = soc_id; + soc_dev_attr->machine = ux500_get_machine(); + soc_dev_attr->family = ux500_get_family(); + soc_dev_attr->revision = ux500_get_revision(); +} + +struct device_attribute ux500_soc_attr = + __ATTR(process, S_IRUGO, ux500_get_process, NULL); + +struct device * __init ux500_soc_device_init(const char *soc_id) +{ + struct device *parent; + struct soc_device *soc_dev; + struct soc_device_attribute *soc_dev_attr; + + soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + if (!soc_dev_attr) + return ERR_PTR(-ENOMEM); + + soc_info_populate(soc_dev_attr, soc_id); + + soc_dev = soc_device_register(soc_dev_attr); + if (IS_ERR_OR_NULL(soc_dev)) { + kfree(soc_dev_attr); + return NULL; + } + + parent = soc_device_to_device(soc_dev); + if (!IS_ERR_OR_NULL(parent)) + device_create_file(parent, &ux500_soc_attr); + + return parent; +} diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h index 80e10f5..9ec20b9 100644 --- a/arch/arm/mach-ux500/include/mach/db8500-regs.h +++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h @@ -161,4 +161,7 @@ #define U8500_MODEM_BASE 0xe000000 #define U8500_APE_BASE 0x6000000 +/* SoC identification number information */ +#define U8500_BB_UID_BASE (U8500_BACKUPRAM1_BASE + 0xFC0) + #endif diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h index e46b8b1..74b43bb 100644 --- a/arch/arm/mach-ux500/include/mach/setup.h +++ b/arch/arm/mach-ux500/include/mach/setup.h @@ -27,6 +27,8 @@ extern void __init u5500_sdi_init(struct device *parent); extern void __init db5500_dma_init(struct device *parent); +extern struct device *ux500_soc_device_init(const char *soc_id); + /* We re-use nomadik_timer for this platform */ extern void nmdk_timer_init(void); -- 1.7.5.4 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 0/6] ux500: Export SoC information and some platform clean-up @ 2012-01-20 16:10 Lee Jones 2012-01-20 16:10 ` [PATCH 4/6] mach-ux500: export System-on-Chip information ux500 via sysfs Lee Jones 0 siblings, 1 reply; 13+ messages in thread From: Lee Jones @ 2012-01-20 16:10 UTC (permalink / raw) To: linux-arm-kernel This patch-set satisfies 4 objectives: 1. Ensures each platform device can specify a suitable parent 2. Provides a bus for SoC devices as a means to export information 3. Allows ux500 to make use of the new SoC bus 4. Cleans up unnecessary complexity from ux500 code Documentation/ABI/testing/sysfs-devices-soc | 58 ++++++++ arch/arm/mach-ux500/Kconfig | 1 + arch/arm/mach-ux500/board-mop500-sdi.c | 31 ++-- arch/arm/mach-ux500/board-mop500.c | 74 +++++++---- arch/arm/mach-ux500/board-mop500.h | 8 +- arch/arm/mach-ux500/board-u5500-sdi.c | 4 +- arch/arm/mach-ux500/board-u5500.c | 27 +++-- arch/arm/mach-ux500/cpu-db5500.c | 36 ++++- arch/arm/mach-ux500/cpu-db8500.c | 44 +++++- arch/arm/mach-ux500/cpu.c | 70 ++++++++++ arch/arm/mach-ux500/devices-common.c | 79 +++--------- arch/arm/mach-ux500/devices-common.h | 83 ++++++----- arch/arm/mach-ux500/devices-db5500.h | 116 +++++++++------- arch/arm/mach-ux500/devices-db8500.h | 176 ++++++++++++++---------- arch/arm/mach-ux500/dma-db5500.c | 3 +- arch/arm/mach-ux500/include/mach/db8500-regs.h | 3 + arch/arm/mach-ux500/include/mach/setup.h | 10 +- arch/arm/mach-ux500/include/mach/usb.h | 4 +- arch/arm/mach-ux500/usb.c | 7 +- drivers/base/Kconfig | 3 + drivers/base/Makefile | 1 + drivers/base/soc.c | 175 +++++++++++++++++++++++ include/linux/sys_soc.h | 37 +++++ 23 files changed, 746 insertions(+), 304 deletions(-) ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 4/6] mach-ux500: export System-on-Chip information ux500 via sysfs 2012-01-20 16:10 [PATCH 0/6] ux500: Export SoC information and some platform clean-up Lee Jones @ 2012-01-20 16:10 ` Lee Jones 0 siblings, 0 replies; 13+ messages in thread From: Lee Jones @ 2012-01-20 16:10 UTC (permalink / raw) To: linux-arm-kernel Here we make use of the new System-On-Chip bus driver to export vital SoC information out to userspace via sysfs. This patch provides a data structure of strings to populate the base nodes found in: /sys/devices/soc[0|1|2|...]/[family|machine|revision|soc_id]. It also adds one more node as requested by ST-Ericsson. 'process' depicts the way in which the silicon was manufactured. Signed-off-by: Lee Jones <lee.jones@linaro.org> --- arch/arm/mach-ux500/Kconfig | 1 + arch/arm/mach-ux500/cpu-db5500.c | 30 ++++++++--- arch/arm/mach-ux500/cpu-db8500.c | 33 +++++++++-- arch/arm/mach-ux500/cpu.c | 70 ++++++++++++++++++++++++ arch/arm/mach-ux500/include/mach/db8500-regs.h | 3 + arch/arm/mach-ux500/include/mach/setup.h | 2 + 6 files changed, 125 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index a3e0c86..ce8bac2 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -27,6 +27,7 @@ config MACH_U8500 bool "U8500 Development platform" depends on UX500_SOC_DB8500 select TPS6105X + select SOC_BUS help Include support for the mop500 development platform. diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c index c402fd6..8f8acfd 100644 --- a/arch/arm/mach-ux500/cpu-db5500.c +++ b/arch/arm/mach-ux500/cpu-db5500.c @@ -212,18 +212,32 @@ static int usb_db5500_tx_dma_cfg[] = { DB5500_DMA_DEV38_USB_OTG_OEP_8 }; -struct device* __init u5500_init_devices(void) +static const char *db5500_read_soc_id(void) { - /* FIXME: First parameter to be a real parent. */ - db5500_add_gpios(NULL); + return kasprintf(GFP_KERNEL, "u5500 currently unsupported\n"); +} + +static struct device * __init db5500_soc_device_init(void) +{ + const char *soc_id = db5500_read_soc_id(); + + return ux500_soc_device_init(soc_id); +} + +struct device * __init u5500_init_devices(void) +{ + struct device *parent; + + parent = db5500_soc_device_init(); + + db5500_add_gpios(parent); db5500_pmu_init(); - db5500_dma_init(NULL); - db5500_add_rtc(NULL); - db5500_add_usb(NULL, usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg); + db5500_dma_init(parent); + db5500_add_rtc(parent); + db5500_add_usb(parent, usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg); platform_add_devices(db5500_platform_devs, ARRAY_SIZE(db5500_platform_devs)); - /* FIXME: Return value to be a real parent. */ - return NULL; + return parent; } diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 1e8a2cb..afcde3d 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -24,6 +24,7 @@ #include <mach/setup.h> #include <mach/devices.h> #include <mach/usb.h> +#include <mach/db8500-regs.h> #include "devices-db8500.h" #include "ste-dma40-db8500.h" @@ -164,18 +165,38 @@ static int usb_db8500_tx_dma_cfg[] = { DB8500_DMA_DEV39_USB_OTG_OEP_8 }; +static const char *db8500_read_soc_id(void) +{ + void __iomem *uid = __io_address(U8500_BB_UID_BASE); + + return kasprintf(GFP_KERNEL, "%08x%08x%08x%08x%08x", + readl((u32 *)uid+1), + readl((u32 *)uid+1), readl((u32 *)uid+2), + readl((u32 *)uid+3), readl((u32 *)uid+4)); +} + +static struct device * __init db8500_soc_device_init(void) +{ + const char *soc_id = db8500_read_soc_id(); + + return ux500_soc_device_init(soc_id); +} + /* * This function is called from the board init */ -struct device* __init u8500_init_devices(void) +struct device * __init u8500_init_devices(void) { - db8500_add_rtc(NULL); - db8500_add_gpios(NULL); - db8500_add_usb(NULL, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); + struct device *parent; + + parent = db8500_soc_device_init(); + + db8500_add_rtc(parent); + db8500_add_gpios(parent); + db8500_add_usb(parent, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); platform_device_register_simple("cpufreq-u8500", -1, NULL, 0); platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); - /* FIXME: Return value to be a real parent. */ - return NULL; + return parent; } diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index f418574..5f702f9 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c @@ -2,6 +2,7 @@ * Copyright (C) ST-Ericsson SA 2010 * * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson + * Author: Lee Jones <lee.jones@linaro.org> for ST-Ericsson * License terms: GNU General Public License (GPL) version 2 */ @@ -11,6 +12,10 @@ #include <linux/mfd/db8500-prcmu.h> #include <linux/mfd/db5500-prcmu.h> #include <linux/clksrc-dbx500-prcmu.h> +#include <linux/sys_soc.h> +#include <linux/err.h> +#include <linux/slab.h> +#include <linux/stat.h> #include <asm/hardware/gic.h> #include <asm/mach/map.h> @@ -50,3 +55,68 @@ void __init ux500_init_irq(void) db8500_prcmu_early_init(); clk_init(); } + +static const char * __init ux500_get_machine(void) +{ + return kasprintf(GFP_KERNEL, "DB%4x", dbx500_partnumber()); +} + +static const char * __init ux500_get_family(void) +{ + return kasprintf(GFP_KERNEL, "ux500"); +} + +static const char * __init ux500_get_revision(void) +{ + unsigned int rev = dbx500_revision(); + + if (rev == 0x01) + return kasprintf(GFP_KERNEL, "%s", "ED"); + else if (rev >= 0xA0) + return kasprintf(GFP_KERNEL, "%d.%d", + (rev >> 4) - 0xA + 1, rev & 0xf); + + return kasprintf(GFP_KERNEL, "%s", "Unknown"); +} + +static ssize_t ux500_get_process(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + if (dbx500_id.process == 0x00) + return sprintf(buf, "Standard\n"); + + return sprintf(buf, "%02xnm\n", dbx500_id.process); +} + +static void __init soc_info_populate(struct soc_device_attribute *soc_dev_attr, + const char *soc_id) +{ + soc_dev_attr->soc_id = soc_id; + soc_dev_attr->machine = ux500_get_machine(); + soc_dev_attr->family = ux500_get_family(); + soc_dev_attr->revision = ux500_get_revision(); +} + +struct device_attribute ux500_soc_attr = + __ATTR(process, S_IRUGO, ux500_get_process, NULL); + +struct device * __init ux500_soc_device_init(const char *soc_id) +{ + struct device *parent; + struct soc_device *soc_dev; + struct soc_device_attribute *soc_dev_attr; + + soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + if (!soc_dev_attr) + return ERR_PTR(-ENOMEM); + + soc_info_populate(soc_dev_attr, soc_id); + + soc_dev = soc_device_register(soc_dev_attr); + parent = soc_device_to_device(soc_dev); + if (!IS_ERR_OR_NULL(parent)) + device_create_file(parent, &ux500_soc_attr); + + return parent; +} diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h index 80e10f5..9ec20b9 100644 --- a/arch/arm/mach-ux500/include/mach/db8500-regs.h +++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h @@ -161,4 +161,7 @@ #define U8500_MODEM_BASE 0xe000000 #define U8500_APE_BASE 0x6000000 +/* SoC identification number information */ +#define U8500_BB_UID_BASE (U8500_BACKUPRAM1_BASE + 0xFC0) + #endif diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h index e46b8b1..74b43bb 100644 --- a/arch/arm/mach-ux500/include/mach/setup.h +++ b/arch/arm/mach-ux500/include/mach/setup.h @@ -27,6 +27,8 @@ extern void __init u5500_sdi_init(struct device *parent); extern void __init db5500_dma_init(struct device *parent); +extern struct device *ux500_soc_device_init(const char *soc_id); + /* We re-use nomadik_timer for this platform */ extern void nmdk_timer_init(void); -- 1.7.5.4 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 0/6] ux500: Export SoC information and some platform clean-up @ 2011-10-17 11:52 Lee Jones 2011-10-17 11:52 ` [PATCH 4/6] mach-ux500: export System-on-Chip information ux500 via sysfs Lee Jones 0 siblings, 1 reply; 13+ messages in thread From: Lee Jones @ 2011-10-17 11:52 UTC (permalink / raw) To: linux-arm-kernel This patch-set satisfies 4 objectives: 1. Ensures each platform device can specify a suitable parent 2. Provides a bus for SoC devices as a means to export information 3. Allows ux500 to make use of the new SoC bus 4. Cleans up unnecessary complexity from ux500 code Documentation/ABI/testing/sysfs-devices-soc | 24 ++++ arch/arm/mach-ux500/Kconfig | 1 + arch/arm/mach-ux500/board-mop500-sdi.c | 30 ++-- arch/arm/mach-ux500/board-mop500.c | 74 +++++++---- arch/arm/mach-ux500/board-mop500.h | 6 +- arch/arm/mach-ux500/board-u5500-sdi.c | 4 +- arch/arm/mach-ux500/board-u5500.c | 27 +++-- arch/arm/mach-ux500/cpu-db5500.c | 37 ++++- arch/arm/mach-ux500/cpu-db8500.c | 45 +++++- arch/arm/mach-ux500/cpu.c | 67 +++++++++ arch/arm/mach-ux500/devices-common.c | 79 +++--------- arch/arm/mach-ux500/devices-common.h | 71 +++++----- arch/arm/mach-ux500/devices-db5500.h | 116 +++++++++------- arch/arm/mach-ux500/devices-db8500.h | 176 ++++++++++++++---------- arch/arm/mach-ux500/dma-db5500.c | 3 +- arch/arm/mach-ux500/include/mach/db8500-regs.h | 3 + arch/arm/mach-ux500/include/mach/setup.h | 10 +- arch/arm/mach-ux500/include/mach/usb.h | 4 +- arch/arm/mach-ux500/usb.c | 7 +- drivers/base/Kconfig | 3 + drivers/base/Makefile | 1 + drivers/base/soc.c | 115 +++++++++++++++ include/linux/sys_soc.h | 38 +++++ 23 files changed, 639 insertions(+), 302 deletions(-) ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 4/6] mach-ux500: export System-on-Chip information ux500 via sysfs 2011-10-17 11:52 [PATCH 0/6] ux500: Export SoC information and some platform clean-up Lee Jones @ 2011-10-17 11:52 ` Lee Jones 0 siblings, 0 replies; 13+ messages in thread From: Lee Jones @ 2011-10-17 11:52 UTC (permalink / raw) To: linux-arm-kernel Here we make use of the new System-On-Chip bus driver to export vital SoC information out to userspace via sysfs. This patch provides a data structure of strings to populate the base nodes found in: /sys/devices/soc[0|1|2|...]/[family|machine|revision|soc_id]. It also adds one more node as requested by ST-Ericsson. 'process' depicts the way in which the silicon was manufactured. Signed-off-by: Lee Jones <lee.jones@linaro.org> --- arch/arm/mach-ux500/Kconfig | 1 + arch/arm/mach-ux500/cpu-db5500.c | 32 +++++++++--- arch/arm/mach-ux500/cpu-db8500.c | 36 ++++++++++--- arch/arm/mach-ux500/cpu.c | 67 ++++++++++++++++++++++++ arch/arm/mach-ux500/include/mach/db8500-regs.h | 3 + arch/arm/mach-ux500/include/mach/setup.h | 6 ++- 6 files changed, 128 insertions(+), 17 deletions(-) diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig index 86188b2..1c462ed 100644 --- a/arch/arm/mach-ux500/Kconfig +++ b/arch/arm/mach-ux500/Kconfig @@ -27,6 +27,7 @@ config MACH_U8500 bool "U8500 Development platform" depends on UX500_SOC_DB8500 select TPS6105X + select SOC_BUS help Include support for the mop500 development platform. diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c index 3995284..6bbc9da 100644 --- a/arch/arm/mach-ux500/cpu-db5500.c +++ b/arch/arm/mach-ux500/cpu-db5500.c @@ -220,17 +220,33 @@ static int usb_db5500_tx_dma_cfg[] = { DB5500_DMA_DEV38_USB_OTG_OEP_8 }; -struct device* __init u5500_init_devices(void) +static const char *db5500_read_soc_id(void) { - /* FIXME: First parameter to be a real parent. */ - db5500_add_gpios(NULL); - db5500_dma_init(NULL); - db5500_add_rtc(NULL); - db5500_add_usb(NULL, usb_db5500_rx_dma_cfg, usb_db5500_tx_dma_cfg); + return kasprintf(GFP_KERNEL, "u5500 currently unsupported\n"); +} + +static struct device * __init db5500_soc_device_init(void) +{ + const char *soc_id = db5500_read_soc_id(); + + return ux500_soc_device_init(soc_id); +} + +struct device * __init u5500_init_devices(void) +{ + struct device *parent; + int i; + + parent = db5500_soc_device_init(); + + db5500_add_gpios(parent); + db5500_dma_init(parent); + db5500_add_rtc(parent); + db5500_add_usb(parent, usb_db5500_rx_dma_cfg, + usb_db5500_tx_dma_cfg); platform_add_devices(db5500_platform_devs, ARRAY_SIZE(db5500_platform_devs)); - /* FIXME: Return value to be a real parent. */ - return NULL; + return parent; } diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 375171e..c83440b 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -24,6 +24,7 @@ #include <mach/setup.h> #include <mach/devices.h> #include <mach/usb.h> +#include <mach/db8500-regs.h> #include "devices-db8500.h" #include "ste-dma40-db8500.h" @@ -188,22 +189,43 @@ static int usb_db8500_tx_dma_cfg[] = { DB8500_DMA_DEV39_USB_OTG_OEP_8 }; +static const char *db8500_read_soc_id(void) +{ + void __iomem *uid = __io_address(U8500_BB_UID_BASE); + + return kasprintf(GFP_KERNEL, "%08x%08x%08x%08x%08x", + readl((u32 *)uid+1), + readl((u32 *)uid+1), readl((u32 *)uid+2), + readl((u32 *)uid+3), readl((u32 *)uid+4)); +} + +static struct device * __init db8500_soc_device_init(void) +{ + const char *soc_id = db8500_read_soc_id(); + + return ux500_soc_device_init(soc_id); +} + /* * This function is called from the board init */ -struct device* __init u8500_init_devices(void) +struct device * __init u8500_init_devices(void) { + struct device *parent; + int i; + + parent = db8500_soc_device_init(); + if (cpu_is_u8500ed()) dma40_u8500ed_fixup(); - /* FIXME: First parameter to be a real parent. */ - db8500_add_rtc(NULL); - db8500_add_gpios(NULL); - db8500_add_usb(NULL, usb_db8500_rx_dma_cfg, usb_db8500_tx_dma_cfg); + db8500_add_rtc(parent); + db8500_add_gpios(parent); + db8500_add_usb(parent, usb_db8500_rx_dma_cfg, + usb_db8500_tx_dma_cfg); platform_device_register_simple("cpufreq-u8500", -1, NULL, 0); platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); - /* FIXME: Return value to be a real parent. */ - return NULL; + return parent; } diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index b457799..3315436 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c @@ -2,6 +2,7 @@ * Copyright (C) ST-Ericsson SA 2010 * * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson + * Author: Lee Jones <lee.jones@linaro.org> for ST-Ericsson * License terms: GNU General Public License (GPL) version 2 */ @@ -10,6 +11,9 @@ #include <linux/clk.h> #include <linux/mfd/db8500-prcmu.h> #include <linux/mfd/db5500-prcmu.h> +#include <linux/sys_soc.h> +#include <linux/err.h> +#include <linux/slab.h> #include <asm/hardware/gic.h> #include <asm/mach/map.h> @@ -77,3 +81,66 @@ static void __init ux500_timer_init(void) struct sys_timer ux500_timer = { .init = ux500_timer_init, }; + +static const char * __init ux500_get_machine(void) +{ + return kasprintf(GFP_KERNEL, "DB%4x", dbx500_partnumber()); +} + +static const char * __init ux500_get_family(void) +{ + return kasprintf(GFP_KERNEL, "ux500"); +} + +static const char * __init ux500_get_revision(void) +{ + unsigned int rev = dbx500_revision(); + + if (rev == 0x01) + return kasprintf(GFP_KERNEL, "%s", "ED"); + else if (rev >= 0xA0) + return kasprintf(GFP_KERNEL, "%d.%d", + (rev >> 4) - 0xA + 1, rev & 0xf); + + return kasprintf(GFP_KERNEL, "%s", "Unknown"); +} + +static ssize_t __init ux500_get_process(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + if (dbx500_id.process == 0x00) + return sprintf(buf, "Standard\n"); + + return sprintf(buf, "%02xnm\n", dbx500_id.process); +} + +static void __init soc_info_populate(struct soc_device_attribute *soc_dev_attr, + const char *soc_id) +{ + soc_dev_attr->soc_id = soc_id; + soc_dev_attr->machine = ux500_get_machine(); + soc_dev_attr->family = ux500_get_family(); + soc_dev_attr->revision = ux500_get_revision(); +} + +struct device_attribute ux500_soc_attr = + __ATTR(process, S_IRUGO, ux500_get_process, NULL); + +struct device * __init ux500_soc_device_init(const char *soc_id) +{ + struct device *parent; + struct soc_device_attribute *soc_dev_attr; + + soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + if (!soc_dev_attr) + return ERR_PTR(-ENOMEM); + + soc_info_populate(soc_dev_attr, soc_id); + + parent = soc_device_register(soc_dev_attr); + if (!IS_ERR_OR_NULL(parent)) + device_create_file(parent, &ux500_soc_attr); + + return parent; +} diff --git a/arch/arm/mach-ux500/include/mach/db8500-regs.h b/arch/arm/mach-ux500/include/mach/db8500-regs.h index 0499971..22a9a5d 100644 --- a/arch/arm/mach-ux500/include/mach/db8500-regs.h +++ b/arch/arm/mach-ux500/include/mach/db8500-regs.h @@ -166,4 +166,7 @@ #define U8500_MODEM_BASE 0xe000000 #define U8500_APE_BASE 0x6000000 +/* SoC identification number information */ +#define U8500_BB_UID_BASE (U8500_BACKUPRAM1_BASE + 0xFC0) + #endif diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h index 88e8d6b..74b43bb 100644 --- a/arch/arm/mach-ux500/include/mach/setup.h +++ b/arch/arm/mach-ux500/include/mach/setup.h @@ -18,8 +18,8 @@ void __init ux500_map_io(void); extern void __init u5500_map_io(void); extern void __init u8500_map_io(void); -extern void __init u5500_init_devices(void); -extern void __init u8500_init_devices(void); +extern struct device * __init u5500_init_devices(void); +extern struct device * __init u8500_init_devices(void); extern void __init ux500_init_irq(void); @@ -27,6 +27,8 @@ extern void __init u5500_sdi_init(struct device *parent); extern void __init db5500_dma_init(struct device *parent); +extern struct device *ux500_soc_device_init(const char *soc_id); + /* We re-use nomadik_timer for this platform */ extern void nmdk_timer_init(void); -- 1.7.5.4 ^ permalink raw reply related [flat|nested] 13+ messages in thread
end of thread, other threads:[~2012-02-06 19:22 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-02-01 9:23 [PATCH 0/6] ux500: Export SoC information and some platform clean-up Lee Jones 2012-02-01 9:23 ` [PATCH 1/6] mach-ux500: pass parent pointer to each platform device Lee Jones 2012-02-01 9:23 ` [PATCH 2/6] drivers/base: add bus for System-on-Chip devices Lee Jones 2012-02-01 15:52 ` Jamie Iles 2012-02-01 16:55 ` Arnd Bergmann 2012-02-01 9:23 ` [PATCH 3/6] Documentation: add information for new sysfs soc bus functionality Lee Jones 2012-02-01 9:23 ` [PATCH 4/6] mach-ux500: export System-on-Chip information ux500 via sysfs Lee Jones 2012-02-01 9:23 ` [PATCH 5/6] mach-ux500: move top level platform devices in sysfs to /sys/devices/socX Lee Jones 2012-02-01 9:23 ` [PATCH 6/6] mach-ux500: remove intermediary add_platform_device* functions Lee Jones -- strict thread matches above, loose matches on Subject: below -- 2012-02-06 19:22 [PATCH 0/6] ux500: Export SoC information and some platform clean-up Lee Jones 2012-02-06 19:22 ` [PATCH 4/6] mach-ux500: export System-on-Chip information ux500 via sysfs Lee Jones 2012-01-21 17:08 [PATCH 0/6] ux500: Export SoC information and some platform clean-up Lee Jones 2012-01-21 17:08 ` [PATCH 4/6] mach-ux500: export System-on-Chip information ux500 via sysfs Lee Jones 2012-01-20 16:10 [PATCH 0/6] ux500: Export SoC information and some platform clean-up Lee Jones 2012-01-20 16:10 ` [PATCH 4/6] mach-ux500: export System-on-Chip information ux500 via sysfs Lee Jones 2011-10-17 11:52 [PATCH 0/6] ux500: Export SoC information and some platform clean-up Lee Jones 2011-10-17 11:52 ` [PATCH 4/6] mach-ux500: export System-on-Chip information ux500 via sysfs Lee Jones
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).