diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-davinci/include/mach/nand.h | 80 | ||||
-rw-r--r-- | arch/arm/mach-pxa/include/mach/pxa3xx_nand.h | 3 | ||||
-rw-r--r-- | arch/blackfin/kernel/process.c | 2 | ||||
-rw-r--r-- | arch/frv/mm/tlb-miss.S | 1 | ||||
-rw-r--r-- | arch/mips/include/asm/txx9/ndfmc.h | 30 | ||||
-rw-r--r-- | arch/mips/include/asm/txx9/rbtx4939.h | 9 | ||||
-rw-r--r-- | arch/mips/include/asm/txx9/tx4938.h | 1 | ||||
-rw-r--r-- | arch/mips/include/asm/txx9/tx4939.h | 2 | ||||
-rw-r--r-- | arch/mips/txx9/generic/setup.c | 21 | ||||
-rw-r--r-- | arch/mips/txx9/generic/setup_tx4938.c | 21 | ||||
-rw-r--r-- | arch/mips/txx9/generic/setup_tx4939.c | 17 | ||||
-rw-r--r-- | arch/mips/txx9/rbtx4938/setup.c | 2 | ||||
-rw-r--r-- | arch/mips/txx9/rbtx4939/setup.c | 161 | ||||
-rw-r--r-- | arch/powerpc/boot/dts/tqm8548-bigflash.dts | 7 | ||||
-rw-r--r-- | arch/powerpc/boot/dts/tqm8548.dts | 7 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_lbc.c | 2 | ||||
-rw-r--r-- | arch/x86/Kconfig | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/apic.h | 3 | ||||
-rw-r--r-- | arch/x86/include/asm/io_apic.h | 11 | ||||
-rw-r--r-- | arch/x86/kernel/apic/apic.c | 70 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 140 |
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 | |||
58 | struct 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 | |||
16 | struct 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 | |||
27 | void 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 @@ | |||
130 | void rbtx4939_prom_init(void); | 130 | void rbtx4939_prom_init(void); |
131 | void rbtx4939_irq_setup(void); | 131 | void rbtx4939_irq_setup(void); |
132 | 132 | ||
133 | struct mtd_partition; | ||
134 | struct map_info; | ||
135 | struct 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); | |||
291 | void tx4938_setup_pcierr_irq(void); | 291 | void tx4938_setup_pcierr_irq(void); |
292 | void tx4938_irq_init(void); | 292 | void tx4938_irq_init(void); |
293 | void tx4938_mtd_init(int ch); | 293 | void tx4938_mtd_init(int ch); |
294 | void tx4938_ndfmc_init(unsigned int hold, unsigned int spw); | ||
294 | 295 | ||
295 | struct tx4938ide_platform_info { | 296 | struct 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); | |||
542 | void tx4939_mtd_init(int ch); | 542 | void tx4939_mtd_init(int ch); |
543 | void tx4939_ata_init(void); | 543 | void tx4939_ata_init(void); |
544 | void tx4939_rtc_init(void); | 544 | void tx4939_rtc_init(void); |
545 | void 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 | ||
695 | void __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) |
695 | static DEFINE_SPINLOCK(txx9_iocled_lock); | 716 | static 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 | ||
28 | static void __init tx4938_wdr_init(void) | 29 | static 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 | ||
386 | void __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 | |||
385 | static void __init tx4938_stop_unused_modules(void) | 406 | static 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 | ||
32 | static void __init tx4939_wdr_init(void) | 33 | static 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 | ||
461 | void __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 | |||
460 | static void __init tx4939_stop_unused_modules(void) | 477 | static 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 */ | ||
290 | static 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 | |||
309 | static 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 | |||
318 | static 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 | |||
326 | static 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 | |||
367 | static 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 | |||
374 | static 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 | ||
436 | static void __init rbtx4939_mtd_init(void) | ||
437 | { | ||
438 | } | ||
439 | #endif | ||
440 | |||
285 | static void __init rbtx4939_arch_init(void) | 441 | static 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 | |||
253 | config X86_X2APIC | 253 | config 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 | |||
1882 | config INTR_REMAP | 1883 | config 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); | |||
107 | extern void native_apic_icr_write(u32 low, u32 id); | 107 | extern void native_apic_icr_write(u32 low, u32 id); |
108 | extern u64 native_apic_icr_read(void); | 108 | extern 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); | |||
162 | extern void ioapic_init_mappings(void); | 162 | extern void ioapic_init_mappings(void); |
163 | 163 | ||
164 | #ifdef CONFIG_X86_64 | 164 | #ifdef CONFIG_X86_64 |
165 | extern int save_IO_APIC_setup(void); | 165 | extern struct IO_APIC_route_entry **alloc_ioapic_entries(void); |
166 | extern void mask_IO_APIC_setup(void); | 166 | extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries); |
167 | extern void restore_IO_APIC_setup(void); | 167 | extern int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries); |
168 | extern void reinit_intr_remapped_IO_APIC(int); | 168 | extern void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries); |
169 | extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries); | ||
170 | extern void reinit_intr_remapped_IO_APIC(int intr_remapping, | ||
171 | struct IO_APIC_route_entry **ioapic_entries); | ||
169 | #endif | 172 | #endif |
170 | 173 | ||
171 | extern void probe_nr_irqs_gsi(void); | 174 | extern 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 | } |
2055 | device_initcall(init_lapic_sysfs); | 2107 | |
2108 | /* local apic needs to resume before other devices access its registers. */ | ||
2109 | core_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 */ | 854 | struct IO_APIC_route_entry **alloc_ioapic_entries(void) |
855 | static 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 | |||
874 | nomem: | ||
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 | */ |
860 | int save_IO_APIC_setup(void) | 885 | int 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 | |||
891 | nomem: | ||
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 | ||
900 | void mask_IO_APIC_setup(void) | 904 | /* |
905 | * Mask all IO APIC entries. | ||
906 | */ | ||
907 | void 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 | ||
919 | void restore_IO_APIC_setup(void) | 930 | /* |
931 | * Restore IO APIC entries which was saved in ioapic_entries. | ||
932 | */ | ||
933 | int 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 | ||
934 | void reinit_intr_remapped_IO_APIC(int intr_remapping) | 951 | void 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 | |||
965 | void 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) | |||
2495 | static inline void irq_complete_move(struct irq_desc **descp) {} | 2524 | static 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 |
2499 | static void __eoi_ioapic_irq(unsigned int irq, struct irq_cfg *cfg) | 2528 | static 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 | ||
2546 | static void ack_apic_edge(unsigned int irq) | 2574 | static 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 | ||
2683 | static 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 | |||
2692 | static 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 | |||
2654 | static struct irq_chip ioapic_chip __read_mostly = { | 2702 | static 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 |