Blame view

drivers/acpi/processor_idle.c 34.3 KB
c942fddf8   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
  /*
   * processor_idle - idle state submodule to the ACPI processor driver
   *
   *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
   *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
c5ab81ca0   Dominik Brodowski   ACPI: C-States: b...
7
   *  Copyright (C) 2004, 2005 Dominik Brodowski <linux@brodo.de>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
9
   *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
   *  			- Added processor hotplug support
02df8b938   Venkatesh Pallipadi   [ACPI] enable C2 ...
10
11
   *  Copyright (C) 2005  Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
   *  			- Added support for C3 on SMP
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
   */
b6ec26fb9   Sudeep Holla   ACPI / processor_...
13
  #define pr_fmt(fmt) "ACPI: " fmt
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
  #include <linux/module.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
17
  #include <linux/acpi.h>
  #include <linux/dmi.h>
e2668fb53   Daniel Lezcano   ACPI / idle : rem...
18
  #include <linux/sched.h>       /* need_resched() */
ee41eebf9   Thomas Gleixner   ACPI/processor: U...
19
  #include <linux/tick.h>
4f86d3a8e   Len Brown   cpuidle: consolid...
20
  #include <linux/cpuidle.h>
6727ad9e2   Chris Metcalf   nmi_backtrace: ge...
21
  #include <linux/cpu.h>
8b48463f8   Lv Zheng   ACPI: Clean up in...
22
  #include <acpi/processor.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23

3434933b1   Thomas Gleixner   [PATCH] ACPI: fix...
24
25
26
27
28
29
30
31
32
  /*
   * Include the apic definitions for x86 to have the APIC timer related defines
   * available also for UP (on SMP it gets magically included via linux/smp.h).
   * asm/acpi.h is not an option, as it would require more include magic. Also
   * creating an empty asm-ia64/apic.h would just trade pest vs. cholera.
   */
  #ifdef CONFIG_X86
  #include <asm/apic.h>
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
  #define ACPI_PROCESSOR_CLASS            "processor"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
  #define _COMPONENT              ACPI_PROCESSOR_COMPONENT
f52fd66d2   Len Brown   ACPI: clean up AC...
35
  ACPI_MODULE_NAME("processor_idle");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36

dc2251bf9   Rafael J. Wysocki   cpuidle: Eliminat...
37
  #define ACPI_IDLE_STATE_START	(IS_ENABLED(CONFIG_ARCH_HAS_CPU_RELAX) ? 1 : 0)
4f86d3a8e   Len Brown   cpuidle: consolid...
38
39
  static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER;
  module_param(max_cstate, uint, 0000);
b6835052a   Andreas Mohr   ACPI: apply "__re...
40
  static unsigned int nocst __read_mostly;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
  module_param(nocst, uint, 0000);
d3e7e99f2   Len Brown   ACPI: create "pro...
42
43
  static int bm_check_disable __read_mostly;
  module_param(bm_check_disable, uint, 0000);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44

25de57183   Len Brown   cpuidle: default ...
45
  static unsigned int latency_factor __read_mostly = 2;
4963f6204   Len Brown   cpuidle: create p...
46
  module_param(latency_factor, uint, 0644);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
47

3d339dcbb   Daniel Lezcano   cpuidle / ACPI : ...
48
  static DEFINE_PER_CPU(struct cpuidle_device *, acpi_cpuidle_device);
35ae71335   Sudeep Holla   ACPI / processor_...
49
50
51
52
53
54
  struct cpuidle_driver acpi_idle_driver = {
  	.name =		"acpi_idle",
  	.owner =	THIS_MODULE,
  };
  
  #ifdef CONFIG_ACPI_PROCESSOR_CSTATE
25528213f   Peter Zijlstra   tags: Fix DEFINE_...
55
56
  static
  DEFINE_PER_CPU(struct acpi_processor_cx * [CPUIDLE_STATE_MAX], acpi_cstate);
ac3ebafa8   Daniel Lezcano   ACPI / idle: remo...
57

