1 /* 2 * driver for powerbutton on IBM cell blades 3 * 4 * (C) Copyright IBM Corp. 2005-2008 5 * 6 * Author: Christian Krafft <krafft@de.ibm.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2, or (at your option) 11 * any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 */ 22 23 #include <linux/input.h> 24 #include <linux/module.h> 25 #include <linux/platform_device.h> 26 #include <asm/pmi.h> 27 #include <asm/prom.h> 28 29 static struct input_dev *button_dev; 30 static struct platform_device *button_pdev; 31 32 static void cbe_powerbutton_handle_pmi(pmi_message_t pmi_msg) 33 { 34 BUG_ON(pmi_msg.type != PMI_TYPE_POWER_BUTTON); 35 36 input_report_key(button_dev, KEY_POWER, 1); 37 input_sync(button_dev); 38 input_report_key(button_dev, KEY_POWER, 0); 39 input_sync(button_dev); 40 } 41 42 static struct pmi_handler cbe_pmi_handler = { 43 .type = PMI_TYPE_POWER_BUTTON, 44 .handle_pmi_message = cbe_powerbutton_handle_pmi, 45 }; 46 47 static int __init cbe_powerbutton_init(void) 48 { 49 int ret = 0; 50 struct input_dev *dev; 51 52 if (!of_machine_is_compatible("IBM,CBPLUS-1.0")) { 53 printk(KERN_ERR "%s: Not a cell blade.\n", __func__); 54 ret = -ENODEV; 55 goto out; 56 } 57 58 dev = input_allocate_device(); 59 if (!dev) { 60 ret = -ENOMEM; 61 printk(KERN_ERR "%s: Not enough memory.\n", __func__); 62 goto out; 63 } 64 65 set_bit(EV_KEY, dev->evbit); 66 set_bit(KEY_POWER, dev->keybit); 67 68 dev->name = "Power Button"; 69 dev->id.bustype = BUS_HOST; 70 71 /* this makes the button look like an acpi power button 72 * no clue whether anyone relies on that though */ 73 dev->id.product = 0x02; 74 dev->phys = "LNXPWRBN/button/input0"; 75 76 button_pdev = platform_device_register_simple("power_button", 0, NULL, 0); 77 if (IS_ERR(button_pdev)) { 78 ret = PTR_ERR(button_pdev); 79 goto out_free_input; 80 } 81 82 dev->dev.parent = &button_pdev->dev; 83 ret = input_register_device(dev); 84 if (ret) { 85 printk(KERN_ERR "%s: Failed to register device\n", __func__); 86 goto out_free_pdev; 87 } 88 89 button_dev = dev; 90 91 ret = pmi_register_handler(&cbe_pmi_handler); 92 if (ret) { 93 printk(KERN_ERR "%s: Failed to register with pmi.\n", __func__); 94 goto out_free_pdev; 95 } 96 97 goto out; 98 99 out_free_pdev: 100 platform_device_unregister(button_pdev); 101 out_free_input: 102 input_free_device(dev); 103 out: 104 return ret; 105 } 106 107 static void __exit cbe_powerbutton_exit(void) 108 { 109 pmi_unregister_handler(&cbe_pmi_handler); 110 platform_device_unregister(button_pdev); 111 input_free_device(button_dev); 112 } 113 114 module_init(cbe_powerbutton_init); 115 module_exit(cbe_powerbutton_exit); 116 117 MODULE_LICENSE("GPL"); 118 MODULE_AUTHOR("Christian Krafft <krafft@de.ibm.com>"); 119