diff options
-rw-r--r-- | MAINTAINERS | 5 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c | 4 | ||||
-rw-r--r-- | drivers/ata/Kconfig | 1 | ||||
-rw-r--r-- | drivers/platform/x86/acer-wmi.c | 3 | ||||
-rw-r--r-- | drivers/platform/x86/acerhdf.c | 68 | ||||
-rw-r--r-- | drivers/platform/x86/asus_acpi.c | 321 | ||||
-rw-r--r-- | drivers/platform/x86/dell-wmi.c | 42 | ||||
-rw-r--r-- | drivers/platform/x86/fujitsu-laptop.c | 8 | ||||
-rw-r--r-- | drivers/platform/x86/hp-wmi.c | 11 | ||||
-rw-r--r-- | drivers/platform/x86/msi-wmi.c | 10 | ||||
-rw-r--r-- | drivers/platform/x86/toshiba_acpi.c | 259 | ||||
-rw-r--r-- | drivers/platform/x86/wmi.c | 4 |
12 files changed, 431 insertions, 305 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index cf3f412..66f5f7d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3652,6 +3652,11 @@ W: http://0pointer.de/lennart/tchibo.html S: Maintained F: drivers/platform/x86/msi-laptop.c +MSI WMI SUPPORT +M: Anisse Astier <anisse@astier.eu> +S: Supported +F: drivers/platform/x86/msi-wmi.c + MULTIFUNCTION DEVICES (MFD) M: Samuel Ortiz <sameo@linux.intel.com> T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6.git diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index f28decf..1b1920f 100644 --- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -190,9 +190,11 @@ static void do_drv_write(void *_cmd) static void drv_read(struct drv_cmd *cmd) { + int err; cmd->val = 0; - smp_call_function_single(cpumask_any(cmd->mask), do_drv_read, cmd, 1); + err = smp_call_function_any(cmd->mask, do_drv_read, cmd, 1); + WARN_ON_ONCE(err); /* smp_call_function_any() was buggy? */ } static void drv_write(struct drv_cmd *cmd) diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 85844d0..56c6374 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -40,7 +40,6 @@ config ATA_VERBOSE_ERROR config ATA_ACPI bool "ATA ACPI Support" depends on ACPI && PCI - select ACPI_DOCK default y help This option adds support for ATA-related ACPI objects. diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 454970d..07d14df 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -96,9 +96,6 @@ struct acer_quirks { MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB"); MODULE_ALIAS("wmi:6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3"); -/* Temporary workaround until the WMI sysfs interface goes in */ -MODULE_ALIAS("dmi:*:*Acer*:*:"); - /* * Interface capability flags */ diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index 79b15b9..7b2384d 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c @@ -52,7 +52,7 @@ */ #undef START_IN_KERNEL_MODE -#define DRV_VER "0.5.20" +#define DRV_VER "0.5.22" /* * According to the Atom N270 datasheet, @@ -156,19 +156,25 @@ static const struct bios_settings_t bios_tbl[] = { {"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x20, 0x00} }, /* Acer 1410 */ {"Acer", "Aspire 1410", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, - /* special BIOS / other */ + {"Acer", "Aspire 1410", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, + /* Acer 1810xx */ + {"Acer", "Aspire 1810TZ", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, + {"Acer", "Aspire 1810T", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, + {"Acer", "Aspire 1810T", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, + {"Acer", "Aspire 1810TZ", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, + /* Gateway */ {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x21, 0x00} }, {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x20, 0x00} }, - {"Gateway ", "LT31 ", "v1.3103 ", 0x55, 0x58, - {0x10, 0x0f, 0x00} }, - {"Gateway ", "LT31 ", "v1.3201 ", 0x55, 0x58, - {0x10, 0x0f, 0x00} }, - {"Gateway ", "LT31 ", "v1.3302 ", 0x55, 0x58, - {0x10, 0x0f, 0x00} }, + {"Gateway", "LT31", "v1.3103", 0x55, 0x58, {0x10, 0x0f, 0x00} }, + {"Gateway", "LT31", "v1.3201", 0x55, 0x58, {0x10, 0x0f, 0x00} }, + {"Gateway", "LT31", "v1.3302", 0x55, 0x58, {0x10, 0x0f, 0x00} }, + /* Packard Bell */ {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x21, 0x00} }, {"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} }, {"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x21, 0x00} }, {"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x20, 0x00} }, + {"Packard Bell", "DOTMU", "v1.3303", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, + {"Packard Bell", "DOTMU", "v0.3120", 0x55, 0x58, {0x9e, 0x9e, 0x00} }, /* pewpew-terminator */ {"", "", "", 0, 0, {0, 0, 0} } }; @@ -486,13 +492,26 @@ static struct platform_driver acerhdf_driver = { .remove = acerhdf_remove, }; +/* checks if str begins with start */ +static int str_starts_with(const char *str, const char *start) +{ + unsigned long str_len = 0, start_len = 0; + + str_len = strlen(str); + start_len = strlen(start); + + if (str_len >= start_len && + !strncmp(str, start, start_len)) + return 1; + + return 0; +} /* check hardware */ static int acerhdf_check_hardware(void) { char const *vendor, *version, *product; - int i; - unsigned long prod_len = 0; + const struct bios_settings_t *bt = NULL; /* get BIOS data */ vendor = dmi_get_system_info(DMI_SYS_VENDOR); @@ -514,20 +533,20 @@ static int acerhdf_check_hardware(void) kernelmode = 0; } - prod_len = strlen(product); - if (verbose) pr_info("BIOS info: %s %s, product: %s\n", vendor, version, product); /* search BIOS version and vendor in BIOS settings table */ - for (i = 0; bios_tbl[i].version[0]; i++) { - if (strlen(bios_tbl[i].product) >= prod_len && - !strncmp(bios_tbl[i].product, product, - strlen(bios_tbl[i].product)) && - !strcmp(bios_tbl[i].vendor, vendor) && - !strcmp(bios_tbl[i].version, version)) { - bios_cfg = &bios_tbl[i]; + for (bt = bios_tbl; bt->vendor[0]; bt++) { + /* + * check if actual hardware BIOS vendor, product and version + * IDs start with the strings of BIOS table entry + */ + if (str_starts_with(vendor, bt->vendor) && + str_starts_with(product, bt->product) && + str_starts_with(version, bt->version)) { + bios_cfg = bt; break; } } @@ -640,9 +659,14 @@ static void __exit acerhdf_exit(void) MODULE_LICENSE("GPL"); MODULE_AUTHOR("Peter Feuerer"); MODULE_DESCRIPTION("Aspire One temperature and fan driver"); -MODULE_ALIAS("dmi:*:*Acer*:*:"); -MODULE_ALIAS("dmi:*:*Gateway*:*:"); -MODULE_ALIAS("dmi:*:*Packard Bell*:*:"); +MODULE_ALIAS("dmi:*:*Acer*:pnAOA*:"); +MODULE_ALIAS("dmi:*:*Acer*:pnAspire 1410*:"); +MODULE_ALIAS("dmi:*:*Acer*:pnAspire 1810*:"); +MODULE_ALIAS("dmi:*:*Gateway*:pnAOA*:"); +MODULE_ALIAS("dmi:*:*Gateway*:pnLT31*:"); +MODULE_ALIAS("dmi:*:*Packard Bell*:pnAOA*:"); +MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOA*:"); +MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOTMU*:"); module_init(acerhdf_init); module_exit(acerhdf_exit); diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c index 0c9c531..c1d2aee 100644 --- a/drivers/platform/x86/asus_acpi.c +++ b/drivers/platform/x86/asus_acpi.c @@ -35,6 +35,7 @@ #include <linux/init.h> #include <linux/types.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/backlight.h> #include <acpi/acpi_drivers.h> #include <acpi/acpi_bus.h> @@ -513,26 +514,12 @@ static int read_acpi_int(acpi_handle handle, const char *method, int *val) return (status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER); } -/* - * We write our info in page, we begin at offset off and cannot write more - * than count bytes. We set eof to 1 if we handle those 2 values. We return the - * number of bytes written in page - */ -static int -proc_read_info(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int asus_info_proc_show(struct seq_file *m, void *v) { - int len = 0; int temp; - char buf[16]; /* enough for all info */ - /* - * We use the easy way, we don't care of off and count, - * so we don't set eof to 1 - */ - len += sprintf(page, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n"); - len += sprintf(page + len, "Model reference : %s\n", - hotk->methods->name); + seq_printf(m, ACPI_HOTK_NAME " " ASUS_ACPI_VERSION "\n"); + seq_printf(m, "Model reference : %s\n", hotk->methods->name); /* * The SFUN method probably allows the original driver to get the list * of features supported by a given model. For now, 0x0100 or 0x0800 @@ -540,8 +527,7 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof, * The significance of others is yet to be found. */ if (read_acpi_int(hotk->handle, "SFUN", &temp)) - len += - sprintf(page + len, "SFUN value : 0x%04x\n", temp); + seq_printf(m, "SFUN value : 0x%04x\n", temp); /* * Another value for userspace: the ASYM method returns 0x02 for * battery low and 0x04 for battery critical, its readings tend to be @@ -550,30 +536,34 @@ proc_read_info(char *page, char **start, off_t off, int count, int *eof, * silently ignored. */ if (read_acpi_int(hotk->handle, "ASYM", &temp)) - len += - sprintf(page + len, "ASYM value : 0x%04x\n", temp); + seq_printf(m, "ASYM value : 0x%04x\n", temp); if (asus_info) { - snprintf(buf, 16, "%d", asus_info->length); - len += sprintf(page + len, "DSDT length : %s\n", buf); - snprintf(buf, 16, "%d", asus_info->checksum); - len += sprintf(page + len, "DSDT checksum : %s\n", buf); - snprintf(buf, 16, "%d", asus_info->revision); - len += sprintf(page + len, "DSDT revision : %s\n", buf); - snprintf(buf, 7, "%s", asus_info->oem_id); - len += sprintf(page + len, "OEM id : %s\n", buf); - snprintf(buf, 9, "%s", asus_info->oem_table_id); - len += sprintf(page + len, "OEM table id : %s\n", buf); - snprintf(buf, 16, "%x", asus_info->oem_revision); - len += sprintf(page + len, "OEM revision : 0x%s\n", buf); - snprintf(buf, 5, "%s", asus_info->asl_compiler_id); - len += sprintf(page + len, "ASL comp vendor id : %s\n", buf); - snprintf(buf, 16, "%x", asus_info->asl_compiler_revision); - len += sprintf(page + len, "ASL comp revision : 0x%s\n", buf); + seq_printf(m, "DSDT length : %d\n", asus_info->length); + seq_printf(m, "DSDT checksum : %d\n", asus_info->checksum); + seq_printf(m, "DSDT revision : %d\n", asus_info->revision); + seq_printf(m, "OEM id : %.*s\n", ACPI_OEM_ID_SIZE, asus_info->oem_id); + seq_printf(m, "OEM table id : %.*s\n", ACPI_OEM_TABLE_ID_SIZE, asus_info->oem_table_id); + seq_printf(m, "OEM revision : 0x%x\n", asus_info->oem_revision); + seq_printf(m, "ASL comp vendor id : %.*s\n", ACPI_NAME_SIZE, asus_info->asl_compiler_id); + seq_printf(m, "ASL comp revision : 0x%x\n", asus_info->asl_compiler_revision); } - return len; + return 0; +} + +static int asus_info_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, asus_info_proc_show, NULL); } +static const struct file_operations asus_info_proc_fops = { + .owner = THIS_MODULE, + .open = asus_info_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + /* * /proc handlers * We write our info in page, we begin at offset off and cannot write more @@ -639,34 +629,48 @@ write_led(const char __user *buffer, unsigned long count, /* * Proc handlers for MLED */ -static int -proc_read_mled(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int mled_proc_show(struct seq_file *m, void *v) { - return sprintf(page, "%d\n", - read_led(hotk->methods->mled_status, MLED_ON)); + seq_printf(m, "%d\n", read_led(hotk->methods->mled_status, MLED_ON)); + return 0; } -static int -proc_write_mled(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static int mled_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, mled_proc_show, NULL); +} + +static ssize_t mled_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { return write_led(buffer, count, hotk->methods->mt_mled, MLED_ON, 1); } +static const struct file_operations mled_proc_fops = { + .owner = THIS_MODULE, + .open = mled_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = mled_proc_write, +}; + /* * Proc handlers for LED display */ -static int -proc_read_ledd(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int ledd_proc_show(struct seq_file *m, void *v) { - return sprintf(page, "0x%08x\n", hotk->ledd_status); + seq_printf(m, "0x%08x\n", hotk->ledd_status); + return 0; } -static int -proc_write_ledd(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static int ledd_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, ledd_proc_show, NULL); +} + +static ssize_t ledd_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { int rv, value; @@ -682,61 +686,104 @@ proc_write_ledd(struct file *file, const char __user *buffer, return rv; } +static const struct file_operations ledd_proc_fops = { + .owner = THIS_MODULE, + .open = ledd_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = ledd_proc_write, +}; + /* * Proc handlers for WLED */ -static int -proc_read_wled(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int wled_proc_show(struct seq_file *m, void *v) { - return sprintf(page, "%d\n", - read_led(hotk->methods->wled_status, WLED_ON)); + seq_printf(m, "%d\n", read_led(hotk->methods->wled_status, WLED_ON)); + return 0; } -static int -proc_write_wled(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static int wled_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, wled_proc_show, NULL); +} + +static ssize_t wled_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { return write_led(buffer, count, hotk->methods->mt_wled, WLED_ON, 0); } +static const struct file_operations wled_proc_fops = { + .owner = THIS_MODULE, + .open = wled_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = wled_proc_write, +}; + /* * Proc handlers for Bluetooth */ -static int -proc_read_bluetooth(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int bluetooth_proc_show(struct seq_file *m, void *v) { - return sprintf(page, "%d\n", read_led(hotk->methods->bt_status, BT_ON)); + seq_printf(m, "%d\n", read_led(hotk->methods->bt_status, BT_ON)); + return 0; } -static int -proc_write_bluetooth(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static int bluetooth_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, bluetooth_proc_show, NULL); +} + +static ssize_t bluetooth_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *pos) { /* Note: mt_bt_switch controls both internal Bluetooth adapter's presence and its LED */ return write_led(buffer, count, hotk->methods->mt_bt_switch, BT_ON, 0); } +static const struct file_operations bluetooth_proc_fops = { + .owner = THIS_MODULE, + .open = bluetooth_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = bluetooth_proc_write, +}; + /* * Proc handlers for TLED */ -static int -proc_read_tled(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int tled_proc_show(struct seq_file *m, void *v) { - return sprintf(page, "%d\n", - read_led(hotk->methods->tled_status, TLED_ON)); + seq_printf(m, "%d\n", read_led(hotk->methods->tled_status, TLED_ON)); + return 0; } -static int -proc_write_tled(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static int tled_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, tled_proc_show, NULL); +} + +static ssize_t tled_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { return write_led(buffer, count, hotk->methods->mt_tled, TLED_ON, 0); } +static const struct file_operations tled_proc_fops = { + .owner = THIS_MODULE, + .open = tled_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = tled_proc_write, +}; + static int get_lcd_state(void) { int lcd = 0; @@ -829,16 +876,19 @@ static int set_lcd_state(int value) } -static int -proc_read_lcd(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int lcd_proc_show(struct seq_file *m, void *v) { - return sprintf(page, "%d\n", get_lcd_state()); + seq_printf(m, "%d\n", get_lcd_state()); + return 0; } -static int -proc_write_lcd(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static int lcd_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, lcd_proc_show, NULL); +} + +static ssize_t lcd_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { int rv, value; @@ -848,6 +898,15 @@ proc_write_lcd(struct file *file, const char __user *buffer, return rv; } +static const struct file_operations lcd_proc_fops = { + .owner = THIS_MODULE, + .open = lcd_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = lcd_proc_write, +}; + static int read_brightness(struct backlight_device *bd) { int value; @@ -907,16 +966,19 @@ static int set_brightness_status(struct backlight_device *bd) return set_brightness(bd->props.brightness); } -static int -proc_read_brn(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int brn_proc_show(struct seq_file *m, void *v) { - return sprintf(page, "%d\n", read_brightness(NULL)); + seq_printf(m, "%d\n", read_brightness(NULL)); + return 0; } -static int -proc_write_brn(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static int brn_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, brn_proc_show, NULL); +} + +static ssize_t brn_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { int rv, value; @@ -929,6 +991,15 @@ proc_write_brn(struct file *file, const char __user *buffer, return rv; } +static const struct file_operations brn_proc_fops = { + .owner = THIS_MODULE, + .open = brn_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = brn_proc_write, +}; + static void set_display(int value) { /* no sanity check needed for now */ @@ -942,9 +1013,7 @@ static void set_display(int value) * Now, *this* one could be more user-friendly, but so far, no-one has * complained. The significance of bits is the same as in proc_write_disp() */ -static int -proc_read_disp(char *page, char **start, off_t off, int count, int *eof, - void *data) +static int disp_proc_show(struct seq_file *m, void *v) { int value = 0; @@ -952,7 +1021,13 @@ proc_read_disp(char *page, char **start, off_t off, int count, int *eof, printk(KERN_WARNING "Asus ACPI: Error reading display status\n"); value &= 0x07; /* needed for some models, shouldn't hurt others */ - return sprintf(page, "%d\n", value); + seq_printf(m, "%d\n", value); + return 0; +} + +static int disp_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, disp_proc_show, NULL); } /* @@ -961,9 +1036,8 @@ proc_read_disp(char *page, char **start, off_t off, int count, int *eof, * (bitwise) of these will suffice. I never actually tested 3 displays hooked * up simultaneously, so be warned. See the acpi4asus README for more info. */ -static int -proc_write_disp(struct file *file, const char __user *buffer, - unsigned long count, void *data) +static ssize_t disp_proc_write(struct file *file, const char __user *buffer, + size_t count, loff_t *pos) { int rv, value; @@ -973,25 +1047,27 @@ proc_write_disp(struct file *file, const char __user *buffer, return rv; } -typedef int (proc_readfunc) (char *page, char **start, off_t off, int count, - int *eof, void *data); -typedef int (proc_writefunc) (struct file *file, const char __user *buffer, - unsigned long count, void *data); +static const struct file_operations disp_proc_fops = { + .owner = THIS_MODULE, + .open = disp_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = disp_proc_write, +}; static int -asus_proc_add(char *name, proc_writefunc *writefunc, - proc_readfunc *readfunc, mode_t mode, +asus_proc_add(char *name, const struct file_operations *proc_fops, mode_t mode, struct acpi_device *device) { - struct proc_dir_entry *proc = - create_proc_entry(name, mode, acpi_device_dir(device)); + struct proc_dir_entry *proc; + + proc = proc_create_data(name, mode, acpi_device_dir(device), + proc_fops, acpi_driver_data(device)); if (!proc) { printk(KERN_WARNING " Unable to create %s fs entry\n", name); return -1; } - proc->write_proc = writefunc; - proc->read_proc = readfunc; - proc->data = acpi_driver_data(device); proc->uid = asus_uid; proc->gid = asus_gid; return 0; @@ -1020,10 +1096,9 @@ static int asus_hotk_add_fs(struct acpi_device *device) if (!acpi_device_dir(device)) return -ENODEV; - proc = create_proc_entry(PROC_INFO, mode, acpi_device_dir(device)); + proc = proc_create(PROC_INFO, mode, acpi_device_dir(device), + &asus_info_proc_fops); if (proc) { - proc->read_proc = proc_read_info; - proc->data = acpi_driver_data(device); proc->uid = asus_uid; proc->gid = asus_gid; } else { @@ -1032,28 +1107,23 @@ static int asus_hotk_add_fs(struct acpi_device *device) } if (hotk->methods->mt_wled) { - asus_proc_add(PROC_WLED, &proc_write_wled, &proc_read_wled, - mode, device); + asus_proc_add(PROC_WLED, &wled_proc_fops, mode, device); } if (hotk->methods->mt_ledd) { - asus_proc_add(PROC_LEDD, &proc_write_ledd, &proc_read_ledd, - mode, device); + asus_proc_add(PROC_LEDD, &ledd_proc_fops, mode, device); } if (hotk->methods->mt_mled) { - asus_proc_add(PROC_MLED, &proc_write_mled, &proc_read_mled, - mode, device); + asus_proc_add(PROC_MLED, &mled_proc_fops, mode, device); } if (hotk->methods->mt_tled) { - asus_proc_add(PROC_TLED, &proc_write_tled, &proc_read_tled, - mode, device); + asus_proc_add(PROC_TLED, &tled_proc_fops, mode, device); } if (hotk->methods->mt_bt_switch) { - asus_proc_add(PROC_BT, &proc_write_bluetooth, - &proc_read_bluetooth, mode, device); + asus_proc_add(PROC_BT, &bluetooth_proc_fops, mode, device); } /* @@ -1061,19 +1131,16 @@ static int asus_hotk_add_fs(struct acpi_device *device) * accessible from the keyboard */ if (hotk->methods->mt_lcd_switch && hotk->methods->lcd_status) { - asus_proc_add(PROC_LCD, &proc_write_lcd, &proc_read_lcd, mode, - device); + asus_proc_add(PROC_LCD, &lcd_proc_fops, mode, device); } if ((hotk->methods->brightness_up && hotk->methods->brightness_down) || (hotk->methods->brightness_get && hotk->methods->brightness_set)) { - asus_proc_add(PROC_BRN, &proc_write_brn, &proc_read_brn, mode, - device); + asus_proc_add(PROC_BRN, &brn_proc_fops, mode, device); } if (hotk->methods->display_set) { - asus_proc_add(PROC_DISP, &proc_write_disp, &proc_read_disp, - mode, device); + asus_proc_add(PROC_DISP, &disp_proc_fops, mode, device); } return 0; diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c index 67f3fe7..916ccb2 100644 --- a/drivers/platform/x86/dell-wmi.c +++ b/drivers/platform/x86/dell-wmi.c @@ -238,6 +238,7 @@ static void dell_wmi_notify(u32 value, void *context) input_sync(dell_wmi_input_dev); } } + kfree(obj); } @@ -324,37 +325,34 @@ static int __init dell_wmi_init(void) int err; if (wmi_has_guid(DELL_EVENT_GUID)) { + printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n"); + return -ENODEV; + } - dmi_walk(find_hk_type, NULL); - - err = dell_wmi_input_setup(); - - if (err) - return err; - - err = wmi_install_notify_handler(DELL_EVENT_GUID, - dell_wmi_notify, NULL); - if (err) { - input_unregister_device(dell_wmi_input_dev); - printk(KERN_ERR "dell-wmi: Unable to register" - " notify handler - %d\n", err); - return err; - } + dmi_walk(find_hk_type, NULL); + acpi_video = acpi_video_backlight_support(); - acpi_video = acpi_video_backlight_support(); + err = dell_wmi_input_setup(); + if (err) + return err; - } else - printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n"); + err = wmi_install_notify_handler(DELL_EVENT_GUID, + dell_wmi_notify, NULL); + if (err) { + input_unregister_device(dell_wmi_input_dev); + printk(KERN_ERR + "dell-wmi: Unable to register notify handler - %d\n", + err); + return err; + } return 0; } static void __exit dell_wmi_exit(void) { - if (wmi_has_guid(DELL_EVENT_GUID)) { - wmi_remove_notify_handler(DELL_EVENT_GUID); - input_unregister_device(dell_wmi_input_dev); - } + wmi_remove_notify_handler(DELL_EVENT_GUID); + input_unregister_device(dell_wmi_input_dev); } module_init(dell_wmi_init); diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index b66029b..5f3320d 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -376,8 +376,8 @@ static int get_lcd_level(void) status = acpi_evaluate_integer(fujitsu->acpi_handle, "GBLL", NULL, &state); - if (status < 0) - return status; + if (ACPI_FAILURE(status)) + return 0; fujitsu->brightness_level = state & 0x0fffffff; @@ -398,8 +398,8 @@ static int get_max_brightness(void) status = acpi_evaluate_integer(fujitsu->acpi_handle, "RBLL", NULL, &state); - if (status < 0) - return status; + if (ACPI_FAILURE(status)) + return -1; fujitsu->max_brightness = state; diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 63c3e65..8781d8fa 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -134,10 +134,15 @@ static int hp_wmi_perform_query(int query, int write, int value) obj = output.pointer; - if (!obj || obj->type != ACPI_TYPE_BUFFER) + if (!obj) return -EINVAL; + else if (obj->type != ACPI_TYPE_BUFFER) { + kfree(obj); + return -EINVAL; + } bios_return = *((struct bios_return *)obj->buffer.pointer); + kfree(obj); if (bios_return.return_code > 0) return bios_return.return_code * -1; else @@ -340,10 +345,12 @@ static void hp_wmi_notify(u32 value, void *context) if (!obj || obj->type != ACPI_TYPE_BUFFER || obj->buffer.length != 8) { printk(KERN_INFO "HP WMI: Unknown response received\n"); + kfree(obj); return; } eventcode = *((u8 *) obj->buffer.pointer); + kfree(obj); if (eventcode == 0x4) eventcode = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0, 0); @@ -381,6 +388,8 @@ static void hp_wmi_notify(u32 value, void *context) } else printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n", eventcode); + + kfree(obj); } static int __init hp_wmi_input_setup(void) diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c index 0c8fe14..7f77f90 100644 --- a/drivers/platform/x86/msi-wmi.c +++ b/drivers/platform/x86/msi-wmi.c @@ -34,16 +34,6 @@ MODULE_LICENSE("GPL"); MODULE_ALIAS("wmi:551A1F84-FBDD-4125-91DB-3EA8F44F1D45"); MODULE_ALIAS("wmi:B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2"); -/* Temporary workaround until the WMI sysfs interface goes in - { "svn", DMI_SYS_VENDOR }, - { "pn", DMI_PRODUCT_NAME }, - { "pvr", DMI_PRODUCT_VERSION }, - { "rvn", DMI_BOARD_VENDOR }, - { "rn", DMI_BOARD_NAME }, -*/ - -MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-6638:*"); - #define DRV_NAME "msi-wmi" #define DRV_PFX DRV_NAME ": " diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 51c0a8b..77bf5d8 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -42,6 +42,7 @@ #include <linux/init.h> #include <linux/types.h> #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/backlight.h> #include <linux/platform_device.h> #include <linux/rfkill.h> @@ -357,63 +358,6 @@ static int force_fan; static int last_key_event; static int key_event_valid; -typedef struct _ProcItem { - const char *name; - char *(*read_func) (char *); - unsigned long (*write_func) (const char *, unsigned long); -} ProcItem; - -/* proc file handlers - */ - -static int -dispatch_read(char *page, char **start, off_t off, int count, int *eof, - ProcItem * item) -{ - char *p = page; - int len; - - if (off == 0) - p = item->read_func(p); - - /* ISSUE: I don't understand this code */ - len = (p - page); - if (len <= off + count) - *eof = 1; - *start = page + off; - len -= off; - if (len > count) - len = count; - if (len < 0) - len = 0; - return len; -} - -static int -dispatch_write(struct file *file, const char __user * buffer, - unsigned long count, ProcItem * item) -{ - int result; - char *tmp_buffer; - - /* Arg buffer points to userspace memory, which can't be accessed - * directly. Since we're making a copy, zero-terminate the - * destination so that sscanf can be used on it safely. - */ - tmp_buffer = kmalloc(count + 1, GFP_KERNEL); - if (!tmp_buffer) - return -ENOMEM; - - if (copy_from_user(tmp_buffer, buffer, count)) { - result = -EFAULT; - } else { - tmp_buffer[count] = 0; - result = item->write_func(tmp_buffer, count); - } - kfree(tmp_buffer); - return result; -} - static int get_lcd(struct backlight_device *bd) { u32 hci_result; @@ -426,19 +370,24 @@ static int get_lcd(struct backlight_device *bd) return -EFAULT; } -static char *read_lcd(char *p) +static int lcd_proc_show(struct seq_file *m, void *v) { int value = get_lcd(NULL); if (value >= 0) { - p += sprintf(p, "brightness: %d\n", value); - p += sprintf(p, "brightness_levels: %d\n", + seq_printf(m, "brightness: %d\n", value); + seq_printf(m, "brightness_levels: %d\n", HCI_LCD_BRIGHTNESS_LEVELS); } else { printk(MY_ERR "Error reading LCD brightness\n"); } - return p; + return 0; +} + +static int lcd_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, lcd_proc_show, NULL); } static int set_lcd(int value) @@ -458,12 +407,20 @@ static int set_lcd_status(struct backlight_device *bd) return set_lcd(bd->props.brightness); } -static unsigned long write_lcd(const char *buffer, unsigned long count) +static ssize_t lcd_proc_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) { + char cmd[42]; + size_t len; int value; int ret; - if (sscanf(buffer, " brightness : %i", &value) == 1 && + len = min(count, sizeof(cmd) - 1); + if (copy_from_user(cmd, buf, len)) + return -EFAULT; + cmd[len] = '\0'; + + if (sscanf(cmd, " brightness : %i", &value) == 1 && value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) { ret = set_lcd(value); if (ret == 0) @@ -474,7 +431,16 @@ static unsigned long write_lcd(const char *buffer, unsigned long count) return ret; } -static char *read_video(char *p) +static const struct file_operations lcd_proc_fops = { + .owner = THIS_MODULE, + .open = lcd_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = lcd_proc_write, +}; + +static int video_proc_show(struct seq_file *m, void *v) { u32 hci_result; u32 value; @@ -484,18 +450,25 @@ static char *read_video(char *p) int is_lcd = (value & HCI_VIDEO_OUT_LCD) ? 1 : 0; int is_crt = (value & HCI_VIDEO_OUT_CRT) ? 1 : 0; int is_tv = (value & HCI_VIDEO_OUT_TV) ? 1 : 0; - p += sprintf(p, "lcd_out: %d\n", is_lcd); - p += sprintf(p, "crt_out: %d\n", is_crt); - p += sprintf(p, "tv_out: %d\n", is_tv); + seq_printf(m, "lcd_out: %d\n", is_lcd); + seq_printf(m, "crt_out: %d\n", is_crt); + seq_printf(m, "tv_out: %d\n", is_tv); } else { printk(MY_ERR "Error reading video out status\n"); } - return p; + return 0; } -static unsigned long write_video(const char *buffer, unsigned long count) +static int video_proc_open(struct inode *inode, struct file *file) { + return single_open(file, video_proc_show, NULL); +} + +static ssize_t video_proc_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) +{ + char *cmd, *buffer; int value; int remain = count; int lcd_out = -1; @@ -504,6 +477,17 @@ static unsigned long write_video(const char *buffer, unsigned long count) u32 hci_result; u32 video_out; + cmd = kmalloc(count + 1, GFP_KERNEL); + if (!cmd) + return -ENOMEM; + if (copy_from_user(cmd, buf, count)) { + kfree(cmd); + return -EFAULT; + } + cmd[count] = '\0'; + + buffer = cmd; + /* scan expression. Multiple expressions may be delimited with ; * * NOTE: to keep scanning simple, invalid fields are ignored @@ -523,6 +507,8 @@ static unsigned long write_video(const char *buffer, unsigned long count) while (remain && *(buffer - 1) != ';'); } + kfree(cmd); + hci_read1(HCI_VIDEO_OUT, &video_out, &hci_result); if (hci_result == HCI_SUCCESS) { unsigned int new_video_out = video_out; @@ -543,28 +529,50 @@ static unsigned long write_video(const char *buffer, unsigned long count) return count; } -static char *read_fan(char *p) +static const struct file_operations video_proc_fops = { + .owner = THIS_MODULE, + .open = video_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = video_proc_write, +}; + +static int fan_proc_show(struct seq_file *m, void *v) { u32 hci_result; u32 value; hci_read1(HCI_FAN, &value, &hci_result); if (hci_result == HCI_SUCCESS) { - p += sprintf(p, "running: %d\n", (value > 0)); - p += sprintf(p, "force_on: %d\n", force_fan); + seq_printf(m, "running: %d\n", (value > 0)); + seq_printf(m, "force_on: %d\n", force_fan); } else { printk(MY_ERR "Error reading fan status\n"); } - return p; + return 0; +} + +static int fan_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, fan_proc_show, NULL); } -static unsigned long write_fan(const char *buffer, unsigned long count) +static ssize_t fan_proc_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) { + char cmd[42]; + size_t len; int value; u32 hci_result; - if (sscanf(buffer, " force_on : %i", &value) == 1 && + len = min(count, sizeof(cmd) - 1); + if (copy_from_user(cmd, buf, len)) + return -EFAULT; + cmd[len] = '\0'; + + if (sscanf(cmd, " force_on : %i", &value) == 1 && value >= 0 && value <= 1) { hci_write1(HCI_FAN, value, &hci_result); if (hci_result != HCI_SUCCESS) @@ -578,7 +586,16 @@ static unsigned long write_fan(const char *buffer, unsigned long count) return count; } -static char *read_keys(char *p) +static const struct file_operations fan_proc_fops = { + .owner = THIS_MODULE, + .open = fan_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = fan_proc_write, +}; + +static int keys_proc_show(struct seq_file *m, void *v) { u32 hci_result; u32 value; @@ -602,18 +619,30 @@ static char *read_keys(char *p) } } - p += sprintf(p, "hotkey_ready: %d\n", key_event_valid); - p += sprintf(p, "hotkey: 0x%04x\n", last_key_event); + seq_printf(m, "hotkey_ready: %d\n", key_event_valid); + seq_printf(m, "hotkey: 0x%04x\n", last_key_event); +end: + return 0; +} - end: - return p; +static int keys_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, keys_proc_show, NULL); } -static unsigned long write_keys(const char *buffer, unsigned long count) +static ssize_t keys_proc_write(struct file *file, const char __user *buf, + size_t count, loff_t *pos) { + char cmd[42]; + size_t len; int value; - if (sscanf(buffer, " hotkey_ready : %i", &value) == 1 && value == 0) { + len = min(count, sizeof(cmd) - 1); + if (copy_from_user(cmd, buf, len)) + return -EFAULT; + cmd[len] = '\0'; + + if (sscanf(cmd, " hotkey_ready : %i", &value) == 1 && value == 0) { key_event_valid = 0; } else { return -EINVAL; @@ -622,52 +651,58 @@ static unsigned long write_keys(const char *buffer, unsigned long count) return count; } -static char *read_version(char *p) +static const struct file_operations keys_proc_fops = { + .owner = THIS_MODULE, + .open = keys_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = keys_proc_write, +}; + +static int version_proc_show(struct seq_file *m, void *v) { - p += sprintf(p, "driver: %s\n", TOSHIBA_ACPI_VERSION); - p += sprintf(p, "proc_interface: %d\n", - PROC_INTERFACE_VERSION); - return p; + seq_printf(m, "driver: %s\n", TOSHIBA_ACPI_VERSION); + seq_printf(m, "proc_interface: %d\n", PROC_INTERFACE_VERSION); + return 0; } +static int version_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, version_proc_show, PDE(inode)->data); +} + +static const struct file_operations version_proc_fops = { + .owner = THIS_MODULE, + .open = version_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + /* proc and module init */ #define PROC_TOSHIBA "toshiba" -static ProcItem proc_items[] = { - {"lcd", read_lcd, write_lcd}, - {"video", read_video, write_video}, - {"fan", read_fan, write_fan}, - {"keys", read_keys, write_keys}, - {"version", read_version, NULL}, - {NULL} -}; - static acpi_status __init add_device(void) { - struct proc_dir_entry *proc; - ProcItem *item; - - for (item = proc_items; item->name; ++item) { - proc = create_proc_read_entry(item->name, - S_IFREG | S_IRUGO | S_IWUSR, - toshiba_proc_dir, - (read_proc_t *) dispatch_read, - item); - if (proc && item->write_func) - proc->write_proc = (write_proc_t *) dispatch_write; - } + proc_create("lcd", S_IRUGO | S_IWUSR, toshiba_proc_dir, &lcd_proc_fops); + proc_create("video", S_IRUGO | S_IWUSR, toshiba_proc_dir, &video_proc_fops); + proc_create("fan", S_IRUGO | S_IWUSR, toshiba_proc_dir, &fan_proc_fops); + proc_create("keys", S_IRUGO | S_IWUSR, toshiba_proc_dir, &keys_proc_fops); + proc_create("version", S_IRUGO, toshiba_proc_dir, &version_proc_fops); return AE_OK; } static acpi_status remove_device(void) { - ProcItem *item; - - for (item = proc_items; item->name; ++item) - remove_proc_entry(item->name, toshiba_proc_dir); + remove_proc_entry("lcd", toshiba_proc_dir); + remove_proc_entry("video", toshiba_proc_dir); + remove_proc_entry("fan", toshiba_proc_dir); + remove_proc_entry("keys", toshiba_proc_dir); + remove_proc_entry("version", toshiba_proc_dir); return AE_OK; } diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index e425a86..9f93d6c 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c @@ -540,8 +540,8 @@ EXPORT_SYMBOL_GPL(wmi_remove_notify_handler); /** * wmi_get_event_data - Get WMI data associated with an event * - * @event - Event to find - * &out - Buffer to hold event data + * @event: Event to find + * @out: Buffer to hold event data. out->pointer should be freed with kfree() * * Returns extra data associated with an event in WMI. */ |