From bea57077e44ec9c1e6d3a3c142c8a3c0289e290d Mon Sep 17 00:00:00 2001 From: Len Brown Date: Tue, 10 Feb 2015 15:42:03 -0500 Subject: intel_idle: support additional Broadwell model Signed-off-by: Len Brown --- drivers/idle/intel_idle.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 9cceacb92f9..1bc0c170f12 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -727,6 +727,7 @@ static const struct x86_cpu_id intel_idle_ids[] = { ICPU(0x46, idle_cpu_hsw), ICPU(0x4d, idle_cpu_avn), ICPU(0x3d, idle_cpu_bdw), + ICPU(0x47, idle_cpu_bdw), ICPU(0x4f, idle_cpu_bdw), ICPU(0x56, idle_cpu_bdw), {} -- cgit v1.2.3-70-g09d2 From e06bf91b59d3d95359e046ffcdc577145933da10 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 11 Feb 2015 17:33:23 +0100 Subject: Revert "ACPI / EC: Add GPE reference counting debugging messages" Revert commit b5bca896ef3c (ACPI / EC: Add GPE reference counting debugging messages), because it depends on commit f252cb09e1cb (ACPI / EC: Add query flushing support) which breaks system suspend on Acer Aspire S5 and needs to be reverted. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 14d0c89ada2..40002ae7db2 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -31,7 +31,6 @@ /* Uncomment next line to get verbose printout */ /* #define DEBUG */ -#define DEBUG_REF 0 #define pr_fmt(fmt) "ACPI : EC: " fmt #include @@ -91,13 +90,6 @@ enum { #define ACPI_EC_COMMAND_POLL 0x01 /* Available for command byte */ #define ACPI_EC_COMMAND_COMPLETE 0x02 /* Completed last byte */ -#define ec_debug_ref(ec, fmt, ...) \ - do { \ - if (DEBUG_REF) \ - pr_debug("%lu: " fmt, ec->reference_count, \ - ## __VA_ARGS__); \ - } while (0) - /* ec.c is compiled in acpi namespace so this shows up as acpi.ec_delay param */ static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY; module_param(ec_delay, uint, 0644); @@ -364,14 +356,12 @@ static void acpi_ec_submit_event(struct acpi_ec *ec) /* Hold reference for pending event */ if (!acpi_ec_submit_flushable_request(ec, true)) return; - ec_debug_ref(ec, "Increase event\n"); if (!test_and_set_bit(EC_FLAGS_EVENT_PENDING, &ec->flags)) { pr_debug("***** Event query started *****\n"); schedule_work(&ec->work); return; } acpi_ec_complete_request(ec); - ec_debug_ref(ec, "Decrease event\n"); } static void acpi_ec_complete_event(struct acpi_ec *ec) @@ -381,7 +371,6 @@ static void acpi_ec_complete_event(struct acpi_ec *ec) pr_debug("***** Event query stopped *****\n"); /* Unhold reference for pending event */ acpi_ec_complete_request(ec); - ec_debug_ref(ec, "Decrease event\n"); /* Check if there is another SCI_EVT detected */ acpi_ec_submit_event(ec); } @@ -392,14 +381,12 @@ static void acpi_ec_submit_detection(struct acpi_ec *ec) /* Hold reference for query submission */ if (!acpi_ec_submit_flushable_request(ec, false)) return; - ec_debug_ref(ec, "Increase query\n"); if (!test_and_set_bit(EC_FLAGS_EVENT_DETECTED, &ec->flags)) { pr_debug("***** Event detection blocked *****\n"); acpi_ec_submit_event(ec); return; } acpi_ec_complete_request(ec); - ec_debug_ref(ec, "Decrease query\n"); } static void acpi_ec_complete_detection(struct acpi_ec *ec) @@ -409,7 +396,6 @@ static void acpi_ec_complete_detection(struct acpi_ec *ec) pr_debug("***** Event detetion unblocked *****\n"); /* Unhold reference for query submission */ acpi_ec_complete_request(ec); - ec_debug_ref(ec, "Decrease query\n"); } } @@ -584,7 +570,6 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, ret = -EINVAL; goto unlock; } - ec_debug_ref(ec, "Increase command\n"); /* following two actions should be kept atomic */ ec->curr = t; pr_debug("***** Command(%s) started *****\n", @@ -600,7 +585,6 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, ec->curr = NULL; /* Disable GPE for command processing (IBF=0/OBF=1) */ acpi_ec_complete_request(ec); - ec_debug_ref(ec, "Decrease command\n"); unlock: spin_unlock_irqrestore(&ec->lock, tmp); return ret; @@ -762,10 +746,8 @@ static void acpi_ec_start(struct acpi_ec *ec, bool resuming) if (!test_and_set_bit(EC_FLAGS_STARTED, &ec->flags)) { pr_debug("+++++ Starting EC +++++\n"); /* Enable GPE for event processing (SCI_EVT=1) */ - if (!resuming) { + if (!resuming) acpi_ec_submit_request(ec); - ec_debug_ref(ec, "Increase driver\n"); - } pr_info("+++++ EC started +++++\n"); } spin_unlock_irqrestore(&ec->lock, flags); @@ -794,10 +776,8 @@ static void acpi_ec_stop(struct acpi_ec *ec, bool suspending) wait_event(ec->wait, acpi_ec_stopped(ec)); spin_lock_irqsave(&ec->lock, flags); /* Disable GPE for event processing (SCI_EVT=1) */ - if (!suspending) { + if (!suspending) acpi_ec_complete_request(ec); - ec_debug_ref(ec, "Decrease driver\n"); - } clear_bit(EC_FLAGS_STARTED, &ec->flags); clear_bit(EC_FLAGS_STOPPED, &ec->flags); pr_info("+++++ EC stopped +++++\n"); -- cgit v1.2.3-70-g09d2 From 37d11391c2de8a846da50a2972a82289e65e5ea6 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 11 Feb 2015 17:35:05 +0100 Subject: Revert "ACPI / EC: Add query flushing support" Revert commit f252cb09e1cb (ACPI / EC: Add query flushing support), because it breaks system suspend on Acer Aspire S5. The machine just hangs solid at the last stage of suspend (after taking non-boot CPUs offline). Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 101 +++++++++--------------------------------------------- 1 file changed, 16 insertions(+), 85 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 40002ae7db2..982b67faaaf 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -76,9 +76,7 @@ enum ec_command { * when trying to clear the EC */ enum { - EC_FLAGS_EVENT_ENABLED, /* Event is enabled */ - EC_FLAGS_EVENT_PENDING, /* Event is pending */ - EC_FLAGS_EVENT_DETECTED, /* Event is detected */ + EC_FLAGS_QUERY_PENDING, /* Query is pending */ EC_FLAGS_HANDLERS_INSTALLED, /* Handlers for GPE and * OpReg are installed */ EC_FLAGS_STARTED, /* Driver is started */ @@ -153,12 +151,6 @@ static bool acpi_ec_flushed(struct acpi_ec *ec) return ec->reference_count == 1; } -static bool acpi_ec_has_pending_event(struct acpi_ec *ec) -{ - return test_bit(EC_FLAGS_EVENT_DETECTED, &ec->flags) || - test_bit(EC_FLAGS_EVENT_PENDING, &ec->flags); -} - /* -------------------------------------------------------------------------- * EC Registers * -------------------------------------------------------------------------- */ @@ -326,93 +318,36 @@ static void acpi_ec_clear_storm(struct acpi_ec *ec, u8 flag) * the flush operation is not in * progress * @ec: the EC device - * @allow_event: whether event should be handled * * This function must be used before taking a new action that should hold * the reference count. If this function returns false, then the action * must be discarded or it will prevent the flush operation from being * completed. - * - * During flushing, QR_EC command need to pass this check when there is a - * pending event, so that the reference count held for the pending event - * can be decreased by the completion of the QR_EC command. */ -static bool acpi_ec_submit_flushable_request(struct acpi_ec *ec, - bool allow_event) +static bool acpi_ec_submit_flushable_request(struct acpi_ec *ec) { - if (!acpi_ec_started(ec)) { - if (!allow_event || !acpi_ec_has_pending_event(ec)) - return false; - } + if (!acpi_ec_started(ec)) + return false; acpi_ec_submit_request(ec); return true; } -static void acpi_ec_submit_event(struct acpi_ec *ec) +static void acpi_ec_submit_query(struct acpi_ec *ec) { - if (!test_bit(EC_FLAGS_EVENT_DETECTED, &ec->flags) || - !test_bit(EC_FLAGS_EVENT_ENABLED, &ec->flags)) - return; - /* Hold reference for pending event */ - if (!acpi_ec_submit_flushable_request(ec, true)) - return; - if (!test_and_set_bit(EC_FLAGS_EVENT_PENDING, &ec->flags)) { - pr_debug("***** Event query started *****\n"); + if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) { + pr_debug("***** Event started *****\n"); schedule_work(&ec->work); - return; - } - acpi_ec_complete_request(ec); -} - -static void acpi_ec_complete_event(struct acpi_ec *ec) -{ - if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { - clear_bit(EC_FLAGS_EVENT_PENDING, &ec->flags); - pr_debug("***** Event query stopped *****\n"); - /* Unhold reference for pending event */ - acpi_ec_complete_request(ec); - /* Check if there is another SCI_EVT detected */ - acpi_ec_submit_event(ec); - } -} - -static void acpi_ec_submit_detection(struct acpi_ec *ec) -{ - /* Hold reference for query submission */ - if (!acpi_ec_submit_flushable_request(ec, false)) - return; - if (!test_and_set_bit(EC_FLAGS_EVENT_DETECTED, &ec->flags)) { - pr_debug("***** Event detection blocked *****\n"); - acpi_ec_submit_event(ec); - return; } - acpi_ec_complete_request(ec); } -static void acpi_ec_complete_detection(struct acpi_ec *ec) +static void acpi_ec_complete_query(struct acpi_ec *ec) { if (ec->curr->command == ACPI_EC_COMMAND_QUERY) { - clear_bit(EC_FLAGS_EVENT_DETECTED, &ec->flags); - pr_debug("***** Event detetion unblocked *****\n"); - /* Unhold reference for query submission */ - acpi_ec_complete_request(ec); + clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); + pr_debug("***** Event stopped *****\n"); } } -static void acpi_ec_enable_event(struct acpi_ec *ec) -{ - unsigned long flags; - - spin_lock_irqsave(&ec->lock, flags); - set_bit(EC_FLAGS_EVENT_ENABLED, &ec->flags); - /* - * An event may be pending even with SCI_EVT=0, so QR_EC should - * always be issued right after started. - */ - acpi_ec_submit_detection(ec); - spin_unlock_irqrestore(&ec->lock, flags); -} - static int ec_transaction_completed(struct acpi_ec *ec) { unsigned long flags; @@ -454,7 +389,6 @@ static void advance_transaction(struct acpi_ec *ec) t->rdata[t->ri++] = acpi_ec_read_data(ec); if (t->rlen == t->ri) { t->flags |= ACPI_EC_COMMAND_COMPLETE; - acpi_ec_complete_event(ec); if (t->command == ACPI_EC_COMMAND_QUERY) pr_debug("***** Command(%s) hardware completion *****\n", acpi_ec_cmd_string(t->command)); @@ -465,7 +399,6 @@ static void advance_transaction(struct acpi_ec *ec) } else if (t->wlen == t->wi && (status & ACPI_EC_FLAG_IBF) == 0) { t->flags |= ACPI_EC_COMMAND_COMPLETE; - acpi_ec_complete_event(ec); wakeup = true; } goto out; @@ -474,17 +407,16 @@ static void advance_transaction(struct acpi_ec *ec) !(status & ACPI_EC_FLAG_SCI) && (t->command == ACPI_EC_COMMAND_QUERY)) { t->flags |= ACPI_EC_COMMAND_POLL; - acpi_ec_complete_detection(ec); + acpi_ec_complete_query(ec); t->rdata[t->ri++] = 0x00; t->flags |= ACPI_EC_COMMAND_COMPLETE; - acpi_ec_complete_event(ec); pr_debug("***** Command(%s) software completion *****\n", acpi_ec_cmd_string(t->command)); wakeup = true; } else if ((status & ACPI_EC_FLAG_IBF) == 0) { acpi_ec_write_cmd(ec, t->command); t->flags |= ACPI_EC_COMMAND_POLL; - acpi_ec_complete_detection(ec); + acpi_ec_complete_query(ec); } else goto err; goto out; @@ -505,7 +437,7 @@ err: } out: if (status & ACPI_EC_FLAG_SCI) - acpi_ec_submit_detection(ec); + acpi_ec_submit_query(ec); if (wakeup && in_interrupt()) wake_up(&ec->wait); } @@ -566,7 +498,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, /* start transaction */ spin_lock_irqsave(&ec->lock, tmp); /* Enable GPE for command processing (IBF=0/OBF=1) */ - if (!acpi_ec_submit_flushable_request(ec, true)) { + if (!acpi_ec_submit_flushable_request(ec)) { ret = -EINVAL; goto unlock; } @@ -947,9 +879,7 @@ static void acpi_ec_gpe_poller(struct work_struct *work) { struct acpi_ec *ec = container_of(work, struct acpi_ec, work); - pr_debug("***** Event poller started *****\n"); acpi_ec_query(ec, NULL); - pr_debug("***** Event poller stopped *****\n"); } static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, @@ -1019,6 +949,7 @@ static struct acpi_ec *make_acpi_ec(void) if (!ec) return NULL; + ec->flags = 1 << EC_FLAGS_QUERY_PENDING; mutex_init(&ec->mutex); init_waitqueue_head(&ec->wait); INIT_LIST_HEAD(&ec->list); @@ -1169,7 +1100,7 @@ static int acpi_ec_add(struct acpi_device *device) ret = ec_install_handlers(ec); /* EC is fully operational, allow queries */ - acpi_ec_enable_event(ec); + clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); /* Clear stale _Q events if hardware might require that */ if (EC_FLAGS_CLEAR_ON_RESUME) -- cgit v1.2.3-70-g09d2 From 59d84ca8c46a93ad62f9129458e897e7fe5075de Mon Sep 17 00:00:00 2001 From: Quentin Lambert Date: Mon, 9 Feb 2015 10:45:32 +0100 Subject: PM / OPP / clk: Remove unnecessary OOM message This patch reduces the kernel size by removing error messages that duplicate the normal OOM message. A simplified version of the semantic patch that finds this problem is as follows: (http://coccinelle.lip6.fr) @@ identifier f,print,l; expression e; constant char[] c; @@ e = \(kzalloc\|kmalloc\|devm_kzalloc\|devm_kmalloc\)(...); if (e == NULL) { <+... - print(...,c,...); ... when any ( goto l; | return ...; ) ...+> } Signed-off-by: Quentin Lambert Acked-by: Nishanth Menon Signed-off-by: Rafael J. Wysocki --- drivers/base/firmware_class.c | 1 - drivers/base/power/clock_ops.c | 4 +--- drivers/base/power/opp.c | 8 ++------ 3 files changed, 3 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 58470c39530..c3293f0a857 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -855,7 +855,6 @@ fw_create_instance(struct firmware *firmware, const char *fw_name, fw_priv = kzalloc(sizeof(*fw_priv), GFP_KERNEL); if (!fw_priv) { - dev_err(device, "%s: kmalloc failed\n", __func__); fw_priv = ERR_PTR(-ENOMEM); goto exit; } diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index d626576a4f7..7fdd0172605 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c @@ -81,10 +81,8 @@ static int __pm_clk_add(struct device *dev, const char *con_id, return -EINVAL; ce = kzalloc(sizeof(*ce), GFP_KERNEL); - if (!ce) { - dev_err(dev, "Not enough memory for clock entry.\n"); + if (!ce) return -ENOMEM; - } if (con_id) { ce->con_id = kstrdup(con_id, GFP_KERNEL); diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c index 15bf29974c3..677fb284355 100644 --- a/drivers/base/power/opp.c +++ b/drivers/base/power/opp.c @@ -474,10 +474,8 @@ static int _opp_add_dynamic(struct device *dev, unsigned long freq, /* allocate new OPP node */ new_opp = kzalloc(sizeof(*new_opp), GFP_KERNEL); - if (!new_opp) { - dev_warn(dev, "%s: Unable to create new OPP node\n", __func__); + if (!new_opp) return -ENOMEM; - } /* Hold our list modification lock here */ mutex_lock(&dev_opp_list_lock); @@ -695,10 +693,8 @@ static int _opp_set_availability(struct device *dev, unsigned long freq, /* keep the node allocated */ new_opp = kmalloc(sizeof(*new_opp), GFP_KERNEL); - if (!new_opp) { - dev_warn(dev, "%s: Unable to create OPP\n", __func__); + if (!new_opp) return -ENOMEM; - } mutex_lock(&dev_opp_list_lock); -- cgit v1.2.3-70-g09d2 From d4d4eda23794c701442e55129dd4f8f2fefd5e4d Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Mon, 9 Feb 2015 13:38:17 -0500 Subject: cpufreq: speedstep-smi: enable interrupts when waiting On Dell Latitude C600 laptop with Pentium 3 850MHz processor, the speedstep-smi driver sometimes loads and sometimes doesn't load with "change to state X failed" message. The hardware sometimes refuses to change frequency and in this case, we need to retry later. I found out that we need to enable interrupts while waiting. When we enable interrupts, the hardware blockage that prevents frequency transition resolves and the transition is possible. With disabled interrupts, the blockage doesn't resolve (no matter how long do we wait). The exact reasons for this hardware behavior are unknown. This patch enables interrupts in the function speedstep_set_state that can be called with disabled interrupts. However, this function is called with disabled interrupts only from speedstep_get_freqs, so it shouldn't cause any problem. Signed-off-by: Mikulas Patocka Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/speedstep-lib.c | 3 +++ drivers/cpufreq/speedstep-smi.c | 12 ++++++++++++ 2 files changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/cpufreq/speedstep-lib.c b/drivers/cpufreq/speedstep-lib.c index 7047821a7f8..4ab7a215667 100644 --- a/drivers/cpufreq/speedstep-lib.c +++ b/drivers/cpufreq/speedstep-lib.c @@ -400,6 +400,7 @@ unsigned int speedstep_get_freqs(enum speedstep_processor processor, pr_debug("previous speed is %u\n", prev_speed); + preempt_disable(); local_irq_save(flags); /* switch to low state */ @@ -464,6 +465,8 @@ unsigned int speedstep_get_freqs(enum speedstep_processor processor, out: local_irq_restore(flags); + preempt_enable(); + return ret; } EXPORT_SYMBOL_GPL(speedstep_get_freqs); diff --git a/drivers/cpufreq/speedstep-smi.c b/drivers/cpufreq/speedstep-smi.c index 5fc96d5d656..819229e824f 100644 --- a/drivers/cpufreq/speedstep-smi.c +++ b/drivers/cpufreq/speedstep-smi.c @@ -156,6 +156,7 @@ static void speedstep_set_state(unsigned int state) return; /* Disable IRQs */ + preempt_disable(); local_irq_save(flags); command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff); @@ -166,9 +167,19 @@ static void speedstep_set_state(unsigned int state) do { if (retry) { + /* + * We need to enable interrupts, otherwise the blockage + * won't resolve. + * + * We disable preemption so that other processes don't + * run. If other processes were running, they could + * submit more DMA requests, making the blockage worse. + */ pr_debug("retry %u, previous result %u, waiting...\n", retry, result); + local_irq_enable(); mdelay(retry * 50); + local_irq_disable(); } retry++; __asm__ __volatile__( @@ -185,6 +196,7 @@ static void speedstep_set_state(unsigned int state) /* enable IRQs */ local_irq_restore(flags); + preempt_enable(); if (new_state == state) pr_debug("change to %u MHz succeeded after %u tries " -- cgit v1.2.3-70-g09d2 From 04a695edcaee386207e5a43a41bafa8388bf3bf4 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 10 Feb 2015 13:35:47 +0300 Subject: PM / devfreq: event: testing the wrong variable There is a typo here so we test "edev" but we intended to test "edev[i]". Fixes: f262f28c1470 ('PM / devfreq: event: Add devfreq_event class') Signed-off-by: Dan Carpenter Reviewed-by: Chanwoo Choi Signed-off-by: Rafael J. Wysocki --- drivers/devfreq/event/exynos-ppmu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/devfreq/event/exynos-ppmu.c b/drivers/devfreq/event/exynos-ppmu.c index 135be0aada9..ad8347385f5 100644 --- a/drivers/devfreq/event/exynos-ppmu.c +++ b/drivers/devfreq/event/exynos-ppmu.c @@ -327,8 +327,8 @@ static int exynos_ppmu_probe(struct platform_device *pdev) for (i = 0; i < info->num_events; i++) { edev[i] = devm_devfreq_event_add_edev(&pdev->dev, &desc[i]); - if (IS_ERR(edev)) { - ret = PTR_ERR(edev); + if (IS_ERR(edev[i])) { + ret = PTR_ERR(edev[i]); dev_err(&pdev->dev, "failed to add devfreq-event device\n"); goto err; -- cgit v1.2.3-70-g09d2