From 302822996fd572676bb66a7c4351f6faa0e4ddfd Mon Sep 17 00:00:00 2001 From: Liu Chuansheng Date: Thu, 12 Sep 2013 01:42:57 +0800 Subject: [PATCH 01/18] ACPI / osl: implement acpi_os_sleep() with msleep() Currently, acpi_os_sleep() uses schedule_timeout_interruptible() which can be interrupted by a signal, and that causes the real sleep time to be shorter. According to the ACPI spec: The Sleep term is used to implement long-term timing requirements. Execution is delayed for at least the required number of milliseconds. The sleeping time should be at least the required number msecs, so use msleep() which guarantees that to implement it. Signed-off-by: Liu Chuansheng Signed-off-by: Rafael J. Wysocki --- drivers/acpi/osl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index e5f416c7f66e..b1629b571cb2 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -820,7 +820,7 @@ acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler) void acpi_os_sleep(u64 ms) { - schedule_timeout_interruptible(msecs_to_jiffies(ms)); + msleep(ms); } void acpi_os_stall(u32 us) From 763f527b68c6b026439f0b12ebe232d96b5563df Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Thu, 12 Sep 2013 03:32:03 -0400 Subject: [PATCH 02/18] ACPI / button: Using input_set_capability() to mark device's event capability Input layer provides input_set_capability() to set input device's event related bits. This patch is to use it to replace origin code. Signed-off-by: Lan Tianyu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/button.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index a55773801c5f..c971929d75c2 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -383,18 +383,15 @@ static int acpi_button_add(struct acpi_device *device) switch (button->type) { case ACPI_BUTTON_TYPE_POWER: - input->evbit[0] = BIT_MASK(EV_KEY); - set_bit(KEY_POWER, input->keybit); + input_set_capability(input, EV_KEY, KEY_POWER); break; case ACPI_BUTTON_TYPE_SLEEP: - input->evbit[0] = BIT_MASK(EV_KEY); - set_bit(KEY_SLEEP, input->keybit); + input_set_capability(input, EV_KEY, KEY_SLEEP); break; case ACPI_BUTTON_TYPE_LID: - input->evbit[0] = BIT_MASK(EV_SW); - set_bit(SW_LID, input->swbit); + input_set_capability(input, EV_SW, SW_LID); break; } From 16a26e85279fd672050ffc3637038366629e8653 Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Thu, 12 Sep 2013 03:32:04 -0400 Subject: [PATCH 03/18] ACPI / EC: Convert all printk() calls to dynamic debug function This patch is to convert all printks in the ec driver to pr_debug/info/err and define pr_fmt macro to replace PREFIX. Signed-off-by: Lan Tianyu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 49 +++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index a06d98374705..d5309fd49458 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -28,6 +28,7 @@ /* Uncomment next line to get verbose printout */ /* #define DEBUG */ +#define pr_fmt(fmt) "ACPI : EC: " fmt #include #include @@ -49,9 +50,6 @@ #define ACPI_EC_DEVICE_NAME "Embedded Controller" #define ACPI_EC_FILE_INFO "info" -#undef PREFIX -#define PREFIX "ACPI: EC: " - /* EC status register */ #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ @@ -131,26 +129,26 @@ static int EC_FLAGS_SKIP_DSDT_SCAN; /* Not all BIOS survive early DSDT scan */ static inline u8 acpi_ec_read_status(struct acpi_ec *ec) { u8 x = inb(ec->command_addr); - pr_debug(PREFIX "---> status = 0x%2.2x\n", x); + pr_debug("---> status = 0x%2.2x\n", x); return x; } static inline u8 acpi_ec_read_data(struct acpi_ec *ec) { u8 x = inb(ec->data_addr); - pr_debug(PREFIX "---> data = 0x%2.2x\n", x); + pr_debug("---> data = 0x%2.2x\n", x); return x; } static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) { - pr_debug(PREFIX "<--- command = 0x%2.2x\n", command); + pr_debug("<--- command = 0x%2.2x\n", command); outb(command, ec->command_addr); } static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) { - pr_debug(PREFIX "<--- data = 0x%2.2x\n", data); + pr_debug("<--- data = 0x%2.2x\n", data); outb(data, ec->data_addr); } @@ -241,7 +239,7 @@ static int ec_poll(struct acpi_ec *ec) } advance_transaction(ec, acpi_ec_read_status(ec)); } while (time_before(jiffies, delay)); - pr_debug(PREFIX "controller reset, restart transaction\n"); + pr_debug("controller reset, restart transaction\n"); spin_lock_irqsave(&ec->lock, flags); start_transaction(ec); spin_unlock_irqrestore(&ec->lock, flags); @@ -309,12 +307,12 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) } } if (ec_wait_ibf0(ec)) { - pr_err(PREFIX "input buffer is not empty, " + pr_err("input buffer is not empty, " "aborting transaction\n"); status = -ETIME; goto end; } - pr_debug(PREFIX "transaction start (cmd=0x%02x, addr=0x%02x)\n", + pr_debug("transaction start (cmd=0x%02x, addr=0x%02x)\n", t->command, t->wdata ? t->wdata[0] : 0); /* disable GPE during transaction if storm is detected */ if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { @@ -331,12 +329,12 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) /* It is safe to enable the GPE outside of the transaction. */ acpi_enable_gpe(NULL, ec->gpe); } else if (t->irq_count > ec_storm_threshold) { - pr_info(PREFIX "GPE storm detected(%d GPEs), " + pr_info("GPE storm detected(%d GPEs), " "transactions will use polling mode\n", t->irq_count); set_bit(EC_FLAGS_GPE_STORM, &ec->flags); } - pr_debug(PREFIX "transaction end\n"); + pr_debug("transaction end\n"); end: if (ec->global_lock) acpi_release_global_lock(glk); @@ -570,12 +568,12 @@ static void acpi_ec_run(void *cxt) struct acpi_ec_query_handler *handler = cxt; if (!handler) return; - pr_debug(PREFIX "start query execution\n"); + pr_debug("start query execution\n"); if (handler->func) handler->func(handler->data); else if (handler->handle) acpi_evaluate_object(handler->handle, NULL, NULL, NULL); - pr_debug(PREFIX "stop query execution\n"); + pr_debug("stop query execution\n"); kfree(handler); } @@ -593,7 +591,8 @@ static int acpi_ec_sync_query(struct acpi_ec *ec) if (!copy) return -ENOMEM; memcpy(copy, handler, sizeof(*copy)); - pr_debug(PREFIX "push query execution (0x%2x) on queue\n", value); + pr_debug("push query execution (0x%2x) on queue\n", + value); return acpi_os_execute((copy->func) ? OSL_NOTIFY_HANDLER : OSL_GPE_HANDLER, acpi_ec_run, copy); @@ -616,7 +615,7 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state) { if (state & ACPI_EC_FLAG_SCI) { if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { - pr_debug(PREFIX "push gpe query to the queue\n"); + pr_debug("push gpe query to the queue\n"); return acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ec_gpe_query, ec); } @@ -630,7 +629,7 @@ static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, struct acpi_ec *ec = data; u8 status = acpi_ec_read_status(ec); - pr_debug(PREFIX "~~~> interrupt, status:0x%02x\n", status); + pr_debug("~~~> interrupt, status:0x%02x\n", status); advance_transaction(ec, status); if (ec_transaction_done(ec) && @@ -776,7 +775,7 @@ static int ec_install_handlers(struct acpi_ec *ec) * The AE_NOT_FOUND error will be ignored and OS * continue to initialize EC. */ - printk(KERN_ERR "Fail in evaluating the _REG object" + pr_err("Fail in evaluating the _REG object" " of EC device. Broken bios is suspected.\n"); } else { acpi_remove_gpe_handler(NULL, ec->gpe, @@ -795,10 +794,10 @@ static void ec_remove_handlers(struct acpi_ec *ec) acpi_disable_gpe(NULL, ec->gpe); if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) - pr_err(PREFIX "failed to remove space handler\n"); + pr_err("failed to remove space handler\n"); if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler))) - pr_err(PREFIX "failed to remove gpe handler\n"); + pr_err("failed to remove gpe handler\n"); clear_bit(EC_FLAGS_HANDLERS_INSTALLED, &ec->flags); } @@ -840,7 +839,7 @@ static int acpi_ec_add(struct acpi_device *device) ret = !!request_region(ec->command_addr, 1, "EC cmd"); WARN(!ret, "Could not request EC cmd io port 0x%lx", ec->command_addr); - pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", + pr_info("GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", ec->gpe, ec->command_addr, ec->data_addr); ret = ec_install_handlers(ec); @@ -931,7 +930,7 @@ static int ec_validate_ecdt(const struct dmi_system_id *id) /* MSI EC needs special treatment, enable it */ static int ec_flag_msi(const struct dmi_system_id *id) { - printk(KERN_DEBUG PREFIX "Detected MSI hardware, enabling workarounds.\n"); + pr_debug("Detected MSI hardware, enabling workarounds.\n"); EC_FLAGS_MSI = 1; EC_FLAGS_VALIDATE_ECDT = 1; return 0; @@ -1010,7 +1009,7 @@ int __init acpi_ec_ecdt_probe(void) status = acpi_get_table(ACPI_SIG_ECDT, 1, (struct acpi_table_header **)&ecdt_ptr); if (ACPI_SUCCESS(status)) { - pr_info(PREFIX "EC description table is found, configuring boot EC\n"); + pr_info("EC description table is found, configuring boot EC\n"); boot_ec->command_addr = ecdt_ptr->control.address; boot_ec->data_addr = ecdt_ptr->data.address; boot_ec->gpe = ecdt_ptr->gpe; @@ -1030,7 +1029,7 @@ int __init acpi_ec_ecdt_probe(void) /* This workaround is needed only on some broken machines, * which require early EC, but fail to provide ECDT */ - printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); + pr_debug("Look up EC in DSDT\n"); status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, boot_ec, NULL); /* Check that acpi_get_devices actually find something */ @@ -1042,7 +1041,7 @@ int __init acpi_ec_ecdt_probe(void) saved_ec->data_addr != boot_ec->data_addr || saved_ec->gpe != boot_ec->gpe || saved_ec->handle != boot_ec->handle) - pr_info(PREFIX "ASUSTek keeps feeding us with broken " + pr_info("ASUSTek keeps feeding us with broken " "ECDT tables, which are very hard to workaround. " "Trying to use DSDT EC info instead. Please send " "output of acpidump to linux-acpi@vger.kernel.org\n"); From c48b156517348a0130e9e6edbeba95f9b4e50d65 Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Thu, 12 Sep 2013 03:32:05 -0400 Subject: [PATCH 04/18] ACPI / sysfs: make GPE sysfs attributes only accept correct values According to the design, GPE sysfs attributes should accept "disable", "enable", "clear" and integer numbers as params. Current code checks "disable", "enable" and "clear" first. If the param doesn't match, pass it to strtoul() as a string representing an integer number and assign the return value to the given GPE count. It is missing the check of whether or not the param really represents an integer number and strtoul() will return 0 if the string is not a number. This causes any params except for "enable", "disable", "clear" and a number to make the GPE count become 0. This patch is to use kstrtoul() to replace strtoul() and check the return value. If the convertion is successful, use as the new GPE count. If not, return an error. Signed-off-by: Lan Tianyu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/sysfs.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 05306a59aedc..b55778704444 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -564,6 +564,7 @@ static ssize_t counter_set(struct kobject *kobj, acpi_event_status status; acpi_handle handle; int result = 0; + unsigned long tmp; if (index == num_gpes + ACPI_NUM_FIXED_EVENTS + COUNT_SCI) { int i; @@ -596,8 +597,10 @@ static ssize_t counter_set(struct kobject *kobj, else if (!strcmp(buf, "clear\n") && (status & ACPI_EVENT_FLAG_SET)) result = acpi_clear_gpe(handle, index); + else if (!kstrtoul(buf, 0, &tmp)) + all_counters[index].count = tmp; else - all_counters[index].count = strtoul(buf, NULL, 0); + result = -EINVAL; } else if (index < num_gpes + ACPI_NUM_FIXED_EVENTS) { int event = index - num_gpes; if (!strcmp(buf, "disable\n") && @@ -609,8 +612,10 @@ static ssize_t counter_set(struct kobject *kobj, else if (!strcmp(buf, "clear\n") && (status & ACPI_EVENT_FLAG_SET)) result = acpi_clear_event(event); + else if (!kstrtoul(buf, 0, &tmp)) + all_counters[index].count = tmp; else - all_counters[index].count = strtoul(buf, NULL, 0); + result = -EINVAL; } else all_counters[index].count = strtoul(buf, NULL, 0); From cc8ef52707341e67a12067d6ead991d56ea017ca Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 25 Sep 2013 20:39:45 +0800 Subject: [PATCH 05/18] ACPI / AC: convert ACPI ac driver to platform bus Signed-off-by: Zhang Rui Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ac.c | 163 +++++++++++++++++------------------ drivers/acpi/acpi_platform.c | 1 + 2 files changed, 81 insertions(+), 83 deletions(-) diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index f37beaa32750..324b5a096eff 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -34,6 +34,7 @@ #include #include #endif +#include #include #include #include @@ -61,39 +62,12 @@ extern void *acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir); static int acpi_ac_open_fs(struct inode *inode, struct file *file); #endif -static int acpi_ac_add(struct acpi_device *device); -static int acpi_ac_remove(struct acpi_device *device); -static void acpi_ac_notify(struct acpi_device *device, u32 event); - -static const struct acpi_device_id ac_device_ids[] = { - {"ACPI0003", 0}, - {"", 0}, -}; -MODULE_DEVICE_TABLE(acpi, ac_device_ids); - -#ifdef CONFIG_PM_SLEEP -static int acpi_ac_resume(struct device *dev); -#endif -static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume); - static int ac_sleep_before_get_state_ms; -static struct acpi_driver acpi_ac_driver = { - .name = "ac", - .class = ACPI_AC_CLASS, - .ids = ac_device_ids, - .flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS, - .ops = { - .add = acpi_ac_add, - .remove = acpi_ac_remove, - .notify = acpi_ac_notify, - }, - .drv.pm = &acpi_ac_pm, -}; - struct acpi_ac { struct power_supply charger; - struct acpi_device * device; + struct acpi_device *adev; + struct platform_device *pdev; unsigned long long state; }; @@ -115,15 +89,13 @@ static const struct file_operations acpi_ac_fops = { static int acpi_ac_get_state(struct acpi_ac *ac) { - acpi_status status = AE_OK; + acpi_status status; - - if (!ac) - return -EINVAL; - - status = acpi_evaluate_integer(ac->device->handle, "_PSR", NULL, &ac->state); + status = acpi_evaluate_integer(ac->adev->handle, "_PSR", NULL, + &ac->state); if (ACPI_FAILURE(status)) { - ACPI_EXCEPTION((AE_INFO, status, "Error reading AC Adapter state")); + ACPI_EXCEPTION((AE_INFO, status, + "Error reading AC Adapter state")); ac->state = ACPI_AC_STATUS_UNKNOWN; return -ENODEV; } @@ -201,36 +173,36 @@ static int acpi_ac_open_fs(struct inode *inode, struct file *file) return single_open(file, acpi_ac_seq_show, PDE_DATA(inode)); } -static int acpi_ac_add_fs(struct acpi_device *device) +static int acpi_ac_add_fs(struct acpi_ac *ac) { struct proc_dir_entry *entry = NULL; printk(KERN_WARNING PREFIX "Deprecated procfs I/F for AC is loaded," " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n"); - if (!acpi_device_dir(device)) { - acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), - acpi_ac_dir); - if (!acpi_device_dir(device)) + if (!acpi_device_dir(ac->adev)) { + acpi_device_dir(ac->adev) = + proc_mkdir(acpi_device_bid(ac->adev), acpi_ac_dir); + if (!acpi_device_dir(ac->adev)) return -ENODEV; } /* 'state' [R] */ entry = proc_create_data(ACPI_AC_FILE_STATE, - S_IRUGO, acpi_device_dir(device), - &acpi_ac_fops, acpi_driver_data(device)); + S_IRUGO, acpi_device_dir(ac->adev), + &acpi_ac_fops, ac); if (!entry) return -ENODEV; return 0; } -static int acpi_ac_remove_fs(struct acpi_device *device) +static int acpi_ac_remove_fs(struct acpi_ac *ac) { - if (acpi_device_dir(device)) { - remove_proc_entry(ACPI_AC_FILE_STATE, acpi_device_dir(device)); - - remove_proc_entry(acpi_device_bid(device), acpi_ac_dir); - acpi_device_dir(device) = NULL; + if (acpi_device_dir(ac->adev)) { + remove_proc_entry(ACPI_AC_FILE_STATE, + acpi_device_dir(ac->adev)); + remove_proc_entry(acpi_device_bid(ac->adev), acpi_ac_dir); + acpi_device_dir(ac->adev) = NULL; } return 0; @@ -241,10 +213,9 @@ static int acpi_ac_remove_fs(struct acpi_device *device) Driver Model -------------------------------------------------------------------------- */ -static void acpi_ac_notify(struct acpi_device *device, u32 event) +static void acpi_ac_notify_handler(acpi_handle handle, u32 event, void *data) { - struct acpi_ac *ac = acpi_driver_data(device); - + struct acpi_ac *ac = data; if (!ac) return; @@ -267,10 +238,10 @@ static void acpi_ac_notify(struct acpi_device *device, u32 event) msleep(ac_sleep_before_get_state_ms); acpi_ac_get_state(ac); - acpi_bus_generate_netlink_event(device->pnp.device_class, - dev_name(&device->dev), event, - (u32) ac->state); - acpi_notifier_call_chain(device, event, (u32) ac->state); + acpi_bus_generate_netlink_event(ac->adev->pnp.device_class, + dev_name(&ac->pdev->dev), + event, (u32) ac->state); + acpi_notifier_call_chain(ac->adev, event, (u32) ac->state); kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); } @@ -295,50 +266,61 @@ static struct dmi_system_id ac_dmi_table[] = { {}, }; -static int acpi_ac_add(struct acpi_device *device) +static int acpi_ac_probe(struct platform_device *pdev) { int result = 0; struct acpi_ac *ac = NULL; + struct acpi_device *adev; - - if (!device) + if (!pdev) return -EINVAL; + result = acpi_bus_get_device(ACPI_HANDLE(&pdev->dev), &adev); + if (result) + return -ENODEV; + ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL); if (!ac) return -ENOMEM; - ac->device = device; - strcpy(acpi_device_name(device), ACPI_AC_DEVICE_NAME); - strcpy(acpi_device_class(device), ACPI_AC_CLASS); - device->driver_data = ac; + strcpy(acpi_device_name(adev), ACPI_AC_DEVICE_NAME); + strcpy(acpi_device_class(adev), ACPI_AC_CLASS); + ac->adev = adev; + ac->pdev = pdev; + platform_set_drvdata(pdev, ac); result = acpi_ac_get_state(ac); if (result) goto end; #ifdef CONFIG_ACPI_PROCFS_POWER - result = acpi_ac_add_fs(device); -#endif + result = acpi_ac_add_fs(ac); if (result) goto end; - ac->charger.name = acpi_device_bid(device); +#endif + ac->charger.name = acpi_device_bid(adev); ac->charger.type = POWER_SUPPLY_TYPE_MAINS; ac->charger.properties = ac_props; ac->charger.num_properties = ARRAY_SIZE(ac_props); ac->charger.get_property = get_ac_property; - result = power_supply_register(&ac->device->dev, &ac->charger); + result = power_supply_register(&pdev->dev, &ac->charger); if (result) goto end; + result = acpi_install_notify_handler(ACPI_HANDLE(&pdev->dev), + ACPI_DEVICE_NOTIFY, acpi_ac_notify_handler, ac); + if (result) { + power_supply_unregister(&ac->charger); + goto end; + } printk(KERN_INFO PREFIX "%s [%s] (%s)\n", - acpi_device_name(device), acpi_device_bid(device), + acpi_device_name(adev), acpi_device_bid(adev), ac->state ? "on-line" : "off-line"); end: if (result) { #ifdef CONFIG_ACPI_PROCFS_POWER - acpi_ac_remove_fs(device); + acpi_ac_remove_fs(ac); #endif kfree(ac); } @@ -356,7 +338,7 @@ static int acpi_ac_resume(struct device *dev) if (!dev) return -EINVAL; - ac = acpi_driver_data(to_acpi_device(dev)); + ac = platform_get_drvdata(to_platform_device(dev)); if (!ac) return -EINVAL; @@ -368,21 +350,24 @@ static int acpi_ac_resume(struct device *dev) return 0; } #endif +static SIMPLE_DEV_PM_OPS(acpi_ac_pm_ops, NULL, acpi_ac_resume); -static int acpi_ac_remove(struct acpi_device *device) +static int acpi_ac_remove(struct platform_device *pdev) { - struct acpi_ac *ac = NULL; + struct acpi_ac *ac; - - if (!device || !acpi_driver_data(device)) + if (!pdev) return -EINVAL; - ac = acpi_driver_data(device); + acpi_remove_notify_handler(ACPI_HANDLE(&pdev->dev), + ACPI_DEVICE_NOTIFY, acpi_ac_notify_handler); + ac = platform_get_drvdata(pdev); if (ac->charger.dev) power_supply_unregister(&ac->charger); + #ifdef CONFIG_ACPI_PROCFS_POWER - acpi_ac_remove_fs(device); + acpi_ac_remove_fs(ac); #endif kfree(ac); @@ -390,6 +375,23 @@ static int acpi_ac_remove(struct acpi_device *device) return 0; } +static const struct acpi_device_id acpi_ac_match[] = { + { "ACPI0003", 0 }, + { } +}; +MODULE_DEVICE_TABLE(acpi, acpi_ac_match); + +static struct platform_driver acpi_ac_driver = { + .probe = acpi_ac_probe, + .remove = acpi_ac_remove, + .driver = { + .name = "acpi-ac", + .owner = THIS_MODULE, + .pm = &acpi_ac_pm_ops, + .acpi_match_table = ACPI_PTR(acpi_ac_match), + }, +}; + static int __init acpi_ac_init(void) { int result; @@ -403,7 +405,7 @@ static int __init acpi_ac_init(void) return -ENODEV; #endif - result = acpi_bus_register_driver(&acpi_ac_driver); + result = platform_driver_register(&acpi_ac_driver); if (result < 0) { #ifdef CONFIG_ACPI_PROCFS_POWER acpi_unlock_ac_dir(acpi_ac_dir); @@ -416,15 +418,10 @@ static int __init acpi_ac_init(void) static void __exit acpi_ac_exit(void) { - - acpi_bus_unregister_driver(&acpi_ac_driver); - + platform_driver_unregister(&acpi_ac_driver); #ifdef CONFIG_ACPI_PROCFS_POWER acpi_unlock_ac_dir(acpi_ac_dir); #endif - - return; } - module_init(acpi_ac_init); module_exit(acpi_ac_exit); diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 1bde12708f9e..6259bc28ef18 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -29,6 +29,7 @@ ACPI_MODULE_NAME("platform"); static const struct acpi_device_id acpi_platform_device_ids[] = { { "PNP0D40" }, + { "ACPI0003" }, { } }; From 11fa8da5fb14b23ff796c09d61a162a27deeb04f Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 25 Sep 2013 20:39:46 +0800 Subject: [PATCH 06/18] ideapad_laptop: introduce #ifdef CONFIG_PM_SLEEP for PM specific code ideapad_acpi_resume() and ideapad_pm is meaningful only if CONFIG_PM_SLEEP is set. Thus introduce #ifdef for this piece of code. Signed-off-by: Zhang Rui CC: Matthew Garrett CC: Ike Panhc Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/ideapad-laptop.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 89c4519d48ac..5021c55210e8 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -901,6 +901,7 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event) } } +#ifdef CONFIG_PM_SLEEP static int ideapad_acpi_resume(struct device *device) { ideapad_sync_rfk_state(ideapad_priv); @@ -909,6 +910,7 @@ static int ideapad_acpi_resume(struct device *device) } static SIMPLE_DEV_PM_OPS(ideapad_pm, NULL, ideapad_acpi_resume); +#endif static struct acpi_driver ideapad_acpi_driver = { .name = "ideapad_acpi", @@ -917,7 +919,9 @@ static struct acpi_driver ideapad_acpi_driver = { .ops.add = ideapad_acpi_add, .ops.remove = ideapad_acpi_remove, .ops.notify = ideapad_acpi_notify, +#ifdef CONFIG_PM_SLEEP .drv.pm = &ideapad_pm, +#endif .owner = THIS_MODULE, }; module_acpi_driver(ideapad_acpi_driver); From 469f64349c5e7bd072d1ca5a72b8f2a80ef118f2 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 25 Sep 2013 20:39:47 +0800 Subject: [PATCH 07/18] ideapad_laptop: introduce struct acpi_device pointer to ideapad_private structure Introduce struct acpi_device pointer to ideapad_private structure. At the same time, replace all adevice with adev to be short and consistent. Signed-off-by: Zhang Rui CC: Matthew Garrett CC: Ike Panhc Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/ideapad-laptop.c | 48 ++++++++++++++------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 5021c55210e8..edd3656b07b9 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -73,6 +73,7 @@ enum { }; struct ideapad_private { + struct acpi_device *adev; struct rfkill *rfk[IDEAPAD_RFKILL_DEV_NUM]; struct platform_device *platform_device; struct input_dev *inputdev; @@ -468,9 +469,9 @@ static void ideapad_sync_rfk_state(struct ideapad_private *priv) rfkill_set_hw_state(priv->rfk[i], hw_blocked); } -static int ideapad_register_rfkill(struct acpi_device *adevice, int dev) +static int ideapad_register_rfkill(struct acpi_device *adev, int dev) { - struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); + struct ideapad_private *priv = dev_get_drvdata(&adev->dev); int ret; unsigned long sw_blocked; @@ -482,7 +483,7 @@ static int ideapad_register_rfkill(struct acpi_device *adevice, int dev) return 0; } - priv->rfk[dev] = rfkill_alloc(ideapad_rfk_data[dev].name, &adevice->dev, + priv->rfk[dev] = rfkill_alloc(ideapad_rfk_data[dev].name, &adev->dev, ideapad_rfk_data[dev].type, &ideapad_rfk_ops, (void *)(long)dev); if (!priv->rfk[dev]) @@ -504,9 +505,9 @@ static int ideapad_register_rfkill(struct acpi_device *adevice, int dev) return 0; } -static void ideapad_unregister_rfkill(struct acpi_device *adevice, int dev) +static void ideapad_unregister_rfkill(struct acpi_device *adev, int dev) { - struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); + struct ideapad_private *priv = dev_get_drvdata(&adev->dev); if (!priv->rfk[dev]) return; @@ -761,13 +762,13 @@ static const struct acpi_device_id ideapad_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); -static void ideapad_sync_touchpad_state(struct acpi_device *adevice) +static void ideapad_sync_touchpad_state(struct acpi_device *adev) { - struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); + struct ideapad_private *priv = dev_get_drvdata(&adev->dev); unsigned long value; /* Without reading from EC touchpad LED doesn't switch state */ - if (!read_ec_data(adevice->handle, VPCCMD_R_TOUCHPAD, &value)) { + if (!read_ec_data(adev->handle, VPCCMD_R_TOUCHPAD, &value)) { /* Some IdeaPads don't really turn off touchpad - they only * switch the LED state. We (de)activate KBC AUX port to turn * touchpad off and on. We send KEY_TOUCHPAD_OFF and @@ -779,22 +780,23 @@ static void ideapad_sync_touchpad_state(struct acpi_device *adevice) } } -static int ideapad_acpi_add(struct acpi_device *adevice) +static int ideapad_acpi_add(struct acpi_device *adev) { int ret, i; int cfg; struct ideapad_private *priv; - if (read_method_int(adevice->handle, "_CFG", &cfg)) + if (read_method_int(adev->handle, "_CFG", &cfg)) return -ENODEV; priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; - dev_set_drvdata(&adevice->dev, priv); + dev_set_drvdata(&adev->dev, priv); ideapad_priv = priv; - ideapad_handle = adevice->handle; + ideapad_handle = adev->handle; priv->cfg = cfg; + priv->adev = adev; ret = ideapad_platform_init(priv); if (ret) @@ -810,12 +812,12 @@ static int ideapad_acpi_add(struct acpi_device *adevice) for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) { if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) - ideapad_register_rfkill(adevice, i); + ideapad_register_rfkill(adev, i); else priv->rfk[i] = NULL; } ideapad_sync_rfk_state(priv); - ideapad_sync_touchpad_state(adevice); + ideapad_sync_touchpad_state(adev); if (!acpi_video_backlight_support()) { ret = ideapad_backlight_init(priv); @@ -827,7 +829,7 @@ static int ideapad_acpi_add(struct acpi_device *adevice) backlight_failed: for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) - ideapad_unregister_rfkill(adevice, i); + ideapad_unregister_rfkill(adev, i); ideapad_input_exit(priv); input_failed: ideapad_debugfs_exit(priv); @@ -838,27 +840,27 @@ platform_failed: return ret; } -static int ideapad_acpi_remove(struct acpi_device *adevice) +static int ideapad_acpi_remove(struct acpi_device *adev) { - struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); + struct ideapad_private *priv = dev_get_drvdata(&adev->dev); int i; ideapad_backlight_exit(priv); for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) - ideapad_unregister_rfkill(adevice, i); + ideapad_unregister_rfkill(adev, i); ideapad_input_exit(priv); ideapad_debugfs_exit(priv); ideapad_platform_exit(priv); - dev_set_drvdata(&adevice->dev, NULL); + dev_set_drvdata(&adev->dev, NULL); kfree(priv); return 0; } -static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event) +static void ideapad_acpi_notify(struct acpi_device *adev, u32 event) { - struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); - acpi_handle handle = adevice->handle; + struct ideapad_private *priv = dev_get_drvdata(&adev->dev); + acpi_handle handle = adev->handle; unsigned long vpc1, vpc2, vpc_bit; if (read_ec_data(handle, VPCCMD_R_VPC1, &vpc1)) @@ -880,7 +882,7 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event) ideapad_input_report(priv, vpc_bit); break; case 5: - ideapad_sync_touchpad_state(adevice); + ideapad_sync_touchpad_state(adev); break; case 4: ideapad_backlight_notify_brightness(priv); From 75a11f11a49da9862ff2fbae75428076571cebe4 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 25 Sep 2013 20:39:48 +0800 Subject: [PATCH 08/18] ideapad_laptop: convert internal function calls to use ideapad_private as parameter As struct ideapad_private has all the information needed for any operations, convert ideapad_register_rfkill()/ideapad_unregister_rfkill() and ideapad_sync_touchpad_state() to use struct ideapad_private as the parameter, to be consistent with the others. Signed-off-by: Zhang Rui CC: Matthew Garrett CC: Ike Panhc Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/ideapad-laptop.c | 38 +++++++++++++++------------ 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index edd3656b07b9..70fb5ba7e47a 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -469,9 +469,8 @@ static void ideapad_sync_rfk_state(struct ideapad_private *priv) rfkill_set_hw_state(priv->rfk[i], hw_blocked); } -static int ideapad_register_rfkill(struct acpi_device *adev, int dev) +static int ideapad_register_rfkill(struct ideapad_private *priv, int dev) { - struct ideapad_private *priv = dev_get_drvdata(&adev->dev); int ret; unsigned long sw_blocked; @@ -483,8 +482,10 @@ static int ideapad_register_rfkill(struct acpi_device *adev, int dev) return 0; } - priv->rfk[dev] = rfkill_alloc(ideapad_rfk_data[dev].name, &adev->dev, - ideapad_rfk_data[dev].type, &ideapad_rfk_ops, + priv->rfk[dev] = rfkill_alloc(ideapad_rfk_data[dev].name, + &priv->adev->dev, + ideapad_rfk_data[dev].type, + &ideapad_rfk_ops, (void *)(long)dev); if (!priv->rfk[dev]) return -ENOMEM; @@ -505,10 +506,8 @@ static int ideapad_register_rfkill(struct acpi_device *adev, int dev) return 0; } -static void ideapad_unregister_rfkill(struct acpi_device *adev, int dev) +static void ideapad_unregister_rfkill(struct ideapad_private *priv, int dev) { - struct ideapad_private *priv = dev_get_drvdata(&adev->dev); - if (!priv->rfk[dev]) return; @@ -762,13 +761,12 @@ static const struct acpi_device_id ideapad_device_ids[] = { }; MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); -static void ideapad_sync_touchpad_state(struct acpi_device *adev) +static void ideapad_sync_touchpad_state(struct ideapad_private *priv) { - struct ideapad_private *priv = dev_get_drvdata(&adev->dev); unsigned long value; /* Without reading from EC touchpad LED doesn't switch state */ - if (!read_ec_data(adev->handle, VPCCMD_R_TOUCHPAD, &value)) { + if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) { /* Some IdeaPads don't really turn off touchpad - they only * switch the LED state. We (de)activate KBC AUX port to turn * touchpad off and on. We send KEY_TOUCHPAD_OFF and @@ -812,12 +810,12 @@ static int ideapad_acpi_add(struct acpi_device *adev) for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) { if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) - ideapad_register_rfkill(adev, i); + ideapad_register_rfkill(priv, i); else priv->rfk[i] = NULL; } ideapad_sync_rfk_state(priv); - ideapad_sync_touchpad_state(adev); + ideapad_sync_touchpad_state(priv); if (!acpi_video_backlight_support()) { ret = ideapad_backlight_init(priv); @@ -829,7 +827,7 @@ static int ideapad_acpi_add(struct acpi_device *adev) backlight_failed: for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) - ideapad_unregister_rfkill(adev, i); + ideapad_unregister_rfkill(priv, i); ideapad_input_exit(priv); input_failed: ideapad_debugfs_exit(priv); @@ -847,7 +845,7 @@ static int ideapad_acpi_remove(struct acpi_device *adev) ideapad_backlight_exit(priv); for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) - ideapad_unregister_rfkill(adev, i); + ideapad_unregister_rfkill(priv, i); ideapad_input_exit(priv); ideapad_debugfs_exit(priv); ideapad_platform_exit(priv); @@ -882,7 +880,7 @@ static void ideapad_acpi_notify(struct acpi_device *adev, u32 event) ideapad_input_report(priv, vpc_bit); break; case 5: - ideapad_sync_touchpad_state(adev); + ideapad_sync_touchpad_state(priv); break; case 4: ideapad_backlight_notify_brightness(priv); @@ -906,8 +904,14 @@ static void ideapad_acpi_notify(struct acpi_device *adev, u32 event) #ifdef CONFIG_PM_SLEEP static int ideapad_acpi_resume(struct device *device) { - ideapad_sync_rfk_state(ideapad_priv); - ideapad_sync_touchpad_state(to_acpi_device(device)); + struct ideapad_private *priv; + + if (!device) + return -EINVAL; + priv = dev_get_drvdata(device); + + ideapad_sync_rfk_state(priv); + ideapad_sync_touchpad_state(priv); return 0; } From 331e0ea243ed15bbf0958f46861505f2065e99f8 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 25 Sep 2013 20:39:49 +0800 Subject: [PATCH 09/18] ideapad_laptop: remove ideapad_handle and ideapad_priv The current code use ideapad_handle and ideapad_priv to store some information for the ideapad device. But as they are global/static variables, the driver will be broken if there are more than one ideapad ACPI device node on a platform. Although this does not happen for now and may not happen in the future, but still, this is a software bug. Remove these two variables in this patch. Signed-off-by: Zhang Rui CC: Matthew Garrett CC: Ike Panhc Signed-off-by: Rafael J. Wysocki --- drivers/platform/x86/ideapad-laptop.c | 114 ++++++++++++++++---------- 1 file changed, 69 insertions(+), 45 deletions(-) diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 70fb5ba7e47a..cad48b5cc409 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -72,9 +72,15 @@ enum { VPCCMD_W_BL_POWER = 0x33, }; +struct ideapad_rfk_priv { + int dev; + struct ideapad_private *priv; +}; + struct ideapad_private { struct acpi_device *adev; struct rfkill *rfk[IDEAPAD_RFKILL_DEV_NUM]; + struct ideapad_rfk_priv rfk_priv[IDEAPAD_RFKILL_DEV_NUM]; struct platform_device *platform_device; struct input_dev *inputdev; struct backlight_device *blightdev; @@ -82,8 +88,6 @@ struct ideapad_private { unsigned long cfg; }; -static acpi_handle ideapad_handle; -static struct ideapad_private *ideapad_priv; static bool no_bt_rfkill; module_param(no_bt_rfkill, bool, 0444); MODULE_PARM_DESC(no_bt_rfkill, "No rfkill for bluetooth."); @@ -201,34 +205,38 @@ static int write_ec_cmd(acpi_handle handle, int cmd, unsigned long data) */ static int debugfs_status_show(struct seq_file *s, void *data) { + struct ideapad_private *priv = s->private; unsigned long value; - if (!read_ec_data(ideapad_handle, VPCCMD_R_BL_MAX, &value)) + if (!priv) + return -EINVAL; + + if (!read_ec_data(priv->adev->handle, VPCCMD_R_BL_MAX, &value)) seq_printf(s, "Backlight max:\t%lu\n", value); - if (!read_ec_data(ideapad_handle, VPCCMD_R_BL, &value)) + if (!read_ec_data(priv->adev->handle, VPCCMD_R_BL, &value)) seq_printf(s, "Backlight now:\t%lu\n", value); - if (!read_ec_data(ideapad_handle, VPCCMD_R_BL_POWER, &value)) + if (!read_ec_data(priv->adev->handle, VPCCMD_R_BL_POWER, &value)) seq_printf(s, "BL power value:\t%s\n", value ? "On" : "Off"); seq_printf(s, "=====================\n"); - if (!read_ec_data(ideapad_handle, VPCCMD_R_RF, &value)) + if (!read_ec_data(priv->adev->handle, VPCCMD_R_RF, &value)) seq_printf(s, "Radio status:\t%s(%lu)\n", value ? "On" : "Off", value); - if (!read_ec_data(ideapad_handle, VPCCMD_R_WIFI, &value)) + if (!read_ec_data(priv->adev->handle, VPCCMD_R_WIFI, &value)) seq_printf(s, "Wifi status:\t%s(%lu)\n", value ? "On" : "Off", value); - if (!read_ec_data(ideapad_handle, VPCCMD_R_BT, &value)) + if (!read_ec_data(priv->adev->handle, VPCCMD_R_BT, &value)) seq_printf(s, "BT status:\t%s(%lu)\n", value ? "On" : "Off", value); - if (!read_ec_data(ideapad_handle, VPCCMD_R_3G, &value)) + if (!read_ec_data(priv->adev->handle, VPCCMD_R_3G, &value)) seq_printf(s, "3G status:\t%s(%lu)\n", value ? "On" : "Off", value); seq_printf(s, "=====================\n"); - if (!read_ec_data(ideapad_handle, VPCCMD_R_TOUCHPAD, &value)) + if (!read_ec_data(priv->adev->handle, VPCCMD_R_TOUCHPAD, &value)) seq_printf(s, "Touchpad status:%s(%lu)\n", value ? "On" : "Off", value); - if (!read_ec_data(ideapad_handle, VPCCMD_R_CAMERA, &value)) + if (!read_ec_data(priv->adev->handle, VPCCMD_R_CAMERA, &value)) seq_printf(s, "Camera status:\t%s(%lu)\n", value ? "On" : "Off", value); @@ -237,7 +245,7 @@ static int debugfs_status_show(struct seq_file *s, void *data) static int debugfs_status_open(struct inode *inode, struct file *file) { - return single_open(file, debugfs_status_show, NULL); + return single_open(file, debugfs_status_show, inode->i_private); } static const struct file_operations debugfs_status_fops = { @@ -250,21 +258,23 @@ static const struct file_operations debugfs_status_fops = { static int debugfs_cfg_show(struct seq_file *s, void *data) { - if (!ideapad_priv) { + struct ideapad_private *priv = s->private; + + if (!priv) { seq_printf(s, "cfg: N/A\n"); } else { seq_printf(s, "cfg: 0x%.8lX\n\nCapability: ", - ideapad_priv->cfg); - if (test_bit(CFG_BT_BIT, &ideapad_priv->cfg)) + priv->cfg); + if (test_bit(CFG_BT_BIT, &priv->cfg)) seq_printf(s, "Bluetooth "); - if (test_bit(CFG_3G_BIT, &ideapad_priv->cfg)) + if (test_bit(CFG_3G_BIT, &priv->cfg)) seq_printf(s, "3G "); - if (test_bit(CFG_WIFI_BIT, &ideapad_priv->cfg)) + if (test_bit(CFG_WIFI_BIT, &priv->cfg)) seq_printf(s, "Wireless "); - if (test_bit(CFG_CAMERA_BIT, &ideapad_priv->cfg)) + if (test_bit(CFG_CAMERA_BIT, &priv->cfg)) seq_printf(s, "Camera "); seq_printf(s, "\nGraphic: "); - switch ((ideapad_priv->cfg)&0x700) { + switch ((priv->cfg)&0x700) { case 0x100: seq_printf(s, "Intel"); break; @@ -288,7 +298,7 @@ static int debugfs_cfg_show(struct seq_file *s, void *data) static int debugfs_cfg_open(struct inode *inode, struct file *file) { - return single_open(file, debugfs_cfg_show, NULL); + return single_open(file, debugfs_cfg_show, inode->i_private); } static const struct file_operations debugfs_cfg_fops = { @@ -309,14 +319,14 @@ static int ideapad_debugfs_init(struct ideapad_private *priv) goto errout; } - node = debugfs_create_file("cfg", S_IRUGO, priv->debug, NULL, + node = debugfs_create_file("cfg", S_IRUGO, priv->debug, priv, &debugfs_cfg_fops); if (!node) { pr_err("failed to create cfg in debugfs"); goto errout; } - node = debugfs_create_file("status", S_IRUGO, priv->debug, NULL, + node = debugfs_create_file("status", S_IRUGO, priv->debug, priv, &debugfs_status_fops); if (!node) { pr_err("failed to create status in debugfs"); @@ -343,8 +353,9 @@ static ssize_t show_ideapad_cam(struct device *dev, char *buf) { unsigned long result; + struct ideapad_private *priv = dev_get_drvdata(dev); - if (read_ec_data(ideapad_handle, VPCCMD_R_CAMERA, &result)) + if (read_ec_data(priv->adev->handle, VPCCMD_R_CAMERA, &result)) return sprintf(buf, "-1\n"); return sprintf(buf, "%lu\n", result); } @@ -354,12 +365,13 @@ static ssize_t store_ideapad_cam(struct device *dev, const char *buf, size_t count) { int ret, state; + struct ideapad_private *priv = dev_get_drvdata(dev); if (!count) return 0; if (sscanf(buf, "%i", &state) != 1) return -EINVAL; - ret = write_ec_cmd(ideapad_handle, VPCCMD_W_CAMERA, state); + ret = write_ec_cmd(priv->adev->handle, VPCCMD_W_CAMERA, state); if (ret < 0) return -EIO; return count; @@ -372,8 +384,9 @@ static ssize_t show_ideapad_fan(struct device *dev, char *buf) { unsigned long result; + struct ideapad_private *priv = dev_get_drvdata(dev); - if (read_ec_data(ideapad_handle, VPCCMD_R_FAN, &result)) + if (read_ec_data(priv->adev->handle, VPCCMD_R_FAN, &result)) return sprintf(buf, "-1\n"); return sprintf(buf, "%lu\n", result); } @@ -383,6 +396,7 @@ static ssize_t store_ideapad_fan(struct device *dev, const char *buf, size_t count) { int ret, state; + struct ideapad_private *priv = dev_get_drvdata(dev); if (!count) return 0; @@ -390,7 +404,7 @@ static ssize_t store_ideapad_fan(struct device *dev, return -EINVAL; if (state < 0 || state > 4 || state == 3) return -EINVAL; - ret = write_ec_cmd(ideapad_handle, VPCCMD_W_FAN, state); + ret = write_ec_cmd(priv->adev->handle, VPCCMD_W_FAN, state); if (ret < 0) return -EIO; return count; @@ -416,7 +430,8 @@ static umode_t ideapad_is_visible(struct kobject *kobj, supported = test_bit(CFG_CAMERA_BIT, &(priv->cfg)); else if (attr == &dev_attr_fan_mode.attr) { unsigned long value; - supported = !read_ec_data(ideapad_handle, VPCCMD_R_FAN, &value); + supported = !read_ec_data(priv->adev->handle, VPCCMD_R_FAN, + &value); } else supported = true; @@ -446,9 +461,9 @@ const struct ideapad_rfk_data ideapad_rfk_data[] = { static int ideapad_rfk_set(void *data, bool blocked) { - unsigned long opcode = (unsigned long)data; + struct ideapad_rfk_priv *priv = data; - return write_ec_cmd(ideapad_handle, opcode, !blocked); + return write_ec_cmd(priv->priv->adev->handle, priv->dev, !blocked); } static struct rfkill_ops ideapad_rfk_ops = { @@ -460,7 +475,7 @@ static void ideapad_sync_rfk_state(struct ideapad_private *priv) unsigned long hw_blocked; int i; - if (read_ec_data(ideapad_handle, VPCCMD_R_RF, &hw_blocked)) + if (read_ec_data(priv->adev->handle, VPCCMD_R_RF, &hw_blocked)) return; hw_blocked = !hw_blocked; @@ -477,20 +492,22 @@ static int ideapad_register_rfkill(struct ideapad_private *priv, int dev) if (no_bt_rfkill && (ideapad_rfk_data[dev].type == RFKILL_TYPE_BLUETOOTH)) { /* Force to enable bluetooth when no_bt_rfkill=1 */ - write_ec_cmd(ideapad_handle, + write_ec_cmd(priv->adev->handle, ideapad_rfk_data[dev].opcode, 1); return 0; } + priv->rfk_priv[dev].dev = dev; + priv->rfk_priv[dev].priv = priv; priv->rfk[dev] = rfkill_alloc(ideapad_rfk_data[dev].name, &priv->adev->dev, ideapad_rfk_data[dev].type, &ideapad_rfk_ops, - (void *)(long)dev); + &priv->rfk_priv[dev]); if (!priv->rfk[dev]) return -ENOMEM; - if (read_ec_data(ideapad_handle, ideapad_rfk_data[dev].opcode-1, + if (read_ec_data(priv->adev->handle, ideapad_rfk_data[dev].opcode-1, &sw_blocked)) { rfkill_init_sw_state(priv->rfk[dev], 0); } else { @@ -623,7 +640,7 @@ static void ideapad_input_novokey(struct ideapad_private *priv) { unsigned long long_pressed; - if (read_ec_data(ideapad_handle, VPCCMD_R_NOVO, &long_pressed)) + if (read_ec_data(priv->adev->handle, VPCCMD_R_NOVO, &long_pressed)) return; if (long_pressed) ideapad_input_report(priv, 17); @@ -635,7 +652,7 @@ static void ideapad_check_special_buttons(struct ideapad_private *priv) { unsigned long bit, value; - read_ec_data(ideapad_handle, VPCCMD_R_SPECIAL_BUTTONS, &value); + read_ec_data(priv->adev->handle, VPCCMD_R_SPECIAL_BUTTONS, &value); for (bit = 0; bit < 16; bit++) { if (test_bit(bit, &value)) { @@ -662,19 +679,28 @@ static void ideapad_check_special_buttons(struct ideapad_private *priv) */ static int ideapad_backlight_get_brightness(struct backlight_device *blightdev) { + struct ideapad_private *priv = bl_get_data(blightdev); unsigned long now; - if (read_ec_data(ideapad_handle, VPCCMD_R_BL, &now)) + if (!priv) + return -EINVAL; + + if (read_ec_data(priv->adev->handle, VPCCMD_R_BL, &now)) return -EIO; return now; } static int ideapad_backlight_update_status(struct backlight_device *blightdev) { - if (write_ec_cmd(ideapad_handle, VPCCMD_W_BL, + struct ideapad_private *priv = bl_get_data(blightdev); + + if (!priv) + return -EINVAL; + + if (write_ec_cmd(priv->adev->handle, VPCCMD_W_BL, blightdev->props.brightness)) return -EIO; - if (write_ec_cmd(ideapad_handle, VPCCMD_W_BL_POWER, + if (write_ec_cmd(priv->adev->handle, VPCCMD_W_BL_POWER, blightdev->props.power == FB_BLANK_POWERDOWN ? 0 : 1)) return -EIO; @@ -692,11 +718,11 @@ static int ideapad_backlight_init(struct ideapad_private *priv) struct backlight_properties props; unsigned long max, now, power; - if (read_ec_data(ideapad_handle, VPCCMD_R_BL_MAX, &max)) + if (read_ec_data(priv->adev->handle, VPCCMD_R_BL_MAX, &max)) return -EIO; - if (read_ec_data(ideapad_handle, VPCCMD_R_BL, &now)) + if (read_ec_data(priv->adev->handle, VPCCMD_R_BL, &now)) return -EIO; - if (read_ec_data(ideapad_handle, VPCCMD_R_BL_POWER, &power)) + if (read_ec_data(priv->adev->handle, VPCCMD_R_BL_POWER, &power)) return -EIO; memset(&props, 0, sizeof(struct backlight_properties)); @@ -734,7 +760,7 @@ static void ideapad_backlight_notify_power(struct ideapad_private *priv) if (!blightdev) return; - if (read_ec_data(ideapad_handle, VPCCMD_R_BL_POWER, &power)) + if (read_ec_data(priv->adev->handle, VPCCMD_R_BL_POWER, &power)) return; blightdev->props.power = power ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; } @@ -745,7 +771,7 @@ static void ideapad_backlight_notify_brightness(struct ideapad_private *priv) /* if we control brightness via acpi video driver */ if (priv->blightdev == NULL) { - read_ec_data(ideapad_handle, VPCCMD_R_BL, &now); + read_ec_data(priv->adev->handle, VPCCMD_R_BL, &now); return; } @@ -791,8 +817,6 @@ static int ideapad_acpi_add(struct acpi_device *adev) if (!priv) return -ENOMEM; dev_set_drvdata(&adev->dev, priv); - ideapad_priv = priv; - ideapad_handle = adev->handle; priv->cfg = cfg; priv->adev = adev; From b5c37b798f2d29b9b2926e0abf008a13ce6c91fe Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 25 Sep 2013 20:39:50 +0800 Subject: [PATCH 10/18] ideapad_laptop: convert ideapad device/driver to platform bus This patch does two things, 1. enumerate the ideapad device node to platform bus. 2. convert the current driver from ACPI bus to platform bus. Note, with this patch, the platform device node created by ACPI, with the name VPC2004:00, is used as the parent device of the input, backlight, rfkill sysfs class device. Plus the ideapad_platform private sysfs attributes, i.e. camera_power and fan_mode, are also moved to the new platform device node. The previous platform device node "ideapad" is removed. Signed-off-by: Zhang Rui CC: Matthew Garrett CC: Ike Panhc Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_platform.c | 2 +- drivers/platform/x86/ideapad-laptop.c | 236 ++++++++++++-------------- 2 files changed, 114 insertions(+), 124 deletions(-) diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 6259bc28ef18..c20b02beec7c 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -30,7 +30,7 @@ static const struct acpi_device_id acpi_platform_device_ids[] = { { "PNP0D40" }, { "ACPI0003" }, - + { "VPC2004" }, { } }; diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index cad48b5cc409..6788acc22ab9 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -500,7 +500,7 @@ static int ideapad_register_rfkill(struct ideapad_private *priv, int dev) priv->rfk_priv[dev].priv = priv; priv->rfk[dev] = rfkill_alloc(ideapad_rfk_data[dev].name, - &priv->adev->dev, + &priv->platform_device->dev, ideapad_rfk_data[dev].type, &ideapad_rfk_ops, &priv->rfk_priv[dev]); @@ -535,37 +535,16 @@ static void ideapad_unregister_rfkill(struct ideapad_private *priv, int dev) /* * Platform device */ -static int ideapad_platform_init(struct ideapad_private *priv) +static int ideapad_sysfs_init(struct ideapad_private *priv) { - int result; - - priv->platform_device = platform_device_alloc("ideapad", -1); - if (!priv->platform_device) - return -ENOMEM; - platform_set_drvdata(priv->platform_device, priv); - - result = platform_device_add(priv->platform_device); - if (result) - goto fail_platform_device; - - result = sysfs_create_group(&priv->platform_device->dev.kobj, + return sysfs_create_group(&priv->platform_device->dev.kobj, &ideapad_attribute_group); - if (result) - goto fail_sysfs; - return 0; - -fail_sysfs: - platform_device_del(priv->platform_device); -fail_platform_device: - platform_device_put(priv->platform_device); - return result; } -static void ideapad_platform_exit(struct ideapad_private *priv) +static void ideapad_sysfs_exit(struct ideapad_private *priv) { sysfs_remove_group(&priv->platform_device->dev.kobj, &ideapad_attribute_group); - platform_device_unregister(priv->platform_device); } /* @@ -781,12 +760,6 @@ static void ideapad_backlight_notify_brightness(struct ideapad_private *priv) /* * module init/exit */ -static const struct acpi_device_id ideapad_device_ids[] = { - { "VPC2004", 0}, - { "", 0}, -}; -MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); - static void ideapad_sync_touchpad_state(struct ideapad_private *priv) { unsigned long value; @@ -804,85 +777,9 @@ static void ideapad_sync_touchpad_state(struct ideapad_private *priv) } } -static int ideapad_acpi_add(struct acpi_device *adev) +static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data) { - int ret, i; - int cfg; - struct ideapad_private *priv; - - if (read_method_int(adev->handle, "_CFG", &cfg)) - return -ENODEV; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - dev_set_drvdata(&adev->dev, priv); - priv->cfg = cfg; - priv->adev = adev; - - ret = ideapad_platform_init(priv); - if (ret) - goto platform_failed; - - ret = ideapad_debugfs_init(priv); - if (ret) - goto debugfs_failed; - - ret = ideapad_input_init(priv); - if (ret) - goto input_failed; - - for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) { - if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) - ideapad_register_rfkill(priv, i); - else - priv->rfk[i] = NULL; - } - ideapad_sync_rfk_state(priv); - ideapad_sync_touchpad_state(priv); - - if (!acpi_video_backlight_support()) { - ret = ideapad_backlight_init(priv); - if (ret && ret != -ENODEV) - goto backlight_failed; - } - - return 0; - -backlight_failed: - for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) - ideapad_unregister_rfkill(priv, i); - ideapad_input_exit(priv); -input_failed: - ideapad_debugfs_exit(priv); -debugfs_failed: - ideapad_platform_exit(priv); -platform_failed: - kfree(priv); - return ret; -} - -static int ideapad_acpi_remove(struct acpi_device *adev) -{ - struct ideapad_private *priv = dev_get_drvdata(&adev->dev); - int i; - - ideapad_backlight_exit(priv); - for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) - ideapad_unregister_rfkill(priv, i); - ideapad_input_exit(priv); - ideapad_debugfs_exit(priv); - ideapad_platform_exit(priv); - dev_set_drvdata(&adev->dev, NULL); - kfree(priv); - - return 0; -} - -static void ideapad_acpi_notify(struct acpi_device *adev, u32 event) -{ - struct ideapad_private *priv = dev_get_drvdata(&adev->dev); - acpi_handle handle = adev->handle; + struct ideapad_private *priv = data; unsigned long vpc1, vpc2, vpc_bit; if (read_ec_data(handle, VPCCMD_R_VPC1, &vpc1)) @@ -925,6 +822,95 @@ static void ideapad_acpi_notify(struct acpi_device *adev, u32 event) } } +static int ideapad_acpi_add(struct platform_device *pdev) +{ + int ret, i; + int cfg; + struct ideapad_private *priv; + struct acpi_device *adev; + + ret = acpi_bus_get_device(ACPI_HANDLE(&pdev->dev), &adev); + if (ret) + return -ENODEV; + + if (read_method_int(adev->handle, "_CFG", &cfg)) + return -ENODEV; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + dev_set_drvdata(&pdev->dev, priv); + priv->cfg = cfg; + priv->adev = adev; + priv->platform_device = pdev; + + ret = ideapad_sysfs_init(priv); + if (ret) + goto sysfs_failed; + + ret = ideapad_debugfs_init(priv); + if (ret) + goto debugfs_failed; + + ret = ideapad_input_init(priv); + if (ret) + goto input_failed; + + for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) { + if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) + ideapad_register_rfkill(priv, i); + else + priv->rfk[i] = NULL; + } + ideapad_sync_rfk_state(priv); + ideapad_sync_touchpad_state(priv); + + if (!acpi_video_backlight_support()) { + ret = ideapad_backlight_init(priv); + if (ret && ret != -ENODEV) + goto backlight_failed; + } + ret = acpi_install_notify_handler(adev->handle, + ACPI_DEVICE_NOTIFY, ideapad_acpi_notify, priv); + if (ret) + goto notification_failed; + + return 0; +notification_failed: + ideapad_backlight_exit(priv); +backlight_failed: + for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) + ideapad_unregister_rfkill(priv, i); + ideapad_input_exit(priv); +input_failed: + ideapad_debugfs_exit(priv); +debugfs_failed: + ideapad_sysfs_exit(priv); +sysfs_failed: + kfree(priv); + return ret; +} + +static int ideapad_acpi_remove(struct platform_device *pdev) +{ + struct ideapad_private *priv = dev_get_drvdata(&pdev->dev); + int i; + + acpi_remove_notify_handler(priv->adev->handle, + ACPI_DEVICE_NOTIFY, ideapad_acpi_notify); + ideapad_backlight_exit(priv); + for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) + ideapad_unregister_rfkill(priv, i); + ideapad_input_exit(priv); + ideapad_debugfs_exit(priv); + ideapad_sysfs_exit(priv); + dev_set_drvdata(&pdev->dev, NULL); + kfree(priv); + + return 0; +} + #ifdef CONFIG_PM_SLEEP static int ideapad_acpi_resume(struct device *device) { @@ -938,23 +924,27 @@ static int ideapad_acpi_resume(struct device *device) ideapad_sync_touchpad_state(priv); return 0; } - +#endif static SIMPLE_DEV_PM_OPS(ideapad_pm, NULL, ideapad_acpi_resume); -#endif -static struct acpi_driver ideapad_acpi_driver = { - .name = "ideapad_acpi", - .class = "IdeaPad", - .ids = ideapad_device_ids, - .ops.add = ideapad_acpi_add, - .ops.remove = ideapad_acpi_remove, - .ops.notify = ideapad_acpi_notify, -#ifdef CONFIG_PM_SLEEP - .drv.pm = &ideapad_pm, -#endif - .owner = THIS_MODULE, +static const struct acpi_device_id ideapad_device_ids[] = { + { "VPC2004", 0}, + { "", 0}, }; -module_acpi_driver(ideapad_acpi_driver); +MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); + +static struct platform_driver ideapad_acpi_driver = { + .probe = ideapad_acpi_add, + .remove = ideapad_acpi_remove, + .driver = { + .name = "ideapad_acpi", + .owner = THIS_MODULE, + .pm = &ideapad_pm, + .acpi_match_table = ACPI_PTR(ideapad_device_ids), + }, +}; + +module_platform_driver(ideapad_acpi_driver); MODULE_AUTHOR("David Woodhouse "); MODULE_DESCRIPTION("IdeaPad ACPI Extras"); From 766a8a6dd89268107df1f6783f6a6338efcbf07e Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Fri, 13 Sep 2013 18:15:46 +0300 Subject: [PATCH 11/18] ACPI / thermal: convert printk(LEVEL...) to pr_ Convert printks to pr_* format. Additionally re-use PREFIX constant instead of hardcoded strings. Signed-off-by: Andy Shevchenko Signed-off-by: Rafael J. Wysocki --- drivers/acpi/thermal.c | 43 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 6a0329340b42..e600b5dbfcb6 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -299,8 +299,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No critical threshold\n")); } else if (tmp <= 2732) { - printk(KERN_WARNING FW_BUG "Invalid critical threshold " - "(%llu)\n", tmp); + pr_warn(FW_BUG "Invalid critical threshold (%llu)\n", + tmp); tz->trips.critical.flags.valid = 0; } else { tz->trips.critical.flags.valid = 1; @@ -317,8 +317,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) * Allow override critical threshold */ if (crt_k > tz->trips.critical.temperature) - printk(KERN_WARNING PREFIX - "Critical threshold %d C\n", crt); + pr_warn(PREFIX "Critical threshold %d C\n", + crt); tz->trips.critical.temperature = crt_k; } } @@ -390,8 +390,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) status = acpi_evaluate_reference(tz->device->handle, "_PSL", NULL, &devices); if (ACPI_FAILURE(status)) { - printk(KERN_WARNING PREFIX - "Invalid passive threshold\n"); + pr_warn(PREFIX "Invalid passive threshold\n"); tz->trips.passive.flags.valid = 0; } else @@ -453,8 +452,8 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) status = acpi_evaluate_reference(tz->device->handle, name, NULL, &devices); if (ACPI_FAILURE(status)) { - printk(KERN_WARNING PREFIX - "Invalid active%d threshold\n", i); + pr_warn(PREFIX "Invalid active%d threshold\n", + i); tz->trips.active[i].flags.valid = 0; } else @@ -505,7 +504,7 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) valid |= tz->trips.active[i].flags.valid; if (!valid) { - printk(KERN_WARNING FW_BUG "No valid trip found\n"); + pr_warn(FW_BUG "No valid trip found\n"); return -ENODEV; } return 0; @@ -923,8 +922,7 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) acpi_bus_private_data_handler, tz->thermal_zone); if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX - "Error attaching device data\n"); + pr_err(PREFIX "Error attaching device data\n"); return -ENODEV; } @@ -1094,9 +1092,8 @@ static int acpi_thermal_add(struct acpi_device *device) if (result) goto free_memory; - printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n", - acpi_device_name(device), acpi_device_bid(device), - KELVIN_TO_CELSIUS(tz->temperature)); + pr_info(PREFIX "%s [%s] (%ld C)\n", acpi_device_name(device), + acpi_device_bid(device), KELVIN_TO_CELSIUS(tz->temperature)); goto end; free_memory: @@ -1159,24 +1156,24 @@ static int acpi_thermal_resume(struct device *dev) static int thermal_act(const struct dmi_system_id *d) { if (act == 0) { - printk(KERN_NOTICE "ACPI: %s detected: " - "disabling all active thermal trip points\n", d->ident); + pr_notice(PREFIX "%s detected: " + "disabling all active thermal trip points\n", d->ident); act = -1; } return 0; } static int thermal_nocrt(const struct dmi_system_id *d) { - printk(KERN_NOTICE "ACPI: %s detected: " - "disabling all critical thermal trip point actions.\n", d->ident); + pr_notice(PREFIX "%s detected: " + "disabling all critical thermal trip point actions.\n", d->ident); nocrt = 1; return 0; } static int thermal_tzp(const struct dmi_system_id *d) { if (tzp == 0) { - printk(KERN_NOTICE "ACPI: %s detected: " - "enabling thermal zone polling\n", d->ident); + pr_notice(PREFIX "%s detected: " + "enabling thermal zone polling\n", d->ident); tzp = 300; /* 300 dS = 30 Seconds */ } return 0; @@ -1184,8 +1181,8 @@ static int thermal_tzp(const struct dmi_system_id *d) { static int thermal_psv(const struct dmi_system_id *d) { if (psv == 0) { - printk(KERN_NOTICE "ACPI: %s detected: " - "disabling all passive thermal trip points\n", d->ident); + pr_notice(PREFIX "%s detected: " + "disabling all passive thermal trip points\n", d->ident); psv = -1; } return 0; @@ -1238,7 +1235,7 @@ static int __init acpi_thermal_init(void) dmi_check_system(thermal_dmi_table); if (off) { - printk(KERN_NOTICE "ACPI: thermal control disabled\n"); + pr_notice(PREFIX "thermal control disabled\n"); return -ENODEV; } From dd96dc32d59bdf620670a4a527ed9916796f654e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 30 Sep 2013 17:29:43 +0200 Subject: [PATCH 12/18] x86 / ACPI: fix incorrect placement of __initdata tag __initdata tag should not be placed between "struct" and "resource" because it prevents the variable from being placed in the intended .init.data section. Fix it. Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Kyungmin Park Signed-off-by: Rafael J. Wysocki --- arch/x86/kernel/acpi/boot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 40c76604199f..d00db60a5e04 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -745,7 +745,7 @@ static int __init acpi_parse_sbf(struct acpi_table_header *table) #ifdef CONFIG_HPET_TIMER #include -static struct __initdata resource *hpet_res; +static struct resource *hpet_res __initdata; static int __init acpi_parse_hpet(struct acpi_table_header *table) { From e54968ca1eaa78749d7a7fc20227639a31dff629 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 7 Oct 2013 17:12:21 +0300 Subject: [PATCH 13/18] ACPI / platform: Add ACPI IDs for Intel SST audio device This adds ACPI IDs for Intel Smart Sound Technology (SST) device found in Intel Haswell and BayTrail platforms. Signed-off-by: Jarkko Nikula Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_platform.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 1bde12708f9e..ed0f06390245 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -30,6 +30,9 @@ static const struct acpi_device_id acpi_platform_device_ids[] = { { "PNP0D40" }, + /* Intel Smart Sound Technology */ + { "INT33C8" }, + { "80860F28" }, { } }; From 088f1fd267c7f43b5d87850a0fa0c7e851ecae97 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Wed, 9 Oct 2013 09:49:20 +0300 Subject: [PATCH 14/18] ACPI / LPSS: fix UART Auto Flow Control There is an additional bit in the GENERAL register on newer silicon that needs to be set or UART's RTS pin fails to reflect the flow control settings in the Modem Control Register. This will fix an issue where the RTS pin of the UART stays always at 1.8V, regardless of the register settings. Signed-off-by: Heikki Krogerus Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_lpss.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/acpi_lpss.c b/drivers/acpi/acpi_lpss.c index fb78bb9ad8f6..d3961014aad7 100644 --- a/drivers/acpi/acpi_lpss.c +++ b/drivers/acpi/acpi_lpss.c @@ -30,6 +30,7 @@ ACPI_MODULE_NAME("acpi_lpss"); /* Offsets relative to LPSS_PRIVATE_OFFSET */ #define LPSS_GENERAL 0x08 #define LPSS_GENERAL_LTR_MODE_SW BIT(2) +#define LPSS_GENERAL_UART_RTS_OVRD BIT(3) #define LPSS_SW_LTR 0x10 #define LPSS_AUTO_LTR 0x14 #define LPSS_TX_INT 0x20 @@ -68,11 +69,16 @@ struct lpss_private_data { static void lpss_uart_setup(struct lpss_private_data *pdata) { - unsigned int tx_int_offset = pdata->dev_desc->prv_offset + LPSS_TX_INT; + unsigned int offset; u32 reg; - reg = readl(pdata->mmio_base + tx_int_offset); - writel(reg | LPSS_TX_INT_MASK, pdata->mmio_base + tx_int_offset); + offset = pdata->dev_desc->prv_offset + LPSS_TX_INT; + reg = readl(pdata->mmio_base + offset); + writel(reg | LPSS_TX_INT_MASK, pdata->mmio_base + offset); + + offset = pdata->dev_desc->prv_offset + LPSS_GENERAL; + reg = readl(pdata->mmio_base + offset); + writel(reg | LPSS_GENERAL_UART_RTS_OVRD, pdata->mmio_base + offset); } static struct lpss_device_desc lpt_dev_desc = { From e83dda06242073b1c7f9a88f1001e32a4b9fcd1d Mon Sep 17 00:00:00 2001 From: Al Stone Date: Wed, 9 Oct 2013 14:21:10 -0600 Subject: [PATCH 15/18] ACPI: improve acpi_extract_package() utility The current version requires one to know the size of the package a priori; this is almost impossible if the package is composed of strings of variable length. This change allows the utility to allocate a buffer of the proper size if asked. Signed-off-by: Al Stone Signed-off-by: Rafael J. Wysocki --- drivers/acpi/utils.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 552248b0005b..fc2cd3284080 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -169,11 +169,20 @@ acpi_extract_package(union acpi_object *package, /* * Validate output buffer. */ - if (buffer->length < size_required) { + if (buffer->length == ACPI_ALLOCATE_BUFFER) { + buffer->pointer = ACPI_ALLOCATE(size_required); + if (!buffer->pointer) + return AE_NO_MEMORY; buffer->length = size_required; - return AE_BUFFER_OVERFLOW; - } else if (buffer->length != size_required || !buffer->pointer) { - return AE_BAD_PARAMETER; + memset(buffer->pointer, 0, size_required); + } else { + if (buffer->length < size_required) { + buffer->length = size_required; + return AE_BUFFER_OVERFLOW; + } else if (buffer->length != size_required || + !buffer->pointer) { + return AE_BAD_PARAMETER; + } } head = buffer->pointer; From ab0fd674d6cef0904baa511f22613ef6474f8169 Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Sat, 12 Oct 2013 21:04:48 +0800 Subject: [PATCH 16/18] ACPI / AC: Remove AC's proc directory. AC's proc directory is not used and so remove it. Prepare for removing /proc/acpi directory. Signed-off-by: Lan Tianyu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ac.c | 129 ++-------------------------------------------- 1 file changed, 3 insertions(+), 126 deletions(-) diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 324b5a096eff..b9f0d5f4bba5 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -30,10 +30,6 @@ #include #include #include -#ifdef CONFIG_ACPI_PROCFS_POWER -#include -#include -#endif #include #include #include @@ -56,12 +52,6 @@ MODULE_AUTHOR("Paul Diefenbaugh"); MODULE_DESCRIPTION("ACPI AC Adapter Driver"); MODULE_LICENSE("GPL"); -#ifdef CONFIG_ACPI_PROCFS_POWER -extern struct proc_dir_entry *acpi_lock_ac_dir(void); -extern void *acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir); -static int acpi_ac_open_fs(struct inode *inode, struct file *file); -#endif - static int ac_sleep_before_get_state_ms; struct acpi_ac { @@ -73,16 +63,6 @@ struct acpi_ac { #define to_acpi_ac(x) container_of(x, struct acpi_ac, charger) -#ifdef CONFIG_ACPI_PROCFS_POWER -static const struct file_operations acpi_ac_fops = { - .owner = THIS_MODULE, - .open = acpi_ac_open_fs, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; -#endif - /* -------------------------------------------------------------------------- AC Adapter Management -------------------------------------------------------------------------- */ @@ -132,83 +112,6 @@ static enum power_supply_property ac_props[] = { POWER_SUPPLY_PROP_ONLINE, }; -#ifdef CONFIG_ACPI_PROCFS_POWER -/* -------------------------------------------------------------------------- - FS Interface (/proc) - -------------------------------------------------------------------------- */ - -static struct proc_dir_entry *acpi_ac_dir; - -static int acpi_ac_seq_show(struct seq_file *seq, void *offset) -{ - struct acpi_ac *ac = seq->private; - - - if (!ac) - return 0; - - if (acpi_ac_get_state(ac)) { - seq_puts(seq, "ERROR: Unable to read AC Adapter state\n"); - return 0; - } - - seq_puts(seq, "state: "); - switch (ac->state) { - case ACPI_AC_STATUS_OFFLINE: - seq_puts(seq, "off-line\n"); - break; - case ACPI_AC_STATUS_ONLINE: - seq_puts(seq, "on-line\n"); - break; - default: - seq_puts(seq, "unknown\n"); - break; - } - - return 0; -} - -static int acpi_ac_open_fs(struct inode *inode, struct file *file) -{ - return single_open(file, acpi_ac_seq_show, PDE_DATA(inode)); -} - -static int acpi_ac_add_fs(struct acpi_ac *ac) -{ - struct proc_dir_entry *entry = NULL; - - printk(KERN_WARNING PREFIX "Deprecated procfs I/F for AC is loaded," - " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n"); - if (!acpi_device_dir(ac->adev)) { - acpi_device_dir(ac->adev) = - proc_mkdir(acpi_device_bid(ac->adev), acpi_ac_dir); - if (!acpi_device_dir(ac->adev)) - return -ENODEV; - } - - /* 'state' [R] */ - entry = proc_create_data(ACPI_AC_FILE_STATE, - S_IRUGO, acpi_device_dir(ac->adev), - &acpi_ac_fops, ac); - if (!entry) - return -ENODEV; - return 0; -} - -static int acpi_ac_remove_fs(struct acpi_ac *ac) -{ - - if (acpi_device_dir(ac->adev)) { - remove_proc_entry(ACPI_AC_FILE_STATE, - acpi_device_dir(ac->adev)); - remove_proc_entry(acpi_device_bid(ac->adev), acpi_ac_dir); - acpi_device_dir(ac->adev) = NULL; - } - - return 0; -} -#endif - /* -------------------------------------------------------------------------- Driver Model -------------------------------------------------------------------------- */ @@ -293,11 +196,6 @@ static int acpi_ac_probe(struct platform_device *pdev) if (result) goto end; -#ifdef CONFIG_ACPI_PROCFS_POWER - result = acpi_ac_add_fs(ac); - if (result) - goto end; -#endif ac->charger.name = acpi_device_bid(adev); ac->charger.type = POWER_SUPPLY_TYPE_MAINS; ac->charger.properties = ac_props; @@ -317,13 +215,9 @@ static int acpi_ac_probe(struct platform_device *pdev) acpi_device_name(adev), acpi_device_bid(adev), ac->state ? "on-line" : "off-line"); - end: - if (result) { -#ifdef CONFIG_ACPI_PROCFS_POWER - acpi_ac_remove_fs(ac); -#endif +end: + if (result) kfree(ac); - } dmi_check_system(ac_dmi_table); return result; @@ -366,10 +260,6 @@ static int acpi_ac_remove(struct platform_device *pdev) if (ac->charger.dev) power_supply_unregister(&ac->charger); -#ifdef CONFIG_ACPI_PROCFS_POWER - acpi_ac_remove_fs(ac); -#endif - kfree(ac); return 0; @@ -399,19 +289,9 @@ static int __init acpi_ac_init(void) if (acpi_disabled) return -ENODEV; -#ifdef CONFIG_ACPI_PROCFS_POWER - acpi_ac_dir = acpi_lock_ac_dir(); - if (!acpi_ac_dir) - return -ENODEV; -#endif - result = platform_driver_register(&acpi_ac_driver); - if (result < 0) { -#ifdef CONFIG_ACPI_PROCFS_POWER - acpi_unlock_ac_dir(acpi_ac_dir); -#endif + if (result < 0) return -ENODEV; - } return 0; } @@ -419,9 +299,6 @@ static int __init acpi_ac_init(void) static void __exit acpi_ac_exit(void) { platform_driver_unregister(&acpi_ac_driver); -#ifdef CONFIG_ACPI_PROCFS_POWER - acpi_unlock_ac_dir(acpi_ac_dir); -#endif } module_init(acpi_ac_init); module_exit(acpi_ac_exit); From 9208e3110bf0a6ba4ded56e374857d4b6609c911 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Wed, 16 Oct 2013 13:15:14 +0300 Subject: [PATCH 17/18] ACPI / platform: add ACPI ID for a Broadcom GPS chip This adds ACPI ID for Broadcom GPS receiver BCM4752. Signed-off-by: Heikki Krogerus Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_platform.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index aef79db906fe..8a4cfc7e71f0 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -31,6 +31,7 @@ static const struct acpi_device_id acpi_platform_device_ids[] = { { "PNP0D40" }, { "ACPI0003" }, { "VPC2004" }, + { "BCM4752" }, /* Intel Smart Sound Technology */ { "INT33C8" }, From 5e2be4e0edff4a1021b6743ca6859129cd8e7067 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 18 Oct 2013 12:01:43 +0300 Subject: [PATCH 18/18] ACPI / osl: remove an unneeded NULL check "str" is never NULL here so I have removed the check. There are static checkers which complain about superfluous NULL checks because it may indicate confusion or a bug. Signed-off-by: Dan Carpenter Signed-off-by: Rafael J. Wysocki --- drivers/acpi/osl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index b1629b571cb2..4923dd4232b3 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -1335,7 +1335,7 @@ static int __init acpi_os_name_setup(char *str) if (!str || !*str) return 0; - for (; count-- && str && *str; str++) { + for (; count-- && *str; str++) { if (isalnum(*str) || *str == ' ' || *str == ':') *p++ = *str; else if (*str == '\'' || *str == '"')