aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-02-02 14:24:44 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-02-02 14:24:44 -0500
commitbd1d462e13b278fc57752d0b9b15040e60e561a0 (patch)
treee2fdf1c18a93aab02830bcb8a5db8cdddfbb63a8 /drivers/acpi
parentd5c38b137ac8a6e3dbed13bc494d60df5b69dfc4 (diff)
parent62aa2b537c6f5957afd98e29f96897419ed5ebab (diff)
Merge 3.3-rc2 into the driver-core-next branch.
This was done to resolve a merge and build problem with the drivers/acpi/processor_driver.c file. Reported-by: Stephen Rothwell <sfr@canb.auug.org.au> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/Makefile1
-rw-r--r--drivers/acpi/apei/apei-base.c35
-rw-r--r--drivers/acpi/apei/einj.c95
-rw-r--r--drivers/acpi/atomicio.c422
-rw-r--r--drivers/acpi/osl.c152
-rw-r--r--drivers/acpi/processor_driver.c135
-rw-r--r--drivers/acpi/sleep.c8
7 files changed, 318 insertions, 530 deletions
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index c07f44f05f9d..1567028d2038 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -19,7 +19,6 @@ obj-y += acpi.o \
19 19
20# All the builtin files are in the "acpi." module_param namespace. 20# All the builtin files are in the "acpi." module_param namespace.
21acpi-y += osl.o utils.o reboot.o 21acpi-y += osl.o utils.o reboot.o
22acpi-y += atomicio.o
23acpi-y += nvs.o 22acpi-y += nvs.o
24 23
25# sleep related files 24# sleep related files
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c
index e45350cb6ac8..e5d53b7ddc7e 100644
--- a/drivers/acpi/apei/apei-base.c
+++ b/drivers/acpi/apei/apei-base.c
@@ -596,33 +596,19 @@ int apei_read(u64 *val, struct acpi_generic_address *reg)
596{ 596{
597 int rc; 597 int rc;
598 u64 address; 598 u64 address;
599 u32 tmp, width = reg->bit_width;
600 acpi_status status; 599 acpi_status status;
601 600
602 rc = apei_check_gar(reg, &address); 601 rc = apei_check_gar(reg, &address);
603 if (rc) 602 if (rc)
604 return rc; 603 return rc;
605 604
606 if (width == 64)
607 width = 32; /* Break into two 32-bit transfers */
608
609 *val = 0; 605 *val = 0;
610 switch(reg->space_id) { 606 switch(reg->space_id) {
611 case ACPI_ADR_SPACE_SYSTEM_MEMORY: 607 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
612 status = acpi_os_read_memory((acpi_physical_address) 608 status = acpi_os_read_memory64((acpi_physical_address)
613 address, &tmp, width); 609 address, val, reg->bit_width);
614 if (ACPI_FAILURE(status)) 610 if (ACPI_FAILURE(status))
615 return -EIO; 611 return -EIO;
616 *val = tmp;
617
618 if (reg->bit_width == 64) {
619 /* Read the top 32 bits */
620 status = acpi_os_read_memory((acpi_physical_address)
621 (address + 4), &tmp, 32);
622 if (ACPI_FAILURE(status))
623 return -EIO;
624 *val |= ((u64)tmp << 32);
625 }
626 break; 612 break;
627 case ACPI_ADR_SPACE_SYSTEM_IO: 613 case ACPI_ADR_SPACE_SYSTEM_IO:
628 status = acpi_os_read_port(address, (u32 *)val, reg->bit_width); 614 status = acpi_os_read_port(address, (u32 *)val, reg->bit_width);
@@ -642,31 +628,18 @@ int apei_write(u64 val, struct acpi_generic_address *reg)
642{ 628{
643 int rc; 629 int rc;
644 u64 address; 630 u64 address;
645 u32 width = reg->bit_width;
646 acpi_status status; 631 acpi_status status;
647 632
648 rc = apei_check_gar(reg, &address); 633 rc = apei_check_gar(reg, &address);
649 if (rc) 634 if (rc)
650 return rc; 635 return rc;
651 636
652 if (width == 64)
653 width = 32; /* Break into two 32-bit transfers */
654
655 switch (reg->space_id) { 637 switch (reg->space_id) {
656 case ACPI_ADR_SPACE_SYSTEM_MEMORY: 638 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
657 status = acpi_os_write_memory((acpi_physical_address) 639 status = acpi_os_write_memory64((acpi_physical_address)
658 address, ACPI_LODWORD(val), 640 address, val, reg->bit_width);
659 width);
660 if (ACPI_FAILURE(status)) 641 if (ACPI_FAILURE(status))
661 return -EIO; 642 return -EIO;
662
663 if (reg->bit_width == 64) {
664 status = acpi_os_write_memory((acpi_physical_address)
665 (address + 4),
666 ACPI_HIDWORD(val), 32);
667 if (ACPI_FAILURE(status))
668 return -EIO;
669 }
670 break; 643 break;
671 case ACPI_ADR_SPACE_SYSTEM_IO: 644 case ACPI_ADR_SPACE_SYSTEM_IO:
672 status = acpi_os_write_port(address, val, reg->bit_width); 645 status = acpi_os_write_port(address, val, reg->bit_width);
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
index 5b898d4dda99..4ca087dd5f4f 100644
--- a/drivers/acpi/apei/einj.c
+++ b/drivers/acpi/apei/einj.c
@@ -141,21 +141,6 @@ static DEFINE_MUTEX(einj_mutex);
141 141
142static void *einj_param; 142static void *einj_param;
143 143
144#ifndef readq
145static inline __u64 readq(volatile void __iomem *addr)
146{
147 return ((__u64)readl(addr+4) << 32) + readl(addr);
148}
149#endif
150
151#ifndef writeq
152static inline void writeq(__u64 val, volatile void __iomem *addr)
153{
154 writel(val, addr);
155 writel(val >> 32, addr+4);
156}
157#endif
158
159static void einj_exec_ctx_init(struct apei_exec_context *ctx) 144static void einj_exec_ctx_init(struct apei_exec_context *ctx)
160{ 145{
161 apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type), 146 apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type),
@@ -204,22 +189,21 @@ static int einj_timedout(u64 *t)
204static void check_vendor_extension(u64 paddr, 189static void check_vendor_extension(u64 paddr,
205 struct set_error_type_with_address *v5param) 190 struct set_error_type_with_address *v5param)
206{ 191{
207 int offset = readl(&v5param->vendor_extension); 192 int offset = v5param->vendor_extension;
208 struct vendor_error_type_extension *v; 193 struct vendor_error_type_extension *v;
209 u32 sbdf; 194 u32 sbdf;
210 195
211 if (!offset) 196 if (!offset)
212 return; 197 return;
213 v = ioremap(paddr + offset, sizeof(*v)); 198 v = acpi_os_map_memory(paddr + offset, sizeof(*v));
214 if (!v) 199 if (!v)
215 return; 200 return;
216 sbdf = readl(&v->pcie_sbdf); 201 sbdf = v->pcie_sbdf;
217 sprintf(vendor_dev, "%x:%x:%x.%x vendor_id=%x device_id=%x rev_id=%x\n", 202 sprintf(vendor_dev, "%x:%x:%x.%x vendor_id=%x device_id=%x rev_id=%x\n",
218 sbdf >> 24, (sbdf >> 16) & 0xff, 203 sbdf >> 24, (sbdf >> 16) & 0xff,
219 (sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7, 204 (sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7,
220 readw(&v->vendor_id), readw(&v->device_id), 205 v->vendor_id, v->device_id, v->rev_id);
221 readb(&v->rev_id)); 206 acpi_os_unmap_memory(v, sizeof(*v));
222 iounmap(v);
223} 207}
224 208
225static void *einj_get_parameter_address(void) 209static void *einj_get_parameter_address(void)
@@ -247,7 +231,7 @@ static void *einj_get_parameter_address(void)
247 if (paddrv5) { 231 if (paddrv5) {
248 struct set_error_type_with_address *v5param; 232 struct set_error_type_with_address *v5param;
249 233
250 v5param = ioremap(paddrv5, sizeof(*v5param)); 234 v5param = acpi_os_map_memory(paddrv5, sizeof(*v5param));
251 if (v5param) { 235 if (v5param) {
252 acpi5 = 1; 236 acpi5 = 1;
253 check_vendor_extension(paddrv5, v5param); 237 check_vendor_extension(paddrv5, v5param);
@@ -257,17 +241,17 @@ static void *einj_get_parameter_address(void)
257 if (paddrv4) { 241 if (paddrv4) {
258 struct einj_parameter *v4param; 242 struct einj_parameter *v4param;
259 243
260 v4param = ioremap(paddrv4, sizeof(*v4param)); 244 v4param = acpi_os_map_memory(paddrv4, sizeof(*v4param));
261 if (!v4param) 245 if (!v4param)
262 return 0; 246 return NULL;
263 if (readq(&v4param->reserved1) || readq(&v4param->reserved2)) { 247 if (v4param->reserved1 || v4param->reserved2) {
264 iounmap(v4param); 248 acpi_os_unmap_memory(v4param, sizeof(*v4param));
265 return 0; 249 return NULL;
266 } 250 }
267 return v4param; 251 return v4param;
268 } 252 }
269 253
270 return 0; 254 return NULL;
271} 255}
272 256
273/* do sanity check to trigger table */ 257/* do sanity check to trigger table */
@@ -276,7 +260,7 @@ static int einj_check_trigger_header(struct acpi_einj_trigger *trigger_tab)
276 if (trigger_tab->header_size != sizeof(struct acpi_einj_trigger)) 260 if (trigger_tab->header_size != sizeof(struct acpi_einj_trigger))
277 return -EINVAL; 261 return -EINVAL;
278 if (trigger_tab->table_size > PAGE_SIZE || 262 if (trigger_tab->table_size > PAGE_SIZE ||
279 trigger_tab->table_size <= trigger_tab->header_size) 263 trigger_tab->table_size < trigger_tab->header_size)
280 return -EINVAL; 264 return -EINVAL;
281 if (trigger_tab->entry_count != 265 if (trigger_tab->entry_count !=
282 (trigger_tab->table_size - trigger_tab->header_size) / 266 (trigger_tab->table_size - trigger_tab->header_size) /
@@ -340,6 +324,11 @@ static int __einj_error_trigger(u64 trigger_paddr, u32 type,
340 "The trigger error action table is invalid\n"); 324 "The trigger error action table is invalid\n");
341 goto out_rel_header; 325 goto out_rel_header;
342 } 326 }
327
328 /* No action structures in the TRIGGER_ERROR table, nothing to do */
329 if (!trigger_tab->entry_count)
330 goto out_rel_header;
331
343 rc = -EIO; 332 rc = -EIO;
344 table_size = trigger_tab->table_size; 333 table_size = trigger_tab->table_size;
345 r = request_mem_region(trigger_paddr + sizeof(*trigger_tab), 334 r = request_mem_region(trigger_paddr + sizeof(*trigger_tab),
@@ -435,41 +424,41 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)
435 if (acpi5) { 424 if (acpi5) {
436 struct set_error_type_with_address *v5param = einj_param; 425 struct set_error_type_with_address *v5param = einj_param;
437 426
438 writel(type, &v5param->type); 427 v5param->type = type;
439 if (type & 0x80000000) { 428 if (type & 0x80000000) {
440 switch (vendor_flags) { 429 switch (vendor_flags) {
441 case SETWA_FLAGS_APICID: 430 case SETWA_FLAGS_APICID:
442 writel(param1, &v5param->apicid); 431 v5param->apicid = param1;
443 break; 432 break;
444 case SETWA_FLAGS_MEM: 433 case SETWA_FLAGS_MEM:
445 writeq(param1, &v5param->memory_address); 434 v5param->memory_address = param1;
446 writeq(param2, &v5param->memory_address_range); 435 v5param->memory_address_range = param2;
447 break; 436 break;
448 case SETWA_FLAGS_PCIE_SBDF: 437 case SETWA_FLAGS_PCIE_SBDF:
449 writel(param1, &v5param->pcie_sbdf); 438 v5param->pcie_sbdf = param1;
450 break; 439 break;
451 } 440 }
452 writel(vendor_flags, &v5param->flags); 441 v5param->flags = vendor_flags;
453 } else { 442 } else {
454 switch (type) { 443 switch (type) {
455 case ACPI_EINJ_PROCESSOR_CORRECTABLE: 444 case ACPI_EINJ_PROCESSOR_CORRECTABLE:
456 case ACPI_EINJ_PROCESSOR_UNCORRECTABLE: 445 case ACPI_EINJ_PROCESSOR_UNCORRECTABLE:
457 case ACPI_EINJ_PROCESSOR_FATAL: 446 case ACPI_EINJ_PROCESSOR_FATAL:
458 writel(param1, &v5param->apicid); 447 v5param->apicid = param1;
459 writel(SETWA_FLAGS_APICID, &v5param->flags); 448 v5param->flags = SETWA_FLAGS_APICID;
460 break; 449 break;
461 case ACPI_EINJ_MEMORY_CORRECTABLE: 450 case ACPI_EINJ_MEMORY_CORRECTABLE:
462 case ACPI_EINJ_MEMORY_UNCORRECTABLE: 451 case ACPI_EINJ_MEMORY_UNCORRECTABLE:
463 case ACPI_EINJ_MEMORY_FATAL: 452 case ACPI_EINJ_MEMORY_FATAL:
464 writeq(param1, &v5param->memory_address); 453 v5param->memory_address = param1;
465 writeq(param2, &v5param->memory_address_range); 454 v5param->memory_address_range = param2;
466 writel(SETWA_FLAGS_MEM, &v5param->flags); 455 v5param->flags = SETWA_FLAGS_MEM;
467 break; 456 break;
468 case ACPI_EINJ_PCIX_CORRECTABLE: 457 case ACPI_EINJ_PCIX_CORRECTABLE:
469 case ACPI_EINJ_PCIX_UNCORRECTABLE: 458 case ACPI_EINJ_PCIX_UNCORRECTABLE:
470 case ACPI_EINJ_PCIX_FATAL: 459 case ACPI_EINJ_PCIX_FATAL:
471 writel(param1, &v5param->pcie_sbdf); 460 v5param->pcie_sbdf = param1;
472 writel(SETWA_FLAGS_PCIE_SBDF, &v5param->flags); 461 v5param->flags = SETWA_FLAGS_PCIE_SBDF;
473 break; 462 break;
474 } 463 }
475 } 464 }
@@ -479,8 +468,8 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)
479 return rc; 468 return rc;
480 if (einj_param) { 469 if (einj_param) {
481 struct einj_parameter *v4param = einj_param; 470 struct einj_parameter *v4param = einj_param;
482 writeq(param1, &v4param->param1); 471 v4param->param1 = param1;
483 writeq(param2, &v4param->param2); 472 v4param->param2 = param2;
484 } 473 }
485 } 474 }
486 rc = apei_exec_run(&ctx, ACPI_EINJ_EXECUTE_OPERATION); 475 rc = apei_exec_run(&ctx, ACPI_EINJ_EXECUTE_OPERATION);
@@ -731,8 +720,13 @@ static int __init einj_init(void)
731 return 0; 720 return 0;
732 721
733err_unmap: 722err_unmap:
734 if (einj_param) 723 if (einj_param) {
735 iounmap(einj_param); 724 acpi_size size = (acpi5) ?
725 sizeof(struct set_error_type_with_address) :
726 sizeof(struct einj_parameter);
727
728 acpi_os_unmap_memory(einj_param, size);
729 }
736 apei_exec_post_unmap_gars(&ctx); 730 apei_exec_post_unmap_gars(&ctx);
737err_release: 731err_release:
738 apei_resources_release(&einj_resources); 732 apei_resources_release(&einj_resources);
@@ -748,8 +742,13 @@ static void __exit einj_exit(void)
748{ 742{
749 struct apei_exec_context ctx; 743 struct apei_exec_context ctx;
750 744
751 if (einj_param) 745 if (einj_param) {
752 iounmap(einj_param); 746 acpi_size size = (acpi5) ?
747 sizeof(struct set_error_type_with_address) :
748 sizeof(struct einj_parameter);
749
750 acpi_os_unmap_memory(einj_param, size);
751 }
753 einj_exec_ctx_init(&ctx); 752 einj_exec_ctx_init(&ctx);
754 apei_exec_post_unmap_gars(&ctx); 753 apei_exec_post_unmap_gars(&ctx);
755 apei_resources_release(&einj_resources); 754 apei_resources_release(&einj_resources);
diff --git a/drivers/acpi/atomicio.c b/drivers/acpi/atomicio.c
deleted file mode 100644
index d4a5b3d3657b..000000000000
--- a/drivers/acpi/atomicio.c
+++ /dev/null
@@ -1,422 +0,0 @@
1/*
2 * atomicio.c - ACPI IO memory pre-mapping/post-unmapping, then
3 * accessing in atomic context.
4 *
5 * This is used for NMI handler to access IO memory area, because
6 * ioremap/iounmap can not be used in NMI handler. The IO memory area
7 * is pre-mapped in process context and accessed in NMI handler.
8 *
9 * Copyright (C) 2009-2010, Intel Corp.
10 * Author: Huang Ying <ying.huang@intel.com>
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License version
14 * 2 as published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26#include <linux/kernel.h>
27#include <linux/export.h>
28#include <linux/init.h>
29#include <linux/acpi.h>
30#include <linux/io.h>
31#include <linux/kref.h>
32#include <linux/rculist.h>
33#include <linux/interrupt.h>
34#include <linux/slab.h>
35#include <linux/mm.h>
36#include <linux/highmem.h>
37#include <acpi/atomicio.h>
38
39#define ACPI_PFX "ACPI: "
40
41static LIST_HEAD(acpi_iomaps);
42/*
43 * Used for mutual exclusion between writers of acpi_iomaps list, for
44 * synchronization between readers and writer, RCU is used.
45 */
46static DEFINE_SPINLOCK(acpi_iomaps_lock);
47
48struct acpi_iomap {
49 struct list_head list;
50 void __iomem *vaddr;
51 unsigned long size;
52 phys_addr_t paddr;
53 struct kref ref;
54};
55
56/* acpi_iomaps_lock or RCU read lock must be held before calling */
57static struct acpi_iomap *__acpi_find_iomap(phys_addr_t paddr,
58 unsigned long size)
59{
60 struct acpi_iomap *map;
61
62 list_for_each_entry_rcu(map, &acpi_iomaps, list) {
63 if (map->paddr + map->size >= paddr + size &&
64 map->paddr <= paddr)
65 return map;
66 }
67 return NULL;
68}
69
70/*
71 * Atomic "ioremap" used by NMI handler, if the specified IO memory
72 * area is not pre-mapped, NULL will be returned.
73 *
74 * acpi_iomaps_lock or RCU read lock must be held before calling
75 */
76static void __iomem *__acpi_ioremap_fast(phys_addr_t paddr,
77 unsigned long size)
78{
79 struct acpi_iomap *map;
80
81 map = __acpi_find_iomap(paddr, size/8);
82 if (map)
83 return map->vaddr + (paddr - map->paddr);
84 else
85 return NULL;
86}
87
88/* acpi_iomaps_lock must be held before calling */
89static void __iomem *__acpi_try_ioremap(phys_addr_t paddr,
90 unsigned long size)
91{
92 struct acpi_iomap *map;
93
94 map = __acpi_find_iomap(paddr, size);
95 if (map) {
96 kref_get(&map->ref);
97 return map->vaddr + (paddr - map->paddr);
98 } else
99 return NULL;
100}
101
102#ifndef CONFIG_IA64
103#define should_use_kmap(pfn) page_is_ram(pfn)
104#else
105/* ioremap will take care of cache attributes */
106#define should_use_kmap(pfn) 0
107#endif
108
109static void __iomem *acpi_map(phys_addr_t pg_off, unsigned long pg_sz)
110{
111 unsigned long pfn;
112
113 pfn = pg_off >> PAGE_SHIFT;
114 if (should_use_kmap(pfn)) {
115 if (pg_sz > PAGE_SIZE)
116 return NULL;
117 return (void __iomem __force *)kmap(pfn_to_page(pfn));
118 } else
119 return ioremap(pg_off, pg_sz);
120}
121
122static void acpi_unmap(phys_addr_t pg_off, void __iomem *vaddr)
123{
124 unsigned long pfn;
125
126 pfn = pg_off >> PAGE_SHIFT;
127 if (page_is_ram(pfn))
128 kunmap(pfn_to_page(pfn));
129 else
130 iounmap(vaddr);
131}
132
133/*
134 * Used to pre-map the specified IO memory area. First try to find
135 * whether the area is already pre-mapped, if it is, increase the
136 * reference count (in __acpi_try_ioremap) and return; otherwise, do
137 * the real ioremap, and add the mapping into acpi_iomaps list.
138 */
139static void __iomem *acpi_pre_map(phys_addr_t paddr,
140 unsigned long size)
141{
142 void __iomem *vaddr;
143 struct acpi_iomap *map;
144 unsigned long pg_sz, flags;
145 phys_addr_t pg_off;
146
147 spin_lock_irqsave(&acpi_iomaps_lock, flags);
148 vaddr = __acpi_try_ioremap(paddr, size);
149 spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
150 if (vaddr)
151 return vaddr;
152
153 pg_off = paddr & PAGE_MASK;
154 pg_sz = ((paddr + size + PAGE_SIZE - 1) & PAGE_MASK) - pg_off;
155 vaddr = acpi_map(pg_off, pg_sz);
156 if (!vaddr)
157 return NULL;
158 map = kmalloc(sizeof(*map), GFP_KERNEL);
159 if (!map)
160 goto err_unmap;
161 INIT_LIST_HEAD(&map->list);
162 map->paddr = pg_off;
163 map->size = pg_sz;
164 map->vaddr = vaddr;
165 kref_init(&map->ref);
166
167 spin_lock_irqsave(&acpi_iomaps_lock, flags);
168 vaddr = __acpi_try_ioremap(paddr, size);
169 if (vaddr) {
170 spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
171 acpi_unmap(pg_off, map->vaddr);
172 kfree(map);
173 return vaddr;
174 }
175 list_add_tail_rcu(&map->list, &acpi_iomaps);
176 spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
177
178 return map->vaddr + (paddr - map->paddr);
179err_unmap:
180 acpi_unmap(pg_off, vaddr);
181 return NULL;
182}
183
184/* acpi_iomaps_lock must be held before calling */
185static void __acpi_kref_del_iomap(struct kref *ref)
186{
187 struct acpi_iomap *map;
188
189 map = container_of(ref, struct acpi_iomap, ref);
190 list_del_rcu(&map->list);
191}
192
193/*
194 * Used to post-unmap the specified IO memory area. The iounmap is
195 * done only if the reference count goes zero.
196 */
197static void acpi_post_unmap(phys_addr_t paddr, unsigned long size)
198{
199 struct acpi_iomap *map;
200 unsigned long flags;
201 int del;
202
203 spin_lock_irqsave(&acpi_iomaps_lock, flags);
204 map = __acpi_find_iomap(paddr, size);
205 BUG_ON(!map);
206 del = kref_put(&map->ref, __acpi_kref_del_iomap);
207 spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
208
209 if (!del)
210 return;
211
212 synchronize_rcu();
213 acpi_unmap(map->paddr, map->vaddr);
214 kfree(map);
215}
216
217/* In NMI handler, should set silent = 1 */
218static int acpi_check_gar(struct acpi_generic_address *reg,
219 u64 *paddr, int silent)
220{
221 u32 width, space_id;
222
223 width = reg->bit_width;
224 space_id = reg->space_id;
225 /* Handle possible alignment issues */
226 memcpy(paddr, &reg->address, sizeof(*paddr));
227 if (!*paddr) {
228 if (!silent)
229 pr_warning(FW_BUG ACPI_PFX
230 "Invalid physical address in GAR [0x%llx/%u/%u]\n",
231 *paddr, width, space_id);
232 return -EINVAL;
233 }
234
235 if ((width != 8) && (width != 16) && (width != 32) && (width != 64)) {
236 if (!silent)
237 pr_warning(FW_BUG ACPI_PFX
238 "Invalid bit width in GAR [0x%llx/%u/%u]\n",
239 *paddr, width, space_id);
240 return -EINVAL;
241 }
242
243 if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY &&
244 space_id != ACPI_ADR_SPACE_SYSTEM_IO) {
245 if (!silent)
246 pr_warning(FW_BUG ACPI_PFX
247 "Invalid address space type in GAR [0x%llx/%u/%u]\n",
248 *paddr, width, space_id);
249 return -EINVAL;
250 }
251
252 return 0;
253}
254
255/* Pre-map, working on GAR */
256int acpi_pre_map_gar(struct acpi_generic_address *reg)
257{
258 u64 paddr;
259 void __iomem *vaddr;
260 int rc;
261
262 if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
263 return 0;
264
265 rc = acpi_check_gar(reg, &paddr, 0);
266 if (rc)
267 return rc;
268
269 vaddr = acpi_pre_map(paddr, reg->bit_width / 8);
270 if (!vaddr)
271 return -EIO;
272
273 return 0;
274}
275EXPORT_SYMBOL_GPL(acpi_pre_map_gar);
276
277/* Post-unmap, working on GAR */
278int acpi_post_unmap_gar(struct acpi_generic_address *reg)
279{
280 u64 paddr;
281 int rc;
282
283 if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
284 return 0;
285
286 rc = acpi_check_gar(reg, &paddr, 0);
287 if (rc)
288 return rc;
289
290 acpi_post_unmap(paddr, reg->bit_width / 8);
291
292 return 0;
293}
294EXPORT_SYMBOL_GPL(acpi_post_unmap_gar);
295
296#ifdef readq
297static inline u64 read64(const volatile void __iomem *addr)
298{
299 return readq(addr);
300}
301#else
302static inline u64 read64(const volatile void __iomem *addr)
303{
304 u64 l, h;
305 l = readl(addr);
306 h = readl(addr+4);
307 return l | (h << 32);
308}
309#endif
310
311/*
312 * Can be used in atomic (including NMI) or process context. RCU read
313 * lock can only be released after the IO memory area accessing.
314 */
315static int acpi_atomic_read_mem(u64 paddr, u64 *val, u32 width)
316{
317 void __iomem *addr;
318
319 rcu_read_lock();
320 addr = __acpi_ioremap_fast(paddr, width);
321 switch (width) {
322 case 8:
323 *val = readb(addr);
324 break;
325 case 16:
326 *val = readw(addr);
327 break;
328 case 32:
329 *val = readl(addr);
330 break;
331 case 64:
332 *val = read64(addr);
333 break;
334 default:
335 return -EINVAL;
336 }
337 rcu_read_unlock();
338
339 return 0;
340}
341
342#ifdef writeq
343static inline void write64(u64 val, volatile void __iomem *addr)
344{
345 writeq(val, addr);
346}
347#else
348static inline void write64(u64 val, volatile void __iomem *addr)
349{
350 writel(val, addr);
351 writel(val>>32, addr+4);
352}
353#endif
354
355static int acpi_atomic_write_mem(u64 paddr, u64 val, u32 width)
356{
357 void __iomem *addr;
358
359 rcu_read_lock();
360 addr = __acpi_ioremap_fast(paddr, width);
361 switch (width) {
362 case 8:
363 writeb(val, addr);
364 break;
365 case 16:
366 writew(val, addr);
367 break;
368 case 32:
369 writel(val, addr);
370 break;
371 case 64:
372 write64(val, addr);
373 break;
374 default:
375 return -EINVAL;
376 }
377 rcu_read_unlock();
378
379 return 0;
380}
381
382/* GAR accessing in atomic (including NMI) or process context */
383int acpi_atomic_read(u64 *val, struct acpi_generic_address *reg)
384{
385 u64 paddr;
386 int rc;
387
388 rc = acpi_check_gar(reg, &paddr, 1);
389 if (rc)
390 return rc;
391
392 *val = 0;
393 switch (reg->space_id) {
394 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
395 return acpi_atomic_read_mem(paddr, val, reg->bit_width);
396 case ACPI_ADR_SPACE_SYSTEM_IO:
397 return acpi_os_read_port(paddr, (u32 *)val, reg->bit_width);
398 default:
399 return -EINVAL;
400 }
401}
402EXPORT_SYMBOL_GPL(acpi_atomic_read);
403
404int acpi_atomic_write(u64 val, struct acpi_generic_address *reg)
405{
406 u64 paddr;
407 int rc;
408
409 rc = acpi_check_gar(reg, &paddr, 1);
410 if (rc)
411 return rc;
412
413 switch (reg->space_id) {
414 case ACPI_ADR_SPACE_SYSTEM_MEMORY:
415 return acpi_atomic_write_mem(paddr, val, reg->bit_width);
416 case ACPI_ADR_SPACE_SYSTEM_IO:
417 return acpi_os_write_port(paddr, val, reg->bit_width);
418 default:
419 return -EINVAL;
420 }
421}
422EXPORT_SYMBOL_GPL(acpi_atomic_write);
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index fcc12d842bcc..412a1e04a922 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -31,6 +31,7 @@
31#include <linux/kernel.h> 31#include <linux/kernel.h>
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/mm.h> 33#include <linux/mm.h>
34#include <linux/highmem.h>
34#include <linux/pci.h> 35#include <linux/pci.h>
35#include <linux/interrupt.h> 36#include <linux/interrupt.h>
36#include <linux/kmod.h> 37#include <linux/kmod.h>
@@ -321,6 +322,37 @@ acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
321 return NULL; 322 return NULL;
322} 323}
323 324
325#ifndef CONFIG_IA64
326#define should_use_kmap(pfn) page_is_ram(pfn)
327#else
328/* ioremap will take care of cache attributes */
329#define should_use_kmap(pfn) 0
330#endif
331
332static void __iomem *acpi_map(acpi_physical_address pg_off, unsigned long pg_sz)
333{
334 unsigned long pfn;
335
336 pfn = pg_off >> PAGE_SHIFT;
337 if (should_use_kmap(pfn)) {
338 if (pg_sz > PAGE_SIZE)
339 return NULL;
340 return (void __iomem __force *)kmap(pfn_to_page(pfn));
341 } else
342 return acpi_os_ioremap(pg_off, pg_sz);
343}
344
345static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr)
346{
347 unsigned long pfn;
348
349 pfn = pg_off >> PAGE_SHIFT;
350 if (page_is_ram(pfn))
351 kunmap(pfn_to_page(pfn));
352 else
353 iounmap(vaddr);
354}
355
324void __iomem *__init_refok 356void __iomem *__init_refok
325acpi_os_map_memory(acpi_physical_address phys, acpi_size size) 357acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
326{ 358{
@@ -353,7 +385,7 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
353 385
354 pg_off = round_down(phys, PAGE_SIZE); 386 pg_off = round_down(phys, PAGE_SIZE);
355 pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off; 387 pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
356 virt = acpi_os_ioremap(pg_off, pg_sz); 388 virt = acpi_map(pg_off, pg_sz);
357 if (!virt) { 389 if (!virt) {
358 mutex_unlock(&acpi_ioremap_lock); 390 mutex_unlock(&acpi_ioremap_lock);
359 kfree(map); 391 kfree(map);
@@ -384,7 +416,7 @@ static void acpi_os_map_cleanup(struct acpi_ioremap *map)
384{ 416{
385 if (!map->refcount) { 417 if (!map->refcount) {
386 synchronize_rcu(); 418 synchronize_rcu();
387 iounmap(map->virt); 419 acpi_unmap(map->phys, map->virt);
388 kfree(map); 420 kfree(map);
389 } 421 }
390} 422}
@@ -710,6 +742,67 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
710 return AE_OK; 742 return AE_OK;
711} 743}
712 744
745#ifdef readq
746static inline u64 read64(const volatile void __iomem *addr)
747{
748 return readq(addr);
749}
750#else
751static inline u64 read64(const volatile void __iomem *addr)
752{
753 u64 l, h;
754 l = readl(addr);
755 h = readl(addr+4);
756 return l | (h << 32);
757}
758#endif
759
760acpi_status
761acpi_os_read_memory64(acpi_physical_address phys_addr, u64 *value, u32 width)
762{
763 void __iomem *virt_addr;
764 unsigned int size = width / 8;
765 bool unmap = false;
766 u64 dummy;
767
768 rcu_read_lock();
769 virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
770 if (!virt_addr) {
771 rcu_read_unlock();
772 virt_addr = acpi_os_ioremap(phys_addr, size);
773 if (!virt_addr)
774 return AE_BAD_ADDRESS;
775 unmap = true;
776 }
777
778 if (!value)
779 value = &dummy;
780
781 switch (width) {
782 case 8:
783 *(u8 *) value = readb(virt_addr);
784 break;
785 case 16:
786 *(u16 *) value = readw(virt_addr);
787 break;
788 case 32:
789 *(u32 *) value = readl(virt_addr);
790 break;
791 case 64:
792 *(u64 *) value = read64(virt_addr);
793 break;
794 default:
795 BUG();
796 }
797
798 if (unmap)
799 iounmap(virt_addr);
800 else
801 rcu_read_unlock();
802
803 return AE_OK;
804}
805
713acpi_status 806acpi_status
714acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) 807acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
715{ 808{
@@ -749,6 +842,61 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
749 return AE_OK; 842 return AE_OK;
750} 843}
751 844
845#ifdef writeq
846static inline void write64(u64 val, volatile void __iomem *addr)
847{
848 writeq(val, addr);
849}
850#else
851static inline void write64(u64 val, volatile void __iomem *addr)
852{
853 writel(val, addr);
854 writel(val>>32, addr+4);
855}
856#endif
857
858acpi_status
859acpi_os_write_memory64(acpi_physical_address phys_addr, u64 value, u32 width)
860{
861 void __iomem *virt_addr;
862 unsigned int size = width / 8;
863 bool unmap = false;
864
865 rcu_read_lock();
866 virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
867 if (!virt_addr) {
868 rcu_read_unlock();
869 virt_addr = acpi_os_ioremap(phys_addr, size);
870 if (!virt_addr)
871 return AE_BAD_ADDRESS;
872 unmap = true;
873 }
874
875 switch (width) {
876 case 8:
877 writeb(value, virt_addr);
878 break;
879 case 16:
880 writew(value, virt_addr);
881 break;
882 case 32:
883 writel(value, virt_addr);
884 break;
885 case 64:
886 write64(value, virt_addr);
887 break;
888 default:
889 BUG();
890 }
891
892 if (unmap)
893 iounmap(virt_addr);
894 else
895 rcu_read_unlock();
896
897 return AE_OK;
898}
899
752acpi_status 900acpi_status
753acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg, 901acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
754 u64 *value, u32 width) 902 u64 *value, u32 width)
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index e6920d0aca53..f289d2afbd4e 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -84,7 +84,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type);
84static void acpi_processor_notify(struct acpi_device *device, u32 event); 84static void acpi_processor_notify(struct acpi_device *device, u32 event);
85static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr); 85static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr);
86static int acpi_processor_handle_eject(struct acpi_processor *pr); 86static int acpi_processor_handle_eject(struct acpi_processor *pr);
87 87static int acpi_processor_start(struct acpi_processor *pr);
88 88
89static const struct acpi_device_id processor_device_ids[] = { 89static const struct acpi_device_id processor_device_ids[] = {
90 {ACPI_PROCESSOR_OBJECT_HID, 0}, 90 {ACPI_PROCESSOR_OBJECT_HID, 0},
@@ -423,10 +423,29 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb,
423 struct acpi_processor *pr = per_cpu(processors, cpu); 423 struct acpi_processor *pr = per_cpu(processors, cpu);
424 424
425 if (action == CPU_ONLINE && pr) { 425 if (action == CPU_ONLINE && pr) {
426 acpi_processor_ppc_has_changed(pr, 0); 426 /* CPU got physically hotplugged and onlined the first time:
427 acpi_processor_hotplug(pr); 427 * Initialize missing things
428 acpi_processor_reevaluate_tstate(pr, action); 428 */
429 acpi_processor_tstate_has_changed(pr); 429 if (pr->flags.need_hotplug_init) {
430 struct cpuidle_driver *idle_driver =
431 cpuidle_get_driver();
432
433 printk(KERN_INFO "Will online and init hotplugged "
434 "CPU: %d\n", pr->id);
435 WARN(acpi_processor_start(pr), "Failed to start CPU:"
436 " %d\n", pr->id);
437 pr->flags.need_hotplug_init = 0;
438 if (idle_driver && !strcmp(idle_driver->name,
439 "intel_idle")) {
440 intel_idle_cpu_init(pr->id);
441 }
442 /* Normal CPU soft online event */
443 } else {
444 acpi_processor_ppc_has_changed(pr, 0);
445 acpi_processor_cst_has_changed(pr);
446 acpi_processor_reevaluate_tstate(pr, action);
447 acpi_processor_tstate_has_changed(pr);
448 }
430 } 449 }
431 if (action == CPU_DEAD && pr) { 450 if (action == CPU_DEAD && pr) {
432 /* invalidate the flag.throttling after one CPU is offline */ 451 /* invalidate the flag.throttling after one CPU is offline */
@@ -440,6 +459,71 @@ static struct notifier_block acpi_cpu_notifier =
440 .notifier_call = acpi_cpu_soft_notify, 459 .notifier_call = acpi_cpu_soft_notify,
441}; 460};
442 461
462/*
463 * acpi_processor_start() is called by the cpu_hotplug_notifier func:
464 * acpi_cpu_soft_notify(). Getting it __cpuinit{data} is difficult, the
465 * root cause seem to be that acpi_processor_uninstall_hotplug_notify()
466 * is in the module_exit (__exit) func. Allowing acpi_processor_start()
467 * to not be in __cpuinit section, but being called from __cpuinit funcs
468 * via __ref looks like the right thing to do here.
469 */
470static __ref int acpi_processor_start(struct acpi_processor *pr)
471{
472 struct acpi_device *device = per_cpu(processor_device_array, pr->id);
473 int result = 0;
474
475#ifdef CONFIG_CPU_FREQ
476 acpi_processor_ppc_has_changed(pr, 0);
477#endif
478 acpi_processor_get_throttling_info(pr);
479 acpi_processor_get_limit_info(pr);
480
481 if (!cpuidle_get_driver() || cpuidle_get_driver() == &acpi_idle_driver)
482 acpi_processor_power_init(pr, device);
483
484 pr->cdev = thermal_cooling_device_register("Processor", device,
485 &processor_cooling_ops);
486 if (IS_ERR(pr->cdev)) {
487 result = PTR_ERR(pr->cdev);
488 goto err_power_exit;
489 }
490
491 dev_dbg(&device->dev, "registered as cooling_device%d\n",
492 pr->cdev->id);
493
494 result = sysfs_create_link(&device->dev.kobj,
495 &pr->cdev->device.kobj,
496 "thermal_cooling");
497 if (result) {
498 printk(KERN_ERR PREFIX "Create sysfs link\n");
499 goto err_thermal_unregister;
500 }
501 result = sysfs_create_link(&pr->cdev->device.kobj,
502 &device->dev.kobj,
503 "device");
504 if (result) {
505 printk(KERN_ERR PREFIX "Create sysfs link\n");
506 goto err_remove_sysfs_thermal;
507 }
508
509 return 0;
510
511err_remove_sysfs_thermal:
512 sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
513err_thermal_unregister:
514 thermal_cooling_device_unregister(pr->cdev);
515err_power_exit:
516 acpi_processor_power_exit(pr, device);
517
518 return result;
519}
520
521/*
522 * Do not put anything in here which needs the core to be online.
523 * For example MSR access or setting up things which check for cpuinfo_x86
524 * (cpu_data(cpu)) values, like CPU feature flags, family, model, etc.
525 * Such things have to be put in and set up above in acpi_processor_start()
526 */
443static int __cpuinit acpi_processor_add(struct acpi_device *device) 527static int __cpuinit acpi_processor_add(struct acpi_device *device)
444{ 528{
445 struct acpi_processor *pr = NULL; 529 struct acpi_processor *pr = NULL;
@@ -509,35 +593,23 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device)
509 &processor_cooling_ops); 593 &processor_cooling_ops);
510 if (IS_ERR(pr->cdev)) { 594 if (IS_ERR(pr->cdev)) {
511 result = PTR_ERR(pr->cdev); 595 result = PTR_ERR(pr->cdev);
512 goto err_power_exit; 596 goto err_remove_sysfs;
513 } 597 }
514 598
515 dev_dbg(&device->dev, "registered as cooling_device%d\n", 599 /*
516 pr->cdev->id); 600 * Do not start hotplugged CPUs now, but when they
601 * are onlined the first time
602 */
603 if (pr->flags.need_hotplug_init)
604 return 0;
517 605
518 result = sysfs_create_link(&device->dev.kobj, 606 result = acpi_processor_start(pr);
519 &pr->cdev->device.kobj, 607 if (result)
520 "thermal_cooling");
521 if (result) {
522 printk(KERN_ERR PREFIX "Create sysfs link\n");
523 goto err_thermal_unregister;
524 }
525 result = sysfs_create_link(&pr->cdev->device.kobj,
526 &device->dev.kobj,
527 "device");
528 if (result) {
529 printk(KERN_ERR PREFIX "Create sysfs link\n");
530 goto err_remove_sysfs; 608 goto err_remove_sysfs;
531 }
532 609
533 return 0; 610 return 0;
534 611
535err_remove_sysfs: 612err_remove_sysfs:
536 sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
537err_thermal_unregister:
538 thermal_cooling_device_unregister(pr->cdev);
539err_power_exit:
540 acpi_processor_power_exit(pr, device);
541 sysfs_remove_link(&device->dev.kobj, "sysdev"); 613 sysfs_remove_link(&device->dev.kobj, "sysdev");
542err_free_cpumask: 614err_free_cpumask:
543 free_cpumask_var(pr->throttling.shared_cpu_map); 615 free_cpumask_var(pr->throttling.shared_cpu_map);
@@ -736,6 +808,17 @@ static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr)
736 return AE_ERROR; 808 return AE_ERROR;
737 } 809 }
738 810
811 /* CPU got hot-plugged, but cpu_data is not initialized yet
812 * Set flag to delay cpu_idle/throttling initialization
813 * in:
814 * acpi_processor_add()
815 * acpi_processor_get_info()
816 * and do it when the CPU gets online the first time
817 * TBD: Cleanup above functions and try to do this more elegant.
818 */
819 printk(KERN_INFO "CPU %d got hotplugged\n", pr->id);
820 pr->flags.need_hotplug_init = 1;
821
739 return AE_OK; 822 return AE_OK;
740} 823}
741 824
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 0a7ed69546ba..ca191ff97844 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -438,6 +438,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
438 }, 438 },
439 { 439 {
440 .callback = init_nvs_nosave, 440 .callback = init_nvs_nosave,
441 .ident = "Sony Vaio VPCCW29FX",
442 .matches = {
443 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
444 DMI_MATCH(DMI_PRODUCT_NAME, "VPCCW29FX"),
445 },
446 },
447 {
448 .callback = init_nvs_nosave,
441 .ident = "Averatec AV1020-ED2", 449 .ident = "Averatec AV1020-ED2",
442 .matches = { 450 .matches = {
443 DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"), 451 DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"),