d18960494   Thomas Renninger   ACPI, intel_idle:...
58
59
60
  static int disabled_by_idle_boot_param(void)
  {
  	return boot_option_idle_override == IDLE_POLL ||
d18960494   Thomas Renninger   ACPI, intel_idle:...
61
62
  		boot_option_idle_override == IDLE_HALT;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63
64
65
66
67
68
  /*
   * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
   * For now disable this. Probably a bug somewhere else.
   *
   * To skip this limit, boot/load with a large max_cstate limit.
   */
1855256c4   Jeff Garzik   drivers/firmware:...
69
  static int set_max_cstate(const struct dmi_system_id *id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
70
71
72
  {
  	if (max_cstate > ACPI_PROCESSOR_MAX_POWER)
  		return 0;
b6ec26fb9   Sudeep Holla   ACPI / processor_...
73
74
75
76
  	pr_notice("%s detected - limiting to C%ld max_cstate."
  		  " Override with \"processor.max_cstate=%d\"
  ", id->ident,
  		  (long)id->driver_data, ACPI_PROCESSOR_MAX_POWER + 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77

3d35600a9   Len Brown   [ACPI] fix 64-bit...
78
  	max_cstate = (long)id->driver_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79
80
81
  
  	return 0;
  }
b03466883   Mathias Krause   ACPI / processor:...
82
  static const struct dmi_system_id processor_power_dmi_table[] = {
876c184b3   Thomas Rosner   [ACPI] Disable C2...
83
84
85
  	{ set_max_cstate, "Clevo 5600D", {
  	  DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
  	  DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
4be44fcd3   Len Brown   [ACPI] Lindent al...
86
  	 (void *)2},
370d5cd88   Arjan van de Ven   ACPI: fix High cp...
87
88
89
90
91
92
93
94
  	{ set_max_cstate, "Pavilion zv5000", {
  	  DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
  	  DMI_MATCH(DMI_PRODUCT_NAME,"Pavilion zv5000 (DS502A#ABA)")},
  	 (void *)1},
  	{ set_max_cstate, "Asus L8400B", {
  	  DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
  	  DMI_MATCH(DMI_PRODUCT_NAME,"L8400B series Notebook PC")},
  	 (void *)1},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
95
96
  	{},
  };
4f86d3a8e   Len Brown   cpuidle: consolid...
97

2e906655b   venkatesh.pallipadi@intel.com   ACPI: idle: Fix a...
98
99
100
101
  /*
   * Callers should disable interrupts before the call and enable
   * interrupts after return.
   */
6727ad9e2   Chris Metcalf   nmi_backtrace: ge...
102
  static void __cpuidle acpi_safe_halt(void)
ddc081a19   Venkatesh Pallipadi   cpuidle: fix HP n...
103
  {
ea8117478   Peter Zijlstra   sched, idle: Fix ...
104
  	if (!tif_need_resched()) {
ddc081a19   Venkatesh Pallipadi   cpuidle: fix HP n...
105
  		safe_halt();
71e93d156   Venki Pallipadi   ACPI: lockdep war...
106
107
  		local_irq_disable();
  	}
ddc081a19   Venkatesh Pallipadi   cpuidle: fix HP n...
108
  }
169a0abbe   Thomas Gleixner   [PATCH] ACPI keep...
109
110
111
112
  #ifdef ARCH_APICTIMER_STOPS_ON_C3
  
  /*
   * Some BIOS implementations switch to C3 in the published C2 state.
296d93cd0   Linus Torvalds   Revert "ACPI: Onl...
113
114
115
   * This seems to be a common problem on AMD boxen, but other vendors
   * are affected too. We pick the most conservative approach: we assume
   * that the local APIC stops in both C2 and C3.
169a0abbe   Thomas Gleixner   [PATCH] ACPI keep...
116
   */
7e275cc4e   Len Brown   ACPI: idle: renam...
117
  static void lapic_timer_check_state(int state, struct acpi_processor *pr,
169a0abbe   Thomas Gleixner   [PATCH] ACPI keep...
118
119
120
  				   struct acpi_processor_cx *cx)
  {
  	struct acpi_processor_power *pwr = &pr->power;
e585bef81   Thomas Gleixner   [PATCH] i386: add...
121
  	u8 type = local_apic_timer_c2_ok ? ACPI_STATE_C3 : ACPI_STATE_C2;
169a0abbe   Thomas Gleixner   [PATCH] ACPI keep...
122

db954b589   Venkatesh Pallipadi   x86 ACPI: Add sup...
123
124
  	if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT))
  		return;
07c94a381   Borislav Petkov   x86/amd: Simplify...
125
  	if (boot_cpu_has_bug(X86_BUG_AMD_APIC_C1E))
87ad57bac   Shaohua Li   cpuidle: makes AM...
126
  		type = ACPI_STATE_C1;
169a0abbe   Thomas Gleixner   [PATCH] ACPI keep...
127
128
129
130
131
132
  	/*
  	 * Check, if one of the previous states already marked the lapic
  	 * unstable
  	 */
  	if (pwr->timer_broadcast_on_state < state)
  		return;
e585bef81   Thomas Gleixner   [PATCH] i386: add...
133
  	if (cx->type >= type)
296d93cd0   Linus Torvalds   Revert "ACPI: Onl...
134
  		pr->power.timer_broadcast_on_state = state;
169a0abbe   Thomas Gleixner   [PATCH] ACPI keep...
135
  }
918aae42a   Hidetoshi Seto   ACPI: fix for lap...
136
  static void __lapic_timer_propagate_broadcast(void *arg)
169a0abbe   Thomas Gleixner   [PATCH] ACPI keep...
137
  {
f833bab87   Suresh Siddha   clockevent: Preve...
138
  	struct acpi_processor *pr = (struct acpi_processor *) arg;
e9e2cdb41   Thomas Gleixner   [PATCH] clockeven...
139

ee41eebf9   Thomas Gleixner   ACPI/processor: U...
140
141
142
143
  	if (pr->power.timer_broadcast_on_state < INT_MAX)
  		tick_broadcast_enable();
  	else
  		tick_broadcast_disable();
e9e2cdb41   Thomas Gleixner   [PATCH] clockeven...
144
  }
918aae42a   Hidetoshi Seto   ACPI: fix for lap...
145
146
147
148
149
  static void lapic_timer_propagate_broadcast(struct acpi_processor *pr)
  {
  	smp_call_function_single(pr->id, __lapic_timer_propagate_broadcast,
  				 (void *)pr, 1);
  }
e9e2cdb41   Thomas Gleixner   [PATCH] clockeven...
150
  /* Power(C) State timer broadcast control */
aa6b43d57   Peter Zijlstra   ACPI: processor: ...
151
152
  static bool lapic_timer_needs_broadcast(struct acpi_processor *pr,
  					struct acpi_processor_cx *cx)
e9e2cdb41   Thomas Gleixner   [PATCH] clockeven...
153
  {
aa6b43d57   Peter Zijlstra   ACPI: processor: ...
154
  	return cx - pr->power.states >= pr->power.timer_broadcast_on_state;
169a0abbe   Thomas Gleixner   [PATCH] ACPI keep...
155
156
157
  }
  
  #else
7e275cc4e   Len Brown   ACPI: idle: renam...
158
  static void lapic_timer_check_state(int state, struct acpi_processor *pr,
169a0abbe   Thomas Gleixner   [PATCH] ACPI keep...
159
  				   struct acpi_processor_cx *cstate) { }
7e275cc4e   Len Brown   ACPI: idle: renam...
160
  static void lapic_timer_propagate_broadcast(struct acpi_processor *pr) { }
aa6b43d57   Peter Zijlstra   ACPI: processor: ...
161
162
163
  
  static bool lapic_timer_needs_broadcast(struct acpi_processor *pr,
  					struct acpi_processor_cx *cx)
e9e2cdb41   Thomas Gleixner   [PATCH] clockeven...
164
  {
955921289   Rafael J. Wysocki   ACPI: processor: ...
165
  	return false;
e9e2cdb41   Thomas Gleixner   [PATCH] clockeven...
166
  }
169a0abbe   Thomas Gleixner   [PATCH] ACPI keep...
167
168
  
  #endif
592913ecb   John Stultz   time: Kill off CO...
169
  #if defined(CONFIG_X86)
520daf721   Len Brown   ACPI: idle: fix i...
170
  static void tsc_check_state(int state)
ddb25f9ac   Andi Kleen   x86: don't disabl...
171
172
  {
  	switch (boot_cpu_data.x86_vendor) {
7377ed4bd   Pu Wen   ACPI: Add Hygon D...
173
  	case X86_VENDOR_HYGON:
ddb25f9ac   Andi Kleen   x86: don't disabl...
174
  	case X86_VENDOR_AMD:
40fb17152   Venki Pallipadi   x86: support alwa...
175
  	case X86_VENDOR_INTEL:
fe6daab1e   davidwang   x86/centaur: Mark...
176
  	case X86_VENDOR_CENTAUR:
773b2f30a   Tony W Wang-oc   ACPI, x86: Add Zh...
177
  	case X86_VENDOR_ZHAOXIN:
ddb25f9ac   Andi Kleen   x86: don't disabl...
178
179
180
181
  		/*
  		 * AMD Fam10h TSC will tick in all
  		 * C/P/S0/S1 states when this bit is set.
  		 */
40fb17152   Venki Pallipadi   x86: support alwa...
182
  		if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
520daf721   Len Brown   ACPI: idle: fix i...
183
  			return;
57d2dd4bd   Gustavo A. R. Silva   ACPI: Use fallthr...
184
  		fallthrough;
ddb25f9ac   Andi Kleen   x86: don't disabl...
185
  	default:
520daf721   Len Brown   ACPI: idle: fix i...
186
187
188
  		/* TSC could halt in idle, so notify users */
  		if (state > ACPI_STATE_C1)
  			mark_tsc_unstable("TSC halts in idle");
ddb25f9ac   Andi Kleen   x86: don't disabl...
189
190
  	}
  }
520daf721   Len Brown   ACPI: idle: fix i...
191
192
  #else
  static void tsc_check_state(int state) { return; }
ddb25f9ac   Andi Kleen   x86: don't disabl...
193
  #endif
4be44fcd3   Len Brown   [ACPI] Lindent al...
194
  static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
195
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
196

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197
  	if (!pr->pblk)
d550d98d3   Patrick Mochel   ACPI: delete trac...
198
  		return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
200
  	/* if info is obtained from pblk/fadt, type equals state */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
202
  	pr->power.states[ACPI_STATE_C2].type = ACPI_STATE_C2;
  	pr->power.states[ACPI_STATE_C3].type = ACPI_STATE_C3;
4c0335526   Venkatesh Pallipadi   [ACPI] Add suppor...
203
204
205
  #ifndef CONFIG_HOTPLUG_CPU
  	/*
  	 * Check for P_LVL2_UP flag before entering C2 and above on
4f86d3a8e   Len Brown   cpuidle: consolid...
206
  	 * an SMP system.
4c0335526   Venkatesh Pallipadi   [ACPI] Add suppor...
207
  	 */
ad71860a1   Alexey Starikovskiy   ACPICA: minimal p...
208
  	if ((num_online_cpus() > 1) &&
cee324b14   Alexey Starikovskiy   ACPICA: use new A...
209
  	    !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED))
d550d98d3   Patrick Mochel   ACPI: delete trac...
210
  		return -ENODEV;
4c0335526   Venkatesh Pallipadi   [ACPI] Add suppor...
211
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
212
213
214
215
216
  	/* determine C2 and C3 address from pblk */
  	pr->power.states[ACPI_STATE_C2].address = pr->pblk + 4;
  	pr->power.states[ACPI_STATE_C3].address = pr->pblk + 5;
  
  	/* determine latencies from FADT */
ba494beea   Bob Moore   ACPICA: AcpiSrc: ...
217
218
  	pr->power.states[ACPI_STATE_C2].latency = acpi_gbl_FADT.c2_latency;
  	pr->power.states[ACPI_STATE_C3].latency = acpi_gbl_FADT.c3_latency;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
219

5d76b6f6c   Len Brown   ACPI: enable C2 a...
220
221
222
223
  	/*
  	 * FADT specified C2 latency must be less than or equal to
  	 * 100 microseconds.
  	 */
ba494beea   Bob Moore   ACPICA: AcpiSrc: ...
224
  	if (acpi_gbl_FADT.c2_latency > ACPI_PROCESSOR_MAX_C2_LATENCY) {
5d76b6f6c   Len Brown   ACPI: enable C2 a...
225
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
ba494beea   Bob Moore   ACPICA: AcpiSrc: ...
226
227
  			"C2 latency too large [%d]
  ", acpi_gbl_FADT.c2_latency));
5d76b6f6c   Len Brown   ACPI: enable C2 a...
228
229
230
  		/* invalidate C2 */
  		pr->power.states[ACPI_STATE_C2].address = 0;
  	}
a6d72c189   Len Brown   ACPI: allow C3 > ...
231
232
233
234
  	/*
  	 * FADT supplied C3 latency must be less than or equal to
  	 * 1000 microseconds.
  	 */
ba494beea   Bob Moore   ACPICA: AcpiSrc: ...
235
  	if (acpi_gbl_FADT.c3_latency > ACPI_PROCESSOR_MAX_C3_LATENCY) {
a6d72c189   Len Brown   ACPI: allow C3 > ...
236
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
ba494beea   Bob Moore   ACPICA: AcpiSrc: ...
237
238
  			"C3 latency too large [%d]
  ", acpi_gbl_FADT.c3_latency));
a6d72c189   Len Brown   ACPI: allow C3 > ...
239
240
241
  		/* invalidate C3 */
  		pr->power.states[ACPI_STATE_C3].address = 0;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
242
243
244
245
246
  	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  			  "lvl2[0x%08x] lvl3[0x%08x]
  ",
  			  pr->power.states[ACPI_STATE_C2].address,
  			  pr->power.states[ACPI_STATE_C3].address));
34a62cd0d   Yazen Ghannam   ACPI / processor:...
247
248
249
250
251
252
  	snprintf(pr->power.states[ACPI_STATE_C2].desc,
  			 ACPI_CX_DESC_LEN, "ACPI P_LVL2 IOPORT 0x%x",
  			 pr->power.states[ACPI_STATE_C2].address);
  	snprintf(pr->power.states[ACPI_STATE_C3].desc,
  			 ACPI_CX_DESC_LEN, "ACPI P_LVL3 IOPORT 0x%x",
  			 pr->power.states[ACPI_STATE_C3].address);
d550d98d3   Patrick Mochel   ACPI: delete trac...
253
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
254
  }
