diff options
Diffstat (limited to 'arch')
31 files changed, 551 insertions, 618 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 296bc03d1cf1..91d5ef3397be 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -324,7 +324,7 @@ menu "Kernel Features" | |||
| 324 | 324 | ||
| 325 | config SMP | 325 | config SMP |
| 326 | bool "Symmetric Multi-Processing (EXPERIMENTAL)" | 326 | bool "Symmetric Multi-Processing (EXPERIMENTAL)" |
| 327 | depends on EXPERIMENTAL && BROKEN #&& n | 327 | depends on EXPERIMENTAL && REALVIEW_MPCORE |
| 328 | help | 328 | help |
| 329 | This enables support for systems with more than one CPU. If you have | 329 | This enables support for systems with more than one CPU. If you have |
| 330 | a system with only one CPU, like most personal computers, say N. If | 330 | a system with only one CPU, like most personal computers, say N. If |
| @@ -585,7 +585,7 @@ config FPE_NWFPE | |||
| 585 | 585 | ||
| 586 | config FPE_NWFPE_XP | 586 | config FPE_NWFPE_XP |
| 587 | bool "Support extended precision" | 587 | bool "Support extended precision" |
| 588 | depends on FPE_NWFPE && !CPU_BIG_ENDIAN | 588 | depends on FPE_NWFPE |
| 589 | help | 589 | help |
| 590 | Say Y to include 80-bit support in the kernel floating-point | 590 | Say Y to include 80-bit support in the kernel floating-point |
| 591 | emulator. Otherwise, only 32 and 64-bit support is compiled in. | 591 | emulator. Otherwise, only 32 and 64-bit support is compiled in. |
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c index df140962bb0f..6851abaf5524 100644 --- a/arch/arm/mach-ixp2000/core.c +++ b/arch/arm/mach-ixp2000/core.c | |||
| @@ -84,63 +84,54 @@ static struct map_desc ixp2000_io_desc[] __initdata = { | |||
| 84 | .virtual = IXP2000_CAP_VIRT_BASE, | 84 | .virtual = IXP2000_CAP_VIRT_BASE, |
| 85 | .pfn = __phys_to_pfn(IXP2000_CAP_PHYS_BASE), | 85 | .pfn = __phys_to_pfn(IXP2000_CAP_PHYS_BASE), |
| 86 | .length = IXP2000_CAP_SIZE, | 86 | .length = IXP2000_CAP_SIZE, |
| 87 | .type = MT_DEVICE | 87 | .type = MT_IXP2000_DEVICE, |
| 88 | }, { | 88 | }, { |
| 89 | .virtual = IXP2000_INTCTL_VIRT_BASE, | 89 | .virtual = IXP2000_INTCTL_VIRT_BASE, |
| 90 | .pfn = __phys_to_pfn(IXP2000_INTCTL_PHYS_BASE), | 90 | .pfn = __phys_to_pfn(IXP2000_INTCTL_PHYS_BASE), |
| 91 | .length = IXP2000_INTCTL_SIZE, | 91 | .length = IXP2000_INTCTL_SIZE, |
| 92 | .type = MT_DEVICE | 92 | .type = MT_IXP2000_DEVICE, |
| 93 | }, { | 93 | }, { |
| 94 | .virtual = IXP2000_PCI_CREG_VIRT_BASE, | 94 | .virtual = IXP2000_PCI_CREG_VIRT_BASE, |
| 95 | .pfn = __phys_to_pfn(IXP2000_PCI_CREG_PHYS_BASE), | 95 | .pfn = __phys_to_pfn(IXP2000_PCI_CREG_PHYS_BASE), |
| 96 | .length = IXP2000_PCI_CREG_SIZE, | 96 | .length = IXP2000_PCI_CREG_SIZE, |
| 97 | .type = MT_DEVICE | 97 | .type = MT_IXP2000_DEVICE, |
| 98 | }, { | 98 | }, { |
| 99 | .virtual = IXP2000_PCI_CSR_VIRT_BASE, | 99 | .virtual = IXP2000_PCI_CSR_VIRT_BASE, |
| 100 | .pfn = __phys_to_pfn(IXP2000_PCI_CSR_PHYS_BASE), | 100 | .pfn = __phys_to_pfn(IXP2000_PCI_CSR_PHYS_BASE), |
| 101 | .length = IXP2000_PCI_CSR_SIZE, | 101 | .length = IXP2000_PCI_CSR_SIZE, |
| 102 | .type = MT_DEVICE | 102 | .type = MT_IXP2000_DEVICE, |
| 103 | }, { | 103 | }, { |
| 104 | .virtual = IXP2000_MSF_VIRT_BASE, | 104 | .virtual = IXP2000_MSF_VIRT_BASE, |
| 105 | .pfn = __phys_to_pfn(IXP2000_MSF_PHYS_BASE), | 105 | .pfn = __phys_to_pfn(IXP2000_MSF_PHYS_BASE), |
| 106 | .length = IXP2000_MSF_SIZE, | 106 | .length = IXP2000_MSF_SIZE, |
| 107 | .type = MT_DEVICE | 107 | .type = MT_IXP2000_DEVICE, |
| 108 | }, { | 108 | }, { |
| 109 | .virtual = IXP2000_PCI_IO_VIRT_BASE, | 109 | .virtual = IXP2000_PCI_IO_VIRT_BASE, |
| 110 | .pfn = __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE), | 110 | .pfn = __phys_to_pfn(IXP2000_PCI_IO_PHYS_BASE), |
| 111 | .length = IXP2000_PCI_IO_SIZE, | 111 | .length = IXP2000_PCI_IO_SIZE, |
| 112 | .type = MT_DEVICE | 112 | .type = MT_IXP2000_DEVICE, |
| 113 | }, { | 113 | }, { |
| 114 | .virtual = IXP2000_PCI_CFG0_VIRT_BASE, | 114 | .virtual = IXP2000_PCI_CFG0_VIRT_BASE, |
| 115 | .pfn = __phys_to_pfn(IXP2000_PCI_CFG0_PHYS_BASE), | 115 | .pfn = __phys_to_pfn(IXP2000_PCI_CFG0_PHYS_BASE), |
| 116 | .length = IXP2000_PCI_CFG0_SIZE, | 116 | .length = IXP2000_PCI_CFG0_SIZE, |
| 117 | .type = MT_DEVICE | 117 | .type = MT_IXP2000_DEVICE, |
| 118 | }, { | 118 | }, { |
| 119 | .virtual = IXP2000_PCI_CFG1_VIRT_BASE, | 119 | .virtual = IXP2000_PCI_CFG1_VIRT_BASE, |
| 120 | .pfn = __phys_to_pfn(IXP2000_PCI_CFG1_PHYS_BASE), | 120 | .pfn = __phys_to_pfn(IXP2000_PCI_CFG1_PHYS_BASE), |
| 121 | .length = IXP2000_PCI_CFG1_SIZE, | 121 | .length = IXP2000_PCI_CFG1_SIZE, |
| 122 | .type = MT_DEVICE | 122 | .type = MT_IXP2000_DEVICE, |
| 123 | } | 123 | } |
| 124 | }; | 124 | }; |
| 125 | 125 | ||
| 126 | void __init ixp2000_map_io(void) | 126 | void __init ixp2000_map_io(void) |
| 127 | { | 127 | { |
| 128 | extern unsigned int processor_id; | ||
| 129 | |||
| 130 | /* | 128 | /* |
| 131 | * On IXP2400 CPUs we need to use MT_IXP2000_DEVICE for | 129 | * On IXP2400 CPUs we need to use MT_IXP2000_DEVICE so that |
| 132 | * tweaking the PMDs so XCB=101. On IXP2800s we use the normal | 130 | * XCB=101 (to avoid triggering erratum #66), and given that |
| 133 | * PMD flags. | 131 | * this mode speeds up I/O accesses and we have write buffer |
| 132 | * flushes in the right places anyway, it doesn't hurt to use | ||
| 133 | * XCB=101 for all IXP2000s. | ||
| 134 | */ | 134 | */ |
| 135 | if ((processor_id & 0xfffffff0) == 0x69054190) { | ||
| 136 | int i; | ||
| 137 | |||
| 138 | printk(KERN_INFO "Enabling IXP2400 erratum #66 workaround\n"); | ||
| 139 | |||
| 140 | for(i=0;i<ARRAY_SIZE(ixp2000_io_desc);i++) | ||
| 141 | ixp2000_io_desc[i].type = MT_IXP2000_DEVICE; | ||
| 142 | } | ||
| 143 | |||
| 144 | iotable_init(ixp2000_io_desc, ARRAY_SIZE(ixp2000_io_desc)); | 135 | iotable_init(ixp2000_io_desc, ARRAY_SIZE(ixp2000_io_desc)); |
| 145 | 136 | ||
| 146 | /* Set slowport to 8-bit mode. */ | 137 | /* Set slowport to 8-bit mode. */ |
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig index 4b63dc9eabfe..129976866d47 100644 --- a/arch/arm/mach-realview/Kconfig +++ b/arch/arm/mach-realview/Kconfig | |||
| @@ -8,4 +8,13 @@ config MACH_REALVIEW_EB | |||
| 8 | help | 8 | help |
| 9 | Include support for the ARM(R) RealView Emulation Baseboard platform. | 9 | Include support for the ARM(R) RealView Emulation Baseboard platform. |
| 10 | 10 | ||
| 11 | config REALVIEW_MPCORE | ||
| 12 | bool "Support MPcore tile" | ||
| 13 | depends on MACH_REALVIEW_EB | ||
| 14 | help | ||
| 15 | Enable support for the MPCore tile on the Realview platform. | ||
| 16 | Since there are device address and interrupt differences, a | ||
| 17 | kernel built with this option enabled is not compatible with | ||
| 18 | other tiles. | ||
| 19 | |||
| 11 | endmenu | 20 | endmenu |
diff --git a/arch/arm/mach-realview/Makefile b/arch/arm/mach-realview/Makefile index 8d37ea1605fd..011a85c10627 100644 --- a/arch/arm/mach-realview/Makefile +++ b/arch/arm/mach-realview/Makefile | |||
| @@ -4,3 +4,4 @@ | |||
| 4 | 4 | ||
| 5 | obj-y := core.o clock.o | 5 | obj-y := core.o clock.o |
| 6 | obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o | 6 | obj-$(CONFIG_MACH_REALVIEW_EB) += realview_eb.o |
| 7 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | ||
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h index 575599db74db..d83e8bad2038 100644 --- a/arch/arm/mach-realview/core.h +++ b/arch/arm/mach-realview/core.h | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #define __ASM_ARCH_REALVIEW_H | 23 | #define __ASM_ARCH_REALVIEW_H |
| 24 | 24 | ||
| 25 | #include <asm/hardware/amba.h> | 25 | #include <asm/hardware/amba.h> |
| 26 | #include <asm/leds.h> | ||
| 26 | #include <asm/io.h> | 27 | #include <asm/io.h> |
| 27 | 28 | ||
| 28 | #define __io_address(n) __io(IO_ADDRESS(n)) | 29 | #define __io_address(n) __io(IO_ADDRESS(n)) |
diff --git a/arch/arm/mach-realview/headsmp.S b/arch/arm/mach-realview/headsmp.S new file mode 100644 index 000000000000..4075473cf68a --- /dev/null +++ b/arch/arm/mach-realview/headsmp.S | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-realview/headsmp.S | ||
| 3 | * | ||
| 4 | * Copyright (c) 2003 ARM Limited | ||
| 5 | * All Rights Reserved | ||
| 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 | #include <linux/linkage.h> | ||
| 12 | #include <linux/init.h> | ||
| 13 | |||
| 14 | __INIT | ||
| 15 | |||
| 16 | /* | ||
| 17 | * Realview specific entry point for secondary CPUs. This provides | ||
| 18 | * a "holding pen" into which all secondary cores are held until we're | ||
| 19 | * ready for them to initialise. | ||
| 20 | */ | ||
| 21 | ENTRY(realview_secondary_startup) | ||
| 22 | mrc p15, 0, r0, c0, c0, 5 | ||
| 23 | and r0, r0, #15 | ||
| 24 | adr r4, 1f | ||
| 25 | ldmia r4, {r5, r6} | ||
| 26 | sub r4, r4, r5 | ||
| 27 | add r6, r6, r4 | ||
| 28 | pen: ldr r7, [r6] | ||
| 29 | cmp r7, r0 | ||
| 30 | bne pen | ||
| 31 | |||
| 32 | /* | ||
| 33 | * we've been released from the holding pen: secondary_stack | ||
| 34 | * should now contain the SVC stack for this core | ||
| 35 | */ | ||
| 36 | b secondary_startup | ||
| 37 | |||
| 38 | 1: .long . | ||
| 39 | .long pen_release | ||
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c new file mode 100644 index 000000000000..9844644d0fb5 --- /dev/null +++ b/arch/arm/mach-realview/platsmp.c | |||
| @@ -0,0 +1,195 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/mach-realview/platsmp.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2002 ARM Ltd. | ||
| 5 | * All Rights Reserved | ||
| 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 | #include <linux/init.h> | ||
| 12 | #include <linux/errno.h> | ||
| 13 | #include <linux/delay.h> | ||
| 14 | #include <linux/device.h> | ||
| 15 | #include <linux/smp.h> | ||
| 16 | |||
| 17 | #include <asm/cacheflush.h> | ||
| 18 | #include <asm/hardware/arm_scu.h> | ||
| 19 | #include <asm/hardware.h> | ||
| 20 | |||
| 21 | #include "core.h" | ||
| 22 | |||
| 23 | extern void realview_secondary_startup(void); | ||
| 24 | |||
| 25 | /* | ||
| 26 | * control for which core is the next to come out of the secondary | ||
| 27 | * boot "holding pen" | ||
| 28 | */ | ||
| 29 | volatile int __cpuinitdata pen_release = -1; | ||
| 30 | |||
| 31 | static unsigned int __init get_core_count(void) | ||
| 32 | { | ||
| 33 | unsigned int ncores; | ||
| 34 | |||
| 35 | ncores = __raw_readl(IO_ADDRESS(REALVIEW_MPCORE_SCU_BASE) + SCU_CONFIG); | ||
| 36 | |||
| 37 | return (ncores & 0x03) + 1; | ||
| 38 | } | ||
| 39 | |||
| 40 | static DEFINE_SPINLOCK(boot_lock); | ||
| 41 | |||
| 42 | void __cpuinit platform_secondary_init(unsigned int cpu) | ||
| 43 | { | ||
| 44 | /* | ||
| 45 | * the primary core may have used a "cross call" soft interrupt | ||
| 46 | * to get this processor out of WFI in the BootMonitor - make | ||
| 47 | * sure that we are no longer being sent this soft interrupt | ||
| 48 | */ | ||
| 49 | smp_cross_call_done(cpumask_of_cpu(cpu)); | ||
| 50 | |||
| 51 | /* | ||
| 52 | * if any interrupts are already enabled for the primary | ||
| 53 | * core (e.g. timer irq), then they will not have been enabled | ||
| 54 | * for us: do so | ||
| 55 | */ | ||
| 56 | gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE)); | ||
| 57 | |||
| 58 | /* | ||
| 59 | * let the primary processor know we're out of the | ||
| 60 | * pen, then head off into the C entry point | ||
| 61 | */ | ||
| 62 | pen_release = -1; | ||
| 63 | |||
| 64 | /* | ||
| 65 | * Synchronise with the boot thread. | ||
| 66 | */ | ||
| 67 | spin_lock(&boot_lock); | ||
| 68 | spin_unlock(&boot_lock); | ||
| 69 | } | ||
| 70 | |||
| 71 | int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) | ||
| 72 | { | ||
| 73 | unsigned long timeout; | ||
| 74 | |||
| 75 | /* | ||
| 76 | * set synchronisation state between this boot processor | ||
| 77 | * and the secondary one | ||
| 78 | */ | ||
| 79 | spin_lock(&boot_lock); | ||
| 80 | |||
| 81 | /* | ||
| 82 | * The secondary processor is waiting to be released from | ||
| 83 | * the holding pen - release it, then wait for it to flag | ||
| 84 | * that it has been released by resetting pen_release. | ||
| 85 | * | ||
| 86 | * Note that "pen_release" is the hardware CPU ID, whereas | ||
| 87 | * "cpu" is Linux's internal ID. | ||
| 88 | */ | ||
| 89 | pen_release = cpu; | ||
| 90 | flush_cache_all(); | ||
| 91 | |||
| 92 | /* | ||
| 93 | * XXX | ||
| 94 | * | ||
| 95 | * This is a later addition to the booting protocol: the | ||
| 96 | * bootMonitor now puts secondary cores into WFI, so | ||
| 97 | * poke_milo() no longer gets the cores moving; we need | ||
| 98 | * to send a soft interrupt to wake the secondary core. | ||
| 99 | * Use smp_cross_call() for this, since there's little | ||
| 100 | * point duplicating the code here | ||
| 101 | */ | ||
| 102 | smp_cross_call(cpumask_of_cpu(cpu)); | ||
| 103 | |||
| 104 | timeout = jiffies + (1 * HZ); | ||
| 105 | while (time_before(jiffies, timeout)) { | ||
| 106 | if (pen_release == -1) | ||
| 107 | break; | ||
| 108 | |||
| 109 | udelay(10); | ||
| 110 | } | ||
| 111 | |||
| 112 | /* | ||
| 113 | * now the secondary core is starting up let it run its | ||
| 114 | * calibrations, then wait for it to finish | ||
| 115 | */ | ||
| 116 | spin_unlock(&boot_lock); | ||
| 117 | |||
| 118 | return pen_release != -1 ? -ENOSYS : 0; | ||
| 119 | } | ||
| 120 | |||
| 121 | static void __init poke_milo(void) | ||
| 122 | { | ||
| 123 | extern void secondary_startup(void); | ||
| 124 | |||
| 125 | /* nobody is to be released from the pen yet */ | ||
| 126 | pen_release = -1; | ||
| 127 | |||
| 128 | /* | ||
| 129 | * write the address of secondary startup into the system-wide | ||
| 130 | * flags register, then clear the bottom two bits, which is what | ||
| 131 | * BootMonitor is waiting for | ||
| 132 | */ | ||
| 133 | #if 1 | ||
| 134 | #define REALVIEW_SYS_FLAGSS_OFFSET 0x30 | ||
| 135 | __raw_writel(virt_to_phys(realview_secondary_startup), | ||
| 136 | (IO_ADDRESS(REALVIEW_SYS_BASE) + | ||
| 137 | REALVIEW_SYS_FLAGSS_OFFSET)); | ||
| 138 | #define REALVIEW_SYS_FLAGSC_OFFSET 0x34 | ||
| 139 | __raw_writel(3, | ||
| 140 | (IO_ADDRESS(REALVIEW_SYS_BASE) + | ||
| 141 | REALVIEW_SYS_FLAGSC_OFFSET)); | ||
| 142 | #endif | ||
| 143 | |||
| 144 | mb(); | ||
| 145 | } | ||
| 146 | |||
| 147 | void __init smp_prepare_cpus(unsigned int max_cpus) | ||
| 148 | { | ||
| 149 | unsigned int ncores = get_core_count(); | ||
| 150 | unsigned int cpu = smp_processor_id(); | ||
| 151 | int i; | ||
| 152 | |||
| 153 | /* sanity check */ | ||
| 154 | if (ncores == 0) { | ||
| 155 | printk(KERN_ERR | ||
| 156 | "Realview: strange CM count of 0? Default to 1\n"); | ||
| 157 | |||
| 158 | ncores = 1; | ||
| 159 | } | ||
| 160 | |||
| 161 | if (ncores > NR_CPUS) { | ||
| 162 | printk(KERN_WARNING | ||
| 163 | "Realview: no. of cores (%d) greater than configured " | ||
| 164 | "maximum of %d - clipping\n", | ||
| 165 | ncores, NR_CPUS); | ||
| 166 | ncores = NR_CPUS; | ||
| 167 | } | ||
| 168 | |||
| 169 | smp_store_cpu_info(cpu); | ||
| 170 | |||
| 171 | /* | ||
| 172 | * are we trying to boot more cores than exist? | ||
| 173 | */ | ||
| 174 | if (max_cpus > ncores) | ||
| 175 | max_cpus = ncores; | ||
| 176 | |||
| 177 | /* | ||
| 178 | * Initialise the possible/present maps. | ||
| 179 | * cpu_possible_map describes the set of CPUs which may be present | ||
| 180 | * cpu_present_map describes the set of CPUs populated | ||
| 181 | */ | ||
| 182 | for (i = 0; i < max_cpus; i++) { | ||
| 183 | cpu_set(i, cpu_possible_map); | ||
| 184 | cpu_set(i, cpu_present_map); | ||
| 185 | } | ||
| 186 | |||
| 187 | /* | ||
| 188 | * Do we need any more CPUs? If so, then let them know where | ||
| 189 | * to start. Note that, on modern versions of MILO, the "poke" | ||
| 190 | * doesn't actually do anything until each individual core is | ||
| 191 | * sent a soft interrupt to get it out of WFI | ||
| 192 | */ | ||
| 193 | if (max_cpus > 1) | ||
| 194 | poke_milo(); | ||
| 195 | } | ||
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index 267bb07e39b7..7dc32503fdf2 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c | |||
| @@ -136,6 +136,11 @@ static struct amba_device *amba_devs[] __initdata = { | |||
| 136 | 136 | ||
| 137 | static void __init gic_init_irq(void) | 137 | static void __init gic_init_irq(void) |
| 138 | { | 138 | { |
| 139 | #ifdef CONFIG_REALVIEW_MPCORE | ||
| 140 | writel(0x0000a05f, __io_address(REALVIEW_SYS_LOCK)); | ||
| 141 | writel(0x008003c0, __io_address(REALVIEW_SYS_BASE) + 0xd8); | ||
| 142 | writel(0x00000000, __io_address(REALVIEW_SYS_LOCK)); | ||
| 143 | #endif | ||
| 139 | gic_dist_init(__io_address(REALVIEW_GIC_DIST_BASE)); | 144 | gic_dist_init(__io_address(REALVIEW_GIC_DIST_BASE)); |
| 140 | gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE)); | 145 | gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE)); |
| 141 | } | 146 | } |
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index fb5b40289de2..9e50127be635 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c | |||
| @@ -354,7 +354,7 @@ void __init build_mem_type_table(void) | |||
| 354 | { | 354 | { |
| 355 | struct cachepolicy *cp; | 355 | struct cachepolicy *cp; |
| 356 | unsigned int cr = get_cr(); | 356 | unsigned int cr = get_cr(); |
| 357 | unsigned int user_pgprot; | 357 | unsigned int user_pgprot, kern_pgprot; |
| 358 | int cpu_arch = cpu_architecture(); | 358 | int cpu_arch = cpu_architecture(); |
| 359 | int i; | 359 | int i; |
| 360 | 360 | ||
| @@ -381,7 +381,7 @@ void __init build_mem_type_table(void) | |||
| 381 | } | 381 | } |
| 382 | 382 | ||
| 383 | cp = &cache_policies[cachepolicy]; | 383 | cp = &cache_policies[cachepolicy]; |
| 384 | user_pgprot = cp->pte; | 384 | kern_pgprot = user_pgprot = cp->pte; |
| 385 | 385 | ||
| 386 | /* | 386 | /* |
| 387 | * ARMv6 and above have extended page tables. | 387 | * ARMv6 and above have extended page tables. |
| @@ -393,6 +393,7 @@ void __init build_mem_type_table(void) | |||
| 393 | */ | 393 | */ |
| 394 | mem_types[MT_MEMORY].prot_sect &= ~PMD_BIT4; | 394 | mem_types[MT_MEMORY].prot_sect &= ~PMD_BIT4; |
| 395 | mem_types[MT_ROM].prot_sect &= ~PMD_BIT4; | 395 | mem_types[MT_ROM].prot_sect &= ~PMD_BIT4; |
| 396 | |||
| 396 | /* | 397 | /* |
| 397 | * Mark cache clean areas and XIP ROM read only | 398 | * Mark cache clean areas and XIP ROM read only |
| 398 | * from SVC mode and no access from userspace. | 399 | * from SVC mode and no access from userspace. |
| @@ -412,32 +413,47 @@ void __init build_mem_type_table(void) | |||
| 412 | * (iow, non-global) | 413 | * (iow, non-global) |
| 413 | */ | 414 | */ |
| 414 | user_pgprot |= L_PTE_ASID; | 415 | user_pgprot |= L_PTE_ASID; |
| 416 | |||
| 417 | #ifdef CONFIG_SMP | ||
| 418 | /* | ||
| 419 | * Mark memory with the "shared" attribute for SMP systems | ||
| 420 | */ | ||
| 421 | user_pgprot |= L_PTE_SHARED; | ||
| 422 | kern_pgprot |= L_PTE_SHARED; | ||
| 423 | mem_types[MT_MEMORY].prot_sect |= PMD_SECT_S; | ||
| 424 | #endif | ||
| 415 | } | 425 | } |
| 416 | 426 | ||
| 427 | for (i = 0; i < 16; i++) { | ||
| 428 | unsigned long v = pgprot_val(protection_map[i]); | ||
| 429 | v = (v & ~(L_PTE_BUFFERABLE|L_PTE_CACHEABLE)) | user_pgprot; | ||
| 430 | protection_map[i] = __pgprot(v); | ||
| 431 | } | ||
| 432 | |||
| 433 | mem_types[MT_LOW_VECTORS].prot_pte |= kern_pgprot; | ||
| 434 | mem_types[MT_HIGH_VECTORS].prot_pte |= kern_pgprot; | ||
| 435 | |||
| 417 | if (cpu_arch >= CPU_ARCH_ARMv5) { | 436 | if (cpu_arch >= CPU_ARCH_ARMv5) { |
| 418 | mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE; | 437 | #ifndef CONFIG_SMP |
| 419 | mem_types[MT_HIGH_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE; | 438 | /* |
| 439 | * Only use write-through for non-SMP systems | ||
| 440 | */ | ||
| 441 | mem_types[MT_LOW_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE; | ||
| 442 | mem_types[MT_HIGH_VECTORS].prot_pte &= ~L_PTE_BUFFERABLE; | ||
| 443 | #endif | ||
| 420 | } else { | 444 | } else { |
| 421 | mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte; | ||
| 422 | mem_types[MT_HIGH_VECTORS].prot_pte |= cp->pte; | ||
| 423 | mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1); | 445 | mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1); |
| 424 | } | 446 | } |
| 425 | 447 | ||
| 448 | pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | | ||
| 449 | L_PTE_DIRTY | L_PTE_WRITE | | ||
| 450 | L_PTE_EXEC | kern_pgprot); | ||
| 451 | |||
| 426 | mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; | 452 | mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask; |
| 427 | mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; | 453 | mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask; |
| 428 | mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; | 454 | mem_types[MT_MEMORY].prot_sect |= ecc_mask | cp->pmd; |
| 429 | mem_types[MT_ROM].prot_sect |= cp->pmd; | 455 | mem_types[MT_ROM].prot_sect |= cp->pmd; |
| 430 | 456 | ||
| 431 | for (i = 0; i < 16; i++) { | ||
| 432 | unsigned long v = pgprot_val(protection_map[i]); | ||
| 433 | v = (v & ~(PTE_BUFFERABLE|PTE_CACHEABLE)) | user_pgprot; | ||
| 434 | protection_map[i] = __pgprot(v); | ||
| 435 | } | ||
| 436 | |||
| 437 | pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | | ||
| 438 | L_PTE_DIRTY | L_PTE_WRITE | | ||
| 439 | L_PTE_EXEC | cp->pte); | ||
| 440 | |||
| 441 | switch (cp->pmd) { | 457 | switch (cp->pmd) { |
| 442 | case PMD_SECT_WT: | 458 | case PMD_SECT_WT: |
| 443 | mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT; | 459 | mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT; |
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 9bb5fff406fb..92f3ca31b7b9 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/linkage.h> | 12 | #include <linux/linkage.h> |
| 13 | #include <asm/assembler.h> | 13 | #include <asm/assembler.h> |
| 14 | #include <asm/asm-offsets.h> | 14 | #include <asm/asm-offsets.h> |
| 15 | #include <asm/hardware/arm_scu.h> | ||
| 15 | #include <asm/procinfo.h> | 16 | #include <asm/procinfo.h> |
| 16 | #include <asm/pgtable.h> | 17 | #include <asm/pgtable.h> |
| 17 | 18 | ||
| @@ -112,6 +113,9 @@ ENTRY(cpu_v6_dcache_clean_area) | |||
| 112 | ENTRY(cpu_v6_switch_mm) | 113 | ENTRY(cpu_v6_switch_mm) |
| 113 | mov r2, #0 | 114 | mov r2, #0 |
| 114 | ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id | 115 | ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id |
| 116 | #ifdef CONFIG_SMP | ||
| 117 | orr r0, r0, #2 @ set shared pgtable | ||
| 118 | #endif | ||
| 115 | mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB | 119 | mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB |
| 116 | mcr p15, 0, r2, c7, c10, 4 @ drain write buffer | 120 | mcr p15, 0, r2, c7, c10, 4 @ drain write buffer |
| 117 | mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 | 121 | mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 |
| @@ -140,7 +144,7 @@ ENTRY(cpu_v6_switch_mm) | |||
| 140 | ENTRY(cpu_v6_set_pte) | 144 | ENTRY(cpu_v6_set_pte) |
| 141 | str r1, [r0], #-2048 @ linux version | 145 | str r1, [r0], #-2048 @ linux version |
| 142 | 146 | ||
| 143 | bic r2, r1, #0x000007f0 | 147 | bic r2, r1, #0x000003f0 |
| 144 | bic r2, r2, #0x00000003 | 148 | bic r2, r2, #0x00000003 |
| 145 | orr r2, r2, #PTE_EXT_AP0 | 2 | 149 | orr r2, r2, #PTE_EXT_AP0 | 2 |
| 146 | 150 | ||
| @@ -191,6 +195,23 @@ cpu_v6_name: | |||
| 191 | * - cache type register is implemented | 195 | * - cache type register is implemented |
| 192 | */ | 196 | */ |
| 193 | __v6_setup: | 197 | __v6_setup: |
| 198 | #ifdef CONFIG_SMP | ||
| 199 | /* Set up the SCU on core 0 only */ | ||
| 200 | mrc p15, 0, r0, c0, c0, 5 @ CPU core number | ||
| 201 | ands r0, r0, #15 | ||
| 202 | moveq r0, #0x10000000 @ SCU_BASE | ||
| 203 | orreq r0, r0, #0x00100000 | ||
| 204 | ldreq r5, [r0, #SCU_CTRL] | ||
| 205 | orreq r5, r5, #1 | ||
| 206 | streq r5, [r0, #SCU_CTRL] | ||
| 207 | |||
| 208 | #ifndef CONFIG_CPU_DCACHE_DISABLE | ||
| 209 | mrc p15, 0, r0, c1, c0, 1 @ Enable SMP/nAMP mode | ||
| 210 | orr r0, r0, #0x20 | ||
| 211 | mcr p15, 0, r0, c1, c0, 1 | ||
| 212 | #endif | ||
| 213 | #endif | ||
| 214 | |||
| 194 | mov r0, #0 | 215 | mov r0, #0 |
| 195 | mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache | 216 | mcr p15, 0, r0, c7, c14, 0 @ clean+invalidate D cache |
| 196 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache | 217 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache |
| @@ -198,6 +219,9 @@ __v6_setup: | |||
| 198 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | 219 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer |
| 199 | mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs | 220 | mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs |
| 200 | mcr p15, 0, r0, c2, c0, 2 @ TTB control register | 221 | mcr p15, 0, r0, c2, c0, 2 @ TTB control register |
| 222 | #ifdef CONFIG_SMP | ||
| 223 | orr r4, r4, #2 @ set shared pgtable | ||
| 224 | #endif | ||
| 201 | mcr p15, 0, r4, c2, c0, 1 @ load TTB1 | 225 | mcr p15, 0, r4, c2, c0, 1 @ load TTB1 |
| 202 | #ifdef CONFIG_VFP | 226 | #ifdef CONFIG_VFP |
| 203 | mrc p15, 0, r0, c1, c0, 2 | 227 | mrc p15, 0, r0, c1, c0, 2 |
diff --git a/arch/arm/nwfpe/fpa11.h b/arch/arm/nwfpe/fpa11.h index 9677ae8448e8..da4c616b6c49 100644 --- a/arch/arm/nwfpe/fpa11.h +++ b/arch/arm/nwfpe/fpa11.h | |||
| @@ -60,7 +60,7 @@ typedef union tagFPREG { | |||
| 60 | #ifdef CONFIG_FPE_NWFPE_XP | 60 | #ifdef CONFIG_FPE_NWFPE_XP |
| 61 | floatx80 fExtended; | 61 | floatx80 fExtended; |
| 62 | #else | 62 | #else |
| 63 | int padding[3]; | 63 | u32 padding[3]; |
| 64 | #endif | 64 | #endif |
| 65 | } FPREG; | 65 | } FPREG; |
| 66 | 66 | ||
diff --git a/arch/arm/nwfpe/fpa11_cpdt.c b/arch/arm/nwfpe/fpa11_cpdt.c index b0db5cbcc3b1..32859fa8dcfc 100644 --- a/arch/arm/nwfpe/fpa11_cpdt.c +++ b/arch/arm/nwfpe/fpa11_cpdt.c | |||
| @@ -59,8 +59,13 @@ static inline void loadExtended(const unsigned int Fn, const unsigned int __user | |||
| 59 | p = (unsigned int *) &fpa11->fpreg[Fn].fExtended; | 59 | p = (unsigned int *) &fpa11->fpreg[Fn].fExtended; |
| 60 | fpa11->fType[Fn] = typeExtended; | 60 | fpa11->fType[Fn] = typeExtended; |
| 61 | get_user(p[0], &pMem[0]); /* sign & exponent */ | 61 | get_user(p[0], &pMem[0]); /* sign & exponent */ |
| 62 | #ifdef __ARMEB__ | ||
| 63 | get_user(p[1], &pMem[1]); /* ms bits */ | ||
| 64 | get_user(p[2], &pMem[2]); /* ls bits */ | ||
| 65 | #else | ||
| 62 | get_user(p[1], &pMem[2]); /* ls bits */ | 66 | get_user(p[1], &pMem[2]); /* ls bits */ |
| 63 | get_user(p[2], &pMem[1]); /* ms bits */ | 67 | get_user(p[2], &pMem[1]); /* ms bits */ |
| 68 | #endif | ||
| 64 | } | 69 | } |
| 65 | #endif | 70 | #endif |
| 66 | 71 | ||
| @@ -177,8 +182,13 @@ static inline void storeExtended(const unsigned int Fn, unsigned int __user *pMe | |||
| 177 | } | 182 | } |
| 178 | 183 | ||
| 179 | put_user(val.i[0], &pMem[0]); /* sign & exp */ | 184 | put_user(val.i[0], &pMem[0]); /* sign & exp */ |
| 185 | #ifdef __ARMEB__ | ||
| 186 | put_user(val.i[1], &pMem[1]); /* msw */ | ||
| 187 | put_user(val.i[2], &pMem[2]); | ||
| 188 | #else | ||
| 180 | put_user(val.i[1], &pMem[2]); | 189 | put_user(val.i[1], &pMem[2]); |
| 181 | put_user(val.i[2], &pMem[1]); /* msw */ | 190 | put_user(val.i[2], &pMem[1]); /* msw */ |
| 191 | #endif | ||
| 182 | } | 192 | } |
| 183 | #endif | 193 | #endif |
| 184 | 194 | ||
diff --git a/arch/arm/nwfpe/fpopcode.c b/arch/arm/nwfpe/fpopcode.c index 4c9f5703148c..67ff2ab08ea0 100644 --- a/arch/arm/nwfpe/fpopcode.c +++ b/arch/arm/nwfpe/fpopcode.c | |||
| @@ -29,14 +29,14 @@ | |||
| 29 | 29 | ||
| 30 | #ifdef CONFIG_FPE_NWFPE_XP | 30 | #ifdef CONFIG_FPE_NWFPE_XP |
| 31 | const floatx80 floatx80Constant[] = { | 31 | const floatx80 floatx80Constant[] = { |
| 32 | {0x0000, 0x0000000000000000ULL}, /* extended 0.0 */ | 32 | { .high = 0x0000, .low = 0x0000000000000000ULL},/* extended 0.0 */ |
| 33 | {0x3fff, 0x8000000000000000ULL}, /* extended 1.0 */ | 33 | { .high = 0x3fff, .low = 0x8000000000000000ULL},/* extended 1.0 */ |
| 34 | {0x4000, 0x8000000000000000ULL}, /* extended 2.0 */ | 34 | { .high = 0x4000, .low = 0x8000000000000000ULL},/* extended 2.0 */ |
| 35 | {0x4000, 0xc000000000000000ULL}, /* extended 3.0 */ | 35 | { .high = 0x4000, .low = 0xc000000000000000ULL},/* extended 3.0 */ |
| 36 | {0x4001, 0x8000000000000000ULL}, /* extended 4.0 */ | 36 | { .high = 0x4001, .low = 0x8000000000000000ULL},/* extended 4.0 */ |
| 37 | {0x4001, 0xa000000000000000ULL}, /* extended 5.0 */ | 37 | { .high = 0x4001, .low = 0xa000000000000000ULL},/* extended 5.0 */ |
| 38 | {0x3ffe, 0x8000000000000000ULL}, /* extended 0.5 */ | 38 | { .high = 0x3ffe, .low = 0x8000000000000000ULL},/* extended 0.5 */ |
| 39 | {0x4002, 0xa000000000000000ULL} /* extended 10.0 */ | 39 | { .high = 0x4002, .low = 0xa000000000000000ULL},/* extended 10.0 */ |
| 40 | }; | 40 | }; |
| 41 | #endif | 41 | #endif |
| 42 | 42 | ||
diff --git a/arch/arm/nwfpe/softfloat-specialize b/arch/arm/nwfpe/softfloat-specialize index acf409144763..d4a4c8e06635 100644 --- a/arch/arm/nwfpe/softfloat-specialize +++ b/arch/arm/nwfpe/softfloat-specialize | |||
| @@ -332,6 +332,7 @@ static floatx80 commonNaNToFloatx80( commonNaNT a ) | |||
| 332 | 332 | ||
| 333 | z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); | 333 | z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); |
| 334 | z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; | 334 | z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; |
| 335 | z.__padding = 0; | ||
| 335 | return z; | 336 | return z; |
| 336 | 337 | ||
| 337 | } | 338 | } |
diff --git a/arch/arm/nwfpe/softfloat.c b/arch/arm/nwfpe/softfloat.c index f9f049132a17..0f9656e482ba 100644 --- a/arch/arm/nwfpe/softfloat.c +++ b/arch/arm/nwfpe/softfloat.c | |||
| @@ -531,6 +531,7 @@ INLINE floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig ) | |||
| 531 | 531 | ||
| 532 | z.low = zSig; | 532 | z.low = zSig; |
| 533 | z.high = ( ( (bits16) zSign )<<15 ) + zExp; | 533 | z.high = ( ( (bits16) zSign )<<15 ) + zExp; |
| 534 | z.__padding = 0; | ||
| 534 | return z; | 535 | return z; |
| 535 | 536 | ||
| 536 | } | 537 | } |
| @@ -2831,6 +2832,7 @@ static floatx80 subFloatx80Sigs( struct roundingData *roundData, floatx80 a, flo | |||
| 2831 | roundData->exception |= float_flag_invalid; | 2832 | roundData->exception |= float_flag_invalid; |
| 2832 | z.low = floatx80_default_nan_low; | 2833 | z.low = floatx80_default_nan_low; |
| 2833 | z.high = floatx80_default_nan_high; | 2834 | z.high = floatx80_default_nan_high; |
| 2835 | z.__padding = 0; | ||
| 2834 | return z; | 2836 | return z; |
| 2835 | } | 2837 | } |
| 2836 | if ( aExp == 0 ) { | 2838 | if ( aExp == 0 ) { |
| @@ -2950,6 +2952,7 @@ floatx80 floatx80_mul( struct roundingData *roundData, floatx80 a, floatx80 b ) | |||
| 2950 | roundData->exception |= float_flag_invalid; | 2952 | roundData->exception |= float_flag_invalid; |
| 2951 | z.low = floatx80_default_nan_low; | 2953 | z.low = floatx80_default_nan_low; |
| 2952 | z.high = floatx80_default_nan_high; | 2954 | z.high = floatx80_default_nan_high; |
| 2955 | z.__padding = 0; | ||
| 2953 | return z; | 2956 | return z; |
| 2954 | } | 2957 | } |
| 2955 | return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); | 2958 | return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) ); |
| @@ -3015,6 +3018,7 @@ floatx80 floatx80_div( struct roundingData *roundData, floatx80 a, floatx80 b ) | |||
| 3015 | roundData->exception |= float_flag_invalid; | 3018 | roundData->exception |= float_flag_invalid; |
| 3016 | z.low = floatx80_default_nan_low; | 3019 | z.low = floatx80_default_nan_low; |
| 3017 | z.high = floatx80_default_nan_high; | 3020 | z.high = floatx80_default_nan_high; |
| 3021 | z.__padding = 0; | ||
| 3018 | return z; | 3022 | return z; |
| 3019 | } | 3023 | } |
| 3020 | roundData->exception |= float_flag_divbyzero; | 3024 | roundData->exception |= float_flag_divbyzero; |
| @@ -3093,6 +3097,7 @@ floatx80 floatx80_rem( struct roundingData *roundData, floatx80 a, floatx80 b ) | |||
| 3093 | roundData->exception |= float_flag_invalid; | 3097 | roundData->exception |= float_flag_invalid; |
| 3094 | z.low = floatx80_default_nan_low; | 3098 | z.low = floatx80_default_nan_low; |
| 3095 | z.high = floatx80_default_nan_high; | 3099 | z.high = floatx80_default_nan_high; |
| 3100 | z.__padding = 0; | ||
| 3096 | return z; | 3101 | return z; |
| 3097 | } | 3102 | } |
| 3098 | normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); | 3103 | normalizeFloatx80Subnormal( bSig, &bExp, &bSig ); |
| @@ -3184,6 +3189,7 @@ floatx80 floatx80_sqrt( struct roundingData *roundData, floatx80 a ) | |||
| 3184 | roundData->exception |= float_flag_invalid; | 3189 | roundData->exception |= float_flag_invalid; |
| 3185 | z.low = floatx80_default_nan_low; | 3190 | z.low = floatx80_default_nan_low; |
| 3186 | z.high = floatx80_default_nan_high; | 3191 | z.high = floatx80_default_nan_high; |
| 3192 | z.__padding = 0; | ||
| 3187 | return z; | 3193 | return z; |
| 3188 | } | 3194 | } |
| 3189 | if ( aExp == 0 ) { | 3195 | if ( aExp == 0 ) { |
diff --git a/arch/arm/nwfpe/softfloat.h b/arch/arm/nwfpe/softfloat.h index 14151700b6b2..978c699673c6 100644 --- a/arch/arm/nwfpe/softfloat.h +++ b/arch/arm/nwfpe/softfloat.h | |||
| @@ -51,11 +51,17 @@ input or output the `floatx80' type will be defined. | |||
| 51 | Software IEC/IEEE floating-point types. | 51 | Software IEC/IEEE floating-point types. |
| 52 | ------------------------------------------------------------------------------- | 52 | ------------------------------------------------------------------------------- |
| 53 | */ | 53 | */ |
| 54 | typedef unsigned long int float32; | 54 | typedef u32 float32; |
| 55 | typedef unsigned long long float64; | 55 | typedef u64 float64; |
| 56 | typedef struct { | 56 | typedef struct { |
| 57 | unsigned short high; | 57 | #ifdef __ARMEB__ |
| 58 | unsigned long long low; | 58 | u16 __padding; |
| 59 | u16 high; | ||
| 60 | #else | ||
| 61 | u16 high; | ||
| 62 | u16 __padding; | ||
| 63 | #endif | ||
| 64 | u64 low; | ||
| 59 | } floatx80; | 65 | } floatx80; |
| 60 | 66 | ||
| 61 | /* | 67 | /* |
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c index caa9f7711343..871366b83b3f 100644 --- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | |||
| @@ -377,10 +377,9 @@ acpi_cpufreq_cpu_init ( | |||
| 377 | arg0.buffer.length = 12; | 377 | arg0.buffer.length = 12; |
| 378 | arg0.buffer.pointer = (u8 *) arg0_buf; | 378 | arg0.buffer.pointer = (u8 *) arg0_buf; |
| 379 | 379 | ||
| 380 | data = kmalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL); | 380 | data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL); |
| 381 | if (!data) | 381 | if (!data) |
| 382 | return (-ENOMEM); | 382 | return (-ENOMEM); |
| 383 | memset(data, 0, sizeof(struct cpufreq_acpi_io)); | ||
| 384 | 383 | ||
| 385 | acpi_io_data[cpu] = data; | 384 | acpi_io_data[cpu] = data; |
| 386 | 385 | ||
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c index 73a5dc5b26b8..edcd626001da 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c | |||
| @@ -171,10 +171,9 @@ static int get_ranges (unsigned char *pst) | |||
| 171 | unsigned int speed; | 171 | unsigned int speed; |
| 172 | u8 fid, vid; | 172 | u8 fid, vid; |
| 173 | 173 | ||
| 174 | powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL); | 174 | powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) * (number_scales + 1)), GFP_KERNEL); |
| 175 | if (!powernow_table) | 175 | if (!powernow_table) |
| 176 | return -ENOMEM; | 176 | return -ENOMEM; |
| 177 | memset(powernow_table, 0, (sizeof(struct cpufreq_frequency_table) * (number_scales + 1))); | ||
| 178 | 177 | ||
| 179 | for (j=0 ; j < number_scales; j++) { | 178 | for (j=0 ; j < number_scales; j++) { |
| 180 | fid = *pst++; | 179 | fid = *pst++; |
| @@ -305,16 +304,13 @@ static int powernow_acpi_init(void) | |||
| 305 | goto err0; | 304 | goto err0; |
| 306 | } | 305 | } |
| 307 | 306 | ||
| 308 | acpi_processor_perf = kmalloc(sizeof(struct acpi_processor_performance), | 307 | acpi_processor_perf = kzalloc(sizeof(struct acpi_processor_performance), |
| 309 | GFP_KERNEL); | 308 | GFP_KERNEL); |
| 310 | |||
| 311 | if (!acpi_processor_perf) { | 309 | if (!acpi_processor_perf) { |
| 312 | retval = -ENOMEM; | 310 | retval = -ENOMEM; |
| 313 | goto err0; | 311 | goto err0; |
| 314 | } | 312 | } |
| 315 | 313 | ||
| 316 | memset(acpi_processor_perf, 0, sizeof(struct acpi_processor_performance)); | ||
| 317 | |||
| 318 | if (acpi_processor_register_performance(acpi_processor_perf, 0)) { | 314 | if (acpi_processor_register_performance(acpi_processor_perf, 0)) { |
| 319 | retval = -EIO; | 315 | retval = -EIO; |
| 320 | goto err1; | 316 | goto err1; |
| @@ -337,14 +333,12 @@ static int powernow_acpi_init(void) | |||
| 337 | goto err2; | 333 | goto err2; |
| 338 | } | 334 | } |
| 339 | 335 | ||
| 340 | powernow_table = kmalloc((number_scales + 1) * (sizeof(struct cpufreq_frequency_table)), GFP_KERNEL); | 336 | powernow_table = kzalloc((number_scales + 1) * (sizeof(struct cpufreq_frequency_table)), GFP_KERNEL); |
| 341 | if (!powernow_table) { | 337 | if (!powernow_table) { |
| 342 | retval = -ENOMEM; | 338 | retval = -ENOMEM; |
| 343 | goto err2; | 339 | goto err2; |
| 344 | } | 340 | } |
| 345 | 341 | ||
| 346 | memset(powernow_table, 0, ((number_scales + 1) * sizeof(struct cpufreq_frequency_table))); | ||
| 347 | |||
| 348 | pc.val = (unsigned long) acpi_processor_perf->states[0].control; | 342 | pc.val = (unsigned long) acpi_processor_perf->states[0].control; |
| 349 | for (i = 0; i < number_scales; i++) { | 343 | for (i = 0; i < number_scales; i++) { |
| 350 | u8 fid, vid; | 344 | u8 fid, vid; |
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 2d5c9adba0cd..68a1fc87f4ca 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c | |||
| @@ -462,7 +462,6 @@ static int check_supported_cpu(unsigned int cpu) | |||
| 462 | 462 | ||
| 463 | oldmask = current->cpus_allowed; | 463 | oldmask = current->cpus_allowed; |
| 464 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | 464 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); |
| 465 | schedule(); | ||
| 466 | 465 | ||
| 467 | if (smp_processor_id() != cpu) { | 466 | if (smp_processor_id() != cpu) { |
| 468 | printk(KERN_ERR "limiting to cpu %u failed\n", cpu); | 467 | printk(KERN_ERR "limiting to cpu %u failed\n", cpu); |
| @@ -497,9 +496,7 @@ static int check_supported_cpu(unsigned int cpu) | |||
| 497 | 496 | ||
| 498 | out: | 497 | out: |
| 499 | set_cpus_allowed(current, oldmask); | 498 | set_cpus_allowed(current, oldmask); |
| 500 | schedule(); | ||
| 501 | return rc; | 499 | return rc; |
| 502 | |||
| 503 | } | 500 | } |
| 504 | 501 | ||
| 505 | static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8 maxvid) | 502 | static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8 maxvid) |
| @@ -913,7 +910,6 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
| 913 | /* only run on specific CPU from here on */ | 910 | /* only run on specific CPU from here on */ |
| 914 | oldmask = current->cpus_allowed; | 911 | oldmask = current->cpus_allowed; |
| 915 | set_cpus_allowed(current, cpumask_of_cpu(pol->cpu)); | 912 | set_cpus_allowed(current, cpumask_of_cpu(pol->cpu)); |
| 916 | schedule(); | ||
| 917 | 913 | ||
| 918 | if (smp_processor_id() != pol->cpu) { | 914 | if (smp_processor_id() != pol->cpu) { |
| 919 | printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu); | 915 | printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu); |
| @@ -968,8 +964,6 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
| 968 | 964 | ||
| 969 | err_out: | 965 | err_out: |
| 970 | set_cpus_allowed(current, oldmask); | 966 | set_cpus_allowed(current, oldmask); |
| 971 | schedule(); | ||
| 972 | |||
| 973 | return ret; | 967 | return ret; |
| 974 | } | 968 | } |
| 975 | 969 | ||
| @@ -991,12 +985,11 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
| 991 | if (!check_supported_cpu(pol->cpu)) | 985 | if (!check_supported_cpu(pol->cpu)) |
| 992 | return -ENODEV; | 986 | return -ENODEV; |
| 993 | 987 | ||
| 994 | data = kmalloc(sizeof(struct powernow_k8_data), GFP_KERNEL); | 988 | data = kzalloc(sizeof(struct powernow_k8_data), GFP_KERNEL); |
| 995 | if (!data) { | 989 | if (!data) { |
| 996 | printk(KERN_ERR PFX "unable to alloc powernow_k8_data"); | 990 | printk(KERN_ERR PFX "unable to alloc powernow_k8_data"); |
| 997 | return -ENOMEM; | 991 | return -ENOMEM; |
| 998 | } | 992 | } |
| 999 | memset(data,0,sizeof(struct powernow_k8_data)); | ||
| 1000 | 993 | ||
| 1001 | data->cpu = pol->cpu; | 994 | data->cpu = pol->cpu; |
| 1002 | 995 | ||
| @@ -1026,7 +1019,6 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
| 1026 | /* only run on specific CPU from here on */ | 1019 | /* only run on specific CPU from here on */ |
| 1027 | oldmask = current->cpus_allowed; | 1020 | oldmask = current->cpus_allowed; |
| 1028 | set_cpus_allowed(current, cpumask_of_cpu(pol->cpu)); | 1021 | set_cpus_allowed(current, cpumask_of_cpu(pol->cpu)); |
| 1029 | schedule(); | ||
| 1030 | 1022 | ||
| 1031 | if (smp_processor_id() != pol->cpu) { | 1023 | if (smp_processor_id() != pol->cpu) { |
| 1032 | printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu); | 1024 | printk(KERN_ERR "limiting to cpu %u failed\n", pol->cpu); |
| @@ -1045,7 +1037,6 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
| 1045 | 1037 | ||
| 1046 | /* run on any CPU again */ | 1038 | /* run on any CPU again */ |
| 1047 | set_cpus_allowed(current, oldmask); | 1039 | set_cpus_allowed(current, oldmask); |
| 1048 | schedule(); | ||
| 1049 | 1040 | ||
| 1050 | pol->governor = CPUFREQ_DEFAULT_GOVERNOR; | 1041 | pol->governor = CPUFREQ_DEFAULT_GOVERNOR; |
| 1051 | pol->cpus = cpu_core_map[pol->cpu]; | 1042 | pol->cpus = cpu_core_map[pol->cpu]; |
| @@ -1080,7 +1071,6 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
| 1080 | 1071 | ||
| 1081 | err_out: | 1072 | err_out: |
| 1082 | set_cpus_allowed(current, oldmask); | 1073 | set_cpus_allowed(current, oldmask); |
| 1083 | schedule(); | ||
| 1084 | powernow_k8_cpu_exit_acpi(data); | 1074 | powernow_k8_cpu_exit_acpi(data); |
| 1085 | 1075 | ||
| 1086 | kfree(data); | 1076 | kfree(data); |
| @@ -1116,17 +1106,14 @@ static unsigned int powernowk8_get (unsigned int cpu) | |||
| 1116 | set_cpus_allowed(current, oldmask); | 1106 | set_cpus_allowed(current, oldmask); |
| 1117 | return 0; | 1107 | return 0; |
| 1118 | } | 1108 | } |
| 1119 | preempt_disable(); | 1109 | |
| 1120 | |||
| 1121 | if (query_current_values_with_pending_wait(data)) | 1110 | if (query_current_values_with_pending_wait(data)) |
| 1122 | goto out; | 1111 | goto out; |
| 1123 | 1112 | ||
| 1124 | khz = find_khz_freq_from_fid(data->currfid); | 1113 | khz = find_khz_freq_from_fid(data->currfid); |
| 1125 | 1114 | ||
| 1126 | out: | 1115 | out: |
| 1127 | preempt_enable_no_resched(); | ||
| 1128 | set_cpus_allowed(current, oldmask); | 1116 | set_cpus_allowed(current, oldmask); |
| 1129 | |||
| 1130 | return khz; | 1117 | return khz; |
| 1131 | } | 1118 | } |
| 1132 | 1119 | ||
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c index 0ea010a7afb1..edb9873e27e3 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c | |||
| @@ -423,12 +423,11 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy) | |||
| 423 | } | 423 | } |
| 424 | } | 424 | } |
| 425 | 425 | ||
| 426 | centrino_model[cpu] = kmalloc(sizeof(struct cpu_model), GFP_KERNEL); | 426 | centrino_model[cpu] = kzalloc(sizeof(struct cpu_model), GFP_KERNEL); |
| 427 | if (!centrino_model[cpu]) { | 427 | if (!centrino_model[cpu]) { |
| 428 | result = -ENOMEM; | 428 | result = -ENOMEM; |
| 429 | goto err_unreg; | 429 | goto err_unreg; |
| 430 | } | 430 | } |
| 431 | memset(centrino_model[cpu], 0, sizeof(struct cpu_model)); | ||
| 432 | 431 | ||
| 433 | centrino_model[cpu]->model_name=NULL; | 432 | centrino_model[cpu]->model_name=NULL; |
| 434 | centrino_model[cpu]->max_freq = p.states[0].core_frequency * 1000; | 433 | centrino_model[cpu]->max_freq = p.states[0].core_frequency * 1000; |
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 9f2093c1f44b..d4de8a4814be 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
| @@ -191,6 +191,7 @@ config IOSAPIC | |||
| 191 | 191 | ||
| 192 | config IA64_SGI_SN_XP | 192 | config IA64_SGI_SN_XP |
| 193 | tristate "Support communication between SGI SSIs" | 193 | tristate "Support communication between SGI SSIs" |
| 194 | depends on IA64_GENERIC || IA64_SGI_SN2 | ||
| 194 | select IA64_UNCACHED_ALLOCATOR | 195 | select IA64_UNCACHED_ALLOCATOR |
| 195 | help | 196 | help |
| 196 | An SGI machine can be divided into multiple Single System | 197 | An SGI machine can be divided into multiple Single System |
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 6537445dac0e..3cfb8be3ff6d 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig | |||
| @@ -201,6 +201,14 @@ config SUN_OPENPROMFS | |||
| 201 | Only choose N if you know in advance that you will not need to modify | 201 | Only choose N if you know in advance that you will not need to modify |
| 202 | OpenPROM settings on the running system. | 202 | OpenPROM settings on the running system. |
| 203 | 203 | ||
| 204 | config SPARC_LED | ||
| 205 | tristate "Sun4m LED driver" | ||
| 206 | help | ||
| 207 | This driver toggles the front-panel LED on sun4m systems | ||
| 208 | in a user-specifyable manner. It's state can be probed | ||
| 209 | by reading /proc/led and it's blinking mode can be changed | ||
| 210 | via writes to /proc/led | ||
| 211 | |||
| 204 | source "fs/Kconfig.binfmt" | 212 | source "fs/Kconfig.binfmt" |
| 205 | 213 | ||
| 206 | config SUNOS_EMUL | 214 | config SUNOS_EMUL |
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index 3d22ba2af01c..1b83e21841b5 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile | |||
| @@ -21,6 +21,7 @@ obj-$(CONFIG_SUN_AUXIO) += auxio.o | |||
| 21 | obj-$(CONFIG_PCI) += ebus.o | 21 | obj-$(CONFIG_PCI) += ebus.o |
| 22 | obj-$(CONFIG_SUN_PM) += apc.o pmc.o | 22 | obj-$(CONFIG_SUN_PM) += apc.o pmc.o |
| 23 | obj-$(CONFIG_MODULES) += module.o sparc_ksyms.o | 23 | obj-$(CONFIG_MODULES) += module.o sparc_ksyms.o |
| 24 | obj-$(CONFIG_SPARC_LED) += led.o | ||
| 24 | 25 | ||
| 25 | ifdef CONFIG_SUNOS_EMUL | 26 | ifdef CONFIG_SUNOS_EMUL |
| 26 | obj-y += sys_sunos.o sunos_ioctl.o | 27 | obj-y += sys_sunos.o sunos_ioctl.o |
diff --git a/arch/sparc/kernel/led.c b/arch/sparc/kernel/led.c new file mode 100644 index 000000000000..2a3afca453c9 --- /dev/null +++ b/arch/sparc/kernel/led.c | |||
| @@ -0,0 +1,139 @@ | |||
| 1 | #include <linux/kernel.h> | ||
| 2 | #include <linux/module.h> | ||
| 3 | #include <linux/init.h> | ||
| 4 | #include <linux/proc_fs.h> | ||
| 5 | #include <linux/string.h> | ||
| 6 | |||
| 7 | #include <asm/auxio.h> | ||
| 8 | |||
| 9 | #define LED_MAX_LENGTH 8 /* maximum chars written to proc file */ | ||
| 10 | |||
| 11 | static inline void led_toggle(void) | ||
| 12 | { | ||
| 13 | unsigned char val = get_auxio(); | ||
| 14 | unsigned char on, off; | ||
| 15 | |||
| 16 | if (val & AUXIO_LED) { | ||
| 17 | on = 0; | ||
| 18 | off = AUXIO_LED; | ||
| 19 | } else { | ||
| 20 | on = AUXIO_LED; | ||
| 21 | off = 0; | ||
| 22 | } | ||
| 23 | |||
| 24 | set_auxio(on, off); | ||
| 25 | } | ||
| 26 | |||
| 27 | static struct timer_list led_blink_timer; | ||
| 28 | |||
| 29 | static void led_blink(unsigned long timeout) | ||
| 30 | { | ||
| 31 | led_toggle(); | ||
| 32 | |||
| 33 | /* reschedule */ | ||
| 34 | if (!timeout) { /* blink according to load */ | ||
| 35 | led_blink_timer.expires = jiffies + | ||
| 36 | ((1 + (avenrun[0] >> FSHIFT)) * HZ); | ||
| 37 | led_blink_timer.data = 0; | ||
| 38 | } else { /* blink at user specified interval */ | ||
| 39 | led_blink_timer.expires = jiffies + (timeout * HZ); | ||
| 40 | led_blink_timer.data = timeout; | ||
| 41 | } | ||
| 42 | add_timer(&led_blink_timer); | ||
| 43 | } | ||
| 44 | |||
| 45 | static int led_read_proc(char *buf, char **start, off_t offset, int count, | ||
| 46 | int *eof, void *data) | ||
| 47 | { | ||
| 48 | int len = 0; | ||
| 49 | |||
| 50 | if (get_auxio() & AUXIO_LED) | ||
| 51 | len = sprintf(buf, "on\n"); | ||
| 52 | else | ||
| 53 | len = sprintf(buf, "off\n"); | ||
| 54 | |||
| 55 | return len; | ||
| 56 | } | ||
| 57 | |||
| 58 | static int led_write_proc(struct file *file, const char *buffer, | ||
| 59 | unsigned long count, void *data) | ||
| 60 | { | ||
| 61 | char *buf = NULL; | ||
| 62 | |||
| 63 | if (count > LED_MAX_LENGTH) | ||
| 64 | count = LED_MAX_LENGTH; | ||
| 65 | |||
| 66 | buf = kmalloc(sizeof(char) * (count + 1), GFP_KERNEL); | ||
| 67 | if (!buf) | ||
| 68 | return -ENOMEM; | ||
| 69 | |||
| 70 | if (copy_from_user(buf, buffer, count)) { | ||
| 71 | kfree(buf); | ||
| 72 | return -EFAULT; | ||
| 73 | } | ||
| 74 | |||
| 75 | buf[count] = '\0'; | ||
| 76 | |||
| 77 | /* work around \n when echo'ing into proc */ | ||
| 78 | if (buf[count - 1] == '\n') | ||
| 79 | buf[count - 1] = '\0'; | ||
| 80 | |||
| 81 | /* before we change anything we want to stop any running timers, | ||
| 82 | * otherwise calls such as on will have no persistent effect | ||
| 83 | */ | ||
| 84 | del_timer_sync(&led_blink_timer); | ||
| 85 | |||
| 86 | if (!strcmp(buf, "on")) { | ||
| 87 | auxio_set_led(AUXIO_LED_ON); | ||
| 88 | } else if (!strcmp(buf, "toggle")) { | ||
| 89 | led_toggle(); | ||
| 90 | } else if ((*buf > '0') && (*buf <= '9')) { | ||
| 91 | led_blink(simple_strtoul(buf, NULL, 10)); | ||
| 92 | } else if (!strcmp(buf, "load")) { | ||
| 93 | led_blink(0); | ||
| 94 | } else { | ||
| 95 | auxio_set_led(AUXIO_LED_OFF); | ||
| 96 | } | ||
| 97 | |||
| 98 | kfree(buf); | ||
| 99 | |||
| 100 | return count; | ||
| 101 | } | ||
| 102 | |||
| 103 | static struct proc_dir_entry *led; | ||
| 104 | |||
| 105 | #define LED_VERSION "0.1" | ||
| 106 | |||
| 107 | static int __init led_init(void) | ||
| 108 | { | ||
| 109 | init_timer(&led_blink_timer); | ||
| 110 | led_blink_timer.function = led_blink; | ||
| 111 | |||
| 112 | led = create_proc_entry("led", 0, NULL); | ||
| 113 | if (!led) | ||
| 114 | return -ENOMEM; | ||
| 115 | |||
| 116 | led->read_proc = led_read_proc; /* reader function */ | ||
| 117 | led->write_proc = led_write_proc; /* writer function */ | ||
| 118 | led->owner = THIS_MODULE; | ||
| 119 | |||
| 120 | printk(KERN_INFO | ||
| 121 | "led: version %s, Lars Kotthoff <metalhead@metalhead.ws>\n", | ||
| 122 | LED_VERSION); | ||
| 123 | |||
| 124 | return 0; | ||
| 125 | } | ||
| 126 | |||
| 127 | static void __exit led_exit(void) | ||
| 128 | { | ||
| 129 | remove_proc_entry("led", NULL); | ||
| 130 | del_timer_sync(&led_blink_timer); | ||
| 131 | } | ||
| 132 | |||
| 133 | module_init(led_init); | ||
| 134 | module_exit(led_exit); | ||
| 135 | |||
| 136 | MODULE_AUTHOR("Lars Kotthoff <metalhead@metalhead.ws>"); | ||
| 137 | MODULE_DESCRIPTION("Provides control of the front LED on SPARC systems."); | ||
| 138 | MODULE_LICENSE("GPL"); | ||
| 139 | MODULE_VERSION(LED_VERSION); | ||
diff --git a/arch/sparc/kernel/sunos_ioctl.c b/arch/sparc/kernel/sunos_ioctl.c index df1c0b31a930..a6ba3d26222c 100644 --- a/arch/sparc/kernel/sunos_ioctl.c +++ b/arch/sparc/kernel/sunos_ioctl.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include <linux/smp_lock.h> | 23 | #include <linux/smp_lock.h> |
| 24 | #include <linux/syscalls.h> | 24 | #include <linux/syscalls.h> |
| 25 | #include <linux/file.h> | 25 | #include <linux/file.h> |
| 26 | #include <asm/kbio.h> | ||
| 27 | 26 | ||
| 28 | #if 0 | 27 | #if 0 |
| 29 | extern char sunkbd_type; | 28 | extern char sunkbd_type; |
diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c index e6a00325075a..92e26304de90 100644 --- a/arch/sparc64/kernel/ioctl32.c +++ b/arch/sparc64/kernel/ioctl32.c | |||
| @@ -11,33 +11,14 @@ | |||
| 11 | 11 | ||
| 12 | #define INCLUDES | 12 | #define INCLUDES |
| 13 | #include "compat_ioctl.c" | 13 | #include "compat_ioctl.c" |
| 14 | #include <linux/ncp_fs.h> | ||
| 15 | #include <linux/syscalls.h> | 14 | #include <linux/syscalls.h> |
| 16 | #include <asm/fbio.h> | 15 | #include <asm/fbio.h> |
| 17 | #include <asm/kbio.h> | ||
| 18 | #include <asm/vuid_event.h> | ||
| 19 | #include <asm/envctrl.h> | ||
| 20 | #include <asm/display7seg.h> | ||
| 21 | #include <asm/openpromio.h> | ||
| 22 | #include <asm/audioio.h> | ||
| 23 | #include <asm/watchdog.h> | ||
| 24 | 16 | ||
| 25 | /* Use this to get at 32-bit user passed pointers. | 17 | /* Use this to get at 32-bit user passed pointers. |
| 26 | * See sys_sparc32.c for description about it. | 18 | * See sys_sparc32.c for description about it. |
| 27 | */ | 19 | */ |
| 28 | #define A(__x) compat_ptr(__x) | 20 | #define A(__x) compat_ptr(__x) |
| 29 | 21 | ||
| 30 | static __inline__ void *alloc_user_space(long len) | ||
| 31 | { | ||
| 32 | struct pt_regs *regs = current_thread_info()->kregs; | ||
| 33 | unsigned long usp = regs->u_regs[UREG_I6]; | ||
| 34 | |||
| 35 | if (!(test_thread_flag(TIF_32BIT))) | ||
| 36 | usp += STACK_BIAS; | ||
| 37 | |||
| 38 | return (void *) (usp - len); | ||
| 39 | } | ||
| 40 | |||
| 41 | #define CODE | 22 | #define CODE |
| 42 | #include "compat_ioctl.c" | 23 | #include "compat_ioctl.c" |
| 43 | 24 | ||
| @@ -111,357 +92,6 @@ static int fbiogscursor(unsigned int fd, unsigned int cmd, unsigned long arg) | |||
| 111 | return sys_ioctl (fd, FBIOSCURSOR, (unsigned long)p); | 92 | return sys_ioctl (fd, FBIOSCURSOR, (unsigned long)p); |
| 112 | } | 93 | } |
| 113 | 94 | ||
| 114 | #if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE) | ||
| 115 | /* This really belongs in include/linux/drm.h -DaveM */ | ||
| 116 | #include "../../../drivers/char/drm/drm.h" | ||
| 117 | |||
| 118 | typedef struct drm32_version { | ||
| 119 | int version_major; /* Major version */ | ||
| 120 | int version_minor; /* Minor version */ | ||
| 121 | int version_patchlevel;/* Patch level */ | ||
| 122 | int name_len; /* Length of name buffer */ | ||
| 123 | u32 name; /* Name of driver */ | ||
| 124 | int date_len; /* Length of date buffer */ | ||
| 125 | u32 date; /* User-space buffer to hold date */ | ||
| 126 | int desc_len; /* Length of desc buffer */ | ||
| 127 | u32 desc; /* User-space buffer to hold desc */ | ||
| 128 | } drm32_version_t; | ||
| 129 | #define DRM32_IOCTL_VERSION DRM_IOWR(0x00, drm32_version_t) | ||
| 130 | |||
| 131 | static int drm32_version(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
| 132 | { | ||
| 133 | drm32_version_t __user *uversion = (drm32_version_t __user *)arg; | ||
| 134 | drm_version_t __user *p = compat_alloc_user_space(sizeof(*p)); | ||
| 135 | compat_uptr_t addr; | ||
| 136 | int n; | ||
| 137 | int ret; | ||
| 138 | |||
| 139 | if (clear_user(p, 3 * sizeof(int)) || | ||
| 140 | get_user(n, &uversion->name_len) || | ||
| 141 | put_user(n, &p->name_len) || | ||
| 142 | get_user(addr, &uversion->name) || | ||
| 143 | put_user(compat_ptr(addr), &p->name) || | ||
| 144 | get_user(n, &uversion->date_len) || | ||
| 145 | put_user(n, &p->date_len) || | ||
| 146 | get_user(addr, &uversion->date) || | ||
| 147 | put_user(compat_ptr(addr), &p->date) || | ||
| 148 | get_user(n, &uversion->desc_len) || | ||
| 149 | put_user(n, &p->desc_len) || | ||
| 150 | get_user(addr, &uversion->desc) || | ||
| 151 | put_user(compat_ptr(addr), &p->desc)) | ||
| 152 | return -EFAULT; | ||
| 153 | |||
| 154 | ret = sys_ioctl(fd, DRM_IOCTL_VERSION, (unsigned long)p); | ||
| 155 | if (ret) | ||
| 156 | return ret; | ||
| 157 | |||
| 158 | if (copy_in_user(uversion, p, 3 * sizeof(int)) || | ||
| 159 | get_user(n, &p->name_len) || | ||
| 160 | put_user(n, &uversion->name_len) || | ||
| 161 | get_user(n, &p->date_len) || | ||
| 162 | put_user(n, &uversion->date_len) || | ||
| 163 | get_user(n, &p->desc_len) || | ||
| 164 | put_user(n, &uversion->desc_len)) | ||
| 165 | return -EFAULT; | ||
| 166 | |||
| 167 | return 0; | ||
| 168 | } | ||
| 169 | |||
| 170 | typedef struct drm32_unique { | ||
| 171 | int unique_len; /* Length of unique */ | ||
| 172 | u32 unique; /* Unique name for driver instantiation */ | ||
| 173 | } drm32_unique_t; | ||
| 174 | #define DRM32_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm32_unique_t) | ||
| 175 | #define DRM32_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm32_unique_t) | ||
| 176 | |||
| 177 | static int drm32_getsetunique(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
| 178 | { | ||
| 179 | drm32_unique_t __user *uarg = (drm32_unique_t __user *)arg; | ||
| 180 | drm_unique_t __user *p = compat_alloc_user_space(sizeof(*p)); | ||
| 181 | compat_uptr_t addr; | ||
| 182 | int n; | ||
| 183 | int ret; | ||
| 184 | |||
| 185 | if (get_user(n, &uarg->unique_len) || | ||
| 186 | put_user(n, &p->unique_len) || | ||
| 187 | get_user(addr, &uarg->unique) || | ||
| 188 | put_user(compat_ptr(addr), &p->unique)) | ||
| 189 | return -EFAULT; | ||
| 190 | |||
| 191 | if (cmd == DRM32_IOCTL_GET_UNIQUE) | ||
| 192 | ret = sys_ioctl (fd, DRM_IOCTL_GET_UNIQUE, (unsigned long)p); | ||
| 193 | else | ||
| 194 | ret = sys_ioctl (fd, DRM_IOCTL_SET_UNIQUE, (unsigned long)p); | ||
| 195 | |||
| 196 | if (ret) | ||
| 197 | return ret; | ||
| 198 | |||
| 199 | if (get_user(n, &p->unique_len) || put_user(n, &uarg->unique_len)) | ||
| 200 | return -EFAULT; | ||
| 201 | |||
| 202 | return 0; | ||
| 203 | } | ||
| 204 | |||
| 205 | typedef struct drm32_map { | ||
| 206 | u32 offset; /* Requested physical address (0 for SAREA)*/ | ||
| 207 | u32 size; /* Requested physical size (bytes) */ | ||
| 208 | drm_map_type_t type; /* Type of memory to map */ | ||
| 209 | drm_map_flags_t flags; /* Flags */ | ||
| 210 | u32 handle; /* User-space: "Handle" to pass to mmap */ | ||
| 211 | /* Kernel-space: kernel-virtual address */ | ||
| 212 | int mtrr; /* MTRR slot used */ | ||
| 213 | /* Private data */ | ||
| 214 | } drm32_map_t; | ||
| 215 | #define DRM32_IOCTL_ADD_MAP DRM_IOWR(0x15, drm32_map_t) | ||
| 216 | |||
| 217 | static int drm32_addmap(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
| 218 | { | ||
| 219 | drm32_map_t __user *uarg = (drm32_map_t __user *) arg; | ||
| 220 | drm_map_t karg; | ||
| 221 | mm_segment_t old_fs; | ||
| 222 | u32 tmp; | ||
| 223 | int ret; | ||
| 224 | |||
| 225 | ret = get_user(karg.offset, &uarg->offset); | ||
| 226 | ret |= get_user(karg.size, &uarg->size); | ||
| 227 | ret |= get_user(karg.type, &uarg->type); | ||
| 228 | ret |= get_user(karg.flags, &uarg->flags); | ||
| 229 | ret |= get_user(tmp, &uarg->handle); | ||
| 230 | ret |= get_user(karg.mtrr, &uarg->mtrr); | ||
| 231 | if (ret) | ||
| 232 | return -EFAULT; | ||
| 233 | |||
| 234 | karg.handle = (void *) (unsigned long) tmp; | ||
| 235 | |||
| 236 | old_fs = get_fs(); | ||
| 237 | set_fs(KERNEL_DS); | ||
| 238 | ret = sys_ioctl(fd, DRM_IOCTL_ADD_MAP, (unsigned long) &karg); | ||
| 239 | set_fs(old_fs); | ||
| 240 | |||
| 241 | if (!ret) { | ||
| 242 | ret = put_user(karg.offset, &uarg->offset); | ||
| 243 | ret |= put_user(karg.size, &uarg->size); | ||
| 244 | ret |= put_user(karg.type, &uarg->type); | ||
| 245 | ret |= put_user(karg.flags, &uarg->flags); | ||
| 246 | tmp = (u32) (long)karg.handle; | ||
| 247 | ret |= put_user(tmp, &uarg->handle); | ||
| 248 | ret |= put_user(karg.mtrr, &uarg->mtrr); | ||
| 249 | if (ret) | ||
| 250 | ret = -EFAULT; | ||
| 251 | } | ||
| 252 | |||
| 253 | return ret; | ||
| 254 | } | ||
| 255 | |||
| 256 | typedef struct drm32_buf_info { | ||
| 257 | int count; /* Entries in list */ | ||
| 258 | u32 list; /* (drm_buf_desc_t *) */ | ||
| 259 | } drm32_buf_info_t; | ||
| 260 | #define DRM32_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm32_buf_info_t) | ||
| 261 | |||
| 262 | static int drm32_info_bufs(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
| 263 | { | ||
| 264 | drm32_buf_info_t __user *uarg = (drm32_buf_info_t __user *)arg; | ||
| 265 | drm_buf_info_t __user *p = compat_alloc_user_space(sizeof(*p)); | ||
| 266 | compat_uptr_t addr; | ||
| 267 | int n; | ||
| 268 | int ret; | ||
| 269 | |||
| 270 | if (get_user(n, &uarg->count) || put_user(n, &p->count) || | ||
| 271 | get_user(addr, &uarg->list) || put_user(compat_ptr(addr), &p->list)) | ||
| 272 | return -EFAULT; | ||
| 273 | |||
| 274 | ret = sys_ioctl(fd, DRM_IOCTL_INFO_BUFS, (unsigned long)p); | ||
| 275 | if (ret) | ||
| 276 | return ret; | ||
| 277 | |||
| 278 | if (get_user(n, &p->count) || put_user(n, &uarg->count)) | ||
| 279 | return -EFAULT; | ||
| 280 | |||
| 281 | return 0; | ||
| 282 | } | ||
| 283 | |||
| 284 | typedef struct drm32_buf_free { | ||
| 285 | int count; | ||
| 286 | u32 list; /* (int *) */ | ||
| 287 | } drm32_buf_free_t; | ||
| 288 | #define DRM32_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm32_buf_free_t) | ||
| 289 | |||
| 290 | static int drm32_free_bufs(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
| 291 | { | ||
| 292 | drm32_buf_free_t __user *uarg = (drm32_buf_free_t __user *)arg; | ||
| 293 | drm_buf_free_t __user *p = compat_alloc_user_space(sizeof(*p)); | ||
| 294 | compat_uptr_t addr; | ||
| 295 | int n; | ||
| 296 | |||
| 297 | if (get_user(n, &uarg->count) || put_user(n, &p->count) || | ||
| 298 | get_user(addr, &uarg->list) || put_user(compat_ptr(addr), &p->list)) | ||
| 299 | return -EFAULT; | ||
| 300 | |||
| 301 | return sys_ioctl(fd, DRM_IOCTL_FREE_BUFS, (unsigned long)p); | ||
| 302 | } | ||
| 303 | |||
| 304 | typedef struct drm32_buf_pub { | ||
| 305 | int idx; /* Index into master buflist */ | ||
| 306 | int total; /* Buffer size */ | ||
| 307 | int used; /* Amount of buffer in use (for DMA) */ | ||
| 308 | u32 address; /* Address of buffer (void *) */ | ||
| 309 | } drm32_buf_pub_t; | ||
| 310 | |||
| 311 | typedef struct drm32_buf_map { | ||
| 312 | int count; /* Length of buflist */ | ||
| 313 | u32 virtual; /* Mmaped area in user-virtual (void *) */ | ||
| 314 | u32 list; /* Buffer information (drm_buf_pub_t *) */ | ||
| 315 | } drm32_buf_map_t; | ||
| 316 | #define DRM32_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm32_buf_map_t) | ||
| 317 | |||
| 318 | static int drm32_map_bufs(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
| 319 | { | ||
| 320 | drm32_buf_map_t __user *uarg = (drm32_buf_map_t __user *)arg; | ||
| 321 | drm32_buf_pub_t __user *ulist; | ||
| 322 | drm_buf_map_t __user *arg64; | ||
| 323 | drm_buf_pub_t __user *list; | ||
| 324 | int orig_count, ret, i; | ||
| 325 | int n; | ||
| 326 | compat_uptr_t addr; | ||
| 327 | |||
| 328 | if (get_user(orig_count, &uarg->count)) | ||
| 329 | return -EFAULT; | ||
| 330 | |||
| 331 | arg64 = compat_alloc_user_space(sizeof(drm_buf_map_t) + | ||
| 332 | (size_t)orig_count * sizeof(drm_buf_pub_t)); | ||
| 333 | list = (void __user *)(arg64 + 1); | ||
| 334 | |||
| 335 | if (put_user(orig_count, &arg64->count) || | ||
| 336 | put_user(list, &arg64->list) || | ||
| 337 | get_user(addr, &uarg->virtual) || | ||
| 338 | put_user(compat_ptr(addr), &arg64->virtual) || | ||
| 339 | get_user(addr, &uarg->list)) | ||
| 340 | return -EFAULT; | ||
| 341 | |||
| 342 | ulist = compat_ptr(addr); | ||
| 343 | |||
| 344 | for (i = 0; i < orig_count; i++) { | ||
| 345 | if (get_user(n, &ulist[i].idx) || | ||
| 346 | put_user(n, &list[i].idx) || | ||
| 347 | get_user(n, &ulist[i].total) || | ||
| 348 | put_user(n, &list[i].total) || | ||
| 349 | get_user(n, &ulist[i].used) || | ||
| 350 | put_user(n, &list[i].used) || | ||
| 351 | get_user(addr, &ulist[i].address) || | ||
| 352 | put_user(compat_ptr(addr), &list[i].address)) | ||
| 353 | return -EFAULT; | ||
| 354 | } | ||
| 355 | |||
| 356 | ret = sys_ioctl(fd, DRM_IOCTL_MAP_BUFS, (unsigned long) arg64); | ||
| 357 | if (ret) | ||
| 358 | return ret; | ||
| 359 | |||
| 360 | for (i = 0; i < orig_count; i++) { | ||
| 361 | void __user *p; | ||
| 362 | if (get_user(n, &list[i].idx) || | ||
| 363 | put_user(n, &ulist[i].idx) || | ||
| 364 | get_user(n, &list[i].total) || | ||
| 365 | put_user(n, &ulist[i].total) || | ||
| 366 | get_user(n, &list[i].used) || | ||
| 367 | put_user(n, &ulist[i].used) || | ||
| 368 | get_user(p, &list[i].address) || | ||
| 369 | put_user((unsigned long)p, &ulist[i].address)) | ||
| 370 | return -EFAULT; | ||
| 371 | } | ||
| 372 | |||
| 373 | if (get_user(n, &arg64->count) || put_user(n, &uarg->count)) | ||
| 374 | return -EFAULT; | ||
| 375 | |||
| 376 | return 0; | ||
| 377 | } | ||
| 378 | |||
| 379 | typedef struct drm32_dma { | ||
| 380 | /* Indices here refer to the offset into | ||
| 381 | buflist in drm_buf_get_t. */ | ||
| 382 | int context; /* Context handle */ | ||
| 383 | int send_count; /* Number of buffers to send */ | ||
| 384 | u32 send_indices; /* List of handles to buffers (int *) */ | ||
| 385 | u32 send_sizes; /* Lengths of data to send (int *) */ | ||
| 386 | drm_dma_flags_t flags; /* Flags */ | ||
| 387 | int request_count; /* Number of buffers requested */ | ||
| 388 | int request_size; /* Desired size for buffers */ | ||
| 389 | u32 request_indices; /* Buffer information (int *) */ | ||
| 390 | u32 request_sizes; /* (int *) */ | ||
| 391 | int granted_count; /* Number of buffers granted */ | ||
| 392 | } drm32_dma_t; | ||
| 393 | #define DRM32_IOCTL_DMA DRM_IOWR(0x29, drm32_dma_t) | ||
| 394 | |||
| 395 | /* RED PEN The DRM layer blindly dereferences the send/request | ||
| 396 | * index/size arrays even though they are userland | ||
| 397 | * pointers. -DaveM | ||
| 398 | */ | ||
| 399 | static int drm32_dma(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
| 400 | { | ||
| 401 | drm32_dma_t __user *uarg = (drm32_dma_t __user *) arg; | ||
| 402 | drm_dma_t __user *p = compat_alloc_user_space(sizeof(*p)); | ||
| 403 | compat_uptr_t addr; | ||
| 404 | int ret; | ||
| 405 | |||
| 406 | if (copy_in_user(p, uarg, 2 * sizeof(int)) || | ||
| 407 | get_user(addr, &uarg->send_indices) || | ||
| 408 | put_user(compat_ptr(addr), &p->send_indices) || | ||
| 409 | get_user(addr, &uarg->send_sizes) || | ||
| 410 | put_user(compat_ptr(addr), &p->send_sizes) || | ||
| 411 | copy_in_user(&p->flags, &uarg->flags, sizeof(drm_dma_flags_t)) || | ||
| 412 | copy_in_user(&p->request_count, &uarg->request_count, sizeof(int))|| | ||
| 413 | copy_in_user(&p->request_size, &uarg->request_size, sizeof(int)) || | ||
| 414 | get_user(addr, &uarg->request_indices) || | ||
| 415 | put_user(compat_ptr(addr), &p->request_indices) || | ||
| 416 | get_user(addr, &uarg->request_sizes) || | ||
| 417 | put_user(compat_ptr(addr), &p->request_sizes) || | ||
| 418 | copy_in_user(&p->granted_count, &uarg->granted_count, sizeof(int))) | ||
| 419 | return -EFAULT; | ||
| 420 | |||
| 421 | ret = sys_ioctl(fd, DRM_IOCTL_DMA, (unsigned long)p); | ||
| 422 | if (ret) | ||
| 423 | return ret; | ||
| 424 | |||
| 425 | if (copy_in_user(uarg, p, 2 * sizeof(int)) || | ||
| 426 | copy_in_user(&uarg->flags, &p->flags, sizeof(drm_dma_flags_t)) || | ||
| 427 | copy_in_user(&uarg->request_count, &p->request_count, sizeof(int))|| | ||
| 428 | copy_in_user(&uarg->request_size, &p->request_size, sizeof(int)) || | ||
| 429 | copy_in_user(&uarg->granted_count, &p->granted_count, sizeof(int))) | ||
| 430 | return -EFAULT; | ||
| 431 | |||
| 432 | return 0; | ||
| 433 | } | ||
| 434 | |||
| 435 | typedef struct drm32_ctx_res { | ||
| 436 | int count; | ||
| 437 | u32 contexts; /* (drm_ctx_t *) */ | ||
| 438 | } drm32_ctx_res_t; | ||
| 439 | #define DRM32_IOCTL_RES_CTX DRM_IOWR(0x26, drm32_ctx_res_t) | ||
| 440 | |||
| 441 | static int drm32_res_ctx(unsigned int fd, unsigned int cmd, unsigned long arg) | ||
| 442 | { | ||
| 443 | drm32_ctx_res_t __user *uarg = (drm32_ctx_res_t __user *) arg; | ||
| 444 | drm_ctx_res_t __user *p = compat_alloc_user_space(sizeof(*p)); | ||
| 445 | compat_uptr_t addr; | ||
| 446 | int ret; | ||
| 447 | |||
| 448 | if (copy_in_user(p, uarg, sizeof(int)) || | ||
| 449 | get_user(addr, &uarg->contexts) || | ||
| 450 | put_user(compat_ptr(addr), &p->contexts)) | ||
| 451 | return -EFAULT; | ||
| 452 | |||
| 453 | ret = sys_ioctl(fd, DRM_IOCTL_RES_CTX, (unsigned long)p); | ||
| 454 | if (ret) | ||
| 455 | return ret; | ||
| 456 | |||
| 457 | if (copy_in_user(uarg, p, sizeof(int))) | ||
| 458 | return -EFAULT; | ||
| 459 | |||
| 460 | return 0; | ||
| 461 | } | ||
| 462 | |||
| 463 | #endif | ||
| 464 | |||
| 465 | typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *); | 95 | typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *); |
| 466 | 96 | ||
| 467 | #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl) | 97 | #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),sys_ioctl) |
| @@ -485,103 +115,14 @@ COMPATIBLE_IOCTL(FBIOSCURPOS) | |||
| 485 | COMPATIBLE_IOCTL(FBIOGCURPOS) | 115 | COMPATIBLE_IOCTL(FBIOGCURPOS) |
| 486 | COMPATIBLE_IOCTL(FBIOGCURMAX) | 116 | COMPATIBLE_IOCTL(FBIOGCURMAX) |
| 487 | /* Little k */ | 117 | /* Little k */ |
| 488 | COMPATIBLE_IOCTL(KIOCTYPE) | ||
| 489 | COMPATIBLE_IOCTL(KIOCLAYOUT) | ||
| 490 | COMPATIBLE_IOCTL(KIOCGTRANS) | ||
| 491 | COMPATIBLE_IOCTL(KIOCTRANS) | ||
| 492 | COMPATIBLE_IOCTL(KIOCCMD) | ||
| 493 | COMPATIBLE_IOCTL(KIOCSDIRECT) | ||
| 494 | COMPATIBLE_IOCTL(KIOCSLED) | ||
| 495 | COMPATIBLE_IOCTL(KIOCGLED) | ||
| 496 | COMPATIBLE_IOCTL(KIOCSRATE) | ||
| 497 | COMPATIBLE_IOCTL(KIOCGRATE) | ||
| 498 | COMPATIBLE_IOCTL(VUIDSFORMAT) | ||
| 499 | COMPATIBLE_IOCTL(VUIDGFORMAT) | ||
| 500 | /* Little v, the video4linux ioctls */ | 118 | /* Little v, the video4linux ioctls */ |
| 501 | COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */ | 119 | COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */ |
| 502 | COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */ | 120 | COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */ |
| 503 | COMPATIBLE_IOCTL(ENVCTRL_RD_WARNING_TEMPERATURE) | ||
| 504 | COMPATIBLE_IOCTL(ENVCTRL_RD_SHUTDOWN_TEMPERATURE) | ||
| 505 | COMPATIBLE_IOCTL(ENVCTRL_RD_CPU_TEMPERATURE) | ||
| 506 | COMPATIBLE_IOCTL(ENVCTRL_RD_FAN_STATUS) | ||
| 507 | COMPATIBLE_IOCTL(ENVCTRL_RD_VOLTAGE_STATUS) | ||
| 508 | COMPATIBLE_IOCTL(ENVCTRL_RD_SCSI_TEMPERATURE) | ||
| 509 | COMPATIBLE_IOCTL(ENVCTRL_RD_ETHERNET_TEMPERATURE) | ||
| 510 | COMPATIBLE_IOCTL(ENVCTRL_RD_MTHRBD_TEMPERATURE) | ||
| 511 | COMPATIBLE_IOCTL(ENVCTRL_RD_CPU_VOLTAGE) | ||
| 512 | COMPATIBLE_IOCTL(ENVCTRL_RD_GLOBALADDRESS) | ||
| 513 | /* COMPATIBLE_IOCTL(D7SIOCRD) same value as ENVCTRL_RD_VOLTAGE_STATUS */ | ||
| 514 | COMPATIBLE_IOCTL(D7SIOCWR) | ||
| 515 | COMPATIBLE_IOCTL(D7SIOCTM) | ||
| 516 | /* OPENPROMIO, SunOS/Solaris only, the NetBSD one's have | ||
| 517 | * embedded pointers in the arg which we'd need to clean up... | ||
| 518 | */ | ||
| 519 | COMPATIBLE_IOCTL(OPROMGETOPT) | ||
| 520 | COMPATIBLE_IOCTL(OPROMSETOPT) | ||
| 521 | COMPATIBLE_IOCTL(OPROMNXTOPT) | ||
| 522 | COMPATIBLE_IOCTL(OPROMSETOPT2) | ||
| 523 | COMPATIBLE_IOCTL(OPROMNEXT) | ||
| 524 | COMPATIBLE_IOCTL(OPROMCHILD) | ||
| 525 | COMPATIBLE_IOCTL(OPROMGETPROP) | ||
| 526 | COMPATIBLE_IOCTL(OPROMNXTPROP) | ||
| 527 | COMPATIBLE_IOCTL(OPROMU2P) | ||
| 528 | COMPATIBLE_IOCTL(OPROMGETCONS) | ||
| 529 | COMPATIBLE_IOCTL(OPROMGETFBNAME) | ||
| 530 | COMPATIBLE_IOCTL(OPROMGETBOOTARGS) | ||
| 531 | COMPATIBLE_IOCTL(OPROMSETCUR) | ||
| 532 | COMPATIBLE_IOCTL(OPROMPCI2NODE) | ||
| 533 | COMPATIBLE_IOCTL(OPROMPATH2NODE) | ||
| 534 | /* Big L */ | ||
| 535 | COMPATIBLE_IOCTL(LOOP_SET_STATUS64) | ||
| 536 | COMPATIBLE_IOCTL(LOOP_GET_STATUS64) | ||
| 537 | /* Big A */ | ||
| 538 | COMPATIBLE_IOCTL(AUDIO_GETINFO) | ||
| 539 | COMPATIBLE_IOCTL(AUDIO_SETINFO) | ||
| 540 | COMPATIBLE_IOCTL(AUDIO_DRAIN) | ||
| 541 | COMPATIBLE_IOCTL(AUDIO_GETDEV) | ||
| 542 | COMPATIBLE_IOCTL(AUDIO_GETDEV_SUNOS) | ||
| 543 | COMPATIBLE_IOCTL(AUDIO_FLUSH) | ||
| 544 | COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI) | ||
| 545 | #if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE) | ||
| 546 | COMPATIBLE_IOCTL(DRM_IOCTL_GET_MAGIC) | ||
| 547 | COMPATIBLE_IOCTL(DRM_IOCTL_IRQ_BUSID) | ||
| 548 | COMPATIBLE_IOCTL(DRM_IOCTL_AUTH_MAGIC) | ||
| 549 | COMPATIBLE_IOCTL(DRM_IOCTL_BLOCK) | ||
| 550 | COMPATIBLE_IOCTL(DRM_IOCTL_UNBLOCK) | ||
| 551 | COMPATIBLE_IOCTL(DRM_IOCTL_CONTROL) | ||
| 552 | COMPATIBLE_IOCTL(DRM_IOCTL_ADD_BUFS) | ||
| 553 | COMPATIBLE_IOCTL(DRM_IOCTL_MARK_BUFS) | ||
| 554 | COMPATIBLE_IOCTL(DRM_IOCTL_ADD_CTX) | ||
| 555 | COMPATIBLE_IOCTL(DRM_IOCTL_RM_CTX) | ||
| 556 | COMPATIBLE_IOCTL(DRM_IOCTL_MOD_CTX) | ||
| 557 | COMPATIBLE_IOCTL(DRM_IOCTL_GET_CTX) | ||
| 558 | COMPATIBLE_IOCTL(DRM_IOCTL_SWITCH_CTX) | ||
| 559 | COMPATIBLE_IOCTL(DRM_IOCTL_NEW_CTX) | ||
| 560 | COMPATIBLE_IOCTL(DRM_IOCTL_ADD_DRAW) | ||
| 561 | COMPATIBLE_IOCTL(DRM_IOCTL_RM_DRAW) | ||
| 562 | COMPATIBLE_IOCTL(DRM_IOCTL_LOCK) | ||
| 563 | COMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK) | ||
| 564 | COMPATIBLE_IOCTL(DRM_IOCTL_FINISH) | ||
| 565 | #endif /* DRM */ | ||
| 566 | COMPATIBLE_IOCTL(WIOCSTART) | ||
| 567 | COMPATIBLE_IOCTL(WIOCSTOP) | ||
| 568 | COMPATIBLE_IOCTL(WIOCGSTAT) | ||
| 569 | /* And these ioctls need translation */ | 121 | /* And these ioctls need translation */ |
| 570 | /* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */ | 122 | /* Note SIOCRTMSG is no longer, so this is safe and * the user would have seen just an -EINVAL anyways. */ |
| 571 | HANDLE_IOCTL(FBIOPUTCMAP32, fbiogetputcmap) | 123 | HANDLE_IOCTL(FBIOPUTCMAP32, fbiogetputcmap) |
| 572 | HANDLE_IOCTL(FBIOGETCMAP32, fbiogetputcmap) | 124 | HANDLE_IOCTL(FBIOGETCMAP32, fbiogetputcmap) |
| 573 | HANDLE_IOCTL(FBIOSCURSOR32, fbiogscursor) | 125 | HANDLE_IOCTL(FBIOSCURSOR32, fbiogscursor) |
| 574 | #if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE) | ||
| 575 | HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version) | ||
| 576 | HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique) | ||
| 577 | HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique) | ||
| 578 | HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap) | ||
| 579 | HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs) | ||
| 580 | HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs) | ||
| 581 | HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs) | ||
| 582 | HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma) | ||
| 583 | HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx) | ||
| 584 | #endif /* DRM */ | ||
| 585 | #if 0 | 126 | #if 0 |
| 586 | HANDLE_IOCTL(RTC32_IRQP_READ, do_rtc_ioctl) | 127 | HANDLE_IOCTL(RTC32_IRQP_READ, do_rtc_ioctl) |
| 587 | HANDLE_IOCTL(RTC32_IRQP_SET, do_rtc_ioctl) | 128 | HANDLE_IOCTL(RTC32_IRQP_SET, do_rtc_ioctl) |
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index c1f34237cdf2..bf1849dd9c49 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c | |||
| @@ -154,6 +154,7 @@ int prom_callback(long *args) | |||
| 154 | pud_t *pudp; | 154 | pud_t *pudp; |
| 155 | pmd_t *pmdp; | 155 | pmd_t *pmdp; |
| 156 | pte_t *ptep; | 156 | pte_t *ptep; |
| 157 | pte_t pte; | ||
| 157 | 158 | ||
| 158 | for_each_process(p) { | 159 | for_each_process(p) { |
| 159 | mm = p->mm; | 160 | mm = p->mm; |
| @@ -178,8 +179,9 @@ int prom_callback(long *args) | |||
| 178 | * being called from inside OBP. | 179 | * being called from inside OBP. |
| 179 | */ | 180 | */ |
| 180 | ptep = pte_offset_map(pmdp, va); | 181 | ptep = pte_offset_map(pmdp, va); |
| 181 | if (pte_present(*ptep)) { | 182 | pte = *ptep; |
| 182 | tte = pte_val(*ptep); | 183 | if (pte_present(pte)) { |
| 184 | tte = pte_val(pte); | ||
| 183 | res = PROM_TRUE; | 185 | res = PROM_TRUE; |
| 184 | } | 186 | } |
| 185 | pte_unmap(ptep); | 187 | pte_unmap(ptep); |
| @@ -218,6 +220,7 @@ int prom_callback(long *args) | |||
| 218 | pud_t *pudp; | 220 | pud_t *pudp; |
| 219 | pmd_t *pmdp; | 221 | pmd_t *pmdp; |
| 220 | pte_t *ptep; | 222 | pte_t *ptep; |
| 223 | pte_t pte; | ||
| 221 | int error; | 224 | int error; |
| 222 | 225 | ||
| 223 | if ((va >= LOW_OBP_ADDRESS) && (va < HI_OBP_ADDRESS)) { | 226 | if ((va >= LOW_OBP_ADDRESS) && (va < HI_OBP_ADDRESS)) { |
| @@ -240,8 +243,9 @@ int prom_callback(long *args) | |||
| 240 | * being called from inside OBP. | 243 | * being called from inside OBP. |
| 241 | */ | 244 | */ |
| 242 | ptep = pte_offset_kernel(pmdp, va); | 245 | ptep = pte_offset_kernel(pmdp, va); |
| 243 | if (pte_present(*ptep)) { | 246 | pte = *ptep; |
| 244 | tte = pte_val(*ptep); | 247 | if (pte_present(pte)) { |
| 248 | tte = pte_val(pte); | ||
| 245 | res = PROM_TRUE; | 249 | res = PROM_TRUE; |
| 246 | } | 250 | } |
| 247 | goto done; | 251 | goto done; |
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index aecccd0df1d1..009a86e5ded4 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c | |||
| @@ -863,6 +863,7 @@ static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
| 863 | pud_t *pudp = pud_offset(pgdp, address); | 863 | pud_t *pudp = pud_offset(pgdp, address); |
| 864 | pmd_t *pmdp = pmd_offset(pudp, address); | 864 | pmd_t *pmdp = pmd_offset(pudp, address); |
| 865 | pte_t *ptep; | 865 | pte_t *ptep; |
| 866 | pte_t pte; | ||
| 866 | 867 | ||
| 867 | regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); | 868 | regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2); |
| 868 | 869 | ||
| @@ -873,9 +874,10 @@ static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, | |||
| 873 | 874 | ||
| 874 | preempt_disable(); | 875 | preempt_disable(); |
| 875 | ptep = pte_offset_map(pmdp, address); | 876 | ptep = pte_offset_map(pmdp, address); |
| 876 | if (pte_present(*ptep)) { | 877 | pte = *ptep; |
| 878 | if (pte_present(pte)) { | ||
| 877 | unsigned long page = (unsigned long) | 879 | unsigned long page = (unsigned long) |
| 878 | page_address(pte_page(*ptep)); | 880 | page_address(pte_page(pte)); |
| 879 | 881 | ||
| 880 | wmb(); | 882 | wmb(); |
| 881 | __asm__ __volatile__("flush %0 + %1" | 883 | __asm__ __volatile__("flush %0 + %1" |
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index b137fd63f5e1..5d90ee9aebf1 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c | |||
| @@ -839,43 +839,29 @@ void smp_flush_tlb_all(void) | |||
| 839 | * questionable (in theory the big win for threads is the massive sharing of | 839 | * questionable (in theory the big win for threads is the massive sharing of |
| 840 | * address space state across processors). | 840 | * address space state across processors). |
| 841 | */ | 841 | */ |
| 842 | |||
| 843 | /* This currently is only used by the hugetlb arch pre-fault | ||
| 844 | * hook on UltraSPARC-III+ and later when changing the pagesize | ||
| 845 | * bits of the context register for an address space. | ||
| 846 | */ | ||
| 842 | void smp_flush_tlb_mm(struct mm_struct *mm) | 847 | void smp_flush_tlb_mm(struct mm_struct *mm) |
| 843 | { | 848 | { |
| 844 | /* | 849 | u32 ctx = CTX_HWBITS(mm->context); |
| 845 | * This code is called from two places, dup_mmap and exit_mmap. In the | 850 | int cpu = get_cpu(); |
| 846 | * former case, we really need a flush. In the later case, the callers | ||
| 847 | * are single threaded exec_mmap (really need a flush), multithreaded | ||
| 848 | * exec_mmap case (do not need to flush, since the caller gets a new | ||
| 849 | * context via activate_mm), and all other callers of mmput() whence | ||
| 850 | * the flush can be optimized since the associated threads are dead and | ||
| 851 | * the mm is being torn down (__exit_mm and other mmput callers) or the | ||
| 852 | * owning thread is dissociating itself from the mm. The | ||
| 853 | * (atomic_read(&mm->mm_users) == 0) check ensures real work is done | ||
| 854 | * for single thread exec and dup_mmap cases. An alternate check might | ||
| 855 | * have been (current->mm != mm). | ||
| 856 | * Kanoj Sarcar | ||
| 857 | */ | ||
| 858 | if (atomic_read(&mm->mm_users) == 0) | ||
| 859 | return; | ||
| 860 | |||
| 861 | { | ||
| 862 | u32 ctx = CTX_HWBITS(mm->context); | ||
| 863 | int cpu = get_cpu(); | ||
| 864 | 851 | ||
| 865 | if (atomic_read(&mm->mm_users) == 1) { | 852 | if (atomic_read(&mm->mm_users) == 1) { |
| 866 | mm->cpu_vm_mask = cpumask_of_cpu(cpu); | 853 | mm->cpu_vm_mask = cpumask_of_cpu(cpu); |
| 867 | goto local_flush_and_out; | 854 | goto local_flush_and_out; |
| 868 | } | 855 | } |
| 869 | 856 | ||
| 870 | smp_cross_call_masked(&xcall_flush_tlb_mm, | 857 | smp_cross_call_masked(&xcall_flush_tlb_mm, |
| 871 | ctx, 0, 0, | 858 | ctx, 0, 0, |
| 872 | mm->cpu_vm_mask); | 859 | mm->cpu_vm_mask); |
| 873 | 860 | ||
| 874 | local_flush_and_out: | 861 | local_flush_and_out: |
| 875 | __flush_tlb_mm(ctx, SECONDARY_CONTEXT); | 862 | __flush_tlb_mm(ctx, SECONDARY_CONTEXT); |
| 876 | 863 | ||
| 877 | put_cpu(); | 864 | put_cpu(); |
| 878 | } | ||
| 879 | } | 865 | } |
| 880 | 866 | ||
| 881 | void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long *vaddrs) | 867 | void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long *vaddrs) |
| @@ -883,34 +869,13 @@ void smp_flush_tlb_pending(struct mm_struct *mm, unsigned long nr, unsigned long | |||
| 883 | u32 ctx = CTX_HWBITS(mm->context); | 869 | u32 ctx = CTX_HWBITS(mm->context); |
| 884 | int cpu = get_cpu(); | 870 | int cpu = get_cpu(); |
| 885 | 871 | ||
| 886 | if (mm == current->active_mm && atomic_read(&mm->mm_users) == 1) { | 872 | if (mm == current->active_mm && atomic_read(&mm->mm_users) == 1) |
| 887 | mm->cpu_vm_mask = cpumask_of_cpu(cpu); | 873 | mm->cpu_vm_mask = cpumask_of_cpu(cpu); |
| 888 | goto local_flush_and_out; | 874 | else |
| 889 | } else { | 875 | smp_cross_call_masked(&xcall_flush_tlb_pending, |
| 890 | /* This optimization is not valid. Normally | 876 | ctx, nr, (unsigned long) vaddrs, |
| 891 | * we will be holding the page_table_lock, but | 877 | mm->cpu_vm_mask); |
| 892 | * there is an exception which is copy_page_range() | ||
| 893 | * when forking. The lock is held during the individual | ||
| 894 | * page table updates in the parent, but not at the | ||
| 895 | * top level, which is where we are invoked. | ||
| 896 | */ | ||
| 897 | if (0) { | ||
| 898 | cpumask_t this_cpu_mask = cpumask_of_cpu(cpu); | ||
| 899 | |||
| 900 | /* By virtue of running under the mm->page_table_lock, | ||
| 901 | * and mmu_context.h:switch_mm doing the same, the | ||
| 902 | * following operation is safe. | ||
| 903 | */ | ||
| 904 | if (cpus_equal(mm->cpu_vm_mask, this_cpu_mask)) | ||
| 905 | goto local_flush_and_out; | ||
| 906 | } | ||
| 907 | } | ||
| 908 | |||
| 909 | smp_cross_call_masked(&xcall_flush_tlb_pending, | ||
| 910 | ctx, nr, (unsigned long) vaddrs, | ||
| 911 | mm->cpu_vm_mask); | ||
| 912 | 878 | ||
| 913 | local_flush_and_out: | ||
| 914 | __flush_tlb_pending(ctx, nr, vaddrs); | 879 | __flush_tlb_pending(ctx, nr, vaddrs); |
| 915 | 880 | ||
| 916 | put_cpu(); | 881 | put_cpu(); |
diff --git a/arch/sparc64/kernel/sunos_ioctl32.c b/arch/sparc64/kernel/sunos_ioctl32.c index 7654b8a7f03a..3f619ead22cc 100644 --- a/arch/sparc64/kernel/sunos_ioctl32.c +++ b/arch/sparc64/kernel/sunos_ioctl32.c | |||
| @@ -24,7 +24,6 @@ | |||
| 24 | #include <linux/smp_lock.h> | 24 | #include <linux/smp_lock.h> |
| 25 | #include <linux/syscalls.h> | 25 | #include <linux/syscalls.h> |
| 26 | #include <linux/compat.h> | 26 | #include <linux/compat.h> |
| 27 | #include <asm/kbio.h> | ||
| 28 | 27 | ||
| 29 | #define SUNOS_NR_OPEN 256 | 28 | #define SUNOS_NR_OPEN 256 |
| 30 | 29 | ||
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index 38c5525087a2..459c8fbe02b4 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c | |||
| @@ -60,17 +60,6 @@ static void __iomem *mstk48t59_regs; | |||
| 60 | 60 | ||
| 61 | static int set_rtc_mmss(unsigned long); | 61 | static int set_rtc_mmss(unsigned long); |
| 62 | 62 | ||
| 63 | static __init unsigned long dummy_get_tick(void) | ||
| 64 | { | ||
| 65 | return 0; | ||
| 66 | } | ||
| 67 | |||
| 68 | static __initdata struct sparc64_tick_ops dummy_tick_ops = { | ||
| 69 | .get_tick = dummy_get_tick, | ||
| 70 | }; | ||
| 71 | |||
| 72 | struct sparc64_tick_ops *tick_ops __read_mostly = &dummy_tick_ops; | ||
| 73 | |||
| 74 | #define TICK_PRIV_BIT (1UL << 63) | 63 | #define TICK_PRIV_BIT (1UL << 63) |
| 75 | 64 | ||
| 76 | #ifdef CONFIG_SMP | 65 | #ifdef CONFIG_SMP |
| @@ -200,6 +189,8 @@ static struct sparc64_tick_ops tick_operations __read_mostly = { | |||
| 200 | .softint_mask = 1UL << 0, | 189 | .softint_mask = 1UL << 0, |
| 201 | }; | 190 | }; |
| 202 | 191 | ||
| 192 | struct sparc64_tick_ops *tick_ops __read_mostly = &tick_operations; | ||
| 193 | |||
| 203 | static void stick_init_tick(unsigned long offset) | 194 | static void stick_init_tick(unsigned long offset) |
| 204 | { | 195 | { |
| 205 | tick_disable_protection(); | 196 | tick_disable_protection(); |
