#include <linux/proc_fs.h>
#include <linux/backlight.h>
+#include <linux/fb.h>
#include <asm/uaccess.h>
#include <linux/dmi.h>
"\\_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 */
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 */
printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION);
printk(IBM_INFO "%s\n", IBM_URL);
+ if (ibm_thinkpad_ec_found)
+ printk(IBM_INFO "ThinkPad EC firmware %s\n",
+ ibm_thinkpad_ec_found);
+
return 0;
}
return 0;
}
+#if defined(CONFIG_ACPI_IBM_DOCK) || defined(CONFIG_ACPI_IBM_BAY)
static int _sta(acpi_handle handle)
{
int status;
return status;
}
+#endif
#ifdef CONFIG_ACPI_IBM_DOCK
#define dock_docked() (_sta(dock_handle) & 1)
}
#endif
+#ifdef CONFIG_ACPI_IBM_BAY
static int bay_status_supported;
static int bay_status2_supported;
static int bay_eject_supported;
{
acpi_bus_generate_event(ibm->device, event, 0);
}
+#endif /* CONFIG_ACPI_IBM_BAY */
static int cmos_read(char *p)
{
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_properties ibm_backlight_data = {
- .owner = THIS_MODULE,
+static struct backlight_ops ibm_backlight_data = {
.get_brightness = brightness_get,
.update_status = brightness_update_status,
- .max_brightness = 7,
};
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)) {
return PTR_ERR(ibm_backlight_device);
}
+ ibm_backlight_device->props.max_brightness = 7;
+ ibm_backlight_device->props.brightness = b;
+ backlight_update_status(ibm_backlight_device);
+
return 0;
}
.type = ACPI_SYSTEM_NOTIFY,
},
#endif
+#ifdef CONFIG_ACPI_IBM_BAY
{
.name = "bay",
.init = bay_init,
.handle = &bay_handle,
.type = ACPI_SYSTEM_NOTIFY,
},
+#endif /* CONFIG_ACPI_IBM_BAY */
{
.name = "cmos",
.read = cmos_read,
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;
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;
return ret;
}
+static void ibm_exit(struct ibm_struct *ibm);
+
static int __init ibm_init(struct ibm_struct *ibm)
{
int ret;
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;
}
ibm_handle_init(#object, &object##_handle, *object##_parent, \
object##_paths, ARRAY_SIZE(object##_paths), &object##_path)
-static int set_ibm_param(const char *val, struct kernel_param *kp)
+static int __init set_ibm_param(const char *val, struct kernel_param *kp)
{
unsigned int i;
#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);
for (i = ARRAY_SIZE(ibms) - 1; i >= 0; i--)
ibm_exit(&ibms[i]);
- remove_proc_entry(IBM_DIR, acpi_root_dir);
+ if (proc_dir)
+ remove_proc_entry(IBM_DIR, acpi_root_dir);
if (ibm_thinkpad_ec_found)
kfree(ibm_thinkpad_ec_found);
if (acpi_disabled)
return -ENODEV;
- if (!acpi_specific_hotkey_enabled) {
- printk(IBM_ERR "using generic hotkey driver\n");
- return -ENODEV;
- }
-
/* ec is required because many other handles are relative to it */
IBM_HANDLE_INIT(ec);
if (!ec_handle) {
/* Models with newer firmware report the EC in DMI */
ibm_thinkpad_ec_found = check_dmi_for_ec();
- if (ibm_thinkpad_ec_found)
- printk(IBM_INFO "ThinkPad EC firmware %s\n",
- ibm_thinkpad_ec_found);
/* these handles are not required */
IBM_HANDLE_INIT(vid);
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);
proc_dir = proc_mkdir(IBM_DIR, acpi_root_dir);
if (!proc_dir) {
printk(IBM_ERR "unable to create proc dir %s", IBM_DIR);
+ acpi_ibm_exit();
return -ENODEV;
}
proc_dir->owner = THIS_MODULE;