991528d73   Venkatesh Pallipadi   ACPI: Processor n...
255
  static int acpi_processor_get_power_info_default(struct acpi_processor *pr)
acf05f4b7   Venkatesh Pallipadi   [ACPI] update /pr...
256
  {
991528d73   Venkatesh Pallipadi   ACPI: Processor n...
257
258
259
260
261
  	if (!pr->power.states[ACPI_STATE_C1].valid) {
  		/* set the first C-State to C1 */
  		/* all processors need to support C1 */
  		pr->power.states[ACPI_STATE_C1].type = ACPI_STATE_C1;
  		pr->power.states[ACPI_STATE_C1].valid = 1;
0fda6b403   Venkatesh Pallipadi   2.6.25 regression...
262
  		pr->power.states[ACPI_STATE_C1].entry_method = ACPI_CSTATE_HALT;
248e8841b   Yazen Ghannam   ACPI / processor:...
263
264
265
  
  		snprintf(pr->power.states[ACPI_STATE_C1].desc,
  			 ACPI_CX_DESC_LEN, "ACPI HLT");
991528d73   Venkatesh Pallipadi   ACPI: Processor n...
266
267
  	}
  	/* the C0 state only exists as a filler in our array */
acf05f4b7   Venkatesh Pallipadi   [ACPI] update /pr...
268
  	pr->power.states[ACPI_STATE_C0].valid = 1;
d550d98d3   Patrick Mochel   ACPI: delete trac...
269
  	return 0;
acf05f4b7   Venkatesh Pallipadi   [ACPI] update /pr...
270
  }
987c78531   Rafael J. Wysocki   ACPI: processor: ...
271
272
273
274
275
276
277
278
279
280
  static int acpi_processor_get_power_info_cst(struct acpi_processor *pr)
  {
  	int ret;
  
  	if (nocst)
  		return -ENODEV;
  
  	ret = acpi_processor_evaluate_cst(pr->handle, pr->id, &pr->power);
  	if (ret)
  		return ret;
496121c02   Zhang Rui   ACPI: processor: ...
281
  	if (!pr->power.count)
987c78531   Rafael J. Wysocki   ACPI: processor: ...
282
283
284
285
286
  		return -EFAULT;
  
  	pr->flags.has_cst = 1;
  	return 0;
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
287
288
  static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
  					   struct acpi_processor_cx *cx)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
289
  {
ee1ca48fa   Pallipadi, Venkatesh   ACPI: Disable ARB...
290
291
  	static int bm_check_flag = -1;
  	static int bm_control_flag = -1;
02df8b938   Venkatesh Pallipadi   [ACPI] enable C2 ...
292

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
293
294
  
  	if (!cx->address)
d550d98d3   Patrick Mochel   ACPI: delete trac...
295
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
296
297
  
  	/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
298
299
300
301
302
303
304
305
  	 * PIIX4 Erratum #18: We don't support C3 when Type-F (fast)
  	 * DMA transfers are used by any ISA device to avoid livelock.
  	 * Note that we could disable Type-F DMA (as recommended by
  	 * the erratum), but this is known to disrupt certain ISA
  	 * devices thus we take the conservative approach.
  	 */
  	else if (errata.piix4.fdma) {
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
4be44fcd3   Len Brown   [ACPI] Lindent al...
306
307
  				  "C3 not supported on PIIX4 with Type-F DMA
  "));
d550d98d3   Patrick Mochel   ACPI: delete trac...
308
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
309
  	}
02df8b938   Venkatesh Pallipadi   [ACPI] enable C2 ...
310
  	/* All the logic here assumes flags.bm_check is same across all CPUs */
ee1ca48fa   Pallipadi, Venkatesh   ACPI: Disable ARB...
311
  	if (bm_check_flag == -1) {
02df8b938   Venkatesh Pallipadi   [ACPI] enable C2 ...
312
313
314
  		/* Determine whether bm_check is needed based on CPU  */
  		acpi_processor_power_init_bm_check(&(pr->flags), pr->id);
  		bm_check_flag = pr->flags.bm_check;
ee1ca48fa   Pallipadi, Venkatesh   ACPI: Disable ARB...
315
  		bm_control_flag = pr->flags.bm_control;
02df8b938   Venkatesh Pallipadi   [ACPI] enable C2 ...
316
317
  	} else {
  		pr->flags.bm_check = bm_check_flag;
ee1ca48fa   Pallipadi, Venkatesh   ACPI: Disable ARB...
318
  		pr->flags.bm_control = bm_control_flag;
02df8b938   Venkatesh Pallipadi   [ACPI] enable C2 ...
319
320
321
  	}
  
  	if (pr->flags.bm_check) {
02df8b938   Venkatesh Pallipadi   [ACPI] enable C2 ...
322
  		if (!pr->flags.bm_control) {
ed3110efb   Venki Pallipadi   ACPI: fix "Time P...
323
324
325
326
327
328
329
330
331
332
333
334
  			if (pr->flags.has_cst != 1) {
  				/* bus mastering control is necessary */
  				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  					"C3 support requires BM control
  "));
  				return;
  			} else {
  				/* Here we enter C3 without bus mastering */
  				ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  					"C3 support without BM control
  "));
  			}
02df8b938   Venkatesh Pallipadi   [ACPI] enable C2 ...
335
336
  		}
  	} else {
02df8b938   Venkatesh Pallipadi   [ACPI] enable C2 ...
337
338
339
340
  		/*
  		 * WBINVD should be set in fadt, for C3 state to be
  		 * supported on when bm_check is not required.
  		 */
cee324b14   Alexey Starikovskiy   ACPICA: use new A...
341
  		if (!(acpi_gbl_FADT.flags & ACPI_FADT_WBINVD)) {
02df8b938   Venkatesh Pallipadi   [ACPI] enable C2 ...
342
  			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
4be44fcd3   Len Brown   [ACPI] Lindent al...
343
344
345
  					  "Cache invalidation should work properly"
  					  " for C3 to be enabled on SMP systems
  "));
d550d98d3   Patrick Mochel   ACPI: delete trac...
346
  			return;
02df8b938   Venkatesh Pallipadi   [ACPI] enable C2 ...
347
  		}
02df8b938   Venkatesh Pallipadi   [ACPI] enable C2 ...
348
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
349
350
351
352
353
354
355
  	/*
  	 * Otherwise we've met all of our C3 requirements.
  	 * Normalize the C3 latency to expidite policy.  Enable
  	 * checking of bus mastering status (bm_check) so we can
  	 * use this in our C3 policy
  	 */
  	cx->valid = 1;
4f86d3a8e   Len Brown   cpuidle: consolid...
356

31878dd86   Len Brown   ACPI: remove BM_R...
357
358
359
360
361
362
363
364
  	/*
  	 * On older chipsets, BM_RLD needs to be set
  	 * in order for Bus Master activity to wake the
  	 * system from C3.  Newer chipsets handle DMA
  	 * during C3 automatically and BM_RLD is a NOP.
  	 * In either case, the proper way to
  	 * handle BM_RLD is to set it and leave it set.
  	 */
50ffba1bd   Bob Moore   ACPICA: Rename AC...
365
  	acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
366

d550d98d3   Patrick Mochel   ACPI: delete trac...
367
  	return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
368
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
369
370
371
372
  static int acpi_processor_power_verify(struct acpi_processor *pr)
  {
  	unsigned int i;
  	unsigned int working = 0;
6eb0a0fd0   Venkatesh Pallipadi   [PATCH] i386: Han...
373

169a0abbe   Thomas Gleixner   [PATCH] ACPI keep...
374
  	pr->power.timer_broadcast_on_state = INT_MAX;
6eb0a0fd0   Venkatesh Pallipadi   [PATCH] i386: Han...
375

a0bf284bf   Len Brown   ACPI: Idle C-stat...
376
  	for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
377
378
379
380
381
382
383
384
  		struct acpi_processor_cx *cx = &pr->power.states[i];
  
  		switch (cx->type) {
  		case ACPI_STATE_C1:
  			cx->valid = 1;
  			break;
  
  		case ACPI_STATE_C2:
d22edd293   Len Brown   ACPI: delete acpi...
385
386
  			if (!cx->address)
  				break;
cad1525a5   Al Stone   ACPI: remove trai...
387
  			cx->valid = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
388
389
390
391
392
393
  			break;
  
  		case ACPI_STATE_C3:
  			acpi_processor_power_verify_c3(pr, cx);
  			break;
  		}
7e275cc4e   Len Brown   ACPI: idle: renam...
394
395
  		if (!cx->valid)
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
396

7e275cc4e   Len Brown   ACPI: idle: renam...
397
398
399
  		lapic_timer_check_state(i, pr, cx);
  		tsc_check_state(cx->type);
  		working++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
400
  	}
bd6633476   Andi Kleen   [PATCH] x86_64: F...
401

918aae42a   Hidetoshi Seto   ACPI: fix for lap...
402
  	lapic_timer_propagate_broadcast(pr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
403
404
405
  
  	return (working);
  }
a36a7fecf   Sudeep Holla   ACPI / processor_...
406
  static int acpi_processor_get_cstate_info(struct acpi_processor *pr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
407
408
409
  {
  	unsigned int i;
  	int result;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
410
411
412
  
  	/* NOTE: the idle thread may not be running while calling
  	 * this function */
991528d73   Venkatesh Pallipadi   ACPI: Processor n...
413
414
  	/* Zero initialize all the C-states info. */
  	memset(pr->power.states, 0, sizeof(pr->power.states));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
415
  	result = acpi_processor_get_power_info_cst(pr);
6d93c6480   Venkatesh Pallipadi   [ACPI] Prefer _CS...
416
  	if (result == -ENODEV)
c5a114f1f   Darrick J. Wong   [PATCH] fix "ACPI...
417
  		result = acpi_processor_get_power_info_fadt(pr);
6d93c6480   Venkatesh Pallipadi   [ACPI] Prefer _CS...
418

991528d73   Venkatesh Pallipadi   ACPI: Processor n...
419
420
421
422
  	if (result)
  		return result;
  
  	acpi_processor_get_power_info_default(pr);
cf8247884   Janosch Machowinski   [ACPI] handle BIO...
423
  	pr->power.count = acpi_processor_power_verify(pr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
424

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
425
426
427
428
429
  	/*
  	 * if one state of type C2 or C3 is available, mark this
  	 * CPU as being "idle manageable"
  	 */
  	for (i = 1; i < ACPI_PROCESSOR_MAX_POWER; i++) {
acf05f4b7   Venkatesh Pallipadi   [ACPI] update /pr...
430
  		if (pr->power.states[i].valid) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
431
  			pr->power.count = i;
496121c02   Zhang Rui   ACPI: processor: ...
432
  			pr->flags.power = 1;
acf05f4b7   Venkatesh Pallipadi   [ACPI] update /pr...
433
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
434
  	}
d550d98d3   Patrick Mochel   ACPI: delete trac...
435
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
436
  }
4f86d3a8e   Len Brown   cpuidle: consolid...
437
438
439
440
441
442
  /**
   * acpi_idle_bm_check - checks if bus master activity was detected
   */
  static int acpi_idle_bm_check(void)
  {
  	u32 bm_status = 0;
d3e7e99f2   Len Brown   ACPI: create "pro...
443
444
  	if (bm_check_disable)
  		return 0;
50ffba1bd   Bob Moore   ACPICA: Rename AC...
445
  	acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
4f86d3a8e   Len Brown   cpuidle: consolid...
446
  	if (bm_status)
50ffba1bd   Bob Moore   ACPICA: Rename AC...
447
  		acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
4f86d3a8e   Len Brown   cpuidle: consolid...
448
449
450
451
452
453
454
455
456
457
458
459
  	/*
  	 * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
  	 * the true state of bus mastering activity; forcing us to
  	 * manually check the BMIDEA bit of each IDE channel.
  	 */
  	else if (errata.piix4.bmisx) {
  		if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01)
  		    || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01))
  			bm_status = 1;
  	}
  	return bm_status;
  }
fa583f71a   Yin Fengwei   ACPI: processor_i...
460
461
462
463
464
465
466
467
468
469
470
471
  static void wait_for_freeze(void)
  {
  #ifdef	CONFIG_X86
  	/* No delay is needed if we are in guest */
  	if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
  		return;
  #endif
  	/* Dummy wait op - must do something useless after P_LVL2 read
  	   because chipsets cannot guarantee that STPCLK# signal
  	   gets asserted in time to freeze execution properly. */
  	inl(acpi_gbl_FADT.xpm_timer_block.address);
  }
4f86d3a8e   Len Brown   cpuidle: consolid...
472
  /**
b00783fd9   Rafael J. Wysocki   ACPI / cpuidle: D...
473
   * acpi_idle_do_entry - enter idle state using the appropriate method
4f86d3a8e   Len Brown   cpuidle: consolid...
474
   * @cx: cstate data
bc71bec91   venkatesh.pallipadi@intel.com   ACPI: enable MWAI...
475
476
   *
   * Caller disables interrupt before call and enables interrupt after return.
4f86d3a8e   Len Brown   cpuidle: consolid...
477
   */
6727ad9e2   Chris Metcalf   nmi_backtrace: ge...
478
  static void __cpuidle acpi_idle_do_entry(struct acpi_processor_cx *cx)
4f86d3a8e   Len Brown   cpuidle: consolid...
479
  {
bc71bec91   venkatesh.pallipadi@intel.com   ACPI: enable MWAI...
480
  	if (cx->entry_method == ACPI_CSTATE_FFH) {
4f86d3a8e   Len Brown   cpuidle: consolid...
481
482
  		/* Call into architectural FFH based C-state */
  		acpi_processor_ffh_cstate_enter(cx);
bc71bec91   venkatesh.pallipadi@intel.com   ACPI: enable MWAI...
483
484
  	} else if (cx->entry_method == ACPI_CSTATE_HALT) {
  		acpi_safe_halt();
4f86d3a8e   Len Brown   cpuidle: consolid...
485
  	} else {
4f86d3a8e   Len Brown   cpuidle: consolid...
486
487
  		/* IO port based C-state */
  		inb(cx->address);
fa583f71a   Yin Fengwei   ACPI: processor_i...
488
  		wait_for_freeze();
4f86d3a8e   Len Brown   cpuidle: consolid...
489
490
491
492
  	}
  }
  
  /**
1a022e3f1   Boris Ostrovsky   idle, x86: Allow ...
493
494
495
496
497
498
   * acpi_idle_play_dead - enters an ACPI state for long-term idle (i.e. off-lining)
   * @dev: the target CPU
   * @index: the index of suggested state
   */
  static int acpi_idle_play_dead(struct cpuidle_device *dev, int index)
  {
6240a10dc   Alex Shi   cpuidle / ACPI: r...
499
  	struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu);
1a022e3f1   Boris Ostrovsky   idle, x86: Allow ...
500
501
502
503
504
505
  
  	ACPI_FLUSH_CPU_CACHE();
  
  	while (1) {
  
  		if (cx->entry_method == ACPI_CSTATE_HALT)
54f700777   Tony Luck   ACPI processor: U...
506
  			safe_halt();
1a022e3f1   Boris Ostrovsky   idle, x86: Allow ...
507
508
  		else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) {
  			inb(cx->address);
fa583f71a   Yin Fengwei   ACPI: processor_i...
509
  			wait_for_freeze();
1a022e3f1   Boris Ostrovsky   idle, x86: Allow ...
510
511
512
513
514
515
516
  		} else
  			return -ENODEV;
  	}
  
  	/* Never reached */
  	return 0;
  }
