diff options
Diffstat (limited to 'arch')
327 files changed, 5616 insertions, 3552 deletions
diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c index 1383f8601a93..1d4aabfcf9a1 100644 --- a/arch/alpha/kernel/sys_nautilus.c +++ b/arch/alpha/kernel/sys_nautilus.c | |||
@@ -185,7 +185,6 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr) | |||
185 | mb(); | 185 | mb(); |
186 | } | 186 | } |
187 | 187 | ||
188 | extern void free_reserved_mem(void *, void *); | ||
189 | extern void pcibios_claim_one_bus(struct pci_bus *); | 188 | extern void pcibios_claim_one_bus(struct pci_bus *); |
190 | 189 | ||
191 | static struct resource irongate_io = { | 190 | static struct resource irongate_io = { |
@@ -239,8 +238,8 @@ nautilus_init_pci(void) | |||
239 | if (pci_mem < memtop) | 238 | if (pci_mem < memtop) |
240 | memtop = pci_mem; | 239 | memtop = pci_mem; |
241 | if (memtop > alpha_mv.min_mem_address) { | 240 | if (memtop > alpha_mv.min_mem_address) { |
242 | free_reserved_mem(__va(alpha_mv.min_mem_address), | 241 | free_reserved_area((unsigned long)__va(alpha_mv.min_mem_address), |
243 | __va(memtop)); | 242 | (unsigned long)__va(memtop), 0, NULL); |
244 | printk("nautilus_init_pci: %ldk freed\n", | 243 | printk("nautilus_init_pci: %ldk freed\n", |
245 | (memtop - alpha_mv.min_mem_address) >> 10); | 244 | (memtop - alpha_mv.min_mem_address) >> 10); |
246 | } | 245 | } |
diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c index 1ad6ca74bed2..0ba85ee4a466 100644 --- a/arch/alpha/mm/init.c +++ b/arch/alpha/mm/init.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <asm/console.h> | 31 | #include <asm/console.h> |
32 | #include <asm/tlb.h> | 32 | #include <asm/tlb.h> |
33 | #include <asm/setup.h> | 33 | #include <asm/setup.h> |
34 | #include <asm/sections.h> | ||
34 | 35 | ||
35 | extern void die_if_kernel(char *,struct pt_regs *,long); | 36 | extern void die_if_kernel(char *,struct pt_regs *,long); |
36 | 37 | ||
@@ -281,8 +282,6 @@ printk_memory_info(void) | |||
281 | { | 282 | { |
282 | unsigned long codesize, reservedpages, datasize, initsize, tmp; | 283 | unsigned long codesize, reservedpages, datasize, initsize, tmp; |
283 | extern int page_is_ram(unsigned long) __init; | 284 | extern int page_is_ram(unsigned long) __init; |
284 | extern char _text, _etext, _data, _edata; | ||
285 | extern char __init_begin, __init_end; | ||
286 | 285 | ||
287 | /* printk all informations */ | 286 | /* printk all informations */ |
288 | reservedpages = 0; | 287 | reservedpages = 0; |
@@ -318,32 +317,15 @@ mem_init(void) | |||
318 | #endif /* CONFIG_DISCONTIGMEM */ | 317 | #endif /* CONFIG_DISCONTIGMEM */ |
319 | 318 | ||
320 | void | 319 | void |
321 | free_reserved_mem(void *start, void *end) | ||
322 | { | ||
323 | void *__start = start; | ||
324 | for (; __start < end; __start += PAGE_SIZE) { | ||
325 | ClearPageReserved(virt_to_page(__start)); | ||
326 | init_page_count(virt_to_page(__start)); | ||
327 | free_page((long)__start); | ||
328 | totalram_pages++; | ||
329 | } | ||
330 | } | ||
331 | |||
332 | void | ||
333 | free_initmem(void) | 320 | free_initmem(void) |
334 | { | 321 | { |
335 | extern char __init_begin, __init_end; | 322 | free_initmem_default(0); |
336 | |||
337 | free_reserved_mem(&__init_begin, &__init_end); | ||
338 | printk ("Freeing unused kernel memory: %ldk freed\n", | ||
339 | (&__init_end - &__init_begin) >> 10); | ||
340 | } | 323 | } |
341 | 324 | ||
342 | #ifdef CONFIG_BLK_DEV_INITRD | 325 | #ifdef CONFIG_BLK_DEV_INITRD |
343 | void | 326 | void |
344 | free_initrd_mem(unsigned long start, unsigned long end) | 327 | free_initrd_mem(unsigned long start, unsigned long end) |
345 | { | 328 | { |
346 | free_reserved_mem((void *)start, (void *)end); | 329 | free_reserved_area(start, end, 0, "initrd"); |
347 | printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); | ||
348 | } | 330 | } |
349 | #endif | 331 | #endif |
diff --git a/arch/alpha/mm/numa.c b/arch/alpha/mm/numa.c index 3973ae395772..33885048fa36 100644 --- a/arch/alpha/mm/numa.c +++ b/arch/alpha/mm/numa.c | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include <asm/hwrpb.h> | 18 | #include <asm/hwrpb.h> |
19 | #include <asm/pgalloc.h> | 19 | #include <asm/pgalloc.h> |
20 | #include <asm/sections.h> | ||
20 | 21 | ||
21 | pg_data_t node_data[MAX_NUMNODES]; | 22 | pg_data_t node_data[MAX_NUMNODES]; |
22 | EXPORT_SYMBOL(node_data); | 23 | EXPORT_SYMBOL(node_data); |
@@ -325,8 +326,6 @@ void __init mem_init(void) | |||
325 | { | 326 | { |
326 | unsigned long codesize, reservedpages, datasize, initsize, pfn; | 327 | unsigned long codesize, reservedpages, datasize, initsize, pfn; |
327 | extern int page_is_ram(unsigned long) __init; | 328 | extern int page_is_ram(unsigned long) __init; |
328 | extern char _text, _etext, _data, _edata; | ||
329 | extern char __init_begin, __init_end; | ||
330 | unsigned long nid, i; | 329 | unsigned long nid, i; |
331 | high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); | 330 | high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); |
332 | 331 | ||
diff --git a/arch/arc/include/asm/irqflags.h b/arch/arc/include/asm/irqflags.h index ccd84806b62f..eac071668201 100644 --- a/arch/arc/include/asm/irqflags.h +++ b/arch/arc/include/asm/irqflags.h | |||
@@ -39,7 +39,7 @@ static inline long arch_local_irq_save(void) | |||
39 | " flag.nz %0 \n" | 39 | " flag.nz %0 \n" |
40 | : "=r"(temp), "=r"(flags) | 40 | : "=r"(temp), "=r"(flags) |
41 | : "n"((STATUS_E1_MASK | STATUS_E2_MASK)) | 41 | : "n"((STATUS_E1_MASK | STATUS_E2_MASK)) |
42 | : "cc"); | 42 | : "memory", "cc"); |
43 | 43 | ||
44 | return flags; | 44 | return flags; |
45 | } | 45 | } |
@@ -53,7 +53,8 @@ static inline void arch_local_irq_restore(unsigned long flags) | |||
53 | __asm__ __volatile__( | 53 | __asm__ __volatile__( |
54 | " flag %0 \n" | 54 | " flag %0 \n" |
55 | : | 55 | : |
56 | : "r"(flags)); | 56 | : "r"(flags) |
57 | : "memory"); | ||
57 | } | 58 | } |
58 | 59 | ||
59 | /* | 60 | /* |
@@ -73,7 +74,8 @@ static inline void arch_local_irq_disable(void) | |||
73 | " and %0, %0, %1 \n" | 74 | " and %0, %0, %1 \n" |
74 | " flag %0 \n" | 75 | " flag %0 \n" |
75 | : "=&r"(temp) | 76 | : "=&r"(temp) |
76 | : "n"(~(STATUS_E1_MASK | STATUS_E2_MASK))); | 77 | : "n"(~(STATUS_E1_MASK | STATUS_E2_MASK)) |
78 | : "memory"); | ||
77 | } | 79 | } |
78 | 80 | ||
79 | /* | 81 | /* |
@@ -85,7 +87,9 @@ static inline long arch_local_save_flags(void) | |||
85 | 87 | ||
86 | __asm__ __volatile__( | 88 | __asm__ __volatile__( |
87 | " lr %0, [status32] \n" | 89 | " lr %0, [status32] \n" |
88 | : "=&r"(temp)); | 90 | : "=&r"(temp) |
91 | : | ||
92 | : "memory"); | ||
89 | 93 | ||
90 | return temp; | 94 | return temp; |
91 | } | 95 | } |
diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c index caf797de23fc..727d4794ea0f 100644 --- a/arch/arc/mm/init.c +++ b/arch/arc/mm/init.c | |||
@@ -144,37 +144,18 @@ void __init mem_init(void) | |||
144 | PAGES_TO_KB(reserved_pages)); | 144 | PAGES_TO_KB(reserved_pages)); |
145 | } | 145 | } |
146 | 146 | ||
147 | static void __init free_init_pages(const char *what, unsigned long begin, | ||
148 | unsigned long end) | ||
149 | { | ||
150 | unsigned long addr; | ||
151 | |||
152 | pr_info("Freeing %s: %ldk [%lx] to [%lx]\n", | ||
153 | what, TO_KB(end - begin), begin, end); | ||
154 | |||
155 | /* need to check that the page we free is not a partial page */ | ||
156 | for (addr = begin; addr + PAGE_SIZE <= end; addr += PAGE_SIZE) { | ||
157 | ClearPageReserved(virt_to_page(addr)); | ||
158 | init_page_count(virt_to_page(addr)); | ||
159 | free_page(addr); | ||
160 | totalram_pages++; | ||
161 | } | ||
162 | } | ||
163 | |||
164 | /* | 147 | /* |
165 | * free_initmem: Free all the __init memory. | 148 | * free_initmem: Free all the __init memory. |
166 | */ | 149 | */ |
167 | void __init_refok free_initmem(void) | 150 | void __init_refok free_initmem(void) |
168 | { | 151 | { |
169 | free_init_pages("unused kernel memory", | 152 | free_initmem_default(0); |
170 | (unsigned long)__init_begin, | ||
171 | (unsigned long)__init_end); | ||
172 | } | 153 | } |
173 | 154 | ||
174 | #ifdef CONFIG_BLK_DEV_INITRD | 155 | #ifdef CONFIG_BLK_DEV_INITRD |
175 | void __init free_initrd_mem(unsigned long start, unsigned long end) | 156 | void __init free_initrd_mem(unsigned long start, unsigned long end) |
176 | { | 157 | { |
177 | free_init_pages("initrd memory", start, end); | 158 | free_reserved_area(start, end, 0, "initrd"); |
178 | } | 159 | } |
179 | #endif | 160 | #endif |
180 | 161 | ||
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index fcedd612c54c..a39e3214ea3d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -550,6 +550,8 @@ config ARCH_IXP4XX | |||
550 | select GENERIC_CLOCKEVENTS | 550 | select GENERIC_CLOCKEVENTS |
551 | select MIGHT_HAVE_PCI | 551 | select MIGHT_HAVE_PCI |
552 | select NEED_MACH_IO_H | 552 | select NEED_MACH_IO_H |
553 | select USB_EHCI_BIG_ENDIAN_MMIO | ||
554 | select USB_EHCI_BIG_ENDIAN_DESC | ||
553 | help | 555 | help |
554 | Support for Intel's IXP4XX (XScale) family of processors. | 556 | Support for Intel's IXP4XX (XScale) family of processors. |
555 | 557 | ||
diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index cb7bcc51608d..39253b9aedd1 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi | |||
@@ -322,6 +322,24 @@ | |||
322 | }; | 322 | }; |
323 | }; | 323 | }; |
324 | 324 | ||
325 | spi0 { | ||
326 | pinctrl_spi0: spi0-0 { | ||
327 | atmel,pins = | ||
328 | <0 0 0x1 0x0 /* PA0 periph A SPI0_MISO pin */ | ||
329 | 0 1 0x1 0x0 /* PA1 periph A SPI0_MOSI pin */ | ||
330 | 0 2 0x1 0x0>; /* PA2 periph A SPI0_SPCK pin */ | ||
331 | }; | ||
332 | }; | ||
333 | |||
334 | spi1 { | ||
335 | pinctrl_spi1: spi1-0 { | ||
336 | atmel,pins = | ||
337 | <1 0 0x1 0x0 /* PB0 periph A SPI1_MISO pin */ | ||
338 | 1 1 0x1 0x0 /* PB1 periph A SPI1_MOSI pin */ | ||
339 | 1 2 0x1 0x0>; /* PB2 periph A SPI1_SPCK pin */ | ||
340 | }; | ||
341 | }; | ||
342 | |||
325 | pioA: gpio@fffff400 { | 343 | pioA: gpio@fffff400 { |
326 | compatible = "atmel,at91rm9200-gpio"; | 344 | compatible = "atmel,at91rm9200-gpio"; |
327 | reg = <0xfffff400 0x200>; | 345 | reg = <0xfffff400 0x200>; |
@@ -471,6 +489,28 @@ | |||
471 | status = "disabled"; | 489 | status = "disabled"; |
472 | }; | 490 | }; |
473 | 491 | ||
492 | spi0: spi@fffc8000 { | ||
493 | #address-cells = <1>; | ||
494 | #size-cells = <0>; | ||
495 | compatible = "atmel,at91rm9200-spi"; | ||
496 | reg = <0xfffc8000 0x200>; | ||
497 | interrupts = <12 4 3>; | ||
498 | pinctrl-names = "default"; | ||
499 | pinctrl-0 = <&pinctrl_spi0>; | ||
500 | status = "disabled"; | ||
501 | }; | ||
502 | |||
503 | spi1: spi@fffcc000 { | ||
504 | #address-cells = <1>; | ||
505 | #size-cells = <0>; | ||
506 | compatible = "atmel,at91rm9200-spi"; | ||
507 | reg = <0xfffcc000 0x200>; | ||
508 | interrupts = <13 4 3>; | ||
509 | pinctrl-names = "default"; | ||
510 | pinctrl-0 = <&pinctrl_spi1>; | ||
511 | status = "disabled"; | ||
512 | }; | ||
513 | |||
474 | adc0: adc@fffe0000 { | 514 | adc0: adc@fffe0000 { |
475 | compatible = "atmel,at91sam9260-adc"; | 515 | compatible = "atmel,at91sam9260-adc"; |
476 | reg = <0xfffe0000 0x100>; | 516 | reg = <0xfffe0000 0x100>; |
diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index 271d4de026e9..94b58ab2cc08 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi | |||
@@ -303,6 +303,24 @@ | |||
303 | }; | 303 | }; |
304 | }; | 304 | }; |
305 | 305 | ||
306 | spi0 { | ||
307 | pinctrl_spi0: spi0-0 { | ||
308 | atmel,pins = | ||
309 | <0 0 0x2 0x0 /* PA0 periph B SPI0_MISO pin */ | ||
310 | 0 1 0x2 0x0 /* PA1 periph B SPI0_MOSI pin */ | ||
311 | 0 2 0x2 0x0>; /* PA2 periph B SPI0_SPCK pin */ | ||
312 | }; | ||
313 | }; | ||
314 | |||
315 | spi1 { | ||
316 | pinctrl_spi1: spi1-0 { | ||
317 | atmel,pins = | ||
318 | <1 12 0x1 0x0 /* PB12 periph A SPI1_MISO pin */ | ||
319 | 1 13 0x1 0x0 /* PB13 periph A SPI1_MOSI pin */ | ||
320 | 1 14 0x1 0x0>; /* PB14 periph A SPI1_SPCK pin */ | ||
321 | }; | ||
322 | }; | ||
323 | |||
306 | pioA: gpio@fffff200 { | 324 | pioA: gpio@fffff200 { |
307 | compatible = "atmel,at91rm9200-gpio"; | 325 | compatible = "atmel,at91rm9200-gpio"; |
308 | reg = <0xfffff200 0x200>; | 326 | reg = <0xfffff200 0x200>; |
@@ -462,6 +480,28 @@ | |||
462 | reg = <0xfffffd40 0x10>; | 480 | reg = <0xfffffd40 0x10>; |
463 | status = "disabled"; | 481 | status = "disabled"; |
464 | }; | 482 | }; |
483 | |||
484 | spi0: spi@fffa4000 { | ||
485 | #address-cells = <1>; | ||
486 | #size-cells = <0>; | ||
487 | compatible = "atmel,at91rm9200-spi"; | ||
488 | reg = <0xfffa4000 0x200>; | ||
489 | interrupts = <14 4 3>; | ||
490 | pinctrl-names = "default"; | ||
491 | pinctrl-0 = <&pinctrl_spi0>; | ||
492 | status = "disabled"; | ||
493 | }; | ||
494 | |||
495 | spi1: spi@fffa8000 { | ||
496 | #address-cells = <1>; | ||
497 | #size-cells = <0>; | ||
498 | compatible = "atmel,at91rm9200-spi"; | ||
499 | reg = <0xfffa8000 0x200>; | ||
500 | interrupts = <15 4 3>; | ||
501 | pinctrl-names = "default"; | ||
502 | pinctrl-0 = <&pinctrl_spi1>; | ||
503 | status = "disabled"; | ||
504 | }; | ||
465 | }; | 505 | }; |
466 | 506 | ||
467 | nand0: nand@40000000 { | 507 | nand0: nand@40000000 { |
diff --git a/arch/arm/boot/dts/at91sam9263ek.dts b/arch/arm/boot/dts/at91sam9263ek.dts index 1eb08728f527..a14e424b2e81 100644 --- a/arch/arm/boot/dts/at91sam9263ek.dts +++ b/arch/arm/boot/dts/at91sam9263ek.dts | |||
@@ -79,6 +79,16 @@ | |||
79 | }; | 79 | }; |
80 | }; | 80 | }; |
81 | }; | 81 | }; |
82 | |||
83 | spi0: spi@fffa4000 { | ||
84 | status = "okay"; | ||
85 | cs-gpios = <&pioA 5 0>, <0>, <0>, <0>; | ||
86 | mtd_dataflash@0 { | ||
87 | compatible = "atmel,at45", "atmel,dataflash"; | ||
88 | spi-max-frequency = <50000000>; | ||
89 | reg = <0>; | ||
90 | }; | ||
91 | }; | ||
82 | }; | 92 | }; |
83 | 93 | ||
84 | nand0: nand@40000000 { | 94 | nand0: nand@40000000 { |
diff --git a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi index da15e83e7f17..23d1f468f27f 100644 --- a/arch/arm/boot/dts/at91sam9g20ek_common.dtsi +++ b/arch/arm/boot/dts/at91sam9g20ek_common.dtsi | |||
@@ -96,6 +96,16 @@ | |||
96 | status = "okay"; | 96 | status = "okay"; |
97 | pinctrl-0 = <&pinctrl_ssc0_tx>; | 97 | pinctrl-0 = <&pinctrl_ssc0_tx>; |
98 | }; | 98 | }; |
99 | |||
100 | spi0: spi@fffc8000 { | ||
101 | status = "okay"; | ||
102 | cs-gpios = <0>, <&pioC 11 0>, <0>, <0>; | ||
103 | mtd_dataflash@0 { | ||
104 | compatible = "atmel,at45", "atmel,dataflash"; | ||
105 | spi-max-frequency = <50000000>; | ||
106 | reg = <1>; | ||
107 | }; | ||
108 | }; | ||
99 | }; | 109 | }; |
100 | 110 | ||
101 | nand0: nand@40000000 { | 111 | nand0: nand@40000000 { |
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index 6b1d4cab24c2..cfdf429578b5 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi | |||
@@ -322,6 +322,24 @@ | |||
322 | }; | 322 | }; |
323 | }; | 323 | }; |
324 | 324 | ||
325 | spi0 { | ||
326 | pinctrl_spi0: spi0-0 { | ||
327 | atmel,pins = | ||
328 | <1 0 0x1 0x0 /* PB0 periph A SPI0_MISO pin */ | ||
329 | 1 1 0x1 0x0 /* PB1 periph A SPI0_MOSI pin */ | ||
330 | 1 2 0x1 0x0>; /* PB2 periph A SPI0_SPCK pin */ | ||
331 | }; | ||
332 | }; | ||
333 | |||
334 | spi1 { | ||
335 | pinctrl_spi1: spi1-0 { | ||
336 | atmel,pins = | ||
337 | <1 14 0x1 0x0 /* PB14 periph A SPI1_MISO pin */ | ||
338 | 1 15 0x1 0x0 /* PB15 periph A SPI1_MOSI pin */ | ||
339 | 1 16 0x1 0x0>; /* PB16 periph A SPI1_SPCK pin */ | ||
340 | }; | ||
341 | }; | ||
342 | |||
325 | pioA: gpio@fffff200 { | 343 | pioA: gpio@fffff200 { |
326 | compatible = "atmel,at91rm9200-gpio"; | 344 | compatible = "atmel,at91rm9200-gpio"; |
327 | reg = <0xfffff200 0x200>; | 345 | reg = <0xfffff200 0x200>; |
@@ -531,6 +549,28 @@ | |||
531 | reg = <0xfffffd40 0x10>; | 549 | reg = <0xfffffd40 0x10>; |
532 | status = "disabled"; | 550 | status = "disabled"; |
533 | }; | 551 | }; |
552 | |||
553 | spi0: spi@fffa4000 { | ||
554 | #address-cells = <1>; | ||
555 | #size-cells = <0>; | ||
556 | compatible = "atmel,at91rm9200-spi"; | ||
557 | reg = <0xfffa4000 0x200>; | ||
558 | interrupts = <14 4 3>; | ||
559 | pinctrl-names = "default"; | ||
560 | pinctrl-0 = <&pinctrl_spi0>; | ||
561 | status = "disabled"; | ||
562 | }; | ||
563 | |||
564 | spi1: spi@fffa8000 { | ||
565 | #address-cells = <1>; | ||
566 | #size-cells = <0>; | ||
567 | compatible = "atmel,at91rm9200-spi"; | ||
568 | reg = <0xfffa8000 0x200>; | ||
569 | interrupts = <15 4 3>; | ||
570 | pinctrl-names = "default"; | ||
571 | pinctrl-0 = <&pinctrl_spi1>; | ||
572 | status = "disabled"; | ||
573 | }; | ||
534 | }; | 574 | }; |
535 | 575 | ||
536 | nand0: nand@40000000 { | 576 | nand0: nand@40000000 { |
diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts index 20c31913c270..92c52a7d70bc 100644 --- a/arch/arm/boot/dts/at91sam9m10g45ek.dts +++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts | |||
@@ -102,6 +102,16 @@ | |||
102 | }; | 102 | }; |
103 | }; | 103 | }; |
104 | }; | 104 | }; |
105 | |||
106 | spi0: spi@fffa4000{ | ||
107 | status = "okay"; | ||
108 | cs-gpios = <&pioB 3 0>, <0>, <0>, <0>; | ||
109 | mtd_dataflash@0 { | ||
110 | compatible = "atmel,at45", "atmel,dataflash"; | ||
111 | spi-max-frequency = <13000000>; | ||
112 | reg = <0>; | ||
113 | }; | ||
114 | }; | ||
105 | }; | 115 | }; |
106 | 116 | ||
107 | nand0: nand@40000000 { | 117 | nand0: nand@40000000 { |
diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index 7750f98dd764..b2961f1ea51b 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi | |||
@@ -261,6 +261,24 @@ | |||
261 | }; | 261 | }; |
262 | }; | 262 | }; |
263 | 263 | ||
264 | spi0 { | ||
265 | pinctrl_spi0: spi0-0 { | ||
266 | atmel,pins = | ||
267 | <0 11 0x1 0x0 /* PA11 periph A SPI0_MISO pin */ | ||
268 | 0 12 0x1 0x0 /* PA12 periph A SPI0_MOSI pin */ | ||
269 | 0 13 0x1 0x0>; /* PA13 periph A SPI0_SPCK pin */ | ||
270 | }; | ||
271 | }; | ||
272 | |||
273 | spi1 { | ||
274 | pinctrl_spi1: spi1-0 { | ||
275 | atmel,pins = | ||
276 | <0 21 0x2 0x0 /* PA21 periph B SPI1_MISO pin */ | ||
277 | 0 22 0x2 0x0 /* PA22 periph B SPI1_MOSI pin */ | ||
278 | 0 23 0x2 0x0>; /* PA23 periph B SPI1_SPCK pin */ | ||
279 | }; | ||
280 | }; | ||
281 | |||
264 | pioA: gpio@fffff400 { | 282 | pioA: gpio@fffff400 { |
265 | compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; | 283 | compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; |
266 | reg = <0xfffff400 0x200>; | 284 | reg = <0xfffff400 0x200>; |
@@ -373,6 +391,28 @@ | |||
373 | #size-cells = <0>; | 391 | #size-cells = <0>; |
374 | status = "disabled"; | 392 | status = "disabled"; |
375 | }; | 393 | }; |
394 | |||
395 | spi0: spi@f0000000 { | ||
396 | #address-cells = <1>; | ||
397 | #size-cells = <0>; | ||
398 | compatible = "atmel,at91rm9200-spi"; | ||
399 | reg = <0xf0000000 0x100>; | ||
400 | interrupts = <13 4 3>; | ||
401 | pinctrl-names = "default"; | ||
402 | pinctrl-0 = <&pinctrl_spi0>; | ||
403 | status = "disabled"; | ||
404 | }; | ||
405 | |||
406 | spi1: spi@f0004000 { | ||
407 | #address-cells = <1>; | ||
408 | #size-cells = <0>; | ||
409 | compatible = "atmel,at91rm9200-spi"; | ||
410 | reg = <0xf0004000 0x100>; | ||
411 | interrupts = <14 4 3>; | ||
412 | pinctrl-names = "default"; | ||
413 | pinctrl-0 = <&pinctrl_spi1>; | ||
414 | status = "disabled"; | ||
415 | }; | ||
376 | }; | 416 | }; |
377 | 417 | ||
378 | nand0: nand@40000000 { | 418 | nand0: nand@40000000 { |
diff --git a/arch/arm/boot/dts/at91sam9n12ek.dts b/arch/arm/boot/dts/at91sam9n12ek.dts index d400f8de4387..34c842b1efb2 100644 --- a/arch/arm/boot/dts/at91sam9n12ek.dts +++ b/arch/arm/boot/dts/at91sam9n12ek.dts | |||
@@ -67,6 +67,16 @@ | |||
67 | }; | 67 | }; |
68 | }; | 68 | }; |
69 | }; | 69 | }; |
70 | |||
71 | spi0: spi@f0000000 { | ||
72 | status = "okay"; | ||
73 | cs-gpios = <&pioA 14 0>, <0>, <0>, <0>; | ||
74 | m25p80@0 { | ||
75 | compatible = "atmel,at25df321a"; | ||
76 | spi-max-frequency = <50000000>; | ||
77 | reg = <0>; | ||
78 | }; | ||
79 | }; | ||
70 | }; | 80 | }; |
71 | 81 | ||
72 | nand0: nand@40000000 { | 82 | nand0: nand@40000000 { |
diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index a98c0d50fbbe..347b438d47fa 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi | |||
@@ -343,6 +343,24 @@ | |||
343 | }; | 343 | }; |
344 | }; | 344 | }; |
345 | 345 | ||
346 | spi0 { | ||
347 | pinctrl_spi0: spi0-0 { | ||
348 | atmel,pins = | ||
349 | <0 11 0x1 0x0 /* PA11 periph A SPI0_MISO pin */ | ||
350 | 0 12 0x1 0x0 /* PA12 periph A SPI0_MOSI pin */ | ||
351 | 0 13 0x1 0x0>; /* PA13 periph A SPI0_SPCK pin */ | ||
352 | }; | ||
353 | }; | ||
354 | |||
355 | spi1 { | ||
356 | pinctrl_spi1: spi1-0 { | ||
357 | atmel,pins = | ||
358 | <0 21 0x2 0x0 /* PA21 periph B SPI1_MISO pin */ | ||
359 | 0 22 0x2 0x0 /* PA22 periph B SPI1_MOSI pin */ | ||
360 | 0 23 0x2 0x0>; /* PA23 periph B SPI1_SPCK pin */ | ||
361 | }; | ||
362 | }; | ||
363 | |||
346 | pioA: gpio@fffff400 { | 364 | pioA: gpio@fffff400 { |
347 | compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; | 365 | compatible = "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio"; |
348 | reg = <0xfffff400 0x200>; | 366 | reg = <0xfffff400 0x200>; |
@@ -529,6 +547,28 @@ | |||
529 | trigger-value = <0x6>; | 547 | trigger-value = <0x6>; |
530 | }; | 548 | }; |
531 | }; | 549 | }; |
550 | |||
551 | spi0: spi@f0000000 { | ||
552 | #address-cells = <1>; | ||
553 | #size-cells = <0>; | ||
554 | compatible = "atmel,at91rm9200-spi"; | ||
555 | reg = <0xf0000000 0x100>; | ||
556 | interrupts = <13 4 3>; | ||
557 | pinctrl-names = "default"; | ||
558 | pinctrl-0 = <&pinctrl_spi0>; | ||
559 | status = "disabled"; | ||
560 | }; | ||
561 | |||
562 | spi1: spi@f0004000 { | ||
563 | #address-cells = <1>; | ||
564 | #size-cells = <0>; | ||
565 | compatible = "atmel,at91rm9200-spi"; | ||
566 | reg = <0xf0004000 0x100>; | ||
567 | interrupts = <14 4 3>; | ||
568 | pinctrl-names = "default"; | ||
569 | pinctrl-0 = <&pinctrl_spi1>; | ||
570 | status = "disabled"; | ||
571 | }; | ||
532 | }; | 572 | }; |
533 | 573 | ||
534 | nand0: nand@40000000 { | 574 | nand0: nand@40000000 { |
diff --git a/arch/arm/boot/dts/at91sam9x5ek.dtsi b/arch/arm/boot/dts/at91sam9x5ek.dtsi index 8a7cf1d9cf5d..09f5e667ca7a 100644 --- a/arch/arm/boot/dts/at91sam9x5ek.dtsi +++ b/arch/arm/boot/dts/at91sam9x5ek.dtsi | |||
@@ -84,6 +84,16 @@ | |||
84 | }; | 84 | }; |
85 | }; | 85 | }; |
86 | }; | 86 | }; |
87 | |||
88 | spi0: spi@f0000000 { | ||
89 | status = "okay"; | ||
90 | cs-gpios = <&pioA 14 0>, <0>, <0>, <0>; | ||
91 | m25p80@0 { | ||
92 | compatible = "atmel,at25df321a"; | ||
93 | spi-max-frequency = <50000000>; | ||
94 | reg = <0>; | ||
95 | }; | ||
96 | }; | ||
87 | }; | 97 | }; |
88 | 98 | ||
89 | usb0: ohci@00600000 { | 99 | usb0: ohci@00600000 { |
diff --git a/arch/arm/boot/dts/imx28-m28evk.dts b/arch/arm/boot/dts/imx28-m28evk.dts index 6ce3d17c3a29..fd36e1cca104 100644 --- a/arch/arm/boot/dts/imx28-m28evk.dts +++ b/arch/arm/boot/dts/imx28-m28evk.dts | |||
@@ -152,7 +152,6 @@ | |||
152 | i2c0: i2c@80058000 { | 152 | i2c0: i2c@80058000 { |
153 | pinctrl-names = "default"; | 153 | pinctrl-names = "default"; |
154 | pinctrl-0 = <&i2c0_pins_a>; | 154 | pinctrl-0 = <&i2c0_pins_a>; |
155 | clock-frequency = <400000>; | ||
156 | status = "okay"; | 155 | status = "okay"; |
157 | 156 | ||
158 | sgtl5000: codec@0a { | 157 | sgtl5000: codec@0a { |
diff --git a/arch/arm/boot/dts/imx28-sps1.dts b/arch/arm/boot/dts/imx28-sps1.dts index e6cde8aa7fff..6c6a5442800a 100644 --- a/arch/arm/boot/dts/imx28-sps1.dts +++ b/arch/arm/boot/dts/imx28-sps1.dts | |||
@@ -70,7 +70,6 @@ | |||
70 | i2c0: i2c@80058000 { | 70 | i2c0: i2c@80058000 { |
71 | pinctrl-names = "default"; | 71 | pinctrl-names = "default"; |
72 | pinctrl-0 = <&i2c0_pins_a>; | 72 | pinctrl-0 = <&i2c0_pins_a>; |
73 | clock-frequency = <400000>; | ||
74 | status = "okay"; | 73 | status = "okay"; |
75 | 74 | ||
76 | rtc: rtc@51 { | 75 | rtc: rtc@51 { |
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 06ec460b4581..281a223591ff 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi | |||
@@ -91,6 +91,7 @@ | |||
91 | compatible = "arm,cortex-a9-twd-timer"; | 91 | compatible = "arm,cortex-a9-twd-timer"; |
92 | reg = <0x00a00600 0x20>; | 92 | reg = <0x00a00600 0x20>; |
93 | interrupts = <1 13 0xf01>; | 93 | interrupts = <1 13 0xf01>; |
94 | clocks = <&clks 15>; | ||
94 | }; | 95 | }; |
95 | 96 | ||
96 | L2: l2-cache@00a02000 { | 97 | L2: l2-cache@00a02000 { |
diff --git a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts index 93c3afbef9ee..3694e94f6e99 100644 --- a/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts +++ b/arch/arm/boot/dts/kirkwood-iomega_ix2_200.dts | |||
@@ -96,11 +96,11 @@ | |||
96 | marvell,function = "gpio"; | 96 | marvell,function = "gpio"; |
97 | }; | 97 | }; |
98 | pmx_led_rebuild_brt_ctrl_1: pmx-led-rebuild-brt-ctrl-1 { | 98 | pmx_led_rebuild_brt_ctrl_1: pmx-led-rebuild-brt-ctrl-1 { |
99 | marvell,pins = "mpp44"; | 99 | marvell,pins = "mpp46"; |
100 | marvell,function = "gpio"; | 100 | marvell,function = "gpio"; |
101 | }; | 101 | }; |
102 | pmx_led_rebuild_brt_ctrl_2: pmx-led-rebuild-brt-ctrl-2 { | 102 | pmx_led_rebuild_brt_ctrl_2: pmx-led-rebuild-brt-ctrl-2 { |
103 | marvell,pins = "mpp45"; | 103 | marvell,pins = "mpp47"; |
104 | marvell,function = "gpio"; | 104 | marvell,function = "gpio"; |
105 | }; | 105 | }; |
106 | 106 | ||
@@ -157,14 +157,14 @@ | |||
157 | gpios = <&gpio0 16 0>; | 157 | gpios = <&gpio0 16 0>; |
158 | linux,default-trigger = "default-on"; | 158 | linux,default-trigger = "default-on"; |
159 | }; | 159 | }; |
160 | health_led1 { | 160 | rebuild_led { |
161 | label = "status:white:rebuild_led"; | ||
162 | gpios = <&gpio1 4 0>; | ||
163 | }; | ||
164 | health_led { | ||
161 | label = "status:red:health_led"; | 165 | label = "status:red:health_led"; |
162 | gpios = <&gpio1 5 0>; | 166 | gpios = <&gpio1 5 0>; |
163 | }; | 167 | }; |
164 | health_led2 { | ||
165 | label = "status:white:health_led"; | ||
166 | gpios = <&gpio1 4 0>; | ||
167 | }; | ||
168 | backup_led { | 168 | backup_led { |
169 | label = "status:blue:backup_led"; | 169 | label = "status:blue:backup_led"; |
170 | gpios = <&gpio0 15 0>; | 170 | gpios = <&gpio0 15 0>; |
diff --git a/arch/arm/boot/dts/msm8660-surf.dts b/arch/arm/boot/dts/msm8660-surf.dts index 31f2157cd7d7..67f8670c4d6a 100644 --- a/arch/arm/boot/dts/msm8660-surf.dts +++ b/arch/arm/boot/dts/msm8660-surf.dts | |||
@@ -38,4 +38,10 @@ | |||
38 | <0x19c00000 0x1000>; | 38 | <0x19c00000 0x1000>; |
39 | interrupts = <0 195 0x0>; | 39 | interrupts = <0 195 0x0>; |
40 | }; | 40 | }; |
41 | |||
42 | qcom,ssbi@500000 { | ||
43 | compatible = "qcom,ssbi"; | ||
44 | reg = <0x500000 0x1000>; | ||
45 | qcom,controller-type = "pmic-arbiter"; | ||
46 | }; | ||
41 | }; | 47 | }; |
diff --git a/arch/arm/boot/dts/msm8960-cdp.dts b/arch/arm/boot/dts/msm8960-cdp.dts index 9e621b5ad3dd..c9b09a813a4b 100644 --- a/arch/arm/boot/dts/msm8960-cdp.dts +++ b/arch/arm/boot/dts/msm8960-cdp.dts | |||
@@ -38,4 +38,10 @@ | |||
38 | <0x16400000 0x1000>; | 38 | <0x16400000 0x1000>; |
39 | interrupts = <0 154 0x0>; | 39 | interrupts = <0 154 0x0>; |
40 | }; | 40 | }; |
41 | |||
42 | qcom,ssbi@500000 { | ||
43 | compatible = "qcom,ssbi"; | ||
44 | reg = <0x500000 0x1000>; | ||
45 | qcom,controller-type = "pmic-arbiter"; | ||
46 | }; | ||
41 | }; | 47 | }; |
diff --git a/arch/arm/boot/dts/spear1310.dtsi b/arch/arm/boot/dts/spear1310.dtsi index 1513c1927cc8..122ae94076c8 100644 --- a/arch/arm/boot/dts/spear1310.dtsi +++ b/arch/arm/boot/dts/spear1310.dtsi | |||
@@ -89,7 +89,7 @@ | |||
89 | pinmux: pinmux@e0700000 { | 89 | pinmux: pinmux@e0700000 { |
90 | compatible = "st,spear1310-pinmux"; | 90 | compatible = "st,spear1310-pinmux"; |
91 | reg = <0xe0700000 0x1000>; | 91 | reg = <0xe0700000 0x1000>; |
92 | #gpio-range-cells = <2>; | 92 | #gpio-range-cells = <3>; |
93 | }; | 93 | }; |
94 | 94 | ||
95 | apb { | 95 | apb { |
@@ -212,7 +212,7 @@ | |||
212 | interrupt-controller; | 212 | interrupt-controller; |
213 | gpio-controller; | 213 | gpio-controller; |
214 | #gpio-cells = <2>; | 214 | #gpio-cells = <2>; |
215 | gpio-ranges = <&pinmux 0 246>; | 215 | gpio-ranges = <&pinmux 0 0 246>; |
216 | status = "disabled"; | 216 | status = "disabled"; |
217 | 217 | ||
218 | st-plgpio,ngpio = <246>; | 218 | st-plgpio,ngpio = <246>; |
diff --git a/arch/arm/boot/dts/spear1340.dtsi b/arch/arm/boot/dts/spear1340.dtsi index 34da11aa6795..c511c4772efd 100644 --- a/arch/arm/boot/dts/spear1340.dtsi +++ b/arch/arm/boot/dts/spear1340.dtsi | |||
@@ -63,7 +63,7 @@ | |||
63 | pinmux: pinmux@e0700000 { | 63 | pinmux: pinmux@e0700000 { |
64 | compatible = "st,spear1340-pinmux"; | 64 | compatible = "st,spear1340-pinmux"; |
65 | reg = <0xe0700000 0x1000>; | 65 | reg = <0xe0700000 0x1000>; |
66 | #gpio-range-cells = <2>; | 66 | #gpio-range-cells = <3>; |
67 | }; | 67 | }; |
68 | 68 | ||
69 | pwm: pwm@e0180000 { | 69 | pwm: pwm@e0180000 { |
@@ -127,7 +127,7 @@ | |||
127 | interrupt-controller; | 127 | interrupt-controller; |
128 | gpio-controller; | 128 | gpio-controller; |
129 | #gpio-cells = <2>; | 129 | #gpio-cells = <2>; |
130 | gpio-ranges = <&pinmux 0 252>; | 130 | gpio-ranges = <&pinmux 0 0 252>; |
131 | status = "disabled"; | 131 | status = "disabled"; |
132 | 132 | ||
133 | st-plgpio,ngpio = <250>; | 133 | st-plgpio,ngpio = <250>; |
diff --git a/arch/arm/boot/dts/spear310.dtsi b/arch/arm/boot/dts/spear310.dtsi index ab45b8c81982..95372080eea6 100644 --- a/arch/arm/boot/dts/spear310.dtsi +++ b/arch/arm/boot/dts/spear310.dtsi | |||
@@ -25,7 +25,7 @@ | |||
25 | pinmux: pinmux@b4000000 { | 25 | pinmux: pinmux@b4000000 { |
26 | compatible = "st,spear310-pinmux"; | 26 | compatible = "st,spear310-pinmux"; |
27 | reg = <0xb4000000 0x1000>; | 27 | reg = <0xb4000000 0x1000>; |
28 | #gpio-range-cells = <2>; | 28 | #gpio-range-cells = <3>; |
29 | }; | 29 | }; |
30 | 30 | ||
31 | fsmc: flash@44000000 { | 31 | fsmc: flash@44000000 { |
@@ -102,7 +102,7 @@ | |||
102 | interrupt-controller; | 102 | interrupt-controller; |
103 | gpio-controller; | 103 | gpio-controller; |
104 | #gpio-cells = <2>; | 104 | #gpio-cells = <2>; |
105 | gpio-ranges = <&pinmux 0 102>; | 105 | gpio-ranges = <&pinmux 0 0 102>; |
106 | status = "disabled"; | 106 | status = "disabled"; |
107 | 107 | ||
108 | st-plgpio,ngpio = <102>; | 108 | st-plgpio,ngpio = <102>; |
diff --git a/arch/arm/boot/dts/spear320.dtsi b/arch/arm/boot/dts/spear320.dtsi index caa5520b1fd4..ffea342aeec9 100644 --- a/arch/arm/boot/dts/spear320.dtsi +++ b/arch/arm/boot/dts/spear320.dtsi | |||
@@ -24,7 +24,7 @@ | |||
24 | pinmux: pinmux@b3000000 { | 24 | pinmux: pinmux@b3000000 { |
25 | compatible = "st,spear320-pinmux"; | 25 | compatible = "st,spear320-pinmux"; |
26 | reg = <0xb3000000 0x1000>; | 26 | reg = <0xb3000000 0x1000>; |
27 | #gpio-range-cells = <2>; | 27 | #gpio-range-cells = <3>; |
28 | }; | 28 | }; |
29 | 29 | ||
30 | clcd@90000000 { | 30 | clcd@90000000 { |
@@ -130,7 +130,7 @@ | |||
130 | interrupt-controller; | 130 | interrupt-controller; |
131 | gpio-controller; | 131 | gpio-controller; |
132 | #gpio-cells = <2>; | 132 | #gpio-cells = <2>; |
133 | gpio-ranges = <&pinmux 0 102>; | 133 | gpio-ranges = <&pinmux 0 0 102>; |
134 | status = "disabled"; | 134 | status = "disabled"; |
135 | 135 | ||
136 | st-plgpio,ngpio = <102>; | 136 | st-plgpio,ngpio = <102>; |
diff --git a/arch/arm/boot/dts/vt8500-bv07.dts b/arch/arm/boot/dts/vt8500-bv07.dts index 567cf4e8ab84..877b33afa7ed 100644 --- a/arch/arm/boot/dts/vt8500-bv07.dts +++ b/arch/arm/boot/dts/vt8500-bv07.dts | |||
@@ -11,26 +11,22 @@ | |||
11 | 11 | ||
12 | / { | 12 | / { |
13 | model = "Benign BV07 Netbook"; | 13 | model = "Benign BV07 Netbook"; |
14 | }; | ||
14 | 15 | ||
15 | /* | 16 | &fb { |
16 | * Display node is based on Sascha Hauer's patch on dri-devel. | 17 | bits-per-pixel = <16>; |
17 | * Added a bpp property to calculate the size of the framebuffer | 18 | display-timings { |
18 | * until the binding is formalized. | 19 | native-mode = <&timing0>; |
19 | */ | 20 | timing0: 800x480 { |
20 | display: display@0 { | 21 | clock-frequency = <0>; /* unused but required */ |
21 | modes { | 22 | hactive = <800>; |
22 | mode0: mode@0 { | 23 | vactive = <480>; |
23 | hactive = <800>; | 24 | hfront-porch = <40>; |
24 | vactive = <480>; | 25 | hback-porch = <88>; |
25 | hback-porch = <88>; | 26 | hsync-len = <0>; |
26 | hfront-porch = <40>; | 27 | vback-porch = <32>; |
27 | hsync-len = <0>; | 28 | vfront-porch = <11>; |
28 | vback-porch = <32>; | 29 | vsync-len = <1>; |
29 | vfront-porch = <11>; | ||
30 | vsync-len = <1>; | ||
31 | clock = <0>; /* unused but required */ | ||
32 | bpp = <16>; /* non-standard but required */ | ||
33 | }; | ||
34 | }; | 30 | }; |
35 | }; | 31 | }; |
36 | }; | 32 | }; |
diff --git a/arch/arm/boot/dts/vt8500.dtsi b/arch/arm/boot/dts/vt8500.dtsi index cf31ced46602..68c8dc644383 100644 --- a/arch/arm/boot/dts/vt8500.dtsi +++ b/arch/arm/boot/dts/vt8500.dtsi | |||
@@ -98,12 +98,10 @@ | |||
98 | interrupts = <43>; | 98 | interrupts = <43>; |
99 | }; | 99 | }; |
100 | 100 | ||
101 | fb@d800e400 { | 101 | fb: fb@d8050800 { |
102 | compatible = "via,vt8500-fb"; | 102 | compatible = "via,vt8500-fb"; |
103 | reg = <0xd800e400 0x400>; | 103 | reg = <0xd800e400 0x400>; |
104 | interrupts = <12>; | 104 | interrupts = <12>; |
105 | display = <&display>; | ||
106 | default-mode = <&mode0>; | ||
107 | }; | 105 | }; |
108 | 106 | ||
109 | ge_rops@d8050400 { | 107 | ge_rops@d8050400 { |
diff --git a/arch/arm/boot/dts/wm8505-ref.dts b/arch/arm/boot/dts/wm8505-ref.dts index fd4e248074c6..edd2cec3d37f 100644 --- a/arch/arm/boot/dts/wm8505-ref.dts +++ b/arch/arm/boot/dts/wm8505-ref.dts | |||
@@ -11,26 +11,22 @@ | |||
11 | 11 | ||
12 | / { | 12 | / { |
13 | model = "Wondermedia WM8505 Netbook"; | 13 | model = "Wondermedia WM8505 Netbook"; |
14 | }; | ||
14 | 15 | ||
15 | /* | 16 | &fb { |
16 | * Display node is based on Sascha Hauer's patch on dri-devel. | 17 | bits-per-pixel = <32>; |
17 | * Added a bpp property to calculate the size of the framebuffer | 18 | display-timings { |
18 | * until the binding is formalized. | 19 | native-mode = <&timing0>; |
19 | */ | 20 | timing0: 800x480 { |
20 | display: display@0 { | 21 | clock-frequency = <0>; /* unused but required */ |
21 | modes { | 22 | hactive = <800>; |
22 | mode0: mode@0 { | 23 | vactive = <480>; |
23 | hactive = <800>; | 24 | hfront-porch = <40>; |
24 | vactive = <480>; | 25 | hback-porch = <88>; |
25 | hback-porch = <88>; | 26 | hsync-len = <0>; |
26 | hfront-porch = <40>; | 27 | vback-porch = <32>; |
27 | hsync-len = <0>; | 28 | vfront-porch = <11>; |
28 | vback-porch = <32>; | 29 | vsync-len = <1>; |
29 | vfront-porch = <11>; | ||
30 | vsync-len = <1>; | ||
31 | clock = <0>; /* unused but required */ | ||
32 | bpp = <32>; /* non-standard but required */ | ||
33 | }; | ||
34 | }; | 30 | }; |
35 | }; | 31 | }; |
36 | }; | 32 | }; |
diff --git a/arch/arm/boot/dts/wm8505.dtsi b/arch/arm/boot/dts/wm8505.dtsi index e74a1c0fb9a2..bcf668d31b28 100644 --- a/arch/arm/boot/dts/wm8505.dtsi +++ b/arch/arm/boot/dts/wm8505.dtsi | |||
@@ -128,11 +128,9 @@ | |||
128 | interrupts = <0>; | 128 | interrupts = <0>; |
129 | }; | 129 | }; |
130 | 130 | ||
131 | fb@d8050800 { | 131 | fb: fb@d8050800 { |
132 | compatible = "wm,wm8505-fb"; | 132 | compatible = "wm,wm8505-fb"; |
133 | reg = <0xd8050800 0x200>; | 133 | reg = <0xd8050800 0x200>; |
134 | display = <&display>; | ||
135 | default-mode = <&mode0>; | ||
136 | }; | 134 | }; |
137 | 135 | ||
138 | ge_rops@d8050400 { | 136 | ge_rops@d8050400 { |
diff --git a/arch/arm/boot/dts/wm8650-mid.dts b/arch/arm/boot/dts/wm8650-mid.dts index cefd938f842f..61671a0d9ede 100644 --- a/arch/arm/boot/dts/wm8650-mid.dts +++ b/arch/arm/boot/dts/wm8650-mid.dts | |||
@@ -11,26 +11,24 @@ | |||
11 | 11 | ||
12 | / { | 12 | / { |
13 | model = "Wondermedia WM8650-MID Tablet"; | 13 | model = "Wondermedia WM8650-MID Tablet"; |
14 | }; | ||
15 | |||
16 | &fb { | ||
17 | bits-per-pixel = <16>; | ||
14 | 18 | ||
15 | /* | 19 | display-timings { |
16 | * Display node is based on Sascha Hauer's patch on dri-devel. | 20 | native-mode = <&timing0>; |
17 | * Added a bpp property to calculate the size of the framebuffer | 21 | timing0: 800x480 { |
18 | * until the binding is formalized. | 22 | clock-frequency = <0>; /* unused but required */ |
19 | */ | 23 | hactive = <800>; |
20 | display: display@0 { | 24 | vactive = <480>; |
21 | modes { | 25 | hfront-porch = <40>; |
22 | mode0: mode@0 { | 26 | hback-porch = <88>; |
23 | hactive = <800>; | 27 | hsync-len = <0>; |
24 | vactive = <480>; | 28 | vback-porch = <32>; |
25 | hback-porch = <88>; | 29 | vfront-porch = <11>; |
26 | hfront-porch = <40>; | 30 | vsync-len = <1>; |
27 | hsync-len = <0>; | ||
28 | vback-porch = <32>; | ||
29 | vfront-porch = <11>; | ||
30 | vsync-len = <1>; | ||
31 | clock = <0>; /* unused but required */ | ||
32 | bpp = <16>; /* non-standard but required */ | ||
33 | }; | ||
34 | }; | 31 | }; |
35 | }; | 32 | }; |
36 | }; | 33 | }; |
34 | |||
diff --git a/arch/arm/boot/dts/wm8650.dtsi b/arch/arm/boot/dts/wm8650.dtsi index db3c0a12e052..9313407bbc30 100644 --- a/arch/arm/boot/dts/wm8650.dtsi +++ b/arch/arm/boot/dts/wm8650.dtsi | |||
@@ -128,11 +128,9 @@ | |||
128 | interrupts = <43>; | 128 | interrupts = <43>; |
129 | }; | 129 | }; |
130 | 130 | ||
131 | fb@d8050800 { | 131 | fb: fb@d8050800 { |
132 | compatible = "wm,wm8505-fb"; | 132 | compatible = "wm,wm8505-fb"; |
133 | reg = <0xd8050800 0x200>; | 133 | reg = <0xd8050800 0x200>; |
134 | display = <&display>; | ||
135 | default-mode = <&mode0>; | ||
136 | }; | 134 | }; |
137 | 135 | ||
138 | ge_rops@d8050400 { | 136 | ge_rops@d8050400 { |
diff --git a/arch/arm/boot/dts/wm8850-w70v2.dts b/arch/arm/boot/dts/wm8850-w70v2.dts index fcc660c89540..32d22532cd6c 100644 --- a/arch/arm/boot/dts/wm8850-w70v2.dts +++ b/arch/arm/boot/dts/wm8850-w70v2.dts | |||
@@ -15,28 +15,6 @@ | |||
15 | / { | 15 | / { |
16 | model = "Wondermedia WM8850-W70v2 Tablet"; | 16 | model = "Wondermedia WM8850-W70v2 Tablet"; |
17 | 17 | ||
18 | /* | ||
19 | * Display node is based on Sascha Hauer's patch on dri-devel. | ||
20 | * Added a bpp property to calculate the size of the framebuffer | ||
21 | * until the binding is formalized. | ||
22 | */ | ||
23 | display: display@0 { | ||
24 | modes { | ||
25 | mode0: mode@0 { | ||
26 | hactive = <800>; | ||
27 | vactive = <480>; | ||
28 | hback-porch = <88>; | ||
29 | hfront-porch = <40>; | ||
30 | hsync-len = <0>; | ||
31 | vback-porch = <32>; | ||
32 | vfront-porch = <11>; | ||
33 | vsync-len = <1>; | ||
34 | clock = <0>; /* unused but required */ | ||
35 | bpp = <16>; /* non-standard but required */ | ||
36 | }; | ||
37 | }; | ||
38 | }; | ||
39 | |||
40 | backlight { | 18 | backlight { |
41 | compatible = "pwm-backlight"; | 19 | compatible = "pwm-backlight"; |
42 | pwms = <&pwm 0 50000 1>; /* duty inverted */ | 20 | pwms = <&pwm 0 50000 1>; /* duty inverted */ |
@@ -45,3 +23,21 @@ | |||
45 | default-brightness-level = <5>; | 23 | default-brightness-level = <5>; |
46 | }; | 24 | }; |
47 | }; | 25 | }; |
26 | |||
27 | &fb { | ||
28 | bits-per-pixel = <16>; | ||
29 | display-timings { | ||
30 | native-mode = <&timing0>; | ||
31 | timing0: 800x480 { | ||
32 | clock-frequency = <0>; /* unused but required */ | ||
33 | hactive = <800>; | ||
34 | vactive = <480>; | ||
35 | hfront-porch = <40>; | ||
36 | hback-porch = <88>; | ||
37 | hsync-len = <0>; | ||
38 | vback-porch = <32>; | ||
39 | vfront-porch = <11>; | ||
40 | vsync-len = <1>; | ||
41 | }; | ||
42 | }; | ||
43 | }; | ||
diff --git a/arch/arm/boot/dts/wm8850.dtsi b/arch/arm/boot/dts/wm8850.dtsi index e8cbfdc87bba..7149cd13e3b9 100644 --- a/arch/arm/boot/dts/wm8850.dtsi +++ b/arch/arm/boot/dts/wm8850.dtsi | |||
@@ -135,11 +135,9 @@ | |||
135 | }; | 135 | }; |
136 | }; | 136 | }; |
137 | 137 | ||
138 | fb@d8051700 { | 138 | fb: fb@d8051700 { |
139 | compatible = "wm,wm8505-fb"; | 139 | compatible = "wm,wm8505-fb"; |
140 | reg = <0xd8051700 0x200>; | 140 | reg = <0xd8051700 0x200>; |
141 | display = <&display>; | ||
142 | default-mode = <&mode0>; | ||
143 | }; | 141 | }; |
144 | 142 | ||
145 | ge_rops@d8050400 { | 143 | ge_rops@d8050400 { |
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index e36b01025321..088d6c11a0fa 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig | |||
@@ -188,6 +188,7 @@ CONFIG_USB_EHCI_HCD=y | |||
188 | CONFIG_USB_EHCI_MXC=y | 188 | CONFIG_USB_EHCI_MXC=y |
189 | CONFIG_USB_CHIPIDEA=y | 189 | CONFIG_USB_CHIPIDEA=y |
190 | CONFIG_USB_CHIPIDEA_HOST=y | 190 | CONFIG_USB_CHIPIDEA_HOST=y |
191 | CONFIG_USB_PHY=y | ||
191 | CONFIG_USB_MXS_PHY=y | 192 | CONFIG_USB_MXS_PHY=y |
192 | CONFIG_USB_STORAGE=y | 193 | CONFIG_USB_STORAGE=y |
193 | CONFIG_MMC=y | 194 | CONFIG_MMC=y |
diff --git a/arch/arm/configs/lpc32xx_defconfig b/arch/arm/configs/lpc32xx_defconfig index 92386b20bd09..afa7249fac6e 100644 --- a/arch/arm/configs/lpc32xx_defconfig +++ b/arch/arm/configs/lpc32xx_defconfig | |||
@@ -134,6 +134,7 @@ CONFIG_SND_DEBUG_VERBOSE=y | |||
134 | # CONFIG_SND_SPI is not set | 134 | # CONFIG_SND_SPI is not set |
135 | CONFIG_SND_SOC=y | 135 | CONFIG_SND_SOC=y |
136 | CONFIG_USB=y | 136 | CONFIG_USB=y |
137 | CONFIG_USB_PHY=y | ||
137 | CONFIG_USB_OHCI_HCD=y | 138 | CONFIG_USB_OHCI_HCD=y |
138 | CONFIG_USB_STORAGE=y | 139 | CONFIG_USB_STORAGE=y |
139 | CONFIG_USB_GADGET=y | 140 | CONFIG_USB_GADGET=y |
diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig index 6a99e30f81d2..87924d671115 100644 --- a/arch/arm/configs/mxs_defconfig +++ b/arch/arm/configs/mxs_defconfig | |||
@@ -120,6 +120,7 @@ CONFIG_USB_EHCI_HCD=y | |||
120 | CONFIG_USB_CHIPIDEA=y | 120 | CONFIG_USB_CHIPIDEA=y |
121 | CONFIG_USB_CHIPIDEA_HOST=y | 121 | CONFIG_USB_CHIPIDEA_HOST=y |
122 | CONFIG_USB_STORAGE=y | 122 | CONFIG_USB_STORAGE=y |
123 | CONFIG_USB_PHY=y | ||
123 | CONFIG_USB_MXS_PHY=y | 124 | CONFIG_USB_MXS_PHY=y |
124 | CONFIG_MMC=y | 125 | CONFIG_MMC=y |
125 | CONFIG_MMC_MXS=y | 126 | CONFIG_MMC_MXS=y |
diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig index 42eab9a2a0fd..7e0ebb64a7f9 100644 --- a/arch/arm/configs/omap1_defconfig +++ b/arch/arm/configs/omap1_defconfig | |||
@@ -195,6 +195,7 @@ CONFIG_SND_SOC=y | |||
195 | CONFIG_SND_OMAP_SOC=y | 195 | CONFIG_SND_OMAP_SOC=y |
196 | # CONFIG_USB_HID is not set | 196 | # CONFIG_USB_HID is not set |
197 | CONFIG_USB=y | 197 | CONFIG_USB=y |
198 | CONFIG_USB_PHY=y | ||
198 | CONFIG_USB_DEBUG=y | 199 | CONFIG_USB_DEBUG=y |
199 | CONFIG_USB_DEVICEFS=y | 200 | CONFIG_USB_DEVICEFS=y |
200 | # CONFIG_USB_DEVICE_CLASS is not set | 201 | # CONFIG_USB_DEVICE_CLASS is not set |
diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h index cca9f15704ed..ea289e1435e7 100644 --- a/arch/arm/include/asm/glue-cache.h +++ b/arch/arm/include/asm/glue-cache.h | |||
@@ -19,14 +19,6 @@ | |||
19 | #undef _CACHE | 19 | #undef _CACHE |
20 | #undef MULTI_CACHE | 20 | #undef MULTI_CACHE |
21 | 21 | ||
22 | #if defined(CONFIG_CPU_CACHE_V3) | ||
23 | # ifdef _CACHE | ||
24 | # define MULTI_CACHE 1 | ||
25 | # else | ||
26 | # define _CACHE v3 | ||
27 | # endif | ||
28 | #endif | ||
29 | |||
30 | #if defined(CONFIG_CPU_CACHE_V4) | 22 | #if defined(CONFIG_CPU_CACHE_V4) |
31 | # ifdef _CACHE | 23 | # ifdef _CACHE |
32 | # define MULTI_CACHE 1 | 24 | # define MULTI_CACHE 1 |
diff --git a/arch/arm/include/asm/hardware/iop3xx.h b/arch/arm/include/asm/hardware/iop3xx.h index 02fe2fbe2477..ed94b1a366ae 100644 --- a/arch/arm/include/asm/hardware/iop3xx.h +++ b/arch/arm/include/asm/hardware/iop3xx.h | |||
@@ -37,7 +37,7 @@ extern int iop3xx_get_init_atu(void); | |||
37 | * IOP3XX processor registers | 37 | * IOP3XX processor registers |
38 | */ | 38 | */ |
39 | #define IOP3XX_PERIPHERAL_PHYS_BASE 0xffffe000 | 39 | #define IOP3XX_PERIPHERAL_PHYS_BASE 0xffffe000 |
40 | #define IOP3XX_PERIPHERAL_VIRT_BASE 0xfeffe000 | 40 | #define IOP3XX_PERIPHERAL_VIRT_BASE 0xfedfe000 |
41 | #define IOP3XX_PERIPHERAL_SIZE 0x00002000 | 41 | #define IOP3XX_PERIPHERAL_SIZE 0x00002000 |
42 | #define IOP3XX_PERIPHERAL_UPPER_PA (IOP3XX_PERIPHERAL_PHYS_BASE +\ | 42 | #define IOP3XX_PERIPHERAL_UPPER_PA (IOP3XX_PERIPHERAL_PHYS_BASE +\ |
43 | IOP3XX_PERIPHERAL_SIZE - 1) | 43 | IOP3XX_PERIPHERAL_SIZE - 1) |
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h index 6ef8afd1b64c..86b8fe398b95 100644 --- a/arch/arm/include/asm/pgtable-3level.h +++ b/arch/arm/include/asm/pgtable-3level.h | |||
@@ -111,7 +111,7 @@ | |||
111 | #define L_PTE_S2_MT_WRITETHROUGH (_AT(pteval_t, 0xa) << 2) /* MemAttr[3:0] */ | 111 | #define L_PTE_S2_MT_WRITETHROUGH (_AT(pteval_t, 0xa) << 2) /* MemAttr[3:0] */ |
112 | #define L_PTE_S2_MT_WRITEBACK (_AT(pteval_t, 0xf) << 2) /* MemAttr[3:0] */ | 112 | #define L_PTE_S2_MT_WRITEBACK (_AT(pteval_t, 0xf) << 2) /* MemAttr[3:0] */ |
113 | #define L_PTE_S2_RDONLY (_AT(pteval_t, 1) << 6) /* HAP[1] */ | 113 | #define L_PTE_S2_RDONLY (_AT(pteval_t, 1) << 6) /* HAP[1] */ |
114 | #define L_PTE_S2_RDWR (_AT(pteval_t, 2) << 6) /* HAP[2:1] */ | 114 | #define L_PTE_S2_RDWR (_AT(pteval_t, 3) << 6) /* HAP[2:1] */ |
115 | 115 | ||
116 | /* | 116 | /* |
117 | * Hyp-mode PL2 PTE definitions for LPAE. | 117 | * Hyp-mode PL2 PTE definitions for LPAE. |
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 80d6fc4dbe4a..9bcd262a9008 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h | |||
@@ -61,6 +61,15 @@ extern void __pgd_error(const char *file, int line, pgd_t); | |||
61 | #define FIRST_USER_ADDRESS PAGE_SIZE | 61 | #define FIRST_USER_ADDRESS PAGE_SIZE |
62 | 62 | ||
63 | /* | 63 | /* |
64 | * Use TASK_SIZE as the ceiling argument for free_pgtables() and | ||
65 | * free_pgd_range() to avoid freeing the modules pmd when LPAE is enabled (pmd | ||
66 | * page shared between user and kernel). | ||
67 | */ | ||
68 | #ifdef CONFIG_ARM_LPAE | ||
69 | #define USER_PGTABLES_CEILING TASK_SIZE | ||
70 | #endif | ||
71 | |||
72 | /* | ||
64 | * The pgprot_* and protection_map entries will be fixed up in runtime | 73 | * The pgprot_* and protection_map entries will be fixed up in runtime |
65 | * to include the cachable and bufferable bits based on memory policy, | 74 | * to include the cachable and bufferable bits based on memory policy, |
66 | * as well as any architecture dependent bits like global/ASID and SMP | 75 | * as well as any architecture dependent bits like global/ASID and SMP |
diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h index 9e9c041358ca..ab865e65a84c 100644 --- a/arch/arm/include/asm/tlbflush.h +++ b/arch/arm/include/asm/tlbflush.h | |||
@@ -14,7 +14,6 @@ | |||
14 | 14 | ||
15 | #include <asm/glue.h> | 15 | #include <asm/glue.h> |
16 | 16 | ||
17 | #define TLB_V3_PAGE (1 << 0) | ||
18 | #define TLB_V4_U_PAGE (1 << 1) | 17 | #define TLB_V4_U_PAGE (1 << 1) |
19 | #define TLB_V4_D_PAGE (1 << 2) | 18 | #define TLB_V4_D_PAGE (1 << 2) |
20 | #define TLB_V4_I_PAGE (1 << 3) | 19 | #define TLB_V4_I_PAGE (1 << 3) |
@@ -22,7 +21,6 @@ | |||
22 | #define TLB_V6_D_PAGE (1 << 5) | 21 | #define TLB_V6_D_PAGE (1 << 5) |
23 | #define TLB_V6_I_PAGE (1 << 6) | 22 | #define TLB_V6_I_PAGE (1 << 6) |
24 | 23 | ||
25 | #define TLB_V3_FULL (1 << 8) | ||
26 | #define TLB_V4_U_FULL (1 << 9) | 24 | #define TLB_V4_U_FULL (1 << 9) |
27 | #define TLB_V4_D_FULL (1 << 10) | 25 | #define TLB_V4_D_FULL (1 << 10) |
28 | #define TLB_V4_I_FULL (1 << 11) | 26 | #define TLB_V4_I_FULL (1 << 11) |
@@ -52,7 +50,6 @@ | |||
52 | * ============= | 50 | * ============= |
53 | * | 51 | * |
54 | * We have the following to choose from: | 52 | * We have the following to choose from: |
55 | * v3 - ARMv3 | ||
56 | * v4 - ARMv4 without write buffer | 53 | * v4 - ARMv4 without write buffer |
57 | * v4wb - ARMv4 with write buffer without I TLB flush entry instruction | 54 | * v4wb - ARMv4 with write buffer without I TLB flush entry instruction |
58 | * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction | 55 | * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction |
@@ -330,7 +327,6 @@ static inline void local_flush_tlb_all(void) | |||
330 | if (tlb_flag(TLB_WB)) | 327 | if (tlb_flag(TLB_WB)) |
331 | dsb(); | 328 | dsb(); |
332 | 329 | ||
333 | tlb_op(TLB_V3_FULL, "c6, c0, 0", zero); | ||
334 | tlb_op(TLB_V4_U_FULL | TLB_V6_U_FULL, "c8, c7, 0", zero); | 330 | tlb_op(TLB_V4_U_FULL | TLB_V6_U_FULL, "c8, c7, 0", zero); |
335 | tlb_op(TLB_V4_D_FULL | TLB_V6_D_FULL, "c8, c6, 0", zero); | 331 | tlb_op(TLB_V4_D_FULL | TLB_V6_D_FULL, "c8, c6, 0", zero); |
336 | tlb_op(TLB_V4_I_FULL | TLB_V6_I_FULL, "c8, c5, 0", zero); | 332 | tlb_op(TLB_V4_I_FULL | TLB_V6_I_FULL, "c8, c5, 0", zero); |
@@ -351,9 +347,8 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm) | |||
351 | if (tlb_flag(TLB_WB)) | 347 | if (tlb_flag(TLB_WB)) |
352 | dsb(); | 348 | dsb(); |
353 | 349 | ||
354 | if (possible_tlb_flags & (TLB_V3_FULL|TLB_V4_U_FULL|TLB_V4_D_FULL|TLB_V4_I_FULL)) { | 350 | if (possible_tlb_flags & (TLB_V4_U_FULL|TLB_V4_D_FULL|TLB_V4_I_FULL)) { |
355 | if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) { | 351 | if (cpumask_test_cpu(get_cpu(), mm_cpumask(mm))) { |
356 | tlb_op(TLB_V3_FULL, "c6, c0, 0", zero); | ||
357 | tlb_op(TLB_V4_U_FULL, "c8, c7, 0", zero); | 352 | tlb_op(TLB_V4_U_FULL, "c8, c7, 0", zero); |
358 | tlb_op(TLB_V4_D_FULL, "c8, c6, 0", zero); | 353 | tlb_op(TLB_V4_D_FULL, "c8, c6, 0", zero); |
359 | tlb_op(TLB_V4_I_FULL, "c8, c5, 0", zero); | 354 | tlb_op(TLB_V4_I_FULL, "c8, c5, 0", zero); |
@@ -385,9 +380,8 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) | |||
385 | if (tlb_flag(TLB_WB)) | 380 | if (tlb_flag(TLB_WB)) |
386 | dsb(); | 381 | dsb(); |
387 | 382 | ||
388 | if (possible_tlb_flags & (TLB_V3_PAGE|TLB_V4_U_PAGE|TLB_V4_D_PAGE|TLB_V4_I_PAGE|TLB_V4_I_FULL) && | 383 | if (possible_tlb_flags & (TLB_V4_U_PAGE|TLB_V4_D_PAGE|TLB_V4_I_PAGE|TLB_V4_I_FULL) && |
389 | cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { | 384 | cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { |
390 | tlb_op(TLB_V3_PAGE, "c6, c0, 0", uaddr); | ||
391 | tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", uaddr); | 385 | tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", uaddr); |
392 | tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", uaddr); | 386 | tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", uaddr); |
393 | tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", uaddr); | 387 | tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", uaddr); |
@@ -418,7 +412,6 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr) | |||
418 | if (tlb_flag(TLB_WB)) | 412 | if (tlb_flag(TLB_WB)) |
419 | dsb(); | 413 | dsb(); |
420 | 414 | ||
421 | tlb_op(TLB_V3_PAGE, "c6, c0, 0", kaddr); | ||
422 | tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", kaddr); | 415 | tlb_op(TLB_V4_U_PAGE, "c8, c7, 1", kaddr); |
423 | tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", kaddr); | 416 | tlb_op(TLB_V4_D_PAGE, "c8, c6, 1", kaddr); |
424 | tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", kaddr); | 417 | tlb_op(TLB_V4_I_PAGE, "c8, c5, 1", kaddr); |
diff --git a/arch/arm/kernel/early_printk.c b/arch/arm/kernel/early_printk.c index 85aa2b292692..43076536965c 100644 --- a/arch/arm/kernel/early_printk.c +++ b/arch/arm/kernel/early_printk.c | |||
@@ -29,28 +29,17 @@ static void early_console_write(struct console *con, const char *s, unsigned n) | |||
29 | early_write(s, n); | 29 | early_write(s, n); |
30 | } | 30 | } |
31 | 31 | ||
32 | static struct console early_console = { | 32 | static struct console early_console_dev = { |
33 | .name = "earlycon", | 33 | .name = "earlycon", |
34 | .write = early_console_write, | 34 | .write = early_console_write, |
35 | .flags = CON_PRINTBUFFER | CON_BOOT, | 35 | .flags = CON_PRINTBUFFER | CON_BOOT, |
36 | .index = -1, | 36 | .index = -1, |
37 | }; | 37 | }; |
38 | 38 | ||
39 | asmlinkage void early_printk(const char *fmt, ...) | ||
40 | { | ||
41 | char buf[512]; | ||
42 | int n; | ||
43 | va_list ap; | ||
44 | |||
45 | va_start(ap, fmt); | ||
46 | n = vscnprintf(buf, sizeof(buf), fmt, ap); | ||
47 | early_write(buf, n); | ||
48 | va_end(ap); | ||
49 | } | ||
50 | |||
51 | static int __init setup_early_printk(char *buf) | 39 | static int __init setup_early_printk(char *buf) |
52 | { | 40 | { |
53 | register_console(&early_console); | 41 | early_console = &early_console_dev; |
42 | register_console(&early_console_dev); | ||
54 | return 0; | 43 | return 0; |
55 | } | 44 | } |
56 | 45 | ||
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 5dc1aa6f0f7d..1fd749ee4a1b 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c | |||
@@ -1043,7 +1043,7 @@ static int dbg_cpu_pm_notify(struct notifier_block *self, unsigned long action, | |||
1043 | return NOTIFY_OK; | 1043 | return NOTIFY_OK; |
1044 | } | 1044 | } |
1045 | 1045 | ||
1046 | static struct notifier_block __cpuinitdata dbg_cpu_pm_nb = { | 1046 | static struct notifier_block dbg_cpu_pm_nb = { |
1047 | .notifier_call = dbg_cpu_pm_notify, | 1047 | .notifier_call = dbg_cpu_pm_notify, |
1048 | }; | 1048 | }; |
1049 | 1049 | ||
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index 146157dfe27c..8c3094d0f7b7 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c | |||
@@ -253,7 +253,10 @@ validate_event(struct pmu_hw_events *hw_events, | |||
253 | struct arm_pmu *armpmu = to_arm_pmu(event->pmu); | 253 | struct arm_pmu *armpmu = to_arm_pmu(event->pmu); |
254 | struct pmu *leader_pmu = event->group_leader->pmu; | 254 | struct pmu *leader_pmu = event->group_leader->pmu; |
255 | 255 | ||
256 | if (event->pmu != leader_pmu || event->state <= PERF_EVENT_STATE_OFF) | 256 | if (event->pmu != leader_pmu || event->state < PERF_EVENT_STATE_OFF) |
257 | return 1; | ||
258 | |||
259 | if (event->state == PERF_EVENT_STATE_OFF && !event->attr.enable_on_exec) | ||
257 | return 1; | 260 | return 1; |
258 | 261 | ||
259 | return armpmu->get_event_idx(hw_events, event) >= 0; | 262 | return armpmu->get_event_idx(hw_events, event) >= 0; |
diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c index bd6f56b9ec21..59d2adb764a9 100644 --- a/arch/arm/kernel/sched_clock.c +++ b/arch/arm/kernel/sched_clock.c | |||
@@ -45,12 +45,12 @@ static u32 notrace jiffy_sched_clock_read(void) | |||
45 | 45 | ||
46 | static u32 __read_mostly (*read_sched_clock)(void) = jiffy_sched_clock_read; | 46 | static u32 __read_mostly (*read_sched_clock)(void) = jiffy_sched_clock_read; |
47 | 47 | ||
48 | static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift) | 48 | static inline u64 notrace cyc_to_ns(u64 cyc, u32 mult, u32 shift) |
49 | { | 49 | { |
50 | return (cyc * mult) >> shift; | 50 | return (cyc * mult) >> shift; |
51 | } | 51 | } |
52 | 52 | ||
53 | static unsigned long long cyc_to_sched_clock(u32 cyc, u32 mask) | 53 | static unsigned long long notrace cyc_to_sched_clock(u32 cyc, u32 mask) |
54 | { | 54 | { |
55 | u64 epoch_ns; | 55 | u64 epoch_ns; |
56 | u32 epoch_cyc; | 56 | u32 epoch_cyc; |
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index d343a6c3a6d1..234e339196c0 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -56,7 +56,6 @@ | |||
56 | #include <asm/virt.h> | 56 | #include <asm/virt.h> |
57 | 57 | ||
58 | #include "atags.h" | 58 | #include "atags.h" |
59 | #include "tcm.h" | ||
60 | 59 | ||
61 | 60 | ||
62 | #if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE) | 61 | #if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE) |
@@ -798,8 +797,6 @@ void __init setup_arch(char **cmdline_p) | |||
798 | 797 | ||
799 | reserve_crashkernel(); | 798 | reserve_crashkernel(); |
800 | 799 | ||
801 | tcm_init(); | ||
802 | |||
803 | #ifdef CONFIG_MULTI_IRQ_HANDLER | 800 | #ifdef CONFIG_MULTI_IRQ_HANDLER |
804 | handle_arch_irq = mdesc->handle_irq; | 801 | handle_arch_irq = mdesc->handle_irq; |
805 | #endif | 802 | #endif |
diff --git a/arch/arm/kernel/tcm.c b/arch/arm/kernel/tcm.c index 30ae6bb4a310..f50f19e5c138 100644 --- a/arch/arm/kernel/tcm.c +++ b/arch/arm/kernel/tcm.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <asm/mach/map.h> | 17 | #include <asm/mach/map.h> |
18 | #include <asm/memory.h> | 18 | #include <asm/memory.h> |
19 | #include <asm/system_info.h> | 19 | #include <asm/system_info.h> |
20 | #include "tcm.h" | ||
21 | 20 | ||
22 | static struct gen_pool *tcm_pool; | 21 | static struct gen_pool *tcm_pool; |
23 | static bool dtcm_present; | 22 | static bool dtcm_present; |
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index 5a936988eb24..c1fe498983ac 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c | |||
@@ -201,6 +201,7 @@ int kvm_dev_ioctl_check_extension(long ext) | |||
201 | break; | 201 | break; |
202 | case KVM_CAP_ARM_SET_DEVICE_ADDR: | 202 | case KVM_CAP_ARM_SET_DEVICE_ADDR: |
203 | r = 1; | 203 | r = 1; |
204 | break; | ||
204 | case KVM_CAP_NR_VCPUS: | 205 | case KVM_CAP_NR_VCPUS: |
205 | r = num_online_cpus(); | 206 | r = num_online_cpus(); |
206 | break; | 207 | break; |
diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c index 4ea9a982269c..7bed7556077a 100644 --- a/arch/arm/kvm/coproc.c +++ b/arch/arm/kvm/coproc.c | |||
@@ -79,11 +79,11 @@ static bool access_dcsw(struct kvm_vcpu *vcpu, | |||
79 | u32 val; | 79 | u32 val; |
80 | int cpu; | 80 | int cpu; |
81 | 81 | ||
82 | cpu = get_cpu(); | ||
83 | |||
84 | if (!p->is_write) | 82 | if (!p->is_write) |
85 | return read_from_write_only(vcpu, p); | 83 | return read_from_write_only(vcpu, p); |
86 | 84 | ||
85 | cpu = get_cpu(); | ||
86 | |||
87 | cpumask_setall(&vcpu->arch.require_dcache_flush); | 87 | cpumask_setall(&vcpu->arch.require_dcache_flush); |
88 | cpumask_clear_cpu(cpu, &vcpu->arch.require_dcache_flush); | 88 | cpumask_clear_cpu(cpu, &vcpu->arch.require_dcache_flush); |
89 | 89 | ||
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c index b67cd5374117..44199bc2c665 100644 --- a/arch/arm/mach-at91/at91sam9260.c +++ b/arch/arm/mach-at91/at91sam9260.c | |||
@@ -232,6 +232,8 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
232 | CLKDEV_CON_DEV_ID("t2_clk", "fffdc000.timer", &tc5_clk), | 232 | CLKDEV_CON_DEV_ID("t2_clk", "fffdc000.timer", &tc5_clk), |
233 | CLKDEV_CON_DEV_ID("hclk", "500000.ohci", &ohci_clk), | 233 | CLKDEV_CON_DEV_ID("hclk", "500000.ohci", &ohci_clk), |
234 | CLKDEV_CON_DEV_ID("mci_clk", "fffa8000.mmc", &mmc_clk), | 234 | CLKDEV_CON_DEV_ID("mci_clk", "fffa8000.mmc", &mmc_clk), |
235 | CLKDEV_CON_DEV_ID("spi_clk", "fffc8000.spi", &spi0_clk), | ||
236 | CLKDEV_CON_DEV_ID("spi_clk", "fffcc000.spi", &spi1_clk), | ||
235 | /* fake hclk clock */ | 237 | /* fake hclk clock */ |
236 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), | 238 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), |
237 | CLKDEV_CON_ID("pioA", &pioA_clk), | 239 | CLKDEV_CON_ID("pioA", &pioA_clk), |
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c index d3addee43d8d..2ec5efea3f03 100644 --- a/arch/arm/mach-at91/at91sam9g45.c +++ b/arch/arm/mach-at91/at91sam9g45.c | |||
@@ -262,6 +262,8 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
262 | CLKDEV_CON_DEV_ID("mci_clk", "fffd0000.mmc", &mmc1_clk), | 262 | CLKDEV_CON_DEV_ID("mci_clk", "fffd0000.mmc", &mmc1_clk), |
263 | CLKDEV_CON_DEV_ID(NULL, "fff84000.i2c", &twi0_clk), | 263 | CLKDEV_CON_DEV_ID(NULL, "fff84000.i2c", &twi0_clk), |
264 | CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", &twi1_clk), | 264 | CLKDEV_CON_DEV_ID(NULL, "fff88000.i2c", &twi1_clk), |
265 | CLKDEV_CON_DEV_ID("spi_clk", "fffa4000.spi", &spi0_clk), | ||
266 | CLKDEV_CON_DEV_ID("spi_clk", "fffa8000.spi", &spi1_clk), | ||
265 | /* fake hclk clock */ | 267 | /* fake hclk clock */ |
266 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk), | 268 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &uhphs_clk), |
267 | CLKDEV_CON_DEV_ID(NULL, "fffff200.gpio", &pioA_clk), | 269 | CLKDEV_CON_DEV_ID(NULL, "fffff200.gpio", &pioA_clk), |
diff --git a/arch/arm/mach-at91/at91sam9n12.c b/arch/arm/mach-at91/at91sam9n12.c index 5dfc8fd87103..ccd078355eed 100644 --- a/arch/arm/mach-at91/at91sam9n12.c +++ b/arch/arm/mach-at91/at91sam9n12.c | |||
@@ -172,6 +172,8 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
172 | CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma_clk), | 172 | CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma_clk), |
173 | CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk), | 173 | CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk), |
174 | CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk), | 174 | CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk), |
175 | CLKDEV_CON_DEV_ID("spi_clk", "f0000000.spi", &spi0_clk), | ||
176 | CLKDEV_CON_DEV_ID("spi_clk", "f0004000.spi", &spi1_clk), | ||
175 | CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioAB_clk), | 177 | CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioAB_clk), |
176 | CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioAB_clk), | 178 | CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioAB_clk), |
177 | CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCD_clk), | 179 | CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCD_clk), |
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c index 44a9a62dcc13..a200d8a17123 100644 --- a/arch/arm/mach-at91/at91sam9x5.c +++ b/arch/arm/mach-at91/at91sam9x5.c | |||
@@ -237,6 +237,8 @@ static struct clk_lookup periph_clocks_lookups[] = { | |||
237 | CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk), | 237 | CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk), |
238 | CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk), | 238 | CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk), |
239 | CLKDEV_CON_DEV_ID(NULL, "f8018000.i2c", &twi2_clk), | 239 | CLKDEV_CON_DEV_ID(NULL, "f8018000.i2c", &twi2_clk), |
240 | CLKDEV_CON_DEV_ID("spi_clk", "f0000000.spi", &spi0_clk), | ||
241 | CLKDEV_CON_DEV_ID("spi_clk", "f0004000.spi", &spi1_clk), | ||
240 | CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioAB_clk), | 242 | CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioAB_clk), |
241 | CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioAB_clk), | 243 | CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioAB_clk), |
242 | CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCD_clk), | 244 | CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCD_clk), |
diff --git a/arch/arm/mach-exynos/mach-universal_c210.c b/arch/arm/mach-exynos/mach-universal_c210.c index 497fcb793dc1..d28c7fbaba2d 100644 --- a/arch/arm/mach-exynos/mach-universal_c210.c +++ b/arch/arm/mach-exynos/mach-universal_c210.c | |||
@@ -97,6 +97,19 @@ static struct s3c2410_uartcfg universal_uartcfgs[] __initdata = { | |||
97 | static struct regulator_consumer_supply max8952_consumer = | 97 | static struct regulator_consumer_supply max8952_consumer = |
98 | REGULATOR_SUPPLY("vdd_arm", NULL); | 98 | REGULATOR_SUPPLY("vdd_arm", NULL); |
99 | 99 | ||
100 | static struct regulator_init_data universal_max8952_reg_data = { | ||
101 | .constraints = { | ||
102 | .name = "VARM_1.2V", | ||
103 | .min_uV = 770000, | ||
104 | .max_uV = 1400000, | ||
105 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, | ||
106 | .always_on = 1, | ||
107 | .boot_on = 1, | ||
108 | }, | ||
109 | .num_consumer_supplies = 1, | ||
110 | .consumer_supplies = &max8952_consumer, | ||
111 | }; | ||
112 | |||
100 | static struct max8952_platform_data universal_max8952_pdata __initdata = { | 113 | static struct max8952_platform_data universal_max8952_pdata __initdata = { |
101 | .gpio_vid0 = EXYNOS4_GPX0(3), | 114 | .gpio_vid0 = EXYNOS4_GPX0(3), |
102 | .gpio_vid1 = EXYNOS4_GPX0(4), | 115 | .gpio_vid1 = EXYNOS4_GPX0(4), |
@@ -105,19 +118,7 @@ static struct max8952_platform_data universal_max8952_pdata __initdata = { | |||
105 | .dvs_mode = { 48, 32, 28, 18 }, /* 1.25, 1.20, 1.05, 0.95V */ | 118 | .dvs_mode = { 48, 32, 28, 18 }, /* 1.25, 1.20, 1.05, 0.95V */ |
106 | .sync_freq = 0, /* default: fastest */ | 119 | .sync_freq = 0, /* default: fastest */ |
107 | .ramp_speed = 0, /* default: fastest */ | 120 | .ramp_speed = 0, /* default: fastest */ |
108 | 121 | .reg_data = &universal_max8952_reg_data, | |
109 | .reg_data = { | ||
110 | .constraints = { | ||
111 | .name = "VARM_1.2V", | ||
112 | .min_uV = 770000, | ||
113 | .max_uV = 1400000, | ||
114 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, | ||
115 | .always_on = 1, | ||
116 | .boot_on = 1, | ||
117 | }, | ||
118 | .num_consumer_supplies = 1, | ||
119 | .consumer_supplies = &max8952_consumer, | ||
120 | }, | ||
121 | }; | 122 | }; |
122 | 123 | ||
123 | static struct regulator_consumer_supply lp3974_buck1_consumer = | 124 | static struct regulator_consumer_supply lp3974_buck1_consumer = |
diff --git a/arch/arm/mach-exynos/setup-usb-phy.c b/arch/arm/mach-exynos/setup-usb-phy.c index b81cc569a8dd..6af40662a449 100644 --- a/arch/arm/mach-exynos/setup-usb-phy.c +++ b/arch/arm/mach-exynos/setup-usb-phy.c | |||
@@ -204,9 +204,9 @@ static int exynos4210_usb_phy1_exit(struct platform_device *pdev) | |||
204 | 204 | ||
205 | int s5p_usb_phy_init(struct platform_device *pdev, int type) | 205 | int s5p_usb_phy_init(struct platform_device *pdev, int type) |
206 | { | 206 | { |
207 | if (type == S5P_USB_PHY_DEVICE) | 207 | if (type == USB_PHY_TYPE_DEVICE) |
208 | return exynos4210_usb_phy0_init(pdev); | 208 | return exynos4210_usb_phy0_init(pdev); |
209 | else if (type == S5P_USB_PHY_HOST) | 209 | else if (type == USB_PHY_TYPE_HOST) |
210 | return exynos4210_usb_phy1_init(pdev); | 210 | return exynos4210_usb_phy1_init(pdev); |
211 | 211 | ||
212 | return -EINVAL; | 212 | return -EINVAL; |
@@ -214,9 +214,9 @@ int s5p_usb_phy_init(struct platform_device *pdev, int type) | |||
214 | 214 | ||
215 | int s5p_usb_phy_exit(struct platform_device *pdev, int type) | 215 | int s5p_usb_phy_exit(struct platform_device *pdev, int type) |
216 | { | 216 | { |
217 | if (type == S5P_USB_PHY_DEVICE) | 217 | if (type == USB_PHY_TYPE_DEVICE) |
218 | return exynos4210_usb_phy0_exit(pdev); | 218 | return exynos4210_usb_phy0_exit(pdev); |
219 | else if (type == S5P_USB_PHY_HOST) | 219 | else if (type == USB_PHY_TYPE_HOST) |
220 | return exynos4210_usb_phy1_exit(pdev); | 220 | return exynos4210_usb_phy1_exit(pdev); |
221 | 221 | ||
222 | return -EINVAL; | 222 | return -EINVAL; |
diff --git a/arch/arm/mach-highbank/hotplug.c b/arch/arm/mach-highbank/hotplug.c index f30c52843396..890cae23c12a 100644 --- a/arch/arm/mach-highbank/hotplug.c +++ b/arch/arm/mach-highbank/hotplug.c | |||
@@ -28,13 +28,11 @@ extern void secondary_startup(void); | |||
28 | */ | 28 | */ |
29 | void __ref highbank_cpu_die(unsigned int cpu) | 29 | void __ref highbank_cpu_die(unsigned int cpu) |
30 | { | 30 | { |
31 | flush_cache_all(); | ||
32 | |||
33 | highbank_set_cpu_jump(cpu, phys_to_virt(0)); | 31 | highbank_set_cpu_jump(cpu, phys_to_virt(0)); |
34 | highbank_set_core_pwr(); | ||
35 | 32 | ||
36 | cpu_do_idle(); | 33 | flush_cache_louis(); |
34 | highbank_set_core_pwr(); | ||
37 | 35 | ||
38 | /* We should never return from idle */ | 36 | while (1) |
39 | panic("highbank: cpu %d unexpectedly exit from shutdown\n", cpu); | 37 | cpu_do_idle(); |
40 | } | 38 | } |
diff --git a/arch/arm/mach-imx/clk-busy.c b/arch/arm/mach-imx/clk-busy.c index 1ab91b5209e6..85b728cc27ab 100644 --- a/arch/arm/mach-imx/clk-busy.c +++ b/arch/arm/mach-imx/clk-busy.c | |||
@@ -169,7 +169,7 @@ struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift, | |||
169 | 169 | ||
170 | busy->mux.reg = reg; | 170 | busy->mux.reg = reg; |
171 | busy->mux.shift = shift; | 171 | busy->mux.shift = shift; |
172 | busy->mux.width = width; | 172 | busy->mux.mask = BIT(width) - 1; |
173 | busy->mux.lock = &imx_ccm_lock; | 173 | busy->mux.lock = &imx_ccm_lock; |
174 | busy->mux_ops = &clk_mux_ops; | 174 | busy->mux_ops = &clk_mux_ops; |
175 | 175 | ||
diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c index e13a8fa5e62c..2193c834f55c 100644 --- a/arch/arm/mach-imx/clk-imx35.c +++ b/arch/arm/mach-imx/clk-imx35.c | |||
@@ -257,6 +257,7 @@ int __init mx35_clocks_init(void) | |||
257 | clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0"); | 257 | clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0"); |
258 | clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0"); | 258 | clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0"); |
259 | clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0"); | 259 | clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0"); |
260 | clk_register_clkdev(clk[admux_gate], "audmux", NULL); | ||
260 | 261 | ||
261 | clk_prepare_enable(clk[spba_gate]); | 262 | clk_prepare_enable(clk[spba_gate]); |
262 | clk_prepare_enable(clk[gpio1_gate]); | 263 | clk_prepare_enable(clk[gpio1_gate]); |
@@ -265,6 +266,7 @@ int __init mx35_clocks_init(void) | |||
265 | clk_prepare_enable(clk[iim_gate]); | 266 | clk_prepare_enable(clk[iim_gate]); |
266 | clk_prepare_enable(clk[emi_gate]); | 267 | clk_prepare_enable(clk[emi_gate]); |
267 | clk_prepare_enable(clk[max_gate]); | 268 | clk_prepare_enable(clk[max_gate]); |
269 | clk_prepare_enable(clk[iomuxc_gate]); | ||
268 | 270 | ||
269 | /* | 271 | /* |
270 | * SCC is needed to boot via mmc after a watchdog reset. The clock code | 272 | * SCC is needed to boot via mmc after a watchdog reset. The clock code |
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 2f9ff93a4e61..d38e54f5b6d7 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c | |||
@@ -115,7 +115,7 @@ static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m" | |||
115 | static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", }; | 115 | static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", }; |
116 | static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", }; | 116 | static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", }; |
117 | static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", }; | 117 | static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", }; |
118 | static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_pfd1_540m", }; | 118 | static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", }; |
119 | static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", }; | 119 | static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", }; |
120 | static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; | 120 | static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; |
121 | static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; | 121 | static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; |
@@ -443,7 +443,6 @@ int __init mx6q_clocks_init(void) | |||
443 | 443 | ||
444 | clk_register_clkdev(clk[gpt_ipg], "ipg", "imx-gpt.0"); | 444 | clk_register_clkdev(clk[gpt_ipg], "ipg", "imx-gpt.0"); |
445 | clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0"); | 445 | clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0"); |
446 | clk_register_clkdev(clk[twd], NULL, "smp_twd"); | ||
447 | clk_register_clkdev(clk[cko1_sel], "cko1_sel", NULL); | 446 | clk_register_clkdev(clk[cko1_sel], "cko1_sel", NULL); |
448 | clk_register_clkdev(clk[ahb], "ahb", NULL); | 447 | clk_register_clkdev(clk[ahb], "ahb", NULL); |
449 | clk_register_clkdev(clk[cko1], "cko1", NULL); | 448 | clk_register_clkdev(clk[cko1], "cko1", NULL); |
diff --git a/arch/arm/mach-kirkwood/board-iomega_ix2_200.c b/arch/arm/mach-kirkwood/board-iomega_ix2_200.c index f655b2637b0e..e5f70415905a 100644 --- a/arch/arm/mach-kirkwood/board-iomega_ix2_200.c +++ b/arch/arm/mach-kirkwood/board-iomega_ix2_200.c | |||
@@ -20,10 +20,15 @@ static struct mv643xx_eth_platform_data iomega_ix2_200_ge00_data = { | |||
20 | .duplex = DUPLEX_FULL, | 20 | .duplex = DUPLEX_FULL, |
21 | }; | 21 | }; |
22 | 22 | ||
23 | static struct mv643xx_eth_platform_data iomega_ix2_200_ge01_data = { | ||
24 | .phy_addr = MV643XX_ETH_PHY_ADDR(11), | ||
25 | }; | ||
26 | |||
23 | void __init iomega_ix2_200_init(void) | 27 | void __init iomega_ix2_200_init(void) |
24 | { | 28 | { |
25 | /* | 29 | /* |
26 | * Basic setup. Needs to be called early. | 30 | * Basic setup. Needs to be called early. |
27 | */ | 31 | */ |
28 | kirkwood_ge01_init(&iomega_ix2_200_ge00_data); | 32 | kirkwood_ge00_init(&iomega_ix2_200_ge00_data); |
33 | kirkwood_ge01_init(&iomega_ix2_200_ge01_data); | ||
29 | } | 34 | } |
diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c index 9f64d5632e07..76901f4ce611 100644 --- a/arch/arm/mach-mmp/aspenite.c +++ b/arch/arm/mach-mmp/aspenite.c | |||
@@ -223,13 +223,7 @@ static struct pxa27x_keypad_platform_data aspenite_keypad_info __initdata = { | |||
223 | }; | 223 | }; |
224 | 224 | ||
225 | #if defined(CONFIG_USB_EHCI_MV) | 225 | #if defined(CONFIG_USB_EHCI_MV) |
226 | static char *pxa168_sph_clock_name[] = { | ||
227 | [0] = "PXA168-USBCLK", | ||
228 | }; | ||
229 | |||
230 | static struct mv_usb_platform_data pxa168_sph_pdata = { | 226 | static struct mv_usb_platform_data pxa168_sph_pdata = { |
231 | .clknum = 1, | ||
232 | .clkname = pxa168_sph_clock_name, | ||
233 | .mode = MV_USB_MODE_HOST, | 227 | .mode = MV_USB_MODE_HOST, |
234 | .phy_init = pxa_usb_phy_init, | 228 | .phy_init = pxa_usb_phy_init, |
235 | .phy_deinit = pxa_usb_phy_deinit, | 229 | .phy_deinit = pxa_usb_phy_deinit, |
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c index 22a9058f9f4d..6528a5fa6a26 100644 --- a/arch/arm/mach-mmp/ttc_dkb.c +++ b/arch/arm/mach-mmp/ttc_dkb.c | |||
@@ -162,13 +162,7 @@ static struct i2c_board_info ttc_dkb_i2c_info[] = { | |||
162 | #ifdef CONFIG_USB_SUPPORT | 162 | #ifdef CONFIG_USB_SUPPORT |
163 | #if defined(CONFIG_USB_MV_UDC) || defined(CONFIG_USB_EHCI_MV_U2O) | 163 | #if defined(CONFIG_USB_MV_UDC) || defined(CONFIG_USB_EHCI_MV_U2O) |
164 | 164 | ||
165 | static char *pxa910_usb_clock_name[] = { | ||
166 | [0] = "U2OCLK", | ||
167 | }; | ||
168 | |||
169 | static struct mv_usb_platform_data ttc_usb_pdata = { | 165 | static struct mv_usb_platform_data ttc_usb_pdata = { |
170 | .clknum = 1, | ||
171 | .clkname = pxa910_usb_clock_name, | ||
172 | .vbus = NULL, | 166 | .vbus = NULL, |
173 | .mode = MV_USB_MODE_OTG, | 167 | .mode = MV_USB_MODE_OTG, |
174 | .otg_force_a_bus_req = 1, | 168 | .otg_force_a_bus_req = 1, |
diff --git a/arch/arm/mach-mvebu/irq-armada-370-xp.c b/arch/arm/mach-mvebu/irq-armada-370-xp.c index 6a9195e10579..d5970f5a1e8d 100644 --- a/arch/arm/mach-mvebu/irq-armada-370-xp.c +++ b/arch/arm/mach-mvebu/irq-armada-370-xp.c | |||
@@ -61,7 +61,6 @@ static struct irq_domain *armada_370_xp_mpic_domain; | |||
61 | */ | 61 | */ |
62 | static void armada_370_xp_irq_mask(struct irq_data *d) | 62 | static void armada_370_xp_irq_mask(struct irq_data *d) |
63 | { | 63 | { |
64 | #ifdef CONFIG_SMP | ||
65 | irq_hw_number_t hwirq = irqd_to_hwirq(d); | 64 | irq_hw_number_t hwirq = irqd_to_hwirq(d); |
66 | 65 | ||
67 | if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) | 66 | if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) |
@@ -70,15 +69,10 @@ static void armada_370_xp_irq_mask(struct irq_data *d) | |||
70 | else | 69 | else |
71 | writel(hwirq, per_cpu_int_base + | 70 | writel(hwirq, per_cpu_int_base + |
72 | ARMADA_370_XP_INT_SET_MASK_OFFS); | 71 | ARMADA_370_XP_INT_SET_MASK_OFFS); |
73 | #else | ||
74 | writel(irqd_to_hwirq(d), | ||
75 | per_cpu_int_base + ARMADA_370_XP_INT_SET_MASK_OFFS); | ||
76 | #endif | ||
77 | } | 72 | } |
78 | 73 | ||
79 | static void armada_370_xp_irq_unmask(struct irq_data *d) | 74 | static void armada_370_xp_irq_unmask(struct irq_data *d) |
80 | { | 75 | { |
81 | #ifdef CONFIG_SMP | ||
82 | irq_hw_number_t hwirq = irqd_to_hwirq(d); | 76 | irq_hw_number_t hwirq = irqd_to_hwirq(d); |
83 | 77 | ||
84 | if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) | 78 | if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) |
@@ -87,10 +81,6 @@ static void armada_370_xp_irq_unmask(struct irq_data *d) | |||
87 | else | 81 | else |
88 | writel(hwirq, per_cpu_int_base + | 82 | writel(hwirq, per_cpu_int_base + |
89 | ARMADA_370_XP_INT_CLEAR_MASK_OFFS); | 83 | ARMADA_370_XP_INT_CLEAR_MASK_OFFS); |
90 | #else | ||
91 | writel(irqd_to_hwirq(d), | ||
92 | per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); | ||
93 | #endif | ||
94 | } | 84 | } |
95 | 85 | ||
96 | #ifdef CONFIG_SMP | 86 | #ifdef CONFIG_SMP |
@@ -146,7 +136,11 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h, | |||
146 | unsigned int virq, irq_hw_number_t hw) | 136 | unsigned int virq, irq_hw_number_t hw) |
147 | { | 137 | { |
148 | armada_370_xp_irq_mask(irq_get_irq_data(virq)); | 138 | armada_370_xp_irq_mask(irq_get_irq_data(virq)); |
149 | writel(hw, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS); | 139 | if (hw != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) |
140 | writel(hw, per_cpu_int_base + | ||
141 | ARMADA_370_XP_INT_CLEAR_MASK_OFFS); | ||
142 | else | ||
143 | writel(hw, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS); | ||
150 | irq_set_status_flags(virq, IRQ_LEVEL); | 144 | irq_set_status_flags(virq, IRQ_LEVEL); |
151 | 145 | ||
152 | if (hw == ARMADA_370_XP_TIMER0_PER_CPU_IRQ) { | 146 | if (hw == ARMADA_370_XP_TIMER0_PER_CPU_IRQ) { |
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 9e0576569e07..eaba9dc91a0d 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c | |||
@@ -2714,16 +2714,22 @@ static struct omap_ocp2scp_dev ocp2scp_dev_attr[] = { | |||
2714 | { } | 2714 | { } |
2715 | }; | 2715 | }; |
2716 | 2716 | ||
2717 | static struct omap_hwmod_opt_clk ocp2scp_usb_phy_opt_clks[] = { | ||
2718 | { .role = "48mhz", .clk = "ocp2scp_usb_phy_phy_48m" }, | ||
2719 | }; | ||
2720 | |||
2721 | /* ocp2scp_usb_phy */ | 2717 | /* ocp2scp_usb_phy */ |
2722 | static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { | 2718 | static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { |
2723 | .name = "ocp2scp_usb_phy", | 2719 | .name = "ocp2scp_usb_phy", |
2724 | .class = &omap44xx_ocp2scp_hwmod_class, | 2720 | .class = &omap44xx_ocp2scp_hwmod_class, |
2725 | .clkdm_name = "l3_init_clkdm", | 2721 | .clkdm_name = "l3_init_clkdm", |
2726 | .main_clk = "func_48m_fclk", | 2722 | /* |
2723 | * ocp2scp_usb_phy_phy_48m is provided by the OMAP4 PRCM IP | ||
2724 | * block as an "optional clock," and normally should never be | ||
2725 | * specified as the main_clk for an OMAP IP block. However it | ||
2726 | * turns out that this clock is actually the main clock for | ||
2727 | * the ocp2scp_usb_phy IP block: | ||
2728 | * http://lists.infradead.org/pipermail/linux-arm-kernel/2012-September/119943.html | ||
2729 | * So listing ocp2scp_usb_phy_phy_48m as a main_clk here seems | ||
2730 | * to be the best workaround. | ||
2731 | */ | ||
2732 | .main_clk = "ocp2scp_usb_phy_phy_48m", | ||
2727 | .prcm = { | 2733 | .prcm = { |
2728 | .omap4 = { | 2734 | .omap4 = { |
2729 | .clkctrl_offs = OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET, | 2735 | .clkctrl_offs = OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET, |
@@ -2732,8 +2738,6 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { | |||
2732 | }, | 2738 | }, |
2733 | }, | 2739 | }, |
2734 | .dev_attr = ocp2scp_dev_attr, | 2740 | .dev_attr = ocp2scp_dev_attr, |
2735 | .opt_clks = ocp2scp_usb_phy_opt_clks, | ||
2736 | .opt_clks_cnt = ARRAY_SIZE(ocp2scp_usb_phy_opt_clks), | ||
2737 | }; | 2741 | }; |
2738 | 2742 | ||
2739 | /* | 2743 | /* |
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2440.c b/arch/arm/mach-s3c24xx/clock-s3c2440.c index 04b87ec92537..1069b5680826 100644 --- a/arch/arm/mach-s3c24xx/clock-s3c2440.c +++ b/arch/arm/mach-s3c24xx/clock-s3c2440.c | |||
@@ -123,6 +123,11 @@ static struct clk s3c2440_clk_ac97 = { | |||
123 | .ctrlbit = S3C2440_CLKCON_AC97, | 123 | .ctrlbit = S3C2440_CLKCON_AC97, |
124 | }; | 124 | }; |
125 | 125 | ||
126 | #define S3C24XX_VA_UART0 (S3C_VA_UART) | ||
127 | #define S3C24XX_VA_UART1 (S3C_VA_UART + 0x4000 ) | ||
128 | #define S3C24XX_VA_UART2 (S3C_VA_UART + 0x8000 ) | ||
129 | #define S3C24XX_VA_UART3 (S3C_VA_UART + 0xC000 ) | ||
130 | |||
126 | static unsigned long s3c2440_fclk_n_getrate(struct clk *clk) | 131 | static unsigned long s3c2440_fclk_n_getrate(struct clk *clk) |
127 | { | 132 | { |
128 | unsigned long ucon0, ucon1, ucon2, divisor; | 133 | unsigned long ucon0, ucon1, ucon2, divisor; |
diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c index 6bcf87f65f9e..92e609440c57 100644 --- a/arch/arm/mach-s3c24xx/common.c +++ b/arch/arm/mach-s3c24xx/common.c | |||
@@ -239,6 +239,11 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size) | |||
239 | 239 | ||
240 | /* Serial port registrations */ | 240 | /* Serial port registrations */ |
241 | 241 | ||
242 | #define S3C2410_PA_UART0 (S3C24XX_PA_UART) | ||
243 | #define S3C2410_PA_UART1 (S3C24XX_PA_UART + 0x4000 ) | ||
244 | #define S3C2410_PA_UART2 (S3C24XX_PA_UART + 0x8000 ) | ||
245 | #define S3C2443_PA_UART3 (S3C24XX_PA_UART + 0xC000 ) | ||
246 | |||
242 | static struct resource s3c2410_uart0_resource[] = { | 247 | static struct resource s3c2410_uart0_resource[] = { |
243 | [0] = DEFINE_RES_MEM(S3C2410_PA_UART0, SZ_16K), | 248 | [0] = DEFINE_RES_MEM(S3C2410_PA_UART0, SZ_16K), |
244 | [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX0, \ | 249 | [1] = DEFINE_RES_NAMED(IRQ_S3CUART_RX0, \ |
diff --git a/arch/arm/mach-s3c24xx/include/mach/irqs.h b/arch/arm/mach-s3c24xx/include/mach/irqs.h index b7a9f4d469e8..1e73f5fa8659 100644 --- a/arch/arm/mach-s3c24xx/include/mach/irqs.h +++ b/arch/arm/mach-s3c24xx/include/mach/irqs.h | |||
@@ -188,10 +188,8 @@ | |||
188 | 188 | ||
189 | #if defined(CONFIG_CPU_S3C2416) | 189 | #if defined(CONFIG_CPU_S3C2416) |
190 | #define NR_IRQS (IRQ_S3C2416_I2S1 + 1) | 190 | #define NR_IRQS (IRQ_S3C2416_I2S1 + 1) |
191 | #elif defined(CONFIG_CPU_S3C2443) | ||
192 | #define NR_IRQS (IRQ_S3C2443_AC97+1) | ||
193 | #else | 191 | #else |
194 | #define NR_IRQS (IRQ_S3C2440_AC97+1) | 192 | #define NR_IRQS (IRQ_S3C2443_AC97 + 1) |
195 | #endif | 193 | #endif |
196 | 194 | ||
197 | /* compatibility define. */ | 195 | /* compatibility define. */ |
diff --git a/arch/arm/mach-s3c24xx/irq.c b/arch/arm/mach-s3c24xx/irq.c index cb9f5e011e73..d8ba9bee4c7e 100644 --- a/arch/arm/mach-s3c24xx/irq.c +++ b/arch/arm/mach-s3c24xx/irq.c | |||
@@ -500,7 +500,7 @@ struct s3c_irq_intc *s3c24xx_init_intc(struct device_node *np, | |||
500 | base = (void *)0xfd000000; | 500 | base = (void *)0xfd000000; |
501 | 501 | ||
502 | intc->reg_mask = base + 0xa4; | 502 | intc->reg_mask = base + 0xa4; |
503 | intc->reg_pending = base + 0x08; | 503 | intc->reg_pending = base + 0xa8; |
504 | irq_num = 20; | 504 | irq_num = 20; |
505 | irq_start = S3C2410_IRQ(32); | 505 | irq_start = S3C2410_IRQ(32); |
506 | irq_offset = 4; | 506 | irq_offset = 4; |
diff --git a/arch/arm/mach-s3c64xx/setup-usb-phy.c b/arch/arm/mach-s3c64xx/setup-usb-phy.c index c8174d95339b..ca960bda02fd 100644 --- a/arch/arm/mach-s3c64xx/setup-usb-phy.c +++ b/arch/arm/mach-s3c64xx/setup-usb-phy.c | |||
@@ -76,7 +76,7 @@ static int s3c_usb_otgphy_exit(struct platform_device *pdev) | |||
76 | 76 | ||
77 | int s5p_usb_phy_init(struct platform_device *pdev, int type) | 77 | int s5p_usb_phy_init(struct platform_device *pdev, int type) |
78 | { | 78 | { |
79 | if (type == S5P_USB_PHY_DEVICE) | 79 | if (type == USB_PHY_TYPE_DEVICE) |
80 | return s3c_usb_otgphy_init(pdev); | 80 | return s3c_usb_otgphy_init(pdev); |
81 | 81 | ||
82 | return -EINVAL; | 82 | return -EINVAL; |
@@ -84,7 +84,7 @@ int s5p_usb_phy_init(struct platform_device *pdev, int type) | |||
84 | 84 | ||
85 | int s5p_usb_phy_exit(struct platform_device *pdev, int type) | 85 | int s5p_usb_phy_exit(struct platform_device *pdev, int type) |
86 | { | 86 | { |
87 | if (type == S5P_USB_PHY_DEVICE) | 87 | if (type == USB_PHY_TYPE_DEVICE) |
88 | return s3c_usb_otgphy_exit(pdev); | 88 | return s3c_usb_otgphy_exit(pdev); |
89 | 89 | ||
90 | return -EINVAL; | 90 | return -EINVAL; |
diff --git a/arch/arm/mach-s5pv210/setup-usb-phy.c b/arch/arm/mach-s5pv210/setup-usb-phy.c index 356a0900af03..b2ee5333f89c 100644 --- a/arch/arm/mach-s5pv210/setup-usb-phy.c +++ b/arch/arm/mach-s5pv210/setup-usb-phy.c | |||
@@ -80,7 +80,7 @@ static int s5pv210_usb_otgphy_exit(struct platform_device *pdev) | |||
80 | 80 | ||
81 | int s5p_usb_phy_init(struct platform_device *pdev, int type) | 81 | int s5p_usb_phy_init(struct platform_device *pdev, int type) |
82 | { | 82 | { |
83 | if (type == S5P_USB_PHY_DEVICE) | 83 | if (type == USB_PHY_TYPE_DEVICE) |
84 | return s5pv210_usb_otgphy_init(pdev); | 84 | return s5pv210_usb_otgphy_init(pdev); |
85 | 85 | ||
86 | return -EINVAL; | 86 | return -EINVAL; |
@@ -88,7 +88,7 @@ int s5p_usb_phy_init(struct platform_device *pdev, int type) | |||
88 | 88 | ||
89 | int s5p_usb_phy_exit(struct platform_device *pdev, int type) | 89 | int s5p_usb_phy_exit(struct platform_device *pdev, int type) |
90 | { | 90 | { |
91 | if (type == S5P_USB_PHY_DEVICE) | 91 | if (type == USB_PHY_TYPE_DEVICE) |
92 | return s5pv210_usb_otgphy_exit(pdev); | 92 | return s5pv210_usb_otgphy_exit(pdev); |
93 | 93 | ||
94 | return -EINVAL; | 94 | return -EINVAL; |
diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c index f2ec0777cfbe..ff8b7ba9b93c 100644 --- a/arch/arm/mach-shmobile/board-armadillo800eva.c +++ b/arch/arm/mach-shmobile/board-armadillo800eva.c | |||
@@ -169,7 +169,7 @@ static int usbhsf_get_id(struct platform_device *pdev) | |||
169 | return USBHS_GADGET; | 169 | return USBHS_GADGET; |
170 | } | 170 | } |
171 | 171 | ||
172 | static void usbhsf_power_ctrl(struct platform_device *pdev, | 172 | static int usbhsf_power_ctrl(struct platform_device *pdev, |
173 | void __iomem *base, int enable) | 173 | void __iomem *base, int enable) |
174 | { | 174 | { |
175 | struct usbhsf_private *priv = usbhsf_get_priv(pdev); | 175 | struct usbhsf_private *priv = usbhsf_get_priv(pdev); |
@@ -223,6 +223,8 @@ static void usbhsf_power_ctrl(struct platform_device *pdev, | |||
223 | clk_disable(priv->pci); /* usb work around */ | 223 | clk_disable(priv->pci); /* usb work around */ |
224 | clk_disable(priv->usb24); /* usb work around */ | 224 | clk_disable(priv->usb24); /* usb work around */ |
225 | } | 225 | } |
226 | |||
227 | return 0; | ||
226 | } | 228 | } |
227 | 229 | ||
228 | static int usbhsf_get_vbus(struct platform_device *pdev) | 230 | static int usbhsf_get_vbus(struct platform_device *pdev) |
@@ -239,7 +241,7 @@ static irqreturn_t usbhsf_interrupt(int irq, void *data) | |||
239 | return IRQ_HANDLED; | 241 | return IRQ_HANDLED; |
240 | } | 242 | } |
241 | 243 | ||
242 | static void usbhsf_hardware_exit(struct platform_device *pdev) | 244 | static int usbhsf_hardware_exit(struct platform_device *pdev) |
243 | { | 245 | { |
244 | struct usbhsf_private *priv = usbhsf_get_priv(pdev); | 246 | struct usbhsf_private *priv = usbhsf_get_priv(pdev); |
245 | 247 | ||
@@ -264,6 +266,8 @@ static void usbhsf_hardware_exit(struct platform_device *pdev) | |||
264 | priv->usbh_base = NULL; | 266 | priv->usbh_base = NULL; |
265 | 267 | ||
266 | free_irq(IRQ7, pdev); | 268 | free_irq(IRQ7, pdev); |
269 | |||
270 | return 0; | ||
267 | } | 271 | } |
268 | 272 | ||
269 | static int usbhsf_hardware_init(struct platform_device *pdev) | 273 | static int usbhsf_hardware_init(struct platform_device *pdev) |
diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c index 7f3a6b7e7b7c..a385f570bbfc 100644 --- a/arch/arm/mach-shmobile/board-kzm9g.c +++ b/arch/arm/mach-shmobile/board-kzm9g.c | |||
@@ -155,12 +155,14 @@ static int usbhs_get_vbus(struct platform_device *pdev) | |||
155 | return !((1 << 7) & __raw_readw(priv->cr2)); | 155 | return !((1 << 7) & __raw_readw(priv->cr2)); |
156 | } | 156 | } |
157 | 157 | ||
158 | static void usbhs_phy_reset(struct platform_device *pdev) | 158 | static int usbhs_phy_reset(struct platform_device *pdev) |
159 | { | 159 | { |
160 | struct usbhs_private *priv = usbhs_get_priv(pdev); | 160 | struct usbhs_private *priv = usbhs_get_priv(pdev); |
161 | 161 | ||
162 | /* init phy */ | 162 | /* init phy */ |
163 | __raw_writew(0x8a0a, priv->cr2); | 163 | __raw_writew(0x8a0a, priv->cr2); |
164 | |||
165 | return 0; | ||
164 | } | 166 | } |
165 | 167 | ||
166 | static int usbhs_get_id(struct platform_device *pdev) | 168 | static int usbhs_get_id(struct platform_device *pdev) |
@@ -202,7 +204,7 @@ static int usbhs_hardware_init(struct platform_device *pdev) | |||
202 | return 0; | 204 | return 0; |
203 | } | 205 | } |
204 | 206 | ||
205 | static void usbhs_hardware_exit(struct platform_device *pdev) | 207 | static int usbhs_hardware_exit(struct platform_device *pdev) |
206 | { | 208 | { |
207 | struct usbhs_private *priv = usbhs_get_priv(pdev); | 209 | struct usbhs_private *priv = usbhs_get_priv(pdev); |
208 | 210 | ||
@@ -210,6 +212,8 @@ static void usbhs_hardware_exit(struct platform_device *pdev) | |||
210 | __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->phy); | 212 | __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->phy); |
211 | 213 | ||
212 | free_irq(IRQ15, pdev); | 214 | free_irq(IRQ15, pdev); |
215 | |||
216 | return 0; | ||
213 | } | 217 | } |
214 | 218 | ||
215 | static u32 usbhs_pipe_cfg[] = { | 219 | static u32 usbhs_pipe_cfg[] = { |
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index db968a585ff0..979237c18dad 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c | |||
@@ -596,12 +596,14 @@ static int usbhs_get_vbus(struct platform_device *pdev) | |||
596 | return usbhs_is_connected(usbhs_get_priv(pdev)); | 596 | return usbhs_is_connected(usbhs_get_priv(pdev)); |
597 | } | 597 | } |
598 | 598 | ||
599 | static void usbhs_phy_reset(struct platform_device *pdev) | 599 | static int usbhs_phy_reset(struct platform_device *pdev) |
600 | { | 600 | { |
601 | struct usbhs_private *priv = usbhs_get_priv(pdev); | 601 | struct usbhs_private *priv = usbhs_get_priv(pdev); |
602 | 602 | ||
603 | /* init phy */ | 603 | /* init phy */ |
604 | __raw_writew(0x8a0a, priv->usbcrcaddr); | 604 | __raw_writew(0x8a0a, priv->usbcrcaddr); |
605 | |||
606 | return 0; | ||
605 | } | 607 | } |
606 | 608 | ||
607 | static int usbhs0_get_id(struct platform_device *pdev) | 609 | static int usbhs0_get_id(struct platform_device *pdev) |
@@ -628,11 +630,13 @@ static int usbhs0_hardware_init(struct platform_device *pdev) | |||
628 | return 0; | 630 | return 0; |
629 | } | 631 | } |
630 | 632 | ||
631 | static void usbhs0_hardware_exit(struct platform_device *pdev) | 633 | static int usbhs0_hardware_exit(struct platform_device *pdev) |
632 | { | 634 | { |
633 | struct usbhs_private *priv = usbhs_get_priv(pdev); | 635 | struct usbhs_private *priv = usbhs_get_priv(pdev); |
634 | 636 | ||
635 | cancel_delayed_work_sync(&priv->work); | 637 | cancel_delayed_work_sync(&priv->work); |
638 | |||
639 | return 0; | ||
636 | } | 640 | } |
637 | 641 | ||
638 | static struct usbhs_private usbhs0_private = { | 642 | static struct usbhs_private usbhs0_private = { |
@@ -735,7 +739,7 @@ static int usbhs1_hardware_init(struct platform_device *pdev) | |||
735 | return 0; | 739 | return 0; |
736 | } | 740 | } |
737 | 741 | ||
738 | static void usbhs1_hardware_exit(struct platform_device *pdev) | 742 | static int usbhs1_hardware_exit(struct platform_device *pdev) |
739 | { | 743 | { |
740 | struct usbhs_private *priv = usbhs_get_priv(pdev); | 744 | struct usbhs_private *priv = usbhs_get_priv(pdev); |
741 | 745 | ||
@@ -743,6 +747,8 @@ static void usbhs1_hardware_exit(struct platform_device *pdev) | |||
743 | __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->usbphyaddr); | 747 | __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->usbphyaddr); |
744 | 748 | ||
745 | free_irq(IRQ8, pdev); | 749 | free_irq(IRQ8, pdev); |
750 | |||
751 | return 0; | ||
746 | } | 752 | } |
747 | 753 | ||
748 | static int usbhs1_get_id(struct platform_device *pdev) | 754 | static int usbhs1_get_id(struct platform_device *pdev) |
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index d1c4893894ce..dbc653ea851c 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig | |||
@@ -18,8 +18,8 @@ config ARCH_TEGRA_2x_SOC | |||
18 | select PL310_ERRATA_727915 if CACHE_L2X0 | 18 | select PL310_ERRATA_727915 if CACHE_L2X0 |
19 | select PL310_ERRATA_769419 if CACHE_L2X0 | 19 | select PL310_ERRATA_769419 if CACHE_L2X0 |
20 | select USB_ARCH_HAS_EHCI if USB_SUPPORT | 20 | select USB_ARCH_HAS_EHCI if USB_SUPPORT |
21 | select USB_ULPI if USB | 21 | select USB_ULPI if USB_PHY |
22 | select USB_ULPI_VIEWPORT if USB_SUPPORT | 22 | select USB_ULPI_VIEWPORT if USB_PHY |
23 | help | 23 | help |
24 | Support for NVIDIA Tegra AP20 and T20 processors, based on the | 24 | Support for NVIDIA Tegra AP20 and T20 processors, based on the |
25 | ARM CortexA9MP CPU and the ARM PL310 L2 cache controller | 25 | ARM CortexA9MP CPU and the ARM PL310 L2 cache controller |
@@ -37,8 +37,8 @@ config ARCH_TEGRA_3x_SOC | |||
37 | select PINCTRL_TEGRA30 | 37 | select PINCTRL_TEGRA30 |
38 | select PL310_ERRATA_769419 if CACHE_L2X0 | 38 | select PL310_ERRATA_769419 if CACHE_L2X0 |
39 | select USB_ARCH_HAS_EHCI if USB_SUPPORT | 39 | select USB_ARCH_HAS_EHCI if USB_SUPPORT |
40 | select USB_ULPI if USB | 40 | select USB_ULPI if USB_PHY |
41 | select USB_ULPI_VIEWPORT if USB_SUPPORT | 41 | select USB_ULPI_VIEWPORT if USB_PHY |
42 | help | 42 | help |
43 | Support for NVIDIA Tegra T30 processor family, based on the | 43 | Support for NVIDIA Tegra T30 processor family, based on the |
44 | ARM CortexA9MP CPU and the ARM PL310 L2 cache controller | 44 | ARM CortexA9MP CPU and the ARM PL310 L2 cache controller |
diff --git a/arch/arm/mach-ux500/board-mop500-regulators.c b/arch/arm/mach-ux500/board-mop500-regulators.c index 2a17bc506cff..ff3c9f016591 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.c +++ b/arch/arm/mach-ux500/board-mop500-regulators.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * | 5 | * |
6 | * Authors: Sundar Iyer <sundar.iyer@stericsson.com> | 6 | * Authors: Sundar Iyer <sundar.iyer@stericsson.com> |
7 | * Bengt Jonsson <bengt.g.jonsson@stericsson.com> | 7 | * Bengt Jonsson <bengt.g.jonsson@stericsson.com> |
8 | * Daniel Willerud <daniel.willerud@stericsson.com> | ||
8 | * | 9 | * |
9 | * MOP500 board specific initialization for regulators | 10 | * MOP500 board specific initialization for regulators |
10 | */ | 11 | */ |
@@ -12,6 +13,7 @@ | |||
12 | #include <linux/regulator/machine.h> | 13 | #include <linux/regulator/machine.h> |
13 | #include <linux/regulator/ab8500.h> | 14 | #include <linux/regulator/ab8500.h> |
14 | #include "board-mop500-regulators.h" | 15 | #include "board-mop500-regulators.h" |
16 | #include "id.h" | ||
15 | 17 | ||
16 | static struct regulator_consumer_supply gpio_en_3v3_consumers[] = { | 18 | static struct regulator_consumer_supply gpio_en_3v3_consumers[] = { |
17 | REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), | 19 | REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), |
@@ -53,21 +55,37 @@ struct regulator_init_data tps61052_regulator = { | |||
53 | }; | 55 | }; |
54 | 56 | ||
55 | static struct regulator_consumer_supply ab8500_vaux1_consumers[] = { | 57 | static struct regulator_consumer_supply ab8500_vaux1_consumers[] = { |
56 | /* External displays, connector on board 2v5 power supply */ | 58 | /* Main display, u8500 R3 uib */ |
57 | REGULATOR_SUPPLY("vaux12v5", "mcde.0"), | 59 | REGULATOR_SUPPLY("vddi", "mcde_disp_sony_acx424akp.0"), |
60 | /* Main display, u8500 uib and ST uib */ | ||
61 | REGULATOR_SUPPLY("vdd1", "samsung_s6d16d0.0"), | ||
62 | /* Secondary display, ST uib */ | ||
63 | REGULATOR_SUPPLY("vdd1", "samsung_s6d16d0.1"), | ||
58 | /* SFH7741 proximity sensor */ | 64 | /* SFH7741 proximity sensor */ |
59 | REGULATOR_SUPPLY("vcc", "gpio-keys.0"), | 65 | REGULATOR_SUPPLY("vcc", "gpio-keys.0"), |
60 | /* BH1780GLS ambient light sensor */ | 66 | /* BH1780GLS ambient light sensor */ |
61 | REGULATOR_SUPPLY("vcc", "2-0029"), | 67 | REGULATOR_SUPPLY("vcc", "2-0029"), |
62 | /* lsm303dlh accelerometer */ | 68 | /* lsm303dlh accelerometer */ |
63 | REGULATOR_SUPPLY("vdd", "3-0018"), | 69 | REGULATOR_SUPPLY("vdd", "2-0018"), |
70 | /* lsm303dlhc accelerometer */ | ||
71 | REGULATOR_SUPPLY("vdd", "2-0019"), | ||
64 | /* lsm303dlh magnetometer */ | 72 | /* lsm303dlh magnetometer */ |
65 | REGULATOR_SUPPLY("vdd", "3-001e"), | 73 | REGULATOR_SUPPLY("vdd", "2-001e"), |
66 | /* Rohm BU21013 Touchscreen devices */ | 74 | /* Rohm BU21013 Touchscreen devices */ |
67 | REGULATOR_SUPPLY("avdd", "3-005c"), | 75 | REGULATOR_SUPPLY("avdd", "3-005c"), |
68 | REGULATOR_SUPPLY("avdd", "3-005d"), | 76 | REGULATOR_SUPPLY("avdd", "3-005d"), |
69 | /* Synaptics RMI4 Touchscreen device */ | 77 | /* Synaptics RMI4 Touchscreen device */ |
70 | REGULATOR_SUPPLY("vdd", "3-004b"), | 78 | REGULATOR_SUPPLY("vdd", "3-004b"), |
79 | /* L3G4200D Gyroscope device */ | ||
80 | REGULATOR_SUPPLY("vdd", "2-0068"), | ||
81 | /* Ambient light sensor device */ | ||
82 | REGULATOR_SUPPLY("vdd", "3-0029"), | ||
83 | /* Pressure sensor device */ | ||
84 | REGULATOR_SUPPLY("vdd", "2-005c"), | ||
85 | /* Cypress TrueTouch Touchscreen device */ | ||
86 | REGULATOR_SUPPLY("vcpin", "spi8.0"), | ||
87 | /* Camera device */ | ||
88 | REGULATOR_SUPPLY("vaux12v5", "mmio_camera"), | ||
71 | }; | 89 | }; |
72 | 90 | ||
73 | static struct regulator_consumer_supply ab8500_vaux2_consumers[] = { | 91 | static struct regulator_consumer_supply ab8500_vaux2_consumers[] = { |
@@ -75,18 +93,50 @@ static struct regulator_consumer_supply ab8500_vaux2_consumers[] = { | |||
75 | REGULATOR_SUPPLY("vmmc", "sdi4"), | 93 | REGULATOR_SUPPLY("vmmc", "sdi4"), |
76 | /* AB8500 audio codec */ | 94 | /* AB8500 audio codec */ |
77 | REGULATOR_SUPPLY("vcc-N2158", "ab8500-codec.0"), | 95 | REGULATOR_SUPPLY("vcc-N2158", "ab8500-codec.0"), |
96 | /* AB8500 accessory detect 1 */ | ||
97 | REGULATOR_SUPPLY("vcc-N2158", "ab8500-acc-det.0"), | ||
98 | /* AB8500 Tv-out device */ | ||
99 | REGULATOR_SUPPLY("vcc-N2158", "mcde_tv_ab8500.4"), | ||
100 | /* AV8100 HDMI device */ | ||
101 | REGULATOR_SUPPLY("vcc-N2158", "av8100_hdmi.3"), | ||
78 | }; | 102 | }; |
79 | 103 | ||
80 | static struct regulator_consumer_supply ab8500_vaux3_consumers[] = { | 104 | static struct regulator_consumer_supply ab8500_vaux3_consumers[] = { |
105 | REGULATOR_SUPPLY("v-SD-STM", "stm"), | ||
81 | /* External MMC slot power */ | 106 | /* External MMC slot power */ |
82 | REGULATOR_SUPPLY("vmmc", "sdi0"), | 107 | REGULATOR_SUPPLY("vmmc", "sdi0"), |
83 | }; | 108 | }; |
84 | 109 | ||
110 | static struct regulator_consumer_supply ab8505_vaux4_consumers[] = { | ||
111 | }; | ||
112 | |||
113 | static struct regulator_consumer_supply ab8505_vaux5_consumers[] = { | ||
114 | }; | ||
115 | |||
116 | static struct regulator_consumer_supply ab8505_vaux6_consumers[] = { | ||
117 | }; | ||
118 | |||
119 | static struct regulator_consumer_supply ab8505_vaux8_consumers[] = { | ||
120 | /* AB8500 audio codec device */ | ||
121 | REGULATOR_SUPPLY("v-aux8", NULL), | ||
122 | }; | ||
123 | |||
124 | static struct regulator_consumer_supply ab8505_vadc_consumers[] = { | ||
125 | /* Internal general-purpose ADC */ | ||
126 | REGULATOR_SUPPLY("vddadc", "ab8500-gpadc.0"), | ||
127 | /* ADC for charger */ | ||
128 | REGULATOR_SUPPLY("vddadc", "ab8500-charger.0"), | ||
129 | }; | ||
130 | |||
85 | static struct regulator_consumer_supply ab8500_vtvout_consumers[] = { | 131 | static struct regulator_consumer_supply ab8500_vtvout_consumers[] = { |
86 | /* TV-out DENC supply */ | 132 | /* TV-out DENC supply */ |
87 | REGULATOR_SUPPLY("vtvout", "ab8500-denc.0"), | 133 | REGULATOR_SUPPLY("vtvout", "ab8500-denc.0"), |
88 | /* Internal general-purpose ADC */ | 134 | /* Internal general-purpose ADC */ |
89 | REGULATOR_SUPPLY("vddadc", "ab8500-gpadc.0"), | 135 | REGULATOR_SUPPLY("vddadc", "ab8500-gpadc.0"), |
136 | /* ADC for charger */ | ||
137 | REGULATOR_SUPPLY("vddadc", "ab8500-charger.0"), | ||
138 | /* AB8500 Tv-out device */ | ||
139 | REGULATOR_SUPPLY("vtvout", "mcde_tv_ab8500.4"), | ||
90 | }; | 140 | }; |
91 | 141 | ||
92 | static struct regulator_consumer_supply ab8500_vaud_consumers[] = { | 142 | static struct regulator_consumer_supply ab8500_vaud_consumers[] = { |
@@ -114,77 +164,90 @@ static struct regulator_consumer_supply ab8500_vintcore_consumers[] = { | |||
114 | REGULATOR_SUPPLY("v-intcore", NULL), | 164 | REGULATOR_SUPPLY("v-intcore", NULL), |
115 | /* USB Transceiver */ | 165 | /* USB Transceiver */ |
116 | REGULATOR_SUPPLY("vddulpivio18", "ab8500-usb.0"), | 166 | REGULATOR_SUPPLY("vddulpivio18", "ab8500-usb.0"), |
167 | /* Handled by abx500 clk driver */ | ||
168 | REGULATOR_SUPPLY("v-intcore", "abx500-clk.0"), | ||
169 | }; | ||
170 | |||
171 | static struct regulator_consumer_supply ab8505_usb_consumers[] = { | ||
172 | /* HS USB OTG physical interface */ | ||
173 | REGULATOR_SUPPLY("v-ape", NULL), | ||
117 | }; | 174 | }; |
118 | 175 | ||
119 | static struct regulator_consumer_supply ab8500_vana_consumers[] = { | 176 | static struct regulator_consumer_supply ab8500_vana_consumers[] = { |
120 | /* External displays, connector on board, 1v8 power supply */ | 177 | /* DB8500 DSI */ |
121 | REGULATOR_SUPPLY("vsmps2", "mcde.0"), | 178 | REGULATOR_SUPPLY("vdddsi1v2", "mcde"), |
179 | REGULATOR_SUPPLY("vdddsi1v2", "b2r2_core"), | ||
180 | REGULATOR_SUPPLY("vdddsi1v2", "b2r2_1_core"), | ||
181 | REGULATOR_SUPPLY("vdddsi1v2", "dsilink.0"), | ||
182 | REGULATOR_SUPPLY("vdddsi1v2", "dsilink.1"), | ||
183 | REGULATOR_SUPPLY("vdddsi1v2", "dsilink.2"), | ||
184 | /* DB8500 CSI */ | ||
185 | REGULATOR_SUPPLY("vddcsi1v2", "mmio_camera"), | ||
122 | }; | 186 | }; |
123 | 187 | ||
124 | /* ab8500 regulator register initialization */ | 188 | /* ab8500 regulator register initialization */ |
125 | struct ab8500_regulator_reg_init | 189 | static struct ab8500_regulator_reg_init ab8500_reg_init[] = { |
126 | ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { | ||
127 | /* | 190 | /* |
128 | * VanaRequestCtrl = HP/LP depending on VxRequest | 191 | * VanaRequestCtrl = HP/LP depending on VxRequest |
129 | * VextSupply1RequestCtrl = HP/LP depending on VxRequest | 192 | * VextSupply1RequestCtrl = HP/LP depending on VxRequest |
130 | */ | 193 | */ |
131 | INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL2, 0x00), | 194 | INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL2, 0xf0, 0x00), |
132 | /* | 195 | /* |
133 | * VextSupply2RequestCtrl = HP/LP depending on VxRequest | 196 | * VextSupply2RequestCtrl = HP/LP depending on VxRequest |
134 | * VextSupply3RequestCtrl = HP/LP depending on VxRequest | 197 | * VextSupply3RequestCtrl = HP/LP depending on VxRequest |
135 | * Vaux1RequestCtrl = HP/LP depending on VxRequest | 198 | * Vaux1RequestCtrl = HP/LP depending on VxRequest |
136 | * Vaux2RequestCtrl = HP/LP depending on VxRequest | 199 | * Vaux2RequestCtrl = HP/LP depending on VxRequest |
137 | */ | 200 | */ |
138 | INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL3, 0x00), | 201 | INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL3, 0xff, 0x00), |
139 | /* | 202 | /* |
140 | * Vaux3RequestCtrl = HP/LP depending on VxRequest | 203 | * Vaux3RequestCtrl = HP/LP depending on VxRequest |
141 | * SwHPReq = Control through SWValid disabled | 204 | * SwHPReq = Control through SWValid disabled |
142 | */ | 205 | */ |
143 | INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL4, 0x00), | 206 | INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL4, 0x07, 0x00), |
144 | /* | 207 | /* |
145 | * VanaSysClkReq1HPValid = disabled | 208 | * VanaSysClkReq1HPValid = disabled |
146 | * Vaux1SysClkReq1HPValid = disabled | 209 | * Vaux1SysClkReq1HPValid = disabled |
147 | * Vaux2SysClkReq1HPValid = disabled | 210 | * Vaux2SysClkReq1HPValid = disabled |
148 | * Vaux3SysClkReq1HPValid = disabled | 211 | * Vaux3SysClkReq1HPValid = disabled |
149 | */ | 212 | */ |
150 | INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID1, 0x00), | 213 | INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID1, 0xe8, 0x00), |
151 | /* | 214 | /* |
152 | * VextSupply1SysClkReq1HPValid = disabled | 215 | * VextSupply1SysClkReq1HPValid = disabled |
153 | * VextSupply2SysClkReq1HPValid = disabled | 216 | * VextSupply2SysClkReq1HPValid = disabled |
154 | * VextSupply3SysClkReq1HPValid = SysClkReq1 controlled | 217 | * VextSupply3SysClkReq1HPValid = SysClkReq1 controlled |
155 | */ | 218 | */ |
156 | INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID2, 0x40), | 219 | INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID2, 0x70, 0x40), |
157 | /* | 220 | /* |
158 | * VanaHwHPReq1Valid = disabled | 221 | * VanaHwHPReq1Valid = disabled |
159 | * Vaux1HwHPreq1Valid = disabled | 222 | * Vaux1HwHPreq1Valid = disabled |
160 | * Vaux2HwHPReq1Valid = disabled | 223 | * Vaux2HwHPReq1Valid = disabled |
161 | * Vaux3HwHPReqValid = disabled | 224 | * Vaux3HwHPReqValid = disabled |
162 | */ | 225 | */ |
163 | INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID1, 0x00), | 226 | INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID1, 0xe8, 0x00), |
164 | /* | 227 | /* |
165 | * VextSupply1HwHPReq1Valid = disabled | 228 | * VextSupply1HwHPReq1Valid = disabled |
166 | * VextSupply2HwHPReq1Valid = disabled | 229 | * VextSupply2HwHPReq1Valid = disabled |
167 | * VextSupply3HwHPReq1Valid = disabled | 230 | * VextSupply3HwHPReq1Valid = disabled |
168 | */ | 231 | */ |
169 | INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID2, 0x00), | 232 | INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID2, 0x07, 0x00), |
170 | /* | 233 | /* |
171 | * VanaHwHPReq2Valid = disabled | 234 | * VanaHwHPReq2Valid = disabled |
172 | * Vaux1HwHPReq2Valid = disabled | 235 | * Vaux1HwHPReq2Valid = disabled |
173 | * Vaux2HwHPReq2Valid = disabled | 236 | * Vaux2HwHPReq2Valid = disabled |
174 | * Vaux3HwHPReq2Valid = disabled | 237 | * Vaux3HwHPReq2Valid = disabled |
175 | */ | 238 | */ |
176 | INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID1, 0x00), | 239 | INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID1, 0xe8, 0x00), |
177 | /* | 240 | /* |
178 | * VextSupply1HwHPReq2Valid = disabled | 241 | * VextSupply1HwHPReq2Valid = disabled |
179 | * VextSupply2HwHPReq2Valid = disabled | 242 | * VextSupply2HwHPReq2Valid = disabled |
180 | * VextSupply3HwHPReq2Valid = HWReq2 controlled | 243 | * VextSupply3HwHPReq2Valid = HWReq2 controlled |
181 | */ | 244 | */ |
182 | INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID2, 0x04), | 245 | INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID2, 0x07, 0x04), |
183 | /* | 246 | /* |
184 | * VanaSwHPReqValid = disabled | 247 | * VanaSwHPReqValid = disabled |
185 | * Vaux1SwHPReqValid = disabled | 248 | * Vaux1SwHPReqValid = disabled |
186 | */ | 249 | */ |
187 | INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID1, 0x00), | 250 | INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID1, 0xa0, 0x00), |
188 | /* | 251 | /* |
189 | * Vaux2SwHPReqValid = disabled | 252 | * Vaux2SwHPReqValid = disabled |
190 | * Vaux3SwHPReqValid = disabled | 253 | * Vaux3SwHPReqValid = disabled |
@@ -192,7 +255,7 @@ ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { | |||
192 | * VextSupply2SwHPReqValid = disabled | 255 | * VextSupply2SwHPReqValid = disabled |
193 | * VextSupply3SwHPReqValid = disabled | 256 | * VextSupply3SwHPReqValid = disabled |
194 | */ | 257 | */ |
195 | INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID2, 0x00), | 258 | INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID2, 0x1f, 0x00), |
196 | /* | 259 | /* |
197 | * SysClkReq2Valid1 = SysClkReq2 controlled | 260 | * SysClkReq2Valid1 = SysClkReq2 controlled |
198 | * SysClkReq3Valid1 = disabled | 261 | * SysClkReq3Valid1 = disabled |
@@ -202,7 +265,7 @@ ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { | |||
202 | * SysClkReq7Valid1 = disabled | 265 | * SysClkReq7Valid1 = disabled |
203 | * SysClkReq8Valid1 = disabled | 266 | * SysClkReq8Valid1 = disabled |
204 | */ | 267 | */ |
205 | INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID1, 0x2a), | 268 | INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID1, 0xfe, 0x2a), |
206 | /* | 269 | /* |
207 | * SysClkReq2Valid2 = disabled | 270 | * SysClkReq2Valid2 = disabled |
208 | * SysClkReq3Valid2 = disabled | 271 | * SysClkReq3Valid2 = disabled |
@@ -212,7 +275,7 @@ ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { | |||
212 | * SysClkReq7Valid2 = disabled | 275 | * SysClkReq7Valid2 = disabled |
213 | * SysClkReq8Valid2 = disabled | 276 | * SysClkReq8Valid2 = disabled |
214 | */ | 277 | */ |
215 | INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID2, 0x20), | 278 | INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID2, 0xfe, 0x20), |
216 | /* | 279 | /* |
217 | * VTVoutEna = disabled | 280 | * VTVoutEna = disabled |
218 | * Vintcore12Ena = disabled | 281 | * Vintcore12Ena = disabled |
@@ -220,66 +283,62 @@ ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { | |||
220 | * Vintcore12LP = inactive (HP) | 283 | * Vintcore12LP = inactive (HP) |
221 | * VTVoutLP = inactive (HP) | 284 | * VTVoutLP = inactive (HP) |
222 | */ | 285 | */ |
223 | INIT_REGULATOR_REGISTER(AB8500_REGUMISC1, 0x10), | 286 | INIT_REGULATOR_REGISTER(AB8500_REGUMISC1, 0xfe, 0x10), |
224 | /* | 287 | /* |
225 | * VaudioEna = disabled | 288 | * VaudioEna = disabled |
226 | * VdmicEna = disabled | 289 | * VdmicEna = disabled |
227 | * Vamic1Ena = disabled | 290 | * Vamic1Ena = disabled |
228 | * Vamic2Ena = disabled | 291 | * Vamic2Ena = disabled |
229 | */ | 292 | */ |
230 | INIT_REGULATOR_REGISTER(AB8500_VAUDIOSUPPLY, 0x00), | 293 | INIT_REGULATOR_REGISTER(AB8500_VAUDIOSUPPLY, 0x1e, 0x00), |
231 | /* | 294 | /* |
232 | * Vamic1_dzout = high-Z when Vamic1 is disabled | 295 | * Vamic1_dzout = high-Z when Vamic1 is disabled |
233 | * Vamic2_dzout = high-Z when Vamic2 is disabled | 296 | * Vamic2_dzout = high-Z when Vamic2 is disabled |
234 | */ | 297 | */ |
235 | INIT_REGULATOR_REGISTER(AB8500_REGUCTRL1VAMIC, 0x00), | 298 | INIT_REGULATOR_REGISTER(AB8500_REGUCTRL1VAMIC, 0x03, 0x00), |
236 | /* | 299 | /* |
237 | * VPll = Hw controlled | 300 | * VPll = Hw controlled (NOTE! PRCMU bits) |
238 | * VanaRegu = force off | 301 | * VanaRegu = force off |
239 | */ | 302 | */ |
240 | INIT_REGULATOR_REGISTER(AB8500_VPLLVANAREGU, 0x02), | 303 | INIT_REGULATOR_REGISTER(AB8500_VPLLVANAREGU, 0x0f, 0x02), |
241 | /* | 304 | /* |
242 | * VrefDDREna = disabled | 305 | * VrefDDREna = disabled |
243 | * VrefDDRSleepMode = inactive (no pulldown) | 306 | * VrefDDRSleepMode = inactive (no pulldown) |
244 | */ | 307 | */ |
245 | INIT_REGULATOR_REGISTER(AB8500_VREFDDR, 0x00), | 308 | INIT_REGULATOR_REGISTER(AB8500_VREFDDR, 0x03, 0x00), |
246 | /* | 309 | /* |
247 | * VextSupply1Regu = HW control | 310 | * VextSupply1Regu = force LP |
248 | * VextSupply2Regu = HW control | 311 | * VextSupply2Regu = force OFF |
249 | * VextSupply3Regu = HW control | 312 | * VextSupply3Regu = force HP (-> STBB2=LP and TPS=LP) |
250 | * ExtSupply2Bypass = ExtSupply12LPn ball is 0 when Ena is 0 | 313 | * ExtSupply2Bypass = ExtSupply12LPn ball is 0 when Ena is 0 |
251 | * ExtSupply3Bypass = ExtSupply3LPn ball is 0 when Ena is 0 | 314 | * ExtSupply3Bypass = ExtSupply3LPn ball is 0 when Ena is 0 |
252 | */ | 315 | */ |
253 | INIT_REGULATOR_REGISTER(AB8500_EXTSUPPLYREGU, 0x2a), | 316 | INIT_REGULATOR_REGISTER(AB8500_EXTSUPPLYREGU, 0xff, 0x13), |
254 | /* | 317 | /* |
255 | * Vaux1Regu = force HP | 318 | * Vaux1Regu = force HP |
256 | * Vaux2Regu = force off | 319 | * Vaux2Regu = force off |
257 | */ | 320 | */ |
258 | INIT_REGULATOR_REGISTER(AB8500_VAUX12REGU, 0x01), | 321 | INIT_REGULATOR_REGISTER(AB8500_VAUX12REGU, 0x0f, 0x01), |
259 | /* | 322 | /* |
260 | * Vaux3regu = force off | 323 | * Vaux3Regu = force off |
261 | */ | 324 | */ |
262 | INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3REGU, 0x00), | 325 | INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3REGU, 0x03, 0x00), |
263 | /* | 326 | /* |
264 | * Vsmps1 = 1.15V | 327 | * Vaux1Sel = 2.8 V |
265 | */ | 328 | */ |
266 | INIT_REGULATOR_REGISTER(AB8500_VSMPS1SEL1, 0x24), | 329 | INIT_REGULATOR_REGISTER(AB8500_VAUX1SEL, 0x0f, 0x0C), |
267 | /* | ||
268 | * Vaux1Sel = 2.5 V | ||
269 | */ | ||
270 | INIT_REGULATOR_REGISTER(AB8500_VAUX1SEL, 0x08), | ||
271 | /* | 330 | /* |
272 | * Vaux2Sel = 2.9 V | 331 | * Vaux2Sel = 2.9 V |
273 | */ | 332 | */ |
274 | INIT_REGULATOR_REGISTER(AB8500_VAUX2SEL, 0x0d), | 333 | INIT_REGULATOR_REGISTER(AB8500_VAUX2SEL, 0x0f, 0x0d), |
275 | /* | 334 | /* |
276 | * Vaux3Sel = 2.91 V | 335 | * Vaux3Sel = 2.91 V |
277 | */ | 336 | */ |
278 | INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3SEL, 0x07), | 337 | INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3SEL, 0x07, 0x07), |
279 | /* | 338 | /* |
280 | * VextSupply12LP = disabled (no LP) | 339 | * VextSupply12LP = disabled (no LP) |
281 | */ | 340 | */ |
282 | INIT_REGULATOR_REGISTER(AB8500_REGUCTRL2SPARE, 0x00), | 341 | INIT_REGULATOR_REGISTER(AB8500_REGUCTRL2SPARE, 0x01, 0x00), |
283 | /* | 342 | /* |
284 | * Vaux1Disch = short discharge time | 343 | * Vaux1Disch = short discharge time |
285 | * Vaux2Disch = short discharge time | 344 | * Vaux2Disch = short discharge time |
@@ -288,33 +347,26 @@ ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = { | |||
288 | * VTVoutDisch = short discharge time | 347 | * VTVoutDisch = short discharge time |
289 | * VaudioDisch = short discharge time | 348 | * VaudioDisch = short discharge time |
290 | */ | 349 | */ |
291 | INIT_REGULATOR_REGISTER(AB8500_REGUCTRLDISCH, 0x00), | 350 | INIT_REGULATOR_REGISTER(AB8500_REGUCTRLDISCH, 0xfc, 0x00), |
292 | /* | 351 | /* |
293 | * VanaDisch = short discharge time | 352 | * VanaDisch = short discharge time |
294 | * VdmicPullDownEna = pulldown disabled when Vdmic is disabled | 353 | * VdmicPullDownEna = pulldown disabled when Vdmic is disabled |
295 | * VdmicDisch = short discharge time | 354 | * VdmicDisch = short discharge time |
296 | */ | 355 | */ |
297 | INIT_REGULATOR_REGISTER(AB8500_REGUCTRLDISCH2, 0x00), | 356 | INIT_REGULATOR_REGISTER(AB8500_REGUCTRLDISCH2, 0x16, 0x00), |
298 | }; | 357 | }; |
299 | 358 | ||
300 | /* AB8500 regulators */ | 359 | /* AB8500 regulators */ |
301 | struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { | 360 | static struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { |
302 | /* supplies to the display/camera */ | 361 | /* supplies to the display/camera */ |
303 | [AB8500_LDO_AUX1] = { | 362 | [AB8500_LDO_AUX1] = { |
304 | .constraints = { | 363 | .constraints = { |
305 | .name = "V-DISPLAY", | 364 | .name = "V-DISPLAY", |
306 | .min_uV = 2500000, | 365 | .min_uV = 2800000, |
307 | .max_uV = 2900000, | 366 | .max_uV = 3300000, |
308 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | 367 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | |
309 | REGULATOR_CHANGE_STATUS, | 368 | REGULATOR_CHANGE_STATUS, |
310 | .boot_on = 1, /* display is on at boot */ | 369 | .boot_on = 1, /* display is on at boot */ |
311 | /* | ||
312 | * This voltage cannot be disabled right now because | ||
313 | * it is somehow affecting the external MMC | ||
314 | * functionality, though that typically will use | ||
315 | * AUX3. | ||
316 | */ | ||
317 | .always_on = 1, | ||
318 | }, | 370 | }, |
319 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux1_consumers), | 371 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux1_consumers), |
320 | .consumer_supplies = ab8500_vaux1_consumers, | 372 | .consumer_supplies = ab8500_vaux1_consumers, |
@@ -326,7 +378,10 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { | |||
326 | .min_uV = 1100000, | 378 | .min_uV = 1100000, |
327 | .max_uV = 3300000, | 379 | .max_uV = 3300000, |
328 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | 380 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | |
329 | REGULATOR_CHANGE_STATUS, | 381 | REGULATOR_CHANGE_STATUS | |
382 | REGULATOR_CHANGE_MODE, | ||
383 | .valid_modes_mask = REGULATOR_MODE_NORMAL | | ||
384 | REGULATOR_MODE_IDLE, | ||
330 | }, | 385 | }, |
331 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux2_consumers), | 386 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux2_consumers), |
332 | .consumer_supplies = ab8500_vaux2_consumers, | 387 | .consumer_supplies = ab8500_vaux2_consumers, |
@@ -338,7 +393,10 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { | |||
338 | .min_uV = 1100000, | 393 | .min_uV = 1100000, |
339 | .max_uV = 3300000, | 394 | .max_uV = 3300000, |
340 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | 395 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | |
341 | REGULATOR_CHANGE_STATUS, | 396 | REGULATOR_CHANGE_STATUS | |
397 | REGULATOR_CHANGE_MODE, | ||
398 | .valid_modes_mask = REGULATOR_MODE_NORMAL | | ||
399 | REGULATOR_MODE_IDLE, | ||
342 | }, | 400 | }, |
343 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux3_consumers), | 401 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux3_consumers), |
344 | .consumer_supplies = ab8500_vaux3_consumers, | 402 | .consumer_supplies = ab8500_vaux3_consumers, |
@@ -392,18 +450,614 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = { | |||
392 | [AB8500_LDO_INTCORE] = { | 450 | [AB8500_LDO_INTCORE] = { |
393 | .constraints = { | 451 | .constraints = { |
394 | .name = "V-INTCORE", | 452 | .name = "V-INTCORE", |
395 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | 453 | .min_uV = 1250000, |
454 | .max_uV = 1350000, | ||
455 | .input_uV = 1800000, | ||
456 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | ||
457 | REGULATOR_CHANGE_STATUS | | ||
458 | REGULATOR_CHANGE_MODE | | ||
459 | REGULATOR_CHANGE_DRMS, | ||
460 | .valid_modes_mask = REGULATOR_MODE_NORMAL | | ||
461 | REGULATOR_MODE_IDLE, | ||
396 | }, | 462 | }, |
397 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vintcore_consumers), | 463 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vintcore_consumers), |
398 | .consumer_supplies = ab8500_vintcore_consumers, | 464 | .consumer_supplies = ab8500_vintcore_consumers, |
399 | }, | 465 | }, |
400 | /* supply for U8500 CSI/DSI, VANA LDO */ | 466 | /* supply for U8500 CSI-DSI, VANA LDO */ |
401 | [AB8500_LDO_ANA] = { | 467 | [AB8500_LDO_ANA] = { |
402 | .constraints = { | 468 | .constraints = { |
403 | .name = "V-CSI/DSI", | 469 | .name = "V-CSI-DSI", |
404 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | 470 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
405 | }, | 471 | }, |
406 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vana_consumers), | 472 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vana_consumers), |
407 | .consumer_supplies = ab8500_vana_consumers, | 473 | .consumer_supplies = ab8500_vana_consumers, |
408 | }, | 474 | }, |
409 | }; | 475 | }; |
476 | |||
477 | /* supply for VextSupply3 */ | ||
478 | static struct regulator_consumer_supply ab8500_ext_supply3_consumers[] = { | ||
479 | /* SIM supply for 3 V SIM cards */ | ||
480 | REGULATOR_SUPPLY("vinvsim", "sim-detect.0"), | ||
481 | }; | ||
482 | |||
483 | /* extended configuration for VextSupply2, only used for HREFP_V20 boards */ | ||
484 | static struct ab8500_ext_regulator_cfg ab8500_ext_supply2 = { | ||
485 | .hwreq = true, | ||
486 | }; | ||
487 | |||
488 | /* | ||
489 | * AB8500 external regulators | ||
490 | */ | ||
491 | static struct regulator_init_data ab8500_ext_regulators[] = { | ||
492 | /* fixed Vbat supplies VSMPS1_EXT_1V8 */ | ||
493 | [AB8500_EXT_SUPPLY1] = { | ||
494 | .constraints = { | ||
495 | .name = "ab8500-ext-supply1", | ||
496 | .min_uV = 1800000, | ||
497 | .max_uV = 1800000, | ||
498 | .initial_mode = REGULATOR_MODE_IDLE, | ||
499 | .boot_on = 1, | ||
500 | .always_on = 1, | ||
501 | }, | ||
502 | }, | ||
503 | /* fixed Vbat supplies VSMPS2_EXT_1V36 and VSMPS5_EXT_1V15 */ | ||
504 | [AB8500_EXT_SUPPLY2] = { | ||
505 | .constraints = { | ||
506 | .name = "ab8500-ext-supply2", | ||
507 | .min_uV = 1360000, | ||
508 | .max_uV = 1360000, | ||
509 | }, | ||
510 | }, | ||
511 | /* fixed Vbat supplies VSMPS3_EXT_3V4 and VSMPS4_EXT_3V4 */ | ||
512 | [AB8500_EXT_SUPPLY3] = { | ||
513 | .constraints = { | ||
514 | .name = "ab8500-ext-supply3", | ||
515 | .min_uV = 3400000, | ||
516 | .max_uV = 3400000, | ||
517 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
518 | .boot_on = 1, | ||
519 | }, | ||
520 | .num_consumer_supplies = | ||
521 | ARRAY_SIZE(ab8500_ext_supply3_consumers), | ||
522 | .consumer_supplies = ab8500_ext_supply3_consumers, | ||
523 | }, | ||
524 | }; | ||
525 | |||
526 | /* ab8505 regulator register initialization */ | ||
527 | static struct ab8500_regulator_reg_init ab8505_reg_init[] = { | ||
528 | /* | ||
529 | * VarmRequestCtrl | ||
530 | * VsmpsCRequestCtrl | ||
531 | * VsmpsARequestCtrl | ||
532 | * VsmpsBRequestCtrl | ||
533 | */ | ||
534 | INIT_REGULATOR_REGISTER(AB8505_REGUREQUESTCTRL1, 0x00, 0x00), | ||
535 | /* | ||
536 | * VsafeRequestCtrl | ||
537 | * VpllRequestCtrl | ||
538 | * VanaRequestCtrl = HP/LP depending on VxRequest | ||
539 | */ | ||
540 | INIT_REGULATOR_REGISTER(AB8505_REGUREQUESTCTRL2, 0x30, 0x00), | ||
541 | /* | ||
542 | * Vaux1RequestCtrl = HP/LP depending on VxRequest | ||
543 | * Vaux2RequestCtrl = HP/LP depending on VxRequest | ||
544 | */ | ||
545 | INIT_REGULATOR_REGISTER(AB8505_REGUREQUESTCTRL3, 0xf0, 0x00), | ||
546 | /* | ||
547 | * Vaux3RequestCtrl = HP/LP depending on VxRequest | ||
548 | * SwHPReq = Control through SWValid disabled | ||
549 | */ | ||
550 | INIT_REGULATOR_REGISTER(AB8505_REGUREQUESTCTRL4, 0x07, 0x00), | ||
551 | /* | ||
552 | * VsmpsASysClkReq1HPValid | ||
553 | * VsmpsBSysClkReq1HPValid | ||
554 | * VsafeSysClkReq1HPValid | ||
555 | * VanaSysClkReq1HPValid = disabled | ||
556 | * VpllSysClkReq1HPValid | ||
557 | * Vaux1SysClkReq1HPValid = disabled | ||
558 | * Vaux2SysClkReq1HPValid = disabled | ||
559 | * Vaux3SysClkReq1HPValid = disabled | ||
560 | */ | ||
561 | INIT_REGULATOR_REGISTER(AB8505_REGUSYSCLKREQ1HPVALID1, 0xe8, 0x00), | ||
562 | /* | ||
563 | * VsmpsCSysClkReq1HPValid | ||
564 | * VarmSysClkReq1HPValid | ||
565 | * VbbSysClkReq1HPValid | ||
566 | * VsmpsMSysClkReq1HPValid | ||
567 | */ | ||
568 | INIT_REGULATOR_REGISTER(AB8505_REGUSYSCLKREQ1HPVALID2, 0x00, 0x00), | ||
569 | /* | ||
570 | * VsmpsAHwHPReq1Valid | ||
571 | * VsmpsBHwHPReq1Valid | ||
572 | * VsafeHwHPReq1Valid | ||
573 | * VanaHwHPReq1Valid = disabled | ||
574 | * VpllHwHPReq1Valid | ||
575 | * Vaux1HwHPreq1Valid = disabled | ||
576 | * Vaux2HwHPReq1Valid = disabled | ||
577 | * Vaux3HwHPReqValid = disabled | ||
578 | */ | ||
579 | INIT_REGULATOR_REGISTER(AB8505_REGUHWHPREQ1VALID1, 0xe8, 0x00), | ||
580 | /* | ||
581 | * VsmpsMHwHPReq1Valid | ||
582 | */ | ||
583 | INIT_REGULATOR_REGISTER(AB8505_REGUHWHPREQ1VALID2, 0x00, 0x00), | ||
584 | /* | ||
585 | * VsmpsAHwHPReq2Valid | ||
586 | * VsmpsBHwHPReq2Valid | ||
587 | * VsafeHwHPReq2Valid | ||
588 | * VanaHwHPReq2Valid = disabled | ||
589 | * VpllHwHPReq2Valid | ||
590 | * Vaux1HwHPReq2Valid = disabled | ||
591 | * Vaux2HwHPReq2Valid = disabled | ||
592 | * Vaux3HwHPReq2Valid = disabled | ||
593 | */ | ||
594 | INIT_REGULATOR_REGISTER(AB8505_REGUHWHPREQ2VALID1, 0xe8, 0x00), | ||
595 | /* | ||
596 | * VsmpsMHwHPReq2Valid | ||
597 | */ | ||
598 | INIT_REGULATOR_REGISTER(AB8505_REGUHWHPREQ2VALID2, 0x00, 0x00), | ||
599 | /** | ||
600 | * VsmpsCSwHPReqValid | ||
601 | * VarmSwHPReqValid | ||
602 | * VsmpsASwHPReqValid | ||
603 | * VsmpsBSwHPReqValid | ||
604 | * VsafeSwHPReqValid | ||
605 | * VanaSwHPReqValid | ||
606 | * VanaSwHPReqValid = disabled | ||
607 | * VpllSwHPReqValid | ||
608 | * Vaux1SwHPReqValid = disabled | ||
609 | */ | ||
610 | INIT_REGULATOR_REGISTER(AB8505_REGUSWHPREQVALID1, 0xa0, 0x00), | ||
611 | /* | ||
612 | * Vaux2SwHPReqValid = disabled | ||
613 | * Vaux3SwHPReqValid = disabled | ||
614 | * VsmpsMSwHPReqValid | ||
615 | */ | ||
616 | INIT_REGULATOR_REGISTER(AB8505_REGUSWHPREQVALID2, 0x03, 0x00), | ||
617 | /* | ||
618 | * SysClkReq2Valid1 = SysClkReq2 controlled | ||
619 | * SysClkReq3Valid1 = disabled | ||
620 | * SysClkReq4Valid1 = SysClkReq4 controlled | ||
621 | */ | ||
622 | INIT_REGULATOR_REGISTER(AB8505_REGUSYSCLKREQVALID1, 0x0e, 0x0a), | ||
623 | /* | ||
624 | * SysClkReq2Valid2 = disabled | ||
625 | * SysClkReq3Valid2 = disabled | ||
626 | * SysClkReq4Valid2 = disabled | ||
627 | */ | ||
628 | INIT_REGULATOR_REGISTER(AB8505_REGUSYSCLKREQVALID2, 0x0e, 0x00), | ||
629 | /* | ||
630 | * Vaux4SwHPReqValid | ||
631 | * Vaux4HwHPReq2Valid | ||
632 | * Vaux4HwHPReq1Valid | ||
633 | * Vaux4SysClkReq1HPValid | ||
634 | */ | ||
635 | INIT_REGULATOR_REGISTER(AB8505_REGUVAUX4REQVALID, 0x00, 0x00), | ||
636 | /* | ||
637 | * VadcEna = disabled | ||
638 | * VintCore12Ena = disabled | ||
639 | * VintCore12Sel = 1.25 V | ||
640 | * VintCore12LP = inactive (HP) | ||
641 | * VadcLP = inactive (HP) | ||
642 | */ | ||
643 | INIT_REGULATOR_REGISTER(AB8505_REGUMISC1, 0xfe, 0x10), | ||
644 | /* | ||
645 | * VaudioEna = disabled | ||
646 | * Vaux8Ena = disabled | ||
647 | * Vamic1Ena = disabled | ||
648 | * Vamic2Ena = disabled | ||
649 | */ | ||
650 | INIT_REGULATOR_REGISTER(AB8505_VAUDIOSUPPLY, 0x1e, 0x00), | ||
651 | /* | ||
652 | * Vamic1_dzout = high-Z when Vamic1 is disabled | ||
653 | * Vamic2_dzout = high-Z when Vamic2 is disabled | ||
654 | */ | ||
655 | INIT_REGULATOR_REGISTER(AB8505_REGUCTRL1VAMIC, 0x03, 0x00), | ||
656 | /* | ||
657 | * VsmpsARegu | ||
658 | * VsmpsASelCtrl | ||
659 | * VsmpsAAutoMode | ||
660 | * VsmpsAPWMMode | ||
661 | */ | ||
662 | INIT_REGULATOR_REGISTER(AB8505_VSMPSAREGU, 0x00, 0x00), | ||
663 | /* | ||
664 | * VsmpsBRegu | ||
665 | * VsmpsBSelCtrl | ||
666 | * VsmpsBAutoMode | ||
667 | * VsmpsBPWMMode | ||
668 | */ | ||
669 | INIT_REGULATOR_REGISTER(AB8505_VSMPSBREGU, 0x00, 0x00), | ||
670 | /* | ||
671 | * VsafeRegu | ||
672 | * VsafeSelCtrl | ||
673 | * VsafeAutoMode | ||
674 | * VsafePWMMode | ||
675 | */ | ||
676 | INIT_REGULATOR_REGISTER(AB8505_VSAFEREGU, 0x00, 0x00), | ||
677 | /* | ||
678 | * VPll = Hw controlled (NOTE! PRCMU bits) | ||
679 | * VanaRegu = force off | ||
680 | */ | ||
681 | INIT_REGULATOR_REGISTER(AB8505_VPLLVANAREGU, 0x0f, 0x02), | ||
682 | /* | ||
683 | * VextSupply1Regu = force OFF (OTP_ExtSupply12LPnPolarity 1) | ||
684 | * VextSupply2Regu = force OFF (OTP_ExtSupply12LPnPolarity 1) | ||
685 | * VextSupply3Regu = force OFF (OTP_ExtSupply3LPnPolarity 0) | ||
686 | * ExtSupply2Bypass = ExtSupply12LPn ball is 0 when Ena is 0 | ||
687 | * ExtSupply3Bypass = ExtSupply3LPn ball is 0 when Ena is 0 | ||
688 | */ | ||
689 | INIT_REGULATOR_REGISTER(AB8505_EXTSUPPLYREGU, 0xff, 0x30), | ||
690 | /* | ||
691 | * Vaux1Regu = force HP | ||
692 | * Vaux2Regu = force off | ||
693 | */ | ||
694 | INIT_REGULATOR_REGISTER(AB8505_VAUX12REGU, 0x0f, 0x01), | ||
695 | /* | ||
696 | * Vaux3Regu = force off | ||
697 | */ | ||
698 | INIT_REGULATOR_REGISTER(AB8505_VRF1VAUX3REGU, 0x03, 0x00), | ||
699 | /* | ||
700 | * VsmpsASel1 | ||
701 | */ | ||
702 | INIT_REGULATOR_REGISTER(AB8505_VSMPSASEL1, 0x00, 0x00), | ||
703 | /* | ||
704 | * VsmpsASel2 | ||
705 | */ | ||
706 | INIT_REGULATOR_REGISTER(AB8505_VSMPSASEL2, 0x00, 0x00), | ||
707 | /* | ||
708 | * VsmpsASel3 | ||
709 | */ | ||
710 | INIT_REGULATOR_REGISTER(AB8505_VSMPSASEL3, 0x00, 0x00), | ||
711 | /* | ||
712 | * VsmpsBSel1 | ||
713 | */ | ||
714 | INIT_REGULATOR_REGISTER(AB8505_VSMPSBSEL1, 0x00, 0x00), | ||
715 | /* | ||
716 | * VsmpsBSel2 | ||
717 | */ | ||
718 | INIT_REGULATOR_REGISTER(AB8505_VSMPSBSEL2, 0x00, 0x00), | ||
719 | /* | ||
720 | * VsmpsBSel3 | ||
721 | */ | ||
722 | INIT_REGULATOR_REGISTER(AB8505_VSMPSBSEL3, 0x00, 0x00), | ||
723 | /* | ||
724 | * VsafeSel1 | ||
725 | */ | ||
726 | INIT_REGULATOR_REGISTER(AB8505_VSAFESEL1, 0x00, 0x00), | ||
727 | /* | ||
728 | * VsafeSel2 | ||
729 | */ | ||
730 | INIT_REGULATOR_REGISTER(AB8505_VSAFESEL2, 0x00, 0x00), | ||
731 | /* | ||
732 | * VsafeSel3 | ||
733 | */ | ||
734 | INIT_REGULATOR_REGISTER(AB8505_VSAFESEL3, 0x00, 0x00), | ||
735 | /* | ||
736 | * Vaux1Sel = 2.8 V | ||
737 | */ | ||
738 | INIT_REGULATOR_REGISTER(AB8505_VAUX1SEL, 0x0f, 0x0C), | ||
739 | /* | ||
740 | * Vaux2Sel = 2.9 V | ||
741 | */ | ||
742 | INIT_REGULATOR_REGISTER(AB8505_VAUX2SEL, 0x0f, 0x0d), | ||
743 | /* | ||
744 | * Vaux3Sel = 2.91 V | ||
745 | */ | ||
746 | INIT_REGULATOR_REGISTER(AB8505_VRF1VAUX3SEL, 0x07, 0x07), | ||
747 | /* | ||
748 | * Vaux4RequestCtrl | ||
749 | */ | ||
750 | INIT_REGULATOR_REGISTER(AB8505_VAUX4REQCTRL, 0x00, 0x00), | ||
751 | /* | ||
752 | * Vaux4Regu | ||
753 | */ | ||
754 | INIT_REGULATOR_REGISTER(AB8505_VAUX4REGU, 0x00, 0x00), | ||
755 | /* | ||
756 | * Vaux4Sel | ||
757 | */ | ||
758 | INIT_REGULATOR_REGISTER(AB8505_VAUX4SEL, 0x00, 0x00), | ||
759 | /* | ||
760 | * Vaux1Disch = short discharge time | ||
761 | * Vaux2Disch = short discharge time | ||
762 | * Vaux3Disch = short discharge time | ||
763 | * Vintcore12Disch = short discharge time | ||
764 | * VTVoutDisch = short discharge time | ||
765 | * VaudioDisch = short discharge time | ||
766 | */ | ||
767 | INIT_REGULATOR_REGISTER(AB8505_REGUCTRLDISCH, 0xfc, 0x00), | ||
768 | /* | ||
769 | * VanaDisch = short discharge time | ||
770 | * Vaux8PullDownEna = pulldown disabled when Vaux8 is disabled | ||
771 | * Vaux8Disch = short discharge time | ||
772 | */ | ||
773 | INIT_REGULATOR_REGISTER(AB8505_REGUCTRLDISCH2, 0x16, 0x00), | ||
774 | /* | ||
775 | * Vaux4Disch = short discharge time | ||
776 | */ | ||
777 | INIT_REGULATOR_REGISTER(AB8505_REGUCTRLDISCH3, 0x01, 0x00), | ||
778 | /* | ||
779 | * Vaux5Sel | ||
780 | * Vaux5LP | ||
781 | * Vaux5Ena | ||
782 | * Vaux5Disch | ||
783 | * Vaux5DisSfst | ||
784 | * Vaux5DisPulld | ||
785 | */ | ||
786 | INIT_REGULATOR_REGISTER(AB8505_CTRLVAUX5, 0x00, 0x00), | ||
787 | /* | ||
788 | * Vaux6Sel | ||
789 | * Vaux6LP | ||
790 | * Vaux6Ena | ||
791 | * Vaux6DisPulld | ||
792 | */ | ||
793 | INIT_REGULATOR_REGISTER(AB8505_CTRLVAUX6, 0x00, 0x00), | ||
794 | }; | ||
795 | |||
796 | struct regulator_init_data ab8505_regulators[AB8505_NUM_REGULATORS] = { | ||
797 | /* supplies to the display/camera */ | ||
798 | [AB8505_LDO_AUX1] = { | ||
799 | .constraints = { | ||
800 | .name = "V-DISPLAY", | ||
801 | .min_uV = 2800000, | ||
802 | .max_uV = 3300000, | ||
803 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | ||
804 | REGULATOR_CHANGE_STATUS, | ||
805 | .boot_on = 1, /* display is on at boot */ | ||
806 | }, | ||
807 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux1_consumers), | ||
808 | .consumer_supplies = ab8500_vaux1_consumers, | ||
809 | }, | ||
810 | /* supplies to the on-board eMMC */ | ||
811 | [AB8505_LDO_AUX2] = { | ||
812 | .constraints = { | ||
813 | .name = "V-eMMC1", | ||
814 | .min_uV = 1100000, | ||
815 | .max_uV = 3300000, | ||
816 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | ||
817 | REGULATOR_CHANGE_STATUS | | ||
818 | REGULATOR_CHANGE_MODE, | ||
819 | .valid_modes_mask = REGULATOR_MODE_NORMAL | | ||
820 | REGULATOR_MODE_IDLE, | ||
821 | }, | ||
822 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux2_consumers), | ||
823 | .consumer_supplies = ab8500_vaux2_consumers, | ||
824 | }, | ||
825 | /* supply for VAUX3, supplies to SDcard slots */ | ||
826 | [AB8505_LDO_AUX3] = { | ||
827 | .constraints = { | ||
828 | .name = "V-MMC-SD", | ||
829 | .min_uV = 1100000, | ||
830 | .max_uV = 3300000, | ||
831 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | ||
832 | REGULATOR_CHANGE_STATUS | | ||
833 | REGULATOR_CHANGE_MODE, | ||
834 | .valid_modes_mask = REGULATOR_MODE_NORMAL | | ||
835 | REGULATOR_MODE_IDLE, | ||
836 | }, | ||
837 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vaux3_consumers), | ||
838 | .consumer_supplies = ab8500_vaux3_consumers, | ||
839 | }, | ||
840 | /* supply for VAUX4, supplies to NFC and standalone secure element */ | ||
841 | [AB8505_LDO_AUX4] = { | ||
842 | .constraints = { | ||
843 | .name = "V-NFC-SE", | ||
844 | .min_uV = 1100000, | ||
845 | .max_uV = 3300000, | ||
846 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | ||
847 | REGULATOR_CHANGE_STATUS | | ||
848 | REGULATOR_CHANGE_MODE, | ||
849 | .valid_modes_mask = REGULATOR_MODE_NORMAL | | ||
850 | REGULATOR_MODE_IDLE, | ||
851 | }, | ||
852 | .num_consumer_supplies = ARRAY_SIZE(ab8505_vaux4_consumers), | ||
853 | .consumer_supplies = ab8505_vaux4_consumers, | ||
854 | }, | ||
855 | /* supply for VAUX5, supplies to TBD */ | ||
856 | [AB8505_LDO_AUX5] = { | ||
857 | .constraints = { | ||
858 | .name = "V-AUX5", | ||
859 | .min_uV = 1050000, | ||
860 | .max_uV = 2790000, | ||
861 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | ||
862 | REGULATOR_CHANGE_STATUS | | ||
863 | REGULATOR_CHANGE_MODE, | ||
864 | .valid_modes_mask = REGULATOR_MODE_NORMAL | | ||
865 | REGULATOR_MODE_IDLE, | ||
866 | }, | ||
867 | .num_consumer_supplies = ARRAY_SIZE(ab8505_vaux5_consumers), | ||
868 | .consumer_supplies = ab8505_vaux5_consumers, | ||
869 | }, | ||
870 | /* supply for VAUX6, supplies to TBD */ | ||
871 | [AB8505_LDO_AUX6] = { | ||
872 | .constraints = { | ||
873 | .name = "V-AUX6", | ||
874 | .min_uV = 1050000, | ||
875 | .max_uV = 2790000, | ||
876 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | ||
877 | REGULATOR_CHANGE_STATUS | | ||
878 | REGULATOR_CHANGE_MODE, | ||
879 | .valid_modes_mask = REGULATOR_MODE_NORMAL | | ||
880 | REGULATOR_MODE_IDLE, | ||
881 | }, | ||
882 | .num_consumer_supplies = ARRAY_SIZE(ab8505_vaux6_consumers), | ||
883 | .consumer_supplies = ab8505_vaux6_consumers, | ||
884 | }, | ||
885 | /* supply for gpadc, ADC LDO */ | ||
886 | [AB8505_LDO_ADC] = { | ||
887 | .constraints = { | ||
888 | .name = "V-ADC", | ||
889 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
890 | }, | ||
891 | .num_consumer_supplies = ARRAY_SIZE(ab8505_vadc_consumers), | ||
892 | .consumer_supplies = ab8505_vadc_consumers, | ||
893 | }, | ||
894 | /* supply for ab8500-vaudio, VAUDIO LDO */ | ||
895 | [AB8505_LDO_AUDIO] = { | ||
896 | .constraints = { | ||
897 | .name = "V-AUD", | ||
898 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
899 | }, | ||
900 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vaud_consumers), | ||
901 | .consumer_supplies = ab8500_vaud_consumers, | ||
902 | }, | ||
903 | /* supply for v-anamic1 VAMic1-LDO */ | ||
904 | [AB8505_LDO_ANAMIC1] = { | ||
905 | .constraints = { | ||
906 | .name = "V-AMIC1", | ||
907 | .valid_ops_mask = REGULATOR_CHANGE_STATUS | | ||
908 | REGULATOR_CHANGE_MODE, | ||
909 | .valid_modes_mask = REGULATOR_MODE_NORMAL | | ||
910 | REGULATOR_MODE_IDLE, | ||
911 | }, | ||
912 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vamic1_consumers), | ||
913 | .consumer_supplies = ab8500_vamic1_consumers, | ||
914 | }, | ||
915 | /* supply for v-amic2, VAMIC2 LDO, reuse constants for AMIC1 */ | ||
916 | [AB8505_LDO_ANAMIC2] = { | ||
917 | .constraints = { | ||
918 | .name = "V-AMIC2", | ||
919 | .valid_ops_mask = REGULATOR_CHANGE_STATUS | | ||
920 | REGULATOR_CHANGE_MODE, | ||
921 | .valid_modes_mask = REGULATOR_MODE_NORMAL | | ||
922 | REGULATOR_MODE_IDLE, | ||
923 | }, | ||
924 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vamic2_consumers), | ||
925 | .consumer_supplies = ab8500_vamic2_consumers, | ||
926 | }, | ||
927 | /* supply for v-aux8, VAUX8 LDO */ | ||
928 | [AB8505_LDO_AUX8] = { | ||
929 | .constraints = { | ||
930 | .name = "V-AUX8", | ||
931 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
932 | }, | ||
933 | .num_consumer_supplies = ARRAY_SIZE(ab8505_vaux8_consumers), | ||
934 | .consumer_supplies = ab8505_vaux8_consumers, | ||
935 | }, | ||
936 | /* supply for v-intcore12, VINTCORE12 LDO */ | ||
937 | [AB8505_LDO_INTCORE] = { | ||
938 | .constraints = { | ||
939 | .name = "V-INTCORE", | ||
940 | .min_uV = 1250000, | ||
941 | .max_uV = 1350000, | ||
942 | .input_uV = 1800000, | ||
943 | .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | | ||
944 | REGULATOR_CHANGE_STATUS | | ||
945 | REGULATOR_CHANGE_MODE | | ||
946 | REGULATOR_CHANGE_DRMS, | ||
947 | .valid_modes_mask = REGULATOR_MODE_NORMAL | | ||
948 | REGULATOR_MODE_IDLE, | ||
949 | }, | ||
950 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vintcore_consumers), | ||
951 | .consumer_supplies = ab8500_vintcore_consumers, | ||
952 | }, | ||
953 | /* supply for LDO USB */ | ||
954 | [AB8505_LDO_USB] = { | ||
955 | .constraints = { | ||
956 | .name = "V-USB", | ||
957 | .valid_ops_mask = REGULATOR_CHANGE_STATUS | | ||
958 | REGULATOR_CHANGE_MODE, | ||
959 | .valid_modes_mask = REGULATOR_MODE_NORMAL | | ||
960 | REGULATOR_MODE_IDLE, | ||
961 | }, | ||
962 | .num_consumer_supplies = ARRAY_SIZE(ab8505_usb_consumers), | ||
963 | .consumer_supplies = ab8505_usb_consumers, | ||
964 | }, | ||
965 | /* supply for U8500 CSI-DSI, VANA LDO */ | ||
966 | [AB8505_LDO_ANA] = { | ||
967 | .constraints = { | ||
968 | .name = "V-CSI-DSI", | ||
969 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
970 | }, | ||
971 | .num_consumer_supplies = ARRAY_SIZE(ab8500_vana_consumers), | ||
972 | .consumer_supplies = ab8500_vana_consumers, | ||
973 | }, | ||
974 | }; | ||
975 | |||
976 | struct ab8500_regulator_platform_data ab8500_regulator_plat_data = { | ||
977 | .reg_init = ab8500_reg_init, | ||
978 | .num_reg_init = ARRAY_SIZE(ab8500_reg_init), | ||
979 | .regulator = ab8500_regulators, | ||
980 | .num_regulator = ARRAY_SIZE(ab8500_regulators), | ||
981 | .ext_regulator = ab8500_ext_regulators, | ||
982 | .num_ext_regulator = ARRAY_SIZE(ab8500_ext_regulators), | ||
983 | }; | ||
984 | |||
985 | /* Use the AB8500 init settings for AB8505 as they are the same right now */ | ||
986 | struct ab8500_regulator_platform_data ab8505_regulator_plat_data = { | ||
987 | .reg_init = ab8505_reg_init, | ||
988 | .num_reg_init = ARRAY_SIZE(ab8505_reg_init), | ||
989 | .regulator = ab8505_regulators, | ||
990 | .num_regulator = ARRAY_SIZE(ab8505_regulators), | ||
991 | }; | ||
992 | |||
993 | static void ab8500_modify_reg_init(int id, u8 mask, u8 value) | ||
994 | { | ||
995 | int i; | ||
996 | |||
997 | if (cpu_is_u8520()) { | ||
998 | for (i = ARRAY_SIZE(ab8505_reg_init) - 1; i >= 0; i--) { | ||
999 | if (ab8505_reg_init[i].id == id) { | ||
1000 | u8 initval = ab8505_reg_init[i].value; | ||
1001 | initval = (initval & ~mask) | (value & mask); | ||
1002 | ab8505_reg_init[i].value = initval; | ||
1003 | |||
1004 | BUG_ON(mask & ~ab8505_reg_init[i].mask); | ||
1005 | return; | ||
1006 | } | ||
1007 | } | ||
1008 | } else { | ||
1009 | for (i = ARRAY_SIZE(ab8500_reg_init) - 1; i >= 0; i--) { | ||
1010 | if (ab8500_reg_init[i].id == id) { | ||
1011 | u8 initval = ab8500_reg_init[i].value; | ||
1012 | initval = (initval & ~mask) | (value & mask); | ||
1013 | ab8500_reg_init[i].value = initval; | ||
1014 | |||
1015 | BUG_ON(mask & ~ab8500_reg_init[i].mask); | ||
1016 | return; | ||
1017 | } | ||
1018 | } | ||
1019 | } | ||
1020 | |||
1021 | BUG_ON(1); | ||
1022 | } | ||
1023 | |||
1024 | void mop500_regulator_init(void) | ||
1025 | { | ||
1026 | struct regulator_init_data *regulator; | ||
1027 | |||
1028 | /* | ||
1029 | * Temporarily turn on Vaux2 on 8520 machine | ||
1030 | */ | ||
1031 | if (cpu_is_u8520()) { | ||
1032 | /* Vaux2 initialized to be on */ | ||
1033 | ab8500_modify_reg_init(AB8505_VAUX12REGU, 0x0f, 0x05); | ||
1034 | } | ||
1035 | |||
1036 | /* | ||
1037 | * Handle AB8500_EXT_SUPPLY2 on HREFP_V20_V50 boards (do it for | ||
1038 | * all HREFP_V20 boards) | ||
1039 | */ | ||
1040 | if (cpu_is_u8500v20()) { | ||
1041 | /* VextSupply2RequestCtrl = HP/OFF depending on VxRequest */ | ||
1042 | ab8500_modify_reg_init(AB8500_REGUREQUESTCTRL3, 0x01, 0x01); | ||
1043 | |||
1044 | /* VextSupply2SysClkReq1HPValid = SysClkReq1 controlled */ | ||
1045 | ab8500_modify_reg_init(AB8500_REGUSYSCLKREQ1HPVALID2, | ||
1046 | 0x20, 0x20); | ||
1047 | |||
1048 | /* VextSupply2 = force HP at initialization */ | ||
1049 | ab8500_modify_reg_init(AB8500_EXTSUPPLYREGU, 0x0c, 0x04); | ||
1050 | |||
1051 | /* enable VextSupply2 during platform active */ | ||
1052 | regulator = &ab8500_ext_regulators[AB8500_EXT_SUPPLY2]; | ||
1053 | regulator->constraints.always_on = 1; | ||
1054 | |||
1055 | /* disable VextSupply2 in suspend */ | ||
1056 | regulator = &ab8500_ext_regulators[AB8500_EXT_SUPPLY2]; | ||
1057 | regulator->constraints.state_mem.disabled = 1; | ||
1058 | regulator->constraints.state_standby.disabled = 1; | ||
1059 | |||
1060 | /* enable VextSupply2 HW control (used in suspend) */ | ||
1061 | regulator->driver_data = (void *)&ab8500_ext_supply2; | ||
1062 | } | ||
1063 | } | ||
diff --git a/arch/arm/mach-ux500/board-mop500-regulators.h b/arch/arm/mach-ux500/board-mop500-regulators.h index 78a0642a2206..9bece38fe933 100644 --- a/arch/arm/mach-ux500/board-mop500-regulators.h +++ b/arch/arm/mach-ux500/board-mop500-regulators.h | |||
@@ -14,10 +14,11 @@ | |||
14 | #include <linux/regulator/machine.h> | 14 | #include <linux/regulator/machine.h> |
15 | #include <linux/regulator/ab8500.h> | 15 | #include <linux/regulator/ab8500.h> |
16 | 16 | ||
17 | extern struct ab8500_regulator_reg_init | 17 | extern struct ab8500_regulator_platform_data ab8500_regulator_plat_data; |
18 | ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS]; | 18 | extern struct ab8500_regulator_platform_data ab8505_regulator_plat_data; |
19 | extern struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS]; | ||
20 | extern struct regulator_init_data tps61052_regulator; | 19 | extern struct regulator_init_data tps61052_regulator; |
21 | extern struct regulator_init_data gpio_en_3v3_regulator; | 20 | extern struct regulator_init_data gpio_en_3v3_regulator; |
22 | 21 | ||
22 | void mop500_regulator_init(void); | ||
23 | |||
23 | #endif | 24 | #endif |
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 87d2d7b38ce9..ce672378a830 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c | |||
@@ -199,10 +199,7 @@ static struct platform_device snowball_sbnet_dev = { | |||
199 | 199 | ||
200 | struct ab8500_platform_data ab8500_platdata = { | 200 | struct ab8500_platform_data ab8500_platdata = { |
201 | .irq_base = MOP500_AB8500_IRQ_BASE, | 201 | .irq_base = MOP500_AB8500_IRQ_BASE, |
202 | .regulator_reg_init = ab8500_regulator_reg_init, | 202 | .regulator = &ab8500_regulator_plat_data, |
203 | .num_regulator_reg_init = ARRAY_SIZE(ab8500_regulator_reg_init), | ||
204 | .regulator = ab8500_regulators, | ||
205 | .num_regulator = ARRAY_SIZE(ab8500_regulators), | ||
206 | .gpio = &ab8500_gpio_pdata, | 203 | .gpio = &ab8500_gpio_pdata, |
207 | .codec = &ab8500_codec_pdata, | 204 | .codec = &ab8500_codec_pdata, |
208 | }; | 205 | }; |
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 915683cb67d6..c5e20b52e3b7 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <linux/regulator/fixed.h> | 21 | #include <linux/regulator/fixed.h> |
22 | #include <linux/regulator/machine.h> | 22 | #include <linux/regulator/machine.h> |
23 | #include <linux/vexpress.h> | 23 | #include <linux/vexpress.h> |
24 | #include <linux/clk-provider.h> | ||
25 | #include <linux/clkdev.h> | ||
24 | 26 | ||
25 | #include <asm/arch_timer.h> | 27 | #include <asm/arch_timer.h> |
26 | #include <asm/mach-types.h> | 28 | #include <asm/mach-types.h> |
@@ -433,7 +435,7 @@ static void __init v2m_dt_timer_init(void) | |||
433 | { | 435 | { |
434 | struct device_node *node = NULL; | 436 | struct device_node *node = NULL; |
435 | 437 | ||
436 | vexpress_clk_of_init(); | 438 | of_clk_init(NULL); |
437 | 439 | ||
438 | do { | 440 | do { |
439 | node = of_find_compatible_node(node, NULL, "arm,sp804"); | 441 | node = of_find_compatible_node(node, NULL, "arm,sp804"); |
@@ -441,6 +443,10 @@ static void __init v2m_dt_timer_init(void) | |||
441 | if (node) { | 443 | if (node) { |
442 | pr_info("Using SP804 '%s' as a clock & events source\n", | 444 | pr_info("Using SP804 '%s' as a clock & events source\n", |
443 | node->full_name); | 445 | node->full_name); |
446 | WARN_ON(clk_register_clkdev(of_clk_get_by_name(node, | ||
447 | "timclken1"), "v2m-timer0", "sp804")); | ||
448 | WARN_ON(clk_register_clkdev(of_clk_get_by_name(node, | ||
449 | "timclken2"), "v2m-timer1", "sp804")); | ||
444 | v2m_sp804_init(of_iomap(node, 0), | 450 | v2m_sp804_init(of_iomap(node, 0), |
445 | irq_of_parse_and_map(node, 0)); | 451 | irq_of_parse_and_map(node, 0)); |
446 | } | 452 | } |
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 025d17328730..4045c4931a30 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -43,7 +43,7 @@ config CPU_ARM740T | |||
43 | depends on !MMU | 43 | depends on !MMU |
44 | select CPU_32v4T | 44 | select CPU_32v4T |
45 | select CPU_ABRT_LV4T | 45 | select CPU_ABRT_LV4T |
46 | select CPU_CACHE_V3 # although the core is v4t | 46 | select CPU_CACHE_V4 |
47 | select CPU_CP15_MPU | 47 | select CPU_CP15_MPU |
48 | select CPU_PABRT_LEGACY | 48 | select CPU_PABRT_LEGACY |
49 | help | 49 | help |
@@ -469,9 +469,6 @@ config CPU_PABRT_V7 | |||
469 | bool | 469 | bool |
470 | 470 | ||
471 | # The cache model | 471 | # The cache model |
472 | config CPU_CACHE_V3 | ||
473 | bool | ||
474 | |||
475 | config CPU_CACHE_V4 | 472 | config CPU_CACHE_V4 |
476 | bool | 473 | bool |
477 | 474 | ||
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 4e333fa2756f..9e51be96f635 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile | |||
@@ -33,7 +33,6 @@ obj-$(CONFIG_CPU_PABRT_LEGACY) += pabort-legacy.o | |||
33 | obj-$(CONFIG_CPU_PABRT_V6) += pabort-v6.o | 33 | obj-$(CONFIG_CPU_PABRT_V6) += pabort-v6.o |
34 | obj-$(CONFIG_CPU_PABRT_V7) += pabort-v7.o | 34 | obj-$(CONFIG_CPU_PABRT_V7) += pabort-v7.o |
35 | 35 | ||
36 | obj-$(CONFIG_CPU_CACHE_V3) += cache-v3.o | ||
37 | obj-$(CONFIG_CPU_CACHE_V4) += cache-v4.o | 36 | obj-$(CONFIG_CPU_CACHE_V4) += cache-v4.o |
38 | obj-$(CONFIG_CPU_CACHE_V4WT) += cache-v4wt.o | 37 | obj-$(CONFIG_CPU_CACHE_V4WT) += cache-v4wt.o |
39 | obj-$(CONFIG_CPU_CACHE_V4WB) += cache-v4wb.o | 38 | obj-$(CONFIG_CPU_CACHE_V4WB) += cache-v4wb.o |
diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c index dd3d59122cc3..48bc3c0a87ce 100644 --- a/arch/arm/mm/cache-feroceon-l2.c +++ b/arch/arm/mm/cache-feroceon-l2.c | |||
@@ -343,6 +343,7 @@ void __init feroceon_l2_init(int __l2_wt_override) | |||
343 | outer_cache.inv_range = feroceon_l2_inv_range; | 343 | outer_cache.inv_range = feroceon_l2_inv_range; |
344 | outer_cache.clean_range = feroceon_l2_clean_range; | 344 | outer_cache.clean_range = feroceon_l2_clean_range; |
345 | outer_cache.flush_range = feroceon_l2_flush_range; | 345 | outer_cache.flush_range = feroceon_l2_flush_range; |
346 | outer_cache.inv_all = l2_inv_all; | ||
346 | 347 | ||
347 | enable_l2(); | 348 | enable_l2(); |
348 | 349 | ||
diff --git a/arch/arm/mm/cache-v3.S b/arch/arm/mm/cache-v3.S deleted file mode 100644 index 8a3fadece8d3..000000000000 --- a/arch/arm/mm/cache-v3.S +++ /dev/null | |||
@@ -1,137 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mm/cache-v3.S | ||
3 | * | ||
4 | * Copyright (C) 1997-2002 Russell king | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #include <linux/linkage.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <asm/page.h> | ||
13 | #include "proc-macros.S" | ||
14 | |||
15 | /* | ||
16 | * flush_icache_all() | ||
17 | * | ||
18 | * Unconditionally clean and invalidate the entire icache. | ||
19 | */ | ||
20 | ENTRY(v3_flush_icache_all) | ||
21 | mov pc, lr | ||
22 | ENDPROC(v3_flush_icache_all) | ||
23 | |||
24 | /* | ||
25 | * flush_user_cache_all() | ||
26 | * | ||
27 | * Invalidate all cache entries in a particular address | ||
28 | * space. | ||
29 | * | ||
30 | * - mm - mm_struct describing address space | ||
31 | */ | ||
32 | ENTRY(v3_flush_user_cache_all) | ||
33 | /* FALLTHROUGH */ | ||
34 | /* | ||
35 | * flush_kern_cache_all() | ||
36 | * | ||
37 | * Clean and invalidate the entire cache. | ||
38 | */ | ||
39 | ENTRY(v3_flush_kern_cache_all) | ||
40 | /* FALLTHROUGH */ | ||
41 | |||
42 | /* | ||
43 | * flush_user_cache_range(start, end, flags) | ||
44 | * | ||
45 | * Invalidate a range of cache entries in the specified | ||
46 | * address space. | ||
47 | * | ||
48 | * - start - start address (may not be aligned) | ||
49 | * - end - end address (exclusive, may not be aligned) | ||
50 | * - flags - vma_area_struct flags describing address space | ||
51 | */ | ||
52 | ENTRY(v3_flush_user_cache_range) | ||
53 | mov ip, #0 | ||
54 | mcreq p15, 0, ip, c7, c0, 0 @ flush ID cache | ||
55 | mov pc, lr | ||
56 | |||
57 | /* | ||
58 | * coherent_kern_range(start, end) | ||
59 | * | ||
60 | * Ensure coherency between the Icache and the Dcache in the | ||
61 | * region described by start. If you have non-snooping | ||
62 | * Harvard caches, you need to implement this function. | ||
63 | * | ||
64 | * - start - virtual start address | ||
65 | * - end - virtual end address | ||
66 | */ | ||
67 | ENTRY(v3_coherent_kern_range) | ||
68 | /* FALLTHROUGH */ | ||
69 | |||
70 | /* | ||
71 | * coherent_user_range(start, end) | ||
72 | * | ||
73 | * Ensure coherency between the Icache and the Dcache in the | ||
74 | * region described by start. If you have non-snooping | ||
75 | * Harvard caches, you need to implement this function. | ||
76 | * | ||
77 | * - start - virtual start address | ||
78 | * - end - virtual end address | ||
79 | */ | ||
80 | ENTRY(v3_coherent_user_range) | ||
81 | mov r0, #0 | ||
82 | mov pc, lr | ||
83 | |||
84 | /* | ||
85 | * flush_kern_dcache_area(void *page, size_t size) | ||
86 | * | ||
87 | * Ensure no D cache aliasing occurs, either with itself or | ||
88 | * the I cache | ||
89 | * | ||
90 | * - addr - kernel address | ||
91 | * - size - region size | ||
92 | */ | ||
93 | ENTRY(v3_flush_kern_dcache_area) | ||
94 | /* FALLTHROUGH */ | ||
95 | |||
96 | /* | ||
97 | * dma_flush_range(start, end) | ||
98 | * | ||
99 | * Clean and invalidate the specified virtual address range. | ||
100 | * | ||
101 | * - start - virtual start address | ||
102 | * - end - virtual end address | ||
103 | */ | ||
104 | ENTRY(v3_dma_flush_range) | ||
105 | mov r0, #0 | ||
106 | mcr p15, 0, r0, c7, c0, 0 @ flush ID cache | ||
107 | mov pc, lr | ||
108 | |||
109 | /* | ||
110 | * dma_unmap_area(start, size, dir) | ||
111 | * - start - kernel virtual start address | ||
112 | * - size - size of region | ||
113 | * - dir - DMA direction | ||
114 | */ | ||
115 | ENTRY(v3_dma_unmap_area) | ||
116 | teq r2, #DMA_TO_DEVICE | ||
117 | bne v3_dma_flush_range | ||
118 | /* FALLTHROUGH */ | ||
119 | |||
120 | /* | ||
121 | * dma_map_area(start, size, dir) | ||
122 | * - start - kernel virtual start address | ||
123 | * - size - size of region | ||
124 | * - dir - DMA direction | ||
125 | */ | ||
126 | ENTRY(v3_dma_map_area) | ||
127 | mov pc, lr | ||
128 | ENDPROC(v3_dma_unmap_area) | ||
129 | ENDPROC(v3_dma_map_area) | ||
130 | |||
131 | .globl v3_flush_kern_cache_louis | ||
132 | .equ v3_flush_kern_cache_louis, v3_flush_kern_cache_all | ||
133 | |||
134 | __INITDATA | ||
135 | |||
136 | @ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S) | ||
137 | define_cache_functions v3 | ||
diff --git a/arch/arm/mm/cache-v4.S b/arch/arm/mm/cache-v4.S index 43e5d77be677..a7ba68f59f0c 100644 --- a/arch/arm/mm/cache-v4.S +++ b/arch/arm/mm/cache-v4.S | |||
@@ -58,7 +58,7 @@ ENTRY(v4_flush_kern_cache_all) | |||
58 | ENTRY(v4_flush_user_cache_range) | 58 | ENTRY(v4_flush_user_cache_range) |
59 | #ifdef CONFIG_CPU_CP15 | 59 | #ifdef CONFIG_CPU_CP15 |
60 | mov ip, #0 | 60 | mov ip, #0 |
61 | mcreq p15, 0, ip, c7, c7, 0 @ flush ID cache | 61 | mcr p15, 0, ip, c7, c7, 0 @ flush ID cache |
62 | mov pc, lr | 62 | mov pc, lr |
63 | #else | 63 | #else |
64 | /* FALLTHROUGH */ | 64 | /* FALLTHROUGH */ |
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index ad722f1208a5..9a5cdc01fcdf 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
@@ -99,6 +99,9 @@ void show_mem(unsigned int filter) | |||
99 | printk("Mem-info:\n"); | 99 | printk("Mem-info:\n"); |
100 | show_free_areas(filter); | 100 | show_free_areas(filter); |
101 | 101 | ||
102 | if (filter & SHOW_MEM_FILTER_PAGE_COUNT) | ||
103 | return; | ||
104 | |||
102 | for_each_bank (i, mi) { | 105 | for_each_bank (i, mi) { |
103 | struct membank *bank = &mi->bank[i]; | 106 | struct membank *bank = &mi->bank[i]; |
104 | unsigned int pfn1, pfn2; | 107 | unsigned int pfn1, pfn2; |
@@ -424,24 +427,6 @@ void __init bootmem_init(void) | |||
424 | max_pfn = max_high - PHYS_PFN_OFFSET; | 427 | max_pfn = max_high - PHYS_PFN_OFFSET; |
425 | } | 428 | } |
426 | 429 | ||
427 | static inline int free_area(unsigned long pfn, unsigned long end, char *s) | ||
428 | { | ||
429 | unsigned int pages = 0, size = (end - pfn) << (PAGE_SHIFT - 10); | ||
430 | |||
431 | for (; pfn < end; pfn++) { | ||
432 | struct page *page = pfn_to_page(pfn); | ||
433 | ClearPageReserved(page); | ||
434 | init_page_count(page); | ||
435 | __free_page(page); | ||
436 | pages++; | ||
437 | } | ||
438 | |||
439 | if (size && s) | ||
440 | printk(KERN_INFO "Freeing %s memory: %dK\n", s, size); | ||
441 | |||
442 | return pages; | ||
443 | } | ||
444 | |||
445 | /* | 430 | /* |
446 | * Poison init memory with an undefined instruction (ARM) or a branch to an | 431 | * Poison init memory with an undefined instruction (ARM) or a branch to an |
447 | * undefined instruction (Thumb). | 432 | * undefined instruction (Thumb). |
@@ -534,6 +519,14 @@ static void __init free_unused_memmap(struct meminfo *mi) | |||
534 | #endif | 519 | #endif |
535 | } | 520 | } |
536 | 521 | ||
522 | #ifdef CONFIG_HIGHMEM | ||
523 | static inline void free_area_high(unsigned long pfn, unsigned long end) | ||
524 | { | ||
525 | for (; pfn < end; pfn++) | ||
526 | free_highmem_page(pfn_to_page(pfn)); | ||
527 | } | ||
528 | #endif | ||
529 | |||
537 | static void __init free_highpages(void) | 530 | static void __init free_highpages(void) |
538 | { | 531 | { |
539 | #ifdef CONFIG_HIGHMEM | 532 | #ifdef CONFIG_HIGHMEM |
@@ -569,8 +562,7 @@ static void __init free_highpages(void) | |||
569 | if (res_end > end) | 562 | if (res_end > end) |
570 | res_end = end; | 563 | res_end = end; |
571 | if (res_start != start) | 564 | if (res_start != start) |
572 | totalhigh_pages += free_area(start, res_start, | 565 | free_area_high(start, res_start); |
573 | NULL); | ||
574 | start = res_end; | 566 | start = res_end; |
575 | if (start == end) | 567 | if (start == end) |
576 | break; | 568 | break; |
@@ -578,9 +570,8 @@ static void __init free_highpages(void) | |||
578 | 570 | ||
579 | /* And now free anything which remains */ | 571 | /* And now free anything which remains */ |
580 | if (start < end) | 572 | if (start < end) |
581 | totalhigh_pages += free_area(start, end, NULL); | 573 | free_area_high(start, end); |
582 | } | 574 | } |
583 | totalram_pages += totalhigh_pages; | ||
584 | #endif | 575 | #endif |
585 | } | 576 | } |
586 | 577 | ||
@@ -609,8 +600,7 @@ void __init mem_init(void) | |||
609 | 600 | ||
610 | #ifdef CONFIG_SA1111 | 601 | #ifdef CONFIG_SA1111 |
611 | /* now that our DMA memory is actually so designated, we can free it */ | 602 | /* now that our DMA memory is actually so designated, we can free it */ |
612 | totalram_pages += free_area(PHYS_PFN_OFFSET, | 603 | free_reserved_area(__va(PHYS_PFN_OFFSET), swapper_pg_dir, 0, NULL); |
613 | __phys_to_pfn(__pa(swapper_pg_dir)), NULL); | ||
614 | #endif | 604 | #endif |
615 | 605 | ||
616 | free_highpages(); | 606 | free_highpages(); |
@@ -738,16 +728,12 @@ void free_initmem(void) | |||
738 | extern char __tcm_start, __tcm_end; | 728 | extern char __tcm_start, __tcm_end; |
739 | 729 | ||
740 | poison_init_mem(&__tcm_start, &__tcm_end - &__tcm_start); | 730 | poison_init_mem(&__tcm_start, &__tcm_end - &__tcm_start); |
741 | totalram_pages += free_area(__phys_to_pfn(__pa(&__tcm_start)), | 731 | free_reserved_area(&__tcm_start, &__tcm_end, 0, "TCM link"); |
742 | __phys_to_pfn(__pa(&__tcm_end)), | ||
743 | "TCM link"); | ||
744 | #endif | 732 | #endif |
745 | 733 | ||
746 | poison_init_mem(__init_begin, __init_end - __init_begin); | 734 | poison_init_mem(__init_begin, __init_end - __init_begin); |
747 | if (!machine_is_integrator() && !machine_is_cintegrator()) | 735 | if (!machine_is_integrator() && !machine_is_cintegrator()) |
748 | totalram_pages += free_area(__phys_to_pfn(__pa(__init_begin)), | 736 | free_initmem_default(0); |
749 | __phys_to_pfn(__pa(__init_end)), | ||
750 | "init"); | ||
751 | } | 737 | } |
752 | 738 | ||
753 | #ifdef CONFIG_BLK_DEV_INITRD | 739 | #ifdef CONFIG_BLK_DEV_INITRD |
@@ -758,9 +744,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) | |||
758 | { | 744 | { |
759 | if (!keep_initrd) { | 745 | if (!keep_initrd) { |
760 | poison_init_mem((void *)start, PAGE_ALIGN(end) - start); | 746 | poison_init_mem((void *)start, PAGE_ALIGN(end) - start); |
761 | totalram_pages += free_area(__phys_to_pfn(__pa(start)), | 747 | free_reserved_area(start, end, 0, "initrd"); |
762 | __phys_to_pfn(__pa(end)), | ||
763 | "initrd"); | ||
764 | } | 748 | } |
765 | } | 749 | } |
766 | 750 | ||
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 78978945492a..a84ff763ac39 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <asm/mach/pci.h> | 34 | #include <asm/mach/pci.h> |
35 | 35 | ||
36 | #include "mm.h" | 36 | #include "mm.h" |
37 | #include "tcm.h" | ||
37 | 38 | ||
38 | /* | 39 | /* |
39 | * empty_zero_page is a special page that is used for | 40 | * empty_zero_page is a special page that is used for |
@@ -1277,6 +1278,7 @@ void __init paging_init(struct machine_desc *mdesc) | |||
1277 | dma_contiguous_remap(); | 1278 | dma_contiguous_remap(); |
1278 | devicemaps_init(mdesc); | 1279 | devicemaps_init(mdesc); |
1279 | kmap_init(); | 1280 | kmap_init(); |
1281 | tcm_init(); | ||
1280 | 1282 | ||
1281 | top_pmd = pmd_off_k(0xffff0000); | 1283 | top_pmd = pmd_off_k(0xffff0000); |
1282 | 1284 | ||
diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S index dc5de5d53f20..fde2d2a794cf 100644 --- a/arch/arm/mm/proc-arm740.S +++ b/arch/arm/mm/proc-arm740.S | |||
@@ -77,24 +77,27 @@ __arm740_setup: | |||
77 | mcr p15, 0, r0, c6, c0 @ set area 0, default | 77 | mcr p15, 0, r0, c6, c0 @ set area 0, default |
78 | 78 | ||
79 | ldr r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM | 79 | ldr r0, =(CONFIG_DRAM_BASE & 0xFFFFF000) @ base[31:12] of RAM |
80 | ldr r1, =(CONFIG_DRAM_SIZE >> 12) @ size of RAM (must be >= 4KB) | 80 | ldr r3, =(CONFIG_DRAM_SIZE >> 12) @ size of RAM (must be >= 4KB) |
81 | mov r2, #10 @ 11 is the minimum (4KB) | 81 | mov r4, #10 @ 11 is the minimum (4KB) |
82 | 1: add r2, r2, #1 @ area size *= 2 | 82 | 1: add r4, r4, #1 @ area size *= 2 |
83 | mov r1, r1, lsr #1 | 83 | movs r3, r3, lsr #1 |
84 | bne 1b @ count not zero r-shift | 84 | bne 1b @ count not zero r-shift |
85 | orr r0, r0, r2, lsl #1 @ the area register value | 85 | orr r0, r0, r4, lsl #1 @ the area register value |
86 | orr r0, r0, #1 @ set enable bit | 86 | orr r0, r0, #1 @ set enable bit |
87 | mcr p15, 0, r0, c6, c1 @ set area 1, RAM | 87 | mcr p15, 0, r0, c6, c1 @ set area 1, RAM |
88 | 88 | ||
89 | ldr r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH | 89 | ldr r0, =(CONFIG_FLASH_MEM_BASE & 0xFFFFF000) @ base[31:12] of FLASH |
90 | ldr r1, =(CONFIG_FLASH_SIZE >> 12) @ size of FLASH (must be >= 4KB) | 90 | ldr r3, =(CONFIG_FLASH_SIZE >> 12) @ size of FLASH (must be >= 4KB) |
91 | mov r2, #10 @ 11 is the minimum (4KB) | 91 | cmp r3, #0 |
92 | 1: add r2, r2, #1 @ area size *= 2 | 92 | moveq r0, #0 |
93 | mov r1, r1, lsr #1 | 93 | beq 2f |
94 | mov r4, #10 @ 11 is the minimum (4KB) | ||
95 | 1: add r4, r4, #1 @ area size *= 2 | ||
96 | movs r3, r3, lsr #1 | ||
94 | bne 1b @ count not zero r-shift | 97 | bne 1b @ count not zero r-shift |
95 | orr r0, r0, r2, lsl #1 @ the area register value | 98 | orr r0, r0, r4, lsl #1 @ the area register value |
96 | orr r0, r0, #1 @ set enable bit | 99 | orr r0, r0, #1 @ set enable bit |
97 | mcr p15, 0, r0, c6, c2 @ set area 2, ROM/FLASH | 100 | 2: mcr p15, 0, r0, c6, c2 @ set area 2, ROM/FLASH |
98 | 101 | ||
99 | mov r0, #0x06 | 102 | mov r0, #0x06 |
100 | mcr p15, 0, r0, c2, c0 @ Region 1&2 cacheable | 103 | mcr p15, 0, r0, c2, c0 @ Region 1&2 cacheable |
@@ -137,13 +140,14 @@ __arm740_proc_info: | |||
137 | .long 0x41807400 | 140 | .long 0x41807400 |
138 | .long 0xfffffff0 | 141 | .long 0xfffffff0 |
139 | .long 0 | 142 | .long 0 |
143 | .long 0 | ||
140 | b __arm740_setup | 144 | b __arm740_setup |
141 | .long cpu_arch_name | 145 | .long cpu_arch_name |
142 | .long cpu_elf_name | 146 | .long cpu_elf_name |
143 | .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT | 147 | .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB | HWCAP_26BIT |
144 | .long cpu_arm740_name | 148 | .long cpu_arm740_name |
145 | .long arm740_processor_functions | 149 | .long arm740_processor_functions |
146 | .long 0 | 150 | .long 0 |
147 | .long 0 | 151 | .long 0 |
148 | .long v3_cache_fns @ cache model | 152 | .long v4_cache_fns @ cache model |
149 | .size __arm740_proc_info, . - __arm740_proc_info | 153 | .size __arm740_proc_info, . - __arm740_proc_info |
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S index 2c3b9421ab5e..2556cf1c2da1 100644 --- a/arch/arm/mm/proc-arm920.S +++ b/arch/arm/mm/proc-arm920.S | |||
@@ -387,7 +387,7 @@ ENTRY(cpu_arm920_set_pte_ext) | |||
387 | /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */ | 387 | /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */ |
388 | .globl cpu_arm920_suspend_size | 388 | .globl cpu_arm920_suspend_size |
389 | .equ cpu_arm920_suspend_size, 4 * 3 | 389 | .equ cpu_arm920_suspend_size, 4 * 3 |
390 | #ifdef CONFIG_PM_SLEEP | 390 | #ifdef CONFIG_ARM_CPU_SUSPEND |
391 | ENTRY(cpu_arm920_do_suspend) | 391 | ENTRY(cpu_arm920_do_suspend) |
392 | stmfd sp!, {r4 - r6, lr} | 392 | stmfd sp!, {r4 - r6, lr} |
393 | mrc p15, 0, r4, c13, c0, 0 @ PID | 393 | mrc p15, 0, r4, c13, c0, 0 @ PID |
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S index f1803f7e2972..344c8a548cc0 100644 --- a/arch/arm/mm/proc-arm926.S +++ b/arch/arm/mm/proc-arm926.S | |||
@@ -402,7 +402,7 @@ ENTRY(cpu_arm926_set_pte_ext) | |||
402 | /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */ | 402 | /* Suspend/resume support: taken from arch/arm/plat-s3c24xx/sleep.S */ |
403 | .globl cpu_arm926_suspend_size | 403 | .globl cpu_arm926_suspend_size |
404 | .equ cpu_arm926_suspend_size, 4 * 3 | 404 | .equ cpu_arm926_suspend_size, 4 * 3 |
405 | #ifdef CONFIG_PM_SLEEP | 405 | #ifdef CONFIG_ARM_CPU_SUSPEND |
406 | ENTRY(cpu_arm926_do_suspend) | 406 | ENTRY(cpu_arm926_do_suspend) |
407 | stmfd sp!, {r4 - r6, lr} | 407 | stmfd sp!, {r4 - r6, lr} |
408 | mrc p15, 0, r4, c13, c0, 0 @ PID | 408 | mrc p15, 0, r4, c13, c0, 0 @ PID |
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S index 82f9cdc751d6..0b60dd3d742a 100644 --- a/arch/arm/mm/proc-mohawk.S +++ b/arch/arm/mm/proc-mohawk.S | |||
@@ -350,7 +350,7 @@ ENTRY(cpu_mohawk_set_pte_ext) | |||
350 | 350 | ||
351 | .globl cpu_mohawk_suspend_size | 351 | .globl cpu_mohawk_suspend_size |
352 | .equ cpu_mohawk_suspend_size, 4 * 6 | 352 | .equ cpu_mohawk_suspend_size, 4 * 6 |
353 | #ifdef CONFIG_PM_SLEEP | 353 | #ifdef CONFIG_ARM_CPU_SUSPEND |
354 | ENTRY(cpu_mohawk_do_suspend) | 354 | ENTRY(cpu_mohawk_do_suspend) |
355 | stmfd sp!, {r4 - r9, lr} | 355 | stmfd sp!, {r4 - r9, lr} |
356 | mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode | 356 | mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode |
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S index 3aa0da11fd84..d92dfd081429 100644 --- a/arch/arm/mm/proc-sa1100.S +++ b/arch/arm/mm/proc-sa1100.S | |||
@@ -172,7 +172,7 @@ ENTRY(cpu_sa1100_set_pte_ext) | |||
172 | 172 | ||
173 | .globl cpu_sa1100_suspend_size | 173 | .globl cpu_sa1100_suspend_size |
174 | .equ cpu_sa1100_suspend_size, 4 * 3 | 174 | .equ cpu_sa1100_suspend_size, 4 * 3 |
175 | #ifdef CONFIG_PM_SLEEP | 175 | #ifdef CONFIG_ARM_CPU_SUSPEND |
176 | ENTRY(cpu_sa1100_do_suspend) | 176 | ENTRY(cpu_sa1100_do_suspend) |
177 | stmfd sp!, {r4 - r6, lr} | 177 | stmfd sp!, {r4 - r6, lr} |
178 | mrc p15, 0, r4, c3, c0, 0 @ domain ID | 178 | mrc p15, 0, r4, c3, c0, 0 @ domain ID |
diff --git a/arch/arm/mm/proc-syms.c b/arch/arm/mm/proc-syms.c index 3e6210b4d6d4..054b491ff764 100644 --- a/arch/arm/mm/proc-syms.c +++ b/arch/arm/mm/proc-syms.c | |||
@@ -17,7 +17,9 @@ | |||
17 | 17 | ||
18 | #ifndef MULTI_CPU | 18 | #ifndef MULTI_CPU |
19 | EXPORT_SYMBOL(cpu_dcache_clean_area); | 19 | EXPORT_SYMBOL(cpu_dcache_clean_area); |
20 | #ifdef CONFIG_MMU | ||
20 | EXPORT_SYMBOL(cpu_set_pte_ext); | 21 | EXPORT_SYMBOL(cpu_set_pte_ext); |
22 | #endif | ||
21 | #else | 23 | #else |
22 | EXPORT_SYMBOL(processor); | 24 | EXPORT_SYMBOL(processor); |
23 | #endif | 25 | #endif |
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index bcaaa8de9325..5c07ee4fe3eb 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S | |||
@@ -138,7 +138,7 @@ ENTRY(cpu_v6_set_pte_ext) | |||
138 | /* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */ | 138 | /* Suspend/resume support: taken from arch/arm/mach-s3c64xx/sleep.S */ |
139 | .globl cpu_v6_suspend_size | 139 | .globl cpu_v6_suspend_size |
140 | .equ cpu_v6_suspend_size, 4 * 6 | 140 | .equ cpu_v6_suspend_size, 4 * 6 |
141 | #ifdef CONFIG_PM_SLEEP | 141 | #ifdef CONFIG_ARM_CPU_SUSPEND |
142 | ENTRY(cpu_v6_do_suspend) | 142 | ENTRY(cpu_v6_do_suspend) |
143 | stmfd sp!, {r4 - r9, lr} | 143 | stmfd sp!, {r4 - r9, lr} |
144 | mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID | 144 | mrc p15, 0, r4, c13, c0, 0 @ FCSE/PID |
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S index eb93d6487f35..e8efd83b6f25 100644 --- a/arch/arm/mm/proc-xsc3.S +++ b/arch/arm/mm/proc-xsc3.S | |||
@@ -413,7 +413,7 @@ ENTRY(cpu_xsc3_set_pte_ext) | |||
413 | 413 | ||
414 | .globl cpu_xsc3_suspend_size | 414 | .globl cpu_xsc3_suspend_size |
415 | .equ cpu_xsc3_suspend_size, 4 * 6 | 415 | .equ cpu_xsc3_suspend_size, 4 * 6 |
416 | #ifdef CONFIG_PM_SLEEP | 416 | #ifdef CONFIG_ARM_CPU_SUSPEND |
417 | ENTRY(cpu_xsc3_do_suspend) | 417 | ENTRY(cpu_xsc3_do_suspend) |
418 | stmfd sp!, {r4 - r9, lr} | 418 | stmfd sp!, {r4 - r9, lr} |
419 | mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode | 419 | mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode |
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S index 25510361aa18..e766f889bfd6 100644 --- a/arch/arm/mm/proc-xscale.S +++ b/arch/arm/mm/proc-xscale.S | |||
@@ -528,7 +528,7 @@ ENTRY(cpu_xscale_set_pte_ext) | |||
528 | 528 | ||
529 | .globl cpu_xscale_suspend_size | 529 | .globl cpu_xscale_suspend_size |
530 | .equ cpu_xscale_suspend_size, 4 * 6 | 530 | .equ cpu_xscale_suspend_size, 4 * 6 |
531 | #ifdef CONFIG_PM_SLEEP | 531 | #ifdef CONFIG_ARM_CPU_SUSPEND |
532 | ENTRY(cpu_xscale_do_suspend) | 532 | ENTRY(cpu_xscale_do_suspend) |
533 | stmfd sp!, {r4 - r9, lr} | 533 | stmfd sp!, {r4 - r9, lr} |
534 | mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode | 534 | mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode |
diff --git a/arch/arm/kernel/tcm.h b/arch/arm/mm/tcm.h index 8015ad434a40..8015ad434a40 100644 --- a/arch/arm/kernel/tcm.h +++ b/arch/arm/mm/tcm.h | |||
diff --git a/arch/arm/plat-samsung/devs.c b/arch/arm/plat-samsung/devs.c index 51afedda9ab6..03db14d8ace9 100644 --- a/arch/arm/plat-samsung/devs.c +++ b/arch/arm/plat-samsung/devs.c | |||
@@ -10,6 +10,7 @@ | |||
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/amba/pl330.h> | ||
13 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
14 | #include <linux/types.h> | 15 | #include <linux/types.h> |
15 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
@@ -1552,6 +1553,9 @@ void __init s3c64xx_spi0_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, | |||
1552 | pd.num_cs = num_cs; | 1553 | pd.num_cs = num_cs; |
1553 | pd.src_clk_nr = src_clk_nr; | 1554 | pd.src_clk_nr = src_clk_nr; |
1554 | pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio; | 1555 | pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi0_cfg_gpio; |
1556 | #ifdef CONFIG_PL330_DMA | ||
1557 | pd.filter = pl330_filter; | ||
1558 | #endif | ||
1555 | 1559 | ||
1556 | s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi0); | 1560 | s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi0); |
1557 | } | 1561 | } |
@@ -1590,6 +1594,9 @@ void __init s3c64xx_spi1_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, | |||
1590 | pd.num_cs = num_cs; | 1594 | pd.num_cs = num_cs; |
1591 | pd.src_clk_nr = src_clk_nr; | 1595 | pd.src_clk_nr = src_clk_nr; |
1592 | pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi1_cfg_gpio; | 1596 | pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi1_cfg_gpio; |
1597 | #ifdef CONFIG_PL330_DMA | ||
1598 | pd.filter = pl330_filter; | ||
1599 | #endif | ||
1593 | 1600 | ||
1594 | s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi1); | 1601 | s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi1); |
1595 | } | 1602 | } |
@@ -1628,6 +1635,9 @@ void __init s3c64xx_spi2_set_platdata(int (*cfg_gpio)(void), int src_clk_nr, | |||
1628 | pd.num_cs = num_cs; | 1635 | pd.num_cs = num_cs; |
1629 | pd.src_clk_nr = src_clk_nr; | 1636 | pd.src_clk_nr = src_clk_nr; |
1630 | pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi2_cfg_gpio; | 1637 | pd.cfg_gpio = (cfg_gpio) ? cfg_gpio : s3c64xx_spi2_cfg_gpio; |
1638 | #ifdef CONFIG_PL330_DMA | ||
1639 | pd.filter = pl330_filter; | ||
1640 | #endif | ||
1631 | 1641 | ||
1632 | s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi2); | 1642 | s3c_set_platdata(&pd, sizeof(pd), &s3c64xx_device_spi2); |
1633 | } | 1643 | } |
diff --git a/arch/arm/plat-samsung/include/plat/fb.h b/arch/arm/plat-samsung/include/plat/fb.h index b885322717a1..9ae507270785 100644 --- a/arch/arm/plat-samsung/include/plat/fb.h +++ b/arch/arm/plat-samsung/include/plat/fb.h | |||
@@ -15,55 +15,7 @@ | |||
15 | #ifndef __PLAT_S3C_FB_H | 15 | #ifndef __PLAT_S3C_FB_H |
16 | #define __PLAT_S3C_FB_H __FILE__ | 16 | #define __PLAT_S3C_FB_H __FILE__ |
17 | 17 | ||
18 | /* S3C_FB_MAX_WIN | 18 | #include <linux/platform_data/video_s3c.h> |
19 | * Set to the maximum number of windows that any of the supported hardware | ||
20 | * can use. Since the platform data uses this for an array size, having it | ||
21 | * set to the maximum of any version of the hardware can do is safe. | ||
22 | */ | ||
23 | #define S3C_FB_MAX_WIN (5) | ||
24 | |||
25 | /** | ||
26 | * struct s3c_fb_pd_win - per window setup data | ||
27 | * @xres : The window X size. | ||
28 | * @yres : The window Y size. | ||
29 | * @virtual_x: The virtual X size. | ||
30 | * @virtual_y: The virtual Y size. | ||
31 | */ | ||
32 | struct s3c_fb_pd_win { | ||
33 | unsigned short default_bpp; | ||
34 | unsigned short max_bpp; | ||
35 | unsigned short xres; | ||
36 | unsigned short yres; | ||
37 | unsigned short virtual_x; | ||
38 | unsigned short virtual_y; | ||
39 | }; | ||
40 | |||
41 | /** | ||
42 | * struct s3c_fb_platdata - S3C driver platform specific information | ||
43 | * @setup_gpio: Setup the external GPIO pins to the right state to transfer | ||
44 | * the data from the display system to the connected display | ||
45 | * device. | ||
46 | * @vidcon0: The base vidcon0 values to control the panel data format. | ||
47 | * @vidcon1: The base vidcon1 values to control the panel data output. | ||
48 | * @vtiming: Video timing when connected to a RGB type panel. | ||
49 | * @win: The setup data for each hardware window, or NULL for unused. | ||
50 | * @display_mode: The LCD output display mode. | ||
51 | * | ||
52 | * The platform data supplies the video driver with all the information | ||
53 | * it requires to work with the display(s) attached to the machine. It | ||
54 | * controls the initial mode, the number of display windows (0 is always | ||
55 | * the base framebuffer) that are initialised etc. | ||
56 | * | ||
57 | */ | ||
58 | struct s3c_fb_platdata { | ||
59 | void (*setup_gpio)(void); | ||
60 | |||
61 | struct s3c_fb_pd_win *win[S3C_FB_MAX_WIN]; | ||
62 | struct fb_videomode *vtiming; | ||
63 | |||
64 | u32 vidcon0; | ||
65 | u32 vidcon1; | ||
66 | }; | ||
67 | 19 | ||
68 | /** | 20 | /** |
69 | * s3c_fb_set_platdata() - Setup the FB device with platform data. | 21 | * s3c_fb_set_platdata() - Setup the FB device with platform data. |
diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h index 29c26a818842..f05f2afa440d 100644 --- a/arch/arm/plat-samsung/include/plat/regs-serial.h +++ b/arch/arm/plat-samsung/include/plat/regs-serial.h | |||
@@ -1,281 +1 @@ | |||
1 | /* arch/arm/plat-samsung/include/plat/regs-serial.h | #include <linux/serial_s3c.h> | |
2 | * | ||
3 | * From linux/include/asm-arm/hardware/serial_s3c2410.h | ||
4 | * | ||
5 | * Internal header file for Samsung S3C2410 serial ports (UART0-2) | ||
6 | * | ||
7 | * Copyright (C) 2002 Shane Nay (shane@minirl.com) | ||
8 | * | ||
9 | * Additional defines, Copyright 2003 Simtec Electronics (linux@simtec.co.uk) | ||
10 | * | ||
11 | * Adapted from: | ||
12 | * | ||
13 | * Internal header file for MX1ADS serial ports (UART1 & 2) | ||
14 | * | ||
15 | * Copyright (C) 2002 Shane Nay (shane@minirl.com) | ||
16 | * | ||
17 | * This program is free software; you can redistribute it and/or modify | ||
18 | * it under the terms of the GNU General Public License as published by | ||
19 | * the Free Software Foundation; either version 2 of the License, or | ||
20 | * (at your option) any later version. | ||
21 | * | ||
22 | * This program is distributed in the hope that it will be useful, | ||
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
25 | * GNU General Public License for more details. | ||
26 | * | ||
27 | * You should have received a copy of the GNU General Public License | ||
28 | * along with this program; if not, write to the Free Software | ||
29 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
30 | */ | ||
31 | |||
32 | #ifndef __ASM_ARM_REGS_SERIAL_H | ||
33 | #define __ASM_ARM_REGS_SERIAL_H | ||
34 | |||
35 | #define S3C24XX_VA_UART0 (S3C_VA_UART) | ||
36 | #define S3C24XX_VA_UART1 (S3C_VA_UART + 0x4000 ) | ||
37 | #define S3C24XX_VA_UART2 (S3C_VA_UART + 0x8000 ) | ||
38 | #define S3C24XX_VA_UART3 (S3C_VA_UART + 0xC000 ) | ||
39 | |||
40 | #define S3C2410_PA_UART0 (S3C24XX_PA_UART) | ||
41 | #define S3C2410_PA_UART1 (S3C24XX_PA_UART + 0x4000 ) | ||
42 | #define S3C2410_PA_UART2 (S3C24XX_PA_UART + 0x8000 ) | ||
43 | #define S3C2443_PA_UART3 (S3C24XX_PA_UART + 0xC000 ) | ||
44 | |||
45 | #define S3C2410_URXH (0x24) | ||
46 | #define S3C2410_UTXH (0x20) | ||
47 | #define S3C2410_ULCON (0x00) | ||
48 | #define S3C2410_UCON (0x04) | ||
49 | #define S3C2410_UFCON (0x08) | ||
50 | #define S3C2410_UMCON (0x0C) | ||
51 | #define S3C2410_UBRDIV (0x28) | ||
52 | #define S3C2410_UTRSTAT (0x10) | ||
53 | #define S3C2410_UERSTAT (0x14) | ||
54 | #define S3C2410_UFSTAT (0x18) | ||
55 | #define S3C2410_UMSTAT (0x1C) | ||
56 | |||
57 | #define S3C2410_LCON_CFGMASK ((0xF<<3)|(0x3)) | ||
58 | |||
59 | #define S3C2410_LCON_CS5 (0x0) | ||
60 | #define S3C2410_LCON_CS6 (0x1) | ||
61 | #define S3C2410_LCON_CS7 (0x2) | ||
62 | #define S3C2410_LCON_CS8 (0x3) | ||
63 | #define S3C2410_LCON_CSMASK (0x3) | ||
64 | |||
65 | #define S3C2410_LCON_PNONE (0x0) | ||
66 | #define S3C2410_LCON_PEVEN (0x5 << 3) | ||
67 | #define S3C2410_LCON_PODD (0x4 << 3) | ||
68 | #define S3C2410_LCON_PMASK (0x7 << 3) | ||
69 | |||
70 | #define S3C2410_LCON_STOPB (1<<2) | ||
71 | #define S3C2410_LCON_IRM (1<<6) | ||
72 | |||
73 | #define S3C2440_UCON_CLKMASK (3<<10) | ||
74 | #define S3C2440_UCON_CLKSHIFT (10) | ||
75 | #define S3C2440_UCON_PCLK (0<<10) | ||
76 | #define S3C2440_UCON_UCLK (1<<10) | ||
77 | #define S3C2440_UCON_PCLK2 (2<<10) | ||
78 | #define S3C2440_UCON_FCLK (3<<10) | ||
79 | #define S3C2443_UCON_EPLL (3<<10) | ||
80 | |||
81 | #define S3C6400_UCON_CLKMASK (3<<10) | ||
82 | #define S3C6400_UCON_CLKSHIFT (10) | ||
83 | #define S3C6400_UCON_PCLK (0<<10) | ||
84 | #define S3C6400_UCON_PCLK2 (2<<10) | ||
85 | #define S3C6400_UCON_UCLK0 (1<<10) | ||
86 | #define S3C6400_UCON_UCLK1 (3<<10) | ||
87 | |||
88 | #define S3C2440_UCON2_FCLK_EN (1<<15) | ||
89 | #define S3C2440_UCON0_DIVMASK (15 << 12) | ||
90 | #define S3C2440_UCON1_DIVMASK (15 << 12) | ||
91 | #define S3C2440_UCON2_DIVMASK (7 << 12) | ||
92 | #define S3C2440_UCON_DIVSHIFT (12) | ||
93 | |||
94 | #define S3C2412_UCON_CLKMASK (3<<10) | ||
95 | #define S3C2412_UCON_CLKSHIFT (10) | ||
96 | #define S3C2412_UCON_UCLK (1<<10) | ||
97 | #define S3C2412_UCON_USYSCLK (3<<10) | ||
98 | #define S3C2412_UCON_PCLK (0<<10) | ||
99 | #define S3C2412_UCON_PCLK2 (2<<10) | ||
100 | |||
101 | #define S3C2410_UCON_CLKMASK (1 << 10) | ||
102 | #define S3C2410_UCON_CLKSHIFT (10) | ||
103 | #define S3C2410_UCON_UCLK (1<<10) | ||
104 | #define S3C2410_UCON_SBREAK (1<<4) | ||
105 | |||
106 | #define S3C2410_UCON_TXILEVEL (1<<9) | ||
107 | #define S3C2410_UCON_RXILEVEL (1<<8) | ||
108 | #define S3C2410_UCON_TXIRQMODE (1<<2) | ||
109 | #define S3C2410_UCON_RXIRQMODE (1<<0) | ||
110 | #define S3C2410_UCON_RXFIFO_TOI (1<<7) | ||
111 | #define S3C2443_UCON_RXERR_IRQEN (1<<6) | ||
112 | #define S3C2443_UCON_LOOPBACK (1<<5) | ||
113 | |||
114 | #define S3C2410_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ | ||
115 | S3C2410_UCON_RXILEVEL | \ | ||
116 | S3C2410_UCON_TXIRQMODE | \ | ||
117 | S3C2410_UCON_RXIRQMODE | \ | ||
118 | S3C2410_UCON_RXFIFO_TOI) | ||
119 | |||
120 | #define S3C2410_UFCON_FIFOMODE (1<<0) | ||
121 | #define S3C2410_UFCON_TXTRIG0 (0<<6) | ||
122 | #define S3C2410_UFCON_RXTRIG8 (1<<4) | ||
123 | #define S3C2410_UFCON_RXTRIG12 (2<<4) | ||
124 | |||
125 | /* S3C2440 FIFO trigger levels */ | ||
126 | #define S3C2440_UFCON_RXTRIG1 (0<<4) | ||
127 | #define S3C2440_UFCON_RXTRIG8 (1<<4) | ||
128 | #define S3C2440_UFCON_RXTRIG16 (2<<4) | ||
129 | #define S3C2440_UFCON_RXTRIG32 (3<<4) | ||
130 | |||
131 | #define S3C2440_UFCON_TXTRIG0 (0<<6) | ||
132 | #define S3C2440_UFCON_TXTRIG16 (1<<6) | ||
133 | #define S3C2440_UFCON_TXTRIG32 (2<<6) | ||
134 | #define S3C2440_UFCON_TXTRIG48 (3<<6) | ||
135 | |||
136 | #define S3C2410_UFCON_RESETBOTH (3<<1) | ||
137 | #define S3C2410_UFCON_RESETTX (1<<2) | ||
138 | #define S3C2410_UFCON_RESETRX (1<<1) | ||
139 | |||
140 | #define S3C2410_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \ | ||
141 | S3C2410_UFCON_TXTRIG0 | \ | ||
142 | S3C2410_UFCON_RXTRIG8 ) | ||
143 | |||
144 | #define S3C2410_UMCOM_AFC (1<<4) | ||
145 | #define S3C2410_UMCOM_RTS_LOW (1<<0) | ||
146 | |||
147 | #define S3C2412_UMCON_AFC_63 (0<<5) /* same as s3c2443 */ | ||
148 | #define S3C2412_UMCON_AFC_56 (1<<5) | ||
149 | #define S3C2412_UMCON_AFC_48 (2<<5) | ||
150 | #define S3C2412_UMCON_AFC_40 (3<<5) | ||
151 | #define S3C2412_UMCON_AFC_32 (4<<5) | ||
152 | #define S3C2412_UMCON_AFC_24 (5<<5) | ||
153 | #define S3C2412_UMCON_AFC_16 (6<<5) | ||
154 | #define S3C2412_UMCON_AFC_8 (7<<5) | ||
155 | |||
156 | #define S3C2410_UFSTAT_TXFULL (1<<9) | ||
157 | #define S3C2410_UFSTAT_RXFULL (1<<8) | ||
158 | #define S3C2410_UFSTAT_TXMASK (15<<4) | ||
159 | #define S3C2410_UFSTAT_TXSHIFT (4) | ||
160 | #define S3C2410_UFSTAT_RXMASK (15<<0) | ||
161 | #define S3C2410_UFSTAT_RXSHIFT (0) | ||
162 | |||
163 | /* UFSTAT S3C2443 same as S3C2440 */ | ||
164 | #define S3C2440_UFSTAT_TXFULL (1<<14) | ||
165 | #define S3C2440_UFSTAT_RXFULL (1<<6) | ||
166 | #define S3C2440_UFSTAT_TXSHIFT (8) | ||
167 | #define S3C2440_UFSTAT_RXSHIFT (0) | ||
168 | #define S3C2440_UFSTAT_TXMASK (63<<8) | ||
169 | #define S3C2440_UFSTAT_RXMASK (63) | ||
170 | |||
171 | #define S3C2410_UTRSTAT_TXE (1<<2) | ||
172 | #define S3C2410_UTRSTAT_TXFE (1<<1) | ||
173 | #define S3C2410_UTRSTAT_RXDR (1<<0) | ||
174 | |||
175 | #define S3C2410_UERSTAT_OVERRUN (1<<0) | ||
176 | #define S3C2410_UERSTAT_FRAME (1<<2) | ||
177 | #define S3C2410_UERSTAT_BREAK (1<<3) | ||
178 | #define S3C2443_UERSTAT_PARITY (1<<1) | ||
179 | |||
180 | #define S3C2410_UERSTAT_ANY (S3C2410_UERSTAT_OVERRUN | \ | ||
181 | S3C2410_UERSTAT_FRAME | \ | ||
182 | S3C2410_UERSTAT_BREAK) | ||
183 | |||
184 | #define S3C2410_UMSTAT_CTS (1<<0) | ||
185 | #define S3C2410_UMSTAT_DeltaCTS (1<<2) | ||
186 | |||
187 | #define S3C2443_DIVSLOT (0x2C) | ||
188 | |||
189 | /* S3C64XX interrupt registers. */ | ||
190 | #define S3C64XX_UINTP 0x30 | ||
191 | #define S3C64XX_UINTSP 0x34 | ||
192 | #define S3C64XX_UINTM 0x38 | ||
193 | |||
194 | #define S3C64XX_UINTM_RXD (0) | ||
195 | #define S3C64XX_UINTM_TXD (2) | ||
196 | #define S3C64XX_UINTM_RXD_MSK (1 << S3C64XX_UINTM_RXD) | ||
197 | #define S3C64XX_UINTM_TXD_MSK (1 << S3C64XX_UINTM_TXD) | ||
198 | |||
199 | /* Following are specific to S5PV210 */ | ||
200 | #define S5PV210_UCON_CLKMASK (1<<10) | ||
201 | #define S5PV210_UCON_CLKSHIFT (10) | ||
202 | #define S5PV210_UCON_PCLK (0<<10) | ||
203 | #define S5PV210_UCON_UCLK (1<<10) | ||
204 | |||
205 | #define S5PV210_UFCON_TXTRIG0 (0<<8) | ||
206 | #define S5PV210_UFCON_TXTRIG4 (1<<8) | ||
207 | #define S5PV210_UFCON_TXTRIG8 (2<<8) | ||
208 | #define S5PV210_UFCON_TXTRIG16 (3<<8) | ||
209 | #define S5PV210_UFCON_TXTRIG32 (4<<8) | ||
210 | #define S5PV210_UFCON_TXTRIG64 (5<<8) | ||
211 | #define S5PV210_UFCON_TXTRIG128 (6<<8) | ||
212 | #define S5PV210_UFCON_TXTRIG256 (7<<8) | ||
213 | |||
214 | #define S5PV210_UFCON_RXTRIG1 (0<<4) | ||
215 | #define S5PV210_UFCON_RXTRIG4 (1<<4) | ||
216 | #define S5PV210_UFCON_RXTRIG8 (2<<4) | ||
217 | #define S5PV210_UFCON_RXTRIG16 (3<<4) | ||
218 | #define S5PV210_UFCON_RXTRIG32 (4<<4) | ||
219 | #define S5PV210_UFCON_RXTRIG64 (5<<4) | ||
220 | #define S5PV210_UFCON_RXTRIG128 (6<<4) | ||
221 | #define S5PV210_UFCON_RXTRIG256 (7<<4) | ||
222 | |||
223 | #define S5PV210_UFSTAT_TXFULL (1<<24) | ||
224 | #define S5PV210_UFSTAT_RXFULL (1<<8) | ||
225 | #define S5PV210_UFSTAT_TXMASK (255<<16) | ||
226 | #define S5PV210_UFSTAT_TXSHIFT (16) | ||
227 | #define S5PV210_UFSTAT_RXMASK (255<<0) | ||
228 | #define S5PV210_UFSTAT_RXSHIFT (0) | ||
229 | |||
230 | #define S3C2410_UCON_CLKSEL0 (1 << 0) | ||
231 | #define S3C2410_UCON_CLKSEL1 (1 << 1) | ||
232 | #define S3C2410_UCON_CLKSEL2 (1 << 2) | ||
233 | #define S3C2410_UCON_CLKSEL3 (1 << 3) | ||
234 | |||
235 | /* Default values for s5pv210 UCON and UFCON uart registers */ | ||
236 | #define S5PV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ | ||
237 | S3C2410_UCON_RXILEVEL | \ | ||
238 | S3C2410_UCON_TXIRQMODE | \ | ||
239 | S3C2410_UCON_RXIRQMODE | \ | ||
240 | S3C2410_UCON_RXFIFO_TOI | \ | ||
241 | S3C2443_UCON_RXERR_IRQEN) | ||
242 | |||
243 | #define S5PV210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \ | ||
244 | S5PV210_UFCON_TXTRIG4 | \ | ||
245 | S5PV210_UFCON_RXTRIG4) | ||
246 | |||
247 | #ifndef __ASSEMBLY__ | ||
248 | |||
249 | /* configuration structure for per-machine configurations for the | ||
250 | * serial port | ||
251 | * | ||
252 | * the pointer is setup by the machine specific initialisation from the | ||
253 | * arch/arm/mach-s3c2410/ directory. | ||
254 | */ | ||
255 | |||
256 | struct s3c2410_uartcfg { | ||
257 | unsigned char hwport; /* hardware port number */ | ||
258 | unsigned char unused; | ||
259 | unsigned short flags; | ||
260 | upf_t uart_flags; /* default uart flags */ | ||
261 | unsigned int clk_sel; | ||
262 | |||
263 | unsigned int has_fracval; | ||
264 | |||
265 | unsigned long ucon; /* value of ucon for port */ | ||
266 | unsigned long ulcon; /* value of ulcon for port */ | ||
267 | unsigned long ufcon; /* value of ufcon for port */ | ||
268 | }; | ||
269 | |||
270 | /* s3c24xx_uart_devs | ||
271 | * | ||
272 | * this is exported from the core as we cannot use driver_register(), | ||
273 | * or platform_add_device() before the console_initcall() | ||
274 | */ | ||
275 | |||
276 | extern struct platform_device *s3c24xx_uart_devs[4]; | ||
277 | |||
278 | #endif /* __ASSEMBLY__ */ | ||
279 | |||
280 | #endif /* __ASM_ARM_REGS_SERIAL_H */ | ||
281 | |||
diff --git a/arch/arm/plat-samsung/include/plat/usb-phy.h b/arch/arm/plat-samsung/include/plat/usb-phy.h index 959bcdb03a25..ab34dfadb7f9 100644 --- a/arch/arm/plat-samsung/include/plat/usb-phy.h +++ b/arch/arm/plat-samsung/include/plat/usb-phy.h | |||
@@ -11,10 +11,7 @@ | |||
11 | #ifndef __PLAT_SAMSUNG_USB_PHY_H | 11 | #ifndef __PLAT_SAMSUNG_USB_PHY_H |
12 | #define __PLAT_SAMSUNG_USB_PHY_H __FILE__ | 12 | #define __PLAT_SAMSUNG_USB_PHY_H __FILE__ |
13 | 13 | ||
14 | enum s5p_usb_phy_type { | 14 | #include <linux/usb/samsung_usb_phy.h> |
15 | S5P_USB_PHY_DEVICE, | ||
16 | S5P_USB_PHY_HOST, | ||
17 | }; | ||
18 | 15 | ||
19 | extern int s5p_usb_phy_init(struct platform_device *pdev, int type); | 16 | extern int s5p_usb_phy_init(struct platform_device *pdev, int type); |
20 | extern int s5p_usb_phy_exit(struct platform_device *pdev, int type); | 17 | extern int s5p_usb_phy_exit(struct platform_device *pdev, int type); |
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 800aac306a08..f497ca77925a 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c | |||
@@ -197,24 +197,6 @@ void __init bootmem_init(void) | |||
197 | max_pfn = max_low_pfn = max; | 197 | max_pfn = max_low_pfn = max; |
198 | } | 198 | } |
199 | 199 | ||
200 | static inline int free_area(unsigned long pfn, unsigned long end, char *s) | ||
201 | { | ||
202 | unsigned int pages = 0, size = (end - pfn) << (PAGE_SHIFT - 10); | ||
203 | |||
204 | for (; pfn < end; pfn++) { | ||
205 | struct page *page = pfn_to_page(pfn); | ||
206 | ClearPageReserved(page); | ||
207 | init_page_count(page); | ||
208 | __free_page(page); | ||
209 | pages++; | ||
210 | } | ||
211 | |||
212 | if (size && s) | ||
213 | pr_info("Freeing %s memory: %dK\n", s, size); | ||
214 | |||
215 | return pages; | ||
216 | } | ||
217 | |||
218 | /* | 200 | /* |
219 | * Poison init memory with an undefined instruction (0x0). | 201 | * Poison init memory with an undefined instruction (0x0). |
220 | */ | 202 | */ |
@@ -405,9 +387,7 @@ void __init mem_init(void) | |||
405 | void free_initmem(void) | 387 | void free_initmem(void) |
406 | { | 388 | { |
407 | poison_init_mem(__init_begin, __init_end - __init_begin); | 389 | poison_init_mem(__init_begin, __init_end - __init_begin); |
408 | totalram_pages += free_area(__phys_to_pfn(__pa(__init_begin)), | 390 | free_initmem_default(0); |
409 | __phys_to_pfn(__pa(__init_end)), | ||
410 | "init"); | ||
411 | } | 391 | } |
412 | 392 | ||
413 | #ifdef CONFIG_BLK_DEV_INITRD | 393 | #ifdef CONFIG_BLK_DEV_INITRD |
@@ -418,9 +398,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) | |||
418 | { | 398 | { |
419 | if (!keep_initrd) { | 399 | if (!keep_initrd) { |
420 | poison_init_mem((void *)start, PAGE_ALIGN(end) - start); | 400 | poison_init_mem((void *)start, PAGE_ALIGN(end) - start); |
421 | totalram_pages += free_area(__phys_to_pfn(__pa(start)), | 401 | free_reserved_area(start, end, 0, "initrd"); |
422 | __phys_to_pfn(__pa(end)), | ||
423 | "initrd"); | ||
424 | } | 402 | } |
425 | } | 403 | } |
426 | 404 | ||
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 70b8cd4021c4..eeecc9c8ed68 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c | |||
@@ -391,17 +391,14 @@ int kern_addr_valid(unsigned long addr) | |||
391 | } | 391 | } |
392 | #ifdef CONFIG_SPARSEMEM_VMEMMAP | 392 | #ifdef CONFIG_SPARSEMEM_VMEMMAP |
393 | #ifdef CONFIG_ARM64_64K_PAGES | 393 | #ifdef CONFIG_ARM64_64K_PAGES |
394 | int __meminit vmemmap_populate(struct page *start_page, | 394 | int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) |
395 | unsigned long size, int node) | ||
396 | { | 395 | { |
397 | return vmemmap_populate_basepages(start_page, size, node); | 396 | return vmemmap_populate_basepages(start, end, node); |
398 | } | 397 | } |
399 | #else /* !CONFIG_ARM64_64K_PAGES */ | 398 | #else /* !CONFIG_ARM64_64K_PAGES */ |
400 | int __meminit vmemmap_populate(struct page *start_page, | 399 | int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) |
401 | unsigned long size, int node) | ||
402 | { | 400 | { |
403 | unsigned long addr = (unsigned long)start_page; | 401 | unsigned long addr = start; |
404 | unsigned long end = (unsigned long)(start_page + size); | ||
405 | unsigned long next; | 402 | unsigned long next; |
406 | pgd_t *pgd; | 403 | pgd_t *pgd; |
407 | pud_t *pud; | 404 | pud_t *pud; |
@@ -434,7 +431,7 @@ int __meminit vmemmap_populate(struct page *start_page, | |||
434 | return 0; | 431 | return 0; |
435 | } | 432 | } |
436 | #endif /* CONFIG_ARM64_64K_PAGES */ | 433 | #endif /* CONFIG_ARM64_64K_PAGES */ |
437 | void vmemmap_free(struct page *memmap, unsigned long nr_pages) | 434 | void vmemmap_free(unsigned long start, unsigned long end) |
438 | { | 435 | { |
439 | } | 436 | } |
440 | #endif /* CONFIG_SPARSEMEM_VMEMMAP */ | 437 | #endif /* CONFIG_SPARSEMEM_VMEMMAP */ |
diff --git a/arch/avr32/include/asm/io.h b/arch/avr32/include/asm/io.h index cf60d0a9f176..fc6483f83ccc 100644 --- a/arch/avr32/include/asm/io.h +++ b/arch/avr32/include/asm/io.h | |||
@@ -165,6 +165,10 @@ BUILDIO_IOPORT(l, u32) | |||
165 | #define readw_be __raw_readw | 165 | #define readw_be __raw_readw |
166 | #define readl_be __raw_readl | 166 | #define readl_be __raw_readl |
167 | 167 | ||
168 | #define writeb_relaxed writeb | ||
169 | #define writew_relaxed writew | ||
170 | #define writel_relaxed writel | ||
171 | |||
168 | #define writeb_be __raw_writeb | 172 | #define writeb_be __raw_writeb |
169 | #define writew_be __raw_writew | 173 | #define writew_be __raw_writew |
170 | #define writel_be __raw_writel | 174 | #define writel_be __raw_writel |
diff --git a/arch/avr32/mm/init.c b/arch/avr32/mm/init.c index 2798c2d4a1cf..e66e8406f992 100644 --- a/arch/avr32/mm/init.c +++ b/arch/avr32/mm/init.c | |||
@@ -146,34 +146,14 @@ void __init mem_init(void) | |||
146 | initsize >> 10); | 146 | initsize >> 10); |
147 | } | 147 | } |
148 | 148 | ||
149 | static inline void free_area(unsigned long addr, unsigned long end, char *s) | ||
150 | { | ||
151 | unsigned int size = (end - addr) >> 10; | ||
152 | |||
153 | for (; addr < end; addr += PAGE_SIZE) { | ||
154 | struct page *page = virt_to_page(addr); | ||
155 | ClearPageReserved(page); | ||
156 | init_page_count(page); | ||
157 | free_page(addr); | ||
158 | totalram_pages++; | ||
159 | } | ||
160 | |||
161 | if (size && s) | ||
162 | printk(KERN_INFO "Freeing %s memory: %dK (%lx - %lx)\n", | ||
163 | s, size, end - (size << 10), end); | ||
164 | } | ||
165 | |||
166 | void free_initmem(void) | 149 | void free_initmem(void) |
167 | { | 150 | { |
168 | free_area((unsigned long)__init_begin, (unsigned long)__init_end, | 151 | free_initmem_default(0); |
169 | "init"); | ||
170 | } | 152 | } |
171 | 153 | ||
172 | #ifdef CONFIG_BLK_DEV_INITRD | 154 | #ifdef CONFIG_BLK_DEV_INITRD |
173 | |||
174 | void free_initrd_mem(unsigned long start, unsigned long end) | 155 | void free_initrd_mem(unsigned long start, unsigned long end) |
175 | { | 156 | { |
176 | free_area(start, end, "initrd"); | 157 | free_reserved_area(start, end, 0, "initrd"); |
177 | } | 158 | } |
178 | |||
179 | #endif | 159 | #endif |
diff --git a/arch/blackfin/kernel/early_printk.c b/arch/blackfin/kernel/early_printk.c index 84ed8375113c..61fbd2de993d 100644 --- a/arch/blackfin/kernel/early_printk.c +++ b/arch/blackfin/kernel/early_printk.c | |||
@@ -25,8 +25,6 @@ extern struct console *bfin_earlyserial_init(unsigned int port, | |||
25 | extern struct console *bfin_jc_early_init(void); | 25 | extern struct console *bfin_jc_early_init(void); |
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | static struct console *early_console; | ||
29 | |||
30 | /* Default console */ | 28 | /* Default console */ |
31 | #define DEFAULT_PORT 0 | 29 | #define DEFAULT_PORT 0 |
32 | #define DEFAULT_CFLAG CS8|B57600 | 30 | #define DEFAULT_CFLAG CS8|B57600 |
diff --git a/arch/blackfin/mm/init.c b/arch/blackfin/mm/init.c index 9cb85537bd2b..82d01a71207f 100644 --- a/arch/blackfin/mm/init.c +++ b/arch/blackfin/mm/init.c | |||
@@ -103,7 +103,7 @@ void __init mem_init(void) | |||
103 | max_mapnr = num_physpages = MAP_NR(high_memory); | 103 | max_mapnr = num_physpages = MAP_NR(high_memory); |
104 | printk(KERN_DEBUG "Kernel managed physical pages: %lu\n", num_physpages); | 104 | printk(KERN_DEBUG "Kernel managed physical pages: %lu\n", num_physpages); |
105 | 105 | ||
106 | /* This will put all memory onto the freelists. */ | 106 | /* This will put all low memory onto the freelists. */ |
107 | totalram_pages = free_all_bootmem(); | 107 | totalram_pages = free_all_bootmem(); |
108 | 108 | ||
109 | reservedpages = 0; | 109 | reservedpages = 0; |
@@ -129,24 +129,11 @@ void __init mem_init(void) | |||
129 | initk, codek, datak, DMA_UNCACHED_REGION >> 10, (reservedpages << (PAGE_SHIFT-10))); | 129 | initk, codek, datak, DMA_UNCACHED_REGION >> 10, (reservedpages << (PAGE_SHIFT-10))); |
130 | } | 130 | } |
131 | 131 | ||
132 | static void __init free_init_pages(const char *what, unsigned long begin, unsigned long end) | ||
133 | { | ||
134 | unsigned long addr; | ||
135 | /* next to check that the page we free is not a partial page */ | ||
136 | for (addr = begin; addr + PAGE_SIZE <= end; addr += PAGE_SIZE) { | ||
137 | ClearPageReserved(virt_to_page(addr)); | ||
138 | init_page_count(virt_to_page(addr)); | ||
139 | free_page(addr); | ||
140 | totalram_pages++; | ||
141 | } | ||
142 | printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); | ||
143 | } | ||
144 | |||
145 | #ifdef CONFIG_BLK_DEV_INITRD | 132 | #ifdef CONFIG_BLK_DEV_INITRD |
146 | void __init free_initrd_mem(unsigned long start, unsigned long end) | 133 | void __init free_initrd_mem(unsigned long start, unsigned long end) |
147 | { | 134 | { |
148 | #ifndef CONFIG_MPU | 135 | #ifndef CONFIG_MPU |
149 | free_init_pages("initrd memory", start, end); | 136 | free_reserved_area(start, end, 0, "initrd"); |
150 | #endif | 137 | #endif |
151 | } | 138 | } |
152 | #endif | 139 | #endif |
@@ -154,10 +141,7 @@ void __init free_initrd_mem(unsigned long start, unsigned long end) | |||
154 | void __init_refok free_initmem(void) | 141 | void __init_refok free_initmem(void) |
155 | { | 142 | { |
156 | #if defined CONFIG_RAMKERNEL && !defined CONFIG_MPU | 143 | #if defined CONFIG_RAMKERNEL && !defined CONFIG_MPU |
157 | free_init_pages("unused kernel memory", | 144 | free_initmem_default(0); |
158 | (unsigned long)(&__init_begin), | ||
159 | (unsigned long)(&__init_end)); | ||
160 | |||
161 | if (memory_start == (unsigned long)(&__init_end)) | 145 | if (memory_start == (unsigned long)(&__init_end)) |
162 | memory_start = (unsigned long)(&__init_begin); | 146 | memory_start = (unsigned long)(&__init_begin); |
163 | #endif | 147 | #endif |
diff --git a/arch/c6x/include/asm/irqflags.h b/arch/c6x/include/asm/irqflags.h index cf78e09e18c3..2c71d5634ec2 100644 --- a/arch/c6x/include/asm/irqflags.h +++ b/arch/c6x/include/asm/irqflags.h | |||
@@ -27,7 +27,7 @@ static inline unsigned long arch_local_save_flags(void) | |||
27 | /* set interrupt enabled status */ | 27 | /* set interrupt enabled status */ |
28 | static inline void arch_local_irq_restore(unsigned long flags) | 28 | static inline void arch_local_irq_restore(unsigned long flags) |
29 | { | 29 | { |
30 | asm volatile (" mvc .s2 %0,CSR\n" : : "b"(flags)); | 30 | asm volatile (" mvc .s2 %0,CSR\n" : : "b"(flags) : "memory"); |
31 | } | 31 | } |
32 | 32 | ||
33 | /* unconditionally enable interrupts */ | 33 | /* unconditionally enable interrupts */ |
diff --git a/arch/c6x/mm/init.c b/arch/c6x/mm/init.c index 89395f09648a..a9fcd89b251b 100644 --- a/arch/c6x/mm/init.c +++ b/arch/c6x/mm/init.c | |||
@@ -77,37 +77,11 @@ void __init mem_init(void) | |||
77 | #ifdef CONFIG_BLK_DEV_INITRD | 77 | #ifdef CONFIG_BLK_DEV_INITRD |
78 | void __init free_initrd_mem(unsigned long start, unsigned long end) | 78 | void __init free_initrd_mem(unsigned long start, unsigned long end) |
79 | { | 79 | { |
80 | int pages = 0; | 80 | free_reserved_area(start, end, 0, "initrd"); |
81 | for (; start < end; start += PAGE_SIZE) { | ||
82 | ClearPageReserved(virt_to_page(start)); | ||
83 | init_page_count(virt_to_page(start)); | ||
84 | free_page(start); | ||
85 | totalram_pages++; | ||
86 | pages++; | ||
87 | } | ||
88 | printk(KERN_INFO "Freeing initrd memory: %luk freed\n", | ||
89 | (pages * PAGE_SIZE) >> 10); | ||
90 | } | 81 | } |
91 | #endif | 82 | #endif |
92 | 83 | ||
93 | void __init free_initmem(void) | 84 | void __init free_initmem(void) |
94 | { | 85 | { |
95 | unsigned long addr; | 86 | free_initmem_default(0); |
96 | |||
97 | /* | ||
98 | * The following code should be cool even if these sections | ||
99 | * are not page aligned. | ||
100 | */ | ||
101 | addr = PAGE_ALIGN((unsigned long)(__init_begin)); | ||
102 | |||
103 | /* next to check that the page we free is not a partial page */ | ||
104 | for (; addr + PAGE_SIZE < (unsigned long)(__init_end); | ||
105 | addr += PAGE_SIZE) { | ||
106 | ClearPageReserved(virt_to_page(addr)); | ||
107 | init_page_count(virt_to_page(addr)); | ||
108 | free_page(addr); | ||
109 | totalram_pages++; | ||
110 | } | ||
111 | printk(KERN_INFO "Freeing unused kernel memory: %dK freed\n", | ||
112 | (int) ((addr - PAGE_ALIGN((long) &__init_begin)) >> 10)); | ||
113 | } | 87 | } |
diff --git a/arch/cris/mm/init.c b/arch/cris/mm/init.c index d72ab58fd83e..9ac80946dada 100644 --- a/arch/cris/mm/init.c +++ b/arch/cris/mm/init.c | |||
@@ -12,12 +12,10 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/bootmem.h> | 13 | #include <linux/bootmem.h> |
14 | #include <asm/tlb.h> | 14 | #include <asm/tlb.h> |
15 | #include <asm/sections.h> | ||
15 | 16 | ||
16 | unsigned long empty_zero_page; | 17 | unsigned long empty_zero_page; |
17 | 18 | ||
18 | extern char _stext, _edata, _etext; /* From linkerscript */ | ||
19 | extern char __init_begin, __init_end; | ||
20 | |||
21 | void __init | 19 | void __init |
22 | mem_init(void) | 20 | mem_init(void) |
23 | { | 21 | { |
@@ -67,15 +65,5 @@ mem_init(void) | |||
67 | void | 65 | void |
68 | free_initmem(void) | 66 | free_initmem(void) |
69 | { | 67 | { |
70 | unsigned long addr; | 68 | free_initmem_default(0); |
71 | |||
72 | addr = (unsigned long)(&__init_begin); | ||
73 | for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { | ||
74 | ClearPageReserved(virt_to_page(addr)); | ||
75 | init_page_count(virt_to_page(addr)); | ||
76 | free_page(addr); | ||
77 | totalram_pages++; | ||
78 | } | ||
79 | printk (KERN_INFO "Freeing unused kernel memory: %luk freed\n", | ||
80 | (unsigned long)((&__init_end - &__init_begin) >> 10)); | ||
81 | } | 69 | } |
diff --git a/arch/frv/mm/init.c b/arch/frv/mm/init.c index 92e97b0894a6..dee354fa6b64 100644 --- a/arch/frv/mm/init.c +++ b/arch/frv/mm/init.c | |||
@@ -122,7 +122,7 @@ void __init mem_init(void) | |||
122 | #endif | 122 | #endif |
123 | int codek = 0, datak = 0; | 123 | int codek = 0, datak = 0; |
124 | 124 | ||
125 | /* this will put all memory onto the freelists */ | 125 | /* this will put all low memory onto the freelists */ |
126 | totalram_pages = free_all_bootmem(); | 126 | totalram_pages = free_all_bootmem(); |
127 | 127 | ||
128 | #ifdef CONFIG_MMU | 128 | #ifdef CONFIG_MMU |
@@ -131,14 +131,8 @@ void __init mem_init(void) | |||
131 | datapages++; | 131 | datapages++; |
132 | 132 | ||
133 | #ifdef CONFIG_HIGHMEM | 133 | #ifdef CONFIG_HIGHMEM |
134 | for (pfn = num_physpages - 1; pfn >= num_mappedpages; pfn--) { | 134 | for (pfn = num_physpages - 1; pfn >= num_mappedpages; pfn--) |
135 | struct page *page = &mem_map[pfn]; | 135 | free_highmem_page(&mem_map[pfn]); |
136 | |||
137 | ClearPageReserved(page); | ||
138 | init_page_count(page); | ||
139 | __free_page(page); | ||
140 | totalram_pages++; | ||
141 | } | ||
142 | #endif | 136 | #endif |
143 | 137 | ||
144 | codek = ((unsigned long) &_etext - (unsigned long) &_stext) >> 10; | 138 | codek = ((unsigned long) &_etext - (unsigned long) &_stext) >> 10; |
@@ -168,21 +162,7 @@ void __init mem_init(void) | |||
168 | void free_initmem(void) | 162 | void free_initmem(void) |
169 | { | 163 | { |
170 | #if defined(CONFIG_RAMKERNEL) && !defined(CONFIG_PROTECT_KERNEL) | 164 | #if defined(CONFIG_RAMKERNEL) && !defined(CONFIG_PROTECT_KERNEL) |
171 | unsigned long start, end, addr; | 165 | free_initmem_default(0); |
172 | |||
173 | start = PAGE_ALIGN((unsigned long) &__init_begin); /* round up */ | ||
174 | end = ((unsigned long) &__init_end) & PAGE_MASK; /* round down */ | ||
175 | |||
176 | /* next to check that the page we free is not a partial page */ | ||
177 | for (addr = start; addr < end; addr += PAGE_SIZE) { | ||
178 | ClearPageReserved(virt_to_page(addr)); | ||
179 | init_page_count(virt_to_page(addr)); | ||
180 | free_page(addr); | ||
181 | totalram_pages++; | ||
182 | } | ||
183 | |||
184 | printk("Freeing unused kernel memory: %ldKiB freed (0x%lx - 0x%lx)\n", | ||
185 | (end - start) >> 10, start, end); | ||
186 | #endif | 166 | #endif |
187 | } /* end free_initmem() */ | 167 | } /* end free_initmem() */ |
188 | 168 | ||
@@ -193,14 +173,6 @@ void free_initmem(void) | |||
193 | #ifdef CONFIG_BLK_DEV_INITRD | 173 | #ifdef CONFIG_BLK_DEV_INITRD |
194 | void __init free_initrd_mem(unsigned long start, unsigned long end) | 174 | void __init free_initrd_mem(unsigned long start, unsigned long end) |
195 | { | 175 | { |
196 | int pages = 0; | 176 | free_reserved_area(start, end, 0, "initrd"); |
197 | for (; start < end; start += PAGE_SIZE) { | ||
198 | ClearPageReserved(virt_to_page(start)); | ||
199 | init_page_count(virt_to_page(start)); | ||
200 | free_page(start); | ||
201 | totalram_pages++; | ||
202 | pages++; | ||
203 | } | ||
204 | printk("Freeing initrd memory: %dKiB freed\n", (pages * PAGE_SIZE) >> 10); | ||
205 | } /* end free_initrd_mem() */ | 177 | } /* end free_initrd_mem() */ |
206 | #endif | 178 | #endif |
diff --git a/arch/h8300/mm/init.c b/arch/h8300/mm/init.c index 981e25094b1a..ff349d70a29b 100644 --- a/arch/h8300/mm/init.c +++ b/arch/h8300/mm/init.c | |||
@@ -139,7 +139,7 @@ void __init mem_init(void) | |||
139 | start_mem = PAGE_ALIGN(start_mem); | 139 | start_mem = PAGE_ALIGN(start_mem); |
140 | max_mapnr = num_physpages = MAP_NR(high_memory); | 140 | max_mapnr = num_physpages = MAP_NR(high_memory); |
141 | 141 | ||
142 | /* this will put all memory onto the freelists */ | 142 | /* this will put all low memory onto the freelists */ |
143 | totalram_pages = free_all_bootmem(); | 143 | totalram_pages = free_all_bootmem(); |
144 | 144 | ||
145 | codek = (_etext - _stext) >> 10; | 145 | codek = (_etext - _stext) >> 10; |
@@ -161,15 +161,7 @@ void __init mem_init(void) | |||
161 | #ifdef CONFIG_BLK_DEV_INITRD | 161 | #ifdef CONFIG_BLK_DEV_INITRD |
162 | void free_initrd_mem(unsigned long start, unsigned long end) | 162 | void free_initrd_mem(unsigned long start, unsigned long end) |
163 | { | 163 | { |
164 | int pages = 0; | 164 | free_reserved_area(start, end, 0, "initrd"); |
165 | for (; start < end; start += PAGE_SIZE) { | ||
166 | ClearPageReserved(virt_to_page(start)); | ||
167 | init_page_count(virt_to_page(start)); | ||
168 | free_page(start); | ||
169 | totalram_pages++; | ||
170 | pages++; | ||
171 | } | ||
172 | printk ("Freeing initrd memory: %dk freed\n", pages); | ||
173 | } | 165 | } |
174 | #endif | 166 | #endif |
175 | 167 | ||
@@ -177,23 +169,7 @@ void | |||
177 | free_initmem(void) | 169 | free_initmem(void) |
178 | { | 170 | { |
179 | #ifdef CONFIG_RAMKERNEL | 171 | #ifdef CONFIG_RAMKERNEL |
180 | unsigned long addr; | 172 | free_initmem_default(0); |
181 | /* | ||
182 | * the following code should be cool even if these sections | ||
183 | * are not page aligned. | ||
184 | */ | ||
185 | addr = PAGE_ALIGN((unsigned long)(__init_begin)); | ||
186 | /* next to check that the page we free is not a partial page */ | ||
187 | for (; addr + PAGE_SIZE < (unsigned long)__init_end; addr +=PAGE_SIZE) { | ||
188 | ClearPageReserved(virt_to_page(addr)); | ||
189 | init_page_count(virt_to_page(addr)); | ||
190 | free_page(addr); | ||
191 | totalram_pages++; | ||
192 | } | ||
193 | printk(KERN_INFO "Freeing unused kernel memory: %ldk freed (0x%x - 0x%x)\n", | ||
194 | (addr - PAGE_ALIGN((long) __init_begin)) >> 10, | ||
195 | (int)(PAGE_ALIGN((unsigned long)__init_begin)), | ||
196 | (int)(addr - PAGE_SIZE)); | ||
197 | #endif | 173 | #endif |
198 | } | 174 | } |
199 | 175 | ||
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 9a02f71c6b1f..e7e55a00f94f 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
@@ -187,7 +187,7 @@ config IA64_DIG | |||
187 | 187 | ||
188 | config IA64_DIG_VTD | 188 | config IA64_DIG_VTD |
189 | bool "DIG+Intel+IOMMU" | 189 | bool "DIG+Intel+IOMMU" |
190 | select DMAR | 190 | select INTEL_IOMMU |
191 | select PCI_MSI | 191 | select PCI_MSI |
192 | 192 | ||
193 | config IA64_HP_ZX1 | 193 | config IA64_HP_ZX1 |
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index da2f319fb71d..e70cadec7ce6 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c | |||
@@ -142,8 +142,7 @@ static void transmit_chars(struct tty_struct *tty, struct serial_state *info, | |||
142 | goto out; | 142 | goto out; |
143 | } | 143 | } |
144 | 144 | ||
145 | if (info->xmit.head == info->xmit.tail || tty->stopped || | 145 | if (info->xmit.head == info->xmit.tail || tty->stopped) { |
146 | tty->hw_stopped) { | ||
147 | #ifdef SIMSERIAL_DEBUG | 146 | #ifdef SIMSERIAL_DEBUG |
148 | printk("transmit_chars: head=%d, tail=%d, stopped=%d\n", | 147 | printk("transmit_chars: head=%d, tail=%d, stopped=%d\n", |
149 | info->xmit.head, info->xmit.tail, tty->stopped); | 148 | info->xmit.head, info->xmit.tail, tty->stopped); |
@@ -181,7 +180,7 @@ static void rs_flush_chars(struct tty_struct *tty) | |||
181 | struct serial_state *info = tty->driver_data; | 180 | struct serial_state *info = tty->driver_data; |
182 | 181 | ||
183 | if (info->xmit.head == info->xmit.tail || tty->stopped || | 182 | if (info->xmit.head == info->xmit.tail || tty->stopped || |
184 | tty->hw_stopped || !info->xmit.buf) | 183 | !info->xmit.buf) |
185 | return; | 184 | return; |
186 | 185 | ||
187 | transmit_chars(tty, info, NULL); | 186 | transmit_chars(tty, info, NULL); |
@@ -217,7 +216,7 @@ static int rs_write(struct tty_struct * tty, | |||
217 | * Hey, we transmit directly from here in our case | 216 | * Hey, we transmit directly from here in our case |
218 | */ | 217 | */ |
219 | if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) && | 218 | if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) && |
220 | !tty->stopped && !tty->hw_stopped) | 219 | !tty->stopped) |
221 | transmit_chars(tty, info, NULL); | 220 | transmit_chars(tty, info, NULL); |
222 | 221 | ||
223 | return ret; | 222 | return ret; |
@@ -325,14 +324,6 @@ static int rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) | |||
325 | 324 | ||
326 | #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) | 325 | #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) |
327 | 326 | ||
328 | static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | ||
329 | { | ||
330 | /* Handle turning off CRTSCTS */ | ||
331 | if ((old_termios->c_cflag & CRTSCTS) && | ||
332 | !(tty->termios.c_cflag & CRTSCTS)) { | ||
333 | tty->hw_stopped = 0; | ||
334 | } | ||
335 | } | ||
336 | /* | 327 | /* |
337 | * This routine will shutdown a serial port; interrupts are disabled, and | 328 | * This routine will shutdown a serial port; interrupts are disabled, and |
338 | * DTR is dropped if the hangup on close termio flag is on. | 329 | * DTR is dropped if the hangup on close termio flag is on. |
@@ -481,7 +472,6 @@ static const struct tty_operations hp_ops = { | |||
481 | .throttle = rs_throttle, | 472 | .throttle = rs_throttle, |
482 | .unthrottle = rs_unthrottle, | 473 | .unthrottle = rs_unthrottle, |
483 | .send_xchar = rs_send_xchar, | 474 | .send_xchar = rs_send_xchar, |
484 | .set_termios = rs_set_termios, | ||
485 | .hangup = rs_hangup, | 475 | .hangup = rs_hangup, |
486 | .proc_fops = &rs_proc_fops, | 476 | .proc_fops = &rs_proc_fops, |
487 | }; | 477 | }; |
diff --git a/arch/ia64/include/asm/futex.h b/arch/ia64/include/asm/futex.h index d2bf1fd5e44f..76acbcd5c060 100644 --- a/arch/ia64/include/asm/futex.h +++ b/arch/ia64/include/asm/futex.h | |||
@@ -106,16 +106,15 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | |||
106 | return -EFAULT; | 106 | return -EFAULT; |
107 | 107 | ||
108 | { | 108 | { |
109 | register unsigned long r8 __asm ("r8"); | 109 | register unsigned long r8 __asm ("r8") = 0; |
110 | unsigned long prev; | 110 | unsigned long prev; |
111 | __asm__ __volatile__( | 111 | __asm__ __volatile__( |
112 | " mf;; \n" | 112 | " mf;; \n" |
113 | " mov %0=r0 \n" | ||
114 | " mov ar.ccv=%4;; \n" | 113 | " mov ar.ccv=%4;; \n" |
115 | "[1:] cmpxchg4.acq %1=[%2],%3,ar.ccv \n" | 114 | "[1:] cmpxchg4.acq %1=[%2],%3,ar.ccv \n" |
116 | " .xdata4 \"__ex_table\", 1b-., 2f-. \n" | 115 | " .xdata4 \"__ex_table\", 1b-., 2f-. \n" |
117 | "[2:]" | 116 | "[2:]" |
118 | : "=r" (r8), "=r" (prev) | 117 | : "+r" (r8), "=&r" (prev) |
119 | : "r" (uaddr), "r" (newval), | 118 | : "r" (uaddr), "r" (newval), |
120 | "rO" ((long) (unsigned) oldval) | 119 | "rO" ((long) (unsigned) oldval) |
121 | : "memory"); | 120 | : "memory"); |
diff --git a/arch/ia64/include/asm/hugetlb.h b/arch/ia64/include/asm/hugetlb.h index 94eaa5bd5d0c..aa910054b8e7 100644 --- a/arch/ia64/include/asm/hugetlb.h +++ b/arch/ia64/include/asm/hugetlb.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define _ASM_IA64_HUGETLB_H | 2 | #define _ASM_IA64_HUGETLB_H |
3 | 3 | ||
4 | #include <asm/page.h> | 4 | #include <asm/page.h> |
5 | #include <asm-generic/hugetlb.h> | ||
5 | 6 | ||
6 | 7 | ||
7 | void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr, | 8 | void hugetlb_free_pgd_range(struct mmu_gather *tlb, unsigned long addr, |
diff --git a/arch/ia64/include/asm/mca.h b/arch/ia64/include/asm/mca.h index 43f96ab18fa0..8c7096168716 100644 --- a/arch/ia64/include/asm/mca.h +++ b/arch/ia64/include/asm/mca.h | |||
@@ -143,6 +143,7 @@ extern unsigned long __per_cpu_mca[NR_CPUS]; | |||
143 | extern int cpe_vector; | 143 | extern int cpe_vector; |
144 | extern int ia64_cpe_irq; | 144 | extern int ia64_cpe_irq; |
145 | extern void ia64_mca_init(void); | 145 | extern void ia64_mca_init(void); |
146 | extern void ia64_mca_irq_init(void); | ||
146 | extern void ia64_mca_cpu_init(void *); | 147 | extern void ia64_mca_cpu_init(void *); |
147 | extern void ia64_os_mca_dispatch(void); | 148 | extern void ia64_os_mca_dispatch(void); |
148 | extern void ia64_os_mca_dispatch_end(void); | 149 | extern void ia64_os_mca_dispatch_end(void); |
diff --git a/arch/ia64/include/asm/numa.h b/arch/ia64/include/asm/numa.h index 2e27ef175652..2db0a6c6daa5 100644 --- a/arch/ia64/include/asm/numa.h +++ b/arch/ia64/include/asm/numa.h | |||
@@ -67,14 +67,13 @@ extern int paddr_to_nid(unsigned long paddr); | |||
67 | 67 | ||
68 | extern void map_cpu_to_node(int cpu, int nid); | 68 | extern void map_cpu_to_node(int cpu, int nid); |
69 | extern void unmap_cpu_from_node(int cpu, int nid); | 69 | extern void unmap_cpu_from_node(int cpu, int nid); |
70 | 70 | extern void numa_clear_node(int cpu); | |
71 | 71 | ||
72 | #else /* !CONFIG_NUMA */ | 72 | #else /* !CONFIG_NUMA */ |
73 | #define map_cpu_to_node(cpu, nid) do{}while(0) | 73 | #define map_cpu_to_node(cpu, nid) do{}while(0) |
74 | #define unmap_cpu_from_node(cpu, nid) do{}while(0) | 74 | #define unmap_cpu_from_node(cpu, nid) do{}while(0) |
75 | |||
76 | #define paddr_to_nid(addr) 0 | 75 | #define paddr_to_nid(addr) 0 |
77 | 76 | #define numa_clear_node(cpu) do { } while (0) | |
78 | #endif /* CONFIG_NUMA */ | 77 | #endif /* CONFIG_NUMA */ |
79 | 78 | ||
80 | #endif /* _ASM_IA64_NUMA_H */ | 79 | #endif /* _ASM_IA64_NUMA_H */ |
diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index c4cd45d97749..abc6dee3799c 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S | |||
@@ -90,53 +90,6 @@ ENTRY(fsys_getpid) | |||
90 | FSYS_RETURN | 90 | FSYS_RETURN |
91 | END(fsys_getpid) | 91 | END(fsys_getpid) |
92 | 92 | ||
93 | ENTRY(fsys_getppid) | ||
94 | .prologue | ||
95 | .altrp b6 | ||
96 | .body | ||
97 | add r17=IA64_TASK_GROUP_LEADER_OFFSET,r16 | ||
98 | ;; | ||
99 | ld8 r17=[r17] // r17 = current->group_leader | ||
100 | add r9=TI_FLAGS+IA64_TASK_SIZE,r16 | ||
101 | ;; | ||
102 | |||
103 | ld4 r9=[r9] | ||
104 | add r17=IA64_TASK_REAL_PARENT_OFFSET,r17 // r17 = ¤t->group_leader->real_parent | ||
105 | ;; | ||
106 | and r9=TIF_ALLWORK_MASK,r9 | ||
107 | |||
108 | 1: ld8 r18=[r17] // r18 = current->group_leader->real_parent | ||
109 | ;; | ||
110 | cmp.ne p8,p0=0,r9 | ||
111 | add r8=IA64_TASK_TGID_OFFSET,r18 // r8 = ¤t->group_leader->real_parent->tgid | ||
112 | ;; | ||
113 | |||
114 | /* | ||
115 | * The .acq is needed to ensure that the read of tgid has returned its data before | ||
116 | * we re-check "real_parent". | ||
117 | */ | ||
118 | ld4.acq r8=[r8] // r8 = current->group_leader->real_parent->tgid | ||
119 | #ifdef CONFIG_SMP | ||
120 | /* | ||
121 | * Re-read current->group_leader->real_parent. | ||
122 | */ | ||
123 | ld8 r19=[r17] // r19 = current->group_leader->real_parent | ||
124 | (p8) br.spnt.many fsys_fallback_syscall | ||
125 | ;; | ||
126 | cmp.ne p6,p0=r18,r19 // did real_parent change? | ||
127 | mov r19=0 // i must not leak kernel bits... | ||
128 | (p6) br.cond.spnt.few 1b // yes -> redo the read of tgid and the check | ||
129 | ;; | ||
130 | mov r17=0 // i must not leak kernel bits... | ||
131 | mov r18=0 // i must not leak kernel bits... | ||
132 | #else | ||
133 | mov r17=0 // i must not leak kernel bits... | ||
134 | mov r18=0 // i must not leak kernel bits... | ||
135 | mov r19=0 // i must not leak kernel bits... | ||
136 | #endif | ||
137 | FSYS_RETURN | ||
138 | END(fsys_getppid) | ||
139 | |||
140 | ENTRY(fsys_set_tid_address) | 93 | ENTRY(fsys_set_tid_address) |
141 | .prologue | 94 | .prologue |
142 | .altrp b6 | 95 | .altrp b6 |
@@ -614,7 +567,7 @@ paravirt_fsyscall_table: | |||
614 | data8 0 // chown | 567 | data8 0 // chown |
615 | data8 0 // lseek // 1040 | 568 | data8 0 // lseek // 1040 |
616 | data8 fsys_getpid // getpid | 569 | data8 fsys_getpid // getpid |
617 | data8 fsys_getppid // getppid | 570 | data8 0 // getppid |
618 | data8 0 // mount | 571 | data8 0 // mount |
619 | data8 0 // umount | 572 | data8 0 // umount |
620 | data8 0 // setuid // 1045 | 573 | data8 0 // setuid // 1045 |
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index ee33c3aaa2fc..19f107be734e 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c | |||
@@ -76,7 +76,7 @@ | |||
76 | * PCI pin -> global system interrupt (GSI) -> IA-64 vector <-> IRQ | 76 | * PCI pin -> global system interrupt (GSI) -> IA-64 vector <-> IRQ |
77 | * | 77 | * |
78 | * Note: The term "IRQ" is loosely used everywhere in Linux kernel to | 78 | * Note: The term "IRQ" is loosely used everywhere in Linux kernel to |
79 | * describeinterrupts. Now we use "IRQ" only for Linux IRQ's. ISA IRQ | 79 | * describe interrupts. Now we use "IRQ" only for Linux IRQ's. ISA IRQ |
80 | * (isa_irq) is the only exception in this source code. | 80 | * (isa_irq) is the only exception in this source code. |
81 | */ | 81 | */ |
82 | 82 | ||
@@ -1010,6 +1010,26 @@ iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver) | |||
1010 | return 0; | 1010 | return 0; |
1011 | } | 1011 | } |
1012 | 1012 | ||
1013 | static int | ||
1014 | iosapic_delete_rte(unsigned int irq, unsigned int gsi) | ||
1015 | { | ||
1016 | struct iosapic_rte_info *rte, *temp; | ||
1017 | |||
1018 | list_for_each_entry_safe(rte, temp, &iosapic_intr_info[irq].rtes, | ||
1019 | rte_list) { | ||
1020 | if (rte->iosapic->gsi_base + rte->rte_index == gsi) { | ||
1021 | if (rte->refcnt) | ||
1022 | return -EBUSY; | ||
1023 | |||
1024 | list_del(&rte->rte_list); | ||
1025 | kfree(rte); | ||
1026 | return 0; | ||
1027 | } | ||
1028 | } | ||
1029 | |||
1030 | return -EINVAL; | ||
1031 | } | ||
1032 | |||
1013 | int iosapic_init(unsigned long phys_addr, unsigned int gsi_base) | 1033 | int iosapic_init(unsigned long phys_addr, unsigned int gsi_base) |
1014 | { | 1034 | { |
1015 | int num_rte, err, index; | 1035 | int num_rte, err, index; |
@@ -1069,7 +1089,7 @@ int iosapic_init(unsigned long phys_addr, unsigned int gsi_base) | |||
1069 | 1089 | ||
1070 | int iosapic_remove(unsigned int gsi_base) | 1090 | int iosapic_remove(unsigned int gsi_base) |
1071 | { | 1091 | { |
1072 | int index, err = 0; | 1092 | int i, irq, index, err = 0; |
1073 | unsigned long flags; | 1093 | unsigned long flags; |
1074 | 1094 | ||
1075 | spin_lock_irqsave(&iosapic_lock, flags); | 1095 | spin_lock_irqsave(&iosapic_lock, flags); |
@@ -1087,6 +1107,16 @@ int iosapic_remove(unsigned int gsi_base) | |||
1087 | goto out; | 1107 | goto out; |
1088 | } | 1108 | } |
1089 | 1109 | ||
1110 | for (i = gsi_base; i < gsi_base + iosapic_lists[index].num_rte; i++) { | ||
1111 | irq = __gsi_to_irq(i); | ||
1112 | if (irq < 0) | ||
1113 | continue; | ||
1114 | |||
1115 | err = iosapic_delete_rte(irq, i); | ||
1116 | if (err) | ||
1117 | goto out; | ||
1118 | } | ||
1119 | |||
1090 | iounmap(iosapic_lists[index].addr); | 1120 | iounmap(iosapic_lists[index].addr); |
1091 | iosapic_free(index); | 1121 | iosapic_free(index); |
1092 | out: | 1122 | out: |
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c index ad69606613eb..f2c418281130 100644 --- a/arch/ia64/kernel/irq.c +++ b/arch/ia64/kernel/irq.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/kernel_stat.h> | 24 | #include <linux/kernel_stat.h> |
25 | 25 | ||
26 | #include <asm/mca.h> | ||
27 | |||
26 | /* | 28 | /* |
27 | * 'what should we do if we get a hw irq event on an illegal vector'. | 29 | * 'what should we do if we get a hw irq event on an illegal vector'. |
28 | * each architecture has to answer this themselves. | 30 | * each architecture has to answer this themselves. |
@@ -83,6 +85,12 @@ bool is_affinity_mask_valid(const struct cpumask *cpumask) | |||
83 | 85 | ||
84 | #endif /* CONFIG_SMP */ | 86 | #endif /* CONFIG_SMP */ |
85 | 87 | ||
88 | int __init arch_early_irq_init(void) | ||
89 | { | ||
90 | ia64_mca_irq_init(); | ||
91 | return 0; | ||
92 | } | ||
93 | |||
86 | #ifdef CONFIG_HOTPLUG_CPU | 94 | #ifdef CONFIG_HOTPLUG_CPU |
87 | unsigned int vectors_in_migration[NR_IRQS]; | 95 | unsigned int vectors_in_migration[NR_IRQS]; |
88 | 96 | ||
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c index 65bf9cd39044..d7396dbb07bb 100644 --- a/arch/ia64/kernel/mca.c +++ b/arch/ia64/kernel/mca.c | |||
@@ -2074,22 +2074,16 @@ ia64_mca_init(void) | |||
2074 | printk(KERN_INFO "MCA related initialization done\n"); | 2074 | printk(KERN_INFO "MCA related initialization done\n"); |
2075 | } | 2075 | } |
2076 | 2076 | ||
2077 | |||
2077 | /* | 2078 | /* |
2078 | * ia64_mca_late_init | 2079 | * These pieces cannot be done in ia64_mca_init() because it is called before |
2079 | * | 2080 | * early_irq_init() which would wipe out our percpu irq registrations. But we |
2080 | * Opportunity to setup things that require initialization later | 2081 | * cannot leave them until ia64_mca_late_init() because by then all the other |
2081 | * than ia64_mca_init. Setup a timer to poll for CPEs if the | 2082 | * processors have been brought online and have set their own CMC vectors to |
2082 | * platform doesn't support an interrupt driven mechanism. | 2083 | * point at a non-existant action. Called from arch_early_irq_init(). |
2083 | * | ||
2084 | * Inputs : None | ||
2085 | * Outputs : Status | ||
2086 | */ | 2084 | */ |
2087 | static int __init | 2085 | void __init ia64_mca_irq_init(void) |
2088 | ia64_mca_late_init(void) | ||
2089 | { | 2086 | { |
2090 | if (!mca_init) | ||
2091 | return 0; | ||
2092 | |||
2093 | /* | 2087 | /* |
2094 | * Configure the CMCI/P vector and handler. Interrupts for CMC are | 2088 | * Configure the CMCI/P vector and handler. Interrupts for CMC are |
2095 | * per-processor, so AP CMC interrupts are setup in smp_callin() (smpboot.c). | 2089 | * per-processor, so AP CMC interrupts are setup in smp_callin() (smpboot.c). |
@@ -2108,6 +2102,23 @@ ia64_mca_late_init(void) | |||
2108 | /* Setup the CPEI/P handler */ | 2102 | /* Setup the CPEI/P handler */ |
2109 | register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction); | 2103 | register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction); |
2110 | #endif | 2104 | #endif |
2105 | } | ||
2106 | |||
2107 | /* | ||
2108 | * ia64_mca_late_init | ||
2109 | * | ||
2110 | * Opportunity to setup things that require initialization later | ||
2111 | * than ia64_mca_init. Setup a timer to poll for CPEs if the | ||
2112 | * platform doesn't support an interrupt driven mechanism. | ||
2113 | * | ||
2114 | * Inputs : None | ||
2115 | * Outputs : Status | ||
2116 | */ | ||
2117 | static int __init | ||
2118 | ia64_mca_late_init(void) | ||
2119 | { | ||
2120 | if (!mca_init) | ||
2121 | return 0; | ||
2111 | 2122 | ||
2112 | register_hotcpu_notifier(&mca_cpu_notifier); | 2123 | register_hotcpu_notifier(&mca_cpu_notifier); |
2113 | 2124 | ||
diff --git a/arch/ia64/kernel/mca_drv.c b/arch/ia64/kernel/mca_drv.c index 9392e021c93b..94f8bf777afa 100644 --- a/arch/ia64/kernel/mca_drv.c +++ b/arch/ia64/kernel/mca_drv.c | |||
@@ -349,7 +349,7 @@ init_record_index_pools(void) | |||
349 | 349 | ||
350 | /* - 3 - */ | 350 | /* - 3 - */ |
351 | slidx_pool.max_idx = (rec_max_size/sect_min_size) * 2 + 1; | 351 | slidx_pool.max_idx = (rec_max_size/sect_min_size) * 2 + 1; |
352 | slidx_pool.buffer = (slidx_list_t *) | 352 | slidx_pool.buffer = |
353 | kmalloc(slidx_pool.max_idx * sizeof(slidx_list_t), GFP_KERNEL); | 353 | kmalloc(slidx_pool.max_idx * sizeof(slidx_list_t), GFP_KERNEL); |
354 | 354 | ||
355 | return slidx_pool.buffer ? 0 : -ENOMEM; | 355 | return slidx_pool.buffer ? 0 : -ENOMEM; |
diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c index 77597e5ea60a..79521d5499f9 100644 --- a/arch/ia64/kernel/palinfo.c +++ b/arch/ia64/kernel/palinfo.c | |||
@@ -849,17 +849,6 @@ static palinfo_entry_t palinfo_entries[]={ | |||
849 | 849 | ||
850 | #define NR_PALINFO_ENTRIES (int) ARRAY_SIZE(palinfo_entries) | 850 | #define NR_PALINFO_ENTRIES (int) ARRAY_SIZE(palinfo_entries) |
851 | 851 | ||
852 | /* | ||
853 | * this array is used to keep track of the proc entries we create. This is | ||
854 | * required in the module mode when we need to remove all entries. The procfs code | ||
855 | * does not do recursion of deletion | ||
856 | * | ||
857 | * Notes: | ||
858 | * - +1 accounts for the cpuN directory entry in /proc/pal | ||
859 | */ | ||
860 | #define NR_PALINFO_PROC_ENTRIES (NR_CPUS*(NR_PALINFO_ENTRIES+1)) | ||
861 | |||
862 | static struct proc_dir_entry *palinfo_proc_entries[NR_PALINFO_PROC_ENTRIES]; | ||
863 | static struct proc_dir_entry *palinfo_dir; | 852 | static struct proc_dir_entry *palinfo_dir; |
864 | 853 | ||
865 | /* | 854 | /* |
@@ -971,60 +960,32 @@ palinfo_read_entry(char *page, char **start, off_t off, int count, int *eof, voi | |||
971 | static void __cpuinit | 960 | static void __cpuinit |
972 | create_palinfo_proc_entries(unsigned int cpu) | 961 | create_palinfo_proc_entries(unsigned int cpu) |
973 | { | 962 | { |
974 | # define CPUSTR "cpu%d" | ||
975 | |||
976 | pal_func_cpu_u_t f; | 963 | pal_func_cpu_u_t f; |
977 | struct proc_dir_entry **pdir; | ||
978 | struct proc_dir_entry *cpu_dir; | 964 | struct proc_dir_entry *cpu_dir; |
979 | int j; | 965 | int j; |
980 | char cpustr[sizeof(CPUSTR)]; | 966 | char cpustr[3+4+1]; /* cpu numbers are up to 4095 on itanic */ |
981 | 967 | sprintf(cpustr, "cpu%d", cpu); | |
982 | |||
983 | /* | ||
984 | * we keep track of created entries in a depth-first order for | ||
985 | * cleanup purposes. Each entry is stored into palinfo_proc_entries | ||
986 | */ | ||
987 | sprintf(cpustr,CPUSTR, cpu); | ||
988 | 968 | ||
989 | cpu_dir = proc_mkdir(cpustr, palinfo_dir); | 969 | cpu_dir = proc_mkdir(cpustr, palinfo_dir); |
970 | if (!cpu_dir) | ||
971 | return; | ||
990 | 972 | ||
991 | f.req_cpu = cpu; | 973 | f.req_cpu = cpu; |
992 | 974 | ||
993 | /* | ||
994 | * Compute the location to store per cpu entries | ||
995 | * We dont store the top level entry in this list, but | ||
996 | * remove it finally after removing all cpu entries. | ||
997 | */ | ||
998 | pdir = &palinfo_proc_entries[cpu*(NR_PALINFO_ENTRIES+1)]; | ||
999 | *pdir++ = cpu_dir; | ||
1000 | for (j=0; j < NR_PALINFO_ENTRIES; j++) { | 975 | for (j=0; j < NR_PALINFO_ENTRIES; j++) { |
1001 | f.func_id = j; | 976 | f.func_id = j; |
1002 | *pdir = create_proc_read_entry( | 977 | create_proc_read_entry( |
1003 | palinfo_entries[j].name, 0, cpu_dir, | 978 | palinfo_entries[j].name, 0, cpu_dir, |
1004 | palinfo_read_entry, (void *)f.value); | 979 | palinfo_read_entry, (void *)f.value); |
1005 | pdir++; | ||
1006 | } | 980 | } |
1007 | } | 981 | } |
1008 | 982 | ||
1009 | static void | 983 | static void |
1010 | remove_palinfo_proc_entries(unsigned int hcpu) | 984 | remove_palinfo_proc_entries(unsigned int hcpu) |
1011 | { | 985 | { |
1012 | int j; | 986 | char cpustr[3+4+1]; /* cpu numbers are up to 4095 on itanic */ |
1013 | struct proc_dir_entry *cpu_dir, **pdir; | 987 | sprintf(cpustr, "cpu%d", hcpu); |
1014 | 988 | remove_proc_subtree(cpustr, palinfo_dir); | |
1015 | pdir = &palinfo_proc_entries[hcpu*(NR_PALINFO_ENTRIES+1)]; | ||
1016 | cpu_dir = *pdir; | ||
1017 | *pdir++=NULL; | ||
1018 | for (j=0; j < (NR_PALINFO_ENTRIES); j++) { | ||
1019 | if ((*pdir)) { | ||
1020 | remove_proc_entry ((*pdir)->name, cpu_dir); | ||
1021 | *pdir ++= NULL; | ||
1022 | } | ||
1023 | } | ||
1024 | |||
1025 | if (cpu_dir) { | ||
1026 | remove_proc_entry(cpu_dir->name, palinfo_dir); | ||
1027 | } | ||
1028 | } | 989 | } |
1029 | 990 | ||
1030 | static int __cpuinit palinfo_cpu_callback(struct notifier_block *nfb, | 991 | static int __cpuinit palinfo_cpu_callback(struct notifier_block *nfb, |
@@ -1058,6 +1019,8 @@ palinfo_init(void) | |||
1058 | 1019 | ||
1059 | printk(KERN_INFO "PAL Information Facility v%s\n", PALINFO_VERSION); | 1020 | printk(KERN_INFO "PAL Information Facility v%s\n", PALINFO_VERSION); |
1060 | palinfo_dir = proc_mkdir("pal", NULL); | 1021 | palinfo_dir = proc_mkdir("pal", NULL); |
1022 | if (!palinfo_dir) | ||
1023 | return -ENOMEM; | ||
1061 | 1024 | ||
1062 | /* Create palinfo dirs in /proc for all online cpus */ | 1025 | /* Create palinfo dirs in /proc for all online cpus */ |
1063 | for_each_online_cpu(i) { | 1026 | for_each_online_cpu(i) { |
@@ -1073,22 +1036,8 @@ palinfo_init(void) | |||
1073 | static void __exit | 1036 | static void __exit |
1074 | palinfo_exit(void) | 1037 | palinfo_exit(void) |
1075 | { | 1038 | { |
1076 | int i = 0; | ||
1077 | |||
1078 | /* remove all nodes: depth first pass. Could optimize this */ | ||
1079 | for_each_online_cpu(i) { | ||
1080 | remove_palinfo_proc_entries(i); | ||
1081 | } | ||
1082 | |||
1083 | /* | ||
1084 | * Remove the top level entry finally | ||
1085 | */ | ||
1086 | remove_proc_entry(palinfo_dir->name, NULL); | ||
1087 | |||
1088 | /* | ||
1089 | * Unregister from cpu notifier callbacks | ||
1090 | */ | ||
1091 | unregister_hotcpu_notifier(&palinfo_cpu_notifier); | 1039 | unregister_hotcpu_notifier(&palinfo_cpu_notifier); |
1040 | remove_proc_subtree("pal", NULL); | ||
1092 | } | 1041 | } |
1093 | 1042 | ||
1094 | module_init(palinfo_init); | 1043 | module_init(palinfo_init); |
diff --git a/arch/ia64/kvm/vtlb.c b/arch/ia64/kvm/vtlb.c index 4332f7ee5203..a7869f8f49a6 100644 --- a/arch/ia64/kvm/vtlb.c +++ b/arch/ia64/kvm/vtlb.c | |||
@@ -256,7 +256,7 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte) | |||
256 | "srlz.d;;" | 256 | "srlz.d;;" |
257 | "ssm psr.i;;" | 257 | "ssm psr.i;;" |
258 | "srlz.d;;" | 258 | "srlz.d;;" |
259 | : "=r"(ret) : "r"(iha), "r"(pte):"memory"); | 259 | : "=&r"(ret) : "r"(iha), "r"(pte) : "memory"); |
260 | 260 | ||
261 | return ret; | 261 | return ret; |
262 | } | 262 | } |
diff --git a/arch/ia64/mm/contig.c b/arch/ia64/mm/contig.c index 80dab509dfb0..67c59ebec899 100644 --- a/arch/ia64/mm/contig.c +++ b/arch/ia64/mm/contig.c | |||
@@ -47,6 +47,8 @@ void show_mem(unsigned int filter) | |||
47 | printk(KERN_INFO "Mem-info:\n"); | 47 | printk(KERN_INFO "Mem-info:\n"); |
48 | show_free_areas(filter); | 48 | show_free_areas(filter); |
49 | printk(KERN_INFO "Node memory in pages:\n"); | 49 | printk(KERN_INFO "Node memory in pages:\n"); |
50 | if (filter & SHOW_MEM_FILTER_PAGE_COUNT) | ||
51 | return; | ||
50 | for_each_online_pgdat(pgdat) { | 52 | for_each_online_pgdat(pgdat) { |
51 | unsigned long present; | 53 | unsigned long present; |
52 | unsigned long flags; | 54 | unsigned long flags; |
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c index c2e955ee79a8..ae4db4bd6d97 100644 --- a/arch/ia64/mm/discontig.c +++ b/arch/ia64/mm/discontig.c | |||
@@ -623,6 +623,8 @@ void show_mem(unsigned int filter) | |||
623 | 623 | ||
624 | printk(KERN_INFO "Mem-info:\n"); | 624 | printk(KERN_INFO "Mem-info:\n"); |
625 | show_free_areas(filter); | 625 | show_free_areas(filter); |
626 | if (filter & SHOW_MEM_FILTER_PAGE_COUNT) | ||
627 | return; | ||
626 | printk(KERN_INFO "Node memory in pages:\n"); | 628 | printk(KERN_INFO "Node memory in pages:\n"); |
627 | for_each_online_pgdat(pgdat) { | 629 | for_each_online_pgdat(pgdat) { |
628 | unsigned long present; | 630 | unsigned long present; |
@@ -817,13 +819,12 @@ void arch_refresh_nodedata(int update_node, pg_data_t *update_pgdat) | |||
817 | #endif | 819 | #endif |
818 | 820 | ||
819 | #ifdef CONFIG_SPARSEMEM_VMEMMAP | 821 | #ifdef CONFIG_SPARSEMEM_VMEMMAP |
820 | int __meminit vmemmap_populate(struct page *start_page, | 822 | int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) |
821 | unsigned long size, int node) | ||
822 | { | 823 | { |
823 | return vmemmap_populate_basepages(start_page, size, node); | 824 | return vmemmap_populate_basepages(start, end, node); |
824 | } | 825 | } |
825 | 826 | ||
826 | void vmemmap_free(struct page *memmap, unsigned long nr_pages) | 827 | void vmemmap_free(unsigned long start, unsigned long end) |
827 | { | 828 | { |
828 | } | 829 | } |
829 | #endif | 830 | #endif |
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 20bc967c7209..d1fe4b402601 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c | |||
@@ -154,25 +154,14 @@ ia64_init_addr_space (void) | |||
154 | void | 154 | void |
155 | free_initmem (void) | 155 | free_initmem (void) |
156 | { | 156 | { |
157 | unsigned long addr, eaddr; | 157 | free_reserved_area((unsigned long)ia64_imva(__init_begin), |
158 | 158 | (unsigned long)ia64_imva(__init_end), | |
159 | addr = (unsigned long) ia64_imva(__init_begin); | 159 | 0, "unused kernel"); |
160 | eaddr = (unsigned long) ia64_imva(__init_end); | ||
161 | while (addr < eaddr) { | ||
162 | ClearPageReserved(virt_to_page(addr)); | ||
163 | init_page_count(virt_to_page(addr)); | ||
164 | free_page(addr); | ||
165 | ++totalram_pages; | ||
166 | addr += PAGE_SIZE; | ||
167 | } | ||
168 | printk(KERN_INFO "Freeing unused kernel memory: %ldkB freed\n", | ||
169 | (__init_end - __init_begin) >> 10); | ||
170 | } | 160 | } |
171 | 161 | ||
172 | void __init | 162 | void __init |
173 | free_initrd_mem (unsigned long start, unsigned long end) | 163 | free_initrd_mem (unsigned long start, unsigned long end) |
174 | { | 164 | { |
175 | struct page *page; | ||
176 | /* | 165 | /* |
177 | * EFI uses 4KB pages while the kernel can use 4KB or bigger. | 166 | * EFI uses 4KB pages while the kernel can use 4KB or bigger. |
178 | * Thus EFI and the kernel may have different page sizes. It is | 167 | * Thus EFI and the kernel may have different page sizes. It is |
@@ -213,11 +202,7 @@ free_initrd_mem (unsigned long start, unsigned long end) | |||
213 | for (; start < end; start += PAGE_SIZE) { | 202 | for (; start < end; start += PAGE_SIZE) { |
214 | if (!virt_addr_valid(start)) | 203 | if (!virt_addr_valid(start)) |
215 | continue; | 204 | continue; |
216 | page = virt_to_page(start); | 205 | free_reserved_page(virt_to_page(start)); |
217 | ClearPageReserved(page); | ||
218 | init_page_count(page); | ||
219 | free_page(start); | ||
220 | ++totalram_pages; | ||
221 | } | 206 | } |
222 | } | 207 | } |
223 | 208 | ||
diff --git a/arch/ia64/mm/ioremap.c b/arch/ia64/mm/ioremap.c index 3dccdd8eb275..43964cde6214 100644 --- a/arch/ia64/mm/ioremap.c +++ b/arch/ia64/mm/ioremap.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include <asm/meminit.h> | 16 | #include <asm/meminit.h> |
17 | 17 | ||
18 | static inline void __iomem * | 18 | static inline void __iomem * |
19 | __ioremap (unsigned long phys_addr) | 19 | __ioremap_uc(unsigned long phys_addr) |
20 | { | 20 | { |
21 | return (void __iomem *) (__IA64_UNCACHED_OFFSET | phys_addr); | 21 | return (void __iomem *) (__IA64_UNCACHED_OFFSET | phys_addr); |
22 | } | 22 | } |
@@ -24,7 +24,11 @@ __ioremap (unsigned long phys_addr) | |||
24 | void __iomem * | 24 | void __iomem * |
25 | early_ioremap (unsigned long phys_addr, unsigned long size) | 25 | early_ioremap (unsigned long phys_addr, unsigned long size) |
26 | { | 26 | { |
27 | return __ioremap(phys_addr); | 27 | u64 attr; |
28 | attr = kern_mem_attribute(phys_addr, size); | ||
29 | if (attr & EFI_MEMORY_WB) | ||
30 | return (void __iomem *) phys_to_virt(phys_addr); | ||
31 | return __ioremap_uc(phys_addr); | ||
28 | } | 32 | } |
29 | 33 | ||
30 | void __iomem * | 34 | void __iomem * |
@@ -47,7 +51,7 @@ ioremap (unsigned long phys_addr, unsigned long size) | |||
47 | if (attr & EFI_MEMORY_WB) | 51 | if (attr & EFI_MEMORY_WB) |
48 | return (void __iomem *) phys_to_virt(phys_addr); | 52 | return (void __iomem *) phys_to_virt(phys_addr); |
49 | else if (attr & EFI_MEMORY_UC) | 53 | else if (attr & EFI_MEMORY_UC) |
50 | return __ioremap(phys_addr); | 54 | return __ioremap_uc(phys_addr); |
51 | 55 | ||
52 | /* | 56 | /* |
53 | * Some chipsets don't support UC access to memory. If | 57 | * Some chipsets don't support UC access to memory. If |
@@ -93,7 +97,7 @@ ioremap (unsigned long phys_addr, unsigned long size) | |||
93 | return (void __iomem *) (offset + (char __iomem *)addr); | 97 | return (void __iomem *) (offset + (char __iomem *)addr); |
94 | } | 98 | } |
95 | 99 | ||
96 | return __ioremap(phys_addr); | 100 | return __ioremap_uc(phys_addr); |
97 | } | 101 | } |
98 | EXPORT_SYMBOL(ioremap); | 102 | EXPORT_SYMBOL(ioremap); |
99 | 103 | ||
@@ -103,7 +107,7 @@ ioremap_nocache (unsigned long phys_addr, unsigned long size) | |||
103 | if (kern_mem_attribute(phys_addr, size) & EFI_MEMORY_WB) | 107 | if (kern_mem_attribute(phys_addr, size) & EFI_MEMORY_WB) |
104 | return NULL; | 108 | return NULL; |
105 | 109 | ||
106 | return __ioremap(phys_addr); | 110 | return __ioremap_uc(phys_addr); |
107 | } | 111 | } |
108 | EXPORT_SYMBOL(ioremap_nocache); | 112 | EXPORT_SYMBOL(ioremap_nocache); |
109 | 113 | ||
diff --git a/arch/ia64/mm/numa.c b/arch/ia64/mm/numa.c index 3efea7d0a351..4248492b9321 100644 --- a/arch/ia64/mm/numa.c +++ b/arch/ia64/mm/numa.c | |||
@@ -61,18 +61,36 @@ paddr_to_nid(unsigned long paddr) | |||
61 | int __meminit __early_pfn_to_nid(unsigned long pfn) | 61 | int __meminit __early_pfn_to_nid(unsigned long pfn) |
62 | { | 62 | { |
63 | int i, section = pfn >> PFN_SECTION_SHIFT, ssec, esec; | 63 | int i, section = pfn >> PFN_SECTION_SHIFT, ssec, esec; |
64 | /* | ||
65 | * NOTE: The following SMP-unsafe globals are only used early in boot | ||
66 | * when the kernel is running single-threaded. | ||
67 | */ | ||
68 | static int __meminitdata last_ssec, last_esec; | ||
69 | static int __meminitdata last_nid; | ||
70 | |||
71 | if (section >= last_ssec && section < last_esec) | ||
72 | return last_nid; | ||
64 | 73 | ||
65 | for (i = 0; i < num_node_memblks; i++) { | 74 | for (i = 0; i < num_node_memblks; i++) { |
66 | ssec = node_memblk[i].start_paddr >> PA_SECTION_SHIFT; | 75 | ssec = node_memblk[i].start_paddr >> PA_SECTION_SHIFT; |
67 | esec = (node_memblk[i].start_paddr + node_memblk[i].size + | 76 | esec = (node_memblk[i].start_paddr + node_memblk[i].size + |
68 | ((1L << PA_SECTION_SHIFT) - 1)) >> PA_SECTION_SHIFT; | 77 | ((1L << PA_SECTION_SHIFT) - 1)) >> PA_SECTION_SHIFT; |
69 | if (section >= ssec && section < esec) | 78 | if (section >= ssec && section < esec) { |
79 | last_ssec = ssec; | ||
80 | last_esec = esec; | ||
81 | last_nid = node_memblk[i].nid; | ||
70 | return node_memblk[i].nid; | 82 | return node_memblk[i].nid; |
83 | } | ||
71 | } | 84 | } |
72 | 85 | ||
73 | return -1; | 86 | return -1; |
74 | } | 87 | } |
75 | 88 | ||
89 | void __cpuinit numa_clear_node(int cpu) | ||
90 | { | ||
91 | unmap_cpu_from_node(cpu, NUMA_NO_NODE); | ||
92 | } | ||
93 | |||
76 | #ifdef CONFIG_MEMORY_HOTPLUG | 94 | #ifdef CONFIG_MEMORY_HOTPLUG |
77 | /* | 95 | /* |
78 | * SRAT information is stored in node_memblk[], then we can use SRAT | 96 | * SRAT information is stored in node_memblk[], then we can use SRAT |
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 60532ab27346..de1474ff0bc5 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
18 | #include <linux/pci-acpi.h> | ||
18 | #include <linux/init.h> | 19 | #include <linux/init.h> |
19 | #include <linux/ioport.h> | 20 | #include <linux/ioport.h> |
20 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
@@ -458,6 +459,16 @@ void pcibios_fixup_bus(struct pci_bus *b) | |||
458 | platform_pci_fixup_bus(b); | 459 | platform_pci_fixup_bus(b); |
459 | } | 460 | } |
460 | 461 | ||
462 | void pcibios_add_bus(struct pci_bus *bus) | ||
463 | { | ||
464 | acpi_pci_add_bus(bus); | ||
465 | } | ||
466 | |||
467 | void pcibios_remove_bus(struct pci_bus *bus) | ||
468 | { | ||
469 | acpi_pci_remove_bus(bus); | ||
470 | } | ||
471 | |||
461 | void pcibios_set_master (struct pci_dev *dev) | 472 | void pcibios_set_master (struct pci_dev *dev) |
462 | { | 473 | { |
463 | /* No special bus mastering setup handling */ | 474 | /* No special bus mastering setup handling */ |
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c index 14c1711238c0..e35f6485c1fd 100644 --- a/arch/ia64/sn/kernel/tiocx.c +++ b/arch/ia64/sn/kernel/tiocx.c | |||
@@ -490,11 +490,14 @@ static int __init tiocx_init(void) | |||
490 | { | 490 | { |
491 | cnodeid_t cnodeid; | 491 | cnodeid_t cnodeid; |
492 | int found_tiocx_device = 0; | 492 | int found_tiocx_device = 0; |
493 | int err; | ||
493 | 494 | ||
494 | if (!ia64_platform_is("sn2")) | 495 | if (!ia64_platform_is("sn2")) |
495 | return 0; | 496 | return 0; |
496 | 497 | ||
497 | bus_register(&tiocx_bus_type); | 498 | err = bus_register(&tiocx_bus_type); |
499 | if (err) | ||
500 | return err; | ||
498 | 501 | ||
499 | for (cnodeid = 0; cnodeid < num_cnodes; cnodeid++) { | 502 | for (cnodeid = 0; cnodeid < num_cnodes; cnodeid++) { |
500 | nasid_t nasid; | 503 | nasid_t nasid; |
diff --git a/arch/m32r/mm/init.c b/arch/m32r/mm/init.c index 78b660e903da..ab4cbce91a9b 100644 --- a/arch/m32r/mm/init.c +++ b/arch/m32r/mm/init.c | |||
@@ -28,10 +28,7 @@ | |||
28 | #include <asm/mmu_context.h> | 28 | #include <asm/mmu_context.h> |
29 | #include <asm/setup.h> | 29 | #include <asm/setup.h> |
30 | #include <asm/tlb.h> | 30 | #include <asm/tlb.h> |
31 | 31 | #include <asm/sections.h> | |
32 | /* References to section boundaries */ | ||
33 | extern char _text, _etext, _edata; | ||
34 | extern char __init_begin, __init_end; | ||
35 | 32 | ||
36 | pgd_t swapper_pg_dir[1024]; | 33 | pgd_t swapper_pg_dir[1024]; |
37 | 34 | ||
@@ -184,17 +181,7 @@ void __init mem_init(void) | |||
184 | *======================================================================*/ | 181 | *======================================================================*/ |
185 | void free_initmem(void) | 182 | void free_initmem(void) |
186 | { | 183 | { |
187 | unsigned long addr; | 184 | free_initmem_default(0); |
188 | |||
189 | addr = (unsigned long)(&__init_begin); | ||
190 | for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { | ||
191 | ClearPageReserved(virt_to_page(addr)); | ||
192 | init_page_count(virt_to_page(addr)); | ||
193 | free_page(addr); | ||
194 | totalram_pages++; | ||
195 | } | ||
196 | printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", \ | ||
197 | (int)(&__init_end - &__init_begin) >> 10); | ||
198 | } | 185 | } |
199 | 186 | ||
200 | #ifdef CONFIG_BLK_DEV_INITRD | 187 | #ifdef CONFIG_BLK_DEV_INITRD |
@@ -204,13 +191,6 @@ void free_initmem(void) | |||
204 | *======================================================================*/ | 191 | *======================================================================*/ |
205 | void free_initrd_mem(unsigned long start, unsigned long end) | 192 | void free_initrd_mem(unsigned long start, unsigned long end) |
206 | { | 193 | { |
207 | unsigned long p; | 194 | free_reserved_area(start, end, 0, "initrd"); |
208 | for (p = start; p < end; p += PAGE_SIZE) { | ||
209 | ClearPageReserved(virt_to_page(p)); | ||
210 | init_page_count(virt_to_page(p)); | ||
211 | free_page(p); | ||
212 | totalram_pages++; | ||
213 | } | ||
214 | printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10); | ||
215 | } | 195 | } |
216 | #endif | 196 | #endif |
diff --git a/arch/m68k/include/asm/gpio.h b/arch/m68k/include/asm/gpio.h index 4395ffc51fdb..8cc83431805b 100644 --- a/arch/m68k/include/asm/gpio.h +++ b/arch/m68k/include/asm/gpio.h | |||
@@ -86,4 +86,24 @@ static inline int gpio_cansleep(unsigned gpio) | |||
86 | return gpio < MCFGPIO_PIN_MAX ? 0 : __gpio_cansleep(gpio); | 86 | return gpio < MCFGPIO_PIN_MAX ? 0 : __gpio_cansleep(gpio); |
87 | } | 87 | } |
88 | 88 | ||
89 | static inline int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) | ||
90 | { | ||
91 | int err; | ||
92 | |||
93 | err = gpio_request(gpio, label); | ||
94 | if (err) | ||
95 | return err; | ||
96 | |||
97 | if (flags & GPIOF_DIR_IN) | ||
98 | err = gpio_direction_input(gpio); | ||
99 | else | ||
100 | err = gpio_direction_output(gpio, | ||
101 | (flags & GPIOF_INIT_HIGH) ? 1 : 0); | ||
102 | |||
103 | if (err) | ||
104 | gpio_free(gpio); | ||
105 | |||
106 | return err; | ||
107 | } | ||
108 | |||
89 | #endif | 109 | #endif |
diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c index 519aad8fa812..1af2ca3411f6 100644 --- a/arch/m68k/mm/init.c +++ b/arch/m68k/mm/init.c | |||
@@ -110,18 +110,7 @@ void __init paging_init(void) | |||
110 | void free_initmem(void) | 110 | void free_initmem(void) |
111 | { | 111 | { |
112 | #ifndef CONFIG_MMU_SUN3 | 112 | #ifndef CONFIG_MMU_SUN3 |
113 | unsigned long addr; | 113 | free_initmem_default(0); |
114 | |||
115 | addr = (unsigned long) __init_begin; | ||
116 | for (; addr < ((unsigned long) __init_end); addr += PAGE_SIZE) { | ||
117 | ClearPageReserved(virt_to_page(addr)); | ||
118 | init_page_count(virt_to_page(addr)); | ||
119 | free_page(addr); | ||
120 | totalram_pages++; | ||
121 | } | ||
122 | pr_notice("Freeing unused kernel memory: %luk freed (0x%x - 0x%x)\n", | ||
123 | (addr - (unsigned long) __init_begin) >> 10, | ||
124 | (unsigned int) __init_begin, (unsigned int) __init_end); | ||
125 | #endif /* CONFIG_MMU_SUN3 */ | 114 | #endif /* CONFIG_MMU_SUN3 */ |
126 | } | 115 | } |
127 | 116 | ||
@@ -213,15 +202,6 @@ void __init mem_init(void) | |||
213 | #ifdef CONFIG_BLK_DEV_INITRD | 202 | #ifdef CONFIG_BLK_DEV_INITRD |
214 | void free_initrd_mem(unsigned long start, unsigned long end) | 203 | void free_initrd_mem(unsigned long start, unsigned long end) |
215 | { | 204 | { |
216 | int pages = 0; | 205 | free_reserved_area(start, end, 0, "initrd"); |
217 | for (; start < end; start += PAGE_SIZE) { | ||
218 | ClearPageReserved(virt_to_page(start)); | ||
219 | init_page_count(virt_to_page(start)); | ||
220 | free_page(start); | ||
221 | totalram_pages++; | ||
222 | pages++; | ||
223 | } | ||
224 | pr_notice("Freeing initrd memory: %dk freed\n", | ||
225 | pages << (PAGE_SHIFT - 10)); | ||
226 | } | 206 | } |
227 | #endif | 207 | #endif |
diff --git a/arch/metag/mm/init.c b/arch/metag/mm/init.c index 504a398d5f8b..d05b8455c44c 100644 --- a/arch/metag/mm/init.c +++ b/arch/metag/mm/init.c | |||
@@ -380,14 +380,8 @@ void __init mem_init(void) | |||
380 | 380 | ||
381 | #ifdef CONFIG_HIGHMEM | 381 | #ifdef CONFIG_HIGHMEM |
382 | unsigned long tmp; | 382 | unsigned long tmp; |
383 | for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) { | 383 | for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) |
384 | struct page *page = pfn_to_page(tmp); | 384 | free_highmem_page(pfn_to_page(tmp)); |
385 | ClearPageReserved(page); | ||
386 | init_page_count(page); | ||
387 | __free_page(page); | ||
388 | totalhigh_pages++; | ||
389 | } | ||
390 | totalram_pages += totalhigh_pages; | ||
391 | num_physpages += totalhigh_pages; | 385 | num_physpages += totalhigh_pages; |
392 | #endif /* CONFIG_HIGHMEM */ | 386 | #endif /* CONFIG_HIGHMEM */ |
393 | 387 | ||
@@ -412,32 +406,15 @@ void __init mem_init(void) | |||
412 | return; | 406 | return; |
413 | } | 407 | } |
414 | 408 | ||
415 | static void free_init_pages(char *what, unsigned long begin, unsigned long end) | ||
416 | { | ||
417 | unsigned long addr; | ||
418 | |||
419 | for (addr = begin; addr < end; addr += PAGE_SIZE) { | ||
420 | ClearPageReserved(virt_to_page(addr)); | ||
421 | init_page_count(virt_to_page(addr)); | ||
422 | memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); | ||
423 | free_page(addr); | ||
424 | totalram_pages++; | ||
425 | } | ||
426 | pr_info("Freeing %s: %luk freed\n", what, (end - begin) >> 10); | ||
427 | } | ||
428 | |||
429 | void free_initmem(void) | 409 | void free_initmem(void) |
430 | { | 410 | { |
431 | free_init_pages("unused kernel memory", | 411 | free_initmem_default(POISON_FREE_INITMEM); |
432 | (unsigned long)(&__init_begin), | ||
433 | (unsigned long)(&__init_end)); | ||
434 | } | 412 | } |
435 | 413 | ||
436 | #ifdef CONFIG_BLK_DEV_INITRD | 414 | #ifdef CONFIG_BLK_DEV_INITRD |
437 | void free_initrd_mem(unsigned long start, unsigned long end) | 415 | void free_initrd_mem(unsigned long start, unsigned long end) |
438 | { | 416 | { |
439 | end = end & PAGE_MASK; | 417 | free_reserved_area(start, end, POISON_FREE_INITMEM, "initrd"); |
440 | free_init_pages("initrd memory", start, end); | ||
441 | } | 418 | } |
442 | #endif | 419 | #endif |
443 | 420 | ||
diff --git a/arch/microblaze/include/asm/setup.h b/arch/microblaze/include/asm/setup.h index 0e0b0a5ec756..f05df5630c84 100644 --- a/arch/microblaze/include/asm/setup.h +++ b/arch/microblaze/include/asm/setup.h | |||
@@ -46,7 +46,6 @@ void machine_shutdown(void); | |||
46 | void machine_halt(void); | 46 | void machine_halt(void); |
47 | void machine_power_off(void); | 47 | void machine_power_off(void); |
48 | 48 | ||
49 | void free_init_pages(char *what, unsigned long begin, unsigned long end); | ||
50 | extern void *alloc_maybe_bootmem(size_t size, gfp_t mask); | 49 | extern void *alloc_maybe_bootmem(size_t size, gfp_t mask); |
51 | extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask); | 50 | extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask); |
52 | 51 | ||
diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c index 60dcacc68038..365f2d53f1b2 100644 --- a/arch/microblaze/kernel/early_printk.c +++ b/arch/microblaze/kernel/early_printk.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <asm/setup.h> | 21 | #include <asm/setup.h> |
22 | #include <asm/prom.h> | 22 | #include <asm/prom.h> |
23 | 23 | ||
24 | static u32 early_console_initialized; | ||
25 | static u32 base_addr; | 24 | static u32 base_addr; |
26 | 25 | ||
27 | #ifdef CONFIG_SERIAL_UARTLITE_CONSOLE | 26 | #ifdef CONFIG_SERIAL_UARTLITE_CONSOLE |
@@ -109,27 +108,11 @@ static struct console early_serial_uart16550_console = { | |||
109 | }; | 108 | }; |
110 | #endif /* CONFIG_SERIAL_8250_CONSOLE */ | 109 | #endif /* CONFIG_SERIAL_8250_CONSOLE */ |
111 | 110 | ||
112 | static struct console *early_console; | ||
113 | |||
114 | void early_printk(const char *fmt, ...) | ||
115 | { | ||
116 | char buf[512]; | ||
117 | int n; | ||
118 | va_list ap; | ||
119 | |||
120 | if (early_console_initialized) { | ||
121 | va_start(ap, fmt); | ||
122 | n = vscnprintf(buf, 512, fmt, ap); | ||
123 | early_console->write(early_console, buf, n); | ||
124 | va_end(ap); | ||
125 | } | ||
126 | } | ||
127 | |||
128 | int __init setup_early_printk(char *opt) | 111 | int __init setup_early_printk(char *opt) |
129 | { | 112 | { |
130 | int version = 0; | 113 | int version = 0; |
131 | 114 | ||
132 | if (early_console_initialized) | 115 | if (early_console) |
133 | return 1; | 116 | return 1; |
134 | 117 | ||
135 | base_addr = of_early_console(&version); | 118 | base_addr = of_early_console(&version); |
@@ -159,7 +142,6 @@ int __init setup_early_printk(char *opt) | |||
159 | } | 142 | } |
160 | 143 | ||
161 | register_console(early_console); | 144 | register_console(early_console); |
162 | early_console_initialized = 1; | ||
163 | return 0; | 145 | return 0; |
164 | } | 146 | } |
165 | return 1; | 147 | return 1; |
@@ -169,7 +151,7 @@ int __init setup_early_printk(char *opt) | |||
169 | * only for early console because of performance degression */ | 151 | * only for early console because of performance degression */ |
170 | void __init remap_early_printk(void) | 152 | void __init remap_early_printk(void) |
171 | { | 153 | { |
172 | if (!early_console_initialized || !early_console) | 154 | if (!early_console) |
173 | return; | 155 | return; |
174 | pr_info("early_printk_console remapping from 0x%x to ", base_addr); | 156 | pr_info("early_printk_console remapping from 0x%x to ", base_addr); |
175 | base_addr = (u32) ioremap(base_addr, PAGE_SIZE); | 157 | base_addr = (u32) ioremap(base_addr, PAGE_SIZE); |
@@ -194,9 +176,9 @@ void __init remap_early_printk(void) | |||
194 | 176 | ||
195 | void __init disable_early_printk(void) | 177 | void __init disable_early_printk(void) |
196 | { | 178 | { |
197 | if (!early_console_initialized || !early_console) | 179 | if (!early_console) |
198 | return; | 180 | return; |
199 | pr_warn("disabling early console\n"); | 181 | pr_warn("disabling early console\n"); |
200 | unregister_console(early_console); | 182 | unregister_console(early_console); |
201 | early_console_initialized = 0; | 183 | early_console = NULL; |
202 | } | 184 | } |
diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c index 8f8b367c079e..4ec137d13ad7 100644 --- a/arch/microblaze/mm/init.c +++ b/arch/microblaze/mm/init.c | |||
@@ -82,13 +82,9 @@ static unsigned long highmem_setup(void) | |||
82 | /* FIXME not sure about */ | 82 | /* FIXME not sure about */ |
83 | if (memblock_is_reserved(pfn << PAGE_SHIFT)) | 83 | if (memblock_is_reserved(pfn << PAGE_SHIFT)) |
84 | continue; | 84 | continue; |
85 | ClearPageReserved(page); | 85 | free_highmem_page(page); |
86 | init_page_count(page); | ||
87 | __free_page(page); | ||
88 | totalhigh_pages++; | ||
89 | reservedpages++; | 86 | reservedpages++; |
90 | } | 87 | } |
91 | totalram_pages += totalhigh_pages; | ||
92 | pr_info("High memory: %luk\n", | 88 | pr_info("High memory: %luk\n", |
93 | totalhigh_pages << (PAGE_SHIFT-10)); | 89 | totalhigh_pages << (PAGE_SHIFT-10)); |
94 | 90 | ||
@@ -236,40 +232,16 @@ void __init setup_memory(void) | |||
236 | paging_init(); | 232 | paging_init(); |
237 | } | 233 | } |
238 | 234 | ||
239 | void free_init_pages(char *what, unsigned long begin, unsigned long end) | ||
240 | { | ||
241 | unsigned long addr; | ||
242 | |||
243 | for (addr = begin; addr < end; addr += PAGE_SIZE) { | ||
244 | ClearPageReserved(virt_to_page(addr)); | ||
245 | init_page_count(virt_to_page(addr)); | ||
246 | free_page(addr); | ||
247 | totalram_pages++; | ||
248 | } | ||
249 | pr_info("Freeing %s: %ldk freed\n", what, (end - begin) >> 10); | ||
250 | } | ||
251 | |||
252 | #ifdef CONFIG_BLK_DEV_INITRD | 235 | #ifdef CONFIG_BLK_DEV_INITRD |
253 | void free_initrd_mem(unsigned long start, unsigned long end) | 236 | void free_initrd_mem(unsigned long start, unsigned long end) |
254 | { | 237 | { |
255 | int pages = 0; | 238 | free_reserved_area(start, end, 0, "initrd"); |
256 | for (; start < end; start += PAGE_SIZE) { | ||
257 | ClearPageReserved(virt_to_page(start)); | ||
258 | init_page_count(virt_to_page(start)); | ||
259 | free_page(start); | ||
260 | totalram_pages++; | ||
261 | pages++; | ||
262 | } | ||
263 | pr_notice("Freeing initrd memory: %dk freed\n", | ||
264 | (int)(pages * (PAGE_SIZE / 1024))); | ||
265 | } | 239 | } |
266 | #endif | 240 | #endif |
267 | 241 | ||
268 | void free_initmem(void) | 242 | void free_initmem(void) |
269 | { | 243 | { |
270 | free_init_pages("unused kernel memory", | 244 | free_initmem_default(0); |
271 | (unsigned long)(&__init_begin), | ||
272 | (unsigned long)(&__init_end)); | ||
273 | } | 245 | } |
274 | 246 | ||
275 | void __init mem_init(void) | 247 | void __init mem_init(void) |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 51244bf97271..3a7b3954ce1b 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -404,6 +404,8 @@ config PMC_MSP | |||
404 | select IRQ_CPU | 404 | select IRQ_CPU |
405 | select SERIAL_8250 | 405 | select SERIAL_8250 |
406 | select SERIAL_8250_CONSOLE | 406 | select SERIAL_8250_CONSOLE |
407 | select USB_EHCI_BIG_ENDIAN_MMIO | ||
408 | select USB_EHCI_BIG_ENDIAN_DESC | ||
407 | help | 409 | help |
408 | This adds support for the PMC-Sierra family of Multi-Service | 410 | This adds support for the PMC-Sierra family of Multi-Service |
409 | Processor System-On-A-Chips. These parts include a number | 411 | Processor System-On-A-Chips. These parts include a number |
@@ -1433,6 +1435,7 @@ config CPU_CAVIUM_OCTEON | |||
1433 | select CPU_SUPPORTS_HUGEPAGES | 1435 | select CPU_SUPPORTS_HUGEPAGES |
1434 | select LIBFDT | 1436 | select LIBFDT |
1435 | select USE_OF | 1437 | select USE_OF |
1438 | select USB_EHCI_BIG_ENDIAN_MMIO | ||
1436 | help | 1439 | help |
1437 | The Cavium Octeon processor is a highly integrated chip containing | 1440 | The Cavium Octeon processor is a highly integrated chip containing |
1438 | many ethernet hardware widgets for networking tasks. The processor | 1441 | many ethernet hardware widgets for networking tasks. The processor |
diff --git a/arch/mips/bcm63xx/dev-spi.c b/arch/mips/bcm63xx/dev-spi.c index f1c9c3e2f678..e97fd60e92ef 100644 --- a/arch/mips/bcm63xx/dev-spi.c +++ b/arch/mips/bcm63xx/dev-spi.c | |||
@@ -85,20 +85,9 @@ static struct platform_device bcm63xx_spi_device = { | |||
85 | 85 | ||
86 | int __init bcm63xx_spi_register(void) | 86 | int __init bcm63xx_spi_register(void) |
87 | { | 87 | { |
88 | struct clk *periph_clk; | ||
89 | |||
90 | if (BCMCPU_IS_6328() || BCMCPU_IS_6345()) | 88 | if (BCMCPU_IS_6328() || BCMCPU_IS_6345()) |
91 | return -ENODEV; | 89 | return -ENODEV; |
92 | 90 | ||
93 | periph_clk = clk_get(NULL, "periph"); | ||
94 | if (IS_ERR(periph_clk)) { | ||
95 | pr_err("unable to get periph clock\n"); | ||
96 | return -ENODEV; | ||
97 | } | ||
98 | |||
99 | /* Set bus frequency */ | ||
100 | spi_pdata.speed_hz = clk_get_rate(periph_clk); | ||
101 | |||
102 | spi_resources[0].start = bcm63xx_regset_address(RSET_SPI); | 91 | spi_resources[0].start = bcm63xx_regset_address(RSET_SPI); |
103 | spi_resources[0].end = spi_resources[0].start; | 92 | spi_resources[0].end = spi_resources[0].start; |
104 | spi_resources[1].start = bcm63xx_get_irq_number(IRQ_SPI); | 93 | spi_resources[1].start = bcm63xx_get_irq_number(IRQ_SPI); |
diff --git a/arch/mips/include/asm/hugetlb.h b/arch/mips/include/asm/hugetlb.h index ef99db994c2f..fe0d15d32660 100644 --- a/arch/mips/include/asm/hugetlb.h +++ b/arch/mips/include/asm/hugetlb.h | |||
@@ -10,6 +10,7 @@ | |||
10 | #define __ASM_HUGETLB_H | 10 | #define __ASM_HUGETLB_H |
11 | 11 | ||
12 | #include <asm/page.h> | 12 | #include <asm/page.h> |
13 | #include <asm-generic/hugetlb.h> | ||
13 | 14 | ||
14 | 15 | ||
15 | static inline int is_hugepage_only_range(struct mm_struct *mm, | 16 | static inline int is_hugepage_only_range(struct mm_struct *mm, |
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h index c9bae1362606..b0184cf02575 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h | |||
@@ -13,7 +13,6 @@ struct bcm63xx_spi_pdata { | |||
13 | unsigned int msg_ctl_width; | 13 | unsigned int msg_ctl_width; |
14 | int bus_num; | 14 | int bus_num; |
15 | int num_chipselect; | 15 | int num_chipselect; |
16 | u32 speed_hz; | ||
17 | }; | 16 | }; |
18 | 17 | ||
19 | enum bcm63xx_regs_spi { | 18 | enum bcm63xx_regs_spi { |
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h index 99fc547af9d3..eab99e536b5c 100644 --- a/arch/mips/include/asm/page.h +++ b/arch/mips/include/asm/page.h | |||
@@ -31,7 +31,7 @@ | |||
31 | #define PAGE_SHIFT 16 | 31 | #define PAGE_SHIFT 16 |
32 | #endif | 32 | #endif |
33 | #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) | 33 | #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) |
34 | #define PAGE_MASK (~(PAGE_SIZE - 1)) | 34 | #define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) |
35 | 35 | ||
36 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT | 36 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT |
37 | #define HPAGE_SHIFT (PAGE_SHIFT + PAGE_SHIFT - 3) | 37 | #define HPAGE_SHIFT (PAGE_SHIFT + PAGE_SHIFT - 3) |
diff --git a/arch/mips/kernel/early_printk.c b/arch/mips/kernel/early_printk.c index 9e6440eaa455..505cb77d1280 100644 --- a/arch/mips/kernel/early_printk.c +++ b/arch/mips/kernel/early_printk.c | |||
@@ -7,7 +7,9 @@ | |||
7 | * Copyright (C) 2007 MIPS Technologies, Inc. | 7 | * Copyright (C) 2007 MIPS Technologies, Inc. |
8 | * written by Ralf Baechle (ralf@linux-mips.org) | 8 | * written by Ralf Baechle (ralf@linux-mips.org) |
9 | */ | 9 | */ |
10 | #include <linux/kernel.h> | ||
10 | #include <linux/console.h> | 11 | #include <linux/console.h> |
12 | #include <linux/printk.h> | ||
11 | #include <linux/init.h> | 13 | #include <linux/init.h> |
12 | 14 | ||
13 | #include <asm/setup.h> | 15 | #include <asm/setup.h> |
@@ -24,20 +26,18 @@ static void early_console_write(struct console *con, const char *s, unsigned n) | |||
24 | } | 26 | } |
25 | } | 27 | } |
26 | 28 | ||
27 | static struct console early_console = { | 29 | static struct console early_console_prom = { |
28 | .name = "early", | 30 | .name = "early", |
29 | .write = early_console_write, | 31 | .write = early_console_write, |
30 | .flags = CON_PRINTBUFFER | CON_BOOT, | 32 | .flags = CON_PRINTBUFFER | CON_BOOT, |
31 | .index = -1 | 33 | .index = -1 |
32 | }; | 34 | }; |
33 | 35 | ||
34 | static int early_console_initialized __initdata; | ||
35 | |||
36 | void __init setup_early_printk(void) | 36 | void __init setup_early_printk(void) |
37 | { | 37 | { |
38 | if (early_console_initialized) | 38 | if (early_console) |
39 | return; | 39 | return; |
40 | early_console_initialized = 1; | 40 | early_console = &early_console_prom; |
41 | 41 | ||
42 | register_console(&early_console); | 42 | register_console(&early_console_prom); |
43 | } | 43 | } |
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 67929251286c..3d0346dbccf4 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
@@ -77,10 +77,9 @@ EXPORT_SYMBOL_GPL(empty_zero_page); | |||
77 | /* | 77 | /* |
78 | * Not static inline because used by IP27 special magic initialization code | 78 | * Not static inline because used by IP27 special magic initialization code |
79 | */ | 79 | */ |
80 | unsigned long setup_zero_pages(void) | 80 | void setup_zero_pages(void) |
81 | { | 81 | { |
82 | unsigned int order; | 82 | unsigned int order, i; |
83 | unsigned long size; | ||
84 | struct page *page; | 83 | struct page *page; |
85 | 84 | ||
86 | if (cpu_has_vce) | 85 | if (cpu_has_vce) |
@@ -94,15 +93,10 @@ unsigned long setup_zero_pages(void) | |||
94 | 93 | ||
95 | page = virt_to_page((void *)empty_zero_page); | 94 | page = virt_to_page((void *)empty_zero_page); |
96 | split_page(page, order); | 95 | split_page(page, order); |
97 | while (page < virt_to_page((void *)(empty_zero_page + (PAGE_SIZE << order)))) { | 96 | for (i = 0; i < (1 << order); i++, page++) |
98 | SetPageReserved(page); | 97 | mark_page_reserved(page); |
99 | page++; | ||
100 | } | ||
101 | |||
102 | size = PAGE_SIZE << order; | ||
103 | zero_page_mask = (size - 1) & PAGE_MASK; | ||
104 | 98 | ||
105 | return 1UL << order; | 99 | zero_page_mask = ((PAGE_SIZE << order) - 1) & PAGE_MASK; |
106 | } | 100 | } |
107 | 101 | ||
108 | #ifdef CONFIG_MIPS_MT_SMTC | 102 | #ifdef CONFIG_MIPS_MT_SMTC |
@@ -380,7 +374,7 @@ void __init mem_init(void) | |||
380 | high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); | 374 | high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); |
381 | 375 | ||
382 | totalram_pages += free_all_bootmem(); | 376 | totalram_pages += free_all_bootmem(); |
383 | totalram_pages -= setup_zero_pages(); /* Setup zeroed pages. */ | 377 | setup_zero_pages(); /* Setup zeroed pages. */ |
384 | 378 | ||
385 | reservedpages = ram = 0; | 379 | reservedpages = ram = 0; |
386 | for (tmp = 0; tmp < max_low_pfn; tmp++) | 380 | for (tmp = 0; tmp < max_low_pfn; tmp++) |
@@ -399,12 +393,8 @@ void __init mem_init(void) | |||
399 | SetPageReserved(page); | 393 | SetPageReserved(page); |
400 | continue; | 394 | continue; |
401 | } | 395 | } |
402 | ClearPageReserved(page); | 396 | free_highmem_page(page); |
403 | init_page_count(page); | ||
404 | __free_page(page); | ||
405 | totalhigh_pages++; | ||
406 | } | 397 | } |
407 | totalram_pages += totalhigh_pages; | ||
408 | num_physpages += totalhigh_pages; | 398 | num_physpages += totalhigh_pages; |
409 | #endif | 399 | #endif |
410 | 400 | ||
@@ -440,11 +430,8 @@ void free_init_pages(const char *what, unsigned long begin, unsigned long end) | |||
440 | struct page *page = pfn_to_page(pfn); | 430 | struct page *page = pfn_to_page(pfn); |
441 | void *addr = phys_to_virt(PFN_PHYS(pfn)); | 431 | void *addr = phys_to_virt(PFN_PHYS(pfn)); |
442 | 432 | ||
443 | ClearPageReserved(page); | ||
444 | init_page_count(page); | ||
445 | memset(addr, POISON_FREE_INITMEM, PAGE_SIZE); | 433 | memset(addr, POISON_FREE_INITMEM, PAGE_SIZE); |
446 | __free_page(page); | 434 | free_reserved_page(page); |
447 | totalram_pages++; | ||
448 | } | 435 | } |
449 | printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); | 436 | printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); |
450 | } | 437 | } |
@@ -452,18 +439,14 @@ void free_init_pages(const char *what, unsigned long begin, unsigned long end) | |||
452 | #ifdef CONFIG_BLK_DEV_INITRD | 439 | #ifdef CONFIG_BLK_DEV_INITRD |
453 | void free_initrd_mem(unsigned long start, unsigned long end) | 440 | void free_initrd_mem(unsigned long start, unsigned long end) |
454 | { | 441 | { |
455 | free_init_pages("initrd memory", | 442 | free_reserved_area(start, end, POISON_FREE_INITMEM, "initrd"); |
456 | virt_to_phys((void *)start), | ||
457 | virt_to_phys((void *)end)); | ||
458 | } | 443 | } |
459 | #endif | 444 | #endif |
460 | 445 | ||
461 | void __init_refok free_initmem(void) | 446 | void __init_refok free_initmem(void) |
462 | { | 447 | { |
463 | prom_free_prom_memory(); | 448 | prom_free_prom_memory(); |
464 | free_init_pages("unused kernel memory", | 449 | free_initmem_default(POISON_FREE_INITMEM); |
465 | __pa_symbol(&__init_begin), | ||
466 | __pa_symbol(&__init_end)); | ||
467 | } | 450 | } |
468 | 451 | ||
469 | #ifndef CONFIG_MIPS_PGD_C0_CONTEXT | 452 | #ifndef CONFIG_MIPS_PGD_C0_CONTEXT |
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 0872f12f268d..594e60d6a43b 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c | |||
@@ -115,7 +115,6 @@ static void pcibios_scanbus(struct pci_controller *hose) | |||
115 | pci_bus_assign_resources(bus); | 115 | pci_bus_assign_resources(bus); |
116 | pci_enable_bridges(bus); | 116 | pci_enable_bridges(bus); |
117 | } | 117 | } |
118 | bus->dev.of_node = hose->of_node; | ||
119 | } | 118 | } |
120 | } | 119 | } |
121 | 120 | ||
@@ -169,6 +168,13 @@ void pci_load_of_ranges(struct pci_controller *hose, struct device_node *node) | |||
169 | } | 168 | } |
170 | } | 169 | } |
171 | } | 170 | } |
171 | |||
172 | struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus) | ||
173 | { | ||
174 | struct pci_controller *hose = bus->sysdata; | ||
175 | |||
176 | return of_node_get(hose->of_node); | ||
177 | } | ||
172 | #endif | 178 | #endif |
173 | 179 | ||
174 | static DEFINE_MUTEX(pci_scan_mutex); | 180 | static DEFINE_MUTEX(pci_scan_mutex); |
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c index 3505d08ff2fd..5f2bddb1860e 100644 --- a/arch/mips/sgi-ip27/ip27-memory.c +++ b/arch/mips/sgi-ip27/ip27-memory.c | |||
@@ -457,7 +457,7 @@ void __init prom_free_prom_memory(void) | |||
457 | /* We got nothing to free here ... */ | 457 | /* We got nothing to free here ... */ |
458 | } | 458 | } |
459 | 459 | ||
460 | extern unsigned long setup_zero_pages(void); | 460 | extern void setup_zero_pages(void); |
461 | 461 | ||
462 | void __init paging_init(void) | 462 | void __init paging_init(void) |
463 | { | 463 | { |
@@ -492,7 +492,7 @@ void __init mem_init(void) | |||
492 | totalram_pages += free_all_bootmem_node(NODE_DATA(node)); | 492 | totalram_pages += free_all_bootmem_node(NODE_DATA(node)); |
493 | } | 493 | } |
494 | 494 | ||
495 | totalram_pages -= setup_zero_pages(); /* This comes from node 0 */ | 495 | setup_zero_pages(); /* This comes from node 0 */ |
496 | 496 | ||
497 | codesize = (unsigned long) &_etext - (unsigned long) &_text; | 497 | codesize = (unsigned long) &_etext - (unsigned long) &_text; |
498 | datasize = (unsigned long) &_edata - (unsigned long) &_etext; | 498 | datasize = (unsigned long) &_edata - (unsigned long) &_etext; |
diff --git a/arch/mn10300/mm/init.c b/arch/mn10300/mm/init.c index e57e5bc23562..5a8ace63a6b4 100644 --- a/arch/mn10300/mm/init.c +++ b/arch/mn10300/mm/init.c | |||
@@ -139,30 +139,11 @@ void __init mem_init(void) | |||
139 | } | 139 | } |
140 | 140 | ||
141 | /* | 141 | /* |
142 | * | ||
143 | */ | ||
144 | void free_init_pages(char *what, unsigned long begin, unsigned long end) | ||
145 | { | ||
146 | unsigned long addr; | ||
147 | |||
148 | for (addr = begin; addr < end; addr += PAGE_SIZE) { | ||
149 | ClearPageReserved(virt_to_page(addr)); | ||
150 | init_page_count(virt_to_page(addr)); | ||
151 | memset((void *) addr, 0xcc, PAGE_SIZE); | ||
152 | free_page(addr); | ||
153 | totalram_pages++; | ||
154 | } | ||
155 | printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); | ||
156 | } | ||
157 | |||
158 | /* | ||
159 | * recycle memory containing stuff only required for initialisation | 142 | * recycle memory containing stuff only required for initialisation |
160 | */ | 143 | */ |
161 | void free_initmem(void) | 144 | void free_initmem(void) |
162 | { | 145 | { |
163 | free_init_pages("unused kernel memory", | 146 | free_initmem_default(POISON_FREE_INITMEM); |
164 | (unsigned long) &__init_begin, | ||
165 | (unsigned long) &__init_end); | ||
166 | } | 147 | } |
167 | 148 | ||
168 | /* | 149 | /* |
@@ -171,6 +152,6 @@ void free_initmem(void) | |||
171 | #ifdef CONFIG_BLK_DEV_INITRD | 152 | #ifdef CONFIG_BLK_DEV_INITRD |
172 | void free_initrd_mem(unsigned long start, unsigned long end) | 153 | void free_initrd_mem(unsigned long start, unsigned long end) |
173 | { | 154 | { |
174 | free_init_pages("initrd memory", start, end); | 155 | free_reserved_area(start, end, POISON_FREE_INITMEM, "initrd"); |
175 | } | 156 | } |
176 | #endif | 157 | #endif |
diff --git a/arch/openrisc/mm/init.c b/arch/openrisc/mm/init.c index e7fdc50c4bf0..b3cbc6703837 100644 --- a/arch/openrisc/mm/init.c +++ b/arch/openrisc/mm/init.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <asm/kmap_types.h> | 43 | #include <asm/kmap_types.h> |
44 | #include <asm/fixmap.h> | 44 | #include <asm/fixmap.h> |
45 | #include <asm/tlbflush.h> | 45 | #include <asm/tlbflush.h> |
46 | #include <asm/sections.h> | ||
46 | 47 | ||
47 | int mem_init_done; | 48 | int mem_init_done; |
48 | 49 | ||
@@ -201,9 +202,6 @@ void __init paging_init(void) | |||
201 | 202 | ||
202 | /* References to section boundaries */ | 203 | /* References to section boundaries */ |
203 | 204 | ||
204 | extern char _stext, _etext, _edata, __bss_start, _end; | ||
205 | extern char __init_begin, __init_end; | ||
206 | |||
207 | static int __init free_pages_init(void) | 205 | static int __init free_pages_init(void) |
208 | { | 206 | { |
209 | int reservedpages, pfn; | 207 | int reservedpages, pfn; |
@@ -263,30 +261,11 @@ void __init mem_init(void) | |||
263 | #ifdef CONFIG_BLK_DEV_INITRD | 261 | #ifdef CONFIG_BLK_DEV_INITRD |
264 | void free_initrd_mem(unsigned long start, unsigned long end) | 262 | void free_initrd_mem(unsigned long start, unsigned long end) |
265 | { | 263 | { |
266 | printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", | 264 | free_reserved_area(start, end, 0, "initrd"); |
267 | (end - start) >> 10); | ||
268 | |||
269 | for (; start < end; start += PAGE_SIZE) { | ||
270 | ClearPageReserved(virt_to_page(start)); | ||
271 | init_page_count(virt_to_page(start)); | ||
272 | free_page(start); | ||
273 | totalram_pages++; | ||
274 | } | ||
275 | } | 265 | } |
276 | #endif | 266 | #endif |
277 | 267 | ||
278 | void free_initmem(void) | 268 | void free_initmem(void) |
279 | { | 269 | { |
280 | unsigned long addr; | 270 | free_initmem_default(0); |
281 | |||
282 | addr = (unsigned long)(&__init_begin); | ||
283 | for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { | ||
284 | ClearPageReserved(virt_to_page(addr)); | ||
285 | init_page_count(virt_to_page(addr)); | ||
286 | free_page(addr); | ||
287 | totalram_pages++; | ||
288 | } | ||
289 | printk(KERN_INFO "Freeing unused kernel memory: %luk freed\n", | ||
290 | ((unsigned long)&__init_end - | ||
291 | (unsigned long)&__init_begin) >> 10); | ||
292 | } | 271 | } |
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index 01d95e2f0581..113e28206503 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile | |||
@@ -65,8 +65,10 @@ ifndef CONFIG_FUNCTION_TRACER | |||
65 | endif | 65 | endif |
66 | 66 | ||
67 | # Use long jumps instead of long branches (needed if your linker fails to | 67 | # Use long jumps instead of long branches (needed if your linker fails to |
68 | # link a too big vmlinux executable) | 68 | # link a too big vmlinux executable). Not enabled for building modules. |
69 | cflags-$(CONFIG_MLONGCALLS) += -mlong-calls | 69 | ifdef CONFIG_MLONGCALLS |
70 | KBUILD_CFLAGS_KERNEL += -mlong-calls | ||
71 | endif | ||
70 | 72 | ||
71 | # select which processor to optimise for | 73 | # select which processor to optimise for |
72 | cflags-$(CONFIG_PA7100) += -march=1.1 -mschedule=7100 | 74 | cflags-$(CONFIG_PA7100) += -march=1.1 -mschedule=7100 |
diff --git a/arch/parisc/include/asm/cacheflush.h b/arch/parisc/include/asm/cacheflush.h index 79f694f3ad9b..f0e2784e7cca 100644 --- a/arch/parisc/include/asm/cacheflush.h +++ b/arch/parisc/include/asm/cacheflush.h | |||
@@ -140,7 +140,10 @@ static inline void *kmap(struct page *page) | |||
140 | return page_address(page); | 140 | return page_address(page); |
141 | } | 141 | } |
142 | 142 | ||
143 | #define kunmap(page) kunmap_parisc(page_address(page)) | 143 | static inline void kunmap(struct page *page) |
144 | { | ||
145 | kunmap_parisc(page_address(page)); | ||
146 | } | ||
144 | 147 | ||
145 | static inline void *kmap_atomic(struct page *page) | 148 | static inline void *kmap_atomic(struct page *page) |
146 | { | 149 | { |
diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h index 7df49fad29f9..1e40d7f86be3 100644 --- a/arch/parisc/include/asm/pgtable.h +++ b/arch/parisc/include/asm/pgtable.h | |||
@@ -16,6 +16,8 @@ | |||
16 | #include <asm/processor.h> | 16 | #include <asm/processor.h> |
17 | #include <asm/cache.h> | 17 | #include <asm/cache.h> |
18 | 18 | ||
19 | extern spinlock_t pa_dbit_lock; | ||
20 | |||
19 | /* | 21 | /* |
20 | * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel | 22 | * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel |
21 | * memory. For the return value to be meaningful, ADDR must be >= | 23 | * memory. For the return value to be meaningful, ADDR must be >= |
@@ -44,8 +46,11 @@ extern void purge_tlb_entries(struct mm_struct *, unsigned long); | |||
44 | 46 | ||
45 | #define set_pte_at(mm, addr, ptep, pteval) \ | 47 | #define set_pte_at(mm, addr, ptep, pteval) \ |
46 | do { \ | 48 | do { \ |
49 | unsigned long flags; \ | ||
50 | spin_lock_irqsave(&pa_dbit_lock, flags); \ | ||
47 | set_pte(ptep, pteval); \ | 51 | set_pte(ptep, pteval); \ |
48 | purge_tlb_entries(mm, addr); \ | 52 | purge_tlb_entries(mm, addr); \ |
53 | spin_unlock_irqrestore(&pa_dbit_lock, flags); \ | ||
49 | } while (0) | 54 | } while (0) |
50 | 55 | ||
51 | #endif /* !__ASSEMBLY__ */ | 56 | #endif /* !__ASSEMBLY__ */ |
@@ -435,48 +440,46 @@ extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *); | |||
435 | 440 | ||
436 | static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) | 441 | static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) |
437 | { | 442 | { |
438 | #ifdef CONFIG_SMP | 443 | pte_t pte; |
444 | unsigned long flags; | ||
445 | |||
439 | if (!pte_young(*ptep)) | 446 | if (!pte_young(*ptep)) |
440 | return 0; | 447 | return 0; |
441 | return test_and_clear_bit(xlate_pabit(_PAGE_ACCESSED_BIT), &pte_val(*ptep)); | 448 | |
442 | #else | 449 | spin_lock_irqsave(&pa_dbit_lock, flags); |
443 | pte_t pte = *ptep; | 450 | pte = *ptep; |
444 | if (!pte_young(pte)) | 451 | if (!pte_young(pte)) { |
452 | spin_unlock_irqrestore(&pa_dbit_lock, flags); | ||
445 | return 0; | 453 | return 0; |
446 | set_pte_at(vma->vm_mm, addr, ptep, pte_mkold(pte)); | 454 | } |
455 | set_pte(ptep, pte_mkold(pte)); | ||
456 | purge_tlb_entries(vma->vm_mm, addr); | ||
457 | spin_unlock_irqrestore(&pa_dbit_lock, flags); | ||
447 | return 1; | 458 | return 1; |
448 | #endif | ||
449 | } | 459 | } |
450 | 460 | ||
451 | extern spinlock_t pa_dbit_lock; | ||
452 | |||
453 | struct mm_struct; | 461 | struct mm_struct; |
454 | static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | 462 | static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) |
455 | { | 463 | { |
456 | pte_t old_pte; | 464 | pte_t old_pte; |
465 | unsigned long flags; | ||
457 | 466 | ||
458 | spin_lock(&pa_dbit_lock); | 467 | spin_lock_irqsave(&pa_dbit_lock, flags); |
459 | old_pte = *ptep; | 468 | old_pte = *ptep; |
460 | pte_clear(mm,addr,ptep); | 469 | pte_clear(mm,addr,ptep); |
461 | spin_unlock(&pa_dbit_lock); | 470 | purge_tlb_entries(mm, addr); |
471 | spin_unlock_irqrestore(&pa_dbit_lock, flags); | ||
462 | 472 | ||
463 | return old_pte; | 473 | return old_pte; |
464 | } | 474 | } |
465 | 475 | ||
466 | static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | 476 | static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) |
467 | { | 477 | { |
468 | #ifdef CONFIG_SMP | 478 | unsigned long flags; |
469 | unsigned long new, old; | 479 | spin_lock_irqsave(&pa_dbit_lock, flags); |
470 | 480 | set_pte(ptep, pte_wrprotect(*ptep)); | |
471 | do { | ||
472 | old = pte_val(*ptep); | ||
473 | new = pte_val(pte_wrprotect(__pte (old))); | ||
474 | } while (cmpxchg((unsigned long *) ptep, old, new) != old); | ||
475 | purge_tlb_entries(mm, addr); | 481 | purge_tlb_entries(mm, addr); |
476 | #else | 482 | spin_unlock_irqrestore(&pa_dbit_lock, flags); |
477 | pte_t old_pte = *ptep; | ||
478 | set_pte_at(mm, addr, ptep, pte_wrprotect(old_pte)); | ||
479 | #endif | ||
480 | } | 483 | } |
481 | 484 | ||
482 | #define pte_same(A,B) (pte_val(A) == pte_val(B)) | 485 | #define pte_same(A,B) (pte_val(A) == pte_val(B)) |
diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h index 4ba2c93770f1..e0a82358517e 100644 --- a/arch/parisc/include/asm/uaccess.h +++ b/arch/parisc/include/asm/uaccess.h | |||
@@ -181,30 +181,24 @@ struct exception_data { | |||
181 | #if !defined(CONFIG_64BIT) | 181 | #if !defined(CONFIG_64BIT) |
182 | 182 | ||
183 | #define __put_kernel_asm64(__val,ptr) do { \ | 183 | #define __put_kernel_asm64(__val,ptr) do { \ |
184 | u64 __val64 = (u64)(__val); \ | ||
185 | u32 hi = (__val64) >> 32; \ | ||
186 | u32 lo = (__val64) & 0xffffffff; \ | ||
187 | __asm__ __volatile__ ( \ | 184 | __asm__ __volatile__ ( \ |
188 | "\n1:\tstw %2,0(%1)" \ | 185 | "\n1:\tstw %2,0(%1)" \ |
189 | "\n2:\tstw %3,4(%1)\n\t" \ | 186 | "\n2:\tstw %R2,4(%1)\n\t" \ |
190 | ASM_EXCEPTIONTABLE_ENTRY(1b,fixup_put_user_skip_2)\ | 187 | ASM_EXCEPTIONTABLE_ENTRY(1b,fixup_put_user_skip_2)\ |
191 | ASM_EXCEPTIONTABLE_ENTRY(2b,fixup_put_user_skip_1)\ | 188 | ASM_EXCEPTIONTABLE_ENTRY(2b,fixup_put_user_skip_1)\ |
192 | : "=r"(__pu_err) \ | 189 | : "=r"(__pu_err) \ |
193 | : "r"(ptr), "r"(hi), "r"(lo), "0"(__pu_err) \ | 190 | : "r"(ptr), "r"(__val), "0"(__pu_err) \ |
194 | : "r1"); \ | 191 | : "r1"); \ |
195 | } while (0) | 192 | } while (0) |
196 | 193 | ||
197 | #define __put_user_asm64(__val,ptr) do { \ | 194 | #define __put_user_asm64(__val,ptr) do { \ |
198 | u64 __val64 = (u64)(__val); \ | ||
199 | u32 hi = (__val64) >> 32; \ | ||
200 | u32 lo = (__val64) & 0xffffffff; \ | ||
201 | __asm__ __volatile__ ( \ | 195 | __asm__ __volatile__ ( \ |
202 | "\n1:\tstw %2,0(%%sr3,%1)" \ | 196 | "\n1:\tstw %2,0(%%sr3,%1)" \ |
203 | "\n2:\tstw %3,4(%%sr3,%1)\n\t" \ | 197 | "\n2:\tstw %R2,4(%%sr3,%1)\n\t" \ |
204 | ASM_EXCEPTIONTABLE_ENTRY(1b,fixup_put_user_skip_2)\ | 198 | ASM_EXCEPTIONTABLE_ENTRY(1b,fixup_put_user_skip_2)\ |
205 | ASM_EXCEPTIONTABLE_ENTRY(2b,fixup_put_user_skip_1)\ | 199 | ASM_EXCEPTIONTABLE_ENTRY(2b,fixup_put_user_skip_1)\ |
206 | : "=r"(__pu_err) \ | 200 | : "=r"(__pu_err) \ |
207 | : "r"(ptr), "r"(hi), "r"(lo), "0"(__pu_err) \ | 201 | : "r"(ptr), "r"(__val), "0"(__pu_err) \ |
208 | : "r1"); \ | 202 | : "r1"); \ |
209 | } while (0) | 203 | } while (0) |
210 | 204 | ||
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index 4b12890642eb..83ded26cad06 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c | |||
@@ -421,14 +421,11 @@ void purge_tlb_entries(struct mm_struct *mm, unsigned long addr) | |||
421 | /* Note: purge_tlb_entries can be called at startup with | 421 | /* Note: purge_tlb_entries can be called at startup with |
422 | no context. */ | 422 | no context. */ |
423 | 423 | ||
424 | /* Disable preemption while we play with %sr1. */ | ||
425 | preempt_disable(); | ||
426 | mtsp(mm->context, 1); | ||
427 | purge_tlb_start(flags); | 424 | purge_tlb_start(flags); |
425 | mtsp(mm->context, 1); | ||
428 | pdtlb(addr); | 426 | pdtlb(addr); |
429 | pitlb(addr); | 427 | pitlb(addr); |
430 | purge_tlb_end(flags); | 428 | purge_tlb_end(flags); |
431 | preempt_enable(); | ||
432 | } | 429 | } |
433 | EXPORT_SYMBOL(purge_tlb_entries); | 430 | EXPORT_SYMBOL(purge_tlb_entries); |
434 | 431 | ||
diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c index 6795dc6c995f..568b2c61ea02 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c | |||
@@ -120,11 +120,13 @@ extern void __ashrdi3(void); | |||
120 | extern void __ashldi3(void); | 120 | extern void __ashldi3(void); |
121 | extern void __lshrdi3(void); | 121 | extern void __lshrdi3(void); |
122 | extern void __muldi3(void); | 122 | extern void __muldi3(void); |
123 | extern void __ucmpdi2(void); | ||
123 | 124 | ||
124 | EXPORT_SYMBOL(__ashrdi3); | 125 | EXPORT_SYMBOL(__ashrdi3); |
125 | EXPORT_SYMBOL(__ashldi3); | 126 | EXPORT_SYMBOL(__ashldi3); |
126 | EXPORT_SYMBOL(__lshrdi3); | 127 | EXPORT_SYMBOL(__lshrdi3); |
127 | EXPORT_SYMBOL(__muldi3); | 128 | EXPORT_SYMBOL(__muldi3); |
129 | EXPORT_SYMBOL(__ucmpdi2); | ||
128 | 130 | ||
129 | asmlinkage void * __canonicalize_funcptr_for_compare(void *); | 131 | asmlinkage void * __canonicalize_funcptr_for_compare(void *); |
130 | EXPORT_SYMBOL(__canonicalize_funcptr_for_compare); | 132 | EXPORT_SYMBOL(__canonicalize_funcptr_for_compare); |
diff --git a/arch/parisc/lib/Makefile b/arch/parisc/lib/Makefile index 5f2e6904d14a..5651536ac733 100644 --- a/arch/parisc/lib/Makefile +++ b/arch/parisc/lib/Makefile | |||
@@ -2,6 +2,7 @@ | |||
2 | # Makefile for parisc-specific library files | 2 | # Makefile for parisc-specific library files |
3 | # | 3 | # |
4 | 4 | ||
5 | lib-y := lusercopy.o bitops.o checksum.o io.o memset.o fixup.o memcpy.o | 5 | lib-y := lusercopy.o bitops.o checksum.o io.o memset.o fixup.o memcpy.o \ |
6 | ucmpdi2.o | ||
6 | 7 | ||
7 | obj-y := iomap.o | 8 | obj-y := iomap.o |
diff --git a/arch/parisc/lib/ucmpdi2.c b/arch/parisc/lib/ucmpdi2.c new file mode 100644 index 000000000000..149c016f32c5 --- /dev/null +++ b/arch/parisc/lib/ucmpdi2.c | |||
@@ -0,0 +1,25 @@ | |||
1 | #include <linux/module.h> | ||
2 | |||
3 | union ull_union { | ||
4 | unsigned long long ull; | ||
5 | struct { | ||
6 | unsigned int high; | ||
7 | unsigned int low; | ||
8 | } ui; | ||
9 | }; | ||
10 | |||
11 | int __ucmpdi2(unsigned long long a, unsigned long long b) | ||
12 | { | ||
13 | union ull_union au = {.ull = a}; | ||
14 | union ull_union bu = {.ull = b}; | ||
15 | |||
16 | if (au.ui.high < bu.ui.high) | ||
17 | return 0; | ||
18 | else if (au.ui.high > bu.ui.high) | ||
19 | return 2; | ||
20 | if (au.ui.low < bu.ui.low) | ||
21 | return 0; | ||
22 | else if (au.ui.low > bu.ui.low) | ||
23 | return 2; | ||
24 | return 1; | ||
25 | } | ||
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 3ac462de53a4..157b931e7b09 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c | |||
@@ -505,7 +505,6 @@ static void __init map_pages(unsigned long start_vaddr, | |||
505 | 505 | ||
506 | void free_initmem(void) | 506 | void free_initmem(void) |
507 | { | 507 | { |
508 | unsigned long addr; | ||
509 | unsigned long init_begin = (unsigned long)__init_begin; | 508 | unsigned long init_begin = (unsigned long)__init_begin; |
510 | unsigned long init_end = (unsigned long)__init_end; | 509 | unsigned long init_end = (unsigned long)__init_end; |
511 | 510 | ||
@@ -533,19 +532,10 @@ void free_initmem(void) | |||
533 | * pages are no-longer executable */ | 532 | * pages are no-longer executable */ |
534 | flush_icache_range(init_begin, init_end); | 533 | flush_icache_range(init_begin, init_end); |
535 | 534 | ||
536 | for (addr = init_begin; addr < init_end; addr += PAGE_SIZE) { | 535 | num_physpages += free_initmem_default(0); |
537 | ClearPageReserved(virt_to_page(addr)); | ||
538 | init_page_count(virt_to_page(addr)); | ||
539 | free_page(addr); | ||
540 | num_physpages++; | ||
541 | totalram_pages++; | ||
542 | } | ||
543 | 536 | ||
544 | /* set up a new led state on systems shipped LED State panel */ | 537 | /* set up a new led state on systems shipped LED State panel */ |
545 | pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BCOMPLETE); | 538 | pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BCOMPLETE); |
546 | |||
547 | printk(KERN_INFO "Freeing unused kernel memory: %luk freed\n", | ||
548 | (init_end - init_begin) >> 10); | ||
549 | } | 539 | } |
550 | 540 | ||
551 | 541 | ||
@@ -697,6 +687,8 @@ void show_mem(unsigned int filter) | |||
697 | 687 | ||
698 | printk(KERN_INFO "Mem-info:\n"); | 688 | printk(KERN_INFO "Mem-info:\n"); |
699 | show_free_areas(filter); | 689 | show_free_areas(filter); |
690 | if (filter & SHOW_MEM_FILTER_PAGE_COUNT) | ||
691 | return; | ||
700 | #ifndef CONFIG_DISCONTIGMEM | 692 | #ifndef CONFIG_DISCONTIGMEM |
701 | i = max_mapnr; | 693 | i = max_mapnr; |
702 | while (i-- > 0) { | 694 | while (i-- > 0) { |
@@ -1107,15 +1099,6 @@ void flush_tlb_all(void) | |||
1107 | #ifdef CONFIG_BLK_DEV_INITRD | 1099 | #ifdef CONFIG_BLK_DEV_INITRD |
1108 | void free_initrd_mem(unsigned long start, unsigned long end) | 1100 | void free_initrd_mem(unsigned long start, unsigned long end) |
1109 | { | 1101 | { |
1110 | if (start >= end) | 1102 | num_physpages += free_reserved_area(start, end, 0, "initrd"); |
1111 | return; | ||
1112 | printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10); | ||
1113 | for (; start < end; start += PAGE_SIZE) { | ||
1114 | ClearPageReserved(virt_to_page(start)); | ||
1115 | init_page_count(virt_to_page(start)); | ||
1116 | free_page(start); | ||
1117 | num_physpages++; | ||
1118 | totalram_pages++; | ||
1119 | } | ||
1120 | } | 1103 | } |
1121 | #endif | 1104 | #endif |
diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/asm/hugetlb.h index 62e11a32c4c2..4fcbd6b14a3a 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #ifdef CONFIG_HUGETLB_PAGE | 4 | #ifdef CONFIG_HUGETLB_PAGE |
5 | #include <asm/page.h> | 5 | #include <asm/page.h> |
6 | #include <asm-generic/hugetlb.h> | ||
6 | 7 | ||
7 | extern struct kmem_cache *hugepte_cache; | 8 | extern struct kmem_cache *hugepte_cache; |
8 | 9 | ||
diff --git a/arch/powerpc/include/asm/uprobes.h b/arch/powerpc/include/asm/uprobes.h index b532060d0916..23016020915e 100644 --- a/arch/powerpc/include/asm/uprobes.h +++ b/arch/powerpc/include/asm/uprobes.h | |||
@@ -51,4 +51,5 @@ extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs); | |||
51 | extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); | 51 | extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); |
52 | extern int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data); | 52 | extern int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data); |
53 | extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs); | 53 | extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs); |
54 | extern unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs); | ||
54 | #endif /* _ASM_UPROBES_H */ | 55 | #endif /* _ASM_UPROBES_H */ |
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c index b3ba5163eae2..9ec3fe174cba 100644 --- a/arch/powerpc/kernel/crash_dump.c +++ b/arch/powerpc/kernel/crash_dump.c | |||
@@ -150,10 +150,7 @@ void crash_free_reserved_phys_range(unsigned long begin, unsigned long end) | |||
150 | if (addr <= rtas_end && ((addr + PAGE_SIZE) > rtas_start)) | 150 | if (addr <= rtas_end && ((addr + PAGE_SIZE) > rtas_start)) |
151 | continue; | 151 | continue; |
152 | 152 | ||
153 | ClearPageReserved(pfn_to_page(addr >> PAGE_SHIFT)); | 153 | free_reserved_page(pfn_to_page(addr >> PAGE_SHIFT)); |
154 | init_page_count(pfn_to_page(addr >> PAGE_SHIFT)); | ||
155 | free_page((unsigned long)__va(addr)); | ||
156 | totalram_pages++; | ||
157 | } | 154 | } |
158 | } | 155 | } |
159 | #endif | 156 | #endif |
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S index 256c5bf0adb7..04d69c4a5ac2 100644 --- a/arch/powerpc/kernel/entry_64.S +++ b/arch/powerpc/kernel/entry_64.S | |||
@@ -304,7 +304,7 @@ syscall_exit_work: | |||
304 | subi r12,r12,TI_FLAGS | 304 | subi r12,r12,TI_FLAGS |
305 | 305 | ||
306 | 4: /* Anything else left to do? */ | 306 | 4: /* Anything else left to do? */ |
307 | SET_DEFAULT_THREAD_PPR(r3, r9) /* Set thread.ppr = 3 */ | 307 | SET_DEFAULT_THREAD_PPR(r3, r10) /* Set thread.ppr = 3 */ |
308 | andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) | 308 | andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) |
309 | beq .ret_from_except_lite | 309 | beq .ret_from_except_lite |
310 | 310 | ||
@@ -657,7 +657,7 @@ resume_kernel: | |||
657 | /* Clear _TIF_EMULATE_STACK_STORE flag */ | 657 | /* Clear _TIF_EMULATE_STACK_STORE flag */ |
658 | lis r11,_TIF_EMULATE_STACK_STORE@h | 658 | lis r11,_TIF_EMULATE_STACK_STORE@h |
659 | addi r5,r9,TI_FLAGS | 659 | addi r5,r9,TI_FLAGS |
660 | ldarx r4,0,r5 | 660 | 0: ldarx r4,0,r5 |
661 | andc r4,r4,r11 | 661 | andc r4,r4,r11 |
662 | stdcx. r4,0,r5 | 662 | stdcx. r4,0,r5 |
663 | bne- 0b | 663 | bne- 0b |
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c index 06c8202a69cf..2230fd0ca3e4 100644 --- a/arch/powerpc/kernel/fadump.c +++ b/arch/powerpc/kernel/fadump.c | |||
@@ -1045,10 +1045,7 @@ static void fadump_release_memory(unsigned long begin, unsigned long end) | |||
1045 | if (addr <= ra_end && ((addr + PAGE_SIZE) > ra_start)) | 1045 | if (addr <= ra_end && ((addr + PAGE_SIZE) > ra_start)) |
1046 | continue; | 1046 | continue; |
1047 | 1047 | ||
1048 | ClearPageReserved(pfn_to_page(addr >> PAGE_SHIFT)); | 1048 | free_reserved_page(pfn_to_page(addr >> PAGE_SHIFT)); |
1049 | init_page_count(pfn_to_page(addr >> PAGE_SHIFT)); | ||
1050 | free_page((unsigned long)__va(addr)); | ||
1051 | totalram_pages++; | ||
1052 | } | 1049 | } |
1053 | } | 1050 | } |
1054 | 1051 | ||
diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c index a61b133c4f99..6782221d49bd 100644 --- a/arch/powerpc/kernel/kvm.c +++ b/arch/powerpc/kernel/kvm.c | |||
@@ -756,12 +756,7 @@ static __init void kvm_free_tmp(void) | |||
756 | end = (ulong)&kvm_tmp[ARRAY_SIZE(kvm_tmp)] & PAGE_MASK; | 756 | end = (ulong)&kvm_tmp[ARRAY_SIZE(kvm_tmp)] & PAGE_MASK; |
757 | 757 | ||
758 | /* Free the tmp space we don't need */ | 758 | /* Free the tmp space we don't need */ |
759 | for (; start < end; start += PAGE_SIZE) { | 759 | free_reserved_area(start, end, 0, NULL); |
760 | ClearPageReserved(virt_to_page(start)); | ||
761 | init_page_count(virt_to_page(start)); | ||
762 | free_page(start); | ||
763 | totalram_pages++; | ||
764 | } | ||
765 | } | 760 | } |
766 | 761 | ||
767 | static int __init kvm_guest_init(void) | 762 | static int __init kvm_guest_init(void) |
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 59dd545fdde1..16e77a81ab4f 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -555,10 +555,12 @@ static inline void tm_recheckpoint_new_task(struct task_struct *new) | |||
555 | new->thread.regs->msr |= | 555 | new->thread.regs->msr |= |
556 | (MSR_FP | new->thread.fpexc_mode); | 556 | (MSR_FP | new->thread.fpexc_mode); |
557 | } | 557 | } |
558 | #ifdef CONFIG_ALTIVEC | ||
558 | if (msr & MSR_VEC) { | 559 | if (msr & MSR_VEC) { |
559 | do_load_up_transact_altivec(&new->thread); | 560 | do_load_up_transact_altivec(&new->thread); |
560 | new->thread.regs->msr |= MSR_VEC; | 561 | new->thread.regs->msr |= MSR_VEC; |
561 | } | 562 | } |
563 | #endif | ||
562 | /* We may as well turn on VSX too since all the state is restored now */ | 564 | /* We may as well turn on VSX too since all the state is restored now */ |
563 | if (msr & MSR_VSX) | 565 | if (msr & MSR_VSX) |
564 | new->thread.regs->msr |= MSR_VSX; | 566 | new->thread.regs->msr |= MSR_VSX; |
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 3acb28e245b4..95068bf569ad 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
@@ -866,10 +866,12 @@ static long restore_tm_user_regs(struct pt_regs *regs, | |||
866 | do_load_up_transact_fpu(¤t->thread); | 866 | do_load_up_transact_fpu(¤t->thread); |
867 | regs->msr |= (MSR_FP | current->thread.fpexc_mode); | 867 | regs->msr |= (MSR_FP | current->thread.fpexc_mode); |
868 | } | 868 | } |
869 | #ifdef CONFIG_ALTIVEC | ||
869 | if (msr & MSR_VEC) { | 870 | if (msr & MSR_VEC) { |
870 | do_load_up_transact_altivec(¤t->thread); | 871 | do_load_up_transact_altivec(¤t->thread); |
871 | regs->msr |= MSR_VEC; | 872 | regs->msr |= MSR_VEC; |
872 | } | 873 | } |
874 | #endif | ||
873 | 875 | ||
874 | return 0; | 876 | return 0; |
875 | } | 877 | } |
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 995f8543cb57..c1794286098c 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c | |||
@@ -522,10 +522,12 @@ static long restore_tm_sigcontexts(struct pt_regs *regs, | |||
522 | do_load_up_transact_fpu(¤t->thread); | 522 | do_load_up_transact_fpu(¤t->thread); |
523 | regs->msr |= (MSR_FP | current->thread.fpexc_mode); | 523 | regs->msr |= (MSR_FP | current->thread.fpexc_mode); |
524 | } | 524 | } |
525 | #ifdef CONFIG_ALTIVEC | ||
525 | if (msr & MSR_VEC) { | 526 | if (msr & MSR_VEC) { |
526 | do_load_up_transact_altivec(¤t->thread); | 527 | do_load_up_transact_altivec(¤t->thread); |
527 | regs->msr |= MSR_VEC; | 528 | regs->msr |= MSR_VEC; |
528 | } | 529 | } |
530 | #endif | ||
529 | 531 | ||
530 | return err; | 532 | return err; |
531 | } | 533 | } |
diff --git a/arch/powerpc/kernel/tm.S b/arch/powerpc/kernel/tm.S index 84dbace657ce..2da67e7a16d5 100644 --- a/arch/powerpc/kernel/tm.S +++ b/arch/powerpc/kernel/tm.S | |||
@@ -309,6 +309,7 @@ _GLOBAL(tm_recheckpoint) | |||
309 | or r5, r6, r5 /* Set MSR.FP+.VSX/.VEC */ | 309 | or r5, r6, r5 /* Set MSR.FP+.VSX/.VEC */ |
310 | mtmsr r5 | 310 | mtmsr r5 |
311 | 311 | ||
312 | #ifdef CONFIG_ALTIVEC | ||
312 | /* FP and VEC registers: These are recheckpointed from thread.fpr[] | 313 | /* FP and VEC registers: These are recheckpointed from thread.fpr[] |
313 | * and thread.vr[] respectively. The thread.transact_fpr[] version | 314 | * and thread.vr[] respectively. The thread.transact_fpr[] version |
314 | * is more modern, and will be loaded subsequently by any FPUnavailable | 315 | * is more modern, and will be loaded subsequently by any FPUnavailable |
@@ -323,6 +324,7 @@ _GLOBAL(tm_recheckpoint) | |||
323 | REST_32VRS(0, r5, r3) /* r5 scratch, r3 THREAD ptr */ | 324 | REST_32VRS(0, r5, r3) /* r5 scratch, r3 THREAD ptr */ |
324 | ld r5, THREAD_VRSAVE(r3) | 325 | ld r5, THREAD_VRSAVE(r3) |
325 | mtspr SPRN_VRSAVE, r5 | 326 | mtspr SPRN_VRSAVE, r5 |
327 | #endif | ||
326 | 328 | ||
327 | dont_restore_vec: | 329 | dont_restore_vec: |
328 | andi. r0, r4, MSR_FP | 330 | andi. r0, r4, MSR_FP |
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c index f9748498fe58..13b867093499 100644 --- a/arch/powerpc/kernel/udbg.c +++ b/arch/powerpc/kernel/udbg.c | |||
@@ -156,15 +156,13 @@ static struct console udbg_console = { | |||
156 | .index = 0, | 156 | .index = 0, |
157 | }; | 157 | }; |
158 | 158 | ||
159 | static int early_console_initialized; | ||
160 | |||
161 | /* | 159 | /* |
162 | * Called by setup_system after ppc_md->probe and ppc_md->early_init. | 160 | * Called by setup_system after ppc_md->probe and ppc_md->early_init. |
163 | * Call it again after setting udbg_putc in ppc_md->setup_arch. | 161 | * Call it again after setting udbg_putc in ppc_md->setup_arch. |
164 | */ | 162 | */ |
165 | void __init register_early_udbg_console(void) | 163 | void __init register_early_udbg_console(void) |
166 | { | 164 | { |
167 | if (early_console_initialized) | 165 | if (early_console) |
168 | return; | 166 | return; |
169 | 167 | ||
170 | if (!udbg_putc) | 168 | if (!udbg_putc) |
@@ -174,7 +172,7 @@ void __init register_early_udbg_console(void) | |||
174 | printk(KERN_INFO "early console immortal !\n"); | 172 | printk(KERN_INFO "early console immortal !\n"); |
175 | udbg_console.flags &= ~CON_BOOT; | 173 | udbg_console.flags &= ~CON_BOOT; |
176 | } | 174 | } |
177 | early_console_initialized = 1; | 175 | early_console = &udbg_console; |
178 | register_console(&udbg_console); | 176 | register_console(&udbg_console); |
179 | } | 177 | } |
180 | 178 | ||
diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c index bc77834dbf43..59f419b935f2 100644 --- a/arch/powerpc/kernel/uprobes.c +++ b/arch/powerpc/kernel/uprobes.c | |||
@@ -31,6 +31,16 @@ | |||
31 | #define UPROBE_TRAP_NR UINT_MAX | 31 | #define UPROBE_TRAP_NR UINT_MAX |
32 | 32 | ||
33 | /** | 33 | /** |
34 | * is_trap_insn - check if the instruction is a trap variant | ||
35 | * @insn: instruction to be checked. | ||
36 | * Returns true if @insn is a trap variant. | ||
37 | */ | ||
38 | bool is_trap_insn(uprobe_opcode_t *insn) | ||
39 | { | ||
40 | return (is_trap(*insn)); | ||
41 | } | ||
42 | |||
43 | /** | ||
34 | * arch_uprobe_analyze_insn | 44 | * arch_uprobe_analyze_insn |
35 | * @mm: the probed address space. | 45 | * @mm: the probed address space. |
36 | * @arch_uprobe: the probepoint information. | 46 | * @arch_uprobe: the probepoint information. |
@@ -43,12 +53,6 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, | |||
43 | if (addr & 0x03) | 53 | if (addr & 0x03) |
44 | return -EINVAL; | 54 | return -EINVAL; |
45 | 55 | ||
46 | /* | ||
47 | * We currently don't support a uprobe on an already | ||
48 | * existing breakpoint instruction underneath | ||
49 | */ | ||
50 | if (is_trap(auprobe->ainsn)) | ||
51 | return -ENOTSUPP; | ||
52 | return 0; | 56 | return 0; |
53 | } | 57 | } |
54 | 58 | ||
@@ -188,3 +192,16 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) | |||
188 | 192 | ||
189 | return false; | 193 | return false; |
190 | } | 194 | } |
195 | |||
196 | unsigned long | ||
197 | arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs) | ||
198 | { | ||
199 | unsigned long orig_ret_vaddr; | ||
200 | |||
201 | orig_ret_vaddr = regs->link; | ||
202 | |||
203 | /* Replace the return addr with trampoline addr */ | ||
204 | regs->link = trampoline_vaddr; | ||
205 | |||
206 | return orig_ret_vaddr; | ||
207 | } | ||
diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h index 41cefd43655f..33db48a8ce24 100644 --- a/arch/powerpc/kvm/e500.h +++ b/arch/powerpc/kvm/e500.h | |||
@@ -26,17 +26,20 @@ | |||
26 | #define E500_PID_NUM 3 | 26 | #define E500_PID_NUM 3 |
27 | #define E500_TLB_NUM 2 | 27 | #define E500_TLB_NUM 2 |
28 | 28 | ||
29 | #define E500_TLB_VALID 1 | 29 | /* entry is mapped somewhere in host TLB */ |
30 | #define E500_TLB_BITMAP 2 | 30 | #define E500_TLB_VALID (1 << 0) |
31 | /* TLB1 entry is mapped by host TLB1, tracked by bitmaps */ | ||
32 | #define E500_TLB_BITMAP (1 << 1) | ||
33 | /* TLB1 entry is mapped by host TLB0 */ | ||
31 | #define E500_TLB_TLB0 (1 << 2) | 34 | #define E500_TLB_TLB0 (1 << 2) |
32 | 35 | ||
33 | struct tlbe_ref { | 36 | struct tlbe_ref { |
34 | pfn_t pfn; | 37 | pfn_t pfn; /* valid only for TLB0, except briefly */ |
35 | unsigned int flags; /* E500_TLB_* */ | 38 | unsigned int flags; /* E500_TLB_* */ |
36 | }; | 39 | }; |
37 | 40 | ||
38 | struct tlbe_priv { | 41 | struct tlbe_priv { |
39 | struct tlbe_ref ref; /* TLB0 only -- TLB1 uses tlb_refs */ | 42 | struct tlbe_ref ref; |
40 | }; | 43 | }; |
41 | 44 | ||
42 | #ifdef CONFIG_KVM_E500V2 | 45 | #ifdef CONFIG_KVM_E500V2 |
@@ -63,17 +66,6 @@ struct kvmppc_vcpu_e500 { | |||
63 | 66 | ||
64 | unsigned int gtlb_nv[E500_TLB_NUM]; | 67 | unsigned int gtlb_nv[E500_TLB_NUM]; |
65 | 68 | ||
66 | /* | ||
67 | * information associated with each host TLB entry -- | ||
68 | * TLB1 only for now. If/when guest TLB1 entries can be | ||
69 | * mapped with host TLB0, this will be used for that too. | ||
70 | * | ||
71 | * We don't want to use this for guest TLB0 because then we'd | ||
72 | * have the overhead of doing the translation again even if | ||
73 | * the entry is still in the guest TLB (e.g. we swapped out | ||
74 | * and back, and our host TLB entries got evicted). | ||
75 | */ | ||
76 | struct tlbe_ref *tlb_refs[E500_TLB_NUM]; | ||
77 | unsigned int host_tlb1_nv; | 69 | unsigned int host_tlb1_nv; |
78 | 70 | ||
79 | u32 svr; | 71 | u32 svr; |
diff --git a/arch/powerpc/kvm/e500_mmu_host.c b/arch/powerpc/kvm/e500_mmu_host.c index a222edfb9a9b..1c6a9d729df4 100644 --- a/arch/powerpc/kvm/e500_mmu_host.c +++ b/arch/powerpc/kvm/e500_mmu_host.c | |||
@@ -193,8 +193,11 @@ void inval_gtlbe_on_host(struct kvmppc_vcpu_e500 *vcpu_e500, int tlbsel, | |||
193 | struct tlbe_ref *ref = &vcpu_e500->gtlb_priv[tlbsel][esel].ref; | 193 | struct tlbe_ref *ref = &vcpu_e500->gtlb_priv[tlbsel][esel].ref; |
194 | 194 | ||
195 | /* Don't bother with unmapped entries */ | 195 | /* Don't bother with unmapped entries */ |
196 | if (!(ref->flags & E500_TLB_VALID)) | 196 | if (!(ref->flags & E500_TLB_VALID)) { |
197 | return; | 197 | WARN(ref->flags & (E500_TLB_BITMAP | E500_TLB_TLB0), |
198 | "%s: flags %x\n", __func__, ref->flags); | ||
199 | WARN_ON(tlbsel == 1 && vcpu_e500->g2h_tlb1_map[esel]); | ||
200 | } | ||
198 | 201 | ||
199 | if (tlbsel == 1 && ref->flags & E500_TLB_BITMAP) { | 202 | if (tlbsel == 1 && ref->flags & E500_TLB_BITMAP) { |
200 | u64 tmp = vcpu_e500->g2h_tlb1_map[esel]; | 203 | u64 tmp = vcpu_e500->g2h_tlb1_map[esel]; |
@@ -248,7 +251,7 @@ static inline void kvmppc_e500_ref_setup(struct tlbe_ref *ref, | |||
248 | pfn_t pfn) | 251 | pfn_t pfn) |
249 | { | 252 | { |
250 | ref->pfn = pfn; | 253 | ref->pfn = pfn; |
251 | ref->flags = E500_TLB_VALID; | 254 | ref->flags |= E500_TLB_VALID; |
252 | 255 | ||
253 | if (tlbe_is_writable(gtlbe)) | 256 | if (tlbe_is_writable(gtlbe)) |
254 | kvm_set_pfn_dirty(pfn); | 257 | kvm_set_pfn_dirty(pfn); |
@@ -257,6 +260,7 @@ static inline void kvmppc_e500_ref_setup(struct tlbe_ref *ref, | |||
257 | static inline void kvmppc_e500_ref_release(struct tlbe_ref *ref) | 260 | static inline void kvmppc_e500_ref_release(struct tlbe_ref *ref) |
258 | { | 261 | { |
259 | if (ref->flags & E500_TLB_VALID) { | 262 | if (ref->flags & E500_TLB_VALID) { |
263 | /* FIXME: don't log bogus pfn for TLB1 */ | ||
260 | trace_kvm_booke206_ref_release(ref->pfn, ref->flags); | 264 | trace_kvm_booke206_ref_release(ref->pfn, ref->flags); |
261 | ref->flags = 0; | 265 | ref->flags = 0; |
262 | } | 266 | } |
@@ -274,36 +278,23 @@ static void clear_tlb1_bitmap(struct kvmppc_vcpu_e500 *vcpu_e500) | |||
274 | 278 | ||
275 | static void clear_tlb_privs(struct kvmppc_vcpu_e500 *vcpu_e500) | 279 | static void clear_tlb_privs(struct kvmppc_vcpu_e500 *vcpu_e500) |
276 | { | 280 | { |
277 | int tlbsel = 0; | 281 | int tlbsel; |
278 | int i; | ||
279 | |||
280 | for (i = 0; i < vcpu_e500->gtlb_params[tlbsel].entries; i++) { | ||
281 | struct tlbe_ref *ref = | ||
282 | &vcpu_e500->gtlb_priv[tlbsel][i].ref; | ||
283 | kvmppc_e500_ref_release(ref); | ||
284 | } | ||
285 | } | ||
286 | |||
287 | static void clear_tlb_refs(struct kvmppc_vcpu_e500 *vcpu_e500) | ||
288 | { | ||
289 | int stlbsel = 1; | ||
290 | int i; | 282 | int i; |
291 | 283 | ||
292 | kvmppc_e500_tlbil_all(vcpu_e500); | 284 | for (tlbsel = 0; tlbsel <= 1; tlbsel++) { |
293 | 285 | for (i = 0; i < vcpu_e500->gtlb_params[tlbsel].entries; i++) { | |
294 | for (i = 0; i < host_tlb_params[stlbsel].entries; i++) { | 286 | struct tlbe_ref *ref = |
295 | struct tlbe_ref *ref = | 287 | &vcpu_e500->gtlb_priv[tlbsel][i].ref; |
296 | &vcpu_e500->tlb_refs[stlbsel][i]; | 288 | kvmppc_e500_ref_release(ref); |
297 | kvmppc_e500_ref_release(ref); | 289 | } |
298 | } | 290 | } |
299 | |||
300 | clear_tlb_privs(vcpu_e500); | ||
301 | } | 291 | } |
302 | 292 | ||
303 | void kvmppc_core_flush_tlb(struct kvm_vcpu *vcpu) | 293 | void kvmppc_core_flush_tlb(struct kvm_vcpu *vcpu) |
304 | { | 294 | { |
305 | struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); | 295 | struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); |
306 | clear_tlb_refs(vcpu_e500); | 296 | kvmppc_e500_tlbil_all(vcpu_e500); |
297 | clear_tlb_privs(vcpu_e500); | ||
307 | clear_tlb1_bitmap(vcpu_e500); | 298 | clear_tlb1_bitmap(vcpu_e500); |
308 | } | 299 | } |
309 | 300 | ||
@@ -458,8 +449,6 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, | |||
458 | gvaddr &= ~((tsize_pages << PAGE_SHIFT) - 1); | 449 | gvaddr &= ~((tsize_pages << PAGE_SHIFT) - 1); |
459 | } | 450 | } |
460 | 451 | ||
461 | /* Drop old ref and setup new one. */ | ||
462 | kvmppc_e500_ref_release(ref); | ||
463 | kvmppc_e500_ref_setup(ref, gtlbe, pfn); | 452 | kvmppc_e500_ref_setup(ref, gtlbe, pfn); |
464 | 453 | ||
465 | kvmppc_e500_setup_stlbe(&vcpu_e500->vcpu, gtlbe, tsize, | 454 | kvmppc_e500_setup_stlbe(&vcpu_e500->vcpu, gtlbe, tsize, |
@@ -507,14 +496,15 @@ static int kvmppc_e500_tlb1_map_tlb1(struct kvmppc_vcpu_e500 *vcpu_e500, | |||
507 | if (unlikely(vcpu_e500->host_tlb1_nv >= tlb1_max_shadow_size())) | 496 | if (unlikely(vcpu_e500->host_tlb1_nv >= tlb1_max_shadow_size())) |
508 | vcpu_e500->host_tlb1_nv = 0; | 497 | vcpu_e500->host_tlb1_nv = 0; |
509 | 498 | ||
510 | vcpu_e500->tlb_refs[1][sesel] = *ref; | ||
511 | vcpu_e500->g2h_tlb1_map[esel] |= (u64)1 << sesel; | ||
512 | vcpu_e500->gtlb_priv[1][esel].ref.flags |= E500_TLB_BITMAP; | ||
513 | if (vcpu_e500->h2g_tlb1_rmap[sesel]) { | 499 | if (vcpu_e500->h2g_tlb1_rmap[sesel]) { |
514 | unsigned int idx = vcpu_e500->h2g_tlb1_rmap[sesel]; | 500 | unsigned int idx = vcpu_e500->h2g_tlb1_rmap[sesel] - 1; |
515 | vcpu_e500->g2h_tlb1_map[idx] &= ~(1ULL << sesel); | 501 | vcpu_e500->g2h_tlb1_map[idx] &= ~(1ULL << sesel); |
516 | } | 502 | } |
517 | vcpu_e500->h2g_tlb1_rmap[sesel] = esel; | 503 | |
504 | vcpu_e500->gtlb_priv[1][esel].ref.flags |= E500_TLB_BITMAP; | ||
505 | vcpu_e500->g2h_tlb1_map[esel] |= (u64)1 << sesel; | ||
506 | vcpu_e500->h2g_tlb1_rmap[sesel] = esel + 1; | ||
507 | WARN_ON(!(ref->flags & E500_TLB_VALID)); | ||
518 | 508 | ||
519 | return sesel; | 509 | return sesel; |
520 | } | 510 | } |
@@ -526,13 +516,12 @@ static int kvmppc_e500_tlb1_map(struct kvmppc_vcpu_e500 *vcpu_e500, | |||
526 | u64 gvaddr, gfn_t gfn, struct kvm_book3e_206_tlb_entry *gtlbe, | 516 | u64 gvaddr, gfn_t gfn, struct kvm_book3e_206_tlb_entry *gtlbe, |
527 | struct kvm_book3e_206_tlb_entry *stlbe, int esel) | 517 | struct kvm_book3e_206_tlb_entry *stlbe, int esel) |
528 | { | 518 | { |
529 | struct tlbe_ref ref; | 519 | struct tlbe_ref *ref = &vcpu_e500->gtlb_priv[1][esel].ref; |
530 | int sesel; | 520 | int sesel; |
531 | int r; | 521 | int r; |
532 | 522 | ||
533 | ref.flags = 0; | ||
534 | r = kvmppc_e500_shadow_map(vcpu_e500, gvaddr, gfn, gtlbe, 1, stlbe, | 523 | r = kvmppc_e500_shadow_map(vcpu_e500, gvaddr, gfn, gtlbe, 1, stlbe, |
535 | &ref); | 524 | ref); |
536 | if (r) | 525 | if (r) |
537 | return r; | 526 | return r; |
538 | 527 | ||
@@ -544,7 +533,7 @@ static int kvmppc_e500_tlb1_map(struct kvmppc_vcpu_e500 *vcpu_e500, | |||
544 | } | 533 | } |
545 | 534 | ||
546 | /* Otherwise map into TLB1 */ | 535 | /* Otherwise map into TLB1 */ |
547 | sesel = kvmppc_e500_tlb1_map_tlb1(vcpu_e500, &ref, esel); | 536 | sesel = kvmppc_e500_tlb1_map_tlb1(vcpu_e500, ref, esel); |
548 | write_stlbe(vcpu_e500, gtlbe, stlbe, 1, sesel); | 537 | write_stlbe(vcpu_e500, gtlbe, stlbe, 1, sesel); |
549 | 538 | ||
550 | return 0; | 539 | return 0; |
@@ -565,7 +554,7 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 eaddr, gpa_t gpaddr, | |||
565 | case 0: | 554 | case 0: |
566 | priv = &vcpu_e500->gtlb_priv[tlbsel][esel]; | 555 | priv = &vcpu_e500->gtlb_priv[tlbsel][esel]; |
567 | 556 | ||
568 | /* Triggers after clear_tlb_refs or on initial mapping */ | 557 | /* Triggers after clear_tlb_privs or on initial mapping */ |
569 | if (!(priv->ref.flags & E500_TLB_VALID)) { | 558 | if (!(priv->ref.flags & E500_TLB_VALID)) { |
570 | kvmppc_e500_tlb0_map(vcpu_e500, esel, &stlbe); | 559 | kvmppc_e500_tlb0_map(vcpu_e500, esel, &stlbe); |
571 | } else { | 560 | } else { |
@@ -665,35 +654,16 @@ int e500_mmu_host_init(struct kvmppc_vcpu_e500 *vcpu_e500) | |||
665 | host_tlb_params[0].entries / host_tlb_params[0].ways; | 654 | host_tlb_params[0].entries / host_tlb_params[0].ways; |
666 | host_tlb_params[1].sets = 1; | 655 | host_tlb_params[1].sets = 1; |
667 | 656 | ||
668 | vcpu_e500->tlb_refs[0] = | ||
669 | kzalloc(sizeof(struct tlbe_ref) * host_tlb_params[0].entries, | ||
670 | GFP_KERNEL); | ||
671 | if (!vcpu_e500->tlb_refs[0]) | ||
672 | goto err; | ||
673 | |||
674 | vcpu_e500->tlb_refs[1] = | ||
675 | kzalloc(sizeof(struct tlbe_ref) * host_tlb_params[1].entries, | ||
676 | GFP_KERNEL); | ||
677 | if (!vcpu_e500->tlb_refs[1]) | ||
678 | goto err; | ||
679 | |||
680 | vcpu_e500->h2g_tlb1_rmap = kzalloc(sizeof(unsigned int) * | 657 | vcpu_e500->h2g_tlb1_rmap = kzalloc(sizeof(unsigned int) * |
681 | host_tlb_params[1].entries, | 658 | host_tlb_params[1].entries, |
682 | GFP_KERNEL); | 659 | GFP_KERNEL); |
683 | if (!vcpu_e500->h2g_tlb1_rmap) | 660 | if (!vcpu_e500->h2g_tlb1_rmap) |
684 | goto err; | 661 | return -EINVAL; |
685 | 662 | ||
686 | return 0; | 663 | return 0; |
687 | |||
688 | err: | ||
689 | kfree(vcpu_e500->tlb_refs[0]); | ||
690 | kfree(vcpu_e500->tlb_refs[1]); | ||
691 | return -EINVAL; | ||
692 | } | 664 | } |
693 | 665 | ||
694 | void e500_mmu_host_uninit(struct kvmppc_vcpu_e500 *vcpu_e500) | 666 | void e500_mmu_host_uninit(struct kvmppc_vcpu_e500 *vcpu_e500) |
695 | { | 667 | { |
696 | kfree(vcpu_e500->h2g_tlb1_rmap); | 668 | kfree(vcpu_e500->h2g_tlb1_rmap); |
697 | kfree(vcpu_e500->tlb_refs[0]); | ||
698 | kfree(vcpu_e500->tlb_refs[1]); | ||
699 | } | 669 | } |
diff --git a/arch/powerpc/kvm/e500mc.c b/arch/powerpc/kvm/e500mc.c index 1f89d26e65fb..2f4baa074b2e 100644 --- a/arch/powerpc/kvm/e500mc.c +++ b/arch/powerpc/kvm/e500mc.c | |||
@@ -108,6 +108,8 @@ void kvmppc_mmu_msr_notify(struct kvm_vcpu *vcpu, u32 old_msr) | |||
108 | { | 108 | { |
109 | } | 109 | } |
110 | 110 | ||
111 | static DEFINE_PER_CPU(struct kvm_vcpu *, last_vcpu_on_cpu); | ||
112 | |||
111 | void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | 113 | void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) |
112 | { | 114 | { |
113 | struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); | 115 | struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); |
@@ -136,8 +138,11 @@ void kvmppc_core_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
136 | mtspr(SPRN_GDEAR, vcpu->arch.shared->dar); | 138 | mtspr(SPRN_GDEAR, vcpu->arch.shared->dar); |
137 | mtspr(SPRN_GESR, vcpu->arch.shared->esr); | 139 | mtspr(SPRN_GESR, vcpu->arch.shared->esr); |
138 | 140 | ||
139 | if (vcpu->arch.oldpir != mfspr(SPRN_PIR)) | 141 | if (vcpu->arch.oldpir != mfspr(SPRN_PIR) || |
142 | __get_cpu_var(last_vcpu_on_cpu) != vcpu) { | ||
140 | kvmppc_e500_tlbil_all(vcpu_e500); | 143 | kvmppc_e500_tlbil_all(vcpu_e500); |
144 | __get_cpu_var(last_vcpu_on_cpu) = vcpu; | ||
145 | } | ||
141 | 146 | ||
142 | kvmppc_load_guest_fp(vcpu); | 147 | kvmppc_load_guest_fp(vcpu); |
143 | } | 148 | } |
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 7e2246fb2f31..5a535b73ea18 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c | |||
@@ -263,19 +263,14 @@ static __meminit void vmemmap_list_populate(unsigned long phys, | |||
263 | vmemmap_list = vmem_back; | 263 | vmemmap_list = vmem_back; |
264 | } | 264 | } |
265 | 265 | ||
266 | int __meminit vmemmap_populate(struct page *start_page, | 266 | int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) |
267 | unsigned long nr_pages, int node) | ||
268 | { | 267 | { |
269 | unsigned long start = (unsigned long)start_page; | ||
270 | unsigned long end = (unsigned long)(start_page + nr_pages); | ||
271 | unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift; | 268 | unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift; |
272 | 269 | ||
273 | /* Align to the page size of the linear mapping. */ | 270 | /* Align to the page size of the linear mapping. */ |
274 | start = _ALIGN_DOWN(start, page_size); | 271 | start = _ALIGN_DOWN(start, page_size); |
275 | 272 | ||
276 | pr_debug("vmemmap_populate page %p, %ld pages, node %d\n", | 273 | pr_debug("vmemmap_populate %lx..%lx, node %d\n", start, end, node); |
277 | start_page, nr_pages, node); | ||
278 | pr_debug(" -> map %lx..%lx\n", start, end); | ||
279 | 274 | ||
280 | for (; start < end; start += page_size) { | 275 | for (; start < end; start += page_size) { |
281 | void *p; | 276 | void *p; |
@@ -298,7 +293,7 @@ int __meminit vmemmap_populate(struct page *start_page, | |||
298 | return 0; | 293 | return 0; |
299 | } | 294 | } |
300 | 295 | ||
301 | void vmemmap_free(struct page *memmap, unsigned long nr_pages) | 296 | void vmemmap_free(unsigned long start, unsigned long end) |
302 | { | 297 | { |
303 | } | 298 | } |
304 | 299 | ||
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index f1f7409a4183..cd76c454942f 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c | |||
@@ -352,13 +352,9 @@ void __init mem_init(void) | |||
352 | struct page *page = pfn_to_page(pfn); | 352 | struct page *page = pfn_to_page(pfn); |
353 | if (memblock_is_reserved(paddr)) | 353 | if (memblock_is_reserved(paddr)) |
354 | continue; | 354 | continue; |
355 | ClearPageReserved(page); | 355 | free_highmem_page(page); |
356 | init_page_count(page); | ||
357 | __free_page(page); | ||
358 | totalhigh_pages++; | ||
359 | reservedpages--; | 356 | reservedpages--; |
360 | } | 357 | } |
361 | totalram_pages += totalhigh_pages; | ||
362 | printk(KERN_DEBUG "High memory: %luk\n", | 358 | printk(KERN_DEBUG "High memory: %luk\n", |
363 | totalhigh_pages << (PAGE_SHIFT-10)); | 359 | totalhigh_pages << (PAGE_SHIFT-10)); |
364 | } | 360 | } |
@@ -405,39 +401,14 @@ void __init mem_init(void) | |||
405 | 401 | ||
406 | void free_initmem(void) | 402 | void free_initmem(void) |
407 | { | 403 | { |
408 | unsigned long addr; | ||
409 | |||
410 | ppc_md.progress = ppc_printk_progress; | 404 | ppc_md.progress = ppc_printk_progress; |
411 | 405 | free_initmem_default(POISON_FREE_INITMEM); | |
412 | addr = (unsigned long)__init_begin; | ||
413 | for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) { | ||
414 | memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); | ||
415 | ClearPageReserved(virt_to_page(addr)); | ||
416 | init_page_count(virt_to_page(addr)); | ||
417 | free_page(addr); | ||
418 | totalram_pages++; | ||
419 | } | ||
420 | pr_info("Freeing unused kernel memory: %luk freed\n", | ||
421 | ((unsigned long)__init_end - | ||
422 | (unsigned long)__init_begin) >> 10); | ||
423 | } | 406 | } |
424 | 407 | ||
425 | #ifdef CONFIG_BLK_DEV_INITRD | 408 | #ifdef CONFIG_BLK_DEV_INITRD |
426 | void __init free_initrd_mem(unsigned long start, unsigned long end) | 409 | void __init free_initrd_mem(unsigned long start, unsigned long end) |
427 | { | 410 | { |
428 | if (start >= end) | 411 | free_reserved_area(start, end, 0, "initrd"); |
429 | return; | ||
430 | |||
431 | start = _ALIGN_DOWN(start, PAGE_SIZE); | ||
432 | end = _ALIGN_UP(end, PAGE_SIZE); | ||
433 | pr_info("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); | ||
434 | |||
435 | for (; start < end; start += PAGE_SIZE) { | ||
436 | ClearPageReserved(virt_to_page(start)); | ||
437 | init_page_count(virt_to_page(start)); | ||
438 | free_page(start); | ||
439 | totalram_pages++; | ||
440 | } | ||
441 | } | 412 | } |
442 | #endif | 413 | #endif |
443 | 414 | ||
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index bba87ca2b4d7..fa33c546e778 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/pfn.h> | 22 | #include <linux/pfn.h> |
23 | #include <linux/cpuset.h> | 23 | #include <linux/cpuset.h> |
24 | #include <linux/node.h> | 24 | #include <linux/node.h> |
25 | #include <linux/slab.h> | ||
25 | #include <asm/sparsemem.h> | 26 | #include <asm/sparsemem.h> |
26 | #include <asm/prom.h> | 27 | #include <asm/prom.h> |
27 | #include <asm/smp.h> | 28 | #include <asm/smp.h> |
@@ -62,14 +63,11 @@ static int distance_lookup_table[MAX_NUMNODES][MAX_DISTANCE_REF_POINTS]; | |||
62 | */ | 63 | */ |
63 | static void __init setup_node_to_cpumask_map(void) | 64 | static void __init setup_node_to_cpumask_map(void) |
64 | { | 65 | { |
65 | unsigned int node, num = 0; | 66 | unsigned int node; |
66 | 67 | ||
67 | /* setup nr_node_ids if not done yet */ | 68 | /* setup nr_node_ids if not done yet */ |
68 | if (nr_node_ids == MAX_NUMNODES) { | 69 | if (nr_node_ids == MAX_NUMNODES) |
69 | for_each_node_mask(node, node_possible_map) | 70 | setup_nr_node_ids(); |
70 | num = node; | ||
71 | nr_node_ids = num + 1; | ||
72 | } | ||
73 | 71 | ||
74 | /* allocate the map */ | 72 | /* allocate the map */ |
75 | for (node = 0; node < nr_node_ids; node++) | 73 | for (node = 0; node < nr_node_ids; node++) |
diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index 0effe9f5a1ea..7be93367d92f 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig | |||
@@ -274,6 +274,8 @@ config 440EPX | |||
274 | select IBM_EMAC_EMAC4 | 274 | select IBM_EMAC_EMAC4 |
275 | select IBM_EMAC_RGMII | 275 | select IBM_EMAC_RGMII |
276 | select IBM_EMAC_ZMII | 276 | select IBM_EMAC_ZMII |
277 | select USB_EHCI_BIG_ENDIAN_MMIO | ||
278 | select USB_EHCI_BIG_ENDIAN_DESC | ||
277 | 279 | ||
278 | config 440GRX | 280 | config 440GRX |
279 | bool | 281 | bool |
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig index c16999802ecf..381a592826a2 100644 --- a/arch/powerpc/platforms/512x/Kconfig +++ b/arch/powerpc/platforms/512x/Kconfig | |||
@@ -7,6 +7,8 @@ config PPC_MPC512x | |||
7 | select PPC_PCI_CHOICE | 7 | select PPC_PCI_CHOICE |
8 | select FSL_PCI if PCI | 8 | select FSL_PCI if PCI |
9 | select ARCH_WANT_OPTIONAL_GPIOLIB | 9 | select ARCH_WANT_OPTIONAL_GPIOLIB |
10 | select USB_EHCI_BIG_ENDIAN_MMIO | ||
11 | select USB_EHCI_BIG_ENDIAN_DESC | ||
10 | 12 | ||
11 | config MPC5121_ADS | 13 | config MPC5121_ADS |
12 | bool "Freescale MPC5121E ADS" | 14 | bool "Freescale MPC5121E ADS" |
diff --git a/arch/powerpc/platforms/512x/mpc512x_shared.c b/arch/powerpc/platforms/512x/mpc512x_shared.c index d30235b7e3f7..db6ac389ef8c 100644 --- a/arch/powerpc/platforms/512x/mpc512x_shared.c +++ b/arch/powerpc/platforms/512x/mpc512x_shared.c | |||
@@ -172,12 +172,9 @@ static struct fsl_diu_shared_fb __attribute__ ((__aligned__(8))) diu_shared_fb; | |||
172 | 172 | ||
173 | static inline void mpc512x_free_bootmem(struct page *page) | 173 | static inline void mpc512x_free_bootmem(struct page *page) |
174 | { | 174 | { |
175 | __ClearPageReserved(page); | ||
176 | BUG_ON(PageTail(page)); | 175 | BUG_ON(PageTail(page)); |
177 | BUG_ON(atomic_read(&page->_count) > 1); | 176 | BUG_ON(atomic_read(&page->_count) > 1); |
178 | atomic_set(&page->_count, 1); | 177 | free_reserved_page(page); |
179 | __free_page(page); | ||
180 | totalram_pages++; | ||
181 | } | 178 | } |
182 | 179 | ||
183 | void mpc512x_release_bootmem(void) | 180 | void mpc512x_release_bootmem(void) |
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 2372c609fa2b..9a432de363b8 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c | |||
@@ -72,6 +72,7 @@ unsigned long memory_block_size_bytes(void) | |||
72 | return get_memblock_size(); | 72 | return get_memblock_size(); |
73 | } | 73 | } |
74 | 74 | ||
75 | #ifdef CONFIG_MEMORY_HOTREMOVE | ||
75 | static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size) | 76 | static int pseries_remove_memblock(unsigned long base, unsigned int memblock_size) |
76 | { | 77 | { |
77 | unsigned long start, start_pfn; | 78 | unsigned long start, start_pfn; |
@@ -153,6 +154,17 @@ static int pseries_remove_memory(struct device_node *np) | |||
153 | ret = pseries_remove_memblock(base, lmb_size); | 154 | ret = pseries_remove_memblock(base, lmb_size); |
154 | return ret; | 155 | return ret; |
155 | } | 156 | } |
157 | #else | ||
158 | static inline int pseries_remove_memblock(unsigned long base, | ||
159 | unsigned int memblock_size) | ||
160 | { | ||
161 | return -EOPNOTSUPP; | ||
162 | } | ||
163 | static inline int pseries_remove_memory(struct device_node *np) | ||
164 | { | ||
165 | return -EOPNOTSUPP; | ||
166 | } | ||
167 | #endif /* CONFIG_MEMORY_HOTREMOVE */ | ||
156 | 168 | ||
157 | static int pseries_add_memory(struct device_node *np) | 169 | static int pseries_add_memory(struct device_node *np) |
158 | { | 170 | { |
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 0da39fed355a..299731e9036b 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c | |||
@@ -186,7 +186,13 @@ static long pSeries_lpar_hpte_remove(unsigned long hpte_group) | |||
186 | (0x1UL << 4), &dummy1, &dummy2); | 186 | (0x1UL << 4), &dummy1, &dummy2); |
187 | if (lpar_rc == H_SUCCESS) | 187 | if (lpar_rc == H_SUCCESS) |
188 | return i; | 188 | return i; |
189 | BUG_ON(lpar_rc != H_NOT_FOUND); | 189 | |
190 | /* | ||
191 | * The test for adjunct partition is performed before the | ||
192 | * ANDCOND test. H_RESOURCE may be returned, so we need to | ||
193 | * check for that as well. | ||
194 | */ | ||
195 | BUG_ON(lpar_rc != H_NOT_FOUND && lpar_rc != H_RESOURCE); | ||
190 | 196 | ||
191 | slot_offset++; | 197 | slot_offset++; |
192 | slot_offset &= 0x7; | 198 | slot_offset &= 0x7; |
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index eb8fb629f00b..bda6ba6f3cf5 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -375,19 +375,6 @@ config PACK_STACK | |||
375 | 375 | ||
376 | Say Y if you are unsure. | 376 | Say Y if you are unsure. |
377 | 377 | ||
378 | config SMALL_STACK | ||
379 | def_bool n | ||
380 | prompt "Use 8kb for kernel stack instead of 16kb" | ||
381 | depends on PACK_STACK && 64BIT && !LOCKDEP | ||
382 | help | ||
383 | If you say Y here and the compiler supports the -mkernel-backchain | ||
384 | option the kernel will use a smaller kernel stack size. The reduced | ||
385 | size is 8kb instead of 16kb. This allows to run more threads on a | ||
386 | system and reduces the pressure on the memory management for higher | ||
387 | order page allocations. | ||
388 | |||
389 | Say N if you are unsure. | ||
390 | |||
391 | config CHECK_STACK | 378 | config CHECK_STACK |
392 | def_bool y | 379 | def_bool y |
393 | prompt "Detect kernel stack overflow" | 380 | prompt "Detect kernel stack overflow" |
diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 7e3ce78d4290..a7d68a467ce8 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile | |||
@@ -55,22 +55,12 @@ cflags-$(CONFIG_FRAME_POINTER) += -fno-optimize-sibling-calls | |||
55 | ifeq ($(call cc-option-yn,-mkernel-backchain),y) | 55 | ifeq ($(call cc-option-yn,-mkernel-backchain),y) |
56 | cflags-$(CONFIG_PACK_STACK) += -mkernel-backchain -D__PACK_STACK | 56 | cflags-$(CONFIG_PACK_STACK) += -mkernel-backchain -D__PACK_STACK |
57 | aflags-$(CONFIG_PACK_STACK) += -D__PACK_STACK | 57 | aflags-$(CONFIG_PACK_STACK) += -D__PACK_STACK |
58 | cflags-$(CONFIG_SMALL_STACK) += -D__SMALL_STACK | ||
59 | aflags-$(CONFIG_SMALL_STACK) += -D__SMALL_STACK | ||
60 | ifdef CONFIG_SMALL_STACK | ||
61 | STACK_SIZE := $(shell echo $$(($(STACK_SIZE)/2)) ) | ||
62 | endif | ||
63 | endif | 58 | endif |
64 | 59 | ||
65 | # new style option for packed stacks | 60 | # new style option for packed stacks |
66 | ifeq ($(call cc-option-yn,-mpacked-stack),y) | 61 | ifeq ($(call cc-option-yn,-mpacked-stack),y) |
67 | cflags-$(CONFIG_PACK_STACK) += -mpacked-stack -D__PACK_STACK | 62 | cflags-$(CONFIG_PACK_STACK) += -mpacked-stack -D__PACK_STACK |
68 | aflags-$(CONFIG_PACK_STACK) += -D__PACK_STACK | 63 | aflags-$(CONFIG_PACK_STACK) += -D__PACK_STACK |
69 | cflags-$(CONFIG_SMALL_STACK) += -D__SMALL_STACK | ||
70 | aflags-$(CONFIG_SMALL_STACK) += -D__SMALL_STACK | ||
71 | ifdef CONFIG_SMALL_STACK | ||
72 | STACK_SIZE := $(shell echo $$(($(STACK_SIZE)/2)) ) | ||
73 | endif | ||
74 | endif | 64 | endif |
75 | 65 | ||
76 | ifeq ($(call cc-option-yn,-mstack-size=8192 -mstack-guard=128),y) | 66 | ifeq ($(call cc-option-yn,-mstack-size=8192 -mstack-guard=128),y) |
diff --git a/arch/s390/hypfs/hypfs_dbfs.c b/arch/s390/hypfs/hypfs_dbfs.c index 9fd4a40c6752..bb5dd496614f 100644 --- a/arch/s390/hypfs/hypfs_dbfs.c +++ b/arch/s390/hypfs/hypfs_dbfs.c | |||
@@ -105,9 +105,7 @@ void hypfs_dbfs_remove_file(struct hypfs_dbfs_file *df) | |||
105 | int hypfs_dbfs_init(void) | 105 | int hypfs_dbfs_init(void) |
106 | { | 106 | { |
107 | dbfs_dir = debugfs_create_dir("s390_hypfs", NULL); | 107 | dbfs_dir = debugfs_create_dir("s390_hypfs", NULL); |
108 | if (IS_ERR(dbfs_dir)) | 108 | return PTR_RET(dbfs_dir); |
109 | return PTR_ERR(dbfs_dir); | ||
110 | return 0; | ||
111 | } | 109 | } |
112 | 110 | ||
113 | void hypfs_dbfs_exit(void) | 111 | void hypfs_dbfs_exit(void) |
diff --git a/arch/s390/include/asm/bitops.h b/arch/s390/include/asm/bitops.h index 15422933c60b..4d8604e311f3 100644 --- a/arch/s390/include/asm/bitops.h +++ b/arch/s390/include/asm/bitops.h | |||
@@ -61,8 +61,6 @@ extern const char _sb_findmap[]; | |||
61 | 61 | ||
62 | #ifndef CONFIG_64BIT | 62 | #ifndef CONFIG_64BIT |
63 | 63 | ||
64 | #define __BITOPS_ALIGN 3 | ||
65 | #define __BITOPS_WORDSIZE 32 | ||
66 | #define __BITOPS_OR "or" | 64 | #define __BITOPS_OR "or" |
67 | #define __BITOPS_AND "nr" | 65 | #define __BITOPS_AND "nr" |
68 | #define __BITOPS_XOR "xr" | 66 | #define __BITOPS_XOR "xr" |
@@ -81,8 +79,6 @@ extern const char _sb_findmap[]; | |||
81 | 79 | ||
82 | #else /* CONFIG_64BIT */ | 80 | #else /* CONFIG_64BIT */ |
83 | 81 | ||
84 | #define __BITOPS_ALIGN 7 | ||
85 | #define __BITOPS_WORDSIZE 64 | ||
86 | #define __BITOPS_OR "ogr" | 82 | #define __BITOPS_OR "ogr" |
87 | #define __BITOPS_AND "ngr" | 83 | #define __BITOPS_AND "ngr" |
88 | #define __BITOPS_XOR "xgr" | 84 | #define __BITOPS_XOR "xgr" |
@@ -101,8 +97,7 @@ extern const char _sb_findmap[]; | |||
101 | 97 | ||
102 | #endif /* CONFIG_64BIT */ | 98 | #endif /* CONFIG_64BIT */ |
103 | 99 | ||
104 | #define __BITOPS_WORDS(bits) (((bits)+__BITOPS_WORDSIZE-1)/__BITOPS_WORDSIZE) | 100 | #define __BITOPS_WORDS(bits) (((bits) + BITS_PER_LONG - 1) / BITS_PER_LONG) |
105 | #define __BITOPS_BARRIER() asm volatile("" : : : "memory") | ||
106 | 101 | ||
107 | #ifdef CONFIG_SMP | 102 | #ifdef CONFIG_SMP |
108 | /* | 103 | /* |
@@ -114,9 +109,9 @@ static inline void set_bit_cs(unsigned long nr, volatile unsigned long *ptr) | |||
114 | 109 | ||
115 | addr = (unsigned long) ptr; | 110 | addr = (unsigned long) ptr; |
116 | /* calculate address for CS */ | 111 | /* calculate address for CS */ |
117 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | 112 | addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; |
118 | /* make OR mask */ | 113 | /* make OR mask */ |
119 | mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1)); | 114 | mask = 1UL << (nr & (BITS_PER_LONG - 1)); |
120 | /* Do the atomic update. */ | 115 | /* Do the atomic update. */ |
121 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_OR); | 116 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_OR); |
122 | } | 117 | } |
@@ -130,9 +125,9 @@ static inline void clear_bit_cs(unsigned long nr, volatile unsigned long *ptr) | |||
130 | 125 | ||
131 | addr = (unsigned long) ptr; | 126 | addr = (unsigned long) ptr; |
132 | /* calculate address for CS */ | 127 | /* calculate address for CS */ |
133 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | 128 | addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; |
134 | /* make AND mask */ | 129 | /* make AND mask */ |
135 | mask = ~(1UL << (nr & (__BITOPS_WORDSIZE - 1))); | 130 | mask = ~(1UL << (nr & (BITS_PER_LONG - 1))); |
136 | /* Do the atomic update. */ | 131 | /* Do the atomic update. */ |
137 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_AND); | 132 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_AND); |
138 | } | 133 | } |
@@ -146,9 +141,9 @@ static inline void change_bit_cs(unsigned long nr, volatile unsigned long *ptr) | |||
146 | 141 | ||
147 | addr = (unsigned long) ptr; | 142 | addr = (unsigned long) ptr; |
148 | /* calculate address for CS */ | 143 | /* calculate address for CS */ |
149 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | 144 | addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; |
150 | /* make XOR mask */ | 145 | /* make XOR mask */ |
151 | mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1)); | 146 | mask = 1UL << (nr & (BITS_PER_LONG - 1)); |
152 | /* Do the atomic update. */ | 147 | /* Do the atomic update. */ |
153 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_XOR); | 148 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_XOR); |
154 | } | 149 | } |
@@ -163,12 +158,12 @@ test_and_set_bit_cs(unsigned long nr, volatile unsigned long *ptr) | |||
163 | 158 | ||
164 | addr = (unsigned long) ptr; | 159 | addr = (unsigned long) ptr; |
165 | /* calculate address for CS */ | 160 | /* calculate address for CS */ |
166 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | 161 | addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; |
167 | /* make OR/test mask */ | 162 | /* make OR/test mask */ |
168 | mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1)); | 163 | mask = 1UL << (nr & (BITS_PER_LONG - 1)); |
169 | /* Do the atomic update. */ | 164 | /* Do the atomic update. */ |
170 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_OR); | 165 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_OR); |
171 | __BITOPS_BARRIER(); | 166 | barrier(); |
172 | return (old & mask) != 0; | 167 | return (old & mask) != 0; |
173 | } | 168 | } |
174 | 169 | ||
@@ -182,12 +177,12 @@ test_and_clear_bit_cs(unsigned long nr, volatile unsigned long *ptr) | |||
182 | 177 | ||
183 | addr = (unsigned long) ptr; | 178 | addr = (unsigned long) ptr; |
184 | /* calculate address for CS */ | 179 | /* calculate address for CS */ |
185 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | 180 | addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; |
186 | /* make AND/test mask */ | 181 | /* make AND/test mask */ |
187 | mask = ~(1UL << (nr & (__BITOPS_WORDSIZE - 1))); | 182 | mask = ~(1UL << (nr & (BITS_PER_LONG - 1))); |
188 | /* Do the atomic update. */ | 183 | /* Do the atomic update. */ |
189 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_AND); | 184 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_AND); |
190 | __BITOPS_BARRIER(); | 185 | barrier(); |
191 | return (old ^ new) != 0; | 186 | return (old ^ new) != 0; |
192 | } | 187 | } |
193 | 188 | ||
@@ -201,12 +196,12 @@ test_and_change_bit_cs(unsigned long nr, volatile unsigned long *ptr) | |||
201 | 196 | ||
202 | addr = (unsigned long) ptr; | 197 | addr = (unsigned long) ptr; |
203 | /* calculate address for CS */ | 198 | /* calculate address for CS */ |
204 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | 199 | addr += (nr ^ (nr & (BITS_PER_LONG - 1))) >> 3; |
205 | /* make XOR/test mask */ | 200 | /* make XOR/test mask */ |
206 | mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1)); | 201 | mask = 1UL << (nr & (BITS_PER_LONG - 1)); |
207 | /* Do the atomic update. */ | 202 | /* Do the atomic update. */ |
208 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_XOR); | 203 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_XOR); |
209 | __BITOPS_BARRIER(); | 204 | barrier(); |
210 | return (old & mask) != 0; | 205 | return (old & mask) != 0; |
211 | } | 206 | } |
212 | #endif /* CONFIG_SMP */ | 207 | #endif /* CONFIG_SMP */ |
@@ -218,7 +213,7 @@ static inline void __set_bit(unsigned long nr, volatile unsigned long *ptr) | |||
218 | { | 213 | { |
219 | unsigned long addr; | 214 | unsigned long addr; |
220 | 215 | ||
221 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | 216 | addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); |
222 | asm volatile( | 217 | asm volatile( |
223 | " oc %O0(1,%R0),%1" | 218 | " oc %O0(1,%R0),%1" |
224 | : "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc" ); | 219 | : "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc" ); |
@@ -229,7 +224,7 @@ __constant_set_bit(const unsigned long nr, volatile unsigned long *ptr) | |||
229 | { | 224 | { |
230 | unsigned long addr; | 225 | unsigned long addr; |
231 | 226 | ||
232 | addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | 227 | addr = ((unsigned long) ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3); |
233 | *(unsigned char *) addr |= 1 << (nr & 7); | 228 | *(unsigned char *) addr |= 1 << (nr & 7); |
234 | } | 229 | } |
235 | 230 | ||
@@ -246,7 +241,7 @@ __clear_bit(unsigned long nr, volatile unsigned long *ptr) | |||
246 | { | 241 | { |
247 | unsigned long addr; | 242 | unsigned long addr; |
248 | 243 | ||
249 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | 244 | addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); |
250 | asm volatile( | 245 | asm volatile( |
251 | " nc %O0(1,%R0),%1" | 246 | " nc %O0(1,%R0),%1" |
252 | : "=Q" (*(char *) addr) : "Q" (_ni_bitmap[nr & 7]) : "cc" ); | 247 | : "=Q" (*(char *) addr) : "Q" (_ni_bitmap[nr & 7]) : "cc" ); |
@@ -257,7 +252,7 @@ __constant_clear_bit(const unsigned long nr, volatile unsigned long *ptr) | |||
257 | { | 252 | { |
258 | unsigned long addr; | 253 | unsigned long addr; |
259 | 254 | ||
260 | addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | 255 | addr = ((unsigned long) ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3); |
261 | *(unsigned char *) addr &= ~(1 << (nr & 7)); | 256 | *(unsigned char *) addr &= ~(1 << (nr & 7)); |
262 | } | 257 | } |
263 | 258 | ||
@@ -273,7 +268,7 @@ static inline void __change_bit(unsigned long nr, volatile unsigned long *ptr) | |||
273 | { | 268 | { |
274 | unsigned long addr; | 269 | unsigned long addr; |
275 | 270 | ||
276 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | 271 | addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); |
277 | asm volatile( | 272 | asm volatile( |
278 | " xc %O0(1,%R0),%1" | 273 | " xc %O0(1,%R0),%1" |
279 | : "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc" ); | 274 | : "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc" ); |
@@ -284,7 +279,7 @@ __constant_change_bit(const unsigned long nr, volatile unsigned long *ptr) | |||
284 | { | 279 | { |
285 | unsigned long addr; | 280 | unsigned long addr; |
286 | 281 | ||
287 | addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | 282 | addr = ((unsigned long) ptr) + ((nr ^ (BITS_PER_LONG - 8)) >> 3); |
288 | *(unsigned char *) addr ^= 1 << (nr & 7); | 283 | *(unsigned char *) addr ^= 1 << (nr & 7); |
289 | } | 284 | } |
290 | 285 | ||
@@ -302,7 +297,7 @@ test_and_set_bit_simple(unsigned long nr, volatile unsigned long *ptr) | |||
302 | unsigned long addr; | 297 | unsigned long addr; |
303 | unsigned char ch; | 298 | unsigned char ch; |
304 | 299 | ||
305 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | 300 | addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); |
306 | ch = *(unsigned char *) addr; | 301 | ch = *(unsigned char *) addr; |
307 | asm volatile( | 302 | asm volatile( |
308 | " oc %O0(1,%R0),%1" | 303 | " oc %O0(1,%R0),%1" |
@@ -321,7 +316,7 @@ test_and_clear_bit_simple(unsigned long nr, volatile unsigned long *ptr) | |||
321 | unsigned long addr; | 316 | unsigned long addr; |
322 | unsigned char ch; | 317 | unsigned char ch; |
323 | 318 | ||
324 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | 319 | addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); |
325 | ch = *(unsigned char *) addr; | 320 | ch = *(unsigned char *) addr; |
326 | asm volatile( | 321 | asm volatile( |
327 | " nc %O0(1,%R0),%1" | 322 | " nc %O0(1,%R0),%1" |
@@ -340,7 +335,7 @@ test_and_change_bit_simple(unsigned long nr, volatile unsigned long *ptr) | |||
340 | unsigned long addr; | 335 | unsigned long addr; |
341 | unsigned char ch; | 336 | unsigned char ch; |
342 | 337 | ||
343 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | 338 | addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); |
344 | ch = *(unsigned char *) addr; | 339 | ch = *(unsigned char *) addr; |
345 | asm volatile( | 340 | asm volatile( |
346 | " xc %O0(1,%R0),%1" | 341 | " xc %O0(1,%R0),%1" |
@@ -376,7 +371,7 @@ static inline int __test_bit(unsigned long nr, const volatile unsigned long *ptr | |||
376 | unsigned long addr; | 371 | unsigned long addr; |
377 | unsigned char ch; | 372 | unsigned char ch; |
378 | 373 | ||
379 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | 374 | addr = (unsigned long) ptr + ((nr ^ (BITS_PER_LONG - 8)) >> 3); |
380 | ch = *(volatile unsigned char *) addr; | 375 | ch = *(volatile unsigned char *) addr; |
381 | return (ch >> (nr & 7)) & 1; | 376 | return (ch >> (nr & 7)) & 1; |
382 | } | 377 | } |
@@ -384,7 +379,7 @@ static inline int __test_bit(unsigned long nr, const volatile unsigned long *ptr | |||
384 | static inline int | 379 | static inline int |
385 | __constant_test_bit(unsigned long nr, const volatile unsigned long *addr) { | 380 | __constant_test_bit(unsigned long nr, const volatile unsigned long *addr) { |
386 | return (((volatile char *) addr) | 381 | return (((volatile char *) addr) |
387 | [(nr^(__BITOPS_WORDSIZE-8))>>3] & (1<<(nr&7))) != 0; | 382 | [(nr^(BITS_PER_LONG-8))>>3] & (1<<(nr&7))) != 0; |
388 | } | 383 | } |
389 | 384 | ||
390 | #define test_bit(nr,addr) \ | 385 | #define test_bit(nr,addr) \ |
@@ -693,18 +688,18 @@ static inline int find_next_bit_left(const unsigned long *addr, | |||
693 | 688 | ||
694 | if (offset >= size) | 689 | if (offset >= size) |
695 | return size; | 690 | return size; |
696 | bit = offset & (__BITOPS_WORDSIZE - 1); | 691 | bit = offset & (BITS_PER_LONG - 1); |
697 | offset -= bit; | 692 | offset -= bit; |
698 | size -= offset; | 693 | size -= offset; |
699 | p = addr + offset / __BITOPS_WORDSIZE; | 694 | p = addr + offset / BITS_PER_LONG; |
700 | if (bit) { | 695 | if (bit) { |
701 | set = __flo_word(0, *p & (~0UL << bit)); | 696 | set = __flo_word(0, *p & (~0UL << bit)); |
702 | if (set >= size) | 697 | if (set >= size) |
703 | return size + offset; | 698 | return size + offset; |
704 | if (set < __BITOPS_WORDSIZE) | 699 | if (set < BITS_PER_LONG) |
705 | return set + offset; | 700 | return set + offset; |
706 | offset += __BITOPS_WORDSIZE; | 701 | offset += BITS_PER_LONG; |
707 | size -= __BITOPS_WORDSIZE; | 702 | size -= BITS_PER_LONG; |
708 | p++; | 703 | p++; |
709 | } | 704 | } |
710 | return offset + find_first_bit_left(p, size); | 705 | return offset + find_first_bit_left(p, size); |
@@ -736,22 +731,22 @@ static inline int find_next_zero_bit (const unsigned long * addr, | |||
736 | 731 | ||
737 | if (offset >= size) | 732 | if (offset >= size) |
738 | return size; | 733 | return size; |
739 | bit = offset & (__BITOPS_WORDSIZE - 1); | 734 | bit = offset & (BITS_PER_LONG - 1); |
740 | offset -= bit; | 735 | offset -= bit; |
741 | size -= offset; | 736 | size -= offset; |
742 | p = addr + offset / __BITOPS_WORDSIZE; | 737 | p = addr + offset / BITS_PER_LONG; |
743 | if (bit) { | 738 | if (bit) { |
744 | /* | 739 | /* |
745 | * __ffz_word returns __BITOPS_WORDSIZE | 740 | * __ffz_word returns BITS_PER_LONG |
746 | * if no zero bit is present in the word. | 741 | * if no zero bit is present in the word. |
747 | */ | 742 | */ |
748 | set = __ffz_word(bit, *p >> bit); | 743 | set = __ffz_word(bit, *p >> bit); |
749 | if (set >= size) | 744 | if (set >= size) |
750 | return size + offset; | 745 | return size + offset; |
751 | if (set < __BITOPS_WORDSIZE) | 746 | if (set < BITS_PER_LONG) |
752 | return set + offset; | 747 | return set + offset; |
753 | offset += __BITOPS_WORDSIZE; | 748 | offset += BITS_PER_LONG; |
754 | size -= __BITOPS_WORDSIZE; | 749 | size -= BITS_PER_LONG; |
755 | p++; | 750 | p++; |
756 | } | 751 | } |
757 | return offset + find_first_zero_bit(p, size); | 752 | return offset + find_first_zero_bit(p, size); |
@@ -773,22 +768,22 @@ static inline int find_next_bit (const unsigned long * addr, | |||
773 | 768 | ||
774 | if (offset >= size) | 769 | if (offset >= size) |
775 | return size; | 770 | return size; |
776 | bit = offset & (__BITOPS_WORDSIZE - 1); | 771 | bit = offset & (BITS_PER_LONG - 1); |
777 | offset -= bit; | 772 | offset -= bit; |
778 | size -= offset; | 773 | size -= offset; |
779 | p = addr + offset / __BITOPS_WORDSIZE; | 774 | p = addr + offset / BITS_PER_LONG; |
780 | if (bit) { | 775 | if (bit) { |
781 | /* | 776 | /* |
782 | * __ffs_word returns __BITOPS_WORDSIZE | 777 | * __ffs_word returns BITS_PER_LONG |
783 | * if no one bit is present in the word. | 778 | * if no one bit is present in the word. |
784 | */ | 779 | */ |
785 | set = __ffs_word(0, *p & (~0UL << bit)); | 780 | set = __ffs_word(0, *p & (~0UL << bit)); |
786 | if (set >= size) | 781 | if (set >= size) |
787 | return size + offset; | 782 | return size + offset; |
788 | if (set < __BITOPS_WORDSIZE) | 783 | if (set < BITS_PER_LONG) |
789 | return set + offset; | 784 | return set + offset; |
790 | offset += __BITOPS_WORDSIZE; | 785 | offset += BITS_PER_LONG; |
791 | size -= __BITOPS_WORDSIZE; | 786 | size -= BITS_PER_LONG; |
792 | p++; | 787 | p++; |
793 | } | 788 | } |
794 | return offset + find_first_bit(p, size); | 789 | return offset + find_first_bit(p, size); |
@@ -843,22 +838,22 @@ static inline int find_next_zero_bit_le(void *vaddr, unsigned long size, | |||
843 | 838 | ||
844 | if (offset >= size) | 839 | if (offset >= size) |
845 | return size; | 840 | return size; |
846 | bit = offset & (__BITOPS_WORDSIZE - 1); | 841 | bit = offset & (BITS_PER_LONG - 1); |
847 | offset -= bit; | 842 | offset -= bit; |
848 | size -= offset; | 843 | size -= offset; |
849 | p = addr + offset / __BITOPS_WORDSIZE; | 844 | p = addr + offset / BITS_PER_LONG; |
850 | if (bit) { | 845 | if (bit) { |
851 | /* | 846 | /* |
852 | * s390 version of ffz returns __BITOPS_WORDSIZE | 847 | * s390 version of ffz returns BITS_PER_LONG |
853 | * if no zero bit is present in the word. | 848 | * if no zero bit is present in the word. |
854 | */ | 849 | */ |
855 | set = __ffz_word(bit, __load_ulong_le(p, 0) >> bit); | 850 | set = __ffz_word(bit, __load_ulong_le(p, 0) >> bit); |
856 | if (set >= size) | 851 | if (set >= size) |
857 | return size + offset; | 852 | return size + offset; |
858 | if (set < __BITOPS_WORDSIZE) | 853 | if (set < BITS_PER_LONG) |
859 | return set + offset; | 854 | return set + offset; |
860 | offset += __BITOPS_WORDSIZE; | 855 | offset += BITS_PER_LONG; |
861 | size -= __BITOPS_WORDSIZE; | 856 | size -= BITS_PER_LONG; |
862 | p++; | 857 | p++; |
863 | } | 858 | } |
864 | return offset + find_first_zero_bit_le(p, size); | 859 | return offset + find_first_zero_bit_le(p, size); |
@@ -885,22 +880,22 @@ static inline int find_next_bit_le(void *vaddr, unsigned long size, | |||
885 | 880 | ||
886 | if (offset >= size) | 881 | if (offset >= size) |
887 | return size; | 882 | return size; |
888 | bit = offset & (__BITOPS_WORDSIZE - 1); | 883 | bit = offset & (BITS_PER_LONG - 1); |
889 | offset -= bit; | 884 | offset -= bit; |
890 | size -= offset; | 885 | size -= offset; |
891 | p = addr + offset / __BITOPS_WORDSIZE; | 886 | p = addr + offset / BITS_PER_LONG; |
892 | if (bit) { | 887 | if (bit) { |
893 | /* | 888 | /* |
894 | * s390 version of ffz returns __BITOPS_WORDSIZE | 889 | * s390 version of ffz returns BITS_PER_LONG |
895 | * if no zero bit is present in the word. | 890 | * if no zero bit is present in the word. |
896 | */ | 891 | */ |
897 | set = __ffs_word(0, __load_ulong_le(p, 0) & (~0UL << bit)); | 892 | set = __ffs_word(0, __load_ulong_le(p, 0) & (~0UL << bit)); |
898 | if (set >= size) | 893 | if (set >= size) |
899 | return size + offset; | 894 | return size + offset; |
900 | if (set < __BITOPS_WORDSIZE) | 895 | if (set < BITS_PER_LONG) |
901 | return set + offset; | 896 | return set + offset; |
902 | offset += __BITOPS_WORDSIZE; | 897 | offset += BITS_PER_LONG; |
903 | size -= __BITOPS_WORDSIZE; | 898 | size -= BITS_PER_LONG; |
904 | p++; | 899 | p++; |
905 | } | 900 | } |
906 | return offset + find_first_bit_le(p, size); | 901 | return offset + find_first_bit_le(p, size); |
diff --git a/arch/s390/include/asm/ccwdev.h b/arch/s390/include/asm/ccwdev.h index e6061617a50b..f201af8be580 100644 --- a/arch/s390/include/asm/ccwdev.h +++ b/arch/s390/include/asm/ccwdev.h | |||
@@ -220,7 +220,8 @@ extern void ccw_device_get_id(struct ccw_device *, struct ccw_dev_id *); | |||
220 | #define to_ccwdrv(n) container_of(n, struct ccw_driver, driver) | 220 | #define to_ccwdrv(n) container_of(n, struct ccw_driver, driver) |
221 | 221 | ||
222 | extern struct ccw_device *ccw_device_probe_console(void); | 222 | extern struct ccw_device *ccw_device_probe_console(void); |
223 | extern int ccw_device_force_console(void); | 223 | extern void ccw_device_wait_idle(struct ccw_device *); |
224 | extern int ccw_device_force_console(struct ccw_device *); | ||
224 | 225 | ||
225 | int ccw_device_siosl(struct ccw_device *); | 226 | int ccw_device_siosl(struct ccw_device *); |
226 | 227 | ||
diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h index ad2b924167d7..ffb898961c8d 100644 --- a/arch/s390/include/asm/cio.h +++ b/arch/s390/include/asm/cio.h | |||
@@ -296,8 +296,6 @@ static inline int ccw_dev_id_is_equal(struct ccw_dev_id *dev_id1, | |||
296 | return 0; | 296 | return 0; |
297 | } | 297 | } |
298 | 298 | ||
299 | extern void wait_cons_dev(void); | ||
300 | |||
301 | extern void css_schedule_reprobe(void); | 299 | extern void css_schedule_reprobe(void); |
302 | 300 | ||
303 | extern void reipl_ccw_dev(struct ccw_dev_id *id); | 301 | extern void reipl_ccw_dev(struct ccw_dev_id *id); |
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index f8c6df6cd1f0..c1e7c646727c 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h | |||
@@ -70,6 +70,22 @@ typedef u32 compat_ulong_t; | |||
70 | typedef u64 compat_u64; | 70 | typedef u64 compat_u64; |
71 | typedef u32 compat_uptr_t; | 71 | typedef u32 compat_uptr_t; |
72 | 72 | ||
73 | typedef struct { | ||
74 | u32 mask; | ||
75 | u32 addr; | ||
76 | } __aligned(8) psw_compat_t; | ||
77 | |||
78 | typedef struct { | ||
79 | psw_compat_t psw; | ||
80 | u32 gprs[NUM_GPRS]; | ||
81 | u32 acrs[NUM_ACRS]; | ||
82 | u32 orig_gpr2; | ||
83 | } s390_compat_regs; | ||
84 | |||
85 | typedef struct { | ||
86 | u32 gprs_high[NUM_GPRS]; | ||
87 | } s390_compat_regs_high; | ||
88 | |||
73 | struct compat_timespec { | 89 | struct compat_timespec { |
74 | compat_time_t tv_sec; | 90 | compat_time_t tv_sec; |
75 | s32 tv_nsec; | 91 | s32 tv_nsec; |
@@ -124,18 +140,33 @@ struct compat_flock64 { | |||
124 | }; | 140 | }; |
125 | 141 | ||
126 | struct compat_statfs { | 142 | struct compat_statfs { |
127 | s32 f_type; | 143 | u32 f_type; |
128 | s32 f_bsize; | 144 | u32 f_bsize; |
129 | s32 f_blocks; | 145 | u32 f_blocks; |
130 | s32 f_bfree; | 146 | u32 f_bfree; |
131 | s32 f_bavail; | 147 | u32 f_bavail; |
132 | s32 f_files; | 148 | u32 f_files; |
133 | s32 f_ffree; | 149 | u32 f_ffree; |
150 | compat_fsid_t f_fsid; | ||
151 | u32 f_namelen; | ||
152 | u32 f_frsize; | ||
153 | u32 f_flags; | ||
154 | u32 f_spare[4]; | ||
155 | }; | ||
156 | |||
157 | struct compat_statfs64 { | ||
158 | u32 f_type; | ||
159 | u32 f_bsize; | ||
160 | u64 f_blocks; | ||
161 | u64 f_bfree; | ||
162 | u64 f_bavail; | ||
163 | u64 f_files; | ||
164 | u64 f_ffree; | ||
134 | compat_fsid_t f_fsid; | 165 | compat_fsid_t f_fsid; |
135 | s32 f_namelen; | 166 | u32 f_namelen; |
136 | s32 f_frsize; | 167 | u32 f_frsize; |
137 | s32 f_flags; | 168 | u32 f_flags; |
138 | s32 f_spare[5]; | 169 | u32 f_spare[4]; |
139 | }; | 170 | }; |
140 | 171 | ||
141 | #define COMPAT_RLIM_OLD_INFINITY 0x7fffffff | 172 | #define COMPAT_RLIM_OLD_INFINITY 0x7fffffff |
@@ -248,8 +279,6 @@ static inline int is_compat_task(void) | |||
248 | return is_32bit_task(); | 279 | return is_32bit_task(); |
249 | } | 280 | } |
250 | 281 | ||
251 | #endif | ||
252 | |||
253 | static inline void __user *arch_compat_alloc_user_space(long len) | 282 | static inline void __user *arch_compat_alloc_user_space(long len) |
254 | { | 283 | { |
255 | unsigned long stack; | 284 | unsigned long stack; |
@@ -260,6 +289,8 @@ static inline void __user *arch_compat_alloc_user_space(long len) | |||
260 | return (void __user *) (stack - len); | 289 | return (void __user *) (stack - len); |
261 | } | 290 | } |
262 | 291 | ||
292 | #endif | ||
293 | |||
263 | struct compat_ipc64_perm { | 294 | struct compat_ipc64_perm { |
264 | compat_key_t key; | 295 | compat_key_t key; |
265 | __compat_uid32_t uid; | 296 | __compat_uid32_t uid; |
diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h index 1bfdf24b85a2..78f4f8711d58 100644 --- a/arch/s390/include/asm/elf.h +++ b/arch/s390/include/asm/elf.h | |||
@@ -119,6 +119,8 @@ | |||
119 | */ | 119 | */ |
120 | 120 | ||
121 | #include <asm/ptrace.h> | 121 | #include <asm/ptrace.h> |
122 | #include <asm/compat.h> | ||
123 | #include <asm/syscall.h> | ||
122 | #include <asm/user.h> | 124 | #include <asm/user.h> |
123 | 125 | ||
124 | typedef s390_fp_regs elf_fpregset_t; | 126 | typedef s390_fp_regs elf_fpregset_t; |
@@ -180,18 +182,31 @@ extern unsigned long elf_hwcap; | |||
180 | extern char elf_platform[]; | 182 | extern char elf_platform[]; |
181 | #define ELF_PLATFORM (elf_platform) | 183 | #define ELF_PLATFORM (elf_platform) |
182 | 184 | ||
183 | #ifdef CONFIG_64BIT | 185 | #ifndef CONFIG_COMPAT |
186 | #define SET_PERSONALITY(ex) \ | ||
187 | do { \ | ||
188 | set_personality(PER_LINUX | \ | ||
189 | (current->personality & (~PER_MASK))); \ | ||
190 | current_thread_info()->sys_call_table = \ | ||
191 | (unsigned long) &sys_call_table; \ | ||
192 | } while (0) | ||
193 | #else /* CONFIG_COMPAT */ | ||
184 | #define SET_PERSONALITY(ex) \ | 194 | #define SET_PERSONALITY(ex) \ |
185 | do { \ | 195 | do { \ |
186 | if (personality(current->personality) != PER_LINUX32) \ | 196 | if (personality(current->personality) != PER_LINUX32) \ |
187 | set_personality(PER_LINUX | \ | 197 | set_personality(PER_LINUX | \ |
188 | (current->personality & ~PER_MASK)); \ | 198 | (current->personality & ~PER_MASK)); \ |
189 | if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ | 199 | if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \ |
190 | set_thread_flag(TIF_31BIT); \ | 200 | set_thread_flag(TIF_31BIT); \ |
191 | else \ | 201 | current_thread_info()->sys_call_table = \ |
202 | (unsigned long) &sys_call_table_emu; \ | ||
203 | } else { \ | ||
192 | clear_thread_flag(TIF_31BIT); \ | 204 | clear_thread_flag(TIF_31BIT); \ |
205 | current_thread_info()->sys_call_table = \ | ||
206 | (unsigned long) &sys_call_table; \ | ||
207 | } \ | ||
193 | } while (0) | 208 | } while (0) |
194 | #endif /* CONFIG_64BIT */ | 209 | #endif /* CONFIG_COMPAT */ |
195 | 210 | ||
196 | #define STACK_RND_MASK 0x7ffUL | 211 | #define STACK_RND_MASK 0x7ffUL |
197 | 212 | ||
diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h index 593753ee07f3..bd90359d6d22 100644 --- a/arch/s390/include/asm/hugetlb.h +++ b/arch/s390/include/asm/hugetlb.h | |||
@@ -114,7 +114,7 @@ static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, | |||
114 | #define huge_ptep_set_wrprotect(__mm, __addr, __ptep) \ | 114 | #define huge_ptep_set_wrprotect(__mm, __addr, __ptep) \ |
115 | ({ \ | 115 | ({ \ |
116 | pte_t __pte = huge_ptep_get(__ptep); \ | 116 | pte_t __pte = huge_ptep_get(__ptep); \ |
117 | if (pte_write(__pte)) { \ | 117 | if (huge_pte_write(__pte)) { \ |
118 | huge_ptep_invalidate(__mm, __addr, __ptep); \ | 118 | huge_ptep_invalidate(__mm, __addr, __ptep); \ |
119 | set_huge_pte_at(__mm, __addr, __ptep, \ | 119 | set_huge_pte_at(__mm, __addr, __ptep, \ |
120 | huge_pte_wrprotect(__pte)); \ | 120 | huge_pte_wrprotect(__pte)); \ |
@@ -127,4 +127,58 @@ static inline void huge_ptep_clear_flush(struct vm_area_struct *vma, | |||
127 | huge_ptep_invalidate(vma->vm_mm, address, ptep); | 127 | huge_ptep_invalidate(vma->vm_mm, address, ptep); |
128 | } | 128 | } |
129 | 129 | ||
130 | static inline pte_t mk_huge_pte(struct page *page, pgprot_t pgprot) | ||
131 | { | ||
132 | pte_t pte; | ||
133 | pmd_t pmd; | ||
134 | |||
135 | pmd = mk_pmd_phys(page_to_phys(page), pgprot); | ||
136 | pte_val(pte) = pmd_val(pmd); | ||
137 | return pte; | ||
138 | } | ||
139 | |||
140 | static inline int huge_pte_write(pte_t pte) | ||
141 | { | ||
142 | pmd_t pmd; | ||
143 | |||
144 | pmd_val(pmd) = pte_val(pte); | ||
145 | return pmd_write(pmd); | ||
146 | } | ||
147 | |||
148 | static inline int huge_pte_dirty(pte_t pte) | ||
149 | { | ||
150 | /* No dirty bit in the segment table entry. */ | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | static inline pte_t huge_pte_mkwrite(pte_t pte) | ||
155 | { | ||
156 | pmd_t pmd; | ||
157 | |||
158 | pmd_val(pmd) = pte_val(pte); | ||
159 | pte_val(pte) = pmd_val(pmd_mkwrite(pmd)); | ||
160 | return pte; | ||
161 | } | ||
162 | |||
163 | static inline pte_t huge_pte_mkdirty(pte_t pte) | ||
164 | { | ||
165 | /* No dirty bit in the segment table entry. */ | ||
166 | return pte; | ||
167 | } | ||
168 | |||
169 | static inline pte_t huge_pte_modify(pte_t pte, pgprot_t newprot) | ||
170 | { | ||
171 | pmd_t pmd; | ||
172 | |||
173 | pmd_val(pmd) = pte_val(pte); | ||
174 | pte_val(pte) = pmd_val(pmd_modify(pmd, newprot)); | ||
175 | return pte; | ||
176 | } | ||
177 | |||
178 | static inline void huge_pte_clear(struct mm_struct *mm, unsigned long addr, | ||
179 | pte_t *ptep) | ||
180 | { | ||
181 | pmd_clear((pmd_t *) ptep); | ||
182 | } | ||
183 | |||
130 | #endif /* _ASM_S390_HUGETLB_H */ | 184 | #endif /* _ASM_S390_HUGETLB_H */ |
diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h index 27cb32185ce1..379d96e2105e 100644 --- a/arch/s390/include/asm/io.h +++ b/arch/s390/include/asm/io.h | |||
@@ -50,10 +50,6 @@ void unxlate_dev_mem_ptr(unsigned long phys, void *addr); | |||
50 | #define ioremap_nocache(addr, size) ioremap(addr, size) | 50 | #define ioremap_nocache(addr, size) ioremap(addr, size) |
51 | #define ioremap_wc ioremap_nocache | 51 | #define ioremap_wc ioremap_nocache |
52 | 52 | ||
53 | /* TODO: s390 cannot support io_remap_pfn_range... */ | ||
54 | #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ | ||
55 | remap_pfn_range(vma, vaddr, pfn, size, prot) | ||
56 | |||
57 | static inline void __iomem *ioremap(unsigned long offset, unsigned long size) | 53 | static inline void __iomem *ioremap(unsigned long offset, unsigned long size) |
58 | { | 54 | { |
59 | return (void __iomem *) offset; | 55 | return (void __iomem *) offset; |
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h index 05333b7f0469..6c1801235db9 100644 --- a/arch/s390/include/asm/pci.h +++ b/arch/s390/include/asm/pci.h | |||
@@ -140,6 +140,7 @@ static inline bool zdev_enabled(struct zpci_dev *zdev) | |||
140 | struct zpci_dev *zpci_alloc_device(void); | 140 | struct zpci_dev *zpci_alloc_device(void); |
141 | int zpci_create_device(struct zpci_dev *); | 141 | int zpci_create_device(struct zpci_dev *); |
142 | int zpci_enable_device(struct zpci_dev *); | 142 | int zpci_enable_device(struct zpci_dev *); |
143 | int zpci_disable_device(struct zpci_dev *); | ||
143 | void zpci_stop_device(struct zpci_dev *); | 144 | void zpci_stop_device(struct zpci_dev *); |
144 | void zpci_free_device(struct zpci_dev *); | 145 | void zpci_free_device(struct zpci_dev *); |
145 | int zpci_scan_device(struct zpci_dev *); | 146 | int zpci_scan_device(struct zpci_dev *); |
diff --git a/arch/s390/include/asm/pci_debug.h b/arch/s390/include/asm/pci_debug.h index 6bbec4265b6e..1ca5d1047c71 100644 --- a/arch/s390/include/asm/pci_debug.h +++ b/arch/s390/include/asm/pci_debug.h | |||
@@ -7,14 +7,11 @@ extern debug_info_t *pci_debug_msg_id; | |||
7 | extern debug_info_t *pci_debug_err_id; | 7 | extern debug_info_t *pci_debug_err_id; |
8 | 8 | ||
9 | #ifdef CONFIG_PCI_DEBUG | 9 | #ifdef CONFIG_PCI_DEBUG |
10 | #define zpci_dbg(fmt, args...) \ | 10 | #define zpci_dbg(imp, fmt, args...) \ |
11 | do { \ | 11 | debug_sprintf_event(pci_debug_msg_id, imp, fmt, ##args) |
12 | if (pci_debug_msg_id->level >= 2) \ | ||
13 | debug_sprintf_event(pci_debug_msg_id, 2, fmt , ## args);\ | ||
14 | } while (0) | ||
15 | 12 | ||
16 | #else /* !CONFIG_PCI_DEBUG */ | 13 | #else /* !CONFIG_PCI_DEBUG */ |
17 | #define zpci_dbg(fmt, args...) do { } while (0) | 14 | #define zpci_dbg(imp, fmt, args...) do { } while (0) |
18 | #endif | 15 | #endif |
19 | 16 | ||
20 | #define zpci_err(text...) \ | 17 | #define zpci_err(text...) \ |
diff --git a/arch/s390/include/asm/pci_insn.h b/arch/s390/include/asm/pci_insn.h index 1486a98d5dad..e6a2bdd4d705 100644 --- a/arch/s390/include/asm/pci_insn.h +++ b/arch/s390/include/asm/pci_insn.h | |||
@@ -1,10 +1,6 @@ | |||
1 | #ifndef _ASM_S390_PCI_INSN_H | 1 | #ifndef _ASM_S390_PCI_INSN_H |
2 | #define _ASM_S390_PCI_INSN_H | 2 | #define _ASM_S390_PCI_INSN_H |
3 | 3 | ||
4 | #include <linux/delay.h> | ||
5 | |||
6 | #define ZPCI_INSN_BUSY_DELAY 1 /* 1 microsecond */ | ||
7 | |||
8 | /* Load/Store status codes */ | 4 | /* Load/Store status codes */ |
9 | #define ZPCI_PCI_ST_FUNC_NOT_ENABLED 4 | 5 | #define ZPCI_PCI_ST_FUNC_NOT_ENABLED 4 |
10 | #define ZPCI_PCI_ST_FUNC_IN_ERR 8 | 6 | #define ZPCI_PCI_ST_FUNC_IN_ERR 8 |
@@ -82,199 +78,12 @@ struct zpci_fib { | |||
82 | u64 reserved7; | 78 | u64 reserved7; |
83 | } __packed; | 79 | } __packed; |
84 | 80 | ||
85 | /* Modify PCI Function Controls */ | ||
86 | static inline u8 __mpcifc(u64 req, struct zpci_fib *fib, u8 *status) | ||
87 | { | ||
88 | u8 cc; | ||
89 | |||
90 | asm volatile ( | ||
91 | " .insn rxy,0xe300000000d0,%[req],%[fib]\n" | ||
92 | " ipm %[cc]\n" | ||
93 | " srl %[cc],28\n" | ||
94 | : [cc] "=d" (cc), [req] "+d" (req), [fib] "+Q" (*fib) | ||
95 | : : "cc"); | ||
96 | *status = req >> 24 & 0xff; | ||
97 | return cc; | ||
98 | } | ||
99 | |||
100 | static inline int mpcifc_instr(u64 req, struct zpci_fib *fib) | ||
101 | { | ||
102 | u8 cc, status; | ||
103 | |||
104 | do { | ||
105 | cc = __mpcifc(req, fib, &status); | ||
106 | if (cc == 2) | ||
107 | msleep(ZPCI_INSN_BUSY_DELAY); | ||
108 | } while (cc == 2); | ||
109 | |||
110 | if (cc) | ||
111 | printk_once(KERN_ERR "%s: error cc: %d status: %d\n", | ||
112 | __func__, cc, status); | ||
113 | return (cc) ? -EIO : 0; | ||
114 | } | ||
115 | |||
116 | /* Refresh PCI Translations */ | ||
117 | static inline u8 __rpcit(u64 fn, u64 addr, u64 range, u8 *status) | ||
118 | { | ||
119 | register u64 __addr asm("2") = addr; | ||
120 | register u64 __range asm("3") = range; | ||
121 | u8 cc; | ||
122 | |||
123 | asm volatile ( | ||
124 | " .insn rre,0xb9d30000,%[fn],%[addr]\n" | ||
125 | " ipm %[cc]\n" | ||
126 | " srl %[cc],28\n" | ||
127 | : [cc] "=d" (cc), [fn] "+d" (fn) | ||
128 | : [addr] "d" (__addr), "d" (__range) | ||
129 | : "cc"); | ||
130 | *status = fn >> 24 & 0xff; | ||
131 | return cc; | ||
132 | } | ||
133 | |||
134 | static inline int rpcit_instr(u64 fn, u64 addr, u64 range) | ||
135 | { | ||
136 | u8 cc, status; | ||
137 | |||
138 | do { | ||
139 | cc = __rpcit(fn, addr, range, &status); | ||
140 | if (cc == 2) | ||
141 | udelay(ZPCI_INSN_BUSY_DELAY); | ||
142 | } while (cc == 2); | ||
143 | |||
144 | if (cc) | ||
145 | printk_once(KERN_ERR "%s: error cc: %d status: %d dma_addr: %Lx size: %Lx\n", | ||
146 | __func__, cc, status, addr, range); | ||
147 | return (cc) ? -EIO : 0; | ||
148 | } | ||
149 | |||
150 | /* Store PCI function controls */ | ||
151 | static inline u8 __stpcifc(u32 handle, u8 space, struct zpci_fib *fib, u8 *status) | ||
152 | { | ||
153 | u64 fn = (u64) handle << 32 | space << 16; | ||
154 | u8 cc; | ||
155 | |||
156 | asm volatile ( | ||
157 | " .insn rxy,0xe300000000d4,%[fn],%[fib]\n" | ||
158 | " ipm %[cc]\n" | ||
159 | " srl %[cc],28\n" | ||
160 | : [cc] "=d" (cc), [fn] "+d" (fn), [fib] "=m" (*fib) | ||
161 | : : "cc"); | ||
162 | *status = fn >> 24 & 0xff; | ||
163 | return cc; | ||
164 | } | ||
165 | |||
166 | /* Set Interruption Controls */ | ||
167 | static inline void sic_instr(u16 ctl, char *unused, u8 isc) | ||
168 | { | ||
169 | asm volatile ( | ||
170 | " .insn rsy,0xeb00000000d1,%[ctl],%[isc],%[u]\n" | ||
171 | : : [ctl] "d" (ctl), [isc] "d" (isc << 27), [u] "Q" (*unused)); | ||
172 | } | ||
173 | |||
174 | /* PCI Load */ | ||
175 | static inline u8 __pcilg(u64 *data, u64 req, u64 offset, u8 *status) | ||
176 | { | ||
177 | register u64 __req asm("2") = req; | ||
178 | register u64 __offset asm("3") = offset; | ||
179 | u64 __data; | ||
180 | u8 cc; | ||
181 | |||
182 | asm volatile ( | ||
183 | " .insn rre,0xb9d20000,%[data],%[req]\n" | ||
184 | " ipm %[cc]\n" | ||
185 | " srl %[cc],28\n" | ||
186 | : [cc] "=d" (cc), [data] "=d" (__data), [req] "+d" (__req) | ||
187 | : "d" (__offset) | ||
188 | : "cc"); | ||
189 | *status = __req >> 24 & 0xff; | ||
190 | *data = __data; | ||
191 | return cc; | ||
192 | } | ||
193 | |||
194 | static inline int pcilg_instr(u64 *data, u64 req, u64 offset) | ||
195 | { | ||
196 | u8 cc, status; | ||
197 | |||
198 | do { | ||
199 | cc = __pcilg(data, req, offset, &status); | ||
200 | if (cc == 2) | ||
201 | udelay(ZPCI_INSN_BUSY_DELAY); | ||
202 | } while (cc == 2); | ||
203 | |||
204 | if (cc) { | ||
205 | printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", | ||
206 | __func__, cc, status, req, offset); | ||
207 | /* TODO: on IO errors set data to 0xff... | ||
208 | * here or in users of pcilg (le conversion)? | ||
209 | */ | ||
210 | } | ||
211 | return (cc) ? -EIO : 0; | ||
212 | } | ||
213 | |||
214 | /* PCI Store */ | ||
215 | static inline u8 __pcistg(u64 data, u64 req, u64 offset, u8 *status) | ||
216 | { | ||
217 | register u64 __req asm("2") = req; | ||
218 | register u64 __offset asm("3") = offset; | ||
219 | u8 cc; | ||
220 | |||
221 | asm volatile ( | ||
222 | " .insn rre,0xb9d00000,%[data],%[req]\n" | ||
223 | " ipm %[cc]\n" | ||
224 | " srl %[cc],28\n" | ||
225 | : [cc] "=d" (cc), [req] "+d" (__req) | ||
226 | : "d" (__offset), [data] "d" (data) | ||
227 | : "cc"); | ||
228 | *status = __req >> 24 & 0xff; | ||
229 | return cc; | ||
230 | } | ||
231 | |||
232 | static inline int pcistg_instr(u64 data, u64 req, u64 offset) | ||
233 | { | ||
234 | u8 cc, status; | ||
235 | |||
236 | do { | ||
237 | cc = __pcistg(data, req, offset, &status); | ||
238 | if (cc == 2) | ||
239 | udelay(ZPCI_INSN_BUSY_DELAY); | ||
240 | } while (cc == 2); | ||
241 | |||
242 | if (cc) | ||
243 | printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", | ||
244 | __func__, cc, status, req, offset); | ||
245 | return (cc) ? -EIO : 0; | ||
246 | } | ||
247 | |||
248 | /* PCI Store Block */ | ||
249 | static inline u8 __pcistb(const u64 *data, u64 req, u64 offset, u8 *status) | ||
250 | { | ||
251 | u8 cc; | ||
252 | |||
253 | asm volatile ( | ||
254 | " .insn rsy,0xeb00000000d0,%[req],%[offset],%[data]\n" | ||
255 | " ipm %[cc]\n" | ||
256 | " srl %[cc],28\n" | ||
257 | : [cc] "=d" (cc), [req] "+d" (req) | ||
258 | : [offset] "d" (offset), [data] "Q" (*data) | ||
259 | : "cc"); | ||
260 | *status = req >> 24 & 0xff; | ||
261 | return cc; | ||
262 | } | ||
263 | |||
264 | static inline int pcistb_instr(const u64 *data, u64 req, u64 offset) | ||
265 | { | ||
266 | u8 cc, status; | ||
267 | |||
268 | do { | ||
269 | cc = __pcistb(data, req, offset, &status); | ||
270 | if (cc == 2) | ||
271 | udelay(ZPCI_INSN_BUSY_DELAY); | ||
272 | } while (cc == 2); | ||
273 | 81 | ||
274 | if (cc) | 82 | int s390pci_mod_fc(u64 req, struct zpci_fib *fib); |
275 | printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", | 83 | int s390pci_refresh_trans(u64 fn, u64 addr, u64 range); |
276 | __func__, cc, status, req, offset); | 84 | int s390pci_load(u64 *data, u64 req, u64 offset); |
277 | return (cc) ? -EIO : 0; | 85 | int s390pci_store(u64 data, u64 req, u64 offset); |
278 | } | 86 | int s390pci_store_block(const u64 *data, u64 req, u64 offset); |
87 | void set_irq_ctrl(u16 ctl, char *unused, u8 isc); | ||
279 | 88 | ||
280 | #endif | 89 | #endif |
diff --git a/arch/s390/include/asm/pci_io.h b/arch/s390/include/asm/pci_io.h index 5fd81f31d6c7..83a9caa6ae53 100644 --- a/arch/s390/include/asm/pci_io.h +++ b/arch/s390/include/asm/pci_io.h | |||
@@ -36,7 +36,7 @@ static inline RETTYPE zpci_read_##RETTYPE(const volatile void __iomem *addr) \ | |||
36 | u64 data; \ | 36 | u64 data; \ |
37 | int rc; \ | 37 | int rc; \ |
38 | \ | 38 | \ |
39 | rc = pcilg_instr(&data, req, ZPCI_OFFSET(addr)); \ | 39 | rc = s390pci_load(&data, req, ZPCI_OFFSET(addr)); \ |
40 | if (rc) \ | 40 | if (rc) \ |
41 | data = -1ULL; \ | 41 | data = -1ULL; \ |
42 | return (RETTYPE) data; \ | 42 | return (RETTYPE) data; \ |
@@ -50,7 +50,7 @@ static inline void zpci_write_##VALTYPE(VALTYPE val, \ | |||
50 | u64 req = ZPCI_CREATE_REQ(entry->fh, entry->bar, LENGTH); \ | 50 | u64 req = ZPCI_CREATE_REQ(entry->fh, entry->bar, LENGTH); \ |
51 | u64 data = (VALTYPE) val; \ | 51 | u64 data = (VALTYPE) val; \ |
52 | \ | 52 | \ |
53 | pcistg_instr(data, req, ZPCI_OFFSET(addr)); \ | 53 | s390pci_store(data, req, ZPCI_OFFSET(addr)); \ |
54 | } | 54 | } |
55 | 55 | ||
56 | zpci_read(8, u64) | 56 | zpci_read(8, u64) |
@@ -83,15 +83,18 @@ static inline int zpci_write_single(u64 req, const u64 *data, u64 offset, u8 len | |||
83 | val = 0; /* let FW report error */ | 83 | val = 0; /* let FW report error */ |
84 | break; | 84 | break; |
85 | } | 85 | } |
86 | return pcistg_instr(val, req, offset); | 86 | return s390pci_store(val, req, offset); |
87 | } | 87 | } |
88 | 88 | ||
89 | static inline int zpci_read_single(u64 req, u64 *dst, u64 offset, u8 len) | 89 | static inline int zpci_read_single(u64 req, u64 *dst, u64 offset, u8 len) |
90 | { | 90 | { |
91 | u64 data; | 91 | u64 data; |
92 | u8 cc; | 92 | int cc; |
93 | |||
94 | cc = s390pci_load(&data, req, offset); | ||
95 | if (cc) | ||
96 | goto out; | ||
93 | 97 | ||
94 | cc = pcilg_instr(&data, req, offset); | ||
95 | switch (len) { | 98 | switch (len) { |
96 | case 1: | 99 | case 1: |
97 | *((u8 *) dst) = (u8) data; | 100 | *((u8 *) dst) = (u8) data; |
@@ -106,12 +109,13 @@ static inline int zpci_read_single(u64 req, u64 *dst, u64 offset, u8 len) | |||
106 | *((u64 *) dst) = (u64) data; | 109 | *((u64 *) dst) = (u64) data; |
107 | break; | 110 | break; |
108 | } | 111 | } |
112 | out: | ||
109 | return cc; | 113 | return cc; |
110 | } | 114 | } |
111 | 115 | ||
112 | static inline int zpci_write_block(u64 req, const u64 *data, u64 offset) | 116 | static inline int zpci_write_block(u64 req, const u64 *data, u64 offset) |
113 | { | 117 | { |
114 | return pcistb_instr(data, req, offset); | 118 | return s390pci_store_block(data, req, offset); |
115 | } | 119 | } |
116 | 120 | ||
117 | static inline u8 zpci_get_max_write_size(u64 src, u64 dst, int len, int max) | 121 | static inline u8 zpci_get_max_write_size(u64 src, u64 dst, int len, int max) |
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 4a5443118cfb..b4622915bd15 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h | |||
@@ -57,6 +57,10 @@ extern unsigned long zero_page_mask; | |||
57 | (((unsigned long)(vaddr)) &zero_page_mask)))) | 57 | (((unsigned long)(vaddr)) &zero_page_mask)))) |
58 | #define __HAVE_COLOR_ZERO_PAGE | 58 | #define __HAVE_COLOR_ZERO_PAGE |
59 | 59 | ||
60 | /* TODO: s390 cannot support io_remap_pfn_range... */ | ||
61 | #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ | ||
62 | remap_pfn_range(vma, vaddr, pfn, size, prot) | ||
63 | |||
60 | #endif /* !__ASSEMBLY__ */ | 64 | #endif /* !__ASSEMBLY__ */ |
61 | 65 | ||
62 | /* | 66 | /* |
@@ -420,6 +424,13 @@ extern unsigned long MODULES_END; | |||
420 | #define __S110 PAGE_RW | 424 | #define __S110 PAGE_RW |
421 | #define __S111 PAGE_RW | 425 | #define __S111 PAGE_RW |
422 | 426 | ||
427 | /* | ||
428 | * Segment entry (large page) protection definitions. | ||
429 | */ | ||
430 | #define SEGMENT_NONE __pgprot(_HPAGE_TYPE_NONE) | ||
431 | #define SEGMENT_RO __pgprot(_HPAGE_TYPE_RO) | ||
432 | #define SEGMENT_RW __pgprot(_HPAGE_TYPE_RW) | ||
433 | |||
423 | static inline int mm_exclusive(struct mm_struct *mm) | 434 | static inline int mm_exclusive(struct mm_struct *mm) |
424 | { | 435 | { |
425 | return likely(mm == current->active_mm && | 436 | return likely(mm == current->active_mm && |
@@ -760,6 +771,8 @@ void gmap_disable(struct gmap *gmap); | |||
760 | int gmap_map_segment(struct gmap *gmap, unsigned long from, | 771 | int gmap_map_segment(struct gmap *gmap, unsigned long from, |
761 | unsigned long to, unsigned long length); | 772 | unsigned long to, unsigned long length); |
762 | int gmap_unmap_segment(struct gmap *gmap, unsigned long to, unsigned long len); | 773 | int gmap_unmap_segment(struct gmap *gmap, unsigned long to, unsigned long len); |
774 | unsigned long __gmap_translate(unsigned long address, struct gmap *); | ||
775 | unsigned long gmap_translate(unsigned long address, struct gmap *); | ||
763 | unsigned long __gmap_fault(unsigned long address, struct gmap *); | 776 | unsigned long __gmap_fault(unsigned long address, struct gmap *); |
764 | unsigned long gmap_fault(unsigned long address, struct gmap *); | 777 | unsigned long gmap_fault(unsigned long address, struct gmap *); |
765 | void gmap_discard(unsigned long from, unsigned long to, struct gmap *); | 778 | void gmap_discard(unsigned long from, unsigned long to, struct gmap *); |
@@ -908,26 +921,6 @@ static inline pte_t pte_mkspecial(pte_t pte) | |||
908 | #ifdef CONFIG_HUGETLB_PAGE | 921 | #ifdef CONFIG_HUGETLB_PAGE |
909 | static inline pte_t pte_mkhuge(pte_t pte) | 922 | static inline pte_t pte_mkhuge(pte_t pte) |
910 | { | 923 | { |
911 | /* | ||
912 | * PROT_NONE needs to be remapped from the pte type to the ste type. | ||
913 | * The HW invalid bit is also different for pte and ste. The pte | ||
914 | * invalid bit happens to be the same as the ste _SEGMENT_ENTRY_LARGE | ||
915 | * bit, so we don't have to clear it. | ||
916 | */ | ||
917 | if (pte_val(pte) & _PAGE_INVALID) { | ||
918 | if (pte_val(pte) & _PAGE_SWT) | ||
919 | pte_val(pte) |= _HPAGE_TYPE_NONE; | ||
920 | pte_val(pte) |= _SEGMENT_ENTRY_INV; | ||
921 | } | ||
922 | /* | ||
923 | * Clear SW pte bits, there are no SW bits in a segment table entry. | ||
924 | */ | ||
925 | pte_val(pte) &= ~(_PAGE_SWT | _PAGE_SWX | _PAGE_SWC | | ||
926 | _PAGE_SWR | _PAGE_SWW); | ||
927 | /* | ||
928 | * Also set the change-override bit because we don't need dirty bit | ||
929 | * tracking for hugetlbfs pages. | ||
930 | */ | ||
931 | pte_val(pte) |= (_SEGMENT_ENTRY_LARGE | _SEGMENT_ENTRY_CO); | 924 | pte_val(pte) |= (_SEGMENT_ENTRY_LARGE | _SEGMENT_ENTRY_CO); |
932 | return pte; | 925 | return pte; |
933 | } | 926 | } |
@@ -1272,31 +1265,7 @@ static inline void __pmd_idte(unsigned long address, pmd_t *pmdp) | |||
1272 | } | 1265 | } |
1273 | } | 1266 | } |
1274 | 1267 | ||
1275 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 1268 | #if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLB_PAGE) |
1276 | |||
1277 | #define SEGMENT_NONE __pgprot(_HPAGE_TYPE_NONE) | ||
1278 | #define SEGMENT_RO __pgprot(_HPAGE_TYPE_RO) | ||
1279 | #define SEGMENT_RW __pgprot(_HPAGE_TYPE_RW) | ||
1280 | |||
1281 | #define __HAVE_ARCH_PGTABLE_DEPOSIT | ||
1282 | extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable); | ||
1283 | |||
1284 | #define __HAVE_ARCH_PGTABLE_WITHDRAW | ||
1285 | extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm); | ||
1286 | |||
1287 | static inline int pmd_trans_splitting(pmd_t pmd) | ||
1288 | { | ||
1289 | return pmd_val(pmd) & _SEGMENT_ENTRY_SPLIT; | ||
1290 | } | ||
1291 | |||
1292 | static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, | ||
1293 | pmd_t *pmdp, pmd_t entry) | ||
1294 | { | ||
1295 | if (!(pmd_val(entry) & _SEGMENT_ENTRY_INV) && MACHINE_HAS_EDAT1) | ||
1296 | pmd_val(entry) |= _SEGMENT_ENTRY_CO; | ||
1297 | *pmdp = entry; | ||
1298 | } | ||
1299 | |||
1300 | static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot) | 1269 | static inline unsigned long massage_pgprot_pmd(pgprot_t pgprot) |
1301 | { | 1270 | { |
1302 | /* | 1271 | /* |
@@ -1317,10 +1286,11 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot) | |||
1317 | return pmd; | 1286 | return pmd; |
1318 | } | 1287 | } |
1319 | 1288 | ||
1320 | static inline pmd_t pmd_mkhuge(pmd_t pmd) | 1289 | static inline pmd_t mk_pmd_phys(unsigned long physpage, pgprot_t pgprot) |
1321 | { | 1290 | { |
1322 | pmd_val(pmd) |= _SEGMENT_ENTRY_LARGE; | 1291 | pmd_t __pmd; |
1323 | return pmd; | 1292 | pmd_val(__pmd) = physpage + massage_pgprot_pmd(pgprot); |
1293 | return __pmd; | ||
1324 | } | 1294 | } |
1325 | 1295 | ||
1326 | static inline pmd_t pmd_mkwrite(pmd_t pmd) | 1296 | static inline pmd_t pmd_mkwrite(pmd_t pmd) |
@@ -1330,6 +1300,34 @@ static inline pmd_t pmd_mkwrite(pmd_t pmd) | |||
1330 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO; | 1300 | pmd_val(pmd) &= ~_SEGMENT_ENTRY_RO; |
1331 | return pmd; | 1301 | return pmd; |
1332 | } | 1302 | } |
1303 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLB_PAGE */ | ||
1304 | |||
1305 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
1306 | |||
1307 | #define __HAVE_ARCH_PGTABLE_DEPOSIT | ||
1308 | extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pgtable_t pgtable); | ||
1309 | |||
1310 | #define __HAVE_ARCH_PGTABLE_WITHDRAW | ||
1311 | extern pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm); | ||
1312 | |||
1313 | static inline int pmd_trans_splitting(pmd_t pmd) | ||
1314 | { | ||
1315 | return pmd_val(pmd) & _SEGMENT_ENTRY_SPLIT; | ||
1316 | } | ||
1317 | |||
1318 | static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr, | ||
1319 | pmd_t *pmdp, pmd_t entry) | ||
1320 | { | ||
1321 | if (!(pmd_val(entry) & _SEGMENT_ENTRY_INV) && MACHINE_HAS_EDAT1) | ||
1322 | pmd_val(entry) |= _SEGMENT_ENTRY_CO; | ||
1323 | *pmdp = entry; | ||
1324 | } | ||
1325 | |||
1326 | static inline pmd_t pmd_mkhuge(pmd_t pmd) | ||
1327 | { | ||
1328 | pmd_val(pmd) |= _SEGMENT_ENTRY_LARGE; | ||
1329 | return pmd; | ||
1330 | } | ||
1333 | 1331 | ||
1334 | static inline pmd_t pmd_wrprotect(pmd_t pmd) | 1332 | static inline pmd_t pmd_wrprotect(pmd_t pmd) |
1335 | { | 1333 | { |
@@ -1426,13 +1424,6 @@ static inline void pmdp_set_wrprotect(struct mm_struct *mm, | |||
1426 | } | 1424 | } |
1427 | } | 1425 | } |
1428 | 1426 | ||
1429 | static inline pmd_t mk_pmd_phys(unsigned long physpage, pgprot_t pgprot) | ||
1430 | { | ||
1431 | pmd_t __pmd; | ||
1432 | pmd_val(__pmd) = physpage + massage_pgprot_pmd(pgprot); | ||
1433 | return __pmd; | ||
1434 | } | ||
1435 | |||
1436 | #define pfn_pmd(pfn, pgprot) mk_pmd_phys(__pa((pfn) << PAGE_SHIFT), (pgprot)) | 1427 | #define pfn_pmd(pfn, pgprot) mk_pmd_phys(__pa((pfn) << PAGE_SHIFT), (pgprot)) |
1437 | #define mk_pmd(page, pgprot) pfn_pmd(page_to_pfn(page), (pgprot)) | 1428 | #define mk_pmd(page, pgprot) pfn_pmd(page_to_pfn(page), (pgprot)) |
1438 | 1429 | ||
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index 94e749c90230..6b499870662f 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h | |||
@@ -161,7 +161,8 @@ extern unsigned long thread_saved_pc(struct task_struct *t); | |||
161 | 161 | ||
162 | extern void show_code(struct pt_regs *regs); | 162 | extern void show_code(struct pt_regs *regs); |
163 | extern void print_fn_code(unsigned char *code, unsigned long len); | 163 | extern void print_fn_code(unsigned char *code, unsigned long len); |
164 | extern int insn_to_mnemonic(unsigned char *instruction, char buf[8]); | 164 | extern int insn_to_mnemonic(unsigned char *instruction, char *buf, |
165 | unsigned int len); | ||
165 | 166 | ||
166 | unsigned long get_wchan(struct task_struct *p); | 167 | unsigned long get_wchan(struct task_struct *p); |
167 | #define task_pt_regs(tsk) ((struct pt_regs *) \ | 168 | #define task_pt_regs(tsk) ((struct pt_regs *) \ |
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h index 3ee5da3bc10c..559512a455da 100644 --- a/arch/s390/include/asm/ptrace.h +++ b/arch/s390/include/asm/ptrace.h | |||
@@ -9,9 +9,7 @@ | |||
9 | #include <uapi/asm/ptrace.h> | 9 | #include <uapi/asm/ptrace.h> |
10 | 10 | ||
11 | #ifndef __ASSEMBLY__ | 11 | #ifndef __ASSEMBLY__ |
12 | #ifndef __s390x__ | 12 | |
13 | #else /* __s390x__ */ | ||
14 | #endif /* __s390x__ */ | ||
15 | extern long psw_kernel_bits; | 13 | extern long psw_kernel_bits; |
16 | extern long psw_user_bits; | 14 | extern long psw_user_bits; |
17 | 15 | ||
@@ -77,8 +75,6 @@ struct per_struct_kernel { | |||
77 | #define PER_CONTROL_SUSPENSION 0x00400000UL | 75 | #define PER_CONTROL_SUSPENSION 0x00400000UL |
78 | #define PER_CONTROL_ALTERATION 0x00200000UL | 76 | #define PER_CONTROL_ALTERATION 0x00200000UL |
79 | 77 | ||
80 | #ifdef __s390x__ | ||
81 | #endif /* __s390x__ */ | ||
82 | /* | 78 | /* |
83 | * These are defined as per linux/ptrace.h, which see. | 79 | * These are defined as per linux/ptrace.h, which see. |
84 | */ | 80 | */ |
diff --git a/arch/s390/include/asm/syscall.h b/arch/s390/include/asm/syscall.h index fe7b99759e12..cd29d2f4e4f3 100644 --- a/arch/s390/include/asm/syscall.h +++ b/arch/s390/include/asm/syscall.h | |||
@@ -23,6 +23,7 @@ | |||
23 | * type here is what we want [need] for both 32 bit and 64 bit systems. | 23 | * type here is what we want [need] for both 32 bit and 64 bit systems. |
24 | */ | 24 | */ |
25 | extern const unsigned int sys_call_table[]; | 25 | extern const unsigned int sys_call_table[]; |
26 | extern const unsigned int sys_call_table_emu[]; | ||
26 | 27 | ||
27 | static inline long syscall_get_nr(struct task_struct *task, | 28 | static inline long syscall_get_nr(struct task_struct *task, |
28 | struct pt_regs *regs) | 29 | struct pt_regs *regs) |
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index 9e2cfe0349c3..eb5f64d26d06 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h | |||
@@ -14,13 +14,8 @@ | |||
14 | #define THREAD_ORDER 1 | 14 | #define THREAD_ORDER 1 |
15 | #define ASYNC_ORDER 1 | 15 | #define ASYNC_ORDER 1 |
16 | #else /* CONFIG_64BIT */ | 16 | #else /* CONFIG_64BIT */ |
17 | #ifndef __SMALL_STACK | ||
18 | #define THREAD_ORDER 2 | 17 | #define THREAD_ORDER 2 |
19 | #define ASYNC_ORDER 2 | 18 | #define ASYNC_ORDER 2 |
20 | #else | ||
21 | #define THREAD_ORDER 1 | ||
22 | #define ASYNC_ORDER 1 | ||
23 | #endif | ||
24 | #endif /* CONFIG_64BIT */ | 19 | #endif /* CONFIG_64BIT */ |
25 | 20 | ||
26 | #define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) | 21 | #define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) |
@@ -41,6 +36,7 @@ struct thread_info { | |||
41 | struct task_struct *task; /* main task structure */ | 36 | struct task_struct *task; /* main task structure */ |
42 | struct exec_domain *exec_domain; /* execution domain */ | 37 | struct exec_domain *exec_domain; /* execution domain */ |
43 | unsigned long flags; /* low level flags */ | 38 | unsigned long flags; /* low level flags */ |
39 | unsigned long sys_call_table; /* System call table address */ | ||
44 | unsigned int cpu; /* current CPU */ | 40 | unsigned int cpu; /* current CPU */ |
45 | int preempt_count; /* 0 => preemptable, <0 => BUG */ | 41 | int preempt_count; /* 0 => preemptable, <0 => BUG */ |
46 | struct restart_block restart_block; | 42 | struct restart_block restart_block; |
diff --git a/arch/s390/include/uapi/asm/ptrace.h b/arch/s390/include/uapi/asm/ptrace.h index a5ca214b34fd..3aa9f1ec5b29 100644 --- a/arch/s390/include/uapi/asm/ptrace.h +++ b/arch/s390/include/uapi/asm/ptrace.h | |||
@@ -215,12 +215,6 @@ typedef struct | |||
215 | unsigned long addr; | 215 | unsigned long addr; |
216 | } __attribute__ ((aligned(8))) psw_t; | 216 | } __attribute__ ((aligned(8))) psw_t; |
217 | 217 | ||
218 | typedef struct | ||
219 | { | ||
220 | __u32 mask; | ||
221 | __u32 addr; | ||
222 | } __attribute__ ((aligned(8))) psw_compat_t; | ||
223 | |||
224 | #ifndef __s390x__ | 218 | #ifndef __s390x__ |
225 | 219 | ||
226 | #define PSW_MASK_PER 0x40000000UL | 220 | #define PSW_MASK_PER 0x40000000UL |
@@ -295,20 +289,6 @@ typedef struct | |||
295 | unsigned long orig_gpr2; | 289 | unsigned long orig_gpr2; |
296 | } s390_regs; | 290 | } s390_regs; |
297 | 291 | ||
298 | typedef struct | ||
299 | { | ||
300 | psw_compat_t psw; | ||
301 | __u32 gprs[NUM_GPRS]; | ||
302 | __u32 acrs[NUM_ACRS]; | ||
303 | __u32 orig_gpr2; | ||
304 | } s390_compat_regs; | ||
305 | |||
306 | typedef struct | ||
307 | { | ||
308 | __u32 gprs_high[NUM_GPRS]; | ||
309 | } s390_compat_regs_high; | ||
310 | |||
311 | |||
312 | /* | 292 | /* |
313 | * Now for the user space program event recording (trace) definitions. | 293 | * Now for the user space program event recording (trace) definitions. |
314 | * The following structures are used only for the ptrace interface, don't | 294 | * The following structures are used only for the ptrace interface, don't |
diff --git a/arch/s390/include/uapi/asm/statfs.h b/arch/s390/include/uapi/asm/statfs.h index 5acca0a34c20..a61d538756f2 100644 --- a/arch/s390/include/uapi/asm/statfs.h +++ b/arch/s390/include/uapi/asm/statfs.h | |||
@@ -7,9 +7,6 @@ | |||
7 | #ifndef _S390_STATFS_H | 7 | #ifndef _S390_STATFS_H |
8 | #define _S390_STATFS_H | 8 | #define _S390_STATFS_H |
9 | 9 | ||
10 | #ifndef __s390x__ | ||
11 | #include <asm-generic/statfs.h> | ||
12 | #else | ||
13 | /* | 10 | /* |
14 | * We can't use <asm-generic/statfs.h> because in 64-bit mode | 11 | * We can't use <asm-generic/statfs.h> because in 64-bit mode |
15 | * we mix ints of different sizes in our struct statfs. | 12 | * we mix ints of different sizes in our struct statfs. |
@@ -21,49 +18,33 @@ typedef __kernel_fsid_t fsid_t; | |||
21 | #endif | 18 | #endif |
22 | 19 | ||
23 | struct statfs { | 20 | struct statfs { |
24 | int f_type; | 21 | unsigned int f_type; |
25 | int f_bsize; | 22 | unsigned int f_bsize; |
26 | long f_blocks; | 23 | unsigned long f_blocks; |
27 | long f_bfree; | 24 | unsigned long f_bfree; |
28 | long f_bavail; | 25 | unsigned long f_bavail; |
29 | long f_files; | 26 | unsigned long f_files; |
30 | long f_ffree; | 27 | unsigned long f_ffree; |
31 | __kernel_fsid_t f_fsid; | 28 | __kernel_fsid_t f_fsid; |
32 | int f_namelen; | 29 | unsigned int f_namelen; |
33 | int f_frsize; | 30 | unsigned int f_frsize; |
34 | int f_flags; | 31 | unsigned int f_flags; |
35 | int f_spare[4]; | 32 | unsigned int f_spare[4]; |
36 | }; | 33 | }; |
37 | 34 | ||
38 | struct statfs64 { | 35 | struct statfs64 { |
39 | int f_type; | 36 | unsigned int f_type; |
40 | int f_bsize; | 37 | unsigned int f_bsize; |
41 | long f_blocks; | 38 | unsigned long f_blocks; |
42 | long f_bfree; | 39 | unsigned long f_bfree; |
43 | long f_bavail; | 40 | unsigned long f_bavail; |
44 | long f_files; | 41 | unsigned long f_files; |
45 | long f_ffree; | 42 | unsigned long f_ffree; |
46 | __kernel_fsid_t f_fsid; | 43 | __kernel_fsid_t f_fsid; |
47 | int f_namelen; | 44 | unsigned int f_namelen; |
48 | int f_frsize; | 45 | unsigned int f_frsize; |
49 | int f_flags; | 46 | unsigned int f_flags; |
50 | int f_spare[4]; | 47 | unsigned int f_spare[4]; |
51 | }; | 48 | }; |
52 | 49 | ||
53 | struct compat_statfs64 { | ||
54 | __u32 f_type; | ||
55 | __u32 f_bsize; | ||
56 | __u64 f_blocks; | ||
57 | __u64 f_bfree; | ||
58 | __u64 f_bavail; | ||
59 | __u64 f_files; | ||
60 | __u64 f_ffree; | ||
61 | __kernel_fsid_t f_fsid; | ||
62 | __u32 f_namelen; | ||
63 | __u32 f_frsize; | ||
64 | __u32 f_flags; | ||
65 | __u32 f_spare[4]; | ||
66 | }; | ||
67 | |||
68 | #endif /* __s390x__ */ | ||
69 | #endif | 50 | #endif |
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 2ac311ef5c9b..1386fcaf4ef6 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile | |||
@@ -14,16 +14,25 @@ endif | |||
14 | CFLAGS_smp.o := -Wno-nonnull | 14 | CFLAGS_smp.o := -Wno-nonnull |
15 | 15 | ||
16 | # | 16 | # |
17 | # Disable tailcall optimizations for stack / callchain walking functions | ||
18 | # since this might generate broken code when accessing register 15 and | ||
19 | # passing its content to other functions. | ||
20 | # | ||
21 | CFLAGS_stacktrace.o += -fno-optimize-sibling-calls | ||
22 | CFLAGS_dumpstack.o += -fno-optimize-sibling-calls | ||
23 | |||
24 | # | ||
17 | # Pass UTS_MACHINE for user_regset definition | 25 | # Pass UTS_MACHINE for user_regset definition |
18 | # | 26 | # |
19 | CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' | 27 | CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' |
20 | 28 | ||
21 | CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w | 29 | CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w |
22 | 30 | ||
23 | obj-y := bitmap.o traps.o time.o process.o base.o early.o setup.o vtime.o \ | 31 | obj-y := bitmap.o traps.o time.o process.o base.o early.o setup.o vtime.o |
24 | processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o \ | 32 | obj-y += processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o |
25 | debug.o irq.o ipl.o dis.o diag.o mem_detect.o sclp.o vdso.o \ | 33 | obj-y += debug.o irq.o ipl.o dis.o diag.o mem_detect.o sclp.o vdso.o |
26 | sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o | 34 | obj-y += sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o |
35 | obj-y += dumpstack.o | ||
27 | 36 | ||
28 | obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) | 37 | obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) |
29 | obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) | 38 | obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) |
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index fface87056eb..7a82f9f70100 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c | |||
@@ -35,6 +35,7 @@ int main(void) | |||
35 | DEFINE(__TI_task, offsetof(struct thread_info, task)); | 35 | DEFINE(__TI_task, offsetof(struct thread_info, task)); |
36 | DEFINE(__TI_domain, offsetof(struct thread_info, exec_domain)); | 36 | DEFINE(__TI_domain, offsetof(struct thread_info, exec_domain)); |
37 | DEFINE(__TI_flags, offsetof(struct thread_info, flags)); | 37 | DEFINE(__TI_flags, offsetof(struct thread_info, flags)); |
38 | DEFINE(__TI_sysc_table, offsetof(struct thread_info, sys_call_table)); | ||
38 | DEFINE(__TI_cpu, offsetof(struct thread_info, cpu)); | 39 | DEFINE(__TI_cpu, offsetof(struct thread_info, cpu)); |
39 | DEFINE(__TI_precount, offsetof(struct thread_info, preempt_count)); | 40 | DEFINE(__TI_precount, offsetof(struct thread_info, preempt_count)); |
40 | DEFINE(__TI_user_timer, offsetof(struct thread_info, user_timer)); | 41 | DEFINE(__TI_user_timer, offsetof(struct thread_info, user_timer)); |
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index 6de049fbe62d..c439ac9ced09 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c | |||
@@ -362,6 +362,7 @@ static int setup_frame32(int sig, struct k_sigaction *ka, | |||
362 | /* set extra registers only for synchronous signals */ | 362 | /* set extra registers only for synchronous signals */ |
363 | regs->gprs[4] = regs->int_code & 127; | 363 | regs->gprs[4] = regs->int_code & 127; |
364 | regs->gprs[5] = regs->int_parm_long; | 364 | regs->gprs[5] = regs->int_parm_long; |
365 | regs->gprs[6] = task_thread_info(current)->last_break; | ||
365 | } | 366 | } |
366 | 367 | ||
367 | /* Place signal number on stack to allow backtrace from handler. */ | 368 | /* Place signal number on stack to allow backtrace from handler. */ |
@@ -421,6 +422,7 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
421 | regs->gprs[2] = map_signal(sig); | 422 | regs->gprs[2] = map_signal(sig); |
422 | regs->gprs[3] = (__force __u64) &frame->info; | 423 | regs->gprs[3] = (__force __u64) &frame->info; |
423 | regs->gprs[4] = (__force __u64) &frame->uc; | 424 | regs->gprs[4] = (__force __u64) &frame->uc; |
425 | regs->gprs[5] = task_thread_info(current)->last_break; | ||
424 | return 0; | 426 | return 0; |
425 | 427 | ||
426 | give_sigsegv: | 428 | give_sigsegv: |
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c index 3ad5e9540160..7f4a4a8c847c 100644 --- a/arch/s390/kernel/dis.c +++ b/arch/s390/kernel/dis.c | |||
@@ -1696,14 +1696,15 @@ static struct insn *find_insn(unsigned char *code) | |||
1696 | * insn_to_mnemonic - decode an s390 instruction | 1696 | * insn_to_mnemonic - decode an s390 instruction |
1697 | * @instruction: instruction to decode | 1697 | * @instruction: instruction to decode |
1698 | * @buf: buffer to fill with mnemonic | 1698 | * @buf: buffer to fill with mnemonic |
1699 | * @len: length of buffer | ||
1699 | * | 1700 | * |
1700 | * Decode the instruction at @instruction and store the corresponding | 1701 | * Decode the instruction at @instruction and store the corresponding |
1701 | * mnemonic into @buf. | 1702 | * mnemonic into @buf of length @len. |
1702 | * @buf is left unchanged if the instruction could not be decoded. | 1703 | * @buf is left unchanged if the instruction could not be decoded. |
1703 | * Returns: | 1704 | * Returns: |
1704 | * %0 on success, %-ENOENT if the instruction was not found. | 1705 | * %0 on success, %-ENOENT if the instruction was not found. |
1705 | */ | 1706 | */ |
1706 | int insn_to_mnemonic(unsigned char *instruction, char buf[8]) | 1707 | int insn_to_mnemonic(unsigned char *instruction, char *buf, unsigned int len) |
1707 | { | 1708 | { |
1708 | struct insn *insn; | 1709 | struct insn *insn; |
1709 | 1710 | ||
@@ -1711,10 +1712,10 @@ int insn_to_mnemonic(unsigned char *instruction, char buf[8]) | |||
1711 | if (!insn) | 1712 | if (!insn) |
1712 | return -ENOENT; | 1713 | return -ENOENT; |
1713 | if (insn->name[0] == '\0') | 1714 | if (insn->name[0] == '\0') |
1714 | snprintf(buf, 8, "%s", | 1715 | snprintf(buf, len, "%s", |
1715 | long_insn_name[(int) insn->name[1]]); | 1716 | long_insn_name[(int) insn->name[1]]); |
1716 | else | 1717 | else |
1717 | snprintf(buf, 8, "%.5s", insn->name); | 1718 | snprintf(buf, len, "%.5s", insn->name); |
1718 | return 0; | 1719 | return 0; |
1719 | } | 1720 | } |
1720 | EXPORT_SYMBOL_GPL(insn_to_mnemonic); | 1721 | EXPORT_SYMBOL_GPL(insn_to_mnemonic); |
diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c new file mode 100644 index 000000000000..03dce39d01ee --- /dev/null +++ b/arch/s390/kernel/dumpstack.c | |||
@@ -0,0 +1,236 @@ | |||
1 | /* | ||
2 | * Stack dumping functions | ||
3 | * | ||
4 | * Copyright IBM Corp. 1999, 2013 | ||
5 | */ | ||
6 | |||
7 | #include <linux/kallsyms.h> | ||
8 | #include <linux/hardirq.h> | ||
9 | #include <linux/kprobes.h> | ||
10 | #include <linux/utsname.h> | ||
11 | #include <linux/export.h> | ||
12 | #include <linux/kdebug.h> | ||
13 | #include <linux/ptrace.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/sched.h> | ||
16 | #include <asm/processor.h> | ||
17 | #include <asm/debug.h> | ||
18 | #include <asm/ipl.h> | ||
19 | |||
20 | #ifndef CONFIG_64BIT | ||
21 | #define LONG "%08lx " | ||
22 | #define FOURLONG "%08lx %08lx %08lx %08lx\n" | ||
23 | static int kstack_depth_to_print = 12; | ||
24 | #else /* CONFIG_64BIT */ | ||
25 | #define LONG "%016lx " | ||
26 | #define FOURLONG "%016lx %016lx %016lx %016lx\n" | ||
27 | static int kstack_depth_to_print = 20; | ||
28 | #endif /* CONFIG_64BIT */ | ||
29 | |||
30 | /* | ||
31 | * For show_trace we have tree different stack to consider: | ||
32 | * - the panic stack which is used if the kernel stack has overflown | ||
33 | * - the asynchronous interrupt stack (cpu related) | ||
34 | * - the synchronous kernel stack (process related) | ||
35 | * The stack trace can start at any of the three stack and can potentially | ||
36 | * touch all of them. The order is: panic stack, async stack, sync stack. | ||
37 | */ | ||
38 | static unsigned long | ||
39 | __show_trace(unsigned long sp, unsigned long low, unsigned long high) | ||
40 | { | ||
41 | struct stack_frame *sf; | ||
42 | struct pt_regs *regs; | ||
43 | |||
44 | while (1) { | ||
45 | sp = sp & PSW_ADDR_INSN; | ||
46 | if (sp < low || sp > high - sizeof(*sf)) | ||
47 | return sp; | ||
48 | sf = (struct stack_frame *) sp; | ||
49 | printk("([<%016lx>] ", sf->gprs[8] & PSW_ADDR_INSN); | ||
50 | print_symbol("%s)\n", sf->gprs[8] & PSW_ADDR_INSN); | ||
51 | /* Follow the backchain. */ | ||
52 | while (1) { | ||
53 | low = sp; | ||
54 | sp = sf->back_chain & PSW_ADDR_INSN; | ||
55 | if (!sp) | ||
56 | break; | ||
57 | if (sp <= low || sp > high - sizeof(*sf)) | ||
58 | return sp; | ||
59 | sf = (struct stack_frame *) sp; | ||
60 | printk(" [<%016lx>] ", sf->gprs[8] & PSW_ADDR_INSN); | ||
61 | print_symbol("%s\n", sf->gprs[8] & PSW_ADDR_INSN); | ||
62 | } | ||
63 | /* Zero backchain detected, check for interrupt frame. */ | ||
64 | sp = (unsigned long) (sf + 1); | ||
65 | if (sp <= low || sp > high - sizeof(*regs)) | ||
66 | return sp; | ||
67 | regs = (struct pt_regs *) sp; | ||
68 | printk(" [<%016lx>] ", regs->psw.addr & PSW_ADDR_INSN); | ||
69 | print_symbol("%s\n", regs->psw.addr & PSW_ADDR_INSN); | ||
70 | low = sp; | ||
71 | sp = regs->gprs[15]; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | static void show_trace(struct task_struct *task, unsigned long *stack) | ||
76 | { | ||
77 | register unsigned long __r15 asm ("15"); | ||
78 | unsigned long sp; | ||
79 | |||
80 | sp = (unsigned long) stack; | ||
81 | if (!sp) | ||
82 | sp = task ? task->thread.ksp : __r15; | ||
83 | printk("Call Trace:\n"); | ||
84 | #ifdef CONFIG_CHECK_STACK | ||
85 | sp = __show_trace(sp, S390_lowcore.panic_stack - 4096, | ||
86 | S390_lowcore.panic_stack); | ||
87 | #endif | ||
88 | sp = __show_trace(sp, S390_lowcore.async_stack - ASYNC_SIZE, | ||
89 | S390_lowcore.async_stack); | ||
90 | if (task) | ||
91 | __show_trace(sp, (unsigned long) task_stack_page(task), | ||
92 | (unsigned long) task_stack_page(task) + THREAD_SIZE); | ||
93 | else | ||
94 | __show_trace(sp, S390_lowcore.thread_info, | ||
95 | S390_lowcore.thread_info + THREAD_SIZE); | ||
96 | if (!task) | ||
97 | task = current; | ||
98 | debug_show_held_locks(task); | ||
99 | } | ||
100 | |||
101 | void show_stack(struct task_struct *task, unsigned long *sp) | ||
102 | { | ||
103 | register unsigned long *__r15 asm ("15"); | ||
104 | unsigned long *stack; | ||
105 | int i; | ||
106 | |||
107 | if (!sp) | ||
108 | stack = task ? (unsigned long *) task->thread.ksp : __r15; | ||
109 | else | ||
110 | stack = sp; | ||
111 | |||
112 | for (i = 0; i < kstack_depth_to_print; i++) { | ||
113 | if (((addr_t) stack & (THREAD_SIZE-1)) == 0) | ||
114 | break; | ||
115 | if ((i * sizeof(long) % 32) == 0) | ||
116 | printk("%s ", i == 0 ? "" : "\n"); | ||
117 | printk(LONG, *stack++); | ||
118 | } | ||
119 | printk("\n"); | ||
120 | show_trace(task, sp); | ||
121 | } | ||
122 | |||
123 | static void show_last_breaking_event(struct pt_regs *regs) | ||
124 | { | ||
125 | #ifdef CONFIG_64BIT | ||
126 | printk("Last Breaking-Event-Address:\n"); | ||
127 | printk(" [<%016lx>] ", regs->args[0] & PSW_ADDR_INSN); | ||
128 | print_symbol("%s\n", regs->args[0] & PSW_ADDR_INSN); | ||
129 | #endif | ||
130 | } | ||
131 | |||
132 | /* | ||
133 | * The architecture-independent dump_stack generator | ||
134 | */ | ||
135 | void dump_stack(void) | ||
136 | { | ||
137 | printk("CPU: %d %s %s %.*s\n", | ||
138 | task_thread_info(current)->cpu, print_tainted(), | ||
139 | init_utsname()->release, | ||
140 | (int)strcspn(init_utsname()->version, " "), | ||
141 | init_utsname()->version); | ||
142 | printk("Process %s (pid: %d, task: %p, ksp: %p)\n", | ||
143 | current->comm, current->pid, current, | ||
144 | (void *) current->thread.ksp); | ||
145 | show_stack(NULL, NULL); | ||
146 | } | ||
147 | EXPORT_SYMBOL(dump_stack); | ||
148 | |||
149 | static inline int mask_bits(struct pt_regs *regs, unsigned long bits) | ||
150 | { | ||
151 | return (regs->psw.mask & bits) / ((~bits + 1) & bits); | ||
152 | } | ||
153 | |||
154 | void show_registers(struct pt_regs *regs) | ||
155 | { | ||
156 | char *mode; | ||
157 | |||
158 | mode = user_mode(regs) ? "User" : "Krnl"; | ||
159 | printk("%s PSW : %p %p", | ||
160 | mode, (void *) regs->psw.mask, | ||
161 | (void *) regs->psw.addr); | ||
162 | print_symbol(" (%s)\n", regs->psw.addr & PSW_ADDR_INSN); | ||
163 | printk(" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x " | ||
164 | "P:%x AS:%x CC:%x PM:%x", mask_bits(regs, PSW_MASK_PER), | ||
165 | mask_bits(regs, PSW_MASK_DAT), mask_bits(regs, PSW_MASK_IO), | ||
166 | mask_bits(regs, PSW_MASK_EXT), mask_bits(regs, PSW_MASK_KEY), | ||
167 | mask_bits(regs, PSW_MASK_MCHECK), mask_bits(regs, PSW_MASK_WAIT), | ||
168 | mask_bits(regs, PSW_MASK_PSTATE), mask_bits(regs, PSW_MASK_ASC), | ||
169 | mask_bits(regs, PSW_MASK_CC), mask_bits(regs, PSW_MASK_PM)); | ||
170 | #ifdef CONFIG_64BIT | ||
171 | printk(" EA:%x", mask_bits(regs, PSW_MASK_EA | PSW_MASK_BA)); | ||
172 | #endif | ||
173 | printk("\n%s GPRS: " FOURLONG, mode, | ||
174 | regs->gprs[0], regs->gprs[1], regs->gprs[2], regs->gprs[3]); | ||
175 | printk(" " FOURLONG, | ||
176 | regs->gprs[4], regs->gprs[5], regs->gprs[6], regs->gprs[7]); | ||
177 | printk(" " FOURLONG, | ||
178 | regs->gprs[8], regs->gprs[9], regs->gprs[10], regs->gprs[11]); | ||
179 | printk(" " FOURLONG, | ||
180 | regs->gprs[12], regs->gprs[13], regs->gprs[14], regs->gprs[15]); | ||
181 | show_code(regs); | ||
182 | } | ||
183 | |||
184 | void show_regs(struct pt_regs *regs) | ||
185 | { | ||
186 | printk("CPU: %d %s %s %.*s\n", | ||
187 | task_thread_info(current)->cpu, print_tainted(), | ||
188 | init_utsname()->release, | ||
189 | (int)strcspn(init_utsname()->version, " "), | ||
190 | init_utsname()->version); | ||
191 | printk("Process %s (pid: %d, task: %p, ksp: %p)\n", | ||
192 | current->comm, current->pid, current, | ||
193 | (void *) current->thread.ksp); | ||
194 | show_registers(regs); | ||
195 | /* Show stack backtrace if pt_regs is from kernel mode */ | ||
196 | if (!user_mode(regs)) | ||
197 | show_trace(NULL, (unsigned long *) regs->gprs[15]); | ||
198 | show_last_breaking_event(regs); | ||
199 | } | ||
200 | |||
201 | static DEFINE_SPINLOCK(die_lock); | ||
202 | |||
203 | void die(struct pt_regs *regs, const char *str) | ||
204 | { | ||
205 | static int die_counter; | ||
206 | |||
207 | oops_enter(); | ||
208 | lgr_info_log(); | ||
209 | debug_stop_all(); | ||
210 | console_verbose(); | ||
211 | spin_lock_irq(&die_lock); | ||
212 | bust_spinlocks(1); | ||
213 | printk("%s: %04x [#%d] ", str, regs->int_code & 0xffff, ++die_counter); | ||
214 | #ifdef CONFIG_PREEMPT | ||
215 | printk("PREEMPT "); | ||
216 | #endif | ||
217 | #ifdef CONFIG_SMP | ||
218 | printk("SMP "); | ||
219 | #endif | ||
220 | #ifdef CONFIG_DEBUG_PAGEALLOC | ||
221 | printk("DEBUG_PAGEALLOC"); | ||
222 | #endif | ||
223 | printk("\n"); | ||
224 | notify_die(DIE_OOPS, str, regs, 0, regs->int_code & 0xffff, SIGSEGV); | ||
225 | print_modules(); | ||
226 | show_regs(regs); | ||
227 | bust_spinlocks(0); | ||
228 | add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); | ||
229 | spin_unlock_irq(&die_lock); | ||
230 | if (in_interrupt()) | ||
231 | panic("Fatal exception in interrupt"); | ||
232 | if (panic_on_oops) | ||
233 | panic("Fatal exception: panic_on_oops"); | ||
234 | oops_exit(); | ||
235 | do_exit(SIGSEGV); | ||
236 | } | ||
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 94feff7d6132..4d5e6f8a7978 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -45,6 +45,7 @@ _TIF_TRACE = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \ | |||
45 | 45 | ||
46 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER | 46 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER |
47 | STACK_SIZE = 1 << STACK_SHIFT | 47 | STACK_SIZE = 1 << STACK_SHIFT |
48 | STACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE | ||
48 | 49 | ||
49 | #define BASED(name) name-system_call(%r13) | 50 | #define BASED(name) name-system_call(%r13) |
50 | 51 | ||
@@ -97,10 +98,10 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
97 | sra %r14,\shift | 98 | sra %r14,\shift |
98 | jnz 1f | 99 | jnz 1f |
99 | CHECK_STACK 1<<\shift,\savearea | 100 | CHECK_STACK 1<<\shift,\savearea |
101 | ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | ||
100 | j 2f | 102 | j 2f |
101 | 1: l %r15,\stack # load target stack | 103 | 1: l %r15,\stack # load target stack |
102 | 2: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | 104 | 2: la %r11,STACK_FRAME_OVERHEAD(%r15) |
103 | la %r11,STACK_FRAME_OVERHEAD(%r15) | ||
104 | .endm | 105 | .endm |
105 | 106 | ||
106 | .macro ADD64 high,low,timer | 107 | .macro ADD64 high,low,timer |
@@ -150,7 +151,7 @@ ENTRY(__switch_to) | |||
150 | l %r4,__THREAD_info(%r2) # get thread_info of prev | 151 | l %r4,__THREAD_info(%r2) # get thread_info of prev |
151 | l %r5,__THREAD_info(%r3) # get thread_info of next | 152 | l %r5,__THREAD_info(%r3) # get thread_info of next |
152 | lr %r15,%r5 | 153 | lr %r15,%r5 |
153 | ahi %r15,STACK_SIZE # end of kernel stack of next | 154 | ahi %r15,STACK_INIT # end of kernel stack of next |
154 | st %r3,__LC_CURRENT # store task struct of next | 155 | st %r3,__LC_CURRENT # store task struct of next |
155 | st %r5,__LC_THREAD_INFO # store thread info of next | 156 | st %r5,__LC_THREAD_INFO # store thread info of next |
156 | st %r15,__LC_KERNEL_STACK # store end of kernel stack | 157 | st %r15,__LC_KERNEL_STACK # store end of kernel stack |
@@ -178,7 +179,6 @@ sysc_stm: | |||
178 | l %r13,__LC_SVC_NEW_PSW+4 | 179 | l %r13,__LC_SVC_NEW_PSW+4 |
179 | sysc_per: | 180 | sysc_per: |
180 | l %r15,__LC_KERNEL_STACK | 181 | l %r15,__LC_KERNEL_STACK |
181 | ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | ||
182 | la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs | 182 | la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs |
183 | sysc_vtime: | 183 | sysc_vtime: |
184 | UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER | 184 | UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER |
@@ -188,6 +188,7 @@ sysc_vtime: | |||
188 | mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC | 188 | mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC |
189 | sysc_do_svc: | 189 | sysc_do_svc: |
190 | oi __TI_flags+3(%r12),_TIF_SYSCALL | 190 | oi __TI_flags+3(%r12),_TIF_SYSCALL |
191 | l %r10,__TI_sysc_table(%r12) # 31 bit system call table | ||
191 | lh %r8,__PT_INT_CODE+2(%r11) | 192 | lh %r8,__PT_INT_CODE+2(%r11) |
192 | sla %r8,2 # shift and test for svc0 | 193 | sla %r8,2 # shift and test for svc0 |
193 | jnz sysc_nr_ok | 194 | jnz sysc_nr_ok |
@@ -198,7 +199,6 @@ sysc_do_svc: | |||
198 | lr %r8,%r1 | 199 | lr %r8,%r1 |
199 | sla %r8,2 | 200 | sla %r8,2 |
200 | sysc_nr_ok: | 201 | sysc_nr_ok: |
201 | l %r10,BASED(.Lsys_call_table) # 31 bit system call table | ||
202 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) | 202 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) |
203 | st %r2,__PT_ORIG_GPR2(%r11) | 203 | st %r2,__PT_ORIG_GPR2(%r11) |
204 | st %r7,STACK_FRAME_OVERHEAD(%r15) | 204 | st %r7,STACK_FRAME_OVERHEAD(%r15) |
@@ -359,11 +359,11 @@ ENTRY(pgm_check_handler) | |||
359 | tm __LC_PGM_ILC+3,0x80 # check for per exception | 359 | tm __LC_PGM_ILC+3,0x80 # check for per exception |
360 | jnz pgm_svcper # -> single stepped svc | 360 | jnz pgm_svcper # -> single stepped svc |
361 | 0: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC | 361 | 0: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC |
362 | ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | ||
362 | j 2f | 363 | j 2f |
363 | 1: UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER | 364 | 1: UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER |
364 | l %r15,__LC_KERNEL_STACK | 365 | l %r15,__LC_KERNEL_STACK |
365 | 2: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | 366 | 2: la %r11,STACK_FRAME_OVERHEAD(%r15) |
366 | la %r11,STACK_FRAME_OVERHEAD(%r15) | ||
367 | stm %r0,%r7,__PT_R0(%r11) | 367 | stm %r0,%r7,__PT_R0(%r11) |
368 | mvc __PT_R8(32,%r11),__LC_SAVE_AREA_SYNC | 368 | mvc __PT_R8(32,%r11),__LC_SAVE_AREA_SYNC |
369 | stm %r8,%r9,__PT_PSW(%r11) | 369 | stm %r8,%r9,__PT_PSW(%r11) |
@@ -485,7 +485,6 @@ io_work: | |||
485 | # | 485 | # |
486 | io_work_user: | 486 | io_work_user: |
487 | l %r1,__LC_KERNEL_STACK | 487 | l %r1,__LC_KERNEL_STACK |
488 | ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | ||
489 | mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) | 488 | mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) |
490 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) | 489 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) |
491 | la %r11,STACK_FRAME_OVERHEAD(%r1) | 490 | la %r11,STACK_FRAME_OVERHEAD(%r1) |
@@ -646,7 +645,6 @@ mcck_skip: | |||
646 | tm __PT_PSW+1(%r11),0x01 # returning to user ? | 645 | tm __PT_PSW+1(%r11),0x01 # returning to user ? |
647 | jno mcck_return | 646 | jno mcck_return |
648 | l %r1,__LC_KERNEL_STACK # switch to kernel stack | 647 | l %r1,__LC_KERNEL_STACK # switch to kernel stack |
649 | ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | ||
650 | mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) | 648 | mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) |
651 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) | 649 | xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) |
652 | la %r11,STACK_FRAME_OVERHEAD(%r15) | 650 | la %r11,STACK_FRAME_OVERHEAD(%r15) |
@@ -674,6 +672,7 @@ mcck_panic: | |||
674 | sra %r14,PAGE_SHIFT | 672 | sra %r14,PAGE_SHIFT |
675 | jz 0f | 673 | jz 0f |
676 | l %r15,__LC_PANIC_STACK | 674 | l %r15,__LC_PANIC_STACK |
675 | j mcck_skip | ||
677 | 0: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | 676 | 0: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) |
678 | j mcck_skip | 677 | j mcck_skip |
679 | 678 | ||
@@ -714,12 +713,10 @@ ENTRY(restart_int_handler) | |||
714 | */ | 713 | */ |
715 | stack_overflow: | 714 | stack_overflow: |
716 | l %r15,__LC_PANIC_STACK # change to panic stack | 715 | l %r15,__LC_PANIC_STACK # change to panic stack |
717 | ahi %r15,-__PT_SIZE # create pt_regs | 716 | la %r11,STACK_FRAME_OVERHEAD(%r15) |
718 | stm %r0,%r7,__PT_R0(%r15) | 717 | stm %r0,%r7,__PT_R0(%r11) |
719 | stm %r8,%r9,__PT_PSW(%r15) | 718 | stm %r8,%r9,__PT_PSW(%r11) |
720 | mvc __PT_R8(32,%r11),0(%r14) | 719 | mvc __PT_R8(32,%r11),0(%r14) |
721 | lr %r15,%r11 | ||
722 | ahi %r15,-STACK_FRAME_OVERHEAD | ||
723 | l %r1,BASED(1f) | 720 | l %r1,BASED(1f) |
724 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) | 721 | xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) |
725 | lr %r2,%r11 # pass pointer to pt_regs | 722 | lr %r2,%r11 # pass pointer to pt_regs |
@@ -799,15 +796,14 @@ cleanup_system_call: | |||
799 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 796 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
800 | # set up saved register 11 | 797 | # set up saved register 11 |
801 | l %r15,__LC_KERNEL_STACK | 798 | l %r15,__LC_KERNEL_STACK |
802 | ahi %r15,-__PT_SIZE | 799 | la %r9,STACK_FRAME_OVERHEAD(%r15) |
803 | st %r15,12(%r11) # r11 pt_regs pointer | 800 | st %r9,12(%r11) # r11 pt_regs pointer |
804 | # fill pt_regs | 801 | # fill pt_regs |
805 | mvc __PT_R8(32,%r15),__LC_SAVE_AREA_SYNC | 802 | mvc __PT_R8(32,%r9),__LC_SAVE_AREA_SYNC |
806 | stm %r0,%r7,__PT_R0(%r15) | 803 | stm %r0,%r7,__PT_R0(%r9) |
807 | mvc __PT_PSW(8,%r15),__LC_SVC_OLD_PSW | 804 | mvc __PT_PSW(8,%r9),__LC_SVC_OLD_PSW |
808 | mvc __PT_INT_CODE(4,%r15),__LC_SVC_ILC | 805 | mvc __PT_INT_CODE(4,%r9),__LC_SVC_ILC |
809 | # setup saved register 15 | 806 | # setup saved register 15 |
810 | ahi %r15,-STACK_FRAME_OVERHEAD | ||
811 | st %r15,28(%r11) # r15 stack pointer | 807 | st %r15,28(%r11) # r15 stack pointer |
812 | # set new psw address and exit | 808 | # set new psw address and exit |
813 | l %r9,BASED(cleanup_table+4) # sysc_do_svc + 0x80000000 | 809 | l %r9,BASED(cleanup_table+4) # sysc_do_svc + 0x80000000 |
@@ -910,7 +906,6 @@ cleanup_idle_wait: | |||
910 | .Ltrace_enter: .long do_syscall_trace_enter | 906 | .Ltrace_enter: .long do_syscall_trace_enter |
911 | .Ltrace_exit: .long do_syscall_trace_exit | 907 | .Ltrace_exit: .long do_syscall_trace_exit |
912 | .Lschedule_tail: .long schedule_tail | 908 | .Lschedule_tail: .long schedule_tail |
913 | .Lsys_call_table: .long sys_call_table | ||
914 | .Lsysc_per: .long sysc_per + 0x80000000 | 909 | .Lsysc_per: .long sysc_per + 0x80000000 |
915 | #ifdef CONFIG_TRACE_IRQFLAGS | 910 | #ifdef CONFIG_TRACE_IRQFLAGS |
916 | .Lhardirqs_on: .long trace_hardirqs_on_caller | 911 | .Lhardirqs_on: .long trace_hardirqs_on_caller |
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h index c3a736a3ed44..aa0ab02e9595 100644 --- a/arch/s390/kernel/entry.h +++ b/arch/s390/kernel/entry.h | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <asm/cputime.h> | 7 | #include <asm/cputime.h> |
8 | 8 | ||
9 | extern void *restart_stack; | 9 | extern void *restart_stack; |
10 | extern unsigned long suspend_zero_pages; | ||
10 | 11 | ||
11 | void system_call(void); | 12 | void system_call(void); |
12 | void pgm_check_handler(void); | 13 | void pgm_check_handler(void); |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 2e6d60c55f90..4c17eece707e 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
@@ -39,6 +39,7 @@ __PT_R15 = __PT_GPRS + 120 | |||
39 | 39 | ||
40 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER | 40 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER |
41 | STACK_SIZE = 1 << STACK_SHIFT | 41 | STACK_SIZE = 1 << STACK_SHIFT |
42 | STACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE | ||
42 | 43 | ||
43 | _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ | 44 | _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ |
44 | _TIF_MCCK_PENDING | _TIF_PER_TRAP ) | 45 | _TIF_MCCK_PENDING | _TIF_PER_TRAP ) |
@@ -124,10 +125,10 @@ _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) | |||
124 | srag %r14,%r14,\shift | 125 | srag %r14,%r14,\shift |
125 | jnz 1f | 126 | jnz 1f |
126 | CHECK_STACK 1<<\shift,\savearea | 127 | CHECK_STACK 1<<\shift,\savearea |
128 | aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | ||
127 | j 2f | 129 | j 2f |
128 | 1: lg %r15,\stack # load target stack | 130 | 1: lg %r15,\stack # load target stack |
129 | 2: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | 131 | 2: la %r11,STACK_FRAME_OVERHEAD(%r15) |
130 | la %r11,STACK_FRAME_OVERHEAD(%r15) | ||
131 | .endm | 132 | .endm |
132 | 133 | ||
133 | .macro UPDATE_VTIME scratch,enter_timer | 134 | .macro UPDATE_VTIME scratch,enter_timer |
@@ -177,7 +178,7 @@ ENTRY(__switch_to) | |||
177 | lg %r4,__THREAD_info(%r2) # get thread_info of prev | 178 | lg %r4,__THREAD_info(%r2) # get thread_info of prev |
178 | lg %r5,__THREAD_info(%r3) # get thread_info of next | 179 | lg %r5,__THREAD_info(%r3) # get thread_info of next |
179 | lgr %r15,%r5 | 180 | lgr %r15,%r5 |
180 | aghi %r15,STACK_SIZE # end of kernel stack of next | 181 | aghi %r15,STACK_INIT # end of kernel stack of next |
181 | stg %r3,__LC_CURRENT # store task struct of next | 182 | stg %r3,__LC_CURRENT # store task struct of next |
182 | stg %r5,__LC_THREAD_INFO # store thread info of next | 183 | stg %r5,__LC_THREAD_INFO # store thread info of next |
183 | stg %r15,__LC_KERNEL_STACK # store end of kernel stack | 184 | stg %r15,__LC_KERNEL_STACK # store end of kernel stack |
@@ -203,10 +204,8 @@ sysc_stmg: | |||
203 | stmg %r8,%r15,__LC_SAVE_AREA_SYNC | 204 | stmg %r8,%r15,__LC_SAVE_AREA_SYNC |
204 | lg %r10,__LC_LAST_BREAK | 205 | lg %r10,__LC_LAST_BREAK |
205 | lg %r12,__LC_THREAD_INFO | 206 | lg %r12,__LC_THREAD_INFO |
206 | larl %r13,system_call | ||
207 | sysc_per: | 207 | sysc_per: |
208 | lg %r15,__LC_KERNEL_STACK | 208 | lg %r15,__LC_KERNEL_STACK |
209 | aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | ||
210 | la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs | 209 | la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs |
211 | sysc_vtime: | 210 | sysc_vtime: |
212 | UPDATE_VTIME %r13,__LC_SYNC_ENTER_TIMER | 211 | UPDATE_VTIME %r13,__LC_SYNC_ENTER_TIMER |
@@ -217,6 +216,7 @@ sysc_vtime: | |||
217 | mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC | 216 | mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC |
218 | sysc_do_svc: | 217 | sysc_do_svc: |
219 | oi __TI_flags+7(%r12),_TIF_SYSCALL | 218 | oi __TI_flags+7(%r12),_TIF_SYSCALL |
219 | lg %r10,__TI_sysc_table(%r12) # address of system call table | ||
220 | llgh %r8,__PT_INT_CODE+2(%r11) | 220 | llgh %r8,__PT_INT_CODE+2(%r11) |
221 | slag %r8,%r8,2 # shift and test for svc 0 | 221 | slag %r8,%r8,2 # shift and test for svc 0 |
222 | jnz sysc_nr_ok | 222 | jnz sysc_nr_ok |
@@ -227,13 +227,6 @@ sysc_do_svc: | |||
227 | sth %r1,__PT_INT_CODE+2(%r11) | 227 | sth %r1,__PT_INT_CODE+2(%r11) |
228 | slag %r8,%r1,2 | 228 | slag %r8,%r1,2 |
229 | sysc_nr_ok: | 229 | sysc_nr_ok: |
230 | larl %r10,sys_call_table # 64 bit system call table | ||
231 | #ifdef CONFIG_COMPAT | ||
232 | tm __TI_flags+5(%r12),(_TIF_31BIT>>16) | ||
233 | jno sysc_noemu | ||
234 | larl %r10,sys_call_table_emu # 31 bit system call table | ||
235 | sysc_noemu: | ||
236 | #endif | ||
237 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) | 230 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) |
238 | stg %r2,__PT_ORIG_GPR2(%r11) | 231 | stg %r2,__PT_ORIG_GPR2(%r11) |
239 | stg %r7,STACK_FRAME_OVERHEAD(%r15) | 232 | stg %r7,STACK_FRAME_OVERHEAD(%r15) |
@@ -389,6 +382,7 @@ ENTRY(pgm_check_handler) | |||
389 | tm __LC_PGM_ILC+3,0x80 # check for per exception | 382 | tm __LC_PGM_ILC+3,0x80 # check for per exception |
390 | jnz pgm_svcper # -> single stepped svc | 383 | jnz pgm_svcper # -> single stepped svc |
391 | 0: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC | 384 | 0: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC |
385 | aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | ||
392 | j 2f | 386 | j 2f |
393 | 1: UPDATE_VTIME %r14,__LC_SYNC_ENTER_TIMER | 387 | 1: UPDATE_VTIME %r14,__LC_SYNC_ENTER_TIMER |
394 | LAST_BREAK %r14 | 388 | LAST_BREAK %r14 |
@@ -398,8 +392,7 @@ ENTRY(pgm_check_handler) | |||
398 | tm __LC_PGM_ILC+2,0x02 # check for transaction abort | 392 | tm __LC_PGM_ILC+2,0x02 # check for transaction abort |
399 | jz 2f | 393 | jz 2f |
400 | mvc __THREAD_trap_tdb(256,%r14),0(%r13) | 394 | mvc __THREAD_trap_tdb(256,%r14),0(%r13) |
401 | 2: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | 395 | 2: la %r11,STACK_FRAME_OVERHEAD(%r15) |
402 | la %r11,STACK_FRAME_OVERHEAD(%r15) | ||
403 | stmg %r0,%r7,__PT_R0(%r11) | 396 | stmg %r0,%r7,__PT_R0(%r11) |
404 | mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC | 397 | mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC |
405 | stmg %r8,%r9,__PT_PSW(%r11) | 398 | stmg %r8,%r9,__PT_PSW(%r11) |
@@ -526,7 +519,6 @@ io_work: | |||
526 | # | 519 | # |
527 | io_work_user: | 520 | io_work_user: |
528 | lg %r1,__LC_KERNEL_STACK | 521 | lg %r1,__LC_KERNEL_STACK |
529 | aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | ||
530 | mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) | 522 | mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) |
531 | xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) | 523 | xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) |
532 | la %r11,STACK_FRAME_OVERHEAD(%r1) | 524 | la %r11,STACK_FRAME_OVERHEAD(%r1) |
@@ -688,7 +680,6 @@ mcck_skip: | |||
688 | tm __PT_PSW+1(%r11),0x01 # returning to user ? | 680 | tm __PT_PSW+1(%r11),0x01 # returning to user ? |
689 | jno mcck_return | 681 | jno mcck_return |
690 | lg %r1,__LC_KERNEL_STACK # switch to kernel stack | 682 | lg %r1,__LC_KERNEL_STACK # switch to kernel stack |
691 | aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE) | ||
692 | mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) | 683 | mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11) |
693 | xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) | 684 | xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) |
694 | la %r11,STACK_FRAME_OVERHEAD(%r1) | 685 | la %r11,STACK_FRAME_OVERHEAD(%r1) |
@@ -755,14 +746,12 @@ ENTRY(restart_int_handler) | |||
755 | * Setup a pt_regs so that show_trace can provide a good call trace. | 746 | * Setup a pt_regs so that show_trace can provide a good call trace. |
756 | */ | 747 | */ |
757 | stack_overflow: | 748 | stack_overflow: |
758 | lg %r11,__LC_PANIC_STACK # change to panic stack | 749 | lg %r15,__LC_PANIC_STACK # change to panic stack |
759 | aghi %r11,-__PT_SIZE # create pt_regs | 750 | la %r11,STACK_FRAME_OVERHEAD(%r15) |
760 | stmg %r0,%r7,__PT_R0(%r11) | 751 | stmg %r0,%r7,__PT_R0(%r11) |
761 | stmg %r8,%r9,__PT_PSW(%r11) | 752 | stmg %r8,%r9,__PT_PSW(%r11) |
762 | mvc __PT_R8(64,%r11),0(%r14) | 753 | mvc __PT_R8(64,%r11),0(%r14) |
763 | stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2 | 754 | stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2 |
764 | lgr %r15,%r11 | ||
765 | aghi %r15,-STACK_FRAME_OVERHEAD | ||
766 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) | 755 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) |
767 | lgr %r2,%r11 # pass pointer to pt_regs | 756 | lgr %r2,%r11 # pass pointer to pt_regs |
768 | jg kernel_stack_overflow | 757 | jg kernel_stack_overflow |
@@ -846,15 +835,14 @@ cleanup_system_call: | |||
846 | mvc __TI_last_break(8,%r12),16(%r11) | 835 | mvc __TI_last_break(8,%r12),16(%r11) |
847 | 0: # set up saved register r11 | 836 | 0: # set up saved register r11 |
848 | lg %r15,__LC_KERNEL_STACK | 837 | lg %r15,__LC_KERNEL_STACK |
849 | aghi %r15,-__PT_SIZE | 838 | la %r9,STACK_FRAME_OVERHEAD(%r15) |
850 | stg %r15,24(%r11) # r11 pt_regs pointer | 839 | stg %r9,24(%r11) # r11 pt_regs pointer |
851 | # fill pt_regs | 840 | # fill pt_regs |
852 | mvc __PT_R8(64,%r15),__LC_SAVE_AREA_SYNC | 841 | mvc __PT_R8(64,%r9),__LC_SAVE_AREA_SYNC |
853 | stmg %r0,%r7,__PT_R0(%r15) | 842 | stmg %r0,%r7,__PT_R0(%r9) |
854 | mvc __PT_PSW(16,%r15),__LC_SVC_OLD_PSW | 843 | mvc __PT_PSW(16,%r9),__LC_SVC_OLD_PSW |
855 | mvc __PT_INT_CODE(4,%r15),__LC_SVC_ILC | 844 | mvc __PT_INT_CODE(4,%r9),__LC_SVC_ILC |
856 | # setup saved register r15 | 845 | # setup saved register r15 |
857 | aghi %r15,-STACK_FRAME_OVERHEAD | ||
858 | stg %r15,56(%r11) # r15 stack pointer | 846 | stg %r15,56(%r11) # r15 stack pointer |
859 | # set new psw address and exit | 847 | # set new psw address and exit |
860 | larl %r9,sysc_do_svc | 848 | larl %r9,sysc_do_svc |
@@ -1011,6 +999,7 @@ sys_call_table: | |||
1011 | #ifdef CONFIG_COMPAT | 999 | #ifdef CONFIG_COMPAT |
1012 | 1000 | ||
1013 | #define SYSCALL(esa,esame,emu) .long emu | 1001 | #define SYSCALL(esa,esame,emu) .long emu |
1002 | .globl sys_call_table_emu | ||
1014 | sys_call_table_emu: | 1003 | sys_call_table_emu: |
1015 | #include "syscalls.S" | 1004 | #include "syscalls.S" |
1016 | #undef SYSCALL | 1005 | #undef SYSCALL |
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index b3de27700016..ac2178161ec3 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/reboot.h> | 13 | #include <linux/reboot.h> |
14 | #include <linux/ftrace.h> | 14 | #include <linux/ftrace.h> |
15 | #include <linux/debug_locks.h> | 15 | #include <linux/debug_locks.h> |
16 | #include <linux/suspend.h> | ||
16 | #include <asm/cio.h> | 17 | #include <asm/cio.h> |
17 | #include <asm/setup.h> | 18 | #include <asm/setup.h> |
18 | #include <asm/pgtable.h> | 19 | #include <asm/pgtable.h> |
@@ -67,6 +68,35 @@ void setup_regs(void) | |||
67 | memcpy((void *) SAVE_AREA_BASE, (void *) sa, sizeof(struct save_area)); | 68 | memcpy((void *) SAVE_AREA_BASE, (void *) sa, sizeof(struct save_area)); |
68 | } | 69 | } |
69 | 70 | ||
71 | /* | ||
72 | * PM notifier callback for kdump | ||
73 | */ | ||
74 | static int machine_kdump_pm_cb(struct notifier_block *nb, unsigned long action, | ||
75 | void *ptr) | ||
76 | { | ||
77 | switch (action) { | ||
78 | case PM_SUSPEND_PREPARE: | ||
79 | case PM_HIBERNATION_PREPARE: | ||
80 | if (crashk_res.start) | ||
81 | crash_map_reserved_pages(); | ||
82 | break; | ||
83 | case PM_POST_SUSPEND: | ||
84 | case PM_POST_HIBERNATION: | ||
85 | if (crashk_res.start) | ||
86 | crash_unmap_reserved_pages(); | ||
87 | break; | ||
88 | default: | ||
89 | return NOTIFY_DONE; | ||
90 | } | ||
91 | return NOTIFY_OK; | ||
92 | } | ||
93 | |||
94 | static int __init machine_kdump_pm_init(void) | ||
95 | { | ||
96 | pm_notifier(machine_kdump_pm_cb, 0); | ||
97 | return 0; | ||
98 | } | ||
99 | arch_initcall(machine_kdump_pm_init); | ||
70 | #endif | 100 | #endif |
71 | 101 | ||
72 | /* | 102 | /* |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 29268859d8ee..0f419c5765c8 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -377,11 +377,14 @@ static void __init setup_lowcore(void) | |||
377 | PSW_MASK_DAT | PSW_MASK_MCHECK; | 377 | PSW_MASK_DAT | PSW_MASK_MCHECK; |
378 | lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler; | 378 | lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler; |
379 | lc->clock_comparator = -1ULL; | 379 | lc->clock_comparator = -1ULL; |
380 | lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE; | 380 | lc->kernel_stack = ((unsigned long) &init_thread_union) |
381 | + THREAD_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); | ||
381 | lc->async_stack = (unsigned long) | 382 | lc->async_stack = (unsigned long) |
382 | __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE; | 383 | __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) |
384 | + ASYNC_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); | ||
383 | lc->panic_stack = (unsigned long) | 385 | lc->panic_stack = (unsigned long) |
384 | __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE; | 386 | __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) |
387 | + PAGE_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); | ||
385 | lc->current_task = (unsigned long) init_thread_union.thread_info.task; | 388 | lc->current_task = (unsigned long) init_thread_union.thread_info.task; |
386 | lc->thread_info = (unsigned long) &init_thread_union; | 389 | lc->thread_info = (unsigned long) &init_thread_union; |
387 | lc->machine_flags = S390_lowcore.machine_flags; | 390 | lc->machine_flags = S390_lowcore.machine_flags; |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 6ff5845679e6..8074cb4b7cbf 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -181,8 +181,10 @@ static int __cpuinit pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu) | |||
181 | lc = pcpu->lowcore; | 181 | lc = pcpu->lowcore; |
182 | memcpy(lc, &S390_lowcore, 512); | 182 | memcpy(lc, &S390_lowcore, 512); |
183 | memset((char *) lc + 512, 0, sizeof(*lc) - 512); | 183 | memset((char *) lc + 512, 0, sizeof(*lc) - 512); |
184 | lc->async_stack = pcpu->async_stack + ASYNC_SIZE; | 184 | lc->async_stack = pcpu->async_stack + ASYNC_SIZE |
185 | lc->panic_stack = pcpu->panic_stack + PAGE_SIZE; | 185 | - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); |
186 | lc->panic_stack = pcpu->panic_stack + PAGE_SIZE | ||
187 | - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); | ||
186 | lc->cpu_nr = cpu; | 188 | lc->cpu_nr = cpu; |
187 | #ifndef CONFIG_64BIT | 189 | #ifndef CONFIG_64BIT |
188 | if (MACHINE_HAS_IEEE) { | 190 | if (MACHINE_HAS_IEEE) { |
@@ -253,7 +255,8 @@ static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *tsk) | |||
253 | struct _lowcore *lc = pcpu->lowcore; | 255 | struct _lowcore *lc = pcpu->lowcore; |
254 | struct thread_info *ti = task_thread_info(tsk); | 256 | struct thread_info *ti = task_thread_info(tsk); |
255 | 257 | ||
256 | lc->kernel_stack = (unsigned long) task_stack_page(tsk) + THREAD_SIZE; | 258 | lc->kernel_stack = (unsigned long) task_stack_page(tsk) |
259 | + THREAD_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); | ||
257 | lc->thread_info = (unsigned long) task_thread_info(tsk); | 260 | lc->thread_info = (unsigned long) task_thread_info(tsk); |
258 | lc->current_task = (unsigned long) tsk; | 261 | lc->current_task = (unsigned long) tsk; |
259 | lc->user_timer = ti->user_timer; | 262 | lc->user_timer = ti->user_timer; |
@@ -809,8 +812,10 @@ void __init smp_prepare_boot_cpu(void) | |||
809 | pcpu->state = CPU_STATE_CONFIGURED; | 812 | pcpu->state = CPU_STATE_CONFIGURED; |
810 | pcpu->address = boot_cpu_address; | 813 | pcpu->address = boot_cpu_address; |
811 | pcpu->lowcore = (struct _lowcore *)(unsigned long) store_prefix(); | 814 | pcpu->lowcore = (struct _lowcore *)(unsigned long) store_prefix(); |
812 | pcpu->async_stack = S390_lowcore.async_stack - ASYNC_SIZE; | 815 | pcpu->async_stack = S390_lowcore.async_stack - ASYNC_SIZE |
813 | pcpu->panic_stack = S390_lowcore.panic_stack - PAGE_SIZE; | 816 | + STACK_FRAME_OVERHEAD + sizeof(struct pt_regs); |
817 | pcpu->panic_stack = S390_lowcore.panic_stack - PAGE_SIZE | ||
818 | + STACK_FRAME_OVERHEAD + sizeof(struct pt_regs); | ||
814 | S390_lowcore.percpu_offset = __per_cpu_offset[0]; | 819 | S390_lowcore.percpu_offset = __per_cpu_offset[0]; |
815 | smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN); | 820 | smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN); |
816 | set_cpu_present(0, true); | 821 | set_cpu_present(0, true); |
diff --git a/arch/s390/kernel/suspend.c b/arch/s390/kernel/suspend.c index aa1494d0e380..c479d2f9605b 100644 --- a/arch/s390/kernel/suspend.c +++ b/arch/s390/kernel/suspend.c | |||
@@ -41,6 +41,7 @@ struct page_key_data { | |||
41 | static struct page_key_data *page_key_data; | 41 | static struct page_key_data *page_key_data; |
42 | static struct page_key_data *page_key_rp, *page_key_wp; | 42 | static struct page_key_data *page_key_rp, *page_key_wp; |
43 | static unsigned long page_key_rx, page_key_wx; | 43 | static unsigned long page_key_rx, page_key_wx; |
44 | unsigned long suspend_zero_pages; | ||
44 | 45 | ||
45 | /* | 46 | /* |
46 | * For each page in the hibernation image one additional byte is | 47 | * For each page in the hibernation image one additional byte is |
@@ -149,6 +150,36 @@ int pfn_is_nosave(unsigned long pfn) | |||
149 | return 0; | 150 | return 0; |
150 | } | 151 | } |
151 | 152 | ||
153 | /* | ||
154 | * PM notifier callback for suspend | ||
155 | */ | ||
156 | static int suspend_pm_cb(struct notifier_block *nb, unsigned long action, | ||
157 | void *ptr) | ||
158 | { | ||
159 | switch (action) { | ||
160 | case PM_SUSPEND_PREPARE: | ||
161 | case PM_HIBERNATION_PREPARE: | ||
162 | suspend_zero_pages = __get_free_pages(GFP_KERNEL, LC_ORDER); | ||
163 | if (!suspend_zero_pages) | ||
164 | return NOTIFY_BAD; | ||
165 | break; | ||
166 | case PM_POST_SUSPEND: | ||
167 | case PM_POST_HIBERNATION: | ||
168 | free_pages(suspend_zero_pages, LC_ORDER); | ||
169 | break; | ||
170 | default: | ||
171 | return NOTIFY_DONE; | ||
172 | } | ||
173 | return NOTIFY_OK; | ||
174 | } | ||
175 | |||
176 | static int __init suspend_pm_init(void) | ||
177 | { | ||
178 | pm_notifier(suspend_pm_cb, 0); | ||
179 | return 0; | ||
180 | } | ||
181 | arch_initcall(suspend_pm_init); | ||
182 | |||
152 | void save_processor_state(void) | 183 | void save_processor_state(void) |
153 | { | 184 | { |
154 | /* swsusp_arch_suspend() actually saves all cpu register contents. | 185 | /* swsusp_arch_suspend() actually saves all cpu register contents. |
diff --git a/arch/s390/kernel/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S index d4ca4e0617b5..c487be4cfc81 100644 --- a/arch/s390/kernel/swsusp_asm64.S +++ b/arch/s390/kernel/swsusp_asm64.S | |||
@@ -36,8 +36,8 @@ ENTRY(swsusp_arch_suspend) | |||
36 | /* Store prefix register on stack */ | 36 | /* Store prefix register on stack */ |
37 | stpx __SF_EMPTY(%r15) | 37 | stpx __SF_EMPTY(%r15) |
38 | 38 | ||
39 | /* Save prefix register contents for lowcore */ | 39 | /* Save prefix register contents for lowcore copy */ |
40 | llgf %r4,__SF_EMPTY(%r15) | 40 | llgf %r10,__SF_EMPTY(%r15) |
41 | 41 | ||
42 | /* Get pointer to save area */ | 42 | /* Get pointer to save area */ |
43 | lghi %r1,0x1000 | 43 | lghi %r1,0x1000 |
@@ -91,7 +91,18 @@ ENTRY(swsusp_arch_suspend) | |||
91 | xc __SF_EMPTY(4,%r15),__SF_EMPTY(%r15) | 91 | xc __SF_EMPTY(4,%r15),__SF_EMPTY(%r15) |
92 | spx __SF_EMPTY(%r15) | 92 | spx __SF_EMPTY(%r15) |
93 | 93 | ||
94 | /* Save absolute zero pages */ | ||
95 | larl %r2,suspend_zero_pages | ||
96 | lg %r2,0(%r2) | ||
97 | lghi %r4,0 | ||
98 | lghi %r3,2*PAGE_SIZE | ||
99 | lghi %r5,2*PAGE_SIZE | ||
100 | 1: mvcle %r2,%r4,0 | ||
101 | jo 1b | ||
102 | |||
103 | /* Copy lowcore to absolute zero lowcore */ | ||
94 | lghi %r2,0 | 104 | lghi %r2,0 |
105 | lgr %r4,%r10 | ||
95 | lghi %r3,2*PAGE_SIZE | 106 | lghi %r3,2*PAGE_SIZE |
96 | lghi %r5,2*PAGE_SIZE | 107 | lghi %r5,2*PAGE_SIZE |
97 | 1: mvcle %r2,%r4,0 | 108 | 1: mvcle %r2,%r4,0 |
@@ -248,8 +259,20 @@ restore_registers: | |||
248 | /* Load old stack */ | 259 | /* Load old stack */ |
249 | lg %r15,0x2f8(%r13) | 260 | lg %r15,0x2f8(%r13) |
250 | 261 | ||
262 | /* Save prefix register */ | ||
263 | mvc __SF_EMPTY(4,%r15),0x318(%r13) | ||
264 | |||
265 | /* Restore absolute zero pages */ | ||
266 | lghi %r2,0 | ||
267 | larl %r4,suspend_zero_pages | ||
268 | lg %r4,0(%r4) | ||
269 | lghi %r3,2*PAGE_SIZE | ||
270 | lghi %r5,2*PAGE_SIZE | ||
271 | 1: mvcle %r2,%r4,0 | ||
272 | jo 1b | ||
273 | |||
251 | /* Restore prefix register */ | 274 | /* Restore prefix register */ |
252 | spx 0x318(%r13) | 275 | spx __SF_EMPTY(%r15) |
253 | 276 | ||
254 | /* Activate DAT */ | 277 | /* Activate DAT */ |
255 | stosm __SF_EMPTY(%r15),0x04 | 278 | stosm __SF_EMPTY(%r15),0x04 |
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 13dd63fba367..c5762324d9ee 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c | |||
@@ -12,49 +12,16 @@ | |||
12 | * 'Traps.c' handles hardware traps and faults after we have saved some | 12 | * 'Traps.c' handles hardware traps and faults after we have saved some |
13 | * state in 'asm.s'. | 13 | * state in 'asm.s'. |
14 | */ | 14 | */ |
15 | #include <linux/sched.h> | 15 | #include <linux/kprobes.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kdebug.h> |
17 | #include <linux/string.h> | 17 | #include <linux/module.h> |
18 | #include <linux/errno.h> | ||
19 | #include <linux/ptrace.h> | 18 | #include <linux/ptrace.h> |
20 | #include <linux/timer.h> | 19 | #include <linux/sched.h> |
21 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
22 | #include <linux/smp.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/seq_file.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/kdebug.h> | ||
29 | #include <linux/kallsyms.h> | ||
30 | #include <linux/reboot.h> | ||
31 | #include <linux/kprobes.h> | ||
32 | #include <linux/bug.h> | ||
33 | #include <linux/utsname.h> | ||
34 | #include <asm/uaccess.h> | ||
35 | #include <asm/io.h> | ||
36 | #include <linux/atomic.h> | ||
37 | #include <asm/mathemu.h> | ||
38 | #include <asm/cpcmd.h> | ||
39 | #include <asm/lowcore.h> | ||
40 | #include <asm/debug.h> | ||
41 | #include <asm/ipl.h> | ||
42 | #include "entry.h" | 21 | #include "entry.h" |
43 | 22 | ||
44 | int show_unhandled_signals = 1; | 23 | int show_unhandled_signals = 1; |
45 | 24 | ||
46 | #define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; }) | ||
47 | |||
48 | #ifndef CONFIG_64BIT | ||
49 | #define LONG "%08lx " | ||
50 | #define FOURLONG "%08lx %08lx %08lx %08lx\n" | ||
51 | static int kstack_depth_to_print = 12; | ||
52 | #else /* CONFIG_64BIT */ | ||
53 | #define LONG "%016lx " | ||
54 | #define FOURLONG "%016lx %016lx %016lx %016lx\n" | ||
55 | static int kstack_depth_to_print = 20; | ||
56 | #endif /* CONFIG_64BIT */ | ||
57 | |||
58 | static inline void __user *get_trap_ip(struct pt_regs *regs) | 25 | static inline void __user *get_trap_ip(struct pt_regs *regs) |
59 | { | 26 | { |
60 | #ifdef CONFIG_64BIT | 27 | #ifdef CONFIG_64BIT |
@@ -72,215 +39,6 @@ static inline void __user *get_trap_ip(struct pt_regs *regs) | |||
72 | #endif | 39 | #endif |
73 | } | 40 | } |
74 | 41 | ||
75 | /* | ||
76 | * For show_trace we have tree different stack to consider: | ||
77 | * - the panic stack which is used if the kernel stack has overflown | ||
78 | * - the asynchronous interrupt stack (cpu related) | ||
79 | * - the synchronous kernel stack (process related) | ||
80 | * The stack trace can start at any of the three stack and can potentially | ||
81 | * touch all of them. The order is: panic stack, async stack, sync stack. | ||
82 | */ | ||
83 | static unsigned long | ||
84 | __show_trace(unsigned long sp, unsigned long low, unsigned long high) | ||
85 | { | ||
86 | struct stack_frame *sf; | ||
87 | struct pt_regs *regs; | ||
88 | |||
89 | while (1) { | ||
90 | sp = sp & PSW_ADDR_INSN; | ||
91 | if (sp < low || sp > high - sizeof(*sf)) | ||
92 | return sp; | ||
93 | sf = (struct stack_frame *) sp; | ||
94 | printk("([<%016lx>] ", sf->gprs[8] & PSW_ADDR_INSN); | ||
95 | print_symbol("%s)\n", sf->gprs[8] & PSW_ADDR_INSN); | ||
96 | /* Follow the backchain. */ | ||
97 | while (1) { | ||
98 | low = sp; | ||
99 | sp = sf->back_chain & PSW_ADDR_INSN; | ||
100 | if (!sp) | ||
101 | break; | ||
102 | if (sp <= low || sp > high - sizeof(*sf)) | ||
103 | return sp; | ||
104 | sf = (struct stack_frame *) sp; | ||
105 | printk(" [<%016lx>] ", sf->gprs[8] & PSW_ADDR_INSN); | ||
106 | print_symbol("%s\n", sf->gprs[8] & PSW_ADDR_INSN); | ||
107 | } | ||
108 | /* Zero backchain detected, check for interrupt frame. */ | ||
109 | sp = (unsigned long) (sf + 1); | ||
110 | if (sp <= low || sp > high - sizeof(*regs)) | ||
111 | return sp; | ||
112 | regs = (struct pt_regs *) sp; | ||
113 | printk(" [<%016lx>] ", regs->psw.addr & PSW_ADDR_INSN); | ||
114 | print_symbol("%s\n", regs->psw.addr & PSW_ADDR_INSN); | ||
115 | low = sp; | ||
116 | sp = regs->gprs[15]; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | static void show_trace(struct task_struct *task, unsigned long *stack) | ||
121 | { | ||
122 | register unsigned long __r15 asm ("15"); | ||
123 | unsigned long sp; | ||
124 | |||
125 | sp = (unsigned long) stack; | ||
126 | if (!sp) | ||
127 | sp = task ? task->thread.ksp : __r15; | ||
128 | printk("Call Trace:\n"); | ||
129 | #ifdef CONFIG_CHECK_STACK | ||
130 | sp = __show_trace(sp, S390_lowcore.panic_stack - 4096, | ||
131 | S390_lowcore.panic_stack); | ||
132 | #endif | ||
133 | sp = __show_trace(sp, S390_lowcore.async_stack - ASYNC_SIZE, | ||
134 | S390_lowcore.async_stack); | ||
135 | if (task) | ||
136 | __show_trace(sp, (unsigned long) task_stack_page(task), | ||
137 | (unsigned long) task_stack_page(task) + THREAD_SIZE); | ||
138 | else | ||
139 | __show_trace(sp, S390_lowcore.thread_info, | ||
140 | S390_lowcore.thread_info + THREAD_SIZE); | ||
141 | if (!task) | ||
142 | task = current; | ||
143 | debug_show_held_locks(task); | ||
144 | } | ||
145 | |||
146 | void show_stack(struct task_struct *task, unsigned long *sp) | ||
147 | { | ||
148 | register unsigned long * __r15 asm ("15"); | ||
149 | unsigned long *stack; | ||
150 | int i; | ||
151 | |||
152 | if (!sp) | ||
153 | stack = task ? (unsigned long *) task->thread.ksp : __r15; | ||
154 | else | ||
155 | stack = sp; | ||
156 | |||
157 | for (i = 0; i < kstack_depth_to_print; i++) { | ||
158 | if (((addr_t) stack & (THREAD_SIZE-1)) == 0) | ||
159 | break; | ||
160 | if ((i * sizeof(long) % 32) == 0) | ||
161 | printk("%s ", i == 0 ? "" : "\n"); | ||
162 | printk(LONG, *stack++); | ||
163 | } | ||
164 | printk("\n"); | ||
165 | show_trace(task, sp); | ||
166 | } | ||
167 | |||
168 | static void show_last_breaking_event(struct pt_regs *regs) | ||
169 | { | ||
170 | #ifdef CONFIG_64BIT | ||
171 | printk("Last Breaking-Event-Address:\n"); | ||
172 | printk(" [<%016lx>] ", regs->args[0] & PSW_ADDR_INSN); | ||
173 | print_symbol("%s\n", regs->args[0] & PSW_ADDR_INSN); | ||
174 | #endif | ||
175 | } | ||
176 | |||
177 | /* | ||
178 | * The architecture-independent dump_stack generator | ||
179 | */ | ||
180 | void dump_stack(void) | ||
181 | { | ||
182 | printk("CPU: %d %s %s %.*s\n", | ||
183 | task_thread_info(current)->cpu, print_tainted(), | ||
184 | init_utsname()->release, | ||
185 | (int)strcspn(init_utsname()->version, " "), | ||
186 | init_utsname()->version); | ||
187 | printk("Process %s (pid: %d, task: %p, ksp: %p)\n", | ||
188 | current->comm, current->pid, current, | ||
189 | (void *) current->thread.ksp); | ||
190 | show_stack(NULL, NULL); | ||
191 | } | ||
192 | EXPORT_SYMBOL(dump_stack); | ||
193 | |||
194 | static inline int mask_bits(struct pt_regs *regs, unsigned long bits) | ||
195 | { | ||
196 | return (regs->psw.mask & bits) / ((~bits + 1) & bits); | ||
197 | } | ||
198 | |||
199 | void show_registers(struct pt_regs *regs) | ||
200 | { | ||
201 | char *mode; | ||
202 | |||
203 | mode = user_mode(regs) ? "User" : "Krnl"; | ||
204 | printk("%s PSW : %p %p", | ||
205 | mode, (void *) regs->psw.mask, | ||
206 | (void *) regs->psw.addr); | ||
207 | print_symbol(" (%s)\n", regs->psw.addr & PSW_ADDR_INSN); | ||
208 | printk(" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x " | ||
209 | "P:%x AS:%x CC:%x PM:%x", mask_bits(regs, PSW_MASK_PER), | ||
210 | mask_bits(regs, PSW_MASK_DAT), mask_bits(regs, PSW_MASK_IO), | ||
211 | mask_bits(regs, PSW_MASK_EXT), mask_bits(regs, PSW_MASK_KEY), | ||
212 | mask_bits(regs, PSW_MASK_MCHECK), mask_bits(regs, PSW_MASK_WAIT), | ||
213 | mask_bits(regs, PSW_MASK_PSTATE), mask_bits(regs, PSW_MASK_ASC), | ||
214 | mask_bits(regs, PSW_MASK_CC), mask_bits(regs, PSW_MASK_PM)); | ||
215 | #ifdef CONFIG_64BIT | ||
216 | printk(" EA:%x", mask_bits(regs, PSW_MASK_EA | PSW_MASK_BA)); | ||
217 | #endif | ||
218 | printk("\n%s GPRS: " FOURLONG, mode, | ||
219 | regs->gprs[0], regs->gprs[1], regs->gprs[2], regs->gprs[3]); | ||
220 | printk(" " FOURLONG, | ||
221 | regs->gprs[4], regs->gprs[5], regs->gprs[6], regs->gprs[7]); | ||
222 | printk(" " FOURLONG, | ||
223 | regs->gprs[8], regs->gprs[9], regs->gprs[10], regs->gprs[11]); | ||
224 | printk(" " FOURLONG, | ||
225 | regs->gprs[12], regs->gprs[13], regs->gprs[14], regs->gprs[15]); | ||
226 | |||
227 | show_code(regs); | ||
228 | } | ||
229 | |||
230 | void show_regs(struct pt_regs *regs) | ||
231 | { | ||
232 | printk("CPU: %d %s %s %.*s\n", | ||
233 | task_thread_info(current)->cpu, print_tainted(), | ||
234 | init_utsname()->release, | ||
235 | (int)strcspn(init_utsname()->version, " "), | ||
236 | init_utsname()->version); | ||
237 | printk("Process %s (pid: %d, task: %p, ksp: %p)\n", | ||
238 | current->comm, current->pid, current, | ||
239 | (void *) current->thread.ksp); | ||
240 | show_registers(regs); | ||
241 | /* Show stack backtrace if pt_regs is from kernel mode */ | ||
242 | if (!user_mode(regs)) | ||
243 | show_trace(NULL, (unsigned long *) regs->gprs[15]); | ||
244 | show_last_breaking_event(regs); | ||
245 | } | ||
246 | |||
247 | static DEFINE_SPINLOCK(die_lock); | ||
248 | |||
249 | void die(struct pt_regs *regs, const char *str) | ||
250 | { | ||
251 | static int die_counter; | ||
252 | |||
253 | oops_enter(); | ||
254 | lgr_info_log(); | ||
255 | debug_stop_all(); | ||
256 | console_verbose(); | ||
257 | spin_lock_irq(&die_lock); | ||
258 | bust_spinlocks(1); | ||
259 | printk("%s: %04x [#%d] ", str, regs->int_code & 0xffff, ++die_counter); | ||
260 | #ifdef CONFIG_PREEMPT | ||
261 | printk("PREEMPT "); | ||
262 | #endif | ||
263 | #ifdef CONFIG_SMP | ||
264 | printk("SMP "); | ||
265 | #endif | ||
266 | #ifdef CONFIG_DEBUG_PAGEALLOC | ||
267 | printk("DEBUG_PAGEALLOC"); | ||
268 | #endif | ||
269 | printk("\n"); | ||
270 | notify_die(DIE_OOPS, str, regs, 0, regs->int_code & 0xffff, SIGSEGV); | ||
271 | print_modules(); | ||
272 | show_regs(regs); | ||
273 | bust_spinlocks(0); | ||
274 | add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); | ||
275 | spin_unlock_irq(&die_lock); | ||
276 | if (in_interrupt()) | ||
277 | panic("Fatal exception in interrupt"); | ||
278 | if (panic_on_oops) | ||
279 | panic("Fatal exception: panic_on_oops"); | ||
280 | oops_exit(); | ||
281 | do_exit(SIGSEGV); | ||
282 | } | ||
283 | |||
284 | static inline void report_user_fault(struct pt_regs *regs, int signr) | 42 | static inline void report_user_fault(struct pt_regs *regs, int signr) |
285 | { | 43 | { |
286 | if ((task_pid_nr(current) > 1) && !show_unhandled_signals) | 44 | if ((task_pid_nr(current) > 1) && !show_unhandled_signals) |
diff --git a/arch/s390/kvm/trace.h b/arch/s390/kvm/trace.h index 2b29e62351d3..53252d2d4720 100644 --- a/arch/s390/kvm/trace.h +++ b/arch/s390/kvm/trace.h | |||
@@ -117,7 +117,7 @@ TRACE_EVENT(kvm_s390_intercept_instruction, | |||
117 | __entry->instruction, | 117 | __entry->instruction, |
118 | insn_to_mnemonic((unsigned char *) | 118 | insn_to_mnemonic((unsigned char *) |
119 | &__entry->instruction, | 119 | &__entry->instruction, |
120 | __entry->insn) ? | 120 | __entry->insn, sizeof(__entry->insn)) ? |
121 | "unknown" : __entry->insn) | 121 | "unknown" : __entry->insn) |
122 | ); | 122 | ); |
123 | 123 | ||
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c index 479e94282910..9d84a1feefef 100644 --- a/arch/s390/mm/cmm.c +++ b/arch/s390/mm/cmm.c | |||
@@ -458,12 +458,10 @@ static int __init cmm_init(void) | |||
458 | if (rc) | 458 | if (rc) |
459 | goto out_pm; | 459 | goto out_pm; |
460 | cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread"); | 460 | cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread"); |
461 | rc = IS_ERR(cmm_thread_ptr) ? PTR_ERR(cmm_thread_ptr) : 0; | 461 | if (!IS_ERR(cmm_thread_ptr)) |
462 | if (rc) | 462 | return 0; |
463 | goto out_kthread; | ||
464 | return 0; | ||
465 | 463 | ||
466 | out_kthread: | 464 | rc = PTR_ERR(cmm_thread_ptr); |
467 | unregister_pm_notifier(&cmm_power_notifier); | 465 | unregister_pm_notifier(&cmm_power_notifier); |
468 | out_pm: | 466 | out_pm: |
469 | unregister_oom_notifier(&cmm_oom_nb); | 467 | unregister_oom_notifier(&cmm_oom_nb); |
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 2fb9e63b8fc4..047c3e4c59a2 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c | |||
@@ -395,8 +395,13 @@ void __kprobes do_protection_exception(struct pt_regs *regs) | |||
395 | int fault; | 395 | int fault; |
396 | 396 | ||
397 | trans_exc_code = regs->int_parm_long; | 397 | trans_exc_code = regs->int_parm_long; |
398 | /* Protection exception is suppressing, decrement psw address. */ | 398 | /* |
399 | regs->psw.addr = __rewind_psw(regs->psw, regs->int_code >> 16); | 399 | * Protection exceptions are suppressing, decrement psw address. |
400 | * The exception to this rule are aborted transactions, for these | ||
401 | * the PSW already points to the correct location. | ||
402 | */ | ||
403 | if (!(regs->int_code & 0x200)) | ||
404 | regs->psw.addr = __rewind_psw(regs->psw, regs->int_code >> 16); | ||
400 | /* | 405 | /* |
401 | * Check for low-address protection. This needs to be treated | 406 | * Check for low-address protection. This needs to be treated |
402 | * as a special case because the translation exception code | 407 | * as a special case because the translation exception code |
diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c index 532525ec88c1..121089d57802 100644 --- a/arch/s390/mm/hugetlbpage.c +++ b/arch/s390/mm/hugetlbpage.c | |||
@@ -39,7 +39,7 @@ int arch_prepare_hugepage(struct page *page) | |||
39 | if (!ptep) | 39 | if (!ptep) |
40 | return -ENOMEM; | 40 | return -ENOMEM; |
41 | 41 | ||
42 | pte = mk_pte(page, PAGE_RW); | 42 | pte_val(pte) = addr; |
43 | for (i = 0; i < PTRS_PER_PTE; i++) { | 43 | for (i = 0; i < PTRS_PER_PTE; i++) { |
44 | set_pte_at(&init_mm, addr + i * PAGE_SIZE, ptep + i, pte); | 44 | set_pte_at(&init_mm, addr + i * PAGE_SIZE, ptep + i, pte); |
45 | pte_val(pte) += PAGE_SIZE; | 45 | pte_val(pte) += PAGE_SIZE; |
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 49ce6bb2c641..0b09b2342302 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c | |||
@@ -42,11 +42,10 @@ pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE))); | |||
42 | unsigned long empty_zero_page, zero_page_mask; | 42 | unsigned long empty_zero_page, zero_page_mask; |
43 | EXPORT_SYMBOL(empty_zero_page); | 43 | EXPORT_SYMBOL(empty_zero_page); |
44 | 44 | ||
45 | static unsigned long __init setup_zero_pages(void) | 45 | static void __init setup_zero_pages(void) |
46 | { | 46 | { |
47 | struct cpuid cpu_id; | 47 | struct cpuid cpu_id; |
48 | unsigned int order; | 48 | unsigned int order; |
49 | unsigned long size; | ||
50 | struct page *page; | 49 | struct page *page; |
51 | int i; | 50 | int i; |
52 | 51 | ||
@@ -63,10 +62,18 @@ static unsigned long __init setup_zero_pages(void) | |||
63 | break; | 62 | break; |
64 | case 0x2097: /* z10 */ | 63 | case 0x2097: /* z10 */ |
65 | case 0x2098: /* z10 */ | 64 | case 0x2098: /* z10 */ |
66 | default: | 65 | case 0x2817: /* z196 */ |
66 | case 0x2818: /* z196 */ | ||
67 | order = 2; | 67 | order = 2; |
68 | break; | 68 | break; |
69 | case 0x2827: /* zEC12 */ | ||
70 | default: | ||
71 | order = 5; | ||
72 | break; | ||
69 | } | 73 | } |
74 | /* Limit number of empty zero pages for small memory sizes */ | ||
75 | if (order > 2 && totalram_pages <= 16384) | ||
76 | order = 2; | ||
70 | 77 | ||
71 | empty_zero_page = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order); | 78 | empty_zero_page = __get_free_pages(GFP_KERNEL | __GFP_ZERO, order); |
72 | if (!empty_zero_page) | 79 | if (!empty_zero_page) |
@@ -75,14 +82,11 @@ static unsigned long __init setup_zero_pages(void) | |||
75 | page = virt_to_page((void *) empty_zero_page); | 82 | page = virt_to_page((void *) empty_zero_page); |
76 | split_page(page, order); | 83 | split_page(page, order); |
77 | for (i = 1 << order; i > 0; i--) { | 84 | for (i = 1 << order; i > 0; i--) { |
78 | SetPageReserved(page); | 85 | mark_page_reserved(page); |
79 | page++; | 86 | page++; |
80 | } | 87 | } |
81 | 88 | ||
82 | size = PAGE_SIZE << order; | 89 | zero_page_mask = ((PAGE_SIZE << order) - 1) & PAGE_MASK; |
83 | zero_page_mask = (size - 1) & PAGE_MASK; | ||
84 | |||
85 | return 1UL << order; | ||
86 | } | 90 | } |
87 | 91 | ||
88 | /* | 92 | /* |
@@ -139,7 +143,7 @@ void __init mem_init(void) | |||
139 | 143 | ||
140 | /* this will put all low memory onto the freelists */ | 144 | /* this will put all low memory onto the freelists */ |
141 | totalram_pages += free_all_bootmem(); | 145 | totalram_pages += free_all_bootmem(); |
142 | totalram_pages -= setup_zero_pages(); /* Setup zeroed pages. */ | 146 | setup_zero_pages(); /* Setup zeroed pages. */ |
143 | 147 | ||
144 | reservedpages = 0; | 148 | reservedpages = 0; |
145 | 149 | ||
@@ -158,34 +162,15 @@ void __init mem_init(void) | |||
158 | PFN_ALIGN((unsigned long)&_eshared) - 1); | 162 | PFN_ALIGN((unsigned long)&_eshared) - 1); |
159 | } | 163 | } |
160 | 164 | ||
161 | void free_init_pages(char *what, unsigned long begin, unsigned long end) | ||
162 | { | ||
163 | unsigned long addr = begin; | ||
164 | |||
165 | if (begin >= end) | ||
166 | return; | ||
167 | for (; addr < end; addr += PAGE_SIZE) { | ||
168 | ClearPageReserved(virt_to_page(addr)); | ||
169 | init_page_count(virt_to_page(addr)); | ||
170 | memset((void *)(addr & PAGE_MASK), POISON_FREE_INITMEM, | ||
171 | PAGE_SIZE); | ||
172 | free_page(addr); | ||
173 | totalram_pages++; | ||
174 | } | ||
175 | printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10); | ||
176 | } | ||
177 | |||
178 | void free_initmem(void) | 165 | void free_initmem(void) |
179 | { | 166 | { |
180 | free_init_pages("unused kernel memory", | 167 | free_initmem_default(0); |
181 | (unsigned long)&__init_begin, | ||
182 | (unsigned long)&__init_end); | ||
183 | } | 168 | } |
184 | 169 | ||
185 | #ifdef CONFIG_BLK_DEV_INITRD | 170 | #ifdef CONFIG_BLK_DEV_INITRD |
186 | void __init free_initrd_mem(unsigned long start, unsigned long end) | 171 | void __init free_initrd_mem(unsigned long start, unsigned long end) |
187 | { | 172 | { |
188 | free_init_pages("initrd memory", start, end); | 173 | free_reserved_area(start, end, POISON_FREE_INITMEM, "initrd"); |
189 | } | 174 | } |
190 | #endif | 175 | #endif |
191 | 176 | ||
diff --git a/arch/s390/mm/pageattr.c b/arch/s390/mm/pageattr.c index d21040ed5e59..80adfbf75065 100644 --- a/arch/s390/mm/pageattr.c +++ b/arch/s390/mm/pageattr.c | |||
@@ -9,31 +9,25 @@ | |||
9 | #include <asm/pgtable.h> | 9 | #include <asm/pgtable.h> |
10 | #include <asm/page.h> | 10 | #include <asm/page.h> |
11 | 11 | ||
12 | static inline unsigned long sske_frame(unsigned long addr, unsigned char skey) | ||
13 | { | ||
14 | asm volatile(".insn rrf,0xb22b0000,%[skey],%[addr],9,0" | ||
15 | : [addr] "+a" (addr) : [skey] "d" (skey)); | ||
16 | return addr; | ||
17 | } | ||
18 | |||
12 | void storage_key_init_range(unsigned long start, unsigned long end) | 19 | void storage_key_init_range(unsigned long start, unsigned long end) |
13 | { | 20 | { |
14 | unsigned long boundary, function, size; | 21 | unsigned long boundary, size; |
15 | 22 | ||
16 | while (start < end) { | 23 | while (start < end) { |
17 | if (MACHINE_HAS_EDAT2) { | ||
18 | /* set storage keys for a 2GB frame */ | ||
19 | function = 0x22000 | PAGE_DEFAULT_KEY; | ||
20 | size = 1UL << 31; | ||
21 | boundary = (start + size) & ~(size - 1); | ||
22 | if (boundary <= end) { | ||
23 | do { | ||
24 | start = pfmf(function, start); | ||
25 | } while (start < boundary); | ||
26 | continue; | ||
27 | } | ||
28 | } | ||
29 | if (MACHINE_HAS_EDAT1) { | 24 | if (MACHINE_HAS_EDAT1) { |
30 | /* set storage keys for a 1MB frame */ | 25 | /* set storage keys for a 1MB frame */ |
31 | function = 0x21000 | PAGE_DEFAULT_KEY; | ||
32 | size = 1UL << 20; | 26 | size = 1UL << 20; |
33 | boundary = (start + size) & ~(size - 1); | 27 | boundary = (start + size) & ~(size - 1); |
34 | if (boundary <= end) { | 28 | if (boundary <= end) { |
35 | do { | 29 | do { |
36 | start = pfmf(function, start); | 30 | start = sske_frame(start, PAGE_DEFAULT_KEY); |
37 | } while (start < boundary); | 31 | } while (start < boundary); |
38 | continue; | 32 | continue; |
39 | } | 33 | } |
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index ae44d2a34313..bd954e96f51c 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
@@ -379,75 +379,183 @@ out_unmap: | |||
379 | } | 379 | } |
380 | EXPORT_SYMBOL_GPL(gmap_map_segment); | 380 | EXPORT_SYMBOL_GPL(gmap_map_segment); |
381 | 381 | ||
382 | /* | 382 | static unsigned long *gmap_table_walk(unsigned long address, struct gmap *gmap) |
383 | * this function is assumed to be called with mmap_sem held | ||
384 | */ | ||
385 | unsigned long __gmap_fault(unsigned long address, struct gmap *gmap) | ||
386 | { | 383 | { |
387 | unsigned long *table, vmaddr, segment; | 384 | unsigned long *table; |
388 | struct mm_struct *mm; | ||
389 | struct gmap_pgtable *mp; | ||
390 | struct gmap_rmap *rmap; | ||
391 | struct vm_area_struct *vma; | ||
392 | struct page *page; | ||
393 | pgd_t *pgd; | ||
394 | pud_t *pud; | ||
395 | pmd_t *pmd; | ||
396 | 385 | ||
397 | current->thread.gmap_addr = address; | ||
398 | mm = gmap->mm; | ||
399 | /* Walk the gmap address space page table */ | ||
400 | table = gmap->table + ((address >> 53) & 0x7ff); | 386 | table = gmap->table + ((address >> 53) & 0x7ff); |
401 | if (unlikely(*table & _REGION_ENTRY_INV)) | 387 | if (unlikely(*table & _REGION_ENTRY_INV)) |
402 | return -EFAULT; | 388 | return ERR_PTR(-EFAULT); |
403 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 389 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
404 | table = table + ((address >> 42) & 0x7ff); | 390 | table = table + ((address >> 42) & 0x7ff); |
405 | if (unlikely(*table & _REGION_ENTRY_INV)) | 391 | if (unlikely(*table & _REGION_ENTRY_INV)) |
406 | return -EFAULT; | 392 | return ERR_PTR(-EFAULT); |
407 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 393 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
408 | table = table + ((address >> 31) & 0x7ff); | 394 | table = table + ((address >> 31) & 0x7ff); |
409 | if (unlikely(*table & _REGION_ENTRY_INV)) | 395 | if (unlikely(*table & _REGION_ENTRY_INV)) |
410 | return -EFAULT; | 396 | return ERR_PTR(-EFAULT); |
411 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 397 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
412 | table = table + ((address >> 20) & 0x7ff); | 398 | table = table + ((address >> 20) & 0x7ff); |
399 | return table; | ||
400 | } | ||
401 | |||
402 | /** | ||
403 | * __gmap_translate - translate a guest address to a user space address | ||
404 | * @address: guest address | ||
405 | * @gmap: pointer to guest mapping meta data structure | ||
406 | * | ||
407 | * Returns user space address which corresponds to the guest address or | ||
408 | * -EFAULT if no such mapping exists. | ||
409 | * This function does not establish potentially missing page table entries. | ||
410 | * The mmap_sem of the mm that belongs to the address space must be held | ||
411 | * when this function gets called. | ||
412 | */ | ||
413 | unsigned long __gmap_translate(unsigned long address, struct gmap *gmap) | ||
414 | { | ||
415 | unsigned long *segment_ptr, vmaddr, segment; | ||
416 | struct gmap_pgtable *mp; | ||
417 | struct page *page; | ||
413 | 418 | ||
419 | current->thread.gmap_addr = address; | ||
420 | segment_ptr = gmap_table_walk(address, gmap); | ||
421 | if (IS_ERR(segment_ptr)) | ||
422 | return PTR_ERR(segment_ptr); | ||
414 | /* Convert the gmap address to an mm address. */ | 423 | /* Convert the gmap address to an mm address. */ |
415 | segment = *table; | 424 | segment = *segment_ptr; |
416 | if (likely(!(segment & _SEGMENT_ENTRY_INV))) { | 425 | if (!(segment & _SEGMENT_ENTRY_INV)) { |
417 | page = pfn_to_page(segment >> PAGE_SHIFT); | 426 | page = pfn_to_page(segment >> PAGE_SHIFT); |
418 | mp = (struct gmap_pgtable *) page->index; | 427 | mp = (struct gmap_pgtable *) page->index; |
419 | return mp->vmaddr | (address & ~PMD_MASK); | 428 | return mp->vmaddr | (address & ~PMD_MASK); |
420 | } else if (segment & _SEGMENT_ENTRY_RO) { | 429 | } else if (segment & _SEGMENT_ENTRY_RO) { |
421 | vmaddr = segment & _SEGMENT_ENTRY_ORIGIN; | 430 | vmaddr = segment & _SEGMENT_ENTRY_ORIGIN; |
422 | vma = find_vma(mm, vmaddr); | 431 | return vmaddr | (address & ~PMD_MASK); |
423 | if (!vma || vma->vm_start > vmaddr) | 432 | } |
424 | return -EFAULT; | 433 | return -EFAULT; |
425 | 434 | } | |
426 | /* Walk the parent mm page table */ | 435 | EXPORT_SYMBOL_GPL(__gmap_translate); |
427 | pgd = pgd_offset(mm, vmaddr); | 436 | |
428 | pud = pud_alloc(mm, pgd, vmaddr); | 437 | /** |
429 | if (!pud) | 438 | * gmap_translate - translate a guest address to a user space address |
430 | return -ENOMEM; | 439 | * @address: guest address |
431 | pmd = pmd_alloc(mm, pud, vmaddr); | 440 | * @gmap: pointer to guest mapping meta data structure |
432 | if (!pmd) | 441 | * |
433 | return -ENOMEM; | 442 | * Returns user space address which corresponds to the guest address or |
434 | if (!pmd_present(*pmd) && | 443 | * -EFAULT if no such mapping exists. |
435 | __pte_alloc(mm, vma, pmd, vmaddr)) | 444 | * This function does not establish potentially missing page table entries. |
436 | return -ENOMEM; | 445 | */ |
437 | /* pmd now points to a valid segment table entry. */ | 446 | unsigned long gmap_translate(unsigned long address, struct gmap *gmap) |
438 | rmap = kmalloc(sizeof(*rmap), GFP_KERNEL|__GFP_REPEAT); | 447 | { |
439 | if (!rmap) | 448 | unsigned long rc; |
440 | return -ENOMEM; | 449 | |
441 | /* Link gmap segment table entry location to page table. */ | 450 | down_read(&gmap->mm->mmap_sem); |
442 | page = pmd_page(*pmd); | 451 | rc = __gmap_translate(address, gmap); |
443 | mp = (struct gmap_pgtable *) page->index; | 452 | up_read(&gmap->mm->mmap_sem); |
444 | rmap->entry = table; | 453 | return rc; |
445 | spin_lock(&mm->page_table_lock); | 454 | } |
455 | EXPORT_SYMBOL_GPL(gmap_translate); | ||
456 | |||
457 | static int gmap_connect_pgtable(unsigned long segment, | ||
458 | unsigned long *segment_ptr, | ||
459 | struct gmap *gmap) | ||
460 | { | ||
461 | unsigned long vmaddr; | ||
462 | struct vm_area_struct *vma; | ||
463 | struct gmap_pgtable *mp; | ||
464 | struct gmap_rmap *rmap; | ||
465 | struct mm_struct *mm; | ||
466 | struct page *page; | ||
467 | pgd_t *pgd; | ||
468 | pud_t *pud; | ||
469 | pmd_t *pmd; | ||
470 | |||
471 | mm = gmap->mm; | ||
472 | vmaddr = segment & _SEGMENT_ENTRY_ORIGIN; | ||
473 | vma = find_vma(mm, vmaddr); | ||
474 | if (!vma || vma->vm_start > vmaddr) | ||
475 | return -EFAULT; | ||
476 | /* Walk the parent mm page table */ | ||
477 | pgd = pgd_offset(mm, vmaddr); | ||
478 | pud = pud_alloc(mm, pgd, vmaddr); | ||
479 | if (!pud) | ||
480 | return -ENOMEM; | ||
481 | pmd = pmd_alloc(mm, pud, vmaddr); | ||
482 | if (!pmd) | ||
483 | return -ENOMEM; | ||
484 | if (!pmd_present(*pmd) && | ||
485 | __pte_alloc(mm, vma, pmd, vmaddr)) | ||
486 | return -ENOMEM; | ||
487 | /* pmd now points to a valid segment table entry. */ | ||
488 | rmap = kmalloc(sizeof(*rmap), GFP_KERNEL|__GFP_REPEAT); | ||
489 | if (!rmap) | ||
490 | return -ENOMEM; | ||
491 | /* Link gmap segment table entry location to page table. */ | ||
492 | page = pmd_page(*pmd); | ||
493 | mp = (struct gmap_pgtable *) page->index; | ||
494 | rmap->entry = segment_ptr; | ||
495 | spin_lock(&mm->page_table_lock); | ||
496 | if (*segment_ptr == segment) { | ||
446 | list_add(&rmap->list, &mp->mapper); | 497 | list_add(&rmap->list, &mp->mapper); |
447 | spin_unlock(&mm->page_table_lock); | ||
448 | /* Set gmap segment table entry to page table. */ | 498 | /* Set gmap segment table entry to page table. */ |
449 | *table = pmd_val(*pmd) & PAGE_MASK; | 499 | *segment_ptr = pmd_val(*pmd) & PAGE_MASK; |
450 | return vmaddr | (address & ~PMD_MASK); | 500 | rmap = NULL; |
501 | } | ||
502 | spin_unlock(&mm->page_table_lock); | ||
503 | kfree(rmap); | ||
504 | return 0; | ||
505 | } | ||
506 | |||
507 | static void gmap_disconnect_pgtable(struct mm_struct *mm, unsigned long *table) | ||
508 | { | ||
509 | struct gmap_rmap *rmap, *next; | ||
510 | struct gmap_pgtable *mp; | ||
511 | struct page *page; | ||
512 | int flush; | ||
513 | |||
514 | flush = 0; | ||
515 | spin_lock(&mm->page_table_lock); | ||
516 | page = pfn_to_page(__pa(table) >> PAGE_SHIFT); | ||
517 | mp = (struct gmap_pgtable *) page->index; | ||
518 | list_for_each_entry_safe(rmap, next, &mp->mapper, list) { | ||
519 | *rmap->entry = | ||
520 | _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO | mp->vmaddr; | ||
521 | list_del(&rmap->list); | ||
522 | kfree(rmap); | ||
523 | flush = 1; | ||
524 | } | ||
525 | spin_unlock(&mm->page_table_lock); | ||
526 | if (flush) | ||
527 | __tlb_flush_global(); | ||
528 | } | ||
529 | |||
530 | /* | ||
531 | * this function is assumed to be called with mmap_sem held | ||
532 | */ | ||
533 | unsigned long __gmap_fault(unsigned long address, struct gmap *gmap) | ||
534 | { | ||
535 | unsigned long *segment_ptr, segment; | ||
536 | struct gmap_pgtable *mp; | ||
537 | struct page *page; | ||
538 | int rc; | ||
539 | |||
540 | current->thread.gmap_addr = address; | ||
541 | segment_ptr = gmap_table_walk(address, gmap); | ||
542 | if (IS_ERR(segment_ptr)) | ||
543 | return -EFAULT; | ||
544 | /* Convert the gmap address to an mm address. */ | ||
545 | while (1) { | ||
546 | segment = *segment_ptr; | ||
547 | if (!(segment & _SEGMENT_ENTRY_INV)) { | ||
548 | /* Page table is present */ | ||
549 | page = pfn_to_page(segment >> PAGE_SHIFT); | ||
550 | mp = (struct gmap_pgtable *) page->index; | ||
551 | return mp->vmaddr | (address & ~PMD_MASK); | ||
552 | } | ||
553 | if (!(segment & _SEGMENT_ENTRY_RO)) | ||
554 | /* Nothing mapped in the gmap address space. */ | ||
555 | break; | ||
556 | rc = gmap_connect_pgtable(segment, segment_ptr, gmap); | ||
557 | if (rc) | ||
558 | return rc; | ||
451 | } | 559 | } |
452 | return -EFAULT; | 560 | return -EFAULT; |
453 | } | 561 | } |
@@ -511,29 +619,6 @@ void gmap_discard(unsigned long from, unsigned long to, struct gmap *gmap) | |||
511 | } | 619 | } |
512 | EXPORT_SYMBOL_GPL(gmap_discard); | 620 | EXPORT_SYMBOL_GPL(gmap_discard); |
513 | 621 | ||
514 | void gmap_unmap_notifier(struct mm_struct *mm, unsigned long *table) | ||
515 | { | ||
516 | struct gmap_rmap *rmap, *next; | ||
517 | struct gmap_pgtable *mp; | ||
518 | struct page *page; | ||
519 | int flush; | ||
520 | |||
521 | flush = 0; | ||
522 | spin_lock(&mm->page_table_lock); | ||
523 | page = pfn_to_page(__pa(table) >> PAGE_SHIFT); | ||
524 | mp = (struct gmap_pgtable *) page->index; | ||
525 | list_for_each_entry_safe(rmap, next, &mp->mapper, list) { | ||
526 | *rmap->entry = | ||
527 | _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO | mp->vmaddr; | ||
528 | list_del(&rmap->list); | ||
529 | kfree(rmap); | ||
530 | flush = 1; | ||
531 | } | ||
532 | spin_unlock(&mm->page_table_lock); | ||
533 | if (flush) | ||
534 | __tlb_flush_global(); | ||
535 | } | ||
536 | |||
537 | static inline unsigned long *page_table_alloc_pgste(struct mm_struct *mm, | 622 | static inline unsigned long *page_table_alloc_pgste(struct mm_struct *mm, |
538 | unsigned long vmaddr) | 623 | unsigned long vmaddr) |
539 | { | 624 | { |
@@ -586,8 +671,8 @@ static inline void page_table_free_pgste(unsigned long *table) | |||
586 | { | 671 | { |
587 | } | 672 | } |
588 | 673 | ||
589 | static inline void gmap_unmap_notifier(struct mm_struct *mm, | 674 | static inline void gmap_disconnect_pgtable(struct mm_struct *mm, |
590 | unsigned long *table) | 675 | unsigned long *table) |
591 | { | 676 | { |
592 | } | 677 | } |
593 | 678 | ||
@@ -653,7 +738,7 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) | |||
653 | unsigned int bit, mask; | 738 | unsigned int bit, mask; |
654 | 739 | ||
655 | if (mm_has_pgste(mm)) { | 740 | if (mm_has_pgste(mm)) { |
656 | gmap_unmap_notifier(mm, table); | 741 | gmap_disconnect_pgtable(mm, table); |
657 | return page_table_free_pgste(table); | 742 | return page_table_free_pgste(table); |
658 | } | 743 | } |
659 | /* Free 1K/2K page table fragment of a 4K page */ | 744 | /* Free 1K/2K page table fragment of a 4K page */ |
@@ -696,7 +781,7 @@ void page_table_free_rcu(struct mmu_gather *tlb, unsigned long *table) | |||
696 | 781 | ||
697 | mm = tlb->mm; | 782 | mm = tlb->mm; |
698 | if (mm_has_pgste(mm)) { | 783 | if (mm_has_pgste(mm)) { |
699 | gmap_unmap_notifier(mm, table); | 784 | gmap_disconnect_pgtable(mm, table); |
700 | table = (unsigned long *) (__pa(table) | FRAG_MASK); | 785 | table = (unsigned long *) (__pa(table) | FRAG_MASK); |
701 | tlb_remove_table(tlb, table); | 786 | tlb_remove_table(tlb, table); |
702 | return; | 787 | return; |
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index ffab84db6907..35837054f734 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c | |||
@@ -191,19 +191,16 @@ static void vmem_remove_range(unsigned long start, unsigned long size) | |||
191 | /* | 191 | /* |
192 | * Add a backed mem_map array to the virtual mem_map array. | 192 | * Add a backed mem_map array to the virtual mem_map array. |
193 | */ | 193 | */ |
194 | int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node) | 194 | int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) |
195 | { | 195 | { |
196 | unsigned long address, start_addr, end_addr; | 196 | unsigned long address = start; |
197 | pgd_t *pg_dir; | 197 | pgd_t *pg_dir; |
198 | pud_t *pu_dir; | 198 | pud_t *pu_dir; |
199 | pmd_t *pm_dir; | 199 | pmd_t *pm_dir; |
200 | pte_t *pt_dir; | 200 | pte_t *pt_dir; |
201 | int ret = -ENOMEM; | 201 | int ret = -ENOMEM; |
202 | 202 | ||
203 | start_addr = (unsigned long) start; | 203 | for (address = start; address < end;) { |
204 | end_addr = (unsigned long) (start + nr); | ||
205 | |||
206 | for (address = start_addr; address < end_addr;) { | ||
207 | pg_dir = pgd_offset_k(address); | 204 | pg_dir = pgd_offset_k(address); |
208 | if (pgd_none(*pg_dir)) { | 205 | if (pgd_none(*pg_dir)) { |
209 | pu_dir = vmem_pud_alloc(); | 206 | pu_dir = vmem_pud_alloc(); |
@@ -262,14 +259,14 @@ int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node) | |||
262 | } | 259 | } |
263 | address += PAGE_SIZE; | 260 | address += PAGE_SIZE; |
264 | } | 261 | } |
265 | memset(start, 0, nr * sizeof(struct page)); | 262 | memset((void *)start, 0, end - start); |
266 | ret = 0; | 263 | ret = 0; |
267 | out: | 264 | out: |
268 | flush_tlb_kernel_range(start_addr, end_addr); | 265 | flush_tlb_kernel_range(start, end); |
269 | return ret; | 266 | return ret; |
270 | } | 267 | } |
271 | 268 | ||
272 | void vmemmap_free(struct page *memmap, unsigned long nr_pages) | 269 | void vmemmap_free(unsigned long start, unsigned long end) |
273 | { | 270 | { |
274 | } | 271 | } |
275 | 272 | ||
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 0972e91cced2..82f165f8078c 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c | |||
@@ -747,10 +747,9 @@ void bpf_jit_compile(struct sk_filter *fp) | |||
747 | 747 | ||
748 | if (!bpf_jit_enable) | 748 | if (!bpf_jit_enable) |
749 | return; | 749 | return; |
750 | addrs = kmalloc(fp->len * sizeof(*addrs), GFP_KERNEL); | 750 | addrs = kcalloc(fp->len, sizeof(*addrs), GFP_KERNEL); |
751 | if (addrs == NULL) | 751 | if (addrs == NULL) |
752 | return; | 752 | return; |
753 | memset(addrs, 0, fp->len * sizeof(*addrs)); | ||
754 | memset(&jit, 0, sizeof(cjit)); | 753 | memset(&jit, 0, sizeof(cjit)); |
755 | memset(&cjit, 0, sizeof(cjit)); | 754 | memset(&cjit, 0, sizeof(cjit)); |
756 | 755 | ||
diff --git a/arch/s390/oprofile/init.c b/arch/s390/oprofile/init.c index 584b93674ea4..ffeb17ce7f31 100644 --- a/arch/s390/oprofile/init.c +++ b/arch/s390/oprofile/init.c | |||
@@ -440,6 +440,7 @@ static int oprofile_hwsampler_init(struct oprofile_operations *ops) | |||
440 | switch (id.machine) { | 440 | switch (id.machine) { |
441 | case 0x2097: case 0x2098: ops->cpu_type = "s390/z10"; break; | 441 | case 0x2097: case 0x2098: ops->cpu_type = "s390/z10"; break; |
442 | case 0x2817: case 0x2818: ops->cpu_type = "s390/z196"; break; | 442 | case 0x2817: case 0x2818: ops->cpu_type = "s390/z196"; break; |
443 | case 0x2827: ops->cpu_type = "s390/zEC12"; break; | ||
443 | default: return -ENODEV; | 444 | default: return -ENODEV; |
444 | } | 445 | } |
445 | } | 446 | } |
diff --git a/arch/s390/pci/Makefile b/arch/s390/pci/Makefile index f0f426a113ce..086a2e37935d 100644 --- a/arch/s390/pci/Makefile +++ b/arch/s390/pci/Makefile | |||
@@ -2,5 +2,5 @@ | |||
2 | # Makefile for the s390 PCI subsystem. | 2 | # Makefile for the s390 PCI subsystem. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_PCI) += pci.o pci_dma.o pci_clp.o pci_msi.o \ | 5 | obj-$(CONFIG_PCI) += pci.o pci_dma.o pci_clp.o pci_msi.o pci_sysfs.o \ |
6 | pci_sysfs.o pci_event.o pci_debug.o | 6 | pci_event.o pci_debug.o pci_insn.o |
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 27b4c17855b9..e6f15b5d8b7d 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c | |||
@@ -99,9 +99,6 @@ static int __read_mostly aisb_max; | |||
99 | static struct kmem_cache *zdev_irq_cache; | 99 | static struct kmem_cache *zdev_irq_cache; |
100 | static struct kmem_cache *zdev_fmb_cache; | 100 | static struct kmem_cache *zdev_fmb_cache; |
101 | 101 | ||
102 | debug_info_t *pci_debug_msg_id; | ||
103 | debug_info_t *pci_debug_err_id; | ||
104 | |||
105 | static inline int irq_to_msi_nr(unsigned int irq) | 102 | static inline int irq_to_msi_nr(unsigned int irq) |
106 | { | 103 | { |
107 | return irq & ZPCI_MSI_MASK; | 104 | return irq & ZPCI_MSI_MASK; |
@@ -179,7 +176,7 @@ static int zpci_register_airq(struct zpci_dev *zdev, unsigned int aisb, | |||
179 | fib->aisb = (u64) bucket->aisb + aisb / 8; | 176 | fib->aisb = (u64) bucket->aisb + aisb / 8; |
180 | fib->aisbo = aisb & ZPCI_MSI_MASK; | 177 | fib->aisbo = aisb & ZPCI_MSI_MASK; |
181 | 178 | ||
182 | rc = mpcifc_instr(req, fib); | 179 | rc = s390pci_mod_fc(req, fib); |
183 | pr_debug("%s mpcifc returned noi: %d\n", __func__, fib->noi); | 180 | pr_debug("%s mpcifc returned noi: %d\n", __func__, fib->noi); |
184 | 181 | ||
185 | free_page((unsigned long) fib); | 182 | free_page((unsigned long) fib); |
@@ -209,7 +206,7 @@ static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args | |||
209 | fib->iota = args->iota; | 206 | fib->iota = args->iota; |
210 | fib->fmb_addr = args->fmb_addr; | 207 | fib->fmb_addr = args->fmb_addr; |
211 | 208 | ||
212 | rc = mpcifc_instr(req, fib); | 209 | rc = s390pci_mod_fc(req, fib); |
213 | free_page((unsigned long) fib); | 210 | free_page((unsigned long) fib); |
214 | return rc; | 211 | return rc; |
215 | } | 212 | } |
@@ -249,10 +246,9 @@ int zpci_fmb_enable_device(struct zpci_dev *zdev) | |||
249 | if (zdev->fmb) | 246 | if (zdev->fmb) |
250 | return -EINVAL; | 247 | return -EINVAL; |
251 | 248 | ||
252 | zdev->fmb = kmem_cache_alloc(zdev_fmb_cache, GFP_KERNEL); | 249 | zdev->fmb = kmem_cache_zalloc(zdev_fmb_cache, GFP_KERNEL); |
253 | if (!zdev->fmb) | 250 | if (!zdev->fmb) |
254 | return -ENOMEM; | 251 | return -ENOMEM; |
255 | memset(zdev->fmb, 0, sizeof(*zdev->fmb)); | ||
256 | WARN_ON((u64) zdev->fmb & 0xf); | 252 | WARN_ON((u64) zdev->fmb & 0xf); |
257 | 253 | ||
258 | args.fmb_addr = virt_to_phys(zdev->fmb); | 254 | args.fmb_addr = virt_to_phys(zdev->fmb); |
@@ -284,12 +280,12 @@ static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len) | |||
284 | u64 data; | 280 | u64 data; |
285 | int rc; | 281 | int rc; |
286 | 282 | ||
287 | rc = pcilg_instr(&data, req, offset); | 283 | rc = s390pci_load(&data, req, offset); |
288 | data = data << ((8 - len) * 8); | 284 | if (!rc) { |
289 | data = le64_to_cpu(data); | 285 | data = data << ((8 - len) * 8); |
290 | if (!rc) | 286 | data = le64_to_cpu(data); |
291 | *val = (u32) data; | 287 | *val = (u32) data; |
292 | else | 288 | } else |
293 | *val = 0xffffffff; | 289 | *val = 0xffffffff; |
294 | return rc; | 290 | return rc; |
295 | } | 291 | } |
@@ -302,7 +298,7 @@ static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len) | |||
302 | 298 | ||
303 | data = cpu_to_le64(data); | 299 | data = cpu_to_le64(data); |
304 | data = data >> ((8 - len) * 8); | 300 | data = data >> ((8 - len) * 8); |
305 | rc = pcistg_instr(data, req, offset); | 301 | rc = s390pci_store(data, req, offset); |
306 | return rc; | 302 | return rc; |
307 | } | 303 | } |
308 | 304 | ||
@@ -409,20 +405,28 @@ static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, | |||
409 | int size, u32 *val) | 405 | int size, u32 *val) |
410 | { | 406 | { |
411 | struct zpci_dev *zdev = get_zdev_by_bus(bus); | 407 | struct zpci_dev *zdev = get_zdev_by_bus(bus); |
408 | int ret; | ||
412 | 409 | ||
413 | if (!zdev || devfn != ZPCI_DEVFN) | 410 | if (!zdev || devfn != ZPCI_DEVFN) |
414 | return 0; | 411 | ret = -ENODEV; |
415 | return zpci_cfg_load(zdev, where, val, size); | 412 | else |
413 | ret = zpci_cfg_load(zdev, where, val, size); | ||
414 | |||
415 | return ret; | ||
416 | } | 416 | } |
417 | 417 | ||
418 | static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, | 418 | static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, |
419 | int size, u32 val) | 419 | int size, u32 val) |
420 | { | 420 | { |
421 | struct zpci_dev *zdev = get_zdev_by_bus(bus); | 421 | struct zpci_dev *zdev = get_zdev_by_bus(bus); |
422 | int ret; | ||
422 | 423 | ||
423 | if (!zdev || devfn != ZPCI_DEVFN) | 424 | if (!zdev || devfn != ZPCI_DEVFN) |
424 | return 0; | 425 | ret = -ENODEV; |
425 | return zpci_cfg_store(zdev, where, val, size); | 426 | else |
427 | ret = zpci_cfg_store(zdev, where, val, size); | ||
428 | |||
429 | return ret; | ||
426 | } | 430 | } |
427 | 431 | ||
428 | static struct pci_ops pci_root_ops = { | 432 | static struct pci_ops pci_root_ops = { |
@@ -474,7 +478,7 @@ scan: | |||
474 | } | 478 | } |
475 | 479 | ||
476 | /* enable interrupts again */ | 480 | /* enable interrupts again */ |
477 | sic_instr(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); | 481 | set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); |
478 | 482 | ||
479 | /* check again to not lose initiative */ | 483 | /* check again to not lose initiative */ |
480 | rmb(); | 484 | rmb(); |
@@ -596,19 +600,6 @@ static void zpci_map_resources(struct zpci_dev *zdev) | |||
596 | } | 600 | } |
597 | }; | 601 | }; |
598 | 602 | ||
599 | static void zpci_unmap_resources(struct pci_dev *pdev) | ||
600 | { | ||
601 | resource_size_t len; | ||
602 | int i; | ||
603 | |||
604 | for (i = 0; i < PCI_BAR_COUNT; i++) { | ||
605 | len = pci_resource_len(pdev, i); | ||
606 | if (!len) | ||
607 | continue; | ||
608 | pci_iounmap(pdev, (void *) pdev->resource[i].start); | ||
609 | } | ||
610 | }; | ||
611 | |||
612 | struct zpci_dev *zpci_alloc_device(void) | 603 | struct zpci_dev *zpci_alloc_device(void) |
613 | { | 604 | { |
614 | struct zpci_dev *zdev; | 605 | struct zpci_dev *zdev; |
@@ -636,32 +627,6 @@ void zpci_free_device(struct zpci_dev *zdev) | |||
636 | kfree(zdev); | 627 | kfree(zdev); |
637 | } | 628 | } |
638 | 629 | ||
639 | /* Called on removal of pci_dev, leaves zpci and bus device */ | ||
640 | static void zpci_remove_device(struct pci_dev *pdev) | ||
641 | { | ||
642 | struct zpci_dev *zdev = get_zdev(pdev); | ||
643 | |||
644 | dev_info(&pdev->dev, "Removing device %u\n", zdev->domain); | ||
645 | zdev->state = ZPCI_FN_STATE_CONFIGURED; | ||
646 | zpci_dma_exit_device(zdev); | ||
647 | zpci_fmb_disable_device(zdev); | ||
648 | zpci_sysfs_remove_device(&pdev->dev); | ||
649 | zpci_unmap_resources(pdev); | ||
650 | list_del(&zdev->entry); /* can be called from init */ | ||
651 | zdev->pdev = NULL; | ||
652 | } | ||
653 | |||
654 | static void zpci_scan_devices(void) | ||
655 | { | ||
656 | struct zpci_dev *zdev; | ||
657 | |||
658 | mutex_lock(&zpci_list_lock); | ||
659 | list_for_each_entry(zdev, &zpci_list, entry) | ||
660 | if (zdev->state == ZPCI_FN_STATE_CONFIGURED) | ||
661 | zpci_scan_device(zdev); | ||
662 | mutex_unlock(&zpci_list_lock); | ||
663 | } | ||
664 | |||
665 | /* | 630 | /* |
666 | * Too late for any s390 specific setup, since interrupts must be set up | 631 | * Too late for any s390 specific setup, since interrupts must be set up |
667 | * already which requires DMA setup too and the pci scan will access the | 632 | * already which requires DMA setup too and the pci scan will access the |
@@ -688,12 +653,6 @@ int pcibios_enable_device(struct pci_dev *pdev, int mask) | |||
688 | return 0; | 653 | return 0; |
689 | } | 654 | } |
690 | 655 | ||
691 | void pcibios_disable_device(struct pci_dev *pdev) | ||
692 | { | ||
693 | zpci_remove_device(pdev); | ||
694 | pdev->sysdata = NULL; | ||
695 | } | ||
696 | |||
697 | int pcibios_add_platform_entries(struct pci_dev *pdev) | 656 | int pcibios_add_platform_entries(struct pci_dev *pdev) |
698 | { | 657 | { |
699 | return zpci_sysfs_add_device(&pdev->dev); | 658 | return zpci_sysfs_add_device(&pdev->dev); |
@@ -789,7 +748,7 @@ static int __init zpci_irq_init(void) | |||
789 | spin_lock_init(&bucket->lock); | 748 | spin_lock_init(&bucket->lock); |
790 | /* set summary to 1 to be called every time for the ISC */ | 749 | /* set summary to 1 to be called every time for the ISC */ |
791 | *zpci_irq_si = 1; | 750 | *zpci_irq_si = 1; |
792 | sic_instr(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); | 751 | set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); |
793 | return 0; | 752 | return 0; |
794 | 753 | ||
795 | out_ai: | 754 | out_ai: |
@@ -872,7 +831,19 @@ static void zpci_free_iomap(struct zpci_dev *zdev, int entry) | |||
872 | spin_unlock(&zpci_iomap_lock); | 831 | spin_unlock(&zpci_iomap_lock); |
873 | } | 832 | } |
874 | 833 | ||
875 | static int zpci_create_device_bus(struct zpci_dev *zdev) | 834 | int pcibios_add_device(struct pci_dev *pdev) |
835 | { | ||
836 | struct zpci_dev *zdev = get_zdev(pdev); | ||
837 | |||
838 | zdev->pdev = pdev; | ||
839 | zpci_debug_init_device(zdev); | ||
840 | zpci_fmb_enable_device(zdev); | ||
841 | zpci_map_resources(zdev); | ||
842 | |||
843 | return 0; | ||
844 | } | ||
845 | |||
846 | static int zpci_scan_bus(struct zpci_dev *zdev) | ||
876 | { | 847 | { |
877 | struct resource *res; | 848 | struct resource *res; |
878 | LIST_HEAD(resources); | 849 | LIST_HEAD(resources); |
@@ -909,8 +880,8 @@ static int zpci_create_device_bus(struct zpci_dev *zdev) | |||
909 | pci_add_resource(&resources, res); | 880 | pci_add_resource(&resources, res); |
910 | } | 881 | } |
911 | 882 | ||
912 | zdev->bus = pci_create_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops, | 883 | zdev->bus = pci_scan_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops, |
913 | zdev, &resources); | 884 | zdev, &resources); |
914 | if (!zdev->bus) | 885 | if (!zdev->bus) |
915 | return -EIO; | 886 | return -EIO; |
916 | 887 | ||
@@ -959,6 +930,13 @@ out: | |||
959 | } | 930 | } |
960 | EXPORT_SYMBOL_GPL(zpci_enable_device); | 931 | EXPORT_SYMBOL_GPL(zpci_enable_device); |
961 | 932 | ||
933 | int zpci_disable_device(struct zpci_dev *zdev) | ||
934 | { | ||
935 | zpci_dma_exit_device(zdev); | ||
936 | return clp_disable_fh(zdev); | ||
937 | } | ||
938 | EXPORT_SYMBOL_GPL(zpci_disable_device); | ||
939 | |||
962 | int zpci_create_device(struct zpci_dev *zdev) | 940 | int zpci_create_device(struct zpci_dev *zdev) |
963 | { | 941 | { |
964 | int rc; | 942 | int rc; |
@@ -967,9 +945,16 @@ int zpci_create_device(struct zpci_dev *zdev) | |||
967 | if (rc) | 945 | if (rc) |
968 | goto out; | 946 | goto out; |
969 | 947 | ||
970 | rc = zpci_create_device_bus(zdev); | 948 | if (zdev->state == ZPCI_FN_STATE_CONFIGURED) { |
949 | rc = zpci_enable_device(zdev); | ||
950 | if (rc) | ||
951 | goto out_free; | ||
952 | |||
953 | zdev->state = ZPCI_FN_STATE_ONLINE; | ||
954 | } | ||
955 | rc = zpci_scan_bus(zdev); | ||
971 | if (rc) | 956 | if (rc) |
972 | goto out_bus; | 957 | goto out_disable; |
973 | 958 | ||
974 | mutex_lock(&zpci_list_lock); | 959 | mutex_lock(&zpci_list_lock); |
975 | list_add_tail(&zdev->entry, &zpci_list); | 960 | list_add_tail(&zdev->entry, &zpci_list); |
@@ -977,21 +962,12 @@ int zpci_create_device(struct zpci_dev *zdev) | |||
977 | hotplug_ops->create_slot(zdev); | 962 | hotplug_ops->create_slot(zdev); |
978 | mutex_unlock(&zpci_list_lock); | 963 | mutex_unlock(&zpci_list_lock); |
979 | 964 | ||
980 | if (zdev->state == ZPCI_FN_STATE_STANDBY) | ||
981 | return 0; | ||
982 | |||
983 | rc = zpci_enable_device(zdev); | ||
984 | if (rc) | ||
985 | goto out_start; | ||
986 | return 0; | 965 | return 0; |
987 | 966 | ||
988 | out_start: | 967 | out_disable: |
989 | mutex_lock(&zpci_list_lock); | 968 | if (zdev->state == ZPCI_FN_STATE_ONLINE) |
990 | list_del(&zdev->entry); | 969 | zpci_disable_device(zdev); |
991 | if (hotplug_ops) | 970 | out_free: |
992 | hotplug_ops->remove_slot(zdev); | ||
993 | mutex_unlock(&zpci_list_lock); | ||
994 | out_bus: | ||
995 | zpci_free_domain(zdev); | 971 | zpci_free_domain(zdev); |
996 | out: | 972 | out: |
997 | return rc; | 973 | return rc; |
@@ -1016,15 +992,9 @@ int zpci_scan_device(struct zpci_dev *zdev) | |||
1016 | goto out; | 992 | goto out; |
1017 | } | 993 | } |
1018 | 994 | ||
1019 | zpci_debug_init_device(zdev); | ||
1020 | zpci_fmb_enable_device(zdev); | ||
1021 | zpci_map_resources(zdev); | ||
1022 | pci_bus_add_devices(zdev->bus); | 995 | pci_bus_add_devices(zdev->bus); |
1023 | 996 | ||
1024 | /* now that pdev was added to the bus mark it as used */ | ||
1025 | zdev->state = ZPCI_FN_STATE_ONLINE; | ||
1026 | return 0; | 997 | return 0; |
1027 | |||
1028 | out: | 998 | out: |
1029 | zpci_dma_exit_device(zdev); | 999 | zpci_dma_exit_device(zdev); |
1030 | clp_disable_fh(zdev); | 1000 | clp_disable_fh(zdev); |
@@ -1087,13 +1057,13 @@ void zpci_deregister_hp_ops(void) | |||
1087 | } | 1057 | } |
1088 | EXPORT_SYMBOL_GPL(zpci_deregister_hp_ops); | 1058 | EXPORT_SYMBOL_GPL(zpci_deregister_hp_ops); |
1089 | 1059 | ||
1090 | unsigned int s390_pci_probe = 1; | 1060 | unsigned int s390_pci_probe; |
1091 | EXPORT_SYMBOL_GPL(s390_pci_probe); | 1061 | EXPORT_SYMBOL_GPL(s390_pci_probe); |
1092 | 1062 | ||
1093 | char * __init pcibios_setup(char *str) | 1063 | char * __init pcibios_setup(char *str) |
1094 | { | 1064 | { |
1095 | if (!strcmp(str, "off")) { | 1065 | if (!strcmp(str, "on")) { |
1096 | s390_pci_probe = 0; | 1066 | s390_pci_probe = 1; |
1097 | return NULL; | 1067 | return NULL; |
1098 | } | 1068 | } |
1099 | return str; | 1069 | return str; |
@@ -1138,7 +1108,6 @@ static int __init pci_base_init(void) | |||
1138 | if (rc) | 1108 | if (rc) |
1139 | goto out_find; | 1109 | goto out_find; |
1140 | 1110 | ||
1141 | zpci_scan_devices(); | ||
1142 | return 0; | 1111 | return 0; |
1143 | 1112 | ||
1144 | out_find: | 1113 | out_find: |
diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c index f339fe2feb15..bd34359d1546 100644 --- a/arch/s390/pci/pci_clp.c +++ b/arch/s390/pci/pci_clp.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/err.h> | 13 | #include <linux/err.h> |
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <linux/pci.h> | 15 | #include <linux/pci.h> |
16 | #include <asm/pci_debug.h> | ||
16 | #include <asm/pci_clp.h> | 17 | #include <asm/pci_clp.h> |
17 | 18 | ||
18 | /* | 19 | /* |
@@ -144,6 +145,7 @@ int clp_add_pci_device(u32 fid, u32 fh, int configured) | |||
144 | struct zpci_dev *zdev; | 145 | struct zpci_dev *zdev; |
145 | int rc; | 146 | int rc; |
146 | 147 | ||
148 | zpci_dbg(3, "add fid:%x, fh:%x, c:%d\n", fid, fh, configured); | ||
147 | zdev = zpci_alloc_device(); | 149 | zdev = zpci_alloc_device(); |
148 | if (IS_ERR(zdev)) | 150 | if (IS_ERR(zdev)) |
149 | return PTR_ERR(zdev); | 151 | return PTR_ERR(zdev); |
@@ -204,8 +206,8 @@ static int clp_set_pci_fn(u32 *fh, u8 nr_dma_as, u8 command) | |||
204 | if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) | 206 | if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) |
205 | *fh = rrb->response.fh; | 207 | *fh = rrb->response.fh; |
206 | else { | 208 | else { |
207 | pr_err("Set PCI FN failed with response: %x cc: %d\n", | 209 | zpci_dbg(0, "SPF fh:%x, cc:%d, resp:%x\n", *fh, rc, |
208 | rrb->response.hdr.rsp, rc); | 210 | rrb->response.hdr.rsp); |
209 | rc = -EIO; | 211 | rc = -EIO; |
210 | } | 212 | } |
211 | clp_free_block(rrb); | 213 | clp_free_block(rrb); |
@@ -221,6 +223,8 @@ int clp_enable_fh(struct zpci_dev *zdev, u8 nr_dma_as) | |||
221 | if (!rc) | 223 | if (!rc) |
222 | /* Success -> store enabled handle in zdev */ | 224 | /* Success -> store enabled handle in zdev */ |
223 | zdev->fh = fh; | 225 | zdev->fh = fh; |
226 | |||
227 | zpci_dbg(3, "ena fid:%x, fh:%x, rc:%d\n", zdev->fid, zdev->fh, rc); | ||
224 | return rc; | 228 | return rc; |
225 | } | 229 | } |
226 | 230 | ||
@@ -237,9 +241,8 @@ int clp_disable_fh(struct zpci_dev *zdev) | |||
237 | if (!rc) | 241 | if (!rc) |
238 | /* Success -> store disabled handle in zdev */ | 242 | /* Success -> store disabled handle in zdev */ |
239 | zdev->fh = fh; | 243 | zdev->fh = fh; |
240 | else | 244 | |
241 | dev_err(&zdev->pdev->dev, | 245 | zpci_dbg(3, "dis fid:%x, fh:%x, rc:%d\n", zdev->fid, zdev->fh, rc); |
242 | "Failed to disable fn handle: 0x%x\n", fh); | ||
243 | return rc; | 246 | return rc; |
244 | } | 247 | } |
245 | 248 | ||
diff --git a/arch/s390/pci/pci_debug.c b/arch/s390/pci/pci_debug.c index a5d07bc2a547..771b82359af4 100644 --- a/arch/s390/pci/pci_debug.c +++ b/arch/s390/pci/pci_debug.c | |||
@@ -11,12 +11,17 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/seq_file.h> | 12 | #include <linux/seq_file.h> |
13 | #include <linux/debugfs.h> | 13 | #include <linux/debugfs.h> |
14 | #include <linux/export.h> | ||
14 | #include <linux/pci.h> | 15 | #include <linux/pci.h> |
15 | #include <asm/debug.h> | 16 | #include <asm/debug.h> |
16 | 17 | ||
17 | #include <asm/pci_dma.h> | 18 | #include <asm/pci_dma.h> |
18 | 19 | ||
19 | static struct dentry *debugfs_root; | 20 | static struct dentry *debugfs_root; |
21 | debug_info_t *pci_debug_msg_id; | ||
22 | EXPORT_SYMBOL_GPL(pci_debug_msg_id); | ||
23 | debug_info_t *pci_debug_err_id; | ||
24 | EXPORT_SYMBOL_GPL(pci_debug_err_id); | ||
20 | 25 | ||
21 | static char *pci_perf_names[] = { | 26 | static char *pci_perf_names[] = { |
22 | /* hardware counters */ | 27 | /* hardware counters */ |
@@ -168,7 +173,6 @@ int __init zpci_debug_init(void) | |||
168 | return -EINVAL; | 173 | return -EINVAL; |
169 | debug_register_view(pci_debug_msg_id, &debug_sprintf_view); | 174 | debug_register_view(pci_debug_msg_id, &debug_sprintf_view); |
170 | debug_set_level(pci_debug_msg_id, 3); | 175 | debug_set_level(pci_debug_msg_id, 3); |
171 | zpci_dbg("Debug view initialized\n"); | ||
172 | 176 | ||
173 | /* error log */ | 177 | /* error log */ |
174 | pci_debug_err_id = debug_register("pci_error", 2, 1, 16); | 178 | pci_debug_err_id = debug_register("pci_error", 2, 1, 16); |
@@ -176,7 +180,6 @@ int __init zpci_debug_init(void) | |||
176 | return -EINVAL; | 180 | return -EINVAL; |
177 | debug_register_view(pci_debug_err_id, &debug_hex_ascii_view); | 181 | debug_register_view(pci_debug_err_id, &debug_hex_ascii_view); |
178 | debug_set_level(pci_debug_err_id, 6); | 182 | debug_set_level(pci_debug_err_id, 6); |
179 | zpci_err("Debug view initialized\n"); | ||
180 | 183 | ||
181 | debugfs_root = debugfs_create_dir("pci", NULL); | 184 | debugfs_root = debugfs_create_dir("pci", NULL); |
182 | return 0; | 185 | return 0; |
diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c index a547419907c3..f8e69d5bc0a9 100644 --- a/arch/s390/pci/pci_dma.c +++ b/arch/s390/pci/pci_dma.c | |||
@@ -169,8 +169,9 @@ static int dma_update_trans(struct zpci_dev *zdev, unsigned long pa, | |||
169 | * needs to be redone! | 169 | * needs to be redone! |
170 | */ | 170 | */ |
171 | goto no_refresh; | 171 | goto no_refresh; |
172 | rc = rpcit_instr((u64) zdev->fh << 32, start_dma_addr, | 172 | |
173 | nr_pages * PAGE_SIZE); | 173 | rc = s390pci_refresh_trans((u64) zdev->fh << 32, start_dma_addr, |
174 | nr_pages * PAGE_SIZE); | ||
174 | 175 | ||
175 | no_refresh: | 176 | no_refresh: |
176 | spin_unlock_irqrestore(&zdev->dma_table_lock, irq_flags); | 177 | spin_unlock_irqrestore(&zdev->dma_table_lock, irq_flags); |
@@ -268,8 +269,6 @@ static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page, | |||
268 | int flags = ZPCI_PTE_VALID; | 269 | int flags = ZPCI_PTE_VALID; |
269 | dma_addr_t dma_addr; | 270 | dma_addr_t dma_addr; |
270 | 271 | ||
271 | WARN_ON_ONCE(offset > PAGE_SIZE); | ||
272 | |||
273 | /* This rounds up number of pages based on size and offset */ | 272 | /* This rounds up number of pages based on size and offset */ |
274 | nr_pages = iommu_num_pages(pa, size, PAGE_SIZE); | 273 | nr_pages = iommu_num_pages(pa, size, PAGE_SIZE); |
275 | iommu_page_index = dma_alloc_iommu(zdev, nr_pages); | 274 | iommu_page_index = dma_alloc_iommu(zdev, nr_pages); |
@@ -291,7 +290,7 @@ static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page, | |||
291 | 290 | ||
292 | if (!dma_update_trans(zdev, pa, dma_addr, size, flags)) { | 291 | if (!dma_update_trans(zdev, pa, dma_addr, size, flags)) { |
293 | atomic64_add(nr_pages, (atomic64_t *) &zdev->fmb->mapped_pages); | 292 | atomic64_add(nr_pages, (atomic64_t *) &zdev->fmb->mapped_pages); |
294 | return dma_addr + offset; | 293 | return dma_addr + (offset & ~PAGE_MASK); |
295 | } | 294 | } |
296 | 295 | ||
297 | out_free: | 296 | out_free: |
diff --git a/arch/s390/pci/pci_insn.c b/arch/s390/pci/pci_insn.c new file mode 100644 index 000000000000..22eeb9d7ffeb --- /dev/null +++ b/arch/s390/pci/pci_insn.c | |||
@@ -0,0 +1,202 @@ | |||
1 | /* | ||
2 | * s390 specific pci instructions | ||
3 | * | ||
4 | * Copyright IBM Corp. 2013 | ||
5 | */ | ||
6 | |||
7 | #include <linux/export.h> | ||
8 | #include <linux/errno.h> | ||
9 | #include <linux/delay.h> | ||
10 | #include <asm/pci_insn.h> | ||
11 | #include <asm/processor.h> | ||
12 | |||
13 | #define ZPCI_INSN_BUSY_DELAY 1 /* 1 microsecond */ | ||
14 | |||
15 | /* Modify PCI Function Controls */ | ||
16 | static inline u8 __mpcifc(u64 req, struct zpci_fib *fib, u8 *status) | ||
17 | { | ||
18 | u8 cc; | ||
19 | |||
20 | asm volatile ( | ||
21 | " .insn rxy,0xe300000000d0,%[req],%[fib]\n" | ||
22 | " ipm %[cc]\n" | ||
23 | " srl %[cc],28\n" | ||
24 | : [cc] "=d" (cc), [req] "+d" (req), [fib] "+Q" (*fib) | ||
25 | : : "cc"); | ||
26 | *status = req >> 24 & 0xff; | ||
27 | return cc; | ||
28 | } | ||
29 | |||
30 | int s390pci_mod_fc(u64 req, struct zpci_fib *fib) | ||
31 | { | ||
32 | u8 cc, status; | ||
33 | |||
34 | do { | ||
35 | cc = __mpcifc(req, fib, &status); | ||
36 | if (cc == 2) | ||
37 | msleep(ZPCI_INSN_BUSY_DELAY); | ||
38 | } while (cc == 2); | ||
39 | |||
40 | if (cc) | ||
41 | printk_once(KERN_ERR "%s: error cc: %d status: %d\n", | ||
42 | __func__, cc, status); | ||
43 | return (cc) ? -EIO : 0; | ||
44 | } | ||
45 | |||
46 | /* Refresh PCI Translations */ | ||
47 | static inline u8 __rpcit(u64 fn, u64 addr, u64 range, u8 *status) | ||
48 | { | ||
49 | register u64 __addr asm("2") = addr; | ||
50 | register u64 __range asm("3") = range; | ||
51 | u8 cc; | ||
52 | |||
53 | asm volatile ( | ||
54 | " .insn rre,0xb9d30000,%[fn],%[addr]\n" | ||
55 | " ipm %[cc]\n" | ||
56 | " srl %[cc],28\n" | ||
57 | : [cc] "=d" (cc), [fn] "+d" (fn) | ||
58 | : [addr] "d" (__addr), "d" (__range) | ||
59 | : "cc"); | ||
60 | *status = fn >> 24 & 0xff; | ||
61 | return cc; | ||
62 | } | ||
63 | |||
64 | int s390pci_refresh_trans(u64 fn, u64 addr, u64 range) | ||
65 | { | ||
66 | u8 cc, status; | ||
67 | |||
68 | do { | ||
69 | cc = __rpcit(fn, addr, range, &status); | ||
70 | if (cc == 2) | ||
71 | udelay(ZPCI_INSN_BUSY_DELAY); | ||
72 | } while (cc == 2); | ||
73 | |||
74 | if (cc) | ||
75 | printk_once(KERN_ERR "%s: error cc: %d status: %d dma_addr: %Lx size: %Lx\n", | ||
76 | __func__, cc, status, addr, range); | ||
77 | return (cc) ? -EIO : 0; | ||
78 | } | ||
79 | |||
80 | /* Set Interruption Controls */ | ||
81 | void set_irq_ctrl(u16 ctl, char *unused, u8 isc) | ||
82 | { | ||
83 | asm volatile ( | ||
84 | " .insn rsy,0xeb00000000d1,%[ctl],%[isc],%[u]\n" | ||
85 | : : [ctl] "d" (ctl), [isc] "d" (isc << 27), [u] "Q" (*unused)); | ||
86 | } | ||
87 | |||
88 | /* PCI Load */ | ||
89 | static inline int __pcilg(u64 *data, u64 req, u64 offset, u8 *status) | ||
90 | { | ||
91 | register u64 __req asm("2") = req; | ||
92 | register u64 __offset asm("3") = offset; | ||
93 | int cc = -ENXIO; | ||
94 | u64 __data; | ||
95 | |||
96 | asm volatile ( | ||
97 | " .insn rre,0xb9d20000,%[data],%[req]\n" | ||
98 | "0: ipm %[cc]\n" | ||
99 | " srl %[cc],28\n" | ||
100 | "1:\n" | ||
101 | EX_TABLE(0b, 1b) | ||
102 | : [cc] "+d" (cc), [data] "=d" (__data), [req] "+d" (__req) | ||
103 | : "d" (__offset) | ||
104 | : "cc"); | ||
105 | *status = __req >> 24 & 0xff; | ||
106 | if (!cc) | ||
107 | *data = __data; | ||
108 | |||
109 | return cc; | ||
110 | } | ||
111 | |||
112 | int s390pci_load(u64 *data, u64 req, u64 offset) | ||
113 | { | ||
114 | u8 status; | ||
115 | int cc; | ||
116 | |||
117 | do { | ||
118 | cc = __pcilg(data, req, offset, &status); | ||
119 | if (cc == 2) | ||
120 | udelay(ZPCI_INSN_BUSY_DELAY); | ||
121 | } while (cc == 2); | ||
122 | |||
123 | if (cc) | ||
124 | printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", | ||
125 | __func__, cc, status, req, offset); | ||
126 | return (cc > 0) ? -EIO : cc; | ||
127 | } | ||
128 | EXPORT_SYMBOL_GPL(s390pci_load); | ||
129 | |||
130 | /* PCI Store */ | ||
131 | static inline int __pcistg(u64 data, u64 req, u64 offset, u8 *status) | ||
132 | { | ||
133 | register u64 __req asm("2") = req; | ||
134 | register u64 __offset asm("3") = offset; | ||
135 | int cc = -ENXIO; | ||
136 | |||
137 | asm volatile ( | ||
138 | " .insn rre,0xb9d00000,%[data],%[req]\n" | ||
139 | "0: ipm %[cc]\n" | ||
140 | " srl %[cc],28\n" | ||
141 | "1:\n" | ||
142 | EX_TABLE(0b, 1b) | ||
143 | : [cc] "+d" (cc), [req] "+d" (__req) | ||
144 | : "d" (__offset), [data] "d" (data) | ||
145 | : "cc"); | ||
146 | *status = __req >> 24 & 0xff; | ||
147 | return cc; | ||
148 | } | ||
149 | |||
150 | int s390pci_store(u64 data, u64 req, u64 offset) | ||
151 | { | ||
152 | u8 status; | ||
153 | int cc; | ||
154 | |||
155 | do { | ||
156 | cc = __pcistg(data, req, offset, &status); | ||
157 | if (cc == 2) | ||
158 | udelay(ZPCI_INSN_BUSY_DELAY); | ||
159 | } while (cc == 2); | ||
160 | |||
161 | if (cc) | ||
162 | printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", | ||
163 | __func__, cc, status, req, offset); | ||
164 | return (cc > 0) ? -EIO : cc; | ||
165 | } | ||
166 | EXPORT_SYMBOL_GPL(s390pci_store); | ||
167 | |||
168 | /* PCI Store Block */ | ||
169 | static inline int __pcistb(const u64 *data, u64 req, u64 offset, u8 *status) | ||
170 | { | ||
171 | int cc = -ENXIO; | ||
172 | |||
173 | asm volatile ( | ||
174 | " .insn rsy,0xeb00000000d0,%[req],%[offset],%[data]\n" | ||
175 | "0: ipm %[cc]\n" | ||
176 | " srl %[cc],28\n" | ||
177 | "1:\n" | ||
178 | EX_TABLE(0b, 1b) | ||
179 | : [cc] "+d" (cc), [req] "+d" (req) | ||
180 | : [offset] "d" (offset), [data] "Q" (*data) | ||
181 | : "cc"); | ||
182 | *status = req >> 24 & 0xff; | ||
183 | return cc; | ||
184 | } | ||
185 | |||
186 | int s390pci_store_block(const u64 *data, u64 req, u64 offset) | ||
187 | { | ||
188 | u8 status; | ||
189 | int cc; | ||
190 | |||
191 | do { | ||
192 | cc = __pcistb(data, req, offset, &status); | ||
193 | if (cc == 2) | ||
194 | udelay(ZPCI_INSN_BUSY_DELAY); | ||
195 | } while (cc == 2); | ||
196 | |||
197 | if (cc) | ||
198 | printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", | ||
199 | __func__, cc, status, req, offset); | ||
200 | return (cc > 0) ? -EIO : cc; | ||
201 | } | ||
202 | EXPORT_SYMBOL_GPL(s390pci_store_block); | ||
diff --git a/arch/s390/pci/pci_msi.c b/arch/s390/pci/pci_msi.c index 0297931335e1..b097aed05a9b 100644 --- a/arch/s390/pci/pci_msi.c +++ b/arch/s390/pci/pci_msi.c | |||
@@ -18,8 +18,9 @@ | |||
18 | 18 | ||
19 | /* mapping of irq numbers to msi_desc */ | 19 | /* mapping of irq numbers to msi_desc */ |
20 | static struct hlist_head *msi_hash; | 20 | static struct hlist_head *msi_hash; |
21 | static unsigned int msihash_shift = 6; | 21 | static const unsigned int msi_hash_bits = 8; |
22 | #define msi_hashfn(nr) hash_long(nr, msihash_shift) | 22 | #define MSI_HASH_BUCKETS (1U << msi_hash_bits) |
23 | #define msi_hashfn(nr) hash_long(nr, msi_hash_bits) | ||
23 | 24 | ||
24 | static DEFINE_SPINLOCK(msi_map_lock); | 25 | static DEFINE_SPINLOCK(msi_map_lock); |
25 | 26 | ||
@@ -74,6 +75,7 @@ int zpci_setup_msi_irq(struct zpci_dev *zdev, struct msi_desc *msi, | |||
74 | map->irq = nr; | 75 | map->irq = nr; |
75 | map->msi = msi; | 76 | map->msi = msi; |
76 | zdev->msi_map[nr & ZPCI_MSI_MASK] = map; | 77 | zdev->msi_map[nr & ZPCI_MSI_MASK] = map; |
78 | INIT_HLIST_NODE(&map->msi_chain); | ||
77 | 79 | ||
78 | pr_debug("%s hashing irq: %u to bucket nr: %llu\n", | 80 | pr_debug("%s hashing irq: %u to bucket nr: %llu\n", |
79 | __func__, nr, msi_hashfn(nr)); | 81 | __func__, nr, msi_hashfn(nr)); |
@@ -125,11 +127,11 @@ int __init zpci_msihash_init(void) | |||
125 | { | 127 | { |
126 | unsigned int i; | 128 | unsigned int i; |
127 | 129 | ||
128 | msi_hash = kmalloc(256 * sizeof(*msi_hash), GFP_KERNEL); | 130 | msi_hash = kmalloc(MSI_HASH_BUCKETS * sizeof(*msi_hash), GFP_KERNEL); |
129 | if (!msi_hash) | 131 | if (!msi_hash) |
130 | return -ENOMEM; | 132 | return -ENOMEM; |
131 | 133 | ||
132 | for (i = 0; i < (1U << msihash_shift); i++) | 134 | for (i = 0; i < MSI_HASH_BUCKETS; i++) |
133 | INIT_HLIST_HEAD(&msi_hash[i]); | 135 | INIT_HLIST_HEAD(&msi_hash[i]); |
134 | return 0; | 136 | return 0; |
135 | } | 137 | } |
diff --git a/arch/score/mm/init.c b/arch/score/mm/init.c index cee6bce1e30c..1592aad7dbc4 100644 --- a/arch/score/mm/init.c +++ b/arch/score/mm/init.c | |||
@@ -43,7 +43,7 @@ EXPORT_SYMBOL_GPL(empty_zero_page); | |||
43 | 43 | ||
44 | static struct kcore_list kcore_mem, kcore_vmalloc; | 44 | static struct kcore_list kcore_mem, kcore_vmalloc; |
45 | 45 | ||
46 | static unsigned long setup_zero_page(void) | 46 | static void setup_zero_page(void) |
47 | { | 47 | { |
48 | struct page *page; | 48 | struct page *page; |
49 | 49 | ||
@@ -52,9 +52,7 @@ static unsigned long setup_zero_page(void) | |||
52 | panic("Oh boy, that early out of memory?"); | 52 | panic("Oh boy, that early out of memory?"); |
53 | 53 | ||
54 | page = virt_to_page((void *) empty_zero_page); | 54 | page = virt_to_page((void *) empty_zero_page); |
55 | SetPageReserved(page); | 55 | mark_page_reserved(page); |
56 | |||
57 | return 1UL; | ||
58 | } | 56 | } |
59 | 57 | ||
60 | #ifndef CONFIG_NEED_MULTIPLE_NODES | 58 | #ifndef CONFIG_NEED_MULTIPLE_NODES |
@@ -84,7 +82,7 @@ void __init mem_init(void) | |||
84 | 82 | ||
85 | high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); | 83 | high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); |
86 | totalram_pages += free_all_bootmem(); | 84 | totalram_pages += free_all_bootmem(); |
87 | totalram_pages -= setup_zero_page(); /* Setup zeroed pages. */ | 85 | setup_zero_page(); /* Setup zeroed pages. */ |
88 | reservedpages = 0; | 86 | reservedpages = 0; |
89 | 87 | ||
90 | for (tmp = 0; tmp < max_low_pfn; tmp++) | 88 | for (tmp = 0; tmp < max_low_pfn; tmp++) |
@@ -109,37 +107,16 @@ void __init mem_init(void) | |||
109 | } | 107 | } |
110 | #endif /* !CONFIG_NEED_MULTIPLE_NODES */ | 108 | #endif /* !CONFIG_NEED_MULTIPLE_NODES */ |
111 | 109 | ||
112 | static void free_init_pages(const char *what, unsigned long begin, unsigned long end) | ||
113 | { | ||
114 | unsigned long pfn; | ||
115 | |||
116 | for (pfn = PFN_UP(begin); pfn < PFN_DOWN(end); pfn++) { | ||
117 | struct page *page = pfn_to_page(pfn); | ||
118 | void *addr = phys_to_virt(PFN_PHYS(pfn)); | ||
119 | |||
120 | ClearPageReserved(page); | ||
121 | init_page_count(page); | ||
122 | memset(addr, POISON_FREE_INITMEM, PAGE_SIZE); | ||
123 | __free_page(page); | ||
124 | totalram_pages++; | ||
125 | } | ||
126 | printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); | ||
127 | } | ||
128 | |||
129 | #ifdef CONFIG_BLK_DEV_INITRD | 110 | #ifdef CONFIG_BLK_DEV_INITRD |
130 | void free_initrd_mem(unsigned long start, unsigned long end) | 111 | void free_initrd_mem(unsigned long start, unsigned long end) |
131 | { | 112 | { |
132 | free_init_pages("initrd memory", | 113 | free_reserved_area(start, end, POISON_FREE_INITMEM, "initrd"); |
133 | virt_to_phys((void *) start), | ||
134 | virt_to_phys((void *) end)); | ||
135 | } | 114 | } |
136 | #endif | 115 | #endif |
137 | 116 | ||
138 | void __init_refok free_initmem(void) | 117 | void __init_refok free_initmem(void) |
139 | { | 118 | { |
140 | free_init_pages("unused kernel memory", | 119 | free_initmem_default(POISON_FREE_INITMEM); |
141 | __pa(&__init_begin), | ||
142 | __pa(&__init_end)); | ||
143 | } | 120 | } |
144 | 121 | ||
145 | unsigned long pgd_current; | 122 | unsigned long pgd_current; |
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index aaff7671101b..764530c85aa9 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c | |||
@@ -254,11 +254,13 @@ static int usbhs_get_id(struct platform_device *pdev) | |||
254 | return gpio_get_value(GPIO_PTB3); | 254 | return gpio_get_value(GPIO_PTB3); |
255 | } | 255 | } |
256 | 256 | ||
257 | static void usbhs_phy_reset(struct platform_device *pdev) | 257 | static int usbhs_phy_reset(struct platform_device *pdev) |
258 | { | 258 | { |
259 | /* enable vbus if HOST */ | 259 | /* enable vbus if HOST */ |
260 | if (!gpio_get_value(GPIO_PTB3)) | 260 | if (!gpio_get_value(GPIO_PTB3)) |
261 | gpio_set_value(GPIO_PTB5, 1); | 261 | gpio_set_value(GPIO_PTB5, 1); |
262 | |||
263 | return 0; | ||
262 | } | 264 | } |
263 | 265 | ||
264 | static struct renesas_usbhs_platform_info usbhs_info = { | 266 | static struct renesas_usbhs_platform_info usbhs_info = { |
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index c2c85f6cd738..a162a7f86b2e 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c | |||
@@ -35,7 +35,7 @@ static unsigned int nr_ports; | |||
35 | 35 | ||
36 | static struct sh7786_pcie_hwops { | 36 | static struct sh7786_pcie_hwops { |
37 | int (*core_init)(void); | 37 | int (*core_init)(void); |
38 | async_func_ptr *port_init_hw; | 38 | async_func_t port_init_hw; |
39 | } *sh7786_pcie_hwops; | 39 | } *sh7786_pcie_hwops; |
40 | 40 | ||
41 | static struct resource sh7786_pci0_resources[] = { | 41 | static struct resource sh7786_pci0_resources[] = { |
diff --git a/arch/sh/include/asm/hugetlb.h b/arch/sh/include/asm/hugetlb.h index b3808c7d67b2..699255d6d1c6 100644 --- a/arch/sh/include/asm/hugetlb.h +++ b/arch/sh/include/asm/hugetlb.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include <asm/cacheflush.h> | 4 | #include <asm/cacheflush.h> |
5 | #include <asm/page.h> | 5 | #include <asm/page.h> |
6 | #include <asm-generic/hugetlb.h> | ||
6 | 7 | ||
7 | 8 | ||
8 | static inline int is_hugepage_only_range(struct mm_struct *mm, | 9 | static inline int is_hugepage_only_range(struct mm_struct *mm, |
diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c index 47475cca068a..fe584e516964 100644 --- a/arch/sh/kernel/sh_bios.c +++ b/arch/sh/kernel/sh_bios.c | |||
@@ -104,6 +104,7 @@ void sh_bios_vbr_reload(void) | |||
104 | ); | 104 | ); |
105 | } | 105 | } |
106 | 106 | ||
107 | #ifdef CONFIG_EARLY_PRINTK | ||
107 | /* | 108 | /* |
108 | * Print a string through the BIOS | 109 | * Print a string through the BIOS |
109 | */ | 110 | */ |
@@ -144,8 +145,6 @@ static struct console bios_console = { | |||
144 | .index = -1, | 145 | .index = -1, |
145 | }; | 146 | }; |
146 | 147 | ||
147 | static struct console *early_console; | ||
148 | |||
149 | static int __init setup_early_printk(char *buf) | 148 | static int __init setup_early_printk(char *buf) |
150 | { | 149 | { |
151 | int keep_early = 0; | 150 | int keep_early = 0; |
@@ -170,3 +169,4 @@ static int __init setup_early_printk(char *buf) | |||
170 | return 0; | 169 | return 0; |
171 | } | 170 | } |
172 | early_param("earlyprintk", setup_early_printk); | 171 | early_param("earlyprintk", setup_early_printk); |
172 | #endif | ||
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 105794037143..20f9ead650d3 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c | |||
@@ -417,15 +417,13 @@ void __init mem_init(void) | |||
417 | 417 | ||
418 | for_each_online_node(nid) { | 418 | for_each_online_node(nid) { |
419 | pg_data_t *pgdat = NODE_DATA(nid); | 419 | pg_data_t *pgdat = NODE_DATA(nid); |
420 | unsigned long node_pages = 0; | ||
421 | void *node_high_memory; | 420 | void *node_high_memory; |
422 | 421 | ||
423 | num_physpages += pgdat->node_present_pages; | 422 | num_physpages += pgdat->node_present_pages; |
424 | 423 | ||
425 | if (pgdat->node_spanned_pages) | 424 | if (pgdat->node_spanned_pages) |
426 | node_pages = free_all_bootmem_node(pgdat); | 425 | totalram_pages += free_all_bootmem_node(pgdat); |
427 | 426 | ||
428 | totalram_pages += node_pages; | ||
429 | 427 | ||
430 | node_high_memory = (void *)__va((pgdat->node_start_pfn + | 428 | node_high_memory = (void *)__va((pgdat->node_start_pfn + |
431 | pgdat->node_spanned_pages) << | 429 | pgdat->node_spanned_pages) << |
@@ -501,31 +499,13 @@ void __init mem_init(void) | |||
501 | 499 | ||
502 | void free_initmem(void) | 500 | void free_initmem(void) |
503 | { | 501 | { |
504 | unsigned long addr; | 502 | free_initmem_default(0); |
505 | |||
506 | addr = (unsigned long)(&__init_begin); | ||
507 | for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { | ||
508 | ClearPageReserved(virt_to_page(addr)); | ||
509 | init_page_count(virt_to_page(addr)); | ||
510 | free_page(addr); | ||
511 | totalram_pages++; | ||
512 | } | ||
513 | printk("Freeing unused kernel memory: %ldk freed\n", | ||
514 | ((unsigned long)&__init_end - | ||
515 | (unsigned long)&__init_begin) >> 10); | ||
516 | } | 503 | } |
517 | 504 | ||
518 | #ifdef CONFIG_BLK_DEV_INITRD | 505 | #ifdef CONFIG_BLK_DEV_INITRD |
519 | void free_initrd_mem(unsigned long start, unsigned long end) | 506 | void free_initrd_mem(unsigned long start, unsigned long end) |
520 | { | 507 | { |
521 | unsigned long p; | 508 | free_reserved_area(start, end, 0, "initrd"); |
522 | for (p = start; p < end; p += PAGE_SIZE) { | ||
523 | ClearPageReserved(virt_to_page(p)); | ||
524 | init_page_count(virt_to_page(p)); | ||
525 | free_page(p); | ||
526 | totalram_pages++; | ||
527 | } | ||
528 | printk("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); | ||
529 | } | 509 | } |
530 | #endif | 510 | #endif |
531 | 511 | ||
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 3d361f236308..66dc562950ae 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
@@ -407,6 +407,8 @@ config SERIAL_CONSOLE | |||
407 | config SPARC_LEON | 407 | config SPARC_LEON |
408 | bool "Sparc Leon processor family" | 408 | bool "Sparc Leon processor family" |
409 | depends on SPARC32 | 409 | depends on SPARC32 |
410 | select USB_EHCI_BIG_ENDIAN_MMIO | ||
411 | select USB_EHCI_BIG_ENDIAN_DESC | ||
410 | ---help--- | 412 | ---help--- |
411 | If you say Y here if you are running on a SPARC-LEON processor. | 413 | If you say Y here if you are running on a SPARC-LEON processor. |
412 | The LEON processor is a synthesizable VHDL model of the | 414 | The LEON processor is a synthesizable VHDL model of the |
diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild index e26d430ce2fd..ff18e3cfb6b1 100644 --- a/arch/sparc/include/asm/Kbuild +++ b/arch/sparc/include/asm/Kbuild | |||
@@ -2,11 +2,16 @@ | |||
2 | 2 | ||
3 | 3 | ||
4 | generic-y += clkdev.h | 4 | generic-y += clkdev.h |
5 | generic-y += cputime.h | ||
5 | generic-y += div64.h | 6 | generic-y += div64.h |
7 | generic-y += emergency-restart.h | ||
6 | generic-y += exec.h | 8 | generic-y += exec.h |
7 | generic-y += local64.h | 9 | generic-y += local64.h |
10 | generic-y += mutex.h | ||
8 | generic-y += irq_regs.h | 11 | generic-y += irq_regs.h |
9 | generic-y += local.h | 12 | generic-y += local.h |
10 | generic-y += module.h | 13 | generic-y += module.h |
14 | generic-y += serial.h | ||
11 | generic-y += trace_clock.h | 15 | generic-y += trace_clock.h |
16 | generic-y += types.h | ||
12 | generic-y += word-at-a-time.h | 17 | generic-y += word-at-a-time.h |
diff --git a/arch/sparc/include/asm/cputime.h b/arch/sparc/include/asm/cputime.h deleted file mode 100644 index 1a642b81e019..000000000000 --- a/arch/sparc/include/asm/cputime.h +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | #ifndef __SPARC_CPUTIME_H | ||
2 | #define __SPARC_CPUTIME_H | ||
3 | |||
4 | #include <asm-generic/cputime.h> | ||
5 | |||
6 | #endif /* __SPARC_CPUTIME_H */ | ||
diff --git a/arch/sparc/include/asm/emergency-restart.h b/arch/sparc/include/asm/emergency-restart.h deleted file mode 100644 index 108d8c48e42e..000000000000 --- a/arch/sparc/include/asm/emergency-restart.h +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | #ifndef _ASM_EMERGENCY_RESTART_H | ||
2 | #define _ASM_EMERGENCY_RESTART_H | ||
3 | |||
4 | #include <asm-generic/emergency-restart.h> | ||
5 | |||
6 | #endif /* _ASM_EMERGENCY_RESTART_H */ | ||
diff --git a/arch/sparc/include/asm/hugetlb.h b/arch/sparc/include/asm/hugetlb.h index 7eb57d245044..e4cab465b81f 100644 --- a/arch/sparc/include/asm/hugetlb.h +++ b/arch/sparc/include/asm/hugetlb.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define _ASM_SPARC64_HUGETLB_H | 2 | #define _ASM_SPARC64_HUGETLB_H |
3 | 3 | ||
4 | #include <asm/page.h> | 4 | #include <asm/page.h> |
5 | #include <asm-generic/hugetlb.h> | ||
5 | 6 | ||
6 | 7 | ||
7 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | 8 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, |
diff --git a/arch/sparc/include/asm/mutex.h b/arch/sparc/include/asm/mutex.h deleted file mode 100644 index 458c1f7fbc18..000000000000 --- a/arch/sparc/include/asm/mutex.h +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | /* | ||
2 | * Pull in the generic implementation for the mutex fastpath. | ||
3 | * | ||
4 | * TODO: implement optimized primitives instead, or leave the generic | ||
5 | * implementation in place, or pick the atomic_xchg() based generic | ||
6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
7 | */ | ||
8 | |||
9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index 08fcce90316b..7619f2f792af 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h | |||
@@ -915,6 +915,7 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma, | |||
915 | return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot); | 915 | return remap_pfn_range(vma, from, phys_base >> PAGE_SHIFT, size, prot); |
916 | } | 916 | } |
917 | 917 | ||
918 | #include <asm/tlbflush.h> | ||
918 | #include <asm-generic/pgtable.h> | 919 | #include <asm-generic/pgtable.h> |
919 | 920 | ||
920 | /* We provide our own get_unmapped_area to cope with VA holes and | 921 | /* We provide our own get_unmapped_area to cope with VA holes and |
diff --git a/arch/sparc/include/asm/serial.h b/arch/sparc/include/asm/serial.h deleted file mode 100644 index f90d61c28059..000000000000 --- a/arch/sparc/include/asm/serial.h +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | #ifndef __SPARC_SERIAL_H | ||
2 | #define __SPARC_SERIAL_H | ||
3 | |||
4 | #define BASE_BAUD ( 1843200 / 16 ) | ||
5 | |||
6 | #endif /* __SPARC_SERIAL_H */ | ||
diff --git a/arch/sparc/include/asm/smp_32.h b/arch/sparc/include/asm/smp_32.h index b73da3c5f10a..3c8917f054de 100644 --- a/arch/sparc/include/asm/smp_32.h +++ b/arch/sparc/include/asm/smp_32.h | |||
@@ -36,7 +36,6 @@ typedef void (*smpfunc_t)(unsigned long, unsigned long, unsigned long, | |||
36 | unsigned long, unsigned long); | 36 | unsigned long, unsigned long); |
37 | 37 | ||
38 | void cpu_panic(void); | 38 | void cpu_panic(void); |
39 | extern void smp4m_irq_rotate(int cpu); | ||
40 | 39 | ||
41 | /* | 40 | /* |
42 | * General functions that each host system must provide. | 41 | * General functions that each host system must provide. |
@@ -46,7 +45,6 @@ void sun4m_init_smp(void); | |||
46 | void sun4d_init_smp(void); | 45 | void sun4d_init_smp(void); |
47 | 46 | ||
48 | void smp_callin(void); | 47 | void smp_callin(void); |
49 | void smp_boot_cpus(void); | ||
50 | void smp_store_cpu_info(int); | 48 | void smp_store_cpu_info(int); |
51 | 49 | ||
52 | void smp_resched_interrupt(void); | 50 | void smp_resched_interrupt(void); |
@@ -107,9 +105,6 @@ extern int hard_smp_processor_id(void); | |||
107 | 105 | ||
108 | #define raw_smp_processor_id() (current_thread_info()->cpu) | 106 | #define raw_smp_processor_id() (current_thread_info()->cpu) |
109 | 107 | ||
110 | #define prof_multiplier(__cpu) cpu_data(__cpu).multiplier | ||
111 | #define prof_counter(__cpu) cpu_data(__cpu).counter | ||
112 | |||
113 | void smp_setup_cpu_possible_map(void); | 108 | void smp_setup_cpu_possible_map(void); |
114 | 109 | ||
115 | #endif /* !(__ASSEMBLY__) */ | 110 | #endif /* !(__ASSEMBLY__) */ |
diff --git a/arch/sparc/include/asm/switch_to_64.h b/arch/sparc/include/asm/switch_to_64.h index cad36f56fa03..c7de3323819c 100644 --- a/arch/sparc/include/asm/switch_to_64.h +++ b/arch/sparc/include/asm/switch_to_64.h | |||
@@ -18,8 +18,7 @@ do { \ | |||
18 | * and 2 stores in this critical code path. -DaveM | 18 | * and 2 stores in this critical code path. -DaveM |
19 | */ | 19 | */ |
20 | #define switch_to(prev, next, last) \ | 20 | #define switch_to(prev, next, last) \ |
21 | do { flush_tlb_pending(); \ | 21 | do { save_and_clear_fpu(); \ |
22 | save_and_clear_fpu(); \ | ||
23 | /* If you are tempted to conditionalize the following */ \ | 22 | /* If you are tempted to conditionalize the following */ \ |
24 | /* so that ASI is only written if it changes, think again. */ \ | 23 | /* so that ASI is only written if it changes, think again. */ \ |
25 | __asm__ __volatile__("wr %%g0, %0, %%asi" \ | 24 | __asm__ __volatile__("wr %%g0, %0, %%asi" \ |
diff --git a/arch/sparc/include/asm/tlbflush_64.h b/arch/sparc/include/asm/tlbflush_64.h index 2ef463494153..f0d6a9700f4c 100644 --- a/arch/sparc/include/asm/tlbflush_64.h +++ b/arch/sparc/include/asm/tlbflush_64.h | |||
@@ -11,24 +11,40 @@ | |||
11 | struct tlb_batch { | 11 | struct tlb_batch { |
12 | struct mm_struct *mm; | 12 | struct mm_struct *mm; |
13 | unsigned long tlb_nr; | 13 | unsigned long tlb_nr; |
14 | unsigned long active; | ||
14 | unsigned long vaddrs[TLB_BATCH_NR]; | 15 | unsigned long vaddrs[TLB_BATCH_NR]; |
15 | }; | 16 | }; |
16 | 17 | ||
17 | extern void flush_tsb_kernel_range(unsigned long start, unsigned long end); | 18 | extern void flush_tsb_kernel_range(unsigned long start, unsigned long end); |
18 | extern void flush_tsb_user(struct tlb_batch *tb); | 19 | extern void flush_tsb_user(struct tlb_batch *tb); |
20 | extern void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr); | ||
19 | 21 | ||
20 | /* TLB flush operations. */ | 22 | /* TLB flush operations. */ |
21 | 23 | ||
22 | extern void flush_tlb_pending(void); | 24 | static inline void flush_tlb_mm(struct mm_struct *mm) |
25 | { | ||
26 | } | ||
27 | |||
28 | static inline void flush_tlb_page(struct vm_area_struct *vma, | ||
29 | unsigned long vmaddr) | ||
30 | { | ||
31 | } | ||
32 | |||
33 | static inline void flush_tlb_range(struct vm_area_struct *vma, | ||
34 | unsigned long start, unsigned long end) | ||
35 | { | ||
36 | } | ||
37 | |||
38 | #define __HAVE_ARCH_ENTER_LAZY_MMU_MODE | ||
23 | 39 | ||
24 | #define flush_tlb_range(vma,start,end) \ | 40 | extern void flush_tlb_pending(void); |
25 | do { (void)(start); flush_tlb_pending(); } while (0) | 41 | extern void arch_enter_lazy_mmu_mode(void); |
26 | #define flush_tlb_page(vma,addr) flush_tlb_pending() | 42 | extern void arch_leave_lazy_mmu_mode(void); |
27 | #define flush_tlb_mm(mm) flush_tlb_pending() | 43 | #define arch_flush_lazy_mmu_mode() do {} while (0) |
28 | 44 | ||
29 | /* Local cpu only. */ | 45 | /* Local cpu only. */ |
30 | extern void __flush_tlb_all(void); | 46 | extern void __flush_tlb_all(void); |
31 | 47 | extern void __flush_tlb_page(unsigned long context, unsigned long vaddr); | |
32 | extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end); | 48 | extern void __flush_tlb_kernel_range(unsigned long start, unsigned long end); |
33 | 49 | ||
34 | #ifndef CONFIG_SMP | 50 | #ifndef CONFIG_SMP |
@@ -38,15 +54,24 @@ do { flush_tsb_kernel_range(start,end); \ | |||
38 | __flush_tlb_kernel_range(start,end); \ | 54 | __flush_tlb_kernel_range(start,end); \ |
39 | } while (0) | 55 | } while (0) |
40 | 56 | ||
57 | static inline void global_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr) | ||
58 | { | ||
59 | __flush_tlb_page(CTX_HWBITS(mm->context), vaddr); | ||
60 | } | ||
61 | |||
41 | #else /* CONFIG_SMP */ | 62 | #else /* CONFIG_SMP */ |
42 | 63 | ||
43 | extern void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end); | 64 | extern void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end); |
65 | extern void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr); | ||
44 | 66 | ||
45 | #define flush_tlb_kernel_range(start, end) \ | 67 | #define flush_tlb_kernel_range(start, end) \ |
46 | do { flush_tsb_kernel_range(start,end); \ | 68 | do { flush_tsb_kernel_range(start,end); \ |
47 | smp_flush_tlb_kernel_range(start, end); \ | 69 | smp_flush_tlb_kernel_range(start, end); \ |
48 | } while (0) | 70 | } while (0) |
49 | 71 | ||
72 | #define global_flush_tlb_page(mm, vaddr) \ | ||
73 | smp_flush_tlb_page(mm, vaddr) | ||
74 | |||
50 | #endif /* ! CONFIG_SMP */ | 75 | #endif /* ! CONFIG_SMP */ |
51 | 76 | ||
52 | #endif /* _SPARC64_TLBFLUSH_H */ | 77 | #endif /* _SPARC64_TLBFLUSH_H */ |
diff --git a/arch/sparc/include/uapi/asm/Kbuild b/arch/sparc/include/uapi/asm/Kbuild index ce175aff71b7..b5843ee09fb5 100644 --- a/arch/sparc/include/uapi/asm/Kbuild +++ b/arch/sparc/include/uapi/asm/Kbuild | |||
@@ -44,7 +44,6 @@ header-y += swab.h | |||
44 | header-y += termbits.h | 44 | header-y += termbits.h |
45 | header-y += termios.h | 45 | header-y += termios.h |
46 | header-y += traps.h | 46 | header-y += traps.h |
47 | header-y += types.h | ||
48 | header-y += uctx.h | 47 | header-y += uctx.h |
49 | header-y += unistd.h | 48 | header-y += unistd.h |
50 | header-y += utrap.h | 49 | header-y += utrap.h |
diff --git a/arch/sparc/include/uapi/asm/types.h b/arch/sparc/include/uapi/asm/types.h deleted file mode 100644 index 383d156cde9c..000000000000 --- a/arch/sparc/include/uapi/asm/types.h +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | #ifndef _SPARC_TYPES_H | ||
2 | #define _SPARC_TYPES_H | ||
3 | /* | ||
4 | * This file is never included by application software unless | ||
5 | * explicitly requested (e.g., via linux/types.h) in which case the | ||
6 | * application is Linux specific so (user-) name space pollution is | ||
7 | * not a major issue. However, for interoperability, libraries still | ||
8 | * need to be careful to avoid a name clashes. | ||
9 | */ | ||
10 | |||
11 | #if defined(__sparc__) | ||
12 | |||
13 | #include <asm-generic/int-ll64.h> | ||
14 | |||
15 | #endif /* defined(__sparc__) */ | ||
16 | |||
17 | #endif /* defined(_SPARC_TYPES_H) */ | ||
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index c025ffce7a40..77539eda928c 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c | |||
@@ -851,7 +851,7 @@ void smp_tsb_sync(struct mm_struct *mm) | |||
851 | } | 851 | } |
852 | 852 | ||
853 | extern unsigned long xcall_flush_tlb_mm; | 853 | extern unsigned long xcall_flush_tlb_mm; |
854 | extern unsigned long xcall_flush_tlb_pending; | 854 | extern unsigned long xcall_flush_tlb_page; |
855 | extern unsigned long xcall_flush_tlb_kernel_range; | 855 | extern unsigned long xcall_flush_tlb_kernel_range; |
856 | extern unsigned long xcall_fetch_glob_regs; | 856 | extern unsigned long xcall_fetch_glob_regs; |
857 | extern unsigned long xcall_fetch_glob_pmu; | 857 | extern unsigned long xcall_fetch_glob_pmu; |
@@ -1076,23 +1076,56 @@ local_flush_and_out: | |||
1076 | put_cpu(); | 1076 | put_cpu(); |
1077 | } | 1077 | } |
1078 | 1078 | ||
1079 | struct tlb_pending_info { | ||
1080 | unsigned long ctx; | ||
1081 | unsigned long nr; | ||
1082 | unsigned long *vaddrs; | ||
1083 | }; | ||
1084 | |||
1085 | static void tlb_pending_func(void *info) | ||
1086 | { | ||
1087 | struct tlb_pending_info *t = info; | ||
1088 | |||
1089 | __flush_tlb_pending(t->ctx, t->nr, t->vaddrs); | ||
1090 | } | ||
1091 | |||
1079 | void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long *vaddrs) | 1092 | void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long *vaddrs) |
1080 | { | 1093 | { |
1081 | u32 ctx = CTX_HWBITS(mm->context); | 1094 | u32 ctx = CTX_HWBITS(mm->context); |
1095 | struct tlb_pending_info info; | ||
1082 | int cpu = get_cpu(); | 1096 | int cpu = get_cpu(); |
1083 | 1097 | ||
1098 | info.ctx = ctx; | ||
1099 | info.nr = nr; | ||
1100 | info.vaddrs = vaddrs; | ||
1101 | |||
1084 | if (mm == current->mm && atomic_read(&mm->mm_users) == 1) | 1102 | if (mm == current->mm && atomic_read(&mm->mm_users) == 1) |
1085 | cpumask_copy(mm_cpumask(mm), cpumask_of(cpu)); | 1103 | cpumask_copy(mm_cpumask(mm), cpumask_of(cpu)); |
1086 | else | 1104 | else |
1087 | smp_cross_call_masked(&xcall_flush_tlb_pending, | 1105 | smp_call_function_many(mm_cpumask(mm), tlb_pending_func, |
1088 | ctx, nr, (unsigned long) vaddrs, | 1106 | &info, 1); |
1089 | mm_cpumask(mm)); | ||
1090 | 1107 | ||
1091 | __flush_tlb_pending(ctx, nr, vaddrs); | 1108 | __flush_tlb_pending(ctx, nr, vaddrs); |
1092 | 1109 | ||
1093 | put_cpu(); | 1110 | put_cpu(); |
1094 | } | 1111 | } |
1095 | 1112 | ||
1113 | void smp_flush_tlb_page(struct mm_struct *mm, unsigned long vaddr) | ||
1114 | { | ||
1115 | unsigned long context = CTX_HWBITS(mm->context); | ||
1116 | int cpu = get_cpu(); | ||
1117 | |||
1118 | if (mm == current->mm && atomic_read(&mm->mm_users) == 1) | ||
1119 | cpumask_copy(mm_cpumask(mm), cpumask_of(cpu)); | ||
1120 | else | ||
1121 | smp_cross_call_masked(&xcall_flush_tlb_page, | ||
1122 | context, vaddr, 0, | ||
1123 | mm_cpumask(mm)); | ||
1124 | __flush_tlb_page(context, vaddr); | ||
1125 | |||
1126 | put_cpu(); | ||
1127 | } | ||
1128 | |||
1096 | void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end) | 1129 | void smp_flush_tlb_kernel_range(unsigned long start, unsigned long end) |
1097 | { | 1130 | { |
1098 | start &= PAGE_MASK; | 1131 | start &= PAGE_MASK; |
diff --git a/arch/sparc/lib/bitext.c b/arch/sparc/lib/bitext.c index 48d00e72ce15..8ec4e9c0251a 100644 --- a/arch/sparc/lib/bitext.c +++ b/arch/sparc/lib/bitext.c | |||
@@ -119,11 +119,7 @@ void bit_map_clear(struct bit_map *t, int offset, int len) | |||
119 | 119 | ||
120 | void bit_map_init(struct bit_map *t, unsigned long *map, int size) | 120 | void bit_map_init(struct bit_map *t, unsigned long *map, int size) |
121 | { | 121 | { |
122 | 122 | bitmap_zero(map, size); | |
123 | if ((size & 07) != 0) | ||
124 | BUG(); | ||
125 | memset(map, 0, size>>3); | ||
126 | |||
127 | memset(t, 0, sizeof *t); | 123 | memset(t, 0, sizeof *t); |
128 | spin_lock_init(&t->lock); | 124 | spin_lock_init(&t->lock); |
129 | t->map = map; | 125 | t->map = map; |
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c index 48e0c030e8f5..4490c397bb5b 100644 --- a/arch/sparc/mm/init_32.c +++ b/arch/sparc/mm/init_32.c | |||
@@ -282,14 +282,8 @@ static void map_high_region(unsigned long start_pfn, unsigned long end_pfn) | |||
282 | printk("mapping high region %08lx - %08lx\n", start_pfn, end_pfn); | 282 | printk("mapping high region %08lx - %08lx\n", start_pfn, end_pfn); |
283 | #endif | 283 | #endif |
284 | 284 | ||
285 | for (tmp = start_pfn; tmp < end_pfn; tmp++) { | 285 | for (tmp = start_pfn; tmp < end_pfn; tmp++) |
286 | struct page *page = pfn_to_page(tmp); | 286 | free_highmem_page(pfn_to_page(tmp)); |
287 | |||
288 | ClearPageReserved(page); | ||
289 | init_page_count(page); | ||
290 | __free_page(page); | ||
291 | totalhigh_pages++; | ||
292 | } | ||
293 | } | 287 | } |
294 | 288 | ||
295 | void __init mem_init(void) | 289 | void __init mem_init(void) |
@@ -347,8 +341,6 @@ void __init mem_init(void) | |||
347 | map_high_region(start_pfn, end_pfn); | 341 | map_high_region(start_pfn, end_pfn); |
348 | } | 342 | } |
349 | 343 | ||
350 | totalram_pages += totalhigh_pages; | ||
351 | |||
352 | codepages = (((unsigned long) &_etext) - ((unsigned long)&_start)); | 344 | codepages = (((unsigned long) &_etext) - ((unsigned long)&_start)); |
353 | codepages = PAGE_ALIGN(codepages) >> PAGE_SHIFT; | 345 | codepages = PAGE_ALIGN(codepages) >> PAGE_SHIFT; |
354 | datapages = (((unsigned long) &_edata) - ((unsigned long)&_etext)); | 346 | datapages = (((unsigned long) &_edata) - ((unsigned long)&_etext)); |
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 1588d33d5492..6ac99d64a13c 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c | |||
@@ -2181,10 +2181,9 @@ unsigned long vmemmap_table[VMEMMAP_SIZE]; | |||
2181 | static long __meminitdata addr_start, addr_end; | 2181 | static long __meminitdata addr_start, addr_end; |
2182 | static int __meminitdata node_start; | 2182 | static int __meminitdata node_start; |
2183 | 2183 | ||
2184 | int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node) | 2184 | int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend, |
2185 | int node) | ||
2185 | { | 2186 | { |
2186 | unsigned long vstart = (unsigned long) start; | ||
2187 | unsigned long vend = (unsigned long) (start + nr); | ||
2188 | unsigned long phys_start = (vstart - VMEMMAP_BASE); | 2187 | unsigned long phys_start = (vstart - VMEMMAP_BASE); |
2189 | unsigned long phys_end = (vend - VMEMMAP_BASE); | 2188 | unsigned long phys_end = (vend - VMEMMAP_BASE); |
2190 | unsigned long addr = phys_start & VMEMMAP_CHUNK_MASK; | 2189 | unsigned long addr = phys_start & VMEMMAP_CHUNK_MASK; |
@@ -2236,7 +2235,7 @@ void __meminit vmemmap_populate_print_last(void) | |||
2236 | } | 2235 | } |
2237 | } | 2236 | } |
2238 | 2237 | ||
2239 | void vmemmap_free(struct page *memmap, unsigned long nr_pages) | 2238 | void vmemmap_free(unsigned long start, unsigned long end) |
2240 | { | 2239 | { |
2241 | } | 2240 | } |
2242 | 2241 | ||
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c index 0f4f7191fbba..28f96f27c768 100644 --- a/arch/sparc/mm/iommu.c +++ b/arch/sparc/mm/iommu.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #define IOMMU_RNGE IOMMU_RNGE_256MB | 34 | #define IOMMU_RNGE IOMMU_RNGE_256MB |
35 | #define IOMMU_START 0xF0000000 | 35 | #define IOMMU_START 0xF0000000 |
36 | #define IOMMU_WINSIZE (256*1024*1024U) | 36 | #define IOMMU_WINSIZE (256*1024*1024U) |
37 | #define IOMMU_NPTES (IOMMU_WINSIZE/PAGE_SIZE) /* 64K PTEs, 265KB */ | 37 | #define IOMMU_NPTES (IOMMU_WINSIZE/PAGE_SIZE) /* 64K PTEs, 256KB */ |
38 | #define IOMMU_ORDER 6 /* 4096 * (1<<6) */ | 38 | #define IOMMU_ORDER 6 /* 4096 * (1<<6) */ |
39 | 39 | ||
40 | /* srmmu.c */ | 40 | /* srmmu.c */ |
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index c38bb72e3e80..036c2797dece 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c | |||
@@ -280,7 +280,9 @@ static void __init srmmu_nocache_init(void) | |||
280 | SRMMU_NOCACHE_ALIGN_MAX, 0UL); | 280 | SRMMU_NOCACHE_ALIGN_MAX, 0UL); |
281 | memset(srmmu_nocache_pool, 0, srmmu_nocache_size); | 281 | memset(srmmu_nocache_pool, 0, srmmu_nocache_size); |
282 | 282 | ||
283 | srmmu_nocache_bitmap = __alloc_bootmem(bitmap_bits >> 3, SMP_CACHE_BYTES, 0UL); | 283 | srmmu_nocache_bitmap = |
284 | __alloc_bootmem(BITS_TO_LONGS(bitmap_bits) * sizeof(long), | ||
285 | SMP_CACHE_BYTES, 0UL); | ||
284 | bit_map_init(&srmmu_nocache_map, srmmu_nocache_bitmap, bitmap_bits); | 286 | bit_map_init(&srmmu_nocache_map, srmmu_nocache_bitmap, bitmap_bits); |
285 | 287 | ||
286 | srmmu_swapper_pg_dir = __srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE); | 288 | srmmu_swapper_pg_dir = __srmmu_get_nocache(SRMMU_PGD_TABLE_SIZE, SRMMU_PGD_TABLE_SIZE); |
diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c index ba6ae7ffdc2c..83d89bcb44af 100644 --- a/arch/sparc/mm/tlb.c +++ b/arch/sparc/mm/tlb.c | |||
@@ -24,11 +24,17 @@ static DEFINE_PER_CPU(struct tlb_batch, tlb_batch); | |||
24 | void flush_tlb_pending(void) | 24 | void flush_tlb_pending(void) |
25 | { | 25 | { |
26 | struct tlb_batch *tb = &get_cpu_var(tlb_batch); | 26 | struct tlb_batch *tb = &get_cpu_var(tlb_batch); |
27 | struct mm_struct *mm = tb->mm; | ||
27 | 28 | ||
28 | if (tb->tlb_nr) { | 29 | if (!tb->tlb_nr) |
29 | flush_tsb_user(tb); | 30 | goto out; |
30 | 31 | ||
31 | if (CTX_VALID(tb->mm->context)) { | 32 | flush_tsb_user(tb); |
33 | |||
34 | if (CTX_VALID(mm->context)) { | ||
35 | if (tb->tlb_nr == 1) { | ||
36 | global_flush_tlb_page(mm, tb->vaddrs[0]); | ||
37 | } else { | ||
32 | #ifdef CONFIG_SMP | 38 | #ifdef CONFIG_SMP |
33 | smp_flush_tlb_pending(tb->mm, tb->tlb_nr, | 39 | smp_flush_tlb_pending(tb->mm, tb->tlb_nr, |
34 | &tb->vaddrs[0]); | 40 | &tb->vaddrs[0]); |
@@ -37,12 +43,30 @@ void flush_tlb_pending(void) | |||
37 | tb->tlb_nr, &tb->vaddrs[0]); | 43 | tb->tlb_nr, &tb->vaddrs[0]); |
38 | #endif | 44 | #endif |
39 | } | 45 | } |
40 | tb->tlb_nr = 0; | ||
41 | } | 46 | } |
42 | 47 | ||
48 | tb->tlb_nr = 0; | ||
49 | |||
50 | out: | ||
43 | put_cpu_var(tlb_batch); | 51 | put_cpu_var(tlb_batch); |
44 | } | 52 | } |
45 | 53 | ||
54 | void arch_enter_lazy_mmu_mode(void) | ||
55 | { | ||
56 | struct tlb_batch *tb = &__get_cpu_var(tlb_batch); | ||
57 | |||
58 | tb->active = 1; | ||
59 | } | ||
60 | |||
61 | void arch_leave_lazy_mmu_mode(void) | ||
62 | { | ||
63 | struct tlb_batch *tb = &__get_cpu_var(tlb_batch); | ||
64 | |||
65 | if (tb->tlb_nr) | ||
66 | flush_tlb_pending(); | ||
67 | tb->active = 0; | ||
68 | } | ||
69 | |||
46 | static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr, | 70 | static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr, |
47 | bool exec) | 71 | bool exec) |
48 | { | 72 | { |
@@ -60,6 +84,12 @@ static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr, | |||
60 | nr = 0; | 84 | nr = 0; |
61 | } | 85 | } |
62 | 86 | ||
87 | if (!tb->active) { | ||
88 | global_flush_tlb_page(mm, vaddr); | ||
89 | flush_tsb_user_page(mm, vaddr); | ||
90 | goto out; | ||
91 | } | ||
92 | |||
63 | if (nr == 0) | 93 | if (nr == 0) |
64 | tb->mm = mm; | 94 | tb->mm = mm; |
65 | 95 | ||
@@ -68,6 +98,7 @@ static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr, | |||
68 | if (nr >= TLB_BATCH_NR) | 98 | if (nr >= TLB_BATCH_NR) |
69 | flush_tlb_pending(); | 99 | flush_tlb_pending(); |
70 | 100 | ||
101 | out: | ||
71 | put_cpu_var(tlb_batch); | 102 | put_cpu_var(tlb_batch); |
72 | } | 103 | } |
73 | 104 | ||
diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c index 428982b9becf..2cc3bce5ee91 100644 --- a/arch/sparc/mm/tsb.c +++ b/arch/sparc/mm/tsb.c | |||
@@ -7,11 +7,10 @@ | |||
7 | #include <linux/preempt.h> | 7 | #include <linux/preempt.h> |
8 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
9 | #include <asm/page.h> | 9 | #include <asm/page.h> |
10 | #include <asm/tlbflush.h> | ||
11 | #include <asm/tlb.h> | ||
12 | #include <asm/mmu_context.h> | ||
13 | #include <asm/pgtable.h> | 10 | #include <asm/pgtable.h> |
11 | #include <asm/mmu_context.h> | ||
14 | #include <asm/tsb.h> | 12 | #include <asm/tsb.h> |
13 | #include <asm/tlb.h> | ||
15 | #include <asm/oplib.h> | 14 | #include <asm/oplib.h> |
16 | 15 | ||
17 | extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; | 16 | extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; |
@@ -46,23 +45,27 @@ void flush_tsb_kernel_range(unsigned long start, unsigned long end) | |||
46 | } | 45 | } |
47 | } | 46 | } |
48 | 47 | ||
49 | static void __flush_tsb_one(struct tlb_batch *tb, unsigned long hash_shift, | 48 | static void __flush_tsb_one_entry(unsigned long tsb, unsigned long v, |
50 | unsigned long tsb, unsigned long nentries) | 49 | unsigned long hash_shift, |
50 | unsigned long nentries) | ||
51 | { | 51 | { |
52 | unsigned long i; | 52 | unsigned long tag, ent, hash; |
53 | 53 | ||
54 | for (i = 0; i < tb->tlb_nr; i++) { | 54 | v &= ~0x1UL; |
55 | unsigned long v = tb->vaddrs[i]; | 55 | hash = tsb_hash(v, hash_shift, nentries); |
56 | unsigned long tag, ent, hash; | 56 | ent = tsb + (hash * sizeof(struct tsb)); |
57 | tag = (v >> 22UL); | ||
57 | 58 | ||
58 | v &= ~0x1UL; | 59 | tsb_flush(ent, tag); |
60 | } | ||
59 | 61 | ||
60 | hash = tsb_hash(v, hash_shift, nentries); | 62 | static void __flush_tsb_one(struct tlb_batch *tb, unsigned long hash_shift, |
61 | ent = tsb + (hash * sizeof(struct tsb)); | 63 | unsigned long tsb, unsigned long nentries) |
62 | tag = (v >> 22UL); | 64 | { |
65 | unsigned long i; | ||
63 | 66 | ||
64 | tsb_flush(ent, tag); | 67 | for (i = 0; i < tb->tlb_nr; i++) |
65 | } | 68 | __flush_tsb_one_entry(tsb, tb->vaddrs[i], hash_shift, nentries); |
66 | } | 69 | } |
67 | 70 | ||
68 | void flush_tsb_user(struct tlb_batch *tb) | 71 | void flush_tsb_user(struct tlb_batch *tb) |
@@ -90,6 +93,30 @@ void flush_tsb_user(struct tlb_batch *tb) | |||
90 | spin_unlock_irqrestore(&mm->context.lock, flags); | 93 | spin_unlock_irqrestore(&mm->context.lock, flags); |
91 | } | 94 | } |
92 | 95 | ||
96 | void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr) | ||
97 | { | ||
98 | unsigned long nentries, base, flags; | ||
99 | |||
100 | spin_lock_irqsave(&mm->context.lock, flags); | ||
101 | |||
102 | base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb; | ||
103 | nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries; | ||
104 | if (tlb_type == cheetah_plus || tlb_type == hypervisor) | ||
105 | base = __pa(base); | ||
106 | __flush_tsb_one_entry(base, vaddr, PAGE_SHIFT, nentries); | ||
107 | |||
108 | #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE) | ||
109 | if (mm->context.tsb_block[MM_TSB_HUGE].tsb) { | ||
110 | base = (unsigned long) mm->context.tsb_block[MM_TSB_HUGE].tsb; | ||
111 | nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries; | ||
112 | if (tlb_type == cheetah_plus || tlb_type == hypervisor) | ||
113 | base = __pa(base); | ||
114 | __flush_tsb_one_entry(base, vaddr, HPAGE_SHIFT, nentries); | ||
115 | } | ||
116 | #endif | ||
117 | spin_unlock_irqrestore(&mm->context.lock, flags); | ||
118 | } | ||
119 | |||
93 | #define HV_PGSZ_IDX_BASE HV_PGSZ_IDX_8K | 120 | #define HV_PGSZ_IDX_BASE HV_PGSZ_IDX_8K |
94 | #define HV_PGSZ_MASK_BASE HV_PGSZ_MASK_8K | 121 | #define HV_PGSZ_MASK_BASE HV_PGSZ_MASK_8K |
95 | 122 | ||
diff --git a/arch/sparc/mm/ultra.S b/arch/sparc/mm/ultra.S index f8e13d421fcb..432aa0cb1b38 100644 --- a/arch/sparc/mm/ultra.S +++ b/arch/sparc/mm/ultra.S | |||
@@ -53,6 +53,33 @@ __flush_tlb_mm: /* 18 insns */ | |||
53 | nop | 53 | nop |
54 | 54 | ||
55 | .align 32 | 55 | .align 32 |
56 | .globl __flush_tlb_page | ||
57 | __flush_tlb_page: /* 22 insns */ | ||
58 | /* %o0 = context, %o1 = vaddr */ | ||
59 | rdpr %pstate, %g7 | ||
60 | andn %g7, PSTATE_IE, %g2 | ||
61 | wrpr %g2, %pstate | ||
62 | mov SECONDARY_CONTEXT, %o4 | ||
63 | ldxa [%o4] ASI_DMMU, %g2 | ||
64 | stxa %o0, [%o4] ASI_DMMU | ||
65 | andcc %o1, 1, %g0 | ||
66 | andn %o1, 1, %o3 | ||
67 | be,pn %icc, 1f | ||
68 | or %o3, 0x10, %o3 | ||
69 | stxa %g0, [%o3] ASI_IMMU_DEMAP | ||
70 | 1: stxa %g0, [%o3] ASI_DMMU_DEMAP | ||
71 | membar #Sync | ||
72 | stxa %g2, [%o4] ASI_DMMU | ||
73 | sethi %hi(KERNBASE), %o4 | ||
74 | flush %o4 | ||
75 | retl | ||
76 | wrpr %g7, 0x0, %pstate | ||
77 | nop | ||
78 | nop | ||
79 | nop | ||
80 | nop | ||
81 | |||
82 | .align 32 | ||
56 | .globl __flush_tlb_pending | 83 | .globl __flush_tlb_pending |
57 | __flush_tlb_pending: /* 26 insns */ | 84 | __flush_tlb_pending: /* 26 insns */ |
58 | /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ | 85 | /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ |
@@ -203,6 +230,31 @@ __cheetah_flush_tlb_mm: /* 19 insns */ | |||
203 | retl | 230 | retl |
204 | wrpr %g7, 0x0, %pstate | 231 | wrpr %g7, 0x0, %pstate |
205 | 232 | ||
233 | __cheetah_flush_tlb_page: /* 22 insns */ | ||
234 | /* %o0 = context, %o1 = vaddr */ | ||
235 | rdpr %pstate, %g7 | ||
236 | andn %g7, PSTATE_IE, %g2 | ||
237 | wrpr %g2, 0x0, %pstate | ||
238 | wrpr %g0, 1, %tl | ||
239 | mov PRIMARY_CONTEXT, %o4 | ||
240 | ldxa [%o4] ASI_DMMU, %g2 | ||
241 | srlx %g2, CTX_PGSZ1_NUC_SHIFT, %o3 | ||
242 | sllx %o3, CTX_PGSZ1_NUC_SHIFT, %o3 | ||
243 | or %o0, %o3, %o0 /* Preserve nucleus page size fields */ | ||
244 | stxa %o0, [%o4] ASI_DMMU | ||
245 | andcc %o1, 1, %g0 | ||
246 | be,pn %icc, 1f | ||
247 | andn %o1, 1, %o3 | ||
248 | stxa %g0, [%o3] ASI_IMMU_DEMAP | ||
249 | 1: stxa %g0, [%o3] ASI_DMMU_DEMAP | ||
250 | membar #Sync | ||
251 | stxa %g2, [%o4] ASI_DMMU | ||
252 | sethi %hi(KERNBASE), %o4 | ||
253 | flush %o4 | ||
254 | wrpr %g0, 0, %tl | ||
255 | retl | ||
256 | wrpr %g7, 0x0, %pstate | ||
257 | |||
206 | __cheetah_flush_tlb_pending: /* 27 insns */ | 258 | __cheetah_flush_tlb_pending: /* 27 insns */ |
207 | /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ | 259 | /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ |
208 | rdpr %pstate, %g7 | 260 | rdpr %pstate, %g7 |
@@ -269,6 +321,20 @@ __hypervisor_flush_tlb_mm: /* 10 insns */ | |||
269 | retl | 321 | retl |
270 | nop | 322 | nop |
271 | 323 | ||
324 | __hypervisor_flush_tlb_page: /* 11 insns */ | ||
325 | /* %o0 = context, %o1 = vaddr */ | ||
326 | mov %o0, %g2 | ||
327 | mov %o1, %o0 /* ARG0: vaddr + IMMU-bit */ | ||
328 | mov %g2, %o1 /* ARG1: mmu context */ | ||
329 | mov HV_MMU_ALL, %o2 /* ARG2: flags */ | ||
330 | srlx %o0, PAGE_SHIFT, %o0 | ||
331 | sllx %o0, PAGE_SHIFT, %o0 | ||
332 | ta HV_MMU_UNMAP_ADDR_TRAP | ||
333 | brnz,pn %o0, __hypervisor_tlb_tl0_error | ||
334 | mov HV_MMU_UNMAP_ADDR_TRAP, %o1 | ||
335 | retl | ||
336 | nop | ||
337 | |||
272 | __hypervisor_flush_tlb_pending: /* 16 insns */ | 338 | __hypervisor_flush_tlb_pending: /* 16 insns */ |
273 | /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ | 339 | /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ |
274 | sllx %o1, 3, %g1 | 340 | sllx %o1, 3, %g1 |
@@ -339,6 +405,13 @@ cheetah_patch_cachetlbops: | |||
339 | call tlb_patch_one | 405 | call tlb_patch_one |
340 | mov 19, %o2 | 406 | mov 19, %o2 |
341 | 407 | ||
408 | sethi %hi(__flush_tlb_page), %o0 | ||
409 | or %o0, %lo(__flush_tlb_page), %o0 | ||
410 | sethi %hi(__cheetah_flush_tlb_page), %o1 | ||
411 | or %o1, %lo(__cheetah_flush_tlb_page), %o1 | ||
412 | call tlb_patch_one | ||
413 | mov 22, %o2 | ||
414 | |||
342 | sethi %hi(__flush_tlb_pending), %o0 | 415 | sethi %hi(__flush_tlb_pending), %o0 |
343 | or %o0, %lo(__flush_tlb_pending), %o0 | 416 | or %o0, %lo(__flush_tlb_pending), %o0 |
344 | sethi %hi(__cheetah_flush_tlb_pending), %o1 | 417 | sethi %hi(__cheetah_flush_tlb_pending), %o1 |
@@ -397,10 +470,9 @@ xcall_flush_tlb_mm: /* 21 insns */ | |||
397 | nop | 470 | nop |
398 | nop | 471 | nop |
399 | 472 | ||
400 | .globl xcall_flush_tlb_pending | 473 | .globl xcall_flush_tlb_page |
401 | xcall_flush_tlb_pending: /* 21 insns */ | 474 | xcall_flush_tlb_page: /* 17 insns */ |
402 | /* %g5=context, %g1=nr, %g7=vaddrs[] */ | 475 | /* %g5=context, %g1=vaddr */ |
403 | sllx %g1, 3, %g1 | ||
404 | mov PRIMARY_CONTEXT, %g4 | 476 | mov PRIMARY_CONTEXT, %g4 |
405 | ldxa [%g4] ASI_DMMU, %g2 | 477 | ldxa [%g4] ASI_DMMU, %g2 |
406 | srlx %g2, CTX_PGSZ1_NUC_SHIFT, %g4 | 478 | srlx %g2, CTX_PGSZ1_NUC_SHIFT, %g4 |
@@ -408,20 +480,16 @@ xcall_flush_tlb_pending: /* 21 insns */ | |||
408 | or %g5, %g4, %g5 | 480 | or %g5, %g4, %g5 |
409 | mov PRIMARY_CONTEXT, %g4 | 481 | mov PRIMARY_CONTEXT, %g4 |
410 | stxa %g5, [%g4] ASI_DMMU | 482 | stxa %g5, [%g4] ASI_DMMU |
411 | 1: sub %g1, (1 << 3), %g1 | 483 | andcc %g1, 0x1, %g0 |
412 | ldx [%g7 + %g1], %g5 | ||
413 | andcc %g5, 0x1, %g0 | ||
414 | be,pn %icc, 2f | 484 | be,pn %icc, 2f |
415 | 485 | andn %g1, 0x1, %g5 | |
416 | andn %g5, 0x1, %g5 | ||
417 | stxa %g0, [%g5] ASI_IMMU_DEMAP | 486 | stxa %g0, [%g5] ASI_IMMU_DEMAP |
418 | 2: stxa %g0, [%g5] ASI_DMMU_DEMAP | 487 | 2: stxa %g0, [%g5] ASI_DMMU_DEMAP |
419 | membar #Sync | 488 | membar #Sync |
420 | brnz,pt %g1, 1b | ||
421 | nop | ||
422 | stxa %g2, [%g4] ASI_DMMU | 489 | stxa %g2, [%g4] ASI_DMMU |
423 | retry | 490 | retry |
424 | nop | 491 | nop |
492 | nop | ||
425 | 493 | ||
426 | .globl xcall_flush_tlb_kernel_range | 494 | .globl xcall_flush_tlb_kernel_range |
427 | xcall_flush_tlb_kernel_range: /* 25 insns */ | 495 | xcall_flush_tlb_kernel_range: /* 25 insns */ |
@@ -656,15 +724,13 @@ __hypervisor_xcall_flush_tlb_mm: /* 21 insns */ | |||
656 | membar #Sync | 724 | membar #Sync |
657 | retry | 725 | retry |
658 | 726 | ||
659 | .globl __hypervisor_xcall_flush_tlb_pending | 727 | .globl __hypervisor_xcall_flush_tlb_page |
660 | __hypervisor_xcall_flush_tlb_pending: /* 21 insns */ | 728 | __hypervisor_xcall_flush_tlb_page: /* 17 insns */ |
661 | /* %g5=ctx, %g1=nr, %g7=vaddrs[], %g2,%g3,%g4,g6=scratch */ | 729 | /* %g5=ctx, %g1=vaddr */ |
662 | sllx %g1, 3, %g1 | ||
663 | mov %o0, %g2 | 730 | mov %o0, %g2 |
664 | mov %o1, %g3 | 731 | mov %o1, %g3 |
665 | mov %o2, %g4 | 732 | mov %o2, %g4 |
666 | 1: sub %g1, (1 << 3), %g1 | 733 | mov %g1, %o0 /* ARG0: virtual address */ |
667 | ldx [%g7 + %g1], %o0 /* ARG0: virtual address */ | ||
668 | mov %g5, %o1 /* ARG1: mmu context */ | 734 | mov %g5, %o1 /* ARG1: mmu context */ |
669 | mov HV_MMU_ALL, %o2 /* ARG2: flags */ | 735 | mov HV_MMU_ALL, %o2 /* ARG2: flags */ |
670 | srlx %o0, PAGE_SHIFT, %o0 | 736 | srlx %o0, PAGE_SHIFT, %o0 |
@@ -673,8 +739,6 @@ __hypervisor_xcall_flush_tlb_pending: /* 21 insns */ | |||
673 | mov HV_MMU_UNMAP_ADDR_TRAP, %g6 | 739 | mov HV_MMU_UNMAP_ADDR_TRAP, %g6 |
674 | brnz,a,pn %o0, __hypervisor_tlb_xcall_error | 740 | brnz,a,pn %o0, __hypervisor_tlb_xcall_error |
675 | mov %o0, %g5 | 741 | mov %o0, %g5 |
676 | brnz,pt %g1, 1b | ||
677 | nop | ||
678 | mov %g2, %o0 | 742 | mov %g2, %o0 |
679 | mov %g3, %o1 | 743 | mov %g3, %o1 |
680 | mov %g4, %o2 | 744 | mov %g4, %o2 |
@@ -757,6 +821,13 @@ hypervisor_patch_cachetlbops: | |||
757 | call tlb_patch_one | 821 | call tlb_patch_one |
758 | mov 10, %o2 | 822 | mov 10, %o2 |
759 | 823 | ||
824 | sethi %hi(__flush_tlb_page), %o0 | ||
825 | or %o0, %lo(__flush_tlb_page), %o0 | ||
826 | sethi %hi(__hypervisor_flush_tlb_page), %o1 | ||
827 | or %o1, %lo(__hypervisor_flush_tlb_page), %o1 | ||
828 | call tlb_patch_one | ||
829 | mov 11, %o2 | ||
830 | |||
760 | sethi %hi(__flush_tlb_pending), %o0 | 831 | sethi %hi(__flush_tlb_pending), %o0 |
761 | or %o0, %lo(__flush_tlb_pending), %o0 | 832 | or %o0, %lo(__flush_tlb_pending), %o0 |
762 | sethi %hi(__hypervisor_flush_tlb_pending), %o1 | 833 | sethi %hi(__hypervisor_flush_tlb_pending), %o1 |
@@ -788,12 +859,12 @@ hypervisor_patch_cachetlbops: | |||
788 | call tlb_patch_one | 859 | call tlb_patch_one |
789 | mov 21, %o2 | 860 | mov 21, %o2 |
790 | 861 | ||
791 | sethi %hi(xcall_flush_tlb_pending), %o0 | 862 | sethi %hi(xcall_flush_tlb_page), %o0 |
792 | or %o0, %lo(xcall_flush_tlb_pending), %o0 | 863 | or %o0, %lo(xcall_flush_tlb_page), %o0 |
793 | sethi %hi(__hypervisor_xcall_flush_tlb_pending), %o1 | 864 | sethi %hi(__hypervisor_xcall_flush_tlb_page), %o1 |
794 | or %o1, %lo(__hypervisor_xcall_flush_tlb_pending), %o1 | 865 | or %o1, %lo(__hypervisor_xcall_flush_tlb_page), %o1 |
795 | call tlb_patch_one | 866 | call tlb_patch_one |
796 | mov 21, %o2 | 867 | mov 17, %o2 |
797 | 868 | ||
798 | sethi %hi(xcall_flush_tlb_kernel_range), %o0 | 869 | sethi %hi(xcall_flush_tlb_kernel_range), %o0 |
799 | or %o0, %lo(xcall_flush_tlb_kernel_range), %o0 | 870 | or %o0, %lo(xcall_flush_tlb_kernel_range), %o0 |
diff --git a/arch/tile/include/asm/hugetlb.h b/arch/tile/include/asm/hugetlb.h index 0f885af2b621..3257733003f8 100644 --- a/arch/tile/include/asm/hugetlb.h +++ b/arch/tile/include/asm/hugetlb.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #define _ASM_TILE_HUGETLB_H | 16 | #define _ASM_TILE_HUGETLB_H |
17 | 17 | ||
18 | #include <asm/page.h> | 18 | #include <asm/page.h> |
19 | #include <asm-generic/hugetlb.h> | ||
19 | 20 | ||
20 | 21 | ||
21 | static inline int is_hugepage_only_range(struct mm_struct *mm, | 22 | static inline int is_hugepage_only_range(struct mm_struct *mm, |
diff --git a/arch/tile/include/asm/irqflags.h b/arch/tile/include/asm/irqflags.h index 241c0bb60b12..c96f9bbb760d 100644 --- a/arch/tile/include/asm/irqflags.h +++ b/arch/tile/include/asm/irqflags.h | |||
@@ -40,7 +40,15 @@ | |||
40 | #include <asm/percpu.h> | 40 | #include <asm/percpu.h> |
41 | #include <arch/spr_def.h> | 41 | #include <arch/spr_def.h> |
42 | 42 | ||
43 | /* Set and clear kernel interrupt masks. */ | 43 | /* |
44 | * Set and clear kernel interrupt masks. | ||
45 | * | ||
46 | * NOTE: __insn_mtspr() is a compiler builtin marked as a memory | ||
47 | * clobber. We rely on it being equivalent to a compiler barrier in | ||
48 | * this code since arch_local_irq_save() and friends must act as | ||
49 | * compiler barriers. This compiler semantic is baked into enough | ||
50 | * places that the compiler will maintain it going forward. | ||
51 | */ | ||
44 | #if CHIP_HAS_SPLIT_INTR_MASK() | 52 | #if CHIP_HAS_SPLIT_INTR_MASK() |
45 | #if INT_PERF_COUNT < 32 || INT_AUX_PERF_COUNT < 32 || INT_MEM_ERROR >= 32 | 53 | #if INT_PERF_COUNT < 32 || INT_AUX_PERF_COUNT < 32 || INT_MEM_ERROR >= 32 |
46 | # error Fix assumptions about which word various interrupts are in | 54 | # error Fix assumptions about which word various interrupts are in |
diff --git a/arch/tile/kernel/early_printk.c b/arch/tile/kernel/early_printk.c index afb9c9a0d887..34d72a151bf3 100644 --- a/arch/tile/kernel/early_printk.c +++ b/arch/tile/kernel/early_printk.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
19 | #include <linux/irqflags.h> | 19 | #include <linux/irqflags.h> |
20 | #include <linux/printk.h> | ||
20 | #include <asm/setup.h> | 21 | #include <asm/setup.h> |
21 | #include <hv/hypervisor.h> | 22 | #include <hv/hypervisor.h> |
22 | 23 | ||
@@ -33,25 +34,8 @@ static struct console early_hv_console = { | |||
33 | }; | 34 | }; |
34 | 35 | ||
35 | /* Direct interface for emergencies */ | 36 | /* Direct interface for emergencies */ |
36 | static struct console *early_console = &early_hv_console; | ||
37 | static int early_console_initialized; | ||
38 | static int early_console_complete; | 37 | static int early_console_complete; |
39 | 38 | ||
40 | static void early_vprintk(const char *fmt, va_list ap) | ||
41 | { | ||
42 | char buf[512]; | ||
43 | int n = vscnprintf(buf, sizeof(buf), fmt, ap); | ||
44 | early_console->write(early_console, buf, n); | ||
45 | } | ||
46 | |||
47 | void early_printk(const char *fmt, ...) | ||
48 | { | ||
49 | va_list ap; | ||
50 | va_start(ap, fmt); | ||
51 | early_vprintk(fmt, ap); | ||
52 | va_end(ap); | ||
53 | } | ||
54 | |||
55 | void early_panic(const char *fmt, ...) | 39 | void early_panic(const char *fmt, ...) |
56 | { | 40 | { |
57 | va_list ap; | 41 | va_list ap; |
@@ -69,14 +53,13 @@ static int __initdata keep_early; | |||
69 | 53 | ||
70 | static int __init setup_early_printk(char *str) | 54 | static int __init setup_early_printk(char *str) |
71 | { | 55 | { |
72 | if (early_console_initialized) | 56 | if (early_console) |
73 | return 1; | 57 | return 1; |
74 | 58 | ||
75 | if (str != NULL && strncmp(str, "keep", 4) == 0) | 59 | if (str != NULL && strncmp(str, "keep", 4) == 0) |
76 | keep_early = 1; | 60 | keep_early = 1; |
77 | 61 | ||
78 | early_console = &early_hv_console; | 62 | early_console = &early_hv_console; |
79 | early_console_initialized = 1; | ||
80 | register_console(early_console); | 63 | register_console(early_console); |
81 | 64 | ||
82 | return 0; | 65 | return 0; |
@@ -85,12 +68,12 @@ static int __init setup_early_printk(char *str) | |||
85 | void __init disable_early_printk(void) | 68 | void __init disable_early_printk(void) |
86 | { | 69 | { |
87 | early_console_complete = 1; | 70 | early_console_complete = 1; |
88 | if (!early_console_initialized || !early_console) | 71 | if (!early_console) |
89 | return; | 72 | return; |
90 | if (!keep_early) { | 73 | if (!keep_early) { |
91 | early_printk("disabling early console\n"); | 74 | early_printk("disabling early console\n"); |
92 | unregister_console(early_console); | 75 | unregister_console(early_console); |
93 | early_console_initialized = 0; | 76 | early_console = NULL; |
94 | } else { | 77 | } else { |
95 | early_printk("keeping early console\n"); | 78 | early_printk("keeping early console\n"); |
96 | } | 79 | } |
@@ -98,7 +81,7 @@ void __init disable_early_printk(void) | |||
98 | 81 | ||
99 | void warn_early_printk(void) | 82 | void warn_early_printk(void) |
100 | { | 83 | { |
101 | if (early_console_complete || early_console_initialized) | 84 | if (early_console_complete || early_console) |
102 | return; | 85 | return; |
103 | early_printk("\ | 86 | early_printk("\ |
104 | Machine shutting down before console output is fully initialized.\n\ | 87 | Machine shutting down before console output is fully initialized.\n\ |
diff --git a/arch/tile/mm/pgtable.c b/arch/tile/mm/pgtable.c index b3b4972c2451..dfd63ce87327 100644 --- a/arch/tile/mm/pgtable.c +++ b/arch/tile/mm/pgtable.c | |||
@@ -592,12 +592,7 @@ void iounmap(volatile void __iomem *addr_in) | |||
592 | in parallel. Reuse of the virtual address is prevented by | 592 | in parallel. Reuse of the virtual address is prevented by |
593 | leaving it in the global lists until we're done with it. | 593 | leaving it in the global lists until we're done with it. |
594 | cpa takes care of the direct mappings. */ | 594 | cpa takes care of the direct mappings. */ |
595 | read_lock(&vmlist_lock); | 595 | p = find_vm_area((void *)addr); |
596 | for (p = vmlist; p; p = p->next) { | ||
597 | if (p->addr == addr) | ||
598 | break; | ||
599 | } | ||
600 | read_unlock(&vmlist_lock); | ||
601 | 596 | ||
602 | if (!p) { | 597 | if (!p) { |
603 | pr_err("iounmap: bad address %p\n", addr); | 598 | pr_err("iounmap: bad address %p\n", addr); |
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 80b47cb71e0a..acbe6c67afba 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c | |||
@@ -568,11 +568,7 @@ void chan_interrupt(struct line *line, int irq) | |||
568 | reactivate_fd(chan->fd, irq); | 568 | reactivate_fd(chan->fd, irq); |
569 | if (err == -EIO) { | 569 | if (err == -EIO) { |
570 | if (chan->primary) { | 570 | if (chan->primary) { |
571 | struct tty_struct *tty = tty_port_tty_get(&line->port); | 571 | tty_port_tty_hangup(&line->port, false); |
572 | if (tty != NULL) { | ||
573 | tty_hangup(tty); | ||
574 | tty_kref_put(tty); | ||
575 | } | ||
576 | if (line->chan_out != chan) | 572 | if (line->chan_out != chan) |
577 | close_one_chan(line->chan_out, 1); | 573 | close_one_chan(line->chan_out, 1); |
578 | } | 574 | } |
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index be541cf69fd2..8035145f043b 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -248,7 +248,6 @@ static irqreturn_t line_write_interrupt(int irq, void *data) | |||
248 | { | 248 | { |
249 | struct chan *chan = data; | 249 | struct chan *chan = data; |
250 | struct line *line = chan->line; | 250 | struct line *line = chan->line; |
251 | struct tty_struct *tty; | ||
252 | int err; | 251 | int err; |
253 | 252 | ||
254 | /* | 253 | /* |
@@ -267,12 +266,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data) | |||
267 | } | 266 | } |
268 | spin_unlock(&line->lock); | 267 | spin_unlock(&line->lock); |
269 | 268 | ||
270 | tty = tty_port_tty_get(&line->port); | 269 | tty_port_tty_wakeup(&line->port); |
271 | if (tty == NULL) | ||
272 | return IRQ_NONE; | ||
273 | |||
274 | tty_wakeup(tty); | ||
275 | tty_kref_put(tty); | ||
276 | 270 | ||
277 | return IRQ_HANDLED; | 271 | return IRQ_HANDLED; |
278 | } | 272 | } |
diff --git a/arch/um/kernel/early_printk.c b/arch/um/kernel/early_printk.c index 49480f092456..4a0800bc37b2 100644 --- a/arch/um/kernel/early_printk.c +++ b/arch/um/kernel/early_printk.c | |||
@@ -16,7 +16,7 @@ static void early_console_write(struct console *con, const char *s, unsigned int | |||
16 | um_early_printk(s, n); | 16 | um_early_printk(s, n); |
17 | } | 17 | } |
18 | 18 | ||
19 | static struct console early_console = { | 19 | static struct console early_console_dev = { |
20 | .name = "earlycon", | 20 | .name = "earlycon", |
21 | .write = early_console_write, | 21 | .write = early_console_write, |
22 | .flags = CON_BOOT, | 22 | .flags = CON_BOOT, |
@@ -25,8 +25,10 @@ static struct console early_console = { | |||
25 | 25 | ||
26 | static int __init setup_early_printk(char *buf) | 26 | static int __init setup_early_printk(char *buf) |
27 | { | 27 | { |
28 | register_console(&early_console); | 28 | if (!early_console) { |
29 | 29 | early_console = &early_console_dev; | |
30 | register_console(&early_console_dev); | ||
31 | } | ||
30 | return 0; | 32 | return 0; |
31 | } | 33 | } |
32 | 34 | ||
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index 5abcbfbe7e25..9df292b270a8 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c | |||
@@ -42,17 +42,12 @@ static unsigned long brk_end; | |||
42 | static void setup_highmem(unsigned long highmem_start, | 42 | static void setup_highmem(unsigned long highmem_start, |
43 | unsigned long highmem_len) | 43 | unsigned long highmem_len) |
44 | { | 44 | { |
45 | struct page *page; | ||
46 | unsigned long highmem_pfn; | 45 | unsigned long highmem_pfn; |
47 | int i; | 46 | int i; |
48 | 47 | ||
49 | highmem_pfn = __pa(highmem_start) >> PAGE_SHIFT; | 48 | highmem_pfn = __pa(highmem_start) >> PAGE_SHIFT; |
50 | for (i = 0; i < highmem_len >> PAGE_SHIFT; i++) { | 49 | for (i = 0; i < highmem_len >> PAGE_SHIFT; i++) |
51 | page = &mem_map[highmem_pfn + i]; | 50 | free_highmem_page(&mem_map[highmem_pfn + i]); |
52 | ClearPageReserved(page); | ||
53 | init_page_count(page); | ||
54 | __free_page(page); | ||
55 | } | ||
56 | } | 51 | } |
57 | #endif | 52 | #endif |
58 | 53 | ||
@@ -73,18 +68,13 @@ void __init mem_init(void) | |||
73 | totalram_pages = free_all_bootmem(); | 68 | totalram_pages = free_all_bootmem(); |
74 | max_low_pfn = totalram_pages; | 69 | max_low_pfn = totalram_pages; |
75 | #ifdef CONFIG_HIGHMEM | 70 | #ifdef CONFIG_HIGHMEM |
76 | totalhigh_pages = highmem >> PAGE_SHIFT; | 71 | setup_highmem(end_iomem, highmem); |
77 | totalram_pages += totalhigh_pages; | ||
78 | #endif | 72 | #endif |
79 | num_physpages = totalram_pages; | 73 | num_physpages = totalram_pages; |
80 | max_pfn = totalram_pages; | 74 | max_pfn = totalram_pages; |
81 | printk(KERN_INFO "Memory: %luk available\n", | 75 | printk(KERN_INFO "Memory: %luk available\n", |
82 | nr_free_pages() << (PAGE_SHIFT-10)); | 76 | nr_free_pages() << (PAGE_SHIFT-10)); |
83 | kmalloc_ok = 1; | 77 | kmalloc_ok = 1; |
84 | |||
85 | #ifdef CONFIG_HIGHMEM | ||
86 | setup_highmem(end_iomem, highmem); | ||
87 | #endif | ||
88 | } | 78 | } |
89 | 79 | ||
90 | /* | 80 | /* |
@@ -254,15 +244,7 @@ void free_initmem(void) | |||
254 | #ifdef CONFIG_BLK_DEV_INITRD | 244 | #ifdef CONFIG_BLK_DEV_INITRD |
255 | void free_initrd_mem(unsigned long start, unsigned long end) | 245 | void free_initrd_mem(unsigned long start, unsigned long end) |
256 | { | 246 | { |
257 | if (start < end) | 247 | free_reserved_area(start, end, 0, "initrd"); |
258 | printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", | ||
259 | (end - start) >> 10); | ||
260 | for (; start < end; start += PAGE_SIZE) { | ||
261 | ClearPageReserved(virt_to_page(start)); | ||
262 | init_page_count(virt_to_page(start)); | ||
263 | free_page(start); | ||
264 | totalram_pages++; | ||
265 | } | ||
266 | } | 248 | } |
267 | #endif | 249 | #endif |
268 | 250 | ||
diff --git a/arch/unicore32/kernel/early_printk.c b/arch/unicore32/kernel/early_printk.c index 3922255f1fa8..9be0d5d02a9a 100644 --- a/arch/unicore32/kernel/early_printk.c +++ b/arch/unicore32/kernel/early_printk.c | |||
@@ -33,21 +33,17 @@ static struct console early_ocd_console = { | |||
33 | .index = -1, | 33 | .index = -1, |
34 | }; | 34 | }; |
35 | 35 | ||
36 | /* Direct interface for emergencies */ | ||
37 | static struct console *early_console = &early_ocd_console; | ||
38 | |||
39 | static int __initdata keep_early; | ||
40 | |||
41 | static int __init setup_early_printk(char *buf) | 36 | static int __init setup_early_printk(char *buf) |
42 | { | 37 | { |
43 | if (!buf) | 38 | int keep_early; |
39 | |||
40 | if (!buf || early_console) | ||
44 | return 0; | 41 | return 0; |
45 | 42 | ||
46 | if (strstr(buf, "keep")) | 43 | if (strstr(buf, "keep")) |
47 | keep_early = 1; | 44 | keep_early = 1; |
48 | 45 | ||
49 | if (!strncmp(buf, "ocd", 3)) | 46 | early_console = &early_ocd_console; |
50 | early_console = &early_ocd_console; | ||
51 | 47 | ||
52 | if (keep_early) | 48 | if (keep_early) |
53 | early_console->flags &= ~CON_BOOT; | 49 | early_console->flags &= ~CON_BOOT; |
diff --git a/arch/unicore32/mm/init.c b/arch/unicore32/mm/init.c index de186bde8975..63df12d71ce3 100644 --- a/arch/unicore32/mm/init.c +++ b/arch/unicore32/mm/init.c | |||
@@ -66,6 +66,9 @@ void show_mem(unsigned int filter) | |||
66 | printk(KERN_DEFAULT "Mem-info:\n"); | 66 | printk(KERN_DEFAULT "Mem-info:\n"); |
67 | show_free_areas(filter); | 67 | show_free_areas(filter); |
68 | 68 | ||
69 | if (filter & SHOW_MEM_FILTER_PAGE_COUNT) | ||
70 | return; | ||
71 | |||
69 | for_each_bank(i, mi) { | 72 | for_each_bank(i, mi) { |
70 | struct membank *bank = &mi->bank[i]; | 73 | struct membank *bank = &mi->bank[i]; |
71 | unsigned int pfn1, pfn2; | 74 | unsigned int pfn1, pfn2; |
@@ -313,24 +316,6 @@ void __init bootmem_init(void) | |||
313 | max_pfn = max_high - PHYS_PFN_OFFSET; | 316 | max_pfn = max_high - PHYS_PFN_OFFSET; |
314 | } | 317 | } |
315 | 318 | ||
316 | static inline int free_area(unsigned long pfn, unsigned long end, char *s) | ||
317 | { | ||
318 | unsigned int pages = 0, size = (end - pfn) << (PAGE_SHIFT - 10); | ||
319 | |||
320 | for (; pfn < end; pfn++) { | ||
321 | struct page *page = pfn_to_page(pfn); | ||
322 | ClearPageReserved(page); | ||
323 | init_page_count(page); | ||
324 | __free_page(page); | ||
325 | pages++; | ||
326 | } | ||
327 | |||
328 | if (size && s) | ||
329 | printk(KERN_INFO "Freeing %s memory: %dK\n", s, size); | ||
330 | |||
331 | return pages; | ||
332 | } | ||
333 | |||
334 | static inline void | 319 | static inline void |
335 | free_memmap(unsigned long start_pfn, unsigned long end_pfn) | 320 | free_memmap(unsigned long start_pfn, unsigned long end_pfn) |
336 | { | 321 | { |
@@ -404,9 +389,9 @@ void __init mem_init(void) | |||
404 | 389 | ||
405 | max_mapnr = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map; | 390 | max_mapnr = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map; |
406 | 391 | ||
407 | /* this will put all unused low memory onto the freelists */ | ||
408 | free_unused_memmap(&meminfo); | 392 | free_unused_memmap(&meminfo); |
409 | 393 | ||
394 | /* this will put all unused low memory onto the freelists */ | ||
410 | totalram_pages += free_all_bootmem(); | 395 | totalram_pages += free_all_bootmem(); |
411 | 396 | ||
412 | reserved_pages = free_pages = 0; | 397 | reserved_pages = free_pages = 0; |
@@ -491,9 +476,7 @@ void __init mem_init(void) | |||
491 | 476 | ||
492 | void free_initmem(void) | 477 | void free_initmem(void) |
493 | { | 478 | { |
494 | totalram_pages += free_area(__phys_to_pfn(__pa(__init_begin)), | 479 | free_initmem_default(0); |
495 | __phys_to_pfn(__pa(__init_end)), | ||
496 | "init"); | ||
497 | } | 480 | } |
498 | 481 | ||
499 | #ifdef CONFIG_BLK_DEV_INITRD | 482 | #ifdef CONFIG_BLK_DEV_INITRD |
@@ -503,9 +486,7 @@ static int keep_initrd; | |||
503 | void free_initrd_mem(unsigned long start, unsigned long end) | 486 | void free_initrd_mem(unsigned long start, unsigned long end) |
504 | { | 487 | { |
505 | if (!keep_initrd) | 488 | if (!keep_initrd) |
506 | totalram_pages += free_area(__phys_to_pfn(__pa(start)), | 489 | free_reserved_area(start, end, 0, "initrd"); |
507 | __phys_to_pfn(__pa(end)), | ||
508 | "initrd"); | ||
509 | } | 490 | } |
510 | 491 | ||
511 | static int __init keepinitrd_setup(char *__unused) | 492 | static int __init keepinitrd_setup(char *__unused) |
diff --git a/arch/unicore32/mm/ioremap.c b/arch/unicore32/mm/ioremap.c index b7a605597b08..13068ee22f33 100644 --- a/arch/unicore32/mm/ioremap.c +++ b/arch/unicore32/mm/ioremap.c | |||
@@ -235,7 +235,7 @@ EXPORT_SYMBOL(__uc32_ioremap_cached); | |||
235 | void __uc32_iounmap(volatile void __iomem *io_addr) | 235 | void __uc32_iounmap(volatile void __iomem *io_addr) |
236 | { | 236 | { |
237 | void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr); | 237 | void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr); |
238 | struct vm_struct **p, *tmp; | 238 | struct vm_struct *vm; |
239 | 239 | ||
240 | /* | 240 | /* |
241 | * If this is a section based mapping we need to handle it | 241 | * If this is a section based mapping we need to handle it |
@@ -244,17 +244,10 @@ void __uc32_iounmap(volatile void __iomem *io_addr) | |||
244 | * all the mappings before the area can be reclaimed | 244 | * all the mappings before the area can be reclaimed |
245 | * by someone else. | 245 | * by someone else. |
246 | */ | 246 | */ |
247 | write_lock(&vmlist_lock); | 247 | vm = find_vm_area(addr); |
248 | for (p = &vmlist ; (tmp = *p) ; p = &tmp->next) { | 248 | if (vm && (vm->flags & VM_IOREMAP) && |
249 | if ((tmp->flags & VM_IOREMAP) && (tmp->addr == addr)) { | 249 | (vm->flags & VM_UNICORE_SECTION_MAPPING)) |
250 | if (tmp->flags & VM_UNICORE_SECTION_MAPPING) { | 250 | unmap_area_sections((unsigned long)vm->addr, vm->size); |
251 | unmap_area_sections((unsigned long)tmp->addr, | ||
252 | tmp->size); | ||
253 | } | ||
254 | break; | ||
255 | } | ||
256 | } | ||
257 | write_unlock(&vmlist_lock); | ||
258 | 251 | ||
259 | vunmap(addr); | 252 | vunmap(addr); |
260 | } | 253 | } |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index fcf293994992..d75b48c11be5 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -1546,6 +1546,7 @@ config X86_SMAP | |||
1546 | config EFI | 1546 | config EFI |
1547 | bool "EFI runtime service support" | 1547 | bool "EFI runtime service support" |
1548 | depends on ACPI | 1548 | depends on ACPI |
1549 | select UCS2_STRING | ||
1549 | ---help--- | 1550 | ---help--- |
1550 | This enables the kernel to use EFI runtime services that are | 1551 | This enables the kernel to use EFI runtime services that are |
1551 | available (such as the EFI variable services). | 1552 | available (such as the EFI variable services). |
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index c205035a6b96..35ee62fccf98 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c | |||
@@ -251,6 +251,51 @@ static void find_bits(unsigned long mask, u8 *pos, u8 *size) | |||
251 | *size = len; | 251 | *size = len; |
252 | } | 252 | } |
253 | 253 | ||
254 | static efi_status_t setup_efi_vars(struct boot_params *params) | ||
255 | { | ||
256 | struct setup_data *data; | ||
257 | struct efi_var_bootdata *efidata; | ||
258 | u64 store_size, remaining_size, var_size; | ||
259 | efi_status_t status; | ||
260 | |||
261 | if (sys_table->runtime->hdr.revision < EFI_2_00_SYSTEM_TABLE_REVISION) | ||
262 | return EFI_UNSUPPORTED; | ||
263 | |||
264 | data = (struct setup_data *)(unsigned long)params->hdr.setup_data; | ||
265 | |||
266 | while (data && data->next) | ||
267 | data = (struct setup_data *)(unsigned long)data->next; | ||
268 | |||
269 | status = efi_call_phys4((void *)sys_table->runtime->query_variable_info, | ||
270 | EFI_VARIABLE_NON_VOLATILE | | ||
271 | EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||
272 | EFI_VARIABLE_RUNTIME_ACCESS, &store_size, | ||
273 | &remaining_size, &var_size); | ||
274 | |||
275 | if (status != EFI_SUCCESS) | ||
276 | return status; | ||
277 | |||
278 | status = efi_call_phys3(sys_table->boottime->allocate_pool, | ||
279 | EFI_LOADER_DATA, sizeof(*efidata), &efidata); | ||
280 | |||
281 | if (status != EFI_SUCCESS) | ||
282 | return status; | ||
283 | |||
284 | efidata->data.type = SETUP_EFI_VARS; | ||
285 | efidata->data.len = sizeof(struct efi_var_bootdata) - | ||
286 | sizeof(struct setup_data); | ||
287 | efidata->data.next = 0; | ||
288 | efidata->store_size = store_size; | ||
289 | efidata->remaining_size = remaining_size; | ||
290 | efidata->max_var_size = var_size; | ||
291 | |||
292 | if (data) | ||
293 | data->next = (unsigned long)efidata; | ||
294 | else | ||
295 | params->hdr.setup_data = (unsigned long)efidata; | ||
296 | |||
297 | } | ||
298 | |||
254 | static efi_status_t setup_efi_pci(struct boot_params *params) | 299 | static efi_status_t setup_efi_pci(struct boot_params *params) |
255 | { | 300 | { |
256 | efi_pci_io_protocol *pci; | 301 | efi_pci_io_protocol *pci; |
@@ -1157,6 +1202,8 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table, | |||
1157 | 1202 | ||
1158 | setup_graphics(boot_params); | 1203 | setup_graphics(boot_params); |
1159 | 1204 | ||
1205 | setup_efi_vars(boot_params); | ||
1206 | |||
1160 | setup_efi_pci(boot_params); | 1207 | setup_efi_pci(boot_params); |
1161 | 1208 | ||
1162 | status = efi_call_phys3(sys_table->boottime->allocate_pool, | 1209 | status = efi_call_phys3(sys_table->boottime->allocate_pool, |
diff --git a/arch/x86/include/asm/context_tracking.h b/arch/x86/include/asm/context_tracking.h index 1616562683e9..1fe49704b146 100644 --- a/arch/x86/include/asm/context_tracking.h +++ b/arch/x86/include/asm/context_tracking.h | |||
@@ -1,31 +1,10 @@ | |||
1 | #ifndef _ASM_X86_CONTEXT_TRACKING_H | 1 | #ifndef _ASM_X86_CONTEXT_TRACKING_H |
2 | #define _ASM_X86_CONTEXT_TRACKING_H | 2 | #define _ASM_X86_CONTEXT_TRACKING_H |
3 | 3 | ||
4 | #ifndef __ASSEMBLY__ | ||
5 | #include <linux/context_tracking.h> | ||
6 | #include <asm/ptrace.h> | ||
7 | |||
8 | static inline void exception_enter(struct pt_regs *regs) | ||
9 | { | ||
10 | user_exit(); | ||
11 | } | ||
12 | |||
13 | static inline void exception_exit(struct pt_regs *regs) | ||
14 | { | ||
15 | #ifdef CONFIG_CONTEXT_TRACKING | ||
16 | if (user_mode(regs)) | ||
17 | user_enter(); | ||
18 | #endif | ||
19 | } | ||
20 | |||
21 | #else /* __ASSEMBLY__ */ | ||
22 | |||
23 | #ifdef CONFIG_CONTEXT_TRACKING | 4 | #ifdef CONFIG_CONTEXT_TRACKING |
24 | # define SCHEDULE_USER call schedule_user | 5 | # define SCHEDULE_USER call schedule_user |
25 | #else | 6 | #else |
26 | # define SCHEDULE_USER call schedule | 7 | # define SCHEDULE_USER call schedule |
27 | #endif | 8 | #endif |
28 | 9 | ||
29 | #endif /* !__ASSEMBLY__ */ | ||
30 | |||
31 | #endif | 10 | #endif |
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 93fe929d1cee..ac10df72925b 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h | |||
@@ -168,6 +168,7 @@ | |||
168 | #define X86_FEATURE_TOPOEXT (6*32+22) /* topology extensions CPUID leafs */ | 168 | #define X86_FEATURE_TOPOEXT (6*32+22) /* topology extensions CPUID leafs */ |
169 | #define X86_FEATURE_PERFCTR_CORE (6*32+23) /* core performance counter extensions */ | 169 | #define X86_FEATURE_PERFCTR_CORE (6*32+23) /* core performance counter extensions */ |
170 | #define X86_FEATURE_PERFCTR_NB (6*32+24) /* NB performance counter extensions */ | 170 | #define X86_FEATURE_PERFCTR_NB (6*32+24) /* NB performance counter extensions */ |
171 | #define X86_FEATURE_PERFCTR_L2 (6*32+28) /* L2 performance counter extensions */ | ||
171 | 172 | ||
172 | /* | 173 | /* |
173 | * Auxiliary flags: Linux defined - For features scattered in various | 174 | * Auxiliary flags: Linux defined - For features scattered in various |
@@ -311,6 +312,7 @@ extern const char * const x86_power_flags[32]; | |||
311 | #define cpu_has_pclmulqdq boot_cpu_has(X86_FEATURE_PCLMULQDQ) | 312 | #define cpu_has_pclmulqdq boot_cpu_has(X86_FEATURE_PCLMULQDQ) |
312 | #define cpu_has_perfctr_core boot_cpu_has(X86_FEATURE_PERFCTR_CORE) | 313 | #define cpu_has_perfctr_core boot_cpu_has(X86_FEATURE_PERFCTR_CORE) |
313 | #define cpu_has_perfctr_nb boot_cpu_has(X86_FEATURE_PERFCTR_NB) | 314 | #define cpu_has_perfctr_nb boot_cpu_has(X86_FEATURE_PERFCTR_NB) |
315 | #define cpu_has_perfctr_l2 boot_cpu_has(X86_FEATURE_PERFCTR_L2) | ||
314 | #define cpu_has_cx8 boot_cpu_has(X86_FEATURE_CX8) | 316 | #define cpu_has_cx8 boot_cpu_has(X86_FEATURE_CX8) |
315 | #define cpu_has_cx16 boot_cpu_has(X86_FEATURE_CX16) | 317 | #define cpu_has_cx16 boot_cpu_has(X86_FEATURE_CX16) |
316 | #define cpu_has_eager_fpu boot_cpu_has(X86_FEATURE_EAGER_FPU) | 318 | #define cpu_has_eager_fpu boot_cpu_has(X86_FEATURE_EAGER_FPU) |
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 60c89f30c727..2fb5d5884e23 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h | |||
@@ -102,6 +102,13 @@ extern void efi_call_phys_epilog(void); | |||
102 | extern void efi_unmap_memmap(void); | 102 | extern void efi_unmap_memmap(void); |
103 | extern void efi_memory_uc(u64 addr, unsigned long size); | 103 | extern void efi_memory_uc(u64 addr, unsigned long size); |
104 | 104 | ||
105 | struct efi_var_bootdata { | ||
106 | struct setup_data data; | ||
107 | u64 store_size; | ||
108 | u64 remaining_size; | ||
109 | u64 max_var_size; | ||
110 | }; | ||
111 | |||
105 | #ifdef CONFIG_EFI | 112 | #ifdef CONFIG_EFI |
106 | 113 | ||
107 | static inline bool efi_is_native(void) | 114 | static inline bool efi_is_native(void) |
diff --git a/arch/x86/include/asm/hugetlb.h b/arch/x86/include/asm/hugetlb.h index bdd35dbd0605..a8091216963b 100644 --- a/arch/x86/include/asm/hugetlb.h +++ b/arch/x86/include/asm/hugetlb.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define _ASM_X86_HUGETLB_H | 2 | #define _ASM_X86_HUGETLB_H |
3 | 3 | ||
4 | #include <asm/page.h> | 4 | #include <asm/page.h> |
5 | #include <asm-generic/hugetlb.h> | ||
5 | 6 | ||
6 | 7 | ||
7 | static inline int is_hugepage_only_range(struct mm_struct *mm, | 8 | static inline int is_hugepage_only_range(struct mm_struct *mm, |
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h index 5edd1742cfd0..7361e47db79f 100644 --- a/arch/x86/include/asm/paravirt.h +++ b/arch/x86/include/asm/paravirt.h | |||
@@ -703,7 +703,10 @@ static inline void arch_leave_lazy_mmu_mode(void) | |||
703 | PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave); | 703 | PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave); |
704 | } | 704 | } |
705 | 705 | ||
706 | void arch_flush_lazy_mmu_mode(void); | 706 | static inline void arch_flush_lazy_mmu_mode(void) |
707 | { | ||
708 | PVOP_VCALL0(pv_mmu_ops.lazy_mode.flush); | ||
709 | } | ||
707 | 710 | ||
708 | static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, | 711 | static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx, |
709 | phys_addr_t phys, pgprot_t flags) | 712 | phys_addr_t phys, pgprot_t flags) |
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h index 142236ed83af..b3b0ec1dac86 100644 --- a/arch/x86/include/asm/paravirt_types.h +++ b/arch/x86/include/asm/paravirt_types.h | |||
@@ -91,6 +91,7 @@ struct pv_lazy_ops { | |||
91 | /* Set deferred update mode, used for batching operations. */ | 91 | /* Set deferred update mode, used for batching operations. */ |
92 | void (*enter)(void); | 92 | void (*enter)(void); |
93 | void (*leave)(void); | 93 | void (*leave)(void); |
94 | void (*flush)(void); | ||
94 | }; | 95 | }; |
95 | 96 | ||
96 | struct pv_time_ops { | 97 | struct pv_time_ops { |
@@ -679,6 +680,7 @@ void paravirt_end_context_switch(struct task_struct *next); | |||
679 | 680 | ||
680 | void paravirt_enter_lazy_mmu(void); | 681 | void paravirt_enter_lazy_mmu(void); |
681 | void paravirt_leave_lazy_mmu(void); | 682 | void paravirt_leave_lazy_mmu(void); |
683 | void paravirt_flush_lazy_mmu(void); | ||
682 | 684 | ||
683 | void _paravirt_nop(void); | 685 | void _paravirt_nop(void); |
684 | u32 _paravirt_ident_32(u32); | 686 | u32 _paravirt_ident_32(u32); |
diff --git a/arch/x86/include/asm/perf_event_p4.h b/arch/x86/include/asm/perf_event_p4.h index 4f7e67e2345e..85e13ccf15c4 100644 --- a/arch/x86/include/asm/perf_event_p4.h +++ b/arch/x86/include/asm/perf_event_p4.h | |||
@@ -24,45 +24,45 @@ | |||
24 | #define ARCH_P4_CNTRVAL_MASK ((1ULL << ARCH_P4_CNTRVAL_BITS) - 1) | 24 | #define ARCH_P4_CNTRVAL_MASK ((1ULL << ARCH_P4_CNTRVAL_BITS) - 1) |
25 | #define ARCH_P4_UNFLAGGED_BIT ((1ULL) << (ARCH_P4_CNTRVAL_BITS - 1)) | 25 | #define ARCH_P4_UNFLAGGED_BIT ((1ULL) << (ARCH_P4_CNTRVAL_BITS - 1)) |
26 | 26 | ||
27 | #define P4_ESCR_EVENT_MASK 0x7e000000U | 27 | #define P4_ESCR_EVENT_MASK 0x7e000000ULL |
28 | #define P4_ESCR_EVENT_SHIFT 25 | 28 | #define P4_ESCR_EVENT_SHIFT 25 |
29 | #define P4_ESCR_EVENTMASK_MASK 0x01fffe00U | 29 | #define P4_ESCR_EVENTMASK_MASK 0x01fffe00ULL |
30 | #define P4_ESCR_EVENTMASK_SHIFT 9 | 30 | #define P4_ESCR_EVENTMASK_SHIFT 9 |
31 | #define P4_ESCR_TAG_MASK 0x000001e0U | 31 | #define P4_ESCR_TAG_MASK 0x000001e0ULL |
32 | #define P4_ESCR_TAG_SHIFT 5 | 32 | #define P4_ESCR_TAG_SHIFT 5 |
33 | #define P4_ESCR_TAG_ENABLE 0x00000010U | 33 | #define P4_ESCR_TAG_ENABLE 0x00000010ULL |
34 | #define P4_ESCR_T0_OS 0x00000008U | 34 | #define P4_ESCR_T0_OS 0x00000008ULL |
35 | #define P4_ESCR_T0_USR 0x00000004U | 35 | #define P4_ESCR_T0_USR 0x00000004ULL |
36 | #define P4_ESCR_T1_OS 0x00000002U | 36 | #define P4_ESCR_T1_OS 0x00000002ULL |
37 | #define P4_ESCR_T1_USR 0x00000001U | 37 | #define P4_ESCR_T1_USR 0x00000001ULL |
38 | 38 | ||
39 | #define P4_ESCR_EVENT(v) ((v) << P4_ESCR_EVENT_SHIFT) | 39 | #define P4_ESCR_EVENT(v) ((v) << P4_ESCR_EVENT_SHIFT) |
40 | #define P4_ESCR_EMASK(v) ((v) << P4_ESCR_EVENTMASK_SHIFT) | 40 | #define P4_ESCR_EMASK(v) ((v) << P4_ESCR_EVENTMASK_SHIFT) |
41 | #define P4_ESCR_TAG(v) ((v) << P4_ESCR_TAG_SHIFT) | 41 | #define P4_ESCR_TAG(v) ((v) << P4_ESCR_TAG_SHIFT) |
42 | 42 | ||
43 | #define P4_CCCR_OVF 0x80000000U | 43 | #define P4_CCCR_OVF 0x80000000ULL |
44 | #define P4_CCCR_CASCADE 0x40000000U | 44 | #define P4_CCCR_CASCADE 0x40000000ULL |
45 | #define P4_CCCR_OVF_PMI_T0 0x04000000U | 45 | #define P4_CCCR_OVF_PMI_T0 0x04000000ULL |
46 | #define P4_CCCR_OVF_PMI_T1 0x08000000U | 46 | #define P4_CCCR_OVF_PMI_T1 0x08000000ULL |
47 | #define P4_CCCR_FORCE_OVF 0x02000000U | 47 | #define P4_CCCR_FORCE_OVF 0x02000000ULL |
48 | #define P4_CCCR_EDGE 0x01000000U | 48 | #define P4_CCCR_EDGE 0x01000000ULL |
49 | #define P4_CCCR_THRESHOLD_MASK 0x00f00000U | 49 | #define P4_CCCR_THRESHOLD_MASK 0x00f00000ULL |
50 | #define P4_CCCR_THRESHOLD_SHIFT 20 | 50 | #define P4_CCCR_THRESHOLD_SHIFT 20 |
51 | #define P4_CCCR_COMPLEMENT 0x00080000U | 51 | #define P4_CCCR_COMPLEMENT 0x00080000ULL |
52 | #define P4_CCCR_COMPARE 0x00040000U | 52 | #define P4_CCCR_COMPARE 0x00040000ULL |
53 | #define P4_CCCR_ESCR_SELECT_MASK 0x0000e000U | 53 | #define P4_CCCR_ESCR_SELECT_MASK 0x0000e000ULL |
54 | #define P4_CCCR_ESCR_SELECT_SHIFT 13 | 54 | #define P4_CCCR_ESCR_SELECT_SHIFT 13 |
55 | #define P4_CCCR_ENABLE 0x00001000U | 55 | #define P4_CCCR_ENABLE 0x00001000ULL |
56 | #define P4_CCCR_THREAD_SINGLE 0x00010000U | 56 | #define P4_CCCR_THREAD_SINGLE 0x00010000ULL |
57 | #define P4_CCCR_THREAD_BOTH 0x00020000U | 57 | #define P4_CCCR_THREAD_BOTH 0x00020000ULL |
58 | #define P4_CCCR_THREAD_ANY 0x00030000U | 58 | #define P4_CCCR_THREAD_ANY 0x00030000ULL |
59 | #define P4_CCCR_RESERVED 0x00000fffU | 59 | #define P4_CCCR_RESERVED 0x00000fffULL |
60 | 60 | ||
61 | #define P4_CCCR_THRESHOLD(v) ((v) << P4_CCCR_THRESHOLD_SHIFT) | 61 | #define P4_CCCR_THRESHOLD(v) ((v) << P4_CCCR_THRESHOLD_SHIFT) |
62 | #define P4_CCCR_ESEL(v) ((v) << P4_CCCR_ESCR_SELECT_SHIFT) | 62 | #define P4_CCCR_ESEL(v) ((v) << P4_CCCR_ESCR_SELECT_SHIFT) |
63 | 63 | ||
64 | #define P4_GEN_ESCR_EMASK(class, name, bit) \ | 64 | #define P4_GEN_ESCR_EMASK(class, name, bit) \ |
65 | class##__##name = ((1 << bit) << P4_ESCR_EVENTMASK_SHIFT) | 65 | class##__##name = ((1ULL << bit) << P4_ESCR_EVENTMASK_SHIFT) |
66 | #define P4_ESCR_EMASK_BIT(class, name) class##__##name | 66 | #define P4_ESCR_EMASK_BIT(class, name) class##__##name |
67 | 67 | ||
68 | /* | 68 | /* |
@@ -107,7 +107,7 @@ | |||
107 | * P4_PEBS_CONFIG_MASK and related bits on | 107 | * P4_PEBS_CONFIG_MASK and related bits on |
108 | * modification.) | 108 | * modification.) |
109 | */ | 109 | */ |
110 | #define P4_CONFIG_ALIASABLE (1 << 9) | 110 | #define P4_CONFIG_ALIASABLE (1ULL << 9) |
111 | 111 | ||
112 | /* | 112 | /* |
113 | * The bits we allow to pass for RAW events | 113 | * The bits we allow to pass for RAW events |
@@ -784,17 +784,17 @@ enum P4_ESCR_EMASKS { | |||
784 | * Note we have UOP and PEBS bits reserved for now | 784 | * Note we have UOP and PEBS bits reserved for now |
785 | * just in case if we will need them once | 785 | * just in case if we will need them once |
786 | */ | 786 | */ |
787 | #define P4_PEBS_CONFIG_ENABLE (1 << 7) | 787 | #define P4_PEBS_CONFIG_ENABLE (1ULL << 7) |
788 | #define P4_PEBS_CONFIG_UOP_TAG (1 << 8) | 788 | #define P4_PEBS_CONFIG_UOP_TAG (1ULL << 8) |
789 | #define P4_PEBS_CONFIG_METRIC_MASK 0x3f | 789 | #define P4_PEBS_CONFIG_METRIC_MASK 0x3FLL |
790 | #define P4_PEBS_CONFIG_MASK 0xff | 790 | #define P4_PEBS_CONFIG_MASK 0xFFLL |
791 | 791 | ||
792 | /* | 792 | /* |
793 | * mem: Only counters MSR_IQ_COUNTER4 (16) and | 793 | * mem: Only counters MSR_IQ_COUNTER4 (16) and |
794 | * MSR_IQ_COUNTER5 (17) are allowed for PEBS sampling | 794 | * MSR_IQ_COUNTER5 (17) are allowed for PEBS sampling |
795 | */ | 795 | */ |
796 | #define P4_PEBS_ENABLE 0x02000000U | 796 | #define P4_PEBS_ENABLE 0x02000000ULL |
797 | #define P4_PEBS_ENABLE_UOP_TAG 0x01000000U | 797 | #define P4_PEBS_ENABLE_UOP_TAG 0x01000000ULL |
798 | 798 | ||
799 | #define p4_config_unpack_metric(v) (((u64)(v)) & P4_PEBS_CONFIG_METRIC_MASK) | 799 | #define p4_config_unpack_metric(v) (((u64)(v)) & P4_PEBS_CONFIG_METRIC_MASK) |
800 | #define p4_config_unpack_pebs(v) (((u64)(v)) & P4_PEBS_CONFIG_MASK) | 800 | #define p4_config_unpack_pebs(v) (((u64)(v)) & P4_PEBS_CONFIG_MASK) |
diff --git a/arch/x86/include/asm/tlb.h b/arch/x86/include/asm/tlb.h index 4fef20773b8f..c7797307fc2b 100644 --- a/arch/x86/include/asm/tlb.h +++ b/arch/x86/include/asm/tlb.h | |||
@@ -7,7 +7,7 @@ | |||
7 | 7 | ||
8 | #define tlb_flush(tlb) \ | 8 | #define tlb_flush(tlb) \ |
9 | { \ | 9 | { \ |
10 | if (tlb->fullmm == 0) \ | 10 | if (!tlb->fullmm && !tlb->need_flush_all) \ |
11 | flush_tlb_mm_range(tlb->mm, tlb->start, tlb->end, 0UL); \ | 11 | flush_tlb_mm_range(tlb->mm, tlb->start, tlb->end, 0UL); \ |
12 | else \ | 12 | else \ |
13 | flush_tlb_mm_range(tlb->mm, 0UL, TLB_FLUSH_ALL, 0UL); \ | 13 | flush_tlb_mm_range(tlb->mm, 0UL, TLB_FLUSH_ALL, 0UL); \ |
diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h index 8ff8be7835ab..6e5197910fd8 100644 --- a/arch/x86/include/asm/uprobes.h +++ b/arch/x86/include/asm/uprobes.h | |||
@@ -55,4 +55,5 @@ extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs); | |||
55 | extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); | 55 | extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); |
56 | extern int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data); | 56 | extern int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data); |
57 | extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs); | 57 | extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs); |
58 | extern unsigned long arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs); | ||
58 | #endif /* _ASM_UPROBES_H */ | 59 | #endif /* _ASM_UPROBES_H */ |
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h index c15ddaf90710..08744242b8d2 100644 --- a/arch/x86/include/uapi/asm/bootparam.h +++ b/arch/x86/include/uapi/asm/bootparam.h | |||
@@ -6,6 +6,7 @@ | |||
6 | #define SETUP_E820_EXT 1 | 6 | #define SETUP_E820_EXT 1 |
7 | #define SETUP_DTB 2 | 7 | #define SETUP_DTB 2 |
8 | #define SETUP_PCI 3 | 8 | #define SETUP_PCI 3 |
9 | #define SETUP_EFI_VARS 4 | ||
9 | 10 | ||
10 | /* ram_size flags */ | 11 | /* ram_size flags */ |
11 | #define RAMDISK_IMAGE_START_MASK 0x07FF | 12 | #define RAMDISK_IMAGE_START_MASK 0x07FF |
diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h index 7a060f4b411f..b5757885d7a4 100644 --- a/arch/x86/include/uapi/asm/msr-index.h +++ b/arch/x86/include/uapi/asm/msr-index.h | |||
@@ -72,6 +72,7 @@ | |||
72 | #define MSR_IA32_PEBS_ENABLE 0x000003f1 | 72 | #define MSR_IA32_PEBS_ENABLE 0x000003f1 |
73 | #define MSR_IA32_DS_AREA 0x00000600 | 73 | #define MSR_IA32_DS_AREA 0x00000600 |
74 | #define MSR_IA32_PERF_CAPABILITIES 0x00000345 | 74 | #define MSR_IA32_PERF_CAPABILITIES 0x00000345 |
75 | #define MSR_PEBS_LD_LAT_THRESHOLD 0x000003f6 | ||
75 | 76 | ||
76 | #define MSR_MTRRfix64K_00000 0x00000250 | 77 | #define MSR_MTRRfix64K_00000 0x00000250 |
77 | #define MSR_MTRRfix16K_80000 0x00000258 | 78 | #define MSR_MTRRfix16K_80000 0x00000258 |
@@ -195,6 +196,10 @@ | |||
195 | #define MSR_AMD64_IBSBRTARGET 0xc001103b | 196 | #define MSR_AMD64_IBSBRTARGET 0xc001103b |
196 | #define MSR_AMD64_IBS_REG_COUNT_MAX 8 /* includes MSR_AMD64_IBSBRTARGET */ | 197 | #define MSR_AMD64_IBS_REG_COUNT_MAX 8 /* includes MSR_AMD64_IBSBRTARGET */ |
197 | 198 | ||
199 | /* Fam 16h MSRs */ | ||
200 | #define MSR_F16H_L2I_PERF_CTL 0xc0010230 | ||
201 | #define MSR_F16H_L2I_PERF_CTR 0xc0010231 | ||
202 | |||
198 | /* Fam 15h MSRs */ | 203 | /* Fam 15h MSRs */ |
199 | #define MSR_F15H_PERF_CTL 0xc0010200 | 204 | #define MSR_F15H_PERF_CTL 0xc0010200 |
200 | #define MSR_F15H_PERF_CTR 0xc0010201 | 205 | #define MSR_F15H_PERF_CTR 0xc0010201 |
diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index a0e067d3d96c..deef0399fc78 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile | |||
@@ -31,7 +31,7 @@ obj-$(CONFIG_CPU_SUP_UMC_32) += umc.o | |||
31 | obj-$(CONFIG_PERF_EVENTS) += perf_event.o | 31 | obj-$(CONFIG_PERF_EVENTS) += perf_event.o |
32 | 32 | ||
33 | ifdef CONFIG_PERF_EVENTS | 33 | ifdef CONFIG_PERF_EVENTS |
34 | obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd.o | 34 | obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd.o perf_event_amd_uncore.o |
35 | obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_knc.o perf_event_p4.o | 35 | obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_knc.o perf_event_p4.o |
36 | obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o | 36 | obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o |
37 | obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_uncore.o | 37 | obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_uncore.o |
@@ -43,10 +43,10 @@ obj-$(CONFIG_MTRR) += mtrr/ | |||
43 | obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o perf_event_amd_ibs.o | 43 | obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o perf_event_amd_ibs.o |
44 | 44 | ||
45 | quiet_cmd_mkcapflags = MKCAP $@ | 45 | quiet_cmd_mkcapflags = MKCAP $@ |
46 | cmd_mkcapflags = $(PERL) $(srctree)/$(src)/mkcapflags.pl $< $@ | 46 | cmd_mkcapflags = $(CONFIG_SHELL) $(srctree)/$(src)/mkcapflags.sh $< $@ |
47 | 47 | ||
48 | cpufeature = $(src)/../../include/asm/cpufeature.h | 48 | cpufeature = $(src)/../../include/asm/cpufeature.h |
49 | 49 | ||
50 | targets += capflags.c | 50 | targets += capflags.c |
51 | $(obj)/capflags.c: $(cpufeature) $(src)/mkcapflags.pl FORCE | 51 | $(obj)/capflags.c: $(cpufeature) $(src)/mkcapflags.sh FORCE |
52 | $(call if_changed,mkcapflags) | 52 | $(call if_changed,mkcapflags) |
diff --git a/arch/x86/kernel/cpu/mkcapflags.pl b/arch/x86/kernel/cpu/mkcapflags.pl deleted file mode 100644 index 091972ef49de..000000000000 --- a/arch/x86/kernel/cpu/mkcapflags.pl +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | #!/usr/bin/perl -w | ||
2 | # | ||
3 | # Generate the x86_cap_flags[] array from include/asm-x86/cpufeature.h | ||
4 | # | ||
5 | |||
6 | ($in, $out) = @ARGV; | ||
7 | |||
8 | open(IN, "< $in\0") or die "$0: cannot open: $in: $!\n"; | ||
9 | open(OUT, "> $out\0") or die "$0: cannot create: $out: $!\n"; | ||
10 | |||
11 | print OUT "#ifndef _ASM_X86_CPUFEATURE_H\n"; | ||
12 | print OUT "#include <asm/cpufeature.h>\n"; | ||
13 | print OUT "#endif\n"; | ||
14 | print OUT "\n"; | ||
15 | print OUT "const char * const x86_cap_flags[NCAPINTS*32] = {\n"; | ||
16 | |||
17 | %features = (); | ||
18 | $err = 0; | ||
19 | |||
20 | while (defined($line = <IN>)) { | ||
21 | if ($line =~ /^\s*\#\s*define\s+(X86_FEATURE_(\S+))\s+(.*)$/) { | ||
22 | $macro = $1; | ||
23 | $feature = "\L$2"; | ||
24 | $tail = $3; | ||
25 | if ($tail =~ /\/\*\s*\"([^"]*)\".*\*\//) { | ||
26 | $feature = "\L$1"; | ||
27 | } | ||
28 | |||
29 | next if ($feature eq ''); | ||
30 | |||
31 | if ($features{$feature}++) { | ||
32 | print STDERR "$in: duplicate feature name: $feature\n"; | ||
33 | $err++; | ||
34 | } | ||
35 | printf OUT "\t%-32s = \"%s\",\n", "[$macro]", $feature; | ||
36 | } | ||
37 | } | ||
38 | print OUT "};\n"; | ||
39 | |||
40 | close(IN); | ||
41 | close(OUT); | ||
42 | |||
43 | if ($err) { | ||
44 | unlink($out); | ||
45 | exit(1); | ||
46 | } | ||
47 | |||
48 | exit(0); | ||
diff --git a/arch/x86/kernel/cpu/mkcapflags.sh b/arch/x86/kernel/cpu/mkcapflags.sh new file mode 100644 index 000000000000..2bf616505499 --- /dev/null +++ b/arch/x86/kernel/cpu/mkcapflags.sh | |||
@@ -0,0 +1,41 @@ | |||
1 | #!/bin/sh | ||
2 | # | ||
3 | # Generate the x86_cap_flags[] array from include/asm/cpufeature.h | ||
4 | # | ||
5 | |||
6 | IN=$1 | ||
7 | OUT=$2 | ||
8 | |||
9 | TABS="$(printf '\t\t\t\t\t')" | ||
10 | trap 'rm "$OUT"' EXIT | ||
11 | |||
12 | ( | ||
13 | echo "#ifndef _ASM_X86_CPUFEATURE_H" | ||
14 | echo "#include <asm/cpufeature.h>" | ||
15 | echo "#endif" | ||
16 | echo "" | ||
17 | echo "const char * const x86_cap_flags[NCAPINTS*32] = {" | ||
18 | |||
19 | # Iterate through any input lines starting with #define X86_FEATURE_ | ||
20 | sed -n -e 's/\t/ /g' -e 's/^ *# *define *X86_FEATURE_//p' $IN | | ||
21 | while read i | ||
22 | do | ||
23 | # Name is everything up to the first whitespace | ||
24 | NAME="$(echo "$i" | sed 's/ .*//')" | ||
25 | |||
26 | # If the /* comment */ starts with a quote string, grab that. | ||
27 | VALUE="$(echo "$i" | sed -n 's@.*/\* *\("[^"]*"\).*\*/@\1@p')" | ||
28 | [ -z "$VALUE" ] && VALUE="\"$NAME\"" | ||
29 | [ "$VALUE" == '""' ] && continue | ||
30 | |||
31 | # Name is uppercase, VALUE is all lowercase | ||
32 | VALUE="$(echo "$VALUE" | tr A-Z a-z)" | ||
33 | |||
34 | TABCOUNT=$(( ( 5*8 - 14 - $(echo "$NAME" | wc -c) ) / 8 )) | ||
35 | printf "\t[%s]%.*s = %s,\n" \ | ||
36 | "X86_FEATURE_$NAME" "$TABCOUNT" "$TABS" "$VALUE" | ||
37 | done | ||
38 | echo "};" | ||
39 | ) > $OUT | ||
40 | |||
41 | trap - EXIT | ||
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index a7d26d83fb70..8f4be53ea04b 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c | |||
@@ -35,13 +35,6 @@ static bool __init ms_hyperv_platform(void) | |||
35 | if (!boot_cpu_has(X86_FEATURE_HYPERVISOR)) | 35 | if (!boot_cpu_has(X86_FEATURE_HYPERVISOR)) |
36 | return false; | 36 | return false; |
37 | 37 | ||
38 | /* | ||
39 | * Xen emulates Hyper-V to support enlightened Windows. | ||
40 | * Check to see first if we are on a Xen Hypervisor. | ||
41 | */ | ||
42 | if (xen_cpuid_base()) | ||
43 | return false; | ||
44 | |||
45 | cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS, | 38 | cpuid(HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS, |
46 | &eax, &hyp_signature[0], &hyp_signature[1], &hyp_signature[2]); | 39 | &eax, &hyp_signature[0], &hyp_signature[1], &hyp_signature[2]); |
47 | 40 | ||
@@ -82,12 +75,6 @@ static void __init ms_hyperv_init_platform(void) | |||
82 | 75 | ||
83 | if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE) | 76 | if (ms_hyperv.features & HV_X64_MSR_TIME_REF_COUNT_AVAILABLE) |
84 | clocksource_register_hz(&hyperv_cs, NSEC_PER_SEC/100); | 77 | clocksource_register_hz(&hyperv_cs, NSEC_PER_SEC/100); |
85 | #if IS_ENABLED(CONFIG_HYPERV) | ||
86 | /* | ||
87 | * Setup the IDT for hypervisor callback. | ||
88 | */ | ||
89 | alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector); | ||
90 | #endif | ||
91 | } | 78 | } |
92 | 79 | ||
93 | const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = { | 80 | const __refconst struct hypervisor_x86 x86_hyper_ms_hyperv = { |
@@ -103,6 +90,11 @@ static irq_handler_t vmbus_isr; | |||
103 | 90 | ||
104 | void hv_register_vmbus_handler(int irq, irq_handler_t handler) | 91 | void hv_register_vmbus_handler(int irq, irq_handler_t handler) |
105 | { | 92 | { |
93 | /* | ||
94 | * Setup the IDT for hypervisor callback. | ||
95 | */ | ||
96 | alloc_intr_gate(HYPERVISOR_CALLBACK_VECTOR, hyperv_callback_vector); | ||
97 | |||
106 | vmbus_irq = irq; | 98 | vmbus_irq = irq; |
107 | vmbus_isr = handler; | 99 | vmbus_isr = handler; |
108 | } | 100 | } |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index bf0f01aea994..1025f3c99d20 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -180,8 +180,9 @@ static void release_pmc_hardware(void) {} | |||
180 | 180 | ||
181 | static bool check_hw_exists(void) | 181 | static bool check_hw_exists(void) |
182 | { | 182 | { |
183 | u64 val, val_new = ~0; | 183 | u64 val, val_fail, val_new= ~0; |
184 | int i, reg, ret = 0; | 184 | int i, reg, reg_fail, ret = 0; |
185 | int bios_fail = 0; | ||
185 | 186 | ||
186 | /* | 187 | /* |
187 | * Check to see if the BIOS enabled any of the counters, if so | 188 | * Check to see if the BIOS enabled any of the counters, if so |
@@ -192,8 +193,11 @@ static bool check_hw_exists(void) | |||
192 | ret = rdmsrl_safe(reg, &val); | 193 | ret = rdmsrl_safe(reg, &val); |
193 | if (ret) | 194 | if (ret) |
194 | goto msr_fail; | 195 | goto msr_fail; |
195 | if (val & ARCH_PERFMON_EVENTSEL_ENABLE) | 196 | if (val & ARCH_PERFMON_EVENTSEL_ENABLE) { |
196 | goto bios_fail; | 197 | bios_fail = 1; |
198 | val_fail = val; | ||
199 | reg_fail = reg; | ||
200 | } | ||
197 | } | 201 | } |
198 | 202 | ||
199 | if (x86_pmu.num_counters_fixed) { | 203 | if (x86_pmu.num_counters_fixed) { |
@@ -202,8 +206,11 @@ static bool check_hw_exists(void) | |||
202 | if (ret) | 206 | if (ret) |
203 | goto msr_fail; | 207 | goto msr_fail; |
204 | for (i = 0; i < x86_pmu.num_counters_fixed; i++) { | 208 | for (i = 0; i < x86_pmu.num_counters_fixed; i++) { |
205 | if (val & (0x03 << i*4)) | 209 | if (val & (0x03 << i*4)) { |
206 | goto bios_fail; | 210 | bios_fail = 1; |
211 | val_fail = val; | ||
212 | reg_fail = reg; | ||
213 | } | ||
207 | } | 214 | } |
208 | } | 215 | } |
209 | 216 | ||
@@ -221,14 +228,13 @@ static bool check_hw_exists(void) | |||
221 | if (ret || val != val_new) | 228 | if (ret || val != val_new) |
222 | goto msr_fail; | 229 | goto msr_fail; |
223 | 230 | ||
224 | return true; | ||
225 | |||
226 | bios_fail: | ||
227 | /* | 231 | /* |
228 | * We still allow the PMU driver to operate: | 232 | * We still allow the PMU driver to operate: |
229 | */ | 233 | */ |
230 | printk(KERN_CONT "Broken BIOS detected, complain to your hardware vendor.\n"); | 234 | if (bios_fail) { |
231 | printk(KERN_ERR FW_BUG "the BIOS has corrupted hw-PMU resources (MSR %x is %Lx)\n", reg, val); | 235 | printk(KERN_CONT "Broken BIOS detected, complain to your hardware vendor.\n"); |
236 | printk(KERN_ERR FW_BUG "the BIOS has corrupted hw-PMU resources (MSR %x is %Lx)\n", reg_fail, val_fail); | ||
237 | } | ||
232 | 238 | ||
233 | return true; | 239 | return true; |
234 | 240 | ||
@@ -1316,9 +1322,16 @@ static struct attribute_group x86_pmu_format_group = { | |||
1316 | */ | 1322 | */ |
1317 | static void __init filter_events(struct attribute **attrs) | 1323 | static void __init filter_events(struct attribute **attrs) |
1318 | { | 1324 | { |
1325 | struct device_attribute *d; | ||
1326 | struct perf_pmu_events_attr *pmu_attr; | ||
1319 | int i, j; | 1327 | int i, j; |
1320 | 1328 | ||
1321 | for (i = 0; attrs[i]; i++) { | 1329 | for (i = 0; attrs[i]; i++) { |
1330 | d = (struct device_attribute *)attrs[i]; | ||
1331 | pmu_attr = container_of(d, struct perf_pmu_events_attr, attr); | ||
1332 | /* str trumps id */ | ||
1333 | if (pmu_attr->event_str) | ||
1334 | continue; | ||
1322 | if (x86_pmu.event_map(i)) | 1335 | if (x86_pmu.event_map(i)) |
1323 | continue; | 1336 | continue; |
1324 | 1337 | ||
@@ -1330,22 +1343,45 @@ static void __init filter_events(struct attribute **attrs) | |||
1330 | } | 1343 | } |
1331 | } | 1344 | } |
1332 | 1345 | ||
1333 | static ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, | 1346 | /* Merge two pointer arrays */ |
1347 | static __init struct attribute **merge_attr(struct attribute **a, struct attribute **b) | ||
1348 | { | ||
1349 | struct attribute **new; | ||
1350 | int j, i; | ||
1351 | |||
1352 | for (j = 0; a[j]; j++) | ||
1353 | ; | ||
1354 | for (i = 0; b[i]; i++) | ||
1355 | j++; | ||
1356 | j++; | ||
1357 | |||
1358 | new = kmalloc(sizeof(struct attribute *) * j, GFP_KERNEL); | ||
1359 | if (!new) | ||
1360 | return NULL; | ||
1361 | |||
1362 | j = 0; | ||
1363 | for (i = 0; a[i]; i++) | ||
1364 | new[j++] = a[i]; | ||
1365 | for (i = 0; b[i]; i++) | ||
1366 | new[j++] = b[i]; | ||
1367 | new[j] = NULL; | ||
1368 | |||
1369 | return new; | ||
1370 | } | ||
1371 | |||
1372 | ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, | ||
1334 | char *page) | 1373 | char *page) |
1335 | { | 1374 | { |
1336 | struct perf_pmu_events_attr *pmu_attr = \ | 1375 | struct perf_pmu_events_attr *pmu_attr = \ |
1337 | container_of(attr, struct perf_pmu_events_attr, attr); | 1376 | container_of(attr, struct perf_pmu_events_attr, attr); |
1338 | |||
1339 | u64 config = x86_pmu.event_map(pmu_attr->id); | 1377 | u64 config = x86_pmu.event_map(pmu_attr->id); |
1340 | return x86_pmu.events_sysfs_show(page, config); | ||
1341 | } | ||
1342 | 1378 | ||
1343 | #define EVENT_VAR(_id) event_attr_##_id | 1379 | /* string trumps id */ |
1344 | #define EVENT_PTR(_id) &event_attr_##_id.attr.attr | 1380 | if (pmu_attr->event_str) |
1381 | return sprintf(page, "%s", pmu_attr->event_str); | ||
1345 | 1382 | ||
1346 | #define EVENT_ATTR(_name, _id) \ | 1383 | return x86_pmu.events_sysfs_show(page, config); |
1347 | PMU_EVENT_ATTR(_name, EVENT_VAR(_id), PERF_COUNT_HW_##_id, \ | 1384 | } |
1348 | events_sysfs_show) | ||
1349 | 1385 | ||
1350 | EVENT_ATTR(cpu-cycles, CPU_CYCLES ); | 1386 | EVENT_ATTR(cpu-cycles, CPU_CYCLES ); |
1351 | EVENT_ATTR(instructions, INSTRUCTIONS ); | 1387 | EVENT_ATTR(instructions, INSTRUCTIONS ); |
@@ -1459,16 +1495,27 @@ static int __init init_hw_perf_events(void) | |||
1459 | 1495 | ||
1460 | unconstrained = (struct event_constraint) | 1496 | unconstrained = (struct event_constraint) |
1461 | __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1, | 1497 | __EVENT_CONSTRAINT(0, (1ULL << x86_pmu.num_counters) - 1, |
1462 | 0, x86_pmu.num_counters, 0); | 1498 | 0, x86_pmu.num_counters, 0, 0); |
1463 | 1499 | ||
1464 | x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */ | 1500 | x86_pmu.attr_rdpmc = 1; /* enable userspace RDPMC usage by default */ |
1465 | x86_pmu_format_group.attrs = x86_pmu.format_attrs; | 1501 | x86_pmu_format_group.attrs = x86_pmu.format_attrs; |
1466 | 1502 | ||
1503 | if (x86_pmu.event_attrs) | ||
1504 | x86_pmu_events_group.attrs = x86_pmu.event_attrs; | ||
1505 | |||
1467 | if (!x86_pmu.events_sysfs_show) | 1506 | if (!x86_pmu.events_sysfs_show) |
1468 | x86_pmu_events_group.attrs = &empty_attrs; | 1507 | x86_pmu_events_group.attrs = &empty_attrs; |
1469 | else | 1508 | else |
1470 | filter_events(x86_pmu_events_group.attrs); | 1509 | filter_events(x86_pmu_events_group.attrs); |
1471 | 1510 | ||
1511 | if (x86_pmu.cpu_events) { | ||
1512 | struct attribute **tmp; | ||
1513 | |||
1514 | tmp = merge_attr(x86_pmu_events_group.attrs, x86_pmu.cpu_events); | ||
1515 | if (!WARN_ON(!tmp)) | ||
1516 | x86_pmu_events_group.attrs = tmp; | ||
1517 | } | ||
1518 | |||
1472 | pr_info("... version: %d\n", x86_pmu.version); | 1519 | pr_info("... version: %d\n", x86_pmu.version); |
1473 | pr_info("... bit width: %d\n", x86_pmu.cntval_bits); | 1520 | pr_info("... bit width: %d\n", x86_pmu.cntval_bits); |
1474 | pr_info("... generic registers: %d\n", x86_pmu.num_counters); | 1521 | pr_info("... generic registers: %d\n", x86_pmu.num_counters); |
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 7f5c75c2afdd..ba9aadfa683b 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h | |||
@@ -46,6 +46,7 @@ enum extra_reg_type { | |||
46 | EXTRA_REG_RSP_0 = 0, /* offcore_response_0 */ | 46 | EXTRA_REG_RSP_0 = 0, /* offcore_response_0 */ |
47 | EXTRA_REG_RSP_1 = 1, /* offcore_response_1 */ | 47 | EXTRA_REG_RSP_1 = 1, /* offcore_response_1 */ |
48 | EXTRA_REG_LBR = 2, /* lbr_select */ | 48 | EXTRA_REG_LBR = 2, /* lbr_select */ |
49 | EXTRA_REG_LDLAT = 3, /* ld_lat_threshold */ | ||
49 | 50 | ||
50 | EXTRA_REG_MAX /* number of entries needed */ | 51 | EXTRA_REG_MAX /* number of entries needed */ |
51 | }; | 52 | }; |
@@ -59,7 +60,13 @@ struct event_constraint { | |||
59 | u64 cmask; | 60 | u64 cmask; |
60 | int weight; | 61 | int weight; |
61 | int overlap; | 62 | int overlap; |
63 | int flags; | ||
62 | }; | 64 | }; |
65 | /* | ||
66 | * struct event_constraint flags | ||
67 | */ | ||
68 | #define PERF_X86_EVENT_PEBS_LDLAT 0x1 /* ld+ldlat data address sampling */ | ||
69 | #define PERF_X86_EVENT_PEBS_ST 0x2 /* st data address sampling */ | ||
63 | 70 | ||
64 | struct amd_nb { | 71 | struct amd_nb { |
65 | int nb_id; /* NorthBridge id */ | 72 | int nb_id; /* NorthBridge id */ |
@@ -170,16 +177,17 @@ struct cpu_hw_events { | |||
170 | void *kfree_on_online; | 177 | void *kfree_on_online; |
171 | }; | 178 | }; |
172 | 179 | ||
173 | #define __EVENT_CONSTRAINT(c, n, m, w, o) {\ | 180 | #define __EVENT_CONSTRAINT(c, n, m, w, o, f) {\ |
174 | { .idxmsk64 = (n) }, \ | 181 | { .idxmsk64 = (n) }, \ |
175 | .code = (c), \ | 182 | .code = (c), \ |
176 | .cmask = (m), \ | 183 | .cmask = (m), \ |
177 | .weight = (w), \ | 184 | .weight = (w), \ |
178 | .overlap = (o), \ | 185 | .overlap = (o), \ |
186 | .flags = f, \ | ||
179 | } | 187 | } |
180 | 188 | ||
181 | #define EVENT_CONSTRAINT(c, n, m) \ | 189 | #define EVENT_CONSTRAINT(c, n, m) \ |
182 | __EVENT_CONSTRAINT(c, n, m, HWEIGHT(n), 0) | 190 | __EVENT_CONSTRAINT(c, n, m, HWEIGHT(n), 0, 0) |
183 | 191 | ||
184 | /* | 192 | /* |
185 | * The overlap flag marks event constraints with overlapping counter | 193 | * The overlap flag marks event constraints with overlapping counter |
@@ -203,7 +211,7 @@ struct cpu_hw_events { | |||
203 | * and its counter masks must be kept at a minimum. | 211 | * and its counter masks must be kept at a minimum. |
204 | */ | 212 | */ |
205 | #define EVENT_CONSTRAINT_OVERLAP(c, n, m) \ | 213 | #define EVENT_CONSTRAINT_OVERLAP(c, n, m) \ |
206 | __EVENT_CONSTRAINT(c, n, m, HWEIGHT(n), 1) | 214 | __EVENT_CONSTRAINT(c, n, m, HWEIGHT(n), 1, 0) |
207 | 215 | ||
208 | /* | 216 | /* |
209 | * Constraint on the Event code. | 217 | * Constraint on the Event code. |
@@ -231,6 +239,14 @@ struct cpu_hw_events { | |||
231 | #define INTEL_UEVENT_CONSTRAINT(c, n) \ | 239 | #define INTEL_UEVENT_CONSTRAINT(c, n) \ |
232 | EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK) | 240 | EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK) |
233 | 241 | ||
242 | #define INTEL_PLD_CONSTRAINT(c, n) \ | ||
243 | __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK, \ | ||
244 | HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LDLAT) | ||
245 | |||
246 | #define INTEL_PST_CONSTRAINT(c, n) \ | ||
247 | __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK, \ | ||
248 | HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST) | ||
249 | |||
234 | #define EVENT_CONSTRAINT_END \ | 250 | #define EVENT_CONSTRAINT_END \ |
235 | EVENT_CONSTRAINT(0, 0, 0) | 251 | EVENT_CONSTRAINT(0, 0, 0) |
236 | 252 | ||
@@ -260,12 +276,22 @@ struct extra_reg { | |||
260 | .msr = (ms), \ | 276 | .msr = (ms), \ |
261 | .config_mask = (m), \ | 277 | .config_mask = (m), \ |
262 | .valid_mask = (vm), \ | 278 | .valid_mask = (vm), \ |
263 | .idx = EXTRA_REG_##i \ | 279 | .idx = EXTRA_REG_##i, \ |
264 | } | 280 | } |
265 | 281 | ||
266 | #define INTEL_EVENT_EXTRA_REG(event, msr, vm, idx) \ | 282 | #define INTEL_EVENT_EXTRA_REG(event, msr, vm, idx) \ |
267 | EVENT_EXTRA_REG(event, msr, ARCH_PERFMON_EVENTSEL_EVENT, vm, idx) | 283 | EVENT_EXTRA_REG(event, msr, ARCH_PERFMON_EVENTSEL_EVENT, vm, idx) |
268 | 284 | ||
285 | #define INTEL_UEVENT_EXTRA_REG(event, msr, vm, idx) \ | ||
286 | EVENT_EXTRA_REG(event, msr, ARCH_PERFMON_EVENTSEL_EVENT | \ | ||
287 | ARCH_PERFMON_EVENTSEL_UMASK, vm, idx) | ||
288 | |||
289 | #define INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(c) \ | ||
290 | INTEL_UEVENT_EXTRA_REG(c, \ | ||
291 | MSR_PEBS_LD_LAT_THRESHOLD, \ | ||
292 | 0xffff, \ | ||
293 | LDLAT) | ||
294 | |||
269 | #define EVENT_EXTRA_END EVENT_EXTRA_REG(0, 0, 0, 0, RSP_0) | 295 | #define EVENT_EXTRA_END EVENT_EXTRA_REG(0, 0, 0, 0, RSP_0) |
270 | 296 | ||
271 | union perf_capabilities { | 297 | union perf_capabilities { |
@@ -355,8 +381,10 @@ struct x86_pmu { | |||
355 | */ | 381 | */ |
356 | int attr_rdpmc; | 382 | int attr_rdpmc; |
357 | struct attribute **format_attrs; | 383 | struct attribute **format_attrs; |
384 | struct attribute **event_attrs; | ||
358 | 385 | ||
359 | ssize_t (*events_sysfs_show)(char *page, u64 config); | 386 | ssize_t (*events_sysfs_show)(char *page, u64 config); |
387 | struct attribute **cpu_events; | ||
360 | 388 | ||
361 | /* | 389 | /* |
362 | * CPU Hotplug hooks | 390 | * CPU Hotplug hooks |
@@ -421,6 +449,23 @@ do { \ | |||
421 | #define ERF_NO_HT_SHARING 1 | 449 | #define ERF_NO_HT_SHARING 1 |
422 | #define ERF_HAS_RSP_1 2 | 450 | #define ERF_HAS_RSP_1 2 |
423 | 451 | ||
452 | #define EVENT_VAR(_id) event_attr_##_id | ||
453 | #define EVENT_PTR(_id) &event_attr_##_id.attr.attr | ||
454 | |||
455 | #define EVENT_ATTR(_name, _id) \ | ||
456 | static struct perf_pmu_events_attr EVENT_VAR(_id) = { \ | ||
457 | .attr = __ATTR(_name, 0444, events_sysfs_show, NULL), \ | ||
458 | .id = PERF_COUNT_HW_##_id, \ | ||
459 | .event_str = NULL, \ | ||
460 | }; | ||
461 | |||
462 | #define EVENT_ATTR_STR(_name, v, str) \ | ||
463 | static struct perf_pmu_events_attr event_attr_##v = { \ | ||
464 | .attr = __ATTR(_name, 0444, events_sysfs_show, NULL), \ | ||
465 | .id = 0, \ | ||
466 | .event_str = str, \ | ||
467 | }; | ||
468 | |||
424 | extern struct x86_pmu x86_pmu __read_mostly; | 469 | extern struct x86_pmu x86_pmu __read_mostly; |
425 | 470 | ||
426 | DECLARE_PER_CPU(struct cpu_hw_events, cpu_hw_events); | 471 | DECLARE_PER_CPU(struct cpu_hw_events, cpu_hw_events); |
@@ -628,6 +673,9 @@ int p6_pmu_init(void); | |||
628 | 673 | ||
629 | int knc_pmu_init(void); | 674 | int knc_pmu_init(void); |
630 | 675 | ||
676 | ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, | ||
677 | char *page); | ||
678 | |||
631 | #else /* CONFIG_CPU_SUP_INTEL */ | 679 | #else /* CONFIG_CPU_SUP_INTEL */ |
632 | 680 | ||
633 | static inline void reserve_ds_buffers(void) | 681 | static inline void reserve_ds_buffers(void) |
diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c index dfdab42aed27..7e28d9467bb4 100644 --- a/arch/x86/kernel/cpu/perf_event_amd.c +++ b/arch/x86/kernel/cpu/perf_event_amd.c | |||
@@ -132,14 +132,11 @@ static u64 amd_pmu_event_map(int hw_event) | |||
132 | return amd_perfmon_event_map[hw_event]; | 132 | return amd_perfmon_event_map[hw_event]; |
133 | } | 133 | } |
134 | 134 | ||
135 | static struct event_constraint *amd_nb_event_constraint; | ||
136 | |||
137 | /* | 135 | /* |
138 | * Previously calculated offsets | 136 | * Previously calculated offsets |
139 | */ | 137 | */ |
140 | static unsigned int event_offsets[X86_PMC_IDX_MAX] __read_mostly; | 138 | static unsigned int event_offsets[X86_PMC_IDX_MAX] __read_mostly; |
141 | static unsigned int count_offsets[X86_PMC_IDX_MAX] __read_mostly; | 139 | static unsigned int count_offsets[X86_PMC_IDX_MAX] __read_mostly; |
142 | static unsigned int rdpmc_indexes[X86_PMC_IDX_MAX] __read_mostly; | ||
143 | 140 | ||
144 | /* | 141 | /* |
145 | * Legacy CPUs: | 142 | * Legacy CPUs: |
@@ -147,14 +144,10 @@ static unsigned int rdpmc_indexes[X86_PMC_IDX_MAX] __read_mostly; | |||
147 | * | 144 | * |
148 | * CPUs with core performance counter extensions: | 145 | * CPUs with core performance counter extensions: |
149 | * 6 counters starting at 0xc0010200 each offset by 2 | 146 | * 6 counters starting at 0xc0010200 each offset by 2 |
150 | * | ||
151 | * CPUs with north bridge performance counter extensions: | ||
152 | * 4 additional counters starting at 0xc0010240 each offset by 2 | ||
153 | * (indexed right above either one of the above core counters) | ||
154 | */ | 147 | */ |
155 | static inline int amd_pmu_addr_offset(int index, bool eventsel) | 148 | static inline int amd_pmu_addr_offset(int index, bool eventsel) |
156 | { | 149 | { |
157 | int offset, first, base; | 150 | int offset; |
158 | 151 | ||
159 | if (!index) | 152 | if (!index) |
160 | return index; | 153 | return index; |
@@ -167,23 +160,7 @@ static inline int amd_pmu_addr_offset(int index, bool eventsel) | |||
167 | if (offset) | 160 | if (offset) |
168 | return offset; | 161 | return offset; |
169 | 162 | ||
170 | if (amd_nb_event_constraint && | 163 | if (!cpu_has_perfctr_core) |
171 | test_bit(index, amd_nb_event_constraint->idxmsk)) { | ||
172 | /* | ||
173 | * calculate the offset of NB counters with respect to | ||
174 | * base eventsel or perfctr | ||
175 | */ | ||
176 | |||
177 | first = find_first_bit(amd_nb_event_constraint->idxmsk, | ||
178 | X86_PMC_IDX_MAX); | ||
179 | |||
180 | if (eventsel) | ||
181 | base = MSR_F15H_NB_PERF_CTL - x86_pmu.eventsel; | ||
182 | else | ||
183 | base = MSR_F15H_NB_PERF_CTR - x86_pmu.perfctr; | ||
184 | |||
185 | offset = base + ((index - first) << 1); | ||
186 | } else if (!cpu_has_perfctr_core) | ||
187 | offset = index; | 164 | offset = index; |
188 | else | 165 | else |
189 | offset = index << 1; | 166 | offset = index << 1; |
@@ -196,36 +173,6 @@ static inline int amd_pmu_addr_offset(int index, bool eventsel) | |||
196 | return offset; | 173 | return offset; |
197 | } | 174 | } |
198 | 175 | ||
199 | static inline int amd_pmu_rdpmc_index(int index) | ||
200 | { | ||
201 | int ret, first; | ||
202 | |||
203 | if (!index) | ||
204 | return index; | ||
205 | |||
206 | ret = rdpmc_indexes[index]; | ||
207 | |||
208 | if (ret) | ||
209 | return ret; | ||
210 | |||
211 | if (amd_nb_event_constraint && | ||
212 | test_bit(index, amd_nb_event_constraint->idxmsk)) { | ||
213 | /* | ||
214 | * according to the mnual, ECX value of the NB counters is | ||
215 | * the index of the NB counter (0, 1, 2 or 3) plus 6 | ||
216 | */ | ||
217 | |||
218 | first = find_first_bit(amd_nb_event_constraint->idxmsk, | ||
219 | X86_PMC_IDX_MAX); | ||
220 | ret = index - first + 6; | ||
221 | } else | ||
222 | ret = index; | ||
223 | |||
224 | rdpmc_indexes[index] = ret; | ||
225 | |||
226 | return ret; | ||
227 | } | ||
228 | |||
229 | static int amd_core_hw_config(struct perf_event *event) | 176 | static int amd_core_hw_config(struct perf_event *event) |
230 | { | 177 | { |
231 | if (event->attr.exclude_host && event->attr.exclude_guest) | 178 | if (event->attr.exclude_host && event->attr.exclude_guest) |
@@ -245,34 +192,6 @@ static int amd_core_hw_config(struct perf_event *event) | |||
245 | } | 192 | } |
246 | 193 | ||
247 | /* | 194 | /* |
248 | * NB counters do not support the following event select bits: | ||
249 | * Host/Guest only | ||
250 | * Counter mask | ||
251 | * Invert counter mask | ||
252 | * Edge detect | ||
253 | * OS/User mode | ||
254 | */ | ||
255 | static int amd_nb_hw_config(struct perf_event *event) | ||
256 | { | ||
257 | /* for NB, we only allow system wide counting mode */ | ||
258 | if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK) | ||
259 | return -EINVAL; | ||
260 | |||
261 | if (event->attr.exclude_user || event->attr.exclude_kernel || | ||
262 | event->attr.exclude_host || event->attr.exclude_guest) | ||
263 | return -EINVAL; | ||
264 | |||
265 | event->hw.config &= ~(ARCH_PERFMON_EVENTSEL_USR | | ||
266 | ARCH_PERFMON_EVENTSEL_OS); | ||
267 | |||
268 | if (event->hw.config & ~(AMD64_RAW_EVENT_MASK_NB | | ||
269 | ARCH_PERFMON_EVENTSEL_INT)) | ||
270 | return -EINVAL; | ||
271 | |||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | /* | ||
276 | * AMD64 events are detected based on their event codes. | 195 | * AMD64 events are detected based on their event codes. |
277 | */ | 196 | */ |
278 | static inline unsigned int amd_get_event_code(struct hw_perf_event *hwc) | 197 | static inline unsigned int amd_get_event_code(struct hw_perf_event *hwc) |
@@ -285,11 +204,6 @@ static inline int amd_is_nb_event(struct hw_perf_event *hwc) | |||
285 | return (hwc->config & 0xe0) == 0xe0; | 204 | return (hwc->config & 0xe0) == 0xe0; |
286 | } | 205 | } |
287 | 206 | ||
288 | static inline int amd_is_perfctr_nb_event(struct hw_perf_event *hwc) | ||
289 | { | ||
290 | return amd_nb_event_constraint && amd_is_nb_event(hwc); | ||
291 | } | ||
292 | |||
293 | static inline int amd_has_nb(struct cpu_hw_events *cpuc) | 207 | static inline int amd_has_nb(struct cpu_hw_events *cpuc) |
294 | { | 208 | { |
295 | struct amd_nb *nb = cpuc->amd_nb; | 209 | struct amd_nb *nb = cpuc->amd_nb; |
@@ -315,9 +229,6 @@ static int amd_pmu_hw_config(struct perf_event *event) | |||
315 | if (event->attr.type == PERF_TYPE_RAW) | 229 | if (event->attr.type == PERF_TYPE_RAW) |
316 | event->hw.config |= event->attr.config & AMD64_RAW_EVENT_MASK; | 230 | event->hw.config |= event->attr.config & AMD64_RAW_EVENT_MASK; |
317 | 231 | ||
318 | if (amd_is_perfctr_nb_event(&event->hw)) | ||
319 | return amd_nb_hw_config(event); | ||
320 | |||
321 | return amd_core_hw_config(event); | 232 | return amd_core_hw_config(event); |
322 | } | 233 | } |
323 | 234 | ||
@@ -341,19 +252,6 @@ static void __amd_put_nb_event_constraints(struct cpu_hw_events *cpuc, | |||
341 | } | 252 | } |
342 | } | 253 | } |
343 | 254 | ||
344 | static void amd_nb_interrupt_hw_config(struct hw_perf_event *hwc) | ||
345 | { | ||
346 | int core_id = cpu_data(smp_processor_id()).cpu_core_id; | ||
347 | |||
348 | /* deliver interrupts only to this core */ | ||
349 | if (hwc->config & ARCH_PERFMON_EVENTSEL_INT) { | ||
350 | hwc->config |= AMD64_EVENTSEL_INT_CORE_ENABLE; | ||
351 | hwc->config &= ~AMD64_EVENTSEL_INT_CORE_SEL_MASK; | ||
352 | hwc->config |= (u64)(core_id) << | ||
353 | AMD64_EVENTSEL_INT_CORE_SEL_SHIFT; | ||
354 | } | ||
355 | } | ||
356 | |||
357 | /* | 255 | /* |
358 | * AMD64 NorthBridge events need special treatment because | 256 | * AMD64 NorthBridge events need special treatment because |
359 | * counter access needs to be synchronized across all cores | 257 | * counter access needs to be synchronized across all cores |
@@ -441,9 +339,6 @@ __amd_get_nb_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *ev | |||
441 | if (new == -1) | 339 | if (new == -1) |
442 | return &emptyconstraint; | 340 | return &emptyconstraint; |
443 | 341 | ||
444 | if (amd_is_perfctr_nb_event(hwc)) | ||
445 | amd_nb_interrupt_hw_config(hwc); | ||
446 | |||
447 | return &nb->event_constraints[new]; | 342 | return &nb->event_constraints[new]; |
448 | } | 343 | } |
449 | 344 | ||
@@ -543,8 +438,7 @@ amd_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event) | |||
543 | if (!(amd_has_nb(cpuc) && amd_is_nb_event(&event->hw))) | 438 | if (!(amd_has_nb(cpuc) && amd_is_nb_event(&event->hw))) |
544 | return &unconstrained; | 439 | return &unconstrained; |
545 | 440 | ||
546 | return __amd_get_nb_event_constraints(cpuc, event, | 441 | return __amd_get_nb_event_constraints(cpuc, event, NULL); |
547 | amd_nb_event_constraint); | ||
548 | } | 442 | } |
549 | 443 | ||
550 | static void amd_put_event_constraints(struct cpu_hw_events *cpuc, | 444 | static void amd_put_event_constraints(struct cpu_hw_events *cpuc, |
@@ -643,9 +537,6 @@ static struct event_constraint amd_f15_PMC30 = EVENT_CONSTRAINT_OVERLAP(0, 0x09, | |||
643 | static struct event_constraint amd_f15_PMC50 = EVENT_CONSTRAINT(0, 0x3F, 0); | 537 | static struct event_constraint amd_f15_PMC50 = EVENT_CONSTRAINT(0, 0x3F, 0); |
644 | static struct event_constraint amd_f15_PMC53 = EVENT_CONSTRAINT(0, 0x38, 0); | 538 | static struct event_constraint amd_f15_PMC53 = EVENT_CONSTRAINT(0, 0x38, 0); |
645 | 539 | ||
646 | static struct event_constraint amd_NBPMC96 = EVENT_CONSTRAINT(0, 0x3C0, 0); | ||
647 | static struct event_constraint amd_NBPMC74 = EVENT_CONSTRAINT(0, 0xF0, 0); | ||
648 | |||
649 | static struct event_constraint * | 540 | static struct event_constraint * |
650 | amd_get_event_constraints_f15h(struct cpu_hw_events *cpuc, struct perf_event *event) | 541 | amd_get_event_constraints_f15h(struct cpu_hw_events *cpuc, struct perf_event *event) |
651 | { | 542 | { |
@@ -711,8 +602,8 @@ amd_get_event_constraints_f15h(struct cpu_hw_events *cpuc, struct perf_event *ev | |||
711 | return &amd_f15_PMC20; | 602 | return &amd_f15_PMC20; |
712 | } | 603 | } |
713 | case AMD_EVENT_NB: | 604 | case AMD_EVENT_NB: |
714 | return __amd_get_nb_event_constraints(cpuc, event, | 605 | /* moved to perf_event_amd_uncore.c */ |
715 | amd_nb_event_constraint); | 606 | return &emptyconstraint; |
716 | default: | 607 | default: |
717 | return &emptyconstraint; | 608 | return &emptyconstraint; |
718 | } | 609 | } |
@@ -738,7 +629,6 @@ static __initconst const struct x86_pmu amd_pmu = { | |||
738 | .eventsel = MSR_K7_EVNTSEL0, | 629 | .eventsel = MSR_K7_EVNTSEL0, |
739 | .perfctr = MSR_K7_PERFCTR0, | 630 | .perfctr = MSR_K7_PERFCTR0, |
740 | .addr_offset = amd_pmu_addr_offset, | 631 | .addr_offset = amd_pmu_addr_offset, |
741 | .rdpmc_index = amd_pmu_rdpmc_index, | ||
742 | .event_map = amd_pmu_event_map, | 632 | .event_map = amd_pmu_event_map, |
743 | .max_events = ARRAY_SIZE(amd_perfmon_event_map), | 633 | .max_events = ARRAY_SIZE(amd_perfmon_event_map), |
744 | .num_counters = AMD64_NUM_COUNTERS, | 634 | .num_counters = AMD64_NUM_COUNTERS, |
@@ -790,23 +680,6 @@ static int setup_perfctr_core(void) | |||
790 | return 0; | 680 | return 0; |
791 | } | 681 | } |
792 | 682 | ||
793 | static int setup_perfctr_nb(void) | ||
794 | { | ||
795 | if (!cpu_has_perfctr_nb) | ||
796 | return -ENODEV; | ||
797 | |||
798 | x86_pmu.num_counters += AMD64_NUM_COUNTERS_NB; | ||
799 | |||
800 | if (cpu_has_perfctr_core) | ||
801 | amd_nb_event_constraint = &amd_NBPMC96; | ||
802 | else | ||
803 | amd_nb_event_constraint = &amd_NBPMC74; | ||
804 | |||
805 | printk(KERN_INFO "perf: AMD northbridge performance counters detected\n"); | ||
806 | |||
807 | return 0; | ||
808 | } | ||
809 | |||
810 | __init int amd_pmu_init(void) | 683 | __init int amd_pmu_init(void) |
811 | { | 684 | { |
812 | /* Performance-monitoring supported from K7 and later: */ | 685 | /* Performance-monitoring supported from K7 and later: */ |
@@ -817,7 +690,6 @@ __init int amd_pmu_init(void) | |||
817 | 690 | ||
818 | setup_event_constraints(); | 691 | setup_event_constraints(); |
819 | setup_perfctr_core(); | 692 | setup_perfctr_core(); |
820 | setup_perfctr_nb(); | ||
821 | 693 | ||
822 | /* Events are common for all AMDs */ | 694 | /* Events are common for all AMDs */ |
823 | memcpy(hw_cache_event_ids, amd_hw_cache_event_ids, | 695 | memcpy(hw_cache_event_ids, amd_hw_cache_event_ids, |
diff --git a/arch/x86/kernel/cpu/perf_event_amd_uncore.c b/arch/x86/kernel/cpu/perf_event_amd_uncore.c new file mode 100644 index 000000000000..c0c661adf03e --- /dev/null +++ b/arch/x86/kernel/cpu/perf_event_amd_uncore.c | |||
@@ -0,0 +1,547 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Author: Jacob Shin <jacob.shin@amd.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/perf_event.h> | ||
12 | #include <linux/percpu.h> | ||
13 | #include <linux/types.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/cpu.h> | ||
17 | #include <linux/cpumask.h> | ||
18 | |||
19 | #include <asm/cpufeature.h> | ||
20 | #include <asm/perf_event.h> | ||
21 | #include <asm/msr.h> | ||
22 | |||
23 | #define NUM_COUNTERS_NB 4 | ||
24 | #define NUM_COUNTERS_L2 4 | ||
25 | #define MAX_COUNTERS NUM_COUNTERS_NB | ||
26 | |||
27 | #define RDPMC_BASE_NB 6 | ||
28 | #define RDPMC_BASE_L2 10 | ||
29 | |||
30 | #define COUNTER_SHIFT 16 | ||
31 | |||
32 | struct amd_uncore { | ||
33 | int id; | ||
34 | int refcnt; | ||
35 | int cpu; | ||
36 | int num_counters; | ||
37 | int rdpmc_base; | ||
38 | u32 msr_base; | ||
39 | cpumask_t *active_mask; | ||
40 | struct pmu *pmu; | ||
41 | struct perf_event *events[MAX_COUNTERS]; | ||
42 | struct amd_uncore *free_when_cpu_online; | ||
43 | }; | ||
44 | |||
45 | static struct amd_uncore * __percpu *amd_uncore_nb; | ||
46 | static struct amd_uncore * __percpu *amd_uncore_l2; | ||
47 | |||
48 | static struct pmu amd_nb_pmu; | ||
49 | static struct pmu amd_l2_pmu; | ||
50 | |||
51 | static cpumask_t amd_nb_active_mask; | ||
52 | static cpumask_t amd_l2_active_mask; | ||
53 | |||
54 | static bool is_nb_event(struct perf_event *event) | ||
55 | { | ||
56 | return event->pmu->type == amd_nb_pmu.type; | ||
57 | } | ||
58 | |||
59 | static bool is_l2_event(struct perf_event *event) | ||
60 | { | ||
61 | return event->pmu->type == amd_l2_pmu.type; | ||
62 | } | ||
63 | |||
64 | static struct amd_uncore *event_to_amd_uncore(struct perf_event *event) | ||
65 | { | ||
66 | if (is_nb_event(event) && amd_uncore_nb) | ||
67 | return *per_cpu_ptr(amd_uncore_nb, event->cpu); | ||
68 | else if (is_l2_event(event) && amd_uncore_l2) | ||
69 | return *per_cpu_ptr(amd_uncore_l2, event->cpu); | ||
70 | |||
71 | return NULL; | ||
72 | } | ||
73 | |||
74 | static void amd_uncore_read(struct perf_event *event) | ||
75 | { | ||
76 | struct hw_perf_event *hwc = &event->hw; | ||
77 | u64 prev, new; | ||
78 | s64 delta; | ||
79 | |||
80 | /* | ||
81 | * since we do not enable counter overflow interrupts, | ||
82 | * we do not have to worry about prev_count changing on us | ||
83 | */ | ||
84 | |||
85 | prev = local64_read(&hwc->prev_count); | ||
86 | rdpmcl(hwc->event_base_rdpmc, new); | ||
87 | local64_set(&hwc->prev_count, new); | ||
88 | delta = (new << COUNTER_SHIFT) - (prev << COUNTER_SHIFT); | ||
89 | delta >>= COUNTER_SHIFT; | ||
90 | local64_add(delta, &event->count); | ||
91 | } | ||
92 | |||
93 | static void amd_uncore_start(struct perf_event *event, int flags) | ||
94 | { | ||
95 | struct hw_perf_event *hwc = &event->hw; | ||
96 | |||
97 | if (flags & PERF_EF_RELOAD) | ||
98 | wrmsrl(hwc->event_base, (u64)local64_read(&hwc->prev_count)); | ||
99 | |||
100 | hwc->state = 0; | ||
101 | wrmsrl(hwc->config_base, (hwc->config | ARCH_PERFMON_EVENTSEL_ENABLE)); | ||
102 | perf_event_update_userpage(event); | ||
103 | } | ||
104 | |||
105 | static void amd_uncore_stop(struct perf_event *event, int flags) | ||
106 | { | ||
107 | struct hw_perf_event *hwc = &event->hw; | ||
108 | |||
109 | wrmsrl(hwc->config_base, hwc->config); | ||
110 | hwc->state |= PERF_HES_STOPPED; | ||
111 | |||
112 | if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) { | ||
113 | amd_uncore_read(event); | ||
114 | hwc->state |= PERF_HES_UPTODATE; | ||
115 | } | ||
116 | } | ||
117 | |||
118 | static int amd_uncore_add(struct perf_event *event, int flags) | ||
119 | { | ||
120 | int i; | ||
121 | struct amd_uncore *uncore = event_to_amd_uncore(event); | ||
122 | struct hw_perf_event *hwc = &event->hw; | ||
123 | |||
124 | /* are we already assigned? */ | ||
125 | if (hwc->idx != -1 && uncore->events[hwc->idx] == event) | ||
126 | goto out; | ||
127 | |||
128 | for (i = 0; i < uncore->num_counters; i++) { | ||
129 | if (uncore->events[i] == event) { | ||
130 | hwc->idx = i; | ||
131 | goto out; | ||
132 | } | ||
133 | } | ||
134 | |||
135 | /* if not, take the first available counter */ | ||
136 | hwc->idx = -1; | ||
137 | for (i = 0; i < uncore->num_counters; i++) { | ||
138 | if (cmpxchg(&uncore->events[i], NULL, event) == NULL) { | ||
139 | hwc->idx = i; | ||
140 | break; | ||
141 | } | ||
142 | } | ||
143 | |||
144 | out: | ||
145 | if (hwc->idx == -1) | ||
146 | return -EBUSY; | ||
147 | |||
148 | hwc->config_base = uncore->msr_base + (2 * hwc->idx); | ||
149 | hwc->event_base = uncore->msr_base + 1 + (2 * hwc->idx); | ||
150 | hwc->event_base_rdpmc = uncore->rdpmc_base + hwc->idx; | ||
151 | hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; | ||
152 | |||
153 | if (flags & PERF_EF_START) | ||
154 | amd_uncore_start(event, PERF_EF_RELOAD); | ||
155 | |||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | static void amd_uncore_del(struct perf_event *event, int flags) | ||
160 | { | ||
161 | int i; | ||
162 | struct amd_uncore *uncore = event_to_amd_uncore(event); | ||
163 | struct hw_perf_event *hwc = &event->hw; | ||
164 | |||
165 | amd_uncore_stop(event, PERF_EF_UPDATE); | ||
166 | |||
167 | for (i = 0; i < uncore->num_counters; i++) { | ||
168 | if (cmpxchg(&uncore->events[i], event, NULL) == event) | ||
169 | break; | ||
170 | } | ||
171 | |||
172 | hwc->idx = -1; | ||
173 | } | ||
174 | |||
175 | static int amd_uncore_event_init(struct perf_event *event) | ||
176 | { | ||
177 | struct amd_uncore *uncore; | ||
178 | struct hw_perf_event *hwc = &event->hw; | ||
179 | |||
180 | if (event->attr.type != event->pmu->type) | ||
181 | return -ENOENT; | ||
182 | |||
183 | /* | ||
184 | * NB and L2 counters (MSRs) are shared across all cores that share the | ||
185 | * same NB / L2 cache. Interrupts can be directed to a single target | ||
186 | * core, however, event counts generated by processes running on other | ||
187 | * cores cannot be masked out. So we do not support sampling and | ||
188 | * per-thread events. | ||
189 | */ | ||
190 | if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK) | ||
191 | return -EINVAL; | ||
192 | |||
193 | /* NB and L2 counters do not have usr/os/guest/host bits */ | ||
194 | if (event->attr.exclude_user || event->attr.exclude_kernel || | ||
195 | event->attr.exclude_host || event->attr.exclude_guest) | ||
196 | return -EINVAL; | ||
197 | |||
198 | /* and we do not enable counter overflow interrupts */ | ||
199 | hwc->config = event->attr.config & AMD64_RAW_EVENT_MASK_NB; | ||
200 | hwc->idx = -1; | ||
201 | |||
202 | if (event->cpu < 0) | ||
203 | return -EINVAL; | ||
204 | |||
205 | uncore = event_to_amd_uncore(event); | ||
206 | if (!uncore) | ||
207 | return -ENODEV; | ||
208 | |||
209 | /* | ||
210 | * since request can come in to any of the shared cores, we will remap | ||
211 | * to a single common cpu. | ||
212 | */ | ||
213 | event->cpu = uncore->cpu; | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | static ssize_t amd_uncore_attr_show_cpumask(struct device *dev, | ||
219 | struct device_attribute *attr, | ||
220 | char *buf) | ||
221 | { | ||
222 | int n; | ||
223 | cpumask_t *active_mask; | ||
224 | struct pmu *pmu = dev_get_drvdata(dev); | ||
225 | |||
226 | if (pmu->type == amd_nb_pmu.type) | ||
227 | active_mask = &amd_nb_active_mask; | ||
228 | else if (pmu->type == amd_l2_pmu.type) | ||
229 | active_mask = &amd_l2_active_mask; | ||
230 | else | ||
231 | return 0; | ||
232 | |||
233 | n = cpulist_scnprintf(buf, PAGE_SIZE - 2, active_mask); | ||
234 | buf[n++] = '\n'; | ||
235 | buf[n] = '\0'; | ||
236 | return n; | ||
237 | } | ||
238 | static DEVICE_ATTR(cpumask, S_IRUGO, amd_uncore_attr_show_cpumask, NULL); | ||
239 | |||
240 | static struct attribute *amd_uncore_attrs[] = { | ||
241 | &dev_attr_cpumask.attr, | ||
242 | NULL, | ||
243 | }; | ||
244 | |||
245 | static struct attribute_group amd_uncore_attr_group = { | ||
246 | .attrs = amd_uncore_attrs, | ||
247 | }; | ||
248 | |||
249 | PMU_FORMAT_ATTR(event, "config:0-7,32-35"); | ||
250 | PMU_FORMAT_ATTR(umask, "config:8-15"); | ||
251 | |||
252 | static struct attribute *amd_uncore_format_attr[] = { | ||
253 | &format_attr_event.attr, | ||
254 | &format_attr_umask.attr, | ||
255 | NULL, | ||
256 | }; | ||
257 | |||
258 | static struct attribute_group amd_uncore_format_group = { | ||
259 | .name = "format", | ||
260 | .attrs = amd_uncore_format_attr, | ||
261 | }; | ||
262 | |||
263 | static const struct attribute_group *amd_uncore_attr_groups[] = { | ||
264 | &amd_uncore_attr_group, | ||
265 | &amd_uncore_format_group, | ||
266 | NULL, | ||
267 | }; | ||
268 | |||
269 | static struct pmu amd_nb_pmu = { | ||
270 | .attr_groups = amd_uncore_attr_groups, | ||
271 | .name = "amd_nb", | ||
272 | .event_init = amd_uncore_event_init, | ||
273 | .add = amd_uncore_add, | ||
274 | .del = amd_uncore_del, | ||
275 | .start = amd_uncore_start, | ||
276 | .stop = amd_uncore_stop, | ||
277 | .read = amd_uncore_read, | ||
278 | }; | ||
279 | |||
280 | static struct pmu amd_l2_pmu = { | ||
281 | .attr_groups = amd_uncore_attr_groups, | ||
282 | .name = "amd_l2", | ||
283 | .event_init = amd_uncore_event_init, | ||
284 | .add = amd_uncore_add, | ||
285 | .del = amd_uncore_del, | ||
286 | .start = amd_uncore_start, | ||
287 | .stop = amd_uncore_stop, | ||
288 | .read = amd_uncore_read, | ||
289 | }; | ||
290 | |||
291 | static struct amd_uncore * __cpuinit amd_uncore_alloc(unsigned int cpu) | ||
292 | { | ||
293 | return kzalloc_node(sizeof(struct amd_uncore), GFP_KERNEL, | ||
294 | cpu_to_node(cpu)); | ||
295 | } | ||
296 | |||
297 | static void __cpuinit amd_uncore_cpu_up_prepare(unsigned int cpu) | ||
298 | { | ||
299 | struct amd_uncore *uncore; | ||
300 | |||
301 | if (amd_uncore_nb) { | ||
302 | uncore = amd_uncore_alloc(cpu); | ||
303 | uncore->cpu = cpu; | ||
304 | uncore->num_counters = NUM_COUNTERS_NB; | ||
305 | uncore->rdpmc_base = RDPMC_BASE_NB; | ||
306 | uncore->msr_base = MSR_F15H_NB_PERF_CTL; | ||
307 | uncore->active_mask = &amd_nb_active_mask; | ||
308 | uncore->pmu = &amd_nb_pmu; | ||
309 | *per_cpu_ptr(amd_uncore_nb, cpu) = uncore; | ||
310 | } | ||
311 | |||
312 | if (amd_uncore_l2) { | ||
313 | uncore = amd_uncore_alloc(cpu); | ||
314 | uncore->cpu = cpu; | ||
315 | uncore->num_counters = NUM_COUNTERS_L2; | ||
316 | uncore->rdpmc_base = RDPMC_BASE_L2; | ||
317 | uncore->msr_base = MSR_F16H_L2I_PERF_CTL; | ||
318 | uncore->active_mask = &amd_l2_active_mask; | ||
319 | uncore->pmu = &amd_l2_pmu; | ||
320 | *per_cpu_ptr(amd_uncore_l2, cpu) = uncore; | ||
321 | } | ||
322 | } | ||
323 | |||
324 | static struct amd_uncore * | ||
325 | __cpuinit amd_uncore_find_online_sibling(struct amd_uncore *this, | ||
326 | struct amd_uncore * __percpu *uncores) | ||
327 | { | ||
328 | unsigned int cpu; | ||
329 | struct amd_uncore *that; | ||
330 | |||
331 | for_each_online_cpu(cpu) { | ||
332 | that = *per_cpu_ptr(uncores, cpu); | ||
333 | |||
334 | if (!that) | ||
335 | continue; | ||
336 | |||
337 | if (this == that) | ||
338 | continue; | ||
339 | |||
340 | if (this->id == that->id) { | ||
341 | that->free_when_cpu_online = this; | ||
342 | this = that; | ||
343 | break; | ||
344 | } | ||
345 | } | ||
346 | |||
347 | this->refcnt++; | ||
348 | return this; | ||
349 | } | ||
350 | |||
351 | static void __cpuinit amd_uncore_cpu_starting(unsigned int cpu) | ||
352 | { | ||
353 | unsigned int eax, ebx, ecx, edx; | ||
354 | struct amd_uncore *uncore; | ||
355 | |||
356 | if (amd_uncore_nb) { | ||
357 | uncore = *per_cpu_ptr(amd_uncore_nb, cpu); | ||
358 | cpuid(0x8000001e, &eax, &ebx, &ecx, &edx); | ||
359 | uncore->id = ecx & 0xff; | ||
360 | |||
361 | uncore = amd_uncore_find_online_sibling(uncore, amd_uncore_nb); | ||
362 | *per_cpu_ptr(amd_uncore_nb, cpu) = uncore; | ||
363 | } | ||
364 | |||
365 | if (amd_uncore_l2) { | ||
366 | unsigned int apicid = cpu_data(cpu).apicid; | ||
367 | unsigned int nshared; | ||
368 | |||
369 | uncore = *per_cpu_ptr(amd_uncore_l2, cpu); | ||
370 | cpuid_count(0x8000001d, 2, &eax, &ebx, &ecx, &edx); | ||
371 | nshared = ((eax >> 14) & 0xfff) + 1; | ||
372 | uncore->id = apicid - (apicid % nshared); | ||
373 | |||
374 | uncore = amd_uncore_find_online_sibling(uncore, amd_uncore_l2); | ||
375 | *per_cpu_ptr(amd_uncore_l2, cpu) = uncore; | ||
376 | } | ||
377 | } | ||
378 | |||
379 | static void __cpuinit uncore_online(unsigned int cpu, | ||
380 | struct amd_uncore * __percpu *uncores) | ||
381 | { | ||
382 | struct amd_uncore *uncore = *per_cpu_ptr(uncores, cpu); | ||
383 | |||
384 | kfree(uncore->free_when_cpu_online); | ||
385 | uncore->free_when_cpu_online = NULL; | ||
386 | |||
387 | if (cpu == uncore->cpu) | ||
388 | cpumask_set_cpu(cpu, uncore->active_mask); | ||
389 | } | ||
390 | |||
391 | static void __cpuinit amd_uncore_cpu_online(unsigned int cpu) | ||
392 | { | ||
393 | if (amd_uncore_nb) | ||
394 | uncore_online(cpu, amd_uncore_nb); | ||
395 | |||
396 | if (amd_uncore_l2) | ||
397 | uncore_online(cpu, amd_uncore_l2); | ||
398 | } | ||
399 | |||
400 | static void __cpuinit uncore_down_prepare(unsigned int cpu, | ||
401 | struct amd_uncore * __percpu *uncores) | ||
402 | { | ||
403 | unsigned int i; | ||
404 | struct amd_uncore *this = *per_cpu_ptr(uncores, cpu); | ||
405 | |||
406 | if (this->cpu != cpu) | ||
407 | return; | ||
408 | |||
409 | /* this cpu is going down, migrate to a shared sibling if possible */ | ||
410 | for_each_online_cpu(i) { | ||
411 | struct amd_uncore *that = *per_cpu_ptr(uncores, i); | ||
412 | |||
413 | if (cpu == i) | ||
414 | continue; | ||
415 | |||
416 | if (this == that) { | ||
417 | perf_pmu_migrate_context(this->pmu, cpu, i); | ||
418 | cpumask_clear_cpu(cpu, that->active_mask); | ||
419 | cpumask_set_cpu(i, that->active_mask); | ||
420 | that->cpu = i; | ||
421 | break; | ||
422 | } | ||
423 | } | ||
424 | } | ||
425 | |||
426 | static void __cpuinit amd_uncore_cpu_down_prepare(unsigned int cpu) | ||
427 | { | ||
428 | if (amd_uncore_nb) | ||
429 | uncore_down_prepare(cpu, amd_uncore_nb); | ||
430 | |||
431 | if (amd_uncore_l2) | ||
432 | uncore_down_prepare(cpu, amd_uncore_l2); | ||
433 | } | ||
434 | |||
435 | static void __cpuinit uncore_dead(unsigned int cpu, | ||
436 | struct amd_uncore * __percpu *uncores) | ||
437 | { | ||
438 | struct amd_uncore *uncore = *per_cpu_ptr(uncores, cpu); | ||
439 | |||
440 | if (cpu == uncore->cpu) | ||
441 | cpumask_clear_cpu(cpu, uncore->active_mask); | ||
442 | |||
443 | if (!--uncore->refcnt) | ||
444 | kfree(uncore); | ||
445 | *per_cpu_ptr(amd_uncore_nb, cpu) = NULL; | ||
446 | } | ||
447 | |||
448 | static void __cpuinit amd_uncore_cpu_dead(unsigned int cpu) | ||
449 | { | ||
450 | if (amd_uncore_nb) | ||
451 | uncore_dead(cpu, amd_uncore_nb); | ||
452 | |||
453 | if (amd_uncore_l2) | ||
454 | uncore_dead(cpu, amd_uncore_l2); | ||
455 | } | ||
456 | |||
457 | static int __cpuinit | ||
458 | amd_uncore_cpu_notifier(struct notifier_block *self, unsigned long action, | ||
459 | void *hcpu) | ||
460 | { | ||
461 | unsigned int cpu = (long)hcpu; | ||
462 | |||
463 | switch (action & ~CPU_TASKS_FROZEN) { | ||
464 | case CPU_UP_PREPARE: | ||
465 | amd_uncore_cpu_up_prepare(cpu); | ||
466 | break; | ||
467 | |||
468 | case CPU_STARTING: | ||
469 | amd_uncore_cpu_starting(cpu); | ||
470 | break; | ||
471 | |||
472 | case CPU_ONLINE: | ||
473 | amd_uncore_cpu_online(cpu); | ||
474 | break; | ||
475 | |||
476 | case CPU_DOWN_PREPARE: | ||
477 | amd_uncore_cpu_down_prepare(cpu); | ||
478 | break; | ||
479 | |||
480 | case CPU_UP_CANCELED: | ||
481 | case CPU_DEAD: | ||
482 | amd_uncore_cpu_dead(cpu); | ||
483 | break; | ||
484 | |||
485 | default: | ||
486 | break; | ||
487 | } | ||
488 | |||
489 | return NOTIFY_OK; | ||
490 | } | ||
491 | |||
492 | static struct notifier_block amd_uncore_cpu_notifier_block __cpuinitdata = { | ||
493 | .notifier_call = amd_uncore_cpu_notifier, | ||
494 | .priority = CPU_PRI_PERF + 1, | ||
495 | }; | ||
496 | |||
497 | static void __init init_cpu_already_online(void *dummy) | ||
498 | { | ||
499 | unsigned int cpu = smp_processor_id(); | ||
500 | |||
501 | amd_uncore_cpu_starting(cpu); | ||
502 | amd_uncore_cpu_online(cpu); | ||
503 | } | ||
504 | |||
505 | static int __init amd_uncore_init(void) | ||
506 | { | ||
507 | unsigned int cpu; | ||
508 | int ret = -ENODEV; | ||
509 | |||
510 | if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) | ||
511 | return -ENODEV; | ||
512 | |||
513 | if (!cpu_has_topoext) | ||
514 | return -ENODEV; | ||
515 | |||
516 | if (cpu_has_perfctr_nb) { | ||
517 | amd_uncore_nb = alloc_percpu(struct amd_uncore *); | ||
518 | perf_pmu_register(&amd_nb_pmu, amd_nb_pmu.name, -1); | ||
519 | |||
520 | printk(KERN_INFO "perf: AMD NB counters detected\n"); | ||
521 | ret = 0; | ||
522 | } | ||
523 | |||
524 | if (cpu_has_perfctr_l2) { | ||
525 | amd_uncore_l2 = alloc_percpu(struct amd_uncore *); | ||
526 | perf_pmu_register(&amd_l2_pmu, amd_l2_pmu.name, -1); | ||
527 | |||
528 | printk(KERN_INFO "perf: AMD L2I counters detected\n"); | ||
529 | ret = 0; | ||
530 | } | ||
531 | |||
532 | if (ret) | ||
533 | return -ENODEV; | ||
534 | |||
535 | get_online_cpus(); | ||
536 | /* init cpus already online before registering for hotplug notifier */ | ||
537 | for_each_online_cpu(cpu) { | ||
538 | amd_uncore_cpu_up_prepare(cpu); | ||
539 | smp_call_function_single(cpu, init_cpu_already_online, NULL, 1); | ||
540 | } | ||
541 | |||
542 | register_cpu_notifier(&amd_uncore_cpu_notifier_block); | ||
543 | put_online_cpus(); | ||
544 | |||
545 | return 0; | ||
546 | } | ||
547 | device_initcall(amd_uncore_init); | ||
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index dab7580c47ae..ffd6050a1de4 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
@@ -81,6 +81,7 @@ static struct event_constraint intel_nehalem_event_constraints[] __read_mostly = | |||
81 | static struct extra_reg intel_nehalem_extra_regs[] __read_mostly = | 81 | static struct extra_reg intel_nehalem_extra_regs[] __read_mostly = |
82 | { | 82 | { |
83 | INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0xffff, RSP_0), | 83 | INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0xffff, RSP_0), |
84 | INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x100b), | ||
84 | EVENT_EXTRA_END | 85 | EVENT_EXTRA_END |
85 | }; | 86 | }; |
86 | 87 | ||
@@ -108,6 +109,8 @@ static struct event_constraint intel_snb_event_constraints[] __read_mostly = | |||
108 | INTEL_EVENT_CONSTRAINT(0x48, 0x4), /* L1D_PEND_MISS.PENDING */ | 109 | INTEL_EVENT_CONSTRAINT(0x48, 0x4), /* L1D_PEND_MISS.PENDING */ |
109 | INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */ | 110 | INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */ |
110 | INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */ | 111 | INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */ |
112 | INTEL_UEVENT_CONSTRAINT(0x04a3, 0xf), /* CYCLE_ACTIVITY.CYCLES_NO_DISPATCH */ | ||
113 | INTEL_UEVENT_CONSTRAINT(0x02a3, 0x4), /* CYCLE_ACTIVITY.CYCLES_L1D_PENDING */ | ||
111 | EVENT_CONSTRAINT_END | 114 | EVENT_CONSTRAINT_END |
112 | }; | 115 | }; |
113 | 116 | ||
@@ -136,6 +139,7 @@ static struct extra_reg intel_westmere_extra_regs[] __read_mostly = | |||
136 | { | 139 | { |
137 | INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0xffff, RSP_0), | 140 | INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0xffff, RSP_0), |
138 | INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0xffff, RSP_1), | 141 | INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0xffff, RSP_1), |
142 | INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x100b), | ||
139 | EVENT_EXTRA_END | 143 | EVENT_EXTRA_END |
140 | }; | 144 | }; |
141 | 145 | ||
@@ -153,11 +157,34 @@ static struct event_constraint intel_gen_event_constraints[] __read_mostly = | |||
153 | }; | 157 | }; |
154 | 158 | ||
155 | static struct extra_reg intel_snb_extra_regs[] __read_mostly = { | 159 | static struct extra_reg intel_snb_extra_regs[] __read_mostly = { |
156 | INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3fffffffffull, RSP_0), | 160 | INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3f807f8fffull, RSP_0), |
157 | INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3fffffffffull, RSP_1), | 161 | INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3f807f8fffull, RSP_1), |
162 | INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd), | ||
163 | INTEL_UEVENT_PEBS_LDLAT_EXTRA_REG(0x01cd), | ||
164 | EVENT_EXTRA_END | ||
165 | }; | ||
166 | |||
167 | static struct extra_reg intel_snbep_extra_regs[] __read_mostly = { | ||
168 | INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3fffff8fffull, RSP_0), | ||
169 | INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3fffff8fffull, RSP_1), | ||
158 | EVENT_EXTRA_END | 170 | EVENT_EXTRA_END |
159 | }; | 171 | }; |
160 | 172 | ||
173 | EVENT_ATTR_STR(mem-loads, mem_ld_nhm, "event=0x0b,umask=0x10,ldlat=3"); | ||
174 | EVENT_ATTR_STR(mem-loads, mem_ld_snb, "event=0xcd,umask=0x1,ldlat=3"); | ||
175 | EVENT_ATTR_STR(mem-stores, mem_st_snb, "event=0xcd,umask=0x2"); | ||
176 | |||
177 | struct attribute *nhm_events_attrs[] = { | ||
178 | EVENT_PTR(mem_ld_nhm), | ||
179 | NULL, | ||
180 | }; | ||
181 | |||
182 | struct attribute *snb_events_attrs[] = { | ||
183 | EVENT_PTR(mem_ld_snb), | ||
184 | EVENT_PTR(mem_st_snb), | ||
185 | NULL, | ||
186 | }; | ||
187 | |||
161 | static u64 intel_pmu_event_map(int hw_event) | 188 | static u64 intel_pmu_event_map(int hw_event) |
162 | { | 189 | { |
163 | return intel_perfmon_event_map[hw_event]; | 190 | return intel_perfmon_event_map[hw_event]; |
@@ -1392,8 +1419,11 @@ x86_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event) | |||
1392 | 1419 | ||
1393 | if (x86_pmu.event_constraints) { | 1420 | if (x86_pmu.event_constraints) { |
1394 | for_each_event_constraint(c, x86_pmu.event_constraints) { | 1421 | for_each_event_constraint(c, x86_pmu.event_constraints) { |
1395 | if ((event->hw.config & c->cmask) == c->code) | 1422 | if ((event->hw.config & c->cmask) == c->code) { |
1423 | /* hw.flags zeroed at initialization */ | ||
1424 | event->hw.flags |= c->flags; | ||
1396 | return c; | 1425 | return c; |
1426 | } | ||
1397 | } | 1427 | } |
1398 | } | 1428 | } |
1399 | 1429 | ||
@@ -1438,6 +1468,7 @@ intel_put_shared_regs_event_constraints(struct cpu_hw_events *cpuc, | |||
1438 | static void intel_put_event_constraints(struct cpu_hw_events *cpuc, | 1468 | static void intel_put_event_constraints(struct cpu_hw_events *cpuc, |
1439 | struct perf_event *event) | 1469 | struct perf_event *event) |
1440 | { | 1470 | { |
1471 | event->hw.flags = 0; | ||
1441 | intel_put_shared_regs_event_constraints(cpuc, event); | 1472 | intel_put_shared_regs_event_constraints(cpuc, event); |
1442 | } | 1473 | } |
1443 | 1474 | ||
@@ -1761,6 +1792,8 @@ static void intel_pmu_flush_branch_stack(void) | |||
1761 | 1792 | ||
1762 | PMU_FORMAT_ATTR(offcore_rsp, "config1:0-63"); | 1793 | PMU_FORMAT_ATTR(offcore_rsp, "config1:0-63"); |
1763 | 1794 | ||
1795 | PMU_FORMAT_ATTR(ldlat, "config1:0-15"); | ||
1796 | |||
1764 | static struct attribute *intel_arch3_formats_attr[] = { | 1797 | static struct attribute *intel_arch3_formats_attr[] = { |
1765 | &format_attr_event.attr, | 1798 | &format_attr_event.attr, |
1766 | &format_attr_umask.attr, | 1799 | &format_attr_umask.attr, |
@@ -1771,6 +1804,7 @@ static struct attribute *intel_arch3_formats_attr[] = { | |||
1771 | &format_attr_cmask.attr, | 1804 | &format_attr_cmask.attr, |
1772 | 1805 | ||
1773 | &format_attr_offcore_rsp.attr, /* XXX do NHM/WSM + SNB breakout */ | 1806 | &format_attr_offcore_rsp.attr, /* XXX do NHM/WSM + SNB breakout */ |
1807 | &format_attr_ldlat.attr, /* PEBS load latency */ | ||
1774 | NULL, | 1808 | NULL, |
1775 | }; | 1809 | }; |
1776 | 1810 | ||
@@ -2031,6 +2065,8 @@ __init int intel_pmu_init(void) | |||
2031 | x86_pmu.enable_all = intel_pmu_nhm_enable_all; | 2065 | x86_pmu.enable_all = intel_pmu_nhm_enable_all; |
2032 | x86_pmu.extra_regs = intel_nehalem_extra_regs; | 2066 | x86_pmu.extra_regs = intel_nehalem_extra_regs; |
2033 | 2067 | ||
2068 | x86_pmu.cpu_events = nhm_events_attrs; | ||
2069 | |||
2034 | /* UOPS_ISSUED.STALLED_CYCLES */ | 2070 | /* UOPS_ISSUED.STALLED_CYCLES */ |
2035 | intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = | 2071 | intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = |
2036 | X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1); | 2072 | X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1); |
@@ -2074,6 +2110,8 @@ __init int intel_pmu_init(void) | |||
2074 | x86_pmu.extra_regs = intel_westmere_extra_regs; | 2110 | x86_pmu.extra_regs = intel_westmere_extra_regs; |
2075 | x86_pmu.er_flags |= ERF_HAS_RSP_1; | 2111 | x86_pmu.er_flags |= ERF_HAS_RSP_1; |
2076 | 2112 | ||
2113 | x86_pmu.cpu_events = nhm_events_attrs; | ||
2114 | |||
2077 | /* UOPS_ISSUED.STALLED_CYCLES */ | 2115 | /* UOPS_ISSUED.STALLED_CYCLES */ |
2078 | intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = | 2116 | intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = |
2079 | X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1); | 2117 | X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1); |
@@ -2097,11 +2135,16 @@ __init int intel_pmu_init(void) | |||
2097 | x86_pmu.event_constraints = intel_snb_event_constraints; | 2135 | x86_pmu.event_constraints = intel_snb_event_constraints; |
2098 | x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints; | 2136 | x86_pmu.pebs_constraints = intel_snb_pebs_event_constraints; |
2099 | x86_pmu.pebs_aliases = intel_pebs_aliases_snb; | 2137 | x86_pmu.pebs_aliases = intel_pebs_aliases_snb; |
2100 | x86_pmu.extra_regs = intel_snb_extra_regs; | 2138 | if (boot_cpu_data.x86_model == 45) |
2139 | x86_pmu.extra_regs = intel_snbep_extra_regs; | ||
2140 | else | ||
2141 | x86_pmu.extra_regs = intel_snb_extra_regs; | ||
2101 | /* all extra regs are per-cpu when HT is on */ | 2142 | /* all extra regs are per-cpu when HT is on */ |
2102 | x86_pmu.er_flags |= ERF_HAS_RSP_1; | 2143 | x86_pmu.er_flags |= ERF_HAS_RSP_1; |
2103 | x86_pmu.er_flags |= ERF_NO_HT_SHARING; | 2144 | x86_pmu.er_flags |= ERF_NO_HT_SHARING; |
2104 | 2145 | ||
2146 | x86_pmu.cpu_events = snb_events_attrs; | ||
2147 | |||
2105 | /* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */ | 2148 | /* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */ |
2106 | intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = | 2149 | intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = |
2107 | X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1); | 2150 | X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1); |
@@ -2123,11 +2166,16 @@ __init int intel_pmu_init(void) | |||
2123 | x86_pmu.event_constraints = intel_ivb_event_constraints; | 2166 | x86_pmu.event_constraints = intel_ivb_event_constraints; |
2124 | x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints; | 2167 | x86_pmu.pebs_constraints = intel_ivb_pebs_event_constraints; |
2125 | x86_pmu.pebs_aliases = intel_pebs_aliases_snb; | 2168 | x86_pmu.pebs_aliases = intel_pebs_aliases_snb; |
2126 | x86_pmu.extra_regs = intel_snb_extra_regs; | 2169 | if (boot_cpu_data.x86_model == 62) |
2170 | x86_pmu.extra_regs = intel_snbep_extra_regs; | ||
2171 | else | ||
2172 | x86_pmu.extra_regs = intel_snb_extra_regs; | ||
2127 | /* all extra regs are per-cpu when HT is on */ | 2173 | /* all extra regs are per-cpu when HT is on */ |
2128 | x86_pmu.er_flags |= ERF_HAS_RSP_1; | 2174 | x86_pmu.er_flags |= ERF_HAS_RSP_1; |
2129 | x86_pmu.er_flags |= ERF_NO_HT_SHARING; | 2175 | x86_pmu.er_flags |= ERF_NO_HT_SHARING; |
2130 | 2176 | ||
2177 | x86_pmu.cpu_events = snb_events_attrs; | ||
2178 | |||
2131 | /* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */ | 2179 | /* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */ |
2132 | intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = | 2180 | intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = |
2133 | X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1); | 2181 | X86_CONFIG(.event=0x0e, .umask=0x01, .inv=1, .cmask=1); |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index b05a575d56f4..60250f687052 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c | |||
@@ -24,6 +24,130 @@ struct pebs_record_32 { | |||
24 | 24 | ||
25 | */ | 25 | */ |
26 | 26 | ||
27 | union intel_x86_pebs_dse { | ||
28 | u64 val; | ||
29 | struct { | ||
30 | unsigned int ld_dse:4; | ||
31 | unsigned int ld_stlb_miss:1; | ||
32 | unsigned int ld_locked:1; | ||
33 | unsigned int ld_reserved:26; | ||
34 | }; | ||
35 | struct { | ||
36 | unsigned int st_l1d_hit:1; | ||
37 | unsigned int st_reserved1:3; | ||
38 | unsigned int st_stlb_miss:1; | ||
39 | unsigned int st_locked:1; | ||
40 | unsigned int st_reserved2:26; | ||
41 | }; | ||
42 | }; | ||
43 | |||
44 | |||
45 | /* | ||
46 | * Map PEBS Load Latency Data Source encodings to generic | ||
47 | * memory data source information | ||
48 | */ | ||
49 | #define P(a, b) PERF_MEM_S(a, b) | ||
50 | #define OP_LH (P(OP, LOAD) | P(LVL, HIT)) | ||
51 | #define SNOOP_NONE_MISS (P(SNOOP, NONE) | P(SNOOP, MISS)) | ||
52 | |||
53 | static const u64 pebs_data_source[] = { | ||
54 | P(OP, LOAD) | P(LVL, MISS) | P(LVL, L3) | P(SNOOP, NA),/* 0x00:ukn L3 */ | ||
55 | OP_LH | P(LVL, L1) | P(SNOOP, NONE), /* 0x01: L1 local */ | ||
56 | OP_LH | P(LVL, LFB) | P(SNOOP, NONE), /* 0x02: LFB hit */ | ||
57 | OP_LH | P(LVL, L2) | P(SNOOP, NONE), /* 0x03: L2 hit */ | ||
58 | OP_LH | P(LVL, L3) | P(SNOOP, NONE), /* 0x04: L3 hit */ | ||
59 | OP_LH | P(LVL, L3) | P(SNOOP, MISS), /* 0x05: L3 hit, snoop miss */ | ||
60 | OP_LH | P(LVL, L3) | P(SNOOP, HIT), /* 0x06: L3 hit, snoop hit */ | ||
61 | OP_LH | P(LVL, L3) | P(SNOOP, HITM), /* 0x07: L3 hit, snoop hitm */ | ||
62 | OP_LH | P(LVL, REM_CCE1) | P(SNOOP, HIT), /* 0x08: L3 miss snoop hit */ | ||
63 | OP_LH | P(LVL, REM_CCE1) | P(SNOOP, HITM), /* 0x09: L3 miss snoop hitm*/ | ||
64 | OP_LH | P(LVL, LOC_RAM) | P(SNOOP, HIT), /* 0x0a: L3 miss, shared */ | ||
65 | OP_LH | P(LVL, REM_RAM1) | P(SNOOP, HIT), /* 0x0b: L3 miss, shared */ | ||
66 | OP_LH | P(LVL, LOC_RAM) | SNOOP_NONE_MISS,/* 0x0c: L3 miss, excl */ | ||
67 | OP_LH | P(LVL, REM_RAM1) | SNOOP_NONE_MISS,/* 0x0d: L3 miss, excl */ | ||
68 | OP_LH | P(LVL, IO) | P(SNOOP, NONE), /* 0x0e: I/O */ | ||
69 | OP_LH | P(LVL, UNC) | P(SNOOP, NONE), /* 0x0f: uncached */ | ||
70 | }; | ||
71 | |||
72 | static u64 precise_store_data(u64 status) | ||
73 | { | ||
74 | union intel_x86_pebs_dse dse; | ||
75 | u64 val = P(OP, STORE) | P(SNOOP, NA) | P(LVL, L1) | P(TLB, L2); | ||
76 | |||
77 | dse.val = status; | ||
78 | |||
79 | /* | ||
80 | * bit 4: TLB access | ||
81 | * 1 = stored missed 2nd level TLB | ||
82 | * | ||
83 | * so it either hit the walker or the OS | ||
84 | * otherwise hit 2nd level TLB | ||
85 | */ | ||
86 | if (dse.st_stlb_miss) | ||
87 | val |= P(TLB, MISS); | ||
88 | else | ||
89 | val |= P(TLB, HIT); | ||
90 | |||
91 | /* | ||
92 | * bit 0: hit L1 data cache | ||
93 | * if not set, then all we know is that | ||
94 | * it missed L1D | ||
95 | */ | ||
96 | if (dse.st_l1d_hit) | ||
97 | val |= P(LVL, HIT); | ||
98 | else | ||
99 | val |= P(LVL, MISS); | ||
100 | |||
101 | /* | ||
102 | * bit 5: Locked prefix | ||
103 | */ | ||
104 | if (dse.st_locked) | ||
105 | val |= P(LOCK, LOCKED); | ||
106 | |||
107 | return val; | ||
108 | } | ||
109 | |||
110 | static u64 load_latency_data(u64 status) | ||
111 | { | ||
112 | union intel_x86_pebs_dse dse; | ||
113 | u64 val; | ||
114 | int model = boot_cpu_data.x86_model; | ||
115 | int fam = boot_cpu_data.x86; | ||
116 | |||
117 | dse.val = status; | ||
118 | |||
119 | /* | ||
120 | * use the mapping table for bit 0-3 | ||
121 | */ | ||
122 | val = pebs_data_source[dse.ld_dse]; | ||
123 | |||
124 | /* | ||
125 | * Nehalem models do not support TLB, Lock infos | ||
126 | */ | ||
127 | if (fam == 0x6 && (model == 26 || model == 30 | ||
128 | || model == 31 || model == 46)) { | ||
129 | val |= P(TLB, NA) | P(LOCK, NA); | ||
130 | return val; | ||
131 | } | ||
132 | /* | ||
133 | * bit 4: TLB access | ||
134 | * 0 = did not miss 2nd level TLB | ||
135 | * 1 = missed 2nd level TLB | ||
136 | */ | ||
137 | if (dse.ld_stlb_miss) | ||
138 | val |= P(TLB, MISS) | P(TLB, L2); | ||
139 | else | ||
140 | val |= P(TLB, HIT) | P(TLB, L1) | P(TLB, L2); | ||
141 | |||
142 | /* | ||
143 | * bit 5: locked prefix | ||
144 | */ | ||
145 | if (dse.ld_locked) | ||
146 | val |= P(LOCK, LOCKED); | ||
147 | |||
148 | return val; | ||
149 | } | ||
150 | |||
27 | struct pebs_record_core { | 151 | struct pebs_record_core { |
28 | u64 flags, ip; | 152 | u64 flags, ip; |
29 | u64 ax, bx, cx, dx; | 153 | u64 ax, bx, cx, dx; |
@@ -314,10 +438,11 @@ int intel_pmu_drain_bts_buffer(void) | |||
314 | if (top <= at) | 438 | if (top <= at) |
315 | return 0; | 439 | return 0; |
316 | 440 | ||
441 | memset(®s, 0, sizeof(regs)); | ||
442 | |||
317 | ds->bts_index = ds->bts_buffer_base; | 443 | ds->bts_index = ds->bts_buffer_base; |
318 | 444 | ||
319 | perf_sample_data_init(&data, 0, event->hw.last_period); | 445 | perf_sample_data_init(&data, 0, event->hw.last_period); |
320 | regs.ip = 0; | ||
321 | 446 | ||
322 | /* | 447 | /* |
323 | * Prepare a generic sample, i.e. fill in the invariant fields. | 448 | * Prepare a generic sample, i.e. fill in the invariant fields. |
@@ -364,7 +489,7 @@ struct event_constraint intel_atom_pebs_event_constraints[] = { | |||
364 | }; | 489 | }; |
365 | 490 | ||
366 | struct event_constraint intel_nehalem_pebs_event_constraints[] = { | 491 | struct event_constraint intel_nehalem_pebs_event_constraints[] = { |
367 | INTEL_EVENT_CONSTRAINT(0x0b, 0xf), /* MEM_INST_RETIRED.* */ | 492 | INTEL_PLD_CONSTRAINT(0x100b, 0xf), /* MEM_INST_RETIRED.* */ |
368 | INTEL_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */ | 493 | INTEL_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */ |
369 | INTEL_UEVENT_CONSTRAINT(0x010c, 0xf), /* MEM_STORE_RETIRED.DTLB_MISS */ | 494 | INTEL_UEVENT_CONSTRAINT(0x010c, 0xf), /* MEM_STORE_RETIRED.DTLB_MISS */ |
370 | INTEL_EVENT_CONSTRAINT(0xc0, 0xf), /* INST_RETIRED.ANY */ | 495 | INTEL_EVENT_CONSTRAINT(0xc0, 0xf), /* INST_RETIRED.ANY */ |
@@ -379,7 +504,7 @@ struct event_constraint intel_nehalem_pebs_event_constraints[] = { | |||
379 | }; | 504 | }; |
380 | 505 | ||
381 | struct event_constraint intel_westmere_pebs_event_constraints[] = { | 506 | struct event_constraint intel_westmere_pebs_event_constraints[] = { |
382 | INTEL_EVENT_CONSTRAINT(0x0b, 0xf), /* MEM_INST_RETIRED.* */ | 507 | INTEL_PLD_CONSTRAINT(0x100b, 0xf), /* MEM_INST_RETIRED.* */ |
383 | INTEL_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */ | 508 | INTEL_EVENT_CONSTRAINT(0x0f, 0xf), /* MEM_UNCORE_RETIRED.* */ |
384 | INTEL_UEVENT_CONSTRAINT(0x010c, 0xf), /* MEM_STORE_RETIRED.DTLB_MISS */ | 509 | INTEL_UEVENT_CONSTRAINT(0x010c, 0xf), /* MEM_STORE_RETIRED.DTLB_MISS */ |
385 | INTEL_EVENT_CONSTRAINT(0xc0, 0xf), /* INSTR_RETIRED.* */ | 510 | INTEL_EVENT_CONSTRAINT(0xc0, 0xf), /* INSTR_RETIRED.* */ |
@@ -399,7 +524,8 @@ struct event_constraint intel_snb_pebs_event_constraints[] = { | |||
399 | INTEL_UEVENT_CONSTRAINT(0x02c2, 0xf), /* UOPS_RETIRED.RETIRE_SLOTS */ | 524 | INTEL_UEVENT_CONSTRAINT(0x02c2, 0xf), /* UOPS_RETIRED.RETIRE_SLOTS */ |
400 | INTEL_EVENT_CONSTRAINT(0xc4, 0xf), /* BR_INST_RETIRED.* */ | 525 | INTEL_EVENT_CONSTRAINT(0xc4, 0xf), /* BR_INST_RETIRED.* */ |
401 | INTEL_EVENT_CONSTRAINT(0xc5, 0xf), /* BR_MISP_RETIRED.* */ | 526 | INTEL_EVENT_CONSTRAINT(0xc5, 0xf), /* BR_MISP_RETIRED.* */ |
402 | INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.* */ | 527 | INTEL_PLD_CONSTRAINT(0x01cd, 0x8), /* MEM_TRANS_RETIRED.LAT_ABOVE_THR */ |
528 | INTEL_PST_CONSTRAINT(0x02cd, 0x8), /* MEM_TRANS_RETIRED.PRECISE_STORES */ | ||
403 | INTEL_EVENT_CONSTRAINT(0xd0, 0xf), /* MEM_UOP_RETIRED.* */ | 529 | INTEL_EVENT_CONSTRAINT(0xd0, 0xf), /* MEM_UOP_RETIRED.* */ |
404 | INTEL_EVENT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */ | 530 | INTEL_EVENT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */ |
405 | INTEL_EVENT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */ | 531 | INTEL_EVENT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */ |
@@ -413,7 +539,8 @@ struct event_constraint intel_ivb_pebs_event_constraints[] = { | |||
413 | INTEL_UEVENT_CONSTRAINT(0x02c2, 0xf), /* UOPS_RETIRED.RETIRE_SLOTS */ | 539 | INTEL_UEVENT_CONSTRAINT(0x02c2, 0xf), /* UOPS_RETIRED.RETIRE_SLOTS */ |
414 | INTEL_EVENT_CONSTRAINT(0xc4, 0xf), /* BR_INST_RETIRED.* */ | 540 | INTEL_EVENT_CONSTRAINT(0xc4, 0xf), /* BR_INST_RETIRED.* */ |
415 | INTEL_EVENT_CONSTRAINT(0xc5, 0xf), /* BR_MISP_RETIRED.* */ | 541 | INTEL_EVENT_CONSTRAINT(0xc5, 0xf), /* BR_MISP_RETIRED.* */ |
416 | INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.* */ | 542 | INTEL_PLD_CONSTRAINT(0x01cd, 0x8), /* MEM_TRANS_RETIRED.LAT_ABOVE_THR */ |
543 | INTEL_PST_CONSTRAINT(0x02cd, 0x8), /* MEM_TRANS_RETIRED.PRECISE_STORES */ | ||
417 | INTEL_EVENT_CONSTRAINT(0xd0, 0xf), /* MEM_UOP_RETIRED.* */ | 544 | INTEL_EVENT_CONSTRAINT(0xd0, 0xf), /* MEM_UOP_RETIRED.* */ |
418 | INTEL_EVENT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */ | 545 | INTEL_EVENT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */ |
419 | INTEL_EVENT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */ | 546 | INTEL_EVENT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */ |
@@ -430,8 +557,10 @@ struct event_constraint *intel_pebs_constraints(struct perf_event *event) | |||
430 | 557 | ||
431 | if (x86_pmu.pebs_constraints) { | 558 | if (x86_pmu.pebs_constraints) { |
432 | for_each_event_constraint(c, x86_pmu.pebs_constraints) { | 559 | for_each_event_constraint(c, x86_pmu.pebs_constraints) { |
433 | if ((event->hw.config & c->cmask) == c->code) | 560 | if ((event->hw.config & c->cmask) == c->code) { |
561 | event->hw.flags |= c->flags; | ||
434 | return c; | 562 | return c; |
563 | } | ||
435 | } | 564 | } |
436 | } | 565 | } |
437 | 566 | ||
@@ -446,6 +575,11 @@ void intel_pmu_pebs_enable(struct perf_event *event) | |||
446 | hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT; | 575 | hwc->config &= ~ARCH_PERFMON_EVENTSEL_INT; |
447 | 576 | ||
448 | cpuc->pebs_enabled |= 1ULL << hwc->idx; | 577 | cpuc->pebs_enabled |= 1ULL << hwc->idx; |
578 | |||
579 | if (event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT) | ||
580 | cpuc->pebs_enabled |= 1ULL << (hwc->idx + 32); | ||
581 | else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST) | ||
582 | cpuc->pebs_enabled |= 1ULL << 63; | ||
449 | } | 583 | } |
450 | 584 | ||
451 | void intel_pmu_pebs_disable(struct perf_event *event) | 585 | void intel_pmu_pebs_disable(struct perf_event *event) |
@@ -558,20 +692,51 @@ static void __intel_pmu_pebs_event(struct perf_event *event, | |||
558 | struct pt_regs *iregs, void *__pebs) | 692 | struct pt_regs *iregs, void *__pebs) |
559 | { | 693 | { |
560 | /* | 694 | /* |
561 | * We cast to pebs_record_core since that is a subset of | 695 | * We cast to pebs_record_nhm to get the load latency data |
562 | * both formats and we don't use the other fields in this | 696 | * if extra_reg MSR_PEBS_LD_LAT_THRESHOLD used |
563 | * routine. | ||
564 | */ | 697 | */ |
565 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 698 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
566 | struct pebs_record_core *pebs = __pebs; | 699 | struct pebs_record_nhm *pebs = __pebs; |
567 | struct perf_sample_data data; | 700 | struct perf_sample_data data; |
568 | struct pt_regs regs; | 701 | struct pt_regs regs; |
702 | u64 sample_type; | ||
703 | int fll, fst; | ||
569 | 704 | ||
570 | if (!intel_pmu_save_and_restart(event)) | 705 | if (!intel_pmu_save_and_restart(event)) |
571 | return; | 706 | return; |
572 | 707 | ||
708 | fll = event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT; | ||
709 | fst = event->hw.flags & PERF_X86_EVENT_PEBS_ST; | ||
710 | |||
573 | perf_sample_data_init(&data, 0, event->hw.last_period); | 711 | perf_sample_data_init(&data, 0, event->hw.last_period); |
574 | 712 | ||
713 | data.period = event->hw.last_period; | ||
714 | sample_type = event->attr.sample_type; | ||
715 | |||
716 | /* | ||
717 | * if PEBS-LL or PreciseStore | ||
718 | */ | ||
719 | if (fll || fst) { | ||
720 | if (sample_type & PERF_SAMPLE_ADDR) | ||
721 | data.addr = pebs->dla; | ||
722 | |||
723 | /* | ||
724 | * Use latency for weight (only avail with PEBS-LL) | ||
725 | */ | ||
726 | if (fll && (sample_type & PERF_SAMPLE_WEIGHT)) | ||
727 | data.weight = pebs->lat; | ||
728 | |||
729 | /* | ||
730 | * data.data_src encodes the data source | ||
731 | */ | ||
732 | if (sample_type & PERF_SAMPLE_DATA_SRC) { | ||
733 | if (fll) | ||
734 | data.data_src.val = load_latency_data(pebs->dse); | ||
735 | else | ||
736 | data.data_src.val = precise_store_data(pebs->dse); | ||
737 | } | ||
738 | } | ||
739 | |||
575 | /* | 740 | /* |
576 | * We use the interrupt regs as a base because the PEBS record | 741 | * We use the interrupt regs as a base because the PEBS record |
577 | * does not contain a full regs set, specifically it seems to | 742 | * does not contain a full regs set, specifically it seems to |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index b43200dbfe7e..d0f9e5aa2151 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c | |||
@@ -17,6 +17,9 @@ static struct event_constraint constraint_fixed = | |||
17 | static struct event_constraint constraint_empty = | 17 | static struct event_constraint constraint_empty = |
18 | EVENT_CONSTRAINT(0, 0, 0); | 18 | EVENT_CONSTRAINT(0, 0, 0); |
19 | 19 | ||
20 | #define __BITS_VALUE(x, i, n) ((typeof(x))(((x) >> ((i) * (n))) & \ | ||
21 | ((1ULL << (n)) - 1))) | ||
22 | |||
20 | DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7"); | 23 | DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7"); |
21 | DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21"); | 24 | DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21"); |
22 | DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); | 25 | DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); |
@@ -31,9 +34,13 @@ DEFINE_UNCORE_FORMAT_ATTR(occ_sel, occ_sel, "config:14-15"); | |||
31 | DEFINE_UNCORE_FORMAT_ATTR(occ_invert, occ_invert, "config:30"); | 34 | DEFINE_UNCORE_FORMAT_ATTR(occ_invert, occ_invert, "config:30"); |
32 | DEFINE_UNCORE_FORMAT_ATTR(occ_edge, occ_edge, "config:14-51"); | 35 | DEFINE_UNCORE_FORMAT_ATTR(occ_edge, occ_edge, "config:14-51"); |
33 | DEFINE_UNCORE_FORMAT_ATTR(filter_tid, filter_tid, "config1:0-4"); | 36 | DEFINE_UNCORE_FORMAT_ATTR(filter_tid, filter_tid, "config1:0-4"); |
37 | DEFINE_UNCORE_FORMAT_ATTR(filter_link, filter_link, "config1:5-8"); | ||
34 | DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17"); | 38 | DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17"); |
39 | DEFINE_UNCORE_FORMAT_ATTR(filter_nid2, filter_nid, "config1:32-47"); | ||
35 | DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22"); | 40 | DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22"); |
41 | DEFINE_UNCORE_FORMAT_ATTR(filter_state2, filter_state, "config1:17-22"); | ||
36 | DEFINE_UNCORE_FORMAT_ATTR(filter_opc, filter_opc, "config1:23-31"); | 42 | DEFINE_UNCORE_FORMAT_ATTR(filter_opc, filter_opc, "config1:23-31"); |
43 | DEFINE_UNCORE_FORMAT_ATTR(filter_opc2, filter_opc, "config1:52-60"); | ||
37 | DEFINE_UNCORE_FORMAT_ATTR(filter_band0, filter_band0, "config1:0-7"); | 44 | DEFINE_UNCORE_FORMAT_ATTR(filter_band0, filter_band0, "config1:0-7"); |
38 | DEFINE_UNCORE_FORMAT_ATTR(filter_band1, filter_band1, "config1:8-15"); | 45 | DEFINE_UNCORE_FORMAT_ATTR(filter_band1, filter_band1, "config1:8-15"); |
39 | DEFINE_UNCORE_FORMAT_ATTR(filter_band2, filter_band2, "config1:16-23"); | 46 | DEFINE_UNCORE_FORMAT_ATTR(filter_band2, filter_band2, "config1:16-23"); |
@@ -110,6 +117,21 @@ static void uncore_put_constraint(struct intel_uncore_box *box, struct perf_even | |||
110 | reg1->alloc = 0; | 117 | reg1->alloc = 0; |
111 | } | 118 | } |
112 | 119 | ||
120 | static u64 uncore_shared_reg_config(struct intel_uncore_box *box, int idx) | ||
121 | { | ||
122 | struct intel_uncore_extra_reg *er; | ||
123 | unsigned long flags; | ||
124 | u64 config; | ||
125 | |||
126 | er = &box->shared_regs[idx]; | ||
127 | |||
128 | raw_spin_lock_irqsave(&er->lock, flags); | ||
129 | config = er->config; | ||
130 | raw_spin_unlock_irqrestore(&er->lock, flags); | ||
131 | |||
132 | return config; | ||
133 | } | ||
134 | |||
113 | /* Sandy Bridge-EP uncore support */ | 135 | /* Sandy Bridge-EP uncore support */ |
114 | static struct intel_uncore_type snbep_uncore_cbox; | 136 | static struct intel_uncore_type snbep_uncore_cbox; |
115 | static struct intel_uncore_type snbep_uncore_pcu; | 137 | static struct intel_uncore_type snbep_uncore_pcu; |
@@ -205,7 +227,7 @@ static void snbep_uncore_msr_enable_event(struct intel_uncore_box *box, struct p | |||
205 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | 227 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; |
206 | 228 | ||
207 | if (reg1->idx != EXTRA_REG_NONE) | 229 | if (reg1->idx != EXTRA_REG_NONE) |
208 | wrmsrl(reg1->reg, reg1->config); | 230 | wrmsrl(reg1->reg, uncore_shared_reg_config(box, 0)); |
209 | 231 | ||
210 | wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN); | 232 | wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN); |
211 | } | 233 | } |
@@ -226,29 +248,6 @@ static void snbep_uncore_msr_init_box(struct intel_uncore_box *box) | |||
226 | wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT); | 248 | wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT); |
227 | } | 249 | } |
228 | 250 | ||
229 | static int snbep_uncore_hw_config(struct intel_uncore_box *box, struct perf_event *event) | ||
230 | { | ||
231 | struct hw_perf_event *hwc = &event->hw; | ||
232 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
233 | |||
234 | if (box->pmu->type == &snbep_uncore_cbox) { | ||
235 | reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER + | ||
236 | SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx; | ||
237 | reg1->config = event->attr.config1 & | ||
238 | SNBEP_CB0_MSR_PMON_BOX_FILTER_MASK; | ||
239 | } else { | ||
240 | if (box->pmu->type == &snbep_uncore_pcu) { | ||
241 | reg1->reg = SNBEP_PCU_MSR_PMON_BOX_FILTER; | ||
242 | reg1->config = event->attr.config1 & SNBEP_PCU_MSR_PMON_BOX_FILTER_MASK; | ||
243 | } else { | ||
244 | return 0; | ||
245 | } | ||
246 | } | ||
247 | reg1->idx = 0; | ||
248 | |||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | static struct attribute *snbep_uncore_formats_attr[] = { | 251 | static struct attribute *snbep_uncore_formats_attr[] = { |
253 | &format_attr_event.attr, | 252 | &format_attr_event.attr, |
254 | &format_attr_umask.attr, | 253 | &format_attr_umask.attr, |
@@ -345,16 +344,16 @@ static struct attribute_group snbep_uncore_qpi_format_group = { | |||
345 | .attrs = snbep_uncore_qpi_formats_attr, | 344 | .attrs = snbep_uncore_qpi_formats_attr, |
346 | }; | 345 | }; |
347 | 346 | ||
347 | #define SNBEP_UNCORE_MSR_OPS_COMMON_INIT() \ | ||
348 | .init_box = snbep_uncore_msr_init_box, \ | ||
349 | .disable_box = snbep_uncore_msr_disable_box, \ | ||
350 | .enable_box = snbep_uncore_msr_enable_box, \ | ||
351 | .disable_event = snbep_uncore_msr_disable_event, \ | ||
352 | .enable_event = snbep_uncore_msr_enable_event, \ | ||
353 | .read_counter = uncore_msr_read_counter | ||
354 | |||
348 | static struct intel_uncore_ops snbep_uncore_msr_ops = { | 355 | static struct intel_uncore_ops snbep_uncore_msr_ops = { |
349 | .init_box = snbep_uncore_msr_init_box, | 356 | SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), |
350 | .disable_box = snbep_uncore_msr_disable_box, | ||
351 | .enable_box = snbep_uncore_msr_enable_box, | ||
352 | .disable_event = snbep_uncore_msr_disable_event, | ||
353 | .enable_event = snbep_uncore_msr_enable_event, | ||
354 | .read_counter = uncore_msr_read_counter, | ||
355 | .get_constraint = uncore_get_constraint, | ||
356 | .put_constraint = uncore_put_constraint, | ||
357 | .hw_config = snbep_uncore_hw_config, | ||
358 | }; | 357 | }; |
359 | 358 | ||
360 | static struct intel_uncore_ops snbep_uncore_pci_ops = { | 359 | static struct intel_uncore_ops snbep_uncore_pci_ops = { |
@@ -372,6 +371,7 @@ static struct event_constraint snbep_uncore_cbox_constraints[] = { | |||
372 | UNCORE_EVENT_CONSTRAINT(0x04, 0x3), | 371 | UNCORE_EVENT_CONSTRAINT(0x04, 0x3), |
373 | UNCORE_EVENT_CONSTRAINT(0x05, 0x3), | 372 | UNCORE_EVENT_CONSTRAINT(0x05, 0x3), |
374 | UNCORE_EVENT_CONSTRAINT(0x07, 0x3), | 373 | UNCORE_EVENT_CONSTRAINT(0x07, 0x3), |
374 | UNCORE_EVENT_CONSTRAINT(0x09, 0x3), | ||
375 | UNCORE_EVENT_CONSTRAINT(0x11, 0x1), | 375 | UNCORE_EVENT_CONSTRAINT(0x11, 0x1), |
376 | UNCORE_EVENT_CONSTRAINT(0x12, 0x3), | 376 | UNCORE_EVENT_CONSTRAINT(0x12, 0x3), |
377 | UNCORE_EVENT_CONSTRAINT(0x13, 0x3), | 377 | UNCORE_EVENT_CONSTRAINT(0x13, 0x3), |
@@ -421,6 +421,14 @@ static struct event_constraint snbep_uncore_r3qpi_constraints[] = { | |||
421 | UNCORE_EVENT_CONSTRAINT(0x24, 0x3), | 421 | UNCORE_EVENT_CONSTRAINT(0x24, 0x3), |
422 | UNCORE_EVENT_CONSTRAINT(0x25, 0x3), | 422 | UNCORE_EVENT_CONSTRAINT(0x25, 0x3), |
423 | UNCORE_EVENT_CONSTRAINT(0x26, 0x3), | 423 | UNCORE_EVENT_CONSTRAINT(0x26, 0x3), |
424 | UNCORE_EVENT_CONSTRAINT(0x28, 0x3), | ||
425 | UNCORE_EVENT_CONSTRAINT(0x29, 0x3), | ||
426 | UNCORE_EVENT_CONSTRAINT(0x2a, 0x3), | ||
427 | UNCORE_EVENT_CONSTRAINT(0x2b, 0x3), | ||
428 | UNCORE_EVENT_CONSTRAINT(0x2c, 0x3), | ||
429 | UNCORE_EVENT_CONSTRAINT(0x2d, 0x3), | ||
430 | UNCORE_EVENT_CONSTRAINT(0x2e, 0x3), | ||
431 | UNCORE_EVENT_CONSTRAINT(0x2f, 0x3), | ||
424 | UNCORE_EVENT_CONSTRAINT(0x30, 0x3), | 432 | UNCORE_EVENT_CONSTRAINT(0x30, 0x3), |
425 | UNCORE_EVENT_CONSTRAINT(0x31, 0x3), | 433 | UNCORE_EVENT_CONSTRAINT(0x31, 0x3), |
426 | UNCORE_EVENT_CONSTRAINT(0x32, 0x3), | 434 | UNCORE_EVENT_CONSTRAINT(0x32, 0x3), |
@@ -428,6 +436,8 @@ static struct event_constraint snbep_uncore_r3qpi_constraints[] = { | |||
428 | UNCORE_EVENT_CONSTRAINT(0x34, 0x3), | 436 | UNCORE_EVENT_CONSTRAINT(0x34, 0x3), |
429 | UNCORE_EVENT_CONSTRAINT(0x36, 0x3), | 437 | UNCORE_EVENT_CONSTRAINT(0x36, 0x3), |
430 | UNCORE_EVENT_CONSTRAINT(0x37, 0x3), | 438 | UNCORE_EVENT_CONSTRAINT(0x37, 0x3), |
439 | UNCORE_EVENT_CONSTRAINT(0x38, 0x3), | ||
440 | UNCORE_EVENT_CONSTRAINT(0x39, 0x3), | ||
431 | EVENT_CONSTRAINT_END | 441 | EVENT_CONSTRAINT_END |
432 | }; | 442 | }; |
433 | 443 | ||
@@ -446,6 +456,145 @@ static struct intel_uncore_type snbep_uncore_ubox = { | |||
446 | .format_group = &snbep_uncore_ubox_format_group, | 456 | .format_group = &snbep_uncore_ubox_format_group, |
447 | }; | 457 | }; |
448 | 458 | ||
459 | static struct extra_reg snbep_uncore_cbox_extra_regs[] = { | ||
460 | SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN, | ||
461 | SNBEP_CBO_PMON_CTL_TID_EN, 0x1), | ||
462 | SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4), | ||
463 | SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4), | ||
464 | SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4), | ||
465 | SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x6), | ||
466 | SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x8), | ||
467 | SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x8), | ||
468 | SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0xc), | ||
469 | SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0xc), | ||
470 | SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x2), | ||
471 | SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x2), | ||
472 | SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x2), | ||
473 | SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x2), | ||
474 | SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x8), | ||
475 | SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x8), | ||
476 | SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0xc), | ||
477 | SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0xc), | ||
478 | SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x2), | ||
479 | SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x2), | ||
480 | SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x2), | ||
481 | SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x2), | ||
482 | EVENT_EXTRA_END | ||
483 | }; | ||
484 | |||
485 | static void snbep_cbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event) | ||
486 | { | ||
487 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
488 | struct intel_uncore_extra_reg *er = &box->shared_regs[0]; | ||
489 | int i; | ||
490 | |||
491 | if (uncore_box_is_fake(box)) | ||
492 | return; | ||
493 | |||
494 | for (i = 0; i < 5; i++) { | ||
495 | if (reg1->alloc & (0x1 << i)) | ||
496 | atomic_sub(1 << (i * 6), &er->ref); | ||
497 | } | ||
498 | reg1->alloc = 0; | ||
499 | } | ||
500 | |||
501 | static struct event_constraint * | ||
502 | __snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event, | ||
503 | u64 (*cbox_filter_mask)(int fields)) | ||
504 | { | ||
505 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
506 | struct intel_uncore_extra_reg *er = &box->shared_regs[0]; | ||
507 | int i, alloc = 0; | ||
508 | unsigned long flags; | ||
509 | u64 mask; | ||
510 | |||
511 | if (reg1->idx == EXTRA_REG_NONE) | ||
512 | return NULL; | ||
513 | |||
514 | raw_spin_lock_irqsave(&er->lock, flags); | ||
515 | for (i = 0; i < 5; i++) { | ||
516 | if (!(reg1->idx & (0x1 << i))) | ||
517 | continue; | ||
518 | if (!uncore_box_is_fake(box) && (reg1->alloc & (0x1 << i))) | ||
519 | continue; | ||
520 | |||
521 | mask = cbox_filter_mask(0x1 << i); | ||
522 | if (!__BITS_VALUE(atomic_read(&er->ref), i, 6) || | ||
523 | !((reg1->config ^ er->config) & mask)) { | ||
524 | atomic_add(1 << (i * 6), &er->ref); | ||
525 | er->config &= ~mask; | ||
526 | er->config |= reg1->config & mask; | ||
527 | alloc |= (0x1 << i); | ||
528 | } else { | ||
529 | break; | ||
530 | } | ||
531 | } | ||
532 | raw_spin_unlock_irqrestore(&er->lock, flags); | ||
533 | if (i < 5) | ||
534 | goto fail; | ||
535 | |||
536 | if (!uncore_box_is_fake(box)) | ||
537 | reg1->alloc |= alloc; | ||
538 | |||
539 | return 0; | ||
540 | fail: | ||
541 | for (; i >= 0; i--) { | ||
542 | if (alloc & (0x1 << i)) | ||
543 | atomic_sub(1 << (i * 6), &er->ref); | ||
544 | } | ||
545 | return &constraint_empty; | ||
546 | } | ||
547 | |||
548 | static u64 snbep_cbox_filter_mask(int fields) | ||
549 | { | ||
550 | u64 mask = 0; | ||
551 | |||
552 | if (fields & 0x1) | ||
553 | mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_TID; | ||
554 | if (fields & 0x2) | ||
555 | mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_NID; | ||
556 | if (fields & 0x4) | ||
557 | mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_STATE; | ||
558 | if (fields & 0x8) | ||
559 | mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_OPC; | ||
560 | |||
561 | return mask; | ||
562 | } | ||
563 | |||
564 | static struct event_constraint * | ||
565 | snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event) | ||
566 | { | ||
567 | return __snbep_cbox_get_constraint(box, event, snbep_cbox_filter_mask); | ||
568 | } | ||
569 | |||
570 | static int snbep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) | ||
571 | { | ||
572 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
573 | struct extra_reg *er; | ||
574 | int idx = 0; | ||
575 | |||
576 | for (er = snbep_uncore_cbox_extra_regs; er->msr; er++) { | ||
577 | if (er->event != (event->hw.config & er->config_mask)) | ||
578 | continue; | ||
579 | idx |= er->idx; | ||
580 | } | ||
581 | |||
582 | if (idx) { | ||
583 | reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER + | ||
584 | SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx; | ||
585 | reg1->config = event->attr.config1 & snbep_cbox_filter_mask(idx); | ||
586 | reg1->idx = idx; | ||
587 | } | ||
588 | return 0; | ||
589 | } | ||
590 | |||
591 | static struct intel_uncore_ops snbep_uncore_cbox_ops = { | ||
592 | SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), | ||
593 | .hw_config = snbep_cbox_hw_config, | ||
594 | .get_constraint = snbep_cbox_get_constraint, | ||
595 | .put_constraint = snbep_cbox_put_constraint, | ||
596 | }; | ||
597 | |||
449 | static struct intel_uncore_type snbep_uncore_cbox = { | 598 | static struct intel_uncore_type snbep_uncore_cbox = { |
450 | .name = "cbox", | 599 | .name = "cbox", |
451 | .num_counters = 4, | 600 | .num_counters = 4, |
@@ -458,10 +607,104 @@ static struct intel_uncore_type snbep_uncore_cbox = { | |||
458 | .msr_offset = SNBEP_CBO_MSR_OFFSET, | 607 | .msr_offset = SNBEP_CBO_MSR_OFFSET, |
459 | .num_shared_regs = 1, | 608 | .num_shared_regs = 1, |
460 | .constraints = snbep_uncore_cbox_constraints, | 609 | .constraints = snbep_uncore_cbox_constraints, |
461 | .ops = &snbep_uncore_msr_ops, | 610 | .ops = &snbep_uncore_cbox_ops, |
462 | .format_group = &snbep_uncore_cbox_format_group, | 611 | .format_group = &snbep_uncore_cbox_format_group, |
463 | }; | 612 | }; |
464 | 613 | ||
614 | static u64 snbep_pcu_alter_er(struct perf_event *event, int new_idx, bool modify) | ||
615 | { | ||
616 | struct hw_perf_event *hwc = &event->hw; | ||
617 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
618 | u64 config = reg1->config; | ||
619 | |||
620 | if (new_idx > reg1->idx) | ||
621 | config <<= 8 * (new_idx - reg1->idx); | ||
622 | else | ||
623 | config >>= 8 * (reg1->idx - new_idx); | ||
624 | |||
625 | if (modify) { | ||
626 | hwc->config += new_idx - reg1->idx; | ||
627 | reg1->config = config; | ||
628 | reg1->idx = new_idx; | ||
629 | } | ||
630 | return config; | ||
631 | } | ||
632 | |||
633 | static struct event_constraint * | ||
634 | snbep_pcu_get_constraint(struct intel_uncore_box *box, struct perf_event *event) | ||
635 | { | ||
636 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
637 | struct intel_uncore_extra_reg *er = &box->shared_regs[0]; | ||
638 | unsigned long flags; | ||
639 | int idx = reg1->idx; | ||
640 | u64 mask, config1 = reg1->config; | ||
641 | bool ok = false; | ||
642 | |||
643 | if (reg1->idx == EXTRA_REG_NONE || | ||
644 | (!uncore_box_is_fake(box) && reg1->alloc)) | ||
645 | return NULL; | ||
646 | again: | ||
647 | mask = 0xff << (idx * 8); | ||
648 | raw_spin_lock_irqsave(&er->lock, flags); | ||
649 | if (!__BITS_VALUE(atomic_read(&er->ref), idx, 8) || | ||
650 | !((config1 ^ er->config) & mask)) { | ||
651 | atomic_add(1 << (idx * 8), &er->ref); | ||
652 | er->config &= ~mask; | ||
653 | er->config |= config1 & mask; | ||
654 | ok = true; | ||
655 | } | ||
656 | raw_spin_unlock_irqrestore(&er->lock, flags); | ||
657 | |||
658 | if (!ok) { | ||
659 | idx = (idx + 1) % 4; | ||
660 | if (idx != reg1->idx) { | ||
661 | config1 = snbep_pcu_alter_er(event, idx, false); | ||
662 | goto again; | ||
663 | } | ||
664 | return &constraint_empty; | ||
665 | } | ||
666 | |||
667 | if (!uncore_box_is_fake(box)) { | ||
668 | if (idx != reg1->idx) | ||
669 | snbep_pcu_alter_er(event, idx, true); | ||
670 | reg1->alloc = 1; | ||
671 | } | ||
672 | return NULL; | ||
673 | } | ||
674 | |||
675 | static void snbep_pcu_put_constraint(struct intel_uncore_box *box, struct perf_event *event) | ||
676 | { | ||
677 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
678 | struct intel_uncore_extra_reg *er = &box->shared_regs[0]; | ||
679 | |||
680 | if (uncore_box_is_fake(box) || !reg1->alloc) | ||
681 | return; | ||
682 | |||
683 | atomic_sub(1 << (reg1->idx * 8), &er->ref); | ||
684 | reg1->alloc = 0; | ||
685 | } | ||
686 | |||
687 | static int snbep_pcu_hw_config(struct intel_uncore_box *box, struct perf_event *event) | ||
688 | { | ||
689 | struct hw_perf_event *hwc = &event->hw; | ||
690 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
691 | int ev_sel = hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK; | ||
692 | |||
693 | if (ev_sel >= 0xb && ev_sel <= 0xe) { | ||
694 | reg1->reg = SNBEP_PCU_MSR_PMON_BOX_FILTER; | ||
695 | reg1->idx = ev_sel - 0xb; | ||
696 | reg1->config = event->attr.config1 & (0xff << reg1->idx); | ||
697 | } | ||
698 | return 0; | ||
699 | } | ||
700 | |||
701 | static struct intel_uncore_ops snbep_uncore_pcu_ops = { | ||
702 | SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), | ||
703 | .hw_config = snbep_pcu_hw_config, | ||
704 | .get_constraint = snbep_pcu_get_constraint, | ||
705 | .put_constraint = snbep_pcu_put_constraint, | ||
706 | }; | ||
707 | |||
465 | static struct intel_uncore_type snbep_uncore_pcu = { | 708 | static struct intel_uncore_type snbep_uncore_pcu = { |
466 | .name = "pcu", | 709 | .name = "pcu", |
467 | .num_counters = 4, | 710 | .num_counters = 4, |
@@ -472,7 +715,7 @@ static struct intel_uncore_type snbep_uncore_pcu = { | |||
472 | .event_mask = SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK, | 715 | .event_mask = SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK, |
473 | .box_ctl = SNBEP_PCU_MSR_PMON_BOX_CTL, | 716 | .box_ctl = SNBEP_PCU_MSR_PMON_BOX_CTL, |
474 | .num_shared_regs = 1, | 717 | .num_shared_regs = 1, |
475 | .ops = &snbep_uncore_msr_ops, | 718 | .ops = &snbep_uncore_pcu_ops, |
476 | .format_group = &snbep_uncore_pcu_format_group, | 719 | .format_group = &snbep_uncore_pcu_format_group, |
477 | }; | 720 | }; |
478 | 721 | ||
@@ -544,55 +787,63 @@ static struct intel_uncore_type snbep_uncore_r3qpi = { | |||
544 | SNBEP_UNCORE_PCI_COMMON_INIT(), | 787 | SNBEP_UNCORE_PCI_COMMON_INIT(), |
545 | }; | 788 | }; |
546 | 789 | ||
790 | enum { | ||
791 | SNBEP_PCI_UNCORE_HA, | ||
792 | SNBEP_PCI_UNCORE_IMC, | ||
793 | SNBEP_PCI_UNCORE_QPI, | ||
794 | SNBEP_PCI_UNCORE_R2PCIE, | ||
795 | SNBEP_PCI_UNCORE_R3QPI, | ||
796 | }; | ||
797 | |||
547 | static struct intel_uncore_type *snbep_pci_uncores[] = { | 798 | static struct intel_uncore_type *snbep_pci_uncores[] = { |
548 | &snbep_uncore_ha, | 799 | [SNBEP_PCI_UNCORE_HA] = &snbep_uncore_ha, |
549 | &snbep_uncore_imc, | 800 | [SNBEP_PCI_UNCORE_IMC] = &snbep_uncore_imc, |
550 | &snbep_uncore_qpi, | 801 | [SNBEP_PCI_UNCORE_QPI] = &snbep_uncore_qpi, |
551 | &snbep_uncore_r2pcie, | 802 | [SNBEP_PCI_UNCORE_R2PCIE] = &snbep_uncore_r2pcie, |
552 | &snbep_uncore_r3qpi, | 803 | [SNBEP_PCI_UNCORE_R3QPI] = &snbep_uncore_r3qpi, |
553 | NULL, | 804 | NULL, |
554 | }; | 805 | }; |
555 | 806 | ||
556 | static DEFINE_PCI_DEVICE_TABLE(snbep_uncore_pci_ids) = { | 807 | static DEFINE_PCI_DEVICE_TABLE(snbep_uncore_pci_ids) = { |
557 | { /* Home Agent */ | 808 | { /* Home Agent */ |
558 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA), | 809 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA), |
559 | .driver_data = (unsigned long)&snbep_uncore_ha, | 810 | .driver_data = SNBEP_PCI_UNCORE_HA, |
560 | }, | 811 | }, |
561 | { /* MC Channel 0 */ | 812 | { /* MC Channel 0 */ |
562 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0), | 813 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0), |
563 | .driver_data = (unsigned long)&snbep_uncore_imc, | 814 | .driver_data = SNBEP_PCI_UNCORE_IMC, |
564 | }, | 815 | }, |
565 | { /* MC Channel 1 */ | 816 | { /* MC Channel 1 */ |
566 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1), | 817 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1), |
567 | .driver_data = (unsigned long)&snbep_uncore_imc, | 818 | .driver_data = SNBEP_PCI_UNCORE_IMC, |
568 | }, | 819 | }, |
569 | { /* MC Channel 2 */ | 820 | { /* MC Channel 2 */ |
570 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2), | 821 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2), |
571 | .driver_data = (unsigned long)&snbep_uncore_imc, | 822 | .driver_data = SNBEP_PCI_UNCORE_IMC, |
572 | }, | 823 | }, |
573 | { /* MC Channel 3 */ | 824 | { /* MC Channel 3 */ |
574 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3), | 825 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3), |
575 | .driver_data = (unsigned long)&snbep_uncore_imc, | 826 | .driver_data = SNBEP_PCI_UNCORE_IMC, |
576 | }, | 827 | }, |
577 | { /* QPI Port 0 */ | 828 | { /* QPI Port 0 */ |
578 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0), | 829 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0), |
579 | .driver_data = (unsigned long)&snbep_uncore_qpi, | 830 | .driver_data = SNBEP_PCI_UNCORE_QPI, |
580 | }, | 831 | }, |
581 | { /* QPI Port 1 */ | 832 | { /* QPI Port 1 */ |
582 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1), | 833 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1), |
583 | .driver_data = (unsigned long)&snbep_uncore_qpi, | 834 | .driver_data = SNBEP_PCI_UNCORE_QPI, |
584 | }, | 835 | }, |
585 | { /* P2PCIe */ | 836 | { /* R2PCIe */ |
586 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE), | 837 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE), |
587 | .driver_data = (unsigned long)&snbep_uncore_r2pcie, | 838 | .driver_data = SNBEP_PCI_UNCORE_R2PCIE, |
588 | }, | 839 | }, |
589 | { /* R3QPI Link 0 */ | 840 | { /* R3QPI Link 0 */ |
590 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0), | 841 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0), |
591 | .driver_data = (unsigned long)&snbep_uncore_r3qpi, | 842 | .driver_data = SNBEP_PCI_UNCORE_R3QPI, |
592 | }, | 843 | }, |
593 | { /* R3QPI Link 1 */ | 844 | { /* R3QPI Link 1 */ |
594 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1), | 845 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1), |
595 | .driver_data = (unsigned long)&snbep_uncore_r3qpi, | 846 | .driver_data = SNBEP_PCI_UNCORE_R3QPI, |
596 | }, | 847 | }, |
597 | { /* end: all zeroes */ } | 848 | { /* end: all zeroes */ } |
598 | }; | 849 | }; |
@@ -605,7 +856,7 @@ static struct pci_driver snbep_uncore_pci_driver = { | |||
605 | /* | 856 | /* |
606 | * build pci bus to socket mapping | 857 | * build pci bus to socket mapping |
607 | */ | 858 | */ |
608 | static int snbep_pci2phy_map_init(void) | 859 | static int snbep_pci2phy_map_init(int devid) |
609 | { | 860 | { |
610 | struct pci_dev *ubox_dev = NULL; | 861 | struct pci_dev *ubox_dev = NULL; |
611 | int i, bus, nodeid; | 862 | int i, bus, nodeid; |
@@ -614,9 +865,7 @@ static int snbep_pci2phy_map_init(void) | |||
614 | 865 | ||
615 | while (1) { | 866 | while (1) { |
616 | /* find the UBOX device */ | 867 | /* find the UBOX device */ |
617 | ubox_dev = pci_get_device(PCI_VENDOR_ID_INTEL, | 868 | ubox_dev = pci_get_device(PCI_VENDOR_ID_INTEL, devid, ubox_dev); |
618 | PCI_DEVICE_ID_INTEL_JAKETOWN_UBOX, | ||
619 | ubox_dev); | ||
620 | if (!ubox_dev) | 869 | if (!ubox_dev) |
621 | break; | 870 | break; |
622 | bus = ubox_dev->bus->number; | 871 | bus = ubox_dev->bus->number; |
@@ -639,7 +888,7 @@ static int snbep_pci2phy_map_init(void) | |||
639 | break; | 888 | break; |
640 | } | 889 | } |
641 | } | 890 | } |
642 | }; | 891 | } |
643 | 892 | ||
644 | if (ubox_dev) | 893 | if (ubox_dev) |
645 | pci_dev_put(ubox_dev); | 894 | pci_dev_put(ubox_dev); |
@@ -648,6 +897,440 @@ static int snbep_pci2phy_map_init(void) | |||
648 | } | 897 | } |
649 | /* end of Sandy Bridge-EP uncore support */ | 898 | /* end of Sandy Bridge-EP uncore support */ |
650 | 899 | ||
900 | /* IvyTown uncore support */ | ||
901 | static void ivt_uncore_msr_init_box(struct intel_uncore_box *box) | ||
902 | { | ||
903 | unsigned msr = uncore_msr_box_ctl(box); | ||
904 | if (msr) | ||
905 | wrmsrl(msr, IVT_PMON_BOX_CTL_INT); | ||
906 | } | ||
907 | |||
908 | static void ivt_uncore_pci_init_box(struct intel_uncore_box *box) | ||
909 | { | ||
910 | struct pci_dev *pdev = box->pci_dev; | ||
911 | |||
912 | pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, IVT_PMON_BOX_CTL_INT); | ||
913 | } | ||
914 | |||
915 | #define IVT_UNCORE_MSR_OPS_COMMON_INIT() \ | ||
916 | .init_box = ivt_uncore_msr_init_box, \ | ||
917 | .disable_box = snbep_uncore_msr_disable_box, \ | ||
918 | .enable_box = snbep_uncore_msr_enable_box, \ | ||
919 | .disable_event = snbep_uncore_msr_disable_event, \ | ||
920 | .enable_event = snbep_uncore_msr_enable_event, \ | ||
921 | .read_counter = uncore_msr_read_counter | ||
922 | |||
923 | static struct intel_uncore_ops ivt_uncore_msr_ops = { | ||
924 | IVT_UNCORE_MSR_OPS_COMMON_INIT(), | ||
925 | }; | ||
926 | |||
927 | static struct intel_uncore_ops ivt_uncore_pci_ops = { | ||
928 | .init_box = ivt_uncore_pci_init_box, | ||
929 | .disable_box = snbep_uncore_pci_disable_box, | ||
930 | .enable_box = snbep_uncore_pci_enable_box, | ||
931 | .disable_event = snbep_uncore_pci_disable_event, | ||
932 | .enable_event = snbep_uncore_pci_enable_event, | ||
933 | .read_counter = snbep_uncore_pci_read_counter, | ||
934 | }; | ||
935 | |||
936 | #define IVT_UNCORE_PCI_COMMON_INIT() \ | ||
937 | .perf_ctr = SNBEP_PCI_PMON_CTR0, \ | ||
938 | .event_ctl = SNBEP_PCI_PMON_CTL0, \ | ||
939 | .event_mask = IVT_PMON_RAW_EVENT_MASK, \ | ||
940 | .box_ctl = SNBEP_PCI_PMON_BOX_CTL, \ | ||
941 | .ops = &ivt_uncore_pci_ops, \ | ||
942 | .format_group = &ivt_uncore_format_group | ||
943 | |||
944 | static struct attribute *ivt_uncore_formats_attr[] = { | ||
945 | &format_attr_event.attr, | ||
946 | &format_attr_umask.attr, | ||
947 | &format_attr_edge.attr, | ||
948 | &format_attr_inv.attr, | ||
949 | &format_attr_thresh8.attr, | ||
950 | NULL, | ||
951 | }; | ||
952 | |||
953 | static struct attribute *ivt_uncore_ubox_formats_attr[] = { | ||
954 | &format_attr_event.attr, | ||
955 | &format_attr_umask.attr, | ||
956 | &format_attr_edge.attr, | ||
957 | &format_attr_inv.attr, | ||
958 | &format_attr_thresh5.attr, | ||
959 | NULL, | ||
960 | }; | ||
961 | |||
962 | static struct attribute *ivt_uncore_cbox_formats_attr[] = { | ||
963 | &format_attr_event.attr, | ||
964 | &format_attr_umask.attr, | ||
965 | &format_attr_edge.attr, | ||
966 | &format_attr_tid_en.attr, | ||
967 | &format_attr_thresh8.attr, | ||
968 | &format_attr_filter_tid.attr, | ||
969 | &format_attr_filter_link.attr, | ||
970 | &format_attr_filter_state2.attr, | ||
971 | &format_attr_filter_nid2.attr, | ||
972 | &format_attr_filter_opc2.attr, | ||
973 | NULL, | ||
974 | }; | ||
975 | |||
976 | static struct attribute *ivt_uncore_pcu_formats_attr[] = { | ||
977 | &format_attr_event_ext.attr, | ||
978 | &format_attr_occ_sel.attr, | ||
979 | &format_attr_edge.attr, | ||
980 | &format_attr_thresh5.attr, | ||
981 | &format_attr_occ_invert.attr, | ||
982 | &format_attr_occ_edge.attr, | ||
983 | &format_attr_filter_band0.attr, | ||
984 | &format_attr_filter_band1.attr, | ||
985 | &format_attr_filter_band2.attr, | ||
986 | &format_attr_filter_band3.attr, | ||
987 | NULL, | ||
988 | }; | ||
989 | |||
990 | static struct attribute *ivt_uncore_qpi_formats_attr[] = { | ||
991 | &format_attr_event_ext.attr, | ||
992 | &format_attr_umask.attr, | ||
993 | &format_attr_edge.attr, | ||
994 | &format_attr_thresh8.attr, | ||
995 | NULL, | ||
996 | }; | ||
997 | |||
998 | static struct attribute_group ivt_uncore_format_group = { | ||
999 | .name = "format", | ||
1000 | .attrs = ivt_uncore_formats_attr, | ||
1001 | }; | ||
1002 | |||
1003 | static struct attribute_group ivt_uncore_ubox_format_group = { | ||
1004 | .name = "format", | ||
1005 | .attrs = ivt_uncore_ubox_formats_attr, | ||
1006 | }; | ||
1007 | |||
1008 | static struct attribute_group ivt_uncore_cbox_format_group = { | ||
1009 | .name = "format", | ||
1010 | .attrs = ivt_uncore_cbox_formats_attr, | ||
1011 | }; | ||
1012 | |||
1013 | static struct attribute_group ivt_uncore_pcu_format_group = { | ||
1014 | .name = "format", | ||
1015 | .attrs = ivt_uncore_pcu_formats_attr, | ||
1016 | }; | ||
1017 | |||
1018 | static struct attribute_group ivt_uncore_qpi_format_group = { | ||
1019 | .name = "format", | ||
1020 | .attrs = ivt_uncore_qpi_formats_attr, | ||
1021 | }; | ||
1022 | |||
1023 | static struct intel_uncore_type ivt_uncore_ubox = { | ||
1024 | .name = "ubox", | ||
1025 | .num_counters = 2, | ||
1026 | .num_boxes = 1, | ||
1027 | .perf_ctr_bits = 44, | ||
1028 | .fixed_ctr_bits = 48, | ||
1029 | .perf_ctr = SNBEP_U_MSR_PMON_CTR0, | ||
1030 | .event_ctl = SNBEP_U_MSR_PMON_CTL0, | ||
1031 | .event_mask = IVT_U_MSR_PMON_RAW_EVENT_MASK, | ||
1032 | .fixed_ctr = SNBEP_U_MSR_PMON_UCLK_FIXED_CTR, | ||
1033 | .fixed_ctl = SNBEP_U_MSR_PMON_UCLK_FIXED_CTL, | ||
1034 | .ops = &ivt_uncore_msr_ops, | ||
1035 | .format_group = &ivt_uncore_ubox_format_group, | ||
1036 | }; | ||
1037 | |||
1038 | static struct extra_reg ivt_uncore_cbox_extra_regs[] = { | ||
1039 | SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN, | ||
1040 | SNBEP_CBO_PMON_CTL_TID_EN, 0x1), | ||
1041 | SNBEP_CBO_EVENT_EXTRA_REG(0x1031, 0x10ff, 0x2), | ||
1042 | SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4), | ||
1043 | SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4), | ||
1044 | SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4), | ||
1045 | SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0xc), | ||
1046 | SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x10), | ||
1047 | SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10), | ||
1048 | SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10), | ||
1049 | SNBEP_CBO_EVENT_EXTRA_REG(0x2335, 0xffff, 0x10), | ||
1050 | SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0x18), | ||
1051 | SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0x18), | ||
1052 | SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x8), | ||
1053 | SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x8), | ||
1054 | SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x8), | ||
1055 | SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x8), | ||
1056 | SNBEP_CBO_EVENT_EXTRA_REG(0x8135, 0xffff, 0x10), | ||
1057 | SNBEP_CBO_EVENT_EXTRA_REG(0x8335, 0xffff, 0x10), | ||
1058 | SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x10), | ||
1059 | SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x10), | ||
1060 | SNBEP_CBO_EVENT_EXTRA_REG(0x2336, 0xffff, 0x10), | ||
1061 | SNBEP_CBO_EVENT_EXTRA_REG(0x2336, 0xffff, 0x10), | ||
1062 | SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0x18), | ||
1063 | SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0x18), | ||
1064 | SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x8), | ||
1065 | SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x8), | ||
1066 | SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x8), | ||
1067 | SNBEP_CBO_EVENT_EXTRA_REG(0x5036, 0xffff, 0x8), | ||
1068 | SNBEP_CBO_EVENT_EXTRA_REG(0x8136, 0xffff, 0x10), | ||
1069 | SNBEP_CBO_EVENT_EXTRA_REG(0x8336, 0xffff, 0x10), | ||
1070 | SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x8), | ||
1071 | EVENT_EXTRA_END | ||
1072 | }; | ||
1073 | |||
1074 | static u64 ivt_cbox_filter_mask(int fields) | ||
1075 | { | ||
1076 | u64 mask = 0; | ||
1077 | |||
1078 | if (fields & 0x1) | ||
1079 | mask |= IVT_CB0_MSR_PMON_BOX_FILTER_TID; | ||
1080 | if (fields & 0x2) | ||
1081 | mask |= IVT_CB0_MSR_PMON_BOX_FILTER_LINK; | ||
1082 | if (fields & 0x4) | ||
1083 | mask |= IVT_CB0_MSR_PMON_BOX_FILTER_STATE; | ||
1084 | if (fields & 0x8) | ||
1085 | mask |= IVT_CB0_MSR_PMON_BOX_FILTER_NID; | ||
1086 | if (fields & 0x10) | ||
1087 | mask |= IVT_CB0_MSR_PMON_BOX_FILTER_OPC; | ||
1088 | |||
1089 | return mask; | ||
1090 | } | ||
1091 | |||
1092 | static struct event_constraint * | ||
1093 | ivt_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event) | ||
1094 | { | ||
1095 | return __snbep_cbox_get_constraint(box, event, ivt_cbox_filter_mask); | ||
1096 | } | ||
1097 | |||
1098 | static int ivt_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) | ||
1099 | { | ||
1100 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | ||
1101 | struct extra_reg *er; | ||
1102 | int idx = 0; | ||
1103 | |||
1104 | for (er = ivt_uncore_cbox_extra_regs; er->msr; er++) { | ||
1105 | if (er->event != (event->hw.config & er->config_mask)) | ||
1106 | continue; | ||
1107 | idx |= er->idx; | ||
1108 | } | ||
1109 | |||
1110 | if (idx) { | ||
1111 | reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER + | ||
1112 | SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx; | ||
1113 | reg1->config = event->attr.config1 & ivt_cbox_filter_mask(idx); | ||
1114 | reg1->idx = idx; | ||
1115 | } | ||
1116 | return 0; | ||
1117 | } | ||
1118 | |||
1119 | static void ivt_cbox_enable_event(struct intel_uncore_box *box, struct perf_event *event) | ||
1120 | { | ||
1121 | struct hw_perf_event *hwc = &event->hw; | ||
1122 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | ||
1123 | |||
1124 | if (reg1->idx != EXTRA_REG_NONE) { | ||
1125 | u64 filter = uncore_shared_reg_config(box, 0); | ||
1126 | wrmsrl(reg1->reg, filter & 0xffffffff); | ||
1127 | wrmsrl(reg1->reg + 6, filter >> 32); | ||
1128 | } | ||
1129 | |||
1130 | wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN); | ||
1131 | } | ||
1132 | |||
1133 | static struct intel_uncore_ops ivt_uncore_cbox_ops = { | ||
1134 | .init_box = ivt_uncore_msr_init_box, | ||
1135 | .disable_box = snbep_uncore_msr_disable_box, | ||
1136 | .enable_box = snbep_uncore_msr_enable_box, | ||
1137 | .disable_event = snbep_uncore_msr_disable_event, | ||
1138 | .enable_event = ivt_cbox_enable_event, | ||
1139 | .read_counter = uncore_msr_read_counter, | ||
1140 | .hw_config = ivt_cbox_hw_config, | ||
1141 | .get_constraint = ivt_cbox_get_constraint, | ||
1142 | .put_constraint = snbep_cbox_put_constraint, | ||
1143 | }; | ||
1144 | |||
1145 | static struct intel_uncore_type ivt_uncore_cbox = { | ||
1146 | .name = "cbox", | ||
1147 | .num_counters = 4, | ||
1148 | .num_boxes = 15, | ||
1149 | .perf_ctr_bits = 44, | ||
1150 | .event_ctl = SNBEP_C0_MSR_PMON_CTL0, | ||
1151 | .perf_ctr = SNBEP_C0_MSR_PMON_CTR0, | ||
1152 | .event_mask = IVT_CBO_MSR_PMON_RAW_EVENT_MASK, | ||
1153 | .box_ctl = SNBEP_C0_MSR_PMON_BOX_CTL, | ||
1154 | .msr_offset = SNBEP_CBO_MSR_OFFSET, | ||
1155 | .num_shared_regs = 1, | ||
1156 | .constraints = snbep_uncore_cbox_constraints, | ||
1157 | .ops = &ivt_uncore_cbox_ops, | ||
1158 | .format_group = &ivt_uncore_cbox_format_group, | ||
1159 | }; | ||
1160 | |||
1161 | static struct intel_uncore_ops ivt_uncore_pcu_ops = { | ||
1162 | IVT_UNCORE_MSR_OPS_COMMON_INIT(), | ||
1163 | .hw_config = snbep_pcu_hw_config, | ||
1164 | .get_constraint = snbep_pcu_get_constraint, | ||
1165 | .put_constraint = snbep_pcu_put_constraint, | ||
1166 | }; | ||
1167 | |||
1168 | static struct intel_uncore_type ivt_uncore_pcu = { | ||
1169 | .name = "pcu", | ||
1170 | .num_counters = 4, | ||
1171 | .num_boxes = 1, | ||
1172 | .perf_ctr_bits = 48, | ||
1173 | .perf_ctr = SNBEP_PCU_MSR_PMON_CTR0, | ||
1174 | .event_ctl = SNBEP_PCU_MSR_PMON_CTL0, | ||
1175 | .event_mask = IVT_PCU_MSR_PMON_RAW_EVENT_MASK, | ||
1176 | .box_ctl = SNBEP_PCU_MSR_PMON_BOX_CTL, | ||
1177 | .num_shared_regs = 1, | ||
1178 | .ops = &ivt_uncore_pcu_ops, | ||
1179 | .format_group = &ivt_uncore_pcu_format_group, | ||
1180 | }; | ||
1181 | |||
1182 | static struct intel_uncore_type *ivt_msr_uncores[] = { | ||
1183 | &ivt_uncore_ubox, | ||
1184 | &ivt_uncore_cbox, | ||
1185 | &ivt_uncore_pcu, | ||
1186 | NULL, | ||
1187 | }; | ||
1188 | |||
1189 | static struct intel_uncore_type ivt_uncore_ha = { | ||
1190 | .name = "ha", | ||
1191 | .num_counters = 4, | ||
1192 | .num_boxes = 2, | ||
1193 | .perf_ctr_bits = 48, | ||
1194 | IVT_UNCORE_PCI_COMMON_INIT(), | ||
1195 | }; | ||
1196 | |||
1197 | static struct intel_uncore_type ivt_uncore_imc = { | ||
1198 | .name = "imc", | ||
1199 | .num_counters = 4, | ||
1200 | .num_boxes = 8, | ||
1201 | .perf_ctr_bits = 48, | ||
1202 | .fixed_ctr_bits = 48, | ||
1203 | .fixed_ctr = SNBEP_MC_CHy_PCI_PMON_FIXED_CTR, | ||
1204 | .fixed_ctl = SNBEP_MC_CHy_PCI_PMON_FIXED_CTL, | ||
1205 | IVT_UNCORE_PCI_COMMON_INIT(), | ||
1206 | }; | ||
1207 | |||
1208 | static struct intel_uncore_type ivt_uncore_qpi = { | ||
1209 | .name = "qpi", | ||
1210 | .num_counters = 4, | ||
1211 | .num_boxes = 3, | ||
1212 | .perf_ctr_bits = 48, | ||
1213 | .perf_ctr = SNBEP_PCI_PMON_CTR0, | ||
1214 | .event_ctl = SNBEP_PCI_PMON_CTL0, | ||
1215 | .event_mask = IVT_QPI_PCI_PMON_RAW_EVENT_MASK, | ||
1216 | .box_ctl = SNBEP_PCI_PMON_BOX_CTL, | ||
1217 | .ops = &ivt_uncore_pci_ops, | ||
1218 | .format_group = &ivt_uncore_qpi_format_group, | ||
1219 | }; | ||
1220 | |||
1221 | static struct intel_uncore_type ivt_uncore_r2pcie = { | ||
1222 | .name = "r2pcie", | ||
1223 | .num_counters = 4, | ||
1224 | .num_boxes = 1, | ||
1225 | .perf_ctr_bits = 44, | ||
1226 | .constraints = snbep_uncore_r2pcie_constraints, | ||
1227 | IVT_UNCORE_PCI_COMMON_INIT(), | ||
1228 | }; | ||
1229 | |||
1230 | static struct intel_uncore_type ivt_uncore_r3qpi = { | ||
1231 | .name = "r3qpi", | ||
1232 | .num_counters = 3, | ||
1233 | .num_boxes = 2, | ||
1234 | .perf_ctr_bits = 44, | ||
1235 | .constraints = snbep_uncore_r3qpi_constraints, | ||
1236 | IVT_UNCORE_PCI_COMMON_INIT(), | ||
1237 | }; | ||
1238 | |||
1239 | enum { | ||
1240 | IVT_PCI_UNCORE_HA, | ||
1241 | IVT_PCI_UNCORE_IMC, | ||
1242 | IVT_PCI_UNCORE_QPI, | ||
1243 | IVT_PCI_UNCORE_R2PCIE, | ||
1244 | IVT_PCI_UNCORE_R3QPI, | ||
1245 | }; | ||
1246 | |||
1247 | static struct intel_uncore_type *ivt_pci_uncores[] = { | ||
1248 | [IVT_PCI_UNCORE_HA] = &ivt_uncore_ha, | ||
1249 | [IVT_PCI_UNCORE_IMC] = &ivt_uncore_imc, | ||
1250 | [IVT_PCI_UNCORE_QPI] = &ivt_uncore_qpi, | ||
1251 | [IVT_PCI_UNCORE_R2PCIE] = &ivt_uncore_r2pcie, | ||
1252 | [IVT_PCI_UNCORE_R3QPI] = &ivt_uncore_r3qpi, | ||
1253 | NULL, | ||
1254 | }; | ||
1255 | |||
1256 | static DEFINE_PCI_DEVICE_TABLE(ivt_uncore_pci_ids) = { | ||
1257 | { /* Home Agent 0 */ | ||
1258 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe30), | ||
1259 | .driver_data = IVT_PCI_UNCORE_HA, | ||
1260 | }, | ||
1261 | { /* Home Agent 1 */ | ||
1262 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe38), | ||
1263 | .driver_data = IVT_PCI_UNCORE_HA, | ||
1264 | }, | ||
1265 | { /* MC0 Channel 0 */ | ||
1266 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb4), | ||
1267 | .driver_data = IVT_PCI_UNCORE_IMC, | ||
1268 | }, | ||
1269 | { /* MC0 Channel 1 */ | ||
1270 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb5), | ||
1271 | .driver_data = IVT_PCI_UNCORE_IMC, | ||
1272 | }, | ||
1273 | { /* MC0 Channel 3 */ | ||
1274 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb0), | ||
1275 | .driver_data = IVT_PCI_UNCORE_IMC, | ||
1276 | }, | ||
1277 | { /* MC0 Channel 4 */ | ||
1278 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb1), | ||
1279 | .driver_data = IVT_PCI_UNCORE_IMC, | ||
1280 | }, | ||
1281 | { /* MC1 Channel 0 */ | ||
1282 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef4), | ||
1283 | .driver_data = IVT_PCI_UNCORE_IMC, | ||
1284 | }, | ||
1285 | { /* MC1 Channel 1 */ | ||
1286 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef5), | ||
1287 | .driver_data = IVT_PCI_UNCORE_IMC, | ||
1288 | }, | ||
1289 | { /* MC1 Channel 3 */ | ||
1290 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef0), | ||
1291 | .driver_data = IVT_PCI_UNCORE_IMC, | ||
1292 | }, | ||
1293 | { /* MC1 Channel 4 */ | ||
1294 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1), | ||
1295 | .driver_data = IVT_PCI_UNCORE_IMC, | ||
1296 | }, | ||
1297 | { /* QPI0 Port 0 */ | ||
1298 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32), | ||
1299 | .driver_data = IVT_PCI_UNCORE_QPI, | ||
1300 | }, | ||
1301 | { /* QPI0 Port 1 */ | ||
1302 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe33), | ||
1303 | .driver_data = IVT_PCI_UNCORE_QPI, | ||
1304 | }, | ||
1305 | { /* QPI1 Port 2 */ | ||
1306 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3a), | ||
1307 | .driver_data = IVT_PCI_UNCORE_QPI, | ||
1308 | }, | ||
1309 | { /* R2PCIe */ | ||
1310 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe34), | ||
1311 | .driver_data = IVT_PCI_UNCORE_R2PCIE, | ||
1312 | }, | ||
1313 | { /* R3QPI0 Link 0 */ | ||
1314 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe36), | ||
1315 | .driver_data = IVT_PCI_UNCORE_R3QPI, | ||
1316 | }, | ||
1317 | { /* R3QPI0 Link 1 */ | ||
1318 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe37), | ||
1319 | .driver_data = IVT_PCI_UNCORE_R3QPI, | ||
1320 | }, | ||
1321 | { /* R3QPI1 Link 2 */ | ||
1322 | PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3e), | ||
1323 | .driver_data = IVT_PCI_UNCORE_R3QPI, | ||
1324 | }, | ||
1325 | { /* end: all zeroes */ } | ||
1326 | }; | ||
1327 | |||
1328 | static struct pci_driver ivt_uncore_pci_driver = { | ||
1329 | .name = "ivt_uncore", | ||
1330 | .id_table = ivt_uncore_pci_ids, | ||
1331 | }; | ||
1332 | /* end of IvyTown uncore support */ | ||
1333 | |||
651 | /* Sandy Bridge uncore support */ | 1334 | /* Sandy Bridge uncore support */ |
652 | static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) | 1335 | static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) |
653 | { | 1336 | { |
@@ -808,9 +1491,6 @@ static struct intel_uncore_type *nhm_msr_uncores[] = { | |||
808 | /* end of Nehalem uncore support */ | 1491 | /* end of Nehalem uncore support */ |
809 | 1492 | ||
810 | /* Nehalem-EX uncore support */ | 1493 | /* Nehalem-EX uncore support */ |
811 | #define __BITS_VALUE(x, i, n) ((typeof(x))(((x) >> ((i) * (n))) & \ | ||
812 | ((1ULL << (n)) - 1))) | ||
813 | |||
814 | DEFINE_UNCORE_FORMAT_ATTR(event5, event, "config:1-5"); | 1494 | DEFINE_UNCORE_FORMAT_ATTR(event5, event, "config:1-5"); |
815 | DEFINE_UNCORE_FORMAT_ATTR(counter, counter, "config:6-7"); | 1495 | DEFINE_UNCORE_FORMAT_ATTR(counter, counter, "config:6-7"); |
816 | DEFINE_UNCORE_FORMAT_ATTR(match, match, "config1:0-63"); | 1496 | DEFINE_UNCORE_FORMAT_ATTR(match, match, "config1:0-63"); |
@@ -1161,7 +1841,7 @@ static struct extra_reg nhmex_uncore_mbox_extra_regs[] = { | |||
1161 | }; | 1841 | }; |
1162 | 1842 | ||
1163 | /* Nehalem-EX or Westmere-EX ? */ | 1843 | /* Nehalem-EX or Westmere-EX ? */ |
1164 | bool uncore_nhmex; | 1844 | static bool uncore_nhmex; |
1165 | 1845 | ||
1166 | static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 config) | 1846 | static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 config) |
1167 | { | 1847 | { |
@@ -1239,7 +1919,7 @@ static void nhmex_mbox_put_shared_reg(struct intel_uncore_box *box, int idx) | |||
1239 | atomic_sub(1 << (idx * 8), &er->ref); | 1919 | atomic_sub(1 << (idx * 8), &er->ref); |
1240 | } | 1920 | } |
1241 | 1921 | ||
1242 | u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modify) | 1922 | static u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modify) |
1243 | { | 1923 | { |
1244 | struct hw_perf_event *hwc = &event->hw; | 1924 | struct hw_perf_event *hwc = &event->hw; |
1245 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | 1925 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; |
@@ -1554,7 +2234,7 @@ static struct intel_uncore_type nhmex_uncore_mbox = { | |||
1554 | .format_group = &nhmex_uncore_mbox_format_group, | 2234 | .format_group = &nhmex_uncore_mbox_format_group, |
1555 | }; | 2235 | }; |
1556 | 2236 | ||
1557 | void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event) | 2237 | static void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event) |
1558 | { | 2238 | { |
1559 | struct hw_perf_event *hwc = &event->hw; | 2239 | struct hw_perf_event *hwc = &event->hw; |
1560 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | 2240 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; |
@@ -1724,21 +2404,6 @@ static int nhmex_rbox_hw_config(struct intel_uncore_box *box, struct perf_event | |||
1724 | return 0; | 2404 | return 0; |
1725 | } | 2405 | } |
1726 | 2406 | ||
1727 | static u64 nhmex_rbox_shared_reg_config(struct intel_uncore_box *box, int idx) | ||
1728 | { | ||
1729 | struct intel_uncore_extra_reg *er; | ||
1730 | unsigned long flags; | ||
1731 | u64 config; | ||
1732 | |||
1733 | er = &box->shared_regs[idx]; | ||
1734 | |||
1735 | raw_spin_lock_irqsave(&er->lock, flags); | ||
1736 | config = er->config; | ||
1737 | raw_spin_unlock_irqrestore(&er->lock, flags); | ||
1738 | |||
1739 | return config; | ||
1740 | } | ||
1741 | |||
1742 | static void nhmex_rbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) | 2407 | static void nhmex_rbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) |
1743 | { | 2408 | { |
1744 | struct hw_perf_event *hwc = &event->hw; | 2409 | struct hw_perf_event *hwc = &event->hw; |
@@ -1759,7 +2424,7 @@ static void nhmex_rbox_msr_enable_event(struct intel_uncore_box *box, struct per | |||
1759 | case 2: | 2424 | case 2: |
1760 | case 3: | 2425 | case 3: |
1761 | wrmsrl(NHMEX_R_MSR_PORTN_QLX_CFG(port), | 2426 | wrmsrl(NHMEX_R_MSR_PORTN_QLX_CFG(port), |
1762 | nhmex_rbox_shared_reg_config(box, 2 + (idx / 6) * 5)); | 2427 | uncore_shared_reg_config(box, 2 + (idx / 6) * 5)); |
1763 | break; | 2428 | break; |
1764 | case 4: | 2429 | case 4: |
1765 | wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port), | 2430 | wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port), |
@@ -2285,7 +2950,7 @@ out: | |||
2285 | return ret; | 2950 | return ret; |
2286 | } | 2951 | } |
2287 | 2952 | ||
2288 | int uncore_pmu_event_init(struct perf_event *event) | 2953 | static int uncore_pmu_event_init(struct perf_event *event) |
2289 | { | 2954 | { |
2290 | struct intel_uncore_pmu *pmu; | 2955 | struct intel_uncore_pmu *pmu; |
2291 | struct intel_uncore_box *box; | 2956 | struct intel_uncore_box *box; |
@@ -2438,7 +3103,7 @@ static int __init uncore_type_init(struct intel_uncore_type *type) | |||
2438 | 3103 | ||
2439 | type->unconstrainted = (struct event_constraint) | 3104 | type->unconstrainted = (struct event_constraint) |
2440 | __EVENT_CONSTRAINT(0, (1ULL << type->num_counters) - 1, | 3105 | __EVENT_CONSTRAINT(0, (1ULL << type->num_counters) - 1, |
2441 | 0, type->num_counters, 0); | 3106 | 0, type->num_counters, 0, 0); |
2442 | 3107 | ||
2443 | for (i = 0; i < type->num_boxes; i++) { | 3108 | for (i = 0; i < type->num_boxes; i++) { |
2444 | pmus[i].func_id = -1; | 3109 | pmus[i].func_id = -1; |
@@ -2556,6 +3221,8 @@ static void uncore_pci_remove(struct pci_dev *pdev) | |||
2556 | if (WARN_ON_ONCE(phys_id != box->phys_id)) | 3221 | if (WARN_ON_ONCE(phys_id != box->phys_id)) |
2557 | return; | 3222 | return; |
2558 | 3223 | ||
3224 | pci_set_drvdata(pdev, NULL); | ||
3225 | |||
2559 | raw_spin_lock(&uncore_box_lock); | 3226 | raw_spin_lock(&uncore_box_lock); |
2560 | list_del(&box->list); | 3227 | list_del(&box->list); |
2561 | raw_spin_unlock(&uncore_box_lock); | 3228 | raw_spin_unlock(&uncore_box_lock); |
@@ -2574,11 +3241,7 @@ static void uncore_pci_remove(struct pci_dev *pdev) | |||
2574 | static int uncore_pci_probe(struct pci_dev *pdev, | 3241 | static int uncore_pci_probe(struct pci_dev *pdev, |
2575 | const struct pci_device_id *id) | 3242 | const struct pci_device_id *id) |
2576 | { | 3243 | { |
2577 | struct intel_uncore_type *type; | 3244 | return uncore_pci_add(pci_uncores[id->driver_data], pdev); |
2578 | |||
2579 | type = (struct intel_uncore_type *)id->driver_data; | ||
2580 | |||
2581 | return uncore_pci_add(type, pdev); | ||
2582 | } | 3245 | } |
2583 | 3246 | ||
2584 | static int __init uncore_pci_init(void) | 3247 | static int __init uncore_pci_init(void) |
@@ -2587,12 +3250,19 @@ static int __init uncore_pci_init(void) | |||
2587 | 3250 | ||
2588 | switch (boot_cpu_data.x86_model) { | 3251 | switch (boot_cpu_data.x86_model) { |
2589 | case 45: /* Sandy Bridge-EP */ | 3252 | case 45: /* Sandy Bridge-EP */ |
2590 | ret = snbep_pci2phy_map_init(); | 3253 | ret = snbep_pci2phy_map_init(0x3ce0); |
2591 | if (ret) | 3254 | if (ret) |
2592 | return ret; | 3255 | return ret; |
2593 | pci_uncores = snbep_pci_uncores; | 3256 | pci_uncores = snbep_pci_uncores; |
2594 | uncore_pci_driver = &snbep_uncore_pci_driver; | 3257 | uncore_pci_driver = &snbep_uncore_pci_driver; |
2595 | break; | 3258 | break; |
3259 | case 62: /* IvyTown */ | ||
3260 | ret = snbep_pci2phy_map_init(0x0e1e); | ||
3261 | if (ret) | ||
3262 | return ret; | ||
3263 | pci_uncores = ivt_pci_uncores; | ||
3264 | uncore_pci_driver = &ivt_uncore_pci_driver; | ||
3265 | break; | ||
2596 | default: | 3266 | default: |
2597 | return 0; | 3267 | return 0; |
2598 | } | 3268 | } |
@@ -2622,6 +3292,21 @@ static void __init uncore_pci_exit(void) | |||
2622 | } | 3292 | } |
2623 | } | 3293 | } |
2624 | 3294 | ||
3295 | /* CPU hot plug/unplug are serialized by cpu_add_remove_lock mutex */ | ||
3296 | static LIST_HEAD(boxes_to_free); | ||
3297 | |||
3298 | static void __cpuinit uncore_kfree_boxes(void) | ||
3299 | { | ||
3300 | struct intel_uncore_box *box; | ||
3301 | |||
3302 | while (!list_empty(&boxes_to_free)) { | ||
3303 | box = list_entry(boxes_to_free.next, | ||
3304 | struct intel_uncore_box, list); | ||
3305 | list_del(&box->list); | ||
3306 | kfree(box); | ||
3307 | } | ||
3308 | } | ||
3309 | |||
2625 | static void __cpuinit uncore_cpu_dying(int cpu) | 3310 | static void __cpuinit uncore_cpu_dying(int cpu) |
2626 | { | 3311 | { |
2627 | struct intel_uncore_type *type; | 3312 | struct intel_uncore_type *type; |
@@ -2636,7 +3321,7 @@ static void __cpuinit uncore_cpu_dying(int cpu) | |||
2636 | box = *per_cpu_ptr(pmu->box, cpu); | 3321 | box = *per_cpu_ptr(pmu->box, cpu); |
2637 | *per_cpu_ptr(pmu->box, cpu) = NULL; | 3322 | *per_cpu_ptr(pmu->box, cpu) = NULL; |
2638 | if (box && atomic_dec_and_test(&box->refcnt)) | 3323 | if (box && atomic_dec_and_test(&box->refcnt)) |
2639 | kfree(box); | 3324 | list_add(&box->list, &boxes_to_free); |
2640 | } | 3325 | } |
2641 | } | 3326 | } |
2642 | } | 3327 | } |
@@ -2666,8 +3351,11 @@ static int __cpuinit uncore_cpu_starting(int cpu) | |||
2666 | if (exist && exist->phys_id == phys_id) { | 3351 | if (exist && exist->phys_id == phys_id) { |
2667 | atomic_inc(&exist->refcnt); | 3352 | atomic_inc(&exist->refcnt); |
2668 | *per_cpu_ptr(pmu->box, cpu) = exist; | 3353 | *per_cpu_ptr(pmu->box, cpu) = exist; |
2669 | kfree(box); | 3354 | if (box) { |
2670 | box = NULL; | 3355 | list_add(&box->list, |
3356 | &boxes_to_free); | ||
3357 | box = NULL; | ||
3358 | } | ||
2671 | break; | 3359 | break; |
2672 | } | 3360 | } |
2673 | } | 3361 | } |
@@ -2806,6 +3494,10 @@ static int | |||
2806 | case CPU_DYING: | 3494 | case CPU_DYING: |
2807 | uncore_cpu_dying(cpu); | 3495 | uncore_cpu_dying(cpu); |
2808 | break; | 3496 | break; |
3497 | case CPU_ONLINE: | ||
3498 | case CPU_DEAD: | ||
3499 | uncore_kfree_boxes(); | ||
3500 | break; | ||
2809 | default: | 3501 | default: |
2810 | break; | 3502 | break; |
2811 | } | 3503 | } |
@@ -2871,6 +3563,12 @@ static int __init uncore_cpu_init(void) | |||
2871 | nhmex_uncore_cbox.num_boxes = max_cores; | 3563 | nhmex_uncore_cbox.num_boxes = max_cores; |
2872 | msr_uncores = nhmex_msr_uncores; | 3564 | msr_uncores = nhmex_msr_uncores; |
2873 | break; | 3565 | break; |
3566 | case 62: /* IvyTown */ | ||
3567 | if (ivt_uncore_cbox.num_boxes > max_cores) | ||
3568 | ivt_uncore_cbox.num_boxes = max_cores; | ||
3569 | msr_uncores = ivt_msr_uncores; | ||
3570 | break; | ||
3571 | |||
2874 | default: | 3572 | default: |
2875 | return 0; | 3573 | return 0; |
2876 | } | 3574 | } |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index e68a4550e952..f9528917f6e8 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h | |||
@@ -76,7 +76,7 @@ | |||
76 | #define SNBEP_PMON_CTL_UMASK_MASK 0x0000ff00 | 76 | #define SNBEP_PMON_CTL_UMASK_MASK 0x0000ff00 |
77 | #define SNBEP_PMON_CTL_RST (1 << 17) | 77 | #define SNBEP_PMON_CTL_RST (1 << 17) |
78 | #define SNBEP_PMON_CTL_EDGE_DET (1 << 18) | 78 | #define SNBEP_PMON_CTL_EDGE_DET (1 << 18) |
79 | #define SNBEP_PMON_CTL_EV_SEL_EXT (1 << 21) /* only for QPI */ | 79 | #define SNBEP_PMON_CTL_EV_SEL_EXT (1 << 21) |
80 | #define SNBEP_PMON_CTL_EN (1 << 22) | 80 | #define SNBEP_PMON_CTL_EN (1 << 22) |
81 | #define SNBEP_PMON_CTL_INVERT (1 << 23) | 81 | #define SNBEP_PMON_CTL_INVERT (1 << 23) |
82 | #define SNBEP_PMON_CTL_TRESH_MASK 0xff000000 | 82 | #define SNBEP_PMON_CTL_TRESH_MASK 0xff000000 |
@@ -148,9 +148,20 @@ | |||
148 | #define SNBEP_C0_MSR_PMON_CTL0 0xd10 | 148 | #define SNBEP_C0_MSR_PMON_CTL0 0xd10 |
149 | #define SNBEP_C0_MSR_PMON_BOX_CTL 0xd04 | 149 | #define SNBEP_C0_MSR_PMON_BOX_CTL 0xd04 |
150 | #define SNBEP_C0_MSR_PMON_BOX_FILTER 0xd14 | 150 | #define SNBEP_C0_MSR_PMON_BOX_FILTER 0xd14 |
151 | #define SNBEP_CB0_MSR_PMON_BOX_FILTER_MASK 0xfffffc1f | ||
152 | #define SNBEP_CBO_MSR_OFFSET 0x20 | 151 | #define SNBEP_CBO_MSR_OFFSET 0x20 |
153 | 152 | ||
153 | #define SNBEP_CB0_MSR_PMON_BOX_FILTER_TID 0x1f | ||
154 | #define SNBEP_CB0_MSR_PMON_BOX_FILTER_NID 0x3fc00 | ||
155 | #define SNBEP_CB0_MSR_PMON_BOX_FILTER_STATE 0x7c0000 | ||
156 | #define SNBEP_CB0_MSR_PMON_BOX_FILTER_OPC 0xff800000 | ||
157 | |||
158 | #define SNBEP_CBO_EVENT_EXTRA_REG(e, m, i) { \ | ||
159 | .event = (e), \ | ||
160 | .msr = SNBEP_C0_MSR_PMON_BOX_FILTER, \ | ||
161 | .config_mask = (m), \ | ||
162 | .idx = (i) \ | ||
163 | } | ||
164 | |||
154 | /* SNB-EP PCU register */ | 165 | /* SNB-EP PCU register */ |
155 | #define SNBEP_PCU_MSR_PMON_CTR0 0xc36 | 166 | #define SNBEP_PCU_MSR_PMON_CTR0 0xc36 |
156 | #define SNBEP_PCU_MSR_PMON_CTL0 0xc30 | 167 | #define SNBEP_PCU_MSR_PMON_CTL0 0xc30 |
@@ -160,6 +171,55 @@ | |||
160 | #define SNBEP_PCU_MSR_CORE_C3_CTR 0x3fc | 171 | #define SNBEP_PCU_MSR_CORE_C3_CTR 0x3fc |
161 | #define SNBEP_PCU_MSR_CORE_C6_CTR 0x3fd | 172 | #define SNBEP_PCU_MSR_CORE_C6_CTR 0x3fd |
162 | 173 | ||
174 | /* IVT event control */ | ||
175 | #define IVT_PMON_BOX_CTL_INT (SNBEP_PMON_BOX_CTL_RST_CTRL | \ | ||
176 | SNBEP_PMON_BOX_CTL_RST_CTRS) | ||
177 | #define IVT_PMON_RAW_EVENT_MASK (SNBEP_PMON_CTL_EV_SEL_MASK | \ | ||
178 | SNBEP_PMON_CTL_UMASK_MASK | \ | ||
179 | SNBEP_PMON_CTL_EDGE_DET | \ | ||
180 | SNBEP_PMON_CTL_TRESH_MASK) | ||
181 | /* IVT Ubox */ | ||
182 | #define IVT_U_MSR_PMON_GLOBAL_CTL 0xc00 | ||
183 | #define IVT_U_PMON_GLOBAL_FRZ_ALL (1 << 31) | ||
184 | #define IVT_U_PMON_GLOBAL_UNFRZ_ALL (1 << 29) | ||
185 | |||
186 | #define IVT_U_MSR_PMON_RAW_EVENT_MASK \ | ||
187 | (SNBEP_PMON_CTL_EV_SEL_MASK | \ | ||
188 | SNBEP_PMON_CTL_UMASK_MASK | \ | ||
189 | SNBEP_PMON_CTL_EDGE_DET | \ | ||
190 | SNBEP_U_MSR_PMON_CTL_TRESH_MASK) | ||
191 | /* IVT Cbo */ | ||
192 | #define IVT_CBO_MSR_PMON_RAW_EVENT_MASK (IVT_PMON_RAW_EVENT_MASK | \ | ||
193 | SNBEP_CBO_PMON_CTL_TID_EN) | ||
194 | |||
195 | #define IVT_CB0_MSR_PMON_BOX_FILTER_TID (0x1fULL << 0) | ||
196 | #define IVT_CB0_MSR_PMON_BOX_FILTER_LINK (0xfULL << 5) | ||
197 | #define IVT_CB0_MSR_PMON_BOX_FILTER_STATE (0x3fULL << 17) | ||
198 | #define IVT_CB0_MSR_PMON_BOX_FILTER_NID (0xffffULL << 32) | ||
199 | #define IVT_CB0_MSR_PMON_BOX_FILTER_OPC (0x1ffULL << 52) | ||
200 | #define IVT_CB0_MSR_PMON_BOX_FILTER_C6 (0x1ULL << 61) | ||
201 | #define IVT_CB0_MSR_PMON_BOX_FILTER_NC (0x1ULL << 62) | ||
202 | #define IVT_CB0_MSR_PMON_BOX_FILTER_IOSC (0x1ULL << 63) | ||
203 | |||
204 | /* IVT home agent */ | ||
205 | #define IVT_HA_PCI_PMON_CTL_Q_OCC_RST (1 << 16) | ||
206 | #define IVT_HA_PCI_PMON_RAW_EVENT_MASK \ | ||
207 | (IVT_PMON_RAW_EVENT_MASK | \ | ||
208 | IVT_HA_PCI_PMON_CTL_Q_OCC_RST) | ||
209 | /* IVT PCU */ | ||
210 | #define IVT_PCU_MSR_PMON_RAW_EVENT_MASK \ | ||
211 | (SNBEP_PMON_CTL_EV_SEL_MASK | \ | ||
212 | SNBEP_PMON_CTL_EV_SEL_EXT | \ | ||
213 | SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \ | ||
214 | SNBEP_PMON_CTL_EDGE_DET | \ | ||
215 | SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \ | ||
216 | SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ | ||
217 | SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET) | ||
218 | /* IVT QPI */ | ||
219 | #define IVT_QPI_PCI_PMON_RAW_EVENT_MASK \ | ||
220 | (IVT_PMON_RAW_EVENT_MASK | \ | ||
221 | SNBEP_PMON_CTL_EV_SEL_EXT) | ||
222 | |||
163 | /* NHM-EX event control */ | 223 | /* NHM-EX event control */ |
164 | #define NHMEX_PMON_CTL_EV_SEL_MASK 0x000000ff | 224 | #define NHMEX_PMON_CTL_EV_SEL_MASK 0x000000ff |
165 | #define NHMEX_PMON_CTL_UMASK_MASK 0x0000ff00 | 225 | #define NHMEX_PMON_CTL_UMASK_MASK 0x0000ff00 |
diff --git a/arch/x86/kernel/cpu/perf_event_p4.c b/arch/x86/kernel/cpu/perf_event_p4.c index 92c7e39a079f..3486e6660357 100644 --- a/arch/x86/kernel/cpu/perf_event_p4.c +++ b/arch/x86/kernel/cpu/perf_event_p4.c | |||
@@ -895,8 +895,8 @@ static void p4_pmu_disable_pebs(void) | |||
895 | * So at moment let leave metrics turned on forever -- it's | 895 | * So at moment let leave metrics turned on forever -- it's |
896 | * ok for now but need to be revisited! | 896 | * ok for now but need to be revisited! |
897 | * | 897 | * |
898 | * (void)wrmsrl_safe(MSR_IA32_PEBS_ENABLE, (u64)0); | 898 | * (void)wrmsrl_safe(MSR_IA32_PEBS_ENABLE, 0); |
899 | * (void)wrmsrl_safe(MSR_P4_PEBS_MATRIX_VERT, (u64)0); | 899 | * (void)wrmsrl_safe(MSR_P4_PEBS_MATRIX_VERT, 0); |
900 | */ | 900 | */ |
901 | } | 901 | } |
902 | 902 | ||
@@ -910,8 +910,7 @@ static inline void p4_pmu_disable_event(struct perf_event *event) | |||
910 | * asserted again and again | 910 | * asserted again and again |
911 | */ | 911 | */ |
912 | (void)wrmsrl_safe(hwc->config_base, | 912 | (void)wrmsrl_safe(hwc->config_base, |
913 | (u64)(p4_config_unpack_cccr(hwc->config)) & | 913 | p4_config_unpack_cccr(hwc->config) & ~P4_CCCR_ENABLE & ~P4_CCCR_OVF & ~P4_CCCR_RESERVED); |
914 | ~P4_CCCR_ENABLE & ~P4_CCCR_OVF & ~P4_CCCR_RESERVED); | ||
915 | } | 914 | } |
916 | 915 | ||
917 | static void p4_pmu_disable_all(void) | 916 | static void p4_pmu_disable_all(void) |
@@ -957,7 +956,7 @@ static void p4_pmu_enable_event(struct perf_event *event) | |||
957 | u64 escr_addr, cccr; | 956 | u64 escr_addr, cccr; |
958 | 957 | ||
959 | bind = &p4_event_bind_map[idx]; | 958 | bind = &p4_event_bind_map[idx]; |
960 | escr_addr = (u64)bind->escr_msr[thread]; | 959 | escr_addr = bind->escr_msr[thread]; |
961 | 960 | ||
962 | /* | 961 | /* |
963 | * - we dont support cascaded counters yet | 962 | * - we dont support cascaded counters yet |
diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index 9b9f18b49918..d15f575a861b 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c | |||
@@ -169,25 +169,9 @@ static struct console early_serial_console = { | |||
169 | .index = -1, | 169 | .index = -1, |
170 | }; | 170 | }; |
171 | 171 | ||
172 | /* Direct interface for emergencies */ | ||
173 | static struct console *early_console = &early_vga_console; | ||
174 | static int __initdata early_console_initialized; | ||
175 | |||
176 | asmlinkage void early_printk(const char *fmt, ...) | ||
177 | { | ||
178 | char buf[512]; | ||
179 | int n; | ||
180 | va_list ap; | ||
181 | |||
182 | va_start(ap, fmt); | ||
183 | n = vscnprintf(buf, sizeof(buf), fmt, ap); | ||
184 | early_console->write(early_console, buf, n); | ||
185 | va_end(ap); | ||
186 | } | ||
187 | |||
188 | static inline void early_console_register(struct console *con, int keep_early) | 172 | static inline void early_console_register(struct console *con, int keep_early) |
189 | { | 173 | { |
190 | if (early_console->index != -1) { | 174 | if (con->index != -1) { |
191 | printk(KERN_CRIT "ERROR: earlyprintk= %s already used\n", | 175 | printk(KERN_CRIT "ERROR: earlyprintk= %s already used\n", |
192 | con->name); | 176 | con->name); |
193 | return; | 177 | return; |
@@ -207,9 +191,8 @@ static int __init setup_early_printk(char *buf) | |||
207 | if (!buf) | 191 | if (!buf) |
208 | return 0; | 192 | return 0; |
209 | 193 | ||
210 | if (early_console_initialized) | 194 | if (early_console) |
211 | return 0; | 195 | return 0; |
212 | early_console_initialized = 1; | ||
213 | 196 | ||
214 | keep = (strstr(buf, "keep") != NULL); | 197 | keep = (strstr(buf, "keep") != NULL); |
215 | 198 | ||
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 7bfe318d3d8a..9895a9a41380 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c | |||
@@ -353,7 +353,11 @@ int __kprobes __copy_instruction(u8 *dest, u8 *src) | |||
353 | * have given. | 353 | * have given. |
354 | */ | 354 | */ |
355 | newdisp = (u8 *) src + (s64) insn.displacement.value - (u8 *) dest; | 355 | newdisp = (u8 *) src + (s64) insn.displacement.value - (u8 *) dest; |
356 | BUG_ON((s64) (s32) newdisp != newdisp); /* Sanity check. */ | 356 | if ((s64) (s32) newdisp != newdisp) { |
357 | pr_err("Kprobes error: new displacement does not fit into s32 (%llx)\n", newdisp); | ||
358 | pr_err("\tSrc: %p, Dest: %p, old disp: %x\n", src, dest, insn.displacement.value); | ||
359 | return 0; | ||
360 | } | ||
357 | disp = (u8 *) dest + insn_offset_displacement(&insn); | 361 | disp = (u8 *) dest + insn_offset_displacement(&insn); |
358 | *(s32 *) disp = (s32) newdisp; | 362 | *(s32 *) disp = (s32) newdisp; |
359 | } | 363 | } |
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index b686a904d7c3..cd6d9a5a42f6 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c | |||
@@ -20,6 +20,7 @@ | |||
20 | * Authors: Anthony Liguori <aliguori@us.ibm.com> | 20 | * Authors: Anthony Liguori <aliguori@us.ibm.com> |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/context_tracking.h> | ||
23 | #include <linux/module.h> | 24 | #include <linux/module.h> |
24 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
25 | #include <linux/kvm_para.h> | 26 | #include <linux/kvm_para.h> |
@@ -43,7 +44,6 @@ | |||
43 | #include <asm/apicdef.h> | 44 | #include <asm/apicdef.h> |
44 | #include <asm/hypervisor.h> | 45 | #include <asm/hypervisor.h> |
45 | #include <asm/kvm_guest.h> | 46 | #include <asm/kvm_guest.h> |
46 | #include <asm/context_tracking.h> | ||
47 | 47 | ||
48 | static int kvmapf = 1; | 48 | static int kvmapf = 1; |
49 | 49 | ||
@@ -254,16 +254,18 @@ EXPORT_SYMBOL_GPL(kvm_read_and_reset_pf_reason); | |||
254 | dotraplinkage void __kprobes | 254 | dotraplinkage void __kprobes |
255 | do_async_page_fault(struct pt_regs *regs, unsigned long error_code) | 255 | do_async_page_fault(struct pt_regs *regs, unsigned long error_code) |
256 | { | 256 | { |
257 | enum ctx_state prev_state; | ||
258 | |||
257 | switch (kvm_read_and_reset_pf_reason()) { | 259 | switch (kvm_read_and_reset_pf_reason()) { |
258 | default: | 260 | default: |
259 | do_page_fault(regs, error_code); | 261 | do_page_fault(regs, error_code); |
260 | break; | 262 | break; |
261 | case KVM_PV_REASON_PAGE_NOT_PRESENT: | 263 | case KVM_PV_REASON_PAGE_NOT_PRESENT: |
262 | /* page is swapped out by the host. */ | 264 | /* page is swapped out by the host. */ |
263 | exception_enter(regs); | 265 | prev_state = exception_enter(); |
264 | exit_idle(); | 266 | exit_idle(); |
265 | kvm_async_pf_task_wait((u32)read_cr2()); | 267 | kvm_async_pf_task_wait((u32)read_cr2()); |
266 | exception_exit(regs); | 268 | exception_exit(prev_state); |
267 | break; | 269 | break; |
268 | case KVM_PV_REASON_PAGE_READY: | 270 | case KVM_PV_REASON_PAGE_READY: |
269 | rcu_irq_enter(); | 271 | rcu_irq_enter(); |
diff --git a/arch/x86/kernel/microcode_core_early.c b/arch/x86/kernel/microcode_core_early.c index 577db8417d15..833d51d6ee06 100644 --- a/arch/x86/kernel/microcode_core_early.c +++ b/arch/x86/kernel/microcode_core_early.c | |||
@@ -45,9 +45,6 @@ static int __cpuinit x86_vendor(void) | |||
45 | u32 eax = 0x00000000; | 45 | u32 eax = 0x00000000; |
46 | u32 ebx, ecx = 0, edx; | 46 | u32 ebx, ecx = 0, edx; |
47 | 47 | ||
48 | if (!have_cpuid_p()) | ||
49 | return X86_VENDOR_UNKNOWN; | ||
50 | |||
51 | native_cpuid(&eax, &ebx, &ecx, &edx); | 48 | native_cpuid(&eax, &ebx, &ecx, &edx); |
52 | 49 | ||
53 | if (CPUID_IS(CPUID_INTEL1, CPUID_INTEL2, CPUID_INTEL3, ebx, ecx, edx)) | 50 | if (CPUID_IS(CPUID_INTEL1, CPUID_INTEL2, CPUID_INTEL3, ebx, ecx, edx)) |
@@ -59,18 +56,45 @@ static int __cpuinit x86_vendor(void) | |||
59 | return X86_VENDOR_UNKNOWN; | 56 | return X86_VENDOR_UNKNOWN; |
60 | } | 57 | } |
61 | 58 | ||
59 | static int __cpuinit x86_family(void) | ||
60 | { | ||
61 | u32 eax = 0x00000001; | ||
62 | u32 ebx, ecx = 0, edx; | ||
63 | int x86; | ||
64 | |||
65 | native_cpuid(&eax, &ebx, &ecx, &edx); | ||
66 | |||
67 | x86 = (eax >> 8) & 0xf; | ||
68 | if (x86 == 15) | ||
69 | x86 += (eax >> 20) & 0xff; | ||
70 | |||
71 | return x86; | ||
72 | } | ||
73 | |||
62 | void __init load_ucode_bsp(void) | 74 | void __init load_ucode_bsp(void) |
63 | { | 75 | { |
64 | int vendor = x86_vendor(); | 76 | int vendor, x86; |
77 | |||
78 | if (!have_cpuid_p()) | ||
79 | return; | ||
65 | 80 | ||
66 | if (vendor == X86_VENDOR_INTEL) | 81 | vendor = x86_vendor(); |
82 | x86 = x86_family(); | ||
83 | |||
84 | if (vendor == X86_VENDOR_INTEL && x86 >= 6) | ||
67 | load_ucode_intel_bsp(); | 85 | load_ucode_intel_bsp(); |
68 | } | 86 | } |
69 | 87 | ||
70 | void __cpuinit load_ucode_ap(void) | 88 | void __cpuinit load_ucode_ap(void) |
71 | { | 89 | { |
72 | int vendor = x86_vendor(); | 90 | int vendor, x86; |
91 | |||
92 | if (!have_cpuid_p()) | ||
93 | return; | ||
94 | |||
95 | vendor = x86_vendor(); | ||
96 | x86 = x86_family(); | ||
73 | 97 | ||
74 | if (vendor == X86_VENDOR_INTEL) | 98 | if (vendor == X86_VENDOR_INTEL && x86 >= 6) |
75 | load_ucode_intel_ap(); | 99 | load_ucode_intel_ap(); |
76 | } | 100 | } |
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 17fff18a1031..8bfb335f74bb 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c | |||
@@ -263,6 +263,18 @@ void paravirt_leave_lazy_mmu(void) | |||
263 | leave_lazy(PARAVIRT_LAZY_MMU); | 263 | leave_lazy(PARAVIRT_LAZY_MMU); |
264 | } | 264 | } |
265 | 265 | ||
266 | void paravirt_flush_lazy_mmu(void) | ||
267 | { | ||
268 | preempt_disable(); | ||
269 | |||
270 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { | ||
271 | arch_leave_lazy_mmu_mode(); | ||
272 | arch_enter_lazy_mmu_mode(); | ||
273 | } | ||
274 | |||
275 | preempt_enable(); | ||
276 | } | ||
277 | |||
266 | void paravirt_start_context_switch(struct task_struct *prev) | 278 | void paravirt_start_context_switch(struct task_struct *prev) |
267 | { | 279 | { |
268 | BUG_ON(preemptible()); | 280 | BUG_ON(preemptible()); |
@@ -292,18 +304,6 @@ enum paravirt_lazy_mode paravirt_get_lazy_mode(void) | |||
292 | return this_cpu_read(paravirt_lazy_mode); | 304 | return this_cpu_read(paravirt_lazy_mode); |
293 | } | 305 | } |
294 | 306 | ||
295 | void arch_flush_lazy_mmu_mode(void) | ||
296 | { | ||
297 | preempt_disable(); | ||
298 | |||
299 | if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) { | ||
300 | arch_leave_lazy_mmu_mode(); | ||
301 | arch_enter_lazy_mmu_mode(); | ||
302 | } | ||
303 | |||
304 | preempt_enable(); | ||
305 | } | ||
306 | |||
307 | struct pv_info pv_info = { | 307 | struct pv_info pv_info = { |
308 | .name = "bare hardware", | 308 | .name = "bare hardware", |
309 | .paravirt_enabled = 0, | 309 | .paravirt_enabled = 0, |
@@ -475,6 +475,7 @@ struct pv_mmu_ops pv_mmu_ops = { | |||
475 | .lazy_mode = { | 475 | .lazy_mode = { |
476 | .enter = paravirt_nop, | 476 | .enter = paravirt_nop, |
477 | .leave = paravirt_nop, | 477 | .leave = paravirt_nop, |
478 | .flush = paravirt_nop, | ||
478 | }, | 479 | }, |
479 | 480 | ||
480 | .set_fixmap = native_set_fixmap, | 481 | .set_fixmap = native_set_fixmap, |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 90d8cc930f5e..fae9134a2de9 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -507,11 +507,14 @@ static void __init memblock_x86_reserve_range_setup_data(void) | |||
507 | /* | 507 | /* |
508 | * Keep the crash kernel below this limit. On 32 bits earlier kernels | 508 | * Keep the crash kernel below this limit. On 32 bits earlier kernels |
509 | * would limit the kernel to the low 512 MiB due to mapping restrictions. | 509 | * would limit the kernel to the low 512 MiB due to mapping restrictions. |
510 | * On 64bit, old kexec-tools need to under 896MiB. | ||
510 | */ | 511 | */ |
511 | #ifdef CONFIG_X86_32 | 512 | #ifdef CONFIG_X86_32 |
512 | # define CRASH_KERNEL_ADDR_MAX (512 << 20) | 513 | # define CRASH_KERNEL_ADDR_LOW_MAX (512 << 20) |
514 | # define CRASH_KERNEL_ADDR_HIGH_MAX (512 << 20) | ||
513 | #else | 515 | #else |
514 | # define CRASH_KERNEL_ADDR_MAX MAXMEM | 516 | # define CRASH_KERNEL_ADDR_LOW_MAX (896UL<<20) |
517 | # define CRASH_KERNEL_ADDR_HIGH_MAX MAXMEM | ||
515 | #endif | 518 | #endif |
516 | 519 | ||
517 | static void __init reserve_crashkernel_low(void) | 520 | static void __init reserve_crashkernel_low(void) |
@@ -521,19 +524,35 @@ static void __init reserve_crashkernel_low(void) | |||
521 | unsigned long long low_base = 0, low_size = 0; | 524 | unsigned long long low_base = 0, low_size = 0; |
522 | unsigned long total_low_mem; | 525 | unsigned long total_low_mem; |
523 | unsigned long long base; | 526 | unsigned long long base; |
527 | bool auto_set = false; | ||
524 | int ret; | 528 | int ret; |
525 | 529 | ||
526 | total_low_mem = memblock_mem_size(1UL<<(32-PAGE_SHIFT)); | 530 | total_low_mem = memblock_mem_size(1UL<<(32-PAGE_SHIFT)); |
531 | /* crashkernel=Y,low */ | ||
527 | ret = parse_crashkernel_low(boot_command_line, total_low_mem, | 532 | ret = parse_crashkernel_low(boot_command_line, total_low_mem, |
528 | &low_size, &base); | 533 | &low_size, &base); |
529 | if (ret != 0 || low_size <= 0) | 534 | if (ret != 0) { |
530 | return; | 535 | /* |
536 | * two parts from lib/swiotlb.c: | ||
537 | * swiotlb size: user specified with swiotlb= or default. | ||
538 | * swiotlb overflow buffer: now is hardcoded to 32k. | ||
539 | * We round it to 8M for other buffers that | ||
540 | * may need to stay low too. | ||
541 | */ | ||
542 | low_size = swiotlb_size_or_default() + (8UL<<20); | ||
543 | auto_set = true; | ||
544 | } else { | ||
545 | /* passed with crashkernel=0,low ? */ | ||
546 | if (!low_size) | ||
547 | return; | ||
548 | } | ||
531 | 549 | ||
532 | low_base = memblock_find_in_range(low_size, (1ULL<<32), | 550 | low_base = memblock_find_in_range(low_size, (1ULL<<32), |
533 | low_size, alignment); | 551 | low_size, alignment); |
534 | 552 | ||
535 | if (!low_base) { | 553 | if (!low_base) { |
536 | pr_info("crashkernel low reservation failed - No suitable area found.\n"); | 554 | if (!auto_set) |
555 | pr_info("crashkernel low reservation failed - No suitable area found.\n"); | ||
537 | 556 | ||
538 | return; | 557 | return; |
539 | } | 558 | } |
@@ -554,14 +573,22 @@ static void __init reserve_crashkernel(void) | |||
554 | const unsigned long long alignment = 16<<20; /* 16M */ | 573 | const unsigned long long alignment = 16<<20; /* 16M */ |
555 | unsigned long long total_mem; | 574 | unsigned long long total_mem; |
556 | unsigned long long crash_size, crash_base; | 575 | unsigned long long crash_size, crash_base; |
576 | bool high = false; | ||
557 | int ret; | 577 | int ret; |
558 | 578 | ||
559 | total_mem = memblock_phys_mem_size(); | 579 | total_mem = memblock_phys_mem_size(); |
560 | 580 | ||
581 | /* crashkernel=XM */ | ||
561 | ret = parse_crashkernel(boot_command_line, total_mem, | 582 | ret = parse_crashkernel(boot_command_line, total_mem, |
562 | &crash_size, &crash_base); | 583 | &crash_size, &crash_base); |
563 | if (ret != 0 || crash_size <= 0) | 584 | if (ret != 0 || crash_size <= 0) { |
564 | return; | 585 | /* crashkernel=X,high */ |
586 | ret = parse_crashkernel_high(boot_command_line, total_mem, | ||
587 | &crash_size, &crash_base); | ||
588 | if (ret != 0 || crash_size <= 0) | ||
589 | return; | ||
590 | high = true; | ||
591 | } | ||
565 | 592 | ||
566 | /* 0 means: find the address automatically */ | 593 | /* 0 means: find the address automatically */ |
567 | if (crash_base <= 0) { | 594 | if (crash_base <= 0) { |
@@ -569,7 +596,9 @@ static void __init reserve_crashkernel(void) | |||
569 | * kexec want bzImage is below CRASH_KERNEL_ADDR_MAX | 596 | * kexec want bzImage is below CRASH_KERNEL_ADDR_MAX |
570 | */ | 597 | */ |
571 | crash_base = memblock_find_in_range(alignment, | 598 | crash_base = memblock_find_in_range(alignment, |
572 | CRASH_KERNEL_ADDR_MAX, crash_size, alignment); | 599 | high ? CRASH_KERNEL_ADDR_HIGH_MAX : |
600 | CRASH_KERNEL_ADDR_LOW_MAX, | ||
601 | crash_size, alignment); | ||
573 | 602 | ||
574 | if (!crash_base) { | 603 | if (!crash_base) { |
575 | pr_info("crashkernel reservation failed - No suitable area found.\n"); | 604 | pr_info("crashkernel reservation failed - No suitable area found.\n"); |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 68bda7a84159..ff6d2271cbe2 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 13 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
14 | 14 | ||
15 | #include <linux/context_tracking.h> | ||
15 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
16 | #include <linux/kallsyms.h> | 17 | #include <linux/kallsyms.h> |
17 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
@@ -55,8 +56,6 @@ | |||
55 | #include <asm/i387.h> | 56 | #include <asm/i387.h> |
56 | #include <asm/fpu-internal.h> | 57 | #include <asm/fpu-internal.h> |
57 | #include <asm/mce.h> | 58 | #include <asm/mce.h> |
58 | #include <asm/context_tracking.h> | ||
59 | |||
60 | #include <asm/mach_traps.h> | 59 | #include <asm/mach_traps.h> |
61 | 60 | ||
62 | #ifdef CONFIG_X86_64 | 61 | #ifdef CONFIG_X86_64 |
@@ -176,34 +175,38 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs, | |||
176 | #define DO_ERROR(trapnr, signr, str, name) \ | 175 | #define DO_ERROR(trapnr, signr, str, name) \ |
177 | dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ | 176 | dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ |
178 | { \ | 177 | { \ |
179 | exception_enter(regs); \ | 178 | enum ctx_state prev_state; \ |
179 | \ | ||
180 | prev_state = exception_enter(); \ | ||
180 | if (notify_die(DIE_TRAP, str, regs, error_code, \ | 181 | if (notify_die(DIE_TRAP, str, regs, error_code, \ |
181 | trapnr, signr) == NOTIFY_STOP) { \ | 182 | trapnr, signr) == NOTIFY_STOP) { \ |
182 | exception_exit(regs); \ | 183 | exception_exit(prev_state); \ |
183 | return; \ | 184 | return; \ |
184 | } \ | 185 | } \ |
185 | conditional_sti(regs); \ | 186 | conditional_sti(regs); \ |
186 | do_trap(trapnr, signr, str, regs, error_code, NULL); \ | 187 | do_trap(trapnr, signr, str, regs, error_code, NULL); \ |
187 | exception_exit(regs); \ | 188 | exception_exit(prev_state); \ |
188 | } | 189 | } |
189 | 190 | ||
190 | #define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ | 191 | #define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr) \ |
191 | dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ | 192 | dotraplinkage void do_##name(struct pt_regs *regs, long error_code) \ |
192 | { \ | 193 | { \ |
193 | siginfo_t info; \ | 194 | siginfo_t info; \ |
195 | enum ctx_state prev_state; \ | ||
196 | \ | ||
194 | info.si_signo = signr; \ | 197 | info.si_signo = signr; \ |
195 | info.si_errno = 0; \ | 198 | info.si_errno = 0; \ |
196 | info.si_code = sicode; \ | 199 | info.si_code = sicode; \ |
197 | info.si_addr = (void __user *)siaddr; \ | 200 | info.si_addr = (void __user *)siaddr; \ |
198 | exception_enter(regs); \ | 201 | prev_state = exception_enter(); \ |
199 | if (notify_die(DIE_TRAP, str, regs, error_code, \ | 202 | if (notify_die(DIE_TRAP, str, regs, error_code, \ |
200 | trapnr, signr) == NOTIFY_STOP) { \ | 203 | trapnr, signr) == NOTIFY_STOP) { \ |
201 | exception_exit(regs); \ | 204 | exception_exit(prev_state); \ |
202 | return; \ | 205 | return; \ |
203 | } \ | 206 | } \ |
204 | conditional_sti(regs); \ | 207 | conditional_sti(regs); \ |
205 | do_trap(trapnr, signr, str, regs, error_code, &info); \ | 208 | do_trap(trapnr, signr, str, regs, error_code, &info); \ |
206 | exception_exit(regs); \ | 209 | exception_exit(prev_state); \ |
207 | } | 210 | } |
208 | 211 | ||
209 | DO_ERROR_INFO(X86_TRAP_DE, SIGFPE, "divide error", divide_error, FPE_INTDIV, | 212 | DO_ERROR_INFO(X86_TRAP_DE, SIGFPE, "divide error", divide_error, FPE_INTDIV, |
@@ -226,14 +229,16 @@ DO_ERROR_INFO(X86_TRAP_AC, SIGBUS, "alignment check", alignment_check, | |||
226 | /* Runs on IST stack */ | 229 | /* Runs on IST stack */ |
227 | dotraplinkage void do_stack_segment(struct pt_regs *regs, long error_code) | 230 | dotraplinkage void do_stack_segment(struct pt_regs *regs, long error_code) |
228 | { | 231 | { |
229 | exception_enter(regs); | 232 | enum ctx_state prev_state; |
233 | |||
234 | prev_state = exception_enter(); | ||
230 | if (notify_die(DIE_TRAP, "stack segment", regs, error_code, | 235 | if (notify_die(DIE_TRAP, "stack segment", regs, error_code, |
231 | X86_TRAP_SS, SIGBUS) != NOTIFY_STOP) { | 236 | X86_TRAP_SS, SIGBUS) != NOTIFY_STOP) { |
232 | preempt_conditional_sti(regs); | 237 | preempt_conditional_sti(regs); |
233 | do_trap(X86_TRAP_SS, SIGBUS, "stack segment", regs, error_code, NULL); | 238 | do_trap(X86_TRAP_SS, SIGBUS, "stack segment", regs, error_code, NULL); |
234 | preempt_conditional_cli(regs); | 239 | preempt_conditional_cli(regs); |
235 | } | 240 | } |
236 | exception_exit(regs); | 241 | exception_exit(prev_state); |
237 | } | 242 | } |
238 | 243 | ||
239 | dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code) | 244 | dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code) |
@@ -241,7 +246,7 @@ dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code) | |||
241 | static const char str[] = "double fault"; | 246 | static const char str[] = "double fault"; |
242 | struct task_struct *tsk = current; | 247 | struct task_struct *tsk = current; |
243 | 248 | ||
244 | exception_enter(regs); | 249 | exception_enter(); |
245 | /* Return not checked because double check cannot be ignored */ | 250 | /* Return not checked because double check cannot be ignored */ |
246 | notify_die(DIE_TRAP, str, regs, error_code, X86_TRAP_DF, SIGSEGV); | 251 | notify_die(DIE_TRAP, str, regs, error_code, X86_TRAP_DF, SIGSEGV); |
247 | 252 | ||
@@ -261,8 +266,9 @@ dotraplinkage void __kprobes | |||
261 | do_general_protection(struct pt_regs *regs, long error_code) | 266 | do_general_protection(struct pt_regs *regs, long error_code) |
262 | { | 267 | { |
263 | struct task_struct *tsk; | 268 | struct task_struct *tsk; |
269 | enum ctx_state prev_state; | ||
264 | 270 | ||
265 | exception_enter(regs); | 271 | prev_state = exception_enter(); |
266 | conditional_sti(regs); | 272 | conditional_sti(regs); |
267 | 273 | ||
268 | #ifdef CONFIG_X86_32 | 274 | #ifdef CONFIG_X86_32 |
@@ -300,12 +306,14 @@ do_general_protection(struct pt_regs *regs, long error_code) | |||
300 | 306 | ||
301 | force_sig(SIGSEGV, tsk); | 307 | force_sig(SIGSEGV, tsk); |
302 | exit: | 308 | exit: |
303 | exception_exit(regs); | 309 | exception_exit(prev_state); |
304 | } | 310 | } |
305 | 311 | ||
306 | /* May run on IST stack. */ | 312 | /* May run on IST stack. */ |
307 | dotraplinkage void __kprobes notrace do_int3(struct pt_regs *regs, long error_code) | 313 | dotraplinkage void __kprobes notrace do_int3(struct pt_regs *regs, long error_code) |
308 | { | 314 | { |
315 | enum ctx_state prev_state; | ||
316 | |||
309 | #ifdef CONFIG_DYNAMIC_FTRACE | 317 | #ifdef CONFIG_DYNAMIC_FTRACE |
310 | /* | 318 | /* |
311 | * ftrace must be first, everything else may cause a recursive crash. | 319 | * ftrace must be first, everything else may cause a recursive crash. |
@@ -315,7 +323,7 @@ dotraplinkage void __kprobes notrace do_int3(struct pt_regs *regs, long error_co | |||
315 | ftrace_int3_handler(regs)) | 323 | ftrace_int3_handler(regs)) |
316 | return; | 324 | return; |
317 | #endif | 325 | #endif |
318 | exception_enter(regs); | 326 | prev_state = exception_enter(); |
319 | #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP | 327 | #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP |
320 | if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP, | 328 | if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP, |
321 | SIGTRAP) == NOTIFY_STOP) | 329 | SIGTRAP) == NOTIFY_STOP) |
@@ -336,7 +344,7 @@ dotraplinkage void __kprobes notrace do_int3(struct pt_regs *regs, long error_co | |||
336 | preempt_conditional_cli(regs); | 344 | preempt_conditional_cli(regs); |
337 | debug_stack_usage_dec(); | 345 | debug_stack_usage_dec(); |
338 | exit: | 346 | exit: |
339 | exception_exit(regs); | 347 | exception_exit(prev_state); |
340 | } | 348 | } |
341 | 349 | ||
342 | #ifdef CONFIG_X86_64 | 350 | #ifdef CONFIG_X86_64 |
@@ -393,11 +401,12 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) | |||
393 | dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) | 401 | dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) |
394 | { | 402 | { |
395 | struct task_struct *tsk = current; | 403 | struct task_struct *tsk = current; |
404 | enum ctx_state prev_state; | ||
396 | int user_icebp = 0; | 405 | int user_icebp = 0; |
397 | unsigned long dr6; | 406 | unsigned long dr6; |
398 | int si_code; | 407 | int si_code; |
399 | 408 | ||
400 | exception_enter(regs); | 409 | prev_state = exception_enter(); |
401 | 410 | ||
402 | get_debugreg(dr6, 6); | 411 | get_debugreg(dr6, 6); |
403 | 412 | ||
@@ -467,7 +476,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code) | |||
467 | debug_stack_usage_dec(); | 476 | debug_stack_usage_dec(); |
468 | 477 | ||
469 | exit: | 478 | exit: |
470 | exception_exit(regs); | 479 | exception_exit(prev_state); |
471 | } | 480 | } |
472 | 481 | ||
473 | /* | 482 | /* |
@@ -561,17 +570,21 @@ void math_error(struct pt_regs *regs, int error_code, int trapnr) | |||
561 | 570 | ||
562 | dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code) | 571 | dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code) |
563 | { | 572 | { |
564 | exception_enter(regs); | 573 | enum ctx_state prev_state; |
574 | |||
575 | prev_state = exception_enter(); | ||
565 | math_error(regs, error_code, X86_TRAP_MF); | 576 | math_error(regs, error_code, X86_TRAP_MF); |
566 | exception_exit(regs); | 577 | exception_exit(prev_state); |
567 | } | 578 | } |
568 | 579 | ||
569 | dotraplinkage void | 580 | dotraplinkage void |
570 | do_simd_coprocessor_error(struct pt_regs *regs, long error_code) | 581 | do_simd_coprocessor_error(struct pt_regs *regs, long error_code) |
571 | { | 582 | { |
572 | exception_enter(regs); | 583 | enum ctx_state prev_state; |
584 | |||
585 | prev_state = exception_enter(); | ||
573 | math_error(regs, error_code, X86_TRAP_XF); | 586 | math_error(regs, error_code, X86_TRAP_XF); |
574 | exception_exit(regs); | 587 | exception_exit(prev_state); |
575 | } | 588 | } |
576 | 589 | ||
577 | dotraplinkage void | 590 | dotraplinkage void |
@@ -639,7 +652,9 @@ EXPORT_SYMBOL_GPL(math_state_restore); | |||
639 | dotraplinkage void __kprobes | 652 | dotraplinkage void __kprobes |
640 | do_device_not_available(struct pt_regs *regs, long error_code) | 653 | do_device_not_available(struct pt_regs *regs, long error_code) |
641 | { | 654 | { |
642 | exception_enter(regs); | 655 | enum ctx_state prev_state; |
656 | |||
657 | prev_state = exception_enter(); | ||
643 | BUG_ON(use_eager_fpu()); | 658 | BUG_ON(use_eager_fpu()); |
644 | 659 | ||
645 | #ifdef CONFIG_MATH_EMULATION | 660 | #ifdef CONFIG_MATH_EMULATION |
@@ -650,7 +665,7 @@ do_device_not_available(struct pt_regs *regs, long error_code) | |||
650 | 665 | ||
651 | info.regs = regs; | 666 | info.regs = regs; |
652 | math_emulate(&info); | 667 | math_emulate(&info); |
653 | exception_exit(regs); | 668 | exception_exit(prev_state); |
654 | return; | 669 | return; |
655 | } | 670 | } |
656 | #endif | 671 | #endif |
@@ -658,15 +673,16 @@ do_device_not_available(struct pt_regs *regs, long error_code) | |||
658 | #ifdef CONFIG_X86_32 | 673 | #ifdef CONFIG_X86_32 |
659 | conditional_sti(regs); | 674 | conditional_sti(regs); |
660 | #endif | 675 | #endif |
661 | exception_exit(regs); | 676 | exception_exit(prev_state); |
662 | } | 677 | } |
663 | 678 | ||
664 | #ifdef CONFIG_X86_32 | 679 | #ifdef CONFIG_X86_32 |
665 | dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code) | 680 | dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code) |
666 | { | 681 | { |
667 | siginfo_t info; | 682 | siginfo_t info; |
683 | enum ctx_state prev_state; | ||
668 | 684 | ||
669 | exception_enter(regs); | 685 | prev_state = exception_enter(); |
670 | local_irq_enable(); | 686 | local_irq_enable(); |
671 | 687 | ||
672 | info.si_signo = SIGILL; | 688 | info.si_signo = SIGILL; |
@@ -678,7 +694,7 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code) | |||
678 | do_trap(X86_TRAP_IRET, SIGILL, "iret exception", regs, error_code, | 694 | do_trap(X86_TRAP_IRET, SIGILL, "iret exception", regs, error_code, |
679 | &info); | 695 | &info); |
680 | } | 696 | } |
681 | exception_exit(regs); | 697 | exception_exit(prev_state); |
682 | } | 698 | } |
683 | #endif | 699 | #endif |
684 | 700 | ||
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c index 0ba4cfb4f412..2ed845928b5f 100644 --- a/arch/x86/kernel/uprobes.c +++ b/arch/x86/kernel/uprobes.c | |||
@@ -697,3 +697,32 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) | |||
697 | send_sig(SIGTRAP, current, 0); | 697 | send_sig(SIGTRAP, current, 0); |
698 | return ret; | 698 | return ret; |
699 | } | 699 | } |
700 | |||
701 | unsigned long | ||
702 | arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs) | ||
703 | { | ||
704 | int rasize, ncopied; | ||
705 | unsigned long orig_ret_vaddr = 0; /* clear high bits for 32-bit apps */ | ||
706 | |||
707 | rasize = is_ia32_task() ? 4 : 8; | ||
708 | ncopied = copy_from_user(&orig_ret_vaddr, (void __user *)regs->sp, rasize); | ||
709 | if (unlikely(ncopied)) | ||
710 | return -1; | ||
711 | |||
712 | /* check whether address has been already hijacked */ | ||
713 | if (orig_ret_vaddr == trampoline_vaddr) | ||
714 | return orig_ret_vaddr; | ||
715 | |||
716 | ncopied = copy_to_user((void __user *)regs->sp, &trampoline_vaddr, rasize); | ||
717 | if (likely(!ncopied)) | ||
718 | return orig_ret_vaddr; | ||
719 | |||
720 | if (ncopied != rasize) { | ||
721 | pr_err("uprobe: return address clobbered: pid=%d, %%sp=%#lx, " | ||
722 | "%%ip=%#lx\n", current->pid, regs->sp, regs->ip); | ||
723 | |||
724 | force_sig_info(SIGSEGV, SEND_SIG_FORCED, current); | ||
725 | } | ||
726 | |||
727 | return -1; | ||
728 | } | ||
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 1cbd89ca5569..7114c63f047d 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -1334,6 +1334,7 @@ __init void lguest_init(void) | |||
1334 | pv_mmu_ops.read_cr3 = lguest_read_cr3; | 1334 | pv_mmu_ops.read_cr3 = lguest_read_cr3; |
1335 | pv_mmu_ops.lazy_mode.enter = paravirt_enter_lazy_mmu; | 1335 | pv_mmu_ops.lazy_mode.enter = paravirt_enter_lazy_mmu; |
1336 | pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mmu_mode; | 1336 | pv_mmu_ops.lazy_mode.leave = lguest_leave_lazy_mmu_mode; |
1337 | pv_mmu_ops.lazy_mode.flush = paravirt_flush_lazy_mmu; | ||
1337 | pv_mmu_ops.pte_update = lguest_pte_update; | 1338 | pv_mmu_ops.pte_update = lguest_pte_update; |
1338 | pv_mmu_ops.pte_update_defer = lguest_pte_update; | 1339 | pv_mmu_ops.pte_update_defer = lguest_pte_update; |
1339 | 1340 | ||
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 2b97525246d4..022a9a0a3c63 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
@@ -13,12 +13,12 @@ | |||
13 | #include <linux/perf_event.h> /* perf_sw_event */ | 13 | #include <linux/perf_event.h> /* perf_sw_event */ |
14 | #include <linux/hugetlb.h> /* hstate_index_to_shift */ | 14 | #include <linux/hugetlb.h> /* hstate_index_to_shift */ |
15 | #include <linux/prefetch.h> /* prefetchw */ | 15 | #include <linux/prefetch.h> /* prefetchw */ |
16 | #include <linux/context_tracking.h> /* exception_enter(), ... */ | ||
16 | 17 | ||
17 | #include <asm/traps.h> /* dotraplinkage, ... */ | 18 | #include <asm/traps.h> /* dotraplinkage, ... */ |
18 | #include <asm/pgalloc.h> /* pgd_*(), ... */ | 19 | #include <asm/pgalloc.h> /* pgd_*(), ... */ |
19 | #include <asm/kmemcheck.h> /* kmemcheck_*(), ... */ | 20 | #include <asm/kmemcheck.h> /* kmemcheck_*(), ... */ |
20 | #include <asm/fixmap.h> /* VSYSCALL_START */ | 21 | #include <asm/fixmap.h> /* VSYSCALL_START */ |
21 | #include <asm/context_tracking.h> /* exception_enter(), ... */ | ||
22 | 22 | ||
23 | /* | 23 | /* |
24 | * Page fault error code bits: | 24 | * Page fault error code bits: |
@@ -378,10 +378,12 @@ static noinline __kprobes int vmalloc_fault(unsigned long address) | |||
378 | if (pgd_none(*pgd_ref)) | 378 | if (pgd_none(*pgd_ref)) |
379 | return -1; | 379 | return -1; |
380 | 380 | ||
381 | if (pgd_none(*pgd)) | 381 | if (pgd_none(*pgd)) { |
382 | set_pgd(pgd, *pgd_ref); | 382 | set_pgd(pgd, *pgd_ref); |
383 | else | 383 | arch_flush_lazy_mmu_mode(); |
384 | } else { | ||
384 | BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref)); | 385 | BUG_ON(pgd_page_vaddr(*pgd) != pgd_page_vaddr(*pgd_ref)); |
386 | } | ||
385 | 387 | ||
386 | /* | 388 | /* |
387 | * Below here mismatches are bugs because these lower tables | 389 | * Below here mismatches are bugs because these lower tables |
@@ -1222,7 +1224,9 @@ good_area: | |||
1222 | dotraplinkage void __kprobes | 1224 | dotraplinkage void __kprobes |
1223 | do_page_fault(struct pt_regs *regs, unsigned long error_code) | 1225 | do_page_fault(struct pt_regs *regs, unsigned long error_code) |
1224 | { | 1226 | { |
1225 | exception_enter(regs); | 1227 | enum ctx_state prev_state; |
1228 | |||
1229 | prev_state = exception_enter(); | ||
1226 | __do_page_fault(regs, error_code); | 1230 | __do_page_fault(regs, error_code); |
1227 | exception_exit(regs); | 1231 | exception_exit(prev_state); |
1228 | } | 1232 | } |
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c index 6f31ee56c008..252b8f5489ba 100644 --- a/arch/x86/mm/highmem_32.c +++ b/arch/x86/mm/highmem_32.c | |||
@@ -137,5 +137,4 @@ void __init set_highmem_pages_init(void) | |||
137 | add_highpages_with_active_regions(nid, zone_start_pfn, | 137 | add_highpages_with_active_regions(nid, zone_start_pfn, |
138 | zone_end_pfn); | 138 | zone_end_pfn); |
139 | } | 139 | } |
140 | totalram_pages += totalhigh_pages; | ||
141 | } | 140 | } |
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index 59b7fc453277..fdc5dca14fb3 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c | |||
@@ -515,11 +515,8 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) | |||
515 | printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10); | 515 | printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10); |
516 | 516 | ||
517 | for (; addr < end; addr += PAGE_SIZE) { | 517 | for (; addr < end; addr += PAGE_SIZE) { |
518 | ClearPageReserved(virt_to_page(addr)); | ||
519 | init_page_count(virt_to_page(addr)); | ||
520 | memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); | 518 | memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE); |
521 | free_page(addr); | 519 | free_reserved_page(virt_to_page(addr)); |
522 | totalram_pages++; | ||
523 | } | 520 | } |
524 | #endif | 521 | #endif |
525 | } | 522 | } |
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index 2d19001151d5..3ac7e319918d 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c | |||
@@ -427,14 +427,6 @@ static void __init permanent_kmaps_init(pgd_t *pgd_base) | |||
427 | pkmap_page_table = pte; | 427 | pkmap_page_table = pte; |
428 | } | 428 | } |
429 | 429 | ||
430 | static void __init add_one_highpage_init(struct page *page) | ||
431 | { | ||
432 | ClearPageReserved(page); | ||
433 | init_page_count(page); | ||
434 | __free_page(page); | ||
435 | totalhigh_pages++; | ||
436 | } | ||
437 | |||
438 | void __init add_highpages_with_active_regions(int nid, | 430 | void __init add_highpages_with_active_regions(int nid, |
439 | unsigned long start_pfn, unsigned long end_pfn) | 431 | unsigned long start_pfn, unsigned long end_pfn) |
440 | { | 432 | { |
@@ -448,7 +440,7 @@ void __init add_highpages_with_active_regions(int nid, | |||
448 | start_pfn, end_pfn); | 440 | start_pfn, end_pfn); |
449 | for ( ; pfn < e_pfn; pfn++) | 441 | for ( ; pfn < e_pfn; pfn++) |
450 | if (pfn_valid(pfn)) | 442 | if (pfn_valid(pfn)) |
451 | add_one_highpage_init(pfn_to_page(pfn)); | 443 | free_highmem_page(pfn_to_page(pfn)); |
452 | } | 444 | } |
453 | } | 445 | } |
454 | #else | 446 | #else |
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 474e28f10815..71ff55a1b287 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -1011,11 +1011,8 @@ remove_pagetable(unsigned long start, unsigned long end, bool direct) | |||
1011 | flush_tlb_all(); | 1011 | flush_tlb_all(); |
1012 | } | 1012 | } |
1013 | 1013 | ||
1014 | void __ref vmemmap_free(struct page *memmap, unsigned long nr_pages) | 1014 | void __ref vmemmap_free(unsigned long start, unsigned long end) |
1015 | { | 1015 | { |
1016 | unsigned long start = (unsigned long)memmap; | ||
1017 | unsigned long end = (unsigned long)(memmap + nr_pages); | ||
1018 | |||
1019 | remove_pagetable(start, end, false); | 1016 | remove_pagetable(start, end, false); |
1020 | } | 1017 | } |
1021 | 1018 | ||
@@ -1067,10 +1064,9 @@ void __init mem_init(void) | |||
1067 | 1064 | ||
1068 | /* clear_bss() already clear the empty_zero_page */ | 1065 | /* clear_bss() already clear the empty_zero_page */ |
1069 | 1066 | ||
1070 | reservedpages = 0; | ||
1071 | |||
1072 | /* this will put all low memory onto the freelists */ | ||
1073 | register_page_bootmem_info(); | 1067 | register_page_bootmem_info(); |
1068 | |||
1069 | /* this will put all memory onto the freelists */ | ||
1074 | totalram_pages = free_all_bootmem(); | 1070 | totalram_pages = free_all_bootmem(); |
1075 | 1071 | ||
1076 | absent_pages = absent_pages_in_range(0, max_pfn); | 1072 | absent_pages = absent_pages_in_range(0, max_pfn); |
@@ -1285,18 +1281,17 @@ static long __meminitdata addr_start, addr_end; | |||
1285 | static void __meminitdata *p_start, *p_end; | 1281 | static void __meminitdata *p_start, *p_end; |
1286 | static int __meminitdata node_start; | 1282 | static int __meminitdata node_start; |
1287 | 1283 | ||
1288 | int __meminit | 1284 | static int __meminit vmemmap_populate_hugepages(unsigned long start, |
1289 | vmemmap_populate(struct page *start_page, unsigned long size, int node) | 1285 | unsigned long end, int node) |
1290 | { | 1286 | { |
1291 | unsigned long addr = (unsigned long)start_page; | 1287 | unsigned long addr; |
1292 | unsigned long end = (unsigned long)(start_page + size); | ||
1293 | unsigned long next; | 1288 | unsigned long next; |
1294 | pgd_t *pgd; | 1289 | pgd_t *pgd; |
1295 | pud_t *pud; | 1290 | pud_t *pud; |
1296 | pmd_t *pmd; | 1291 | pmd_t *pmd; |
1297 | 1292 | ||
1298 | for (; addr < end; addr = next) { | 1293 | for (addr = start; addr < end; addr = next) { |
1299 | void *p = NULL; | 1294 | next = pmd_addr_end(addr, end); |
1300 | 1295 | ||
1301 | pgd = vmemmap_pgd_populate(addr, node); | 1296 | pgd = vmemmap_pgd_populate(addr, node); |
1302 | if (!pgd) | 1297 | if (!pgd) |
@@ -1306,31 +1301,14 @@ vmemmap_populate(struct page *start_page, unsigned long size, int node) | |||
1306 | if (!pud) | 1301 | if (!pud) |
1307 | return -ENOMEM; | 1302 | return -ENOMEM; |
1308 | 1303 | ||
1309 | if (!cpu_has_pse) { | 1304 | pmd = pmd_offset(pud, addr); |
1310 | next = (addr + PAGE_SIZE) & PAGE_MASK; | 1305 | if (pmd_none(*pmd)) { |
1311 | pmd = vmemmap_pmd_populate(pud, addr, node); | 1306 | void *p; |
1312 | |||
1313 | if (!pmd) | ||
1314 | return -ENOMEM; | ||
1315 | |||
1316 | p = vmemmap_pte_populate(pmd, addr, node); | ||
1317 | 1307 | ||
1318 | if (!p) | 1308 | p = vmemmap_alloc_block_buf(PMD_SIZE, node); |
1319 | return -ENOMEM; | 1309 | if (p) { |
1320 | |||
1321 | addr_end = addr + PAGE_SIZE; | ||
1322 | p_end = p + PAGE_SIZE; | ||
1323 | } else { | ||
1324 | next = pmd_addr_end(addr, end); | ||
1325 | |||
1326 | pmd = pmd_offset(pud, addr); | ||
1327 | if (pmd_none(*pmd)) { | ||
1328 | pte_t entry; | 1310 | pte_t entry; |
1329 | 1311 | ||
1330 | p = vmemmap_alloc_block_buf(PMD_SIZE, node); | ||
1331 | if (!p) | ||
1332 | return -ENOMEM; | ||
1333 | |||
1334 | entry = pfn_pte(__pa(p) >> PAGE_SHIFT, | 1312 | entry = pfn_pte(__pa(p) >> PAGE_SHIFT, |
1335 | PAGE_KERNEL_LARGE); | 1313 | PAGE_KERNEL_LARGE); |
1336 | set_pmd(pmd, __pmd(pte_val(entry))); | 1314 | set_pmd(pmd, __pmd(pte_val(entry))); |
@@ -1347,15 +1325,32 @@ vmemmap_populate(struct page *start_page, unsigned long size, int node) | |||
1347 | 1325 | ||
1348 | addr_end = addr + PMD_SIZE; | 1326 | addr_end = addr + PMD_SIZE; |
1349 | p_end = p + PMD_SIZE; | 1327 | p_end = p + PMD_SIZE; |
1350 | } else | 1328 | continue; |
1351 | vmemmap_verify((pte_t *)pmd, node, addr, next); | 1329 | } |
1330 | } else if (pmd_large(*pmd)) { | ||
1331 | vmemmap_verify((pte_t *)pmd, node, addr, next); | ||
1332 | continue; | ||
1352 | } | 1333 | } |
1353 | 1334 | pr_warn_once("vmemmap: falling back to regular page backing\n"); | |
1335 | if (vmemmap_populate_basepages(addr, next, node)) | ||
1336 | return -ENOMEM; | ||
1354 | } | 1337 | } |
1355 | sync_global_pgds((unsigned long)start_page, end - 1); | ||
1356 | return 0; | 1338 | return 0; |
1357 | } | 1339 | } |
1358 | 1340 | ||
1341 | int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node) | ||
1342 | { | ||
1343 | int err; | ||
1344 | |||
1345 | if (cpu_has_pse) | ||
1346 | err = vmemmap_populate_hugepages(start, end, node); | ||
1347 | else | ||
1348 | err = vmemmap_populate_basepages(start, end, node); | ||
1349 | if (!err) | ||
1350 | sync_global_pgds(start, end - 1); | ||
1351 | return err; | ||
1352 | } | ||
1353 | |||
1359 | #if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) && defined(CONFIG_HAVE_BOOTMEM_INFO_NODE) | 1354 | #if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) && defined(CONFIG_HAVE_BOOTMEM_INFO_NODE) |
1360 | void register_page_bootmem_memmap(unsigned long section_nr, | 1355 | void register_page_bootmem_memmap(unsigned long section_nr, |
1361 | struct page *start_page, unsigned long size) | 1356 | struct page *start_page, unsigned long size) |
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index 78fe3f1ac49f..9a1e6583910c 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c | |||
@@ -282,12 +282,7 @@ void iounmap(volatile void __iomem *addr) | |||
282 | in parallel. Reuse of the virtual address is prevented by | 282 | in parallel. Reuse of the virtual address is prevented by |
283 | leaving it in the global lists until we're done with it. | 283 | leaving it in the global lists until we're done with it. |
284 | cpa takes care of the direct mappings. */ | 284 | cpa takes care of the direct mappings. */ |
285 | read_lock(&vmlist_lock); | 285 | p = find_vm_area((void __force *)addr); |
286 | for (p = vmlist; p; p = p->next) { | ||
287 | if (p->addr == (void __force *)addr) | ||
288 | break; | ||
289 | } | ||
290 | read_unlock(&vmlist_lock); | ||
291 | 286 | ||
292 | if (!p) { | 287 | if (!p) { |
293 | printk(KERN_ERR "iounmap: bad address %p\n", addr); | 288 | printk(KERN_ERR "iounmap: bad address %p\n", addr); |
diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c index 72fe01e9e414..a71c4e207679 100644 --- a/arch/x86/mm/numa.c +++ b/arch/x86/mm/numa.c | |||
@@ -114,14 +114,11 @@ void numa_clear_node(int cpu) | |||
114 | */ | 114 | */ |
115 | void __init setup_node_to_cpumask_map(void) | 115 | void __init setup_node_to_cpumask_map(void) |
116 | { | 116 | { |
117 | unsigned int node, num = 0; | 117 | unsigned int node; |
118 | 118 | ||
119 | /* setup nr_node_ids if not done yet */ | 119 | /* setup nr_node_ids if not done yet */ |
120 | if (nr_node_ids == MAX_NUMNODES) { | 120 | if (nr_node_ids == MAX_NUMNODES) |
121 | for_each_node_mask(node, node_possible_map) | 121 | setup_nr_node_ids(); |
122 | num = node; | ||
123 | nr_node_ids = num + 1; | ||
124 | } | ||
125 | 122 | ||
126 | /* allocate the map */ | 123 | /* allocate the map */ |
127 | for (node = 0; node < nr_node_ids; node++) | 124 | for (node = 0; node < nr_node_ids; node++) |
diff --git a/arch/x86/mm/pageattr-test.c b/arch/x86/mm/pageattr-test.c index b0086567271c..d0b1773d9d2e 100644 --- a/arch/x86/mm/pageattr-test.c +++ b/arch/x86/mm/pageattr-test.c | |||
@@ -68,7 +68,7 @@ static int print_split(struct split_state *s) | |||
68 | s->gpg++; | 68 | s->gpg++; |
69 | i += GPS/PAGE_SIZE; | 69 | i += GPS/PAGE_SIZE; |
70 | } else if (level == PG_LEVEL_2M) { | 70 | } else if (level == PG_LEVEL_2M) { |
71 | if (!(pte_val(*pte) & _PAGE_PSE)) { | 71 | if ((pte_val(*pte) & _PAGE_PRESENT) && !(pte_val(*pte) & _PAGE_PSE)) { |
72 | printk(KERN_ERR | 72 | printk(KERN_ERR |
73 | "%lx level %d but not PSE %Lx\n", | 73 | "%lx level %d but not PSE %Lx\n", |
74 | addr, level, (u64)pte_val(*pte)); | 74 | addr, level, (u64)pte_val(*pte)); |
@@ -130,13 +130,12 @@ static int pageattr_test(void) | |||
130 | } | 130 | } |
131 | 131 | ||
132 | failed += print_split(&sa); | 132 | failed += print_split(&sa); |
133 | srandom32(100); | ||
134 | 133 | ||
135 | for (i = 0; i < NTEST; i++) { | 134 | for (i = 0; i < NTEST; i++) { |
136 | unsigned long pfn = random32() % max_pfn_mapped; | 135 | unsigned long pfn = prandom_u32() % max_pfn_mapped; |
137 | 136 | ||
138 | addr[i] = (unsigned long)__va(pfn << PAGE_SHIFT); | 137 | addr[i] = (unsigned long)__va(pfn << PAGE_SHIFT); |
139 | len[i] = random32() % 100; | 138 | len[i] = prandom_u32() % 100; |
140 | len[i] = min_t(unsigned long, len[i], max_pfn_mapped - pfn - 1); | 139 | len[i] = min_t(unsigned long, len[i], max_pfn_mapped - pfn - 1); |
141 | 140 | ||
142 | if (len[i] == 0) | 141 | if (len[i] == 0) |
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 091934e1d0d9..fb4e73ec24d8 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
@@ -467,7 +467,7 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, | |||
467 | * We are safe now. Check whether the new pgprot is the same: | 467 | * We are safe now. Check whether the new pgprot is the same: |
468 | */ | 468 | */ |
469 | old_pte = *kpte; | 469 | old_pte = *kpte; |
470 | old_prot = new_prot = req_prot = pte_pgprot(old_pte); | 470 | old_prot = req_prot = pte_pgprot(old_pte); |
471 | 471 | ||
472 | pgprot_val(req_prot) &= ~pgprot_val(cpa->mask_clr); | 472 | pgprot_val(req_prot) &= ~pgprot_val(cpa->mask_clr); |
473 | pgprot_val(req_prot) |= pgprot_val(cpa->mask_set); | 473 | pgprot_val(req_prot) |= pgprot_val(cpa->mask_set); |
@@ -478,12 +478,12 @@ try_preserve_large_page(pte_t *kpte, unsigned long address, | |||
478 | * a non present pmd. The canon_pgprot will clear _PAGE_GLOBAL | 478 | * a non present pmd. The canon_pgprot will clear _PAGE_GLOBAL |
479 | * for the ancient hardware that doesn't support it. | 479 | * for the ancient hardware that doesn't support it. |
480 | */ | 480 | */ |
481 | if (pgprot_val(new_prot) & _PAGE_PRESENT) | 481 | if (pgprot_val(req_prot) & _PAGE_PRESENT) |
482 | pgprot_val(new_prot) |= _PAGE_PSE | _PAGE_GLOBAL; | 482 | pgprot_val(req_prot) |= _PAGE_PSE | _PAGE_GLOBAL; |
483 | else | 483 | else |
484 | pgprot_val(new_prot) &= ~(_PAGE_PSE | _PAGE_GLOBAL); | 484 | pgprot_val(req_prot) &= ~(_PAGE_PSE | _PAGE_GLOBAL); |
485 | 485 | ||
486 | new_prot = canon_pgprot(new_prot); | 486 | req_prot = canon_pgprot(req_prot); |
487 | 487 | ||
488 | /* | 488 | /* |
489 | * old_pte points to the large page base address. So we need | 489 | * old_pte points to the large page base address. So we need |
@@ -1413,6 +1413,8 @@ void kernel_map_pages(struct page *page, int numpages, int enable) | |||
1413 | * but that can deadlock->flush only current cpu: | 1413 | * but that can deadlock->flush only current cpu: |
1414 | */ | 1414 | */ |
1415 | __flush_tlb_all(); | 1415 | __flush_tlb_all(); |
1416 | |||
1417 | arch_flush_lazy_mmu_mode(); | ||
1416 | } | 1418 | } |
1417 | 1419 | ||
1418 | #ifdef CONFIG_HIBERNATION | 1420 | #ifdef CONFIG_HIBERNATION |
diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index 193350b51f90..17fda6a8b3c2 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c | |||
@@ -58,6 +58,13 @@ void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte) | |||
58 | void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) | 58 | void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) |
59 | { | 59 | { |
60 | paravirt_release_pmd(__pa(pmd) >> PAGE_SHIFT); | 60 | paravirt_release_pmd(__pa(pmd) >> PAGE_SHIFT); |
61 | /* | ||
62 | * NOTE! For PAE, any changes to the top page-directory-pointer-table | ||
63 | * entries need a full cr3 reload to flush. | ||
64 | */ | ||
65 | #ifdef CONFIG_X86_PAE | ||
66 | tlb->need_flush_all = 1; | ||
67 | #endif | ||
61 | tlb_remove_page(tlb, virt_to_page(pmd)); | 68 | tlb_remove_page(tlb, virt_to_page(pmd)); |
62 | } | 69 | } |
63 | 70 | ||
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 901177d75ff5..305c68b8d538 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
@@ -6,6 +6,7 @@ | |||
6 | 6 | ||
7 | #include <linux/sched.h> | 7 | #include <linux/sched.h> |
8 | #include <linux/pci.h> | 8 | #include <linux/pci.h> |
9 | #include <linux/pci-acpi.h> | ||
9 | #include <linux/ioport.h> | 10 | #include <linux/ioport.h> |
10 | #include <linux/init.h> | 11 | #include <linux/init.h> |
11 | #include <linux/dmi.h> | 12 | #include <linux/dmi.h> |
@@ -170,6 +171,16 @@ void pcibios_fixup_bus(struct pci_bus *b) | |||
170 | pcibios_fixup_device_resources(dev); | 171 | pcibios_fixup_device_resources(dev); |
171 | } | 172 | } |
172 | 173 | ||
174 | void pcibios_add_bus(struct pci_bus *bus) | ||
175 | { | ||
176 | acpi_pci_add_bus(bus); | ||
177 | } | ||
178 | |||
179 | void pcibios_remove_bus(struct pci_bus *bus) | ||
180 | { | ||
181 | acpi_pci_remove_bus(bus); | ||
182 | } | ||
183 | |||
173 | /* | 184 | /* |
174 | * Only use DMI information to set this if nothing was passed | 185 | * Only use DMI information to set this if nothing was passed |
175 | * on the kernel command line (which was parsed earlier). | 186 | * on the kernel command line (which was parsed earlier). |
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 94e76620460f..4a9be6ddf054 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c | |||
@@ -177,7 +177,7 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
177 | goto error; | 177 | goto error; |
178 | i = 0; | 178 | i = 0; |
179 | list_for_each_entry(msidesc, &dev->msi_list, list) { | 179 | list_for_each_entry(msidesc, &dev->msi_list, list) { |
180 | irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], 0, | 180 | irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], |
181 | (type == PCI_CAP_ID_MSIX) ? | 181 | (type == PCI_CAP_ID_MSIX) ? |
182 | "pcifront-msi-x" : | 182 | "pcifront-msi-x" : |
183 | "pcifront-msi", | 183 | "pcifront-msi", |
@@ -244,7 +244,7 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
244 | dev_dbg(&dev->dev, | 244 | dev_dbg(&dev->dev, |
245 | "xen: msi already bound to pirq=%d\n", pirq); | 245 | "xen: msi already bound to pirq=%d\n", pirq); |
246 | } | 246 | } |
247 | irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq, 0, | 247 | irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq, |
248 | (type == PCI_CAP_ID_MSIX) ? | 248 | (type == PCI_CAP_ID_MSIX) ? |
249 | "msi-x" : "msi", | 249 | "msi-x" : "msi", |
250 | DOMID_SELF); | 250 | DOMID_SELF); |
@@ -326,7 +326,7 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) | |||
326 | } | 326 | } |
327 | 327 | ||
328 | ret = xen_bind_pirq_msi_to_irq(dev, msidesc, | 328 | ret = xen_bind_pirq_msi_to_irq(dev, msidesc, |
329 | map_irq.pirq, map_irq.index, | 329 | map_irq.pirq, |
330 | (type == PCI_CAP_ID_MSIX) ? | 330 | (type == PCI_CAP_ID_MSIX) ? |
331 | "msi-x" : "msi", | 331 | "msi-x" : "msi", |
332 | domid); | 332 | domid); |
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 5f2ecaf3f9d8..e4a86a677ce1 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/io.h> | 41 | #include <linux/io.h> |
42 | #include <linux/reboot.h> | 42 | #include <linux/reboot.h> |
43 | #include <linux/bcd.h> | 43 | #include <linux/bcd.h> |
44 | #include <linux/ucs2_string.h> | ||
44 | 45 | ||
45 | #include <asm/setup.h> | 46 | #include <asm/setup.h> |
46 | #include <asm/efi.h> | 47 | #include <asm/efi.h> |
@@ -51,6 +52,13 @@ | |||
51 | 52 | ||
52 | #define EFI_DEBUG 1 | 53 | #define EFI_DEBUG 1 |
53 | 54 | ||
55 | /* | ||
56 | * There's some additional metadata associated with each | ||
57 | * variable. Intel's reference implementation is 60 bytes - bump that | ||
58 | * to account for potential alignment constraints | ||
59 | */ | ||
60 | #define VAR_METADATA_SIZE 64 | ||
61 | |||
54 | struct efi __read_mostly efi = { | 62 | struct efi __read_mostly efi = { |
55 | .mps = EFI_INVALID_TABLE_ADDR, | 63 | .mps = EFI_INVALID_TABLE_ADDR, |
56 | .acpi = EFI_INVALID_TABLE_ADDR, | 64 | .acpi = EFI_INVALID_TABLE_ADDR, |
@@ -69,6 +77,13 @@ struct efi_memory_map memmap; | |||
69 | static struct efi efi_phys __initdata; | 77 | static struct efi efi_phys __initdata; |
70 | static efi_system_table_t efi_systab __initdata; | 78 | static efi_system_table_t efi_systab __initdata; |
71 | 79 | ||
80 | static u64 efi_var_store_size; | ||
81 | static u64 efi_var_remaining_size; | ||
82 | static u64 efi_var_max_var_size; | ||
83 | static u64 boot_used_size; | ||
84 | static u64 boot_var_size; | ||
85 | static u64 active_size; | ||
86 | |||
72 | unsigned long x86_efi_facility; | 87 | unsigned long x86_efi_facility; |
73 | 88 | ||
74 | /* | 89 | /* |
@@ -98,6 +113,15 @@ static int __init setup_add_efi_memmap(char *arg) | |||
98 | } | 113 | } |
99 | early_param("add_efi_memmap", setup_add_efi_memmap); | 114 | early_param("add_efi_memmap", setup_add_efi_memmap); |
100 | 115 | ||
116 | static bool efi_no_storage_paranoia; | ||
117 | |||
118 | static int __init setup_storage_paranoia(char *arg) | ||
119 | { | ||
120 | efi_no_storage_paranoia = true; | ||
121 | return 0; | ||
122 | } | ||
123 | early_param("efi_no_storage_paranoia", setup_storage_paranoia); | ||
124 | |||
101 | 125 | ||
102 | static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) | 126 | static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) |
103 | { | 127 | { |
@@ -162,8 +186,53 @@ static efi_status_t virt_efi_get_next_variable(unsigned long *name_size, | |||
162 | efi_char16_t *name, | 186 | efi_char16_t *name, |
163 | efi_guid_t *vendor) | 187 | efi_guid_t *vendor) |
164 | { | 188 | { |
165 | return efi_call_virt3(get_next_variable, | 189 | efi_status_t status; |
166 | name_size, name, vendor); | 190 | static bool finished = false; |
191 | static u64 var_size; | ||
192 | |||
193 | status = efi_call_virt3(get_next_variable, | ||
194 | name_size, name, vendor); | ||
195 | |||
196 | if (status == EFI_NOT_FOUND) { | ||
197 | finished = true; | ||
198 | if (var_size < boot_used_size) { | ||
199 | boot_var_size = boot_used_size - var_size; | ||
200 | active_size += boot_var_size; | ||
201 | } else { | ||
202 | printk(KERN_WARNING FW_BUG "efi: Inconsistent initial sizes\n"); | ||
203 | } | ||
204 | } | ||
205 | |||
206 | if (boot_used_size && !finished) { | ||
207 | unsigned long size; | ||
208 | u32 attr; | ||
209 | efi_status_t s; | ||
210 | void *tmp; | ||
211 | |||
212 | s = virt_efi_get_variable(name, vendor, &attr, &size, NULL); | ||
213 | |||
214 | if (s != EFI_BUFFER_TOO_SMALL || !size) | ||
215 | return status; | ||
216 | |||
217 | tmp = kmalloc(size, GFP_ATOMIC); | ||
218 | |||
219 | if (!tmp) | ||
220 | return status; | ||
221 | |||
222 | s = virt_efi_get_variable(name, vendor, &attr, &size, tmp); | ||
223 | |||
224 | if (s == EFI_SUCCESS && (attr & EFI_VARIABLE_NON_VOLATILE)) { | ||
225 | var_size += size; | ||
226 | var_size += ucs2_strsize(name, 1024); | ||
227 | active_size += size; | ||
228 | active_size += VAR_METADATA_SIZE; | ||
229 | active_size += ucs2_strsize(name, 1024); | ||
230 | } | ||
231 | |||
232 | kfree(tmp); | ||
233 | } | ||
234 | |||
235 | return status; | ||
167 | } | 236 | } |
168 | 237 | ||
169 | static efi_status_t virt_efi_set_variable(efi_char16_t *name, | 238 | static efi_status_t virt_efi_set_variable(efi_char16_t *name, |
@@ -172,9 +241,34 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name, | |||
172 | unsigned long data_size, | 241 | unsigned long data_size, |
173 | void *data) | 242 | void *data) |
174 | { | 243 | { |
175 | return efi_call_virt5(set_variable, | 244 | efi_status_t status; |
176 | name, vendor, attr, | 245 | u32 orig_attr = 0; |
177 | data_size, data); | 246 | unsigned long orig_size = 0; |
247 | |||
248 | status = virt_efi_get_variable(name, vendor, &orig_attr, &orig_size, | ||
249 | NULL); | ||
250 | |||
251 | if (status != EFI_BUFFER_TOO_SMALL) | ||
252 | orig_size = 0; | ||
253 | |||
254 | status = efi_call_virt5(set_variable, | ||
255 | name, vendor, attr, | ||
256 | data_size, data); | ||
257 | |||
258 | if (status == EFI_SUCCESS) { | ||
259 | if (orig_size) { | ||
260 | active_size -= orig_size; | ||
261 | active_size -= ucs2_strsize(name, 1024); | ||
262 | active_size -= VAR_METADATA_SIZE; | ||
263 | } | ||
264 | if (data_size) { | ||
265 | active_size += data_size; | ||
266 | active_size += ucs2_strsize(name, 1024); | ||
267 | active_size += VAR_METADATA_SIZE; | ||
268 | } | ||
269 | } | ||
270 | |||
271 | return status; | ||
178 | } | 272 | } |
179 | 273 | ||
180 | static efi_status_t virt_efi_query_variable_info(u32 attr, | 274 | static efi_status_t virt_efi_query_variable_info(u32 attr, |
@@ -682,6 +776,9 @@ void __init efi_init(void) | |||
682 | char vendor[100] = "unknown"; | 776 | char vendor[100] = "unknown"; |
683 | int i = 0; | 777 | int i = 0; |
684 | void *tmp; | 778 | void *tmp; |
779 | struct setup_data *data; | ||
780 | struct efi_var_bootdata *efi_var_data; | ||
781 | u64 pa_data; | ||
685 | 782 | ||
686 | #ifdef CONFIG_X86_32 | 783 | #ifdef CONFIG_X86_32 |
687 | if (boot_params.efi_info.efi_systab_hi || | 784 | if (boot_params.efi_info.efi_systab_hi || |
@@ -699,6 +796,22 @@ void __init efi_init(void) | |||
699 | if (efi_systab_init(efi_phys.systab)) | 796 | if (efi_systab_init(efi_phys.systab)) |
700 | return; | 797 | return; |
701 | 798 | ||
799 | pa_data = boot_params.hdr.setup_data; | ||
800 | while (pa_data) { | ||
801 | data = early_ioremap(pa_data, sizeof(*efi_var_data)); | ||
802 | if (data->type == SETUP_EFI_VARS) { | ||
803 | efi_var_data = (struct efi_var_bootdata *)data; | ||
804 | |||
805 | efi_var_store_size = efi_var_data->store_size; | ||
806 | efi_var_remaining_size = efi_var_data->remaining_size; | ||
807 | efi_var_max_var_size = efi_var_data->max_var_size; | ||
808 | } | ||
809 | pa_data = data->next; | ||
810 | early_iounmap(data, sizeof(*efi_var_data)); | ||
811 | } | ||
812 | |||
813 | boot_used_size = efi_var_store_size - efi_var_remaining_size; | ||
814 | |||
702 | set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility); | 815 | set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility); |
703 | 816 | ||
704 | /* | 817 | /* |
@@ -999,3 +1112,48 @@ u64 efi_mem_attributes(unsigned long phys_addr) | |||
999 | } | 1112 | } |
1000 | return 0; | 1113 | return 0; |
1001 | } | 1114 | } |
1115 | |||
1116 | /* | ||
1117 | * Some firmware has serious problems when using more than 50% of the EFI | ||
1118 | * variable store, i.e. it triggers bugs that can brick machines. Ensure that | ||
1119 | * we never use more than this safe limit. | ||
1120 | * | ||
1121 | * Return EFI_SUCCESS if it is safe to write 'size' bytes to the variable | ||
1122 | * store. | ||
1123 | */ | ||
1124 | efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) | ||
1125 | { | ||
1126 | efi_status_t status; | ||
1127 | u64 storage_size, remaining_size, max_size; | ||
1128 | |||
1129 | status = efi.query_variable_info(attributes, &storage_size, | ||
1130 | &remaining_size, &max_size); | ||
1131 | if (status != EFI_SUCCESS) | ||
1132 | return status; | ||
1133 | |||
1134 | if (!max_size && remaining_size > size) | ||
1135 | printk_once(KERN_ERR FW_BUG "Broken EFI implementation" | ||
1136 | " is returning MaxVariableSize=0\n"); | ||
1137 | /* | ||
1138 | * Some firmware implementations refuse to boot if there's insufficient | ||
1139 | * space in the variable store. We account for that by refusing the | ||
1140 | * write if permitting it would reduce the available space to under | ||
1141 | * 50%. However, some firmware won't reclaim variable space until | ||
1142 | * after the used (not merely the actively used) space drops below | ||
1143 | * a threshold. We can approximate that case with the value calculated | ||
1144 | * above. If both the firmware and our calculations indicate that the | ||
1145 | * available space would drop below 50%, refuse the write. | ||
1146 | */ | ||
1147 | |||
1148 | if (!storage_size || size > remaining_size || | ||
1149 | (max_size && size > max_size)) | ||
1150 | return EFI_OUT_OF_RESOURCES; | ||
1151 | |||
1152 | if (!efi_no_storage_paranoia && | ||
1153 | ((active_size + size + VAR_METADATA_SIZE > storage_size / 2) && | ||
1154 | (remaining_size - size < storage_size / 2))) | ||
1155 | return EFI_OUT_OF_RESOURCES; | ||
1156 | |||
1157 | return EFI_SUCCESS; | ||
1158 | } | ||
1159 | EXPORT_SYMBOL_GPL(efi_query_variable_store); | ||
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index c8e1c7b95c3b..ddbd54a9b845 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
32 | #include <linux/gfp.h> | 32 | #include <linux/gfp.h> |
33 | #include <linux/memblock.h> | 33 | #include <linux/memblock.h> |
34 | #include <linux/edd.h> | ||
34 | 35 | ||
35 | #include <xen/xen.h> | 36 | #include <xen/xen.h> |
36 | #include <xen/events.h> | 37 | #include <xen/events.h> |
@@ -1306,6 +1307,55 @@ static const struct machine_ops xen_machine_ops __initconst = { | |||
1306 | .emergency_restart = xen_emergency_restart, | 1307 | .emergency_restart = xen_emergency_restart, |
1307 | }; | 1308 | }; |
1308 | 1309 | ||
1310 | static void __init xen_boot_params_init_edd(void) | ||
1311 | { | ||
1312 | #if IS_ENABLED(CONFIG_EDD) | ||
1313 | struct xen_platform_op op; | ||
1314 | struct edd_info *edd_info; | ||
1315 | u32 *mbr_signature; | ||
1316 | unsigned nr; | ||
1317 | int ret; | ||
1318 | |||
1319 | edd_info = boot_params.eddbuf; | ||
1320 | mbr_signature = boot_params.edd_mbr_sig_buffer; | ||
1321 | |||
1322 | op.cmd = XENPF_firmware_info; | ||
1323 | |||
1324 | op.u.firmware_info.type = XEN_FW_DISK_INFO; | ||
1325 | for (nr = 0; nr < EDDMAXNR; nr++) { | ||
1326 | struct edd_info *info = edd_info + nr; | ||
1327 | |||
1328 | op.u.firmware_info.index = nr; | ||
1329 | info->params.length = sizeof(info->params); | ||
1330 | set_xen_guest_handle(op.u.firmware_info.u.disk_info.edd_params, | ||
1331 | &info->params); | ||
1332 | ret = HYPERVISOR_dom0_op(&op); | ||
1333 | if (ret) | ||
1334 | break; | ||
1335 | |||
1336 | #define C(x) info->x = op.u.firmware_info.u.disk_info.x | ||
1337 | C(device); | ||
1338 | C(version); | ||
1339 | C(interface_support); | ||
1340 | C(legacy_max_cylinder); | ||
1341 | C(legacy_max_head); | ||
1342 | C(legacy_sectors_per_track); | ||
1343 | #undef C | ||
1344 | } | ||
1345 | boot_params.eddbuf_entries = nr; | ||
1346 | |||
1347 | op.u.firmware_info.type = XEN_FW_DISK_MBR_SIGNATURE; | ||
1348 | for (nr = 0; nr < EDD_MBR_SIG_MAX; nr++) { | ||
1349 | op.u.firmware_info.index = nr; | ||
1350 | ret = HYPERVISOR_dom0_op(&op); | ||
1351 | if (ret) | ||
1352 | break; | ||
1353 | mbr_signature[nr] = op.u.firmware_info.u.disk_mbr_signature.mbr_signature; | ||
1354 | } | ||
1355 | boot_params.edd_mbr_sig_buf_entries = nr; | ||
1356 | #endif | ||
1357 | } | ||
1358 | |||
1309 | /* | 1359 | /* |
1310 | * Set up the GDT and segment registers for -fstack-protector. Until | 1360 | * Set up the GDT and segment registers for -fstack-protector. Until |
1311 | * we do this, we have to be careful not to call any stack-protected | 1361 | * we do this, we have to be careful not to call any stack-protected |
@@ -1508,6 +1558,8 @@ asmlinkage void __init xen_start_kernel(void) | |||
1508 | /* Avoid searching for BIOS MP tables */ | 1558 | /* Avoid searching for BIOS MP tables */ |
1509 | x86_init.mpparse.find_smp_config = x86_init_noop; | 1559 | x86_init.mpparse.find_smp_config = x86_init_noop; |
1510 | x86_init.mpparse.get_smp_config = x86_init_uint_noop; | 1560 | x86_init.mpparse.get_smp_config = x86_init_uint_noop; |
1561 | |||
1562 | xen_boot_params_init_edd(); | ||
1511 | } | 1563 | } |
1512 | #ifdef CONFIG_PCI | 1564 | #ifdef CONFIG_PCI |
1513 | /* PCI BIOS service won't work from a PV guest. */ | 1565 | /* PCI BIOS service won't work from a PV guest. */ |
@@ -1589,8 +1641,11 @@ static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self, | |||
1589 | switch (action) { | 1641 | switch (action) { |
1590 | case CPU_UP_PREPARE: | 1642 | case CPU_UP_PREPARE: |
1591 | xen_vcpu_setup(cpu); | 1643 | xen_vcpu_setup(cpu); |
1592 | if (xen_have_vector_callback) | 1644 | if (xen_have_vector_callback) { |
1593 | xen_init_lock_cpu(cpu); | 1645 | xen_init_lock_cpu(cpu); |
1646 | if (xen_feature(XENFEAT_hvm_safe_pvclock)) | ||
1647 | xen_setup_timer(cpu); | ||
1648 | } | ||
1594 | break; | 1649 | break; |
1595 | default: | 1650 | default: |
1596 | break; | 1651 | break; |
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 6afbb2ca9a0a..e006c18d288a 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -1748,14 +1748,18 @@ static void *m2v(phys_addr_t maddr) | |||
1748 | } | 1748 | } |
1749 | 1749 | ||
1750 | /* Set the page permissions on an identity-mapped pages */ | 1750 | /* Set the page permissions on an identity-mapped pages */ |
1751 | static void set_page_prot(void *addr, pgprot_t prot) | 1751 | static void set_page_prot_flags(void *addr, pgprot_t prot, unsigned long flags) |
1752 | { | 1752 | { |
1753 | unsigned long pfn = __pa(addr) >> PAGE_SHIFT; | 1753 | unsigned long pfn = __pa(addr) >> PAGE_SHIFT; |
1754 | pte_t pte = pfn_pte(pfn, prot); | 1754 | pte_t pte = pfn_pte(pfn, prot); |
1755 | 1755 | ||
1756 | if (HYPERVISOR_update_va_mapping((unsigned long)addr, pte, 0)) | 1756 | if (HYPERVISOR_update_va_mapping((unsigned long)addr, pte, flags)) |
1757 | BUG(); | 1757 | BUG(); |
1758 | } | 1758 | } |
1759 | static void set_page_prot(void *addr, pgprot_t prot) | ||
1760 | { | ||
1761 | return set_page_prot_flags(addr, prot, UVMF_NONE); | ||
1762 | } | ||
1759 | #ifdef CONFIG_X86_32 | 1763 | #ifdef CONFIG_X86_32 |
1760 | static void __init xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn) | 1764 | static void __init xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn) |
1761 | { | 1765 | { |
@@ -1839,12 +1843,12 @@ static void __init check_pt_base(unsigned long *pt_base, unsigned long *pt_end, | |||
1839 | unsigned long addr) | 1843 | unsigned long addr) |
1840 | { | 1844 | { |
1841 | if (*pt_base == PFN_DOWN(__pa(addr))) { | 1845 | if (*pt_base == PFN_DOWN(__pa(addr))) { |
1842 | set_page_prot((void *)addr, PAGE_KERNEL); | 1846 | set_page_prot_flags((void *)addr, PAGE_KERNEL, UVMF_INVLPG); |
1843 | clear_page((void *)addr); | 1847 | clear_page((void *)addr); |
1844 | (*pt_base)++; | 1848 | (*pt_base)++; |
1845 | } | 1849 | } |
1846 | if (*pt_end == PFN_DOWN(__pa(addr))) { | 1850 | if (*pt_end == PFN_DOWN(__pa(addr))) { |
1847 | set_page_prot((void *)addr, PAGE_KERNEL); | 1851 | set_page_prot_flags((void *)addr, PAGE_KERNEL, UVMF_INVLPG); |
1848 | clear_page((void *)addr); | 1852 | clear_page((void *)addr); |
1849 | (*pt_end)--; | 1853 | (*pt_end)--; |
1850 | } | 1854 | } |
@@ -2196,6 +2200,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = { | |||
2196 | .lazy_mode = { | 2200 | .lazy_mode = { |
2197 | .enter = paravirt_enter_lazy_mmu, | 2201 | .enter = paravirt_enter_lazy_mmu, |
2198 | .leave = xen_leave_lazy_mmu, | 2202 | .leave = xen_leave_lazy_mmu, |
2203 | .flush = paravirt_flush_lazy_mmu, | ||
2199 | }, | 2204 | }, |
2200 | 2205 | ||
2201 | .set_fixmap = xen_set_fixmap, | 2206 | .set_fixmap = xen_set_fixmap, |
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 73642e946031..8ff37995d54e 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c | |||
@@ -144,6 +144,13 @@ static int xen_smp_intr_init(unsigned int cpu) | |||
144 | goto fail; | 144 | goto fail; |
145 | per_cpu(xen_callfuncsingle_irq, cpu) = rc; | 145 | per_cpu(xen_callfuncsingle_irq, cpu) = rc; |
146 | 146 | ||
147 | /* | ||
148 | * The IRQ worker on PVHVM goes through the native path and uses the | ||
149 | * IPI mechanism. | ||
150 | */ | ||
151 | if (xen_hvm_domain()) | ||
152 | return 0; | ||
153 | |||
147 | callfunc_name = kasprintf(GFP_KERNEL, "irqwork%d", cpu); | 154 | callfunc_name = kasprintf(GFP_KERNEL, "irqwork%d", cpu); |
148 | rc = bind_ipi_to_irqhandler(XEN_IRQ_WORK_VECTOR, | 155 | rc = bind_ipi_to_irqhandler(XEN_IRQ_WORK_VECTOR, |
149 | cpu, | 156 | cpu, |
@@ -167,6 +174,9 @@ static int xen_smp_intr_init(unsigned int cpu) | |||
167 | if (per_cpu(xen_callfuncsingle_irq, cpu) >= 0) | 174 | if (per_cpu(xen_callfuncsingle_irq, cpu) >= 0) |
168 | unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), | 175 | unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), |
169 | NULL); | 176 | NULL); |
177 | if (xen_hvm_domain()) | ||
178 | return rc; | ||
179 | |||
170 | if (per_cpu(xen_irq_work, cpu) >= 0) | 180 | if (per_cpu(xen_irq_work, cpu) >= 0) |
171 | unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL); | 181 | unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL); |
172 | 182 | ||
@@ -418,7 +428,7 @@ static int xen_cpu_disable(void) | |||
418 | 428 | ||
419 | static void xen_cpu_die(unsigned int cpu) | 429 | static void xen_cpu_die(unsigned int cpu) |
420 | { | 430 | { |
421 | while (HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL)) { | 431 | while (xen_pv_domain() && HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL)) { |
422 | current->state = TASK_UNINTERRUPTIBLE; | 432 | current->state = TASK_UNINTERRUPTIBLE; |
423 | schedule_timeout(HZ/10); | 433 | schedule_timeout(HZ/10); |
424 | } | 434 | } |
@@ -426,7 +436,8 @@ static void xen_cpu_die(unsigned int cpu) | |||
426 | unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu), NULL); | 436 | unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu), NULL); |
427 | unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu), NULL); | 437 | unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu), NULL); |
428 | unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL); | 438 | unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL); |
429 | unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL); | 439 | if (!xen_hvm_domain()) |
440 | unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL); | ||
430 | xen_uninit_lock_cpu(cpu); | 441 | xen_uninit_lock_cpu(cpu); |
431 | xen_teardown_timer(cpu); | 442 | xen_teardown_timer(cpu); |
432 | } | 443 | } |
@@ -657,11 +668,7 @@ static int __cpuinit xen_hvm_cpu_up(unsigned int cpu, struct task_struct *tidle) | |||
657 | 668 | ||
658 | static void xen_hvm_cpu_die(unsigned int cpu) | 669 | static void xen_hvm_cpu_die(unsigned int cpu) |
659 | { | 670 | { |
660 | unbind_from_irqhandler(per_cpu(xen_resched_irq, cpu), NULL); | 671 | xen_cpu_die(cpu); |
661 | unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu), NULL); | ||
662 | unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu), NULL); | ||
663 | unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL); | ||
664 | unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL); | ||
665 | native_cpu_die(cpu); | 672 | native_cpu_die(cpu); |
666 | } | 673 | } |
667 | 674 | ||
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index f7a080ef0354..8b54603ce816 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c | |||
@@ -364,6 +364,16 @@ void __cpuinit xen_init_lock_cpu(int cpu) | |||
364 | int irq; | 364 | int irq; |
365 | const char *name; | 365 | const char *name; |
366 | 366 | ||
367 | WARN(per_cpu(lock_kicker_irq, cpu) > 0, "spinlock on CPU%d exists on IRQ%d!\n", | ||
368 | cpu, per_cpu(lock_kicker_irq, cpu)); | ||
369 | |||
370 | /* | ||
371 | * See git commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23 | ||
372 | * (xen: disable PV spinlocks on HVM) | ||
373 | */ | ||
374 | if (xen_hvm_domain()) | ||
375 | return; | ||
376 | |||
367 | name = kasprintf(GFP_KERNEL, "spinlock%d", cpu); | 377 | name = kasprintf(GFP_KERNEL, "spinlock%d", cpu); |
368 | irq = bind_ipi_to_irqhandler(XEN_SPIN_UNLOCK_VECTOR, | 378 | irq = bind_ipi_to_irqhandler(XEN_SPIN_UNLOCK_VECTOR, |
369 | cpu, | 379 | cpu, |
@@ -382,11 +392,26 @@ void __cpuinit xen_init_lock_cpu(int cpu) | |||
382 | 392 | ||
383 | void xen_uninit_lock_cpu(int cpu) | 393 | void xen_uninit_lock_cpu(int cpu) |
384 | { | 394 | { |
395 | /* | ||
396 | * See git commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23 | ||
397 | * (xen: disable PV spinlocks on HVM) | ||
398 | */ | ||
399 | if (xen_hvm_domain()) | ||
400 | return; | ||
401 | |||
385 | unbind_from_irqhandler(per_cpu(lock_kicker_irq, cpu), NULL); | 402 | unbind_from_irqhandler(per_cpu(lock_kicker_irq, cpu), NULL); |
403 | per_cpu(lock_kicker_irq, cpu) = -1; | ||
386 | } | 404 | } |
387 | 405 | ||
388 | void __init xen_init_spinlocks(void) | 406 | void __init xen_init_spinlocks(void) |
389 | { | 407 | { |
408 | /* | ||
409 | * See git commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23 | ||
410 | * (xen: disable PV spinlocks on HVM) | ||
411 | */ | ||
412 | if (xen_hvm_domain()) | ||
413 | return; | ||
414 | |||
390 | BUILD_BUG_ON(sizeof(struct xen_spinlock) > sizeof(arch_spinlock_t)); | 415 | BUILD_BUG_ON(sizeof(struct xen_spinlock) > sizeof(arch_spinlock_t)); |
391 | 416 | ||
392 | pv_lock_ops.spin_is_locked = xen_spin_is_locked; | 417 | pv_lock_ops.spin_is_locked = xen_spin_is_locked; |
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index 0296a9522501..3d88bfdf9e1c 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c | |||
@@ -377,7 +377,7 @@ static const struct clock_event_device xen_vcpuop_clockevent = { | |||
377 | 377 | ||
378 | static const struct clock_event_device *xen_clockevent = | 378 | static const struct clock_event_device *xen_clockevent = |
379 | &xen_timerop_clockevent; | 379 | &xen_timerop_clockevent; |
380 | static DEFINE_PER_CPU(struct clock_event_device, xen_clock_events); | 380 | static DEFINE_PER_CPU(struct clock_event_device, xen_clock_events) = { .irq = -1 }; |
381 | 381 | ||
382 | static irqreturn_t xen_timer_interrupt(int irq, void *dev_id) | 382 | static irqreturn_t xen_timer_interrupt(int irq, void *dev_id) |
383 | { | 383 | { |
@@ -401,6 +401,9 @@ void xen_setup_timer(int cpu) | |||
401 | struct clock_event_device *evt; | 401 | struct clock_event_device *evt; |
402 | int irq; | 402 | int irq; |
403 | 403 | ||
404 | evt = &per_cpu(xen_clock_events, cpu); | ||
405 | WARN(evt->irq >= 0, "IRQ%d for CPU%d is already allocated\n", evt->irq, cpu); | ||
406 | |||
404 | printk(KERN_INFO "installing Xen timer for CPU %d\n", cpu); | 407 | printk(KERN_INFO "installing Xen timer for CPU %d\n", cpu); |
405 | 408 | ||
406 | name = kasprintf(GFP_KERNEL, "timer%d", cpu); | 409 | name = kasprintf(GFP_KERNEL, "timer%d", cpu); |
@@ -413,7 +416,6 @@ void xen_setup_timer(int cpu) | |||
413 | IRQF_FORCE_RESUME, | 416 | IRQF_FORCE_RESUME, |
414 | name, NULL); | 417 | name, NULL); |
415 | 418 | ||
416 | evt = &per_cpu(xen_clock_events, cpu); | ||
417 | memcpy(evt, xen_clockevent, sizeof(*evt)); | 419 | memcpy(evt, xen_clockevent, sizeof(*evt)); |
418 | 420 | ||
419 | evt->cpumask = cpumask_of(cpu); | 421 | evt->cpumask = cpumask_of(cpu); |
@@ -426,6 +428,7 @@ void xen_teardown_timer(int cpu) | |||
426 | BUG_ON(cpu == 0); | 428 | BUG_ON(cpu == 0); |
427 | evt = &per_cpu(xen_clock_events, cpu); | 429 | evt = &per_cpu(xen_clock_events, cpu); |
428 | unbind_from_irqhandler(evt->irq, NULL); | 430 | unbind_from_irqhandler(evt->irq, NULL); |
431 | evt->irq = -1; | ||
429 | } | 432 | } |
430 | 433 | ||
431 | void xen_setup_cpu_clockevents(void) | 434 | void xen_setup_cpu_clockevents(void) |
@@ -497,7 +500,11 @@ static void xen_hvm_setup_cpu_clockevents(void) | |||
497 | { | 500 | { |
498 | int cpu = smp_processor_id(); | 501 | int cpu = smp_processor_id(); |
499 | xen_setup_runstate_info(cpu); | 502 | xen_setup_runstate_info(cpu); |
500 | xen_setup_timer(cpu); | 503 | /* |
504 | * xen_setup_timer(cpu) - snprintf is bad in atomic context. Hence | ||
505 | * doing it xen_hvm_cpu_notify (which gets called by smp_init during | ||
506 | * early bootup and also during CPU hotplug events). | ||
507 | */ | ||
501 | xen_setup_cpu_clockevents(); | 508 | xen_setup_cpu_clockevents(); |
502 | } | 509 | } |
503 | 510 | ||
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index 7a5156ffebb6..bba125b4bb06 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c | |||
@@ -208,32 +208,17 @@ void __init mem_init(void) | |||
208 | highmemsize >> 10); | 208 | highmemsize >> 10); |
209 | } | 209 | } |
210 | 210 | ||
211 | void | ||
212 | free_reserved_mem(void *start, void *end) | ||
213 | { | ||
214 | for (; start < end; start += PAGE_SIZE) { | ||
215 | ClearPageReserved(virt_to_page(start)); | ||
216 | init_page_count(virt_to_page(start)); | ||
217 | free_page((unsigned long)start); | ||
218 | totalram_pages++; | ||
219 | } | ||
220 | } | ||
221 | |||
222 | #ifdef CONFIG_BLK_DEV_INITRD | 211 | #ifdef CONFIG_BLK_DEV_INITRD |
223 | extern int initrd_is_mapped; | 212 | extern int initrd_is_mapped; |
224 | 213 | ||
225 | void free_initrd_mem(unsigned long start, unsigned long end) | 214 | void free_initrd_mem(unsigned long start, unsigned long end) |
226 | { | 215 | { |
227 | if (initrd_is_mapped) { | 216 | if (initrd_is_mapped) |
228 | free_reserved_mem((void*)start, (void*)end); | 217 | free_reserved_area(start, end, 0, "initrd"); |
229 | printk ("Freeing initrd memory: %ldk freed\n",(end-start)>>10); | ||
230 | } | ||
231 | } | 218 | } |
232 | #endif | 219 | #endif |
233 | 220 | ||
234 | void free_initmem(void) | 221 | void free_initmem(void) |
235 | { | 222 | { |
236 | free_reserved_mem(__init_begin, __init_end); | 223 | free_initmem_default(0); |
237 | printk("Freeing unused kernel memory: %zuk freed\n", | ||
238 | (__init_end - __init_begin) >> 10); | ||
239 | } | 224 | } |