Commit b037bba7 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for_linus' of...

Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86: (45 commits)
  compal-laptop: Make it depend on CONFIG_RFKILL
  classmate-laptop: Added some keys present in other devices
  MAINTAINERS: Add git tree to x86 Platform Drivers
  asus-acpi: remove duplicate comparison of asus_model strings
  toshiba-acpi: fix multimedia keys on some machines
  dell-laptop: Fix errors on failure and exit paths
  dell-laptop: Fix build error by making buffer_mutex static
  asus-laptop: fix style problems reported by checkpath.pl
  asus-laptop: use device_create_file() instead of platform_group
  asus-laptop: clean led code
  asus-laptop: add gps rfkill
  asus-laptop: set initial lcd state
  asus-laptop: leds, remove dead code and fix asus_led_exit()/asus_led_init()
  asus-laptop: add backlight changes notifications
  asus-laptop: add bluetooth keys found on M9V
  asus-laptop: switch to sparse keymap library
  asus-laptop: rename wireless_status to wlan_status to avoid confusion
  asus-laptop: add error check for write_acpi_int calls
  asus-laptop: stop using ASUS_HANDLE and use relative methods instead
  asus-laptop: rename function talking directly to acpi with asus_xxx scheme
  ...
parents a03696e9 51c1410b
What: /sys/devices/platform/asus-laptop/display What: /sys/devices/platform/asus_laptop/display
Date: January 2007 Date: January 2007
KernelVersion: 2.6.20 KernelVersion: 2.6.20
Contact: "Corentin Chary" <corentincj@iksaif.net> Contact: "Corentin Chary" <corentincj@iksaif.net>
...@@ -13,7 +13,7 @@ Description: ...@@ -13,7 +13,7 @@ Description:
Ex: - 0 (0000b) means no display Ex: - 0 (0000b) means no display
- 3 (0011b) CRT+LCD. - 3 (0011b) CRT+LCD.
What: /sys/devices/platform/asus-laptop/gps What: /sys/devices/platform/asus_laptop/gps
Date: January 2007 Date: January 2007
KernelVersion: 2.6.20 KernelVersion: 2.6.20
Contact: "Corentin Chary" <corentincj@iksaif.net> Contact: "Corentin Chary" <corentincj@iksaif.net>
...@@ -21,7 +21,7 @@ Description: ...@@ -21,7 +21,7 @@ Description:
Control the gps device. 1 means on, 0 means off. Control the gps device. 1 means on, 0 means off.
Users: Lapsus Users: Lapsus
What: /sys/devices/platform/asus-laptop/ledd What: /sys/devices/platform/asus_laptop/ledd
Date: January 2007 Date: January 2007
KernelVersion: 2.6.20 KernelVersion: 2.6.20
Contact: "Corentin Chary" <corentincj@iksaif.net> Contact: "Corentin Chary" <corentincj@iksaif.net>
...@@ -29,11 +29,11 @@ Description: ...@@ -29,11 +29,11 @@ Description:
Some models like the W1N have a LED display that can be Some models like the W1N have a LED display that can be
used to display several informations. used to display several informations.
To control the LED display, use the following : To control the LED display, use the following :
echo 0x0T000DDD > /sys/devices/platform/asus-laptop/ echo 0x0T000DDD > /sys/devices/platform/asus_laptop/
where T control the 3 letters display, and DDD the 3 digits display. where T control the 3 letters display, and DDD the 3 digits display.
The DDD table can be found in Documentation/laptops/asus-laptop.txt The DDD table can be found in Documentation/laptops/asus-laptop.txt
What: /sys/devices/platform/asus-laptop/bluetooth What: /sys/devices/platform/asus_laptop/bluetooth
Date: January 2007 Date: January 2007
KernelVersion: 2.6.20 KernelVersion: 2.6.20
Contact: "Corentin Chary" <corentincj@iksaif.net> Contact: "Corentin Chary" <corentincj@iksaif.net>
...@@ -42,7 +42,7 @@ Description: ...@@ -42,7 +42,7 @@ Description:
This may control the led, the device or both. This may control the led, the device or both.
Users: Lapsus Users: Lapsus
What: /sys/devices/platform/asus-laptop/wlan What: /sys/devices/platform/asus_laptop/wlan
Date: January 2007 Date: January 2007
KernelVersion: 2.6.20 KernelVersion: 2.6.20
Contact: "Corentin Chary" <corentincj@iksaif.net> Contact: "Corentin Chary" <corentincj@iksaif.net>
......
What: /sys/devices/platform/eeepc-laptop/disp What: /sys/devices/platform/eeepc/disp
Date: May 2008 Date: May 2008
KernelVersion: 2.6.26 KernelVersion: 2.6.26
Contact: "Corentin Chary" <corentincj@iksaif.net> Contact: "Corentin Chary" <corentincj@iksaif.net>
...@@ -9,21 +9,21 @@ Description: ...@@ -9,21 +9,21 @@ Description:
- 3 = LCD+CRT - 3 = LCD+CRT
If you run X11, you should use xrandr instead. If you run X11, you should use xrandr instead.
What: /sys/devices/platform/eeepc-laptop/camera What: /sys/devices/platform/eeepc/camera
Date: May 2008 Date: May 2008
KernelVersion: 2.6.26 KernelVersion: 2.6.26
Contact: "Corentin Chary" <corentincj@iksaif.net> Contact: "Corentin Chary" <corentincj@iksaif.net>
Description: Description:
Control the camera. 1 means on, 0 means off. Control the camera. 1 means on, 0 means off.
What: /sys/devices/platform/eeepc-laptop/cardr What: /sys/devices/platform/eeepc/cardr
Date: May 2008 Date: May 2008
KernelVersion: 2.6.26 KernelVersion: 2.6.26
Contact: "Corentin Chary" <corentincj@iksaif.net> Contact: "Corentin Chary" <corentincj@iksaif.net>
Description: Description:
Control the card reader. 1 means on, 0 means off. Control the card reader. 1 means on, 0 means off.
What: /sys/devices/platform/eeepc-laptop/cpufv What: /sys/devices/platform/eeepc/cpufv
Date: Jun 2009 Date: Jun 2009
KernelVersion: 2.6.31 KernelVersion: 2.6.31
Contact: "Corentin Chary" <corentincj@iksaif.net> Contact: "Corentin Chary" <corentincj@iksaif.net>
...@@ -42,7 +42,7 @@ Description: ...@@ -42,7 +42,7 @@ Description:
`------------ Availables modes `------------ Availables modes
For example, 0x301 means: mode 1 selected, 3 available modes. For example, 0x301 means: mode 1 selected, 3 available modes.
What: /sys/devices/platform/eeepc-laptop/available_cpufv What: /sys/devices/platform/eeepc/available_cpufv
Date: Jun 2009 Date: Jun 2009
KernelVersion: 2.6.31 KernelVersion: 2.6.31
Contact: "Corentin Chary" <corentincj@iksaif.net> Contact: "Corentin Chary" <corentincj@iksaif.net>
......
...@@ -650,6 +650,10 @@ LCD, CRT or DVI (if available). The following commands are available: ...@@ -650,6 +650,10 @@ LCD, CRT or DVI (if available). The following commands are available:
echo expand_toggle > /proc/acpi/ibm/video echo expand_toggle > /proc/acpi/ibm/video
echo video_switch > /proc/acpi/ibm/video echo video_switch > /proc/acpi/ibm/video
NOTE: Access to this feature is restricted to processes owning the
CAP_SYS_ADMIN capability for safety reasons, as it can interact badly
enough with some versions of X.org to crash it.
Each video output device can be enabled or disabled individually. Each video output device can be enabled or disabled individually.
Reading /proc/acpi/ibm/video shows the status of each device. Reading /proc/acpi/ibm/video shows the status of each device.
......
...@@ -6097,6 +6097,7 @@ F: arch/x86/ ...@@ -6097,6 +6097,7 @@ F: arch/x86/
X86 PLATFORM DRIVERS X86 PLATFORM DRIVERS
M: Matthew Garrett <mjg@redhat.com> M: Matthew Garrett <mjg@redhat.com>
L: platform-driver-x86@vger.kernel.org L: platform-driver-x86@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.git
S: Maintained S: Maintained
F: drivers/platform/x86 F: drivers/platform/x86
......
...@@ -59,6 +59,8 @@ config ASUS_LAPTOP ...@@ -59,6 +59,8 @@ config ASUS_LAPTOP
select NEW_LEDS select NEW_LEDS
select BACKLIGHT_CLASS_DEVICE select BACKLIGHT_CLASS_DEVICE
depends on INPUT depends on INPUT
depends on RFKILL || RFKILL = n
select INPUT_SPARSEKMAP
---help--- ---help---
This is the new Linux driver for Asus laptops. It may also support some This is the new Linux driver for Asus laptops. It may also support some
MEDION, JVC or VICTOR laptops. It makes all the extra buttons generate MEDION, JVC or VICTOR laptops. It makes all the extra buttons generate
...@@ -177,6 +179,7 @@ config COMPAL_LAPTOP ...@@ -177,6 +179,7 @@ config COMPAL_LAPTOP
tristate "Compal Laptop Extras" tristate "Compal Laptop Extras"
depends on ACPI depends on ACPI
depends on BACKLIGHT_CLASS_DEVICE depends on BACKLIGHT_CLASS_DEVICE
depends on RFKILL
---help--- ---help---
This is a driver for laptops built by Compal: This is a driver for laptops built by Compal:
...@@ -320,9 +323,15 @@ config THINKPAD_ACPI_VIDEO ...@@ -320,9 +323,15 @@ config THINKPAD_ACPI_VIDEO
server running, phase of the moon, and the current mood of server running, phase of the moon, and the current mood of
Schroedinger's cat. If you can use X.org's RandR to control Schroedinger's cat. If you can use X.org's RandR to control
your ThinkPad's video output ports instead of this feature, your ThinkPad's video output ports instead of this feature,
don't think twice: do it and say N here to save some memory. don't think twice: do it and say N here to save memory and avoid
bad interactions with X.org.
NOTE: access to this feature is limited to processes with the
CAP_SYS_ADMIN capability, to avoid local DoS issues in platforms
where it interacts badly with X.org.
If you are not sure, say Y here. If you are not sure, say Y here but do try to check if you could
be using X.org RandR instead.
config THINKPAD_ACPI_HOTKEY_POLL config THINKPAD_ACPI_HOTKEY_POLL
bool "Support NVRAM polling for hot keys" bool "Support NVRAM polling for hot keys"
......
This diff is collapsed.
...@@ -1225,9 +1225,8 @@ static int asus_model_match(char *model) ...@@ -1225,9 +1225,8 @@ static int asus_model_match(char *model)
else if (strncmp(model, "M2N", 3) == 0 || else if (strncmp(model, "M2N", 3) == 0 ||
strncmp(model, "M3N", 3) == 0 || strncmp(model, "M3N", 3) == 0 ||
strncmp(model, "M5N", 3) == 0 || strncmp(model, "M5N", 3) == 0 ||
strncmp(model, "M6N", 3) == 0 ||
strncmp(model, "S1N", 3) == 0 || strncmp(model, "S1N", 3) == 0 ||
strncmp(model, "S5N", 3) == 0 || strncmp(model, "W1N", 3) == 0) strncmp(model, "S5N", 3) == 0)
return xxN; return xxN;
else if (strncmp(model, "M1", 2) == 0) else if (strncmp(model, "M1", 2) == 0)
return M1A; return M1A;
......
...@@ -507,6 +507,10 @@ static int cmpc_keys_codes[] = { ...@@ -507,6 +507,10 @@ static int cmpc_keys_codes[] = {
KEY_BRIGHTNESSDOWN, KEY_BRIGHTNESSDOWN,
KEY_BRIGHTNESSUP, KEY_BRIGHTNESSUP,
KEY_VENDOR, KEY_VENDOR,
KEY_UNKNOWN,
KEY_CAMERA,
KEY_BACK,
KEY_FORWARD,
KEY_MAX KEY_MAX
}; };
......
...@@ -132,8 +132,8 @@ static struct dmi_system_id __devinitdata dell_blacklist[] = { ...@@ -132,8 +132,8 @@ static struct dmi_system_id __devinitdata dell_blacklist[] = {
}; };
static struct calling_interface_buffer *buffer; static struct calling_interface_buffer *buffer;
struct page *bufferpage; static struct page *bufferpage;
DEFINE_MUTEX(buffer_mutex); static DEFINE_MUTEX(buffer_mutex);
static int hwswitch_state; static int hwswitch_state;
...@@ -580,6 +580,7 @@ static int __init dell_init(void) ...@@ -580,6 +580,7 @@ static int __init dell_init(void)
fail_backlight: fail_backlight:
i8042_remove_filter(dell_laptop_i8042_filter); i8042_remove_filter(dell_laptop_i8042_filter);
cancel_delayed_work_sync(&dell_rfkill_work);
fail_filter: fail_filter:
dell_cleanup_rfkill(); dell_cleanup_rfkill();
fail_rfkill: fail_rfkill:
...@@ -597,12 +598,12 @@ static int __init dell_init(void) ...@@ -597,12 +598,12 @@ static int __init dell_init(void)
static void __exit dell_exit(void) static void __exit dell_exit(void)
{ {
cancel_delayed_work_sync(&dell_rfkill_work);
i8042_remove_filter(dell_laptop_i8042_filter); i8042_remove_filter(dell_laptop_i8042_filter);
cancel_delayed_work_sync(&dell_rfkill_work);
backlight_device_unregister(dell_backlight_device); backlight_device_unregister(dell_backlight_device);
dell_cleanup_rfkill(); dell_cleanup_rfkill();
if (platform_device) { if (platform_device) {
platform_device_del(platform_device); platform_device_unregister(platform_device);
platform_driver_unregister(&platform_driver); platform_driver_unregister(&platform_driver);
} }
kfree(da_tokens); kfree(da_tokens);
......
...@@ -578,6 +578,8 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc) ...@@ -578,6 +578,8 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc)
struct pci_dev *dev; struct pci_dev *dev;
struct pci_bus *bus; struct pci_bus *bus;
bool blocked = eeepc_wlan_rfkill_blocked(eeepc); bool blocked = eeepc_wlan_rfkill_blocked(eeepc);
bool absent;
u32 l;
if (eeepc->wlan_rfkill) if (eeepc->wlan_rfkill)
rfkill_set_sw_state(eeepc->wlan_rfkill, blocked); rfkill_set_sw_state(eeepc->wlan_rfkill, blocked);
...@@ -591,6 +593,22 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc) ...@@ -591,6 +593,22 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc)
goto out_unlock; goto out_unlock;
} }
if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
pr_err("Unable to read PCI config space?\n");
goto out_unlock;
}
absent = (l == 0xffffffff);
if (blocked != absent) {
pr_warning("BIOS says wireless lan is %s, "
"but the pci device is %s\n",
blocked ? "blocked" : "unblocked",
absent ? "absent" : "present");
pr_warning("skipped wireless hotplug as probably "
"inappropriate for this model\n");
goto out_unlock;
}
if (!blocked) { if (!blocked) {
dev = pci_get_slot(bus, 0); dev = pci_get_slot(bus, 0);
if (dev) { if (dev) {
...@@ -1277,7 +1295,8 @@ static void eeepc_dmi_check(struct eeepc_laptop *eeepc) ...@@ -1277,7 +1295,8 @@ static void eeepc_dmi_check(struct eeepc_laptop *eeepc)
* hotplug code. In fact, current hotplug code seems to unplug another * hotplug code. In fact, current hotplug code seems to unplug another
* device... * device...
*/ */
if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0) { if (strcmp(model, "1005HA") == 0 || strcmp(model, "1201N") == 0 ||
strcmp(model, "1005PE") == 0) {
eeepc->hotplug_disabled = true; eeepc->hotplug_disabled = true;
pr_info("wlan hotplug disabled\n"); pr_info("wlan hotplug disabled\n");
} }
......
...@@ -286,6 +286,7 @@ struct ibm_init_struct { ...@@ -286,6 +286,7 @@ struct ibm_init_struct {
char param[32]; char param[32];
int (*init) (struct ibm_init_struct *); int (*init) (struct ibm_init_struct *);
mode_t base_procfs_mode;
struct ibm_struct *data; struct ibm_struct *data;
}; };
...@@ -2082,6 +2083,7 @@ static struct attribute_set *hotkey_dev_attributes; ...@@ -2082,6 +2083,7 @@ static struct attribute_set *hotkey_dev_attributes;
static void tpacpi_driver_event(const unsigned int hkey_event); static void tpacpi_driver_event(const unsigned int hkey_event);
static void hotkey_driver_event(const unsigned int scancode); static void hotkey_driver_event(const unsigned int scancode);
static void hotkey_poll_setup(const bool may_warn);
/* HKEY.MHKG() return bits */ /* HKEY.MHKG() return bits */
#define TP_HOTKEY_TABLET_MASK (1 << 3) #define TP_HOTKEY_TABLET_MASK (1 << 3)
...@@ -2264,6 +2266,8 @@ static int tpacpi_hotkey_driver_mask_set(const u32 mask) ...@@ -2264,6 +2266,8 @@ static int tpacpi_hotkey_driver_mask_set(const u32 mask)
rc = hotkey_mask_set((hotkey_acpi_mask | hotkey_driver_mask) & rc = hotkey_mask_set((hotkey_acpi_mask | hotkey_driver_mask) &
~hotkey_source_mask); ~hotkey_source_mask);
hotkey_poll_setup(true);
mutex_unlock(&hotkey_mutex); mutex_unlock(&hotkey_mutex);
return rc; return rc;
...@@ -2548,7 +2552,7 @@ static void hotkey_poll_stop_sync(void) ...@@ -2548,7 +2552,7 @@ static void hotkey_poll_stop_sync(void)
} }
/* call with hotkey_mutex held */ /* call with hotkey_mutex held */
static void hotkey_poll_setup(bool may_warn) static void hotkey_poll_setup(const bool may_warn)
{ {
const u32 poll_driver_mask = hotkey_driver_mask & hotkey_source_mask; const u32 poll_driver_mask = hotkey_driver_mask & hotkey_source_mask;
const u32 poll_user_mask = hotkey_user_mask & hotkey_source_mask; const u32 poll_user_mask = hotkey_user_mask & hotkey_source_mask;
...@@ -2579,7 +2583,7 @@ static void hotkey_poll_setup(bool may_warn) ...@@ -2579,7 +2583,7 @@ static void hotkey_poll_setup(bool may_warn)
} }
} }
static void hotkey_poll_setup_safe(bool may_warn) static void hotkey_poll_setup_safe(const bool may_warn)
{ {
mutex_lock(&hotkey_mutex); mutex_lock(&hotkey_mutex);
hotkey_poll_setup(may_warn); hotkey_poll_setup(may_warn);
...@@ -2597,7 +2601,11 @@ static void hotkey_poll_set_freq(unsigned int freq) ...@@ -2597,7 +2601,11 @@ static void hotkey_poll_set_freq(unsigned int freq)
#else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */ #else /* CONFIG_THINKPAD_ACPI_HOTKEY_POLL */
static void hotkey_poll_setup_safe(bool __unused) static void hotkey_poll_setup(const bool __unused)
{
}
static void hotkey_poll_setup_safe(const bool __unused)
{ {
} }
...@@ -2607,16 +2615,11 @@ static int hotkey_inputdev_open(struct input_dev *dev) ...@@ -2607,16 +2615,11 @@ static int hotkey_inputdev_open(struct input_dev *dev)
{ {
switch (tpacpi_lifecycle) { switch (tpacpi_lifecycle) {
case TPACPI_LIFE_INIT: case TPACPI_LIFE_INIT:
/*
* hotkey_init will call hotkey_poll_setup_safe
* at the appropriate moment
*/
return 0;
case TPACPI_LIFE_EXITING:
return -EBUSY;
case TPACPI_LIFE_RUNNING: case TPACPI_LIFE_RUNNING:
hotkey_poll_setup_safe(false); hotkey_poll_setup_safe(false);
return 0; return 0;
case TPACPI_LIFE_EXITING:
return -EBUSY;
} }
/* Should only happen if tpacpi_lifecycle is corrupt */ /* Should only happen if tpacpi_lifecycle is corrupt */
...@@ -2627,7 +2630,7 @@ static int hotkey_inputdev_open(struct input_dev *dev) ...@@ -2627,7 +2630,7 @@ static int hotkey_inputdev_open(struct input_dev *dev)
static void hotkey_inputdev_close(struct input_dev *dev) static void hotkey_inputdev_close(struct input_dev *dev)
{ {
/* disable hotkey polling when possible */ /* disable hotkey polling when possible */
if (tpacpi_lifecycle == TPACPI_LIFE_RUNNING && if (tpacpi_lifecycle != TPACPI_LIFE_EXITING &&
!(hotkey_source_mask & hotkey_driver_mask)) !(hotkey_source_mask & hotkey_driver_mask))
hotkey_poll_setup_safe(false); hotkey_poll_setup_safe(false);
} }
...@@ -3655,13 +3658,19 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) ...@@ -3655,13 +3658,19 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
break; break;
case 3: case 3:
/* 0x3000-0x3FFF: bay-related wakeups */ /* 0x3000-0x3FFF: bay-related wakeups */
if (hkey == TP_HKEY_EV_BAYEJ_ACK) { switch (hkey) {
case TP_HKEY_EV_BAYEJ_ACK:
hotkey_autosleep_ack = 1; hotkey_autosleep_ack = 1;
printk(TPACPI_INFO printk(TPACPI_INFO
"bay ejected\n"); "bay ejected\n");
hotkey_wakeup_hotunplug_complete_notify_change(); hotkey_wakeup_hotunplug_complete_notify_change();
known_ev = true; known_ev = true;
} else { break;
case TP_HKEY_EV_OPTDRV_EJ:
/* FIXME: kick libata if SATA link offline */
known_ev = true;
break;
default:
known_ev = false; known_ev = false;
} }
break; break;
...@@ -3870,7 +3879,7 @@ enum { ...@@ -3870,7 +3879,7 @@ enum {
TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */ TP_ACPI_BLUETOOTH_HWPRESENT = 0x01, /* Bluetooth hw available */
TP_ACPI_BLUETOOTH_RADIOSSW = 0x02, /* Bluetooth radio enabled */ TP_ACPI_BLUETOOTH_RADIOSSW = 0x02, /* Bluetooth radio enabled */
TP_ACPI_BLUETOOTH_RESUMECTRL = 0x04, /* Bluetooth state at resume: TP_ACPI_BLUETOOTH_RESUMECTRL = 0x04, /* Bluetooth state at resume:
off / last state */ 0 = disable, 1 = enable */
}; };
enum { enum {
...@@ -3916,10 +3925,11 @@ static int bluetooth_set_status(enum tpacpi_rfkill_state state) ...@@ -3916,10 +3925,11 @@ static int bluetooth_set_status(enum tpacpi_rfkill_state state)
} }
#endif #endif
/* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */
status = TP_ACPI_BLUETOOTH_RESUMECTRL;
if (state == TPACPI_RFK_RADIO_ON) if (state == TPACPI_RFK_RADIO_ON)
status |= TP_ACPI_BLUETOOTH_RADIOSSW; status = TP_ACPI_BLUETOOTH_RADIOSSW
| TP_ACPI_BLUETOOTH_RESUMECTRL;
else
status = 0;
if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status)) if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
return -EIO; return -EIO;
...@@ -4070,7 +4080,7 @@ enum { ...@@ -4070,7 +4080,7 @@ enum {
TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */ TP_ACPI_WANCARD_HWPRESENT = 0x01, /* Wan hw available */
TP_ACPI_WANCARD_RADIOSSW = 0x02, /* Wan radio enabled */ TP_ACPI_WANCARD_RADIOSSW = 0x02, /* Wan radio enabled */
TP_ACPI_WANCARD_RESUMECTRL = 0x04, /* Wan state at resume: TP_ACPI_WANCARD_RESUMECTRL = 0x04, /* Wan state at resume:
off / last state */ 0 = disable, 1 = enable */
}; };
#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw" #define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw"
...@@ -4107,10 +4117,11 @@ static int wan_set_status(enum tpacpi_rfkill_state state) ...@@ -4107,10 +4117,11 @@ static int wan_set_status(enum tpacpi_rfkill_state state)
} }
#endif #endif
/* We make sure to set TP_ACPI_WANCARD_RESUMECTRL */
status = TP_ACPI_WANCARD_RESUMECTRL;
if (state == TPACPI_RFK_RADIO_ON) if (state == TPACPI_RFK_RADIO_ON)
status |= TP_ACPI_WANCARD_RADIOSSW; status = TP_ACPI_WANCARD_RADIOSSW
| TP_ACPI_WANCARD_RESUMECTRL;
else
status = 0;
if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status)) if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
return -EIO; return -EIO;
...@@ -4619,6 +4630,10 @@ static int video_read(struct seq_file *m) ...@@ -4619,6 +4630,10 @@ static int video_read(struct seq_file *m)
return 0; return 0;
} }
/* Even reads can crash X.org, so... */
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
status = video_outputsw_get(); status = video_outputsw_get();
if (status < 0) if (status < 0)
return status; return status;
...@@ -4652,6 +4667,10 @@ static int video_write(char *buf) ...@@ -4652,6 +4667,10 @@ static int video_write(char *buf)
if (video_supported == TPACPI_VIDEO_NONE) if (video_supported == TPACPI_VIDEO_NONE)
return -ENODEV; return -ENODEV;
/* Even reads can crash X.org, let alone writes... */
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
enable = 0; enable = 0;
disable = 0; disable = 0;
...@@ -6133,13 +6152,13 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = { ...@@ -6133,13 +6152,13 @@ static const struct tpacpi_quirk brightness_quirk_table[] __initconst = {
TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC), /* T43/p ATI */ TPACPI_Q_IBM('1', 'Y', TPACPI_BRGHT_Q_EC), /* T43/p ATI */
/* Models with ATI GPUs that can use ECNVRAM */ /* Models with ATI GPUs that can use ECNVRAM */
TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_EC), TPACPI_Q_IBM('1', 'R', TPACPI_BRGHT_Q_EC), /* R50,51 T40-42 */
TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), TPACPI_Q_IBM('1', 'Q', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), TPACPI_Q_IBM('7', '6', TPACPI_BRGHT_Q_EC), /* R52 */
TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), TPACPI_Q_IBM('7', '8', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
/* Models with Intel Extreme Graphics 2 */ /* Models with Intel Extreme Graphics 2 */
TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC), TPACPI_Q_IBM('1', 'U', TPACPI_BRGHT_Q_NOEC), /* X40 */
TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), TPACPI_Q_IBM('1', 'V', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC), TPACPI_Q_IBM('1', 'W', TPACPI_BRGHT_Q_ASK|TPACPI_BRGHT_Q_EC),
...@@ -6522,7 +6541,8 @@ static int volume_set_status(const u8 status) ...@@ -6522,7 +6541,8 @@ static int volume_set_status(const u8 status)
return volume_set_status_ec(status); return volume_set_status_ec(status);
} }
static int volume_set_mute_ec(const bool mute) /* returns < 0 on error, 0 on no change, 1 on change */
static int __volume_set_mute_ec(const bool mute)
{ {
int rc; int rc;
u8 s, n; u8 s, n;
...@@ -6537,22 +6557,37 @@ static int volume_set_mute_ec(const bool mute) ...@@ -6537,22 +6557,37 @@ static int volume_set_mute_ec(const bool mute)
n = (mute) ? s | TP_EC_AUDIO_MUTESW_MSK : n = (mute) ? s | TP_EC_AUDIO_MUTESW_MSK :
s & ~TP_EC_AUDIO_MUTESW_MSK; s & ~TP_EC_AUDIO_MUTESW_MSK;
if (n != s) if (n != s) {
rc = volume_set_status_ec(n); rc = volume_set_status_ec(n);
if (!rc)
rc = 1;
}
unlock: unlock:
mutex_unlock(&volume_mutex); mutex_unlock(&volume_mutex);
return rc; return rc;
} }
static int volume_alsa_set_mute(const bool mute)
{
dbg_printk(TPACPI_DBG_MIXER, "ALSA: trying to %smute\n",
(mute) ? "" : "un");
return __volume_set_mute_ec(mute);
}
static int volume_set_mute(const bool mute) static int volume_set_mute(const bool mute)
{ {
int rc;
dbg_printk(TPACPI_DBG_MIXER, "trying to %smute\n", dbg_printk(TPACPI_DBG_MIXER, "trying to %smute\n",
(mute) ? "" : "un"); (mute) ? "" : "un");
return volume_set_mute_ec(mute);
rc = __volume_set_mute_ec(mute);
return (rc < 0) ? rc : 0;
} }
static int volume_set_volume_ec(const u8 vol) /* returns < 0 on error, 0 on no change, 1 on change */
static int __volume_set_volume_ec(const u8 vol)
{ {
int rc; int rc;
u8 s, n; u8 s, n;
...@@ -6569,19 +6604,22 @@ static int volume_set_volume_ec(const u8 vol) ...@@ -6569,19 +6604,22 @@ static int volume_set_volume_ec(const u8 vol)
n = (s & ~TP_EC_AUDIO_LVL_MSK) | vol; n = (s & ~TP_EC_AUDIO_LVL_MSK) | vol;
if (n != s) if (n != s) {
rc = volume_set_status_ec(n); rc = volume_set_status_ec(n);
if (!rc)
rc = 1;
}
unlock: unlock:
mutex_unlock(&volume_mutex); mutex_unlock(&volume_mutex);
return rc; return rc;
} }
static int volume_set_volume(const u8 vol) static int volume_alsa_set_volume(const u8 vol)
{ {
dbg_printk(TPACPI_DBG_MIXER, dbg_printk(TPACPI_DBG_MIXER,
"trying to set volume level to %hu\n", vol); "ALSA: trying to set volume level to %hu\n", vol);
return volume_set_volume_ec(vol); return __volume_set_volume_ec(vol);
} }
static void volume_alsa_notify_change(void) static void volume_alsa_notify_change(void)
...@@ -6628,7 +6666,7 @@ static int volume_alsa_vol_get(struct snd_kcontrol *kcontrol, ...@@ -6628,7 +6666,7 @@ static int volume_alsa_vol_get(struct snd_kcontrol *kcontrol,
static int volume_alsa_vol_put(struct snd_kcontrol *kcontrol, static int volume_alsa_vol_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
return volume_set_volume(ucontrol->value.integer.value[0]); return volume_alsa_set_volume(ucontrol->value.integer.value[0]);
} }
#define volume_alsa_mute_info snd_ctl_boolean_mono_info #define volume_alsa_mute_info snd_ctl_boolean_mono_info
...@@ -6651,7 +6689,7 @@ static int volume_alsa_mute_get(struct snd_kcontrol *kcontrol, ...@@ -6651,7 +6689,7 @@ static int volume_alsa_mute_get(struct snd_kcontrol *kcontrol,
static int volume_alsa_mute_put(struct snd_kcontrol *kcontrol, static int volume_alsa_mute_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
return volume_set_mute(!ucontrol->value.integer.value[0]); return volume_alsa_set_mute(!ucontrol->value.integer.value[0]);
} }
static struct snd_kcontrol_new volume_alsa_control_vol __devinitdata = { static struct snd_kcontrol_new volume_alsa_control_vol __devinitdata = {
...@@ -8477,9 +8515,10 @@ static int __init ibm_init(struct ibm_init_struct *iibm) ...@@ -8477,9 +8515,10 @@ static int __init ibm_init(struct ibm_init_struct *iibm)
"%s installed\n", ibm->name); "%s installed\n", ibm->name);
if (ibm->read) { if (ibm->read) {
mode_t mode; mode_t mode = iibm->base_procfs_mode;
mode = S_IRUGO; if (!mode)
mode = S_IRUGO;
if (ibm->write) if (ibm->write)
mode |= S_IWUSR; mode |= S_IWUSR;
entry = proc_create_data(ibm->name, mode, proc_dir, entry = proc_create_data(ibm->name, mode, proc_dir,
...@@ -8670,6 +8709,7 @@ static struct ibm_init_struct ibms_init[] __initdata = { ...@@ -8670,6 +8709,7 @@ static struct ibm_init_struct ibms_init[] __initdata = {
#ifdef CONFIG_THINKPAD_ACPI_VIDEO #ifdef CONFIG_THINKPAD_ACPI_VIDEO
{ {
.init = video_init, .init = video_init,
.base_procfs_mode = S_IRUSR,
.data = &video_driver_data, .data = &video_driver_data,
}, },
#endif #endif
...@@ -9032,6 +9072,9 @@ static int __init thinkpad_acpi_module_init(void) ...@@ -9032,6 +9072,9 @@ static int __init thinkpad_acpi_module_init(void)
return ret; return ret;
} }
} }
tpacpi_lifecycle = TPACPI_LIFE_RUNNING;
ret = input_register_device(tpacpi_inputdev); ret = input_register_device(tpacpi_inputdev);
if (ret < 0) { if (ret < 0) {
printk(TPACPI_ERR "unable to register input device\n"); printk(TPACPI_ERR "unable to register input device\n");
...@@ -9041,7 +9084,6 @@ static int __init thinkpad_acpi_module_init(void) ...@@ -9041,7 +9084,6 @@ static int __init thinkpad_acpi_module_init(void)
tp_features.input_device_registered = 1; tp_features.input_device_registered = 1;
} }
tpacpi_lifecycle = TPACPI_LIFE_RUNNING;
return 0; return 0;
} }
......
...@@ -814,21 +814,23 @@ static void toshiba_acpi_notify(acpi_handle handle, u32 event, void *context) ...@@ -814,21 +814,23 @@ static void toshiba_acpi_notify(acpi_handle handle, u32 event, void *context)
if (hci_result == HCI_SUCCESS) { if (hci_result == HCI_SUCCESS) {
if (value == 0x100) if (value == 0x100)
continue; continue;
else if (value & 0x80) { /* act on key press; ignore key release */
key = toshiba_acpi_get_entry_by_scancode if (value & 0x80)
(value & ~0x80); continue;
if (!key) {
printk(MY_INFO "Unknown key %x\n", key = toshiba_acpi_get_entry_by_scancode
value & ~0x80); (value);
continue; if (!key) {
} printk(MY_INFO "Unknown key %x\n",
input_report_key(toshiba_acpi.hotkey_dev, value);
key->keycode, 1); continue;
input_sync(toshiba_acpi.hotkey_dev);
input_report_key(toshiba_acpi.hotkey_dev,
key->keycode, 0);
input_sync(toshiba_acpi.hotkey_dev);
} }
input_report_key(toshiba_acpi.hotkey_dev,
key->keycode, 1);
input_sync(toshiba_acpi.hotkey_dev);
input_report_key(toshiba_acpi.hotkey_dev,
key->keycode, 0);
input_sync(toshiba_acpi.hotkey_dev);
} else if (hci_result == HCI_NOT_SUPPORTED) { } else if (hci_result == HCI_NOT_SUPPORTED) {
/* This is a workaround for an unresolved issue on /* This is a workaround for an unresolved issue on
* some machines where system events sporadically * some machines where system events sporadically
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment