@@ -45,6 +45,10 @@ static bool i8042_unlock;
4545module_param_named (unlock , i8042_unlock , bool , 0 );
4646MODULE_PARM_DESC (unlock , "Ignore keyboard lock." );
4747
48+ static bool i8042_probe_defer ;
49+ module_param_named (probe_defer , i8042_probe_defer , bool , 0 );
50+ MODULE_PARM_DESC (probe_defer , "Allow deferred probing." );
51+
4852enum i8042_controller_reset_mode {
4953 I8042_RESET_NEVER ,
5054 I8042_RESET_ALWAYS ,
@@ -711,7 +715,7 @@ static int i8042_set_mux_mode(bool multiplex, unsigned char *mux_version)
711715 * LCS/Telegraphics.
712716 */
713717
714- static int __init i8042_check_mux (void )
718+ static int i8042_check_mux (void )
715719{
716720 unsigned char mux_version ;
717721
@@ -740,10 +744,10 @@ static int __init i8042_check_mux(void)
740744/*
741745 * The following is used to test AUX IRQ delivery.
742746 */
743- static struct completion i8042_aux_irq_delivered __initdata ;
744- static bool i8042_irq_being_tested __initdata ;
747+ static struct completion i8042_aux_irq_delivered ;
748+ static bool i8042_irq_being_tested ;
745749
746- static irqreturn_t __init i8042_aux_test_irq (int irq , void * dev_id )
750+ static irqreturn_t i8042_aux_test_irq (int irq , void * dev_id )
747751{
748752 unsigned long flags ;
749753 unsigned char str , data ;
@@ -770,7 +774,7 @@ static irqreturn_t __init i8042_aux_test_irq(int irq, void *dev_id)
770774 * verifies success by readinng CTR. Used when testing for presence of AUX
771775 * port.
772776 */
773- static int __init i8042_toggle_aux (bool on )
777+ static int i8042_toggle_aux (bool on )
774778{
775779 unsigned char param ;
776780 int i ;
@@ -798,7 +802,7 @@ static int __init i8042_toggle_aux(bool on)
798802 * the presence of an AUX interface.
799803 */
800804
801- static int __init i8042_check_aux (void )
805+ static int i8042_check_aux (void )
802806{
803807 int retval = -1 ;
804808 bool irq_registered = false;
@@ -1005,7 +1009,7 @@ static int i8042_controller_init(void)
10051009
10061010 if (i8042_command (& ctr [n ++ % 2 ], I8042_CMD_CTL_RCTR )) {
10071011 pr_err ("Can't read CTR while initializing i8042\n" );
1008- return - EIO ;
1012+ return i8042_probe_defer ? - EPROBE_DEFER : - EIO ;
10091013 }
10101014
10111015 } while (n < 2 || ctr [0 ] != ctr [1 ]);
@@ -1320,7 +1324,7 @@ static void i8042_shutdown(struct platform_device *dev)
13201324 i8042_controller_reset (false);
13211325}
13221326
1323- static int __init i8042_create_kbd_port (void )
1327+ static int i8042_create_kbd_port (void )
13241328{
13251329 struct serio * serio ;
13261330 struct i8042_port * port = & i8042_ports [I8042_KBD_PORT_NO ];
@@ -1349,7 +1353,7 @@ static int __init i8042_create_kbd_port(void)
13491353 return 0 ;
13501354}
13511355
1352- static int __init i8042_create_aux_port (int idx )
1356+ static int i8042_create_aux_port (int idx )
13531357{
13541358 struct serio * serio ;
13551359 int port_no = idx < 0 ? I8042_AUX_PORT_NO : I8042_MUX_PORT_NO + idx ;
@@ -1386,13 +1390,13 @@ static int __init i8042_create_aux_port(int idx)
13861390 return 0 ;
13871391}
13881392
1389- static void __init i8042_free_kbd_port (void )
1393+ static void i8042_free_kbd_port (void )
13901394{
13911395 kfree (i8042_ports [I8042_KBD_PORT_NO ].serio );
13921396 i8042_ports [I8042_KBD_PORT_NO ].serio = NULL ;
13931397}
13941398
1395- static void __init i8042_free_aux_ports (void )
1399+ static void i8042_free_aux_ports (void )
13961400{
13971401 int i ;
13981402
@@ -1402,7 +1406,7 @@ static void __init i8042_free_aux_ports(void)
14021406 }
14031407}
14041408
1405- static void __init i8042_register_ports (void )
1409+ static void i8042_register_ports (void )
14061410{
14071411 int i ;
14081412
@@ -1443,7 +1447,7 @@ static void i8042_free_irqs(void)
14431447 i8042_aux_irq_registered = i8042_kbd_irq_registered = false;
14441448}
14451449
1446- static int __init i8042_setup_aux (void )
1450+ static int i8042_setup_aux (void )
14471451{
14481452 int (* aux_enable )(void );
14491453 int error ;
@@ -1485,7 +1489,7 @@ static int __init i8042_setup_aux(void)
14851489 return error ;
14861490}
14871491
1488- static int __init i8042_setup_kbd (void )
1492+ static int i8042_setup_kbd (void )
14891493{
14901494 int error ;
14911495
@@ -1535,7 +1539,7 @@ static int i8042_kbd_bind_notifier(struct notifier_block *nb,
15351539 return 0 ;
15361540}
15371541
1538- static int __init i8042_probe (struct platform_device * dev )
1542+ static int i8042_probe (struct platform_device * dev )
15391543{
15401544 int error ;
15411545
@@ -1600,6 +1604,7 @@ static struct platform_driver i8042_driver = {
16001604 .pm = & i8042_pm_ops ,
16011605#endif
16021606 },
1607+ .probe = i8042_probe ,
16031608 .remove = i8042_remove ,
16041609 .shutdown = i8042_shutdown ,
16051610};
@@ -1610,7 +1615,6 @@ static struct notifier_block i8042_kbd_bind_notifier_block = {
16101615
16111616static int __init i8042_init (void )
16121617{
1613- struct platform_device * pdev ;
16141618 int err ;
16151619
16161620 dbg_init ();
@@ -1626,17 +1630,29 @@ static int __init i8042_init(void)
16261630 /* Set this before creating the dev to allow i8042_command to work right away */
16271631 i8042_present = true;
16281632
1629- pdev = platform_create_bundle (& i8042_driver , i8042_probe , NULL , 0 , NULL , 0 );
1630- if (IS_ERR (pdev )) {
1631- err = PTR_ERR (pdev );
1633+ err = platform_driver_register (& i8042_driver );
1634+ if (err )
16321635 goto err_platform_exit ;
1636+
1637+ i8042_platform_device = platform_device_alloc ("i8042" , -1 );
1638+ if (!i8042_platform_device ) {
1639+ err = - ENOMEM ;
1640+ goto err_unregister_driver ;
16331641 }
16341642
1643+ err = platform_device_add (i8042_platform_device );
1644+ if (err )
1645+ goto err_free_device ;
1646+
16351647 bus_register_notifier (& serio_bus , & i8042_kbd_bind_notifier_block );
16361648 panic_blink = i8042_panic_blink ;
16371649
16381650 return 0 ;
16391651
1652+ err_free_device :
1653+ platform_device_put (i8042_platform_device );
1654+ err_unregister_driver :
1655+ platform_driver_unregister (& i8042_driver );
16401656 err_platform_exit :
16411657 i8042_platform_exit ();
16421658 return err ;
0 commit comments