summaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/Kconfig20
-rw-r--r--drivers/misc/asus-laptop.c5
-rw-r--r--drivers/misc/msi-laptop.c2
-rw-r--r--drivers/misc/sony-laptop.c28
-rw-r--r--drivers/misc/thinkpad_acpi.c166
-rw-r--r--drivers/misc/thinkpad_acpi.h1
6 files changed, 127 insertions, 95 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index a26655881e6a..73e248fb2ff1 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -202,25 +202,5 @@ config THINKPAD_ACPI_BAY
If you are not sure, say Y here.
-config THINKPAD_ACPI_INPUT_ENABLED
- bool "Enable input layer support by default"
- depends on THINKPAD_ACPI
- default n
- ---help---
- This option enables thinkpad-acpi hot key handling over the input
- layer at driver load time. When it is unset, the driver does not
- enable hot key handling by default, and also starts up with a mostly
- empty keymap.
-
- This option should be enabled if you have a new enough HAL or other
- userspace support that properly handles the thinkpad-acpi event
- device. It auto-tunes the hot key support to those reported by the
- firmware and enables it automatically.
-
- If unsure, say N here to retain the old behaviour of ibm-acpi, and
- thinkpad-acpi up to kernel 2.6.21: userspace will have to enable and
- set up the thinkpad-acpi hot key handling using the sysfs interace
- after loading the driver.
-
endif # MISC_DEVICES
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c
index d0fc4fd212e6..7dce318df1bd 100644
--- a/drivers/misc/asus-laptop.c
+++ b/drivers/misc/asus-laptop.c
@@ -732,7 +732,7 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
lcd_blank(FB_BLANK_POWERDOWN);
}
- acpi_bus_generate_event(hotk->device, event,
+ acpi_bus_generate_proc_event(hotk->device, event,
hotk->event_count[event % 128]++);
return;
@@ -1072,7 +1072,8 @@ static void asus_backlight_exit(void)
}
#define ASUS_LED_UNREGISTER(object) \
- led_classdev_unregister(&object##_led)
+ if (object##_led.dev) \
+ led_classdev_unregister(&object##_led)
static void asus_led_exit(void)
{
diff --git a/drivers/misc/msi-laptop.c b/drivers/misc/msi-laptop.c
index 932a415197b3..349be934db7c 100644
--- a/drivers/misc/msi-laptop.c
+++ b/drivers/misc/msi-laptop.c
@@ -353,7 +353,7 @@ static int __init msi_init(void)
if (IS_ERR(msibl_device))
return PTR_ERR(msibl_device);
- msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1,
+ msibl_device->props.max_brightness = MSI_LCD_LEVEL_MAX-1;
ret = platform_driver_register(&msipf_driver);
if (ret)
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
index 91da6880ae93..d38ddce592c0 100644
--- a/drivers/misc/sony-laptop.c
+++ b/drivers/misc/sony-laptop.c
@@ -856,6 +856,15 @@ static struct dmi_system_id sony_nc_ids[] = {
},
},
{
+ .ident = "Sony Vaio FZ Series",
+ .callback = sony_nc_C_enable,
+ .driver_data = sony_C_events,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ"),
+ },
+ },
+ {
.ident = "Sony Vaio C Series",
.callback = sony_nc_C_enable,
.driver_data = sony_C_events,
@@ -904,7 +913,7 @@ static void sony_acpi_notify(acpi_handle handle, u32 event, void *data)
dprintk("sony_acpi_notify, event: 0x%.2x\n", ev);
sony_laptop_report_input_event(ev);
- acpi_bus_generate_event(sony_nc_acpi_device, 1, ev);
+ acpi_bus_generate_proc_event(sony_nc_acpi_device, 1, ev);
}
static acpi_status sony_walk_callback(acpi_handle handle, u32 level,
@@ -2292,7 +2301,7 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id)
found:
sony_laptop_report_input_event(device_event);
- acpi_bus_generate_event(spic_dev.acpi_dev, 1, device_event);
+ acpi_bus_generate_proc_event(spic_dev.acpi_dev, 1, device_event);
sonypi_compat_report_event(device_event);
return IRQ_HANDLED;
@@ -2308,8 +2317,6 @@ static int sony_pic_remove(struct acpi_device *device, int type)
struct sony_pic_ioport *io, *tmp_io;
struct sony_pic_irq *irq, *tmp_irq;
- sonypi_compat_exit();
-
if (sony_pic_disable(device)) {
printk(KERN_ERR DRV_PFX "Couldn't disable device.\n");
return -ENXIO;
@@ -2319,6 +2326,8 @@ static int sony_pic_remove(struct acpi_device *device, int type)
release_region(spic_dev.cur_ioport->io.minimum,
spic_dev.cur_ioport->io.address_length);
+ sonypi_compat_exit();
+
sony_laptop_remove_input();
/* pf attrs */
@@ -2384,6 +2393,9 @@ static int sony_pic_add(struct acpi_device *device)
goto err_free_resources;
}
+ if (sonypi_compat_init())
+ goto err_remove_input;
+
/* request io port */
list_for_each_entry(io, &spic_dev.ioports, list) {
if (request_region(io->io.minimum, io->io.address_length,
@@ -2398,7 +2410,7 @@ static int sony_pic_add(struct acpi_device *device)
if (!spic_dev.cur_ioport) {
printk(KERN_ERR DRV_PFX "Failed to request_region.\n");
result = -ENODEV;
- goto err_remove_input;
+ goto err_remove_compat;
}
/* request IRQ */
@@ -2438,9 +2450,6 @@ static int sony_pic_add(struct acpi_device *device)
if (result)
goto err_remove_pf;
- if (sonypi_compat_init())
- goto err_remove_pf;
-
return 0;
err_remove_pf:
@@ -2456,6 +2465,9 @@ err_release_region:
release_region(spic_dev.cur_ioport->io.minimum,
spic_dev.cur_ioport->io.address_length);
+err_remove_compat:
+ sonypi_compat_exit();
+
err_remove_input:
sony_laptop_remove_input();
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index f6cd34a3dbac..0222bbaf7b76 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -21,7 +21,7 @@
* 02110-1301, USA.
*/
-#define IBM_VERSION "0.15"
+#define IBM_VERSION "0.16"
#define TPACPI_SYSFS_VERSION 0x010000
/*
@@ -906,9 +906,26 @@ static ssize_t hotkey_radio_sw_show(struct device *dev,
static struct device_attribute dev_attr_hotkey_radio_sw =
__ATTR(hotkey_radio_sw, S_IRUGO, hotkey_radio_sw_show, NULL);
+/* sysfs hotkey report_mode -------------------------------------------- */
+static ssize_t hotkey_report_mode_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ (hotkey_report_mode != 0) ? hotkey_report_mode : 1);
+}
+
+static struct device_attribute dev_attr_hotkey_report_mode =
+ __ATTR(hotkey_report_mode, S_IRUGO, hotkey_report_mode_show, NULL);
+
/* --------------------------------------------------------------------- */
-static struct attribute *hotkey_mask_attributes[] = {
+static struct attribute *hotkey_attributes[] __initdata = {
+ &dev_attr_hotkey_enable.attr,
+ &dev_attr_hotkey_report_mode.attr,
+};
+
+static struct attribute *hotkey_mask_attributes[] __initdata = {
&dev_attr_hotkey_mask.attr,
&dev_attr_hotkey_bios_enabled.attr,
&dev_attr_hotkey_bios_mask.attr,
@@ -987,11 +1004,12 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
str_supported(tp_features.hotkey));
if (tp_features.hotkey) {
- hotkey_dev_attributes = create_attr_set(7, NULL);
+ hotkey_dev_attributes = create_attr_set(8, NULL);
if (!hotkey_dev_attributes)
return -ENOMEM;
- res = add_to_attr_set(hotkey_dev_attributes,
- &dev_attr_hotkey_enable.attr);
+ res = add_many_to_attr_set(hotkey_dev_attributes,
+ hotkey_attributes,
+ ARRAY_SIZE(hotkey_attributes));
if (res)
return res;
@@ -1055,11 +1073,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
TPACPI_HOTKEY_MAP_SIZE);
}
-#ifndef CONFIG_THINKPAD_ACPI_INPUT_ENABLED
- for (i = 0; i < 12; i++)
- hotkey_keycode_map[i] = KEY_UNKNOWN;
-#endif /* ! CONFIG_THINKPAD_ACPI_INPUT_ENABLED */
-
set_bit(EV_KEY, tpacpi_inputdev->evbit);
set_bit(EV_MSC, tpacpi_inputdev->evbit);
set_bit(MSC_SCAN, tpacpi_inputdev->mscbit);
@@ -1081,14 +1094,17 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
set_bit(SW_RADIO, tpacpi_inputdev->swbit);
}
-#ifdef CONFIG_THINKPAD_ACPI_INPUT_ENABLED
dbg_printk(TPACPI_DBG_INIT,
"enabling hot key handling\n");
res = hotkey_set(1, (hotkey_all_mask & ~hotkey_reserved_mask)
| hotkey_orig_mask);
if (res)
return res;
-#endif /* CONFIG_THINKPAD_ACPI_INPUT_ENABLED */
+
+ dbg_printk(TPACPI_DBG_INIT,
+ "legacy hot key reporting over procfs %s\n",
+ (hotkey_report_mode < 2) ?
+ "enabled" : "disabled");
}
return (tp_features.hotkey)? 0 : 1;
@@ -1142,58 +1158,65 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)
{
u32 hkey;
unsigned int keycode, scancode;
- int sendacpi = 1;
+ int send_acpi_ev = 0;
if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
- if (tpacpi_inputdev->users > 0) {
- switch (hkey >> 12) {
- case 1:
- /* 0x1000-0x1FFF: key presses */
- scancode = hkey & 0xfff;
- if (scancode > 0 && scancode < 0x21) {
- scancode--;
- keycode = hotkey_keycode_map[scancode];
- tpacpi_input_send_key(scancode, keycode);
- sendacpi = (keycode == KEY_RESERVED
- || keycode == KEY_UNKNOWN);
- } else {
- printk(IBM_ERR
- "hotkey 0x%04x out of range for keyboard map\n",
- hkey);
- }
- break;
- case 5:
- /* 0x5000-0x5FFF: LID */
- /* we don't handle it through this path, just
- * eat up known LID events */
- if (hkey != 0x5001 && hkey != 0x5002) {
- printk(IBM_ERR
- "unknown LID-related hotkey event: 0x%04x\n",
- hkey);
- }
+ switch (hkey >> 12) {
+ case 1:
+ /* 0x1000-0x1FFF: key presses */
+ scancode = hkey & 0xfff;
+ if (scancode > 0 && scancode < 0x21) {
+ scancode--;
+ keycode = hotkey_keycode_map[scancode];
+ tpacpi_input_send_key(scancode, keycode);
+ } else {
+ printk(IBM_ERR
+ "hotkey 0x%04x out of range for keyboard map\n",
+ hkey);
+ send_acpi_ev = 1;
+ }
+ break;
+ case 5:
+ /* 0x5000-0x5FFF: LID */
+ /* we don't handle it through this path, just
+ * eat up known LID events */
+ if (hkey != 0x5001 && hkey != 0x5002) {
+ printk(IBM_ERR
+ "unknown LID-related hotkey event: 0x%04x\n",
+ hkey);
+ send_acpi_ev = 1;
+ }
+ break;
+ case 7:
+ /* 0x7000-0x7FFF: misc */
+ if (tp_features.hotkey_wlsw && hkey == 0x7000) {
+ tpacpi_input_send_radiosw();
break;
- case 7:
- /* 0x7000-0x7FFF: misc */
- if (tp_features.hotkey_wlsw && hkey == 0x7000) {
- tpacpi_input_send_radiosw();
- sendacpi = 0;
- break;
- }
- /* fallthrough to default */
- default:
- /* case 2: dock-related */
- /* 0x2305 - T43 waking up due to bay lever eject while aslept */
- /* case 3: ultra-bay related. maybe bay in dock? */
- /* 0x3003 - T43 after wake up by bay lever eject (0x2305) */
- printk(IBM_NOTICE "unhandled hotkey event 0x%04x\n", hkey);
}
+ /* fallthrough to default */
+ default:
+ /* case 2: dock-related */
+ /* 0x2305 - T43 waking up due to bay lever eject while aslept */
+ /* case 3: ultra-bay related. maybe bay in dock? */
+ /* 0x3003 - T43 after wake up by bay lever eject (0x2305) */
+ printk(IBM_NOTICE "unhandled HKEY event 0x%04x\n", hkey);
+ send_acpi_ev = 1;
}
-
- if (sendacpi)
- acpi_bus_generate_event(ibm->acpi->device, event, hkey);
} else {
printk(IBM_ERR "unknown hotkey notification event %d\n", event);
- acpi_bus_generate_event(ibm->acpi->device, event, 0);
+ hkey = 0;
+ send_acpi_ev = 1;
+ }
+
+ /* Legacy events */
+ if (send_acpi_ev || hotkey_report_mode < 2)
+ acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey);
+
+ /* netlink events */
+ if (send_acpi_ev) {
+ acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
+ ibm->acpi->device->dev.bus_id,
+ event, hkey);
}
}
@@ -2162,22 +2185,27 @@ static void dock_notify(struct ibm_struct *ibm, u32 event)
int docked = dock_docked();
int pci = ibm->acpi->hid && ibm->acpi->device &&
acpi_match_device_ids(ibm->acpi->device, ibm_pci_device_ids);
+ int data;
if (event == 1 && !pci) /* 570 */
- acpi_bus_generate_event(ibm->acpi->device, event, 1); /* button */
+ data = 1; /* button */
else if (event == 1 && pci) /* 570 */
- acpi_bus_generate_event(ibm->acpi->device, event, 3); /* dock */
+ data = 3; /* dock */
else if (event == 3 && docked)
- acpi_bus_generate_event(ibm->acpi->device, event, 1); /* button */
+ data = 1; /* button */
else if (event == 3 && !docked)
- acpi_bus_generate_event(ibm->acpi->device, event, 2); /* undock */
+ data = 2; /* undock */
else if (event == 0 && docked)
- acpi_bus_generate_event(ibm->acpi->device, event, 3); /* dock */
+ data = 3; /* dock */
else {
printk(IBM_ERR "unknown dock event %d, status %d\n",
event, _sta(dock_handle));
- acpi_bus_generate_event(ibm->acpi->device, event, 0); /* unknown */
+ data = 0; /* unknown */
}
+ acpi_bus_generate_proc_event(ibm->acpi->device, event, data);
+ acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
+ ibm->acpi->device->dev.bus_id,
+ event, data);
}
static int dock_read(char *p)
@@ -2275,7 +2303,10 @@ static int __init bay_init(struct ibm_init_struct *iibm)
static void bay_notify(struct ibm_struct *ibm, u32 event)
{
- acpi_bus_generate_event(ibm->acpi->device, event, 0);
+ acpi_bus_generate_proc_event(ibm->acpi->device, event, 0);
+ acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class,
+ ibm->acpi->device->dev.bus_id,
+ event, 0);
}
#define bay_occupied(b) (_sta(b##_handle) & 1)
@@ -4615,6 +4646,9 @@ module_param_named(fan_control, fan_control_allowed, bool, 0);
static int brightness_mode;
module_param_named(brightness_mode, brightness_mode, int, 0);
+static unsigned int hotkey_report_mode;
+module_param(hotkey_report_mode, uint, 0);
+
#define IBM_PARAM(feature) \
module_param_call(feature, set_ibm_param, NULL, NULL, 0)
@@ -4640,6 +4674,10 @@ static int __init thinkpad_acpi_module_init(void)
{
int ret, i;
+ /* Parameter checking */
+ if (hotkey_report_mode > 2)
+ return -EINVAL;
+
/* Driver-level probe */
get_thinkpad_model_data(&thinkpad_id);
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index eee8809a50d9..082a1cbc16c0 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -181,6 +181,7 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv);
static int experimental;
static u32 dbg_level;
static int force_load;
+static unsigned int hotkey_report_mode;
static int thinkpad_acpi_module_init(void);
static void thinkpad_acpi_module_exit(void);