linux/arch/powerpc/platforms/cell/cbe_powerbutton.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * driver for powerbutton on IBM cell blades
   4 *
   5 * (C) Copyright IBM Corp. 2005-2008
   6 *
   7 * Author: Christian Krafft <krafft@de.ibm.com>
   8 */
   9
  10#include <linux/input.h>
  11#include <linux/module.h>
  12#include <linux/platform_device.h>
  13#include <asm/pmi.h>
  14#include <asm/prom.h>
  15
  16static struct input_dev *button_dev;
  17static struct platform_device *button_pdev;
  18
  19static void cbe_powerbutton_handle_pmi(pmi_message_t pmi_msg)
  20{
  21        BUG_ON(pmi_msg.type != PMI_TYPE_POWER_BUTTON);
  22
  23        input_report_key(button_dev, KEY_POWER, 1);
  24        input_sync(button_dev);
  25        input_report_key(button_dev, KEY_POWER, 0);
  26        input_sync(button_dev);
  27}
  28
  29static struct pmi_handler cbe_pmi_handler = {
  30        .type                   = PMI_TYPE_POWER_BUTTON,
  31        .handle_pmi_message     = cbe_powerbutton_handle_pmi,
  32};
  33
  34static int __init cbe_powerbutton_init(void)
  35{
  36        int ret = 0;
  37        struct input_dev *dev;
  38
  39        if (!of_machine_is_compatible("IBM,CBPLUS-1.0")) {
  40                printk(KERN_ERR "%s: Not a cell blade.\n", __func__);
  41                ret = -ENODEV;
  42                goto out;
  43        }
  44
  45        dev = input_allocate_device();
  46        if (!dev) {
  47                ret = -ENOMEM;
  48                printk(KERN_ERR "%s: Not enough memory.\n", __func__);
  49                goto out;
  50        }
  51
  52        set_bit(EV_KEY, dev->evbit);
  53        set_bit(KEY_POWER, dev->keybit);
  54
  55        dev->name = "Power Button";
  56        dev->id.bustype = BUS_HOST;
  57
  58        /* this makes the button look like an acpi power button
  59         * no clue whether anyone relies on that though */
  60        dev->id.product = 0x02;
  61        dev->phys = "LNXPWRBN/button/input0";
  62
  63        button_pdev = platform_device_register_simple("power_button", 0, NULL, 0);
  64        if (IS_ERR(button_pdev)) {
  65                ret = PTR_ERR(button_pdev);
  66                goto out_free_input;
  67        }
  68
  69        dev->dev.parent = &button_pdev->dev;
  70        ret = input_register_device(dev);
  71        if (ret) {
  72                printk(KERN_ERR "%s: Failed to register device\n", __func__);
  73                goto out_free_pdev;
  74        }
  75
  76        button_dev = dev;
  77
  78        ret = pmi_register_handler(&cbe_pmi_handler);
  79        if (ret) {
  80                printk(KERN_ERR "%s: Failed to register with pmi.\n", __func__);
  81                goto out_free_pdev;
  82        }
  83
  84        goto out;
  85
  86out_free_pdev:
  87        platform_device_unregister(button_pdev);
  88out_free_input:
  89        input_free_device(dev);
  90out:
  91        return ret;
  92}
  93
  94static void __exit cbe_powerbutton_exit(void)
  95{
  96        pmi_unregister_handler(&cbe_pmi_handler);
  97        platform_device_unregister(button_pdev);
  98        input_free_device(button_dev);
  99}
 100
 101module_init(cbe_powerbutton_init);
 102module_exit(cbe_powerbutton_exit);
 103
 104MODULE_LICENSE("GPL");
 105MODULE_AUTHOR("Christian Krafft <krafft@de.ibm.com>");
 106