diff options
Diffstat (limited to 'drivers/platform')
26 files changed, 450 insertions, 831 deletions
diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig index 09fde58..69616ae 100644 --- a/drivers/platform/Kconfig +++ b/drivers/platform/Kconfig @@ -5,4 +5,3 @@ if GOLDFISH source "drivers/platform/goldfish/Kconfig" endif -source "drivers/platform/chrome/Kconfig" diff --git a/drivers/platform/Makefile b/drivers/platform/Makefile index 3656b7b..8a44a4c 100644 --- a/drivers/platform/Makefile +++ b/drivers/platform/Makefile @@ -5,4 +5,3 @@ obj-$(CONFIG_X86) += x86/ obj-$(CONFIG_OLPC) += olpc/ obj-$(CONFIG_GOLDFISH) += goldfish/ -obj-$(CONFIG_CHROME_PLATFORMS) += chrome/ diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig deleted file mode 100644 index b13303e..0000000 --- a/drivers/platform/chrome/Kconfig +++ /dev/null @@ -1,28 +0,0 @@ -# -# Platform support for Chrome OS hardware (Chromebooks and Chromeboxes) -# - -menuconfig CHROME_PLATFORMS - bool "Platform support for Chrome hardware" - depends on X86 - ---help--- - Say Y here to get to see options for platform support for - various Chromebooks and Chromeboxes. This option alone does - not add any kernel code. - - If you say N, all options in this submenu will be skipped and disabled. - -if CHROME_PLATFORMS - -config CHROMEOS_LAPTOP - tristate "Chrome OS Laptop" - depends on I2C - depends on DMI - ---help--- - This driver instantiates i2c and smbus devices such as - light sensors and touchpads. - - If you have a supported Chromebook, choose Y or M here. - The module will be called chromeos_laptop. - -endif # CHROMEOS_PLATFORMS diff --git a/drivers/platform/chrome/Makefile b/drivers/platform/chrome/Makefile deleted file mode 100644 index 015e919..0000000 --- a/drivers/platform/chrome/Makefile +++ /dev/null @@ -1,2 +0,0 @@ - -obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index d9dcd37..b51a746 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -79,6 +79,17 @@ config ASUS_LAPTOP If you have an ACPI-compatible ASUS laptop, say Y or M here. +config CHROMEOS_LAPTOP + tristate "Chrome OS Laptop" + depends on I2C + depends on DMI + ---help--- + This driver instantiates i2c and smbus devices such as + light sensors and touchpads. + + If you have a supported Chromebook, choose Y or M here. + The module will be called chromeos_laptop. + config DELL_LAPTOP tristate "Dell Laptop Extras" depends on X86 diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index f0e6aa4..5dbe193 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -50,6 +50,7 @@ obj-$(CONFIG_INTEL_MID_POWER_BUTTON) += intel_mid_powerbtn.o obj-$(CONFIG_INTEL_OAKTRAIL) += intel_oaktrail.o obj-$(CONFIG_SAMSUNG_Q10) += samsung-q10.o obj-$(CONFIG_APPLE_GMUX) += apple-gmux.o +obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o obj-$(CONFIG_INTEL_RST) += intel-rst.o obj-$(CONFIG_INTEL_SMARTCONNECT) += intel-smartconnect.o diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c index b9429fb..8eea2ef 100644 --- a/drivers/platform/x86/apple-gmux.c +++ b/drivers/platform/x86/apple-gmux.c @@ -289,7 +289,7 @@ static int gmux_switchto(enum vga_switcheroo_client_id id) static int gmux_set_discrete_state(struct apple_gmux_data *gmux_data, enum vga_switcheroo_state state) { - reinit_completion(&gmux_data->powerchange_done); + INIT_COMPLETION(gmux_data->powerchange_done); if (state == VGA_SWITCHEROO_ON) { gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 1); @@ -519,7 +519,7 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) gmux_data->power_state = VGA_SWITCHEROO_ON; - gmux_data->dhandle = ACPI_HANDLE(&pnp->dev); + gmux_data->dhandle = DEVICE_ACPI_HANDLE(&pnp->dev); if (!gmux_data->dhandle) { pr_err("Cannot find acpi handle for pnp device %s\n", dev_name(&pnp->dev)); diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 594323a..0e9c169 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -1494,9 +1494,10 @@ static int asus_input_init(struct asus_laptop *asus) int error; input = input_allocate_device(); - if (!input) + if (!input) { + pr_warn("Unable to allocate input device\n"); return -ENOMEM; - + } input->name = "Asus Laptop extra buttons"; input->phys = ASUS_LAPTOP_FILE "/input0"; input->id.bustype = BUS_HOST; diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/x86/chromeos_laptop.c index 3e5b4497..3e5b4497 100644 --- a/drivers/platform/chrome/chromeos_laptop.c +++ b/drivers/platform/x86/chromeos_laptop.c diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index c608b1d..bb77e18 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -21,7 +21,6 @@ #include <linux/err.h> #include <linux/dmi.h> #include <linux/io.h> -#include <linux/rfkill.h> #include <linux/power_supply.h> #include <linux/acpi.h> #include <linux/mm.h> @@ -90,13 +89,6 @@ static struct platform_driver platform_driver = { static struct platform_device *platform_device; static struct backlight_device *dell_backlight_device; -static struct rfkill *wifi_rfkill; -static struct rfkill *bluetooth_rfkill; -static struct rfkill *wwan_rfkill; -static bool force_rfkill; - -module_param(force_rfkill, bool, 0444); -MODULE_PARM_DESC(force_rfkill, "enable rfkill on non whitelisted models"); static const struct dmi_system_id dell_device_table[] __initconst = { { @@ -363,108 +355,6 @@ dell_send_request(struct calling_interface_buffer *buffer, int class, return buffer; } -/* Derived from information in DellWirelessCtl.cpp: - Class 17, select 11 is radio control. It returns an array of 32-bit values. - - Input byte 0 = 0: Wireless information - - result[0]: return code - result[1]: - Bit 0: Hardware switch supported - Bit 1: Wifi locator supported - Bit 2: Wifi is supported - Bit 3: Bluetooth is supported - Bit 4: WWAN is supported - Bit 5: Wireless keyboard supported - Bits 6-7: Reserved - Bit 8: Wifi is installed - Bit 9: Bluetooth is installed - Bit 10: WWAN is installed - Bits 11-15: Reserved - Bit 16: Hardware switch is on - Bit 17: Wifi is blocked - Bit 18: Bluetooth is blocked - Bit 19: WWAN is blocked - Bits 20-31: Reserved - result[2]: NVRAM size in bytes - result[3]: NVRAM format version number - - Input byte 0 = 2: Wireless switch configuration - result[0]: return code - result[1]: - Bit 0: Wifi controlled by switch - Bit 1: Bluetooth controlled by switch - Bit 2: WWAN controlled by switch - Bits 3-6: Reserved - Bit 7: Wireless switch config locked - Bit 8: Wifi locator enabled - Bits 9-14: Reserved - Bit 15: Wifi locator setting locked - Bits 16-31: Reserved -*/ - -static int dell_rfkill_set(void *data, bool blocked) -{ - int disable = blocked ? 1 : 0; - unsigned long radio = (unsigned long)data; - int hwswitch_bit = (unsigned long)data - 1; - - get_buffer(); - dell_send_request(buffer, 17, 11); - - /* If the hardware switch controls this radio, and the hardware - switch is disabled, always disable the radio */ - if ((hwswitch_state & BIT(hwswitch_bit)) && - !(buffer->output[1] & BIT(16))) - disable = 1; - - buffer->input[0] = (1 | (radio<<8) | (disable << 16)); - dell_send_request(buffer, 17, 11); - - release_buffer(); - return 0; -} - -/* Must be called with the buffer held */ -static void dell_rfkill_update_sw_state(struct rfkill *rfkill, int radio, - int status) -{ - if (status & BIT(0)) { - /* Has hw-switch, sync sw_state to BIOS */ - int block = rfkill_blocked(rfkill); - buffer->input[0] = (1 | (radio << 8) | (block << 16)); - dell_send_request(buffer, 17, 11); - } else { - /* No hw-switch, sync BIOS state to sw_state */ - rfkill_set_sw_state(rfkill, !!(status & BIT(radio + 16))); - } -} - -static void dell_rfkill_update_hw_state(struct rfkill *rfkill, int radio, - int status) -{ - if (hwswitch_state & (BIT(radio - 1))) - rfkill_set_hw_state(rfkill, !(status & BIT(16))); -} - -static void dell_rfkill_query(struct rfkill *rfkill, void *data) -{ - int status; - - get_buffer(); - dell_send_request(buffer, 17, 11); - status = buffer->output[1]; - - dell_rfkill_update_hw_state(rfkill, (unsigned long)data, status); - - release_buffer(); -} - -static const struct rfkill_ops dell_rfkill_ops = { - .set_block = dell_rfkill_set, - .query = dell_rfkill_query, -}; - static struct dentry *dell_laptop_dir; static int dell_debugfs_show(struct seq_file *s, void *data) @@ -534,136 +424,6 @@ static const struct file_operations dell_debugfs_fops = { .release = single_release, }; -static void dell_update_rfkill(struct work_struct *ignored) -{ - int status; - - get_buffer(); - dell_send_request(buffer, 17, 11); - status = buffer->output[1]; - - if (wifi_rfkill) { - dell_rfkill_update_hw_state(wifi_rfkill, 1, status); - dell_rfkill_update_sw_state(wifi_rfkill, 1, status); - } - if (bluetooth_rfkill) { - dell_rfkill_update_hw_state(bluetooth_rfkill, 2, status); - dell_rfkill_update_sw_state(bluetooth_rfkill, 2, status); - } - if (wwan_rfkill) { - dell_rfkill_update_hw_state(wwan_rfkill, 3, status); - dell_rfkill_update_sw_state(wwan_rfkill, 3, status); - } - - release_buffer(); -} -static DECLARE_DELAYED_WORK(dell_rfkill_work, dell_update_rfkill); - - -static int __init dell_setup_rfkill(void) -{ - int status; - int ret; - const char *product; - - /* - * rfkill causes trouble on various non Latitudes, according to Dell - * actually testing the rfkill functionality is only done on Latitudes. - */ - product = dmi_get_system_info(DMI_PRODUCT_NAME); - if (!force_rfkill && (!product || strncmp(product, "Latitude", 8))) - return 0; - - get_buffer(); - dell_send_request(buffer, 17, 11); - status = buffer->output[1]; - buffer->input[0] = 0x2; - dell_send_request(buffer, 17, 11); - hwswitch_state = buffer->output[1]; - release_buffer(); - - if (!(status & BIT(0))) { - if (force_rfkill) { - /* No hwsitch, clear all hw-controlled bits */ - hwswitch_state &= ~7; - } else { - /* rfkill is only tested on laptops with a hwswitch */ - return 0; - } - } - - if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) { - wifi_rfkill = rfkill_alloc("dell-wifi", &platform_device->dev, - RFKILL_TYPE_WLAN, - &dell_rfkill_ops, (void *) 1); - if (!wifi_rfkill) { - ret = -ENOMEM; - goto err_wifi; - } - ret = rfkill_register(wifi_rfkill); - if (ret) - goto err_wifi; - } - - if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) { - bluetooth_rfkill = rfkill_alloc("dell-bluetooth", - &platform_device->dev, - RFKILL_TYPE_BLUETOOTH, - &dell_rfkill_ops, (void *) 2); - if (!bluetooth_rfkill) { - ret = -ENOMEM; - goto err_bluetooth; - } - ret = rfkill_register(bluetooth_rfkill); - if (ret) - goto err_bluetooth; - } - - if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) { - wwan_rfkill = rfkill_alloc("dell-wwan", - &platform_device->dev, - RFKILL_TYPE_WWAN, - &dell_rfkill_ops, (void *) 3); - if (!wwan_rfkill) { - ret = -ENOMEM; - goto err_wwan; - } - ret = rfkill_register(wwan_rfkill); - if (ret) - goto err_wwan; - } - - return 0; -err_wwan: - rfkill_destroy(wwan_rfkill); - if (bluetooth_rfkill) - rfkill_unregister(bluetooth_rfkill); -err_bluetooth: - rfkill_destroy(bluetooth_rfkill); - if (wifi_rfkill) - rfkill_unregister(wifi_rfkill); -err_wifi: - rfkill_destroy(wifi_rfkill); - - return ret; -} - -static void dell_cleanup_rfkill(void) -{ - if (wifi_rfkill) { - rfkill_unregister(wifi_rfkill); - rfkill_destroy(wifi_rfkill); - } - if (bluetooth_rfkill) { - rfkill_unregister(bluetooth_rfkill); - rfkill_destroy(bluetooth_rfkill); - } - if (wwan_rfkill) { - rfkill_unregister(wwan_rfkill); - rfkill_destroy(wwan_rfkill); - } -} - static int dell_send_intensity(struct backlight_device *bd) { int ret = 0; @@ -755,30 +515,6 @@ static void touchpad_led_exit(void) led_classdev_unregister(&touchpad_led); } -static bool dell_laptop_i8042_filter(unsigned char data, unsigned char str, - struct serio *port) -{ - static bool extended; - - if (str & 0x20) - return false; - - if (unlikely(data == 0xe0)) { - extended = true; - return false; - } else if (unlikely(extended)) { - switch (data) { - case 0x8: - schedule_delayed_work(&dell_rfkill_work, - round_jiffies_relative(HZ / 4)); - break; - } - extended = false; - } - - return false; -} - static int __init dell_init(void) { int max_intensity = 0; @@ -821,26 +557,10 @@ static int __init dell_init(void) } buffer = page_address(bufferpage); - ret = dell_setup_rfkill(); - - if (ret) { - pr_warn("Unable to setup rfkill\n"); - goto fail_rfkill; - } - - ret = i8042_install_filter(dell_laptop_i8042_filter); - if (ret) { - pr_warn("Unable to install key filter\n"); - goto fail_filter; - } - if (quirks && quirks->touchpad_led) touchpad_led_init(&platform_device->dev); dell_laptop_dir = debugfs_create_dir("dell_laptop", NULL); - if (dell_laptop_dir != NULL) - debugfs_create_file("rfkill", 0444, dell_laptop_dir, NULL, - &dell_debugfs_fops); #ifdef CONFIG_ACPI /* In the event of an ACPI backlight being available, don't @@ -883,11 +603,6 @@ static int __init dell_init(void) return 0; fail_backlight: - i8042_remove_filter(dell_laptop_i8042_filter); - cancel_delayed_work_sync(&dell_rfkill_work); -fail_filter: - dell_cleanup_rfkill(); -fail_rfkill: free_page((unsigned long)bufferpage); fail_buffer: platform_device_del(platform_device); @@ -905,10 +620,7 @@ static void __exit dell_exit(void) debugfs_remove_recursive(dell_laptop_dir); if (quirks && quirks->touchpad_led) touchpad_led_exit(); - i8042_remove_filter(dell_laptop_i8042_filter); - cancel_delayed_work_sync(&dell_rfkill_work); backlight_device_unregister(dell_backlight_device); - dell_cleanup_rfkill(); if (platform_device) { platform_device_unregister(platform_device); platform_driver_unregister(&platform_driver); diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 60e0900..fa9a217 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c @@ -130,8 +130,7 @@ static const u16 bios_to_linux_keycode[256] __initconst = { KEY_BRIGHTNESSUP, KEY_UNKNOWN, KEY_KBDILLUMTOGGLE, KEY_UNKNOWN, KEY_SWITCHVIDEOMODE, KEY_UNKNOWN, KEY_UNKNOWN, KEY_SWITCHVIDEOMODE, KEY_UNKNOWN, KEY_UNKNOWN, KEY_PROG2, - KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, - KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_MICMUTE, + KEY_UNKNOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -140,8 +139,8 @@ static const u16 bios_to_linux_keycode[256] __initconst = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, KEY_PROG3 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + KEY_PROG3 }; static struct input_dev *dell_wmi_input_dev; diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index dec68e7..a6afd41 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -190,10 +190,16 @@ struct eeepc_laptop { */ static int write_acpi_int(acpi_handle handle, const char *method, int val) { + struct acpi_object_list params; + union acpi_object in_obj; acpi_status status; - status = acpi_execute_simple_method(handle, (char *)method, val); + params.count = 1; + params.pointer = &in_obj; + in_obj.type = ACPI_TYPE_INTEGER; + in_obj.integer.value = val; + status = acpi_evaluate_object(handle, (char *)method, ¶ms, NULL); return (status == AE_OK ? 0 : -1); } @@ -1203,8 +1209,10 @@ static int eeepc_input_init(struct eeepc_laptop *eeepc) int error; input = input_allocate_device(); - if (!input) + if (!input) { + pr_info("Unable to allocate input device\n"); return -ENOMEM; + } input->name = "Asus EeePC extra buttons"; input->phys = EEEPC_LAPTOP_FILE "/input0"; diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index 9d30d69..52b8a97 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -219,7 +219,8 @@ static int call_fext_func(int cmd, int arg0, int arg1, int arg2) { .type = ACPI_TYPE_INTEGER } }; struct acpi_object_list arg_list = { 4, ¶ms[0] }; - unsigned long long value; + struct acpi_buffer output; + union acpi_object out_obj; acpi_handle handle = NULL; status = acpi_get_handle(fujitsu_hotkey->acpi_handle, "FUNC", &handle); @@ -234,7 +235,10 @@ static int call_fext_func(int cmd, int arg0, int arg1, int arg2) params[2].integer.value = arg1; params[3].integer.value = arg2; - status = acpi_evaluate_integer(handle, NULL, &arg_list, &value); + output.length = sizeof(out_obj); + output.pointer = &out_obj; + + status = acpi_evaluate_object(handle, NULL, &arg_list, &output); if (ACPI_FAILURE(status)) { vdbg_printk(FUJLAPTOP_DBG_WARN, "FUNC 0x%x (args 0x%x, 0x%x, 0x%x) call failed\n", @@ -242,10 +246,18 @@ static int call_fext_func(int cmd, int arg0, int arg1, int arg2) return -ENODEV; } + if (out_obj.type != ACPI_TYPE_INTEGER) { + vdbg_printk(FUJLAPTOP_DBG_WARN, + "FUNC 0x%x (args 0x%x, 0x%x, 0x%x) did not " + "return an integer\n", + cmd, arg0, arg1, arg2); + return -ENODEV; + } + vdbg_printk(FUJLAPTOP_DBG_TRACE, "FUNC 0x%x (args 0x%x, 0x%x, 0x%x) returned 0x%x\n", - cmd, arg0, arg1, arg2, (int)value); - return value; + cmd, arg0, arg1, arg2, (int)out_obj.integer.value); + return out_obj.integer.value; } #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) @@ -305,6 +317,8 @@ static enum led_brightness kblamps_get(struct led_classdev *cdev) static int set_lcd_level(int level) { acpi_status status = AE_OK; + union acpi_object arg0 = { ACPI_TYPE_INTEGER }; + struct acpi_object_list arg_list = { 1, &arg0 }; acpi_handle handle = NULL; vdbg_printk(FUJLAPTOP_DBG_TRACE, "set lcd level via SBLL [%d]\n", @@ -319,8 +333,9 @@ static int set_lcd_level(int level) return -ENODEV; } + arg0.integer.value = level; - status = acpi_execute_simple_method(handle, NULL, level); + status = acpi_evaluate_object(handle, NULL, &arg_list, NULL); if (ACPI_FAILURE(status)) return -ENODEV; @@ -330,6 +345,8 @@ static int set_lcd_level(int level) static int set_lcd_level_alt(int level) { acpi_status status = AE_OK; + union acpi_object arg0 = { ACPI_TYPE_INTEGER }; + struct acpi_object_list arg_list = { 1, &arg0 }; acpi_handle handle = NULL; vdbg_printk(FUJLAPTOP_DBG_TRACE, "set lcd level via SBL2 [%d]\n", @@ -344,7 +361,9 @@ static int set_lcd_level_alt(int level) return -ENODEV; } - status = acpi_execute_simple_method(handle, NULL, level); + arg0.integer.value = level; + + status = acpi_evaluate_object(handle, NULL, &arg_list, NULL); if (ACPI_FAILURE(status)) return -ENODEV; @@ -567,10 +586,11 @@ static struct platform_driver fujitsupf_driver = { static void dmi_check_cb_common(const struct dmi_system_id *id) { + acpi_handle handle; pr_info("Identified laptop model '%s'\n", id->ident); if (use_alt_lcd_levels == -1) { - if (acpi_has_method(NULL, - "\\_SB.PCI0.LPCB.FJEX.SBL2")) + if (ACPI_SUCCESS(acpi_get_handle(NULL, + "\\_SB.PCI0.LPCB.FJEX.SBL2", &handle))) use_alt_lcd_levels = 1; else use_alt_lcd_levels = 0; @@ -633,6 +653,7 @@ static struct dmi_system_id fujitsu_dmi_table[] = { static int acpi_fujitsu_add(struct acpi_device *device) { + acpi_handle handle; int result = 0; int state = 0; struct input_dev *input; @@ -681,7 +702,8 @@ static int acpi_fujitsu_add(struct acpi_device *device) fujitsu->dev = device; - if (acpi_has_method(device->handle, METHOD_NAME__INI)) { + if (ACPI_SUCCESS + (acpi_get_handle(device->handle, METHOD_NAME__INI, &handle))) { vdbg_printk(FUJLAPTOP_DBG_INFO, "Invoking _INI\n"); if (ACPI_FAILURE (acpi_evaluate_object @@ -781,6 +803,7 @@ static void acpi_fujitsu_notify(struct acpi_device *device, u32 event) static int acpi_fujitsu_hotkey_add(struct acpi_device *device) { + acpi_handle handle; int result = 0; int state = 0; struct input_dev *input; @@ -843,7 +866,8 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) fujitsu_hotkey->dev = device; - if (acpi_has_method(device->handle, METHOD_NAME__INI)) { + if (ACPI_SUCCESS + (acpi_get_handle(device->handle, METHOD_NAME__INI, &handle))) { vdbg_printk(FUJLAPTOP_DBG_INFO, "Invoking _INI\n"); if (ACPI_FAILURE (acpi_evaluate_object diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 8ba8956..1c86fa0 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -54,7 +54,6 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4"); #define HPWMI_HARDWARE_QUERY 0x4 #define HPWMI_WIRELESS_QUERY 0x5 #define HPWMI_HOTKEY_QUERY 0xc -#define HPWMI_FEATURE_QUERY 0xd #define HPWMI_WIRELESS2_QUERY 0x1b #define HPWMI_POSTCODEERROR_QUERY 0x2a @@ -293,17 +292,6 @@ static int hp_wmi_tablet_state(void) return (state & 0x4) ? 1 : 0; } -static int hp_wmi_bios_2009_later(void) -{ - int state = 0; - int ret = hp_wmi_perform_query(HPWMI_FEATURE_QUERY, 0, &state, - sizeof(state), sizeof(state)); - if (ret) - return ret; - - return (state & 0x10) ? 1 : 0; -} - static int hp_wmi_set_block(void *data, bool blocked) { enum hp_wmi_radio r = (enum hp_wmi_radio) data; @@ -883,7 +871,7 @@ static int __init hp_wmi_bios_setup(struct platform_device *device) gps_rfkill = NULL; rfkill2_count = 0; - if (hp_wmi_bios_2009_later() || hp_wmi_rfkill_setup(device)) + if (hp_wmi_rfkill_setup(device)) hp_wmi_rfkill2_setup(device); err = device_create_file(&device->dev, &dev_attr_display); diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 19ec951..89c4519 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -72,15 +72,8 @@ enum { VPCCMD_W_BL_POWER = 0x33, }; -struct ideapad_rfk_priv { - int dev; - struct ideapad_private *priv; -}; - struct ideapad_private { - struct acpi_device *adev; struct rfkill *rfk[IDEAPAD_RFKILL_DEV_NUM]; - struct ideapad_rfk_priv rfk_priv[IDEAPAD_RFKILL_DEV_NUM]; struct platform_device *platform_device; struct input_dev *inputdev; struct backlight_device *blightdev; @@ -88,6 +81,8 @@ struct ideapad_private { unsigned long cfg; }; +static acpi_handle ideapad_handle; +static struct ideapad_private *ideapad_priv; static bool no_bt_rfkill; module_param(no_bt_rfkill, bool, 0444); MODULE_PARM_DESC(no_bt_rfkill, "No rfkill for bluetooth."); @@ -205,38 +200,34 @@ static int write_ec_cmd(acpi_handle handle, int cmd, unsigned long data) */ static int debugfs_status_show(struct seq_file *s, void *data) { - struct ideapad_private *priv = s->private; unsigned long value; - if (!priv) - return -EINVAL; - - if (!read_ec_data(priv->adev->handle, VPCCMD_R_BL_MAX, &value)) + if (!read_ec_data(ideapad_handle, VPCCMD_R_BL_MAX, &value)) seq_printf(s, "Backlight max:\t%lu\n", value); - if (!read_ec_data(priv->adev->handle, VPCCMD_R_BL, &value)) + if (!read_ec_data(ideapad_handle, VPCCMD_R_BL, &value)) seq_printf(s, "Backlight now:\t%lu\n", value); - if (!read_ec_data(priv->adev->handle, VPCCMD_R_BL_POWER, &value)) + if (!read_ec_data(ideapad_handle, VPCCMD_R_BL_POWER, &value)) seq_printf(s, "BL power value:\t%s\n", value ? "On" : "Off"); seq_printf(s, "=====================\n"); - if (!read_ec_data(priv->adev->handle, VPCCMD_R_RF, &value)) + if (!read_ec_data(ideapad_handle, VPCCMD_R_RF, &value)) seq_printf(s, "Radio status:\t%s(%lu)\n", value ? "On" : "Off", value); - if (!read_ec_data(priv->adev->handle, VPCCMD_R_WIFI, &value)) + if (!read_ec_data(ideapad_handle, VPCCMD_R_WIFI, &value)) seq_printf(s, "Wifi status:\t%s(%lu)\n", value ? "On" : "Off", value); - if (!read_ec_data(priv->adev->handle, VPCCMD_R_BT, &value)) + if (!read_ec_data(ideapad_handle, VPCCMD_R_BT, &value)) seq_printf(s, "BT status:\t%s(%lu)\n", value ? "On" : "Off", value); - if (!read_ec_data(priv->adev->handle, VPCCMD_R_3G, &value)) + if (!read_ec_data(ideapad_handle, VPCCMD_R_3G, &value)) seq_printf(s, "3G status:\t%s(%lu)\n", value ? "On" : "Off", value); seq_printf(s, "=====================\n"); - if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) + if (!read_ec_data(ideapad_handle, VPCCMD_R_TOUCHPAD, &value)) seq_printf(s, "Touchpad status:%s(%lu)\n", value ? "On" : "Off", value); - if (!read_ec_data(priv->adev->handle, VPCCMD_R_CAMERA, &value)) + if (!read_ec_data(ideapad_handle, VPCCMD_R_CAMERA, &value)) seq_printf(s, "Camera status:\t%s(%lu)\n", value ? "On" : "Off", value); @@ -245,7 +236,7 @@ static int debugfs_status_show(struct seq_file *s, void *data) static int debugfs_status_open(struct inode *inode, struct file *file) { - return single_open(file, debugfs_status_show, inode->i_private); + return single_open(file, debugfs_status_show, NULL); } static const struct file_operations debugfs_status_fops = { @@ -258,23 +249,21 @@ static const struct file_operations debugfs_status_fops = { static int debugfs_cfg_show(struct seq_file *s, void *data) { - struct ideapad_private *priv = s->private; - - if (!priv) { + if (!ideapad_priv) { seq_printf(s, "cfg: N/A\n"); } else { seq_printf(s, "cfg: 0x%.8lX\n\nCapability: ", - priv->cfg); - if (test_bit(CFG_BT_BIT, &priv->cfg)) + ideapad_priv->cfg); + if (test_bit(CFG_BT_BIT, &ideapad_priv->cfg)) seq_printf(s, "Bluetooth "); - if (test_bit(CFG_3G_BIT, &priv->cfg)) + if (test_bit(CFG_3G_BIT, &ideapad_priv->cfg)) seq_printf(s, "3G "); - if (test_bit(CFG_WIFI_BIT, &priv->cfg)) + if (test_bit(CFG_WIFI_BIT, &ideapad_priv->cfg)) seq_printf(s, "Wireless "); - if (test_bit(CFG_CAMERA_BIT, &priv->cfg)) + if (test_bit(CFG_CAMERA_BIT, &ideapad_priv->cfg)) seq_printf(s, "Camera "); seq_printf(s, "\nGraphic: "); - switch ((priv->cfg)&0x700) { + switch ((ideapad_priv->cfg)&0x700) { case 0x100: seq_printf(s, "Intel"); break; @@ -298,7 +287,7 @@ static int debugfs_cfg_show(struct seq_file *s, void *data) static int debugfs_cfg_open(struct inode *inode, struct file *file) { - return single_open(file, debugfs_cfg_show, inode->i_private); + return single_open(file, debugfs_cfg_show, NULL); } static const struct file_operations debugfs_cfg_fops = { @@ -319,14 +308,14 @@ static int ideapad_debugfs_init(struct ideapad_private *priv) goto errout; } - node = debugfs_create_file("cfg", S_IRUGO, priv->debug, priv, + node = debugfs_create_file("cfg", S_IRUGO, priv->debug, NULL, &debugfs_cfg_fops); if (!node) { pr_err("failed to create cfg in debugfs"); goto errout; } - node = debugfs_create_file("status", S_IRUGO, priv->debug, priv, + node = debugfs_create_file("status", S_IRUGO, priv->debug, NULL, &debugfs_status_fops); if (!node) { pr_err("failed to create status in debugfs"); @@ -353,9 +342,8 @@ static ssize_t show_ideapad_cam(struct device *dev, char *buf) { unsigned long result; - struct ideapad_private *priv = dev_get_drvdata(dev); - if (read_ec_data(priv->adev->handle, VPCCMD_R_CAMERA, &result)) + if (read_ec_data(ideapad_handle, VPCCMD_R_CAMERA, &result)) return sprintf(buf, "-1\n"); return sprintf(buf, "%lu\n", result); } @@ -365,13 +353,12 @@ static ssize_t store_ideapad_cam(struct device *dev, const char *buf, size_t count) { int ret, state; - struct ideapad_private *priv = dev_get_drvdata(dev); if (!count) return 0; if (sscanf(buf, "%i", &state) != 1) return -EINVAL; - ret = write_ec_cmd(priv->adev->handle, VPCCMD_W_CAMERA, state); + ret = write_ec_cmd(ideapad_handle, VPCCMD_W_CAMERA, state); if (ret < 0) return -EIO; return count; @@ -384,9 +371,8 @@ static ssize_t show_ideapad_fan(struct device *dev, char *buf) { unsigned long result; - struct ideapad_private *priv = dev_get_drvdata(dev); - if (read_ec_data(priv->adev->handle, VPCCMD_R_FAN, &result)) + if (read_ec_data(ideapad_handle, VPCCMD_R_FAN, &result)) return sprintf(buf, "-1\n"); return sprintf(buf, "%lu\n", result); } @@ -396,7 +382,6 @@ static ssize_t store_ideapad_fan(struct device *dev, const char *buf, size_t count) { int ret, state; - struct ideapad_private *priv = dev_get_drvdata(dev); if (!count) return 0; @@ -404,7 +389,7 @@ static ssize_t store_ideapad_fan(struct device *dev, return -EINVAL; if (state < 0 || state > 4 || state == 3) return -EINVAL; - ret = write_ec_cmd(priv->adev->handle, VPCCMD_W_FAN, state); + ret = write_ec_cmd(ideapad_handle, VPCCMD_W_FAN, state); if (ret < 0) return -EIO; return count; @@ -430,8 +415,7 @@ static umode_t ideapad_is_visible(struct kobject *kobj, supported = test_bit(CFG_CAMERA_BIT, &(priv->cfg)); else if (attr == &dev_attr_fan_mode.attr) { unsigned long value; - supported = !read_ec_data(priv->adev->handle, VPCCMD_R_FAN, - &value); + supported = !read_ec_data(ideapad_handle, VPCCMD_R_FAN, &value); } else supported = true; @@ -461,9 +445,9 @@ const struct ideapad_rfk_data ideapad_rfk_data[] = { static int ideapad_rfk_set(void *data, bool blocked) { - struct ideapad_rfk_priv *priv = data; + unsigned long opcode = (unsigned long)data; - return write_ec_cmd(priv->priv->adev->handle, priv->dev, !blocked); + return write_ec_cmd(ideapad_handle, opcode, !blocked); } static struct rfkill_ops ideapad_rfk_ops = { @@ -475,7 +459,7 @@ static void ideapad_sync_rfk_state(struct ideapad_private *priv) unsigned long hw_blocked; int i; - if (read_ec_data(priv->adev->handle, VPCCMD_R_RF, &hw_blocked)) + if (read_ec_data(ideapad_handle, VPCCMD_R_RF, &hw_blocked)) return; hw_blocked = !hw_blocked; @@ -484,30 +468,27 @@ static void ideapad_sync_rfk_state(struct ideapad_private *priv) rfkill_set_hw_state(priv->rfk[i], hw_blocked); } -static int ideapad_register_rfkill(struct ideapad_private *priv, int dev) +static int ideapad_register_rfkill(struct acpi_device *adevice, int dev) { + struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); int ret; unsigned long sw_blocked; if (no_bt_rfkill && (ideapad_rfk_data[dev].type == RFKILL_TYPE_BLUETOOTH)) { /* Force to enable bluetooth when no_bt_rfkill=1 */ - write_ec_cmd(priv->adev->handle, + write_ec_cmd(ideapad_handle, ideapad_rfk_data[dev].opcode, 1); return 0; } - priv->rfk_priv[dev].dev = dev; - priv->rfk_priv[dev].priv = priv; - - priv->rfk[dev] = rfkill_alloc(ideapad_rfk_data[dev].name, - &priv->platform_device->dev, - ideapad_rfk_data[dev].type, - &ideapad_rfk_ops, - &priv->rfk_priv[dev]); + + priv->rfk[dev] = rfkill_alloc(ideapad_rfk_data[dev].name, &adevice->dev, + ideapad_rfk_data[dev].type, &ideapad_rfk_ops, + (void *)(long)dev); if (!priv->rfk[dev]) return -ENOMEM; - if (read_ec_data(priv->adev->handle, ideapad_rfk_data[dev].opcode-1, + if (read_ec_data(ideapad_handle, ideapad_rfk_data[dev].opcode-1, &sw_blocked)) { rfkill_init_sw_state(priv->rfk[dev], 0); } else { @@ -523,8 +504,10 @@ static int ideapad_register_rfkill(struct ideapad_private *priv, int dev) return 0; } -static void ideapad_unregister_rfkill(struct ideapad_private *priv, int dev) +static void ideapad_unregister_rfkill(struct acpi_device *adevice, int dev) { + struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); + if (!priv->rfk[dev]) return; @@ -535,16 +518,37 @@ static void ideapad_unregister_rfkill(struct ideapad_private *priv, int dev) /* * Platform device */ -static int ideapad_sysfs_init(struct ideapad_private *priv) +static int ideapad_platform_init(struct ideapad_private *priv) { - return sysfs_create_group(&priv->platform_device->dev.kobj, + int result; + + priv->platform_device = platform_device_alloc("ideapad", -1); + if (!priv->platform_device) + return -ENOMEM; + platform_set_drvdata(priv->platform_device, priv); + + result = platform_device_add(priv->platform_device); + if (result) + goto fail_platform_device; + + result = sysfs_create_group(&priv->platform_device->dev.kobj, &ideapad_attribute_group); + if (result) + goto fail_sysfs; + return 0; + +fail_sysfs: + platform_device_del(priv->platform_device); +fail_platform_device: + platform_device_put(priv->platform_device); + return result; } -static void ideapad_sysfs_exit(struct ideapad_private *priv) +static void ideapad_platform_exit(struct ideapad_private *priv) { sysfs_remove_group(&priv->platform_device->dev.kobj, &ideapad_attribute_group); + platform_device_unregister(priv->platform_device); } /* @@ -570,8 +574,10 @@ static int ideapad_input_init(struct ideapad_private *priv) int error; inputdev = input_allocate_device(); - if (!inputdev) + if (!inputdev) { + pr_info("Unable to allocate input device\n"); return -ENOMEM; + } inputdev->name = "Ideapad extra buttons"; inputdev->phys = "ideapad/input0"; @@ -617,7 +623,7 @@ static void ideapad_input_novokey(struct ideapad_private *priv) { unsigned long long_pressed; - if (read_ec_data(priv->adev->handle, VPCCMD_R_NOVO, &long_pressed)) + if (read_ec_data(ideapad_handle, VPCCMD_R_NOVO, &long_pressed)) return; if (long_pressed) ideapad_input_report(priv, 17); @@ -629,7 +635,7 @@ static void ideapad_check_special_buttons(struct ideapad_private *priv) { unsigned long bit, value; - read_ec_data(priv->adev->handle, VPCCMD_R_SPECIAL_BUTTONS, &value); + read_ec_data(ideapad_handle, VPCCMD_R_SPECIAL_BUTTONS, &value); for (bit = 0; bit < 16; bit++) { if (test_bit(bit, &value)) { @@ -656,28 +662,19 @@ static void ideapad_check_special_buttons(struct ideapad_private *priv) */ static int ideapad_backlight_get_brightness(struct backlight_device *blightdev) { - struct ideapad_private *priv = bl_get_data(blightdev); unsigned long now; - if (!priv) - return -EINVAL; - - if (read_ec_data(priv->adev->handle, VPCCMD_R_BL, &now)) + if (read_ec_data(ideapad_handle, VPCCMD_R_BL, &now)) return -EIO; return now; } static int ideapad_backlight_update_status(struct backlight_device *blightdev) { - struct ideapad_private *priv = bl_get_data(blightdev); - - if (!priv) - return -EINVAL; - - if (write_ec_cmd(priv->adev->handle, VPCCMD_W_BL, + if (write_ec_cmd(ideapad_handle, VPCCMD_W_BL, blightdev->props.brightness)) return -EIO; - if (write_ec_cmd(priv->adev->handle, VPCCMD_W_BL_POWER, + if (write_ec_cmd(ideapad_handle, VPCCMD_W_BL_POWER, blightdev->props.power == FB_BLANK_POWERDOWN ? 0 : 1)) return -EIO; @@ -695,11 +692,11 @@ static int ideapad_backlight_init(struct ideapad_private *priv) struct backlight_properties props; unsigned long max, now, power; - if (read_ec_data(priv->adev->handle, VPCCMD_R_BL_MAX, &max)) + if (read_ec_data(ideapad_handle, VPCCMD_R_BL_MAX, &max)) return -EIO; - if (read_ec_data(priv->adev->handle, VPCCMD_R_BL, &now)) + if (read_ec_data(ideapad_handle, VPCCMD_R_BL, &now)) return -EIO; - if (read_ec_data(priv->adev->handle, VPCCMD_R_BL_POWER, &power)) + if (read_ec_data(ideapad_handle, VPCCMD_R_BL_POWER, &power)) return -EIO; memset(&props, 0, sizeof(struct backlight_properties)); @@ -737,7 +734,7 @@ static void ideapad_backlight_notify_power(struct ideapad_private *priv) if (!blightdev) return; - if (read_ec_data(priv->adev->handle, VPCCMD_R_BL_POWER, &power)) + if (read_ec_data(ideapad_handle, VPCCMD_R_BL_POWER, &power)) return; blightdev->props.power = power ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; } @@ -748,7 +745,7 @@ static void ideapad_backlight_notify_brightness(struct ideapad_private *priv) /* if we control brightness via acpi video driver */ if (priv->blightdev == NULL) { - read_ec_data(priv->adev->handle, VPCCMD_R_BL, &now); + read_ec_data(ideapad_handle, VPCCMD_R_BL, &now); return; } @@ -758,12 +755,19 @@ static void ideapad_backlight_notify_brightness(struct ideapad_private *priv) /* * module init/exit */ -static void ideapad_sync_touchpad_state(struct ideapad_private *priv) +static const struct acpi_device_id ideapad_device_ids[] = { + { "VPC2004", 0}, + { "", 0}, +}; +MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); + +static void ideapad_sync_touchpad_state(struct acpi_device *adevice) { + struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); unsigned long value; /* Without reading from EC touchpad LED doesn't switch state */ - if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) { + if (!read_ec_data(adevice->handle, VPCCMD_R_TOUCHPAD, &value)) { /* Some IdeaPads don't really turn off touchpad - they only * switch the LED state. We (de)activate KBC AUX port to turn * touchpad off and on. We send KEY_TOUCHPAD_OFF and @@ -775,77 +779,26 @@ static void ideapad_sync_touchpad_state(struct ideapad_private *priv) } } -static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data) -{ - struct ideapad_private *priv = data; - unsigned long vpc1, vpc2, vpc_bit; - - if (read_ec_data(handle, VPCCMD_R_VPC1, &vpc1)) - return; - if (read_ec_data(handle, VPCCMD_R_VPC2, &vpc2)) - return; - - vpc1 = (vpc2 << 8) | vpc1; - for (vpc_bit = 0; vpc_bit < 16; vpc_bit++) { - if (test_bit(vpc_bit, &vpc1)) { - switch (vpc_bit) { - case 9: - ideapad_sync_rfk_state(priv); - break; - case 13: - case 11: - case 7: - case 6: - ideapad_input_report(priv, vpc_bit); - break; - case 5: - ideapad_sync_touchpad_state(priv); - break; - case 4: - ideapad_backlight_notify_brightness(priv); - break; - case 3: - ideapad_input_novokey(priv); - break; - case 2: - ideapad_backlight_notify_power(priv); - break; - case 0: - ideapad_check_special_buttons(priv); - break; - default: - pr_info("Unknown event: %lu\n", vpc_bit); - } - } - } -} - -static int ideapad_acpi_add(struct platform_device *pdev) +static int ideapad_acpi_add(struct acpi_device *adevice) { int ret, i; int cfg; struct ideapad_private *priv; - struct acpi_device *adev; - ret = acpi_bus_get_device(ACPI_HANDLE(&pdev->dev), &adev); - if (ret) - return -ENODEV; - - if (read_method_int(adev->handle, "_CFG", &cfg)) + if (read_method_int(adevice->handle, "_CFG", &cfg)) return -ENODEV; priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; - - dev_set_drvdata(&pdev->dev, priv); + dev_set_drvdata(&adevice->dev, priv); + ideapad_priv = priv; + ideapad_handle = adevice->handle; priv->cfg = cfg; - priv->adev = adev; - priv->platform_device = pdev; - ret = ideapad_sysfs_init(priv); + ret = ideapad_platform_init(priv); if (ret) - goto sysfs_failed; + goto platform_failed; ret = ideapad_debugfs_init(priv); if (ret) @@ -857,92 +810,117 @@ static int ideapad_acpi_add(struct platform_device *pdev) for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) { if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) - ideapad_register_rfkill(priv, i); + ideapad_register_rfkill(adevice, i); else priv->rfk[i] = NULL; } ideapad_sync_rfk_state(priv); - ideapad_sync_touchpad_state(priv); + ideapad_sync_touchpad_state(adevice); if (!acpi_video_backlight_support()) { ret = ideapad_backlight_init(priv); if (ret && ret != -ENODEV) goto backlight_failed; } - ret = acpi_install_notify_handler(adev->handle, - ACPI_DEVICE_NOTIFY, ideapad_acpi_notify, priv); - if (ret) - goto notification_failed; return 0; -notification_failed: - ideapad_backlight_exit(priv); + backlight_failed: for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) - ideapad_unregister_rfkill(priv, i); + ideapad_unregister_rfkill(adevice, i); ideapad_input_exit(priv); input_failed: ideapad_debugfs_exit(priv); debugfs_failed: - ideapad_sysfs_exit(priv); -sysfs_failed: + ideapad_platform_exit(priv); +platform_failed: kfree(priv); return ret; } -static int ideapad_acpi_remove(struct platform_device *pdev) +static int ideapad_acpi_remove(struct acpi_device *adevice) { - struct ideapad_private *priv = dev_get_drvdata(&pdev->dev); + struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); int i; - acpi_remove_notify_handler(priv->adev->handle, - ACPI_DEVICE_NOTIFY, ideapad_acpi_notify); ideapad_backlight_exit(priv); for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) - ideapad_unregister_rfkill(priv, i); + ideapad_unregister_rfkill(adevice, i); ideapad_input_exit(priv); ideapad_debugfs_exit(priv); - ideapad_sysfs_exit(priv); - dev_set_drvdata(&pdev->dev, NULL); + ideapad_platform_exit(priv); + dev_set_drvdata(&adevice->dev, NULL); kfree(priv); return 0; } -#ifdef CONFIG_PM_SLEEP -static int ideapad_acpi_resume(struct device *device) +static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event) { - struct ideapad_private *priv; + struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); + acpi_handle handle = adevice->handle; + unsigned long vpc1, vpc2, vpc_bit; - if (!device) - return -EINVAL; - priv = dev_get_drvdata(device); + if (read_ec_data(handle, VPCCMD_R_VPC1, &vpc1)) + return; + if (read_ec_data(handle, VPCCMD_R_VPC2, &vpc2)) + return; - ideapad_sync_rfk_state(priv); - ideapad_sync_touchpad_state(priv); + vpc1 = (vpc2 << 8) | vpc1; + for (vpc_bit = 0; vpc_bit < 16; vpc_bit++) { + if (test_bit(vpc_bit, &vpc1)) { + switch (vpc_bit) { + case 9: + ideapad_sync_rfk_state(priv); + break; + case 13: + case 11: + case 7: + case 6: + ideapad_input_report(priv, vpc_bit); + break; + case 5: + ideapad_sync_touchpad_state(adevice); + break; + case 4: + ideapad_backlight_notify_brightness(priv); + break; + case 3: + ideapad_input_novokey(priv); + break; + case 2: + ideapad_backlight_notify_power(priv); + break; + case 0: + ideapad_check_special_buttons(priv); + break; + default: + pr_info("Unknown event: %lu\n", vpc_bit); + } + } + } +} + +static int ideapad_acpi_resume(struct device *device) +{ + ideapad_sync_rfk_state(ideapad_priv); + ideapad_sync_touchpad_state(to_acpi_device(device)); return 0; } -#endif -static SIMPLE_DEV_PM_OPS(ideapad_pm, NULL, ideapad_acpi_resume); -static const struct acpi_device_id ideapad_device_ids[] = { - { "VPC2004", 0}, - { "", 0}, -}; -MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); +static SIMPLE_DEV_PM_OPS(ideapad_pm, NULL, ideapad_acpi_resume); -static struct platform_driver ideapad_acpi_driver = { - .probe = ideapad_acpi_add, - .remove = ideapad_acpi_remove, - .driver = { - .name = "ideapad_acpi", - .owner = THIS_MODULE, - .pm = &ideapad_pm, - .acpi_match_table = ACPI_PTR(ideapad_device_ids), - }, +static struct acpi_driver ideapad_acpi_driver = { + .name = "ideapad_acpi", + .class = "IdeaPad", + .ids = ideapad_device_ids, + .ops.add = ideapad_acpi_add, + .ops.remove = ideapad_acpi_remove, + .ops.notify = ideapad_acpi_notify, + .drv.pm = &ideapad_pm, + .owner = THIS_MODULE, }; - -module_platform_driver(ideapad_acpi_driver); +module_acpi_driver(ideapad_acpi_driver); MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); MODULE_DESCRIPTION("IdeaPad ACPI Extras"); diff --git a/drivers/platform/x86/intel-rst.c b/drivers/platform/x86/intel-rst.c index a2083a9..41b740c 100644 --- a/drivers/platform/x86/intel-rst.c +++ b/drivers/platform/x86/intel-rst.c @@ -29,16 +29,24 @@ static ssize_t irst_show_wakeup_events(struct device *dev, char *buf) { struct acpi_device *acpi; - unsigned long long value; + struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *result; acpi_status status; acpi = to_acpi_device(dev); - status = acpi_evaluate_integer(acpi->handle, "GFFS", NULL, &value); + status = acpi_evaluate_object(acpi->handle, "GFFS", NULL, &output); if (!ACPI_SUCCESS(status)) return -EINVAL; - return sprintf(buf, "%lld\n", value); + result = output.pointer; + + if (result->type != ACPI_TYPE_INTEGER) { + kfree(result); + return -EINVAL; + } + + return sprintf(buf, "%lld\n", result->integer.value); } static ssize_t irst_store_wakeup_events(struct device *dev, @@ -46,6 +54,8 @@ static ssize_t irst_store_wakeup_events(struct device *dev, const char *buf, size_t count) { struct acpi_device *acpi; + struct acpi_object_list input; + union acpi_object param; acpi_status status; unsigned long value; int error; @@ -57,7 +67,13 @@ static ssize_t irst_store_wakeup_events(struct device *dev, if (error) return error; - status = acpi_execute_simple_method(acpi->handle, "SFFS", value); + param.type = ACPI_TYPE_INTEGER; + param.integer.value = value; + + input.count = 1; + input.pointer = ¶m; + + status = acpi_evaluate_object(acpi->handle, "SFFS", &input, NULL); if (!ACPI_SUCCESS(status)) return -EINVAL; @@ -75,16 +91,24 @@ static ssize_t irst_show_wakeup_time(struct device *dev, struct device_attribute *attr, char *buf) { struct acpi_device *acpi; - unsigned long long value; + struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *result; acpi_status status; acpi = to_acpi_device(dev); - status = acpi_evaluate_integer(acpi->handle, "GFTV", NULL, &value); + status = acpi_evaluate_object(acpi->handle, "GFTV", NULL, &output); if (!ACPI_SUCCESS(status)) return -EINVAL; - return sprintf(buf, "%lld\n", value); + result = output.pointer; + + if (result->type != ACPI_TYPE_INTEGER) { + kfree(result); + return -EINVAL; + } + + return sprintf(buf, "%lld\n", result->integer.value); } static ssize_t irst_store_wakeup_time(struct device *dev, @@ -92,6 +116,8 @@ static ssize_t irst_store_wakeup_time(struct device *dev, const char *buf, size_t count) { struct acpi_device *acpi; + struct acpi_object_list input; + union acpi_object param; acpi_status status; unsigned long value; int error; @@ -103,7 +129,13 @@ static ssize_t irst_store_wakeup_time(struct device *dev, if (error) return error; - status = acpi_execute_simple_method(acpi->handle, "SFTV", value); + param.type = ACPI_TYPE_INTEGER; + param.integer.value = value; + + input.count = 1; + input.pointer = ¶m; + + status = acpi_evaluate_object(acpi->handle, "SFTV", &input, NULL); if (!ACPI_SUCCESS(status)) return -EINVAL; diff --git a/drivers/platform/x86/intel-smartconnect.c b/drivers/platform/x86/intel-smartconnect.c index 1838400..52259dc 100644 --- a/drivers/platform/x86/intel-smartconnect.c +++ b/drivers/platform/x86/intel-smartconnect.c @@ -25,18 +25,37 @@ MODULE_LICENSE("GPL"); static int smartconnect_acpi_init(struct acpi_device *acpi) { - unsigned long long value; + struct acpi_object_list input; + struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *result; + union acpi_object param; acpi_status status; - status = acpi_evaluate_integer(acpi->handle, "GAOS", NULL, &value); + status = acpi_evaluate_object(acpi->handle, "GAOS", NULL, &output); if (!ACPI_SUCCESS(status)) return -EINVAL; - if (value & 0x1) { + result = output.pointer; + + if (result->type != ACPI_TYPE_INTEGER) { + kfree(result); + return -EINVAL; + } + + if (result->integer.value & 0x1) { + param.type = ACPI_TYPE_INTEGER; + param.integer.value = 0; + + input.count = 1; + input.pointer = ¶m; + dev_info(&acpi->dev, "Disabling Intel Smart Connect\n"); - status = acpi_execute_simple_method(acpi->handle, "SAOS", 0); + status = acpi_evaluate_object(acpi->handle, "SAOS", &input, + NULL); } + kfree(result); + return 0; } diff --git a/drivers/platform/x86/intel_menlow.c b/drivers/platform/x86/intel_menlow.c index 11244f8..d6cfc15 100644 --- a/drivers/platform/x86/intel_menlow.c +++ b/drivers/platform/x86/intel_menlow.c @@ -156,15 +156,19 @@ static struct thermal_cooling_device_ops memory_cooling_ops = { static int intel_menlow_memory_add(struct acpi_device *device) { int result = -ENODEV; + acpi_status status = AE_OK; + acpi_handle dummy; struct thermal_cooling_device *cdev; if (!device) return -EINVAL; - if (!acpi_has_method(device->handle, MEMORY_GET_BANDWIDTH)) + status = acpi_get_handle(device->handle, MEMORY_GET_BANDWIDTH, &dummy); + if (ACPI_FAILURE(status)) goto end; - if (!acpi_has_method(device->handle, MEMORY_SET_BANDWIDTH)) + status = acpi_get_handle(device->handle, MEMORY_SET_BANDWIDTH, &dummy); + if (ACPI_FAILURE(status)) goto end; cdev = thermal_cooling_device_register("Memory controller", device, diff --git a/drivers/platform/x86/intel_mid_powerbtn.c b/drivers/platform/x86/intel_mid_powerbtn.c index 8d67752..6b18aba 100644 --- a/drivers/platform/x86/intel_mid_powerbtn.c +++ b/drivers/platform/x86/intel_mid_powerbtn.c @@ -66,8 +66,10 @@ static int mfld_pb_probe(struct platform_device *pdev) return -EINVAL; input = input_allocate_device(); - if (!input) + if (!input) { + dev_err(&pdev->dev, "Input device allocation error\n"); return -ENOMEM; + } input->name = pdev->name; input->phys = "power-button/input0"; diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c index 60ea476..9215ed7 100644 --- a/drivers/platform/x86/intel_scu_ipc.c +++ b/drivers/platform/x86/intel_scu_ipc.c @@ -25,7 +25,7 @@ #include <linux/interrupt.h> #include <linux/sfi.h> #include <linux/module.h> -#include <asm/intel-mid.h> +#include <asm/mrst.h> #include <asm/intel_scu_ipc.h> /* IPC defines the following message types */ @@ -58,56 +58,12 @@ * message handler is called within firmware. */ +#define IPC_BASE_ADDR 0xFF11C000 /* IPC1 base register address */ +#define IPC_MAX_ADDR 0x100 /* Maximum IPC regisers */ #define IPC_WWBUF_SIZE 20 /* IPC Write buffer Size */ #define IPC_RWBUF_SIZE 20 /* IPC Read buffer Size */ -#define IPC_IOC 0x100 /* IPC command register IOC bit */ - -enum { - SCU_IPC_LINCROFT, - SCU_IPC_PENWELL, - SCU_IPC_CLOVERVIEW, - SCU_IPC_TANGIER, -}; - -/* intel scu ipc driver data*/ -struct intel_scu_ipc_pdata_t { - u32 ipc_base; - u32 i2c_base; - u32 ipc_len; - u32 i2c_len; - u8 irq_mode; -}; - -static struct intel_scu_ipc_pdata_t intel_scu_ipc_pdata[] = { - [SCU_IPC_LINCROFT] = { - .ipc_base = 0xff11c000, - .i2c_base = 0xff12b000, - .ipc_len = 0x100, - .i2c_len = 0x10, - .irq_mode = 0, - }, - [SCU_IPC_PENWELL] = { - .ipc_base = 0xff11c000, - .i2c_base = 0xff12b000, - .ipc_len = 0x100, - .i2c_len = 0x10, - .irq_mode = 1, - }, - [SCU_IPC_CLOVERVIEW] = { - .ipc_base = 0xff11c000, - .i2c_base = 0xff12b000, - .ipc_len = 0x100, - .i2c_len = 0x10, - .irq_mode = 1, - }, - [SCU_IPC_TANGIER] = { - .ipc_base = 0xff009000, - .i2c_base = 0xff00d000, - .ipc_len = 0x100, - .i2c_len = 0x10, - .irq_mode = 0, - }, -}; +#define IPC_I2C_BASE 0xFF12B000 /* I2C control register base address */ +#define IPC_I2C_MAX_ADDR 0x10 /* Maximum I2C regisers */ static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id); static void ipc_remove(struct pci_dev *pdev); @@ -116,8 +72,6 @@ struct intel_scu_ipc_dev { struct pci_dev *pdev; void __iomem *ipc_base; void __iomem *i2c_base; - struct completion cmd_complete; - u8 irq_mode; }; static struct intel_scu_ipc_dev ipcdev; /* Only one for now */ @@ -144,10 +98,6 @@ static DEFINE_MUTEX(ipclock); /* lock used to prevent multiple call to SCU */ */ static inline void ipc_command(u32 cmd) /* Send ipc command */ { - if (ipcdev.irq_mode) { - reinit_completion(&ipcdev.cmd_complete); - writel(cmd | IPC_IOC, ipcdev.ipc_base); - } writel(cmd, ipcdev.ipc_base); } @@ -206,30 +156,6 @@ static inline int busy_loop(void) /* Wait till scu status is busy */ return 0; } -/* Wait till ipc ioc interrupt is received or timeout in 3 HZ */ -static inline int ipc_wait_for_interrupt(void) -{ - int status; - - if (!wait_for_completion_timeout(&ipcdev.cmd_complete, 3 * HZ)) { - struct device *dev = &ipcdev.pdev->dev; - dev_err(dev, "IPC timed out\n"); - return -ETIMEDOUT; - } - - status = ipc_read_status(); - - if ((status >> 1) & 1) - return -EIO; - - return 0; -} - -int intel_scu_ipc_check_status(void) -{ - return ipcdev.irq_mode ? ipc_wait_for_interrupt() : busy_loop(); -} - /* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id) { @@ -270,8 +196,8 @@ static int pwr_reg_rdwr(u16 *addr, u8 *data, u32 count, u32 op, u32 id) ipc_command(4 << 16 | id << 12 | 0 << 8 | op); } - err = intel_scu_ipc_check_status(); - if (!err && id == IPC_CMD_PCNTRL_R) { /* Read rbuf */ + err = busy_loop(); + if (id == IPC_CMD_PCNTRL_R) { /* Read rbuf */ /* Workaround: values are read as 0 without memcpy_fromio */ memcpy_fromio(cbuf, ipcdev.ipc_base + 0x90, 16); for (nc = 0; nc < count; nc++) @@ -465,7 +391,7 @@ int intel_scu_ipc_simple_command(int cmd, int sub) return -ENODEV; } ipc_command(sub << 12 | cmd); - err = intel_scu_ipc_check_status(); + err = busy_loop(); mutex_unlock(&ipclock); return err; } @@ -499,12 +425,10 @@ int intel_scu_ipc_command(int cmd, int sub, u32 *in, int inlen, ipc_data_writel(*in++, 4 * i); ipc_command((inlen << 16) | (sub << 12) | cmd); - err = intel_scu_ipc_check_status(); + err = busy_loop(); - if (!err) { - for (i = 0; i < outlen; i++) - *out++ = ipc_data_readl(4 * i); - } + for (i = 0; i < outlen; i++) + *out++ = ipc_data_readl(4 * i); mutex_unlock(&ipclock); return err; @@ -567,9 +491,6 @@ EXPORT_SYMBOL(intel_scu_ipc_i2c_cntrl); */ static irqreturn_t ioc(int irq, void *dev_id) { - if (ipcdev.irq_mode) - complete(&ipcdev.cmd_complete); - return IRQ_HANDLED; } @@ -583,18 +504,13 @@ static irqreturn_t ioc(int irq, void *dev_id) */ static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id) { - int err, pid; - struct intel_scu_ipc_pdata_t *pdata; + int err; resource_size_t pci_resource; if (ipcdev.pdev) /* We support only one SCU */ return -EBUSY; - pid = id->driver_data; - pdata = &intel_scu_ipc_pdata[pid]; - ipcdev.pdev = pci_dev_get(dev); - ipcdev.irq_mode = pdata->irq_mode; err = pci_enable_device(dev); if (err) @@ -608,16 +524,14 @@ static int ipc_probe(struct pci_dev *dev, const struct pci_device_id *id) if (!pci_resource) return -ENOMEM; - init_completion(&ipcdev.cmd_complete); - if (request_irq(dev->irq, ioc, 0, "intel_scu_ipc", &ipcdev)) return -EBUSY; - ipcdev.ipc_base = ioremap_nocache(pdata->ipc_base, pdata->ipc_len); + ipcdev.ipc_base = ioremap_nocache(IPC_BASE_ADDR, IPC_MAX_ADDR); if (!ipcdev.ipc_base) return -ENOMEM; - ipcdev.i2c_base = ioremap_nocache(pdata->i2c_base, pdata->i2c_len); + ipcdev.i2c_base = ioremap_nocache(IPC_I2C_BASE, IPC_I2C_MAX_ADDR); if (!ipcdev.i2c_base) { iounmap(ipcdev.ipc_base); return -ENOMEM; @@ -650,10 +564,7 @@ static void ipc_remove(struct pci_dev *pdev) } static DEFINE_PCI_DEVICE_TABLE(pci_ids) = { - {PCI_VDEVICE(INTEL, 0x082a), SCU_IPC_LINCROFT}, - {PCI_VDEVICE(INTEL, 0x080e), SCU_IPC_PENWELL}, - {PCI_VDEVICE(INTEL, 0x08ea), SCU_IPC_CLOVERVIEW}, - {PCI_VDEVICE(INTEL, 0x11a0), SCU_IPC_TANGIER}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x082a)}, { 0,} }; MODULE_DEVICE_TABLE(pci, pci_ids); @@ -668,7 +579,7 @@ static struct pci_driver ipc_driver = { static int __init intel_scu_ipc_init(void) { - platform = intel_mid_identify_cpu(); + platform = mrst_identify_cpu(); if (platform == 0) return -ENODEV; return pci_register_driver(&ipc_driver); diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index 3008fd2..10d12b2 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c @@ -490,8 +490,11 @@ static int acpi_pcc_init_input(struct pcc_acpi *pcc) int error; input_dev = input_allocate_device(); - if (!input_dev) + if (!input_dev) { + ACPI_DEBUG_PRINT((ACPI_DB_ERROR, + "Couldn't allocate input device for hotkey")); return -ENOMEM; + } input_dev->name = ACPI_PCC_DRIVER_NAME; input_dev->phys = ACPI_PCC_INPUT_PHYS; diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index fb233ae..13ec195 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -140,12 +140,12 @@ MODULE_PARM_DESC(kbd_backlight_timeout, "on the model (default: no change from current value)"); #ifdef CONFIG_PM_SLEEP +static void sony_nc_kbd_backlight_resume(void); static void sony_nc_thermal_resume(void); #endif static int sony_nc_kbd_backlight_setup(struct platform_device *pd, unsigned int handle); -static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd, - unsigned int handle); +static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd); static int sony_nc_battery_care_setup(struct platform_device *pd, unsigned int handle); @@ -304,8 +304,8 @@ static int sony_laptop_input_keycode_map[] = { KEY_FN_F10, /* 14 SONYPI_EVENT_FNKEY_F10 */ KEY_FN_F11, /* 15 SONYPI_EVENT_FNKEY_F11 */ KEY_FN_F12, /* 16 SONYPI_EVENT_FNKEY_F12 */ - KEY_FN_1, /* 17 SONYPI_EVENT_FNKEY_1 */ - KEY_FN_2, /* 18 SONYPI_EVENT_FNKEY_2 */ + KEY_FN_F1, /* 17 SONYPI_EVENT_FNKEY_1 */ + KEY_FN_F2, /* 18 SONYPI_EVENT_FNKEY_2 */ KEY_FN_D, /* 19 SONYPI_EVENT_FNKEY_D */ KEY_FN_E, /* 20 SONYPI_EVENT_FNKEY_E */ KEY_FN_F, /* 21 SONYPI_EVENT_FNKEY_F */ @@ -1444,7 +1444,7 @@ static void sony_nc_function_cleanup(struct platform_device *pd) case 0x014b: case 0x014c: case 0x0163: - sony_nc_kbd_backlight_cleanup(pd, handle); + sony_nc_kbd_backlight_cleanup(pd); break; default: continue; @@ -1486,6 +1486,13 @@ static void sony_nc_function_resume(void) case 0x0135: sony_nc_rfkill_update(); break; + case 0x0137: + case 0x0143: + case 0x014b: + case 0x014c: + case 0x0163: + sony_nc_kbd_backlight_resume(); + break; default: continue; } @@ -1501,6 +1508,7 @@ static void sony_nc_function_resume(void) static int sony_nc_resume(struct device *dev) { struct sony_nc_value *item; + acpi_handle handle; for (item = sony_nc_values; item->name; item++) { int ret; @@ -1515,13 +1523,15 @@ static int sony_nc_resume(struct device *dev) } } - if (acpi_has_method(sony_nc_acpi_handle, "ECON")) { + if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON", + &handle))) { int arg = 1; if (sony_nc_int_call(sony_nc_acpi_handle, "ECON", &arg, NULL)) dprintk("ECON Method failed\n"); } - if (acpi_has_method(sony_nc_acpi_handle, "SN00")) + if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00", + &handle))) sony_nc_function_resume(); return 0; @@ -1815,12 +1825,6 @@ static int sony_nc_kbd_backlight_setup(struct platform_device *pd, int result; int ret = 0; - if (kbdbl_ctl) { - pr_warn("handle 0x%.4x: keyboard backlight setup already done for 0x%.4x\n", - handle, kbdbl_ctl->handle); - return -EBUSY; - } - /* verify the kbd backlight presence, these handles are not used for * keyboard backlight only */ @@ -1880,10 +1884,9 @@ outkzalloc: return ret; } -static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd, - unsigned int handle) +static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd) { - if (kbdbl_ctl && handle == kbdbl_ctl->handle) { + if (kbdbl_ctl) { device_remove_file(&pd->dev, &kbdbl_ctl->mode_attr); device_remove_file(&pd->dev, &kbdbl_ctl->timeout_attr); kfree(kbdbl_ctl); @@ -1891,6 +1894,25 @@ static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd, } } +#ifdef CONFIG_PM_SLEEP +static void sony_nc_kbd_backlight_resume(void) +{ + int ignore = 0; + + if (!kbdbl_ctl) + return; + + if (kbdbl_ctl->mode == 0) + sony_call_snc_handle(kbdbl_ctl->handle, kbdbl_ctl->base, + &ignore); + + if (kbdbl_ctl->timeout != 0) + sony_call_snc_handle(kbdbl_ctl->handle, + (kbdbl_ctl->base + 0x200) | + (kbdbl_ctl->timeout << 0x10), &ignore); +} +#endif + struct battery_care_control { struct device_attribute attrs[2]; unsigned int handle; @@ -2660,6 +2682,7 @@ static void sony_nc_backlight_ng_read_limits(int handle, static void sony_nc_backlight_setup(void) { + acpi_handle unused; int max_brightness = 0; const struct backlight_ops *ops = NULL; struct backlight_properties props; @@ -2694,7 +2717,8 @@ static void sony_nc_backlight_setup(void) sony_nc_backlight_ng_read_limits(0x14c, &sony_bl_props); max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; - } else if (acpi_has_method(sony_nc_acpi_handle, "GBRT")) { + } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", + &unused))) { ops = &sony_backlight_ops; max_brightness = SONY_MAX_BRIGHTNESS - 1; @@ -2726,6 +2750,7 @@ static int sony_nc_add(struct acpi_device *device) { acpi_status status; int result = 0; + acpi_handle handle; struct sony_nc_value *item; pr_info("%s v%s\n", SONY_NC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION); @@ -2765,13 +2790,15 @@ static int sony_nc_add(struct acpi_device *device) goto outplatform; } - if (acpi_has_method(sony_nc_acpi_handle, "ECON")) { + if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON", + &handle))) { int arg = 1; if (sony_nc_int_call(sony_nc_acpi_handle, "ECON", &arg, NULL)) dprintk("ECON Method failed\n"); } - if (acpi_has_method(sony_nc_acpi_handle, "SN00")) { + if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00", + &handle))) { dprintk("Doing SNC setup\n"); /* retrieve the available handles */ result = sony_nc_handles_setup(sony_pf_device); @@ -2794,8 +2821,9 @@ static int sony_nc_add(struct acpi_device *device) /* find the available acpiget as described in the DSDT */ for (; item->acpiget && *item->acpiget; ++item->acpiget) { - if (acpi_has_method(sony_nc_acpi_handle, - *item->acpiget)) { + if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, + *item->acpiget, + &handle))) { dprintk("Found %s getter: %s\n", item->name, *item->acpiget); item->devattr.attr.mode |= S_IRUGO; @@ -2805,8 +2833,9 @@ static int sony_nc_add(struct acpi_device *device) /* find the available acpiset as described in the DSDT */ for (; item->acpiset && *item->acpiset; ++item->acpiset) { - if (acpi_has_method(sony_nc_acpi_handle, - *item->acpiset)) { + if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, + *item->acpiset, + &handle))) { dprintk("Found %s setter: %s\n", item->name, *item->acpiset); item->devattr.attr.mode |= S_IWUSR; diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 58b0274..03ca6c1 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -23,7 +23,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -#define TPACPI_VERSION "0.25" +#define TPACPI_VERSION "0.24" #define TPACPI_SYSFS_VERSION 0x020700 /* @@ -88,7 +88,6 @@ #include <linux/pci_ids.h> -#include <linux/thinkpad_acpi.h> /* ThinkPad CMOS commands */ #define TP_CMOS_VOLUME_DOWN 0 @@ -701,14 +700,6 @@ static void __init drv_acpi_handle_init(const char *name, static acpi_status __init tpacpi_acpi_handle_locate_callback(acpi_handle handle, u32 level, void *context, void **return_value) { - struct acpi_device *dev; - if (!strcmp(context, "video")) { - if (acpi_bus_get_device(handle, &dev)) - return AE_OK; - if (strcmp(ACPI_VIDEO_HID, acpi_device_hid(dev))) - return AE_OK; - } - *(acpi_handle *)return_value = handle; return AE_CTRL_TERMINATE; @@ -721,10 +712,10 @@ static void __init tpacpi_acpi_handle_locate(const char *name, acpi_status status; acpi_handle device_found; - BUG_ON(!name || !handle); + BUG_ON(!name || !hid || !handle); vdbg_printk(TPACPI_DBG_INIT, "trying to locate ACPI handle for %s, using HID %s\n", - name, hid ? hid : "NULL"); + name, hid); memset(&device_found, 0, sizeof(device_found)); status = acpi_get_devices(hid, tpacpi_acpi_handle_locate_callback, @@ -6099,28 +6090,19 @@ static int __init tpacpi_query_bcl_levels(acpi_handle handle) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; union acpi_object *obj; - struct acpi_device *device, *child; int rc; - if (acpi_bus_get_device(handle, &device)) - return 0; - - rc = 0; - list_for_each_entry(child, &device->children, node) { - acpi_status status = acpi_evaluate_object(child->handle, "_BCL", - NULL, &buffer); - if (ACPI_FAILURE(status)) - continue; - + if (ACPI_SUCCESS(acpi_evaluate_object(handle, "_BCL", NULL, &buffer))) { obj = (union acpi_object *)buffer.pointer; if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { pr_err("Unknown _BCL data, please report this to %s\n", - TPACPI_MAIL); + TPACPI_MAIL); rc = 0; } else { rc = obj->package.count; } - break; + } else { + return 0; } kfree(buffer.pointer); @@ -6136,7 +6118,7 @@ static unsigned int __init tpacpi_check_std_acpi_brightness_support(void) acpi_handle video_device; int bcl_levels = 0; - tpacpi_acpi_handle_locate("video", NULL, &video_device); + tpacpi_acpi_handle_locate("video", ACPI_VIDEO_HID, &video_device); if (video_device) bcl_levels = tpacpi_query_bcl_levels(video_device); @@ -6438,12 +6420,7 @@ static struct ibm_struct brightness_driver_data = { #define TPACPI_ALSA_SHRTNAME "ThinkPad Console Audio Control" #define TPACPI_ALSA_MIXERNAME TPACPI_ALSA_SHRTNAME -#if SNDRV_CARDS <= 32 -#define DEFAULT_ALSA_IDX ~((1 << (SNDRV_CARDS - 3)) - 1) -#else -#define DEFAULT_ALSA_IDX ~((1 << (32 - 3)) - 1) -#endif -static int alsa_index = DEFAULT_ALSA_IDX; /* last three slots */ +static int alsa_index = ~((1 << (SNDRV_CARDS - 3)) - 1); /* last three slots */ static char *alsa_id = "ThinkPadEC"; static bool alsa_enable = SNDRV_DEFAULT_ENABLE1; @@ -8373,91 +8350,6 @@ static struct ibm_struct fan_driver_data = { .resume = fan_resume, }; -/************************************************************************* - * Mute LED subdriver - */ - - -struct tp_led_table { - acpi_string name; - int on_value; - int off_value; - int state; -}; - -static struct tp_led_table led_tables[] = { - [TPACPI_LED_MUTE] = { - .name = "SSMS", - .on_value = 1, - .off_value = 0, - }, - [TPACPI_LED_MICMUTE] = { - .name = "MMTS", - .on_value = 2, - .off_value = 0, - }, -}; - -static int mute_led_on_off(struct tp_led_table *t, bool state) -{ - acpi_handle temp; - int output; - - if (!ACPI_SUCCESS(acpi_get_handle(hkey_handle, t->name, &temp))) { - pr_warn("Thinkpad ACPI has no %s interface.\n", t->name); - return -EIO; - } - - if (!acpi_evalf(hkey_handle, &output, t->name, "dd", - state ? t->on_value : t->off_value)) - return -EIO; - - t->state = state; - return state; -} - -int tpacpi_led_set(int whichled, bool on) -{ - struct tp_led_table *t; - - if (whichled < 0 || whichled >= TPACPI_LED_MAX) - return -EINVAL; - - t = &led_tables[whichled]; - if (t->state < 0 || t->state == on) - return t->state; - return mute_led_on_off(t, on); -} -EXPORT_SYMBOL_GPL(tpacpi_led_set); - -static int mute_led_init(struct ibm_init_struct *iibm) -{ - acpi_handle temp; - int i; - - for (i = 0; i < TPACPI_LED_MAX; i++) { - struct tp_led_table *t = &led_tables[i]; - if (ACPI_SUCCESS(acpi_get_handle(hkey_handle, t->name, &temp))) - mute_led_on_off(t, false); - else - t->state = -ENODEV; - } - return 0; -} - -static void mute_led_exit(void) -{ - int i; - - for (i = 0; i < TPACPI_LED_MAX; i++) - tpacpi_led_set(i, false); -} - -static struct ibm_struct mute_led_driver_data = { - .name = "mute_led", - .exit = mute_led_exit, -}; - /**************************************************************************** **************************************************************************** * @@ -8876,10 +8768,6 @@ static struct ibm_init_struct ibms_init[] __initdata = { .init = fan_init, .data = &fan_driver_data, }, - { - .init = mute_led_init, - .data = &mute_led_driver_data, - }, }; static int __init set_ibm_param(const char *val, struct kernel_param *kp) @@ -9168,6 +9056,7 @@ static int __init thinkpad_acpi_module_init(void) mutex_init(&tpacpi_inputdev_send_mutex); tpacpi_inputdev = input_allocate_device(); if (!tpacpi_inputdev) { + pr_err("unable to allocate input device\n"); thinkpad_acpi_module_exit(); return -ENOMEM; } else { diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c index e597de0..4ab618c 100644 --- a/drivers/platform/x86/topstar-laptop.c +++ b/drivers/platform/x86/topstar-laptop.c @@ -80,9 +80,13 @@ static void acpi_topstar_notify(struct acpi_device *device, u32 event) static int acpi_topstar_fncx_switch(struct acpi_device *device, bool state) { acpi_status status; + union acpi_object fncx_params[1] = { + { .type = ACPI_TYPE_INTEGER } + }; + struct acpi_object_list fncx_arg_list = { 1, &fncx_params[0] }; - status = acpi_execute_simple_method(device->handle, "FNCX", - state ? 0x86 : 0x87); + fncx_params[0].integer.value = state ? 0x86 : 0x87; + status = acpi_evaluate_object(device->handle, "FNCX", &fncx_arg_list, NULL); if (ACPI_FAILURE(status)) { pr_err("Unable to switch FNCX notifications\n"); return -ENODEV; @@ -97,8 +101,10 @@ static int acpi_topstar_init_hkey(struct topstar_hkey *hkey) int error; input = input_allocate_device(); - if (!input) + if (!input) { + pr_err("Unable to allocate input device\n"); return -ENOMEM; + } input->name = "Topstar Laptop extra buttons"; input->phys = "topstar/input0"; diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 7fce391..eb3467e 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -191,9 +191,16 @@ static __inline__ void _set_bit(u32 * word, u32 mask, int value) static int write_acpi_int(const char *methodName, int val) { + struct acpi_object_list params; + union acpi_object in_objs[1]; acpi_status status; - status = acpi_execute_simple_method(NULL, (char *)methodName, val); + params.count = ARRAY_SIZE(in_objs); + params.pointer = in_objs; + in_objs[0].type = ACPI_TYPE_INTEGER; + in_objs[0].integer.value = val; + + status = acpi_evaluate_object(NULL, (char *)methodName, ¶ms, NULL); return (status == AE_OK) ? 0 : -EIO; } @@ -940,17 +947,21 @@ static void toshiba_acpi_hotkey_work(struct work_struct *work) */ static int toshiba_acpi_query_hotkey(struct toshiba_acpi_dev *dev) { - unsigned long long value; + struct acpi_buffer buf; + union acpi_object out_obj; acpi_status status; - status = acpi_evaluate_integer(dev->acpi_dev->handle, "INFO", - NULL, &value); - if (ACPI_FAILURE(status)) { + buf.pointer = &out_obj; + buf.length = sizeof(out_obj); + + status = acpi_evaluate_object(dev->acpi_dev->handle, "INFO", + NULL, &buf); + if (ACPI_FAILURE(status) || out_obj.type != ACPI_TYPE_INTEGER) { pr_err("ACPI INFO method execution failed\n"); return -EIO; } - return value; + return out_obj.integer.value; } static void toshiba_acpi_report_hotkey(struct toshiba_acpi_dev *dev, @@ -970,13 +981,15 @@ static void toshiba_acpi_report_hotkey(struct toshiba_acpi_dev *dev, static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) { acpi_status status; - acpi_handle ec_handle; + acpi_handle ec_handle, handle; int error; u32 hci_result; dev->hotkey_dev = input_allocate_device(); - if (!dev->hotkey_dev) + if (!dev->hotkey_dev) { + pr_info("Unable to register input device\n"); return -ENOMEM; + } dev->hotkey_dev->name = "Toshiba input device"; dev->hotkey_dev->phys = "toshiba_acpi/input0"; @@ -995,7 +1008,10 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) */ status = AE_ERROR; ec_handle = ec_get_handle(); - if (ec_handle && acpi_has_method(ec_handle, "NTFY")) { + if (ec_handle) + status = acpi_get_handle(ec_handle, "NTFY", &handle); + + if (ACPI_SUCCESS(status)) { INIT_WORK(&dev->hotkey_work, toshiba_acpi_hotkey_work); error = i8042_install_filter(toshiba_acpi_i8042_filter); @@ -1011,9 +1027,10 @@ static int toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) * Determine hotkey query interface. Prefer using the INFO * method when it is available. */ - if (acpi_has_method(dev->acpi_dev->handle, "INFO")) + status = acpi_get_handle(dev->acpi_dev->handle, "INFO", &handle); + if (ACPI_SUCCESS(status)) { dev->info_supported = 1; - else { + } else { hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); if (hci_result == HCI_SUCCESS) dev->system_event_supported = 1; @@ -1138,10 +1155,15 @@ static int toshiba_acpi_remove(struct acpi_device *acpi_dev) static const char *find_hci_method(acpi_handle handle) { - if (acpi_has_method(handle, "GHCI")) + acpi_status status; + acpi_handle hci_handle; + + status = acpi_get_handle(handle, "GHCI", &hci_handle); + if (ACPI_SUCCESS(status)) return "GHCI"; - if (acpi_has_method(handle, "SPFC")) + status = acpi_get_handle(handle, "SPFC", &hci_handle); + if (ACPI_SUCCESS(status)) return "SPFC"; return NULL; diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index c2e7b26..601ea95 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -252,6 +252,8 @@ static acpi_status wmi_method_enable(struct wmi_block *wblock, int enable) { struct guid_block *block = NULL; char method[5]; + struct acpi_object_list input; + union acpi_object params[1]; acpi_status status; acpi_handle handle; @@ -261,9 +263,13 @@ static acpi_status wmi_method_enable(struct wmi_block *wblock, int enable) if (!block) return AE_NOT_EXIST; + input.count = 1; + input.pointer = params; + params[0].type = ACPI_TYPE_INTEGER; + params[0].integer.value = enable; snprintf(method, 5, "WE%02X", block->notify_id); - status = acpi_execute_simple_method(handle, method, enable); + status = acpi_evaluate_object(handle, method, &input, NULL); if (status != AE_OK && status != AE_NOT_FOUND) return status; @@ -347,10 +353,10 @@ struct acpi_buffer *out) { struct guid_block *block = NULL; struct wmi_block *wblock = NULL; - acpi_handle handle; + acpi_handle handle, wc_handle; acpi_status status, wc_status = AE_ERROR; - struct acpi_object_list input; - union acpi_object wq_params[1]; + struct acpi_object_list input, wc_input; + union acpi_object wc_params[1], wq_params[1]; char method[5]; char wc_method[5] = "WC"; @@ -380,6 +386,11 @@ struct acpi_buffer *out) * enable collection. */ if (block->flags & ACPI_WMI_EXPENSIVE) { + wc_input.count = 1; + wc_input.pointer = wc_params; + wc_params[0].type = ACPI_TYPE_INTEGER; + wc_params[0].integer.value = 1; + strncat(wc_method, block->object_id, 2); /* @@ -387,9 +398,10 @@ struct acpi_buffer *out) * expensive, but have no corresponding WCxx method. So we * should not fail if this happens. */ - if (acpi_has_method(handle, wc_method)) - wc_status = acpi_execute_simple_method(handle, - wc_method, 1); + wc_status = acpi_get_handle(handle, wc_method, &wc_handle); + if (ACPI_SUCCESS(wc_status)) + wc_status = acpi_evaluate_object(handle, wc_method, + &wc_input, NULL); } strcpy(method, "WQ"); @@ -402,7 +414,9 @@ struct acpi_buffer *out) * the WQxx method failed - we should disable collection anyway. */ if ((block->flags & ACPI_WMI_EXPENSIVE) && ACPI_SUCCESS(wc_status)) { - status = acpi_execute_simple_method(handle, wc_method, 0); + wc_params[0].integer.value = 0; + status = acpi_evaluate_object(handle, + wc_method, &wc_input, NULL); } return status; @@ -672,10 +686,8 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, struct wmi_block *wblock; wblock = dev_get_drvdata(dev); - if (!wblock) { - strcat(buf, "\n"); - return strlen(buf); - } + if (!wblock) + return -ENOMEM; wmi_gtoa(wblock->gblock.guid, guid_string); |