summaryrefslogtreecommitdiffstats
path: root/drivers/acpi/ibm_acpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/ibm_acpi.c')
-rw-r--r--drivers/acpi/ibm_acpi.c47
1 files changed, 42 insertions, 5 deletions
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index 4cc534e36e81..dc1096608f43 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -86,6 +86,7 @@
#include <linux/proc_fs.h>
#include <linux/backlight.h>
+#include <linux/fb.h>
#include <asm/uaccess.h>
#include <linux/dmi.h>
@@ -157,6 +158,7 @@ IBM_HANDLE(dock, root, "\\_SB.GDCK", /* X30, X31, X40 */
"\\_SB.PCI.ISA.SLCE", /* 570 */
); /* A21e,G4x,R30,R31,R32,R40,R40e,R50e */
#endif
+#ifdef CONFIG_ACPI_IBM_BAY
IBM_HANDLE(bay, root, "\\_SB.PCI.IDE.SECN.MAST", /* 570 */
"\\_SB.PCI0.IDE0.IDES.IDSM", /* 600e/x, 770e, 770x */
"\\_SB.PCI0.SATA.SCND.MSTR", /* T60, X60, Z60 */
@@ -174,6 +176,7 @@ IBM_HANDLE(bay2, root, "\\_SB.PCI0.IDE0.PRIM.SLAV", /* A3x, R32 */
IBM_HANDLE(bay2_ej, bay2, "_EJ3", /* 600e/x, 770e, A3x */
"_EJ0", /* 770x */
); /* all others */
+#endif /* CONFIG_ACPI_IBM_BAY */
/* don't list other alternatives as we install a notify handler on the 570 */
IBM_HANDLE(pci, root, "\\_SB.PCI"); /* 570 */
@@ -1044,6 +1047,7 @@ static int light_write(char *buf)
return 0;
}
+#if defined(CONFIG_ACPI_IBM_DOCK) || defined(CONFIG_ACPI_IBM_BAY)
static int _sta(acpi_handle handle)
{
int status;
@@ -1053,6 +1057,7 @@ static int _sta(acpi_handle handle)
return status;
}
+#endif
#ifdef CONFIG_ACPI_IBM_DOCK
#define dock_docked() (_sta(dock_handle) & 1)
@@ -1119,6 +1124,7 @@ static void dock_notify(struct ibm_struct *ibm, u32 event)
}
#endif
+#ifdef CONFIG_ACPI_IBM_BAY
static int bay_status_supported;
static int bay_status2_supported;
static int bay_eject_supported;
@@ -1194,6 +1200,7 @@ static void bay_notify(struct ibm_struct *ibm, u32 event)
{
acpi_bus_generate_event(ibm->device, event, 0);
}
+#endif /* CONFIG_ACPI_IBM_BAY */
static int cmos_read(char *p)
{
@@ -1701,7 +1708,10 @@ static int brightness_write(char *buf)
static int brightness_update_status(struct backlight_device *bd)
{
- return brightness_set(bd->props.brightness);
+ return brightness_set(
+ (bd->props.fb_blank == FB_BLANK_UNBLANK &&
+ bd->props.power == FB_BLANK_UNBLANK) ?
+ bd->props.brightness : 0);
}
static struct backlight_ops ibm_backlight_data = {
@@ -1711,6 +1721,12 @@ static struct backlight_ops ibm_backlight_data = {
static int brightness_init(void)
{
+ int b;
+
+ b = brightness_get(NULL);
+ if (b < 0)
+ return b;
+
ibm_backlight_device = backlight_device_register("ibm", NULL, NULL,
&ibm_backlight_data);
if (IS_ERR(ibm_backlight_device)) {
@@ -1718,7 +1734,9 @@ static int brightness_init(void)
return PTR_ERR(ibm_backlight_device);
}
- ibm_backlight_device->props.max_brightness = 7;
+ ibm_backlight_device->props.max_brightness = 7;
+ ibm_backlight_device->props.brightness = b;
+ backlight_update_status(ibm_backlight_device);
return 0;
}
@@ -2353,6 +2371,7 @@ static struct ibm_struct ibms[] = {
.type = ACPI_SYSTEM_NOTIFY,
},
#endif
+#ifdef CONFIG_ACPI_IBM_BAY
{
.name = "bay",
.init = bay_init,
@@ -2362,6 +2381,7 @@ static struct ibm_struct ibms[] = {
.handle = &bay_handle,
.type = ACPI_SYSTEM_NOTIFY,
},
+#endif /* CONFIG_ACPI_IBM_BAY */
{
.name = "cmos",
.read = cmos_read,
@@ -2487,7 +2507,7 @@ static int __init setup_notify(struct ibm_struct *ibm)
ret = acpi_bus_get_device(*ibm->handle, &ibm->device);
if (ret < 0) {
printk(IBM_ERR "%s device not present\n", ibm->name);
- return 0;
+ return -ENODEV;
}
acpi_driver_data(ibm->device) = ibm;
@@ -2496,8 +2516,13 @@ static int __init setup_notify(struct ibm_struct *ibm)
status = acpi_install_notify_handler(*ibm->handle, ibm->type,
dispatch_notify, ibm);
if (ACPI_FAILURE(status)) {
- printk(IBM_ERR "acpi_install_notify_handler(%s) failed: %d\n",
- ibm->name, status);
+ if (status == AE_ALREADY_EXISTS) {
+ printk(IBM_NOTICE "another device driver is already handling %s events\n",
+ ibm->name);
+ } else {
+ printk(IBM_ERR "acpi_install_notify_handler(%s) failed: %d\n",
+ ibm->name, status);
+ }
return -ENODEV;
}
ibm->notify_installed = 1;
@@ -2533,6 +2558,8 @@ static int __init register_driver(struct ibm_struct *ibm)
return ret;
}
+static void ibm_exit(struct ibm_struct *ibm);
+
static int __init ibm_init(struct ibm_struct *ibm)
{
int ret;
@@ -2574,6 +2601,12 @@ static int __init ibm_init(struct ibm_struct *ibm)
if (ibm->notify) {
ret = setup_notify(ibm);
+ if (ret == -ENODEV) {
+ printk(IBM_NOTICE "disabling subdriver %s\n",
+ ibm->name);
+ ibm_exit(ibm);
+ return 0;
+ }
if (ret < 0)
return ret;
}
@@ -2647,7 +2680,9 @@ IBM_PARAM(light);
#ifdef CONFIG_ACPI_IBM_DOCK
IBM_PARAM(dock);
#endif
+#ifdef CONFIG_ACPI_IBM_BAY
IBM_PARAM(bay);
+#endif /* CONFIG_ACPI_IBM_BAY */
IBM_PARAM(cmos);
IBM_PARAM(led);
IBM_PARAM(beep);
@@ -2723,12 +2758,14 @@ static int __init acpi_ibm_init(void)
IBM_HANDLE_INIT(dock);
#endif
IBM_HANDLE_INIT(pci);
+#ifdef CONFIG_ACPI_IBM_BAY
IBM_HANDLE_INIT(bay);
if (bay_handle)
IBM_HANDLE_INIT(bay_ej);
IBM_HANDLE_INIT(bay2);
if (bay2_handle)
IBM_HANDLE_INIT(bay2_ej);
+#endif /* CONFIG_ACPI_IBM_BAY */
IBM_HANDLE_INIT(beep);
IBM_HANDLE_INIT(ecrd);
IBM_HANDLE_INIT(ecwr);