aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/serio/i8042.c')
-rw-r--r--drivers/input/serio/i8042.c54
1 files changed, 35 insertions, 19 deletions
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index c60593c8d2be..082afbf088d6 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -48,6 +48,10 @@ static bool i8042_unlock;
48module_param_named(unlock, i8042_unlock, bool, 0); 48module_param_named(unlock, i8042_unlock, bool, 0);
49MODULE_PARM_DESC(unlock, "Ignore keyboard lock."); 49MODULE_PARM_DESC(unlock, "Ignore keyboard lock.");
50 50
51static bool i8042_probe_defer;
52module_param_named(probe_defer, i8042_probe_defer, bool, 0);
53MODULE_PARM_DESC(probe_defer, "Allow deferred probing.");
54
51enum i8042_controller_reset_mode { 55enum i8042_controller_reset_mode {
52 I8042_RESET_NEVER, 56 I8042_RESET_NEVER,
53 I8042_RESET_ALWAYS, 57 I8042_RESET_ALWAYS,
@@ -702,7 +706,7 @@ static int i8042_set_mux_mode(bool multiplex, unsigned char *mux_version)
702 * LCS/Telegraphics. 706 * LCS/Telegraphics.
703 */ 707 */
704 708
705static int __init i8042_check_mux(void) 709static int i8042_check_mux(void)
706{ 710{
707 unsigned char mux_version; 711 unsigned char mux_version;
708 712
@@ -731,10 +735,10 @@ static int __init i8042_check_mux(void)
731/* 735/*
732 * The following is used to test AUX IRQ delivery. 736 * The following is used to test AUX IRQ delivery.
733 */ 737 */
734static struct completion i8042_aux_irq_delivered __initdata; 738static struct completion i8042_aux_irq_delivered;
735static bool i8042_irq_being_tested __initdata; 739static bool i8042_irq_being_tested;
736 740
737static irqreturn_t __init i8042_aux_test_irq(int irq, void *dev_id) 741static irqreturn_t i8042_aux_test_irq(int irq, void *dev_id)
738{ 742{
739 unsigned long flags; 743 unsigned long flags;
740 unsigned char str, data; 744 unsigned char str, data;
@@ -761,7 +765,7 @@ static irqreturn_t __init i8042_aux_test_irq(int irq, void *dev_id)
761 * verifies success by readinng CTR. Used when testing for presence of AUX 765 * verifies success by readinng CTR. Used when testing for presence of AUX
762 * port. 766 * port.
763 */ 767 */
764static int __init i8042_toggle_aux(bool on) 768static int i8042_toggle_aux(bool on)
765{ 769{
766 unsigned char param; 770 unsigned char param;
767 int i; 771 int i;
@@ -789,7 +793,7 @@ static int __init i8042_toggle_aux(bool on)
789 * the presence of an AUX interface. 793 * the presence of an AUX interface.
790 */ 794 */
791 795
792static int __init i8042_check_aux(void) 796static int i8042_check_aux(void)
793{ 797{
794 int retval = -1; 798 int retval = -1;
795 bool irq_registered = false; 799 bool irq_registered = false;
@@ -996,7 +1000,7 @@ static int i8042_controller_init(void)
996 1000
997 if (i8042_command(&ctr[n++ % 2], I8042_CMD_CTL_RCTR)) { 1001 if (i8042_command(&ctr[n++ % 2], I8042_CMD_CTL_RCTR)) {
998 pr_err("Can't read CTR while initializing i8042\n"); 1002 pr_err("Can't read CTR while initializing i8042\n");
999 return -EIO; 1003 return i8042_probe_defer ? -EPROBE_DEFER : -EIO;
1000 } 1004 }
1001 1005
1002 } while (n < 2 || ctr[0] != ctr[1]); 1006 } while (n < 2 || ctr[0] != ctr[1]);
@@ -1311,7 +1315,7 @@ static void i8042_shutdown(struct platform_device *dev)
1311 i8042_controller_reset(false); 1315 i8042_controller_reset(false);
1312} 1316}
1313 1317
1314static int __init i8042_create_kbd_port(void) 1318static int i8042_create_kbd_port(void)
1315{ 1319{
1316 struct serio *serio; 1320 struct serio *serio;
1317 struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO]; 1321 struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO];
@@ -1339,7 +1343,7 @@ static int __init i8042_create_kbd_port(void)
1339 return 0; 1343 return 0;
1340} 1344}
1341 1345
1342static int __init i8042_create_aux_port(int idx) 1346static int i8042_create_aux_port(int idx)
1343{ 1347{
1344 struct serio *serio; 1348 struct serio *serio;
1345 int port_no = idx < 0 ? I8042_AUX_PORT_NO : I8042_MUX_PORT_NO + idx; 1349 int port_no = idx < 0 ? I8042_AUX_PORT_NO : I8042_MUX_PORT_NO + idx;
@@ -1376,13 +1380,13 @@ static int __init i8042_create_aux_port(int idx)
1376 return 0; 1380 return 0;
1377} 1381}
1378 1382
1379static void __init i8042_free_kbd_port(void) 1383static void i8042_free_kbd_port(void)
1380{ 1384{
1381 kfree(i8042_ports[I8042_KBD_PORT_NO].serio); 1385 kfree(i8042_ports[I8042_KBD_PORT_NO].serio);
1382 i8042_ports[I8042_KBD_PORT_NO].serio = NULL; 1386 i8042_ports[I8042_KBD_PORT_NO].serio = NULL;
1383} 1387}
1384 1388
1385static void __init i8042_free_aux_ports(void) 1389static void i8042_free_aux_ports(void)
1386{ 1390{
1387 int i; 1391 int i;
1388 1392
@@ -1392,7 +1396,7 @@ static void __init i8042_free_aux_ports(void)
1392 } 1396 }
1393} 1397}
1394 1398
1395static void __init i8042_register_ports(void) 1399static void i8042_register_ports(void)
1396{ 1400{
1397 int i; 1401 int i;
1398 1402
@@ -1444,7 +1448,7 @@ static void i8042_free_irqs(void)
1444 i8042_aux_irq_registered = i8042_kbd_irq_registered = false; 1448 i8042_aux_irq_registered = i8042_kbd_irq_registered = false;
1445} 1449}
1446 1450
1447static int __init i8042_setup_aux(void) 1451static int i8042_setup_aux(void)
1448{ 1452{
1449 int (*aux_enable)(void); 1453 int (*aux_enable)(void);
1450 int error; 1454 int error;
@@ -1486,7 +1490,7 @@ static int __init i8042_setup_aux(void)
1486 return error; 1490 return error;
1487} 1491}
1488 1492
1489static int __init i8042_setup_kbd(void) 1493static int i8042_setup_kbd(void)
1490{ 1494{
1491 int error; 1495 int error;
1492 1496
@@ -1536,7 +1540,7 @@ static int i8042_kbd_bind_notifier(struct notifier_block *nb,
1536 return 0; 1540 return 0;
1537} 1541}
1538 1542
1539static int __init i8042_probe(struct platform_device *dev) 1543static int i8042_probe(struct platform_device *dev)
1540{ 1544{
1541 int error; 1545 int error;
1542 1546
@@ -1601,6 +1605,7 @@ static struct platform_driver i8042_driver = {
1601 .pm = &i8042_pm_ops, 1605 .pm = &i8042_pm_ops,
1602#endif 1606#endif
1603 }, 1607 },
1608 .probe = i8042_probe,
1604 .remove = i8042_remove, 1609 .remove = i8042_remove,
1605 .shutdown = i8042_shutdown, 1610 .shutdown = i8042_shutdown,
1606}; 1611};
@@ -1611,7 +1616,6 @@ static struct notifier_block i8042_kbd_bind_notifier_block = {
1611 1616
1612static int __init i8042_init(void) 1617static int __init i8042_init(void)
1613{ 1618{
1614 struct platform_device *pdev;
1615 int err; 1619 int err;
1616 1620
1617 dbg_init(); 1621 dbg_init();
@@ -1627,17 +1631,29 @@ static int __init i8042_init(void)
1627 /* Set this before creating the dev to allow i8042_command to work right away */ 1631 /* Set this before creating the dev to allow i8042_command to work right away */
1628 i8042_present = true; 1632 i8042_present = true;
1629 1633
1630 pdev = platform_create_bundle(&i8042_driver, i8042_probe, NULL, 0, NULL, 0); 1634 err = platform_driver_register(&i8042_driver);
1631 if (IS_ERR(pdev)) { 1635 if (err)
1632 err = PTR_ERR(pdev);
1633 goto err_platform_exit; 1636 goto err_platform_exit;
1637
1638 i8042_platform_device = platform_device_alloc("i8042", -1);
1639 if (!i8042_platform_device) {
1640 err = -ENOMEM;
1641 goto err_unregister_driver;
1634 } 1642 }
1635 1643
1644 err = platform_device_add(i8042_platform_device);
1645 if (err)
1646 goto err_free_device;
1647
1636 bus_register_notifier(&serio_bus, &i8042_kbd_bind_notifier_block); 1648 bus_register_notifier(&serio_bus, &i8042_kbd_bind_notifier_block);
1637 panic_blink = i8042_panic_blink; 1649 panic_blink = i8042_panic_blink;
1638 1650
1639 return 0; 1651 return 0;
1640 1652
1653err_free_device:
1654 platform_device_put(i8042_platform_device);
1655err_unregister_driver:
1656 platform_driver_unregister(&i8042_driver);
1641 err_platform_exit: 1657 err_platform_exit:
1642 i8042_platform_exit(); 1658 i8042_platform_exit();
1643 return err; 1659 return err;