adcb2623f   Rafael J. Wysocki   ACPI / cpuidle: C...
517
518
  static bool acpi_idle_fallback_to_c1(struct acpi_processor *pr)
  {
5f5081852   Rafael J. Wysocki   ACPI / idle: Impl...
519
520
  	return IS_ENABLED(CONFIG_HOTPLUG_CPU) && !pr->flags.has_cst &&
  		!(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED);
adcb2623f   Rafael J. Wysocki   ACPI / cpuidle: C...
521
  }
4f86d3a8e   Len Brown   cpuidle: consolid...
522
  static int c3_cpu_count;
e12f65f7a   Thomas Gleixner   locking, ACPI: An...
523
  static DEFINE_RAW_SPINLOCK(c3_lock);
4f86d3a8e   Len Brown   cpuidle: consolid...
524
525
526
  
  /**
   * acpi_idle_enter_bm - enters C3 with proper BM handling
1fecfdbb7   Peter Zijlstra   ACPI: processor: ...
527
   * @drv: cpuidle driver
6491bc0c6   Rafael J. Wysocki   ACPI / cpuidle: C...
528
529
   * @pr: Target processor
   * @cx: Target state context
1fecfdbb7   Peter Zijlstra   ACPI: processor: ...
530
   * @index: index of target state
4f86d3a8e   Len Brown   cpuidle: consolid...
531
   */
1fecfdbb7   Peter Zijlstra   ACPI: processor: ...
532
533
534
535
  static int acpi_idle_enter_bm(struct cpuidle_driver *drv,
  			       struct acpi_processor *pr,
  			       struct acpi_processor_cx *cx,
  			       int index)
