diff options
Diffstat (limited to 'arch')
257 files changed, 4615 insertions, 2208 deletions
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 770f717bd250..79c6e5a24456 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig | |||
@@ -83,22 +83,20 @@ choice | |||
83 | check out the Linux/Alpha FAQ, accessible on the WWW from | 83 | check out the Linux/Alpha FAQ, accessible on the WWW from |
84 | <http://www.alphalinux.org/>. In summary: | 84 | <http://www.alphalinux.org/>. In summary: |
85 | 85 | ||
86 | Alcor/Alpha-XLT AS 600 | 86 | Alcor/Alpha-XLT AS 600, AS 500, XL-300, XL-366 |
87 | Alpha-XL XL-233, XL-266 | 87 | Alpha-XL XL-233, XL-266 |
88 | AlphaBook1 Alpha laptop | 88 | AlphaBook1 Alpha laptop |
89 | Avanti AS 200, AS 205, AS 250, AS 255, AS 300, AS 400 | 89 | Avanti AS 200, AS 205, AS 250, AS 255, AS 300, AS 400 |
90 | Cabriolet AlphaPC64, AlphaPCI64 | 90 | Cabriolet AlphaPC64, AlphaPCI64 |
91 | DP264 DP264 | 91 | DP264 DP264 / DS20 / ES40 / DS10 / DS10L |
92 | EB164 EB164 21164 evaluation board | 92 | EB164 EB164 21164 evaluation board |
93 | EB64+ EB64+ 21064 evaluation board | 93 | EB64+ EB64+ 21064 evaluation board |
94 | EB66 EB66 21066 evaluation board | 94 | EB66 EB66 21066 evaluation board |
95 | EB66+ EB66+ 21066 evaluation board | 95 | EB66+ EB66+ 21066 evaluation board |
96 | Jensen DECpc 150, DEC 2000 model 300, | 96 | Jensen DECpc 150, DEC 2000 models 300, 500 |
97 | DEC 2000 model 500 | ||
98 | LX164 AlphaPC164-LX | 97 | LX164 AlphaPC164-LX |
99 | Lynx AS 2100A | 98 | Lynx AS 2100A |
100 | Miata Personal Workstation 433a, 433au, 500a, | 99 | Miata Personal Workstation 433/500/600 a/au |
101 | 500au, 600a, or 600au | ||
102 | Marvel AlphaServer ES47 / ES80 / GS1280 | 100 | Marvel AlphaServer ES47 / ES80 / GS1280 |
103 | Mikasa AS 1000 | 101 | Mikasa AS 1000 |
104 | Noname AXPpci33, UDB (Multia) | 102 | Noname AXPpci33, UDB (Multia) |
@@ -108,9 +106,9 @@ choice | |||
108 | Ruffian RPX164-2, AlphaPC164-UX, AlphaPC164-BX | 106 | Ruffian RPX164-2, AlphaPC164-UX, AlphaPC164-BX |
109 | SX164 AlphaPC164-SX | 107 | SX164 AlphaPC164-SX |
110 | Sable AS 2000, AS 2100 | 108 | Sable AS 2000, AS 2100 |
111 | Shark DS 20L | 109 | Shark DS 20L |
112 | Takara Takara | 110 | Takara Takara (OEM) |
113 | Titan AlphaServer ES45 / DS25 | 111 | Titan AlphaServer ES45 / DS25 / DS15 |
114 | Wildfire AlphaServer GS 40/80/160/320 | 112 | Wildfire AlphaServer GS 40/80/160/320 |
115 | 113 | ||
116 | If you don't know what to do, choose "generic". | 114 | If you don't know what to do, choose "generic". |
@@ -481,6 +479,15 @@ config ALPHA_BROKEN_IRQ_MASK | |||
481 | depends on ALPHA_GENERIC || ALPHA_PC164 | 479 | depends on ALPHA_GENERIC || ALPHA_PC164 |
482 | default y | 480 | default y |
483 | 481 | ||
482 | config VGA_HOSE | ||
483 | bool | ||
484 | depends on ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL || ALPHA_TSUNAMI | ||
485 | default y | ||
486 | help | ||
487 | Support VGA on an arbitrary hose; needed for several platforms | ||
488 | which always have multiple hoses, and whose consoles support it. | ||
489 | |||
490 | |||
484 | config ALPHA_SRM | 491 | config ALPHA_SRM |
485 | bool "Use SRM as bootloader" if ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_NAUTILUS || ALPHA_NONAME | 492 | bool "Use SRM as bootloader" if ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_NAUTILUS || ALPHA_NONAME |
486 | default y if ALPHA_JENSEN || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_LYNX || ALPHA_NORITAKE || ALPHA_DP264 || ALPHA_RAWHIDE || ALPHA_EIGER || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_MARVEL | 493 | default y if ALPHA_JENSEN || ALPHA_MIKASA || ALPHA_SABLE || ALPHA_LYNX || ALPHA_NORITAKE || ALPHA_DP264 || ALPHA_RAWHIDE || ALPHA_EIGER || ALPHA_WILDFIRE || ALPHA_TITAN || ALPHA_SHARK || ALPHA_MARVEL |
@@ -537,10 +544,14 @@ config HAVE_DEC_LOCK | |||
537 | default y | 544 | default y |
538 | 545 | ||
539 | config NR_CPUS | 546 | config NR_CPUS |
540 | int "Maximum number of CPUs (2-64)" | 547 | int "Maximum number of CPUs (2-32)" |
541 | range 2 64 | 548 | range 2 32 |
542 | depends on SMP | 549 | depends on SMP |
543 | default "64" | 550 | default "32" if ALPHA_GENERIC || ALPHA_MARVEL |
551 | default "4" if !ALPHA_GENERIC && !ALPHA_MARVEL | ||
552 | help | ||
553 | MARVEL support can handle a maximum of 32 CPUs, all the others | ||
554 | with working support have a maximum of 4 CPUs. | ||
544 | 555 | ||
545 | config ARCH_DISCONTIGMEM_ENABLE | 556 | config ARCH_DISCONTIGMEM_ENABLE |
546 | bool "Discontiguous Memory Support (EXPERIMENTAL)" | 557 | bool "Discontiguous Memory Support (EXPERIMENTAL)" |
@@ -644,6 +655,13 @@ source "arch/alpha/oprofile/Kconfig" | |||
644 | 655 | ||
645 | source "arch/alpha/Kconfig.debug" | 656 | source "arch/alpha/Kconfig.debug" |
646 | 657 | ||
658 | # DUMMY_CONSOLE may be defined in drivers/video/console/Kconfig | ||
659 | # but we also need it if VGA_HOSE is set | ||
660 | config DUMMY_CONSOLE | ||
661 | bool | ||
662 | depends on VGA_HOSE | ||
663 | default y | ||
664 | |||
647 | source "security/Kconfig" | 665 | source "security/Kconfig" |
648 | 666 | ||
649 | source "crypto/Kconfig" | 667 | source "crypto/Kconfig" |
diff --git a/arch/alpha/boot/tools/mkbb.c b/arch/alpha/boot/tools/mkbb.c index 23c7190b047c..632a7fd6d7dc 100644 --- a/arch/alpha/boot/tools/mkbb.c +++ b/arch/alpha/boot/tools/mkbb.c | |||
@@ -81,7 +81,7 @@ typedef union __bootblock { | |||
81 | #define bootblock_label __u1.__label | 81 | #define bootblock_label __u1.__label |
82 | #define bootblock_checksum __u2.__checksum | 82 | #define bootblock_checksum __u2.__checksum |
83 | 83 | ||
84 | main(int argc, char ** argv) | 84 | int main(int argc, char ** argv) |
85 | { | 85 | { |
86 | bootblock bootblock_from_disk; | 86 | bootblock bootblock_from_disk; |
87 | bootblock bootloader_image; | 87 | bootblock bootloader_image; |
diff --git a/arch/alpha/kernel/console.c b/arch/alpha/kernel/console.c index f313b34939bb..da711e37fc97 100644 --- a/arch/alpha/kernel/console.c +++ b/arch/alpha/kernel/console.c | |||
@@ -9,16 +9,20 @@ | |||
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/tty.h> | 10 | #include <linux/tty.h> |
11 | #include <linux/console.h> | 11 | #include <linux/console.h> |
12 | #include <linux/vt.h> | ||
12 | #include <asm/vga.h> | 13 | #include <asm/vga.h> |
13 | #include <asm/machvec.h> | 14 | #include <asm/machvec.h> |
14 | 15 | ||
16 | #include "pci_impl.h" | ||
17 | |||
15 | #ifdef CONFIG_VGA_HOSE | 18 | #ifdef CONFIG_VGA_HOSE |
16 | 19 | ||
17 | /* | 20 | struct pci_controller *pci_vga_hose; |
18 | * Externally-visible vga hose bases | 21 | static struct resource alpha_vga = { |
19 | */ | 22 | .name = "alpha-vga+", |
20 | unsigned long __vga_hose_io_base = 0; /* base for default hose */ | 23 | .start = 0x3C0, |
21 | unsigned long __vga_hose_mem_base = 0; /* base for default hose */ | 24 | .end = 0x3DF |
25 | }; | ||
22 | 26 | ||
23 | static struct pci_controller * __init | 27 | static struct pci_controller * __init |
24 | default_vga_hose_select(struct pci_controller *h1, struct pci_controller *h2) | 28 | default_vga_hose_select(struct pci_controller *h1, struct pci_controller *h2) |
@@ -30,36 +34,58 @@ default_vga_hose_select(struct pci_controller *h1, struct pci_controller *h2) | |||
30 | } | 34 | } |
31 | 35 | ||
32 | void __init | 36 | void __init |
33 | set_vga_hose(struct pci_controller *hose) | ||
34 | { | ||
35 | if (hose) { | ||
36 | __vga_hose_io_base = hose->io_space->start; | ||
37 | __vga_hose_mem_base = hose->mem_space->start; | ||
38 | } | ||
39 | } | ||
40 | |||
41 | void __init | ||
42 | locate_and_init_vga(void *(*sel_func)(void *, void *)) | 37 | locate_and_init_vga(void *(*sel_func)(void *, void *)) |
43 | { | 38 | { |
44 | struct pci_controller *hose = NULL; | 39 | struct pci_controller *hose = NULL; |
45 | struct pci_dev *dev = NULL; | 40 | struct pci_dev *dev = NULL; |
46 | 41 | ||
42 | /* Default the select function */ | ||
47 | if (!sel_func) sel_func = (void *)default_vga_hose_select; | 43 | if (!sel_func) sel_func = (void *)default_vga_hose_select; |
48 | 44 | ||
45 | /* Find the console VGA device */ | ||
49 | for(dev=NULL; (dev=pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, dev));) { | 46 | for(dev=NULL; (dev=pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, dev));) { |
50 | if (!hose) hose = dev->sysdata; | 47 | if (!hose) |
51 | else hose = sel_func(hose, dev->sysdata); | 48 | hose = dev->sysdata; |
49 | else | ||
50 | hose = sel_func(hose, dev->sysdata); | ||
52 | } | 51 | } |
53 | 52 | ||
54 | /* Did we already inititialize the correct one? */ | 53 | /* Did we already initialize the correct one? Is there one? */ |
55 | if (conswitchp == &vga_con && | 54 | if (!hose || (conswitchp == &vga_con && pci_vga_hose == hose)) |
56 | __vga_hose_io_base == hose->io_space->start && | ||
57 | __vga_hose_mem_base == hose->mem_space->start) | ||
58 | return; | 55 | return; |
59 | 56 | ||
60 | /* Set the VGA hose and init the new console */ | 57 | /* Create a new VGA ioport resource WRT the hose it is on. */ |
61 | set_vga_hose(hose); | 58 | alpha_vga.start += hose->io_space->start; |
59 | alpha_vga.end += hose->io_space->start; | ||
60 | request_resource(hose->io_space, &alpha_vga); | ||
61 | |||
62 | /* Set the VGA hose and init the new console. */ | ||
63 | pci_vga_hose = hose; | ||
62 | take_over_console(&vga_con, 0, MAX_NR_CONSOLES-1, 1); | 64 | take_over_console(&vga_con, 0, MAX_NR_CONSOLES-1, 1); |
63 | } | 65 | } |
64 | 66 | ||
67 | void __init | ||
68 | find_console_vga_hose(void) | ||
69 | { | ||
70 | u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset); | ||
71 | |||
72 | if (pu64[7] == 3) { /* TERM_TYPE == graphics */ | ||
73 | struct pci_controller *hose; | ||
74 | int h = (pu64[30] >> 24) & 0xff; /* console hose # */ | ||
75 | |||
76 | /* | ||
77 | * Our hose numbering DOES match the console's, so find | ||
78 | * the right one... | ||
79 | */ | ||
80 | for (hose = hose_head; hose; hose = hose->next) { | ||
81 | if (hose->index == h) break; | ||
82 | } | ||
83 | |||
84 | if (hose) { | ||
85 | printk("Console graphics on hose %d\n", h); | ||
86 | pci_vga_hose = hose; | ||
87 | } | ||
88 | } | ||
89 | } | ||
90 | |||
65 | #endif | 91 | #endif |
diff --git a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c index 7f6a98455e74..f10d2eddd2c3 100644 --- a/arch/alpha/kernel/core_marvel.c +++ b/arch/alpha/kernel/core_marvel.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <asm/pgalloc.h> | 25 | #include <asm/pgalloc.h> |
26 | #include <asm/tlbflush.h> | 26 | #include <asm/tlbflush.h> |
27 | #include <asm/rtc.h> | 27 | #include <asm/rtc.h> |
28 | #include <asm/vga.h> | ||
28 | 29 | ||
29 | #include "proto.h" | 30 | #include "proto.h" |
30 | #include "pci_impl.h" | 31 | #include "pci_impl.h" |
@@ -367,9 +368,8 @@ marvel_io7_present(gct6_node *node) | |||
367 | } | 368 | } |
368 | 369 | ||
369 | static void __init | 370 | static void __init |
370 | marvel_init_vga_hose(void) | 371 | marvel_find_console_vga_hose(void) |
371 | { | 372 | { |
372 | #ifdef CONFIG_VGA_HOSE | ||
373 | u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset); | 373 | u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset); |
374 | 374 | ||
375 | if (pu64[7] == 3) { /* TERM_TYPE == graphics */ | 375 | if (pu64[7] == 3) { /* TERM_TYPE == graphics */ |
@@ -403,7 +403,6 @@ marvel_init_vga_hose(void) | |||
403 | pci_vga_hose = hose; | 403 | pci_vga_hose = hose; |
404 | } | 404 | } |
405 | } | 405 | } |
406 | #endif /* CONFIG_VGA_HOSE */ | ||
407 | } | 406 | } |
408 | 407 | ||
409 | gct6_search_struct gct_wanted_node_list[] = { | 408 | gct6_search_struct gct_wanted_node_list[] = { |
@@ -459,7 +458,7 @@ marvel_init_arch(void) | |||
459 | marvel_init_io7(io7); | 458 | marvel_init_io7(io7); |
460 | 459 | ||
461 | /* Check for graphic console location (if any). */ | 460 | /* Check for graphic console location (if any). */ |
462 | marvel_init_vga_hose(); | 461 | marvel_find_console_vga_hose(); |
463 | } | 462 | } |
464 | 463 | ||
465 | void | 464 | void |
@@ -684,9 +683,6 @@ __marvel_rtc_io(u8 b, unsigned long addr, int write) | |||
684 | /* | 683 | /* |
685 | * IO map support. | 684 | * IO map support. |
686 | */ | 685 | */ |
687 | |||
688 | #define __marvel_is_mem_vga(a) (((a) >= 0xa0000) && ((a) <= 0xc0000)) | ||
689 | |||
690 | void __iomem * | 686 | void __iomem * |
691 | marvel_ioremap(unsigned long addr, unsigned long size) | 687 | marvel_ioremap(unsigned long addr, unsigned long size) |
692 | { | 688 | { |
@@ -698,13 +694,9 @@ marvel_ioremap(unsigned long addr, unsigned long size) | |||
698 | unsigned long pfn; | 694 | unsigned long pfn; |
699 | 695 | ||
700 | /* | 696 | /* |
701 | * Adjust the addr. | 697 | * Adjust the address. |
702 | */ | 698 | */ |
703 | #ifdef CONFIG_VGA_HOSE | 699 | FIXUP_MEMADDR_VGA(addr); |
704 | if (pci_vga_hose && __marvel_is_mem_vga(addr)) { | ||
705 | addr += pci_vga_hose->mem_space->start; | ||
706 | } | ||
707 | #endif | ||
708 | 700 | ||
709 | /* | 701 | /* |
710 | * Find the hose. | 702 | * Find the hose. |
@@ -781,7 +773,9 @@ marvel_ioremap(unsigned long addr, unsigned long size) | |||
781 | return (void __iomem *) vaddr; | 773 | return (void __iomem *) vaddr; |
782 | } | 774 | } |
783 | 775 | ||
784 | return NULL; | 776 | /* Assume it was already a reasonable address */ |
777 | vaddr = baddr + hose->mem_space->start; | ||
778 | return (void __iomem *) vaddr; | ||
785 | } | 779 | } |
786 | 780 | ||
787 | void | 781 | void |
@@ -803,21 +797,12 @@ marvel_is_mmio(const volatile void __iomem *xaddr) | |||
803 | return (addr & 0xFF000000UL) == 0; | 797 | return (addr & 0xFF000000UL) == 0; |
804 | } | 798 | } |
805 | 799 | ||
806 | #define __marvel_is_port_vga(a) \ | ||
807 | (((a) >= 0x3b0) && ((a) < 0x3e0) && ((a) != 0x3b3) && ((a) != 0x3d3)) | ||
808 | #define __marvel_is_port_kbd(a) (((a) == 0x60) || ((a) == 0x64)) | 800 | #define __marvel_is_port_kbd(a) (((a) == 0x60) || ((a) == 0x64)) |
809 | #define __marvel_is_port_rtc(a) (((a) == 0x70) || ((a) == 0x71)) | 801 | #define __marvel_is_port_rtc(a) (((a) == 0x70) || ((a) == 0x71)) |
810 | 802 | ||
811 | void __iomem *marvel_ioportmap (unsigned long addr) | 803 | void __iomem *marvel_ioportmap (unsigned long addr) |
812 | { | 804 | { |
813 | if (__marvel_is_port_rtc (addr) || __marvel_is_port_kbd(addr)) | 805 | FIXUP_IOADDR_VGA(addr); |
814 | ; | ||
815 | #ifdef CONFIG_VGA_HOSE | ||
816 | else if (__marvel_is_port_vga (addr) && pci_vga_hose) | ||
817 | addr += pci_vga_hose->io_space->start; | ||
818 | #endif | ||
819 | else | ||
820 | return NULL; | ||
821 | return (void __iomem *)addr; | 806 | return (void __iomem *)addr; |
822 | } | 807 | } |
823 | 808 | ||
@@ -829,8 +814,14 @@ marvel_ioread8(void __iomem *xaddr) | |||
829 | return 0; | 814 | return 0; |
830 | else if (__marvel_is_port_rtc(addr)) | 815 | else if (__marvel_is_port_rtc(addr)) |
831 | return __marvel_rtc_io(0, addr, 0); | 816 | return __marvel_rtc_io(0, addr, 0); |
832 | else | 817 | else if (marvel_is_ioaddr(addr)) |
833 | return __kernel_ldbu(*(vucp)addr); | 818 | return __kernel_ldbu(*(vucp)addr); |
819 | else | ||
820 | /* this should catch other legacy addresses | ||
821 | that would normally fail on MARVEL, | ||
822 | because there really is nothing there... | ||
823 | */ | ||
824 | return ~0; | ||
834 | } | 825 | } |
835 | 826 | ||
836 | void | 827 | void |
@@ -841,7 +832,7 @@ marvel_iowrite8(u8 b, void __iomem *xaddr) | |||
841 | return; | 832 | return; |
842 | else if (__marvel_is_port_rtc(addr)) | 833 | else if (__marvel_is_port_rtc(addr)) |
843 | __marvel_rtc_io(b, addr, 1); | 834 | __marvel_rtc_io(b, addr, 1); |
844 | else | 835 | else if (marvel_is_ioaddr(addr)) |
845 | __kernel_stb(b, *(vucp)addr); | 836 | __kernel_stb(b, *(vucp)addr); |
846 | } | 837 | } |
847 | 838 | ||
diff --git a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c index 3662fef7db9a..819326627b96 100644 --- a/arch/alpha/kernel/core_titan.c +++ b/arch/alpha/kernel/core_titan.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/smp.h> | 21 | #include <asm/smp.h> |
22 | #include <asm/pgalloc.h> | 22 | #include <asm/pgalloc.h> |
23 | #include <asm/tlbflush.h> | 23 | #include <asm/tlbflush.h> |
24 | #include <asm/vga.h> | ||
24 | 25 | ||
25 | #include "proto.h" | 26 | #include "proto.h" |
26 | #include "pci_impl.h" | 27 | #include "pci_impl.h" |
@@ -35,6 +36,11 @@ struct | |||
35 | } saved_config[4] __attribute__((common)); | 36 | } saved_config[4] __attribute__((common)); |
36 | 37 | ||
37 | /* | 38 | /* |
39 | * Is PChip 1 present? No need to query it more than once. | ||
40 | */ | ||
41 | static int titan_pchip1_present; | ||
42 | |||
43 | /* | ||
38 | * BIOS32-style PCI interface: | 44 | * BIOS32-style PCI interface: |
39 | */ | 45 | */ |
40 | 46 | ||
@@ -344,43 +350,17 @@ titan_init_one_pachip_port(titan_pachip_port *port, int index) | |||
344 | static void __init | 350 | static void __init |
345 | titan_init_pachips(titan_pachip *pachip0, titan_pachip *pachip1) | 351 | titan_init_pachips(titan_pachip *pachip0, titan_pachip *pachip1) |
346 | { | 352 | { |
347 | int pchip1_present = TITAN_cchip->csc.csr & 1L<<14; | 353 | titan_pchip1_present = TITAN_cchip->csc.csr & 1L<<14; |
348 | 354 | ||
349 | /* Init the ports in hose order... */ | 355 | /* Init the ports in hose order... */ |
350 | titan_init_one_pachip_port(&pachip0->g_port, 0); /* hose 0 */ | 356 | titan_init_one_pachip_port(&pachip0->g_port, 0); /* hose 0 */ |
351 | if (pchip1_present) | 357 | if (titan_pchip1_present) |
352 | titan_init_one_pachip_port(&pachip1->g_port, 1);/* hose 1 */ | 358 | titan_init_one_pachip_port(&pachip1->g_port, 1);/* hose 1 */ |
353 | titan_init_one_pachip_port(&pachip0->a_port, 2); /* hose 2 */ | 359 | titan_init_one_pachip_port(&pachip0->a_port, 2); /* hose 2 */ |
354 | if (pchip1_present) | 360 | if (titan_pchip1_present) |
355 | titan_init_one_pachip_port(&pachip1->a_port, 3);/* hose 3 */ | 361 | titan_init_one_pachip_port(&pachip1->a_port, 3);/* hose 3 */ |
356 | } | 362 | } |
357 | 363 | ||
358 | static void __init | ||
359 | titan_init_vga_hose(void) | ||
360 | { | ||
361 | #ifdef CONFIG_VGA_HOSE | ||
362 | u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset); | ||
363 | |||
364 | if (pu64[7] == 3) { /* TERM_TYPE == graphics */ | ||
365 | struct pci_controller *hose; | ||
366 | int h = (pu64[30] >> 24) & 0xff; /* console hose # */ | ||
367 | |||
368 | /* | ||
369 | * Our hose numbering matches the console's, so just find | ||
370 | * the right one... | ||
371 | */ | ||
372 | for (hose = hose_head; hose; hose = hose->next) { | ||
373 | if (hose->index == h) break; | ||
374 | } | ||
375 | |||
376 | if (hose) { | ||
377 | printk("Console graphics on hose %d\n", hose->index); | ||
378 | pci_vga_hose = hose; | ||
379 | } | ||
380 | } | ||
381 | #endif /* CONFIG_VGA_HOSE */ | ||
382 | } | ||
383 | |||
384 | void __init | 364 | void __init |
385 | titan_init_arch(void) | 365 | titan_init_arch(void) |
386 | { | 366 | { |
@@ -406,6 +386,7 @@ titan_init_arch(void) | |||
406 | 386 | ||
407 | /* With multiple PCI busses, we play with I/O as physical addrs. */ | 387 | /* With multiple PCI busses, we play with I/O as physical addrs. */ |
408 | ioport_resource.end = ~0UL; | 388 | ioport_resource.end = ~0UL; |
389 | iomem_resource.end = ~0UL; | ||
409 | 390 | ||
410 | /* PCI DMA Direct Mapping is 1GB at 2GB. */ | 391 | /* PCI DMA Direct Mapping is 1GB at 2GB. */ |
411 | __direct_map_base = 0x80000000; | 392 | __direct_map_base = 0x80000000; |
@@ -415,7 +396,7 @@ titan_init_arch(void) | |||
415 | titan_init_pachips(TITAN_pachip0, TITAN_pachip1); | 396 | titan_init_pachips(TITAN_pachip0, TITAN_pachip1); |
416 | 397 | ||
417 | /* Check for graphic console location (if any). */ | 398 | /* Check for graphic console location (if any). */ |
418 | titan_init_vga_hose(); | 399 | find_console_vga_hose(); |
419 | } | 400 | } |
420 | 401 | ||
421 | static void | 402 | static void |
@@ -441,9 +422,7 @@ titan_kill_one_pachip_port(titan_pachip_port *port, int index) | |||
441 | static void | 422 | static void |
442 | titan_kill_pachips(titan_pachip *pachip0, titan_pachip *pachip1) | 423 | titan_kill_pachips(titan_pachip *pachip0, titan_pachip *pachip1) |
443 | { | 424 | { |
444 | int pchip1_present = TITAN_cchip->csc.csr & 1L<<14; | 425 | if (titan_pchip1_present) { |
445 | |||
446 | if (pchip1_present) { | ||
447 | titan_kill_one_pachip_port(&pachip1->g_port, 1); | 426 | titan_kill_one_pachip_port(&pachip1->g_port, 1); |
448 | titan_kill_one_pachip_port(&pachip1->a_port, 3); | 427 | titan_kill_one_pachip_port(&pachip1->a_port, 3); |
449 | } | 428 | } |
@@ -463,6 +442,14 @@ titan_kill_arch(int mode) | |||
463 | */ | 442 | */ |
464 | 443 | ||
465 | void __iomem * | 444 | void __iomem * |
445 | titan_ioportmap(unsigned long addr) | ||
446 | { | ||
447 | FIXUP_IOADDR_VGA(addr); | ||
448 | return (void __iomem *)(addr + TITAN_IO_BIAS); | ||
449 | } | ||
450 | |||
451 | |||
452 | void __iomem * | ||
466 | titan_ioremap(unsigned long addr, unsigned long size) | 453 | titan_ioremap(unsigned long addr, unsigned long size) |
467 | { | 454 | { |
468 | int h = (addr & TITAN_HOSE_MASK) >> TITAN_HOSE_SHIFT; | 455 | int h = (addr & TITAN_HOSE_MASK) >> TITAN_HOSE_SHIFT; |
@@ -475,14 +462,12 @@ titan_ioremap(unsigned long addr, unsigned long size) | |||
475 | unsigned long pfn; | 462 | unsigned long pfn; |
476 | 463 | ||
477 | /* | 464 | /* |
478 | * Adjust the addr. | 465 | * Adjust the address and hose, if necessary. |
479 | */ | 466 | */ |
480 | #ifdef CONFIG_VGA_HOSE | 467 | if (pci_vga_hose && __is_mem_vga(addr)) { |
481 | if (pci_vga_hose && __titan_is_mem_vga(addr)) { | ||
482 | h = pci_vga_hose->index; | 468 | h = pci_vga_hose->index; |
483 | addr += pci_vga_hose->mem_space->start; | 469 | addr += pci_vga_hose->mem_space->start; |
484 | } | 470 | } |
485 | #endif | ||
486 | 471 | ||
487 | /* | 472 | /* |
488 | * Find the hose. | 473 | * Find the hose. |
@@ -521,8 +506,10 @@ titan_ioremap(unsigned long addr, unsigned long size) | |||
521 | * Map it | 506 | * Map it |
522 | */ | 507 | */ |
523 | area = get_vm_area(size, VM_IOREMAP); | 508 | area = get_vm_area(size, VM_IOREMAP); |
524 | if (!area) | 509 | if (!area) { |
510 | printk("ioremap failed... no vm_area...\n"); | ||
525 | return NULL; | 511 | return NULL; |
512 | } | ||
526 | 513 | ||
527 | ptes = hose->sg_pci->ptes; | 514 | ptes = hose->sg_pci->ptes; |
528 | for (vaddr = (unsigned long)area->addr; | 515 | for (vaddr = (unsigned long)area->addr; |
@@ -539,7 +526,7 @@ titan_ioremap(unsigned long addr, unsigned long size) | |||
539 | if (__alpha_remap_area_pages(vaddr, | 526 | if (__alpha_remap_area_pages(vaddr, |
540 | pfn << PAGE_SHIFT, | 527 | pfn << PAGE_SHIFT, |
541 | PAGE_SIZE, 0)) { | 528 | PAGE_SIZE, 0)) { |
542 | printk("FAILED to map...\n"); | 529 | printk("FAILED to remap_area_pages...\n"); |
543 | vfree(area->addr); | 530 | vfree(area->addr); |
544 | return NULL; | 531 | return NULL; |
545 | } | 532 | } |
@@ -551,7 +538,8 @@ titan_ioremap(unsigned long addr, unsigned long size) | |||
551 | return (void __iomem *) vaddr; | 538 | return (void __iomem *) vaddr; |
552 | } | 539 | } |
553 | 540 | ||
554 | return NULL; | 541 | /* Assume a legacy (read: VGA) address, and return appropriately. */ |
542 | return (void __iomem *)(addr + TITAN_MEM_BIAS); | ||
555 | } | 543 | } |
556 | 544 | ||
557 | void | 545 | void |
@@ -574,6 +562,7 @@ titan_is_mmio(const volatile void __iomem *xaddr) | |||
574 | } | 562 | } |
575 | 563 | ||
576 | #ifndef CONFIG_ALPHA_GENERIC | 564 | #ifndef CONFIG_ALPHA_GENERIC |
565 | EXPORT_SYMBOL(titan_ioportmap); | ||
577 | EXPORT_SYMBOL(titan_ioremap); | 566 | EXPORT_SYMBOL(titan_ioremap); |
578 | EXPORT_SYMBOL(titan_iounmap); | 567 | EXPORT_SYMBOL(titan_iounmap); |
579 | EXPORT_SYMBOL(titan_is_mmio); | 568 | EXPORT_SYMBOL(titan_is_mmio); |
@@ -750,6 +739,7 @@ titan_agp_info(void) | |||
750 | if (titan_query_agp(port)) | 739 | if (titan_query_agp(port)) |
751 | hosenum = 2; | 740 | hosenum = 2; |
752 | if (hosenum < 0 && | 741 | if (hosenum < 0 && |
742 | titan_pchip1_present && | ||
753 | titan_query_agp(port = &TITAN_pachip1->a_port)) | 743 | titan_query_agp(port = &TITAN_pachip1->a_port)) |
754 | hosenum = 3; | 744 | hosenum = 3; |
755 | 745 | ||
diff --git a/arch/alpha/kernel/core_tsunami.c b/arch/alpha/kernel/core_tsunami.c index ce623c6e55e1..ef91e09590d4 100644 --- a/arch/alpha/kernel/core_tsunami.c +++ b/arch/alpha/kernel/core_tsunami.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include <asm/ptrace.h> | 20 | #include <asm/ptrace.h> |
21 | #include <asm/smp.h> | 21 | #include <asm/smp.h> |
22 | #include <asm/vga.h> | ||
22 | 23 | ||
23 | #include "proto.h" | 24 | #include "proto.h" |
24 | #include "pci_impl.h" | 25 | #include "pci_impl.h" |
@@ -349,6 +350,26 @@ tsunami_init_one_pchip(tsunami_pchip *pchip, int index) | |||
349 | tsunami_pci_tbi(hose, 0, -1); | 350 | tsunami_pci_tbi(hose, 0, -1); |
350 | } | 351 | } |
351 | 352 | ||
353 | |||
354 | void __iomem * | ||
355 | tsunami_ioportmap(unsigned long addr) | ||
356 | { | ||
357 | FIXUP_IOADDR_VGA(addr); | ||
358 | return (void __iomem *)(addr + TSUNAMI_IO_BIAS); | ||
359 | } | ||
360 | |||
361 | void __iomem * | ||
362 | tsunami_ioremap(unsigned long addr, unsigned long size) | ||
363 | { | ||
364 | FIXUP_MEMADDR_VGA(addr); | ||
365 | return (void __iomem *)(addr + TSUNAMI_MEM_BIAS); | ||
366 | } | ||
367 | |||
368 | #ifndef CONFIG_ALPHA_GENERIC | ||
369 | EXPORT_SYMBOL(tsunami_ioportmap); | ||
370 | EXPORT_SYMBOL(tsunami_ioremap); | ||
371 | #endif | ||
372 | |||
352 | void __init | 373 | void __init |
353 | tsunami_init_arch(void) | 374 | tsunami_init_arch(void) |
354 | { | 375 | { |
@@ -393,6 +414,9 @@ tsunami_init_arch(void) | |||
393 | tsunami_init_one_pchip(TSUNAMI_pchip0, 0); | 414 | tsunami_init_one_pchip(TSUNAMI_pchip0, 0); |
394 | if (TSUNAMI_cchip->csc.csr & 1L<<14) | 415 | if (TSUNAMI_cchip->csc.csr & 1L<<14) |
395 | tsunami_init_one_pchip(TSUNAMI_pchip1, 1); | 416 | tsunami_init_one_pchip(TSUNAMI_pchip1, 1); |
417 | |||
418 | /* Check for graphic console location (if any). */ | ||
419 | find_console_vga_hose(); | ||
396 | } | 420 | } |
397 | 421 | ||
398 | static void | 422 | static void |
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index c95e95e1ab04..debc8f03886c 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S | |||
@@ -391,11 +391,10 @@ $work_resched: | |||
391 | bne $2, $work_resched | 391 | bne $2, $work_resched |
392 | 392 | ||
393 | $work_notifysig: | 393 | $work_notifysig: |
394 | mov $sp, $17 | 394 | mov $sp, $16 |
395 | br $1, do_switch_stack | 395 | br $1, do_switch_stack |
396 | mov $5, $21 | 396 | mov $sp, $17 |
397 | mov $sp, $18 | 397 | mov $5, $18 |
398 | mov $31, $16 | ||
399 | jsr $26, do_notify_resume | 398 | jsr $26, do_notify_resume |
400 | bsr $1, undo_switch_stack | 399 | bsr $1, undo_switch_stack |
401 | br restore_all | 400 | br restore_all |
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c index 6e7d1fe6e935..28c84e55feb9 100644 --- a/arch/alpha/kernel/pci_iommu.c +++ b/arch/alpha/kernel/pci_iommu.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/pci.h> | 7 | #include <linux/pci.h> |
8 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
9 | #include <linux/bootmem.h> | 9 | #include <linux/bootmem.h> |
10 | #include <linux/log2.h> | ||
10 | 11 | ||
11 | #include <asm/io.h> | 12 | #include <asm/io.h> |
12 | #include <asm/hwrpb.h> | 13 | #include <asm/hwrpb.h> |
@@ -53,7 +54,7 @@ size_for_memory(unsigned long max) | |||
53 | { | 54 | { |
54 | unsigned long mem = max_low_pfn << PAGE_SHIFT; | 55 | unsigned long mem = max_low_pfn << PAGE_SHIFT; |
55 | if (mem < max) | 56 | if (mem < max) |
56 | max = 1UL << ceil_log2(mem); | 57 | max = roundup_pow_of_two(mem); |
57 | return max; | 58 | return max; |
58 | } | 59 | } |
59 | 60 | ||
diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h index 95912ecc65e1..708d5ca87782 100644 --- a/arch/alpha/kernel/proto.h +++ b/arch/alpha/kernel/proto.h | |||
@@ -108,6 +108,15 @@ extern int wildfire_cpuid_to_nid(int); | |||
108 | extern unsigned long wildfire_node_mem_start(int); | 108 | extern unsigned long wildfire_node_mem_start(int); |
109 | extern unsigned long wildfire_node_mem_size(int); | 109 | extern unsigned long wildfire_node_mem_size(int); |
110 | 110 | ||
111 | /* console.c */ | ||
112 | #ifdef CONFIG_VGA_HOSE | ||
113 | extern void find_console_vga_hose(void); | ||
114 | extern void locate_and_init_vga(void *(*)(void *, void *)); | ||
115 | #else | ||
116 | static inline void find_console_vga_hose(void) { } | ||
117 | static inline void locate_and_init_vga(void *(*sel_func)(void *, void *)) { } | ||
118 | #endif | ||
119 | |||
111 | /* setup.c */ | 120 | /* setup.c */ |
112 | extern unsigned long srm_hae; | 121 | extern unsigned long srm_hae; |
113 | extern int boot_cpuid; | 122 | extern int boot_cpuid; |
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index 915f26345c45..bd5e68cd61e8 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/notifier.h> | 43 | #include <linux/notifier.h> |
44 | #include <asm/setup.h> | 44 | #include <asm/setup.h> |
45 | #include <asm/io.h> | 45 | #include <asm/io.h> |
46 | #include <linux/log2.h> | ||
46 | 47 | ||
47 | extern struct atomic_notifier_head panic_notifier_list; | 48 | extern struct atomic_notifier_head panic_notifier_list; |
48 | static int alpha_panic_event(struct notifier_block *, unsigned long, void *); | 49 | static int alpha_panic_event(struct notifier_block *, unsigned long, void *); |
@@ -1303,7 +1304,7 @@ external_cache_probe(int minsize, int width) | |||
1303 | long size = minsize, maxsize = MAX_BCACHE_SIZE * 2; | 1304 | long size = minsize, maxsize = MAX_BCACHE_SIZE * 2; |
1304 | 1305 | ||
1305 | if (maxsize > (max_low_pfn + 1) << PAGE_SHIFT) | 1306 | if (maxsize > (max_low_pfn + 1) << PAGE_SHIFT) |
1306 | maxsize = 1 << (floor_log2(max_low_pfn + 1) + PAGE_SHIFT); | 1307 | maxsize = 1 << (ilog2(max_low_pfn + 1) + PAGE_SHIFT); |
1307 | 1308 | ||
1308 | /* Get the first block cached. */ | 1309 | /* Get the first block cached. */ |
1309 | read_mem_block(__va(0), stride, size); | 1310 | read_mem_block(__va(0), stride, size); |
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index 7f64aa767d5a..410af4f3140e 100644 --- a/arch/alpha/kernel/signal.c +++ b/arch/alpha/kernel/signal.c | |||
@@ -32,8 +32,8 @@ | |||
32 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 32 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
33 | 33 | ||
34 | asmlinkage void ret_from_sys_call(void); | 34 | asmlinkage void ret_from_sys_call(void); |
35 | static int do_signal(sigset_t *, struct pt_regs *, struct switch_stack *, | 35 | static void do_signal(struct pt_regs *, struct switch_stack *, |
36 | unsigned long, unsigned long); | 36 | unsigned long, unsigned long); |
37 | 37 | ||
38 | 38 | ||
39 | /* | 39 | /* |
@@ -146,11 +146,9 @@ sys_rt_sigaction(int sig, const struct sigaction __user *act, | |||
146 | asmlinkage int | 146 | asmlinkage int |
147 | do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw) | 147 | do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw) |
148 | { | 148 | { |
149 | sigset_t oldset; | ||
150 | |||
151 | mask &= _BLOCKABLE; | 149 | mask &= _BLOCKABLE; |
152 | spin_lock_irq(¤t->sighand->siglock); | 150 | spin_lock_irq(¤t->sighand->siglock); |
153 | oldset = current->blocked; | 151 | current->saved_sigmask = current->blocked; |
154 | siginitset(¤t->blocked, mask); | 152 | siginitset(¤t->blocked, mask); |
155 | recalc_sigpending(); | 153 | recalc_sigpending(); |
156 | spin_unlock_irq(¤t->sighand->siglock); | 154 | spin_unlock_irq(¤t->sighand->siglock); |
@@ -160,19 +158,17 @@ do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw) | |||
160 | regs->r0 = EINTR; | 158 | regs->r0 = EINTR; |
161 | regs->r19 = 1; | 159 | regs->r19 = 1; |
162 | 160 | ||
163 | while (1) { | 161 | current->state = TASK_INTERRUPTIBLE; |
164 | current->state = TASK_INTERRUPTIBLE; | 162 | schedule(); |
165 | schedule(); | 163 | set_thread_flag(TIF_RESTORE_SIGMASK); |
166 | if (do_signal(&oldset, regs, sw, 0, 0)) | 164 | return -ERESTARTNOHAND; |
167 | return -EINTR; | ||
168 | } | ||
169 | } | 165 | } |
170 | 166 | ||
171 | asmlinkage int | 167 | asmlinkage int |
172 | do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, | 168 | do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, |
173 | struct pt_regs *regs, struct switch_stack *sw) | 169 | struct pt_regs *regs, struct switch_stack *sw) |
174 | { | 170 | { |
175 | sigset_t oldset, set; | 171 | sigset_t set; |
176 | 172 | ||
177 | /* XXX: Don't preclude handling different sized sigset_t's. */ | 173 | /* XXX: Don't preclude handling different sized sigset_t's. */ |
178 | if (sigsetsize != sizeof(sigset_t)) | 174 | if (sigsetsize != sizeof(sigset_t)) |
@@ -182,7 +178,7 @@ do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, | |||
182 | 178 | ||
183 | sigdelsetmask(&set, ~_BLOCKABLE); | 179 | sigdelsetmask(&set, ~_BLOCKABLE); |
184 | spin_lock_irq(¤t->sighand->siglock); | 180 | spin_lock_irq(¤t->sighand->siglock); |
185 | oldset = current->blocked; | 181 | current->saved_sigmask = current->blocked; |
186 | current->blocked = set; | 182 | current->blocked = set; |
187 | recalc_sigpending(); | 183 | recalc_sigpending(); |
188 | spin_unlock_irq(¤t->sighand->siglock); | 184 | spin_unlock_irq(¤t->sighand->siglock); |
@@ -192,12 +188,10 @@ do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, | |||
192 | regs->r0 = EINTR; | 188 | regs->r0 = EINTR; |
193 | regs->r19 = 1; | 189 | regs->r19 = 1; |
194 | 190 | ||
195 | while (1) { | 191 | current->state = TASK_INTERRUPTIBLE; |
196 | current->state = TASK_INTERRUPTIBLE; | 192 | schedule(); |
197 | schedule(); | 193 | set_thread_flag(TIF_RESTORE_SIGMASK); |
198 | if (do_signal(&oldset, regs, sw, 0, 0)) | 194 | return -ERESTARTNOHAND; |
199 | return -EINTR; | ||
200 | } | ||
201 | } | 195 | } |
202 | 196 | ||
203 | asmlinkage int | 197 | asmlinkage int |
@@ -436,7 +430,7 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, | |||
436 | return err; | 430 | return err; |
437 | } | 431 | } |
438 | 432 | ||
439 | static void | 433 | static int |
440 | setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | 434 | setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, |
441 | struct pt_regs *regs, struct switch_stack * sw) | 435 | struct pt_regs *regs, struct switch_stack * sw) |
442 | { | 436 | { |
@@ -481,13 +475,14 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, | |||
481 | current->comm, current->pid, frame, regs->pc, regs->r26); | 475 | current->comm, current->pid, frame, regs->pc, regs->r26); |
482 | #endif | 476 | #endif |
483 | 477 | ||
484 | return; | 478 | return 0; |
485 | 479 | ||
486 | give_sigsegv: | 480 | give_sigsegv: |
487 | force_sigsegv(sig, current); | 481 | force_sigsegv(sig, current); |
482 | return -EFAULT; | ||
488 | } | 483 | } |
489 | 484 | ||
490 | static void | 485 | static int |
491 | setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 486 | setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
492 | sigset_t *set, struct pt_regs *regs, struct switch_stack * sw) | 487 | sigset_t *set, struct pt_regs *regs, struct switch_stack * sw) |
493 | { | 488 | { |
@@ -543,34 +538,38 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
543 | current->comm, current->pid, frame, regs->pc, regs->r26); | 538 | current->comm, current->pid, frame, regs->pc, regs->r26); |
544 | #endif | 539 | #endif |
545 | 540 | ||
546 | return; | 541 | return 0; |
547 | 542 | ||
548 | give_sigsegv: | 543 | give_sigsegv: |
549 | force_sigsegv(sig, current); | 544 | force_sigsegv(sig, current); |
545 | return -EFAULT; | ||
550 | } | 546 | } |
551 | 547 | ||
552 | 548 | ||
553 | /* | 549 | /* |
554 | * OK, we're invoking a handler. | 550 | * OK, we're invoking a handler. |
555 | */ | 551 | */ |
556 | static inline void | 552 | static inline int |
557 | handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, | 553 | handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, |
558 | sigset_t *oldset, struct pt_regs * regs, struct switch_stack *sw) | 554 | sigset_t *oldset, struct pt_regs * regs, struct switch_stack *sw) |
559 | { | 555 | { |
556 | int ret; | ||
557 | |||
560 | if (ka->sa.sa_flags & SA_SIGINFO) | 558 | if (ka->sa.sa_flags & SA_SIGINFO) |
561 | setup_rt_frame(sig, ka, info, oldset, regs, sw); | 559 | ret = setup_rt_frame(sig, ka, info, oldset, regs, sw); |
562 | else | 560 | else |
563 | setup_frame(sig, ka, oldset, regs, sw); | 561 | ret = setup_frame(sig, ka, oldset, regs, sw); |
564 | 562 | ||
565 | if (ka->sa.sa_flags & SA_RESETHAND) | 563 | if (ret == 0) { |
566 | ka->sa.sa_handler = SIG_DFL; | 564 | spin_lock_irq(¤t->sighand->siglock); |
565 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | ||
566 | if (!(ka->sa.sa_flags & SA_NODEFER)) | ||
567 | sigaddset(¤t->blocked,sig); | ||
568 | recalc_sigpending(); | ||
569 | spin_unlock_irq(¤t->sighand->siglock); | ||
570 | } | ||
567 | 571 | ||
568 | spin_lock_irq(¤t->sighand->siglock); | 572 | return ret; |
569 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | ||
570 | if (!(ka->sa.sa_flags & SA_NODEFER)) | ||
571 | sigaddset(¤t->blocked,sig); | ||
572 | recalc_sigpending(); | ||
573 | spin_unlock_irq(¤t->sighand->siglock); | ||
574 | } | 573 | } |
575 | 574 | ||
576 | static inline void | 575 | static inline void |
@@ -611,30 +610,42 @@ syscall_restart(unsigned long r0, unsigned long r19, | |||
611 | * restart. "r0" is also used as an indicator whether we can restart at | 610 | * restart. "r0" is also used as an indicator whether we can restart at |
612 | * all (if we get here from anything but a syscall return, it will be 0) | 611 | * all (if we get here from anything but a syscall return, it will be 0) |
613 | */ | 612 | */ |
614 | static int | 613 | static void |
615 | do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw, | 614 | do_signal(struct pt_regs * regs, struct switch_stack * sw, |
616 | unsigned long r0, unsigned long r19) | 615 | unsigned long r0, unsigned long r19) |
617 | { | 616 | { |
618 | siginfo_t info; | 617 | siginfo_t info; |
619 | int signr; | 618 | int signr; |
620 | unsigned long single_stepping = ptrace_cancel_bpt(current); | 619 | unsigned long single_stepping = ptrace_cancel_bpt(current); |
621 | struct k_sigaction ka; | 620 | struct k_sigaction ka; |
621 | sigset_t *oldset; | ||
622 | 622 | ||
623 | if (!oldset) | 623 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
624 | oldset = ¤t->saved_sigmask; | ||
625 | else | ||
624 | oldset = ¤t->blocked; | 626 | oldset = ¤t->blocked; |
625 | 627 | ||
626 | /* This lets the debugger run, ... */ | 628 | /* This lets the debugger run, ... */ |
627 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 629 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
630 | |||
628 | /* ... so re-check the single stepping. */ | 631 | /* ... so re-check the single stepping. */ |
629 | single_stepping |= ptrace_cancel_bpt(current); | 632 | single_stepping |= ptrace_cancel_bpt(current); |
630 | 633 | ||
631 | if (signr > 0) { | 634 | if (signr > 0) { |
632 | /* Whee! Actually deliver the signal. */ | 635 | /* Whee! Actually deliver the signal. */ |
633 | if (r0) syscall_restart(r0, r19, regs, &ka); | 636 | if (r0) |
634 | handle_signal(signr, &ka, &info, oldset, regs, sw); | 637 | syscall_restart(r0, r19, regs, &ka); |
638 | if (handle_signal(signr, &ka, &info, oldset, regs, sw) == 0) { | ||
639 | /* A signal was successfully delivered, and the | ||
640 | saved sigmask was stored on the signal frame, | ||
641 | and will be restored by sigreturn. So we can | ||
642 | simply clear the restore sigmask flag. */ | ||
643 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
644 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
645 | } | ||
635 | if (single_stepping) | 646 | if (single_stepping) |
636 | ptrace_set_bpt(current); /* re-set bpt */ | 647 | ptrace_set_bpt(current); /* re-set bpt */ |
637 | return 1; | 648 | return; |
638 | } | 649 | } |
639 | 650 | ||
640 | if (r0) { | 651 | if (r0) { |
@@ -654,17 +665,22 @@ do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw, | |||
654 | break; | 665 | break; |
655 | } | 666 | } |
656 | } | 667 | } |
668 | |||
669 | /* If there's no signal to deliver, we just restore the saved mask. */ | ||
670 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | ||
671 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
672 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
673 | } | ||
674 | |||
657 | if (single_stepping) | 675 | if (single_stepping) |
658 | ptrace_set_bpt(current); /* re-set breakpoint */ | 676 | ptrace_set_bpt(current); /* re-set breakpoint */ |
659 | |||
660 | return 0; | ||
661 | } | 677 | } |
662 | 678 | ||
663 | void | 679 | void |
664 | do_notify_resume(sigset_t *oldset, struct pt_regs *regs, | 680 | do_notify_resume(struct pt_regs *regs, struct switch_stack *sw, |
665 | struct switch_stack *sw, unsigned long r0, | 681 | unsigned long thread_info_flags, |
666 | unsigned long r19, unsigned long thread_info_flags) | 682 | unsigned long r0, unsigned long r19) |
667 | { | 683 | { |
668 | if (thread_info_flags & _TIF_SIGPENDING) | 684 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) |
669 | do_signal(oldset, regs, sw, r0, r19); | 685 | do_signal(regs, sw, r0, r19); |
670 | } | 686 | } |
diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c index 85d2f933dd07..c71b0fd7a61f 100644 --- a/arch/alpha/kernel/sys_dp264.c +++ b/arch/alpha/kernel/sys_dp264.c | |||
@@ -543,6 +543,7 @@ dp264_init_pci(void) | |||
543 | { | 543 | { |
544 | common_init_pci(); | 544 | common_init_pci(); |
545 | SMC669_Init(0); | 545 | SMC669_Init(0); |
546 | locate_and_init_vga(NULL); | ||
546 | } | 547 | } |
547 | 548 | ||
548 | static void __init | 549 | static void __init |
@@ -551,6 +552,14 @@ monet_init_pci(void) | |||
551 | common_init_pci(); | 552 | common_init_pci(); |
552 | SMC669_Init(1); | 553 | SMC669_Init(1); |
553 | es1888_init(); | 554 | es1888_init(); |
555 | locate_and_init_vga(NULL); | ||
556 | } | ||
557 | |||
558 | static void __init | ||
559 | clipper_init_pci(void) | ||
560 | { | ||
561 | common_init_pci(); | ||
562 | locate_and_init_vga(NULL); | ||
554 | } | 563 | } |
555 | 564 | ||
556 | static void __init | 565 | static void __init |
@@ -655,7 +664,7 @@ struct alpha_machine_vector clipper_mv __initmv = { | |||
655 | .init_arch = tsunami_init_arch, | 664 | .init_arch = tsunami_init_arch, |
656 | .init_irq = clipper_init_irq, | 665 | .init_irq = clipper_init_irq, |
657 | .init_rtc = common_init_rtc, | 666 | .init_rtc = common_init_rtc, |
658 | .init_pci = common_init_pci, | 667 | .init_pci = clipper_init_pci, |
659 | .kill_arch = tsunami_kill_arch, | 668 | .kill_arch = tsunami_kill_arch, |
660 | .pci_map_irq = clipper_map_irq, | 669 | .pci_map_irq = clipper_map_irq, |
661 | .pci_swizzle = common_swizzle, | 670 | .pci_swizzle = common_swizzle, |
diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c index e349f03b830e..0bcb968cb60a 100644 --- a/arch/alpha/kernel/sys_marvel.c +++ b/arch/alpha/kernel/sys_marvel.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <asm/core_marvel.h> | 22 | #include <asm/core_marvel.h> |
23 | #include <asm/hwrpb.h> | 23 | #include <asm/hwrpb.h> |
24 | #include <asm/tlbflush.h> | 24 | #include <asm/tlbflush.h> |
25 | #include <asm/vga.h> | ||
25 | 26 | ||
26 | #include "proto.h" | 27 | #include "proto.h" |
27 | #include "err_impl.h" | 28 | #include "err_impl.h" |
@@ -412,10 +413,7 @@ marvel_init_pci(void) | |||
412 | 413 | ||
413 | pci_probe_only = 1; | 414 | pci_probe_only = 1; |
414 | common_init_pci(); | 415 | common_init_pci(); |
415 | |||
416 | #ifdef CONFIG_VGA_HOSE | ||
417 | locate_and_init_vga(NULL); | 416 | locate_and_init_vga(NULL); |
418 | #endif | ||
419 | 417 | ||
420 | /* Clear any io7 errors. */ | 418 | /* Clear any io7 errors. */ |
421 | for (io7 = NULL; (io7 = marvel_next_io7(io7)) != NULL; ) | 419 | for (io7 = NULL; (io7 = marvel_next_io7(io7)) != NULL; ) |
diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c index f009b7bc0943..1d3c1398c428 100644 --- a/arch/alpha/kernel/sys_titan.c +++ b/arch/alpha/kernel/sys_titan.c | |||
@@ -331,9 +331,7 @@ titan_init_pci(void) | |||
331 | pci_probe_only = 1; | 331 | pci_probe_only = 1; |
332 | common_init_pci(); | 332 | common_init_pci(); |
333 | SMC669_Init(0); | 333 | SMC669_Init(0); |
334 | #ifdef CONFIG_VGA_HOSE | ||
335 | locate_and_init_vga(NULL); | 334 | locate_and_init_vga(NULL); |
336 | #endif | ||
337 | } | 335 | } |
338 | 336 | ||
339 | 337 | ||
diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S index f6cfe8ce3f96..79de99e32c35 100644 --- a/arch/alpha/kernel/systbls.S +++ b/arch/alpha/kernel/systbls.S | |||
@@ -465,6 +465,38 @@ sys_call_table: | |||
465 | .quad sys_inotify_init | 465 | .quad sys_inotify_init |
466 | .quad sys_inotify_add_watch /* 445 */ | 466 | .quad sys_inotify_add_watch /* 445 */ |
467 | .quad sys_inotify_rm_watch | 467 | .quad sys_inotify_rm_watch |
468 | .quad sys_fdatasync | ||
469 | .quad sys_kexec_load | ||
470 | .quad sys_migrate_pages | ||
471 | .quad sys_openat /* 450 */ | ||
472 | .quad sys_mkdirat | ||
473 | .quad sys_mknodat | ||
474 | .quad sys_fchownat | ||
475 | .quad sys_futimesat | ||
476 | .quad sys_fstatat64 /* 455 */ | ||
477 | .quad sys_unlinkat | ||
478 | .quad sys_renameat | ||
479 | .quad sys_linkat | ||
480 | .quad sys_symlinkat | ||
481 | .quad sys_readlinkat /* 460 */ | ||
482 | .quad sys_fchmodat | ||
483 | .quad sys_faccessat | ||
484 | .quad sys_pselect6 | ||
485 | .quad sys_ppoll | ||
486 | .quad sys_unshare /* 465 */ | ||
487 | .quad sys_set_robust_list | ||
488 | .quad sys_get_robust_list | ||
489 | .quad sys_splice | ||
490 | .quad sys_sync_file_range | ||
491 | .quad sys_tee /* 470 */ | ||
492 | .quad sys_vmsplice | ||
493 | .quad sys_move_pages | ||
494 | .quad sys_getcpu | ||
495 | .quad sys_epoll_pwait | ||
496 | .quad sys_utimensat /* 475 */ | ||
497 | .quad sys_signalfd | ||
498 | .quad sys_timerfd | ||
499 | .quad sys_eventfd | ||
468 | 500 | ||
469 | .size sys_call_table, . - sys_call_table | 501 | .size sys_call_table, . - sys_call_table |
470 | .type sys_call_table, @object | 502 | .type sys_call_table, @object |
diff --git a/arch/alpha/lib/Makefile b/arch/alpha/lib/Makefile index ea098f3b629f..266f78e13076 100644 --- a/arch/alpha/lib/Makefile +++ b/arch/alpha/lib/Makefile | |||
@@ -37,7 +37,8 @@ lib-y = __divqu.o __remqu.o __divlu.o __remlu.o \ | |||
37 | $(ev6-y)clear_page.o \ | 37 | $(ev6-y)clear_page.o \ |
38 | $(ev6-y)copy_page.o \ | 38 | $(ev6-y)copy_page.o \ |
39 | fpreg.o \ | 39 | fpreg.o \ |
40 | callback_srm.o srm_puts.o srm_printk.o | 40 | callback_srm.o srm_puts.o srm_printk.o \ |
41 | fls.o | ||
41 | 42 | ||
42 | lib-$(CONFIG_SMP) += dec_and_lock.o | 43 | lib-$(CONFIG_SMP) += dec_and_lock.o |
43 | 44 | ||
diff --git a/arch/alpha/lib/fls.c b/arch/alpha/lib/fls.c new file mode 100644 index 000000000000..7ad84ea0acf8 --- /dev/null +++ b/arch/alpha/lib/fls.c | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * arch/alpha/lib/fls.c | ||
3 | */ | ||
4 | |||
5 | #include <linux/module.h> | ||
6 | #include <asm/bitops.h> | ||
7 | |||
8 | /* This is fls(x)-1, except zero is held to zero. This allows most | ||
9 | efficent input into extbl, plus it allows easy handling of fls(0)=0. */ | ||
10 | |||
11 | const unsigned char __flsm1_tab[256] = | ||
12 | { | ||
13 | 0, | ||
14 | 0, | ||
15 | 1, 1, | ||
16 | 2, 2, 2, 2, | ||
17 | 3, 3, 3, 3, 3, 3, 3, 3, | ||
18 | 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, | ||
19 | |||
20 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | ||
21 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, | ||
22 | |||
23 | 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, | ||
24 | 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, | ||
25 | 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, | ||
26 | 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, | ||
27 | |||
28 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, | ||
29 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, | ||
30 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, | ||
31 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, | ||
32 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, | ||
33 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, | ||
34 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, | ||
35 | 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, | ||
36 | }; | ||
37 | |||
38 | EXPORT_SYMBOL(__flsm1_tab); | ||
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 2568d311be21..23348e9561b9 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S | |||
@@ -247,7 +247,7 @@ not_relocated: mov r0, #0 | |||
247 | mov r3, r7 | 247 | mov r3, r7 |
248 | bl decompress_kernel | 248 | bl decompress_kernel |
249 | 249 | ||
250 | add r0, r0, #127 | 250 | add r0, r0, #127 + 128 @ alignment + stack |
251 | bic r0, r0, #127 @ align the kernel length | 251 | bic r0, r0, #127 @ align the kernel length |
252 | /* | 252 | /* |
253 | * r0 = decompressed kernel length | 253 | * r0 = decompressed kernel length |
@@ -269,6 +269,7 @@ not_relocated: mov r0, #0 | |||
269 | stmia r1!, {r9 - r14} | 269 | stmia r1!, {r9 - r14} |
270 | cmp r2, r3 | 270 | cmp r2, r3 |
271 | blo 1b | 271 | blo 1b |
272 | add sp, r1, #128 @ relocate the stack | ||
272 | 273 | ||
273 | bl cache_clean_flush | 274 | bl cache_clean_flush |
274 | add pc, r5, r0 @ call relocation code | 275 | add pc, r5, r0 @ call relocation code |
@@ -476,6 +477,7 @@ __common_mmu_cache_on: | |||
476 | */ | 477 | */ |
477 | .align 5 | 478 | .align 5 |
478 | reloc_start: add r9, r5, r0 | 479 | reloc_start: add r9, r5, r0 |
480 | sub r9, r9, #128 @ do not copy the stack | ||
479 | debug_reloc_start | 481 | debug_reloc_start |
480 | mov r1, r4 | 482 | mov r1, r4 |
481 | 1: | 483 | 1: |
@@ -486,6 +488,7 @@ reloc_start: add r9, r5, r0 | |||
486 | 488 | ||
487 | cmp r5, r9 | 489 | cmp r5, r9 |
488 | blo 1b | 490 | blo 1b |
491 | add sp, r1, #128 @ relocate the stack | ||
489 | debug_reloc_end | 492 | debug_reloc_end |
490 | 493 | ||
491 | call_kernel: bl cache_clean_flush | 494 | call_kernel: bl cache_clean_flush |
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 9179e8220314..f73d62e8ab60 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c | |||
@@ -57,7 +57,7 @@ extern void fp_enter(void); | |||
57 | #define EXPORT_SYMBOL_ALIAS(sym,orig) \ | 57 | #define EXPORT_SYMBOL_ALIAS(sym,orig) \ |
58 | EXPORT_CRC_ALIAS(sym) \ | 58 | EXPORT_CRC_ALIAS(sym) \ |
59 | static const struct kernel_symbol __ksymtab_##sym \ | 59 | static const struct kernel_symbol __ksymtab_##sym \ |
60 | __attribute_used__ __attribute__((section("__ksymtab"))) = \ | 60 | __used __attribute__((section("__ksymtab"))) = \ |
61 | { (unsigned long)&orig, #sym }; | 61 | { (unsigned long)&orig, #sym }; |
62 | 62 | ||
63 | /* | 63 | /* |
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c index 8b63ad89d0a8..ae31deb2d065 100644 --- a/arch/arm/kernel/stacktrace.c +++ b/arch/arm/kernel/stacktrace.c | |||
@@ -13,7 +13,7 @@ int walk_stackframe(unsigned long fp, unsigned long low, unsigned long high, | |||
13 | /* | 13 | /* |
14 | * Check current frame pointer is within bounds | 14 | * Check current frame pointer is within bounds |
15 | */ | 15 | */ |
16 | if ((fp - 12) < low || fp + 4 >= high) | 16 | if (fp < (low + 12) || fp + 4 >= high) |
17 | break; | 17 | break; |
18 | 18 | ||
19 | frame = (struct stackframe *)(fp - 12); | 19 | frame = (struct stackframe *)(fp - 12); |
diff --git a/arch/arm/mach-at91/board-dk.c b/arch/arm/mach-at91/board-dk.c index 6043c38c0a9e..af497896a96c 100644 --- a/arch/arm/mach-at91/board-dk.c +++ b/arch/arm/mach-at91/board-dk.c | |||
@@ -132,7 +132,7 @@ static struct mtd_partition __initdata dk_nand_partition[] = { | |||
132 | }, | 132 | }, |
133 | }; | 133 | }; |
134 | 134 | ||
135 | static struct mtd_partition *nand_partitions(int size, int *num_partitions) | 135 | static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) |
136 | { | 136 | { |
137 | *num_partitions = ARRAY_SIZE(dk_nand_partition); | 137 | *num_partitions = ARRAY_SIZE(dk_nand_partition); |
138 | return dk_nand_partition; | 138 | return dk_nand_partition; |
diff --git a/arch/arm/mach-at91/board-kb9202.c b/arch/arm/mach-at91/board-kb9202.c index 76f6e1e553ea..7d9b1a278fd6 100644 --- a/arch/arm/mach-at91/board-kb9202.c +++ b/arch/arm/mach-at91/board-kb9202.c | |||
@@ -96,7 +96,7 @@ static struct mtd_partition __initdata kb9202_nand_partition[] = { | |||
96 | }, | 96 | }, |
97 | }; | 97 | }; |
98 | 98 | ||
99 | static struct mtd_partition *nand_partitions(int size, int *num_partitions) | 99 | static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) |
100 | { | 100 | { |
101 | *num_partitions = ARRAY_SIZE(kb9202_nand_partition); | 101 | *num_partitions = ARRAY_SIZE(kb9202_nand_partition); |
102 | return kb9202_nand_partition; | 102 | return kb9202_nand_partition; |
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c index 1f0c8a400b3a..26ca8ab3f62a 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c | |||
@@ -178,7 +178,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = { | |||
178 | }, | 178 | }, |
179 | }; | 179 | }; |
180 | 180 | ||
181 | static struct mtd_partition *nand_partitions(int size, int *num_partitions) | 181 | static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) |
182 | { | 182 | { |
183 | *num_partitions = ARRAY_SIZE(ek_nand_partition); | 183 | *num_partitions = ARRAY_SIZE(ek_nand_partition); |
184 | return ek_nand_partition; | 184 | return ek_nand_partition; |
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index f57458559fb6..c164c8e58ae6 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c | |||
@@ -180,7 +180,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = { | |||
180 | }, | 180 | }, |
181 | }; | 181 | }; |
182 | 182 | ||
183 | static struct mtd_partition *nand_partitions(int size, int *num_partitions) | 183 | static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) |
184 | { | 184 | { |
185 | *num_partitions = ARRAY_SIZE(ek_nand_partition); | 185 | *num_partitions = ARRAY_SIZE(ek_nand_partition); |
186 | return ek_nand_partition; | 186 | return ek_nand_partition; |
diff --git a/arch/arm/mach-at91/board-sam9rlek.c b/arch/arm/mach-at91/board-sam9rlek.c index 30c79aca84d4..9b61320f295a 100644 --- a/arch/arm/mach-at91/board-sam9rlek.c +++ b/arch/arm/mach-at91/board-sam9rlek.c | |||
@@ -87,7 +87,7 @@ static struct mtd_partition __initdata ek_nand_partition[] = { | |||
87 | }, | 87 | }, |
88 | }; | 88 | }; |
89 | 89 | ||
90 | static struct mtd_partition *nand_partitions(int size, int *num_partitions) | 90 | static struct mtd_partition * __init nand_partitions(int size, int *num_partitions) |
91 | { | 91 | { |
92 | *num_partitions = ARRAY_SIZE(ek_nand_partition); | 92 | *num_partitions = ARRAY_SIZE(ek_nand_partition); |
93 | return ek_nand_partition; | 93 | return ek_nand_partition; |
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index 06c9a0507d0d..848efb2a4ebf 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c | |||
@@ -364,19 +364,14 @@ static int at91_clk_show(struct seq_file *s, void *unused) | |||
364 | { | 364 | { |
365 | u32 scsr, pcsr, sr; | 365 | u32 scsr, pcsr, sr; |
366 | struct clk *clk; | 366 | struct clk *clk; |
367 | unsigned i; | ||
368 | 367 | ||
369 | seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR)); | 368 | seq_printf(s, "SCSR = %8x\n", scsr = at91_sys_read(AT91_PMC_SCSR)); |
370 | seq_printf(s, "PCSR = %8x\n", pcsr = at91_sys_read(AT91_PMC_PCSR)); | 369 | seq_printf(s, "PCSR = %8x\n", pcsr = at91_sys_read(AT91_PMC_PCSR)); |
371 | |||
372 | seq_printf(s, "MOR = %8x\n", at91_sys_read(AT91_CKGR_MOR)); | 370 | seq_printf(s, "MOR = %8x\n", at91_sys_read(AT91_CKGR_MOR)); |
373 | seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR)); | 371 | seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR)); |
374 | seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR)); | 372 | seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR)); |
375 | seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR)); | 373 | seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR)); |
376 | |||
377 | seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR)); | 374 | seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR)); |
378 | for (i = 0; i < 4; i++) | ||
379 | seq_printf(s, "PCK%d = %8x\n", i, at91_sys_read(AT91_PMC_PCKR(i))); | ||
380 | seq_printf(s, "SR = %8x\n", sr = at91_sys_read(AT91_PMC_SR)); | 375 | seq_printf(s, "SR = %8x\n", sr = at91_sys_read(AT91_PMC_SR)); |
381 | 376 | ||
382 | seq_printf(s, "\n"); | 377 | seq_printf(s, "\n"); |
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index ff8db29e989e..47ff676aca5f 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c | |||
@@ -76,12 +76,11 @@ static int at91_pm_verify_clocks(void) | |||
76 | pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); | 76 | pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); |
77 | return 0; | 77 | return 0; |
78 | } | 78 | } |
79 | } else if (cpu_is_at91sam9260()) { | 79 | } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()) { |
80 | #warning "Check SAM9260 USB clocks" | 80 | if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) { |
81 | } else if (cpu_is_at91sam9261()) { | 81 | pr_debug("AT91: PM - Suspend-to-RAM with USB still active\n"); |
82 | #warning "Check SAM9261 USB clocks" | 82 | return 0; |
83 | } else if (cpu_is_at91sam9263()) { | 83 | } |
84 | #warning "Check SAM9263 USB clocks" | ||
85 | } | 84 | } |
86 | 85 | ||
87 | #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS | 86 | #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS |
diff --git a/arch/arm/mach-footbridge/cats-pci.c b/arch/arm/mach-footbridge/cats-pci.c index 4f984fde7375..35eb232a649a 100644 --- a/arch/arm/mach-footbridge/cats-pci.c +++ b/arch/arm/mach-footbridge/cats-pci.c | |||
@@ -45,7 +45,7 @@ static struct hw_pci cats_pci __initdata = { | |||
45 | .postinit = dc21285_postinit, | 45 | .postinit = dc21285_postinit, |
46 | }; | 46 | }; |
47 | 47 | ||
48 | static int cats_pci_init(void) | 48 | static int __init cats_pci_init(void) |
49 | { | 49 | { |
50 | if (machine_is_cats()) | 50 | if (machine_is_cats()) |
51 | pci_common_init(&cats_pci); | 51 | pci_common_init(&cats_pci); |
diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c index 7a7fa51ec62c..1c474cf709ca 100644 --- a/arch/arm/mach-imx/generic.c +++ b/arch/arm/mach-imx/generic.c | |||
@@ -201,7 +201,6 @@ void __init imx_set_mmc_info(struct imxmmc_platform_data *info) | |||
201 | { | 201 | { |
202 | imx_mmc_device.dev.platform_data = info; | 202 | imx_mmc_device.dev.platform_data = info; |
203 | } | 203 | } |
204 | EXPORT_SYMBOL(imx_set_mmc_info); | ||
205 | 204 | ||
206 | static struct imxfb_mach_info imx_fb_info; | 205 | static struct imxfb_mach_info imx_fb_info; |
207 | 206 | ||
diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c index 0fdd03ab36e6..ce7c15c73004 100644 --- a/arch/arm/mach-ixp2000/ixdp2400.c +++ b/arch/arm/mach-ixp2000/ixdp2400.c | |||
@@ -164,7 +164,7 @@ int __init ixdp2400_pci_init(void) | |||
164 | 164 | ||
165 | subsys_initcall(ixdp2400_pci_init); | 165 | subsys_initcall(ixdp2400_pci_init); |
166 | 166 | ||
167 | void ixdp2400_init_irq(void) | 167 | void __init ixdp2400_init_irq(void) |
168 | { | 168 | { |
169 | ixdp2x00_init_irq(IXDP2400_CPLD_INT_STAT, IXDP2400_CPLD_INT_MASK, IXDP2400_NR_IRQS); | 169 | ixdp2x00_init_irq(IXDP2400_CPLD_INT_STAT, IXDP2400_CPLD_INT_MASK, IXDP2400_NR_IRQS); |
170 | } | 170 | } |
diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c index 70d247f09a7e..14f09b80ab77 100644 --- a/arch/arm/mach-ixp2000/ixdp2800.c +++ b/arch/arm/mach-ixp2000/ixdp2800.c | |||
@@ -279,7 +279,7 @@ int __init ixdp2800_pci_init(void) | |||
279 | 279 | ||
280 | subsys_initcall(ixdp2800_pci_init); | 280 | subsys_initcall(ixdp2800_pci_init); |
281 | 281 | ||
282 | void ixdp2800_init_irq(void) | 282 | void __init ixdp2800_init_irq(void) |
283 | { | 283 | { |
284 | ixdp2x00_init_irq(IXDP2800_CPLD_INT_STAT, IXDP2800_CPLD_INT_MASK, IXDP2800_NR_IRQS); | 284 | ixdp2x00_init_irq(IXDP2800_CPLD_INT_STAT, IXDP2800_CPLD_INT_MASK, IXDP2800_NR_IRQS); |
285 | } | 285 | } |
diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c index 011065b967b4..73c651e83d92 100644 --- a/arch/arm/mach-ixp2000/ixdp2x00.c +++ b/arch/arm/mach-ixp2000/ixdp2x00.c | |||
@@ -145,7 +145,7 @@ static struct irq_chip ixdp2x00_cpld_irq_chip = { | |||
145 | .unmask = ixdp2x00_irq_unmask | 145 | .unmask = ixdp2x00_irq_unmask |
146 | }; | 146 | }; |
147 | 147 | ||
148 | void ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long *mask_reg, unsigned long nr_irqs) | 148 | void __init ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long *mask_reg, unsigned long nr_irqs) |
149 | { | 149 | { |
150 | unsigned int irq; | 150 | unsigned int irq; |
151 | 151 | ||
diff --git a/arch/arm/mach-ixp23xx/ixdp2351.c b/arch/arm/mach-ixp23xx/ixdp2351.c index 7a86a2516eaa..c41a6b5a0acc 100644 --- a/arch/arm/mach-ixp23xx/ixdp2351.c +++ b/arch/arm/mach-ixp23xx/ixdp2351.c | |||
@@ -124,7 +124,7 @@ static struct irq_chip ixdp2351_intb_chip = { | |||
124 | .unmask = ixdp2351_intb_unmask | 124 | .unmask = ixdp2351_intb_unmask |
125 | }; | 125 | }; |
126 | 126 | ||
127 | void ixdp2351_init_irq(void) | 127 | void __init ixdp2351_init_irq(void) |
128 | { | 128 | { |
129 | int irq; | 129 | int irq; |
130 | 130 | ||
diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c index ac7d43d23c28..227f808dc0ec 100644 --- a/arch/arm/mach-ixp23xx/pci.c +++ b/arch/arm/mach-ixp23xx/pci.c | |||
@@ -284,7 +284,7 @@ int ixp23xx_pci_setup(int nr, struct pci_sys_data *sys) | |||
284 | return 1; | 284 | return 1; |
285 | } | 285 | } |
286 | 286 | ||
287 | void ixp23xx_pci_slave_init(void) | 287 | void __init ixp23xx_pci_slave_init(void) |
288 | { | 288 | { |
289 | ixp23xx_pci_common_init(); | 289 | ixp23xx_pci_common_init(); |
290 | } | 290 | } |
diff --git a/arch/arm/mach-ixp23xx/roadrunner.c b/arch/arm/mach-ixp23xx/roadrunner.c index d06e21b70de5..e35644961aa4 100644 --- a/arch/arm/mach-ixp23xx/roadrunner.c +++ b/arch/arm/mach-ixp23xx/roadrunner.c | |||
@@ -110,7 +110,7 @@ static int __init roadrunner_map_irq(struct pci_dev *dev, u8 idsel, u8 pin) | |||
110 | return NO_IRQ; | 110 | return NO_IRQ; |
111 | } | 111 | } |
112 | 112 | ||
113 | static void roadrunner_pci_preinit(void) | 113 | static void __init roadrunner_pci_preinit(void) |
114 | { | 114 | { |
115 | set_irq_type(IRQ_ROADRUNNER_PCI_INTC, IRQT_LOW); | 115 | set_irq_type(IRQ_ROADRUNNER_PCI_INTC, IRQT_LOW); |
116 | set_irq_type(IRQ_ROADRUNNER_PCI_INTD, IRQT_LOW); | 116 | set_irq_type(IRQ_ROADRUNNER_PCI_INTD, IRQT_LOW); |
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig index 9715ef506c24..060909870b50 100644 --- a/arch/arm/mach-ixp4xx/Kconfig +++ b/arch/arm/mach-ixp4xx/Kconfig | |||
@@ -104,9 +104,6 @@ config MACH_DSMG600 | |||
104 | DSM-G600 RevA device. For more information on this platform, | 104 | DSM-G600 RevA device. For more information on this platform, |
105 | see http://www.nslu2-linux.org/wiki/DSMG600/HomePage | 105 | see http://www.nslu2-linux.org/wiki/DSMG600/HomePage |
106 | 106 | ||
107 | # | ||
108 | # Avila and IXDP share the same source for now. Will change in future | ||
109 | # | ||
110 | config ARCH_IXDP4XX | 107 | config ARCH_IXDP4XX |
111 | bool | 108 | bool |
112 | depends on ARCH_IXDP425 || MACH_IXDP465 || MACH_KIXRP435 | 109 | depends on ARCH_IXDP425 || MACH_IXDP465 || MACH_KIXRP435 |
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 64685da1462d..8112f726ffa0 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c | |||
@@ -283,7 +283,7 @@ static struct irqaction ixp4xx_timer_irq = { | |||
283 | .handler = ixp4xx_timer_interrupt, | 283 | .handler = ixp4xx_timer_interrupt, |
284 | }; | 284 | }; |
285 | 285 | ||
286 | static void __init ixp4xx_timer_init(void) | 286 | void __init ixp4xx_timer_init(void) |
287 | { | 287 | { |
288 | /* Reset/disable counter */ | 288 | /* Reset/disable counter */ |
289 | *IXP4XX_OSRT1 = 0; | 289 | *IXP4XX_OSRT1 = 0; |
diff --git a/arch/arm/mach-ixp4xx/coyote-pci.c b/arch/arm/mach-ixp4xx/coyote-pci.c index 7bc94f3def1c..ad2e5b97966e 100644 --- a/arch/arm/mach-ixp4xx/coyote-pci.c +++ b/arch/arm/mach-ixp4xx/coyote-pci.c | |||
@@ -25,10 +25,6 @@ | |||
25 | 25 | ||
26 | #include <asm/mach/pci.h> | 26 | #include <asm/mach/pci.h> |
27 | 27 | ||
28 | extern void ixp4xx_pci_preinit(void); | ||
29 | extern int ixp4xx_setup(int nr, struct pci_sys_data *sys); | ||
30 | extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys); | ||
31 | |||
32 | void __init coyote_pci_preinit(void) | 28 | void __init coyote_pci_preinit(void) |
33 | { | 29 | { |
34 | set_irq_type(IRQ_COYOTE_PCI_SLOT0, IRQT_LOW); | 30 | set_irq_type(IRQ_COYOTE_PCI_SLOT0, IRQT_LOW); |
diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c b/arch/arm/mach-ixp4xx/dsmg600-setup.c index 1caff65e22cc..1e75e105c4f7 100644 --- a/arch/arm/mach-ixp4xx/dsmg600-setup.c +++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <asm/mach-types.h> | 18 | #include <asm/mach-types.h> |
19 | #include <asm/mach/arch.h> | 19 | #include <asm/mach/arch.h> |
20 | #include <asm/mach/flash.h> | 20 | #include <asm/mach/flash.h> |
21 | #include <asm/mach/time.h> | ||
21 | 22 | ||
22 | static struct flash_platform_data dsmg600_flash_data = { | 23 | static struct flash_platform_data dsmg600_flash_data = { |
23 | .map_name = "cfi_probe", | 24 | .map_name = "cfi_probe", |
@@ -128,6 +129,19 @@ static void dsmg600_power_off(void) | |||
128 | gpio_line_set(DSMG600_PO_GPIO, IXP4XX_GPIO_HIGH); | 129 | gpio_line_set(DSMG600_PO_GPIO, IXP4XX_GPIO_HIGH); |
129 | } | 130 | } |
130 | 131 | ||
132 | static void __init dsmg600_timer_init(void) | ||
133 | { | ||
134 | /* The xtal on this machine is non-standard. */ | ||
135 | ixp4xx_timer_freq = DSMG600_FREQ; | ||
136 | |||
137 | /* Call standard timer_init function. */ | ||
138 | ixp4xx_timer_init(); | ||
139 | } | ||
140 | |||
141 | static struct sys_timer dsmg600_timer = { | ||
142 | .init = dsmg600_timer_init, | ||
143 | }; | ||
144 | |||
131 | static void __init dsmg600_init(void) | 145 | static void __init dsmg600_init(void) |
132 | { | 146 | { |
133 | ixp4xx_sys_init(); | 147 | ixp4xx_sys_init(); |
@@ -155,21 +169,13 @@ static void __init dsmg600_init(void) | |||
155 | #endif | 169 | #endif |
156 | } | 170 | } |
157 | 171 | ||
158 | static void __init dsmg600_fixup(struct machine_desc *desc, | ||
159 | struct tag *tags, char **cmdline, struct meminfo *mi) | ||
160 | { | ||
161 | /* The xtal on this machine is non-standard. */ | ||
162 | ixp4xx_timer_freq = DSMG600_FREQ; | ||
163 | } | ||
164 | |||
165 | MACHINE_START(DSMG600, "D-Link DSM-G600 RevA") | 172 | MACHINE_START(DSMG600, "D-Link DSM-G600 RevA") |
166 | /* Maintainer: www.nslu2-linux.org */ | 173 | /* Maintainer: www.nslu2-linux.org */ |
167 | .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, | 174 | .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, |
168 | .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC, | 175 | .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xFFFC, |
169 | .boot_params = 0x00000100, | 176 | .boot_params = 0x00000100, |
170 | .fixup = dsmg600_fixup, | ||
171 | .map_io = ixp4xx_map_io, | 177 | .map_io = ixp4xx_map_io, |
172 | .init_irq = ixp4xx_init_irq, | 178 | .init_irq = ixp4xx_init_irq, |
173 | .timer = &ixp4xx_timer, | 179 | .timer = &dsmg600_timer, |
174 | .init_machine = dsmg600_init, | 180 | .init_machine = dsmg600_init, |
175 | MACHINE_END | 181 | MACHINE_END |
diff --git a/arch/arm/mach-ixp4xx/ixdpg425-pci.c b/arch/arm/mach-ixp4xx/ixdpg425-pci.c index 509a95a692a4..d1e75b7dc3b1 100644 --- a/arch/arm/mach-ixp4xx/ixdpg425-pci.c +++ b/arch/arm/mach-ixp4xx/ixdpg425-pci.c | |||
@@ -23,10 +23,6 @@ | |||
23 | 23 | ||
24 | #include <asm/mach/pci.h> | 24 | #include <asm/mach/pci.h> |
25 | 25 | ||
26 | extern void ixp4xx_pci_preinit(void); | ||
27 | extern int ixp4xx_setup(int nr, struct pci_sys_data *sys); | ||
28 | extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys); | ||
29 | |||
30 | void __init ixdpg425_pci_preinit(void) | 26 | void __init ixdpg425_pci_preinit(void) |
31 | { | 27 | { |
32 | set_irq_type(IRQ_IXP4XX_GPIO6, IRQT_LOW); | 28 | set_irq_type(IRQ_IXP4XX_GPIO6, IRQT_LOW); |
diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c index 9a31444d9214..78a17413ceca 100644 --- a/arch/arm/mach-ixp4xx/nas100d-setup.c +++ b/arch/arm/mach-ixp4xx/nas100d-setup.c | |||
@@ -155,7 +155,8 @@ static void __init nas100d_init(void) | |||
155 | 155 | ||
156 | pm_power_off = nas100d_power_off; | 156 | pm_power_off = nas100d_power_off; |
157 | 157 | ||
158 | /* This is only useful on a modified machine, but it is valuable | 158 | /* |
159 | * This is only useful on a modified machine, but it is valuable | ||
159 | * to have it first in order to see debug messages, and so that | 160 | * to have it first in order to see debug messages, and so that |
160 | * it does *not* get removed if platform_add_devices fails! | 161 | * it does *not* get removed if platform_add_devices fails! |
161 | */ | 162 | */ |
diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c index 162c266e5f8f..9bf8ccbcaccf 100644 --- a/arch/arm/mach-ixp4xx/nslu2-setup.c +++ b/arch/arm/mach-ixp4xx/nslu2-setup.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <asm/mach-types.h> | 22 | #include <asm/mach-types.h> |
23 | #include <asm/mach/arch.h> | 23 | #include <asm/mach/arch.h> |
24 | #include <asm/mach/flash.h> | 24 | #include <asm/mach/flash.h> |
25 | #include <asm/mach/time.h> | ||
25 | 26 | ||
26 | static struct flash_platform_data nslu2_flash_data = { | 27 | static struct flash_platform_data nslu2_flash_data = { |
27 | .map_name = "cfi_probe", | 28 | .map_name = "cfi_probe", |
@@ -49,26 +50,26 @@ static struct ixp4xx_i2c_pins nslu2_i2c_gpio_pins = { | |||
49 | static struct resource nslu2_led_resources[] = { | 50 | static struct resource nslu2_led_resources[] = { |
50 | { | 51 | { |
51 | .name = "ready", /* green led */ | 52 | .name = "ready", /* green led */ |
52 | .start = NSLU2_LED_GRN, | 53 | .start = NSLU2_LED_GRN_GPIO, |
53 | .end = NSLU2_LED_GRN, | 54 | .end = NSLU2_LED_GRN_GPIO, |
54 | .flags = IXP4XX_GPIO_HIGH, | 55 | .flags = IXP4XX_GPIO_HIGH, |
55 | }, | 56 | }, |
56 | { | 57 | { |
57 | .name = "status", /* red led */ | 58 | .name = "status", /* red led */ |
58 | .start = NSLU2_LED_RED, | 59 | .start = NSLU2_LED_RED_GPIO, |
59 | .end = NSLU2_LED_RED, | 60 | .end = NSLU2_LED_RED_GPIO, |
60 | .flags = IXP4XX_GPIO_HIGH, | 61 | .flags = IXP4XX_GPIO_HIGH, |
61 | }, | 62 | }, |
62 | { | 63 | { |
63 | .name = "disk-1", | 64 | .name = "disk-1", |
64 | .start = NSLU2_LED_DISK1, | 65 | .start = NSLU2_LED_DISK1_GPIO, |
65 | .end = NSLU2_LED_DISK1, | 66 | .end = NSLU2_LED_DISK1_GPIO, |
66 | .flags = IXP4XX_GPIO_LOW, | 67 | .flags = IXP4XX_GPIO_LOW, |
67 | }, | 68 | }, |
68 | { | 69 | { |
69 | .name = "disk-2", | 70 | .name = "disk-2", |
70 | .start = NSLU2_LED_DISK2, | 71 | .start = NSLU2_LED_DISK2_GPIO, |
71 | .end = NSLU2_LED_DISK2, | 72 | .end = NSLU2_LED_DISK2_GPIO, |
72 | .flags = IXP4XX_GPIO_LOW, | 73 | .flags = IXP4XX_GPIO_LOW, |
73 | }, | 74 | }, |
74 | }; | 75 | }; |
@@ -157,10 +158,21 @@ static void nslu2_power_off(void) | |||
157 | gpio_line_set(NSLU2_PO_GPIO, IXP4XX_GPIO_HIGH); | 158 | gpio_line_set(NSLU2_PO_GPIO, IXP4XX_GPIO_HIGH); |
158 | } | 159 | } |
159 | 160 | ||
160 | static void __init nslu2_init(void) | 161 | static void __init nslu2_timer_init(void) |
161 | { | 162 | { |
162 | ixp4xx_timer_freq = NSLU2_FREQ; | 163 | /* The xtal on this machine is non-standard. */ |
164 | ixp4xx_timer_freq = NSLU2_FREQ; | ||
165 | |||
166 | /* Call standard timer_init function. */ | ||
167 | ixp4xx_timer_init(); | ||
168 | } | ||
163 | 169 | ||
170 | static struct sys_timer nslu2_timer = { | ||
171 | .init = nslu2_timer_init, | ||
172 | }; | ||
173 | |||
174 | static void __init nslu2_init(void) | ||
175 | { | ||
164 | ixp4xx_sys_init(); | 176 | ixp4xx_sys_init(); |
165 | 177 | ||
166 | nslu2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); | 178 | nslu2_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); |
@@ -169,7 +181,8 @@ static void __init nslu2_init(void) | |||
169 | 181 | ||
170 | pm_power_off = nslu2_power_off; | 182 | pm_power_off = nslu2_power_off; |
171 | 183 | ||
172 | /* This is only useful on a modified machine, but it is valuable | 184 | /* |
185 | * This is only useful on a modified machine, but it is valuable | ||
173 | * to have it first in order to see debug messages, and so that | 186 | * to have it first in order to see debug messages, and so that |
174 | * it does *not* get removed if platform_add_devices fails! | 187 | * it does *not* get removed if platform_add_devices fails! |
175 | */ | 188 | */ |
@@ -185,6 +198,6 @@ MACHINE_START(NSLU2, "Linksys NSLU2") | |||
185 | .boot_params = 0x00000100, | 198 | .boot_params = 0x00000100, |
186 | .map_io = ixp4xx_map_io, | 199 | .map_io = ixp4xx_map_io, |
187 | .init_irq = ixp4xx_init_irq, | 200 | .init_irq = ixp4xx_init_irq, |
188 | .timer = &ixp4xx_timer, | 201 | .timer = &nslu2_timer, |
189 | .init_machine = nslu2_init, | 202 | .init_machine = nslu2_init, |
190 | MACHINE_END | 203 | MACHINE_END |
diff --git a/arch/arm/mach-s3c2410/bast.h b/arch/arm/mach-s3c2410/bast.h deleted file mode 100644 index e98543742eb9..000000000000 --- a/arch/arm/mach-s3c2410/bast.h +++ /dev/null | |||
@@ -1,2 +0,0 @@ | |||
1 | /* linux/arch/arm/mach-s3c2410/bast.h | ||
2 | extern void bast_init_irq(void); | ||
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c index bc308ceb91c3..435adcce6482 100644 --- a/arch/arm/mach-s3c2410/mach-amlm5900.c +++ b/arch/arm/mach-s3c2410/mach-amlm5900.c | |||
@@ -160,7 +160,7 @@ static struct platform_device *amlm5900_devices[] __initdata = { | |||
160 | #endif | 160 | #endif |
161 | }; | 161 | }; |
162 | 162 | ||
163 | void __init amlm5900_map_io(void) | 163 | static void __init amlm5900_map_io(void) |
164 | { | 164 | { |
165 | s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc)); | 165 | s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc)); |
166 | s3c24xx_init_clocks(0); | 166 | s3c24xx_init_clocks(0); |
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c index c602aa39f9c4..782b5814ced2 100644 --- a/arch/arm/mach-s3c2412/s3c2412.c +++ b/arch/arm/mach-s3c2412/s3c2412.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/list.h> | 16 | #include <linux/list.h> |
17 | #include <linux/timer.h> | 17 | #include <linux/timer.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/delay.h> | ||
19 | #include <linux/sysdev.h> | 20 | #include <linux/sysdev.h> |
20 | #include <linux/serial_core.h> | 21 | #include <linux/serial_core.h> |
21 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
@@ -29,6 +30,7 @@ | |||
29 | #include <asm/io.h> | 30 | #include <asm/io.h> |
30 | #include <asm/irq.h> | 31 | #include <asm/irq.h> |
31 | 32 | ||
33 | #include <asm/arch/reset.h> | ||
32 | #include <asm/arch/idle.h> | 34 | #include <asm/arch/idle.h> |
33 | 35 | ||
34 | #include <asm/arch/regs-clock.h> | 36 | #include <asm/arch/regs-clock.h> |
@@ -38,6 +40,7 @@ | |||
38 | #include <asm/arch/regs-gpioj.h> | 40 | #include <asm/arch/regs-gpioj.h> |
39 | #include <asm/arch/regs-dsc.h> | 41 | #include <asm/arch/regs-dsc.h> |
40 | #include <asm/arch/regs-spi.h> | 42 | #include <asm/arch/regs-spi.h> |
43 | #include <asm/arch/regs-s3c2412.h> | ||
41 | 44 | ||
42 | #include <asm/plat-s3c24xx/s3c2412.h> | 45 | #include <asm/plat-s3c24xx/s3c2412.h> |
43 | #include <asm/plat-s3c24xx/cpu.h> | 46 | #include <asm/plat-s3c24xx/cpu.h> |
@@ -106,6 +109,23 @@ static void s3c2412_idle(void) | |||
106 | cpu_do_idle(); | 109 | cpu_do_idle(); |
107 | } | 110 | } |
108 | 111 | ||
112 | static void s3c2412_hard_reset(void) | ||
113 | { | ||
114 | /* errata "Watch-dog/Software Reset Problem" specifies that | ||
115 | * this reset must be done with the SYSCLK sourced from | ||
116 | * EXTCLK instead of FOUT to avoid a glitch in the reset | ||
117 | * mechanism. | ||
118 | * | ||
119 | * See the watchdog section of the S3C2412 manual for more | ||
120 | * information on this fix. | ||
121 | */ | ||
122 | |||
123 | __raw_writel(0x00, S3C2412_CLKSRC); | ||
124 | __raw_writel(S3C2412_SWRST_RESET, S3C2412_SWRST); | ||
125 | |||
126 | mdelay(1); | ||
127 | } | ||
128 | |||
109 | /* s3c2412_map_io | 129 | /* s3c2412_map_io |
110 | * | 130 | * |
111 | * register the standard cpu IO areas, and any passed in from the | 131 | * register the standard cpu IO areas, and any passed in from the |
@@ -122,6 +142,10 @@ void __init s3c2412_map_io(struct map_desc *mach_desc, int mach_size) | |||
122 | 142 | ||
123 | s3c24xx_idle = s3c2412_idle; | 143 | s3c24xx_idle = s3c2412_idle; |
124 | 144 | ||
145 | /* set custom reset hook */ | ||
146 | |||
147 | s3c24xx_reset_hook = s3c2412_hard_reset; | ||
148 | |||
125 | /* register our io-tables */ | 149 | /* register our io-tables */ |
126 | 150 | ||
127 | iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc)); | 151 | iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc)); |
diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c index b5d387ef37e1..bff7ddd06a52 100644 --- a/arch/arm/mach-s3c2440/mach-anubis.c +++ b/arch/arm/mach-s3c2440/mach-anubis.c | |||
@@ -76,8 +76,8 @@ static struct map_desc anubis_iodesc[] __initdata = { | |||
76 | .length = SZ_4K, | 76 | .length = SZ_4K, |
77 | .type = MT_DEVICE, | 77 | .type = MT_DEVICE, |
78 | }, { | 78 | }, { |
79 | .virtual = (u32)ANUBIS_VA_CTRL2, | 79 | .virtual = (u32)ANUBIS_VA_IDREG, |
80 | .pfn = __phys_to_pfn(ANUBIS_PA_CTRL2), | 80 | .pfn = __phys_to_pfn(ANUBIS_PA_IDREG), |
81 | .length = SZ_4K, | 81 | .length = SZ_4K, |
82 | .type = MT_DEVICE, | 82 | .type = MT_DEVICE, |
83 | }, | 83 | }, |
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c index 4d6c7a574c1a..15811601f03d 100644 --- a/arch/arm/mach-s3c2440/mach-osiris.c +++ b/arch/arm/mach-s3c2440/mach-osiris.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/timer.h> | 16 | #include <linux/timer.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/device.h> | 18 | #include <linux/device.h> |
19 | #include <linux/sysdev.h> | ||
19 | #include <linux/serial_core.h> | 20 | #include <linux/serial_core.h> |
20 | 21 | ||
21 | #include <asm/mach/arch.h> | 22 | #include <asm/mach/arch.h> |
@@ -65,6 +66,11 @@ static struct map_desc osiris_iodesc[] __initdata = { | |||
65 | /* CPLD control registers */ | 66 | /* CPLD control registers */ |
66 | 67 | ||
67 | { | 68 | { |
69 | .virtual = (u32)OSIRIS_VA_CTRL0, | ||
70 | .pfn = __phys_to_pfn(OSIRIS_PA_CTRL0), | ||
71 | .length = SZ_16K, | ||
72 | .type = MT_DEVICE, | ||
73 | }, { | ||
68 | .virtual = (u32)OSIRIS_VA_CTRL1, | 74 | .virtual = (u32)OSIRIS_VA_CTRL1, |
69 | .pfn = __phys_to_pfn(OSIRIS_PA_CTRL1), | 75 | .pfn = __phys_to_pfn(OSIRIS_PA_CTRL1), |
70 | .length = SZ_16K, | 76 | .length = SZ_16K, |
@@ -74,6 +80,11 @@ static struct map_desc osiris_iodesc[] __initdata = { | |||
74 | .pfn = __phys_to_pfn(OSIRIS_PA_CTRL2), | 80 | .pfn = __phys_to_pfn(OSIRIS_PA_CTRL2), |
75 | .length = SZ_16K, | 81 | .length = SZ_16K, |
76 | .type = MT_DEVICE, | 82 | .type = MT_DEVICE, |
83 | }, { | ||
84 | .virtual = (u32)OSIRIS_VA_IDREG, | ||
85 | .pfn = __phys_to_pfn(OSIRIS_PA_IDREG), | ||
86 | .length = SZ_16K, | ||
87 | .type = MT_DEVICE, | ||
77 | }, | 88 | }, |
78 | }; | 89 | }; |
79 | 90 | ||
@@ -195,13 +206,13 @@ static void osiris_nand_select(struct s3c2410_nand_set *set, int slot) | |||
195 | pr_debug("osiris_nand: selecting slot %d (set %p,%p)\n", | 206 | pr_debug("osiris_nand: selecting slot %d (set %p,%p)\n", |
196 | slot, set, set->nr_map); | 207 | slot, set, set->nr_map); |
197 | 208 | ||
198 | tmp = __raw_readb(OSIRIS_VA_CTRL1); | 209 | tmp = __raw_readb(OSIRIS_VA_CTRL0); |
199 | tmp &= ~OSIRIS_CTRL1_NANDSEL; | 210 | tmp &= ~OSIRIS_CTRL0_NANDSEL; |
200 | tmp |= slot; | 211 | tmp |= slot; |
201 | 212 | ||
202 | pr_debug("osiris_nand: ctrl1 now %02x\n", tmp); | 213 | pr_debug("osiris_nand: ctrl0 now %02x\n", tmp); |
203 | 214 | ||
204 | __raw_writeb(tmp, OSIRIS_VA_CTRL1); | 215 | __raw_writeb(tmp, OSIRIS_VA_CTRL0); |
205 | } | 216 | } |
206 | 217 | ||
207 | static struct s3c2410_platform_nand osiris_nand_info = { | 218 | static struct s3c2410_platform_nand osiris_nand_info = { |
@@ -235,10 +246,45 @@ static struct platform_device osiris_pcmcia = { | |||
235 | .resource = osiris_pcmcia_resource, | 246 | .resource = osiris_pcmcia_resource, |
236 | }; | 247 | }; |
237 | 248 | ||
249 | /* Osiris power management device */ | ||
250 | |||
251 | #ifdef CONFIG_PM | ||
252 | static unsigned char pm_osiris_ctrl0; | ||
253 | |||
254 | static int osiris_pm_suspend(struct sys_device *sd, pm_message_t state) | ||
255 | { | ||
256 | pm_osiris_ctrl0 = __raw_readb(OSIRIS_VA_CTRL0); | ||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | static int osiris_pm_resume(struct sys_device *sd) | ||
261 | { | ||
262 | if (pm_osiris_ctrl0 & OSIRIS_CTRL0_FIX8) | ||
263 | __raw_writeb(OSIRIS_CTRL1_FIX8, OSIRIS_VA_CTRL1); | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | |||
268 | #else | ||
269 | #define osiris_pm_suspend NULL | ||
270 | #define osiris_pm_resume NULL | ||
271 | #endif | ||
272 | |||
273 | static struct sysdev_class osiris_pm_sysclass = { | ||
274 | set_kset_name("mach-osiris"), | ||
275 | .suspend = osiris_pm_suspend, | ||
276 | .resume = osiris_pm_resume, | ||
277 | }; | ||
278 | |||
279 | static struct sys_device osiris_pm_sysdev = { | ||
280 | .cls = &osiris_pm_sysclass, | ||
281 | }; | ||
282 | |||
238 | /* Standard Osiris devices */ | 283 | /* Standard Osiris devices */ |
239 | 284 | ||
240 | static struct platform_device *osiris_devices[] __initdata = { | 285 | static struct platform_device *osiris_devices[] __initdata = { |
241 | &s3c_device_i2c, | 286 | &s3c_device_i2c, |
287 | &s3c_device_wdt, | ||
242 | &s3c_device_nand, | 288 | &s3c_device_nand, |
243 | &osiris_pcmcia, | 289 | &osiris_pcmcia, |
244 | }; | 290 | }; |
@@ -288,6 +334,9 @@ static void __init osiris_map_io(void) | |||
288 | 334 | ||
289 | static void __init osiris_init(void) | 335 | static void __init osiris_init(void) |
290 | { | 336 | { |
337 | sysdev_class_register(&osiris_pm_sysclass); | ||
338 | sysdev_register(&osiris_pm_sysdev); | ||
339 | |||
291 | platform_add_devices(osiris_devices, ARRAY_SIZE(osiris_devices)); | 340 | platform_add_devices(osiris_devices, ARRAY_SIZE(osiris_devices)); |
292 | }; | 341 | }; |
293 | 342 | ||
@@ -299,5 +348,6 @@ MACHINE_START(OSIRIS, "Simtec-OSIRIS") | |||
299 | .map_io = osiris_map_io, | 348 | .map_io = osiris_map_io, |
300 | .init_machine = osiris_init, | 349 | .init_machine = osiris_init, |
301 | .init_irq = s3c24xx_init_irq, | 350 | .init_irq = s3c24xx_init_irq, |
351 | .init_machine = osiris_init, | ||
302 | .timer = &s3c24xx_timer, | 352 | .timer = &s3c24xx_timer, |
303 | MACHINE_END | 353 | MACHINE_END |
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c index 5955efb5de8d..58402948c47c 100644 --- a/arch/arm/mach-s3c2443/clock.c +++ b/arch/arm/mach-s3c2443/clock.c | |||
@@ -394,7 +394,7 @@ static int s3c2443_setrate_usbhost(struct clk *clk, unsigned long rate) | |||
394 | return 0; | 394 | return 0; |
395 | } | 395 | } |
396 | 396 | ||
397 | struct clk clk_usb_bus_host = { | 397 | static struct clk clk_usb_bus_host = { |
398 | .name = "usb-bus-host-parent", | 398 | .name = "usb-bus-host-parent", |
399 | .id = -1, | 399 | .id = -1, |
400 | .parent = &clk_esysclk, | 400 | .parent = &clk_esysclk, |
@@ -758,7 +758,6 @@ static struct clk init_clocks[] = { | |||
758 | .parent = &clk_h, | 758 | .parent = &clk_h, |
759 | .enable = s3c2443_clkcon_enable_h, | 759 | .enable = s3c2443_clkcon_enable_h, |
760 | .ctrlbit = S3C2443_HCLKCON_CFC, | 760 | .ctrlbit = S3C2443_HCLKCON_CFC, |
761 | .ctrlbit = S3C2443_HCLKCON_HSMMC, | ||
762 | }, { | 761 | }, { |
763 | .name = "ssmc", | 762 | .name = "ssmc", |
764 | .id = -1, | 763 | .id = -1, |
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index d7c038a0256b..4cbf9468f654 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c | |||
@@ -139,12 +139,12 @@ static u_int neponset_get_mctrl(struct uart_port *port) | |||
139 | return ret; | 139 | return ret; |
140 | } | 140 | } |
141 | 141 | ||
142 | static struct sa1100_port_fns neponset_port_fns __initdata = { | 142 | static struct sa1100_port_fns neponset_port_fns __devinitdata = { |
143 | .set_mctrl = neponset_set_mctrl, | 143 | .set_mctrl = neponset_set_mctrl, |
144 | .get_mctrl = neponset_get_mctrl, | 144 | .get_mctrl = neponset_get_mctrl, |
145 | }; | 145 | }; |
146 | 146 | ||
147 | static int neponset_probe(struct platform_device *dev) | 147 | static int __devinit neponset_probe(struct platform_device *dev) |
148 | { | 148 | { |
149 | sa1100_register_uart_fns(&neponset_port_fns); | 149 | sa1100_register_uart_fns(&neponset_port_fns); |
150 | 150 | ||
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 5f472a8b406a..e7904bc92c73 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -379,7 +379,7 @@ config CPU_V7 | |||
379 | select CPU_CP15_MMU | 379 | select CPU_CP15_MMU |
380 | select CPU_HAS_ASID | 380 | select CPU_HAS_ASID |
381 | select CPU_COPY_V6 if MMU | 381 | select CPU_COPY_V6 if MMU |
382 | select CPU_TLB_V6 if MMU | 382 | select CPU_TLB_V7 if MMU |
383 | 383 | ||
384 | # Figure out what processor architecture version we should be using. | 384 | # Figure out what processor architecture version we should be using. |
385 | # This defines the compiler instruction set which depends on the machine type. | 385 | # This defines the compiler instruction set which depends on the machine type. |
@@ -498,6 +498,9 @@ config CPU_TLB_V4WBI | |||
498 | config CPU_TLB_V6 | 498 | config CPU_TLB_V6 |
499 | bool | 499 | bool |
500 | 500 | ||
501 | config CPU_TLB_V7 | ||
502 | bool | ||
503 | |||
501 | endif | 504 | endif |
502 | 505 | ||
503 | config CPU_HAS_ASID | 506 | config CPU_HAS_ASID |
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index b5bd335ff14a..762702765fc3 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile | |||
@@ -46,6 +46,7 @@ obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o | |||
46 | obj-$(CONFIG_CPU_TLB_V4WB) += tlb-v4wb.o | 46 | obj-$(CONFIG_CPU_TLB_V4WB) += tlb-v4wb.o |
47 | obj-$(CONFIG_CPU_TLB_V4WBI) += tlb-v4wbi.o | 47 | obj-$(CONFIG_CPU_TLB_V4WBI) += tlb-v4wbi.o |
48 | obj-$(CONFIG_CPU_TLB_V6) += tlb-v6.o | 48 | obj-$(CONFIG_CPU_TLB_V6) += tlb-v6.o |
49 | obj-$(CONFIG_CPU_TLB_V7) += tlb-v7.o | ||
49 | 50 | ||
50 | obj-$(CONFIG_CPU_ARM610) += proc-arm6_7.o | 51 | obj-$(CONFIG_CPU_ARM610) += proc-arm6_7.o |
51 | obj-$(CONFIG_CPU_ARM710) += proc-arm6_7.o | 52 | obj-$(CONFIG_CPU_ARM710) += proc-arm6_7.o |
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 36440c899583..074b7cb07743 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c | |||
@@ -630,7 +630,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
630 | 630 | ||
631 | fs = get_fs(); | 631 | fs = get_fs(); |
632 | set_fs(KERNEL_DS); | 632 | set_fs(KERNEL_DS); |
633 | if thumb_mode(regs) { | 633 | if (thumb_mode(regs)) { |
634 | fault = __get_user(tinstr, (u16 *)(instrptr & ~1)); | 634 | fault = __get_user(tinstr, (u16 *)(instrptr & ~1)); |
635 | if (!(fault)) | 635 | if (!(fault)) |
636 | instr = thumb2arm(tinstr); | 636 | instr = thumb2arm(tinstr); |
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index dd823dd4a374..718f4782ee8b 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S | |||
@@ -256,7 +256,7 @@ __v7_proc_info: | |||
256 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP | 256 | .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP |
257 | .long cpu_v7_name | 257 | .long cpu_v7_name |
258 | .long v7_processor_functions | 258 | .long v7_processor_functions |
259 | .long v6wbi_tlb_fns | 259 | .long v7wbi_tlb_fns |
260 | .long v6_user_fns | 260 | .long v6_user_fns |
261 | .long v7_cache_fns | 261 | .long v7_cache_fns |
262 | .size __v7_proc_info, . - __v7_proc_info | 262 | .size __v7_proc_info, . - __v7_proc_info |
diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S new file mode 100644 index 000000000000..b56dda8052f7 --- /dev/null +++ b/arch/arm/mm/tlb-v7.S | |||
@@ -0,0 +1,88 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/mm/tlb-v7.S | ||
3 | * | ||
4 | * Copyright (C) 1997-2002 Russell King | ||
5 | * Modified for ARMv7 by Catalin Marinas | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * ARM architecture version 6 TLB handling functions. | ||
12 | * These assume a split I/D TLB. | ||
13 | */ | ||
14 | #include <linux/linkage.h> | ||
15 | #include <asm/asm-offsets.h> | ||
16 | #include <asm/page.h> | ||
17 | #include <asm/tlbflush.h> | ||
18 | #include "proc-macros.S" | ||
19 | |||
20 | /* | ||
21 | * v7wbi_flush_user_tlb_range(start, end, vma) | ||
22 | * | ||
23 | * Invalidate a range of TLB entries in the specified address space. | ||
24 | * | ||
25 | * - start - start address (may not be aligned) | ||
26 | * - end - end address (exclusive, may not be aligned) | ||
27 | * - vma - vma_struct describing address range | ||
28 | * | ||
29 | * It is assumed that: | ||
30 | * - the "Invalidate single entry" instruction will invalidate | ||
31 | * both the I and the D TLBs on Harvard-style TLBs | ||
32 | */ | ||
33 | ENTRY(v7wbi_flush_user_tlb_range) | ||
34 | vma_vm_mm r3, r2 @ get vma->vm_mm | ||
35 | mmid r3, r3 @ get vm_mm->context.id | ||
36 | dsb | ||
37 | mov r0, r0, lsr #PAGE_SHIFT @ align address | ||
38 | mov r1, r1, lsr #PAGE_SHIFT | ||
39 | asid r3, r3 @ mask ASID | ||
40 | orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA | ||
41 | mov r1, r1, lsl #PAGE_SHIFT | ||
42 | vma_vm_flags r2, r2 @ get vma->vm_flags | ||
43 | 1: | ||
44 | mcr p15, 0, r0, c8, c6, 1 @ TLB invalidate D MVA (was 1) | ||
45 | tst r2, #VM_EXEC @ Executable area ? | ||
46 | mcrne p15, 0, r0, c8, c5, 1 @ TLB invalidate I MVA (was 1) | ||
47 | add r0, r0, #PAGE_SZ | ||
48 | cmp r0, r1 | ||
49 | blo 1b | ||
50 | mov ip, #0 | ||
51 | mcr p15, 0, ip, c7, c5, 6 @ flush BTAC/BTB | ||
52 | dsb | ||
53 | mov pc, lr | ||
54 | |||
55 | /* | ||
56 | * v7wbi_flush_kern_tlb_range(start,end) | ||
57 | * | ||
58 | * Invalidate a range of kernel TLB entries | ||
59 | * | ||
60 | * - start - start address (may not be aligned) | ||
61 | * - end - end address (exclusive, may not be aligned) | ||
62 | */ | ||
63 | ENTRY(v7wbi_flush_kern_tlb_range) | ||
64 | dsb | ||
65 | mov r0, r0, lsr #PAGE_SHIFT @ align address | ||
66 | mov r1, r1, lsr #PAGE_SHIFT | ||
67 | mov r0, r0, lsl #PAGE_SHIFT | ||
68 | mov r1, r1, lsl #PAGE_SHIFT | ||
69 | 1: | ||
70 | mcr p15, 0, r0, c8, c6, 1 @ TLB invalidate D MVA | ||
71 | mcr p15, 0, r0, c8, c5, 1 @ TLB invalidate I MVA | ||
72 | add r0, r0, #PAGE_SZ | ||
73 | cmp r0, r1 | ||
74 | blo 1b | ||
75 | mov r2, #0 | ||
76 | mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB | ||
77 | dsb | ||
78 | isb | ||
79 | mov pc, lr | ||
80 | |||
81 | .section ".text.init", #alloc, #execinstr | ||
82 | |||
83 | .type v7wbi_tlb_fns, #object | ||
84 | ENTRY(v7wbi_tlb_fns) | ||
85 | .long v7wbi_flush_user_tlb_range | ||
86 | .long v7wbi_flush_kern_tlb_range | ||
87 | .long v6wbi_tlb_flags | ||
88 | .size v7wbi_tlb_fns, . - v7wbi_tlb_fns | ||
diff --git a/arch/arm/nwfpe/softfloat.h b/arch/arm/nwfpe/softfloat.h index 0a3067452cd2..260fe29d73f5 100644 --- a/arch/arm/nwfpe/softfloat.h +++ b/arch/arm/nwfpe/softfloat.h | |||
@@ -273,4 +273,7 @@ static inline flag float64_lt_nocheck(float64 a, float64 b) | |||
273 | extern flag float32_is_nan( float32 a ); | 273 | extern flag float32_is_nan( float32 a ); |
274 | extern flag float64_is_nan( float64 a ); | 274 | extern flag float64_is_nan( float64 a ); |
275 | 275 | ||
276 | extern int32 float64_to_uint32( struct roundingData *roundData, float64 a ); | ||
277 | extern int32 float64_to_uint32_round_to_zero( float64 a ); | ||
278 | |||
276 | #endif | 279 | #endif |
diff --git a/arch/arm/oprofile/op_model_mpcore.c b/arch/arm/oprofile/op_model_mpcore.c index 898500718249..75bae067922d 100644 --- a/arch/arm/oprofile/op_model_mpcore.c +++ b/arch/arm/oprofile/op_model_mpcore.c | |||
@@ -200,8 +200,10 @@ static int em_call_function(int (*fn)(void)) | |||
200 | data.fn = fn; | 200 | data.fn = fn; |
201 | data.ret = 0; | 201 | data.ret = 0; |
202 | 202 | ||
203 | preempt_disable(); | ||
203 | smp_call_function(em_func, &data, 1, 1); | 204 | smp_call_function(em_func, &data, 1, 1); |
204 | em_func(&data); | 205 | em_func(&data); |
206 | preempt_enable(); | ||
205 | 207 | ||
206 | return data.ret; | 208 | return data.ret; |
207 | } | 209 | } |
@@ -257,8 +259,13 @@ static void em_stop(void) | |||
257 | */ | 259 | */ |
258 | static void em_route_irq(int irq, unsigned int cpu) | 260 | static void em_route_irq(int irq, unsigned int cpu) |
259 | { | 261 | { |
260 | irq_desc[irq].affinity = cpumask_of_cpu(cpu); | 262 | struct irq_desc *desc = irq_desc + irq; |
261 | irq_desc[irq].chip->set_affinity(irq, cpumask_of_cpu(cpu)); | 263 | cpumask_t mask = cpumask_of_cpu(cpu); |
264 | |||
265 | spin_lock_irq(&desc->lock); | ||
266 | desc->affinity = mask; | ||
267 | desc->chip->set_affinity(irq, mask); | ||
268 | spin_unlock_irq(&desc->lock); | ||
262 | } | 269 | } |
263 | 270 | ||
264 | static int em_setup(void) | 271 | static int em_setup(void) |
diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S index ca2a5ad19ea6..806ce26d5243 100644 --- a/arch/arm/vfp/entry.S +++ b/arch/arm/vfp/entry.S | |||
@@ -29,6 +29,10 @@ do_vfp: | |||
29 | add r10, r10, #TI_VFPSTATE @ r10 = workspace | 29 | add r10, r10, #TI_VFPSTATE @ r10 = workspace |
30 | ldr pc, [r4] @ call VFP entry point | 30 | ldr pc, [r4] @ call VFP entry point |
31 | 31 | ||
32 | ENTRY(vfp_null_entry) | ||
33 | mov pc, lr | ||
34 | ENDPROC(vfp_null_entry) | ||
35 | |||
32 | .LCvfp: | 36 | .LCvfp: |
33 | .word vfp_vector | 37 | .word vfp_vector |
34 | 38 | ||
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index f1e5951dc721..1106b5f9cf19 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
@@ -26,8 +26,9 @@ | |||
26 | */ | 26 | */ |
27 | void vfp_testing_entry(void); | 27 | void vfp_testing_entry(void); |
28 | void vfp_support_entry(void); | 28 | void vfp_support_entry(void); |
29 | void vfp_null_entry(void); | ||
29 | 30 | ||
30 | void (*vfp_vector)(void) = vfp_testing_entry; | 31 | void (*vfp_vector)(void) = vfp_null_entry; |
31 | union vfp_state *last_VFP_context[NR_CPUS]; | 32 | union vfp_state *last_VFP_context[NR_CPUS]; |
32 | 33 | ||
33 | /* | 34 | /* |
@@ -321,8 +322,10 @@ static int __init vfp_init(void) | |||
321 | * The handler is already setup to just log calls, so | 322 | * The handler is already setup to just log calls, so |
322 | * we just need to read the VFPSID register. | 323 | * we just need to read the VFPSID register. |
323 | */ | 324 | */ |
325 | vfp_vector = vfp_testing_entry; | ||
324 | vfpsid = fmrx(FPSID); | 326 | vfpsid = fmrx(FPSID); |
325 | barrier(); | 327 | barrier(); |
328 | vfp_vector = vfp_null_entry; | ||
326 | 329 | ||
327 | printk(KERN_INFO "VFP support v0.3: "); | 330 | printk(KERN_INFO "VFP support v0.3: "); |
328 | if (VFP_arch) { | 331 | if (VFP_arch) { |
diff --git a/arch/h8300/kernel/sys_h8300.c b/arch/h8300/kernel/sys_h8300.c index 11ba75a05220..de7688cfd573 100644 --- a/arch/h8300/kernel/sys_h8300.c +++ b/arch/h8300/kernel/sys_h8300.c | |||
@@ -288,9 +288,9 @@ asmlinkage void syscall_print(void *dummy,...) | |||
288 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]) | 288 | int kernel_execve(const char *filename, char *const argv[], char *const envp[]) |
289 | { | 289 | { |
290 | register long res __asm__("er0"); | 290 | register long res __asm__("er0"); |
291 | register char *const *_c __asm__("er3") = envp; | ||
292 | register char *const *_b __asm__("er2") = argv; | ||
291 | register const char * _a __asm__("er1") = filename; | 293 | register const char * _a __asm__("er1") = filename; |
292 | register void *_b __asm__("er2") = argv; | ||
293 | register void *_c __asm__("er3") = envp; | ||
294 | __asm__ __volatile__ ("mov.l %1,er0\n\t" | 294 | __asm__ __volatile__ ("mov.l %1,er0\n\t" |
295 | "trapa #0\n\t" | 295 | "trapa #0\n\t" |
296 | : "=r" (res) | 296 | : "=r" (res) |
diff --git a/arch/h8300/kernel/traps.c b/arch/h8300/kernel/traps.c index 300e3279ca5a..f97183011c2c 100644 --- a/arch/h8300/kernel/traps.c +++ b/arch/h8300/kernel/traps.c | |||
@@ -136,7 +136,7 @@ void show_stack(struct task_struct *task, unsigned long *esp) | |||
136 | printk("\nCall Trace:"); | 136 | printk("\nCall Trace:"); |
137 | i = 0; | 137 | i = 0; |
138 | stack = esp; | 138 | stack = esp; |
139 | while (((unsigned long)stack & (THREAD_SIZE - 1)) == 0) { | 139 | while (((unsigned long)stack & (THREAD_SIZE - 1)) != 0) { |
140 | addr = *stack++; | 140 | addr = *stack++; |
141 | /* | 141 | /* |
142 | * If the address is either in the text segment of the | 142 | * If the address is either in the text segment of the |
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index c2d54b802232..8770a5d0b143 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig | |||
@@ -891,7 +891,7 @@ config PHYSICAL_ALIGN | |||
891 | Don't change this unless you know what you are doing. | 891 | Don't change this unless you know what you are doing. |
892 | 892 | ||
893 | config HOTPLUG_CPU | 893 | config HOTPLUG_CPU |
894 | bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" | 894 | bool "Support for suspend on SMP and hot-pluggable CPUs (EXPERIMENTAL)" |
895 | depends on SMP && HOTPLUG && EXPERIMENTAL && !X86_VOYAGER | 895 | depends on SMP && HOTPLUG && EXPERIMENTAL && !X86_VOYAGER |
896 | ---help--- | 896 | ---help--- |
897 | Say Y here to experiment with turning CPUs off and on, and to | 897 | Say Y here to experiment with turning CPUs off and on, and to |
diff --git a/arch/i386/kernel/cpu/mtrr/main.c b/arch/i386/kernel/cpu/mtrr/main.c index 1cf466df330a..7202b98aac4f 100644 --- a/arch/i386/kernel/cpu/mtrr/main.c +++ b/arch/i386/kernel/cpu/mtrr/main.c | |||
@@ -734,10 +734,13 @@ void mtrr_ap_init(void) | |||
734 | */ | 734 | */ |
735 | void mtrr_save_state(void) | 735 | void mtrr_save_state(void) |
736 | { | 736 | { |
737 | if (smp_processor_id() == 0) | 737 | int cpu = get_cpu(); |
738 | |||
739 | if (cpu == 0) | ||
738 | mtrr_save_fixed_ranges(NULL); | 740 | mtrr_save_fixed_ranges(NULL); |
739 | else | 741 | else |
740 | smp_call_function_single(0, mtrr_save_fixed_ranges, NULL, 1, 1); | 742 | smp_call_function_single(0, mtrr_save_fixed_ranges, NULL, 1, 1); |
743 | put_cpu(); | ||
741 | } | 744 | } |
742 | 745 | ||
743 | static int __init mtrr_init_finialize(void) | 746 | static int __init mtrr_init_finialize(void) |
diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c index 83f825f2e2d7..d865d041bea1 100644 --- a/arch/i386/kernel/microcode.c +++ b/arch/i386/kernel/microcode.c | |||
@@ -478,7 +478,7 @@ static int __init microcode_dev_init (void) | |||
478 | return 0; | 478 | return 0; |
479 | } | 479 | } |
480 | 480 | ||
481 | static void __exit microcode_dev_exit (void) | 481 | static void microcode_dev_exit (void) |
482 | { | 482 | { |
483 | misc_deregister(µcode_dev); | 483 | misc_deregister(µcode_dev); |
484 | } | 484 | } |
diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c index 50dfc65319cd..5513f8d5b5be 100644 --- a/arch/i386/kernel/reboot.c +++ b/arch/i386/kernel/reboot.c | |||
@@ -89,6 +89,14 @@ static int __init set_bios_reboot(struct dmi_system_id *d) | |||
89 | } | 89 | } |
90 | 90 | ||
91 | static struct dmi_system_id __initdata reboot_dmi_table[] = { | 91 | static struct dmi_system_id __initdata reboot_dmi_table[] = { |
92 | { /* Handle problems with rebooting on Dell E520's */ | ||
93 | .callback = set_bios_reboot, | ||
94 | .ident = "Dell E520", | ||
95 | .matches = { | ||
96 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
97 | DMI_MATCH(DMI_PRODUCT_NAME, "Dell DM061"), | ||
98 | }, | ||
99 | }, | ||
92 | { /* Handle problems with rebooting on Dell 1300's */ | 100 | { /* Handle problems with rebooting on Dell 1300's */ |
93 | .callback = set_bios_reboot, | 101 | .callback = set_bios_reboot, |
94 | .ident = "Dell PowerEdge 1300", | 102 | .ident = "Dell PowerEdge 1300", |
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 08f07a74a9d3..88baed1e7e83 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c | |||
@@ -943,10 +943,9 @@ exit: | |||
943 | 943 | ||
944 | static void smp_tune_scheduling(void) | 944 | static void smp_tune_scheduling(void) |
945 | { | 945 | { |
946 | unsigned long cachesize; /* kB */ | ||
947 | |||
948 | if (cpu_khz) { | 946 | if (cpu_khz) { |
949 | cachesize = boot_cpu_data.x86_cache_size; | 947 | /* cache size in kB */ |
948 | long cachesize = boot_cpu_data.x86_cache_size; | ||
950 | 949 | ||
951 | if (cachesize > 0) | 950 | if (cachesize > 0) |
952 | max_cache_size = cachesize * 1024; | 951 | max_cache_size = cachesize * 1024; |
diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index c8726c424b35..c12720d7cbc5 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/bootmem.h> | 27 | #include <linux/bootmem.h> |
28 | #include <linux/mm.h> | 28 | #include <linux/mm.h> |
29 | #include <linux/highmem.h> | 29 | #include <linux/highmem.h> |
30 | #include <linux/sched.h> | ||
30 | #include <asm/vmi.h> | 31 | #include <asm/vmi.h> |
31 | #include <asm/io.h> | 32 | #include <asm/io.h> |
32 | #include <asm/fixmap.h> | 33 | #include <asm/fixmap.h> |
diff --git a/arch/i386/mach-generic/bigsmp.c b/arch/i386/mach-generic/bigsmp.c index e932d3485ae2..58a477baec30 100644 --- a/arch/i386/mach-generic/bigsmp.c +++ b/arch/i386/mach-generic/bigsmp.c | |||
@@ -21,7 +21,7 @@ | |||
21 | 21 | ||
22 | static int dmi_bigsmp; /* can be set by dmi scanners */ | 22 | static int dmi_bigsmp; /* can be set by dmi scanners */ |
23 | 23 | ||
24 | static __init int hp_ht_bigsmp(struct dmi_system_id *d) | 24 | static int hp_ht_bigsmp(struct dmi_system_id *d) |
25 | { | 25 | { |
26 | #ifdef CONFIG_X86_GENERICARCH | 26 | #ifdef CONFIG_X86_GENERICARCH |
27 | printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident); | 27 | printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident); |
@@ -31,7 +31,7 @@ static __init int hp_ht_bigsmp(struct dmi_system_id *d) | |||
31 | } | 31 | } |
32 | 32 | ||
33 | 33 | ||
34 | static struct dmi_system_id __initdata bigsmp_dmi_table[] = { | 34 | static struct dmi_system_id bigsmp_dmi_table[] = { |
35 | { hp_ht_bigsmp, "HP ProLiant DL760 G2", { | 35 | { hp_ht_bigsmp, "HP ProLiant DL760 G2", { |
36 | DMI_MATCH(DMI_BIOS_VENDOR, "HP"), | 36 | DMI_MATCH(DMI_BIOS_VENDOR, "HP"), |
37 | DMI_MATCH(DMI_BIOS_VERSION, "P44-"), | 37 | DMI_MATCH(DMI_BIOS_VERSION, "P44-"), |
@@ -45,7 +45,7 @@ static struct dmi_system_id __initdata bigsmp_dmi_table[] = { | |||
45 | }; | 45 | }; |
46 | 46 | ||
47 | 47 | ||
48 | static int __init probe_bigsmp(void) | 48 | static int probe_bigsmp(void) |
49 | { | 49 | { |
50 | if (def_to_bigsmp) | 50 | if (def_to_bigsmp) |
51 | dmi_bigsmp = 1; | 51 | dmi_bigsmp = 1; |
diff --git a/arch/i386/math-emu/fpu_entry.c b/arch/i386/math-emu/fpu_entry.c index ddf8fa3bbd01..1853524c8b57 100644 --- a/arch/i386/math-emu/fpu_entry.c +++ b/arch/i386/math-emu/fpu_entry.c | |||
@@ -754,7 +754,7 @@ int save_i387_soft(void *s387, struct _fpstate __user * buf) | |||
754 | return -1; | 754 | return -1; |
755 | if ( offset ) | 755 | if ( offset ) |
756 | if (__copy_to_user(d+other, (u_char *)&S387->st_space, offset)) | 756 | if (__copy_to_user(d+other, (u_char *)&S387->st_space, offset)) |
757 | return -1 | 757 | return -1; |
758 | RE_ENTRANT_CHECK_ON; | 758 | RE_ENTRANT_CHECK_ON; |
759 | 759 | ||
760 | return 1; | 760 | return 1; |
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index 29d7d61543a1..1ecb3e43b523 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c | |||
@@ -458,6 +458,11 @@ bad_area: | |||
458 | bad_area_nosemaphore: | 458 | bad_area_nosemaphore: |
459 | /* User mode accesses just cause a SIGSEGV */ | 459 | /* User mode accesses just cause a SIGSEGV */ |
460 | if (error_code & 4) { | 460 | if (error_code & 4) { |
461 | /* | ||
462 | * It's possible to have interrupts off here. | ||
463 | */ | ||
464 | local_irq_enable(); | ||
465 | |||
461 | /* | 466 | /* |
462 | * Valid to do another page fault here because this one came | 467 | * Valid to do another page fault here because this one came |
463 | * from user space. | 468 | * from user space. |
diff --git a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c index a7c0783b269a..11b7a51566a8 100644 --- a/arch/i386/oprofile/nmi_int.c +++ b/arch/i386/oprofile/nmi_int.c | |||
@@ -154,7 +154,7 @@ static int allocate_msrs(void) | |||
154 | size_t counters_size = sizeof(struct op_msr) * model->num_counters; | 154 | size_t counters_size = sizeof(struct op_msr) * model->num_counters; |
155 | 155 | ||
156 | int i; | 156 | int i; |
157 | for_each_online_cpu(i) { | 157 | for_each_possible_cpu(i) { |
158 | cpu_msrs[i].counters = kmalloc(counters_size, GFP_KERNEL); | 158 | cpu_msrs[i].counters = kmalloc(counters_size, GFP_KERNEL); |
159 | if (!cpu_msrs[i].counters) { | 159 | if (!cpu_msrs[i].counters) { |
160 | success = 0; | 160 | success = 0; |
@@ -211,8 +211,14 @@ static int nmi_setup(void) | |||
211 | /* Assume saved/restored counters are the same on all CPUs */ | 211 | /* Assume saved/restored counters are the same on all CPUs */ |
212 | model->fill_in_addresses(&cpu_msrs[0]); | 212 | model->fill_in_addresses(&cpu_msrs[0]); |
213 | for_each_possible_cpu (cpu) { | 213 | for_each_possible_cpu (cpu) { |
214 | if (cpu != 0) | 214 | if (cpu != 0) { |
215 | cpu_msrs[cpu] = cpu_msrs[0]; | 215 | memcpy(cpu_msrs[cpu].counters, cpu_msrs[0].counters, |
216 | sizeof(struct op_msr) * model->num_counters); | ||
217 | |||
218 | memcpy(cpu_msrs[cpu].controls, cpu_msrs[0].controls, | ||
219 | sizeof(struct op_msr) * model->num_controls); | ||
220 | } | ||
221 | |||
216 | } | 222 | } |
217 | on_each_cpu(nmi_save_registers, NULL, 0, 1); | 223 | on_each_cpu(nmi_save_registers, NULL, 0, 1); |
218 | on_each_cpu(nmi_cpu_setup, NULL, 0, 1); | 224 | on_each_cpu(nmi_cpu_setup, NULL, 0, 1); |
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c index b62eafb997bc..b95b42950ed4 100644 --- a/arch/i386/pci/fixup.c +++ b/arch/i386/pci/fixup.c | |||
@@ -436,3 +436,14 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, | |||
436 | pci_early_fixup_cyrix_5530); | 436 | pci_early_fixup_cyrix_5530); |
437 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, | 437 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY, |
438 | pci_early_fixup_cyrix_5530); | 438 | pci_early_fixup_cyrix_5530); |
439 | |||
440 | /* | ||
441 | * Siemens Nixdorf AG FSC Multiprocessor Interrupt Controller: | ||
442 | * prevent update of the BAR0, which doesn't look like a normal BAR. | ||
443 | */ | ||
444 | static void __devinit pci_siemens_interrupt_controller(struct pci_dev *dev) | ||
445 | { | ||
446 | dev->resource[0].flags |= IORESOURCE_PCI_FIXED; | ||
447 | } | ||
448 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SIEMENS, 0x0015, | ||
449 | pci_siemens_interrupt_controller); | ||
diff --git a/arch/ia64/kernel/acpi-processor.c b/arch/ia64/kernel/acpi-processor.c index 4d4993a47e55..5a216c019924 100644 --- a/arch/ia64/kernel/acpi-processor.c +++ b/arch/ia64/kernel/acpi-processor.c | |||
@@ -44,7 +44,7 @@ static void init_intel_pdc(struct acpi_processor *pr) | |||
44 | 44 | ||
45 | buf[0] = ACPI_PDC_REVISION_ID; | 45 | buf[0] = ACPI_PDC_REVISION_ID; |
46 | buf[1] = 1; | 46 | buf[1] = 1; |
47 | buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP; | 47 | buf[2] = ACPI_PDC_EST_CAPABILITY_SMP; |
48 | 48 | ||
49 | obj->type = ACPI_TYPE_BUFFER; | 49 | obj->type = ACPI_TYPE_BUFFER; |
50 | obj->buffer.length = 12; | 50 | obj->buffer.length = 12; |
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index c4784494970e..103dd8edda71 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c | |||
@@ -67,7 +67,8 @@ EXPORT_SYMBOL(pm_power_off); | |||
67 | unsigned int acpi_cpei_override; | 67 | unsigned int acpi_cpei_override; |
68 | unsigned int acpi_cpei_phys_cpuid; | 68 | unsigned int acpi_cpei_phys_cpuid; |
69 | 69 | ||
70 | const char *acpi_get_sysname(void) | 70 | const char __init * |
71 | acpi_get_sysname(void) | ||
71 | { | 72 | { |
72 | #ifdef CONFIG_IA64_GENERIC | 73 | #ifdef CONFIG_IA64_GENERIC |
73 | unsigned long rsdp_phys; | 74 | unsigned long rsdp_phys; |
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index d1c3ed9943e5..af73b8dfde28 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c | |||
@@ -763,6 +763,9 @@ get_wchan (struct task_struct *p) | |||
763 | unsigned long ip; | 763 | unsigned long ip; |
764 | int count = 0; | 764 | int count = 0; |
765 | 765 | ||
766 | if (!p || p == current || p->state == TASK_RUNNING) | ||
767 | return 0; | ||
768 | |||
766 | /* | 769 | /* |
767 | * Note: p may not be a blocked task (it could be current or | 770 | * Note: p may not be a blocked task (it could be current or |
768 | * another process running on some other CPU. Rather than | 771 | * another process running on some other CPU. Rather than |
@@ -773,6 +776,8 @@ get_wchan (struct task_struct *p) | |||
773 | */ | 776 | */ |
774 | unw_init_from_blocked_task(&info, p); | 777 | unw_init_from_blocked_task(&info, p); |
775 | do { | 778 | do { |
779 | if (p->state == TASK_RUNNING) | ||
780 | return 0; | ||
776 | if (unw_unwind(&info) < 0) | 781 | if (unw_unwind(&info) < 0) |
777 | return 0; | 782 | return 0; |
778 | unw_get_ip(&info, &ip); | 783 | unw_get_ip(&info, &ip); |
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 542958079f1b..3c9d8e6089cf 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c | |||
@@ -370,7 +370,7 @@ smp_setup_percpu_timer (void) | |||
370 | { | 370 | { |
371 | } | 371 | } |
372 | 372 | ||
373 | static void __devinit | 373 | static void __cpuinit |
374 | smp_callin (void) | 374 | smp_callin (void) |
375 | { | 375 | { |
376 | int cpuid, phys_id, itc_master; | 376 | int cpuid, phys_id, itc_master; |
@@ -456,7 +456,7 @@ smp_callin (void) | |||
456 | /* | 456 | /* |
457 | * Activate a secondary processor. head.S calls this. | 457 | * Activate a secondary processor. head.S calls this. |
458 | */ | 458 | */ |
459 | int __devinit | 459 | int __cpuinit |
460 | start_secondary (void *unused) | 460 | start_secondary (void *unused) |
461 | { | 461 | { |
462 | /* Early console may use I/O ports */ | 462 | /* Early console may use I/O ports */ |
diff --git a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c index 7d3dd6cdafa4..b0b08b5f3eca 100644 --- a/arch/ia64/kernel/unwind.c +++ b/arch/ia64/kernel/unwind.c | |||
@@ -1860,7 +1860,7 @@ int | |||
1860 | unw_unwind (struct unw_frame_info *info) | 1860 | unw_unwind (struct unw_frame_info *info) |
1861 | { | 1861 | { |
1862 | unsigned long prev_ip, prev_sp, prev_bsp; | 1862 | unsigned long prev_ip, prev_sp, prev_bsp; |
1863 | unsigned long ip, pr, num_regs; | 1863 | unsigned long ip, pr, num_regs, rp_loc, pfs_loc; |
1864 | STAT(unsigned long start, flags;) | 1864 | STAT(unsigned long start, flags;) |
1865 | int retval; | 1865 | int retval; |
1866 | 1866 | ||
@@ -1870,14 +1870,16 @@ unw_unwind (struct unw_frame_info *info) | |||
1870 | prev_sp = info->sp; | 1870 | prev_sp = info->sp; |
1871 | prev_bsp = info->bsp; | 1871 | prev_bsp = info->bsp; |
1872 | 1872 | ||
1873 | /* restore the ip */ | 1873 | /* validate the return IP pointer */ |
1874 | if (!info->rp_loc) { | 1874 | rp_loc = (unsigned long) info->rp_loc; |
1875 | if ((rp_loc < info->regstk.limit) || (rp_loc > info->regstk.top)) { | ||
1875 | /* FIXME: should really be level 0 but it occurs too often. KAO */ | 1876 | /* FIXME: should really be level 0 but it occurs too often. KAO */ |
1876 | UNW_DPRINT(1, "unwind.%s: failed to locate return link (ip=0x%lx)!\n", | 1877 | UNW_DPRINT(1, "unwind.%s: failed to locate return link (ip=0x%lx)!\n", |
1877 | __FUNCTION__, info->ip); | 1878 | __FUNCTION__, info->ip); |
1878 | STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); | 1879 | STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); |
1879 | return -1; | 1880 | return -1; |
1880 | } | 1881 | } |
1882 | /* restore the ip */ | ||
1881 | ip = info->ip = *info->rp_loc; | 1883 | ip = info->ip = *info->rp_loc; |
1882 | if (ip < GATE_ADDR) { | 1884 | if (ip < GATE_ADDR) { |
1883 | UNW_DPRINT(2, "unwind.%s: reached user-space (ip=0x%lx)\n", __FUNCTION__, ip); | 1885 | UNW_DPRINT(2, "unwind.%s: reached user-space (ip=0x%lx)\n", __FUNCTION__, ip); |
@@ -1885,12 +1887,14 @@ unw_unwind (struct unw_frame_info *info) | |||
1885 | return -1; | 1887 | return -1; |
1886 | } | 1888 | } |
1887 | 1889 | ||
1888 | /* restore the cfm: */ | 1890 | /* validate the previous stack frame pointer */ |
1889 | if (!info->pfs_loc) { | 1891 | pfs_loc = (unsigned long) info->pfs_loc; |
1892 | if ((pfs_loc < info->regstk.limit) || (pfs_loc > info->regstk.top)) { | ||
1890 | UNW_DPRINT(0, "unwind.%s: failed to locate ar.pfs!\n", __FUNCTION__); | 1893 | UNW_DPRINT(0, "unwind.%s: failed to locate ar.pfs!\n", __FUNCTION__); |
1891 | STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); | 1894 | STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); |
1892 | return -1; | 1895 | return -1; |
1893 | } | 1896 | } |
1897 | /* restore the cfm: */ | ||
1894 | info->cfm_loc = info->pfs_loc; | 1898 | info->cfm_loc = info->pfs_loc; |
1895 | 1899 | ||
1896 | /* restore the bsp: */ | 1900 | /* restore the bsp: */ |
@@ -1992,13 +1996,16 @@ init_frame_info (struct unw_frame_info *info, struct task_struct *t, | |||
1992 | memset(info, 0, sizeof(*info)); | 1996 | memset(info, 0, sizeof(*info)); |
1993 | 1997 | ||
1994 | rbslimit = (unsigned long) t + IA64_RBS_OFFSET; | 1998 | rbslimit = (unsigned long) t + IA64_RBS_OFFSET; |
1999 | stklimit = (unsigned long) t + IA64_STK_OFFSET; | ||
2000 | |||
1995 | rbstop = sw->ar_bspstore; | 2001 | rbstop = sw->ar_bspstore; |
1996 | if (rbstop - (unsigned long) t >= IA64_STK_OFFSET) | 2002 | if (rbstop > stklimit || rbstop < rbslimit) |
1997 | rbstop = rbslimit; | 2003 | rbstop = rbslimit; |
1998 | 2004 | ||
1999 | stklimit = (unsigned long) t + IA64_STK_OFFSET; | ||
2000 | if (stktop <= rbstop) | 2005 | if (stktop <= rbstop) |
2001 | stktop = rbstop; | 2006 | stktop = rbstop; |
2007 | if (stktop > stklimit) | ||
2008 | stktop = stklimit; | ||
2002 | 2009 | ||
2003 | info->regstk.limit = rbslimit; | 2010 | info->regstk.limit = rbslimit; |
2004 | info->regstk.top = rbstop; | 2011 | info->regstk.top = rbstop; |
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 3549f3b42592..73696b4a2eed 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -354,10 +354,13 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) | |||
354 | 354 | ||
355 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window, | 355 | acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window, |
356 | &windows); | 356 | &windows); |
357 | controller->window = kmalloc_node(sizeof(*controller->window) * windows, | 357 | if (windows) { |
358 | GFP_KERNEL, controller->node); | 358 | controller->window = |
359 | if (!controller->window) | 359 | kmalloc_node(sizeof(*controller->window) * windows, |
360 | goto out2; | 360 | GFP_KERNEL, controller->node); |
361 | if (!controller->window) | ||
362 | goto out2; | ||
363 | } | ||
361 | 364 | ||
362 | name = kmalloc(16, GFP_KERNEL); | 365 | name = kmalloc(16, GFP_KERNEL); |
363 | if (!name) | 366 | if (!name) |
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index a574fcd163dd..684b1c984a44 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c | |||
@@ -194,7 +194,7 @@ void __init early_sn_setup(void) | |||
194 | } | 194 | } |
195 | 195 | ||
196 | extern int platform_intr_list[]; | 196 | extern int platform_intr_list[]; |
197 | static int __initdata shub_1_1_found; | 197 | static int __cpuinitdata shub_1_1_found; |
198 | 198 | ||
199 | /* | 199 | /* |
200 | * sn_check_for_wars | 200 | * sn_check_for_wars |
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index b8536c7c0877..85cdd23b0447 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig | |||
@@ -355,8 +355,9 @@ config RMW_INSNS | |||
355 | adventurous. | 355 | adventurous. |
356 | 356 | ||
357 | config SINGLE_MEMORY_CHUNK | 357 | config SINGLE_MEMORY_CHUNK |
358 | bool "Use one physical chunk of memory only" | 358 | bool "Use one physical chunk of memory only" if ADVANCED && !SUN3 |
359 | depends on ADVANCED && !SUN3 | 359 | default y if SUN3 |
360 | select NEED_MULTIPLE_NODES | ||
360 | help | 361 | help |
361 | Ignore all but the first contiguous chunk of physical memory for VM | 362 | Ignore all but the first contiguous chunk of physical memory for VM |
362 | purposes. This will save a few bytes kernel size and may speed up | 363 | purposes. This will save a few bytes kernel size and may speed up |
@@ -377,6 +378,14 @@ config 060_WRITETHROUGH | |||
377 | is hardwired on. The 53c710 SCSI driver is known to suffer from | 378 | is hardwired on. The 53c710 SCSI driver is known to suffer from |
378 | this problem. | 379 | this problem. |
379 | 380 | ||
381 | config ARCH_DISCONTIGMEM_ENABLE | ||
382 | def_bool !SINGLE_MEMORY_CHUNK | ||
383 | |||
384 | config NODES_SHIFT | ||
385 | int | ||
386 | default "3" | ||
387 | depends on !SINGLE_MEMORY_CHUNK | ||
388 | |||
380 | source "mm/Kconfig" | 389 | source "mm/Kconfig" |
381 | 390 | ||
382 | endmenu | 391 | endmenu |
diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile index c20831a7e1a9..aa383a5ea7ac 100644 --- a/arch/m68k/Makefile +++ b/arch/m68k/Makefile | |||
@@ -19,6 +19,7 @@ COMPILE_ARCH = $(shell uname -m) | |||
19 | # override top level makefile | 19 | # override top level makefile |
20 | AS += -m68020 | 20 | AS += -m68020 |
21 | LDFLAGS := -m m68kelf | 21 | LDFLAGS := -m m68kelf |
22 | LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds | ||
22 | ifneq ($(COMPILE_ARCH),$(ARCH)) | 23 | ifneq ($(COMPILE_ARCH),$(ARCH)) |
23 | # prefix for cross-compiling binaries | 24 | # prefix for cross-compiling binaries |
24 | CROSS_COMPILE = m68k-linux-gnu- | 25 | CROSS_COMPILE = m68k-linux-gnu- |
diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile index 0b68ab8d63d1..a806208c7fb5 100644 --- a/arch/m68k/kernel/Makefile +++ b/arch/m68k/kernel/Makefile | |||
@@ -9,13 +9,12 @@ else | |||
9 | endif | 9 | endif |
10 | extra-y += vmlinux.lds | 10 | extra-y += vmlinux.lds |
11 | 11 | ||
12 | obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o \ | 12 | obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o module.o \ |
13 | sys_m68k.o time.o semaphore.o setup.o m68k_ksyms.o devres.o | 13 | sys_m68k.o time.o semaphore.o setup.o m68k_ksyms.o devres.o |
14 | 14 | ||
15 | devres-y = ../../../kernel/irq/devres.o | 15 | devres-y = ../../../kernel/irq/devres.o |
16 | 16 | ||
17 | obj-$(CONFIG_PCI) += bios32.o | 17 | obj-$(CONFIG_PCI) += bios32.o |
18 | obj-$(CONFIG_MODULES) += module.o | ||
19 | obj-y$(CONFIG_MMU_SUN3) += dma.o # no, it's not a typo | 18 | obj-y$(CONFIG_MMU_SUN3) += dma.o # no, it's not a typo |
20 | 19 | ||
21 | EXTRA_AFLAGS := -traditional | 20 | EXTRA_AFLAGS := -traditional |
diff --git a/arch/m68k/kernel/module.c b/arch/m68k/kernel/module.c index 3b1a2ff61ddc..774862bc6977 100644 --- a/arch/m68k/kernel/module.c +++ b/arch/m68k/kernel/module.c | |||
@@ -1,3 +1,9 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file COPYING in the main directory of this archive | ||
4 | * for more details. | ||
5 | */ | ||
6 | |||
1 | #include <linux/moduleloader.h> | 7 | #include <linux/moduleloader.h> |
2 | #include <linux/elf.h> | 8 | #include <linux/elf.h> |
3 | #include <linux/vmalloc.h> | 9 | #include <linux/vmalloc.h> |
@@ -11,6 +17,8 @@ | |||
11 | #define DEBUGP(fmt...) | 17 | #define DEBUGP(fmt...) |
12 | #endif | 18 | #endif |
13 | 19 | ||
20 | #ifdef CONFIG_MODULES | ||
21 | |||
14 | void *module_alloc(unsigned long size) | 22 | void *module_alloc(unsigned long size) |
15 | { | 23 | { |
16 | if (size == 0) | 24 | if (size == 0) |
@@ -118,11 +126,32 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, | |||
118 | 126 | ||
119 | int module_finalize(const Elf_Ehdr *hdr, | 127 | int module_finalize(const Elf_Ehdr *hdr, |
120 | const Elf_Shdr *sechdrs, | 128 | const Elf_Shdr *sechdrs, |
121 | struct module *me) | 129 | struct module *mod) |
122 | { | 130 | { |
131 | module_fixup(mod, mod->arch.fixup_start, mod->arch.fixup_end); | ||
132 | |||
123 | return 0; | 133 | return 0; |
124 | } | 134 | } |
125 | 135 | ||
126 | void module_arch_cleanup(struct module *mod) | 136 | void module_arch_cleanup(struct module *mod) |
127 | { | 137 | { |
128 | } | 138 | } |
139 | |||
140 | #endif /* CONFIG_MODULES */ | ||
141 | |||
142 | void module_fixup(struct module *mod, struct m68k_fixup_info *start, | ||
143 | struct m68k_fixup_info *end) | ||
144 | { | ||
145 | struct m68k_fixup_info *fixup; | ||
146 | |||
147 | for (fixup = start; fixup < end; fixup++) { | ||
148 | switch (fixup->type) { | ||
149 | case m68k_fixup_memoffset: | ||
150 | *(u32 *)fixup->addr = m68k_memoffset; | ||
151 | break; | ||
152 | case m68k_fixup_vnode_shift: | ||
153 | *(u16 *)fixup->addr += m68k_virt_to_node_shift; | ||
154 | break; | ||
155 | } | ||
156 | } | ||
157 | } | ||
diff --git a/arch/m68k/kernel/module.lds b/arch/m68k/kernel/module.lds new file mode 100644 index 000000000000..fda94fa38243 --- /dev/null +++ b/arch/m68k/kernel/module.lds | |||
@@ -0,0 +1,7 @@ | |||
1 | SECTIONS { | ||
2 | .m68k_fixup : { | ||
3 | __start_fixup = .; | ||
4 | *(.m68k_fixup) | ||
5 | __stop_fixup = .; | ||
6 | } | ||
7 | } | ||
diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c index 610319356691..215c7bd43924 100644 --- a/arch/m68k/kernel/setup.c +++ b/arch/m68k/kernel/setup.c | |||
@@ -60,14 +60,12 @@ extern unsigned long availmem; | |||
60 | int m68k_num_memory; | 60 | int m68k_num_memory; |
61 | int m68k_realnum_memory; | 61 | int m68k_realnum_memory; |
62 | EXPORT_SYMBOL(m68k_realnum_memory); | 62 | EXPORT_SYMBOL(m68k_realnum_memory); |
63 | #ifdef CONFIG_SINGLE_MEMORY_CHUNK | ||
64 | unsigned long m68k_memoffset; | 63 | unsigned long m68k_memoffset; |
65 | EXPORT_SYMBOL(m68k_memoffset); | 64 | EXPORT_SYMBOL(m68k_memoffset); |
66 | #endif | ||
67 | struct mem_info m68k_memory[NUM_MEMINFO]; | 65 | struct mem_info m68k_memory[NUM_MEMINFO]; |
68 | EXPORT_SYMBOL(m68k_memory); | 66 | EXPORT_SYMBOL(m68k_memory); |
69 | 67 | ||
70 | static struct mem_info m68k_ramdisk; | 68 | struct mem_info m68k_ramdisk; |
71 | 69 | ||
72 | static char m68k_command_line[CL_SIZE]; | 70 | static char m68k_command_line[CL_SIZE]; |
73 | 71 | ||
@@ -208,9 +206,6 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record) | |||
208 | void __init setup_arch(char **cmdline_p) | 206 | void __init setup_arch(char **cmdline_p) |
209 | { | 207 | { |
210 | extern int _etext, _edata, _end; | 208 | extern int _etext, _edata, _end; |
211 | #ifndef CONFIG_SUN3 | ||
212 | unsigned long endmem, startmem; | ||
213 | #endif | ||
214 | int i; | 209 | int i; |
215 | 210 | ||
216 | /* The bootinfo is located right after the kernel bss */ | 211 | /* The bootinfo is located right after the kernel bss */ |
@@ -320,30 +315,16 @@ void __init setup_arch(char **cmdline_p) | |||
320 | panic("No configuration setup"); | 315 | panic("No configuration setup"); |
321 | } | 316 | } |
322 | 317 | ||
323 | #ifndef CONFIG_SUN3 | 318 | paging_init(); |
324 | startmem= m68k_memory[0].addr; | ||
325 | endmem = startmem + m68k_memory[0].size; | ||
326 | high_memory = (void *)PAGE_OFFSET; | ||
327 | for (i = 0; i < m68k_num_memory; i++) { | ||
328 | m68k_memory[i].size &= MASK_256K; | ||
329 | if (m68k_memory[i].addr < startmem) | ||
330 | startmem = m68k_memory[i].addr; | ||
331 | if (m68k_memory[i].addr+m68k_memory[i].size > endmem) | ||
332 | endmem = m68k_memory[i].addr+m68k_memory[i].size; | ||
333 | high_memory += m68k_memory[i].size; | ||
334 | } | ||
335 | |||
336 | availmem += init_bootmem_node(NODE_DATA(0), availmem >> PAGE_SHIFT, | ||
337 | startmem >> PAGE_SHIFT, endmem >> PAGE_SHIFT); | ||
338 | |||
339 | for (i = 0; i < m68k_num_memory; i++) | ||
340 | free_bootmem(m68k_memory[i].addr, m68k_memory[i].size); | ||
341 | |||
342 | reserve_bootmem(m68k_memory[0].addr, availmem - m68k_memory[0].addr); | ||
343 | 319 | ||
320 | #ifndef CONFIG_SUN3 | ||
321 | for (i = 1; i < m68k_num_memory; i++) | ||
322 | free_bootmem_node(NODE_DATA(i), m68k_memory[i].addr, | ||
323 | m68k_memory[i].size); | ||
344 | #ifdef CONFIG_BLK_DEV_INITRD | 324 | #ifdef CONFIG_BLK_DEV_INITRD |
345 | if (m68k_ramdisk.size) { | 325 | if (m68k_ramdisk.size) { |
346 | reserve_bootmem(m68k_ramdisk.addr, m68k_ramdisk.size); | 326 | reserve_bootmem_node(__virt_to_node(phys_to_virt(m68k_ramdisk.addr)), |
327 | m68k_ramdisk.addr, m68k_ramdisk.size); | ||
347 | initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr); | 328 | initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr); |
348 | initrd_end = initrd_start + m68k_ramdisk.size; | 329 | initrd_end = initrd_start + m68k_ramdisk.size; |
349 | printk("initrd: %08lx - %08lx\n", initrd_start, initrd_end); | 330 | printk("initrd: %08lx - %08lx\n", initrd_start, initrd_end); |
@@ -362,8 +343,6 @@ void __init setup_arch(char **cmdline_p) | |||
362 | 343 | ||
363 | #endif /* !CONFIG_SUN3 */ | 344 | #endif /* !CONFIG_SUN3 */ |
364 | 345 | ||
365 | paging_init(); | ||
366 | |||
367 | /* set ISA defs early as possible */ | 346 | /* set ISA defs early as possible */ |
368 | #if defined(CONFIG_ISA) && defined(MULTI_ISA) | 347 | #if defined(CONFIG_ISA) && defined(MULTI_ISA) |
369 | #if defined(CONFIG_Q40) | 348 | #if defined(CONFIG_Q40) |
diff --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds index 78f139226a1b..40f02b128f22 100644 --- a/arch/m68k/kernel/vmlinux-std.lds +++ b/arch/m68k/kernel/vmlinux-std.lds | |||
@@ -60,6 +60,11 @@ SECTIONS | |||
60 | __con_initcall_start = .; | 60 | __con_initcall_start = .; |
61 | .con_initcall.init : { *(.con_initcall.init) } | 61 | .con_initcall.init : { *(.con_initcall.init) } |
62 | __con_initcall_end = .; | 62 | __con_initcall_end = .; |
63 | .m68k_fixup : { | ||
64 | __start_fixup = .; | ||
65 | *(.m68k_fixup) | ||
66 | __stop_fixup = .; | ||
67 | } | ||
63 | SECURITY_INIT | 68 | SECURITY_INIT |
64 | #ifdef CONFIG_BLK_DEV_INITRD | 69 | #ifdef CONFIG_BLK_DEV_INITRD |
65 | . = ALIGN(8192); | 70 | . = ALIGN(8192); |
diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds index c8999b2db23b..f06425b6d206 100644 --- a/arch/m68k/kernel/vmlinux-sun3.lds +++ b/arch/m68k/kernel/vmlinux-sun3.lds | |||
@@ -54,6 +54,11 @@ __init_begin = .; | |||
54 | __con_initcall_start = .; | 54 | __con_initcall_start = .; |
55 | .con_initcall.init : { *(.con_initcall.init) } | 55 | .con_initcall.init : { *(.con_initcall.init) } |
56 | __con_initcall_end = .; | 56 | __con_initcall_end = .; |
57 | .m68k_fixup : { | ||
58 | __start_fixup = .; | ||
59 | *(.m68k_fixup) | ||
60 | __stop_fixup = .; | ||
61 | } | ||
57 | SECURITY_INIT | 62 | SECURITY_INIT |
58 | #ifdef CONFIG_BLK_DEV_INITRD | 63 | #ifdef CONFIG_BLK_DEV_INITRD |
59 | . = ALIGN(8192); | 64 | . = ALIGN(8192); |
diff --git a/arch/m68k/mac/debug.c b/arch/m68k/mac/debug.c index 7a5bed5bdc57..e8a57138b4a6 100644 --- a/arch/m68k/mac/debug.c +++ b/arch/m68k/mac/debug.c | |||
@@ -71,7 +71,7 @@ void mac_debugging_short(int pos, short num) | |||
71 | 71 | ||
72 | /* calculate current offset */ | 72 | /* calculate current offset */ |
73 | pengoffset = (unsigned char *)mac_videobase + | 73 | pengoffset = (unsigned char *)mac_videobase + |
74 | (150+line*2) * mac_rowbytes) + 80 * peng; | 74 | (150+line*2) * mac_rowbytes + 80 * peng; |
75 | 75 | ||
76 | pptr = pengoffset; | 76 | pptr = pengoffset; |
77 | 77 | ||
diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c index ab90213e5c54..f1de19e1dde6 100644 --- a/arch/m68k/mm/init.c +++ b/arch/m68k/mm/init.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * to motorola.c and sun3mmu.c | 7 | * to motorola.c and sun3mmu.c |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/module.h> | ||
10 | #include <linux/signal.h> | 11 | #include <linux/signal.h> |
11 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
12 | #include <linux/mm.h> | 13 | #include <linux/mm.h> |
@@ -31,6 +32,37 @@ | |||
31 | 32 | ||
32 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); | 33 | DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); |
33 | 34 | ||
35 | static bootmem_data_t __initdata bootmem_data[MAX_NUMNODES]; | ||
36 | |||
37 | pg_data_t pg_data_map[MAX_NUMNODES]; | ||
38 | EXPORT_SYMBOL(pg_data_map); | ||
39 | |||
40 | int m68k_virt_to_node_shift; | ||
41 | |||
42 | #ifndef CONFIG_SINGLE_MEMORY_CHUNK | ||
43 | pg_data_t *pg_data_table[65]; | ||
44 | EXPORT_SYMBOL(pg_data_table); | ||
45 | #endif | ||
46 | |||
47 | void m68k_setup_node(int node) | ||
48 | { | ||
49 | #ifndef CONFIG_SINGLE_MEMORY_CHUNK | ||
50 | struct mem_info *info = m68k_memory + node; | ||
51 | int i, end; | ||
52 | |||
53 | i = (unsigned long)phys_to_virt(info->addr) >> __virt_to_node_shift(); | ||
54 | end = (unsigned long)phys_to_virt(info->addr + info->size - 1) >> __virt_to_node_shift(); | ||
55 | for (; i <= end; i++) { | ||
56 | if (pg_data_table[i]) | ||
57 | printk("overlap at %u for chunk %u\n", i, node); | ||
58 | pg_data_table[i] = pg_data_map + node; | ||
59 | } | ||
60 | #endif | ||
61 | pg_data_map[node].bdata = bootmem_data + node; | ||
62 | node_set_online(node); | ||
63 | } | ||
64 | |||
65 | |||
34 | /* | 66 | /* |
35 | * ZERO_PAGE is a special page that is used for zero-initialized | 67 | * ZERO_PAGE is a special page that is used for zero-initialized |
36 | * data and COW. | 68 | * data and COW. |
@@ -40,52 +72,51 @@ void *empty_zero_page; | |||
40 | 72 | ||
41 | void show_mem(void) | 73 | void show_mem(void) |
42 | { | 74 | { |
43 | unsigned long i; | 75 | pg_data_t *pgdat; |
44 | int free = 0, total = 0, reserved = 0, shared = 0; | 76 | int free = 0, total = 0, reserved = 0, shared = 0; |
45 | int cached = 0; | 77 | int cached = 0; |
46 | 78 | int i; | |
47 | printk("\nMem-info:\n"); | 79 | |
48 | show_free_areas(); | 80 | printk("\nMem-info:\n"); |
49 | printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); | 81 | show_free_areas(); |
50 | i = max_mapnr; | 82 | printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); |
51 | while (i-- > 0) { | 83 | for_each_online_pgdat(pgdat) { |
52 | total++; | 84 | for (i = 0; i < pgdat->node_spanned_pages; i++) { |
53 | if (PageReserved(mem_map+i)) | 85 | struct page *page = pgdat->node_mem_map + i; |
54 | reserved++; | 86 | total++; |
55 | else if (PageSwapCache(mem_map+i)) | 87 | if (PageReserved(page)) |
56 | cached++; | 88 | reserved++; |
57 | else if (!page_count(mem_map+i)) | 89 | else if (PageSwapCache(page)) |
58 | free++; | 90 | cached++; |
59 | else | 91 | else if (!page_count(page)) |
60 | shared += page_count(mem_map+i) - 1; | 92 | free++; |
61 | } | 93 | else |
62 | printk("%d pages of RAM\n",total); | 94 | shared += page_count(page) - 1; |
63 | printk("%d free pages\n",free); | 95 | } |
64 | printk("%d reserved pages\n",reserved); | 96 | } |
65 | printk("%d pages shared\n",shared); | 97 | printk("%d pages of RAM\n",total); |
66 | printk("%d pages swap cached\n",cached); | 98 | printk("%d free pages\n",free); |
99 | printk("%d reserved pages\n",reserved); | ||
100 | printk("%d pages shared\n",shared); | ||
101 | printk("%d pages swap cached\n",cached); | ||
67 | } | 102 | } |
68 | 103 | ||
69 | extern void init_pointer_table(unsigned long ptable); | 104 | extern void init_pointer_table(unsigned long ptable); |
70 | 105 | ||
71 | /* References to section boundaries */ | 106 | /* References to section boundaries */ |
72 | 107 | ||
73 | extern char _text, _etext, _edata, __bss_start, _end; | 108 | extern char _text[], _etext[]; |
74 | extern char __init_begin, __init_end; | 109 | extern char __init_begin[], __init_end[]; |
75 | 110 | ||
76 | extern pmd_t *zero_pgtable; | 111 | extern pmd_t *zero_pgtable; |
77 | 112 | ||
78 | void __init mem_init(void) | 113 | void __init mem_init(void) |
79 | { | 114 | { |
115 | pg_data_t *pgdat; | ||
80 | int codepages = 0; | 116 | int codepages = 0; |
81 | int datapages = 0; | 117 | int datapages = 0; |
82 | int initpages = 0; | 118 | int initpages = 0; |
83 | unsigned long tmp; | ||
84 | #ifndef CONFIG_SUN3 | ||
85 | int i; | 119 | int i; |
86 | #endif | ||
87 | |||
88 | max_mapnr = num_physpages = (((unsigned long)high_memory - PAGE_OFFSET) >> PAGE_SHIFT); | ||
89 | 120 | ||
90 | #ifdef CONFIG_ATARI | 121 | #ifdef CONFIG_ATARI |
91 | if (MACH_IS_ATARI) | 122 | if (MACH_IS_ATARI) |
@@ -93,19 +124,25 @@ void __init mem_init(void) | |||
93 | #endif | 124 | #endif |
94 | 125 | ||
95 | /* this will put all memory onto the freelists */ | 126 | /* this will put all memory onto the freelists */ |
96 | totalram_pages = free_all_bootmem(); | 127 | totalram_pages = num_physpages = 0; |
97 | 128 | for_each_online_pgdat(pgdat) { | |
98 | for (tmp = PAGE_OFFSET ; tmp < (unsigned long)high_memory; tmp += PAGE_SIZE) { | 129 | num_physpages += pgdat->node_present_pages; |
99 | if (PageReserved(virt_to_page(tmp))) { | 130 | |
100 | if (tmp >= (unsigned long)&_text | 131 | totalram_pages += free_all_bootmem_node(pgdat); |
101 | && tmp < (unsigned long)&_etext) | 132 | for (i = 0; i < pgdat->node_spanned_pages; i++) { |
133 | struct page *page = pgdat->node_mem_map + i; | ||
134 | char *addr = page_to_virt(page); | ||
135 | |||
136 | if (!PageReserved(page)) | ||
137 | continue; | ||
138 | if (addr >= _text && | ||
139 | addr < _etext) | ||
102 | codepages++; | 140 | codepages++; |
103 | else if (tmp >= (unsigned long) &__init_begin | 141 | else if (addr >= __init_begin && |
104 | && tmp < (unsigned long) &__init_end) | 142 | addr < __init_end) |
105 | initpages++; | 143 | initpages++; |
106 | else | 144 | else |
107 | datapages++; | 145 | datapages++; |
108 | continue; | ||
109 | } | 146 | } |
110 | } | 147 | } |
111 | 148 | ||
@@ -124,7 +161,7 @@ void __init mem_init(void) | |||
124 | 161 | ||
125 | printk("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init)\n", | 162 | printk("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init)\n", |
126 | (unsigned long)nr_free_pages() << (PAGE_SHIFT-10), | 163 | (unsigned long)nr_free_pages() << (PAGE_SHIFT-10), |
127 | max_mapnr << (PAGE_SHIFT-10), | 164 | totalram_pages << (PAGE_SHIFT-10), |
128 | codepages << (PAGE_SHIFT-10), | 165 | codepages << (PAGE_SHIFT-10), |
129 | datapages << (PAGE_SHIFT-10), | 166 | datapages << (PAGE_SHIFT-10), |
130 | initpages << (PAGE_SHIFT-10)); | 167 | initpages << (PAGE_SHIFT-10)); |
diff --git a/arch/m68k/mm/memory.c b/arch/m68k/mm/memory.c index 13c0b4ad01eb..b7473525b431 100644 --- a/arch/m68k/mm/memory.c +++ b/arch/m68k/mm/memory.c | |||
@@ -127,67 +127,6 @@ int free_pointer_table (pmd_t *ptable) | |||
127 | return 0; | 127 | return 0; |
128 | } | 128 | } |
129 | 129 | ||
130 | #ifdef DEBUG_INVALID_PTOV | ||
131 | int mm_inv_cnt = 5; | ||
132 | #endif | ||
133 | |||
134 | #ifndef CONFIG_SINGLE_MEMORY_CHUNK | ||
135 | /* | ||
136 | * The following two routines map from a physical address to a kernel | ||
137 | * virtual address and vice versa. | ||
138 | */ | ||
139 | unsigned long mm_vtop(unsigned long vaddr) | ||
140 | { | ||
141 | int i=0; | ||
142 | unsigned long voff = (unsigned long)vaddr - PAGE_OFFSET; | ||
143 | |||
144 | do { | ||
145 | if (voff < m68k_memory[i].size) { | ||
146 | #ifdef DEBUGPV | ||
147 | printk ("VTOP(%p)=%lx\n", vaddr, | ||
148 | m68k_memory[i].addr + voff); | ||
149 | #endif | ||
150 | return m68k_memory[i].addr + voff; | ||
151 | } | ||
152 | voff -= m68k_memory[i].size; | ||
153 | } while (++i < m68k_num_memory); | ||
154 | |||
155 | /* As a special case allow `__pa(high_memory)'. */ | ||
156 | if (voff == 0) | ||
157 | return m68k_memory[i-1].addr + m68k_memory[i-1].size; | ||
158 | |||
159 | return -1; | ||
160 | } | ||
161 | EXPORT_SYMBOL(mm_vtop); | ||
162 | |||
163 | unsigned long mm_ptov (unsigned long paddr) | ||
164 | { | ||
165 | int i = 0; | ||
166 | unsigned long poff, voff = PAGE_OFFSET; | ||
167 | |||
168 | do { | ||
169 | poff = paddr - m68k_memory[i].addr; | ||
170 | if (poff < m68k_memory[i].size) { | ||
171 | #ifdef DEBUGPV | ||
172 | printk ("PTOV(%lx)=%lx\n", paddr, poff + voff); | ||
173 | #endif | ||
174 | return poff + voff; | ||
175 | } | ||
176 | voff += m68k_memory[i].size; | ||
177 | } while (++i < m68k_num_memory); | ||
178 | |||
179 | #ifdef DEBUG_INVALID_PTOV | ||
180 | if (mm_inv_cnt > 0) { | ||
181 | mm_inv_cnt--; | ||
182 | printk("Invalid use of phys_to_virt(0x%lx) at 0x%p!\n", | ||
183 | paddr, __builtin_return_address(0)); | ||
184 | } | ||
185 | #endif | ||
186 | return -1; | ||
187 | } | ||
188 | EXPORT_SYMBOL(mm_ptov); | ||
189 | #endif | ||
190 | |||
191 | /* invalidate page in both caches */ | 130 | /* invalidate page in both caches */ |
192 | static inline void clear040(unsigned long paddr) | 131 | static inline void clear040(unsigned long paddr) |
193 | { | 132 | { |
@@ -354,15 +293,3 @@ void cache_push (unsigned long paddr, int len) | |||
354 | } | 293 | } |
355 | EXPORT_SYMBOL(cache_push); | 294 | EXPORT_SYMBOL(cache_push); |
356 | 295 | ||
357 | #ifndef CONFIG_SINGLE_MEMORY_CHUNK | ||
358 | int mm_end_of_chunk (unsigned long addr, int len) | ||
359 | { | ||
360 | int i; | ||
361 | |||
362 | for (i = 0; i < m68k_num_memory; i++) | ||
363 | if (m68k_memory[i].addr + m68k_memory[i].size == addr + len) | ||
364 | return 1; | ||
365 | return 0; | ||
366 | } | ||
367 | EXPORT_SYMBOL(mm_end_of_chunk); | ||
368 | #endif | ||
diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c index afcccdc6ad45..7d571a2b44dd 100644 --- a/arch/m68k/mm/motorola.c +++ b/arch/m68k/mm/motorola.c | |||
@@ -43,6 +43,11 @@ unsigned long mm_cachebits; | |||
43 | EXPORT_SYMBOL(mm_cachebits); | 43 | EXPORT_SYMBOL(mm_cachebits); |
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | /* size of memory already mapped in head.S */ | ||
47 | #define INIT_MAPPED_SIZE (4UL<<20) | ||
48 | |||
49 | extern unsigned long availmem; | ||
50 | |||
46 | static pte_t * __init kernel_page_table(void) | 51 | static pte_t * __init kernel_page_table(void) |
47 | { | 52 | { |
48 | pte_t *ptablep; | 53 | pte_t *ptablep; |
@@ -98,19 +103,20 @@ static pmd_t * __init kernel_ptr_table(void) | |||
98 | return last_pgtable; | 103 | return last_pgtable; |
99 | } | 104 | } |
100 | 105 | ||
101 | static unsigned long __init | 106 | static void __init map_node(int node) |
102 | map_chunk (unsigned long addr, long size) | ||
103 | { | 107 | { |
104 | #define PTRTREESIZE (256*1024) | 108 | #define PTRTREESIZE (256*1024) |
105 | #define ROOTTREESIZE (32*1024*1024) | 109 | #define ROOTTREESIZE (32*1024*1024) |
106 | static unsigned long virtaddr = PAGE_OFFSET; | 110 | unsigned long physaddr, virtaddr, size; |
107 | unsigned long physaddr; | ||
108 | pgd_t *pgd_dir; | 111 | pgd_t *pgd_dir; |
109 | pmd_t *pmd_dir; | 112 | pmd_t *pmd_dir; |
110 | pte_t *pte_dir; | 113 | pte_t *pte_dir; |
111 | 114 | ||
112 | physaddr = (addr | m68k_supervisor_cachemode | | 115 | size = m68k_memory[node].size; |
113 | _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY); | 116 | physaddr = m68k_memory[node].addr; |
117 | virtaddr = (unsigned long)phys_to_virt(physaddr); | ||
118 | physaddr |= m68k_supervisor_cachemode | | ||
119 | _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY; | ||
114 | if (CPU_IS_040_OR_060) | 120 | if (CPU_IS_040_OR_060) |
115 | physaddr |= _PAGE_GLOBAL040; | 121 | physaddr |= _PAGE_GLOBAL040; |
116 | 122 | ||
@@ -190,8 +196,6 @@ map_chunk (unsigned long addr, long size) | |||
190 | #ifdef DEBUG | 196 | #ifdef DEBUG |
191 | printk("\n"); | 197 | printk("\n"); |
192 | #endif | 198 | #endif |
193 | |||
194 | return virtaddr; | ||
195 | } | 199 | } |
196 | 200 | ||
197 | /* | 201 | /* |
@@ -200,15 +204,16 @@ map_chunk (unsigned long addr, long size) | |||
200 | */ | 204 | */ |
201 | void __init paging_init(void) | 205 | void __init paging_init(void) |
202 | { | 206 | { |
203 | int chunk; | ||
204 | unsigned long mem_avail = 0; | ||
205 | unsigned long zones_size[MAX_NR_ZONES] = { 0, }; | 207 | unsigned long zones_size[MAX_NR_ZONES] = { 0, }; |
208 | unsigned long min_addr, max_addr; | ||
209 | unsigned long addr, size, end; | ||
210 | int i; | ||
206 | 211 | ||
207 | #ifdef DEBUG | 212 | #ifdef DEBUG |
208 | { | 213 | { |
209 | extern unsigned long availmem; | 214 | extern unsigned long availmem; |
210 | printk ("start of paging_init (%p, %lx, %lx, %lx)\n", | 215 | printk ("start of paging_init (%p, %lx)\n", |
211 | kernel_pg_dir, availmem, start_mem, end_mem); | 216 | kernel_pg_dir, availmem); |
212 | } | 217 | } |
213 | #endif | 218 | #endif |
214 | 219 | ||
@@ -222,24 +227,62 @@ void __init paging_init(void) | |||
222 | pgprot_val(protection_map[i]) |= _PAGE_CACHE040; | 227 | pgprot_val(protection_map[i]) |= _PAGE_CACHE040; |
223 | } | 228 | } |
224 | 229 | ||
230 | min_addr = m68k_memory[0].addr; | ||
231 | max_addr = min_addr + m68k_memory[0].size; | ||
232 | for (i = 1; i < m68k_num_memory;) { | ||
233 | if (m68k_memory[i].addr < min_addr) { | ||
234 | printk("Ignoring memory chunk at 0x%lx:0x%lx before the first chunk\n", | ||
235 | m68k_memory[i].addr, m68k_memory[i].size); | ||
236 | printk("Fix your bootloader or use a memfile to make use of this area!\n"); | ||
237 | m68k_num_memory--; | ||
238 | memmove(m68k_memory + i, m68k_memory + i + 1, | ||
239 | (m68k_num_memory - i) * sizeof(struct mem_info)); | ||
240 | continue; | ||
241 | } | ||
242 | addr = m68k_memory[i].addr + m68k_memory[i].size; | ||
243 | if (addr > max_addr) | ||
244 | max_addr = addr; | ||
245 | i++; | ||
246 | } | ||
247 | m68k_memoffset = min_addr - PAGE_OFFSET; | ||
248 | m68k_virt_to_node_shift = fls(max_addr - min_addr - 1) - 6; | ||
249 | |||
250 | module_fixup(NULL, __start_fixup, __stop_fixup); | ||
251 | flush_icache(); | ||
252 | |||
253 | high_memory = phys_to_virt(max_addr); | ||
254 | |||
255 | min_low_pfn = availmem >> PAGE_SHIFT; | ||
256 | max_low_pfn = max_addr >> PAGE_SHIFT; | ||
257 | |||
258 | for (i = 0; i < m68k_num_memory; i++) { | ||
259 | addr = m68k_memory[i].addr; | ||
260 | end = addr + m68k_memory[i].size; | ||
261 | m68k_setup_node(i); | ||
262 | availmem = PAGE_ALIGN(availmem); | ||
263 | availmem += init_bootmem_node(NODE_DATA(i), | ||
264 | availmem >> PAGE_SHIFT, | ||
265 | addr >> PAGE_SHIFT, | ||
266 | end >> PAGE_SHIFT); | ||
267 | } | ||
268 | |||
225 | /* | 269 | /* |
226 | * Map the physical memory available into the kernel virtual | 270 | * Map the physical memory available into the kernel virtual |
227 | * address space. It may allocate some memory for page | 271 | * address space. First initialize the bootmem allocator with |
228 | * tables and thus modify availmem. | 272 | * the memory we already mapped, so map_node() has something |
273 | * to allocate. | ||
229 | */ | 274 | */ |
275 | addr = m68k_memory[0].addr; | ||
276 | size = m68k_memory[0].size; | ||
277 | free_bootmem_node(NODE_DATA(0), availmem, min(INIT_MAPPED_SIZE, size) - (availmem - addr)); | ||
278 | map_node(0); | ||
279 | if (size > INIT_MAPPED_SIZE) | ||
280 | free_bootmem_node(NODE_DATA(0), addr + INIT_MAPPED_SIZE, size - INIT_MAPPED_SIZE); | ||
230 | 281 | ||
231 | for (chunk = 0; chunk < m68k_num_memory; chunk++) { | 282 | for (i = 1; i < m68k_num_memory; i++) |
232 | mem_avail = map_chunk (m68k_memory[chunk].addr, | 283 | map_node(i); |
233 | m68k_memory[chunk].size); | ||
234 | |||
235 | } | ||
236 | 284 | ||
237 | flush_tlb_all(); | 285 | flush_tlb_all(); |
238 | #ifdef DEBUG | ||
239 | printk ("memory available is %ldKB\n", mem_avail >> 10); | ||
240 | printk ("start_mem is %#lx\nvirtual_end is %#lx\n", | ||
241 | start_mem, end_mem); | ||
242 | #endif | ||
243 | 286 | ||
244 | /* | 287 | /* |
245 | * initialize the bad page table and bad page to point | 288 | * initialize the bad page table and bad page to point |
@@ -256,14 +299,11 @@ void __init paging_init(void) | |||
256 | #ifdef DEBUG | 299 | #ifdef DEBUG |
257 | printk ("before free_area_init\n"); | 300 | printk ("before free_area_init\n"); |
258 | #endif | 301 | #endif |
259 | zones_size[ZONE_DMA] = (mach_max_dma_address < (unsigned long)high_memory ? | 302 | for (i = 0; i < m68k_num_memory; i++) { |
260 | (mach_max_dma_address+1) : (unsigned long)high_memory); | 303 | zones_size[ZONE_DMA] = m68k_memory[i].size >> PAGE_SHIFT; |
261 | zones_size[ZONE_NORMAL] = (unsigned long)high_memory - zones_size[0]; | 304 | free_area_init_node(i, pg_data_map + i, zones_size, |
262 | 305 | m68k_memory[i].addr >> PAGE_SHIFT, NULL); | |
263 | zones_size[ZONE_DMA] = (zones_size[ZONE_DMA] - PAGE_OFFSET) >> PAGE_SHIFT; | 306 | } |
264 | zones_size[ZONE_NORMAL] >>= PAGE_SHIFT; | ||
265 | |||
266 | free_area_init(zones_size); | ||
267 | } | 307 | } |
268 | 308 | ||
269 | extern char __init_begin, __init_end; | 309 | extern char __init_begin, __init_end; |
diff --git a/arch/m68k/sun3/config.c b/arch/m68k/sun3/config.c index 4851b8437a87..c0fbd278fbb1 100644 --- a/arch/m68k/sun3/config.c +++ b/arch/m68k/sun3/config.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/contregs.h> | 21 | #include <asm/contregs.h> |
22 | #include <asm/movs.h> | 22 | #include <asm/movs.h> |
23 | #include <asm/pgtable.h> | 23 | #include <asm/pgtable.h> |
24 | #include <asm/pgalloc.h> | ||
24 | #include <asm/sun3-head.h> | 25 | #include <asm/sun3-head.h> |
25 | #include <asm/sun3mmu.h> | 26 | #include <asm/sun3mmu.h> |
26 | #include <asm/rtc.h> | 27 | #include <asm/rtc.h> |
@@ -127,6 +128,7 @@ void __init sun3_bootmem_alloc(unsigned long memory_start, unsigned long memory_ | |||
127 | high_memory = (void *)memory_end; | 128 | high_memory = (void *)memory_end; |
128 | availmem = memory_start; | 129 | availmem = memory_start; |
129 | 130 | ||
131 | m68k_setup_node(0); | ||
130 | availmem += init_bootmem_node(NODE_DATA(0), start_page, 0, num_pages); | 132 | availmem += init_bootmem_node(NODE_DATA(0), start_page, 0, num_pages); |
131 | availmem = (availmem + (PAGE_SIZE-1)) & PAGE_MASK; | 133 | availmem = (availmem + (PAGE_SIZE-1)) & PAGE_MASK; |
132 | 134 | ||
diff --git a/arch/m68knommu/platform/5307/timers.c b/arch/m68knommu/platform/5307/timers.c index 92e58070b016..fb66eadd5896 100644 --- a/arch/m68knommu/platform/5307/timers.c +++ b/arch/m68knommu/platform/5307/timers.c | |||
@@ -62,10 +62,13 @@ void coldfire_tick(void) | |||
62 | 62 | ||
63 | /***************************************************************************/ | 63 | /***************************************************************************/ |
64 | 64 | ||
65 | static int ticks_per_intr; | ||
66 | |||
65 | void coldfire_timer_init(irq_handler_t handler) | 67 | void coldfire_timer_init(irq_handler_t handler) |
66 | { | 68 | { |
67 | __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR)); | 69 | __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR)); |
68 | __raw_writetrr(((MCF_BUSCLK / 16) / HZ), TA(MCFTIMER_TRR)); | 70 | ticks_per_intr = (MCF_BUSCLK / 16) / HZ; |
71 | __raw_writetrr(ticks_per_intr - 1, TA(MCFTIMER_TRR)); | ||
69 | __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | | 72 | __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | |
70 | MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, TA(MCFTIMER_TMR)); | 73 | MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, TA(MCFTIMER_TMR)); |
71 | 74 | ||
@@ -81,11 +84,10 @@ void coldfire_timer_init(irq_handler_t handler) | |||
81 | 84 | ||
82 | unsigned long coldfire_timer_offset(void) | 85 | unsigned long coldfire_timer_offset(void) |
83 | { | 86 | { |
84 | unsigned long trr, tcn, offset; | 87 | unsigned long tcn, offset; |
85 | 88 | ||
86 | tcn = __raw_readw(TA(MCFTIMER_TCN)); | 89 | tcn = __raw_readw(TA(MCFTIMER_TCN)); |
87 | trr = __raw_readtrr(TA(MCFTIMER_TRR)); | 90 | offset = ((tcn + 1) * (1000000 / HZ)) / ticks_per_intr; |
88 | offset = (tcn * (1000000 / HZ)) / trr; | ||
89 | 91 | ||
90 | /* Check if we just wrapped the counters and maybe missed a tick */ | 92 | /* Check if we just wrapped the counters and maybe missed a tick */ |
91 | if ((offset < (1000000 / HZ / 2)) && mcf_timerirqpending(1)) | 93 | if ((offset < (1000000 / HZ / 2)) && mcf_timerirqpending(1)) |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 0f09412e1b7f..9528ee90640a 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -747,9 +747,9 @@ config EARLY_PRINTK | |||
747 | to print messages very early in the bootup process. | 747 | to print messages very early in the bootup process. |
748 | 748 | ||
749 | This is useful for kernel debugging when your machine crashes very | 749 | This is useful for kernel debugging when your machine crashes very |
750 | early before the console code is initialized. For normal operation | 750 | early before the console code is initialized. For normal operation, |
751 | it is not recommended because it looks on some machines ugly and | 751 | it is not recommended because it looks ugly on some machines and |
752 | oesn't cooperate with an X server. You should normally N here, | 752 | doesn't cooperate with an X server. You should normally say N here, |
753 | unless you want to debug such a crash. | 753 | unless you want to debug such a crash. |
754 | 754 | ||
755 | config SYS_HAS_EARLY_PRINTK | 755 | config SYS_HAS_EARLY_PRINTK |
diff --git a/arch/mips/emma2rh/markeins/setup.c b/arch/mips/emma2rh/markeins/setup.c index b29a44739230..2f060e1ed36c 100644 --- a/arch/mips/emma2rh/markeins/setup.c +++ b/arch/mips/emma2rh/markeins/setup.c | |||
@@ -115,30 +115,6 @@ extern void markeins_irq_setup(void); | |||
115 | 115 | ||
116 | static void inline __init markeins_sio_setup(void) | 116 | static void inline __init markeins_sio_setup(void) |
117 | { | 117 | { |
118 | #ifdef CONFIG_KGDB_8250 | ||
119 | struct uart_port emma_port; | ||
120 | |||
121 | memset(&emma_port, 0, sizeof(emma_port)); | ||
122 | |||
123 | emma_port.flags = | ||
124 | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; | ||
125 | emma_port.iotype = UPIO_MEM; | ||
126 | emma_port.regshift = 4; /* I/O addresses are every 8 bytes */ | ||
127 | emma_port.uartclk = 18544000; /* Clock rate of the chip */ | ||
128 | |||
129 | emma_port.line = 0; | ||
130 | emma_port.mapbase = KSEG1ADDR(EMMA2RH_PFUR0_BASE + 3); | ||
131 | emma_port.membase = (u8*)emma_port.mapbase; | ||
132 | early_serial_setup(&emma_port); | ||
133 | |||
134 | emma_port.line = 1; | ||
135 | emma_port.mapbase = KSEG1ADDR(EMMA2RH_PFUR1_BASE + 3); | ||
136 | emma_port.membase = (u8*)emma_port.mapbase; | ||
137 | early_serial_setup(&emma_port); | ||
138 | |||
139 | emma_port.irq = EMMA2RH_IRQ_PFUR1; | ||
140 | kgdb8250_add_port(1, &emma_port); | ||
141 | #endif | ||
142 | } | 118 | } |
143 | 119 | ||
144 | void __init plat_mem_setup(void) | 120 | void __init plat_mem_setup(void) |
diff --git a/arch/mips/jmr3927/rbhma3100/kgdb_io.c b/arch/mips/jmr3927/rbhma3100/kgdb_io.c index 2604f2c9a96e..342579cfdc01 100644 --- a/arch/mips/jmr3927/rbhma3100/kgdb_io.c +++ b/arch/mips/jmr3927/rbhma3100/kgdb_io.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #define TIMEOUT 0xffffff | 36 | #define TIMEOUT 0xffffff |
37 | 37 | ||
38 | static int remoteDebugInitialized = 0; | 38 | static int remoteDebugInitialized = 0; |
39 | static void debugInit(int baud) | 39 | static void debugInit(int baud); |
40 | 40 | ||
41 | int putDebugChar(unsigned char c) | 41 | int putDebugChar(unsigned char c) |
42 | { | 42 | { |
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 37849edd0645..06e04da211d5 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c | |||
@@ -556,6 +556,16 @@ asmlinkage long sys32_sync_file_range(int fd, int __pad, | |||
556 | flags); | 556 | flags); |
557 | } | 557 | } |
558 | 558 | ||
559 | asmlinkage long sys32_fadvise64_64(int fd, int __pad, | ||
560 | unsigned long a2, unsigned long a3, | ||
561 | unsigned long a4, unsigned long a5, | ||
562 | int flags) | ||
563 | { | ||
564 | return sys_fadvise64_64(fd, | ||
565 | merge_64(a2, a3), merge_64(a4, a5), | ||
566 | flags); | ||
567 | } | ||
568 | |||
559 | save_static_function(sys32_clone); | 569 | save_static_function(sys32_clone); |
560 | __attribute_used__ noinline static int | 570 | __attribute_used__ noinline static int |
561 | _sys32_clone(nabi_no_regargs struct pt_regs regs) | 571 | _sys32_clone(nabi_no_regargs struct pt_regs regs) |
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index cc566cf12246..06729596812f 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S | |||
@@ -174,7 +174,7 @@ LEAF(_init_fpu) | |||
174 | or t0, t1 | 174 | or t0, t1 |
175 | mtc0 t0, CP0_STATUS | 175 | mtc0 t0, CP0_STATUS |
176 | #endif /* CONFIG_MIPS_MT_SMTC */ | 176 | #endif /* CONFIG_MIPS_MT_SMTC */ |
177 | fpu_enable_hazard | 177 | enable_fpu_hazard |
178 | 178 | ||
179 | li t1, FPU_DEFAULT | 179 | li t1, FPU_DEFAULT |
180 | ctc1 t1, fcr31 | 180 | ctc1 t1, fcr31 |
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 0c9a9ff8cd25..ae985d1fcca1 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S | |||
@@ -657,7 +657,11 @@ einval: li v0, -EINVAL | |||
657 | sys sys_getcpu 3 | 657 | sys sys_getcpu 3 |
658 | sys sys_epoll_pwait 6 | 658 | sys sys_epoll_pwait 6 |
659 | sys sys_ioprio_set 3 | 659 | sys sys_ioprio_set 3 |
660 | sys sys_ioprio_get 2 | 660 | sys sys_ioprio_get 2 /* 4315 */ |
661 | sys sys_utimensat 4 | ||
662 | sys sys_signalfd 3 | ||
663 | sys sys_timerfd 4 | ||
664 | sys sys_eventfd 1 | ||
661 | .endm | 665 | .endm |
662 | 666 | ||
663 | /* We pre-compute the number of _instruction_ bytes needed to | 667 | /* We pre-compute the number of _instruction_ bytes needed to |
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 23f3b118f718..7bcd5a1a85f5 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S | |||
@@ -473,4 +473,8 @@ sys_call_table: | |||
473 | PTR sys_epoll_pwait | 473 | PTR sys_epoll_pwait |
474 | PTR sys_ioprio_set | 474 | PTR sys_ioprio_set |
475 | PTR sys_ioprio_get | 475 | PTR sys_ioprio_get |
476 | PTR sys_utimensat /* 5275 */ | ||
477 | PTR sys_signalfd | ||
478 | PTR sys_timerfd | ||
479 | PTR sys_eventfd | ||
476 | .size sys_call_table,.-sys_call_table | 480 | .size sys_call_table,.-sys_call_table |
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 6eac28337423..532a2f3b42fc 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S | |||
@@ -299,7 +299,7 @@ EXPORT(sysn32_call_table) | |||
299 | PTR sys_ni_syscall /* res. for afs_syscall */ | 299 | PTR sys_ni_syscall /* res. for afs_syscall */ |
300 | PTR sys_ni_syscall /* res. for security */ | 300 | PTR sys_ni_syscall /* res. for security */ |
301 | PTR sys_gettid | 301 | PTR sys_gettid |
302 | PTR sys32_readahead | 302 | PTR sys_readahead |
303 | PTR sys_setxattr /* 6180 */ | 303 | PTR sys_setxattr /* 6180 */ |
304 | PTR sys_lsetxattr | 304 | PTR sys_lsetxattr |
305 | PTR sys_fsetxattr | 305 | PTR sys_fsetxattr |
@@ -399,4 +399,8 @@ EXPORT(sysn32_call_table) | |||
399 | PTR compat_sys_epoll_pwait | 399 | PTR compat_sys_epoll_pwait |
400 | PTR sys_ioprio_set | 400 | PTR sys_ioprio_set |
401 | PTR sys_ioprio_get | 401 | PTR sys_ioprio_get |
402 | PTR compat_sys_utimensat | ||
403 | PTR compat_sys_signalfd /* 5280 */ | ||
404 | PTR compat_sys_timerfd | ||
405 | PTR sys_eventfd | ||
402 | .size sysn32_call_table,.-sysn32_call_table | 406 | .size sysn32_call_table,.-sysn32_call_table |
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 7e74b412a782..6bbe0f4ed8ba 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S | |||
@@ -459,7 +459,7 @@ sys_call_table: | |||
459 | PTR sys_remap_file_pages | 459 | PTR sys_remap_file_pages |
460 | PTR sys_set_tid_address | 460 | PTR sys_set_tid_address |
461 | PTR sys_restart_syscall | 461 | PTR sys_restart_syscall |
462 | PTR sys_fadvise64_64 | 462 | PTR sys32_fadvise64_64 |
463 | PTR compat_sys_statfs64 /* 4255 */ | 463 | PTR compat_sys_statfs64 /* 4255 */ |
464 | PTR compat_sys_fstatfs64 | 464 | PTR compat_sys_fstatfs64 |
465 | PTR compat_sys_timer_create | 465 | PTR compat_sys_timer_create |
@@ -521,4 +521,8 @@ sys_call_table: | |||
521 | PTR compat_sys_epoll_pwait | 521 | PTR compat_sys_epoll_pwait |
522 | PTR sys_ioprio_set | 522 | PTR sys_ioprio_set |
523 | PTR sys_ioprio_get /* 4315 */ | 523 | PTR sys_ioprio_get /* 4315 */ |
524 | PTR compat_sys_utimensat | ||
525 | PTR compat_sys_signalfd | ||
526 | PTR compat_sys_timerfd | ||
527 | PTR sys_eventfd | ||
524 | .size sys_call_table,.-sys_call_table | 528 | .size sys_call_table,.-sys_call_table |
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index c46e479c992b..67edfa7ed93a 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
@@ -68,7 +68,7 @@ extern ATTRIB_NORET void cpu_idle(void); | |||
68 | * First C code run on the secondary CPUs after being started up by | 68 | * First C code run on the secondary CPUs after being started up by |
69 | * the master. | 69 | * the master. |
70 | */ | 70 | */ |
71 | asmlinkage void start_secondary(void) | 71 | asmlinkage __cpuinit void start_secondary(void) |
72 | { | 72 | { |
73 | unsigned int cpu; | 73 | unsigned int cpu; |
74 | 74 | ||
diff --git a/arch/mips/kernel/smtc-asm.S b/arch/mips/kernel/smtc-asm.S index 921207c4a83c..20938a4cb52d 100644 --- a/arch/mips/kernel/smtc-asm.S +++ b/arch/mips/kernel/smtc-asm.S | |||
@@ -121,10 +121,7 @@ LEAF(self_ipi) | |||
121 | subu t1,sp,PT_SIZE | 121 | subu t1,sp,PT_SIZE |
122 | sw ra,PT_EPC(t1) | 122 | sw ra,PT_EPC(t1) |
123 | sw a0,PT_PADSLOT4(t1) | 123 | sw a0,PT_PADSLOT4(t1) |
124 | LONG_L s0, TI_REGS($28) | ||
125 | LONG_S sp, TI_REGS($28) | ||
126 | la t2,ipi_decode | 124 | la t2,ipi_decode |
127 | LONG_S s0, TI_REGS($28) | ||
128 | sw t2,PT_PADSLOT5(t1) | 125 | sw t2,PT_PADSLOT5(t1) |
129 | /* Save pre-disable value of TCStatus */ | 126 | /* Save pre-disable value of TCStatus */ |
130 | sw t0,PT_TCSTATUS(t1) | 127 | sw t0,PT_TCSTATUS(t1) |
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index b361edb83dc6..21eb5993a19f 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c | |||
@@ -611,12 +611,12 @@ void smtc_cpus_done(void) | |||
611 | int setup_irq_smtc(unsigned int irq, struct irqaction * new, | 611 | int setup_irq_smtc(unsigned int irq, struct irqaction * new, |
612 | unsigned long hwmask) | 612 | unsigned long hwmask) |
613 | { | 613 | { |
614 | #ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG | ||
614 | unsigned int vpe = current_cpu_data.vpe_id; | 615 | unsigned int vpe = current_cpu_data.vpe_id; |
615 | 616 | ||
616 | irq_hwmask[irq] = hwmask; | ||
617 | #ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG | ||
618 | vpemask[vpe][irq - MIPSCPU_INT_BASE] = 1; | 617 | vpemask[vpe][irq - MIPSCPU_INT_BASE] = 1; |
619 | #endif | 618 | #endif |
619 | irq_hwmask[irq] = hwmask; | ||
620 | 620 | ||
621 | return setup_irq(irq, new); | 621 | return setup_irq(irq, new); |
622 | } | 622 | } |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 200de027f354..a7a17eb9bfcd 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -11,6 +11,7 @@ | |||
11 | * Copyright (C) 2000, 01 MIPS Technologies, Inc. | 11 | * Copyright (C) 2000, 01 MIPS Technologies, Inc. |
12 | * Copyright (C) 2002, 2003, 2004, 2005 Maciej W. Rozycki | 12 | * Copyright (C) 2002, 2003, 2004, 2005 Maciej W. Rozycki |
13 | */ | 13 | */ |
14 | #include <linux/bug.h> | ||
14 | #include <linux/init.h> | 15 | #include <linux/init.h> |
15 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
16 | #include <linux/module.h> | 17 | #include <linux/module.h> |
@@ -927,12 +928,6 @@ asmlinkage void do_reserved(struct pt_regs *regs) | |||
927 | (regs->cp0_cause & 0x7f) >> 2); | 928 | (regs->cp0_cause & 0x7f) >> 2); |
928 | } | 929 | } |
929 | 930 | ||
930 | static asmlinkage void do_default_vi(void) | ||
931 | { | ||
932 | show_regs(get_irq_regs()); | ||
933 | panic("Caught unexpected vectored interrupt."); | ||
934 | } | ||
935 | |||
936 | /* | 931 | /* |
937 | * Some MIPS CPUs can enable/disable for cache parity detection, but do | 932 | * Some MIPS CPUs can enable/disable for cache parity detection, but do |
938 | * it different ways. | 933 | * it different ways. |
@@ -1128,6 +1123,12 @@ void mips_srs_free(int set) | |||
1128 | clear_bit(set, &sr->sr_allocated); | 1123 | clear_bit(set, &sr->sr_allocated); |
1129 | } | 1124 | } |
1130 | 1125 | ||
1126 | static asmlinkage void do_default_vi(void) | ||
1127 | { | ||
1128 | show_regs(get_irq_regs()); | ||
1129 | panic("Caught unexpected vectored interrupt."); | ||
1130 | } | ||
1131 | |||
1131 | static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) | 1132 | static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) |
1132 | { | 1133 | { |
1133 | unsigned long handler; | 1134 | unsigned long handler; |
@@ -1190,8 +1191,8 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs) | |||
1190 | 1191 | ||
1191 | memcpy (b, &except_vec_vi, handler_len); | 1192 | memcpy (b, &except_vec_vi, handler_len); |
1192 | #ifdef CONFIG_MIPS_MT_SMTC | 1193 | #ifdef CONFIG_MIPS_MT_SMTC |
1193 | if (n > 7) | 1194 | BUG_ON(n > 7); /* Vector index %d exceeds SMTC maximum. */ |
1194 | printk("Vector index %d exceeds SMTC maximum\n", n); | 1195 | |
1195 | w = (u32 *)(b + mori_offset); | 1196 | w = (u32 *)(b + mori_offset); |
1196 | *w = (*w & 0xffff0000) | (0x100 << n); | 1197 | *w = (*w & 0xffff0000) | (0x100 << n); |
1197 | #endif /* CONFIG_MIPS_MT_SMTC */ | 1198 | #endif /* CONFIG_MIPS_MT_SMTC */ |
@@ -1383,6 +1384,13 @@ void __init per_cpu_trap_init(void) | |||
1383 | cpu_cache_init(); | 1384 | cpu_cache_init(); |
1384 | tlb_init(); | 1385 | tlb_init(); |
1385 | #ifdef CONFIG_MIPS_MT_SMTC | 1386 | #ifdef CONFIG_MIPS_MT_SMTC |
1387 | } else if (!secondaryTC) { | ||
1388 | /* | ||
1389 | * First TC in non-boot VPE must do subset of tlb_init() | ||
1390 | * for MMU countrol registers. | ||
1391 | */ | ||
1392 | write_c0_pagemask(PM_DEFAULT_MASK); | ||
1393 | write_c0_wired(0); | ||
1386 | } | 1394 | } |
1387 | #endif /* CONFIG_MIPS_MT_SMTC */ | 1395 | #endif /* CONFIG_MIPS_MT_SMTC */ |
1388 | } | 1396 | } |
@@ -1531,8 +1539,7 @@ void __init trap_init(void) | |||
1531 | if (cpu_has_mipsmt) | 1539 | if (cpu_has_mipsmt) |
1532 | set_except_vector(25, handle_mt); | 1540 | set_except_vector(25, handle_mt); |
1533 | 1541 | ||
1534 | if (cpu_has_dsp) | 1542 | set_except_vector(26, handle_dsp); |
1535 | set_except_vector(26, handle_dsp); | ||
1536 | 1543 | ||
1537 | if (cpu_has_vce) | 1544 | if (cpu_has_vce) |
1538 | /* Special exception: R4[04]00 uses also the divec space. */ | 1545 | /* Special exception: R4[04]00 uses also the divec space. */ |
diff --git a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c index dfa0acbd7fc2..9f49da95aacf 100644 --- a/arch/mips/mips-boards/atlas/atlas_int.c +++ b/arch/mips/mips-boards/atlas/atlas_int.c | |||
@@ -248,14 +248,13 @@ void __init arch_init_irq(void) | |||
248 | case MIPS_REVISION_CORID_CORE_24K: | 248 | case MIPS_REVISION_CORID_CORE_24K: |
249 | case MIPS_REVISION_CORID_CORE_EMUL_MSC: | 249 | case MIPS_REVISION_CORID_CORE_EMUL_MSC: |
250 | if (cpu_has_veic) | 250 | if (cpu_has_veic) |
251 | init_msc_irqs (MSC01E_INT_BASE, | 251 | init_msc_irqs (MSC01E_INT_BASE, MSC01E_INT_BASE, |
252 | msc_eicirqmap, msc_nr_eicirqs); | 252 | msc_eicirqmap, msc_nr_eicirqs); |
253 | else | 253 | else |
254 | init_msc_irqs (MSC01C_INT_BASE, | 254 | init_msc_irqs (MSC01E_INT_BASE, MSC01C_INT_BASE, |
255 | msc_irqmap, msc_nr_irqs); | 255 | msc_irqmap, msc_nr_irqs); |
256 | } | 256 | } |
257 | 257 | ||
258 | |||
259 | if (cpu_has_veic) { | 258 | if (cpu_has_veic) { |
260 | set_vi_handler (MSC01E_INT_ATLAS, atlas_hw0_irqdispatch); | 259 | set_vi_handler (MSC01E_INT_ATLAS, atlas_hw0_irqdispatch); |
261 | setup_irq (MSC01E_INT_BASE + MSC01E_INT_ATLAS, &atlasirq); | 260 | setup_irq (MSC01E_INT_BASE + MSC01E_INT_ATLAS, &atlasirq); |
diff --git a/arch/mips/mips-boards/atlas/atlas_setup.c b/arch/mips/mips-boards/atlas/atlas_setup.c index 0c6b0ce15028..1cc6ebbedfdd 100644 --- a/arch/mips/mips-boards/atlas/atlas_setup.c +++ b/arch/mips/mips-boards/atlas/atlas_setup.c | |||
@@ -48,6 +48,8 @@ const char *get_system_type(void) | |||
48 | return "MIPS Atlas"; | 48 | return "MIPS Atlas"; |
49 | } | 49 | } |
50 | 50 | ||
51 | const char display_string[] = " LINUX ON ATLAS "; | ||
52 | |||
51 | void __init plat_mem_setup(void) | 53 | void __init plat_mem_setup(void) |
52 | { | 54 | { |
53 | mips_pcibios_init(); | 55 | mips_pcibios_init(); |
diff --git a/arch/mips/mips-boards/generic/display.c b/arch/mips/mips-boards/generic/display.c index 548dbe5ce7c8..5d600054090a 100644 --- a/arch/mips/mips-boards/generic/display.c +++ b/arch/mips/mips-boards/generic/display.c | |||
@@ -19,9 +19,14 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/compiler.h> | 21 | #include <linux/compiler.h> |
22 | #include <linux/timer.h> | ||
22 | #include <asm/io.h> | 23 | #include <asm/io.h> |
23 | #include <asm/mips-boards/generic.h> | 24 | #include <asm/mips-boards/generic.h> |
24 | 25 | ||
26 | extern const char display_string[]; | ||
27 | static unsigned int display_count; | ||
28 | static unsigned int max_display_count; | ||
29 | |||
25 | void mips_display_message(const char *str) | 30 | void mips_display_message(const char *str) |
26 | { | 31 | { |
27 | static unsigned int __iomem *display = NULL; | 32 | static unsigned int __iomem *display = NULL; |
@@ -37,3 +42,22 @@ void mips_display_message(const char *str) | |||
37 | writel(' ', display + i); | 42 | writel(' ', display + i); |
38 | } | 43 | } |
39 | } | 44 | } |
45 | |||
46 | static void scroll_display_message(unsigned long data); | ||
47 | static DEFINE_TIMER(mips_scroll_timer, scroll_display_message, HZ, 0); | ||
48 | |||
49 | static void scroll_display_message(unsigned long data) | ||
50 | { | ||
51 | mips_display_message(&display_string[display_count++]); | ||
52 | if (display_count == max_display_count) | ||
53 | display_count = 0; | ||
54 | |||
55 | mod_timer(&mips_scroll_timer, jiffies + HZ); | ||
56 | } | ||
57 | |||
58 | void mips_scroll_message(void) | ||
59 | { | ||
60 | del_timer_sync(&mips_scroll_timer); | ||
61 | max_display_count = strlen(display_string) + 1 - 8; | ||
62 | mod_timer(&mips_scroll_timer, jiffies + 1); | ||
63 | } | ||
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index df2a2bd3aa5d..b41db9e7ab1f 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c | |||
@@ -53,37 +53,11 @@ | |||
53 | 53 | ||
54 | unsigned long cpu_khz; | 54 | unsigned long cpu_khz; |
55 | 55 | ||
56 | #if defined(CONFIG_MIPS_ATLAS) | ||
57 | static char display_string[] = " LINUX ON ATLAS "; | ||
58 | #endif | ||
59 | #if defined(CONFIG_MIPS_MALTA) | ||
60 | #if defined(CONFIG_MIPS_MT_SMTC) | ||
61 | static char display_string[] = " SMTC LINUX ON MALTA "; | ||
62 | #else | ||
63 | static char display_string[] = " LINUX ON MALTA "; | ||
64 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
65 | #endif | ||
66 | #if defined(CONFIG_MIPS_SEAD) | ||
67 | static char display_string[] = " LINUX ON SEAD "; | ||
68 | #endif | ||
69 | static unsigned int display_count; | ||
70 | #define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) | ||
71 | |||
72 | #define CPUCTR_IMASKBIT (0x100 << MIPSCPU_INT_CPUCTR) | 56 | #define CPUCTR_IMASKBIT (0x100 << MIPSCPU_INT_CPUCTR) |
73 | 57 | ||
74 | static unsigned int timer_tick_count; | ||
75 | static int mips_cpu_timer_irq; | 58 | static int mips_cpu_timer_irq; |
76 | extern void smtc_timer_broadcast(int); | 59 | extern void smtc_timer_broadcast(int); |
77 | 60 | ||
78 | static inline void scroll_display_message(void) | ||
79 | { | ||
80 | if ((timer_tick_count++ % HZ) == 0) { | ||
81 | mips_display_message(&display_string[display_count++]); | ||
82 | if (display_count == MAX_DISPLAY_COUNT) | ||
83 | display_count = 0; | ||
84 | } | ||
85 | } | ||
86 | |||
87 | static void mips_timer_dispatch(void) | 61 | static void mips_timer_dispatch(void) |
88 | { | 62 | { |
89 | do_IRQ(mips_cpu_timer_irq); | 63 | do_IRQ(mips_cpu_timer_irq); |
@@ -114,8 +88,6 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id) | |||
114 | * the general MIPS timer_interrupt routine. | 88 | * the general MIPS timer_interrupt routine. |
115 | */ | 89 | */ |
116 | 90 | ||
117 | int vpflags; | ||
118 | |||
119 | /* | 91 | /* |
120 | * We could be here due to timer interrupt, | 92 | * We could be here due to timer interrupt, |
121 | * perf counter overflow, or both. | 93 | * perf counter overflow, or both. |
@@ -124,15 +96,6 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id) | |||
124 | perf_irq(); | 96 | perf_irq(); |
125 | 97 | ||
126 | if (read_c0_cause() & (1 << 30)) { | 98 | if (read_c0_cause() & (1 << 30)) { |
127 | /* If timer interrupt, make it de-assert */ | ||
128 | write_c0_compare (read_c0_count() - 1); | ||
129 | /* | ||
130 | * DVPE is necessary so long as cross-VPE interrupts | ||
131 | * are done via read-modify-write of Cause register. | ||
132 | */ | ||
133 | vpflags = dvpe(); | ||
134 | clear_c0_cause(CPUCTR_IMASKBIT); | ||
135 | evpe(vpflags); | ||
136 | /* | 99 | /* |
137 | * There are things we only want to do once per tick | 100 | * There are things we only want to do once per tick |
138 | * in an "MP" system. One TC of each VPE will take | 101 | * in an "MP" system. One TC of each VPE will take |
@@ -141,15 +104,13 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id) | |||
141 | * the tick on VPE 0 to run the full timer_interrupt(). | 104 | * the tick on VPE 0 to run the full timer_interrupt(). |
142 | */ | 105 | */ |
143 | if (cpu_data[cpu].vpe_id == 0) { | 106 | if (cpu_data[cpu].vpe_id == 0) { |
144 | timer_interrupt(irq, NULL); | 107 | timer_interrupt(irq, NULL); |
145 | smtc_timer_broadcast(cpu_data[cpu].vpe_id); | ||
146 | scroll_display_message(); | ||
147 | } else { | 108 | } else { |
148 | write_c0_compare(read_c0_count() + | 109 | write_c0_compare(read_c0_count() + |
149 | (mips_hpt_frequency/HZ)); | 110 | (mips_hpt_frequency/HZ)); |
150 | local_timer_interrupt(irq, dev_id); | 111 | local_timer_interrupt(irq, dev_id); |
151 | smtc_timer_broadcast(cpu_data[cpu].vpe_id); | ||
152 | } | 112 | } |
113 | smtc_timer_broadcast(cpu_data[cpu].vpe_id); | ||
153 | } | 114 | } |
154 | #else /* CONFIG_MIPS_MT_SMTC */ | 115 | #else /* CONFIG_MIPS_MT_SMTC */ |
155 | int r2 = cpu_has_mips_r2; | 116 | int r2 = cpu_has_mips_r2; |
@@ -167,8 +128,6 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id) | |||
167 | /* we keep interrupt disabled all the time */ | 128 | /* we keep interrupt disabled all the time */ |
168 | if (!r2 || (read_c0_cause() & (1 << 30))) | 129 | if (!r2 || (read_c0_cause() & (1 << 30))) |
169 | timer_interrupt(irq, NULL); | 130 | timer_interrupt(irq, NULL); |
170 | |||
171 | scroll_display_message(); | ||
172 | } else { | 131 | } else { |
173 | /* Everyone else needs to reset the timer int here as | 132 | /* Everyone else needs to reset the timer int here as |
174 | ll_local_timer_interrupt doesn't */ | 133 | ll_local_timer_interrupt doesn't */ |
@@ -262,6 +221,8 @@ void __init mips_time_init(void) | |||
262 | (est_freq%1000000)*100/1000000); | 221 | (est_freq%1000000)*100/1000000); |
263 | 222 | ||
264 | cpu_khz = est_freq / 1000; | 223 | cpu_khz = est_freq / 1000; |
224 | |||
225 | mips_scroll_message(); | ||
265 | } | 226 | } |
266 | 227 | ||
267 | void __init plat_timer_setup(struct irqaction *irq) | 228 | void __init plat_timer_setup(struct irqaction *irq) |
diff --git a/arch/mips/mips-boards/malta/malta_setup.c b/arch/mips/mips-boards/malta/malta_setup.c index 7873932532a1..c14b7bf89950 100644 --- a/arch/mips/mips-boards/malta/malta_setup.c +++ b/arch/mips/mips-boards/malta/malta_setup.c | |||
@@ -56,6 +56,12 @@ const char *get_system_type(void) | |||
56 | return "MIPS Malta"; | 56 | return "MIPS Malta"; |
57 | } | 57 | } |
58 | 58 | ||
59 | #if defined(CONFIG_MIPS_MT_SMTC) | ||
60 | const char display_string[] = " SMTC LINUX ON MALTA "; | ||
61 | #else | ||
62 | const char display_string[] = " LINUX ON MALTA "; | ||
63 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
64 | |||
59 | #ifdef CONFIG_BLK_DEV_FD | 65 | #ifdef CONFIG_BLK_DEV_FD |
60 | void __init fd_activate(void) | 66 | void __init fd_activate(void) |
61 | { | 67 | { |
diff --git a/arch/mips/mips-boards/sead/sead_setup.c b/arch/mips/mips-boards/sead/sead_setup.c index a189dec7c7bc..811aba100605 100644 --- a/arch/mips/mips-boards/sead/sead_setup.c +++ b/arch/mips/mips-boards/sead/sead_setup.c | |||
@@ -43,6 +43,8 @@ const char *get_system_type(void) | |||
43 | return "MIPS SEAD"; | 43 | return "MIPS SEAD"; |
44 | } | 44 | } |
45 | 45 | ||
46 | const char display_string[] = " LINUX ON SEAD "; | ||
47 | |||
46 | void __init plat_mem_setup(void) | 48 | void __init plat_mem_setup(void) |
47 | { | 49 | { |
48 | ioport_resource.end = 0x7fffffff; | 50 | ioport_resource.end = 0x7fffffff; |
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index f0eb29917d9a..76903c727647 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c | |||
@@ -168,8 +168,9 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, | |||
168 | addr = (unsigned long) page_address(sg->page); | 168 | addr = (unsigned long) page_address(sg->page); |
169 | if (!plat_device_is_coherent(dev) && addr) | 169 | if (!plat_device_is_coherent(dev) && addr) |
170 | __dma_sync(addr + sg->offset, sg->length, direction); | 170 | __dma_sync(addr + sg->offset, sg->length, direction); |
171 | sg->dma_address = plat_map_dma_mem_page(dev, sg->page) + | 171 | sg->dma_address = plat_map_dma_mem(dev, |
172 | sg->offset; | 172 | (void *)(addr + sg->offset), |
173 | sg->length); | ||
173 | } | 174 | } |
174 | 175 | ||
175 | return nents; | 176 | return nents; |
diff --git a/arch/mips/pci/pci-ocelot.c b/arch/mips/pci/pci-ocelot.c index 7f94f26d35ae..1421d34535ef 100644 --- a/arch/mips/pci/pci-ocelot.c +++ b/arch/mips/pci/pci-ocelot.c | |||
@@ -71,19 +71,19 @@ static inline void pci0WriteConfigReg(unsigned int offset, unsigned int data) | |||
71 | } | 71 | } |
72 | 72 | ||
73 | static struct resource ocelot_mem_resource = { | 73 | static struct resource ocelot_mem_resource = { |
74 | start = GT_PCI_MEM_BASE; | 74 | .start = GT_PCI_MEM_BASE, |
75 | end = GT_PCI_MEM_BASE + GT_PCI_MEM_BASE - 1; | 75 | .end = GT_PCI_MEM_BASE + GT_PCI_MEM_BASE - 1, |
76 | }; | 76 | }; |
77 | 77 | ||
78 | static struct resource ocelot_io_resource = { | 78 | static struct resource ocelot_io_resource = { |
79 | start = GT_PCI_IO_BASE; | 79 | .start = GT_PCI_IO_BASE, |
80 | end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1; | 80 | .end = GT_PCI_IO_BASE + GT_PCI_IO_SIZE - 1, |
81 | }; | 81 | }; |
82 | 82 | ||
83 | static struct pci_controller ocelot_pci_controller = { | 83 | static struct pci_controller ocelot_pci_controller = { |
84 | .pci_ops = gt64xxx_pci0_ops; | 84 | .pci_ops = gt64xxx_pci0_ops, |
85 | .mem_resource = &ocelot_mem_resource; | 85 | .mem_resource = &ocelot_mem_resource, |
86 | .io_resource = &ocelot_io_resource; | 86 | .io_resource = &ocelot_io_resource, |
87 | }; | 87 | }; |
88 | 88 | ||
89 | static int __init ocelot_pcibios_init(void) | 89 | static int __init ocelot_pcibios_init(void) |
diff --git a/arch/mips/qemu/q-irq.c b/arch/mips/qemu/q-irq.c index f5ea2fe10f14..89891e984b3b 100644 --- a/arch/mips/qemu/q-irq.c +++ b/arch/mips/qemu/q-irq.c | |||
@@ -7,8 +7,6 @@ | |||
7 | #include <asm/system.h> | 7 | #include <asm/system.h> |
8 | #include <asm/time.h> | 8 | #include <asm/time.h> |
9 | 9 | ||
10 | extern asmlinkage void qemu_handle_int(void); | ||
11 | |||
12 | asmlinkage void plat_irq_dispatch(void) | 10 | asmlinkage void plat_irq_dispatch(void) |
13 | { | 11 | { |
14 | unsigned int pending = read_c0_status() & read_c0_cause(); | 12 | unsigned int pending = read_c0_status() & read_c0_cause(); |
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c index fe8a1066aec1..e5e023f50a07 100644 --- a/arch/mips/sgi-ip27/ip27-memory.c +++ b/arch/mips/sgi-ip27/ip27-memory.c | |||
@@ -517,7 +517,7 @@ void __init paging_init(void) | |||
517 | pfn_t start_pfn = slot_getbasepfn(node, 0); | 517 | pfn_t start_pfn = slot_getbasepfn(node, 0); |
518 | pfn_t end_pfn = node_getmaxclick(node) + 1; | 518 | pfn_t end_pfn = node_getmaxclick(node) + 1; |
519 | 519 | ||
520 | zones_size[ZONE_DMA] = end_pfn - start_pfn; | 520 | zones_size[ZONE_NORMAL] = end_pfn - start_pfn; |
521 | free_area_init_node(node, NODE_DATA(node), | 521 | free_area_init_node(node, NODE_DATA(node), |
522 | zones_size, start_pfn, NULL); | 522 | zones_size, start_pfn, NULL); |
523 | 523 | ||
diff --git a/arch/mips/sgi-ip32/Makefile b/arch/mips/sgi-ip32/Makefile index 7e1416768a60..60f0227425e7 100644 --- a/arch/mips/sgi-ip32/Makefile +++ b/arch/mips/sgi-ip32/Makefile | |||
@@ -3,5 +3,5 @@ | |||
3 | # under Linux. | 3 | # under Linux. |
4 | # | 4 | # |
5 | 5 | ||
6 | obj-y += ip32-berr.o ip32-irq.o ip32-setup.o ip32-reset.o \ | 6 | obj-y += ip32-berr.o ip32-irq.o ip32-platform.o ip32-setup.o ip32-reset.o \ |
7 | crime.o ip32-memory.o | 7 | crime.o ip32-memory.o |
diff --git a/arch/mips/sgi-ip32/ip32-platform.c b/arch/mips/sgi-ip32/ip32-platform.c new file mode 100644 index 000000000000..120b15932caf --- /dev/null +++ b/arch/mips/sgi-ip32/ip32-platform.c | |||
@@ -0,0 +1,20 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/platform_device.h> | ||
3 | |||
4 | static __init int meth_devinit(void) | ||
5 | { | ||
6 | struct platform_device *pd; | ||
7 | int ret; | ||
8 | |||
9 | pd = platform_device_alloc("meth", -1); | ||
10 | if (!pd) | ||
11 | return -ENOMEM; | ||
12 | |||
13 | ret = platform_device_add(pd); | ||
14 | if (ret) | ||
15 | platform_device_put(pd); | ||
16 | |||
17 | return ret; | ||
18 | } | ||
19 | |||
20 | device_initcall(meth_devinit); | ||
diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c index 9ee208daa8b1..97b234361b4d 100644 --- a/arch/mips/sni/pcimt.c +++ b/arch/mips/sni/pcimt.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * for more details. | 6 | * for more details. |
7 | * | 7 | * |
8 | * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org) | 8 | * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org) |
9 | * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de) | 9 | * Copyright (C) 2006,2007 Thomas Bogendoerfer (tsbogend@alpha.franken.de) |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
@@ -131,6 +131,19 @@ static struct resource pcimt_io_resources[] = { | |||
131 | } | 131 | } |
132 | }; | 132 | }; |
133 | 133 | ||
134 | static struct resource pcimt_mem_resources[] = { | ||
135 | { | ||
136 | /* | ||
137 | * this region should only be 4 bytes long, | ||
138 | * but it's 16MB on all RM300C I've checked | ||
139 | */ | ||
140 | .start = 0x1a000000, | ||
141 | .end = 0x1affffff, | ||
142 | .name = "PCI INT ACK", | ||
143 | .flags = IORESOURCE_BUSY | ||
144 | } | ||
145 | }; | ||
146 | |||
134 | static struct resource sni_mem_resource = { | 147 | static struct resource sni_mem_resource = { |
135 | .start = 0x18000000UL, | 148 | .start = 0x18000000UL, |
136 | .end = 0x1fbfffffUL, | 149 | .end = 0x1fbfffffUL, |
@@ -145,6 +158,9 @@ static void __init sni_pcimt_resource_init(void) | |||
145 | /* request I/O space for devices used on all i[345]86 PCs */ | 158 | /* request I/O space for devices used on all i[345]86 PCs */ |
146 | for (i = 0; i < ARRAY_SIZE(pcimt_io_resources); i++) | 159 | for (i = 0; i < ARRAY_SIZE(pcimt_io_resources); i++) |
147 | request_resource(&sni_io_resource, pcimt_io_resources + i); | 160 | request_resource(&sni_io_resource, pcimt_io_resources + i); |
161 | /* request MEM space for devices used on all i[345]86 PCs */ | ||
162 | for (i = 0; i < ARRAY_SIZE(pcimt_mem_resources); i++) | ||
163 | request_resource(&sni_mem_resource, pcimt_mem_resources + i); | ||
148 | } | 164 | } |
149 | 165 | ||
150 | extern struct pci_ops sni_pcimt_ops; | 166 | extern struct pci_ops sni_pcimt_ops; |
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c index 68d7cf609b4f..4fedfbda0c79 100644 --- a/arch/mips/sni/setup.c +++ b/arch/mips/sni/setup.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * for more details. | 6 | * for more details. |
7 | * | 7 | * |
8 | * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org) | 8 | * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org) |
9 | * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de) | 9 | * Copyright (C) 2006,2007 Thomas Bogendoerfer (tsbogend@alpha.franken.de) |
10 | */ | 10 | */ |
11 | #include <linux/eisa.h> | 11 | #include <linux/eisa.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
@@ -92,3 +92,34 @@ void __init plat_mem_setup(void) | |||
92 | 92 | ||
93 | sni_display_setup(); | 93 | sni_display_setup(); |
94 | } | 94 | } |
95 | |||
96 | #if CONFIG_PCI | ||
97 | |||
98 | #include <linux/pci.h> | ||
99 | #include <video/vga.h> | ||
100 | #include <video/cirrus.h> | ||
101 | |||
102 | static void __devinit quirk_cirrus_ram_size(struct pci_dev *dev) | ||
103 | { | ||
104 | u16 cmd; | ||
105 | |||
106 | /* | ||
107 | * firmware doesn't set the ram size correct, so we | ||
108 | * need to do it here, otherwise we get screen corruption | ||
109 | * on older Cirrus chips | ||
110 | */ | ||
111 | pci_read_config_word (dev, PCI_COMMAND, &cmd); | ||
112 | if ((cmd & (PCI_COMMAND_IO|PCI_COMMAND_MEMORY)) | ||
113 | == (PCI_COMMAND_IO|PCI_COMMAND_MEMORY)) { | ||
114 | vga_wseq (NULL, CL_SEQR6, 0x12); /* unlock all extension registers */ | ||
115 | vga_wseq (NULL, CL_SEQRF, 0x18); | ||
116 | } | ||
117 | } | ||
118 | |||
119 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5434_8, | ||
120 | quirk_cirrus_ram_size); | ||
121 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5436, | ||
122 | quirk_cirrus_ram_size); | ||
123 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5446, | ||
124 | quirk_cirrus_ram_size); | ||
125 | #endif | ||
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 56d3c0dcd2b8..5eaeafd30bdf 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -118,6 +118,7 @@ config GENERIC_BUG | |||
118 | depends on BUG | 118 | depends on BUG |
119 | 119 | ||
120 | config SYS_SUPPORTS_APM_EMULATION | 120 | config SYS_SUPPORTS_APM_EMULATION |
121 | default y if PMAC_APM_EMU | ||
121 | bool | 122 | bool |
122 | 123 | ||
123 | config DEFAULT_UIMAGE | 124 | config DEFAULT_UIMAGE |
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 6238b5875fd1..fbafd965dcd2 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
@@ -142,7 +142,6 @@ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ | |||
142 | 142 | ||
143 | # Default to zImage, override when needed | 143 | # Default to zImage, override when needed |
144 | defaultimage-y := zImage | 144 | defaultimage-y := zImage |
145 | defaultimage-$(CONFIG_PPC_ISERIES) := vmlinux | ||
146 | defaultimage-$(CONFIG_DEFAULT_UIMAGE) := uImage | 145 | defaultimage-$(CONFIG_DEFAULT_UIMAGE) := uImage |
147 | KBUILD_IMAGE := $(defaultimage-y) | 146 | KBUILD_IMAGE := $(defaultimage-y) |
148 | all: $(KBUILD_IMAGE) | 147 | all: $(KBUILD_IMAGE) |
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 83788986b93b..ff2701949ee1 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile | |||
@@ -11,20 +11,18 @@ | |||
11 | # bootloader and increase compatibility with OpenFirmware. | 11 | # bootloader and increase compatibility with OpenFirmware. |
12 | # | 12 | # |
13 | # To this end we need to define BOOTCC, etc, as the tools | 13 | # To this end we need to define BOOTCC, etc, as the tools |
14 | # needed to build the 32 bit image. These are normally HOSTCC, | 14 | # needed to build the 32 bit image. That's normally the same |
15 | # but may be a third compiler if, for example, you are cross | 15 | # compiler for the rest of the kernel, with the -m32 flag added. |
16 | # compiling from an intel box. Once the 64bit ppc gcc is | ||
17 | # stable it will probably simply be a compiler switch to | ||
18 | # compile for 32bit mode. | ||
19 | # To make it easier to setup a cross compiler, | 16 | # To make it easier to setup a cross compiler, |
20 | # CROSS32_COMPILE is setup as a prefix just like CROSS_COMPILE | 17 | # CROSS32_COMPILE is setup as a prefix just like CROSS_COMPILE |
21 | # in the toplevel makefile. | 18 | # in the toplevel makefile. |
22 | 19 | ||
23 | all: $(obj)/zImage | 20 | all: $(obj)/zImage |
24 | 21 | ||
25 | HOSTCC := gcc | 22 | BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ |
26 | BOOTCFLAGS := $(HOSTCFLAGS) -fno-builtin -nostdinc -isystem \ | 23 | -fno-strict-aliasing -Os -msoft-float -pipe \ |
27 | $(shell $(CROSS32CC) -print-file-name=include) -fPIC | 24 | -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \ |
25 | -isystem $(shell $(CROSS32CC) -print-file-name=include) | ||
28 | BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc | 26 | BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc |
29 | 27 | ||
30 | ifeq ($(call cc-option-yn, -fstack-protector),y) | 28 | ifeq ($(call cc-option-yn, -fstack-protector),y) |
@@ -33,8 +31,8 @@ endif | |||
33 | 31 | ||
34 | BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) | 32 | BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) |
35 | 33 | ||
36 | $(obj)/44x.o: BOOTCFLAGS += -Wa,-mbooke | 34 | $(obj)/44x.o: BOOTCFLAGS += -mcpu=440 |
37 | $(obj)/ebony.o: BOOTCFLAGS += -Wa,-mbooke | 35 | $(obj)/ebony.o: BOOTCFLAGS += -mcpu=440 |
38 | 36 | ||
39 | zlib := inffast.c inflate.c inftrees.c | 37 | zlib := inffast.c inflate.c inftrees.c |
40 | zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h | 38 | zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h |
@@ -136,6 +134,7 @@ image-$(CONFIG_PPC_EFIKA) += zImage.chrp | |||
136 | image-$(CONFIG_PPC_PMAC) += zImage.pmac | 134 | image-$(CONFIG_PPC_PMAC) += zImage.pmac |
137 | image-$(CONFIG_PPC_HOLLY) += zImage.holly-elf | 135 | image-$(CONFIG_PPC_HOLLY) += zImage.holly-elf |
138 | image-$(CONFIG_PPC_PRPMC2800) += zImage.prpmc2800 | 136 | image-$(CONFIG_PPC_PRPMC2800) += zImage.prpmc2800 |
137 | image-$(CONFIG_PPC_ISERIES) += zImage.iseries | ||
139 | image-$(CONFIG_DEFAULT_UIMAGE) += uImage | 138 | image-$(CONFIG_DEFAULT_UIMAGE) += uImage |
140 | 139 | ||
141 | ifneq ($(CONFIG_DEVICE_TREE),"") | 140 | ifneq ($(CONFIG_DEVICE_TREE),"") |
@@ -185,6 +184,9 @@ $(obj)/zImage.initrd.%: vmlinux $(wrapperbits) | |||
185 | $(obj)/zImage.%: vmlinux $(wrapperbits) | 184 | $(obj)/zImage.%: vmlinux $(wrapperbits) |
186 | $(call if_changed,wrap,$*) | 185 | $(call if_changed,wrap,$*) |
187 | 186 | ||
187 | $(obj)/zImage.iseries: vmlinux | ||
188 | $(STRIP) -s -R .comment $< -o $@ | ||
189 | |||
188 | $(obj)/zImage.ps3: vmlinux | 190 | $(obj)/zImage.ps3: vmlinux |
189 | $(STRIP) -s -R .comment $< -o $@ | 191 | $(STRIP) -s -R .comment $< -o $@ |
190 | 192 | ||
diff --git a/arch/powerpc/boot/crt0.S b/arch/powerpc/boot/crt0.S index 5a4215c4b014..f1c4dfc635be 100644 --- a/arch/powerpc/boot/crt0.S +++ b/arch/powerpc/boot/crt0.S | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | .text | 14 | .text |
15 | /* a procedure descriptor used when booting this as a COFF file */ | 15 | /* a procedure descriptor used when booting this as a COFF file */ |
16 | .globl _zimage_start_opd | ||
16 | _zimage_start_opd: | 17 | _zimage_start_opd: |
17 | .long _zimage_start, 0, 0, 0 | 18 | .long _zimage_start, 0, 0, 0 |
18 | 19 | ||
diff --git a/arch/powerpc/boot/dts/lite5200.dts b/arch/powerpc/boot/dts/lite5200.dts index eae68ab1177f..d29308fe4c24 100644 --- a/arch/powerpc/boot/dts/lite5200.dts +++ b/arch/powerpc/boot/dts/lite5200.dts | |||
@@ -67,7 +67,7 @@ | |||
67 | interrupt-controller; | 67 | interrupt-controller; |
68 | #interrupt-cells = <3>; | 68 | #interrupt-cells = <3>; |
69 | device_type = "interrupt-controller"; | 69 | device_type = "interrupt-controller"; |
70 | compatible = "mpc5200_pic"; | 70 | compatible = "mpc5200-pic"; |
71 | reg = <500 80>; | 71 | reg = <500 80>; |
72 | built-in; | 72 | built-in; |
73 | }; | 73 | }; |
diff --git a/arch/powerpc/boot/dts/lite5200b.dts b/arch/powerpc/boot/dts/lite5200b.dts index 5185625a9419..f242531f0451 100644 --- a/arch/powerpc/boot/dts/lite5200b.dts +++ b/arch/powerpc/boot/dts/lite5200b.dts | |||
@@ -67,7 +67,7 @@ | |||
67 | interrupt-controller; | 67 | interrupt-controller; |
68 | #interrupt-cells = <3>; | 68 | #interrupt-cells = <3>; |
69 | device_type = "interrupt-controller"; | 69 | device_type = "interrupt-controller"; |
70 | compatible = "mpc5200b-pic\0mpc5200_pic"; | 70 | compatible = "mpc5200b-pic\0mpc5200-pic"; |
71 | reg = <500 80>; | 71 | reg = <500 80>; |
72 | built-in; | 72 | built-in; |
73 | }; | 73 | }; |
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index 2ed8b8b3f0ec..da77adc73078 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper | |||
@@ -129,7 +129,7 @@ case "$platform" in | |||
129 | pmac|pseries|chrp) | 129 | pmac|pseries|chrp) |
130 | platformo=$object/of.o | 130 | platformo=$object/of.o |
131 | ;; | 131 | ;; |
132 | pmaccoff) | 132 | coff) |
133 | platformo=$object/of.o | 133 | platformo=$object/of.o |
134 | lds=$object/zImage.coff.lds | 134 | lds=$object/zImage.coff.lds |
135 | ;; | 135 | ;; |
@@ -220,7 +220,7 @@ case "$platform" in | |||
220 | pseries|chrp) | 220 | pseries|chrp) |
221 | $object/addnote "$ofile" | 221 | $object/addnote "$ofile" |
222 | ;; | 222 | ;; |
223 | pmaccoff) | 223 | coff) |
224 | ${CROSS}objcopy -O aixcoff-rs6000 --set-start "$entry" "$ofile" | 224 | ${CROSS}objcopy -O aixcoff-rs6000 --set-start "$entry" "$ofile" |
225 | $object/hack-coff "$ofile" | 225 | $object/hack-coff "$ofile" |
226 | ;; | 226 | ;; |
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 6ef87fb90b8e..b2b5d664d328 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c | |||
@@ -235,6 +235,7 @@ static struct cpu_spec cpu_specs[] = { | |||
235 | .icache_bsize = 128, | 235 | .icache_bsize = 128, |
236 | .dcache_bsize = 128, | 236 | .dcache_bsize = 128, |
237 | .num_pmcs = 8, | 237 | .num_pmcs = 8, |
238 | .pmc_type = PPC_PMC_IBM, | ||
238 | .cpu_setup = __setup_cpu_ppc970, | 239 | .cpu_setup = __setup_cpu_ppc970, |
239 | .cpu_restore = __restore_cpu_ppc970, | 240 | .cpu_restore = __restore_cpu_ppc970, |
240 | .oprofile_cpu_type = "ppc64/970MP", | 241 | .oprofile_cpu_type = "ppc64/970MP", |
@@ -251,6 +252,7 @@ static struct cpu_spec cpu_specs[] = { | |||
251 | .icache_bsize = 128, | 252 | .icache_bsize = 128, |
252 | .dcache_bsize = 128, | 253 | .dcache_bsize = 128, |
253 | .num_pmcs = 8, | 254 | .num_pmcs = 8, |
255 | .pmc_type = PPC_PMC_IBM, | ||
254 | .cpu_setup = __setup_cpu_ppc970MP, | 256 | .cpu_setup = __setup_cpu_ppc970MP, |
255 | .cpu_restore = __restore_cpu_ppc970, | 257 | .cpu_restore = __restore_cpu_ppc970, |
256 | .oprofile_cpu_type = "ppc64/970MP", | 258 | .oprofile_cpu_type = "ppc64/970MP", |
@@ -317,6 +319,7 @@ static struct cpu_spec cpu_specs[] = { | |||
317 | .icache_bsize = 128, | 319 | .icache_bsize = 128, |
318 | .dcache_bsize = 128, | 320 | .dcache_bsize = 128, |
319 | .num_pmcs = 6, | 321 | .num_pmcs = 6, |
322 | .pmc_type = PPC_PMC_IBM, | ||
320 | .oprofile_cpu_type = "ppc64/power6", | 323 | .oprofile_cpu_type = "ppc64/power6", |
321 | .oprofile_type = PPC_OPROFILE_POWER4, | 324 | .oprofile_type = PPC_OPROFILE_POWER4, |
322 | .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV, | 325 | .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV, |
@@ -335,6 +338,7 @@ static struct cpu_spec cpu_specs[] = { | |||
335 | .icache_bsize = 128, | 338 | .icache_bsize = 128, |
336 | .dcache_bsize = 128, | 339 | .dcache_bsize = 128, |
337 | .num_pmcs = 6, | 340 | .num_pmcs = 6, |
341 | .pmc_type = PPC_PMC_IBM, | ||
338 | .oprofile_cpu_type = "ppc64/power6", | 342 | .oprofile_cpu_type = "ppc64/power6", |
339 | .oprofile_type = PPC_OPROFILE_POWER4, | 343 | .oprofile_type = PPC_OPROFILE_POWER4, |
340 | .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV, | 344 | .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV, |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 068377a2a8dc..42c8ed6ed528 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -489,7 +489,7 @@ struct irq_host *irq_alloc_host(unsigned int revmap_type, | |||
489 | case IRQ_HOST_MAP_LINEAR: | 489 | case IRQ_HOST_MAP_LINEAR: |
490 | rmap = (unsigned int *)(host + 1); | 490 | rmap = (unsigned int *)(host + 1); |
491 | for (i = 0; i < revmap_arg; i++) | 491 | for (i = 0; i < revmap_arg; i++) |
492 | rmap[i] = IRQ_NONE; | 492 | rmap[i] = NO_IRQ; |
493 | host->revmap_data.linear.size = revmap_arg; | 493 | host->revmap_data.linear.size = revmap_arg; |
494 | smp_wmb(); | 494 | smp_wmb(); |
495 | host->revmap_data.linear.revmap = rmap; | 495 | host->revmap_data.linear.revmap = rmap; |
@@ -614,7 +614,7 @@ unsigned int irq_create_mapping(struct irq_host *host, | |||
614 | * host->ops->map() to update the flags | 614 | * host->ops->map() to update the flags |
615 | */ | 615 | */ |
616 | virq = irq_find_mapping(host, hwirq); | 616 | virq = irq_find_mapping(host, hwirq); |
617 | if (virq != IRQ_NONE) { | 617 | if (virq != NO_IRQ) { |
618 | if (host->ops->remap) | 618 | if (host->ops->remap) |
619 | host->ops->remap(host, virq, hwirq); | 619 | host->ops->remap(host, virq, hwirq); |
620 | pr_debug("irq: -> existing mapping on virq %d\n", virq); | 620 | pr_debug("irq: -> existing mapping on virq %d\n", virq); |
@@ -741,7 +741,7 @@ void irq_dispose_mapping(unsigned int virq) | |||
741 | switch(host->revmap_type) { | 741 | switch(host->revmap_type) { |
742 | case IRQ_HOST_MAP_LINEAR: | 742 | case IRQ_HOST_MAP_LINEAR: |
743 | if (hwirq < host->revmap_data.linear.size) | 743 | if (hwirq < host->revmap_data.linear.size) |
744 | host->revmap_data.linear.revmap[hwirq] = IRQ_NONE; | 744 | host->revmap_data.linear.revmap[hwirq] = NO_IRQ; |
745 | break; | 745 | break; |
746 | case IRQ_HOST_MAP_TREE: | 746 | case IRQ_HOST_MAP_TREE: |
747 | /* Check if radix tree allocated yet */ | 747 | /* Check if radix tree allocated yet */ |
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c index d501c23e5159..d454f61c9c7c 100644 --- a/arch/powerpc/kernel/of_platform.c +++ b/arch/powerpc/kernel/of_platform.c | |||
@@ -433,7 +433,7 @@ static int __devinit of_pci_phb_probe(struct of_device *dev, | |||
433 | * Note also that we don't do ISA, this will also be fixed with a | 433 | * Note also that we don't do ISA, this will also be fixed with a |
434 | * more massive rework. | 434 | * more massive rework. |
435 | */ | 435 | */ |
436 | pci_setup_phb_io(phb, 0); | 436 | pci_setup_phb_io(phb, pci_io_base == 0); |
437 | 437 | ||
438 | /* Init pci_dn data structures */ | 438 | /* Init pci_dn data structures */ |
439 | pci_devs_phb_init_dynamic(phb); | 439 | pci_devs_phb_init_dynamic(phb); |
diff --git a/arch/powerpc/kernel/pmc.c b/arch/powerpc/kernel/pmc.c index 24d7b7c99bb9..ea04e0ab3f2f 100644 --- a/arch/powerpc/kernel/pmc.c +++ b/arch/powerpc/kernel/pmc.c | |||
@@ -20,8 +20,8 @@ | |||
20 | #include <asm/cputable.h> | 20 | #include <asm/cputable.h> |
21 | #include <asm/pmc.h> | 21 | #include <asm/pmc.h> |
22 | 22 | ||
23 | #ifndef MMCR0_PMA0 | 23 | #ifndef MMCR0_PMAO |
24 | #define MMCR0_PMA0 0 | 24 | #define MMCR0_PMAO 0 |
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | static void dummy_perf(struct pt_regs *regs) | 27 | static void dummy_perf(struct pt_regs *regs) |
@@ -30,7 +30,7 @@ static void dummy_perf(struct pt_regs *regs) | |||
30 | mtpmr(PMRN_PMGC0, mfpmr(PMRN_PMGC0) & ~PMGC0_PMIE); | 30 | mtpmr(PMRN_PMGC0, mfpmr(PMRN_PMGC0) & ~PMGC0_PMIE); |
31 | #elif defined(CONFIG_PPC64) || defined(CONFIG_6xx) | 31 | #elif defined(CONFIG_PPC64) || defined(CONFIG_6xx) |
32 | if (cur_cpu_spec->pmc_type == PPC_PMC_IBM) | 32 | if (cur_cpu_spec->pmc_type == PPC_PMC_IBM) |
33 | mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~(MMCR0_PMXE|MMCR0_PMA0)); | 33 | mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~(MMCR0_PMXE|MMCR0_PMAO)); |
34 | #else | 34 | #else |
35 | mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_PMXE); | 35 | mtspr(SPRN_MMCR0, mfspr(SPRN_MMCR0) & ~MMCR0_PMXE); |
36 | #endif | 36 | #endif |
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 066a6a7a25b8..af42ddab3ab4 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -1171,11 +1171,12 @@ EXPORT_SYMBOL(of_find_node_by_name); | |||
1171 | 1171 | ||
1172 | /** | 1172 | /** |
1173 | * of_find_node_by_type - Find a node by its "device_type" property | 1173 | * of_find_node_by_type - Find a node by its "device_type" property |
1174 | * @from: The node to start searching from or NULL, the node | 1174 | * @from: The node to start searching from, or NULL to start searching |
1175 | * you pass will not be searched, only the next one | 1175 | * the entire device tree. The node you pass will not be |
1176 | * will; typically, you pass what the previous call | 1176 | * searched, only the next one will; typically, you pass |
1177 | * returned. of_node_put() will be called on it | 1177 | * what the previous call returned. of_node_put() will be |
1178 | * @name: The type string to match against | 1178 | * called on from for you. |
1179 | * @type: The type string to match against | ||
1179 | * | 1180 | * |
1180 | * Returns a node pointer with refcount incremented, use | 1181 | * Returns a node pointer with refcount incremented, use |
1181 | * of_node_put() on it when done. | 1182 | * of_node_put() on it when done. |
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index f4f391cdd8f5..bf76562167c3 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
@@ -218,6 +218,7 @@ set_single_step(struct task_struct *task) | |||
218 | regs->msr |= MSR_SE; | 218 | regs->msr |= MSR_SE; |
219 | #endif | 219 | #endif |
220 | } | 220 | } |
221 | set_tsk_thread_flag(task, TIF_SINGLESTEP); | ||
221 | } | 222 | } |
222 | 223 | ||
223 | static inline void | 224 | static inline void |
@@ -233,6 +234,7 @@ clear_single_step(struct task_struct *task) | |||
233 | regs->msr &= ~MSR_SE; | 234 | regs->msr &= ~MSR_SE; |
234 | #endif | 235 | #endif |
235 | } | 236 | } |
237 | clear_tsk_thread_flag(task, TIF_SINGLESTEP); | ||
236 | } | 238 | } |
237 | #endif /* CONFIG_PPC32 */ | 239 | #endif /* CONFIG_PPC32 */ |
238 | 240 | ||
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 22f1ef1b3100..d577b71db375 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -201,13 +201,6 @@ int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic, | |||
201 | /* Can deadlock when called with interrupts disabled */ | 201 | /* Can deadlock when called with interrupts disabled */ |
202 | WARN_ON(irqs_disabled()); | 202 | WARN_ON(irqs_disabled()); |
203 | 203 | ||
204 | /* remove 'self' from the map */ | ||
205 | if (cpu_isset(smp_processor_id(), map)) | ||
206 | cpu_clear(smp_processor_id(), map); | ||
207 | |||
208 | /* sanity check the map, remove any non-online processors. */ | ||
209 | cpus_and(map, map, cpu_online_map); | ||
210 | |||
211 | if (unlikely(smp_ops == NULL)) | 204 | if (unlikely(smp_ops == NULL)) |
212 | return ret; | 205 | return ret; |
213 | 206 | ||
@@ -222,10 +215,17 @@ int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic, | |||
222 | /* Must grab online cpu count with preempt disabled, otherwise | 215 | /* Must grab online cpu count with preempt disabled, otherwise |
223 | * it can change. */ | 216 | * it can change. */ |
224 | num_cpus = num_online_cpus() - 1; | 217 | num_cpus = num_online_cpus() - 1; |
225 | if (!num_cpus || cpus_empty(map)) { | 218 | if (!num_cpus) |
226 | ret = 0; | 219 | goto done; |
227 | goto out; | 220 | |
228 | } | 221 | /* remove 'self' from the map */ |
222 | if (cpu_isset(smp_processor_id(), map)) | ||
223 | cpu_clear(smp_processor_id(), map); | ||
224 | |||
225 | /* sanity check the map, remove any non-online processors. */ | ||
226 | cpus_and(map, map, cpu_online_map); | ||
227 | if (cpus_empty(map)) | ||
228 | goto done; | ||
229 | 229 | ||
230 | call_data = &data; | 230 | call_data = &data; |
231 | smp_wmb(); | 231 | smp_wmb(); |
@@ -263,6 +263,7 @@ int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic, | |||
263 | } | 263 | } |
264 | } | 264 | } |
265 | 265 | ||
266 | done: | ||
266 | ret = 0; | 267 | ret = 0; |
267 | 268 | ||
268 | out: | 269 | out: |
@@ -282,16 +283,17 @@ EXPORT_SYMBOL(smp_call_function); | |||
282 | int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int nonatomic, | 283 | int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int nonatomic, |
283 | int wait) | 284 | int wait) |
284 | { | 285 | { |
285 | cpumask_t map=CPU_MASK_NONE; | 286 | cpumask_t map = CPU_MASK_NONE; |
287 | int ret = -EBUSY; | ||
286 | 288 | ||
287 | if (!cpu_online(cpu)) | 289 | if (!cpu_online(cpu)) |
288 | return -EINVAL; | 290 | return -EINVAL; |
289 | 291 | ||
290 | if (cpu == smp_processor_id()) | ||
291 | return -EBUSY; | ||
292 | |||
293 | cpu_set(cpu, map); | 292 | cpu_set(cpu, map); |
294 | return smp_call_function_map(func,info,nonatomic,wait,map); | 293 | if (cpu != get_cpu()) |
294 | ret = smp_call_function_map(func,info,nonatomic,wait,map); | ||
295 | put_cpu(); | ||
296 | return ret; | ||
295 | } | 297 | } |
296 | EXPORT_SYMBOL(smp_call_function_single); | 298 | EXPORT_SYMBOL(smp_call_function_single); |
297 | 299 | ||
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index f7d7bf19e4fb..21c39ff2dc39 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S | |||
@@ -34,7 +34,6 @@ SECTIONS | |||
34 | /* Text and gots */ | 34 | /* Text and gots */ |
35 | .text : { | 35 | .text : { |
36 | _text = .; | 36 | _text = .; |
37 | *(.text.*) | ||
38 | TEXT_TEXT | 37 | TEXT_TEXT |
39 | SCHED_TEXT | 38 | SCHED_TEXT |
40 | LOCK_TEXT | 39 | LOCK_TEXT |
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 246eeea40ece..0266a94d83b6 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c | |||
@@ -310,11 +310,12 @@ void __init paging_init(void) | |||
310 | 310 | ||
311 | #ifdef CONFIG_HIGHMEM | 311 | #ifdef CONFIG_HIGHMEM |
312 | map_page(PKMAP_BASE, 0, 0); /* XXX gross */ | 312 | map_page(PKMAP_BASE, 0, 0); /* XXX gross */ |
313 | pkmap_page_table = pte_offset_kernel(pmd_offset(pgd_offset_k | 313 | pkmap_page_table = pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k |
314 | (PKMAP_BASE), PKMAP_BASE), PKMAP_BASE); | 314 | (PKMAP_BASE), PKMAP_BASE), PKMAP_BASE), PKMAP_BASE); |
315 | map_page(KMAP_FIX_BEGIN, 0, 0); /* XXX gross */ | 315 | map_page(KMAP_FIX_BEGIN, 0, 0); /* XXX gross */ |
316 | kmap_pte = pte_offset_kernel(pmd_offset(pgd_offset_k | 316 | kmap_pte = pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k |
317 | (KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), KMAP_FIX_BEGIN); | 317 | (KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), |
318 | KMAP_FIX_BEGIN); | ||
318 | kmap_prot = PAGE_KERNEL; | 319 | kmap_prot = PAGE_KERNEL; |
319 | #endif /* CONFIG_HIGHMEM */ | 320 | #endif /* CONFIG_HIGHMEM */ |
320 | 321 | ||
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index d8232b7a08f7..f6ae1a57d652 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c | |||
@@ -93,7 +93,7 @@ void pgd_free(pgd_t *pgd) | |||
93 | free_pages((unsigned long)pgd, PGDIR_ORDER); | 93 | free_pages((unsigned long)pgd, PGDIR_ORDER); |
94 | } | 94 | } |
95 | 95 | ||
96 | pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | 96 | __init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) |
97 | { | 97 | { |
98 | pte_t *pte; | 98 | pte_t *pte; |
99 | extern int mem_init_done; | 99 | extern int mem_init_done; |
diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq.c b/arch/powerpc/platforms/cell/cbe_cpufreq.c index f9ac3fe3be97..ac445998d831 100644 --- a/arch/powerpc/platforms/cell/cbe_cpufreq.c +++ b/arch/powerpc/platforms/cell/cbe_cpufreq.c | |||
@@ -67,6 +67,7 @@ static u64 MIC_Slow_Next_Timer_table[] = { | |||
67 | 0x00003FC000000000ull, | 67 | 0x00003FC000000000ull, |
68 | }; | 68 | }; |
69 | 69 | ||
70 | static unsigned int pmi_frequency_limit = 0; | ||
70 | /* | 71 | /* |
71 | * hardware specific functions | 72 | * hardware specific functions |
72 | */ | 73 | */ |
@@ -164,7 +165,6 @@ static int set_pmode(int cpu, unsigned int slow_mode) { | |||
164 | 165 | ||
165 | static void cbe_cpufreq_handle_pmi(struct of_device *dev, pmi_message_t pmi_msg) | 166 | static void cbe_cpufreq_handle_pmi(struct of_device *dev, pmi_message_t pmi_msg) |
166 | { | 167 | { |
167 | struct cpufreq_policy policy; | ||
168 | u8 cpu; | 168 | u8 cpu; |
169 | u8 cbe_pmode_new; | 169 | u8 cbe_pmode_new; |
170 | 170 | ||
@@ -173,15 +173,27 @@ static void cbe_cpufreq_handle_pmi(struct of_device *dev, pmi_message_t pmi_msg) | |||
173 | cpu = cbe_node_to_cpu(pmi_msg.data1); | 173 | cpu = cbe_node_to_cpu(pmi_msg.data1); |
174 | cbe_pmode_new = pmi_msg.data2; | 174 | cbe_pmode_new = pmi_msg.data2; |
175 | 175 | ||
176 | cpufreq_get_policy(&policy, cpu); | 176 | pmi_frequency_limit = cbe_freqs[cbe_pmode_new].frequency; |
177 | 177 | ||
178 | policy.max = min(policy.max, cbe_freqs[cbe_pmode_new].frequency); | 178 | pr_debug("cbe_handle_pmi: max freq=%d\n", pmi_frequency_limit); |
179 | policy.min = min(policy.min, policy.max); | 179 | } |
180 | |||
181 | static int pmi_notifier(struct notifier_block *nb, | ||
182 | unsigned long event, void *data) | ||
183 | { | ||
184 | struct cpufreq_policy *policy = data; | ||
180 | 185 | ||
181 | pr_debug("cbe_handle_pmi: new policy.min=%d policy.max=%d\n", policy.min, policy.max); | 186 | if (event != CPUFREQ_INCOMPATIBLE) |
182 | cpufreq_set_policy(&policy); | 187 | return 0; |
188 | |||
189 | cpufreq_verify_within_limits(policy, 0, pmi_frequency_limit); | ||
190 | return 0; | ||
183 | } | 191 | } |
184 | 192 | ||
193 | static struct notifier_block pmi_notifier_block = { | ||
194 | .notifier_call = pmi_notifier, | ||
195 | }; | ||
196 | |||
185 | static struct pmi_handler cbe_pmi_handler = { | 197 | static struct pmi_handler cbe_pmi_handler = { |
186 | .type = PMI_TYPE_FREQ_CHANGE, | 198 | .type = PMI_TYPE_FREQ_CHANGE, |
187 | .handle_pmi_message = cbe_cpufreq_handle_pmi, | 199 | .handle_pmi_message = cbe_cpufreq_handle_pmi, |
@@ -238,12 +250,21 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy) | |||
238 | 250 | ||
239 | cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu); | 251 | cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu); |
240 | 252 | ||
253 | if (pmi_dev) { | ||
254 | /* frequency might get limited later, initialize limit with max_freq */ | ||
255 | pmi_frequency_limit = max_freq; | ||
256 | cpufreq_register_notifier(&pmi_notifier_block, CPUFREQ_POLICY_NOTIFIER); | ||
257 | } | ||
258 | |||
241 | /* this ensures that policy->cpuinfo_min and policy->cpuinfo_max are set correctly */ | 259 | /* this ensures that policy->cpuinfo_min and policy->cpuinfo_max are set correctly */ |
242 | return cpufreq_frequency_table_cpuinfo(policy, cbe_freqs); | 260 | return cpufreq_frequency_table_cpuinfo(policy, cbe_freqs); |
243 | } | 261 | } |
244 | 262 | ||
245 | static int cbe_cpufreq_cpu_exit(struct cpufreq_policy *policy) | 263 | static int cbe_cpufreq_cpu_exit(struct cpufreq_policy *policy) |
246 | { | 264 | { |
265 | if (pmi_dev) | ||
266 | cpufreq_unregister_notifier(&pmi_notifier_block, CPUFREQ_POLICY_NOTIFIER); | ||
267 | |||
247 | cpufreq_frequency_table_put_attr(policy->cpu); | 268 | cpufreq_frequency_table_put_attr(policy->cpu); |
248 | return 0; | 269 | return 0; |
249 | } | 270 | } |
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c index 8654749e317b..7c51cb54bca1 100644 --- a/arch/powerpc/platforms/cell/spufs/context.c +++ b/arch/powerpc/platforms/cell/spufs/context.c | |||
@@ -39,7 +39,7 @@ struct spu_context *alloc_spu_context(struct spu_gang *gang) | |||
39 | if (spu_init_csa(&ctx->csa)) | 39 | if (spu_init_csa(&ctx->csa)) |
40 | goto out_free; | 40 | goto out_free; |
41 | spin_lock_init(&ctx->mmio_lock); | 41 | spin_lock_init(&ctx->mmio_lock); |
42 | spin_lock_init(&ctx->mapping_lock); | 42 | mutex_init(&ctx->mapping_lock); |
43 | kref_init(&ctx->kref); | 43 | kref_init(&ctx->kref); |
44 | mutex_init(&ctx->state_mutex); | 44 | mutex_init(&ctx->state_mutex); |
45 | mutex_init(&ctx->run_mutex); | 45 | mutex_init(&ctx->run_mutex); |
@@ -103,6 +103,7 @@ void spu_forget(struct spu_context *ctx) | |||
103 | 103 | ||
104 | void spu_unmap_mappings(struct spu_context *ctx) | 104 | void spu_unmap_mappings(struct spu_context *ctx) |
105 | { | 105 | { |
106 | mutex_lock(&ctx->mapping_lock); | ||
106 | if (ctx->local_store) | 107 | if (ctx->local_store) |
107 | unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1); | 108 | unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1); |
108 | if (ctx->mfc) | 109 | if (ctx->mfc) |
@@ -117,6 +118,7 @@ void spu_unmap_mappings(struct spu_context *ctx) | |||
117 | unmap_mapping_range(ctx->mss, 0, 0x1000, 1); | 118 | unmap_mapping_range(ctx->mss, 0, 0x1000, 1); |
118 | if (ctx->psmap) | 119 | if (ctx->psmap) |
119 | unmap_mapping_range(ctx->psmap, 0, 0x20000, 1); | 120 | unmap_mapping_range(ctx->psmap, 0, 0x20000, 1); |
121 | mutex_unlock(&ctx->mapping_lock); | ||
120 | } | 122 | } |
121 | 123 | ||
122 | /** | 124 | /** |
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 45614c73c784..b1e7e2f8a2e9 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c | |||
@@ -45,11 +45,11 @@ spufs_mem_open(struct inode *inode, struct file *file) | |||
45 | struct spufs_inode_info *i = SPUFS_I(inode); | 45 | struct spufs_inode_info *i = SPUFS_I(inode); |
46 | struct spu_context *ctx = i->i_ctx; | 46 | struct spu_context *ctx = i->i_ctx; |
47 | 47 | ||
48 | spin_lock(&ctx->mapping_lock); | 48 | mutex_lock(&ctx->mapping_lock); |
49 | file->private_data = ctx; | 49 | file->private_data = ctx; |
50 | if (!i->i_openers++) | 50 | if (!i->i_openers++) |
51 | ctx->local_store = inode->i_mapping; | 51 | ctx->local_store = inode->i_mapping; |
52 | spin_unlock(&ctx->mapping_lock); | 52 | mutex_unlock(&ctx->mapping_lock); |
53 | return 0; | 53 | return 0; |
54 | } | 54 | } |
55 | 55 | ||
@@ -59,10 +59,10 @@ spufs_mem_release(struct inode *inode, struct file *file) | |||
59 | struct spufs_inode_info *i = SPUFS_I(inode); | 59 | struct spufs_inode_info *i = SPUFS_I(inode); |
60 | struct spu_context *ctx = i->i_ctx; | 60 | struct spu_context *ctx = i->i_ctx; |
61 | 61 | ||
62 | spin_lock(&ctx->mapping_lock); | 62 | mutex_lock(&ctx->mapping_lock); |
63 | if (!--i->i_openers) | 63 | if (!--i->i_openers) |
64 | ctx->local_store = NULL; | 64 | ctx->local_store = NULL; |
65 | spin_unlock(&ctx->mapping_lock); | 65 | mutex_unlock(&ctx->mapping_lock); |
66 | return 0; | 66 | return 0; |
67 | } | 67 | } |
68 | 68 | ||
@@ -217,6 +217,7 @@ unsigned long spufs_get_unmapped_area(struct file *file, unsigned long addr, | |||
217 | 217 | ||
218 | static const struct file_operations spufs_mem_fops = { | 218 | static const struct file_operations spufs_mem_fops = { |
219 | .open = spufs_mem_open, | 219 | .open = spufs_mem_open, |
220 | .release = spufs_mem_release, | ||
220 | .read = spufs_mem_read, | 221 | .read = spufs_mem_read, |
221 | .write = spufs_mem_write, | 222 | .write = spufs_mem_write, |
222 | .llseek = generic_file_llseek, | 223 | .llseek = generic_file_llseek, |
@@ -309,11 +310,11 @@ static int spufs_cntl_open(struct inode *inode, struct file *file) | |||
309 | struct spufs_inode_info *i = SPUFS_I(inode); | 310 | struct spufs_inode_info *i = SPUFS_I(inode); |
310 | struct spu_context *ctx = i->i_ctx; | 311 | struct spu_context *ctx = i->i_ctx; |
311 | 312 | ||
312 | spin_lock(&ctx->mapping_lock); | 313 | mutex_lock(&ctx->mapping_lock); |
313 | file->private_data = ctx; | 314 | file->private_data = ctx; |
314 | if (!i->i_openers++) | 315 | if (!i->i_openers++) |
315 | ctx->cntl = inode->i_mapping; | 316 | ctx->cntl = inode->i_mapping; |
316 | spin_unlock(&ctx->mapping_lock); | 317 | mutex_unlock(&ctx->mapping_lock); |
317 | return simple_attr_open(inode, file, spufs_cntl_get, | 318 | return simple_attr_open(inode, file, spufs_cntl_get, |
318 | spufs_cntl_set, "0x%08lx"); | 319 | spufs_cntl_set, "0x%08lx"); |
319 | } | 320 | } |
@@ -326,10 +327,10 @@ spufs_cntl_release(struct inode *inode, struct file *file) | |||
326 | 327 | ||
327 | simple_attr_close(inode, file); | 328 | simple_attr_close(inode, file); |
328 | 329 | ||
329 | spin_lock(&ctx->mapping_lock); | 330 | mutex_lock(&ctx->mapping_lock); |
330 | if (!--i->i_openers) | 331 | if (!--i->i_openers) |
331 | ctx->cntl = NULL; | 332 | ctx->cntl = NULL; |
332 | spin_unlock(&ctx->mapping_lock); | 333 | mutex_unlock(&ctx->mapping_lock); |
333 | return 0; | 334 | return 0; |
334 | } | 335 | } |
335 | 336 | ||
@@ -812,11 +813,11 @@ static int spufs_signal1_open(struct inode *inode, struct file *file) | |||
812 | struct spufs_inode_info *i = SPUFS_I(inode); | 813 | struct spufs_inode_info *i = SPUFS_I(inode); |
813 | struct spu_context *ctx = i->i_ctx; | 814 | struct spu_context *ctx = i->i_ctx; |
814 | 815 | ||
815 | spin_lock(&ctx->mapping_lock); | 816 | mutex_lock(&ctx->mapping_lock); |
816 | file->private_data = ctx; | 817 | file->private_data = ctx; |
817 | if (!i->i_openers++) | 818 | if (!i->i_openers++) |
818 | ctx->signal1 = inode->i_mapping; | 819 | ctx->signal1 = inode->i_mapping; |
819 | spin_unlock(&ctx->mapping_lock); | 820 | mutex_unlock(&ctx->mapping_lock); |
820 | return nonseekable_open(inode, file); | 821 | return nonseekable_open(inode, file); |
821 | } | 822 | } |
822 | 823 | ||
@@ -826,10 +827,10 @@ spufs_signal1_release(struct inode *inode, struct file *file) | |||
826 | struct spufs_inode_info *i = SPUFS_I(inode); | 827 | struct spufs_inode_info *i = SPUFS_I(inode); |
827 | struct spu_context *ctx = i->i_ctx; | 828 | struct spu_context *ctx = i->i_ctx; |
828 | 829 | ||
829 | spin_lock(&ctx->mapping_lock); | 830 | mutex_lock(&ctx->mapping_lock); |
830 | if (!--i->i_openers) | 831 | if (!--i->i_openers) |
831 | ctx->signal1 = NULL; | 832 | ctx->signal1 = NULL; |
832 | spin_unlock(&ctx->mapping_lock); | 833 | mutex_unlock(&ctx->mapping_lock); |
833 | return 0; | 834 | return 0; |
834 | } | 835 | } |
835 | 836 | ||
@@ -936,11 +937,11 @@ static int spufs_signal2_open(struct inode *inode, struct file *file) | |||
936 | struct spufs_inode_info *i = SPUFS_I(inode); | 937 | struct spufs_inode_info *i = SPUFS_I(inode); |
937 | struct spu_context *ctx = i->i_ctx; | 938 | struct spu_context *ctx = i->i_ctx; |
938 | 939 | ||
939 | spin_lock(&ctx->mapping_lock); | 940 | mutex_lock(&ctx->mapping_lock); |
940 | file->private_data = ctx; | 941 | file->private_data = ctx; |
941 | if (!i->i_openers++) | 942 | if (!i->i_openers++) |
942 | ctx->signal2 = inode->i_mapping; | 943 | ctx->signal2 = inode->i_mapping; |
943 | spin_unlock(&ctx->mapping_lock); | 944 | mutex_unlock(&ctx->mapping_lock); |
944 | return nonseekable_open(inode, file); | 945 | return nonseekable_open(inode, file); |
945 | } | 946 | } |
946 | 947 | ||
@@ -950,10 +951,10 @@ spufs_signal2_release(struct inode *inode, struct file *file) | |||
950 | struct spufs_inode_info *i = SPUFS_I(inode); | 951 | struct spufs_inode_info *i = SPUFS_I(inode); |
951 | struct spu_context *ctx = i->i_ctx; | 952 | struct spu_context *ctx = i->i_ctx; |
952 | 953 | ||
953 | spin_lock(&ctx->mapping_lock); | 954 | mutex_lock(&ctx->mapping_lock); |
954 | if (!--i->i_openers) | 955 | if (!--i->i_openers) |
955 | ctx->signal2 = NULL; | 956 | ctx->signal2 = NULL; |
956 | spin_unlock(&ctx->mapping_lock); | 957 | mutex_unlock(&ctx->mapping_lock); |
957 | return 0; | 958 | return 0; |
958 | } | 959 | } |
959 | 960 | ||
@@ -1154,10 +1155,10 @@ static int spufs_mss_open(struct inode *inode, struct file *file) | |||
1154 | 1155 | ||
1155 | file->private_data = i->i_ctx; | 1156 | file->private_data = i->i_ctx; |
1156 | 1157 | ||
1157 | spin_lock(&ctx->mapping_lock); | 1158 | mutex_lock(&ctx->mapping_lock); |
1158 | if (!i->i_openers++) | 1159 | if (!i->i_openers++) |
1159 | ctx->mss = inode->i_mapping; | 1160 | ctx->mss = inode->i_mapping; |
1160 | spin_unlock(&ctx->mapping_lock); | 1161 | mutex_unlock(&ctx->mapping_lock); |
1161 | return nonseekable_open(inode, file); | 1162 | return nonseekable_open(inode, file); |
1162 | } | 1163 | } |
1163 | 1164 | ||
@@ -1167,10 +1168,10 @@ spufs_mss_release(struct inode *inode, struct file *file) | |||
1167 | struct spufs_inode_info *i = SPUFS_I(inode); | 1168 | struct spufs_inode_info *i = SPUFS_I(inode); |
1168 | struct spu_context *ctx = i->i_ctx; | 1169 | struct spu_context *ctx = i->i_ctx; |
1169 | 1170 | ||
1170 | spin_lock(&ctx->mapping_lock); | 1171 | mutex_lock(&ctx->mapping_lock); |
1171 | if (!--i->i_openers) | 1172 | if (!--i->i_openers) |
1172 | ctx->mss = NULL; | 1173 | ctx->mss = NULL; |
1173 | spin_unlock(&ctx->mapping_lock); | 1174 | mutex_unlock(&ctx->mapping_lock); |
1174 | return 0; | 1175 | return 0; |
1175 | } | 1176 | } |
1176 | 1177 | ||
@@ -1211,11 +1212,11 @@ static int spufs_psmap_open(struct inode *inode, struct file *file) | |||
1211 | struct spufs_inode_info *i = SPUFS_I(inode); | 1212 | struct spufs_inode_info *i = SPUFS_I(inode); |
1212 | struct spu_context *ctx = i->i_ctx; | 1213 | struct spu_context *ctx = i->i_ctx; |
1213 | 1214 | ||
1214 | spin_lock(&ctx->mapping_lock); | 1215 | mutex_lock(&ctx->mapping_lock); |
1215 | file->private_data = i->i_ctx; | 1216 | file->private_data = i->i_ctx; |
1216 | if (!i->i_openers++) | 1217 | if (!i->i_openers++) |
1217 | ctx->psmap = inode->i_mapping; | 1218 | ctx->psmap = inode->i_mapping; |
1218 | spin_unlock(&ctx->mapping_lock); | 1219 | mutex_unlock(&ctx->mapping_lock); |
1219 | return nonseekable_open(inode, file); | 1220 | return nonseekable_open(inode, file); |
1220 | } | 1221 | } |
1221 | 1222 | ||
@@ -1225,10 +1226,10 @@ spufs_psmap_release(struct inode *inode, struct file *file) | |||
1225 | struct spufs_inode_info *i = SPUFS_I(inode); | 1226 | struct spufs_inode_info *i = SPUFS_I(inode); |
1226 | struct spu_context *ctx = i->i_ctx; | 1227 | struct spu_context *ctx = i->i_ctx; |
1227 | 1228 | ||
1228 | spin_lock(&ctx->mapping_lock); | 1229 | mutex_lock(&ctx->mapping_lock); |
1229 | if (!--i->i_openers) | 1230 | if (!--i->i_openers) |
1230 | ctx->psmap = NULL; | 1231 | ctx->psmap = NULL; |
1231 | spin_unlock(&ctx->mapping_lock); | 1232 | mutex_unlock(&ctx->mapping_lock); |
1232 | return 0; | 1233 | return 0; |
1233 | } | 1234 | } |
1234 | 1235 | ||
@@ -1281,11 +1282,11 @@ static int spufs_mfc_open(struct inode *inode, struct file *file) | |||
1281 | if (atomic_read(&inode->i_count) != 1) | 1282 | if (atomic_read(&inode->i_count) != 1) |
1282 | return -EBUSY; | 1283 | return -EBUSY; |
1283 | 1284 | ||
1284 | spin_lock(&ctx->mapping_lock); | 1285 | mutex_lock(&ctx->mapping_lock); |
1285 | file->private_data = ctx; | 1286 | file->private_data = ctx; |
1286 | if (!i->i_openers++) | 1287 | if (!i->i_openers++) |
1287 | ctx->mfc = inode->i_mapping; | 1288 | ctx->mfc = inode->i_mapping; |
1288 | spin_unlock(&ctx->mapping_lock); | 1289 | mutex_unlock(&ctx->mapping_lock); |
1289 | return nonseekable_open(inode, file); | 1290 | return nonseekable_open(inode, file); |
1290 | } | 1291 | } |
1291 | 1292 | ||
@@ -1295,10 +1296,10 @@ spufs_mfc_release(struct inode *inode, struct file *file) | |||
1295 | struct spufs_inode_info *i = SPUFS_I(inode); | 1296 | struct spufs_inode_info *i = SPUFS_I(inode); |
1296 | struct spu_context *ctx = i->i_ctx; | 1297 | struct spu_context *ctx = i->i_ctx; |
1297 | 1298 | ||
1298 | spin_lock(&ctx->mapping_lock); | 1299 | mutex_lock(&ctx->mapping_lock); |
1299 | if (!--i->i_openers) | 1300 | if (!--i->i_openers) |
1300 | ctx->mfc = NULL; | 1301 | ctx->mfc = NULL; |
1301 | spin_unlock(&ctx->mapping_lock); | 1302 | mutex_unlock(&ctx->mapping_lock); |
1302 | return 0; | 1303 | return 0; |
1303 | } | 1304 | } |
1304 | 1305 | ||
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 7150730e2ff1..9807206e0219 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c | |||
@@ -177,7 +177,7 @@ static int spufs_rmdir(struct inode *parent, struct dentry *dir) | |||
177 | static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files, | 177 | static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files, |
178 | int mode, struct spu_context *ctx) | 178 | int mode, struct spu_context *ctx) |
179 | { | 179 | { |
180 | struct dentry *dentry; | 180 | struct dentry *dentry, *tmp; |
181 | int ret; | 181 | int ret; |
182 | 182 | ||
183 | while (files->name && files->name[0]) { | 183 | while (files->name && files->name[0]) { |
@@ -193,7 +193,20 @@ static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files, | |||
193 | } | 193 | } |
194 | return 0; | 194 | return 0; |
195 | out: | 195 | out: |
196 | spufs_prune_dir(dir); | 196 | /* |
197 | * remove all children from dir. dir->inode is not set so don't | ||
198 | * just simply use spufs_prune_dir() and panic afterwards :) | ||
199 | * dput() looks like it will do the right thing: | ||
200 | * - dec parent's ref counter | ||
201 | * - remove child from parent's child list | ||
202 | * - free child's inode if possible | ||
203 | * - free child | ||
204 | */ | ||
205 | list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) { | ||
206 | dput(dentry); | ||
207 | } | ||
208 | |||
209 | shrink_dcache_parent(dir); | ||
197 | return ret; | 210 | return ret; |
198 | } | 211 | } |
199 | 212 | ||
@@ -274,6 +287,7 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags, | |||
274 | goto out; | 287 | goto out; |
275 | 288 | ||
276 | out_free_ctx: | 289 | out_free_ctx: |
290 | spu_forget(ctx); | ||
277 | put_spu_context(ctx); | 291 | put_spu_context(ctx); |
278 | out_iput: | 292 | out_iput: |
279 | iput(inode); | 293 | iput(inode); |
@@ -349,37 +363,6 @@ out: | |||
349 | return ret; | 363 | return ret; |
350 | } | 364 | } |
351 | 365 | ||
352 | static int spufs_rmgang(struct inode *root, struct dentry *dir) | ||
353 | { | ||
354 | /* FIXME: this fails if the dir is not empty, | ||
355 | which causes a leak of gangs. */ | ||
356 | return simple_rmdir(root, dir); | ||
357 | } | ||
358 | |||
359 | static int spufs_gang_close(struct inode *inode, struct file *file) | ||
360 | { | ||
361 | struct inode *parent; | ||
362 | struct dentry *dir; | ||
363 | int ret; | ||
364 | |||
365 | dir = file->f_path.dentry; | ||
366 | parent = dir->d_parent->d_inode; | ||
367 | |||
368 | ret = spufs_rmgang(parent, dir); | ||
369 | WARN_ON(ret); | ||
370 | |||
371 | return dcache_dir_close(inode, file); | ||
372 | } | ||
373 | |||
374 | const struct file_operations spufs_gang_fops = { | ||
375 | .open = dcache_dir_open, | ||
376 | .release = spufs_gang_close, | ||
377 | .llseek = dcache_dir_lseek, | ||
378 | .read = generic_read_dir, | ||
379 | .readdir = dcache_readdir, | ||
380 | .fsync = simple_sync_file, | ||
381 | }; | ||
382 | |||
383 | static int | 366 | static int |
384 | spufs_mkgang(struct inode *dir, struct dentry *dentry, int mode) | 367 | spufs_mkgang(struct inode *dir, struct dentry *dentry, int mode) |
385 | { | 368 | { |
@@ -407,7 +390,6 @@ spufs_mkgang(struct inode *dir, struct dentry *dentry, int mode) | |||
407 | inode->i_fop = &simple_dir_operations; | 390 | inode->i_fop = &simple_dir_operations; |
408 | 391 | ||
409 | d_instantiate(dentry, inode); | 392 | d_instantiate(dentry, inode); |
410 | dget(dentry); | ||
411 | dir->i_nlink++; | 393 | dir->i_nlink++; |
412 | dentry->d_inode->i_nlink++; | 394 | dentry->d_inode->i_nlink++; |
413 | return ret; | 395 | return ret; |
@@ -437,7 +419,7 @@ static int spufs_gang_open(struct dentry *dentry, struct vfsmount *mnt) | |||
437 | goto out; | 419 | goto out; |
438 | } | 420 | } |
439 | 421 | ||
440 | filp->f_op = &spufs_gang_fops; | 422 | filp->f_op = &simple_dir_operations; |
441 | fd_install(ret, filp); | 423 | fd_install(ret, filp); |
442 | out: | 424 | out: |
443 | return ret; | 425 | return ret; |
@@ -458,8 +440,10 @@ static int spufs_create_gang(struct inode *inode, | |||
458 | * in error path of *_open(). | 440 | * in error path of *_open(). |
459 | */ | 441 | */ |
460 | ret = spufs_gang_open(dget(dentry), mntget(mnt)); | 442 | ret = spufs_gang_open(dget(dentry), mntget(mnt)); |
461 | if (ret < 0) | 443 | if (ret < 0) { |
462 | WARN_ON(spufs_rmgang(inode, dentry)); | 444 | int err = simple_rmdir(inode, dentry); |
445 | WARN_ON(err); | ||
446 | } | ||
463 | 447 | ||
464 | out: | 448 | out: |
465 | mutex_unlock(&inode->i_mutex); | 449 | mutex_unlock(&inode->i_mutex); |
@@ -600,6 +584,10 @@ spufs_create_root(struct super_block *sb, void *data) | |||
600 | struct inode *inode; | 584 | struct inode *inode; |
601 | int ret; | 585 | int ret; |
602 | 586 | ||
587 | ret = -ENODEV; | ||
588 | if (!spu_management_ops) | ||
589 | goto out; | ||
590 | |||
603 | ret = -ENOMEM; | 591 | ret = -ENOMEM; |
604 | inode = spufs_new_inode(sb, S_IFDIR | 0775); | 592 | inode = spufs_new_inode(sb, S_IFDIR | 0775); |
605 | if (!inode) | 593 | if (!inode) |
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index b6ecb30e7d58..3b831e07f1ed 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c | |||
@@ -93,43 +93,6 @@ void spu_stop_tick(struct spu_context *ctx) | |||
93 | } | 93 | } |
94 | } | 94 | } |
95 | 95 | ||
96 | void spu_sched_tick(struct work_struct *work) | ||
97 | { | ||
98 | struct spu_context *ctx = | ||
99 | container_of(work, struct spu_context, sched_work.work); | ||
100 | struct spu *spu; | ||
101 | int preempted = 0; | ||
102 | |||
103 | /* | ||
104 | * If this context is being stopped avoid rescheduling from the | ||
105 | * scheduler tick because we would block on the state_mutex. | ||
106 | * The caller will yield the spu later on anyway. | ||
107 | */ | ||
108 | if (test_bit(SPU_SCHED_EXITING, &ctx->sched_flags)) | ||
109 | return; | ||
110 | |||
111 | mutex_lock(&ctx->state_mutex); | ||
112 | spu = ctx->spu; | ||
113 | if (spu) { | ||
114 | int best = sched_find_first_bit(spu_prio->bitmap); | ||
115 | if (best <= ctx->prio) { | ||
116 | spu_deactivate(ctx); | ||
117 | preempted = 1; | ||
118 | } | ||
119 | } | ||
120 | mutex_unlock(&ctx->state_mutex); | ||
121 | |||
122 | if (preempted) { | ||
123 | /* | ||
124 | * We need to break out of the wait loop in spu_run manually | ||
125 | * to ensure this context gets put on the runqueue again | ||
126 | * ASAP. | ||
127 | */ | ||
128 | wake_up(&ctx->stop_wq); | ||
129 | } else | ||
130 | spu_start_tick(ctx); | ||
131 | } | ||
132 | |||
133 | /** | 96 | /** |
134 | * spu_add_to_active_list - add spu to active list | 97 | * spu_add_to_active_list - add spu to active list |
135 | * @spu: spu to add to the active list | 98 | * @spu: spu to add to the active list |
@@ -273,34 +236,6 @@ static void spu_prio_wait(struct spu_context *ctx) | |||
273 | remove_wait_queue(&ctx->stop_wq, &wait); | 236 | remove_wait_queue(&ctx->stop_wq, &wait); |
274 | } | 237 | } |
275 | 238 | ||
276 | /** | ||
277 | * spu_reschedule - try to find a runnable context for a spu | ||
278 | * @spu: spu available | ||
279 | * | ||
280 | * This function is called whenever a spu becomes idle. It looks for the | ||
281 | * most suitable runnable spu context and schedules it for execution. | ||
282 | */ | ||
283 | static void spu_reschedule(struct spu *spu) | ||
284 | { | ||
285 | int best; | ||
286 | |||
287 | spu_free(spu); | ||
288 | |||
289 | spin_lock(&spu_prio->runq_lock); | ||
290 | best = sched_find_first_bit(spu_prio->bitmap); | ||
291 | if (best < MAX_PRIO) { | ||
292 | struct list_head *rq = &spu_prio->runq[best]; | ||
293 | struct spu_context *ctx; | ||
294 | |||
295 | BUG_ON(list_empty(rq)); | ||
296 | |||
297 | ctx = list_entry(rq->next, struct spu_context, rq); | ||
298 | __spu_del_from_rq(ctx); | ||
299 | wake_up(&ctx->stop_wq); | ||
300 | } | ||
301 | spin_unlock(&spu_prio->runq_lock); | ||
302 | } | ||
303 | |||
304 | static struct spu *spu_get_idle(struct spu_context *ctx) | 239 | static struct spu *spu_get_idle(struct spu_context *ctx) |
305 | { | 240 | { |
306 | struct spu *spu = NULL; | 241 | struct spu *spu = NULL; |
@@ -429,6 +364,51 @@ int spu_activate(struct spu_context *ctx, unsigned long flags) | |||
429 | } | 364 | } |
430 | 365 | ||
431 | /** | 366 | /** |
367 | * grab_runnable_context - try to find a runnable context | ||
368 | * | ||
369 | * Remove the highest priority context on the runqueue and return it | ||
370 | * to the caller. Returns %NULL if no runnable context was found. | ||
371 | */ | ||
372 | static struct spu_context *grab_runnable_context(int prio) | ||
373 | { | ||
374 | struct spu_context *ctx = NULL; | ||
375 | int best; | ||
376 | |||
377 | spin_lock(&spu_prio->runq_lock); | ||
378 | best = sched_find_first_bit(spu_prio->bitmap); | ||
379 | if (best < prio) { | ||
380 | struct list_head *rq = &spu_prio->runq[best]; | ||
381 | |||
382 | BUG_ON(list_empty(rq)); | ||
383 | |||
384 | ctx = list_entry(rq->next, struct spu_context, rq); | ||
385 | __spu_del_from_rq(ctx); | ||
386 | } | ||
387 | spin_unlock(&spu_prio->runq_lock); | ||
388 | |||
389 | return ctx; | ||
390 | } | ||
391 | |||
392 | static int __spu_deactivate(struct spu_context *ctx, int force, int max_prio) | ||
393 | { | ||
394 | struct spu *spu = ctx->spu; | ||
395 | struct spu_context *new = NULL; | ||
396 | |||
397 | if (spu) { | ||
398 | new = grab_runnable_context(max_prio); | ||
399 | if (new || force) { | ||
400 | spu_unbind_context(spu, ctx); | ||
401 | spu_free(spu); | ||
402 | if (new) | ||
403 | wake_up(&new->stop_wq); | ||
404 | } | ||
405 | |||
406 | } | ||
407 | |||
408 | return new != NULL; | ||
409 | } | ||
410 | |||
411 | /** | ||
432 | * spu_deactivate - unbind a context from it's physical spu | 412 | * spu_deactivate - unbind a context from it's physical spu |
433 | * @ctx: spu context to unbind | 413 | * @ctx: spu context to unbind |
434 | * | 414 | * |
@@ -437,12 +417,7 @@ int spu_activate(struct spu_context *ctx, unsigned long flags) | |||
437 | */ | 417 | */ |
438 | void spu_deactivate(struct spu_context *ctx) | 418 | void spu_deactivate(struct spu_context *ctx) |
439 | { | 419 | { |
440 | struct spu *spu = ctx->spu; | 420 | __spu_deactivate(ctx, 1, MAX_PRIO); |
441 | |||
442 | if (spu) { | ||
443 | spu_unbind_context(spu, ctx); | ||
444 | spu_reschedule(spu); | ||
445 | } | ||
446 | } | 421 | } |
447 | 422 | ||
448 | /** | 423 | /** |
@@ -455,21 +430,43 @@ void spu_deactivate(struct spu_context *ctx) | |||
455 | */ | 430 | */ |
456 | void spu_yield(struct spu_context *ctx) | 431 | void spu_yield(struct spu_context *ctx) |
457 | { | 432 | { |
458 | struct spu *spu; | 433 | if (!(ctx->flags & SPU_CREATE_NOSCHED)) { |
459 | 434 | mutex_lock(&ctx->state_mutex); | |
460 | if (mutex_trylock(&ctx->state_mutex)) { | 435 | __spu_deactivate(ctx, 0, MAX_PRIO); |
461 | if ((spu = ctx->spu) != NULL) { | ||
462 | int best = sched_find_first_bit(spu_prio->bitmap); | ||
463 | if (best < MAX_PRIO) { | ||
464 | pr_debug("%s: yielding SPU %d NODE %d\n", | ||
465 | __FUNCTION__, spu->number, spu->node); | ||
466 | spu_deactivate(ctx); | ||
467 | } | ||
468 | } | ||
469 | mutex_unlock(&ctx->state_mutex); | 436 | mutex_unlock(&ctx->state_mutex); |
470 | } | 437 | } |
471 | } | 438 | } |
472 | 439 | ||
440 | void spu_sched_tick(struct work_struct *work) | ||
441 | { | ||
442 | struct spu_context *ctx = | ||
443 | container_of(work, struct spu_context, sched_work.work); | ||
444 | int preempted; | ||
445 | |||
446 | /* | ||
447 | * If this context is being stopped avoid rescheduling from the | ||
448 | * scheduler tick because we would block on the state_mutex. | ||
449 | * The caller will yield the spu later on anyway. | ||
450 | */ | ||
451 | if (test_bit(SPU_SCHED_EXITING, &ctx->sched_flags)) | ||
452 | return; | ||
453 | |||
454 | mutex_lock(&ctx->state_mutex); | ||
455 | preempted = __spu_deactivate(ctx, 0, ctx->prio + 1); | ||
456 | mutex_unlock(&ctx->state_mutex); | ||
457 | |||
458 | if (preempted) { | ||
459 | /* | ||
460 | * We need to break out of the wait loop in spu_run manually | ||
461 | * to ensure this context gets put on the runqueue again | ||
462 | * ASAP. | ||
463 | */ | ||
464 | wake_up(&ctx->stop_wq); | ||
465 | } else { | ||
466 | spu_start_tick(ctx); | ||
467 | } | ||
468 | } | ||
469 | |||
473 | int __init spu_sched_init(void) | 470 | int __init spu_sched_init(void) |
474 | { | 471 | { |
475 | int i; | 472 | int i; |
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index 0a947fd7de57..47617e8014a5 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h | |||
@@ -55,7 +55,7 @@ struct spu_context { | |||
55 | struct address_space *signal2; /* 'signal2' area mappings. */ | 55 | struct address_space *signal2; /* 'signal2' area mappings. */ |
56 | struct address_space *mss; /* 'mss' area mappings. */ | 56 | struct address_space *mss; /* 'mss' area mappings. */ |
57 | struct address_space *psmap; /* 'psmap' area mappings. */ | 57 | struct address_space *psmap; /* 'psmap' area mappings. */ |
58 | spinlock_t mapping_lock; | 58 | struct mutex mapping_lock; |
59 | u64 object_id; /* user space pointer for oprofile */ | 59 | u64 object_id; /* user space pointer for oprofile */ |
60 | 60 | ||
61 | enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state; | 61 | enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state; |
diff --git a/arch/powerpc/platforms/celleb/Makefile b/arch/powerpc/platforms/celleb/Makefile index f4f82520dc4f..5240046d8671 100644 --- a/arch/powerpc/platforms/celleb/Makefile +++ b/arch/powerpc/platforms/celleb/Makefile | |||
@@ -4,5 +4,5 @@ obj-y += interrupt.o iommu.o setup.o \ | |||
4 | 4 | ||
5 | obj-$(CONFIG_SMP) += smp.o | 5 | obj-$(CONFIG_SMP) += smp.o |
6 | obj-$(CONFIG_PPC_UDBG_BEAT) += udbg_beat.o | 6 | obj-$(CONFIG_PPC_UDBG_BEAT) += udbg_beat.o |
7 | obj-$(CONFIG_HAS_TXX9_SERIAL) += scc_sio.o | 7 | obj-$(CONFIG_SERIAL_TXX9) += scc_sio.o |
8 | obj-$(CONFIG_SPU_BASE) += spu_priv1.o | 8 | obj-$(CONFIG_SPU_BASE) += spu_priv1.o |
diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c index 71045677559a..5bcc58d9a4dd 100644 --- a/arch/powerpc/platforms/chrp/pegasos_eth.c +++ b/arch/powerpc/platforms/chrp/pegasos_eth.c | |||
@@ -169,7 +169,7 @@ static int Enable_SRAM(void) | |||
169 | 169 | ||
170 | /***********/ | 170 | /***********/ |
171 | /***********/ | 171 | /***********/ |
172 | int mv643xx_eth_add_pds(void) | 172 | static int __init mv643xx_eth_add_pds(void) |
173 | { | 173 | { |
174 | int ret = 0; | 174 | int ret = 0; |
175 | static struct pci_device_id pci_marvell_mv64360[] = { | 175 | static struct pci_device_id pci_marvell_mv64360[] = { |
diff --git a/arch/powerpc/platforms/pasemi/idle.c b/arch/powerpc/platforms/pasemi/idle.c index 03cd45d8fefa..3c962d5757be 100644 --- a/arch/powerpc/platforms/pasemi/idle.c +++ b/arch/powerpc/platforms/pasemi/idle.c | |||
@@ -26,6 +26,7 @@ | |||
26 | 26 | ||
27 | #include <asm/machdep.h> | 27 | #include <asm/machdep.h> |
28 | #include <asm/reg.h> | 28 | #include <asm/reg.h> |
29 | #include <asm/smp.h> | ||
29 | 30 | ||
30 | #include "pasemi.h" | 31 | #include "pasemi.h" |
31 | 32 | ||
diff --git a/arch/powerpc/platforms/pasemi/iommu.c b/arch/powerpc/platforms/pasemi/iommu.c index 95fa6a7d15ee..f33b21b9f5d4 100644 --- a/arch/powerpc/platforms/pasemi/iommu.c +++ b/arch/powerpc/platforms/pasemi/iommu.c | |||
@@ -31,8 +31,6 @@ | |||
31 | #define IOBMAP_PAGE_SIZE (1 << IOBMAP_PAGE_SHIFT) | 31 | #define IOBMAP_PAGE_SIZE (1 << IOBMAP_PAGE_SHIFT) |
32 | #define IOBMAP_PAGE_MASK (IOBMAP_PAGE_SIZE - 1) | 32 | #define IOBMAP_PAGE_MASK (IOBMAP_PAGE_SIZE - 1) |
33 | 33 | ||
34 | #define IOBMAP_PAGE_FACTOR (PAGE_SHIFT - IOBMAP_PAGE_SHIFT) | ||
35 | |||
36 | #define IOB_BASE 0xe0000000 | 34 | #define IOB_BASE 0xe0000000 |
37 | #define IOB_SIZE 0x3000 | 35 | #define IOB_SIZE 0x3000 |
38 | /* Configuration registers */ | 36 | /* Configuration registers */ |
@@ -97,9 +95,6 @@ static void iobmap_build(struct iommu_table *tbl, long index, | |||
97 | 95 | ||
98 | bus_addr = (tbl->it_offset + index) << PAGE_SHIFT; | 96 | bus_addr = (tbl->it_offset + index) << PAGE_SHIFT; |
99 | 97 | ||
100 | npages <<= IOBMAP_PAGE_FACTOR; | ||
101 | index <<= IOBMAP_PAGE_FACTOR; | ||
102 | |||
103 | ip = ((u32 *)tbl->it_base) + index; | 98 | ip = ((u32 *)tbl->it_base) + index; |
104 | 99 | ||
105 | while (npages--) { | 100 | while (npages--) { |
@@ -125,9 +120,6 @@ static void iobmap_free(struct iommu_table *tbl, long index, | |||
125 | 120 | ||
126 | bus_addr = (tbl->it_offset + index) << PAGE_SHIFT; | 121 | bus_addr = (tbl->it_offset + index) << PAGE_SHIFT; |
127 | 122 | ||
128 | npages <<= IOBMAP_PAGE_FACTOR; | ||
129 | index <<= IOBMAP_PAGE_FACTOR; | ||
130 | |||
131 | ip = ((u32 *)tbl->it_base) + index; | 123 | ip = ((u32 *)tbl->it_base) + index; |
132 | 124 | ||
133 | while (npages--) { | 125 | while (npages--) { |
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index a410bc76a8a8..07b1c4ec428d 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c | |||
@@ -384,7 +384,7 @@ int boot_part; | |||
384 | static dev_t boot_dev; | 384 | static dev_t boot_dev; |
385 | 385 | ||
386 | #ifdef CONFIG_SCSI | 386 | #ifdef CONFIG_SCSI |
387 | void __init note_scsi_host(struct device_node *node, void *host) | 387 | void note_scsi_host(struct device_node *node, void *host) |
388 | { | 388 | { |
389 | int l; | 389 | int l; |
390 | char *p; | 390 | char *p; |
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c index 9da82c266ba9..ec9030dbb5f1 100644 --- a/arch/powerpc/platforms/ps3/interrupt.c +++ b/arch/powerpc/platforms/ps3/interrupt.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <asm/machdep.h> | 25 | #include <asm/machdep.h> |
26 | #include <asm/udbg.h> | 26 | #include <asm/udbg.h> |
27 | #include <asm/lv1call.h> | 27 | #include <asm/lv1call.h> |
28 | #include <asm/smp.h> | ||
28 | 29 | ||
29 | #include "platform.h" | 30 | #include "platform.h" |
30 | 31 | ||
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index b854e7f1001c..f1df942072bb 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c | |||
@@ -752,6 +752,7 @@ skip_gserver_check: | |||
752 | void xics_request_IPIs(void) | 752 | void xics_request_IPIs(void) |
753 | { | 753 | { |
754 | unsigned int ipi; | 754 | unsigned int ipi; |
755 | int rc; | ||
755 | 756 | ||
756 | ipi = irq_create_mapping(xics_host, XICS_IPI); | 757 | ipi = irq_create_mapping(xics_host, XICS_IPI); |
757 | BUG_ON(ipi == NO_IRQ); | 758 | BUG_ON(ipi == NO_IRQ); |
@@ -762,11 +763,12 @@ void xics_request_IPIs(void) | |||
762 | */ | 763 | */ |
763 | set_irq_handler(ipi, handle_percpu_irq); | 764 | set_irq_handler(ipi, handle_percpu_irq); |
764 | if (firmware_has_feature(FW_FEATURE_LPAR)) | 765 | if (firmware_has_feature(FW_FEATURE_LPAR)) |
765 | request_irq(ipi, xics_ipi_action_lpar, IRQF_DISABLED, | 766 | rc = request_irq(ipi, xics_ipi_action_lpar, IRQF_DISABLED, |
766 | "IPI", NULL); | 767 | "IPI", NULL); |
767 | else | 768 | else |
768 | request_irq(ipi, xics_ipi_action_direct, IRQF_DISABLED, | 769 | rc = request_irq(ipi, xics_ipi_action_direct, IRQF_DISABLED, |
769 | "IPI", NULL); | 770 | "IPI", NULL); |
771 | BUG_ON(rc); | ||
770 | } | 772 | } |
771 | #endif /* CONFIG_SMP */ | 773 | #endif /* CONFIG_SMP */ |
772 | 774 | ||
diff --git a/arch/powerpc/sysdev/qe_lib/Kconfig b/arch/powerpc/sysdev/qe_lib/Kconfig index 887739f3badc..f611d344a126 100644 --- a/arch/powerpc/sysdev/qe_lib/Kconfig +++ b/arch/powerpc/sysdev/qe_lib/Kconfig | |||
@@ -5,15 +5,13 @@ | |||
5 | config UCC_SLOW | 5 | config UCC_SLOW |
6 | bool | 6 | bool |
7 | default n | 7 | default n |
8 | select UCC | ||
9 | help | 8 | help |
10 | This option provides qe_lib support to UCC slow | 9 | This option provides qe_lib support to UCC slow |
11 | protocols: UART, BISYNC, QMC | 10 | protocols: UART, BISYNC, QMC |
12 | 11 | ||
13 | config UCC_FAST | 12 | config UCC_FAST |
14 | bool | 13 | bool |
15 | default n | 14 | default y if UCC_GETH |
16 | select UCC | ||
17 | help | 15 | help |
18 | This option provides qe_lib support to UCC fast | 16 | This option provides qe_lib support to UCC fast |
19 | protocols: HDLC, Ethernet, ATM, transparent | 17 | protocols: HDLC, Ethernet, ATM, transparent |
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index ab64256110bd..fba7ca17a67e 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S | |||
@@ -596,7 +596,11 @@ fast_exception_return: | |||
596 | mr r12,r4 /* restart at exc_exit_restart */ | 596 | mr r12,r4 /* restart at exc_exit_restart */ |
597 | b 2b | 597 | b 2b |
598 | 598 | ||
599 | .comm fee_restarts,4 | 599 | .section .bss |
600 | .align 2 | ||
601 | fee_restarts: | ||
602 | .space 4 | ||
603 | .previous | ||
600 | 604 | ||
601 | /* aargh, a nonrecoverable interrupt, panic */ | 605 | /* aargh, a nonrecoverable interrupt, panic */ |
602 | /* aargh, we don't know which trap this is */ | 606 | /* aargh, we don't know which trap this is */ |
@@ -851,7 +855,11 @@ load_dbcr0: | |||
851 | mtspr SPRN_DBSR,r11 /* clear all pending debug events */ | 855 | mtspr SPRN_DBSR,r11 /* clear all pending debug events */ |
852 | blr | 856 | blr |
853 | 857 | ||
854 | .comm global_dbcr0,8 | 858 | .section .bss |
859 | .align 4 | ||
860 | global_dbcr0: | ||
861 | .space 8 | ||
862 | .previous | ||
855 | #endif /* !(CONFIG_4xx || CONFIG_BOOKE) */ | 863 | #endif /* !(CONFIG_4xx || CONFIG_BOOKE) */ |
856 | 864 | ||
857 | do_work: /* r10 contains MSR_KERNEL here */ | 865 | do_work: /* r10 contains MSR_KERNEL here */ |
@@ -926,4 +934,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_601) | |||
926 | /* shouldn't return */ | 934 | /* shouldn't return */ |
927 | b 4b | 935 | b 4b |
928 | 936 | ||
929 | .comm ee_restarts,4 | 937 | .section .bss |
938 | .align 2 | ||
939 | ee_restarts: | ||
940 | .space 4 | ||
941 | .previous | ||
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 4ad499605d05..a4165209ac7c 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <asm/time.h> | 40 | #include <asm/time.h> |
41 | #include <asm/cputable.h> | 41 | #include <asm/cputable.h> |
42 | #include <asm/btext.h> | 42 | #include <asm/btext.h> |
43 | #include <asm/div64.h> | ||
44 | #include <asm/xmon.h> | 43 | #include <asm/xmon.h> |
45 | #include <asm/signal.h> | 44 | #include <asm/signal.h> |
46 | #include <asm/dcr.h> | 45 | #include <asm/dcr.h> |
@@ -93,7 +92,6 @@ EXPORT_SYMBOL(strncpy); | |||
93 | EXPORT_SYMBOL(strcat); | 92 | EXPORT_SYMBOL(strcat); |
94 | EXPORT_SYMBOL(strlen); | 93 | EXPORT_SYMBOL(strlen); |
95 | EXPORT_SYMBOL(strcmp); | 94 | EXPORT_SYMBOL(strcmp); |
96 | EXPORT_SYMBOL(__div64_32); | ||
97 | 95 | ||
98 | EXPORT_SYMBOL(csum_partial); | 96 | EXPORT_SYMBOL(csum_partial); |
99 | EXPORT_SYMBOL(csum_partial_copy_generic); | 97 | EXPORT_SYMBOL(csum_partial_copy_generic); |
diff --git a/arch/ppc/mm/hashtable.S b/arch/ppc/mm/hashtable.S index e756942e65c4..5f364dc50154 100644 --- a/arch/ppc/mm/hashtable.S +++ b/arch/ppc/mm/hashtable.S | |||
@@ -30,7 +30,11 @@ | |||
30 | #include <asm/asm-offsets.h> | 30 | #include <asm/asm-offsets.h> |
31 | 31 | ||
32 | #ifdef CONFIG_SMP | 32 | #ifdef CONFIG_SMP |
33 | .comm mmu_hash_lock,4 | 33 | .section .bss |
34 | .align 2 | ||
35 | .globl mmu_hash_lock | ||
36 | mmu_hash_lock: | ||
37 | .space 4 | ||
34 | #endif /* CONFIG_SMP */ | 38 | #endif /* CONFIG_SMP */ |
35 | 39 | ||
36 | /* | 40 | /* |
@@ -461,9 +465,17 @@ found_slot: | |||
461 | sync /* make sure pte updates get to memory */ | 465 | sync /* make sure pte updates get to memory */ |
462 | blr | 466 | blr |
463 | 467 | ||
464 | .comm next_slot,4 | 468 | .section .bss |
465 | .comm primary_pteg_full,4 | 469 | .align 2 |
466 | .comm htab_hash_searches,4 | 470 | next_slot: |
471 | .space 4 | ||
472 | .globl primary_pteg_full | ||
473 | primary_pteg_full: | ||
474 | .space 4 | ||
475 | .globl htab_hash_searches | ||
476 | htab_hash_searches: | ||
477 | .space 4 | ||
478 | .previous | ||
467 | 479 | ||
468 | /* | 480 | /* |
469 | * Flush the entry for a particular page from the hash table. | 481 | * Flush the entry for a particular page from the hash table. |
diff --git a/arch/ppc/mm/pgtable.c b/arch/ppc/mm/pgtable.c index c023b7298809..35ebb6395ae3 100644 --- a/arch/ppc/mm/pgtable.c +++ b/arch/ppc/mm/pgtable.c | |||
@@ -92,7 +92,7 @@ void pgd_free(pgd_t *pgd) | |||
92 | free_pages((unsigned long)pgd, PGDIR_ORDER); | 92 | free_pages((unsigned long)pgd, PGDIR_ORDER); |
93 | } | 93 | } |
94 | 94 | ||
95 | pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | 95 | __init_refok pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) |
96 | { | 96 | { |
97 | pte_t *pte; | 97 | pte_t *pte; |
98 | extern int mem_init_done; | 98 | extern int mem_init_done; |
diff --git a/arch/ppc/syslib/ibm_ocp.c b/arch/ppc/syslib/ibm_ocp.c index 3f6e55c79181..2ee176610e7c 100644 --- a/arch/ppc/syslib/ibm_ocp.c +++ b/arch/ppc/syslib/ibm_ocp.c | |||
@@ -1,4 +1,5 @@ | |||
1 | #include <linux/module.h> | 1 | #include <linux/module.h> |
2 | #include <asm/ibm4xx.h> | ||
2 | #include <asm/ocp.h> | 3 | #include <asm/ocp.h> |
3 | 4 | ||
4 | struct ocp_sys_info_data ocp_sys_info = { | 5 | struct ocp_sys_info_data ocp_sys_info = { |
diff --git a/arch/ppc/syslib/qspan_pci.c b/arch/ppc/syslib/qspan_pci.c index 85053b2816a9..7a97c7440b30 100644 --- a/arch/ppc/syslib/qspan_pci.c +++ b/arch/ppc/syslib/qspan_pci.c | |||
@@ -365,13 +365,13 @@ int qspan_pcibios_find_class(unsigned int class_code, unsigned short index, | |||
365 | } | 365 | } |
366 | 366 | ||
367 | void __init | 367 | void __init |
368 | m8xx_pcibios_fixup(void)) | 368 | m8xx_pcibios_fixup(void) |
369 | { | 369 | { |
370 | /* Lots to do here, all board and configuration specific. */ | 370 | /* Lots to do here, all board and configuration specific. */ |
371 | } | 371 | } |
372 | 372 | ||
373 | void __init | 373 | void __init |
374 | m8xx_setup_pci_ptrs(void)) | 374 | m8xx_setup_pci_ptrs(void) |
375 | { | 375 | { |
376 | set_config_access_method(qspan); | 376 | set_config_access_method(qspan); |
377 | 377 | ||
diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c index 2782cf9da5b4..b9a1ce1f28e4 100644 --- a/arch/s390/hypfs/hypfs_diag.c +++ b/arch/s390/hypfs/hypfs_diag.c | |||
@@ -481,9 +481,17 @@ out: | |||
481 | 481 | ||
482 | /* Diagnose 224 functions */ | 482 | /* Diagnose 224 functions */ |
483 | 483 | ||
484 | static void diag224(void *ptr) | 484 | static int diag224(void *ptr) |
485 | { | 485 | { |
486 | asm volatile("diag %0,%1,0x224" : :"d" (0), "d"(ptr) : "memory"); | 486 | int rc = -ENOTSUPP; |
487 | |||
488 | asm volatile( | ||
489 | " diag %1,%2,0x224\n" | ||
490 | "0: lhi %0,0x0\n" | ||
491 | "1:\n" | ||
492 | EX_TABLE(0b,1b) | ||
493 | : "+d" (rc) :"d" (0), "d" (ptr) : "memory"); | ||
494 | return rc; | ||
487 | } | 495 | } |
488 | 496 | ||
489 | static int diag224_get_name_table(void) | 497 | static int diag224_get_name_table(void) |
@@ -492,7 +500,10 @@ static int diag224_get_name_table(void) | |||
492 | diag224_cpu_names = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA); | 500 | diag224_cpu_names = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA); |
493 | if (!diag224_cpu_names) | 501 | if (!diag224_cpu_names) |
494 | return -ENOMEM; | 502 | return -ENOMEM; |
495 | diag224(diag224_cpu_names); | 503 | if (diag224(diag224_cpu_names)) { |
504 | kfree(diag224_cpu_names); | ||
505 | return -ENOTSUPP; | ||
506 | } | ||
496 | EBCASC(diag224_cpu_names + 16, (*diag224_cpu_names + 1) * 16); | 507 | EBCASC(diag224_cpu_names + 16, (*diag224_cpu_names + 1) * 16); |
497 | return 0; | 508 | return 0; |
498 | } | 509 | } |
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index dca6eaf82c80..1b2f5ce45320 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c | |||
@@ -163,7 +163,7 @@ unsigned int debug_feature_version = __DEBUG_FEATURE_VERSION; | |||
163 | 163 | ||
164 | static debug_info_t *debug_area_first = NULL; | 164 | static debug_info_t *debug_area_first = NULL; |
165 | static debug_info_t *debug_area_last = NULL; | 165 | static debug_info_t *debug_area_last = NULL; |
166 | static DECLARE_MUTEX(debug_lock); | 166 | static DEFINE_MUTEX(debug_mutex); |
167 | 167 | ||
168 | static int initialized; | 168 | static int initialized; |
169 | 169 | ||
@@ -576,7 +576,7 @@ debug_input(struct file *file, const char __user *user_buf, size_t length, | |||
576 | int rc = 0; | 576 | int rc = 0; |
577 | file_private_info_t *p_info; | 577 | file_private_info_t *p_info; |
578 | 578 | ||
579 | down(&debug_lock); | 579 | mutex_lock(&debug_mutex); |
580 | p_info = ((file_private_info_t *) file->private_data); | 580 | p_info = ((file_private_info_t *) file->private_data); |
581 | if (p_info->view->input_proc) | 581 | if (p_info->view->input_proc) |
582 | rc = p_info->view->input_proc(p_info->debug_info_org, | 582 | rc = p_info->view->input_proc(p_info->debug_info_org, |
@@ -584,7 +584,7 @@ debug_input(struct file *file, const char __user *user_buf, size_t length, | |||
584 | length, offset); | 584 | length, offset); |
585 | else | 585 | else |
586 | rc = -EPERM; | 586 | rc = -EPERM; |
587 | up(&debug_lock); | 587 | mutex_unlock(&debug_mutex); |
588 | return rc; /* number of input characters */ | 588 | return rc; /* number of input characters */ |
589 | } | 589 | } |
590 | 590 | ||
@@ -602,7 +602,7 @@ debug_open(struct inode *inode, struct file *file) | |||
602 | file_private_info_t *p_info; | 602 | file_private_info_t *p_info; |
603 | debug_info_t *debug_info, *debug_info_snapshot; | 603 | debug_info_t *debug_info, *debug_info_snapshot; |
604 | 604 | ||
605 | down(&debug_lock); | 605 | mutex_lock(&debug_mutex); |
606 | debug_info = file->f_path.dentry->d_inode->i_private; | 606 | debug_info = file->f_path.dentry->d_inode->i_private; |
607 | /* find debug view */ | 607 | /* find debug view */ |
608 | for (i = 0; i < DEBUG_MAX_VIEWS; i++) { | 608 | for (i = 0; i < DEBUG_MAX_VIEWS; i++) { |
@@ -653,7 +653,7 @@ found: | |||
653 | file->private_data = p_info; | 653 | file->private_data = p_info; |
654 | debug_info_get(debug_info); | 654 | debug_info_get(debug_info); |
655 | out: | 655 | out: |
656 | up(&debug_lock); | 656 | mutex_unlock(&debug_mutex); |
657 | return rc; | 657 | return rc; |
658 | } | 658 | } |
659 | 659 | ||
@@ -688,7 +688,7 @@ debug_register (char *name, int pages_per_area, int nr_areas, int buf_size) | |||
688 | 688 | ||
689 | if (!initialized) | 689 | if (!initialized) |
690 | BUG(); | 690 | BUG(); |
691 | down(&debug_lock); | 691 | mutex_lock(&debug_mutex); |
692 | 692 | ||
693 | /* create new debug_info */ | 693 | /* create new debug_info */ |
694 | 694 | ||
@@ -702,7 +702,7 @@ out: | |||
702 | if (!rc){ | 702 | if (!rc){ |
703 | printk(KERN_ERR "debug: debug_register failed for %s\n",name); | 703 | printk(KERN_ERR "debug: debug_register failed for %s\n",name); |
704 | } | 704 | } |
705 | up(&debug_lock); | 705 | mutex_unlock(&debug_mutex); |
706 | return rc; | 706 | return rc; |
707 | } | 707 | } |
708 | 708 | ||
@@ -716,9 +716,9 @@ debug_unregister(debug_info_t * id) | |||
716 | { | 716 | { |
717 | if (!id) | 717 | if (!id) |
718 | goto out; | 718 | goto out; |
719 | down(&debug_lock); | 719 | mutex_lock(&debug_mutex); |
720 | debug_info_put(id); | 720 | debug_info_put(id); |
721 | up(&debug_lock); | 721 | mutex_unlock(&debug_mutex); |
722 | 722 | ||
723 | out: | 723 | out: |
724 | return; | 724 | return; |
@@ -1054,11 +1054,11 @@ __init debug_init(void) | |||
1054 | int rc = 0; | 1054 | int rc = 0; |
1055 | 1055 | ||
1056 | s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table); | 1056 | s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table); |
1057 | down(&debug_lock); | 1057 | mutex_lock(&debug_mutex); |
1058 | debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT,NULL); | 1058 | debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT,NULL); |
1059 | printk(KERN_INFO "debug: Initialization complete\n"); | 1059 | printk(KERN_INFO "debug: Initialization complete\n"); |
1060 | initialized = 1; | 1060 | initialized = 1; |
1061 | up(&debug_lock); | 1061 | mutex_unlock(&debug_mutex); |
1062 | 1062 | ||
1063 | return rc; | 1063 | return rc; |
1064 | } | 1064 | } |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 6bfb0889eb10..51d6309e7f3b 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -102,7 +102,7 @@ static struct resource data_resource = { | |||
102 | /* | 102 | /* |
103 | * cpu_init() initializes state that is per-CPU. | 103 | * cpu_init() initializes state that is per-CPU. |
104 | */ | 104 | */ |
105 | void __devinit cpu_init (void) | 105 | void __cpuinit cpu_init(void) |
106 | { | 106 | { |
107 | int addr = hard_smp_processor_id(); | 107 | int addr = hard_smp_processor_id(); |
108 | 108 | ||
@@ -915,7 +915,7 @@ setup_arch(char **cmdline_p) | |||
915 | setup_zfcpdump(console_devno); | 915 | setup_zfcpdump(console_devno); |
916 | } | 916 | } |
917 | 917 | ||
918 | void print_cpu_info(struct cpuinfo_S390 *cpuinfo) | 918 | void __cpuinit print_cpu_info(struct cpuinfo_S390 *cpuinfo) |
919 | { | 919 | { |
920 | printk("cpu %d " | 920 | printk("cpu %d " |
921 | #ifdef CONFIG_SMP | 921 | #ifdef CONFIG_SMP |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 09f028a3266b..8ff2feaf9b00 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -492,7 +492,7 @@ static unsigned int __init smp_count_cpus(void) | |||
492 | /* | 492 | /* |
493 | * Activate a secondary processor. | 493 | * Activate a secondary processor. |
494 | */ | 494 | */ |
495 | int __devinit start_secondary(void *cpuvoid) | 495 | int __cpuinit start_secondary(void *cpuvoid) |
496 | { | 496 | { |
497 | /* Setup the cpu */ | 497 | /* Setup the cpu */ |
498 | cpu_init(); | 498 | cpu_init(); |
@@ -741,7 +741,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
741 | smp_create_idle(cpu); | 741 | smp_create_idle(cpu); |
742 | } | 742 | } |
743 | 743 | ||
744 | void __devinit smp_prepare_boot_cpu(void) | 744 | void __init smp_prepare_boot_cpu(void) |
745 | { | 745 | { |
746 | BUG_ON(smp_processor_id() != 0); | 746 | BUG_ON(smp_processor_id() != 0); |
747 | 747 | ||
@@ -750,7 +750,7 @@ void __devinit smp_prepare_boot_cpu(void) | |||
750 | current_set[0] = current; | 750 | current_set[0] = current; |
751 | } | 751 | } |
752 | 752 | ||
753 | void smp_cpus_done(unsigned int max_cpus) | 753 | void __init smp_cpus_done(unsigned int max_cpus) |
754 | { | 754 | { |
755 | cpu_present_map = cpu_possible_map; | 755 | cpu_present_map = cpu_possible_map; |
756 | } | 756 | } |
diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 7b1122417050..883b03b040c4 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile | |||
@@ -39,7 +39,7 @@ cflags-$(CONFIG_CPU_SH2A) := -m2a $(call cc-option,-m2a-nofpu,) | |||
39 | cflags-$(CONFIG_CPU_SH3) := -m3 | 39 | cflags-$(CONFIG_CPU_SH3) := -m3 |
40 | cflags-$(CONFIG_CPU_SH4) := -m4 \ | 40 | cflags-$(CONFIG_CPU_SH4) := -m4 \ |
41 | $(call cc-option,-mno-implicit-fp,-m4-nofpu) | 41 | $(call cc-option,-mno-implicit-fp,-m4-nofpu) |
42 | cflags-$(CONFIG_CPU_SH4A) := -m4a $(call cc-option,-m4a-nofpu,) | 42 | cflags-$(CONFIG_CPU_SH4A) := $(call cc-option,-m4a,) $(call cc-option,-m4a-nofpu,) |
43 | 43 | ||
44 | cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mb | 44 | cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mb |
45 | cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml | 45 | cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml |
diff --git a/arch/sh/boards/landisk/gio.c b/arch/sh/boards/landisk/gio.c index 50d38be62f01..a37643d002b2 100644 --- a/arch/sh/boards/landisk/gio.c +++ b/arch/sh/boards/landisk/gio.c | |||
@@ -69,7 +69,7 @@ static int gio_ioctl(struct inode *inode, struct file *filp, | |||
69 | } | 69 | } |
70 | 70 | ||
71 | switch (cmd) { | 71 | switch (cmd) { |
72 | case GIODRV_IOCSGIOSETADDR: /* addres set */ | 72 | case GIODRV_IOCSGIOSETADDR: /* address set */ |
73 | addr = data; | 73 | addr = data; |
74 | break; | 74 | break; |
75 | 75 | ||
diff --git a/arch/sh/boards/landisk/setup.c b/arch/sh/boards/landisk/setup.c index 4058b4f50d44..f953c7427769 100644 --- a/arch/sh/boards/landisk/setup.c +++ b/arch/sh/boards/landisk/setup.c | |||
@@ -44,8 +44,14 @@ static struct platform_device cf_ide_device = { | |||
44 | }, | 44 | }, |
45 | }; | 45 | }; |
46 | 46 | ||
47 | static struct platform_device rtc_device = { | ||
48 | .name = "rs5c313", | ||
49 | .id = -1, | ||
50 | }; | ||
51 | |||
47 | static struct platform_device *landisk_devices[] __initdata = { | 52 | static struct platform_device *landisk_devices[] __initdata = { |
48 | &cf_ide_device, | 53 | &cf_ide_device, |
54 | &rtc_device, | ||
49 | }; | 55 | }; |
50 | 56 | ||
51 | static int __init landisk_devices_setup(void) | 57 | static int __init landisk_devices_setup(void) |
diff --git a/arch/sh/boards/renesas/r7780rp/Makefile b/arch/sh/boards/renesas/r7780rp/Makefile index 609e5d50dde8..b1d20afb4eb3 100644 --- a/arch/sh/boards/renesas/r7780rp/Makefile +++ b/arch/sh/boards/renesas/r7780rp/Makefile | |||
@@ -3,5 +3,8 @@ | |||
3 | # | 3 | # |
4 | irqinit-y := irq-r7780rp.o | 4 | irqinit-y := irq-r7780rp.o |
5 | irqinit-$(CONFIG_SH_R7785RP) := irq-r7785rp.o | 5 | irqinit-$(CONFIG_SH_R7785RP) := irq-r7785rp.o |
6 | obj-y := setup.o irq.o $(irqinit-y) | ||
7 | |||
8 | ifneq ($(CONFIG_SH_R7785RP),y) | ||
6 | obj-$(CONFIG_PUSH_SWITCH) += psw.o | 9 | obj-$(CONFIG_PUSH_SWITCH) += psw.o |
7 | obj-y := setup.o irq.o $(irqinit-y) | 10 | endif |
diff --git a/arch/sh/boards/se/73180/setup.c b/arch/sh/boards/se/73180/setup.c index 911ce1cdbd7f..e143017c8975 100644 --- a/arch/sh/boards/se/73180/setup.c +++ b/arch/sh/boards/se/73180/setup.c | |||
@@ -38,8 +38,8 @@ static struct platform_device *se73180_devices[] __initdata = { | |||
38 | 38 | ||
39 | static int __init se73180_devices_setup(void) | 39 | static int __init se73180_devices_setup(void) |
40 | { | 40 | { |
41 | return platform_add_devices(sh7343se_platform_devices, | 41 | return platform_add_devices(se73180_devices, |
42 | ARRAY_SIZE(sh7343se_platform_devices)); | 42 | ARRAY_SIZE(se73180_devices)); |
43 | } | 43 | } |
44 | __initcall(se73180_devices_setup); | 44 | __initcall(se73180_devices_setup); |
45 | 45 | ||
diff --git a/arch/sh/boards/snapgear/rtc.c b/arch/sh/boards/snapgear/rtc.c index 1659fdd6695a..edb3dd936cbb 100644 --- a/arch/sh/boards/snapgear/rtc.c +++ b/arch/sh/boards/snapgear/rtc.c | |||
@@ -108,7 +108,7 @@ static void ds1302_writebyte(unsigned int addr, unsigned int val) | |||
108 | static void ds1302_reset(void) | 108 | static void ds1302_reset(void) |
109 | { | 109 | { |
110 | unsigned long flags; | 110 | unsigned long flags; |
111 | /* Hardware dependant reset/init */ | 111 | /* Hardware dependent reset/init */ |
112 | local_irq_save(flags); | 112 | local_irq_save(flags); |
113 | set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK); | 113 | set_dirp(get_dirp() | RTC_RESET | RTC_IODATA | RTC_SCLK); |
114 | set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); | 114 | set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); |
diff --git a/arch/sh/boards/superh/microdev/io.c b/arch/sh/boards/superh/microdev/io.c index 83419bf4c834..b704e20d7e4d 100644 --- a/arch/sh/boards/superh/microdev/io.c +++ b/arch/sh/boards/superh/microdev/io.c | |||
@@ -198,12 +198,12 @@ void microdev_outb(unsigned char b, unsigned long port) | |||
198 | /* | 198 | /* |
199 | * There is a board feature with the current SH4-202 MicroDev in | 199 | * There is a board feature with the current SH4-202 MicroDev in |
200 | * that the 2 byte enables (nBE0 and nBE1) are tied together (and | 200 | * that the 2 byte enables (nBE0 and nBE1) are tied together (and |
201 | * to the Chip Select Line (Ethernet_CS)). Due to this conectivity, | 201 | * to the Chip Select Line (Ethernet_CS)). Due to this connectivity, |
202 | * it is not possible to safely perform 8-bit writes to the | 202 | * it is not possible to safely perform 8-bit writes to the |
203 | * Ethernet registers, as 16-bits will be consumed from the Data | 203 | * Ethernet registers, as 16-bits will be consumed from the Data |
204 | * lines (corrupting the other byte). Hence, this function is | 204 | * lines (corrupting the other byte). Hence, this function is |
205 | * written to impliment 16-bit read/modify/write for all byte-wide | 205 | * written to implement 16-bit read/modify/write for all byte-wide |
206 | * acceses. | 206 | * accesses. |
207 | * | 207 | * |
208 | * Note: there is no problem with byte READS (even or odd). | 208 | * Note: there is no problem with byte READS (even or odd). |
209 | * | 209 | * |
diff --git a/arch/sh/boards/superh/microdev/irq.c b/arch/sh/boards/superh/microdev/irq.c index 8c64baa30364..4d335077a3ff 100644 --- a/arch/sh/boards/superh/microdev/irq.c +++ b/arch/sh/boards/superh/microdev/irq.c | |||
@@ -11,6 +11,7 @@ | |||
11 | 11 | ||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
14 | #include <linux/interrupt.h> | ||
14 | #include <asm/system.h> | 15 | #include <asm/system.h> |
15 | #include <asm/io.h> | 16 | #include <asm/io.h> |
16 | #include <asm/microdev.h> | 17 | #include <asm/microdev.h> |
@@ -100,7 +101,7 @@ static void disable_microdev_irq(unsigned int irq) | |||
100 | 101 | ||
101 | fpgaIrq = fpgaIrqTable[irq].fpgaIrq; | 102 | fpgaIrq = fpgaIrqTable[irq].fpgaIrq; |
102 | 103 | ||
103 | /* disable interupts on the FPGA INTC register */ | 104 | /* disable interrupts on the FPGA INTC register */ |
104 | ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG); | 105 | ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTDSB_REG); |
105 | } | 106 | } |
106 | 107 | ||
@@ -125,7 +126,7 @@ static void enable_microdev_irq(unsigned int irq) | |||
125 | priorities |= MICRODEV_FPGA_INTPRI_LEVEL(fpgaIrq, pri); | 126 | priorities |= MICRODEV_FPGA_INTPRI_LEVEL(fpgaIrq, pri); |
126 | ctrl_outl(priorities, priorityReg); | 127 | ctrl_outl(priorities, priorityReg); |
127 | 128 | ||
128 | /* enable interupts on the FPGA INTC register */ | 129 | /* enable interrupts on the FPGA INTC register */ |
129 | ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG); | 130 | ctrl_outl(MICRODEV_FPGA_INTC_MASK(fpgaIrq), MICRODEV_FPGA_INTENB_REG); |
130 | } | 131 | } |
131 | 132 | ||
@@ -152,7 +153,7 @@ extern void __init init_microdev_irq(void) | |||
152 | { | 153 | { |
153 | int i; | 154 | int i; |
154 | 155 | ||
155 | /* disable interupts on the FPGA INTC register */ | 156 | /* disable interrupts on the FPGA INTC register */ |
156 | ctrl_outl(~0ul, MICRODEV_FPGA_INTDSB_REG); | 157 | ctrl_outl(~0ul, MICRODEV_FPGA_INTDSB_REG); |
157 | 158 | ||
158 | for (i = 0; i < NUM_EXTERNAL_IRQS; i++) | 159 | for (i = 0; i < NUM_EXTERNAL_IRQS; i++) |
diff --git a/arch/sh/boards/superh/microdev/setup.c b/arch/sh/boards/superh/microdev/setup.c index 031c814e6e76..6396cea1c896 100644 --- a/arch/sh/boards/superh/microdev/setup.c +++ b/arch/sh/boards/superh/microdev/setup.c | |||
@@ -349,7 +349,7 @@ static int __init smsc_superio_setup(void) | |||
349 | SMSC_WRITE_INDEXED(0x00, 0xc7); /* GP47 = nIOWOP */ | 349 | SMSC_WRITE_INDEXED(0x00, 0xc7); /* GP47 = nIOWOP */ |
350 | SMSC_WRITE_INDEXED(0x08, 0xe8); /* GP20 = nIDE2_OE */ | 350 | SMSC_WRITE_INDEXED(0x08, 0xe8); /* GP20 = nIDE2_OE */ |
351 | 351 | ||
352 | /* Exit the configuraton state */ | 352 | /* Exit the configuration state */ |
353 | outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR); | 353 | outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR); |
354 | 354 | ||
355 | return 0; | 355 | return 0; |
diff --git a/arch/sh/boards/unknown/setup.c b/arch/sh/boards/unknown/setup.c index 1c941370a2e3..bee4612de59b 100644 --- a/arch/sh/boards/unknown/setup.c +++ b/arch/sh/boards/unknown/setup.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * May be copied or modified under the terms of the GNU General Public | 6 | * May be copied or modified under the terms of the GNU General Public |
7 | * License. See linux/COPYING for more information. | 7 | * License. See linux/COPYING for more information. |
8 | * | 8 | * |
9 | * Setup code for an unknown machine (internal peripherials only) | 9 | * Setup code for an unknown machine (internal peripherals only) |
10 | * | 10 | * |
11 | * This is the simplest of all boards, and serves only as a quick and dirty | 11 | * This is the simplest of all boards, and serves only as a quick and dirty |
12 | * method to start debugging a new board during bring-up until proper board | 12 | * method to start debugging a new board during bring-up until proper board |
diff --git a/arch/sh/cchips/voyagergx/irq.c b/arch/sh/cchips/voyagergx/irq.c index 70f12907647f..d70e5c8461b5 100644 --- a/arch/sh/cchips/voyagergx/irq.c +++ b/arch/sh/cchips/voyagergx/irq.c | |||
@@ -28,7 +28,7 @@ static void disable_voyagergx_irq(unsigned int irq) | |||
28 | unsigned long val; | 28 | unsigned long val; |
29 | unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); | 29 | unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); |
30 | 30 | ||
31 | pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask); | 31 | pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask); |
32 | val = readl((void __iomem *)VOYAGER_INT_MASK); | 32 | val = readl((void __iomem *)VOYAGER_INT_MASK); |
33 | val &= ~mask; | 33 | val &= ~mask; |
34 | writel(val, (void __iomem *)VOYAGER_INT_MASK); | 34 | writel(val, (void __iomem *)VOYAGER_INT_MASK); |
@@ -39,7 +39,7 @@ static void enable_voyagergx_irq(unsigned int irq) | |||
39 | unsigned long val; | 39 | unsigned long val; |
40 | unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); | 40 | unsigned long mask = 1 << (irq - VOYAGER_IRQ_BASE); |
41 | 41 | ||
42 | pr_debug("disable_voyagergx_irq(%d): mask=%x\n", irq, mask); | 42 | pr_debug("disable_voyagergx_irq(%d): mask=%lx\n", irq, mask); |
43 | val = readl((void __iomem *)VOYAGER_INT_MASK); | 43 | val = readl((void __iomem *)VOYAGER_INT_MASK); |
44 | val |= mask; | 44 | val |= mask; |
45 | writel(val, (void __iomem *)VOYAGER_INT_MASK); | 45 | writel(val, (void __iomem *)VOYAGER_INT_MASK); |
@@ -125,11 +125,12 @@ int voyagergx_irq_demux(int irq) | |||
125 | i = 17; | 125 | i = 17; |
126 | else | 126 | else |
127 | printk("Unexpected IRQ irq = %d status = 0x%08lx\n", irq, val); | 127 | printk("Unexpected IRQ irq = %d status = 0x%08lx\n", irq, val); |
128 | pr_debug("voyagergx_irq_demux %d \n", i); | 128 | pr_debug("voyagergx_irq_demux %ld \n", i); |
129 | if (i < VOYAGER_IRQ_NUM) { | 129 | if (i < VOYAGER_IRQ_NUM) { |
130 | irq = VOYAGER_IRQ_BASE + i; | 130 | irq = VOYAGER_IRQ_BASE + i; |
131 | if (voyagergx_demux[i].func != 0) | 131 | if (voyagergx_demux[i].func != 0) |
132 | irq = voyagergx_demux[i].func(irq, voyagergx_demux[i].dev); | 132 | irq = voyagergx_demux[i].func(irq, |
133 | voyagergx_demux[i].dev); | ||
133 | } | 134 | } |
134 | } | 135 | } |
135 | return irq; | 136 | return irq; |
diff --git a/arch/sh/drivers/dma/dma-api.c b/arch/sh/drivers/dma/dma-api.c index e062067edd24..cf8e11994330 100644 --- a/arch/sh/drivers/dma/dma-api.c +++ b/arch/sh/drivers/dma/dma-api.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/list.h> | 16 | #include <linux/list.h> |
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/mm.h> | 18 | #include <linux/mm.h> |
19 | #include <linux/sched.h> | ||
19 | #include <asm/dma.h> | 20 | #include <asm/dma.h> |
20 | 21 | ||
21 | DEFINE_SPINLOCK(dma_spin_lock); | 22 | DEFINE_SPINLOCK(dma_spin_lock); |
@@ -115,7 +116,7 @@ static int search_cap(const char **haystack, const char *needle) | |||
115 | /** | 116 | /** |
116 | * request_dma_bycap - Allocate a DMA channel based on its capabilities | 117 | * request_dma_bycap - Allocate a DMA channel based on its capabilities |
117 | * @dmac: List of DMA controllers to search | 118 | * @dmac: List of DMA controllers to search |
118 | * @caps: List of capabilites | 119 | * @caps: List of capabilities |
119 | * | 120 | * |
120 | * Search all channels of all DMA controllers to find a channel which | 121 | * Search all channels of all DMA controllers to find a channel which |
121 | * matches the requested capabilities. The result is the channel | 122 | * matches the requested capabilities. The result is the channel |
diff --git a/arch/sh/drivers/dma/dma-isa.c b/arch/sh/drivers/dma/dma-isa.c index 05a74ffdb68d..5fb044b791c3 100644 --- a/arch/sh/drivers/dma/dma-isa.c +++ b/arch/sh/drivers/dma/dma-isa.c | |||
@@ -28,7 +28,7 @@ | |||
28 | * NOTE: ops->xfer() is the preferred way of doing things. However, there | 28 | * NOTE: ops->xfer() is the preferred way of doing things. However, there |
29 | * are some users of the ISA DMA API that exist in common code that we | 29 | * are some users of the ISA DMA API that exist in common code that we |
30 | * don't necessarily want to go out of our way to break, so we still | 30 | * don't necessarily want to go out of our way to break, so we still |
31 | * allow for some compatability at that level. Any new code is strongly | 31 | * allow for some compatibility at that level. Any new code is strongly |
32 | * advised to run far away from the ISA DMA API and use the SH DMA API | 32 | * advised to run far away from the ISA DMA API and use the SH DMA API |
33 | * directly. | 33 | * directly. |
34 | */ | 34 | */ |
diff --git a/arch/sh/drivers/dma/dmabrg.c b/arch/sh/drivers/dma/dmabrg.c index 9d0a29370f21..5e22689c2fcf 100644 --- a/arch/sh/drivers/dma/dmabrg.c +++ b/arch/sh/drivers/dma/dmabrg.c | |||
@@ -33,7 +33,7 @@ | |||
33 | * 9 | HAC1/SSI1 | rec | half done | DMABRGI2 | 33 | * 9 | HAC1/SSI1 | rec | half done | DMABRGI2 |
34 | * | 34 | * |
35 | * all can be enabled/disabled in the DMABRGCR register, | 35 | * all can be enabled/disabled in the DMABRGCR register, |
36 | * as well as checked if they occured. | 36 | * as well as checked if they occurred. |
37 | * | 37 | * |
38 | * DMABRGI0 services USB DMA Address errors, but it still must be | 38 | * DMABRGI0 services USB DMA Address errors, but it still must be |
39 | * enabled/acked in the DMABRGCR register. USB-DMA complete indicator | 39 | * enabled/acked in the DMABRGCR register. USB-DMA complete indicator |
diff --git a/arch/sh/drivers/pci/ops-dreamcast.c b/arch/sh/drivers/pci/ops-dreamcast.c index 381306cf5425..e1284fc69361 100644 --- a/arch/sh/drivers/pci/ops-dreamcast.c +++ b/arch/sh/drivers/pci/ops-dreamcast.c | |||
@@ -57,7 +57,7 @@ struct pci_channel board_pci_channels[] = { | |||
57 | * | 57 | * |
58 | * Also, we could very easily support both Type 0 and Type 1 configurations | 58 | * Also, we could very easily support both Type 0 and Type 1 configurations |
59 | * here, but since it doesn't seem that there is any such implementation in | 59 | * here, but since it doesn't seem that there is any such implementation in |
60 | * existance, we don't bother. | 60 | * existence, we don't bother. |
61 | * | 61 | * |
62 | * I suppose if someone actually gets around to ripping the chip out of | 62 | * I suppose if someone actually gets around to ripping the chip out of |
63 | * the BBA and hanging some more devices off of it, then this might be | 63 | * the BBA and hanging some more devices off of it, then this might be |
diff --git a/arch/sh/drivers/pci/pci-st40.c b/arch/sh/drivers/pci/pci-st40.c index d67656a44b15..543417ff8314 100644 --- a/arch/sh/drivers/pci/pci-st40.c +++ b/arch/sh/drivers/pci/pci-st40.c | |||
@@ -292,7 +292,7 @@ int __init st40pci_init(unsigned memStart, unsigned memSize) | |||
292 | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | | 292 | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | |
293 | PCI_COMMAND_IO); | 293 | PCI_COMMAND_IO); |
294 | 294 | ||
295 | /* Accesse to the 0xb0000000 -> 0xb6000000 area will go through to 0x10000000 -> 0x16000000 | 295 | /* Access to the 0xb0000000 -> 0xb6000000 area will go through to 0x10000000 -> 0x16000000 |
296 | * on the PCI bus. This allows a nice 1-1 bus to phys mapping. | 296 | * on the PCI bus. This allows a nice 1-1 bus to phys mapping. |
297 | */ | 297 | */ |
298 | 298 | ||
@@ -315,7 +315,7 @@ int __init st40pci_init(unsigned memStart, unsigned memSize) | |||
315 | ST40PCI_WRITE(CSR_MBAR0, 0); | 315 | ST40PCI_WRITE(CSR_MBAR0, 0); |
316 | ST40PCI_WRITE(LSR0, 0x0fff0001); | 316 | ST40PCI_WRITE(LSR0, 0x0fff0001); |
317 | 317 | ||
318 | /* ... and set up the initial incomming window to expose all of RAM */ | 318 | /* ... and set up the initial incoming window to expose all of RAM */ |
319 | pci_set_rbar_region(7, memStart, memStart, memSize); | 319 | pci_set_rbar_region(7, memStart, memStart, memSize); |
320 | 320 | ||
321 | /* Maximise timeout values */ | 321 | /* Maximise timeout values */ |
@@ -473,7 +473,7 @@ static void pci_set_rbar_region(unsigned int region, unsigned long localAddr | |||
473 | 473 | ||
474 | mask = r2p2(regionSize) - 0x10000; | 474 | mask = r2p2(regionSize) - 0x10000; |
475 | 475 | ||
476 | /* Diable the region (in case currently in use, should never happen) */ | 476 | /* Disable the region (in case currently in use, should never happen) */ |
477 | ST40PCI_WRITE_INDEXED(RSR, region, 0); | 477 | ST40PCI_WRITE_INDEXED(RSR, region, 0); |
478 | 478 | ||
479 | /* Start of local address space to publish */ | 479 | /* Start of local address space to publish */ |
diff --git a/arch/sh/drivers/pci/pci-st40.h b/arch/sh/drivers/pci/pci-st40.h index d729e0c2d5fe..cf0d35bd135c 100644 --- a/arch/sh/drivers/pci/pci-st40.h +++ b/arch/sh/drivers/pci/pci-st40.h | |||
@@ -4,7 +4,7 @@ | |||
4 | * May be copied or modified under the terms of the GNU General Public | 4 | * May be copied or modified under the terms of the GNU General Public |
5 | * License. See linux/COPYING for more information. | 5 | * License. See linux/COPYING for more information. |
6 | * | 6 | * |
7 | * Defintions for the ST40 PCI hardware. | 7 | * Definitions for the ST40 PCI hardware. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #ifndef __PCI_ST40_H__ | 10 | #ifndef __PCI_ST40_H__ |
diff --git a/arch/sh/drivers/superhyway/ops-sh4-202.c b/arch/sh/drivers/superhyway/ops-sh4-202.c index a55c98a9052b..3b14bf860db6 100644 --- a/arch/sh/drivers/superhyway/ops-sh4-202.c +++ b/arch/sh/drivers/superhyway/ops-sh4-202.c | |||
@@ -130,7 +130,7 @@ static int sh4202_read_vcr(unsigned long base, struct superhyway_vcr_info *vcr) | |||
130 | * Some modules (PBR and ePBR for instance) also appear to have | 130 | * Some modules (PBR and ePBR for instance) also appear to have |
131 | * VCRL/VCRH flipped in the documentation, but on the SH4-202 | 131 | * VCRL/VCRH flipped in the documentation, but on the SH4-202 |
132 | * itself it appears that these are all consistently mapped with | 132 | * itself it appears that these are all consistently mapped with |
133 | * VCRH preceeding VCRL. | 133 | * VCRH preceding VCRL. |
134 | * | 134 | * |
135 | * Do not trust the documentation, for it is evil. | 135 | * Do not trust the documentation, for it is evil. |
136 | */ | 136 | */ |
diff --git a/arch/sh/kernel/cf-enabler.c b/arch/sh/kernel/cf-enabler.c index 0758d48147a0..ebc73b85094a 100644 --- a/arch/sh/kernel/cf-enabler.c +++ b/arch/sh/kernel/cf-enabler.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/mm.h> | 13 | #include <linux/mm.h> |
14 | #include <linux/vmalloc.h> | 14 | #include <linux/vmalloc.h> |
15 | #include <linux/interrupt.h> | ||
15 | #include <asm/io.h> | 16 | #include <asm/io.h> |
16 | #include <asm/irq.h> | 17 | #include <asm/irq.h> |
17 | 18 | ||
@@ -31,7 +32,7 @@ | |||
31 | */ | 32 | */ |
32 | #if defined(CONFIG_CPU_SH4) | 33 | #if defined(CONFIG_CPU_SH4) |
33 | /* SH4 can't access PCMCIA interface through P2 area. | 34 | /* SH4 can't access PCMCIA interface through P2 area. |
34 | * we must remap it with appropreate attribute bit of the page set. | 35 | * we must remap it with appropriate attribute bit of the page set. |
35 | * this part is based on Greg Banks' hd64465_ss.c implementation - Masahiro Abe */ | 36 | * this part is based on Greg Banks' hd64465_ss.c implementation - Masahiro Abe */ |
36 | 37 | ||
37 | #if defined(CONFIG_CF_AREA6) | 38 | #if defined(CONFIG_CF_AREA6) |
@@ -149,6 +150,11 @@ static int __init cf_init_se(void) | |||
149 | ctrl_outb(0x42, PA_MRSHPC_MW2 + 0x200); | 150 | ctrl_outb(0x42, PA_MRSHPC_MW2 + 0x200); |
150 | return 0; | 151 | return 0; |
151 | } | 152 | } |
153 | #else | ||
154 | static int __init cf_init_se(void) | ||
155 | { | ||
156 | return -1; | ||
157 | } | ||
152 | #endif | 158 | #endif |
153 | 159 | ||
154 | int __init cf_init(void) | 160 | int __init cf_init(void) |
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 014f318f5a05..63251549e9a8 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c | |||
@@ -278,6 +278,11 @@ arch_init_clk_ops(struct clk_ops **ops, int type) | |||
278 | { | 278 | { |
279 | } | 279 | } |
280 | 280 | ||
281 | void __init __attribute__ ((weak)) | ||
282 | arch_clk_init(void) | ||
283 | { | ||
284 | } | ||
285 | |||
281 | static int show_clocks(char *buf, char **start, off_t off, | 286 | static int show_clocks(char *buf, char **start, off_t off, |
282 | int len, int *eof, void *data) | 287 | int len, int *eof, void *data) |
283 | { | 288 | { |
@@ -314,6 +319,8 @@ int __init clk_init(void) | |||
314 | ret |= clk_register(clk); | 319 | ret |= clk_register(clk); |
315 | } | 320 | } |
316 | 321 | ||
322 | arch_clk_init(); | ||
323 | |||
317 | /* Kick the child clocks.. */ | 324 | /* Kick the child clocks.. */ |
318 | propagate_rate(&master_clk); | 325 | propagate_rate(&master_clk); |
319 | propagate_rate(&bus_clk); | 326 | propagate_rate(&bus_clk); |
diff --git a/arch/sh/kernel/cpu/irq/maskreg.c b/arch/sh/kernel/cpu/irq/maskreg.c index 492db31b3cab..978992e367a5 100644 --- a/arch/sh/kernel/cpu/irq/maskreg.c +++ b/arch/sh/kernel/cpu/irq/maskreg.c | |||
@@ -38,7 +38,7 @@ static struct hw_interrupt_type maskreg_irq_type = { | |||
38 | .end = end_maskreg_irq | 38 | .end = end_maskreg_irq |
39 | }; | 39 | }; |
40 | 40 | ||
41 | /* actual implementatin */ | 41 | /* actual implementation */ |
42 | static unsigned int startup_maskreg_irq(unsigned int irq) | 42 | static unsigned int startup_maskreg_irq(unsigned int irq) |
43 | { | 43 | { |
44 | enable_maskreg_irq(irq); | 44 | enable_maskreg_irq(irq); |
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S index 832c0b4a1e6c..b0b59d4a33ca 100644 --- a/arch/sh/kernel/cpu/sh3/entry.S +++ b/arch/sh/kernel/cpu/sh3/entry.S | |||
@@ -320,6 +320,9 @@ skip_restore: | |||
320 | 320 | ||
321 | .align 2 | 321 | .align 2 |
322 | 5: .long 0x00001000 ! DSP | 322 | 5: .long 0x00001000 ! DSP |
323 | #ifdef CONFIG_KGDB_NMI | ||
324 | 6: .long in_nmi | ||
325 | #endif | ||
323 | 7: .long 0x30000000 | 326 | 7: .long 0x30000000 |
324 | 327 | ||
325 | ! common exception handler | 328 | ! common exception handler |
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c index fcb2c41bc34e..a33429463e96 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c | |||
@@ -111,7 +111,7 @@ static int shoc_clk_verify_rate(struct clk *clk, unsigned long rate) | |||
111 | return 0; | 111 | return 0; |
112 | } | 112 | } |
113 | 113 | ||
114 | static int shoc_clk_set_rate(struct clk *clk, unsigned long rate) | 114 | static int shoc_clk_set_rate(struct clk *clk, unsigned long rate, int algo_id) |
115 | { | 115 | { |
116 | unsigned long frqcr3; | 116 | unsigned long frqcr3; |
117 | unsigned int tmp; | 117 | unsigned int tmp; |
diff --git a/arch/sh/kernel/cpu/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c index d61dd599169f..c5a4fc77fa06 100644 --- a/arch/sh/kernel/cpu/sh4/fpu.c +++ b/arch/sh/kernel/cpu/sh4/fpu.c | |||
@@ -138,7 +138,7 @@ restore_fpu(struct task_struct *tsk) | |||
138 | /* | 138 | /* |
139 | * Load the FPU with signalling NANS. This bit pattern we're using | 139 | * Load the FPU with signalling NANS. This bit pattern we're using |
140 | * has the property that no matter wether considered as single or as | 140 | * has the property that no matter wether considered as single or as |
141 | * double precission represents signaling NANS. | 141 | * double precision represents signaling NANS. |
142 | */ | 142 | */ |
143 | 143 | ||
144 | static void | 144 | static void |
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c index 8cd04904c77a..fab2eb07196b 100644 --- a/arch/sh/kernel/cpu/sh4/probe.c +++ b/arch/sh/kernel/cpu/sh4/probe.c | |||
@@ -12,6 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <linux/smp.h> | ||
15 | #include <asm/processor.h> | 16 | #include <asm/processor.h> |
16 | #include <asm/cache.h> | 17 | #include <asm/cache.h> |
17 | 18 | ||
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index 6f8f458912c7..03b14cf78ddf 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c | |||
@@ -106,6 +106,7 @@ static struct ipr_data sh7750_ipr_map[] = { | |||
106 | { 38, 2, 8, 7 }, /* DMAC DMAE */ | 106 | { 38, 2, 8, 7 }, /* DMAC DMAE */ |
107 | }; | 107 | }; |
108 | 108 | ||
109 | #ifdef CONFIG_CPU_SUBTYPE_SH7751 | ||
109 | static struct ipr_data sh7751_ipr_map[] = { | 110 | static struct ipr_data sh7751_ipr_map[] = { |
110 | { 44, 2, 8, 7 }, /* DMAC DMTE4 */ | 111 | { 44, 2, 8, 7 }, /* DMAC DMTE4 */ |
111 | { 45, 2, 8, 7 }, /* DMAC DMTE5 */ | 112 | { 45, 2, 8, 7 }, /* DMAC DMTE5 */ |
@@ -117,6 +118,7 @@ static struct ipr_data sh7751_ipr_map[] = { | |||
117 | /*{ 72, INTPRI00, 8, ? },*/ /* TMU3 TUNI */ | 118 | /*{ 72, INTPRI00, 8, ? },*/ /* TMU3 TUNI */ |
118 | /*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */ | 119 | /*{ 76, INTPRI00, 12, ? },*/ /* TMU4 TUNI */ |
119 | }; | 120 | }; |
121 | #endif | ||
120 | 122 | ||
121 | static unsigned long ipr_offsets[] = { | 123 | static unsigned long ipr_offsets[] = { |
122 | 0xffd00004UL, /* 0: IPRA */ | 124 | 0xffd00004UL, /* 0: IPRA */ |
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 29090035bc5b..51b386d454de 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <asm/clock.h> | 17 | #include <asm/clock.h> |
18 | #include <asm/freq.h> | 18 | #include <asm/freq.h> |
19 | 19 | ||
20 | #define SH7722_PLL_FREQ (32000000/8) | ||
21 | #define N (-1) | 20 | #define N (-1) |
22 | #define NM (-2) | 21 | #define NM (-2) |
23 | #define ROUND_NEAREST 0 | 22 | #define ROUND_NEAREST 0 |
@@ -141,28 +140,36 @@ static void adjust_clocks(int originate, int *l, unsigned long v[], | |||
141 | */ | 140 | */ |
142 | static int divisors2[] = { 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40 }; | 141 | static int divisors2[] = { 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40 }; |
143 | 142 | ||
143 | static void master_clk_recalc(struct clk *clk) | ||
144 | { | ||
145 | unsigned frqcr = ctrl_inl(FRQCR); | ||
146 | |||
147 | clk->rate = CONFIG_SH_PCLK_FREQ * (((frqcr >> 24) & 0x1f) + 1); | ||
148 | } | ||
149 | |||
144 | static void master_clk_init(struct clk *clk) | 150 | static void master_clk_init(struct clk *clk) |
145 | { | 151 | { |
146 | clk_set_rate(clk, clk_get_rate(clk)); | 152 | clk->parent = NULL; |
153 | clk->flags |= CLK_RATE_PROPAGATES; | ||
154 | clk->rate = CONFIG_SH_PCLK_FREQ; | ||
155 | master_clk_recalc(clk); | ||
147 | } | 156 | } |
148 | 157 | ||
149 | static void master_clk_recalc(struct clk *clk) | 158 | |
159 | static void module_clk_recalc(struct clk *clk) | ||
150 | { | 160 | { |
151 | unsigned long frqcr = ctrl_inl(FRQCR); | 161 | unsigned long frqcr = ctrl_inl(FRQCR); |
152 | 162 | ||
153 | clk->rate = CONFIG_SH_PCLK_FREQ * (1 + (frqcr >> 24 & 0xF)); | 163 | clk->rate = clk->parent->rate / (((frqcr >> 24) & 0x1f) + 1); |
154 | } | 164 | } |
155 | 165 | ||
156 | static int master_clk_setrate(struct clk *clk, unsigned long rate, int id) | 166 | static int master_clk_setrate(struct clk *clk, unsigned long rate, int id) |
157 | { | 167 | { |
158 | int div = rate / SH7722_PLL_FREQ; | 168 | int div = rate / clk->rate; |
159 | int master_divs[] = { 2, 3, 4, 6, 8, 16 }; | 169 | int master_divs[] = { 2, 3, 4, 6, 8, 16 }; |
160 | int index; | 170 | int index; |
161 | unsigned long frqcr; | 171 | unsigned long frqcr; |
162 | 172 | ||
163 | if (rate < SH7722_PLL_FREQ * 2) | ||
164 | return -EINVAL; | ||
165 | |||
166 | for (index = 1; index < ARRAY_SIZE(master_divs); index++) | 173 | for (index = 1; index < ARRAY_SIZE(master_divs); index++) |
167 | if (div >= master_divs[index - 1] && div < master_divs[index]) | 174 | if (div >= master_divs[index - 1] && div < master_divs[index]) |
168 | break; | 175 | break; |
@@ -185,6 +192,10 @@ static struct clk_ops sh7722_master_clk_ops = { | |||
185 | .set_rate = master_clk_setrate, | 192 | .set_rate = master_clk_setrate, |
186 | }; | 193 | }; |
187 | 194 | ||
195 | static struct clk_ops sh7722_module_clk_ops = { | ||
196 | .recalc = module_clk_recalc, | ||
197 | }; | ||
198 | |||
188 | struct frqcr_context { | 199 | struct frqcr_context { |
189 | unsigned mask; | 200 | unsigned mask; |
190 | unsigned shift; | 201 | unsigned shift; |
@@ -489,7 +500,7 @@ static void sh7722_siu_recalc(struct clk *clk) | |||
489 | 500 | ||
490 | if (siu < 0) | 501 | if (siu < 0) |
491 | return /* siu */ ; | 502 | return /* siu */ ; |
492 | BUG_ON(siu > 1); | 503 | BUG_ON(siu > 2); |
493 | r = ctrl_inl(sh7722_siu_regs[siu]); | 504 | r = ctrl_inl(sh7722_siu_regs[siu]); |
494 | clk->rate = clk->parent->rate * 2 / divisors2[r & 0xF]; | 505 | clk->rate = clk->parent->rate * 2 / divisors2[r & 0xF]; |
495 | } | 506 | } |
@@ -571,7 +582,7 @@ static struct clk *sh7722_clocks[] = { | |||
571 | */ | 582 | */ |
572 | struct clk_ops *onchip_ops[] = { | 583 | struct clk_ops *onchip_ops[] = { |
573 | &sh7722_master_clk_ops, | 584 | &sh7722_master_clk_ops, |
574 | &sh7722_frqcr_clk_ops, | 585 | &sh7722_module_clk_ops, |
575 | &sh7722_frqcr_clk_ops, | 586 | &sh7722_frqcr_clk_ops, |
576 | &sh7722_frqcr_clk_ops, | 587 | &sh7722_frqcr_clk_ops, |
577 | }; | 588 | }; |
@@ -583,7 +594,7 @@ arch_init_clk_ops(struct clk_ops **ops, int type) | |||
583 | *ops = onchip_ops[type]; | 594 | *ops = onchip_ops[type]; |
584 | } | 595 | } |
585 | 596 | ||
586 | int __init sh7722_clock_init(void) | 597 | int __init arch_clk_init(void) |
587 | { | 598 | { |
588 | struct clk *master; | 599 | struct clk *master; |
589 | int i; | 600 | int i; |
@@ -597,4 +608,3 @@ int __init sh7722_clock_init(void) | |||
597 | clk_put(master); | 608 | clk_put(master); |
598 | return 0; | 609 | return 0; |
599 | } | 610 | } |
600 | arch_initcall(sh7722_clock_init); | ||
diff --git a/arch/sh/kernel/kgdb_stub.c b/arch/sh/kernel/kgdb_stub.c index a5323364cbca..edd1ec214e6d 100644 --- a/arch/sh/kernel/kgdb_stub.c +++ b/arch/sh/kernel/kgdb_stub.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * May be copied or modified under the terms of the GNU General Public | 2 | * May be copied or modified under the terms of the GNU General Public |
3 | * License. See linux/COPYING for more information. | 3 | * License. See linux/COPYING for more information. |
4 | * | 4 | * |
5 | * Containes extracts from code by Glenn Engel, Jim Kingdon, | 5 | * Contains extracts from code by Glenn Engel, Jim Kingdon, |
6 | * David Grothe <dave@gcom.com>, Tigran Aivazian <tigran@sco.com>, | 6 | * David Grothe <dave@gcom.com>, Tigran Aivazian <tigran@sco.com>, |
7 | * Amit S. Kale <akale@veritas.com>, William Gatliff <bgat@open-widgets.com>, | 7 | * Amit S. Kale <akale@veritas.com>, William Gatliff <bgat@open-widgets.com>, |
8 | * Ben Lee, Steve Chamberlain and Benoit Miller <fulg@iname.com>. | 8 | * Ben Lee, Steve Chamberlain and Benoit Miller <fulg@iname.com>. |
@@ -85,7 +85,7 @@ | |||
85 | * | 85 | * |
86 | * Responses can be run-length encoded to save space. A '*' means that | 86 | * Responses can be run-length encoded to save space. A '*' means that |
87 | * the next character is an ASCII encoding giving a repeat count which | 87 | * the next character is an ASCII encoding giving a repeat count which |
88 | * stands for that many repititions of the character preceding the '*'. | 88 | * stands for that many repetitions of the character preceding the '*'. |
89 | * The encoding is n+29, yielding a printable character where n >=3 | 89 | * The encoding is n+29, yielding a printable character where n >=3 |
90 | * (which is where RLE starts to win). Don't use an n > 126. | 90 | * (which is where RLE starts to win). Don't use an n > 126. |
91 | * | 91 | * |
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c index 6b4f5748d0be..a11e2aa73cbc 100644 --- a/arch/sh/kernel/process.c +++ b/arch/sh/kernel/process.c | |||
@@ -26,8 +26,6 @@ | |||
26 | static int hlt_counter; | 26 | static int hlt_counter; |
27 | int ubc_usercnt = 0; | 27 | int ubc_usercnt = 0; |
28 | 28 | ||
29 | #define HARD_IDLE_TIMEOUT (HZ / 3) | ||
30 | |||
31 | void (*pm_idle)(void); | 29 | void (*pm_idle)(void); |
32 | void (*pm_power_off)(void); | 30 | void (*pm_power_off)(void); |
33 | EXPORT_SYMBOL(pm_power_off); | 31 | EXPORT_SYMBOL(pm_power_off); |
@@ -44,16 +42,39 @@ void enable_hlt(void) | |||
44 | } | 42 | } |
45 | EXPORT_SYMBOL(enable_hlt); | 43 | EXPORT_SYMBOL(enable_hlt); |
46 | 44 | ||
45 | static int __init nohlt_setup(char *__unused) | ||
46 | { | ||
47 | hlt_counter = 1; | ||
48 | return 1; | ||
49 | } | ||
50 | __setup("nohlt", nohlt_setup); | ||
51 | |||
52 | static int __init hlt_setup(char *__unused) | ||
53 | { | ||
54 | hlt_counter = 0; | ||
55 | return 1; | ||
56 | } | ||
57 | __setup("hlt", hlt_setup); | ||
58 | |||
47 | void default_idle(void) | 59 | void default_idle(void) |
48 | { | 60 | { |
49 | if (!hlt_counter) | 61 | if (!hlt_counter) { |
50 | cpu_sleep(); | 62 | clear_thread_flag(TIF_POLLING_NRFLAG); |
51 | else | 63 | smp_mb__after_clear_bit(); |
52 | cpu_relax(); | 64 | set_bl_bit(); |
65 | while (!need_resched()) | ||
66 | cpu_sleep(); | ||
67 | clear_bl_bit(); | ||
68 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
69 | } else | ||
70 | while (!need_resched()) | ||
71 | cpu_relax(); | ||
53 | } | 72 | } |
54 | 73 | ||
55 | void cpu_idle(void) | 74 | void cpu_idle(void) |
56 | { | 75 | { |
76 | set_thread_flag(TIF_POLLING_NRFLAG); | ||
77 | |||
57 | /* endless idle loop with no priority at all */ | 78 | /* endless idle loop with no priority at all */ |
58 | while (1) { | 79 | while (1) { |
59 | void (*idle)(void) = pm_idle; | 80 | void (*idle)(void) = pm_idle; |
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c index dbebaddcfe39..283e1425ced5 100644 --- a/arch/sh/kernel/smp.c +++ b/arch/sh/kernel/smp.c | |||
@@ -10,6 +10,8 @@ | |||
10 | * Free Software Foundation; either version 2 of the License, or (at your | 10 | * Free Software Foundation; either version 2 of the License, or (at your |
11 | * option) any later version. | 11 | * option) any later version. |
12 | */ | 12 | */ |
13 | |||
14 | #include <linux/err.h> | ||
13 | #include <linux/cache.h> | 15 | #include <linux/cache.h> |
14 | #include <linux/cpumask.h> | 16 | #include <linux/cpumask.h> |
15 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
diff --git a/arch/sh/kernel/syscalls.S b/arch/sh/kernel/syscalls.S index 4357d1a6358f..7db1c2dc5992 100644 --- a/arch/sh/kernel/syscalls.S +++ b/arch/sh/kernel/syscalls.S | |||
@@ -355,3 +355,6 @@ ENTRY(sys_call_table) | |||
355 | .long sys_getcpu | 355 | .long sys_getcpu |
356 | .long sys_epoll_pwait | 356 | .long sys_epoll_pwait |
357 | .long sys_utimensat /* 320 */ | 357 | .long sys_utimensat /* 320 */ |
358 | .long sys_signalfd | ||
359 | .long sys_timerfd | ||
360 | .long sys_eventfd | ||
diff --git a/arch/sh/kernel/timers/timer.c b/arch/sh/kernel/timers/timer.c index a6bcc913d25e..4e7e747d1b69 100644 --- a/arch/sh/kernel/timers/timer.c +++ b/arch/sh/kernel/timers/timer.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include <linux/string.h> | 13 | #include <linux/string.h> |
14 | #include <asm/timer.h> | 14 | #include <asm/timer.h> |
15 | 15 | ||
16 | static struct sys_timer *sys_timers[] __initdata = { | 16 | static struct sys_timer *sys_timers[] = { |
17 | #ifdef CONFIG_SH_TMU | 17 | #ifdef CONFIG_SH_TMU |
18 | &tmu_timer, | 18 | &tmu_timer, |
19 | #endif | 19 | #endif |
@@ -26,7 +26,7 @@ static struct sys_timer *sys_timers[] __initdata = { | |||
26 | NULL, | 26 | NULL, |
27 | }; | 27 | }; |
28 | 28 | ||
29 | static char timer_override[10] __initdata; | 29 | static char timer_override[10]; |
30 | static int __init timer_setup(char *str) | 30 | static int __init timer_setup(char *str) |
31 | { | 31 | { |
32 | if (str) | 32 | if (str) |
@@ -53,4 +53,3 @@ struct sys_timer *get_sys_timer(void) | |||
53 | 53 | ||
54 | return NULL; | 54 | return NULL; |
55 | } | 55 | } |
56 | |||
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c index 3a197649cd83..5b75cb6f8f9b 100644 --- a/arch/sh/kernel/traps.c +++ b/arch/sh/kernel/traps.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/bug.h> | 21 | #include <linux/bug.h> |
22 | #include <linux/debug_locks.h> | 22 | #include <linux/debug_locks.h> |
23 | #include <linux/kdebug.h> | 23 | #include <linux/kdebug.h> |
24 | #include <linux/kexec.h> | ||
24 | #include <linux/limits.h> | 25 | #include <linux/limits.h> |
25 | #include <asm/system.h> | 26 | #include <asm/system.h> |
26 | #include <asm/uaccess.h> | 27 | #include <asm/uaccess.h> |
@@ -101,6 +102,16 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
101 | 102 | ||
102 | bust_spinlocks(0); | 103 | bust_spinlocks(0); |
103 | spin_unlock_irq(&die_lock); | 104 | spin_unlock_irq(&die_lock); |
105 | |||
106 | if (kexec_should_crash(current)) | ||
107 | crash_kexec(regs); | ||
108 | |||
109 | if (in_interrupt()) | ||
110 | panic("Fatal exception in interrupt"); | ||
111 | |||
112 | if (panic_on_oops) | ||
113 | panic("Fatal exception"); | ||
114 | |||
104 | do_exit(SIGSEGV); | 115 | do_exit(SIGSEGV); |
105 | } | 116 | } |
106 | 117 | ||
@@ -513,7 +524,7 @@ static int handle_unaligned_access(u16 instruction, struct pt_regs *regs) | |||
513 | * misaligned data access | 524 | * misaligned data access |
514 | * access to >= 0x80000000 is user mode | 525 | * access to >= 0x80000000 is user mode |
515 | * Unfortuntaly we can't distinguish between instruction address error | 526 | * Unfortuntaly we can't distinguish between instruction address error |
516 | * and data address errors caused by read acceses. | 527 | * and data address errors caused by read accesses. |
517 | */ | 528 | */ |
518 | asmlinkage void do_address_error(struct pt_regs *regs, | 529 | asmlinkage void do_address_error(struct pt_regs *regs, |
519 | unsigned long writeaccess, | 530 | unsigned long writeaccess, |
diff --git a/arch/sh/kernel/vsyscall/vsyscall.c b/arch/sh/kernel/vsyscall/vsyscall.c index e146bafcd14f..2aa9438361bc 100644 --- a/arch/sh/kernel/vsyscall/vsyscall.c +++ b/arch/sh/kernel/vsyscall/vsyscall.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/gfp.h> | 17 | #include <linux/gfp.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/elf.h> | 19 | #include <linux/elf.h> |
20 | #include <linux/sched.h> | ||
20 | 21 | ||
21 | /* | 22 | /* |
22 | * Should the kernel map a VDSO page into processes and pass its | 23 | * Should the kernel map a VDSO page into processes and pass its |
diff --git a/arch/sh/math-emu/math.c b/arch/sh/math-emu/math.c index 1efbac15ff4e..a38e1eed9e77 100644 --- a/arch/sh/math-emu/math.c +++ b/arch/sh/math-emu/math.c | |||
@@ -148,7 +148,7 @@ fmac(struct sh_fpu_soft_struct *fregs, struct pt_regs *regs, int m, int n) | |||
148 | return 0; | 148 | return 0; |
149 | } | 149 | } |
150 | 150 | ||
151 | // to process fmov's extention (odd n for DR access XD). | 151 | // to process fmov's extension (odd n for DR access XD). |
152 | #define FMOV_EXT(x) if(x&1) x+=16-1 | 152 | #define FMOV_EXT(x) if(x&1) x+=16-1 |
153 | 153 | ||
154 | static int | 154 | static int |
diff --git a/arch/sh/mm/copy_page.S b/arch/sh/mm/copy_page.S index 397c94c97315..ae039f2da162 100644 --- a/arch/sh/mm/copy_page.S +++ b/arch/sh/mm/copy_page.S | |||
@@ -129,6 +129,7 @@ ENTRY(__copy_user_page) | |||
129 | rts | 129 | rts |
130 | nop | 130 | nop |
131 | #endif | 131 | #endif |
132 | .align 2 | ||
132 | .Lpsz: .long PAGE_SIZE | 133 | .Lpsz: .long PAGE_SIZE |
133 | /* | 134 | /* |
134 | * __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n); | 135 | * __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n); |
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c index 9207da67ff8a..c878faa4ae46 100644 --- a/arch/sh/mm/fault.c +++ b/arch/sh/mm/fault.c | |||
@@ -15,43 +15,11 @@ | |||
15 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
16 | #include <linux/hardirq.h> | 16 | #include <linux/hardirq.h> |
17 | #include <linux/kprobes.h> | 17 | #include <linux/kprobes.h> |
18 | #include <linux/kdebug.h> | ||
19 | #include <asm/system.h> | 18 | #include <asm/system.h> |
20 | #include <asm/mmu_context.h> | 19 | #include <asm/mmu_context.h> |
21 | #include <asm/tlbflush.h> | 20 | #include <asm/tlbflush.h> |
22 | #include <asm/kgdb.h> | 21 | #include <asm/kgdb.h> |
23 | 22 | ||
24 | #ifdef CONFIG_KPROBES | ||
25 | ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); | ||
26 | |||
27 | /* Hook to register for page fault notifications */ | ||
28 | int register_page_fault_notifier(struct notifier_block *nb) | ||
29 | { | ||
30 | return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); | ||
31 | } | ||
32 | |||
33 | int unregister_page_fault_notifier(struct notifier_block *nb) | ||
34 | { | ||
35 | return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); | ||
36 | } | ||
37 | |||
38 | static inline int notify_page_fault(enum die_val val, struct pt_regs *regs, | ||
39 | int trap, int sig) | ||
40 | { | ||
41 | struct die_args args = { | ||
42 | .regs = regs, | ||
43 | .trapnr = trap, | ||
44 | }; | ||
45 | return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); | ||
46 | } | ||
47 | #else | ||
48 | static inline int notify_page_fault(enum die_val val, struct pt_regs *regs, | ||
49 | int trap, int sig) | ||
50 | { | ||
51 | return NOTIFY_DONE; | ||
52 | } | ||
53 | #endif | ||
54 | |||
55 | /* | 23 | /* |
56 | * This routine handles page faults. It determines the address, | 24 | * This routine handles page faults. It determines the address, |
57 | * and the problem, and then passes it off to one of the appropriate | 25 | * and the problem, and then passes it off to one of the appropriate |
@@ -69,11 +37,6 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, | |||
69 | siginfo_t info; | 37 | siginfo_t info; |
70 | 38 | ||
71 | trace_hardirqs_on(); | 39 | trace_hardirqs_on(); |
72 | |||
73 | if (notify_page_fault(DIE_PAGE_FAULT, regs, | ||
74 | writeaccess, SIGSEGV) == NOTIFY_STOP) | ||
75 | return; | ||
76 | |||
77 | local_irq_enable(); | 40 | local_irq_enable(); |
78 | 41 | ||
79 | #ifdef CONFIG_SH_KGDB | 42 | #ifdef CONFIG_SH_KGDB |
@@ -285,7 +248,7 @@ asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs, | |||
285 | pte_t *pte; | 248 | pte_t *pte; |
286 | pte_t entry; | 249 | pte_t entry; |
287 | struct mm_struct *mm = current->mm; | 250 | struct mm_struct *mm = current->mm; |
288 | spinlock_t *ptl; | 251 | spinlock_t *ptl = NULL; |
289 | int ret = 1; | 252 | int ret = 1; |
290 | 253 | ||
291 | #ifdef CONFIG_SH_KGDB | 254 | #ifdef CONFIG_SH_KGDB |
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 8fe223a890ed..e0e644ff3204 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/bootmem.h> | 13 | #include <linux/bootmem.h> |
14 | #include <linux/proc_fs.h> | 14 | #include <linux/proc_fs.h> |
15 | #include <linux/pagemap.h> | ||
15 | #include <linux/percpu.h> | 16 | #include <linux/percpu.h> |
16 | #include <linux/io.h> | 17 | #include <linux/io.h> |
17 | #include <asm/mmu_context.h> | 18 | #include <asm/mmu_context.h> |
@@ -112,7 +113,7 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot) | |||
112 | * As a performance optimization, other platforms preserve the fixmap mapping | 113 | * As a performance optimization, other platforms preserve the fixmap mapping |
113 | * across a context switch, we don't presently do this, but this could be done | 114 | * across a context switch, we don't presently do this, but this could be done |
114 | * in a similar fashion as to the wired TLB interface that sh64 uses (by way | 115 | * in a similar fashion as to the wired TLB interface that sh64 uses (by way |
115 | * of the memorry mapped UTLB configuration) -- this unfortunately forces us to | 116 | * of the memory mapped UTLB configuration) -- this unfortunately forces us to |
116 | * give up a TLB entry for each mapping we want to preserve. While this may be | 117 | * give up a TLB entry for each mapping we want to preserve. While this may be |
117 | * viable for a small number of fixmaps, it's not particularly useful for | 118 | * viable for a small number of fixmaps, it's not particularly useful for |
118 | * everything and needs to be carefully evaluated. (ie, we may want this for | 119 | * everything and needs to be carefully evaluated. (ie, we may want this for |
diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c index be03d74e99cb..0c7b7e33abdc 100644 --- a/arch/sh/mm/ioremap.c +++ b/arch/sh/mm/ioremap.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <asm/addrspace.h> | 22 | #include <asm/addrspace.h> |
23 | #include <asm/cacheflush.h> | 23 | #include <asm/cacheflush.h> |
24 | #include <asm/tlbflush.h> | 24 | #include <asm/tlbflush.h> |
25 | #include <asm/mmu.h> | ||
25 | 26 | ||
26 | /* | 27 | /* |
27 | * Remap an arbitrary physical address space into the kernel virtual | 28 | * Remap an arbitrary physical address space into the kernel virtual |
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index 02aae06527dc..b6a5a338145b 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Privileged Space Mapping Buffer (PMB) Support. | 4 | * Privileged Space Mapping Buffer (PMB) Support. |
5 | * | 5 | * |
6 | * Copyright (C) 2005, 2006 Paul Mundt | 6 | * Copyright (C) 2005, 2006, 2007 Paul Mundt |
7 | * | 7 | * |
8 | * P1/P2 Section mapping definitions from map32.h, which was: | 8 | * P1/P2 Section mapping definitions from map32.h, which was: |
9 | * | 9 | * |
@@ -68,6 +68,32 @@ static inline unsigned long mk_pmb_data(unsigned int entry) | |||
68 | return mk_pmb_entry(entry) | PMB_DATA; | 68 | return mk_pmb_entry(entry) | PMB_DATA; |
69 | } | 69 | } |
70 | 70 | ||
71 | static DEFINE_SPINLOCK(pmb_list_lock); | ||
72 | static struct pmb_entry *pmb_list; | ||
73 | |||
74 | static inline void pmb_list_add(struct pmb_entry *pmbe) | ||
75 | { | ||
76 | struct pmb_entry **p, *tmp; | ||
77 | |||
78 | p = &pmb_list; | ||
79 | while ((tmp = *p) != NULL) | ||
80 | p = &tmp->next; | ||
81 | |||
82 | pmbe->next = tmp; | ||
83 | *p = pmbe; | ||
84 | } | ||
85 | |||
86 | static inline void pmb_list_del(struct pmb_entry *pmbe) | ||
87 | { | ||
88 | struct pmb_entry **p, *tmp; | ||
89 | |||
90 | for (p = &pmb_list; (tmp = *p); p = &tmp->next) | ||
91 | if (tmp == pmbe) { | ||
92 | *p = tmp->next; | ||
93 | return; | ||
94 | } | ||
95 | } | ||
96 | |||
71 | struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn, | 97 | struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn, |
72 | unsigned long flags) | 98 | unsigned long flags) |
73 | { | 99 | { |
@@ -81,11 +107,19 @@ struct pmb_entry *pmb_alloc(unsigned long vpn, unsigned long ppn, | |||
81 | pmbe->ppn = ppn; | 107 | pmbe->ppn = ppn; |
82 | pmbe->flags = flags; | 108 | pmbe->flags = flags; |
83 | 109 | ||
110 | spin_lock_irq(&pmb_list_lock); | ||
111 | pmb_list_add(pmbe); | ||
112 | spin_unlock_irq(&pmb_list_lock); | ||
113 | |||
84 | return pmbe; | 114 | return pmbe; |
85 | } | 115 | } |
86 | 116 | ||
87 | void pmb_free(struct pmb_entry *pmbe) | 117 | void pmb_free(struct pmb_entry *pmbe) |
88 | { | 118 | { |
119 | spin_lock_irq(&pmb_list_lock); | ||
120 | pmb_list_del(pmbe); | ||
121 | spin_unlock_irq(&pmb_list_lock); | ||
122 | |||
89 | kmem_cache_free(pmb_cache, pmbe); | 123 | kmem_cache_free(pmb_cache, pmbe); |
90 | } | 124 | } |
91 | 125 | ||
@@ -167,31 +201,6 @@ void clear_pmb_entry(struct pmb_entry *pmbe) | |||
167 | clear_bit(entry, &pmb_map); | 201 | clear_bit(entry, &pmb_map); |
168 | } | 202 | } |
169 | 203 | ||
170 | static DEFINE_SPINLOCK(pmb_list_lock); | ||
171 | static struct pmb_entry *pmb_list; | ||
172 | |||
173 | static inline void pmb_list_add(struct pmb_entry *pmbe) | ||
174 | { | ||
175 | struct pmb_entry **p, *tmp; | ||
176 | |||
177 | p = &pmb_list; | ||
178 | while ((tmp = *p) != NULL) | ||
179 | p = &tmp->next; | ||
180 | |||
181 | pmbe->next = tmp; | ||
182 | *p = pmbe; | ||
183 | } | ||
184 | |||
185 | static inline void pmb_list_del(struct pmb_entry *pmbe) | ||
186 | { | ||
187 | struct pmb_entry **p, *tmp; | ||
188 | |||
189 | for (p = &pmb_list; (tmp = *p); p = &tmp->next) | ||
190 | if (tmp == pmbe) { | ||
191 | *p = tmp->next; | ||
192 | return; | ||
193 | } | ||
194 | } | ||
195 | 204 | ||
196 | static struct { | 205 | static struct { |
197 | unsigned long size; | 206 | unsigned long size; |
@@ -283,25 +292,14 @@ void pmb_unmap(unsigned long addr) | |||
283 | } while (pmbe); | 292 | } while (pmbe); |
284 | } | 293 | } |
285 | 294 | ||
286 | static void pmb_cache_ctor(void *pmb, struct kmem_cache *cachep, unsigned long flags) | 295 | static void pmb_cache_ctor(void *pmb, struct kmem_cache *cachep, |
296 | unsigned long flags) | ||
287 | { | 297 | { |
288 | struct pmb_entry *pmbe = pmb; | 298 | struct pmb_entry *pmbe = pmb; |
289 | 299 | ||
290 | memset(pmb, 0, sizeof(struct pmb_entry)); | 300 | memset(pmb, 0, sizeof(struct pmb_entry)); |
291 | 301 | ||
292 | spin_lock_irq(&pmb_list_lock); | ||
293 | |||
294 | pmbe->entry = PMB_NO_ENTRY; | 302 | pmbe->entry = PMB_NO_ENTRY; |
295 | pmb_list_add(pmbe); | ||
296 | |||
297 | spin_unlock_irq(&pmb_list_lock); | ||
298 | } | ||
299 | |||
300 | static void pmb_cache_dtor(void *pmb, struct kmem_cache *cachep, unsigned long flags) | ||
301 | { | ||
302 | spin_lock_irq(&pmb_list_lock); | ||
303 | pmb_list_del(pmb); | ||
304 | spin_unlock_irq(&pmb_list_lock); | ||
305 | } | 303 | } |
306 | 304 | ||
307 | static int __init pmb_init(void) | 305 | static int __init pmb_init(void) |
@@ -312,8 +310,7 @@ static int __init pmb_init(void) | |||
312 | BUG_ON(unlikely(nr_entries >= NR_PMB_ENTRIES)); | 310 | BUG_ON(unlikely(nr_entries >= NR_PMB_ENTRIES)); |
313 | 311 | ||
314 | pmb_cache = kmem_cache_create("pmb", sizeof(struct pmb_entry), 0, | 312 | pmb_cache = kmem_cache_create("pmb", sizeof(struct pmb_entry), 0, |
315 | SLAB_PANIC, pmb_cache_ctor, | 313 | SLAB_PANIC, pmb_cache_ctor, NULL); |
316 | pmb_cache_dtor); | ||
317 | 314 | ||
318 | jump_to_P2(); | 315 | jump_to_P2(); |
319 | 316 | ||
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types index 554f801db67b..fb40f188aff9 100644 --- a/arch/sh/tools/mach-types +++ b/arch/sh/tools/mach-types | |||
@@ -7,8 +7,11 @@ | |||
7 | # | 7 | # |
8 | SE SH_SOLUTION_ENGINE | 8 | SE SH_SOLUTION_ENGINE |
9 | 7751SE SH_7751_SOLUTION_ENGINE | 9 | 7751SE SH_7751_SOLUTION_ENGINE |
10 | 7722SE SH_7722_SOLUTION_ENGINE | ||
10 | 7300SE SH_7300_SOLUTION_ENGINE | 11 | 7300SE SH_7300_SOLUTION_ENGINE |
11 | 7343SE SH_7343_SOLUTION_ENGINE | 12 | 7343SE SH_7343_SOLUTION_ENGINE |
13 | 7206SE SH_7206_SOLUTION_ENGINE | ||
14 | 7619SE SH_7619_SOLUTION_ENGINE | ||
12 | 7780SE SH_7780_SOLUTION_ENGINE | 15 | 7780SE SH_7780_SOLUTION_ENGINE |
13 | 73180SE SH_73180_SOLUTION_ENGINE | 16 | 73180SE SH_73180_SOLUTION_ENGINE |
14 | 7751SYSTEMH SH_7751_SYSTEMH | 17 | 7751SYSTEMH SH_7751_SYSTEMH |
@@ -31,5 +34,3 @@ R7785RP SH_R7785RP | |||
31 | TITAN SH_TITAN | 34 | TITAN SH_TITAN |
32 | SHMIN SH_SHMIN | 35 | SHMIN SH_SHMIN |
33 | 7710VOIPGW SH_7710VOIPGW | 36 | 7710VOIPGW SH_7710VOIPGW |
34 | 7206SE SH_7206_SOLUTION_ENGINE | ||
35 | 7619SE SH_7619_SOLUTION_ENGINE | ||
diff --git a/arch/sh64/kernel/pci_sh5.c b/arch/sh64/kernel/pci_sh5.c index fb51660847c8..3334f99b5835 100644 --- a/arch/sh64/kernel/pci_sh5.c +++ b/arch/sh64/kernel/pci_sh5.c | |||
@@ -521,10 +521,10 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) | |||
521 | bus->resource[0]->start = PCIBIOS_MIN_IO; | 521 | bus->resource[0]->start = PCIBIOS_MIN_IO; |
522 | bus->resource[1]->start = PCIBIOS_MIN_MEM; | 522 | bus->resource[1]->start = PCIBIOS_MIN_MEM; |
523 | #else | 523 | #else |
524 | bus->resource[0]->end = 0 | 524 | bus->resource[0]->end = 0; |
525 | bus->resource[1]->end = 0 | 525 | bus->resource[1]->end = 0; |
526 | bus->resource[0]->start =0 | 526 | bus->resource[0]->start =0; |
527 | bus->resource[1]->start = 0; | 527 | bus->resource[1]->start = 0; |
528 | #endif | 528 | #endif |
529 | /* Turn off downstream PF memory address range by default */ | 529 | /* Turn off downstream PF memory address range by default */ |
530 | bus->resource[2]->start = 1024*1024; | 530 | bus->resource[2]->start = 1024*1024; |
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index bd992c0048f0..fbcc00c6c06e 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
@@ -178,6 +178,13 @@ config ARCH_HAS_ILOG2_U64 | |||
178 | bool | 178 | bool |
179 | default n | 179 | default n |
180 | 180 | ||
181 | config EMULATED_CMPXCHG | ||
182 | bool | ||
183 | default y | ||
184 | help | ||
185 | Sparc32 does not have a CAS instruction like sparc64. cmpxchg() | ||
186 | is emulated, and therefore it is not completely atomic. | ||
187 | |||
181 | config SUN_PM | 188 | config SUN_PM |
182 | bool | 189 | bool |
183 | default y | 190 | default y |
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c index f1401b57ccc7..7b4612da74a6 100644 --- a/arch/sparc/kernel/time.c +++ b/arch/sparc/kernel/time.c | |||
@@ -148,7 +148,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id) | |||
148 | } | 148 | } |
149 | 149 | ||
150 | /* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */ | 150 | /* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */ |
151 | static void __init kick_start_clock(void) | 151 | static void __devinit kick_start_clock(void) |
152 | { | 152 | { |
153 | struct mostek48t02 *regs = (struct mostek48t02 *)mstk48t02_regs; | 153 | struct mostek48t02 *regs = (struct mostek48t02 *)mstk48t02_regs; |
154 | unsigned char sec; | 154 | unsigned char sec; |
@@ -223,7 +223,7 @@ static __inline__ int has_low_battery(void) | |||
223 | return (data1 == data2); /* Was the write blocked? */ | 223 | return (data1 == data2); /* Was the write blocked? */ |
224 | } | 224 | } |
225 | 225 | ||
226 | static void __init mostek_set_system_time(void) | 226 | static void __devinit mostek_set_system_time(void) |
227 | { | 227 | { |
228 | unsigned int year, mon, day, hour, min, sec; | 228 | unsigned int year, mon, day, hour, min, sec; |
229 | struct mostek48t02 *mregs; | 229 | struct mostek48t02 *mregs; |
diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c index 559335f4917d..cbddeb38ffda 100644 --- a/arch/sparc/lib/atomic32.c +++ b/arch/sparc/lib/atomic32.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * atomic32.c: 32-bit atomic_t implementation | 2 | * atomic32.c: 32-bit atomic_t implementation |
3 | * | 3 | * |
4 | * Copyright (C) 2004 Keith M Wesolowski | 4 | * Copyright (C) 2004 Keith M Wesolowski |
5 | * Copyright (C) 2007 Kyle McMartin | ||
5 | * | 6 | * |
6 | * Based on asm-parisc/atomic.h Copyright (C) 2000 Philipp Rumpf | 7 | * Based on asm-parisc/atomic.h Copyright (C) 2000 Philipp Rumpf |
7 | */ | 8 | */ |
@@ -117,3 +118,17 @@ unsigned long ___change_bit(unsigned long *addr, unsigned long mask) | |||
117 | return old & mask; | 118 | return old & mask; |
118 | } | 119 | } |
119 | EXPORT_SYMBOL(___change_bit); | 120 | EXPORT_SYMBOL(___change_bit); |
121 | |||
122 | unsigned long __cmpxchg_u32(volatile u32 *ptr, u32 old, u32 new) | ||
123 | { | ||
124 | unsigned long flags; | ||
125 | u32 prev; | ||
126 | |||
127 | spin_lock_irqsave(ATOMIC_HASH(ptr), flags); | ||
128 | if ((prev = *ptr) == old) | ||
129 | *ptr = new; | ||
130 | spin_unlock_irqrestore(ATOMIC_HASH(ptr), flags); | ||
131 | |||
132 | return (unsigned long)prev; | ||
133 | } | ||
134 | EXPORT_SYMBOL(__cmpxchg_u32); | ||
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index 831781cab271..89a1b469b93d 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig | |||
@@ -147,10 +147,10 @@ config SMP | |||
147 | If you don't know what to do here, say N. | 147 | If you don't know what to do here, say N. |
148 | 148 | ||
149 | config NR_CPUS | 149 | config NR_CPUS |
150 | int "Maximum number of CPUs (2-64)" | 150 | int "Maximum number of CPUs (2-1024)" |
151 | range 2 64 | 151 | range 2 1024 |
152 | depends on SMP | 152 | depends on SMP |
153 | default "32" | 153 | default "64" |
154 | 154 | ||
155 | source "drivers/cpufreq/Kconfig" | 155 | source "drivers/cpufreq/Kconfig" |
156 | 156 | ||
@@ -396,6 +396,15 @@ config SCHED_SMT | |||
396 | when dealing with UltraSPARC cpus at a cost of slightly increased | 396 | when dealing with UltraSPARC cpus at a cost of slightly increased |
397 | overhead in some places. If unsure say N here. | 397 | overhead in some places. If unsure say N here. |
398 | 398 | ||
399 | config SCHED_MC | ||
400 | bool "Multi-core scheduler support" | ||
401 | depends on SMP | ||
402 | default y | ||
403 | help | ||
404 | Multi-core scheduler support improves the CPU scheduler's decision | ||
405 | making when dealing with multi-core CPU chips at a cost of slightly | ||
406 | increased overhead in some places. If unsure say N here. | ||
407 | |||
399 | source "kernel/Kconfig.preempt" | 408 | source "kernel/Kconfig.preempt" |
400 | 409 | ||
401 | config CMDLINE_BOOL | 410 | config CMDLINE_BOOL |
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index c749dccacc32..f964bf28d21a 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | # $Id: Makefile,v 1.70 2002/02/09 19:49:30 davem Exp $ | 1 | # |
2 | # Makefile for the linux kernel. | 2 | # Makefile for the linux kernel. |
3 | # | 3 | # |
4 | 4 | ||
@@ -8,11 +8,11 @@ EXTRA_CFLAGS := -Werror | |||
8 | extra-y := head.o init_task.o vmlinux.lds | 8 | extra-y := head.o init_task.o vmlinux.lds |
9 | 9 | ||
10 | obj-y := process.o setup.o cpu.o idprom.o \ | 10 | obj-y := process.o setup.o cpu.o idprom.o \ |
11 | traps.o devices.o auxio.o una_asm.o \ | 11 | traps.o auxio.o una_asm.o sysfs.o \ |
12 | irq.o ptrace.o time.o sys_sparc.o signal.o \ | 12 | irq.o ptrace.o time.o sys_sparc.o signal.o \ |
13 | unaligned.o central.o pci.o starfire.o semaphore.o \ | 13 | unaligned.o central.o pci.o starfire.o semaphore.o \ |
14 | power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \ | 14 | power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \ |
15 | visemul.o prom.o of_device.o hvapi.o | 15 | visemul.o prom.o of_device.o hvapi.o sstate.o mdesc.o |
16 | 16 | ||
17 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | 17 | obj-$(CONFIG_STACKTRACE) += stacktrace.o |
18 | obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ | 18 | obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ |
diff --git a/arch/sparc64/kernel/devices.c b/arch/sparc64/kernel/devices.c deleted file mode 100644 index 0e03c8e218cd..000000000000 --- a/arch/sparc64/kernel/devices.c +++ /dev/null | |||
@@ -1,196 +0,0 @@ | |||
1 | /* devices.c: Initial scan of the prom device tree for important | ||
2 | * Sparc device nodes which we need to find. | ||
3 | * | ||
4 | * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) | ||
5 | */ | ||
6 | |||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/threads.h> | ||
9 | #include <linux/init.h> | ||
10 | #include <linux/ioport.h> | ||
11 | #include <linux/string.h> | ||
12 | #include <linux/spinlock.h> | ||
13 | #include <linux/errno.h> | ||
14 | #include <linux/bootmem.h> | ||
15 | |||
16 | #include <asm/page.h> | ||
17 | #include <asm/oplib.h> | ||
18 | #include <asm/system.h> | ||
19 | #include <asm/smp.h> | ||
20 | #include <asm/spitfire.h> | ||
21 | #include <asm/timer.h> | ||
22 | #include <asm/cpudata.h> | ||
23 | |||
24 | /* Used to synchronize accesses to NatSemi SUPER I/O chip configure | ||
25 | * operations in asm/ns87303.h | ||
26 | */ | ||
27 | DEFINE_SPINLOCK(ns87303_lock); | ||
28 | |||
29 | extern void cpu_probe(void); | ||
30 | extern void central_probe(void); | ||
31 | |||
32 | static const char *cpu_mid_prop(void) | ||
33 | { | ||
34 | if (tlb_type == spitfire) | ||
35 | return "upa-portid"; | ||
36 | return "portid"; | ||
37 | } | ||
38 | |||
39 | static int get_cpu_mid(struct device_node *dp) | ||
40 | { | ||
41 | struct property *prop; | ||
42 | |||
43 | if (tlb_type == hypervisor) { | ||
44 | struct linux_prom64_registers *reg; | ||
45 | int len; | ||
46 | |||
47 | prop = of_find_property(dp, "cpuid", &len); | ||
48 | if (prop && len == 4) | ||
49 | return *(int *) prop->value; | ||
50 | |||
51 | prop = of_find_property(dp, "reg", NULL); | ||
52 | reg = prop->value; | ||
53 | return (reg[0].phys_addr >> 32) & 0x0fffffffUL; | ||
54 | } else { | ||
55 | const char *prop_name = cpu_mid_prop(); | ||
56 | |||
57 | prop = of_find_property(dp, prop_name, NULL); | ||
58 | if (prop) | ||
59 | return *(int *) prop->value; | ||
60 | return 0; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | static int check_cpu_node(struct device_node *dp, int *cur_inst, | ||
65 | int (*compare)(struct device_node *, int, void *), | ||
66 | void *compare_arg, | ||
67 | struct device_node **dev_node, int *mid) | ||
68 | { | ||
69 | if (!compare(dp, *cur_inst, compare_arg)) { | ||
70 | if (dev_node) | ||
71 | *dev_node = dp; | ||
72 | if (mid) | ||
73 | *mid = get_cpu_mid(dp); | ||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | (*cur_inst)++; | ||
78 | |||
79 | return -ENODEV; | ||
80 | } | ||
81 | |||
82 | static int __cpu_find_by(int (*compare)(struct device_node *, int, void *), | ||
83 | void *compare_arg, | ||
84 | struct device_node **dev_node, int *mid) | ||
85 | { | ||
86 | struct device_node *dp; | ||
87 | int cur_inst; | ||
88 | |||
89 | cur_inst = 0; | ||
90 | for_each_node_by_type(dp, "cpu") { | ||
91 | int err = check_cpu_node(dp, &cur_inst, | ||
92 | compare, compare_arg, | ||
93 | dev_node, mid); | ||
94 | if (err == 0) | ||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | return -ENODEV; | ||
99 | } | ||
100 | |||
101 | static int cpu_instance_compare(struct device_node *dp, int instance, void *_arg) | ||
102 | { | ||
103 | int desired_instance = (int) (long) _arg; | ||
104 | |||
105 | if (instance == desired_instance) | ||
106 | return 0; | ||
107 | return -ENODEV; | ||
108 | } | ||
109 | |||
110 | int cpu_find_by_instance(int instance, struct device_node **dev_node, int *mid) | ||
111 | { | ||
112 | return __cpu_find_by(cpu_instance_compare, (void *)(long)instance, | ||
113 | dev_node, mid); | ||
114 | } | ||
115 | |||
116 | static int cpu_mid_compare(struct device_node *dp, int instance, void *_arg) | ||
117 | { | ||
118 | int desired_mid = (int) (long) _arg; | ||
119 | int this_mid; | ||
120 | |||
121 | this_mid = get_cpu_mid(dp); | ||
122 | if (this_mid == desired_mid) | ||
123 | return 0; | ||
124 | return -ENODEV; | ||
125 | } | ||
126 | |||
127 | int cpu_find_by_mid(int mid, struct device_node **dev_node) | ||
128 | { | ||
129 | return __cpu_find_by(cpu_mid_compare, (void *)(long)mid, | ||
130 | dev_node, NULL); | ||
131 | } | ||
132 | |||
133 | void __init device_scan(void) | ||
134 | { | ||
135 | /* FIX ME FAST... -DaveM */ | ||
136 | ioport_resource.end = 0xffffffffffffffffUL; | ||
137 | |||
138 | prom_printf("Booting Linux...\n"); | ||
139 | |||
140 | #ifndef CONFIG_SMP | ||
141 | { | ||
142 | struct device_node *dp; | ||
143 | int err, def; | ||
144 | |||
145 | err = cpu_find_by_instance(0, &dp, NULL); | ||
146 | if (err) { | ||
147 | prom_printf("No cpu nodes, cannot continue\n"); | ||
148 | prom_halt(); | ||
149 | } | ||
150 | cpu_data(0).clock_tick = | ||
151 | of_getintprop_default(dp, "clock-frequency", 0); | ||
152 | |||
153 | def = ((tlb_type == hypervisor) ? | ||
154 | (8 * 1024) : | ||
155 | (16 * 1024)); | ||
156 | cpu_data(0).dcache_size = of_getintprop_default(dp, | ||
157 | "dcache-size", | ||
158 | def); | ||
159 | |||
160 | def = 32; | ||
161 | cpu_data(0).dcache_line_size = | ||
162 | of_getintprop_default(dp, "dcache-line-size", def); | ||
163 | |||
164 | def = 16 * 1024; | ||
165 | cpu_data(0).icache_size = of_getintprop_default(dp, | ||
166 | "icache-size", | ||
167 | def); | ||
168 | |||
169 | def = 32; | ||
170 | cpu_data(0).icache_line_size = | ||
171 | of_getintprop_default(dp, "icache-line-size", def); | ||
172 | |||
173 | def = ((tlb_type == hypervisor) ? | ||
174 | (3 * 1024 * 1024) : | ||
175 | (4 * 1024 * 1024)); | ||
176 | cpu_data(0).ecache_size = of_getintprop_default(dp, | ||
177 | "ecache-size", | ||
178 | def); | ||
179 | |||
180 | def = 64; | ||
181 | cpu_data(0).ecache_line_size = | ||
182 | of_getintprop_default(dp, "ecache-line-size", def); | ||
183 | printk("CPU[0]: Caches " | ||
184 | "D[sz(%d):line_sz(%d)] " | ||
185 | "I[sz(%d):line_sz(%d)] " | ||
186 | "E[sz(%d):line_sz(%d)]\n", | ||
187 | cpu_data(0).dcache_size, cpu_data(0).dcache_line_size, | ||
188 | cpu_data(0).icache_size, cpu_data(0).icache_line_size, | ||
189 | cpu_data(0).ecache_size, cpu_data(0).ecache_line_size); | ||
190 | } | ||
191 | #endif | ||
192 | |||
193 | central_probe(); | ||
194 | |||
195 | cpu_probe(); | ||
196 | } | ||
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index 732b77cb71f8..8059531bf0ac 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S | |||
@@ -1725,96 +1725,142 @@ real_hard_smp_processor_id: | |||
1725 | * returns %o0: sysino | 1725 | * returns %o0: sysino |
1726 | */ | 1726 | */ |
1727 | .globl sun4v_devino_to_sysino | 1727 | .globl sun4v_devino_to_sysino |
1728 | .type sun4v_devino_to_sysino,#function | ||
1728 | sun4v_devino_to_sysino: | 1729 | sun4v_devino_to_sysino: |
1729 | mov HV_FAST_INTR_DEVINO2SYSINO, %o5 | 1730 | mov HV_FAST_INTR_DEVINO2SYSINO, %o5 |
1730 | ta HV_FAST_TRAP | 1731 | ta HV_FAST_TRAP |
1731 | retl | 1732 | retl |
1732 | mov %o1, %o0 | 1733 | mov %o1, %o0 |
1734 | .size sun4v_devino_to_sysino, .-sun4v_devino_to_sysino | ||
1733 | 1735 | ||
1734 | /* %o0: sysino | 1736 | /* %o0: sysino |
1735 | * | 1737 | * |
1736 | * returns %o0: intr_enabled (HV_INTR_{DISABLED,ENABLED}) | 1738 | * returns %o0: intr_enabled (HV_INTR_{DISABLED,ENABLED}) |
1737 | */ | 1739 | */ |
1738 | .globl sun4v_intr_getenabled | 1740 | .globl sun4v_intr_getenabled |
1741 | .type sun4v_intr_getenabled,#function | ||
1739 | sun4v_intr_getenabled: | 1742 | sun4v_intr_getenabled: |
1740 | mov HV_FAST_INTR_GETENABLED, %o5 | 1743 | mov HV_FAST_INTR_GETENABLED, %o5 |
1741 | ta HV_FAST_TRAP | 1744 | ta HV_FAST_TRAP |
1742 | retl | 1745 | retl |
1743 | mov %o1, %o0 | 1746 | mov %o1, %o0 |
1747 | .size sun4v_intr_getenabled, .-sun4v_intr_getenabled | ||
1744 | 1748 | ||
1745 | /* %o0: sysino | 1749 | /* %o0: sysino |
1746 | * %o1: intr_enabled (HV_INTR_{DISABLED,ENABLED}) | 1750 | * %o1: intr_enabled (HV_INTR_{DISABLED,ENABLED}) |
1747 | */ | 1751 | */ |
1748 | .globl sun4v_intr_setenabled | 1752 | .globl sun4v_intr_setenabled |
1753 | .type sun4v_intr_setenabled,#function | ||
1749 | sun4v_intr_setenabled: | 1754 | sun4v_intr_setenabled: |
1750 | mov HV_FAST_INTR_SETENABLED, %o5 | 1755 | mov HV_FAST_INTR_SETENABLED, %o5 |
1751 | ta HV_FAST_TRAP | 1756 | ta HV_FAST_TRAP |
1752 | retl | 1757 | retl |
1753 | nop | 1758 | nop |
1759 | .size sun4v_intr_setenabled, .-sun4v_intr_setenabled | ||
1754 | 1760 | ||
1755 | /* %o0: sysino | 1761 | /* %o0: sysino |
1756 | * | 1762 | * |
1757 | * returns %o0: intr_state (HV_INTR_STATE_*) | 1763 | * returns %o0: intr_state (HV_INTR_STATE_*) |
1758 | */ | 1764 | */ |
1759 | .globl sun4v_intr_getstate | 1765 | .globl sun4v_intr_getstate |
1766 | .type sun4v_intr_getstate,#function | ||
1760 | sun4v_intr_getstate: | 1767 | sun4v_intr_getstate: |
1761 | mov HV_FAST_INTR_GETSTATE, %o5 | 1768 | mov HV_FAST_INTR_GETSTATE, %o5 |
1762 | ta HV_FAST_TRAP | 1769 | ta HV_FAST_TRAP |
1763 | retl | 1770 | retl |
1764 | mov %o1, %o0 | 1771 | mov %o1, %o0 |
1772 | .size sun4v_intr_getstate, .-sun4v_intr_getstate | ||
1765 | 1773 | ||
1766 | /* %o0: sysino | 1774 | /* %o0: sysino |
1767 | * %o1: intr_state (HV_INTR_STATE_*) | 1775 | * %o1: intr_state (HV_INTR_STATE_*) |
1768 | */ | 1776 | */ |
1769 | .globl sun4v_intr_setstate | 1777 | .globl sun4v_intr_setstate |
1778 | .type sun4v_intr_setstate,#function | ||
1770 | sun4v_intr_setstate: | 1779 | sun4v_intr_setstate: |
1771 | mov HV_FAST_INTR_SETSTATE, %o5 | 1780 | mov HV_FAST_INTR_SETSTATE, %o5 |
1772 | ta HV_FAST_TRAP | 1781 | ta HV_FAST_TRAP |
1773 | retl | 1782 | retl |
1774 | nop | 1783 | nop |
1784 | .size sun4v_intr_setstate, .-sun4v_intr_setstate | ||
1775 | 1785 | ||
1776 | /* %o0: sysino | 1786 | /* %o0: sysino |
1777 | * | 1787 | * |
1778 | * returns %o0: cpuid | 1788 | * returns %o0: cpuid |
1779 | */ | 1789 | */ |
1780 | .globl sun4v_intr_gettarget | 1790 | .globl sun4v_intr_gettarget |
1791 | .type sun4v_intr_gettarget,#function | ||
1781 | sun4v_intr_gettarget: | 1792 | sun4v_intr_gettarget: |
1782 | mov HV_FAST_INTR_GETTARGET, %o5 | 1793 | mov HV_FAST_INTR_GETTARGET, %o5 |
1783 | ta HV_FAST_TRAP | 1794 | ta HV_FAST_TRAP |
1784 | retl | 1795 | retl |
1785 | mov %o1, %o0 | 1796 | mov %o1, %o0 |
1797 | .size sun4v_intr_gettarget, .-sun4v_intr_gettarget | ||
1786 | 1798 | ||
1787 | /* %o0: sysino | 1799 | /* %o0: sysino |
1788 | * %o1: cpuid | 1800 | * %o1: cpuid |
1789 | */ | 1801 | */ |
1790 | .globl sun4v_intr_settarget | 1802 | .globl sun4v_intr_settarget |
1803 | .type sun4v_intr_settarget,#function | ||
1791 | sun4v_intr_settarget: | 1804 | sun4v_intr_settarget: |
1792 | mov HV_FAST_INTR_SETTARGET, %o5 | 1805 | mov HV_FAST_INTR_SETTARGET, %o5 |
1793 | ta HV_FAST_TRAP | 1806 | ta HV_FAST_TRAP |
1794 | retl | 1807 | retl |
1795 | nop | 1808 | nop |
1809 | .size sun4v_intr_settarget, .-sun4v_intr_settarget | ||
1796 | 1810 | ||
1797 | /* %o0: type | 1811 | /* %o0: cpuid |
1798 | * %o1: queue paddr | 1812 | * %o1: pc |
1799 | * %o2: num queue entries | 1813 | * %o2: rtba |
1814 | * %o3: arg0 | ||
1800 | * | 1815 | * |
1801 | * returns %o0: status | 1816 | * returns %o0: status |
1802 | */ | 1817 | */ |
1803 | .globl sun4v_cpu_qconf | 1818 | .globl sun4v_cpu_start |
1804 | sun4v_cpu_qconf: | 1819 | .type sun4v_cpu_start,#function |
1805 | mov HV_FAST_CPU_QCONF, %o5 | 1820 | sun4v_cpu_start: |
1821 | mov HV_FAST_CPU_START, %o5 | ||
1806 | ta HV_FAST_TRAP | 1822 | ta HV_FAST_TRAP |
1807 | retl | 1823 | retl |
1808 | nop | 1824 | nop |
1825 | .size sun4v_cpu_start, .-sun4v_cpu_start | ||
1809 | 1826 | ||
1810 | /* returns %o0: status | 1827 | /* %o0: cpuid |
1828 | * | ||
1829 | * returns %o0: status | ||
1811 | */ | 1830 | */ |
1831 | .globl sun4v_cpu_stop | ||
1832 | .type sun4v_cpu_stop,#function | ||
1833 | sun4v_cpu_stop: | ||
1834 | mov HV_FAST_CPU_STOP, %o5 | ||
1835 | ta HV_FAST_TRAP | ||
1836 | retl | ||
1837 | nop | ||
1838 | .size sun4v_cpu_stop, .-sun4v_cpu_stop | ||
1839 | |||
1840 | /* returns %o0: status */ | ||
1812 | .globl sun4v_cpu_yield | 1841 | .globl sun4v_cpu_yield |
1842 | .type sun4v_cpu_yield, #function | ||
1813 | sun4v_cpu_yield: | 1843 | sun4v_cpu_yield: |
1814 | mov HV_FAST_CPU_YIELD, %o5 | 1844 | mov HV_FAST_CPU_YIELD, %o5 |
1815 | ta HV_FAST_TRAP | 1845 | ta HV_FAST_TRAP |
1816 | retl | 1846 | retl |
1817 | nop | 1847 | nop |
1848 | .size sun4v_cpu_yield, .-sun4v_cpu_yield | ||
1849 | |||
1850 | /* %o0: type | ||
1851 | * %o1: queue paddr | ||
1852 | * %o2: num queue entries | ||
1853 | * | ||
1854 | * returns %o0: status | ||
1855 | */ | ||
1856 | .globl sun4v_cpu_qconf | ||
1857 | .type sun4v_cpu_qconf,#function | ||
1858 | sun4v_cpu_qconf: | ||
1859 | mov HV_FAST_CPU_QCONF, %o5 | ||
1860 | ta HV_FAST_TRAP | ||
1861 | retl | ||
1862 | nop | ||
1863 | .size sun4v_cpu_qconf, .-sun4v_cpu_qconf | ||
1818 | 1864 | ||
1819 | /* %o0: num cpus in cpu list | 1865 | /* %o0: num cpus in cpu list |
1820 | * %o1: cpu list paddr | 1866 | * %o1: cpu list paddr |
@@ -1823,11 +1869,13 @@ sun4v_cpu_yield: | |||
1823 | * returns %o0: status | 1869 | * returns %o0: status |
1824 | */ | 1870 | */ |
1825 | .globl sun4v_cpu_mondo_send | 1871 | .globl sun4v_cpu_mondo_send |
1872 | .type sun4v_cpu_mondo_send,#function | ||
1826 | sun4v_cpu_mondo_send: | 1873 | sun4v_cpu_mondo_send: |
1827 | mov HV_FAST_CPU_MONDO_SEND, %o5 | 1874 | mov HV_FAST_CPU_MONDO_SEND, %o5 |
1828 | ta HV_FAST_TRAP | 1875 | ta HV_FAST_TRAP |
1829 | retl | 1876 | retl |
1830 | nop | 1877 | nop |
1878 | .size sun4v_cpu_mondo_send, .-sun4v_cpu_mondo_send | ||
1831 | 1879 | ||
1832 | /* %o0: CPU ID | 1880 | /* %o0: CPU ID |
1833 | * | 1881 | * |
@@ -1835,6 +1883,7 @@ sun4v_cpu_mondo_send: | |||
1835 | * %o0: cpu state as HV_CPU_STATE_* | 1883 | * %o0: cpu state as HV_CPU_STATE_* |
1836 | */ | 1884 | */ |
1837 | .globl sun4v_cpu_state | 1885 | .globl sun4v_cpu_state |
1886 | .type sun4v_cpu_state,#function | ||
1838 | sun4v_cpu_state: | 1887 | sun4v_cpu_state: |
1839 | mov HV_FAST_CPU_STATE, %o5 | 1888 | mov HV_FAST_CPU_STATE, %o5 |
1840 | ta HV_FAST_TRAP | 1889 | ta HV_FAST_TRAP |
@@ -1843,6 +1892,37 @@ sun4v_cpu_state: | |||
1843 | mov %o1, %o0 | 1892 | mov %o1, %o0 |
1844 | 1: retl | 1893 | 1: retl |
1845 | nop | 1894 | nop |
1895 | .size sun4v_cpu_state, .-sun4v_cpu_state | ||
1896 | |||
1897 | /* %o0: virtual address | ||
1898 | * %o1: must be zero | ||
1899 | * %o2: TTE | ||
1900 | * %o3: HV_MMU_* flags | ||
1901 | * | ||
1902 | * returns %o0: status | ||
1903 | */ | ||
1904 | .globl sun4v_mmu_map_perm_addr | ||
1905 | .type sun4v_mmu_map_perm_addr,#function | ||
1906 | sun4v_mmu_map_perm_addr: | ||
1907 | mov HV_FAST_MMU_MAP_PERM_ADDR, %o5 | ||
1908 | ta HV_FAST_TRAP | ||
1909 | retl | ||
1910 | nop | ||
1911 | .size sun4v_mmu_map_perm_addr, .-sun4v_mmu_map_perm_addr | ||
1912 | |||
1913 | /* %o0: number of TSB descriptions | ||
1914 | * %o1: TSB descriptions real address | ||
1915 | * | ||
1916 | * returns %o0: status | ||
1917 | */ | ||
1918 | .globl sun4v_mmu_tsb_ctx0 | ||
1919 | .type sun4v_mmu_tsb_ctx0,#function | ||
1920 | sun4v_mmu_tsb_ctx0: | ||
1921 | mov HV_FAST_MMU_TSB_CTX0, %o5 | ||
1922 | ta HV_FAST_TRAP | ||
1923 | retl | ||
1924 | nop | ||
1925 | .size sun4v_mmu_tsb_ctx0, .-sun4v_mmu_tsb_ctx0 | ||
1846 | 1926 | ||
1847 | /* %o0: API group number | 1927 | /* %o0: API group number |
1848 | * %o1: pointer to unsigned long major number storage | 1928 | * %o1: pointer to unsigned long major number storage |
@@ -1851,6 +1931,7 @@ sun4v_cpu_state: | |||
1851 | * returns %o0: status | 1931 | * returns %o0: status |
1852 | */ | 1932 | */ |
1853 | .globl sun4v_get_version | 1933 | .globl sun4v_get_version |
1934 | .type sun4v_get_version,#function | ||
1854 | sun4v_get_version: | 1935 | sun4v_get_version: |
1855 | mov HV_CORE_GET_VER, %o5 | 1936 | mov HV_CORE_GET_VER, %o5 |
1856 | mov %o1, %o3 | 1937 | mov %o1, %o3 |
@@ -1859,6 +1940,7 @@ sun4v_get_version: | |||
1859 | stx %o1, [%o3] | 1940 | stx %o1, [%o3] |
1860 | retl | 1941 | retl |
1861 | stx %o2, [%o4] | 1942 | stx %o2, [%o4] |
1943 | .size sun4v_get_version, .-sun4v_get_version | ||
1862 | 1944 | ||
1863 | /* %o0: API group number | 1945 | /* %o0: API group number |
1864 | * %o1: desired major number | 1946 | * %o1: desired major number |
@@ -1868,18 +1950,49 @@ sun4v_get_version: | |||
1868 | * returns %o0: status | 1950 | * returns %o0: status |
1869 | */ | 1951 | */ |
1870 | .globl sun4v_set_version | 1952 | .globl sun4v_set_version |
1953 | .type sun4v_set_version,#function | ||
1871 | sun4v_set_version: | 1954 | sun4v_set_version: |
1872 | mov HV_CORE_SET_VER, %o5 | 1955 | mov HV_CORE_SET_VER, %o5 |
1873 | mov %o3, %o4 | 1956 | mov %o3, %o4 |
1874 | ta HV_CORE_TRAP | 1957 | ta HV_CORE_TRAP |
1875 | retl | 1958 | retl |
1876 | stx %o1, [%o4] | 1959 | stx %o1, [%o4] |
1960 | .size sun4v_set_version, .-sun4v_set_version | ||
1961 | |||
1962 | /* %o0: pointer to unsigned long time | ||
1963 | * | ||
1964 | * returns %o0: status | ||
1965 | */ | ||
1966 | .globl sun4v_tod_get | ||
1967 | .type sun4v_tod_get,#function | ||
1968 | sun4v_tod_get: | ||
1969 | mov %o0, %o4 | ||
1970 | mov HV_FAST_TOD_GET, %o5 | ||
1971 | ta HV_FAST_TRAP | ||
1972 | stx %o1, [%o4] | ||
1973 | retl | ||
1974 | nop | ||
1975 | .size sun4v_tod_get, .-sun4v_tod_get | ||
1976 | |||
1977 | /* %o0: time | ||
1978 | * | ||
1979 | * returns %o0: status | ||
1980 | */ | ||
1981 | .globl sun4v_tod_set | ||
1982 | .type sun4v_tod_set,#function | ||
1983 | sun4v_tod_set: | ||
1984 | mov HV_FAST_TOD_SET, %o5 | ||
1985 | ta HV_FAST_TRAP | ||
1986 | retl | ||
1987 | nop | ||
1988 | .size sun4v_tod_set, .-sun4v_tod_set | ||
1877 | 1989 | ||
1878 | /* %o0: pointer to unsigned long status | 1990 | /* %o0: pointer to unsigned long status |
1879 | * | 1991 | * |
1880 | * returns %o0: signed character | 1992 | * returns %o0: signed character |
1881 | */ | 1993 | */ |
1882 | .globl sun4v_con_getchar | 1994 | .globl sun4v_con_getchar |
1995 | .type sun4v_con_getchar,#function | ||
1883 | sun4v_con_getchar: | 1996 | sun4v_con_getchar: |
1884 | mov %o0, %o4 | 1997 | mov %o0, %o4 |
1885 | mov HV_FAST_CONS_GETCHAR, %o5 | 1998 | mov HV_FAST_CONS_GETCHAR, %o5 |
@@ -1889,17 +2002,20 @@ sun4v_con_getchar: | |||
1889 | stx %o0, [%o4] | 2002 | stx %o0, [%o4] |
1890 | retl | 2003 | retl |
1891 | sra %o1, 0, %o0 | 2004 | sra %o1, 0, %o0 |
2005 | .size sun4v_con_getchar, .-sun4v_con_getchar | ||
1892 | 2006 | ||
1893 | /* %o0: signed long character | 2007 | /* %o0: signed long character |
1894 | * | 2008 | * |
1895 | * returns %o0: status | 2009 | * returns %o0: status |
1896 | */ | 2010 | */ |
1897 | .globl sun4v_con_putchar | 2011 | .globl sun4v_con_putchar |
2012 | .type sun4v_con_putchar,#function | ||
1898 | sun4v_con_putchar: | 2013 | sun4v_con_putchar: |
1899 | mov HV_FAST_CONS_PUTCHAR, %o5 | 2014 | mov HV_FAST_CONS_PUTCHAR, %o5 |
1900 | ta HV_FAST_TRAP | 2015 | ta HV_FAST_TRAP |
1901 | retl | 2016 | retl |
1902 | sra %o0, 0, %o0 | 2017 | sra %o0, 0, %o0 |
2018 | .size sun4v_con_putchar, .-sun4v_con_putchar | ||
1903 | 2019 | ||
1904 | /* %o0: buffer real address | 2020 | /* %o0: buffer real address |
1905 | * %o1: buffer size | 2021 | * %o1: buffer size |
@@ -1908,6 +2024,7 @@ sun4v_con_putchar: | |||
1908 | * returns %o0: status | 2024 | * returns %o0: status |
1909 | */ | 2025 | */ |
1910 | .globl sun4v_con_read | 2026 | .globl sun4v_con_read |
2027 | .type sun4v_con_read,#function | ||
1911 | sun4v_con_read: | 2028 | sun4v_con_read: |
1912 | mov %o2, %o4 | 2029 | mov %o2, %o4 |
1913 | mov HV_FAST_CONS_READ, %o5 | 2030 | mov HV_FAST_CONS_READ, %o5 |
@@ -1922,6 +2039,7 @@ sun4v_con_read: | |||
1922 | stx %o1, [%o4] | 2039 | stx %o1, [%o4] |
1923 | 1: retl | 2040 | 1: retl |
1924 | nop | 2041 | nop |
2042 | .size sun4v_con_read, .-sun4v_con_read | ||
1925 | 2043 | ||
1926 | /* %o0: buffer real address | 2044 | /* %o0: buffer real address |
1927 | * %o1: buffer size | 2045 | * %o1: buffer size |
@@ -1930,6 +2048,7 @@ sun4v_con_read: | |||
1930 | * returns %o0: status | 2048 | * returns %o0: status |
1931 | */ | 2049 | */ |
1932 | .globl sun4v_con_write | 2050 | .globl sun4v_con_write |
2051 | .type sun4v_con_write,#function | ||
1933 | sun4v_con_write: | 2052 | sun4v_con_write: |
1934 | mov %o2, %o4 | 2053 | mov %o2, %o4 |
1935 | mov HV_FAST_CONS_WRITE, %o5 | 2054 | mov HV_FAST_CONS_WRITE, %o5 |
@@ -1937,3 +2056,540 @@ sun4v_con_write: | |||
1937 | stx %o1, [%o4] | 2056 | stx %o1, [%o4] |
1938 | retl | 2057 | retl |
1939 | nop | 2058 | nop |
2059 | .size sun4v_con_write, .-sun4v_con_write | ||
2060 | |||
2061 | /* %o0: soft state | ||
2062 | * %o1: address of description string | ||
2063 | * | ||
2064 | * returns %o0: status | ||
2065 | */ | ||
2066 | .globl sun4v_mach_set_soft_state | ||
2067 | .type sun4v_mach_set_soft_state,#function | ||
2068 | sun4v_mach_set_soft_state: | ||
2069 | mov HV_FAST_MACH_SET_SOFT_STATE, %o5 | ||
2070 | ta HV_FAST_TRAP | ||
2071 | retl | ||
2072 | nop | ||
2073 | .size sun4v_mach_set_soft_state, .-sun4v_mach_set_soft_state | ||
2074 | |||
2075 | /* %o0: exit code | ||
2076 | * | ||
2077 | * Does not return. | ||
2078 | */ | ||
2079 | .globl sun4v_mach_exit | ||
2080 | .type sun4v_mach_exit,#function | ||
2081 | sun4v_mach_exit: | ||
2082 | mov HV_FAST_MACH_EXIT, %o5 | ||
2083 | ta HV_FAST_TRAP | ||
2084 | retl | ||
2085 | nop | ||
2086 | .size sun4v_mach_exit, .-sun4v_mach_exit | ||
2087 | |||
2088 | /* %o0: buffer real address | ||
2089 | * %o1: buffer length | ||
2090 | * %o2: pointer to unsigned long real_buf_len | ||
2091 | * | ||
2092 | * returns %o0: status | ||
2093 | */ | ||
2094 | .globl sun4v_mach_desc | ||
2095 | .type sun4v_mach_desc,#function | ||
2096 | sun4v_mach_desc: | ||
2097 | mov %o2, %o4 | ||
2098 | mov HV_FAST_MACH_DESC, %o5 | ||
2099 | ta HV_FAST_TRAP | ||
2100 | stx %o1, [%o4] | ||
2101 | retl | ||
2102 | nop | ||
2103 | .size sun4v_mach_desc, .-sun4v_mach_desc | ||
2104 | |||
2105 | /* %o0: new timeout in milliseconds | ||
2106 | * %o1: pointer to unsigned long orig_timeout | ||
2107 | * | ||
2108 | * returns %o0: status | ||
2109 | */ | ||
2110 | .globl sun4v_mach_set_watchdog | ||
2111 | .type sun4v_mach_set_watchdog,#function | ||
2112 | sun4v_mach_set_watchdog: | ||
2113 | mov %o1, %o4 | ||
2114 | mov HV_FAST_MACH_SET_WATCHDOG, %o5 | ||
2115 | ta HV_FAST_TRAP | ||
2116 | stx %o1, [%o4] | ||
2117 | retl | ||
2118 | nop | ||
2119 | .size sun4v_mach_set_watchdog, .-sun4v_mach_set_watchdog | ||
2120 | |||
2121 | /* No inputs and does not return. */ | ||
2122 | .globl sun4v_mach_sir | ||
2123 | .type sun4v_mach_sir,#function | ||
2124 | sun4v_mach_sir: | ||
2125 | mov %o1, %o4 | ||
2126 | mov HV_FAST_MACH_SIR, %o5 | ||
2127 | ta HV_FAST_TRAP | ||
2128 | stx %o1, [%o4] | ||
2129 | retl | ||
2130 | nop | ||
2131 | .size sun4v_mach_sir, .-sun4v_mach_sir | ||
2132 | |||
2133 | /* %o0: channel | ||
2134 | * %o1: ra | ||
2135 | * %o2: num_entries | ||
2136 | * | ||
2137 | * returns %o0: status | ||
2138 | */ | ||
2139 | .globl sun4v_ldc_tx_qconf | ||
2140 | .type sun4v_ldc_tx_qconf,#function | ||
2141 | sun4v_ldc_tx_qconf: | ||
2142 | mov HV_FAST_LDC_TX_QCONF, %o5 | ||
2143 | ta HV_FAST_TRAP | ||
2144 | retl | ||
2145 | nop | ||
2146 | .size sun4v_ldc_tx_qconf, .-sun4v_ldc_tx_qconf | ||
2147 | |||
2148 | /* %o0: channel | ||
2149 | * %o1: pointer to unsigned long ra | ||
2150 | * %o2: pointer to unsigned long num_entries | ||
2151 | * | ||
2152 | * returns %o0: status | ||
2153 | */ | ||
2154 | .globl sun4v_ldc_tx_qinfo | ||
2155 | .type sun4v_ldc_tx_qinfo,#function | ||
2156 | sun4v_ldc_tx_qinfo: | ||
2157 | mov %o1, %g1 | ||
2158 | mov %o2, %g2 | ||
2159 | mov HV_FAST_LDC_TX_QINFO, %o5 | ||
2160 | ta HV_FAST_TRAP | ||
2161 | stx %o1, [%g1] | ||
2162 | stx %o2, [%g2] | ||
2163 | retl | ||
2164 | nop | ||
2165 | .size sun4v_ldc_tx_qinfo, .-sun4v_ldc_tx_qinfo | ||
2166 | |||
2167 | /* %o0: channel | ||
2168 | * %o1: pointer to unsigned long head_off | ||
2169 | * %o2: pointer to unsigned long tail_off | ||
2170 | * %o2: pointer to unsigned long chan_state | ||
2171 | * | ||
2172 | * returns %o0: status | ||
2173 | */ | ||
2174 | .globl sun4v_ldc_tx_get_state | ||
2175 | .type sun4v_ldc_tx_get_state,#function | ||
2176 | sun4v_ldc_tx_get_state: | ||
2177 | mov %o1, %g1 | ||
2178 | mov %o2, %g2 | ||
2179 | mov %o3, %g3 | ||
2180 | mov HV_FAST_LDC_TX_GET_STATE, %o5 | ||
2181 | ta HV_FAST_TRAP | ||
2182 | stx %o1, [%g1] | ||
2183 | stx %o2, [%g2] | ||
2184 | stx %o3, [%g3] | ||
2185 | retl | ||
2186 | nop | ||
2187 | .size sun4v_ldc_tx_get_state, .-sun4v_ldc_tx_get_state | ||
2188 | |||
2189 | /* %o0: channel | ||
2190 | * %o1: tail_off | ||
2191 | * | ||
2192 | * returns %o0: status | ||
2193 | */ | ||
2194 | .globl sun4v_ldc_tx_set_qtail | ||
2195 | .type sun4v_ldc_tx_set_qtail,#function | ||
2196 | sun4v_ldc_tx_set_qtail: | ||
2197 | mov HV_FAST_LDC_TX_SET_QTAIL, %o5 | ||
2198 | ta HV_FAST_TRAP | ||
2199 | retl | ||
2200 | nop | ||
2201 | .size sun4v_ldc_tx_set_qtail, .-sun4v_ldc_tx_set_qtail | ||
2202 | |||
2203 | /* %o0: channel | ||
2204 | * %o1: ra | ||
2205 | * %o2: num_entries | ||
2206 | * | ||
2207 | * returns %o0: status | ||
2208 | */ | ||
2209 | .globl sun4v_ldc_rx_qconf | ||
2210 | .type sun4v_ldc_rx_qconf,#function | ||
2211 | sun4v_ldc_rx_qconf: | ||
2212 | mov HV_FAST_LDC_RX_QCONF, %o5 | ||
2213 | ta HV_FAST_TRAP | ||
2214 | retl | ||
2215 | nop | ||
2216 | .size sun4v_ldc_rx_qconf, .-sun4v_ldc_rx_qconf | ||
2217 | |||
2218 | /* %o0: channel | ||
2219 | * %o1: pointer to unsigned long ra | ||
2220 | * %o2: pointer to unsigned long num_entries | ||
2221 | * | ||
2222 | * returns %o0: status | ||
2223 | */ | ||
2224 | .globl sun4v_ldc_rx_qinfo | ||
2225 | .type sun4v_ldc_rx_qinfo,#function | ||
2226 | sun4v_ldc_rx_qinfo: | ||
2227 | mov %o1, %g1 | ||
2228 | mov %o2, %g2 | ||
2229 | mov HV_FAST_LDC_RX_QINFO, %o5 | ||
2230 | ta HV_FAST_TRAP | ||
2231 | stx %o1, [%g1] | ||
2232 | stx %o2, [%g2] | ||
2233 | retl | ||
2234 | nop | ||
2235 | .size sun4v_ldc_rx_qinfo, .-sun4v_ldc_rx_qinfo | ||
2236 | |||
2237 | /* %o0: channel | ||
2238 | * %o1: pointer to unsigned long head_off | ||
2239 | * %o2: pointer to unsigned long tail_off | ||
2240 | * %o2: pointer to unsigned long chan_state | ||
2241 | * | ||
2242 | * returns %o0: status | ||
2243 | */ | ||
2244 | .globl sun4v_ldc_rx_get_state | ||
2245 | .type sun4v_ldc_rx_get_state,#function | ||
2246 | sun4v_ldc_rx_get_state: | ||
2247 | mov %o1, %g1 | ||
2248 | mov %o2, %g2 | ||
2249 | mov %o3, %g3 | ||
2250 | mov HV_FAST_LDC_RX_GET_STATE, %o5 | ||
2251 | ta HV_FAST_TRAP | ||
2252 | stx %o1, [%g1] | ||
2253 | stx %o2, [%g2] | ||
2254 | stx %o3, [%g3] | ||
2255 | retl | ||
2256 | nop | ||
2257 | .size sun4v_ldc_rx_get_state, .-sun4v_ldc_rx_get_state | ||
2258 | |||
2259 | /* %o0: channel | ||
2260 | * %o1: head_off | ||
2261 | * | ||
2262 | * returns %o0: status | ||
2263 | */ | ||
2264 | .globl sun4v_ldc_rx_set_qhead | ||
2265 | .type sun4v_ldc_rx_set_qhead,#function | ||
2266 | sun4v_ldc_rx_set_qhead: | ||
2267 | mov HV_FAST_LDC_RX_SET_QHEAD, %o5 | ||
2268 | ta HV_FAST_TRAP | ||
2269 | retl | ||
2270 | nop | ||
2271 | .size sun4v_ldc_rx_set_qhead, .-sun4v_ldc_rx_set_qhead | ||
2272 | |||
2273 | /* %o0: channel | ||
2274 | * %o1: ra | ||
2275 | * %o2: num_entries | ||
2276 | * | ||
2277 | * returns %o0: status | ||
2278 | */ | ||
2279 | .globl sun4v_ldc_set_map_table | ||
2280 | .type sun4v_ldc_set_map_table,#function | ||
2281 | sun4v_ldc_set_map_table: | ||
2282 | mov HV_FAST_LDC_SET_MAP_TABLE, %o5 | ||
2283 | ta HV_FAST_TRAP | ||
2284 | retl | ||
2285 | nop | ||
2286 | .size sun4v_ldc_set_map_table, .-sun4v_ldc_set_map_table | ||
2287 | |||
2288 | /* %o0: channel | ||
2289 | * %o1: pointer to unsigned long ra | ||
2290 | * %o2: pointer to unsigned long num_entries | ||
2291 | * | ||
2292 | * returns %o0: status | ||
2293 | */ | ||
2294 | .globl sun4v_ldc_get_map_table | ||
2295 | .type sun4v_ldc_get_map_table,#function | ||
2296 | sun4v_ldc_get_map_table: | ||
2297 | mov %o1, %g1 | ||
2298 | mov %o2, %g2 | ||
2299 | mov HV_FAST_LDC_GET_MAP_TABLE, %o5 | ||
2300 | ta HV_FAST_TRAP | ||
2301 | stx %o1, [%g1] | ||
2302 | stx %o2, [%g2] | ||
2303 | retl | ||
2304 | nop | ||
2305 | .size sun4v_ldc_get_map_table, .-sun4v_ldc_get_map_table | ||
2306 | |||
2307 | /* %o0: channel | ||
2308 | * %o1: dir_code | ||
2309 | * %o2: tgt_raddr | ||
2310 | * %o3: lcl_raddr | ||
2311 | * %o4: len | ||
2312 | * %o5: pointer to unsigned long actual_len | ||
2313 | * | ||
2314 | * returns %o0: status | ||
2315 | */ | ||
2316 | .globl sun4v_ldc_copy | ||
2317 | .type sun4v_ldc_copy,#function | ||
2318 | sun4v_ldc_copy: | ||
2319 | mov %o5, %g1 | ||
2320 | mov HV_FAST_LDC_COPY, %o5 | ||
2321 | ta HV_FAST_TRAP | ||
2322 | stx %o1, [%g1] | ||
2323 | retl | ||
2324 | nop | ||
2325 | .size sun4v_ldc_copy, .-sun4v_ldc_copy | ||
2326 | |||
2327 | /* %o0: channel | ||
2328 | * %o1: cookie | ||
2329 | * %o2: pointer to unsigned long ra | ||
2330 | * %o3: pointer to unsigned long perm | ||
2331 | * | ||
2332 | * returns %o0: status | ||
2333 | */ | ||
2334 | .globl sun4v_ldc_mapin | ||
2335 | .type sun4v_ldc_mapin,#function | ||
2336 | sun4v_ldc_mapin: | ||
2337 | mov %o2, %g1 | ||
2338 | mov %o3, %g2 | ||
2339 | mov HV_FAST_LDC_MAPIN, %o5 | ||
2340 | ta HV_FAST_TRAP | ||
2341 | stx %o1, [%g1] | ||
2342 | stx %o2, [%g2] | ||
2343 | retl | ||
2344 | nop | ||
2345 | .size sun4v_ldc_mapin, .-sun4v_ldc_mapin | ||
2346 | |||
2347 | /* %o0: ra | ||
2348 | * | ||
2349 | * returns %o0: status | ||
2350 | */ | ||
2351 | .globl sun4v_ldc_unmap | ||
2352 | .type sun4v_ldc_unmap,#function | ||
2353 | sun4v_ldc_unmap: | ||
2354 | mov HV_FAST_LDC_UNMAP, %o5 | ||
2355 | ta HV_FAST_TRAP | ||
2356 | retl | ||
2357 | nop | ||
2358 | .size sun4v_ldc_unmap, .-sun4v_ldc_unmap | ||
2359 | |||
2360 | /* %o0: channel | ||
2361 | * %o1: cookie | ||
2362 | * %o2: mte_cookie | ||
2363 | * | ||
2364 | * returns %o0: status | ||
2365 | */ | ||
2366 | .globl sun4v_ldc_revoke | ||
2367 | .type sun4v_ldc_revoke,#function | ||
2368 | sun4v_ldc_revoke: | ||
2369 | mov HV_FAST_LDC_REVOKE, %o5 | ||
2370 | ta HV_FAST_TRAP | ||
2371 | retl | ||
2372 | nop | ||
2373 | .size sun4v_ldc_revoke, .-sun4v_ldc_revoke | ||
2374 | |||
2375 | /* %o0: device handle | ||
2376 | * %o1: device INO | ||
2377 | * %o2: pointer to unsigned long cookie | ||
2378 | * | ||
2379 | * returns %o0: status | ||
2380 | */ | ||
2381 | .globl sun4v_vintr_get_cookie | ||
2382 | .type sun4v_vintr_get_cookie,#function | ||
2383 | sun4v_vintr_get_cookie: | ||
2384 | mov %o2, %g1 | ||
2385 | mov HV_FAST_VINTR_GET_COOKIE, %o5 | ||
2386 | ta HV_FAST_TRAP | ||
2387 | stx %o1, [%g1] | ||
2388 | retl | ||
2389 | nop | ||
2390 | .size sun4v_vintr_get_cookie, .-sun4v_vintr_get_cookie | ||
2391 | |||
2392 | /* %o0: device handle | ||
2393 | * %o1: device INO | ||
2394 | * %o2: cookie | ||
2395 | * | ||
2396 | * returns %o0: status | ||
2397 | */ | ||
2398 | .globl sun4v_vintr_set_cookie | ||
2399 | .type sun4v_vintr_set_cookie,#function | ||
2400 | sun4v_vintr_set_cookie: | ||
2401 | mov HV_FAST_VINTR_SET_COOKIE, %o5 | ||
2402 | ta HV_FAST_TRAP | ||
2403 | retl | ||
2404 | nop | ||
2405 | .size sun4v_vintr_set_cookie, .-sun4v_vintr_set_cookie | ||
2406 | |||
2407 | /* %o0: device handle | ||
2408 | * %o1: device INO | ||
2409 | * %o2: pointer to unsigned long valid_state | ||
2410 | * | ||
2411 | * returns %o0: status | ||
2412 | */ | ||
2413 | .globl sun4v_vintr_get_valid | ||
2414 | .type sun4v_vintr_get_valid,#function | ||
2415 | sun4v_vintr_get_valid: | ||
2416 | mov %o2, %g1 | ||
2417 | mov HV_FAST_VINTR_GET_VALID, %o5 | ||
2418 | ta HV_FAST_TRAP | ||
2419 | stx %o1, [%g1] | ||
2420 | retl | ||
2421 | nop | ||
2422 | .size sun4v_vintr_get_valid, .-sun4v_vintr_get_valid | ||
2423 | |||
2424 | /* %o0: device handle | ||
2425 | * %o1: device INO | ||
2426 | * %o2: valid_state | ||
2427 | * | ||
2428 | * returns %o0: status | ||
2429 | */ | ||
2430 | .globl sun4v_vintr_set_valid | ||
2431 | .type sun4v_vintr_set_valid,#function | ||
2432 | sun4v_vintr_set_valid: | ||
2433 | mov HV_FAST_VINTR_SET_VALID, %o5 | ||
2434 | ta HV_FAST_TRAP | ||
2435 | retl | ||
2436 | nop | ||
2437 | .size sun4v_vintr_set_valid, .-sun4v_vintr_set_valid | ||
2438 | |||
2439 | /* %o0: device handle | ||
2440 | * %o1: device INO | ||
2441 | * %o2: pointer to unsigned long state | ||
2442 | * | ||
2443 | * returns %o0: status | ||
2444 | */ | ||
2445 | .globl sun4v_vintr_get_state | ||
2446 | .type sun4v_vintr_get_state,#function | ||
2447 | sun4v_vintr_get_state: | ||
2448 | mov %o2, %g1 | ||
2449 | mov HV_FAST_VINTR_GET_STATE, %o5 | ||
2450 | ta HV_FAST_TRAP | ||
2451 | stx %o1, [%g1] | ||
2452 | retl | ||
2453 | nop | ||
2454 | .size sun4v_vintr_get_state, .-sun4v_vintr_get_state | ||
2455 | |||
2456 | /* %o0: device handle | ||
2457 | * %o1: device INO | ||
2458 | * %o2: state | ||
2459 | * | ||
2460 | * returns %o0: status | ||
2461 | */ | ||
2462 | .globl sun4v_vintr_set_state | ||
2463 | .type sun4v_vintr_set_state,#function | ||
2464 | sun4v_vintr_set_state: | ||
2465 | mov HV_FAST_VINTR_SET_STATE, %o5 | ||
2466 | ta HV_FAST_TRAP | ||
2467 | retl | ||
2468 | nop | ||
2469 | .size sun4v_vintr_set_state, .-sun4v_vintr_set_state | ||
2470 | |||
2471 | /* %o0: device handle | ||
2472 | * %o1: device INO | ||
2473 | * %o2: pointer to unsigned long cpuid | ||
2474 | * | ||
2475 | * returns %o0: status | ||
2476 | */ | ||
2477 | .globl sun4v_vintr_get_target | ||
2478 | .type sun4v_vintr_get_target,#function | ||
2479 | sun4v_vintr_get_target: | ||
2480 | mov %o2, %g1 | ||
2481 | mov HV_FAST_VINTR_GET_TARGET, %o5 | ||
2482 | ta HV_FAST_TRAP | ||
2483 | stx %o1, [%g1] | ||
2484 | retl | ||
2485 | nop | ||
2486 | .size sun4v_vintr_get_target, .-sun4v_vintr_get_target | ||
2487 | |||
2488 | /* %o0: device handle | ||
2489 | * %o1: device INO | ||
2490 | * %o2: cpuid | ||
2491 | * | ||
2492 | * returns %o0: status | ||
2493 | */ | ||
2494 | .globl sun4v_vintr_set_target | ||
2495 | .type sun4v_vintr_set_target,#function | ||
2496 | sun4v_vintr_set_target: | ||
2497 | mov HV_FAST_VINTR_SET_TARGET, %o5 | ||
2498 | ta HV_FAST_TRAP | ||
2499 | retl | ||
2500 | nop | ||
2501 | .size sun4v_vintr_set_target, .-sun4v_vintr_set_target | ||
2502 | |||
2503 | /* %o0: NCS sub-function | ||
2504 | * %o1: sub-function arg real-address | ||
2505 | * %o2: sub-function arg size | ||
2506 | * | ||
2507 | * returns %o0: status | ||
2508 | */ | ||
2509 | .globl sun4v_ncs_request | ||
2510 | .type sun4v_ncs_request,#function | ||
2511 | sun4v_ncs_request: | ||
2512 | mov HV_FAST_NCS_REQUEST, %o5 | ||
2513 | ta HV_FAST_TRAP | ||
2514 | retl | ||
2515 | nop | ||
2516 | .size sun4v_ncs_request, .-sun4v_ncs_request | ||
2517 | |||
2518 | .globl sun4v_svc_send | ||
2519 | .type sun4v_svc_send,#function | ||
2520 | sun4v_svc_send: | ||
2521 | save %sp, -192, %sp | ||
2522 | mov %i0, %o0 | ||
2523 | mov %i1, %o1 | ||
2524 | mov %i2, %o2 | ||
2525 | mov HV_FAST_SVC_SEND, %o5 | ||
2526 | ta HV_FAST_TRAP | ||
2527 | stx %o1, [%i3] | ||
2528 | ret | ||
2529 | restore | ||
2530 | .size sun4v_svc_send, .-sun4v_svc_send | ||
2531 | |||
2532 | .globl sun4v_svc_recv | ||
2533 | .type sun4v_svc_recv,#function | ||
2534 | sun4v_svc_recv: | ||
2535 | save %sp, -192, %sp | ||
2536 | mov %i0, %o0 | ||
2537 | mov %i1, %o1 | ||
2538 | mov %i2, %o2 | ||
2539 | mov HV_FAST_SVC_RECV, %o5 | ||
2540 | ta HV_FAST_TRAP | ||
2541 | stx %o1, [%i3] | ||
2542 | ret | ||
2543 | restore | ||
2544 | .size sun4v_svc_recv, .-sun4v_svc_recv | ||
2545 | |||
2546 | .globl sun4v_svc_getstatus | ||
2547 | .type sun4v_svc_getstatus,#function | ||
2548 | sun4v_svc_getstatus: | ||
2549 | mov HV_FAST_SVC_GETSTATUS, %o5 | ||
2550 | mov %o1, %o4 | ||
2551 | ta HV_FAST_TRAP | ||
2552 | stx %o1, [%o4] | ||
2553 | retl | ||
2554 | nop | ||
2555 | .size sun4v_svc_getstatus, .-sun4v_svc_getstatus | ||
2556 | |||
2557 | .globl sun4v_svc_setstatus | ||
2558 | .type sun4v_svc_setstatus,#function | ||
2559 | sun4v_svc_setstatus: | ||
2560 | mov HV_FAST_SVC_SETSTATUS, %o5 | ||
2561 | ta HV_FAST_TRAP | ||
2562 | retl | ||
2563 | nop | ||
2564 | .size sun4v_svc_setstatus, .-sun4v_svc_setstatus | ||
2565 | |||
2566 | .globl sun4v_svc_clrstatus | ||
2567 | .type sun4v_svc_clrstatus,#function | ||
2568 | sun4v_svc_clrstatus: | ||
2569 | mov HV_FAST_SVC_CLRSTATUS, %o5 | ||
2570 | ta HV_FAST_TRAP | ||
2571 | retl | ||
2572 | nop | ||
2573 | .size sun4v_svc_clrstatus, .-sun4v_svc_clrstatus | ||
2574 | |||
2575 | .globl sun4v_mmustat_conf | ||
2576 | .type sun4v_mmustat_conf,#function | ||
2577 | sun4v_mmustat_conf: | ||
2578 | mov %o1, %o4 | ||
2579 | mov HV_FAST_MMUSTAT_CONF, %o5 | ||
2580 | ta HV_FAST_TRAP | ||
2581 | stx %o1, [%o4] | ||
2582 | retl | ||
2583 | nop | ||
2584 | .size sun4v_mmustat_conf, .-sun4v_mmustat_conf | ||
2585 | |||
2586 | .globl sun4v_mmustat_info | ||
2587 | .type sun4v_mmustat_info,#function | ||
2588 | sun4v_mmustat_info: | ||
2589 | mov %o0, %o4 | ||
2590 | mov HV_FAST_MMUSTAT_INFO, %o5 | ||
2591 | ta HV_FAST_TRAP | ||
2592 | stx %o1, [%o4] | ||
2593 | retl | ||
2594 | nop | ||
2595 | .size sun4v_mmustat_info, .-sun4v_mmustat_info | ||
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S index baea10a98196..77259526cb15 100644 --- a/arch/sparc64/kernel/head.S +++ b/arch/sparc64/kernel/head.S | |||
@@ -523,7 +523,7 @@ tlb_fixup_done: | |||
523 | #else | 523 | #else |
524 | mov 0, %o0 | 524 | mov 0, %o0 |
525 | #endif | 525 | #endif |
526 | stb %o0, [%g6 + TI_CPU] | 526 | sth %o0, [%g6 + TI_CPU] |
527 | 527 | ||
528 | /* Off we go.... */ | 528 | /* Off we go.... */ |
529 | call start_kernel | 529 | call start_kernel |
@@ -653,33 +653,54 @@ setup_tba: | |||
653 | restore | 653 | restore |
654 | sparc64_boot_end: | 654 | sparc64_boot_end: |
655 | 655 | ||
656 | #include "ktlb.S" | ||
657 | #include "tsb.S" | ||
658 | #include "etrap.S" | 656 | #include "etrap.S" |
659 | #include "rtrap.S" | 657 | #include "rtrap.S" |
660 | #include "winfixup.S" | 658 | #include "winfixup.S" |
661 | #include "entry.S" | 659 | #include "entry.S" |
662 | #include "sun4v_tlb_miss.S" | 660 | #include "sun4v_tlb_miss.S" |
663 | #include "sun4v_ivec.S" | 661 | #include "sun4v_ivec.S" |
662 | #include "ktlb.S" | ||
663 | #include "tsb.S" | ||
664 | 664 | ||
665 | /* | 665 | /* |
666 | * The following skip makes sure the trap table in ttable.S is aligned | 666 | * The following skip makes sure the trap table in ttable.S is aligned |
667 | * on a 32K boundary as required by the v9 specs for TBA register. | 667 | * on a 32K boundary as required by the v9 specs for TBA register. |
668 | * | 668 | * |
669 | * We align to a 32K boundary, then we have the 32K kernel TSB, | 669 | * We align to a 32K boundary, then we have the 32K kernel TSB, |
670 | * then the 32K aligned trap table. | 670 | * the 64K kernel 4MB TSB, and then the 32K aligned trap table. |
671 | */ | 671 | */ |
672 | 1: | 672 | 1: |
673 | .skip 0x4000 + _start - 1b | 673 | .skip 0x4000 + _start - 1b |
674 | 674 | ||
675 | ! 0x0000000000408000 | ||
676 | |||
675 | .globl swapper_tsb | 677 | .globl swapper_tsb |
676 | swapper_tsb: | 678 | swapper_tsb: |
677 | .skip (32 * 1024) | 679 | .skip (32 * 1024) |
678 | 680 | ||
679 | ! 0x0000000000408000 | 681 | .globl swapper_4m_tsb |
682 | swapper_4m_tsb: | ||
683 | .skip (64 * 1024) | ||
684 | |||
685 | ! 0x0000000000420000 | ||
680 | 686 | ||
687 | /* Some care needs to be exercised if you try to move the | ||
688 | * location of the trap table relative to other things. For | ||
689 | * one thing there are br* instructions in some of the | ||
690 | * trap table entires which branch back to code in ktlb.S | ||
691 | * Those instructions can only handle a signed 16-bit | ||
692 | * displacement. | ||
693 | * | ||
694 | * There is a binutils bug (bugzilla #4558) which causes | ||
695 | * the relocation overflow checks for such instructions to | ||
696 | * not be done correctly. So bintuils will not notice the | ||
697 | * error and will instead write junk into the relocation and | ||
698 | * you'll have an unbootable kernel. | ||
699 | */ | ||
681 | #include "ttable.S" | 700 | #include "ttable.S" |
682 | 701 | ||
702 | ! 0x0000000000428000 | ||
703 | |||
683 | #include "systbls.S" | 704 | #include "systbls.S" |
684 | 705 | ||
685 | .data | 706 | .data |
diff --git a/arch/sparc64/kernel/hvapi.c b/arch/sparc64/kernel/hvapi.c index f03ffc829c7a..f34f5d6181ef 100644 --- a/arch/sparc64/kernel/hvapi.c +++ b/arch/sparc64/kernel/hvapi.c | |||
@@ -9,6 +9,7 @@ | |||
9 | 9 | ||
10 | #include <asm/hypervisor.h> | 10 | #include <asm/hypervisor.h> |
11 | #include <asm/oplib.h> | 11 | #include <asm/oplib.h> |
12 | #include <asm/sstate.h> | ||
12 | 13 | ||
13 | /* If the hypervisor indicates that the API setting | 14 | /* If the hypervisor indicates that the API setting |
14 | * calls are unsupported, by returning HV_EBADTRAP or | 15 | * calls are unsupported, by returning HV_EBADTRAP or |
@@ -107,7 +108,7 @@ int sun4v_hvapi_register(unsigned long group, unsigned long major, | |||
107 | p->minor = actual_minor; | 108 | p->minor = actual_minor; |
108 | ret = 0; | 109 | ret = 0; |
109 | } else if (hv_ret == HV_EBADTRAP || | 110 | } else if (hv_ret == HV_EBADTRAP || |
110 | HV_ENOTSUPPORTED) { | 111 | hv_ret == HV_ENOTSUPPORTED) { |
111 | if (p->flags & FLAG_PRE_API) { | 112 | if (p->flags & FLAG_PRE_API) { |
112 | if (major == 1) { | 113 | if (major == 1) { |
113 | p->major = 1; | 114 | p->major = 1; |
@@ -179,6 +180,8 @@ void __init sun4v_hvapi_init(void) | |||
179 | if (sun4v_hvapi_register(group, major, &minor)) | 180 | if (sun4v_hvapi_register(group, major, &minor)) |
180 | goto bad; | 181 | goto bad; |
181 | 182 | ||
183 | sun4v_sstate_init(); | ||
184 | |||
182 | return; | 185 | return; |
183 | 186 | ||
184 | bad: | 187 | bad: |
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index 3edc18e1b818..e60d283f60bc 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c | |||
@@ -1,7 +1,6 @@ | |||
1 | /* $Id: irq.c,v 1.114 2002/01/11 08:45:38 davem Exp $ | 1 | /* irq.c: UltraSparc IRQ handling/init/registry. |
2 | * irq.c: UltraSparc IRQ handling/init/registry. | ||
3 | * | 2 | * |
4 | * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) | 3 | * Copyright (C) 1997, 2007 David S. Miller (davem@davemloft.net) |
5 | * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) | 4 | * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) |
6 | * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) | 5 | * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz) |
7 | */ | 6 | */ |
@@ -43,6 +42,7 @@ | |||
43 | #include <asm/cpudata.h> | 42 | #include <asm/cpudata.h> |
44 | #include <asm/auxio.h> | 43 | #include <asm/auxio.h> |
45 | #include <asm/head.h> | 44 | #include <asm/head.h> |
45 | #include <asm/hypervisor.h> | ||
46 | 46 | ||
47 | /* UPA nodes send interrupt packet to UltraSparc with first data reg | 47 | /* UPA nodes send interrupt packet to UltraSparc with first data reg |
48 | * value low 5 (7 on Starfire) bits holding the IRQ identifier being | 48 | * value low 5 (7 on Starfire) bits holding the IRQ identifier being |
@@ -171,8 +171,6 @@ skip: | |||
171 | return 0; | 171 | return 0; |
172 | } | 172 | } |
173 | 173 | ||
174 | extern unsigned long real_hard_smp_processor_id(void); | ||
175 | |||
176 | static unsigned int sun4u_compute_tid(unsigned long imap, unsigned long cpuid) | 174 | static unsigned int sun4u_compute_tid(unsigned long imap, unsigned long cpuid) |
177 | { | 175 | { |
178 | unsigned int tid; | 176 | unsigned int tid; |
@@ -382,6 +380,76 @@ static void sun4v_irq_end(unsigned int virt_irq) | |||
382 | } | 380 | } |
383 | } | 381 | } |
384 | 382 | ||
383 | static void sun4v_virq_enable(unsigned int virt_irq) | ||
384 | { | ||
385 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); | ||
386 | unsigned int ino = bucket - &ivector_table[0]; | ||
387 | |||
388 | if (likely(bucket)) { | ||
389 | unsigned long cpuid, dev_handle, dev_ino; | ||
390 | int err; | ||
391 | |||
392 | cpuid = irq_choose_cpu(virt_irq); | ||
393 | |||
394 | dev_handle = ino & IMAP_IGN; | ||
395 | dev_ino = ino & IMAP_INO; | ||
396 | |||
397 | err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); | ||
398 | if (err != HV_EOK) | ||
399 | printk("sun4v_vintr_set_target(%lx,%lx,%lu): " | ||
400 | "err(%d)\n", | ||
401 | dev_handle, dev_ino, cpuid, err); | ||
402 | err = sun4v_vintr_set_state(dev_handle, dev_ino, | ||
403 | HV_INTR_ENABLED); | ||
404 | if (err != HV_EOK) | ||
405 | printk("sun4v_vintr_set_state(%lx,%lx," | ||
406 | "HV_INTR_ENABLED): err(%d)\n", | ||
407 | dev_handle, dev_ino, err); | ||
408 | } | ||
409 | } | ||
410 | |||
411 | static void sun4v_virq_disable(unsigned int virt_irq) | ||
412 | { | ||
413 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); | ||
414 | unsigned int ino = bucket - &ivector_table[0]; | ||
415 | |||
416 | if (likely(bucket)) { | ||
417 | unsigned long dev_handle, dev_ino; | ||
418 | int err; | ||
419 | |||
420 | dev_handle = ino & IMAP_IGN; | ||
421 | dev_ino = ino & IMAP_INO; | ||
422 | |||
423 | err = sun4v_vintr_set_state(dev_handle, dev_ino, | ||
424 | HV_INTR_DISABLED); | ||
425 | if (err != HV_EOK) | ||
426 | printk("sun4v_vintr_set_state(%lx,%lx," | ||
427 | "HV_INTR_DISABLED): err(%d)\n", | ||
428 | dev_handle, dev_ino, err); | ||
429 | } | ||
430 | } | ||
431 | |||
432 | static void sun4v_virq_end(unsigned int virt_irq) | ||
433 | { | ||
434 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); | ||
435 | unsigned int ino = bucket - &ivector_table[0]; | ||
436 | |||
437 | if (likely(bucket)) { | ||
438 | unsigned long dev_handle, dev_ino; | ||
439 | int err; | ||
440 | |||
441 | dev_handle = ino & IMAP_IGN; | ||
442 | dev_ino = ino & IMAP_INO; | ||
443 | |||
444 | err = sun4v_vintr_set_state(dev_handle, dev_ino, | ||
445 | HV_INTR_STATE_IDLE); | ||
446 | if (err != HV_EOK) | ||
447 | printk("sun4v_vintr_set_state(%lx,%lx," | ||
448 | "HV_INTR_STATE_IDLE): err(%d)\n", | ||
449 | dev_handle, dev_ino, err); | ||
450 | } | ||
451 | } | ||
452 | |||
385 | static void run_pre_handler(unsigned int virt_irq) | 453 | static void run_pre_handler(unsigned int virt_irq) |
386 | { | 454 | { |
387 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); | 455 | struct ino_bucket *bucket = virt_irq_to_bucket(virt_irq); |
@@ -436,6 +504,21 @@ static struct irq_chip sun4v_msi = { | |||
436 | }; | 504 | }; |
437 | #endif | 505 | #endif |
438 | 506 | ||
507 | static struct irq_chip sun4v_virq = { | ||
508 | .typename = "vsun4v", | ||
509 | .enable = sun4v_virq_enable, | ||
510 | .disable = sun4v_virq_disable, | ||
511 | .end = sun4v_virq_end, | ||
512 | }; | ||
513 | |||
514 | static struct irq_chip sun4v_virq_ack = { | ||
515 | .typename = "vsun4v+ack", | ||
516 | .enable = sun4v_virq_enable, | ||
517 | .disable = sun4v_virq_disable, | ||
518 | .ack = run_pre_handler, | ||
519 | .end = sun4v_virq_end, | ||
520 | }; | ||
521 | |||
439 | void irq_install_pre_handler(int virt_irq, | 522 | void irq_install_pre_handler(int virt_irq, |
440 | void (*func)(unsigned int, void *, void *), | 523 | void (*func)(unsigned int, void *, void *), |
441 | void *arg1, void *arg2) | 524 | void *arg1, void *arg2) |
@@ -449,7 +532,8 @@ void irq_install_pre_handler(int virt_irq, | |||
449 | 532 | ||
450 | chip = get_irq_chip(virt_irq); | 533 | chip = get_irq_chip(virt_irq); |
451 | if (chip == &sun4u_irq_ack || | 534 | if (chip == &sun4u_irq_ack || |
452 | chip == &sun4v_irq_ack | 535 | chip == &sun4v_irq_ack || |
536 | chip == &sun4v_virq_ack | ||
453 | #ifdef CONFIG_PCI_MSI | 537 | #ifdef CONFIG_PCI_MSI |
454 | || chip == &sun4v_msi | 538 | || chip == &sun4v_msi |
455 | #endif | 539 | #endif |
@@ -457,7 +541,9 @@ void irq_install_pre_handler(int virt_irq, | |||
457 | return; | 541 | return; |
458 | 542 | ||
459 | chip = (chip == &sun4u_irq ? | 543 | chip = (chip == &sun4u_irq ? |
460 | &sun4u_irq_ack : &sun4v_irq_ack); | 544 | &sun4u_irq_ack : |
545 | (chip == &sun4v_irq ? | ||
546 | &sun4v_irq_ack : &sun4v_virq_ack)); | ||
461 | set_irq_chip(virt_irq, chip); | 547 | set_irq_chip(virt_irq, chip); |
462 | } | 548 | } |
463 | 549 | ||
@@ -494,19 +580,18 @@ out: | |||
494 | return bucket->virt_irq; | 580 | return bucket->virt_irq; |
495 | } | 581 | } |
496 | 582 | ||
497 | unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino) | 583 | static unsigned int sun4v_build_common(unsigned long sysino, |
584 | struct irq_chip *chip) | ||
498 | { | 585 | { |
499 | struct ino_bucket *bucket; | 586 | struct ino_bucket *bucket; |
500 | struct irq_handler_data *data; | 587 | struct irq_handler_data *data; |
501 | unsigned long sysino; | ||
502 | 588 | ||
503 | BUG_ON(tlb_type != hypervisor); | 589 | BUG_ON(tlb_type != hypervisor); |
504 | 590 | ||
505 | sysino = sun4v_devino_to_sysino(devhandle, devino); | ||
506 | bucket = &ivector_table[sysino]; | 591 | bucket = &ivector_table[sysino]; |
507 | if (!bucket->virt_irq) { | 592 | if (!bucket->virt_irq) { |
508 | bucket->virt_irq = virt_irq_alloc(__irq(bucket)); | 593 | bucket->virt_irq = virt_irq_alloc(__irq(bucket)); |
509 | set_irq_chip(bucket->virt_irq, &sun4v_irq); | 594 | set_irq_chip(bucket->virt_irq, chip); |
510 | } | 595 | } |
511 | 596 | ||
512 | data = get_irq_chip_data(bucket->virt_irq); | 597 | data = get_irq_chip_data(bucket->virt_irq); |
@@ -531,6 +616,32 @@ out: | |||
531 | return bucket->virt_irq; | 616 | return bucket->virt_irq; |
532 | } | 617 | } |
533 | 618 | ||
619 | unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino) | ||
620 | { | ||
621 | unsigned long sysino = sun4v_devino_to_sysino(devhandle, devino); | ||
622 | |||
623 | return sun4v_build_common(sysino, &sun4v_irq); | ||
624 | } | ||
625 | |||
626 | unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) | ||
627 | { | ||
628 | unsigned long sysino, hv_err; | ||
629 | |||
630 | BUG_ON(devhandle & ~IMAP_IGN); | ||
631 | BUG_ON(devino & ~IMAP_INO); | ||
632 | |||
633 | sysino = devhandle | devino; | ||
634 | |||
635 | hv_err = sun4v_vintr_set_cookie(devhandle, devino, sysino); | ||
636 | if (hv_err) { | ||
637 | prom_printf("IRQ: Fatal, cannot set cookie for [%x:%x] " | ||
638 | "err=%lu\n", devhandle, devino, hv_err); | ||
639 | prom_halt(); | ||
640 | } | ||
641 | |||
642 | return sun4v_build_common(sysino, &sun4v_virq); | ||
643 | } | ||
644 | |||
534 | #ifdef CONFIG_PCI_MSI | 645 | #ifdef CONFIG_PCI_MSI |
535 | unsigned int sun4v_build_msi(u32 devhandle, unsigned int *virt_irq_p, | 646 | unsigned int sun4v_build_msi(u32 devhandle, unsigned int *virt_irq_p, |
536 | unsigned int msi_start, unsigned int msi_end) | 647 | unsigned int msi_start, unsigned int msi_end) |
@@ -694,9 +805,20 @@ void init_irqwork_curcpu(void) | |||
694 | trap_block[cpu].irq_worklist = 0; | 805 | trap_block[cpu].irq_worklist = 0; |
695 | } | 806 | } |
696 | 807 | ||
697 | static void __cpuinit register_one_mondo(unsigned long paddr, unsigned long type) | 808 | /* Please be very careful with register_one_mondo() and |
809 | * sun4v_register_mondo_queues(). | ||
810 | * | ||
811 | * On SMP this gets invoked from the CPU trampoline before | ||
812 | * the cpu has fully taken over the trap table from OBP, | ||
813 | * and it's kernel stack + %g6 thread register state is | ||
814 | * not fully cooked yet. | ||
815 | * | ||
816 | * Therefore you cannot make any OBP calls, not even prom_printf, | ||
817 | * from these two routines. | ||
818 | */ | ||
819 | static void __cpuinit register_one_mondo(unsigned long paddr, unsigned long type, unsigned long qmask) | ||
698 | { | 820 | { |
699 | unsigned long num_entries = 128; | 821 | unsigned long num_entries = (qmask + 1) / 64; |
700 | unsigned long status; | 822 | unsigned long status; |
701 | 823 | ||
702 | status = sun4v_cpu_qconf(type, paddr, num_entries); | 824 | status = sun4v_cpu_qconf(type, paddr, num_entries); |
@@ -711,44 +833,58 @@ static void __cpuinit sun4v_register_mondo_queues(int this_cpu) | |||
711 | { | 833 | { |
712 | struct trap_per_cpu *tb = &trap_block[this_cpu]; | 834 | struct trap_per_cpu *tb = &trap_block[this_cpu]; |
713 | 835 | ||
714 | register_one_mondo(tb->cpu_mondo_pa, HV_CPU_QUEUE_CPU_MONDO); | 836 | register_one_mondo(tb->cpu_mondo_pa, HV_CPU_QUEUE_CPU_MONDO, |
715 | register_one_mondo(tb->dev_mondo_pa, HV_CPU_QUEUE_DEVICE_MONDO); | 837 | tb->cpu_mondo_qmask); |
716 | register_one_mondo(tb->resum_mondo_pa, HV_CPU_QUEUE_RES_ERROR); | 838 | register_one_mondo(tb->dev_mondo_pa, HV_CPU_QUEUE_DEVICE_MONDO, |
717 | register_one_mondo(tb->nonresum_mondo_pa, HV_CPU_QUEUE_NONRES_ERROR); | 839 | tb->dev_mondo_qmask); |
840 | register_one_mondo(tb->resum_mondo_pa, HV_CPU_QUEUE_RES_ERROR, | ||
841 | tb->resum_qmask); | ||
842 | register_one_mondo(tb->nonresum_mondo_pa, HV_CPU_QUEUE_NONRES_ERROR, | ||
843 | tb->nonresum_qmask); | ||
718 | } | 844 | } |
719 | 845 | ||
720 | static void __cpuinit alloc_one_mondo(unsigned long *pa_ptr, int use_bootmem) | 846 | static void __cpuinit alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask, int use_bootmem) |
721 | { | 847 | { |
722 | void *page; | 848 | unsigned long size = PAGE_ALIGN(qmask + 1); |
849 | unsigned long order = get_order(size); | ||
850 | void *p = NULL; | ||
723 | 851 | ||
724 | if (use_bootmem) | 852 | if (use_bootmem) { |
725 | page = alloc_bootmem_low_pages(PAGE_SIZE); | 853 | p = __alloc_bootmem_low(size, size, 0); |
726 | else | 854 | } else { |
727 | page = (void *) get_zeroed_page(GFP_ATOMIC); | 855 | struct page *page = alloc_pages(GFP_ATOMIC | __GFP_ZERO, order); |
856 | if (page) | ||
857 | p = page_address(page); | ||
858 | } | ||
728 | 859 | ||
729 | if (!page) { | 860 | if (!p) { |
730 | prom_printf("SUN4V: Error, cannot allocate mondo queue.\n"); | 861 | prom_printf("SUN4V: Error, cannot allocate mondo queue.\n"); |
731 | prom_halt(); | 862 | prom_halt(); |
732 | } | 863 | } |
733 | 864 | ||
734 | *pa_ptr = __pa(page); | 865 | *pa_ptr = __pa(p); |
735 | } | 866 | } |
736 | 867 | ||
737 | static void __cpuinit alloc_one_kbuf(unsigned long *pa_ptr, int use_bootmem) | 868 | static void __cpuinit alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask, int use_bootmem) |
738 | { | 869 | { |
739 | void *page; | 870 | unsigned long size = PAGE_ALIGN(qmask + 1); |
871 | unsigned long order = get_order(size); | ||
872 | void *p = NULL; | ||
740 | 873 | ||
741 | if (use_bootmem) | 874 | if (use_bootmem) { |
742 | page = alloc_bootmem_low_pages(PAGE_SIZE); | 875 | p = __alloc_bootmem_low(size, size, 0); |
743 | else | 876 | } else { |
744 | page = (void *) get_zeroed_page(GFP_ATOMIC); | 877 | struct page *page = alloc_pages(GFP_ATOMIC | __GFP_ZERO, order); |
878 | if (page) | ||
879 | p = page_address(page); | ||
880 | } | ||
745 | 881 | ||
746 | if (!page) { | 882 | if (!p) { |
747 | prom_printf("SUN4V: Error, cannot allocate kbuf page.\n"); | 883 | prom_printf("SUN4V: Error, cannot allocate kbuf page.\n"); |
748 | prom_halt(); | 884 | prom_halt(); |
749 | } | 885 | } |
750 | 886 | ||
751 | *pa_ptr = __pa(page); | 887 | *pa_ptr = __pa(p); |
752 | } | 888 | } |
753 | 889 | ||
754 | static void __cpuinit init_cpu_send_mondo_info(struct trap_per_cpu *tb, int use_bootmem) | 890 | static void __cpuinit init_cpu_send_mondo_info(struct trap_per_cpu *tb, int use_bootmem) |
@@ -779,12 +915,12 @@ void __cpuinit sun4v_init_mondo_queues(int use_bootmem, int cpu, int alloc, int | |||
779 | struct trap_per_cpu *tb = &trap_block[cpu]; | 915 | struct trap_per_cpu *tb = &trap_block[cpu]; |
780 | 916 | ||
781 | if (alloc) { | 917 | if (alloc) { |
782 | alloc_one_mondo(&tb->cpu_mondo_pa, use_bootmem); | 918 | alloc_one_mondo(&tb->cpu_mondo_pa, tb->cpu_mondo_qmask, use_bootmem); |
783 | alloc_one_mondo(&tb->dev_mondo_pa, use_bootmem); | 919 | alloc_one_mondo(&tb->dev_mondo_pa, tb->dev_mondo_qmask, use_bootmem); |
784 | alloc_one_mondo(&tb->resum_mondo_pa, use_bootmem); | 920 | alloc_one_mondo(&tb->resum_mondo_pa, tb->resum_qmask, use_bootmem); |
785 | alloc_one_kbuf(&tb->resum_kernel_buf_pa, use_bootmem); | 921 | alloc_one_kbuf(&tb->resum_kernel_buf_pa, tb->resum_qmask, use_bootmem); |
786 | alloc_one_mondo(&tb->nonresum_mondo_pa, use_bootmem); | 922 | alloc_one_mondo(&tb->nonresum_mondo_pa, tb->nonresum_qmask, use_bootmem); |
787 | alloc_one_kbuf(&tb->nonresum_kernel_buf_pa, use_bootmem); | 923 | alloc_one_kbuf(&tb->nonresum_kernel_buf_pa, tb->nonresum_qmask, use_bootmem); |
788 | 924 | ||
789 | init_cpu_send_mondo_info(tb, use_bootmem); | 925 | init_cpu_send_mondo_info(tb, use_bootmem); |
790 | } | 926 | } |
diff --git a/arch/sparc64/kernel/itlb_miss.S b/arch/sparc64/kernel/itlb_miss.S index ad46e2024f4b..5a8377b54955 100644 --- a/arch/sparc64/kernel/itlb_miss.S +++ b/arch/sparc64/kernel/itlb_miss.S | |||
@@ -11,12 +11,12 @@ | |||
11 | /* ITLB ** ICACHE line 2: TSB compare and TLB load */ | 11 | /* ITLB ** ICACHE line 2: TSB compare and TLB load */ |
12 | bne,pn %xcc, tsb_miss_itlb ! Miss | 12 | bne,pn %xcc, tsb_miss_itlb ! Miss |
13 | mov FAULT_CODE_ITLB, %g3 | 13 | mov FAULT_CODE_ITLB, %g3 |
14 | andcc %g5, _PAGE_EXEC_4U, %g0 ! Executable? | 14 | sethi %hi(_PAGE_EXEC_4U), %g4 |
15 | andcc %g5, %g4, %g0 ! Executable? | ||
15 | be,pn %xcc, tsb_do_fault | 16 | be,pn %xcc, tsb_do_fault |
16 | nop ! Delay slot, fill me | 17 | nop ! Delay slot, fill me |
17 | stxa %g5, [%g0] ASI_ITLB_DATA_IN ! Load TLB | 18 | stxa %g5, [%g0] ASI_ITLB_DATA_IN ! Load TLB |
18 | retry ! Trap done | 19 | retry ! Trap done |
19 | nop | ||
20 | 20 | ||
21 | /* ITLB ** ICACHE line 3: */ | 21 | /* ITLB ** ICACHE line 3: */ |
22 | nop | 22 | nop |
diff --git a/arch/sparc64/kernel/mdesc.c b/arch/sparc64/kernel/mdesc.c new file mode 100644 index 000000000000..f0e16045fb16 --- /dev/null +++ b/arch/sparc64/kernel/mdesc.c | |||
@@ -0,0 +1,672 @@ | |||
1 | /* mdesc.c: Sun4V machine description handling. | ||
2 | * | ||
3 | * Copyright (C) 2007 David S. Miller <davem@davemloft.net> | ||
4 | */ | ||
5 | #include <linux/kernel.h> | ||
6 | #include <linux/types.h> | ||
7 | #include <linux/bootmem.h> | ||
8 | #include <linux/log2.h> | ||
9 | |||
10 | #include <asm/hypervisor.h> | ||
11 | #include <asm/mdesc.h> | ||
12 | #include <asm/prom.h> | ||
13 | #include <asm/oplib.h> | ||
14 | #include <asm/smp.h> | ||
15 | |||
16 | /* Unlike the OBP device tree, the machine description is a full-on | ||
17 | * DAG. An arbitrary number of ARCs are possible from one | ||
18 | * node to other nodes and thus we can't use the OBP device_node | ||
19 | * data structure to represent these nodes inside of the kernel. | ||
20 | * | ||
21 | * Actually, it isn't even a DAG, because there are back pointers | ||
22 | * which create cycles in the graph. | ||
23 | * | ||
24 | * mdesc_hdr and mdesc_elem describe the layout of the data structure | ||
25 | * we get from the Hypervisor. | ||
26 | */ | ||
27 | struct mdesc_hdr { | ||
28 | u32 version; /* Transport version */ | ||
29 | u32 node_sz; /* node block size */ | ||
30 | u32 name_sz; /* name block size */ | ||
31 | u32 data_sz; /* data block size */ | ||
32 | }; | ||
33 | |||
34 | struct mdesc_elem { | ||
35 | u8 tag; | ||
36 | #define MD_LIST_END 0x00 | ||
37 | #define MD_NODE 0x4e | ||
38 | #define MD_NODE_END 0x45 | ||
39 | #define MD_NOOP 0x20 | ||
40 | #define MD_PROP_ARC 0x61 | ||
41 | #define MD_PROP_VAL 0x76 | ||
42 | #define MD_PROP_STR 0x73 | ||
43 | #define MD_PROP_DATA 0x64 | ||
44 | u8 name_len; | ||
45 | u16 resv; | ||
46 | u32 name_offset; | ||
47 | union { | ||
48 | struct { | ||
49 | u32 data_len; | ||
50 | u32 data_offset; | ||
51 | } data; | ||
52 | u64 val; | ||
53 | } d; | ||
54 | }; | ||
55 | |||
56 | static struct mdesc_hdr *main_mdesc; | ||
57 | static struct mdesc_node *allnodes; | ||
58 | |||
59 | static struct mdesc_node *allnodes_tail; | ||
60 | static unsigned int unique_id; | ||
61 | |||
62 | static struct mdesc_node **mdesc_hash; | ||
63 | static unsigned int mdesc_hash_size; | ||
64 | |||
65 | static inline unsigned int node_hashfn(u64 node) | ||
66 | { | ||
67 | return ((unsigned int) (node ^ (node >> 8) ^ (node >> 16))) | ||
68 | & (mdesc_hash_size - 1); | ||
69 | } | ||
70 | |||
71 | static inline void hash_node(struct mdesc_node *mp) | ||
72 | { | ||
73 | struct mdesc_node **head = &mdesc_hash[node_hashfn(mp->node)]; | ||
74 | |||
75 | mp->hash_next = *head; | ||
76 | *head = mp; | ||
77 | |||
78 | if (allnodes_tail) { | ||
79 | allnodes_tail->allnodes_next = mp; | ||
80 | allnodes_tail = mp; | ||
81 | } else { | ||
82 | allnodes = allnodes_tail = mp; | ||
83 | } | ||
84 | } | ||
85 | |||
86 | static struct mdesc_node *find_node(u64 node) | ||
87 | { | ||
88 | struct mdesc_node *mp = mdesc_hash[node_hashfn(node)]; | ||
89 | |||
90 | while (mp) { | ||
91 | if (mp->node == node) | ||
92 | return mp; | ||
93 | |||
94 | mp = mp->hash_next; | ||
95 | } | ||
96 | return NULL; | ||
97 | } | ||
98 | |||
99 | struct property *md_find_property(const struct mdesc_node *mp, | ||
100 | const char *name, | ||
101 | int *lenp) | ||
102 | { | ||
103 | struct property *pp; | ||
104 | |||
105 | for (pp = mp->properties; pp != 0; pp = pp->next) { | ||
106 | if (strcasecmp(pp->name, name) == 0) { | ||
107 | if (lenp) | ||
108 | *lenp = pp->length; | ||
109 | break; | ||
110 | } | ||
111 | } | ||
112 | return pp; | ||
113 | } | ||
114 | EXPORT_SYMBOL(md_find_property); | ||
115 | |||
116 | /* | ||
117 | * Find a property with a given name for a given node | ||
118 | * and return the value. | ||
119 | */ | ||
120 | const void *md_get_property(const struct mdesc_node *mp, const char *name, | ||
121 | int *lenp) | ||
122 | { | ||
123 | struct property *pp = md_find_property(mp, name, lenp); | ||
124 | return pp ? pp->value : NULL; | ||
125 | } | ||
126 | EXPORT_SYMBOL(md_get_property); | ||
127 | |||
128 | struct mdesc_node *md_find_node_by_name(struct mdesc_node *from, | ||
129 | const char *name) | ||
130 | { | ||
131 | struct mdesc_node *mp; | ||
132 | |||
133 | mp = from ? from->allnodes_next : allnodes; | ||
134 | for (; mp != NULL; mp = mp->allnodes_next) { | ||
135 | if (strcmp(mp->name, name) == 0) | ||
136 | break; | ||
137 | } | ||
138 | return mp; | ||
139 | } | ||
140 | EXPORT_SYMBOL(md_find_node_by_name); | ||
141 | |||
142 | static unsigned int mdesc_early_allocated; | ||
143 | |||
144 | static void * __init mdesc_early_alloc(unsigned long size) | ||
145 | { | ||
146 | void *ret; | ||
147 | |||
148 | ret = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL); | ||
149 | if (ret == NULL) { | ||
150 | prom_printf("MDESC: alloc of %lu bytes failed.\n", size); | ||
151 | prom_halt(); | ||
152 | } | ||
153 | |||
154 | memset(ret, 0, size); | ||
155 | |||
156 | mdesc_early_allocated += size; | ||
157 | |||
158 | return ret; | ||
159 | } | ||
160 | |||
161 | static unsigned int __init count_arcs(struct mdesc_elem *ep) | ||
162 | { | ||
163 | unsigned int ret = 0; | ||
164 | |||
165 | ep++; | ||
166 | while (ep->tag != MD_NODE_END) { | ||
167 | if (ep->tag == MD_PROP_ARC) | ||
168 | ret++; | ||
169 | ep++; | ||
170 | } | ||
171 | return ret; | ||
172 | } | ||
173 | |||
174 | static void __init mdesc_node_alloc(u64 node, struct mdesc_elem *ep, const char *names) | ||
175 | { | ||
176 | unsigned int num_arcs = count_arcs(ep); | ||
177 | struct mdesc_node *mp; | ||
178 | |||
179 | mp = mdesc_early_alloc(sizeof(*mp) + | ||
180 | (num_arcs * sizeof(struct mdesc_arc))); | ||
181 | mp->name = names + ep->name_offset; | ||
182 | mp->node = node; | ||
183 | mp->unique_id = unique_id++; | ||
184 | mp->num_arcs = num_arcs; | ||
185 | |||
186 | hash_node(mp); | ||
187 | } | ||
188 | |||
189 | static inline struct mdesc_elem *node_block(struct mdesc_hdr *mdesc) | ||
190 | { | ||
191 | return (struct mdesc_elem *) (mdesc + 1); | ||
192 | } | ||
193 | |||
194 | static inline void *name_block(struct mdesc_hdr *mdesc) | ||
195 | { | ||
196 | return ((void *) node_block(mdesc)) + mdesc->node_sz; | ||
197 | } | ||
198 | |||
199 | static inline void *data_block(struct mdesc_hdr *mdesc) | ||
200 | { | ||
201 | return ((void *) name_block(mdesc)) + mdesc->name_sz; | ||
202 | } | ||
203 | |||
204 | /* In order to avoid recursion (the graph can be very deep) we use a | ||
205 | * two pass algorithm. First we allocate all the nodes and hash them. | ||
206 | * Then we iterate over each node, filling in the arcs and properties. | ||
207 | */ | ||
208 | static void __init build_all_nodes(struct mdesc_hdr *mdesc) | ||
209 | { | ||
210 | struct mdesc_elem *start, *ep; | ||
211 | struct mdesc_node *mp; | ||
212 | const char *names; | ||
213 | void *data; | ||
214 | u64 last_node; | ||
215 | |||
216 | start = ep = node_block(mdesc); | ||
217 | last_node = mdesc->node_sz / 16; | ||
218 | |||
219 | names = name_block(mdesc); | ||
220 | |||
221 | while (1) { | ||
222 | u64 node = ep - start; | ||
223 | |||
224 | if (ep->tag == MD_LIST_END) | ||
225 | break; | ||
226 | |||
227 | if (ep->tag != MD_NODE) { | ||
228 | prom_printf("MDESC: Inconsistent element list.\n"); | ||
229 | prom_halt(); | ||
230 | } | ||
231 | |||
232 | mdesc_node_alloc(node, ep, names); | ||
233 | |||
234 | if (ep->d.val >= last_node) { | ||
235 | printk("MDESC: Warning, early break out of node scan.\n"); | ||
236 | printk("MDESC: Next node [%lu] last_node [%lu].\n", | ||
237 | node, last_node); | ||
238 | break; | ||
239 | } | ||
240 | |||
241 | ep = start + ep->d.val; | ||
242 | } | ||
243 | |||
244 | data = data_block(mdesc); | ||
245 | for (mp = allnodes; mp; mp = mp->allnodes_next) { | ||
246 | struct mdesc_elem *ep = start + mp->node; | ||
247 | struct property **link = &mp->properties; | ||
248 | unsigned int this_arc = 0; | ||
249 | |||
250 | ep++; | ||
251 | while (ep->tag != MD_NODE_END) { | ||
252 | switch (ep->tag) { | ||
253 | case MD_PROP_ARC: { | ||
254 | struct mdesc_node *target; | ||
255 | |||
256 | if (this_arc >= mp->num_arcs) { | ||
257 | prom_printf("MDESC: ARC overrun [%u:%u]\n", | ||
258 | this_arc, mp->num_arcs); | ||
259 | prom_halt(); | ||
260 | } | ||
261 | target = find_node(ep->d.val); | ||
262 | if (!target) { | ||
263 | printk("MDESC: Warning, arc points to " | ||
264 | "missing node, ignoring.\n"); | ||
265 | break; | ||
266 | } | ||
267 | mp->arcs[this_arc].name = | ||
268 | (names + ep->name_offset); | ||
269 | mp->arcs[this_arc].arc = target; | ||
270 | this_arc++; | ||
271 | break; | ||
272 | } | ||
273 | |||
274 | case MD_PROP_VAL: | ||
275 | case MD_PROP_STR: | ||
276 | case MD_PROP_DATA: { | ||
277 | struct property *p = mdesc_early_alloc(sizeof(*p)); | ||
278 | |||
279 | p->unique_id = unique_id++; | ||
280 | p->name = (char *) names + ep->name_offset; | ||
281 | if (ep->tag == MD_PROP_VAL) { | ||
282 | p->value = &ep->d.val; | ||
283 | p->length = 8; | ||
284 | } else { | ||
285 | p->value = data + ep->d.data.data_offset; | ||
286 | p->length = ep->d.data.data_len; | ||
287 | } | ||
288 | *link = p; | ||
289 | link = &p->next; | ||
290 | break; | ||
291 | } | ||
292 | |||
293 | case MD_NOOP: | ||
294 | break; | ||
295 | |||
296 | default: | ||
297 | printk("MDESC: Warning, ignoring unknown tag type %02x\n", | ||
298 | ep->tag); | ||
299 | } | ||
300 | ep++; | ||
301 | } | ||
302 | } | ||
303 | } | ||
304 | |||
305 | static unsigned int __init count_nodes(struct mdesc_hdr *mdesc) | ||
306 | { | ||
307 | struct mdesc_elem *ep = node_block(mdesc); | ||
308 | struct mdesc_elem *end; | ||
309 | unsigned int cnt = 0; | ||
310 | |||
311 | end = ((void *)ep) + mdesc->node_sz; | ||
312 | while (ep < end) { | ||
313 | if (ep->tag == MD_NODE) | ||
314 | cnt++; | ||
315 | ep++; | ||
316 | } | ||
317 | return cnt; | ||
318 | } | ||
319 | |||
320 | static void __init report_platform_properties(void) | ||
321 | { | ||
322 | struct mdesc_node *pn = md_find_node_by_name(NULL, "platform"); | ||
323 | const char *s; | ||
324 | const u64 *v; | ||
325 | |||
326 | if (!pn) { | ||
327 | prom_printf("No platform node in machine-description.\n"); | ||
328 | prom_halt(); | ||
329 | } | ||
330 | |||
331 | s = md_get_property(pn, "banner-name", NULL); | ||
332 | printk("PLATFORM: banner-name [%s]\n", s); | ||
333 | s = md_get_property(pn, "name", NULL); | ||
334 | printk("PLATFORM: name [%s]\n", s); | ||
335 | |||
336 | v = md_get_property(pn, "hostid", NULL); | ||
337 | if (v) | ||
338 | printk("PLATFORM: hostid [%08lx]\n", *v); | ||
339 | v = md_get_property(pn, "serial#", NULL); | ||
340 | if (v) | ||
341 | printk("PLATFORM: serial# [%08lx]\n", *v); | ||
342 | v = md_get_property(pn, "stick-frequency", NULL); | ||
343 | printk("PLATFORM: stick-frequency [%08lx]\n", *v); | ||
344 | v = md_get_property(pn, "mac-address", NULL); | ||
345 | if (v) | ||
346 | printk("PLATFORM: mac-address [%lx]\n", *v); | ||
347 | v = md_get_property(pn, "watchdog-resolution", NULL); | ||
348 | if (v) | ||
349 | printk("PLATFORM: watchdog-resolution [%lu ms]\n", *v); | ||
350 | v = md_get_property(pn, "watchdog-max-timeout", NULL); | ||
351 | if (v) | ||
352 | printk("PLATFORM: watchdog-max-timeout [%lu ms]\n", *v); | ||
353 | v = md_get_property(pn, "max-cpus", NULL); | ||
354 | if (v) | ||
355 | printk("PLATFORM: max-cpus [%lu]\n", *v); | ||
356 | } | ||
357 | |||
358 | static int inline find_in_proplist(const char *list, const char *match, int len) | ||
359 | { | ||
360 | while (len > 0) { | ||
361 | int l; | ||
362 | |||
363 | if (!strcmp(list, match)) | ||
364 | return 1; | ||
365 | l = strlen(list) + 1; | ||
366 | list += l; | ||
367 | len -= l; | ||
368 | } | ||
369 | return 0; | ||
370 | } | ||
371 | |||
372 | static void __init fill_in_one_cache(cpuinfo_sparc *c, struct mdesc_node *mp) | ||
373 | { | ||
374 | const u64 *level = md_get_property(mp, "level", NULL); | ||
375 | const u64 *size = md_get_property(mp, "size", NULL); | ||
376 | const u64 *line_size = md_get_property(mp, "line-size", NULL); | ||
377 | const char *type; | ||
378 | int type_len; | ||
379 | |||
380 | type = md_get_property(mp, "type", &type_len); | ||
381 | |||
382 | switch (*level) { | ||
383 | case 1: | ||
384 | if (find_in_proplist(type, "instn", type_len)) { | ||
385 | c->icache_size = *size; | ||
386 | c->icache_line_size = *line_size; | ||
387 | } else if (find_in_proplist(type, "data", type_len)) { | ||
388 | c->dcache_size = *size; | ||
389 | c->dcache_line_size = *line_size; | ||
390 | } | ||
391 | break; | ||
392 | |||
393 | case 2: | ||
394 | c->ecache_size = *size; | ||
395 | c->ecache_line_size = *line_size; | ||
396 | break; | ||
397 | |||
398 | default: | ||
399 | break; | ||
400 | } | ||
401 | |||
402 | if (*level == 1) { | ||
403 | unsigned int i; | ||
404 | |||
405 | for (i = 0; i < mp->num_arcs; i++) { | ||
406 | struct mdesc_node *t = mp->arcs[i].arc; | ||
407 | |||
408 | if (strcmp(mp->arcs[i].name, "fwd")) | ||
409 | continue; | ||
410 | |||
411 | if (!strcmp(t->name, "cache")) | ||
412 | fill_in_one_cache(c, t); | ||
413 | } | ||
414 | } | ||
415 | } | ||
416 | |||
417 | static void __init mark_core_ids(struct mdesc_node *mp, int core_id) | ||
418 | { | ||
419 | unsigned int i; | ||
420 | |||
421 | for (i = 0; i < mp->num_arcs; i++) { | ||
422 | struct mdesc_node *t = mp->arcs[i].arc; | ||
423 | const u64 *id; | ||
424 | |||
425 | if (strcmp(mp->arcs[i].name, "back")) | ||
426 | continue; | ||
427 | |||
428 | if (!strcmp(t->name, "cpu")) { | ||
429 | id = md_get_property(t, "id", NULL); | ||
430 | if (*id < NR_CPUS) | ||
431 | cpu_data(*id).core_id = core_id; | ||
432 | } else { | ||
433 | unsigned int j; | ||
434 | |||
435 | for (j = 0; j < t->num_arcs; j++) { | ||
436 | struct mdesc_node *n = t->arcs[j].arc; | ||
437 | |||
438 | if (strcmp(t->arcs[j].name, "back")) | ||
439 | continue; | ||
440 | |||
441 | if (strcmp(n->name, "cpu")) | ||
442 | continue; | ||
443 | |||
444 | id = md_get_property(n, "id", NULL); | ||
445 | if (*id < NR_CPUS) | ||
446 | cpu_data(*id).core_id = core_id; | ||
447 | } | ||
448 | } | ||
449 | } | ||
450 | } | ||
451 | |||
452 | static void __init set_core_ids(void) | ||
453 | { | ||
454 | struct mdesc_node *mp; | ||
455 | int idx; | ||
456 | |||
457 | idx = 1; | ||
458 | md_for_each_node_by_name(mp, "cache") { | ||
459 | const u64 *level = md_get_property(mp, "level", NULL); | ||
460 | const char *type; | ||
461 | int len; | ||
462 | |||
463 | if (*level != 1) | ||
464 | continue; | ||
465 | |||
466 | type = md_get_property(mp, "type", &len); | ||
467 | if (!find_in_proplist(type, "instn", len)) | ||
468 | continue; | ||
469 | |||
470 | mark_core_ids(mp, idx); | ||
471 | |||
472 | idx++; | ||
473 | } | ||
474 | } | ||
475 | |||
476 | static void __init mark_proc_ids(struct mdesc_node *mp, int proc_id) | ||
477 | { | ||
478 | int i; | ||
479 | |||
480 | for (i = 0; i < mp->num_arcs; i++) { | ||
481 | struct mdesc_node *t = mp->arcs[i].arc; | ||
482 | const u64 *id; | ||
483 | |||
484 | if (strcmp(mp->arcs[i].name, "back")) | ||
485 | continue; | ||
486 | |||
487 | if (strcmp(t->name, "cpu")) | ||
488 | continue; | ||
489 | |||
490 | id = md_get_property(t, "id", NULL); | ||
491 | if (*id < NR_CPUS) | ||
492 | cpu_data(*id).proc_id = proc_id; | ||
493 | } | ||
494 | } | ||
495 | |||
496 | static void __init __set_proc_ids(const char *exec_unit_name) | ||
497 | { | ||
498 | struct mdesc_node *mp; | ||
499 | int idx; | ||
500 | |||
501 | idx = 0; | ||
502 | md_for_each_node_by_name(mp, exec_unit_name) { | ||
503 | const char *type; | ||
504 | int len; | ||
505 | |||
506 | type = md_get_property(mp, "type", &len); | ||
507 | if (!find_in_proplist(type, "int", len) && | ||
508 | !find_in_proplist(type, "integer", len)) | ||
509 | continue; | ||
510 | |||
511 | mark_proc_ids(mp, idx); | ||
512 | |||
513 | idx++; | ||
514 | } | ||
515 | } | ||
516 | |||
517 | static void __init set_proc_ids(void) | ||
518 | { | ||
519 | __set_proc_ids("exec_unit"); | ||
520 | __set_proc_ids("exec-unit"); | ||
521 | } | ||
522 | |||
523 | static void __init get_one_mondo_bits(const u64 *p, unsigned int *mask, unsigned char def) | ||
524 | { | ||
525 | u64 val; | ||
526 | |||
527 | if (!p) | ||
528 | goto use_default; | ||
529 | val = *p; | ||
530 | |||
531 | if (!val || val >= 64) | ||
532 | goto use_default; | ||
533 | |||
534 | *mask = ((1U << val) * 64U) - 1U; | ||
535 | return; | ||
536 | |||
537 | use_default: | ||
538 | *mask = ((1U << def) * 64U) - 1U; | ||
539 | } | ||
540 | |||
541 | static void __init get_mondo_data(struct mdesc_node *mp, struct trap_per_cpu *tb) | ||
542 | { | ||
543 | const u64 *val; | ||
544 | |||
545 | val = md_get_property(mp, "q-cpu-mondo-#bits", NULL); | ||
546 | get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7); | ||
547 | |||
548 | val = md_get_property(mp, "q-dev-mondo-#bits", NULL); | ||
549 | get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7); | ||
550 | |||
551 | val = md_get_property(mp, "q-resumable-#bits", NULL); | ||
552 | get_one_mondo_bits(val, &tb->resum_qmask, 6); | ||
553 | |||
554 | val = md_get_property(mp, "q-nonresumable-#bits", NULL); | ||
555 | get_one_mondo_bits(val, &tb->nonresum_qmask, 2); | ||
556 | } | ||
557 | |||
558 | static void __init mdesc_fill_in_cpu_data(void) | ||
559 | { | ||
560 | struct mdesc_node *mp; | ||
561 | |||
562 | ncpus_probed = 0; | ||
563 | md_for_each_node_by_name(mp, "cpu") { | ||
564 | const u64 *id = md_get_property(mp, "id", NULL); | ||
565 | const u64 *cfreq = md_get_property(mp, "clock-frequency", NULL); | ||
566 | struct trap_per_cpu *tb; | ||
567 | cpuinfo_sparc *c; | ||
568 | unsigned int i; | ||
569 | int cpuid; | ||
570 | |||
571 | ncpus_probed++; | ||
572 | |||
573 | cpuid = *id; | ||
574 | |||
575 | #ifdef CONFIG_SMP | ||
576 | if (cpuid >= NR_CPUS) | ||
577 | continue; | ||
578 | #else | ||
579 | /* On uniprocessor we only want the values for the | ||
580 | * real physical cpu the kernel booted onto, however | ||
581 | * cpu_data() only has one entry at index 0. | ||
582 | */ | ||
583 | if (cpuid != real_hard_smp_processor_id()) | ||
584 | continue; | ||
585 | cpuid = 0; | ||
586 | #endif | ||
587 | |||
588 | c = &cpu_data(cpuid); | ||
589 | c->clock_tick = *cfreq; | ||
590 | |||
591 | tb = &trap_block[cpuid]; | ||
592 | get_mondo_data(mp, tb); | ||
593 | |||
594 | for (i = 0; i < mp->num_arcs; i++) { | ||
595 | struct mdesc_node *t = mp->arcs[i].arc; | ||
596 | unsigned int j; | ||
597 | |||
598 | if (strcmp(mp->arcs[i].name, "fwd")) | ||
599 | continue; | ||
600 | |||
601 | if (!strcmp(t->name, "cache")) { | ||
602 | fill_in_one_cache(c, t); | ||
603 | continue; | ||
604 | } | ||
605 | |||
606 | for (j = 0; j < t->num_arcs; j++) { | ||
607 | struct mdesc_node *n; | ||
608 | |||
609 | n = t->arcs[j].arc; | ||
610 | if (strcmp(t->arcs[j].name, "fwd")) | ||
611 | continue; | ||
612 | |||
613 | if (!strcmp(n->name, "cache")) | ||
614 | fill_in_one_cache(c, n); | ||
615 | } | ||
616 | } | ||
617 | |||
618 | #ifdef CONFIG_SMP | ||
619 | cpu_set(cpuid, cpu_present_map); | ||
620 | cpu_set(cpuid, phys_cpu_present_map); | ||
621 | #endif | ||
622 | |||
623 | c->core_id = 0; | ||
624 | c->proc_id = -1; | ||
625 | } | ||
626 | |||
627 | #ifdef CONFIG_SMP | ||
628 | sparc64_multi_core = 1; | ||
629 | #endif | ||
630 | |||
631 | set_core_ids(); | ||
632 | set_proc_ids(); | ||
633 | |||
634 | smp_fill_in_sib_core_maps(); | ||
635 | } | ||
636 | |||
637 | void __init sun4v_mdesc_init(void) | ||
638 | { | ||
639 | unsigned long len, real_len, status; | ||
640 | |||
641 | (void) sun4v_mach_desc(0UL, 0UL, &len); | ||
642 | |||
643 | printk("MDESC: Size is %lu bytes.\n", len); | ||
644 | |||
645 | main_mdesc = mdesc_early_alloc(len); | ||
646 | |||
647 | status = sun4v_mach_desc(__pa(main_mdesc), len, &real_len); | ||
648 | if (status != HV_EOK || real_len > len) { | ||
649 | prom_printf("sun4v_mach_desc fails, err(%lu), " | ||
650 | "len(%lu), real_len(%lu)\n", | ||
651 | status, len, real_len); | ||
652 | prom_halt(); | ||
653 | } | ||
654 | |||
655 | len = count_nodes(main_mdesc); | ||
656 | printk("MDESC: %lu nodes.\n", len); | ||
657 | |||
658 | len = roundup_pow_of_two(len); | ||
659 | |||
660 | mdesc_hash = mdesc_early_alloc(len * sizeof(struct mdesc_node *)); | ||
661 | mdesc_hash_size = len; | ||
662 | |||
663 | printk("MDESC: Hash size %lu entries.\n", len); | ||
664 | |||
665 | build_all_nodes(main_mdesc); | ||
666 | |||
667 | printk("MDESC: Built graph with %u bytes of memory.\n", | ||
668 | mdesc_early_allocated); | ||
669 | |||
670 | report_platform_properties(); | ||
671 | mdesc_fill_in_cpu_data(); | ||
672 | } | ||
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index 16cc46a71872..6676b93219dc 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c | |||
@@ -343,6 +343,15 @@ static int of_bus_simba_match(struct device_node *np) | |||
343 | 343 | ||
344 | if (model && !strcmp(model, "SUNW,simba")) | 344 | if (model && !strcmp(model, "SUNW,simba")) |
345 | return 1; | 345 | return 1; |
346 | |||
347 | /* Treat PCI busses lacking ranges property just like | ||
348 | * simba. | ||
349 | */ | ||
350 | if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) { | ||
351 | if (!of_find_property(np, "ranges", NULL)) | ||
352 | return 1; | ||
353 | } | ||
354 | |||
346 | return 0; | 355 | return 0; |
347 | } | 356 | } |
348 | 357 | ||
@@ -549,8 +558,6 @@ static int __init build_one_resource(struct device_node *parent, | |||
549 | 558 | ||
550 | static int __init use_1to1_mapping(struct device_node *pp) | 559 | static int __init use_1to1_mapping(struct device_node *pp) |
551 | { | 560 | { |
552 | const char *model; | ||
553 | |||
554 | /* If this is on the PMU bus, don't try to translate it even | 561 | /* If this is on the PMU bus, don't try to translate it even |
555 | * if a ranges property exists. | 562 | * if a ranges property exists. |
556 | */ | 563 | */ |
@@ -567,9 +574,11 @@ static int __init use_1to1_mapping(struct device_node *pp) | |||
567 | if (!strcmp(pp->name, "dma")) | 574 | if (!strcmp(pp->name, "dma")) |
568 | return 0; | 575 | return 0; |
569 | 576 | ||
570 | /* Similarly for Simba PCI bridges. */ | 577 | /* Similarly for all PCI bridges, if we get this far |
571 | model = of_get_property(pp, "model", NULL); | 578 | * it lacks a ranges property, and this will include |
572 | if (model && !strcmp(model, "SUNW,simba")) | 579 | * cases like Simba. |
580 | */ | ||
581 | if (!strcmp(pp->type, "pci") || !strcmp(pp->type, "pciex")) | ||
573 | return 0; | 582 | return 0; |
574 | 583 | ||
575 | return 1; | 584 | return 1; |
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index d4c077dc5e85..81f4a5ea05f7 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c | |||
@@ -306,6 +306,20 @@ static void __init pci_controller_probe(void) | |||
306 | pci_controller_scan(pci_controller_init); | 306 | pci_controller_scan(pci_controller_init); |
307 | } | 307 | } |
308 | 308 | ||
309 | static int ofpci_verbose; | ||
310 | |||
311 | static int __init ofpci_debug(char *str) | ||
312 | { | ||
313 | int val = 0; | ||
314 | |||
315 | get_option(&str, &val); | ||
316 | if (val) | ||
317 | ofpci_verbose = 1; | ||
318 | return 1; | ||
319 | } | ||
320 | |||
321 | __setup("ofpci_debug=", ofpci_debug); | ||
322 | |||
309 | static unsigned long pci_parse_of_flags(u32 addr0) | 323 | static unsigned long pci_parse_of_flags(u32 addr0) |
310 | { | 324 | { |
311 | unsigned long flags = 0; | 325 | unsigned long flags = 0; |
@@ -337,7 +351,9 @@ static void pci_parse_of_addrs(struct of_device *op, | |||
337 | addrs = of_get_property(node, "assigned-addresses", &proplen); | 351 | addrs = of_get_property(node, "assigned-addresses", &proplen); |
338 | if (!addrs) | 352 | if (!addrs) |
339 | return; | 353 | return; |
340 | printk(" parse addresses (%d bytes) @ %p\n", proplen, addrs); | 354 | if (ofpci_verbose) |
355 | printk(" parse addresses (%d bytes) @ %p\n", | ||
356 | proplen, addrs); | ||
341 | op_res = &op->resource[0]; | 357 | op_res = &op->resource[0]; |
342 | for (; proplen >= 20; proplen -= 20, addrs += 5, op_res++) { | 358 | for (; proplen >= 20; proplen -= 20, addrs += 5, op_res++) { |
343 | struct resource *res; | 359 | struct resource *res; |
@@ -348,8 +364,9 @@ static void pci_parse_of_addrs(struct of_device *op, | |||
348 | if (!flags) | 364 | if (!flags) |
349 | continue; | 365 | continue; |
350 | i = addrs[0] & 0xff; | 366 | i = addrs[0] & 0xff; |
351 | printk(" start: %lx, end: %lx, i: %x\n", | 367 | if (ofpci_verbose) |
352 | op_res->start, op_res->end, i); | 368 | printk(" start: %lx, end: %lx, i: %x\n", |
369 | op_res->start, op_res->end, i); | ||
353 | 370 | ||
354 | if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) { | 371 | if (PCI_BASE_ADDRESS_0 <= i && i <= PCI_BASE_ADDRESS_5) { |
355 | res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2]; | 372 | res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2]; |
@@ -393,8 +410,9 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, | |||
393 | if (type == NULL) | 410 | if (type == NULL) |
394 | type = ""; | 411 | type = ""; |
395 | 412 | ||
396 | printk(" create device, devfn: %x, type: %s hostcontroller(%d)\n", | 413 | if (ofpci_verbose) |
397 | devfn, type, host_controller); | 414 | printk(" create device, devfn: %x, type: %s\n", |
415 | devfn, type); | ||
398 | 416 | ||
399 | dev->bus = bus; | 417 | dev->bus = bus; |
400 | dev->sysdata = node; | 418 | dev->sysdata = node; |
@@ -434,8 +452,9 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, | |||
434 | sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), | 452 | sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), |
435 | dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); | 453 | dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); |
436 | } | 454 | } |
437 | printk(" class: 0x%x device name: %s\n", | 455 | if (ofpci_verbose) |
438 | dev->class, pci_name(dev)); | 456 | printk(" class: 0x%x device name: %s\n", |
457 | dev->class, pci_name(dev)); | ||
439 | 458 | ||
440 | /* I have seen IDE devices which will not respond to | 459 | /* I have seen IDE devices which will not respond to |
441 | * the bmdma simplex check reads if bus mastering is | 460 | * the bmdma simplex check reads if bus mastering is |
@@ -469,7 +488,8 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, | |||
469 | } | 488 | } |
470 | pci_parse_of_addrs(sd->op, node, dev); | 489 | pci_parse_of_addrs(sd->op, node, dev); |
471 | 490 | ||
472 | printk(" adding to system ...\n"); | 491 | if (ofpci_verbose) |
492 | printk(" adding to system ...\n"); | ||
473 | 493 | ||
474 | pci_device_add(dev, bus); | 494 | pci_device_add(dev, bus); |
475 | 495 | ||
@@ -502,6 +522,89 @@ static void pci_resource_adjust(struct resource *res, | |||
502 | res->end += root->start; | 522 | res->end += root->start; |
503 | } | 523 | } |
504 | 524 | ||
525 | /* For PCI bus devices which lack a 'ranges' property we interrogate | ||
526 | * the config space values to set the resources, just like the generic | ||
527 | * Linux PCI probing code does. | ||
528 | */ | ||
529 | static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev, | ||
530 | struct pci_bus *bus, | ||
531 | struct pci_pbm_info *pbm) | ||
532 | { | ||
533 | struct resource *res; | ||
534 | u8 io_base_lo, io_limit_lo; | ||
535 | u16 mem_base_lo, mem_limit_lo; | ||
536 | unsigned long base, limit; | ||
537 | |||
538 | pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo); | ||
539 | pci_read_config_byte(dev, PCI_IO_LIMIT, &io_limit_lo); | ||
540 | base = (io_base_lo & PCI_IO_RANGE_MASK) << 8; | ||
541 | limit = (io_limit_lo & PCI_IO_RANGE_MASK) << 8; | ||
542 | |||
543 | if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) { | ||
544 | u16 io_base_hi, io_limit_hi; | ||
545 | |||
546 | pci_read_config_word(dev, PCI_IO_BASE_UPPER16, &io_base_hi); | ||
547 | pci_read_config_word(dev, PCI_IO_LIMIT_UPPER16, &io_limit_hi); | ||
548 | base |= (io_base_hi << 16); | ||
549 | limit |= (io_limit_hi << 16); | ||
550 | } | ||
551 | |||
552 | res = bus->resource[0]; | ||
553 | if (base <= limit) { | ||
554 | res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; | ||
555 | if (!res->start) | ||
556 | res->start = base; | ||
557 | if (!res->end) | ||
558 | res->end = limit + 0xfff; | ||
559 | pci_resource_adjust(res, &pbm->io_space); | ||
560 | } | ||
561 | |||
562 | pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo); | ||
563 | pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo); | ||
564 | base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16; | ||
565 | limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16; | ||
566 | |||
567 | res = bus->resource[1]; | ||
568 | if (base <= limit) { | ||
569 | res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | | ||
570 | IORESOURCE_MEM); | ||
571 | res->start = base; | ||
572 | res->end = limit + 0xfffff; | ||
573 | pci_resource_adjust(res, &pbm->mem_space); | ||
574 | } | ||
575 | |||
576 | pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo); | ||
577 | pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo); | ||
578 | base = (mem_base_lo & PCI_PREF_RANGE_MASK) << 16; | ||
579 | limit = (mem_limit_lo & PCI_PREF_RANGE_MASK) << 16; | ||
580 | |||
581 | if ((mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) { | ||
582 | u32 mem_base_hi, mem_limit_hi; | ||
583 | |||
584 | pci_read_config_dword(dev, PCI_PREF_BASE_UPPER32, &mem_base_hi); | ||
585 | pci_read_config_dword(dev, PCI_PREF_LIMIT_UPPER32, &mem_limit_hi); | ||
586 | |||
587 | /* | ||
588 | * Some bridges set the base > limit by default, and some | ||
589 | * (broken) BIOSes do not initialize them. If we find | ||
590 | * this, just assume they are not being used. | ||
591 | */ | ||
592 | if (mem_base_hi <= mem_limit_hi) { | ||
593 | base |= ((long) mem_base_hi) << 32; | ||
594 | limit |= ((long) mem_limit_hi) << 32; | ||
595 | } | ||
596 | } | ||
597 | |||
598 | res = bus->resource[2]; | ||
599 | if (base <= limit) { | ||
600 | res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | | ||
601 | IORESOURCE_MEM | IORESOURCE_PREFETCH); | ||
602 | res->start = base; | ||
603 | res->end = limit + 0xfffff; | ||
604 | pci_resource_adjust(res, &pbm->mem_space); | ||
605 | } | ||
606 | } | ||
607 | |||
505 | /* Cook up fake bus resources for SUNW,simba PCI bridges which lack | 608 | /* Cook up fake bus resources for SUNW,simba PCI bridges which lack |
506 | * a proper 'ranges' property. | 609 | * a proper 'ranges' property. |
507 | */ | 610 | */ |
@@ -547,7 +650,8 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, | |||
547 | unsigned int flags; | 650 | unsigned int flags; |
548 | u64 size; | 651 | u64 size; |
549 | 652 | ||
550 | printk("of_scan_pci_bridge(%s)\n", node->full_name); | 653 | if (ofpci_verbose) |
654 | printk("of_scan_pci_bridge(%s)\n", node->full_name); | ||
551 | 655 | ||
552 | /* parse bus-range property */ | 656 | /* parse bus-range property */ |
553 | busrange = of_get_property(node, "bus-range", &len); | 657 | busrange = of_get_property(node, "bus-range", &len); |
@@ -560,13 +664,8 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, | |||
560 | simba = 0; | 664 | simba = 0; |
561 | if (ranges == NULL) { | 665 | if (ranges == NULL) { |
562 | const char *model = of_get_property(node, "model", NULL); | 666 | const char *model = of_get_property(node, "model", NULL); |
563 | if (model && !strcmp(model, "SUNW,simba")) { | 667 | if (model && !strcmp(model, "SUNW,simba")) |
564 | simba = 1; | 668 | simba = 1; |
565 | } else { | ||
566 | printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n", | ||
567 | node->full_name); | ||
568 | return; | ||
569 | } | ||
570 | } | 669 | } |
571 | 670 | ||
572 | bus = pci_add_new_bus(dev->bus, dev, busrange[0]); | 671 | bus = pci_add_new_bus(dev->bus, dev, busrange[0]); |
@@ -590,7 +689,10 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, | |||
590 | } | 689 | } |
591 | if (simba) { | 690 | if (simba) { |
592 | apb_fake_ranges(dev, bus, pbm); | 691 | apb_fake_ranges(dev, bus, pbm); |
593 | goto simba_cont; | 692 | goto after_ranges; |
693 | } else if (ranges == NULL) { | ||
694 | pci_cfg_fake_ranges(dev, bus, pbm); | ||
695 | goto after_ranges; | ||
594 | } | 696 | } |
595 | i = 1; | 697 | i = 1; |
596 | for (; len >= 32; len -= 32, ranges += 8) { | 698 | for (; len >= 32; len -= 32, ranges += 8) { |
@@ -629,10 +731,11 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, | |||
629 | */ | 731 | */ |
630 | pci_resource_adjust(res, root); | 732 | pci_resource_adjust(res, root); |
631 | } | 733 | } |
632 | simba_cont: | 734 | after_ranges: |
633 | sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), | 735 | sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), |
634 | bus->number); | 736 | bus->number); |
635 | printk(" bus name: %s\n", bus->name); | 737 | if (ofpci_verbose) |
738 | printk(" bus name: %s\n", bus->name); | ||
636 | 739 | ||
637 | pci_of_scan_bus(pbm, node, bus); | 740 | pci_of_scan_bus(pbm, node, bus); |
638 | } | 741 | } |
@@ -646,12 +749,14 @@ static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm, | |||
646 | int reglen, devfn; | 749 | int reglen, devfn; |
647 | struct pci_dev *dev; | 750 | struct pci_dev *dev; |
648 | 751 | ||
649 | printk("PCI: scan_bus[%s] bus no %d\n", | 752 | if (ofpci_verbose) |
650 | node->full_name, bus->number); | 753 | printk("PCI: scan_bus[%s] bus no %d\n", |
754 | node->full_name, bus->number); | ||
651 | 755 | ||
652 | child = NULL; | 756 | child = NULL; |
653 | while ((child = of_get_next_child(node, child)) != NULL) { | 757 | while ((child = of_get_next_child(node, child)) != NULL) { |
654 | printk(" * %s\n", child->full_name); | 758 | if (ofpci_verbose) |
759 | printk(" * %s\n", child->full_name); | ||
655 | reg = of_get_property(child, "reg", ®len); | 760 | reg = of_get_property(child, "reg", ®len); |
656 | if (reg == NULL || reglen < 20) | 761 | if (reg == NULL || reglen < 20) |
657 | continue; | 762 | continue; |
@@ -661,7 +766,9 @@ static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm, | |||
661 | dev = of_create_pci_dev(pbm, child, bus, devfn, 0); | 766 | dev = of_create_pci_dev(pbm, child, bus, devfn, 0); |
662 | if (!dev) | 767 | if (!dev) |
663 | continue; | 768 | continue; |
664 | printk("PCI: dev header type: %x\n", dev->hdr_type); | 769 | if (ofpci_verbose) |
770 | printk("PCI: dev header type: %x\n", | ||
771 | dev->hdr_type); | ||
665 | 772 | ||
666 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || | 773 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || |
667 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) | 774 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) |
diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c index f974fefc3ebc..4249214608af 100644 --- a/arch/sparc64/kernel/pci_common.c +++ b/arch/sparc64/kernel/pci_common.c | |||
@@ -291,8 +291,9 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm) | |||
291 | 291 | ||
292 | for (i = 0; i < num_pbm_ranges; i++) { | 292 | for (i = 0; i < num_pbm_ranges; i++) { |
293 | const struct linux_prom_pci_ranges *pr = &pbm_ranges[i]; | 293 | const struct linux_prom_pci_ranges *pr = &pbm_ranges[i]; |
294 | unsigned long a; | 294 | unsigned long a, size; |
295 | u32 parent_phys_hi, parent_phys_lo; | 295 | u32 parent_phys_hi, parent_phys_lo; |
296 | u32 size_hi, size_lo; | ||
296 | int type; | 297 | int type; |
297 | 298 | ||
298 | parent_phys_hi = pr->parent_phys_hi; | 299 | parent_phys_hi = pr->parent_phys_hi; |
@@ -300,9 +301,14 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm) | |||
300 | if (tlb_type == hypervisor) | 301 | if (tlb_type == hypervisor) |
301 | parent_phys_hi &= 0x0fffffff; | 302 | parent_phys_hi &= 0x0fffffff; |
302 | 303 | ||
304 | size_hi = pr->size_hi; | ||
305 | size_lo = pr->size_lo; | ||
306 | |||
303 | type = (pr->child_phys_hi >> 24) & 0x3; | 307 | type = (pr->child_phys_hi >> 24) & 0x3; |
304 | a = (((unsigned long)parent_phys_hi << 32UL) | | 308 | a = (((unsigned long)parent_phys_hi << 32UL) | |
305 | ((unsigned long)parent_phys_lo << 0UL)); | 309 | ((unsigned long)parent_phys_lo << 0UL)); |
310 | size = (((unsigned long)size_hi << 32UL) | | ||
311 | ((unsigned long)size_lo << 0UL)); | ||
306 | 312 | ||
307 | switch (type) { | 313 | switch (type) { |
308 | case 0: | 314 | case 0: |
@@ -313,7 +319,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm) | |||
313 | case 1: | 319 | case 1: |
314 | /* 16-bit IO space, 16MB */ | 320 | /* 16-bit IO space, 16MB */ |
315 | pbm->io_space.start = a; | 321 | pbm->io_space.start = a; |
316 | pbm->io_space.end = a + ((16UL*1024UL*1024UL) - 1UL); | 322 | pbm->io_space.end = a + size - 1UL; |
317 | pbm->io_space.flags = IORESOURCE_IO; | 323 | pbm->io_space.flags = IORESOURCE_IO; |
318 | saw_io = 1; | 324 | saw_io = 1; |
319 | break; | 325 | break; |
@@ -321,7 +327,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm) | |||
321 | case 2: | 327 | case 2: |
322 | /* 32-bit MEM space, 2GB */ | 328 | /* 32-bit MEM space, 2GB */ |
323 | pbm->mem_space.start = a; | 329 | pbm->mem_space.start = a; |
324 | pbm->mem_space.end = a + (0x80000000UL - 1UL); | 330 | pbm->mem_space.end = a + size - 1UL; |
325 | pbm->mem_space.flags = IORESOURCE_MEM; | 331 | pbm->mem_space.flags = IORESOURCE_MEM; |
326 | saw_mem = 1; | 332 | saw_mem = 1; |
327 | break; | 333 | break; |
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index e2377796de89..22e1be5c7489 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c | |||
@@ -636,13 +636,18 @@ static void apb_init(struct pci_bus *sabre_bus) | |||
636 | static void sabre_scan_bus(struct pci_pbm_info *pbm) | 636 | static void sabre_scan_bus(struct pci_pbm_info *pbm) |
637 | { | 637 | { |
638 | static int once; | 638 | static int once; |
639 | struct pci_bus *pbus; | ||
640 | 639 | ||
641 | /* The APB bridge speaks to the Sabre host PCI bridge | 640 | /* The APB bridge speaks to the Sabre host PCI bridge |
642 | * at 66Mhz, but the front side of APB runs at 33Mhz | 641 | * at 66Mhz, but the front side of APB runs at 33Mhz |
643 | * for both segments. | 642 | * for both segments. |
643 | * | ||
644 | * Hummingbird systems do not use APB, so they run | ||
645 | * at 66MHZ. | ||
644 | */ | 646 | */ |
645 | pbm->is_66mhz_capable = 0; | 647 | if (hummingbird_p) |
648 | pbm->is_66mhz_capable = 1; | ||
649 | else | ||
650 | pbm->is_66mhz_capable = 0; | ||
646 | 651 | ||
647 | /* This driver has not been verified to handle | 652 | /* This driver has not been verified to handle |
648 | * multiple SABREs yet, so trap this. | 653 | * multiple SABREs yet, so trap this. |
@@ -656,13 +661,13 @@ static void sabre_scan_bus(struct pci_pbm_info *pbm) | |||
656 | } | 661 | } |
657 | once++; | 662 | once++; |
658 | 663 | ||
659 | pbus = pci_scan_one_pbm(pbm); | 664 | pbm->pci_bus = pci_scan_one_pbm(pbm); |
660 | if (!pbus) | 665 | if (!pbm->pci_bus) |
661 | return; | 666 | return; |
662 | 667 | ||
663 | sabre_root_bus = pbus; | 668 | sabre_root_bus = pbm->pci_bus; |
664 | 669 | ||
665 | apb_init(pbus); | 670 | apb_init(pbm->pci_bus); |
666 | 671 | ||
667 | sabre_register_error_handlers(pbm); | 672 | sabre_register_error_handlers(pbm); |
668 | } | 673 | } |
@@ -762,9 +767,10 @@ void sabre_init(struct device_node *dp, char *model_name) | |||
762 | /* Of course, Sun has to encode things a thousand | 767 | /* Of course, Sun has to encode things a thousand |
763 | * different ways, inconsistently. | 768 | * different ways, inconsistently. |
764 | */ | 769 | */ |
765 | cpu_find_by_instance(0, &dp, NULL); | 770 | for_each_node_by_type(dp, "cpu") { |
766 | if (!strcmp(dp->name, "SUNW,UltraSPARC-IIe")) | 771 | if (!strcmp(dp->name, "SUNW,UltraSPARC-IIe")) |
767 | hummingbird_p = 1; | 772 | hummingbird_p = 1; |
773 | } | ||
768 | } | 774 | } |
769 | } | 775 | } |
770 | 776 | ||
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 044e8ec4c0f5..6b3fe2c1d65e 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/percpu.h> | 12 | #include <linux/percpu.h> |
13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
14 | #include <linux/msi.h> | 14 | #include <linux/msi.h> |
15 | #include <linux/log2.h> | ||
15 | 16 | ||
16 | #include <asm/iommu.h> | 17 | #include <asm/iommu.h> |
17 | #include <asm/irq.h> | 18 | #include <asm/irq.h> |
@@ -26,6 +27,9 @@ | |||
26 | 27 | ||
27 | #include "pci_sun4v.h" | 28 | #include "pci_sun4v.h" |
28 | 29 | ||
30 | static unsigned long vpci_major = 1; | ||
31 | static unsigned long vpci_minor = 1; | ||
32 | |||
29 | #define PGLIST_NENTS (PAGE_SIZE / sizeof(u64)) | 33 | #define PGLIST_NENTS (PAGE_SIZE / sizeof(u64)) |
30 | 34 | ||
31 | struct iommu_batch { | 35 | struct iommu_batch { |
@@ -638,9 +642,8 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm) | |||
638 | { | 642 | { |
639 | struct iommu *iommu = pbm->iommu; | 643 | struct iommu *iommu = pbm->iommu; |
640 | struct property *prop; | 644 | struct property *prop; |
641 | unsigned long num_tsb_entries, sz; | 645 | unsigned long num_tsb_entries, sz, tsbsize; |
642 | u32 vdma[2], dma_mask, dma_offset; | 646 | u32 vdma[2], dma_mask, dma_offset; |
643 | int tsbsize; | ||
644 | 647 | ||
645 | prop = of_find_property(pbm->prom_node, "virtual-dma", NULL); | 648 | prop = of_find_property(pbm->prom_node, "virtual-dma", NULL); |
646 | if (prop) { | 649 | if (prop) { |
@@ -654,31 +657,15 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm) | |||
654 | vdma[1] = 0x80000000; | 657 | vdma[1] = 0x80000000; |
655 | } | 658 | } |
656 | 659 | ||
657 | dma_mask = vdma[0]; | 660 | if ((vdma[0] | vdma[1]) & ~IO_PAGE_MASK) { |
658 | switch (vdma[1]) { | 661 | prom_printf("PCI-SUN4V: strange virtual-dma[%08x:%08x].\n", |
659 | case 0x20000000: | 662 | vdma[0], vdma[1]); |
660 | dma_mask |= 0x1fffffff; | 663 | prom_halt(); |
661 | tsbsize = 64; | ||
662 | break; | ||
663 | |||
664 | case 0x40000000: | ||
665 | dma_mask |= 0x3fffffff; | ||
666 | tsbsize = 128; | ||
667 | break; | ||
668 | |||
669 | case 0x80000000: | ||
670 | dma_mask |= 0x7fffffff; | ||
671 | tsbsize = 256; | ||
672 | break; | ||
673 | |||
674 | default: | ||
675 | prom_printf("PCI-SUN4V: strange virtual-dma size.\n"); | ||
676 | prom_halt(); | ||
677 | }; | 664 | }; |
678 | 665 | ||
679 | tsbsize *= (8 * 1024); | 666 | dma_mask = (roundup_pow_of_two(vdma[1]) - 1UL); |
680 | 667 | num_tsb_entries = vdma[1] / IO_PAGE_SIZE; | |
681 | num_tsb_entries = tsbsize / sizeof(iopte_t); | 668 | tsbsize = num_tsb_entries * sizeof(iopte_t); |
682 | 669 | ||
683 | dma_offset = vdma[0]; | 670 | dma_offset = vdma[0]; |
684 | 671 | ||
@@ -689,7 +676,7 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm) | |||
689 | iommu->dma_addr_mask = dma_mask; | 676 | iommu->dma_addr_mask = dma_mask; |
690 | 677 | ||
691 | /* Allocate and initialize the free area map. */ | 678 | /* Allocate and initialize the free area map. */ |
692 | sz = num_tsb_entries / 8; | 679 | sz = (num_tsb_entries + 7) / 8; |
693 | sz = (sz + 7UL) & ~7UL; | 680 | sz = (sz + 7UL) & ~7UL; |
694 | iommu->arena.map = kzalloc(sz, GFP_KERNEL); | 681 | iommu->arena.map = kzalloc(sz, GFP_KERNEL); |
695 | if (!iommu->arena.map) { | 682 | if (!iommu->arena.map) { |
@@ -1178,6 +1165,7 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node | |||
1178 | 1165 | ||
1179 | void sun4v_pci_init(struct device_node *dp, char *model_name) | 1166 | void sun4v_pci_init(struct device_node *dp, char *model_name) |
1180 | { | 1167 | { |
1168 | static int hvapi_negotiated = 0; | ||
1181 | struct pci_controller_info *p; | 1169 | struct pci_controller_info *p; |
1182 | struct pci_pbm_info *pbm; | 1170 | struct pci_pbm_info *pbm; |
1183 | struct iommu *iommu; | 1171 | struct iommu *iommu; |
@@ -1186,6 +1174,20 @@ void sun4v_pci_init(struct device_node *dp, char *model_name) | |||
1186 | u32 devhandle; | 1174 | u32 devhandle; |
1187 | int i; | 1175 | int i; |
1188 | 1176 | ||
1177 | if (!hvapi_negotiated++) { | ||
1178 | int err = sun4v_hvapi_register(HV_GRP_PCI, | ||
1179 | vpci_major, | ||
1180 | &vpci_minor); | ||
1181 | |||
1182 | if (err) { | ||
1183 | prom_printf("SUN4V_PCI: Could not register hvapi, " | ||
1184 | "err=%d\n", err); | ||
1185 | prom_halt(); | ||
1186 | } | ||
1187 | printk("SUN4V_PCI: Registered hvapi major[%lu] minor[%lu]\n", | ||
1188 | vpci_major, vpci_minor); | ||
1189 | } | ||
1190 | |||
1189 | prop = of_find_property(dp, "reg", NULL); | 1191 | prop = of_find_property(dp, "reg", NULL); |
1190 | regs = prop->value; | 1192 | regs = prop->value; |
1191 | 1193 | ||
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c index 699b24b890df..5d6adea3967f 100644 --- a/arch/sparc64/kernel/power.c +++ b/arch/sparc64/kernel/power.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <asm/prom.h> | 19 | #include <asm/prom.h> |
20 | #include <asm/of_device.h> | 20 | #include <asm/of_device.h> |
21 | #include <asm/io.h> | 21 | #include <asm/io.h> |
22 | #include <asm/sstate.h> | ||
22 | 23 | ||
23 | #include <linux/unistd.h> | 24 | #include <linux/unistd.h> |
24 | 25 | ||
@@ -53,6 +54,7 @@ static void (*poweroff_method)(void) = machine_alt_power_off; | |||
53 | 54 | ||
54 | void machine_power_off(void) | 55 | void machine_power_off(void) |
55 | { | 56 | { |
57 | sstate_poweroff(); | ||
56 | if (!serial_console || scons_pwroff) { | 58 | if (!serial_console || scons_pwroff) { |
57 | #ifdef CONFIG_PCI | 59 | #ifdef CONFIG_PCI |
58 | if (power_reg) { | 60 | if (power_reg) { |
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 952762bfb4c0..f5f97e2c669c 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <asm/mmu_context.h> | 45 | #include <asm/mmu_context.h> |
46 | #include <asm/unistd.h> | 46 | #include <asm/unistd.h> |
47 | #include <asm/hypervisor.h> | 47 | #include <asm/hypervisor.h> |
48 | #include <asm/sstate.h> | ||
48 | 49 | ||
49 | /* #define VERBOSE_SHOWREGS */ | 50 | /* #define VERBOSE_SHOWREGS */ |
50 | 51 | ||
@@ -106,6 +107,7 @@ extern void (*prom_keyboard)(void); | |||
106 | 107 | ||
107 | void machine_halt(void) | 108 | void machine_halt(void) |
108 | { | 109 | { |
110 | sstate_halt(); | ||
109 | if (!serial_console && prom_palette) | 111 | if (!serial_console && prom_palette) |
110 | prom_palette (1); | 112 | prom_palette (1); |
111 | if (prom_keyboard) | 113 | if (prom_keyboard) |
@@ -116,6 +118,7 @@ void machine_halt(void) | |||
116 | 118 | ||
117 | void machine_alt_power_off(void) | 119 | void machine_alt_power_off(void) |
118 | { | 120 | { |
121 | sstate_poweroff(); | ||
119 | if (!serial_console && prom_palette) | 122 | if (!serial_console && prom_palette) |
120 | prom_palette(1); | 123 | prom_palette(1); |
121 | if (prom_keyboard) | 124 | if (prom_keyboard) |
@@ -128,6 +131,7 @@ void machine_restart(char * cmd) | |||
128 | { | 131 | { |
129 | char *p; | 132 | char *p; |
130 | 133 | ||
134 | sstate_reboot(); | ||
131 | p = strchr (reboot_command, '\n'); | 135 | p = strchr (reboot_command, '\n'); |
132 | if (p) *p = 0; | 136 | if (p) *p = 0; |
133 | if (!serial_console && prom_palette) | 137 | if (!serial_console && prom_palette) |
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index 02830e4671f5..61036b346664 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <asm/irq.h> | 28 | #include <asm/irq.h> |
29 | #include <asm/asi.h> | 29 | #include <asm/asi.h> |
30 | #include <asm/upa.h> | 30 | #include <asm/upa.h> |
31 | #include <asm/smp.h> | ||
31 | 32 | ||
32 | static struct device_node *allnodes; | 33 | static struct device_node *allnodes; |
33 | 34 | ||
@@ -932,29 +933,29 @@ static void __init fire_irq_trans_init(struct device_node *dp) | |||
932 | * This should conform to both Sunfire/Wildfire server and Fusion | 933 | * This should conform to both Sunfire/Wildfire server and Fusion |
933 | * desktop designs. | 934 | * desktop designs. |
934 | */ | 935 | */ |
935 | #define SYSIO_IMAP_SLOT0 0x2c04UL | 936 | #define SYSIO_IMAP_SLOT0 0x2c00UL |
936 | #define SYSIO_IMAP_SLOT1 0x2c0cUL | 937 | #define SYSIO_IMAP_SLOT1 0x2c08UL |
937 | #define SYSIO_IMAP_SLOT2 0x2c14UL | 938 | #define SYSIO_IMAP_SLOT2 0x2c10UL |
938 | #define SYSIO_IMAP_SLOT3 0x2c1cUL | 939 | #define SYSIO_IMAP_SLOT3 0x2c18UL |
939 | #define SYSIO_IMAP_SCSI 0x3004UL | 940 | #define SYSIO_IMAP_SCSI 0x3000UL |
940 | #define SYSIO_IMAP_ETH 0x300cUL | 941 | #define SYSIO_IMAP_ETH 0x3008UL |
941 | #define SYSIO_IMAP_BPP 0x3014UL | 942 | #define SYSIO_IMAP_BPP 0x3010UL |
942 | #define SYSIO_IMAP_AUDIO 0x301cUL | 943 | #define SYSIO_IMAP_AUDIO 0x3018UL |
943 | #define SYSIO_IMAP_PFAIL 0x3024UL | 944 | #define SYSIO_IMAP_PFAIL 0x3020UL |
944 | #define SYSIO_IMAP_KMS 0x302cUL | 945 | #define SYSIO_IMAP_KMS 0x3028UL |
945 | #define SYSIO_IMAP_FLPY 0x3034UL | 946 | #define SYSIO_IMAP_FLPY 0x3030UL |
946 | #define SYSIO_IMAP_SHW 0x303cUL | 947 | #define SYSIO_IMAP_SHW 0x3038UL |
947 | #define SYSIO_IMAP_KBD 0x3044UL | 948 | #define SYSIO_IMAP_KBD 0x3040UL |
948 | #define SYSIO_IMAP_MS 0x304cUL | 949 | #define SYSIO_IMAP_MS 0x3048UL |
949 | #define SYSIO_IMAP_SER 0x3054UL | 950 | #define SYSIO_IMAP_SER 0x3050UL |
950 | #define SYSIO_IMAP_TIM0 0x3064UL | 951 | #define SYSIO_IMAP_TIM0 0x3060UL |
951 | #define SYSIO_IMAP_TIM1 0x306cUL | 952 | #define SYSIO_IMAP_TIM1 0x3068UL |
952 | #define SYSIO_IMAP_UE 0x3074UL | 953 | #define SYSIO_IMAP_UE 0x3070UL |
953 | #define SYSIO_IMAP_CE 0x307cUL | 954 | #define SYSIO_IMAP_CE 0x3078UL |
954 | #define SYSIO_IMAP_SBERR 0x3084UL | 955 | #define SYSIO_IMAP_SBERR 0x3080UL |
955 | #define SYSIO_IMAP_PMGMT 0x308cUL | 956 | #define SYSIO_IMAP_PMGMT 0x3088UL |
956 | #define SYSIO_IMAP_GFX 0x3094UL | 957 | #define SYSIO_IMAP_GFX 0x3090UL |
957 | #define SYSIO_IMAP_EUPA 0x309cUL | 958 | #define SYSIO_IMAP_EUPA 0x3098UL |
958 | 959 | ||
959 | #define bogon ((unsigned long) -1) | 960 | #define bogon ((unsigned long) -1) |
960 | static unsigned long sysio_irq_offsets[] = { | 961 | static unsigned long sysio_irq_offsets[] = { |
@@ -1005,10 +1006,10 @@ static unsigned long sysio_irq_offsets[] = { | |||
1005 | * Interrupt Clear register pointer, SYSIO specific version. | 1006 | * Interrupt Clear register pointer, SYSIO specific version. |
1006 | */ | 1007 | */ |
1007 | #define SYSIO_ICLR_UNUSED0 0x3400UL | 1008 | #define SYSIO_ICLR_UNUSED0 0x3400UL |
1008 | #define SYSIO_ICLR_SLOT0 0x340cUL | 1009 | #define SYSIO_ICLR_SLOT0 0x3408UL |
1009 | #define SYSIO_ICLR_SLOT1 0x344cUL | 1010 | #define SYSIO_ICLR_SLOT1 0x3448UL |
1010 | #define SYSIO_ICLR_SLOT2 0x348cUL | 1011 | #define SYSIO_ICLR_SLOT2 0x3488UL |
1011 | #define SYSIO_ICLR_SLOT3 0x34ccUL | 1012 | #define SYSIO_ICLR_SLOT3 0x34c8UL |
1012 | static unsigned long sysio_imap_to_iclr(unsigned long imap) | 1013 | static unsigned long sysio_imap_to_iclr(unsigned long imap) |
1013 | { | 1014 | { |
1014 | unsigned long diff = SYSIO_ICLR_UNUSED0 - SYSIO_IMAP_SLOT0; | 1015 | unsigned long diff = SYSIO_ICLR_UNUSED0 - SYSIO_IMAP_SLOT0; |
@@ -1665,6 +1666,155 @@ static struct device_node * __init build_tree(struct device_node *parent, phandl | |||
1665 | return ret; | 1666 | return ret; |
1666 | } | 1667 | } |
1667 | 1668 | ||
1669 | static const char *get_mid_prop(void) | ||
1670 | { | ||
1671 | return (tlb_type == spitfire ? "upa-portid" : "portid"); | ||
1672 | } | ||
1673 | |||
1674 | struct device_node *of_find_node_by_cpuid(int cpuid) | ||
1675 | { | ||
1676 | struct device_node *dp; | ||
1677 | const char *mid_prop = get_mid_prop(); | ||
1678 | |||
1679 | for_each_node_by_type(dp, "cpu") { | ||
1680 | int id = of_getintprop_default(dp, mid_prop, -1); | ||
1681 | const char *this_mid_prop = mid_prop; | ||
1682 | |||
1683 | if (id < 0) { | ||
1684 | this_mid_prop = "cpuid"; | ||
1685 | id = of_getintprop_default(dp, this_mid_prop, -1); | ||
1686 | } | ||
1687 | |||
1688 | if (id < 0) { | ||
1689 | prom_printf("OF: Serious problem, cpu lacks " | ||
1690 | "%s property", this_mid_prop); | ||
1691 | prom_halt(); | ||
1692 | } | ||
1693 | if (cpuid == id) | ||
1694 | return dp; | ||
1695 | } | ||
1696 | return NULL; | ||
1697 | } | ||
1698 | |||
1699 | static void __init of_fill_in_cpu_data(void) | ||
1700 | { | ||
1701 | struct device_node *dp; | ||
1702 | const char *mid_prop = get_mid_prop(); | ||
1703 | |||
1704 | ncpus_probed = 0; | ||
1705 | for_each_node_by_type(dp, "cpu") { | ||
1706 | int cpuid = of_getintprop_default(dp, mid_prop, -1); | ||
1707 | const char *this_mid_prop = mid_prop; | ||
1708 | struct device_node *portid_parent; | ||
1709 | int portid = -1; | ||
1710 | |||
1711 | portid_parent = NULL; | ||
1712 | if (cpuid < 0) { | ||
1713 | this_mid_prop = "cpuid"; | ||
1714 | cpuid = of_getintprop_default(dp, this_mid_prop, -1); | ||
1715 | if (cpuid >= 0) { | ||
1716 | int limit = 2; | ||
1717 | |||
1718 | portid_parent = dp; | ||
1719 | while (limit--) { | ||
1720 | portid_parent = portid_parent->parent; | ||
1721 | if (!portid_parent) | ||
1722 | break; | ||
1723 | portid = of_getintprop_default(portid_parent, | ||
1724 | "portid", -1); | ||
1725 | if (portid >= 0) | ||
1726 | break; | ||
1727 | } | ||
1728 | } | ||
1729 | } | ||
1730 | |||
1731 | if (cpuid < 0) { | ||
1732 | prom_printf("OF: Serious problem, cpu lacks " | ||
1733 | "%s property", this_mid_prop); | ||
1734 | prom_halt(); | ||
1735 | } | ||
1736 | |||
1737 | ncpus_probed++; | ||
1738 | |||
1739 | #ifdef CONFIG_SMP | ||
1740 | if (cpuid >= NR_CPUS) | ||
1741 | continue; | ||
1742 | #else | ||
1743 | /* On uniprocessor we only want the values for the | ||
1744 | * real physical cpu the kernel booted onto, however | ||
1745 | * cpu_data() only has one entry at index 0. | ||
1746 | */ | ||
1747 | if (cpuid != real_hard_smp_processor_id()) | ||
1748 | continue; | ||
1749 | cpuid = 0; | ||
1750 | #endif | ||
1751 | |||
1752 | cpu_data(cpuid).clock_tick = | ||
1753 | of_getintprop_default(dp, "clock-frequency", 0); | ||
1754 | |||
1755 | if (portid_parent) { | ||
1756 | cpu_data(cpuid).dcache_size = | ||
1757 | of_getintprop_default(dp, "l1-dcache-size", | ||
1758 | 16 * 1024); | ||
1759 | cpu_data(cpuid).dcache_line_size = | ||
1760 | of_getintprop_default(dp, "l1-dcache-line-size", | ||
1761 | 32); | ||
1762 | cpu_data(cpuid).icache_size = | ||
1763 | of_getintprop_default(dp, "l1-icache-size", | ||
1764 | 8 * 1024); | ||
1765 | cpu_data(cpuid).icache_line_size = | ||
1766 | of_getintprop_default(dp, "l1-icache-line-size", | ||
1767 | 32); | ||
1768 | cpu_data(cpuid).ecache_size = | ||
1769 | of_getintprop_default(dp, "l2-cache-size", 0); | ||
1770 | cpu_data(cpuid).ecache_line_size = | ||
1771 | of_getintprop_default(dp, "l2-cache-line-size", 0); | ||
1772 | if (!cpu_data(cpuid).ecache_size || | ||
1773 | !cpu_data(cpuid).ecache_line_size) { | ||
1774 | cpu_data(cpuid).ecache_size = | ||
1775 | of_getintprop_default(portid_parent, | ||
1776 | "l2-cache-size", | ||
1777 | (4 * 1024 * 1024)); | ||
1778 | cpu_data(cpuid).ecache_line_size = | ||
1779 | of_getintprop_default(portid_parent, | ||
1780 | "l2-cache-line-size", 64); | ||
1781 | } | ||
1782 | |||
1783 | cpu_data(cpuid).core_id = portid + 1; | ||
1784 | cpu_data(cpuid).proc_id = portid; | ||
1785 | #ifdef CONFIG_SMP | ||
1786 | sparc64_multi_core = 1; | ||
1787 | #endif | ||
1788 | } else { | ||
1789 | cpu_data(cpuid).dcache_size = | ||
1790 | of_getintprop_default(dp, "dcache-size", 16 * 1024); | ||
1791 | cpu_data(cpuid).dcache_line_size = | ||
1792 | of_getintprop_default(dp, "dcache-line-size", 32); | ||
1793 | |||
1794 | cpu_data(cpuid).icache_size = | ||
1795 | of_getintprop_default(dp, "icache-size", 16 * 1024); | ||
1796 | cpu_data(cpuid).icache_line_size = | ||
1797 | of_getintprop_default(dp, "icache-line-size", 32); | ||
1798 | |||
1799 | cpu_data(cpuid).ecache_size = | ||
1800 | of_getintprop_default(dp, "ecache-size", | ||
1801 | (4 * 1024 * 1024)); | ||
1802 | cpu_data(cpuid).ecache_line_size = | ||
1803 | of_getintprop_default(dp, "ecache-line-size", 64); | ||
1804 | |||
1805 | cpu_data(cpuid).core_id = 0; | ||
1806 | cpu_data(cpuid).proc_id = -1; | ||
1807 | } | ||
1808 | |||
1809 | #ifdef CONFIG_SMP | ||
1810 | cpu_set(cpuid, cpu_present_map); | ||
1811 | cpu_set(cpuid, phys_cpu_present_map); | ||
1812 | #endif | ||
1813 | } | ||
1814 | |||
1815 | smp_fill_in_sib_core_maps(); | ||
1816 | } | ||
1817 | |||
1668 | void __init prom_build_devicetree(void) | 1818 | void __init prom_build_devicetree(void) |
1669 | { | 1819 | { |
1670 | struct device_node **nextp; | 1820 | struct device_node **nextp; |
@@ -1679,4 +1829,7 @@ void __init prom_build_devicetree(void) | |||
1679 | &nextp); | 1829 | &nextp); |
1680 | printk("PROM: Built device tree with %u bytes of memory.\n", | 1830 | printk("PROM: Built device tree with %u bytes of memory.\n", |
1681 | prom_early_allocated); | 1831 | prom_early_allocated); |
1832 | |||
1833 | if (tlb_type != hypervisor) | ||
1834 | of_fill_in_cpu_data(); | ||
1682 | } | 1835 | } |
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index 91f6e2a74ad5..a1fd9bcc0b87 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c | |||
@@ -629,29 +629,29 @@ void sbus_set_sbus64(struct sbus_dev *sdev, int bursts) | |||
629 | * This should conform to both Sunfire/Wildfire server and Fusion | 629 | * This should conform to both Sunfire/Wildfire server and Fusion |
630 | * desktop designs. | 630 | * desktop designs. |
631 | */ | 631 | */ |
632 | #define SYSIO_IMAP_SLOT0 0x2c04UL | 632 | #define SYSIO_IMAP_SLOT0 0x2c00UL |
633 | #define SYSIO_IMAP_SLOT1 0x2c0cUL | 633 | #define SYSIO_IMAP_SLOT1 0x2c08UL |
634 | #define SYSIO_IMAP_SLOT2 0x2c14UL | 634 | #define SYSIO_IMAP_SLOT2 0x2c10UL |
635 | #define SYSIO_IMAP_SLOT3 0x2c1cUL | 635 | #define SYSIO_IMAP_SLOT3 0x2c18UL |
636 | #define SYSIO_IMAP_SCSI 0x3004UL | 636 | #define SYSIO_IMAP_SCSI 0x3000UL |
637 | #define SYSIO_IMAP_ETH 0x300cUL | 637 | #define SYSIO_IMAP_ETH 0x3008UL |
638 | #define SYSIO_IMAP_BPP 0x3014UL | 638 | #define SYSIO_IMAP_BPP 0x3010UL |
639 | #define SYSIO_IMAP_AUDIO 0x301cUL | 639 | #define SYSIO_IMAP_AUDIO 0x3018UL |
640 | #define SYSIO_IMAP_PFAIL 0x3024UL | 640 | #define SYSIO_IMAP_PFAIL 0x3020UL |
641 | #define SYSIO_IMAP_KMS 0x302cUL | 641 | #define SYSIO_IMAP_KMS 0x3028UL |
642 | #define SYSIO_IMAP_FLPY 0x3034UL | 642 | #define SYSIO_IMAP_FLPY 0x3030UL |
643 | #define SYSIO_IMAP_SHW 0x303cUL | 643 | #define SYSIO_IMAP_SHW 0x3038UL |
644 | #define SYSIO_IMAP_KBD 0x3044UL | 644 | #define SYSIO_IMAP_KBD 0x3040UL |
645 | #define SYSIO_IMAP_MS 0x304cUL | 645 | #define SYSIO_IMAP_MS 0x3048UL |
646 | #define SYSIO_IMAP_SER 0x3054UL | 646 | #define SYSIO_IMAP_SER 0x3050UL |
647 | #define SYSIO_IMAP_TIM0 0x3064UL | 647 | #define SYSIO_IMAP_TIM0 0x3060UL |
648 | #define SYSIO_IMAP_TIM1 0x306cUL | 648 | #define SYSIO_IMAP_TIM1 0x3068UL |
649 | #define SYSIO_IMAP_UE 0x3074UL | 649 | #define SYSIO_IMAP_UE 0x3070UL |
650 | #define SYSIO_IMAP_CE 0x307cUL | 650 | #define SYSIO_IMAP_CE 0x3078UL |
651 | #define SYSIO_IMAP_SBERR 0x3084UL | 651 | #define SYSIO_IMAP_SBERR 0x3080UL |
652 | #define SYSIO_IMAP_PMGMT 0x308cUL | 652 | #define SYSIO_IMAP_PMGMT 0x3088UL |
653 | #define SYSIO_IMAP_GFX 0x3094UL | 653 | #define SYSIO_IMAP_GFX 0x3090UL |
654 | #define SYSIO_IMAP_EUPA 0x309cUL | 654 | #define SYSIO_IMAP_EUPA 0x3098UL |
655 | 655 | ||
656 | #define bogon ((unsigned long) -1) | 656 | #define bogon ((unsigned long) -1) |
657 | static unsigned long sysio_irq_offsets[] = { | 657 | static unsigned long sysio_irq_offsets[] = { |
@@ -700,10 +700,10 @@ static unsigned long sysio_irq_offsets[] = { | |||
700 | * Interrupt Clear register pointer, SYSIO specific version. | 700 | * Interrupt Clear register pointer, SYSIO specific version. |
701 | */ | 701 | */ |
702 | #define SYSIO_ICLR_UNUSED0 0x3400UL | 702 | #define SYSIO_ICLR_UNUSED0 0x3400UL |
703 | #define SYSIO_ICLR_SLOT0 0x340cUL | 703 | #define SYSIO_ICLR_SLOT0 0x3408UL |
704 | #define SYSIO_ICLR_SLOT1 0x344cUL | 704 | #define SYSIO_ICLR_SLOT1 0x3448UL |
705 | #define SYSIO_ICLR_SLOT2 0x348cUL | 705 | #define SYSIO_ICLR_SLOT2 0x3488UL |
706 | #define SYSIO_ICLR_SLOT3 0x34ccUL | 706 | #define SYSIO_ICLR_SLOT3 0x34c8UL |
707 | static unsigned long sysio_imap_to_iclr(unsigned long imap) | 707 | static unsigned long sysio_imap_to_iclr(unsigned long imap) |
708 | { | 708 | { |
709 | unsigned long diff = SYSIO_ICLR_UNUSED0 - SYSIO_IMAP_SLOT0; | 709 | unsigned long diff = SYSIO_ICLR_UNUSED0 - SYSIO_IMAP_SLOT0; |
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index dea9c3c9ec5f..7490cc670a53 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c | |||
@@ -46,11 +46,17 @@ | |||
46 | #include <asm/sections.h> | 46 | #include <asm/sections.h> |
47 | #include <asm/setup.h> | 47 | #include <asm/setup.h> |
48 | #include <asm/mmu.h> | 48 | #include <asm/mmu.h> |
49 | #include <asm/ns87303.h> | ||
49 | 50 | ||
50 | #ifdef CONFIG_IP_PNP | 51 | #ifdef CONFIG_IP_PNP |
51 | #include <net/ipconfig.h> | 52 | #include <net/ipconfig.h> |
52 | #endif | 53 | #endif |
53 | 54 | ||
55 | /* Used to synchronize accesses to NatSemi SUPER I/O chip configure | ||
56 | * operations in asm/ns87303.h | ||
57 | */ | ||
58 | DEFINE_SPINLOCK(ns87303_lock); | ||
59 | |||
54 | struct screen_info screen_info = { | 60 | struct screen_info screen_info = { |
55 | 0, 0, /* orig-x, orig-y */ | 61 | 0, 0, /* orig-x, orig-y */ |
56 | 0, /* unused */ | 62 | 0, /* unused */ |
@@ -370,8 +376,6 @@ void __init setup_arch(char **cmdline_p) | |||
370 | init_cur_cpu_trap(current_thread_info()); | 376 | init_cur_cpu_trap(current_thread_info()); |
371 | 377 | ||
372 | paging_init(); | 378 | paging_init(); |
373 | |||
374 | smp_setup_cpu_possible_map(); | ||
375 | } | 379 | } |
376 | 380 | ||
377 | static int __init set_preferred_console(void) | 381 | static int __init set_preferred_console(void) |
@@ -424,7 +428,7 @@ extern void mmu_info(struct seq_file *); | |||
424 | unsigned int dcache_parity_tl1_occurred; | 428 | unsigned int dcache_parity_tl1_occurred; |
425 | unsigned int icache_parity_tl1_occurred; | 429 | unsigned int icache_parity_tl1_occurred; |
426 | 430 | ||
427 | static int ncpus_probed; | 431 | int ncpus_probed; |
428 | 432 | ||
429 | static int show_cpuinfo(struct seq_file *m, void *__unused) | 433 | static int show_cpuinfo(struct seq_file *m, void *__unused) |
430 | { | 434 | { |
@@ -509,30 +513,3 @@ void sun_do_break(void) | |||
509 | 513 | ||
510 | int serial_console = -1; | 514 | int serial_console = -1; |
511 | int stop_a_enabled = 1; | 515 | int stop_a_enabled = 1; |
512 | |||
513 | static int __init topology_init(void) | ||
514 | { | ||
515 | int i, err; | ||
516 | |||
517 | err = -ENOMEM; | ||
518 | |||
519 | /* Count the number of physically present processors in | ||
520 | * the machine, even on uniprocessor, so that /proc/cpuinfo | ||
521 | * output is consistent with 2.4.x | ||
522 | */ | ||
523 | ncpus_probed = 0; | ||
524 | while (!cpu_find_by_instance(ncpus_probed, NULL, NULL)) | ||
525 | ncpus_probed++; | ||
526 | |||
527 | for_each_possible_cpu(i) { | ||
528 | struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); | ||
529 | if (p) { | ||
530 | register_cpu(p, i); | ||
531 | err = 0; | ||
532 | } | ||
533 | } | ||
534 | |||
535 | return err; | ||
536 | } | ||
537 | |||
538 | subsys_initcall(topology_init); | ||
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 24fdf1d0adc5..4dcd7d0b60f2 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c | |||
@@ -40,9 +40,12 @@ | |||
40 | #include <asm/tlb.h> | 40 | #include <asm/tlb.h> |
41 | #include <asm/sections.h> | 41 | #include <asm/sections.h> |
42 | #include <asm/prom.h> | 42 | #include <asm/prom.h> |
43 | #include <asm/mdesc.h> | ||
43 | 44 | ||
44 | extern void calibrate_delay(void); | 45 | extern void calibrate_delay(void); |
45 | 46 | ||
47 | int sparc64_multi_core __read_mostly; | ||
48 | |||
46 | /* Please don't make this stuff initdata!!! --DaveM */ | 49 | /* Please don't make this stuff initdata!!! --DaveM */ |
47 | unsigned char boot_cpu_id; | 50 | unsigned char boot_cpu_id; |
48 | 51 | ||
@@ -50,6 +53,8 @@ cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE; | |||
50 | cpumask_t phys_cpu_present_map __read_mostly = CPU_MASK_NONE; | 53 | cpumask_t phys_cpu_present_map __read_mostly = CPU_MASK_NONE; |
51 | cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly = | 54 | cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly = |
52 | { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; | 55 | { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; |
56 | cpumask_t cpu_core_map[NR_CPUS] __read_mostly = | ||
57 | { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; | ||
53 | static cpumask_t smp_commenced_mask; | 58 | static cpumask_t smp_commenced_mask; |
54 | static cpumask_t cpu_callout_map; | 59 | static cpumask_t cpu_callout_map; |
55 | 60 | ||
@@ -75,53 +80,6 @@ void smp_bogo(struct seq_file *m) | |||
75 | i, cpu_data(i).clock_tick); | 80 | i, cpu_data(i).clock_tick); |
76 | } | 81 | } |
77 | 82 | ||
78 | void __init smp_store_cpu_info(int id) | ||
79 | { | ||
80 | struct device_node *dp; | ||
81 | int def; | ||
82 | |||
83 | cpu_data(id).udelay_val = loops_per_jiffy; | ||
84 | |||
85 | cpu_find_by_mid(id, &dp); | ||
86 | cpu_data(id).clock_tick = | ||
87 | of_getintprop_default(dp, "clock-frequency", 0); | ||
88 | |||
89 | def = ((tlb_type == hypervisor) ? (8 * 1024) : (16 * 1024)); | ||
90 | cpu_data(id).dcache_size = | ||
91 | of_getintprop_default(dp, "dcache-size", def); | ||
92 | |||
93 | def = 32; | ||
94 | cpu_data(id).dcache_line_size = | ||
95 | of_getintprop_default(dp, "dcache-line-size", def); | ||
96 | |||
97 | def = 16 * 1024; | ||
98 | cpu_data(id).icache_size = | ||
99 | of_getintprop_default(dp, "icache-size", def); | ||
100 | |||
101 | def = 32; | ||
102 | cpu_data(id).icache_line_size = | ||
103 | of_getintprop_default(dp, "icache-line-size", def); | ||
104 | |||
105 | def = ((tlb_type == hypervisor) ? | ||
106 | (3 * 1024 * 1024) : | ||
107 | (4 * 1024 * 1024)); | ||
108 | cpu_data(id).ecache_size = | ||
109 | of_getintprop_default(dp, "ecache-size", def); | ||
110 | |||
111 | def = 64; | ||
112 | cpu_data(id).ecache_line_size = | ||
113 | of_getintprop_default(dp, "ecache-line-size", def); | ||
114 | |||
115 | printk("CPU[%d]: Caches " | ||
116 | "D[sz(%d):line_sz(%d)] " | ||
117 | "I[sz(%d):line_sz(%d)] " | ||
118 | "E[sz(%d):line_sz(%d)]\n", | ||
119 | id, | ||
120 | cpu_data(id).dcache_size, cpu_data(id).dcache_line_size, | ||
121 | cpu_data(id).icache_size, cpu_data(id).icache_line_size, | ||
122 | cpu_data(id).ecache_size, cpu_data(id).ecache_line_size); | ||
123 | } | ||
124 | |||
125 | extern void setup_sparc64_timer(void); | 83 | extern void setup_sparc64_timer(void); |
126 | 84 | ||
127 | static volatile unsigned long callin_flag = 0; | 85 | static volatile unsigned long callin_flag = 0; |
@@ -145,7 +103,7 @@ void __init smp_callin(void) | |||
145 | local_irq_enable(); | 103 | local_irq_enable(); |
146 | 104 | ||
147 | calibrate_delay(); | 105 | calibrate_delay(); |
148 | smp_store_cpu_info(cpuid); | 106 | cpu_data(cpuid).udelay_val = loops_per_jiffy; |
149 | callin_flag = 1; | 107 | callin_flag = 1; |
150 | __asm__ __volatile__("membar #Sync\n\t" | 108 | __asm__ __volatile__("membar #Sync\n\t" |
151 | "flush %%g6" : : : "memory"); | 109 | "flush %%g6" : : : "memory"); |
@@ -340,9 +298,8 @@ static int __devinit smp_boot_one_cpu(unsigned int cpu) | |||
340 | 298 | ||
341 | prom_startcpu_cpuid(cpu, entry, cookie); | 299 | prom_startcpu_cpuid(cpu, entry, cookie); |
342 | } else { | 300 | } else { |
343 | struct device_node *dp; | 301 | struct device_node *dp = of_find_node_by_cpuid(cpu); |
344 | 302 | ||
345 | cpu_find_by_mid(cpu, &dp); | ||
346 | prom_startcpu(dp->node, entry, cookie); | 303 | prom_startcpu(dp->node, entry, cookie); |
347 | } | 304 | } |
348 | 305 | ||
@@ -447,7 +404,7 @@ static __inline__ void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, c | |||
447 | static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask) | 404 | static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask) |
448 | { | 405 | { |
449 | u64 pstate, ver; | 406 | u64 pstate, ver; |
450 | int nack_busy_id, is_jbus; | 407 | int nack_busy_id, is_jbus, need_more; |
451 | 408 | ||
452 | if (cpus_empty(mask)) | 409 | if (cpus_empty(mask)) |
453 | return; | 410 | return; |
@@ -463,6 +420,7 @@ static void cheetah_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mas | |||
463 | __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); | 420 | __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); |
464 | 421 | ||
465 | retry: | 422 | retry: |
423 | need_more = 0; | ||
466 | __asm__ __volatile__("wrpr %0, %1, %%pstate\n\t" | 424 | __asm__ __volatile__("wrpr %0, %1, %%pstate\n\t" |
467 | : : "r" (pstate), "i" (PSTATE_IE)); | 425 | : : "r" (pstate), "i" (PSTATE_IE)); |
468 | 426 | ||
@@ -491,6 +449,10 @@ retry: | |||
491 | : /* no outputs */ | 449 | : /* no outputs */ |
492 | : "r" (target), "i" (ASI_INTR_W)); | 450 | : "r" (target), "i" (ASI_INTR_W)); |
493 | nack_busy_id++; | 451 | nack_busy_id++; |
452 | if (nack_busy_id == 32) { | ||
453 | need_more = 1; | ||
454 | break; | ||
455 | } | ||
494 | } | 456 | } |
495 | } | 457 | } |
496 | 458 | ||
@@ -507,6 +469,16 @@ retry: | |||
507 | if (dispatch_stat == 0UL) { | 469 | if (dispatch_stat == 0UL) { |
508 | __asm__ __volatile__("wrpr %0, 0x0, %%pstate" | 470 | __asm__ __volatile__("wrpr %0, 0x0, %%pstate" |
509 | : : "r" (pstate)); | 471 | : : "r" (pstate)); |
472 | if (unlikely(need_more)) { | ||
473 | int i, cnt = 0; | ||
474 | for_each_cpu_mask(i, mask) { | ||
475 | cpu_clear(i, mask); | ||
476 | cnt++; | ||
477 | if (cnt == 32) | ||
478 | break; | ||
479 | } | ||
480 | goto retry; | ||
481 | } | ||
510 | return; | 482 | return; |
511 | } | 483 | } |
512 | if (!--stuck) | 484 | if (!--stuck) |
@@ -544,6 +516,8 @@ retry: | |||
544 | if ((dispatch_stat & check_mask) == 0) | 516 | if ((dispatch_stat & check_mask) == 0) |
545 | cpu_clear(i, mask); | 517 | cpu_clear(i, mask); |
546 | this_busy_nack += 2; | 518 | this_busy_nack += 2; |
519 | if (this_busy_nack == 64) | ||
520 | break; | ||
547 | } | 521 | } |
548 | 522 | ||
549 | goto retry; | 523 | goto retry; |
@@ -1191,23 +1165,14 @@ int setup_profiling_timer(unsigned int multiplier) | |||
1191 | 1165 | ||
1192 | static void __init smp_tune_scheduling(void) | 1166 | static void __init smp_tune_scheduling(void) |
1193 | { | 1167 | { |
1194 | struct device_node *dp; | 1168 | unsigned int smallest = ~0U; |
1195 | int instance; | 1169 | int i; |
1196 | unsigned int def, smallest = ~0U; | ||
1197 | |||
1198 | def = ((tlb_type == hypervisor) ? | ||
1199 | (3 * 1024 * 1024) : | ||
1200 | (4 * 1024 * 1024)); | ||
1201 | 1170 | ||
1202 | instance = 0; | 1171 | for (i = 0; i < NR_CPUS; i++) { |
1203 | while (!cpu_find_by_instance(instance, &dp, NULL)) { | 1172 | unsigned int val = cpu_data(i).ecache_size; |
1204 | unsigned int val; | ||
1205 | 1173 | ||
1206 | val = of_getintprop_default(dp, "ecache-size", def); | 1174 | if (val && val < smallest) |
1207 | if (val < smallest) | ||
1208 | smallest = val; | 1175 | smallest = val; |
1209 | |||
1210 | instance++; | ||
1211 | } | 1176 | } |
1212 | 1177 | ||
1213 | /* Any value less than 256K is nonsense. */ | 1178 | /* Any value less than 256K is nonsense. */ |
@@ -1230,60 +1195,59 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
1230 | int i; | 1195 | int i; |
1231 | 1196 | ||
1232 | if (num_possible_cpus() > max_cpus) { | 1197 | if (num_possible_cpus() > max_cpus) { |
1233 | int instance, mid; | 1198 | for_each_possible_cpu(i) { |
1234 | 1199 | if (i != boot_cpu_id) { | |
1235 | instance = 0; | 1200 | cpu_clear(i, phys_cpu_present_map); |
1236 | while (!cpu_find_by_instance(instance, NULL, &mid)) { | 1201 | cpu_clear(i, cpu_present_map); |
1237 | if (mid != boot_cpu_id) { | ||
1238 | cpu_clear(mid, phys_cpu_present_map); | ||
1239 | cpu_clear(mid, cpu_present_map); | ||
1240 | if (num_possible_cpus() <= max_cpus) | 1202 | if (num_possible_cpus() <= max_cpus) |
1241 | break; | 1203 | break; |
1242 | } | 1204 | } |
1243 | instance++; | ||
1244 | } | 1205 | } |
1245 | } | 1206 | } |
1246 | 1207 | ||
1208 | cpu_data(boot_cpu_id).udelay_val = loops_per_jiffy; | ||
1209 | smp_tune_scheduling(); | ||
1210 | } | ||
1211 | |||
1212 | void __devinit smp_prepare_boot_cpu(void) | ||
1213 | { | ||
1214 | } | ||
1215 | |||
1216 | void __devinit smp_fill_in_sib_core_maps(void) | ||
1217 | { | ||
1218 | unsigned int i; | ||
1219 | |||
1247 | for_each_possible_cpu(i) { | 1220 | for_each_possible_cpu(i) { |
1248 | if (tlb_type == hypervisor) { | 1221 | unsigned int j; |
1249 | int j; | ||
1250 | 1222 | ||
1251 | /* XXX get this mapping from machine description */ | 1223 | if (cpu_data(i).core_id == 0) { |
1252 | for_each_possible_cpu(j) { | 1224 | cpu_set(i, cpu_core_map[i]); |
1253 | if ((j >> 2) == (i >> 2)) | 1225 | continue; |
1254 | cpu_set(j, cpu_sibling_map[i]); | 1226 | } |
1255 | } | 1227 | |
1256 | } else { | 1228 | for_each_possible_cpu(j) { |
1257 | cpu_set(i, cpu_sibling_map[i]); | 1229 | if (cpu_data(i).core_id == |
1230 | cpu_data(j).core_id) | ||
1231 | cpu_set(j, cpu_core_map[i]); | ||
1258 | } | 1232 | } |
1259 | } | 1233 | } |
1260 | 1234 | ||
1261 | smp_store_cpu_info(boot_cpu_id); | 1235 | for_each_possible_cpu(i) { |
1262 | smp_tune_scheduling(); | 1236 | unsigned int j; |
1263 | } | ||
1264 | 1237 | ||
1265 | /* Set this up early so that things like the scheduler can init | 1238 | if (cpu_data(i).proc_id == -1) { |
1266 | * properly. We use the same cpu mask for both the present and | 1239 | cpu_set(i, cpu_sibling_map[i]); |
1267 | * possible cpu map. | 1240 | continue; |
1268 | */ | 1241 | } |
1269 | void __init smp_setup_cpu_possible_map(void) | ||
1270 | { | ||
1271 | int instance, mid; | ||
1272 | 1242 | ||
1273 | instance = 0; | 1243 | for_each_possible_cpu(j) { |
1274 | while (!cpu_find_by_instance(instance, NULL, &mid)) { | 1244 | if (cpu_data(i).proc_id == |
1275 | if (mid < NR_CPUS) { | 1245 | cpu_data(j).proc_id) |
1276 | cpu_set(mid, phys_cpu_present_map); | 1246 | cpu_set(j, cpu_sibling_map[i]); |
1277 | cpu_set(mid, cpu_present_map); | ||
1278 | } | 1247 | } |
1279 | instance++; | ||
1280 | } | 1248 | } |
1281 | } | 1249 | } |
1282 | 1250 | ||
1283 | void __devinit smp_prepare_boot_cpu(void) | ||
1284 | { | ||
1285 | } | ||
1286 | |||
1287 | int __cpuinit __cpu_up(unsigned int cpu) | 1251 | int __cpuinit __cpu_up(unsigned int cpu) |
1288 | { | 1252 | { |
1289 | int ret = smp_boot_one_cpu(cpu); | 1253 | int ret = smp_boot_one_cpu(cpu); |
@@ -1337,7 +1301,7 @@ unsigned long __per_cpu_shift __read_mostly; | |||
1337 | EXPORT_SYMBOL(__per_cpu_base); | 1301 | EXPORT_SYMBOL(__per_cpu_base); |
1338 | EXPORT_SYMBOL(__per_cpu_shift); | 1302 | EXPORT_SYMBOL(__per_cpu_shift); |
1339 | 1303 | ||
1340 | void __init setup_per_cpu_areas(void) | 1304 | void __init real_setup_per_cpu_areas(void) |
1341 | { | 1305 | { |
1342 | unsigned long goal, size, i; | 1306 | unsigned long goal, size, i; |
1343 | char *ptr; | 1307 | char *ptr; |
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index d00f51a5683f..6fa761612899 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/syscalls.h> | 24 | #include <linux/syscalls.h> |
25 | #include <linux/percpu.h> | 25 | #include <linux/percpu.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/rwsem.h> | ||
27 | #include <net/compat.h> | 28 | #include <net/compat.h> |
28 | 29 | ||
29 | #include <asm/oplib.h> | 30 | #include <asm/oplib.h> |
@@ -58,7 +59,6 @@ | |||
58 | #include <asm/ns87303.h> | 59 | #include <asm/ns87303.h> |
59 | #include <asm/timer.h> | 60 | #include <asm/timer.h> |
60 | #include <asm/cpudata.h> | 61 | #include <asm/cpudata.h> |
61 | #include <asm/rwsem.h> | ||
62 | 62 | ||
63 | struct poll { | 63 | struct poll { |
64 | int fd; | 64 | int fd; |
diff --git a/arch/sparc64/kernel/sstate.c b/arch/sparc64/kernel/sstate.c new file mode 100644 index 000000000000..5b6e75b7f052 --- /dev/null +++ b/arch/sparc64/kernel/sstate.c | |||
@@ -0,0 +1,104 @@ | |||
1 | /* sstate.c: System soft state support. | ||
2 | * | ||
3 | * Copyright (C) 2007 David S. Miller <davem@davemloft.net> | ||
4 | */ | ||
5 | |||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/notifier.h> | ||
8 | #include <linux/init.h> | ||
9 | |||
10 | #include <asm/hypervisor.h> | ||
11 | #include <asm/sstate.h> | ||
12 | #include <asm/oplib.h> | ||
13 | #include <asm/head.h> | ||
14 | #include <asm/io.h> | ||
15 | |||
16 | static int hv_supports_soft_state; | ||
17 | |||
18 | static unsigned long kimage_addr_to_ra(const char *p) | ||
19 | { | ||
20 | unsigned long val = (unsigned long) p; | ||
21 | |||
22 | return kern_base + (val - KERNBASE); | ||
23 | } | ||
24 | |||
25 | static void do_set_sstate(unsigned long state, const char *msg) | ||
26 | { | ||
27 | unsigned long err; | ||
28 | |||
29 | if (!hv_supports_soft_state) | ||
30 | return; | ||
31 | |||
32 | err = sun4v_mach_set_soft_state(state, kimage_addr_to_ra(msg)); | ||
33 | if (err) { | ||
34 | printk(KERN_WARNING "SSTATE: Failed to set soft-state to " | ||
35 | "state[%lx] msg[%s], err=%lu\n", | ||
36 | state, msg, err); | ||
37 | } | ||
38 | } | ||
39 | |||
40 | static const char booting_msg[32] __attribute__((aligned(32))) = | ||
41 | "Linux booting"; | ||
42 | static const char running_msg[32] __attribute__((aligned(32))) = | ||
43 | "Linux running"; | ||
44 | static const char halting_msg[32] __attribute__((aligned(32))) = | ||
45 | "Linux halting"; | ||
46 | static const char poweroff_msg[32] __attribute__((aligned(32))) = | ||
47 | "Linux powering off"; | ||
48 | static const char rebooting_msg[32] __attribute__((aligned(32))) = | ||
49 | "Linux rebooting"; | ||
50 | static const char panicing_msg[32] __attribute__((aligned(32))) = | ||
51 | "Linux panicing"; | ||
52 | |||
53 | void sstate_booting(void) | ||
54 | { | ||
55 | do_set_sstate(HV_SOFT_STATE_TRANSITION, booting_msg); | ||
56 | } | ||
57 | |||
58 | void sstate_running(void) | ||
59 | { | ||
60 | do_set_sstate(HV_SOFT_STATE_NORMAL, running_msg); | ||
61 | } | ||
62 | |||
63 | void sstate_halt(void) | ||
64 | { | ||
65 | do_set_sstate(HV_SOFT_STATE_TRANSITION, halting_msg); | ||
66 | } | ||
67 | |||
68 | void sstate_poweroff(void) | ||
69 | { | ||
70 | do_set_sstate(HV_SOFT_STATE_TRANSITION, poweroff_msg); | ||
71 | } | ||
72 | |||
73 | void sstate_reboot(void) | ||
74 | { | ||
75 | do_set_sstate(HV_SOFT_STATE_TRANSITION, rebooting_msg); | ||
76 | } | ||
77 | |||
78 | static int sstate_panic_event(struct notifier_block *n, unsigned long event, void *ptr) | ||
79 | { | ||
80 | do_set_sstate(HV_SOFT_STATE_TRANSITION, panicing_msg); | ||
81 | |||
82 | return NOTIFY_DONE; | ||
83 | } | ||
84 | |||
85 | static struct notifier_block sstate_panic_block = { | ||
86 | .notifier_call = sstate_panic_event, | ||
87 | .priority = INT_MAX, | ||
88 | }; | ||
89 | |||
90 | void __init sun4v_sstate_init(void) | ||
91 | { | ||
92 | unsigned long major, minor; | ||
93 | |||
94 | major = 1; | ||
95 | minor = 0; | ||
96 | if (sun4v_hvapi_register(HV_GRP_SOFT_STATE, major, &minor)) | ||
97 | return; | ||
98 | |||
99 | hv_supports_soft_state = 1; | ||
100 | |||
101 | prom_sun4v_guest_soft_state(); | ||
102 | atomic_notifier_chain_register(&panic_notifier_list, | ||
103 | &sstate_panic_block); | ||
104 | } | ||
diff --git a/arch/sparc64/kernel/sun4v_ivec.S b/arch/sparc64/kernel/sun4v_ivec.S index 405855dd886b..574bc248bca6 100644 --- a/arch/sparc64/kernel/sun4v_ivec.S +++ b/arch/sparc64/kernel/sun4v_ivec.S | |||
@@ -22,12 +22,12 @@ sun4v_cpu_mondo: | |||
22 | be,pn %xcc, sun4v_cpu_mondo_queue_empty | 22 | be,pn %xcc, sun4v_cpu_mondo_queue_empty |
23 | nop | 23 | nop |
24 | 24 | ||
25 | /* Get &trap_block[smp_processor_id()] into %g3. */ | 25 | /* Get &trap_block[smp_processor_id()] into %g4. */ |
26 | ldxa [%g0] ASI_SCRATCHPAD, %g3 | 26 | ldxa [%g0] ASI_SCRATCHPAD, %g4 |
27 | sub %g3, TRAP_PER_CPU_FAULT_INFO, %g3 | 27 | sub %g4, TRAP_PER_CPU_FAULT_INFO, %g4 |
28 | 28 | ||
29 | /* Get CPU mondo queue base phys address into %g7. */ | 29 | /* Get CPU mondo queue base phys address into %g7. */ |
30 | ldx [%g3 + TRAP_PER_CPU_CPU_MONDO_PA], %g7 | 30 | ldx [%g4 + TRAP_PER_CPU_CPU_MONDO_PA], %g7 |
31 | 31 | ||
32 | /* Now get the cross-call arguments and handler PC, same | 32 | /* Now get the cross-call arguments and handler PC, same |
33 | * layout as sun4u: | 33 | * layout as sun4u: |
@@ -47,8 +47,7 @@ sun4v_cpu_mondo: | |||
47 | add %g2, 0x40 - 0x8 - 0x8, %g2 | 47 | add %g2, 0x40 - 0x8 - 0x8, %g2 |
48 | 48 | ||
49 | /* Update queue head pointer. */ | 49 | /* Update queue head pointer. */ |
50 | sethi %hi(8192 - 1), %g4 | 50 | lduw [%g4 + TRAP_PER_CPU_CPU_MONDO_QMASK], %g4 |
51 | or %g4, %lo(8192 - 1), %g4 | ||
52 | and %g2, %g4, %g2 | 51 | and %g2, %g4, %g2 |
53 | 52 | ||
54 | mov INTRQ_CPU_MONDO_HEAD, %g4 | 53 | mov INTRQ_CPU_MONDO_HEAD, %g4 |
@@ -71,12 +70,12 @@ sun4v_dev_mondo: | |||
71 | be,pn %xcc, sun4v_dev_mondo_queue_empty | 70 | be,pn %xcc, sun4v_dev_mondo_queue_empty |
72 | nop | 71 | nop |
73 | 72 | ||
74 | /* Get &trap_block[smp_processor_id()] into %g3. */ | 73 | /* Get &trap_block[smp_processor_id()] into %g4. */ |
75 | ldxa [%g0] ASI_SCRATCHPAD, %g3 | 74 | ldxa [%g0] ASI_SCRATCHPAD, %g4 |
76 | sub %g3, TRAP_PER_CPU_FAULT_INFO, %g3 | 75 | sub %g4, TRAP_PER_CPU_FAULT_INFO, %g4 |
77 | 76 | ||
78 | /* Get DEV mondo queue base phys address into %g5. */ | 77 | /* Get DEV mondo queue base phys address into %g5. */ |
79 | ldx [%g3 + TRAP_PER_CPU_DEV_MONDO_PA], %g5 | 78 | ldx [%g4 + TRAP_PER_CPU_DEV_MONDO_PA], %g5 |
80 | 79 | ||
81 | /* Load IVEC into %g3. */ | 80 | /* Load IVEC into %g3. */ |
82 | ldxa [%g5 + %g2] ASI_PHYS_USE_EC, %g3 | 81 | ldxa [%g5 + %g2] ASI_PHYS_USE_EC, %g3 |
@@ -90,8 +89,7 @@ sun4v_dev_mondo: | |||
90 | */ | 89 | */ |
91 | 90 | ||
92 | /* Update queue head pointer, this frees up some registers. */ | 91 | /* Update queue head pointer, this frees up some registers. */ |
93 | sethi %hi(8192 - 1), %g4 | 92 | lduw [%g4 + TRAP_PER_CPU_DEV_MONDO_QMASK], %g4 |
94 | or %g4, %lo(8192 - 1), %g4 | ||
95 | and %g2, %g4, %g2 | 93 | and %g2, %g4, %g2 |
96 | 94 | ||
97 | mov INTRQ_DEVICE_MONDO_HEAD, %g4 | 95 | mov INTRQ_DEVICE_MONDO_HEAD, %g4 |
@@ -143,6 +141,8 @@ sun4v_res_mondo: | |||
143 | brnz,pn %g1, sun4v_res_mondo_queue_full | 141 | brnz,pn %g1, sun4v_res_mondo_queue_full |
144 | nop | 142 | nop |
145 | 143 | ||
144 | lduw [%g3 + TRAP_PER_CPU_RESUM_QMASK], %g4 | ||
145 | |||
146 | /* Remember this entry's offset in %g1. */ | 146 | /* Remember this entry's offset in %g1. */ |
147 | mov %g2, %g1 | 147 | mov %g2, %g1 |
148 | 148 | ||
@@ -173,8 +173,6 @@ sun4v_res_mondo: | |||
173 | add %g2, 0x08, %g2 | 173 | add %g2, 0x08, %g2 |
174 | 174 | ||
175 | /* Update queue head pointer. */ | 175 | /* Update queue head pointer. */ |
176 | sethi %hi(8192 - 1), %g4 | ||
177 | or %g4, %lo(8192 - 1), %g4 | ||
178 | and %g2, %g4, %g2 | 176 | and %g2, %g4, %g2 |
179 | 177 | ||
180 | mov INTRQ_RESUM_MONDO_HEAD, %g4 | 178 | mov INTRQ_RESUM_MONDO_HEAD, %g4 |
@@ -254,6 +252,8 @@ sun4v_nonres_mondo: | |||
254 | brnz,pn %g1, sun4v_nonres_mondo_queue_full | 252 | brnz,pn %g1, sun4v_nonres_mondo_queue_full |
255 | nop | 253 | nop |
256 | 254 | ||
255 | lduw [%g3 + TRAP_PER_CPU_NONRESUM_QMASK], %g4 | ||
256 | |||
257 | /* Remember this entry's offset in %g1. */ | 257 | /* Remember this entry's offset in %g1. */ |
258 | mov %g2, %g1 | 258 | mov %g2, %g1 |
259 | 259 | ||
@@ -284,8 +284,6 @@ sun4v_nonres_mondo: | |||
284 | add %g2, 0x08, %g2 | 284 | add %g2, 0x08, %g2 |
285 | 285 | ||
286 | /* Update queue head pointer. */ | 286 | /* Update queue head pointer. */ |
287 | sethi %hi(8192 - 1), %g4 | ||
288 | or %g4, %lo(8192 - 1), %g4 | ||
289 | and %g2, %g4, %g2 | 287 | and %g2, %g4, %g2 |
290 | 288 | ||
291 | mov INTRQ_NONRESUM_MONDO_HEAD, %g4 | 289 | mov INTRQ_NONRESUM_MONDO_HEAD, %g4 |
diff --git a/arch/sparc64/kernel/sysfs.c b/arch/sparc64/kernel/sysfs.c new file mode 100644 index 000000000000..cdb1477af89f --- /dev/null +++ b/arch/sparc64/kernel/sysfs.c | |||
@@ -0,0 +1,297 @@ | |||
1 | /* sysfs.c: Toplogy sysfs support code for sparc64. | ||
2 | * | ||
3 | * Copyright (C) 2007 David S. Miller <davem@davemloft.net> | ||
4 | */ | ||
5 | #include <linux/sysdev.h> | ||
6 | #include <linux/cpu.h> | ||
7 | #include <linux/smp.h> | ||
8 | #include <linux/percpu.h> | ||
9 | #include <linux/init.h> | ||
10 | |||
11 | #include <asm/hypervisor.h> | ||
12 | #include <asm/spitfire.h> | ||
13 | |||
14 | static DEFINE_PER_CPU(struct hv_mmu_statistics, mmu_stats) __attribute__((aligned(64))); | ||
15 | |||
16 | #define SHOW_MMUSTAT_ULONG(NAME) \ | ||
17 | static ssize_t show_##NAME(struct sys_device *dev, char *buf) \ | ||
18 | { \ | ||
19 | struct hv_mmu_statistics *p = &per_cpu(mmu_stats, dev->id); \ | ||
20 | return sprintf(buf, "%lu\n", p->NAME); \ | ||
21 | } \ | ||
22 | static SYSDEV_ATTR(NAME, 0444, show_##NAME, NULL) | ||
23 | |||
24 | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctx0_8k_tte); | ||
25 | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctx0_8k_tte); | ||
26 | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctx0_64k_tte); | ||
27 | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctx0_64k_tte); | ||
28 | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctx0_4mb_tte); | ||
29 | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctx0_4mb_tte); | ||
30 | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctx0_256mb_tte); | ||
31 | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctx0_256mb_tte); | ||
32 | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctxnon0_8k_tte); | ||
33 | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctxnon0_8k_tte); | ||
34 | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctxnon0_64k_tte); | ||
35 | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctxnon0_64k_tte); | ||
36 | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctxnon0_4mb_tte); | ||
37 | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctxnon0_4mb_tte); | ||
38 | SHOW_MMUSTAT_ULONG(immu_tsb_hits_ctxnon0_256mb_tte); | ||
39 | SHOW_MMUSTAT_ULONG(immu_tsb_ticks_ctxnon0_256mb_tte); | ||
40 | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctx0_8k_tte); | ||
41 | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctx0_8k_tte); | ||
42 | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctx0_64k_tte); | ||
43 | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctx0_64k_tte); | ||
44 | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctx0_4mb_tte); | ||
45 | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctx0_4mb_tte); | ||
46 | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctx0_256mb_tte); | ||
47 | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctx0_256mb_tte); | ||
48 | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctxnon0_8k_tte); | ||
49 | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctxnon0_8k_tte); | ||
50 | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctxnon0_64k_tte); | ||
51 | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctxnon0_64k_tte); | ||
52 | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctxnon0_4mb_tte); | ||
53 | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctxnon0_4mb_tte); | ||
54 | SHOW_MMUSTAT_ULONG(dmmu_tsb_hits_ctxnon0_256mb_tte); | ||
55 | SHOW_MMUSTAT_ULONG(dmmu_tsb_ticks_ctxnon0_256mb_tte); | ||
56 | |||
57 | static struct attribute *mmu_stat_attrs[] = { | ||
58 | &attr_immu_tsb_hits_ctx0_8k_tte.attr, | ||
59 | &attr_immu_tsb_ticks_ctx0_8k_tte.attr, | ||
60 | &attr_immu_tsb_hits_ctx0_64k_tte.attr, | ||
61 | &attr_immu_tsb_ticks_ctx0_64k_tte.attr, | ||
62 | &attr_immu_tsb_hits_ctx0_4mb_tte.attr, | ||
63 | &attr_immu_tsb_ticks_ctx0_4mb_tte.attr, | ||
64 | &attr_immu_tsb_hits_ctx0_256mb_tte.attr, | ||
65 | &attr_immu_tsb_ticks_ctx0_256mb_tte.attr, | ||
66 | &attr_immu_tsb_hits_ctxnon0_8k_tte.attr, | ||
67 | &attr_immu_tsb_ticks_ctxnon0_8k_tte.attr, | ||
68 | &attr_immu_tsb_hits_ctxnon0_64k_tte.attr, | ||
69 | &attr_immu_tsb_ticks_ctxnon0_64k_tte.attr, | ||
70 | &attr_immu_tsb_hits_ctxnon0_4mb_tte.attr, | ||
71 | &attr_immu_tsb_ticks_ctxnon0_4mb_tte.attr, | ||
72 | &attr_immu_tsb_hits_ctxnon0_256mb_tte.attr, | ||
73 | &attr_immu_tsb_ticks_ctxnon0_256mb_tte.attr, | ||
74 | &attr_dmmu_tsb_hits_ctx0_8k_tte.attr, | ||
75 | &attr_dmmu_tsb_ticks_ctx0_8k_tte.attr, | ||
76 | &attr_dmmu_tsb_hits_ctx0_64k_tte.attr, | ||
77 | &attr_dmmu_tsb_ticks_ctx0_64k_tte.attr, | ||
78 | &attr_dmmu_tsb_hits_ctx0_4mb_tte.attr, | ||
79 | &attr_dmmu_tsb_ticks_ctx0_4mb_tte.attr, | ||
80 | &attr_dmmu_tsb_hits_ctx0_256mb_tte.attr, | ||
81 | &attr_dmmu_tsb_ticks_ctx0_256mb_tte.attr, | ||
82 | &attr_dmmu_tsb_hits_ctxnon0_8k_tte.attr, | ||
83 | &attr_dmmu_tsb_ticks_ctxnon0_8k_tte.attr, | ||
84 | &attr_dmmu_tsb_hits_ctxnon0_64k_tte.attr, | ||
85 | &attr_dmmu_tsb_ticks_ctxnon0_64k_tte.attr, | ||
86 | &attr_dmmu_tsb_hits_ctxnon0_4mb_tte.attr, | ||
87 | &attr_dmmu_tsb_ticks_ctxnon0_4mb_tte.attr, | ||
88 | &attr_dmmu_tsb_hits_ctxnon0_256mb_tte.attr, | ||
89 | &attr_dmmu_tsb_ticks_ctxnon0_256mb_tte.attr, | ||
90 | NULL, | ||
91 | }; | ||
92 | |||
93 | static struct attribute_group mmu_stat_group = { | ||
94 | .attrs = mmu_stat_attrs, | ||
95 | .name = "mmu_stats", | ||
96 | }; | ||
97 | |||
98 | /* XXX convert to rusty's on_one_cpu */ | ||
99 | static unsigned long run_on_cpu(unsigned long cpu, | ||
100 | unsigned long (*func)(unsigned long), | ||
101 | unsigned long arg) | ||
102 | { | ||
103 | cpumask_t old_affinity = current->cpus_allowed; | ||
104 | unsigned long ret; | ||
105 | |||
106 | /* should return -EINVAL to userspace */ | ||
107 | if (set_cpus_allowed(current, cpumask_of_cpu(cpu))) | ||
108 | return 0; | ||
109 | |||
110 | ret = func(arg); | ||
111 | |||
112 | set_cpus_allowed(current, old_affinity); | ||
113 | |||
114 | return ret; | ||
115 | } | ||
116 | |||
117 | static unsigned long read_mmustat_enable(unsigned long junk) | ||
118 | { | ||
119 | unsigned long ra = 0; | ||
120 | |||
121 | sun4v_mmustat_info(&ra); | ||
122 | |||
123 | return ra != 0; | ||
124 | } | ||
125 | |||
126 | static unsigned long write_mmustat_enable(unsigned long val) | ||
127 | { | ||
128 | unsigned long ra, orig_ra; | ||
129 | |||
130 | if (val) | ||
131 | ra = __pa(&per_cpu(mmu_stats, smp_processor_id())); | ||
132 | else | ||
133 | ra = 0UL; | ||
134 | |||
135 | return sun4v_mmustat_conf(ra, &orig_ra); | ||
136 | } | ||
137 | |||
138 | static ssize_t show_mmustat_enable(struct sys_device *s, char *buf) | ||
139 | { | ||
140 | unsigned long val = run_on_cpu(s->id, read_mmustat_enable, 0); | ||
141 | return sprintf(buf, "%lx\n", val); | ||
142 | } | ||
143 | |||
144 | static ssize_t store_mmustat_enable(struct sys_device *s, const char *buf, size_t count) | ||
145 | { | ||
146 | unsigned long val, err; | ||
147 | int ret = sscanf(buf, "%ld", &val); | ||
148 | |||
149 | if (ret != 1) | ||
150 | return -EINVAL; | ||
151 | |||
152 | err = run_on_cpu(s->id, write_mmustat_enable, val); | ||
153 | if (err) | ||
154 | return -EIO; | ||
155 | |||
156 | return count; | ||
157 | } | ||
158 | |||
159 | static SYSDEV_ATTR(mmustat_enable, 0644, show_mmustat_enable, store_mmustat_enable); | ||
160 | |||
161 | static int mmu_stats_supported; | ||
162 | |||
163 | static int register_mmu_stats(struct sys_device *s) | ||
164 | { | ||
165 | if (!mmu_stats_supported) | ||
166 | return 0; | ||
167 | sysdev_create_file(s, &attr_mmustat_enable); | ||
168 | return sysfs_create_group(&s->kobj, &mmu_stat_group); | ||
169 | } | ||
170 | |||
171 | #ifdef CONFIG_HOTPLUG_CPU | ||
172 | static void unregister_mmu_stats(struct sys_device *s) | ||
173 | { | ||
174 | if (!mmu_stats_supported) | ||
175 | return; | ||
176 | sysfs_remove_group(&s->kobj, &mmu_stat_group); | ||
177 | sysdev_remove_file(s, &attr_mmustat_enable); | ||
178 | } | ||
179 | #endif | ||
180 | |||
181 | #define SHOW_CPUDATA_ULONG_NAME(NAME, MEMBER) \ | ||
182 | static ssize_t show_##NAME(struct sys_device *dev, char *buf) \ | ||
183 | { \ | ||
184 | cpuinfo_sparc *c = &cpu_data(dev->id); \ | ||
185 | return sprintf(buf, "%lu\n", c->MEMBER); \ | ||
186 | } | ||
187 | |||
188 | #define SHOW_CPUDATA_UINT_NAME(NAME, MEMBER) \ | ||
189 | static ssize_t show_##NAME(struct sys_device *dev, char *buf) \ | ||
190 | { \ | ||
191 | cpuinfo_sparc *c = &cpu_data(dev->id); \ | ||
192 | return sprintf(buf, "%u\n", c->MEMBER); \ | ||
193 | } | ||
194 | |||
195 | SHOW_CPUDATA_ULONG_NAME(clock_tick, clock_tick); | ||
196 | SHOW_CPUDATA_ULONG_NAME(udelay_val, udelay_val); | ||
197 | SHOW_CPUDATA_UINT_NAME(l1_dcache_size, dcache_size); | ||
198 | SHOW_CPUDATA_UINT_NAME(l1_dcache_line_size, dcache_line_size); | ||
199 | SHOW_CPUDATA_UINT_NAME(l1_icache_size, icache_size); | ||
200 | SHOW_CPUDATA_UINT_NAME(l1_icache_line_size, icache_line_size); | ||
201 | SHOW_CPUDATA_UINT_NAME(l2_cache_size, ecache_size); | ||
202 | SHOW_CPUDATA_UINT_NAME(l2_cache_line_size, ecache_line_size); | ||
203 | |||
204 | static struct sysdev_attribute cpu_core_attrs[] = { | ||
205 | _SYSDEV_ATTR(clock_tick, 0444, show_clock_tick, NULL), | ||
206 | _SYSDEV_ATTR(udelay_val, 0444, show_udelay_val, NULL), | ||
207 | _SYSDEV_ATTR(l1_dcache_size, 0444, show_l1_dcache_size, NULL), | ||
208 | _SYSDEV_ATTR(l1_dcache_line_size, 0444, show_l1_dcache_line_size, NULL), | ||
209 | _SYSDEV_ATTR(l1_icache_size, 0444, show_l1_icache_size, NULL), | ||
210 | _SYSDEV_ATTR(l1_icache_line_size, 0444, show_l1_icache_line_size, NULL), | ||
211 | _SYSDEV_ATTR(l2_cache_size, 0444, show_l2_cache_size, NULL), | ||
212 | _SYSDEV_ATTR(l2_cache_line_size, 0444, show_l2_cache_line_size, NULL), | ||
213 | }; | ||
214 | |||
215 | static DEFINE_PER_CPU(struct cpu, cpu_devices); | ||
216 | |||
217 | static void register_cpu_online(unsigned int cpu) | ||
218 | { | ||
219 | struct cpu *c = &per_cpu(cpu_devices, cpu); | ||
220 | struct sys_device *s = &c->sysdev; | ||
221 | int i; | ||
222 | |||
223 | for (i = 0; i < ARRAY_SIZE(cpu_core_attrs); i++) | ||
224 | sysdev_create_file(s, &cpu_core_attrs[i]); | ||
225 | |||
226 | register_mmu_stats(s); | ||
227 | } | ||
228 | |||
229 | #ifdef CONFIG_HOTPLUG_CPU | ||
230 | static void unregister_cpu_online(unsigned int cpu) | ||
231 | { | ||
232 | struct cpu *c = &per_cpu(cpu_devices, cpu); | ||
233 | struct sys_device *s = &c->sysdev; | ||
234 | int i; | ||
235 | |||
236 | unregister_mmu_stats(s); | ||
237 | for (i = 0; i < ARRAY_SIZE(cpu_core_attrs); i++) | ||
238 | sysdev_remove_file(s, &cpu_core_attrs[i]); | ||
239 | } | ||
240 | #endif | ||
241 | |||
242 | static int __cpuinit sysfs_cpu_notify(struct notifier_block *self, | ||
243 | unsigned long action, void *hcpu) | ||
244 | { | ||
245 | unsigned int cpu = (unsigned int)(long)hcpu; | ||
246 | |||
247 | switch (action) { | ||
248 | case CPU_ONLINE: | ||
249 | case CPU_ONLINE_FROZEN: | ||
250 | register_cpu_online(cpu); | ||
251 | break; | ||
252 | #ifdef CONFIG_HOTPLUG_CPU | ||
253 | case CPU_DEAD: | ||
254 | case CPU_DEAD_FROZEN: | ||
255 | unregister_cpu_online(cpu); | ||
256 | break; | ||
257 | #endif | ||
258 | } | ||
259 | return NOTIFY_OK; | ||
260 | } | ||
261 | |||
262 | static struct notifier_block __cpuinitdata sysfs_cpu_nb = { | ||
263 | .notifier_call = sysfs_cpu_notify, | ||
264 | }; | ||
265 | |||
266 | static void __init check_mmu_stats(void) | ||
267 | { | ||
268 | unsigned long dummy1, err; | ||
269 | |||
270 | if (tlb_type != hypervisor) | ||
271 | return; | ||
272 | |||
273 | err = sun4v_mmustat_info(&dummy1); | ||
274 | if (!err) | ||
275 | mmu_stats_supported = 1; | ||
276 | } | ||
277 | |||
278 | static int __init topology_init(void) | ||
279 | { | ||
280 | int cpu; | ||
281 | |||
282 | check_mmu_stats(); | ||
283 | |||
284 | register_cpu_notifier(&sysfs_cpu_nb); | ||
285 | |||
286 | for_each_possible_cpu(cpu) { | ||
287 | struct cpu *c = &per_cpu(cpu_devices, cpu); | ||
288 | |||
289 | register_cpu(c, cpu); | ||
290 | if (cpu_online(cpu)) | ||
291 | register_cpu_online(cpu); | ||
292 | } | ||
293 | |||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | subsys_initcall(topology_init); | ||
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index 2d63d7689962..a31a0439244f 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c | |||
@@ -680,22 +680,14 @@ static int starfire_set_time(u32 val) | |||
680 | 680 | ||
681 | static u32 hypervisor_get_time(void) | 681 | static u32 hypervisor_get_time(void) |
682 | { | 682 | { |
683 | register unsigned long func asm("%o5"); | 683 | unsigned long ret, time; |
684 | register unsigned long arg0 asm("%o0"); | ||
685 | register unsigned long arg1 asm("%o1"); | ||
686 | int retries = 10000; | 684 | int retries = 10000; |
687 | 685 | ||
688 | retry: | 686 | retry: |
689 | func = HV_FAST_TOD_GET; | 687 | ret = sun4v_tod_get(&time); |
690 | arg0 = 0; | 688 | if (ret == HV_EOK) |
691 | arg1 = 0; | 689 | return time; |
692 | __asm__ __volatile__("ta %6" | 690 | if (ret == HV_EWOULDBLOCK) { |
693 | : "=&r" (func), "=&r" (arg0), "=&r" (arg1) | ||
694 | : "0" (func), "1" (arg0), "2" (arg1), | ||
695 | "i" (HV_FAST_TRAP)); | ||
696 | if (arg0 == HV_EOK) | ||
697 | return arg1; | ||
698 | if (arg0 == HV_EWOULDBLOCK) { | ||
699 | if (--retries > 0) { | 691 | if (--retries > 0) { |
700 | udelay(100); | 692 | udelay(100); |
701 | goto retry; | 693 | goto retry; |
@@ -709,20 +701,14 @@ retry: | |||
709 | 701 | ||
710 | static int hypervisor_set_time(u32 secs) | 702 | static int hypervisor_set_time(u32 secs) |
711 | { | 703 | { |
712 | register unsigned long func asm("%o5"); | 704 | unsigned long ret; |
713 | register unsigned long arg0 asm("%o0"); | ||
714 | int retries = 10000; | 705 | int retries = 10000; |
715 | 706 | ||
716 | retry: | 707 | retry: |
717 | func = HV_FAST_TOD_SET; | 708 | ret = sun4v_tod_set(secs); |
718 | arg0 = secs; | 709 | if (ret == HV_EOK) |
719 | __asm__ __volatile__("ta %4" | ||
720 | : "=&r" (func), "=&r" (arg0) | ||
721 | : "0" (func), "1" (arg0), | ||
722 | "i" (HV_FAST_TRAP)); | ||
723 | if (arg0 == HV_EOK) | ||
724 | return 0; | 710 | return 0; |
725 | if (arg0 == HV_EWOULDBLOCK) { | 711 | if (ret == HV_EWOULDBLOCK) { |
726 | if (--retries > 0) { | 712 | if (--retries > 0) { |
727 | udelay(100); | 713 | udelay(100); |
728 | goto retry; | 714 | goto retry; |
@@ -862,7 +848,6 @@ fs_initcall(clock_init); | |||
862 | static unsigned long sparc64_init_timers(void) | 848 | static unsigned long sparc64_init_timers(void) |
863 | { | 849 | { |
864 | struct device_node *dp; | 850 | struct device_node *dp; |
865 | struct property *prop; | ||
866 | unsigned long clock; | 851 | unsigned long clock; |
867 | #ifdef CONFIG_SMP | 852 | #ifdef CONFIG_SMP |
868 | extern void smp_tick_init(void); | 853 | extern void smp_tick_init(void); |
@@ -879,17 +864,15 @@ static unsigned long sparc64_init_timers(void) | |||
879 | if (manuf == 0x17 && impl == 0x13) { | 864 | if (manuf == 0x17 && impl == 0x13) { |
880 | /* Hummingbird, aka Ultra-IIe */ | 865 | /* Hummingbird, aka Ultra-IIe */ |
881 | tick_ops = &hbtick_operations; | 866 | tick_ops = &hbtick_operations; |
882 | prop = of_find_property(dp, "stick-frequency", NULL); | 867 | clock = of_getintprop_default(dp, "stick-frequency", 0); |
883 | } else { | 868 | } else { |
884 | tick_ops = &tick_operations; | 869 | tick_ops = &tick_operations; |
885 | cpu_find_by_instance(0, &dp, NULL); | 870 | clock = local_cpu_data().clock_tick; |
886 | prop = of_find_property(dp, "clock-frequency", NULL); | ||
887 | } | 871 | } |
888 | } else { | 872 | } else { |
889 | tick_ops = &stick_operations; | 873 | tick_ops = &stick_operations; |
890 | prop = of_find_property(dp, "stick-frequency", NULL); | 874 | clock = of_getintprop_default(dp, "stick-frequency", 0); |
891 | } | 875 | } |
892 | clock = *(unsigned int *) prop->value; | ||
893 | 876 | ||
894 | #ifdef CONFIG_SMP | 877 | #ifdef CONFIG_SMP |
895 | smp_tick_init(); | 878 | smp_tick_init(); |
@@ -1365,6 +1348,7 @@ static int hypervisor_set_rtc_time(struct rtc_time *time) | |||
1365 | return hypervisor_set_time(seconds); | 1348 | return hypervisor_set_time(seconds); |
1366 | } | 1349 | } |
1367 | 1350 | ||
1351 | #ifdef CONFIG_PCI | ||
1368 | static void bq4802_get_rtc_time(struct rtc_time *time) | 1352 | static void bq4802_get_rtc_time(struct rtc_time *time) |
1369 | { | 1353 | { |
1370 | unsigned char val = readb(bq4802_regs + 0x0e); | 1354 | unsigned char val = readb(bq4802_regs + 0x0e); |
@@ -1436,6 +1420,7 @@ static int bq4802_set_rtc_time(struct rtc_time *time) | |||
1436 | 1420 | ||
1437 | return 0; | 1421 | return 0; |
1438 | } | 1422 | } |
1423 | #endif /* CONFIG_PCI */ | ||
1439 | 1424 | ||
1440 | struct mini_rtc_ops { | 1425 | struct mini_rtc_ops { |
1441 | void (*get_rtc_time)(struct rtc_time *); | 1426 | void (*get_rtc_time)(struct rtc_time *); |
@@ -1452,10 +1437,12 @@ static struct mini_rtc_ops hypervisor_rtc_ops = { | |||
1452 | .set_rtc_time = hypervisor_set_rtc_time, | 1437 | .set_rtc_time = hypervisor_set_rtc_time, |
1453 | }; | 1438 | }; |
1454 | 1439 | ||
1440 | #ifdef CONFIG_PCI | ||
1455 | static struct mini_rtc_ops bq4802_rtc_ops = { | 1441 | static struct mini_rtc_ops bq4802_rtc_ops = { |
1456 | .get_rtc_time = bq4802_get_rtc_time, | 1442 | .get_rtc_time = bq4802_get_rtc_time, |
1457 | .set_rtc_time = bq4802_set_rtc_time, | 1443 | .set_rtc_time = bq4802_set_rtc_time, |
1458 | }; | 1444 | }; |
1445 | #endif /* CONFIG_PCI */ | ||
1459 | 1446 | ||
1460 | static struct mini_rtc_ops *mini_rtc_ops; | 1447 | static struct mini_rtc_ops *mini_rtc_ops; |
1461 | 1448 | ||
@@ -1579,8 +1566,10 @@ static int __init rtc_mini_init(void) | |||
1579 | mini_rtc_ops = &hypervisor_rtc_ops; | 1566 | mini_rtc_ops = &hypervisor_rtc_ops; |
1580 | else if (this_is_starfire) | 1567 | else if (this_is_starfire) |
1581 | mini_rtc_ops = &starfire_rtc_ops; | 1568 | mini_rtc_ops = &starfire_rtc_ops; |
1569 | #ifdef CONFIG_PCI | ||
1582 | else if (bq4802_regs) | 1570 | else if (bq4802_regs) |
1583 | mini_rtc_ops = &bq4802_rtc_ops; | 1571 | mini_rtc_ops = &bq4802_rtc_ops; |
1572 | #endif /* CONFIG_PCI */ | ||
1584 | else | 1573 | else |
1585 | return -ENODEV; | 1574 | return -ENODEV; |
1586 | 1575 | ||
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index d0fde36395b4..00a9e3286c83 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c | |||
@@ -795,8 +795,7 @@ extern unsigned int cheetah_deferred_trap_vector[], cheetah_deferred_trap_vector | |||
795 | void __init cheetah_ecache_flush_init(void) | 795 | void __init cheetah_ecache_flush_init(void) |
796 | { | 796 | { |
797 | unsigned long largest_size, smallest_linesize, order, ver; | 797 | unsigned long largest_size, smallest_linesize, order, ver; |
798 | struct device_node *dp; | 798 | int i, sz; |
799 | int i, instance, sz; | ||
800 | 799 | ||
801 | /* Scan all cpu device tree nodes, note two values: | 800 | /* Scan all cpu device tree nodes, note two values: |
802 | * 1) largest E-cache size | 801 | * 1) largest E-cache size |
@@ -805,18 +804,20 @@ void __init cheetah_ecache_flush_init(void) | |||
805 | largest_size = 0UL; | 804 | largest_size = 0UL; |
806 | smallest_linesize = ~0UL; | 805 | smallest_linesize = ~0UL; |
807 | 806 | ||
808 | instance = 0; | 807 | for (i = 0; i < NR_CPUS; i++) { |
809 | while (!cpu_find_by_instance(instance, &dp, NULL)) { | ||
810 | unsigned long val; | 808 | unsigned long val; |
811 | 809 | ||
812 | val = of_getintprop_default(dp, "ecache-size", | 810 | val = cpu_data(i).ecache_size; |
813 | (2 * 1024 * 1024)); | 811 | if (!val) |
812 | continue; | ||
813 | |||
814 | if (val > largest_size) | 814 | if (val > largest_size) |
815 | largest_size = val; | 815 | largest_size = val; |
816 | val = of_getintprop_default(dp, "ecache-line-size", 64); | 816 | |
817 | val = cpu_data(i).ecache_line_size; | ||
817 | if (val < smallest_linesize) | 818 | if (val < smallest_linesize) |
818 | smallest_linesize = val; | 819 | smallest_linesize = val; |
819 | instance++; | 820 | |
820 | } | 821 | } |
821 | 822 | ||
822 | if (largest_size == 0UL || smallest_linesize == ~0UL) { | 823 | if (largest_size == 0UL || smallest_linesize == ~0UL) { |
@@ -2564,7 +2565,15 @@ void __init trap_init(void) | |||
2564 | (TRAP_PER_CPU_TSB_HUGE_TEMP != | 2565 | (TRAP_PER_CPU_TSB_HUGE_TEMP != |
2565 | offsetof(struct trap_per_cpu, tsb_huge_temp)) || | 2566 | offsetof(struct trap_per_cpu, tsb_huge_temp)) || |
2566 | (TRAP_PER_CPU_IRQ_WORKLIST != | 2567 | (TRAP_PER_CPU_IRQ_WORKLIST != |
2567 | offsetof(struct trap_per_cpu, irq_worklist))) | 2568 | offsetof(struct trap_per_cpu, irq_worklist)) || |
2569 | (TRAP_PER_CPU_CPU_MONDO_QMASK != | ||
2570 | offsetof(struct trap_per_cpu, cpu_mondo_qmask)) || | ||
2571 | (TRAP_PER_CPU_DEV_MONDO_QMASK != | ||
2572 | offsetof(struct trap_per_cpu, dev_mondo_qmask)) || | ||
2573 | (TRAP_PER_CPU_RESUM_QMASK != | ||
2574 | offsetof(struct trap_per_cpu, resum_qmask)) || | ||
2575 | (TRAP_PER_CPU_NONRESUM_QMASK != | ||
2576 | offsetof(struct trap_per_cpu, nonresum_qmask))) | ||
2568 | trap_per_cpu_offsets_are_bolixed_dave(); | 2577 | trap_per_cpu_offsets_are_bolixed_dave(); |
2569 | 2578 | ||
2570 | if ((TSB_CONFIG_TSB != | 2579 | if ((TSB_CONFIG_TSB != |
diff --git a/arch/sparc64/kernel/vmlinux.lds.S b/arch/sparc64/kernel/vmlinux.lds.S index fb648de18a8d..3ad10f3027e4 100644 --- a/arch/sparc64/kernel/vmlinux.lds.S +++ b/arch/sparc64/kernel/vmlinux.lds.S | |||
@@ -1,5 +1,6 @@ | |||
1 | /* ld script to make UltraLinux kernel */ | 1 | /* ld script to make UltraLinux kernel */ |
2 | 2 | ||
3 | #include <asm/page.h> | ||
3 | #include <asm-generic/vmlinux.lds.h> | 4 | #include <asm-generic/vmlinux.lds.h> |
4 | 5 | ||
5 | OUTPUT_FORMAT("elf64-sparc", "elf64-sparc", "elf64-sparc") | 6 | OUTPUT_FORMAT("elf64-sparc", "elf64-sparc", "elf64-sparc") |
@@ -23,7 +24,7 @@ SECTIONS | |||
23 | _etext = .; | 24 | _etext = .; |
24 | PROVIDE (etext = .); | 25 | PROVIDE (etext = .); |
25 | 26 | ||
26 | RODATA | 27 | RO_DATA(PAGE_SIZE) |
27 | 28 | ||
28 | .data : | 29 | .data : |
29 | { | 30 | { |
@@ -44,7 +45,7 @@ SECTIONS | |||
44 | __ex_table : { *(__ex_table) } | 45 | __ex_table : { *(__ex_table) } |
45 | __stop___ex_table = .; | 46 | __stop___ex_table = .; |
46 | 47 | ||
47 | . = ALIGN(8192); | 48 | . = ALIGN(PAGE_SIZE); |
48 | __init_begin = .; | 49 | __init_begin = .; |
49 | .init.text : { | 50 | .init.text : { |
50 | _sinittext = .; | 51 | _sinittext = .; |
@@ -83,17 +84,17 @@ SECTIONS | |||
83 | __sun4v_2insn_patch_end = .; | 84 | __sun4v_2insn_patch_end = .; |
84 | 85 | ||
85 | #ifdef CONFIG_BLK_DEV_INITRD | 86 | #ifdef CONFIG_BLK_DEV_INITRD |
86 | . = ALIGN(8192); | 87 | . = ALIGN(PAGE_SIZE); |
87 | __initramfs_start = .; | 88 | __initramfs_start = .; |
88 | .init.ramfs : { *(.init.ramfs) } | 89 | .init.ramfs : { *(.init.ramfs) } |
89 | __initramfs_end = .; | 90 | __initramfs_end = .; |
90 | #endif | 91 | #endif |
91 | 92 | ||
92 | . = ALIGN(8192); | 93 | . = ALIGN(PAGE_SIZE); |
93 | __per_cpu_start = .; | 94 | __per_cpu_start = .; |
94 | .data.percpu : { *(.data.percpu) } | 95 | .data.percpu : { *(.data.percpu) } |
95 | __per_cpu_end = .; | 96 | __per_cpu_end = .; |
96 | . = ALIGN(8192); | 97 | . = ALIGN(PAGE_SIZE); |
97 | __init_end = .; | 98 | __init_end = .; |
98 | __bss_start = .; | 99 | __bss_start = .; |
99 | .sbss : { *(.sbss) *(.scommon) } | 100 | .sbss : { *(.sbss) *(.scommon) } |
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index 6e5b01d779d2..3010227fe243 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/kprobes.h> | 23 | #include <linux/kprobes.h> |
24 | #include <linux/cache.h> | 24 | #include <linux/cache.h> |
25 | #include <linux/sort.h> | 25 | #include <linux/sort.h> |
26 | #include <linux/percpu.h> | ||
26 | 27 | ||
27 | #include <asm/head.h> | 28 | #include <asm/head.h> |
28 | #include <asm/system.h> | 29 | #include <asm/system.h> |
@@ -43,8 +44,8 @@ | |||
43 | #include <asm/tsb.h> | 44 | #include <asm/tsb.h> |
44 | #include <asm/hypervisor.h> | 45 | #include <asm/hypervisor.h> |
45 | #include <asm/prom.h> | 46 | #include <asm/prom.h> |
46 | 47 | #include <asm/sstate.h> | |
47 | extern void device_scan(void); | 48 | #include <asm/mdesc.h> |
48 | 49 | ||
49 | #define MAX_PHYS_ADDRESS (1UL << 42UL) | 50 | #define MAX_PHYS_ADDRESS (1UL << 42UL) |
50 | #define KPTE_BITMAP_CHUNK_SZ (256UL * 1024UL * 1024UL) | 51 | #define KPTE_BITMAP_CHUNK_SZ (256UL * 1024UL * 1024UL) |
@@ -60,8 +61,11 @@ unsigned long kern_linear_pte_xor[2] __read_mostly; | |||
60 | unsigned long kpte_linear_bitmap[KPTE_BITMAP_BYTES / sizeof(unsigned long)]; | 61 | unsigned long kpte_linear_bitmap[KPTE_BITMAP_BYTES / sizeof(unsigned long)]; |
61 | 62 | ||
62 | #ifndef CONFIG_DEBUG_PAGEALLOC | 63 | #ifndef CONFIG_DEBUG_PAGEALLOC |
63 | /* A special kernel TSB for 4MB and 256MB linear mappings. */ | 64 | /* A special kernel TSB for 4MB and 256MB linear mappings. |
64 | struct tsb swapper_4m_tsb[KERNEL_TSB4M_NENTRIES]; | 65 | * Space is allocated for this right after the trap table |
66 | * in arch/sparc64/kernel/head.S | ||
67 | */ | ||
68 | extern struct tsb swapper_4m_tsb[KERNEL_TSB4M_NENTRIES]; | ||
65 | #endif | 69 | #endif |
66 | 70 | ||
67 | #define MAX_BANKS 32 | 71 | #define MAX_BANKS 32 |
@@ -190,12 +194,9 @@ inline void flush_dcache_page_impl(struct page *page) | |||
190 | } | 194 | } |
191 | 195 | ||
192 | #define PG_dcache_dirty PG_arch_1 | 196 | #define PG_dcache_dirty PG_arch_1 |
193 | #define PG_dcache_cpu_shift 24UL | 197 | #define PG_dcache_cpu_shift 32UL |
194 | #define PG_dcache_cpu_mask (256UL - 1UL) | 198 | #define PG_dcache_cpu_mask \ |
195 | 199 | ((1UL<<ilog2(roundup_pow_of_two(NR_CPUS)))-1UL) | |
196 | #if NR_CPUS > 256 | ||
197 | #error D-cache dirty tracking and thread_info->cpu need fixing for > 256 cpus | ||
198 | #endif | ||
199 | 200 | ||
200 | #define dcache_dirty_cpu(page) \ | 201 | #define dcache_dirty_cpu(page) \ |
201 | (((page)->flags >> PG_dcache_cpu_shift) & PG_dcache_cpu_mask) | 202 | (((page)->flags >> PG_dcache_cpu_shift) & PG_dcache_cpu_mask) |
@@ -557,26 +558,11 @@ static void __init hypervisor_tlb_lock(unsigned long vaddr, | |||
557 | unsigned long pte, | 558 | unsigned long pte, |
558 | unsigned long mmu) | 559 | unsigned long mmu) |
559 | { | 560 | { |
560 | register unsigned long func asm("%o5"); | 561 | unsigned long ret = sun4v_mmu_map_perm_addr(vaddr, 0, pte, mmu); |
561 | register unsigned long arg0 asm("%o0"); | 562 | |
562 | register unsigned long arg1 asm("%o1"); | 563 | if (ret != 0) { |
563 | register unsigned long arg2 asm("%o2"); | ||
564 | register unsigned long arg3 asm("%o3"); | ||
565 | |||
566 | func = HV_FAST_MMU_MAP_PERM_ADDR; | ||
567 | arg0 = vaddr; | ||
568 | arg1 = 0; | ||
569 | arg2 = pte; | ||
570 | arg3 = mmu; | ||
571 | __asm__ __volatile__("ta 0x80" | ||
572 | : "=&r" (func), "=&r" (arg0), | ||
573 | "=&r" (arg1), "=&r" (arg2), | ||
574 | "=&r" (arg3) | ||
575 | : "0" (func), "1" (arg0), "2" (arg1), | ||
576 | "3" (arg2), "4" (arg3)); | ||
577 | if (arg0 != 0) { | ||
578 | prom_printf("hypervisor_tlb_lock[%lx:%lx:%lx:%lx]: " | 564 | prom_printf("hypervisor_tlb_lock[%lx:%lx:%lx:%lx]: " |
579 | "errors with %lx\n", vaddr, 0, pte, mmu, arg0); | 565 | "errors with %lx\n", vaddr, 0, pte, mmu, ret); |
580 | prom_halt(); | 566 | prom_halt(); |
581 | } | 567 | } |
582 | } | 568 | } |
@@ -1313,20 +1299,16 @@ static void __init sun4v_ktsb_init(void) | |||
1313 | 1299 | ||
1314 | void __cpuinit sun4v_ktsb_register(void) | 1300 | void __cpuinit sun4v_ktsb_register(void) |
1315 | { | 1301 | { |
1316 | register unsigned long func asm("%o5"); | 1302 | unsigned long pa, ret; |
1317 | register unsigned long arg0 asm("%o0"); | ||
1318 | register unsigned long arg1 asm("%o1"); | ||
1319 | unsigned long pa; | ||
1320 | 1303 | ||
1321 | pa = kern_base + ((unsigned long)&ktsb_descr[0] - KERNBASE); | 1304 | pa = kern_base + ((unsigned long)&ktsb_descr[0] - KERNBASE); |
1322 | 1305 | ||
1323 | func = HV_FAST_MMU_TSB_CTX0; | 1306 | ret = sun4v_mmu_tsb_ctx0(NUM_KTSB_DESCR, pa); |
1324 | arg0 = NUM_KTSB_DESCR; | 1307 | if (ret != 0) { |
1325 | arg1 = pa; | 1308 | prom_printf("hypervisor_mmu_tsb_ctx0[%lx]: " |
1326 | __asm__ __volatile__("ta %6" | 1309 | "errors with %lx\n", pa, ret); |
1327 | : "=&r" (func), "=&r" (arg0), "=&r" (arg1) | 1310 | prom_halt(); |
1328 | : "0" (func), "1" (arg0), "2" (arg1), | 1311 | } |
1329 | "i" (HV_FAST_TRAP)); | ||
1330 | } | 1312 | } |
1331 | 1313 | ||
1332 | /* paging_init() sets up the page tables */ | 1314 | /* paging_init() sets up the page tables */ |
@@ -1334,6 +1316,9 @@ void __cpuinit sun4v_ktsb_register(void) | |||
1334 | extern void cheetah_ecache_flush_init(void); | 1316 | extern void cheetah_ecache_flush_init(void); |
1335 | extern void sun4v_patch_tlb_handlers(void); | 1317 | extern void sun4v_patch_tlb_handlers(void); |
1336 | 1318 | ||
1319 | extern void cpu_probe(void); | ||
1320 | extern void central_probe(void); | ||
1321 | |||
1337 | static unsigned long last_valid_pfn; | 1322 | static unsigned long last_valid_pfn; |
1338 | pgd_t swapper_pg_dir[2048]; | 1323 | pgd_t swapper_pg_dir[2048]; |
1339 | 1324 | ||
@@ -1345,9 +1330,24 @@ void __init paging_init(void) | |||
1345 | unsigned long end_pfn, pages_avail, shift, phys_base; | 1330 | unsigned long end_pfn, pages_avail, shift, phys_base; |
1346 | unsigned long real_end, i; | 1331 | unsigned long real_end, i; |
1347 | 1332 | ||
1333 | /* These build time checkes make sure that the dcache_dirty_cpu() | ||
1334 | * page->flags usage will work. | ||
1335 | * | ||
1336 | * When a page gets marked as dcache-dirty, we store the | ||
1337 | * cpu number starting at bit 32 in the page->flags. Also, | ||
1338 | * functions like clear_dcache_dirty_cpu use the cpu mask | ||
1339 | * in 13-bit signed-immediate instruction fields. | ||
1340 | */ | ||
1341 | BUILD_BUG_ON(FLAGS_RESERVED != 32); | ||
1342 | BUILD_BUG_ON(SECTIONS_WIDTH + NODES_WIDTH + ZONES_WIDTH + | ||
1343 | ilog2(roundup_pow_of_two(NR_CPUS)) > FLAGS_RESERVED); | ||
1344 | BUILD_BUG_ON(NR_CPUS > 4096); | ||
1345 | |||
1348 | kern_base = (prom_boot_mapping_phys_low >> 22UL) << 22UL; | 1346 | kern_base = (prom_boot_mapping_phys_low >> 22UL) << 22UL; |
1349 | kern_size = (unsigned long)&_end - (unsigned long)KERNBASE; | 1347 | kern_size = (unsigned long)&_end - (unsigned long)KERNBASE; |
1350 | 1348 | ||
1349 | sstate_booting(); | ||
1350 | |||
1351 | /* Invalidate both kernel TSBs. */ | 1351 | /* Invalidate both kernel TSBs. */ |
1352 | memset(swapper_tsb, 0x40, sizeof(swapper_tsb)); | 1352 | memset(swapper_tsb, 0x40, sizeof(swapper_tsb)); |
1353 | #ifndef CONFIG_DEBUG_PAGEALLOC | 1353 | #ifndef CONFIG_DEBUG_PAGEALLOC |
@@ -1416,8 +1416,13 @@ void __init paging_init(void) | |||
1416 | 1416 | ||
1417 | kernel_physical_mapping_init(); | 1417 | kernel_physical_mapping_init(); |
1418 | 1418 | ||
1419 | real_setup_per_cpu_areas(); | ||
1420 | |||
1419 | prom_build_devicetree(); | 1421 | prom_build_devicetree(); |
1420 | 1422 | ||
1423 | if (tlb_type == hypervisor) | ||
1424 | sun4v_mdesc_init(); | ||
1425 | |||
1421 | { | 1426 | { |
1422 | unsigned long zones_size[MAX_NR_ZONES]; | 1427 | unsigned long zones_size[MAX_NR_ZONES]; |
1423 | unsigned long zholes_size[MAX_NR_ZONES]; | 1428 | unsigned long zholes_size[MAX_NR_ZONES]; |
@@ -1434,7 +1439,10 @@ void __init paging_init(void) | |||
1434 | zholes_size); | 1439 | zholes_size); |
1435 | } | 1440 | } |
1436 | 1441 | ||
1437 | device_scan(); | 1442 | prom_printf("Booting Linux...\n"); |
1443 | |||
1444 | central_probe(); | ||
1445 | cpu_probe(); | ||
1438 | } | 1446 | } |
1439 | 1447 | ||
1440 | static void __init taint_real_pages(void) | 1448 | static void __init taint_real_pages(void) |
diff --git a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c index 0b4213720d43..f3e0c14e9eef 100644 --- a/arch/sparc64/prom/misc.c +++ b/arch/sparc64/prom/misc.c | |||
@@ -15,6 +15,25 @@ | |||
15 | #include <asm/oplib.h> | 15 | #include <asm/oplib.h> |
16 | #include <asm/system.h> | 16 | #include <asm/system.h> |
17 | 17 | ||
18 | int prom_service_exists(const char *service_name) | ||
19 | { | ||
20 | int err = p1275_cmd("test", P1275_ARG(0, P1275_ARG_IN_STRING) | | ||
21 | P1275_INOUT(1, 1), service_name); | ||
22 | |||
23 | if (err) | ||
24 | return 0; | ||
25 | return 1; | ||
26 | } | ||
27 | |||
28 | void prom_sun4v_guest_soft_state(void) | ||
29 | { | ||
30 | const char *svc = "SUNW,soft-state-supported"; | ||
31 | |||
32 | if (!prom_service_exists(svc)) | ||
33 | return; | ||
34 | p1275_cmd(svc, P1275_INOUT(0, 0)); | ||
35 | } | ||
36 | |||
18 | /* Reset and reboot the machine with the command 'bcommand'. */ | 37 | /* Reset and reboot the machine with the command 'bcommand'. */ |
19 | void prom_reboot(const char *bcommand) | 38 | void prom_reboot(const char *bcommand) |
20 | { | 39 | { |
diff --git a/arch/um/Kconfig b/arch/um/Kconfig index c504312219b4..e6ff30266542 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig | |||
@@ -278,6 +278,7 @@ config HIGHMEM | |||
278 | config KERNEL_STACK_ORDER | 278 | config KERNEL_STACK_ORDER |
279 | int "Kernel stack size order" | 279 | int "Kernel stack size order" |
280 | default 1 if 64BIT | 280 | default 1 if 64BIT |
281 | range 1 10 if 64BIT | ||
281 | default 0 if !64BIT | 282 | default 0 if !64BIT |
282 | help | 283 | help |
283 | This option determines the size of UML kernel stacks. They will | 284 | This option determines the size of UML kernel stacks. They will |
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index ced99106f798..4bd40bb43ec2 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/kernel.h" | ||
6 | #include "linux/sched.h" | 7 | #include "linux/sched.h" |
7 | #include "linux/slab.h" | 8 | #include "linux/slab.h" |
8 | #include "linux/list.h" | 9 | #include "linux/list.h" |
diff --git a/arch/um/drivers/stderr_console.c b/arch/um/drivers/stderr_console.c index 911539293871..4739dd527b43 100644 --- a/arch/um/drivers/stderr_console.c +++ b/arch/um/drivers/stderr_console.c | |||
@@ -1,3 +1,4 @@ | |||
1 | #include <linux/kernel.h> | ||
1 | #include <linux/init.h> | 2 | #include <linux/init.h> |
2 | #include <linux/console.h> | 3 | #include <linux/console.h> |
3 | 4 | ||
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 70509ddaac03..2e09f162c42f 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #define MAJOR_NR UBD_MAJOR | 20 | #define MAJOR_NR UBD_MAJOR |
21 | #define UBD_SHIFT 4 | 21 | #define UBD_SHIFT 4 |
22 | 22 | ||
23 | #include "linux/kernel.h" | ||
23 | #include "linux/module.h" | 24 | #include "linux/module.h" |
24 | #include "linux/blkdev.h" | 25 | #include "linux/blkdev.h" |
25 | #include "linux/hdreg.h" | 26 | #include "linux/hdreg.h" |
diff --git a/arch/um/kernel/exitcode.c b/arch/um/kernel/exitcode.c index 8b7f2cdedf94..c716b5a6db13 100644 --- a/arch/um/kernel/exitcode.c +++ b/arch/um/kernel/exitcode.c | |||
@@ -1,8 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/kernel.h" | ||
6 | #include "linux/init.h" | 7 | #include "linux/init.h" |
7 | #include "linux/ctype.h" | 8 | #include "linux/ctype.h" |
8 | #include "linux/proc_fs.h" | 9 | #include "linux/proc_fs.h" |
@@ -24,11 +25,14 @@ static int read_proc_exitcode(char *page, char **start, off_t off, | |||
24 | val = uml_exitcode; | 25 | val = uml_exitcode; |
25 | len = sprintf(page, "%d\n", val); | 26 | len = sprintf(page, "%d\n", val); |
26 | len -= off; | 27 | len -= off; |
27 | if(len <= off+count) *eof = 1; | 28 | if(len <= off+count) |
29 | *eof = 1; | ||
28 | *start = page + off; | 30 | *start = page + off; |
29 | if(len > count) len = count; | 31 | if(len > count) |
30 | if(len < 0) len = 0; | 32 | len = count; |
31 | return(len); | 33 | if(len < 0) |
34 | len = 0; | ||
35 | return len; | ||
32 | } | 36 | } |
33 | 37 | ||
34 | static int write_proc_exitcode(struct file *file, const char __user *buffer, | 38 | static int write_proc_exitcode(struct file *file, const char __user *buffer, |
@@ -38,12 +42,14 @@ static int write_proc_exitcode(struct file *file, const char __user *buffer, | |||
38 | int tmp; | 42 | int tmp; |
39 | 43 | ||
40 | if(copy_from_user(buf, buffer, count)) | 44 | if(copy_from_user(buf, buffer, count)) |
41 | return(-EFAULT); | 45 | return -EFAULT; |
46 | |||
42 | tmp = simple_strtol(buf, &end, 0); | 47 | tmp = simple_strtol(buf, &end, 0); |
43 | if((*end != '\0') && !isspace(*end)) | 48 | if((*end != '\0') && !isspace(*end)) |
44 | return(-EINVAL); | 49 | return -EINVAL; |
50 | |||
45 | uml_exitcode = tmp; | 51 | uml_exitcode = tmp; |
46 | return(count); | 52 | return count; |
47 | } | 53 | } |
48 | 54 | ||
49 | static int make_proc_exitcode(void) | 55 | static int make_proc_exitcode(void) |
@@ -54,24 +60,13 @@ static int make_proc_exitcode(void) | |||
54 | if(ent == NULL){ | 60 | if(ent == NULL){ |
55 | printk(KERN_WARNING "make_proc_exitcode : Failed to register " | 61 | printk(KERN_WARNING "make_proc_exitcode : Failed to register " |
56 | "/proc/exitcode\n"); | 62 | "/proc/exitcode\n"); |
57 | return(0); | 63 | return 0; |
58 | } | 64 | } |
59 | 65 | ||
60 | ent->read_proc = read_proc_exitcode; | 66 | ent->read_proc = read_proc_exitcode; |
61 | ent->write_proc = write_proc_exitcode; | 67 | ent->write_proc = write_proc_exitcode; |
62 | 68 | ||
63 | return(0); | 69 | return 0; |
64 | } | 70 | } |
65 | 71 | ||
66 | __initcall(make_proc_exitcode); | 72 | __initcall(make_proc_exitcode); |
67 | |||
68 | /* | ||
69 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
70 | * Emacs will notice this stuff at the end of the file and automatically | ||
71 | * adjust the settings for this buffer only. This must remain at the end | ||
72 | * of the file. | ||
73 | * --------------------------------------------------------------------------- | ||
74 | * Local variables: | ||
75 | * c-file-style: "linux" | ||
76 | * End: | ||
77 | */ | ||
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 79471f85eb89..3fc13fa8729d 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c | |||
@@ -144,9 +144,7 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode, | |||
144 | int exit_with = WEXITSTATUS(status); | 144 | int exit_with = WEXITSTATUS(status); |
145 | if (exit_with == 2) | 145 | if (exit_with == 2) |
146 | non_fatal("check_ptrace : child exited with status 2. " | 146 | non_fatal("check_ptrace : child exited with status 2. " |
147 | "Serious trouble happening! Try updating " | 147 | "\nDisabling SYSEMU support.\n"); |
148 | "your host skas patch!\nDisabling SYSEMU " | ||
149 | "support."); | ||
150 | non_fatal("check_ptrace : child exited with exitcode %d, while " | 148 | non_fatal("check_ptrace : child exited with exitcode %d, while " |
151 | "expecting %d; status 0x%x\n", exit_with, | 149 | "expecting %d; status 0x%x\n", exit_with, |
152 | exitcode, status); | 150 | exitcode, status); |
@@ -209,6 +207,7 @@ __uml_setup("nosysemu", nosysemu_cmd_param, | |||
209 | static void __init check_sysemu(void) | 207 | static void __init check_sysemu(void) |
210 | { | 208 | { |
211 | void *stack; | 209 | void *stack; |
210 | unsigned long regs[MAX_REG_NR]; | ||
212 | int pid, n, status, count=0; | 211 | int pid, n, status, count=0; |
213 | 212 | ||
214 | non_fatal("Checking syscall emulation patch for ptrace..."); | 213 | non_fatal("Checking syscall emulation patch for ptrace..."); |
@@ -225,11 +224,20 @@ static void __init check_sysemu(void) | |||
225 | fatal("check_sysemu : expected SIGTRAP, got status = %d", | 224 | fatal("check_sysemu : expected SIGTRAP, got status = %d", |
226 | status); | 225 | status); |
227 | 226 | ||
228 | n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, | 227 | if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) |
229 | os_getpid()); | 228 | fatal_perror("check_sysemu : PTRACE_GETREGS failed"); |
230 | if(n < 0) | 229 | if(PT_SYSCALL_NR(regs) != __NR_getpid){ |
231 | fatal_perror("check_sysemu : failed to modify system call " | 230 | non_fatal("check_sysemu got system call number %d, " |
232 | "return"); | 231 | "expected %d...", PT_SYSCALL_NR(regs), __NR_getpid); |
232 | goto fail; | ||
233 | } | ||
234 | |||
235 | n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, os_getpid()); | ||
236 | if(n < 0){ | ||
237 | non_fatal("check_sysemu : failed to modify system call " | ||
238 | "return"); | ||
239 | goto fail; | ||
240 | } | ||
233 | 241 | ||
234 | if (stop_ptraced_child(pid, stack, 0, 0) < 0) | 242 | if (stop_ptraced_child(pid, stack, 0, 0) < 0) |
235 | goto fail_stopped; | 243 | goto fail_stopped; |
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 145bb824b2a8..5ce94430c019 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig | |||
@@ -428,12 +428,15 @@ config NR_CPUS | |||
428 | memory in the static kernel configuration. | 428 | memory in the static kernel configuration. |
429 | 429 | ||
430 | config HOTPLUG_CPU | 430 | config HOTPLUG_CPU |
431 | bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" | 431 | bool "Support for suspend on SMP and hot-pluggable CPUs (EXPERIMENTAL)" |
432 | depends on SMP && HOTPLUG && EXPERIMENTAL | 432 | depends on SMP && HOTPLUG && EXPERIMENTAL |
433 | help | 433 | help |
434 | Say Y here to experiment with turning CPUs off and on. CPUs | 434 | Say Y here to experiment with turning CPUs off and on. CPUs |
435 | can be controlled through /sys/devices/system/cpu/cpu#. | 435 | can be controlled through /sys/devices/system/cpu/cpu#. |
436 | Say N if you want to disable CPU hotplug. | 436 | This is also required for suspend/hibernation on SMP systems. |
437 | |||
438 | Say N if you want to disable CPU hotplug and don't need to | ||
439 | suspend. | ||
437 | 440 | ||
438 | config ARCH_ENABLE_MEMORY_HOTPLUG | 441 | config ARCH_ENABLE_MEMORY_HOTPLUG |
439 | def_bool y | 442 | def_bool y |
diff --git a/arch/x86_64/kernel/k8.c b/arch/x86_64/kernel/k8.c index bc11b32e8b4d..7377ccb21335 100644 --- a/arch/x86_64/kernel/k8.c +++ b/arch/x86_64/kernel/k8.c | |||
@@ -39,10 +39,10 @@ int cache_k8_northbridges(void) | |||
39 | { | 39 | { |
40 | int i; | 40 | int i; |
41 | struct pci_dev *dev; | 41 | struct pci_dev *dev; |
42 | |||
42 | if (num_k8_northbridges) | 43 | if (num_k8_northbridges) |
43 | return 0; | 44 | return 0; |
44 | 45 | ||
45 | num_k8_northbridges = 0; | ||
46 | dev = NULL; | 46 | dev = NULL; |
47 | while ((dev = next_k8_northbridge(dev)) != NULL) | 47 | while ((dev = next_k8_northbridge(dev)) != NULL) |
48 | num_k8_northbridges++; | 48 | num_k8_northbridges++; |
@@ -52,6 +52,11 @@ int cache_k8_northbridges(void) | |||
52 | if (!k8_northbridges) | 52 | if (!k8_northbridges) |
53 | return -ENOMEM; | 53 | return -ENOMEM; |
54 | 54 | ||
55 | if (!num_k8_northbridges) { | ||
56 | k8_northbridges[0] = NULL; | ||
57 | return 0; | ||
58 | } | ||
59 | |||
55 | flush_words = kmalloc(num_k8_northbridges * sizeof(u32), GFP_KERNEL); | 60 | flush_words = kmalloc(num_k8_northbridges * sizeof(u32), GFP_KERNEL); |
56 | if (!flush_words) { | 61 | if (!flush_words) { |
57 | kfree(k8_northbridges); | 62 | kfree(k8_northbridges); |
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index cb29fb96948d..aac1c0be54c6 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -465,13 +465,14 @@ static unsigned int die_nest_count; | |||
465 | 465 | ||
466 | unsigned __kprobes long oops_begin(void) | 466 | unsigned __kprobes long oops_begin(void) |
467 | { | 467 | { |
468 | int cpu = smp_processor_id(); | 468 | int cpu; |
469 | unsigned long flags; | 469 | unsigned long flags; |
470 | 470 | ||
471 | oops_enter(); | 471 | oops_enter(); |
472 | 472 | ||
473 | /* racy, but better than risking deadlock. */ | 473 | /* racy, but better than risking deadlock. */ |
474 | local_irq_save(flags); | 474 | local_irq_save(flags); |
475 | cpu = smp_processor_id(); | ||
475 | if (!spin_trylock(&die_lock)) { | 476 | if (!spin_trylock(&die_lock)) { |
476 | if (cpu == die_owner) | 477 | if (cpu == die_owner) |
477 | /* nested oops. should stop eventually */; | 478 | /* nested oops. should stop eventually */; |
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c index bfb62a13d7ee..635e58d443d7 100644 --- a/arch/x86_64/mm/fault.c +++ b/arch/x86_64/mm/fault.c | |||
@@ -476,6 +476,12 @@ bad_area: | |||
476 | bad_area_nosemaphore: | 476 | bad_area_nosemaphore: |
477 | /* User mode accesses just cause a SIGSEGV */ | 477 | /* User mode accesses just cause a SIGSEGV */ |
478 | if (error_code & PF_USER) { | 478 | if (error_code & PF_USER) { |
479 | |||
480 | /* | ||
481 | * It's possible to have interrupts off here. | ||
482 | */ | ||
483 | local_irq_enable(); | ||
484 | |||
479 | if (is_prefetch(regs, address, error_code)) | 485 | if (is_prefetch(regs, address, error_code)) |
480 | return; | 486 | return; |
481 | 487 | ||
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index 1336da8bdee1..efb6e845114e 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c | |||
@@ -79,6 +79,8 @@ void show_mem(void) | |||
79 | if (unlikely(i % MAX_ORDER_NR_PAGES == 0)) { | 79 | if (unlikely(i % MAX_ORDER_NR_PAGES == 0)) { |
80 | touch_nmi_watchdog(); | 80 | touch_nmi_watchdog(); |
81 | } | 81 | } |
82 | if (!pfn_valid(pgdat->node_start_pfn + i)) | ||
83 | continue; | ||
82 | page = pfn_to_page(pgdat->node_start_pfn + i); | 84 | page = pfn_to_page(pgdat->node_start_pfn + i); |
83 | total++; | 85 | total++; |
84 | if (PageReserved(page)) | 86 | if (PageReserved(page)) |
@@ -761,3 +763,9 @@ int in_gate_area_no_task(unsigned long addr) | |||
761 | { | 763 | { |
762 | return (addr >= VSYSCALL_START) && (addr < VSYSCALL_END); | 764 | return (addr >= VSYSCALL_START) && (addr < VSYSCALL_END); |
763 | } | 765 | } |
766 | |||
767 | void *alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size) | ||
768 | { | ||
769 | return __alloc_bootmem_core(pgdat->bdata, size, | ||
770 | SMP_CACHE_BYTES, (4UL*1024*1024*1024), 0); | ||
771 | } | ||
diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c index 698079b3a336..d0323cd6a2ea 100644 --- a/arch/xtensa/kernel/asm-offsets.c +++ b/arch/xtensa/kernel/asm-offsets.c | |||
@@ -39,6 +39,7 @@ int main(void) | |||
39 | DEFINE(PT_LEND, offsetof (struct pt_regs, lend)); | 39 | DEFINE(PT_LEND, offsetof (struct pt_regs, lend)); |
40 | DEFINE(PT_LCOUNT, offsetof (struct pt_regs, lcount)); | 40 | DEFINE(PT_LCOUNT, offsetof (struct pt_regs, lcount)); |
41 | DEFINE(PT_SAR, offsetof (struct pt_regs, sar)); | 41 | DEFINE(PT_SAR, offsetof (struct pt_regs, sar)); |
42 | DEFINE(PT_ICOUNTLEVEL, offsetof (struct pt_regs, icountlevel)); | ||
42 | DEFINE(PT_SYSCALL, offsetof (struct pt_regs, syscall)); | 43 | DEFINE(PT_SYSCALL, offsetof (struct pt_regs, syscall)); |
43 | DEFINE(PT_AREG, offsetof (struct pt_regs, areg[0])); | 44 | DEFINE(PT_AREG, offsetof (struct pt_regs, areg[0])); |
44 | DEFINE(PT_AREG0, offsetof (struct pt_regs, areg[0])); | 45 | DEFINE(PT_AREG0, offsetof (struct pt_regs, areg[0])); |
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 9e271ba009bf..8dc7a2c26ff9 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S | |||
@@ -125,8 +125,9 @@ _user_exception: | |||
125 | 125 | ||
126 | movi a2, 0 | 126 | movi a2, 0 |
127 | rsr a3, SAR | 127 | rsr a3, SAR |
128 | wsr a2, ICOUNTLEVEL | 128 | xsr a2, ICOUNTLEVEL |
129 | s32i a3, a1, PT_SAR | 129 | s32i a3, a1, PT_SAR |
130 | s32i a2, a1, PT_ICOUNTLEVEL | ||
130 | 131 | ||
131 | /* Rotate ws so that the current windowbase is at bit0. */ | 132 | /* Rotate ws so that the current windowbase is at bit0. */ |
132 | /* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */ | 133 | /* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */ |
@@ -276,8 +277,9 @@ _kernel_exception: | |||
276 | 277 | ||
277 | movi a2, 0 | 278 | movi a2, 0 |
278 | rsr a3, SAR | 279 | rsr a3, SAR |
279 | wsr a2, ICOUNTLEVEL | 280 | xsr a2, ICOUNTLEVEL |
280 | s32i a3, a1, PT_SAR | 281 | s32i a3, a1, PT_SAR |
282 | s32i a2, a1, PT_ICOUNTLEVEL | ||
281 | 283 | ||
282 | /* Rotate ws so that the current windowbase is at bit0. */ | 284 | /* Rotate ws so that the current windowbase is at bit0. */ |
283 | /* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */ | 285 | /* Assume ws = xxwww1yyyy. Rotate ws right, so that a2 = yyyyxxwww1 */ |
@@ -330,14 +332,16 @@ _kernel_exception: | |||
330 | 332 | ||
331 | common_exception: | 333 | common_exception: |
332 | 334 | ||
333 | /* Save EXCVADDR, DEBUGCAUSE, and PC, and clear LCOUNT */ | 335 | /* Save some registers, disable loops and clear the syscall flag. */ |
334 | 336 | ||
335 | rsr a2, DEBUGCAUSE | 337 | rsr a2, DEBUGCAUSE |
336 | rsr a3, EPC_1 | 338 | rsr a3, EPC_1 |
337 | s32i a2, a1, PT_DEBUGCAUSE | 339 | s32i a2, a1, PT_DEBUGCAUSE |
338 | s32i a3, a1, PT_PC | 340 | s32i a3, a1, PT_PC |
339 | 341 | ||
342 | movi a2, -1 | ||
340 | rsr a3, EXCVADDR | 343 | rsr a3, EXCVADDR |
344 | s32i a2, a1, PT_SYSCALL | ||
341 | movi a2, 0 | 345 | movi a2, 0 |
342 | s32i a3, a1, PT_EXCVADDR | 346 | s32i a3, a1, PT_EXCVADDR |
343 | xsr a2, LCOUNT | 347 | xsr a2, LCOUNT |
@@ -450,27 +454,8 @@ common_exception_return: | |||
450 | 454 | ||
451 | /* Restore the state of the task and return from the exception. */ | 455 | /* Restore the state of the task and return from the exception. */ |
452 | 456 | ||
453 | |||
454 | /* If we are returning from a user exception, and the process | ||
455 | * to run next has PT_SINGLESTEP set, we want to setup | ||
456 | * ICOUNT and ICOUNTLEVEL to step one instruction. | ||
457 | * PT_SINGLESTEP is set by sys_ptrace (ptrace.c) | ||
458 | */ | ||
459 | |||
460 | 4: /* a2 holds GET_CURRENT(a2,a1) */ | 457 | 4: /* a2 holds GET_CURRENT(a2,a1) */ |
461 | 458 | ||
462 | l32i a3, a2, TI_TASK | ||
463 | l32i a3, a3, TASK_PTRACE | ||
464 | bbci.l a3, PT_SINGLESTEP_BIT, 1f # jump if single-step flag is not set | ||
465 | |||
466 | movi a3, -2 # PT_SINGLESTEP flag is set, | ||
467 | movi a4, 1 # icountlevel of 1 means it won't | ||
468 | wsr a3, ICOUNT # start counting until after rfe | ||
469 | wsr a4, ICOUNTLEVEL # so setup icount & icountlevel. | ||
470 | isync | ||
471 | |||
472 | 1: | ||
473 | |||
474 | #if XCHAL_EXTRA_SA_SIZE | 459 | #if XCHAL_EXTRA_SA_SIZE |
475 | 460 | ||
476 | /* For user exceptions, restore the extra state from the user's TCB. */ | 461 | /* For user exceptions, restore the extra state from the user's TCB. */ |
@@ -665,6 +650,13 @@ common_exception_exit: | |||
665 | wsr a3, LEND | 650 | wsr a3, LEND |
666 | wsr a2, LCOUNT | 651 | wsr a2, LCOUNT |
667 | 652 | ||
653 | /* We control single stepping through the ICOUNTLEVEL register. */ | ||
654 | |||
655 | l32i a2, a1, PT_ICOUNTLEVEL | ||
656 | movi a3, -2 | ||
657 | wsr a2, ICOUNTLEVEL | ||
658 | wsr a3, ICOUNT | ||
659 | |||
668 | /* Check if it was double exception. */ | 660 | /* Check if it was double exception. */ |
669 | 661 | ||
670 | l32i a0, a1, PT_DEPC | 662 | l32i a0, a1, PT_DEPC |
diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S index ea89910efa44..67e69139520b 100644 --- a/arch/xtensa/kernel/head.S +++ b/arch/xtensa/kernel/head.S | |||
@@ -19,6 +19,8 @@ | |||
19 | #include <asm/page.h> | 19 | #include <asm/page.h> |
20 | #include <asm/cacheasm.h> | 20 | #include <asm/cacheasm.h> |
21 | 21 | ||
22 | #include <linux/linkage.h> | ||
23 | |||
22 | /* | 24 | /* |
23 | * This module contains the entry code for kernel images. It performs the | 25 | * This module contains the entry code for kernel images. It performs the |
24 | * minimal setup needed to call the generic C routines. | 26 | * minimal setup needed to call the generic C routines. |
@@ -227,13 +229,14 @@ _startup: | |||
227 | should_never_return: | 229 | should_never_return: |
228 | j should_never_return | 230 | j should_never_return |
229 | 231 | ||
230 | /* Define some common data structures here. We define them | ||
231 | * here in this assembly file due to their unusual alignment | ||
232 | * requirements. | ||
233 | */ | ||
234 | 232 | ||
235 | .comm swapper_pg_dir,PAGE_SIZE,PAGE_SIZE | 233 | /* |
236 | .comm empty_bad_page_table,PAGE_SIZE,PAGE_SIZE | 234 | * BSS section |
237 | .comm empty_bad_page,PAGE_SIZE,PAGE_SIZE | 235 | */ |
238 | .comm empty_zero_page,PAGE_SIZE,PAGE_SIZE | 236 | |
237 | .section ".bss.page_aligned", "w" | ||
238 | ENTRY(swapper_pg_dir) | ||
239 | .fill PAGE_SIZE, 1, 0 | ||
240 | ENTRY(empty_zero_page) | ||
241 | .fill PAGE_SIZE, 1, 0 | ||
239 | 242 | ||
diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c index 45571ccb72d6..77deae5290f0 100644 --- a/arch/xtensa/kernel/pci.c +++ b/arch/xtensa/kernel/pci.c | |||
@@ -401,7 +401,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
401 | * Also, think for a moment about likes of floppy.c that | 401 | * Also, think for a moment about likes of floppy.c that |
402 | * include architecture specific parts. They may want to redefine ins/outs. | 402 | * include architecture specific parts. They may want to redefine ins/outs. |
403 | * | 403 | * |
404 | * We do not use horroble macroses here because we want to | 404 | * We do not use horrible macros here because we want to |
405 | * advance pointer by sizeof(size). | 405 | * advance pointer by sizeof(size). |
406 | */ | 406 | */ |
407 | void outsb(unsigned long addr, const void *src, unsigned long count) { | 407 | void outsb(unsigned long addr, const void *src, unsigned long count) { |
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 1ecf6716c327..2e8d398cf196 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <asm/platform.h> | 41 | #include <asm/platform.h> |
42 | #include <asm/page.h> | 42 | #include <asm/page.h> |
43 | #include <asm/setup.h> | 43 | #include <asm/setup.h> |
44 | #include <asm/param.h> | ||
44 | 45 | ||
45 | #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) | 46 | #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) |
46 | struct screen_info screen_info = { 0, 24, 0, 0, 0, 80, 0, 0, 0, 24, 1, 16}; | 47 | struct screen_info screen_info = { 0, 24, 0, 0, 0, 80, 0, 0, 0, 24, 1, 16}; |
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index 58107672a619..033aae0336d2 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c | |||
@@ -1,397 +1,239 @@ | |||
1 | // TODO coprocessor stuff | ||
2 | /* | 1 | /* |
3 | * linux/arch/xtensa/kernel/signal.c | 2 | * arch/xtensa/kernel/signal.c |
4 | * | 3 | * |
5 | * Copyright (C) 1991, 1992 Linus Torvalds | 4 | * Default platform functions. |
6 | * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson | ||
7 | * | ||
8 | * Joe Taylor <joe@tensilica.com> | ||
9 | * Chris Zankel <chris@zankel.net> | ||
10 | * | 5 | * |
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
11 | * | 9 | * |
10 | * Copyright (C) 2005, 2006 Tensilica Inc. | ||
11 | * Copyright (C) 1991, 1992 Linus Torvalds | ||
12 | * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson | ||
12 | * | 13 | * |
14 | * Chris Zankel <chris@zankel.net> | ||
15 | * Joe Taylor <joe@tensilica.com> | ||
13 | */ | 16 | */ |
14 | 17 | ||
15 | #include <asm/variant/core.h> | ||
16 | #include <asm/coprocessor.h> | ||
17 | #include <linux/sched.h> | ||
18 | #include <linux/mm.h> | ||
19 | #include <linux/smp.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/signal.h> | 18 | #include <linux/signal.h> |
22 | #include <linux/errno.h> | 19 | #include <linux/errno.h> |
23 | #include <linux/wait.h> | ||
24 | #include <linux/ptrace.h> | 20 | #include <linux/ptrace.h> |
25 | #include <linux/unistd.h> | ||
26 | #include <linux/stddef.h> | ||
27 | #include <linux/personality.h> | 21 | #include <linux/personality.h> |
22 | #include <linux/freezer.h> | ||
23 | |||
28 | #include <asm/ucontext.h> | 24 | #include <asm/ucontext.h> |
29 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
30 | #include <asm/pgtable.h> | ||
31 | #include <asm/cacheflush.h> | 26 | #include <asm/cacheflush.h> |
27 | #include <asm/coprocessor.h> | ||
28 | #include <asm/unistd.h> | ||
32 | 29 | ||
33 | #define DEBUG_SIG 0 | 30 | #define DEBUG_SIG 0 |
34 | 31 | ||
35 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 32 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
36 | 33 | ||
37 | asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, | ||
38 | struct rusage * ru); | ||
39 | asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); | 34 | asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); |
40 | 35 | ||
41 | extern struct task_struct *coproc_owners[]; | 36 | extern struct task_struct *coproc_owners[]; |
42 | 37 | ||
38 | extern void release_all_cp (struct task_struct *); | ||
43 | 39 | ||
44 | /* | 40 | struct rt_sigframe |
45 | * Atomically swap in the new signal mask, and wait for a signal. | 41 | { |
42 | struct siginfo info; | ||
43 | struct ucontext uc; | ||
44 | cp_state_t cpstate; | ||
45 | unsigned char retcode[6]; | ||
46 | unsigned int window[4]; | ||
47 | }; | ||
48 | |||
49 | /* | ||
50 | * Flush register windows stored in pt_regs to stack. | ||
51 | * Returns 1 for errors. | ||
52 | * | ||
53 | * Note that windowbase, windowstart, and wmask are not updated! | ||
46 | */ | 54 | */ |
47 | 55 | ||
48 | int xtensa_sigsuspend(struct pt_regs *regs) | 56 | int |
57 | flush_window_regs_user(struct pt_regs *regs) | ||
49 | { | 58 | { |
50 | old_sigset_t mask = (old_sigset_t) regs->areg[3]; | 59 | const unsigned long ws = regs->windowstart; |
51 | sigset_t saveset; | 60 | const unsigned long wb = regs->windowbase; |
61 | unsigned long sp = 0; | ||
62 | unsigned long wm; | ||
63 | int err = 1; | ||
64 | int base; | ||
52 | 65 | ||
53 | mask &= _BLOCKABLE; | 66 | /* Return if no other frames. */ |
54 | spin_lock_irq(¤t->sighand->siglock); | ||
55 | saveset = current->blocked; | ||
56 | siginitset(¤t->blocked, mask); | ||
57 | recalc_sigpending(); | ||
58 | spin_unlock_irq(¤t->sighand->siglock); | ||
59 | 67 | ||
60 | regs->areg[2] = -EINTR; | 68 | if (regs->wmask == 1) |
61 | while (1) { | 69 | return 0; |
62 | current->state = TASK_INTERRUPTIBLE; | ||
63 | schedule(); | ||
64 | if (do_signal(regs, &saveset)) | ||
65 | return -EINTR; | ||
66 | } | ||
67 | } | ||
68 | 70 | ||
69 | asmlinkage int | 71 | /* Rotate windowmask and skip empty frames. */ |
70 | xtensa_rt_sigsuspend(struct pt_regs *regs) | ||
71 | { | ||
72 | sigset_t *unewset = (sigset_t *) regs->areg[4]; | ||
73 | size_t sigsetsize = (size_t) regs->areg[3]; | ||
74 | sigset_t saveset, newset; | ||
75 | /* XXX: Don't preclude handling different sized sigset_t's. */ | ||
76 | if (sigsetsize != sizeof(sigset_t)) | ||
77 | return -EINVAL; | ||
78 | 72 | ||
79 | if (copy_from_user(&newset, unewset, sizeof(newset))) | 73 | wm = (ws >> wb) | (ws << (XCHAL_NUM_AREGS / 4 - wb)); |
80 | return -EFAULT; | 74 | base = (XCHAL_NUM_AREGS / 4) - (regs->wmask >> 4); |
81 | sigdelsetmask(&newset, ~_BLOCKABLE); | 75 | |
82 | spin_lock_irq(¤t->sighand->siglock); | 76 | /* For call8 or call12 frames, we need the previous stack pointer. */ |
83 | saveset = current->blocked; | ||
84 | current->blocked = newset; | ||
85 | recalc_sigpending(); | ||
86 | spin_unlock_irq(¤t->sighand->siglock); | ||
87 | 77 | ||
88 | regs->areg[2] = -EINTR; | 78 | if ((regs->wmask & 2) == 0) |
89 | while (1) { | 79 | if (__get_user(sp, (int*)(regs->areg[base * 4 + 1] - 12))) |
90 | current->state = TASK_INTERRUPTIBLE; | 80 | goto errout; |
91 | schedule(); | ||
92 | if (do_signal(regs, &saveset)) | ||
93 | return -EINTR; | ||
94 | } | ||
95 | } | ||
96 | 81 | ||
97 | asmlinkage int | 82 | /* Spill frames to stack. */ |
98 | xtensa_sigaction(int sig, const struct old_sigaction *act, | ||
99 | struct old_sigaction *oact) | ||
100 | { | ||
101 | struct k_sigaction new_ka, old_ka; | ||
102 | int ret; | ||
103 | 83 | ||
104 | if (act) { | 84 | while (base < XCHAL_NUM_AREGS / 4) { |
105 | old_sigset_t mask; | ||
106 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || | ||
107 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || | ||
108 | __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) | ||
109 | return -EFAULT; | ||
110 | __get_user(new_ka.sa.sa_flags, &act->sa_flags); | ||
111 | __get_user(mask, &act->sa_mask); | ||
112 | siginitset(&new_ka.sa.sa_mask, mask); | ||
113 | } | ||
114 | 85 | ||
115 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); | 86 | int m = (wm >> base); |
87 | int inc = 0; | ||
116 | 88 | ||
117 | if (!ret && oact) { | 89 | /* Save registers a4..a7 (call8) or a4...a11 (call12) */ |
118 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || | ||
119 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || | ||
120 | __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) | ||
121 | return -EFAULT; | ||
122 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags); | ||
123 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); | ||
124 | } | ||
125 | 90 | ||
126 | return ret; | 91 | if (m & 2) { /* call4 */ |
127 | } | 92 | inc = 1; |
128 | 93 | ||
129 | asmlinkage int | 94 | } else if (m & 4) { /* call8 */ |
130 | xtensa_sigaltstack(struct pt_regs *regs) | 95 | if (copy_to_user((void*)(sp - 32), |
131 | { | 96 | ®s->areg[(base + 1) * 4], 16)) |
132 | const stack_t *uss = (stack_t *) regs->areg[4]; | 97 | goto errout; |
133 | stack_t *uoss = (stack_t *) regs->areg[3]; | 98 | inc = 2; |
134 | 99 | ||
135 | if (regs->depc > 64) | 100 | } else if (m & 8) { /* call12 */ |
136 | panic ("Double exception sys_sigreturn\n"); | 101 | if (copy_to_user((void*)(sp - 48), |
102 | ®s->areg[(base + 1) * 4], 32)) | ||
103 | goto errout; | ||
104 | inc = 3; | ||
105 | } | ||
137 | 106 | ||
107 | /* Save current frame a0..a3 under next SP */ | ||
138 | 108 | ||
139 | return do_sigaltstack(uss, uoss, regs->areg[1]); | 109 | sp = regs->areg[((base + inc) * 4 + 1) % XCHAL_NUM_AREGS]; |
140 | } | 110 | if (copy_to_user((void*)(sp - 16), ®s->areg[base * 4], 16)) |
111 | goto errout; | ||
112 | |||
113 | /* Get current stack pointer for next loop iteration. */ | ||
114 | |||
115 | sp = regs->areg[base * 4 + 1]; | ||
116 | base += inc; | ||
117 | } | ||
118 | |||
119 | return 0; | ||
141 | 120 | ||
121 | errout: | ||
122 | return err; | ||
123 | } | ||
142 | 124 | ||
143 | /* | 125 | /* |
144 | * Do a signal return; undo the signal stack. | 126 | * Note: We don't copy double exception 'regs', we have to finish double exc. |
127 | * first before we return to signal handler! This dbl.exc.handler might cause | ||
128 | * another double exception, but I think we are fine as the situation is the | ||
129 | * same as if we had returned to the signal handerl and got an interrupt | ||
130 | * immediately... | ||
145 | */ | 131 | */ |
146 | 132 | ||
147 | struct sigframe | 133 | static int |
148 | { | 134 | setup_sigcontext(struct sigcontext __user *sc, cp_state_t *cpstate, |
149 | struct sigcontext sc; | 135 | struct pt_regs *regs, unsigned long mask) |
150 | struct _cpstate cpstate; | ||
151 | unsigned long extramask[_NSIG_WORDS-1]; | ||
152 | unsigned char retcode[6]; | ||
153 | unsigned int reserved[4]; /* Reserved area for chaining */ | ||
154 | unsigned int window[4]; /* Window of 4 registers for initial context */ | ||
155 | }; | ||
156 | |||
157 | struct rt_sigframe | ||
158 | { | 136 | { |
159 | struct siginfo info; | 137 | int err = 0; |
160 | struct ucontext uc; | ||
161 | struct _cpstate cpstate; | ||
162 | unsigned char retcode[6]; | ||
163 | unsigned int reserved[4]; /* Reserved area for chaining */ | ||
164 | unsigned int window[4]; /* Window of 4 registers for initial context */ | ||
165 | }; | ||
166 | 138 | ||
167 | extern void release_all_cp (struct task_struct *); | 139 | #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x) |
140 | COPY(pc); | ||
141 | COPY(ps); | ||
142 | COPY(lbeg); | ||
143 | COPY(lend); | ||
144 | COPY(lcount); | ||
145 | COPY(sar); | ||
146 | #undef COPY | ||
168 | 147 | ||
148 | err |= flush_window_regs_user(regs); | ||
149 | err |= __copy_to_user (sc->sc_a, regs->areg, 16 * 4); | ||
169 | 150 | ||
170 | // FIXME restore_cpextra | 151 | // err |= __copy_to_user (sc->sc_a, regs->areg, XCHAL_NUM_AREGS * 4) |
171 | static inline int | ||
172 | restore_cpextra (struct _cpstate *buf) | ||
173 | { | ||
174 | #if 0 | ||
175 | /* The signal handler may have used coprocessors in which | ||
176 | * case they are still enabled. We disable them to force a | ||
177 | * reloading of the original task's CP state by the lazy | ||
178 | * context-switching mechanisms of CP exception handling. | ||
179 | * Also, we essentially discard any coprocessor state that the | ||
180 | * signal handler created. */ | ||
181 | 152 | ||
182 | struct task_struct *tsk = current; | 153 | #if XCHAL_HAVE_CP |
183 | release_all_cp(tsk); | 154 | # error Coprocessors unsupported |
184 | return __copy_from_user(tsk->thread.cpextra, buf, XTENSA_CP_EXTRA_SIZE); | 155 | err |= save_cpextra(cpstate); |
156 | err |= __put_user(err ? NULL : cpstate, &sc->sc_cpstate); | ||
185 | #endif | 157 | #endif |
186 | return 0; | 158 | /* non-iBCS2 extensions.. */ |
187 | } | 159 | err |= __put_user(mask, &sc->oldmask); |
188 | |||
189 | /* Note: We don't copy double exception 'tregs', we have to finish double exc. first before we return to signal handler! This dbl.exc.handler might cause another double exception, but I think we are fine as the situation is the same as if we had returned to the signal handerl and got an interrupt immediately... | ||
190 | */ | ||
191 | 160 | ||
161 | return err; | ||
162 | } | ||
192 | 163 | ||
193 | static int | 164 | static int |
194 | restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) | 165 | restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) |
195 | { | 166 | { |
196 | struct thread_struct *thread; | ||
197 | unsigned int err = 0; | 167 | unsigned int err = 0; |
198 | unsigned long ps; | 168 | unsigned long ps; |
199 | struct _cpstate *buf; | ||
200 | 169 | ||
201 | #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x) | 170 | #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x) |
202 | COPY(pc); | 171 | COPY(pc); |
203 | COPY(depc); | ||
204 | COPY(wmask); | ||
205 | COPY(lbeg); | 172 | COPY(lbeg); |
206 | COPY(lend); | 173 | COPY(lend); |
207 | COPY(lcount); | 174 | COPY(lcount); |
208 | COPY(sar); | 175 | COPY(sar); |
209 | COPY(windowbase); | ||
210 | COPY(windowstart); | ||
211 | #undef COPY | 176 | #undef COPY |
212 | 177 | ||
178 | /* All registers were flushed to stack. Start with a prestine frame. */ | ||
179 | |||
180 | regs->wmask = 1; | ||
181 | regs->windowbase = 0; | ||
182 | regs->windowstart = 1; | ||
183 | |||
213 | /* For PS, restore only PS.CALLINC. | 184 | /* For PS, restore only PS.CALLINC. |
214 | * Assume that all other bits are either the same as for the signal | 185 | * Assume that all other bits are either the same as for the signal |
215 | * handler, or the user mode value doesn't matter (e.g. PS.OWB). | 186 | * handler, or the user mode value doesn't matter (e.g. PS.OWB). |
216 | */ | 187 | */ |
217 | err |= __get_user(ps, &sc->sc_ps); | 188 | err |= __get_user(ps, &sc->sc_ps); |
218 | regs->ps = (regs->ps & ~PS_CALLINC_MASK) | 189 | regs->ps = (regs->ps & ~PS_CALLINC_MASK) | (ps & PS_CALLINC_MASK); |
219 | | (ps & PS_CALLINC_MASK); | ||
220 | 190 | ||
221 | /* Additional corruption checks */ | 191 | /* Additional corruption checks */ |
222 | 192 | ||
223 | if ((regs->windowbase >= (XCHAL_NUM_AREGS/4)) | ||
224 | || ((regs->windowstart & ~((1<<(XCHAL_NUM_AREGS/4)) - 1)) != 0) ) | ||
225 | err = 1; | ||
226 | if ((regs->lcount > 0) | 193 | if ((regs->lcount > 0) |
227 | && ((regs->lbeg > TASK_SIZE) || (regs->lend > TASK_SIZE)) ) | 194 | && ((regs->lbeg > TASK_SIZE) || (regs->lend > TASK_SIZE)) ) |
228 | err = 1; | 195 | err = 1; |
229 | 196 | ||
230 | /* Restore extended register state. | 197 | err |= __copy_from_user(regs->areg, sc->sc_a, 16 * 4); |
231 | * See struct thread_struct in processor.h. | ||
232 | */ | ||
233 | thread = ¤t->thread; | ||
234 | |||
235 | err |= __copy_from_user (regs->areg, sc->sc_areg, XCHAL_NUM_AREGS*4); | ||
236 | err |= __get_user(buf, &sc->sc_cpstate); | ||
237 | if (buf) { | ||
238 | if (!access_ok(VERIFY_READ, buf, sizeof(*buf))) | ||
239 | goto badframe; | ||
240 | err |= restore_cpextra(buf); | ||
241 | } | ||
242 | |||
243 | regs->syscall = -1; /* disable syscall checks */ | ||
244 | return err; | ||
245 | |||
246 | badframe: | ||
247 | return 1; | ||
248 | } | ||
249 | |||
250 | static inline void | ||
251 | flush_my_cpstate(struct task_struct *tsk) | ||
252 | { | ||
253 | unsigned long flags; | ||
254 | local_irq_save(flags); | ||
255 | |||
256 | #if 0 // FIXME | ||
257 | for (i = 0; i < XCHAL_CP_NUM; i++) { | ||
258 | if (tsk == coproc_owners[i]) { | ||
259 | xthal_validate_cp(i); | ||
260 | xthal_save_cpregs(tsk->thread.cpregs_ptr[i], i); | ||
261 | 198 | ||
262 | /* Invalidate and "disown" the cp to allow | 199 | #if XCHAL_HAVE_CP |
263 | * callers the chance to reset cp state in the | 200 | # error Coprocessors unsupported |
264 | * task_struct. */ | 201 | /* The signal handler may have used coprocessors in which |
202 | * case they are still enabled. We disable them to force a | ||
203 | * reloading of the original task's CP state by the lazy | ||
204 | * context-switching mechanisms of CP exception handling. | ||
205 | * Also, we essentially discard any coprocessor state that the | ||
206 | * signal handler created. */ | ||
265 | 207 | ||
266 | xthal_invalidate_cp(i); | 208 | if (!err) { |
267 | coproc_owners[i] = 0; | 209 | struct task_struct *tsk = current; |
268 | } | 210 | release_all_cp(tsk); |
211 | err |= __copy_from_user(tsk->thread.cpextra, sc->sc_cpstate, | ||
212 | XTENSA_CP_EXTRA_SIZE); | ||
269 | } | 213 | } |
270 | #endif | 214 | #endif |
271 | local_irq_restore(flags); | ||
272 | } | ||
273 | |||
274 | /* Return codes: | ||
275 | 0: nothing saved | ||
276 | 1: stuff to save, successful | ||
277 | -1: stuff to save, error happened | ||
278 | */ | ||
279 | static int | ||
280 | save_cpextra (struct _cpstate *buf) | ||
281 | { | ||
282 | #if XCHAL_CP_NUM == 0 | ||
283 | return 0; | ||
284 | #else | ||
285 | |||
286 | /* FIXME: If a task has never used a coprocessor, there is | ||
287 | * no need to save and restore anything. Tracking this | ||
288 | * information would allow us to optimize this section. | ||
289 | * Perhaps we can use current->used_math or (current->flags & | ||
290 | * PF_USEDFPU) or define a new field in the thread | ||
291 | * structure. */ | ||
292 | |||
293 | /* We flush any live, task-owned cp state to the task_struct, | ||
294 | * then copy it all to the sigframe. Then we clear all | ||
295 | * cp/extra state in the task_struct, effectively | ||
296 | * clearing/resetting all cp/extra state for the signal | ||
297 | * handler (cp-exception handling will load these new values | ||
298 | * into the cp/extra registers.) This step is important for | ||
299 | * things like a floating-point cp, where the OS must reset | ||
300 | * the FCR to the default rounding mode. */ | ||
301 | |||
302 | int err = 0; | ||
303 | struct task_struct *tsk = current; | ||
304 | |||
305 | flush_my_cpstate(tsk); | ||
306 | /* Note that we just copy everything: 'extra' and 'cp' state together.*/ | ||
307 | err |= __copy_to_user(buf, tsk->thread.cp_save, XTENSA_CP_EXTRA_SIZE); | ||
308 | memset(tsk->thread.cp_save, 0, XTENSA_CP_EXTRA_SIZE); | ||
309 | |||
310 | #if (XTENSA_CP_EXTRA_SIZE == 0) | ||
311 | #error Sanity check on memset above, cpextra_size should not be zero. | ||
312 | #endif | ||
313 | |||
314 | return err ? -1 : 1; | ||
315 | #endif | ||
316 | } | ||
317 | |||
318 | static int | ||
319 | setup_sigcontext(struct sigcontext *sc, struct _cpstate *cpstate, | ||
320 | struct pt_regs *regs, unsigned long mask) | ||
321 | { | ||
322 | struct thread_struct *thread; | ||
323 | int err = 0; | ||
324 | |||
325 | //printk("setup_sigcontext\n"); | ||
326 | #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x) | ||
327 | COPY(pc); | ||
328 | COPY(ps); | ||
329 | COPY(depc); | ||
330 | COPY(wmask); | ||
331 | COPY(lbeg); | ||
332 | COPY(lend); | ||
333 | COPY(lcount); | ||
334 | COPY(sar); | ||
335 | COPY(windowbase); | ||
336 | COPY(windowstart); | ||
337 | #undef COPY | ||
338 | |||
339 | /* Save extended register state. | ||
340 | * See struct thread_struct in processor.h. | ||
341 | */ | ||
342 | thread = ¤t->thread; | ||
343 | err |= __copy_to_user (sc->sc_areg, regs->areg, XCHAL_NUM_AREGS * 4); | ||
344 | err |= save_cpextra(cpstate); | ||
345 | err |= __put_user(err ? NULL : cpstate, &sc->sc_cpstate); | ||
346 | /* non-iBCS2 extensions.. */ | ||
347 | err |= __put_user(mask, &sc->oldmask); | ||
348 | 215 | ||
216 | regs->syscall = -1; /* disable syscall checks */ | ||
349 | return err; | 217 | return err; |
350 | } | 218 | } |
351 | 219 | ||
352 | asmlinkage int xtensa_sigreturn(struct pt_regs *regs) | ||
353 | { | ||
354 | struct sigframe *frame = (struct sigframe *)regs->areg[1]; | ||
355 | sigset_t set; | ||
356 | if (regs->depc > 64) | ||
357 | panic ("Double exception sys_sigreturn\n"); | ||
358 | |||
359 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | ||
360 | goto badframe; | ||
361 | |||
362 | if (__get_user(set.sig[0], &frame->sc.oldmask) | ||
363 | || (_NSIG_WORDS > 1 | ||
364 | && __copy_from_user(&set.sig[1], &frame->extramask, | ||
365 | sizeof(frame->extramask)))) | ||
366 | goto badframe; | ||
367 | |||
368 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
369 | |||
370 | spin_lock_irq(¤t->sighand->siglock); | ||
371 | current->blocked = set; | ||
372 | recalc_sigpending(); | ||
373 | spin_unlock_irq(¤t->sighand->siglock); | ||
374 | 220 | ||
375 | if (restore_sigcontext(regs, &frame->sc)) | ||
376 | goto badframe; | ||
377 | return regs->areg[2]; | ||
378 | 221 | ||
379 | badframe: | 222 | /* |
380 | force_sig(SIGSEGV, current); | 223 | * Do a signal return; undo the signal stack. |
381 | return 0; | 224 | */ |
382 | } | ||
383 | 225 | ||
384 | asmlinkage int xtensa_rt_sigreturn(struct pt_regs *regs) | 226 | asmlinkage long xtensa_rt_sigreturn(long a0, long a1, long a2, long a3, |
227 | long a4, long a5, struct pt_regs *regs) | ||
385 | { | 228 | { |
386 | struct rt_sigframe *frame = (struct rt_sigframe *)regs->areg[1]; | 229 | struct rt_sigframe __user *frame; |
387 | sigset_t set; | 230 | sigset_t set; |
388 | stack_t st; | ||
389 | int ret; | 231 | int ret; |
232 | |||
390 | if (regs->depc > 64) | 233 | if (regs->depc > 64) |
391 | { | 234 | panic("rt_sigreturn in double exception!\n"); |
392 | printk("!!!!!!! DEPC !!!!!!!\n"); | 235 | |
393 | return 0; | 236 | frame = (struct rt_sigframe __user *) regs->areg[1]; |
394 | } | ||
395 | 237 | ||
396 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | 238 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) |
397 | goto badframe; | 239 | goto badframe; |
@@ -407,13 +249,11 @@ asmlinkage int xtensa_rt_sigreturn(struct pt_regs *regs) | |||
407 | 249 | ||
408 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) | 250 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) |
409 | goto badframe; | 251 | goto badframe; |
252 | |||
410 | ret = regs->areg[2]; | 253 | ret = regs->areg[2]; |
411 | 254 | ||
412 | if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) | 255 | if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->areg[1]) == -EFAULT) |
413 | goto badframe; | 256 | goto badframe; |
414 | /* It is more difficult to avoid calling this function than to | ||
415 | call it and ignore errors. */ | ||
416 | do_sigaltstack(&st, NULL, regs->areg[1]); | ||
417 | 257 | ||
418 | return ret; | 258 | return ret; |
419 | 259 | ||
@@ -422,77 +262,50 @@ badframe: | |||
422 | return 0; | 262 | return 0; |
423 | } | 263 | } |
424 | 264 | ||
425 | /* | 265 | |
426 | * Set up a signal frame. | ||
427 | */ | ||
428 | 266 | ||
429 | /* | 267 | /* |
430 | * Determine which stack to use.. | 268 | * Set up a signal frame. |
431 | */ | 269 | */ |
432 | static inline void * | ||
433 | get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size) | ||
434 | { | ||
435 | if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp)) | ||
436 | sp = current->sas_ss_sp + current->sas_ss_size; | ||
437 | |||
438 | return (void *)((sp - frame_size) & -16ul); | ||
439 | } | ||
440 | |||
441 | #define USE_SIGRETURN 0 | ||
442 | #define USE_RT_SIGRETURN 1 | ||
443 | 270 | ||
444 | static int | 271 | static int |
445 | gen_return_code(unsigned char *codemem, unsigned int use_rt_sigreturn) | 272 | gen_return_code(unsigned char *codemem) |
446 | { | 273 | { |
447 | unsigned int retcall; | ||
448 | int err = 0; | 274 | int err = 0; |
449 | 275 | ||
450 | #if 0 | 276 | /* |
451 | /* Ignoring SA_RESTORER for now; it's supposed to be obsolete, | 277 | * The 12-bit immediate is really split up within the 24-bit MOVI |
452 | * and the xtensa glibc doesn't use it. | 278 | * instruction. As long as the above system call numbers fit within |
279 | * 8-bits, the following code works fine. See the Xtensa ISA for | ||
280 | * details. | ||
453 | */ | 281 | */ |
454 | if (ka->sa.sa_flags & SA_RESTORER) { | ||
455 | regs->pr = (unsigned long) ka->sa.sa_restorer; | ||
456 | } else | ||
457 | #endif /* 0 */ | ||
458 | { | ||
459 | |||
460 | #if (__NR_sigreturn > 255) || (__NR_rt_sigreturn > 255) | ||
461 | |||
462 | /* The 12-bit immediate is really split up within the 24-bit MOVI | ||
463 | * instruction. As long as the above system call numbers fit within | ||
464 | * 8-bits, the following code works fine. See the Xtensa ISA for | ||
465 | * details. | ||
466 | */ | ||
467 | 282 | ||
468 | #error Generating the MOVI instruction below breaks! | 283 | #if __NR_rt_sigreturn > 255 |
284 | # error Generating the MOVI instruction below breaks! | ||
469 | #endif | 285 | #endif |
470 | 286 | ||
471 | retcall = use_rt_sigreturn ? __NR_rt_sigreturn : __NR_sigreturn; | ||
472 | |||
473 | #ifdef __XTENSA_EB__ /* Big Endian version */ | 287 | #ifdef __XTENSA_EB__ /* Big Endian version */ |
474 | /* Generate instruction: MOVI a2, retcall */ | 288 | /* Generate instruction: MOVI a2, __NR_rt_sigreturn */ |
475 | err |= __put_user(0x22, &codemem[0]); | 289 | err |= __put_user(0x22, &codemem[0]); |
476 | err |= __put_user(0x0a, &codemem[1]); | 290 | err |= __put_user(0x0a, &codemem[1]); |
477 | err |= __put_user(retcall, &codemem[2]); | 291 | err |= __put_user(__NR_rt_sigreturn, &codemem[2]); |
478 | /* Generate instruction: SYSCALL */ | 292 | /* Generate instruction: SYSCALL */ |
479 | err |= __put_user(0x00, &codemem[3]); | 293 | err |= __put_user(0x00, &codemem[3]); |
480 | err |= __put_user(0x05, &codemem[4]); | 294 | err |= __put_user(0x05, &codemem[4]); |
481 | err |= __put_user(0x00, &codemem[5]); | 295 | err |= __put_user(0x00, &codemem[5]); |
482 | 296 | ||
483 | #elif defined __XTENSA_EL__ /* Little Endian version */ | 297 | #elif defined __XTENSA_EL__ /* Little Endian version */ |
484 | /* Generate instruction: MOVI a2, retcall */ | 298 | /* Generate instruction: MOVI a2, __NR_rt_sigreturn */ |
485 | err |= __put_user(0x22, &codemem[0]); | 299 | err |= __put_user(0x22, &codemem[0]); |
486 | err |= __put_user(0xa0, &codemem[1]); | 300 | err |= __put_user(0xa0, &codemem[1]); |
487 | err |= __put_user(retcall, &codemem[2]); | 301 | err |= __put_user(__NR_rt_sigreturn, &codemem[2]); |
488 | /* Generate instruction: SYSCALL */ | 302 | /* Generate instruction: SYSCALL */ |
489 | err |= __put_user(0x00, &codemem[3]); | 303 | err |= __put_user(0x00, &codemem[3]); |
490 | err |= __put_user(0x50, &codemem[4]); | 304 | err |= __put_user(0x50, &codemem[4]); |
491 | err |= __put_user(0x00, &codemem[5]); | 305 | err |= __put_user(0x00, &codemem[5]); |
492 | #else | 306 | #else |
493 | #error Must use compiler for Xtensa processors. | 307 | # error Must use compiler for Xtensa processors. |
494 | #endif | 308 | #endif |
495 | } | ||
496 | 309 | ||
497 | /* Flush generated code out of the data cache */ | 310 | /* Flush generated code out of the data cache */ |
498 | 311 | ||
@@ -504,97 +317,29 @@ gen_return_code(unsigned char *codemem, unsigned int use_rt_sigreturn) | |||
504 | return err; | 317 | return err; |
505 | } | 318 | } |
506 | 319 | ||
507 | static void | ||
508 | set_thread_state(struct pt_regs *regs, void *stack, unsigned char *retaddr, | ||
509 | void *handler, unsigned long arg1, void *arg2, void *arg3) | ||
510 | { | ||
511 | /* Set up registers for signal handler */ | ||
512 | start_thread(regs, (unsigned long) handler, (unsigned long) stack); | ||
513 | |||
514 | /* Set up a stack frame for a call4 | ||
515 | * Note: PS.CALLINC is set to one by start_thread | ||
516 | */ | ||
517 | regs->areg[4] = (((unsigned long) retaddr) & 0x3fffffff) | 0x40000000; | ||
518 | regs->areg[6] = arg1; | ||
519 | regs->areg[7] = (unsigned long) arg2; | ||
520 | regs->areg[8] = (unsigned long) arg3; | ||
521 | } | ||
522 | 320 | ||
523 | static void setup_frame(int sig, struct k_sigaction *ka, | 321 | static void setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
524 | sigset_t *set, struct pt_regs *regs) | 322 | sigset_t *set, struct pt_regs *regs) |
525 | { | 323 | { |
526 | struct sigframe *frame; | 324 | struct rt_sigframe *frame; |
527 | int err = 0; | 325 | int err = 0; |
528 | int signal; | 326 | int signal; |
327 | unsigned long sp, ra; | ||
529 | 328 | ||
530 | frame = get_sigframe(ka, regs->areg[1], sizeof(*frame)); | 329 | sp = regs->areg[1]; |
531 | if (regs->depc > 64) | ||
532 | { | ||
533 | printk("!!!!!!! DEPC !!!!!!!\n"); | ||
534 | return; | ||
535 | } | ||
536 | |||
537 | |||
538 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | ||
539 | goto give_sigsegv; | ||
540 | |||
541 | signal = current_thread_info()->exec_domain | ||
542 | && current_thread_info()->exec_domain->signal_invmap | ||
543 | && sig < 32 | ||
544 | ? current_thread_info()->exec_domain->signal_invmap[sig] | ||
545 | : sig; | ||
546 | |||
547 | err |= setup_sigcontext(&frame->sc, &frame->cpstate, regs, set->sig[0]); | ||
548 | 330 | ||
549 | if (_NSIG_WORDS > 1) { | 331 | if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp)) { |
550 | err |= __copy_to_user(frame->extramask, &set->sig[1], | 332 | sp = current->sas_ss_sp + current->sas_ss_size; |
551 | sizeof(frame->extramask)); | ||
552 | } | 333 | } |
553 | 334 | ||
554 | /* Create sys_sigreturn syscall in stack frame */ | 335 | frame = (void *)((sp - sizeof(*frame)) & -16ul); |
555 | err |= gen_return_code(frame->retcode, USE_SIGRETURN); | ||
556 | |||
557 | if (err) | ||
558 | goto give_sigsegv; | ||
559 | |||
560 | /* Create signal handler execution context. | ||
561 | * Return context not modified until this point. | ||
562 | */ | ||
563 | set_thread_state(regs, frame, frame->retcode, | ||
564 | ka->sa.sa_handler, signal, &frame->sc, NULL); | ||
565 | |||
566 | /* Set access mode to USER_DS. Nomenclature is outdated, but | ||
567 | * functionality is used in uaccess.h | ||
568 | */ | ||
569 | set_fs(USER_DS); | ||
570 | |||
571 | |||
572 | #if DEBUG_SIG | ||
573 | printk("SIG deliver (%s:%d): signal=%d sp=%p pc=%08x\n", | ||
574 | current->comm, current->pid, signal, frame, regs->pc); | ||
575 | #endif | ||
576 | |||
577 | return; | ||
578 | |||
579 | give_sigsegv: | ||
580 | if (sig == SIGSEGV) | ||
581 | ka->sa.sa_handler = SIG_DFL; | ||
582 | force_sig(SIGSEGV, current); | ||
583 | } | ||
584 | |||
585 | static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | ||
586 | sigset_t *set, struct pt_regs *regs) | ||
587 | { | ||
588 | struct rt_sigframe *frame; | ||
589 | int err = 0; | ||
590 | int signal; | ||
591 | 336 | ||
592 | frame = get_sigframe(ka, regs->areg[1], sizeof(*frame)); | ||
593 | if (regs->depc > 64) | 337 | if (regs->depc > 64) |
594 | panic ("Double exception sys_sigreturn\n"); | 338 | panic ("Double exception sys_sigreturn\n"); |
595 | 339 | ||
596 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 340 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) { |
597 | goto give_sigsegv; | 341 | goto give_sigsegv; |
342 | } | ||
598 | 343 | ||
599 | signal = current_thread_info()->exec_domain | 344 | signal = current_thread_info()->exec_domain |
600 | && current_thread_info()->exec_domain->signal_invmap | 345 | && current_thread_info()->exec_domain->signal_invmap |
@@ -602,9 +347,12 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
602 | ? current_thread_info()->exec_domain->signal_invmap[sig] | 347 | ? current_thread_info()->exec_domain->signal_invmap[sig] |
603 | : sig; | 348 | : sig; |
604 | 349 | ||
605 | err |= copy_siginfo_to_user(&frame->info, info); | 350 | if (ka->sa.sa_flags & SA_SIGINFO) { |
351 | err |= copy_siginfo_to_user(&frame->info, info); | ||
352 | } | ||
353 | |||
354 | /* Create the user context. */ | ||
606 | 355 | ||
607 | /* Create the ucontext. */ | ||
608 | err |= __put_user(0, &frame->uc.uc_flags); | 356 | err |= __put_user(0, &frame->uc.uc_flags); |
609 | err |= __put_user(0, &frame->uc.uc_link); | 357 | err |= __put_user(0, &frame->uc.uc_link); |
610 | err |= __put_user((void *)current->sas_ss_sp, | 358 | err |= __put_user((void *)current->sas_ss_sp, |
@@ -617,16 +365,31 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
617 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); | 365 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); |
618 | 366 | ||
619 | /* Create sys_rt_sigreturn syscall in stack frame */ | 367 | /* Create sys_rt_sigreturn syscall in stack frame */ |
620 | err |= gen_return_code(frame->retcode, USE_RT_SIGRETURN); | ||
621 | 368 | ||
622 | if (err) | 369 | err |= gen_return_code(frame->retcode); |
370 | |||
371 | if (err) { | ||
623 | goto give_sigsegv; | 372 | goto give_sigsegv; |
373 | } | ||
374 | |||
624 | 375 | ||
625 | /* Create signal handler execution context. | 376 | /* |
377 | * Create signal handler execution context. | ||
626 | * Return context not modified until this point. | 378 | * Return context not modified until this point. |
627 | */ | 379 | */ |
628 | set_thread_state(regs, frame, frame->retcode, | 380 | |
629 | ka->sa.sa_handler, signal, &frame->info, &frame->uc); | 381 | /* Set up registers for signal handler */ |
382 | start_thread(regs, (unsigned long) ka->sa.sa_handler, | ||
383 | (unsigned long) frame); | ||
384 | |||
385 | /* Set up a stack frame for a call4 | ||
386 | * Note: PS.CALLINC is set to one by start_thread | ||
387 | */ | ||
388 | ra = (unsigned long) frame->retcode; | ||
389 | regs->areg[4] = (((unsigned long) ra) & 0x3fffffff) | 0x40000000; | ||
390 | regs->areg[6] = (unsigned long) signal; | ||
391 | regs->areg[7] = (unsigned long) &frame->info; | ||
392 | regs->areg[8] = (unsigned long) &frame->uc; | ||
630 | 393 | ||
631 | /* Set access mode to USER_DS. Nomenclature is outdated, but | 394 | /* Set access mode to USER_DS. Nomenclature is outdated, but |
632 | * functionality is used in uaccess.h | 395 | * functionality is used in uaccess.h |
@@ -646,6 +409,48 @@ give_sigsegv: | |||
646 | force_sig(SIGSEGV, current); | 409 | force_sig(SIGSEGV, current); |
647 | } | 410 | } |
648 | 411 | ||
412 | /* | ||
413 | * Atomically swap in the new signal mask, and wait for a signal. | ||
414 | */ | ||
415 | |||
416 | asmlinkage long xtensa_rt_sigsuspend(sigset_t __user *unewset, | ||
417 | size_t sigsetsize, | ||
418 | long a2, long a3, long a4, long a5, | ||
419 | struct pt_regs *regs) | ||
420 | { | ||
421 | sigset_t saveset, newset; | ||
422 | |||
423 | /* XXX: Don't preclude handling different sized sigset_t's. */ | ||
424 | if (sigsetsize != sizeof(sigset_t)) | ||
425 | return -EINVAL; | ||
426 | |||
427 | if (copy_from_user(&newset, unewset, sizeof(newset))) | ||
428 | return -EFAULT; | ||
429 | |||
430 | sigdelsetmask(&newset, ~_BLOCKABLE); | ||
431 | spin_lock_irq(¤t->sighand->siglock); | ||
432 | saveset = current->blocked; | ||
433 | current->blocked = newset; | ||
434 | recalc_sigpending(); | ||
435 | spin_unlock_irq(¤t->sighand->siglock); | ||
436 | |||
437 | regs->areg[2] = -EINTR; | ||
438 | while (1) { | ||
439 | current->state = TASK_INTERRUPTIBLE; | ||
440 | schedule(); | ||
441 | if (do_signal(regs, &saveset)) | ||
442 | return -EINTR; | ||
443 | } | ||
444 | } | ||
445 | |||
446 | asmlinkage long xtensa_sigaltstack(const stack_t __user *uss, | ||
447 | stack_t __user *uoss, | ||
448 | long a2, long a3, long a4, long a5, | ||
449 | struct pt_regs *regs) | ||
450 | { | ||
451 | return do_sigaltstack(uss, uoss, regs->areg[1]); | ||
452 | } | ||
453 | |||
649 | 454 | ||
650 | 455 | ||
651 | /* | 456 | /* |
@@ -663,51 +468,89 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
663 | int signr; | 468 | int signr; |
664 | struct k_sigaction ka; | 469 | struct k_sigaction ka; |
665 | 470 | ||
471 | if (!user_mode(regs)) | ||
472 | return 0; | ||
473 | |||
474 | if (try_to_freeze()) | ||
475 | goto no_signal; | ||
476 | |||
666 | if (!oldset) | 477 | if (!oldset) |
667 | oldset = ¤t->blocked; | 478 | oldset = ¤t->blocked; |
668 | 479 | ||
480 | task_pt_regs(current)->icountlevel = 0; | ||
481 | |||
669 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 482 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
670 | 483 | ||
671 | /* Are we from a system call? */ | 484 | if (signr > 0) { |
672 | if (regs->syscall >= 0) { | 485 | |
673 | /* If so, check system call restarting.. */ | 486 | /* Are we from a system call? */ |
674 | switch (regs->areg[2]) { | 487 | |
675 | case ERESTARTNOHAND: | 488 | if ((signed)regs->syscall >= 0) { |
676 | case ERESTART_RESTARTBLOCK: | ||
677 | regs->areg[2] = -EINTR; | ||
678 | break; | ||
679 | 489 | ||
680 | case ERESTARTSYS: | 490 | /* If so, check system call restarting.. */ |
681 | if (!(ka.sa.sa_flags & SA_RESTART)) { | 491 | |
492 | switch (regs->areg[2]) { | ||
493 | case -ERESTARTNOHAND: | ||
494 | case -ERESTART_RESTARTBLOCK: | ||
682 | regs->areg[2] = -EINTR; | 495 | regs->areg[2] = -EINTR; |
683 | break; | 496 | break; |
684 | } | 497 | |
685 | /* fallthrough */ | 498 | case -ERESTARTSYS: |
686 | case ERESTARTNOINTR: | 499 | if (!(ka.sa.sa_flags & SA_RESTART)) { |
687 | regs->areg[2] = regs->syscall; | 500 | regs->areg[2] = -EINTR; |
688 | regs->pc -= 3; | 501 | break; |
502 | } | ||
503 | /* fallthrough */ | ||
504 | case -ERESTARTNOINTR: | ||
505 | regs->areg[2] = regs->syscall; | ||
506 | regs->pc -= 3; | ||
507 | break; | ||
508 | |||
509 | default: | ||
510 | /* nothing to do */ | ||
511 | if (regs->areg[2] != 0) | ||
512 | break; | ||
513 | } | ||
689 | } | 514 | } |
690 | } | ||
691 | 515 | ||
692 | if (signr == 0) | 516 | /* Whee! Actually deliver the signal. */ |
693 | return 0; /* no signals delivered */ | 517 | /* Set up the stack frame */ |
518 | setup_frame(signr, &ka, &info, oldset, regs); | ||
694 | 519 | ||
695 | /* Whee! Actually deliver the signal. */ | 520 | if (ka.sa.sa_flags & SA_ONESHOT) |
521 | ka.sa.sa_handler = SIG_DFL; | ||
696 | 522 | ||
697 | /* Set up the stack frame */ | 523 | spin_lock_irq(¤t->sighand->siglock); |
698 | if (ka.sa.sa_flags & SA_SIGINFO) | 524 | sigorsets(¤t->blocked, ¤t->blocked, &ka.sa.sa_mask); |
699 | setup_rt_frame(signr, &ka, &info, oldset, regs); | 525 | if (!(ka.sa.sa_flags & SA_NODEFER)) |
700 | else | 526 | sigaddset(¤t->blocked, signr); |
701 | setup_frame(signr, &ka, oldset, regs); | 527 | recalc_sigpending(); |
528 | spin_unlock_irq(¤t->sighand->siglock); | ||
529 | if (current->ptrace & PT_SINGLESTEP) | ||
530 | task_pt_regs(current)->icountlevel = 1; | ||
702 | 531 | ||
703 | if (ka.sa.sa_flags & SA_ONESHOT) | 532 | return 1; |
704 | ka.sa.sa_handler = SIG_DFL; | 533 | } |
705 | 534 | ||
706 | spin_lock_irq(¤t->sighand->siglock); | 535 | no_signal: |
707 | sigorsets(¤t->blocked, ¤t->blocked, &ka.sa.sa_mask); | 536 | /* Did we come from a system call? */ |
708 | if (!(ka.sa.sa_flags & SA_NODEFER)) | 537 | if ((signed) regs->syscall >= 0) { |
709 | sigaddset(¤t->blocked, signr); | 538 | /* Restart the system call - no handlers present */ |
710 | recalc_sigpending(); | 539 | switch (regs->areg[2]) { |
711 | spin_unlock_irq(¤t->sighand->siglock); | 540 | case -ERESTARTNOHAND: |
712 | return 1; | 541 | case -ERESTARTSYS: |
542 | case -ERESTARTNOINTR: | ||
543 | regs->areg[2] = regs->syscall; | ||
544 | regs->pc -= 3; | ||
545 | break; | ||
546 | case -ERESTART_RESTARTBLOCK: | ||
547 | regs->areg[2] = __NR_restart_syscall; | ||
548 | regs->pc -= 3; | ||
549 | break; | ||
550 | } | ||
551 | } | ||
552 | if (current->ptrace & PT_SINGLESTEP) | ||
553 | task_pt_regs(current)->icountlevel = 1; | ||
554 | return 0; | ||
713 | } | 555 | } |
556 | |||
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index 4b7b4ff79973..b0582c3c5f8d 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S | |||
@@ -84,9 +84,7 @@ SECTIONS | |||
84 | { | 84 | { |
85 | /* The .head.text section must be the first section! */ | 85 | /* The .head.text section must be the first section! */ |
86 | *(.head.text) | 86 | *(.head.text) |
87 | *(.literal) | 87 | *(.literal .text) |
88 | TEXT_TEXT | ||
89 | *(.srom.text) | ||
90 | VMLINUX_SYMBOL(__sched_text_start) = .; | 88 | VMLINUX_SYMBOL(__sched_text_start) = .; |
91 | *(.sched.literal .sched.text) | 89 | *(.sched.literal .sched.text) |
92 | VMLINUX_SYMBOL(__sched_text_end) = .; | 90 | VMLINUX_SYMBOL(__sched_text_end) = .; |
@@ -96,6 +94,7 @@ SECTIONS | |||
96 | 94 | ||
97 | } | 95 | } |
98 | _etext = .; | 96 | _etext = .; |
97 | PROVIDE (etext = .); | ||
99 | 98 | ||
100 | . = ALIGN(16); | 99 | . = ALIGN(16); |
101 | 100 | ||
@@ -103,32 +102,6 @@ SECTIONS | |||
103 | 102 | ||
104 | /* Relocation table */ | 103 | /* Relocation table */ |
105 | 104 | ||
106 | . = ALIGN(16); | ||
107 | __boot_reloc_table_start = ABSOLUTE(.); | ||
108 | |||
109 | __relocate : { | ||
110 | |||
111 | RELOCATE_ENTRY(_WindowVectors_text, | ||
112 | .WindowVectors.text); | ||
113 | #if 0 | ||
114 | RELOCATE_ENTRY(_KernelExceptionVector_literal, | ||
115 | .KernelExceptionVector.literal); | ||
116 | #endif | ||
117 | RELOCATE_ENTRY(_KernelExceptionVector_text, | ||
118 | .KernelExceptionVector.text); | ||
119 | #if 0 | ||
120 | RELOCATE_ENTRY(_UserExceptionVector_literal, | ||
121 | .UserExceptionVector.literal); | ||
122 | #endif | ||
123 | RELOCATE_ENTRY(_UserExceptionVector_text, | ||
124 | .UserExceptionVector.text); | ||
125 | RELOCATE_ENTRY(_DoubleExceptionVector_literal, | ||
126 | .DoubleExceptionVector.literal); | ||
127 | RELOCATE_ENTRY(_DoubleExceptionVector_text, | ||
128 | .DoubleExceptionVector.text); | ||
129 | } | ||
130 | __boot_reloc_table_end = ABSOLUTE(.) ; | ||
131 | |||
132 | .fixup : { *(.fixup) } | 105 | .fixup : { *(.fixup) } |
133 | 106 | ||
134 | . = ALIGN(16); | 107 | . = ALIGN(16); |
@@ -145,8 +118,7 @@ SECTIONS | |||
145 | _fdata = .; | 118 | _fdata = .; |
146 | .data : | 119 | .data : |
147 | { | 120 | { |
148 | DATA_DATA | 121 | *(.data) CONSTRUCTORS |
149 | CONSTRUCTORS | ||
150 | . = ALIGN(XCHAL_ICACHE_LINESIZE); | 122 | . = ALIGN(XCHAL_ICACHE_LINESIZE); |
151 | *(.data.cacheline_aligned) | 123 | *(.data.cacheline_aligned) |
152 | } | 124 | } |
@@ -174,6 +146,22 @@ SECTIONS | |||
174 | __tagtable_begin = .; | 146 | __tagtable_begin = .; |
175 | *(.taglist) | 147 | *(.taglist) |
176 | __tagtable_end = .; | 148 | __tagtable_end = .; |
149 | |||
150 | . = ALIGN(16); | ||
151 | __boot_reloc_table_start = ABSOLUTE(.); | ||
152 | |||
153 | RELOCATE_ENTRY(_WindowVectors_text, | ||
154 | .WindowVectors.text); | ||
155 | RELOCATE_ENTRY(_KernelExceptionVector_text, | ||
156 | .KernelExceptionVector.text); | ||
157 | RELOCATE_ENTRY(_UserExceptionVector_text, | ||
158 | .UserExceptionVector.text); | ||
159 | RELOCATE_ENTRY(_DoubleExceptionVector_literal, | ||
160 | .DoubleExceptionVector.literal); | ||
161 | RELOCATE_ENTRY(_DoubleExceptionVector_text, | ||
162 | .DoubleExceptionVector.text); | ||
163 | |||
164 | __boot_reloc_table_end = ABSOLUTE(.) ; | ||
177 | } | 165 | } |
178 | 166 | ||
179 | . = ALIGN(XCHAL_ICACHE_LINESIZE); | 167 | . = ALIGN(XCHAL_ICACHE_LINESIZE); |
@@ -194,16 +182,6 @@ SECTIONS | |||
194 | 182 | ||
195 | SECURITY_INIT | 183 | SECURITY_INIT |
196 | 184 | ||
197 | . = ALIGN(4); | ||
198 | |||
199 | __start___ftr_fixup = .; | ||
200 | __ftr_fixup : { *(__ftr_fixup) } | ||
201 | __stop___ftr_fixup = .; | ||
202 | |||
203 | . = ALIGN(4096); | ||
204 | __per_cpu_start = .; | ||
205 | .data.percpu : { *(.data.percpu) } | ||
206 | __per_cpu_end = .; | ||
207 | 185 | ||
208 | #ifdef CONFIG_BLK_DEV_INITRD | 186 | #ifdef CONFIG_BLK_DEV_INITRD |
209 | . = ALIGN(4096); | 187 | . = ALIGN(4096); |
@@ -212,6 +190,12 @@ SECTIONS | |||
212 | __initramfs_end = .; | 190 | __initramfs_end = .; |
213 | #endif | 191 | #endif |
214 | 192 | ||
193 | . = ALIGN(4096); | ||
194 | __per_cpu_start = .; | ||
195 | .data.percpu : { *(.data.percpu) } | ||
196 | __per_cpu_end = .; | ||
197 | |||
198 | |||
215 | /* We need this dummy segment here */ | 199 | /* We need this dummy segment here */ |
216 | 200 | ||
217 | . = ALIGN(4); | 201 | . = ALIGN(4); |
@@ -273,9 +257,9 @@ SECTIONS | |||
273 | 257 | ||
274 | /* BSS section */ | 258 | /* BSS section */ |
275 | _bss_start = .; | 259 | _bss_start = .; |
276 | .sbss : { *(.sbss) *(.scommon) } | 260 | .bss : { *(.bss.page_aligned) *(.bss) } |
277 | .bss : { *(COMMON) *(.bss) } | ||
278 | _bss_end = .; | 261 | _bss_end = .; |
262 | |||
279 | _end = .; | 263 | _end = .; |
280 | 264 | ||
281 | /* only used by the boot loader */ | 265 | /* only used by the boot loader */ |
@@ -293,16 +277,16 @@ SECTIONS | |||
293 | *(.ResetVector.text) | 277 | *(.ResetVector.text) |
294 | } | 278 | } |
295 | 279 | ||
296 | |||
297 | /* Sections to be discarded */ | 280 | /* Sections to be discarded */ |
298 | /DISCARD/ : | 281 | /DISCARD/ : |
299 | { | 282 | { |
300 | *(.text.exit) | 283 | *(.exit.literal .exit.text) |
301 | *(.text.exit.literal) | 284 | *(.exit.data) |
302 | *(.data.exit) | ||
303 | *(.exitcall.exit) | 285 | *(.exitcall.exit) |
304 | } | 286 | } |
305 | 287 | ||
288 | .xt.lit : { *(.xt.lit) } | ||
289 | .xt.prop : { *(.xt.prop) } | ||
306 | 290 | ||
307 | .debug 0 : { *(.debug) } | 291 | .debug 0 : { *(.debug) } |
308 | .line 0 : { *(.line) } | 292 | .line 0 : { *(.line) } |
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c index cd7e6a020602..60dbdb43fb4c 100644 --- a/arch/xtensa/kernel/xtensa_ksyms.c +++ b/arch/xtensa/kernel/xtensa_ksyms.c | |||
@@ -38,21 +38,10 @@ | |||
38 | /* | 38 | /* |
39 | * String functions | 39 | * String functions |
40 | */ | 40 | */ |
41 | EXPORT_SYMBOL(memcmp); | ||
42 | EXPORT_SYMBOL(memset); | 41 | EXPORT_SYMBOL(memset); |
43 | EXPORT_SYMBOL(memcpy); | 42 | EXPORT_SYMBOL(memcpy); |
44 | EXPORT_SYMBOL(memmove); | 43 | EXPORT_SYMBOL(memmove); |
45 | EXPORT_SYMBOL(memchr); | ||
46 | EXPORT_SYMBOL(strcat); | ||
47 | EXPORT_SYMBOL(strchr); | ||
48 | EXPORT_SYMBOL(strlen); | ||
49 | EXPORT_SYMBOL(strncat); | ||
50 | EXPORT_SYMBOL(strnlen); | ||
51 | EXPORT_SYMBOL(strrchr); | ||
52 | EXPORT_SYMBOL(strstr); | ||
53 | 44 | ||
54 | EXPORT_SYMBOL(enable_irq); | ||
55 | EXPORT_SYMBOL(disable_irq); | ||
56 | EXPORT_SYMBOL(kernel_thread); | 45 | EXPORT_SYMBOL(kernel_thread); |
57 | 46 | ||
58 | /* | 47 | /* |
diff --git a/arch/xtensa/lib/strncpy_user.S b/arch/xtensa/lib/strncpy_user.S index a834057bda6b..b2655d94558d 100644 --- a/arch/xtensa/lib/strncpy_user.S +++ b/arch/xtensa/lib/strncpy_user.S | |||
@@ -25,18 +25,18 @@ | |||
25 | /* | 25 | /* |
26 | * char *__strncpy_user(char *dst, const char *src, size_t len) | 26 | * char *__strncpy_user(char *dst, const char *src, size_t len) |
27 | */ | 27 | */ |
28 | .text | 28 | |
29 | .begin literal | 29 | #ifdef __XTENSA_EB__ |
30 | .align 4 | 30 | # define MASK0 0xff000000 |
31 | .Lmask0: | 31 | # define MASK1 0x00ff0000 |
32 | .byte 0xff, 0x00, 0x00, 0x00 | 32 | # define MASK2 0x0000ff00 |
33 | .Lmask1: | 33 | # define MASK3 0x000000ff |
34 | .byte 0x00, 0xff, 0x00, 0x00 | 34 | #else |
35 | .Lmask2: | 35 | # define MASK0 0x000000ff |
36 | .byte 0x00, 0x00, 0xff, 0x00 | 36 | # define MASK1 0x0000ff00 |
37 | .Lmask3: | 37 | # define MASK2 0x00ff0000 |
38 | .byte 0x00, 0x00, 0x00, 0xff | 38 | # define MASK3 0xff000000 |
39 | .end literal | 39 | #endif |
40 | 40 | ||
41 | # Register use | 41 | # Register use |
42 | # a0/ return address | 42 | # a0/ return address |
@@ -53,6 +53,7 @@ | |||
53 | # a11/ dst | 53 | # a11/ dst |
54 | # a12/ tmp | 54 | # a12/ tmp |
55 | 55 | ||
56 | .text | ||
56 | .align 4 | 57 | .align 4 |
57 | .global __strncpy_user | 58 | .global __strncpy_user |
58 | .type __strncpy_user,@function | 59 | .type __strncpy_user,@function |
@@ -61,10 +62,10 @@ __strncpy_user: | |||
61 | # a2/ dst, a3/ src, a4/ len | 62 | # a2/ dst, a3/ src, a4/ len |
62 | mov a11, a2 # leave dst in return value register | 63 | mov a11, a2 # leave dst in return value register |
63 | beqz a4, .Lret # if len is zero | 64 | beqz a4, .Lret # if len is zero |
64 | l32r a5, .Lmask0 # mask for byte 0 | 65 | movi a5, MASK0 # mask for byte 0 |
65 | l32r a6, .Lmask1 # mask for byte 1 | 66 | movi a6, MASK1 # mask for byte 1 |
66 | l32r a7, .Lmask2 # mask for byte 2 | 67 | movi a7, MASK2 # mask for byte 2 |
67 | l32r a8, .Lmask3 # mask for byte 3 | 68 | movi a8, MASK3 # mask for byte 3 |
68 | bbsi.l a3, 0, .Lsrc1mod2 # if only 8-bit aligned | 69 | bbsi.l a3, 0, .Lsrc1mod2 # if only 8-bit aligned |
69 | bbsi.l a3, 1, .Lsrc2mod4 # if only 16-bit aligned | 70 | bbsi.l a3, 1, .Lsrc2mod4 # if only 16-bit aligned |
70 | .Lsrcaligned: # return here when src is word-aligned | 71 | .Lsrcaligned: # return here when src is word-aligned |
diff --git a/arch/xtensa/lib/strnlen_user.S b/arch/xtensa/lib/strnlen_user.S index 5e9c1e709b2e..ad3f616322ca 100644 --- a/arch/xtensa/lib/strnlen_user.S +++ b/arch/xtensa/lib/strnlen_user.S | |||
@@ -24,18 +24,18 @@ | |||
24 | /* | 24 | /* |
25 | * size_t __strnlen_user(const char *s, size_t len) | 25 | * size_t __strnlen_user(const char *s, size_t len) |
26 | */ | 26 | */ |
27 | .text | 27 | |
28 | .begin literal | 28 | #ifdef __XTENSA_EB__ |
29 | .align 4 | 29 | # define MASK0 0xff000000 |
30 | .Lmask0: | 30 | # define MASK1 0x00ff0000 |
31 | .byte 0xff, 0x00, 0x00, 0x00 | 31 | # define MASK2 0x0000ff00 |
32 | .Lmask1: | 32 | # define MASK3 0x000000ff |
33 | .byte 0x00, 0xff, 0x00, 0x00 | 33 | #else |
34 | .Lmask2: | 34 | # define MASK0 0x000000ff |
35 | .byte 0x00, 0x00, 0xff, 0x00 | 35 | # define MASK1 0x0000ff00 |
36 | .Lmask3: | 36 | # define MASK2 0x00ff0000 |
37 | .byte 0x00, 0x00, 0x00, 0xff | 37 | # define MASK3 0xff000000 |
38 | .end literal | 38 | #endif |
39 | 39 | ||
40 | # Register use: | 40 | # Register use: |
41 | # a2/ src | 41 | # a2/ src |
@@ -48,6 +48,7 @@ | |||
48 | # a9/ tmp | 48 | # a9/ tmp |
49 | # a10/ tmp | 49 | # a10/ tmp |
50 | 50 | ||
51 | .text | ||
51 | .align 4 | 52 | .align 4 |
52 | .global __strnlen_user | 53 | .global __strnlen_user |
53 | .type __strnlen_user,@function | 54 | .type __strnlen_user,@function |
@@ -56,10 +57,10 @@ __strnlen_user: | |||
56 | # a2/ s, a3/ len | 57 | # a2/ s, a3/ len |
57 | addi a4, a2, -4 # because we overincrement at the end; | 58 | addi a4, a2, -4 # because we overincrement at the end; |
58 | # we compensate with load offsets of 4 | 59 | # we compensate with load offsets of 4 |
59 | l32r a5, .Lmask0 # mask for byte 0 | 60 | movi a5, MASK0 # mask for byte 0 |
60 | l32r a6, .Lmask1 # mask for byte 1 | 61 | movi a6, MASK1 # mask for byte 1 |
61 | l32r a7, .Lmask2 # mask for byte 2 | 62 | movi a7, MASK2 # mask for byte 2 |
62 | l32r a8, .Lmask3 # mask for byte 3 | 63 | movi a8, MASK3 # mask for byte 3 |
63 | bbsi.l a2, 0, .L1mod2 # if only 8-bit aligned | 64 | bbsi.l a2, 0, .L1mod2 # if only 8-bit aligned |
64 | bbsi.l a2, 1, .L2mod4 # if only 16-bit aligned | 65 | bbsi.l a2, 1, .L2mod4 # if only 16-bit aligned |
65 | 66 | ||
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index e1ec2d1e8189..8415c76f11c2 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c | |||
@@ -205,7 +205,7 @@ void __init init_mmu (void) | |||
205 | /* Writing zeros to the <t>TLBCFG special registers ensure | 205 | /* Writing zeros to the <t>TLBCFG special registers ensure |
206 | * that valid values exist in the register. For existing | 206 | * that valid values exist in the register. For existing |
207 | * PGSZID<w> fields, zero selects the first element of the | 207 | * PGSZID<w> fields, zero selects the first element of the |
208 | * page-size array. For nonexistant PGSZID<w> fields, zero is | 208 | * page-size array. For nonexistent PGSZID<w> fields, zero is |
209 | * the best value to write. Also, when changing PGSZID<w> | 209 | * the best value to write. Also, when changing PGSZID<w> |
210 | * fields, the corresponding TLB must be flushed. | 210 | * fields, the corresponding TLB must be flushed. |
211 | */ | 211 | */ |
diff --git a/arch/xtensa/platform-iss/network.c b/arch/xtensa/platform-iss/network.c index 4bfe333be229..f09962fa98c0 100644 --- a/arch/xtensa/platform-iss/network.c +++ b/arch/xtensa/platform-iss/network.c | |||
@@ -473,7 +473,7 @@ static int iss_net_open(struct net_device *dev) | |||
473 | netif_start_queue(dev); | 473 | netif_start_queue(dev); |
474 | 474 | ||
475 | /* clear buffer - it can happen that the host side of the interface | 475 | /* clear buffer - it can happen that the host side of the interface |
476 | * is full when we gethere. In this case, new data is never queued, | 476 | * is full when we get here. In this case, new data is never queued, |
477 | * SIGIOs never arrive, and the net never works. | 477 | * SIGIOs never arrive, and the net never works. |
478 | */ | 478 | */ |
479 | while ((err = iss_net_rx(dev)) > 0) | 479 | while ((err = iss_net_rx(dev)) > 0) |