module_param_named(unlock, i8042_unlock, bool, 0);
 MODULE_PARM_DESC(unlock, "Ignore keyboard lock.");
 
+static bool i8042_probe_defer;
+module_param_named(probe_defer, i8042_probe_defer, bool, 0);
+MODULE_PARM_DESC(probe_defer, "Allow deferred probing.");
+
 enum i8042_controller_reset_mode {
        I8042_RESET_NEVER,
        I8042_RESET_ALWAYS,
  * LCS/Telegraphics.
  */
 
-static int __init i8042_check_mux(void)
+static int i8042_check_mux(void)
 {
        unsigned char mux_version;
 
 /*
  * The following is used to test AUX IRQ delivery.
  */
-static struct completion i8042_aux_irq_delivered __initdata;
-static bool i8042_irq_being_tested __initdata;
+static struct completion i8042_aux_irq_delivered;
+static bool i8042_irq_being_tested;
 
-static irqreturn_t __init i8042_aux_test_irq(int irq, void *dev_id)
+static irqreturn_t i8042_aux_test_irq(int irq, void *dev_id)
 {
        unsigned long flags;
        unsigned char str, data;
  * verifies success by readinng CTR. Used when testing for presence of AUX
  * port.
  */
-static int __init i8042_toggle_aux(bool on)
+static int i8042_toggle_aux(bool on)
 {
        unsigned char param;
        int i;
  * the presence of an AUX interface.
  */
 
-static int __init i8042_check_aux(void)
+static int i8042_check_aux(void)
 {
        int retval = -1;
        bool irq_registered = false;
 
                if (i8042_command(&ctr[n++ % 2], I8042_CMD_CTL_RCTR)) {
                        pr_err("Can't read CTR while initializing i8042\n");
-                       return -EIO;
+                       return i8042_probe_defer ? -EPROBE_DEFER : -EIO;
                }
 
        } while (n < 2 || ctr[0] != ctr[1]);
        i8042_controller_reset(false);
 }
 
-static int __init i8042_create_kbd_port(void)
+static int i8042_create_kbd_port(void)
 {
        struct serio *serio;
        struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO];
        return 0;
 }
 
-static int __init i8042_create_aux_port(int idx)
+static int i8042_create_aux_port(int idx)
 {
        struct serio *serio;
        int port_no = idx < 0 ? I8042_AUX_PORT_NO : I8042_MUX_PORT_NO + idx;
        return 0;
 }
 
-static void __init i8042_free_kbd_port(void)
+static void i8042_free_kbd_port(void)
 {
        kfree(i8042_ports[I8042_KBD_PORT_NO].serio);
        i8042_ports[I8042_KBD_PORT_NO].serio = NULL;
 }
 
-static void __init i8042_free_aux_ports(void)
+static void i8042_free_aux_ports(void)
 {
        int i;
 
        }
 }
 
-static void __init i8042_register_ports(void)
+static void i8042_register_ports(void)
 {
        int i;
 
        i8042_aux_irq_registered = i8042_kbd_irq_registered = false;
 }
 
-static int __init i8042_setup_aux(void)
+static int i8042_setup_aux(void)
 {
        int (*aux_enable)(void);
        int error;
        return error;
 }
 
-static int __init i8042_setup_kbd(void)
+static int i8042_setup_kbd(void)
 {
        int error;
 
        return 0;
 }
 
-static int __init i8042_probe(struct platform_device *dev)
+static int i8042_probe(struct platform_device *dev)
 {
        int error;
 
                .pm     = &i8042_pm_ops,
 #endif
        },
+       .probe          = i8042_probe,
        .remove         = i8042_remove,
        .shutdown       = i8042_shutdown,
 };
 
 static int __init i8042_init(void)
 {
-       struct platform_device *pdev;
        int err;
 
        dbg_init();
        /* Set this before creating the dev to allow i8042_command to work right away */
        i8042_present = true;
 
-       pdev = platform_create_bundle(&i8042_driver, i8042_probe, NULL, 0, NULL, 0);
-       if (IS_ERR(pdev)) {
-               err = PTR_ERR(pdev);
+       err = platform_driver_register(&i8042_driver);
+       if (err)
                goto err_platform_exit;
+
+       i8042_platform_device = platform_device_alloc("i8042", -1);
+       if (!i8042_platform_device) {
+               err = -ENOMEM;
+               goto err_unregister_driver;
        }
 
+       err = platform_device_add(i8042_platform_device);
+       if (err)
+               goto err_free_device;
+
        bus_register_notifier(&serio_bus, &i8042_kbd_bind_notifier_block);
        panic_blink = i8042_panic_blink;
 
        return 0;
 
+err_free_device:
+       platform_device_put(i8042_platform_device);
+err_unregister_driver:
+       platform_driver_unregister(&i8042_driver);
  err_platform_exit:
        i8042_platform_exit();
        return err;