Blame view

drivers/acpi/bus.c 33.1 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
  /*
   *  acpi_bus.c - ACPI Bus Driver ($Revision: 80 $)
   *
   *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6
7
8
9
10
   */
  
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/ioport.h>
d568df84f   Randy Dunlap   ACPI: handle firm...
11
  #include <linux/kernel.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
13
14
15
16
  #include <linux/list.h>
  #include <linux/sched.h>
  #include <linux/pm.h>
  #include <linux/device.h>
  #include <linux/proc_fs.h>
6697c0529   Harvey Harrison   x86: fix sparse w...
17
  #include <linux/acpi.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
18
  #include <linux/slab.h>
49a12877d   Mark Brown   ACPI / init: Flag...
19
  #include <linux/regulator/machine.h>
baa0c019b   Prakash, Prashanth   ACPI / bus: Suppo...
20
21
22
  #include <linux/workqueue.h>
  #include <linux/reboot.h>
  #include <linux/delay.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
24
  #ifdef CONFIG_X86
  #include <asm/mpspec.h>
5d128fbd8   Jean Delvare   ACPI / bus: Only ...
25
  #include <linux/dmi.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
  #endif
88ef16d88   Tomasz Nowicki   ACPI: I/O Remappi...
27
  #include <linux/acpi_iort.h>
7752d5cfe   Robert Hancock   x86: validate aga...
28
  #include <linux/pci.h>
eccddd32c   Huang Ying   ACPI, APEI, Add A...
29
  #include <acpi/apei.h>
cd51e61cf   Rafael J. Wysocki   PM / ACPI: Remove...
30
  #include <linux/suspend.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31

e60cc7a6f   Bjorn Helgaas   ACPI: move privat...
32
  #include "internal.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
  #define _COMPONENT		ACPI_BUS_COMPONENT
f52fd66d2   Len Brown   ACPI: clean up AC...
34
  ACPI_MODULE_NAME("bus");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35

4be44fcd3   Len Brown   [ACPI] Lindent al...
36
37
  struct acpi_device *acpi_root;
  struct proc_dir_entry *acpi_root_dir;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38
  EXPORT_SYMBOL(acpi_root_dir);
cce4f632d   Lin Ming   ACPI: fix early D...
39
  #ifdef CONFIG_X86
73577d1df   Lv Zheng   ACPI: Fix conflic...
40
41
42
43
44
45
  #ifdef CONFIG_ACPI_CUSTOM_DSDT
  static inline int set_copy_dsdt(const struct dmi_system_id *id)
  {
  	return 0;
  }
  #else
aa2110cb1   Lin Ming   ACPI: add boot op...
46
47
48
49
50
51
52
53
  static int set_copy_dsdt(const struct dmi_system_id *id)
  {
  	printk(KERN_NOTICE "%s detected - "
  		"force copy of DSDT to local memory
  ", id->ident);
  	acpi_gbl_copy_dsdt_locally = 1;
  	return 0;
  }
73577d1df   Lv Zheng   ACPI: Fix conflic...
54
  #endif
aa2110cb1   Lin Ming   ACPI: add boot op...
55

ae976358c   Kai Heng Feng   Revert "ACPI / bu...
56
  static const struct dmi_system_id dsdt_dmi_table[] __initconst = {
aa2110cb1   Lin Ming   ACPI: add boot op...
57
  	/*
100cf8778   Len Brown   ACPI: invoke DSDT...
58
  	 * Invoke DSDT corruption work-around on all Toshiba Satellite.
aa2110cb1   Lin Ming   ACPI: add boot op...
59
60
61
62
  	 * https://bugzilla.kernel.org/show_bug.cgi?id=14679
  	 */
  	{
  	 .callback = set_copy_dsdt,
100cf8778   Len Brown   ACPI: invoke DSDT...
63
  	 .ident = "TOSHIBA Satellite",
aa2110cb1   Lin Ming   ACPI: add boot op...
64
65
  	 .matches = {
  		DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
100cf8778   Len Brown   ACPI: invoke DSDT...
66
  		DMI_MATCH(DMI_PRODUCT_NAME, "Satellite"),
aa2110cb1   Lin Ming   ACPI: add boot op...
67
  		},
cce4f632d   Lin Ming   ACPI: fix early D...
68
69
  	},
  	{}
aa2110cb1   Lin Ming   ACPI: add boot op...
70
  };
cce4f632d   Lin Ming   ACPI: fix early D...
71
  #endif
aa2110cb1   Lin Ming   ACPI: add boot op...
72

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
74
75
  /* --------------------------------------------------------------------------
                                  Device Management
     -------------------------------------------------------------------------- */
402ac5361   Bjorn Helgaas   ACPI: add acpi_bu...
76
77
  acpi_status acpi_bus_get_status_handle(acpi_handle handle,
  				       unsigned long long *sta)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
78
  {
402ac5361   Bjorn Helgaas   ACPI: add acpi_bu...
79
  	acpi_status status;
4be44fcd3   Len Brown   [ACPI] Lindent al...
80

402ac5361   Bjorn Helgaas   ACPI: add acpi_bu...
81
82
83
  	status = acpi_evaluate_integer(handle, "_STA", NULL, sta);
  	if (ACPI_SUCCESS(status))
  		return AE_OK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84

402ac5361   Bjorn Helgaas   ACPI: add acpi_bu...
85
86
87
88
  	if (status == AE_NOT_FOUND) {
  		*sta = ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
  		       ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING;
  		return AE_OK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89
  	}
402ac5361   Bjorn Helgaas   ACPI: add acpi_bu...
90
91
  	return status;
  }
5a98231f5   Hans de Goede   ACPI: export acpi...
92
  EXPORT_SYMBOL_GPL(acpi_bus_get_status_handle);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93

402ac5361   Bjorn Helgaas   ACPI: add acpi_bu...
94
95
96
97
  int acpi_bus_get_status(struct acpi_device *device)
  {
  	acpi_status status;
  	unsigned long long sta;
b7ecf663c   Hans de Goede   ACPI / bus: Intro...
98
99
100
101
  	if (acpi_device_always_present(device)) {
  		acpi_set_device_status(device, ACPI_STA_DEFAULT);
  		return 0;
  	}
54ddce706   Hans de Goede   ACPI / bus: Do no...
102
103
104
105
106
  	/* Battery devices must have their deps met before calling _STA */
  	if (acpi_device_is_battery(device) && device->dep_unmet) {
  		acpi_set_device_status(device, 0);
  		return 0;
  	}
402ac5361   Bjorn Helgaas   ACPI: add acpi_bu...
107
108
109
  	status = acpi_bus_get_status_handle(device->handle, &sta);
  	if (ACPI_FAILURE(status))
  		return -ENODEV;
25db115b0   Rafael J. Wysocki   ACPI: Introduce a...
110
  	acpi_set_device_status(device, sta);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111
112
  
  	if (device->status.functional && !device->status.present) {
39a0ad871   Zhao Yakui   ACPI : Load devic...
113
114
115
  		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: "
  		       "functional but not present;
  ",
25db115b0   Rafael J. Wysocki   ACPI: Introduce a...
116
  			device->pnp.bus_id, (u32)sta));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
  	}
4be44fcd3   Len Brown   [ACPI] Lindent al...
118
119
  	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]
  ",
25db115b0   Rafael J. Wysocki   ACPI: Introduce a...
120
  			  device->pnp.bus_id, (u32)sta));
