Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * driver for powerbutton on IBM cell blades
0004  *
0005  * (C) Copyright IBM Corp. 2005-2008
0006  *
0007  * Author: Christian Krafft <krafft@de.ibm.com>
0008  */
0009 
0010 #include <linux/input.h>
0011 #include <linux/module.h>
0012 #include <linux/of.h>
0013 #include <linux/platform_device.h>
0014 #include <asm/pmi.h>
0015 
0016 static struct input_dev *button_dev;
0017 static struct platform_device *button_pdev;
0018 
0019 static void cbe_powerbutton_handle_pmi(pmi_message_t pmi_msg)
0020 {
0021     BUG_ON(pmi_msg.type != PMI_TYPE_POWER_BUTTON);
0022 
0023     input_report_key(button_dev, KEY_POWER, 1);
0024     input_sync(button_dev);
0025     input_report_key(button_dev, KEY_POWER, 0);
0026     input_sync(button_dev);
0027 }
0028 
0029 static struct pmi_handler cbe_pmi_handler = {
0030     .type           = PMI_TYPE_POWER_BUTTON,
0031     .handle_pmi_message = cbe_powerbutton_handle_pmi,
0032 };
0033 
0034 static int __init cbe_powerbutton_init(void)
0035 {
0036     int ret = 0;
0037     struct input_dev *dev;
0038 
0039     if (!of_machine_is_compatible("IBM,CBPLUS-1.0")) {
0040         printk(KERN_ERR "%s: Not a cell blade.\n", __func__);
0041         ret = -ENODEV;
0042         goto out;
0043     }
0044 
0045     dev = input_allocate_device();
0046     if (!dev) {
0047         ret = -ENOMEM;
0048         printk(KERN_ERR "%s: Not enough memory.\n", __func__);
0049         goto out;
0050     }
0051 
0052     set_bit(EV_KEY, dev->evbit);
0053     set_bit(KEY_POWER, dev->keybit);
0054 
0055     dev->name = "Power Button";
0056     dev->id.bustype = BUS_HOST;
0057 
0058     /* this makes the button look like an acpi power button
0059      * no clue whether anyone relies on that though */
0060     dev->id.product = 0x02;
0061     dev->phys = "LNXPWRBN/button/input0";
0062 
0063     button_pdev = platform_device_register_simple("power_button", 0, NULL, 0);
0064     if (IS_ERR(button_pdev)) {
0065         ret = PTR_ERR(button_pdev);
0066         goto out_free_input;
0067     }
0068 
0069     dev->dev.parent = &button_pdev->dev;
0070     ret = input_register_device(dev);
0071     if (ret) {
0072         printk(KERN_ERR "%s: Failed to register device\n", __func__);
0073         goto out_free_pdev;
0074     }
0075 
0076     button_dev = dev;
0077 
0078     ret = pmi_register_handler(&cbe_pmi_handler);
0079     if (ret) {
0080         printk(KERN_ERR "%s: Failed to register with pmi.\n", __func__);
0081         goto out_free_pdev;
0082     }
0083 
0084     goto out;
0085 
0086 out_free_pdev:
0087     platform_device_unregister(button_pdev);
0088 out_free_input:
0089     input_free_device(dev);
0090 out:
0091     return ret;
0092 }
0093 
0094 static void __exit cbe_powerbutton_exit(void)
0095 {
0096     pmi_unregister_handler(&cbe_pmi_handler);
0097     platform_device_unregister(button_pdev);
0098     input_free_device(button_dev);
0099 }
0100 
0101 module_init(cbe_powerbutton_init);
0102 module_exit(cbe_powerbutton_exit);
0103 
0104 MODULE_LICENSE("GPL");
0105 MODULE_AUTHOR("Christian Krafft <krafft@de.ibm.com>");