aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-04-07 06:05:21 -0400
committerIngo Molnar <mingo@elte.hu>2009-04-07 06:05:25 -0400
commit6c009ecef8cca28c7c09eb16d0802e37915a76e1 (patch)
tree11c773f780186fdb9fbc9c80a73fb7c8426b1fba /arch
parent98c2aaf8be5baf7193be37fb28bce8e7327158bc (diff)
parentd508afb437daee7cf07da085b635c44a4ebf9b38 (diff)
Merge branch 'linus' into perfcounters/core
Merge reason: need the upstream facility added by: 7f1e2ca: hrtimer: fix rq->lock inversion (again) Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-davinci/include/mach/nand.h80
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa3xx_nand.h3
-rw-r--r--arch/blackfin/kernel/process.c2
-rw-r--r--arch/frv/mm/tlb-miss.S1
-rw-r--r--arch/mips/include/asm/txx9/ndfmc.h30
-rw-r--r--arch/mips/include/asm/txx9/rbtx4939.h9
-rw-r--r--arch/mips/include/asm/txx9/tx4938.h1
-rw-r--r--arch/mips/include/asm/txx9/tx4939.h2
-rw-r--r--arch/mips/txx9/generic/setup.c21
-rw-r--r--arch/mips/txx9/generic/setup_tx4938.c21
-rw-r--r--arch/mips/txx9/generic/setup_tx4939.c17
-rw-r--r--arch/mips/txx9/rbtx4938/setup.c2
-rw-r--r--arch/mips/txx9/rbtx4939/setup.c161
-rw-r--r--arch/powerpc/boot/dts/tqm8548-bigflash.dts7
-rw-r--r--arch/powerpc/boot/dts/tqm8548.dts7
-rw-r--r--arch/powerpc/sysdev/fsl_lbc.c2
-rw-r--r--arch/x86/Kconfig2
-rw-r--r--arch/x86/include/asm/apic.h3
-rw-r--r--arch/x86/include/asm/io_apic.h11
-rw-r--r--arch/x86/kernel/apic/apic.c70
-rw-r--r--arch/x86/kernel/apic/io_apic.c140
21 files changed, 526 insertions, 66 deletions
diff --git a/arch/arm/mach-davinci/include/mach/nand.h b/arch/arm/mach-davinci/include/mach/nand.h
new file mode 100644
index 000000000000..aa482841270b
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/nand.h
@@ -0,0 +1,80 @@
1/*
2 * mach-davinci/nand.h
3 *
4 * Copyright © 2006 Texas Instruments.
5 *
6 * Ported to 2.6.23 Copyright © 2008 by
7 * Sander Huijsen <Shuijsen@optelecom-nkf.com>
8 * Troy Kisky <troy.kisky@boundarydevices.com>
9 * Dirk Behme <Dirk.Behme@gmail.com>
10 *
11 * --------------------------------------------------------------------------
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28#ifndef __ARCH_ARM_DAVINCI_NAND_H
29#define __ARCH_ARM_DAVINCI_NAND_H
30
31#include <linux/mtd/nand.h>
32
33#define NRCSR_OFFSET 0x00
34#define AWCCR_OFFSET 0x04
35#define A1CR_OFFSET 0x10
36#define NANDFCR_OFFSET 0x60
37#define NANDFSR_OFFSET 0x64
38#define NANDF1ECC_OFFSET 0x70
39
40/* 4-bit ECC syndrome registers */
41#define NAND_4BIT_ECC_LOAD_OFFSET 0xbc
42#define NAND_4BIT_ECC1_OFFSET 0xc0
43#define NAND_4BIT_ECC2_OFFSET 0xc4
44#define NAND_4BIT_ECC3_OFFSET 0xc8
45#define NAND_4BIT_ECC4_OFFSET 0xcc
46#define NAND_ERR_ADD1_OFFSET 0xd0
47#define NAND_ERR_ADD2_OFFSET 0xd4
48#define NAND_ERR_ERRVAL1_OFFSET 0xd8
49#define NAND_ERR_ERRVAL2_OFFSET 0xdc
50
51/* NOTE: boards don't need to use these address bits
52 * for ALE/CLE unless they support booting from NAND.
53 * They're used unless platform data overrides them.
54 */
55#define MASK_ALE 0x08
56#define MASK_CLE 0x10
57
58struct davinci_nand_pdata { /* platform_data */
59 uint32_t mask_ale;
60 uint32_t mask_cle;
61
62 /* for packages using two chipselects */
63 uint32_t mask_chipsel;
64
65 /* board's default static partition info */
66 struct mtd_partition *parts;
67 unsigned nr_parts;
68
69 /* none == NAND_ECC_NONE (strongly *not* advised!!)
70 * soft == NAND_ECC_SOFT
71 * 1-bit == NAND_ECC_HW
72 * 4-bit == NAND_ECC_HW_SYNDROME (not on all chips)
73 */
74 nand_ecc_modes_t ecc_mode;
75
76 /* e.g. NAND_BUSWIDTH_16 or NAND_USE_FLASH_BBT */
77 unsigned options;
78};
79
80#endif /* __ARCH_ARM_DAVINCI_NAND_H */
diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h b/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h
index eb35fca9aea5..3478eae32d8a 100644
--- a/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h
+++ b/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h
@@ -49,6 +49,9 @@ struct pxa3xx_nand_platform_data {
49 */ 49 */
50 int enable_arbiter; 50 int enable_arbiter;
51 51
52 /* allow platform code to keep OBM/bootloader defined NFC config */
53 int keep_config;
54
52 const struct mtd_partition *parts; 55 const struct mtd_partition *parts;
53 unsigned int nr_parts; 56 unsigned int nr_parts;
54 57
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index f49427293ca1..e040e03335ea 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -337,7 +337,7 @@ int _access_ok(unsigned long addr, unsigned long size)
337 if (addr >= memory_mtd_end && (addr + size) <= physical_mem_end) 337 if (addr >= memory_mtd_end && (addr + size) <= physical_mem_end)
338 return 1; 338 return 1;
339 339
340#ifdef CONFIG_ROMFS_MTD_FS 340#ifdef CONFIG_ROMFS_ON_MTD
341 /* For XIP, allow user space to use pointers within the ROMFS. */ 341 /* For XIP, allow user space to use pointers within the ROMFS. */
342 if (addr >= memory_mtd_start && (addr + size) <= memory_mtd_end) 342 if (addr >= memory_mtd_start && (addr + size) <= memory_mtd_end)
343 return 1; 343 return 1;
diff --git a/arch/frv/mm/tlb-miss.S b/arch/frv/mm/tlb-miss.S
index 07643482cad2..7f392bc651a3 100644
--- a/arch/frv/mm/tlb-miss.S
+++ b/arch/frv/mm/tlb-miss.S
@@ -13,7 +13,6 @@
13#include <linux/linkage.h> 13#include <linux/linkage.h>
14#include <asm/page.h> 14#include <asm/page.h>
15#include <asm/pgtable.h> 15#include <asm/pgtable.h>
16#include <asm/highmem.h>
17#include <asm/spr-regs.h> 16#include <asm/spr-regs.h>
18 17
19 .section .text.tlbmiss 18 .section .text.tlbmiss
diff --git a/arch/mips/include/asm/txx9/ndfmc.h b/arch/mips/include/asm/txx9/ndfmc.h
new file mode 100644
index 000000000000..fa67f3df78fc
--- /dev/null
+++ b/arch/mips/include/asm/txx9/ndfmc.h
@@ -0,0 +1,30 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
5 *
6 * (C) Copyright TOSHIBA CORPORATION 2007
7 */
8#ifndef __ASM_TXX9_NDFMC_H
9#define __ASM_TXX9_NDFMC_H
10
11#define NDFMC_PLAT_FLAG_USE_BSPRT 0x01
12#define NDFMC_PLAT_FLAG_NO_RSTR 0x02
13#define NDFMC_PLAT_FLAG_HOLDADD 0x04
14#define NDFMC_PLAT_FLAG_DUMMYWRITE 0x08
15
16struct txx9ndfmc_platform_data {
17 unsigned int shift;
18 unsigned int gbus_clock;
19 unsigned int hold; /* hold time in nanosecond */
20 unsigned int spw; /* strobe pulse width in nanosecond */
21 unsigned int flags;
22 unsigned char ch_mask; /* available channel bitmask */
23 unsigned char wp_mask; /* write-protect bitmask */
24 unsigned char wide_mask; /* 16bit-nand bitmask */
25};
26
27void txx9_ndfmc_init(unsigned long baseaddr,
28 const struct txx9ndfmc_platform_data *plat_data);
29
30#endif /* __ASM_TXX9_NDFMC_H */
diff --git a/arch/mips/include/asm/txx9/rbtx4939.h b/arch/mips/include/asm/txx9/rbtx4939.h
index 1acf428c0b4f..e517899794a8 100644
--- a/arch/mips/include/asm/txx9/rbtx4939.h
+++ b/arch/mips/include/asm/txx9/rbtx4939.h
@@ -130,4 +130,13 @@
130void rbtx4939_prom_init(void); 130void rbtx4939_prom_init(void);
131void rbtx4939_irq_setup(void); 131void rbtx4939_irq_setup(void);
132 132
133struct mtd_partition;
134struct map_info;
135struct rbtx4939_flash_data {
136 unsigned int width;
137 unsigned int nr_parts;
138 struct mtd_partition *parts;
139 void (*map_init)(struct map_info *map);
140};
141
133#endif /* __ASM_TXX9_RBTX4939_H */ 142#endif /* __ASM_TXX9_RBTX4939_H */
diff --git a/arch/mips/include/asm/txx9/tx4938.h b/arch/mips/include/asm/txx9/tx4938.h
index 0b068154054c..cd8bc2021755 100644
--- a/arch/mips/include/asm/txx9/tx4938.h
+++ b/arch/mips/include/asm/txx9/tx4938.h
@@ -291,6 +291,7 @@ int tx4938_pcic1_map_irq(const struct pci_dev *dev, u8 slot);
291void tx4938_setup_pcierr_irq(void); 291void tx4938_setup_pcierr_irq(void);
292void tx4938_irq_init(void); 292void tx4938_irq_init(void);
293void tx4938_mtd_init(int ch); 293void tx4938_mtd_init(int ch);
294void tx4938_ndfmc_init(unsigned int hold, unsigned int spw);
294 295
295struct tx4938ide_platform_info { 296struct tx4938ide_platform_info {
296 /* 297 /*
diff --git a/arch/mips/include/asm/txx9/tx4939.h b/arch/mips/include/asm/txx9/tx4939.h
index 964ef7ede268..f02c50b3abfb 100644
--- a/arch/mips/include/asm/txx9/tx4939.h
+++ b/arch/mips/include/asm/txx9/tx4939.h
@@ -542,5 +542,7 @@ int tx4939_irq(void);
542void tx4939_mtd_init(int ch); 542void tx4939_mtd_init(int ch);
543void tx4939_ata_init(void); 543void tx4939_ata_init(void);
544void tx4939_rtc_init(void); 544void tx4939_rtc_init(void);
545void tx4939_ndfmc_init(unsigned int hold, unsigned int spw,
546 unsigned char ch_mask, unsigned char wide_mask);
545 547
546#endif /* __ASM_TXX9_TX4939_H */ 548#endif /* __ASM_TXX9_TX4939_H */
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c
index a13a08b8c9ec..8a266c6a3f58 100644
--- a/arch/mips/txx9/generic/setup.c
+++ b/arch/mips/txx9/generic/setup.c
@@ -32,6 +32,7 @@
32#include <asm/txx9/generic.h> 32#include <asm/txx9/generic.h>
33#include <asm/txx9/pci.h> 33#include <asm/txx9/pci.h>
34#include <asm/txx9tmr.h> 34#include <asm/txx9tmr.h>
35#include <asm/txx9/ndfmc.h>
35#ifdef CONFIG_CPU_TX49XX 36#ifdef CONFIG_CPU_TX49XX
36#include <asm/txx9/tx4938.h> 37#include <asm/txx9/tx4938.h>
37#endif 38#endif
@@ -691,6 +692,26 @@ void __init txx9_physmap_flash_init(int no, unsigned long addr,
691#endif 692#endif
692} 693}
693 694
695void __init txx9_ndfmc_init(unsigned long baseaddr,
696 const struct txx9ndfmc_platform_data *pdata)
697{
698#if defined(CONFIG_MTD_NAND_TXX9NDFMC) || \
699 defined(CONFIG_MTD_NAND_TXX9NDFMC_MODULE)
700 struct resource res = {
701 .start = baseaddr,
702 .end = baseaddr + 0x1000 - 1,
703 .flags = IORESOURCE_MEM,
704 };
705 struct platform_device *pdev = platform_device_alloc("txx9ndfmc", -1);
706
707 if (!pdev ||
708 platform_device_add_resources(pdev, &res, 1) ||
709 platform_device_add_data(pdev, pdata, sizeof(*pdata)) ||
710 platform_device_add(pdev))
711 platform_device_put(pdev);
712#endif
713}
714
694#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) 715#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
695static DEFINE_SPINLOCK(txx9_iocled_lock); 716static DEFINE_SPINLOCK(txx9_iocled_lock);
696 717
diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c
index 25819ff1c350..f0844f891f0b 100644
--- a/arch/mips/txx9/generic/setup_tx4938.c
+++ b/arch/mips/txx9/generic/setup_tx4938.c
@@ -23,6 +23,7 @@
23#include <asm/txx9tmr.h> 23#include <asm/txx9tmr.h>
24#include <asm/txx9pio.h> 24#include <asm/txx9pio.h>
25#include <asm/txx9/generic.h> 25#include <asm/txx9/generic.h>
26#include <asm/txx9/ndfmc.h>
26#include <asm/txx9/tx4938.h> 27#include <asm/txx9/tx4938.h>
27 28
28static void __init tx4938_wdr_init(void) 29static void __init tx4938_wdr_init(void)
@@ -382,6 +383,26 @@ void __init tx4938_ata_init(unsigned int irq, unsigned int shift, int tune)
382 platform_device_put(pdev); 383 platform_device_put(pdev);
383} 384}
384 385
386void __init tx4938_ndfmc_init(unsigned int hold, unsigned int spw)
387{
388 struct txx9ndfmc_platform_data plat_data = {
389 .shift = 1,
390 .gbus_clock = txx9_gbus_clock,
391 .hold = hold,
392 .spw = spw,
393 .ch_mask = 1,
394 };
395 unsigned long baseaddr = TX4938_NDFMC_REG & 0xfffffffffULL;
396
397#ifdef __BIG_ENDIAN
398 baseaddr += 4;
399#endif
400 if ((__raw_readq(&tx4938_ccfgptr->pcfg) &
401 (TX4938_PCFG_ATA_SEL|TX4938_PCFG_ISA_SEL|TX4938_PCFG_NDF_SEL)) ==
402 TX4938_PCFG_NDF_SEL)
403 txx9_ndfmc_init(baseaddr, &plat_data);
404}
405
385static void __init tx4938_stop_unused_modules(void) 406static void __init tx4938_stop_unused_modules(void)
386{ 407{
387 __u64 pcfg, rst = 0, ckd = 0; 408 __u64 pcfg, rst = 0, ckd = 0;
diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c
index 55440967b3a8..7a25b573e9b0 100644
--- a/arch/mips/txx9/generic/setup_tx4939.c
+++ b/arch/mips/txx9/generic/setup_tx4939.c
@@ -27,6 +27,7 @@
27#include <asm/txx9irq.h> 27#include <asm/txx9irq.h>
28#include <asm/txx9tmr.h> 28#include <asm/txx9tmr.h>
29#include <asm/txx9/generic.h> 29#include <asm/txx9/generic.h>
30#include <asm/txx9/ndfmc.h>
30#include <asm/txx9/tx4939.h> 31#include <asm/txx9/tx4939.h>
31 32
32static void __init tx4939_wdr_init(void) 33static void __init tx4939_wdr_init(void)
@@ -457,6 +458,22 @@ void __init tx4939_rtc_init(void)
457 platform_device_register(&rtc_dev); 458 platform_device_register(&rtc_dev);
458} 459}
459 460
461void __init tx4939_ndfmc_init(unsigned int hold, unsigned int spw,
462 unsigned char ch_mask, unsigned char wide_mask)
463{
464 struct txx9ndfmc_platform_data plat_data = {
465 .shift = 1,
466 .gbus_clock = txx9_gbus_clock,
467 .hold = hold,
468 .spw = spw,
469 .flags = NDFMC_PLAT_FLAG_NO_RSTR | NDFMC_PLAT_FLAG_HOLDADD |
470 NDFMC_PLAT_FLAG_DUMMYWRITE,
471 .ch_mask = ch_mask,
472 .wide_mask = wide_mask,
473 };
474 txx9_ndfmc_init(TX4939_NDFMC_REG & 0xfffffffffULL, &plat_data);
475}
476
460static void __init tx4939_stop_unused_modules(void) 477static void __init tx4939_stop_unused_modules(void)
461{ 478{
462 __u64 pcfg, rst = 0, ckd = 0; 479 __u64 pcfg, rst = 0, ckd = 0;
diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c
index 547ff2920bf0..65d13df8878a 100644
--- a/arch/mips/txx9/rbtx4938/setup.c
+++ b/arch/mips/txx9/rbtx4938/setup.c
@@ -352,6 +352,8 @@ static void __init rbtx4938_device_init(void)
352 rbtx4938_ne_init(); 352 rbtx4938_ne_init();
353 tx4938_wdt_init(); 353 tx4938_wdt_init();
354 rbtx4938_mtd_init(); 354 rbtx4938_mtd_init();
355 /* TC58DVM82A1FT: tDH=10ns, tWP=tRP=tREADID=35ns */
356 tx4938_ndfmc_init(10, 35);
355 tx4938_ata_init(RBTX4938_IRQ_IOC_ATA, 0, 1); 357 tx4938_ata_init(RBTX4938_IRQ_IOC_ATA, 0, 1);
356 txx9_iocled_init(RBTX4938_LED_ADDR - IO_BASE, -1, 8, 1, "green", NULL); 358 txx9_iocled_init(RBTX4938_LED_ADDR - IO_BASE, -1, 8, 1, "green", NULL);
357} 359}
diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c
index 656603b85b71..011e1e332f47 100644
--- a/arch/mips/txx9/rbtx4939/setup.c
+++ b/arch/mips/txx9/rbtx4939/setup.c
@@ -16,6 +16,9 @@
16#include <linux/leds.h> 16#include <linux/leds.h>
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/smc91x.h> 18#include <linux/smc91x.h>
19#include <linux/mtd/mtd.h>
20#include <linux/mtd/partitions.h>
21#include <linux/mtd/map.h>
19#include <asm/reboot.h> 22#include <asm/reboot.h>
20#include <asm/txx9/generic.h> 23#include <asm/txx9/generic.h>
21#include <asm/txx9/pci.h> 24#include <asm/txx9/pci.h>
@@ -282,6 +285,159 @@ static void rbtx4939_7segled_putc(unsigned int pos, unsigned char val)
282 __rbtx4939_7segled_putc(pos, val); 285 __rbtx4939_7segled_putc(pos, val);
283} 286}
284 287
288#if defined(CONFIG_MTD_RBTX4939) || defined(CONFIG_MTD_RBTX4939_MODULE)
289/* special mapping for boot rom */
290static unsigned long rbtx4939_flash_fixup_ofs(unsigned long ofs)
291{
292 u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
293 unsigned char shift;
294
295 if (bdipsw & 8) {
296 /* BOOT Mode: USER ROM1 / USER ROM2 */
297 shift = bdipsw & 3;
298 /* rotate A[23:22] */
299 return (ofs & ~0xc00000) | ((((ofs >> 22) + shift) & 3) << 22);
300 }
301#ifdef __BIG_ENDIAN
302 if (bdipsw == 0)
303 /* BOOT Mode: Monitor ROM */
304 ofs ^= 0x400000; /* swap A[22] */
305#endif
306 return ofs;
307}
308
309static map_word rbtx4939_flash_read16(struct map_info *map, unsigned long ofs)
310{
311 map_word r;
312
313 ofs = rbtx4939_flash_fixup_ofs(ofs);
314 r.x[0] = __raw_readw(map->virt + ofs);
315 return r;
316}
317
318static void rbtx4939_flash_write16(struct map_info *map, const map_word datum,
319 unsigned long ofs)
320{
321 ofs = rbtx4939_flash_fixup_ofs(ofs);
322 __raw_writew(datum.x[0], map->virt + ofs);
323 mb(); /* see inline_map_write() in mtd/map.h */
324}
325
326static void rbtx4939_flash_copy_from(struct map_info *map, void *to,
327 unsigned long from, ssize_t len)
328{
329 u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
330 unsigned char shift;
331 ssize_t curlen;
332
333 from += (unsigned long)map->virt;
334 if (bdipsw & 8) {
335 /* BOOT Mode: USER ROM1 / USER ROM2 */
336 shift = bdipsw & 3;
337 while (len) {
338 curlen = min_t(unsigned long, len,
339 0x400000 - (from & (0x400000 - 1)));
340 memcpy(to,
341 (void *)((from & ~0xc00000) |
342 ((((from >> 22) + shift) & 3) << 22)),
343 curlen);
344 len -= curlen;
345 from += curlen;
346 to += curlen;
347 }
348 return;
349 }
350#ifdef __BIG_ENDIAN
351 if (bdipsw == 0) {
352 /* BOOT Mode: Monitor ROM */
353 while (len) {
354 curlen = min_t(unsigned long, len,
355 0x400000 - (from & (0x400000 - 1)));
356 memcpy(to, (void *)(from ^ 0x400000), curlen);
357 len -= curlen;
358 from += curlen;
359 to += curlen;
360 }
361 return;
362 }
363#endif
364 memcpy(to, (void *)from, len);
365}
366
367static void rbtx4939_flash_map_init(struct map_info *map)
368{
369 map->read = rbtx4939_flash_read16;
370 map->write = rbtx4939_flash_write16;
371 map->copy_from = rbtx4939_flash_copy_from;
372}
373
374static void __init rbtx4939_mtd_init(void)
375{
376 static struct {
377 struct platform_device dev;
378 struct resource res;
379 struct rbtx4939_flash_data data;
380 } pdevs[4];
381 int i;
382 static char names[4][8];
383 static struct mtd_partition parts[4];
384 struct rbtx4939_flash_data *boot_pdata = &pdevs[0].data;
385 u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
386
387 if (bdipsw & 8) {
388 /* BOOT Mode: USER ROM1 / USER ROM2 */
389 boot_pdata->nr_parts = 4;
390 for (i = 0; i < boot_pdata->nr_parts; i++) {
391 sprintf(names[i], "img%d", 4 - i);
392 parts[i].name = names[i];
393 parts[i].size = 0x400000;
394 parts[i].offset = MTDPART_OFS_NXTBLK;
395 }
396 } else if (bdipsw == 0) {
397 /* BOOT Mode: Monitor ROM */
398 boot_pdata->nr_parts = 2;
399 strcpy(names[0], "big");
400 strcpy(names[1], "little");
401 for (i = 0; i < boot_pdata->nr_parts; i++) {
402 parts[i].name = names[i];
403 parts[i].size = 0x400000;
404 parts[i].offset = MTDPART_OFS_NXTBLK;
405 }
406 } else {
407 /* BOOT Mode: ROM Emulator */
408 boot_pdata->nr_parts = 2;
409 parts[0].name = "boot";
410 parts[0].offset = 0xc00000;
411 parts[0].size = 0x400000;
412 parts[1].name = "user";
413 parts[1].offset = 0;
414 parts[1].size = 0xc00000;
415 }
416 boot_pdata->parts = parts;
417 boot_pdata->map_init = rbtx4939_flash_map_init;
418
419 for (i = 0; i < ARRAY_SIZE(pdevs); i++) {
420 struct resource *r = &pdevs[i].res;
421 struct platform_device *dev = &pdevs[i].dev;
422
423 r->start = 0x1f000000 - i * 0x1000000;
424 r->end = r->start + 0x1000000 - 1;
425 r->flags = IORESOURCE_MEM;
426 pdevs[i].data.width = 2;
427 dev->num_resources = 1;
428 dev->resource = r;
429 dev->id = i;
430 dev->name = "rbtx4939-flash";
431 dev->dev.platform_data = &pdevs[i].data;
432 platform_device_register(dev);
433 }
434}
435#else
436static void __init rbtx4939_mtd_init(void)
437{
438}
439#endif
440
285static void __init rbtx4939_arch_init(void) 441static void __init rbtx4939_arch_init(void)
286{ 442{
287 rbtx4939_pci_setup(); 443 rbtx4939_pci_setup();
@@ -333,6 +489,11 @@ static void __init rbtx4939_device_init(void)
333 platform_device_add_data(pdev, &smc_pdata, sizeof(smc_pdata)) || 489 platform_device_add_data(pdev, &smc_pdata, sizeof(smc_pdata)) ||
334 platform_device_add(pdev)) 490 platform_device_add(pdev))
335 platform_device_put(pdev); 491 platform_device_put(pdev);
492 rbtx4939_mtd_init();
493 /* TC58DVM82A1FT: tDH=10ns, tWP=tRP=tREADID=35ns */
494 tx4939_ndfmc_init(10, 35,
495 (1 << 1) | (1 << 2),
496 (1 << 2)); /* ch1:8bit, ch2:16bit */
336 rbtx4939_led_setup(); 497 rbtx4939_led_setup();
337 tx4939_wdt_init(); 498 tx4939_wdt_init();
338 tx4939_ata_init(); 499 tx4939_ata_init();
diff --git a/arch/powerpc/boot/dts/tqm8548-bigflash.dts b/arch/powerpc/boot/dts/tqm8548-bigflash.dts
index 28b1a95257cd..19aa72301c83 100644
--- a/arch/powerpc/boot/dts/tqm8548-bigflash.dts
+++ b/arch/powerpc/boot/dts/tqm8548-bigflash.dts
@@ -397,10 +397,13 @@
397 upm@3,0 { 397 upm@3,0 {
398 #address-cells = <0>; 398 #address-cells = <0>;
399 #size-cells = <0>; 399 #size-cells = <0>;
400 compatible = "fsl,upm-nand"; 400 compatible = "tqc,tqm8548-upm-nand", "fsl,upm-nand";
401 reg = <3 0x0 0x800>; 401 reg = <3 0x0 0x800>;
402 fsl,upm-addr-offset = <0x10>; 402 fsl,upm-addr-offset = <0x10>;
403 fsl,upm-cmd-offset = <0x08>; 403 fsl,upm-cmd-offset = <0x08>;
404 /* Micron MT29F8G08FAB multi-chip device */
405 fsl,upm-addr-line-cs-offsets = <0x0 0x200>;
406 fsl,upm-wait-flags = <0x5>;
404 chip-delay = <25>; // in micro-seconds 407 chip-delay = <25>; // in micro-seconds
405 408
406 nand@0 { 409 nand@0 {
@@ -409,7 +412,7 @@
409 412
410 partition@0 { 413 partition@0 {
411 label = "fs"; 414 label = "fs";
412 reg = <0x00000000 0x01000000>; 415 reg = <0x00000000 0x10000000>;
413 }; 416 };
414 }; 417 };
415 }; 418 };
diff --git a/arch/powerpc/boot/dts/tqm8548.dts b/arch/powerpc/boot/dts/tqm8548.dts
index 826fb622cd3c..49145a04fc6c 100644
--- a/arch/powerpc/boot/dts/tqm8548.dts
+++ b/arch/powerpc/boot/dts/tqm8548.dts
@@ -397,10 +397,13 @@
397 upm@3,0 { 397 upm@3,0 {
398 #address-cells = <0>; 398 #address-cells = <0>;
399 #size-cells = <0>; 399 #size-cells = <0>;
400 compatible = "fsl,upm-nand"; 400 compatible = "tqc,tqm8548-upm-nand", "fsl,upm-nand";
401 reg = <3 0x0 0x800>; 401 reg = <3 0x0 0x800>;
402 fsl,upm-addr-offset = <0x10>; 402 fsl,upm-addr-offset = <0x10>;
403 fsl,upm-cmd-offset = <0x08>; 403 fsl,upm-cmd-offset = <0x08>;
404 /* Micron MT29F8G08FAB multi-chip device */
405 fsl,upm-addr-line-cs-offsets = <0x0 0x200>;
406 fsl,upm-wait-flags = <0x5>;
404 chip-delay = <25>; // in micro-seconds 407 chip-delay = <25>; // in micro-seconds
405 408
406 nand@0 { 409 nand@0 {
@@ -409,7 +412,7 @@
409 412
410 partition@0 { 413 partition@0 {
411 label = "fs"; 414 label = "fs";
412 reg = <0x00000000 0x01000000>; 415 reg = <0x00000000 0x10000000>;
413 }; 416 };
414 }; 417 };
415 }; 418 };
diff --git a/arch/powerpc/sysdev/fsl_lbc.c b/arch/powerpc/sysdev/fsl_lbc.c
index 0494ee55920f..dceb8d1a843d 100644
--- a/arch/powerpc/sysdev/fsl_lbc.c
+++ b/arch/powerpc/sysdev/fsl_lbc.c
@@ -150,7 +150,7 @@ int fsl_upm_run_pattern(struct fsl_upm *upm, void __iomem *io_base, u32 mar)
150 150
151 spin_lock_irqsave(&fsl_lbc_lock, flags); 151 spin_lock_irqsave(&fsl_lbc_lock, flags);
152 152
153 out_be32(&fsl_lbc_regs->mar, mar << (32 - upm->width)); 153 out_be32(&fsl_lbc_regs->mar, mar);
154 154
155 switch (upm->width) { 155 switch (upm->width) {
156 case 8: 156 case 8:
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index bcf4cae711b4..6da24fc6a09e 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -253,6 +253,7 @@ config SMP
253config X86_X2APIC 253config X86_X2APIC
254 bool "Support x2apic" 254 bool "Support x2apic"
255 depends on X86_LOCAL_APIC && X86_64 255 depends on X86_LOCAL_APIC && X86_64
256 select INTR_REMAP
256 ---help--- 257 ---help---
257 This enables x2apic support on CPUs that have this feature. 258 This enables x2apic support on CPUs that have this feature.
258 259
@@ -1882,7 +1883,6 @@ config DMAR_FLOPPY_WA
1882config INTR_REMAP 1883config INTR_REMAP
1883 bool "Support for Interrupt Remapping (EXPERIMENTAL)" 1884 bool "Support for Interrupt Remapping (EXPERIMENTAL)"
1884 depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL 1885 depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI && EXPERIMENTAL
1885 select X86_X2APIC
1886 ---help--- 1886 ---help---
1887 Supports Interrupt remapping for IO-APIC and MSI devices. 1887 Supports Interrupt remapping for IO-APIC and MSI devices.
1888 To use x2apic mode in the CPU's which support x2APIC enhancements or 1888 To use x2apic mode in the CPU's which support x2APIC enhancements or
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index df8a300dfe6c..42f2f8377422 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -107,6 +107,9 @@ extern u32 native_safe_apic_wait_icr_idle(void);
107extern void native_apic_icr_write(u32 low, u32 id); 107extern void native_apic_icr_write(u32 low, u32 id);
108extern u64 native_apic_icr_read(void); 108extern u64 native_apic_icr_read(void);
109 109
110#define EIM_8BIT_APIC_ID 0
111#define EIM_32BIT_APIC_ID 1
112
110#ifdef CONFIG_X86_X2APIC 113#ifdef CONFIG_X86_X2APIC
111/* 114/*
112 * Make previous memory operations globally visible before 115 * Make previous memory operations globally visible before
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 373cc2bbcad2..9d826e436010 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -162,10 +162,13 @@ extern int (*ioapic_renumber_irq)(int ioapic, int irq);
162extern void ioapic_init_mappings(void); 162extern void ioapic_init_mappings(void);
163 163
164#ifdef CONFIG_X86_64 164#ifdef CONFIG_X86_64
165extern int save_IO_APIC_setup(void); 165extern struct IO_APIC_route_entry **alloc_ioapic_entries(void);
166extern void mask_IO_APIC_setup(void); 166extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries);
167extern void restore_IO_APIC_setup(void); 167extern int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
168extern void reinit_intr_remapped_IO_APIC(int); 168extern void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
169extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
170extern void reinit_intr_remapped_IO_APIC(int intr_remapping,
171 struct IO_APIC_route_entry **ioapic_entries);
169#endif 172#endif
170 173
171extern void probe_nr_irqs_gsi(void); 174extern void probe_nr_irqs_gsi(void);
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index b0e5e712a7af..fb504f843e58 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1308,6 +1308,7 @@ void __init enable_IR_x2apic(void)
1308#ifdef CONFIG_INTR_REMAP 1308#ifdef CONFIG_INTR_REMAP
1309 int ret; 1309 int ret;
1310 unsigned long flags; 1310 unsigned long flags;
1311 struct IO_APIC_route_entry **ioapic_entries = NULL;
1311 1312
1312 if (!cpu_has_x2apic) 1313 if (!cpu_has_x2apic)
1313 return; 1314 return;
@@ -1338,17 +1339,23 @@ void __init enable_IR_x2apic(void)
1338 return; 1339 return;
1339 } 1340 }
1340 1341
1341 ret = save_IO_APIC_setup(); 1342 ioapic_entries = alloc_ioapic_entries();
1343 if (!ioapic_entries) {
1344 pr_info("Allocate ioapic_entries failed: %d\n", ret);
1345 goto end;
1346 }
1347
1348 ret = save_IO_APIC_setup(ioapic_entries);
1342 if (ret) { 1349 if (ret) {
1343 pr_info("Saving IO-APIC state failed: %d\n", ret); 1350 pr_info("Saving IO-APIC state failed: %d\n", ret);
1344 goto end; 1351 goto end;
1345 } 1352 }
1346 1353
1347 local_irq_save(flags); 1354 local_irq_save(flags);
1348 mask_IO_APIC_setup(); 1355 mask_IO_APIC_setup(ioapic_entries);
1349 mask_8259A(); 1356 mask_8259A();
1350 1357
1351 ret = enable_intr_remapping(1); 1358 ret = enable_intr_remapping(EIM_32BIT_APIC_ID);
1352 1359
1353 if (ret && x2apic_preenabled) { 1360 if (ret && x2apic_preenabled) {
1354 local_irq_restore(flags); 1361 local_irq_restore(flags);
@@ -1368,9 +1375,9 @@ end_restore:
1368 /* 1375 /*
1369 * IR enabling failed 1376 * IR enabling failed
1370 */ 1377 */
1371 restore_IO_APIC_setup(); 1378 restore_IO_APIC_setup(ioapic_entries);
1372 else 1379 else
1373 reinit_intr_remapped_IO_APIC(x2apic_preenabled); 1380 reinit_intr_remapped_IO_APIC(x2apic_preenabled, ioapic_entries);
1374 1381
1375 unmask_8259A(); 1382 unmask_8259A();
1376 local_irq_restore(flags); 1383 local_irq_restore(flags);
@@ -1383,6 +1390,8 @@ end:
1383 pr_info("Enabled Interrupt-remapping\n"); 1390 pr_info("Enabled Interrupt-remapping\n");
1384 } else 1391 } else
1385 pr_err("Failed to enable Interrupt-remapping and x2apic\n"); 1392 pr_err("Failed to enable Interrupt-remapping and x2apic\n");
1393 if (ioapic_entries)
1394 free_ioapic_entries(ioapic_entries);
1386#else 1395#else
1387 if (!cpu_has_x2apic) 1396 if (!cpu_has_x2apic)
1388 return; 1397 return;
@@ -1958,6 +1967,10 @@ static int lapic_suspend(struct sys_device *dev, pm_message_t state)
1958 1967
1959 local_irq_save(flags); 1968 local_irq_save(flags);
1960 disable_local_APIC(); 1969 disable_local_APIC();
1970#ifdef CONFIG_INTR_REMAP
1971 if (intr_remapping_enabled)
1972 disable_intr_remapping();
1973#endif
1961 local_irq_restore(flags); 1974 local_irq_restore(flags);
1962 return 0; 1975 return 0;
1963} 1976}
@@ -1968,15 +1981,41 @@ static int lapic_resume(struct sys_device *dev)
1968 unsigned long flags; 1981 unsigned long flags;
1969 int maxlvt; 1982 int maxlvt;
1970 1983
1984#ifdef CONFIG_INTR_REMAP
1985 int ret;
1986 struct IO_APIC_route_entry **ioapic_entries = NULL;
1987
1971 if (!apic_pm_state.active) 1988 if (!apic_pm_state.active)
1972 return 0; 1989 return 0;
1973 1990
1974 maxlvt = lapic_get_maxlvt();
1975
1976 local_irq_save(flags); 1991 local_irq_save(flags);
1992 if (x2apic) {
1993 ioapic_entries = alloc_ioapic_entries();
1994 if (!ioapic_entries) {
1995 WARN(1, "Alloc ioapic_entries in lapic resume failed.");
1996 return -ENOMEM;
1997 }
1998
1999 ret = save_IO_APIC_setup(ioapic_entries);
2000 if (ret) {
2001 WARN(1, "Saving IO-APIC state failed: %d\n", ret);
2002 free_ioapic_entries(ioapic_entries);
2003 return ret;
2004 }
2005
2006 mask_IO_APIC_setup(ioapic_entries);
2007 mask_8259A();
2008 enable_x2apic();
2009 }
2010#else
2011 if (!apic_pm_state.active)
2012 return 0;
1977 2013
2014 local_irq_save(flags);
1978 if (x2apic) 2015 if (x2apic)
1979 enable_x2apic(); 2016 enable_x2apic();
2017#endif
2018
1980 else { 2019 else {
1981 /* 2020 /*
1982 * Make sure the APICBASE points to the right address 2021 * Make sure the APICBASE points to the right address
@@ -1990,6 +2029,7 @@ static int lapic_resume(struct sys_device *dev)
1990 wrmsr(MSR_IA32_APICBASE, l, h); 2029 wrmsr(MSR_IA32_APICBASE, l, h);
1991 } 2030 }
1992 2031
2032 maxlvt = lapic_get_maxlvt();
1993 apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED); 2033 apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED);
1994 apic_write(APIC_ID, apic_pm_state.apic_id); 2034 apic_write(APIC_ID, apic_pm_state.apic_id);
1995 apic_write(APIC_DFR, apic_pm_state.apic_dfr); 2035 apic_write(APIC_DFR, apic_pm_state.apic_dfr);
@@ -2013,8 +2053,20 @@ static int lapic_resume(struct sys_device *dev)
2013 apic_write(APIC_ESR, 0); 2053 apic_write(APIC_ESR, 0);
2014 apic_read(APIC_ESR); 2054 apic_read(APIC_ESR);
2015 2055
2056#ifdef CONFIG_INTR_REMAP
2057 if (intr_remapping_enabled)
2058 reenable_intr_remapping(EIM_32BIT_APIC_ID);
2059
2060 if (x2apic) {
2061 unmask_8259A();
2062 restore_IO_APIC_setup(ioapic_entries);
2063 free_ioapic_entries(ioapic_entries);
2064 }
2065#endif
2066
2016 local_irq_restore(flags); 2067 local_irq_restore(flags);
2017 2068
2069
2018 return 0; 2070 return 0;
2019} 2071}
2020 2072
@@ -2052,7 +2104,9 @@ static int __init init_lapic_sysfs(void)
2052 error = sysdev_register(&device_lapic); 2104 error = sysdev_register(&device_lapic);
2053 return error; 2105 return error;
2054} 2106}
2055device_initcall(init_lapic_sysfs); 2107
2108/* local apic needs to resume before other devices access its registers. */
2109core_initcall(init_lapic_sysfs);
2056 2110
2057#else /* CONFIG_PM */ 2111#else /* CONFIG_PM */
2058 2112
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 1bb5c6cee3eb..767fe7e46d68 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -851,63 +851,74 @@ __setup("pirq=", ioapic_pirq_setup);
851#endif /* CONFIG_X86_32 */ 851#endif /* CONFIG_X86_32 */
852 852
853#ifdef CONFIG_INTR_REMAP 853#ifdef CONFIG_INTR_REMAP
854/* I/O APIC RTE contents at the OS boot up */ 854struct IO_APIC_route_entry **alloc_ioapic_entries(void)
855static struct IO_APIC_route_entry *early_ioapic_entries[MAX_IO_APICS]; 855{
856 int apic;
857 struct IO_APIC_route_entry **ioapic_entries;
858
859 ioapic_entries = kzalloc(sizeof(*ioapic_entries) * nr_ioapics,
860 GFP_ATOMIC);
861 if (!ioapic_entries)
862 return 0;
863
864 for (apic = 0; apic < nr_ioapics; apic++) {
865 ioapic_entries[apic] =
866 kzalloc(sizeof(struct IO_APIC_route_entry) *
867 nr_ioapic_registers[apic], GFP_ATOMIC);
868 if (!ioapic_entries[apic])
869 goto nomem;
870 }
871
872 return ioapic_entries;
873
874nomem:
875 while (--apic >= 0)
876 kfree(ioapic_entries[apic]);
877 kfree(ioapic_entries);
878
879 return 0;
880}
856 881
857/* 882/*
858 * Saves all the IO-APIC RTE's 883 * Saves all the IO-APIC RTE's
859 */ 884 */
860int save_IO_APIC_setup(void) 885int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
861{ 886{
862 union IO_APIC_reg_01 reg_01;
863 unsigned long flags;
864 int apic, pin; 887 int apic, pin;
865 888
866 /* 889 if (!ioapic_entries)
867 * The number of IO-APIC IRQ registers (== #pins): 890 return -ENOMEM;
868 */
869 for (apic = 0; apic < nr_ioapics; apic++) {
870 spin_lock_irqsave(&ioapic_lock, flags);
871 reg_01.raw = io_apic_read(apic, 1);
872 spin_unlock_irqrestore(&ioapic_lock, flags);
873 nr_ioapic_registers[apic] = reg_01.bits.entries+1;
874 }
875 891
876 for (apic = 0; apic < nr_ioapics; apic++) { 892 for (apic = 0; apic < nr_ioapics; apic++) {
877 early_ioapic_entries[apic] = 893 if (!ioapic_entries[apic])
878 kzalloc(sizeof(struct IO_APIC_route_entry) * 894 return -ENOMEM;
879 nr_ioapic_registers[apic], GFP_KERNEL);
880 if (!early_ioapic_entries[apic])
881 goto nomem;
882 }
883 895
884 for (apic = 0; apic < nr_ioapics; apic++)
885 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) 896 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
886 early_ioapic_entries[apic][pin] = 897 ioapic_entries[apic][pin] =
887 ioapic_read_entry(apic, pin); 898 ioapic_read_entry(apic, pin);
899 }
888 900
889 return 0; 901 return 0;
890
891nomem:
892 while (apic >= 0)
893 kfree(early_ioapic_entries[apic--]);
894 memset(early_ioapic_entries, 0,
895 ARRAY_SIZE(early_ioapic_entries));
896
897 return -ENOMEM;
898} 902}
899 903
900void mask_IO_APIC_setup(void) 904/*
905 * Mask all IO APIC entries.
906 */
907void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
901{ 908{
902 int apic, pin; 909 int apic, pin;
903 910
911 if (!ioapic_entries)
912 return;
913
904 for (apic = 0; apic < nr_ioapics; apic++) { 914 for (apic = 0; apic < nr_ioapics; apic++) {
905 if (!early_ioapic_entries[apic]) 915 if (!ioapic_entries[apic])
906 break; 916 break;
917
907 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) { 918 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
908 struct IO_APIC_route_entry entry; 919 struct IO_APIC_route_entry entry;
909 920
910 entry = early_ioapic_entries[apic][pin]; 921 entry = ioapic_entries[apic][pin];
911 if (!entry.mask) { 922 if (!entry.mask) {
912 entry.mask = 1; 923 entry.mask = 1;
913 ioapic_write_entry(apic, pin, entry); 924 ioapic_write_entry(apic, pin, entry);
@@ -916,22 +927,30 @@ void mask_IO_APIC_setup(void)
916 } 927 }
917} 928}
918 929
919void restore_IO_APIC_setup(void) 930/*
931 * Restore IO APIC entries which was saved in ioapic_entries.
932 */
933int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
920{ 934{
921 int apic, pin; 935 int apic, pin;
922 936
937 if (!ioapic_entries)
938 return -ENOMEM;
939
923 for (apic = 0; apic < nr_ioapics; apic++) { 940 for (apic = 0; apic < nr_ioapics; apic++) {
924 if (!early_ioapic_entries[apic]) 941 if (!ioapic_entries[apic])
925 break; 942 return -ENOMEM;
943
926 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) 944 for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
927 ioapic_write_entry(apic, pin, 945 ioapic_write_entry(apic, pin,
928 early_ioapic_entries[apic][pin]); 946 ioapic_entries[apic][pin]);
929 kfree(early_ioapic_entries[apic]);
930 early_ioapic_entries[apic] = NULL;
931 } 947 }
948 return 0;
932} 949}
933 950
934void reinit_intr_remapped_IO_APIC(int intr_remapping) 951void reinit_intr_remapped_IO_APIC(int intr_remapping,
952 struct IO_APIC_route_entry **ioapic_entries)
953
935{ 954{
936 /* 955 /*
937 * for now plain restore of previous settings. 956 * for now plain restore of previous settings.
@@ -940,7 +959,17 @@ void reinit_intr_remapped_IO_APIC(int intr_remapping)
940 * table entries. for now, do a plain restore, and wait for 959 * table entries. for now, do a plain restore, and wait for
941 * the setup_IO_APIC_irqs() to do proper initialization. 960 * the setup_IO_APIC_irqs() to do proper initialization.
942 */ 961 */
943 restore_IO_APIC_setup(); 962 restore_IO_APIC_setup(ioapic_entries);
963}
964
965void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries)
966{
967 int apic;
968
969 for (apic = 0; apic < nr_ioapics; apic++)
970 kfree(ioapic_entries[apic]);
971
972 kfree(ioapic_entries);
944} 973}
945#endif 974#endif
946 975
@@ -2495,7 +2524,7 @@ static void irq_complete_move(struct irq_desc **descp)
2495static inline void irq_complete_move(struct irq_desc **descp) {} 2524static inline void irq_complete_move(struct irq_desc **descp) {}
2496#endif 2525#endif
2497 2526
2498#ifdef CONFIG_INTR_REMAP 2527#ifdef CONFIG_X86_X2APIC
2499static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) 2528static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg)
2500{ 2529{
2501 int apic, pin; 2530 int apic, pin;
@@ -2540,7 +2569,6 @@ static void ack_x2apic_edge(unsigned int irq)
2540{ 2569{
2541 ack_x2APIC_irq(); 2570 ack_x2APIC_irq();
2542} 2571}
2543
2544#endif 2572#endif
2545 2573
2546static void ack_apic_edge(unsigned int irq) 2574static void ack_apic_edge(unsigned int irq)
@@ -2651,6 +2679,26 @@ static void ack_apic_level(unsigned int irq)
2651#endif 2679#endif
2652} 2680}
2653 2681
2682#ifdef CONFIG_INTR_REMAP
2683static void ir_ack_apic_edge(unsigned int irq)
2684{
2685#ifdef CONFIG_X86_X2APIC
2686 if (x2apic_enabled())
2687 return ack_x2apic_edge(irq);
2688#endif
2689 return ack_apic_edge(irq);
2690}
2691
2692static void ir_ack_apic_level(unsigned int irq)
2693{
2694#ifdef CONFIG_X86_X2APIC
2695 if (x2apic_enabled())
2696 return ack_x2apic_level(irq);
2697#endif
2698 return ack_apic_level(irq);
2699}
2700#endif /* CONFIG_INTR_REMAP */
2701
2654static struct irq_chip ioapic_chip __read_mostly = { 2702static struct irq_chip ioapic_chip __read_mostly = {
2655 .name = "IO-APIC", 2703 .name = "IO-APIC",
2656 .startup = startup_ioapic_irq, 2704 .startup = startup_ioapic_irq,
@@ -2670,8 +2718,8 @@ static struct irq_chip ir_ioapic_chip __read_mostly = {
2670 .mask = mask_IO_APIC_irq, 2718 .mask = mask_IO_APIC_irq,
2671 .unmask = unmask_IO_APIC_irq, 2719 .unmask = unmask_IO_APIC_irq,
2672#ifdef CONFIG_INTR_REMAP 2720#ifdef CONFIG_INTR_REMAP
2673 .ack = ack_x2apic_edge, 2721 .ack = ir_ack_apic_edge,
2674 .eoi = ack_x2apic_level, 2722 .eoi = ir_ack_apic_level,
2675#ifdef CONFIG_SMP 2723#ifdef CONFIG_SMP
2676 .set_affinity = set_ir_ioapic_affinity_irq, 2724 .set_affinity = set_ir_ioapic_affinity_irq,
2677#endif 2725#endif
@@ -3397,7 +3445,7 @@ static struct irq_chip msi_ir_chip = {
3397 .unmask = unmask_msi_irq, 3445 .unmask = unmask_msi_irq,
3398 .mask = mask_msi_irq, 3446 .mask = mask_msi_irq,
3399#ifdef CONFIG_INTR_REMAP 3447#ifdef CONFIG_INTR_REMAP
3400 .ack = ack_x2apic_edge, 3448 .ack = ir_ack_apic_edge,
3401#ifdef CONFIG_SMP 3449#ifdef CONFIG_SMP
3402 .set_affinity = ir_set_msi_irq_affinity, 3450 .set_affinity = ir_set_msi_irq_affinity,
3403#endif 3451#endif