d550d98d3   Patrick Mochel   ACPI: delete trac...
121
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
122
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
123
  EXPORT_SYMBOL(acpi_bus_get_status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124

207339398   Zhang Rui   ACPI: attach ther...
125
  void acpi_bus_private_data_handler(acpi_handle handle,
8e4319c42   Bob Moore   ACPICA: Fix sever...
126
  				   void *context)
207339398   Zhang Rui   ACPI: attach ther...
127
128
129
130
  {
  	return;
  }
  EXPORT_SYMBOL(acpi_bus_private_data_handler);
72013795a   Lan Tianyu   ACPI: Add acpi_bu...
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
  int acpi_bus_attach_private_data(acpi_handle handle, void *data)
  {
  	acpi_status status;
  
  	status = acpi_attach_data(handle,
  			acpi_bus_private_data_handler, data);
  	if (ACPI_FAILURE(status)) {
  		acpi_handle_debug(handle, "Error attaching device data
  ");
  		return -ENODEV;
  	}
  
  	return 0;
  }
  EXPORT_SYMBOL_GPL(acpi_bus_attach_private_data);
207339398   Zhang Rui   ACPI: attach ther...
146
147
  int acpi_bus_get_private_data(acpi_handle handle, void **data)
  {
6a8c0af6e   Bjorn Helgaas   ACPI: Remove usel...
148
  	acpi_status status;
207339398   Zhang Rui   ACPI: attach ther...
149

f296f648e   Vamshi K Sthambamkadi   ACPI: bus: Fix NU...
150
  	if (!data)
207339398   Zhang Rui   ACPI: attach ther...
151
152
153
  		return -EINVAL;
  
  	status = acpi_get_data(handle, acpi_bus_private_data_handler, data);
72013795a   Lan Tianyu   ACPI: Add acpi_bu...
154
155
156
  	if (ACPI_FAILURE(status)) {
  		acpi_handle_debug(handle, "No context for object
  ");
207339398   Zhang Rui   ACPI: attach ther...
157
158
159
160
161
  		return -ENODEV;
  	}
  
  	return 0;
  }
72013795a   Lan Tianyu   ACPI: Add acpi_bu...
162
163
164
165
166
167
168
  EXPORT_SYMBOL_GPL(acpi_bus_get_private_data);
  
  void acpi_bus_detach_private_data(acpi_handle handle)
  {
  	acpi_detach_data(handle, acpi_bus_private_data_handler);
  }
  EXPORT_SYMBOL_GPL(acpi_bus_detach_private_data);
207339398   Zhang Rui   ACPI: attach ther...
169

70023de88   Shaohua Li   ACPI: Add a gener...
170
  static void acpi_print_osc_error(acpi_handle handle,
f26f5c8b8   Rafael J. Wysocki   ACPI / bus: Use a...
171
  				 struct acpi_osc_context *context, char *error)
70023de88   Shaohua Li   ACPI: Add a gener...
172
  {
70023de88   Shaohua Li   ACPI: Add a gener...
173
  	int i;
f26f5c8b8   Rafael J. Wysocki   ACPI / bus: Use a...
174
175
176
177
  	acpi_handle_debug(handle, "(%s): %s
  ", context->uuid_str, error);
  
  	pr_debug("_OSC request data:");
70023de88   Shaohua Li   ACPI: Add a gener...
178
  	for (i = 0; i < context->cap.length; i += sizeof(u32))
f26f5c8b8   Rafael J. Wysocki   ACPI / bus: Use a...
179
180
181
182
  		pr_debug(" %x", *((u32 *)(context->cap.pointer + i)));
  
  	pr_debug("
  ");
70023de88   Shaohua Li   ACPI: Add a gener...
183
  }
70023de88   Shaohua Li   ACPI: Add a gener...
184
185
186
187
188
189
  acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context)
  {
  	acpi_status status;
  	struct acpi_object_list input;
  	union acpi_object in_params[4];
  	union acpi_object *out_obj;
dfcaad8fa   Andy Shevchenko   ACPI / bus: Switc...
190
  	guid_t guid;
70023de88   Shaohua Li   ACPI: Add a gener...
191
  	u32 errors;
9dc130fcc   Shaohua Li   ACPI: fix OSC reg...
192
  	struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
70023de88   Shaohua Li   ACPI: Add a gener...
193
194
195
  
  	if (!context)
  		return AE_ERROR;
dfcaad8fa   Andy Shevchenko   ACPI / bus: Switc...
196
  	if (guid_parse(context->uuid_str, &guid))
70023de88   Shaohua Li   ACPI: Add a gener...
197
198
199
200
201
202
203
204
205
  		return AE_ERROR;
  	context->ret.length = ACPI_ALLOCATE_BUFFER;
  	context->ret.pointer = NULL;
  
  	/* Setting up input parameters */
  	input.count = 4;
  	input.pointer = in_params;
  	in_params[0].type 		= ACPI_TYPE_BUFFER;
  	in_params[0].buffer.length 	= 16;
dfcaad8fa   Andy Shevchenko   ACPI / bus: Switc...
206
  	in_params[0].buffer.pointer	= (u8 *)&guid;
70023de88   Shaohua Li   ACPI: Add a gener...
207
208
209
210
211
212
213
  	in_params[1].type 		= ACPI_TYPE_INTEGER;
  	in_params[1].integer.value 	= context->rev;
  	in_params[2].type 		= ACPI_TYPE_INTEGER;
  	in_params[2].integer.value	= context->cap.length/sizeof(u32);
  	in_params[3].type		= ACPI_TYPE_BUFFER;
  	in_params[3].buffer.length 	= context->cap.length;
  	in_params[3].buffer.pointer 	= context->cap.pointer;
9dc130fcc   Shaohua Li   ACPI: fix OSC reg...
214
  	status = acpi_evaluate_object(handle, "_OSC", &input, &output);
70023de88   Shaohua Li   ACPI: Add a gener...
215
216
  	if (ACPI_FAILURE(status))
  		return status;
9dc130fcc   Shaohua Li   ACPI: fix OSC reg...
217
  	if (!output.length)
70023de88   Shaohua Li   ACPI: Add a gener...
218
  		return AE_NULL_OBJECT;
9dc130fcc   Shaohua Li   ACPI: fix OSC reg...
219
220
221
  	out_obj = output.pointer;
  	if (out_obj->type != ACPI_TYPE_BUFFER
  		|| out_obj->buffer.length != context->cap.length) {
70023de88   Shaohua Li   ACPI: Add a gener...
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
  		acpi_print_osc_error(handle, context,
  			"_OSC evaluation returned wrong type");
  		status = AE_TYPE;
  		goto out_kfree;
  	}
  	/* Need to ignore the bit0 in result code */
  	errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
  	if (errors) {
  		if (errors & OSC_REQUEST_ERROR)
  			acpi_print_osc_error(handle, context,
  				"_OSC request failed");
  		if (errors & OSC_INVALID_UUID_ERROR)
  			acpi_print_osc_error(handle, context,
  				"_OSC invalid UUID");
  		if (errors & OSC_INVALID_REVISION_ERROR)
  			acpi_print_osc_error(handle, context,
  				"_OSC invalid revision");
  		if (errors & OSC_CAPABILITIES_MASK_ERROR) {
b938a229c   Bjorn Helgaas   ACPI: Rename OSC_...
240
  			if (((u32 *)context->cap.pointer)[OSC_QUERY_DWORD]
70023de88   Shaohua Li   ACPI: Add a gener...
241
242
243
244
245
246
247
248
249
  			    & OSC_QUERY_ENABLE)
  				goto out_success;
  			status = AE_SUPPORT;
  			goto out_kfree;
  		}
  		status = AE_ERROR;
  		goto out_kfree;
  	}
  out_success:
9dc130fcc   Shaohua Li   ACPI: fix OSC reg...
250
  	context->ret.length = out_obj->buffer.length;
e2cb5f084   Andrei Epure   ACPI: replace kma...
251
252
  	context->ret.pointer = kmemdup(out_obj->buffer.pointer,
  				       context->ret.length, GFP_KERNEL);
9dc130fcc   Shaohua Li   ACPI: fix OSC reg...
253
254
255
256
  	if (!context->ret.pointer) {
  		status =  AE_NO_MEMORY;
  		goto out_kfree;
  	}
9dc130fcc   Shaohua Li   ACPI: fix OSC reg...
257
  	status =  AE_OK;
70023de88   Shaohua Li   ACPI: Add a gener...
258
259
  
  out_kfree:
9dc130fcc   Shaohua Li   ACPI: fix OSC reg...
260
261
262
  	kfree(output.pointer);
  	if (status != AE_OK)
  		context->ret.pointer = NULL;
70023de88   Shaohua Li   ACPI: Add a gener...
263
264
265
  	return status;
  }
  EXPORT_SYMBOL(acpi_run_osc);
eccddd32c   Huang Ying   ACPI, APEI, Add A...
266
  bool osc_sb_apei_support_acked;
a36a7fecf   Sudeep Holla   ACPI / processor_...
267
268
269
270
271
272
273
  
  /*
   * ACPI 6.0 Section 8.4.4.2 Idle State Coordination
   * OSPM supports platform coordinated low power idle(LPI) states
   */
  bool osc_pc_lpi_support_confirmed;
  EXPORT_SYMBOL_GPL(osc_pc_lpi_support_confirmed);
3563ff964   Shaohua Li   ACPI: Add platfor...
274
275
276
277
278
279
280
281
282
283
284
  static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48";
  static void acpi_bus_osc_support(void)
  {
  	u32 capbuf[2];
  	struct acpi_osc_context context = {
  		.uuid_str = sb_uuid_str,
  		.rev = 1,
  		.cap.length = 8,
  		.cap.pointer = capbuf,
  	};
  	acpi_handle handle;
b938a229c   Bjorn Helgaas   ACPI: Rename OSC_...
285
286
  	capbuf[OSC_QUERY_DWORD] = OSC_QUERY_ENABLE;
  	capbuf[OSC_SUPPORT_DWORD] = OSC_SB_PR3_SUPPORT; /* _PR3 is in use */
bcb2b0b2b   Sudeep Holla   ACPI: Eliminate C...
287
288
289
290
  	if (IS_ENABLED(CONFIG_ACPI_PROCESSOR_AGGREGATOR))
  		capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PAD_SUPPORT;
  	if (IS_ENABLED(CONFIG_ACPI_PROCESSOR))
  		capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PPC_OST_SUPPORT;
eccddd32c   Huang Ying   ACPI, APEI, Add A...
291

b938a229c   Bjorn Helgaas   ACPI: Rename OSC_...
292
  	capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_HOTPLUG_OST_SUPPORT;
a36a7fecf   Sudeep Holla   ACPI / processor_...
293
  	capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PCLPI_SUPPORT;
c2f4191a9   Toshi Kani   ACPI: Set hotplug...
294

5c2832e91   Srinivas Pandruvada   acpi/bus: Enable ...
295
296
297
298
299
300
  #ifdef CONFIG_X86
  	if (boot_cpu_has(X86_FEATURE_HWP)) {
  		capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_SUPPORT;
  		capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPCV2_SUPPORT;
  	}
  #endif
de966cf4a   Tim Chen   sched/x86: Change...
301
  	if (IS_ENABLED(CONFIG_SCHED_MC_PRIO))
8b533a0ee   Srinivas Pandruvada   acpi/bus: Set _OS...
302
  		capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_DIVERSE_HIGH_SUPPORT;
eccddd32c   Huang Ying   ACPI, APEI, Add A...
303
  	if (!ghes_disable)
b938a229c   Bjorn Helgaas   ACPI: Rename OSC_...
304
  		capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_APEI_SUPPORT;
3563ff964   Shaohua Li   ACPI: Add platfor...
305
306
  	if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)))
  		return;
eccddd32c   Huang Ying   ACPI, APEI, Add A...
307
308
  	if (ACPI_SUCCESS(acpi_run_osc(handle, &context))) {
  		u32 *capbuf_ret = context.ret.pointer;
a36a7fecf   Sudeep Holla   ACPI / processor_...
309
  		if (context.ret.length > OSC_SUPPORT_DWORD) {
eccddd32c   Huang Ying   ACPI, APEI, Add A...
310
  			osc_sb_apei_support_acked =
b938a229c   Bjorn Helgaas   ACPI: Rename OSC_...
311
  				capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_APEI_SUPPORT;
a36a7fecf   Sudeep Holla   ACPI / processor_...
312
313
314
  			osc_pc_lpi_support_confirmed =
  				capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_PCLPI_SUPPORT;
  		}
3563ff964   Shaohua Li   ACPI: Add platfor...
315
  		kfree(context.ret.pointer);
eccddd32c   Huang Ying   ACPI, APEI, Add A...
316
317
  	}
  	/* do we need to check other returned cap? Sounds no */
3563ff964   Shaohua Li   ACPI: Add platfor...
318
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
319
  /* --------------------------------------------------------------------------
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320
321
                               Notification Handling
     -------------------------------------------------------------------------- */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322
323
324
325
326
  /**
   * acpi_bus_notify
   * ---------------
   * Callback for all 'system-level' device notifications (values 0x00-0x7F).
   */
4be44fcd3   Len Brown   [ACPI] Lindent al...
327
  static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
328
  {
1a699476e   Rafael J. Wysocki   ACPI / hotplug / ...
329
  	struct acpi_device *adev;
6d2781310   Bjorn Helgaas   ACPI: allow drive...
330
  	struct acpi_driver *driver;
1a699476e   Rafael J. Wysocki   ACPI / hotplug / ...
331
  	u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE;
d0103387b   Rafael J. Wysocki   ACPI / notify: Cl...
332
  	bool hotplug_event = false;
02c37bd8d   Bjorn Helgaas   ACPI: simplify no...
333

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
334
  	switch (type) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
335
  	case ACPI_NOTIFY_BUS_CHECK:
1a699476e   Rafael J. Wysocki   ACPI / hotplug / ...
336
337
  		acpi_handle_debug(handle, "ACPI_NOTIFY_BUS_CHECK event
  ");
d0103387b   Rafael J. Wysocki   ACPI / notify: Cl...
338
  		hotplug_event = true;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
339
340
341
  		break;
  
  	case ACPI_NOTIFY_DEVICE_CHECK:
1a699476e   Rafael J. Wysocki   ACPI / hotplug / ...
342
343
  		acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK event
  ");
d0103387b   Rafael J. Wysocki   ACPI / notify: Cl...
344
  		hotplug_event = true;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
345
346
347
  		break;
  
  	case ACPI_NOTIFY_DEVICE_WAKE:
1a699476e   Rafael J. Wysocki   ACPI / hotplug / ...
348
349
  		acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_WAKE event
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
350
351
352
  		break;
  
  	case ACPI_NOTIFY_EJECT_REQUEST:
1a699476e   Rafael J. Wysocki   ACPI / hotplug / ...
353
354
  		acpi_handle_debug(handle, "ACPI_NOTIFY_EJECT_REQUEST event
  ");
d0103387b   Rafael J. Wysocki   ACPI / notify: Cl...
355
  		hotplug_event = true;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
356
357
358
  		break;
  
  	case ACPI_NOTIFY_DEVICE_CHECK_LIGHT:
1a699476e   Rafael J. Wysocki   ACPI / hotplug / ...
359
360
  		acpi_handle_debug(handle, "ACPI_NOTIFY_DEVICE_CHECK_LIGHT event
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
361
362
363
364
  		/* TBD: Exactly what does 'light' mean? */
  		break;
  
  	case ACPI_NOTIFY_FREQUENCY_MISMATCH:
1a699476e   Rafael J. Wysocki   ACPI / hotplug / ...
365
366
367
  		acpi_handle_err(handle, "Device cannot be configured due "
  				"to a frequency mismatch
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
368
369
370
  		break;
  
  	case ACPI_NOTIFY_BUS_MODE_MISMATCH:
1a699476e   Rafael J. Wysocki   ACPI / hotplug / ...
371
372
373
  		acpi_handle_err(handle, "Device cannot be configured due "
  				"to a bus mode mismatch
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
374
375
376
  		break;
  
  	case ACPI_NOTIFY_POWER_FAULT:
1a699476e   Rafael J. Wysocki   ACPI / hotplug / ...
377
378
  		acpi_handle_err(handle, "Device has suffered a power fault
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
379
380
381
  		break;
  
  	default:
f66abe92c   Rafael J. Wysocki   ACPI / notify: Do...
382
383
384
  		acpi_handle_debug(handle, "Unknown event type 0x%x
  ", type);
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
385
  	}
1a699476e   Rafael J. Wysocki   ACPI / hotplug / ...
386
387
388
  	adev = acpi_bus_get_acpi_device(handle);
  	if (!adev)
  		goto err;
78ea4639a   Rafael J. Wysocki   ACPI / hotplug: F...
389

1a699476e   Rafael J. Wysocki   ACPI / hotplug / ...
390
391
392
393
  	driver = adev->driver;
  	if (driver && driver->ops.notify &&
  	    (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS))
  		driver->ops.notify(adev, type);
9a4d8d60d   Lee, Chun-Yi   ACPI / bus: handl...
394
395
396
397
398
399
  	if (!hotplug_event) {
  		acpi_bus_put_acpi_device(adev);
  		return;
  	}
  
  	if (ACPI_SUCCESS(acpi_hotplug_schedule(adev, type)))
d0103387b   Rafael J. Wysocki   ACPI / notify: Cl...
400
  		return;
1a699476e   Rafael J. Wysocki   ACPI / hotplug / ...
401
  	acpi_bus_put_acpi_device(adev);
1a699476e   Rafael J. Wysocki   ACPI / hotplug / ...
402
403
  
   err:
700b8422f   Rafael J. Wysocki   ACPI: Drop acpi_e...
404
  	acpi_evaluate_ost(handle, type, ost_code, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
405
  }
5894b0c46   Rafael J. Wysocki   ACPI / scan: Move...
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
  static void acpi_device_notify(acpi_handle handle, u32 event, void *data)
  {
  	struct acpi_device *device = data;
  
  	device->driver->ops.notify(device, event);
  }
  
  static void acpi_device_notify_fixed(void *data)
  {
  	struct acpi_device *device = data;
  
  	/* Fixed hardware devices have no handles */
  	acpi_device_notify(NULL, ACPI_FIXED_HARDWARE_EVENT, device);
  }
  
  static u32 acpi_device_fixed_event(void *data)
  {
  	acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_device_notify_fixed, data);
  	return ACPI_INTERRUPT_HANDLED;
  }
  
  static int acpi_device_install_notify_handler(struct acpi_device *device)
  {
  	acpi_status status;
  
  	if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON)
  		status =
  		    acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
  						     acpi_device_fixed_event,
  						     device);
  	else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON)
  		status =
  		    acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
  						     acpi_device_fixed_event,
  						     device);
  	else
  		status = acpi_install_notify_handler(device->handle,
  						     ACPI_DEVICE_NOTIFY,
  						     acpi_device_notify,
  						     device);
  
  	if (ACPI_FAILURE(status))
  		return -EINVAL;
  	return 0;
  }
  
  static void acpi_device_remove_notify_handler(struct acpi_device *device)
  {
  	if (device->device_type == ACPI_BUS_TYPE_POWER_BUTTON)
  		acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
  						acpi_device_fixed_event);
  	else if (device->device_type == ACPI_BUS_TYPE_SLEEP_BUTTON)
  		acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
  						acpi_device_fixed_event);
  	else
  		acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
  					   acpi_device_notify);
  }
baa0c019b   Prakash, Prashanth   ACPI / bus: Suppo...
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
  /* Handle events targeting \_SB device (at present only graceful shutdown) */
  
  #define ACPI_SB_NOTIFY_SHUTDOWN_REQUEST 0x81
  #define ACPI_SB_INDICATE_INTERVAL	10000
  
  static void sb_notify_work(struct work_struct *dummy)
  {
  	acpi_handle sb_handle;
  
  	orderly_poweroff(true);
  
  	/*
  	 * After initiating graceful shutdown, the ACPI spec requires OSPM
  	 * to evaluate _OST method once every 10seconds to indicate that
  	 * the shutdown is in progress
  	 */
  	acpi_get_handle(NULL, "\\_SB", &sb_handle);
  	while (1) {
  		pr_info("Graceful shutdown in progress.
  ");
  		acpi_evaluate_ost(sb_handle, ACPI_OST_EC_OSPM_SHUTDOWN,
  				ACPI_OST_SC_OS_SHUTDOWN_IN_PROGRESS, NULL);
  		msleep(ACPI_SB_INDICATE_INTERVAL);
  	}
  }
  
  static void acpi_sb_notify(acpi_handle handle, u32 event, void *data)
  {
  	static DECLARE_WORK(acpi_sb_work, sb_notify_work);
  
  	if (event == ACPI_SB_NOTIFY_SHUTDOWN_REQUEST) {
  		if (!work_busy(&acpi_sb_work))
  			schedule_work(&acpi_sb_work);
  	} else
  		pr_warn("event %x is not supported by \\_SB device
  ", event);
  }
  
  static int __init acpi_setup_sb_notify_handler(void)
  {
  	acpi_handle sb_handle;
  
  	if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &sb_handle)))
  		return -ENXIO;
  
  	if (ACPI_FAILURE(acpi_install_notify_handler(sb_handle, ACPI_DEVICE_NOTIFY,
  						acpi_sb_notify, NULL)))
  		return -EINVAL;
  
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
515
  /* --------------------------------------------------------------------------
68c6b148d   Rafael J. Wysocki   ACPI / scan: Move...
516
517
                               Device Matching
     -------------------------------------------------------------------------- */
3b95bd160   Aleksey Makarov   ACPI: introduce a...
518
519
520
521
522
523
524
  /**
   * acpi_get_first_physical_node - Get first physical node of an ACPI device
   * @adev:	ACPI device in question
   *
   * Return: First physical node of ACPI device @adev
   */
  struct device *acpi_get_first_physical_node(struct acpi_device *adev)
e91a398c3   Rafael J. Wysocki   ACPI / bus: Move ...
525
526
  {
  	struct mutex *physical_node_lock = &adev->physical_node_lock;
3b95bd160   Aleksey Makarov   ACPI: introduce a...
527
  	struct device *phys_dev;
e91a398c3   Rafael J. Wysocki   ACPI / bus: Move ...
528
529
530
  
  	mutex_lock(physical_node_lock);
  	if (list_empty(&adev->physical_node_list)) {
3b95bd160   Aleksey Makarov   ACPI: introduce a...
531
  		phys_dev = NULL;
e91a398c3   Rafael J. Wysocki   ACPI / bus: Move ...
532
533
534
535
536
  	} else {
  		const struct acpi_device_physical_node *node;
  
  		node = list_first_entry(&adev->physical_node_list,
  					struct acpi_device_physical_node, node);
3b95bd160   Aleksey Makarov   ACPI: introduce a...
537
538
  
  		phys_dev = node->dev;
e91a398c3   Rafael J. Wysocki   ACPI / bus: Move ...
539
540
  	}
  	mutex_unlock(physical_node_lock);
3b95bd160   Aleksey Makarov   ACPI: introduce a...
541
542
543
544
545
546
547
548
549
  	return phys_dev;
  }
  
  static struct acpi_device *acpi_primary_dev_companion(struct acpi_device *adev,
  						      const struct device *dev)
  {
  	const struct device *phys_dev = acpi_get_first_physical_node(adev);
  
  	return phys_dev && phys_dev == dev ? adev : NULL;
e91a398c3   Rafael J. Wysocki   ACPI / bus: Move ...
550
  }
3431e490b   Rafael J. Wysocki   Merge branch 'acp...
551
552
553
554
555
556
557
558
559
560
561
562
563
564
  /**
   * acpi_device_is_first_physical_node - Is given dev first physical node
   * @adev: ACPI companion device
   * @dev: Physical device to check
   *
   * Function checks if given @dev is the first physical devices attached to
   * the ACPI companion device. This distinction is needed in some cases
   * where the same companion device is shared between many physical devices.
   *
   * Note that the caller have to provide valid @adev pointer.
   */
  bool acpi_device_is_first_physical_node(struct acpi_device *adev,
  					const struct device *dev)
  {
e91a398c3   Rafael J. Wysocki   ACPI / bus: Move ...
565
  	return !!acpi_primary_dev_companion(adev, dev);
3431e490b   Rafael J. Wysocki   Merge branch 'acp...
566
  }
68c6b148d   Rafael J. Wysocki   ACPI / scan: Move...
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
  /*
   * acpi_companion_match() - Can we match via ACPI companion device
   * @dev: Device in question
   *
   * Check if the given device has an ACPI companion and if that companion has
   * a valid list of PNP IDs, and if the device is the first (primary) physical
   * device associated with it.  Return the companion pointer if that's the case
   * or NULL otherwise.
   *
   * If multiple physical devices are attached to a single ACPI companion, we need
   * to be careful.  The usage scenario for this kind of relationship is that all
   * of the physical devices in question use resources provided by the ACPI
   * companion.  A typical case is an MFD device where all the sub-devices share
   * the parent's ACPI companion.  In such cases we can only allow the primary
   * (first) physical device to be matched with the help of the companion's PNP
   * IDs.
   *
   * Additional physical devices sharing the ACPI companion can still use
   * resources available from it but they will be matched normally using functions
   * provided by their bus types (and analogously for their modalias).
   */
  struct acpi_device *acpi_companion_match(const struct device *dev)
  {
  	struct acpi_device *adev;
68c6b148d   Rafael J. Wysocki   ACPI / scan: Move...
591
592
593
594
595
596
597
  
  	adev = ACPI_COMPANION(dev);
  	if (!adev)
  		return NULL;
  
  	if (list_empty(&adev->pnp.ids))
  		return NULL;
e91a398c3   Rafael J. Wysocki   ACPI / bus: Move ...
598
  	return acpi_primary_dev_companion(adev, dev);
68c6b148d   Rafael J. Wysocki   ACPI / scan: Move...
599
600
601
602
603
604
  }
  
  /**
   * acpi_of_match_device - Match device object using the "compatible" property.
   * @adev: ACPI device object to match.
   * @of_match_table: List of device IDs to match against.
4222f38ca   Andy Shevchenko   ACPI / bus: Do no...
605
   * @of_id: OF ID if matched
68c6b148d   Rafael J. Wysocki   ACPI / scan: Move...
606
607
608
609
610
611
   *
   * If @dev has an ACPI companion which has ACPI_DT_NAMESPACE_HID in its list of
   * identifiers and a _DSD object with the "compatible" property, use that
   * property to match against the given list of identifiers.
   */
  static bool acpi_of_match_device(struct acpi_device *adev,
4222f38ca   Andy Shevchenko   ACPI / bus: Do no...
612
613
  				 const struct of_device_id *of_match_table,
  				 const struct of_device_id **of_id)
68c6b148d   Rafael J. Wysocki   ACPI / scan: Move...
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
  {
  	const union acpi_object *of_compatible, *obj;
  	int i, nval;
  
  	if (!adev)
  		return false;
  
  	of_compatible = adev->data.of_compatible;
  	if (!of_match_table || !of_compatible)
  		return false;
  
  	if (of_compatible->type == ACPI_TYPE_PACKAGE) {
  		nval = of_compatible->package.count;
  		obj = of_compatible->package.elements;
  	} else { /* Must be ACPI_TYPE_STRING. */
  		nval = 1;
  		obj = of_compatible;
  	}
  	/* Now we can look for the driver DT compatible strings */
  	for (i = 0; i < nval; i++, obj++) {
  		const struct of_device_id *id;
  
  		for (id = of_match_table; id->compatible[0]; id++)
4222f38ca   Andy Shevchenko   ACPI / bus: Do no...
637
638
639
  			if (!strcasecmp(obj->string.pointer, id->compatible)) {
  				if (of_id)
  					*of_id = id;
68c6b148d   Rafael J. Wysocki   ACPI / scan: Move...
640
  				return true;
4222f38ca   Andy Shevchenko   ACPI / bus: Do no...
641
  			}
68c6b148d   Rafael J. Wysocki   ACPI / scan: Move...
642
643
644
645
  	}
  
  	return false;
  }
51ede5d96   Dan O'Donovan   ACPI / bus: Intro...
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
  static bool acpi_of_modalias(struct acpi_device *adev,
  			     char *modalias, size_t len)
  {
  	const union acpi_object *of_compatible;
  	const union acpi_object *obj;
  	const char *str, *chr;
  
  	of_compatible = adev->data.of_compatible;
  	if (!of_compatible)
  		return false;
  
  	if (of_compatible->type == ACPI_TYPE_PACKAGE)
  		obj = of_compatible->package.elements;
  	else /* Must be ACPI_TYPE_STRING. */
  		obj = of_compatible;
  
  	str = obj->string.pointer;
  	chr = strchr(str, ',');
  	strlcpy(modalias, chr ? chr + 1 : str, len);
  
  	return true;
  }
  
  /**
   * acpi_set_modalias - Set modalias using "compatible" property or supplied ID
   * @adev:	ACPI device object to match
   * @default_id:	ID string to use as default if no compatible string found
   * @modalias:   Pointer to buffer that modalias value will be copied into
   * @len:	Length of modalias buffer
   *
   * This is a counterpart of of_modalias_node() for struct acpi_device objects.
   * If there is a compatible string for @adev, it will be copied to @modalias
   * with the vendor prefix stripped; otherwise, @default_id will be used.
   */
  void acpi_set_modalias(struct acpi_device *adev, const char *default_id,
  		       char *modalias, size_t len)
  {
  	if (!acpi_of_modalias(adev, modalias, len))
  		strlcpy(modalias, default_id, len);
  }
  EXPORT_SYMBOL_GPL(acpi_set_modalias);
68c6b148d   Rafael J. Wysocki   ACPI / scan: Move...
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
  static bool __acpi_match_device_cls(const struct acpi_device_id *id,
  				    struct acpi_hardware_id *hwid)
  {
  	int i, msk, byte_shift;
  	char buf[3];
  
  	if (!id->cls)
  		return false;
  
  	/* Apply class-code bitmask, before checking each class-code byte */
  	for (i = 1; i <= 3; i++) {
  		byte_shift = 8 * (3 - i);
  		msk = (id->cls_msk >> byte_shift) & 0xFF;
  		if (!msk)
  			continue;
  
  		sprintf(buf, "%02x", (id->cls >> byte_shift) & msk);
  		if (strncmp(buf, &hwid->id[(i - 1) * 2], 2))
  			return false;
  	}
  	return true;
  }
4222f38ca   Andy Shevchenko   ACPI / bus: Do no...
709
710
711
712
713
  static bool __acpi_match_device(struct acpi_device *device,
  				const struct acpi_device_id *acpi_ids,
  				const struct of_device_id *of_ids,
  				const struct acpi_device_id **acpi_id,
  				const struct of_device_id **of_id)
68c6b148d   Rafael J. Wysocki   ACPI / scan: Move...
714
715
716
717
718
719
720
721
722
  {
  	const struct acpi_device_id *id;
  	struct acpi_hardware_id *hwid;
  
  	/*
  	 * If the device is not present, it is unnecessary to load device
  	 * driver for it.
  	 */
  	if (!device || !device->status.present)
4222f38ca   Andy Shevchenko   ACPI / bus: Do no...
723
  		return false;
68c6b148d   Rafael J. Wysocki   ACPI / scan: Move...
724
725
726
  
  	list_for_each_entry(hwid, &device->pnp.ids, list) {
  		/* First, check the ACPI/PNP IDs provided by the caller. */
4222f38ca   Andy Shevchenko   ACPI / bus: Do no...
727
728
729
730
731
732
733
  		if (acpi_ids) {
  			for (id = acpi_ids; id->id[0] || id->cls; id++) {
  				if (id->id[0] && !strcmp((char *)id->id, hwid->id))
  					goto out_acpi_match;
  				if (id->cls && __acpi_match_device_cls(id, hwid))
  					goto out_acpi_match;
  			}
68c6b148d   Rafael J. Wysocki   ACPI / scan: Move...
734
735
736
737
738
  		}
  
  		/*
  		 * Next, check ACPI_DT_NAMESPACE_HID and try to match the
  		 * "compatible" property if found.
68c6b148d   Rafael J. Wysocki   ACPI / scan: Move...
739
  		 */
4222f38ca   Andy Shevchenko   ACPI / bus: Do no...
740
741
  		if (!strcmp(ACPI_DT_NAMESPACE_HID, hwid->id))
  			return acpi_of_match_device(device, of_ids, of_id);
68c6b148d   Rafael J. Wysocki   ACPI / scan: Move...
742
  	}
4222f38ca   Andy Shevchenko   ACPI / bus: Do no...
743
744
745
746
747
748
  	return false;
  
  out_acpi_match:
  	if (acpi_id)
  		*acpi_id = id;
  	return true;
68c6b148d   Rafael J. Wysocki   ACPI / scan: Move...
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
  }
  
  /**
   * acpi_match_device - Match a struct device against a given list of ACPI IDs
   * @ids: Array of struct acpi_device_id object to match against.
   * @dev: The device structure to match.
   *
   * Check if @dev has a valid ACPI handle and if there is a struct acpi_device
   * object for that handle and use that object to match against a given list of
   * device IDs.
   *
   * Return a pointer to the first matching ID on success or %NULL on failure.
   */
  const struct acpi_device_id *acpi_match_device(const struct acpi_device_id *ids,
  					       const struct device *dev)
  {
4222f38ca   Andy Shevchenko   ACPI / bus: Do no...
765
766
767
768
  	const struct acpi_device_id *id = NULL;
  
  	__acpi_match_device(acpi_companion_match(dev), ids, NULL, &id, NULL);
  	return id;
68c6b148d   Rafael J. Wysocki   ACPI / scan: Move...
769
770
  }
  EXPORT_SYMBOL_GPL(acpi_match_device);
886ca88be   Andy Shevchenko   ACPI / bus: Respe...
771
772
773
774
775
776
777
778
779
780
  static const void *acpi_of_device_get_match_data(const struct device *dev)
  {
  	struct acpi_device *adev = ACPI_COMPANION(dev);
  	const struct of_device_id *match = NULL;
  
  	if (!acpi_of_match_device(adev, dev->driver->of_match_table, &match))
  		return NULL;
  
  	return match->data;
  }
67dcc26d2   Andy Shevchenko   device property: ...
781
  const void *acpi_device_get_match_data(const struct device *dev)
80212a162   Sinan Kaya   ACPI / bus: Intro...
782
783
  {
  	const struct acpi_device_id *match;
886ca88be   Andy Shevchenko   ACPI / bus: Respe...
784
785
  	if (!dev->driver->acpi_match_table)
  		return acpi_of_device_get_match_data(dev);
80212a162   Sinan Kaya   ACPI / bus: Intro...
786
787
788
  	match = acpi_match_device(dev->driver->acpi_match_table, dev);
  	if (!match)
  		return NULL;
67dcc26d2   Andy Shevchenko   device property: ...
789
  	return (const void *)match->driver_data;
80212a162   Sinan Kaya   ACPI / bus: Intro...
790
  }
29d5325a1   Andy Shevchenko   ACPI / bus: Renam...
791
  EXPORT_SYMBOL_GPL(acpi_device_get_match_data);
80212a162   Sinan Kaya   ACPI / bus: Intro...
792

68c6b148d   Rafael J. Wysocki   ACPI / scan: Move...
793
794
795
  int acpi_match_device_ids(struct acpi_device *device,
  			  const struct acpi_device_id *ids)
  {
4222f38ca   Andy Shevchenko   ACPI / bus: Do no...
796
  	return __acpi_match_device(device, ids, NULL, NULL, NULL) ? 0 : -ENOENT;
68c6b148d   Rafael J. Wysocki   ACPI / scan: Move...
797
798
799
800
801
802
803
804
  }
  EXPORT_SYMBOL(acpi_match_device_ids);
  
  bool acpi_driver_match_device(struct device *dev,
  			      const struct device_driver *drv)
  {
  	if (!drv->acpi_match_table)
  		return acpi_of_match_device(ACPI_COMPANION(dev),
4222f38ca   Andy Shevchenko   ACPI / bus: Do no...
805
806
  					    drv->of_match_table,
  					    NULL);
68c6b148d   Rafael J. Wysocki   ACPI / scan: Move...
807

4222f38ca   Andy Shevchenko   ACPI / bus: Do no...
808
809
810
  	return __acpi_match_device(acpi_companion_match(dev),
  				   drv->acpi_match_table, drv->of_match_table,
  				   NULL, NULL);
68c6b148d   Rafael J. Wysocki   ACPI / scan: Move...
811
812
813
814
  }
  EXPORT_SYMBOL_GPL(acpi_driver_match_device);
  
  /* --------------------------------------------------------------------------
5894b0c46   Rafael J. Wysocki   ACPI / scan: Move...
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
                                ACPI Driver Management
     -------------------------------------------------------------------------- */
  
  /**
   * acpi_bus_register_driver - register a driver with the ACPI bus
   * @driver: driver being registered
   *
   * Registers a driver with the ACPI bus.  Searches the namespace for all
   * devices that match the driver's criteria and binds.  Returns zero for
   * success or a negative error status for failure.
   */
  int acpi_bus_register_driver(struct acpi_driver *driver)
  {
  	int ret;
  
  	if (acpi_disabled)
  		return -ENODEV;
  	driver->drv.name = driver->name;
  	driver->drv.bus = &acpi_bus_type;
  	driver->drv.owner = driver->owner;
  
  	ret = driver_register(&driver->drv);
  	return ret;
  }
  
  EXPORT_SYMBOL(acpi_bus_register_driver);
  
  /**
   * acpi_bus_unregister_driver - unregisters a driver with the ACPI bus
   * @driver: driver to unregister
   *
   * Unregisters a driver with the ACPI bus.  Searches the namespace for all
   * devices that match the driver's criteria and unbinds.
   */
  void acpi_bus_unregister_driver(struct acpi_driver *driver)
  {
  	driver_unregister(&driver->drv);
  }
  
  EXPORT_SYMBOL(acpi_bus_unregister_driver);
  
  /* --------------------------------------------------------------------------
                                ACPI Bus operations
     -------------------------------------------------------------------------- */
  
  static int acpi_bus_match(struct device *dev, struct device_driver *drv)
  {
  	struct acpi_device *acpi_dev = to_acpi_device(dev);
  	struct acpi_driver *acpi_drv = to_acpi_driver(drv);
  
  	return acpi_dev->flags.match_driver
  		&& !acpi_match_device_ids(acpi_dev, acpi_drv->ids);
  }
  
  static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env)
  {
  	return __acpi_device_uevent_modalias(to_acpi_device(dev), env);
  }
  
  static int acpi_device_probe(struct device *dev)
  {
  	struct acpi_device *acpi_dev = to_acpi_device(dev);
  	struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver);
  	int ret;
  
  	if (acpi_dev->handler && !acpi_is_pnp_device(acpi_dev))
  		return -EINVAL;
  
  	if (!acpi_drv->ops.add)
  		return -ENOSYS;
  
  	ret = acpi_drv->ops.add(acpi_dev);
  	if (ret)
  		return ret;
  
  	acpi_dev->driver = acpi_drv;
  	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
  			  "Driver [%s] successfully bound to device [%s]
  ",
  			  acpi_drv->name, acpi_dev->pnp.bus_id));
  
  	if (acpi_drv->ops.notify) {
  		ret = acpi_device_install_notify_handler(acpi_dev);
  		if (ret) {
  			if (acpi_drv->ops.remove)
  				acpi_drv->ops.remove(acpi_dev);
  
  			acpi_dev->driver = NULL;
  			acpi_dev->driver_data = NULL;
  			return ret;
  		}
  	}
  
  	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]
  ",
  			  acpi_drv->name, acpi_dev->pnp.bus_id));
  	get_device(dev);
  	return 0;
  }
