Skip to content

Commit

Permalink
powerpc/cell: Add support for power button of future IBM cell blades
Browse files Browse the repository at this point in the history
This patch adds support for the power button on future IBM cell blades.
It actually doesn't shut down the machine. Instead it exposes an
input device /dev/input/event0 to userspace which sends KEY_POWER
if power button has been pressed.
haldaemon actually recognizes the button, so a plattform independent acpid
replacement should handle it correctly.

Signed-off-by: Christian Krafft <krafft@de.ibm.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
  • Loading branch information
Christian Krafft authored and Benjamin Herrenschmidt committed Jul 22, 2008
1 parent 70694a8 commit 4795b78
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 0 deletions.
8 changes: 8 additions & 0 deletions arch/powerpc/platforms/cell/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@ config PPC_IBM_CELL_RESETBUTTON
Support Pinhole Resetbutton on IBM Cell blades.
This adds a method to trigger system reset via front panel pinhole button.

config PPC_IBM_CELL_POWERBUTTON
tristate "IBM Cell Blade power button"
depends on PPC_IBM_CELL_BLADE && PPC_PMI && INPUT_EVDEV
default y
help
Support Powerbutton on IBM Cell blades.
This will enable the powerbutton as an input device.

config CBE_THERM
tristate "CBE thermal support"
default m
Expand Down
2 changes: 2 additions & 0 deletions arch/powerpc/platforms/cell/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ obj-$(CONFIG_CBE_CPUFREQ) += cbe-cpufreq.o
cbe-cpufreq-y += cbe_cpufreq_pervasive.o cbe_cpufreq.o
obj-$(CONFIG_CBE_CPUFREQ_SPU_GOVERNOR) += cpufreq_spudemand.o

obj-$(CONFIG_PPC_IBM_CELL_POWERBUTTON) += cbe_powerbutton.o

ifeq ($(CONFIG_SMP),y)
obj-$(CONFIG_PPC_CELL_NATIVE) += smp.o
endif
Expand Down
117 changes: 117 additions & 0 deletions arch/powerpc/platforms/cell/cbe_powerbutton.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* driver for powerbutton on IBM cell blades
*
* (C) Copyright IBM Corp. 2005-2008
*
* Author: Christian Krafft <krafft@de.ibm.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <linux/input.h>
#include <linux/platform_device.h>
#include <asm/pmi.h>
#include <asm/prom.h>

static struct input_dev *button_dev;
static struct platform_device *button_pdev;

static void cbe_powerbutton_handle_pmi(pmi_message_t pmi_msg)
{
BUG_ON(pmi_msg.type != PMI_TYPE_POWER_BUTTON);

input_report_key(button_dev, KEY_POWER, 1);
input_sync(button_dev);
input_report_key(button_dev, KEY_POWER, 0);
input_sync(button_dev);
}

static struct pmi_handler cbe_pmi_handler = {
.type = PMI_TYPE_POWER_BUTTON,
.handle_pmi_message = cbe_powerbutton_handle_pmi,
};

static int __init cbe_powerbutton_init(void)
{
int ret = 0;
struct input_dev *dev;

if (!machine_is_compatible("IBM,CBPLUS-1.0")) {
printk(KERN_ERR "%s: Not a cell blade.\n", __func__);
ret = -ENODEV;
goto out;
}

dev = input_allocate_device();
if (!dev) {
ret = -ENOMEM;
printk(KERN_ERR "%s: Not enough memory.\n", __func__);
goto out;
}

set_bit(EV_KEY, dev->evbit);
set_bit(KEY_POWER, dev->keybit);

dev->name = "Power Button";
dev->id.bustype = BUS_HOST;

/* this makes the button look like an acpi power button
* no clue whether anyone relies on that though */
dev->id.product = 0x02;
dev->phys = "LNXPWRBN/button/input0";

button_pdev = platform_device_register_simple("power_button", 0, NULL, 0);
if (IS_ERR(button_pdev)) {
ret = PTR_ERR(button_pdev);
goto out_free_input;
}

dev->dev.parent = &button_pdev->dev;
ret = input_register_device(dev);
if (ret) {
printk(KERN_ERR "%s: Failed to register device\n", __func__);
goto out_free_pdev;
}

button_dev = dev;

ret = pmi_register_handler(&cbe_pmi_handler);
if (ret) {
printk(KERN_ERR "%s: Failed to register with pmi.\n", __func__);
goto out_free_pdev;
}

goto out;

out_free_pdev:
platform_device_unregister(button_pdev);
out_free_input:
input_free_device(dev);
out:
return ret;
}

static void __exit cbe_powerbutton_exit(void)
{
pmi_unregister_handler(&cbe_pmi_handler);
platform_device_unregister(button_pdev);
input_free_device(button_dev);
}

module_init(cbe_powerbutton_init);
module_exit(cbe_powerbutton_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Christian Krafft <krafft@de.ibm.com>");
1 change: 1 addition & 0 deletions include/asm-powerpc/pmi.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#ifdef __KERNEL__

#define PMI_TYPE_FREQ_CHANGE 0x01
#define PMI_TYPE_POWER_BUTTON 0x02
#define PMI_READ_TYPE 0
#define PMI_READ_DATA0 1
#define PMI_READ_DATA1 2
Expand Down

0 comments on commit 4795b78

Please sign in to comment.