gta02: Add notify handler to probe device children
authorLars-Peter Clausen <lars@metafoo.de>
Sun, 4 Apr 2010 18:37:28 +0000 (20:37 +0200)
committerLars-Peter Clausen <lars@metafoo.de>
Mon, 17 May 2010 18:59:37 +0000 (20:59 +0200)
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.

arch/arm/mach-s3c2440/mach-gta02.c

index 4d6286e..f28fa8f 100644 (file)
@@ -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();