4f86d3a8e   Len Brown   cpuidle: consolid...
536
  {
1fecfdbb7   Peter Zijlstra   ACPI: processor: ...
537
538
539
  	static struct acpi_processor_cx safe_cx = {
  		.entry_method = ACPI_CSTATE_HALT,
  	};
4f86d3a8e   Len Brown   cpuidle: consolid...
540
  	/*
ddc081a19   Venkatesh Pallipadi   cpuidle: fix HP n...
541
542
  	 * disable bus master
  	 * bm_check implies we need ARB_DIS
ddc081a19   Venkatesh Pallipadi   cpuidle: fix HP n...
543
544
  	 * bm_control implies whether we can do ARB_DIS
  	 *
1fecfdbb7   Peter Zijlstra   ACPI: processor: ...
545
546
  	 * That leaves a case where bm_check is set and bm_control is not set.
  	 * In that case we cannot do much, we enter C3 without doing anything.
ddc081a19   Venkatesh Pallipadi   cpuidle: fix HP n...
547
  	 */
1fecfdbb7   Peter Zijlstra   ACPI: processor: ...
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
  	bool dis_bm = pr->flags.bm_control;
  
  	/* If we can skip BM, demote to a safe state. */
  	if (!cx->bm_sts_skip && acpi_idle_bm_check()) {
  		dis_bm = false;
  		index = drv->safe_state_index;
  		if (index >= 0) {
  			cx = this_cpu_read(acpi_cstate[index]);
  		} else {
  			cx = &safe_cx;
  			index = -EBUSY;
  		}
  	}
  
  	if (dis_bm) {
e12f65f7a   Thomas Gleixner   locking, ACPI: An...
563
  		raw_spin_lock(&c3_lock);
4f86d3a8e   Len Brown   cpuidle: consolid...
564
565
566
  		c3_cpu_count++;
  		/* Disable bus master arbitration when all CPUs are in C3 */
  		if (c3_cpu_count == num_online_cpus())
50ffba1bd   Bob Moore   ACPICA: Rename AC...
567
  			acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
e12f65f7a   Thomas Gleixner   locking, ACPI: An...
568
  		raw_spin_unlock(&c3_lock);
ddc081a19   Venkatesh Pallipadi   cpuidle: fix HP n...
569
  	}
4f86d3a8e   Len Brown   cpuidle: consolid...
570

1fecfdbb7   Peter Zijlstra   ACPI: processor: ...
571
  	rcu_idle_enter();
ddc081a19   Venkatesh Pallipadi   cpuidle: fix HP n...
572
  	acpi_idle_do_entry(cx);
4f86d3a8e   Len Brown   cpuidle: consolid...
573

1fecfdbb7   Peter Zijlstra   ACPI: processor: ...
574
  	rcu_idle_exit();
ddc081a19   Venkatesh Pallipadi   cpuidle: fix HP n...
575
  	/* Re-enable bus master arbitration */
1fecfdbb7   Peter Zijlstra   ACPI: processor: ...
576
  	if (dis_bm) {
e12f65f7a   Thomas Gleixner   locking, ACPI: An...
577
  		raw_spin_lock(&c3_lock);
50ffba1bd   Bob Moore   ACPICA: Rename AC...
578
  		acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
4f86d3a8e   Len Brown   cpuidle: consolid...
579
  		c3_cpu_count--;
e12f65f7a   Thomas Gleixner   locking, ACPI: An...
580
  		raw_spin_unlock(&c3_lock);
4f86d3a8e   Len Brown   cpuidle: consolid...
581
  	}
1fecfdbb7   Peter Zijlstra   ACPI: processor: ...
582
583
  
  	return index;
6491bc0c6   Rafael J. Wysocki   ACPI / cpuidle: C...
584
585
586
587
588
589
590
591
592
593
594
595
596
  }
  
  static int acpi_idle_enter(struct cpuidle_device *dev,
  			   struct cpuidle_driver *drv, int index)
  {
  	struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu);
  	struct acpi_processor *pr;
  
  	pr = __this_cpu_read(processors);
  	if (unlikely(!pr))
  		return -EINVAL;
  
  	if (cx->type != ACPI_STATE_C1) {
1fecfdbb7   Peter Zijlstra   ACPI: processor: ...
597
598
599
600
  		if (cx->type == ACPI_STATE_C3 && pr->flags.bm_check)
  			return acpi_idle_enter_bm(drv, pr, cx, index);
  
  		/* C2 to C1 demotion. */
5f5081852   Rafael J. Wysocki   ACPI / idle: Impl...
601
  		if (acpi_idle_fallback_to_c1(pr) && num_online_cpus() > 1) {
dc2251bf9   Rafael J. Wysocki   cpuidle: Eliminat...
602
  			index = ACPI_IDLE_STATE_START;
6491bc0c6   Rafael J. Wysocki   ACPI / cpuidle: C...
603
  			cx = per_cpu(acpi_cstate[index], dev->cpu);
6491bc0c6   Rafael J. Wysocki   ACPI / cpuidle: C...
604
605
  		}
  	}
6491bc0c6   Rafael J. Wysocki   ACPI / cpuidle: C...
606
607
608
609
  	if (cx->type == ACPI_STATE_C3)
  		ACPI_FLUSH_CPU_CACHE();
  
  	acpi_idle_do_entry(cx);
e978aa7d7   Deepthi Dharwar   cpuidle: Move dev...
610
  	return index;
4f86d3a8e   Len Brown   cpuidle: consolid...
611
  }
efe971121   Neal Liu   cpuidle: change e...
612
613
  static int acpi_idle_enter_s2idle(struct cpuidle_device *dev,
  				  struct cpuidle_driver *drv, int index)
5f5081852   Rafael J. Wysocki   ACPI / idle: Impl...
614
615
616
617
618
619
620
  {
  	struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu);
  
  	if (cx->type == ACPI_STATE_C3) {
  		struct acpi_processor *pr = __this_cpu_read(processors);
  
  		if (unlikely(!pr))
0a398945d   Neal Liu   cpuidle: ACPI: fi...
621
  			return 0;
5f5081852   Rafael J. Wysocki   ACPI / idle: Impl...
622
623
  
  		if (pr->flags.bm_check) {
1fecfdbb7   Peter Zijlstra   ACPI: processor: ...
624
625
626
627
628
629
  			u8 bm_sts_skip = cx->bm_sts_skip;
  
  			/* Don't check BM_STS, do an unconditional ARB_DIS for S2IDLE */
  			cx->bm_sts_skip = 1;
  			acpi_idle_enter_bm(drv, pr, cx, index);
  			cx->bm_sts_skip = bm_sts_skip;
0a398945d   Neal Liu   cpuidle: ACPI: fi...
630
  			return 0;
5f5081852   Rafael J. Wysocki   ACPI / idle: Impl...
631
632
633
634
635
  		} else {
  			ACPI_FLUSH_CPU_CACHE();
  		}
  	}
  	acpi_idle_do_entry(cx);
efe971121   Neal Liu   cpuidle: change e...
636
637
  
  	return 0;
5f5081852   Rafael J. Wysocki   ACPI / idle: Impl...
638
  }
6ef0f086b   Daniel Lezcano   ACPI / idle: pass...
639
640
  static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr,
  					   struct cpuidle_device *dev)
4f86d3a8e   Len Brown   cpuidle: consolid...
641
  {
dc2251bf9   Rafael J. Wysocki   cpuidle: Eliminat...
642
  	int i, count = ACPI_IDLE_STATE_START;
4f86d3a8e   Len Brown   cpuidle: consolid...
643
  	struct acpi_processor_cx *cx;
aa6b43d57   Peter Zijlstra   ACPI: processor: ...
644
  	struct cpuidle_state *state;
4f86d3a8e   Len Brown   cpuidle: consolid...
645

615dfd93e   Len Brown   ACPI: prevent pro...
646
647
  	if (max_cstate == 0)
  		max_cstate = 1;
4f86d3a8e   Len Brown   cpuidle: consolid...
648
  	for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
a889a23a9   Peter Zijlstra   ACPI: processor: ...
649
  		state = &acpi_idle_driver.states[count];
4f86d3a8e   Len Brown   cpuidle: consolid...
650
  		cx = &pr->power.states[i];
4f86d3a8e   Len Brown   cpuidle: consolid...
651
652
653
  
  		if (!cx->valid)
  			continue;
6240a10dc   Alex Shi   cpuidle / ACPI: r...
654
  		per_cpu(acpi_cstate[count], dev->cpu) = cx;
4f86d3a8e   Len Brown   cpuidle: consolid...
655

a889a23a9   Peter Zijlstra   ACPI: processor: ...
656
  		if (lapic_timer_needs_broadcast(pr, cx))
aa6b43d57   Peter Zijlstra   ACPI: processor: ...
657
  			state->flags |= CPUIDLE_FLAG_TIMER_STOP;
a889a23a9   Peter Zijlstra   ACPI: processor: ...
658

1fecfdbb7   Peter Zijlstra   ACPI: processor: ...
659
  		if (cx->type == ACPI_STATE_C3) {
a889a23a9   Peter Zijlstra   ACPI: processor: ...
660
  			state->flags |= CPUIDLE_FLAG_TLB_FLUSHED;
1fecfdbb7   Peter Zijlstra   ACPI: processor: ...
661
662
663
  			if (pr->flags.bm_check)
  				state->flags |= CPUIDLE_FLAG_RCU_IDLE;
  		}
aa6b43d57   Peter Zijlstra   ACPI: processor: ...
664

46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
665
666
667
668
  		count++;
  		if (count == CPUIDLE_STATE_MAX)
  			break;
  	}
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
669
670
671
672
673
  	if (!count)
  		return -EINVAL;
  
  	return 0;
  }
a36a7fecf   Sudeep Holla   ACPI / processor_...
674
  static int acpi_processor_setup_cstates(struct acpi_processor *pr)
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
675
  {
1b39e3f81   Rafael J. Wysocki   cpuidle: Make dri...
676
  	int i, count;
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
677
678
679
  	struct acpi_processor_cx *cx;
  	struct cpuidle_state *state;
  	struct cpuidle_driver *drv = &acpi_idle_driver;
615dfd93e   Len Brown   ACPI: prevent pro...
680
681
  	if (max_cstate == 0)
  		max_cstate = 1;
1b39e3f81   Rafael J. Wysocki   cpuidle: Make dri...
682
683
684
685
686
687
  	if (IS_ENABLED(CONFIG_ARCH_HAS_CPU_RELAX)) {
  		cpuidle_poll_state_init(drv);
  		count = 1;
  	} else {
  		count = 0;
  	}
4f86d3a8e   Len Brown   cpuidle: consolid...
688
689
  	for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) {
  		cx = &pr->power.states[i];
4f86d3a8e   Len Brown   cpuidle: consolid...
690
691
692
  
  		if (!cx->valid)
  			continue;
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
693
  		state = &drv->states[count];
4f86d3a8e   Len Brown   cpuidle: consolid...
694
  		snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i);
