Blame view

drivers/acpi/osl.c 38.7 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
  /*
   *  acpi_osl.c - OS-dependent functions ($Revision: 83 $)
   *
   *  Copyright (C) 2000       Andrew Henroid
   *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
   *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
f1241c87a   Matthew Wilcox   Add down_timeout ...
7
8
   *  Copyright (c) 2008 Intel Corporation
   *   Author: Matthew Wilcox <willy@linux.intel.com>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
   *
   * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   *
   *  This program is free software; you can redistribute it and/or modify
   *  it under the terms of the GNU General Public License as published by
   *  the Free Software Foundation; either version 2 of the License, or
   *  (at your option) any later version.
   *
   *  This program is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU General Public License for more details.
   *
   *  You should have received a copy of the GNU General Public License
   *  along with this program; if not, write to the Free Software
   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   *
   * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   *
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
29
30
31
32
33
  #include <linux/module.h>
  #include <linux/kernel.h>
  #include <linux/slab.h>
  #include <linux/mm.h>
  #include <linux/pci.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
35
36
37
38
  #include <linux/interrupt.h>
  #include <linux/kmod.h>
  #include <linux/delay.h>
  #include <linux/workqueue.h>
  #include <linux/nmi.h>
ad71860a1   Alexey Starikovskiy   ACPICA: minimal p...
39
  #include <linux/acpi.h>
2d6d9fd3a   Rafael J. Wysocki   ACPI: Introduce a...
40
  #include <linux/acpi_io.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
  #include <linux/efi.h>
df92e6959   Thomas Renninger   ACPI: track opreg...
42
43
  #include <linux/ioport.h>
  #include <linux/list.h>
f1241c87a   Matthew Wilcox   Add down_timeout ...
44
45
46
47
48
49
50
51
52
  #include <linux/jiffies.h>
  #include <linux/semaphore.h>
  
  #include <asm/io.h>
  #include <asm/uaccess.h>
  
  #include <acpi/acpi.h>
  #include <acpi/acpi_bus.h>
  #include <acpi/processor.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
53

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
  #define _COMPONENT		ACPI_OS_SERVICES
f52fd66d2   Len Brown   ACPI: clean up AC...
55
  ACPI_MODULE_NAME("osl");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
  #define PREFIX		"ACPI: "
4be44fcd3   Len Brown   [ACPI] Lindent al...
57
58
59
  struct acpi_os_dpc {
  	acpi_osd_exec_callback function;
  	void *context;
65f27f384   David Howells   WorkStruct: Pass ...
60
  	struct work_struct work;
9ac618566   Bjorn Helgaas   ACPI: simplify de...
61
  	int wait;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
62
63
64
65
66
67
68
69
70
71
72
73
74
75
  };
  
  #ifdef CONFIG_ACPI_CUSTOM_DSDT
  #include CONFIG_ACPI_CUSTOM_DSDT_FILE
  #endif
  
  #ifdef ENABLE_DEBUGGER
  #include <linux/kdb.h>
  
  /* stuff for debugger support */
  int acpi_in_debugger;
  EXPORT_SYMBOL(acpi_in_debugger);
  
  extern char line_buf[80];
4be44fcd3   Len Brown   [ACPI] Lindent al...
76
  #endif				/*ENABLE_DEBUGGER */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
78
79
80
  static acpi_osd_handler acpi_irq_handler;
  static void *acpi_irq_context;
  static struct workqueue_struct *kacpid_wq;
88db5e148   Alexey Starikovskiy   ACPI: created a d...
81
  static struct workqueue_struct *kacpi_notify_wq;
