diff options
author | Lars-Peter Clausen <lars@metafoo.de> | 2010-04-04 20:37:28 +0200 |
---|---|---|
committer | Lars-Peter Clausen <lars@metafoo.de> | 2010-05-17 20:59:37 +0200 |
commit | b27e3d74ea6afd91cd4763bca94cd19f4bedb5fc (patch) | |
tree | 4af6e71840fb7275c60d20b621389e225df4801f | |
parent | e46f39af3ced84382ec61fd0ca2d23d444331292 (diff) |
gta02: Add notify handler to probe device children
On the gta02 we often have a child parent relationship between different
devices. The child devices can only be probed after their parant has been.
Instead of adding a probe completed handler to each device we handle this in a
generic way with a bus notifier.
-rw-r--r-- | arch/arm/mach-s3c2440/mach-gta02.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c index 4d6286ecf1b..f28fa8f3b15 100644 --- a/arch/arm/mach-s3c2440/mach-gta02.c +++ b/arch/arm/mach-s3c2440/mach-gta02.c @@ -754,6 +754,58 @@ static void gta02_poweroff(void) pcf50633_reg_set_bit_mask(gta02_pcf, PCF50633_REG_OOCSHDWN, 1, 1); } +struct gta02_device_children { + const char *dev_name; + size_t num_children; + struct platform_device **children; + void (*probed_callback)(struct device *dev); +}; + +static struct gta02_device_children gta02_device_children[] = { +}; + +static int gta02_add_child_devices(struct device *parent, + struct platform_device **children, + size_t num_children) +{ + size_t i; + + for (i = 0; i < num_children; ++i) + children[i]->dev.parent = parent; + + return platform_add_devices(children, num_children); +} + +static int gta02_device_registered(struct notifier_block *block, + unsigned long action, void *data) +{ + struct device *dev = data; + const char *devname = dev_name(dev); + size_t i; + + if (action != BUS_NOTIFY_BOUND_DRIVER) + return 0; + + for (i = 0; i < ARRAY_SIZE(gta02_device_children); ++i) { + if (strcmp(devname, gta02_device_children[i].dev_name) == 0) { + gta02_add_child_devices(dev, gta02_device_children[i].children, + gta02_device_children[i].num_children); + + if (gta02_device_children[i].probed_callback) + gta02_device_children[i].probed_callback(dev); + break; + } + } + + return 0; +} + +static struct notifier_block gta02_device_register_notifier = { + .notifier_call = gta02_device_registered, + .priority = INT_MAX, +}; + + /* On hardware rev 5 and earlier the leds are missing a resistor and reading * from their gpio pins will always return 0, so we have to shadow the * led states software */ @@ -841,6 +893,9 @@ static void __init gta02_machine_init(void) /* Set the panic callback to make AUX LED blink at ~5Hz. */ panic_blink = gta02_panic_blink; + bus_register_notifier(&platform_bus_type, >a02_device_register_notifier); + bus_register_notifier(&spi_bus_type, >a02_device_register_notifier); + gta02_hijack_gpb(); gta02_request_gpios(); |