[PATCH] arm: vexpress: hook platform_data to clcd_pl11x by amba bus_notify
Barry Song
21cnbao at gmail.com
Sat Dec 15 00:39:24 EST 2012
From: Barry Song <Baohua.Song at csr.com>
when using dtb to boot v2p-ca9, clcd probe will fail due to missed
the platform_data:
clcd-pl11x: probe of 10020000.clcd failed with error -22
this patch hooks the platform_data to clcd and make lcd of v2p-ca9
can work while booting vexpress by DTB.
Tested on qemu by "qemu-system-arm -M vexpress-a9 -m 512M -kernel
zImage -dtb ./vexpress-v2p-ca9.dtb"
Signed-off-by: Barry Song <Baohua.Song at csr.com>
---
arch/arm/mach-vexpress/ct-ca9x4.c | 30 +++++++++++++++++++++
arch/arm/mach-vexpress/include/mach/motherboard.h | 1 +
arch/arm/mach-vexpress/v2m.c | 10 +++++++
3 files changed, 41 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index 4f471fa..92b03e7 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -111,6 +111,35 @@ static struct amba_device *ct_ca9x4_amba_devs[] __initdata = {
&gpio_device,
};
+static int ct_ca9x4_of_amba_notify(struct notifier_block *nb, unsigned long action,
+ void *data)
+{
+ struct device *dev = data;
+
+ /* We are only intereted in device addition */
+ if (action != BUS_NOTIFY_ADD_DEVICE)
+ return 0;
+
+ if (!of_find_compatible_node(NULL, NULL, "arm,vexpress,v2p-ca9"))
+ return 0;
+
+ if (of_device_is_compatible(dev->of_node, "arm,pl111"))
+ dev->platform_data = &ct_ca9x4_clcd_data;
+
+ return 0;
+}
+
+static struct notifier_block ct_ca9x4_amba_nb = {
+ .notifier_call = ct_ca9x4_of_amba_notify,
+};
+
+static void ct_ca9x4_register_bus_nb(void)
+{
+ /* Register callbacks on OF amba device addition/removal
+ * to handle linking them to the right platform_data
+ */
+ bus_register_notifier(&amba_bustype, &ct_ca9x4_amba_nb);
+}
static struct v2m_osc ct_osc1 = {
.osc = 1,
@@ -211,6 +240,7 @@ struct ct_desc ct_ca9x4_desc __initdata = {
.map_io = ct_ca9x4_map_io,
.init_irq = ct_ca9x4_init_irq,
.init_tile = ct_ca9x4_init,
+ .bus_notifer = ct_ca9x4_register_bus_nb,
#ifdef CONFIG_SMP
.init_cpu_map = ct_ca9x4_init_cpu_map,
.smp_enable = ct_ca9x4_smp_enable,
diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h
index 1e388c7..f88982b 100644
--- a/arch/arm/mach-vexpress/include/mach/motherboard.h
+++ b/arch/arm/mach-vexpress/include/mach/motherboard.h
@@ -141,6 +141,7 @@ struct ct_desc {
void (*init_early)(void);
void (*init_irq)(void);
void (*init_tile)(void);
+ void (*bus_notifer)(void);
#ifdef CONFIG_SMP
void (*init_cpu_map)(void);
void (*smp_enable)(unsigned int);
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 560e0df..e9147f8 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -431,6 +431,8 @@ static void __init v2m_clk_init(void)
clk = v2m_osc_register("mb:osc1", &v2m_mb_osc1);
for (i = 0; i < ARRAY_SIZE(v2m_osc1_periphs); i++)
WARN_ON(clk_register_clkdev(clk, NULL, v2m_osc1_periphs[i]));
+ if (of_find_compatible_node(NULL, NULL, "arm,vexpress,v2p-ca9"))
+ WARN_ON(clk_register_clkdev(clk, NULL, "10020000.clcd"));
clk = clk_register_fixed_rate(NULL, "mb:osc2", NULL,
CLK_IS_ROOT, 24000000);
@@ -651,7 +653,15 @@ static struct of_dev_auxdata v2m_dt_auxdata_lookup[] __initdata = {
static void __init v2m_dt_init(void)
{
+ int i;
+
l2x0_of_init(0x00400000, 0xfe0fffff);
+
+ /* some devices need to hook platform_data */
+ for (i = 0; i < ARRAY_SIZE(ct_descs); i++)
+ if (ct_descs[i]->bus_notifer)
+ ct_descs[i]->bus_notifer();
+
of_platform_populate(NULL, of_default_bus_match_table,
v2m_dt_auxdata_lookup, NULL);
pm_power_off = v2m_power_off;
--
1.7.1
More information about the linux-arm-kernel
mailing list