6af8bef14   Prarit Bhargava   PCI hotplug: acpi...
82
83
  struct workqueue_struct *kacpi_hotplug_wq;
  EXPORT_SYMBOL(kacpi_hotplug_wq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84

df92e6959   Thomas Renninger   ACPI: track opreg...
85
86
87
88
89
90
91
  struct acpi_res_list {
  	resource_size_t start;
  	resource_size_t end;
  	acpi_adr_space_type resource_type; /* IO port, System memory, ...*/
  	char name[5];   /* only can have a length of 4 chars, make use of this
  			   one instead of res->name, no need to kalloc then */
  	struct list_head resource_list;
a5fe1a03f   Lin Ming   ACPICA: fix leak ...
92
  	int count;
df92e6959   Thomas Renninger   ACPI: track opreg...
93
94
95
96
  };
  
  static LIST_HEAD(resource_list_head);
  static DEFINE_SPINLOCK(acpi_res_lock);
620242ae8   Myron Stowe   ACPI: Maintain a ...
97
98
99
100
101
102
103
104
105
  /*
   * This list of permanent mappings is for memory that may be accessed from
   * interrupt context, where we can't do the ioremap().
   */
  struct acpi_ioremap {
  	struct list_head list;
  	void __iomem *virt;
  	acpi_physical_address phys;
  	acpi_size size;
b7c1fadd6   Rafael J. Wysocki   ACPI: Do not use ...
106
  	unsigned long refcount;
620242ae8   Myron Stowe   ACPI: Maintain a ...
107
108
109
  };
  
  static LIST_HEAD(acpi_ioremaps);
7bbb89035   Rafael J. Wysocki   ACPI: Change acpi...
110
  static DEFINE_MUTEX(acpi_ioremap_lock);
620242ae8   Myron Stowe   ACPI: Maintain a ...
111

b0ed7a915   Lin Ming   ACPICA/ACPI: Add ...
112
  static void __init acpi_osi_setup_late(void);
ae00d8124   Len Brown   ACPI: extend "acp...
113

d4b7dc499   Len Brown   ACPI: make _OSI(L...
114
  /*
a6e0887f2   Len Brown   ACPI: delete OSI(...
115
   * The story of _OSI(Linux)
d4b7dc499   Len Brown   ACPI: make _OSI(L...
116
   *
a6e0887f2   Len Brown   ACPI: delete OSI(...
117
118
   * From pre-history through Linux-2.6.22,
   * Linux responded TRUE upon a BIOS OSI(Linux) query.
d4b7dc499   Len Brown   ACPI: make _OSI(L...
119
   *
a6e0887f2   Len Brown   ACPI: delete OSI(...
120
121
122
123
   * Unfortunately, reference BIOS writers got wind of this
   * and put OSI(Linux) in their example code, quickly exposing
   * this string as ill-conceived and opening the door to
   * an un-bounded number of BIOS incompatibilities.
d4b7dc499   Len Brown   ACPI: make _OSI(L...
124
   *
a6e0887f2   Len Brown   ACPI: delete OSI(...
125
126
127
128
129
130
131
132
133
134
135
   * For example, OSI(Linux) was used on resume to re-POST a
   * video card on one system, because Linux at that time
   * could not do a speedy restore in its native driver.
   * But then upon gaining quick native restore capability,
   * Linux has no way to tell the BIOS to skip the time-consuming
   * POST -- putting Linux at a permanent performance disadvantage.
   * On another system, the BIOS writer used OSI(Linux)
   * to infer native OS support for IPMI!  On other systems,
   * OSI(Linux) simply got in the way of Linux claiming to
   * be compatible with other operating systems, exposing
   * BIOS issues such as skipped device initialization.
d4b7dc499   Len Brown   ACPI: make _OSI(L...
136
   *
a6e0887f2   Len Brown   ACPI: delete OSI(...
137
138
   * So "Linux" turned out to be a really poor chose of
   * OSI string, and from Linux-2.6.23 onward we respond FALSE.
d4b7dc499   Len Brown   ACPI: make _OSI(L...
139
140
   *
   * BIOS writers should NOT query _OSI(Linux) on future systems.
a6e0887f2   Len Brown   ACPI: delete OSI(...
141
142
143
144
   * Linux will complain on the console when it sees it, and return FALSE.
   * To get Linux to return TRUE for your system  will require
   * a kernel source update to add a DMI entry,
   * or boot with "acpi_osi=Linux"
d4b7dc499   Len Brown   ACPI: make _OSI(L...
145
   */
d4b7dc499   Len Brown   ACPI: make _OSI(L...
146

1d15d84e8   Adrian Bunk   ACPI: make struct...
147
  static struct osi_linux {
d4b7dc499   Len Brown   ACPI: make _OSI(L...
148
149
150
  	unsigned int	enable:1;
  	unsigned int	dmi:1;
  	unsigned int	cmdline:1;
d90aa92c0   Lin Ming   acpi: fix _OSI st...
151
  } osi_linux = {0, 0, 0};
f507654d4   Len Brown   ACPI: Make _OSI(L...
152

b0ed7a915   Lin Ming   ACPICA/ACPI: Add ...
153
154
155
  static u32 acpi_osi_handler(acpi_string interface, u32 supported)
  {
  	if (!strcmp("Linux", interface)) {
8997621bb   Len Brown   ACPI print OSI(Li...
156
  		printk_once(KERN_NOTICE FW_BUG PREFIX
b0ed7a915   Lin Ming   ACPICA/ACPI: Add ...
157
158
159
160
161
162
163
164
165
  			"BIOS _OSI(Linux) query %s%s
  ",
  			osi_linux.enable ? "honored" : "ignored",
  			osi_linux.cmdline ? " via cmdline" :
  			osi_linux.dmi ? " via DMI" : "");
  	}
  
  	return supported;
  }
9a47cdb1b   Bjorn Helgaas   ACPI: move FADT r...
166
167
168
  static void __init acpi_request_region (struct acpi_generic_address *addr,
  	unsigned int length, char *desc)
  {
9a47cdb1b   Bjorn Helgaas   ACPI: move FADT r...
169
170
  	if (!addr->address || !length)
  		return;
cfa806f05   Andi Kleen   gcc-4.6: ACPI: fi...
171
  	/* Resources are never freed */
eee3c859c   Len Brown   Pull motherboard ...
172
  	if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
cfa806f05   Andi Kleen   gcc-4.6: ACPI: fi...
173
  		request_region(addr->address, length, desc);
eee3c859c   Len Brown   Pull motherboard ...
174
  	else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
cfa806f05   Andi Kleen   gcc-4.6: ACPI: fi...
175
  		request_mem_region(addr->address, length, desc);
9a47cdb1b   Bjorn Helgaas   ACPI: move FADT r...
176
177
178
179
  }
  
  static int __init acpi_reserve_resources(void)
  {
eee3c859c   Len Brown   Pull motherboard ...
180
  	acpi_request_region(&acpi_gbl_FADT.xpm1a_event_block, acpi_gbl_FADT.pm1_event_length,
9a47cdb1b   Bjorn Helgaas   ACPI: move FADT r...
181
  		"ACPI PM1a_EVT_BLK");
eee3c859c   Len Brown   Pull motherboard ...
182
  	acpi_request_region(&acpi_gbl_FADT.xpm1b_event_block, acpi_gbl_FADT.pm1_event_length,
9a47cdb1b   Bjorn Helgaas   ACPI: move FADT r...
183
  		"ACPI PM1b_EVT_BLK");
eee3c859c   Len Brown   Pull motherboard ...
184
  	acpi_request_region(&acpi_gbl_FADT.xpm1a_control_block, acpi_gbl_FADT.pm1_control_length,
9a47cdb1b   Bjorn Helgaas   ACPI: move FADT r...
185
  		"ACPI PM1a_CNT_BLK");
eee3c859c   Len Brown   Pull motherboard ...
186
  	acpi_request_region(&acpi_gbl_FADT.xpm1b_control_block, acpi_gbl_FADT.pm1_control_length,
9a47cdb1b   Bjorn Helgaas   ACPI: move FADT r...
187
  		"ACPI PM1b_CNT_BLK");
eee3c859c   Len Brown   Pull motherboard ...
188
189
  	if (acpi_gbl_FADT.pm_timer_length == 4)
  		acpi_request_region(&acpi_gbl_FADT.xpm_timer_block, 4, "ACPI PM_TMR");
9a47cdb1b   Bjorn Helgaas   ACPI: move FADT r...
190

eee3c859c   Len Brown   Pull motherboard ...
191
  	acpi_request_region(&acpi_gbl_FADT.xpm2_control_block, acpi_gbl_FADT.pm2_control_length,
9a47cdb1b   Bjorn Helgaas   ACPI: move FADT r...
192
193
194
  		"ACPI PM2_CNT_BLK");
  
  	/* Length of GPE blocks must be a non-negative multiple of 2 */
eee3c859c   Len Brown   Pull motherboard ...
195
196
197
  	if (!(acpi_gbl_FADT.gpe0_block_length & 0x1))
  		acpi_request_region(&acpi_gbl_FADT.xgpe0_block,
  			       acpi_gbl_FADT.gpe0_block_length, "ACPI GPE0_BLK");
9a47cdb1b   Bjorn Helgaas   ACPI: move FADT r...
198

eee3c859c   Len Brown   Pull motherboard ...
199
200
201
  	if (!(acpi_gbl_FADT.gpe1_block_length & 0x1))
  		acpi_request_region(&acpi_gbl_FADT.xgpe1_block,
  			       acpi_gbl_FADT.gpe1_block_length, "ACPI GPE1_BLK");
9a47cdb1b   Bjorn Helgaas   ACPI: move FADT r...
202
203
204
205
  
  	return 0;
  }
  device_initcall(acpi_reserve_resources);
4be44fcd3   Len Brown   [ACPI] Lindent al...
206
  void acpi_os_printf(const char *fmt, ...)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
207
208
209
210
211
212
  {
  	va_list args;
  	va_start(args, fmt);
  	acpi_os_vprintf(fmt, args);
  	va_end(args);
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
213

4be44fcd3   Len Brown   [ACPI] Lindent al...
214
  void acpi_os_vprintf(const char *fmt, va_list args)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
215
216
  {
  	static char buffer[512];
4be44fcd3   Len Brown   [ACPI] Lindent al...
217

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218
219
220
221
222
223
  	vsprintf(buffer, fmt, args);
  
  #ifdef ENABLE_DEBUGGER
  	if (acpi_in_debugger) {
  		kdb_printf("%s", buffer);
  	} else {
4d9391557   Frank Seidel   ACPI: add missing...
224
  		printk(KERN_CONT "%s", buffer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
225
226
  	}
  #else
4d9391557   Frank Seidel   ACPI: add missing...
227
  	printk(KERN_CONT "%s", buffer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
228
229
  #endif
  }
4996c0230   Takao Indoh   ACPI: introduce "...
230
231
232
233
234
235
236
237
238
  #ifdef CONFIG_KEXEC
  static unsigned long acpi_rsdp;
  static int __init setup_acpi_rsdp(char *arg)
  {
  	acpi_rsdp = simple_strtoul(arg, NULL, 16);
  	return 0;
  }
  early_param("acpi_rsdp", setup_acpi_rsdp);
  #endif
ad71860a1   Alexey Starikovskiy   ACPICA: minimal p...
239
  acpi_physical_address __init acpi_os_get_root_pointer(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
240
  {
4996c0230   Takao Indoh   ACPI: introduce "...
241
242
243
244
  #ifdef CONFIG_KEXEC
  	if (acpi_rsdp)
  		return acpi_rsdp;
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245
  	if (efi_enabled) {
b2c99e3c7   Bjorn Helgaas   [PATCH] EFI: keep...
246
  		if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
ad71860a1   Alexey Starikovskiy   ACPICA: minimal p...
247
  			return efi.acpi20;
b2c99e3c7   Bjorn Helgaas   [PATCH] EFI: keep...
248
  		else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
ad71860a1   Alexey Starikovskiy   ACPICA: minimal p...
249
  			return efi.acpi;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
250
  		else {
4be44fcd3   Len Brown   [ACPI] Lindent al...
251
252
253
  			printk(KERN_ERR PREFIX
  			       "System description tables not found
  ");
ad71860a1   Alexey Starikovskiy   ACPICA: minimal p...
254
  			return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
255
  		}
239665a3b   Len Brown   ACPI: tables: com...
256
257
258
259
260
261
  	} else {
  		acpi_physical_address pa = 0;
  
  		acpi_find_root_pointer(&pa);
  		return pa;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
  }
78cdb3ed4   Myron Stowe   ACPI: Convert sim...
263
  /* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
4a3cba5e7   Myron Stowe   ACPI: Page based ...
264
265
  static struct acpi_ioremap *
  acpi_map_lookup(acpi_physical_address phys, acpi_size size)
620242ae8   Myron Stowe   ACPI: Maintain a ...
266
267
  {
  	struct acpi_ioremap *map;
78cdb3ed4   Myron Stowe   ACPI: Convert sim...
268
  	list_for_each_entry_rcu(map, &acpi_ioremaps, list)
620242ae8   Myron Stowe   ACPI: Maintain a ...
269
270
  		if (map->phys <= phys &&
  		    phys + size <= map->phys + map->size)
4a3cba5e7   Myron Stowe   ACPI: Page based ...
271
272
273
274
275
276
277
278
279
280
281
282
283
284
  			return map;
  
  	return NULL;
  }
  
  /* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
  static void __iomem *
  acpi_map_vaddr_lookup(acpi_physical_address phys, unsigned int size)
  {
  	struct acpi_ioremap *map;
  
  	map = acpi_map_lookup(phys, size);
  	if (map)
  		return map->virt + (phys - map->phys);
620242ae8   Myron Stowe   ACPI: Maintain a ...
285
286
287
  
  	return NULL;
  }
13606a2de   Rafael J. Wysocki   ACPI: Introduce a...
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
  void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size)
  {
  	struct acpi_ioremap *map;
  	void __iomem *virt = NULL;
  
  	mutex_lock(&acpi_ioremap_lock);
  	map = acpi_map_lookup(phys, size);
  	if (map) {
  		virt = map->virt + (phys - map->phys);
  		map->refcount++;
  	}
  	mutex_unlock(&acpi_ioremap_lock);
  	return virt;
  }
  EXPORT_SYMBOL_GPL(acpi_os_get_iomem);
78cdb3ed4   Myron Stowe   ACPI: Convert sim...
303
  /* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
620242ae8   Myron Stowe   ACPI: Maintain a ...
304
305
306
307
  static struct acpi_ioremap *
  acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
  {
  	struct acpi_ioremap *map;
78cdb3ed4   Myron Stowe   ACPI: Convert sim...
308
  	list_for_each_entry_rcu(map, &acpi_ioremaps, list)
4a3cba5e7   Myron Stowe   ACPI: Page based ...
309
310
  		if (map->virt <= virt &&
  		    virt + size <= map->virt + map->size)
620242ae8   Myron Stowe   ACPI: Maintain a ...
311
312
313
314
  			return map;
  
  	return NULL;
  }
2fdf07417   Jan Beulich   acpi: make __acpi...
315
316
  void __iomem *__init_refok
  acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
317
  {
7ffd0443f   Rafael J. Wysocki   ACPI: Make acpi_o...
318
  	struct acpi_ioremap *map;
620242ae8   Myron Stowe   ACPI: Maintain a ...
319
  	void __iomem *virt;
2d6d9fd3a   Rafael J. Wysocki   ACPI: Introduce a...
320
321
  	acpi_physical_address pg_off;
  	acpi_size pg_sz;
620242ae8   Myron Stowe   ACPI: Maintain a ...
322

9f4fd61fa   Bjorn Helgaas   [PATCH] ACPI: cle...
323
324
325
  	if (phys > ULONG_MAX) {
  		printk(KERN_ERR PREFIX "Cannot map memory that high
  ");
70c0846e4   Randy Dunlap   ACPI: Fix sparse ...
326
  		return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
327
  	}
620242ae8   Myron Stowe   ACPI: Maintain a ...
328
329
  
  	if (!acpi_gbl_permanent_mmap)
ad71860a1   Alexey Starikovskiy   ACPICA: minimal p...
330
  		return __acpi_map_table((unsigned long)phys, size);
620242ae8   Myron Stowe   ACPI: Maintain a ...
331

7ffd0443f   Rafael J. Wysocki   ACPI: Make acpi_o...
332
333
334
335
  	mutex_lock(&acpi_ioremap_lock);
  	/* Check if there's a suitable mapping already. */
  	map = acpi_map_lookup(phys, size);
  	if (map) {
b7c1fadd6   Rafael J. Wysocki   ACPI: Do not use ...
336
  		map->refcount++;
7ffd0443f   Rafael J. Wysocki   ACPI: Make acpi_o...
337
338
  		goto out;
  	}
620242ae8   Myron Stowe   ACPI: Maintain a ...
339
  	map = kzalloc(sizeof(*map), GFP_KERNEL);
7ffd0443f   Rafael J. Wysocki   ACPI: Make acpi_o...
340
341
  	if (!map) {
  		mutex_unlock(&acpi_ioremap_lock);
620242ae8   Myron Stowe   ACPI: Maintain a ...
342
  		return NULL;
7ffd0443f   Rafael J. Wysocki   ACPI: Make acpi_o...
343
  	}
620242ae8   Myron Stowe   ACPI: Maintain a ...
344

4a3cba5e7   Myron Stowe   ACPI: Page based ...
345
346
  	pg_off = round_down(phys, PAGE_SIZE);
  	pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
2d6d9fd3a   Rafael J. Wysocki   ACPI: Introduce a...
347
  	virt = acpi_os_ioremap(pg_off, pg_sz);
620242ae8   Myron Stowe   ACPI: Maintain a ...
348
  	if (!virt) {
7ffd0443f   Rafael J. Wysocki   ACPI: Make acpi_o...
349
  		mutex_unlock(&acpi_ioremap_lock);
620242ae8   Myron Stowe   ACPI: Maintain a ...
350
351
352
353
354
355
  		kfree(map);
  		return NULL;
  	}
  
  	INIT_LIST_HEAD(&map->list);
  	map->virt = virt;
4a3cba5e7   Myron Stowe   ACPI: Page based ...
356
357
  	map->phys = pg_off;
  	map->size = pg_sz;
b7c1fadd6   Rafael J. Wysocki   ACPI: Do not use ...
358
  	map->refcount = 1;
620242ae8   Myron Stowe   ACPI: Maintain a ...
359

78cdb3ed4   Myron Stowe   ACPI: Convert sim...
360
  	list_add_tail_rcu(&map->list, &acpi_ioremaps);
620242ae8   Myron Stowe   ACPI: Maintain a ...
361

7ffd0443f   Rafael J. Wysocki   ACPI: Make acpi_o...
362
363
   out:
  	mutex_unlock(&acpi_ioremap_lock);
4a3cba5e7   Myron Stowe   ACPI: Page based ...
364
  	return map->virt + (phys - map->phys);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
365
  }
55a82ab31   Kylene Jo Hall   [PATCH] tpm: add ...
366
  EXPORT_SYMBOL_GPL(acpi_os_map_memory);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
367

b7c1fadd6   Rafael J. Wysocki   ACPI: Do not use ...
368
  static void acpi_os_drop_map_ref(struct acpi_ioremap *map)
4a3cba5e7   Myron Stowe   ACPI: Page based ...
369
  {
b7c1fadd6   Rafael J. Wysocki   ACPI: Do not use ...
370
371
  	if (!--map->refcount)
  		list_del_rcu(&map->list);
4a3cba5e7   Myron Stowe   ACPI: Page based ...
372
  }
4a3cba5e7   Myron Stowe   ACPI: Page based ...
373

b7c1fadd6   Rafael J. Wysocki   ACPI: Do not use ...
374
  static void acpi_os_map_cleanup(struct acpi_ioremap *map)
7fe135dc0   Rafael J. Wysocki   ACPI: Avoid walki...
375
  {
b7c1fadd6   Rafael J. Wysocki   ACPI: Do not use ...
376
377
378
379
380
  	if (!map->refcount) {
  		synchronize_rcu();
  		iounmap(map->virt);
  		kfree(map);
  	}
4a3cba5e7   Myron Stowe   ACPI: Page based ...
381
  }
0d3a9cf5a   Jeremy Fitzhardinge   acpi: add some mi...
382
  void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
383
  {
620242ae8   Myron Stowe   ACPI: Maintain a ...
384
  	struct acpi_ioremap *map;
620242ae8   Myron Stowe   ACPI: Maintain a ...
385
386
  
  	if (!acpi_gbl_permanent_mmap) {
7d97277b7   Yinghai Lu   acpi/x86: introdu...
387
  		__acpi_unmap_table(virt, size);
620242ae8   Myron Stowe   ACPI: Maintain a ...
388
389
  		return;
  	}
7bbb89035   Rafael J. Wysocki   ACPI: Change acpi...
390
  	mutex_lock(&acpi_ioremap_lock);
620242ae8   Myron Stowe   ACPI: Maintain a ...
391
392
  	map = acpi_map_lookup_virt(virt, size);
  	if (!map) {
7bbb89035   Rafael J. Wysocki   ACPI: Change acpi...
393
  		mutex_unlock(&acpi_ioremap_lock);
7fe135dc0   Rafael J. Wysocki   ACPI: Avoid walki...
394
395
  		WARN(true, PREFIX "%s: bad address %p
  ", __func__, virt);
620242ae8   Myron Stowe   ACPI: Maintain a ...
396
397
  		return;
  	}
b7c1fadd6   Rafael J. Wysocki   ACPI: Do not use ...
398
  	acpi_os_drop_map_ref(map);
7bbb89035   Rafael J. Wysocki   ACPI: Change acpi...
399
  	mutex_unlock(&acpi_ioremap_lock);
620242ae8   Myron Stowe   ACPI: Maintain a ...
400

b7c1fadd6   Rafael J. Wysocki   ACPI: Do not use ...
401
  	acpi_os_map_cleanup(map);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
402
  }
55a82ab31   Kylene Jo Hall   [PATCH] tpm: add ...
403
  EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
404

0d3a9cf5a   Jeremy Fitzhardinge   acpi: add some mi...
405
  void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
7d97277b7   Yinghai Lu   acpi/x86: introdu...
406
407
408
409
  {
  	if (!acpi_gbl_permanent_mmap)
  		__acpi_unmap_table(virt, size);
  }
073b4964b   Rafael J. Wysocki   ACPI: Do not expo...
410
  static int acpi_os_map_generic_address(struct acpi_generic_address *addr)
297185212   Myron Stowe   ACPI: Add interfa...
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
  {
  	void __iomem *virt;
  
  	if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
  		return 0;
  
  	if (!addr->address || !addr->bit_width)
  		return -EINVAL;
  
  	virt = acpi_os_map_memory(addr->address, addr->bit_width / 8);
  	if (!virt)
  		return -EIO;
  
  	return 0;
  }
297185212   Myron Stowe   ACPI: Add interfa...
426

073b4964b   Rafael J. Wysocki   ACPI: Do not expo...
427
  static void acpi_os_unmap_generic_address(struct acpi_generic_address *addr)
297185212   Myron Stowe   ACPI: Add interfa...
428
  {
7fe135dc0   Rafael J. Wysocki   ACPI: Avoid walki...
429
  	struct acpi_ioremap *map;
297185212   Myron Stowe   ACPI: Add interfa...
430
431
432
433
434
435
  
  	if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
  		return;
  
  	if (!addr->address || !addr->bit_width)
  		return;
7bbb89035   Rafael J. Wysocki   ACPI: Change acpi...
436
  	mutex_lock(&acpi_ioremap_lock);
7fe135dc0   Rafael J. Wysocki   ACPI: Avoid walki...
437
438
439
440
441
  	map = acpi_map_lookup(addr->address, addr->bit_width / 8);
  	if (!map) {
  		mutex_unlock(&acpi_ioremap_lock);
  		return;
  	}
b7c1fadd6   Rafael J. Wysocki   ACPI: Do not use ...
442
  	acpi_os_drop_map_ref(map);
7bbb89035   Rafael J. Wysocki   ACPI: Change acpi...
443
  	mutex_unlock(&acpi_ioremap_lock);
297185212   Myron Stowe   ACPI: Add interfa...
444

b7c1fadd6   Rafael J. Wysocki   ACPI: Do not use ...
445
  	acpi_os_map_cleanup(map);
297185212   Myron Stowe   ACPI: Add interfa...
446
  }
297185212   Myron Stowe   ACPI: Add interfa...
447

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
448
449
  #ifdef ACPI_FUTURE_USAGE
  acpi_status
4be44fcd3   Len Brown   [ACPI] Lindent al...
450
  acpi_os_get_physical_address(void *virt, acpi_physical_address * phys)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
451
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
452
  	if (!phys || !virt)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
453
454
455
456
457
458
459
460
461
462
463
464
465
  		return AE_BAD_PARAMETER;
  
  	*phys = virt_to_phys(virt);
  
  	return AE_OK;
  }
  #endif
  
  #define ACPI_MAX_OVERRIDE_LEN 100
  
  static char acpi_os_name[ACPI_MAX_OVERRIDE_LEN];
  
  acpi_status
4be44fcd3   Len Brown   [ACPI] Lindent al...
466
467
  acpi_os_predefined_override(const struct acpi_predefined_names *init_val,
  			    acpi_string * new_val)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
468
469
470
471
472
  {
  	if (!init_val || !new_val)
  		return AE_BAD_PARAMETER;
  
  	*new_val = NULL;
4be44fcd3   Len Brown   [ACPI] Lindent al...
473
  	if (!memcmp(init_val->name, "_OS_", 4) && strlen(acpi_os_name)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
474
475
  		printk(KERN_INFO PREFIX "Overriding _OS definition to '%s'
  ",
4be44fcd3   Len Brown   [ACPI] Lindent al...
476
  		       acpi_os_name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
477
478
479
480
481
482
483
  		*new_val = acpi_os_name;
  	}
  
  	return AE_OK;
  }
  
  acpi_status
4be44fcd3   Len Brown   [ACPI] Lindent al...
484
485
  acpi_os_table_override(struct acpi_table_header * existing_table,
  		       struct acpi_table_header ** new_table)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
486
487
488
  {
  	if (!existing_table || !new_table)
  		return AE_BAD_PARAMETER;
71fc47a9a   Markus Gaugusch   ACPI: basic initr...
489
  	*new_table = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
490
491
  #ifdef CONFIG_ACPI_CUSTOM_DSDT
  	if (strncmp(existing_table->signature, "DSDT", 4) == 0)
4be44fcd3   Len Brown   [ACPI] Lindent al...
492
  		*new_table = (struct acpi_table_header *)AmlCode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
493
  #endif
6ed31e92e   Éric Piel   ACPI: Taint kerne...
494
495
496
497
498
499
500
501
  	if (*new_table != NULL) {
  		printk(KERN_WARNING PREFIX "Override [%4.4s-%8.8s], "
  			   "this is unsafe: tainting kernel
  ",
  		       existing_table->signature,
  		       existing_table->oem_table_id);
  		add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
502
503
  	return AE_OK;
  }
7d12e780e   David Howells   IRQ: Maintain reg...
504
  static irqreturn_t acpi_irq(int irq, void *dev_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
505
  {
5229e87d5   Len Brown   ACPI: create /sys...
506
507
508
509
510
511
512
  	u32 handled;
  
  	handled = (*acpi_irq_handler) (acpi_irq_context);
  
  	if (handled) {
  		acpi_irq_handled++;
  		return IRQ_HANDLED;
88bea188b   Len Brown   ACPI: add /sys/fi...
513
514
  	} else {
  		acpi_irq_not_handled++;
5229e87d5   Len Brown   ACPI: create /sys...
515
  		return IRQ_NONE;
88bea188b   Len Brown   ACPI: add /sys/fi...
516
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
517
518
519
  }
  
  acpi_status
4be44fcd3   Len Brown   [ACPI] Lindent al...
520
521
  acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,
  				  void *context)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
522
523
  {
  	unsigned int irq;
5229e87d5   Len Brown   ACPI: create /sys...
524
  	acpi_irq_stats_init();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
525
  	/*
23fe36306   Rafael J. Wysocki   ACPI: Avoid calli...
526
527
  	 * ACPI interrupts different from the SCI in our copy of the FADT are
  	 * not supported.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
528
  	 */
23fe36306   Rafael J. Wysocki   ACPI: Avoid calli...
529
530
531
532
533
  	if (gsi != acpi_gbl_FADT.sci_interrupt)
  		return AE_BAD_PARAMETER;
  
  	if (acpi_irq_handler)
  		return AE_ALREADY_ACQUIRED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
534
535
536
537
538
539
540
541
542
  	if (acpi_gsi_to_irq(gsi, &irq) < 0) {
  		printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered
  ",
  		       gsi);
  		return AE_OK;
  	}
  
  	acpi_irq_handler = handler;
  	acpi_irq_context = context;
dace14537   Thomas Gleixner   [PATCH] irq-flags...
543
  	if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
544
545
  		printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed
  ", irq);
23fe36306   Rafael J. Wysocki   ACPI: Avoid calli...
546
  		acpi_irq_handler = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
547
548
  		return AE_NOT_ACQUIRED;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
549
550
551
  
  	return AE_OK;
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
552
  acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
553
  {
23fe36306   Rafael J. Wysocki   ACPI: Avoid calli...
554
555
556
557
558
  	if (irq != acpi_gbl_FADT.sci_interrupt)
  		return AE_BAD_PARAMETER;
  
  	free_irq(irq, acpi_irq);
  	acpi_irq_handler = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
559
560
561
562
563
564
565
  
  	return AE_OK;
  }
  
  /*
   * Running in interpreter thread context, safe to sleep
   */
439913fff   Lin Ming   ACPI: replace acp...
566
  void acpi_os_sleep(u64 ms)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
567
  {
01a527ec7   Nishanth Aravamudan   [PATCH] drivers/a...
568
  	schedule_timeout_interruptible(msecs_to_jiffies(ms));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
569
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
570

4be44fcd3   Len Brown   [ACPI] Lindent al...
571
  void acpi_os_stall(u32 us)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
572
573
574
575
576
577
578
579
580
581
582
  {
  	while (us) {
  		u32 delay = 1000;
  
  		if (delay > us)
  			delay = us;
  		udelay(delay);
  		touch_nmi_watchdog();
  		us -= delay;
  	}
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
583

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
584
585
586
587
588
  /*
   * Support ACPI 3.0 AML Timer operand
   * Returns 64-bit free-running, monotonically increasing timer
   * with 100ns granularity
   */
4be44fcd3   Len Brown   [ACPI] Lindent al...
589
  u64 acpi_os_get_timer(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
  {
  	static u64 t;
  
  #ifdef	CONFIG_HPET
  	/* TBD: use HPET if available */
  #endif
  
  #ifdef	CONFIG_X86_PM_TIMER
  	/* TBD: default to PM timer if HPET was not available */
  #endif
  	if (!t)
  		printk(KERN_ERR PREFIX "acpi_os_get_timer() TBD
  ");
  
  	return ++t;
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
606
  acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
607
608
609
610
611
  {
  	u32 dummy;
  
  	if (!value)
  		value = &dummy;
49fbabf56   Zhao Yakui   ACPI: Handle I/O ...
612
613
  	*value = 0;
  	if (width <= 8) {
4be44fcd3   Len Brown   [ACPI] Lindent al...
614
  		*(u8 *) value = inb(port);
49fbabf56   Zhao Yakui   ACPI: Handle I/O ...
615
  	} else if (width <= 16) {
4be44fcd3   Len Brown   [ACPI] Lindent al...
616
  		*(u16 *) value = inw(port);
49fbabf56   Zhao Yakui   ACPI: Handle I/O ...
617
  	} else if (width <= 32) {
4be44fcd3   Len Brown   [ACPI] Lindent al...
618
  		*(u32 *) value = inl(port);
49fbabf56   Zhao Yakui   ACPI: Handle I/O ...
619
  	} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
620
621
622
623
624
  		BUG();
  	}
  
  	return AE_OK;
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
625

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
626
  EXPORT_SYMBOL(acpi_os_read_port);
4be44fcd3   Len Brown   [ACPI] Lindent al...
627
  acpi_status acpi_os_write_port(acpi_io_address port, u32 value, u32 width)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
628
  {
49fbabf56   Zhao Yakui   ACPI: Handle I/O ...
629
  	if (width <= 8) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
630
  		outb(value, port);
49fbabf56   Zhao Yakui   ACPI: Handle I/O ...
631
  	} else if (width <= 16) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
632
  		outw(value, port);
49fbabf56   Zhao Yakui   ACPI: Handle I/O ...
633
  	} else if (width <= 32) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
634
  		outl(value, port);
49fbabf56   Zhao Yakui   ACPI: Handle I/O ...
635
  	} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
636
637
638
639
640
  		BUG();
  	}
  
  	return AE_OK;
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
641

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
642
643
644
  EXPORT_SYMBOL(acpi_os_write_port);
  
  acpi_status
4be44fcd3   Len Brown   [ACPI] Lindent al...
645
  acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
646
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
647
  	void __iomem *virt_addr;
884b821fa   Rafael J. Wysocki   ACPI: Fix acpi_os...
648
649
650
  	unsigned int size = width / 8;
  	bool unmap = false;
  	u32 dummy;
620242ae8   Myron Stowe   ACPI: Maintain a ...
651

78cdb3ed4   Myron Stowe   ACPI: Convert sim...
652
  	rcu_read_lock();
620242ae8   Myron Stowe   ACPI: Maintain a ...
653
  	virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
620242ae8   Myron Stowe   ACPI: Maintain a ...
654
  	if (!virt_addr) {
884b821fa   Rafael J. Wysocki   ACPI: Fix acpi_os...
655
  		rcu_read_unlock();
2d6d9fd3a   Rafael J. Wysocki   ACPI: Introduce a...
656
  		virt_addr = acpi_os_ioremap(phys_addr, size);
884b821fa   Rafael J. Wysocki   ACPI: Fix acpi_os...
657
658
659
  		if (!virt_addr)
  			return AE_BAD_ADDRESS;
  		unmap = true;
620242ae8   Myron Stowe   ACPI: Maintain a ...
660
  	}
884b821fa   Rafael J. Wysocki   ACPI: Fix acpi_os...
661

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
662
663
664
665
666
  	if (!value)
  		value = &dummy;
  
  	switch (width) {
  	case 8:
4be44fcd3   Len Brown   [ACPI] Lindent al...
667
  		*(u8 *) value = readb(virt_addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
668
669
  		break;
  	case 16:
4be44fcd3   Len Brown   [ACPI] Lindent al...
670
  		*(u16 *) value = readw(virt_addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
671
672
  		break;
  	case 32:
4be44fcd3   Len Brown   [ACPI] Lindent al...
673
  		*(u32 *) value = readl(virt_addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
674
675
676
677
  		break;
  	default:
  		BUG();
  	}
620242ae8   Myron Stowe   ACPI: Maintain a ...
678
679
  	if (unmap)
  		iounmap(virt_addr);
884b821fa   Rafael J. Wysocki   ACPI: Fix acpi_os...
680
681
  	else
  		rcu_read_unlock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
682
683
684
685
686
  
  	return AE_OK;
  }
  
  acpi_status
4be44fcd3   Len Brown   [ACPI] Lindent al...
687
  acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
688
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
689
  	void __iomem *virt_addr;
884b821fa   Rafael J. Wysocki   ACPI: Fix acpi_os...
690
691
  	unsigned int size = width / 8;
  	bool unmap = false;
620242ae8   Myron Stowe   ACPI: Maintain a ...
692

78cdb3ed4   Myron Stowe   ACPI: Convert sim...
693
  	rcu_read_lock();
620242ae8   Myron Stowe   ACPI: Maintain a ...
694
  	virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
620242ae8   Myron Stowe   ACPI: Maintain a ...
695
  	if (!virt_addr) {
884b821fa   Rafael J. Wysocki   ACPI: Fix acpi_os...
696
  		rcu_read_unlock();
2d6d9fd3a   Rafael J. Wysocki   ACPI: Introduce a...
697
  		virt_addr = acpi_os_ioremap(phys_addr, size);
884b821fa   Rafael J. Wysocki   ACPI: Fix acpi_os...
698
699
700
  		if (!virt_addr)
  			return AE_BAD_ADDRESS;
  		unmap = true;
620242ae8   Myron Stowe   ACPI: Maintain a ...
701
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
702
703
704
705
706
707
708
709
710
711
712
713
714
715
  
  	switch (width) {
  	case 8:
  		writeb(value, virt_addr);
  		break;
  	case 16:
  		writew(value, virt_addr);
  		break;
  	case 32:
  		writel(value, virt_addr);
  		break;
  	default:
  		BUG();
  	}
620242ae8   Myron Stowe   ACPI: Maintain a ...
716
717
  	if (unmap)
  		iounmap(virt_addr);
884b821fa   Rafael J. Wysocki   ACPI: Fix acpi_os...
718
719
  	else
  		rcu_read_unlock();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
720
721
722
  
  	return AE_OK;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
723
  acpi_status
4be44fcd3   Len Brown   [ACPI] Lindent al...
724
  acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
c5f0231ee   Bob Moore   ACPICA: Fix acpi_...
725
  			       u64 *value, u32 width)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
726
727
  {
  	int result, size;
c5f0231ee   Bob Moore   ACPICA: Fix acpi_...
728
  	u32 value32;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
  
  	if (!value)
  		return AE_BAD_PARAMETER;
  
  	switch (width) {
  	case 8:
  		size = 1;
  		break;
  	case 16:
  		size = 2;
  		break;
  	case 32:
  		size = 4;
  		break;
  	default:
  		return AE_ERROR;
  	}
b6ce068a1   Matthew Wilcox   Change pci_raw_op...
746
747
  	result = raw_pci_read(pci_id->segment, pci_id->bus,
  				PCI_DEVFN(pci_id->device, pci_id->function),
c5f0231ee   Bob Moore   ACPICA: Fix acpi_...
748
749
  				reg, size, &value32);
  	*value = value32;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
750
751
752
  
  	return (result ? AE_ERROR : AE_OK);
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
753

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
754
  acpi_status
4be44fcd3   Len Brown   [ACPI] Lindent al...
755
  acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
439913fff   Lin Ming   ACPI: replace acp...
756
  				u64 value, u32 width)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
  {
  	int result, size;
  
  	switch (width) {
  	case 8:
  		size = 1;
  		break;
  	case 16:
  		size = 2;
  		break;
  	case 32:
  		size = 4;
  		break;
  	default:
  		return AE_ERROR;
  	}
b6ce068a1   Matthew Wilcox   Change pci_raw_op...
773
774
775
  	result = raw_pci_write(pci_id->segment, pci_id->bus,
  				PCI_DEVFN(pci_id->device, pci_id->function),
  				reg, size, value);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
776
777
778
  
  	return (result ? AE_ERROR : AE_OK);
  }
65f27f384   David Howells   WorkStruct: Pass ...
779
  static void acpi_os_execute_deferred(struct work_struct *work)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
780
  {
65f27f384   David Howells   WorkStruct: Pass ...
781
  	struct acpi_os_dpc *dpc = container_of(work, struct acpi_os_dpc, work);
88db5e148   Alexey Starikovskiy   ACPI: created a d...
782

9ac618566   Bjorn Helgaas   ACPI: simplify de...
783
784
  	if (dpc->wait)
  		acpi_os_wait_events_complete(NULL);
19cd847ab   Zhang Rui   ACPI: fix hotplug...
785
786
787
  
  	dpc->function(dpc->context);
  	kfree(dpc);
19cd847ab   Zhang Rui   ACPI: fix hotplug...
788
  }
b8d35192c   Alexey Starikovskiy   ACPI: execute Not...
789
790
791
792
793
794
795
796
797
798
799
800
801
802
  /*******************************************************************************
   *
   * FUNCTION:    acpi_os_execute
   *
   * PARAMETERS:  Type               - Type of the callback
   *              Function           - Function to be executed
   *              Context            - Function parameters
   *
   * RETURN:      Status
   *
   * DESCRIPTION: Depending on type, either queues function for deferred execution or
   *              immediately executes function on a separate thread.
   *
   ******************************************************************************/
19cd847ab   Zhang Rui   ACPI: fix hotplug...
803
804
  static acpi_status __acpi_os_execute(acpi_execute_type type,
  	acpi_osd_exec_callback function, void *context, int hp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
805
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
806
807
  	acpi_status status = AE_OK;
  	struct acpi_os_dpc *dpc;
17bc54eef   Alexey Starikovskiy   ACPI: Defer enabl...
808
  	struct workqueue_struct *queue;
19cd847ab   Zhang Rui   ACPI: fix hotplug...
809
  	int ret;
72945b2b9   Len Brown   [PATCH] Revert "A...
810
811
812
813
  	ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
  			  "Scheduling function [%p(%p)] for deferred execution.
  ",
  			  function, context));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
814

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
815
816
  	/*
  	 * Allocate/initialize DPC structure.  Note that this memory will be
65f27f384   David Howells   WorkStruct: Pass ...
817
  	 * freed by the callee.  The kernel handles the work_struct list  in a
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
818
819
820
  	 * way that allows us to also free its memory inside the callee.
  	 * Because we may want to schedule several tasks with different
  	 * parameters we can't use the approach some kernel code uses of
65f27f384   David Howells   WorkStruct: Pass ...
821
  	 * having a static work_struct.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
822
  	 */
72945b2b9   Len Brown   [PATCH] Revert "A...
823

65f27f384   David Howells   WorkStruct: Pass ...
824
  	dpc = kmalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
825
  	if (!dpc)
889c78be9   Lin Ming   ACPI: osl.c: repl...
826
  		return AE_NO_MEMORY;
b976fe19a   Linus Torvalds   Revert "ACPI: cre...
827

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
828
829
  	dpc->function = function;
  	dpc->context = context;
b976fe19a   Linus Torvalds   Revert "ACPI: cre...
830

c02256be7   Zhang Rui   ACPI: fix a deadl...
831
832
833
834
835
836
837
838
  	/*
  	 * We can't run hotplug code in keventd_wq/kacpid_wq/kacpid_notify_wq
  	 * because the hotplug code may call driver .remove() functions,
  	 * which invoke flush_scheduled_work/acpi_os_wait_events_complete
  	 * to flush these workqueues.
  	 */
  	queue = hp ? kacpi_hotplug_wq :
  		(type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq);
9ac618566   Bjorn Helgaas   ACPI: simplify de...
839
  	dpc->wait = hp ? 1 : 0;
bc73675b9   Zhang Rui   ACPI: fixes a fal...
840
841
842
843
844
845
846
  
  	if (queue == kacpi_hotplug_wq)
  		INIT_WORK(&dpc->work, acpi_os_execute_deferred);
  	else if (queue == kacpi_notify_wq)
  		INIT_WORK(&dpc->work, acpi_os_execute_deferred);
  	else
  		INIT_WORK(&dpc->work, acpi_os_execute_deferred);
8fec62b2d   Tejun Heo   acpi: use queue_w...
847
848
849
850
851
852
853
854
  	/*
  	 * On some machines, a software-initiated SMI causes corruption unless
  	 * the SMI runs on CPU 0.  An SMI can be initiated by any AML, but
  	 * typically it's done in GPE-related methods that are run via
  	 * workqueues, so we can avoid the known corruption cases by always
  	 * queueing on CPU 0.
  	 */
  	ret = queue_work_on(0, queue, &dpc->work);
19cd847ab   Zhang Rui   ACPI: fix hotplug...
855
856
  
  	if (!ret) {
55ac9a018   Lin Ming   ACPI: replace ACP...
857
858
859
  		printk(KERN_ERR PREFIX
  			  "Call to queue_work() failed.
  ");
17bc54eef   Alexey Starikovskiy   ACPI: Defer enabl...
860
861
  		status = AE_ERROR;
  		kfree(dpc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
862
  	}
889c78be9   Lin Ming   ACPI: osl.c: repl...
863
  	return status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
864
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
865

19cd847ab   Zhang Rui   ACPI: fix hotplug...
866
867
868
869
870
  acpi_status acpi_os_execute(acpi_execute_type type,
  			    acpi_osd_exec_callback function, void *context)
  {
  	return __acpi_os_execute(type, function, context, 0);
  }
b8d35192c   Alexey Starikovskiy   ACPI: execute Not...
871
  EXPORT_SYMBOL(acpi_os_execute);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
872

19cd847ab   Zhang Rui   ACPI: fix hotplug...
873
874
875
876
877
  acpi_status acpi_os_hotplug_execute(acpi_osd_exec_callback function,
  	void *context)
  {
  	return __acpi_os_execute(0, function, context, 1);
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
878
  void acpi_os_wait_events_complete(void *context)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
879
880
  {
  	flush_workqueue(kacpid_wq);
2f67a0695   Zhang Rui   flush kacpi_notif...
881
  	flush_workqueue(kacpi_notify_wq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
882
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
883

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
884
  EXPORT_SYMBOL(acpi_os_wait_events_complete);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
885
  acpi_status
4be44fcd3   Len Brown   [ACPI] Lindent al...
886
  acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
887
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
888
  	struct semaphore *sem = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
889

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
890
891
  	sem = acpi_os_allocate(sizeof(struct semaphore));
  	if (!sem)
d550d98d3   Patrick Mochel   ACPI: delete trac...
892
  		return AE_NO_MEMORY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
893
894
895
  	memset(sem, 0, sizeof(struct semaphore));
  
  	sema_init(sem, initial_units);
4be44fcd3   Len Brown   [ACPI] Lindent al...
896
  	*handle = (acpi_handle *) sem;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
897

4be44fcd3   Len Brown   [ACPI] Lindent al...
898
899
900
  	ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Creating semaphore[%p|%d].
  ",
  			  *handle, initial_units));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
901

d550d98d3   Patrick Mochel   ACPI: delete trac...
902
  	return AE_OK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
903
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
904

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
905
906
907
908
909
910
  /*
   * TODO: A better way to delete semaphores?  Linux doesn't have a
   * 'delete_semaphore()' function -- may result in an invalid
   * pointer dereference for non-synchronized consumers.	Should
   * we at least check for blocked threads and signal/cancel them?
   */
4be44fcd3   Len Brown   [ACPI] Lindent al...
911
  acpi_status acpi_os_delete_semaphore(acpi_handle handle)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
912
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
913
  	struct semaphore *sem = (struct semaphore *)handle;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
914

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
915
  	if (!sem)
d550d98d3   Patrick Mochel   ACPI: delete trac...
916
  		return AE_BAD_PARAMETER;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
917

4be44fcd3   Len Brown   [ACPI] Lindent al...
918
919
  	ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Deleting semaphore[%p].
  ", handle));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
920

f1241c87a   Matthew Wilcox   Add down_timeout ...
921
  	BUG_ON(!list_empty(&sem->wait_list));
02438d877   Len Brown   ACPI: delete acpi...
922
  	kfree(sem);
4be44fcd3   Len Brown   [ACPI] Lindent al...
923
  	sem = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
924

d550d98d3   Patrick Mochel   ACPI: delete trac...
925
  	return AE_OK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
926
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
927

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
928
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
929
930
   * TODO: Support for units > 1?
   */
4be44fcd3   Len Brown   [ACPI] Lindent al...
931
  acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
932
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
933
934
  	acpi_status status = AE_OK;
  	struct semaphore *sem = (struct semaphore *)handle;
f1241c87a   Matthew Wilcox   Add down_timeout ...
935
  	long jiffies;
4be44fcd3   Len Brown   [ACPI] Lindent al...
936
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
937

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
938
  	if (!sem || (units < 1))
d550d98d3   Patrick Mochel   ACPI: delete trac...
939
  		return AE_BAD_PARAMETER;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
940
941
  
  	if (units > 1)
d550d98d3   Patrick Mochel   ACPI: delete trac...
942
  		return AE_SUPPORT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
943

4be44fcd3   Len Brown   [ACPI] Lindent al...
944
945
946
  	ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]
  ",
  			  handle, units, timeout));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
947

f1241c87a   Matthew Wilcox   Add down_timeout ...
948
949
950
951
952
953
954
955
  	if (timeout == ACPI_WAIT_FOREVER)
  		jiffies = MAX_SCHEDULE_TIMEOUT;
  	else
  		jiffies = msecs_to_jiffies(timeout);
  	
  	ret = down_timeout(sem, jiffies);
  	if (ret)
  		status = AE_TIME;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
956
957
  
  	if (ACPI_FAILURE(status)) {
9e7e2c047   Bjorn Helgaas   ACPI: acpi_os_wai...
958
  		ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
a6fc67202   Thomas Renninger   ACPI: Enable ACPI...
959
  				  "Failed to acquire semaphore[%p|%d|%d], %s",
4be44fcd3   Len Brown   [ACPI] Lindent al...
960
961
962
963
  				  handle, units, timeout,
  				  acpi_format_exception(status)));
  	} else {
  		ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
a6fc67202   Thomas Renninger   ACPI: Enable ACPI...
964
  				  "Acquired semaphore[%p|%d|%d]", handle,
4be44fcd3   Len Brown   [ACPI] Lindent al...
965
  				  units, timeout));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
966
  	}
d550d98d3   Patrick Mochel   ACPI: delete trac...
967
  	return status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
968
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
969

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
970
971
972
  /*
   * TODO: Support for units > 1?
   */
4be44fcd3   Len Brown   [ACPI] Lindent al...
973
  acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
974
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
975
  	struct semaphore *sem = (struct semaphore *)handle;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
976

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
977
  	if (!sem || (units < 1))
d550d98d3   Patrick Mochel   ACPI: delete trac...
978
  		return AE_BAD_PARAMETER;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
979
980
  
  	if (units > 1)
d550d98d3   Patrick Mochel   ACPI: delete trac...
981
  		return AE_SUPPORT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
982

4be44fcd3   Len Brown   [ACPI] Lindent al...
983
984
985
  	ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Signaling semaphore[%p|%d]
  ", handle,
  			  units));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
986
987
  
  	up(sem);
d550d98d3   Patrick Mochel   ACPI: delete trac...
988
  	return AE_OK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
989
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
990

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
991
  #ifdef ACPI_FUTURE_USAGE
4be44fcd3   Len Brown   [ACPI] Lindent al...
992
  u32 acpi_os_get_line(char *buffer)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
  {
  
  #ifdef ENABLE_DEBUGGER
  	if (acpi_in_debugger) {
  		u32 chars;
  
  		kdb_read(buffer, sizeof(line_buf));
  
  		/* remove the CR kdb includes */
  		chars = strlen(buffer) - 1;
  		buffer[chars] = '\0';
  	}
  #endif
  
  	return 0;
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
1009
  #endif				/*  ACPI_FUTURE_USAGE  */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1010

4be44fcd3   Len Brown   [ACPI] Lindent al...
1011
  acpi_status acpi_os_signal(u32 function, void *info)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1012
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
1013
  	switch (function) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
  	case ACPI_SIGNAL_FATAL:
  		printk(KERN_ERR PREFIX "Fatal opcode executed
  ");
  		break;
  	case ACPI_SIGNAL_BREAKPOINT:
  		/*
  		 * AML Breakpoint
  		 * ACPI spec. says to treat it as a NOP unless
  		 * you are debugging.  So if/when we integrate
  		 * AML debugger into the kernel debugger its
  		 * hook will go here.  But until then it is
  		 * not useful to print anything on breakpoints.
  		 */
  		break;
  	default:
  		break;
  	}
  
  	return AE_OK;
  }
4be44fcd3   Len Brown   [ACPI] Lindent al...
1034

4be44fcd3   Len Brown   [ACPI] Lindent al...
1035
  static int __init acpi_os_name_setup(char *str)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1036
1037
  {
  	char *p = acpi_os_name;
4be44fcd3   Len Brown   [ACPI] Lindent al...
1038
  	int count = ACPI_MAX_OVERRIDE_LEN - 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
  
  	if (!str || !*str)
  		return 0;
  
  	for (; count-- && str && *str; str++) {
  		if (isalnum(*str) || *str == ' ' || *str == ':')
  			*p++ = *str;
  		else if (*str == '\'' || *str == '"')
  			continue;
  		else
  			break;
  	}
  	*p = 0;
  
  	return 1;
4be44fcd3   Len Brown   [ACPI] Lindent al...
1054

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1055
1056
1057
  }
  
  __setup("acpi_os_name=", acpi_os_name_setup);
12d320646   Lin Ming   ACPI: fix allowin...
1058
1059
1060
1061
1062
1063
1064
  #define	OSI_STRING_LENGTH_MAX 64	/* arbitrary */
  #define	OSI_STRING_ENTRIES_MAX 16	/* arbitrary */
  
  struct osi_setup_entry {
  	char string[OSI_STRING_LENGTH_MAX];
  	bool enable;
  };
aa165971c   Shaohua Li   ACPI: add missing...
1065
1066
1067
1068
1069
1070
1071
  static struct osi_setup_entry __initdata
  		osi_setup_entries[OSI_STRING_ENTRIES_MAX] = {
  	{"Module Device", true},
  	{"Processor Device", true},
  	{"3.0 _SCP Extensions", true},
  	{"Processor Aggregator Device", true},
  };
12d320646   Lin Ming   ACPI: fix allowin...
1072

d90aa92c0   Lin Ming   acpi: fix _OSI st...
1073
1074
  void __init acpi_osi_setup(char *str)
  {
12d320646   Lin Ming   ACPI: fix allowin...
1075
1076
1077
  	struct osi_setup_entry *osi;
  	bool enable = true;
  	int i;
d90aa92c0   Lin Ming   acpi: fix _OSI st...
1078
1079
1080
1081
1082
1083
1084
  	if (!acpi_gbl_create_osi_method)
  		return;
  
  	if (str == NULL || *str == '\0') {
  		printk(KERN_INFO PREFIX "_OSI method disabled
  ");
  		acpi_gbl_create_osi_method = FALSE;
12d320646   Lin Ming   ACPI: fix allowin...
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
  		return;
  	}
  
  	if (*str == '!') {
  		str++;
  		enable = false;
  	}
  
  	for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
  		osi = &osi_setup_entries[i];
  		if (!strcmp(osi->string, str)) {
  			osi->enable = enable;
  			break;
  		} else if (osi->string[0] == '\0') {
  			osi->enable = enable;
  			strncpy(osi->string, str, OSI_STRING_LENGTH_MAX);
  			break;
  		}
  	}
d90aa92c0   Lin Ming   acpi: fix _OSI st...
1104
  }
d4b7dc499   Len Brown   ACPI: make _OSI(L...
1105
1106
  static void __init set_osi_linux(unsigned int enable)
  {
d90aa92c0   Lin Ming   acpi: fix _OSI st...
1107
  	if (osi_linux.enable != enable)
d4b7dc499   Len Brown   ACPI: make _OSI(L...
1108
  		osi_linux.enable = enable;
b0ed7a915   Lin Ming   ACPICA/ACPI: Add ...
1109
1110
1111
1112
1113
  
  	if (osi_linux.enable)
  		acpi_osi_setup("Linux");
  	else
  		acpi_osi_setup("!Linux");
d4b7dc499   Len Brown   ACPI: make _OSI(L...
1114
1115
1116
1117
1118
  	return;
  }
  
  static void __init acpi_cmdline_osi_linux(unsigned int enable)
  {
d90aa92c0   Lin Ming   acpi: fix _OSI st...
1119
1120
  	osi_linux.cmdline = 1;	/* cmdline set the default and override DMI */
  	osi_linux.dmi = 0;
d4b7dc499   Len Brown   ACPI: make _OSI(L...
1121
1122
1123
1124
1125
1126
1127
  	set_osi_linux(enable);
  
  	return;
  }
  
  void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
  {
d4b7dc499   Len Brown   ACPI: make _OSI(L...
1128
1129
1130
1131
1132
  	printk(KERN_NOTICE PREFIX "DMI detected: %s
  ", d->ident);
  
  	if (enable == -1)
  		return;
d90aa92c0   Lin Ming   acpi: fix _OSI st...
1133
  	osi_linux.dmi = 1;	/* DMI knows that this box asks OSI(Linux) */
d4b7dc499   Len Brown   ACPI: make _OSI(L...
1134
  	set_osi_linux(enable);
f507654d4   Len Brown   ACPI: Make _OSI(L...
1135

f507654d4   Len Brown   ACPI: Make _OSI(L...
1136
1137
  	return;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1138
  /*
ae00d8124   Len Brown   ACPI: extend "acp...
1139
1140
   * Modify the list of "OS Interfaces" reported to BIOS via _OSI
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1141
   * empty string disables _OSI
ae00d8124   Len Brown   ACPI: extend "acp...
1142
1143
   * string starting with '!' disables that string
   * otherwise string is added to list, augmenting built-in strings
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1144
   */
b0ed7a915   Lin Ming   ACPICA/ACPI: Add ...
1145
  static void __init acpi_osi_setup_late(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1146
  {
12d320646   Lin Ming   ACPI: fix allowin...
1147
1148
1149
  	struct osi_setup_entry *osi;
  	char *str;
  	int i;
d90aa92c0   Lin Ming   acpi: fix _OSI st...
1150
  	acpi_status status;
b0ed7a915   Lin Ming   ACPICA/ACPI: Add ...
1151

12d320646   Lin Ming   ACPI: fix allowin...
1152
1153
1154
  	for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
  		osi = &osi_setup_entries[i];
  		str = osi->string;
b0ed7a915   Lin Ming   ACPICA/ACPI: Add ...
1155

12d320646   Lin Ming   ACPI: fix allowin...
1156
1157
1158
1159
  		if (*str == '\0')
  			break;
  		if (osi->enable) {
  			status = acpi_install_interface(str);
d90aa92c0   Lin Ming   acpi: fix _OSI st...
1160

12d320646   Lin Ming   ACPI: fix allowin...
1161
1162
1163
1164
1165
  			if (ACPI_SUCCESS(status))
  				printk(KERN_INFO PREFIX "Added _OSI(%s)
  ", str);
  		} else {
  			status = acpi_remove_interface(str);
d90aa92c0   Lin Ming   acpi: fix _OSI st...
1166

12d320646   Lin Ming   ACPI: fix allowin...
1167
1168
1169
1170
  			if (ACPI_SUCCESS(status))
  				printk(KERN_INFO PREFIX "Deleted _OSI(%s)
  ", str);
  		}
b0ed7a915   Lin Ming   ACPICA/ACPI: Add ...
1171
1172
  	}
  }
d90aa92c0   Lin Ming   acpi: fix _OSI st...
1173
  static int __init osi_setup(char *str)
b0ed7a915   Lin Ming   ACPICA/ACPI: Add ...
1174
  {
d90aa92c0   Lin Ming   acpi: fix _OSI st...
1175
1176
1177
1178
1179
1180
  	if (str && !strcmp("Linux", str))
  		acpi_cmdline_osi_linux(1);
  	else if (str && !strcmp("!Linux", str))
  		acpi_cmdline_osi_linux(0);
  	else
  		acpi_osi_setup(str);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1181
1182
1183
  
  	return 1;
  }
d90aa92c0   Lin Ming   acpi: fix _OSI st...
1184
  __setup("acpi_osi=", osi_setup);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1185
1186
  
  /* enable serialization to combat AE_ALREADY_EXISTS errors */
4be44fcd3   Len Brown   [ACPI] Lindent al...
1187
  static int __init acpi_serialize_setup(char *str)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
  {
  	printk(KERN_INFO PREFIX "serialize enabled
  ");
  
  	acpi_gbl_all_methods_serialized = TRUE;
  
  	return 1;
  }
  
  __setup("acpi_serialize", acpi_serialize_setup);
df92e6959   Thomas Renninger   ACPI: track opreg...
1198
1199
1200
1201
1202
1203
  /* Check of resource interference between native drivers and ACPI
   * OperationRegions (SystemIO and System Memory only).
   * IO ports and memory declared in ACPI might be used by the ACPI subsystem
   * in arbitrary AML code and can interfere with legacy drivers.
   * acpi_enforce_resources= can be set to:
   *
7e90560c5   Luca Tettamanti   ACPI: acpi_enforc...
1204
   *   - strict (default) (2)
df92e6959   Thomas Renninger   ACPI: track opreg...
1205
   *     -> further driver trying to access the resources will not load
7e90560c5   Luca Tettamanti   ACPI: acpi_enforc...
1206
   *   - lax              (1)
df92e6959   Thomas Renninger   ACPI: track opreg...
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
   *     -> further driver trying to access the resources will load, but you
   *     get a system message that something might go wrong...
   *
   *   - no               (0)
   *     -> ACPI Operation Region resources will not be registered
   *
   */
  #define ENFORCE_RESOURCES_STRICT 2
  #define ENFORCE_RESOURCES_LAX    1
  #define ENFORCE_RESOURCES_NO     0
7e90560c5   Luca Tettamanti   ACPI: acpi_enforc...
1217
  static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_STRICT;
df92e6959   Thomas Renninger   ACPI: track opreg...
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
  
  static int __init acpi_enforce_resources_setup(char *str)
  {
  	if (str == NULL || *str == '\0')
  		return 0;
  
  	if (!strcmp("strict", str))
  		acpi_enforce_resources = ENFORCE_RESOURCES_STRICT;
  	else if (!strcmp("lax", str))
  		acpi_enforce_resources = ENFORCE_RESOURCES_LAX;
  	else if (!strcmp("no", str))
  		acpi_enforce_resources = ENFORCE_RESOURCES_NO;
  
  	return 1;
  }
  
  __setup("acpi_enforce_resources=", acpi_enforce_resources_setup);
  
  /* Check for resource conflicts between ACPI OperationRegions and native
   * drivers */
876fba43c   Jean Delvare   ACPI: add const t...
1238
  int acpi_check_resource_conflict(const struct resource *res)
df92e6959   Thomas Renninger   ACPI: track opreg...
1239
1240
  {
  	struct acpi_res_list *res_list_elem;
106d1a0ab   Thomas Renninger   ACPI: fix resourc...
1241
  	int ioport = 0, clash = 0;
df92e6959   Thomas Renninger   ACPI: track opreg...
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
  
  	if (acpi_enforce_resources == ENFORCE_RESOURCES_NO)
  		return 0;
  	if (!(res->flags & IORESOURCE_IO) && !(res->flags & IORESOURCE_MEM))
  		return 0;
  
  	ioport = res->flags & IORESOURCE_IO;
  
  	spin_lock(&acpi_res_lock);
  	list_for_each_entry(res_list_elem, &resource_list_head,
  			    resource_list) {
  		if (ioport && (res_list_elem->resource_type
  			       != ACPI_ADR_SPACE_SYSTEM_IO))
  			continue;
  		if (!ioport && (res_list_elem->resource_type
  				!= ACPI_ADR_SPACE_SYSTEM_MEMORY))
  			continue;
  
  		if (res->end < res_list_elem->start
  		    || res_list_elem->end < res->start)
  			continue;
  		clash = 1;
  		break;
  	}
  	spin_unlock(&acpi_res_lock);
  
  	if (clash) {
  		if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) {
1638bca89   Chase Douglas   ACPI: Reduce ACPI...
1270
  			printk(KERN_WARNING "ACPI: resource %s %pR"
106d1a0ab   Thomas Renninger   ACPI: fix resourc...
1271
1272
1273
  			       " conflicts with ACPI region %s "
  			       "[%s 0x%zx-0x%zx]
  ",
1638bca89   Chase Douglas   ACPI: Reduce ACPI...
1274
  			       res->name, res, res_list_elem->name,
106d1a0ab   Thomas Renninger   ACPI: fix resourc...
1275
1276
1277
1278
  			       (res_list_elem->resource_type ==
  				ACPI_ADR_SPACE_SYSTEM_IO) ? "io" : "mem",
  			       (size_t) res_list_elem->start,
  			       (size_t) res_list_elem->end);
14f03343a   Jean Delvare   ACPI: Clarify res...
1279
1280
1281
1282
1283
1284
1285
1286
1287
  			if (acpi_enforce_resources == ENFORCE_RESOURCES_LAX)
  				printk(KERN_NOTICE "ACPI: This conflict may"
  				       " cause random problems and system"
  				       " instability
  ");
  			printk(KERN_INFO "ACPI: If an ACPI driver is available"
  			       " for this device, you should use it instead of"
  			       " the native driver
  ");
df92e6959   Thomas Renninger   ACPI: track opreg...
1288
1289
1290
1291
1292
1293
  		}
  		if (acpi_enforce_resources == ENFORCE_RESOURCES_STRICT)
  			return -EBUSY;
  	}
  	return 0;
  }
443dea72d   Thomas Renninger   ACPI: Export acpi...
1294
  EXPORT_SYMBOL(acpi_check_resource_conflict);
df92e6959   Thomas Renninger   ACPI: track opreg...
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
  
  int acpi_check_region(resource_size_t start, resource_size_t n,
  		      const char *name)
  {
  	struct resource res = {
  		.start = start,
  		.end   = start + n - 1,
  		.name  = name,
  		.flags = IORESOURCE_IO,
  	};
  
  	return acpi_check_resource_conflict(&res);
  }
  EXPORT_SYMBOL(acpi_check_region);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1309
  /*
70dd6beac   Jean Delvare   hwmon: (asus_atk0...
1310
1311
1312
1313
1314
1315
1316
1317
1318
   * Let drivers know whether the resource checks are effective
   */
  int acpi_resources_are_enforced(void)
  {
  	return acpi_enforce_resources == ENFORCE_RESOURCES_STRICT;
  }
  EXPORT_SYMBOL(acpi_resources_are_enforced);
  
  /*
9f63b88bd   Lin Ming   ACPI: osl, add ac...
1319
1320
1321
1322
1323
1324
1325
1326
   * Deallocate the memory for a spinlock.
   */
  void acpi_os_delete_lock(acpi_spinlock handle)
  {
  	ACPI_FREE(handle);
  }
  
  /*
73459f73e   Robert Moore   ACPICA 20050617-0...
1327
1328
1329
   * Acquire a spinlock.
   *
   * handle is a pointer to the spinlock_t.
73459f73e   Robert Moore   ACPICA 20050617-0...
1330
   */
967440e3b   Bob Moore   ACPI: ACPICA 2006...
1331
  acpi_cpu_flags acpi_os_acquire_lock(acpi_spinlock lockp)
73459f73e   Robert Moore   ACPICA 20050617-0...
1332
  {
b8e4d8935   Bob Moore   [ACPI] ACPICA 200...
1333
  	acpi_cpu_flags flags;
967440e3b   Bob Moore   ACPI: ACPICA 2006...
1334
  	spin_lock_irqsave(lockp, flags);
73459f73e   Robert Moore   ACPICA 20050617-0...
1335
1336
1337
1338
1339
1340
  	return flags;
  }
  
  /*
   * Release a spinlock. See above.
   */
967440e3b   Bob Moore   ACPI: ACPICA 2006...
1341
  void acpi_os_release_lock(acpi_spinlock lockp, acpi_cpu_flags flags)
73459f73e   Robert Moore   ACPICA 20050617-0...
1342
  {
967440e3b   Bob Moore   ACPI: ACPICA 2006...
1343
  	spin_unlock_irqrestore(lockp, flags);
73459f73e   Robert Moore   ACPICA 20050617-0...
1344
  }
73459f73e   Robert Moore   ACPICA 20050617-0...
1345
1346
1347
1348
1349
1350
  #ifndef ACPI_USE_LOCAL_CACHE
  
  /*******************************************************************************
   *
   * FUNCTION:    acpi_os_create_cache
   *
b229cf92e   Bob Moore   ACPI: ACPICA 2006...
1351
1352
1353
1354
   * PARAMETERS:  name      - Ascii name for the cache
   *              size      - Size of each cached object
   *              depth     - Maximum depth of the cache (in objects) <ignored>
   *              cache     - Where the new cache object is returned
73459f73e   Robert Moore   ACPICA 20050617-0...
1355
   *
b229cf92e   Bob Moore   ACPI: ACPICA 2006...
1356
   * RETURN:      status
73459f73e   Robert Moore   ACPICA 20050617-0...
1357
1358
1359
1360
1361
1362
   *
   * DESCRIPTION: Create a cache object
   *
   ******************************************************************************/
  
  acpi_status
4be44fcd3   Len Brown   [ACPI] Lindent al...
1363
  acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache)
73459f73e   Robert Moore   ACPICA 20050617-0...
1364
  {
20c2df83d   Paul Mundt   mm: Remove slab d...
1365
  	*cache = kmem_cache_create(name, size, 0, 0, NULL);
a6fdbf90b   Adrian Bunk   ACPI: fix NULL ch...
1366
  	if (*cache == NULL)
b229cf92e   Bob Moore   ACPI: ACPICA 2006...
1367
1368
1369
  		return AE_ERROR;
  	else
  		return AE_OK;
73459f73e   Robert Moore   ACPICA 20050617-0...
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
  }
  
  /*******************************************************************************
   *
   * FUNCTION:    acpi_os_purge_cache
   *
   * PARAMETERS:  Cache           - Handle to cache object
   *
   * RETURN:      Status
   *
   * DESCRIPTION: Free all objects within the requested cache.
   *
   ******************************************************************************/
4be44fcd3   Len Brown   [ACPI] Lindent al...
1383
  acpi_status acpi_os_purge_cache(acpi_cache_t * cache)
73459f73e   Robert Moore   ACPICA 20050617-0...
1384
  {
50dd09697   Jan Engelhardt   ACPI: Remove unne...
1385
  	kmem_cache_shrink(cache);
4be44fcd3   Len Brown   [ACPI] Lindent al...
1386
  	return (AE_OK);
73459f73e   Robert Moore   ACPICA 20050617-0...
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
  }
  
  /*******************************************************************************
   *
   * FUNCTION:    acpi_os_delete_cache
   *
   * PARAMETERS:  Cache           - Handle to cache object
   *
   * RETURN:      Status
   *
   * DESCRIPTION: Free all objects within the requested cache and delete the
   *              cache object.
   *
   ******************************************************************************/
4be44fcd3   Len Brown   [ACPI] Lindent al...
1401
  acpi_status acpi_os_delete_cache(acpi_cache_t * cache)
73459f73e   Robert Moore   ACPICA 20050617-0...
1402
  {
1a1d92c10   Alexey Dobriyan   [PATCH] Really ig...
1403
  	kmem_cache_destroy(cache);
4be44fcd3   Len Brown   [ACPI] Lindent al...
1404
  	return (AE_OK);
73459f73e   Robert Moore   ACPICA 20050617-0...
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
  }
  
  /*******************************************************************************
   *
   * FUNCTION:    acpi_os_release_object
   *
   * PARAMETERS:  Cache       - Handle to cache object
   *              Object      - The object to be released
   *
   * RETURN:      None
   *
   * DESCRIPTION: Release an object to the specified cache.  If cache is full,
   *              the object is deleted.
   *
   ******************************************************************************/
4be44fcd3   Len Brown   [ACPI] Lindent al...
1420
  acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
73459f73e   Robert Moore   ACPICA 20050617-0...
1421
  {
4be44fcd3   Len Brown   [ACPI] Lindent al...
1422
1423
  	kmem_cache_free(cache, object);
  	return (AE_OK);
73459f73e   Robert Moore   ACPICA 20050617-0...
1424
  }
a5fe1a03f   Lin Ming   ACPICA: fix leak ...
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
  static inline int acpi_res_list_add(struct acpi_res_list *res)
  {
  	struct acpi_res_list *res_list_elem;
  
  	list_for_each_entry(res_list_elem, &resource_list_head,
  			    resource_list) {
  
  		if (res->resource_type == res_list_elem->resource_type &&
  		    res->start == res_list_elem->start &&
  		    res->end == res_list_elem->end) {
  
  			/*
  			 * The Region(addr,len) already exist in the list,
  			 * just increase the count
  			 */
  
  			res_list_elem->count++;
  			return 0;
  		}
  	}
  
  	res->count = 1;
  	list_add(&res->resource_list, &resource_list_head);
  	return 1;
  }
  
  static inline void acpi_res_list_del(struct acpi_res_list *res)
  {
  	struct acpi_res_list *res_list_elem;
  
  	list_for_each_entry(res_list_elem, &resource_list_head,
  			    resource_list) {
  
  		if (res->resource_type == res_list_elem->resource_type &&
  		    res->start == res_list_elem->start &&
  		    res->end == res_list_elem->end) {
  
  			/*
  			 * If the res count is decreased to 0,
  			 * remove and free it
  			 */
  
  			if (--res_list_elem->count == 0) {
  				list_del(&res_list_elem->resource_list);
  				kfree(res_list_elem);
  			}
  			return;
  		}
  	}
  }
  
  acpi_status
  acpi_os_invalidate_address(
      u8                   space_id,
      acpi_physical_address   address,
      acpi_size               length)
  {
  	struct acpi_res_list res;
  
  	switch (space_id) {
  	case ACPI_ADR_SPACE_SYSTEM_IO:
  	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
883931612   Thomas Weber   Fix typos in comm...
1487
  		/* Only interference checks against SystemIO and SystemMemory
a5fe1a03f   Lin Ming   ACPICA: fix leak ...
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
  		   are needed */
  		res.start = address;
  		res.end = address + length - 1;
  		res.resource_type = space_id;
  		spin_lock(&acpi_res_lock);
  		acpi_res_list_del(&res);
  		spin_unlock(&acpi_res_lock);
  		break;
  	case ACPI_ADR_SPACE_PCI_CONFIG:
  	case ACPI_ADR_SPACE_EC:
  	case ACPI_ADR_SPACE_SMBUS:
  	case ACPI_ADR_SPACE_CMOS:
  	case ACPI_ADR_SPACE_PCI_BAR_TARGET:
  	case ACPI_ADR_SPACE_DATA_TABLE:
  	case ACPI_ADR_SPACE_FIXED_HARDWARE:
  		break;
  	}
  	return AE_OK;
  }
b229cf92e   Bob Moore   ACPI: ACPICA 2006...
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
  /******************************************************************************
   *
   * FUNCTION:    acpi_os_validate_address
   *
   * PARAMETERS:  space_id             - ACPI space ID
   *              address             - Physical address
   *              length              - Address length
   *
   * RETURN:      AE_OK if address/length is valid for the space_id. Otherwise,
   *              should return AE_AML_ILLEGAL_ADDRESS.
   *
   * DESCRIPTION: Validate a system address via the host OS. Used to validate
   *              the addresses accessed by AML operation regions.
   *
   *****************************************************************************/
  
  acpi_status
  acpi_os_validate_address (
      u8                   space_id,
      acpi_physical_address   address,
df92e6959   Thomas Renninger   ACPI: track opreg...
1527
1528
      acpi_size               length,
      char *name)
b229cf92e   Bob Moore   ACPI: ACPICA 2006...
1529
  {
df92e6959   Thomas Renninger   ACPI: track opreg...
1530
  	struct acpi_res_list *res;
a5fe1a03f   Lin Ming   ACPICA: fix leak ...
1531
  	int added;
df92e6959   Thomas Renninger   ACPI: track opreg...
1532
1533
  	if (acpi_enforce_resources == ENFORCE_RESOURCES_NO)
  		return AE_OK;
b229cf92e   Bob Moore   ACPI: ACPICA 2006...
1534

df92e6959   Thomas Renninger   ACPI: track opreg...
1535
1536
1537
  	switch (space_id) {
  	case ACPI_ADR_SPACE_SYSTEM_IO:
  	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
883931612   Thomas Weber   Fix typos in comm...
1538
  		/* Only interference checks against SystemIO and SystemMemory
df92e6959   Thomas Renninger   ACPI: track opreg...
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
  		   are needed */
  		res = kzalloc(sizeof(struct acpi_res_list), GFP_KERNEL);
  		if (!res)
  			return AE_OK;
  		/* ACPI names are fixed to 4 bytes, still better use strlcpy */
  		strlcpy(res->name, name, 5);
  		res->start = address;
  		res->end = address + length - 1;
  		res->resource_type = space_id;
  		spin_lock(&acpi_res_lock);
a5fe1a03f   Lin Ming   ACPICA: fix leak ...
1549
  		added = acpi_res_list_add(res);
df92e6959   Thomas Renninger   ACPI: track opreg...
1550
  		spin_unlock(&acpi_res_lock);
a5fe1a03f   Lin Ming   ACPICA: fix leak ...
1551
1552
1553
1554
  		pr_debug("%s %s resource: start: 0x%llx, end: 0x%llx, "
  			 "name: %s
  ", added ? "Added" : "Already exist",
  			 (space_id == ACPI_ADR_SPACE_SYSTEM_IO)
df92e6959   Thomas Renninger   ACPI: track opreg...
1555
1556
1557
1558
  			 ? "SystemIO" : "System Memory",
  			 (unsigned long long)res->start,
  			 (unsigned long long)res->end,
  			 res->name);
a5fe1a03f   Lin Ming   ACPICA: fix leak ...
1559
1560
  		if (!added)
  			kfree(res);
df92e6959   Thomas Renninger   ACPI: track opreg...
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
  		break;
  	case ACPI_ADR_SPACE_PCI_CONFIG:
  	case ACPI_ADR_SPACE_EC:
  	case ACPI_ADR_SPACE_SMBUS:
  	case ACPI_ADR_SPACE_CMOS:
  	case ACPI_ADR_SPACE_PCI_BAR_TARGET:
  	case ACPI_ADR_SPACE_DATA_TABLE:
  	case ACPI_ADR_SPACE_FIXED_HARDWARE:
  		break;
  	}
  	return AE_OK;
b229cf92e   Bob Moore   ACPI: ACPICA 2006...
1572
  }
73459f73e   Robert Moore   ACPICA 20050617-0...
1573
  #endif
d362edaf5   Myron Stowe   ACPI: Pre-map 'sy...
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
  
  acpi_status __init acpi_os_initialize(void)
  {
  	acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1a_event_block);
  	acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1b_event_block);
  	acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe0_block);
  	acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe1_block);
  
  	return AE_OK;
  }
32d47eeff   Zhang Rui   ACPI: fix a secti...
1584
  acpi_status __init acpi_os_initialize1(void)
d362edaf5   Myron Stowe   ACPI: Pre-map 'sy...
1585
  {
44d2588e1   Tejun Heo   acpi: kacpi*_wq d...
1586
1587
1588
  	kacpid_wq = alloc_workqueue("kacpid", 0, 1);
  	kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1);
  	kacpi_hotplug_wq = alloc_workqueue("kacpi_hotplug", 0, 1);
d362edaf5   Myron Stowe   ACPI: Pre-map 'sy...
1589
1590
1591
  	BUG_ON(!kacpid_wq);
  	BUG_ON(!kacpi_notify_wq);
  	BUG_ON(!kacpi_hotplug_wq);
1bd64d42a   Len Brown   Merge branch 'acp...
1592
1593
  	acpi_install_interface_handler(acpi_osi_handler);
  	acpi_osi_setup_late();
d362edaf5   Myron Stowe   ACPI: Pre-map 'sy...
1594
1595
1596
1597
1598
1599
  	return AE_OK;
  }
  
  acpi_status acpi_os_terminate(void)
  {
  	if (acpi_irq_handler) {
23fe36306   Rafael J. Wysocki   ACPI: Avoid calli...
1600
  		acpi_os_remove_interrupt_handler(acpi_gbl_FADT.sci_interrupt,
d362edaf5   Myron Stowe   ACPI: Pre-map 'sy...
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
  						 acpi_irq_handler);
  	}
  
  	acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe1_block);
  	acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe0_block);
  	acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1b_event_block);
  	acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1a_event_block);
  
  	destroy_workqueue(kacpid_wq);
  	destroy_workqueue(kacpi_notify_wq);
  	destroy_workqueue(kacpi_hotplug_wq);
  
  	return AE_OK;
  }