aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2010-04-04 20:37:28 +0200
committerLars-Peter Clausen <lars@metafoo.de>2010-05-17 20:59:37 +0200
commitb27e3d74ea6afd91cd4763bca94cd19f4bedb5fc (patch)
tree4af6e71840fb7275c60d20b621389e225df4801f
parente46f39af3ced84382ec61fd0ca2d23d444331292 (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.c55
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, &gta02_device_register_notifier);
+ bus_register_notifier(&spi_bus_type, &gta02_device_register_notifier);
+
gta02_hijack_gpb();
gta02_request_gpios();