a36a7fecf   Sudeep Holla   ACPI / processor_...
695
  		strlcpy(state->desc, cx->desc, CPUIDLE_DESC_LEN);
4f86d3a8e   Len Brown   cpuidle: consolid...
696
  		state->exit_latency = cx->latency;
4963f6204   Len Brown   cpuidle: create p...
697
  		state->target_residency = cx->latency * latency_factor;
6491bc0c6   Rafael J. Wysocki   ACPI / cpuidle: C...
698
  		state->enter = acpi_idle_enter;
4f86d3a8e   Len Brown   cpuidle: consolid...
699
700
  
  		state->flags = 0;
6491bc0c6   Rafael J. Wysocki   ACPI / cpuidle: C...
701
  		if (cx->type == ACPI_STATE_C1 || cx->type == ACPI_STATE_C2) {
1a022e3f1   Boris Ostrovsky   idle, x86: Allow ...
702
  			state->enter_dead = acpi_idle_play_dead;
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
703
  			drv->safe_state_index = count;
4f86d3a8e   Len Brown   cpuidle: consolid...
704
  		}
5f5081852   Rafael J. Wysocki   ACPI / idle: Impl...
705
  		/*
28ba086ed   Rafael J. Wysocki   PM / s2idle: Rena...
706
  		 * Halt-induced C1 is not good for ->enter_s2idle, because it
5f5081852   Rafael J. Wysocki   ACPI / idle: Impl...
707
708
709
710
711
712
  		 * re-enables interrupts on exit.  Moreover, C1 is generally not
  		 * particularly interesting from the suspend-to-idle angle, so
  		 * avoid C1 and the situations in which we may need to fall back
  		 * to it altogether.
  		 */
  		if (cx->type != ACPI_STATE_C1 && !acpi_idle_fallback_to_c1(pr))
28ba086ed   Rafael J. Wysocki   PM / s2idle: Rena...
713
  			state->enter_s2idle = acpi_idle_enter_s2idle;
4f86d3a8e   Len Brown   cpuidle: consolid...
714
715
  
  		count++;
9a0b84158   venkatesh.pallipadi@intel.com   cpuidle: Add a po...
716
717
  		if (count == CPUIDLE_STATE_MAX)
  			break;
4f86d3a8e   Len Brown   cpuidle: consolid...
718
  	}
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
719
  	drv->state_count = count;
4f86d3a8e   Len Brown   cpuidle: consolid...
720
721
722
  
  	if (!count)
  		return -EINVAL;
4f86d3a8e   Len Brown   cpuidle: consolid...
723
724
  	return 0;
  }
35ae71335   Sudeep Holla   ACPI / processor_...
725
726
  static inline void acpi_processor_cstate_first_run_checks(void)
  {
35ae71335   Sudeep Holla   ACPI / processor_...
727
728
729
730
731
732
733
734
735
736
737
  	static int first_run;
  
  	if (first_run)
  		return;
  	dmi_check_system(processor_power_dmi_table);
  	max_cstate = acpi_processor_cstate_check(max_cstate);
  	if (max_cstate < ACPI_C_STATES_MAX)
  		pr_notice("ACPI: processor limited to max C-state %d
  ",
  			  max_cstate);
  	first_run++;
bc9463888   Rafael J. Wysocki   ACPI: processor: ...
738
739
740
741
  	if (nocst)
  		return;
  
  	acpi_processor_claim_cst_control();
35ae71335   Sudeep Holla   ACPI / processor_...
742
743
744
745
746
  }
  #else
  
  static inline int disabled_by_idle_boot_param(void) { return 0; }
  static inline void acpi_processor_cstate_first_run_checks(void) { }
a36a7fecf   Sudeep Holla   ACPI / processor_...
747
  static int acpi_processor_get_cstate_info(struct acpi_processor *pr)
35ae71335   Sudeep Holla   ACPI / processor_...
748
749
750
751
752
753
754
755
756
  {
  	return -ENODEV;
  }
  
  static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr,
  					   struct cpuidle_device *dev)
  {
  	return -EINVAL;
  }
a36a7fecf   Sudeep Holla   ACPI / processor_...
757
  static int acpi_processor_setup_cstates(struct acpi_processor *pr)
35ae71335   Sudeep Holla   ACPI / processor_...
758
759
760
761
762
  {
  	return -EINVAL;
  }
  
  #endif /* CONFIG_ACPI_PROCESSOR_CSTATE */
