From patchwork Mon Jan 10 01:38:12 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shaohua Li X-Patchwork-Id: 467371 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p0A1cxWH026072 for ; Mon, 10 Jan 2011 01:39:00 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752868Ab1AJBiz (ORCPT ); Sun, 9 Jan 2011 20:38:55 -0500 Received: from mga11.intel.com ([192.55.52.93]:15567 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752772Ab1AJBiz (ORCPT ); Sun, 9 Jan 2011 20:38:55 -0500 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga102.fm.intel.com with ESMTP; 09 Jan 2011 17:38:54 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.60,297,1291622400"; d="scan'208";a="875902334" Received: from unknown (HELO [10.239.36.124]) ([10.239.36.124]) by fmsmga001.fm.intel.com with ESMTP; 09 Jan 2011 17:38:54 -0800 Subject: [PATCH]intel_idle: open broadcast clock event - resend From: Shaohua Li To: linux acpi Cc: Len Brown , Andrew Morton Date: Mon, 10 Jan 2011 09:38:12 +0800 Message-ID: <1294623493.1949.589.camel@sli10-conroe> Mime-Version: 1.0 X-Mailer: Evolution 2.30.3 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Mon, 10 Jan 2011 01:39:00 +0000 (UTC) Index: linux/drivers/idle/intel_idle.c =================================================================== --- linux.orig/drivers/idle/intel_idle.c 2011-01-10 09:27:07.000000000 +0800 +++ linux/drivers/idle/intel_idle.c 2011-01-10 09:29:59.000000000 +0800 @@ -59,6 +59,8 @@ #include /* ktime_get_real() */ #include #include +#include +#include #include #define INTEL_IDLE_VERSION "0.4" @@ -73,6 +75,7 @@ static int max_cstate = MWAIT_MAX_NUM_CS static unsigned int mwait_substates; +#define LAPIC_TIMER_ALWAYS_RELIABLE 0xFFFFFFFF /* Reliable LAPIC Timer States, bit 1 for C1 etc. */ static unsigned int lapic_timer_reliable_states = (1 << 1); /* Default to only C1 */ @@ -243,6 +246,39 @@ static int intel_idle(struct cpuidle_dev return usec_delta; } +static void __setup_broadcast_timer(void *arg) +{ + unsigned long reason = (unsigned long)arg; + int cpu = smp_processor_id(); + + reason = reason ? + CLOCK_EVT_NOTIFY_BROADCAST_ON : CLOCK_EVT_NOTIFY_BROADCAST_OFF; + + clockevents_notify(reason, &cpu); +} + +static int __cpuinit setup_broadcast_cpuhp_notify(struct notifier_block *n, + unsigned long action, void *hcpu) +{ + int hotcpu = (unsigned long)hcpu; + + switch (action & 0xf) { + case CPU_ONLINE: + smp_call_function_single(hotcpu, __setup_broadcast_timer, + (void *)true, 1); + break; + case CPU_DOWN_PREPARE: + smp_call_function_single(hotcpu, __setup_broadcast_timer, + (void *)false, 1); + break; + } + return NOTIFY_OK; +} + +static struct notifier_block __cpuinitdata setup_broadcast_notifier = { + .notifier_call = setup_broadcast_cpuhp_notify, +}; + /* * intel_idle_probe() */ @@ -305,7 +341,11 @@ static int intel_idle_probe(void) } if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */ - lapic_timer_reliable_states = 0xFFFFFFFF; + lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE; + else { + smp_call_function(__setup_broadcast_timer, (void *)true, 1); + register_cpu_notifier(&setup_broadcast_notifier); + } pr_debug(PREFIX "v" INTEL_IDLE_VERSION " model 0x%X\n", boot_cpu_data.x86_model); @@ -428,6 +468,11 @@ static void __exit intel_idle_exit(void) intel_idle_cpuidle_devices_uninit(); cpuidle_unregister_driver(&intel_idle_driver); + if (lapic_timer_reliable_states != LAPIC_TIMER_ALWAYS_RELIABLE) { + smp_call_function(__setup_broadcast_timer, (void *)false, 1); + unregister_cpu_notifier(&setup_broadcast_notifier); + } + return; }