67fbd0a3a   Tom Todd   ACPI: bus: Fix a ...
914
  static int acpi_device_remove(struct device *dev)
5894b0c46   Rafael J. Wysocki   ACPI / scan: Move...
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
  {
  	struct acpi_device *acpi_dev = to_acpi_device(dev);
  	struct acpi_driver *acpi_drv = acpi_dev->driver;
  
  	if (acpi_drv) {
  		if (acpi_drv->ops.notify)
  			acpi_device_remove_notify_handler(acpi_dev);
  		if (acpi_drv->ops.remove)
  			acpi_drv->ops.remove(acpi_dev);
  	}
  	acpi_dev->driver = NULL;
  	acpi_dev->driver_data = NULL;
  
  	put_device(dev);
  	return 0;
  }
  
  struct bus_type acpi_bus_type = {
  	.name		= "acpi",
  	.match		= acpi_bus_match,
  	.probe		= acpi_device_probe,
  	.remove		= acpi_device_remove,
  	.uevent		= acpi_device_uevent,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
939
940
941
  /* --------------------------------------------------------------------------
                               Initialization/Cleanup
     -------------------------------------------------------------------------- */
4be44fcd3   Len Brown   [ACPI] Lindent al...
942
  static int __init acpi_bus_init_irq(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
943
  {
6a8c0af6e   Bjorn Helgaas   ACPI: Remove usel...
944
  	acpi_status status;
4be44fcd3   Len Brown   [ACPI] Lindent al...
945
  	char *message = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
946

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
947

aafbcd165   Alexey Starikovskiy   ACPI: invoke acpi...
948
  	/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
949
950
951
952
953
954
955
956
957
958
959
960
961
962
  	 * Let the system know what interrupt model we are using by
  	 * evaluating the \_PIC object, if exists.
  	 */
  
  	switch (acpi_irq_model) {
  	case ACPI_IRQ_MODEL_PIC:
  		message = "PIC";
  		break;
  	case ACPI_IRQ_MODEL_IOAPIC:
  		message = "IOAPIC";
  		break;
  	case ACPI_IRQ_MODEL_IOSAPIC:
  		message = "IOSAPIC";
  		break;
fbe61ec71   Hanjun Guo   ARM64 / ACPI: Int...
963
964
965
  	case ACPI_IRQ_MODEL_GIC:
  		message = "GIC";
  		break;
3948ec940   John Keller   ACPI: Altix: ACPI...
966
967
968
  	case ACPI_IRQ_MODEL_PLATFORM:
  		message = "platform specific model";
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
969
970
971
  	default:
  		printk(KERN_WARNING PREFIX "Unknown interrupt routing model
  ");
d550d98d3   Patrick Mochel   ACPI: delete trac...
972
  		return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
973
974
975
976
  	}
  
  	printk(KERN_INFO PREFIX "Using %s for interrupt routing
  ", message);
0db982026   Jiang Liu   ACPI: introduce h...
977
  	status = acpi_execute_simple_method(NULL, "\\_PIC", acpi_irq_model);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
978
  	if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) {
a6fc67202   Thomas Renninger   ACPI: Enable ACPI...
979
  		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PIC"));
d550d98d3   Patrick Mochel   ACPI: delete trac...
980
  		return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
981
  	}
d550d98d3   Patrick Mochel   ACPI: delete trac...
982
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
983
  }
b064a8fa7   Rafael J. Wysocki   ACPI / init: Swit...
984
985
986
987
988
989
990
991
992
993
  /**
   * acpi_early_init - Initialize ACPICA and populate the ACPI namespace.
   *
   * The ACPI tables are accessible after this, but the handling of events has not
   * been initialized and the global lock is not available yet, so AML should not
   * be executed at this point.
   *
   * Doing this before switching the EFI runtime services to virtual mode allows
   * the EfiBootServices memory to be freed slightly earlier on boot.
   */
4be44fcd3   Len Brown   [ACPI] Lindent al...
994
  void __init acpi_early_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
995
  {
6a8c0af6e   Bjorn Helgaas   ACPI: Remove usel...
996
  	acpi_status status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
997
998
  
  	if (acpi_disabled)
d550d98d3   Patrick Mochel   ACPI: delete trac...
999
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1000

61686124f   Bob Moore   [ACPI] ACPICA 200...
1001
1002
  	printk(KERN_INFO PREFIX "Core revision %08x
  ", ACPI_CA_VERSION);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1003
1004
1005
  	/* enable workarounds, unless strict ACPI spec. compliance */
  	if (!acpi_strict)
  		acpi_gbl_enable_interpreter_slack = TRUE;
8d3523fb3   Lv Zheng   ACPI / osl: Remov...
1006
  	acpi_permanent_mmap = true;
ad71860a1   Alexey Starikovskiy   ACPICA: minimal p...
1007

5d128fbd8   Jean Delvare   ACPI / bus: Only ...
1008
  #ifdef CONFIG_X86
ae976358c   Kai Heng Feng   Revert "ACPI / bu...
1009
1010
  	/*
  	 * If the machine falls into the DMI check table,
5d128fbd8   Jean Delvare   ACPI / bus: Only ...
1011
1012
1013
1014
  	 * DSDT will be copied to memory.
  	 * Note that calling dmi_check_system() here on other architectures
  	 * would not be OK because only x86 initializes dmi early enough.
  	 * Thankfully only x86 systems need such quirks for now.
ae976358c   Kai Heng Feng   Revert "ACPI / bu...
1015
1016
  	 */
  	dmi_check_system(dsdt_dmi_table);
5d128fbd8   Jean Delvare   ACPI / bus: Only ...
1017
  #endif
aa2110cb1   Lin Ming   ACPI: add boot op...
1018

ad71860a1   Alexey Starikovskiy   ACPICA: minimal p...
1019
1020
1021
1022
1023
1024
1025
  	status = acpi_reallocate_root_table();
  	if (ACPI_FAILURE(status)) {
  		printk(KERN_ERR PREFIX
  		       "Unable to reallocate ACPI tables
  ");
  		goto error0;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1026
1027
  	status = acpi_initialize_subsystem();
  	if (ACPI_FAILURE(status)) {
4be44fcd3   Len Brown   [ACPI] Lindent al...
1028
1029
1030
  		printk(KERN_ERR PREFIX
  		       "Unable to initialize the ACPI Interpreter
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1031
1032
  		goto error0;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1033
1034
  #ifdef CONFIG_X86
  	if (!acpi_ioapic) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1035
  		/* compatible (0) means level (3) */
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
1036
1037
1038
1039
  		if (!(acpi_sci_flags & ACPI_MADT_TRIGGER_MASK)) {
  			acpi_sci_flags &= ~ACPI_MADT_TRIGGER_MASK;
  			acpi_sci_flags |= ACPI_MADT_TRIGGER_LEVEL;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1040
  		/* Set PIC-mode SCI trigger type */
cee324b14   Alexey Starikovskiy   ACPICA: use new A...
1041
  		acpi_pic_sci_set_trigger(acpi_gbl_FADT.sci_interrupt,
5f3b1a8b6   Alexey Starikovskiy   ACPICA: Remove du...
1042
  					 (acpi_sci_flags & ACPI_MADT_TRIGGER_MASK) >> 2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1043
  	} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1044
  		/*
cee324b14   Alexey Starikovskiy   ACPICA: use new A...
1045
  		 * now that acpi_gbl_FADT is initialized,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1046
1047
  		 * update it with result from INT_SRC_OVR parsing
  		 */
cee324b14   Alexey Starikovskiy   ACPICA: use new A...
1048
  		acpi_gbl_FADT.sci_interrupt = acpi_sci_override_gsi;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1049
1050
  	}
  #endif
b064a8fa7   Rafael J. Wysocki   ACPI / init: Swit...
1051
1052
1053
1054
1055
1056
1057
1058
1059
  	return;
  
   error0:
  	disable_acpi();
  }
  
  /**
   * acpi_subsystem_init - Finalize the early initialization of ACPI.
   *
3af03f77c   Baoquan He   ACPI / bus: Corre...
1060
   * Switch over the platform to the ACPI mode (if possible).
b064a8fa7   Rafael J. Wysocki   ACPI / init: Swit...
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
   *
   * Doing this too early is generally unsafe, but at the same time it needs to be
   * done before all things that really depend on ACPI.  The right spot appears to
   * be before finalizing the EFI initialization.
   */
  void __init acpi_subsystem_init(void)
  {
  	acpi_status status;
  
  	if (acpi_disabled)
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1072

4505a2015   Rafael J. Wysocki   ACPI: Drop ACPI_N...
1073
  	status = acpi_enable_subsystem(~ACPI_NO_ACPI_ENABLE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1074
1075
1076
  	if (ACPI_FAILURE(status)) {
  		printk(KERN_ERR PREFIX "Unable to enable ACPI
  ");
b064a8fa7   Rafael J. Wysocki   ACPI / init: Swit...
1077
1078
1079
1080
1081
1082
1083
1084
1085
  		disable_acpi();
  	} else {
  		/*
  		 * If the system is using ACPI then we can be reasonably
  		 * confident that any regulators are managed by the firmware
  		 * so tell the regulator core it has everything it needs to
  		 * know.
  		 */
  		regulator_has_full_constraints();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1086
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1087
  }
68bdb6773   Octavian Purdila   ACPI: add support...
1088
1089
1090
1091
1092
1093
  static acpi_status acpi_bus_table_handler(u32 event, void *table, void *context)
  {
  	acpi_scan_table_handler(event, table, context);
  
  	return acpi_sysfs_table_handler(event, table, context);
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
1094
  static int __init acpi_bus_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1095
  {
6a8c0af6e   Bjorn Helgaas   ACPI: Remove usel...
1096
1097
  	int result;
  	acpi_status status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1098

176f9c180   Jiri Slaby   ACPI: remove doub...
1099
  	acpi_os_initialize1();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1100

d737f333b   Erik Schmauss   ACPI: probe ECDT ...
1101
1102
1103
1104
1105
1106
  	status = acpi_load_tables();
  	if (ACPI_FAILURE(status)) {
  		printk(KERN_ERR PREFIX
  		       "Unable to load the System Description Tables
  ");
  		goto error1;
fe6cbea0f   Lv Zheng   ACPI 2.0 / ECDT: ...
1107
  	}
b1c033082   Rafael J. Wysocki   ACPI: EC: Look fo...
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
  	/*
  	 * ACPI 2.0 requires the EC driver to be loaded and work before the EC
  	 * device is found in the namespace.
  	 *
  	 * This is accomplished by looking for the ECDT table and getting the EC
  	 * parameters out of that.
  	 *
  	 * Do that before calling acpi_initialize_objects() which may trigger EC
  	 * address space accesses.
  	 */
  	acpi_ec_ecdt_probe();
fe6cbea0f   Lv Zheng   ACPI 2.0 / ECDT: ...
1119
1120
1121
1122
1123
1124
1125
  	status = acpi_enable_subsystem(ACPI_NO_ACPI_ENABLE);
  	if (ACPI_FAILURE(status)) {
  		printk(KERN_ERR PREFIX
  		       "Unable to start the ACPI Interpreter
  ");
  		goto error1;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1126
1127
1128
1129
1130
1131
  	status = acpi_initialize_objects(ACPI_FULL_INITIALIZATION);
  	if (ACPI_FAILURE(status)) {
  		printk(KERN_ERR PREFIX "Unable to initialize ACPI objects
  ");
  		goto error1;
  	}
a21211672   Srinivas Pandruvada   ACPI / processor:...
1132
1133
  	/* Set capability bits for _OSC under processor scope */
  	acpi_early_processor_osc();
b1d248d96   Zhang Rui   ACPI: install ACP...
1134
  	/*
fc54ab729   Lin Ming   ACPI: run _OSC af...
1135
1136
1137
1138
1139
1140
  	 * _OSC method may exist in module level code,
  	 * so it must be run after ACPI_FULL_INITIALIZATION
  	 */
  	acpi_bus_osc_support();
  
  	/*
b1d248d96   Zhang Rui   ACPI: install ACP...
1141
1142
1143
  	 * _PDC control method may load dynamic SSDT tables,
  	 * and we need to install the table handler before that.
  	 */
68bdb6773   Octavian Purdila   ACPI: add support...
1144
  	status = acpi_install_table_handler(acpi_bus_table_handler, NULL);
b1d248d96   Zhang Rui   ACPI: install ACP...
1145
  	acpi_sysfs_init();
78f169965   Alex Chiang   ACPI: processor: ...
1146
  	acpi_early_processor_set_pdc();
455c8793d   Zhao Yakui   ACPI: Enable EC d...
1147
1148
1149
1150
  	/*
  	 * Maybe EC region is required at bus_scan/acpi_get_devices. So it
  	 * is necessary to enable it as early as possible.
  	 */
dcf15cbde   Lv Zheng   ACPI / EC: Fix a ...
1151
  	acpi_ec_dsdt_probe();
455c8793d   Zhao Yakui   ACPI: Enable EC d...
1152

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1153
1154
  	printk(KERN_INFO PREFIX "Interpreter enabled
  ");
aafbcd165   Alexey Starikovskiy   ACPI: invoke acpi...
1155
1156
  	/* Initialize sleep structures */
  	acpi_sleep_init();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
  	/*
  	 * Get the system interrupt model and evaluate \_PIC.
  	 */
  	result = acpi_bus_init_irq();
  	if (result)
  		goto error1;
  
  	/*
  	 * Register the for all standard device notifications.
  	 */
4be44fcd3   Len Brown   [ACPI] Lindent al...
1167
1168
1169
  	status =
  	    acpi_install_notify_handler(ACPI_ROOT_OBJECT, ACPI_SYSTEM_NOTIFY,
  					&acpi_bus_notify, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1170
  	if (ACPI_FAILURE(status)) {
4be44fcd3   Len Brown   [ACPI] Lindent al...
1171
1172
1173
  		printk(KERN_ERR PREFIX
  		       "Unable to register for device notifications
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1174
1175
1176
1177
1178
1179
1180
  		goto error1;
  	}
  
  	/*
  	 * Create the top ACPI proc directory
  	 */
  	acpi_root_dir = proc_mkdir(ACPI_BUS_FILE_ROOT, NULL);
1dcc3d336   Rafael J. Wysocki   ACPI / bus: Move ...
1181
1182
1183
  	result = bus_register(&acpi_bus_type);
  	if (!result)
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1184
1185
  
  	/* Mimic structured exception handling */
4be44fcd3   Len Brown   [ACPI] Lindent al...
1186
        error1:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1187
  	acpi_terminate();
d550d98d3   Patrick Mochel   ACPI: delete trac...
1188
  	return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1189
  }
99e0d2fc6   Greg Kroah-Hartman   kobject: convert ...
1190
  struct kobject *acpi_kobj;
f2d4753fb   Matthew Garrett   ACPI: export acpi...
1191
  EXPORT_SYMBOL_GPL(acpi_kobj);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1192

4be44fcd3   Len Brown   [ACPI] Lindent al...
1193
  static int __init acpi_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1194
  {
6831c6edc   Rafael J. Wysocki   PM: Drop pm_flags...
1195
  	int result;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1196

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1197
1198
1199
  	if (acpi_disabled) {
  		printk(KERN_INFO PREFIX "Interpreter disabled.
  ");
d550d98d3   Patrick Mochel   ACPI: delete trac...
1200
  		return -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1201
  	}
f62ed9e33   Greg Kroah-Hartman   firmware: change ...
1202
  	acpi_kobj = kobject_create_and_add("acpi", firmware_kobj);
99e0d2fc6   Greg Kroah-Hartman   kobject: convert ...
1203
  	if (!acpi_kobj) {
96b2dd1f1   Harvey Harrison   ACPI: replace rem...
1204
1205
  		printk(KERN_WARNING "%s: kset create error
  ", __func__);
99e0d2fc6   Greg Kroah-Hartman   kobject: convert ...
1206
1207
  		acpi_kobj = NULL;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1208
1209
  
  	result = acpi_bus_init();
6831c6edc   Rafael J. Wysocki   PM: Drop pm_flags...
1210
  	if (result) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1211
  		disable_acpi();
81d0273df   Bjorn Helgaas   ACPI: skip DMI po...
1212
  		return result;
6831c6edc   Rafael J. Wysocki   PM: Drop pm_flags...
1213
  	}
81d0273df   Bjorn Helgaas   ACPI: skip DMI po...
1214

6831c6edc   Rafael J. Wysocki   PM: Drop pm_flags...
1215
  	pci_mmcfg_late_init();
88ef16d88   Tomasz Nowicki   ACPI: I/O Remappi...
1216
  	acpi_iort_init();
e747f2749   Bjorn Helgaas   ACPI: call acpi_s...
1217
  	acpi_scan_init();
a5f820feb   Bjorn Helgaas   ACPI: call acpi_e...
1218
  	acpi_ec_init();
a25ee9200   Zhang Rui   ACPI: introduce d...
1219
  	acpi_debugfs_init();
9cee43e07   Bjorn Helgaas   ACPI: call acpi_s...
1220
  	acpi_sleep_proc_init();
201b8c655   Bjorn Helgaas   ACPI: call acpi_w...
1221
  	acpi_wakeup_device_init();
836d08301   Lv Zheng   ACPI / debugger: ...
1222
  	acpi_debugger_init();
baa0c019b   Prakash, Prashanth   ACPI / bus: Suppo...
1223
  	acpi_setup_sb_notify_handler();
6831c6edc   Rafael J. Wysocki   PM: Drop pm_flags...
1224
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1225
1226
1227
  }
  
  subsys_initcall(acpi_init);