Commit ef152de5 authored by Stelian Pop's avatar Stelian Pop Committed by Linus Torvalds

[PATCH] sonypi driver update (PM and DMI VGN-)

This updates the sonypi driver by:
 * fixing the power management handling, using the new device
   model PM scheme.

 * adds "VGN-" as a DMI search pattern for a Sony Vaio laptop.

Florian Lohoff reported the power management issue and tested the
patch.

Many users reported the DMI name issue, including Till Busch who
made a patch for dmi_scan.c.
Signed-off-by: default avatarStelian Pop <stelian@popies.net>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent d2644a78
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/dmi.h> #include <linux/dmi.h>
#include <linux/sysdev.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -603,11 +604,9 @@ struct miscdevice sonypi_misc_device = { ...@@ -603,11 +604,9 @@ struct miscdevice sonypi_misc_device = {
}; };
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int sonypi_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data) { static int old_camera_power;
static int old_camera_power;
switch (rqst) { static int sonypi_suspend(struct sys_device *dev, u32 state) {
case PM_SUSPEND:
sonypi_call2(0x81, 0); /* make sure we don't get any more events */ sonypi_call2(0x81, 0); /* make sure we don't get any more events */
if (camera) { if (camera) {
old_camera_power = sonypi_device.camera_power; old_camera_power = sonypi_device.camera_power;
...@@ -620,8 +619,10 @@ static int sonypi_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data) ...@@ -620,8 +619,10 @@ static int sonypi_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
/* disable ACPI mode */ /* disable ACPI mode */
if (!SONYPI_ACPI_ACTIVE && fnkeyinit) if (!SONYPI_ACPI_ACTIVE && fnkeyinit)
outb(0xf1, 0xb2); outb(0xf1, 0xb2);
break; return 0;
case PM_RESUME: }
static int sonypi_resume(struct sys_device *dev) {
/* Enable ACPI mode to get Fn key events */ /* Enable ACPI mode to get Fn key events */
if (!SONYPI_ACPI_ACTIVE && fnkeyinit) if (!SONYPI_ACPI_ACTIVE && fnkeyinit)
outb(0xf0, 0xb2); outb(0xf0, 0xb2);
...@@ -637,10 +638,34 @@ static int sonypi_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data) ...@@ -637,10 +638,34 @@ static int sonypi_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
sonypi_call1(0x82); sonypi_call1(0x82);
if (camera && old_camera_power) if (camera && old_camera_power)
sonypi_camera_on(); sonypi_camera_on();
return 0;
}
/* Old PM scheme */
static int sonypi_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data) {
switch (rqst) {
case PM_SUSPEND:
sonypi_suspend(NULL, 0);
break;
case PM_RESUME:
sonypi_resume(NULL);
break; break;
} }
return 0; return 0;
} }
/* New PM scheme (device model) */
static struct sysdev_class sonypi_sysclass = {
set_kset_name("sonypi"),
.suspend = sonypi_suspend,
.resume = sonypi_resume,
};
static struct sys_device sonypi_sysdev = {
.id = 0,
.cls = &sonypi_sysclass,
};
#endif #endif
static int __devinit sonypi_probe(struct pci_dev *pcidev) { static int __devinit sonypi_probe(struct pci_dev *pcidev) {
...@@ -735,6 +760,21 @@ static int __devinit sonypi_probe(struct pci_dev *pcidev) { ...@@ -735,6 +760,21 @@ static int __devinit sonypi_probe(struct pci_dev *pcidev) {
goto out3; goto out3;
} }
#ifdef CONFIG_PM
sonypi_device.pm = pm_register(PM_PCI_DEV, 0, sonypi_pm_callback);
if (sysdev_class_register(&sonypi_sysclass) != 0) {
printk(KERN_ERR "sonypi: sysdev_class_register failed\n");
ret = -ENODEV;
goto out4;
}
if (sysdev_register(&sonypi_sysdev) != 0) {
printk(KERN_ERR "sonypi: sysdev_register failed\n");
ret = -ENODEV;
goto out5;
}
#endif
/* Enable ACPI mode to get Fn key events */ /* Enable ACPI mode to get Fn key events */
if (!SONYPI_ACPI_ACTIVE && fnkeyinit) if (!SONYPI_ACPI_ACTIVE && fnkeyinit)
outb(0xf0, 0xb2); outb(0xf0, 0xb2);
...@@ -744,7 +784,7 @@ static int __devinit sonypi_probe(struct pci_dev *pcidev) { ...@@ -744,7 +784,7 @@ static int __devinit sonypi_probe(struct pci_dev *pcidev) {
SONYPI_DRIVER_MINORVERSION); SONYPI_DRIVER_MINORVERSION);
printk(KERN_INFO "sonypi: detected %s model, " printk(KERN_INFO "sonypi: detected %s model, "
"verbose = %d, fnkeyinit = %s, camera = %s, " "verbose = %d, fnkeyinit = %s, camera = %s, "
"compat = %s, mask = 0x%08lx, useinput = %s\n", "compat = %s, mask = 0x%08lx, useinput = %s, acpi = %s\n",
(sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) ? (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) ?
"type1" : "type2", "type1" : "type2",
verbose, verbose,
...@@ -752,10 +792,12 @@ static int __devinit sonypi_probe(struct pci_dev *pcidev) { ...@@ -752,10 +792,12 @@ static int __devinit sonypi_probe(struct pci_dev *pcidev) {
camera ? "on" : "off", camera ? "on" : "off",
compat ? "on" : "off", compat ? "on" : "off",
mask, mask,
useinput ? "on" : "off"); useinput ? "on" : "off",
SONYPI_ACPI_ACTIVE ? "on" : "off");
printk(KERN_INFO "sonypi: enabled at irq=%d, port1=0x%x, port2=0x%x\n", printk(KERN_INFO "sonypi: enabled at irq=%d, port1=0x%x, port2=0x%x\n",
sonypi_device.irq, sonypi_device.irq,
sonypi_device.ioport1, sonypi_device.ioport2); sonypi_device.ioport1, sonypi_device.ioport2);
if (minor == -1) if (minor == -1)
printk(KERN_INFO "sonypi: device allocated minor is %d\n", printk(KERN_INFO "sonypi: device allocated minor is %d\n",
sonypi_misc_device.minor); sonypi_misc_device.minor);
...@@ -777,12 +819,14 @@ static int __devinit sonypi_probe(struct pci_dev *pcidev) { ...@@ -777,12 +819,14 @@ static int __devinit sonypi_probe(struct pci_dev *pcidev) {
} }
#endif /* SONYPI_USE_INPUT */ #endif /* SONYPI_USE_INPUT */
#ifdef CONFIG_PM
sonypi_device.pm = pm_register(PM_PCI_DEV, 0, sonypi_pm_callback);
#endif
return 0; return 0;
#ifdef CONFIG_PM
out5:
sysdev_class_unregister(&sonypi_sysclass);
out4:
free_irq(sonypi_device.irq, sonypi_irq);
#endif
out3: out3:
release_region(sonypi_device.ioport1, sonypi_device.region_size); release_region(sonypi_device.ioport1, sonypi_device.region_size);
out2: out2:
...@@ -795,6 +839,9 @@ static void __devexit sonypi_remove(void) { ...@@ -795,6 +839,9 @@ static void __devexit sonypi_remove(void) {
#ifdef CONFIG_PM #ifdef CONFIG_PM
pm_unregister(sonypi_device.pm); pm_unregister(sonypi_device.pm);
sysdev_unregister(&sonypi_sysdev);
sysdev_class_unregister(&sonypi_sysclass);
#endif #endif
sonypi_call2(0x81, 0); /* make sure we don't get any more events */ sonypi_call2(0x81, 0); /* make sure we don't get any more events */
...@@ -829,6 +876,13 @@ static struct dmi_system_id __initdata sonypi_dmi_table[] = { ...@@ -829,6 +876,13 @@ static struct dmi_system_id __initdata sonypi_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "PCG-"), DMI_MATCH(DMI_PRODUCT_NAME, "PCG-"),
}, },
}, },
{
.ident = "Sony Vaio",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, "VGN-"),
},
},
{ } { }
}; };
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
#define SONYPI_DRIVER_MAJORVERSION 1 #define SONYPI_DRIVER_MAJORVERSION 1
#define SONYPI_DRIVER_MINORVERSION 22 #define SONYPI_DRIVER_MINORVERSION 23
#define SONYPI_DEVICE_MODEL_TYPE1 1 #define SONYPI_DEVICE_MODEL_TYPE1 1
#define SONYPI_DEVICE_MODEL_TYPE2 2 #define SONYPI_DEVICE_MODEL_TYPE2 2
......
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