a36a7fecf   Sudeep Holla   ACPI / processor_...
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
  struct acpi_lpi_states_array {
  	unsigned int size;
  	unsigned int composite_states_size;
  	struct acpi_lpi_state *entries;
  	struct acpi_lpi_state *composite_states[ACPI_PROCESSOR_MAX_POWER];
  };
  
  static int obj_get_integer(union acpi_object *obj, u32 *value)
  {
  	if (obj->type != ACPI_TYPE_INTEGER)
  		return -EINVAL;
  
  	*value = obj->integer.value;
  	return 0;
  }
  
  static int acpi_processor_evaluate_lpi(acpi_handle handle,
  				       struct acpi_lpi_states_array *info)
  {
  	acpi_status status;
  	int ret = 0;
  	int pkg_count, state_idx = 1, loop;
  	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
  	union acpi_object *lpi_data;
  	struct acpi_lpi_state *lpi_state;
  
  	status = acpi_evaluate_object(handle, "_LPI", NULL, &buffer);
  	if (ACPI_FAILURE(status)) {
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No _LPI, giving up
  "));
  		return -ENODEV;
  	}
  
  	lpi_data = buffer.pointer;
  
  	/* There must be at least 4 elements = 3 elements + 1 package */
  	if (!lpi_data || lpi_data->type != ACPI_TYPE_PACKAGE ||
  	    lpi_data->package.count < 4) {
  		pr_debug("not enough elements in _LPI
  ");
  		ret = -ENODATA;
  		goto end;
  	}
  
  	pkg_count = lpi_data->package.elements[2].integer.value;
  
  	/* Validate number of power states. */
  	if (pkg_count < 1 || pkg_count != lpi_data->package.count - 3) {
  		pr_debug("count given by _LPI is not valid
  ");
  		ret = -ENODATA;
  		goto end;
  	}
  
  	lpi_state = kcalloc(pkg_count, sizeof(*lpi_state), GFP_KERNEL);
  	if (!lpi_state) {
  		ret = -ENOMEM;
  		goto end;
  	}
  
  	info->size = pkg_count;
  	info->entries = lpi_state;
  
  	/* LPI States start at index 3 */
  	for (loop = 3; state_idx <= pkg_count; loop++, state_idx++, lpi_state++) {
  		union acpi_object *element, *pkg_elem, *obj;
  
  		element = &lpi_data->package.elements[loop];
  		if (element->type != ACPI_TYPE_PACKAGE || element->package.count < 7)
  			continue;
  
  		pkg_elem = element->package.elements;
  
  		obj = pkg_elem + 6;
  		if (obj->type == ACPI_TYPE_BUFFER) {
  			struct acpi_power_register *reg;
  
  			reg = (struct acpi_power_register *)obj->buffer.pointer;
  			if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO &&
  			    reg->space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)
  				continue;
  
  			lpi_state->address = reg->address;
  			lpi_state->entry_method =
  				reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE ?
  				ACPI_CSTATE_FFH : ACPI_CSTATE_SYSTEMIO;
  		} else if (obj->type == ACPI_TYPE_INTEGER) {
  			lpi_state->entry_method = ACPI_CSTATE_INTEGER;
  			lpi_state->address = obj->integer.value;
  		} else {
  			continue;
  		}
  
  		/* elements[7,8] skipped for now i.e. Residency/Usage counter*/
  
  		obj = pkg_elem + 9;
  		if (obj->type == ACPI_TYPE_STRING)
  			strlcpy(lpi_state->desc, obj->string.pointer,
  				ACPI_CX_DESC_LEN);
  
  		lpi_state->index = state_idx;
  		if (obj_get_integer(pkg_elem + 0, &lpi_state->min_residency)) {
  			pr_debug("No min. residency found, assuming 10 us
  ");
  			lpi_state->min_residency = 10;
  		}
  
  		if (obj_get_integer(pkg_elem + 1, &lpi_state->wake_latency)) {
  			pr_debug("No wakeup residency found, assuming 10 us
  ");
  			lpi_state->wake_latency = 10;
  		}
  
  		if (obj_get_integer(pkg_elem + 2, &lpi_state->flags))
  			lpi_state->flags = 0;
  
  		if (obj_get_integer(pkg_elem + 3, &lpi_state->arch_flags))
  			lpi_state->arch_flags = 0;
  
  		if (obj_get_integer(pkg_elem + 4, &lpi_state->res_cnt_freq))
  			lpi_state->res_cnt_freq = 1;
  
  		if (obj_get_integer(pkg_elem + 5, &lpi_state->enable_parent_state))
  			lpi_state->enable_parent_state = 0;
  	}
  
  	acpi_handle_debug(handle, "Found %d power states
  ", state_idx);
  end:
  	kfree(buffer.pointer);
  	return ret;
  }
  
  /*
   * flat_state_cnt - the number of composite LPI states after the process of flattening
   */
  static int flat_state_cnt;
  
  /**
   * combine_lpi_states - combine local and parent LPI states to form a composite LPI state
   *
   * @local: local LPI state
   * @parent: parent LPI state
   * @result: composite LPI state
   */
  static bool combine_lpi_states(struct acpi_lpi_state *local,
  			       struct acpi_lpi_state *parent,
  			       struct acpi_lpi_state *result)
  {
  	if (parent->entry_method == ACPI_CSTATE_INTEGER) {
  		if (!parent->address) /* 0 means autopromotable */
  			return false;
  		result->address = local->address + parent->address;
  	} else {
  		result->address = parent->address;
  	}
  
  	result->min_residency = max(local->min_residency, parent->min_residency);
  	result->wake_latency = local->wake_latency + parent->wake_latency;
  	result->enable_parent_state = parent->enable_parent_state;
  	result->entry_method = local->entry_method;
  
  	result->flags = parent->flags;
  	result->arch_flags = parent->arch_flags;
  	result->index = parent->index;
  
  	strlcpy(result->desc, local->desc, ACPI_CX_DESC_LEN);
  	strlcat(result->desc, "+", ACPI_CX_DESC_LEN);
  	strlcat(result->desc, parent->desc, ACPI_CX_DESC_LEN);
  	return true;
  }
  
  #define ACPI_LPI_STATE_FLAGS_ENABLED			BIT(0)
  
  static void stash_composite_state(struct acpi_lpi_states_array *curr_level,
  				  struct acpi_lpi_state *t)
  {
  	curr_level->composite_states[curr_level->composite_states_size++] = t;
  }
  
  static int flatten_lpi_states(struct acpi_processor *pr,
  			      struct acpi_lpi_states_array *curr_level,
  			      struct acpi_lpi_states_array *prev_level)
  {
  	int i, j, state_count = curr_level->size;
  	struct acpi_lpi_state *p, *t = curr_level->entries;
  
  	curr_level->composite_states_size = 0;
  	for (j = 0; j < state_count; j++, t++) {
  		struct acpi_lpi_state *flpi;
  
  		if (!(t->flags & ACPI_LPI_STATE_FLAGS_ENABLED))
  			continue;
  
  		if (flat_state_cnt >= ACPI_PROCESSOR_MAX_POWER) {
  			pr_warn("Limiting number of LPI states to max (%d)
  ",
  				ACPI_PROCESSOR_MAX_POWER);
  			pr_warn("Please increase ACPI_PROCESSOR_MAX_POWER if needed.
  ");
  			break;
  		}
  
  		flpi = &pr->power.lpi_states[flat_state_cnt];
  
  		if (!prev_level) { /* leaf/processor node */
  			memcpy(flpi, t, sizeof(*t));
  			stash_composite_state(curr_level, flpi);
  			flat_state_cnt++;
  			continue;
  		}
  
  		for (i = 0; i < prev_level->composite_states_size; i++) {
  			p = prev_level->composite_states[i];
  			if (t->index <= p->enable_parent_state &&
  			    combine_lpi_states(p, t, flpi)) {
  				stash_composite_state(curr_level, flpi);
  				flat_state_cnt++;
  				flpi++;
  			}
  		}
  	}
  
  	kfree(curr_level->entries);
  	return 0;
  }
  
  static int acpi_processor_get_lpi_info(struct acpi_processor *pr)
  {
  	int ret, i;
  	acpi_status status;
  	acpi_handle handle = pr->handle, pr_ahandle;
  	struct acpi_device *d = NULL;
  	struct acpi_lpi_states_array info[2], *tmp, *prev, *curr;
  
  	if (!osc_pc_lpi_support_confirmed)
  		return -EOPNOTSUPP;
  
  	if (!acpi_has_method(handle, "_LPI"))
  		return -EINVAL;
  
  	flat_state_cnt = 0;
  	prev = &info[0];
  	curr = &info[1];
  	handle = pr->handle;
  	ret = acpi_processor_evaluate_lpi(handle, prev);
  	if (ret)
  		return ret;
  	flatten_lpi_states(pr, prev, NULL);
  
  	status = acpi_get_parent(handle, &pr_ahandle);
  	while (ACPI_SUCCESS(status)) {
  		acpi_bus_get_device(pr_ahandle, &d);
  		handle = pr_ahandle;
  
  		if (strcmp(acpi_device_hid(d), ACPI_PROCESSOR_CONTAINER_HID))
  			break;
  
  		/* can be optional ? */
  		if (!acpi_has_method(handle, "_LPI"))
  			break;
  
  		ret = acpi_processor_evaluate_lpi(handle, curr);
  		if (ret)
  			break;
  
  		/* flatten all the LPI states in this level of hierarchy */
  		flatten_lpi_states(pr, curr, prev);
  
  		tmp = prev, prev = curr, curr = tmp;
  
  		status = acpi_get_parent(handle, &pr_ahandle);
  	}
  
  	pr->power.count = flat_state_cnt;
  	/* reset the index after flattening */
  	for (i = 0; i < pr->power.count; i++)
  		pr->power.lpi_states[i].index = i;
  
  	/* Tell driver that _LPI is supported. */
  	pr->flags.has_lpi = 1;
  	pr->flags.power = 1;
  
  	return 0;
  }
  
  int __weak acpi_processor_ffh_lpi_probe(unsigned int cpu)
  {
  	return -ENODEV;
  }
  
  int __weak acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi)
  {
  	return -ENODEV;
  }
  
  /**
   * acpi_idle_lpi_enter - enters an ACPI any LPI state
   * @dev: the target CPU
   * @drv: cpuidle driver containing cpuidle state info
   * @index: index of target state
   *
   * Return: 0 for success or negative value for error
   */
  static int acpi_idle_lpi_enter(struct cpuidle_device *dev,
  			       struct cpuidle_driver *drv, int index)
  {
  	struct acpi_processor *pr;
  	struct acpi_lpi_state *lpi;
  
  	pr = __this_cpu_read(processors);
  
  	if (unlikely(!pr))
  		return -EINVAL;
  
  	lpi = &pr->power.lpi_states[index];
  	if (lpi->entry_method == ACPI_CSTATE_FFH)
  		return acpi_processor_ffh_lpi_enter(lpi);
  
  	return -EINVAL;
  }
  
  static int acpi_processor_setup_lpi_states(struct acpi_processor *pr)
  {
  	int i;
  	struct acpi_lpi_state *lpi;
  	struct cpuidle_state *state;
  	struct cpuidle_driver *drv = &acpi_idle_driver;
  
  	if (!pr->flags.has_lpi)
  		return -EOPNOTSUPP;
  
  	for (i = 0; i < pr->power.count && i < CPUIDLE_STATE_MAX; i++) {
  		lpi = &pr->power.lpi_states[i];
  
  		state = &drv->states[i];
  		snprintf(state->name, CPUIDLE_NAME_LEN, "LPI-%d", i);
  		strlcpy(state->desc, lpi->desc, CPUIDLE_DESC_LEN);
  		state->exit_latency = lpi->wake_latency;
  		state->target_residency = lpi->min_residency;
  		if (lpi->arch_flags)
  			state->flags |= CPUIDLE_FLAG_TIMER_STOP;
  		state->enter = acpi_idle_lpi_enter;
  		drv->safe_state_index = i;
  	}
  
  	drv->state_count = i;
  
  	return 0;
  }
  
  /**
   * acpi_processor_setup_cpuidle_states- prepares and configures cpuidle
   * global state data i.e. idle routines
   *
   * @pr: the ACPI processor
   */
  static int acpi_processor_setup_cpuidle_states(struct acpi_processor *pr)
  {
  	int i;
  	struct cpuidle_driver *drv = &acpi_idle_driver;
  
  	if (!pr->flags.power_setup_done || !pr->flags.power)
  		return -EINVAL;
  
  	drv->safe_state_index = -1;
dc2251bf9   Rafael J. Wysocki   cpuidle: Eliminat...
1129
  	for (i = ACPI_IDLE_STATE_START; i < CPUIDLE_STATE_MAX; i++) {
a36a7fecf   Sudeep Holla   ACPI / processor_...
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
  		drv->states[i].name[0] = '\0';
  		drv->states[i].desc[0] = '\0';
  	}
  
  	if (pr->flags.has_lpi)
  		return acpi_processor_setup_lpi_states(pr);
  
  	return acpi_processor_setup_cstates(pr);
  }
  
  /**
   * acpi_processor_setup_cpuidle_dev - prepares and configures CPUIDLE
   * device i.e. per-cpu data
   *
   * @pr: the ACPI processor
   * @dev : the cpuidle device
   */
  static int acpi_processor_setup_cpuidle_dev(struct acpi_processor *pr,
  					    struct cpuidle_device *dev)
  {
  	if (!pr->flags.power_setup_done || !pr->flags.power || !dev)
  		return -EINVAL;
  
  	dev->cpu = pr->id;
  	if (pr->flags.has_lpi)
  		return acpi_processor_ffh_lpi_probe(pr->id);
  
  	return acpi_processor_setup_cpuidle_cx(pr, dev);
  }
  
  static int acpi_processor_get_power_info(struct acpi_processor *pr)
  {
  	int ret;
  
  	ret = acpi_processor_get_lpi_info(pr);
  	if (ret)
  		ret = acpi_processor_get_cstate_info(pr);
  
  	return ret;
  }
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
1170
  int acpi_processor_hotplug(struct acpi_processor *pr)
4f86d3a8e   Len Brown   cpuidle: consolid...
1171
  {
dcb84f335   Venkatesh Pallipadi   cpuidle acpi driv...
1172
  	int ret = 0;
e8b1b59dc   Wei Yongjun   cpuidle / ACPI: f...
1173
  	struct cpuidle_device *dev;
4f86d3a8e   Len Brown   cpuidle: consolid...
1174

d18960494   Thomas Renninger   ACPI, intel_idle:...
1175
  	if (disabled_by_idle_boot_param())
36a913586   Venkatesh Pallipadi   ACPI: Fix acpi_pr...
1176
  		return 0;
4f86d3a8e   Len Brown   cpuidle: consolid...
1177
1178
  	if (!pr->flags.power_setup_done)
  		return -ENODEV;
e8b1b59dc   Wei Yongjun   cpuidle / ACPI: f...
1179
  	dev = per_cpu(acpi_cpuidle_device, pr->id);
4f86d3a8e   Len Brown   cpuidle: consolid...
1180
  	cpuidle_pause_and_lock();
3d339dcbb   Daniel Lezcano   cpuidle / ACPI : ...
1181
  	cpuidle_disable_device(dev);
a36a7fecf   Sudeep Holla   ACPI / processor_...
1182
1183
1184
  	ret = acpi_processor_get_power_info(pr);
  	if (!ret && pr->flags.power) {
  		acpi_processor_setup_cpuidle_dev(pr, dev);
3d339dcbb   Daniel Lezcano   cpuidle / ACPI : ...
1185
  		ret = cpuidle_enable_device(dev);
dcb84f335   Venkatesh Pallipadi   cpuidle acpi driv...
1186
  	}
4f86d3a8e   Len Brown   cpuidle: consolid...
1187
1188
1189
1190
  	cpuidle_resume_and_unlock();
  
  	return ret;
  }
a36a7fecf   Sudeep Holla   ACPI / processor_...
1191
  int acpi_processor_power_state_has_changed(struct acpi_processor *pr)
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
1192
1193
1194
  {
  	int cpu;
  	struct acpi_processor *_pr;
3d339dcbb   Daniel Lezcano   cpuidle / ACPI : ...
1195
  	struct cpuidle_device *dev;
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
1196
1197
1198
  
  	if (disabled_by_idle_boot_param())
  		return 0;
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
1199
1200
1201
1202
1203
1204
1205
1206
  	if (!pr->flags.power_setup_done)
  		return -ENODEV;
  
  	/*
  	 * FIXME:  Design the ACPI notification to make it once per
  	 * system instead of once per-cpu.  This condition is a hack
  	 * to make the code that updates C-States be called once.
  	 */
9505626d7   Paul E. McKenney   ACPI: Fix unprote...
1207
  	if (pr->id == 0 && cpuidle_get_driver() == &acpi_idle_driver) {
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
1208

46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
1209
1210
  		/* Protect against cpu-hotplug */
  		get_online_cpus();
6726655df   Jiri Kosina   ACPI / cpuidle: f...
1211
  		cpuidle_pause_and_lock();
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
1212
1213
1214
1215
1216
1217
  
  		/* Disable all cpuidle devices */
  		for_each_online_cpu(cpu) {
  			_pr = per_cpu(processors, cpu);
  			if (!_pr || !_pr->flags.power_setup_done)
  				continue;
3d339dcbb   Daniel Lezcano   cpuidle / ACPI : ...
1218
1219
  			dev = per_cpu(acpi_cpuidle_device, cpu);
  			cpuidle_disable_device(dev);
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
1220
1221
1222
  		}
  
  		/* Populate Updated C-state information */
f427e5f1c   Thomas Schlichter   ACPI / processor:...
1223
  		acpi_processor_get_power_info(pr);
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
1224
1225
1226
1227
1228
1229
1230
1231
1232
  		acpi_processor_setup_cpuidle_states(pr);
  
  		/* Enable all cpuidle devices */
  		for_each_online_cpu(cpu) {
  			_pr = per_cpu(processors, cpu);
  			if (!_pr || !_pr->flags.power_setup_done)
  				continue;
  			acpi_processor_get_power_info(_pr);
  			if (_pr->flags.power) {
3d339dcbb   Daniel Lezcano   cpuidle / ACPI : ...
1233
  				dev = per_cpu(acpi_cpuidle_device, cpu);
a36a7fecf   Sudeep Holla   ACPI / processor_...
1234
  				acpi_processor_setup_cpuidle_dev(_pr, dev);
3d339dcbb   Daniel Lezcano   cpuidle / ACPI : ...
1235
  				cpuidle_enable_device(dev);
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
1236
1237
  			}
  		}
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
1238
  		cpuidle_resume_and_unlock();
6726655df   Jiri Kosina   ACPI / cpuidle: f...
1239
  		put_online_cpus();
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
1240
1241
1242
1243
1244
1245
  	}
  
  	return 0;
  }
  
  static int acpi_processor_registered;
fe7bf106e   Paul Gortmaker   acpi: delete __cp...
1246
  int acpi_processor_power_init(struct acpi_processor *pr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1247
  {
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
1248
  	int retval;
3d339dcbb   Daniel Lezcano   cpuidle / ACPI : ...
1249
  	struct cpuidle_device *dev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1250

d18960494   Thomas Renninger   ACPI, intel_idle:...
1251
  	if (disabled_by_idle_boot_param())
36a913586   Venkatesh Pallipadi   ACPI: Fix acpi_pr...
1252
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1253

35ae71335   Sudeep Holla   ACPI / processor_...
1254
  	acpi_processor_cstate_first_run_checks();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1255

35ae71335   Sudeep Holla   ACPI / processor_...
1256
1257
  	if (!acpi_processor_get_power_info(pr))
  		pr->flags.power_setup_done = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1258
1259
1260
1261
1262
1263
  
  	/*
  	 * Install the idle handler if processor power management is supported.
  	 * Note that we use previously set idle handler will be used on
  	 * platforms that only support C1.
  	 */
36a913586   Venkatesh Pallipadi   ACPI: Fix acpi_pr...
1264
  	if (pr->flags.power) {
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
1265
1266
1267
1268
1269
1270
  		/* Register acpi_idle_driver if not already registered */
  		if (!acpi_processor_registered) {
  			acpi_processor_setup_cpuidle_states(pr);
  			retval = cpuidle_register_driver(&acpi_idle_driver);
  			if (retval)
  				return retval;
b6ec26fb9   Sudeep Holla   ACPI / processor_...
1271
1272
1273
  			pr_debug("%s registered with cpuidle
  ",
  				 acpi_idle_driver.name);
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
1274
  		}
3d339dcbb   Daniel Lezcano   cpuidle / ACPI : ...
1275
1276
1277
1278
1279
  
  		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
  		if (!dev)
  			return -ENOMEM;
  		per_cpu(acpi_cpuidle_device, pr->id) = dev;
a36a7fecf   Sudeep Holla   ACPI / processor_...
1280
  		acpi_processor_setup_cpuidle_dev(pr, dev);
3d339dcbb   Daniel Lezcano   cpuidle / ACPI : ...
1281

46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
1282
1283
1284
  		/* Register per-cpu cpuidle_device. Cpuidle driver
  		 * must already be registered before registering device
  		 */
3d339dcbb   Daniel Lezcano   cpuidle / ACPI : ...
1285
  		retval = cpuidle_register_device(dev);
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
1286
1287
1288
1289
1290
1291
  		if (retval) {
  			if (acpi_processor_registered == 0)
  				cpuidle_unregister_driver(&acpi_idle_driver);
  			return retval;
  		}
  		acpi_processor_registered++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1292
  	}
d550d98d3   Patrick Mochel   ACPI: delete trac...
1293
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1294
  }
38a991b62   Daniel Lezcano   ACPI / processor:...
1295
  int acpi_processor_power_exit(struct acpi_processor *pr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1296
  {
3d339dcbb   Daniel Lezcano   cpuidle / ACPI : ...
1297
  	struct cpuidle_device *dev = per_cpu(acpi_cpuidle_device, pr->id);
d18960494   Thomas Renninger   ACPI, intel_idle:...
1298
  	if (disabled_by_idle_boot_param())
36a913586   Venkatesh Pallipadi   ACPI: Fix acpi_pr...
1299
  		return 0;
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
1300
  	if (pr->flags.power) {
3d339dcbb   Daniel Lezcano   cpuidle / ACPI : ...
1301
  		cpuidle_unregister_device(dev);
46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
1302
1303
1304
1305
  		acpi_processor_registered--;
  		if (acpi_processor_registered == 0)
  			cpuidle_unregister_driver(&acpi_idle_driver);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1306

46bcfad7a   Deepthi Dharwar   cpuidle: Single/G...
1307
  	pr->flags.power_setup_done = 0;
d550d98d3   Patrick Mochel   ACPI: delete trac...
1308
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1309
  }