diff options
Diffstat (limited to 'drivers/platform/x86/panasonic-laptop.c')
| -rw-r--r-- | drivers/platform/x86/panasonic-laptop.c | 73 |
1 files changed, 32 insertions, 41 deletions
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index cc1e0ba104d..3f870972247 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c @@ -125,12 +125,10 @@ #include <linux/seq_file.h> #include <linux/uaccess.h> #include <linux/slab.h> -#include <acpi/acpi_bus.h> -#include <acpi/acpi_drivers.h> +#include <linux/acpi.h> #include <linux/input.h> #include <linux/input/sparse-keymap.h> - #ifndef ACPI_HOTKEY_COMPONENT #define ACPI_HOTKEY_COMPONENT 0x10000000 #endif @@ -176,8 +174,7 @@ enum SINF_BITS { SINF_NUM_BATTERIES = 0, /* R1 handles SINF_AC_CUR_BRIGHT as SINF_CUR_BRIGHT, doesn't know AC state */ static int acpi_pcc_hotkey_add(struct acpi_device *device); -static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type); -static int acpi_pcc_hotkey_resume(struct acpi_device *device); +static int acpi_pcc_hotkey_remove(struct acpi_device *device); static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event); static const struct acpi_device_id pcc_device_ids[] = { @@ -189,6 +186,11 @@ static const struct acpi_device_id pcc_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, pcc_device_ids); +#ifdef CONFIG_PM_SLEEP +static int acpi_pcc_hotkey_resume(struct device *dev); +#endif +static SIMPLE_DEV_PM_OPS(acpi_pcc_hotkey_pm, NULL, acpi_pcc_hotkey_resume); + static struct acpi_driver acpi_pcc_driver = { .name = ACPI_PCC_DRIVER_NAME, .class = ACPI_PCC_CLASS, @@ -196,9 +198,9 @@ static struct acpi_driver acpi_pcc_driver = { .ops = { .add = acpi_pcc_hotkey_add, .remove = acpi_pcc_hotkey_remove, - .resume = acpi_pcc_hotkey_resume, .notify = acpi_pcc_hotkey_notify, }, + .drv.pm = &acpi_pcc_hotkey_pm, }; static const struct key_entry panasonic_keymap[] = { @@ -447,6 +449,7 @@ static struct attribute_group pcc_attr_group = { /* hotkey input device driver */ +static int sleep_keydown_seen; static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc) { struct input_dev *hotk_input_dev = pcc->input_dev; @@ -461,7 +464,14 @@ static void acpi_pcc_generate_keyinput(struct pcc_acpi *pcc) return; } - acpi_bus_generate_proc_event(pcc->device, HKEY_NOTIFY, result); + /* hack: some firmware sends no key down for sleep / hibernate */ + if ((result & 0xf) == 0x7 || (result & 0xf) == 0xa) { + if (result & 0x80) + sleep_keydown_seen = 1; + if (!sleep_keydown_seen) + sparse_keymap_report_event(hotk_input_dev, + result & 0xf, 0x80, false); + } if (!sparse_keymap_report_event(hotk_input_dev, result & 0xf, result & 0x80, false)) @@ -489,11 +499,8 @@ static int acpi_pcc_init_input(struct pcc_acpi *pcc) int error; input_dev = input_allocate_device(); - if (!input_dev) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Couldn't allocate input device for hotkey")); + if (!input_dev) return -ENOMEM; - } input_dev->name = ACPI_PCC_DRIVER_NAME; input_dev->phys = ACPI_PCC_INPUT_PHYS; @@ -538,11 +545,16 @@ static void acpi_pcc_destroy_input(struct pcc_acpi *pcc) /* kernel module interface */ -static int acpi_pcc_hotkey_resume(struct acpi_device *device) +#ifdef CONFIG_PM_SLEEP +static int acpi_pcc_hotkey_resume(struct device *dev) { - struct pcc_acpi *pcc = acpi_driver_data(device); + struct pcc_acpi *pcc; + + if (!dev) + return -EINVAL; - if (device == NULL || pcc == NULL) + pcc = acpi_driver_data(to_acpi_device(dev)); + if (!pcc) return -EINVAL; ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Sticky mode restore: %d\n", @@ -550,6 +562,7 @@ static int acpi_pcc_hotkey_resume(struct acpi_device *device) return acpi_pcc_write_sset(pcc, SINF_STICKY_KEY, pcc->sticky_mode); } +#endif static int acpi_pcc_hotkey_add(struct acpi_device *device) { @@ -562,8 +575,8 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) num_sifr = acpi_pcc_get_sqty(device); - if (num_sifr > 255) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "num_sifr too large")); + if (num_sifr < 0 || num_sifr > 255) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "num_sifr out of range")); return -ENODEV; } @@ -602,6 +615,7 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) } /* initialize backlight */ memset(&props, 0, sizeof(struct backlight_properties)); + props.type = BACKLIGHT_PLATFORM; props.max_brightness = pcc->sinf[SINF_AC_MAX_BRIGHT]; pcc->backlight = backlight_device_register("panasonic", NULL, pcc, &pcc_backlight_ops, &props); @@ -635,24 +649,7 @@ out_hotkey: return result; } -static int __init acpi_pcc_init(void) -{ - int result = 0; - - if (acpi_disabled) - return -ENODEV; - - result = acpi_bus_register_driver(&acpi_pcc_driver); - if (result < 0) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error registering hotkey driver\n")); - return -ENODEV; - } - - return 0; -} - -static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type) +static int acpi_pcc_hotkey_remove(struct acpi_device *device) { struct pcc_acpi *pcc = acpi_driver_data(device); @@ -671,10 +668,4 @@ static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type) return 0; } -static void __exit acpi_pcc_exit(void) -{ - acpi_bus_unregister_driver(&acpi_pcc_driver); -} - -module_init(acpi_pcc_init); -module_exit(acpi_pcc_exit); +module_acpi_driver(acpi_pcc_driver); |
