diff options
289 files changed, 9835 insertions, 3443 deletions
diff --git a/Documentation/devicetree/bindings/interrupt-controller/mips-gic.txt b/Documentation/devicetree/bindings/interrupt-controller/mips-gic.txt new file mode 100644 index 000000000000..5a65478e5d40 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/mips-gic.txt | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | MIPS Global Interrupt Controller (GIC) | ||
| 2 | |||
| 3 | The MIPS GIC routes external interrupts to individual VPEs and IRQ pins. | ||
| 4 | It also supports local (per-processor) interrupts and software-generated | ||
| 5 | interrupts which can be used as IPIs. The GIC also includes a free-running | ||
| 6 | global timer, per-CPU count/compare timers, and a watchdog. | ||
| 7 | |||
| 8 | Required properties: | ||
| 9 | - compatible : Should be "mti,gic". | ||
| 10 | - interrupt-controller : Identifies the node as an interrupt controller | ||
| 11 | - #interrupt-cells : Specifies the number of cells needed to encode an | ||
| 12 | interrupt specifier. Should be 3. | ||
| 13 | - The first cell is the type of interrupt, local or shared. | ||
| 14 | See <include/dt-bindings/interrupt-controller/mips-gic.h>. | ||
| 15 | - The second cell is the GIC interrupt number. | ||
| 16 | - The third cell encodes the interrupt flags. | ||
| 17 | See <include/dt-bindings/interrupt-controller/irq.h> for a list of valid | ||
| 18 | flags. | ||
| 19 | |||
| 20 | Optional properties: | ||
| 21 | - reg : Base address and length of the GIC registers. If not present, | ||
| 22 | the base address reported by the hardware GCR_GIC_BASE will be used. | ||
| 23 | - mti,reserved-cpu-vectors : Specifies the list of CPU interrupt vectors | ||
| 24 | to which the GIC may not route interrupts. Valid values are 2 - 7. | ||
| 25 | This property is ignored if the CPU is started in EIC mode. | ||
| 26 | |||
| 27 | Required properties for timer sub-node: | ||
| 28 | - compatible : Should be "mti,gic-timer". | ||
| 29 | - interrupts : Interrupt for the GIC local timer. | ||
| 30 | - clock-frequency : Clock frequency at which the GIC timers operate. | ||
| 31 | |||
| 32 | Example: | ||
| 33 | |||
| 34 | gic: interrupt-controller@1bdc0000 { | ||
| 35 | compatible = "mti,gic"; | ||
| 36 | reg = <0x1bdc0000 0x20000>; | ||
| 37 | |||
| 38 | interrupt-controller; | ||
| 39 | #interrupt-cells = <3>; | ||
| 40 | |||
| 41 | mti,reserved-cpu-vectors = <7>; | ||
| 42 | |||
| 43 | timer { | ||
| 44 | compatible = "mti,gic-timer"; | ||
| 45 | interrupts = <GIC_LOCAL 1 IRQ_TYPE_NONE>; | ||
| 46 | clock-frequency = <50000000>; | ||
| 47 | }; | ||
| 48 | }; | ||
| 49 | |||
| 50 | uart@18101400 { | ||
| 51 | ... | ||
| 52 | interrupt-parent = <&gic>; | ||
| 53 | interrupts = <GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>; | ||
| 54 | ... | ||
| 55 | }; | ||
diff --git a/Documentation/devicetree/bindings/mips/brcm/bcm3384-intc.txt b/Documentation/devicetree/bindings/mips/brcm/bcm3384-intc.txt new file mode 100644 index 000000000000..d4e0141d3620 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/brcm/bcm3384-intc.txt | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | * Interrupt Controller | ||
| 2 | |||
| 3 | Properties: | ||
| 4 | - compatible: "brcm,bcm3384-intc" | ||
| 5 | |||
| 6 | Compatibility with BCM3384 and possibly other BCM33xx/BCM63xx SoCs. | ||
| 7 | |||
| 8 | - reg: Address/length pairs for each mask/status register set. Length must | ||
| 9 | be 8. If multiple register sets are specified, the first set will | ||
| 10 | handle IRQ offsets 0..31, the second set 32..63, and so on. | ||
| 11 | |||
| 12 | - interrupt-controller: This is an interrupt controller. | ||
| 13 | |||
| 14 | - #interrupt-cells: Must be <1>. Just a simple IRQ offset; no level/edge | ||
| 15 | or polarity configuration is possible with this controller. | ||
| 16 | |||
| 17 | - interrupt-parent: This controller is cascaded from a MIPS CPU HW IRQ, or | ||
| 18 | from another INTC. | ||
| 19 | |||
| 20 | - interrupts: The IRQ on the parent controller. | ||
| 21 | |||
| 22 | Example: | ||
| 23 | periph_intc: periph_intc@14e00038 { | ||
| 24 | compatible = "brcm,bcm3384-intc"; | ||
| 25 | |||
| 26 | /* | ||
| 27 | * IRQs 0..31: mask reg 0x14e00038, status reg 0x14e0003c | ||
| 28 | * IRQs 32..63: mask reg 0x14e00340, status reg 0x14e00344 | ||
| 29 | */ | ||
| 30 | reg = <0x14e00038 0x8 0x14e00340 0x8>; | ||
| 31 | |||
| 32 | interrupt-controller; | ||
| 33 | #interrupt-cells = <1>; | ||
| 34 | |||
| 35 | interrupt-parent = <&cpu_intc>; | ||
| 36 | interrupts = <4>; | ||
| 37 | }; | ||
diff --git a/Documentation/devicetree/bindings/mips/brcm/bmips.txt b/Documentation/devicetree/bindings/mips/brcm/bmips.txt new file mode 100644 index 000000000000..8ef71b4085ca --- /dev/null +++ b/Documentation/devicetree/bindings/mips/brcm/bmips.txt | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | * Broadcom MIPS (BMIPS) CPUs | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible: "brcm,bmips3300", "brcm,bmips4350", "brcm,bmips4380", | ||
| 5 | "brcm,bmips5000" | ||
| 6 | |||
| 7 | - mips-hpt-frequency: This is common to all CPUs in the system so it lives | ||
| 8 | under the "cpus" node. | ||
diff --git a/Documentation/devicetree/bindings/mips/brcm/cm-dsl.txt b/Documentation/devicetree/bindings/mips/brcm/cm-dsl.txt new file mode 100644 index 000000000000..8a139cb3c0b5 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/brcm/cm-dsl.txt | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | * Broadcom cable/DSL platforms | ||
| 2 | |||
| 3 | SoCs: | ||
| 4 | |||
| 5 | Required properties: | ||
| 6 | - compatible: "brcm,bcm3384", "brcm,bcm33843" | ||
| 7 | |||
| 8 | Boards: | ||
| 9 | |||
| 10 | Required properties: | ||
| 11 | - compatible: "brcm,bcm93384wvg" | ||
diff --git a/Documentation/devicetree/bindings/mips/brcm/usb.txt b/Documentation/devicetree/bindings/mips/brcm/usb.txt new file mode 100644 index 000000000000..452c45c7bf29 --- /dev/null +++ b/Documentation/devicetree/bindings/mips/brcm/usb.txt | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | * Broadcom USB controllers | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible: "brcm,bcm3384-ohci", "brcm,bcm3384-ehci" | ||
| 5 | |||
| 6 | These currently use the generic-ohci and generic-ehci drivers. On some | ||
| 7 | systems, special handling may be needed in the following cases: | ||
| 8 | |||
| 9 | - Restoring state after systemwide power save modes | ||
| 10 | - Sharing PHYs with the USBD (UDC) hardware | ||
| 11 | - Figuring out which controllers are disabled on ASIC bondout variants | ||
diff --git a/Documentation/devicetree/bindings/mips/cpu_irq.txt b/Documentation/devicetree/bindings/mips/cpu_irq.txt index 13aa4b62c62a..fc149f326dae 100644 --- a/Documentation/devicetree/bindings/mips/cpu_irq.txt +++ b/Documentation/devicetree/bindings/mips/cpu_irq.txt | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | MIPS CPU interrupt controller | 1 | MIPS CPU interrupt controller |
| 2 | 2 | ||
| 3 | On MIPS the mips_cpu_intc_init() helper can be used to initialize the 8 CPU | 3 | On MIPS the mips_cpu_irq_of_init() helper can be used to initialize the 8 CPU |
| 4 | IRQs from a devicetree file and create a irq_domain for IRQ controller. | 4 | IRQs from a devicetree file and create a irq_domain for IRQ controller. |
| 5 | 5 | ||
| 6 | With the irq_domain in place we can describe how the 8 IRQs are wired to the | 6 | With the irq_domain in place we can describe how the 8 IRQs are wired to the |
| @@ -36,7 +36,7 @@ Example devicetree: | |||
| 36 | 36 | ||
| 37 | Example platform irq.c: | 37 | Example platform irq.c: |
| 38 | static struct of_device_id __initdata of_irq_ids[] = { | 38 | static struct of_device_id __initdata of_irq_ids[] = { |
| 39 | { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_intc_init }, | 39 | { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_irq_of_init }, |
| 40 | { .compatible = "ralink,rt2880-intc", .data = intc_of_init }, | 40 | { .compatible = "ralink,rt2880-intc", .data = intc_of_init }, |
| 41 | {}, | 41 | {}, |
| 42 | }; | 42 | }; |
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 2417cb0b493b..cc6151c431c8 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt | |||
| @@ -101,6 +101,7 @@ mitsubishi Mitsubishi Electric Corporation | |||
| 101 | mosaixtech Mosaix Technologies, Inc. | 101 | mosaixtech Mosaix Technologies, Inc. |
| 102 | moxa Moxa | 102 | moxa Moxa |
| 103 | mpl MPL AG | 103 | mpl MPL AG |
| 104 | mti Imagination Technologies Ltd. (formerly MIPS Technologies Inc.) | ||
| 104 | mundoreader Mundo Reader S.L. | 105 | mundoreader Mundo Reader S.L. |
| 105 | murata Murata Manufacturing Co., Ltd. | 106 | murata Murata Manufacturing Co., Ltd. |
| 106 | mxicy Macronix International Co., Ltd. | 107 | mxicy Macronix International Co., Ltd. |
diff --git a/MAINTAINERS b/MAINTAINERS index 34b4b841da40..e186bf90ed8a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -2085,6 +2085,14 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/rpi/linux-rpi.git | |||
| 2085 | S: Maintained | 2085 | S: Maintained |
| 2086 | N: bcm2835 | 2086 | N: bcm2835 |
| 2087 | 2087 | ||
| 2088 | BROADCOM BCM33XX MIPS ARCHITECTURE | ||
| 2089 | M: Kevin Cernekee <cernekee@gmail.com> | ||
| 2090 | L: linux-mips@linux-mips.org | ||
| 2091 | S: Maintained | ||
| 2092 | F: arch/mips/bcm3384/* | ||
| 2093 | F: arch/mips/include/asm/mach-bcm3384/* | ||
| 2094 | F: arch/mips/kernel/*bmips* | ||
| 2095 | |||
| 2088 | BROADCOM BCM5301X ARM ARCHITECTURE | 2096 | BROADCOM BCM5301X ARM ARCHITECTURE |
| 2089 | M: Hauke Mehrtens <hauke@hauke-m.de> | 2097 | M: Hauke Mehrtens <hauke@hauke-m.de> |
| 2090 | L: linux-arm-kernel@lists.infradead.org | 2098 | L: linux-arm-kernel@lists.infradead.org |
| @@ -2101,6 +2109,12 @@ S: Maintained | |||
| 2101 | F: arch/arm/mach-bcm/bcm63xx.c | 2109 | F: arch/arm/mach-bcm/bcm63xx.c |
| 2102 | F: arch/arm/include/debug/bcm63xx.S | 2110 | F: arch/arm/include/debug/bcm63xx.S |
| 2103 | 2111 | ||
| 2112 | BROADCOM BCM63XX/BCM33XX UDC DRIVER | ||
| 2113 | M: Kevin Cernekee <cernekee@gmail.com> | ||
| 2114 | L: linux-usb@vger.kernel.org | ||
| 2115 | S: Maintained | ||
| 2116 | F: drivers/usb/gadget/udc/bcm63xx_udc.* | ||
| 2117 | |||
| 2104 | BROADCOM BCM7XXX ARM ARCHITECTURE | 2118 | BROADCOM BCM7XXX ARM ARCHITECTURE |
| 2105 | M: Marc Carino <marc.ceeeee@gmail.com> | 2119 | M: Marc Carino <marc.ceeeee@gmail.com> |
| 2106 | M: Brian Norris <computersforpeace@gmail.com> | 2120 | M: Brian Norris <computersforpeace@gmail.com> |
| @@ -2112,6 +2126,18 @@ F: arch/arm/mach-bcm/*brcmstb* | |||
| 2112 | F: arch/arm/boot/dts/bcm7*.dts* | 2126 | F: arch/arm/boot/dts/bcm7*.dts* |
| 2113 | F: drivers/bus/brcmstb_gisb.c | 2127 | F: drivers/bus/brcmstb_gisb.c |
| 2114 | 2128 | ||
| 2129 | BROADCOM BMIPS MIPS ARCHITECTURE | ||
| 2130 | M: Kevin Cernekee <cernekee@gmail.com> | ||
| 2131 | M: Florian Fainelli <f.fainelli@gmail.com> | ||
| 2132 | L: linux-mips@linux-mips.org | ||
| 2133 | S: Maintained | ||
| 2134 | F: arch/mips/bmips/* | ||
| 2135 | F: arch/mips/include/asm/mach-bmips/* | ||
| 2136 | F: arch/mips/kernel/*bmips* | ||
| 2137 | F: arch/mips/boot/dts/bcm*.dts* | ||
| 2138 | F: drivers/irqchip/irq-bcm7* | ||
| 2139 | F: drivers/irqchip/irq-brcmstb* | ||
| 2140 | |||
| 2115 | BROADCOM TG3 GIGABIT ETHERNET DRIVER | 2141 | BROADCOM TG3 GIGABIT ETHERNET DRIVER |
| 2116 | M: Prashant Sreedharan <prashant@broadcom.com> | 2142 | M: Prashant Sreedharan <prashant@broadcom.com> |
| 2117 | M: Michael Chan <mchan@broadcom.com> | 2143 | M: Michael Chan <mchan@broadcom.com> |
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index f5e18bf3275e..e5fc463b36d0 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms | |||
| @@ -2,7 +2,9 @@ | |||
| 2 | 2 | ||
| 3 | platforms += alchemy | 3 | platforms += alchemy |
| 4 | platforms += ar7 | 4 | platforms += ar7 |
| 5 | platforms += ath25 | ||
| 5 | platforms += ath79 | 6 | platforms += ath79 |
| 7 | platforms += bcm3384 | ||
| 6 | platforms += bcm47xx | 8 | platforms += bcm47xx |
| 7 | platforms += bcm63xx | 9 | platforms += bcm63xx |
| 8 | platforms += cavium-octeon | 10 | platforms += cavium-octeon |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 9536ef912f59..3289969ee423 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
| @@ -53,6 +53,7 @@ config MIPS | |||
| 53 | select HAVE_CC_STACKPROTECTOR | 53 | select HAVE_CC_STACKPROTECTOR |
| 54 | select CPU_PM if CPU_IDLE | 54 | select CPU_PM if CPU_IDLE |
| 55 | select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST | 55 | select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST |
| 56 | select ARCH_BINFMT_ELF_STATE | ||
| 56 | 57 | ||
| 57 | menu "Machine selection" | 58 | menu "Machine selection" |
| 58 | 59 | ||
| @@ -62,7 +63,7 @@ choice | |||
| 62 | 63 | ||
| 63 | config MIPS_ALCHEMY | 64 | config MIPS_ALCHEMY |
| 64 | bool "Alchemy processor based machines" | 65 | bool "Alchemy processor based machines" |
| 65 | select 64BIT_PHYS_ADDR | 66 | select ARCH_PHYS_ADDR_T_64BIT |
| 66 | select CEVT_R4K | 67 | select CEVT_R4K |
| 67 | select CSRC_R4K | 68 | select CSRC_R4K |
| 68 | select IRQ_CPU | 69 | select IRQ_CPU |
| @@ -96,6 +97,20 @@ config AR7 | |||
| 96 | Support for the Texas Instruments AR7 System-on-a-Chip | 97 | Support for the Texas Instruments AR7 System-on-a-Chip |
| 97 | family: TNETD7100, 7200 and 7300. | 98 | family: TNETD7100, 7200 and 7300. |
| 98 | 99 | ||
| 100 | config ATH25 | ||
| 101 | bool "Atheros AR231x/AR531x SoC support" | ||
| 102 | select CEVT_R4K | ||
| 103 | select CSRC_R4K | ||
| 104 | select DMA_NONCOHERENT | ||
| 105 | select IRQ_CPU | ||
| 106 | select IRQ_DOMAIN | ||
| 107 | select SYS_HAS_CPU_MIPS32_R1 | ||
| 108 | select SYS_SUPPORTS_BIG_ENDIAN | ||
| 109 | select SYS_SUPPORTS_32BIT_KERNEL | ||
| 110 | select SYS_HAS_EARLY_PRINTK | ||
| 111 | help | ||
| 112 | Support for Atheros AR231x and Atheros AR531x based boards | ||
| 113 | |||
| 99 | config ATH79 | 114 | config ATH79 |
| 100 | bool "Atheros AR71XX/AR724X/AR913X based boards" | 115 | bool "Atheros AR71XX/AR724X/AR913X based boards" |
| 101 | select ARCH_REQUIRE_GPIOLIB | 116 | select ARCH_REQUIRE_GPIOLIB |
| @@ -115,6 +130,32 @@ config ATH79 | |||
| 115 | help | 130 | help |
| 116 | Support for the Atheros AR71XX/AR724X/AR913X SoCs. | 131 | Support for the Atheros AR71XX/AR724X/AR913X SoCs. |
| 117 | 132 | ||
| 133 | config BCM3384 | ||
| 134 | bool "Broadcom BCM3384 based boards" | ||
| 135 | select BOOT_RAW | ||
| 136 | select NO_EXCEPT_FILL | ||
| 137 | select USE_OF | ||
| 138 | select CEVT_R4K | ||
| 139 | select CSRC_R4K | ||
| 140 | select SYNC_R4K | ||
| 141 | select COMMON_CLK | ||
| 142 | select DMA_NONCOHERENT | ||
| 143 | select IRQ_CPU | ||
| 144 | select SYS_SUPPORTS_32BIT_KERNEL | ||
| 145 | select SYS_SUPPORTS_BIG_ENDIAN | ||
| 146 | select SYS_SUPPORTS_HIGHMEM | ||
| 147 | select SYS_HAS_CPU_BMIPS5000 | ||
| 148 | select SWAP_IO_SPACE | ||
| 149 | select USB_EHCI_BIG_ENDIAN_DESC | ||
| 150 | select USB_EHCI_BIG_ENDIAN_MMIO | ||
| 151 | select USB_OHCI_BIG_ENDIAN_DESC | ||
| 152 | select USB_OHCI_BIG_ENDIAN_MMIO | ||
| 153 | help | ||
| 154 | Support for BCM3384 based boards. BCM3384/BCM33843 is a cable modem | ||
| 155 | chipset with a Linux application processor that is often used to | ||
| 156 | provide Samba services, a CUPS print server, and/or advanced routing | ||
| 157 | features. | ||
| 158 | |||
| 118 | config BCM47XX | 159 | config BCM47XX |
| 119 | bool "Broadcom BCM47XX based boards" | 160 | bool "Broadcom BCM47XX based boards" |
| 120 | select ARCH_WANT_OPTIONAL_GPIOLIB | 161 | select ARCH_WANT_OPTIONAL_GPIOLIB |
| @@ -269,6 +310,8 @@ config LANTIQ | |||
| 269 | select USE_OF | 310 | select USE_OF |
| 270 | select PINCTRL | 311 | select PINCTRL |
| 271 | select PINCTRL_LANTIQ | 312 | select PINCTRL_LANTIQ |
| 313 | select ARCH_HAS_RESET_CONTROLLER | ||
| 314 | select RESET_CONTROLLER | ||
| 272 | 315 | ||
| 273 | config LASAT | 316 | config LASAT |
| 274 | bool "LASAT Networks platforms" | 317 | bool "LASAT Networks platforms" |
| @@ -315,17 +358,18 @@ config MIPS_MALTA | |||
| 315 | select BOOT_RAW | 358 | select BOOT_RAW |
| 316 | select CEVT_R4K | 359 | select CEVT_R4K |
| 317 | select CSRC_R4K | 360 | select CSRC_R4K |
| 318 | select CSRC_GIC | 361 | select CLKSRC_MIPS_GIC |
| 319 | select DMA_MAYBE_COHERENT | 362 | select DMA_MAYBE_COHERENT |
| 320 | select GENERIC_ISA_DMA | 363 | select GENERIC_ISA_DMA |
| 321 | select HAVE_PCSPKR_PLATFORM | 364 | select HAVE_PCSPKR_PLATFORM |
| 322 | select IRQ_CPU | 365 | select IRQ_CPU |
| 323 | select IRQ_GIC | 366 | select MIPS_GIC |
| 324 | select HW_HAS_PCI | 367 | select HW_HAS_PCI |
| 325 | select I8253 | 368 | select I8253 |
| 326 | select I8259 | 369 | select I8259 |
| 327 | select MIPS_BONITO64 | 370 | select MIPS_BONITO64 |
| 328 | select MIPS_CPU_SCACHE | 371 | select MIPS_CPU_SCACHE |
| 372 | select MIPS_L1_CACHE_SHIFT_6 | ||
| 329 | select PCI_GT64XXX_PCI0 | 373 | select PCI_GT64XXX_PCI0 |
| 330 | select MIPS_MSC | 374 | select MIPS_MSC |
| 331 | select SWAP_IO_SPACE | 375 | select SWAP_IO_SPACE |
| @@ -340,6 +384,7 @@ config MIPS_MALTA | |||
| 340 | select SYS_SUPPORTS_64BIT_KERNEL | 384 | select SYS_SUPPORTS_64BIT_KERNEL |
| 341 | select SYS_SUPPORTS_BIG_ENDIAN | 385 | select SYS_SUPPORTS_BIG_ENDIAN |
| 342 | select SYS_SUPPORTS_LITTLE_ENDIAN | 386 | select SYS_SUPPORTS_LITTLE_ENDIAN |
| 387 | select SYS_SUPPORTS_MICROMIPS | ||
| 343 | select SYS_SUPPORTS_MIPS_CMP | 388 | select SYS_SUPPORTS_MIPS_CMP |
| 344 | select SYS_SUPPORTS_MIPS_CPS | 389 | select SYS_SUPPORTS_MIPS_CPS |
| 345 | select SYS_SUPPORTS_MIPS16 | 390 | select SYS_SUPPORTS_MIPS16 |
| @@ -357,12 +402,12 @@ config MIPS_SEAD3 | |||
| 357 | select BUILTIN_DTB | 402 | select BUILTIN_DTB |
| 358 | select CEVT_R4K | 403 | select CEVT_R4K |
| 359 | select CSRC_R4K | 404 | select CSRC_R4K |
| 360 | select CSRC_GIC | 405 | select CLKSRC_MIPS_GIC |
| 361 | select CPU_MIPSR2_IRQ_VI | 406 | select CPU_MIPSR2_IRQ_VI |
| 362 | select CPU_MIPSR2_IRQ_EI | 407 | select CPU_MIPSR2_IRQ_EI |
| 363 | select DMA_NONCOHERENT | 408 | select DMA_NONCOHERENT |
| 364 | select IRQ_CPU | 409 | select IRQ_CPU |
| 365 | select IRQ_GIC | 410 | select MIPS_GIC |
| 366 | select LIBFDT | 411 | select LIBFDT |
| 367 | select MIPS_MSC | 412 | select MIPS_MSC |
| 368 | select SYS_HAS_CPU_MIPS32_R1 | 413 | select SYS_HAS_CPU_MIPS32_R1 |
| @@ -726,7 +771,7 @@ config MIKROTIK_RB532 | |||
| 726 | config CAVIUM_OCTEON_SOC | 771 | config CAVIUM_OCTEON_SOC |
| 727 | bool "Cavium Networks Octeon SoC based boards" | 772 | bool "Cavium Networks Octeon SoC based boards" |
| 728 | select CEVT_R4K | 773 | select CEVT_R4K |
| 729 | select 64BIT_PHYS_ADDR | 774 | select ARCH_PHYS_ADDR_T_64BIT |
| 730 | select DMA_COHERENT | 775 | select DMA_COHERENT |
| 731 | select SYS_SUPPORTS_64BIT_KERNEL | 776 | select SYS_SUPPORTS_64BIT_KERNEL |
| 732 | select SYS_SUPPORTS_BIG_ENDIAN | 777 | select SYS_SUPPORTS_BIG_ENDIAN |
| @@ -768,7 +813,7 @@ config NLM_XLR_BOARD | |||
| 768 | select SWAP_IO_SPACE | 813 | select SWAP_IO_SPACE |
| 769 | select SYS_SUPPORTS_32BIT_KERNEL | 814 | select SYS_SUPPORTS_32BIT_KERNEL |
| 770 | select SYS_SUPPORTS_64BIT_KERNEL | 815 | select SYS_SUPPORTS_64BIT_KERNEL |
| 771 | select 64BIT_PHYS_ADDR | 816 | select ARCH_PHYS_ADDR_T_64BIT |
| 772 | select SYS_SUPPORTS_BIG_ENDIAN | 817 | select SYS_SUPPORTS_BIG_ENDIAN |
| 773 | select SYS_SUPPORTS_HIGHMEM | 818 | select SYS_SUPPORTS_HIGHMEM |
| 774 | select DMA_COHERENT | 819 | select DMA_COHERENT |
| @@ -794,7 +839,7 @@ config NLM_XLP_BOARD | |||
| 794 | select HW_HAS_PCI | 839 | select HW_HAS_PCI |
| 795 | select SYS_SUPPORTS_32BIT_KERNEL | 840 | select SYS_SUPPORTS_32BIT_KERNEL |
| 796 | select SYS_SUPPORTS_64BIT_KERNEL | 841 | select SYS_SUPPORTS_64BIT_KERNEL |
| 797 | select 64BIT_PHYS_ADDR | 842 | select ARCH_PHYS_ADDR_T_64BIT |
| 798 | select SYS_SUPPORTS_BIG_ENDIAN | 843 | select SYS_SUPPORTS_BIG_ENDIAN |
| 799 | select SYS_SUPPORTS_LITTLE_ENDIAN | 844 | select SYS_SUPPORTS_LITTLE_ENDIAN |
| 800 | select SYS_SUPPORTS_HIGHMEM | 845 | select SYS_SUPPORTS_HIGHMEM |
| @@ -835,6 +880,7 @@ config MIPS_PARAVIRT | |||
| 835 | endchoice | 880 | endchoice |
| 836 | 881 | ||
| 837 | source "arch/mips/alchemy/Kconfig" | 882 | source "arch/mips/alchemy/Kconfig" |
| 883 | source "arch/mips/ath25/Kconfig" | ||
| 838 | source "arch/mips/ath79/Kconfig" | 884 | source "arch/mips/ath79/Kconfig" |
| 839 | source "arch/mips/bcm47xx/Kconfig" | 885 | source "arch/mips/bcm47xx/Kconfig" |
| 840 | source "arch/mips/bcm63xx/Kconfig" | 886 | source "arch/mips/bcm63xx/Kconfig" |
| @@ -907,10 +953,6 @@ config CEVT_GT641XX | |||
| 907 | config CEVT_R4K | 953 | config CEVT_R4K |
| 908 | bool | 954 | bool |
| 909 | 955 | ||
| 910 | config CEVT_GIC | ||
| 911 | select MIPS_CM | ||
| 912 | bool | ||
| 913 | |||
| 914 | config CEVT_SB1250 | 956 | config CEVT_SB1250 |
| 915 | bool | 957 | bool |
| 916 | 958 | ||
| @@ -926,10 +968,6 @@ config CSRC_IOASIC | |||
| 926 | config CSRC_R4K | 968 | config CSRC_R4K |
| 927 | bool | 969 | bool |
| 928 | 970 | ||
| 929 | config CSRC_GIC | ||
| 930 | select MIPS_CM | ||
| 931 | bool | ||
| 932 | |||
| 933 | config CSRC_SB1250 | 971 | config CSRC_SB1250 |
| 934 | bool | 972 | bool |
| 935 | 973 | ||
| @@ -941,7 +979,7 @@ config FW_CFE | |||
| 941 | bool | 979 | bool |
| 942 | 980 | ||
| 943 | config ARCH_DMA_ADDR_T_64BIT | 981 | config ARCH_DMA_ADDR_T_64BIT |
| 944 | def_bool (HIGHMEM && 64BIT_PHYS_ADDR) || 64BIT | 982 | def_bool (HIGHMEM && ARCH_PHYS_ADDR_T_64BIT) || 64BIT |
| 945 | 983 | ||
| 946 | config DMA_MAYBE_COHERENT | 984 | config DMA_MAYBE_COHERENT |
| 947 | select DMA_NONCOHERENT | 985 | select DMA_NONCOHERENT |
| @@ -975,6 +1013,7 @@ config SYS_SUPPORTS_HOTPLUG_CPU | |||
| 975 | 1013 | ||
| 976 | config I8259 | 1014 | config I8259 |
| 977 | bool | 1015 | bool |
| 1016 | select IRQ_DOMAIN | ||
| 978 | 1017 | ||
| 979 | config MIPS_BONITO64 | 1018 | config MIPS_BONITO64 |
| 980 | bool | 1019 | bool |
| @@ -1055,6 +1094,7 @@ config MIPS_HUGE_TLB_SUPPORT | |||
| 1055 | 1094 | ||
| 1056 | config IRQ_CPU | 1095 | config IRQ_CPU |
| 1057 | bool | 1096 | bool |
| 1097 | select IRQ_DOMAIN | ||
| 1058 | 1098 | ||
| 1059 | config IRQ_CPU_RM7K | 1099 | config IRQ_CPU_RM7K |
| 1060 | bool | 1100 | bool |
| @@ -1071,10 +1111,6 @@ config IRQ_TXX9 | |||
| 1071 | config IRQ_GT641XX | 1111 | config IRQ_GT641XX |
| 1072 | bool | 1112 | bool |
| 1073 | 1113 | ||
| 1074 | config IRQ_GIC | ||
| 1075 | select MIPS_CM | ||
| 1076 | bool | ||
| 1077 | |||
| 1078 | config PCI_GT64XXX_PCI0 | 1114 | config PCI_GT64XXX_PCI0 |
| 1079 | bool | 1115 | bool |
| 1080 | 1116 | ||
| @@ -1574,6 +1610,7 @@ config CPU_LOONGSON1 | |||
| 1574 | select CPU_HAS_PREFETCH | 1610 | select CPU_HAS_PREFETCH |
| 1575 | select CPU_SUPPORTS_32BIT_KERNEL | 1611 | select CPU_SUPPORTS_32BIT_KERNEL |
| 1576 | select CPU_SUPPORTS_HIGHMEM | 1612 | select CPU_SUPPORTS_HIGHMEM |
| 1613 | select CPU_SUPPORTS_CPUFREQ | ||
| 1577 | 1614 | ||
| 1578 | config CPU_BMIPS32_3300 | 1615 | config CPU_BMIPS32_3300 |
| 1579 | select SMP_UP if SMP | 1616 | select SMP_UP if SMP |
| @@ -1586,12 +1623,14 @@ config CPU_BMIPS4350 | |||
| 1586 | 1623 | ||
| 1587 | config CPU_BMIPS4380 | 1624 | config CPU_BMIPS4380 |
| 1588 | bool | 1625 | bool |
| 1626 | select MIPS_L1_CACHE_SHIFT_6 | ||
| 1589 | select SYS_SUPPORTS_SMP | 1627 | select SYS_SUPPORTS_SMP |
| 1590 | select SYS_SUPPORTS_HOTPLUG_CPU | 1628 | select SYS_SUPPORTS_HOTPLUG_CPU |
| 1591 | 1629 | ||
| 1592 | config CPU_BMIPS5000 | 1630 | config CPU_BMIPS5000 |
| 1593 | bool | 1631 | bool |
| 1594 | select MIPS_CPU_SCACHE | 1632 | select MIPS_CPU_SCACHE |
| 1633 | select MIPS_L1_CACHE_SHIFT_7 | ||
| 1595 | select SYS_SUPPORTS_SMP | 1634 | select SYS_SUPPORTS_SMP |
| 1596 | select SYS_SUPPORTS_HOTPLUG_CPU | 1635 | select SYS_SUPPORTS_HOTPLUG_CPU |
| 1597 | 1636 | ||
| @@ -1886,15 +1925,6 @@ config FORCE_MAX_ZONEORDER | |||
| 1886 | The page size is not necessarily 4KB. Keep this in mind | 1925 | The page size is not necessarily 4KB. Keep this in mind |
| 1887 | when choosing a value for this option. | 1926 | when choosing a value for this option. |
| 1888 | 1927 | ||
| 1889 | config CEVT_GIC | ||
| 1890 | bool "Use GIC global counter for clock events" | ||
| 1891 | depends on IRQ_GIC && !MIPS_SEAD3 | ||
| 1892 | help | ||
| 1893 | Use the GIC global counter for the clock events. The R4K clock | ||
| 1894 | event driver is always present, so if the platform ends up not | ||
| 1895 | detecting a GIC, it will fall back to the R4K timer for the | ||
| 1896 | generation of clock events. | ||
| 1897 | |||
| 1898 | config BOARD_SCACHE | 1928 | config BOARD_SCACHE |
| 1899 | bool | 1929 | bool |
| 1900 | 1930 | ||
| @@ -1908,7 +1938,6 @@ config IP22_CPU_SCACHE | |||
| 1908 | config MIPS_CPU_SCACHE | 1938 | config MIPS_CPU_SCACHE |
| 1909 | bool | 1939 | bool |
| 1910 | select BOARD_SCACHE | 1940 | select BOARD_SCACHE |
| 1911 | select MIPS_L1_CACHE_SHIFT_6 | ||
| 1912 | 1941 | ||
| 1913 | config R5000_CPU_SCACHE | 1942 | config R5000_CPU_SCACHE |
| 1914 | bool | 1943 | bool |
| @@ -2095,11 +2124,8 @@ config SB1_PASS_2_1_WORKAROUNDS | |||
| 2095 | default y | 2124 | default y |
| 2096 | 2125 | ||
| 2097 | 2126 | ||
| 2098 | config 64BIT_PHYS_ADDR | ||
| 2099 | bool | ||
| 2100 | |||
| 2101 | config ARCH_PHYS_ADDR_T_64BIT | 2127 | config ARCH_PHYS_ADDR_T_64BIT |
| 2102 | def_bool 64BIT_PHYS_ADDR | 2128 | bool |
| 2103 | 2129 | ||
| 2104 | choice | 2130 | choice |
| 2105 | prompt "SmartMIPS or microMIPS ASE support" | 2131 | prompt "SmartMIPS or microMIPS ASE support" |
| @@ -2122,7 +2148,7 @@ config CPU_HAS_SMARTMIPS | |||
| 2122 | here. | 2148 | here. |
| 2123 | 2149 | ||
| 2124 | config CPU_MICROMIPS | 2150 | config CPU_MICROMIPS |
| 2125 | depends on SYS_SUPPORTS_MICROMIPS | 2151 | depends on 32BIT && SYS_SUPPORTS_MICROMIPS |
| 2126 | bool "microMIPS" | 2152 | bool "microMIPS" |
| 2127 | help | 2153 | help |
| 2128 | When this option is enabled the kernel will be built using the | 2154 | When this option is enabled the kernel will be built using the |
diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug index 3a2b775e8458..88a9f433f6fc 100644 --- a/arch/mips/Kconfig.debug +++ b/arch/mips/Kconfig.debug | |||
| @@ -122,4 +122,17 @@ config SPINLOCK_TEST | |||
| 122 | help | 122 | help |
| 123 | Add several files to the debugfs to test spinlock speed. | 123 | Add several files to the debugfs to test spinlock speed. |
| 124 | 124 | ||
| 125 | config FP32XX_HYBRID_FPRS | ||
| 126 | bool "Run FP32 & FPXX code with hybrid FPRs" | ||
| 127 | depends on MIPS_O32_FP64_SUPPORT | ||
| 128 | help | ||
| 129 | The hybrid FPR scheme is normally used only when a program needs to | ||
| 130 | execute a mix of FP32 & FP64A code, since the trapping & emulation | ||
| 131 | that it entails is expensive. When enabled, this option will lead | ||
| 132 | to the kernel running programs which use the FP32 & FPXX FP ABIs | ||
| 133 | using the hybrid FPR scheme, which can be useful for debugging | ||
| 134 | purposes. | ||
| 135 | |||
| 136 | If unsure, say N. | ||
| 137 | |||
| 125 | endmenu | 138 | endmenu |
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 58076472bdd8..2563a088d3b8 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
| @@ -380,6 +380,7 @@ define archhelp | |||
| 380 | echo ' vmlinux.ecoff - ECOFF boot image' | 380 | echo ' vmlinux.ecoff - ECOFF boot image' |
| 381 | echo ' vmlinux.bin - Raw binary boot image' | 381 | echo ' vmlinux.bin - Raw binary boot image' |
| 382 | echo ' vmlinux.srec - SREC boot image' | 382 | echo ' vmlinux.srec - SREC boot image' |
| 383 | echo ' vmlinux.32 - 64-bit boot image wrapped in 32bits (IP22/IP32)' | ||
| 383 | echo ' vmlinuz - Compressed boot(zboot) image' | 384 | echo ' vmlinuz - Compressed boot(zboot) image' |
| 384 | echo ' vmlinuz.ecoff - ECOFF zboot image' | 385 | echo ' vmlinuz.ecoff - ECOFF zboot image' |
| 385 | echo ' vmlinuz.bin - Raw binary zboot image' | 386 | echo ' vmlinuz.bin - Raw binary zboot image' |
diff --git a/arch/mips/alchemy/common/clock.c b/arch/mips/alchemy/common/clock.c index d7557cde271a..203e4403c366 100644 --- a/arch/mips/alchemy/common/clock.c +++ b/arch/mips/alchemy/common/clock.c | |||
| @@ -37,7 +37,6 @@ | |||
| 37 | #include <linux/io.h> | 37 | #include <linux/io.h> |
| 38 | #include <linux/clk-provider.h> | 38 | #include <linux/clk-provider.h> |
| 39 | #include <linux/clkdev.h> | 39 | #include <linux/clkdev.h> |
| 40 | #include <linux/clk-private.h> | ||
| 41 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
| 42 | #include <linux/spinlock.h> | 41 | #include <linux/spinlock.h> |
| 43 | #include <linux/types.h> | 42 | #include <linux/types.h> |
| @@ -397,10 +396,10 @@ static long alchemy_clk_fgcs_detr(struct clk_hw *hw, unsigned long rate, | |||
| 397 | break; | 396 | break; |
| 398 | 397 | ||
| 399 | /* if this parent is currently unused, remember it. | 398 | /* if this parent is currently unused, remember it. |
| 400 | * XXX: I know it's a layering violation, but it works | 399 | * XXX: we would actually want clk_has_active_children() |
| 401 | * so well.. (if (!clk_has_active_children(pc)) ) | 400 | * but this is a good-enough approximation for now. |
| 402 | */ | 401 | */ |
| 403 | if (pc->prepare_count == 0) { | 402 | if (!__clk_is_prepared(pc)) { |
| 404 | if (!free) | 403 | if (!free) |
| 405 | free = pc; | 404 | free = pc; |
| 406 | } | 405 | } |
diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c index ea8f41869e56..4e72daf12c32 100644 --- a/arch/mips/alchemy/common/setup.c +++ b/arch/mips/alchemy/common/setup.c | |||
| @@ -70,9 +70,9 @@ void __init plat_mem_setup(void) | |||
| 70 | iomem_resource.end = IOMEM_RESOURCE_END; | 70 | iomem_resource.end = IOMEM_RESOURCE_END; |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_PCI) | 73 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_PCI) |
| 74 | /* This routine should be valid for all Au1x based boards */ | 74 | /* This routine should be valid for all Au1x based boards */ |
| 75 | phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) | 75 | phys_addr_t __fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) |
| 76 | { | 76 | { |
| 77 | unsigned long start = ALCHEMY_PCI_MEMWIN_START; | 77 | unsigned long start = ALCHEMY_PCI_MEMWIN_START; |
| 78 | unsigned long end = ALCHEMY_PCI_MEMWIN_END; | 78 | unsigned long end = ALCHEMY_PCI_MEMWIN_END; |
| @@ -83,7 +83,7 @@ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) | |||
| 83 | 83 | ||
| 84 | /* Check for PCI memory window */ | 84 | /* Check for PCI memory window */ |
| 85 | if (phys_addr >= start && (phys_addr + size - 1) <= end) | 85 | if (phys_addr >= start && (phys_addr + size - 1) <= end) |
| 86 | return (phys_t)(AU1500_PCI_MEM_PHYS_ADDR + phys_addr); | 86 | return (phys_addr_t)(AU1500_PCI_MEM_PHYS_ADDR + phys_addr); |
| 87 | 87 | ||
| 88 | /* default nop */ | 88 | /* default nop */ |
| 89 | return phys_addr; | 89 | return phys_addr; |
diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c index 7e2356fd5fd6..af2441dbfc12 100644 --- a/arch/mips/ar7/platform.c +++ b/arch/mips/ar7/platform.c | |||
| @@ -311,8 +311,7 @@ static void __init cpmac_get_mac(int instance, unsigned char *dev_addr) | |||
| 311 | &dev_addr[0], &dev_addr[1], | 311 | &dev_addr[0], &dev_addr[1], |
| 312 | &dev_addr[2], &dev_addr[3], | 312 | &dev_addr[2], &dev_addr[3], |
| 313 | &dev_addr[4], &dev_addr[5]) != 6) { | 313 | &dev_addr[4], &dev_addr[5]) != 6) { |
| 314 | pr_warning("cannot parse mac address, " | 314 | pr_warn("cannot parse mac address, using random address\n"); |
| 315 | "using random address\n"); | ||
| 316 | eth_random_addr(dev_addr); | 315 | eth_random_addr(dev_addr); |
| 317 | } | 316 | } |
| 318 | } else | 317 | } else |
| @@ -665,7 +664,7 @@ static int __init ar7_register_devices(void) | |||
| 665 | 664 | ||
| 666 | res = platform_device_register(&physmap_flash); | 665 | res = platform_device_register(&physmap_flash); |
| 667 | if (res) | 666 | if (res) |
| 668 | pr_warning("unable to register physmap-flash: %d\n", res); | 667 | pr_warn("unable to register physmap-flash: %d\n", res); |
| 669 | 668 | ||
| 670 | if (ar7_is_titan()) | 669 | if (ar7_is_titan()) |
| 671 | titan_fixup_devices(); | 670 | titan_fixup_devices(); |
| @@ -673,13 +672,13 @@ static int __init ar7_register_devices(void) | |||
| 673 | ar7_device_disable(vlynq_low_data.reset_bit); | 672 | ar7_device_disable(vlynq_low_data.reset_bit); |
| 674 | res = platform_device_register(&vlynq_low); | 673 | res = platform_device_register(&vlynq_low); |
| 675 | if (res) | 674 | if (res) |
| 676 | pr_warning("unable to register vlynq-low: %d\n", res); | 675 | pr_warn("unable to register vlynq-low: %d\n", res); |
| 677 | 676 | ||
| 678 | if (ar7_has_high_vlynq()) { | 677 | if (ar7_has_high_vlynq()) { |
| 679 | ar7_device_disable(vlynq_high_data.reset_bit); | 678 | ar7_device_disable(vlynq_high_data.reset_bit); |
| 680 | res = platform_device_register(&vlynq_high); | 679 | res = platform_device_register(&vlynq_high); |
| 681 | if (res) | 680 | if (res) |
| 682 | pr_warning("unable to register vlynq-high: %d\n", res); | 681 | pr_warn("unable to register vlynq-high: %d\n", res); |
| 683 | } | 682 | } |
| 684 | 683 | ||
| 685 | if (ar7_has_high_cpmac()) { | 684 | if (ar7_has_high_cpmac()) { |
| @@ -689,9 +688,10 @@ static int __init ar7_register_devices(void) | |||
| 689 | 688 | ||
| 690 | res = platform_device_register(&cpmac_high); | 689 | res = platform_device_register(&cpmac_high); |
| 691 | if (res) | 690 | if (res) |
| 692 | pr_warning("unable to register cpmac-high: %d\n", res); | 691 | pr_warn("unable to register cpmac-high: %d\n", |
| 692 | res); | ||
| 693 | } else | 693 | } else |
| 694 | pr_warning("unable to add cpmac-high phy: %d\n", res); | 694 | pr_warn("unable to add cpmac-high phy: %d\n", res); |
| 695 | } else | 695 | } else |
| 696 | cpmac_low_data.phy_mask = 0xffffffff; | 696 | cpmac_low_data.phy_mask = 0xffffffff; |
| 697 | 697 | ||
| @@ -700,18 +700,18 @@ static int __init ar7_register_devices(void) | |||
| 700 | cpmac_get_mac(0, cpmac_low_data.dev_addr); | 700 | cpmac_get_mac(0, cpmac_low_data.dev_addr); |
| 701 | res = platform_device_register(&cpmac_low); | 701 | res = platform_device_register(&cpmac_low); |
| 702 | if (res) | 702 | if (res) |
| 703 | pr_warning("unable to register cpmac-low: %d\n", res); | 703 | pr_warn("unable to register cpmac-low: %d\n", res); |
| 704 | } else | 704 | } else |
| 705 | pr_warning("unable to add cpmac-low phy: %d\n", res); | 705 | pr_warn("unable to add cpmac-low phy: %d\n", res); |
| 706 | 706 | ||
| 707 | detect_leds(); | 707 | detect_leds(); |
| 708 | res = platform_device_register(&ar7_gpio_leds); | 708 | res = platform_device_register(&ar7_gpio_leds); |
| 709 | if (res) | 709 | if (res) |
| 710 | pr_warning("unable to register leds: %d\n", res); | 710 | pr_warn("unable to register leds: %d\n", res); |
| 711 | 711 | ||
| 712 | res = platform_device_register(&ar7_udc); | 712 | res = platform_device_register(&ar7_udc); |
| 713 | if (res) | 713 | if (res) |
| 714 | pr_warning("unable to register usb slave: %d\n", res); | 714 | pr_warn("unable to register usb slave: %d\n", res); |
| 715 | 715 | ||
| 716 | /* Register watchdog only if enabled in hardware */ | 716 | /* Register watchdog only if enabled in hardware */ |
| 717 | bootcr = ioremap_nocache(AR7_REGS_DCL, 4); | 717 | bootcr = ioremap_nocache(AR7_REGS_DCL, 4); |
| @@ -726,7 +726,7 @@ static int __init ar7_register_devices(void) | |||
| 726 | ar7_wdt_res.end = ar7_wdt_res.start + 0x20; | 726 | ar7_wdt_res.end = ar7_wdt_res.start + 0x20; |
| 727 | res = platform_device_register(&ar7_wdt); | 727 | res = platform_device_register(&ar7_wdt); |
| 728 | if (res) | 728 | if (res) |
| 729 | pr_warning("unable to register watchdog: %d\n", res); | 729 | pr_warn("unable to register watchdog: %d\n", res); |
| 730 | } | 730 | } |
| 731 | 731 | ||
| 732 | return 0; | 732 | return 0; |
diff --git a/arch/mips/ath25/Kconfig b/arch/mips/ath25/Kconfig new file mode 100644 index 000000000000..fc19dd57e42d --- /dev/null +++ b/arch/mips/ath25/Kconfig | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | config SOC_AR5312 | ||
| 2 | bool "Atheros AR5312/AR2312+ SoC support" | ||
| 3 | depends on ATH25 | ||
| 4 | default y | ||
| 5 | |||
| 6 | config SOC_AR2315 | ||
| 7 | bool "Atheros AR2315+ SoC support" | ||
| 8 | depends on ATH25 | ||
| 9 | default y | ||
| 10 | |||
| 11 | config PCI_AR2315 | ||
| 12 | bool "Atheros AR2315 PCI controller support" | ||
| 13 | depends on SOC_AR2315 | ||
| 14 | select HW_HAS_PCI | ||
| 15 | select PCI | ||
| 16 | default y | ||
diff --git a/arch/mips/ath25/Makefile b/arch/mips/ath25/Makefile new file mode 100644 index 000000000000..eabad7da446a --- /dev/null +++ b/arch/mips/ath25/Makefile | |||
| @@ -0,0 +1,16 @@ | |||
| 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 | # Copyright (C) 2006 FON Technology, SL. | ||
| 7 | # Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> | ||
| 8 | # Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org> | ||
| 9 | # | ||
| 10 | |||
| 11 | obj-y += board.o prom.o devices.o | ||
| 12 | |||
| 13 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | ||
| 14 | |||
| 15 | obj-$(CONFIG_SOC_AR5312) += ar5312.o | ||
| 16 | obj-$(CONFIG_SOC_AR2315) += ar2315.o | ||
diff --git a/arch/mips/ath25/Platform b/arch/mips/ath25/Platform new file mode 100644 index 000000000000..ef3f81fa080b --- /dev/null +++ b/arch/mips/ath25/Platform | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | # | ||
| 2 | # Atheros AR531X/AR231X WiSoC | ||
| 3 | # | ||
| 4 | platform-$(CONFIG_ATH25) += ath25/ | ||
| 5 | cflags-$(CONFIG_ATH25) += -I$(srctree)/arch/mips/include/asm/mach-ath25 | ||
| 6 | load-$(CONFIG_ATH25) += 0xffffffff80041000 | ||
diff --git a/arch/mips/ath25/ar2315.c b/arch/mips/ath25/ar2315.c new file mode 100644 index 000000000000..2befa7d766a6 --- /dev/null +++ b/arch/mips/ath25/ar2315.c | |||
| @@ -0,0 +1,364 @@ | |||
| 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 | * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. | ||
| 7 | * Copyright (C) 2006 FON Technology, SL. | ||
| 8 | * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> | ||
| 9 | * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> | ||
| 10 | * Copyright (C) 2012 Alexandros C. Couloumbis <alex@ozo.com> | ||
| 11 | */ | ||
| 12 | |||
| 13 | /* | ||
| 14 | * Platform devices for Atheros AR2315 SoCs | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/init.h> | ||
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/bitops.h> | ||
| 20 | #include <linux/irqdomain.h> | ||
| 21 | #include <linux/interrupt.h> | ||
| 22 | #include <linux/platform_device.h> | ||
| 23 | #include <linux/reboot.h> | ||
| 24 | #include <asm/bootinfo.h> | ||
| 25 | #include <asm/reboot.h> | ||
| 26 | #include <asm/time.h> | ||
| 27 | |||
| 28 | #include <ath25_platform.h> | ||
| 29 | |||
| 30 | #include "devices.h" | ||
| 31 | #include "ar2315.h" | ||
| 32 | #include "ar2315_regs.h" | ||
| 33 | |||
| 34 | static void __iomem *ar2315_rst_base; | ||
| 35 | static struct irq_domain *ar2315_misc_irq_domain; | ||
| 36 | |||
| 37 | static inline u32 ar2315_rst_reg_read(u32 reg) | ||
| 38 | { | ||
| 39 | return __raw_readl(ar2315_rst_base + reg); | ||
| 40 | } | ||
| 41 | |||
| 42 | static inline void ar2315_rst_reg_write(u32 reg, u32 val) | ||
| 43 | { | ||
| 44 | __raw_writel(val, ar2315_rst_base + reg); | ||
| 45 | } | ||
| 46 | |||
| 47 | static inline void ar2315_rst_reg_mask(u32 reg, u32 mask, u32 val) | ||
| 48 | { | ||
| 49 | u32 ret = ar2315_rst_reg_read(reg); | ||
| 50 | |||
| 51 | ret &= ~mask; | ||
| 52 | ret |= val; | ||
| 53 | ar2315_rst_reg_write(reg, ret); | ||
| 54 | } | ||
| 55 | |||
| 56 | static irqreturn_t ar2315_ahb_err_handler(int cpl, void *dev_id) | ||
| 57 | { | ||
| 58 | ar2315_rst_reg_write(AR2315_AHB_ERR0, AR2315_AHB_ERROR_DET); | ||
| 59 | ar2315_rst_reg_read(AR2315_AHB_ERR1); | ||
| 60 | |||
| 61 | pr_emerg("AHB fatal error\n"); | ||
| 62 | machine_restart("AHB error"); /* Catastrophic failure */ | ||
| 63 | |||
| 64 | return IRQ_HANDLED; | ||
| 65 | } | ||
| 66 | |||
| 67 | static struct irqaction ar2315_ahb_err_interrupt = { | ||
| 68 | .handler = ar2315_ahb_err_handler, | ||
| 69 | .name = "ar2315-ahb-error", | ||
| 70 | }; | ||
| 71 | |||
| 72 | static void ar2315_misc_irq_handler(unsigned irq, struct irq_desc *desc) | ||
| 73 | { | ||
| 74 | u32 pending = ar2315_rst_reg_read(AR2315_ISR) & | ||
| 75 | ar2315_rst_reg_read(AR2315_IMR); | ||
| 76 | unsigned nr, misc_irq = 0; | ||
| 77 | |||
| 78 | if (pending) { | ||
| 79 | struct irq_domain *domain = irq_get_handler_data(irq); | ||
| 80 | |||
| 81 | nr = __ffs(pending); | ||
| 82 | misc_irq = irq_find_mapping(domain, nr); | ||
| 83 | } | ||
| 84 | |||
| 85 | if (misc_irq) { | ||
| 86 | if (nr == AR2315_MISC_IRQ_GPIO) | ||
| 87 | ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_GPIO); | ||
| 88 | else if (nr == AR2315_MISC_IRQ_WATCHDOG) | ||
| 89 | ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_WD); | ||
| 90 | generic_handle_irq(misc_irq); | ||
| 91 | } else { | ||
| 92 | spurious_interrupt(); | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | static void ar2315_misc_irq_unmask(struct irq_data *d) | ||
| 97 | { | ||
| 98 | ar2315_rst_reg_mask(AR2315_IMR, 0, BIT(d->hwirq)); | ||
| 99 | } | ||
| 100 | |||
| 101 | static void ar2315_misc_irq_mask(struct irq_data *d) | ||
| 102 | { | ||
| 103 | ar2315_rst_reg_mask(AR2315_IMR, BIT(d->hwirq), 0); | ||
| 104 | } | ||
| 105 | |||
| 106 | static struct irq_chip ar2315_misc_irq_chip = { | ||
| 107 | .name = "ar2315-misc", | ||
| 108 | .irq_unmask = ar2315_misc_irq_unmask, | ||
| 109 | .irq_mask = ar2315_misc_irq_mask, | ||
| 110 | }; | ||
| 111 | |||
| 112 | static int ar2315_misc_irq_map(struct irq_domain *d, unsigned irq, | ||
| 113 | irq_hw_number_t hw) | ||
| 114 | { | ||
| 115 | irq_set_chip_and_handler(irq, &ar2315_misc_irq_chip, handle_level_irq); | ||
| 116 | return 0; | ||
| 117 | } | ||
| 118 | |||
| 119 | static struct irq_domain_ops ar2315_misc_irq_domain_ops = { | ||
| 120 | .map = ar2315_misc_irq_map, | ||
| 121 | }; | ||
| 122 | |||
| 123 | /* | ||
| 124 | * Called when an interrupt is received, this function | ||
| 125 | * determines exactly which interrupt it was, and it | ||
| 126 | * invokes the appropriate handler. | ||
| 127 | * | ||
| 128 | * Implicitly, we also define interrupt priority by | ||
| 129 | * choosing which to dispatch first. | ||
| 130 | */ | ||
| 131 | static void ar2315_irq_dispatch(void) | ||
| 132 | { | ||
| 133 | u32 pending = read_c0_status() & read_c0_cause(); | ||
| 134 | |||
| 135 | if (pending & CAUSEF_IP3) | ||
| 136 | do_IRQ(AR2315_IRQ_WLAN0); | ||
| 137 | #ifdef CONFIG_PCI_AR2315 | ||
| 138 | else if (pending & CAUSEF_IP5) | ||
| 139 | do_IRQ(AR2315_IRQ_LCBUS_PCI); | ||
| 140 | #endif | ||
| 141 | else if (pending & CAUSEF_IP2) | ||
| 142 | do_IRQ(AR2315_IRQ_MISC); | ||
| 143 | else if (pending & CAUSEF_IP7) | ||
| 144 | do_IRQ(ATH25_IRQ_CPU_CLOCK); | ||
| 145 | else | ||
| 146 | spurious_interrupt(); | ||
| 147 | } | ||
| 148 | |||
| 149 | void __init ar2315_arch_init_irq(void) | ||
| 150 | { | ||
| 151 | struct irq_domain *domain; | ||
| 152 | unsigned irq; | ||
| 153 | |||
| 154 | ath25_irq_dispatch = ar2315_irq_dispatch; | ||
| 155 | |||
| 156 | domain = irq_domain_add_linear(NULL, AR2315_MISC_IRQ_COUNT, | ||
| 157 | &ar2315_misc_irq_domain_ops, NULL); | ||
| 158 | if (!domain) | ||
| 159 | panic("Failed to add IRQ domain"); | ||
| 160 | |||
| 161 | irq = irq_create_mapping(domain, AR2315_MISC_IRQ_AHB); | ||
| 162 | setup_irq(irq, &ar2315_ahb_err_interrupt); | ||
| 163 | |||
| 164 | irq_set_chained_handler(AR2315_IRQ_MISC, ar2315_misc_irq_handler); | ||
| 165 | irq_set_handler_data(AR2315_IRQ_MISC, domain); | ||
| 166 | |||
| 167 | ar2315_misc_irq_domain = domain; | ||
| 168 | } | ||
| 169 | |||
| 170 | void __init ar2315_init_devices(void) | ||
| 171 | { | ||
| 172 | /* Find board configuration */ | ||
| 173 | ath25_find_config(AR2315_SPI_READ_BASE, AR2315_SPI_READ_SIZE); | ||
| 174 | |||
| 175 | ath25_add_wmac(0, AR2315_WLAN0_BASE, AR2315_IRQ_WLAN0); | ||
| 176 | } | ||
| 177 | |||
| 178 | static void ar2315_restart(char *command) | ||
| 179 | { | ||
| 180 | void (*mips_reset_vec)(void) = (void *)0xbfc00000; | ||
| 181 | |||
| 182 | local_irq_disable(); | ||
| 183 | |||
| 184 | /* try reset the system via reset control */ | ||
| 185 | ar2315_rst_reg_write(AR2315_COLD_RESET, AR2317_RESET_SYSTEM); | ||
| 186 | |||
| 187 | /* Cold reset does not work on the AR2315/6, use the GPIO reset bits | ||
| 188 | * a workaround. Give it some time to attempt a gpio based hardware | ||
| 189 | * reset (atheros reference design workaround) */ | ||
| 190 | |||
| 191 | /* TODO: implement the GPIO reset workaround */ | ||
| 192 | |||
| 193 | /* Some boards (e.g. Senao EOC-2610) don't implement the reset logic | ||
| 194 | * workaround. Attempt to jump to the mips reset location - | ||
| 195 | * the boot loader itself might be able to recover the system */ | ||
| 196 | mips_reset_vec(); | ||
| 197 | } | ||
| 198 | |||
| 199 | /* | ||
| 200 | * This table is indexed by bits 5..4 of the CLOCKCTL1 register | ||
| 201 | * to determine the predevisor value. | ||
| 202 | */ | ||
| 203 | static int clockctl1_predivide_table[4] __initdata = { 1, 2, 4, 5 }; | ||
| 204 | static int pllc_divide_table[5] __initdata = { 2, 3, 4, 6, 3 }; | ||
| 205 | |||
| 206 | static unsigned __init ar2315_sys_clk(u32 clock_ctl) | ||
| 207 | { | ||
| 208 | unsigned int pllc_ctrl, cpu_div; | ||
| 209 | unsigned int pllc_out, refdiv, fdiv, divby2; | ||
| 210 | unsigned int clk_div; | ||
| 211 | |||
| 212 | pllc_ctrl = ar2315_rst_reg_read(AR2315_PLLC_CTL); | ||
| 213 | refdiv = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_REF_DIV); | ||
| 214 | refdiv = clockctl1_predivide_table[refdiv]; | ||
| 215 | fdiv = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_FDBACK_DIV); | ||
| 216 | divby2 = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_ADD_FDBACK_DIV) + 1; | ||
| 217 | pllc_out = (40000000 / refdiv) * (2 * divby2) * fdiv; | ||
| 218 | |||
| 219 | /* clkm input selected */ | ||
| 220 | switch (clock_ctl & AR2315_CPUCLK_CLK_SEL_M) { | ||
| 221 | case 0: | ||
| 222 | case 1: | ||
| 223 | clk_div = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_CLKM_DIV); | ||
| 224 | clk_div = pllc_divide_table[clk_div]; | ||
| 225 | break; | ||
| 226 | case 2: | ||
| 227 | clk_div = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_CLKC_DIV); | ||
| 228 | clk_div = pllc_divide_table[clk_div]; | ||
| 229 | break; | ||
| 230 | default: | ||
| 231 | pllc_out = 40000000; | ||
| 232 | clk_div = 1; | ||
| 233 | break; | ||
| 234 | } | ||
| 235 | |||
| 236 | cpu_div = ATH25_REG_MS(clock_ctl, AR2315_CPUCLK_CLK_DIV); | ||
| 237 | cpu_div = cpu_div * 2 ?: 1; | ||
| 238 | |||
| 239 | return pllc_out / (clk_div * cpu_div); | ||
| 240 | } | ||
| 241 | |||
| 242 | static inline unsigned ar2315_cpu_frequency(void) | ||
| 243 | { | ||
| 244 | return ar2315_sys_clk(ar2315_rst_reg_read(AR2315_CPUCLK)); | ||
| 245 | } | ||
| 246 | |||
| 247 | static inline unsigned ar2315_apb_frequency(void) | ||
| 248 | { | ||
| 249 | return ar2315_sys_clk(ar2315_rst_reg_read(AR2315_AMBACLK)); | ||
| 250 | } | ||
| 251 | |||
| 252 | void __init ar2315_plat_time_init(void) | ||
| 253 | { | ||
| 254 | mips_hpt_frequency = ar2315_cpu_frequency() / 2; | ||
| 255 | } | ||
| 256 | |||
| 257 | void __init ar2315_plat_mem_setup(void) | ||
| 258 | { | ||
| 259 | void __iomem *sdram_base; | ||
| 260 | u32 memsize, memcfg; | ||
| 261 | u32 devid; | ||
| 262 | u32 config; | ||
| 263 | |||
| 264 | /* Detect memory size */ | ||
| 265 | sdram_base = ioremap_nocache(AR2315_SDRAMCTL_BASE, | ||
| 266 | AR2315_SDRAMCTL_SIZE); | ||
| 267 | memcfg = __raw_readl(sdram_base + AR2315_MEM_CFG); | ||
| 268 | memsize = 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_DATA_WIDTH); | ||
| 269 | memsize <<= 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_COL_WIDTH); | ||
| 270 | memsize <<= 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_ROW_WIDTH); | ||
| 271 | memsize <<= 3; | ||
| 272 | add_memory_region(0, memsize, BOOT_MEM_RAM); | ||
| 273 | iounmap(sdram_base); | ||
| 274 | |||
| 275 | ar2315_rst_base = ioremap_nocache(AR2315_RST_BASE, AR2315_RST_SIZE); | ||
| 276 | |||
| 277 | /* Detect the hardware based on the device ID */ | ||
| 278 | devid = ar2315_rst_reg_read(AR2315_SREV) & AR2315_REV_CHIP; | ||
| 279 | switch (devid) { | ||
| 280 | case 0x91: /* Need to check */ | ||
| 281 | ath25_soc = ATH25_SOC_AR2318; | ||
| 282 | break; | ||
| 283 | case 0x90: | ||
| 284 | ath25_soc = ATH25_SOC_AR2317; | ||
| 285 | break; | ||
| 286 | case 0x87: | ||
| 287 | ath25_soc = ATH25_SOC_AR2316; | ||
| 288 | break; | ||
| 289 | case 0x86: | ||
| 290 | default: | ||
| 291 | ath25_soc = ATH25_SOC_AR2315; | ||
| 292 | break; | ||
| 293 | } | ||
| 294 | ath25_board.devid = devid; | ||
| 295 | |||
| 296 | /* Clear any lingering AHB errors */ | ||
| 297 | config = read_c0_config(); | ||
| 298 | write_c0_config(config & ~0x3); | ||
| 299 | ar2315_rst_reg_write(AR2315_AHB_ERR0, AR2315_AHB_ERROR_DET); | ||
| 300 | ar2315_rst_reg_read(AR2315_AHB_ERR1); | ||
| 301 | ar2315_rst_reg_write(AR2315_WDT_CTRL, AR2315_WDT_CTRL_IGNORE); | ||
| 302 | |||
| 303 | _machine_restart = ar2315_restart; | ||
| 304 | } | ||
| 305 | |||
| 306 | #ifdef CONFIG_PCI_AR2315 | ||
| 307 | static struct resource ar2315_pci_res[] = { | ||
| 308 | { | ||
| 309 | .name = "ar2315-pci-ctrl", | ||
| 310 | .flags = IORESOURCE_MEM, | ||
| 311 | .start = AR2315_PCI_BASE, | ||
| 312 | .end = AR2315_PCI_BASE + AR2315_PCI_SIZE - 1, | ||
| 313 | }, | ||
| 314 | { | ||
| 315 | .name = "ar2315-pci-ext", | ||
| 316 | .flags = IORESOURCE_MEM, | ||
| 317 | .start = AR2315_PCI_EXT_BASE, | ||
| 318 | .end = AR2315_PCI_EXT_BASE + AR2315_PCI_EXT_SIZE - 1, | ||
| 319 | }, | ||
| 320 | { | ||
| 321 | .name = "ar2315-pci", | ||
| 322 | .flags = IORESOURCE_IRQ, | ||
| 323 | .start = AR2315_IRQ_LCBUS_PCI, | ||
| 324 | .end = AR2315_IRQ_LCBUS_PCI, | ||
| 325 | }, | ||
| 326 | }; | ||
| 327 | #endif | ||
| 328 | |||
| 329 | void __init ar2315_arch_init(void) | ||
| 330 | { | ||
| 331 | unsigned irq = irq_create_mapping(ar2315_misc_irq_domain, | ||
| 332 | AR2315_MISC_IRQ_UART0); | ||
| 333 | |||
| 334 | ath25_serial_setup(AR2315_UART0_BASE, irq, ar2315_apb_frequency()); | ||
| 335 | |||
| 336 | #ifdef CONFIG_PCI_AR2315 | ||
| 337 | if (ath25_soc == ATH25_SOC_AR2315) { | ||
| 338 | /* Reset PCI DMA logic */ | ||
| 339 | ar2315_rst_reg_mask(AR2315_RESET, 0, AR2315_RESET_PCIDMA); | ||
| 340 | msleep(20); | ||
| 341 | ar2315_rst_reg_mask(AR2315_RESET, AR2315_RESET_PCIDMA, 0); | ||
| 342 | msleep(20); | ||
| 343 | |||
| 344 | /* Configure endians */ | ||
| 345 | ar2315_rst_reg_mask(AR2315_ENDIAN_CTL, 0, AR2315_CONFIG_PCIAHB | | ||
| 346 | AR2315_CONFIG_PCIAHB_BRIDGE); | ||
| 347 | |||
| 348 | /* Configure as PCI host with DMA */ | ||
| 349 | ar2315_rst_reg_write(AR2315_PCICLK, AR2315_PCICLK_PLLC_CLKM | | ||
| 350 | (AR2315_PCICLK_IN_FREQ_DIV_6 << | ||
| 351 | AR2315_PCICLK_DIV_S)); | ||
| 352 | ar2315_rst_reg_mask(AR2315_AHB_ARB_CTL, 0, AR2315_ARB_PCI); | ||
| 353 | ar2315_rst_reg_mask(AR2315_IF_CTL, AR2315_IF_PCI_CLK_MASK | | ||
| 354 | AR2315_IF_MASK, AR2315_IF_PCI | | ||
| 355 | AR2315_IF_PCI_HOST | AR2315_IF_PCI_INTR | | ||
| 356 | (AR2315_IF_PCI_CLK_OUTPUT_CLK << | ||
| 357 | AR2315_IF_PCI_CLK_SHIFT)); | ||
| 358 | |||
| 359 | platform_device_register_simple("ar2315-pci", -1, | ||
| 360 | ar2315_pci_res, | ||
| 361 | ARRAY_SIZE(ar2315_pci_res)); | ||
| 362 | } | ||
| 363 | #endif | ||
| 364 | } | ||
diff --git a/arch/mips/ath25/ar2315.h b/arch/mips/ath25/ar2315.h new file mode 100644 index 000000000000..877afe63eed5 --- /dev/null +++ b/arch/mips/ath25/ar2315.h | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | #ifndef __AR2315_H | ||
| 2 | #define __AR2315_H | ||
| 3 | |||
| 4 | #ifdef CONFIG_SOC_AR2315 | ||
| 5 | |||
| 6 | void ar2315_arch_init_irq(void); | ||
| 7 | void ar2315_init_devices(void); | ||
| 8 | void ar2315_plat_time_init(void); | ||
| 9 | void ar2315_plat_mem_setup(void); | ||
| 10 | void ar2315_arch_init(void); | ||
| 11 | |||
| 12 | #else | ||
| 13 | |||
| 14 | static inline void ar2315_arch_init_irq(void) {} | ||
| 15 | static inline void ar2315_init_devices(void) {} | ||
| 16 | static inline void ar2315_plat_time_init(void) {} | ||
| 17 | static inline void ar2315_plat_mem_setup(void) {} | ||
| 18 | static inline void ar2315_arch_init(void) {} | ||
| 19 | |||
| 20 | #endif | ||
| 21 | |||
| 22 | #endif /* __AR2315_H */ | ||
diff --git a/arch/mips/ath25/ar2315_regs.h b/arch/mips/ath25/ar2315_regs.h new file mode 100644 index 000000000000..16e86149cb74 --- /dev/null +++ b/arch/mips/ath25/ar2315_regs.h | |||
| @@ -0,0 +1,410 @@ | |||
| 1 | /* | ||
| 2 | * Register definitions for AR2315+ | ||
| 3 | * | ||
| 4 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 5 | * License. See the file "COPYING" in the main directory of this archive | ||
| 6 | * for more details. | ||
| 7 | * | ||
| 8 | * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. | ||
| 9 | * Copyright (C) 2006 FON Technology, SL. | ||
| 10 | * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> | ||
| 11 | * Copyright (C) 2006-2008 Felix Fietkau <nbd@openwrt.org> | ||
| 12 | */ | ||
| 13 | |||
| 14 | #ifndef __ASM_MACH_ATH25_AR2315_REGS_H | ||
| 15 | #define __ASM_MACH_ATH25_AR2315_REGS_H | ||
| 16 | |||
| 17 | /* | ||
| 18 | * IRQs | ||
| 19 | */ | ||
| 20 | #define AR2315_IRQ_MISC (MIPS_CPU_IRQ_BASE + 2) /* C0_CAUSE: 0x0400 */ | ||
| 21 | #define AR2315_IRQ_WLAN0 (MIPS_CPU_IRQ_BASE + 3) /* C0_CAUSE: 0x0800 */ | ||
| 22 | #define AR2315_IRQ_ENET0 (MIPS_CPU_IRQ_BASE + 4) /* C0_CAUSE: 0x1000 */ | ||
| 23 | #define AR2315_IRQ_LCBUS_PCI (MIPS_CPU_IRQ_BASE + 5) /* C0_CAUSE: 0x2000 */ | ||
| 24 | #define AR2315_IRQ_WLAN0_POLL (MIPS_CPU_IRQ_BASE + 6) /* C0_CAUSE: 0x4000 */ | ||
| 25 | |||
| 26 | /* | ||
| 27 | * Miscellaneous interrupts, which share IP2. | ||
| 28 | */ | ||
| 29 | #define AR2315_MISC_IRQ_UART0 0 | ||
| 30 | #define AR2315_MISC_IRQ_I2C_RSVD 1 | ||
| 31 | #define AR2315_MISC_IRQ_SPI 2 | ||
| 32 | #define AR2315_MISC_IRQ_AHB 3 | ||
| 33 | #define AR2315_MISC_IRQ_APB 4 | ||
| 34 | #define AR2315_MISC_IRQ_TIMER 5 | ||
| 35 | #define AR2315_MISC_IRQ_GPIO 6 | ||
| 36 | #define AR2315_MISC_IRQ_WATCHDOG 7 | ||
| 37 | #define AR2315_MISC_IRQ_IR_RSVD 8 | ||
| 38 | #define AR2315_MISC_IRQ_COUNT 9 | ||
| 39 | |||
| 40 | /* | ||
| 41 | * Address map | ||
| 42 | */ | ||
| 43 | #define AR2315_SPI_READ_BASE 0x08000000 /* SPI flash */ | ||
| 44 | #define AR2315_SPI_READ_SIZE 0x01000000 | ||
| 45 | #define AR2315_WLAN0_BASE 0x10000000 /* Wireless MMR */ | ||
| 46 | #define AR2315_PCI_BASE 0x10100000 /* PCI MMR */ | ||
| 47 | #define AR2315_PCI_SIZE 0x00001000 | ||
| 48 | #define AR2315_SDRAMCTL_BASE 0x10300000 /* SDRAM MMR */ | ||
| 49 | #define AR2315_SDRAMCTL_SIZE 0x00000020 | ||
| 50 | #define AR2315_LOCAL_BASE 0x10400000 /* Local bus MMR */ | ||
| 51 | #define AR2315_ENET0_BASE 0x10500000 /* Ethernet MMR */ | ||
| 52 | #define AR2315_RST_BASE 0x11000000 /* Reset control MMR */ | ||
| 53 | #define AR2315_RST_SIZE 0x00000100 | ||
| 54 | #define AR2315_UART0_BASE 0x11100000 /* UART MMR */ | ||
| 55 | #define AR2315_SPI_MMR_BASE 0x11300000 /* SPI flash MMR */ | ||
| 56 | #define AR2315_SPI_MMR_SIZE 0x00000010 | ||
| 57 | #define AR2315_PCI_EXT_BASE 0x80000000 /* PCI external */ | ||
| 58 | #define AR2315_PCI_EXT_SIZE 0x40000000 | ||
| 59 | |||
| 60 | /* | ||
| 61 | * Configuration registers | ||
| 62 | */ | ||
| 63 | |||
| 64 | /* Cold reset register */ | ||
| 65 | #define AR2315_COLD_RESET 0x0000 | ||
| 66 | |||
| 67 | #define AR2315_RESET_COLD_AHB 0x00000001 | ||
| 68 | #define AR2315_RESET_COLD_APB 0x00000002 | ||
| 69 | #define AR2315_RESET_COLD_CPU 0x00000004 | ||
| 70 | #define AR2315_RESET_COLD_CPUWARM 0x00000008 | ||
| 71 | #define AR2315_RESET_SYSTEM (RESET_COLD_CPU |\ | ||
| 72 | RESET_COLD_APB |\ | ||
| 73 | RESET_COLD_AHB) /* full system */ | ||
| 74 | #define AR2317_RESET_SYSTEM 0x00000010 | ||
| 75 | |||
| 76 | /* Reset register */ | ||
| 77 | #define AR2315_RESET 0x0004 | ||
| 78 | |||
| 79 | #define AR2315_RESET_WARM_WLAN0_MAC 0x00000001 /* warm reset WLAN0 MAC */ | ||
| 80 | #define AR2315_RESET_WARM_WLAN0_BB 0x00000002 /* warm reset WLAN0 BB */ | ||
| 81 | #define AR2315_RESET_MPEGTS_RSVD 0x00000004 /* warm reset MPEG-TS */ | ||
| 82 | #define AR2315_RESET_PCIDMA 0x00000008 /* warm reset PCI ahb/dma */ | ||
| 83 | #define AR2315_RESET_MEMCTL 0x00000010 /* warm reset mem control */ | ||
| 84 | #define AR2315_RESET_LOCAL 0x00000020 /* warm reset local bus */ | ||
| 85 | #define AR2315_RESET_I2C_RSVD 0x00000040 /* warm reset I2C bus */ | ||
| 86 | #define AR2315_RESET_SPI 0x00000080 /* warm reset SPI iface */ | ||
| 87 | #define AR2315_RESET_UART0 0x00000100 /* warm reset UART0 */ | ||
| 88 | #define AR2315_RESET_IR_RSVD 0x00000200 /* warm reset IR iface */ | ||
| 89 | #define AR2315_RESET_EPHY0 0x00000400 /* cold reset ENET0 phy */ | ||
| 90 | #define AR2315_RESET_ENET0 0x00000800 /* cold reset ENET0 MAC */ | ||
| 91 | |||
| 92 | /* AHB master arbitration control */ | ||
| 93 | #define AR2315_AHB_ARB_CTL 0x0008 | ||
| 94 | |||
| 95 | #define AR2315_ARB_CPU 0x00000001 /* CPU, default */ | ||
| 96 | #define AR2315_ARB_WLAN 0x00000002 /* WLAN */ | ||
| 97 | #define AR2315_ARB_MPEGTS_RSVD 0x00000004 /* MPEG-TS */ | ||
| 98 | #define AR2315_ARB_LOCAL 0x00000008 /* Local bus */ | ||
| 99 | #define AR2315_ARB_PCI 0x00000010 /* PCI bus */ | ||
| 100 | #define AR2315_ARB_ETHERNET 0x00000020 /* Ethernet */ | ||
| 101 | #define AR2315_ARB_RETRY 0x00000100 /* Retry policy (debug) */ | ||
| 102 | |||
| 103 | /* Config Register */ | ||
| 104 | #define AR2315_ENDIAN_CTL 0x000c | ||
| 105 | |||
| 106 | #define AR2315_CONFIG_AHB 0x00000001 /* EC-AHB bridge endian */ | ||
| 107 | #define AR2315_CONFIG_WLAN 0x00000002 /* WLAN byteswap */ | ||
| 108 | #define AR2315_CONFIG_MPEGTS_RSVD 0x00000004 /* MPEG-TS byteswap */ | ||
| 109 | #define AR2315_CONFIG_PCI 0x00000008 /* PCI byteswap */ | ||
| 110 | #define AR2315_CONFIG_MEMCTL 0x00000010 /* Mem controller endian */ | ||
| 111 | #define AR2315_CONFIG_LOCAL 0x00000020 /* Local bus byteswap */ | ||
| 112 | #define AR2315_CONFIG_ETHERNET 0x00000040 /* Ethernet byteswap */ | ||
| 113 | #define AR2315_CONFIG_MERGE 0x00000200 /* CPU write buffer merge */ | ||
| 114 | #define AR2315_CONFIG_CPU 0x00000400 /* CPU big endian */ | ||
| 115 | #define AR2315_CONFIG_BIG 0x00000400 | ||
| 116 | #define AR2315_CONFIG_PCIAHB 0x00000800 | ||
| 117 | #define AR2315_CONFIG_PCIAHB_BRIDGE 0x00001000 | ||
| 118 | #define AR2315_CONFIG_SPI 0x00008000 /* SPI byteswap */ | ||
| 119 | #define AR2315_CONFIG_CPU_DRAM 0x00010000 | ||
| 120 | #define AR2315_CONFIG_CPU_PCI 0x00020000 | ||
| 121 | #define AR2315_CONFIG_CPU_MMR 0x00040000 | ||
| 122 | |||
| 123 | /* NMI control */ | ||
| 124 | #define AR2315_NMI_CTL 0x0010 | ||
| 125 | |||
| 126 | #define AR2315_NMI_EN 1 | ||
| 127 | |||
| 128 | /* Revision Register - Initial value is 0x3010 (WMAC 3.0, AR231X 1.0). */ | ||
| 129 | #define AR2315_SREV 0x0014 | ||
| 130 | |||
| 131 | #define AR2315_REV_MAJ 0x000000f0 | ||
| 132 | #define AR2315_REV_MAJ_S 4 | ||
| 133 | #define AR2315_REV_MIN 0x0000000f | ||
| 134 | #define AR2315_REV_MIN_S 0 | ||
| 135 | #define AR2315_REV_CHIP (AR2315_REV_MAJ | AR2315_REV_MIN) | ||
| 136 | |||
| 137 | /* Interface Enable */ | ||
| 138 | #define AR2315_IF_CTL 0x0018 | ||
| 139 | |||
| 140 | #define AR2315_IF_MASK 0x00000007 | ||
| 141 | #define AR2315_IF_DISABLED 0 /* Disable all */ | ||
| 142 | #define AR2315_IF_PCI 1 /* PCI */ | ||
| 143 | #define AR2315_IF_TS_LOCAL 2 /* Local bus */ | ||
| 144 | #define AR2315_IF_ALL 3 /* Emulation only */ | ||
| 145 | #define AR2315_IF_LOCAL_HOST 0x00000008 | ||
| 146 | #define AR2315_IF_PCI_HOST 0x00000010 | ||
| 147 | #define AR2315_IF_PCI_INTR 0x00000020 | ||
| 148 | #define AR2315_IF_PCI_CLK_MASK 0x00030000 | ||
| 149 | #define AR2315_IF_PCI_CLK_INPUT 0 | ||
| 150 | #define AR2315_IF_PCI_CLK_OUTPUT_LOW 1 | ||
| 151 | #define AR2315_IF_PCI_CLK_OUTPUT_CLK 2 | ||
| 152 | #define AR2315_IF_PCI_CLK_OUTPUT_HIGH 3 | ||
| 153 | #define AR2315_IF_PCI_CLK_SHIFT 16 | ||
| 154 | |||
| 155 | /* APB Interrupt control */ | ||
| 156 | #define AR2315_ISR 0x0020 | ||
| 157 | #define AR2315_IMR 0x0024 | ||
| 158 | #define AR2315_GISR 0x0028 | ||
| 159 | |||
| 160 | #define AR2315_ISR_UART0 0x00000001 /* high speed UART */ | ||
| 161 | #define AR2315_ISR_I2C_RSVD 0x00000002 /* I2C bus */ | ||
| 162 | #define AR2315_ISR_SPI 0x00000004 /* SPI bus */ | ||
| 163 | #define AR2315_ISR_AHB 0x00000008 /* AHB error */ | ||
| 164 | #define AR2315_ISR_APB 0x00000010 /* APB error */ | ||
| 165 | #define AR2315_ISR_TIMER 0x00000020 /* Timer */ | ||
| 166 | #define AR2315_ISR_GPIO 0x00000040 /* GPIO */ | ||
| 167 | #define AR2315_ISR_WD 0x00000080 /* Watchdog */ | ||
| 168 | #define AR2315_ISR_IR_RSVD 0x00000100 /* IR */ | ||
| 169 | |||
| 170 | #define AR2315_GISR_MISC 0x00000001 /* Misc */ | ||
| 171 | #define AR2315_GISR_WLAN0 0x00000002 /* WLAN0 */ | ||
| 172 | #define AR2315_GISR_MPEGTS_RSVD 0x00000004 /* MPEG-TS */ | ||
| 173 | #define AR2315_GISR_LOCALPCI 0x00000008 /* Local/PCI bus */ | ||
| 174 | #define AR2315_GISR_WMACPOLL 0x00000010 | ||
| 175 | #define AR2315_GISR_TIMER 0x00000020 | ||
| 176 | #define AR2315_GISR_ETHERNET 0x00000040 /* Ethernet */ | ||
| 177 | |||
| 178 | /* Generic timer */ | ||
| 179 | #define AR2315_TIMER 0x0030 | ||
| 180 | #define AR2315_RELOAD 0x0034 | ||
| 181 | |||
| 182 | /* Watchdog timer */ | ||
| 183 | #define AR2315_WDT_TIMER 0x0038 | ||
| 184 | #define AR2315_WDT_CTRL 0x003c | ||
| 185 | |||
| 186 | #define AR2315_WDT_CTRL_IGNORE 0x00000000 /* ignore expiration */ | ||
| 187 | #define AR2315_WDT_CTRL_NMI 0x00000001 /* NMI on watchdog */ | ||
| 188 | #define AR2315_WDT_CTRL_RESET 0x00000002 /* reset on watchdog */ | ||
| 189 | |||
| 190 | /* CPU Performance Counters */ | ||
| 191 | #define AR2315_PERFCNT0 0x0048 | ||
| 192 | #define AR2315_PERFCNT1 0x004c | ||
| 193 | |||
| 194 | #define AR2315_PERF0_DATAHIT 0x00000001 /* Count Data Cache Hits */ | ||
| 195 | #define AR2315_PERF0_DATAMISS 0x00000002 /* Count Data Cache Misses */ | ||
| 196 | #define AR2315_PERF0_INSTHIT 0x00000004 /* Count Instruction Cache Hits */ | ||
| 197 | #define AR2315_PERF0_INSTMISS 0x00000008 /* Count Instruction Cache Misses */ | ||
| 198 | #define AR2315_PERF0_ACTIVE 0x00000010 /* Count Active Processor Cycles */ | ||
| 199 | #define AR2315_PERF0_WBHIT 0x00000020 /* Count CPU Write Buffer Hits */ | ||
| 200 | #define AR2315_PERF0_WBMISS 0x00000040 /* Count CPU Write Buffer Misses */ | ||
| 201 | |||
| 202 | #define AR2315_PERF1_EB_ARDY 0x00000001 /* Count EB_ARdy signal */ | ||
| 203 | #define AR2315_PERF1_EB_AVALID 0x00000002 /* Count EB_AValid signal */ | ||
| 204 | #define AR2315_PERF1_EB_WDRDY 0x00000004 /* Count EB_WDRdy signal */ | ||
| 205 | #define AR2315_PERF1_EB_RDVAL 0x00000008 /* Count EB_RdVal signal */ | ||
| 206 | #define AR2315_PERF1_VRADDR 0x00000010 /* Count valid read address cycles*/ | ||
| 207 | #define AR2315_PERF1_VWADDR 0x00000020 /* Count valid write address cycl.*/ | ||
| 208 | #define AR2315_PERF1_VWDATA 0x00000040 /* Count valid write data cycles */ | ||
| 209 | |||
| 210 | /* AHB Error Reporting */ | ||
| 211 | #define AR2315_AHB_ERR0 0x0050 /* error */ | ||
| 212 | #define AR2315_AHB_ERR1 0x0054 /* haddr */ | ||
| 213 | #define AR2315_AHB_ERR2 0x0058 /* hwdata */ | ||
| 214 | #define AR2315_AHB_ERR3 0x005c /* hrdata */ | ||
| 215 | #define AR2315_AHB_ERR4 0x0060 /* status */ | ||
| 216 | |||
| 217 | #define AR2315_AHB_ERROR_DET 1 /* AHB Error has been detected, */ | ||
| 218 | /* write 1 to clear all bits in ERR0 */ | ||
| 219 | #define AR2315_AHB_ERROR_OVR 2 /* AHB Error overflow has been detected */ | ||
| 220 | #define AR2315_AHB_ERROR_WDT 4 /* AHB Error due to wdt instead of hresp */ | ||
| 221 | |||
| 222 | #define AR2315_PROCERR_HMAST 0x0000000f | ||
| 223 | #define AR2315_PROCERR_HMAST_DFLT 0 | ||
| 224 | #define AR2315_PROCERR_HMAST_WMAC 1 | ||
| 225 | #define AR2315_PROCERR_HMAST_ENET 2 | ||
| 226 | #define AR2315_PROCERR_HMAST_PCIENDPT 3 | ||
| 227 | #define AR2315_PROCERR_HMAST_LOCAL 4 | ||
| 228 | #define AR2315_PROCERR_HMAST_CPU 5 | ||
| 229 | #define AR2315_PROCERR_HMAST_PCITGT 6 | ||
| 230 | #define AR2315_PROCERR_HMAST_S 0 | ||
| 231 | #define AR2315_PROCERR_HWRITE 0x00000010 | ||
| 232 | #define AR2315_PROCERR_HSIZE 0x00000060 | ||
| 233 | #define AR2315_PROCERR_HSIZE_S 5 | ||
| 234 | #define AR2315_PROCERR_HTRANS 0x00000180 | ||
| 235 | #define AR2315_PROCERR_HTRANS_S 7 | ||
| 236 | #define AR2315_PROCERR_HBURST 0x00000e00 | ||
| 237 | #define AR2315_PROCERR_HBURST_S 9 | ||
| 238 | |||
| 239 | /* Clock Control */ | ||
| 240 | #define AR2315_PLLC_CTL 0x0064 | ||
| 241 | #define AR2315_PLLV_CTL 0x0068 | ||
| 242 | #define AR2315_CPUCLK 0x006c | ||
| 243 | #define AR2315_AMBACLK 0x0070 | ||
| 244 | #define AR2315_SYNCCLK 0x0074 | ||
| 245 | #define AR2315_DSL_SLEEP_CTL 0x0080 | ||
| 246 | #define AR2315_DSL_SLEEP_DUR 0x0084 | ||
| 247 | |||
| 248 | /* PLLc Control fields */ | ||
| 249 | #define AR2315_PLLC_REF_DIV_M 0x00000003 | ||
| 250 | #define AR2315_PLLC_REF_DIV_S 0 | ||
| 251 | #define AR2315_PLLC_FDBACK_DIV_M 0x0000007c | ||
| 252 | #define AR2315_PLLC_FDBACK_DIV_S 2 | ||
| 253 | #define AR2315_PLLC_ADD_FDBACK_DIV_M 0x00000080 | ||
| 254 | #define AR2315_PLLC_ADD_FDBACK_DIV_S 7 | ||
| 255 | #define AR2315_PLLC_CLKC_DIV_M 0x0001c000 | ||
| 256 | #define AR2315_PLLC_CLKC_DIV_S 14 | ||
| 257 | #define AR2315_PLLC_CLKM_DIV_M 0x00700000 | ||
| 258 | #define AR2315_PLLC_CLKM_DIV_S 20 | ||
| 259 | |||
| 260 | /* CPU CLK Control fields */ | ||
| 261 | #define AR2315_CPUCLK_CLK_SEL_M 0x00000003 | ||
| 262 | #define AR2315_CPUCLK_CLK_SEL_S 0 | ||
| 263 | #define AR2315_CPUCLK_CLK_DIV_M 0x0000000c | ||
| 264 | #define AR2315_CPUCLK_CLK_DIV_S 2 | ||
| 265 | |||
| 266 | /* AMBA CLK Control fields */ | ||
| 267 | #define AR2315_AMBACLK_CLK_SEL_M 0x00000003 | ||
| 268 | #define AR2315_AMBACLK_CLK_SEL_S 0 | ||
| 269 | #define AR2315_AMBACLK_CLK_DIV_M 0x0000000c | ||
| 270 | #define AR2315_AMBACLK_CLK_DIV_S 2 | ||
| 271 | |||
| 272 | /* PCI Clock Control */ | ||
| 273 | #define AR2315_PCICLK 0x00a4 | ||
| 274 | |||
| 275 | #define AR2315_PCICLK_INPUT_M 0x00000003 | ||
| 276 | #define AR2315_PCICLK_INPUT_S 0 | ||
| 277 | #define AR2315_PCICLK_PLLC_CLKM 0 | ||
| 278 | #define AR2315_PCICLK_PLLC_CLKM1 1 | ||
| 279 | #define AR2315_PCICLK_PLLC_CLKC 2 | ||
| 280 | #define AR2315_PCICLK_REF_CLK 3 | ||
| 281 | #define AR2315_PCICLK_DIV_M 0x0000000c | ||
| 282 | #define AR2315_PCICLK_DIV_S 2 | ||
| 283 | #define AR2315_PCICLK_IN_FREQ 0 | ||
| 284 | #define AR2315_PCICLK_IN_FREQ_DIV_6 1 | ||
| 285 | #define AR2315_PCICLK_IN_FREQ_DIV_8 2 | ||
| 286 | #define AR2315_PCICLK_IN_FREQ_DIV_10 3 | ||
| 287 | |||
| 288 | /* Observation Control Register */ | ||
| 289 | #define AR2315_OCR 0x00b0 | ||
| 290 | |||
| 291 | #define AR2315_OCR_GPIO0_IRIN 0x00000040 | ||
| 292 | #define AR2315_OCR_GPIO1_IROUT 0x00000080 | ||
| 293 | #define AR2315_OCR_GPIO3_RXCLR 0x00000200 | ||
| 294 | |||
| 295 | /* General Clock Control */ | ||
| 296 | #define AR2315_MISCCLK 0x00b4 | ||
| 297 | |||
| 298 | #define AR2315_MISCCLK_PLLBYPASS_EN 0x00000001 | ||
| 299 | #define AR2315_MISCCLK_PROCREFCLK 0x00000002 | ||
| 300 | |||
| 301 | /* | ||
| 302 | * SDRAM Controller | ||
| 303 | * - No read or write buffers are included. | ||
| 304 | */ | ||
| 305 | #define AR2315_MEM_CFG 0x0000 | ||
| 306 | #define AR2315_MEM_CTRL 0x000c | ||
| 307 | #define AR2315_MEM_REF 0x0010 | ||
| 308 | |||
| 309 | #define AR2315_MEM_CFG_DATA_WIDTH_M 0x00006000 | ||
| 310 | #define AR2315_MEM_CFG_DATA_WIDTH_S 13 | ||
| 311 | #define AR2315_MEM_CFG_COL_WIDTH_M 0x00001e00 | ||
| 312 | #define AR2315_MEM_CFG_COL_WIDTH_S 9 | ||
| 313 | #define AR2315_MEM_CFG_ROW_WIDTH_M 0x000001e0 | ||
| 314 | #define AR2315_MEM_CFG_ROW_WIDTH_S 5 | ||
| 315 | #define AR2315_MEM_CFG_BANKADDR_BITS_M 0x00000018 | ||
| 316 | #define AR2315_MEM_CFG_BANKADDR_BITS_S 3 | ||
| 317 | |||
| 318 | /* | ||
| 319 | * Local Bus Interface Registers | ||
| 320 | */ | ||
| 321 | #define AR2315_LB_CONFIG 0x0000 | ||
| 322 | |||
| 323 | #define AR2315_LBCONF_OE 0x00000001 /* =1 OE is low-true */ | ||
| 324 | #define AR2315_LBCONF_CS0 0x00000002 /* =1 first CS is low-true */ | ||
| 325 | #define AR2315_LBCONF_CS1 0x00000004 /* =1 2nd CS is low-true */ | ||
| 326 | #define AR2315_LBCONF_RDY 0x00000008 /* =1 RDY is low-true */ | ||
| 327 | #define AR2315_LBCONF_WE 0x00000010 /* =1 Write En is low-true */ | ||
| 328 | #define AR2315_LBCONF_WAIT 0x00000020 /* =1 WAIT is low-true */ | ||
| 329 | #define AR2315_LBCONF_ADS 0x00000040 /* =1 Adr Strobe is low-true */ | ||
| 330 | #define AR2315_LBCONF_MOT 0x00000080 /* =0 Intel, =1 Motorola */ | ||
| 331 | #define AR2315_LBCONF_8CS 0x00000100 /* =1 8 bits CS, 0= 16bits */ | ||
| 332 | #define AR2315_LBCONF_8DS 0x00000200 /* =1 8 bits Data S, 0=16bits */ | ||
| 333 | #define AR2315_LBCONF_ADS_EN 0x00000400 /* =1 Enable ADS */ | ||
| 334 | #define AR2315_LBCONF_ADR_OE 0x00000800 /* =1 Adr cap on OE, WE or DS */ | ||
| 335 | #define AR2315_LBCONF_ADDT_MUX 0x00001000 /* =1 Adr and Data share bus */ | ||
| 336 | #define AR2315_LBCONF_DATA_OE 0x00002000 /* =1 Data cap on OE, WE, DS */ | ||
| 337 | #define AR2315_LBCONF_16DATA 0x00004000 /* =1 Data is 16 bits wide */ | ||
| 338 | #define AR2315_LBCONF_SWAPDT 0x00008000 /* =1 Byte swap data */ | ||
| 339 | #define AR2315_LBCONF_SYNC 0x00010000 /* =1 Bus synchronous to clk */ | ||
| 340 | #define AR2315_LBCONF_INT 0x00020000 /* =1 Intr is low true */ | ||
| 341 | #define AR2315_LBCONF_INT_CTR0 0x00000000 /* GND high-Z, Vdd is high-Z */ | ||
| 342 | #define AR2315_LBCONF_INT_CTR1 0x00040000 /* GND drive, Vdd is high-Z */ | ||
| 343 | #define AR2315_LBCONF_INT_CTR2 0x00080000 /* GND high-Z, Vdd drive */ | ||
| 344 | #define AR2315_LBCONF_INT_CTR3 0x000c0000 /* GND drive, Vdd drive */ | ||
| 345 | #define AR2315_LBCONF_RDY_WAIT 0x00100000 /* =1 RDY is negative of WAIT */ | ||
| 346 | #define AR2315_LBCONF_INT_PULSE 0x00200000 /* =1 Interrupt is a pulse */ | ||
| 347 | #define AR2315_LBCONF_ENABLE 0x00400000 /* =1 Falcon respond to LB */ | ||
| 348 | |||
| 349 | #define AR2315_LB_CLKSEL 0x0004 | ||
| 350 | |||
| 351 | #define AR2315_LBCLK_EXT 0x00000001 /* use external clk for lb */ | ||
| 352 | |||
| 353 | #define AR2315_LB_1MS 0x0008 | ||
| 354 | |||
| 355 | #define AR2315_LB1MS_MASK 0x0003ffff /* # of AHB clk cycles in 1ms */ | ||
| 356 | |||
| 357 | #define AR2315_LB_MISCCFG 0x000c | ||
| 358 | |||
| 359 | #define AR2315_LBM_TXD_EN 0x00000001 /* Enable TXD for fragments */ | ||
| 360 | #define AR2315_LBM_RX_INTEN 0x00000002 /* Enable LB ints on RX ready */ | ||
| 361 | #define AR2315_LBM_MBOXWR_INTEN 0x00000004 /* Enable LB ints on mbox wr */ | ||
| 362 | #define AR2315_LBM_MBOXRD_INTEN 0x00000008 /* Enable LB ints on mbox rd */ | ||
| 363 | #define AR2315_LMB_DESCSWAP_EN 0x00000010 /* Byte swap desc enable */ | ||
| 364 | #define AR2315_LBM_TIMEOUT_M 0x00ffff80 | ||
| 365 | #define AR2315_LBM_TIMEOUT_S 7 | ||
| 366 | #define AR2315_LBM_PORTMUX 0x07000000 | ||
| 367 | |||
| 368 | #define AR2315_LB_RXTSOFF 0x0010 | ||
| 369 | |||
| 370 | #define AR2315_LB_TX_CHAIN_EN 0x0100 | ||
| 371 | |||
| 372 | #define AR2315_LB_TXEN_0 0x00000001 | ||
| 373 | #define AR2315_LB_TXEN_1 0x00000002 | ||
| 374 | #define AR2315_LB_TXEN_2 0x00000004 | ||
| 375 | #define AR2315_LB_TXEN_3 0x00000008 | ||
| 376 | |||
| 377 | #define AR2315_LB_TX_CHAIN_DIS 0x0104 | ||
| 378 | #define AR2315_LB_TX_DESC_PTR 0x0200 | ||
| 379 | |||
| 380 | #define AR2315_LB_RX_CHAIN_EN 0x0400 | ||
| 381 | |||
| 382 | #define AR2315_LB_RXEN 0x00000001 | ||
| 383 | |||
| 384 | #define AR2315_LB_RX_CHAIN_DIS 0x0404 | ||
| 385 | #define AR2315_LB_RX_DESC_PTR 0x0408 | ||
| 386 | |||
| 387 | #define AR2315_LB_INT_STATUS 0x0500 | ||
| 388 | |||
| 389 | #define AR2315_LB_INT_TX_DESC 0x00000001 | ||
| 390 | #define AR2315_LB_INT_TX_OK 0x00000002 | ||
| 391 | #define AR2315_LB_INT_TX_ERR 0x00000004 | ||
| 392 | #define AR2315_LB_INT_TX_EOF 0x00000008 | ||
| 393 | #define AR2315_LB_INT_RX_DESC 0x00000010 | ||
| 394 | #define AR2315_LB_INT_RX_OK 0x00000020 | ||
| 395 | #define AR2315_LB_INT_RX_ERR 0x00000040 | ||
| 396 | #define AR2315_LB_INT_RX_EOF 0x00000080 | ||
| 397 | #define AR2315_LB_INT_TX_TRUNC 0x00000100 | ||
| 398 | #define AR2315_LB_INT_TX_STARVE 0x00000200 | ||
| 399 | #define AR2315_LB_INT_LB_TIMEOUT 0x00000400 | ||
| 400 | #define AR2315_LB_INT_LB_ERR 0x00000800 | ||
| 401 | #define AR2315_LB_INT_MBOX_WR 0x00001000 | ||
| 402 | #define AR2315_LB_INT_MBOX_RD 0x00002000 | ||
| 403 | |||
| 404 | /* Bit definitions for INT MASK are the same as INT_STATUS */ | ||
| 405 | #define AR2315_LB_INT_MASK 0x0504 | ||
| 406 | |||
| 407 | #define AR2315_LB_INT_EN 0x0508 | ||
| 408 | #define AR2315_LB_MBOX 0x0600 | ||
| 409 | |||
| 410 | #endif /* __ASM_MACH_ATH25_AR2315_REGS_H */ | ||
diff --git a/arch/mips/ath25/ar5312.c b/arch/mips/ath25/ar5312.c new file mode 100644 index 000000000000..b6887f75144c --- /dev/null +++ b/arch/mips/ath25/ar5312.c | |||
| @@ -0,0 +1,393 @@ | |||
| 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 | * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. | ||
| 7 | * Copyright (C) 2006 FON Technology, SL. | ||
| 8 | * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> | ||
| 9 | * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org> | ||
| 10 | * Copyright (C) 2012 Alexandros C. Couloumbis <alex@ozo.com> | ||
| 11 | */ | ||
| 12 | |||
| 13 | /* | ||
| 14 | * Platform devices for Atheros AR5312 SoCs | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/init.h> | ||
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/bitops.h> | ||
| 20 | #include <linux/irqdomain.h> | ||
| 21 | #include <linux/interrupt.h> | ||
| 22 | #include <linux/platform_device.h> | ||
| 23 | #include <linux/mtd/physmap.h> | ||
| 24 | #include <linux/reboot.h> | ||
| 25 | #include <asm/bootinfo.h> | ||
| 26 | #include <asm/reboot.h> | ||
| 27 | #include <asm/time.h> | ||
| 28 | |||
| 29 | #include <ath25_platform.h> | ||
| 30 | |||
| 31 | #include "devices.h" | ||
| 32 | #include "ar5312.h" | ||
| 33 | #include "ar5312_regs.h" | ||
| 34 | |||
| 35 | static void __iomem *ar5312_rst_base; | ||
| 36 | static struct irq_domain *ar5312_misc_irq_domain; | ||
| 37 | |||
| 38 | static inline u32 ar5312_rst_reg_read(u32 reg) | ||
| 39 | { | ||
| 40 | return __raw_readl(ar5312_rst_base + reg); | ||
| 41 | } | ||
| 42 | |||
| 43 | static inline void ar5312_rst_reg_write(u32 reg, u32 val) | ||
| 44 | { | ||
| 45 | __raw_writel(val, ar5312_rst_base + reg); | ||
| 46 | } | ||
| 47 | |||
| 48 | static inline void ar5312_rst_reg_mask(u32 reg, u32 mask, u32 val) | ||
| 49 | { | ||
| 50 | u32 ret = ar5312_rst_reg_read(reg); | ||
| 51 | |||
| 52 | ret &= ~mask; | ||
| 53 | ret |= val; | ||
| 54 | ar5312_rst_reg_write(reg, ret); | ||
| 55 | } | ||
| 56 | |||
| 57 | static irqreturn_t ar5312_ahb_err_handler(int cpl, void *dev_id) | ||
| 58 | { | ||
| 59 | u32 proc1 = ar5312_rst_reg_read(AR5312_PROC1); | ||
| 60 | u32 proc_addr = ar5312_rst_reg_read(AR5312_PROCADDR); /* clears error */ | ||
| 61 | u32 dma1 = ar5312_rst_reg_read(AR5312_DMA1); | ||
| 62 | u32 dma_addr = ar5312_rst_reg_read(AR5312_DMAADDR); /* clears error */ | ||
| 63 | |||
| 64 | pr_emerg("AHB interrupt: PROCADDR=0x%8.8x PROC1=0x%8.8x DMAADDR=0x%8.8x DMA1=0x%8.8x\n", | ||
| 65 | proc_addr, proc1, dma_addr, dma1); | ||
| 66 | |||
| 67 | machine_restart("AHB error"); /* Catastrophic failure */ | ||
| 68 | return IRQ_HANDLED; | ||
| 69 | } | ||
| 70 | |||
| 71 | static struct irqaction ar5312_ahb_err_interrupt = { | ||
| 72 | .handler = ar5312_ahb_err_handler, | ||
| 73 | .name = "ar5312-ahb-error", | ||
| 74 | }; | ||
| 75 | |||
| 76 | static void ar5312_misc_irq_handler(unsigned irq, struct irq_desc *desc) | ||
| 77 | { | ||
| 78 | u32 pending = ar5312_rst_reg_read(AR5312_ISR) & | ||
| 79 | ar5312_rst_reg_read(AR5312_IMR); | ||
| 80 | unsigned nr, misc_irq = 0; | ||
| 81 | |||
| 82 | if (pending) { | ||
| 83 | struct irq_domain *domain = irq_get_handler_data(irq); | ||
| 84 | |||
| 85 | nr = __ffs(pending); | ||
| 86 | misc_irq = irq_find_mapping(domain, nr); | ||
| 87 | } | ||
| 88 | |||
| 89 | if (misc_irq) { | ||
| 90 | generic_handle_irq(misc_irq); | ||
| 91 | if (nr == AR5312_MISC_IRQ_TIMER) | ||
| 92 | ar5312_rst_reg_read(AR5312_TIMER); | ||
| 93 | } else { | ||
| 94 | spurious_interrupt(); | ||
| 95 | } | ||
| 96 | } | ||
| 97 | |||
| 98 | /* Enable the specified AR5312_MISC_IRQ interrupt */ | ||
| 99 | static void ar5312_misc_irq_unmask(struct irq_data *d) | ||
| 100 | { | ||
| 101 | ar5312_rst_reg_mask(AR5312_IMR, 0, BIT(d->hwirq)); | ||
| 102 | } | ||
| 103 | |||
| 104 | /* Disable the specified AR5312_MISC_IRQ interrupt */ | ||
| 105 | static void ar5312_misc_irq_mask(struct irq_data *d) | ||
| 106 | { | ||
| 107 | ar5312_rst_reg_mask(AR5312_IMR, BIT(d->hwirq), 0); | ||
| 108 | ar5312_rst_reg_read(AR5312_IMR); /* flush write buffer */ | ||
| 109 | } | ||
| 110 | |||
| 111 | static struct irq_chip ar5312_misc_irq_chip = { | ||
| 112 | .name = "ar5312-misc", | ||
| 113 | .irq_unmask = ar5312_misc_irq_unmask, | ||
| 114 | .irq_mask = ar5312_misc_irq_mask, | ||
| 115 | }; | ||
| 116 | |||
| 117 | static int ar5312_misc_irq_map(struct irq_domain *d, unsigned irq, | ||
| 118 | irq_hw_number_t hw) | ||
| 119 | { | ||
| 120 | irq_set_chip_and_handler(irq, &ar5312_misc_irq_chip, handle_level_irq); | ||
| 121 | return 0; | ||
| 122 | } | ||
| 123 | |||
| 124 | static struct irq_domain_ops ar5312_misc_irq_domain_ops = { | ||
| 125 | .map = ar5312_misc_irq_map, | ||
| 126 | }; | ||
| 127 | |||
| 128 | static void ar5312_irq_dispatch(void) | ||
| 129 | { | ||
| 130 | u32 pending = read_c0_status() & read_c0_cause(); | ||
| 131 | |||
| 132 | if (pending & CAUSEF_IP2) | ||
| 133 | do_IRQ(AR5312_IRQ_WLAN0); | ||
| 134 | else if (pending & CAUSEF_IP5) | ||
| 135 | do_IRQ(AR5312_IRQ_WLAN1); | ||
| 136 | else if (pending & CAUSEF_IP6) | ||
| 137 | do_IRQ(AR5312_IRQ_MISC); | ||
| 138 | else if (pending & CAUSEF_IP7) | ||
| 139 | do_IRQ(ATH25_IRQ_CPU_CLOCK); | ||
| 140 | else | ||
| 141 | spurious_interrupt(); | ||
| 142 | } | ||
| 143 | |||
| 144 | void __init ar5312_arch_init_irq(void) | ||
| 145 | { | ||
| 146 | struct irq_domain *domain; | ||
| 147 | unsigned irq; | ||
| 148 | |||
| 149 | ath25_irq_dispatch = ar5312_irq_dispatch; | ||
| 150 | |||
| 151 | domain = irq_domain_add_linear(NULL, AR5312_MISC_IRQ_COUNT, | ||
| 152 | &ar5312_misc_irq_domain_ops, NULL); | ||
| 153 | if (!domain) | ||
| 154 | panic("Failed to add IRQ domain"); | ||
| 155 | |||
| 156 | irq = irq_create_mapping(domain, AR5312_MISC_IRQ_AHB_PROC); | ||
| 157 | setup_irq(irq, &ar5312_ahb_err_interrupt); | ||
| 158 | |||
| 159 | irq_set_chained_handler(AR5312_IRQ_MISC, ar5312_misc_irq_handler); | ||
| 160 | irq_set_handler_data(AR5312_IRQ_MISC, domain); | ||
| 161 | |||
| 162 | ar5312_misc_irq_domain = domain; | ||
| 163 | } | ||
| 164 | |||
| 165 | static struct physmap_flash_data ar5312_flash_data = { | ||
| 166 | .width = 2, | ||
| 167 | }; | ||
| 168 | |||
| 169 | static struct resource ar5312_flash_resource = { | ||
| 170 | .start = AR5312_FLASH_BASE, | ||
| 171 | .end = AR5312_FLASH_BASE + AR5312_FLASH_SIZE - 1, | ||
| 172 | .flags = IORESOURCE_MEM, | ||
| 173 | }; | ||
| 174 | |||
| 175 | static struct platform_device ar5312_physmap_flash = { | ||
| 176 | .name = "physmap-flash", | ||
| 177 | .id = 0, | ||
| 178 | .dev.platform_data = &ar5312_flash_data, | ||
| 179 | .resource = &ar5312_flash_resource, | ||
| 180 | .num_resources = 1, | ||
| 181 | }; | ||
| 182 | |||
| 183 | static void __init ar5312_flash_init(void) | ||
| 184 | { | ||
| 185 | void __iomem *flashctl_base; | ||
| 186 | u32 ctl; | ||
| 187 | |||
| 188 | flashctl_base = ioremap_nocache(AR5312_FLASHCTL_BASE, | ||
| 189 | AR5312_FLASHCTL_SIZE); | ||
| 190 | |||
| 191 | ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL0); | ||
| 192 | ctl &= AR5312_FLASHCTL_MW; | ||
| 193 | |||
| 194 | /* fixup flash width */ | ||
| 195 | switch (ctl) { | ||
| 196 | case AR5312_FLASHCTL_MW16: | ||
| 197 | ar5312_flash_data.width = 2; | ||
| 198 | break; | ||
| 199 | case AR5312_FLASHCTL_MW8: | ||
| 200 | default: | ||
| 201 | ar5312_flash_data.width = 1; | ||
| 202 | break; | ||
| 203 | } | ||
| 204 | |||
| 205 | /* | ||
| 206 | * Configure flash bank 0. | ||
| 207 | * Assume 8M window size. Flash will be aliased if it's smaller | ||
| 208 | */ | ||
| 209 | ctl |= AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC_8M | AR5312_FLASHCTL_RBLE; | ||
| 210 | ctl |= 0x01 << AR5312_FLASHCTL_IDCY_S; | ||
| 211 | ctl |= 0x07 << AR5312_FLASHCTL_WST1_S; | ||
| 212 | ctl |= 0x07 << AR5312_FLASHCTL_WST2_S; | ||
| 213 | __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL0); | ||
| 214 | |||
| 215 | /* Disable other flash banks */ | ||
| 216 | ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL1); | ||
| 217 | ctl &= ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC); | ||
| 218 | __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL1); | ||
| 219 | ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL2); | ||
| 220 | ctl &= ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC); | ||
| 221 | __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL2); | ||
| 222 | |||
| 223 | iounmap(flashctl_base); | ||
| 224 | } | ||
| 225 | |||
| 226 | void __init ar5312_init_devices(void) | ||
| 227 | { | ||
| 228 | struct ath25_boarddata *config; | ||
| 229 | |||
| 230 | ar5312_flash_init(); | ||
| 231 | |||
| 232 | /* Locate board/radio config data */ | ||
| 233 | ath25_find_config(AR5312_FLASH_BASE, AR5312_FLASH_SIZE); | ||
| 234 | config = ath25_board.config; | ||
| 235 | |||
| 236 | /* AR2313 has CPU minor rev. 10 */ | ||
| 237 | if ((current_cpu_data.processor_id & 0xff) == 0x0a) | ||
| 238 | ath25_soc = ATH25_SOC_AR2313; | ||
| 239 | |||
| 240 | /* AR2312 shares the same Silicon ID as AR5312 */ | ||
| 241 | else if (config->flags & BD_ISCASPER) | ||
| 242 | ath25_soc = ATH25_SOC_AR2312; | ||
| 243 | |||
| 244 | /* Everything else is probably AR5312 or compatible */ | ||
| 245 | else | ||
| 246 | ath25_soc = ATH25_SOC_AR5312; | ||
| 247 | |||
| 248 | platform_device_register(&ar5312_physmap_flash); | ||
| 249 | |||
| 250 | switch (ath25_soc) { | ||
| 251 | case ATH25_SOC_AR5312: | ||
| 252 | if (!ath25_board.radio) | ||
| 253 | return; | ||
| 254 | |||
| 255 | if (!(config->flags & BD_WLAN0)) | ||
| 256 | break; | ||
| 257 | |||
| 258 | ath25_add_wmac(0, AR5312_WLAN0_BASE, AR5312_IRQ_WLAN0); | ||
| 259 | break; | ||
| 260 | case ATH25_SOC_AR2312: | ||
| 261 | case ATH25_SOC_AR2313: | ||
| 262 | if (!ath25_board.radio) | ||
| 263 | return; | ||
| 264 | break; | ||
| 265 | default: | ||
| 266 | break; | ||
| 267 | } | ||
| 268 | |||
| 269 | if (config->flags & BD_WLAN1) | ||
| 270 | ath25_add_wmac(1, AR5312_WLAN1_BASE, AR5312_IRQ_WLAN1); | ||
| 271 | } | ||
| 272 | |||
| 273 | static void ar5312_restart(char *command) | ||
| 274 | { | ||
| 275 | /* reset the system */ | ||
| 276 | local_irq_disable(); | ||
| 277 | while (1) | ||
| 278 | ar5312_rst_reg_write(AR5312_RESET, AR5312_RESET_SYSTEM); | ||
| 279 | } | ||
| 280 | |||
| 281 | /* | ||
| 282 | * This table is indexed by bits 5..4 of the CLOCKCTL1 register | ||
| 283 | * to determine the predevisor value. | ||
| 284 | */ | ||
| 285 | static unsigned clockctl1_predivide_table[4] __initdata = { 1, 2, 4, 5 }; | ||
| 286 | |||
| 287 | static unsigned __init ar5312_cpu_frequency(void) | ||
| 288 | { | ||
| 289 | u32 scratch, devid, clock_ctl1; | ||
| 290 | u32 predivide_mask, multiplier_mask, doubler_mask; | ||
| 291 | unsigned predivide_shift, multiplier_shift; | ||
| 292 | unsigned predivide_select, predivisor, multiplier; | ||
| 293 | |||
| 294 | /* Trust the bootrom's idea of cpu frequency. */ | ||
| 295 | scratch = ar5312_rst_reg_read(AR5312_SCRATCH); | ||
| 296 | if (scratch) | ||
| 297 | return scratch; | ||
| 298 | |||
| 299 | devid = ar5312_rst_reg_read(AR5312_REV); | ||
| 300 | devid = (devid & AR5312_REV_MAJ) >> AR5312_REV_MAJ_S; | ||
| 301 | if (devid == AR5312_REV_MAJ_AR2313) { | ||
| 302 | predivide_mask = AR2313_CLOCKCTL1_PREDIVIDE_MASK; | ||
| 303 | predivide_shift = AR2313_CLOCKCTL1_PREDIVIDE_SHIFT; | ||
| 304 | multiplier_mask = AR2313_CLOCKCTL1_MULTIPLIER_MASK; | ||
| 305 | multiplier_shift = AR2313_CLOCKCTL1_MULTIPLIER_SHIFT; | ||
| 306 | doubler_mask = AR2313_CLOCKCTL1_DOUBLER_MASK; | ||
| 307 | } else { /* AR5312 and AR2312 */ | ||
| 308 | predivide_mask = AR5312_CLOCKCTL1_PREDIVIDE_MASK; | ||
| 309 | predivide_shift = AR5312_CLOCKCTL1_PREDIVIDE_SHIFT; | ||
| 310 | multiplier_mask = AR5312_CLOCKCTL1_MULTIPLIER_MASK; | ||
| 311 | multiplier_shift = AR5312_CLOCKCTL1_MULTIPLIER_SHIFT; | ||
| 312 | doubler_mask = AR5312_CLOCKCTL1_DOUBLER_MASK; | ||
| 313 | } | ||
| 314 | |||
| 315 | /* | ||
| 316 | * Clocking is derived from a fixed 40MHz input clock. | ||
| 317 | * | ||
| 318 | * cpu_freq = input_clock * MULT (where MULT is PLL multiplier) | ||
| 319 | * sys_freq = cpu_freq / 4 (used for APB clock, serial, | ||
| 320 | * flash, Timer, Watchdog Timer) | ||
| 321 | * | ||
| 322 | * cnt_freq = cpu_freq / 2 (use for CPU count/compare) | ||
| 323 | * | ||
| 324 | * So, for example, with a PLL multiplier of 5, we have | ||
| 325 | * | ||
| 326 | * cpu_freq = 200MHz | ||
| 327 | * sys_freq = 50MHz | ||
| 328 | * cnt_freq = 100MHz | ||
| 329 | * | ||
| 330 | * We compute the CPU frequency, based on PLL settings. | ||
| 331 | */ | ||
| 332 | |||
| 333 | clock_ctl1 = ar5312_rst_reg_read(AR5312_CLOCKCTL1); | ||
| 334 | predivide_select = (clock_ctl1 & predivide_mask) >> predivide_shift; | ||
| 335 | predivisor = clockctl1_predivide_table[predivide_select]; | ||
| 336 | multiplier = (clock_ctl1 & multiplier_mask) >> multiplier_shift; | ||
| 337 | |||
| 338 | if (clock_ctl1 & doubler_mask) | ||
| 339 | multiplier <<= 1; | ||
| 340 | |||
| 341 | return (40000000 / predivisor) * multiplier; | ||
| 342 | } | ||
| 343 | |||
| 344 | static inline unsigned ar5312_sys_frequency(void) | ||
| 345 | { | ||
| 346 | return ar5312_cpu_frequency() / 4; | ||
| 347 | } | ||
| 348 | |||
| 349 | void __init ar5312_plat_time_init(void) | ||
| 350 | { | ||
| 351 | mips_hpt_frequency = ar5312_cpu_frequency() / 2; | ||
| 352 | } | ||
| 353 | |||
| 354 | void __init ar5312_plat_mem_setup(void) | ||
| 355 | { | ||
| 356 | void __iomem *sdram_base; | ||
| 357 | u32 memsize, memcfg, bank0_ac, bank1_ac; | ||
| 358 | u32 devid; | ||
| 359 | |||
| 360 | /* Detect memory size */ | ||
| 361 | sdram_base = ioremap_nocache(AR5312_SDRAMCTL_BASE, | ||
| 362 | AR5312_SDRAMCTL_SIZE); | ||
| 363 | memcfg = __raw_readl(sdram_base + AR5312_MEM_CFG1); | ||
| 364 | bank0_ac = ATH25_REG_MS(memcfg, AR5312_MEM_CFG1_AC0); | ||
| 365 | bank1_ac = ATH25_REG_MS(memcfg, AR5312_MEM_CFG1_AC1); | ||
| 366 | memsize = (bank0_ac ? (1 << (bank0_ac + 1)) : 0) + | ||
| 367 | (bank1_ac ? (1 << (bank1_ac + 1)) : 0); | ||
| 368 | memsize <<= 20; | ||
| 369 | add_memory_region(0, memsize, BOOT_MEM_RAM); | ||
| 370 | iounmap(sdram_base); | ||
| 371 | |||
| 372 | ar5312_rst_base = ioremap_nocache(AR5312_RST_BASE, AR5312_RST_SIZE); | ||
| 373 | |||
| 374 | devid = ar5312_rst_reg_read(AR5312_REV); | ||
| 375 | devid >>= AR5312_REV_WMAC_MIN_S; | ||
| 376 | devid &= AR5312_REV_CHIP; | ||
| 377 | ath25_board.devid = (u16)devid; | ||
| 378 | |||
| 379 | /* Clear any lingering AHB errors */ | ||
| 380 | ar5312_rst_reg_read(AR5312_PROCADDR); | ||
| 381 | ar5312_rst_reg_read(AR5312_DMAADDR); | ||
| 382 | ar5312_rst_reg_write(AR5312_WDT_CTRL, AR5312_WDT_CTRL_IGNORE); | ||
| 383 | |||
| 384 | _machine_restart = ar5312_restart; | ||
| 385 | } | ||
| 386 | |||
| 387 | void __init ar5312_arch_init(void) | ||
| 388 | { | ||
| 389 | unsigned irq = irq_create_mapping(ar5312_misc_irq_domain, | ||
| 390 | AR5312_MISC_IRQ_UART0); | ||
| 391 | |||
| 392 | ath25_serial_setup(AR5312_UART0_BASE, irq, ar5312_sys_frequency()); | ||
| 393 | } | ||
diff --git a/arch/mips/ath25/ar5312.h b/arch/mips/ath25/ar5312.h new file mode 100644 index 000000000000..470abb0052bd --- /dev/null +++ b/arch/mips/ath25/ar5312.h | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | #ifndef __AR5312_H | ||
| 2 | #define __AR5312_H | ||
| 3 | |||
| 4 | #ifdef CONFIG_SOC_AR5312 | ||
| 5 | |||
| 6 | void ar5312_arch_init_irq(void); | ||
| 7 | void ar5312_init_devices(void); | ||
| 8 | void ar5312_plat_time_init(void); | ||
| 9 | void ar5312_plat_mem_setup(void); | ||
| 10 | void ar5312_arch_init(void); | ||
| 11 | |||
| 12 | #else | ||
| 13 | |||
| 14 | static inline void ar5312_arch_init_irq(void) {} | ||
| 15 | static inline void ar5312_init_devices(void) {} | ||
| 16 | static inline void ar5312_plat_time_init(void) {} | ||
| 17 | static inline void ar5312_plat_mem_setup(void) {} | ||
| 18 | static inline void ar5312_arch_init(void) {} | ||
| 19 | |||
| 20 | #endif | ||
| 21 | |||
| 22 | #endif /* __AR5312_H */ | ||
diff --git a/arch/mips/ath25/ar5312_regs.h b/arch/mips/ath25/ar5312_regs.h new file mode 100644 index 000000000000..4b947f967439 --- /dev/null +++ b/arch/mips/ath25/ar5312_regs.h | |||
| @@ -0,0 +1,224 @@ | |||
| 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 | * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. | ||
| 7 | * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> | ||
| 8 | * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef __ASM_MACH_ATH25_AR5312_REGS_H | ||
| 12 | #define __ASM_MACH_ATH25_AR5312_REGS_H | ||
| 13 | |||
| 14 | /* | ||
| 15 | * IRQs | ||
| 16 | */ | ||
| 17 | #define AR5312_IRQ_WLAN0 (MIPS_CPU_IRQ_BASE + 2) /* C0_CAUSE: 0x0400 */ | ||
| 18 | #define AR5312_IRQ_ENET0 (MIPS_CPU_IRQ_BASE + 3) /* C0_CAUSE: 0x0800 */ | ||
| 19 | #define AR5312_IRQ_ENET1 (MIPS_CPU_IRQ_BASE + 4) /* C0_CAUSE: 0x1000 */ | ||
| 20 | #define AR5312_IRQ_WLAN1 (MIPS_CPU_IRQ_BASE + 5) /* C0_CAUSE: 0x2000 */ | ||
| 21 | #define AR5312_IRQ_MISC (MIPS_CPU_IRQ_BASE + 6) /* C0_CAUSE: 0x4000 */ | ||
| 22 | |||
| 23 | /* | ||
| 24 | * Miscellaneous interrupts, which share IP6. | ||
| 25 | */ | ||
| 26 | #define AR5312_MISC_IRQ_TIMER 0 | ||
| 27 | #define AR5312_MISC_IRQ_AHB_PROC 1 | ||
| 28 | #define AR5312_MISC_IRQ_AHB_DMA 2 | ||
| 29 | #define AR5312_MISC_IRQ_GPIO 3 | ||
| 30 | #define AR5312_MISC_IRQ_UART0 4 | ||
| 31 | #define AR5312_MISC_IRQ_UART0_DMA 5 | ||
| 32 | #define AR5312_MISC_IRQ_WATCHDOG 6 | ||
| 33 | #define AR5312_MISC_IRQ_LOCAL 7 | ||
| 34 | #define AR5312_MISC_IRQ_SPI 8 | ||
| 35 | #define AR5312_MISC_IRQ_COUNT 9 | ||
| 36 | |||
| 37 | /* | ||
| 38 | * Address Map | ||
| 39 | * | ||
| 40 | * The AR5312 supports 2 enet MACS, even though many reference boards only | ||
| 41 | * actually use 1 of them (i.e. Only MAC 0 is actually connected to an enet | ||
| 42 | * PHY or PHY switch. The AR2312 supports 1 enet MAC. | ||
| 43 | */ | ||
| 44 | #define AR5312_WLAN0_BASE 0x18000000 | ||
| 45 | #define AR5312_ENET0_BASE 0x18100000 | ||
| 46 | #define AR5312_ENET1_BASE 0x18200000 | ||
| 47 | #define AR5312_SDRAMCTL_BASE 0x18300000 | ||
| 48 | #define AR5312_SDRAMCTL_SIZE 0x00000010 | ||
| 49 | #define AR5312_FLASHCTL_BASE 0x18400000 | ||
| 50 | #define AR5312_FLASHCTL_SIZE 0x00000010 | ||
| 51 | #define AR5312_WLAN1_BASE 0x18500000 | ||
| 52 | #define AR5312_UART0_BASE 0x1c000000 /* UART MMR */ | ||
| 53 | #define AR5312_GPIO_BASE 0x1c002000 | ||
| 54 | #define AR5312_GPIO_SIZE 0x00000010 | ||
| 55 | #define AR5312_RST_BASE 0x1c003000 | ||
| 56 | #define AR5312_RST_SIZE 0x00000100 | ||
| 57 | #define AR5312_FLASH_BASE 0x1e000000 | ||
| 58 | #define AR5312_FLASH_SIZE 0x00800000 | ||
| 59 | |||
| 60 | /* | ||
| 61 | * Need these defines to determine true number of ethernet MACs | ||
| 62 | */ | ||
| 63 | #define AR5312_AR5312_REV2 0x0052 /* AR5312 WMAC (AP31) */ | ||
| 64 | #define AR5312_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */ | ||
| 65 | #define AR5312_AR2313_REV8 0x0058 /* AR2313 WMAC (AP43-030) */ | ||
| 66 | |||
| 67 | /* Reset/Timer Block Address Map */ | ||
| 68 | #define AR5312_TIMER 0x0000 /* countdown timer */ | ||
| 69 | #define AR5312_RELOAD 0x0004 /* timer reload value */ | ||
| 70 | #define AR5312_WDT_CTRL 0x0008 /* watchdog cntrl */ | ||
| 71 | #define AR5312_WDT_TIMER 0x000c /* watchdog timer */ | ||
| 72 | #define AR5312_ISR 0x0010 /* Intr Status Reg */ | ||
| 73 | #define AR5312_IMR 0x0014 /* Intr Mask Reg */ | ||
| 74 | #define AR5312_RESET 0x0020 | ||
| 75 | #define AR5312_CLOCKCTL1 0x0064 | ||
| 76 | #define AR5312_SCRATCH 0x006c | ||
| 77 | #define AR5312_PROCADDR 0x0070 | ||
| 78 | #define AR5312_PROC1 0x0074 | ||
| 79 | #define AR5312_DMAADDR 0x0078 | ||
| 80 | #define AR5312_DMA1 0x007c | ||
| 81 | #define AR5312_ENABLE 0x0080 /* interface enb */ | ||
| 82 | #define AR5312_REV 0x0090 /* revision */ | ||
| 83 | |||
| 84 | /* AR5312_WDT_CTRL register bit field definitions */ | ||
| 85 | #define AR5312_WDT_CTRL_IGNORE 0x00000000 /* ignore expiration */ | ||
| 86 | #define AR5312_WDT_CTRL_NMI 0x00000001 | ||
| 87 | #define AR5312_WDT_CTRL_RESET 0x00000002 | ||
| 88 | |||
| 89 | /* AR5312_ISR register bit field definitions */ | ||
| 90 | #define AR5312_ISR_TIMER 0x00000001 | ||
| 91 | #define AR5312_ISR_AHBPROC 0x00000002 | ||
| 92 | #define AR5312_ISR_AHBDMA 0x00000004 | ||
| 93 | #define AR5312_ISR_GPIO 0x00000008 | ||
| 94 | #define AR5312_ISR_UART0 0x00000010 | ||
| 95 | #define AR5312_ISR_UART0DMA 0x00000020 | ||
| 96 | #define AR5312_ISR_WD 0x00000040 | ||
| 97 | #define AR5312_ISR_LOCAL 0x00000080 | ||
| 98 | |||
| 99 | /* AR5312_RESET register bit field definitions */ | ||
| 100 | #define AR5312_RESET_SYSTEM 0x00000001 /* cold reset full system */ | ||
| 101 | #define AR5312_RESET_PROC 0x00000002 /* cold reset MIPS core */ | ||
| 102 | #define AR5312_RESET_WLAN0 0x00000004 /* cold reset WLAN MAC/BB */ | ||
| 103 | #define AR5312_RESET_EPHY0 0x00000008 /* cold reset ENET0 phy */ | ||
| 104 | #define AR5312_RESET_EPHY1 0x00000010 /* cold reset ENET1 phy */ | ||
| 105 | #define AR5312_RESET_ENET0 0x00000020 /* cold reset ENET0 MAC */ | ||
| 106 | #define AR5312_RESET_ENET1 0x00000040 /* cold reset ENET1 MAC */ | ||
| 107 | #define AR5312_RESET_UART0 0x00000100 /* cold reset UART0 */ | ||
| 108 | #define AR5312_RESET_WLAN1 0x00000200 /* cold reset WLAN MAC/BB */ | ||
| 109 | #define AR5312_RESET_APB 0x00000400 /* cold reset APB ar5312 */ | ||
| 110 | #define AR5312_RESET_WARM_PROC 0x00001000 /* warm reset MIPS core */ | ||
| 111 | #define AR5312_RESET_WARM_WLAN0_MAC 0x00002000 /* warm reset WLAN0 MAC */ | ||
| 112 | #define AR5312_RESET_WARM_WLAN0_BB 0x00004000 /* warm reset WLAN0 BB */ | ||
| 113 | #define AR5312_RESET_NMI 0x00010000 /* send an NMI to the CPU */ | ||
| 114 | #define AR5312_RESET_WARM_WLAN1_MAC 0x00020000 /* warm reset WLAN1 MAC */ | ||
| 115 | #define AR5312_RESET_WARM_WLAN1_BB 0x00040000 /* warm reset WLAN1 BB */ | ||
| 116 | #define AR5312_RESET_LOCAL_BUS 0x00080000 /* reset local bus */ | ||
| 117 | #define AR5312_RESET_WDOG 0x00100000 /* last reset was a wdt */ | ||
| 118 | |||
| 119 | #define AR5312_RESET_WMAC0_BITS (AR5312_RESET_WLAN0 |\ | ||
| 120 | AR5312_RESET_WARM_WLAN0_MAC |\ | ||
| 121 | AR5312_RESET_WARM_WLAN0_BB) | ||
| 122 | |||
| 123 | #define AR5312_RESET_WMAC1_BITS (AR5312_RESET_WLAN1 |\ | ||
| 124 | AR5312_RESET_WARM_WLAN1_MAC |\ | ||
| 125 | AR5312_RESET_WARM_WLAN1_BB) | ||
| 126 | |||
| 127 | /* AR5312_CLOCKCTL1 register bit field definitions */ | ||
| 128 | #define AR5312_CLOCKCTL1_PREDIVIDE_MASK 0x00000030 | ||
| 129 | #define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT 4 | ||
| 130 | #define AR5312_CLOCKCTL1_MULTIPLIER_MASK 0x00001f00 | ||
| 131 | #define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT 8 | ||
| 132 | #define AR5312_CLOCKCTL1_DOUBLER_MASK 0x00010000 | ||
| 133 | |||
| 134 | /* Valid for AR5312 and AR2312 */ | ||
| 135 | #define AR5312_CLOCKCTL1_PREDIVIDE_MASK 0x00000030 | ||
| 136 | #define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT 4 | ||
| 137 | #define AR5312_CLOCKCTL1_MULTIPLIER_MASK 0x00001f00 | ||
| 138 | #define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT 8 | ||
| 139 | #define AR5312_CLOCKCTL1_DOUBLER_MASK 0x00010000 | ||
| 140 | |||
| 141 | /* Valid for AR2313 */ | ||
| 142 | #define AR2313_CLOCKCTL1_PREDIVIDE_MASK 0x00003000 | ||
| 143 | #define AR2313_CLOCKCTL1_PREDIVIDE_SHIFT 12 | ||
| 144 | #define AR2313_CLOCKCTL1_MULTIPLIER_MASK 0x001f0000 | ||
| 145 | #define AR2313_CLOCKCTL1_MULTIPLIER_SHIFT 16 | ||
| 146 | #define AR2313_CLOCKCTL1_DOUBLER_MASK 0x00000000 | ||
| 147 | |||
| 148 | /* AR5312_ENABLE register bit field definitions */ | ||
| 149 | #define AR5312_ENABLE_WLAN0 0x00000001 | ||
| 150 | #define AR5312_ENABLE_ENET0 0x00000002 | ||
| 151 | #define AR5312_ENABLE_ENET1 0x00000004 | ||
| 152 | #define AR5312_ENABLE_UART_AND_WLAN1_PIO 0x00000008/* UART & WLAN1 PIO */ | ||
| 153 | #define AR5312_ENABLE_WLAN1_DMA 0x00000010/* WLAN1 DMAs */ | ||
| 154 | #define AR5312_ENABLE_WLAN1 (AR5312_ENABLE_UART_AND_WLAN1_PIO |\ | ||
| 155 | AR5312_ENABLE_WLAN1_DMA) | ||
| 156 | |||
| 157 | /* AR5312_REV register bit field definitions */ | ||
| 158 | #define AR5312_REV_WMAC_MAJ 0x0000f000 | ||
| 159 | #define AR5312_REV_WMAC_MAJ_S 12 | ||
| 160 | #define AR5312_REV_WMAC_MIN 0x00000f00 | ||
| 161 | #define AR5312_REV_WMAC_MIN_S 8 | ||
| 162 | #define AR5312_REV_MAJ 0x000000f0 | ||
| 163 | #define AR5312_REV_MAJ_S 4 | ||
| 164 | #define AR5312_REV_MIN 0x0000000f | ||
| 165 | #define AR5312_REV_MIN_S 0 | ||
| 166 | #define AR5312_REV_CHIP (AR5312_REV_MAJ|AR5312_REV_MIN) | ||
| 167 | |||
| 168 | /* Major revision numbers, bits 7..4 of Revision ID register */ | ||
| 169 | #define AR5312_REV_MAJ_AR5312 0x4 | ||
| 170 | #define AR5312_REV_MAJ_AR2313 0x5 | ||
| 171 | |||
| 172 | /* Minor revision numbers, bits 3..0 of Revision ID register */ | ||
| 173 | #define AR5312_REV_MIN_DUAL 0x0 /* Dual WLAN version */ | ||
| 174 | #define AR5312_REV_MIN_SINGLE 0x1 /* Single WLAN version */ | ||
| 175 | |||
| 176 | /* | ||
| 177 | * ARM Flash Controller -- 3 flash banks with either x8 or x16 devices | ||
| 178 | */ | ||
| 179 | #define AR5312_FLASHCTL0 0x0000 | ||
| 180 | #define AR5312_FLASHCTL1 0x0004 | ||
| 181 | #define AR5312_FLASHCTL2 0x0008 | ||
| 182 | |||
| 183 | /* AR5312_FLASHCTL register bit field definitions */ | ||
| 184 | #define AR5312_FLASHCTL_IDCY 0x0000000f /* Idle cycle turnaround time */ | ||
| 185 | #define AR5312_FLASHCTL_IDCY_S 0 | ||
| 186 | #define AR5312_FLASHCTL_WST1 0x000003e0 /* Wait state 1 */ | ||
| 187 | #define AR5312_FLASHCTL_WST1_S 5 | ||
| 188 | #define AR5312_FLASHCTL_RBLE 0x00000400 /* Read byte lane enable */ | ||
| 189 | #define AR5312_FLASHCTL_WST2 0x0000f800 /* Wait state 2 */ | ||
| 190 | #define AR5312_FLASHCTL_WST2_S 11 | ||
| 191 | #define AR5312_FLASHCTL_AC 0x00070000 /* Flash addr check (added) */ | ||
| 192 | #define AR5312_FLASHCTL_AC_S 16 | ||
| 193 | #define AR5312_FLASHCTL_AC_128K 0x00000000 | ||
| 194 | #define AR5312_FLASHCTL_AC_256K 0x00010000 | ||
| 195 | #define AR5312_FLASHCTL_AC_512K 0x00020000 | ||
| 196 | #define AR5312_FLASHCTL_AC_1M 0x00030000 | ||
| 197 | #define AR5312_FLASHCTL_AC_2M 0x00040000 | ||
| 198 | #define AR5312_FLASHCTL_AC_4M 0x00050000 | ||
| 199 | #define AR5312_FLASHCTL_AC_8M 0x00060000 | ||
| 200 | #define AR5312_FLASHCTL_AC_RES 0x00070000 /* 16MB is not supported */ | ||
| 201 | #define AR5312_FLASHCTL_E 0x00080000 /* Flash bank enable (added) */ | ||
| 202 | #define AR5312_FLASHCTL_BUSERR 0x01000000 /* Bus transfer error flag */ | ||
| 203 | #define AR5312_FLASHCTL_WPERR 0x02000000 /* Write protect error flag */ | ||
| 204 | #define AR5312_FLASHCTL_WP 0x04000000 /* Write protect */ | ||
| 205 | #define AR5312_FLASHCTL_BM 0x08000000 /* Burst mode */ | ||
| 206 | #define AR5312_FLASHCTL_MW 0x30000000 /* Mem width */ | ||
| 207 | #define AR5312_FLASHCTL_MW8 0x00000000 /* Mem width x8 */ | ||
| 208 | #define AR5312_FLASHCTL_MW16 0x10000000 /* Mem width x16 */ | ||
| 209 | #define AR5312_FLASHCTL_MW32 0x20000000 /* Mem width x32 (not supp) */ | ||
| 210 | #define AR5312_FLASHCTL_ATNR 0x00000000 /* Access == no retry */ | ||
| 211 | #define AR5312_FLASHCTL_ATR 0x80000000 /* Access == retry every */ | ||
| 212 | #define AR5312_FLASHCTL_ATR4 0xc0000000 /* Access == retry every 4 */ | ||
| 213 | |||
| 214 | /* | ||
| 215 | * ARM SDRAM Controller -- just enough to determine memory size | ||
| 216 | */ | ||
| 217 | #define AR5312_MEM_CFG1 0x0004 | ||
| 218 | |||
| 219 | #define AR5312_MEM_CFG1_AC0_M 0x00000700 /* bank 0: SDRAM addr check */ | ||
| 220 | #define AR5312_MEM_CFG1_AC0_S 8 | ||
| 221 | #define AR5312_MEM_CFG1_AC1_M 0x00007000 /* bank 1: SDRAM addr check */ | ||
| 222 | #define AR5312_MEM_CFG1_AC1_S 12 | ||
| 223 | |||
| 224 | #endif /* __ASM_MACH_ATH25_AR5312_REGS_H */ | ||
diff --git a/arch/mips/ath25/board.c b/arch/mips/ath25/board.c new file mode 100644 index 000000000000..b8bb78282d6a --- /dev/null +++ b/arch/mips/ath25/board.c | |||
| @@ -0,0 +1,234 @@ | |||
| 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 | * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. | ||
| 7 | * Copyright (C) 2006 FON Technology, SL. | ||
| 8 | * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> | ||
| 9 | * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org> | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/init.h> | ||
| 13 | #include <linux/interrupt.h> | ||
| 14 | #include <asm/irq_cpu.h> | ||
| 15 | #include <asm/reboot.h> | ||
| 16 | #include <asm/bootinfo.h> | ||
| 17 | #include <asm/time.h> | ||
| 18 | |||
| 19 | #include <ath25_platform.h> | ||
| 20 | #include "devices.h" | ||
| 21 | #include "ar5312.h" | ||
| 22 | #include "ar2315.h" | ||
| 23 | |||
| 24 | void (*ath25_irq_dispatch)(void); | ||
| 25 | |||
| 26 | static inline bool check_radio_magic(const void __iomem *addr) | ||
| 27 | { | ||
| 28 | addr += 0x7a; /* offset for flash magic */ | ||
| 29 | return (__raw_readb(addr) == 0x5a) && (__raw_readb(addr + 1) == 0xa5); | ||
| 30 | } | ||
| 31 | |||
| 32 | static inline bool check_notempty(const void __iomem *addr) | ||
| 33 | { | ||
| 34 | return __raw_readl(addr) != 0xffffffff; | ||
| 35 | } | ||
| 36 | |||
| 37 | static inline bool check_board_data(const void __iomem *addr, bool broken) | ||
| 38 | { | ||
| 39 | /* config magic found */ | ||
| 40 | if (__raw_readl(addr) == ATH25_BD_MAGIC) | ||
| 41 | return true; | ||
| 42 | |||
| 43 | if (!broken) | ||
| 44 | return false; | ||
| 45 | |||
| 46 | /* broken board data detected, use radio data to find the | ||
| 47 | * offset, user will fix this */ | ||
| 48 | |||
| 49 | if (check_radio_magic(addr + 0x1000)) | ||
| 50 | return true; | ||
| 51 | if (check_radio_magic(addr + 0xf8)) | ||
| 52 | return true; | ||
| 53 | |||
| 54 | return false; | ||
| 55 | } | ||
| 56 | |||
| 57 | static const void __iomem * __init find_board_config(const void __iomem *limit, | ||
| 58 | const bool broken) | ||
| 59 | { | ||
| 60 | const void __iomem *addr; | ||
| 61 | const void __iomem *begin = limit - 0x1000; | ||
| 62 | const void __iomem *end = limit - 0x30000; | ||
| 63 | |||
| 64 | for (addr = begin; addr >= end; addr -= 0x1000) | ||
| 65 | if (check_board_data(addr, broken)) | ||
| 66 | return addr; | ||
| 67 | |||
| 68 | return NULL; | ||
| 69 | } | ||
| 70 | |||
| 71 | static const void __iomem * __init find_radio_config(const void __iomem *limit, | ||
| 72 | const void __iomem *bcfg) | ||
| 73 | { | ||
| 74 | const void __iomem *rcfg, *begin, *end; | ||
| 75 | |||
| 76 | /* | ||
| 77 | * Now find the start of Radio Configuration data, using heuristics: | ||
| 78 | * Search forward from Board Configuration data by 0x1000 bytes | ||
| 79 | * at a time until we find non-0xffffffff. | ||
| 80 | */ | ||
| 81 | begin = bcfg + 0x1000; | ||
| 82 | end = limit; | ||
| 83 | for (rcfg = begin; rcfg < end; rcfg += 0x1000) | ||
| 84 | if (check_notempty(rcfg) && check_radio_magic(rcfg)) | ||
| 85 | return rcfg; | ||
| 86 | |||
| 87 | /* AR2316 relocates radio config to new location */ | ||
| 88 | begin = bcfg + 0xf8; | ||
| 89 | end = limit - 0x1000 + 0xf8; | ||
| 90 | for (rcfg = begin; rcfg < end; rcfg += 0x1000) | ||
| 91 | if (check_notempty(rcfg) && check_radio_magic(rcfg)) | ||
| 92 | return rcfg; | ||
| 93 | |||
| 94 | return NULL; | ||
| 95 | } | ||
| 96 | |||
| 97 | /* | ||
| 98 | * NB: Search region size could be larger than the actual flash size, | ||
| 99 | * but this shouldn't be a problem here, because the flash | ||
| 100 | * will simply be mapped multiple times. | ||
| 101 | */ | ||
| 102 | int __init ath25_find_config(phys_addr_t base, unsigned long size) | ||
| 103 | { | ||
| 104 | const void __iomem *flash_base, *flash_limit; | ||
| 105 | struct ath25_boarddata *config; | ||
| 106 | unsigned int rcfg_size; | ||
| 107 | int broken_boarddata = 0; | ||
| 108 | const void __iomem *bcfg, *rcfg; | ||
| 109 | u8 *board_data; | ||
| 110 | u8 *radio_data; | ||
| 111 | u8 *mac_addr; | ||
| 112 | u32 offset; | ||
| 113 | |||
| 114 | flash_base = ioremap_nocache(base, size); | ||
| 115 | flash_limit = flash_base + size; | ||
| 116 | |||
| 117 | ath25_board.config = NULL; | ||
| 118 | ath25_board.radio = NULL; | ||
| 119 | |||
| 120 | /* Copy the board and radio data to RAM, because accessing the mapped | ||
| 121 | * memory of the flash directly after booting is not safe */ | ||
| 122 | |||
| 123 | /* Try to find valid board and radio data */ | ||
| 124 | bcfg = find_board_config(flash_limit, false); | ||
| 125 | |||
| 126 | /* If that fails, try to at least find valid radio data */ | ||
| 127 | if (!bcfg) { | ||
| 128 | bcfg = find_board_config(flash_limit, true); | ||
| 129 | broken_boarddata = 1; | ||
| 130 | } | ||
| 131 | |||
| 132 | if (!bcfg) { | ||
| 133 | pr_warn("WARNING: No board configuration data found!\n"); | ||
| 134 | goto error; | ||
| 135 | } | ||
| 136 | |||
| 137 | board_data = kzalloc(BOARD_CONFIG_BUFSZ, GFP_KERNEL); | ||
| 138 | ath25_board.config = (struct ath25_boarddata *)board_data; | ||
| 139 | memcpy_fromio(board_data, bcfg, 0x100); | ||
| 140 | if (broken_boarddata) { | ||
| 141 | pr_warn("WARNING: broken board data detected\n"); | ||
| 142 | config = ath25_board.config; | ||
| 143 | if (is_zero_ether_addr(config->enet0_mac)) { | ||
| 144 | pr_info("Fixing up empty mac addresses\n"); | ||
| 145 | config->reset_config_gpio = 0xffff; | ||
| 146 | config->sys_led_gpio = 0xffff; | ||
| 147 | random_ether_addr(config->wlan0_mac); | ||
| 148 | config->wlan0_mac[0] &= ~0x06; | ||
| 149 | random_ether_addr(config->enet0_mac); | ||
| 150 | random_ether_addr(config->enet1_mac); | ||
| 151 | } | ||
| 152 | } | ||
| 153 | |||
| 154 | /* Radio config starts 0x100 bytes after board config, regardless | ||
| 155 | * of what the physical layout on the flash chip looks like */ | ||
| 156 | |||
| 157 | rcfg = find_radio_config(flash_limit, bcfg); | ||
| 158 | if (!rcfg) { | ||
| 159 | pr_warn("WARNING: Could not find Radio Configuration data\n"); | ||
| 160 | goto error; | ||
| 161 | } | ||
| 162 | |||
| 163 | radio_data = board_data + 0x100 + ((rcfg - bcfg) & 0xfff); | ||
| 164 | ath25_board.radio = radio_data; | ||
| 165 | offset = radio_data - board_data; | ||
| 166 | pr_info("Radio config found at offset 0x%x (0x%x)\n", rcfg - bcfg, | ||
| 167 | offset); | ||
| 168 | rcfg_size = BOARD_CONFIG_BUFSZ - offset; | ||
| 169 | memcpy_fromio(radio_data, rcfg, rcfg_size); | ||
| 170 | |||
| 171 | mac_addr = &radio_data[0x1d * 2]; | ||
| 172 | if (is_broadcast_ether_addr(mac_addr)) { | ||
| 173 | pr_info("Radio MAC is blank; using board-data\n"); | ||
| 174 | ether_addr_copy(mac_addr, ath25_board.config->wlan0_mac); | ||
| 175 | } | ||
| 176 | |||
| 177 | iounmap(flash_base); | ||
| 178 | |||
| 179 | return 0; | ||
| 180 | |||
| 181 | error: | ||
| 182 | iounmap(flash_base); | ||
| 183 | return -ENODEV; | ||
| 184 | } | ||
| 185 | |||
| 186 | static void ath25_halt(void) | ||
| 187 | { | ||
| 188 | local_irq_disable(); | ||
| 189 | unreachable(); | ||
| 190 | } | ||
| 191 | |||
| 192 | void __init plat_mem_setup(void) | ||
| 193 | { | ||
| 194 | _machine_halt = ath25_halt; | ||
| 195 | pm_power_off = ath25_halt; | ||
| 196 | |||
| 197 | if (is_ar5312()) | ||
| 198 | ar5312_plat_mem_setup(); | ||
| 199 | else | ||
| 200 | ar2315_plat_mem_setup(); | ||
| 201 | |||
| 202 | /* Disable data watchpoints */ | ||
| 203 | write_c0_watchlo0(0); | ||
| 204 | } | ||
| 205 | |||
| 206 | asmlinkage void plat_irq_dispatch(void) | ||
| 207 | { | ||
| 208 | ath25_irq_dispatch(); | ||
| 209 | } | ||
| 210 | |||
| 211 | void __init plat_time_init(void) | ||
| 212 | { | ||
| 213 | if (is_ar5312()) | ||
| 214 | ar5312_plat_time_init(); | ||
| 215 | else | ||
| 216 | ar2315_plat_time_init(); | ||
| 217 | } | ||
| 218 | |||
| 219 | unsigned int __cpuinit get_c0_compare_int(void) | ||
| 220 | { | ||
| 221 | return CP0_LEGACY_COMPARE_IRQ; | ||
| 222 | } | ||
| 223 | |||
| 224 | void __init arch_init_irq(void) | ||
| 225 | { | ||
| 226 | clear_c0_status(ST0_IM); | ||
| 227 | mips_cpu_irq_init(); | ||
| 228 | |||
| 229 | /* Initialize interrupt controllers */ | ||
| 230 | if (is_ar5312()) | ||
| 231 | ar5312_arch_init_irq(); | ||
| 232 | else | ||
| 233 | ar2315_arch_init_irq(); | ||
| 234 | } | ||
diff --git a/arch/mips/ath25/devices.c b/arch/mips/ath25/devices.c new file mode 100644 index 000000000000..7a64567d1ac3 --- /dev/null +++ b/arch/mips/ath25/devices.c | |||
| @@ -0,0 +1,125 @@ | |||
| 1 | #include <linux/kernel.h> | ||
| 2 | #include <linux/init.h> | ||
| 3 | #include <linux/serial_8250.h> | ||
| 4 | #include <linux/platform_device.h> | ||
| 5 | #include <asm/bootinfo.h> | ||
| 6 | |||
| 7 | #include <ath25_platform.h> | ||
| 8 | #include "devices.h" | ||
| 9 | #include "ar5312.h" | ||
| 10 | #include "ar2315.h" | ||
| 11 | |||
| 12 | struct ar231x_board_config ath25_board; | ||
| 13 | enum ath25_soc_type ath25_soc = ATH25_SOC_UNKNOWN; | ||
| 14 | |||
| 15 | static struct resource ath25_wmac0_res[] = { | ||
| 16 | { | ||
| 17 | .name = "wmac0_membase", | ||
| 18 | .flags = IORESOURCE_MEM, | ||
| 19 | }, | ||
| 20 | { | ||
| 21 | .name = "wmac0_irq", | ||
| 22 | .flags = IORESOURCE_IRQ, | ||
| 23 | } | ||
| 24 | }; | ||
| 25 | |||
| 26 | static struct resource ath25_wmac1_res[] = { | ||
| 27 | { | ||
| 28 | .name = "wmac1_membase", | ||
| 29 | .flags = IORESOURCE_MEM, | ||
| 30 | }, | ||
| 31 | { | ||
| 32 | .name = "wmac1_irq", | ||
| 33 | .flags = IORESOURCE_IRQ, | ||
| 34 | } | ||
| 35 | }; | ||
| 36 | |||
| 37 | static struct platform_device ath25_wmac[] = { | ||
| 38 | { | ||
| 39 | .id = 0, | ||
| 40 | .name = "ar231x-wmac", | ||
| 41 | .resource = ath25_wmac0_res, | ||
| 42 | .num_resources = ARRAY_SIZE(ath25_wmac0_res), | ||
| 43 | .dev.platform_data = &ath25_board, | ||
| 44 | }, | ||
| 45 | { | ||
| 46 | .id = 1, | ||
| 47 | .name = "ar231x-wmac", | ||
| 48 | .resource = ath25_wmac1_res, | ||
| 49 | .num_resources = ARRAY_SIZE(ath25_wmac1_res), | ||
| 50 | .dev.platform_data = &ath25_board, | ||
| 51 | }, | ||
| 52 | }; | ||
| 53 | |||
| 54 | static const char * const soc_type_strings[] = { | ||
| 55 | [ATH25_SOC_AR5312] = "Atheros AR5312", | ||
| 56 | [ATH25_SOC_AR2312] = "Atheros AR2312", | ||
| 57 | [ATH25_SOC_AR2313] = "Atheros AR2313", | ||
| 58 | [ATH25_SOC_AR2315] = "Atheros AR2315", | ||
| 59 | [ATH25_SOC_AR2316] = "Atheros AR2316", | ||
| 60 | [ATH25_SOC_AR2317] = "Atheros AR2317", | ||
| 61 | [ATH25_SOC_AR2318] = "Atheros AR2318", | ||
| 62 | [ATH25_SOC_UNKNOWN] = "Atheros (unknown)", | ||
| 63 | }; | ||
| 64 | |||
| 65 | const char *get_system_type(void) | ||
| 66 | { | ||
| 67 | if ((ath25_soc >= ARRAY_SIZE(soc_type_strings)) || | ||
| 68 | !soc_type_strings[ath25_soc]) | ||
| 69 | return soc_type_strings[ATH25_SOC_UNKNOWN]; | ||
| 70 | return soc_type_strings[ath25_soc]; | ||
| 71 | } | ||
| 72 | |||
| 73 | void __init ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk) | ||
| 74 | { | ||
| 75 | struct uart_port s; | ||
| 76 | |||
| 77 | memset(&s, 0, sizeof(s)); | ||
| 78 | |||
| 79 | s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP; | ||
| 80 | s.iotype = UPIO_MEM32; | ||
| 81 | s.irq = irq; | ||
| 82 | s.regshift = 2; | ||
| 83 | s.mapbase = mapbase; | ||
| 84 | s.uartclk = uartclk; | ||
| 85 | |||
| 86 | early_serial_setup(&s); | ||
| 87 | } | ||
| 88 | |||
| 89 | int __init ath25_add_wmac(int nr, u32 base, int irq) | ||
| 90 | { | ||
| 91 | struct resource *res; | ||
| 92 | |||
| 93 | ath25_wmac[nr].dev.platform_data = &ath25_board; | ||
| 94 | res = &ath25_wmac[nr].resource[0]; | ||
| 95 | res->start = base; | ||
| 96 | res->end = base + 0x10000 - 1; | ||
| 97 | res++; | ||
| 98 | res->start = irq; | ||
| 99 | res->end = irq; | ||
| 100 | return platform_device_register(&ath25_wmac[nr]); | ||
| 101 | } | ||
| 102 | |||
| 103 | static int __init ath25_register_devices(void) | ||
| 104 | { | ||
| 105 | if (is_ar5312()) | ||
| 106 | ar5312_init_devices(); | ||
| 107 | else | ||
| 108 | ar2315_init_devices(); | ||
| 109 | |||
| 110 | return 0; | ||
| 111 | } | ||
| 112 | |||
| 113 | device_initcall(ath25_register_devices); | ||
| 114 | |||
| 115 | static int __init ath25_arch_init(void) | ||
| 116 | { | ||
| 117 | if (is_ar5312()) | ||
| 118 | ar5312_arch_init(); | ||
| 119 | else | ||
| 120 | ar2315_arch_init(); | ||
| 121 | |||
| 122 | return 0; | ||
| 123 | } | ||
| 124 | |||
| 125 | arch_initcall(ath25_arch_init); | ||
diff --git a/arch/mips/ath25/devices.h b/arch/mips/ath25/devices.h new file mode 100644 index 000000000000..04d414115356 --- /dev/null +++ b/arch/mips/ath25/devices.h | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | #ifndef __ATH25_DEVICES_H | ||
| 2 | #define __ATH25_DEVICES_H | ||
| 3 | |||
| 4 | #include <linux/cpu.h> | ||
| 5 | |||
| 6 | #define ATH25_REG_MS(_val, _field) (((_val) & _field##_M) >> _field##_S) | ||
| 7 | |||
| 8 | #define ATH25_IRQ_CPU_CLOCK (MIPS_CPU_IRQ_BASE + 7) /* C0_CAUSE: 0x8000 */ | ||
| 9 | |||
| 10 | enum ath25_soc_type { | ||
| 11 | /* handled by ar5312.c */ | ||
| 12 | ATH25_SOC_AR2312, | ||
| 13 | ATH25_SOC_AR2313, | ||
| 14 | ATH25_SOC_AR5312, | ||
| 15 | |||
| 16 | /* handled by ar2315.c */ | ||
| 17 | ATH25_SOC_AR2315, | ||
| 18 | ATH25_SOC_AR2316, | ||
| 19 | ATH25_SOC_AR2317, | ||
| 20 | ATH25_SOC_AR2318, | ||
| 21 | |||
| 22 | ATH25_SOC_UNKNOWN | ||
| 23 | }; | ||
| 24 | |||
| 25 | extern enum ath25_soc_type ath25_soc; | ||
| 26 | extern struct ar231x_board_config ath25_board; | ||
| 27 | extern void (*ath25_irq_dispatch)(void); | ||
| 28 | |||
| 29 | int ath25_find_config(phys_addr_t offset, unsigned long size); | ||
| 30 | void ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk); | ||
| 31 | int ath25_add_wmac(int nr, u32 base, int irq); | ||
| 32 | |||
| 33 | static inline bool is_ar2315(void) | ||
| 34 | { | ||
| 35 | return (current_cpu_data.cputype == CPU_4KEC); | ||
| 36 | } | ||
| 37 | |||
| 38 | static inline bool is_ar5312(void) | ||
| 39 | { | ||
| 40 | return !is_ar2315(); | ||
| 41 | } | ||
| 42 | |||
| 43 | #endif | ||
diff --git a/arch/mips/ath25/early_printk.c b/arch/mips/ath25/early_printk.c new file mode 100644 index 000000000000..36035b628161 --- /dev/null +++ b/arch/mips/ath25/early_printk.c | |||
| @@ -0,0 +1,44 @@ | |||
| 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 | * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/mm.h> | ||
| 10 | #include <linux/io.h> | ||
| 11 | #include <linux/serial_reg.h> | ||
| 12 | |||
| 13 | #include "devices.h" | ||
| 14 | #include "ar2315_regs.h" | ||
| 15 | #include "ar5312_regs.h" | ||
| 16 | |||
| 17 | static inline void prom_uart_wr(void __iomem *base, unsigned reg, | ||
| 18 | unsigned char ch) | ||
| 19 | { | ||
| 20 | __raw_writel(ch, base + 4 * reg); | ||
| 21 | } | ||
| 22 | |||
| 23 | static inline unsigned char prom_uart_rr(void __iomem *base, unsigned reg) | ||
| 24 | { | ||
| 25 | return __raw_readl(base + 4 * reg); | ||
| 26 | } | ||
| 27 | |||
| 28 | void prom_putchar(unsigned char ch) | ||
| 29 | { | ||
| 30 | static void __iomem *base; | ||
| 31 | |||
| 32 | if (unlikely(base == NULL)) { | ||
| 33 | if (is_ar2315()) | ||
| 34 | base = (void __iomem *)(KSEG1ADDR(AR2315_UART0_BASE)); | ||
| 35 | else | ||
| 36 | base = (void __iomem *)(KSEG1ADDR(AR5312_UART0_BASE)); | ||
| 37 | } | ||
| 38 | |||
| 39 | while ((prom_uart_rr(base, UART_LSR) & UART_LSR_THRE) == 0) | ||
| 40 | ; | ||
| 41 | prom_uart_wr(base, UART_TX, ch); | ||
| 42 | while ((prom_uart_rr(base, UART_LSR) & UART_LSR_THRE) == 0) | ||
| 43 | ; | ||
| 44 | } | ||
diff --git a/arch/mips/ath25/prom.c b/arch/mips/ath25/prom.c new file mode 100644 index 000000000000..edf82be8870d --- /dev/null +++ b/arch/mips/ath25/prom.c | |||
| @@ -0,0 +1,26 @@ | |||
| 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 | * Copyright MontaVista Software Inc | ||
| 7 | * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. | ||
| 8 | * Copyright (C) 2006 FON Technology, SL. | ||
| 9 | * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> | ||
| 10 | * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> | ||
| 11 | */ | ||
| 12 | |||
| 13 | /* | ||
| 14 | * Prom setup file for AR5312/AR231x SoCs | ||
| 15 | */ | ||
| 16 | |||
| 17 | #include <linux/init.h> | ||
| 18 | #include <asm/bootinfo.h> | ||
| 19 | |||
| 20 | void __init prom_init(void) | ||
| 21 | { | ||
| 22 | } | ||
| 23 | |||
| 24 | void __init prom_free_prom_memory(void) | ||
| 25 | { | ||
| 26 | } | ||
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c index 9c0e1761773f..6adae366f11a 100644 --- a/arch/mips/ath79/irq.c +++ b/arch/mips/ath79/irq.c | |||
| @@ -359,7 +359,6 @@ void __init arch_init_irq(void) | |||
| 359 | BUG(); | 359 | BUG(); |
| 360 | } | 360 | } |
| 361 | 361 | ||
| 362 | cp0_perfcount_irq = ATH79_MISC_IRQ(5); | ||
| 363 | mips_cpu_irq_init(); | 362 | mips_cpu_irq_init(); |
| 364 | ath79_misc_irq_init(); | 363 | ath79_misc_irq_init(); |
| 365 | 364 | ||
diff --git a/arch/mips/ath79/prom.c b/arch/mips/ath79/prom.c index e9cbd7c2918f..e1fe63051136 100644 --- a/arch/mips/ath79/prom.c +++ b/arch/mips/ath79/prom.c | |||
| @@ -13,42 +13,24 @@ | |||
| 13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
| 15 | #include <linux/string.h> | 15 | #include <linux/string.h> |
| 16 | #include <linux/initrd.h> | ||
| 16 | 17 | ||
| 17 | #include <asm/bootinfo.h> | 18 | #include <asm/bootinfo.h> |
| 18 | #include <asm/addrspace.h> | 19 | #include <asm/addrspace.h> |
| 20 | #include <asm/fw/fw.h> | ||
| 19 | 21 | ||
| 20 | #include "common.h" | 22 | #include "common.h" |
| 21 | 23 | ||
| 22 | static inline int is_valid_ram_addr(void *addr) | ||
| 23 | { | ||
| 24 | if (((u32) addr > KSEG0) && | ||
| 25 | ((u32) addr < (KSEG0 + ATH79_MEM_SIZE_MAX))) | ||
| 26 | return 1; | ||
| 27 | |||
| 28 | if (((u32) addr > KSEG1) && | ||
| 29 | ((u32) addr < (KSEG1 + ATH79_MEM_SIZE_MAX))) | ||
| 30 | return 1; | ||
| 31 | |||
| 32 | return 0; | ||
| 33 | } | ||
| 34 | |||
| 35 | static __init void ath79_prom_init_cmdline(int argc, char **argv) | ||
| 36 | { | ||
| 37 | int i; | ||
| 38 | |||
| 39 | if (!is_valid_ram_addr(argv)) | ||
| 40 | return; | ||
| 41 | |||
| 42 | for (i = 0; i < argc; i++) | ||
| 43 | if (is_valid_ram_addr(argv[i])) { | ||
| 44 | strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); | ||
| 45 | strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline)); | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 49 | void __init prom_init(void) | 24 | void __init prom_init(void) |
| 50 | { | 25 | { |
| 51 | ath79_prom_init_cmdline(fw_arg0, (char **)fw_arg1); | 26 | fw_init_cmdline(); |
| 27 | |||
| 28 | /* Read the initrd address from the firmware environment */ | ||
| 29 | initrd_start = fw_getenvl("initrd_start"); | ||
| 30 | if (initrd_start) { | ||
| 31 | initrd_start = KSEG0ADDR(initrd_start); | ||
| 32 | initrd_end = initrd_start + fw_getenvl("initrd_size"); | ||
| 33 | } | ||
| 52 | } | 34 | } |
| 53 | 35 | ||
| 54 | void __init prom_free_prom_memory(void) | 36 | void __init prom_free_prom_memory(void) |
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c index 64807a4809d0..a73c93c3d44a 100644 --- a/arch/mips/ath79/setup.c +++ b/arch/mips/ath79/setup.c | |||
| @@ -182,6 +182,11 @@ const char *get_system_type(void) | |||
| 182 | return ath79_sys_type; | 182 | return ath79_sys_type; |
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | int get_c0_perfcount_int(void) | ||
| 186 | { | ||
| 187 | return ATH79_MISC_IRQ(5); | ||
| 188 | } | ||
| 189 | |||
| 185 | unsigned int get_c0_compare_int(void) | 190 | unsigned int get_c0_compare_int(void) |
| 186 | { | 191 | { |
| 187 | return CP0_LEGACY_COMPARE_IRQ; | 192 | return CP0_LEGACY_COMPARE_IRQ; |
diff --git a/arch/mips/bcm3384/Makefile b/arch/mips/bcm3384/Makefile new file mode 100644 index 000000000000..a393955cba08 --- /dev/null +++ b/arch/mips/bcm3384/Makefile | |||
| @@ -0,0 +1 @@ | |||
| obj-y += setup.o irq.o dma.o | |||
diff --git a/arch/mips/bcm3384/Platform b/arch/mips/bcm3384/Platform new file mode 100644 index 000000000000..8e1ca0819e1b --- /dev/null +++ b/arch/mips/bcm3384/Platform | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | # | ||
| 2 | # Broadcom BCM3384 boards | ||
| 3 | # | ||
| 4 | platform-$(CONFIG_BCM3384) += bcm3384/ | ||
| 5 | cflags-$(CONFIG_BCM3384) += \ | ||
| 6 | -I$(srctree)/arch/mips/include/asm/mach-bcm3384/ | ||
| 7 | load-$(CONFIG_BCM3384) := 0xffffffff80010000 | ||
diff --git a/arch/mips/bcm3384/dma.c b/arch/mips/bcm3384/dma.c new file mode 100644 index 000000000000..ea42012fd4f5 --- /dev/null +++ b/arch/mips/bcm3384/dma.c | |||
| @@ -0,0 +1,81 @@ | |||
| 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 | * Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/device.h> | ||
| 10 | #include <linux/dma-direction.h> | ||
| 11 | #include <linux/dma-mapping.h> | ||
| 12 | #include <linux/init.h> | ||
| 13 | #include <linux/mm.h> | ||
| 14 | #include <linux/of.h> | ||
| 15 | #include <linux/pci.h> | ||
| 16 | #include <linux/types.h> | ||
| 17 | #include <dma-coherence.h> | ||
| 18 | |||
| 19 | /* | ||
| 20 | * BCM3384 has configurable address translation windows which allow the | ||
| 21 | * peripherals' DMA addresses to be different from the Zephyr-visible | ||
| 22 | * physical addresses. e.g. usb_dma_addr = zephyr_pa ^ 0x08000000 | ||
| 23 | * | ||
| 24 | * If our DT "memory" node has a "dma-xor-mask" property we will enable this | ||
| 25 | * translation using the provided offset. | ||
| 26 | */ | ||
| 27 | static u32 bcm3384_dma_xor_mask; | ||
| 28 | static u32 bcm3384_dma_xor_limit = 0xffffffff; | ||
| 29 | |||
| 30 | /* | ||
| 31 | * PCI collapses the memory hole at 0x10000000 - 0x1fffffff. | ||
| 32 | * On systems with a dma-xor-mask, this range is guaranteed to live above | ||
| 33 | * the dma-xor-limit. | ||
| 34 | */ | ||
| 35 | #define BCM3384_MEM_HOLE_PA 0x10000000 | ||
| 36 | #define BCM3384_MEM_HOLE_SIZE 0x10000000 | ||
| 37 | |||
| 38 | static dma_addr_t bcm3384_phys_to_dma(struct device *dev, phys_addr_t pa) | ||
| 39 | { | ||
| 40 | if (dev && dev_is_pci(dev) && | ||
| 41 | pa >= (BCM3384_MEM_HOLE_PA + BCM3384_MEM_HOLE_SIZE)) | ||
| 42 | return pa - BCM3384_MEM_HOLE_SIZE; | ||
| 43 | if (pa <= bcm3384_dma_xor_limit) | ||
| 44 | return pa ^ bcm3384_dma_xor_mask; | ||
| 45 | return pa; | ||
| 46 | } | ||
| 47 | |||
| 48 | dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size) | ||
| 49 | { | ||
| 50 | return bcm3384_phys_to_dma(dev, virt_to_phys(addr)); | ||
| 51 | } | ||
| 52 | |||
| 53 | dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page) | ||
| 54 | { | ||
| 55 | return bcm3384_phys_to_dma(dev, page_to_phys(page)); | ||
| 56 | } | ||
| 57 | |||
| 58 | unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) | ||
| 59 | { | ||
| 60 | if (dev && dev_is_pci(dev) && | ||
| 61 | dma_addr >= BCM3384_MEM_HOLE_PA) | ||
| 62 | return dma_addr + BCM3384_MEM_HOLE_SIZE; | ||
| 63 | if ((dma_addr ^ bcm3384_dma_xor_mask) <= bcm3384_dma_xor_limit) | ||
| 64 | return dma_addr ^ bcm3384_dma_xor_mask; | ||
| 65 | return dma_addr; | ||
| 66 | } | ||
| 67 | |||
| 68 | static int __init bcm3384_init_dma_xor(void) | ||
| 69 | { | ||
| 70 | struct device_node *np = of_find_node_by_type(NULL, "memory"); | ||
| 71 | |||
| 72 | if (!np) | ||
| 73 | return 0; | ||
| 74 | |||
| 75 | of_property_read_u32(np, "dma-xor-mask", &bcm3384_dma_xor_mask); | ||
| 76 | of_property_read_u32(np, "dma-xor-limit", &bcm3384_dma_xor_limit); | ||
| 77 | |||
| 78 | of_node_put(np); | ||
| 79 | return 0; | ||
| 80 | } | ||
| 81 | arch_initcall(bcm3384_init_dma_xor); | ||
diff --git a/arch/mips/bcm3384/irq.c b/arch/mips/bcm3384/irq.c new file mode 100644 index 000000000000..0fb5134fb832 --- /dev/null +++ b/arch/mips/bcm3384/irq.c | |||
| @@ -0,0 +1,193 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Partially based on arch/mips/ralink/irq.c | ||
| 7 | * | ||
| 8 | * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> | ||
| 9 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | ||
| 10 | * Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com> | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/io.h> | ||
| 14 | #include <linux/bitops.h> | ||
| 15 | #include <linux/of_platform.h> | ||
| 16 | #include <linux/of_address.h> | ||
| 17 | #include <linux/of_irq.h> | ||
| 18 | #include <linux/irqdomain.h> | ||
| 19 | #include <linux/interrupt.h> | ||
| 20 | #include <linux/slab.h> | ||
| 21 | #include <linux/spinlock.h> | ||
| 22 | |||
| 23 | #include <asm/bmips.h> | ||
| 24 | #include <asm/irq_cpu.h> | ||
| 25 | #include <asm/mipsregs.h> | ||
| 26 | |||
| 27 | /* INTC register offsets */ | ||
| 28 | #define INTC_REG_ENABLE 0x00 | ||
| 29 | #define INTC_REG_STATUS 0x04 | ||
| 30 | |||
| 31 | #define MAX_WORDS 2 | ||
| 32 | #define IRQS_PER_WORD 32 | ||
| 33 | |||
| 34 | struct bcm3384_intc { | ||
| 35 | int n_words; | ||
| 36 | void __iomem *reg[MAX_WORDS]; | ||
| 37 | u32 enable[MAX_WORDS]; | ||
| 38 | spinlock_t lock; | ||
| 39 | }; | ||
| 40 | |||
| 41 | static void bcm3384_intc_irq_unmask(struct irq_data *d) | ||
| 42 | { | ||
| 43 | struct bcm3384_intc *priv = d->domain->host_data; | ||
| 44 | unsigned long flags; | ||
| 45 | int idx = d->hwirq / IRQS_PER_WORD; | ||
| 46 | int bit = d->hwirq % IRQS_PER_WORD; | ||
| 47 | |||
| 48 | spin_lock_irqsave(&priv->lock, flags); | ||
| 49 | priv->enable[idx] |= BIT(bit); | ||
| 50 | __raw_writel(priv->enable[idx], priv->reg[idx] + INTC_REG_ENABLE); | ||
| 51 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 52 | } | ||
| 53 | |||
| 54 | static void bcm3384_intc_irq_mask(struct irq_data *d) | ||
| 55 | { | ||
| 56 | struct bcm3384_intc *priv = d->domain->host_data; | ||
| 57 | unsigned long flags; | ||
| 58 | int idx = d->hwirq / IRQS_PER_WORD; | ||
| 59 | int bit = d->hwirq % IRQS_PER_WORD; | ||
| 60 | |||
| 61 | spin_lock_irqsave(&priv->lock, flags); | ||
| 62 | priv->enable[idx] &= ~BIT(bit); | ||
| 63 | __raw_writel(priv->enable[idx], priv->reg[idx] + INTC_REG_ENABLE); | ||
| 64 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 65 | } | ||
| 66 | |||
| 67 | static struct irq_chip bcm3384_intc_irq_chip = { | ||
| 68 | .name = "INTC", | ||
| 69 | .irq_unmask = bcm3384_intc_irq_unmask, | ||
| 70 | .irq_mask = bcm3384_intc_irq_mask, | ||
| 71 | .irq_mask_ack = bcm3384_intc_irq_mask, | ||
| 72 | }; | ||
| 73 | |||
| 74 | unsigned int get_c0_compare_int(void) | ||
| 75 | { | ||
| 76 | return CP0_LEGACY_COMPARE_IRQ; | ||
| 77 | } | ||
| 78 | |||
| 79 | static void bcm3384_intc_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
| 80 | { | ||
| 81 | struct irq_domain *domain = irq_get_handler_data(irq); | ||
| 82 | struct bcm3384_intc *priv = domain->host_data; | ||
| 83 | unsigned long flags; | ||
| 84 | unsigned int idx; | ||
| 85 | |||
| 86 | for (idx = 0; idx < priv->n_words; idx++) { | ||
| 87 | unsigned long pending; | ||
| 88 | int hwirq; | ||
| 89 | |||
| 90 | spin_lock_irqsave(&priv->lock, flags); | ||
| 91 | pending = __raw_readl(priv->reg[idx] + INTC_REG_STATUS) & | ||
| 92 | priv->enable[idx]; | ||
| 93 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 94 | |||
| 95 | for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) { | ||
| 96 | generic_handle_irq(irq_find_mapping(domain, | ||
| 97 | hwirq + idx * IRQS_PER_WORD)); | ||
| 98 | } | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | asmlinkage void plat_irq_dispatch(void) | ||
| 103 | { | ||
| 104 | unsigned long pending = | ||
| 105 | (read_c0_status() & read_c0_cause() & ST0_IM) >> STATUSB_IP0; | ||
| 106 | int bit; | ||
| 107 | |||
| 108 | for_each_set_bit(bit, &pending, 8) | ||
| 109 | do_IRQ(MIPS_CPU_IRQ_BASE + bit); | ||
| 110 | } | ||
| 111 | |||
| 112 | static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) | ||
| 113 | { | ||
| 114 | irq_set_chip_and_handler(irq, &bcm3384_intc_irq_chip, handle_level_irq); | ||
| 115 | return 0; | ||
| 116 | } | ||
| 117 | |||
| 118 | static const struct irq_domain_ops irq_domain_ops = { | ||
| 119 | .xlate = irq_domain_xlate_onecell, | ||
| 120 | .map = intc_map, | ||
| 121 | }; | ||
| 122 | |||
| 123 | static int __init ioremap_one_pair(struct bcm3384_intc *priv, | ||
| 124 | struct device_node *node, | ||
| 125 | int idx) | ||
| 126 | { | ||
| 127 | struct resource res; | ||
| 128 | |||
| 129 | if (of_address_to_resource(node, idx, &res)) | ||
| 130 | return 0; | ||
| 131 | |||
| 132 | if (request_mem_region(res.start, resource_size(&res), | ||
| 133 | res.name) < 0) | ||
| 134 | pr_err("Failed to request INTC register region\n"); | ||
| 135 | |||
| 136 | priv->reg[idx] = ioremap_nocache(res.start, resource_size(&res)); | ||
| 137 | if (!priv->reg[idx]) | ||
| 138 | panic("Failed to ioremap INTC register range"); | ||
| 139 | |||
| 140 | /* start up with everything masked before we hook the parent IRQ */ | ||
| 141 | __raw_writel(0, priv->reg[idx] + INTC_REG_ENABLE); | ||
| 142 | priv->enable[idx] = 0; | ||
| 143 | |||
| 144 | return IRQS_PER_WORD; | ||
| 145 | } | ||
| 146 | |||
| 147 | static int __init intc_of_init(struct device_node *node, | ||
| 148 | struct device_node *parent) | ||
| 149 | { | ||
| 150 | struct irq_domain *domain; | ||
| 151 | unsigned int parent_irq, n_irqs = 0; | ||
| 152 | struct bcm3384_intc *priv; | ||
| 153 | |||
| 154 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
| 155 | if (!priv) | ||
| 156 | panic("Failed to allocate bcm3384_intc struct"); | ||
| 157 | |||
| 158 | spin_lock_init(&priv->lock); | ||
| 159 | |||
| 160 | parent_irq = irq_of_parse_and_map(node, 0); | ||
| 161 | if (!parent_irq) | ||
| 162 | panic("Failed to get INTC IRQ"); | ||
| 163 | |||
| 164 | n_irqs += ioremap_one_pair(priv, node, 0); | ||
| 165 | n_irqs += ioremap_one_pair(priv, node, 1); | ||
| 166 | |||
| 167 | if (!n_irqs) | ||
| 168 | panic("Failed to map INTC registers"); | ||
| 169 | |||
| 170 | priv->n_words = n_irqs / IRQS_PER_WORD; | ||
| 171 | domain = irq_domain_add_linear(node, n_irqs, &irq_domain_ops, priv); | ||
| 172 | if (!domain) | ||
| 173 | panic("Failed to add irqdomain"); | ||
| 174 | |||
| 175 | irq_set_chained_handler(parent_irq, bcm3384_intc_irq_handler); | ||
| 176 | irq_set_handler_data(parent_irq, domain); | ||
| 177 | |||
| 178 | return 0; | ||
| 179 | } | ||
| 180 | |||
| 181 | static struct of_device_id of_irq_ids[] __initdata = { | ||
| 182 | { .compatible = "mti,cpu-interrupt-controller", | ||
| 183 | .data = mips_cpu_intc_init }, | ||
| 184 | { .compatible = "brcm,bcm3384-intc", | ||
| 185 | .data = intc_of_init }, | ||
| 186 | {}, | ||
| 187 | }; | ||
| 188 | |||
| 189 | void __init arch_init_irq(void) | ||
| 190 | { | ||
| 191 | bmips_tp1_irqs = 0; | ||
| 192 | of_irq_init(of_irq_ids); | ||
| 193 | } | ||
diff --git a/arch/mips/bcm3384/setup.c b/arch/mips/bcm3384/setup.c new file mode 100644 index 000000000000..d84b8400b874 --- /dev/null +++ b/arch/mips/bcm3384/setup.c | |||
| @@ -0,0 +1,97 @@ | |||
| 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 | * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> | ||
| 7 | * Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com> | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/init.h> | ||
| 11 | #include <linux/bootmem.h> | ||
| 12 | #include <linux/clk-provider.h> | ||
| 13 | #include <linux/ioport.h> | ||
| 14 | #include <linux/of.h> | ||
| 15 | #include <linux/of_fdt.h> | ||
| 16 | #include <linux/of_platform.h> | ||
| 17 | #include <linux/smp.h> | ||
| 18 | #include <asm/addrspace.h> | ||
| 19 | #include <asm/bmips.h> | ||
| 20 | #include <asm/bootinfo.h> | ||
| 21 | #include <asm/prom.h> | ||
| 22 | #include <asm/smp-ops.h> | ||
| 23 | #include <asm/time.h> | ||
| 24 | |||
| 25 | void __init prom_init(void) | ||
| 26 | { | ||
| 27 | register_bmips_smp_ops(); | ||
| 28 | } | ||
| 29 | |||
| 30 | void __init prom_free_prom_memory(void) | ||
| 31 | { | ||
| 32 | } | ||
| 33 | |||
| 34 | const char *get_system_type(void) | ||
| 35 | { | ||
| 36 | return "BCM3384"; | ||
| 37 | } | ||
| 38 | |||
| 39 | void __init plat_time_init(void) | ||
| 40 | { | ||
| 41 | struct device_node *np; | ||
| 42 | u32 freq; | ||
| 43 | |||
| 44 | np = of_find_node_by_name(NULL, "cpus"); | ||
| 45 | if (!np) | ||
| 46 | panic("missing 'cpus' DT node"); | ||
| 47 | if (of_property_read_u32(np, "mips-hpt-frequency", &freq) < 0) | ||
| 48 | panic("missing 'mips-hpt-frequency' property"); | ||
| 49 | of_node_put(np); | ||
| 50 | |||
| 51 | mips_hpt_frequency = freq; | ||
| 52 | } | ||
| 53 | |||
| 54 | void __init plat_mem_setup(void) | ||
| 55 | { | ||
| 56 | void *dtb = __dtb_start; | ||
| 57 | |||
| 58 | set_io_port_base(0); | ||
| 59 | ioport_resource.start = 0; | ||
| 60 | ioport_resource.end = ~0; | ||
| 61 | |||
| 62 | /* intended to somewhat resemble ARM; see Documentation/arm/Booting */ | ||
| 63 | if (fw_arg0 == 0 && fw_arg1 == 0xffffffff) | ||
| 64 | dtb = phys_to_virt(fw_arg2); | ||
| 65 | |||
| 66 | __dt_setup_arch(dtb); | ||
| 67 | |||
| 68 | strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); | ||
| 69 | } | ||
| 70 | |||
| 71 | void __init device_tree_init(void) | ||
| 72 | { | ||
| 73 | struct device_node *np; | ||
| 74 | |||
| 75 | unflatten_and_copy_device_tree(); | ||
| 76 | |||
| 77 | /* Disable SMP boot unless both CPUs are listed in DT and !disabled */ | ||
| 78 | np = of_find_node_by_name(NULL, "cpus"); | ||
| 79 | if (np && of_get_available_child_count(np) <= 1) | ||
| 80 | bmips_smp_enabled = 0; | ||
| 81 | of_node_put(np); | ||
| 82 | } | ||
| 83 | |||
| 84 | int __init plat_of_setup(void) | ||
| 85 | { | ||
| 86 | return __dt_register_buses("brcm,bcm3384", "simple-bus"); | ||
| 87 | } | ||
| 88 | |||
| 89 | arch_initcall(plat_of_setup); | ||
| 90 | |||
| 91 | static int __init plat_dev_init(void) | ||
| 92 | { | ||
| 93 | of_clk_init(NULL); | ||
| 94 | return 0; | ||
| 95 | } | ||
| 96 | |||
| 97 | device_initcall(plat_dev_init); | ||
diff --git a/arch/mips/bcm47xx/bcm47xx_private.h b/arch/mips/bcm47xx/bcm47xx_private.h index f1cc9d0495d8..ea909a56a3ee 100644 --- a/arch/mips/bcm47xx/bcm47xx_private.h +++ b/arch/mips/bcm47xx/bcm47xx_private.h | |||
| @@ -6,12 +6,18 @@ | |||
| 6 | /* prom.c */ | 6 | /* prom.c */ |
| 7 | void __init bcm47xx_prom_highmem_init(void); | 7 | void __init bcm47xx_prom_highmem_init(void); |
| 8 | 8 | ||
| 9 | /* sprom.c */ | ||
| 10 | void bcm47xx_sprom_register_fallbacks(void); | ||
| 11 | |||
| 9 | /* buttons.c */ | 12 | /* buttons.c */ |
| 10 | int __init bcm47xx_buttons_register(void); | 13 | int __init bcm47xx_buttons_register(void); |
| 11 | 14 | ||
| 12 | /* leds.c */ | 15 | /* leds.c */ |
| 13 | void __init bcm47xx_leds_register(void); | 16 | void __init bcm47xx_leds_register(void); |
| 14 | 17 | ||
| 18 | /* setup.c */ | ||
| 19 | void __init bcm47xx_bus_setup(void); | ||
| 20 | |||
| 15 | /* workarounds.c */ | 21 | /* workarounds.c */ |
| 16 | void __init bcm47xx_workarounds(void); | 22 | void __init bcm47xx_workarounds(void); |
| 17 | 23 | ||
diff --git a/arch/mips/bcm47xx/irq.c b/arch/mips/bcm47xx/irq.c index e0585b76ec19..21b4497f09be 100644 --- a/arch/mips/bcm47xx/irq.c +++ b/arch/mips/bcm47xx/irq.c | |||
| @@ -22,6 +22,8 @@ | |||
| 22 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 22 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
| 23 | */ | 23 | */ |
| 24 | 24 | ||
| 25 | #include "bcm47xx_private.h" | ||
| 26 | |||
| 25 | #include <linux/types.h> | 27 | #include <linux/types.h> |
| 26 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
| 27 | #include <linux/irq.h> | 29 | #include <linux/irq.h> |
| @@ -65,6 +67,12 @@ DEFINE_HWx_IRQDISPATCH(7) | |||
| 65 | 67 | ||
| 66 | void __init arch_init_irq(void) | 68 | void __init arch_init_irq(void) |
| 67 | { | 69 | { |
| 70 | /* | ||
| 71 | * This is the first arch callback after mm_init (we can use kmalloc), | ||
| 72 | * so let's finish bus initialization now. | ||
| 73 | */ | ||
| 74 | bcm47xx_bus_setup(); | ||
| 75 | |||
| 68 | #ifdef CONFIG_BCM47XX_BCMA | 76 | #ifdef CONFIG_BCM47XX_BCMA |
| 69 | if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) { | 77 | if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) { |
| 70 | bcma_write32(bcm47xx_bus.bcma.bus.drv_mips.core, | 78 | bcma_write32(bcm47xx_bus.bcma.bus.drv_mips.core, |
diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c index 2bed73a684ae..c5c381c43f17 100644 --- a/arch/mips/bcm47xx/nvram.c +++ b/arch/mips/bcm47xx/nvram.c | |||
| @@ -13,24 +13,35 @@ | |||
| 13 | 13 | ||
| 14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
| 15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 16 | #include <linux/ssb/ssb.h> | ||
| 17 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 18 | #include <linux/string.h> | 17 | #include <linux/string.h> |
| 19 | #include <asm/addrspace.h> | 18 | #include <linux/mtd/mtd.h> |
| 20 | #include <bcm47xx_nvram.h> | 19 | #include <bcm47xx_nvram.h> |
| 21 | #include <asm/mach-bcm47xx/bcm47xx.h> | 20 | |
| 21 | #define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */ | ||
| 22 | #define NVRAM_SPACE 0x8000 | ||
| 23 | |||
| 24 | #define FLASH_MIN 0x00020000 /* Minimum flash size */ | ||
| 25 | |||
| 26 | struct nvram_header { | ||
| 27 | u32 magic; | ||
| 28 | u32 len; | ||
| 29 | u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */ | ||
| 30 | u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */ | ||
| 31 | u32 config_ncdl; /* ncdl values for memc */ | ||
| 32 | }; | ||
| 22 | 33 | ||
| 23 | static char nvram_buf[NVRAM_SPACE]; | 34 | static char nvram_buf[NVRAM_SPACE]; |
| 24 | static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000}; | 35 | static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000}; |
| 25 | 36 | ||
| 26 | static u32 find_nvram_size(u32 end) | 37 | static u32 find_nvram_size(void __iomem *end) |
| 27 | { | 38 | { |
| 28 | struct nvram_header *header; | 39 | struct nvram_header __iomem *header; |
| 29 | int i; | 40 | int i; |
| 30 | 41 | ||
| 31 | for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) { | 42 | for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) { |
| 32 | header = (struct nvram_header *)KSEG1ADDR(end - nvram_sizes[i]); | 43 | header = (struct nvram_header *)(end - nvram_sizes[i]); |
| 33 | if (header->magic == NVRAM_HEADER) | 44 | if (header->magic == NVRAM_MAGIC) |
| 34 | return nvram_sizes[i]; | 45 | return nvram_sizes[i]; |
| 35 | } | 46 | } |
| 36 | 47 | ||
| @@ -38,36 +49,40 @@ static u32 find_nvram_size(u32 end) | |||
| 38 | } | 49 | } |
| 39 | 50 | ||
| 40 | /* Probe for NVRAM header */ | 51 | /* Probe for NVRAM header */ |
| 41 | static int nvram_find_and_copy(u32 base, u32 lim) | 52 | static int nvram_find_and_copy(void __iomem *iobase, u32 lim) |
| 42 | { | 53 | { |
| 43 | struct nvram_header *header; | 54 | struct nvram_header __iomem *header; |
| 44 | int i; | 55 | int i; |
| 45 | u32 off; | 56 | u32 off; |
| 46 | u32 *src, *dst; | 57 | u32 *src, *dst; |
| 47 | u32 size; | 58 | u32 size; |
| 48 | 59 | ||
| 60 | if (nvram_buf[0]) { | ||
| 61 | pr_warn("nvram already initialized\n"); | ||
| 62 | return -EEXIST; | ||
| 63 | } | ||
| 64 | |||
| 49 | /* TODO: when nvram is on nand flash check for bad blocks first. */ | 65 | /* TODO: when nvram is on nand flash check for bad blocks first. */ |
| 50 | off = FLASH_MIN; | 66 | off = FLASH_MIN; |
| 51 | while (off <= lim) { | 67 | while (off <= lim) { |
| 52 | /* Windowed flash access */ | 68 | /* Windowed flash access */ |
| 53 | size = find_nvram_size(base + off); | 69 | size = find_nvram_size(iobase + off); |
| 54 | if (size) { | 70 | if (size) { |
| 55 | header = (struct nvram_header *)KSEG1ADDR(base + off - | 71 | header = (struct nvram_header *)(iobase + off - size); |
| 56 | size); | ||
| 57 | goto found; | 72 | goto found; |
| 58 | } | 73 | } |
| 59 | off <<= 1; | 74 | off <<= 1; |
| 60 | } | 75 | } |
| 61 | 76 | ||
| 62 | /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ | 77 | /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ |
| 63 | header = (struct nvram_header *) KSEG1ADDR(base + 4096); | 78 | header = (struct nvram_header *)(iobase + 4096); |
| 64 | if (header->magic == NVRAM_HEADER) { | 79 | if (header->magic == NVRAM_MAGIC) { |
| 65 | size = NVRAM_SPACE; | 80 | size = NVRAM_SPACE; |
| 66 | goto found; | 81 | goto found; |
| 67 | } | 82 | } |
| 68 | 83 | ||
| 69 | header = (struct nvram_header *) KSEG1ADDR(base + 1024); | 84 | header = (struct nvram_header *)(iobase + 1024); |
| 70 | if (header->magic == NVRAM_HEADER) { | 85 | if (header->magic == NVRAM_MAGIC) { |
| 71 | size = NVRAM_SPACE; | 86 | size = NVRAM_SPACE; |
| 72 | goto found; | 87 | goto found; |
| 73 | } | 88 | } |
| @@ -94,71 +109,73 @@ found: | |||
| 94 | return 0; | 109 | return 0; |
| 95 | } | 110 | } |
| 96 | 111 | ||
| 97 | #ifdef CONFIG_BCM47XX_SSB | 112 | /* |
| 98 | static int nvram_init_ssb(void) | 113 | * On bcm47xx we need access to the NVRAM very early, so we can't use mtd |
| 114 | * subsystem to access flash. We can't even use platform device / driver to | ||
| 115 | * store memory offset. | ||
| 116 | * To handle this we provide following symbol. It's supposed to be called as | ||
| 117 | * soon as we get info about flash device, before any NVRAM entry is needed. | ||
| 118 | */ | ||
| 119 | int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) | ||
| 99 | { | 120 | { |
| 100 | struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore; | 121 | void __iomem *iobase; |
| 101 | u32 base; | 122 | int err; |
| 102 | u32 lim; | ||
| 103 | |||
| 104 | if (mcore->pflash.present) { | ||
| 105 | base = mcore->pflash.window; | ||
| 106 | lim = mcore->pflash.window_size; | ||
| 107 | } else { | ||
| 108 | pr_err("Couldn't find supported flash memory\n"); | ||
| 109 | return -ENXIO; | ||
| 110 | } | ||
| 111 | 123 | ||
| 112 | return nvram_find_and_copy(base, lim); | 124 | iobase = ioremap_nocache(base, lim); |
| 113 | } | 125 | if (!iobase) |
| 114 | #endif | 126 | return -ENOMEM; |
| 115 | 127 | ||
| 116 | #ifdef CONFIG_BCM47XX_BCMA | 128 | err = nvram_find_and_copy(iobase, lim); |
| 117 | static int nvram_init_bcma(void) | 129 | |
| 118 | { | 130 | iounmap(iobase); |
| 119 | struct bcma_drv_cc *cc = &bcm47xx_bus.bcma.bus.drv_cc; | ||
| 120 | u32 base; | ||
| 121 | u32 lim; | ||
| 122 | |||
| 123 | #ifdef CONFIG_BCMA_NFLASH | ||
| 124 | if (cc->nflash.boot) { | ||
| 125 | base = BCMA_SOC_FLASH1; | ||
| 126 | lim = BCMA_SOC_FLASH1_SZ; | ||
| 127 | } else | ||
| 128 | #endif | ||
| 129 | if (cc->pflash.present) { | ||
| 130 | base = cc->pflash.window; | ||
| 131 | lim = cc->pflash.window_size; | ||
| 132 | #ifdef CONFIG_BCMA_SFLASH | ||
| 133 | } else if (cc->sflash.present) { | ||
| 134 | base = cc->sflash.window; | ||
| 135 | lim = cc->sflash.size; | ||
| 136 | #endif | ||
| 137 | } else { | ||
| 138 | pr_err("Couldn't find supported flash memory\n"); | ||
| 139 | return -ENXIO; | ||
| 140 | } | ||
| 141 | 131 | ||
| 142 | return nvram_find_and_copy(base, lim); | 132 | return err; |
| 143 | } | 133 | } |
| 144 | #endif | ||
| 145 | 134 | ||
| 146 | static int nvram_init(void) | 135 | static int nvram_init(void) |
| 147 | { | 136 | { |
| 148 | switch (bcm47xx_bus_type) { | 137 | #ifdef CONFIG_MTD |
| 149 | #ifdef CONFIG_BCM47XX_SSB | 138 | struct mtd_info *mtd; |
| 150 | case BCM47XX_BUS_TYPE_SSB: | 139 | struct nvram_header header; |
| 151 | return nvram_init_ssb(); | 140 | size_t bytes_read; |
| 152 | #endif | 141 | int err, i; |
| 153 | #ifdef CONFIG_BCM47XX_BCMA | 142 | |
| 154 | case BCM47XX_BUS_TYPE_BCMA: | 143 | mtd = get_mtd_device_nm("nvram"); |
| 155 | return nvram_init_bcma(); | 144 | if (IS_ERR(mtd)) |
| 156 | #endif | 145 | return -ENODEV; |
| 146 | |||
| 147 | for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) { | ||
| 148 | loff_t from = mtd->size - nvram_sizes[i]; | ||
| 149 | |||
| 150 | if (from < 0) | ||
| 151 | continue; | ||
| 152 | |||
| 153 | err = mtd_read(mtd, from, sizeof(header), &bytes_read, | ||
| 154 | (uint8_t *)&header); | ||
| 155 | if (!err && header.magic == NVRAM_MAGIC) { | ||
| 156 | u8 *dst = (uint8_t *)nvram_buf; | ||
| 157 | size_t len = header.len; | ||
| 158 | |||
| 159 | if (header.len > NVRAM_SPACE) { | ||
| 160 | pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", | ||
| 161 | header.len, NVRAM_SPACE); | ||
| 162 | len = NVRAM_SPACE; | ||
| 163 | } | ||
| 164 | |||
| 165 | err = mtd_read(mtd, from, len, &bytes_read, dst); | ||
| 166 | if (err) | ||
| 167 | return err; | ||
| 168 | memset(dst + bytes_read, 0x0, NVRAM_SPACE - bytes_read); | ||
| 169 | |||
| 170 | return 0; | ||
| 171 | } | ||
| 157 | } | 172 | } |
| 173 | #endif | ||
| 174 | |||
| 158 | return -ENXIO; | 175 | return -ENXIO; |
| 159 | } | 176 | } |
| 160 | 177 | ||
| 161 | int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len) | 178 | int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len) |
| 162 | { | 179 | { |
| 163 | char *var, *value, *end, *eq; | 180 | char *var, *value, *end, *eq; |
| 164 | int err; | 181 | int err; |
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index c00585d915bc..e43b5046cb30 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c | |||
| @@ -102,23 +102,6 @@ static void bcm47xx_machine_halt(void) | |||
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | #ifdef CONFIG_BCM47XX_SSB | 104 | #ifdef CONFIG_BCM47XX_SSB |
| 105 | static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out) | ||
| 106 | { | ||
| 107 | char prefix[10]; | ||
| 108 | |||
| 109 | if (bus->bustype == SSB_BUSTYPE_PCI) { | ||
| 110 | memset(out, 0, sizeof(struct ssb_sprom)); | ||
| 111 | snprintf(prefix, sizeof(prefix), "pci/%u/%u/", | ||
| 112 | bus->host_pci->bus->number + 1, | ||
| 113 | PCI_SLOT(bus->host_pci->devfn)); | ||
| 114 | bcm47xx_fill_sprom(out, prefix, false); | ||
| 115 | return 0; | ||
| 116 | } else { | ||
| 117 | printk(KERN_WARNING "bcm47xx: unable to fill SPROM for given bustype.\n"); | ||
| 118 | return -EINVAL; | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 122 | static int bcm47xx_get_invariants(struct ssb_bus *bus, | 105 | static int bcm47xx_get_invariants(struct ssb_bus *bus, |
| 123 | struct ssb_init_invariants *iv) | 106 | struct ssb_init_invariants *iv) |
| 124 | { | 107 | { |
| @@ -144,11 +127,6 @@ static void __init bcm47xx_register_ssb(void) | |||
| 144 | char buf[100]; | 127 | char buf[100]; |
| 145 | struct ssb_mipscore *mcore; | 128 | struct ssb_mipscore *mcore; |
| 146 | 129 | ||
| 147 | err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb); | ||
| 148 | if (err) | ||
| 149 | printk(KERN_WARNING "bcm47xx: someone else already registered" | ||
| 150 | " a ssb SPROM callback handler (err %d)\n", err); | ||
| 151 | |||
| 152 | err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE, | 130 | err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE, |
| 153 | bcm47xx_get_invariants); | 131 | bcm47xx_get_invariants); |
| 154 | if (err) | 132 | if (err) |
| @@ -171,56 +149,21 @@ static void __init bcm47xx_register_ssb(void) | |||
| 171 | #endif | 149 | #endif |
| 172 | 150 | ||
| 173 | #ifdef CONFIG_BCM47XX_BCMA | 151 | #ifdef CONFIG_BCM47XX_BCMA |
| 174 | static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out) | ||
| 175 | { | ||
| 176 | char prefix[10]; | ||
| 177 | struct bcma_device *core; | ||
| 178 | |||
| 179 | switch (bus->hosttype) { | ||
| 180 | case BCMA_HOSTTYPE_PCI: | ||
| 181 | memset(out, 0, sizeof(struct ssb_sprom)); | ||
| 182 | snprintf(prefix, sizeof(prefix), "pci/%u/%u/", | ||
| 183 | bus->host_pci->bus->number + 1, | ||
| 184 | PCI_SLOT(bus->host_pci->devfn)); | ||
| 185 | bcm47xx_fill_sprom(out, prefix, false); | ||
| 186 | return 0; | ||
| 187 | case BCMA_HOSTTYPE_SOC: | ||
| 188 | memset(out, 0, sizeof(struct ssb_sprom)); | ||
| 189 | core = bcma_find_core(bus, BCMA_CORE_80211); | ||
| 190 | if (core) { | ||
| 191 | snprintf(prefix, sizeof(prefix), "sb/%u/", | ||
| 192 | core->core_index); | ||
| 193 | bcm47xx_fill_sprom(out, prefix, true); | ||
| 194 | } else { | ||
| 195 | bcm47xx_fill_sprom(out, NULL, false); | ||
| 196 | } | ||
| 197 | return 0; | ||
| 198 | default: | ||
| 199 | pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n"); | ||
| 200 | return -EINVAL; | ||
| 201 | } | ||
| 202 | } | ||
| 203 | |||
| 204 | static void __init bcm47xx_register_bcma(void) | 152 | static void __init bcm47xx_register_bcma(void) |
| 205 | { | 153 | { |
| 206 | int err; | 154 | int err; |
| 207 | 155 | ||
| 208 | err = bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma); | ||
| 209 | if (err) | ||
| 210 | pr_warn("bcm47xx: someone else already registered a bcma SPROM callback handler (err %d)\n", err); | ||
| 211 | |||
| 212 | err = bcma_host_soc_register(&bcm47xx_bus.bcma); | 156 | err = bcma_host_soc_register(&bcm47xx_bus.bcma); |
| 213 | if (err) | 157 | if (err) |
| 214 | panic("Failed to register BCMA bus (err %d)", err); | 158 | panic("Failed to register BCMA bus (err %d)", err); |
| 215 | |||
| 216 | err = bcma_host_soc_init(&bcm47xx_bus.bcma); | ||
| 217 | if (err) | ||
| 218 | panic("Failed to initialize BCMA bus (err %d)", err); | ||
| 219 | |||
| 220 | bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, NULL); | ||
| 221 | } | 159 | } |
| 222 | #endif | 160 | #endif |
| 223 | 161 | ||
| 162 | /* | ||
| 163 | * Memory setup is done in the early part of MIPS's arch_mem_init. It's supposed | ||
| 164 | * to detect memory and record it with add_memory_region. | ||
| 165 | * Any extra initializaion performed here must not use kmalloc or bootmem. | ||
| 166 | */ | ||
| 224 | void __init plat_mem_setup(void) | 167 | void __init plat_mem_setup(void) |
| 225 | { | 168 | { |
| 226 | struct cpuinfo_mips *c = ¤t_cpu_data; | 169 | struct cpuinfo_mips *c = ¤t_cpu_data; |
| @@ -229,6 +172,7 @@ void __init plat_mem_setup(void) | |||
| 229 | printk(KERN_INFO "bcm47xx: using bcma bus\n"); | 172 | printk(KERN_INFO "bcm47xx: using bcma bus\n"); |
| 230 | #ifdef CONFIG_BCM47XX_BCMA | 173 | #ifdef CONFIG_BCM47XX_BCMA |
| 231 | bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA; | 174 | bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA; |
| 175 | bcm47xx_sprom_register_fallbacks(); | ||
| 232 | bcm47xx_register_bcma(); | 176 | bcm47xx_register_bcma(); |
| 233 | bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id); | 177 | bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id); |
| 234 | #ifdef CONFIG_HIGHMEM | 178 | #ifdef CONFIG_HIGHMEM |
| @@ -239,6 +183,7 @@ void __init plat_mem_setup(void) | |||
| 239 | printk(KERN_INFO "bcm47xx: using ssb bus\n"); | 183 | printk(KERN_INFO "bcm47xx: using ssb bus\n"); |
| 240 | #ifdef CONFIG_BCM47XX_SSB | 184 | #ifdef CONFIG_BCM47XX_SSB |
| 241 | bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB; | 185 | bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB; |
| 186 | bcm47xx_sprom_register_fallbacks(); | ||
| 242 | bcm47xx_register_ssb(); | 187 | bcm47xx_register_ssb(); |
| 243 | bcm47xx_set_system_type(bcm47xx_bus.ssb.chip_id); | 188 | bcm47xx_set_system_type(bcm47xx_bus.ssb.chip_id); |
| 244 | #endif | 189 | #endif |
| @@ -247,6 +192,28 @@ void __init plat_mem_setup(void) | |||
| 247 | _machine_restart = bcm47xx_machine_restart; | 192 | _machine_restart = bcm47xx_machine_restart; |
| 248 | _machine_halt = bcm47xx_machine_halt; | 193 | _machine_halt = bcm47xx_machine_halt; |
| 249 | pm_power_off = bcm47xx_machine_halt; | 194 | pm_power_off = bcm47xx_machine_halt; |
| 195 | } | ||
| 196 | |||
| 197 | /* | ||
| 198 | * This finishes bus initialization doing things that were not possible without | ||
| 199 | * kmalloc. Make sure to call it late enough (after mm_init). | ||
| 200 | */ | ||
| 201 | void __init bcm47xx_bus_setup(void) | ||
| 202 | { | ||
| 203 | #ifdef CONFIG_BCM47XX_BCMA | ||
| 204 | if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) { | ||
| 205 | int err; | ||
| 206 | |||
| 207 | err = bcma_host_soc_init(&bcm47xx_bus.bcma); | ||
| 208 | if (err) | ||
| 209 | panic("Failed to initialize BCMA bus (err %d)", err); | ||
| 210 | |||
| 211 | bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, | ||
| 212 | NULL); | ||
| 213 | } | ||
| 214 | #endif | ||
| 215 | |||
| 216 | /* With bus initialized we can access NVRAM and detect the board */ | ||
| 250 | bcm47xx_board_detect(); | 217 | bcm47xx_board_detect(); |
| 251 | mips_set_machine_name(bcm47xx_board_get_name()); | 218 | mips_set_machine_name(bcm47xx_board_get_name()); |
| 252 | } | 219 | } |
diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c index 41226b68de3d..2eff7fe99c6b 100644 --- a/arch/mips/bcm47xx/sprom.c +++ b/arch/mips/bcm47xx/sprom.c | |||
| @@ -136,6 +136,20 @@ static void nvram_read_leddc(const char *prefix, const char *name, | |||
| 136 | *leddc_off_time = (val >> 16) & 0xff; | 136 | *leddc_off_time = (val >> 16) & 0xff; |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | static void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6]) | ||
| 140 | { | ||
| 141 | if (strchr(buf, ':')) | ||
| 142 | sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], | ||
| 143 | &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4], | ||
| 144 | &macaddr[5]); | ||
| 145 | else if (strchr(buf, '-')) | ||
| 146 | sscanf(buf, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &macaddr[0], | ||
| 147 | &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4], | ||
| 148 | &macaddr[5]); | ||
| 149 | else | ||
| 150 | pr_warn("Can not parse mac address: %s\n", buf); | ||
| 151 | } | ||
| 152 | |||
| 139 | static void nvram_read_macaddr(const char *prefix, const char *name, | 153 | static void nvram_read_macaddr(const char *prefix, const char *name, |
| 140 | u8 val[6], bool fallback) | 154 | u8 val[6], bool fallback) |
| 141 | { | 155 | { |
| @@ -801,3 +815,71 @@ void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo, | |||
| 801 | nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true); | 815 | nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true); |
| 802 | } | 816 | } |
| 803 | #endif | 817 | #endif |
| 818 | |||
| 819 | #if defined(CONFIG_BCM47XX_SSB) | ||
| 820 | static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out) | ||
| 821 | { | ||
| 822 | char prefix[10]; | ||
| 823 | |||
| 824 | if (bus->bustype == SSB_BUSTYPE_PCI) { | ||
| 825 | memset(out, 0, sizeof(struct ssb_sprom)); | ||
| 826 | snprintf(prefix, sizeof(prefix), "pci/%u/%u/", | ||
| 827 | bus->host_pci->bus->number + 1, | ||
| 828 | PCI_SLOT(bus->host_pci->devfn)); | ||
| 829 | bcm47xx_fill_sprom(out, prefix, false); | ||
| 830 | return 0; | ||
| 831 | } else { | ||
| 832 | pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n"); | ||
| 833 | return -EINVAL; | ||
| 834 | } | ||
| 835 | } | ||
| 836 | #endif | ||
| 837 | |||
| 838 | #if defined(CONFIG_BCM47XX_BCMA) | ||
| 839 | static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out) | ||
| 840 | { | ||
| 841 | char prefix[10]; | ||
| 842 | struct bcma_device *core; | ||
| 843 | |||
| 844 | switch (bus->hosttype) { | ||
| 845 | case BCMA_HOSTTYPE_PCI: | ||
| 846 | memset(out, 0, sizeof(struct ssb_sprom)); | ||
| 847 | snprintf(prefix, sizeof(prefix), "pci/%u/%u/", | ||
| 848 | bus->host_pci->bus->number + 1, | ||
| 849 | PCI_SLOT(bus->host_pci->devfn)); | ||
| 850 | bcm47xx_fill_sprom(out, prefix, false); | ||
| 851 | return 0; | ||
| 852 | case BCMA_HOSTTYPE_SOC: | ||
| 853 | memset(out, 0, sizeof(struct ssb_sprom)); | ||
| 854 | core = bcma_find_core(bus, BCMA_CORE_80211); | ||
| 855 | if (core) { | ||
| 856 | snprintf(prefix, sizeof(prefix), "sb/%u/", | ||
| 857 | core->core_index); | ||
| 858 | bcm47xx_fill_sprom(out, prefix, true); | ||
| 859 | } else { | ||
| 860 | bcm47xx_fill_sprom(out, NULL, false); | ||
| 861 | } | ||
| 862 | return 0; | ||
| 863 | default: | ||
| 864 | pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n"); | ||
| 865 | return -EINVAL; | ||
| 866 | } | ||
| 867 | } | ||
| 868 | #endif | ||
| 869 | |||
| 870 | /* | ||
| 871 | * On bcm47xx we need to register SPROM fallback handler very early, so we can't | ||
| 872 | * use anything like platform device / driver for this. | ||
| 873 | */ | ||
| 874 | void bcm47xx_sprom_register_fallbacks(void) | ||
| 875 | { | ||
| 876 | #if defined(CONFIG_BCM47XX_SSB) | ||
| 877 | if (ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb)) | ||
| 878 | pr_warn("Failed to registered ssb SPROM handler\n"); | ||
| 879 | #endif | ||
| 880 | |||
| 881 | #if defined(CONFIG_BCM47XX_BCMA) | ||
| 882 | if (bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma)) | ||
| 883 | pr_warn("Failed to registered bcma SPROM handler\n"); | ||
| 884 | #endif | ||
| 885 | } | ||
diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c index 536f64443031..307ec8b8e41c 100644 --- a/arch/mips/bcm63xx/cpu.c +++ b/arch/mips/bcm63xx/cpu.c | |||
| @@ -263,7 +263,7 @@ static unsigned int detect_memory_size(void) | |||
| 263 | 263 | ||
| 264 | if (BCMCPU_IS_6345()) { | 264 | if (BCMCPU_IS_6345()) { |
| 265 | val = bcm_sdram_readl(SDRAM_MBASE_REG); | 265 | val = bcm_sdram_readl(SDRAM_MBASE_REG); |
| 266 | return (val * 8 * 1024 * 1024); | 266 | return val * 8 * 1024 * 1024; |
| 267 | } | 267 | } |
| 268 | 268 | ||
| 269 | if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) { | 269 | if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) { |
diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile index ca9c90e2cabf..4f49fa477f14 100644 --- a/arch/mips/boot/dts/Makefile +++ b/arch/mips/boot/dts/Makefile | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | dtb-$(CONFIG_BCM3384) += bcm93384wvg.dtb | ||
| 1 | dtb-$(CONFIG_CAVIUM_OCTEON_SOC) += octeon_3xxx.dtb octeon_68xx.dtb | 2 | dtb-$(CONFIG_CAVIUM_OCTEON_SOC) += octeon_3xxx.dtb octeon_68xx.dtb |
| 2 | dtb-$(CONFIG_DT_EASY50712) += easy50712.dtb | 3 | dtb-$(CONFIG_DT_EASY50712) += easy50712.dtb |
| 3 | dtb-$(CONFIG_DT_XLP_EVP) += xlp_evp.dtb | 4 | dtb-$(CONFIG_DT_XLP_EVP) += xlp_evp.dtb |
diff --git a/arch/mips/boot/dts/bcm3384.dtsi b/arch/mips/boot/dts/bcm3384.dtsi new file mode 100644 index 000000000000..21b074a99c94 --- /dev/null +++ b/arch/mips/boot/dts/bcm3384.dtsi | |||
| @@ -0,0 +1,109 @@ | |||
| 1 | / { | ||
| 2 | #address-cells = <1>; | ||
| 3 | #size-cells = <1>; | ||
| 4 | compatible = "brcm,bcm3384", "brcm,bcm33843"; | ||
| 5 | |||
| 6 | cpus { | ||
| 7 | #address-cells = <1>; | ||
| 8 | #size-cells = <0>; | ||
| 9 | |||
| 10 | /* On BMIPS5000 this is 1/8th of the CPU core clock */ | ||
| 11 | mips-hpt-frequency = <100000000>; | ||
| 12 | |||
| 13 | cpu@0 { | ||
| 14 | compatible = "brcm,bmips5000"; | ||
| 15 | device_type = "cpu"; | ||
| 16 | reg = <0>; | ||
| 17 | }; | ||
| 18 | |||
| 19 | cpu@1 { | ||
| 20 | compatible = "brcm,bmips5000"; | ||
| 21 | device_type = "cpu"; | ||
| 22 | reg = <1>; | ||
| 23 | }; | ||
| 24 | }; | ||
| 25 | |||
| 26 | clocks { | ||
| 27 | #address-cells = <1>; | ||
| 28 | #size-cells = <0>; | ||
| 29 | |||
| 30 | periph_clk: periph_clk@0 { | ||
| 31 | compatible = "fixed-clock"; | ||
| 32 | #clock-cells = <0>; | ||
| 33 | clock-frequency = <54000000>; | ||
| 34 | }; | ||
| 35 | }; | ||
| 36 | |||
| 37 | aliases { | ||
| 38 | uart0 = &uart0; | ||
| 39 | }; | ||
| 40 | |||
| 41 | cpu_intc: cpu_intc@0 { | ||
| 42 | #address-cells = <0>; | ||
| 43 | compatible = "mti,cpu-interrupt-controller"; | ||
| 44 | |||
| 45 | interrupt-controller; | ||
| 46 | #interrupt-cells = <1>; | ||
| 47 | }; | ||
| 48 | |||
| 49 | periph_intc: periph_intc@14e00038 { | ||
| 50 | compatible = "brcm,bcm3384-intc"; | ||
| 51 | reg = <0x14e00038 0x8 0x14e00340 0x8>; | ||
| 52 | |||
| 53 | interrupt-controller; | ||
| 54 | #interrupt-cells = <1>; | ||
| 55 | |||
| 56 | interrupt-parent = <&cpu_intc>; | ||
| 57 | interrupts = <4>; | ||
| 58 | }; | ||
| 59 | |||
| 60 | zmips_intc: zmips_intc@104b0060 { | ||
| 61 | compatible = "brcm,bcm3384-intc"; | ||
| 62 | reg = <0x104b0060 0x8>; | ||
| 63 | |||
| 64 | interrupt-controller; | ||
| 65 | #interrupt-cells = <1>; | ||
| 66 | |||
| 67 | interrupt-parent = <&periph_intc>; | ||
| 68 | interrupts = <29>; | ||
| 69 | }; | ||
| 70 | |||
| 71 | iop_intc: iop_intc@14e00058 { | ||
| 72 | compatible = "brcm,bcm3384-intc"; | ||
| 73 | reg = <0x14e00058 0x8>; | ||
| 74 | |||
| 75 | interrupt-controller; | ||
| 76 | #interrupt-cells = <1>; | ||
| 77 | |||
| 78 | interrupt-parent = <&cpu_intc>; | ||
| 79 | interrupts = <6>; | ||
| 80 | }; | ||
| 81 | |||
| 82 | uart0: serial@14e00520 { | ||
| 83 | compatible = "brcm,bcm6345-uart"; | ||
| 84 | reg = <0x14e00520 0x18>; | ||
| 85 | interrupt-parent = <&periph_intc>; | ||
| 86 | interrupts = <2>; | ||
| 87 | clocks = <&periph_clk>; | ||
| 88 | status = "disabled"; | ||
| 89 | }; | ||
| 90 | |||
| 91 | ehci0: usb@15400300 { | ||
| 92 | compatible = "brcm,bcm3384-ehci", "generic-ehci"; | ||
| 93 | reg = <0x15400300 0x100>; | ||
| 94 | big-endian; | ||
| 95 | interrupt-parent = <&periph_intc>; | ||
| 96 | interrupts = <41>; | ||
| 97 | status = "disabled"; | ||
| 98 | }; | ||
| 99 | |||
| 100 | ohci0: usb@15400400 { | ||
| 101 | compatible = "brcm,bcm3384-ohci", "generic-ohci"; | ||
| 102 | reg = <0x15400400 0x100>; | ||
| 103 | big-endian; | ||
| 104 | no-big-frame-no; | ||
| 105 | interrupt-parent = <&periph_intc>; | ||
| 106 | interrupts = <40>; | ||
| 107 | status = "disabled"; | ||
| 108 | }; | ||
| 109 | }; | ||
diff --git a/arch/mips/boot/dts/bcm93384wvg.dts b/arch/mips/boot/dts/bcm93384wvg.dts new file mode 100644 index 000000000000..831741179212 --- /dev/null +++ b/arch/mips/boot/dts/bcm93384wvg.dts | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /dts-v1/; | ||
| 2 | |||
| 3 | /include/ "bcm3384.dtsi" | ||
| 4 | |||
| 5 | / { | ||
| 6 | compatible = "brcm,bcm93384wvg", "brcm,bcm3384"; | ||
| 7 | model = "Broadcom BCM93384WVG"; | ||
| 8 | |||
| 9 | chosen { | ||
| 10 | bootargs = "console=ttyS0,115200"; | ||
| 11 | stdout-path = &uart0; | ||
| 12 | }; | ||
| 13 | |||
| 14 | memory@0 { | ||
| 15 | device_type = "memory"; | ||
| 16 | reg = <0x0 0x04000000>; | ||
| 17 | dma-xor-mask = <0x08000000>; | ||
| 18 | dma-xor-limit = <0x0fffffff>; | ||
| 19 | }; | ||
| 20 | }; | ||
| 21 | |||
| 22 | &uart0 { | ||
| 23 | status = "okay"; | ||
| 24 | }; | ||
| 25 | |||
| 26 | &ehci0 { | ||
| 27 | status = "okay"; | ||
| 28 | }; | ||
| 29 | |||
| 30 | &ohci0 { | ||
| 31 | status = "okay"; | ||
| 32 | }; | ||
diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c index 02f244475207..3778655c4a37 100644 --- a/arch/mips/cavium-octeon/dma-octeon.c +++ b/arch/mips/cavium-octeon/dma-octeon.c | |||
| @@ -262,8 +262,8 @@ char *octeon_swiotlb; | |||
| 262 | void __init plat_swiotlb_setup(void) | 262 | void __init plat_swiotlb_setup(void) |
| 263 | { | 263 | { |
| 264 | int i; | 264 | int i; |
| 265 | phys_t max_addr; | 265 | phys_addr_t max_addr; |
| 266 | phys_t addr_size; | 266 | phys_addr_t addr_size; |
| 267 | size_t swiotlbsize; | 267 | size_t swiotlbsize; |
| 268 | unsigned long swiotlb_nslabs; | 268 | unsigned long swiotlb_nslabs; |
| 269 | 269 | ||
diff --git a/arch/mips/cavium-octeon/executive/octeon-model.c b/arch/mips/cavium-octeon/executive/octeon-model.c index f4c1b36fdf65..e15b049b3bd7 100644 --- a/arch/mips/cavium-octeon/executive/octeon-model.c +++ b/arch/mips/cavium-octeon/executive/octeon-model.c | |||
| @@ -28,22 +28,23 @@ | |||
| 28 | #include <asm/octeon/octeon.h> | 28 | #include <asm/octeon/octeon.h> |
| 29 | 29 | ||
| 30 | /** | 30 | /** |
| 31 | * Given the chip processor ID from COP0, this function returns a | 31 | * Read a byte of fuse data |
| 32 | * string representing the chip model number. The string is of the | 32 | * @byte_addr: address to read |
| 33 | * form CNXXXXpX.X-FREQ-SUFFIX. | ||
| 34 | * - XXXX = The chip model number | ||
| 35 | * - X.X = Chip pass number | ||
| 36 | * - FREQ = Current frequency in Mhz | ||
| 37 | * - SUFFIX = NSP, EXP, SCP, SSP, or CP | ||
| 38 | * | ||
| 39 | * @chip_id: Chip ID | ||
| 40 | * | 33 | * |
| 41 | * Returns Model string | 34 | * Returns fuse value: 0 or 1 |
| 42 | */ | 35 | */ |
| 43 | const char *octeon_model_get_string(uint32_t chip_id) | 36 | static uint8_t __init cvmx_fuse_read_byte(int byte_addr) |
| 44 | { | 37 | { |
| 45 | static char buffer[32]; | 38 | union cvmx_mio_fus_rcmd read_cmd; |
| 46 | return octeon_model_get_string_buffer(chip_id, buffer); | 39 | |
| 40 | read_cmd.u64 = 0; | ||
| 41 | read_cmd.s.addr = byte_addr; | ||
| 42 | read_cmd.s.pend = 1; | ||
| 43 | cvmx_write_csr(CVMX_MIO_FUS_RCMD, read_cmd.u64); | ||
| 44 | while ((read_cmd.u64 = cvmx_read_csr(CVMX_MIO_FUS_RCMD)) | ||
| 45 | && read_cmd.s.pend) | ||
| 46 | ; | ||
| 47 | return read_cmd.s.dat; | ||
| 47 | } | 48 | } |
| 48 | 49 | ||
| 49 | /* | 50 | /* |
| @@ -51,7 +52,8 @@ const char *octeon_model_get_string(uint32_t chip_id) | |||
| 51 | * as running early in u-boot static/global variables don't work when | 52 | * as running early in u-boot static/global variables don't work when |
| 52 | * running from flash. | 53 | * running from flash. |
| 53 | */ | 54 | */ |
| 54 | const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer) | 55 | static const char *__init octeon_model_get_string_buffer(uint32_t chip_id, |
| 56 | char *buffer) | ||
| 55 | { | 57 | { |
| 56 | const char *family; | 58 | const char *family; |
| 57 | const char *core_model; | 59 | const char *core_model; |
| @@ -407,3 +409,22 @@ const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer) | |||
| 407 | sprintf(buffer, "CN%s%sp%s-%d-%s", family, core_model, pass, clock_mhz, suffix); | 409 | sprintf(buffer, "CN%s%sp%s-%d-%s", family, core_model, pass, clock_mhz, suffix); |
| 408 | return buffer; | 410 | return buffer; |
| 409 | } | 411 | } |
| 412 | |||
| 413 | /** | ||
| 414 | * Given the chip processor ID from COP0, this function returns a | ||
| 415 | * string representing the chip model number. The string is of the | ||
| 416 | * form CNXXXXpX.X-FREQ-SUFFIX. | ||
| 417 | * - XXXX = The chip model number | ||
| 418 | * - X.X = Chip pass number | ||
| 419 | * - FREQ = Current frequency in Mhz | ||
| 420 | * - SUFFIX = NSP, EXP, SCP, SSP, or CP | ||
| 421 | * | ||
| 422 | * @chip_id: Chip ID | ||
| 423 | * | ||
| 424 | * Returns Model string | ||
| 425 | */ | ||
| 426 | const char *__init octeon_model_get_string(uint32_t chip_id) | ||
| 427 | { | ||
| 428 | static char buffer[32]; | ||
| 429 | return octeon_model_get_string_buffer(chip_id, buffer); | ||
| 430 | } | ||
diff --git a/arch/mips/configs/bcm3384_defconfig b/arch/mips/configs/bcm3384_defconfig new file mode 100644 index 000000000000..88711c28ff32 --- /dev/null +++ b/arch/mips/configs/bcm3384_defconfig | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | CONFIG_BCM3384=y | ||
| 2 | CONFIG_HIGHMEM=y | ||
| 3 | CONFIG_SMP=y | ||
| 4 | CONFIG_NR_CPUS=4 | ||
| 5 | # CONFIG_SECCOMP is not set | ||
| 6 | CONFIG_MIPS_O32_FP64_SUPPORT=y | ||
| 7 | # CONFIG_LOCALVERSION_AUTO is not set | ||
| 8 | # CONFIG_SWAP is not set | ||
| 9 | CONFIG_NO_HZ=y | ||
| 10 | CONFIG_BLK_DEV_INITRD=y | ||
| 11 | # CONFIG_RD_GZIP is not set | ||
| 12 | CONFIG_EXPERT=y | ||
| 13 | # CONFIG_VM_EVENT_COUNTERS is not set | ||
| 14 | # CONFIG_SLUB_DEBUG is not set | ||
| 15 | # CONFIG_BLK_DEV_BSG is not set | ||
| 16 | # CONFIG_IOSCHED_DEADLINE is not set | ||
| 17 | # CONFIG_IOSCHED_CFQ is not set | ||
| 18 | CONFIG_NET=y | ||
| 19 | CONFIG_PACKET=y | ||
| 20 | CONFIG_PACKET_DIAG=y | ||
| 21 | CONFIG_UNIX=y | ||
| 22 | CONFIG_INET=y | ||
| 23 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
| 24 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
| 25 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
| 26 | # CONFIG_INET_LRO is not set | ||
| 27 | # CONFIG_INET_DIAG is not set | ||
| 28 | CONFIG_CFG80211=y | ||
| 29 | CONFIG_NL80211_TESTMODE=y | ||
| 30 | CONFIG_MAC80211=y | ||
| 31 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
| 32 | CONFIG_DEVTMPFS=y | ||
| 33 | CONFIG_DEVTMPFS_MOUNT=y | ||
| 34 | # CONFIG_STANDALONE is not set | ||
| 35 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set | ||
| 36 | CONFIG_MTD=y | ||
| 37 | CONFIG_MTD_CFI=y | ||
| 38 | CONFIG_MTD_CFI_INTELEXT=y | ||
| 39 | CONFIG_MTD_CFI_AMDSTD=y | ||
| 40 | CONFIG_MTD_PHYSMAP=y | ||
| 41 | # CONFIG_BLK_DEV is not set | ||
| 42 | CONFIG_SCSI=y | ||
| 43 | CONFIG_BLK_DEV_SD=y | ||
| 44 | # CONFIG_SCSI_LOWLEVEL is not set | ||
| 45 | CONFIG_NETDEVICES=y | ||
| 46 | CONFIG_USB_USBNET=y | ||
| 47 | # CONFIG_INPUT is not set | ||
| 48 | # CONFIG_SERIO is not set | ||
| 49 | # CONFIG_VT is not set | ||
| 50 | # CONFIG_DEVKMEM is not set | ||
| 51 | CONFIG_SERIAL_EARLYCON_FORCE=y | ||
| 52 | CONFIG_SERIAL_BCM63XX=y | ||
| 53 | CONFIG_SERIAL_BCM63XX_CONSOLE=y | ||
| 54 | # CONFIG_HW_RANDOM is not set | ||
| 55 | # CONFIG_HWMON is not set | ||
| 56 | CONFIG_USB=y | ||
| 57 | CONFIG_USB_EHCI_HCD=y | ||
| 58 | # CONFIG_USB_EHCI_TT_NEWSCHED is not set | ||
| 59 | CONFIG_USB_EHCI_HCD_PLATFORM=y | ||
| 60 | CONFIG_USB_OHCI_HCD=y | ||
| 61 | CONFIG_USB_OHCI_HCD_PLATFORM=y | ||
| 62 | CONFIG_USB_STORAGE=y | ||
| 63 | CONFIG_EXT4_FS=y | ||
| 64 | CONFIG_EXT4_FS_POSIX_ACL=y | ||
| 65 | CONFIG_EXT4_FS_SECURITY=y | ||
| 66 | # CONFIG_DNOTIFY is not set | ||
| 67 | CONFIG_FUSE_FS=y | ||
| 68 | CONFIG_VFAT_FS=y | ||
| 69 | CONFIG_PROC_KCORE=y | ||
| 70 | CONFIG_TMPFS=y | ||
| 71 | CONFIG_NFS_FS=y | ||
| 72 | CONFIG_CIFS=y | ||
| 73 | CONFIG_NLS_CODEPAGE_437=y | ||
| 74 | CONFIG_NLS_ASCII=y | ||
| 75 | CONFIG_NLS_ISO8859_1=y | ||
| 76 | CONFIG_DEBUG_FS=y | ||
| 77 | CONFIG_MAGIC_SYSRQ=y | ||
| 78 | # CONFIG_CRYPTO_HW is not set | ||
diff --git a/arch/mips/fw/lib/cmdline.c b/arch/mips/fw/lib/cmdline.c index ffd0345780ae..6ecda64ad184 100644 --- a/arch/mips/fw/lib/cmdline.c +++ b/arch/mips/fw/lib/cmdline.c | |||
| @@ -68,7 +68,7 @@ char *fw_getenv(char *envname) | |||
| 68 | result = fw_envp(index + 1); | 68 | result = fw_envp(index + 1); |
| 69 | break; | 69 | break; |
| 70 | } else if (fw_envp(index)[i] == '=') { | 70 | } else if (fw_envp(index)[i] == '=') { |
| 71 | result = (fw_envp(index + 1) + i); | 71 | result = fw_envp(index) + i + 1; |
| 72 | break; | 72 | break; |
| 73 | } | 73 | } |
| 74 | } | 74 | } |
| @@ -88,13 +88,13 @@ unsigned long fw_getenvl(char *envname) | |||
| 88 | { | 88 | { |
| 89 | unsigned long envl = 0UL; | 89 | unsigned long envl = 0UL; |
| 90 | char *str; | 90 | char *str; |
| 91 | long val; | ||
| 92 | int tmp; | 91 | int tmp; |
| 93 | 92 | ||
| 94 | str = fw_getenv(envname); | 93 | str = fw_getenv(envname); |
| 95 | if (str) { | 94 | if (str) { |
| 96 | tmp = kstrtol(str, 0, &val); | 95 | tmp = kstrtoul(str, 0, &envl); |
| 97 | envl = (unsigned long)val; | 96 | if (tmp) |
| 97 | envl = 0; | ||
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | return envl; | 100 | return envl; |
diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h index 6dd6bfc607e9..857da84cfc92 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <linux/irqflags.h> | 17 | #include <linux/irqflags.h> |
| 18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
| 19 | #include <asm/barrier.h> | 19 | #include <asm/barrier.h> |
| 20 | #include <asm/compiler.h> | ||
| 20 | #include <asm/cpu-features.h> | 21 | #include <asm/cpu-features.h> |
| 21 | #include <asm/cmpxchg.h> | 22 | #include <asm/cmpxchg.h> |
| 22 | #include <asm/war.h> | 23 | #include <asm/war.h> |
| @@ -40,95 +41,97 @@ | |||
| 40 | */ | 41 | */ |
| 41 | #define atomic_set(v, i) ((v)->counter = (i)) | 42 | #define atomic_set(v, i) ((v)->counter = (i)) |
| 42 | 43 | ||
| 43 | #define ATOMIC_OP(op, c_op, asm_op) \ | 44 | #define ATOMIC_OP(op, c_op, asm_op) \ |
| 44 | static __inline__ void atomic_##op(int i, atomic_t * v) \ | 45 | static __inline__ void atomic_##op(int i, atomic_t * v) \ |
| 45 | { \ | 46 | { \ |
| 46 | if (kernel_uses_llsc && R10000_LLSC_WAR) { \ | 47 | if (kernel_uses_llsc && R10000_LLSC_WAR) { \ |
| 47 | int temp; \ | 48 | int temp; \ |
| 48 | \ | 49 | \ |
| 49 | __asm__ __volatile__( \ | 50 | __asm__ __volatile__( \ |
| 50 | " .set arch=r4000 \n" \ | 51 | " .set arch=r4000 \n" \ |
| 51 | "1: ll %0, %1 # atomic_" #op " \n" \ | 52 | "1: ll %0, %1 # atomic_" #op " \n" \ |
| 52 | " " #asm_op " %0, %2 \n" \ | 53 | " " #asm_op " %0, %2 \n" \ |
| 53 | " sc %0, %1 \n" \ | 54 | " sc %0, %1 \n" \ |
| 54 | " beqzl %0, 1b \n" \ | 55 | " beqzl %0, 1b \n" \ |
| 55 | " .set mips0 \n" \ | 56 | " .set mips0 \n" \ |
| 56 | : "=&r" (temp), "+m" (v->counter) \ | 57 | : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \ |
| 57 | : "Ir" (i)); \ | 58 | : "Ir" (i)); \ |
| 58 | } else if (kernel_uses_llsc) { \ | 59 | } else if (kernel_uses_llsc) { \ |
| 59 | int temp; \ | 60 | int temp; \ |
| 60 | \ | 61 | \ |
| 61 | do { \ | 62 | do { \ |
| 62 | __asm__ __volatile__( \ | 63 | __asm__ __volatile__( \ |
| 63 | " .set arch=r4000 \n" \ | 64 | " .set arch=r4000 \n" \ |
| 64 | " ll %0, %1 # atomic_" #op "\n" \ | 65 | " ll %0, %1 # atomic_" #op "\n" \ |
| 65 | " " #asm_op " %0, %2 \n" \ | 66 | " " #asm_op " %0, %2 \n" \ |
| 66 | " sc %0, %1 \n" \ | 67 | " sc %0, %1 \n" \ |
| 67 | " .set mips0 \n" \ | 68 | " .set mips0 \n" \ |
| 68 | : "=&r" (temp), "+m" (v->counter) \ | 69 | : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \ |
| 69 | : "Ir" (i)); \ | 70 | : "Ir" (i)); \ |
| 70 | } while (unlikely(!temp)); \ | 71 | } while (unlikely(!temp)); \ |
| 71 | } else { \ | 72 | } else { \ |
| 72 | unsigned long flags; \ | 73 | unsigned long flags; \ |
| 73 | \ | 74 | \ |
| 74 | raw_local_irq_save(flags); \ | 75 | raw_local_irq_save(flags); \ |
| 75 | v->counter c_op i; \ | 76 | v->counter c_op i; \ |
| 76 | raw_local_irq_restore(flags); \ | 77 | raw_local_irq_restore(flags); \ |
| 77 | } \ | 78 | } \ |
| 78 | } \ | ||
| 79 | |||
| 80 | #define ATOMIC_OP_RETURN(op, c_op, asm_op) \ | ||
| 81 | static __inline__ int atomic_##op##_return(int i, atomic_t * v) \ | ||
| 82 | { \ | ||
| 83 | int result; \ | ||
| 84 | \ | ||
| 85 | smp_mb__before_llsc(); \ | ||
| 86 | \ | ||
| 87 | if (kernel_uses_llsc && R10000_LLSC_WAR) { \ | ||
| 88 | int temp; \ | ||
| 89 | \ | ||
| 90 | __asm__ __volatile__( \ | ||
| 91 | " .set arch=r4000 \n" \ | ||
| 92 | "1: ll %1, %2 # atomic_" #op "_return \n" \ | ||
| 93 | " " #asm_op " %0, %1, %3 \n" \ | ||
| 94 | " sc %0, %2 \n" \ | ||
| 95 | " beqzl %0, 1b \n" \ | ||
| 96 | " " #asm_op " %0, %1, %3 \n" \ | ||
| 97 | " .set mips0 \n" \ | ||
| 98 | : "=&r" (result), "=&r" (temp), "+m" (v->counter) \ | ||
| 99 | : "Ir" (i)); \ | ||
| 100 | } else if (kernel_uses_llsc) { \ | ||
| 101 | int temp; \ | ||
| 102 | \ | ||
| 103 | do { \ | ||
| 104 | __asm__ __volatile__( \ | ||
| 105 | " .set arch=r4000 \n" \ | ||
| 106 | " ll %1, %2 # atomic_" #op "_return \n" \ | ||
| 107 | " " #asm_op " %0, %1, %3 \n" \ | ||
| 108 | " sc %0, %2 \n" \ | ||
| 109 | " .set mips0 \n" \ | ||
| 110 | : "=&r" (result), "=&r" (temp), "+m" (v->counter) \ | ||
| 111 | : "Ir" (i)); \ | ||
| 112 | } while (unlikely(!result)); \ | ||
| 113 | \ | ||
| 114 | result = temp; result c_op i; \ | ||
| 115 | } else { \ | ||
| 116 | unsigned long flags; \ | ||
| 117 | \ | ||
| 118 | raw_local_irq_save(flags); \ | ||
| 119 | result = v->counter; \ | ||
| 120 | result c_op i; \ | ||
| 121 | v->counter = result; \ | ||
| 122 | raw_local_irq_restore(flags); \ | ||
| 123 | } \ | ||
| 124 | \ | ||
| 125 | smp_llsc_mb(); \ | ||
| 126 | \ | ||
| 127 | return result; \ | ||
| 128 | } | 79 | } |
| 129 | 80 | ||
| 130 | #define ATOMIC_OPS(op, c_op, asm_op) \ | 81 | #define ATOMIC_OP_RETURN(op, c_op, asm_op) \ |
| 131 | ATOMIC_OP(op, c_op, asm_op) \ | 82 | static __inline__ int atomic_##op##_return(int i, atomic_t * v) \ |
| 83 | { \ | ||
| 84 | int result; \ | ||
| 85 | \ | ||
| 86 | smp_mb__before_llsc(); \ | ||
| 87 | \ | ||
| 88 | if (kernel_uses_llsc && R10000_LLSC_WAR) { \ | ||
| 89 | int temp; \ | ||
| 90 | \ | ||
| 91 | __asm__ __volatile__( \ | ||
| 92 | " .set arch=r4000 \n" \ | ||
| 93 | "1: ll %1, %2 # atomic_" #op "_return \n" \ | ||
| 94 | " " #asm_op " %0, %1, %3 \n" \ | ||
| 95 | " sc %0, %2 \n" \ | ||
| 96 | " beqzl %0, 1b \n" \ | ||
| 97 | " " #asm_op " %0, %1, %3 \n" \ | ||
| 98 | " .set mips0 \n" \ | ||
| 99 | : "=&r" (result), "=&r" (temp), \ | ||
| 100 | "+" GCC_OFF12_ASM() (v->counter) \ | ||
| 101 | : "Ir" (i)); \ | ||
| 102 | } else if (kernel_uses_llsc) { \ | ||
| 103 | int temp; \ | ||
| 104 | \ | ||
| 105 | do { \ | ||
| 106 | __asm__ __volatile__( \ | ||
| 107 | " .set arch=r4000 \n" \ | ||
| 108 | " ll %1, %2 # atomic_" #op "_return \n" \ | ||
| 109 | " " #asm_op " %0, %1, %3 \n" \ | ||
| 110 | " sc %0, %2 \n" \ | ||
| 111 | " .set mips0 \n" \ | ||
| 112 | : "=&r" (result), "=&r" (temp), \ | ||
| 113 | "+" GCC_OFF12_ASM() (v->counter) \ | ||
| 114 | : "Ir" (i)); \ | ||
| 115 | } while (unlikely(!result)); \ | ||
| 116 | \ | ||
| 117 | result = temp; result c_op i; \ | ||
| 118 | } else { \ | ||
| 119 | unsigned long flags; \ | ||
| 120 | \ | ||
| 121 | raw_local_irq_save(flags); \ | ||
| 122 | result = v->counter; \ | ||
| 123 | result c_op i; \ | ||
| 124 | v->counter = result; \ | ||
| 125 | raw_local_irq_restore(flags); \ | ||
| 126 | } \ | ||
| 127 | \ | ||
| 128 | smp_llsc_mb(); \ | ||
| 129 | \ | ||
| 130 | return result; \ | ||
| 131 | } | ||
| 132 | |||
| 133 | #define ATOMIC_OPS(op, c_op, asm_op) \ | ||
| 134 | ATOMIC_OP(op, c_op, asm_op) \ | ||
| 132 | ATOMIC_OP_RETURN(op, c_op, asm_op) | 135 | ATOMIC_OP_RETURN(op, c_op, asm_op) |
| 133 | 136 | ||
| 134 | ATOMIC_OPS(add, +=, addu) | 137 | ATOMIC_OPS(add, +=, addu) |
| @@ -167,8 +170,9 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) | |||
| 167 | " .set reorder \n" | 170 | " .set reorder \n" |
| 168 | "1: \n" | 171 | "1: \n" |
| 169 | " .set mips0 \n" | 172 | " .set mips0 \n" |
| 170 | : "=&r" (result), "=&r" (temp), "+m" (v->counter) | 173 | : "=&r" (result), "=&r" (temp), |
| 171 | : "Ir" (i), "m" (v->counter) | 174 | "+" GCC_OFF12_ASM() (v->counter) |
| 175 | : "Ir" (i), GCC_OFF12_ASM() (v->counter) | ||
| 172 | : "memory"); | 176 | : "memory"); |
| 173 | } else if (kernel_uses_llsc) { | 177 | } else if (kernel_uses_llsc) { |
| 174 | int temp; | 178 | int temp; |
| @@ -185,7 +189,8 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) | |||
| 185 | " .set reorder \n" | 189 | " .set reorder \n" |
| 186 | "1: \n" | 190 | "1: \n" |
| 187 | " .set mips0 \n" | 191 | " .set mips0 \n" |
| 188 | : "=&r" (result), "=&r" (temp), "+m" (v->counter) | 192 | : "=&r" (result), "=&r" (temp), |
| 193 | "+" GCC_OFF12_ASM() (v->counter) | ||
| 189 | : "Ir" (i)); | 194 | : "Ir" (i)); |
| 190 | } else { | 195 | } else { |
| 191 | unsigned long flags; | 196 | unsigned long flags; |
| @@ -315,96 +320,98 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) | |||
| 315 | */ | 320 | */ |
| 316 | #define atomic64_set(v, i) ((v)->counter = (i)) | 321 | #define atomic64_set(v, i) ((v)->counter = (i)) |
| 317 | 322 | ||
| 318 | #define ATOMIC64_OP(op, c_op, asm_op) \ | 323 | #define ATOMIC64_OP(op, c_op, asm_op) \ |
| 319 | static __inline__ void atomic64_##op(long i, atomic64_t * v) \ | 324 | static __inline__ void atomic64_##op(long i, atomic64_t * v) \ |
| 320 | { \ | 325 | { \ |
| 321 | if (kernel_uses_llsc && R10000_LLSC_WAR) { \ | 326 | if (kernel_uses_llsc && R10000_LLSC_WAR) { \ |
| 322 | long temp; \ | 327 | long temp; \ |
| 323 | \ | 328 | \ |
| 324 | __asm__ __volatile__( \ | 329 | __asm__ __volatile__( \ |
| 325 | " .set arch=r4000 \n" \ | 330 | " .set arch=r4000 \n" \ |
| 326 | "1: lld %0, %1 # atomic64_" #op " \n" \ | 331 | "1: lld %0, %1 # atomic64_" #op " \n" \ |
| 327 | " " #asm_op " %0, %2 \n" \ | 332 | " " #asm_op " %0, %2 \n" \ |
| 328 | " scd %0, %1 \n" \ | 333 | " scd %0, %1 \n" \ |
| 329 | " beqzl %0, 1b \n" \ | 334 | " beqzl %0, 1b \n" \ |
| 330 | " .set mips0 \n" \ | 335 | " .set mips0 \n" \ |
| 331 | : "=&r" (temp), "+m" (v->counter) \ | 336 | : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \ |
| 332 | : "Ir" (i)); \ | 337 | : "Ir" (i)); \ |
| 333 | } else if (kernel_uses_llsc) { \ | 338 | } else if (kernel_uses_llsc) { \ |
| 334 | long temp; \ | 339 | long temp; \ |
| 335 | \ | 340 | \ |
| 336 | do { \ | 341 | do { \ |
| 337 | __asm__ __volatile__( \ | 342 | __asm__ __volatile__( \ |
| 338 | " .set arch=r4000 \n" \ | 343 | " .set arch=r4000 \n" \ |
| 339 | " lld %0, %1 # atomic64_" #op "\n" \ | 344 | " lld %0, %1 # atomic64_" #op "\n" \ |
| 340 | " " #asm_op " %0, %2 \n" \ | 345 | " " #asm_op " %0, %2 \n" \ |
| 341 | " scd %0, %1 \n" \ | 346 | " scd %0, %1 \n" \ |
| 342 | " .set mips0 \n" \ | 347 | " .set mips0 \n" \ |
| 343 | : "=&r" (temp), "+m" (v->counter) \ | 348 | : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \ |
| 344 | : "Ir" (i)); \ | 349 | : "Ir" (i)); \ |
| 345 | } while (unlikely(!temp)); \ | 350 | } while (unlikely(!temp)); \ |
| 346 | } else { \ | 351 | } else { \ |
| 347 | unsigned long flags; \ | 352 | unsigned long flags; \ |
| 348 | \ | 353 | \ |
| 349 | raw_local_irq_save(flags); \ | 354 | raw_local_irq_save(flags); \ |
| 350 | v->counter c_op i; \ | 355 | v->counter c_op i; \ |
| 351 | raw_local_irq_restore(flags); \ | 356 | raw_local_irq_restore(flags); \ |
| 352 | } \ | 357 | } \ |
| 353 | } \ | 358 | } |
| 354 | 359 | ||
| 355 | #define ATOMIC64_OP_RETURN(op, c_op, asm_op) \ | 360 | #define ATOMIC64_OP_RETURN(op, c_op, asm_op) \ |
| 356 | static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \ | 361 | static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \ |
| 357 | { \ | 362 | { \ |
| 358 | long result; \ | 363 | long result; \ |
| 359 | \ | 364 | \ |
| 360 | smp_mb__before_llsc(); \ | 365 | smp_mb__before_llsc(); \ |
| 361 | \ | 366 | \ |
| 362 | if (kernel_uses_llsc && R10000_LLSC_WAR) { \ | 367 | if (kernel_uses_llsc && R10000_LLSC_WAR) { \ |
| 363 | long temp; \ | 368 | long temp; \ |
| 364 | \ | 369 | \ |
| 365 | __asm__ __volatile__( \ | 370 | __asm__ __volatile__( \ |
| 366 | " .set arch=r4000 \n" \ | 371 | " .set arch=r4000 \n" \ |
| 367 | "1: lld %1, %2 # atomic64_" #op "_return\n" \ | 372 | "1: lld %1, %2 # atomic64_" #op "_return\n" \ |
| 368 | " " #asm_op " %0, %1, %3 \n" \ | 373 | " " #asm_op " %0, %1, %3 \n" \ |
| 369 | " scd %0, %2 \n" \ | 374 | " scd %0, %2 \n" \ |
| 370 | " beqzl %0, 1b \n" \ | 375 | " beqzl %0, 1b \n" \ |
| 371 | " " #asm_op " %0, %1, %3 \n" \ | 376 | " " #asm_op " %0, %1, %3 \n" \ |
| 372 | " .set mips0 \n" \ | 377 | " .set mips0 \n" \ |
| 373 | : "=&r" (result), "=&r" (temp), "+m" (v->counter) \ | 378 | : "=&r" (result), "=&r" (temp), \ |
| 374 | : "Ir" (i)); \ | 379 | "+" GCC_OFF12_ASM() (v->counter) \ |
| 375 | } else if (kernel_uses_llsc) { \ | 380 | : "Ir" (i)); \ |
| 376 | long temp; \ | 381 | } else if (kernel_uses_llsc) { \ |
| 377 | \ | 382 | long temp; \ |
| 378 | do { \ | 383 | \ |
| 379 | __asm__ __volatile__( \ | 384 | do { \ |
| 380 | " .set arch=r4000 \n" \ | 385 | __asm__ __volatile__( \ |
| 381 | " lld %1, %2 # atomic64_" #op "_return\n" \ | 386 | " .set arch=r4000 \n" \ |
| 382 | " " #asm_op " %0, %1, %3 \n" \ | 387 | " lld %1, %2 # atomic64_" #op "_return\n" \ |
| 383 | " scd %0, %2 \n" \ | 388 | " " #asm_op " %0, %1, %3 \n" \ |
| 384 | " .set mips0 \n" \ | 389 | " scd %0, %2 \n" \ |
| 385 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) \ | 390 | " .set mips0 \n" \ |
| 386 | : "Ir" (i), "m" (v->counter) \ | 391 | : "=&r" (result), "=&r" (temp), \ |
| 387 | : "memory"); \ | 392 | "=" GCC_OFF12_ASM() (v->counter) \ |
| 388 | } while (unlikely(!result)); \ | 393 | : "Ir" (i), GCC_OFF12_ASM() (v->counter) \ |
| 389 | \ | 394 | : "memory"); \ |
| 390 | result = temp; result c_op i; \ | 395 | } while (unlikely(!result)); \ |
| 391 | } else { \ | 396 | \ |
| 392 | unsigned long flags; \ | 397 | result = temp; result c_op i; \ |
| 393 | \ | 398 | } else { \ |
| 394 | raw_local_irq_save(flags); \ | 399 | unsigned long flags; \ |
| 395 | result = v->counter; \ | 400 | \ |
| 396 | result c_op i; \ | 401 | raw_local_irq_save(flags); \ |
| 397 | v->counter = result; \ | 402 | result = v->counter; \ |
| 398 | raw_local_irq_restore(flags); \ | 403 | result c_op i; \ |
| 399 | } \ | 404 | v->counter = result; \ |
| 400 | \ | 405 | raw_local_irq_restore(flags); \ |
| 401 | smp_llsc_mb(); \ | 406 | } \ |
| 402 | \ | 407 | \ |
| 403 | return result; \ | 408 | smp_llsc_mb(); \ |
| 409 | \ | ||
| 410 | return result; \ | ||
| 404 | } | 411 | } |
| 405 | 412 | ||
| 406 | #define ATOMIC64_OPS(op, c_op, asm_op) \ | 413 | #define ATOMIC64_OPS(op, c_op, asm_op) \ |
| 407 | ATOMIC64_OP(op, c_op, asm_op) \ | 414 | ATOMIC64_OP(op, c_op, asm_op) \ |
| 408 | ATOMIC64_OP_RETURN(op, c_op, asm_op) | 415 | ATOMIC64_OP_RETURN(op, c_op, asm_op) |
| 409 | 416 | ||
| 410 | ATOMIC64_OPS(add, +=, daddu) | 417 | ATOMIC64_OPS(add, +=, daddu) |
| @@ -415,7 +422,8 @@ ATOMIC64_OPS(sub, -=, dsubu) | |||
| 415 | #undef ATOMIC64_OP | 422 | #undef ATOMIC64_OP |
| 416 | 423 | ||
| 417 | /* | 424 | /* |
| 418 | * atomic64_sub_if_positive - conditionally subtract integer from atomic variable | 425 | * atomic64_sub_if_positive - conditionally subtract integer from atomic |
| 426 | * variable | ||
| 419 | * @i: integer value to subtract | 427 | * @i: integer value to subtract |
| 420 | * @v: pointer of type atomic64_t | 428 | * @v: pointer of type atomic64_t |
| 421 | * | 429 | * |
| @@ -443,8 +451,9 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) | |||
| 443 | " .set reorder \n" | 451 | " .set reorder \n" |
| 444 | "1: \n" | 452 | "1: \n" |
| 445 | " .set mips0 \n" | 453 | " .set mips0 \n" |
| 446 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) | 454 | : "=&r" (result), "=&r" (temp), |
| 447 | : "Ir" (i), "m" (v->counter) | 455 | "=" GCC_OFF12_ASM() (v->counter) |
| 456 | : "Ir" (i), GCC_OFF12_ASM() (v->counter) | ||
| 448 | : "memory"); | 457 | : "memory"); |
| 449 | } else if (kernel_uses_llsc) { | 458 | } else if (kernel_uses_llsc) { |
| 450 | long temp; | 459 | long temp; |
| @@ -461,7 +470,8 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) | |||
| 461 | " .set reorder \n" | 470 | " .set reorder \n" |
| 462 | "1: \n" | 471 | "1: \n" |
| 463 | " .set mips0 \n" | 472 | " .set mips0 \n" |
| 464 | : "=&r" (result), "=&r" (temp), "+m" (v->counter) | 473 | : "=&r" (result), "=&r" (temp), |
| 474 | "+" GCC_OFF12_ASM() (v->counter) | ||
| 465 | : "Ir" (i)); | 475 | : "Ir" (i)); |
| 466 | } else { | 476 | } else { |
| 467 | unsigned long flags; | 477 | unsigned long flags; |
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h index bae6b0fa8ab5..6663bcca9d0c 100644 --- a/arch/mips/include/asm/bitops.h +++ b/arch/mips/include/asm/bitops.h | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
| 18 | #include <asm/barrier.h> | 18 | #include <asm/barrier.h> |
| 19 | #include <asm/byteorder.h> /* sigh ... */ | 19 | #include <asm/byteorder.h> /* sigh ... */ |
| 20 | #include <asm/compiler.h> | ||
| 20 | #include <asm/cpu-features.h> | 21 | #include <asm/cpu-features.h> |
| 21 | #include <asm/sgidefs.h> | 22 | #include <asm/sgidefs.h> |
| 22 | #include <asm/war.h> | 23 | #include <asm/war.h> |
| @@ -78,8 +79,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 78 | " " __SC "%0, %1 \n" | 79 | " " __SC "%0, %1 \n" |
| 79 | " beqzl %0, 1b \n" | 80 | " beqzl %0, 1b \n" |
| 80 | " .set mips0 \n" | 81 | " .set mips0 \n" |
| 81 | : "=&r" (temp), "=m" (*m) | 82 | : "=&r" (temp), "=" GCC_OFF12_ASM() (*m) |
| 82 | : "ir" (1UL << bit), "m" (*m)); | 83 | : "ir" (1UL << bit), GCC_OFF12_ASM() (*m)); |
| 83 | #ifdef CONFIG_CPU_MIPSR2 | 84 | #ifdef CONFIG_CPU_MIPSR2 |
| 84 | } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { | 85 | } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { |
| 85 | do { | 86 | do { |
| @@ -87,7 +88,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 87 | " " __LL "%0, %1 # set_bit \n" | 88 | " " __LL "%0, %1 # set_bit \n" |
| 88 | " " __INS "%0, %3, %2, 1 \n" | 89 | " " __INS "%0, %3, %2, 1 \n" |
| 89 | " " __SC "%0, %1 \n" | 90 | " " __SC "%0, %1 \n" |
| 90 | : "=&r" (temp), "+m" (*m) | 91 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m) |
| 91 | : "ir" (bit), "r" (~0)); | 92 | : "ir" (bit), "r" (~0)); |
| 92 | } while (unlikely(!temp)); | 93 | } while (unlikely(!temp)); |
| 93 | #endif /* CONFIG_CPU_MIPSR2 */ | 94 | #endif /* CONFIG_CPU_MIPSR2 */ |
| @@ -99,7 +100,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 99 | " or %0, %2 \n" | 100 | " or %0, %2 \n" |
| 100 | " " __SC "%0, %1 \n" | 101 | " " __SC "%0, %1 \n" |
| 101 | " .set mips0 \n" | 102 | " .set mips0 \n" |
| 102 | : "=&r" (temp), "+m" (*m) | 103 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m) |
| 103 | : "ir" (1UL << bit)); | 104 | : "ir" (1UL << bit)); |
| 104 | } while (unlikely(!temp)); | 105 | } while (unlikely(!temp)); |
| 105 | } else | 106 | } else |
| @@ -130,7 +131,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 130 | " " __SC "%0, %1 \n" | 131 | " " __SC "%0, %1 \n" |
| 131 | " beqzl %0, 1b \n" | 132 | " beqzl %0, 1b \n" |
| 132 | " .set mips0 \n" | 133 | " .set mips0 \n" |
| 133 | : "=&r" (temp), "+m" (*m) | 134 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m) |
| 134 | : "ir" (~(1UL << bit))); | 135 | : "ir" (~(1UL << bit))); |
| 135 | #ifdef CONFIG_CPU_MIPSR2 | 136 | #ifdef CONFIG_CPU_MIPSR2 |
| 136 | } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { | 137 | } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { |
| @@ -139,7 +140,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 139 | " " __LL "%0, %1 # clear_bit \n" | 140 | " " __LL "%0, %1 # clear_bit \n" |
| 140 | " " __INS "%0, $0, %2, 1 \n" | 141 | " " __INS "%0, $0, %2, 1 \n" |
| 141 | " " __SC "%0, %1 \n" | 142 | " " __SC "%0, %1 \n" |
| 142 | : "=&r" (temp), "+m" (*m) | 143 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m) |
| 143 | : "ir" (bit)); | 144 | : "ir" (bit)); |
| 144 | } while (unlikely(!temp)); | 145 | } while (unlikely(!temp)); |
| 145 | #endif /* CONFIG_CPU_MIPSR2 */ | 146 | #endif /* CONFIG_CPU_MIPSR2 */ |
| @@ -151,7 +152,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 151 | " and %0, %2 \n" | 152 | " and %0, %2 \n" |
| 152 | " " __SC "%0, %1 \n" | 153 | " " __SC "%0, %1 \n" |
| 153 | " .set mips0 \n" | 154 | " .set mips0 \n" |
| 154 | : "=&r" (temp), "+m" (*m) | 155 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m) |
| 155 | : "ir" (~(1UL << bit))); | 156 | : "ir" (~(1UL << bit))); |
| 156 | } while (unlikely(!temp)); | 157 | } while (unlikely(!temp)); |
| 157 | } else | 158 | } else |
| @@ -196,7 +197,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 196 | " " __SC "%0, %1 \n" | 197 | " " __SC "%0, %1 \n" |
| 197 | " beqzl %0, 1b \n" | 198 | " beqzl %0, 1b \n" |
| 198 | " .set mips0 \n" | 199 | " .set mips0 \n" |
| 199 | : "=&r" (temp), "+m" (*m) | 200 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m) |
| 200 | : "ir" (1UL << bit)); | 201 | : "ir" (1UL << bit)); |
| 201 | } else if (kernel_uses_llsc) { | 202 | } else if (kernel_uses_llsc) { |
| 202 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); | 203 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); |
| @@ -209,7 +210,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) | |||
| 209 | " xor %0, %2 \n" | 210 | " xor %0, %2 \n" |
| 210 | " " __SC "%0, %1 \n" | 211 | " " __SC "%0, %1 \n" |
| 211 | " .set mips0 \n" | 212 | " .set mips0 \n" |
| 212 | : "=&r" (temp), "+m" (*m) | 213 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m) |
| 213 | : "ir" (1UL << bit)); | 214 | : "ir" (1UL << bit)); |
| 214 | } while (unlikely(!temp)); | 215 | } while (unlikely(!temp)); |
| 215 | } else | 216 | } else |
| @@ -244,7 +245,7 @@ static inline int test_and_set_bit(unsigned long nr, | |||
| 244 | " beqzl %2, 1b \n" | 245 | " beqzl %2, 1b \n" |
| 245 | " and %2, %0, %3 \n" | 246 | " and %2, %0, %3 \n" |
| 246 | " .set mips0 \n" | 247 | " .set mips0 \n" |
| 247 | : "=&r" (temp), "+m" (*m), "=&r" (res) | 248 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) |
| 248 | : "r" (1UL << bit) | 249 | : "r" (1UL << bit) |
| 249 | : "memory"); | 250 | : "memory"); |
| 250 | } else if (kernel_uses_llsc) { | 251 | } else if (kernel_uses_llsc) { |
| @@ -258,7 +259,7 @@ static inline int test_and_set_bit(unsigned long nr, | |||
| 258 | " or %2, %0, %3 \n" | 259 | " or %2, %0, %3 \n" |
| 259 | " " __SC "%2, %1 \n" | 260 | " " __SC "%2, %1 \n" |
| 260 | " .set mips0 \n" | 261 | " .set mips0 \n" |
| 261 | : "=&r" (temp), "+m" (*m), "=&r" (res) | 262 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) |
| 262 | : "r" (1UL << bit) | 263 | : "r" (1UL << bit) |
| 263 | : "memory"); | 264 | : "memory"); |
| 264 | } while (unlikely(!res)); | 265 | } while (unlikely(!res)); |
| @@ -312,7 +313,7 @@ static inline int test_and_set_bit_lock(unsigned long nr, | |||
| 312 | " or %2, %0, %3 \n" | 313 | " or %2, %0, %3 \n" |
| 313 | " " __SC "%2, %1 \n" | 314 | " " __SC "%2, %1 \n" |
| 314 | " .set mips0 \n" | 315 | " .set mips0 \n" |
| 315 | : "=&r" (temp), "+m" (*m), "=&r" (res) | 316 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) |
| 316 | : "r" (1UL << bit) | 317 | : "r" (1UL << bit) |
| 317 | : "memory"); | 318 | : "memory"); |
| 318 | } while (unlikely(!res)); | 319 | } while (unlikely(!res)); |
| @@ -354,7 +355,7 @@ static inline int test_and_clear_bit(unsigned long nr, | |||
| 354 | " beqzl %2, 1b \n" | 355 | " beqzl %2, 1b \n" |
| 355 | " and %2, %0, %3 \n" | 356 | " and %2, %0, %3 \n" |
| 356 | " .set mips0 \n" | 357 | " .set mips0 \n" |
| 357 | : "=&r" (temp), "+m" (*m), "=&r" (res) | 358 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) |
| 358 | : "r" (1UL << bit) | 359 | : "r" (1UL << bit) |
| 359 | : "memory"); | 360 | : "memory"); |
| 360 | #ifdef CONFIG_CPU_MIPSR2 | 361 | #ifdef CONFIG_CPU_MIPSR2 |
| @@ -368,7 +369,7 @@ static inline int test_and_clear_bit(unsigned long nr, | |||
| 368 | " " __EXT "%2, %0, %3, 1 \n" | 369 | " " __EXT "%2, %0, %3, 1 \n" |
| 369 | " " __INS "%0, $0, %3, 1 \n" | 370 | " " __INS "%0, $0, %3, 1 \n" |
| 370 | " " __SC "%0, %1 \n" | 371 | " " __SC "%0, %1 \n" |
| 371 | : "=&r" (temp), "+m" (*m), "=&r" (res) | 372 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) |
| 372 | : "ir" (bit) | 373 | : "ir" (bit) |
| 373 | : "memory"); | 374 | : "memory"); |
| 374 | } while (unlikely(!temp)); | 375 | } while (unlikely(!temp)); |
| @@ -385,7 +386,7 @@ static inline int test_and_clear_bit(unsigned long nr, | |||
| 385 | " xor %2, %3 \n" | 386 | " xor %2, %3 \n" |
| 386 | " " __SC "%2, %1 \n" | 387 | " " __SC "%2, %1 \n" |
| 387 | " .set mips0 \n" | 388 | " .set mips0 \n" |
| 388 | : "=&r" (temp), "+m" (*m), "=&r" (res) | 389 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) |
| 389 | : "r" (1UL << bit) | 390 | : "r" (1UL << bit) |
| 390 | : "memory"); | 391 | : "memory"); |
| 391 | } while (unlikely(!res)); | 392 | } while (unlikely(!res)); |
| @@ -427,7 +428,7 @@ static inline int test_and_change_bit(unsigned long nr, | |||
| 427 | " beqzl %2, 1b \n" | 428 | " beqzl %2, 1b \n" |
| 428 | " and %2, %0, %3 \n" | 429 | " and %2, %0, %3 \n" |
| 429 | " .set mips0 \n" | 430 | " .set mips0 \n" |
| 430 | : "=&r" (temp), "+m" (*m), "=&r" (res) | 431 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) |
| 431 | : "r" (1UL << bit) | 432 | : "r" (1UL << bit) |
| 432 | : "memory"); | 433 | : "memory"); |
| 433 | } else if (kernel_uses_llsc) { | 434 | } else if (kernel_uses_llsc) { |
| @@ -441,7 +442,7 @@ static inline int test_and_change_bit(unsigned long nr, | |||
| 441 | " xor %2, %0, %3 \n" | 442 | " xor %2, %0, %3 \n" |
| 442 | " " __SC "\t%2, %1 \n" | 443 | " " __SC "\t%2, %1 \n" |
| 443 | " .set mips0 \n" | 444 | " .set mips0 \n" |
| 444 | : "=&r" (temp), "+m" (*m), "=&r" (res) | 445 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) |
| 445 | : "r" (1UL << bit) | 446 | : "r" (1UL << bit) |
| 446 | : "memory"); | 447 | : "memory"); |
| 447 | } while (unlikely(!res)); | 448 | } while (unlikely(!res)); |
diff --git a/arch/mips/include/asm/bmips.h b/arch/mips/include/asm/bmips.h index cbaccebf5065..30939b02e3ff 100644 --- a/arch/mips/include/asm/bmips.h +++ b/arch/mips/include/asm/bmips.h | |||
| @@ -84,6 +84,7 @@ extern char bmips_smp_int_vec_end; | |||
| 84 | extern int bmips_smp_enabled; | 84 | extern int bmips_smp_enabled; |
| 85 | extern int bmips_cpu_offset; | 85 | extern int bmips_cpu_offset; |
| 86 | extern cpumask_t bmips_booted_mask; | 86 | extern cpumask_t bmips_booted_mask; |
| 87 | extern unsigned long bmips_tp1_irqs; | ||
| 87 | 88 | ||
| 88 | extern void bmips_ebase_setup(void); | 89 | extern void bmips_ebase_setup(void); |
| 89 | extern asmlinkage void plat_wired_tlb_setup(void); | 90 | extern asmlinkage void plat_wired_tlb_setup(void); |
diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h index 1f7ca8b00404..b603804caac5 100644 --- a/arch/mips/include/asm/bootinfo.h +++ b/arch/mips/include/asm/bootinfo.h | |||
| @@ -70,10 +70,7 @@ enum loongson_machine_type { | |||
| 70 | MACH_DEXXON_GDIUM2F10, | 70 | MACH_DEXXON_GDIUM2F10, |
| 71 | MACH_LEMOTE_NAS, | 71 | MACH_LEMOTE_NAS, |
| 72 | MACH_LEMOTE_LL2F, | 72 | MACH_LEMOTE_LL2F, |
| 73 | MACH_LEMOTE_A1004, | 73 | MACH_LOONGSON_GENERIC, |
| 74 | MACH_LEMOTE_A1101, | ||
| 75 | MACH_LEMOTE_A1201, | ||
| 76 | MACH_LEMOTE_A1205, | ||
| 77 | MACH_LOONGSON_END | 74 | MACH_LOONGSON_END |
| 78 | }; | 75 | }; |
| 79 | 76 | ||
| @@ -101,16 +98,16 @@ extern unsigned long mips_machtype; | |||
| 101 | struct boot_mem_map { | 98 | struct boot_mem_map { |
| 102 | int nr_map; | 99 | int nr_map; |
| 103 | struct boot_mem_map_entry { | 100 | struct boot_mem_map_entry { |
| 104 | phys_t addr; /* start of memory segment */ | 101 | phys_addr_t addr; /* start of memory segment */ |
| 105 | phys_t size; /* size of memory segment */ | 102 | phys_addr_t size; /* size of memory segment */ |
| 106 | long type; /* type of memory segment */ | 103 | long type; /* type of memory segment */ |
| 107 | } map[BOOT_MEM_MAP_MAX]; | 104 | } map[BOOT_MEM_MAP_MAX]; |
| 108 | }; | 105 | }; |
| 109 | 106 | ||
| 110 | extern struct boot_mem_map boot_mem_map; | 107 | extern struct boot_mem_map boot_mem_map; |
| 111 | 108 | ||
| 112 | extern void add_memory_region(phys_t start, phys_t size, long type); | 109 | extern void add_memory_region(phys_addr_t start, phys_addr_t size, long type); |
| 113 | extern void detect_memory_region(phys_t start, phys_t sz_min, phys_t sz_max); | 110 | extern void detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max); |
| 114 | 111 | ||
| 115 | extern void prom_init(void); | 112 | extern void prom_init(void); |
| 116 | extern void prom_free_prom_memory(void); | 113 | extern void prom_free_prom_memory(void); |
diff --git a/arch/mips/include/asm/clock.h b/arch/mips/include/asm/clock.h index 778e32d817bc..4809c29a4890 100644 --- a/arch/mips/include/asm/clock.h +++ b/arch/mips/include/asm/clock.h | |||
| @@ -35,9 +35,6 @@ struct clk { | |||
| 35 | #define CLK_ALWAYS_ENABLED (1 << 0) | 35 | #define CLK_ALWAYS_ENABLED (1 << 0) |
| 36 | #define CLK_RATE_PROPAGATES (1 << 1) | 36 | #define CLK_RATE_PROPAGATES (1 << 1) |
| 37 | 37 | ||
| 38 | /* Should be defined by processor-specific code */ | ||
| 39 | void arch_init_clk_ops(struct clk_ops **, int type); | ||
| 40 | |||
| 41 | int clk_init(void); | 38 | int clk_init(void); |
| 42 | 39 | ||
| 43 | int __clk_enable(struct clk *); | 40 | int __clk_enable(struct clk *); |
diff --git a/arch/mips/include/asm/cmpxchg.h b/arch/mips/include/asm/cmpxchg.h index eefcaa363a87..28b1edf19501 100644 --- a/arch/mips/include/asm/cmpxchg.h +++ b/arch/mips/include/asm/cmpxchg.h | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | #include <linux/bug.h> | 11 | #include <linux/bug.h> |
| 12 | #include <linux/irqflags.h> | 12 | #include <linux/irqflags.h> |
| 13 | #include <asm/compiler.h> | ||
| 13 | #include <asm/war.h> | 14 | #include <asm/war.h> |
| 14 | 15 | ||
| 15 | static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) | 16 | static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) |
| @@ -30,8 +31,8 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) | |||
| 30 | " sc %2, %1 \n" | 31 | " sc %2, %1 \n" |
| 31 | " beqzl %2, 1b \n" | 32 | " beqzl %2, 1b \n" |
| 32 | " .set mips0 \n" | 33 | " .set mips0 \n" |
| 33 | : "=&r" (retval), "=m" (*m), "=&r" (dummy) | 34 | : "=&r" (retval), "=" GCC_OFF12_ASM() (*m), "=&r" (dummy) |
| 34 | : "R" (*m), "Jr" (val) | 35 | : GCC_OFF12_ASM() (*m), "Jr" (val) |
| 35 | : "memory"); | 36 | : "memory"); |
| 36 | } else if (kernel_uses_llsc) { | 37 | } else if (kernel_uses_llsc) { |
| 37 | unsigned long dummy; | 38 | unsigned long dummy; |
| @@ -45,8 +46,9 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) | |||
| 45 | " .set arch=r4000 \n" | 46 | " .set arch=r4000 \n" |
| 46 | " sc %2, %1 \n" | 47 | " sc %2, %1 \n" |
| 47 | " .set mips0 \n" | 48 | " .set mips0 \n" |
| 48 | : "=&r" (retval), "=m" (*m), "=&r" (dummy) | 49 | : "=&r" (retval), "=" GCC_OFF12_ASM() (*m), |
| 49 | : "R" (*m), "Jr" (val) | 50 | "=&r" (dummy) |
| 51 | : GCC_OFF12_ASM() (*m), "Jr" (val) | ||
| 50 | : "memory"); | 52 | : "memory"); |
| 51 | } while (unlikely(!dummy)); | 53 | } while (unlikely(!dummy)); |
| 52 | } else { | 54 | } else { |
| @@ -80,8 +82,8 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val) | |||
| 80 | " scd %2, %1 \n" | 82 | " scd %2, %1 \n" |
| 81 | " beqzl %2, 1b \n" | 83 | " beqzl %2, 1b \n" |
| 82 | " .set mips0 \n" | 84 | " .set mips0 \n" |
| 83 | : "=&r" (retval), "=m" (*m), "=&r" (dummy) | 85 | : "=&r" (retval), "=" GCC_OFF12_ASM() (*m), "=&r" (dummy) |
| 84 | : "R" (*m), "Jr" (val) | 86 | : GCC_OFF12_ASM() (*m), "Jr" (val) |
| 85 | : "memory"); | 87 | : "memory"); |
| 86 | } else if (kernel_uses_llsc) { | 88 | } else if (kernel_uses_llsc) { |
| 87 | unsigned long dummy; | 89 | unsigned long dummy; |
| @@ -93,8 +95,9 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val) | |||
| 93 | " move %2, %z4 \n" | 95 | " move %2, %z4 \n" |
| 94 | " scd %2, %1 \n" | 96 | " scd %2, %1 \n" |
| 95 | " .set mips0 \n" | 97 | " .set mips0 \n" |
| 96 | : "=&r" (retval), "=m" (*m), "=&r" (dummy) | 98 | : "=&r" (retval), "=" GCC_OFF12_ASM() (*m), |
| 97 | : "R" (*m), "Jr" (val) | 99 | "=&r" (dummy) |
| 100 | : GCC_OFF12_ASM() (*m), "Jr" (val) | ||
| 98 | : "memory"); | 101 | : "memory"); |
| 99 | } while (unlikely(!dummy)); | 102 | } while (unlikely(!dummy)); |
| 100 | } else { | 103 | } else { |
| @@ -155,8 +158,8 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz | |||
| 155 | " beqzl $1, 1b \n" \ | 158 | " beqzl $1, 1b \n" \ |
| 156 | "2: \n" \ | 159 | "2: \n" \ |
| 157 | " .set pop \n" \ | 160 | " .set pop \n" \ |
| 158 | : "=&r" (__ret), "=R" (*m) \ | 161 | : "=&r" (__ret), "=" GCC_OFF12_ASM() (*m) \ |
| 159 | : "R" (*m), "Jr" (old), "Jr" (new) \ | 162 | : GCC_OFF12_ASM() (*m), "Jr" (old), "Jr" (new) \ |
| 160 | : "memory"); \ | 163 | : "memory"); \ |
| 161 | } else if (kernel_uses_llsc) { \ | 164 | } else if (kernel_uses_llsc) { \ |
| 162 | __asm__ __volatile__( \ | 165 | __asm__ __volatile__( \ |
| @@ -172,8 +175,8 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz | |||
| 172 | " beqz $1, 1b \n" \ | 175 | " beqz $1, 1b \n" \ |
| 173 | " .set pop \n" \ | 176 | " .set pop \n" \ |
| 174 | "2: \n" \ | 177 | "2: \n" \ |
| 175 | : "=&r" (__ret), "=R" (*m) \ | 178 | : "=&r" (__ret), "=" GCC_OFF12_ASM() (*m) \ |
| 176 | : "R" (*m), "Jr" (old), "Jr" (new) \ | 179 | : GCC_OFF12_ASM() (*m), "Jr" (old), "Jr" (new) \ |
| 177 | : "memory"); \ | 180 | : "memory"); \ |
| 178 | } else { \ | 181 | } else { \ |
| 179 | unsigned long __flags; \ | 182 | unsigned long __flags; \ |
diff --git a/arch/mips/include/asm/compiler.h b/arch/mips/include/asm/compiler.h index 71f5c5cfc58a..c73815e0123a 100644 --- a/arch/mips/include/asm/compiler.h +++ b/arch/mips/include/asm/compiler.h | |||
| @@ -16,4 +16,12 @@ | |||
| 16 | #define GCC_REG_ACCUM "accum" | 16 | #define GCC_REG_ACCUM "accum" |
| 17 | #endif | 17 | #endif |
| 18 | 18 | ||
| 19 | #ifndef CONFIG_CPU_MICROMIPS | ||
| 20 | #define GCC_OFF12_ASM() "R" | ||
| 21 | #elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) | ||
| 22 | #define GCC_OFF12_ASM() "ZC" | ||
| 23 | #else | ||
| 24 | #error "microMIPS compilation unsupported with GCC older than 4.9" | ||
| 25 | #endif | ||
| 26 | |||
| 19 | #endif /* _ASM_COMPILER_H */ | 27 | #endif /* _ASM_COMPILER_H */ |
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index 3325f3eb248c..2897cfafcaf0 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h | |||
| @@ -344,4 +344,8 @@ | |||
| 344 | # define cpu_has_msa 0 | 344 | # define cpu_has_msa 0 |
| 345 | #endif | 345 | #endif |
| 346 | 346 | ||
| 347 | #ifndef cpu_has_fre | ||
| 348 | # define cpu_has_fre (cpu_data[0].options & MIPS_CPU_FRE) | ||
| 349 | #endif | ||
| 350 | |||
| 347 | #endif /* __ASM_CPU_FEATURES_H */ | 351 | #endif /* __ASM_CPU_FEATURES_H */ |
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index dfdc77ed1839..33866fce4d63 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h | |||
| @@ -142,6 +142,7 @@ | |||
| 142 | #define PRID_IMP_BMIPS3300_BUG 0x0000 | 142 | #define PRID_IMP_BMIPS3300_BUG 0x0000 |
| 143 | #define PRID_IMP_BMIPS43XX 0xa000 | 143 | #define PRID_IMP_BMIPS43XX 0xa000 |
| 144 | #define PRID_IMP_BMIPS5000 0x5a00 | 144 | #define PRID_IMP_BMIPS5000 0x5a00 |
| 145 | #define PRID_IMP_BMIPS5200 0x5b00 | ||
| 145 | 146 | ||
| 146 | #define PRID_REV_BMIPS4380_LO 0x0040 | 147 | #define PRID_REV_BMIPS4380_LO 0x0040 |
| 147 | #define PRID_REV_BMIPS4380_HI 0x006f | 148 | #define PRID_REV_BMIPS4380_HI 0x006f |
| @@ -368,6 +369,7 @@ enum cpu_type_enum { | |||
| 368 | #define MIPS_CPU_HTW 0x100000000ull /* CPU support Hardware Page Table Walker */ | 369 | #define MIPS_CPU_HTW 0x100000000ull /* CPU support Hardware Page Table Walker */ |
| 369 | #define MIPS_CPU_RIXIEX 0x200000000ull /* CPU has unique exception codes for {Read, Execute}-Inhibit exceptions */ | 370 | #define MIPS_CPU_RIXIEX 0x200000000ull /* CPU has unique exception codes for {Read, Execute}-Inhibit exceptions */ |
| 370 | #define MIPS_CPU_MAAR 0x400000000ull /* MAAR(I) registers are present */ | 371 | #define MIPS_CPU_MAAR 0x400000000ull /* MAAR(I) registers are present */ |
| 372 | #define MIPS_CPU_FRE 0x800000000ull /* FRE & UFE bits implemented */ | ||
| 371 | 373 | ||
| 372 | /* | 374 | /* |
| 373 | * CPU ASE encodings | 375 | * CPU ASE encodings |
diff --git a/arch/mips/include/asm/edac.h b/arch/mips/include/asm/edac.h index 4da0c1fe30d9..ae6fedcb0060 100644 --- a/arch/mips/include/asm/edac.h +++ b/arch/mips/include/asm/edac.h | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | #ifndef ASM_EDAC_H | 1 | #ifndef ASM_EDAC_H |
| 2 | #define ASM_EDAC_H | 2 | #define ASM_EDAC_H |
| 3 | 3 | ||
| 4 | #include <asm/compiler.h> | ||
| 5 | |||
| 4 | /* ECC atomic, DMA, SMP and interrupt safe scrub function */ | 6 | /* ECC atomic, DMA, SMP and interrupt safe scrub function */ |
| 5 | 7 | ||
| 6 | static inline void atomic_scrub(void *va, u32 size) | 8 | static inline void atomic_scrub(void *va, u32 size) |
| @@ -24,8 +26,8 @@ static inline void atomic_scrub(void *va, u32 size) | |||
| 24 | " sc %0, %1 \n" | 26 | " sc %0, %1 \n" |
| 25 | " beqz %0, 1b \n" | 27 | " beqz %0, 1b \n" |
| 26 | " .set mips0 \n" | 28 | " .set mips0 \n" |
| 27 | : "=&r" (temp), "=m" (*virt_addr) | 29 | : "=&r" (temp), "=" GCC_OFF12_ASM() (*virt_addr) |
| 28 | : "m" (*virt_addr)); | 30 | : GCC_OFF12_ASM() (*virt_addr)); |
| 29 | 31 | ||
| 30 | virt_addr++; | 32 | virt_addr++; |
| 31 | } | 33 | } |
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index 1d38fe0edd2d..eb4d95de619c 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h | |||
| @@ -8,6 +8,8 @@ | |||
| 8 | #ifndef _ASM_ELF_H | 8 | #ifndef _ASM_ELF_H |
| 9 | #define _ASM_ELF_H | 9 | #define _ASM_ELF_H |
| 10 | 10 | ||
| 11 | #include <linux/fs.h> | ||
| 12 | #include <uapi/linux/elf.h> | ||
| 11 | 13 | ||
| 12 | /* ELF header e_flags defines. */ | 14 | /* ELF header e_flags defines. */ |
| 13 | /* MIPS architecture level. */ | 15 | /* MIPS architecture level. */ |
| @@ -28,6 +30,7 @@ | |||
| 28 | #define PT_MIPS_REGINFO 0x70000000 | 30 | #define PT_MIPS_REGINFO 0x70000000 |
| 29 | #define PT_MIPS_RTPROC 0x70000001 | 31 | #define PT_MIPS_RTPROC 0x70000001 |
| 30 | #define PT_MIPS_OPTIONS 0x70000002 | 32 | #define PT_MIPS_OPTIONS 0x70000002 |
| 33 | #define PT_MIPS_ABIFLAGS 0x70000003 | ||
| 31 | 34 | ||
| 32 | /* Flags in the e_flags field of the header */ | 35 | /* Flags in the e_flags field of the header */ |
| 33 | #define EF_MIPS_NOREORDER 0x00000001 | 36 | #define EF_MIPS_NOREORDER 0x00000001 |
| @@ -174,6 +177,30 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | |||
| 174 | typedef double elf_fpreg_t; | 177 | typedef double elf_fpreg_t; |
| 175 | typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; | 178 | typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; |
| 176 | 179 | ||
| 180 | struct mips_elf_abiflags_v0 { | ||
| 181 | uint16_t version; /* Version of flags structure */ | ||
| 182 | uint8_t isa_level; /* The level of the ISA: 1-5, 32, 64 */ | ||
| 183 | uint8_t isa_rev; /* The revision of ISA: 0 for MIPS V and below, | ||
| 184 | 1-n otherwise */ | ||
| 185 | uint8_t gpr_size; /* The size of general purpose registers */ | ||
| 186 | uint8_t cpr1_size; /* The size of co-processor 1 registers */ | ||
| 187 | uint8_t cpr2_size; /* The size of co-processor 2 registers */ | ||
| 188 | uint8_t fp_abi; /* The floating-point ABI */ | ||
| 189 | uint32_t isa_ext; /* Mask of processor-specific extensions */ | ||
| 190 | uint32_t ases; /* Mask of ASEs used */ | ||
| 191 | uint32_t flags1; /* Mask of general flags */ | ||
| 192 | uint32_t flags2; | ||
| 193 | }; | ||
| 194 | |||
| 195 | #define MIPS_ABI_FP_ANY 0 /* FP ABI doesn't matter */ | ||
| 196 | #define MIPS_ABI_FP_DOUBLE 1 /* -mdouble-float */ | ||
| 197 | #define MIPS_ABI_FP_SINGLE 2 /* -msingle-float */ | ||
| 198 | #define MIPS_ABI_FP_SOFT 3 /* -msoft-float */ | ||
| 199 | #define MIPS_ABI_FP_OLD_64 4 /* -mips32r2 -mfp64 */ | ||
| 200 | #define MIPS_ABI_FP_XX 5 /* -mfpxx */ | ||
| 201 | #define MIPS_ABI_FP_64 6 /* -mips32r2 -mfp64 */ | ||
| 202 | #define MIPS_ABI_FP_64A 7 /* -mips32r2 -mfp64 -mno-odd-spreg */ | ||
| 203 | |||
| 177 | #ifdef CONFIG_32BIT | 204 | #ifdef CONFIG_32BIT |
| 178 | 205 | ||
| 179 | /* | 206 | /* |
| @@ -262,16 +289,13 @@ extern struct mips_abi mips_abi_n32; | |||
| 262 | 289 | ||
| 263 | #ifdef CONFIG_32BIT | 290 | #ifdef CONFIG_32BIT |
| 264 | 291 | ||
| 265 | #define SET_PERSONALITY(ex) \ | 292 | #define SET_PERSONALITY2(ex, state) \ |
| 266 | do { \ | 293 | do { \ |
| 267 | if ((ex).e_flags & EF_MIPS_FP64) \ | ||
| 268 | clear_thread_flag(TIF_32BIT_FPREGS); \ | ||
| 269 | else \ | ||
| 270 | set_thread_flag(TIF_32BIT_FPREGS); \ | ||
| 271 | \ | ||
| 272 | if (personality(current->personality) != PER_LINUX) \ | 294 | if (personality(current->personality) != PER_LINUX) \ |
| 273 | set_personality(PER_LINUX); \ | 295 | set_personality(PER_LINUX); \ |
| 274 | \ | 296 | \ |
| 297 | mips_set_personality_fp(state); \ | ||
| 298 | \ | ||
| 275 | current->thread.abi = &mips_abi; \ | 299 | current->thread.abi = &mips_abi; \ |
| 276 | } while (0) | 300 | } while (0) |
| 277 | 301 | ||
| @@ -291,44 +315,44 @@ do { \ | |||
| 291 | #endif | 315 | #endif |
| 292 | 316 | ||
| 293 | #ifdef CONFIG_MIPS32_O32 | 317 | #ifdef CONFIG_MIPS32_O32 |
| 294 | #define __SET_PERSONALITY32_O32(ex) \ | 318 | #define __SET_PERSONALITY32_O32(ex, state) \ |
| 295 | do { \ | 319 | do { \ |
| 296 | set_thread_flag(TIF_32BIT_REGS); \ | 320 | set_thread_flag(TIF_32BIT_REGS); \ |
| 297 | set_thread_flag(TIF_32BIT_ADDR); \ | 321 | set_thread_flag(TIF_32BIT_ADDR); \ |
| 298 | \ | 322 | \ |
| 299 | if (!((ex).e_flags & EF_MIPS_FP64)) \ | 323 | mips_set_personality_fp(state); \ |
| 300 | set_thread_flag(TIF_32BIT_FPREGS); \ | ||
| 301 | \ | 324 | \ |
| 302 | current->thread.abi = &mips_abi_32; \ | 325 | current->thread.abi = &mips_abi_32; \ |
| 303 | } while (0) | 326 | } while (0) |
| 304 | #else | 327 | #else |
| 305 | #define __SET_PERSONALITY32_O32(ex) \ | 328 | #define __SET_PERSONALITY32_O32(ex, state) \ |
| 306 | do { } while (0) | 329 | do { } while (0) |
| 307 | #endif | 330 | #endif |
| 308 | 331 | ||
| 309 | #ifdef CONFIG_MIPS32_COMPAT | 332 | #ifdef CONFIG_MIPS32_COMPAT |
| 310 | #define __SET_PERSONALITY32(ex) \ | 333 | #define __SET_PERSONALITY32(ex, state) \ |
| 311 | do { \ | 334 | do { \ |
| 312 | if ((((ex).e_flags & EF_MIPS_ABI2) != 0) && \ | 335 | if ((((ex).e_flags & EF_MIPS_ABI2) != 0) && \ |
| 313 | ((ex).e_flags & EF_MIPS_ABI) == 0) \ | 336 | ((ex).e_flags & EF_MIPS_ABI) == 0) \ |
| 314 | __SET_PERSONALITY32_N32(); \ | 337 | __SET_PERSONALITY32_N32(); \ |
| 315 | else \ | 338 | else \ |
| 316 | __SET_PERSONALITY32_O32(ex); \ | 339 | __SET_PERSONALITY32_O32(ex, state); \ |
| 317 | } while (0) | 340 | } while (0) |
| 318 | #else | 341 | #else |
| 319 | #define __SET_PERSONALITY32(ex) do { } while (0) | 342 | #define __SET_PERSONALITY32(ex, state) do { } while (0) |
| 320 | #endif | 343 | #endif |
| 321 | 344 | ||
| 322 | #define SET_PERSONALITY(ex) \ | 345 | #define SET_PERSONALITY2(ex, state) \ |
| 323 | do { \ | 346 | do { \ |
| 324 | unsigned int p; \ | 347 | unsigned int p; \ |
| 325 | \ | 348 | \ |
| 326 | clear_thread_flag(TIF_32BIT_REGS); \ | 349 | clear_thread_flag(TIF_32BIT_REGS); \ |
| 327 | clear_thread_flag(TIF_32BIT_FPREGS); \ | 350 | clear_thread_flag(TIF_32BIT_FPREGS); \ |
| 351 | clear_thread_flag(TIF_HYBRID_FPREGS); \ | ||
| 328 | clear_thread_flag(TIF_32BIT_ADDR); \ | 352 | clear_thread_flag(TIF_32BIT_ADDR); \ |
| 329 | \ | 353 | \ |
| 330 | if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ | 354 | if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ |
| 331 | __SET_PERSONALITY32(ex); \ | 355 | __SET_PERSONALITY32(ex, state); \ |
| 332 | else \ | 356 | else \ |
| 333 | current->thread.abi = &mips_abi; \ | 357 | current->thread.abi = &mips_abi; \ |
| 334 | \ | 358 | \ |
| @@ -390,4 +414,24 @@ struct mm_struct; | |||
| 390 | extern unsigned long arch_randomize_brk(struct mm_struct *mm); | 414 | extern unsigned long arch_randomize_brk(struct mm_struct *mm); |
| 391 | #define arch_randomize_brk arch_randomize_brk | 415 | #define arch_randomize_brk arch_randomize_brk |
| 392 | 416 | ||
| 417 | struct arch_elf_state { | ||
| 418 | int fp_abi; | ||
| 419 | int interp_fp_abi; | ||
| 420 | int overall_abi; | ||
| 421 | }; | ||
| 422 | |||
| 423 | #define INIT_ARCH_ELF_STATE { \ | ||
| 424 | .fp_abi = -1, \ | ||
| 425 | .interp_fp_abi = -1, \ | ||
| 426 | .overall_abi = -1, \ | ||
| 427 | } | ||
| 428 | |||
| 429 | extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf, | ||
| 430 | bool is_interp, struct arch_elf_state *state); | ||
| 431 | |||
| 432 | extern int arch_check_elf(void *ehdr, bool has_interpreter, | ||
| 433 | struct arch_elf_state *state); | ||
| 434 | |||
| 435 | extern void mips_set_personality_fp(struct arch_elf_state *state); | ||
| 436 | |||
| 393 | #endif /* _ASM_ELF_H */ | 437 | #endif /* _ASM_ELF_H */ |
diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h index dd562414cd5e..994d21939676 100644 --- a/arch/mips/include/asm/fpu.h +++ b/arch/mips/include/asm/fpu.h | |||
| @@ -36,14 +36,16 @@ extern void _restore_fp(struct task_struct *); | |||
| 36 | 36 | ||
| 37 | /* | 37 | /* |
| 38 | * This enum specifies a mode in which we want the FPU to operate, for cores | 38 | * This enum specifies a mode in which we want the FPU to operate, for cores |
| 39 | * which implement the Status.FR bit. Note that FPU_32BIT & FPU_64BIT | 39 | * which implement the Status.FR bit. Note that the bottom bit of the value |
| 40 | * purposefully have the values 0 & 1 respectively, so that an integer value | 40 | * purposefully matches the desired value of the Status.FR bit. |
| 41 | * of Status.FR can be trivially casted to the corresponding enum fpu_mode. | ||
| 42 | */ | 41 | */ |
| 43 | enum fpu_mode { | 42 | enum fpu_mode { |
| 44 | FPU_32BIT = 0, /* FR = 0 */ | 43 | FPU_32BIT = 0, /* FR = 0 */ |
| 45 | FPU_64BIT, /* FR = 1 */ | 44 | FPU_64BIT, /* FR = 1, FRE = 0 */ |
| 46 | FPU_AS_IS, | 45 | FPU_AS_IS, |
| 46 | FPU_HYBRID, /* FR = 1, FRE = 1 */ | ||
| 47 | |||
| 48 | #define FPU_FR_MASK 0x1 | ||
| 47 | }; | 49 | }; |
| 48 | 50 | ||
| 49 | static inline int __enable_fpu(enum fpu_mode mode) | 51 | static inline int __enable_fpu(enum fpu_mode mode) |
| @@ -57,6 +59,14 @@ static inline int __enable_fpu(enum fpu_mode mode) | |||
| 57 | enable_fpu_hazard(); | 59 | enable_fpu_hazard(); |
| 58 | return 0; | 60 | return 0; |
| 59 | 61 | ||
| 62 | case FPU_HYBRID: | ||
| 63 | if (!cpu_has_fre) | ||
| 64 | return SIGFPE; | ||
| 65 | |||
| 66 | /* set FRE */ | ||
| 67 | write_c0_config5(read_c0_config5() | MIPS_CONF5_FRE); | ||
| 68 | goto fr_common; | ||
| 69 | |||
| 60 | case FPU_64BIT: | 70 | case FPU_64BIT: |
| 61 | #if !(defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_64BIT)) | 71 | #if !(defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_64BIT)) |
| 62 | /* we only have a 32-bit FPU */ | 72 | /* we only have a 32-bit FPU */ |
| @@ -64,8 +74,11 @@ static inline int __enable_fpu(enum fpu_mode mode) | |||
| 64 | #endif | 74 | #endif |
| 65 | /* fall through */ | 75 | /* fall through */ |
| 66 | case FPU_32BIT: | 76 | case FPU_32BIT: |
| 77 | /* clear FRE */ | ||
| 78 | write_c0_config5(read_c0_config5() & ~MIPS_CONF5_FRE); | ||
| 79 | fr_common: | ||
| 67 | /* set CU1 & change FR appropriately */ | 80 | /* set CU1 & change FR appropriately */ |
| 68 | fr = (int)mode; | 81 | fr = (int)mode & FPU_FR_MASK; |
| 69 | change_c0_status(ST0_CU1 | ST0_FR, ST0_CU1 | (fr ? ST0_FR : 0)); | 82 | change_c0_status(ST0_CU1 | ST0_FR, ST0_CU1 | (fr ? ST0_FR : 0)); |
| 70 | enable_fpu_hazard(); | 83 | enable_fpu_hazard(); |
| 71 | 84 | ||
| @@ -102,13 +115,17 @@ static inline int __own_fpu(void) | |||
| 102 | enum fpu_mode mode; | 115 | enum fpu_mode mode; |
| 103 | int ret; | 116 | int ret; |
| 104 | 117 | ||
| 105 | mode = !test_thread_flag(TIF_32BIT_FPREGS); | 118 | if (test_thread_flag(TIF_HYBRID_FPREGS)) |
| 119 | mode = FPU_HYBRID; | ||
| 120 | else | ||
| 121 | mode = !test_thread_flag(TIF_32BIT_FPREGS); | ||
| 122 | |||
| 106 | ret = __enable_fpu(mode); | 123 | ret = __enable_fpu(mode); |
| 107 | if (ret) | 124 | if (ret) |
| 108 | return ret; | 125 | return ret; |
| 109 | 126 | ||
| 110 | KSTK_STATUS(current) |= ST0_CU1; | 127 | KSTK_STATUS(current) |= ST0_CU1; |
| 111 | if (mode == FPU_64BIT) | 128 | if (mode == FPU_64BIT || mode == FPU_HYBRID) |
| 112 | KSTK_STATUS(current) |= ST0_FR; | 129 | KSTK_STATUS(current) |= ST0_FR; |
| 113 | else /* mode == FPU_32BIT */ | 130 | else /* mode == FPU_32BIT */ |
| 114 | KSTK_STATUS(current) &= ~ST0_FR; | 131 | KSTK_STATUS(current) &= ~ST0_FR; |
| @@ -166,8 +183,24 @@ static inline int init_fpu(void) | |||
| 166 | 183 | ||
| 167 | if (cpu_has_fpu) { | 184 | if (cpu_has_fpu) { |
| 168 | ret = __own_fpu(); | 185 | ret = __own_fpu(); |
| 169 | if (!ret) | 186 | if (!ret) { |
| 187 | unsigned int config5 = read_c0_config5(); | ||
| 188 | |||
| 189 | /* | ||
| 190 | * Ensure FRE is clear whilst running _init_fpu, since | ||
| 191 | * single precision FP instructions are used. If FRE | ||
| 192 | * was set then we'll just end up initialising all 32 | ||
| 193 | * 64b registers. | ||
| 194 | */ | ||
| 195 | write_c0_config5(config5 & ~MIPS_CONF5_FRE); | ||
| 196 | enable_fpu_hazard(); | ||
| 197 | |||
| 170 | _init_fpu(); | 198 | _init_fpu(); |
| 199 | |||
| 200 | /* Restore FRE */ | ||
| 201 | write_c0_config5(config5); | ||
| 202 | enable_fpu_hazard(); | ||
| 203 | } | ||
| 171 | } else | 204 | } else |
| 172 | fpu_emulator_init_fpu(); | 205 | fpu_emulator_init_fpu(); |
| 173 | 206 | ||
diff --git a/arch/mips/include/asm/futex.h b/arch/mips/include/asm/futex.h index 194cda0396a3..ef9987a61d88 100644 --- a/arch/mips/include/asm/futex.h +++ b/arch/mips/include/asm/futex.h | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/uaccess.h> | 14 | #include <linux/uaccess.h> |
| 15 | #include <asm/asm-eva.h> | 15 | #include <asm/asm-eva.h> |
| 16 | #include <asm/barrier.h> | 16 | #include <asm/barrier.h> |
| 17 | #include <asm/compiler.h> | ||
| 17 | #include <asm/errno.h> | 18 | #include <asm/errno.h> |
| 18 | #include <asm/war.h> | 19 | #include <asm/war.h> |
| 19 | 20 | ||
| @@ -32,6 +33,7 @@ | |||
| 32 | " beqzl $1, 1b \n" \ | 33 | " beqzl $1, 1b \n" \ |
| 33 | __WEAK_LLSC_MB \ | 34 | __WEAK_LLSC_MB \ |
| 34 | "3: \n" \ | 35 | "3: \n" \ |
| 36 | " .insn \n" \ | ||
| 35 | " .set pop \n" \ | 37 | " .set pop \n" \ |
| 36 | " .set mips0 \n" \ | 38 | " .set mips0 \n" \ |
| 37 | " .section .fixup,\"ax\" \n" \ | 39 | " .section .fixup,\"ax\" \n" \ |
| @@ -42,8 +44,10 @@ | |||
| 42 | " "__UA_ADDR "\t1b, 4b \n" \ | 44 | " "__UA_ADDR "\t1b, 4b \n" \ |
| 43 | " "__UA_ADDR "\t2b, 4b \n" \ | 45 | " "__UA_ADDR "\t2b, 4b \n" \ |
| 44 | " .previous \n" \ | 46 | " .previous \n" \ |
| 45 | : "=r" (ret), "=&r" (oldval), "=R" (*uaddr) \ | 47 | : "=r" (ret), "=&r" (oldval), \ |
| 46 | : "0" (0), "R" (*uaddr), "Jr" (oparg), "i" (-EFAULT) \ | 48 | "=" GCC_OFF12_ASM() (*uaddr) \ |
| 49 | : "0" (0), GCC_OFF12_ASM() (*uaddr), "Jr" (oparg), \ | ||
| 50 | "i" (-EFAULT) \ | ||
| 47 | : "memory"); \ | 51 | : "memory"); \ |
| 48 | } else if (cpu_has_llsc) { \ | 52 | } else if (cpu_has_llsc) { \ |
| 49 | __asm__ __volatile__( \ | 53 | __asm__ __volatile__( \ |
| @@ -58,6 +62,7 @@ | |||
| 58 | " beqz $1, 1b \n" \ | 62 | " beqz $1, 1b \n" \ |
| 59 | __WEAK_LLSC_MB \ | 63 | __WEAK_LLSC_MB \ |
| 60 | "3: \n" \ | 64 | "3: \n" \ |
| 65 | " .insn \n" \ | ||
| 61 | " .set pop \n" \ | 66 | " .set pop \n" \ |
| 62 | " .set mips0 \n" \ | 67 | " .set mips0 \n" \ |
| 63 | " .section .fixup,\"ax\" \n" \ | 68 | " .section .fixup,\"ax\" \n" \ |
| @@ -68,8 +73,10 @@ | |||
| 68 | " "__UA_ADDR "\t1b, 4b \n" \ | 73 | " "__UA_ADDR "\t1b, 4b \n" \ |
| 69 | " "__UA_ADDR "\t2b, 4b \n" \ | 74 | " "__UA_ADDR "\t2b, 4b \n" \ |
| 70 | " .previous \n" \ | 75 | " .previous \n" \ |
| 71 | : "=r" (ret), "=&r" (oldval), "=R" (*uaddr) \ | 76 | : "=r" (ret), "=&r" (oldval), \ |
| 72 | : "0" (0), "R" (*uaddr), "Jr" (oparg), "i" (-EFAULT) \ | 77 | "=" GCC_OFF12_ASM() (*uaddr) \ |
| 78 | : "0" (0), GCC_OFF12_ASM() (*uaddr), "Jr" (oparg), \ | ||
| 79 | "i" (-EFAULT) \ | ||
| 73 | : "memory"); \ | 80 | : "memory"); \ |
| 74 | } else \ | 81 | } else \ |
| 75 | ret = -ENOSYS; \ | 82 | ret = -ENOSYS; \ |
| @@ -157,6 +164,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | |||
| 157 | " beqzl $1, 1b \n" | 164 | " beqzl $1, 1b \n" |
| 158 | __WEAK_LLSC_MB | 165 | __WEAK_LLSC_MB |
| 159 | "3: \n" | 166 | "3: \n" |
| 167 | " .insn \n" | ||
| 160 | " .set pop \n" | 168 | " .set pop \n" |
| 161 | " .section .fixup,\"ax\" \n" | 169 | " .section .fixup,\"ax\" \n" |
| 162 | "4: li %0, %6 \n" | 170 | "4: li %0, %6 \n" |
| @@ -166,8 +174,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | |||
| 166 | " "__UA_ADDR "\t1b, 4b \n" | 174 | " "__UA_ADDR "\t1b, 4b \n" |
| 167 | " "__UA_ADDR "\t2b, 4b \n" | 175 | " "__UA_ADDR "\t2b, 4b \n" |
| 168 | " .previous \n" | 176 | " .previous \n" |
| 169 | : "+r" (ret), "=&r" (val), "=R" (*uaddr) | 177 | : "+r" (ret), "=&r" (val), "=" GCC_OFF12_ASM() (*uaddr) |
| 170 | : "R" (*uaddr), "Jr" (oldval), "Jr" (newval), "i" (-EFAULT) | 178 | : GCC_OFF12_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval), |
| 179 | "i" (-EFAULT) | ||
| 171 | : "memory"); | 180 | : "memory"); |
| 172 | } else if (cpu_has_llsc) { | 181 | } else if (cpu_has_llsc) { |
| 173 | __asm__ __volatile__( | 182 | __asm__ __volatile__( |
| @@ -184,6 +193,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | |||
| 184 | " beqz $1, 1b \n" | 193 | " beqz $1, 1b \n" |
| 185 | __WEAK_LLSC_MB | 194 | __WEAK_LLSC_MB |
| 186 | "3: \n" | 195 | "3: \n" |
| 196 | " .insn \n" | ||
| 187 | " .set pop \n" | 197 | " .set pop \n" |
| 188 | " .section .fixup,\"ax\" \n" | 198 | " .section .fixup,\"ax\" \n" |
| 189 | "4: li %0, %6 \n" | 199 | "4: li %0, %6 \n" |
| @@ -193,8 +203,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | |||
| 193 | " "__UA_ADDR "\t1b, 4b \n" | 203 | " "__UA_ADDR "\t1b, 4b \n" |
| 194 | " "__UA_ADDR "\t2b, 4b \n" | 204 | " "__UA_ADDR "\t2b, 4b \n" |
| 195 | " .previous \n" | 205 | " .previous \n" |
| 196 | : "+r" (ret), "=&r" (val), "=R" (*uaddr) | 206 | : "+r" (ret), "=&r" (val), "=" GCC_OFF12_ASM() (*uaddr) |
| 197 | : "R" (*uaddr), "Jr" (oldval), "Jr" (newval), "i" (-EFAULT) | 207 | : GCC_OFF12_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval), |
| 208 | "i" (-EFAULT) | ||
| 198 | : "memory"); | 209 | : "memory"); |
| 199 | } else | 210 | } else |
| 200 | return -ENOSYS; | 211 | return -ENOSYS; |
diff --git a/arch/mips/include/asm/hpet.h b/arch/mips/include/asm/hpet.h new file mode 100644 index 000000000000..18a8f778bfaa --- /dev/null +++ b/arch/mips/include/asm/hpet.h | |||
| @@ -0,0 +1,73 @@ | |||
| 1 | #ifndef _ASM_HPET_H | ||
| 2 | #define _ASM_HPET_H | ||
| 3 | |||
| 4 | #ifdef CONFIG_RS780_HPET | ||
| 5 | |||
| 6 | #define HPET_MMAP_SIZE 1024 | ||
| 7 | |||
| 8 | #define HPET_ID 0x000 | ||
| 9 | #define HPET_PERIOD 0x004 | ||
| 10 | #define HPET_CFG 0x010 | ||
| 11 | #define HPET_STATUS 0x020 | ||
| 12 | #define HPET_COUNTER 0x0f0 | ||
| 13 | |||
| 14 | #define HPET_Tn_CFG(n) (0x100 + 0x20 * n) | ||
| 15 | #define HPET_Tn_CMP(n) (0x108 + 0x20 * n) | ||
| 16 | #define HPET_Tn_ROUTE(n) (0x110 + 0x20 * n) | ||
| 17 | |||
| 18 | #define HPET_T0_IRS 0x001 | ||
| 19 | #define HPET_T1_IRS 0x002 | ||
| 20 | #define HPET_T3_IRS 0x004 | ||
| 21 | |||
| 22 | #define HPET_T0_CFG 0x100 | ||
| 23 | #define HPET_T0_CMP 0x108 | ||
| 24 | #define HPET_T0_ROUTE 0x110 | ||
| 25 | #define HPET_T1_CFG 0x120 | ||
| 26 | #define HPET_T1_CMP 0x128 | ||
| 27 | #define HPET_T1_ROUTE 0x130 | ||
| 28 | #define HPET_T2_CFG 0x140 | ||
| 29 | #define HPET_T2_CMP 0x148 | ||
| 30 | #define HPET_T2_ROUTE 0x150 | ||
| 31 | |||
| 32 | #define HPET_ID_REV 0x000000ff | ||
| 33 | #define HPET_ID_NUMBER 0x00001f00 | ||
| 34 | #define HPET_ID_64BIT 0x00002000 | ||
| 35 | #define HPET_ID_LEGSUP 0x00008000 | ||
| 36 | #define HPET_ID_VENDOR 0xffff0000 | ||
| 37 | #define HPET_ID_NUMBER_SHIFT 8 | ||
| 38 | #define HPET_ID_VENDOR_SHIFT 16 | ||
| 39 | |||
| 40 | #define HPET_CFG_ENABLE 0x001 | ||
| 41 | #define HPET_CFG_LEGACY 0x002 | ||
| 42 | #define HPET_LEGACY_8254 2 | ||
| 43 | #define HPET_LEGACY_RTC 8 | ||
| 44 | |||
| 45 | #define HPET_TN_LEVEL 0x0002 | ||
| 46 | #define HPET_TN_ENABLE 0x0004 | ||
| 47 | #define HPET_TN_PERIODIC 0x0008 | ||
| 48 | #define HPET_TN_PERIODIC_CAP 0x0010 | ||
| 49 | #define HPET_TN_64BIT_CAP 0x0020 | ||
| 50 | #define HPET_TN_SETVAL 0x0040 | ||
| 51 | #define HPET_TN_32BIT 0x0100 | ||
| 52 | #define HPET_TN_ROUTE 0x3e00 | ||
| 53 | #define HPET_TN_FSB 0x4000 | ||
| 54 | #define HPET_TN_FSB_CAP 0x8000 | ||
| 55 | #define HPET_TN_ROUTE_SHIFT 9 | ||
| 56 | |||
| 57 | /* Max HPET Period is 10^8 femto sec as in HPET spec */ | ||
| 58 | #define HPET_MAX_PERIOD 100000000UL | ||
| 59 | /* | ||
| 60 | * Min HPET period is 10^5 femto sec just for safety. If it is less than this, | ||
| 61 | * then 32 bit HPET counter wrapsaround in less than 0.5 sec. | ||
| 62 | */ | ||
| 63 | #define HPET_MIN_PERIOD 100000UL | ||
| 64 | |||
| 65 | #define HPET_ADDR 0x20000 | ||
| 66 | #define HPET_MMIO_ADDR 0x90000e0000020000 | ||
| 67 | #define HPET_FREQ 14318780 | ||
| 68 | #define HPET_COMPARE_VAL ((HPET_FREQ + HZ / 2) / HZ) | ||
| 69 | #define HPET_T0_IRQ 0 | ||
| 70 | |||
| 71 | extern void __init setup_hpet_timer(void); | ||
| 72 | #endif /* CONFIG_RS780_HPET */ | ||
| 73 | #endif /* _ASM_HPET_H */ | ||
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index 933b50e125a0..9e777cd42b67 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h | |||
| @@ -167,7 +167,7 @@ static inline void * isa_bus_to_virt(unsigned long address) | |||
| 167 | */ | 167 | */ |
| 168 | #define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) | 168 | #define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) |
| 169 | 169 | ||
| 170 | extern void __iomem * __ioremap(phys_t offset, phys_t size, unsigned long flags); | 170 | extern void __iomem * __ioremap(phys_addr_t offset, phys_addr_t size, unsigned long flags); |
| 171 | extern void __iounmap(const volatile void __iomem *addr); | 171 | extern void __iounmap(const volatile void __iomem *addr); |
| 172 | 172 | ||
| 173 | #ifndef CONFIG_PCI | 173 | #ifndef CONFIG_PCI |
| @@ -175,7 +175,7 @@ struct pci_dev; | |||
| 175 | static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {} | 175 | static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {} |
| 176 | #endif | 176 | #endif |
| 177 | 177 | ||
| 178 | static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, | 178 | static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long size, |
| 179 | unsigned long flags) | 179 | unsigned long flags) |
| 180 | { | 180 | { |
| 181 | void __iomem *addr = plat_ioremap(offset, size, flags); | 181 | void __iomem *addr = plat_ioremap(offset, size, flags); |
| @@ -183,7 +183,7 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, | |||
| 183 | if (addr) | 183 | if (addr) |
| 184 | return addr; | 184 | return addr; |
| 185 | 185 | ||
| 186 | #define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL)) | 186 | #define __IS_LOW512(addr) (!((phys_addr_t)(addr) & (phys_addr_t) ~0x1fffffffULL)) |
| 187 | 187 | ||
| 188 | if (cpu_has_64bit_addresses) { | 188 | if (cpu_has_64bit_addresses) { |
| 189 | u64 base = UNCAC_BASE; | 189 | u64 base = UNCAC_BASE; |
| @@ -197,7 +197,7 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, | |||
| 197 | return (void __iomem *) (unsigned long) (base + offset); | 197 | return (void __iomem *) (unsigned long) (base + offset); |
| 198 | } else if (__builtin_constant_p(offset) && | 198 | } else if (__builtin_constant_p(offset) && |
| 199 | __builtin_constant_p(size) && __builtin_constant_p(flags)) { | 199 | __builtin_constant_p(size) && __builtin_constant_p(flags)) { |
| 200 | phys_t phys_addr, last_addr; | 200 | phys_addr_t phys_addr, last_addr; |
| 201 | 201 | ||
| 202 | phys_addr = fixup_bigphys_addr(offset, size); | 202 | phys_addr = fixup_bigphys_addr(offset, size); |
| 203 | 203 | ||
diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h index 39f07aec640c..5a4e1bb8fb1b 100644 --- a/arch/mips/include/asm/irq.h +++ b/arch/mips/include/asm/irq.h | |||
| @@ -48,4 +48,7 @@ extern int cp0_compare_irq; | |||
| 48 | extern int cp0_compare_irq_shift; | 48 | extern int cp0_compare_irq_shift; |
| 49 | extern int cp0_perfcount_irq; | 49 | extern int cp0_perfcount_irq; |
| 50 | 50 | ||
| 51 | void arch_trigger_all_cpu_backtrace(bool); | ||
| 52 | #define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace | ||
| 53 | |||
| 51 | #endif /* _ASM_IRQ_H */ | 54 | #endif /* _ASM_IRQ_H */ |
diff --git a/arch/mips/include/asm/irq_cpu.h b/arch/mips/include/asm/irq_cpu.h index 3f11fdb3ed8c..39a160bb41dc 100644 --- a/arch/mips/include/asm/irq_cpu.h +++ b/arch/mips/include/asm/irq_cpu.h | |||
| @@ -19,8 +19,8 @@ extern void rm9k_cpu_irq_init(void); | |||
| 19 | 19 | ||
| 20 | #ifdef CONFIG_IRQ_DOMAIN | 20 | #ifdef CONFIG_IRQ_DOMAIN |
| 21 | struct device_node; | 21 | struct device_node; |
| 22 | extern int mips_cpu_intc_init(struct device_node *of_node, | 22 | extern int mips_cpu_irq_of_init(struct device_node *of_node, |
| 23 | struct device_node *parent); | 23 | struct device_node *parent); |
| 24 | #endif | 24 | #endif |
| 25 | 25 | ||
| 26 | #endif /* _ASM_IRQ_CPU_H */ | 26 | #endif /* _ASM_IRQ_CPU_H */ |
diff --git a/arch/mips/include/asm/mach-ath25/ath25_platform.h b/arch/mips/include/asm/mach-ath25/ath25_platform.h new file mode 100644 index 000000000000..4f4ee4f9e5ec --- /dev/null +++ b/arch/mips/include/asm/mach-ath25/ath25_platform.h | |||
| @@ -0,0 +1,73 @@ | |||
| 1 | #ifndef __ASM_MACH_ATH25_PLATFORM_H | ||
| 2 | #define __ASM_MACH_ATH25_PLATFORM_H | ||
| 3 | |||
| 4 | #include <linux/etherdevice.h> | ||
| 5 | |||
| 6 | /* | ||
| 7 | * This is board-specific data that is stored in a "fixed" location in flash. | ||
| 8 | * It is shared across operating systems, so it should not be changed lightly. | ||
| 9 | * The main reason we need it is in order to extract the ethernet MAC | ||
| 10 | * address(es). | ||
| 11 | */ | ||
| 12 | struct ath25_boarddata { | ||
| 13 | u32 magic; /* board data is valid */ | ||
| 14 | #define ATH25_BD_MAGIC 0x35333131 /* "5311", for all 531x/231x platforms */ | ||
| 15 | u16 cksum; /* checksum (starting with BD_REV 2) */ | ||
| 16 | u16 rev; /* revision of this struct */ | ||
| 17 | #define BD_REV 4 | ||
| 18 | char board_name[64]; /* Name of board */ | ||
| 19 | u16 major; /* Board major number */ | ||
| 20 | u16 minor; /* Board minor number */ | ||
| 21 | u32 flags; /* Board configuration */ | ||
| 22 | #define BD_ENET0 0x00000001 /* ENET0 is stuffed */ | ||
| 23 | #define BD_ENET1 0x00000002 /* ENET1 is stuffed */ | ||
| 24 | #define BD_UART1 0x00000004 /* UART1 is stuffed */ | ||
| 25 | #define BD_UART0 0x00000008 /* UART0 is stuffed (dma) */ | ||
| 26 | #define BD_RSTFACTORY 0x00000010 /* Reset factory defaults stuffed */ | ||
| 27 | #define BD_SYSLED 0x00000020 /* System LED stuffed */ | ||
| 28 | #define BD_EXTUARTCLK 0x00000040 /* External UART clock */ | ||
| 29 | #define BD_CPUFREQ 0x00000080 /* cpu freq is valid in nvram */ | ||
| 30 | #define BD_SYSFREQ 0x00000100 /* sys freq is set in nvram */ | ||
| 31 | #define BD_WLAN0 0x00000200 /* Enable WLAN0 */ | ||
| 32 | #define BD_MEMCAP 0x00000400 /* CAP SDRAM @ mem_cap for testing */ | ||
| 33 | #define BD_DISWATCHDOG 0x00000800 /* disable system watchdog */ | ||
| 34 | #define BD_WLAN1 0x00001000 /* Enable WLAN1 (ar5212) */ | ||
| 35 | #define BD_ISCASPER 0x00002000 /* FLAG for AR2312 */ | ||
| 36 | #define BD_WLAN0_2G_EN 0x00004000 /* FLAG for radio0_2G */ | ||
| 37 | #define BD_WLAN0_5G_EN 0x00008000 /* FLAG for radio0_2G */ | ||
| 38 | #define BD_WLAN1_2G_EN 0x00020000 /* FLAG for radio0_2G */ | ||
| 39 | #define BD_WLAN1_5G_EN 0x00040000 /* FLAG for radio0_2G */ | ||
| 40 | u16 reset_config_gpio; /* Reset factory GPIO pin */ | ||
| 41 | u16 sys_led_gpio; /* System LED GPIO pin */ | ||
| 42 | |||
| 43 | u32 cpu_freq; /* CPU core frequency in Hz */ | ||
| 44 | u32 sys_freq; /* System frequency in Hz */ | ||
| 45 | u32 cnt_freq; /* Calculated C0_COUNT frequency */ | ||
| 46 | |||
| 47 | u8 wlan0_mac[ETH_ALEN]; | ||
| 48 | u8 enet0_mac[ETH_ALEN]; | ||
| 49 | u8 enet1_mac[ETH_ALEN]; | ||
| 50 | |||
| 51 | u16 pci_id; /* Pseudo PCIID for common code */ | ||
| 52 | u16 mem_cap; /* cap bank1 in MB */ | ||
| 53 | |||
| 54 | /* version 3 */ | ||
| 55 | u8 wlan1_mac[ETH_ALEN]; /* (ar5212) */ | ||
| 56 | }; | ||
| 57 | |||
| 58 | #define BOARD_CONFIG_BUFSZ 0x1000 | ||
| 59 | |||
| 60 | /* | ||
| 61 | * Platform device information for the Wireless MAC | ||
| 62 | */ | ||
| 63 | struct ar231x_board_config { | ||
| 64 | u16 devid; | ||
| 65 | |||
| 66 | /* board config data */ | ||
| 67 | struct ath25_boarddata *config; | ||
| 68 | |||
| 69 | /* radio calibration data */ | ||
| 70 | const char *radio; | ||
| 71 | }; | ||
| 72 | |||
| 73 | #endif /* __ASM_MACH_ATH25_PLATFORM_H */ | ||
diff --git a/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h new file mode 100644 index 000000000000..ade0356df257 --- /dev/null +++ b/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h | |||
| @@ -0,0 +1,64 @@ | |||
| 1 | /* | ||
| 2 | * Atheros AR231x/AR531x SoC specific CPU feature overrides | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org> | ||
| 5 | * | ||
| 6 | * This file was derived from: include/asm-mips/cpu-features.h | ||
| 7 | * Copyright (C) 2003, 2004 Ralf Baechle | ||
| 8 | * Copyright (C) 2004 Maciej W. Rozycki | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify it | ||
| 11 | * under the terms of the GNU General Public License version 2 as published | ||
| 12 | * by the Free Software Foundation. | ||
| 13 | * | ||
| 14 | */ | ||
| 15 | #ifndef __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H | ||
| 16 | #define __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H | ||
| 17 | |||
| 18 | /* | ||
| 19 | * The Atheros AR531x/AR231x SoCs have MIPS 4Kc/4KEc core. | ||
| 20 | */ | ||
| 21 | #define cpu_has_tlb 1 | ||
| 22 | #define cpu_has_4kex 1 | ||
| 23 | #define cpu_has_3k_cache 0 | ||
| 24 | #define cpu_has_4k_cache 1 | ||
| 25 | #define cpu_has_tx39_cache 0 | ||
| 26 | #define cpu_has_sb1_cache 0 | ||
| 27 | #define cpu_has_fpu 0 | ||
| 28 | #define cpu_has_32fpr 0 | ||
| 29 | #define cpu_has_counter 1 | ||
| 30 | #define cpu_has_ejtag 1 | ||
| 31 | |||
| 32 | #if !defined(CONFIG_SOC_AR5312) | ||
| 33 | # define cpu_has_llsc 1 | ||
| 34 | #else | ||
| 35 | /* | ||
| 36 | * The MIPS 4Kc V0.9 core in the AR5312/AR2312 have problems with the | ||
| 37 | * ll/sc instructions. | ||
| 38 | */ | ||
| 39 | # define cpu_has_llsc 0 | ||
| 40 | #endif | ||
| 41 | |||
| 42 | #define cpu_has_mips16 0 | ||
| 43 | #define cpu_has_mdmx 0 | ||
| 44 | #define cpu_has_mips3d 0 | ||
| 45 | #define cpu_has_smartmips 0 | ||
| 46 | |||
| 47 | #define cpu_has_mips32r1 1 | ||
| 48 | |||
| 49 | #if !defined(CONFIG_SOC_AR5312) | ||
| 50 | # define cpu_has_mips32r2 1 | ||
| 51 | #endif | ||
| 52 | |||
| 53 | #define cpu_has_mips64r1 0 | ||
| 54 | #define cpu_has_mips64r2 0 | ||
| 55 | |||
| 56 | #define cpu_has_dsp 0 | ||
| 57 | #define cpu_has_mipsmt 0 | ||
| 58 | |||
| 59 | #define cpu_has_64bits 0 | ||
| 60 | #define cpu_has_64bit_zero_reg 0 | ||
| 61 | #define cpu_has_64bit_gp_regs 0 | ||
| 62 | #define cpu_has_64bit_addresses 0 | ||
| 63 | |||
| 64 | #endif /* __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H */ | ||
diff --git a/arch/mips/include/asm/mach-ath25/dma-coherence.h b/arch/mips/include/asm/mach-ath25/dma-coherence.h new file mode 100644 index 000000000000..d8009c93a465 --- /dev/null +++ b/arch/mips/include/asm/mach-ath25/dma-coherence.h | |||
| @@ -0,0 +1,82 @@ | |||
| 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 | * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org> | ||
| 7 | * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org> | ||
| 8 | * | ||
| 9 | */ | ||
| 10 | #ifndef __ASM_MACH_ATH25_DMA_COHERENCE_H | ||
| 11 | #define __ASM_MACH_ATH25_DMA_COHERENCE_H | ||
| 12 | |||
| 13 | #include <linux/device.h> | ||
| 14 | |||
| 15 | /* | ||
| 16 | * We need some arbitrary non-zero value to be programmed to the BAR1 register | ||
| 17 | * of PCI host controller to enable DMA. The same value should be used as the | ||
| 18 | * offset to calculate the physical address of DMA buffer for PCI devices. | ||
| 19 | */ | ||
| 20 | #define AR2315_PCI_HOST_SDRAM_BASEADDR 0x20000000 | ||
| 21 | |||
| 22 | static inline dma_addr_t ath25_dev_offset(struct device *dev) | ||
| 23 | { | ||
| 24 | #ifdef CONFIG_PCI | ||
| 25 | extern struct bus_type pci_bus_type; | ||
| 26 | |||
| 27 | if (dev && dev->bus == &pci_bus_type) | ||
| 28 | return AR2315_PCI_HOST_SDRAM_BASEADDR; | ||
| 29 | #endif | ||
| 30 | return 0; | ||
| 31 | } | ||
| 32 | |||
| 33 | static inline dma_addr_t | ||
| 34 | plat_map_dma_mem(struct device *dev, void *addr, size_t size) | ||
| 35 | { | ||
| 36 | return virt_to_phys(addr) + ath25_dev_offset(dev); | ||
| 37 | } | ||
| 38 | |||
| 39 | static inline dma_addr_t | ||
| 40 | plat_map_dma_mem_page(struct device *dev, struct page *page) | ||
| 41 | { | ||
| 42 | return page_to_phys(page) + ath25_dev_offset(dev); | ||
| 43 | } | ||
| 44 | |||
| 45 | static inline unsigned long | ||
| 46 | plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) | ||
| 47 | { | ||
| 48 | return dma_addr - ath25_dev_offset(dev); | ||
| 49 | } | ||
| 50 | |||
| 51 | static inline void | ||
| 52 | plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, size_t size, | ||
| 53 | enum dma_data_direction direction) | ||
| 54 | { | ||
| 55 | } | ||
| 56 | |||
| 57 | static inline int plat_dma_supported(struct device *dev, u64 mask) | ||
| 58 | { | ||
| 59 | return 1; | ||
| 60 | } | ||
| 61 | |||
| 62 | static inline void plat_extra_sync_for_device(struct device *dev) | ||
| 63 | { | ||
| 64 | } | ||
| 65 | |||
| 66 | static inline int plat_dma_mapping_error(struct device *dev, | ||
| 67 | dma_addr_t dma_addr) | ||
| 68 | { | ||
| 69 | return 0; | ||
| 70 | } | ||
| 71 | |||
| 72 | static inline int plat_device_is_coherent(struct device *dev) | ||
| 73 | { | ||
| 74 | #ifdef CONFIG_DMA_COHERENT | ||
| 75 | return 1; | ||
| 76 | #endif | ||
| 77 | #ifdef CONFIG_DMA_NONCOHERENT | ||
| 78 | return 0; | ||
| 79 | #endif | ||
| 80 | } | ||
| 81 | |||
| 82 | #endif /* __ASM_MACH_ATH25_DMA_COHERENCE_H */ | ||
diff --git a/arch/mips/include/asm/mach-ath25/gpio.h b/arch/mips/include/asm/mach-ath25/gpio.h new file mode 100644 index 000000000000..713564b8e8ef --- /dev/null +++ b/arch/mips/include/asm/mach-ath25/gpio.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | #ifndef __ASM_MACH_ATH25_GPIO_H | ||
| 2 | #define __ASM_MACH_ATH25_GPIO_H | ||
| 3 | |||
| 4 | #include <asm-generic/gpio.h> | ||
| 5 | |||
| 6 | #define gpio_get_value __gpio_get_value | ||
| 7 | #define gpio_set_value __gpio_set_value | ||
| 8 | #define gpio_cansleep __gpio_cansleep | ||
| 9 | #define gpio_to_irq __gpio_to_irq | ||
| 10 | |||
| 11 | static inline int irq_to_gpio(unsigned irq) | ||
| 12 | { | ||
| 13 | return -EINVAL; | ||
| 14 | } | ||
| 15 | |||
| 16 | #endif /* __ASM_MACH_ATH25_GPIO_H */ | ||
diff --git a/arch/mips/include/asm/mach-ath25/war.h b/arch/mips/include/asm/mach-ath25/war.h new file mode 100644 index 000000000000..e3a5250ebd67 --- /dev/null +++ b/arch/mips/include/asm/mach-ath25/war.h | |||
| @@ -0,0 +1,25 @@ | |||
| 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 | * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org> | ||
| 7 | */ | ||
| 8 | #ifndef __ASM_MACH_ATH25_WAR_H | ||
| 9 | #define __ASM_MACH_ATH25_WAR_H | ||
| 10 | |||
| 11 | #define R4600_V1_INDEX_ICACHEOP_WAR 0 | ||
| 12 | #define R4600_V1_HIT_CACHEOP_WAR 0 | ||
| 13 | #define R4600_V2_HIT_CACHEOP_WAR 0 | ||
| 14 | #define R5432_CP0_INTERRUPT_WAR 0 | ||
| 15 | #define BCM1250_M3_WAR 0 | ||
| 16 | #define SIBYTE_1956_WAR 0 | ||
| 17 | #define MIPS4K_ICACHE_REFILL_WAR 0 | ||
| 18 | #define MIPS_CACHE_SYNC_WAR 0 | ||
| 19 | #define TX49XX_ICACHE_INDEX_INV_WAR 0 | ||
| 20 | #define RM9000_CDEX_SMP_WAR 0 | ||
| 21 | #define ICACHE_REFILLS_WORKAROUND_WAR 0 | ||
| 22 | #define R10000_LLSC_WAR 0 | ||
| 23 | #define MIPS34K_MISSED_ITLB_WAR 0 | ||
| 24 | |||
| 25 | #endif /* __ASM_MACH_ATH25_WAR_H */ | ||
diff --git a/arch/mips/include/asm/mach-au1x00/ioremap.h b/arch/mips/include/asm/mach-au1x00/ioremap.h index 75a94ad3ac91..99fea1fbb4f5 100644 --- a/arch/mips/include/asm/mach-au1x00/ioremap.h +++ b/arch/mips/include/asm/mach-au1x00/ioremap.h | |||
| @@ -11,10 +11,10 @@ | |||
| 11 | 11 | ||
| 12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
| 13 | 13 | ||
| 14 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_PCI) | 14 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_PCI) |
| 15 | extern phys_t __fixup_bigphys_addr(phys_t, phys_t); | 15 | extern phys_addr_t __fixup_bigphys_addr(phys_addr_t, phys_addr_t); |
| 16 | #else | 16 | #else |
| 17 | static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) | 17 | static inline phys_addr_t __fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) |
| 18 | { | 18 | { |
| 19 | return phys_addr; | 19 | return phys_addr; |
| 20 | } | 20 | } |
| @@ -23,12 +23,12 @@ static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) | |||
| 23 | /* | 23 | /* |
| 24 | * Allow physical addresses to be fixed up to help 36-bit peripherals. | 24 | * Allow physical addresses to be fixed up to help 36-bit peripherals. |
| 25 | */ | 25 | */ |
| 26 | static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) | 26 | static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) |
| 27 | { | 27 | { |
| 28 | return __fixup_bigphys_addr(phys_addr, size); | 28 | return __fixup_bigphys_addr(phys_addr, size); |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, | 31 | static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, |
| 32 | unsigned long flags) | 32 | unsigned long flags) |
| 33 | { | 33 | { |
| 34 | return NULL; | 34 | return NULL; |
diff --git a/arch/mips/include/asm/mach-bcm3384/dma-coherence.h b/arch/mips/include/asm/mach-bcm3384/dma-coherence.h new file mode 100644 index 000000000000..a3be8e50e1f0 --- /dev/null +++ b/arch/mips/include/asm/mach-bcm3384/dma-coherence.h | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org> | ||
| 3 | * Copyright (C) 2009 Broadcom Corporation | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | */ | ||
| 14 | |||
| 15 | #ifndef __ASM_MACH_BCM3384_DMA_COHERENCE_H | ||
| 16 | #define __ASM_MACH_BCM3384_DMA_COHERENCE_H | ||
| 17 | |||
| 18 | struct device; | ||
| 19 | |||
| 20 | extern dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size); | ||
| 21 | extern dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page); | ||
| 22 | extern unsigned long plat_dma_addr_to_phys(struct device *dev, | ||
| 23 | dma_addr_t dma_addr); | ||
| 24 | |||
| 25 | static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, | ||
| 26 | size_t size, enum dma_data_direction direction) | ||
| 27 | { | ||
| 28 | } | ||
| 29 | |||
| 30 | static inline int plat_dma_supported(struct device *dev, u64 mask) | ||
| 31 | { | ||
| 32 | /* | ||
| 33 | * we fall back to GFP_DMA when the mask isn't all 1s, | ||
| 34 | * so we can't guarantee allocations that must be | ||
| 35 | * within a tighter range than GFP_DMA.. | ||
| 36 | */ | ||
| 37 | if (mask < DMA_BIT_MASK(24)) | ||
| 38 | return 0; | ||
| 39 | |||
| 40 | return 1; | ||
| 41 | } | ||
| 42 | |||
| 43 | static inline int plat_device_is_coherent(struct device *dev) | ||
| 44 | { | ||
| 45 | return 0; | ||
| 46 | } | ||
| 47 | |||
| 48 | #endif /* __ASM_MACH_BCM3384_DMA_COHERENCE_H */ | ||
diff --git a/arch/mips/include/asm/mach-bcm3384/war.h b/arch/mips/include/asm/mach-bcm3384/war.h new file mode 100644 index 000000000000..59d7599059b0 --- /dev/null +++ b/arch/mips/include/asm/mach-bcm3384/war.h | |||
| @@ -0,0 +1,24 @@ | |||
| 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 | * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> | ||
| 7 | */ | ||
| 8 | #ifndef __ASM_MIPS_MACH_BCM3384_WAR_H | ||
| 9 | #define __ASM_MIPS_MACH_BCM3384_WAR_H | ||
| 10 | |||
| 11 | #define R4600_V1_INDEX_ICACHEOP_WAR 0 | ||
| 12 | #define R4600_V1_HIT_CACHEOP_WAR 0 | ||
| 13 | #define R4600_V2_HIT_CACHEOP_WAR 0 | ||
| 14 | #define R5432_CP0_INTERRUPT_WAR 0 | ||
| 15 | #define BCM1250_M3_WAR 0 | ||
| 16 | #define SIBYTE_1956_WAR 0 | ||
| 17 | #define MIPS4K_ICACHE_REFILL_WAR 0 | ||
| 18 | #define MIPS_CACHE_SYNC_WAR 0 | ||
| 19 | #define TX49XX_ICACHE_INDEX_INV_WAR 0 | ||
| 20 | #define ICACHE_REFILLS_WORKAROUND_WAR 0 | ||
| 21 | #define R10000_LLSC_WAR 0 | ||
| 22 | #define MIPS34K_MISSED_ITLB_WAR 0 | ||
| 23 | |||
| 24 | #endif /* __ASM_MIPS_MACH_BCM3384_WAR_H */ | ||
diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h index 36a3fc1aa3ae..ee59ffe99922 100644 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h | |||
| @@ -14,40 +14,8 @@ | |||
| 14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
| 15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
| 16 | 16 | ||
| 17 | struct nvram_header { | 17 | int bcm47xx_nvram_init_from_mem(u32 base, u32 lim); |
| 18 | u32 magic; | 18 | int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len); |
| 19 | u32 len; | ||
| 20 | u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */ | ||
| 21 | u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */ | ||
| 22 | u32 config_ncdl; /* ncdl values for memc */ | ||
| 23 | }; | ||
| 24 | |||
| 25 | #define NVRAM_HEADER 0x48534C46 /* 'FLSH' */ | ||
| 26 | #define NVRAM_VERSION 1 | ||
| 27 | #define NVRAM_HEADER_SIZE 20 | ||
| 28 | #define NVRAM_SPACE 0x8000 | ||
| 29 | |||
| 30 | #define FLASH_MIN 0x00020000 /* Minimum flash size */ | ||
| 31 | |||
| 32 | #define NVRAM_MAX_VALUE_LEN 255 | ||
| 33 | #define NVRAM_MAX_PARAM_LEN 64 | ||
| 34 | |||
| 35 | extern int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len); | ||
| 36 | |||
| 37 | static inline void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6]) | ||
| 38 | { | ||
| 39 | if (strchr(buf, ':')) | ||
| 40 | sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], | ||
| 41 | &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4], | ||
| 42 | &macaddr[5]); | ||
| 43 | else if (strchr(buf, '-')) | ||
| 44 | sscanf(buf, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &macaddr[0], | ||
| 45 | &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4], | ||
| 46 | &macaddr[5]); | ||
| 47 | else | ||
| 48 | printk(KERN_WARNING "Can not parse mac address: %s\n", buf); | ||
| 49 | } | ||
| 50 | |||
| 51 | int bcm47xx_nvram_gpio_pin(const char *name); | 19 | int bcm47xx_nvram_gpio_pin(const char *name); |
| 52 | 20 | ||
| 53 | #endif /* __BCM47XX_NVRAM_H */ | 21 | #endif /* __BCM47XX_NVRAM_H */ |
diff --git a/arch/mips/include/asm/mach-bcm63xx/ioremap.h b/arch/mips/include/asm/mach-bcm63xx/ioremap.h index ff15e3b14e7a..aea6e64b828f 100644 --- a/arch/mips/include/asm/mach-bcm63xx/ioremap.h +++ b/arch/mips/include/asm/mach-bcm63xx/ioremap.h | |||
| @@ -3,12 +3,12 @@ | |||
| 3 | 3 | ||
| 4 | #include <bcm63xx_cpu.h> | 4 | #include <bcm63xx_cpu.h> |
| 5 | 5 | ||
| 6 | static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) | 6 | static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) |
| 7 | { | 7 | { |
| 8 | return phys_addr; | 8 | return phys_addr; |
| 9 | } | 9 | } |
| 10 | 10 | ||
| 11 | static inline int is_bcm63xx_internal_registers(phys_t offset) | 11 | static inline int is_bcm63xx_internal_registers(phys_addr_t offset) |
| 12 | { | 12 | { |
| 13 | switch (bcm63xx_get_cpu_id()) { | 13 | switch (bcm63xx_get_cpu_id()) { |
| 14 | case BCM3368_CPU_ID: | 14 | case BCM3368_CPU_ID: |
| @@ -32,7 +32,7 @@ static inline int is_bcm63xx_internal_registers(phys_t offset) | |||
| 32 | return 0; | 32 | return 0; |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, | 35 | static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, |
| 36 | unsigned long flags) | 36 | unsigned long flags) |
| 37 | { | 37 | { |
| 38 | if (is_bcm63xx_internal_registers(offset)) | 38 | if (is_bcm63xx_internal_registers(offset)) |
diff --git a/arch/mips/include/asm/mach-generic/ioremap.h b/arch/mips/include/asm/mach-generic/ioremap.h index b379938d47f0..513371f7c39c 100644 --- a/arch/mips/include/asm/mach-generic/ioremap.h +++ b/arch/mips/include/asm/mach-generic/ioremap.h | |||
| @@ -15,12 +15,12 @@ | |||
| 15 | * Allow physical addresses to be fixed up to help peripherals located | 15 | * Allow physical addresses to be fixed up to help peripherals located |
| 16 | * outside the low 32-bit range -- generic pass-through version. | 16 | * outside the low 32-bit range -- generic pass-through version. |
| 17 | */ | 17 | */ |
| 18 | static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) | 18 | static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) |
| 19 | { | 19 | { |
| 20 | return phys_addr; | 20 | return phys_addr; |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, | 23 | static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, |
| 24 | unsigned long flags) | 24 | unsigned long flags) |
| 25 | { | 25 | { |
| 26 | return NULL; | 26 | return NULL; |
diff --git a/arch/mips/include/asm/mach-generic/irq.h b/arch/mips/include/asm/mach-generic/irq.h index 139cd200e79d..050e18bb1a04 100644 --- a/arch/mips/include/asm/mach-generic/irq.h +++ b/arch/mips/include/asm/mach-generic/irq.h | |||
| @@ -36,4 +36,10 @@ | |||
| 36 | 36 | ||
| 37 | #endif /* CONFIG_IRQ_CPU */ | 37 | #endif /* CONFIG_IRQ_CPU */ |
| 38 | 38 | ||
| 39 | #ifdef CONFIG_MIPS_GIC | ||
| 40 | #ifndef MIPS_GIC_IRQ_BASE | ||
| 41 | #define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8) | ||
| 42 | #endif | ||
| 43 | #endif /* CONFIG_MIPS_GIC */ | ||
| 44 | |||
| 39 | #endif /* __ASM_MACH_GENERIC_IRQ_H */ | 45 | #endif /* __ASM_MACH_GENERIC_IRQ_H */ |
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq.h b/arch/mips/include/asm/mach-lantiq/lantiq.h index f196cceb7322..4e5ae6523cb4 100644 --- a/arch/mips/include/asm/mach-lantiq/lantiq.h +++ b/arch/mips/include/asm/mach-lantiq/lantiq.h | |||
| @@ -48,6 +48,8 @@ extern struct clk *clk_get_ppe(void); | |||
| 48 | extern unsigned char ltq_boot_select(void); | 48 | extern unsigned char ltq_boot_select(void); |
| 49 | /* find out what caused the last cpu reset */ | 49 | /* find out what caused the last cpu reset */ |
| 50 | extern int ltq_reset_cause(void); | 50 | extern int ltq_reset_cause(void); |
| 51 | /* find out the soc type */ | ||
| 52 | extern int ltq_soc_type(void); | ||
| 51 | 53 | ||
| 52 | #define IOPORT_RESOURCE_START 0x10000000 | 54 | #define IOPORT_RESOURCE_START 0x10000000 |
| 53 | #define IOPORT_RESOURCE_END 0xffffffff | 55 | #define IOPORT_RESOURCE_END 0xffffffff |
diff --git a/arch/mips/include/asm/mach-loongson/boot_param.h b/arch/mips/include/asm/mach-loongson/boot_param.h index 3388fc53599e..fa802926523f 100644 --- a/arch/mips/include/asm/mach-loongson/boot_param.h +++ b/arch/mips/include/asm/mach-loongson/boot_param.h | |||
| @@ -10,7 +10,8 @@ | |||
| 10 | #define VIDEO_ROM 7 | 10 | #define VIDEO_ROM 7 |
| 11 | #define ADAPTER_ROM 8 | 11 | #define ADAPTER_ROM 8 |
| 12 | #define ACPI_TABLE 9 | 12 | #define ACPI_TABLE 9 |
| 13 | #define MAX_MEMORY_TYPE 10 | 13 | #define SMBIOS_TABLE 10 |
| 14 | #define MAX_MEMORY_TYPE 11 | ||
| 14 | 15 | ||
| 15 | #define LOONGSON3_BOOT_MEM_MAP_MAX 128 | 16 | #define LOONGSON3_BOOT_MEM_MAP_MAX 128 |
| 16 | struct efi_memory_map_loongson { | 17 | struct efi_memory_map_loongson { |
| @@ -42,15 +43,49 @@ struct efi_cpuinfo_loongson { | |||
| 42 | u32 processor_id; /* PRID, e.g. 6305, 6306 */ | 43 | u32 processor_id; /* PRID, e.g. 6305, 6306 */ |
| 43 | u32 cputype; /* Loongson_3A/3B, etc. */ | 44 | u32 cputype; /* Loongson_3A/3B, etc. */ |
| 44 | u32 total_node; /* num of total numa nodes */ | 45 | u32 total_node; /* num of total numa nodes */ |
| 45 | u32 cpu_startup_core_id; /* Core id */ | 46 | u16 cpu_startup_core_id; /* Boot core id */ |
| 47 | u16 reserved_cores_mask; | ||
| 46 | u32 cpu_clock_freq; /* cpu_clock */ | 48 | u32 cpu_clock_freq; /* cpu_clock */ |
| 47 | u32 nr_cpus; | 49 | u32 nr_cpus; |
| 48 | } __packed; | 50 | } __packed; |
| 49 | 51 | ||
| 52 | #define MAX_UARTS 64 | ||
| 53 | struct uart_device { | ||
| 54 | u32 iotype; /* see include/linux/serial_core.h */ | ||
| 55 | u32 uartclk; | ||
| 56 | u32 int_offset; | ||
| 57 | u64 uart_base; | ||
| 58 | } __packed; | ||
| 59 | |||
| 60 | #define MAX_SENSORS 64 | ||
| 61 | #define SENSOR_TEMPER 0x00000001 | ||
| 62 | #define SENSOR_VOLTAGE 0x00000002 | ||
| 63 | #define SENSOR_FAN 0x00000004 | ||
| 64 | struct sensor_device { | ||
| 65 | char name[32]; /* a formal name */ | ||
| 66 | char label[64]; /* a flexible description */ | ||
| 67 | u32 type; /* SENSOR_* */ | ||
| 68 | u32 id; /* instance id of a sensor-class */ | ||
| 69 | u32 fan_policy; /* see loongson_hwmon.h */ | ||
| 70 | u32 fan_percent;/* only for constant speed policy */ | ||
| 71 | u64 base_addr; /* base address of device registers */ | ||
| 72 | } __packed; | ||
| 73 | |||
| 50 | struct system_loongson { | 74 | struct system_loongson { |
| 51 | u16 vers; /* version of system_loongson */ | 75 | u16 vers; /* version of system_loongson */ |
| 52 | u32 ccnuma_smp; /* 0: no numa; 1: has numa */ | 76 | u32 ccnuma_smp; /* 0: no numa; 1: has numa */ |
| 53 | u32 sing_double_channel; /* 1:single; 2:double */ | 77 | u32 sing_double_channel; /* 1:single; 2:double */ |
| 78 | u32 nr_uarts; | ||
| 79 | struct uart_device uarts[MAX_UARTS]; | ||
| 80 | u32 nr_sensors; | ||
| 81 | struct sensor_device sensors[MAX_SENSORS]; | ||
| 82 | char has_ec; | ||
| 83 | char ec_name[32]; | ||
| 84 | u64 ec_base_addr; | ||
| 85 | char has_tcm; | ||
| 86 | char tcm_name[32]; | ||
| 87 | u64 tcm_base_addr; | ||
| 88 | u64 workarounds; /* see workarounds.h */ | ||
| 54 | } __packed; | 89 | } __packed; |
| 55 | 90 | ||
| 56 | struct irq_source_routing_table { | 91 | struct irq_source_routing_table { |
| @@ -149,6 +184,8 @@ struct loongson_system_configuration { | |||
| 149 | u32 nr_nodes; | 184 | u32 nr_nodes; |
| 150 | int cores_per_node; | 185 | int cores_per_node; |
| 151 | int cores_per_package; | 186 | int cores_per_package; |
| 187 | u16 boot_cpu_id; | ||
| 188 | u16 reserved_cpus_mask; | ||
| 152 | enum loongson_cpu_type cputype; | 189 | enum loongson_cpu_type cputype; |
| 153 | u64 ht_control_base; | 190 | u64 ht_control_base; |
| 154 | u64 pci_mem_start_addr; | 191 | u64 pci_mem_start_addr; |
| @@ -159,9 +196,15 @@ struct loongson_system_configuration { | |||
| 159 | u64 suspend_addr; | 196 | u64 suspend_addr; |
| 160 | u64 vgabios_addr; | 197 | u64 vgabios_addr; |
| 161 | u32 dma_mask_bits; | 198 | u32 dma_mask_bits; |
| 199 | char ecname[32]; | ||
| 200 | u32 nr_uarts; | ||
| 201 | struct uart_device uarts[MAX_UARTS]; | ||
| 202 | u32 nr_sensors; | ||
| 203 | struct sensor_device sensors[MAX_SENSORS]; | ||
| 204 | u64 workarounds; | ||
| 162 | }; | 205 | }; |
| 163 | 206 | ||
| 164 | extern struct efi_memory_map_loongson *loongson_memmap; | 207 | extern struct efi_memory_map_loongson *loongson_memmap; |
| 165 | extern struct loongson_system_configuration loongson_sysconf; | 208 | extern struct loongson_system_configuration loongson_sysconf; |
| 166 | extern int cpuhotplug_workaround; | 209 | |
| 167 | #endif | 210 | #endif |
diff --git a/arch/mips/include/asm/mach-loongson/dma-coherence.h b/arch/mips/include/asm/mach-loongson/dma-coherence.h index 6a902751cc7f..a90534161bd2 100644 --- a/arch/mips/include/asm/mach-loongson/dma-coherence.h +++ b/arch/mips/include/asm/mach-loongson/dma-coherence.h | |||
| @@ -23,7 +23,7 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, | |||
| 23 | size_t size) | 23 | size_t size) |
| 24 | { | 24 | { |
| 25 | #ifdef CONFIG_CPU_LOONGSON3 | 25 | #ifdef CONFIG_CPU_LOONGSON3 |
| 26 | return virt_to_phys(addr); | 26 | return phys_to_dma(dev, virt_to_phys(addr)); |
| 27 | #else | 27 | #else |
| 28 | return virt_to_phys(addr) | 0x80000000; | 28 | return virt_to_phys(addr) | 0x80000000; |
| 29 | #endif | 29 | #endif |
| @@ -33,7 +33,7 @@ static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, | |||
| 33 | struct page *page) | 33 | struct page *page) |
| 34 | { | 34 | { |
| 35 | #ifdef CONFIG_CPU_LOONGSON3 | 35 | #ifdef CONFIG_CPU_LOONGSON3 |
| 36 | return page_to_phys(page); | 36 | return phys_to_dma(dev, page_to_phys(page)); |
| 37 | #else | 37 | #else |
| 38 | return page_to_phys(page) | 0x80000000; | 38 | return page_to_phys(page) | 0x80000000; |
| 39 | #endif | 39 | #endif |
| @@ -43,7 +43,7 @@ static inline unsigned long plat_dma_addr_to_phys(struct device *dev, | |||
| 43 | dma_addr_t dma_addr) | 43 | dma_addr_t dma_addr) |
| 44 | { | 44 | { |
| 45 | #if defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_64BIT) | 45 | #if defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_64BIT) |
| 46 | return dma_addr; | 46 | return dma_to_phys(dev, dma_addr); |
| 47 | #elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) | 47 | #elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) |
| 48 | return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff); | 48 | return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff); |
| 49 | #else | 49 | #else |
diff --git a/arch/mips/include/asm/mach-loongson/irq.h b/arch/mips/include/asm/mach-loongson/irq.h index 34560bda6626..a281cca5f2fb 100644 --- a/arch/mips/include/asm/mach-loongson/irq.h +++ b/arch/mips/include/asm/mach-loongson/irq.h | |||
| @@ -32,8 +32,7 @@ | |||
| 32 | #define LOONGSON_INT_ROUTER_LPC LOONGSON_INT_ROUTER_ENTRY(0x0a) | 32 | #define LOONGSON_INT_ROUTER_LPC LOONGSON_INT_ROUTER_ENTRY(0x0a) |
| 33 | #define LOONGSON_INT_ROUTER_HT1(n) LOONGSON_INT_ROUTER_ENTRY(n + 0x18) | 33 | #define LOONGSON_INT_ROUTER_HT1(n) LOONGSON_INT_ROUTER_ENTRY(n + 0x18) |
| 34 | 34 | ||
| 35 | #define LOONGSON_INT_CORE0_INT0 0x11 /* route to int 0 of core 0 */ | 35 | #define LOONGSON_INT_COREx_INTy(x, y) (1<<(x) | 1<<(y+4)) /* route to int y of core x */ |
| 36 | #define LOONGSON_INT_CORE0_INT1 0x21 /* route to int 1 of core 0 */ | ||
| 37 | 36 | ||
| 38 | #endif | 37 | #endif |
| 39 | 38 | ||
diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h index 92bf76c21441..5459ac09679f 100644 --- a/arch/mips/include/asm/mach-loongson/loongson.h +++ b/arch/mips/include/asm/mach-loongson/loongson.h | |||
| @@ -35,7 +35,7 @@ extern void __init prom_init_cmdline(void); | |||
| 35 | extern void __init prom_init_machtype(void); | 35 | extern void __init prom_init_machtype(void); |
| 36 | extern void __init prom_init_env(void); | 36 | extern void __init prom_init_env(void); |
| 37 | #ifdef CONFIG_LOONGSON_UART_BASE | 37 | #ifdef CONFIG_LOONGSON_UART_BASE |
| 38 | extern unsigned long _loongson_uart_base, loongson_uart_base; | 38 | extern unsigned long _loongson_uart_base[], loongson_uart_base[]; |
| 39 | extern void prom_init_loongson_uart_base(void); | 39 | extern void prom_init_loongson_uart_base(void); |
| 40 | #endif | 40 | #endif |
| 41 | 41 | ||
diff --git a/arch/mips/include/asm/mach-loongson/loongson_hwmon.h b/arch/mips/include/asm/mach-loongson/loongson_hwmon.h new file mode 100644 index 000000000000..4431fc54a36c --- /dev/null +++ b/arch/mips/include/asm/mach-loongson/loongson_hwmon.h | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | #ifndef __LOONGSON_HWMON_H_ | ||
| 2 | #define __LOONGSON_HWMON_H_ | ||
| 3 | |||
| 4 | #include <linux/types.h> | ||
| 5 | |||
| 6 | #define MIN_TEMP 0 | ||
| 7 | #define MAX_TEMP 255 | ||
| 8 | #define NOT_VALID_TEMP 999 | ||
| 9 | |||
| 10 | typedef int (*get_temp_fun)(int); | ||
| 11 | extern int loongson3_cpu_temp(int); | ||
| 12 | |||
| 13 | /* 0:Max speed, 1:Manual, 2:Auto */ | ||
| 14 | enum fan_control_mode { | ||
| 15 | FAN_FULL_MODE = 0, | ||
| 16 | FAN_MANUAL_MODE = 1, | ||
| 17 | FAN_AUTO_MODE = 2, | ||
| 18 | FAN_MODE_END | ||
| 19 | }; | ||
| 20 | |||
| 21 | struct temp_range { | ||
| 22 | u8 low; | ||
| 23 | u8 high; | ||
| 24 | u8 level; | ||
| 25 | }; | ||
| 26 | |||
| 27 | #define CONSTANT_SPEED_POLICY 0 /* at constent speed */ | ||
| 28 | #define STEP_SPEED_POLICY 1 /* use up/down arrays to describe policy */ | ||
| 29 | #define KERNEL_HELPER_POLICY 2 /* kernel as a helper to fan control */ | ||
| 30 | |||
| 31 | #define MAX_STEP_NUM 16 | ||
| 32 | #define MAX_FAN_LEVEL 255 | ||
| 33 | |||
| 34 | /* loongson_fan_policy works when fan work at FAN_AUTO_MODE */ | ||
| 35 | struct loongson_fan_policy { | ||
| 36 | u8 type; | ||
| 37 | |||
| 38 | /* percent only used when type is CONSTANT_SPEED_POLICY */ | ||
| 39 | u8 percent; | ||
| 40 | |||
| 41 | /* period between two check. (Unit: S) */ | ||
| 42 | u8 adjust_period; | ||
| 43 | |||
| 44 | /* fan adjust usually depend on a temprature input */ | ||
| 45 | get_temp_fun depend_temp; | ||
| 46 | |||
| 47 | /* up_step/down_step used when type is STEP_SPEED_POLICY */ | ||
| 48 | u8 up_step_num; | ||
| 49 | u8 down_step_num; | ||
| 50 | struct temp_range up_step[MAX_STEP_NUM]; | ||
| 51 | struct temp_range down_step[MAX_STEP_NUM]; | ||
| 52 | struct delayed_work work; | ||
| 53 | }; | ||
| 54 | |||
| 55 | #endif /* __LOONGSON_HWMON_H_*/ | ||
diff --git a/arch/mips/include/asm/mach-loongson/machine.h b/arch/mips/include/asm/mach-loongson/machine.h index 228e37847a36..cb2b60249cd2 100644 --- a/arch/mips/include/asm/mach-loongson/machine.h +++ b/arch/mips/include/asm/mach-loongson/machine.h | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | 26 | ||
| 27 | #ifdef CONFIG_LOONGSON_MACH3X | 27 | #ifdef CONFIG_LOONGSON_MACH3X |
| 28 | 28 | ||
| 29 | #define LOONGSON_MACHTYPE MACH_LEMOTE_A1101 | 29 | #define LOONGSON_MACHTYPE MACH_LOONGSON_GENERIC |
| 30 | 30 | ||
| 31 | #endif /* CONFIG_LOONGSON_MACH3X */ | 31 | #endif /* CONFIG_LOONGSON_MACH3X */ |
| 32 | 32 | ||
diff --git a/arch/mips/include/asm/mach-loongson/topology.h b/arch/mips/include/asm/mach-loongson/topology.h index 5598ba77d2ef..0d8f3b55bdbc 100644 --- a/arch/mips/include/asm/mach-loongson/topology.h +++ b/arch/mips/include/asm/mach-loongson/topology.h | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | #ifdef CONFIG_NUMA | 4 | #ifdef CONFIG_NUMA |
| 5 | 5 | ||
| 6 | #define cpu_to_node(cpu) ((cpu) >> 2) | 6 | #define cpu_to_node(cpu) (cpu_logical_map(cpu) >> 2) |
| 7 | #define parent_node(node) (node) | 7 | #define parent_node(node) (node) |
| 8 | #define cpumask_of_node(node) (&__node_data[(node)]->cpumask) | 8 | #define cpumask_of_node(node) (&__node_data[(node)]->cpumask) |
| 9 | 9 | ||
diff --git a/arch/mips/include/asm/mach-loongson/workarounds.h b/arch/mips/include/asm/mach-loongson/workarounds.h new file mode 100644 index 000000000000..e180c1422eae --- /dev/null +++ b/arch/mips/include/asm/mach-loongson/workarounds.h | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | #ifndef __ASM_MACH_LOONGSON_WORKAROUNDS_H_ | ||
| 2 | #define __ASM_MACH_LOONGSON_WORKAROUNDS_H_ | ||
| 3 | |||
| 4 | #define WORKAROUND_CPUFREQ 0x00000001 | ||
| 5 | #define WORKAROUND_CPUHOTPLUG 0x00000002 | ||
| 6 | |||
| 7 | #endif | ||
diff --git a/arch/mips/include/asm/mach-loongson1/cpufreq.h b/arch/mips/include/asm/mach-loongson1/cpufreq.h new file mode 100644 index 000000000000..e7765ce30bcf --- /dev/null +++ b/arch/mips/include/asm/mach-loongson1/cpufreq.h | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com> | ||
| 3 | * | ||
| 4 | * Loongson 1 CPUFreq platform support. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License as published by the | ||
| 8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 9 | * option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | |||
| 13 | #ifndef __ASM_MACH_LOONGSON1_CPUFREQ_H | ||
| 14 | #define __ASM_MACH_LOONGSON1_CPUFREQ_H | ||
| 15 | |||
| 16 | struct plat_ls1x_cpufreq { | ||
| 17 | const char *clk_name; /* CPU clk */ | ||
| 18 | const char *osc_clk_name; /* OSC clk */ | ||
| 19 | unsigned int max_freq; /* in kHz */ | ||
| 20 | unsigned int min_freq; /* in kHz */ | ||
| 21 | }; | ||
| 22 | |||
| 23 | #endif /* __ASM_MACH_LOONGSON1_CPUFREQ_H */ | ||
diff --git a/arch/mips/include/asm/mach-loongson1/loongson1.h b/arch/mips/include/asm/mach-loongson1/loongson1.h index 5c437c2ba6b3..20e0c2b155dd 100644 --- a/arch/mips/include/asm/mach-loongson1/loongson1.h +++ b/arch/mips/include/asm/mach-loongson1/loongson1.h | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #define DEFAULT_MEMSIZE 256 /* If no memsize provided */ | 16 | #define DEFAULT_MEMSIZE 256 /* If no memsize provided */ |
| 17 | 17 | ||
| 18 | /* Loongson 1 Register Bases */ | 18 | /* Loongson 1 Register Bases */ |
| 19 | #define LS1X_MUX_BASE 0x1fd00420 | ||
| 19 | #define LS1X_INTC_BASE 0x1fd01040 | 20 | #define LS1X_INTC_BASE 0x1fd01040 |
| 20 | #define LS1X_EHCI_BASE 0x1fe00000 | 21 | #define LS1X_EHCI_BASE 0x1fe00000 |
| 21 | #define LS1X_OHCI_BASE 0x1fe08000 | 22 | #define LS1X_OHCI_BASE 0x1fe08000 |
| @@ -31,7 +32,10 @@ | |||
| 31 | #define LS1X_I2C0_BASE 0x1fe58000 | 32 | #define LS1X_I2C0_BASE 0x1fe58000 |
| 32 | #define LS1X_I2C1_BASE 0x1fe68000 | 33 | #define LS1X_I2C1_BASE 0x1fe68000 |
| 33 | #define LS1X_I2C2_BASE 0x1fe70000 | 34 | #define LS1X_I2C2_BASE 0x1fe70000 |
| 34 | #define LS1X_PWM_BASE 0x1fe5c000 | 35 | #define LS1X_PWM0_BASE 0x1fe5c000 |
| 36 | #define LS1X_PWM1_BASE 0x1fe5c010 | ||
| 37 | #define LS1X_PWM2_BASE 0x1fe5c020 | ||
| 38 | #define LS1X_PWM3_BASE 0x1fe5c030 | ||
| 35 | #define LS1X_WDT_BASE 0x1fe5c060 | 39 | #define LS1X_WDT_BASE 0x1fe5c060 |
| 36 | #define LS1X_RTC_BASE 0x1fe64000 | 40 | #define LS1X_RTC_BASE 0x1fe64000 |
| 37 | #define LS1X_AC97_BASE 0x1fe74000 | 41 | #define LS1X_AC97_BASE 0x1fe74000 |
| @@ -39,6 +43,8 @@ | |||
| 39 | #define LS1X_CLK_BASE 0x1fe78030 | 43 | #define LS1X_CLK_BASE 0x1fe78030 |
| 40 | 44 | ||
| 41 | #include <regs-clk.h> | 45 | #include <regs-clk.h> |
| 46 | #include <regs-mux.h> | ||
| 47 | #include <regs-pwm.h> | ||
| 42 | #include <regs-wdt.h> | 48 | #include <regs-wdt.h> |
| 43 | 49 | ||
| 44 | #endif /* __ASM_MACH_LOONGSON1_LOONGSON1_H */ | 50 | #endif /* __ASM_MACH_LOONGSON1_LOONGSON1_H */ |
diff --git a/arch/mips/include/asm/mach-loongson1/platform.h b/arch/mips/include/asm/mach-loongson1/platform.h index 30c13e508fff..47de55e0c835 100644 --- a/arch/mips/include/asm/mach-loongson1/platform.h +++ b/arch/mips/include/asm/mach-loongson1/platform.h | |||
| @@ -13,10 +13,12 @@ | |||
| 13 | 13 | ||
| 14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
| 15 | 15 | ||
| 16 | extern struct platform_device ls1x_uart_device; | 16 | extern struct platform_device ls1x_uart_pdev; |
| 17 | extern struct platform_device ls1x_eth0_device; | 17 | extern struct platform_device ls1x_cpufreq_pdev; |
| 18 | extern struct platform_device ls1x_ehci_device; | 18 | extern struct platform_device ls1x_eth0_pdev; |
| 19 | extern struct platform_device ls1x_rtc_device; | 19 | extern struct platform_device ls1x_eth1_pdev; |
| 20 | extern struct platform_device ls1x_ehci_pdev; | ||
| 21 | extern struct platform_device ls1x_rtc_pdev; | ||
| 20 | 22 | ||
| 21 | extern void __init ls1x_clk_init(void); | 23 | extern void __init ls1x_clk_init(void); |
| 22 | extern void __init ls1x_serial_setup(struct platform_device *pdev); | 24 | extern void __init ls1x_serial_setup(struct platform_device *pdev); |
diff --git a/arch/mips/include/asm/mach-loongson1/regs-clk.h b/arch/mips/include/asm/mach-loongson1/regs-clk.h index fb6a3ff9318f..ee2445b10fc3 100644 --- a/arch/mips/include/asm/mach-loongson1/regs-clk.h +++ b/arch/mips/include/asm/mach-loongson1/regs-clk.h | |||
| @@ -20,15 +20,32 @@ | |||
| 20 | 20 | ||
| 21 | /* Clock PLL Divisor Register Bits */ | 21 | /* Clock PLL Divisor Register Bits */ |
| 22 | #define DIV_DC_EN (0x1 << 31) | 22 | #define DIV_DC_EN (0x1 << 31) |
| 23 | #define DIV_DC_RST (0x1 << 30) | ||
| 23 | #define DIV_CPU_EN (0x1 << 25) | 24 | #define DIV_CPU_EN (0x1 << 25) |
| 25 | #define DIV_CPU_RST (0x1 << 24) | ||
| 24 | #define DIV_DDR_EN (0x1 << 19) | 26 | #define DIV_DDR_EN (0x1 << 19) |
| 27 | #define DIV_DDR_RST (0x1 << 18) | ||
| 28 | #define RST_DC_EN (0x1 << 5) | ||
| 29 | #define RST_DC (0x1 << 4) | ||
| 30 | #define RST_DDR_EN (0x1 << 3) | ||
| 31 | #define RST_DDR (0x1 << 2) | ||
| 32 | #define RST_CPU_EN (0x1 << 1) | ||
| 33 | #define RST_CPU 0x1 | ||
| 25 | 34 | ||
| 26 | #define DIV_DC_SHIFT 26 | 35 | #define DIV_DC_SHIFT 26 |
| 27 | #define DIV_CPU_SHIFT 20 | 36 | #define DIV_CPU_SHIFT 20 |
| 28 | #define DIV_DDR_SHIFT 14 | 37 | #define DIV_DDR_SHIFT 14 |
| 29 | 38 | ||
| 30 | #define DIV_DC_WIDTH 5 | 39 | #define DIV_DC_WIDTH 4 |
| 31 | #define DIV_CPU_WIDTH 5 | 40 | #define DIV_CPU_WIDTH 4 |
| 32 | #define DIV_DDR_WIDTH 5 | 41 | #define DIV_DDR_WIDTH 4 |
| 42 | |||
| 43 | #define BYPASS_DC_SHIFT 12 | ||
| 44 | #define BYPASS_DDR_SHIFT 10 | ||
| 45 | #define BYPASS_CPU_SHIFT 8 | ||
| 46 | |||
| 47 | #define BYPASS_DC_WIDTH 1 | ||
| 48 | #define BYPASS_DDR_WIDTH 1 | ||
| 49 | #define BYPASS_CPU_WIDTH 1 | ||
| 33 | 50 | ||
| 34 | #endif /* __ASM_MACH_LOONGSON1_REGS_CLK_H */ | 51 | #endif /* __ASM_MACH_LOONGSON1_REGS_CLK_H */ |
diff --git a/arch/mips/include/asm/mach-loongson1/regs-mux.h b/arch/mips/include/asm/mach-loongson1/regs-mux.h new file mode 100644 index 000000000000..fb1e36efaa19 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson1/regs-mux.h | |||
| @@ -0,0 +1,67 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com> | ||
| 3 | * | ||
| 4 | * Loongson 1 MUX Register Definitions. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License as published by the | ||
| 8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 9 | * option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef __ASM_MACH_LOONGSON1_REGS_MUX_H | ||
| 13 | #define __ASM_MACH_LOONGSON1_REGS_MUX_H | ||
| 14 | |||
| 15 | #define LS1X_MUX_REG(x) \ | ||
| 16 | ((void __iomem *)KSEG1ADDR(LS1X_MUX_BASE + (x))) | ||
| 17 | |||
| 18 | #define LS1X_MUX_CTRL0 LS1X_MUX_REG(0x0) | ||
| 19 | #define LS1X_MUX_CTRL1 LS1X_MUX_REG(0x4) | ||
| 20 | |||
| 21 | /* MUX CTRL0 Register Bits */ | ||
| 22 | #define UART0_USE_PWM23 (0x1 << 28) | ||
| 23 | #define UART0_USE_PWM01 (0x1 << 27) | ||
| 24 | #define UART1_USE_LCD0_5_6_11 (0x1 << 26) | ||
| 25 | #define I2C2_USE_CAN1 (0x1 << 25) | ||
| 26 | #define I2C1_USE_CAN0 (0x1 << 24) | ||
| 27 | #define NAND3_USE_UART5 (0x1 << 23) | ||
| 28 | #define NAND3_USE_UART4 (0x1 << 22) | ||
| 29 | #define NAND3_USE_UART1_DAT (0x1 << 21) | ||
| 30 | #define NAND3_USE_UART1_CTS (0x1 << 20) | ||
| 31 | #define NAND3_USE_PWM23 (0x1 << 19) | ||
| 32 | #define NAND3_USE_PWM01 (0x1 << 18) | ||
| 33 | #define NAND2_USE_UART5 (0x1 << 17) | ||
| 34 | #define NAND2_USE_UART4 (0x1 << 16) | ||
| 35 | #define NAND2_USE_UART1_DAT (0x1 << 15) | ||
| 36 | #define NAND2_USE_UART1_CTS (0x1 << 14) | ||
| 37 | #define NAND2_USE_PWM23 (0x1 << 13) | ||
| 38 | #define NAND2_USE_PWM01 (0x1 << 12) | ||
| 39 | #define NAND1_USE_UART5 (0x1 << 11) | ||
| 40 | #define NAND1_USE_UART4 (0x1 << 10) | ||
| 41 | #define NAND1_USE_UART1_DAT (0x1 << 9) | ||
| 42 | #define NAND1_USE_UART1_CTS (0x1 << 8) | ||
| 43 | #define NAND1_USE_PWM23 (0x1 << 7) | ||
| 44 | #define NAND1_USE_PWM01 (0x1 << 6) | ||
| 45 | #define GMAC1_USE_UART1 (0x1 << 4) | ||
| 46 | #define GMAC1_USE_UART0 (0x1 << 3) | ||
| 47 | #define LCD_USE_UART0_DAT (0x1 << 2) | ||
| 48 | #define LCD_USE_UART15 (0x1 << 1) | ||
| 49 | #define LCD_USE_UART0 0x1 | ||
| 50 | |||
| 51 | /* MUX CTRL1 Register Bits */ | ||
| 52 | #define USB_RESET (0x1 << 31) | ||
| 53 | #define SPI1_CS_USE_PWM01 (0x1 << 24) | ||
| 54 | #define SPI1_USE_CAN (0x1 << 23) | ||
| 55 | #define DISABLE_DDR_CONFSPACE (0x1 << 20) | ||
| 56 | #define DDR32TO16EN (0x1 << 16) | ||
| 57 | #define GMAC1_SHUT (0x1 << 13) | ||
| 58 | #define GMAC0_SHUT (0x1 << 12) | ||
| 59 | #define USB_SHUT (0x1 << 11) | ||
| 60 | #define UART1_3_USE_CAN1 (0x1 << 5) | ||
| 61 | #define UART1_2_USE_CAN0 (0x1 << 4) | ||
| 62 | #define GMAC1_USE_TXCLK (0x1 << 3) | ||
| 63 | #define GMAC0_USE_TXCLK (0x1 << 2) | ||
| 64 | #define GMAC1_USE_PWM23 (0x1 << 1) | ||
| 65 | #define GMAC0_USE_PWM01 0x1 | ||
| 66 | |||
| 67 | #endif /* __ASM_MACH_LOONGSON1_REGS_MUX_H */ | ||
diff --git a/arch/mips/include/asm/mach-loongson1/regs-pwm.h b/arch/mips/include/asm/mach-loongson1/regs-pwm.h new file mode 100644 index 000000000000..99f2bcc586f0 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson1/regs-pwm.h | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com> | ||
| 3 | * | ||
| 4 | * Loongson 1 PWM Register Definitions. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License as published by the | ||
| 8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 9 | * option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef __ASM_MACH_LOONGSON1_REGS_PWM_H | ||
| 13 | #define __ASM_MACH_LOONGSON1_REGS_PWM_H | ||
| 14 | |||
| 15 | /* Loongson 1 PWM Timer Register Definitions */ | ||
| 16 | #define PWM_CNT 0x0 | ||
| 17 | #define PWM_HRC 0x4 | ||
| 18 | #define PWM_LRC 0x8 | ||
| 19 | #define PWM_CTRL 0xc | ||
| 20 | |||
| 21 | /* PWM Control Register Bits */ | ||
| 22 | #define CNT_RST (0x1 << 7) | ||
| 23 | #define INT_SR (0x1 << 6) | ||
| 24 | #define INT_EN (0x1 << 5) | ||
| 25 | #define PWM_SINGLE (0x1 << 4) | ||
| 26 | #define PWM_OE (0x1 << 3) | ||
| 27 | #define CNT_EN 0x1 | ||
| 28 | |||
| 29 | #endif /* __ASM_MACH_LOONGSON1_REGS_PWM_H */ | ||
diff --git a/arch/mips/include/asm/mach-loongson1/regs-wdt.h b/arch/mips/include/asm/mach-loongson1/regs-wdt.h index 6574568c2084..c39ee982ad3b 100644 --- a/arch/mips/include/asm/mach-loongson1/regs-wdt.h +++ b/arch/mips/include/asm/mach-loongson1/regs-wdt.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> | 2 | * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> |
| 3 | * | 3 | * |
| 4 | * Loongson 1 watchdog register definitions. | 4 | * Loongson 1 Watchdog Register Definitions. |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
| 7 | * under the terms of the GNU General Public License as published by the | 7 | * under the terms of the GNU General Public License as published by the |
| @@ -12,11 +12,8 @@ | |||
| 12 | #ifndef __ASM_MACH_LOONGSON1_REGS_WDT_H | 12 | #ifndef __ASM_MACH_LOONGSON1_REGS_WDT_H |
| 13 | #define __ASM_MACH_LOONGSON1_REGS_WDT_H | 13 | #define __ASM_MACH_LOONGSON1_REGS_WDT_H |
| 14 | 14 | ||
| 15 | #define LS1X_WDT_REG(x) \ | 15 | #define WDT_EN 0x0 |
| 16 | ((void __iomem *)KSEG1ADDR(LS1X_WDT_BASE + (x))) | 16 | #define WDT_TIMER 0x4 |
| 17 | 17 | #define WDT_SET 0x8 | |
| 18 | #define LS1X_WDT_EN LS1X_WDT_REG(0x0) | ||
| 19 | #define LS1X_WDT_SET LS1X_WDT_REG(0x4) | ||
| 20 | #define LS1X_WDT_TIMER LS1X_WDT_REG(0x8) | ||
| 21 | 18 | ||
| 22 | #endif /* __ASM_MACH_LOONGSON1_REGS_WDT_H */ | 19 | #endif /* __ASM_MACH_LOONGSON1_REGS_WDT_H */ |
diff --git a/arch/mips/include/asm/mach-malta/irq.h b/arch/mips/include/asm/mach-malta/irq.h index f2c13d211abb..47cfe64efbb0 100644 --- a/arch/mips/include/asm/mach-malta/irq.h +++ b/arch/mips/include/asm/mach-malta/irq.h | |||
| @@ -2,7 +2,6 @@ | |||
| 2 | #define __ASM_MACH_MIPS_IRQ_H | 2 | #define __ASM_MACH_MIPS_IRQ_H |
| 3 | 3 | ||
| 4 | 4 | ||
| 5 | #define GIC_NUM_INTRS (24 + NR_CPUS * 2) | ||
| 6 | #define NR_IRQS 256 | 5 | #define NR_IRQS 256 |
| 7 | 6 | ||
| 8 | #include_next <irq.h> | 7 | #include_next <irq.h> |
diff --git a/arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h b/arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h index fc946c835995..2e54b4bff5cf 100644 --- a/arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h +++ b/arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h | |||
| @@ -49,6 +49,7 @@ | |||
| 49 | 49 | ||
| 50 | #include <linux/types.h> | 50 | #include <linux/types.h> |
| 51 | 51 | ||
| 52 | #include <asm/compiler.h> | ||
| 52 | #include <asm/war.h> | 53 | #include <asm/war.h> |
| 53 | 54 | ||
| 54 | #ifndef R10000_LLSC_WAR | 55 | #ifndef R10000_LLSC_WAR |
| @@ -84,8 +85,8 @@ static inline void set_value_reg32(volatile u32 *const addr, | |||
| 84 | " "__beqz"%0, 1b \n" | 85 | " "__beqz"%0, 1b \n" |
| 85 | " nop \n" | 86 | " nop \n" |
| 86 | " .set pop \n" | 87 | " .set pop \n" |
| 87 | : "=&r" (temp), "=m" (*addr) | 88 | : "=&r" (temp), "=" GCC_OFF12_ASM() (*addr) |
| 88 | : "ir" (~mask), "ir" (value), "m" (*addr)); | 89 | : "ir" (~mask), "ir" (value), GCC_OFF12_ASM() (*addr)); |
| 89 | } | 90 | } |
| 90 | 91 | ||
| 91 | /* | 92 | /* |
| @@ -105,8 +106,8 @@ static inline void set_reg32(volatile u32 *const addr, | |||
| 105 | " "__beqz"%0, 1b \n" | 106 | " "__beqz"%0, 1b \n" |
| 106 | " nop \n" | 107 | " nop \n" |
| 107 | " .set pop \n" | 108 | " .set pop \n" |
| 108 | : "=&r" (temp), "=m" (*addr) | 109 | : "=&r" (temp), "=" GCC_OFF12_ASM() (*addr) |
| 109 | : "ir" (mask), "m" (*addr)); | 110 | : "ir" (mask), GCC_OFF12_ASM() (*addr)); |
| 110 | } | 111 | } |
| 111 | 112 | ||
| 112 | /* | 113 | /* |
| @@ -126,8 +127,8 @@ static inline void clear_reg32(volatile u32 *const addr, | |||
| 126 | " "__beqz"%0, 1b \n" | 127 | " "__beqz"%0, 1b \n" |
| 127 | " nop \n" | 128 | " nop \n" |
| 128 | " .set pop \n" | 129 | " .set pop \n" |
| 129 | : "=&r" (temp), "=m" (*addr) | 130 | : "=&r" (temp), "=" GCC_OFF12_ASM() (*addr) |
| 130 | : "ir" (~mask), "m" (*addr)); | 131 | : "ir" (~mask), GCC_OFF12_ASM() (*addr)); |
| 131 | } | 132 | } |
| 132 | 133 | ||
| 133 | /* | 134 | /* |
| @@ -147,8 +148,8 @@ static inline void toggle_reg32(volatile u32 *const addr, | |||
| 147 | " "__beqz"%0, 1b \n" | 148 | " "__beqz"%0, 1b \n" |
| 148 | " nop \n" | 149 | " nop \n" |
| 149 | " .set pop \n" | 150 | " .set pop \n" |
| 150 | : "=&r" (temp), "=m" (*addr) | 151 | : "=&r" (temp), "=" GCC_OFF12_ASM() (*addr) |
| 151 | : "ir" (mask), "m" (*addr)); | 152 | : "ir" (mask), GCC_OFF12_ASM() (*addr)); |
| 152 | } | 153 | } |
| 153 | 154 | ||
| 154 | /* | 155 | /* |
| @@ -219,8 +220,8 @@ static inline u32 blocking_read_reg32(volatile u32 *const addr) | |||
| 219 | " .set arch=r4000 \n" \ | 220 | " .set arch=r4000 \n" \ |
| 220 | "1: ll %0, %1 #custom_read_reg32 \n" \ | 221 | "1: ll %0, %1 #custom_read_reg32 \n" \ |
| 221 | " .set pop \n" \ | 222 | " .set pop \n" \ |
| 222 | : "=r" (tmp), "=m" (*address) \ | 223 | : "=r" (tmp), "=" GCC_OFF12_ASM() (*address) \ |
| 223 | : "m" (*address)) | 224 | : GCC_OFF12_ASM() (*address)) |
| 224 | 225 | ||
| 225 | #define custom_write_reg32(address, tmp) \ | 226 | #define custom_write_reg32(address, tmp) \ |
| 226 | __asm__ __volatile__( \ | 227 | __asm__ __volatile__( \ |
| @@ -230,7 +231,7 @@ static inline u32 blocking_read_reg32(volatile u32 *const addr) | |||
| 230 | " "__beqz"%0, 1b \n" \ | 231 | " "__beqz"%0, 1b \n" \ |
| 231 | " nop \n" \ | 232 | " nop \n" \ |
| 232 | " .set pop \n" \ | 233 | " .set pop \n" \ |
| 233 | : "=&r" (tmp), "=m" (*address) \ | 234 | : "=&r" (tmp), "=" GCC_OFF12_ASM() (*address) \ |
| 234 | : "0" (tmp), "m" (*address)) | 235 | : "0" (tmp), GCC_OFF12_ASM() (*address)) |
| 235 | 236 | ||
| 236 | #endif /* __ASM_REGOPS_H__ */ | 237 | #endif /* __ASM_REGOPS_H__ */ |
diff --git a/arch/mips/include/asm/mach-ralink/mt7620.h b/arch/mips/include/asm/mach-ralink/mt7620.h index 6f9b24f51157..1976fb815fd1 100644 --- a/arch/mips/include/asm/mach-ralink/mt7620.h +++ b/arch/mips/include/asm/mach-ralink/mt7620.h | |||
| @@ -13,6 +13,13 @@ | |||
| 13 | #ifndef _MT7620_REGS_H_ | 13 | #ifndef _MT7620_REGS_H_ |
| 14 | #define _MT7620_REGS_H_ | 14 | #define _MT7620_REGS_H_ |
| 15 | 15 | ||
| 16 | enum mt762x_soc_type { | ||
| 17 | MT762X_SOC_UNKNOWN = 0, | ||
| 18 | MT762X_SOC_MT7620A, | ||
| 19 | MT762X_SOC_MT7620N, | ||
| 20 | MT762X_SOC_MT7628AN, | ||
| 21 | }; | ||
| 22 | |||
| 16 | #define MT7620_SYSC_BASE 0x10000000 | 23 | #define MT7620_SYSC_BASE 0x10000000 |
| 17 | 24 | ||
| 18 | #define SYSC_REG_CHIP_NAME0 0x00 | 25 | #define SYSC_REG_CHIP_NAME0 0x00 |
| @@ -25,11 +32,9 @@ | |||
| 25 | #define SYSC_REG_CPLL_CONFIG0 0x54 | 32 | #define SYSC_REG_CPLL_CONFIG0 0x54 |
| 26 | #define SYSC_REG_CPLL_CONFIG1 0x58 | 33 | #define SYSC_REG_CPLL_CONFIG1 0x58 |
| 27 | 34 | ||
| 28 | #define MT7620N_CHIP_NAME0 0x33365452 | 35 | #define MT7620_CHIP_NAME0 0x3637544d |
| 29 | #define MT7620N_CHIP_NAME1 0x20203235 | 36 | #define MT7620_CHIP_NAME1 0x20203032 |
| 30 | 37 | #define MT7628_CHIP_NAME1 0x20203832 | |
| 31 | #define MT7620A_CHIP_NAME0 0x3637544d | ||
| 32 | #define MT7620A_CHIP_NAME1 0x20203032 | ||
| 33 | 38 | ||
| 34 | #define SYSCFG0_XTAL_FREQ_SEL BIT(6) | 39 | #define SYSCFG0_XTAL_FREQ_SEL BIT(6) |
| 35 | 40 | ||
| @@ -74,6 +79,9 @@ | |||
| 74 | #define SYSCFG0_DRAM_TYPE_DDR1 1 | 79 | #define SYSCFG0_DRAM_TYPE_DDR1 1 |
| 75 | #define SYSCFG0_DRAM_TYPE_DDR2 2 | 80 | #define SYSCFG0_DRAM_TYPE_DDR2 2 |
| 76 | 81 | ||
| 82 | #define SYSCFG0_DRAM_TYPE_DDR2_MT7628 0 | ||
| 83 | #define SYSCFG0_DRAM_TYPE_DDR1_MT7628 1 | ||
| 84 | |||
| 77 | #define MT7620_DRAM_BASE 0x0 | 85 | #define MT7620_DRAM_BASE 0x0 |
| 78 | #define MT7620_SDRAM_SIZE_MIN 2 | 86 | #define MT7620_SDRAM_SIZE_MIN 2 |
| 79 | #define MT7620_SDRAM_SIZE_MAX 64 | 87 | #define MT7620_SDRAM_SIZE_MAX 64 |
| @@ -82,7 +90,6 @@ | |||
| 82 | #define MT7620_DDR2_SIZE_MIN 32 | 90 | #define MT7620_DDR2_SIZE_MIN 32 |
| 83 | #define MT7620_DDR2_SIZE_MAX 256 | 91 | #define MT7620_DDR2_SIZE_MAX 256 |
| 84 | 92 | ||
| 85 | #define MT7620_GPIO_MODE_I2C BIT(0) | ||
| 86 | #define MT7620_GPIO_MODE_UART0_SHIFT 2 | 93 | #define MT7620_GPIO_MODE_UART0_SHIFT 2 |
| 87 | #define MT7620_GPIO_MODE_UART0_MASK 0x7 | 94 | #define MT7620_GPIO_MODE_UART0_MASK 0x7 |
| 88 | #define MT7620_GPIO_MODE_UART0(x) ((x) << MT7620_GPIO_MODE_UART0_SHIFT) | 95 | #define MT7620_GPIO_MODE_UART0(x) ((x) << MT7620_GPIO_MODE_UART0_SHIFT) |
| @@ -94,15 +101,40 @@ | |||
| 94 | #define MT7620_GPIO_MODE_GPIO_UARTF 0x5 | 101 | #define MT7620_GPIO_MODE_GPIO_UARTF 0x5 |
| 95 | #define MT7620_GPIO_MODE_GPIO_I2S 0x6 | 102 | #define MT7620_GPIO_MODE_GPIO_I2S 0x6 |
| 96 | #define MT7620_GPIO_MODE_GPIO 0x7 | 103 | #define MT7620_GPIO_MODE_GPIO 0x7 |
| 97 | #define MT7620_GPIO_MODE_UART1 BIT(5) | 104 | |
| 98 | #define MT7620_GPIO_MODE_MDIO BIT(8) | 105 | #define MT7620_GPIO_MODE_NAND 0 |
| 99 | #define MT7620_GPIO_MODE_RGMII1 BIT(9) | 106 | #define MT7620_GPIO_MODE_SD 1 |
| 100 | #define MT7620_GPIO_MODE_RGMII2 BIT(10) | 107 | #define MT7620_GPIO_MODE_ND_SD_GPIO 2 |
| 101 | #define MT7620_GPIO_MODE_SPI BIT(11) | 108 | #define MT7620_GPIO_MODE_ND_SD_MASK 0x3 |
| 102 | #define MT7620_GPIO_MODE_SPI_REF_CLK BIT(12) | 109 | #define MT7620_GPIO_MODE_ND_SD_SHIFT 18 |
| 103 | #define MT7620_GPIO_MODE_WLED BIT(13) | 110 | |
| 104 | #define MT7620_GPIO_MODE_JTAG BIT(15) | 111 | #define MT7620_GPIO_MODE_PCIE_RST 0 |
| 105 | #define MT7620_GPIO_MODE_EPHY BIT(15) | 112 | #define MT7620_GPIO_MODE_PCIE_REF 1 |
| 106 | #define MT7620_GPIO_MODE_WDT BIT(22) | 113 | #define MT7620_GPIO_MODE_PCIE_GPIO 2 |
| 114 | #define MT7620_GPIO_MODE_PCIE_MASK 0x3 | ||
| 115 | #define MT7620_GPIO_MODE_PCIE_SHIFT 16 | ||
| 116 | |||
| 117 | #define MT7620_GPIO_MODE_WDT_RST 0 | ||
| 118 | #define MT7620_GPIO_MODE_WDT_REF 1 | ||
| 119 | #define MT7620_GPIO_MODE_WDT_GPIO 2 | ||
| 120 | #define MT7620_GPIO_MODE_WDT_MASK 0x3 | ||
| 121 | #define MT7620_GPIO_MODE_WDT_SHIFT 21 | ||
| 122 | |||
| 123 | #define MT7620_GPIO_MODE_I2C 0 | ||
| 124 | #define MT7620_GPIO_MODE_UART1 5 | ||
| 125 | #define MT7620_GPIO_MODE_MDIO 8 | ||
| 126 | #define MT7620_GPIO_MODE_RGMII1 9 | ||
| 127 | #define MT7620_GPIO_MODE_RGMII2 10 | ||
| 128 | #define MT7620_GPIO_MODE_SPI 11 | ||
| 129 | #define MT7620_GPIO_MODE_SPI_REF_CLK 12 | ||
| 130 | #define MT7620_GPIO_MODE_WLED 13 | ||
| 131 | #define MT7620_GPIO_MODE_JTAG 15 | ||
| 132 | #define MT7620_GPIO_MODE_EPHY 15 | ||
| 133 | #define MT7620_GPIO_MODE_PA 20 | ||
| 134 | |||
| 135 | static inline int mt7620_get_eco(void) | ||
| 136 | { | ||
| 137 | return rt_sysc_r32(SYSC_REG_CHIP_REV) & CHIP_REV_ECO_MASK; | ||
| 138 | } | ||
| 107 | 139 | ||
| 108 | #endif | 140 | #endif |
diff --git a/arch/mips/include/asm/mach-ralink/pinmux.h b/arch/mips/include/asm/mach-ralink/pinmux.h new file mode 100644 index 000000000000..be106cb2e26d --- /dev/null +++ b/arch/mips/include/asm/mach-ralink/pinmux.h | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify | ||
| 3 | * it under the terms of the GNU General Public License version 2 as | ||
| 4 | * publishhed by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2012 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #ifndef _RT288X_PINMUX_H__ | ||
| 10 | #define _RT288X_PINMUX_H__ | ||
| 11 | |||
| 12 | #define FUNC(name, value, pin_first, pin_count) \ | ||
| 13 | { name, value, pin_first, pin_count } | ||
| 14 | |||
| 15 | #define GRP(_name, _func, _mask, _shift) \ | ||
| 16 | { .name = _name, .mask = _mask, .shift = _shift, \ | ||
| 17 | .func = _func, .gpio = _mask, \ | ||
| 18 | .func_count = ARRAY_SIZE(_func) } | ||
| 19 | |||
| 20 | #define GRP_G(_name, _func, _mask, _gpio, _shift) \ | ||
| 21 | { .name = _name, .mask = _mask, .shift = _shift, \ | ||
| 22 | .func = _func, .gpio = _gpio, \ | ||
| 23 | .func_count = ARRAY_SIZE(_func) } | ||
| 24 | |||
| 25 | struct rt2880_pmx_group; | ||
| 26 | |||
| 27 | struct rt2880_pmx_func { | ||
| 28 | const char *name; | ||
| 29 | const char value; | ||
| 30 | |||
| 31 | int pin_first; | ||
| 32 | int pin_count; | ||
| 33 | int *pins; | ||
| 34 | |||
| 35 | int *groups; | ||
| 36 | int group_count; | ||
| 37 | |||
| 38 | int enabled; | ||
| 39 | }; | ||
| 40 | |||
| 41 | struct rt2880_pmx_group { | ||
| 42 | const char *name; | ||
| 43 | int enabled; | ||
| 44 | |||
| 45 | const u32 shift; | ||
| 46 | const char mask; | ||
| 47 | const char gpio; | ||
| 48 | |||
| 49 | struct rt2880_pmx_func *func; | ||
| 50 | int func_count; | ||
| 51 | }; | ||
| 52 | |||
| 53 | extern struct rt2880_pmx_group *rt2880_pinmux_data; | ||
| 54 | |||
| 55 | #endif | ||
diff --git a/arch/mips/include/asm/mach-ralink/ralink_regs.h b/arch/mips/include/asm/mach-ralink/ralink_regs.h index 5a508f9f9432..bd93014490df 100644 --- a/arch/mips/include/asm/mach-ralink/ralink_regs.h +++ b/arch/mips/include/asm/mach-ralink/ralink_regs.h | |||
| @@ -26,6 +26,13 @@ static inline u32 rt_sysc_r32(unsigned reg) | |||
| 26 | return __raw_readl(rt_sysc_membase + reg); | 26 | return __raw_readl(rt_sysc_membase + reg); |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | static inline void rt_sysc_m32(u32 clr, u32 set, unsigned reg) | ||
| 30 | { | ||
| 31 | u32 val = rt_sysc_r32(reg) & ~clr; | ||
| 32 | |||
| 33 | __raw_writel(val | set, rt_sysc_membase + reg); | ||
| 34 | } | ||
| 35 | |||
| 29 | static inline void rt_memc_w32(u32 val, unsigned reg) | 36 | static inline void rt_memc_w32(u32 val, unsigned reg) |
| 30 | { | 37 | { |
| 31 | __raw_writel(val, rt_memc_membase + reg); | 38 | __raw_writel(val, rt_memc_membase + reg); |
diff --git a/arch/mips/include/asm/mach-ralink/rt305x.h b/arch/mips/include/asm/mach-ralink/rt305x.h index 069bf37a6010..96f731bac79a 100644 --- a/arch/mips/include/asm/mach-ralink/rt305x.h +++ b/arch/mips/include/asm/mach-ralink/rt305x.h | |||
| @@ -125,24 +125,29 @@ static inline int soc_is_rt5350(void) | |||
| 125 | #define RT305X_GPIO_GE0_TXD0 40 | 125 | #define RT305X_GPIO_GE0_TXD0 40 |
| 126 | #define RT305X_GPIO_GE0_RXCLK 51 | 126 | #define RT305X_GPIO_GE0_RXCLK 51 |
| 127 | 127 | ||
| 128 | #define RT305X_GPIO_MODE_I2C BIT(0) | ||
| 129 | #define RT305X_GPIO_MODE_SPI BIT(1) | ||
| 130 | #define RT305X_GPIO_MODE_UART0_SHIFT 2 | 128 | #define RT305X_GPIO_MODE_UART0_SHIFT 2 |
| 131 | #define RT305X_GPIO_MODE_UART0_MASK 0x7 | 129 | #define RT305X_GPIO_MODE_UART0_MASK 0x7 |
| 132 | #define RT305X_GPIO_MODE_UART0(x) ((x) << RT305X_GPIO_MODE_UART0_SHIFT) | 130 | #define RT305X_GPIO_MODE_UART0(x) ((x) << RT305X_GPIO_MODE_UART0_SHIFT) |
| 133 | #define RT305X_GPIO_MODE_UARTF 0x0 | 131 | #define RT305X_GPIO_MODE_UARTF 0 |
| 134 | #define RT305X_GPIO_MODE_PCM_UARTF 0x1 | 132 | #define RT305X_GPIO_MODE_PCM_UARTF 1 |
| 135 | #define RT305X_GPIO_MODE_PCM_I2S 0x2 | 133 | #define RT305X_GPIO_MODE_PCM_I2S 2 |
| 136 | #define RT305X_GPIO_MODE_I2S_UARTF 0x3 | 134 | #define RT305X_GPIO_MODE_I2S_UARTF 3 |
| 137 | #define RT305X_GPIO_MODE_PCM_GPIO 0x4 | 135 | #define RT305X_GPIO_MODE_PCM_GPIO 4 |
| 138 | #define RT305X_GPIO_MODE_GPIO_UARTF 0x5 | 136 | #define RT305X_GPIO_MODE_GPIO_UARTF 5 |
| 139 | #define RT305X_GPIO_MODE_GPIO_I2S 0x6 | 137 | #define RT305X_GPIO_MODE_GPIO_I2S 6 |
| 140 | #define RT305X_GPIO_MODE_GPIO 0x7 | 138 | #define RT305X_GPIO_MODE_GPIO 7 |
| 141 | #define RT305X_GPIO_MODE_UART1 BIT(5) | 139 | |
| 142 | #define RT305X_GPIO_MODE_JTAG BIT(6) | 140 | #define RT305X_GPIO_MODE_I2C 0 |
| 143 | #define RT305X_GPIO_MODE_MDIO BIT(7) | 141 | #define RT305X_GPIO_MODE_SPI 1 |
| 144 | #define RT305X_GPIO_MODE_SDRAM BIT(8) | 142 | #define RT305X_GPIO_MODE_UART1 5 |
| 145 | #define RT305X_GPIO_MODE_RGMII BIT(9) | 143 | #define RT305X_GPIO_MODE_JTAG 6 |
| 144 | #define RT305X_GPIO_MODE_MDIO 7 | ||
| 145 | #define RT305X_GPIO_MODE_SDRAM 8 | ||
| 146 | #define RT305X_GPIO_MODE_RGMII 9 | ||
| 147 | #define RT5350_GPIO_MODE_PHY_LED 14 | ||
| 148 | #define RT5350_GPIO_MODE_SPI_CS1 21 | ||
| 149 | #define RT3352_GPIO_MODE_LNA 18 | ||
| 150 | #define RT3352_GPIO_MODE_PA 20 | ||
| 146 | 151 | ||
| 147 | #define RT3352_SYSC_REG_SYSCFG0 0x010 | 152 | #define RT3352_SYSC_REG_SYSCFG0 0x010 |
| 148 | #define RT3352_SYSC_REG_SYSCFG1 0x014 | 153 | #define RT3352_SYSC_REG_SYSCFG1 0x014 |
diff --git a/arch/mips/include/asm/mach-ralink/rt3883.h b/arch/mips/include/asm/mach-ralink/rt3883.h index 058382f37f92..0fbe6f9257cd 100644 --- a/arch/mips/include/asm/mach-ralink/rt3883.h +++ b/arch/mips/include/asm/mach-ralink/rt3883.h | |||
| @@ -112,8 +112,6 @@ | |||
| 112 | #define RT3883_CLKCFG1_PCI_CLK_EN BIT(19) | 112 | #define RT3883_CLKCFG1_PCI_CLK_EN BIT(19) |
| 113 | #define RT3883_CLKCFG1_UPHY0_CLK_EN BIT(18) | 113 | #define RT3883_CLKCFG1_UPHY0_CLK_EN BIT(18) |
| 114 | 114 | ||
| 115 | #define RT3883_GPIO_MODE_I2C BIT(0) | ||
| 116 | #define RT3883_GPIO_MODE_SPI BIT(1) | ||
| 117 | #define RT3883_GPIO_MODE_UART0_SHIFT 2 | 115 | #define RT3883_GPIO_MODE_UART0_SHIFT 2 |
| 118 | #define RT3883_GPIO_MODE_UART0_MASK 0x7 | 116 | #define RT3883_GPIO_MODE_UART0_MASK 0x7 |
| 119 | #define RT3883_GPIO_MODE_UART0(x) ((x) << RT3883_GPIO_MODE_UART0_SHIFT) | 117 | #define RT3883_GPIO_MODE_UART0(x) ((x) << RT3883_GPIO_MODE_UART0_SHIFT) |
| @@ -125,11 +123,15 @@ | |||
| 125 | #define RT3883_GPIO_MODE_GPIO_UARTF 0x5 | 123 | #define RT3883_GPIO_MODE_GPIO_UARTF 0x5 |
| 126 | #define RT3883_GPIO_MODE_GPIO_I2S 0x6 | 124 | #define RT3883_GPIO_MODE_GPIO_I2S 0x6 |
| 127 | #define RT3883_GPIO_MODE_GPIO 0x7 | 125 | #define RT3883_GPIO_MODE_GPIO 0x7 |
| 128 | #define RT3883_GPIO_MODE_UART1 BIT(5) | 126 | |
| 129 | #define RT3883_GPIO_MODE_JTAG BIT(6) | 127 | #define RT3883_GPIO_MODE_I2C 0 |
| 130 | #define RT3883_GPIO_MODE_MDIO BIT(7) | 128 | #define RT3883_GPIO_MODE_SPI 1 |
| 131 | #define RT3883_GPIO_MODE_GE1 BIT(9) | 129 | #define RT3883_GPIO_MODE_UART1 5 |
| 132 | #define RT3883_GPIO_MODE_GE2 BIT(10) | 130 | #define RT3883_GPIO_MODE_JTAG 6 |
| 131 | #define RT3883_GPIO_MODE_MDIO 7 | ||
| 132 | #define RT3883_GPIO_MODE_GE1 9 | ||
| 133 | #define RT3883_GPIO_MODE_GE2 10 | ||
| 134 | |||
| 133 | #define RT3883_GPIO_MODE_PCI_SHIFT 11 | 135 | #define RT3883_GPIO_MODE_PCI_SHIFT 11 |
| 134 | #define RT3883_GPIO_MODE_PCI_MASK 0x7 | 136 | #define RT3883_GPIO_MODE_PCI_MASK 0x7 |
| 135 | #define RT3883_GPIO_MODE_PCI (RT3883_GPIO_MODE_PCI_MASK << RT3883_GPIO_MODE_PCI_SHIFT) | 137 | #define RT3883_GPIO_MODE_PCI (RT3883_GPIO_MODE_PCI_MASK << RT3883_GPIO_MODE_PCI_SHIFT) |
diff --git a/arch/mips/include/asm/mach-sead3/irq.h b/arch/mips/include/asm/mach-sead3/irq.h index d8106f75b9af..5d154cfbcf4c 100644 --- a/arch/mips/include/asm/mach-sead3/irq.h +++ b/arch/mips/include/asm/mach-sead3/irq.h | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | #ifndef __ASM_MACH_MIPS_IRQ_H | 1 | #ifndef __ASM_MACH_MIPS_IRQ_H |
| 2 | #define __ASM_MACH_MIPS_IRQ_H | 2 | #define __ASM_MACH_MIPS_IRQ_H |
| 3 | 3 | ||
| 4 | #define GIC_NUM_INTRS (24 + NR_CPUS * 2) | ||
| 5 | #define NR_IRQS 256 | 4 | #define NR_IRQS 256 |
| 6 | 5 | ||
| 7 | 6 | ||
diff --git a/arch/mips/include/asm/mach-tx39xx/ioremap.h b/arch/mips/include/asm/mach-tx39xx/ioremap.h index 93c6c04ffda3..0874cd2b06d7 100644 --- a/arch/mips/include/asm/mach-tx39xx/ioremap.h +++ b/arch/mips/include/asm/mach-tx39xx/ioremap.h | |||
| @@ -15,12 +15,12 @@ | |||
| 15 | * Allow physical addresses to be fixed up to help peripherals located | 15 | * Allow physical addresses to be fixed up to help peripherals located |
| 16 | * outside the low 32-bit range -- generic pass-through version. | 16 | * outside the low 32-bit range -- generic pass-through version. |
| 17 | */ | 17 | */ |
| 18 | static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) | 18 | static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) |
| 19 | { | 19 | { |
| 20 | return phys_addr; | 20 | return phys_addr; |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, | 23 | static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, |
| 24 | unsigned long flags) | 24 | unsigned long flags) |
| 25 | { | 25 | { |
| 26 | #define TXX9_DIRECTMAP_BASE 0xff000000ul | 26 | #define TXX9_DIRECTMAP_BASE 0xff000000ul |
diff --git a/arch/mips/include/asm/mach-tx49xx/ioremap.h b/arch/mips/include/asm/mach-tx49xx/ioremap.h index 1e7beae72229..4b6a8441b25f 100644 --- a/arch/mips/include/asm/mach-tx49xx/ioremap.h +++ b/arch/mips/include/asm/mach-tx49xx/ioremap.h | |||
| @@ -15,12 +15,12 @@ | |||
| 15 | * Allow physical addresses to be fixed up to help peripherals located | 15 | * Allow physical addresses to be fixed up to help peripherals located |
| 16 | * outside the low 32-bit range -- generic pass-through version. | 16 | * outside the low 32-bit range -- generic pass-through version. |
| 17 | */ | 17 | */ |
| 18 | static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) | 18 | static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) |
| 19 | { | 19 | { |
| 20 | return phys_addr; | 20 | return phys_addr; |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, | 23 | static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, |
| 24 | unsigned long flags) | 24 | unsigned long flags) |
| 25 | { | 25 | { |
| 26 | #ifdef CONFIG_64BIT | 26 | #ifdef CONFIG_64BIT |
diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h index e330732ddf98..987ff580466b 100644 --- a/arch/mips/include/asm/mips-boards/maltaint.h +++ b/arch/mips/include/asm/mips-boards/maltaint.h | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | #ifndef _MIPS_MALTAINT_H | 10 | #ifndef _MIPS_MALTAINT_H |
| 11 | #define _MIPS_MALTAINT_H | 11 | #define _MIPS_MALTAINT_H |
| 12 | 12 | ||
| 13 | #define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8) | 13 | #include <linux/irqchip/mips-gic.h> |
| 14 | 14 | ||
| 15 | /* | 15 | /* |
| 16 | * Interrupts 0..15 are used for Malta ISA compatible interrupts | 16 | * Interrupts 0..15 are used for Malta ISA compatible interrupts |
| @@ -22,29 +22,28 @@ | |||
| 22 | #define MIPSCPU_INT_SW1 1 | 22 | #define MIPSCPU_INT_SW1 1 |
| 23 | #define MIPSCPU_INT_MB0 2 | 23 | #define MIPSCPU_INT_MB0 2 |
| 24 | #define MIPSCPU_INT_I8259A MIPSCPU_INT_MB0 | 24 | #define MIPSCPU_INT_I8259A MIPSCPU_INT_MB0 |
| 25 | #define MIPSCPU_INT_GIC MIPSCPU_INT_MB0 /* GIC chained interrupt */ | ||
| 25 | #define MIPSCPU_INT_MB1 3 | 26 | #define MIPSCPU_INT_MB1 3 |
| 26 | #define MIPSCPU_INT_SMI MIPSCPU_INT_MB1 | 27 | #define MIPSCPU_INT_SMI MIPSCPU_INT_MB1 |
| 27 | #define MIPSCPU_INT_IPI0 MIPSCPU_INT_MB1 /* GIC IPI */ | ||
| 28 | #define MIPSCPU_INT_MB2 4 | 28 | #define MIPSCPU_INT_MB2 4 |
| 29 | #define MIPSCPU_INT_IPI1 MIPSCPU_INT_MB2 /* GIC IPI */ | ||
| 30 | #define MIPSCPU_INT_MB3 5 | 29 | #define MIPSCPU_INT_MB3 5 |
| 31 | #define MIPSCPU_INT_COREHI MIPSCPU_INT_MB3 | 30 | #define MIPSCPU_INT_COREHI MIPSCPU_INT_MB3 |
| 32 | #define MIPSCPU_INT_MB4 6 | 31 | #define MIPSCPU_INT_MB4 6 |
| 33 | #define MIPSCPU_INT_CORELO MIPSCPU_INT_MB4 | 32 | #define MIPSCPU_INT_CORELO MIPSCPU_INT_MB4 |
| 34 | 33 | ||
| 35 | /* | 34 | /* |
| 36 | * Interrupts 64..127 are used for Soc-it Classic interrupts | 35 | * Interrupts 96..127 are used for Soc-it Classic interrupts |
| 37 | */ | 36 | */ |
| 38 | #define MSC01C_INT_BASE 64 | 37 | #define MSC01C_INT_BASE 96 |
| 39 | 38 | ||
| 40 | /* SOC-it Classic interrupt offsets */ | 39 | /* SOC-it Classic interrupt offsets */ |
| 41 | #define MSC01C_INT_TMR 0 | 40 | #define MSC01C_INT_TMR 0 |
| 42 | #define MSC01C_INT_PCI 1 | 41 | #define MSC01C_INT_PCI 1 |
| 43 | 42 | ||
| 44 | /* | 43 | /* |
| 45 | * Interrupts 64..127 are used for Soc-it EIC interrupts | 44 | * Interrupts 96..127 are used for Soc-it EIC interrupts |
| 46 | */ | 45 | */ |
| 47 | #define MSC01E_INT_BASE 64 | 46 | #define MSC01E_INT_BASE 96 |
| 48 | 47 | ||
| 49 | /* SOC-it EIC interrupt offsets */ | 48 | /* SOC-it EIC interrupt offsets */ |
| 50 | #define MSC01E_INT_SW0 1 | 49 | #define MSC01E_INT_SW0 1 |
| @@ -63,14 +62,7 @@ | |||
| 63 | #define MSC01E_INT_PERFCTR 10 | 62 | #define MSC01E_INT_PERFCTR 10 |
| 64 | #define MSC01E_INT_CPUCTR 11 | 63 | #define MSC01E_INT_CPUCTR 11 |
| 65 | 64 | ||
| 66 | /* External Interrupts used for IPI */ | 65 | /* GIC external interrupts */ |
| 67 | #define GIC_IPI_EXT_INTR_RESCHED_VPE0 16 | 66 | #define GIC_INT_I8259A GIC_SHARED_TO_HWIRQ(3) |
| 68 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE0 17 | ||
| 69 | #define GIC_IPI_EXT_INTR_RESCHED_VPE1 18 | ||
| 70 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE1 19 | ||
| 71 | #define GIC_IPI_EXT_INTR_RESCHED_VPE2 20 | ||
| 72 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE2 21 | ||
| 73 | #define GIC_IPI_EXT_INTR_RESCHED_VPE3 22 | ||
| 74 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE3 23 | ||
| 75 | 67 | ||
| 76 | #endif /* !(_MIPS_MALTAINT_H) */ | 68 | #endif /* !(_MIPS_MALTAINT_H) */ |
diff --git a/arch/mips/include/asm/mips-boards/sead3int.h b/arch/mips/include/asm/mips-boards/sead3int.h index 6b17aaf7d901..8932c7de0419 100644 --- a/arch/mips/include/asm/mips-boards/sead3int.h +++ b/arch/mips/include/asm/mips-boards/sead3int.h | |||
| @@ -10,10 +10,23 @@ | |||
| 10 | #ifndef _MIPS_SEAD3INT_H | 10 | #ifndef _MIPS_SEAD3INT_H |
| 11 | #define _MIPS_SEAD3INT_H | 11 | #define _MIPS_SEAD3INT_H |
| 12 | 12 | ||
| 13 | #include <linux/irqchip/mips-gic.h> | ||
| 14 | |||
| 13 | /* SEAD-3 GIC address space definitions. */ | 15 | /* SEAD-3 GIC address space definitions. */ |
| 14 | #define GIC_BASE_ADDR 0x1b1c0000 | 16 | #define GIC_BASE_ADDR 0x1b1c0000 |
| 15 | #define GIC_ADDRSPACE_SZ (128 * 1024) | 17 | #define GIC_ADDRSPACE_SZ (128 * 1024) |
| 16 | 18 | ||
| 17 | #define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 0) | 19 | /* CPU interrupt offsets */ |
| 20 | #define CPU_INT_GIC 2 | ||
| 21 | #define CPU_INT_EHCI 2 | ||
| 22 | #define CPU_INT_UART0 4 | ||
| 23 | #define CPU_INT_UART1 4 | ||
| 24 | #define CPU_INT_NET 6 | ||
| 25 | |||
| 26 | /* GIC interrupt offsets */ | ||
| 27 | #define GIC_INT_NET GIC_SHARED_TO_HWIRQ(0) | ||
| 28 | #define GIC_INT_UART1 GIC_SHARED_TO_HWIRQ(2) | ||
| 29 | #define GIC_INT_UART0 GIC_SHARED_TO_HWIRQ(3) | ||
| 30 | #define GIC_INT_EHCI GIC_SHARED_TO_HWIRQ(5) | ||
| 18 | 31 | ||
| 19 | #endif /* !(_MIPS_SEAD3INT_H) */ | 32 | #endif /* !(_MIPS_SEAD3INT_H) */ |
diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h index 6a9d2dd005ca..b95a827d763e 100644 --- a/arch/mips/include/asm/mips-cm.h +++ b/arch/mips/include/asm/mips-cm.h | |||
| @@ -30,7 +30,7 @@ extern void __iomem *mips_cm_l2sync_base; | |||
| 30 | * different way by defining a function with the same prototype except for the | 30 | * different way by defining a function with the same prototype except for the |
| 31 | * name mips_cm_phys_base (without underscores). | 31 | * name mips_cm_phys_base (without underscores). |
| 32 | */ | 32 | */ |
| 33 | extern phys_t __mips_cm_phys_base(void); | 33 | extern phys_addr_t __mips_cm_phys_base(void); |
| 34 | 34 | ||
| 35 | /** | 35 | /** |
| 36 | * mips_cm_probe - probe for a Coherence Manager | 36 | * mips_cm_probe - probe for a Coherence Manager |
diff --git a/arch/mips/include/asm/mips-cpc.h b/arch/mips/include/asm/mips-cpc.h index e139a534e0fd..1cebe8c79051 100644 --- a/arch/mips/include/asm/mips-cpc.h +++ b/arch/mips/include/asm/mips-cpc.h | |||
| @@ -25,7 +25,7 @@ extern void __iomem *mips_cpc_base; | |||
| 25 | * memory mapped registers. This is platform dependant & must therefore be | 25 | * memory mapped registers. This is platform dependant & must therefore be |
| 26 | * implemented per-platform. | 26 | * implemented per-platform. |
| 27 | */ | 27 | */ |
| 28 | extern phys_t mips_cpc_default_phys_base(void); | 28 | extern phys_addr_t mips_cpc_default_phys_base(void); |
| 29 | 29 | ||
| 30 | /** | 30 | /** |
| 31 | * mips_cpc_phys_base - retrieve the physical base address of the CPC | 31 | * mips_cpc_phys_base - retrieve the physical base address of the CPC |
| @@ -35,7 +35,7 @@ extern phys_t mips_cpc_default_phys_base(void); | |||
| 35 | * is present. It may be overriden by individual platforms which determine | 35 | * is present. It may be overriden by individual platforms which determine |
| 36 | * this address in a different way. | 36 | * this address in a different way. |
| 37 | */ | 37 | */ |
| 38 | extern phys_t __weak mips_cpc_phys_base(void); | 38 | extern phys_addr_t __weak mips_cpc_phys_base(void); |
| 39 | 39 | ||
| 40 | /** | 40 | /** |
| 41 | * mips_cpc_probe - probe for a Cluster Power Controller | 41 | * mips_cpc_probe - probe for a Cluster Power Controller |
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 22a135ac91de..5e4aef304b02 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h | |||
| @@ -653,6 +653,9 @@ | |||
| 653 | #define MIPS_CONF5_NF (_ULCAST_(1) << 0) | 653 | #define MIPS_CONF5_NF (_ULCAST_(1) << 0) |
| 654 | #define MIPS_CONF5_UFR (_ULCAST_(1) << 2) | 654 | #define MIPS_CONF5_UFR (_ULCAST_(1) << 2) |
| 655 | #define MIPS_CONF5_MRP (_ULCAST_(1) << 3) | 655 | #define MIPS_CONF5_MRP (_ULCAST_(1) << 3) |
| 656 | #define MIPS_CONF5_MVH (_ULCAST_(1) << 5) | ||
| 657 | #define MIPS_CONF5_FRE (_ULCAST_(1) << 8) | ||
| 658 | #define MIPS_CONF5_UFE (_ULCAST_(1) << 9) | ||
| 656 | #define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27) | 659 | #define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27) |
| 657 | #define MIPS_CONF5_EVA (_ULCAST_(1) << 28) | 660 | #define MIPS_CONF5_EVA (_ULCAST_(1) << 28) |
| 658 | #define MIPS_CONF5_CV (_ULCAST_(1) << 29) | 661 | #define MIPS_CONF5_CV (_ULCAST_(1) << 29) |
| @@ -694,6 +697,7 @@ | |||
| 694 | #define MIPS_FPIR_W (_ULCAST_(1) << 20) | 697 | #define MIPS_FPIR_W (_ULCAST_(1) << 20) |
| 695 | #define MIPS_FPIR_L (_ULCAST_(1) << 21) | 698 | #define MIPS_FPIR_L (_ULCAST_(1) << 21) |
| 696 | #define MIPS_FPIR_F64 (_ULCAST_(1) << 22) | 699 | #define MIPS_FPIR_F64 (_ULCAST_(1) << 22) |
| 700 | #define MIPS_FPIR_FREP (_ULCAST_(1) << 29) | ||
| 697 | 701 | ||
| 698 | /* | 702 | /* |
| 699 | * Bits in the MIPS32 Memory Segmentation registers. | 703 | * Bits in the MIPS32 Memory Segmentation registers. |
| @@ -994,6 +998,39 @@ do { \ | |||
| 994 | local_irq_restore(__flags); \ | 998 | local_irq_restore(__flags); \ |
| 995 | } while (0) | 999 | } while (0) |
| 996 | 1000 | ||
| 1001 | #define __readx_32bit_c0_register(source) \ | ||
| 1002 | ({ \ | ||
| 1003 | unsigned int __res; \ | ||
| 1004 | \ | ||
| 1005 | __asm__ __volatile__( \ | ||
| 1006 | " .set push \n" \ | ||
| 1007 | " .set noat \n" \ | ||
| 1008 | " .set mips32r2 \n" \ | ||
| 1009 | " .insn \n" \ | ||
| 1010 | " # mfhc0 $1, %1 \n" \ | ||
| 1011 | " .word (0x40410000 | ((%1 & 0x1f) << 11)) \n" \ | ||
| 1012 | " move %0, $1 \n" \ | ||
| 1013 | " .set pop \n" \ | ||
| 1014 | : "=r" (__res) \ | ||
| 1015 | : "i" (source)); \ | ||
| 1016 | __res; \ | ||
| 1017 | }) | ||
| 1018 | |||
| 1019 | #define __writex_32bit_c0_register(register, value) \ | ||
| 1020 | do { \ | ||
| 1021 | __asm__ __volatile__( \ | ||
| 1022 | " .set push \n" \ | ||
| 1023 | " .set noat \n" \ | ||
| 1024 | " .set mips32r2 \n" \ | ||
| 1025 | " move $1, %0 \n" \ | ||
| 1026 | " # mthc0 $1, %1 \n" \ | ||
| 1027 | " .insn \n" \ | ||
| 1028 | " .word (0x40c10000 | ((%1 & 0x1f) << 11)) \n" \ | ||
| 1029 | " .set pop \n" \ | ||
| 1030 | : \ | ||
| 1031 | : "r" (value), "i" (register)); \ | ||
| 1032 | } while (0) | ||
| 1033 | |||
| 997 | #define read_c0_index() __read_32bit_c0_register($0, 0) | 1034 | #define read_c0_index() __read_32bit_c0_register($0, 0) |
| 998 | #define write_c0_index(val) __write_32bit_c0_register($0, 0, val) | 1035 | #define write_c0_index(val) __write_32bit_c0_register($0, 0, val) |
| 999 | 1036 | ||
| @@ -1003,9 +1040,15 @@ do { \ | |||
| 1003 | #define read_c0_entrylo0() __read_ulong_c0_register($2, 0) | 1040 | #define read_c0_entrylo0() __read_ulong_c0_register($2, 0) |
| 1004 | #define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val) | 1041 | #define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val) |
| 1005 | 1042 | ||
| 1043 | #define readx_c0_entrylo0() __readx_32bit_c0_register(2) | ||
| 1044 | #define writex_c0_entrylo0(val) __writex_32bit_c0_register(2, val) | ||
| 1045 | |||
| 1006 | #define read_c0_entrylo1() __read_ulong_c0_register($3, 0) | 1046 | #define read_c0_entrylo1() __read_ulong_c0_register($3, 0) |
| 1007 | #define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val) | 1047 | #define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val) |
| 1008 | 1048 | ||
| 1049 | #define readx_c0_entrylo1() __readx_32bit_c0_register(3) | ||
| 1050 | #define writex_c0_entrylo1(val) __writex_32bit_c0_register(3, val) | ||
| 1051 | |||
| 1009 | #define read_c0_conf() __read_32bit_c0_register($3, 0) | 1052 | #define read_c0_conf() __read_32bit_c0_register($3, 0) |
| 1010 | #define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) | 1053 | #define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) |
| 1011 | 1054 | ||
diff --git a/arch/mips/include/asm/octeon/cvmx-cmd-queue.h b/arch/mips/include/asm/octeon/cvmx-cmd-queue.h index 024a71b2bff9..75739c83f07e 100644 --- a/arch/mips/include/asm/octeon/cvmx-cmd-queue.h +++ b/arch/mips/include/asm/octeon/cvmx-cmd-queue.h | |||
| @@ -76,6 +76,8 @@ | |||
| 76 | 76 | ||
| 77 | #include <linux/prefetch.h> | 77 | #include <linux/prefetch.h> |
| 78 | 78 | ||
| 79 | #include <asm/compiler.h> | ||
| 80 | |||
| 79 | #include <asm/octeon/cvmx-fpa.h> | 81 | #include <asm/octeon/cvmx-fpa.h> |
| 80 | /** | 82 | /** |
| 81 | * By default we disable the max depth support. Most programs | 83 | * By default we disable the max depth support. Most programs |
| @@ -273,7 +275,7 @@ static inline void __cvmx_cmd_queue_lock(cvmx_cmd_queue_id_t queue_id, | |||
| 273 | " lbu %[ticket], %[now_serving]\n" | 275 | " lbu %[ticket], %[now_serving]\n" |
| 274 | "4:\n" | 276 | "4:\n" |
| 275 | ".set pop\n" : | 277 | ".set pop\n" : |
| 276 | [ticket_ptr] "=m"(__cvmx_cmd_queue_state_ptr->ticket[__cvmx_cmd_queue_get_index(queue_id)]), | 278 | [ticket_ptr] "=" GCC_OFF12_ASM()(__cvmx_cmd_queue_state_ptr->ticket[__cvmx_cmd_queue_get_index(queue_id)]), |
| 277 | [now_serving] "=m"(qptr->now_serving), [ticket] "=r"(tmp), | 279 | [now_serving] "=m"(qptr->now_serving), [ticket] "=r"(tmp), |
| 278 | [my_ticket] "=r"(my_ticket) | 280 | [my_ticket] "=r"(my_ticket) |
| 279 | ); | 281 | ); |
diff --git a/arch/mips/include/asm/octeon/cvmx-pow.h b/arch/mips/include/asm/octeon/cvmx-pow.h index 4b4d0ecfd9eb..2188e65afb86 100644 --- a/arch/mips/include/asm/octeon/cvmx-pow.h +++ b/arch/mips/include/asm/octeon/cvmx-pow.h | |||
| @@ -1066,7 +1066,7 @@ static inline void __cvmx_pow_warn_if_pending_switch(const char *function) | |||
| 1066 | uint64_t switch_complete; | 1066 | uint64_t switch_complete; |
| 1067 | CVMX_MF_CHORD(switch_complete); | 1067 | CVMX_MF_CHORD(switch_complete); |
| 1068 | if (!switch_complete) | 1068 | if (!switch_complete) |
| 1069 | pr_warning("%s called with tag switch in progress\n", function); | 1069 | pr_warn("%s called with tag switch in progress\n", function); |
| 1070 | } | 1070 | } |
| 1071 | 1071 | ||
| 1072 | /** | 1072 | /** |
| @@ -1084,8 +1084,7 @@ static inline void cvmx_pow_tag_sw_wait(void) | |||
| 1084 | if (unlikely(switch_complete)) | 1084 | if (unlikely(switch_complete)) |
| 1085 | break; | 1085 | break; |
| 1086 | if (unlikely(cvmx_get_cycle() > start_cycle + MAX_CYCLES)) { | 1086 | if (unlikely(cvmx_get_cycle() > start_cycle + MAX_CYCLES)) { |
| 1087 | pr_warning("Tag switch is taking a long time, " | 1087 | pr_warn("Tag switch is taking a long time, possible deadlock\n"); |
| 1088 | "possible deadlock\n"); | ||
| 1089 | start_cycle = -MAX_CYCLES - 1; | 1088 | start_cycle = -MAX_CYCLES - 1; |
| 1090 | } | 1089 | } |
| 1091 | } | 1090 | } |
| @@ -1296,19 +1295,16 @@ static inline void cvmx_pow_tag_sw_nocheck(uint32_t tag, | |||
| 1296 | __cvmx_pow_warn_if_pending_switch(__func__); | 1295 | __cvmx_pow_warn_if_pending_switch(__func__); |
| 1297 | current_tag = cvmx_pow_get_current_tag(); | 1296 | current_tag = cvmx_pow_get_current_tag(); |
| 1298 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) | 1297 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) |
| 1299 | pr_warning("%s called with NULL_NULL tag\n", | 1298 | pr_warn("%s called with NULL_NULL tag\n", __func__); |
| 1300 | __func__); | ||
| 1301 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) | 1299 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) |
| 1302 | pr_warning("%s called with NULL tag\n", __func__); | 1300 | pr_warn("%s called with NULL tag\n", __func__); |
| 1303 | if ((current_tag.s.type == tag_type) | 1301 | if ((current_tag.s.type == tag_type) |
| 1304 | && (current_tag.s.tag == tag)) | 1302 | && (current_tag.s.tag == tag)) |
| 1305 | pr_warning("%s called to perform a tag switch to the " | 1303 | pr_warn("%s called to perform a tag switch to the same tag\n", |
| 1306 | "same tag\n", | 1304 | __func__); |
| 1307 | __func__); | ||
| 1308 | if (tag_type == CVMX_POW_TAG_TYPE_NULL) | 1305 | if (tag_type == CVMX_POW_TAG_TYPE_NULL) |
| 1309 | pr_warning("%s called to perform a tag switch to " | 1306 | pr_warn("%s called to perform a tag switch to NULL. Use cvmx_pow_tag_sw_null() instead\n", |
| 1310 | "NULL. Use cvmx_pow_tag_sw_null() instead\n", | 1307 | __func__); |
| 1311 | __func__); | ||
| 1312 | } | 1308 | } |
| 1313 | 1309 | ||
| 1314 | /* | 1310 | /* |
| @@ -1407,23 +1403,19 @@ static inline void cvmx_pow_tag_sw_full_nocheck(cvmx_wqe_t *wqp, uint32_t tag, | |||
| 1407 | __cvmx_pow_warn_if_pending_switch(__func__); | 1403 | __cvmx_pow_warn_if_pending_switch(__func__); |
| 1408 | current_tag = cvmx_pow_get_current_tag(); | 1404 | current_tag = cvmx_pow_get_current_tag(); |
| 1409 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) | 1405 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) |
| 1410 | pr_warning("%s called with NULL_NULL tag\n", | 1406 | pr_warn("%s called with NULL_NULL tag\n", __func__); |
| 1411 | __func__); | ||
| 1412 | if ((current_tag.s.type == tag_type) | 1407 | if ((current_tag.s.type == tag_type) |
| 1413 | && (current_tag.s.tag == tag)) | 1408 | && (current_tag.s.tag == tag)) |
| 1414 | pr_warning("%s called to perform a tag switch to " | 1409 | pr_warn("%s called to perform a tag switch to the same tag\n", |
| 1415 | "the same tag\n", | 1410 | __func__); |
| 1416 | __func__); | ||
| 1417 | if (tag_type == CVMX_POW_TAG_TYPE_NULL) | 1411 | if (tag_type == CVMX_POW_TAG_TYPE_NULL) |
| 1418 | pr_warning("%s called to perform a tag switch to " | 1412 | pr_warn("%s called to perform a tag switch to NULL. Use cvmx_pow_tag_sw_null() instead\n", |
| 1419 | "NULL. Use cvmx_pow_tag_sw_null() instead\n", | 1413 | __func__); |
| 1420 | __func__); | ||
| 1421 | if (wqp != cvmx_phys_to_ptr(0x80)) | 1414 | if (wqp != cvmx_phys_to_ptr(0x80)) |
| 1422 | if (wqp != cvmx_pow_get_current_wqp()) | 1415 | if (wqp != cvmx_pow_get_current_wqp()) |
| 1423 | pr_warning("%s passed WQE(%p) doesn't match " | 1416 | pr_warn("%s passed WQE(%p) doesn't match the address in the POW(%p)\n", |
| 1424 | "the address in the POW(%p)\n", | 1417 | __func__, wqp, |
| 1425 | __func__, wqp, | 1418 | cvmx_pow_get_current_wqp()); |
| 1426 | cvmx_pow_get_current_wqp()); | ||
| 1427 | } | 1419 | } |
| 1428 | 1420 | ||
| 1429 | /* | 1421 | /* |
| @@ -1507,12 +1499,10 @@ static inline void cvmx_pow_tag_sw_null_nocheck(void) | |||
| 1507 | __cvmx_pow_warn_if_pending_switch(__func__); | 1499 | __cvmx_pow_warn_if_pending_switch(__func__); |
| 1508 | current_tag = cvmx_pow_get_current_tag(); | 1500 | current_tag = cvmx_pow_get_current_tag(); |
| 1509 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) | 1501 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) |
| 1510 | pr_warning("%s called with NULL_NULL tag\n", | 1502 | pr_warn("%s called with NULL_NULL tag\n", __func__); |
| 1511 | __func__); | ||
| 1512 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) | 1503 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) |
| 1513 | pr_warning("%s called when we already have a " | 1504 | pr_warn("%s called when we already have a NULL tag\n", |
| 1514 | "NULL tag\n", | 1505 | __func__); |
| 1515 | __func__); | ||
| 1516 | } | 1506 | } |
| 1517 | 1507 | ||
| 1518 | tag_req.u64 = 0; | 1508 | tag_req.u64 = 0; |
| @@ -1725,17 +1715,14 @@ static inline void cvmx_pow_tag_sw_desched_nocheck( | |||
| 1725 | __cvmx_pow_warn_if_pending_switch(__func__); | 1715 | __cvmx_pow_warn_if_pending_switch(__func__); |
| 1726 | current_tag = cvmx_pow_get_current_tag(); | 1716 | current_tag = cvmx_pow_get_current_tag(); |
| 1727 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) | 1717 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) |
| 1728 | pr_warning("%s called with NULL_NULL tag\n", | 1718 | pr_warn("%s called with NULL_NULL tag\n", __func__); |
| 1729 | __func__); | ||
| 1730 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) | 1719 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) |
| 1731 | pr_warning("%s called with NULL tag. Deschedule not " | 1720 | pr_warn("%s called with NULL tag. Deschedule not allowed from NULL state\n", |
| 1732 | "allowed from NULL state\n", | 1721 | __func__); |
| 1733 | __func__); | ||
| 1734 | if ((current_tag.s.type != CVMX_POW_TAG_TYPE_ATOMIC) | 1722 | if ((current_tag.s.type != CVMX_POW_TAG_TYPE_ATOMIC) |
| 1735 | && (tag_type != CVMX_POW_TAG_TYPE_ATOMIC)) | 1723 | && (tag_type != CVMX_POW_TAG_TYPE_ATOMIC)) |
| 1736 | pr_warning("%s called where neither the before or " | 1724 | pr_warn("%s called where neither the before or after tag is ATOMIC\n", |
| 1737 | "after tag is ATOMIC\n", | 1725 | __func__); |
| 1738 | __func__); | ||
| 1739 | } | 1726 | } |
| 1740 | 1727 | ||
| 1741 | tag_req.u64 = 0; | 1728 | tag_req.u64 = 0; |
| @@ -1832,12 +1819,10 @@ static inline void cvmx_pow_desched(uint64_t no_sched) | |||
| 1832 | __cvmx_pow_warn_if_pending_switch(__func__); | 1819 | __cvmx_pow_warn_if_pending_switch(__func__); |
| 1833 | current_tag = cvmx_pow_get_current_tag(); | 1820 | current_tag = cvmx_pow_get_current_tag(); |
| 1834 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) | 1821 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) |
| 1835 | pr_warning("%s called with NULL_NULL tag\n", | 1822 | pr_warn("%s called with NULL_NULL tag\n", __func__); |
| 1836 | __func__); | ||
| 1837 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) | 1823 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) |
| 1838 | pr_warning("%s called with NULL tag. Deschedule not " | 1824 | pr_warn("%s called with NULL tag. Deschedule not expected from NULL state\n", |
| 1839 | "expected from NULL state\n", | 1825 | __func__); |
| 1840 | __func__); | ||
| 1841 | } | 1826 | } |
| 1842 | 1827 | ||
| 1843 | /* Need to make sure any writes to the work queue entry are complete */ | 1828 | /* Need to make sure any writes to the work queue entry are complete */ |
diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h index f991e7701d3d..33db1c806b01 100644 --- a/arch/mips/include/asm/octeon/cvmx.h +++ b/arch/mips/include/asm/octeon/cvmx.h | |||
| @@ -451,67 +451,4 @@ static inline uint32_t cvmx_octeon_num_cores(void) | |||
| 451 | return cvmx_pop(ciu_fuse); | 451 | return cvmx_pop(ciu_fuse); |
| 452 | } | 452 | } |
| 453 | 453 | ||
| 454 | /** | ||
| 455 | * Read a byte of fuse data | ||
| 456 | * @byte_addr: address to read | ||
| 457 | * | ||
| 458 | * Returns fuse value: 0 or 1 | ||
| 459 | */ | ||
| 460 | static uint8_t cvmx_fuse_read_byte(int byte_addr) | ||
| 461 | { | ||
| 462 | union cvmx_mio_fus_rcmd read_cmd; | ||
| 463 | |||
| 464 | read_cmd.u64 = 0; | ||
| 465 | read_cmd.s.addr = byte_addr; | ||
| 466 | read_cmd.s.pend = 1; | ||
| 467 | cvmx_write_csr(CVMX_MIO_FUS_RCMD, read_cmd.u64); | ||
| 468 | while ((read_cmd.u64 = cvmx_read_csr(CVMX_MIO_FUS_RCMD)) | ||
| 469 | && read_cmd.s.pend) | ||
| 470 | ; | ||
| 471 | return read_cmd.s.dat; | ||
| 472 | } | ||
| 473 | |||
| 474 | /** | ||
| 475 | * Read a single fuse bit | ||
| 476 | * | ||
| 477 | * @fuse: Fuse number (0-1024) | ||
| 478 | * | ||
| 479 | * Returns fuse value: 0 or 1 | ||
| 480 | */ | ||
| 481 | static inline int cvmx_fuse_read(int fuse) | ||
| 482 | { | ||
| 483 | return (cvmx_fuse_read_byte(fuse >> 3) >> (fuse & 0x7)) & 1; | ||
| 484 | } | ||
| 485 | |||
| 486 | static inline int cvmx_octeon_model_CN36XX(void) | ||
| 487 | { | ||
| 488 | return OCTEON_IS_MODEL(OCTEON_CN38XX) | ||
| 489 | && !cvmx_octeon_is_pass1() | ||
| 490 | && cvmx_fuse_read(264); | ||
| 491 | } | ||
| 492 | |||
| 493 | static inline int cvmx_octeon_zip_present(void) | ||
| 494 | { | ||
| 495 | return octeon_has_feature(OCTEON_FEATURE_ZIP); | ||
| 496 | } | ||
| 497 | |||
| 498 | static inline int cvmx_octeon_dfa_present(void) | ||
| 499 | { | ||
| 500 | if (!OCTEON_IS_MODEL(OCTEON_CN38XX) | ||
| 501 | && !OCTEON_IS_MODEL(OCTEON_CN31XX) | ||
| 502 | && !OCTEON_IS_MODEL(OCTEON_CN58XX)) | ||
| 503 | return 0; | ||
| 504 | else if (OCTEON_IS_MODEL(OCTEON_CN3020)) | ||
| 505 | return 0; | ||
| 506 | else if (cvmx_octeon_is_pass1()) | ||
| 507 | return 1; | ||
| 508 | else | ||
| 509 | return !cvmx_fuse_read(120); | ||
| 510 | } | ||
| 511 | |||
| 512 | static inline int cvmx_octeon_crypto_present(void) | ||
| 513 | { | ||
| 514 | return octeon_has_feature(OCTEON_FEATURE_CRYPTO); | ||
| 515 | } | ||
| 516 | |||
| 517 | #endif /* __CVMX_H__ */ | 454 | #endif /* __CVMX_H__ */ |
diff --git a/arch/mips/include/asm/octeon/octeon-feature.h b/arch/mips/include/asm/octeon/octeon-feature.h index 90e05a8d4b15..c4fe81f47f53 100644 --- a/arch/mips/include/asm/octeon/octeon-feature.h +++ b/arch/mips/include/asm/octeon/octeon-feature.h | |||
| @@ -86,8 +86,6 @@ enum octeon_feature { | |||
| 86 | OCTEON_MAX_FEATURE | 86 | OCTEON_MAX_FEATURE |
| 87 | }; | 87 | }; |
| 88 | 88 | ||
| 89 | static inline int cvmx_fuse_read(int fuse); | ||
| 90 | |||
| 91 | /** | 89 | /** |
| 92 | * Determine if the current Octeon supports a specific feature. These | 90 | * Determine if the current Octeon supports a specific feature. These |
| 93 | * checks have been optimized to be fairly quick, but they should still | 91 | * checks have been optimized to be fairly quick, but they should still |
| @@ -105,33 +103,6 @@ static inline int octeon_has_feature(enum octeon_feature feature) | |||
| 105 | case OCTEON_FEATURE_SAAD: | 103 | case OCTEON_FEATURE_SAAD: |
| 106 | return !OCTEON_IS_MODEL(OCTEON_CN3XXX); | 104 | return !OCTEON_IS_MODEL(OCTEON_CN3XXX); |
| 107 | 105 | ||
| 108 | case OCTEON_FEATURE_ZIP: | ||
| 109 | if (OCTEON_IS_MODEL(OCTEON_CN30XX) | ||
| 110 | || OCTEON_IS_MODEL(OCTEON_CN50XX) | ||
| 111 | || OCTEON_IS_MODEL(OCTEON_CN52XX)) | ||
| 112 | return 0; | ||
| 113 | else if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1)) | ||
| 114 | return 1; | ||
| 115 | else | ||
| 116 | return !cvmx_fuse_read(121); | ||
| 117 | |||
| 118 | case OCTEON_FEATURE_CRYPTO: | ||
| 119 | if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) { | ||
| 120 | union cvmx_mio_fus_dat2 fus_2; | ||
| 121 | fus_2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2); | ||
| 122 | if (fus_2.s.nocrypto || fus_2.s.nomul) { | ||
| 123 | return 0; | ||
| 124 | } else if (!fus_2.s.dorm_crypto) { | ||
| 125 | return 1; | ||
| 126 | } else { | ||
| 127 | union cvmx_rnm_ctl_status st; | ||
| 128 | st.u64 = cvmx_read_csr(CVMX_RNM_CTL_STATUS); | ||
| 129 | return st.s.eer_val; | ||
| 130 | } | ||
| 131 | } else { | ||
| 132 | return !cvmx_fuse_read(90); | ||
| 133 | } | ||
| 134 | |||
| 135 | case OCTEON_FEATURE_DORM_CRYPTO: | 106 | case OCTEON_FEATURE_DORM_CRYPTO: |
| 136 | if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) { | 107 | if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) { |
| 137 | union cvmx_mio_fus_dat2 fus_2; | 108 | union cvmx_mio_fus_dat2 fus_2; |
| @@ -188,29 +159,6 @@ static inline int octeon_has_feature(enum octeon_feature feature) | |||
| 188 | && !OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X) | 159 | && !OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X) |
| 189 | && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X); | 160 | && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X); |
| 190 | 161 | ||
| 191 | case OCTEON_FEATURE_DFA: | ||
| 192 | if (!OCTEON_IS_MODEL(OCTEON_CN38XX) | ||
| 193 | && !OCTEON_IS_MODEL(OCTEON_CN31XX) | ||
| 194 | && !OCTEON_IS_MODEL(OCTEON_CN58XX)) | ||
| 195 | return 0; | ||
| 196 | else if (OCTEON_IS_MODEL(OCTEON_CN3020)) | ||
| 197 | return 0; | ||
| 198 | else | ||
| 199 | return !cvmx_fuse_read(120); | ||
| 200 | |||
| 201 | case OCTEON_FEATURE_HFA: | ||
| 202 | if (!OCTEON_IS_MODEL(OCTEON_CN6XXX)) | ||
| 203 | return 0; | ||
| 204 | else | ||
| 205 | return !cvmx_fuse_read(90); | ||
| 206 | |||
| 207 | case OCTEON_FEATURE_DFM: | ||
| 208 | if (!(OCTEON_IS_MODEL(OCTEON_CN63XX) | ||
| 209 | || OCTEON_IS_MODEL(OCTEON_CN66XX))) | ||
| 210 | return 0; | ||
| 211 | else | ||
| 212 | return !cvmx_fuse_read(90); | ||
| 213 | |||
| 214 | case OCTEON_FEATURE_MDIO_CLAUSE_45: | 162 | case OCTEON_FEATURE_MDIO_CLAUSE_45: |
| 215 | return !(OCTEON_IS_MODEL(OCTEON_CN3XXX) | 163 | return !(OCTEON_IS_MODEL(OCTEON_CN3XXX) |
| 216 | || OCTEON_IS_MODEL(OCTEON_CN58XX) | 164 | || OCTEON_IS_MODEL(OCTEON_CN58XX) |
diff --git a/arch/mips/include/asm/octeon/octeon-model.h b/arch/mips/include/asm/octeon/octeon-model.h index e2c122c6a657..e8a1c2fd52cd 100644 --- a/arch/mips/include/asm/octeon/octeon-model.h +++ b/arch/mips/include/asm/octeon/octeon-model.h | |||
| @@ -326,8 +326,7 @@ static inline int __octeon_is_model_runtime__(uint32_t model) | |||
| 326 | #define OCTEON_IS_COMMON_BINARY() 1 | 326 | #define OCTEON_IS_COMMON_BINARY() 1 |
| 327 | #undef OCTEON_MODEL | 327 | #undef OCTEON_MODEL |
| 328 | 328 | ||
| 329 | const char *octeon_model_get_string(uint32_t chip_id); | 329 | const char *__init octeon_model_get_string(uint32_t chip_id); |
| 330 | const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer); | ||
| 331 | 330 | ||
| 332 | /* | 331 | /* |
| 333 | * Return the octeon family, i.e., ProcessorID of the PrID register. | 332 | * Return the octeon family, i.e., ProcessorID of the PrID register. |
diff --git a/arch/mips/include/asm/paccess.h b/arch/mips/include/asm/paccess.h index 2474fc5d1751..af81ab0da55f 100644 --- a/arch/mips/include/asm/paccess.h +++ b/arch/mips/include/asm/paccess.h | |||
| @@ -56,6 +56,7 @@ struct __large_pstruct { unsigned long buf[100]; }; | |||
| 56 | "1:\t" insn "\t%1,%2\n\t" \ | 56 | "1:\t" insn "\t%1,%2\n\t" \ |
| 57 | "move\t%0,$0\n" \ | 57 | "move\t%0,$0\n" \ |
| 58 | "2:\n\t" \ | 58 | "2:\n\t" \ |
| 59 | ".insn\n\t" \ | ||
| 59 | ".section\t.fixup,\"ax\"\n" \ | 60 | ".section\t.fixup,\"ax\"\n" \ |
| 60 | "3:\tli\t%0,%3\n\t" \ | 61 | "3:\tli\t%0,%3\n\t" \ |
| 61 | "move\t%1,$0\n\t" \ | 62 | "move\t%1,$0\n\t" \ |
| @@ -94,6 +95,7 @@ extern void __get_dbe_unknown(void); | |||
| 94 | "1:\t" insn "\t%1,%2\n\t" \ | 95 | "1:\t" insn "\t%1,%2\n\t" \ |
| 95 | "move\t%0,$0\n" \ | 96 | "move\t%0,$0\n" \ |
| 96 | "2:\n\t" \ | 97 | "2:\n\t" \ |
| 98 | ".insn\n\t" \ | ||
| 97 | ".section\t.fixup,\"ax\"\n" \ | 99 | ".section\t.fixup,\"ax\"\n" \ |
| 98 | "3:\tli\t%0,%3\n\t" \ | 100 | "3:\tli\t%0,%3\n\t" \ |
| 99 | "j\t2b\n\t" \ | 101 | "j\t2b\n\t" \ |
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h index 3be81803595d..154b70a10483 100644 --- a/arch/mips/include/asm/page.h +++ b/arch/mips/include/asm/page.h | |||
| @@ -116,7 +116,7 @@ extern void copy_user_highpage(struct page *to, struct page *from, | |||
| 116 | /* | 116 | /* |
| 117 | * These are used to make use of C type-checking.. | 117 | * These are used to make use of C type-checking.. |
| 118 | */ | 118 | */ |
| 119 | #ifdef CONFIG_64BIT_PHYS_ADDR | 119 | #ifdef CONFIG_PHYS_ADDR_T_64BIT |
| 120 | #ifdef CONFIG_CPU_MIPS32 | 120 | #ifdef CONFIG_CPU_MIPS32 |
| 121 | typedef struct { unsigned long pte_low, pte_high; } pte_t; | 121 | typedef struct { unsigned long pte_low, pte_high; } pte_t; |
| 122 | #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) | 122 | #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) |
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index 974b0e308963..69529624a005 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h | |||
| @@ -84,7 +84,7 @@ static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, | |||
| 84 | const struct resource *rsrc, resource_size_t *start, | 84 | const struct resource *rsrc, resource_size_t *start, |
| 85 | resource_size_t *end) | 85 | resource_size_t *end) |
| 86 | { | 86 | { |
| 87 | phys_t size = resource_size(rsrc); | 87 | phys_addr_t size = resource_size(rsrc); |
| 88 | 88 | ||
| 89 | *start = fixup_bigphys_addr(rsrc->start, size); | 89 | *start = fixup_bigphys_addr(rsrc->start, size); |
| 90 | *end = rsrc->start + size; | 90 | *end = rsrc->start + size; |
diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h index cd7d6064bcbe..68984b612f9d 100644 --- a/arch/mips/include/asm/pgtable-32.h +++ b/arch/mips/include/asm/pgtable-32.h | |||
| @@ -69,7 +69,7 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
| 69 | # define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE) | 69 | # define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE) |
| 70 | #endif | 70 | #endif |
| 71 | 71 | ||
| 72 | #ifdef CONFIG_64BIT_PHYS_ADDR | 72 | #ifdef CONFIG_PHYS_ADDR_T_64BIT |
| 73 | #define pte_ERROR(e) \ | 73 | #define pte_ERROR(e) \ |
| 74 | printk("%s:%d: bad pte %016Lx.\n", __FILE__, __LINE__, pte_val(e)) | 74 | printk("%s:%d: bad pte %016Lx.\n", __FILE__, __LINE__, pte_val(e)) |
| 75 | #else | 75 | #else |
| @@ -103,7 +103,7 @@ static inline void pmd_clear(pmd_t *pmdp) | |||
| 103 | pmd_val(*pmdp) = ((unsigned long) invalid_pte_table); | 103 | pmd_val(*pmdp) = ((unsigned long) invalid_pte_table); |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 106 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
| 107 | #define pte_page(x) pfn_to_page(pte_pfn(x)) | 107 | #define pte_page(x) pfn_to_page(pte_pfn(x)) |
| 108 | #define pte_pfn(x) ((unsigned long)((x).pte_high >> 6)) | 108 | #define pte_pfn(x) ((unsigned long)((x).pte_high >> 6)) |
| 109 | static inline pte_t | 109 | static inline pte_t |
| @@ -126,7 +126,7 @@ pfn_pte(unsigned long pfn, pgprot_t prot) | |||
| 126 | #define pte_pfn(x) ((unsigned long)((x).pte >> _PFN_SHIFT)) | 126 | #define pte_pfn(x) ((unsigned long)((x).pte >> _PFN_SHIFT)) |
| 127 | #define pfn_pte(pfn, prot) __pte(((unsigned long long)(pfn) << _PFN_SHIFT) | pgprot_val(prot)) | 127 | #define pfn_pte(pfn, prot) __pte(((unsigned long long)(pfn) << _PFN_SHIFT) | pgprot_val(prot)) |
| 128 | #endif | 128 | #endif |
| 129 | #endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */ | 129 | #endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */ |
| 130 | 130 | ||
| 131 | #define __pgd_offset(address) pgd_index(address) | 131 | #define __pgd_offset(address) pgd_index(address) |
| 132 | #define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) | 132 | #define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) |
| @@ -155,73 +155,75 @@ pfn_pte(unsigned long pfn, pgprot_t prot) | |||
| 155 | #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) | 155 | #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) |
| 156 | 156 | ||
| 157 | /* Swap entries must have VALID bit cleared. */ | 157 | /* Swap entries must have VALID bit cleared. */ |
| 158 | #define __swp_type(x) (((x).val >> 10) & 0x1f) | 158 | #define __swp_type(x) (((x).val >> 10) & 0x1f) |
| 159 | #define __swp_offset(x) ((x).val >> 15) | 159 | #define __swp_offset(x) ((x).val >> 15) |
| 160 | #define __swp_entry(type,offset) \ | 160 | #define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 10) | ((offset) << 15) }) |
| 161 | ((swp_entry_t) { ((type) << 10) | ((offset) << 15) }) | 161 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) |
| 162 | #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) | ||
| 162 | 163 | ||
| 163 | /* | 164 | /* |
| 164 | * Bits 0, 4, 8, and 9 are taken, split up 28 bits of offset into this range: | 165 | * Encode and decode a nonlinear file mapping entry |
| 165 | */ | 166 | */ |
| 166 | #define PTE_FILE_MAX_BITS 28 | 167 | #define pte_to_pgoff(_pte) ((((_pte).pte >> 1 ) & 0x07) | \ |
| 167 | 168 | (((_pte).pte >> 2 ) & 0x38) | \ | |
| 168 | #define pte_to_pgoff(_pte) ((((_pte).pte >> 1 ) & 0x07) | \ | 169 | (((_pte).pte >> 10) << 6 )) |
| 169 | (((_pte).pte >> 2 ) & 0x38) | \ | ||
| 170 | (((_pte).pte >> 10) << 6 )) | ||
| 171 | 170 | ||
| 172 | #define pgoff_to_pte(off) ((pte_t) { (((off) & 0x07) << 1 ) | \ | 171 | #define pgoff_to_pte(off) ((pte_t) { (((off) & 0x07) << 1 ) | \ |
| 173 | (((off) & 0x38) << 2 ) | \ | 172 | (((off) & 0x38) << 2 ) | \ |
| 174 | (((off) >> 6 ) << 10) | \ | 173 | (((off) >> 6 ) << 10) | \ |
| 175 | _PAGE_FILE }) | 174 | _PAGE_FILE }) |
| 176 | 175 | ||
| 176 | /* | ||
| 177 | * Bits 0, 4, 8, and 9 are taken, split up 28 bits of offset into this range: | ||
| 178 | */ | ||
| 179 | #define PTE_FILE_MAX_BITS 28 | ||
| 177 | #else | 180 | #else |
| 178 | 181 | ||
| 182 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) | ||
| 183 | |||
| 179 | /* Swap entries must have VALID and GLOBAL bits cleared. */ | 184 | /* Swap entries must have VALID and GLOBAL bits cleared. */ |
| 180 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 185 | #define __swp_type(x) (((x).val >> 2) & 0x1f) |
| 181 | #define __swp_type(x) (((x).val >> 2) & 0x1f) | 186 | #define __swp_offset(x) ((x).val >> 7) |
| 182 | #define __swp_offset(x) ((x).val >> 7) | 187 | #define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 7) }) |
| 183 | #define __swp_entry(type,offset) \ | 188 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high }) |
| 184 | ((swp_entry_t) { ((type) << 2) | ((offset) << 7) }) | 189 | #define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val }) |
| 185 | #else | ||
| 186 | #define __swp_type(x) (((x).val >> 8) & 0x1f) | ||
| 187 | #define __swp_offset(x) ((x).val >> 13) | ||
| 188 | #define __swp_entry(type,offset) \ | ||
| 189 | ((swp_entry_t) { ((type) << 8) | ((offset) << 13) }) | ||
| 190 | #endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */ | ||
| 191 | 190 | ||
| 192 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | ||
| 193 | /* | 191 | /* |
| 194 | * Bits 0 and 1 of pte_high are taken, use the rest for the page offset... | 192 | * Bits 0 and 1 of pte_high are taken, use the rest for the page offset... |
| 195 | */ | 193 | */ |
| 196 | #define PTE_FILE_MAX_BITS 30 | 194 | #define pte_to_pgoff(_pte) ((_pte).pte_high >> 2) |
| 197 | 195 | #define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) << 2 }) | |
| 198 | #define pte_to_pgoff(_pte) ((_pte).pte_high >> 2) | ||
| 199 | #define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) << 2 }) | ||
| 200 | 196 | ||
| 197 | #define PTE_FILE_MAX_BITS 30 | ||
| 201 | #else | 198 | #else |
| 202 | /* | 199 | /* |
| 203 | * Bits 0, 4, 6, and 7 are taken, split up 28 bits of offset into this range: | 200 | * Constraints: |
| 201 | * _PAGE_PRESENT at bit 0 | ||
| 202 | * _PAGE_MODIFIED at bit 4 | ||
| 203 | * _PAGE_GLOBAL at bit 6 | ||
| 204 | * _PAGE_VALID at bit 7 | ||
| 204 | */ | 205 | */ |
| 205 | #define PTE_FILE_MAX_BITS 28 | 206 | #define __swp_type(x) (((x).val >> 8) & 0x1f) |
| 207 | #define __swp_offset(x) ((x).val >> 13) | ||
| 208 | #define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 8) | ((offset) << 13) }) | ||
| 209 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) | ||
| 210 | #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) | ||
| 206 | 211 | ||
| 207 | #define pte_to_pgoff(_pte) ((((_pte).pte >> 1) & 0x7) | \ | 212 | /* |
| 208 | (((_pte).pte >> 2) & 0x8) | \ | 213 | * Encode and decode a nonlinear file mapping entry |
| 209 | (((_pte).pte >> 8) << 4)) | 214 | */ |
| 215 | #define pte_to_pgoff(_pte) ((((_pte).pte >> 1) & 0x7) | \ | ||
| 216 | (((_pte).pte >> 2) & 0x8) | \ | ||
| 217 | (((_pte).pte >> 8) << 4)) | ||
| 210 | 218 | ||
| 211 | #define pgoff_to_pte(off) ((pte_t) { (((off) & 0x7) << 1) | \ | 219 | #define pgoff_to_pte(off) ((pte_t) { (((off) & 0x7) << 1) | \ |
| 212 | (((off) & 0x8) << 2) | \ | 220 | (((off) & 0x8) << 2) | \ |
| 213 | (((off) >> 4) << 8) | \ | 221 | (((off) >> 4) << 8) | \ |
| 214 | _PAGE_FILE }) | 222 | _PAGE_FILE }) |
| 215 | #endif | ||
| 216 | 223 | ||
| 217 | #endif | 224 | #define PTE_FILE_MAX_BITS 28 |
| 225 | #endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */ | ||
| 218 | 226 | ||
| 219 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 227 | #endif /* defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) */ |
| 220 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high }) | ||
| 221 | #define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val }) | ||
| 222 | #else | ||
| 223 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) | ||
| 224 | #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) | ||
| 225 | #endif | ||
| 226 | 228 | ||
| 227 | #endif /* _ASM_PGTABLE_32_H */ | 229 | #endif /* _ASM_PGTABLE_32_H */ |
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h index e747bfa0be7e..ca11f14f40a3 100644 --- a/arch/mips/include/asm/pgtable-bits.h +++ b/arch/mips/include/asm/pgtable-bits.h | |||
| @@ -32,39 +32,41 @@ | |||
| 32 | * unpredictable things. The code (when it is written) to deal with | 32 | * unpredictable things. The code (when it is written) to deal with |
| 33 | * this problem will be in the update_mmu_cache() code for the r4k. | 33 | * this problem will be in the update_mmu_cache() code for the r4k. |
| 34 | */ | 34 | */ |
| 35 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 35 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
| 36 | 36 | ||
| 37 | /* | 37 | /* |
| 38 | * The following bits are directly used by the TLB hardware | 38 | * The following bits are directly used by the TLB hardware |
| 39 | */ | 39 | */ |
| 40 | #define _PAGE_R4KBUG (1 << 0) /* workaround for r4k bug */ | 40 | #define _PAGE_GLOBAL_SHIFT 0 |
| 41 | #define _PAGE_GLOBAL (1 << 0) | 41 | #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) |
| 42 | #define _PAGE_VALID_SHIFT 1 | 42 | #define _PAGE_VALID_SHIFT (_PAGE_GLOBAL_SHIFT + 1) |
| 43 | #define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) | 43 | #define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) |
| 44 | #define _PAGE_SILENT_READ (1 << 1) /* synonym */ | 44 | #define _PAGE_DIRTY_SHIFT (_PAGE_VALID_SHIFT + 1) |
| 45 | #define _PAGE_DIRTY_SHIFT 2 | 45 | #define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT) |
| 46 | #define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT) /* The MIPS dirty bit */ | 46 | #define _CACHE_SHIFT (_PAGE_DIRTY_SHIFT + 1) |
| 47 | #define _PAGE_SILENT_WRITE (1 << 2) | 47 | #define _CACHE_MASK (7 << _CACHE_SHIFT) |
| 48 | #define _CACHE_SHIFT 3 | ||
| 49 | #define _CACHE_MASK (7 << 3) | ||
| 50 | 48 | ||
| 51 | /* | 49 | /* |
| 52 | * The following bits are implemented in software | 50 | * The following bits are implemented in software |
| 53 | * | 51 | * |
| 54 | * _PAGE_FILE semantics: set:pagecache unset:swap | 52 | * _PAGE_FILE semantics: set:pagecache unset:swap |
| 55 | */ | 53 | */ |
| 56 | #define _PAGE_PRESENT_SHIFT 6 | 54 | #define _PAGE_PRESENT_SHIFT (_CACHE_SHIFT + 3) |
| 57 | #define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) | 55 | #define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) |
| 58 | #define _PAGE_READ_SHIFT 7 | 56 | #define _PAGE_READ_SHIFT (_PAGE_PRESENT_SHIFT + 1) |
| 59 | #define _PAGE_READ (1 << _PAGE_READ_SHIFT) | 57 | #define _PAGE_READ (1 << _PAGE_READ_SHIFT) |
| 60 | #define _PAGE_WRITE_SHIFT 8 | 58 | #define _PAGE_WRITE_SHIFT (_PAGE_READ_SHIFT + 1) |
| 61 | #define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) | 59 | #define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) |
| 62 | #define _PAGE_ACCESSED_SHIFT 9 | 60 | #define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1) |
| 63 | #define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) | 61 | #define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) |
| 64 | #define _PAGE_MODIFIED_SHIFT 10 | 62 | #define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1) |
| 65 | #define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) | 63 | #define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) |
| 66 | 64 | ||
| 67 | #define _PAGE_FILE (1 << 10) | 65 | #define _PAGE_SILENT_READ _PAGE_VALID |
| 66 | #define _PAGE_SILENT_WRITE _PAGE_DIRTY | ||
| 67 | #define _PAGE_FILE _PAGE_MODIFIED | ||
| 68 | |||
| 69 | #define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3) | ||
| 68 | 70 | ||
| 69 | #elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) | 71 | #elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) |
| 70 | 72 | ||
| @@ -172,7 +174,7 @@ | |||
| 172 | 174 | ||
| 173 | #define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3) | 175 | #define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3) |
| 174 | 176 | ||
| 175 | #endif /* defined(CONFIG_64BIT_PHYS_ADDR && defined(CONFIG_CPU_MIPS32) */ | 177 | #endif /* defined(CONFIG_PHYS_ADDR_T_64BIT && defined(CONFIG_CPU_MIPS32) */ |
| 176 | 178 | ||
| 177 | #ifndef _PFN_SHIFT | 179 | #ifndef _PFN_SHIFT |
| 178 | #define _PFN_SHIFT PAGE_SHIFT | 180 | #define _PFN_SHIFT PAGE_SHIFT |
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index d6d1928539b1..62a6ba383d4f 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h | |||
| @@ -125,7 +125,7 @@ do { \ | |||
| 125 | extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, | 125 | extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, |
| 126 | pte_t pteval); | 126 | pte_t pteval); |
| 127 | 127 | ||
| 128 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 128 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
| 129 | 129 | ||
| 130 | #define pte_none(pte) (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL)) | 130 | #define pte_none(pte) (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL)) |
| 131 | #define pte_present(pte) ((pte).pte_low & _PAGE_PRESENT) | 131 | #define pte_present(pte) ((pte).pte_low & _PAGE_PRESENT) |
| @@ -227,7 +227,7 @@ extern pgd_t swapper_pg_dir[]; | |||
| 227 | * The following only work if pte_present() is true. | 227 | * The following only work if pte_present() is true. |
| 228 | * Undefined behaviour if not.. | 228 | * Undefined behaviour if not.. |
| 229 | */ | 229 | */ |
| 230 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 230 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
| 231 | static inline int pte_write(pte_t pte) { return pte.pte_low & _PAGE_WRITE; } | 231 | static inline int pte_write(pte_t pte) { return pte.pte_low & _PAGE_WRITE; } |
| 232 | static inline int pte_dirty(pte_t pte) { return pte.pte_low & _PAGE_MODIFIED; } | 232 | static inline int pte_dirty(pte_t pte) { return pte.pte_low & _PAGE_MODIFIED; } |
| 233 | static inline int pte_young(pte_t pte) { return pte.pte_low & _PAGE_ACCESSED; } | 233 | static inline int pte_young(pte_t pte) { return pte.pte_low & _PAGE_ACCESSED; } |
| @@ -297,13 +297,13 @@ static inline pte_t pte_wrprotect(pte_t pte) | |||
| 297 | 297 | ||
| 298 | static inline pte_t pte_mkclean(pte_t pte) | 298 | static inline pte_t pte_mkclean(pte_t pte) |
| 299 | { | 299 | { |
| 300 | pte_val(pte) &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE); | 300 | pte_val(pte) &= ~(_PAGE_MODIFIED | _PAGE_SILENT_WRITE); |
| 301 | return pte; | 301 | return pte; |
| 302 | } | 302 | } |
| 303 | 303 | ||
| 304 | static inline pte_t pte_mkold(pte_t pte) | 304 | static inline pte_t pte_mkold(pte_t pte) |
| 305 | { | 305 | { |
| 306 | pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ); | 306 | pte_val(pte) &= ~(_PAGE_ACCESSED | _PAGE_SILENT_READ); |
| 307 | return pte; | 307 | return pte; |
| 308 | } | 308 | } |
| 309 | 309 | ||
| @@ -382,13 +382,13 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot) | |||
| 382 | */ | 382 | */ |
| 383 | #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) | 383 | #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) |
| 384 | 384 | ||
| 385 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 385 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
| 386 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | 386 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) |
| 387 | { | 387 | { |
| 388 | pte.pte_low &= _PAGE_CHG_MASK; | 388 | pte.pte_low &= _PAGE_CHG_MASK; |
| 389 | pte.pte_high &= ~0x3f; | 389 | pte.pte_high &= (_PFN_MASK | _CACHE_MASK); |
| 390 | pte.pte_low |= pgprot_val(newprot); | 390 | pte.pte_low |= pgprot_val(newprot); |
| 391 | pte.pte_high |= pgprot_val(newprot) & 0x3f; | 391 | pte.pte_high |= pgprot_val(newprot) & ~(_PFN_MASK | _CACHE_MASK); |
| 392 | return pte; | 392 | return pte; |
| 393 | } | 393 | } |
| 394 | #else | 394 | #else |
| @@ -419,7 +419,7 @@ static inline void update_mmu_cache_pmd(struct vm_area_struct *vma, | |||
| 419 | 419 | ||
| 420 | #define kern_addr_valid(addr) (1) | 420 | #define kern_addr_valid(addr) (1) |
| 421 | 421 | ||
| 422 | #ifdef CONFIG_64BIT_PHYS_ADDR | 422 | #ifdef CONFIG_PHYS_ADDR_T_64BIT |
| 423 | extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot); | 423 | extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot); |
| 424 | 424 | ||
| 425 | static inline int io_remap_pfn_range(struct vm_area_struct *vma, | 425 | static inline int io_remap_pfn_range(struct vm_area_struct *vma, |
| @@ -428,7 +428,7 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma, | |||
| 428 | unsigned long size, | 428 | unsigned long size, |
| 429 | pgprot_t prot) | 429 | pgprot_t prot) |
| 430 | { | 430 | { |
| 431 | phys_t phys_addr_high = fixup_bigphys_addr(pfn << PAGE_SHIFT, size); | 431 | phys_addr_t phys_addr_high = fixup_bigphys_addr(pfn << PAGE_SHIFT, size); |
| 432 | return remap_pfn_range(vma, vaddr, phys_addr_high >> PAGE_SHIFT, size, prot); | 432 | return remap_pfn_range(vma, vaddr, phys_addr_high >> PAGE_SHIFT, size, prot); |
| 433 | } | 433 | } |
| 434 | #define io_remap_pfn_range io_remap_pfn_range | 434 | #define io_remap_pfn_range io_remap_pfn_range |
diff --git a/arch/mips/include/asm/prom.h b/arch/mips/include/asm/prom.h index a9494c0141fb..eaa26270a5e5 100644 --- a/arch/mips/include/asm/prom.h +++ b/arch/mips/include/asm/prom.h | |||
| @@ -22,6 +22,7 @@ extern void device_tree_init(void); | |||
| 22 | struct boot_param_header; | 22 | struct boot_param_header; |
| 23 | 23 | ||
| 24 | extern void __dt_setup_arch(void *bph); | 24 | extern void __dt_setup_arch(void *bph); |
| 25 | extern int __dt_register_buses(const char *bus0, const char *bus1); | ||
| 25 | 26 | ||
| 26 | #define dt_setup_arch(sym) \ | 27 | #define dt_setup_arch(sym) \ |
| 27 | ({ \ | 28 | ({ \ |
diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h index cd6e0afc6833..e293a8d89a6d 100644 --- a/arch/mips/include/asm/r4kcache.h +++ b/arch/mips/include/asm/r4kcache.h | |||
| @@ -47,79 +47,20 @@ extern void (*r4k_blast_icache)(void); | |||
| 47 | 47 | ||
| 48 | #ifdef CONFIG_MIPS_MT | 48 | #ifdef CONFIG_MIPS_MT |
| 49 | 49 | ||
| 50 | /* | ||
| 51 | * Optionally force single-threaded execution during I-cache flushes. | ||
| 52 | */ | ||
| 53 | #define PROTECT_CACHE_FLUSHES 1 | ||
| 54 | |||
| 55 | #ifdef PROTECT_CACHE_FLUSHES | ||
| 56 | |||
| 57 | extern int mt_protiflush; | ||
| 58 | extern int mt_protdflush; | ||
| 59 | extern void mt_cflush_lockdown(void); | ||
| 60 | extern void mt_cflush_release(void); | ||
| 61 | |||
| 62 | #define BEGIN_MT_IPROT \ | ||
| 63 | unsigned long flags = 0; \ | ||
| 64 | unsigned long mtflags = 0; \ | ||
| 65 | if(mt_protiflush) { \ | ||
| 66 | local_irq_save(flags); \ | ||
| 67 | ehb(); \ | ||
| 68 | mtflags = dvpe(); \ | ||
| 69 | mt_cflush_lockdown(); \ | ||
| 70 | } | ||
| 71 | |||
| 72 | #define END_MT_IPROT \ | ||
| 73 | if(mt_protiflush) { \ | ||
| 74 | mt_cflush_release(); \ | ||
| 75 | evpe(mtflags); \ | ||
| 76 | local_irq_restore(flags); \ | ||
| 77 | } | ||
| 78 | |||
| 79 | #define BEGIN_MT_DPROT \ | ||
| 80 | unsigned long flags = 0; \ | ||
| 81 | unsigned long mtflags = 0; \ | ||
| 82 | if(mt_protdflush) { \ | ||
| 83 | local_irq_save(flags); \ | ||
| 84 | ehb(); \ | ||
| 85 | mtflags = dvpe(); \ | ||
| 86 | mt_cflush_lockdown(); \ | ||
| 87 | } | ||
| 88 | |||
| 89 | #define END_MT_DPROT \ | ||
| 90 | if(mt_protdflush) { \ | ||
| 91 | mt_cflush_release(); \ | ||
| 92 | evpe(mtflags); \ | ||
| 93 | local_irq_restore(flags); \ | ||
| 94 | } | ||
| 95 | |||
| 96 | #else | ||
| 97 | |||
| 98 | #define BEGIN_MT_IPROT | ||
| 99 | #define BEGIN_MT_DPROT | ||
| 100 | #define END_MT_IPROT | ||
| 101 | #define END_MT_DPROT | ||
| 102 | |||
| 103 | #endif /* PROTECT_CACHE_FLUSHES */ | ||
| 104 | |||
| 105 | #define __iflush_prologue \ | 50 | #define __iflush_prologue \ |
| 106 | unsigned long redundance; \ | 51 | unsigned long redundance; \ |
| 107 | extern int mt_n_iflushes; \ | 52 | extern int mt_n_iflushes; \ |
| 108 | BEGIN_MT_IPROT \ | ||
| 109 | for (redundance = 0; redundance < mt_n_iflushes; redundance++) { | 53 | for (redundance = 0; redundance < mt_n_iflushes; redundance++) { |
| 110 | 54 | ||
| 111 | #define __iflush_epilogue \ | 55 | #define __iflush_epilogue \ |
| 112 | END_MT_IPROT \ | ||
| 113 | } | 56 | } |
| 114 | 57 | ||
| 115 | #define __dflush_prologue \ | 58 | #define __dflush_prologue \ |
| 116 | unsigned long redundance; \ | 59 | unsigned long redundance; \ |
| 117 | extern int mt_n_dflushes; \ | 60 | extern int mt_n_dflushes; \ |
| 118 | BEGIN_MT_DPROT \ | ||
| 119 | for (redundance = 0; redundance < mt_n_dflushes; redundance++) { | 61 | for (redundance = 0; redundance < mt_n_dflushes; redundance++) { |
| 120 | 62 | ||
| 121 | #define __dflush_epilogue \ | 63 | #define __dflush_epilogue \ |
| 122 | END_MT_DPROT \ | ||
| 123 | } | 64 | } |
| 124 | 65 | ||
| 125 | #define __inv_dflush_prologue __dflush_prologue | 66 | #define __inv_dflush_prologue __dflush_prologue |
diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h index 78d201fb6c87..c6d06d383ef9 100644 --- a/arch/mips/include/asm/spinlock.h +++ b/arch/mips/include/asm/spinlock.h | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/compiler.h> | 12 | #include <linux/compiler.h> |
| 13 | 13 | ||
| 14 | #include <asm/barrier.h> | 14 | #include <asm/barrier.h> |
| 15 | #include <asm/compiler.h> | ||
| 15 | #include <asm/war.h> | 16 | #include <asm/war.h> |
| 16 | 17 | ||
| 17 | /* | 18 | /* |
| @@ -88,7 +89,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) | |||
| 88 | " subu %[ticket], %[ticket], 1 \n" | 89 | " subu %[ticket], %[ticket], 1 \n" |
| 89 | " .previous \n" | 90 | " .previous \n" |
| 90 | " .set pop \n" | 91 | " .set pop \n" |
| 91 | : [ticket_ptr] "+m" (lock->lock), | 92 | : [ticket_ptr] "+" GCC_OFF12_ASM() (lock->lock), |
| 92 | [serving_now_ptr] "+m" (lock->h.serving_now), | 93 | [serving_now_ptr] "+m" (lock->h.serving_now), |
| 93 | [ticket] "=&r" (tmp), | 94 | [ticket] "=&r" (tmp), |
| 94 | [my_ticket] "=&r" (my_ticket) | 95 | [my_ticket] "=&r" (my_ticket) |
| @@ -121,7 +122,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) | |||
| 121 | " subu %[ticket], %[ticket], 1 \n" | 122 | " subu %[ticket], %[ticket], 1 \n" |
| 122 | " .previous \n" | 123 | " .previous \n" |
| 123 | " .set pop \n" | 124 | " .set pop \n" |
| 124 | : [ticket_ptr] "+m" (lock->lock), | 125 | : [ticket_ptr] "+" GCC_OFF12_ASM() (lock->lock), |
| 125 | [serving_now_ptr] "+m" (lock->h.serving_now), | 126 | [serving_now_ptr] "+m" (lock->h.serving_now), |
| 126 | [ticket] "=&r" (tmp), | 127 | [ticket] "=&r" (tmp), |
| 127 | [my_ticket] "=&r" (my_ticket) | 128 | [my_ticket] "=&r" (my_ticket) |
| @@ -163,7 +164,7 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) | |||
| 163 | " li %[ticket], 0 \n" | 164 | " li %[ticket], 0 \n" |
| 164 | " .previous \n" | 165 | " .previous \n" |
| 165 | " .set pop \n" | 166 | " .set pop \n" |
| 166 | : [ticket_ptr] "+m" (lock->lock), | 167 | : [ticket_ptr] "+" GCC_OFF12_ASM() (lock->lock), |
| 167 | [ticket] "=&r" (tmp), | 168 | [ticket] "=&r" (tmp), |
| 168 | [my_ticket] "=&r" (tmp2), | 169 | [my_ticket] "=&r" (tmp2), |
| 169 | [now_serving] "=&r" (tmp3) | 170 | [now_serving] "=&r" (tmp3) |
| @@ -187,7 +188,7 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) | |||
| 187 | " li %[ticket], 0 \n" | 188 | " li %[ticket], 0 \n" |
| 188 | " .previous \n" | 189 | " .previous \n" |
| 189 | " .set pop \n" | 190 | " .set pop \n" |
| 190 | : [ticket_ptr] "+m" (lock->lock), | 191 | : [ticket_ptr] "+" GCC_OFF12_ASM() (lock->lock), |
| 191 | [ticket] "=&r" (tmp), | 192 | [ticket] "=&r" (tmp), |
| 192 | [my_ticket] "=&r" (tmp2), | 193 | [my_ticket] "=&r" (tmp2), |
| 193 | [now_serving] "=&r" (tmp3) | 194 | [now_serving] "=&r" (tmp3) |
| @@ -234,8 +235,8 @@ static inline void arch_read_lock(arch_rwlock_t *rw) | |||
| 234 | " beqzl %1, 1b \n" | 235 | " beqzl %1, 1b \n" |
| 235 | " nop \n" | 236 | " nop \n" |
| 236 | " .set reorder \n" | 237 | " .set reorder \n" |
| 237 | : "=m" (rw->lock), "=&r" (tmp) | 238 | : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp) |
| 238 | : "m" (rw->lock) | 239 | : GCC_OFF12_ASM() (rw->lock) |
| 239 | : "memory"); | 240 | : "memory"); |
| 240 | } else { | 241 | } else { |
| 241 | do { | 242 | do { |
| @@ -244,8 +245,8 @@ static inline void arch_read_lock(arch_rwlock_t *rw) | |||
| 244 | " bltz %1, 1b \n" | 245 | " bltz %1, 1b \n" |
| 245 | " addu %1, 1 \n" | 246 | " addu %1, 1 \n" |
| 246 | "2: sc %1, %0 \n" | 247 | "2: sc %1, %0 \n" |
| 247 | : "=m" (rw->lock), "=&r" (tmp) | 248 | : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp) |
| 248 | : "m" (rw->lock) | 249 | : GCC_OFF12_ASM() (rw->lock) |
| 249 | : "memory"); | 250 | : "memory"); |
| 250 | } while (unlikely(!tmp)); | 251 | } while (unlikely(!tmp)); |
| 251 | } | 252 | } |
| @@ -268,8 +269,8 @@ static inline void arch_read_unlock(arch_rwlock_t *rw) | |||
| 268 | " sub %1, 1 \n" | 269 | " sub %1, 1 \n" |
| 269 | " sc %1, %0 \n" | 270 | " sc %1, %0 \n" |
| 270 | " beqzl %1, 1b \n" | 271 | " beqzl %1, 1b \n" |
| 271 | : "=m" (rw->lock), "=&r" (tmp) | 272 | : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp) |
| 272 | : "m" (rw->lock) | 273 | : GCC_OFF12_ASM() (rw->lock) |
| 273 | : "memory"); | 274 | : "memory"); |
| 274 | } else { | 275 | } else { |
| 275 | do { | 276 | do { |
| @@ -277,8 +278,8 @@ static inline void arch_read_unlock(arch_rwlock_t *rw) | |||
| 277 | "1: ll %1, %2 # arch_read_unlock \n" | 278 | "1: ll %1, %2 # arch_read_unlock \n" |
| 278 | " sub %1, 1 \n" | 279 | " sub %1, 1 \n" |
| 279 | " sc %1, %0 \n" | 280 | " sc %1, %0 \n" |
| 280 | : "=m" (rw->lock), "=&r" (tmp) | 281 | : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp) |
| 281 | : "m" (rw->lock) | 282 | : GCC_OFF12_ASM() (rw->lock) |
| 282 | : "memory"); | 283 | : "memory"); |
| 283 | } while (unlikely(!tmp)); | 284 | } while (unlikely(!tmp)); |
| 284 | } | 285 | } |
| @@ -298,8 +299,8 @@ static inline void arch_write_lock(arch_rwlock_t *rw) | |||
| 298 | " beqzl %1, 1b \n" | 299 | " beqzl %1, 1b \n" |
| 299 | " nop \n" | 300 | " nop \n" |
| 300 | " .set reorder \n" | 301 | " .set reorder \n" |
| 301 | : "=m" (rw->lock), "=&r" (tmp) | 302 | : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp) |
| 302 | : "m" (rw->lock) | 303 | : GCC_OFF12_ASM() (rw->lock) |
| 303 | : "memory"); | 304 | : "memory"); |
| 304 | } else { | 305 | } else { |
| 305 | do { | 306 | do { |
| @@ -308,8 +309,8 @@ static inline void arch_write_lock(arch_rwlock_t *rw) | |||
| 308 | " bnez %1, 1b \n" | 309 | " bnez %1, 1b \n" |
| 309 | " lui %1, 0x8000 \n" | 310 | " lui %1, 0x8000 \n" |
| 310 | "2: sc %1, %0 \n" | 311 | "2: sc %1, %0 \n" |
| 311 | : "=m" (rw->lock), "=&r" (tmp) | 312 | : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp) |
| 312 | : "m" (rw->lock) | 313 | : GCC_OFF12_ASM() (rw->lock) |
| 313 | : "memory"); | 314 | : "memory"); |
| 314 | } while (unlikely(!tmp)); | 315 | } while (unlikely(!tmp)); |
| 315 | } | 316 | } |
| @@ -348,8 +349,8 @@ static inline int arch_read_trylock(arch_rwlock_t *rw) | |||
| 348 | __WEAK_LLSC_MB | 349 | __WEAK_LLSC_MB |
| 349 | " li %2, 1 \n" | 350 | " li %2, 1 \n" |
| 350 | "2: \n" | 351 | "2: \n" |
| 351 | : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) | 352 | : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret) |
| 352 | : "m" (rw->lock) | 353 | : GCC_OFF12_ASM() (rw->lock) |
| 353 | : "memory"); | 354 | : "memory"); |
| 354 | } else { | 355 | } else { |
| 355 | __asm__ __volatile__( | 356 | __asm__ __volatile__( |
| @@ -365,8 +366,8 @@ static inline int arch_read_trylock(arch_rwlock_t *rw) | |||
| 365 | __WEAK_LLSC_MB | 366 | __WEAK_LLSC_MB |
| 366 | " li %2, 1 \n" | 367 | " li %2, 1 \n" |
| 367 | "2: \n" | 368 | "2: \n" |
| 368 | : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) | 369 | : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret) |
| 369 | : "m" (rw->lock) | 370 | : GCC_OFF12_ASM() (rw->lock) |
| 370 | : "memory"); | 371 | : "memory"); |
| 371 | } | 372 | } |
| 372 | 373 | ||
| @@ -392,8 +393,8 @@ static inline int arch_write_trylock(arch_rwlock_t *rw) | |||
| 392 | " li %2, 1 \n" | 393 | " li %2, 1 \n" |
| 393 | " .set reorder \n" | 394 | " .set reorder \n" |
| 394 | "2: \n" | 395 | "2: \n" |
| 395 | : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) | 396 | : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret) |
| 396 | : "m" (rw->lock) | 397 | : GCC_OFF12_ASM() (rw->lock) |
| 397 | : "memory"); | 398 | : "memory"); |
| 398 | } else { | 399 | } else { |
| 399 | do { | 400 | do { |
| @@ -405,8 +406,9 @@ static inline int arch_write_trylock(arch_rwlock_t *rw) | |||
| 405 | " sc %1, %0 \n" | 406 | " sc %1, %0 \n" |
| 406 | " li %2, 1 \n" | 407 | " li %2, 1 \n" |
| 407 | "2: \n" | 408 | "2: \n" |
| 408 | : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) | 409 | : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp), |
| 409 | : "m" (rw->lock) | 410 | "=&r" (ret) |
| 411 | : GCC_OFF12_ASM() (rw->lock) | ||
| 410 | : "memory"); | 412 | : "memory"); |
| 411 | } while (unlikely(!tmp)); | 413 | } while (unlikely(!tmp)); |
| 412 | 414 | ||
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index 7de865805deb..99eea59604e9 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h | |||
| @@ -116,6 +116,7 @@ static inline struct thread_info *current_thread_info(void) | |||
| 116 | #define TIF_LOAD_WATCH 25 /* If set, load watch registers */ | 116 | #define TIF_LOAD_WATCH 25 /* If set, load watch registers */ |
| 117 | #define TIF_SYSCALL_TRACEPOINT 26 /* syscall tracepoint instrumentation */ | 117 | #define TIF_SYSCALL_TRACEPOINT 26 /* syscall tracepoint instrumentation */ |
| 118 | #define TIF_32BIT_FPREGS 27 /* 32-bit floating point registers */ | 118 | #define TIF_32BIT_FPREGS 27 /* 32-bit floating point registers */ |
| 119 | #define TIF_HYBRID_FPREGS 28 /* 64b FP registers, odd singles in bits 63:32 of even doubles */ | ||
| 119 | #define TIF_USEDMSA 29 /* MSA has been used this quantum */ | 120 | #define TIF_USEDMSA 29 /* MSA has been used this quantum */ |
| 120 | #define TIF_MSA_CTX_LIVE 30 /* MSA context must be preserved */ | 121 | #define TIF_MSA_CTX_LIVE 30 /* MSA context must be preserved */ |
| 121 | #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ | 122 | #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ |
| @@ -135,6 +136,7 @@ static inline struct thread_info *current_thread_info(void) | |||
| 135 | #define _TIF_FPUBOUND (1<<TIF_FPUBOUND) | 136 | #define _TIF_FPUBOUND (1<<TIF_FPUBOUND) |
| 136 | #define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH) | 137 | #define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH) |
| 137 | #define _TIF_32BIT_FPREGS (1<<TIF_32BIT_FPREGS) | 138 | #define _TIF_32BIT_FPREGS (1<<TIF_32BIT_FPREGS) |
| 139 | #define _TIF_HYBRID_FPREGS (1<<TIF_HYBRID_FPREGS) | ||
| 138 | #define _TIF_USEDMSA (1<<TIF_USEDMSA) | 140 | #define _TIF_USEDMSA (1<<TIF_USEDMSA) |
| 139 | #define _TIF_MSA_CTX_LIVE (1<<TIF_MSA_CTX_LIVE) | 141 | #define _TIF_MSA_CTX_LIVE (1<<TIF_MSA_CTX_LIVE) |
| 140 | #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) | 142 | #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) |
diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h index 8f3047d611ee..8ab2874225c4 100644 --- a/arch/mips/include/asm/time.h +++ b/arch/mips/include/asm/time.h | |||
| @@ -46,19 +46,17 @@ extern unsigned int mips_hpt_frequency; | |||
| 46 | * so it lives here. | 46 | * so it lives here. |
| 47 | */ | 47 | */ |
| 48 | extern int (*perf_irq)(void); | 48 | extern int (*perf_irq)(void); |
| 49 | extern int __weak get_c0_perfcount_int(void); | ||
| 49 | 50 | ||
| 50 | /* | 51 | /* |
| 51 | * Initialize the calling CPU's compare interrupt as clockevent device | 52 | * Initialize the calling CPU's compare interrupt as clockevent device |
| 52 | */ | 53 | */ |
| 53 | extern unsigned int __weak get_c0_compare_int(void); | 54 | extern unsigned int __weak get_c0_compare_int(void); |
| 54 | extern int r4k_clockevent_init(void); | 55 | extern int r4k_clockevent_init(void); |
| 55 | extern int gic_clockevent_init(void); | ||
| 56 | 56 | ||
| 57 | static inline int mips_clockevent_init(void) | 57 | static inline int mips_clockevent_init(void) |
| 58 | { | 58 | { |
| 59 | #if defined(CONFIG_CEVT_GIC) | 59 | #ifdef CONFIG_CEVT_R4K |
| 60 | return (gic_clockevent_init() | r4k_clockevent_init()); | ||
| 61 | #elif defined(CONFIG_CEVT_R4K) | ||
| 62 | return r4k_clockevent_init(); | 60 | return r4k_clockevent_init(); |
| 63 | #else | 61 | #else |
| 64 | return -ENXIO; | 62 | return -ENXIO; |
diff --git a/arch/mips/include/asm/types.h b/arch/mips/include/asm/types.h index a845aafedee4..148d42a17f30 100644 --- a/arch/mips/include/asm/types.h +++ b/arch/mips/include/asm/types.h | |||
| @@ -11,23 +11,7 @@ | |||
| 11 | #ifndef _ASM_TYPES_H | 11 | #ifndef _ASM_TYPES_H |
| 12 | #define _ASM_TYPES_H | 12 | #define _ASM_TYPES_H |
| 13 | 13 | ||
| 14 | # include <asm-generic/int-ll64.h> | 14 | #include <asm-generic/int-ll64.h> |
| 15 | #include <uapi/asm/types.h> | 15 | #include <uapi/asm/types.h> |
| 16 | 16 | ||
| 17 | /* | ||
| 18 | * These aren't exported outside the kernel to avoid name space clashes | ||
| 19 | */ | ||
| 20 | #ifndef __ASSEMBLY__ | ||
| 21 | |||
| 22 | /* | ||
| 23 | * Don't use phys_t. You've been warned. | ||
| 24 | */ | ||
| 25 | #ifdef CONFIG_64BIT_PHYS_ADDR | ||
| 26 | typedef unsigned long long phys_t; | ||
| 27 | #else | ||
| 28 | typedef unsigned long phys_t; | ||
| 29 | #endif | ||
| 30 | |||
| 31 | #endif /* __ASSEMBLY__ */ | ||
| 32 | |||
| 33 | #endif /* _ASM_TYPES_H */ | 17 | #endif /* _ASM_TYPES_H */ |
diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h index 22a5624e2fd2..bf8b32450ef6 100644 --- a/arch/mips/include/asm/uaccess.h +++ b/arch/mips/include/asm/uaccess.h | |||
| @@ -1325,33 +1325,6 @@ strncpy_from_user(char *__to, const char __user *__from, long __len) | |||
| 1325 | return res; | 1325 | return res; |
| 1326 | } | 1326 | } |
| 1327 | 1327 | ||
| 1328 | /* Returns: 0 if bad, string length+1 (memory size) of string if ok */ | ||
| 1329 | static inline long __strlen_user(const char __user *s) | ||
| 1330 | { | ||
| 1331 | long res; | ||
| 1332 | |||
| 1333 | if (segment_eq(get_fs(), get_ds())) { | ||
| 1334 | __asm__ __volatile__( | ||
| 1335 | "move\t$4, %1\n\t" | ||
| 1336 | __MODULE_JAL(__strlen_kernel_nocheck_asm) | ||
| 1337 | "move\t%0, $2" | ||
| 1338 | : "=r" (res) | ||
| 1339 | : "r" (s) | ||
| 1340 | : "$2", "$4", __UA_t0, "$31"); | ||
| 1341 | } else { | ||
| 1342 | might_fault(); | ||
| 1343 | __asm__ __volatile__( | ||
| 1344 | "move\t$4, %1\n\t" | ||
| 1345 | __MODULE_JAL(__strlen_user_nocheck_asm) | ||
| 1346 | "move\t%0, $2" | ||
| 1347 | : "=r" (res) | ||
| 1348 | : "r" (s) | ||
| 1349 | : "$2", "$4", __UA_t0, "$31"); | ||
| 1350 | } | ||
| 1351 | |||
| 1352 | return res; | ||
| 1353 | } | ||
| 1354 | |||
| 1355 | /* | 1328 | /* |
| 1356 | * strlen_user: - Get the size of a string in user space. | 1329 | * strlen_user: - Get the size of a string in user space. |
| 1357 | * @str: The string to measure. | 1330 | * @str: The string to measure. |
diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h index 708c5d414905..fc1cdd25fcda 100644 --- a/arch/mips/include/asm/uasm.h +++ b/arch/mips/include/asm/uasm.h | |||
| @@ -136,9 +136,11 @@ Ip_u1s2(_lui); | |||
| 136 | Ip_u2s3u1(_lw); | 136 | Ip_u2s3u1(_lw); |
| 137 | Ip_u3u1u2(_lwx); | 137 | Ip_u3u1u2(_lwx); |
| 138 | Ip_u1u2u3(_mfc0); | 138 | Ip_u1u2u3(_mfc0); |
| 139 | Ip_u1u2u3(_mfhc0); | ||
| 139 | Ip_u1(_mfhi); | 140 | Ip_u1(_mfhi); |
| 140 | Ip_u1(_mflo); | 141 | Ip_u1(_mflo); |
| 141 | Ip_u1u2u3(_mtc0); | 142 | Ip_u1u2u3(_mtc0); |
| 143 | Ip_u1u2u3(_mthc0); | ||
| 142 | Ip_u3u1u2(_mul); | 144 | Ip_u3u1u2(_mul); |
| 143 | Ip_u3u1u2(_or); | 145 | Ip_u3u1u2(_or); |
| 144 | Ip_u2u1u3(_ori); | 146 | Ip_u2u1u3(_ori); |
diff --git a/arch/mips/include/uapi/asm/inst.h b/arch/mips/include/uapi/asm/inst.h index 4bfdb9d4c186..89c22433b1c6 100644 --- a/arch/mips/include/uapi/asm/inst.h +++ b/arch/mips/include/uapi/asm/inst.h | |||
| @@ -108,9 +108,10 @@ enum rt_op { | |||
| 108 | */ | 108 | */ |
| 109 | enum cop_op { | 109 | enum cop_op { |
| 110 | mfc_op = 0x00, dmfc_op = 0x01, | 110 | mfc_op = 0x00, dmfc_op = 0x01, |
| 111 | cfc_op = 0x02, mfhc_op = 0x03, | 111 | cfc_op = 0x02, mfhc0_op = 0x02, |
| 112 | mtc_op = 0x04, dmtc_op = 0x05, | 112 | mfhc_op = 0x03, mtc_op = 0x04, |
| 113 | ctc_op = 0x06, mthc_op = 0x07, | 113 | dmtc_op = 0x05, ctc_op = 0x06, |
| 114 | mthc0_op = 0x06, mthc_op = 0x07, | ||
| 114 | bc_op = 0x08, cop_op = 0x10, | 115 | bc_op = 0x08, cop_op = 0x10, |
| 115 | copm_op = 0x18 | 116 | copm_op = 0x18 |
| 116 | }; | 117 | }; |
diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c index 76eafcb79c89..ef796f97b996 100644 --- a/arch/mips/jz4740/setup.c +++ b/arch/mips/jz4740/setup.c | |||
| @@ -32,7 +32,7 @@ static void __init jz4740_detect_mem(void) | |||
| 32 | { | 32 | { |
| 33 | void __iomem *jz_emc_base; | 33 | void __iomem *jz_emc_base; |
| 34 | u32 ctrl, bus, bank, rows, cols; | 34 | u32 ctrl, bus, bank, rows, cols; |
| 35 | phys_t size; | 35 | phys_addr_t size; |
| 36 | 36 | ||
| 37 | jz_emc_base = ioremap(JZ4740_EMC_BASE_ADDR, 0x100); | 37 | jz_emc_base = ioremap(JZ4740_EMC_BASE_ADDR, 0x100); |
| 38 | ctrl = readl(jz_emc_base + JZ4740_EMC_SDRAM_CTRL); | 38 | ctrl = readl(jz_emc_base + JZ4740_EMC_SDRAM_CTRL); |
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 008a2fed0584..92987d1bbe5f 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile | |||
| @@ -4,9 +4,10 @@ | |||
| 4 | 4 | ||
| 5 | extra-y := head.o vmlinux.lds | 5 | extra-y := head.o vmlinux.lds |
| 6 | 6 | ||
| 7 | obj-y += cpu-probe.o branch.o entry.o genex.o idle.o irq.o process.o \ | 7 | obj-y += cpu-probe.o branch.o elf.o entry.o genex.o idle.o irq.o \ |
| 8 | prom.o ptrace.o reset.o setup.o signal.o syscall.o \ | 8 | process.o prom.o ptrace.o reset.o setup.o signal.o \ |
| 9 | time.o topology.o traps.o unaligned.o watch.o vdso.o | 9 | syscall.o time.o topology.o traps.o unaligned.o watch.o \ |
| 10 | vdso.o | ||
| 10 | 11 | ||
| 11 | ifdef CONFIG_FUNCTION_TRACER | 12 | ifdef CONFIG_FUNCTION_TRACER |
| 12 | CFLAGS_REMOVE_ftrace.o = -pg | 13 | CFLAGS_REMOVE_ftrace.o = -pg |
| @@ -18,12 +19,10 @@ endif | |||
| 18 | obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o | 19 | obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o |
| 19 | obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o | 20 | obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o |
| 20 | obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o | 21 | obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o |
| 21 | obj-$(CONFIG_CEVT_GIC) += cevt-gic.o | ||
| 22 | obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o | 22 | obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o |
| 23 | obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o | 23 | obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o |
| 24 | obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o | 24 | obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o |
| 25 | obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o | 25 | obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o |
| 26 | obj-$(CONFIG_CSRC_GIC) += csrc-gic.o | ||
| 27 | obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o | 26 | obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o |
| 28 | obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o | 27 | obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o |
| 29 | obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o | 28 | obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o |
| @@ -68,7 +67,6 @@ obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o | |||
| 68 | obj-$(CONFIG_MIPS_MSC) += irq-msc01.o | 67 | obj-$(CONFIG_MIPS_MSC) += irq-msc01.o |
| 69 | obj-$(CONFIG_IRQ_TXX9) += irq_txx9.o | 68 | obj-$(CONFIG_IRQ_TXX9) += irq_txx9.o |
| 70 | obj-$(CONFIG_IRQ_GT641XX) += irq-gt641xx.o | 69 | obj-$(CONFIG_IRQ_GT641XX) += irq-gt641xx.o |
| 71 | obj-$(CONFIG_IRQ_GIC) += irq-gic.o | ||
| 72 | 70 | ||
| 73 | obj-$(CONFIG_KPROBES) += kprobes.o | 71 | obj-$(CONFIG_KPROBES) += kprobes.o |
| 74 | obj-$(CONFIG_32BIT) += scall32-o32.o | 72 | obj-$(CONFIG_32BIT) += scall32-o32.o |
diff --git a/arch/mips/kernel/cevt-gic.c b/arch/mips/kernel/cevt-gic.c deleted file mode 100644 index 6093716980b9..000000000000 --- a/arch/mips/kernel/cevt-gic.c +++ /dev/null | |||
| @@ -1,105 +0,0 @@ | |||
| 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 | * Copyright (C) 2013 Imagination Technologies Ltd. | ||
| 7 | */ | ||
| 8 | #include <linux/clockchips.h> | ||
| 9 | #include <linux/interrupt.h> | ||
| 10 | #include <linux/percpu.h> | ||
| 11 | #include <linux/smp.h> | ||
| 12 | #include <linux/irq.h> | ||
| 13 | |||
| 14 | #include <asm/time.h> | ||
| 15 | #include <asm/gic.h> | ||
| 16 | #include <asm/mips-boards/maltaint.h> | ||
| 17 | |||
| 18 | DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); | ||
| 19 | int gic_timer_irq_installed; | ||
| 20 | |||
| 21 | |||
| 22 | static int gic_next_event(unsigned long delta, struct clock_event_device *evt) | ||
| 23 | { | ||
| 24 | u64 cnt; | ||
| 25 | int res; | ||
| 26 | |||
| 27 | cnt = gic_read_count(); | ||
| 28 | cnt += (u64)delta; | ||
| 29 | gic_write_cpu_compare(cnt, cpumask_first(evt->cpumask)); | ||
| 30 | res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0; | ||
| 31 | return res; | ||
| 32 | } | ||
| 33 | |||
| 34 | void gic_set_clock_mode(enum clock_event_mode mode, | ||
| 35 | struct clock_event_device *evt) | ||
| 36 | { | ||
| 37 | /* Nothing to do ... */ | ||
| 38 | } | ||
| 39 | |||
| 40 | irqreturn_t gic_compare_interrupt(int irq, void *dev_id) | ||
| 41 | { | ||
| 42 | struct clock_event_device *cd; | ||
| 43 | int cpu = smp_processor_id(); | ||
| 44 | |||
| 45 | gic_write_compare(gic_read_compare()); | ||
| 46 | cd = &per_cpu(gic_clockevent_device, cpu); | ||
| 47 | cd->event_handler(cd); | ||
| 48 | return IRQ_HANDLED; | ||
| 49 | } | ||
| 50 | |||
| 51 | struct irqaction gic_compare_irqaction = { | ||
| 52 | .handler = gic_compare_interrupt, | ||
| 53 | .flags = IRQF_PERCPU | IRQF_TIMER, | ||
| 54 | .name = "timer", | ||
| 55 | }; | ||
| 56 | |||
| 57 | |||
| 58 | void gic_event_handler(struct clock_event_device *dev) | ||
| 59 | { | ||
| 60 | } | ||
| 61 | |||
| 62 | int gic_clockevent_init(void) | ||
| 63 | { | ||
| 64 | unsigned int cpu = smp_processor_id(); | ||
| 65 | struct clock_event_device *cd; | ||
| 66 | unsigned int irq; | ||
| 67 | |||
| 68 | if (!cpu_has_counter || !gic_frequency) | ||
| 69 | return -ENXIO; | ||
| 70 | |||
| 71 | irq = MIPS_GIC_IRQ_BASE; | ||
| 72 | |||
| 73 | cd = &per_cpu(gic_clockevent_device, cpu); | ||
| 74 | |||
| 75 | cd->name = "MIPS GIC"; | ||
| 76 | cd->features = CLOCK_EVT_FEAT_ONESHOT | | ||
| 77 | CLOCK_EVT_FEAT_C3STOP; | ||
| 78 | |||
| 79 | clockevent_set_clock(cd, gic_frequency); | ||
| 80 | |||
| 81 | /* Calculate the min / max delta */ | ||
| 82 | cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); | ||
| 83 | cd->min_delta_ns = clockevent_delta2ns(0x300, cd); | ||
| 84 | |||
| 85 | cd->rating = 300; | ||
| 86 | cd->irq = irq; | ||
| 87 | cd->cpumask = cpumask_of(cpu); | ||
| 88 | cd->set_next_event = gic_next_event; | ||
| 89 | cd->set_mode = gic_set_clock_mode; | ||
| 90 | cd->event_handler = gic_event_handler; | ||
| 91 | |||
| 92 | clockevents_register_device(cd); | ||
| 93 | |||
| 94 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_MAP), 0x80000002); | ||
| 95 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), GIC_VPE_SMASK_CMP_MSK); | ||
| 96 | |||
| 97 | if (gic_timer_irq_installed) | ||
| 98 | return 0; | ||
| 99 | |||
| 100 | gic_timer_irq_installed = 1; | ||
| 101 | |||
| 102 | setup_irq(irq, &gic_compare_irqaction); | ||
| 103 | irq_set_handler(irq, handle_percpu_irq); | ||
| 104 | return 0; | ||
| 105 | } | ||
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index bc127e22fdab..6acaad0480af 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c | |||
| @@ -11,10 +11,10 @@ | |||
| 11 | #include <linux/percpu.h> | 11 | #include <linux/percpu.h> |
| 12 | #include <linux/smp.h> | 12 | #include <linux/smp.h> |
| 13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
| 14 | #include <linux/irqchip/mips-gic.h> | ||
| 14 | 15 | ||
| 15 | #include <asm/time.h> | 16 | #include <asm/time.h> |
| 16 | #include <asm/cevt-r4k.h> | 17 | #include <asm/cevt-r4k.h> |
| 17 | #include <asm/gic.h> | ||
| 18 | 18 | ||
| 19 | static int mips_next_event(unsigned long delta, | 19 | static int mips_next_event(unsigned long delta, |
| 20 | struct clock_event_device *evt) | 20 | struct clock_event_device *evt) |
| @@ -85,8 +85,8 @@ void mips_event_handler(struct clock_event_device *dev) | |||
| 85 | */ | 85 | */ |
| 86 | static int c0_compare_int_pending(void) | 86 | static int c0_compare_int_pending(void) |
| 87 | { | 87 | { |
| 88 | #ifdef CONFIG_IRQ_GIC | 88 | #ifdef CONFIG_MIPS_GIC |
| 89 | if (cpu_has_veic) | 89 | if (gic_present) |
| 90 | return gic_get_timer_pending(); | 90 | return gic_get_timer_pending(); |
| 91 | #endif | 91 | #endif |
| 92 | return (read_c0_cause() >> cp0_compare_irq_shift) & (1ul << CAUSEB_IP); | 92 | return (read_c0_cause() >> cp0_compare_irq_shift) & (1ul << CAUSEB_IP); |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index dc49cf30c2db..5342674842f5 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
| @@ -69,6 +69,63 @@ static int __init htw_disable(char *s) | |||
| 69 | 69 | ||
| 70 | __setup("nohtw", htw_disable); | 70 | __setup("nohtw", htw_disable); |
| 71 | 71 | ||
| 72 | static int mips_ftlb_disabled; | ||
| 73 | static int mips_has_ftlb_configured; | ||
| 74 | |||
| 75 | static void set_ftlb_enable(struct cpuinfo_mips *c, int enable); | ||
| 76 | |||
| 77 | static int __init ftlb_disable(char *s) | ||
| 78 | { | ||
| 79 | unsigned int config4, mmuextdef; | ||
| 80 | |||
| 81 | /* | ||
| 82 | * If the core hasn't done any FTLB configuration, there is nothing | ||
| 83 | * for us to do here. | ||
| 84 | */ | ||
| 85 | if (!mips_has_ftlb_configured) | ||
| 86 | return 1; | ||
| 87 | |||
| 88 | /* Disable it in the boot cpu */ | ||
| 89 | set_ftlb_enable(&cpu_data[0], 0); | ||
| 90 | |||
| 91 | back_to_back_c0_hazard(); | ||
| 92 | |||
| 93 | config4 = read_c0_config4(); | ||
| 94 | |||
| 95 | /* Check that FTLB has been disabled */ | ||
| 96 | mmuextdef = config4 & MIPS_CONF4_MMUEXTDEF; | ||
| 97 | /* MMUSIZEEXT == VTLB ON, FTLB OFF */ | ||
| 98 | if (mmuextdef == MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT) { | ||
| 99 | /* This should never happen */ | ||
| 100 | pr_warn("FTLB could not be disabled!\n"); | ||
| 101 | return 1; | ||
| 102 | } | ||
| 103 | |||
| 104 | mips_ftlb_disabled = 1; | ||
| 105 | mips_has_ftlb_configured = 0; | ||
| 106 | |||
| 107 | /* | ||
| 108 | * noftlb is mainly used for debug purposes so print | ||
| 109 | * an informative message instead of using pr_debug() | ||
| 110 | */ | ||
| 111 | pr_info("FTLB has been disabled\n"); | ||
| 112 | |||
| 113 | /* | ||
| 114 | * Some of these bits are duplicated in the decode_config4. | ||
| 115 | * MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT is the only possible case | ||
| 116 | * once FTLB has been disabled so undo what decode_config4 did. | ||
| 117 | */ | ||
| 118 | cpu_data[0].tlbsize -= cpu_data[0].tlbsizeftlbways * | ||
| 119 | cpu_data[0].tlbsizeftlbsets; | ||
| 120 | cpu_data[0].tlbsizeftlbsets = 0; | ||
| 121 | cpu_data[0].tlbsizeftlbways = 0; | ||
| 122 | |||
| 123 | return 1; | ||
| 124 | } | ||
| 125 | |||
| 126 | __setup("noftlb", ftlb_disable); | ||
| 127 | |||
| 128 | |||
| 72 | static inline void check_errata(void) | 129 | static inline void check_errata(void) |
| 73 | { | 130 | { |
| 74 | struct cpuinfo_mips *c = ¤t_cpu_data; | 131 | struct cpuinfo_mips *c = ¤t_cpu_data; |
| @@ -140,7 +197,7 @@ static inline unsigned long cpu_get_fpu_id(void) | |||
| 140 | */ | 197 | */ |
| 141 | static inline int __cpu_has_fpu(void) | 198 | static inline int __cpu_has_fpu(void) |
| 142 | { | 199 | { |
| 143 | return ((cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE); | 200 | return (cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE; |
| 144 | } | 201 | } |
| 145 | 202 | ||
| 146 | static inline unsigned long cpu_get_msa_id(void) | 203 | static inline unsigned long cpu_get_msa_id(void) |
| @@ -399,6 +456,8 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c) | |||
| 399 | ftlb_page = MIPS_CONF4_VFTLBPAGESIZE; | 456 | ftlb_page = MIPS_CONF4_VFTLBPAGESIZE; |
| 400 | /* fall through */ | 457 | /* fall through */ |
| 401 | case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT: | 458 | case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT: |
| 459 | if (mips_ftlb_disabled) | ||
| 460 | break; | ||
| 402 | newcf4 = (config4 & ~ftlb_page) | | 461 | newcf4 = (config4 & ~ftlb_page) | |
| 403 | (page_size_ftlb(mmuextdef) << | 462 | (page_size_ftlb(mmuextdef) << |
| 404 | MIPS_CONF4_FTLBPAGESIZE_SHIFT); | 463 | MIPS_CONF4_FTLBPAGESIZE_SHIFT); |
| @@ -418,6 +477,7 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c) | |||
| 418 | c->tlbsizeftlbways = ((config4 & MIPS_CONF4_FTLBWAYS) >> | 477 | c->tlbsizeftlbways = ((config4 & MIPS_CONF4_FTLBWAYS) >> |
| 419 | MIPS_CONF4_FTLBWAYS_SHIFT) + 2; | 478 | MIPS_CONF4_FTLBWAYS_SHIFT) + 2; |
| 420 | c->tlbsize += c->tlbsizeftlbways * c->tlbsizeftlbsets; | 479 | c->tlbsize += c->tlbsizeftlbways * c->tlbsizeftlbsets; |
| 480 | mips_has_ftlb_configured = 1; | ||
| 421 | break; | 481 | break; |
| 422 | } | 482 | } |
| 423 | } | 483 | } |
| @@ -432,7 +492,7 @@ static inline unsigned int decode_config5(struct cpuinfo_mips *c) | |||
| 432 | unsigned int config5; | 492 | unsigned int config5; |
| 433 | 493 | ||
| 434 | config5 = read_c0_config5(); | 494 | config5 = read_c0_config5(); |
| 435 | config5 &= ~MIPS_CONF5_UFR; | 495 | config5 &= ~(MIPS_CONF5_UFR | MIPS_CONF5_UFE); |
| 436 | write_c0_config5(config5); | 496 | write_c0_config5(config5); |
| 437 | 497 | ||
| 438 | if (config5 & MIPS_CONF5_EVA) | 498 | if (config5 & MIPS_CONF5_EVA) |
| @@ -453,8 +513,8 @@ static void decode_configs(struct cpuinfo_mips *c) | |||
| 453 | 513 | ||
| 454 | c->scache.flags = MIPS_CACHE_NOT_PRESENT; | 514 | c->scache.flags = MIPS_CACHE_NOT_PRESENT; |
| 455 | 515 | ||
| 456 | /* Enable FTLB if present */ | 516 | /* Enable FTLB if present and not disabled */ |
| 457 | set_ftlb_enable(c, 1); | 517 | set_ftlb_enable(c, !mips_ftlb_disabled); |
| 458 | 518 | ||
| 459 | ok = decode_config0(c); /* Read Config registers. */ | 519 | ok = decode_config0(c); /* Read Config registers. */ |
| 460 | BUG_ON(!ok); /* Arch spec violation! */ | 520 | BUG_ON(!ok); /* Arch spec violation! */ |
| @@ -1058,6 +1118,7 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu) | |||
| 1058 | break; | 1118 | break; |
| 1059 | } | 1119 | } |
| 1060 | case PRID_IMP_BMIPS5000: | 1120 | case PRID_IMP_BMIPS5000: |
| 1121 | case PRID_IMP_BMIPS5200: | ||
| 1061 | c->cputype = CPU_BMIPS5000; | 1122 | c->cputype = CPU_BMIPS5000; |
| 1062 | __cpu_name[cpu] = "Broadcom BMIPS5000"; | 1123 | __cpu_name[cpu] = "Broadcom BMIPS5000"; |
| 1063 | set_elf_platform(cpu, "bmips5000"); | 1124 | set_elf_platform(cpu, "bmips5000"); |
| @@ -1288,6 +1349,8 @@ void cpu_probe(void) | |||
| 1288 | MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) { | 1349 | MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) { |
| 1289 | if (c->fpu_id & MIPS_FPIR_3D) | 1350 | if (c->fpu_id & MIPS_FPIR_3D) |
| 1290 | c->ases |= MIPS_ASE_MIPS3D; | 1351 | c->ases |= MIPS_ASE_MIPS3D; |
| 1352 | if (c->fpu_id & MIPS_FPIR_FREP) | ||
| 1353 | c->options |= MIPS_CPU_FRE; | ||
| 1291 | } | 1354 | } |
| 1292 | } | 1355 | } |
| 1293 | 1356 | ||
diff --git a/arch/mips/kernel/crash_dump.c b/arch/mips/kernel/crash_dump.c index f291cf99b03a..6fe7790e5868 100644 --- a/arch/mips/kernel/crash_dump.c +++ b/arch/mips/kernel/crash_dump.c | |||
| @@ -38,7 +38,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, | |||
| 38 | kunmap_atomic(vaddr); | 38 | kunmap_atomic(vaddr); |
| 39 | } else { | 39 | } else { |
| 40 | if (!kdump_buf_page) { | 40 | if (!kdump_buf_page) { |
| 41 | pr_warning("Kdump: Kdump buffer page not allocated\n"); | 41 | pr_warn("Kdump: Kdump buffer page not allocated\n"); |
| 42 | 42 | ||
| 43 | return -EFAULT; | 43 | return -EFAULT; |
| 44 | } | 44 | } |
| @@ -57,7 +57,7 @@ static int __init kdump_buf_page_init(void) | |||
| 57 | 57 | ||
| 58 | kdump_buf_page = kmalloc(PAGE_SIZE, GFP_KERNEL); | 58 | kdump_buf_page = kmalloc(PAGE_SIZE, GFP_KERNEL); |
| 59 | if (!kdump_buf_page) { | 59 | if (!kdump_buf_page) { |
| 60 | pr_warning("Kdump: Failed to allocate kdump buffer page\n"); | 60 | pr_warn("Kdump: Failed to allocate kdump buffer page\n"); |
| 61 | ret = -ENOMEM; | 61 | ret = -ENOMEM; |
| 62 | } | 62 | } |
| 63 | 63 | ||
diff --git a/arch/mips/kernel/csrc-gic.c b/arch/mips/kernel/csrc-gic.c deleted file mode 100644 index e02620901117..000000000000 --- a/arch/mips/kernel/csrc-gic.c +++ /dev/null | |||
| @@ -1,40 +0,0 @@ | |||
| 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 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. | ||
| 7 | */ | ||
| 8 | #include <linux/init.h> | ||
| 9 | #include <linux/time.h> | ||
| 10 | |||
| 11 | #include <asm/gic.h> | ||
| 12 | |||
| 13 | static cycle_t gic_hpt_read(struct clocksource *cs) | ||
| 14 | { | ||
| 15 | return gic_read_count(); | ||
| 16 | } | ||
| 17 | |||
| 18 | static struct clocksource gic_clocksource = { | ||
| 19 | .name = "GIC", | ||
| 20 | .read = gic_hpt_read, | ||
| 21 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
| 22 | }; | ||
| 23 | |||
| 24 | void __init gic_clocksource_init(unsigned int frequency) | ||
| 25 | { | ||
| 26 | unsigned int config, bits; | ||
| 27 | |||
| 28 | /* Calculate the clocksource mask. */ | ||
| 29 | GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), config); | ||
| 30 | bits = 32 + ((config & GIC_SH_CONFIG_COUNTBITS_MSK) >> | ||
| 31 | (GIC_SH_CONFIG_COUNTBITS_SHF - 2)); | ||
| 32 | |||
| 33 | /* Set clocksource mask. */ | ||
| 34 | gic_clocksource.mask = CLOCKSOURCE_MASK(bits); | ||
| 35 | |||
| 36 | /* Calculate a somewhat reasonable rating value. */ | ||
| 37 | gic_clocksource.rating = 200 + frequency / 10000000; | ||
| 38 | |||
| 39 | clocksource_register_hz(&gic_clocksource, frequency); | ||
| 40 | } | ||
diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c new file mode 100644 index 000000000000..c92b15df6893 --- /dev/null +++ b/arch/mips/kernel/elf.c | |||
| @@ -0,0 +1,191 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2014 Imagination Technologies | ||
| 3 | * Author: Paul Burton <paul.burton@imgtec.com> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License as published by the | ||
| 7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 8 | * option) any later version. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/elf.h> | ||
| 12 | #include <linux/sched.h> | ||
| 13 | |||
| 14 | enum { | ||
| 15 | FP_ERROR = -1, | ||
| 16 | FP_DOUBLE_64A = -2, | ||
| 17 | }; | ||
| 18 | |||
| 19 | int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf, | ||
| 20 | bool is_interp, struct arch_elf_state *state) | ||
| 21 | { | ||
| 22 | struct elfhdr *ehdr = _ehdr; | ||
| 23 | struct elf_phdr *phdr = _phdr; | ||
| 24 | struct mips_elf_abiflags_v0 abiflags; | ||
| 25 | int ret; | ||
| 26 | |||
| 27 | if (config_enabled(CONFIG_64BIT) && | ||
| 28 | (ehdr->e_ident[EI_CLASS] != ELFCLASS32)) | ||
| 29 | return 0; | ||
| 30 | if (phdr->p_type != PT_MIPS_ABIFLAGS) | ||
| 31 | return 0; | ||
| 32 | if (phdr->p_filesz < sizeof(abiflags)) | ||
| 33 | return -EINVAL; | ||
| 34 | |||
| 35 | ret = kernel_read(elf, phdr->p_offset, (char *)&abiflags, | ||
| 36 | sizeof(abiflags)); | ||
| 37 | if (ret < 0) | ||
| 38 | return ret; | ||
| 39 | if (ret != sizeof(abiflags)) | ||
| 40 | return -EIO; | ||
| 41 | |||
| 42 | /* Record the required FP ABIs for use by mips_check_elf */ | ||
| 43 | if (is_interp) | ||
| 44 | state->interp_fp_abi = abiflags.fp_abi; | ||
| 45 | else | ||
| 46 | state->fp_abi = abiflags.fp_abi; | ||
| 47 | |||
| 48 | return 0; | ||
| 49 | } | ||
| 50 | |||
| 51 | static inline unsigned get_fp_abi(struct elfhdr *ehdr, int in_abi) | ||
| 52 | { | ||
| 53 | /* If the ABI requirement is provided, simply return that */ | ||
| 54 | if (in_abi != -1) | ||
| 55 | return in_abi; | ||
| 56 | |||
| 57 | /* If the EF_MIPS_FP64 flag was set, return MIPS_ABI_FP_64 */ | ||
| 58 | if (ehdr->e_flags & EF_MIPS_FP64) | ||
| 59 | return MIPS_ABI_FP_64; | ||
| 60 | |||
| 61 | /* Default to MIPS_ABI_FP_DOUBLE */ | ||
| 62 | return MIPS_ABI_FP_DOUBLE; | ||
| 63 | } | ||
| 64 | |||
| 65 | int arch_check_elf(void *_ehdr, bool has_interpreter, | ||
| 66 | struct arch_elf_state *state) | ||
| 67 | { | ||
| 68 | struct elfhdr *ehdr = _ehdr; | ||
| 69 | unsigned fp_abi, interp_fp_abi, abi0, abi1; | ||
| 70 | |||
| 71 | /* Ignore non-O32 binaries */ | ||
| 72 | if (config_enabled(CONFIG_64BIT) && | ||
| 73 | (ehdr->e_ident[EI_CLASS] != ELFCLASS32)) | ||
| 74 | return 0; | ||
| 75 | |||
| 76 | fp_abi = get_fp_abi(ehdr, state->fp_abi); | ||
| 77 | |||
| 78 | if (has_interpreter) { | ||
| 79 | interp_fp_abi = get_fp_abi(ehdr, state->interp_fp_abi); | ||
| 80 | |||
| 81 | abi0 = min(fp_abi, interp_fp_abi); | ||
| 82 | abi1 = max(fp_abi, interp_fp_abi); | ||
| 83 | } else { | ||
| 84 | abi0 = abi1 = fp_abi; | ||
| 85 | } | ||
| 86 | |||
| 87 | state->overall_abi = FP_ERROR; | ||
| 88 | |||
| 89 | if (abi0 == abi1) { | ||
| 90 | state->overall_abi = abi0; | ||
| 91 | } else if (abi0 == MIPS_ABI_FP_ANY) { | ||
| 92 | state->overall_abi = abi1; | ||
| 93 | } else if (abi0 == MIPS_ABI_FP_DOUBLE) { | ||
| 94 | switch (abi1) { | ||
| 95 | case MIPS_ABI_FP_XX: | ||
| 96 | state->overall_abi = MIPS_ABI_FP_DOUBLE; | ||
| 97 | break; | ||
| 98 | |||
| 99 | case MIPS_ABI_FP_64A: | ||
| 100 | state->overall_abi = FP_DOUBLE_64A; | ||
| 101 | break; | ||
| 102 | } | ||
| 103 | } else if (abi0 == MIPS_ABI_FP_SINGLE || | ||
| 104 | abi0 == MIPS_ABI_FP_SOFT) { | ||
| 105 | /* Cannot link with other ABIs */ | ||
| 106 | } else if (abi0 == MIPS_ABI_FP_OLD_64) { | ||
| 107 | switch (abi1) { | ||
| 108 | case MIPS_ABI_FP_XX: | ||
| 109 | case MIPS_ABI_FP_64: | ||
| 110 | case MIPS_ABI_FP_64A: | ||
| 111 | state->overall_abi = MIPS_ABI_FP_64; | ||
| 112 | break; | ||
| 113 | } | ||
| 114 | } else if (abi0 == MIPS_ABI_FP_XX || | ||
| 115 | abi0 == MIPS_ABI_FP_64 || | ||
| 116 | abi0 == MIPS_ABI_FP_64A) { | ||
| 117 | state->overall_abi = MIPS_ABI_FP_64; | ||
| 118 | } | ||
| 119 | |||
| 120 | switch (state->overall_abi) { | ||
| 121 | case MIPS_ABI_FP_64: | ||
| 122 | case MIPS_ABI_FP_64A: | ||
| 123 | case FP_DOUBLE_64A: | ||
| 124 | if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT)) | ||
| 125 | return -ELIBBAD; | ||
| 126 | break; | ||
| 127 | |||
| 128 | case FP_ERROR: | ||
| 129 | return -ELIBBAD; | ||
| 130 | } | ||
| 131 | |||
| 132 | return 0; | ||
| 133 | } | ||
| 134 | |||
| 135 | void mips_set_personality_fp(struct arch_elf_state *state) | ||
| 136 | { | ||
| 137 | if (config_enabled(CONFIG_FP32XX_HYBRID_FPRS)) { | ||
| 138 | /* | ||
| 139 | * Use hybrid FPRs for all code which can correctly execute | ||
| 140 | * with that mode. | ||
| 141 | */ | ||
| 142 | switch (state->overall_abi) { | ||
| 143 | case MIPS_ABI_FP_DOUBLE: | ||
| 144 | case MIPS_ABI_FP_SINGLE: | ||
| 145 | case MIPS_ABI_FP_SOFT: | ||
| 146 | case MIPS_ABI_FP_XX: | ||
| 147 | case MIPS_ABI_FP_ANY: | ||
| 148 | /* FR=1, FRE=1 */ | ||
| 149 | clear_thread_flag(TIF_32BIT_FPREGS); | ||
| 150 | set_thread_flag(TIF_HYBRID_FPREGS); | ||
| 151 | return; | ||
| 152 | } | ||
| 153 | } | ||
| 154 | |||
| 155 | switch (state->overall_abi) { | ||
| 156 | case MIPS_ABI_FP_DOUBLE: | ||
| 157 | case MIPS_ABI_FP_SINGLE: | ||
| 158 | case MIPS_ABI_FP_SOFT: | ||
| 159 | /* FR=0 */ | ||
| 160 | set_thread_flag(TIF_32BIT_FPREGS); | ||
| 161 | clear_thread_flag(TIF_HYBRID_FPREGS); | ||
| 162 | break; | ||
| 163 | |||
| 164 | case FP_DOUBLE_64A: | ||
| 165 | /* FR=1, FRE=1 */ | ||
| 166 | clear_thread_flag(TIF_32BIT_FPREGS); | ||
| 167 | set_thread_flag(TIF_HYBRID_FPREGS); | ||
| 168 | break; | ||
| 169 | |||
| 170 | case MIPS_ABI_FP_64: | ||
| 171 | case MIPS_ABI_FP_64A: | ||
| 172 | /* FR=1, FRE=0 */ | ||
| 173 | clear_thread_flag(TIF_32BIT_FPREGS); | ||
| 174 | clear_thread_flag(TIF_HYBRID_FPREGS); | ||
| 175 | break; | ||
| 176 | |||
| 177 | case MIPS_ABI_FP_XX: | ||
| 178 | case MIPS_ABI_FP_ANY: | ||
| 179 | if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT)) | ||
| 180 | set_thread_flag(TIF_32BIT_FPREGS); | ||
| 181 | else | ||
| 182 | clear_thread_flag(TIF_32BIT_FPREGS); | ||
| 183 | |||
| 184 | clear_thread_flag(TIF_HYBRID_FPREGS); | ||
| 185 | break; | ||
| 186 | |||
| 187 | default: | ||
| 188 | case FP_ERROR: | ||
| 189 | BUG(); | ||
| 190 | } | ||
| 191 | } | ||
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index 50b364897dda..a74ec3ae557c 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
| 13 | #include <linux/ioport.h> | 13 | #include <linux/ioport.h> |
| 14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
| 15 | #include <linux/irqdomain.h> | ||
| 15 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| 16 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
| 17 | #include <linux/syscore_ops.h> | 18 | #include <linux/syscore_ops.h> |
| @@ -308,6 +309,19 @@ static struct resource pic2_io_resource = { | |||
| 308 | .flags = IORESOURCE_BUSY | 309 | .flags = IORESOURCE_BUSY |
| 309 | }; | 310 | }; |
| 310 | 311 | ||
| 312 | static int i8259A_irq_domain_map(struct irq_domain *d, unsigned int virq, | ||
| 313 | irq_hw_number_t hw) | ||
| 314 | { | ||
| 315 | irq_set_chip_and_handler(virq, &i8259A_chip, handle_level_irq); | ||
| 316 | irq_set_probe(virq); | ||
| 317 | return 0; | ||
| 318 | } | ||
| 319 | |||
| 320 | static struct irq_domain_ops i8259A_ops = { | ||
| 321 | .map = i8259A_irq_domain_map, | ||
| 322 | .xlate = irq_domain_xlate_onecell, | ||
| 323 | }; | ||
| 324 | |||
| 311 | /* | 325 | /* |
| 312 | * On systems with i8259-style interrupt controllers we assume for | 326 | * On systems with i8259-style interrupt controllers we assume for |
| 313 | * driver compatibility reasons interrupts 0 - 15 to be the i8259 | 327 | * driver compatibility reasons interrupts 0 - 15 to be the i8259 |
| @@ -315,17 +329,17 @@ static struct resource pic2_io_resource = { | |||
| 315 | */ | 329 | */ |
| 316 | void __init init_i8259_irqs(void) | 330 | void __init init_i8259_irqs(void) |
| 317 | { | 331 | { |
| 318 | int i; | 332 | struct irq_domain *domain; |
| 319 | 333 | ||
| 320 | insert_resource(&ioport_resource, &pic1_io_resource); | 334 | insert_resource(&ioport_resource, &pic1_io_resource); |
| 321 | insert_resource(&ioport_resource, &pic2_io_resource); | 335 | insert_resource(&ioport_resource, &pic2_io_resource); |
| 322 | 336 | ||
| 323 | init_8259A(0); | 337 | init_8259A(0); |
| 324 | 338 | ||
| 325 | for (i = I8259A_IRQ_BASE; i < I8259A_IRQ_BASE + 16; i++) { | 339 | domain = irq_domain_add_legacy(NULL, 16, I8259A_IRQ_BASE, 0, |
| 326 | irq_set_chip_and_handler(i, &i8259A_chip, handle_level_irq); | 340 | &i8259A_ops, NULL); |
| 327 | irq_set_probe(i); | 341 | if (!domain) |
| 328 | } | 342 | panic("Failed to add i8259 IRQ domain"); |
| 329 | 343 | ||
| 330 | setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2); | 344 | setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2); |
| 331 | } | 345 | } |
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c deleted file mode 100644 index 9e9d8b9a5b97..000000000000 --- a/arch/mips/kernel/irq-gic.c +++ /dev/null | |||
| @@ -1,402 +0,0 @@ | |||
| 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 | * Copyright (C) 2008 Ralf Baechle (ralf@linux-mips.org) | ||
| 7 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. | ||
| 8 | */ | ||
| 9 | #include <linux/bitmap.h> | ||
| 10 | #include <linux/init.h> | ||
| 11 | #include <linux/smp.h> | ||
| 12 | #include <linux/irq.h> | ||
| 13 | #include <linux/clocksource.h> | ||
| 14 | |||
| 15 | #include <asm/io.h> | ||
| 16 | #include <asm/gic.h> | ||
| 17 | #include <asm/setup.h> | ||
| 18 | #include <asm/traps.h> | ||
| 19 | #include <linux/hardirq.h> | ||
| 20 | #include <asm-generic/bitops/find.h> | ||
| 21 | |||
| 22 | unsigned int gic_frequency; | ||
| 23 | unsigned int gic_present; | ||
| 24 | unsigned long _gic_base; | ||
| 25 | unsigned int gic_irq_base; | ||
| 26 | unsigned int gic_irq_flags[GIC_NUM_INTRS]; | ||
| 27 | |||
| 28 | /* The index into this array is the vector # of the interrupt. */ | ||
| 29 | struct gic_shared_intr_map gic_shared_intr_map[GIC_NUM_INTRS]; | ||
| 30 | |||
| 31 | struct gic_pcpu_mask { | ||
| 32 | DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS); | ||
| 33 | }; | ||
| 34 | |||
| 35 | struct gic_pending_regs { | ||
| 36 | DECLARE_BITMAP(pending, GIC_NUM_INTRS); | ||
| 37 | }; | ||
| 38 | |||
| 39 | struct gic_intrmask_regs { | ||
| 40 | DECLARE_BITMAP(intrmask, GIC_NUM_INTRS); | ||
| 41 | }; | ||
| 42 | |||
| 43 | static struct gic_pcpu_mask pcpu_masks[NR_CPUS]; | ||
| 44 | static struct gic_pending_regs pending_regs[NR_CPUS]; | ||
| 45 | static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; | ||
| 46 | |||
| 47 | #if defined(CONFIG_CSRC_GIC) || defined(CONFIG_CEVT_GIC) | ||
| 48 | cycle_t gic_read_count(void) | ||
| 49 | { | ||
| 50 | unsigned int hi, hi2, lo; | ||
| 51 | |||
| 52 | do { | ||
| 53 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi); | ||
| 54 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), lo); | ||
| 55 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi2); | ||
| 56 | } while (hi2 != hi); | ||
| 57 | |||
| 58 | return (((cycle_t) hi) << 32) + lo; | ||
| 59 | } | ||
| 60 | |||
| 61 | void gic_write_compare(cycle_t cnt) | ||
| 62 | { | ||
| 63 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI), | ||
| 64 | (int)(cnt >> 32)); | ||
| 65 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO), | ||
| 66 | (int)(cnt & 0xffffffff)); | ||
| 67 | } | ||
| 68 | |||
| 69 | void gic_write_cpu_compare(cycle_t cnt, int cpu) | ||
| 70 | { | ||
| 71 | unsigned long flags; | ||
| 72 | |||
| 73 | local_irq_save(flags); | ||
| 74 | |||
| 75 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), cpu); | ||
| 76 | GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_HI), | ||
| 77 | (int)(cnt >> 32)); | ||
| 78 | GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_LO), | ||
| 79 | (int)(cnt & 0xffffffff)); | ||
| 80 | |||
| 81 | local_irq_restore(flags); | ||
| 82 | } | ||
| 83 | |||
| 84 | cycle_t gic_read_compare(void) | ||
| 85 | { | ||
| 86 | unsigned int hi, lo; | ||
| 87 | |||
| 88 | GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI), hi); | ||
| 89 | GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO), lo); | ||
| 90 | |||
| 91 | return (((cycle_t) hi) << 32) + lo; | ||
| 92 | } | ||
| 93 | #endif | ||
| 94 | |||
| 95 | unsigned int gic_get_timer_pending(void) | ||
| 96 | { | ||
| 97 | unsigned int vpe_pending; | ||
| 98 | |||
| 99 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0); | ||
| 100 | GICREAD(GIC_REG(VPE_OTHER, GIC_VPE_PEND), vpe_pending); | ||
| 101 | return (vpe_pending & GIC_VPE_PEND_TIMER_MSK); | ||
| 102 | } | ||
| 103 | |||
| 104 | void gic_bind_eic_interrupt(int irq, int set) | ||
| 105 | { | ||
| 106 | /* Convert irq vector # to hw int # */ | ||
| 107 | irq -= GIC_PIN_TO_VEC_OFFSET; | ||
| 108 | |||
| 109 | /* Set irq to use shadow set */ | ||
| 110 | GICWRITE(GIC_REG_ADDR(VPE_LOCAL, GIC_VPE_EIC_SS(irq)), set); | ||
| 111 | } | ||
| 112 | |||
| 113 | void gic_send_ipi(unsigned int intr) | ||
| 114 | { | ||
| 115 | GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr); | ||
| 116 | } | ||
| 117 | |||
| 118 | static void gic_eic_irq_dispatch(void) | ||
| 119 | { | ||
| 120 | unsigned int cause = read_c0_cause(); | ||
| 121 | int irq; | ||
| 122 | |||
| 123 | irq = (cause & ST0_IM) >> STATUSB_IP2; | ||
| 124 | if (irq == 0) | ||
| 125 | irq = -1; | ||
| 126 | |||
| 127 | if (irq >= 0) | ||
| 128 | do_IRQ(gic_irq_base + irq); | ||
| 129 | else | ||
| 130 | spurious_interrupt(); | ||
| 131 | } | ||
| 132 | |||
| 133 | static void __init vpe_local_setup(unsigned int numvpes) | ||
| 134 | { | ||
| 135 | unsigned long timer_intr = GIC_INT_TMR; | ||
| 136 | unsigned long perf_intr = GIC_INT_PERFCTR; | ||
| 137 | unsigned int vpe_ctl; | ||
| 138 | int i; | ||
| 139 | |||
| 140 | if (cpu_has_veic) { | ||
| 141 | /* | ||
| 142 | * GIC timer interrupt -> CPU HW Int X (vector X+2) -> | ||
| 143 | * map to pin X+2-1 (since GIC adds 1) | ||
| 144 | */ | ||
| 145 | timer_intr += (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET); | ||
| 146 | /* | ||
| 147 | * GIC perfcnt interrupt -> CPU HW Int X (vector X+2) -> | ||
| 148 | * map to pin X+2-1 (since GIC adds 1) | ||
| 149 | */ | ||
| 150 | perf_intr += (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET); | ||
| 151 | } | ||
| 152 | |||
| 153 | /* | ||
| 154 | * Setup the default performance counter timer interrupts | ||
| 155 | * for all VPEs | ||
| 156 | */ | ||
| 157 | for (i = 0; i < numvpes; i++) { | ||
| 158 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); | ||
| 159 | |||
| 160 | /* Are Interrupts locally routable? */ | ||
| 161 | GICREAD(GIC_REG(VPE_OTHER, GIC_VPE_CTL), vpe_ctl); | ||
| 162 | if (vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK) | ||
| 163 | GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP), | ||
| 164 | GIC_MAP_TO_PIN_MSK | timer_intr); | ||
| 165 | if (cpu_has_veic) { | ||
| 166 | set_vi_handler(timer_intr + GIC_PIN_TO_VEC_OFFSET, | ||
| 167 | gic_eic_irq_dispatch); | ||
| 168 | gic_shared_intr_map[timer_intr + GIC_PIN_TO_VEC_OFFSET].local_intr_mask |= GIC_VPE_RMASK_TIMER_MSK; | ||
| 169 | } | ||
| 170 | |||
| 171 | if (vpe_ctl & GIC_VPE_CTL_PERFCNT_RTBL_MSK) | ||
| 172 | GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP), | ||
| 173 | GIC_MAP_TO_PIN_MSK | perf_intr); | ||
| 174 | if (cpu_has_veic) { | ||
| 175 | set_vi_handler(perf_intr + GIC_PIN_TO_VEC_OFFSET, gic_eic_irq_dispatch); | ||
| 176 | gic_shared_intr_map[perf_intr + GIC_PIN_TO_VEC_OFFSET].local_intr_mask |= GIC_VPE_RMASK_PERFCNT_MSK; | ||
| 177 | } | ||
| 178 | } | ||
| 179 | } | ||
| 180 | |||
| 181 | unsigned int gic_compare_int(void) | ||
| 182 | { | ||
| 183 | unsigned int pending; | ||
| 184 | |||
| 185 | GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_PEND), pending); | ||
| 186 | if (pending & GIC_VPE_PEND_CMP_MSK) | ||
| 187 | return 1; | ||
| 188 | else | ||
| 189 | return 0; | ||
| 190 | } | ||
| 191 | |||
| 192 | void gic_get_int_mask(unsigned long *dst, const unsigned long *src) | ||
| 193 | { | ||
| 194 | unsigned int i; | ||
| 195 | unsigned long *pending, *intrmask, *pcpu_mask; | ||
| 196 | unsigned long *pending_abs, *intrmask_abs; | ||
| 197 | |||
| 198 | /* Get per-cpu bitmaps */ | ||
| 199 | pending = pending_regs[smp_processor_id()].pending; | ||
| 200 | intrmask = intrmask_regs[smp_processor_id()].intrmask; | ||
| 201 | pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask; | ||
| 202 | |||
| 203 | pending_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED, | ||
| 204 | GIC_SH_PEND_31_0_OFS); | ||
| 205 | intrmask_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED, | ||
| 206 | GIC_SH_MASK_31_0_OFS); | ||
| 207 | |||
| 208 | for (i = 0; i < BITS_TO_LONGS(GIC_NUM_INTRS); i++) { | ||
| 209 | GICREAD(*pending_abs, pending[i]); | ||
| 210 | GICREAD(*intrmask_abs, intrmask[i]); | ||
| 211 | pending_abs++; | ||
| 212 | intrmask_abs++; | ||
| 213 | } | ||
| 214 | |||
| 215 | bitmap_and(pending, pending, intrmask, GIC_NUM_INTRS); | ||
| 216 | bitmap_and(pending, pending, pcpu_mask, GIC_NUM_INTRS); | ||
| 217 | bitmap_and(dst, src, pending, GIC_NUM_INTRS); | ||
| 218 | } | ||
| 219 | |||
| 220 | unsigned int gic_get_int(void) | ||
| 221 | { | ||
| 222 | DECLARE_BITMAP(interrupts, GIC_NUM_INTRS); | ||
| 223 | |||
| 224 | bitmap_fill(interrupts, GIC_NUM_INTRS); | ||
| 225 | gic_get_int_mask(interrupts, interrupts); | ||
| 226 | |||
| 227 | return find_first_bit(interrupts, GIC_NUM_INTRS); | ||
| 228 | } | ||
| 229 | |||
| 230 | static void gic_mask_irq(struct irq_data *d) | ||
| 231 | { | ||
| 232 | GIC_CLR_INTR_MASK(d->irq - gic_irq_base); | ||
| 233 | } | ||
| 234 | |||
| 235 | static void gic_unmask_irq(struct irq_data *d) | ||
| 236 | { | ||
| 237 | GIC_SET_INTR_MASK(d->irq - gic_irq_base); | ||
| 238 | } | ||
| 239 | |||
| 240 | #ifdef CONFIG_SMP | ||
| 241 | static DEFINE_SPINLOCK(gic_lock); | ||
| 242 | |||
| 243 | static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, | ||
| 244 | bool force) | ||
| 245 | { | ||
| 246 | unsigned int irq = (d->irq - gic_irq_base); | ||
| 247 | cpumask_t tmp = CPU_MASK_NONE; | ||
| 248 | unsigned long flags; | ||
| 249 | int i; | ||
| 250 | |||
| 251 | cpumask_and(&tmp, cpumask, cpu_online_mask); | ||
| 252 | if (cpus_empty(tmp)) | ||
| 253 | return -1; | ||
| 254 | |||
| 255 | /* Assumption : cpumask refers to a single CPU */ | ||
| 256 | spin_lock_irqsave(&gic_lock, flags); | ||
| 257 | |||
| 258 | /* Re-route this IRQ */ | ||
| 259 | GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp)); | ||
| 260 | |||
| 261 | /* Update the pcpu_masks */ | ||
| 262 | for (i = 0; i < NR_CPUS; i++) | ||
| 263 | clear_bit(irq, pcpu_masks[i].pcpu_mask); | ||
| 264 | set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask); | ||
| 265 | |||
| 266 | cpumask_copy(d->affinity, cpumask); | ||
| 267 | spin_unlock_irqrestore(&gic_lock, flags); | ||
| 268 | |||
| 269 | return IRQ_SET_MASK_OK_NOCOPY; | ||
| 270 | } | ||
| 271 | #endif | ||
| 272 | |||
| 273 | static struct irq_chip gic_irq_controller = { | ||
| 274 | .name = "MIPS GIC", | ||
| 275 | .irq_ack = gic_irq_ack, | ||
| 276 | .irq_mask = gic_mask_irq, | ||
| 277 | .irq_mask_ack = gic_mask_irq, | ||
| 278 | .irq_unmask = gic_unmask_irq, | ||
| 279 | .irq_eoi = gic_finish_irq, | ||
| 280 | #ifdef CONFIG_SMP | ||
| 281 | .irq_set_affinity = gic_set_affinity, | ||
| 282 | #endif | ||
| 283 | }; | ||
| 284 | |||
| 285 | static void __init gic_setup_intr(unsigned int intr, unsigned int cpu, | ||
| 286 | unsigned int pin, unsigned int polarity, unsigned int trigtype, | ||
| 287 | unsigned int flags) | ||
| 288 | { | ||
| 289 | struct gic_shared_intr_map *map_ptr; | ||
| 290 | |||
| 291 | /* Setup Intr to Pin mapping */ | ||
| 292 | if (pin & GIC_MAP_TO_NMI_MSK) { | ||
| 293 | int i; | ||
| 294 | |||
| 295 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), pin); | ||
| 296 | /* FIXME: hack to route NMI to all cpu's */ | ||
| 297 | for (i = 0; i < NR_CPUS; i += 32) { | ||
| 298 | GICWRITE(GIC_REG_ADDR(SHARED, | ||
| 299 | GIC_SH_MAP_TO_VPE_REG_OFF(intr, i)), | ||
| 300 | 0xffffffff); | ||
| 301 | } | ||
| 302 | } else { | ||
| 303 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), | ||
| 304 | GIC_MAP_TO_PIN_MSK | pin); | ||
| 305 | /* Setup Intr to CPU mapping */ | ||
| 306 | GIC_SH_MAP_TO_VPE_SMASK(intr, cpu); | ||
| 307 | if (cpu_has_veic) { | ||
| 308 | set_vi_handler(pin + GIC_PIN_TO_VEC_OFFSET, | ||
| 309 | gic_eic_irq_dispatch); | ||
| 310 | map_ptr = &gic_shared_intr_map[pin + GIC_PIN_TO_VEC_OFFSET]; | ||
| 311 | if (map_ptr->num_shared_intr >= GIC_MAX_SHARED_INTR) | ||
| 312 | BUG(); | ||
| 313 | map_ptr->intr_list[map_ptr->num_shared_intr++] = intr; | ||
| 314 | } | ||
| 315 | } | ||
| 316 | |||
| 317 | /* Setup Intr Polarity */ | ||
| 318 | GIC_SET_POLARITY(intr, polarity); | ||
| 319 | |||
| 320 | /* Setup Intr Trigger Type */ | ||
| 321 | GIC_SET_TRIGGER(intr, trigtype); | ||
| 322 | |||
| 323 | /* Init Intr Masks */ | ||
| 324 | GIC_CLR_INTR_MASK(intr); | ||
| 325 | |||
| 326 | /* Initialise per-cpu Interrupt software masks */ | ||
| 327 | set_bit(intr, pcpu_masks[cpu].pcpu_mask); | ||
| 328 | |||
| 329 | if ((flags & GIC_FLAG_TRANSPARENT) && (cpu_has_veic == 0)) | ||
| 330 | GIC_SET_INTR_MASK(intr); | ||
| 331 | if (trigtype == GIC_TRIG_EDGE) | ||
| 332 | gic_irq_flags[intr] |= GIC_TRIG_EDGE; | ||
| 333 | } | ||
| 334 | |||
| 335 | static void __init gic_basic_init(int numintrs, int numvpes, | ||
| 336 | struct gic_intr_map *intrmap, int mapsize) | ||
| 337 | { | ||
| 338 | unsigned int i, cpu; | ||
| 339 | unsigned int pin_offset = 0; | ||
| 340 | |||
| 341 | board_bind_eic_interrupt = &gic_bind_eic_interrupt; | ||
| 342 | |||
| 343 | /* Setup defaults */ | ||
| 344 | for (i = 0; i < numintrs; i++) { | ||
| 345 | GIC_SET_POLARITY(i, GIC_POL_POS); | ||
| 346 | GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL); | ||
| 347 | GIC_CLR_INTR_MASK(i); | ||
| 348 | if (i < GIC_NUM_INTRS) { | ||
| 349 | gic_irq_flags[i] = 0; | ||
| 350 | gic_shared_intr_map[i].num_shared_intr = 0; | ||
| 351 | gic_shared_intr_map[i].local_intr_mask = 0; | ||
| 352 | } | ||
| 353 | } | ||
| 354 | |||
| 355 | /* | ||
| 356 | * In EIC mode, the HW_INT# is offset by (2-1). Need to subtract | ||
| 357 | * one because the GIC will add one (since 0=no intr). | ||
| 358 | */ | ||
| 359 | if (cpu_has_veic) | ||
| 360 | pin_offset = (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET); | ||
| 361 | |||
| 362 | /* Setup specifics */ | ||
| 363 | for (i = 0; i < mapsize; i++) { | ||
| 364 | cpu = intrmap[i].cpunum; | ||
| 365 | if (cpu == GIC_UNUSED) | ||
| 366 | continue; | ||
| 367 | gic_setup_intr(i, | ||
| 368 | intrmap[i].cpunum, | ||
| 369 | intrmap[i].pin + pin_offset, | ||
| 370 | intrmap[i].polarity, | ||
| 371 | intrmap[i].trigtype, | ||
| 372 | intrmap[i].flags); | ||
| 373 | } | ||
| 374 | |||
| 375 | vpe_local_setup(numvpes); | ||
| 376 | } | ||
| 377 | |||
| 378 | void __init gic_init(unsigned long gic_base_addr, | ||
| 379 | unsigned long gic_addrspace_size, | ||
| 380 | struct gic_intr_map *intr_map, unsigned int intr_map_size, | ||
| 381 | unsigned int irqbase) | ||
| 382 | { | ||
| 383 | unsigned int gicconfig; | ||
| 384 | int numvpes, numintrs; | ||
| 385 | |||
| 386 | _gic_base = (unsigned long) ioremap_nocache(gic_base_addr, | ||
| 387 | gic_addrspace_size); | ||
| 388 | gic_irq_base = irqbase; | ||
| 389 | |||
| 390 | GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig); | ||
| 391 | numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >> | ||
| 392 | GIC_SH_CONFIG_NUMINTRS_SHF; | ||
| 393 | numintrs = ((numintrs + 1) * 8); | ||
| 394 | |||
| 395 | numvpes = (gicconfig & GIC_SH_CONFIG_NUMVPES_MSK) >> | ||
| 396 | GIC_SH_CONFIG_NUMVPES_SHF; | ||
| 397 | numvpes = numvpes + 1; | ||
| 398 | |||
| 399 | gic_basic_init(numintrs, numvpes, intr_map, intr_map_size); | ||
| 400 | |||
| 401 | gic_platform_init(numintrs, &gic_irq_controller); | ||
| 402 | } | ||
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c index e498f2b3646a..590c2c980fd3 100644 --- a/arch/mips/kernel/irq_cpu.c +++ b/arch/mips/kernel/irq_cpu.c | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #include <asm/irq_cpu.h> | 36 | #include <asm/irq_cpu.h> |
| 37 | #include <asm/mipsregs.h> | 37 | #include <asm/mipsregs.h> |
| 38 | #include <asm/mipsmtregs.h> | 38 | #include <asm/mipsmtregs.h> |
| 39 | #include <asm/setup.h> | ||
| 39 | 40 | ||
| 40 | static inline void unmask_mips_irq(struct irq_data *d) | 41 | static inline void unmask_mips_irq(struct irq_data *d) |
| 41 | { | 42 | { |
| @@ -94,28 +95,24 @@ static struct irq_chip mips_mt_cpu_irq_controller = { | |||
| 94 | .irq_eoi = unmask_mips_irq, | 95 | .irq_eoi = unmask_mips_irq, |
| 95 | }; | 96 | }; |
| 96 | 97 | ||
| 97 | void __init mips_cpu_irq_init(void) | 98 | asmlinkage void __weak plat_irq_dispatch(void) |
| 98 | { | 99 | { |
| 99 | int irq_base = MIPS_CPU_IRQ_BASE; | 100 | unsigned long pending = read_c0_cause() & read_c0_status() & ST0_IM; |
| 100 | int i; | 101 | int irq; |
| 101 | 102 | ||
| 102 | /* Mask interrupts. */ | 103 | if (!pending) { |
| 103 | clear_c0_status(ST0_IM); | 104 | spurious_interrupt(); |
| 104 | clear_c0_cause(CAUSEF_IP); | 105 | return; |
| 105 | 106 | } | |
| 106 | /* Software interrupts are used for MT/CMT IPI */ | ||
| 107 | for (i = irq_base; i < irq_base + 2; i++) | ||
| 108 | irq_set_chip_and_handler(i, cpu_has_mipsmt ? | ||
| 109 | &mips_mt_cpu_irq_controller : | ||
| 110 | &mips_cpu_irq_controller, | ||
| 111 | handle_percpu_irq); | ||
| 112 | 107 | ||
| 113 | for (i = irq_base + 2; i < irq_base + 8; i++) | 108 | pending >>= CAUSEB_IP; |
| 114 | irq_set_chip_and_handler(i, &mips_cpu_irq_controller, | 109 | while (pending) { |
| 115 | handle_percpu_irq); | 110 | irq = fls(pending) - 1; |
| 111 | do_IRQ(MIPS_CPU_IRQ_BASE + irq); | ||
| 112 | pending &= ~BIT(irq); | ||
| 113 | } | ||
| 116 | } | 114 | } |
| 117 | 115 | ||
| 118 | #ifdef CONFIG_IRQ_DOMAIN | ||
| 119 | static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq, | 116 | static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq, |
| 120 | irq_hw_number_t hw) | 117 | irq_hw_number_t hw) |
| 121 | { | 118 | { |
| @@ -128,6 +125,9 @@ static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq, | |||
| 128 | chip = &mips_cpu_irq_controller; | 125 | chip = &mips_cpu_irq_controller; |
| 129 | } | 126 | } |
| 130 | 127 | ||
| 128 | if (cpu_has_vint) | ||
| 129 | set_vi_handler(hw, plat_irq_dispatch); | ||
| 130 | |||
| 131 | irq_set_chip_and_handler(irq, chip, handle_percpu_irq); | 131 | irq_set_chip_and_handler(irq, chip, handle_percpu_irq); |
| 132 | 132 | ||
| 133 | return 0; | 133 | return 0; |
| @@ -138,8 +138,7 @@ static const struct irq_domain_ops mips_cpu_intc_irq_domain_ops = { | |||
| 138 | .xlate = irq_domain_xlate_onecell, | 138 | .xlate = irq_domain_xlate_onecell, |
| 139 | }; | 139 | }; |
| 140 | 140 | ||
| 141 | int __init mips_cpu_intc_init(struct device_node *of_node, | 141 | static void __init __mips_cpu_irq_init(struct device_node *of_node) |
| 142 | struct device_node *parent) | ||
| 143 | { | 142 | { |
| 144 | struct irq_domain *domain; | 143 | struct irq_domain *domain; |
| 145 | 144 | ||
| @@ -151,7 +150,16 @@ int __init mips_cpu_intc_init(struct device_node *of_node, | |||
| 151 | &mips_cpu_intc_irq_domain_ops, NULL); | 150 | &mips_cpu_intc_irq_domain_ops, NULL); |
| 152 | if (!domain) | 151 | if (!domain) |
| 153 | panic("Failed to add irqdomain for MIPS CPU"); | 152 | panic("Failed to add irqdomain for MIPS CPU"); |
| 153 | } | ||
| 154 | 154 | ||
| 155 | void __init mips_cpu_irq_init(void) | ||
| 156 | { | ||
| 157 | __mips_cpu_irq_init(NULL); | ||
| 158 | } | ||
| 159 | |||
| 160 | int __init mips_cpu_irq_of_init(struct device_node *of_node, | ||
| 161 | struct device_node *parent) | ||
| 162 | { | ||
| 163 | __mips_cpu_irq_init(of_node); | ||
| 155 | return 0; | 164 | return 0; |
| 156 | } | 165 | } |
| 157 | #endif /* CONFIG_IRQ_DOMAIN */ | ||
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c index f76f7a08412d..85bbe9b96759 100644 --- a/arch/mips/kernel/mips-cm.c +++ b/arch/mips/kernel/mips-cm.c | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | void __iomem *mips_cm_base; | 16 | void __iomem *mips_cm_base; |
| 17 | void __iomem *mips_cm_l2sync_base; | 17 | void __iomem *mips_cm_l2sync_base; |
| 18 | 18 | ||
| 19 | phys_t __mips_cm_phys_base(void) | 19 | phys_addr_t __mips_cm_phys_base(void) |
| 20 | { | 20 | { |
| 21 | u32 config3 = read_c0_config3(); | 21 | u32 config3 = read_c0_config3(); |
| 22 | u32 cmgcr; | 22 | u32 cmgcr; |
| @@ -30,10 +30,10 @@ phys_t __mips_cm_phys_base(void) | |||
| 30 | return (cmgcr & MIPS_CMGCRF_BASE) << (36 - 32); | 30 | return (cmgcr & MIPS_CMGCRF_BASE) << (36 - 32); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | phys_t mips_cm_phys_base(void) | 33 | phys_addr_t mips_cm_phys_base(void) |
| 34 | __attribute__((weak, alias("__mips_cm_phys_base"))); | 34 | __attribute__((weak, alias("__mips_cm_phys_base"))); |
| 35 | 35 | ||
| 36 | phys_t __mips_cm_l2sync_phys_base(void) | 36 | phys_addr_t __mips_cm_l2sync_phys_base(void) |
| 37 | { | 37 | { |
| 38 | u32 base_reg; | 38 | u32 base_reg; |
| 39 | 39 | ||
| @@ -49,13 +49,13 @@ phys_t __mips_cm_l2sync_phys_base(void) | |||
| 49 | return mips_cm_phys_base() + MIPS_CM_GCR_SIZE; | 49 | return mips_cm_phys_base() + MIPS_CM_GCR_SIZE; |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | phys_t mips_cm_l2sync_phys_base(void) | 52 | phys_addr_t mips_cm_l2sync_phys_base(void) |
| 53 | __attribute__((weak, alias("__mips_cm_l2sync_phys_base"))); | 53 | __attribute__((weak, alias("__mips_cm_l2sync_phys_base"))); |
| 54 | 54 | ||
| 55 | static void mips_cm_probe_l2sync(void) | 55 | static void mips_cm_probe_l2sync(void) |
| 56 | { | 56 | { |
| 57 | unsigned major_rev; | 57 | unsigned major_rev; |
| 58 | phys_t addr; | 58 | phys_addr_t addr; |
| 59 | 59 | ||
| 60 | /* L2-only sync was introduced with CM major revision 6 */ | 60 | /* L2-only sync was introduced with CM major revision 6 */ |
| 61 | major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR_MSK) >> | 61 | major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR_MSK) >> |
| @@ -78,7 +78,7 @@ static void mips_cm_probe_l2sync(void) | |||
| 78 | 78 | ||
| 79 | int mips_cm_probe(void) | 79 | int mips_cm_probe(void) |
| 80 | { | 80 | { |
| 81 | phys_t addr; | 81 | phys_addr_t addr; |
| 82 | u32 base_reg; | 82 | u32 base_reg; |
| 83 | 83 | ||
| 84 | addr = mips_cm_phys_base(); | 84 | addr = mips_cm_phys_base(); |
diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c index ba473608a347..11964501c4b0 100644 --- a/arch/mips/kernel/mips-cpc.c +++ b/arch/mips/kernel/mips-cpc.c | |||
| @@ -21,7 +21,7 @@ static DEFINE_PER_CPU_ALIGNED(spinlock_t, cpc_core_lock); | |||
| 21 | 21 | ||
| 22 | static DEFINE_PER_CPU_ALIGNED(unsigned long, cpc_core_lock_flags); | 22 | static DEFINE_PER_CPU_ALIGNED(unsigned long, cpc_core_lock_flags); |
| 23 | 23 | ||
| 24 | phys_t __weak mips_cpc_phys_base(void) | 24 | phys_addr_t __weak mips_cpc_phys_base(void) |
| 25 | { | 25 | { |
| 26 | u32 cpc_base; | 26 | u32 cpc_base; |
| 27 | 27 | ||
| @@ -44,7 +44,7 @@ phys_t __weak mips_cpc_phys_base(void) | |||
| 44 | 44 | ||
| 45 | int mips_cpc_probe(void) | 45 | int mips_cpc_probe(void) |
| 46 | { | 46 | { |
| 47 | phys_t addr; | 47 | phys_addr_t addr; |
| 48 | unsigned cpu; | 48 | unsigned cpu; |
| 49 | 49 | ||
| 50 | for_each_possible_cpu(cpu) | 50 | for_each_possible_cpu(cpu) |
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c index 2607c3a4ff7e..17eaf0cf760c 100644 --- a/arch/mips/kernel/mips_ksyms.c +++ b/arch/mips/kernel/mips_ksyms.c | |||
| @@ -24,9 +24,7 @@ extern long __strncpy_from_user_nocheck_asm(char *__to, | |||
| 24 | const char *__from, long __len); | 24 | const char *__from, long __len); |
| 25 | extern long __strncpy_from_user_asm(char *__to, const char *__from, | 25 | extern long __strncpy_from_user_asm(char *__to, const char *__from, |
| 26 | long __len); | 26 | long __len); |
| 27 | extern long __strlen_kernel_nocheck_asm(const char *s); | ||
| 28 | extern long __strlen_kernel_asm(const char *s); | 27 | extern long __strlen_kernel_asm(const char *s); |
| 29 | extern long __strlen_user_nocheck_asm(const char *s); | ||
| 30 | extern long __strlen_user_asm(const char *s); | 28 | extern long __strlen_user_asm(const char *s); |
| 31 | extern long __strnlen_kernel_nocheck_asm(const char *s); | 29 | extern long __strnlen_kernel_nocheck_asm(const char *s); |
| 32 | extern long __strnlen_kernel_asm(const char *s); | 30 | extern long __strnlen_kernel_asm(const char *s); |
| @@ -62,9 +60,7 @@ EXPORT_SYMBOL(__strncpy_from_kernel_nocheck_asm); | |||
| 62 | EXPORT_SYMBOL(__strncpy_from_kernel_asm); | 60 | EXPORT_SYMBOL(__strncpy_from_kernel_asm); |
| 63 | EXPORT_SYMBOL(__strncpy_from_user_nocheck_asm); | 61 | EXPORT_SYMBOL(__strncpy_from_user_nocheck_asm); |
| 64 | EXPORT_SYMBOL(__strncpy_from_user_asm); | 62 | EXPORT_SYMBOL(__strncpy_from_user_asm); |
| 65 | EXPORT_SYMBOL(__strlen_kernel_nocheck_asm); | ||
| 66 | EXPORT_SYMBOL(__strlen_kernel_asm); | 63 | EXPORT_SYMBOL(__strlen_kernel_asm); |
| 67 | EXPORT_SYMBOL(__strlen_user_nocheck_asm); | ||
| 68 | EXPORT_SYMBOL(__strlen_user_asm); | 64 | EXPORT_SYMBOL(__strlen_user_asm); |
| 69 | EXPORT_SYMBOL(__strnlen_kernel_nocheck_asm); | 65 | EXPORT_SYMBOL(__strnlen_kernel_nocheck_asm); |
| 70 | EXPORT_SYMBOL(__strnlen_kernel_asm); | 66 | EXPORT_SYMBOL(__strnlen_kernel_asm); |
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index a8f9cdc6f8b0..9466184d0039 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c | |||
| @@ -561,8 +561,8 @@ static int mipspmu_get_irq(void) | |||
| 561 | IRQF_PERCPU | IRQF_NOBALANCING | IRQF_NO_THREAD, | 561 | IRQF_PERCPU | IRQF_NOBALANCING | IRQF_NO_THREAD, |
| 562 | "mips_perf_pmu", NULL); | 562 | "mips_perf_pmu", NULL); |
| 563 | if (err) { | 563 | if (err) { |
| 564 | pr_warning("Unable to request IRQ%d for MIPS " | 564 | pr_warn("Unable to request IRQ%d for MIPS performance counters!\n", |
| 565 | "performance counters!\n", mipspmu.irq); | 565 | mipspmu.irq); |
| 566 | } | 566 | } |
| 567 | } else if (cp0_perfcount_irq < 0) { | 567 | } else if (cp0_perfcount_irq < 0) { |
| 568 | /* | 568 | /* |
| @@ -572,8 +572,7 @@ static int mipspmu_get_irq(void) | |||
| 572 | perf_irq = mipsxx_pmu_handle_shared_irq; | 572 | perf_irq = mipsxx_pmu_handle_shared_irq; |
| 573 | err = 0; | 573 | err = 0; |
| 574 | } else { | 574 | } else { |
| 575 | pr_warning("The platform hasn't properly defined its " | 575 | pr_warn("The platform hasn't properly defined its interrupt controller\n"); |
| 576 | "interrupt controller.\n"); | ||
| 577 | err = -ENOENT; | 576 | err = -ENOENT; |
| 578 | } | 577 | } |
| 579 | 578 | ||
| @@ -1614,22 +1613,13 @@ init_hw_perf_events(void) | |||
| 1614 | counters = counters_total_to_per_cpu(counters); | 1613 | counters = counters_total_to_per_cpu(counters); |
| 1615 | #endif | 1614 | #endif |
| 1616 | 1615 | ||
| 1617 | #ifdef MSC01E_INT_BASE | 1616 | if (get_c0_perfcount_int) |
| 1618 | if (cpu_has_veic) { | 1617 | irq = get_c0_perfcount_int(); |
| 1619 | /* | 1618 | else if ((cp0_perfcount_irq >= 0) && |
| 1620 | * Using platform specific interrupt controller defines. | 1619 | (cp0_compare_irq != cp0_perfcount_irq)) |
| 1621 | */ | 1620 | irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; |
| 1622 | irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; | 1621 | else |
| 1623 | } else { | 1622 | irq = -1; |
| 1624 | #endif | ||
| 1625 | if ((cp0_perfcount_irq >= 0) && | ||
| 1626 | (cp0_compare_irq != cp0_perfcount_irq)) | ||
| 1627 | irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; | ||
| 1628 | else | ||
| 1629 | irq = -1; | ||
| 1630 | #ifdef MSC01E_INT_BASE | ||
| 1631 | } | ||
| 1632 | #endif | ||
| 1633 | 1623 | ||
| 1634 | mipspmu.map_raw_event = mipsxx_pmu_map_raw_event; | 1624 | mipspmu.map_raw_event = mipsxx_pmu_map_raw_event; |
| 1635 | 1625 | ||
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 636b0745d7c7..eb76434828e8 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
| @@ -42,6 +42,7 @@ | |||
| 42 | #include <asm/isadep.h> | 42 | #include <asm/isadep.h> |
| 43 | #include <asm/inst.h> | 43 | #include <asm/inst.h> |
| 44 | #include <asm/stacktrace.h> | 44 | #include <asm/stacktrace.h> |
| 45 | #include <asm/irq_regs.h> | ||
| 45 | 46 | ||
| 46 | #ifdef CONFIG_HOTPLUG_CPU | 47 | #ifdef CONFIG_HOTPLUG_CPU |
| 47 | void arch_cpu_idle_dead(void) | 48 | void arch_cpu_idle_dead(void) |
| @@ -187,21 +188,21 @@ static inline int is_ra_save_ins(union mips_instruction *ip) | |||
| 187 | */ | 188 | */ |
| 188 | if (mm_insn_16bit(ip->halfword[0])) { | 189 | if (mm_insn_16bit(ip->halfword[0])) { |
| 189 | mmi.word = (ip->halfword[0] << 16); | 190 | mmi.word = (ip->halfword[0] << 16); |
| 190 | return ((mmi.mm16_r5_format.opcode == mm_swsp16_op && | 191 | return (mmi.mm16_r5_format.opcode == mm_swsp16_op && |
| 191 | mmi.mm16_r5_format.rt == 31) || | 192 | mmi.mm16_r5_format.rt == 31) || |
| 192 | (mmi.mm16_m_format.opcode == mm_pool16c_op && | 193 | (mmi.mm16_m_format.opcode == mm_pool16c_op && |
| 193 | mmi.mm16_m_format.func == mm_swm16_op)); | 194 | mmi.mm16_m_format.func == mm_swm16_op); |
| 194 | } | 195 | } |
| 195 | else { | 196 | else { |
| 196 | mmi.halfword[0] = ip->halfword[1]; | 197 | mmi.halfword[0] = ip->halfword[1]; |
| 197 | mmi.halfword[1] = ip->halfword[0]; | 198 | mmi.halfword[1] = ip->halfword[0]; |
| 198 | return ((mmi.mm_m_format.opcode == mm_pool32b_op && | 199 | return (mmi.mm_m_format.opcode == mm_pool32b_op && |
| 199 | mmi.mm_m_format.rd > 9 && | 200 | mmi.mm_m_format.rd > 9 && |
| 200 | mmi.mm_m_format.base == 29 && | 201 | mmi.mm_m_format.base == 29 && |
| 201 | mmi.mm_m_format.func == mm_swm32_func) || | 202 | mmi.mm_m_format.func == mm_swm32_func) || |
| 202 | (mmi.i_format.opcode == mm_sw32_op && | 203 | (mmi.i_format.opcode == mm_sw32_op && |
| 203 | mmi.i_format.rs == 29 && | 204 | mmi.i_format.rs == 29 && |
| 204 | mmi.i_format.rt == 31)); | 205 | mmi.i_format.rt == 31); |
| 205 | } | 206 | } |
| 206 | #else | 207 | #else |
| 207 | /* sw / sd $ra, offset($sp) */ | 208 | /* sw / sd $ra, offset($sp) */ |
| @@ -233,7 +234,7 @@ static inline int is_jump_ins(union mips_instruction *ip) | |||
| 233 | if (ip->r_format.opcode != mm_pool32a_op || | 234 | if (ip->r_format.opcode != mm_pool32a_op || |
| 234 | ip->r_format.func != mm_pool32axf_op) | 235 | ip->r_format.func != mm_pool32axf_op) |
| 235 | return 0; | 236 | return 0; |
| 236 | return (((ip->u_format.uimmediate >> 6) & mm_jalr_op) == mm_jalr_op); | 237 | return ((ip->u_format.uimmediate >> 6) & mm_jalr_op) == mm_jalr_op; |
| 237 | #else | 238 | #else |
| 238 | if (ip->j_format.opcode == j_op) | 239 | if (ip->j_format.opcode == j_op) |
| 239 | return 1; | 240 | return 1; |
| @@ -260,13 +261,13 @@ static inline int is_sp_move_ins(union mips_instruction *ip) | |||
| 260 | union mips_instruction mmi; | 261 | union mips_instruction mmi; |
| 261 | 262 | ||
| 262 | mmi.word = (ip->halfword[0] << 16); | 263 | mmi.word = (ip->halfword[0] << 16); |
| 263 | return ((mmi.mm16_r3_format.opcode == mm_pool16d_op && | 264 | return (mmi.mm16_r3_format.opcode == mm_pool16d_op && |
| 264 | mmi.mm16_r3_format.simmediate && mm_addiusp_func) || | 265 | mmi.mm16_r3_format.simmediate && mm_addiusp_func) || |
| 265 | (mmi.mm16_r5_format.opcode == mm_pool16d_op && | 266 | (mmi.mm16_r5_format.opcode == mm_pool16d_op && |
| 266 | mmi.mm16_r5_format.rt == 29)); | 267 | mmi.mm16_r5_format.rt == 29); |
| 267 | } | 268 | } |
| 268 | return (ip->mm_i_format.opcode == mm_addiu32_op && | 269 | return ip->mm_i_format.opcode == mm_addiu32_op && |
| 269 | ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29); | 270 | ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29; |
| 270 | #else | 271 | #else |
| 271 | /* addiu/daddiu sp,sp,-imm */ | 272 | /* addiu/daddiu sp,sp,-imm */ |
| 272 | if (ip->i_format.rs != 29 || ip->i_format.rt != 29) | 273 | if (ip->i_format.rs != 29 || ip->i_format.rt != 29) |
| @@ -532,3 +533,20 @@ unsigned long arch_align_stack(unsigned long sp) | |||
| 532 | 533 | ||
| 533 | return sp & ALMASK; | 534 | return sp & ALMASK; |
| 534 | } | 535 | } |
| 536 | |||
| 537 | static void arch_dump_stack(void *info) | ||
| 538 | { | ||
| 539 | struct pt_regs *regs; | ||
| 540 | |||
| 541 | regs = get_irq_regs(); | ||
| 542 | |||
| 543 | if (regs) | ||
| 544 | show_regs(regs); | ||
| 545 | |||
| 546 | dump_stack(); | ||
| 547 | } | ||
| 548 | |||
| 549 | void arch_trigger_all_cpu_backtrace(bool include_self) | ||
| 550 | { | ||
| 551 | smp_call_function(arch_dump_stack, NULL, 1); | ||
| 552 | } | ||
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c index 5d39bb85bf35..452d4350ce42 100644 --- a/arch/mips/kernel/prom.c +++ b/arch/mips/kernel/prom.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/debugfs.h> | 16 | #include <linux/debugfs.h> |
| 17 | #include <linux/of.h> | 17 | #include <linux/of.h> |
| 18 | #include <linux/of_fdt.h> | 18 | #include <linux/of_fdt.h> |
| 19 | #include <linux/of_platform.h> | ||
| 19 | 20 | ||
| 20 | #include <asm/page.h> | 21 | #include <asm/page.h> |
| 21 | #include <asm/prom.h> | 22 | #include <asm/prom.h> |
| @@ -54,4 +55,21 @@ void __init __dt_setup_arch(void *bph) | |||
| 54 | 55 | ||
| 55 | mips_set_machine_name(of_flat_dt_get_machine_name()); | 56 | mips_set_machine_name(of_flat_dt_get_machine_name()); |
| 56 | } | 57 | } |
| 58 | |||
| 59 | int __init __dt_register_buses(const char *bus0, const char *bus1) | ||
| 60 | { | ||
| 61 | static struct of_device_id of_ids[3]; | ||
| 62 | |||
| 63 | if (!of_have_populated_dt()) | ||
| 64 | panic("device tree not present"); | ||
| 65 | |||
| 66 | strlcpy(of_ids[0].compatible, bus0, sizeof(of_ids[0].compatible)); | ||
| 67 | strlcpy(of_ids[1].compatible, bus1, sizeof(of_ids[1].compatible)); | ||
| 68 | |||
| 69 | if (of_platform_populate(NULL, of_ids, NULL, NULL)) | ||
| 70 | panic("failed to populate DT"); | ||
| 71 | |||
| 72 | return 0; | ||
| 73 | } | ||
| 74 | |||
| 57 | #endif | 75 | #endif |
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index f3b635f86c39..a8c20afeb813 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c | |||
| @@ -82,14 +82,14 @@ static struct resource data_resource = { .name = "Kernel data", }; | |||
| 82 | 82 | ||
| 83 | static void *detect_magic __initdata = detect_memory_region; | 83 | static void *detect_magic __initdata = detect_memory_region; |
| 84 | 84 | ||
| 85 | void __init add_memory_region(phys_t start, phys_t size, long type) | 85 | void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type) |
| 86 | { | 86 | { |
| 87 | int x = boot_mem_map.nr_map; | 87 | int x = boot_mem_map.nr_map; |
| 88 | int i; | 88 | int i; |
| 89 | 89 | ||
| 90 | /* Sanity check */ | 90 | /* Sanity check */ |
| 91 | if (start + size < start) { | 91 | if (start + size < start) { |
| 92 | pr_warning("Trying to add an invalid memory region, skipped\n"); | 92 | pr_warn("Trying to add an invalid memory region, skipped\n"); |
| 93 | return; | 93 | return; |
| 94 | } | 94 | } |
| 95 | 95 | ||
| @@ -127,10 +127,10 @@ void __init add_memory_region(phys_t start, phys_t size, long type) | |||
| 127 | boot_mem_map.nr_map++; | 127 | boot_mem_map.nr_map++; |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | void __init detect_memory_region(phys_t start, phys_t sz_min, phys_t sz_max) | 130 | void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max) |
| 131 | { | 131 | { |
| 132 | void *dm = &detect_magic; | 132 | void *dm = &detect_magic; |
| 133 | phys_t size; | 133 | phys_addr_t size; |
| 134 | 134 | ||
| 135 | for (size = sz_min; size < sz_max; size <<= 1) { | 135 | for (size = sz_min; size < sz_max; size <<= 1) { |
| 136 | if (!memcmp(dm, dm + size, sizeof(detect_magic))) | 136 | if (!memcmp(dm, dm + size, sizeof(detect_magic))) |
| @@ -545,9 +545,9 @@ static int __init early_parse_elfcorehdr(char *p) | |||
| 545 | early_param("elfcorehdr", early_parse_elfcorehdr); | 545 | early_param("elfcorehdr", early_parse_elfcorehdr); |
| 546 | #endif | 546 | #endif |
| 547 | 547 | ||
| 548 | static void __init arch_mem_addpart(phys_t mem, phys_t end, int type) | 548 | static void __init arch_mem_addpart(phys_addr_t mem, phys_addr_t end, int type) |
| 549 | { | 549 | { |
| 550 | phys_t size; | 550 | phys_addr_t size; |
| 551 | int i; | 551 | int i; |
| 552 | 552 | ||
| 553 | size = end - mem; | 553 | size = end - mem; |
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 16f1e4f2bf3c..545bf11bd2ed 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c | |||
| @@ -530,7 +530,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) | |||
| 530 | struct mips_abi *abi = current->thread.abi; | 530 | struct mips_abi *abi = current->thread.abi; |
| 531 | #ifdef CONFIG_CPU_MICROMIPS | 531 | #ifdef CONFIG_CPU_MICROMIPS |
| 532 | void *vdso; | 532 | void *vdso; |
| 533 | unsigned int tmp = (unsigned int)current->mm->context.vdso; | 533 | unsigned long tmp = (unsigned long)current->mm->context.vdso; |
| 534 | 534 | ||
| 535 | set_isa16_mode(tmp); | 535 | set_isa16_mode(tmp); |
| 536 | vdso = (void *)tmp; | 536 | vdso = (void *)tmp; |
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index 06bb5ed6d80a..b8bd9340c9c7 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <asm/bmips.h> | 35 | #include <asm/bmips.h> |
| 36 | #include <asm/traps.h> | 36 | #include <asm/traps.h> |
| 37 | #include <asm/barrier.h> | 37 | #include <asm/barrier.h> |
| 38 | #include <asm/cpu-features.h> | ||
| 38 | 39 | ||
| 39 | static int __maybe_unused max_cpus = 1; | 40 | static int __maybe_unused max_cpus = 1; |
| 40 | 41 | ||
| @@ -42,6 +43,12 @@ static int __maybe_unused max_cpus = 1; | |||
| 42 | int bmips_smp_enabled = 1; | 43 | int bmips_smp_enabled = 1; |
| 43 | int bmips_cpu_offset; | 44 | int bmips_cpu_offset; |
| 44 | cpumask_t bmips_booted_mask; | 45 | cpumask_t bmips_booted_mask; |
| 46 | unsigned long bmips_tp1_irqs = IE_IRQ1; | ||
| 47 | |||
| 48 | #define RESET_FROM_KSEG0 0x80080800 | ||
| 49 | #define RESET_FROM_KSEG1 0xa0080800 | ||
| 50 | |||
| 51 | static void bmips_set_reset_vec(int cpu, u32 val); | ||
| 45 | 52 | ||
| 46 | #ifdef CONFIG_SMP | 53 | #ifdef CONFIG_SMP |
| 47 | 54 | ||
| @@ -194,6 +201,9 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) | |||
| 194 | pr_info("SMP: Booting CPU%d...\n", cpu); | 201 | pr_info("SMP: Booting CPU%d...\n", cpu); |
| 195 | 202 | ||
| 196 | if (cpumask_test_cpu(cpu, &bmips_booted_mask)) { | 203 | if (cpumask_test_cpu(cpu, &bmips_booted_mask)) { |
| 204 | /* kseg1 might not exist if this CPU enabled XKS01 */ | ||
| 205 | bmips_set_reset_vec(cpu, RESET_FROM_KSEG0); | ||
| 206 | |||
| 197 | switch (current_cpu_type()) { | 207 | switch (current_cpu_type()) { |
| 198 | case CPU_BMIPS4350: | 208 | case CPU_BMIPS4350: |
| 199 | case CPU_BMIPS4380: | 209 | case CPU_BMIPS4380: |
| @@ -203,8 +213,9 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) | |||
| 203 | bmips5000_send_ipi_single(cpu, 0); | 213 | bmips5000_send_ipi_single(cpu, 0); |
| 204 | break; | 214 | break; |
| 205 | } | 215 | } |
| 206 | } | 216 | } else { |
| 207 | else { | 217 | bmips_set_reset_vec(cpu, RESET_FROM_KSEG1); |
| 218 | |||
| 208 | switch (current_cpu_type()) { | 219 | switch (current_cpu_type()) { |
| 209 | case CPU_BMIPS4350: | 220 | case CPU_BMIPS4350: |
| 210 | case CPU_BMIPS4380: | 221 | case CPU_BMIPS4380: |
| @@ -213,17 +224,7 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) | |||
| 213 | set_c0_brcm_cmt_ctrl(0x01); | 224 | set_c0_brcm_cmt_ctrl(0x01); |
| 214 | break; | 225 | break; |
| 215 | case CPU_BMIPS5000: | 226 | case CPU_BMIPS5000: |
| 216 | if (cpu & 0x01) | 227 | write_c0_brcm_action(ACTION_BOOT_THREAD(cpu)); |
| 217 | write_c0_brcm_action(ACTION_BOOT_THREAD(cpu)); | ||
| 218 | else { | ||
| 219 | /* | ||
| 220 | * core N thread 0 was already booted; just | ||
| 221 | * pulse the NMI line | ||
| 222 | */ | ||
| 223 | bmips_write_zscm_reg(0x210, 0xc0000000); | ||
| 224 | udelay(10); | ||
| 225 | bmips_write_zscm_reg(0x210, 0x00); | ||
| 226 | } | ||
| 227 | break; | 228 | break; |
| 228 | } | 229 | } |
| 229 | cpumask_set_cpu(cpu, &bmips_booted_mask); | 230 | cpumask_set_cpu(cpu, &bmips_booted_mask); |
| @@ -235,31 +236,12 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) | |||
| 235 | */ | 236 | */ |
| 236 | static void bmips_init_secondary(void) | 237 | static void bmips_init_secondary(void) |
| 237 | { | 238 | { |
| 238 | /* move NMI vector to kseg0, in case XKS01 is enabled */ | ||
| 239 | |||
| 240 | void __iomem *cbr; | ||
| 241 | unsigned long old_vec; | ||
| 242 | unsigned long relo_vector; | ||
| 243 | int boot_cpu; | ||
| 244 | |||
| 245 | switch (current_cpu_type()) { | 239 | switch (current_cpu_type()) { |
| 246 | case CPU_BMIPS4350: | 240 | case CPU_BMIPS4350: |
| 247 | case CPU_BMIPS4380: | 241 | case CPU_BMIPS4380: |
| 248 | cbr = BMIPS_GET_CBR(); | ||
| 249 | |||
| 250 | boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31)); | ||
| 251 | relo_vector = boot_cpu ? BMIPS_RELO_VECTOR_CONTROL_0 : | ||
| 252 | BMIPS_RELO_VECTOR_CONTROL_1; | ||
| 253 | |||
| 254 | old_vec = __raw_readl(cbr + relo_vector); | ||
| 255 | __raw_writel(old_vec & ~0x20000000, cbr + relo_vector); | ||
| 256 | |||
| 257 | clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0); | 242 | clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0); |
| 258 | break; | 243 | break; |
| 259 | case CPU_BMIPS5000: | 244 | case CPU_BMIPS5000: |
| 260 | write_c0_brcm_bootvec(read_c0_brcm_bootvec() & | ||
| 261 | (smp_processor_id() & 0x01 ? ~0x20000000 : ~0x2000)); | ||
| 262 | |||
| 263 | write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0)); | 245 | write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0)); |
| 264 | break; | 246 | break; |
| 265 | } | 247 | } |
| @@ -276,7 +258,7 @@ static void bmips_smp_finish(void) | |||
| 276 | write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ); | 258 | write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ); |
| 277 | 259 | ||
| 278 | irq_enable_hazard(); | 260 | irq_enable_hazard(); |
| 279 | set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ1 | IE_IRQ5 | ST0_IE); | 261 | set_c0_status(IE_SW0 | IE_SW1 | bmips_tp1_irqs | IE_IRQ5 | ST0_IE); |
| 280 | irq_enable_hazard(); | 262 | irq_enable_hazard(); |
| 281 | } | 263 | } |
| 282 | 264 | ||
| @@ -381,6 +363,7 @@ static int bmips_cpu_disable(void) | |||
| 381 | 363 | ||
| 382 | set_cpu_online(cpu, false); | 364 | set_cpu_online(cpu, false); |
| 383 | cpu_clear(cpu, cpu_callin_map); | 365 | cpu_clear(cpu, cpu_callin_map); |
| 366 | clear_c0_status(IE_IRQ5); | ||
| 384 | 367 | ||
| 385 | local_flush_tlb_all(); | 368 | local_flush_tlb_all(); |
| 386 | local_flush_icache_range(0, ~0); | 369 | local_flush_icache_range(0, ~0); |
| @@ -405,7 +388,8 @@ void __ref play_dead(void) | |||
| 405 | * IRQ handlers; this clears ST0_IE and returns immediately. | 388 | * IRQ handlers; this clears ST0_IE and returns immediately. |
| 406 | */ | 389 | */ |
| 407 | clear_c0_cause(CAUSEF_IV | C_SW0 | C_SW1); | 390 | clear_c0_cause(CAUSEF_IV | C_SW0 | C_SW1); |
| 408 | change_c0_status(IE_IRQ5 | IE_IRQ1 | IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV, | 391 | change_c0_status( |
| 392 | IE_IRQ5 | bmips_tp1_irqs | IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV, | ||
| 409 | IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV); | 393 | IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV); |
| 410 | irq_disable_hazard(); | 394 | irq_disable_hazard(); |
| 411 | 395 | ||
| @@ -473,10 +457,61 @@ static inline void bmips_nmi_handler_setup(void) | |||
| 473 | &bmips_smp_int_vec_end); | 457 | &bmips_smp_int_vec_end); |
| 474 | } | 458 | } |
| 475 | 459 | ||
| 460 | struct reset_vec_info { | ||
| 461 | int cpu; | ||
| 462 | u32 val; | ||
| 463 | }; | ||
| 464 | |||
| 465 | static void bmips_set_reset_vec_remote(void *vinfo) | ||
| 466 | { | ||
| 467 | struct reset_vec_info *info = vinfo; | ||
| 468 | int shift = info->cpu & 0x01 ? 16 : 0; | ||
| 469 | u32 mask = ~(0xffff << shift), val = info->val >> 16; | ||
| 470 | |||
| 471 | preempt_disable(); | ||
| 472 | if (smp_processor_id() > 0) { | ||
| 473 | smp_call_function_single(0, &bmips_set_reset_vec_remote, | ||
| 474 | info, 1); | ||
| 475 | } else { | ||
| 476 | if (info->cpu & 0x02) { | ||
| 477 | /* BMIPS5200 "should" use mask/shift, but it's buggy */ | ||
| 478 | bmips_write_zscm_reg(0xa0, (val << 16) | val); | ||
| 479 | bmips_read_zscm_reg(0xa0); | ||
| 480 | } else { | ||
| 481 | write_c0_brcm_bootvec((read_c0_brcm_bootvec() & mask) | | ||
| 482 | (val << shift)); | ||
| 483 | } | ||
| 484 | } | ||
| 485 | preempt_enable(); | ||
| 486 | } | ||
| 487 | |||
| 488 | static void bmips_set_reset_vec(int cpu, u32 val) | ||
| 489 | { | ||
| 490 | struct reset_vec_info info; | ||
| 491 | |||
| 492 | if (current_cpu_type() == CPU_BMIPS5000) { | ||
| 493 | /* this needs to run from CPU0 (which is always online) */ | ||
| 494 | info.cpu = cpu; | ||
| 495 | info.val = val; | ||
| 496 | bmips_set_reset_vec_remote(&info); | ||
| 497 | } else { | ||
| 498 | void __iomem *cbr = BMIPS_GET_CBR(); | ||
| 499 | |||
| 500 | if (cpu == 0) | ||
| 501 | __raw_writel(val, cbr + BMIPS_RELO_VECTOR_CONTROL_0); | ||
| 502 | else { | ||
| 503 | if (current_cpu_type() != CPU_BMIPS4380) | ||
| 504 | return; | ||
| 505 | __raw_writel(val, cbr + BMIPS_RELO_VECTOR_CONTROL_1); | ||
| 506 | } | ||
| 507 | } | ||
| 508 | __sync(); | ||
| 509 | back_to_back_c0_hazard(); | ||
| 510 | } | ||
| 511 | |||
| 476 | void bmips_ebase_setup(void) | 512 | void bmips_ebase_setup(void) |
| 477 | { | 513 | { |
| 478 | unsigned long new_ebase = ebase; | 514 | unsigned long new_ebase = ebase; |
| 479 | void __iomem __maybe_unused *cbr; | ||
| 480 | 515 | ||
| 481 | BUG_ON(ebase != CKSEG0); | 516 | BUG_ON(ebase != CKSEG0); |
| 482 | 517 | ||
| @@ -496,15 +531,14 @@ void bmips_ebase_setup(void) | |||
| 496 | &bmips_smp_int_vec, 0x80); | 531 | &bmips_smp_int_vec, 0x80); |
| 497 | __sync(); | 532 | __sync(); |
| 498 | return; | 533 | return; |
| 534 | case CPU_BMIPS3300: | ||
| 499 | case CPU_BMIPS4380: | 535 | case CPU_BMIPS4380: |
| 500 | /* | 536 | /* |
| 501 | * 0x8000_0000: reset/NMI (initially in kseg1) | 537 | * 0x8000_0000: reset/NMI (initially in kseg1) |
| 502 | * 0x8000_0400: normal vectors | 538 | * 0x8000_0400: normal vectors |
| 503 | */ | 539 | */ |
| 504 | new_ebase = 0x80000400; | 540 | new_ebase = 0x80000400; |
| 505 | cbr = BMIPS_GET_CBR(); | 541 | bmips_set_reset_vec(0, RESET_FROM_KSEG0); |
| 506 | __raw_writel(0x80080800, cbr + BMIPS_RELO_VECTOR_CONTROL_0); | ||
| 507 | __raw_writel(0xa0080800, cbr + BMIPS_RELO_VECTOR_CONTROL_1); | ||
| 508 | break; | 542 | break; |
| 509 | case CPU_BMIPS5000: | 543 | case CPU_BMIPS5000: |
| 510 | /* | 544 | /* |
| @@ -512,10 +546,8 @@ void bmips_ebase_setup(void) | |||
| 512 | * 0x8000_1000: normal vectors | 546 | * 0x8000_1000: normal vectors |
| 513 | */ | 547 | */ |
| 514 | new_ebase = 0x80001000; | 548 | new_ebase = 0x80001000; |
| 515 | write_c0_brcm_bootvec(0xa0088008); | 549 | bmips_set_reset_vec(0, RESET_FROM_KSEG0); |
| 516 | write_c0_ebase(new_ebase); | 550 | write_c0_ebase(new_ebase); |
| 517 | if (max_cpus > 2) | ||
| 518 | bmips_write_zscm_reg(0xa0, 0xa008a008); | ||
| 519 | break; | 551 | break; |
| 520 | default: | 552 | default: |
| 521 | return; | 553 | return; |
diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c index fc8a51553426..1e0a93c5a3e7 100644 --- a/arch/mips/kernel/smp-cmp.c +++ b/arch/mips/kernel/smp-cmp.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/cpumask.h> | 24 | #include <linux/cpumask.h> |
| 25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
| 26 | #include <linux/compiler.h> | 26 | #include <linux/compiler.h> |
| 27 | #include <linux/irqchip/mips-gic.h> | ||
| 27 | 28 | ||
| 28 | #include <linux/atomic.h> | 29 | #include <linux/atomic.h> |
| 29 | #include <asm/cacheflush.h> | 30 | #include <asm/cacheflush.h> |
| @@ -37,7 +38,6 @@ | |||
| 37 | #include <asm/mipsmtregs.h> | 38 | #include <asm/mipsmtregs.h> |
| 38 | #include <asm/mips_mt.h> | 39 | #include <asm/mips_mt.h> |
| 39 | #include <asm/amon.h> | 40 | #include <asm/amon.h> |
| 40 | #include <asm/gic.h> | ||
| 41 | 41 | ||
| 42 | static void cmp_init_secondary(void) | 42 | static void cmp_init_secondary(void) |
| 43 | { | 43 | { |
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c index e6e16a1d4add..bed7590e475f 100644 --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c | |||
| @@ -9,13 +9,13 @@ | |||
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <linux/io.h> | 11 | #include <linux/io.h> |
| 12 | #include <linux/irqchip/mips-gic.h> | ||
| 12 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
| 13 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
| 14 | #include <linux/smp.h> | 15 | #include <linux/smp.h> |
| 15 | #include <linux/types.h> | 16 | #include <linux/types.h> |
| 16 | 17 | ||
| 17 | #include <asm/bcache.h> | 18 | #include <asm/bcache.h> |
| 18 | #include <asm/gic.h> | ||
| 19 | #include <asm/mips-cm.h> | 19 | #include <asm/mips-cm.h> |
| 20 | #include <asm/mips-cpc.h> | 20 | #include <asm/mips-cpc.h> |
| 21 | #include <asm/mips_mt.h> | 21 | #include <asm/mips_mt.h> |
| @@ -273,8 +273,8 @@ static void cps_init_secondary(void) | |||
| 273 | if (cpu_has_mipsmt) | 273 | if (cpu_has_mipsmt) |
| 274 | dmt(); | 274 | dmt(); |
| 275 | 275 | ||
| 276 | change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | | 276 | change_c0_status(ST0_IM, STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | |
| 277 | STATUSF_IP6 | STATUSF_IP7); | 277 | STATUSF_IP5 | STATUSF_IP6 | STATUSF_IP7); |
| 278 | } | 278 | } |
| 279 | 279 | ||
| 280 | static void cps_smp_finish(void) | 280 | static void cps_smp_finish(void) |
diff --git a/arch/mips/kernel/smp-gic.c b/arch/mips/kernel/smp-gic.c index 3b21a96d1ccb..5f0ab5bcd01e 100644 --- a/arch/mips/kernel/smp-gic.c +++ b/arch/mips/kernel/smp-gic.c | |||
| @@ -12,9 +12,9 @@ | |||
| 12 | * option) any later version. | 12 | * option) any later version. |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | #include <linux/irqchip/mips-gic.h> | ||
| 15 | #include <linux/printk.h> | 16 | #include <linux/printk.h> |
| 16 | 17 | ||
| 17 | #include <asm/gic.h> | ||
| 18 | #include <asm/mips-cpc.h> | 18 | #include <asm/mips-cpc.h> |
| 19 | #include <asm/smp-ops.h> | 19 | #include <asm/smp-ops.h> |
| 20 | 20 | ||
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 21f23add04f4..ad86951b73bd 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
| 22 | #include <linux/cpumask.h> | 22 | #include <linux/cpumask.h> |
| 23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
| 24 | #include <linux/irqchip/mips-gic.h> | ||
| 24 | #include <linux/compiler.h> | 25 | #include <linux/compiler.h> |
| 25 | #include <linux/smp.h> | 26 | #include <linux/smp.h> |
| 26 | 27 | ||
| @@ -34,7 +35,6 @@ | |||
| 34 | #include <asm/mipsregs.h> | 35 | #include <asm/mipsregs.h> |
| 35 | #include <asm/mipsmtregs.h> | 36 | #include <asm/mipsmtregs.h> |
| 36 | #include <asm/mips_mt.h> | 37 | #include <asm/mips_mt.h> |
| 37 | #include <asm/gic.h> | ||
| 38 | 38 | ||
| 39 | static void __init smvp_copy_vpe_config(void) | 39 | static void __init smvp_copy_vpe_config(void) |
| 40 | { | 40 | { |
| @@ -119,7 +119,7 @@ static void vsmp_send_ipi_single(int cpu, unsigned int action) | |||
| 119 | unsigned long flags; | 119 | unsigned long flags; |
| 120 | int vpflags; | 120 | int vpflags; |
| 121 | 121 | ||
| 122 | #ifdef CONFIG_IRQ_GIC | 122 | #ifdef CONFIG_MIPS_GIC |
| 123 | if (gic_present) { | 123 | if (gic_present) { |
| 124 | gic_send_ipi_single(cpu, action); | 124 | gic_send_ipi_single(cpu, action); |
| 125 | return; | 125 | return; |
| @@ -158,7 +158,7 @@ static void vsmp_send_ipi_mask(const struct cpumask *mask, unsigned int action) | |||
| 158 | 158 | ||
| 159 | static void vsmp_init_secondary(void) | 159 | static void vsmp_init_secondary(void) |
| 160 | { | 160 | { |
| 161 | #ifdef CONFIG_IRQ_GIC | 161 | #ifdef CONFIG_MIPS_GIC |
| 162 | /* This is Malta specific: IPI,performance and timer interrupts */ | 162 | /* This is Malta specific: IPI,performance and timer interrupts */ |
| 163 | if (gic_present) | 163 | if (gic_present) |
| 164 | change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | | 164 | change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | |
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 4a4f9dda5658..604b558809c4 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c | |||
| @@ -117,6 +117,7 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new) | |||
| 117 | "2: sc %[tmp], (%[addr]) \n" | 117 | "2: sc %[tmp], (%[addr]) \n" |
| 118 | " beqzl %[tmp], 1b \n" | 118 | " beqzl %[tmp], 1b \n" |
| 119 | "3: \n" | 119 | "3: \n" |
| 120 | " .insn \n" | ||
| 120 | " .section .fixup,\"ax\" \n" | 121 | " .section .fixup,\"ax\" \n" |
| 121 | "4: li %[err], %[efault] \n" | 122 | "4: li %[err], %[efault] \n" |
| 122 | " j 3b \n" | 123 | " j 3b \n" |
| @@ -142,6 +143,7 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new) | |||
| 142 | "2: sc %[tmp], (%[addr]) \n" | 143 | "2: sc %[tmp], (%[addr]) \n" |
| 143 | " bnez %[tmp], 4f \n" | 144 | " bnez %[tmp], 4f \n" |
| 144 | "3: \n" | 145 | "3: \n" |
| 146 | " .insn \n" | ||
| 145 | " .subsection 2 \n" | 147 | " .subsection 2 \n" |
| 146 | "4: b 1b \n" | 148 | "4: b 1b \n" |
| 147 | " .previous \n" | 149 | " .previous \n" |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 22b19c275044..ad3d2031c327 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
| @@ -724,6 +724,50 @@ int process_fpemu_return(int sig, void __user *fault_addr) | |||
| 724 | } | 724 | } |
| 725 | } | 725 | } |
| 726 | 726 | ||
| 727 | static int simulate_fp(struct pt_regs *regs, unsigned int opcode, | ||
| 728 | unsigned long old_epc, unsigned long old_ra) | ||
| 729 | { | ||
| 730 | union mips_instruction inst = { .word = opcode }; | ||
| 731 | void __user *fault_addr = NULL; | ||
| 732 | int sig; | ||
| 733 | |||
| 734 | /* If it's obviously not an FP instruction, skip it */ | ||
| 735 | switch (inst.i_format.opcode) { | ||
| 736 | case cop1_op: | ||
| 737 | case cop1x_op: | ||
| 738 | case lwc1_op: | ||
| 739 | case ldc1_op: | ||
| 740 | case swc1_op: | ||
| 741 | case sdc1_op: | ||
| 742 | break; | ||
| 743 | |||
| 744 | default: | ||
| 745 | return -1; | ||
| 746 | } | ||
| 747 | |||
| 748 | /* | ||
| 749 | * do_ri skipped over the instruction via compute_return_epc, undo | ||
| 750 | * that for the FPU emulator. | ||
| 751 | */ | ||
| 752 | regs->cp0_epc = old_epc; | ||
| 753 | regs->regs[31] = old_ra; | ||
| 754 | |||
| 755 | /* Save the FP context to struct thread_struct */ | ||
| 756 | lose_fpu(1); | ||
| 757 | |||
| 758 | /* Run the emulator */ | ||
| 759 | sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1, | ||
| 760 | &fault_addr); | ||
| 761 | |||
| 762 | /* If something went wrong, signal */ | ||
| 763 | process_fpemu_return(sig, fault_addr); | ||
| 764 | |||
| 765 | /* Restore the hardware register state */ | ||
| 766 | own_fpu(1); | ||
| 767 | |||
| 768 | return 0; | ||
| 769 | } | ||
| 770 | |||
| 727 | /* | 771 | /* |
| 728 | * XXX Delayed fp exceptions when doing a lazy ctx switch XXX | 772 | * XXX Delayed fp exceptions when doing a lazy ctx switch XXX |
| 729 | */ | 773 | */ |
| @@ -1016,6 +1060,9 @@ asmlinkage void do_ri(struct pt_regs *regs) | |||
| 1016 | 1060 | ||
| 1017 | if (status < 0) | 1061 | if (status < 0) |
| 1018 | status = simulate_sync(regs, opcode); | 1062 | status = simulate_sync(regs, opcode); |
| 1063 | |||
| 1064 | if (status < 0) | ||
| 1065 | status = simulate_fp(regs, opcode, old_epc, old31); | ||
| 1019 | } | 1066 | } |
| 1020 | 1067 | ||
| 1021 | if (status < 0) | 1068 | if (status < 0) |
| @@ -1380,12 +1427,19 @@ asmlinkage void do_mcheck(struct pt_regs *regs) | |||
| 1380 | show_regs(regs); | 1427 | show_regs(regs); |
| 1381 | 1428 | ||
| 1382 | if (multi_match) { | 1429 | if (multi_match) { |
| 1383 | printk("Index : %0x\n", read_c0_index()); | 1430 | pr_err("Index : %0x\n", read_c0_index()); |
| 1384 | printk("Pagemask: %0x\n", read_c0_pagemask()); | 1431 | pr_err("Pagemask: %0x\n", read_c0_pagemask()); |
| 1385 | printk("EntryHi : %0*lx\n", field, read_c0_entryhi()); | 1432 | pr_err("EntryHi : %0*lx\n", field, read_c0_entryhi()); |
| 1386 | printk("EntryLo0: %0*lx\n", field, read_c0_entrylo0()); | 1433 | pr_err("EntryLo0: %0*lx\n", field, read_c0_entrylo0()); |
| 1387 | printk("EntryLo1: %0*lx\n", field, read_c0_entrylo1()); | 1434 | pr_err("EntryLo1: %0*lx\n", field, read_c0_entrylo1()); |
| 1388 | printk("\n"); | 1435 | pr_err("Wired : %0x\n", read_c0_wired()); |
| 1436 | pr_err("Pagegrain: %0x\n", read_c0_pagegrain()); | ||
| 1437 | if (cpu_has_htw) { | ||
| 1438 | pr_err("PWField : %0*lx\n", field, read_c0_pwfield()); | ||
| 1439 | pr_err("PWSize : %0*lx\n", field, read_c0_pwsize()); | ||
| 1440 | pr_err("PWCtl : %0x\n", read_c0_pwctl()); | ||
| 1441 | } | ||
| 1442 | pr_err("\n"); | ||
| 1389 | dump_tlb_all(); | 1443 | dump_tlb_all(); |
| 1390 | } | 1444 | } |
| 1391 | 1445 | ||
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c index 0f1af58b036a..ed2a278722a9 100644 --- a/arch/mips/kernel/vdso.c +++ b/arch/mips/kernel/vdso.c | |||
| @@ -16,9 +16,11 @@ | |||
| 16 | #include <linux/elf.h> | 16 | #include <linux/elf.h> |
| 17 | #include <linux/vmalloc.h> | 17 | #include <linux/vmalloc.h> |
| 18 | #include <linux/unistd.h> | 18 | #include <linux/unistd.h> |
| 19 | #include <linux/random.h> | ||
| 19 | 20 | ||
| 20 | #include <asm/vdso.h> | 21 | #include <asm/vdso.h> |
| 21 | #include <asm/uasm.h> | 22 | #include <asm/uasm.h> |
| 23 | #include <asm/processor.h> | ||
| 22 | 24 | ||
| 23 | /* | 25 | /* |
| 24 | * Including <asm/unistd.h> would give use the 64-bit syscall numbers ... | 26 | * Including <asm/unistd.h> would give use the 64-bit syscall numbers ... |
| @@ -67,7 +69,18 @@ subsys_initcall(init_vdso); | |||
| 67 | 69 | ||
| 68 | static unsigned long vdso_addr(unsigned long start) | 70 | static unsigned long vdso_addr(unsigned long start) |
| 69 | { | 71 | { |
| 70 | return STACK_TOP; | 72 | unsigned long offset = 0UL; |
| 73 | |||
| 74 | if (current->flags & PF_RANDOMIZE) { | ||
| 75 | offset = get_random_int(); | ||
| 76 | offset <<= PAGE_SHIFT; | ||
| 77 | if (TASK_IS_32BIT_ADDR) | ||
| 78 | offset &= 0xfffffful; | ||
| 79 | else | ||
| 80 | offset &= 0xffffffful; | ||
| 81 | } | ||
| 82 | |||
| 83 | return STACK_TOP + offset; | ||
| 71 | } | 84 | } |
| 72 | 85 | ||
| 73 | int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) | 86 | int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) |
diff --git a/arch/mips/lantiq/falcon/sysctrl.c b/arch/mips/lantiq/falcon/sysctrl.c index 468ffa043607..7edcd4946fc1 100644 --- a/arch/mips/lantiq/falcon/sysctrl.c +++ b/arch/mips/lantiq/falcon/sysctrl.c | |||
| @@ -49,6 +49,7 @@ | |||
| 49 | 49 | ||
| 50 | /* Activation Status Register */ | 50 | /* Activation Status Register */ |
| 51 | #define ACTS_ASC0_ACT 0x00001000 | 51 | #define ACTS_ASC0_ACT 0x00001000 |
| 52 | #define ACTS_SSC0 0x00002000 | ||
| 52 | #define ACTS_ASC1_ACT 0x00000800 | 53 | #define ACTS_ASC1_ACT 0x00000800 |
| 53 | #define ACTS_I2C_ACT 0x00004000 | 54 | #define ACTS_I2C_ACT 0x00004000 |
| 54 | #define ACTS_P0 0x00010000 | 55 | #define ACTS_P0 0x00010000 |
| @@ -147,12 +148,11 @@ static void falcon_gpe_enable(void) | |||
| 147 | if (status & (1 << (GPPC_OFFSET + 1))) | 148 | if (status & (1 << (GPPC_OFFSET + 1))) |
| 148 | return; | 149 | return; |
| 149 | 150 | ||
| 150 | if (status_r32(STATUS_CONFIG) == 0) | 151 | freq = (status_r32(STATUS_CONFIG) & |
| 152 | GPEFREQ_MASK) >> | ||
| 153 | GPEFREQ_OFFSET; | ||
| 154 | if (freq == 0) | ||
| 151 | freq = 1; /* use 625MHz on unfused chip */ | 155 | freq = 1; /* use 625MHz on unfused chip */ |
| 152 | else | ||
| 153 | freq = (status_r32(STATUS_CONFIG) & | ||
| 154 | GPEFREQ_MASK) >> | ||
| 155 | GPEFREQ_OFFSET; | ||
| 156 | 156 | ||
| 157 | /* apply new frequency */ | 157 | /* apply new frequency */ |
| 158 | sysctl_w32_mask(SYSCTL_SYS1, 7 << (GPPC_OFFSET + 1), | 158 | sysctl_w32_mask(SYSCTL_SYS1, 7 << (GPPC_OFFSET + 1), |
| @@ -260,5 +260,6 @@ void __init ltq_soc_init(void) | |||
| 260 | clkdev_add_sys("1e800600.pad", SYSCTL_SYS1, ACTS_PADCTRL4); | 260 | clkdev_add_sys("1e800600.pad", SYSCTL_SYS1, ACTS_PADCTRL4); |
| 261 | clkdev_add_sys("1e100b00.serial", SYSCTL_SYS1, ACTS_ASC1_ACT); | 261 | clkdev_add_sys("1e100b00.serial", SYSCTL_SYS1, ACTS_ASC1_ACT); |
| 262 | clkdev_add_sys("1e100c00.serial", SYSCTL_SYS1, ACTS_ASC0_ACT); | 262 | clkdev_add_sys("1e100c00.serial", SYSCTL_SYS1, ACTS_ASC0_ACT); |
| 263 | clkdev_add_sys("1e100d00.spi", SYSCTL_SYS1, ACTS_SSC0); | ||
| 263 | clkdev_add_sys("1e200000.i2c", SYSCTL_SYS1, ACTS_I2C_ACT); | 264 | clkdev_add_sys("1e200000.i2c", SYSCTL_SYS1, ACTS_I2C_ACT); |
| 264 | } | 265 | } |
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c index 030568a70ac4..6ab10573490d 100644 --- a/arch/mips/lantiq/irq.c +++ b/arch/mips/lantiq/irq.c | |||
| @@ -70,6 +70,7 @@ static struct resource ltq_eiu_irq[MAX_EIU]; | |||
| 70 | static void __iomem *ltq_icu_membase[MAX_IM]; | 70 | static void __iomem *ltq_icu_membase[MAX_IM]; |
| 71 | static void __iomem *ltq_eiu_membase; | 71 | static void __iomem *ltq_eiu_membase; |
| 72 | static struct irq_domain *ltq_domain; | 72 | static struct irq_domain *ltq_domain; |
| 73 | static int ltq_perfcount_irq; | ||
| 73 | 74 | ||
| 74 | int ltq_eiu_get_irq(int exin) | 75 | int ltq_eiu_get_irq(int exin) |
| 75 | { | 76 | { |
| @@ -378,30 +379,6 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) | |||
| 378 | panic("Failed to remap icu memory"); | 379 | panic("Failed to remap icu memory"); |
| 379 | } | 380 | } |
| 380 | 381 | ||
| 381 | /* the external interrupts are optional and xway only */ | ||
| 382 | eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu-xway"); | ||
| 383 | if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) { | ||
| 384 | /* find out how many external irq sources we have */ | ||
| 385 | exin_avail = of_irq_count(eiu_node); | ||
| 386 | |||
| 387 | if (exin_avail > MAX_EIU) | ||
| 388 | exin_avail = MAX_EIU; | ||
| 389 | |||
| 390 | ret = of_irq_to_resource_table(eiu_node, | ||
| 391 | ltq_eiu_irq, exin_avail); | ||
| 392 | if (ret != exin_avail) | ||
| 393 | panic("failed to load external irq resources"); | ||
| 394 | |||
| 395 | if (request_mem_region(res.start, resource_size(&res), | ||
| 396 | res.name) < 0) | ||
| 397 | pr_err("Failed to request eiu memory"); | ||
| 398 | |||
| 399 | ltq_eiu_membase = ioremap_nocache(res.start, | ||
| 400 | resource_size(&res)); | ||
| 401 | if (!ltq_eiu_membase) | ||
| 402 | panic("Failed to remap eiu memory"); | ||
| 403 | } | ||
| 404 | |||
| 405 | /* turn off all irqs by default */ | 382 | /* turn off all irqs by default */ |
| 406 | for (i = 0; i < MAX_IM; i++) { | 383 | for (i = 0; i < MAX_IM; i++) { |
| 407 | /* make sure all irqs are turned off by default */ | 384 | /* make sure all irqs are turned off by default */ |
| @@ -449,7 +426,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) | |||
| 449 | #endif | 426 | #endif |
| 450 | 427 | ||
| 451 | /* tell oprofile which irq to use */ | 428 | /* tell oprofile which irq to use */ |
| 452 | cp0_perfcount_irq = irq_create_mapping(ltq_domain, LTQ_PERF_IRQ); | 429 | ltq_perfcount_irq = irq_create_mapping(ltq_domain, LTQ_PERF_IRQ); |
| 453 | 430 | ||
| 454 | /* | 431 | /* |
| 455 | * if the timer irq is not one of the mips irqs we need to | 432 | * if the timer irq is not one of the mips irqs we need to |
| @@ -458,9 +435,38 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) | |||
| 458 | if (MIPS_CPU_TIMER_IRQ != 7) | 435 | if (MIPS_CPU_TIMER_IRQ != 7) |
| 459 | irq_create_mapping(ltq_domain, MIPS_CPU_TIMER_IRQ); | 436 | irq_create_mapping(ltq_domain, MIPS_CPU_TIMER_IRQ); |
| 460 | 437 | ||
| 438 | /* the external interrupts are optional and xway only */ | ||
| 439 | eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu-xway"); | ||
| 440 | if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) { | ||
| 441 | /* find out how many external irq sources we have */ | ||
| 442 | exin_avail = of_irq_count(eiu_node); | ||
| 443 | |||
| 444 | if (exin_avail > MAX_EIU) | ||
| 445 | exin_avail = MAX_EIU; | ||
| 446 | |||
| 447 | ret = of_irq_to_resource_table(eiu_node, | ||
| 448 | ltq_eiu_irq, exin_avail); | ||
| 449 | if (ret != exin_avail) | ||
| 450 | panic("failed to load external irq resources"); | ||
| 451 | |||
| 452 | if (request_mem_region(res.start, resource_size(&res), | ||
| 453 | res.name) < 0) | ||
| 454 | pr_err("Failed to request eiu memory"); | ||
| 455 | |||
| 456 | ltq_eiu_membase = ioremap_nocache(res.start, | ||
| 457 | resource_size(&res)); | ||
| 458 | if (!ltq_eiu_membase) | ||
| 459 | panic("Failed to remap eiu memory"); | ||
| 460 | } | ||
| 461 | |||
| 461 | return 0; | 462 | return 0; |
| 462 | } | 463 | } |
| 463 | 464 | ||
| 465 | int get_c0_perfcount_int(void) | ||
| 466 | { | ||
| 467 | return ltq_perfcount_irq; | ||
| 468 | } | ||
| 469 | |||
| 464 | unsigned int get_c0_compare_int(void) | 470 | unsigned int get_c0_compare_int(void) |
| 465 | { | 471 | { |
| 466 | return MIPS_CPU_TIMER_IRQ; | 472 | return MIPS_CPU_TIMER_IRQ; |
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c index 7447d322d14e..39ab3e786e59 100644 --- a/arch/mips/lantiq/prom.c +++ b/arch/mips/lantiq/prom.c | |||
| @@ -36,6 +36,11 @@ const char *get_system_type(void) | |||
| 36 | return soc_info.sys_type; | 36 | return soc_info.sys_type; |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | int ltq_soc_type(void) | ||
| 40 | { | ||
| 41 | return soc_info.type; | ||
| 42 | } | ||
| 43 | |||
| 39 | void prom_free_prom_memory(void) | 44 | void prom_free_prom_memory(void) |
| 40 | { | 45 | { |
| 41 | } | 46 | } |
| @@ -72,6 +77,8 @@ void __init plat_mem_setup(void) | |||
| 72 | * parsed resulting in our memory appearing | 77 | * parsed resulting in our memory appearing |
| 73 | */ | 78 | */ |
| 74 | __dt_setup_arch(__dtb_start); | 79 | __dt_setup_arch(__dtb_start); |
| 80 | |||
| 81 | strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); | ||
| 75 | } | 82 | } |
| 76 | 83 | ||
| 77 | void __init device_tree_init(void) | 84 | void __init device_tree_init(void) |
| @@ -97,16 +104,7 @@ void __init prom_init(void) | |||
| 97 | 104 | ||
| 98 | int __init plat_of_setup(void) | 105 | int __init plat_of_setup(void) |
| 99 | { | 106 | { |
| 100 | static struct of_device_id of_ids[3]; | 107 | return __dt_register_buses(soc_info.compatible, "simple-bus"); |
| 101 | |||
| 102 | if (!of_have_populated_dt()) | ||
| 103 | panic("device tree not present"); | ||
| 104 | |||
| 105 | strlcpy(of_ids[0].compatible, soc_info.compatible, | ||
| 106 | sizeof(of_ids[0].compatible)); | ||
| 107 | strncpy(of_ids[1].compatible, "simple-bus", | ||
| 108 | sizeof(of_ids[1].compatible)); | ||
| 109 | return of_platform_populate(NULL, of_ids, NULL, NULL); | ||
| 110 | } | 108 | } |
| 111 | 109 | ||
| 112 | arch_initcall(plat_of_setup); | 110 | arch_initcall(plat_of_setup); |
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile index 087497d97357..a2edc538f477 100644 --- a/arch/mips/lantiq/xway/Makefile +++ b/arch/mips/lantiq/xway/Makefile | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o dcdc.o | 1 | obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o dcdc.o |
| 2 | 2 | ||
| 3 | obj-y += vmmc.o | ||
| 4 | |||
| 3 | obj-$(CONFIG_XRX200_PHY_FW) += xrx200_phy_fw.o | 5 | obj-$(CONFIG_XRX200_PHY_FW) += xrx200_phy_fw.o |
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c index 1fa0f175357e..fe68f9ae47c1 100644 --- a/arch/mips/lantiq/xway/reset.c +++ b/arch/mips/lantiq/xway/reset.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
| 15 | #include <linux/of_address.h> | 15 | #include <linux/of_address.h> |
| 16 | #include <linux/of_platform.h> | 16 | #include <linux/of_platform.h> |
| 17 | #include <linux/reset-controller.h> | ||
| 17 | 18 | ||
| 18 | #include <asm/reboot.h> | 19 | #include <asm/reboot.h> |
| 19 | 20 | ||
| @@ -113,10 +114,77 @@ void ltq_reset_once(unsigned int module, ulong u) | |||
| 113 | ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ); | 114 | ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ); |
| 114 | } | 115 | } |
| 115 | 116 | ||
| 117 | static int ltq_assert_device(struct reset_controller_dev *rcdev, | ||
| 118 | unsigned long id) | ||
| 119 | { | ||
| 120 | u32 val; | ||
| 121 | |||
| 122 | if (id < 8) | ||
| 123 | return -1; | ||
| 124 | |||
| 125 | val = ltq_rcu_r32(RCU_RST_REQ); | ||
| 126 | val |= BIT(id); | ||
| 127 | ltq_rcu_w32(val, RCU_RST_REQ); | ||
| 128 | |||
| 129 | return 0; | ||
| 130 | } | ||
| 131 | |||
| 132 | static int ltq_deassert_device(struct reset_controller_dev *rcdev, | ||
| 133 | unsigned long id) | ||
| 134 | { | ||
| 135 | u32 val; | ||
| 136 | |||
| 137 | if (id < 8) | ||
| 138 | return -1; | ||
| 139 | |||
| 140 | val = ltq_rcu_r32(RCU_RST_REQ); | ||
| 141 | val &= ~BIT(id); | ||
| 142 | ltq_rcu_w32(val, RCU_RST_REQ); | ||
| 143 | |||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | |||
| 147 | static int ltq_reset_device(struct reset_controller_dev *rcdev, | ||
| 148 | unsigned long id) | ||
| 149 | { | ||
| 150 | ltq_assert_device(rcdev, id); | ||
| 151 | return ltq_deassert_device(rcdev, id); | ||
| 152 | } | ||
| 153 | |||
| 154 | static struct reset_control_ops reset_ops = { | ||
| 155 | .reset = ltq_reset_device, | ||
| 156 | .assert = ltq_assert_device, | ||
| 157 | .deassert = ltq_deassert_device, | ||
| 158 | }; | ||
| 159 | |||
| 160 | static struct reset_controller_dev reset_dev = { | ||
| 161 | .ops = &reset_ops, | ||
| 162 | .owner = THIS_MODULE, | ||
| 163 | .nr_resets = 32, | ||
| 164 | .of_reset_n_cells = 1, | ||
| 165 | }; | ||
| 166 | |||
| 167 | void ltq_rst_init(void) | ||
| 168 | { | ||
| 169 | reset_dev.of_node = of_find_compatible_node(NULL, NULL, | ||
| 170 | "lantiq,xway-reset"); | ||
| 171 | if (!reset_dev.of_node) | ||
| 172 | pr_err("Failed to find reset controller node"); | ||
| 173 | else | ||
| 174 | reset_controller_register(&reset_dev); | ||
| 175 | } | ||
| 176 | |||
| 116 | static void ltq_machine_restart(char *command) | 177 | static void ltq_machine_restart(char *command) |
| 117 | { | 178 | { |
| 179 | u32 val = ltq_rcu_r32(RCU_RST_REQ); | ||
| 180 | |||
| 181 | if (of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200")) | ||
| 182 | val |= RCU_RD_GPHY1_XRX200 | RCU_RD_GPHY0_XRX200; | ||
| 183 | |||
| 184 | val |= RCU_RD_SRST; | ||
| 185 | |||
| 118 | local_irq_disable(); | 186 | local_irq_disable(); |
| 119 | ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | RCU_RD_SRST, RCU_RST_REQ); | 187 | ltq_rcu_w32(val, RCU_RST_REQ); |
| 120 | unreachable(); | 188 | unreachable(); |
| 121 | } | 189 | } |
| 122 | 190 | ||
diff --git a/arch/mips/lantiq/xway/vmmc.c b/arch/mips/lantiq/xway/vmmc.c new file mode 100644 index 000000000000..696cd57f6f13 --- /dev/null +++ b/arch/mips/lantiq/xway/vmmc.c | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2012 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/module.h> | ||
| 10 | #include <linux/of_platform.h> | ||
| 11 | #include <linux/of_gpio.h> | ||
| 12 | #include <linux/dma-mapping.h> | ||
| 13 | |||
| 14 | #include <lantiq_soc.h> | ||
| 15 | |||
| 16 | static unsigned int *cp1_base; | ||
| 17 | |||
| 18 | unsigned int *ltq_get_cp1_base(void) | ||
| 19 | { | ||
| 20 | if (!cp1_base) | ||
| 21 | panic("no cp1 base was set\n"); | ||
| 22 | |||
| 23 | return cp1_base; | ||
| 24 | } | ||
| 25 | EXPORT_SYMBOL(ltq_get_cp1_base); | ||
| 26 | |||
| 27 | static int vmmc_probe(struct platform_device *pdev) | ||
| 28 | { | ||
| 29 | #define CP1_SIZE (1 << 20) | ||
| 30 | int gpio_count; | ||
| 31 | dma_addr_t dma; | ||
| 32 | |||
| 33 | cp1_base = | ||
| 34 | (void *) CPHYSADDR(dma_alloc_coherent(NULL, CP1_SIZE, | ||
| 35 | &dma, GFP_ATOMIC)); | ||
| 36 | |||
| 37 | gpio_count = of_gpio_count(pdev->dev.of_node); | ||
| 38 | while (gpio_count > 0) { | ||
| 39 | enum of_gpio_flags flags; | ||
| 40 | int gpio = of_get_gpio_flags(pdev->dev.of_node, | ||
| 41 | --gpio_count, &flags); | ||
| 42 | if (gpio_request(gpio, "vmmc-relay")) | ||
| 43 | continue; | ||
| 44 | dev_info(&pdev->dev, "requested GPIO %d\n", gpio); | ||
| 45 | gpio_direction_output(gpio, | ||
| 46 | (flags & OF_GPIO_ACTIVE_LOW) ? (0) : (1)); | ||
| 47 | } | ||
| 48 | |||
| 49 | dev_info(&pdev->dev, "reserved %dMB at 0x%p", CP1_SIZE >> 20, cp1_base); | ||
| 50 | |||
| 51 | return 0; | ||
| 52 | } | ||
| 53 | |||
| 54 | static const struct of_device_id vmmc_match[] = { | ||
| 55 | { .compatible = "lantiq,vmmc-xway" }, | ||
| 56 | {}, | ||
| 57 | }; | ||
| 58 | MODULE_DEVICE_TABLE(of, vmmc_match); | ||
| 59 | |||
| 60 | static struct platform_driver vmmc_driver = { | ||
| 61 | .probe = vmmc_probe, | ||
| 62 | .driver = { | ||
| 63 | .name = "lantiq,vmmc", | ||
| 64 | .owner = THIS_MODULE, | ||
| 65 | .of_match_table = vmmc_match, | ||
| 66 | }, | ||
| 67 | }; | ||
| 68 | |||
| 69 | module_platform_driver(vmmc_driver); | ||
diff --git a/arch/mips/lantiq/xway/xrx200_phy_fw.c b/arch/mips/lantiq/xway/xrx200_phy_fw.c index d4d9d31f152e..7c1e54c6a36c 100644 --- a/arch/mips/lantiq/xway/xrx200_phy_fw.c +++ b/arch/mips/lantiq/xway/xrx200_phy_fw.c | |||
| @@ -24,7 +24,28 @@ static dma_addr_t xway_gphy_load(struct platform_device *pdev) | |||
| 24 | void *fw_addr; | 24 | void *fw_addr; |
| 25 | size_t size; | 25 | size_t size; |
| 26 | 26 | ||
| 27 | if (of_property_read_string(pdev->dev.of_node, "firmware", &fw_name)) { | 27 | if (of_get_property(pdev->dev.of_node, "firmware1", NULL) || |
| 28 | of_get_property(pdev->dev.of_node, "firmware2", NULL)) { | ||
| 29 | switch (ltq_soc_type()) { | ||
| 30 | case SOC_TYPE_VR9: | ||
| 31 | if (of_property_read_string(pdev->dev.of_node, | ||
| 32 | "firmware1", &fw_name)) { | ||
| 33 | dev_err(&pdev->dev, | ||
| 34 | "failed to load firmware filename\n"); | ||
| 35 | return 0; | ||
| 36 | } | ||
| 37 | break; | ||
| 38 | case SOC_TYPE_VR9_2: | ||
| 39 | if (of_property_read_string(pdev->dev.of_node, | ||
| 40 | "firmware2", &fw_name)) { | ||
| 41 | dev_err(&pdev->dev, | ||
| 42 | "failed to load firmware filename\n"); | ||
| 43 | return 0; | ||
| 44 | } | ||
| 45 | break; | ||
| 46 | } | ||
| 47 | } else if (of_property_read_string(pdev->dev.of_node, | ||
| 48 | "firmware", &fw_name)) { | ||
| 28 | dev_err(&pdev->dev, "failed to load firmware filename\n"); | 49 | dev_err(&pdev->dev, "failed to load firmware filename\n"); |
| 29 | return 0; | 50 | return 0; |
| 30 | } | 51 | } |
diff --git a/arch/mips/lib/iomap.c b/arch/mips/lib/iomap.c index e3acb2dad33a..8e7e378ce51c 100644 --- a/arch/mips/lib/iomap.c +++ b/arch/mips/lib/iomap.c | |||
| @@ -97,14 +97,14 @@ EXPORT_SYMBOL(iowrite32be); | |||
| 97 | 97 | ||
| 98 | /* | 98 | /* |
| 99 | * These are the "repeat MMIO read/write" functions. | 99 | * These are the "repeat MMIO read/write" functions. |
| 100 | * Note the "__raw" accesses, since we don't want to | 100 | * Note the "__mem" accesses, since we want to convert |
| 101 | * convert to CPU byte order. We write in "IO byte | 101 | * to CPU byte order if the host bus happens to not match the |
| 102 | * order" (we also don't have IO barriers). | 102 | * endianness of PCI/ISA (see mach-generic/mangle-port.h). |
| 103 | */ | 103 | */ |
| 104 | static inline void mmio_insb(void __iomem *addr, u8 *dst, int count) | 104 | static inline void mmio_insb(void __iomem *addr, u8 *dst, int count) |
| 105 | { | 105 | { |
| 106 | while (--count >= 0) { | 106 | while (--count >= 0) { |
| 107 | u8 data = __raw_readb(addr); | 107 | u8 data = __mem_readb(addr); |
| 108 | *dst = data; | 108 | *dst = data; |
| 109 | dst++; | 109 | dst++; |
| 110 | } | 110 | } |
| @@ -113,7 +113,7 @@ static inline void mmio_insb(void __iomem *addr, u8 *dst, int count) | |||
| 113 | static inline void mmio_insw(void __iomem *addr, u16 *dst, int count) | 113 | static inline void mmio_insw(void __iomem *addr, u16 *dst, int count) |
| 114 | { | 114 | { |
| 115 | while (--count >= 0) { | 115 | while (--count >= 0) { |
| 116 | u16 data = __raw_readw(addr); | 116 | u16 data = __mem_readw(addr); |
| 117 | *dst = data; | 117 | *dst = data; |
| 118 | dst++; | 118 | dst++; |
| 119 | } | 119 | } |
| @@ -122,7 +122,7 @@ static inline void mmio_insw(void __iomem *addr, u16 *dst, int count) | |||
| 122 | static inline void mmio_insl(void __iomem *addr, u32 *dst, int count) | 122 | static inline void mmio_insl(void __iomem *addr, u32 *dst, int count) |
| 123 | { | 123 | { |
| 124 | while (--count >= 0) { | 124 | while (--count >= 0) { |
| 125 | u32 data = __raw_readl(addr); | 125 | u32 data = __mem_readl(addr); |
| 126 | *dst = data; | 126 | *dst = data; |
| 127 | dst++; | 127 | dst++; |
| 128 | } | 128 | } |
| @@ -131,7 +131,7 @@ static inline void mmio_insl(void __iomem *addr, u32 *dst, int count) | |||
| 131 | static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count) | 131 | static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count) |
| 132 | { | 132 | { |
| 133 | while (--count >= 0) { | 133 | while (--count >= 0) { |
| 134 | __raw_writeb(*src, addr); | 134 | __mem_writeb(*src, addr); |
| 135 | src++; | 135 | src++; |
| 136 | } | 136 | } |
| 137 | } | 137 | } |
| @@ -139,7 +139,7 @@ static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count) | |||
| 139 | static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count) | 139 | static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count) |
| 140 | { | 140 | { |
| 141 | while (--count >= 0) { | 141 | while (--count >= 0) { |
| 142 | __raw_writew(*src, addr); | 142 | __mem_writew(*src, addr); |
| 143 | src++; | 143 | src++; |
| 144 | } | 144 | } |
| 145 | } | 145 | } |
| @@ -147,7 +147,7 @@ static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count) | |||
| 147 | static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count) | 147 | static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count) |
| 148 | { | 148 | { |
| 149 | while (--count >= 0) { | 149 | while (--count >= 0) { |
| 150 | __raw_writel(*src, addr); | 150 | __mem_writel(*src, addr); |
| 151 | src++; | 151 | src++; |
| 152 | } | 152 | } |
| 153 | } | 153 | } |
diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S index 7b0e5462ca51..c8fe6b1968fb 100644 --- a/arch/mips/lib/memset.S +++ b/arch/mips/lib/memset.S | |||
| @@ -114,8 +114,7 @@ | |||
| 114 | R10KCBARRIER(0(ra)) | 114 | R10KCBARRIER(0(ra)) |
| 115 | #ifdef __MIPSEB__ | 115 | #ifdef __MIPSEB__ |
| 116 | EX(LONG_S_L, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */ | 116 | EX(LONG_S_L, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */ |
| 117 | #endif | 117 | #else |
| 118 | #ifdef __MIPSEL__ | ||
| 119 | EX(LONG_S_R, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */ | 118 | EX(LONG_S_R, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */ |
| 120 | #endif | 119 | #endif |
| 121 | PTR_SUBU a0, t0 /* long align ptr */ | 120 | PTR_SUBU a0, t0 /* long align ptr */ |
| @@ -164,8 +163,7 @@ | |||
| 164 | R10KCBARRIER(0(ra)) | 163 | R10KCBARRIER(0(ra)) |
| 165 | #ifdef __MIPSEB__ | 164 | #ifdef __MIPSEB__ |
| 166 | EX(LONG_S_R, a1, -1(a0), .Llast_fixup\@) | 165 | EX(LONG_S_R, a1, -1(a0), .Llast_fixup\@) |
| 167 | #endif | 166 | #else |
| 168 | #ifdef __MIPSEL__ | ||
| 169 | EX(LONG_S_L, a1, -1(a0), .Llast_fixup\@) | 167 | EX(LONG_S_L, a1, -1(a0), .Llast_fixup\@) |
| 170 | #endif | 168 | #endif |
| 171 | 1: jr ra | 169 | 1: jr ra |
diff --git a/arch/mips/lib/mips-atomic.c b/arch/mips/lib/mips-atomic.c index 57bcdaf1f1c8..be777d9a3f85 100644 --- a/arch/mips/lib/mips-atomic.c +++ b/arch/mips/lib/mips-atomic.c | |||
| @@ -42,15 +42,11 @@ notrace void arch_local_irq_disable(void) | |||
| 42 | __asm__ __volatile__( | 42 | __asm__ __volatile__( |
| 43 | " .set push \n" | 43 | " .set push \n" |
| 44 | " .set noat \n" | 44 | " .set noat \n" |
| 45 | #if defined(CONFIG_CPU_MIPSR2) | ||
| 46 | /* see irqflags.h for inline function */ | ||
| 47 | #else | ||
| 48 | " mfc0 $1,$12 \n" | 45 | " mfc0 $1,$12 \n" |
| 49 | " ori $1,0x1f \n" | 46 | " ori $1,0x1f \n" |
| 50 | " xori $1,0x1f \n" | 47 | " xori $1,0x1f \n" |
| 51 | " .set noreorder \n" | 48 | " .set noreorder \n" |
| 52 | " mtc0 $1,$12 \n" | 49 | " mtc0 $1,$12 \n" |
| 53 | #endif | ||
| 54 | " " __stringify(__irq_disable_hazard) " \n" | 50 | " " __stringify(__irq_disable_hazard) " \n" |
| 55 | " .set pop \n" | 51 | " .set pop \n" |
| 56 | : /* no outputs */ | 52 | : /* no outputs */ |
| @@ -72,15 +68,11 @@ notrace unsigned long arch_local_irq_save(void) | |||
| 72 | " .set push \n" | 68 | " .set push \n" |
| 73 | " .set reorder \n" | 69 | " .set reorder \n" |
| 74 | " .set noat \n" | 70 | " .set noat \n" |
| 75 | #if defined(CONFIG_CPU_MIPSR2) | ||
| 76 | /* see irqflags.h for inline function */ | ||
| 77 | #else | ||
| 78 | " mfc0 %[flags], $12 \n" | 71 | " mfc0 %[flags], $12 \n" |
| 79 | " ori $1, %[flags], 0x1f \n" | 72 | " ori $1, %[flags], 0x1f \n" |
| 80 | " xori $1, 0x1f \n" | 73 | " xori $1, 0x1f \n" |
| 81 | " .set noreorder \n" | 74 | " .set noreorder \n" |
| 82 | " mtc0 $1, $12 \n" | 75 | " mtc0 $1, $12 \n" |
| 83 | #endif | ||
| 84 | " " __stringify(__irq_disable_hazard) " \n" | 76 | " " __stringify(__irq_disable_hazard) " \n" |
| 85 | " .set pop \n" | 77 | " .set pop \n" |
| 86 | : [flags] "=r" (flags) | 78 | : [flags] "=r" (flags) |
| @@ -103,18 +95,12 @@ notrace void arch_local_irq_restore(unsigned long flags) | |||
| 103 | " .set push \n" | 95 | " .set push \n" |
| 104 | " .set noreorder \n" | 96 | " .set noreorder \n" |
| 105 | " .set noat \n" | 97 | " .set noat \n" |
| 106 | #if defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) | ||
| 107 | /* see irqflags.h for inline function */ | ||
| 108 | #elif defined(CONFIG_CPU_MIPSR2) | ||
| 109 | /* see irqflags.h for inline function */ | ||
| 110 | #else | ||
| 111 | " mfc0 $1, $12 \n" | 98 | " mfc0 $1, $12 \n" |
| 112 | " andi %[flags], 1 \n" | 99 | " andi %[flags], 1 \n" |
| 113 | " ori $1, 0x1f \n" | 100 | " ori $1, 0x1f \n" |
| 114 | " xori $1, 0x1f \n" | 101 | " xori $1, 0x1f \n" |
| 115 | " or %[flags], $1 \n" | 102 | " or %[flags], $1 \n" |
| 116 | " mtc0 %[flags], $12 \n" | 103 | " mtc0 %[flags], $12 \n" |
| 117 | #endif | ||
| 118 | " " __stringify(__irq_disable_hazard) " \n" | 104 | " " __stringify(__irq_disable_hazard) " \n" |
| 119 | " .set pop \n" | 105 | " .set pop \n" |
| 120 | : [flags] "=r" (__tmp1) | 106 | : [flags] "=r" (__tmp1) |
| @@ -136,18 +122,12 @@ notrace void __arch_local_irq_restore(unsigned long flags) | |||
| 136 | " .set push \n" | 122 | " .set push \n" |
| 137 | " .set noreorder \n" | 123 | " .set noreorder \n" |
| 138 | " .set noat \n" | 124 | " .set noat \n" |
| 139 | #if defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) | ||
| 140 | /* see irqflags.h for inline function */ | ||
| 141 | #elif defined(CONFIG_CPU_MIPSR2) | ||
| 142 | /* see irqflags.h for inline function */ | ||
| 143 | #else | ||
| 144 | " mfc0 $1, $12 \n" | 125 | " mfc0 $1, $12 \n" |
| 145 | " andi %[flags], 1 \n" | 126 | " andi %[flags], 1 \n" |
| 146 | " ori $1, 0x1f \n" | 127 | " ori $1, 0x1f \n" |
| 147 | " xori $1, 0x1f \n" | 128 | " xori $1, 0x1f \n" |
| 148 | " or %[flags], $1 \n" | 129 | " or %[flags], $1 \n" |
| 149 | " mtc0 %[flags], $12 \n" | 130 | " mtc0 %[flags], $12 \n" |
| 150 | #endif | ||
| 151 | " " __stringify(__irq_disable_hazard) " \n" | 131 | " " __stringify(__irq_disable_hazard) " \n" |
| 152 | " .set pop \n" | 132 | " .set pop \n" |
| 153 | : [flags] "=r" (__tmp1) | 133 | : [flags] "=r" (__tmp1) |
diff --git a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c index 1ef365ab3cd3..975a13855116 100644 --- a/arch/mips/lib/r3k_dump_tlb.c +++ b/arch/mips/lib/r3k_dump_tlb.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include <linux/mm.h> | 9 | #include <linux/mm.h> |
| 10 | 10 | ||
| 11 | #include <asm/mipsregs.h> | 11 | #include <asm/mipsregs.h> |
| 12 | #include <asm/mmu_context.h> | ||
| 12 | #include <asm/page.h> | 13 | #include <asm/page.h> |
| 13 | #include <asm/pgtable.h> | 14 | #include <asm/pgtable.h> |
| 14 | #include <asm/tlbdebug.h> | 15 | #include <asm/tlbdebug.h> |
| @@ -21,7 +22,7 @@ static void dump_tlb(int first, int last) | |||
| 21 | unsigned int asid; | 22 | unsigned int asid; |
| 22 | unsigned long entryhi, entrylo0; | 23 | unsigned long entryhi, entrylo0; |
| 23 | 24 | ||
| 24 | asid = read_c0_entryhi() & 0xfc0; | 25 | asid = read_c0_entryhi() & ASID_MASK; |
| 25 | 26 | ||
| 26 | for (i = first; i <= last; i++) { | 27 | for (i = first; i <= last; i++) { |
| 27 | write_c0_index(i<<8); | 28 | write_c0_index(i<<8); |
| @@ -34,8 +35,8 @@ static void dump_tlb(int first, int last) | |||
| 34 | entrylo0 = read_c0_entrylo0(); | 35 | entrylo0 = read_c0_entrylo0(); |
| 35 | 36 | ||
| 36 | /* Unused entries have a virtual address of KSEG0. */ | 37 | /* Unused entries have a virtual address of KSEG0. */ |
| 37 | if ((entryhi & 0xfffff000) != 0x80000000 | 38 | if ((entryhi & PAGE_MASK) != KSEG0 |
| 38 | && (entryhi & 0xfc0) == asid) { | 39 | && (entryhi & ASID_MASK) == asid) { |
| 39 | /* | 40 | /* |
| 40 | * Only print entries in use | 41 | * Only print entries in use |
| 41 | */ | 42 | */ |
| @@ -43,8 +44,8 @@ static void dump_tlb(int first, int last) | |||
| 43 | 44 | ||
| 44 | printk("va=%08lx asid=%08lx" | 45 | printk("va=%08lx asid=%08lx" |
| 45 | " [pa=%06lx n=%d d=%d v=%d g=%d]", | 46 | " [pa=%06lx n=%d d=%d v=%d g=%d]", |
| 46 | (entryhi & 0xfffff000), | 47 | entryhi & PAGE_MASK, |
| 47 | entryhi & 0xfc0, | 48 | entryhi & ASID_MASK, |
| 48 | entrylo0 & PAGE_MASK, | 49 | entrylo0 & PAGE_MASK, |
| 49 | (entrylo0 & (1 << 11)) ? 1 : 0, | 50 | (entrylo0 & (1 << 11)) ? 1 : 0, |
| 50 | (entrylo0 & (1 << 10)) ? 1 : 0, | 51 | (entrylo0 & (1 << 10)) ? 1 : 0, |
diff --git a/arch/mips/lib/strlen_user.S b/arch/mips/lib/strlen_user.S index bef65c98df59..929bbacd697e 100644 --- a/arch/mips/lib/strlen_user.S +++ b/arch/mips/lib/strlen_user.S | |||
| @@ -28,7 +28,6 @@ LEAF(__strlen_\func\()_asm) | |||
| 28 | and v0, a0 | 28 | and v0, a0 |
| 29 | bnez v0, .Lfault\@ | 29 | bnez v0, .Lfault\@ |
| 30 | 30 | ||
| 31 | FEXPORT(__strlen_\func\()_nocheck_asm) | ||
| 32 | move v0, a0 | 31 | move v0, a0 |
| 33 | .ifeqs "\func", "kernel" | 32 | .ifeqs "\func", "kernel" |
| 34 | 1: EX(lbu, v1, (v0), .Lfault\@) | 33 | 1: EX(lbu, v1, (v0), .Lfault\@) |
| @@ -48,9 +47,7 @@ FEXPORT(__strlen_\func\()_nocheck_asm) | |||
| 48 | #ifndef CONFIG_EVA | 47 | #ifndef CONFIG_EVA |
| 49 | /* Set aliases */ | 48 | /* Set aliases */ |
| 50 | .global __strlen_user_asm | 49 | .global __strlen_user_asm |
| 51 | .global __strlen_user_nocheck_asm | ||
| 52 | .set __strlen_user_asm, __strlen_kernel_asm | 50 | .set __strlen_user_asm, __strlen_kernel_asm |
| 53 | .set __strlen_user_nocheck_asm, __strlen_kernel_nocheck_asm | ||
| 54 | #endif | 51 | #endif |
| 55 | 52 | ||
| 56 | __BUILD_STRLEN_ASM kernel | 53 | __BUILD_STRLEN_ASM kernel |
diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig index 1b91fc6a921b..156de85b82cd 100644 --- a/arch/mips/loongson/Kconfig +++ b/arch/mips/loongson/Kconfig | |||
| @@ -86,6 +86,7 @@ config LOONGSON_MACH3X | |||
| 86 | select LOONGSON_MC146818 | 86 | select LOONGSON_MC146818 |
| 87 | select ZONE_DMA32 | 87 | select ZONE_DMA32 |
| 88 | select LEFI_FIRMWARE_INTERFACE | 88 | select LEFI_FIRMWARE_INTERFACE |
| 89 | select PHYS48_TO_HT40 | ||
| 89 | help | 90 | help |
| 90 | Generic Loongson 3 family machines utilize the 3A/3B revision | 91 | Generic Loongson 3 family machines utilize the 3A/3B revision |
| 91 | of Loongson processor and RS780/SBX00 chipset. | 92 | of Loongson processor and RS780/SBX00 chipset. |
| @@ -107,6 +108,18 @@ config CS5536_MFGPT | |||
| 107 | 108 | ||
| 108 | If unsure, say Yes. | 109 | If unsure, say Yes. |
| 109 | 110 | ||
| 111 | config RS780_HPET | ||
| 112 | bool "RS780/SBX00 HPET Timer" | ||
| 113 | depends on LOONGSON_MACH3X | ||
| 114 | select MIPS_EXTERNAL_TIMER | ||
| 115 | help | ||
| 116 | This option enables the hpet timer of AMD RS780/SBX00. | ||
| 117 | |||
| 118 | If you want to enable the Loongson3 CPUFreq Driver, Please enable | ||
| 119 | this option at first, otherwise, You will get wrong system time. | ||
| 120 | |||
| 121 | If unsure, say Yes. | ||
| 122 | |||
| 110 | config LOONGSON_SUSPEND | 123 | config LOONGSON_SUSPEND |
| 111 | bool | 124 | bool |
| 112 | default y | 125 | default y |
| @@ -131,6 +144,10 @@ config SWIOTLB | |||
| 131 | select NEED_SG_DMA_LENGTH | 144 | select NEED_SG_DMA_LENGTH |
| 132 | select NEED_DMA_MAP_STATE | 145 | select NEED_DMA_MAP_STATE |
| 133 | 146 | ||
| 147 | config PHYS48_TO_HT40 | ||
| 148 | bool | ||
| 149 | default y if CPU_LOONGSON3 | ||
| 150 | |||
| 134 | config LOONGSON_MC146818 | 151 | config LOONGSON_MC146818 |
| 135 | bool | 152 | bool |
| 136 | default n | 153 | default n |
diff --git a/arch/mips/loongson/common/cs5536/cs5536_pci.c b/arch/mips/loongson/common/cs5536/cs5536_pci.c index 81bed9d18061..b739723205f8 100644 --- a/arch/mips/loongson/common/cs5536/cs5536_pci.c +++ b/arch/mips/loongson/common/cs5536/cs5536_pci.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | */ | 21 | */ |
| 22 | 22 | ||
| 23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
| 24 | #include <cs5536/cs5536_pci.h> | ||
| 24 | #include <cs5536/cs5536_vsm.h> | 25 | #include <cs5536/cs5536_vsm.h> |
| 25 | 26 | ||
| 26 | enum { | 27 | enum { |
| @@ -35,21 +36,21 @@ enum { | |||
| 35 | }; | 36 | }; |
| 36 | 37 | ||
| 37 | static const cs5536_pci_vsm_write vsm_conf_write[] = { | 38 | static const cs5536_pci_vsm_write vsm_conf_write[] = { |
| 38 | [CS5536_ISA_FUNC] pci_isa_write_reg, | 39 | [CS5536_ISA_FUNC] = pci_isa_write_reg, |
| 39 | [reserved_func] NULL, | 40 | [reserved_func] = NULL, |
| 40 | [CS5536_IDE_FUNC] pci_ide_write_reg, | 41 | [CS5536_IDE_FUNC] = pci_ide_write_reg, |
| 41 | [CS5536_ACC_FUNC] pci_acc_write_reg, | 42 | [CS5536_ACC_FUNC] = pci_acc_write_reg, |
| 42 | [CS5536_OHCI_FUNC] pci_ohci_write_reg, | 43 | [CS5536_OHCI_FUNC] = pci_ohci_write_reg, |
| 43 | [CS5536_EHCI_FUNC] pci_ehci_write_reg, | 44 | [CS5536_EHCI_FUNC] = pci_ehci_write_reg, |
| 44 | }; | 45 | }; |
| 45 | 46 | ||
| 46 | static const cs5536_pci_vsm_read vsm_conf_read[] = { | 47 | static const cs5536_pci_vsm_read vsm_conf_read[] = { |
| 47 | [CS5536_ISA_FUNC] pci_isa_read_reg, | 48 | [CS5536_ISA_FUNC] = pci_isa_read_reg, |
| 48 | [reserved_func] NULL, | 49 | [reserved_func] = NULL, |
| 49 | [CS5536_IDE_FUNC] pci_ide_read_reg, | 50 | [CS5536_IDE_FUNC] = pci_ide_read_reg, |
| 50 | [CS5536_ACC_FUNC] pci_acc_read_reg, | 51 | [CS5536_ACC_FUNC] = pci_acc_read_reg, |
| 51 | [CS5536_OHCI_FUNC] pci_ohci_read_reg, | 52 | [CS5536_OHCI_FUNC] = pci_ohci_read_reg, |
| 52 | [CS5536_EHCI_FUNC] pci_ehci_read_reg, | 53 | [CS5536_EHCI_FUNC] = pci_ehci_read_reg, |
| 53 | }; | 54 | }; |
| 54 | 55 | ||
| 55 | /* | 56 | /* |
diff --git a/arch/mips/loongson/common/dma-swiotlb.c b/arch/mips/loongson/common/dma-swiotlb.c index c2be01f91575..2c6b989c1bc4 100644 --- a/arch/mips/loongson/common/dma-swiotlb.c +++ b/arch/mips/loongson/common/dma-swiotlb.c | |||
| @@ -105,11 +105,25 @@ static int loongson_dma_set_mask(struct device *dev, u64 mask) | |||
| 105 | 105 | ||
| 106 | dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) | 106 | dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) |
| 107 | { | 107 | { |
| 108 | long nid; | ||
| 109 | #ifdef CONFIG_PHYS48_TO_HT40 | ||
| 110 | /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from | ||
| 111 | * Loongson-3's 48bit address space and embed it into 40bit */ | ||
| 112 | nid = (paddr >> 44) & 0x3; | ||
| 113 | paddr = ((nid << 44) ^ paddr) | (nid << 37); | ||
| 114 | #endif | ||
| 108 | return paddr; | 115 | return paddr; |
| 109 | } | 116 | } |
| 110 | 117 | ||
| 111 | phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) | 118 | phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) |
| 112 | { | 119 | { |
| 120 | long nid; | ||
| 121 | #ifdef CONFIG_PHYS48_TO_HT40 | ||
| 122 | /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from | ||
| 123 | * Loongson-3's 48bit address space and embed it into 40bit */ | ||
| 124 | nid = (daddr >> 37) & 0x3; | ||
| 125 | daddr = ((nid << 37) ^ daddr) | (nid << 44); | ||
| 126 | #endif | ||
| 113 | return daddr; | 127 | return daddr; |
| 114 | } | 128 | } |
| 115 | 129 | ||
diff --git a/arch/mips/loongson/common/early_printk.c b/arch/mips/loongson/common/early_printk.c index ced461b39069..6ca632e529dc 100644 --- a/arch/mips/loongson/common/early_printk.c +++ b/arch/mips/loongson/common/early_printk.c | |||
| @@ -30,7 +30,7 @@ void prom_putchar(char c) | |||
| 30 | int timeout; | 30 | int timeout; |
| 31 | unsigned char *uart_base; | 31 | unsigned char *uart_base; |
| 32 | 32 | ||
| 33 | uart_base = (unsigned char *)_loongson_uart_base; | 33 | uart_base = (unsigned char *)_loongson_uart_base[0]; |
| 34 | timeout = 1024; | 34 | timeout = 1024; |
| 35 | 35 | ||
| 36 | while (((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) && | 36 | while (((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) && |
diff --git a/arch/mips/loongson/common/env.c b/arch/mips/loongson/common/env.c index f15228550a22..045ea3d47c87 100644 --- a/arch/mips/loongson/common/env.c +++ b/arch/mips/loongson/common/env.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <asm/bootinfo.h> | 21 | #include <asm/bootinfo.h> |
| 22 | #include <loongson.h> | 22 | #include <loongson.h> |
| 23 | #include <boot_param.h> | 23 | #include <boot_param.h> |
| 24 | #include <workarounds.h> | ||
| 24 | 25 | ||
| 25 | u32 cpu_clock_freq; | 26 | u32 cpu_clock_freq; |
| 26 | EXPORT_SYMBOL(cpu_clock_freq); | 27 | EXPORT_SYMBOL(cpu_clock_freq); |
| @@ -31,7 +32,6 @@ u64 loongson_chipcfg[MAX_PACKAGES] = {0xffffffffbfc00180}; | |||
| 31 | u64 loongson_freqctrl[MAX_PACKAGES]; | 32 | u64 loongson_freqctrl[MAX_PACKAGES]; |
| 32 | 33 | ||
| 33 | unsigned long long smp_group[4]; | 34 | unsigned long long smp_group[4]; |
| 34 | int cpuhotplug_workaround = 0; | ||
| 35 | 35 | ||
| 36 | #define parse_even_earlier(res, option, p) \ | 36 | #define parse_even_earlier(res, option, p) \ |
| 37 | do { \ | 37 | do { \ |
| @@ -67,6 +67,7 @@ void __init prom_init_env(void) | |||
| 67 | #else | 67 | #else |
| 68 | struct boot_params *boot_p; | 68 | struct boot_params *boot_p; |
| 69 | struct loongson_params *loongson_p; | 69 | struct loongson_params *loongson_p; |
| 70 | struct system_loongson *esys; | ||
| 70 | struct efi_cpuinfo_loongson *ecpu; | 71 | struct efi_cpuinfo_loongson *ecpu; |
| 71 | struct irq_source_routing_table *eirq_source; | 72 | struct irq_source_routing_table *eirq_source; |
| 72 | 73 | ||
| @@ -74,6 +75,8 @@ void __init prom_init_env(void) | |||
| 74 | boot_p = (struct boot_params *)fw_arg2; | 75 | boot_p = (struct boot_params *)fw_arg2; |
| 75 | loongson_p = &(boot_p->efi.smbios.lp); | 76 | loongson_p = &(boot_p->efi.smbios.lp); |
| 76 | 77 | ||
| 78 | esys = (struct system_loongson *) | ||
| 79 | ((u64)loongson_p + loongson_p->system_offset); | ||
| 77 | ecpu = (struct efi_cpuinfo_loongson *) | 80 | ecpu = (struct efi_cpuinfo_loongson *) |
| 78 | ((u64)loongson_p + loongson_p->cpu_offset); | 81 | ((u64)loongson_p + loongson_p->cpu_offset); |
| 79 | eirq_source = (struct irq_source_routing_table *) | 82 | eirq_source = (struct irq_source_routing_table *) |
| @@ -95,6 +98,7 @@ void __init prom_init_env(void) | |||
| 95 | loongson_chipcfg[2] = 0x900020001fe00180; | 98 | loongson_chipcfg[2] = 0x900020001fe00180; |
| 96 | loongson_chipcfg[3] = 0x900030001fe00180; | 99 | loongson_chipcfg[3] = 0x900030001fe00180; |
| 97 | loongson_sysconf.ht_control_base = 0x90000EFDFB000000; | 100 | loongson_sysconf.ht_control_base = 0x90000EFDFB000000; |
| 101 | loongson_sysconf.workarounds = WORKAROUND_CPUFREQ; | ||
| 98 | } else if (ecpu->cputype == Loongson_3B) { | 102 | } else if (ecpu->cputype == Loongson_3B) { |
| 99 | loongson_sysconf.cores_per_node = 4; /* One chip has 2 nodes */ | 103 | loongson_sysconf.cores_per_node = 4; /* One chip has 2 nodes */ |
| 100 | loongson_sysconf.cores_per_package = 8; | 104 | loongson_sysconf.cores_per_package = 8; |
| @@ -111,7 +115,7 @@ void __init prom_init_env(void) | |||
| 111 | loongson_freqctrl[2] = 0x900040001fe001d0; | 115 | loongson_freqctrl[2] = 0x900040001fe001d0; |
| 112 | loongson_freqctrl[3] = 0x900060001fe001d0; | 116 | loongson_freqctrl[3] = 0x900060001fe001d0; |
| 113 | loongson_sysconf.ht_control_base = 0x90001EFDFB000000; | 117 | loongson_sysconf.ht_control_base = 0x90001EFDFB000000; |
| 114 | cpuhotplug_workaround = 1; | 118 | loongson_sysconf.workarounds = WORKAROUND_CPUHOTPLUG; |
| 115 | } else { | 119 | } else { |
| 116 | loongson_sysconf.cores_per_node = 1; | 120 | loongson_sysconf.cores_per_node = 1; |
| 117 | loongson_sysconf.cores_per_package = 1; | 121 | loongson_sysconf.cores_per_package = 1; |
| @@ -119,6 +123,8 @@ void __init prom_init_env(void) | |||
| 119 | } | 123 | } |
| 120 | 124 | ||
| 121 | loongson_sysconf.nr_cpus = ecpu->nr_cpus; | 125 | loongson_sysconf.nr_cpus = ecpu->nr_cpus; |
| 126 | loongson_sysconf.boot_cpu_id = ecpu->cpu_startup_core_id; | ||
| 127 | loongson_sysconf.reserved_cpus_mask = ecpu->reserved_cores_mask; | ||
| 122 | if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0) | 128 | if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0) |
| 123 | loongson_sysconf.nr_cpus = NR_CPUS; | 129 | loongson_sysconf.nr_cpus = NR_CPUS; |
| 124 | loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus + | 130 | loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus + |
| @@ -141,6 +147,24 @@ void __init prom_init_env(void) | |||
| 141 | pr_debug("Shutdown Addr: %llx, Restart Addr: %llx, VBIOS Addr: %llx\n", | 147 | pr_debug("Shutdown Addr: %llx, Restart Addr: %llx, VBIOS Addr: %llx\n", |
| 142 | loongson_sysconf.poweroff_addr, loongson_sysconf.restart_addr, | 148 | loongson_sysconf.poweroff_addr, loongson_sysconf.restart_addr, |
| 143 | loongson_sysconf.vgabios_addr); | 149 | loongson_sysconf.vgabios_addr); |
| 150 | |||
| 151 | memset(loongson_sysconf.ecname, 0, 32); | ||
| 152 | if (esys->has_ec) | ||
| 153 | memcpy(loongson_sysconf.ecname, esys->ec_name, 32); | ||
| 154 | loongson_sysconf.workarounds |= esys->workarounds; | ||
| 155 | |||
| 156 | loongson_sysconf.nr_uarts = esys->nr_uarts; | ||
| 157 | if (esys->nr_uarts < 1 || esys->nr_uarts > MAX_UARTS) | ||
| 158 | loongson_sysconf.nr_uarts = 1; | ||
| 159 | memcpy(loongson_sysconf.uarts, esys->uarts, | ||
| 160 | sizeof(struct uart_device) * loongson_sysconf.nr_uarts); | ||
| 161 | |||
| 162 | loongson_sysconf.nr_sensors = esys->nr_sensors; | ||
| 163 | if (loongson_sysconf.nr_sensors > MAX_SENSORS) | ||
| 164 | loongson_sysconf.nr_sensors = 0; | ||
| 165 | if (loongson_sysconf.nr_sensors) | ||
| 166 | memcpy(loongson_sysconf.sensors, esys->sensors, | ||
| 167 | sizeof(struct sensor_device) * loongson_sysconf.nr_sensors); | ||
| 144 | #endif | 168 | #endif |
| 145 | if (cpu_clock_freq == 0) { | 169 | if (cpu_clock_freq == 0) { |
| 146 | processor_id = (¤t_cpu_data)->processor_id; | 170 | processor_id = (¤t_cpu_data)->processor_id; |
diff --git a/arch/mips/loongson/common/gpio.c b/arch/mips/loongson/common/gpio.c index 21869908aaa4..29dbaa253061 100644 --- a/arch/mips/loongson/common/gpio.c +++ b/arch/mips/loongson/common/gpio.c | |||
| @@ -37,7 +37,7 @@ int gpio_get_value(unsigned gpio) | |||
| 37 | val = LOONGSON_GPIODATA; | 37 | val = LOONGSON_GPIODATA; |
| 38 | spin_unlock(&gpio_lock); | 38 | spin_unlock(&gpio_lock); |
| 39 | 39 | ||
| 40 | return ((val & mask) != 0); | 40 | return (val & mask) != 0; |
| 41 | } | 41 | } |
| 42 | EXPORT_SYMBOL(gpio_get_value); | 42 | EXPORT_SYMBOL(gpio_get_value); |
| 43 | 43 | ||
diff --git a/arch/mips/loongson/common/init.c b/arch/mips/loongson/common/init.c index f6af3aba4c86..9b987fe98b5b 100644 --- a/arch/mips/loongson/common/init.c +++ b/arch/mips/loongson/common/init.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <linux/bootmem.h> | 11 | #include <linux/bootmem.h> |
| 12 | #include <asm/bootinfo.h> | ||
| 12 | #include <asm/smp-ops.h> | 13 | #include <asm/smp-ops.h> |
| 13 | 14 | ||
| 14 | #include <loongson.h> | 15 | #include <loongson.h> |
diff --git a/arch/mips/loongson/common/machtype.c b/arch/mips/loongson/common/machtype.c index 1a4797984b8d..f2807bc662a3 100644 --- a/arch/mips/loongson/common/machtype.c +++ b/arch/mips/loongson/common/machtype.c | |||
| @@ -19,19 +19,16 @@ | |||
| 19 | #define MACHTYPE_LEN 50 | 19 | #define MACHTYPE_LEN 50 |
| 20 | 20 | ||
| 21 | static const char *system_types[] = { | 21 | static const char *system_types[] = { |
| 22 | [MACH_LOONGSON_UNKNOWN] "unknown loongson machine", | 22 | [MACH_LOONGSON_UNKNOWN] = "unknown loongson machine", |
| 23 | [MACH_LEMOTE_FL2E] "lemote-fuloong-2e-box", | 23 | [MACH_LEMOTE_FL2E] = "lemote-fuloong-2e-box", |
| 24 | [MACH_LEMOTE_FL2F] "lemote-fuloong-2f-box", | 24 | [MACH_LEMOTE_FL2F] = "lemote-fuloong-2f-box", |
| 25 | [MACH_LEMOTE_ML2F7] "lemote-mengloong-2f-7inches", | 25 | [MACH_LEMOTE_ML2F7] = "lemote-mengloong-2f-7inches", |
| 26 | [MACH_LEMOTE_YL2F89] "lemote-yeeloong-2f-8.9inches", | 26 | [MACH_LEMOTE_YL2F89] = "lemote-yeeloong-2f-8.9inches", |
| 27 | [MACH_DEXXON_GDIUM2F10] "dexxon-gdium-2f", | 27 | [MACH_DEXXON_GDIUM2F10] = "dexxon-gdium-2f", |
| 28 | [MACH_LEMOTE_NAS] "lemote-nas-2f", | 28 | [MACH_LEMOTE_NAS] = "lemote-nas-2f", |
| 29 | [MACH_LEMOTE_LL2F] "lemote-lynloong-2f", | 29 | [MACH_LEMOTE_LL2F] = "lemote-lynloong-2f", |
| 30 | [MACH_LEMOTE_A1004] "lemote-3a-notebook-a1004", | 30 | [MACH_LOONGSON_GENERIC] = "generic-loongson-machine", |
| 31 | [MACH_LEMOTE_A1101] "lemote-3a-itx-a1101", | 31 | [MACH_LOONGSON_END] = NULL, |
| 32 | [MACH_LEMOTE_A1201] "lemote-2gq-notebook-a1201", | ||
| 33 | [MACH_LEMOTE_A1205] "lemote-2gq-aio-a1205", | ||
| 34 | [MACH_LOONGSON_END] NULL, | ||
| 35 | }; | 32 | }; |
| 36 | 33 | ||
| 37 | const char *get_system_type(void) | 34 | const char *get_system_type(void) |
diff --git a/arch/mips/loongson/common/rtc.c b/arch/mips/loongson/common/rtc.c index a90d87c01555..b5709af09f7f 100644 --- a/arch/mips/loongson/common/rtc.c +++ b/arch/mips/loongson/common/rtc.c | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
| 15 | #include <linux/mc146818rtc.h> | 15 | #include <linux/mc146818rtc.h> |
| 16 | 16 | ||
| 17 | struct resource loongson_rtc_resources[] = { | 17 | static struct resource loongson_rtc_resources[] = { |
| 18 | { | 18 | { |
| 19 | .start = RTC_PORT(0), | 19 | .start = RTC_PORT(0), |
| 20 | .end = RTC_PORT(1), | 20 | .end = RTC_PORT(1), |
diff --git a/arch/mips/loongson/common/serial.c b/arch/mips/loongson/common/serial.c index bd2b7095b6dc..c23fa1373729 100644 --- a/arch/mips/loongson/common/serial.c +++ b/arch/mips/loongson/common/serial.c | |||
| @@ -38,20 +38,17 @@ | |||
| 38 | .regshift = 0, \ | 38 | .regshift = 0, \ |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | static struct plat_serial8250_port uart8250_data[][2] = { | 41 | static struct plat_serial8250_port uart8250_data[][MAX_UARTS + 1] = { |
| 42 | [MACH_LOONGSON_UNKNOWN] {}, | 42 | [MACH_LOONGSON_UNKNOWN] = {}, |
| 43 | [MACH_LEMOTE_FL2E] {PORT(4, 1843200), {} }, | 43 | [MACH_LEMOTE_FL2E] = {PORT(4, 1843200), {} }, |
| 44 | [MACH_LEMOTE_FL2F] {PORT(3, 1843200), {} }, | 44 | [MACH_LEMOTE_FL2F] = {PORT(3, 1843200), {} }, |
| 45 | [MACH_LEMOTE_ML2F7] {PORT_M(3, 3686400), {} }, | 45 | [MACH_LEMOTE_ML2F7] = {PORT_M(3, 3686400), {} }, |
| 46 | [MACH_LEMOTE_YL2F89] {PORT_M(3, 3686400), {} }, | 46 | [MACH_LEMOTE_YL2F89] = {PORT_M(3, 3686400), {} }, |
| 47 | [MACH_DEXXON_GDIUM2F10] {PORT_M(3, 3686400), {} }, | 47 | [MACH_DEXXON_GDIUM2F10] = {PORT_M(3, 3686400), {} }, |
| 48 | [MACH_LEMOTE_NAS] {PORT_M(3, 3686400), {} }, | 48 | [MACH_LEMOTE_NAS] = {PORT_M(3, 3686400), {} }, |
| 49 | [MACH_LEMOTE_LL2F] {PORT(3, 1843200), {} }, | 49 | [MACH_LEMOTE_LL2F] = {PORT(3, 1843200), {} }, |
| 50 | [MACH_LEMOTE_A1004] {PORT_M(2, 33177600), {} }, | 50 | [MACH_LOONGSON_GENERIC] = {PORT_M(2, 25000000), {} }, |
| 51 | [MACH_LEMOTE_A1101] {PORT_M(2, 25000000), {} }, | 51 | [MACH_LOONGSON_END] = {}, |
| 52 | [MACH_LEMOTE_A1201] {PORT_M(2, 25000000), {} }, | ||
| 53 | [MACH_LEMOTE_A1205] {PORT_M(2, 25000000), {} }, | ||
| 54 | [MACH_LOONGSON_END] {}, | ||
| 55 | }; | 52 | }; |
| 56 | 53 | ||
| 57 | static struct platform_device uart8250_device = { | 54 | static struct platform_device uart8250_device = { |
| @@ -61,17 +58,52 @@ static struct platform_device uart8250_device = { | |||
| 61 | 58 | ||
| 62 | static int __init serial_init(void) | 59 | static int __init serial_init(void) |
| 63 | { | 60 | { |
| 61 | int i; | ||
| 64 | unsigned char iotype; | 62 | unsigned char iotype; |
| 65 | 63 | ||
| 66 | iotype = uart8250_data[mips_machtype][0].iotype; | 64 | iotype = uart8250_data[mips_machtype][0].iotype; |
| 67 | 65 | ||
| 68 | if (UPIO_MEM == iotype) | 66 | if (UPIO_MEM == iotype) { |
| 67 | uart8250_data[mips_machtype][0].mapbase = | ||
| 68 | loongson_uart_base[0]; | ||
| 69 | uart8250_data[mips_machtype][0].membase = | 69 | uart8250_data[mips_machtype][0].membase = |
| 70 | (void __iomem *)_loongson_uart_base; | 70 | (void __iomem *)_loongson_uart_base[0]; |
| 71 | } | ||
| 71 | else if (UPIO_PORT == iotype) | 72 | else if (UPIO_PORT == iotype) |
| 72 | uart8250_data[mips_machtype][0].iobase = | 73 | uart8250_data[mips_machtype][0].iobase = |
| 73 | loongson_uart_base - LOONGSON_PCIIO_BASE; | 74 | loongson_uart_base[0] - LOONGSON_PCIIO_BASE; |
| 74 | 75 | ||
| 76 | if (loongson_sysconf.uarts[0].uartclk) | ||
| 77 | uart8250_data[mips_machtype][0].uartclk = | ||
| 78 | loongson_sysconf.uarts[0].uartclk; | ||
| 79 | |||
| 80 | for (i = 1; i < loongson_sysconf.nr_uarts; i++) { | ||
| 81 | iotype = loongson_sysconf.uarts[i].iotype; | ||
| 82 | uart8250_data[mips_machtype][i].iotype = iotype; | ||
| 83 | loongson_uart_base[i] = loongson_sysconf.uarts[i].uart_base; | ||
| 84 | |||
| 85 | if (UPIO_MEM == iotype) { | ||
| 86 | uart8250_data[mips_machtype][i].irq = | ||
| 87 | MIPS_CPU_IRQ_BASE + loongson_sysconf.uarts[i].int_offset; | ||
| 88 | uart8250_data[mips_machtype][i].mapbase = | ||
| 89 | loongson_uart_base[i]; | ||
| 90 | uart8250_data[mips_machtype][i].membase = | ||
| 91 | ioremap_nocache(loongson_uart_base[i], 8); | ||
| 92 | } else if (UPIO_PORT == iotype) { | ||
| 93 | uart8250_data[mips_machtype][i].irq = | ||
| 94 | loongson_sysconf.uarts[i].int_offset; | ||
| 95 | uart8250_data[mips_machtype][i].iobase = | ||
| 96 | loongson_uart_base[i] - LOONGSON_PCIIO_BASE; | ||
| 97 | } | ||
| 98 | |||
| 99 | uart8250_data[mips_machtype][i].uartclk = | ||
| 100 | loongson_sysconf.uarts[i].uartclk; | ||
| 101 | uart8250_data[mips_machtype][i].flags = | ||
| 102 | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; | ||
| 103 | } | ||
| 104 | |||
| 105 | memset(&uart8250_data[mips_machtype][loongson_sysconf.nr_uarts], | ||
| 106 | 0, sizeof(struct plat_serial8250_port)); | ||
| 75 | uart8250_device.dev.platform_data = uart8250_data[mips_machtype]; | 107 | uart8250_device.dev.platform_data = uart8250_data[mips_machtype]; |
| 76 | 108 | ||
| 77 | return platform_device_register(&uart8250_device); | 109 | return platform_device_register(&uart8250_device); |
diff --git a/arch/mips/loongson/common/setup.c b/arch/mips/loongson/common/setup.c index bb4ac922e47a..d477dd6bb326 100644 --- a/arch/mips/loongson/common/setup.c +++ b/arch/mips/loongson/common/setup.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
| 11 | 11 | ||
| 12 | #include <asm/wbflush.h> | 12 | #include <asm/wbflush.h> |
| 13 | #include <asm/bootinfo.h> | ||
| 13 | 14 | ||
| 14 | #include <loongson.h> | 15 | #include <loongson.h> |
| 15 | 16 | ||
diff --git a/arch/mips/loongson/common/time.c b/arch/mips/loongson/common/time.c index 262a1f65b05e..e1a5382ad47e 100644 --- a/arch/mips/loongson/common/time.c +++ b/arch/mips/loongson/common/time.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | */ | 12 | */ |
| 13 | #include <asm/mc146818-time.h> | 13 | #include <asm/mc146818-time.h> |
| 14 | #include <asm/time.h> | 14 | #include <asm/time.h> |
| 15 | #include <asm/hpet.h> | ||
| 15 | 16 | ||
| 16 | #include <loongson.h> | 17 | #include <loongson.h> |
| 17 | #include <cs5536/cs5536_mfgpt.h> | 18 | #include <cs5536/cs5536_mfgpt.h> |
| @@ -21,7 +22,11 @@ void __init plat_time_init(void) | |||
| 21 | /* setup mips r4k timer */ | 22 | /* setup mips r4k timer */ |
| 22 | mips_hpt_frequency = cpu_clock_freq / 2; | 23 | mips_hpt_frequency = cpu_clock_freq / 2; |
| 23 | 24 | ||
| 25 | #ifdef CONFIG_RS780_HPET | ||
| 26 | setup_hpet_timer(); | ||
| 27 | #else | ||
| 24 | setup_mfgpt0_timer(); | 28 | setup_mfgpt0_timer(); |
| 29 | #endif | ||
| 25 | } | 30 | } |
| 26 | 31 | ||
| 27 | void read_persistent_clock(struct timespec *ts) | 32 | void read_persistent_clock(struct timespec *ts) |
diff --git a/arch/mips/loongson/common/uart_base.c b/arch/mips/loongson/common/uart_base.c index 1e1eeea73fde..9de559d58e1f 100644 --- a/arch/mips/loongson/common/uart_base.c +++ b/arch/mips/loongson/common/uart_base.c | |||
| @@ -13,22 +13,27 @@ | |||
| 13 | 13 | ||
| 14 | #include <loongson.h> | 14 | #include <loongson.h> |
| 15 | 15 | ||
| 16 | /* ioremapped */ | ||
| 17 | unsigned long _loongson_uart_base; | ||
| 18 | EXPORT_SYMBOL(_loongson_uart_base); | ||
| 19 | /* raw */ | 16 | /* raw */ |
| 20 | unsigned long loongson_uart_base; | 17 | unsigned long loongson_uart_base[MAX_UARTS] = {}; |
| 18 | /* ioremapped */ | ||
| 19 | unsigned long _loongson_uart_base[MAX_UARTS] = {}; | ||
| 20 | |||
| 21 | EXPORT_SYMBOL(loongson_uart_base); | 21 | EXPORT_SYMBOL(loongson_uart_base); |
| 22 | EXPORT_SYMBOL(_loongson_uart_base); | ||
| 22 | 23 | ||
| 23 | void prom_init_loongson_uart_base(void) | 24 | void prom_init_loongson_uart_base(void) |
| 24 | { | 25 | { |
| 25 | switch (mips_machtype) { | 26 | switch (mips_machtype) { |
| 27 | case MACH_LOONGSON_GENERIC: | ||
| 28 | /* The CPU provided serial port (CPU) */ | ||
| 29 | loongson_uart_base[0] = LOONGSON_REG_BASE + 0x1e0; | ||
| 30 | break; | ||
| 26 | case MACH_LEMOTE_FL2E: | 31 | case MACH_LEMOTE_FL2E: |
| 27 | loongson_uart_base = LOONGSON_PCIIO_BASE + 0x3f8; | 32 | loongson_uart_base[0] = LOONGSON_PCIIO_BASE + 0x3f8; |
| 28 | break; | 33 | break; |
| 29 | case MACH_LEMOTE_FL2F: | 34 | case MACH_LEMOTE_FL2F: |
| 30 | case MACH_LEMOTE_LL2F: | 35 | case MACH_LEMOTE_LL2F: |
| 31 | loongson_uart_base = LOONGSON_PCIIO_BASE + 0x2f8; | 36 | loongson_uart_base[0] = LOONGSON_PCIIO_BASE + 0x2f8; |
| 32 | break; | 37 | break; |
| 33 | case MACH_LEMOTE_ML2F7: | 38 | case MACH_LEMOTE_ML2F7: |
| 34 | case MACH_LEMOTE_YL2F89: | 39 | case MACH_LEMOTE_YL2F89: |
| @@ -36,17 +41,10 @@ void prom_init_loongson_uart_base(void) | |||
| 36 | case MACH_LEMOTE_NAS: | 41 | case MACH_LEMOTE_NAS: |
| 37 | default: | 42 | default: |
| 38 | /* The CPU provided serial port (LPC) */ | 43 | /* The CPU provided serial port (LPC) */ |
| 39 | loongson_uart_base = LOONGSON_LIO1_BASE + 0x3f8; | 44 | loongson_uart_base[0] = LOONGSON_LIO1_BASE + 0x3f8; |
| 40 | break; | ||
| 41 | case MACH_LEMOTE_A1004: | ||
| 42 | case MACH_LEMOTE_A1101: | ||
| 43 | case MACH_LEMOTE_A1201: | ||
| 44 | case MACH_LEMOTE_A1205: | ||
| 45 | /* The CPU provided serial port (CPU) */ | ||
| 46 | loongson_uart_base = LOONGSON_REG_BASE + 0x1e0; | ||
| 47 | break; | 45 | break; |
| 48 | } | 46 | } |
| 49 | 47 | ||
| 50 | _loongson_uart_base = | 48 | _loongson_uart_base[0] = |
| 51 | (unsigned long)ioremap_nocache(loongson_uart_base, 8); | 49 | (unsigned long)ioremap_nocache(loongson_uart_base[0], 8); |
| 52 | } | 50 | } |
diff --git a/arch/mips/loongson/lemote-2f/irq.c b/arch/mips/loongson/lemote-2f/irq.c index 6f8682e44483..cab5f43e0e29 100644 --- a/arch/mips/loongson/lemote-2f/irq.c +++ b/arch/mips/loongson/lemote-2f/irq.c | |||
| @@ -93,13 +93,13 @@ static irqreturn_t ip6_action(int cpl, void *dev_id) | |||
| 93 | return IRQ_HANDLED; | 93 | return IRQ_HANDLED; |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | struct irqaction ip6_irqaction = { | 96 | static struct irqaction ip6_irqaction = { |
| 97 | .handler = ip6_action, | 97 | .handler = ip6_action, |
| 98 | .name = "cascade", | 98 | .name = "cascade", |
| 99 | .flags = IRQF_SHARED | IRQF_NO_THREAD, | 99 | .flags = IRQF_SHARED | IRQF_NO_THREAD, |
| 100 | }; | 100 | }; |
| 101 | 101 | ||
| 102 | struct irqaction cascade_irqaction = { | 102 | static struct irqaction cascade_irqaction = { |
| 103 | .handler = no_action, | 103 | .handler = no_action, |
| 104 | .name = "cascade", | 104 | .name = "cascade", |
| 105 | .flags = IRQF_NO_THREAD, | 105 | .flags = IRQF_NO_THREAD, |
diff --git a/arch/mips/loongson/lemote-2f/reset.c b/arch/mips/loongson/lemote-2f/reset.c index 79ac694fe744..a26ca7fcd7e0 100644 --- a/arch/mips/loongson/lemote-2f/reset.c +++ b/arch/mips/loongson/lemote-2f/reset.c | |||
| @@ -76,7 +76,7 @@ static void fl2f_shutdown(void) | |||
| 76 | 76 | ||
| 77 | /* reset support for yeeloong2f and mengloong2f notebook */ | 77 | /* reset support for yeeloong2f and mengloong2f notebook */ |
| 78 | 78 | ||
| 79 | void ml2f_reboot(void) | 79 | static void ml2f_reboot(void) |
| 80 | { | 80 | { |
| 81 | reset_cpu(); | 81 | reset_cpu(); |
| 82 | 82 | ||
diff --git a/arch/mips/loongson/loongson-3/Makefile b/arch/mips/loongson/loongson-3/Makefile index b4df775b9f30..622fead5ebc9 100644 --- a/arch/mips/loongson/loongson-3/Makefile +++ b/arch/mips/loongson/loongson-3/Makefile | |||
| @@ -1,8 +1,10 @@ | |||
| 1 | # | 1 | # |
| 2 | # Makefile for Loongson-3 family machines | 2 | # Makefile for Loongson-3 family machines |
| 3 | # | 3 | # |
| 4 | obj-y += irq.o cop2-ex.o | 4 | obj-y += irq.o cop2-ex.o platform.o |
| 5 | 5 | ||
| 6 | obj-$(CONFIG_SMP) += smp.o | 6 | obj-$(CONFIG_SMP) += smp.o |
| 7 | 7 | ||
| 8 | obj-$(CONFIG_NUMA) += numa.o | 8 | obj-$(CONFIG_NUMA) += numa.o |
| 9 | |||
| 10 | obj-$(CONFIG_RS780_HPET) += hpet.o | ||
diff --git a/arch/mips/loongson/loongson-3/hpet.c b/arch/mips/loongson/loongson-3/hpet.c new file mode 100644 index 000000000000..e898d68668a9 --- /dev/null +++ b/arch/mips/loongson/loongson-3/hpet.c | |||
| @@ -0,0 +1,257 @@ | |||
| 1 | #include <linux/init.h> | ||
| 2 | #include <linux/pci.h> | ||
| 3 | #include <linux/percpu.h> | ||
| 4 | #include <linux/delay.h> | ||
| 5 | #include <linux/spinlock.h> | ||
| 6 | #include <linux/interrupt.h> | ||
| 7 | |||
| 8 | #include <asm/hpet.h> | ||
| 9 | #include <asm/time.h> | ||
| 10 | |||
| 11 | #define SMBUS_CFG_BASE (loongson_sysconf.ht_control_base + 0x0300a000) | ||
| 12 | #define SMBUS_PCI_REG40 0x40 | ||
| 13 | #define SMBUS_PCI_REG64 0x64 | ||
| 14 | #define SMBUS_PCI_REGB4 0xb4 | ||
| 15 | |||
| 16 | static DEFINE_SPINLOCK(hpet_lock); | ||
| 17 | DEFINE_PER_CPU(struct clock_event_device, hpet_clockevent_device); | ||
| 18 | |||
| 19 | static unsigned int smbus_read(int offset) | ||
| 20 | { | ||
| 21 | return *(volatile unsigned int *)(SMBUS_CFG_BASE + offset); | ||
| 22 | } | ||
| 23 | |||
| 24 | static void smbus_write(int offset, int data) | ||
| 25 | { | ||
| 26 | *(volatile unsigned int *)(SMBUS_CFG_BASE + offset) = data; | ||
| 27 | } | ||
| 28 | |||
| 29 | static void smbus_enable(int offset, int bit) | ||
| 30 | { | ||
| 31 | unsigned int cfg = smbus_read(offset); | ||
| 32 | |||
| 33 | cfg |= bit; | ||
| 34 | smbus_write(offset, cfg); | ||
| 35 | } | ||
| 36 | |||
| 37 | static int hpet_read(int offset) | ||
| 38 | { | ||
| 39 | return *(volatile unsigned int *)(HPET_MMIO_ADDR + offset); | ||
| 40 | } | ||
| 41 | |||
| 42 | static void hpet_write(int offset, int data) | ||
| 43 | { | ||
| 44 | *(volatile unsigned int *)(HPET_MMIO_ADDR + offset) = data; | ||
| 45 | } | ||
| 46 | |||
| 47 | static void hpet_start_counter(void) | ||
| 48 | { | ||
| 49 | unsigned int cfg = hpet_read(HPET_CFG); | ||
| 50 | |||
| 51 | cfg |= HPET_CFG_ENABLE; | ||
| 52 | hpet_write(HPET_CFG, cfg); | ||
| 53 | } | ||
| 54 | |||
| 55 | static void hpet_stop_counter(void) | ||
| 56 | { | ||
| 57 | unsigned int cfg = hpet_read(HPET_CFG); | ||
| 58 | |||
| 59 | cfg &= ~HPET_CFG_ENABLE; | ||
| 60 | hpet_write(HPET_CFG, cfg); | ||
| 61 | } | ||
| 62 | |||
| 63 | static void hpet_reset_counter(void) | ||
| 64 | { | ||
| 65 | hpet_write(HPET_COUNTER, 0); | ||
| 66 | hpet_write(HPET_COUNTER + 4, 0); | ||
| 67 | } | ||
| 68 | |||
| 69 | static void hpet_restart_counter(void) | ||
| 70 | { | ||
| 71 | hpet_stop_counter(); | ||
| 72 | hpet_reset_counter(); | ||
| 73 | hpet_start_counter(); | ||
| 74 | } | ||
| 75 | |||
| 76 | static void hpet_enable_legacy_int(void) | ||
| 77 | { | ||
| 78 | /* Do nothing on Loongson-3 */ | ||
| 79 | } | ||
| 80 | |||
| 81 | static void hpet_set_mode(enum clock_event_mode mode, | ||
| 82 | struct clock_event_device *evt) | ||
| 83 | { | ||
| 84 | int cfg = 0; | ||
| 85 | |||
| 86 | spin_lock(&hpet_lock); | ||
| 87 | switch (mode) { | ||
| 88 | case CLOCK_EVT_MODE_PERIODIC: | ||
| 89 | pr_info("set clock event to periodic mode!\n"); | ||
| 90 | /* stop counter */ | ||
| 91 | hpet_stop_counter(); | ||
| 92 | |||
| 93 | /* enables the timer0 to generate a periodic interrupt */ | ||
| 94 | cfg = hpet_read(HPET_T0_CFG); | ||
| 95 | cfg &= ~HPET_TN_LEVEL; | ||
| 96 | cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | | ||
| 97 | HPET_TN_SETVAL | HPET_TN_32BIT; | ||
| 98 | hpet_write(HPET_T0_CFG, cfg); | ||
| 99 | |||
| 100 | /* set the comparator */ | ||
| 101 | hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL); | ||
| 102 | udelay(1); | ||
| 103 | hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL); | ||
| 104 | |||
| 105 | /* start counter */ | ||
| 106 | hpet_start_counter(); | ||
| 107 | break; | ||
| 108 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
| 109 | case CLOCK_EVT_MODE_UNUSED: | ||
| 110 | cfg = hpet_read(HPET_T0_CFG); | ||
| 111 | cfg &= ~HPET_TN_ENABLE; | ||
| 112 | hpet_write(HPET_T0_CFG, cfg); | ||
| 113 | break; | ||
| 114 | case CLOCK_EVT_MODE_ONESHOT: | ||
| 115 | pr_info("set clock event to one shot mode!\n"); | ||
| 116 | cfg = hpet_read(HPET_T0_CFG); | ||
| 117 | /* set timer0 type | ||
| 118 | * 1 : periodic interrupt | ||
| 119 | * 0 : non-periodic(oneshot) interrupt | ||
| 120 | */ | ||
| 121 | cfg &= ~HPET_TN_PERIODIC; | ||
| 122 | cfg |= HPET_TN_ENABLE | HPET_TN_32BIT; | ||
| 123 | hpet_write(HPET_T0_CFG, cfg); | ||
| 124 | break; | ||
| 125 | case CLOCK_EVT_MODE_RESUME: | ||
| 126 | hpet_enable_legacy_int(); | ||
| 127 | break; | ||
| 128 | } | ||
| 129 | spin_unlock(&hpet_lock); | ||
| 130 | } | ||
| 131 | |||
| 132 | static int hpet_next_event(unsigned long delta, | ||
| 133 | struct clock_event_device *evt) | ||
| 134 | { | ||
| 135 | unsigned int cnt; | ||
| 136 | int res; | ||
| 137 | |||
| 138 | cnt = hpet_read(HPET_COUNTER); | ||
| 139 | cnt += delta; | ||
| 140 | hpet_write(HPET_T0_CMP, cnt); | ||
| 141 | |||
| 142 | res = ((int)(hpet_read(HPET_COUNTER) - cnt) > 0) ? -ETIME : 0; | ||
| 143 | return res; | ||
| 144 | } | ||
| 145 | |||
| 146 | static irqreturn_t hpet_irq_handler(int irq, void *data) | ||
| 147 | { | ||
| 148 | int is_irq; | ||
| 149 | struct clock_event_device *cd; | ||
| 150 | unsigned int cpu = smp_processor_id(); | ||
| 151 | |||
| 152 | is_irq = hpet_read(HPET_STATUS); | ||
| 153 | if (is_irq & HPET_T0_IRS) { | ||
| 154 | /* clear the TIMER0 irq status register */ | ||
| 155 | hpet_write(HPET_STATUS, HPET_T0_IRS); | ||
| 156 | cd = &per_cpu(hpet_clockevent_device, cpu); | ||
| 157 | cd->event_handler(cd); | ||
| 158 | return IRQ_HANDLED; | ||
| 159 | } | ||
| 160 | return IRQ_NONE; | ||
| 161 | } | ||
| 162 | |||
| 163 | static struct irqaction hpet_irq = { | ||
| 164 | .handler = hpet_irq_handler, | ||
| 165 | .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER, | ||
| 166 | .name = "hpet", | ||
| 167 | }; | ||
| 168 | |||
| 169 | /* | ||
| 170 | * hpet address assignation and irq setting should be done in bios. | ||
| 171 | * but pmon don't do this, we just setup here directly. | ||
| 172 | * The operation under is normal. unfortunately, hpet_setup process | ||
| 173 | * is before pci initialize. | ||
| 174 | * | ||
| 175 | * { | ||
| 176 | * struct pci_dev *pdev; | ||
| 177 | * | ||
| 178 | * pdev = pci_get_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL); | ||
| 179 | * pci_write_config_word(pdev, SMBUS_PCI_REGB4, HPET_ADDR); | ||
| 180 | * | ||
| 181 | * ... | ||
| 182 | * } | ||
| 183 | */ | ||
| 184 | static void hpet_setup(void) | ||
| 185 | { | ||
| 186 | /* set hpet base address */ | ||
| 187 | smbus_write(SMBUS_PCI_REGB4, HPET_ADDR); | ||
| 188 | |||
| 189 | /* enable decodeing of access to HPET MMIO*/ | ||
| 190 | smbus_enable(SMBUS_PCI_REG40, (1 << 28)); | ||
| 191 | |||
| 192 | /* HPET irq enable */ | ||
| 193 | smbus_enable(SMBUS_PCI_REG64, (1 << 10)); | ||
| 194 | |||
| 195 | hpet_enable_legacy_int(); | ||
| 196 | } | ||
| 197 | |||
| 198 | void __init setup_hpet_timer(void) | ||
| 199 | { | ||
| 200 | unsigned int cpu = smp_processor_id(); | ||
| 201 | struct clock_event_device *cd; | ||
| 202 | |||
| 203 | hpet_setup(); | ||
| 204 | |||
| 205 | cd = &per_cpu(hpet_clockevent_device, cpu); | ||
| 206 | cd->name = "hpet"; | ||
| 207 | cd->rating = 320; | ||
| 208 | cd->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; | ||
| 209 | cd->set_mode = hpet_set_mode; | ||
| 210 | cd->set_next_event = hpet_next_event; | ||
| 211 | cd->irq = HPET_T0_IRQ; | ||
| 212 | cd->cpumask = cpumask_of(cpu); | ||
| 213 | clockevent_set_clock(cd, HPET_FREQ); | ||
| 214 | cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); | ||
| 215 | cd->min_delta_ns = 5000; | ||
| 216 | |||
| 217 | clockevents_register_device(cd); | ||
| 218 | setup_irq(HPET_T0_IRQ, &hpet_irq); | ||
| 219 | pr_info("hpet clock event device register\n"); | ||
| 220 | } | ||
| 221 | |||
| 222 | static cycle_t hpet_read_counter(struct clocksource *cs) | ||
| 223 | { | ||
| 224 | return (cycle_t)hpet_read(HPET_COUNTER); | ||
| 225 | } | ||
| 226 | |||
| 227 | static void hpet_suspend(struct clocksource *cs) | ||
| 228 | { | ||
| 229 | } | ||
| 230 | |||
| 231 | static void hpet_resume(struct clocksource *cs) | ||
| 232 | { | ||
| 233 | hpet_setup(); | ||
| 234 | hpet_restart_counter(); | ||
| 235 | } | ||
| 236 | |||
| 237 | static struct clocksource csrc_hpet = { | ||
| 238 | .name = "hpet", | ||
| 239 | /* mips clocksource rating is less than 300, so hpet is better. */ | ||
| 240 | .rating = 300, | ||
| 241 | .read = hpet_read_counter, | ||
| 242 | .mask = CLOCKSOURCE_MASK(32), | ||
| 243 | /* oneshot mode work normal with this flag */ | ||
| 244 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
| 245 | .suspend = hpet_suspend, | ||
| 246 | .resume = hpet_resume, | ||
| 247 | .mult = 0, | ||
| 248 | .shift = 10, | ||
| 249 | }; | ||
| 250 | |||
| 251 | int __init init_hpet_clocksource(void) | ||
| 252 | { | ||
| 253 | csrc_hpet.mult = clocksource_hz2mult(HPET_FREQ, csrc_hpet.shift); | ||
| 254 | return clocksource_register_hz(&csrc_hpet, HPET_FREQ); | ||
| 255 | } | ||
| 256 | |||
| 257 | arch_initcall(init_hpet_clocksource); | ||
diff --git a/arch/mips/loongson/loongson-3/irq.c b/arch/mips/loongson/loongson-3/irq.c index ca1c62af5188..21221edda7a9 100644 --- a/arch/mips/loongson/loongson-3/irq.c +++ b/arch/mips/loongson/loongson-3/irq.c | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | 9 | ||
| 10 | #include "smp.h" | 10 | #include "smp.h" |
| 11 | 11 | ||
| 12 | unsigned int ht_irq[] = {1, 3, 4, 5, 6, 7, 8, 12, 14, 15}; | 12 | unsigned int ht_irq[] = {0, 1, 3, 4, 5, 6, 7, 8, 12, 14, 15}; |
| 13 | 13 | ||
| 14 | static void ht_irqdispatch(void) | 14 | static void ht_irqdispatch(void) |
| 15 | { | 15 | { |
| @@ -55,8 +55,8 @@ static inline void mask_loongson_irq(struct irq_data *d) | |||
| 55 | /* Workaround: UART IRQ may deliver to any core */ | 55 | /* Workaround: UART IRQ may deliver to any core */ |
| 56 | if (d->irq == LOONGSON_UART_IRQ) { | 56 | if (d->irq == LOONGSON_UART_IRQ) { |
| 57 | int cpu = smp_processor_id(); | 57 | int cpu = smp_processor_id(); |
| 58 | int node_id = cpu / loongson_sysconf.cores_per_node; | 58 | int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node; |
| 59 | int core_id = cpu % loongson_sysconf.cores_per_node; | 59 | int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node; |
| 60 | u64 intenclr_addr = smp_group[node_id] | | 60 | u64 intenclr_addr = smp_group[node_id] | |
| 61 | (u64)(&LOONGSON_INT_ROUTER_INTENCLR); | 61 | (u64)(&LOONGSON_INT_ROUTER_INTENCLR); |
| 62 | u64 introuter_lpc_addr = smp_group[node_id] | | 62 | u64 introuter_lpc_addr = smp_group[node_id] | |
| @@ -72,8 +72,8 @@ static inline void unmask_loongson_irq(struct irq_data *d) | |||
| 72 | /* Workaround: UART IRQ may deliver to any core */ | 72 | /* Workaround: UART IRQ may deliver to any core */ |
| 73 | if (d->irq == LOONGSON_UART_IRQ) { | 73 | if (d->irq == LOONGSON_UART_IRQ) { |
| 74 | int cpu = smp_processor_id(); | 74 | int cpu = smp_processor_id(); |
| 75 | int node_id = cpu / loongson_sysconf.cores_per_node; | 75 | int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node; |
| 76 | int core_id = cpu % loongson_sysconf.cores_per_node; | 76 | int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node; |
| 77 | u64 intenset_addr = smp_group[node_id] | | 77 | u64 intenset_addr = smp_group[node_id] | |
| 78 | (u64)(&LOONGSON_INT_ROUTER_INTENSET); | 78 | (u64)(&LOONGSON_INT_ROUTER_INTENSET); |
| 79 | u64 introuter_lpc_addr = smp_group[node_id] | | 79 | u64 introuter_lpc_addr = smp_group[node_id] | |
| @@ -102,10 +102,12 @@ void irq_router_init(void) | |||
| 102 | int i; | 102 | int i; |
| 103 | 103 | ||
| 104 | /* route LPC int to cpu core0 int 0 */ | 104 | /* route LPC int to cpu core0 int 0 */ |
| 105 | LOONGSON_INT_ROUTER_LPC = LOONGSON_INT_CORE0_INT0; | 105 | LOONGSON_INT_ROUTER_LPC = |
| 106 | LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 0); | ||
| 106 | /* route HT1 int0 ~ int7 to cpu core0 INT1*/ | 107 | /* route HT1 int0 ~ int7 to cpu core0 INT1*/ |
| 107 | for (i = 0; i < 8; i++) | 108 | for (i = 0; i < 8; i++) |
| 108 | LOONGSON_INT_ROUTER_HT1(i) = LOONGSON_INT_CORE0_INT1; | 109 | LOONGSON_INT_ROUTER_HT1(i) = |
| 110 | LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 1); | ||
| 109 | /* enable HT1 interrupt */ | 111 | /* enable HT1 interrupt */ |
| 110 | LOONGSON_HT1_INTN_EN(0) = 0xffffffff; | 112 | LOONGSON_HT1_INTN_EN(0) = 0xffffffff; |
| 111 | /* enable router interrupt intenset */ | 113 | /* enable router interrupt intenset */ |
diff --git a/arch/mips/loongson/loongson-3/numa.c b/arch/mips/loongson/loongson-3/numa.c index 42323bcc5d28..6cae0e75de27 100644 --- a/arch/mips/loongson/loongson-3/numa.c +++ b/arch/mips/loongson/loongson-3/numa.c | |||
| @@ -224,7 +224,7 @@ static void __init node_mem_init(unsigned int node) | |||
| 224 | 224 | ||
| 225 | static __init void prom_meminit(void) | 225 | static __init void prom_meminit(void) |
| 226 | { | 226 | { |
| 227 | unsigned int node, cpu; | 227 | unsigned int node, cpu, active_cpu = 0; |
| 228 | 228 | ||
| 229 | cpu_node_probe(); | 229 | cpu_node_probe(); |
| 230 | init_topology_matrix(); | 230 | init_topology_matrix(); |
| @@ -240,8 +240,14 @@ static __init void prom_meminit(void) | |||
| 240 | node = cpu / loongson_sysconf.cores_per_node; | 240 | node = cpu / loongson_sysconf.cores_per_node; |
| 241 | if (node >= num_online_nodes()) | 241 | if (node >= num_online_nodes()) |
| 242 | node = 0; | 242 | node = 0; |
| 243 | pr_info("NUMA: set cpumask cpu %d on node %d\n", cpu, node); | 243 | |
| 244 | cpu_set(cpu, __node_data[(node)]->cpumask); | 244 | if (loongson_sysconf.reserved_cpus_mask & (1<<cpu)) |
| 245 | continue; | ||
| 246 | |||
| 247 | cpu_set(active_cpu, __node_data[(node)]->cpumask); | ||
| 248 | pr_info("NUMA: set cpumask cpu %d on node %d\n", active_cpu, node); | ||
| 249 | |||
| 250 | active_cpu++; | ||
| 245 | } | 251 | } |
| 246 | } | 252 | } |
| 247 | 253 | ||
diff --git a/arch/mips/loongson/loongson-3/platform.c b/arch/mips/loongson/loongson-3/platform.c new file mode 100644 index 000000000000..25a97cc0ee33 --- /dev/null +++ b/arch/mips/loongson/loongson-3/platform.c | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2009 Lemote Inc. | ||
| 3 | * Author: Wu Zhangjin, wuzhangjin@gmail.com | ||
| 4 | * Xiang Yu, xiangy@lemote.com | ||
| 5 | * Chen Huacai, chenhc@lemote.com | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms of the GNU General Public License as published by the | ||
| 9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 10 | * option) any later version. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/err.h> | ||
| 14 | #include <linux/slab.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | #include <asm/bootinfo.h> | ||
| 17 | #include <boot_param.h> | ||
| 18 | #include <loongson_hwmon.h> | ||
| 19 | #include <workarounds.h> | ||
| 20 | |||
| 21 | static int __init loongson3_platform_init(void) | ||
| 22 | { | ||
| 23 | int i; | ||
| 24 | struct platform_device *pdev; | ||
| 25 | |||
| 26 | if (loongson_sysconf.ecname[0] != '\0') | ||
| 27 | platform_device_register_simple(loongson_sysconf.ecname, -1, NULL, 0); | ||
| 28 | |||
| 29 | for (i = 0; i < loongson_sysconf.nr_sensors; i++) { | ||
| 30 | if (loongson_sysconf.sensors[i].type > SENSOR_FAN) | ||
| 31 | continue; | ||
| 32 | |||
| 33 | pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL); | ||
| 34 | pdev->name = loongson_sysconf.sensors[i].name; | ||
| 35 | pdev->id = loongson_sysconf.sensors[i].id; | ||
| 36 | pdev->dev.platform_data = &loongson_sysconf.sensors[i]; | ||
| 37 | platform_device_register(pdev); | ||
| 38 | } | ||
| 39 | |||
| 40 | return 0; | ||
| 41 | } | ||
| 42 | |||
| 43 | arch_initcall(loongson3_platform_init); | ||
diff --git a/arch/mips/loongson/loongson-3/smp.c b/arch/mips/loongson/loongson-3/smp.c index d8c63af6c7cc..e2eb688b5434 100644 --- a/arch/mips/loongson/loongson-3/smp.c +++ b/arch/mips/loongson/loongson-3/smp.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <asm/tlbflush.h> | 25 | #include <asm/tlbflush.h> |
| 26 | #include <asm/cacheflush.h> | 26 | #include <asm/cacheflush.h> |
| 27 | #include <loongson.h> | 27 | #include <loongson.h> |
| 28 | #include <workarounds.h> | ||
| 28 | 29 | ||
| 29 | #include "smp.h" | 30 | #include "smp.h" |
| 30 | 31 | ||
| @@ -239,7 +240,7 @@ static void ipi_mailbox_buf_init(void) | |||
| 239 | */ | 240 | */ |
| 240 | static void loongson3_send_ipi_single(int cpu, unsigned int action) | 241 | static void loongson3_send_ipi_single(int cpu, unsigned int action) |
| 241 | { | 242 | { |
| 242 | loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu]); | 243 | loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(cpu)]); |
| 243 | } | 244 | } |
| 244 | 245 | ||
| 245 | static void | 246 | static void |
| @@ -248,7 +249,7 @@ loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action) | |||
| 248 | unsigned int i; | 249 | unsigned int i; |
| 249 | 250 | ||
| 250 | for_each_cpu(i, mask) | 251 | for_each_cpu(i, mask) |
| 251 | loongson3_ipi_write32((u32)action, ipi_set0_regs[i]); | 252 | loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(i)]); |
| 252 | } | 253 | } |
| 253 | 254 | ||
| 254 | void loongson3_ipi_interrupt(struct pt_regs *regs) | 255 | void loongson3_ipi_interrupt(struct pt_regs *regs) |
| @@ -257,10 +258,10 @@ void loongson3_ipi_interrupt(struct pt_regs *regs) | |||
| 257 | unsigned int action, c0count; | 258 | unsigned int action, c0count; |
| 258 | 259 | ||
| 259 | /* Load the ipi register to figure out what we're supposed to do */ | 260 | /* Load the ipi register to figure out what we're supposed to do */ |
| 260 | action = loongson3_ipi_read32(ipi_status0_regs[cpu]); | 261 | action = loongson3_ipi_read32(ipi_status0_regs[cpu_logical_map(cpu)]); |
| 261 | 262 | ||
| 262 | /* Clear the ipi register to clear the interrupt */ | 263 | /* Clear the ipi register to clear the interrupt */ |
| 263 | loongson3_ipi_write32((u32)action, ipi_clear0_regs[cpu]); | 264 | loongson3_ipi_write32((u32)action, ipi_clear0_regs[cpu_logical_map(cpu)]); |
| 264 | 265 | ||
| 265 | if (action & SMP_RESCHEDULE_YOURSELF) | 266 | if (action & SMP_RESCHEDULE_YOURSELF) |
| 266 | scheduler_ipi(); | 267 | scheduler_ipi(); |
| @@ -291,12 +292,14 @@ static void loongson3_init_secondary(void) | |||
| 291 | /* Set interrupt mask, but don't enable */ | 292 | /* Set interrupt mask, but don't enable */ |
| 292 | change_c0_status(ST0_IM, imask); | 293 | change_c0_status(ST0_IM, imask); |
| 293 | 294 | ||
| 294 | for (i = 0; i < loongson_sysconf.nr_cpus; i++) | 295 | for (i = 0; i < num_possible_cpus(); i++) |
| 295 | loongson3_ipi_write32(0xffffffff, ipi_en0_regs[i]); | 296 | loongson3_ipi_write32(0xffffffff, ipi_en0_regs[cpu_logical_map(i)]); |
| 296 | 297 | ||
| 297 | cpu_data[cpu].package = cpu / loongson_sysconf.cores_per_package; | ||
| 298 | cpu_data[cpu].core = cpu % loongson_sysconf.cores_per_package; | ||
| 299 | per_cpu(cpu_state, cpu) = CPU_ONLINE; | 298 | per_cpu(cpu_state, cpu) = CPU_ONLINE; |
| 299 | cpu_data[cpu].core = | ||
| 300 | cpu_logical_map(cpu) % loongson_sysconf.cores_per_package; | ||
| 301 | cpu_data[cpu].package = | ||
| 302 | cpu_logical_map(cpu) / loongson_sysconf.cores_per_package; | ||
| 300 | 303 | ||
| 301 | i = 0; | 304 | i = 0; |
| 302 | __this_cpu_write(core0_c0count, 0); | 305 | __this_cpu_write(core0_c0count, 0); |
| @@ -314,37 +317,50 @@ static void loongson3_init_secondary(void) | |||
| 314 | 317 | ||
| 315 | static void loongson3_smp_finish(void) | 318 | static void loongson3_smp_finish(void) |
| 316 | { | 319 | { |
| 320 | int cpu = smp_processor_id(); | ||
| 321 | |||
| 317 | write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ); | 322 | write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ); |
| 318 | local_irq_enable(); | 323 | local_irq_enable(); |
| 319 | loongson3_ipi_write64(0, | 324 | loongson3_ipi_write64(0, |
| 320 | (void *)(ipi_mailbox_buf[smp_processor_id()]+0x0)); | 325 | (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0)); |
| 321 | pr_info("CPU#%d finished, CP0_ST=%x\n", | 326 | pr_info("CPU#%d finished, CP0_ST=%x\n", |
| 322 | smp_processor_id(), read_c0_status()); | 327 | smp_processor_id(), read_c0_status()); |
| 323 | } | 328 | } |
| 324 | 329 | ||
| 325 | static void __init loongson3_smp_setup(void) | 330 | static void __init loongson3_smp_setup(void) |
| 326 | { | 331 | { |
| 327 | int i, num; | 332 | int i = 0, num = 0; /* i: physical id, num: logical id */ |
| 328 | 333 | ||
| 329 | init_cpu_possible(cpu_none_mask); | 334 | init_cpu_possible(cpu_none_mask); |
| 330 | set_cpu_possible(0, true); | ||
| 331 | |||
| 332 | __cpu_number_map[0] = 0; | ||
| 333 | __cpu_logical_map[0] = 0; | ||
| 334 | 335 | ||
| 335 | /* For unified kernel, NR_CPUS is the maximum possible value, | 336 | /* For unified kernel, NR_CPUS is the maximum possible value, |
| 336 | * loongson_sysconf.nr_cpus is the really present value */ | 337 | * loongson_sysconf.nr_cpus is the really present value */ |
| 337 | for (i = 1, num = 0; i < loongson_sysconf.nr_cpus; i++) { | 338 | while (i < loongson_sysconf.nr_cpus) { |
| 338 | set_cpu_possible(i, true); | 339 | if (loongson_sysconf.reserved_cpus_mask & (1<<i)) { |
| 339 | __cpu_number_map[i] = ++num; | 340 | /* Reserved physical CPU cores */ |
| 340 | __cpu_logical_map[num] = i; | 341 | __cpu_number_map[i] = -1; |
| 342 | } else { | ||
| 343 | __cpu_number_map[i] = num; | ||
| 344 | __cpu_logical_map[num] = i; | ||
| 345 | set_cpu_possible(num, true); | ||
| 346 | num++; | ||
| 347 | } | ||
| 348 | i++; | ||
| 341 | } | 349 | } |
| 350 | pr_info("Detected %i available CPU(s)\n", num); | ||
| 351 | |||
| 352 | while (num < loongson_sysconf.nr_cpus) { | ||
| 353 | __cpu_logical_map[num] = -1; | ||
| 354 | num++; | ||
| 355 | } | ||
| 356 | |||
| 342 | ipi_set0_regs_init(); | 357 | ipi_set0_regs_init(); |
| 343 | ipi_clear0_regs_init(); | 358 | ipi_clear0_regs_init(); |
| 344 | ipi_status0_regs_init(); | 359 | ipi_status0_regs_init(); |
| 345 | ipi_en0_regs_init(); | 360 | ipi_en0_regs_init(); |
| 346 | ipi_mailbox_buf_init(); | 361 | ipi_mailbox_buf_init(); |
| 347 | pr_info("Detected %i available secondary CPU(s)\n", num); | 362 | cpu_data[0].core = cpu_logical_map(0) % loongson_sysconf.cores_per_package; |
| 363 | cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package; | ||
| 348 | } | 364 | } |
| 349 | 365 | ||
| 350 | static void __init loongson3_prepare_cpus(unsigned int max_cpus) | 366 | static void __init loongson3_prepare_cpus(unsigned int max_cpus) |
| @@ -371,10 +387,14 @@ static void loongson3_boot_secondary(int cpu, struct task_struct *idle) | |||
| 371 | pr_debug("CPU#%d, func_pc=%lx, sp=%lx, gp=%lx\n", | 387 | pr_debug("CPU#%d, func_pc=%lx, sp=%lx, gp=%lx\n", |
| 372 | cpu, startargs[0], startargs[1], startargs[2]); | 388 | cpu, startargs[0], startargs[1], startargs[2]); |
| 373 | 389 | ||
| 374 | loongson3_ipi_write64(startargs[3], (void *)(ipi_mailbox_buf[cpu]+0x18)); | 390 | loongson3_ipi_write64(startargs[3], |
| 375 | loongson3_ipi_write64(startargs[2], (void *)(ipi_mailbox_buf[cpu]+0x10)); | 391 | (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x18)); |
| 376 | loongson3_ipi_write64(startargs[1], (void *)(ipi_mailbox_buf[cpu]+0x8)); | 392 | loongson3_ipi_write64(startargs[2], |
| 377 | loongson3_ipi_write64(startargs[0], (void *)(ipi_mailbox_buf[cpu]+0x0)); | 393 | (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x10)); |
| 394 | loongson3_ipi_write64(startargs[1], | ||
| 395 | (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x8)); | ||
| 396 | loongson3_ipi_write64(startargs[0], | ||
| 397 | (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0)); | ||
| 378 | } | 398 | } |
| 379 | 399 | ||
| 380 | #ifdef CONFIG_HOTPLUG_CPU | 400 | #ifdef CONFIG_HOTPLUG_CPU |
| @@ -568,7 +588,7 @@ void loongson3_disable_clock(int cpu) | |||
| 568 | if (loongson_sysconf.cputype == Loongson_3A) { | 588 | if (loongson_sysconf.cputype == Loongson_3A) { |
| 569 | LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id)); | 589 | LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id)); |
| 570 | } else if (loongson_sysconf.cputype == Loongson_3B) { | 590 | } else if (loongson_sysconf.cputype == Loongson_3B) { |
| 571 | if (!cpuhotplug_workaround) | 591 | if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG)) |
| 572 | LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3)); | 592 | LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3)); |
| 573 | } | 593 | } |
| 574 | } | 594 | } |
| @@ -581,7 +601,7 @@ void loongson3_enable_clock(int cpu) | |||
| 581 | if (loongson_sysconf.cputype == Loongson_3A) { | 601 | if (loongson_sysconf.cputype == Loongson_3A) { |
| 582 | LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id); | 602 | LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id); |
| 583 | } else if (loongson_sysconf.cputype == Loongson_3B) { | 603 | } else if (loongson_sysconf.cputype == Loongson_3B) { |
| 584 | if (!cpuhotplug_workaround) | 604 | if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG)) |
| 585 | LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3); | 605 | LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3); |
| 586 | } | 606 | } |
| 587 | } | 607 | } |
diff --git a/arch/mips/loongson1/Kconfig b/arch/mips/loongson1/Kconfig index e23c25d09963..a2b796eaf3c3 100644 --- a/arch/mips/loongson1/Kconfig +++ b/arch/mips/loongson1/Kconfig | |||
| @@ -5,8 +5,8 @@ choice | |||
| 5 | 5 | ||
| 6 | config LOONGSON1_LS1B | 6 | config LOONGSON1_LS1B |
| 7 | bool "Loongson LS1B board" | 7 | bool "Loongson LS1B board" |
| 8 | select CEVT_R4K | 8 | select CEVT_R4K if !MIPS_EXTERNAL_TIMER |
| 9 | select CSRC_R4K | 9 | select CSRC_R4K if !MIPS_EXTERNAL_TIMER |
| 10 | select SYS_HAS_CPU_LOONGSON1B | 10 | select SYS_HAS_CPU_LOONGSON1B |
| 11 | select DMA_NONCOHERENT | 11 | select DMA_NONCOHERENT |
| 12 | select BOOT_ELF32 | 12 | select BOOT_ELF32 |
| @@ -16,8 +16,46 @@ config LOONGSON1_LS1B | |||
| 16 | select SYS_SUPPORTS_HIGHMEM | 16 | select SYS_SUPPORTS_HIGHMEM |
| 17 | select SYS_SUPPORTS_MIPS16 | 17 | select SYS_SUPPORTS_MIPS16 |
| 18 | select SYS_HAS_EARLY_PRINTK | 18 | select SYS_HAS_EARLY_PRINTK |
| 19 | select USE_GENERIC_EARLY_PRINTK_8250 | ||
| 19 | select COMMON_CLK | 20 | select COMMON_CLK |
| 20 | 21 | ||
| 21 | endchoice | 22 | endchoice |
| 22 | 23 | ||
| 24 | menuconfig CEVT_CSRC_LS1X | ||
| 25 | bool "Use PWM Timer for clockevent/clocksource" | ||
| 26 | select MIPS_EXTERNAL_TIMER | ||
| 27 | depends on CPU_LOONGSON1 | ||
| 28 | help | ||
| 29 | This option changes the default clockevent/clocksource to PWM Timer, | ||
| 30 | and is required by Loongson1 CPUFreq support. | ||
| 31 | |||
| 32 | If unsure, say N. | ||
| 33 | |||
| 34 | choice | ||
| 35 | prompt "Select clockevent/clocksource" | ||
| 36 | depends on CEVT_CSRC_LS1X | ||
| 37 | default TIMER_USE_PWM0 | ||
| 38 | |||
| 39 | config TIMER_USE_PWM0 | ||
| 40 | bool "Use PWM Timer 0" | ||
| 41 | help | ||
| 42 | Use PWM Timer 0 as the default clockevent/clocksourcer. | ||
| 43 | |||
| 44 | config TIMER_USE_PWM1 | ||
| 45 | bool "Use PWM Timer 1" | ||
| 46 | help | ||
| 47 | Use PWM Timer 1 as the default clockevent/clocksourcer. | ||
| 48 | |||
| 49 | config TIMER_USE_PWM2 | ||
| 50 | bool "Use PWM Timer 2" | ||
| 51 | help | ||
| 52 | Use PWM Timer 2 as the default clockevent/clocksourcer. | ||
| 53 | |||
| 54 | config TIMER_USE_PWM3 | ||
| 55 | bool "Use PWM Timer 3" | ||
| 56 | help | ||
| 57 | Use PWM Timer 3 as the default clockevent/clocksourcer. | ||
| 58 | |||
| 59 | endchoice | ||
| 60 | |||
| 23 | endif # MACH_LOONGSON1 | 61 | endif # MACH_LOONGSON1 |
diff --git a/arch/mips/loongson1/common/Makefile b/arch/mips/loongson1/common/Makefile index b2797709ef5b..723b4ce3b8f0 100644 --- a/arch/mips/loongson1/common/Makefile +++ b/arch/mips/loongson1/common/Makefile | |||
| @@ -2,4 +2,4 @@ | |||
| 2 | # Makefile for common code of loongson1 based machines. | 2 | # Makefile for common code of loongson1 based machines. |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-y += clock.o irq.o platform.o prom.o reset.o setup.o | 5 | obj-y += time.o irq.o platform.o prom.o reset.o setup.o |
diff --git a/arch/mips/loongson1/common/clock.c b/arch/mips/loongson1/common/clock.c deleted file mode 100644 index b4437f19c3d9..000000000000 --- a/arch/mips/loongson1/common/clock.c +++ /dev/null | |||
| @@ -1,28 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License as published by the | ||
| 6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 7 | * option) any later version. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/clk.h> | ||
| 11 | #include <linux/err.h> | ||
| 12 | #include <asm/time.h> | ||
| 13 | #include <platform.h> | ||
| 14 | |||
| 15 | void __init plat_time_init(void) | ||
| 16 | { | ||
| 17 | struct clk *clk; | ||
| 18 | |||
| 19 | /* Initialize LS1X clocks */ | ||
| 20 | ls1x_clk_init(); | ||
| 21 | |||
| 22 | /* setup mips r4k timer */ | ||
| 23 | clk = clk_get(NULL, "cpu"); | ||
| 24 | if (IS_ERR(clk)) | ||
| 25 | panic("unable to get cpu clock, err=%ld", PTR_ERR(clk)); | ||
| 26 | |||
| 27 | mips_hpt_frequency = clk_get_rate(clk) / 2; | ||
| 28 | } | ||
diff --git a/arch/mips/loongson1/common/platform.c b/arch/mips/loongson1/common/platform.c index fdf8cb5987a4..ddf1d4cbf31e 100644 --- a/arch/mips/loongson1/common/platform.c +++ b/arch/mips/loongson1/common/platform.c | |||
| @@ -16,8 +16,10 @@ | |||
| 16 | #include <linux/usb/ehci_pdriver.h> | 16 | #include <linux/usb/ehci_pdriver.h> |
| 17 | #include <asm-generic/sizes.h> | 17 | #include <asm-generic/sizes.h> |
| 18 | 18 | ||
| 19 | #include <cpufreq.h> | ||
| 19 | #include <loongson1.h> | 20 | #include <loongson1.h> |
| 20 | 21 | ||
| 22 | /* 8250/16550 compatible UART */ | ||
| 21 | #define LS1X_UART(_id) \ | 23 | #define LS1X_UART(_id) \ |
| 22 | { \ | 24 | { \ |
| 23 | .mapbase = LS1X_UART ## _id ## _BASE, \ | 25 | .mapbase = LS1X_UART ## _id ## _BASE, \ |
| @@ -27,7 +29,7 @@ | |||
| 27 | .type = PORT_16550A, \ | 29 | .type = PORT_16550A, \ |
| 28 | } | 30 | } |
| 29 | 31 | ||
| 30 | static struct plat_serial8250_port ls1x_serial8250_port[] = { | 32 | static struct plat_serial8250_port ls1x_serial8250_pdata[] = { |
| 31 | LS1X_UART(0), | 33 | LS1X_UART(0), |
| 32 | LS1X_UART(1), | 34 | LS1X_UART(1), |
| 33 | LS1X_UART(2), | 35 | LS1X_UART(2), |
| @@ -35,11 +37,11 @@ static struct plat_serial8250_port ls1x_serial8250_port[] = { | |||
| 35 | {}, | 37 | {}, |
| 36 | }; | 38 | }; |
| 37 | 39 | ||
| 38 | struct platform_device ls1x_uart_device = { | 40 | struct platform_device ls1x_uart_pdev = { |
| 39 | .name = "serial8250", | 41 | .name = "serial8250", |
| 40 | .id = PLAT8250_DEV_PLATFORM, | 42 | .id = PLAT8250_DEV_PLATFORM, |
| 41 | .dev = { | 43 | .dev = { |
| 42 | .platform_data = ls1x_serial8250_port, | 44 | .platform_data = ls1x_serial8250_pdata, |
| 43 | }, | 45 | }, |
| 44 | }; | 46 | }; |
| 45 | 47 | ||
| @@ -48,16 +50,97 @@ void __init ls1x_serial_setup(struct platform_device *pdev) | |||
| 48 | struct clk *clk; | 50 | struct clk *clk; |
| 49 | struct plat_serial8250_port *p; | 51 | struct plat_serial8250_port *p; |
| 50 | 52 | ||
| 51 | clk = clk_get(NULL, pdev->name); | 53 | clk = clk_get(&pdev->dev, pdev->name); |
| 52 | if (IS_ERR(clk)) | 54 | if (IS_ERR(clk)) { |
| 53 | panic("unable to get %s clock, err=%ld", | 55 | pr_err("unable to get %s clock, err=%ld", |
| 54 | pdev->name, PTR_ERR(clk)); | 56 | pdev->name, PTR_ERR(clk)); |
| 57 | return; | ||
| 58 | } | ||
| 59 | clk_prepare_enable(clk); | ||
| 55 | 60 | ||
| 56 | for (p = pdev->dev.platform_data; p->flags != 0; ++p) | 61 | for (p = pdev->dev.platform_data; p->flags != 0; ++p) |
| 57 | p->uartclk = clk_get_rate(clk); | 62 | p->uartclk = clk_get_rate(clk); |
| 58 | } | 63 | } |
| 59 | 64 | ||
| 65 | /* CPUFreq */ | ||
| 66 | static struct plat_ls1x_cpufreq ls1x_cpufreq_pdata = { | ||
| 67 | .clk_name = "cpu_clk", | ||
| 68 | .osc_clk_name = "osc_33m_clk", | ||
| 69 | .max_freq = 266 * 1000, | ||
| 70 | .min_freq = 33 * 1000, | ||
| 71 | }; | ||
| 72 | |||
| 73 | struct platform_device ls1x_cpufreq_pdev = { | ||
| 74 | .name = "ls1x-cpufreq", | ||
| 75 | .dev = { | ||
| 76 | .platform_data = &ls1x_cpufreq_pdata, | ||
| 77 | }, | ||
| 78 | }; | ||
| 79 | |||
| 60 | /* Synopsys Ethernet GMAC */ | 80 | /* Synopsys Ethernet GMAC */ |
| 81 | static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = { | ||
| 82 | .phy_mask = 0, | ||
| 83 | }; | ||
| 84 | |||
| 85 | static struct stmmac_dma_cfg ls1x_eth_dma_cfg = { | ||
| 86 | .pbl = 1, | ||
| 87 | }; | ||
| 88 | |||
| 89 | int ls1x_eth_mux_init(struct platform_device *pdev, void *priv) | ||
| 90 | { | ||
| 91 | struct plat_stmmacenet_data *plat_dat = NULL; | ||
| 92 | u32 val; | ||
| 93 | |||
| 94 | val = __raw_readl(LS1X_MUX_CTRL1); | ||
| 95 | |||
| 96 | plat_dat = dev_get_platdata(&pdev->dev); | ||
| 97 | if (plat_dat->bus_id) { | ||
| 98 | __raw_writel(__raw_readl(LS1X_MUX_CTRL0) | GMAC1_USE_UART1 | | ||
| 99 | GMAC1_USE_UART0, LS1X_MUX_CTRL0); | ||
| 100 | switch (plat_dat->interface) { | ||
| 101 | case PHY_INTERFACE_MODE_RGMII: | ||
| 102 | val &= ~(GMAC1_USE_TXCLK | GMAC1_USE_PWM23); | ||
| 103 | break; | ||
| 104 | case PHY_INTERFACE_MODE_MII: | ||
| 105 | val |= (GMAC1_USE_TXCLK | GMAC1_USE_PWM23); | ||
| 106 | break; | ||
| 107 | default: | ||
| 108 | pr_err("unsupported mii mode %d\n", | ||
| 109 | plat_dat->interface); | ||
| 110 | return -ENOTSUPP; | ||
| 111 | } | ||
| 112 | val &= ~GMAC1_SHUT; | ||
| 113 | } else { | ||
| 114 | switch (plat_dat->interface) { | ||
| 115 | case PHY_INTERFACE_MODE_RGMII: | ||
| 116 | val &= ~(GMAC0_USE_TXCLK | GMAC0_USE_PWM01); | ||
| 117 | break; | ||
| 118 | case PHY_INTERFACE_MODE_MII: | ||
| 119 | val |= (GMAC0_USE_TXCLK | GMAC0_USE_PWM01); | ||
| 120 | break; | ||
| 121 | default: | ||
| 122 | pr_err("unsupported mii mode %d\n", | ||
| 123 | plat_dat->interface); | ||
| 124 | return -ENOTSUPP; | ||
| 125 | } | ||
| 126 | val &= ~GMAC0_SHUT; | ||
| 127 | } | ||
| 128 | __raw_writel(val, LS1X_MUX_CTRL1); | ||
| 129 | |||
| 130 | return 0; | ||
| 131 | } | ||
| 132 | |||
| 133 | static struct plat_stmmacenet_data ls1x_eth0_pdata = { | ||
| 134 | .bus_id = 0, | ||
| 135 | .phy_addr = -1, | ||
| 136 | .interface = PHY_INTERFACE_MODE_MII, | ||
| 137 | .mdio_bus_data = &ls1x_mdio_bus_data, | ||
| 138 | .dma_cfg = &ls1x_eth_dma_cfg, | ||
| 139 | .has_gmac = 1, | ||
| 140 | .tx_coe = 1, | ||
| 141 | .init = ls1x_eth_mux_init, | ||
| 142 | }; | ||
| 143 | |||
| 61 | static struct resource ls1x_eth0_resources[] = { | 144 | static struct resource ls1x_eth0_resources[] = { |
| 62 | [0] = { | 145 | [0] = { |
| 63 | .start = LS1X_GMAC0_BASE, | 146 | .start = LS1X_GMAC0_BASE, |
| @@ -71,25 +154,47 @@ static struct resource ls1x_eth0_resources[] = { | |||
| 71 | }, | 154 | }, |
| 72 | }; | 155 | }; |
| 73 | 156 | ||
| 74 | static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = { | 157 | struct platform_device ls1x_eth0_pdev = { |
| 75 | .phy_mask = 0, | 158 | .name = "stmmaceth", |
| 159 | .id = 0, | ||
| 160 | .num_resources = ARRAY_SIZE(ls1x_eth0_resources), | ||
| 161 | .resource = ls1x_eth0_resources, | ||
| 162 | .dev = { | ||
| 163 | .platform_data = &ls1x_eth0_pdata, | ||
| 164 | }, | ||
| 76 | }; | 165 | }; |
| 77 | 166 | ||
| 78 | static struct plat_stmmacenet_data ls1x_eth_data = { | 167 | static struct plat_stmmacenet_data ls1x_eth1_pdata = { |
| 79 | .bus_id = 0, | 168 | .bus_id = 1, |
| 80 | .phy_addr = -1, | 169 | .phy_addr = -1, |
| 170 | .interface = PHY_INTERFACE_MODE_MII, | ||
| 81 | .mdio_bus_data = &ls1x_mdio_bus_data, | 171 | .mdio_bus_data = &ls1x_mdio_bus_data, |
| 172 | .dma_cfg = &ls1x_eth_dma_cfg, | ||
| 82 | .has_gmac = 1, | 173 | .has_gmac = 1, |
| 83 | .tx_coe = 1, | 174 | .tx_coe = 1, |
| 175 | .init = ls1x_eth_mux_init, | ||
| 84 | }; | 176 | }; |
| 85 | 177 | ||
| 86 | struct platform_device ls1x_eth0_device = { | 178 | static struct resource ls1x_eth1_resources[] = { |
| 179 | [0] = { | ||
| 180 | .start = LS1X_GMAC1_BASE, | ||
| 181 | .end = LS1X_GMAC1_BASE + SZ_64K - 1, | ||
| 182 | .flags = IORESOURCE_MEM, | ||
| 183 | }, | ||
| 184 | [1] = { | ||
| 185 | .name = "macirq", | ||
| 186 | .start = LS1X_GMAC1_IRQ, | ||
| 187 | .flags = IORESOURCE_IRQ, | ||
| 188 | }, | ||
| 189 | }; | ||
| 190 | |||
| 191 | struct platform_device ls1x_eth1_pdev = { | ||
| 87 | .name = "stmmaceth", | 192 | .name = "stmmaceth", |
| 88 | .id = 0, | 193 | .id = 1, |
| 89 | .num_resources = ARRAY_SIZE(ls1x_eth0_resources), | 194 | .num_resources = ARRAY_SIZE(ls1x_eth1_resources), |
| 90 | .resource = ls1x_eth0_resources, | 195 | .resource = ls1x_eth1_resources, |
| 91 | .dev = { | 196 | .dev = { |
| 92 | .platform_data = &ls1x_eth_data, | 197 | .platform_data = &ls1x_eth1_pdata, |
| 93 | }, | 198 | }, |
| 94 | }; | 199 | }; |
| 95 | 200 | ||
| @@ -111,7 +216,7 @@ static struct resource ls1x_ehci_resources[] = { | |||
| 111 | static struct usb_ehci_pdata ls1x_ehci_pdata = { | 216 | static struct usb_ehci_pdata ls1x_ehci_pdata = { |
| 112 | }; | 217 | }; |
| 113 | 218 | ||
| 114 | struct platform_device ls1x_ehci_device = { | 219 | struct platform_device ls1x_ehci_pdev = { |
| 115 | .name = "ehci-platform", | 220 | .name = "ehci-platform", |
| 116 | .id = -1, | 221 | .id = -1, |
| 117 | .num_resources = ARRAY_SIZE(ls1x_ehci_resources), | 222 | .num_resources = ARRAY_SIZE(ls1x_ehci_resources), |
| @@ -123,7 +228,7 @@ struct platform_device ls1x_ehci_device = { | |||
| 123 | }; | 228 | }; |
| 124 | 229 | ||
| 125 | /* Real Time Clock */ | 230 | /* Real Time Clock */ |
| 126 | struct platform_device ls1x_rtc_device = { | 231 | struct platform_device ls1x_rtc_pdev = { |
| 127 | .name = "ls1x-rtc", | 232 | .name = "ls1x-rtc", |
| 128 | .id = -1, | 233 | .id = -1, |
| 129 | }; | 234 | }; |
diff --git a/arch/mips/loongson1/common/prom.c b/arch/mips/loongson1/common/prom.c index 2a47af5a55c3..68600980ea49 100644 --- a/arch/mips/loongson1/common/prom.c +++ b/arch/mips/loongson1/common/prom.c | |||
| @@ -27,7 +27,7 @@ char *prom_getenv(char *envname) | |||
| 27 | i = strlen(envname); | 27 | i = strlen(envname); |
| 28 | 28 | ||
| 29 | while (*env) { | 29 | while (*env) { |
| 30 | if (strncmp(envname, *env, i) == 0 && *(*env+i) == '=') | 30 | if (strncmp(envname, *env, i) == 0 && *(*env + i) == '=') |
| 31 | return *env + i + 1; | 31 | return *env + i + 1; |
| 32 | env++; | 32 | env++; |
| 33 | } | 33 | } |
| @@ -49,7 +49,7 @@ void __init prom_init_cmdline(void) | |||
| 49 | for (i = 1; i < prom_argc; i++) { | 49 | for (i = 1; i < prom_argc; i++) { |
| 50 | strcpy(c, prom_argv[i]); | 50 | strcpy(c, prom_argv[i]); |
| 51 | c += strlen(prom_argv[i]); | 51 | c += strlen(prom_argv[i]); |
| 52 | if (i < prom_argc-1) | 52 | if (i < prom_argc - 1) |
| 53 | *c++ = ' '; | 53 | *c++ = ' '; |
| 54 | } | 54 | } |
| 55 | *c = 0; | 55 | *c = 0; |
| @@ -57,6 +57,7 @@ void __init prom_init_cmdline(void) | |||
| 57 | 57 | ||
| 58 | void __init prom_init(void) | 58 | void __init prom_init(void) |
| 59 | { | 59 | { |
| 60 | void __iomem *uart_base; | ||
| 60 | prom_argc = fw_arg0; | 61 | prom_argc = fw_arg0; |
| 61 | prom_argv = (char **)fw_arg1; | 62 | prom_argv = (char **)fw_arg1; |
| 62 | prom_envp = (char **)fw_arg2; | 63 | prom_envp = (char **)fw_arg2; |
| @@ -65,23 +66,18 @@ void __init prom_init(void) | |||
| 65 | 66 | ||
| 66 | memsize = env_or_default("memsize", DEFAULT_MEMSIZE); | 67 | memsize = env_or_default("memsize", DEFAULT_MEMSIZE); |
| 67 | highmemsize = env_or_default("highmemsize", 0x0); | 68 | highmemsize = env_or_default("highmemsize", 0x0); |
| 68 | } | ||
| 69 | 69 | ||
| 70 | void __init prom_free_prom_memory(void) | 70 | if (strstr(arcs_cmdline, "console=ttyS3")) |
| 71 | { | 71 | uart_base = ioremap_nocache(LS1X_UART3_BASE, 0x0f); |
| 72 | else if (strstr(arcs_cmdline, "console=ttyS2")) | ||
| 73 | uart_base = ioremap_nocache(LS1X_UART2_BASE, 0x0f); | ||
| 74 | else if (strstr(arcs_cmdline, "console=ttyS1")) | ||
| 75 | uart_base = ioremap_nocache(LS1X_UART1_BASE, 0x0f); | ||
| 76 | else | ||
| 77 | uart_base = ioremap_nocache(LS1X_UART0_BASE, 0x0f); | ||
| 78 | setup_8250_early_printk_port((unsigned long)uart_base, 0, 0); | ||
| 72 | } | 79 | } |
| 73 | 80 | ||
| 74 | #define PORT(offset) (u8 *)(KSEG1ADDR(LS1X_UART0_BASE + offset)) | 81 | void __init prom_free_prom_memory(void) |
| 75 | |||
| 76 | void prom_putchar(char c) | ||
| 77 | { | 82 | { |
| 78 | int timeout; | ||
| 79 | |||
| 80 | timeout = 1024; | ||
| 81 | |||
| 82 | while (((readb(PORT(UART_LSR)) & UART_LSR_THRE) == 0) | ||
| 83 | && (timeout-- > 0)) | ||
| 84 | ; | ||
| 85 | |||
| 86 | writeb(c, PORT(UART_TX)); | ||
| 87 | } | 83 | } |
diff --git a/arch/mips/loongson1/common/reset.c b/arch/mips/loongson1/common/reset.c index 547f34b69e4c..c41e4ca56ab4 100644 --- a/arch/mips/loongson1/common/reset.c +++ b/arch/mips/loongson1/common/reset.c | |||
| @@ -14,12 +14,7 @@ | |||
| 14 | 14 | ||
| 15 | #include <loongson1.h> | 15 | #include <loongson1.h> |
| 16 | 16 | ||
| 17 | static void ls1x_restart(char *command) | 17 | static void __iomem *wdt_base; |
| 18 | { | ||
| 19 | __raw_writel(0x1, LS1X_WDT_EN); | ||
| 20 | __raw_writel(0x5000000, LS1X_WDT_TIMER); | ||
| 21 | __raw_writel(0x1, LS1X_WDT_SET); | ||
| 22 | } | ||
| 23 | 18 | ||
| 24 | static void ls1x_halt(void) | 19 | static void ls1x_halt(void) |
| 25 | { | 20 | { |
| @@ -29,6 +24,15 @@ static void ls1x_halt(void) | |||
| 29 | } | 24 | } |
| 30 | } | 25 | } |
| 31 | 26 | ||
| 27 | static void ls1x_restart(char *command) | ||
| 28 | { | ||
| 29 | __raw_writel(0x1, wdt_base + WDT_EN); | ||
| 30 | __raw_writel(0x1, wdt_base + WDT_TIMER); | ||
| 31 | __raw_writel(0x1, wdt_base + WDT_SET); | ||
| 32 | |||
| 33 | ls1x_halt(); | ||
| 34 | } | ||
| 35 | |||
| 32 | static void ls1x_power_off(void) | 36 | static void ls1x_power_off(void) |
| 33 | { | 37 | { |
| 34 | ls1x_halt(); | 38 | ls1x_halt(); |
| @@ -36,6 +40,10 @@ static void ls1x_power_off(void) | |||
| 36 | 40 | ||
| 37 | static int __init ls1x_reboot_setup(void) | 41 | static int __init ls1x_reboot_setup(void) |
| 38 | { | 42 | { |
| 43 | wdt_base = ioremap_nocache(LS1X_WDT_BASE, 0x0f); | ||
| 44 | if (!wdt_base) | ||
| 45 | panic("Failed to remap watchdog registers"); | ||
| 46 | |||
| 39 | _machine_restart = ls1x_restart; | 47 | _machine_restart = ls1x_restart; |
| 40 | _machine_halt = ls1x_halt; | 48 | _machine_halt = ls1x_halt; |
| 41 | pm_power_off = ls1x_power_off; | 49 | pm_power_off = ls1x_power_off; |
diff --git a/arch/mips/loongson1/common/time.c b/arch/mips/loongson1/common/time.c new file mode 100644 index 000000000000..df0f850d6a5f --- /dev/null +++ b/arch/mips/loongson1/common/time.c | |||
| @@ -0,0 +1,226 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com> | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License as published by the | ||
| 6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 7 | * option) any later version. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/clk.h> | ||
| 11 | #include <linux/interrupt.h> | ||
| 12 | #include <asm/time.h> | ||
| 13 | |||
| 14 | #include <loongson1.h> | ||
| 15 | #include <platform.h> | ||
| 16 | |||
| 17 | #ifdef CONFIG_CEVT_CSRC_LS1X | ||
| 18 | |||
| 19 | #if defined(CONFIG_TIMER_USE_PWM1) | ||
| 20 | #define LS1X_TIMER_BASE LS1X_PWM1_BASE | ||
| 21 | #define LS1X_TIMER_IRQ LS1X_PWM1_IRQ | ||
| 22 | |||
| 23 | #elif defined(CONFIG_TIMER_USE_PWM2) | ||
| 24 | #define LS1X_TIMER_BASE LS1X_PWM2_BASE | ||
| 25 | #define LS1X_TIMER_IRQ LS1X_PWM2_IRQ | ||
| 26 | |||
| 27 | #elif defined(CONFIG_TIMER_USE_PWM3) | ||
| 28 | #define LS1X_TIMER_BASE LS1X_PWM3_BASE | ||
| 29 | #define LS1X_TIMER_IRQ LS1X_PWM3_IRQ | ||
| 30 | |||
| 31 | #else | ||
| 32 | #define LS1X_TIMER_BASE LS1X_PWM0_BASE | ||
| 33 | #define LS1X_TIMER_IRQ LS1X_PWM0_IRQ | ||
| 34 | #endif | ||
| 35 | |||
| 36 | DEFINE_RAW_SPINLOCK(ls1x_timer_lock); | ||
| 37 | |||
| 38 | static void __iomem *timer_base; | ||
| 39 | static uint32_t ls1x_jiffies_per_tick; | ||
| 40 | |||
| 41 | static inline void ls1x_pwmtimer_set_period(uint32_t period) | ||
| 42 | { | ||
| 43 | __raw_writel(period, timer_base + PWM_HRC); | ||
| 44 | __raw_writel(period, timer_base + PWM_LRC); | ||
| 45 | } | ||
| 46 | |||
| 47 | static inline void ls1x_pwmtimer_restart(void) | ||
| 48 | { | ||
| 49 | __raw_writel(0x0, timer_base + PWM_CNT); | ||
| 50 | __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL); | ||
| 51 | } | ||
| 52 | |||
| 53 | void __init ls1x_pwmtimer_init(void) | ||
| 54 | { | ||
| 55 | timer_base = ioremap(LS1X_TIMER_BASE, 0xf); | ||
| 56 | if (!timer_base) | ||
| 57 | panic("Failed to remap timer registers"); | ||
| 58 | |||
| 59 | ls1x_jiffies_per_tick = DIV_ROUND_CLOSEST(mips_hpt_frequency, HZ); | ||
| 60 | |||
| 61 | ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick); | ||
| 62 | ls1x_pwmtimer_restart(); | ||
| 63 | } | ||
| 64 | |||
| 65 | static cycle_t ls1x_clocksource_read(struct clocksource *cs) | ||
| 66 | { | ||
| 67 | unsigned long flags; | ||
| 68 | int count; | ||
| 69 | u32 jifs; | ||
| 70 | static int old_count; | ||
| 71 | static u32 old_jifs; | ||
| 72 | |||
| 73 | raw_spin_lock_irqsave(&ls1x_timer_lock, flags); | ||
| 74 | /* | ||
| 75 | * Although our caller may have the read side of xtime_lock, | ||
| 76 | * this is now a seqlock, and we are cheating in this routine | ||
| 77 | * by having side effects on state that we cannot undo if | ||
| 78 | * there is a collision on the seqlock and our caller has to | ||
| 79 | * retry. (Namely, old_jifs and old_count.) So we must treat | ||
| 80 | * jiffies as volatile despite the lock. We read jiffies | ||
| 81 | * before latching the timer count to guarantee that although | ||
| 82 | * the jiffies value might be older than the count (that is, | ||
| 83 | * the counter may underflow between the last point where | ||
| 84 | * jiffies was incremented and the point where we latch the | ||
| 85 | * count), it cannot be newer. | ||
| 86 | */ | ||
| 87 | jifs = jiffies; | ||
| 88 | /* read the count */ | ||
| 89 | count = __raw_readl(timer_base + PWM_CNT); | ||
| 90 | |||
| 91 | /* | ||
| 92 | * It's possible for count to appear to go the wrong way for this | ||
| 93 | * reason: | ||
| 94 | * | ||
| 95 | * The timer counter underflows, but we haven't handled the resulting | ||
| 96 | * interrupt and incremented jiffies yet. | ||
| 97 | * | ||
| 98 | * Previous attempts to handle these cases intelligently were buggy, so | ||
| 99 | * we just do the simple thing now. | ||
| 100 | */ | ||
| 101 | if (count < old_count && jifs == old_jifs) | ||
| 102 | count = old_count; | ||
| 103 | |||
| 104 | old_count = count; | ||
| 105 | old_jifs = jifs; | ||
| 106 | |||
| 107 | raw_spin_unlock_irqrestore(&ls1x_timer_lock, flags); | ||
| 108 | |||
| 109 | return (cycle_t) (jifs * ls1x_jiffies_per_tick) + count; | ||
| 110 | } | ||
| 111 | |||
| 112 | static struct clocksource ls1x_clocksource = { | ||
| 113 | .name = "ls1x-pwmtimer", | ||
| 114 | .read = ls1x_clocksource_read, | ||
| 115 | .mask = CLOCKSOURCE_MASK(24), | ||
| 116 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
| 117 | }; | ||
| 118 | |||
| 119 | static irqreturn_t ls1x_clockevent_isr(int irq, void *devid) | ||
| 120 | { | ||
| 121 | struct clock_event_device *cd = devid; | ||
| 122 | |||
| 123 | ls1x_pwmtimer_restart(); | ||
| 124 | cd->event_handler(cd); | ||
| 125 | |||
| 126 | return IRQ_HANDLED; | ||
| 127 | } | ||
| 128 | |||
| 129 | static void ls1x_clockevent_set_mode(enum clock_event_mode mode, | ||
| 130 | struct clock_event_device *cd) | ||
| 131 | { | ||
| 132 | raw_spin_lock(&ls1x_timer_lock); | ||
| 133 | switch (mode) { | ||
| 134 | case CLOCK_EVT_MODE_PERIODIC: | ||
| 135 | ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick); | ||
| 136 | ls1x_pwmtimer_restart(); | ||
| 137 | case CLOCK_EVT_MODE_RESUME: | ||
| 138 | __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL); | ||
| 139 | break; | ||
| 140 | case CLOCK_EVT_MODE_ONESHOT: | ||
| 141 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
| 142 | __raw_writel(__raw_readl(timer_base + PWM_CTRL) & ~CNT_EN, | ||
| 143 | timer_base + PWM_CTRL); | ||
| 144 | break; | ||
| 145 | default: | ||
| 146 | break; | ||
| 147 | } | ||
| 148 | raw_spin_unlock(&ls1x_timer_lock); | ||
| 149 | } | ||
| 150 | |||
| 151 | static int ls1x_clockevent_set_next(unsigned long evt, | ||
| 152 | struct clock_event_device *cd) | ||
| 153 | { | ||
| 154 | raw_spin_lock(&ls1x_timer_lock); | ||
| 155 | ls1x_pwmtimer_set_period(evt); | ||
| 156 | ls1x_pwmtimer_restart(); | ||
| 157 | raw_spin_unlock(&ls1x_timer_lock); | ||
| 158 | |||
| 159 | return 0; | ||
| 160 | } | ||
| 161 | |||
| 162 | static struct clock_event_device ls1x_clockevent = { | ||
| 163 | .name = "ls1x-pwmtimer", | ||
| 164 | .features = CLOCK_EVT_FEAT_PERIODIC, | ||
| 165 | .rating = 300, | ||
| 166 | .irq = LS1X_TIMER_IRQ, | ||
| 167 | .set_next_event = ls1x_clockevent_set_next, | ||
| 168 | .set_mode = ls1x_clockevent_set_mode, | ||
| 169 | }; | ||
| 170 | |||
| 171 | static struct irqaction ls1x_pwmtimer_irqaction = { | ||
| 172 | .name = "ls1x-pwmtimer", | ||
| 173 | .handler = ls1x_clockevent_isr, | ||
| 174 | .dev_id = &ls1x_clockevent, | ||
| 175 | .flags = IRQF_PERCPU | IRQF_TIMER, | ||
| 176 | }; | ||
| 177 | |||
| 178 | static void __init ls1x_time_init(void) | ||
| 179 | { | ||
| 180 | struct clock_event_device *cd = &ls1x_clockevent; | ||
| 181 | int ret; | ||
| 182 | |||
| 183 | if (!mips_hpt_frequency) | ||
| 184 | panic("Invalid timer clock rate"); | ||
| 185 | |||
| 186 | ls1x_pwmtimer_init(); | ||
| 187 | |||
| 188 | clockevent_set_clock(cd, mips_hpt_frequency); | ||
| 189 | cd->max_delta_ns = clockevent_delta2ns(0xffffff, cd); | ||
| 190 | cd->min_delta_ns = clockevent_delta2ns(0x000300, cd); | ||
| 191 | cd->cpumask = cpumask_of(smp_processor_id()); | ||
| 192 | clockevents_register_device(cd); | ||
| 193 | |||
| 194 | ls1x_clocksource.rating = 200 + mips_hpt_frequency / 10000000; | ||
| 195 | ret = clocksource_register_hz(&ls1x_clocksource, mips_hpt_frequency); | ||
| 196 | if (ret) | ||
| 197 | panic(KERN_ERR "Failed to register clocksource: %d\n", ret); | ||
| 198 | |||
| 199 | setup_irq(LS1X_TIMER_IRQ, &ls1x_pwmtimer_irqaction); | ||
| 200 | } | ||
| 201 | #endif /* CONFIG_CEVT_CSRC_LS1X */ | ||
| 202 | |||
| 203 | void __init plat_time_init(void) | ||
| 204 | { | ||
| 205 | struct clk *clk = NULL; | ||
| 206 | |||
| 207 | /* initialize LS1X clocks */ | ||
| 208 | ls1x_clk_init(); | ||
| 209 | |||
| 210 | #ifdef CONFIG_CEVT_CSRC_LS1X | ||
| 211 | /* setup LS1X PWM timer */ | ||
| 212 | clk = clk_get(NULL, "ls1x_pwmtimer"); | ||
| 213 | if (IS_ERR(clk)) | ||
| 214 | panic("unable to get timer clock, err=%ld", PTR_ERR(clk)); | ||
| 215 | |||
| 216 | mips_hpt_frequency = clk_get_rate(clk); | ||
| 217 | ls1x_time_init(); | ||
| 218 | #else | ||
| 219 | /* setup mips r4k timer */ | ||
| 220 | clk = clk_get(NULL, "cpu_clk"); | ||
| 221 | if (IS_ERR(clk)) | ||
| 222 | panic("unable to get cpu clock, err=%ld", PTR_ERR(clk)); | ||
| 223 | |||
| 224 | mips_hpt_frequency = clk_get_rate(clk) / 2; | ||
| 225 | #endif /* CONFIG_CEVT_CSRC_LS1X */ | ||
| 226 | } | ||
diff --git a/arch/mips/loongson1/ls1b/board.c b/arch/mips/loongson1/ls1b/board.c index b26b10dac70a..58daeea25739 100644 --- a/arch/mips/loongson1/ls1b/board.c +++ b/arch/mips/loongson1/ls1b/board.c | |||
| @@ -10,17 +10,19 @@ | |||
| 10 | #include <platform.h> | 10 | #include <platform.h> |
| 11 | 11 | ||
| 12 | static struct platform_device *ls1b_platform_devices[] __initdata = { | 12 | static struct platform_device *ls1b_platform_devices[] __initdata = { |
| 13 | &ls1x_uart_device, | 13 | &ls1x_uart_pdev, |
| 14 | &ls1x_eth0_device, | 14 | &ls1x_cpufreq_pdev, |
| 15 | &ls1x_ehci_device, | 15 | &ls1x_eth0_pdev, |
| 16 | &ls1x_rtc_device, | 16 | &ls1x_eth1_pdev, |
| 17 | &ls1x_ehci_pdev, | ||
| 18 | &ls1x_rtc_pdev, | ||
| 17 | }; | 19 | }; |
| 18 | 20 | ||
| 19 | static int __init ls1b_platform_init(void) | 21 | static int __init ls1b_platform_init(void) |
| 20 | { | 22 | { |
| 21 | int err; | 23 | int err; |
| 22 | 24 | ||
| 23 | ls1x_serial_setup(&ls1x_uart_device); | 25 | ls1x_serial_setup(&ls1x_uart_pdev); |
| 24 | 26 | ||
| 25 | err = platform_add_devices(ls1b_platform_devices, | 27 | err = platform_add_devices(ls1b_platform_devices, |
| 26 | ARRAY_SIZE(ls1b_platform_devices)); | 28 | ARRAY_SIZE(ls1b_platform_devices)); |
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index cac529a405b8..9dfcd7fc1bc3 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c | |||
| @@ -643,9 +643,14 @@ static inline int cop1_64bit(struct pt_regs *xcp) | |||
| 643 | return !test_thread_flag(TIF_32BIT_FPREGS); | 643 | return !test_thread_flag(TIF_32BIT_FPREGS); |
| 644 | } | 644 | } |
| 645 | 645 | ||
| 646 | static inline bool hybrid_fprs(void) | ||
| 647 | { | ||
| 648 | return test_thread_flag(TIF_HYBRID_FPREGS); | ||
| 649 | } | ||
| 650 | |||
| 646 | #define SIFROMREG(si, x) \ | 651 | #define SIFROMREG(si, x) \ |
| 647 | do { \ | 652 | do { \ |
| 648 | if (cop1_64bit(xcp)) \ | 653 | if (cop1_64bit(xcp) && !hybrid_fprs()) \ |
| 649 | (si) = (int)get_fpr32(&ctx->fpr[x], 0); \ | 654 | (si) = (int)get_fpr32(&ctx->fpr[x], 0); \ |
| 650 | else \ | 655 | else \ |
| 651 | (si) = (int)get_fpr32(&ctx->fpr[(x) & ~1], (x) & 1); \ | 656 | (si) = (int)get_fpr32(&ctx->fpr[(x) & ~1], (x) & 1); \ |
| @@ -653,7 +658,7 @@ do { \ | |||
| 653 | 658 | ||
| 654 | #define SITOREG(si, x) \ | 659 | #define SITOREG(si, x) \ |
| 655 | do { \ | 660 | do { \ |
| 656 | if (cop1_64bit(xcp)) { \ | 661 | if (cop1_64bit(xcp) && !hybrid_fprs()) { \ |
| 657 | unsigned i; \ | 662 | unsigned i; \ |
| 658 | set_fpr32(&ctx->fpr[x], 0, si); \ | 663 | set_fpr32(&ctx->fpr[x], 0, si); \ |
| 659 | for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val32); i++) \ | 664 | for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val32); i++) \ |
diff --git a/arch/mips/math-emu/ieee754dp.c b/arch/mips/math-emu/ieee754dp.c index fd134675fc2e..068f45a415fc 100644 --- a/arch/mips/math-emu/ieee754dp.c +++ b/arch/mips/math-emu/ieee754dp.c | |||
| @@ -38,7 +38,7 @@ int ieee754dp_isnan(union ieee754dp x) | |||
| 38 | static inline int ieee754dp_issnan(union ieee754dp x) | 38 | static inline int ieee754dp_issnan(union ieee754dp x) |
| 39 | { | 39 | { |
| 40 | assert(ieee754dp_isnan(x)); | 40 | assert(ieee754dp_isnan(x)); |
| 41 | return ((DPMANT(x) & DP_MBIT(DP_FBITS-1)) == DP_MBIT(DP_FBITS-1)); | 41 | return (DPMANT(x) & DP_MBIT(DP_FBITS - 1)) == DP_MBIT(DP_FBITS - 1); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | 44 | ||
diff --git a/arch/mips/math-emu/ieee754sp.c b/arch/mips/math-emu/ieee754sp.c index d348efe91445..ba88301579c2 100644 --- a/arch/mips/math-emu/ieee754sp.c +++ b/arch/mips/math-emu/ieee754sp.c | |||
| @@ -38,7 +38,7 @@ int ieee754sp_isnan(union ieee754sp x) | |||
| 38 | static inline int ieee754sp_issnan(union ieee754sp x) | 38 | static inline int ieee754sp_issnan(union ieee754sp x) |
| 39 | { | 39 | { |
| 40 | assert(ieee754sp_isnan(x)); | 40 | assert(ieee754sp_isnan(x)); |
| 41 | return (SPMANT(x) & SP_MBIT(SP_FBITS-1)); | 41 | return SPMANT(x) & SP_MBIT(SP_FBITS - 1); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | 44 | ||
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index 7f4f93ab22b7..67ede4ef9b8d 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile | |||
| @@ -4,7 +4,13 @@ | |||
| 4 | 4 | ||
| 5 | obj-y += cache.o dma-default.o extable.o fault.o \ | 5 | obj-y += cache.o dma-default.o extable.o fault.o \ |
| 6 | gup.o init.o mmap.o page.o page-funcs.o \ | 6 | gup.o init.o mmap.o page.o page-funcs.o \ |
| 7 | tlbex.o tlbex-fault.o tlb-funcs.o uasm-mips.o | 7 | tlbex.o tlbex-fault.o tlb-funcs.o |
| 8 | |||
| 9 | ifdef CONFIG_CPU_MICROMIPS | ||
| 10 | obj-y += uasm-micromips.o | ||
| 11 | else | ||
| 12 | obj-y += uasm-mips.o | ||
| 13 | endif | ||
| 8 | 14 | ||
| 9 | obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o | 15 | obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o |
| 10 | obj-$(CONFIG_64BIT) += pgtable-64.o | 16 | obj-$(CONFIG_64BIT) += pgtable-64.o |
| @@ -22,5 +28,3 @@ obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o | |||
| 22 | obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o | 28 | obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o |
| 23 | obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o | 29 | obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o |
| 24 | obj-$(CONFIG_MIPS_CPU_SCACHE) += sc-mips.o | 30 | obj-$(CONFIG_MIPS_CPU_SCACHE) += sc-mips.o |
| 25 | |||
| 26 | obj-$(CONFIG_SYS_SUPPORTS_MICROMIPS) += uasm-micromips.o | ||
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index fbcd8674ff1d..dd261df005c2 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
| @@ -917,6 +917,18 @@ static inline void alias_74k_erratum(struct cpuinfo_mips *c) | |||
| 917 | } | 917 | } |
| 918 | } | 918 | } |
| 919 | 919 | ||
| 920 | static void b5k_instruction_hazard(void) | ||
| 921 | { | ||
| 922 | __sync(); | ||
| 923 | __sync(); | ||
| 924 | __asm__ __volatile__( | ||
| 925 | " nop; nop; nop; nop; nop; nop; nop; nop\n" | ||
| 926 | " nop; nop; nop; nop; nop; nop; nop; nop\n" | ||
| 927 | " nop; nop; nop; nop; nop; nop; nop; nop\n" | ||
| 928 | " nop; nop; nop; nop; nop; nop; nop; nop\n" | ||
| 929 | : : : "memory"); | ||
| 930 | } | ||
| 931 | |||
| 920 | static char *way_string[] = { NULL, "direct mapped", "2-way", | 932 | static char *way_string[] = { NULL, "direct mapped", "2-way", |
| 921 | "3-way", "4-way", "5-way", "6-way", "7-way", "8-way" | 933 | "3-way", "4-way", "5-way", "6-way", "7-way", "8-way" |
| 922 | }; | 934 | }; |
| @@ -1683,6 +1695,37 @@ void r4k_cache_init(void) | |||
| 1683 | 1695 | ||
| 1684 | coherency_setup(); | 1696 | coherency_setup(); |
| 1685 | board_cache_error_setup = r4k_cache_error_setup; | 1697 | board_cache_error_setup = r4k_cache_error_setup; |
| 1698 | |||
| 1699 | /* | ||
| 1700 | * Per-CPU overrides | ||
| 1701 | */ | ||
| 1702 | switch (current_cpu_type()) { | ||
| 1703 | case CPU_BMIPS4350: | ||
| 1704 | case CPU_BMIPS4380: | ||
| 1705 | /* No IPI is needed because all CPUs share the same D$ */ | ||
| 1706 | flush_data_cache_page = r4k_blast_dcache_page; | ||
| 1707 | break; | ||
| 1708 | case CPU_BMIPS5000: | ||
| 1709 | /* We lose our superpowers if L2 is disabled */ | ||
| 1710 | if (c->scache.flags & MIPS_CACHE_NOT_PRESENT) | ||
| 1711 | break; | ||
| 1712 | |||
| 1713 | /* I$ fills from D$ just by emptying the write buffers */ | ||
| 1714 | flush_cache_page = (void *)b5k_instruction_hazard; | ||
| 1715 | flush_cache_range = (void *)b5k_instruction_hazard; | ||
| 1716 | flush_cache_sigtramp = (void *)b5k_instruction_hazard; | ||
| 1717 | local_flush_data_cache_page = (void *)b5k_instruction_hazard; | ||
| 1718 | flush_data_cache_page = (void *)b5k_instruction_hazard; | ||
| 1719 | flush_icache_range = (void *)b5k_instruction_hazard; | ||
| 1720 | local_flush_icache_range = (void *)b5k_instruction_hazard; | ||
| 1721 | |||
| 1722 | /* Cache aliases are handled in hardware; allow HIGHMEM */ | ||
| 1723 | current_cpu_data.dcache.flags &= ~MIPS_CACHE_ALIASES; | ||
| 1724 | |||
| 1725 | /* Optimization: an L2 flush implicitly flushes the L1 */ | ||
| 1726 | current_cpu_data.options |= MIPS_CPU_INCLUSIVE_CACHES; | ||
| 1727 | break; | ||
| 1728 | } | ||
| 1686 | } | 1729 | } |
| 1687 | 1730 | ||
| 1688 | static int r4k_cache_pm_notifier(struct notifier_block *self, unsigned long cmd, | 1731 | static int r4k_cache_pm_notifier(struct notifier_block *self, unsigned long cmd, |
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 33ba3c558fe4..af5f046e627e 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c | |||
| @@ -61,6 +61,11 @@ static inline struct page *dma_addr_to_page(struct device *dev, | |||
| 61 | * Warning on the terminology - Linux calls an uncached area coherent; | 61 | * Warning on the terminology - Linux calls an uncached area coherent; |
| 62 | * MIPS terminology calls memory areas with hardware maintained coherency | 62 | * MIPS terminology calls memory areas with hardware maintained coherency |
| 63 | * coherent. | 63 | * coherent. |
| 64 | * | ||
| 65 | * Note that the R14000 and R16000 should also be checked for in this | ||
| 66 | * condition. However this function is only called on non-I/O-coherent | ||
| 67 | * systems and only the R10000 and R12000 are used in such systems, the | ||
| 68 | * SGI IP28 Indigo² rsp. SGI IP32 aka O2. | ||
| 64 | */ | 69 | */ |
| 65 | static inline int cpu_needs_post_dma_flush(struct device *dev) | 70 | static inline int cpu_needs_post_dma_flush(struct device *dev) |
| 66 | { | 71 | { |
diff --git a/arch/mips/mm/gup.c b/arch/mips/mm/gup.c index 06ce17c2a905..7cba480568c8 100644 --- a/arch/mips/mm/gup.c +++ b/arch/mips/mm/gup.c | |||
| @@ -17,7 +17,7 @@ | |||
| 17 | 17 | ||
| 18 | static inline pte_t gup_get_pte(pte_t *ptep) | 18 | static inline pte_t gup_get_pte(pte_t *ptep) |
| 19 | { | 19 | { |
| 20 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 20 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
| 21 | pte_t pte; | 21 | pte_t pte; |
| 22 | 22 | ||
| 23 | retry: | 23 | retry: |
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index f42e35e42790..448cde372af0 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
| @@ -95,7 +95,7 @@ static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot) | |||
| 95 | idx += in_interrupt() ? FIX_N_COLOURS : 0; | 95 | idx += in_interrupt() ? FIX_N_COLOURS : 0; |
| 96 | vaddr = __fix_to_virt(FIX_CMAP_END - idx); | 96 | vaddr = __fix_to_virt(FIX_CMAP_END - idx); |
| 97 | pte = mk_pte(page, prot); | 97 | pte = mk_pte(page, prot); |
| 98 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 98 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
| 99 | entrylo = pte.pte_high; | 99 | entrylo = pte.pte_high; |
| 100 | #else | 100 | #else |
| 101 | entrylo = pte_to_entrylo(pte_val(pte)); | 101 | entrylo = pte_to_entrylo(pte_val(pte)); |
diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c index 7f840bc08abf..8d5008cbdc0f 100644 --- a/arch/mips/mm/ioremap.c +++ b/arch/mips/mm/ioremap.c | |||
| @@ -17,9 +17,9 @@ | |||
| 17 | #include <asm/tlbflush.h> | 17 | #include <asm/tlbflush.h> |
| 18 | 18 | ||
| 19 | static inline void remap_area_pte(pte_t * pte, unsigned long address, | 19 | static inline void remap_area_pte(pte_t * pte, unsigned long address, |
| 20 | phys_t size, phys_t phys_addr, unsigned long flags) | 20 | phys_addr_t size, phys_addr_t phys_addr, unsigned long flags) |
| 21 | { | 21 | { |
| 22 | phys_t end; | 22 | phys_addr_t end; |
| 23 | unsigned long pfn; | 23 | unsigned long pfn; |
| 24 | pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE | 24 | pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE |
| 25 | | __WRITEABLE | flags); | 25 | | __WRITEABLE | flags); |
| @@ -43,9 +43,9 @@ static inline void remap_area_pte(pte_t * pte, unsigned long address, | |||
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, | 45 | static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, |
| 46 | phys_t size, phys_t phys_addr, unsigned long flags) | 46 | phys_addr_t size, phys_addr_t phys_addr, unsigned long flags) |
| 47 | { | 47 | { |
| 48 | phys_t end; | 48 | phys_addr_t end; |
| 49 | 49 | ||
| 50 | address &= ~PGDIR_MASK; | 50 | address &= ~PGDIR_MASK; |
| 51 | end = address + size; | 51 | end = address + size; |
| @@ -64,8 +64,8 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, | |||
| 64 | return 0; | 64 | return 0; |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | static int remap_area_pages(unsigned long address, phys_t phys_addr, | 67 | static int remap_area_pages(unsigned long address, phys_addr_t phys_addr, |
| 68 | phys_t size, unsigned long flags) | 68 | phys_addr_t size, unsigned long flags) |
| 69 | { | 69 | { |
| 70 | int error; | 70 | int error; |
| 71 | pgd_t * dir; | 71 | pgd_t * dir; |
| @@ -111,13 +111,13 @@ static int remap_area_pages(unsigned long address, phys_t phys_addr, | |||
| 111 | * caller shouldn't need to know that small detail. | 111 | * caller shouldn't need to know that small detail. |
| 112 | */ | 112 | */ |
| 113 | 113 | ||
| 114 | #define IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL)) | 114 | #define IS_LOW512(addr) (!((phys_addr_t)(addr) & (phys_addr_t) ~0x1fffffffULL)) |
| 115 | 115 | ||
| 116 | void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags) | 116 | void __iomem * __ioremap(phys_addr_t phys_addr, phys_addr_t size, unsigned long flags) |
| 117 | { | 117 | { |
| 118 | struct vm_struct * area; | 118 | struct vm_struct * area; |
| 119 | unsigned long offset; | 119 | unsigned long offset; |
| 120 | phys_t last_addr; | 120 | phys_addr_t last_addr; |
| 121 | void * addr; | 121 | void * addr; |
| 122 | 122 | ||
| 123 | phys_addr = fixup_bigphys_addr(phys_addr, size); | 123 | phys_addr = fixup_bigphys_addr(phys_addr, size); |
diff --git a/arch/mips/mm/sc-r5k.c b/arch/mips/mm/sc-r5k.c index 0216ed6eaa2a..751b5cd18bf2 100644 --- a/arch/mips/mm/sc-r5k.c +++ b/arch/mips/mm/sc-r5k.c | |||
| @@ -81,7 +81,7 @@ static inline int __init r5k_sc_probe(void) | |||
| 81 | unsigned long config = read_c0_config(); | 81 | unsigned long config = read_c0_config(); |
| 82 | 82 | ||
| 83 | if (config & CONF_SC) | 83 | if (config & CONF_SC) |
| 84 | return(0); | 84 | return 0; |
| 85 | 85 | ||
| 86 | scache_size = (512 * 1024) << ((config & R5K_CONF_SS) >> 20); | 86 | scache_size = (512 * 1024) << ((config & R5K_CONF_SS) >> 20); |
| 87 | 87 | ||
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index c3917e251f59..e90b2e899291 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c | |||
| @@ -332,7 +332,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
| 332 | { | 332 | { |
| 333 | ptep = pte_offset_map(pmdp, address); | 333 | ptep = pte_offset_map(pmdp, address); |
| 334 | 334 | ||
| 335 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 335 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
| 336 | write_c0_entrylo0(ptep->pte_high); | 336 | write_c0_entrylo0(ptep->pte_high); |
| 337 | ptep++; | 337 | ptep++; |
| 338 | write_c0_entrylo1(ptep->pte_high); | 338 | write_c0_entrylo1(ptep->pte_high); |
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index e3328a96e809..3978a3d81366 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c | |||
| @@ -637,7 +637,7 @@ static __maybe_unused void build_convert_pte_to_entrylo(u32 **p, | |||
| 637 | if (cpu_has_rixi) { | 637 | if (cpu_has_rixi) { |
| 638 | UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL)); | 638 | UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL)); |
| 639 | } else { | 639 | } else { |
| 640 | #ifdef CONFIG_64BIT_PHYS_ADDR | 640 | #ifdef CONFIG_PHYS_ADDR_T_64BIT |
| 641 | uasm_i_dsrl_safe(p, reg, reg, ilog2(_PAGE_GLOBAL)); | 641 | uasm_i_dsrl_safe(p, reg, reg, ilog2(_PAGE_GLOBAL)); |
| 642 | #else | 642 | #else |
| 643 | UASM_i_SRL(p, reg, reg, ilog2(_PAGE_GLOBAL)); | 643 | UASM_i_SRL(p, reg, reg, ilog2(_PAGE_GLOBAL)); |
| @@ -1009,7 +1009,7 @@ static void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep) | |||
| 1009 | * 64bit address support (36bit on a 32bit CPU) in a 32bit | 1009 | * 64bit address support (36bit on a 32bit CPU) in a 32bit |
| 1010 | * Kernel is a special case. Only a few CPUs use it. | 1010 | * Kernel is a special case. Only a few CPUs use it. |
| 1011 | */ | 1011 | */ |
| 1012 | #ifdef CONFIG_64BIT_PHYS_ADDR | 1012 | #ifdef CONFIG_PHYS_ADDR_T_64BIT |
| 1013 | if (cpu_has_64bits) { | 1013 | if (cpu_has_64bits) { |
| 1014 | uasm_i_ld(p, tmp, 0, ptep); /* get even pte */ | 1014 | uasm_i_ld(p, tmp, 0, ptep); /* get even pte */ |
| 1015 | uasm_i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */ | 1015 | uasm_i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */ |
| @@ -1510,14 +1510,14 @@ static void | |||
| 1510 | iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr) | 1510 | iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr) |
| 1511 | { | 1511 | { |
| 1512 | #ifdef CONFIG_SMP | 1512 | #ifdef CONFIG_SMP |
| 1513 | # ifdef CONFIG_64BIT_PHYS_ADDR | 1513 | # ifdef CONFIG_PHYS_ADDR_T_64BIT |
| 1514 | if (cpu_has_64bits) | 1514 | if (cpu_has_64bits) |
| 1515 | uasm_i_lld(p, pte, 0, ptr); | 1515 | uasm_i_lld(p, pte, 0, ptr); |
| 1516 | else | 1516 | else |
| 1517 | # endif | 1517 | # endif |
| 1518 | UASM_i_LL(p, pte, 0, ptr); | 1518 | UASM_i_LL(p, pte, 0, ptr); |
| 1519 | #else | 1519 | #else |
| 1520 | # ifdef CONFIG_64BIT_PHYS_ADDR | 1520 | # ifdef CONFIG_PHYS_ADDR_T_64BIT |
| 1521 | if (cpu_has_64bits) | 1521 | if (cpu_has_64bits) |
| 1522 | uasm_i_ld(p, pte, 0, ptr); | 1522 | uasm_i_ld(p, pte, 0, ptr); |
| 1523 | else | 1523 | else |
| @@ -1530,13 +1530,13 @@ static void | |||
| 1530 | iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, | 1530 | iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, |
| 1531 | unsigned int mode) | 1531 | unsigned int mode) |
| 1532 | { | 1532 | { |
| 1533 | #ifdef CONFIG_64BIT_PHYS_ADDR | 1533 | #ifdef CONFIG_PHYS_ADDR_T_64BIT |
| 1534 | unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY); | 1534 | unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY); |
| 1535 | #endif | 1535 | #endif |
| 1536 | 1536 | ||
| 1537 | uasm_i_ori(p, pte, pte, mode); | 1537 | uasm_i_ori(p, pte, pte, mode); |
| 1538 | #ifdef CONFIG_SMP | 1538 | #ifdef CONFIG_SMP |
| 1539 | # ifdef CONFIG_64BIT_PHYS_ADDR | 1539 | # ifdef CONFIG_PHYS_ADDR_T_64BIT |
| 1540 | if (cpu_has_64bits) | 1540 | if (cpu_has_64bits) |
| 1541 | uasm_i_scd(p, pte, 0, ptr); | 1541 | uasm_i_scd(p, pte, 0, ptr); |
| 1542 | else | 1542 | else |
| @@ -1548,7 +1548,7 @@ iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, | |||
| 1548 | else | 1548 | else |
| 1549 | uasm_il_beqz(p, r, pte, label_smp_pgtable_change); | 1549 | uasm_il_beqz(p, r, pte, label_smp_pgtable_change); |
| 1550 | 1550 | ||
| 1551 | # ifdef CONFIG_64BIT_PHYS_ADDR | 1551 | # ifdef CONFIG_PHYS_ADDR_T_64BIT |
| 1552 | if (!cpu_has_64bits) { | 1552 | if (!cpu_has_64bits) { |
| 1553 | /* no uasm_i_nop needed */ | 1553 | /* no uasm_i_nop needed */ |
| 1554 | uasm_i_ll(p, pte, sizeof(pte_t) / 2, ptr); | 1554 | uasm_i_ll(p, pte, sizeof(pte_t) / 2, ptr); |
| @@ -1563,14 +1563,14 @@ iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, | |||
| 1563 | uasm_i_nop(p); | 1563 | uasm_i_nop(p); |
| 1564 | # endif | 1564 | # endif |
| 1565 | #else | 1565 | #else |
| 1566 | # ifdef CONFIG_64BIT_PHYS_ADDR | 1566 | # ifdef CONFIG_PHYS_ADDR_T_64BIT |
| 1567 | if (cpu_has_64bits) | 1567 | if (cpu_has_64bits) |
| 1568 | uasm_i_sd(p, pte, 0, ptr); | 1568 | uasm_i_sd(p, pte, 0, ptr); |
| 1569 | else | 1569 | else |
| 1570 | # endif | 1570 | # endif |
| 1571 | UASM_i_SW(p, pte, 0, ptr); | 1571 | UASM_i_SW(p, pte, 0, ptr); |
| 1572 | 1572 | ||
| 1573 | # ifdef CONFIG_64BIT_PHYS_ADDR | 1573 | # ifdef CONFIG_PHYS_ADDR_T_64BIT |
| 1574 | if (!cpu_has_64bits) { | 1574 | if (!cpu_has_64bits) { |
| 1575 | uasm_i_lw(p, pte, sizeof(pte_t) / 2, ptr); | 1575 | uasm_i_lw(p, pte, sizeof(pte_t) / 2, ptr); |
| 1576 | uasm_i_ori(p, pte, pte, hwmode); | 1576 | uasm_i_ori(p, pte, pte, hwmode); |
diff --git a/arch/mips/mm/uasm-mips.c b/arch/mips/mm/uasm-mips.c index 6708a2dbf934..8e02291cfc0c 100644 --- a/arch/mips/mm/uasm-mips.c +++ b/arch/mips/mm/uasm-mips.c | |||
| @@ -96,9 +96,11 @@ static struct insn insn_table[] = { | |||
| 96 | { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | 96 | { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, |
| 97 | { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD }, | 97 | { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD }, |
| 98 | { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET}, | 98 | { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET}, |
| 99 | { insn_mfhc0, M(cop0_op, mfhc0_op, 0, 0, 0, 0), RT | RD | SET}, | ||
| 99 | { insn_mfhi, M(spec_op, 0, 0, 0, 0, mfhi_op), RD }, | 100 | { insn_mfhi, M(spec_op, 0, 0, 0, 0, mfhi_op), RD }, |
| 100 | { insn_mflo, M(spec_op, 0, 0, 0, 0, mflo_op), RD }, | 101 | { insn_mflo, M(spec_op, 0, 0, 0, 0, mflo_op), RD }, |
| 101 | { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET}, | 102 | { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET}, |
| 103 | { insn_mthc0, M(cop0_op, mthc0_op, 0, 0, 0, 0), RT | RD | SET}, | ||
| 102 | { insn_mul, M(spec2_op, 0, 0, 0, 0, mul_op), RS | RT | RD}, | 104 | { insn_mul, M(spec2_op, 0, 0, 0, 0, mul_op), RS | RT | RD}, |
| 103 | { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, | 105 | { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, |
| 104 | { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD }, | 106 | { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD }, |
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c index a01b0d6cedd2..4adf30284813 100644 --- a/arch/mips/mm/uasm.c +++ b/arch/mips/mm/uasm.c | |||
| @@ -51,12 +51,12 @@ enum opcode { | |||
| 51 | insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret, | 51 | insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret, |
| 52 | insn_ext, insn_ins, insn_j, insn_jal, insn_jalr, insn_jr, insn_lb, | 52 | insn_ext, insn_ins, insn_j, insn_jal, insn_jalr, insn_jr, insn_lb, |
| 53 | insn_ld, insn_ldx, insn_lh, insn_ll, insn_lld, insn_lui, insn_lw, | 53 | insn_ld, insn_ldx, insn_lh, insn_ll, insn_lld, insn_lui, insn_lw, |
| 54 | insn_lwx, insn_mfc0, insn_mfhi, insn_mflo, insn_mtc0, insn_mul, | 54 | insn_lwx, insn_mfc0, insn_mfhc0, insn_mfhi, insn_mflo, insn_mtc0, |
| 55 | insn_or, insn_ori, insn_pref, insn_rfe, insn_rotr, insn_sc, insn_scd, | 55 | insn_mthc0, insn_mul, insn_or, insn_ori, insn_pref, insn_rfe, |
| 56 | insn_sd, insn_sll, insn_sllv, insn_slt, insn_sltiu, insn_sltu, insn_sra, | 56 | insn_rotr, insn_sc, insn_scd, insn_sd, insn_sll, insn_sllv, insn_slt, |
| 57 | insn_srl, insn_srlv, insn_subu, insn_sw, insn_sync, insn_syscall, | 57 | insn_sltiu, insn_sltu, insn_sra, insn_srl, insn_srlv, insn_subu, |
| 58 | insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_wait, insn_wsbh, | 58 | insn_sw, insn_sync, insn_syscall, insn_tlbp, insn_tlbr, insn_tlbwi, |
| 59 | insn_xor, insn_xori, insn_yield, | 59 | insn_tlbwr, insn_wait, insn_wsbh, insn_xor, insn_xori, insn_yield, |
| 60 | }; | 60 | }; |
| 61 | 61 | ||
| 62 | struct insn { | 62 | struct insn { |
| @@ -284,9 +284,11 @@ I_u2s3u1(_lld) | |||
| 284 | I_u1s2(_lui) | 284 | I_u1s2(_lui) |
| 285 | I_u2s3u1(_lw) | 285 | I_u2s3u1(_lw) |
| 286 | I_u1u2u3(_mfc0) | 286 | I_u1u2u3(_mfc0) |
| 287 | I_u1u2u3(_mfhc0) | ||
| 287 | I_u1(_mfhi) | 288 | I_u1(_mfhi) |
| 288 | I_u1(_mflo) | 289 | I_u1(_mflo) |
| 289 | I_u1u2u3(_mtc0) | 290 | I_u1u2u3(_mtc0) |
| 291 | I_u1u2u3(_mthc0) | ||
| 290 | I_u3u1u2(_mul) | 292 | I_u3u1u2(_mul) |
| 291 | I_u2u1u3(_ori) | 293 | I_u2u1u3(_ori) |
| 292 | I_u3u1u2(_or) | 294 | I_u3u1u2(_or) |
diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c index 0f60256d3784..6849f533154f 100644 --- a/arch/mips/mti-malta/malta-init.c +++ b/arch/mips/mti-malta/malta-init.c | |||
| @@ -111,7 +111,7 @@ static void __init mips_ejtag_setup(void) | |||
| 111 | flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); | 111 | flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | phys_t mips_cpc_default_phys_base(void) | 114 | phys_addr_t mips_cpc_default_phys_base(void) |
| 115 | { | 115 | { |
| 116 | return CPC_BASE_ADDR; | 116 | return CPC_BASE_ADDR; |
| 117 | } | 117 | } |
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index e4f43baa8f67..d1392f8f5811 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/smp.h> | 18 | #include <linux/smp.h> |
| 19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
| 20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
| 21 | #include <linux/irqchip/mips-gic.h> | ||
| 21 | #include <linux/kernel_stat.h> | 22 | #include <linux/kernel_stat.h> |
| 22 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
| 23 | #include <linux/random.h> | 24 | #include <linux/random.h> |
| @@ -33,19 +34,13 @@ | |||
| 33 | #include <asm/mips-boards/generic.h> | 34 | #include <asm/mips-boards/generic.h> |
| 34 | #include <asm/mips-boards/msc01_pci.h> | 35 | #include <asm/mips-boards/msc01_pci.h> |
| 35 | #include <asm/msc01_ic.h> | 36 | #include <asm/msc01_ic.h> |
| 36 | #include <asm/gic.h> | ||
| 37 | #include <asm/setup.h> | 37 | #include <asm/setup.h> |
| 38 | #include <asm/rtlx.h> | 38 | #include <asm/rtlx.h> |
| 39 | 39 | ||
| 40 | static unsigned long _msc01_biu_base; | 40 | static void __iomem *_msc01_biu_base; |
| 41 | static unsigned int ipi_map[NR_CPUS]; | ||
| 42 | 41 | ||
| 43 | static DEFINE_RAW_SPINLOCK(mips_irq_lock); | 42 | static DEFINE_RAW_SPINLOCK(mips_irq_lock); |
| 44 | 43 | ||
| 45 | #ifdef CONFIG_MIPS_GIC_IPI | ||
| 46 | DECLARE_BITMAP(ipi_ints, GIC_NUM_INTRS); | ||
| 47 | #endif | ||
| 48 | |||
| 49 | static inline int mips_pcibios_iack(void) | 44 | static inline int mips_pcibios_iack(void) |
| 50 | { | 45 | { |
| 51 | int irq; | 46 | int irq; |
| @@ -127,24 +122,10 @@ static void malta_hw0_irqdispatch(void) | |||
| 127 | #endif | 122 | #endif |
| 128 | } | 123 | } |
| 129 | 124 | ||
| 130 | static void malta_ipi_irqdispatch(void) | 125 | static irqreturn_t i8259_handler(int irq, void *dev_id) |
| 131 | { | 126 | { |
| 132 | #ifdef CONFIG_MIPS_GIC_IPI | 127 | malta_hw0_irqdispatch(); |
| 133 | unsigned long irq; | 128 | return IRQ_HANDLED; |
| 134 | DECLARE_BITMAP(pending, GIC_NUM_INTRS); | ||
| 135 | |||
| 136 | gic_get_int_mask(pending, ipi_ints); | ||
| 137 | |||
| 138 | irq = find_first_bit(pending, GIC_NUM_INTRS); | ||
| 139 | |||
| 140 | while (irq < GIC_NUM_INTRS) { | ||
| 141 | do_IRQ(MIPS_GIC_IRQ_BASE + irq); | ||
| 142 | |||
| 143 | irq = find_next_bit(pending, GIC_NUM_INTRS, irq + 1); | ||
| 144 | } | ||
| 145 | #endif | ||
| 146 | if (gic_compare_int()) | ||
| 147 | do_IRQ(MIPS_GIC_IRQ_BASE); | ||
| 148 | } | 129 | } |
| 149 | 130 | ||
| 150 | static void corehi_irqdispatch(void) | 131 | static void corehi_irqdispatch(void) |
| @@ -203,95 +184,10 @@ static void corehi_irqdispatch(void) | |||
| 203 | die("CoreHi interrupt", regs); | 184 | die("CoreHi interrupt", regs); |
| 204 | } | 185 | } |
| 205 | 186 | ||
| 206 | static inline int clz(unsigned long x) | 187 | static irqreturn_t corehi_handler(int irq, void *dev_id) |
| 207 | { | ||
| 208 | __asm__( | ||
| 209 | " .set push \n" | ||
| 210 | " .set mips32 \n" | ||
| 211 | " clz %0, %1 \n" | ||
| 212 | " .set pop \n" | ||
| 213 | : "=r" (x) | ||
| 214 | : "r" (x)); | ||
| 215 | |||
| 216 | return x; | ||
| 217 | } | ||
| 218 | |||
| 219 | /* | ||
| 220 | * Version of ffs that only looks at bits 12..15. | ||
| 221 | */ | ||
| 222 | static inline unsigned int irq_ffs(unsigned int pending) | ||
| 223 | { | ||
| 224 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) | ||
| 225 | return -clz(pending) + 31 - CAUSEB_IP; | ||
| 226 | #else | ||
| 227 | unsigned int a0 = 7; | ||
| 228 | unsigned int t0; | ||
| 229 | |||
| 230 | t0 = pending & 0xf000; | ||
| 231 | t0 = t0 < 1; | ||
| 232 | t0 = t0 << 2; | ||
| 233 | a0 = a0 - t0; | ||
| 234 | pending = pending << t0; | ||
| 235 | |||
| 236 | t0 = pending & 0xc000; | ||
| 237 | t0 = t0 < 1; | ||
| 238 | t0 = t0 << 1; | ||
| 239 | a0 = a0 - t0; | ||
| 240 | pending = pending << t0; | ||
| 241 | |||
| 242 | t0 = pending & 0x8000; | ||
| 243 | t0 = t0 < 1; | ||
| 244 | /* t0 = t0 << 2; */ | ||
| 245 | a0 = a0 - t0; | ||
| 246 | /* pending = pending << t0; */ | ||
| 247 | |||
| 248 | return a0; | ||
| 249 | #endif | ||
| 250 | } | ||
| 251 | |||
| 252 | /* | ||
| 253 | * IRQs on the Malta board look basically (barring software IRQs which we | ||
| 254 | * don't use at all and all external interrupt sources are combined together | ||
| 255 | * on hardware interrupt 0 (MIPS IRQ 2)) like: | ||
| 256 | * | ||
| 257 | * MIPS IRQ Source | ||
| 258 | * -------- ------ | ||
| 259 | * 0 Software (ignored) | ||
| 260 | * 1 Software (ignored) | ||
| 261 | * 2 Combined hardware interrupt (hw0) | ||
| 262 | * 3 Hardware (ignored) | ||
| 263 | * 4 Hardware (ignored) | ||
| 264 | * 5 Hardware (ignored) | ||
| 265 | * 6 Hardware (ignored) | ||
| 266 | * 7 R4k timer (what we use) | ||
| 267 | * | ||
| 268 | * We handle the IRQ according to _our_ priority which is: | ||
| 269 | * | ||
| 270 | * Highest ---- R4k Timer | ||
| 271 | * Lowest ---- Combined hardware interrupt | ||
| 272 | * | ||
| 273 | * then we just return, if multiple IRQs are pending then we will just take | ||
| 274 | * another exception, big deal. | ||
| 275 | */ | ||
| 276 | |||
| 277 | asmlinkage void plat_irq_dispatch(void) | ||
| 278 | { | 188 | { |
| 279 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; | 189 | corehi_irqdispatch(); |
| 280 | int irq; | 190 | return IRQ_HANDLED; |
| 281 | |||
| 282 | if (unlikely(!pending)) { | ||
| 283 | spurious_interrupt(); | ||
| 284 | return; | ||
| 285 | } | ||
| 286 | |||
| 287 | irq = irq_ffs(pending); | ||
| 288 | |||
| 289 | if (irq == MIPSCPU_INT_I8259A) | ||
| 290 | malta_hw0_irqdispatch(); | ||
| 291 | else if (gic_present && ((1 << irq) & ipi_map[smp_processor_id()])) | ||
| 292 | malta_ipi_irqdispatch(); | ||
| 293 | else | ||
| 294 | do_IRQ(MIPS_CPU_IRQ_BASE + irq); | ||
| 295 | } | 191 | } |
| 296 | 192 | ||
| 297 | #ifdef CONFIG_MIPS_MT_SMP | 193 | #ifdef CONFIG_MIPS_MT_SMP |
| @@ -312,13 +208,6 @@ static void ipi_call_dispatch(void) | |||
| 312 | do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ); | 208 | do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ); |
| 313 | } | 209 | } |
| 314 | 210 | ||
| 315 | #endif /* CONFIG_MIPS_MT_SMP */ | ||
| 316 | |||
| 317 | #ifdef CONFIG_MIPS_GIC_IPI | ||
| 318 | |||
| 319 | #define GIC_MIPS_CPU_IPI_RESCHED_IRQ 3 | ||
| 320 | #define GIC_MIPS_CPU_IPI_CALL_IRQ 4 | ||
| 321 | |||
| 322 | static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) | 211 | static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) |
| 323 | { | 212 | { |
| 324 | #ifdef CONFIG_MIPS_VPE_APSP_API_CMP | 213 | #ifdef CONFIG_MIPS_VPE_APSP_API_CMP |
| @@ -349,31 +238,16 @@ static struct irqaction irq_call = { | |||
| 349 | .flags = IRQF_PERCPU, | 238 | .flags = IRQF_PERCPU, |
| 350 | .name = "IPI_call" | 239 | .name = "IPI_call" |
| 351 | }; | 240 | }; |
| 352 | #endif /* CONFIG_MIPS_GIC_IPI */ | 241 | #endif /* CONFIG_MIPS_MT_SMP */ |
| 353 | |||
| 354 | static int gic_resched_int_base; | ||
| 355 | static int gic_call_int_base; | ||
| 356 | #define GIC_RESCHED_INT(cpu) (gic_resched_int_base+(cpu)) | ||
| 357 | #define GIC_CALL_INT(cpu) (gic_call_int_base+(cpu)) | ||
| 358 | |||
| 359 | unsigned int plat_ipi_call_int_xlate(unsigned int cpu) | ||
| 360 | { | ||
| 361 | return GIC_CALL_INT(cpu); | ||
| 362 | } | ||
| 363 | |||
| 364 | unsigned int plat_ipi_resched_int_xlate(unsigned int cpu) | ||
| 365 | { | ||
| 366 | return GIC_RESCHED_INT(cpu); | ||
| 367 | } | ||
| 368 | 242 | ||
| 369 | static struct irqaction i8259irq = { | 243 | static struct irqaction i8259irq = { |
| 370 | .handler = no_action, | 244 | .handler = i8259_handler, |
| 371 | .name = "XT-PIC cascade", | 245 | .name = "XT-PIC cascade", |
| 372 | .flags = IRQF_NO_THREAD, | 246 | .flags = IRQF_NO_THREAD, |
| 373 | }; | 247 | }; |
| 374 | 248 | ||
| 375 | static struct irqaction corehi_irqaction = { | 249 | static struct irqaction corehi_irqaction = { |
| 376 | .handler = no_action, | 250 | .handler = corehi_handler, |
| 377 | .name = "CoreHi", | 251 | .name = "CoreHi", |
| 378 | .flags = IRQF_NO_THREAD, | 252 | .flags = IRQF_NO_THREAD, |
| 379 | }; | 253 | }; |
| @@ -399,60 +273,6 @@ static msc_irqmap_t msc_eicirqmap[] __initdata = { | |||
| 399 | 273 | ||
| 400 | static int msc_nr_eicirqs __initdata = ARRAY_SIZE(msc_eicirqmap); | 274 | static int msc_nr_eicirqs __initdata = ARRAY_SIZE(msc_eicirqmap); |
| 401 | 275 | ||
| 402 | /* | ||
| 403 | * This GIC specific tabular array defines the association between External | ||
| 404 | * Interrupts and CPUs/Core Interrupts. The nature of the External | ||
| 405 | * Interrupts is also defined here - polarity/trigger. | ||
| 406 | */ | ||
| 407 | |||
| 408 | #define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK | ||
| 409 | #define X GIC_UNUSED | ||
| 410 | |||
| 411 | static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { | ||
| 412 | { X, X, X, X, 0 }, | ||
| 413 | { X, X, X, X, 0 }, | ||
| 414 | { X, X, X, X, 0 }, | ||
| 415 | { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
| 416 | { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
| 417 | { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
| 418 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
| 419 | { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
| 420 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
| 421 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
| 422 | { X, X, X, X, 0 }, | ||
| 423 | { X, X, X, X, 0 }, | ||
| 424 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
| 425 | { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
| 426 | { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
| 427 | { X, X, X, X, 0 }, | ||
| 428 | /* The remainder of this table is initialised by fill_ipi_map */ | ||
| 429 | }; | ||
| 430 | #undef X | ||
| 431 | |||
| 432 | #ifdef CONFIG_MIPS_GIC_IPI | ||
| 433 | static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin) | ||
| 434 | { | ||
| 435 | int intr = baseintr + cpu; | ||
| 436 | gic_intr_map[intr].cpunum = cpu; | ||
| 437 | gic_intr_map[intr].pin = cpupin; | ||
| 438 | gic_intr_map[intr].polarity = GIC_POL_POS; | ||
| 439 | gic_intr_map[intr].trigtype = GIC_TRIG_EDGE; | ||
| 440 | gic_intr_map[intr].flags = 0; | ||
| 441 | ipi_map[cpu] |= (1 << (cpupin + 2)); | ||
| 442 | bitmap_set(ipi_ints, intr, 1); | ||
| 443 | } | ||
| 444 | |||
| 445 | static void __init fill_ipi_map(void) | ||
| 446 | { | ||
| 447 | int cpu; | ||
| 448 | |||
| 449 | for (cpu = 0; cpu < nr_cpu_ids; cpu++) { | ||
| 450 | fill_ipi_map1(gic_resched_int_base, cpu, GIC_CPU_INT1); | ||
| 451 | fill_ipi_map1(gic_call_int_base, cpu, GIC_CPU_INT2); | ||
| 452 | } | ||
| 453 | } | ||
| 454 | #endif | ||
| 455 | |||
| 456 | void __init arch_init_ipiirq(int irq, struct irqaction *action) | 276 | void __init arch_init_ipiirq(int irq, struct irqaction *action) |
| 457 | { | 277 | { |
| 458 | setup_irq(irq, action); | 278 | setup_irq(irq, action); |
| @@ -461,6 +281,8 @@ void __init arch_init_ipiirq(int irq, struct irqaction *action) | |||
| 461 | 281 | ||
| 462 | void __init arch_init_irq(void) | 282 | void __init arch_init_irq(void) |
| 463 | { | 283 | { |
| 284 | int corehi_irq, i8259_irq; | ||
| 285 | |||
| 464 | init_i8259_irqs(); | 286 | init_i8259_irqs(); |
| 465 | 287 | ||
| 466 | if (!cpu_has_veic) | 288 | if (!cpu_has_veic) |
| @@ -471,12 +293,12 @@ void __init arch_init_irq(void) | |||
| 471 | gic_present = 1; | 293 | gic_present = 1; |
| 472 | } else { | 294 | } else { |
| 473 | if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) { | 295 | if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) { |
| 474 | _msc01_biu_base = (unsigned long) | 296 | _msc01_biu_base = ioremap_nocache(MSC01_BIU_REG_BASE, |
| 475 | ioremap_nocache(MSC01_BIU_REG_BASE, | ||
| 476 | MSC01_BIU_ADDRSPACE_SZ); | 297 | MSC01_BIU_ADDRSPACE_SZ); |
| 477 | gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) & | 298 | gic_present = |
| 478 | MSC01_SC_CFG_GICPRES_MSK) >> | 299 | (__raw_readl(_msc01_biu_base + MSC01_SC_CFG_OFS) & |
| 479 | MSC01_SC_CFG_GICPRES_SHF; | 300 | MSC01_SC_CFG_GICPRES_MSK) >> |
| 301 | MSC01_SC_CFG_GICPRES_SHF; | ||
| 480 | } | 302 | } |
| 481 | } | 303 | } |
| 482 | if (gic_present) | 304 | if (gic_present) |
| @@ -507,63 +329,20 @@ void __init arch_init_irq(void) | |||
| 507 | msc_nr_irqs); | 329 | msc_nr_irqs); |
| 508 | } | 330 | } |
| 509 | 331 | ||
| 510 | if (cpu_has_veic) { | ||
| 511 | set_vi_handler(MSC01E_INT_I8259A, malta_hw0_irqdispatch); | ||
| 512 | set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch); | ||
| 513 | setup_irq(MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq); | ||
| 514 | setup_irq(MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction); | ||
| 515 | } else if (cpu_has_vint) { | ||
| 516 | set_vi_handler(MIPSCPU_INT_I8259A, malta_hw0_irqdispatch); | ||
| 517 | set_vi_handler(MIPSCPU_INT_COREHI, corehi_irqdispatch); | ||
| 518 | setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); | ||
| 519 | setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, | ||
| 520 | &corehi_irqaction); | ||
| 521 | } else { | ||
| 522 | setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); | ||
| 523 | setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, | ||
| 524 | &corehi_irqaction); | ||
| 525 | } | ||
| 526 | |||
| 527 | if (gic_present) { | 332 | if (gic_present) { |
| 528 | /* FIXME */ | ||
| 529 | int i; | 333 | int i; |
| 530 | #if defined(CONFIG_MIPS_GIC_IPI) | 334 | |
| 531 | gic_call_int_base = GIC_NUM_INTRS - | 335 | gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, MIPSCPU_INT_GIC, |
| 532 | (NR_CPUS - nr_cpu_ids) * 2 - nr_cpu_ids; | 336 | MIPS_GIC_IRQ_BASE); |
| 533 | gic_resched_int_base = gic_call_int_base - nr_cpu_ids; | ||
| 534 | fill_ipi_map(); | ||
| 535 | #endif | ||
| 536 | gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, | ||
| 537 | ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); | ||
| 538 | if (!mips_cm_present()) { | 337 | if (!mips_cm_present()) { |
| 539 | /* Enable the GIC */ | 338 | /* Enable the GIC */ |
| 540 | i = REG(_msc01_biu_base, MSC01_SC_CFG); | 339 | i = __raw_readl(_msc01_biu_base + MSC01_SC_CFG_OFS); |
| 541 | REG(_msc01_biu_base, MSC01_SC_CFG) = | 340 | __raw_writel(i | (0x1 << MSC01_SC_CFG_GICENA_SHF), |
| 542 | (i | (0x1 << MSC01_SC_CFG_GICENA_SHF)); | 341 | _msc01_biu_base + MSC01_SC_CFG_OFS); |
| 543 | pr_debug("GIC Enabled\n"); | 342 | pr_debug("GIC Enabled\n"); |
| 544 | } | 343 | } |
| 545 | #if defined(CONFIG_MIPS_GIC_IPI) | 344 | i8259_irq = MIPS_GIC_IRQ_BASE + GIC_INT_I8259A; |
| 546 | /* set up ipi interrupts */ | 345 | corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI; |
| 547 | if (cpu_has_vint) { | ||
| 548 | set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch); | ||
| 549 | set_vi_handler(MIPSCPU_INT_IPI1, malta_ipi_irqdispatch); | ||
| 550 | } | ||
| 551 | /* Argh.. this really needs sorting out.. */ | ||
| 552 | pr_info("CPU%d: status register was %08x\n", | ||
| 553 | smp_processor_id(), read_c0_status()); | ||
| 554 | write_c0_status(read_c0_status() | STATUSF_IP3 | STATUSF_IP4); | ||
| 555 | pr_info("CPU%d: status register now %08x\n", | ||
| 556 | smp_processor_id(), read_c0_status()); | ||
| 557 | write_c0_status(0x1100dc00); | ||
| 558 | pr_info("CPU%d: status register frc %08x\n", | ||
| 559 | smp_processor_id(), read_c0_status()); | ||
| 560 | for (i = 0; i < nr_cpu_ids; i++) { | ||
| 561 | arch_init_ipiirq(MIPS_GIC_IRQ_BASE + | ||
| 562 | GIC_RESCHED_INT(i), &irq_resched); | ||
| 563 | arch_init_ipiirq(MIPS_GIC_IRQ_BASE + | ||
| 564 | GIC_CALL_INT(i), &irq_call); | ||
| 565 | } | ||
| 566 | #endif | ||
| 567 | } else { | 346 | } else { |
| 568 | #if defined(CONFIG_MIPS_MT_SMP) | 347 | #if defined(CONFIG_MIPS_MT_SMP) |
| 569 | /* set up ipi interrupts */ | 348 | /* set up ipi interrupts */ |
| @@ -573,12 +352,6 @@ void __init arch_init_irq(void) | |||
| 573 | cpu_ipi_resched_irq = MSC01E_INT_SW0; | 352 | cpu_ipi_resched_irq = MSC01E_INT_SW0; |
| 574 | cpu_ipi_call_irq = MSC01E_INT_SW1; | 353 | cpu_ipi_call_irq = MSC01E_INT_SW1; |
| 575 | } else { | 354 | } else { |
| 576 | if (cpu_has_vint) { | ||
| 577 | set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, | ||
| 578 | ipi_resched_dispatch); | ||
| 579 | set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, | ||
| 580 | ipi_call_dispatch); | ||
| 581 | } | ||
| 582 | cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + | 355 | cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + |
| 583 | MIPS_CPU_IPI_RESCHED_IRQ; | 356 | MIPS_CPU_IPI_RESCHED_IRQ; |
| 584 | cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + | 357 | cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + |
| @@ -587,7 +360,21 @@ void __init arch_init_irq(void) | |||
| 587 | arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched); | 360 | arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched); |
| 588 | arch_init_ipiirq(cpu_ipi_call_irq, &irq_call); | 361 | arch_init_ipiirq(cpu_ipi_call_irq, &irq_call); |
| 589 | #endif | 362 | #endif |
| 363 | if (cpu_has_veic) { | ||
| 364 | set_vi_handler(MSC01E_INT_I8259A, | ||
| 365 | malta_hw0_irqdispatch); | ||
| 366 | set_vi_handler(MSC01E_INT_COREHI, | ||
| 367 | corehi_irqdispatch); | ||
| 368 | i8259_irq = MSC01E_INT_BASE + MSC01E_INT_I8259A; | ||
| 369 | corehi_irq = MSC01E_INT_BASE + MSC01E_INT_COREHI; | ||
| 370 | } else { | ||
| 371 | i8259_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_I8259A; | ||
| 372 | corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI; | ||
| 373 | } | ||
| 590 | } | 374 | } |
| 375 | |||
| 376 | setup_irq(i8259_irq, &i8259irq); | ||
| 377 | setup_irq(corehi_irq, &corehi_irqaction); | ||
| 591 | } | 378 | } |
| 592 | 379 | ||
| 593 | void malta_be_init(void) | 380 | void malta_be_init(void) |
| @@ -714,37 +501,3 @@ int malta_be_handler(struct pt_regs *regs, int is_fixup) | |||
| 714 | 501 | ||
| 715 | return retval; | 502 | return retval; |
| 716 | } | 503 | } |
| 717 | |||
| 718 | void gic_enable_interrupt(int irq_vec) | ||
| 719 | { | ||
| 720 | GIC_SET_INTR_MASK(irq_vec); | ||
| 721 | } | ||
| 722 | |||
| 723 | void gic_disable_interrupt(int irq_vec) | ||
| 724 | { | ||
| 725 | GIC_CLR_INTR_MASK(irq_vec); | ||
| 726 | } | ||
| 727 | |||
| 728 | void gic_irq_ack(struct irq_data *d) | ||
| 729 | { | ||
| 730 | int irq = (d->irq - gic_irq_base); | ||
| 731 | |||
| 732 | GIC_CLR_INTR_MASK(irq); | ||
| 733 | |||
| 734 | if (gic_irq_flags[irq] & GIC_TRIG_EDGE) | ||
| 735 | GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); | ||
| 736 | } | ||
| 737 | |||
| 738 | void gic_finish_irq(struct irq_data *d) | ||
| 739 | { | ||
| 740 | /* Enable interrupts. */ | ||
| 741 | GIC_SET_INTR_MASK(d->irq - gic_irq_base); | ||
| 742 | } | ||
| 743 | |||
| 744 | void __init gic_platform_init(int irqs, struct irq_chip *irq_controller) | ||
| 745 | { | ||
| 746 | int i; | ||
| 747 | |||
| 748 | for (i = gic_irq_base; i < (gic_irq_base + irqs); i++) | ||
| 749 | irq_set_chip(i, irq_controller); | ||
| 750 | } | ||
diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index 3778a359f3ad..ce02dbdedc62 100644 --- a/arch/mips/mti-malta/malta-time.c +++ b/arch/mips/mti-malta/malta-time.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
| 25 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
| 26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
| 27 | #include <linux/irqchip/mips-gic.h> | ||
| 27 | #include <linux/timex.h> | 28 | #include <linux/timex.h> |
| 28 | #include <linux/mc146818rtc.h> | 29 | #include <linux/mc146818rtc.h> |
| 29 | 30 | ||
| @@ -37,7 +38,6 @@ | |||
| 37 | #include <asm/time.h> | 38 | #include <asm/time.h> |
| 38 | #include <asm/mc146818-time.h> | 39 | #include <asm/mc146818-time.h> |
| 39 | #include <asm/msc01_ic.h> | 40 | #include <asm/msc01_ic.h> |
| 40 | #include <asm/gic.h> | ||
| 41 | 41 | ||
| 42 | #include <asm/mips-boards/generic.h> | 42 | #include <asm/mips-boards/generic.h> |
| 43 | #include <asm/mips-boards/maltaint.h> | 43 | #include <asm/mips-boards/maltaint.h> |
| @@ -46,6 +46,8 @@ static int mips_cpu_timer_irq; | |||
| 46 | static int mips_cpu_perf_irq; | 46 | static int mips_cpu_perf_irq; |
| 47 | extern int cp0_perfcount_irq; | 47 | extern int cp0_perfcount_irq; |
| 48 | 48 | ||
| 49 | static unsigned int gic_frequency; | ||
| 50 | |||
| 49 | static void mips_timer_dispatch(void) | 51 | static void mips_timer_dispatch(void) |
| 50 | { | 52 | { |
| 51 | do_IRQ(mips_cpu_timer_irq); | 53 | do_IRQ(mips_cpu_timer_irq); |
| @@ -70,9 +72,7 @@ static void __init estimate_frequencies(void) | |||
| 70 | { | 72 | { |
| 71 | unsigned long flags; | 73 | unsigned long flags; |
| 72 | unsigned int count, start; | 74 | unsigned int count, start; |
| 73 | #ifdef CONFIG_IRQ_GIC | 75 | cycle_t giccount = 0, gicstart = 0; |
| 74 | unsigned int giccount = 0, gicstart = 0; | ||
| 75 | #endif | ||
| 76 | 76 | ||
| 77 | #if defined(CONFIG_KVM_GUEST) && CONFIG_KVM_GUEST_TIMER_FREQ | 77 | #if defined(CONFIG_KVM_GUEST) && CONFIG_KVM_GUEST_TIMER_FREQ |
| 78 | mips_hpt_frequency = CONFIG_KVM_GUEST_TIMER_FREQ * 1000000; | 78 | mips_hpt_frequency = CONFIG_KVM_GUEST_TIMER_FREQ * 1000000; |
| @@ -87,32 +87,26 @@ static void __init estimate_frequencies(void) | |||
| 87 | 87 | ||
| 88 | /* Initialize counters. */ | 88 | /* Initialize counters. */ |
| 89 | start = read_c0_count(); | 89 | start = read_c0_count(); |
| 90 | #ifdef CONFIG_IRQ_GIC | ||
| 91 | if (gic_present) | 90 | if (gic_present) |
| 92 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), gicstart); | 91 | gicstart = gic_read_count(); |
| 93 | #endif | ||
| 94 | 92 | ||
| 95 | /* Read counter exactly on falling edge of update flag. */ | 93 | /* Read counter exactly on falling edge of update flag. */ |
| 96 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); | 94 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); |
| 97 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); | 95 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); |
| 98 | 96 | ||
| 99 | count = read_c0_count(); | 97 | count = read_c0_count(); |
| 100 | #ifdef CONFIG_IRQ_GIC | ||
| 101 | if (gic_present) | 98 | if (gic_present) |
| 102 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), giccount); | 99 | giccount = gic_read_count(); |
| 103 | #endif | ||
| 104 | 100 | ||
| 105 | local_irq_restore(flags); | 101 | local_irq_restore(flags); |
| 106 | 102 | ||
| 107 | count -= start; | 103 | count -= start; |
| 108 | mips_hpt_frequency = count; | 104 | mips_hpt_frequency = count; |
| 109 | 105 | ||
| 110 | #ifdef CONFIG_IRQ_GIC | ||
| 111 | if (gic_present) { | 106 | if (gic_present) { |
| 112 | giccount -= gicstart; | 107 | giccount -= gicstart; |
| 113 | gic_frequency = giccount; | 108 | gic_frequency = giccount; |
| 114 | } | 109 | } |
| 115 | #endif | ||
| 116 | } | 110 | } |
| 117 | 111 | ||
| 118 | void read_persistent_clock(struct timespec *ts) | 112 | void read_persistent_clock(struct timespec *ts) |
| @@ -121,35 +115,30 @@ void read_persistent_clock(struct timespec *ts) | |||
| 121 | ts->tv_nsec = 0; | 115 | ts->tv_nsec = 0; |
| 122 | } | 116 | } |
| 123 | 117 | ||
| 124 | static void __init plat_perf_setup(void) | 118 | int get_c0_perfcount_int(void) |
| 125 | { | 119 | { |
| 126 | #ifdef MSC01E_INT_BASE | ||
| 127 | if (cpu_has_veic) { | 120 | if (cpu_has_veic) { |
| 128 | set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch); | 121 | set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch); |
| 129 | mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; | 122 | mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; |
| 130 | } else | 123 | } else if (gic_present) { |
| 131 | #endif | 124 | mips_cpu_perf_irq = gic_get_c0_perfcount_int(); |
| 132 | if (cp0_perfcount_irq >= 0) { | 125 | } else if (cp0_perfcount_irq >= 0) { |
| 133 | if (cpu_has_vint) | ||
| 134 | set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch); | ||
| 135 | mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; | 126 | mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; |
| 136 | #ifdef CONFIG_SMP | 127 | } else { |
| 137 | irq_set_handler(mips_cpu_perf_irq, handle_percpu_irq); | 128 | mips_cpu_perf_irq = -1; |
| 138 | #endif | ||
| 139 | } | 129 | } |
| 130 | |||
| 131 | return mips_cpu_perf_irq; | ||
| 140 | } | 132 | } |
| 141 | 133 | ||
| 142 | unsigned int get_c0_compare_int(void) | 134 | unsigned int get_c0_compare_int(void) |
| 143 | { | 135 | { |
| 144 | #ifdef MSC01E_INT_BASE | ||
| 145 | if (cpu_has_veic) { | 136 | if (cpu_has_veic) { |
| 146 | set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); | 137 | set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); |
| 147 | mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; | 138 | mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; |
| 148 | } else | 139 | } else if (gic_present) { |
| 149 | #endif | 140 | mips_cpu_timer_irq = gic_get_c0_compare_int(); |
| 150 | { | 141 | } else { |
| 151 | if (cpu_has_vint) | ||
| 152 | set_vi_handler(cp0_compare_irq, mips_timer_dispatch); | ||
| 153 | mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; | 142 | mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; |
| 154 | } | 143 | } |
| 155 | 144 | ||
| @@ -191,16 +180,14 @@ void __init plat_time_init(void) | |||
| 191 | setup_pit_timer(); | 180 | setup_pit_timer(); |
| 192 | #endif | 181 | #endif |
| 193 | 182 | ||
| 194 | #ifdef CONFIG_IRQ_GIC | 183 | #ifdef CONFIG_MIPS_GIC |
| 195 | if (gic_present) { | 184 | if (gic_present) { |
| 196 | freq = freqround(gic_frequency, 5000); | 185 | freq = freqround(gic_frequency, 5000); |
| 197 | printk("GIC frequency %d.%02d MHz\n", freq/1000000, | 186 | printk("GIC frequency %d.%02d MHz\n", freq/1000000, |
| 198 | (freq%1000000)*100/1000000); | 187 | (freq%1000000)*100/1000000); |
| 199 | #ifdef CONFIG_CSRC_GIC | 188 | #ifdef CONFIG_CLKSRC_MIPS_GIC |
| 200 | gic_clocksource_init(gic_frequency); | 189 | gic_clocksource_init(gic_frequency); |
| 201 | #endif | 190 | #endif |
| 202 | } | 191 | } |
| 203 | #endif | 192 | #endif |
| 204 | |||
| 205 | plat_perf_setup(); | ||
| 206 | } | 193 | } |
diff --git a/arch/mips/mti-sead3/sead3-ehci.c b/arch/mips/mti-sead3/sead3-ehci.c index 772fc056a92d..014dd7ba4d68 100644 --- a/arch/mips/mti-sead3/sead3-ehci.c +++ b/arch/mips/mti-sead3/sead3-ehci.c | |||
| @@ -9,6 +9,9 @@ | |||
| 9 | #include <linux/irq.h> | 9 | #include <linux/irq.h> |
| 10 | #include <linux/dma-mapping.h> | 10 | #include <linux/dma-mapping.h> |
| 11 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
| 12 | #include <linux/irqchip/mips-gic.h> | ||
| 13 | |||
| 14 | #include <asm/mips-boards/sead3int.h> | ||
| 12 | 15 | ||
| 13 | struct resource ehci_resources[] = { | 16 | struct resource ehci_resources[] = { |
| 14 | { | 17 | { |
| @@ -17,7 +20,6 @@ struct resource ehci_resources[] = { | |||
| 17 | .flags = IORESOURCE_MEM | 20 | .flags = IORESOURCE_MEM |
| 18 | }, | 21 | }, |
| 19 | { | 22 | { |
| 20 | .start = MIPS_CPU_IRQ_BASE + 2, | ||
| 21 | .flags = IORESOURCE_IRQ | 23 | .flags = IORESOURCE_IRQ |
| 22 | } | 24 | } |
| 23 | }; | 25 | }; |
| @@ -37,6 +39,10 @@ static struct platform_device ehci_device = { | |||
| 37 | 39 | ||
| 38 | static int __init ehci_init(void) | 40 | static int __init ehci_init(void) |
| 39 | { | 41 | { |
| 42 | if (gic_present) | ||
| 43 | ehci_resources[1].start = MIPS_GIC_IRQ_BASE + GIC_INT_EHCI; | ||
| 44 | else | ||
| 45 | ehci_resources[1].start = MIPS_CPU_IRQ_BASE + CPU_INT_EHCI; | ||
| 40 | return platform_device_register(&ehci_device); | 46 | return platform_device_register(&ehci_device); |
| 41 | } | 47 | } |
| 42 | 48 | ||
diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c index 6a560ac03def..e31e17f81eef 100644 --- a/arch/mips/mti-sead3/sead3-int.c +++ b/arch/mips/mti-sead3/sead3-int.c | |||
| @@ -7,9 +7,9 @@ | |||
| 7 | */ | 7 | */ |
| 8 | #include <linux/init.h> | 8 | #include <linux/init.h> |
| 9 | #include <linux/irq.h> | 9 | #include <linux/irq.h> |
| 10 | #include <linux/irqchip/mips-gic.h> | ||
| 10 | #include <linux/io.h> | 11 | #include <linux/io.h> |
| 11 | 12 | ||
| 12 | #include <asm/gic.h> | ||
| 13 | #include <asm/irq_cpu.h> | 13 | #include <asm/irq_cpu.h> |
| 14 | #include <asm/setup.h> | 14 | #include <asm/setup.h> |
| 15 | 15 | ||
| @@ -20,138 +20,23 @@ | |||
| 20 | #define SEAD_CONFIG_BASE 0x1b100110 | 20 | #define SEAD_CONFIG_BASE 0x1b100110 |
| 21 | #define SEAD_CONFIG_SIZE 4 | 21 | #define SEAD_CONFIG_SIZE 4 |
| 22 | 22 | ||
| 23 | static unsigned long sead3_config_reg; | 23 | static void __iomem *sead3_config_reg; |
| 24 | |||
| 25 | /* | ||
| 26 | * This table defines the setup for each external GIC interrupt. It is | ||
| 27 | * indexed by interrupt number. | ||
| 28 | */ | ||
| 29 | #define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK | ||
| 30 | static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { | ||
| 31 | { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
| 32 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
| 33 | { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
| 34 | { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
| 35 | { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
| 36 | { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
| 37 | { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
| 38 | { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
| 39 | { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
| 40 | { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED }, | ||
| 41 | { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED }, | ||
| 42 | { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED }, | ||
| 43 | { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED }, | ||
| 44 | { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED }, | ||
| 45 | { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED }, | ||
| 46 | { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED }, | ||
| 47 | }; | ||
| 48 | |||
| 49 | asmlinkage void plat_irq_dispatch(void) | ||
| 50 | { | ||
| 51 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; | ||
| 52 | int irq; | ||
| 53 | |||
| 54 | irq = (fls(pending) - CAUSEB_IP - 1); | ||
| 55 | if (irq >= 0) | ||
| 56 | do_IRQ(MIPS_CPU_IRQ_BASE + irq); | ||
| 57 | else | ||
| 58 | spurious_interrupt(); | ||
| 59 | } | ||
| 60 | 24 | ||
| 61 | void __init arch_init_irq(void) | 25 | void __init arch_init_irq(void) |
| 62 | { | 26 | { |
| 63 | int i; | 27 | if (!cpu_has_veic) |
| 64 | |||
| 65 | if (!cpu_has_veic) { | ||
| 66 | mips_cpu_irq_init(); | 28 | mips_cpu_irq_init(); |
| 67 | 29 | ||
| 68 | if (cpu_has_vint) { | 30 | sead3_config_reg = ioremap_nocache(SEAD_CONFIG_BASE, SEAD_CONFIG_SIZE); |
| 69 | /* install generic handler */ | 31 | gic_present = (__raw_readl(sead3_config_reg) & |
| 70 | for (i = 0; i < 8; i++) | 32 | SEAD_CONFIG_GIC_PRESENT_MSK) >> |
| 71 | set_vi_handler(i, plat_irq_dispatch); | ||
| 72 | } | ||
| 73 | } | ||
| 74 | |||
| 75 | sead3_config_reg = (unsigned long)ioremap_nocache(SEAD_CONFIG_BASE, | ||
| 76 | SEAD_CONFIG_SIZE); | ||
| 77 | gic_present = (REG32(sead3_config_reg) & SEAD_CONFIG_GIC_PRESENT_MSK) >> | ||
| 78 | SEAD_CONFIG_GIC_PRESENT_SHF; | 33 | SEAD_CONFIG_GIC_PRESENT_SHF; |
| 79 | pr_info("GIC: %spresent\n", (gic_present) ? "" : "not "); | 34 | pr_info("GIC: %spresent\n", (gic_present) ? "" : "not "); |
| 80 | pr_info("EIC: %s\n", | 35 | pr_info("EIC: %s\n", |
| 81 | (current_cpu_data.options & MIPS_CPU_VEIC) ? "on" : "off"); | 36 | (current_cpu_data.options & MIPS_CPU_VEIC) ? "on" : "off"); |
| 82 | 37 | ||
| 83 | if (gic_present) | 38 | if (gic_present) |
| 84 | gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, | 39 | gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, CPU_INT_GIC, |
| 85 | ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); | 40 | MIPS_GIC_IRQ_BASE); |
| 86 | } | ||
| 87 | |||
| 88 | void gic_enable_interrupt(int irq_vec) | ||
| 89 | { | ||
| 90 | unsigned int i, irq_source; | ||
| 91 | |||
| 92 | /* enable all the interrupts associated with this vector */ | ||
| 93 | for (i = 0; i < gic_shared_intr_map[irq_vec].num_shared_intr; i++) { | ||
| 94 | irq_source = gic_shared_intr_map[irq_vec].intr_list[i]; | ||
| 95 | GIC_SET_INTR_MASK(irq_source); | ||
| 96 | } | ||
| 97 | /* enable all local interrupts associated with this vector */ | ||
| 98 | if (gic_shared_intr_map[irq_vec].local_intr_mask) { | ||
| 99 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0); | ||
| 100 | GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_SMASK), | ||
| 101 | gic_shared_intr_map[irq_vec].local_intr_mask); | ||
| 102 | } | ||
| 103 | } | 41 | } |
| 104 | 42 | ||
| 105 | void gic_disable_interrupt(int irq_vec) | ||
| 106 | { | ||
| 107 | unsigned int i, irq_source; | ||
| 108 | |||
| 109 | /* disable all the interrupts associated with this vector */ | ||
| 110 | for (i = 0; i < gic_shared_intr_map[irq_vec].num_shared_intr; i++) { | ||
| 111 | irq_source = gic_shared_intr_map[irq_vec].intr_list[i]; | ||
| 112 | GIC_CLR_INTR_MASK(irq_source); | ||
| 113 | } | ||
| 114 | /* disable all local interrupts associated with this vector */ | ||
| 115 | if (gic_shared_intr_map[irq_vec].local_intr_mask) { | ||
| 116 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0); | ||
| 117 | GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), | ||
| 118 | gic_shared_intr_map[irq_vec].local_intr_mask); | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 122 | void gic_irq_ack(struct irq_data *d) | ||
| 123 | { | ||
| 124 | GIC_CLR_INTR_MASK(d->irq - gic_irq_base); | ||
| 125 | } | ||
| 126 | |||
| 127 | void gic_finish_irq(struct irq_data *d) | ||
| 128 | { | ||
| 129 | unsigned int irq = (d->irq - gic_irq_base); | ||
| 130 | unsigned int i, irq_source; | ||
| 131 | |||
| 132 | /* Clear edge detectors. */ | ||
| 133 | for (i = 0; i < gic_shared_intr_map[irq].num_shared_intr; i++) { | ||
| 134 | irq_source = gic_shared_intr_map[irq].intr_list[i]; | ||
| 135 | if (gic_irq_flags[irq_source] & GIC_TRIG_EDGE) | ||
| 136 | GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq_source); | ||
| 137 | } | ||
| 138 | |||
| 139 | /* Enable interrupts. */ | ||
| 140 | GIC_SET_INTR_MASK(irq); | ||
| 141 | } | ||
| 142 | |||
| 143 | void __init gic_platform_init(int irqs, struct irq_chip *irq_controller) | ||
| 144 | { | ||
| 145 | int i; | ||
| 146 | |||
| 147 | /* | ||
| 148 | * For non-EIC mode, we want to setup the GIC in pass-through | ||
| 149 | * mode, as if the GIC didn't exist. Do not map any interrupts | ||
| 150 | * for an external interrupt controller. | ||
| 151 | */ | ||
| 152 | if (!cpu_has_veic) | ||
| 153 | return; | ||
| 154 | |||
| 155 | for (i = gic_irq_base; i < (gic_irq_base + irqs); i++) | ||
| 156 | irq_set_chip_and_handler(i, irq_controller, handle_percpu_irq); | ||
| 157 | } | ||
diff --git a/arch/mips/mti-sead3/sead3-net.c b/arch/mips/mti-sead3/sead3-net.c index dd11e7eb771c..46176b804576 100644 --- a/arch/mips/mti-sead3/sead3-net.c +++ b/arch/mips/mti-sead3/sead3-net.c | |||
| @@ -7,9 +7,12 @@ | |||
| 7 | */ | 7 | */ |
| 8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
| 9 | #include <linux/irq.h> | 9 | #include <linux/irq.h> |
| 10 | #include <linux/irqchip/mips-gic.h> | ||
| 10 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
| 11 | #include <linux/smsc911x.h> | 12 | #include <linux/smsc911x.h> |
| 12 | 13 | ||
| 14 | #include <asm/mips-boards/sead3int.h> | ||
| 15 | |||
| 13 | static struct smsc911x_platform_config sead3_smsc911x_data = { | 16 | static struct smsc911x_platform_config sead3_smsc911x_data = { |
| 14 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, | 17 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, |
| 15 | .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, | 18 | .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, |
| @@ -17,14 +20,13 @@ static struct smsc911x_platform_config sead3_smsc911x_data = { | |||
| 17 | .phy_interface = PHY_INTERFACE_MODE_MII, | 20 | .phy_interface = PHY_INTERFACE_MODE_MII, |
| 18 | }; | 21 | }; |
| 19 | 22 | ||
| 20 | struct resource sead3_net_resourcess[] = { | 23 | struct resource sead3_net_resources[] = { |
| 21 | { | 24 | { |
| 22 | .start = 0x1f010000, | 25 | .start = 0x1f010000, |
| 23 | .end = 0x1f01ffff, | 26 | .end = 0x1f01ffff, |
| 24 | .flags = IORESOURCE_MEM | 27 | .flags = IORESOURCE_MEM |
| 25 | }, | 28 | }, |
| 26 | { | 29 | { |
| 27 | .start = MIPS_CPU_IRQ_BASE + 6, | ||
| 28 | .flags = IORESOURCE_IRQ | 30 | .flags = IORESOURCE_IRQ |
| 29 | } | 31 | } |
| 30 | }; | 32 | }; |
| @@ -35,12 +37,16 @@ static struct platform_device sead3_net_device = { | |||
| 35 | .dev = { | 37 | .dev = { |
| 36 | .platform_data = &sead3_smsc911x_data, | 38 | .platform_data = &sead3_smsc911x_data, |
| 37 | }, | 39 | }, |
| 38 | .num_resources = ARRAY_SIZE(sead3_net_resourcess), | 40 | .num_resources = ARRAY_SIZE(sead3_net_resources), |
| 39 | .resource = sead3_net_resourcess | 41 | .resource = sead3_net_resources |
| 40 | }; | 42 | }; |
| 41 | 43 | ||
| 42 | static int __init sead3_net_init(void) | 44 | static int __init sead3_net_init(void) |
| 43 | { | 45 | { |
| 46 | if (gic_present) | ||
| 47 | sead3_net_resources[1].start = MIPS_GIC_IRQ_BASE + GIC_INT_NET; | ||
| 48 | else | ||
| 49 | sead3_net_resources[1].start = MIPS_CPU_IRQ_BASE + CPU_INT_NET; | ||
| 44 | return platform_device_register(&sead3_net_device); | 50 | return platform_device_register(&sead3_net_device); |
| 45 | } | 51 | } |
| 46 | 52 | ||
diff --git a/arch/mips/mti-sead3/sead3-platform.c b/arch/mips/mti-sead3/sead3-platform.c index 6c3b33dbed18..53ee6f1f018d 100644 --- a/arch/mips/mti-sead3/sead3-platform.c +++ b/arch/mips/mti-sead3/sead3-platform.c | |||
| @@ -7,12 +7,15 @@ | |||
| 7 | */ | 7 | */ |
| 8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
| 9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
| 10 | #include <linux/irqchip/mips-gic.h> | ||
| 10 | #include <linux/serial_8250.h> | 11 | #include <linux/serial_8250.h> |
| 11 | 12 | ||
| 12 | #define UART(base, int) \ | 13 | #include <asm/mips-boards/sead3int.h> |
| 14 | |||
| 15 | #define UART(base) \ | ||
| 13 | { \ | 16 | { \ |
| 14 | .mapbase = base, \ | 17 | .mapbase = base, \ |
| 15 | .irq = int, \ | 18 | .irq = -1, \ |
| 16 | .uartclk = 14745600, \ | 19 | .uartclk = 14745600, \ |
| 17 | .iotype = UPIO_MEM32, \ | 20 | .iotype = UPIO_MEM32, \ |
| 18 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \ | 21 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \ |
| @@ -20,8 +23,8 @@ | |||
| 20 | } | 23 | } |
| 21 | 24 | ||
| 22 | static struct plat_serial8250_port uart8250_data[] = { | 25 | static struct plat_serial8250_port uart8250_data[] = { |
| 23 | UART(0x1f000900, MIPS_CPU_IRQ_BASE + 4), /* ttyS0 = USB */ | 26 | UART(0x1f000900), /* ttyS0 = USB */ |
| 24 | UART(0x1f000800, MIPS_CPU_IRQ_BASE + 4), /* ttyS1 = RS232 */ | 27 | UART(0x1f000800), /* ttyS1 = RS232 */ |
| 25 | { }, | 28 | { }, |
| 26 | }; | 29 | }; |
| 27 | 30 | ||
| @@ -35,6 +38,13 @@ static struct platform_device uart8250_device = { | |||
| 35 | 38 | ||
| 36 | static int __init uart8250_init(void) | 39 | static int __init uart8250_init(void) |
| 37 | { | 40 | { |
| 41 | if (gic_present) { | ||
| 42 | uart8250_data[0].irq = MIPS_GIC_IRQ_BASE + GIC_INT_UART0; | ||
| 43 | uart8250_data[1].irq = MIPS_GIC_IRQ_BASE + GIC_INT_UART1; | ||
| 44 | } else { | ||
| 45 | uart8250_data[0].irq = MIPS_CPU_IRQ_BASE + CPU_INT_UART0; | ||
| 46 | uart8250_data[1].irq = MIPS_CPU_IRQ_BASE + CPU_INT_UART1; | ||
| 47 | } | ||
| 38 | return platform_device_register(&uart8250_device); | 48 | return platform_device_register(&uart8250_device); |
| 39 | } | 49 | } |
| 40 | 50 | ||
diff --git a/arch/mips/mti-sead3/sead3-serial.c b/arch/mips/mti-sead3/sead3-serial.c deleted file mode 100644 index bc52705bbee4..000000000000 --- a/arch/mips/mti-sead3/sead3-serial.c +++ /dev/null | |||
| @@ -1,45 +0,0 @@ | |||
| 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 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. | ||
| 7 | */ | ||
| 8 | #include <linux/module.h> | ||
| 9 | #include <linux/init.h> | ||
| 10 | #include <linux/serial_8250.h> | ||
| 11 | |||
| 12 | #define UART(base, int) \ | ||
| 13 | { \ | ||
| 14 | .mapbase = base, \ | ||
| 15 | .irq = int, \ | ||
| 16 | .uartclk = 14745600, \ | ||
| 17 | .iotype = UPIO_MEM32, \ | ||
| 18 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \ | ||
| 19 | .regshift = 2, \ | ||
| 20 | } | ||
| 21 | |||
| 22 | static struct plat_serial8250_port uart8250_data[] = { | ||
| 23 | UART(0x1f000900, MIPS_CPU_IRQ_BASE + 4), /* ttyS0 = USB */ | ||
| 24 | UART(0x1f000800, MIPS_CPU_IRQ_BASE + 4), /* ttyS1 = RS232 */ | ||
| 25 | { }, | ||
| 26 | }; | ||
| 27 | |||
| 28 | static struct platform_device uart8250_device = { | ||
| 29 | .name = "serial8250", | ||
| 30 | .id = PLAT8250_DEV_PLATFORM, | ||
| 31 | .dev = { | ||
| 32 | .platform_data = uart8250_data, | ||
| 33 | }, | ||
| 34 | }; | ||
| 35 | |||
| 36 | static int __init uart8250_init(void) | ||
| 37 | { | ||
| 38 | return platform_device_register(&uart8250_device); | ||
| 39 | } | ||
| 40 | |||
| 41 | module_init(uart8250_init); | ||
| 42 | |||
| 43 | MODULE_AUTHOR("Chris Dearman <chris@mips.com>"); | ||
| 44 | MODULE_LICENSE("GPL"); | ||
| 45 | MODULE_DESCRIPTION("8250 UART probe driver for the SEAD-3 platform"); | ||
diff --git a/arch/mips/mti-sead3/sead3-time.c b/arch/mips/mti-sead3/sead3-time.c index 678d03d53c60..ec1dd2491f96 100644 --- a/arch/mips/mti-sead3/sead3-time.c +++ b/arch/mips/mti-sead3/sead3-time.c | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. | 6 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. |
| 7 | */ | 7 | */ |
| 8 | #include <linux/init.h> | 8 | #include <linux/init.h> |
| 9 | #include <linux/irqchip/mips-gic.h> | ||
| 9 | 10 | ||
| 10 | #include <asm/cpu.h> | 11 | #include <asm/cpu.h> |
| 11 | #include <asm/setup.h> | 12 | #include <asm/setup.h> |
| @@ -13,19 +14,6 @@ | |||
| 13 | #include <asm/irq.h> | 14 | #include <asm/irq.h> |
| 14 | #include <asm/mips-boards/generic.h> | 15 | #include <asm/mips-boards/generic.h> |
| 15 | 16 | ||
| 16 | static int mips_cpu_timer_irq; | ||
| 17 | static int mips_cpu_perf_irq; | ||
| 18 | |||
| 19 | static void mips_timer_dispatch(void) | ||
| 20 | { | ||
| 21 | do_IRQ(mips_cpu_timer_irq); | ||
| 22 | } | ||
| 23 | |||
| 24 | static void mips_perf_dispatch(void) | ||
| 25 | { | ||
| 26 | do_IRQ(mips_cpu_perf_irq); | ||
| 27 | } | ||
| 28 | |||
| 29 | static void __iomem *status_reg = (void __iomem *)0xbf000410; | 17 | static void __iomem *status_reg = (void __iomem *)0xbf000410; |
| 30 | 18 | ||
| 31 | /* | 19 | /* |
| @@ -81,21 +69,20 @@ void read_persistent_clock(struct timespec *ts) | |||
| 81 | ts->tv_nsec = 0; | 69 | ts->tv_nsec = 0; |
| 82 | } | 70 | } |
| 83 | 71 | ||
| 84 | static void __init plat_perf_setup(void) | 72 | int get_c0_perfcount_int(void) |
| 85 | { | 73 | { |
| 86 | if (cp0_perfcount_irq >= 0) { | 74 | if (gic_present) |
| 87 | if (cpu_has_vint) | 75 | return gic_get_c0_compare_int(); |
| 88 | set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch); | 76 | if (cp0_perfcount_irq >= 0) |
| 89 | mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; | 77 | return MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; |
| 90 | } | 78 | return -1; |
| 91 | } | 79 | } |
| 92 | 80 | ||
| 93 | unsigned int get_c0_compare_int(void) | 81 | unsigned int get_c0_compare_int(void) |
| 94 | { | 82 | { |
| 95 | if (cpu_has_vint) | 83 | if (gic_present) |
| 96 | set_vi_handler(cp0_compare_irq, mips_timer_dispatch); | 84 | return gic_get_c0_compare_int(); |
| 97 | mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; | 85 | return MIPS_CPU_IRQ_BASE + cp0_compare_irq; |
| 98 | return mips_cpu_timer_irq; | ||
| 99 | } | 86 | } |
| 100 | 87 | ||
| 101 | void __init plat_time_init(void) | 88 | void __init plat_time_init(void) |
| @@ -108,6 +95,4 @@ void __init plat_time_init(void) | |||
| 108 | (est_freq % 1000000) * 100 / 1000000); | 95 | (est_freq % 1000000) * 100 / 1000000); |
| 109 | 96 | ||
| 110 | mips_scroll_message(); | 97 | mips_scroll_message(); |
| 111 | |||
| 112 | plat_perf_setup(); | ||
| 113 | } | 98 | } |
diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile index 9c0a6782c091..070afdb297df 100644 --- a/arch/mips/oprofile/Makefile +++ b/arch/mips/oprofile/Makefile | |||
| @@ -14,3 +14,4 @@ oprofile-$(CONFIG_CPU_R10000) += op_model_mipsxx.o | |||
| 14 | oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o | 14 | oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o |
| 15 | oprofile-$(CONFIG_CPU_XLR) += op_model_mipsxx.o | 15 | oprofile-$(CONFIG_CPU_XLR) += op_model_mipsxx.o |
| 16 | oprofile-$(CONFIG_CPU_LOONGSON2) += op_model_loongson2.o | 16 | oprofile-$(CONFIG_CPU_LOONGSON2) += op_model_loongson2.o |
| 17 | oprofile-$(CONFIG_CPU_LOONGSON3) += op_model_loongson3.o | ||
diff --git a/arch/mips/oprofile/backtrace.c b/arch/mips/oprofile/backtrace.c index 83a1dfd8f0e3..5e645c9a3162 100644 --- a/arch/mips/oprofile/backtrace.c +++ b/arch/mips/oprofile/backtrace.c | |||
| @@ -65,7 +65,7 @@ static inline int is_end_of_function_marker(union mips_instruction *ip) | |||
| 65 | * - handle cases where the stack is adjusted inside a function | 65 | * - handle cases where the stack is adjusted inside a function |
| 66 | * (generally doesn't happen) | 66 | * (generally doesn't happen) |
| 67 | * - find optimal value for max_instr_check | 67 | * - find optimal value for max_instr_check |
| 68 | * - try to find a way to handle leaf functions | 68 | * - try to find a better way to handle leaf functions |
| 69 | */ | 69 | */ |
| 70 | 70 | ||
| 71 | static inline int unwind_user_frame(struct stackframe *old_frame, | 71 | static inline int unwind_user_frame(struct stackframe *old_frame, |
| @@ -104,7 +104,7 @@ static inline int unwind_user_frame(struct stackframe *old_frame, | |||
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | if (!ra_offset || !stack_size) | 106 | if (!ra_offset || !stack_size) |
| 107 | return -1; | 107 | goto done; |
| 108 | 108 | ||
| 109 | if (ra_offset) { | 109 | if (ra_offset) { |
| 110 | new_frame.ra = old_frame->sp + ra_offset; | 110 | new_frame.ra = old_frame->sp + ra_offset; |
| @@ -121,6 +121,7 @@ static inline int unwind_user_frame(struct stackframe *old_frame, | |||
| 121 | if (new_frame.sp > old_frame->sp) | 121 | if (new_frame.sp > old_frame->sp) |
| 122 | return -2; | 122 | return -2; |
| 123 | 123 | ||
| 124 | done: | ||
| 124 | new_frame.pc = old_frame->ra; | 125 | new_frame.pc = old_frame->ra; |
| 125 | *old_frame = new_frame; | 126 | *old_frame = new_frame; |
| 126 | 127 | ||
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c index e74732449478..a26cbe372e06 100644 --- a/arch/mips/oprofile/common.c +++ b/arch/mips/oprofile/common.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | 18 | ||
| 19 | extern struct op_mips_model op_model_mipsxx_ops __weak; | 19 | extern struct op_mips_model op_model_mipsxx_ops __weak; |
| 20 | extern struct op_mips_model op_model_loongson2_ops __weak; | 20 | extern struct op_mips_model op_model_loongson2_ops __weak; |
| 21 | extern struct op_mips_model op_model_loongson3_ops __weak; | ||
| 21 | 22 | ||
| 22 | static struct op_mips_model *model; | 23 | static struct op_mips_model *model; |
| 23 | 24 | ||
| @@ -104,8 +105,17 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
| 104 | case CPU_LOONGSON2: | 105 | case CPU_LOONGSON2: |
| 105 | lmodel = &op_model_loongson2_ops; | 106 | lmodel = &op_model_loongson2_ops; |
| 106 | break; | 107 | break; |
| 108 | case CPU_LOONGSON3: | ||
| 109 | lmodel = &op_model_loongson3_ops; | ||
| 110 | break; | ||
| 107 | }; | 111 | }; |
| 108 | 112 | ||
| 113 | /* | ||
| 114 | * Always set the backtrace. This allows unsupported CPU types to still | ||
| 115 | * use timer-based oprofile. | ||
| 116 | */ | ||
| 117 | ops->backtrace = op_mips_backtrace; | ||
| 118 | |||
| 109 | if (!lmodel) | 119 | if (!lmodel) |
| 110 | return -ENODEV; | 120 | return -ENODEV; |
| 111 | 121 | ||
| @@ -121,7 +131,6 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
| 121 | ops->start = op_mips_start; | 131 | ops->start = op_mips_start; |
| 122 | ops->stop = op_mips_stop; | 132 | ops->stop = op_mips_stop; |
| 123 | ops->cpu_type = lmodel->cpu_type; | 133 | ops->cpu_type = lmodel->cpu_type; |
| 124 | ops->backtrace = op_mips_backtrace; | ||
| 125 | 134 | ||
| 126 | printk(KERN_INFO "oprofile: using %s performance monitoring.\n", | 135 | printk(KERN_INFO "oprofile: using %s performance monitoring.\n", |
| 127 | lmodel->cpu_type); | 136 | lmodel->cpu_type); |
diff --git a/arch/mips/oprofile/op_model_loongson3.c b/arch/mips/oprofile/op_model_loongson3.c new file mode 100644 index 000000000000..8bcf7fc40f0d --- /dev/null +++ b/arch/mips/oprofile/op_model_loongson3.c | |||
| @@ -0,0 +1,220 @@ | |||
| 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 | */ | ||
| 7 | #include <linux/init.h> | ||
| 8 | #include <linux/cpu.h> | ||
| 9 | #include <linux/smp.h> | ||
| 10 | #include <linux/proc_fs.h> | ||
| 11 | #include <linux/oprofile.h> | ||
| 12 | #include <linux/spinlock.h> | ||
| 13 | #include <linux/interrupt.h> | ||
| 14 | #include <asm/uaccess.h> | ||
| 15 | #include <irq.h> | ||
| 16 | #include <loongson.h> | ||
| 17 | #include "op_impl.h" | ||
| 18 | |||
| 19 | #define LOONGSON3_PERFCNT_OVERFLOW (1ULL << 63) | ||
| 20 | |||
| 21 | #define LOONGSON3_PERFCTRL_EXL (1UL << 0) | ||
| 22 | #define LOONGSON3_PERFCTRL_KERNEL (1UL << 1) | ||
| 23 | #define LOONGSON3_PERFCTRL_SUPERVISOR (1UL << 2) | ||
| 24 | #define LOONGSON3_PERFCTRL_USER (1UL << 3) | ||
| 25 | #define LOONGSON3_PERFCTRL_ENABLE (1UL << 4) | ||
| 26 | #define LOONGSON3_PERFCTRL_W (1UL << 30) | ||
| 27 | #define LOONGSON3_PERFCTRL_M (1UL << 31) | ||
| 28 | #define LOONGSON3_PERFCTRL_EVENT(idx, event) \ | ||
| 29 | (((event) & (idx ? 0x0f : 0x3f)) << 5) | ||
| 30 | |||
| 31 | /* Loongson-3 PerfCount performance counter1 register */ | ||
| 32 | #define read_c0_perflo1() __read_64bit_c0_register($25, 0) | ||
| 33 | #define write_c0_perflo1(val) __write_64bit_c0_register($25, 0, val) | ||
| 34 | #define read_c0_perfhi1() __read_64bit_c0_register($25, 1) | ||
| 35 | #define write_c0_perfhi1(val) __write_64bit_c0_register($25, 1, val) | ||
| 36 | |||
| 37 | /* Loongson-3 PerfCount performance counter2 register */ | ||
| 38 | #define read_c0_perflo2() __read_64bit_c0_register($25, 2) | ||
| 39 | #define write_c0_perflo2(val) __write_64bit_c0_register($25, 2, val) | ||
| 40 | #define read_c0_perfhi2() __read_64bit_c0_register($25, 3) | ||
| 41 | #define write_c0_perfhi2(val) __write_64bit_c0_register($25, 3, val) | ||
| 42 | |||
| 43 | static int (*save_perf_irq)(void); | ||
| 44 | |||
| 45 | static struct loongson3_register_config { | ||
| 46 | unsigned int control1; | ||
| 47 | unsigned int control2; | ||
| 48 | unsigned long long reset_counter1; | ||
| 49 | unsigned long long reset_counter2; | ||
| 50 | int ctr1_enable, ctr2_enable; | ||
| 51 | } reg; | ||
| 52 | |||
| 53 | static void reset_counters(void *arg) | ||
| 54 | { | ||
| 55 | write_c0_perfhi1(0); | ||
| 56 | write_c0_perfhi2(0); | ||
| 57 | write_c0_perflo1(0xc0000000); | ||
| 58 | write_c0_perflo2(0x40000000); | ||
| 59 | } | ||
| 60 | |||
| 61 | /* Compute all of the registers in preparation for enabling profiling. */ | ||
| 62 | static void loongson3_reg_setup(struct op_counter_config *ctr) | ||
| 63 | { | ||
| 64 | unsigned int control1 = 0; | ||
| 65 | unsigned int control2 = 0; | ||
| 66 | |||
| 67 | reg.reset_counter1 = 0; | ||
| 68 | reg.reset_counter2 = 0; | ||
| 69 | /* Compute the performance counter control word. */ | ||
| 70 | /* For now count kernel and user mode */ | ||
| 71 | if (ctr[0].enabled) { | ||
| 72 | control1 |= LOONGSON3_PERFCTRL_EVENT(0, ctr[0].event) | | ||
| 73 | LOONGSON3_PERFCTRL_ENABLE; | ||
| 74 | if (ctr[0].kernel) | ||
| 75 | control1 |= LOONGSON3_PERFCTRL_KERNEL; | ||
| 76 | if (ctr[0].user) | ||
| 77 | control1 |= LOONGSON3_PERFCTRL_USER; | ||
| 78 | reg.reset_counter1 = 0x8000000000000000ULL - ctr[0].count; | ||
| 79 | } | ||
| 80 | |||
| 81 | if (ctr[1].enabled) { | ||
| 82 | control2 |= LOONGSON3_PERFCTRL_EVENT(1, ctr[1].event) | | ||
| 83 | LOONGSON3_PERFCTRL_ENABLE; | ||
| 84 | if (ctr[1].kernel) | ||
| 85 | control2 |= LOONGSON3_PERFCTRL_KERNEL; | ||
| 86 | if (ctr[1].user) | ||
| 87 | control2 |= LOONGSON3_PERFCTRL_USER; | ||
| 88 | reg.reset_counter2 = 0x8000000000000000ULL - ctr[1].count; | ||
| 89 | } | ||
| 90 | |||
| 91 | if (ctr[0].enabled) | ||
| 92 | control1 |= LOONGSON3_PERFCTRL_EXL; | ||
| 93 | if (ctr[1].enabled) | ||
| 94 | control2 |= LOONGSON3_PERFCTRL_EXL; | ||
| 95 | |||
| 96 | reg.control1 = control1; | ||
| 97 | reg.control2 = control2; | ||
| 98 | reg.ctr1_enable = ctr[0].enabled; | ||
| 99 | reg.ctr2_enable = ctr[1].enabled; | ||
| 100 | } | ||
| 101 | |||
| 102 | /* Program all of the registers in preparation for enabling profiling. */ | ||
| 103 | static void loongson3_cpu_setup(void *args) | ||
| 104 | { | ||
| 105 | uint64_t perfcount1, perfcount2; | ||
| 106 | |||
| 107 | perfcount1 = reg.reset_counter1; | ||
| 108 | perfcount2 = reg.reset_counter2; | ||
| 109 | write_c0_perfhi1(perfcount1); | ||
| 110 | write_c0_perfhi2(perfcount2); | ||
| 111 | } | ||
| 112 | |||
| 113 | static void loongson3_cpu_start(void *args) | ||
| 114 | { | ||
| 115 | /* Start all counters on current CPU */ | ||
| 116 | reg.control1 |= (LOONGSON3_PERFCTRL_W|LOONGSON3_PERFCTRL_M); | ||
| 117 | reg.control2 |= (LOONGSON3_PERFCTRL_W|LOONGSON3_PERFCTRL_M); | ||
| 118 | |||
| 119 | if (reg.ctr1_enable) | ||
| 120 | write_c0_perflo1(reg.control1); | ||
| 121 | if (reg.ctr2_enable) | ||
| 122 | write_c0_perflo2(reg.control2); | ||
| 123 | } | ||
| 124 | |||
| 125 | static void loongson3_cpu_stop(void *args) | ||
| 126 | { | ||
| 127 | /* Stop all counters on current CPU */ | ||
| 128 | write_c0_perflo1(0xc0000000); | ||
| 129 | write_c0_perflo2(0x40000000); | ||
| 130 | memset(®, 0, sizeof(reg)); | ||
| 131 | } | ||
| 132 | |||
| 133 | static int loongson3_perfcount_handler(void) | ||
| 134 | { | ||
| 135 | unsigned long flags; | ||
| 136 | uint64_t counter1, counter2; | ||
| 137 | uint32_t cause, handled = IRQ_NONE; | ||
| 138 | struct pt_regs *regs = get_irq_regs(); | ||
| 139 | |||
| 140 | cause = read_c0_cause(); | ||
| 141 | if (!(cause & CAUSEF_PCI)) | ||
| 142 | return handled; | ||
| 143 | |||
| 144 | counter1 = read_c0_perfhi1(); | ||
| 145 | counter2 = read_c0_perfhi2(); | ||
| 146 | |||
| 147 | local_irq_save(flags); | ||
| 148 | |||
| 149 | if (counter1 & LOONGSON3_PERFCNT_OVERFLOW) { | ||
| 150 | if (reg.ctr1_enable) | ||
| 151 | oprofile_add_sample(regs, 0); | ||
| 152 | counter1 = reg.reset_counter1; | ||
| 153 | } | ||
| 154 | if (counter2 & LOONGSON3_PERFCNT_OVERFLOW) { | ||
| 155 | if (reg.ctr2_enable) | ||
| 156 | oprofile_add_sample(regs, 1); | ||
| 157 | counter2 = reg.reset_counter2; | ||
| 158 | } | ||
| 159 | |||
| 160 | local_irq_restore(flags); | ||
| 161 | |||
| 162 | write_c0_perfhi1(counter1); | ||
| 163 | write_c0_perfhi2(counter2); | ||
| 164 | |||
| 165 | if (!(cause & CAUSEF_TI)) | ||
| 166 | handled = IRQ_HANDLED; | ||
| 167 | |||
| 168 | return handled; | ||
| 169 | } | ||
| 170 | |||
| 171 | static int loongson3_cpu_callback(struct notifier_block *nfb, | ||
| 172 | unsigned long action, void *hcpu) | ||
| 173 | { | ||
| 174 | switch (action) { | ||
| 175 | case CPU_STARTING: | ||
| 176 | case CPU_STARTING_FROZEN: | ||
| 177 | write_c0_perflo1(reg.control1); | ||
| 178 | write_c0_perflo2(reg.control2); | ||
| 179 | break; | ||
| 180 | case CPU_DYING: | ||
| 181 | case CPU_DYING_FROZEN: | ||
| 182 | write_c0_perflo1(0xc0000000); | ||
| 183 | write_c0_perflo2(0x40000000); | ||
| 184 | break; | ||
| 185 | } | ||
| 186 | |||
| 187 | return NOTIFY_OK; | ||
| 188 | } | ||
| 189 | |||
| 190 | static struct notifier_block loongson3_notifier_block = { | ||
| 191 | .notifier_call = loongson3_cpu_callback | ||
| 192 | }; | ||
| 193 | |||
| 194 | static int __init loongson3_init(void) | ||
| 195 | { | ||
| 196 | on_each_cpu(reset_counters, NULL, 1); | ||
| 197 | register_hotcpu_notifier(&loongson3_notifier_block); | ||
| 198 | save_perf_irq = perf_irq; | ||
| 199 | perf_irq = loongson3_perfcount_handler; | ||
| 200 | |||
| 201 | return 0; | ||
| 202 | } | ||
| 203 | |||
| 204 | static void loongson3_exit(void) | ||
| 205 | { | ||
| 206 | on_each_cpu(reset_counters, NULL, 1); | ||
| 207 | unregister_hotcpu_notifier(&loongson3_notifier_block); | ||
| 208 | perf_irq = save_perf_irq; | ||
| 209 | } | ||
| 210 | |||
| 211 | struct op_mips_model op_model_loongson3_ops = { | ||
| 212 | .reg_setup = loongson3_reg_setup, | ||
| 213 | .cpu_setup = loongson3_cpu_setup, | ||
| 214 | .init = loongson3_init, | ||
| 215 | .exit = loongson3_exit, | ||
| 216 | .cpu_start = loongson3_cpu_start, | ||
| 217 | .cpu_stop = loongson3_cpu_stop, | ||
| 218 | .cpu_type = "mips/loongson3", | ||
| 219 | .num_counters = 2 | ||
| 220 | }; | ||
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index 42821ae2d77e..01f721a85c5b 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
| 12 | #include <linux/smp.h> | 12 | #include <linux/smp.h> |
| 13 | #include <asm/irq_regs.h> | 13 | #include <asm/irq_regs.h> |
| 14 | #include <asm/time.h> | ||
| 14 | 15 | ||
| 15 | #include "op_impl.h" | 16 | #include "op_impl.h" |
| 16 | 17 | ||
| @@ -35,6 +36,7 @@ | |||
| 35 | #define M_PERFCTL_COUNT_ALL_THREADS (1UL << 13) | 36 | #define M_PERFCTL_COUNT_ALL_THREADS (1UL << 13) |
| 36 | 37 | ||
| 37 | static int (*save_perf_irq)(void); | 38 | static int (*save_perf_irq)(void); |
| 39 | static int perfcount_irq; | ||
| 38 | 40 | ||
| 39 | /* | 41 | /* |
| 40 | * XLR has only one set of counters per core. Designate the | 42 | * XLR has only one set of counters per core. Designate the |
| @@ -431,8 +433,16 @@ static int __init mipsxx_init(void) | |||
| 431 | save_perf_irq = perf_irq; | 433 | save_perf_irq = perf_irq; |
| 432 | perf_irq = mipsxx_perfcount_handler; | 434 | perf_irq = mipsxx_perfcount_handler; |
| 433 | 435 | ||
| 434 | if ((cp0_perfcount_irq >= 0) && (cp0_compare_irq != cp0_perfcount_irq)) | 436 | if (get_c0_perfcount_int) |
| 435 | return request_irq(cp0_perfcount_irq, mipsxx_perfcount_int, | 437 | perfcount_irq = get_c0_perfcount_int(); |
| 438 | else if ((cp0_perfcount_irq >= 0) && | ||
| 439 | (cp0_compare_irq != cp0_perfcount_irq)) | ||
| 440 | perfcount_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; | ||
| 441 | else | ||
| 442 | perfcount_irq = -1; | ||
| 443 | |||
| 444 | if (perfcount_irq >= 0) | ||
| 445 | return request_irq(perfcount_irq, mipsxx_perfcount_int, | ||
| 436 | 0, "Perfcounter", save_perf_irq); | 446 | 0, "Perfcounter", save_perf_irq); |
| 437 | 447 | ||
| 438 | return 0; | 448 | return 0; |
| @@ -442,8 +452,8 @@ static void mipsxx_exit(void) | |||
| 442 | { | 452 | { |
| 443 | int counters = op_model_mipsxx_ops.num_counters; | 453 | int counters = op_model_mipsxx_ops.num_counters; |
| 444 | 454 | ||
| 445 | if ((cp0_perfcount_irq >= 0) && (cp0_compare_irq != cp0_perfcount_irq)) | 455 | if (perfcount_irq >= 0) |
| 446 | free_irq(cp0_perfcount_irq, save_perf_irq); | 456 | free_irq(perfcount_irq, save_perf_irq); |
| 447 | 457 | ||
| 448 | counters = counters_per_cpu_to_total(counters); | 458 | counters = counters_per_cpu_to_total(counters); |
| 449 | on_each_cpu(reset_counters, (void *)(long)counters, 1); | 459 | on_each_cpu(reset_counters, (void *)(long)counters, 1); |
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 6523d558ff5a..300591c6278d 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile | |||
| @@ -19,6 +19,7 @@ obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o | |||
| 19 | obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ | 19 | obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ |
| 20 | ops-bcm63xx.o | 20 | ops-bcm63xx.o |
| 21 | obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o | 21 | obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o |
| 22 | obj-$(CONFIG_PCI_AR2315) += pci-ar2315.o | ||
| 22 | obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o | 23 | obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o |
| 23 | obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o | 24 | obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o |
| 24 | obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o | 25 | obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o |
| @@ -42,6 +43,7 @@ obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o | |||
| 42 | obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o | 43 | obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o |
| 43 | obj-$(CONFIG_LANTIQ) += fixup-lantiq.o | 44 | obj-$(CONFIG_LANTIQ) += fixup-lantiq.o |
| 44 | obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o | 45 | obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o |
| 46 | obj-$(CONFIG_SOC_RT2880) += pci-rt2880.o | ||
| 45 | obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o | 47 | obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o |
| 46 | obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o | 48 | obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o |
| 47 | obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o | 49 | obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o |
diff --git a/arch/mips/pci/ops-bcm63xx.c b/arch/mips/pci/ops-bcm63xx.c index 13eea696bbe7..d02eb9d16b55 100644 --- a/arch/mips/pci/ops-bcm63xx.c +++ b/arch/mips/pci/ops-bcm63xx.c | |||
| @@ -469,7 +469,7 @@ static int bcm63xx_pcie_can_access(struct pci_bus *bus, int devfn) | |||
| 469 | { | 469 | { |
| 470 | switch (bus->number) { | 470 | switch (bus->number) { |
| 471 | case PCIE_BUS_BRIDGE: | 471 | case PCIE_BUS_BRIDGE: |
| 472 | return (PCI_SLOT(devfn) == 0); | 472 | return PCI_SLOT(devfn) == 0; |
| 473 | case PCIE_BUS_DEVICE: | 473 | case PCIE_BUS_DEVICE: |
| 474 | if (PCI_SLOT(devfn) == 0) | 474 | if (PCI_SLOT(devfn) == 0) |
| 475 | return bcm_pcie_readl(PCIE_DLSTATUS_REG) | 475 | return bcm_pcie_readl(PCIE_DLSTATUS_REG) |
diff --git a/arch/mips/pci/ops-nile4.c b/arch/mips/pci/ops-nile4.c index a1a7c9f4096e..b9d1fd0ff7e2 100644 --- a/arch/mips/pci/ops-nile4.c +++ b/arch/mips/pci/ops-nile4.c | |||
| @@ -13,8 +13,6 @@ | |||
| 13 | 13 | ||
| 14 | volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE; | 14 | volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE; |
| 15 | 15 | ||
| 16 | static DEFINE_SPINLOCK(nile4_pci_lock); | ||
| 17 | |||
| 18 | static int nile4_pcibios_config_access(unsigned char access_type, | 16 | static int nile4_pcibios_config_access(unsigned char access_type, |
| 19 | struct pci_bus *bus, unsigned int devfn, int where, u32 *val) | 17 | struct pci_bus *bus, unsigned int devfn, int where, u32 *val) |
| 20 | { | 18 | { |
| @@ -76,7 +74,6 @@ static int nile4_pcibios_config_access(unsigned char access_type, | |||
| 76 | static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn, | 74 | static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn, |
| 77 | int where, int size, u32 *val) | 75 | int where, int size, u32 *val) |
| 78 | { | 76 | { |
| 79 | unsigned long flags; | ||
| 80 | u32 data = 0; | 77 | u32 data = 0; |
| 81 | int err; | 78 | int err; |
| 82 | 79 | ||
| @@ -85,11 +82,8 @@ static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn, | |||
| 85 | else if ((size == 4) && (where & 3)) | 82 | else if ((size == 4) && (where & 3)) |
| 86 | return PCIBIOS_BAD_REGISTER_NUMBER; | 83 | return PCIBIOS_BAD_REGISTER_NUMBER; |
| 87 | 84 | ||
| 88 | spin_lock_irqsave(&nile4_pci_lock, flags); | ||
| 89 | err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, | 85 | err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, |
| 90 | &data); | 86 | &data); |
| 91 | spin_unlock_irqrestore(&nile4_pci_lock, flags); | ||
| 92 | |||
| 93 | if (err) | 87 | if (err) |
| 94 | return err; | 88 | return err; |
| 95 | 89 | ||
| @@ -106,7 +100,6 @@ static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn, | |||
| 106 | static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn, | 100 | static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn, |
| 107 | int where, int size, u32 val) | 101 | int where, int size, u32 val) |
| 108 | { | 102 | { |
| 109 | unsigned long flags; | ||
| 110 | u32 data = 0; | 103 | u32 data = 0; |
| 111 | int err; | 104 | int err; |
| 112 | 105 | ||
| @@ -115,11 +108,8 @@ static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn, | |||
| 115 | else if ((size == 4) && (where & 3)) | 108 | else if ((size == 4) && (where & 3)) |
| 116 | return PCIBIOS_BAD_REGISTER_NUMBER; | 109 | return PCIBIOS_BAD_REGISTER_NUMBER; |
| 117 | 110 | ||
| 118 | spin_lock_irqsave(&nile4_pci_lock, flags); | ||
| 119 | err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, | 111 | err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, |
| 120 | &data); | 112 | &data); |
| 121 | spin_unlock_irqrestore(&nile4_pci_lock, flags); | ||
| 122 | |||
| 123 | if (err) | 113 | if (err) |
| 124 | return err; | 114 | return err; |
| 125 | 115 | ||
diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c index 50034f985be1..dd2d9f7e9412 100644 --- a/arch/mips/pci/ops-pmcmsp.c +++ b/arch/mips/pci/ops-pmcmsp.c | |||
| @@ -193,8 +193,6 @@ static void pci_proc_init(void) | |||
| 193 | } | 193 | } |
| 194 | #endif /* CONFIG_PROC_FS && PCI_COUNTERS */ | 194 | #endif /* CONFIG_PROC_FS && PCI_COUNTERS */ |
| 195 | 195 | ||
| 196 | static DEFINE_SPINLOCK(bpci_lock); | ||
| 197 | |||
| 198 | /***************************************************************************** | 196 | /***************************************************************************** |
| 199 | * | 197 | * |
| 200 | * STRUCT: pci_io_resource | 198 | * STRUCT: pci_io_resource |
| @@ -368,7 +366,6 @@ int msp_pcibios_config_access(unsigned char access_type, | |||
| 368 | struct msp_pci_regs *preg = (void *)PCI_BASE_REG; | 366 | struct msp_pci_regs *preg = (void *)PCI_BASE_REG; |
| 369 | unsigned char bus_num = bus->number; | 367 | unsigned char bus_num = bus->number; |
| 370 | unsigned char dev_fn = (unsigned char)devfn; | 368 | unsigned char dev_fn = (unsigned char)devfn; |
| 371 | unsigned long flags; | ||
| 372 | unsigned long intr; | 369 | unsigned long intr; |
| 373 | unsigned long value; | 370 | unsigned long value; |
| 374 | static char pciirqflag; | 371 | static char pciirqflag; |
| @@ -401,10 +398,7 @@ int msp_pcibios_config_access(unsigned char access_type, | |||
| 401 | } | 398 | } |
| 402 | 399 | ||
| 403 | #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) | 400 | #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) |
| 404 | local_irq_save(flags); | ||
| 405 | vpe_status = dvpe(); | 401 | vpe_status = dvpe(); |
| 406 | #else | ||
| 407 | spin_lock_irqsave(&bpci_lock, flags); | ||
| 408 | #endif | 402 | #endif |
| 409 | 403 | ||
| 410 | /* | 404 | /* |
| @@ -457,9 +451,6 @@ int msp_pcibios_config_access(unsigned char access_type, | |||
| 457 | 451 | ||
| 458 | #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) | 452 | #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) |
| 459 | evpe(vpe_status); | 453 | evpe(vpe_status); |
| 460 | local_irq_restore(flags); | ||
| 461 | #else | ||
| 462 | spin_unlock_irqrestore(&bpci_lock, flags); | ||
| 463 | #endif | 454 | #endif |
| 464 | 455 | ||
| 465 | return -1; | 456 | return -1; |
| @@ -467,9 +458,6 @@ int msp_pcibios_config_access(unsigned char access_type, | |||
| 467 | 458 | ||
| 468 | #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) | 459 | #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) |
| 469 | evpe(vpe_status); | 460 | evpe(vpe_status); |
| 470 | local_irq_restore(flags); | ||
| 471 | #else | ||
| 472 | spin_unlock_irqrestore(&bpci_lock, flags); | ||
| 473 | #endif | 461 | #endif |
| 474 | 462 | ||
| 475 | return PCIBIOS_SUCCESSFUL; | 463 | return PCIBIOS_SUCCESSFUL; |
diff --git a/arch/mips/pci/pci-ar2315.c b/arch/mips/pci/pci-ar2315.c new file mode 100644 index 000000000000..bd2b3b60da83 --- /dev/null +++ b/arch/mips/pci/pci-ar2315.c | |||
| @@ -0,0 +1,511 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or | ||
| 3 | * modify it under the terms of the GNU General Public License | ||
| 4 | * as published by the Free Software Foundation; either version 2 | ||
| 5 | * of the License, or (at your option) any later version. | ||
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||
| 14 | */ | ||
| 15 | |||
| 16 | /** | ||
| 17 | * Both AR2315 and AR2316 chips have PCI interface unit, which supports DMA | ||
| 18 | * and interrupt. PCI interface supports MMIO access method, but does not | ||
| 19 | * seem to support I/O ports. | ||
| 20 | * | ||
| 21 | * Read/write operation in the region 0x80000000-0xBFFFFFFF causes | ||
| 22 | * a memory read/write command on the PCI bus. 30 LSBs of address on | ||
| 23 | * the bus are taken from memory read/write request and 2 MSBs are | ||
| 24 | * determined by PCI unit configuration. | ||
| 25 | * | ||
| 26 | * To work with the configuration space instead of memory is necessary set | ||
| 27 | * the CFG_SEL bit in the PCI_MISC_CONFIG register. | ||
| 28 | * | ||
| 29 | * Devices on the bus can perform DMA requests via chip BAR1. PCI host | ||
| 30 | * controller BARs are programmend as if an external device is programmed. | ||
| 31 | * Which means that during configuration, IDSEL pin of the chip should be | ||
| 32 | * asserted. | ||
| 33 | * | ||
| 34 | * We know (and support) only one board that uses the PCI interface - | ||
| 35 | * Fonera 2.0g (FON2202). It has a USB EHCI controller connected to the | ||
| 36 | * AR2315 PCI bus. IDSEL pin of USB controller is connected to AD[13] line | ||
| 37 | * and IDSEL pin of AR2315 is connected to AD[16] line. | ||
| 38 | */ | ||
| 39 | |||
| 40 | #include <linux/types.h> | ||
| 41 | #include <linux/pci.h> | ||
| 42 | #include <linux/platform_device.h> | ||
| 43 | #include <linux/kernel.h> | ||
| 44 | #include <linux/init.h> | ||
| 45 | #include <linux/mm.h> | ||
| 46 | #include <linux/delay.h> | ||
| 47 | #include <linux/bitops.h> | ||
| 48 | #include <linux/irq.h> | ||
| 49 | #include <linux/irqdomain.h> | ||
| 50 | #include <linux/io.h> | ||
| 51 | #include <asm/paccess.h> | ||
| 52 | |||
| 53 | /* | ||
| 54 | * PCI Bus Interface Registers | ||
| 55 | */ | ||
| 56 | #define AR2315_PCI_1MS_REG 0x0008 | ||
| 57 | |||
| 58 | #define AR2315_PCI_1MS_MASK 0x3FFFF /* # of AHB clk cycles in 1ms */ | ||
| 59 | |||
| 60 | #define AR2315_PCI_MISC_CONFIG 0x000c | ||
| 61 | |||
| 62 | #define AR2315_PCIMISC_TXD_EN 0x00000001 /* Enable TXD for fragments */ | ||
| 63 | #define AR2315_PCIMISC_CFG_SEL 0x00000002 /* Mem or Config cycles */ | ||
| 64 | #define AR2315_PCIMISC_GIG_MASK 0x0000000C /* bits 31-30 for pci req */ | ||
| 65 | #define AR2315_PCIMISC_RST_MODE 0x00000030 | ||
| 66 | #define AR2315_PCIRST_INPUT 0x00000000 /* 4:5=0 rst is input */ | ||
| 67 | #define AR2315_PCIRST_LOW 0x00000010 /* 4:5=1 rst to GND */ | ||
| 68 | #define AR2315_PCIRST_HIGH 0x00000020 /* 4:5=2 rst to VDD */ | ||
| 69 | #define AR2315_PCIGRANT_EN 0x00000000 /* 6:7=0 early grant en */ | ||
| 70 | #define AR2315_PCIGRANT_FRAME 0x00000040 /* 6:7=1 grant waits 4 frame */ | ||
| 71 | #define AR2315_PCIGRANT_IDLE 0x00000080 /* 6:7=2 grant waits 4 idle */ | ||
| 72 | #define AR2315_PCIGRANT_GAP 0x00000000 /* 6:7=2 grant waits 4 idle */ | ||
| 73 | #define AR2315_PCICACHE_DIS 0x00001000 /* PCI external access cache | ||
| 74 | * disable */ | ||
| 75 | |||
| 76 | #define AR2315_PCI_OUT_TSTAMP 0x0010 | ||
| 77 | |||
| 78 | #define AR2315_PCI_UNCACHE_CFG 0x0014 | ||
| 79 | |||
| 80 | #define AR2315_PCI_IN_EN 0x0100 | ||
| 81 | |||
| 82 | #define AR2315_PCI_IN_EN0 0x01 /* Enable chain 0 */ | ||
| 83 | #define AR2315_PCI_IN_EN1 0x02 /* Enable chain 1 */ | ||
| 84 | #define AR2315_PCI_IN_EN2 0x04 /* Enable chain 2 */ | ||
| 85 | #define AR2315_PCI_IN_EN3 0x08 /* Enable chain 3 */ | ||
| 86 | |||
| 87 | #define AR2315_PCI_IN_DIS 0x0104 | ||
| 88 | |||
| 89 | #define AR2315_PCI_IN_DIS0 0x01 /* Disable chain 0 */ | ||
| 90 | #define AR2315_PCI_IN_DIS1 0x02 /* Disable chain 1 */ | ||
| 91 | #define AR2315_PCI_IN_DIS2 0x04 /* Disable chain 2 */ | ||
| 92 | #define AR2315_PCI_IN_DIS3 0x08 /* Disable chain 3 */ | ||
| 93 | |||
| 94 | #define AR2315_PCI_IN_PTR 0x0200 | ||
| 95 | |||
| 96 | #define AR2315_PCI_OUT_EN 0x0400 | ||
| 97 | |||
| 98 | #define AR2315_PCI_OUT_EN0 0x01 /* Enable chain 0 */ | ||
| 99 | |||
| 100 | #define AR2315_PCI_OUT_DIS 0x0404 | ||
| 101 | |||
| 102 | #define AR2315_PCI_OUT_DIS0 0x01 /* Disable chain 0 */ | ||
| 103 | |||
| 104 | #define AR2315_PCI_OUT_PTR 0x0408 | ||
| 105 | |||
| 106 | /* PCI interrupt status (write one to clear) */ | ||
| 107 | #define AR2315_PCI_ISR 0x0500 | ||
| 108 | |||
| 109 | #define AR2315_PCI_INT_TX 0x00000001 /* Desc In Completed */ | ||
| 110 | #define AR2315_PCI_INT_TXOK 0x00000002 /* Desc In OK */ | ||
| 111 | #define AR2315_PCI_INT_TXERR 0x00000004 /* Desc In ERR */ | ||
| 112 | #define AR2315_PCI_INT_TXEOL 0x00000008 /* Desc In End-of-List */ | ||
| 113 | #define AR2315_PCI_INT_RX 0x00000010 /* Desc Out Completed */ | ||
| 114 | #define AR2315_PCI_INT_RXOK 0x00000020 /* Desc Out OK */ | ||
| 115 | #define AR2315_PCI_INT_RXERR 0x00000040 /* Desc Out ERR */ | ||
| 116 | #define AR2315_PCI_INT_RXEOL 0x00000080 /* Desc Out EOL */ | ||
| 117 | #define AR2315_PCI_INT_TXOOD 0x00000200 /* Desc In Out-of-Desc */ | ||
| 118 | #define AR2315_PCI_INT_DESCMASK 0x0000FFFF /* Desc Mask */ | ||
| 119 | #define AR2315_PCI_INT_EXT 0x02000000 /* Extern PCI INTA */ | ||
| 120 | #define AR2315_PCI_INT_ABORT 0x04000000 /* PCI bus abort event */ | ||
| 121 | |||
| 122 | /* PCI interrupt mask */ | ||
| 123 | #define AR2315_PCI_IMR 0x0504 | ||
| 124 | |||
| 125 | /* Global PCI interrupt enable */ | ||
| 126 | #define AR2315_PCI_IER 0x0508 | ||
| 127 | |||
| 128 | #define AR2315_PCI_IER_DISABLE 0x00 /* disable pci interrupts */ | ||
| 129 | #define AR2315_PCI_IER_ENABLE 0x01 /* enable pci interrupts */ | ||
| 130 | |||
| 131 | #define AR2315_PCI_HOST_IN_EN 0x0800 | ||
| 132 | #define AR2315_PCI_HOST_IN_DIS 0x0804 | ||
| 133 | #define AR2315_PCI_HOST_IN_PTR 0x0810 | ||
| 134 | #define AR2315_PCI_HOST_OUT_EN 0x0900 | ||
| 135 | #define AR2315_PCI_HOST_OUT_DIS 0x0904 | ||
| 136 | #define AR2315_PCI_HOST_OUT_PTR 0x0908 | ||
| 137 | |||
| 138 | /* | ||
| 139 | * PCI interrupts, which share IP5 | ||
| 140 | * Keep ordered according to AR2315_PCI_INT_XXX bits | ||
| 141 | */ | ||
| 142 | #define AR2315_PCI_IRQ_EXT 25 | ||
| 143 | #define AR2315_PCI_IRQ_ABORT 26 | ||
| 144 | #define AR2315_PCI_IRQ_COUNT 27 | ||
| 145 | |||
| 146 | /* Arbitrary size of memory region to access the configuration space */ | ||
| 147 | #define AR2315_PCI_CFG_SIZE 0x00100000 | ||
| 148 | |||
| 149 | #define AR2315_PCI_HOST_SLOT 3 | ||
| 150 | #define AR2315_PCI_HOST_DEVID ((0xff18 << 16) | PCI_VENDOR_ID_ATHEROS) | ||
| 151 | |||
| 152 | /* ??? access BAR */ | ||
| 153 | #define AR2315_PCI_HOST_MBAR0 0x10000000 | ||
| 154 | /* RAM access BAR */ | ||
| 155 | #define AR2315_PCI_HOST_MBAR1 AR2315_PCI_HOST_SDRAM_BASEADDR | ||
| 156 | /* ??? access BAR */ | ||
| 157 | #define AR2315_PCI_HOST_MBAR2 0x30000000 | ||
| 158 | |||
| 159 | struct ar2315_pci_ctrl { | ||
| 160 | void __iomem *cfg_mem; | ||
| 161 | void __iomem *mmr_mem; | ||
| 162 | unsigned irq; | ||
| 163 | unsigned irq_ext; | ||
| 164 | struct irq_domain *domain; | ||
| 165 | struct pci_controller pci_ctrl; | ||
| 166 | struct resource mem_res; | ||
| 167 | struct resource io_res; | ||
| 168 | }; | ||
| 169 | |||
| 170 | static inline struct ar2315_pci_ctrl *ar2315_pci_bus_to_apc(struct pci_bus *bus) | ||
| 171 | { | ||
| 172 | struct pci_controller *hose = bus->sysdata; | ||
| 173 | |||
| 174 | return container_of(hose, struct ar2315_pci_ctrl, pci_ctrl); | ||
| 175 | } | ||
| 176 | |||
| 177 | static inline u32 ar2315_pci_reg_read(struct ar2315_pci_ctrl *apc, u32 reg) | ||
| 178 | { | ||
| 179 | return __raw_readl(apc->mmr_mem + reg); | ||
| 180 | } | ||
| 181 | |||
| 182 | static inline void ar2315_pci_reg_write(struct ar2315_pci_ctrl *apc, u32 reg, | ||
| 183 | u32 val) | ||
| 184 | { | ||
| 185 | __raw_writel(val, apc->mmr_mem + reg); | ||
| 186 | } | ||
| 187 | |||
| 188 | static inline void ar2315_pci_reg_mask(struct ar2315_pci_ctrl *apc, u32 reg, | ||
| 189 | u32 mask, u32 val) | ||
| 190 | { | ||
| 191 | u32 ret = ar2315_pci_reg_read(apc, reg); | ||
| 192 | |||
| 193 | ret &= ~mask; | ||
| 194 | ret |= val; | ||
| 195 | ar2315_pci_reg_write(apc, reg, ret); | ||
| 196 | } | ||
| 197 | |||
| 198 | static int ar2315_pci_cfg_access(struct ar2315_pci_ctrl *apc, unsigned devfn, | ||
| 199 | int where, int size, u32 *ptr, bool write) | ||
| 200 | { | ||
| 201 | int func = PCI_FUNC(devfn); | ||
| 202 | int dev = PCI_SLOT(devfn); | ||
| 203 | u32 addr = (1 << (13 + dev)) | (func << 8) | (where & ~3); | ||
| 204 | u32 mask = 0xffffffff >> 8 * (4 - size); | ||
| 205 | u32 sh = (where & 3) * 8; | ||
| 206 | u32 value, isr; | ||
| 207 | |||
| 208 | /* Prevent access past the remapped area */ | ||
| 209 | if (addr >= AR2315_PCI_CFG_SIZE || dev > 18) | ||
| 210 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 211 | |||
| 212 | /* Clear pending errors */ | ||
| 213 | ar2315_pci_reg_write(apc, AR2315_PCI_ISR, AR2315_PCI_INT_ABORT); | ||
| 214 | /* Select Configuration access */ | ||
| 215 | ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG, 0, | ||
| 216 | AR2315_PCIMISC_CFG_SEL); | ||
| 217 | |||
| 218 | mb(); /* PCI must see space change before we begin */ | ||
| 219 | |||
| 220 | value = __raw_readl(apc->cfg_mem + addr); | ||
| 221 | |||
| 222 | isr = ar2315_pci_reg_read(apc, AR2315_PCI_ISR); | ||
| 223 | |||
| 224 | if (isr & AR2315_PCI_INT_ABORT) | ||
| 225 | goto exit_err; | ||
| 226 | |||
| 227 | if (write) { | ||
| 228 | value = (value & ~(mask << sh)) | *ptr << sh; | ||
| 229 | __raw_writel(value, apc->cfg_mem + addr); | ||
| 230 | isr = ar2315_pci_reg_read(apc, AR2315_PCI_ISR); | ||
| 231 | if (isr & AR2315_PCI_INT_ABORT) | ||
| 232 | goto exit_err; | ||
| 233 | } else { | ||
| 234 | *ptr = (value >> sh) & mask; | ||
| 235 | } | ||
| 236 | |||
| 237 | goto exit; | ||
| 238 | |||
| 239 | exit_err: | ||
| 240 | ar2315_pci_reg_write(apc, AR2315_PCI_ISR, AR2315_PCI_INT_ABORT); | ||
| 241 | if (!write) | ||
| 242 | *ptr = 0xffffffff; | ||
| 243 | |||
| 244 | exit: | ||
| 245 | /* Select Memory access */ | ||
| 246 | ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG, AR2315_PCIMISC_CFG_SEL, | ||
| 247 | 0); | ||
| 248 | |||
| 249 | return isr & AR2315_PCI_INT_ABORT ? PCIBIOS_DEVICE_NOT_FOUND : | ||
| 250 | PCIBIOS_SUCCESSFUL; | ||
| 251 | } | ||
| 252 | |||
| 253 | static inline int ar2315_pci_local_cfg_rd(struct ar2315_pci_ctrl *apc, | ||
| 254 | unsigned devfn, int where, u32 *val) | ||
| 255 | { | ||
| 256 | return ar2315_pci_cfg_access(apc, devfn, where, sizeof(u32), val, | ||
| 257 | false); | ||
| 258 | } | ||
| 259 | |||
| 260 | static inline int ar2315_pci_local_cfg_wr(struct ar2315_pci_ctrl *apc, | ||
| 261 | unsigned devfn, int where, u32 val) | ||
| 262 | { | ||
| 263 | return ar2315_pci_cfg_access(apc, devfn, where, sizeof(u32), &val, | ||
| 264 | true); | ||
| 265 | } | ||
| 266 | |||
| 267 | static int ar2315_pci_cfg_read(struct pci_bus *bus, unsigned devfn, int where, | ||
| 268 | int size, u32 *value) | ||
| 269 | { | ||
| 270 | struct ar2315_pci_ctrl *apc = ar2315_pci_bus_to_apc(bus); | ||
| 271 | |||
| 272 | if (PCI_SLOT(devfn) == AR2315_PCI_HOST_SLOT) | ||
| 273 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 274 | |||
| 275 | return ar2315_pci_cfg_access(apc, devfn, where, size, value, false); | ||
| 276 | } | ||
| 277 | |||
| 278 | static int ar2315_pci_cfg_write(struct pci_bus *bus, unsigned devfn, int where, | ||
| 279 | int size, u32 value) | ||
| 280 | { | ||
| 281 | struct ar2315_pci_ctrl *apc = ar2315_pci_bus_to_apc(bus); | ||
| 282 | |||
| 283 | if (PCI_SLOT(devfn) == AR2315_PCI_HOST_SLOT) | ||
| 284 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 285 | |||
| 286 | return ar2315_pci_cfg_access(apc, devfn, where, size, &value, true); | ||
| 287 | } | ||
| 288 | |||
| 289 | static struct pci_ops ar2315_pci_ops = { | ||
| 290 | .read = ar2315_pci_cfg_read, | ||
| 291 | .write = ar2315_pci_cfg_write, | ||
| 292 | }; | ||
| 293 | |||
| 294 | static int ar2315_pci_host_setup(struct ar2315_pci_ctrl *apc) | ||
| 295 | { | ||
| 296 | unsigned devfn = PCI_DEVFN(AR2315_PCI_HOST_SLOT, 0); | ||
| 297 | int res; | ||
| 298 | u32 id; | ||
| 299 | |||
| 300 | res = ar2315_pci_local_cfg_rd(apc, devfn, PCI_VENDOR_ID, &id); | ||
| 301 | if (res != PCIBIOS_SUCCESSFUL || id != AR2315_PCI_HOST_DEVID) | ||
| 302 | return -ENODEV; | ||
| 303 | |||
| 304 | /* Program MBARs */ | ||
| 305 | ar2315_pci_local_cfg_wr(apc, devfn, PCI_BASE_ADDRESS_0, | ||
| 306 | AR2315_PCI_HOST_MBAR0); | ||
| 307 | ar2315_pci_local_cfg_wr(apc, devfn, PCI_BASE_ADDRESS_1, | ||
| 308 | AR2315_PCI_HOST_MBAR1); | ||
| 309 | ar2315_pci_local_cfg_wr(apc, devfn, PCI_BASE_ADDRESS_2, | ||
| 310 | AR2315_PCI_HOST_MBAR2); | ||
| 311 | |||
| 312 | /* Run */ | ||
| 313 | ar2315_pci_local_cfg_wr(apc, devfn, PCI_COMMAND, PCI_COMMAND_MEMORY | | ||
| 314 | PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL | | ||
| 315 | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | | ||
| 316 | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK); | ||
| 317 | |||
| 318 | return 0; | ||
| 319 | } | ||
| 320 | |||
| 321 | static void ar2315_pci_irq_handler(unsigned irq, struct irq_desc *desc) | ||
| 322 | { | ||
| 323 | struct ar2315_pci_ctrl *apc = irq_get_handler_data(irq); | ||
| 324 | u32 pending = ar2315_pci_reg_read(apc, AR2315_PCI_ISR) & | ||
| 325 | ar2315_pci_reg_read(apc, AR2315_PCI_IMR); | ||
| 326 | unsigned pci_irq = 0; | ||
| 327 | |||
| 328 | if (pending) | ||
| 329 | pci_irq = irq_find_mapping(apc->domain, __ffs(pending)); | ||
| 330 | |||
| 331 | if (pci_irq) | ||
| 332 | generic_handle_irq(pci_irq); | ||
| 333 | else | ||
| 334 | spurious_interrupt(); | ||
| 335 | } | ||
| 336 | |||
| 337 | static void ar2315_pci_irq_mask(struct irq_data *d) | ||
| 338 | { | ||
| 339 | struct ar2315_pci_ctrl *apc = irq_data_get_irq_chip_data(d); | ||
| 340 | |||
| 341 | ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, BIT(d->hwirq), 0); | ||
| 342 | } | ||
| 343 | |||
| 344 | static void ar2315_pci_irq_mask_ack(struct irq_data *d) | ||
| 345 | { | ||
| 346 | struct ar2315_pci_ctrl *apc = irq_data_get_irq_chip_data(d); | ||
| 347 | u32 m = BIT(d->hwirq); | ||
| 348 | |||
| 349 | ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, m, 0); | ||
| 350 | ar2315_pci_reg_write(apc, AR2315_PCI_ISR, m); | ||
| 351 | } | ||
| 352 | |||
| 353 | static void ar2315_pci_irq_unmask(struct irq_data *d) | ||
| 354 | { | ||
| 355 | struct ar2315_pci_ctrl *apc = irq_data_get_irq_chip_data(d); | ||
| 356 | |||
| 357 | ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, 0, BIT(d->hwirq)); | ||
| 358 | } | ||
| 359 | |||
| 360 | static struct irq_chip ar2315_pci_irq_chip = { | ||
| 361 | .name = "AR2315-PCI", | ||
| 362 | .irq_mask = ar2315_pci_irq_mask, | ||
| 363 | .irq_mask_ack = ar2315_pci_irq_mask_ack, | ||
| 364 | .irq_unmask = ar2315_pci_irq_unmask, | ||
| 365 | }; | ||
| 366 | |||
| 367 | static int ar2315_pci_irq_map(struct irq_domain *d, unsigned irq, | ||
| 368 | irq_hw_number_t hw) | ||
| 369 | { | ||
| 370 | irq_set_chip_and_handler(irq, &ar2315_pci_irq_chip, handle_level_irq); | ||
| 371 | irq_set_chip_data(irq, d->host_data); | ||
| 372 | return 0; | ||
| 373 | } | ||
| 374 | |||
| 375 | static struct irq_domain_ops ar2315_pci_irq_domain_ops = { | ||
| 376 | .map = ar2315_pci_irq_map, | ||
| 377 | }; | ||
| 378 | |||
| 379 | static void ar2315_pci_irq_init(struct ar2315_pci_ctrl *apc) | ||
| 380 | { | ||
| 381 | ar2315_pci_reg_mask(apc, AR2315_PCI_IER, AR2315_PCI_IER_ENABLE, 0); | ||
| 382 | ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, (AR2315_PCI_INT_ABORT | | ||
| 383 | AR2315_PCI_INT_EXT), 0); | ||
| 384 | |||
| 385 | apc->irq_ext = irq_create_mapping(apc->domain, AR2315_PCI_IRQ_EXT); | ||
| 386 | |||
| 387 | irq_set_chained_handler(apc->irq, ar2315_pci_irq_handler); | ||
| 388 | irq_set_handler_data(apc->irq, apc); | ||
| 389 | |||
| 390 | /* Clear any pending Abort or external Interrupts | ||
| 391 | * and enable interrupt processing */ | ||
| 392 | ar2315_pci_reg_write(apc, AR2315_PCI_ISR, AR2315_PCI_INT_ABORT | | ||
| 393 | AR2315_PCI_INT_EXT); | ||
| 394 | ar2315_pci_reg_mask(apc, AR2315_PCI_IER, 0, AR2315_PCI_IER_ENABLE); | ||
| 395 | } | ||
| 396 | |||
| 397 | static int ar2315_pci_probe(struct platform_device *pdev) | ||
| 398 | { | ||
| 399 | struct ar2315_pci_ctrl *apc; | ||
| 400 | struct device *dev = &pdev->dev; | ||
| 401 | struct resource *res; | ||
| 402 | int irq, err; | ||
| 403 | |||
| 404 | apc = devm_kzalloc(dev, sizeof(*apc), GFP_KERNEL); | ||
| 405 | if (!apc) | ||
| 406 | return -ENOMEM; | ||
| 407 | |||
| 408 | irq = platform_get_irq(pdev, 0); | ||
| 409 | if (irq < 0) | ||
| 410 | return -EINVAL; | ||
| 411 | apc->irq = irq; | ||
| 412 | |||
| 413 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | ||
| 414 | "ar2315-pci-ctrl"); | ||
| 415 | apc->mmr_mem = devm_ioremap_resource(dev, res); | ||
| 416 | if (IS_ERR(apc->mmr_mem)) | ||
| 417 | return PTR_ERR(apc->mmr_mem); | ||
| 418 | |||
| 419 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | ||
| 420 | "ar2315-pci-ext"); | ||
| 421 | if (!res) | ||
| 422 | return -EINVAL; | ||
| 423 | |||
| 424 | apc->mem_res.name = "AR2315 PCI mem space"; | ||
| 425 | apc->mem_res.parent = res; | ||
| 426 | apc->mem_res.start = res->start; | ||
| 427 | apc->mem_res.end = res->end; | ||
| 428 | apc->mem_res.flags = IORESOURCE_MEM; | ||
| 429 | |||
| 430 | /* Remap PCI config space */ | ||
| 431 | apc->cfg_mem = devm_ioremap_nocache(dev, res->start, | ||
| 432 | AR2315_PCI_CFG_SIZE); | ||
| 433 | if (!apc->cfg_mem) { | ||
| 434 | dev_err(dev, "failed to remap PCI config space\n"); | ||
| 435 | return -ENOMEM; | ||
| 436 | } | ||
| 437 | |||
| 438 | /* Reset the PCI bus by setting bits 5-4 in PCI_MCFG */ | ||
| 439 | ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG, | ||
| 440 | AR2315_PCIMISC_RST_MODE, | ||
| 441 | AR2315_PCIRST_LOW); | ||
| 442 | msleep(100); | ||
| 443 | |||
| 444 | /* Bring the PCI out of reset */ | ||
| 445 | ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG, | ||
| 446 | AR2315_PCIMISC_RST_MODE, | ||
| 447 | AR2315_PCIRST_HIGH | AR2315_PCICACHE_DIS | 0x8); | ||
| 448 | |||
| 449 | ar2315_pci_reg_write(apc, AR2315_PCI_UNCACHE_CFG, | ||
| 450 | 0x1E | /* 1GB uncached */ | ||
| 451 | (1 << 5) | /* Enable uncached */ | ||
| 452 | (0x2 << 30) /* Base: 0x80000000 */); | ||
| 453 | ar2315_pci_reg_read(apc, AR2315_PCI_UNCACHE_CFG); | ||
| 454 | |||
| 455 | msleep(500); | ||
| 456 | |||
| 457 | err = ar2315_pci_host_setup(apc); | ||
| 458 | if (err) | ||
| 459 | return err; | ||
| 460 | |||
| 461 | apc->domain = irq_domain_add_linear(NULL, AR2315_PCI_IRQ_COUNT, | ||
| 462 | &ar2315_pci_irq_domain_ops, apc); | ||
| 463 | if (!apc->domain) { | ||
| 464 | dev_err(dev, "failed to add IRQ domain\n"); | ||
| 465 | return -ENOMEM; | ||
| 466 | } | ||
| 467 | |||
| 468 | ar2315_pci_irq_init(apc); | ||
| 469 | |||
| 470 | /* PCI controller does not support I/O ports */ | ||
| 471 | apc->io_res.name = "AR2315 IO space"; | ||
| 472 | apc->io_res.start = 0; | ||
| 473 | apc->io_res.end = 0; | ||
| 474 | apc->io_res.flags = IORESOURCE_IO, | ||
| 475 | |||
| 476 | apc->pci_ctrl.pci_ops = &ar2315_pci_ops; | ||
| 477 | apc->pci_ctrl.mem_resource = &apc->mem_res, | ||
| 478 | apc->pci_ctrl.io_resource = &apc->io_res, | ||
| 479 | |||
| 480 | register_pci_controller(&apc->pci_ctrl); | ||
| 481 | |||
| 482 | dev_info(dev, "register PCI controller\n"); | ||
| 483 | |||
| 484 | return 0; | ||
| 485 | } | ||
| 486 | |||
| 487 | static struct platform_driver ar2315_pci_driver = { | ||
| 488 | .probe = ar2315_pci_probe, | ||
| 489 | .driver = { | ||
| 490 | .name = "ar2315-pci", | ||
| 491 | .owner = THIS_MODULE, | ||
| 492 | }, | ||
| 493 | }; | ||
| 494 | |||
| 495 | static int __init ar2315_pci_init(void) | ||
| 496 | { | ||
| 497 | return platform_driver_register(&ar2315_pci_driver); | ||
| 498 | } | ||
| 499 | arch_initcall(ar2315_pci_init); | ||
| 500 | |||
| 501 | int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | ||
| 502 | { | ||
| 503 | struct ar2315_pci_ctrl *apc = ar2315_pci_bus_to_apc(dev->bus); | ||
| 504 | |||
| 505 | return slot ? 0 : apc->irq_ext; | ||
| 506 | } | ||
| 507 | |||
| 508 | int pcibios_plat_dev_init(struct pci_dev *dev) | ||
| 509 | { | ||
| 510 | return 0; | ||
| 511 | } | ||
diff --git a/arch/mips/pci/pci-ar71xx.c b/arch/mips/pci/pci-ar71xx.c index d471a26dd5f8..2b534aea20e4 100644 --- a/arch/mips/pci/pci-ar71xx.c +++ b/arch/mips/pci/pci-ar71xx.c | |||
| @@ -50,7 +50,6 @@ | |||
| 50 | 50 | ||
| 51 | struct ar71xx_pci_controller { | 51 | struct ar71xx_pci_controller { |
| 52 | void __iomem *cfg_base; | 52 | void __iomem *cfg_base; |
| 53 | spinlock_t lock; | ||
| 54 | int irq; | 53 | int irq; |
| 55 | int irq_base; | 54 | int irq_base; |
| 56 | struct pci_controller pci_ctrl; | 55 | struct pci_controller pci_ctrl; |
| @@ -182,7 +181,6 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, | |||
| 182 | { | 181 | { |
| 183 | struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus); | 182 | struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus); |
| 184 | void __iomem *base = apc->cfg_base; | 183 | void __iomem *base = apc->cfg_base; |
| 185 | unsigned long flags; | ||
| 186 | u32 data; | 184 | u32 data; |
| 187 | int err; | 185 | int err; |
| 188 | int ret; | 186 | int ret; |
| @@ -190,8 +188,6 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, | |||
| 190 | ret = PCIBIOS_SUCCESSFUL; | 188 | ret = PCIBIOS_SUCCESSFUL; |
| 191 | data = ~0; | 189 | data = ~0; |
| 192 | 190 | ||
| 193 | spin_lock_irqsave(&apc->lock, flags); | ||
| 194 | |||
| 195 | err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, | 191 | err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, |
| 196 | AR71XX_PCI_CFG_CMD_READ); | 192 | AR71XX_PCI_CFG_CMD_READ); |
| 197 | if (err) | 193 | if (err) |
| @@ -199,8 +195,6 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, | |||
| 199 | else | 195 | else |
| 200 | data = __raw_readl(base + AR71XX_PCI_REG_CFG_RDDATA); | 196 | data = __raw_readl(base + AR71XX_PCI_REG_CFG_RDDATA); |
| 201 | 197 | ||
| 202 | spin_unlock_irqrestore(&apc->lock, flags); | ||
| 203 | |||
| 204 | *value = (data >> (8 * (where & 3))) & ar71xx_pci_read_mask[size & 7]; | 198 | *value = (data >> (8 * (where & 3))) & ar71xx_pci_read_mask[size & 7]; |
| 205 | 199 | ||
| 206 | return ret; | 200 | return ret; |
| @@ -211,15 +205,12 @@ static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, | |||
| 211 | { | 205 | { |
| 212 | struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus); | 206 | struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus); |
| 213 | void __iomem *base = apc->cfg_base; | 207 | void __iomem *base = apc->cfg_base; |
| 214 | unsigned long flags; | ||
| 215 | int err; | 208 | int err; |
| 216 | int ret; | 209 | int ret; |
| 217 | 210 | ||
| 218 | value = value << (8 * (where & 3)); | 211 | value = value << (8 * (where & 3)); |
| 219 | ret = PCIBIOS_SUCCESSFUL; | 212 | ret = PCIBIOS_SUCCESSFUL; |
| 220 | 213 | ||
| 221 | spin_lock_irqsave(&apc->lock, flags); | ||
| 222 | |||
| 223 | err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, | 214 | err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, |
| 224 | AR71XX_PCI_CFG_CMD_WRITE); | 215 | AR71XX_PCI_CFG_CMD_WRITE); |
| 225 | if (err) | 216 | if (err) |
| @@ -227,8 +218,6 @@ static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, | |||
| 227 | else | 218 | else |
| 228 | __raw_writel(value, base + AR71XX_PCI_REG_CFG_WRDATA); | 219 | __raw_writel(value, base + AR71XX_PCI_REG_CFG_WRDATA); |
| 229 | 220 | ||
| 230 | spin_unlock_irqrestore(&apc->lock, flags); | ||
| 231 | |||
| 232 | return ret; | 221 | return ret; |
| 233 | } | 222 | } |
| 234 | 223 | ||
| @@ -360,8 +349,6 @@ static int ar71xx_pci_probe(struct platform_device *pdev) | |||
| 360 | if (!apc) | 349 | if (!apc) |
| 361 | return -ENOMEM; | 350 | return -ENOMEM; |
| 362 | 351 | ||
| 363 | spin_lock_init(&apc->lock); | ||
| 364 | |||
| 365 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base"); | 352 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base"); |
| 366 | apc->cfg_base = devm_ioremap_resource(&pdev->dev, res); | 353 | apc->cfg_base = devm_ioremap_resource(&pdev->dev, res); |
| 367 | if (IS_ERR(apc->cfg_base)) | 354 | if (IS_ERR(apc->cfg_base)) |
diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c index 785b2659b519..b7a6fcbb8852 100644 --- a/arch/mips/pci/pci-ar724x.c +++ b/arch/mips/pci/pci-ar724x.c | |||
| @@ -9,7 +9,6 @@ | |||
| 9 | * by the Free Software Foundation. | 9 | * by the Free Software Foundation. |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/spinlock.h> | ||
| 13 | #include <linux/irq.h> | 12 | #include <linux/irq.h> |
| 14 | #include <linux/pci.h> | 13 | #include <linux/pci.h> |
| 15 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| @@ -48,8 +47,6 @@ struct ar724x_pci_controller { | |||
| 48 | bool bar0_is_cached; | 47 | bool bar0_is_cached; |
| 49 | u32 bar0_value; | 48 | u32 bar0_value; |
| 50 | 49 | ||
| 51 | spinlock_t lock; | ||
| 52 | |||
| 53 | struct pci_controller pci_controller; | 50 | struct pci_controller pci_controller; |
| 54 | struct resource io_res; | 51 | struct resource io_res; |
| 55 | struct resource mem_res; | 52 | struct resource mem_res; |
| @@ -75,7 +72,6 @@ pci_bus_to_ar724x_controller(struct pci_bus *bus) | |||
| 75 | static int ar724x_pci_local_write(struct ar724x_pci_controller *apc, | 72 | static int ar724x_pci_local_write(struct ar724x_pci_controller *apc, |
| 76 | int where, int size, u32 value) | 73 | int where, int size, u32 value) |
| 77 | { | 74 | { |
| 78 | unsigned long flags; | ||
| 79 | void __iomem *base; | 75 | void __iomem *base; |
| 80 | u32 data; | 76 | u32 data; |
| 81 | int s; | 77 | int s; |
| @@ -86,8 +82,6 @@ static int ar724x_pci_local_write(struct ar724x_pci_controller *apc, | |||
| 86 | return PCIBIOS_DEVICE_NOT_FOUND; | 82 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 87 | 83 | ||
| 88 | base = apc->crp_base; | 84 | base = apc->crp_base; |
| 89 | |||
| 90 | spin_lock_irqsave(&apc->lock, flags); | ||
| 91 | data = __raw_readl(base + (where & ~3)); | 85 | data = __raw_readl(base + (where & ~3)); |
| 92 | 86 | ||
| 93 | switch (size) { | 87 | switch (size) { |
| @@ -105,14 +99,12 @@ static int ar724x_pci_local_write(struct ar724x_pci_controller *apc, | |||
| 105 | data = value; | 99 | data = value; |
| 106 | break; | 100 | break; |
| 107 | default: | 101 | default: |
| 108 | spin_unlock_irqrestore(&apc->lock, flags); | ||
| 109 | return PCIBIOS_BAD_REGISTER_NUMBER; | 102 | return PCIBIOS_BAD_REGISTER_NUMBER; |
| 110 | } | 103 | } |
| 111 | 104 | ||
| 112 | __raw_writel(data, base + (where & ~3)); | 105 | __raw_writel(data, base + (where & ~3)); |
| 113 | /* flush write */ | 106 | /* flush write */ |
| 114 | __raw_readl(base + (where & ~3)); | 107 | __raw_readl(base + (where & ~3)); |
| 115 | spin_unlock_irqrestore(&apc->lock, flags); | ||
| 116 | 108 | ||
| 117 | return PCIBIOS_SUCCESSFUL; | 109 | return PCIBIOS_SUCCESSFUL; |
| 118 | } | 110 | } |
| @@ -121,7 +113,6 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, | |||
| 121 | int size, uint32_t *value) | 113 | int size, uint32_t *value) |
| 122 | { | 114 | { |
| 123 | struct ar724x_pci_controller *apc; | 115 | struct ar724x_pci_controller *apc; |
| 124 | unsigned long flags; | ||
| 125 | void __iomem *base; | 116 | void __iomem *base; |
| 126 | u32 data; | 117 | u32 data; |
| 127 | 118 | ||
| @@ -133,8 +124,6 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, | |||
| 133 | return PCIBIOS_DEVICE_NOT_FOUND; | 124 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 134 | 125 | ||
| 135 | base = apc->devcfg_base; | 126 | base = apc->devcfg_base; |
| 136 | |||
| 137 | spin_lock_irqsave(&apc->lock, flags); | ||
| 138 | data = __raw_readl(base + (where & ~3)); | 127 | data = __raw_readl(base + (where & ~3)); |
| 139 | 128 | ||
| 140 | switch (size) { | 129 | switch (size) { |
| @@ -153,13 +142,9 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, | |||
| 153 | case 4: | 142 | case 4: |
| 154 | break; | 143 | break; |
| 155 | default: | 144 | default: |
| 156 | spin_unlock_irqrestore(&apc->lock, flags); | ||
| 157 | |||
| 158 | return PCIBIOS_BAD_REGISTER_NUMBER; | 145 | return PCIBIOS_BAD_REGISTER_NUMBER; |
| 159 | } | 146 | } |
| 160 | 147 | ||
| 161 | spin_unlock_irqrestore(&apc->lock, flags); | ||
| 162 | |||
| 163 | if (where == PCI_BASE_ADDRESS_0 && size == 4 && | 148 | if (where == PCI_BASE_ADDRESS_0 && size == 4 && |
| 164 | apc->bar0_is_cached) { | 149 | apc->bar0_is_cached) { |
| 165 | /* use the cached value */ | 150 | /* use the cached value */ |
| @@ -175,7 +160,6 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, | |||
| 175 | int size, uint32_t value) | 160 | int size, uint32_t value) |
| 176 | { | 161 | { |
| 177 | struct ar724x_pci_controller *apc; | 162 | struct ar724x_pci_controller *apc; |
| 178 | unsigned long flags; | ||
| 179 | void __iomem *base; | 163 | void __iomem *base; |
| 180 | u32 data; | 164 | u32 data; |
| 181 | int s; | 165 | int s; |
| @@ -209,8 +193,6 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, | |||
| 209 | } | 193 | } |
| 210 | 194 | ||
| 211 | base = apc->devcfg_base; | 195 | base = apc->devcfg_base; |
| 212 | |||
| 213 | spin_lock_irqsave(&apc->lock, flags); | ||
| 214 | data = __raw_readl(base + (where & ~3)); | 196 | data = __raw_readl(base + (where & ~3)); |
| 215 | 197 | ||
| 216 | switch (size) { | 198 | switch (size) { |
| @@ -228,15 +210,12 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, | |||
| 228 | data = value; | 210 | data = value; |
| 229 | break; | 211 | break; |
| 230 | default: | 212 | default: |
| 231 | spin_unlock_irqrestore(&apc->lock, flags); | ||
| 232 | |||
| 233 | return PCIBIOS_BAD_REGISTER_NUMBER; | 213 | return PCIBIOS_BAD_REGISTER_NUMBER; |
| 234 | } | 214 | } |
| 235 | 215 | ||
| 236 | __raw_writel(data, base + (where & ~3)); | 216 | __raw_writel(data, base + (where & ~3)); |
| 237 | /* flush write */ | 217 | /* flush write */ |
| 238 | __raw_readl(base + (where & ~3)); | 218 | __raw_readl(base + (where & ~3)); |
| 239 | spin_unlock_irqrestore(&apc->lock, flags); | ||
| 240 | 219 | ||
| 241 | return PCIBIOS_SUCCESSFUL; | 220 | return PCIBIOS_SUCCESSFUL; |
| 242 | } | 221 | } |
| @@ -380,8 +359,6 @@ static int ar724x_pci_probe(struct platform_device *pdev) | |||
| 380 | if (apc->irq < 0) | 359 | if (apc->irq < 0) |
| 381 | return -EINVAL; | 360 | return -EINVAL; |
| 382 | 361 | ||
| 383 | spin_lock_init(&apc->lock); | ||
| 384 | |||
| 385 | res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base"); | 362 | res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base"); |
| 386 | if (!res) | 363 | if (!res) |
| 387 | return -EINVAL; | 364 | return -EINVAL; |
diff --git a/arch/mips/pci/pci-rt2880.c b/arch/mips/pci/pci-rt2880.c new file mode 100644 index 000000000000..a4574947e698 --- /dev/null +++ b/arch/mips/pci/pci-rt2880.c | |||
| @@ -0,0 +1,285 @@ | |||
| 1 | /* | ||
| 2 | * Ralink RT288x SoC PCI register definitions | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009 John Crispin <blogic@openwrt.org> | ||
| 5 | * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> | ||
| 6 | * | ||
| 7 | * Parts of this file are based on Ralink's 2.6.21 BSP | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify it | ||
| 10 | * under the terms of the GNU General Public License version 2 as published | ||
| 11 | * by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/types.h> | ||
| 15 | #include <linux/pci.h> | ||
| 16 | #include <linux/io.h> | ||
| 17 | #include <linux/init.h> | ||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/of_platform.h> | ||
| 20 | #include <linux/of_irq.h> | ||
| 21 | #include <linux/of_pci.h> | ||
| 22 | |||
| 23 | #include <asm/mach-ralink/rt288x.h> | ||
| 24 | |||
| 25 | #define RT2880_PCI_BASE 0x00440000 | ||
| 26 | #define RT288X_CPU_IRQ_PCI 4 | ||
| 27 | |||
| 28 | #define RT2880_PCI_MEM_BASE 0x20000000 | ||
| 29 | #define RT2880_PCI_MEM_SIZE 0x10000000 | ||
| 30 | #define RT2880_PCI_IO_BASE 0x00460000 | ||
| 31 | #define RT2880_PCI_IO_SIZE 0x00010000 | ||
| 32 | |||
| 33 | #define RT2880_PCI_REG_PCICFG_ADDR 0x00 | ||
| 34 | #define RT2880_PCI_REG_PCIMSK_ADDR 0x0c | ||
| 35 | #define RT2880_PCI_REG_BAR0SETUP_ADDR 0x10 | ||
| 36 | #define RT2880_PCI_REG_IMBASEBAR0_ADDR 0x18 | ||
| 37 | #define RT2880_PCI_REG_CONFIG_ADDR 0x20 | ||
| 38 | #define RT2880_PCI_REG_CONFIG_DATA 0x24 | ||
| 39 | #define RT2880_PCI_REG_MEMBASE 0x28 | ||
| 40 | #define RT2880_PCI_REG_IOBASE 0x2c | ||
| 41 | #define RT2880_PCI_REG_ID 0x30 | ||
| 42 | #define RT2880_PCI_REG_CLASS 0x34 | ||
| 43 | #define RT2880_PCI_REG_SUBID 0x38 | ||
| 44 | #define RT2880_PCI_REG_ARBCTL 0x80 | ||
| 45 | |||
| 46 | static void __iomem *rt2880_pci_base; | ||
| 47 | static DEFINE_SPINLOCK(rt2880_pci_lock); | ||
| 48 | |||
| 49 | static u32 rt2880_pci_reg_read(u32 reg) | ||
| 50 | { | ||
| 51 | return readl(rt2880_pci_base + reg); | ||
| 52 | } | ||
| 53 | |||
| 54 | static void rt2880_pci_reg_write(u32 val, u32 reg) | ||
| 55 | { | ||
| 56 | writel(val, rt2880_pci_base + reg); | ||
| 57 | } | ||
| 58 | |||
| 59 | static inline u32 rt2880_pci_get_cfgaddr(unsigned int bus, unsigned int slot, | ||
| 60 | unsigned int func, unsigned int where) | ||
| 61 | { | ||
| 62 | return ((bus << 16) | (slot << 11) | (func << 8) | (where & 0xfc) | | ||
| 63 | 0x80000000); | ||
| 64 | } | ||
| 65 | |||
| 66 | static int rt2880_pci_config_read(struct pci_bus *bus, unsigned int devfn, | ||
| 67 | int where, int size, u32 *val) | ||
| 68 | { | ||
| 69 | unsigned long flags; | ||
| 70 | u32 address; | ||
| 71 | u32 data; | ||
| 72 | |||
| 73 | address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), | ||
| 74 | PCI_FUNC(devfn), where); | ||
| 75 | |||
| 76 | spin_lock_irqsave(&rt2880_pci_lock, flags); | ||
| 77 | rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); | ||
| 78 | data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA); | ||
| 79 | spin_unlock_irqrestore(&rt2880_pci_lock, flags); | ||
| 80 | |||
| 81 | switch (size) { | ||
| 82 | case 1: | ||
| 83 | *val = (data >> ((where & 3) << 3)) & 0xff; | ||
| 84 | break; | ||
| 85 | case 2: | ||
| 86 | *val = (data >> ((where & 3) << 3)) & 0xffff; | ||
| 87 | break; | ||
| 88 | case 4: | ||
| 89 | *val = data; | ||
| 90 | break; | ||
| 91 | } | ||
| 92 | |||
| 93 | return PCIBIOS_SUCCESSFUL; | ||
| 94 | } | ||
| 95 | |||
| 96 | static int rt2880_pci_config_write(struct pci_bus *bus, unsigned int devfn, | ||
| 97 | int where, int size, u32 val) | ||
| 98 | { | ||
| 99 | unsigned long flags; | ||
| 100 | u32 address; | ||
| 101 | u32 data; | ||
| 102 | |||
| 103 | address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), | ||
| 104 | PCI_FUNC(devfn), where); | ||
| 105 | |||
| 106 | spin_lock_irqsave(&rt2880_pci_lock, flags); | ||
| 107 | rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); | ||
| 108 | data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA); | ||
| 109 | |||
| 110 | switch (size) { | ||
| 111 | case 1: | ||
| 112 | data = (data & ~(0xff << ((where & 3) << 3))) | | ||
| 113 | (val << ((where & 3) << 3)); | ||
| 114 | break; | ||
| 115 | case 2: | ||
| 116 | data = (data & ~(0xffff << ((where & 3) << 3))) | | ||
| 117 | (val << ((where & 3) << 3)); | ||
| 118 | break; | ||
| 119 | case 4: | ||
| 120 | data = val; | ||
| 121 | break; | ||
| 122 | } | ||
| 123 | |||
| 124 | rt2880_pci_reg_write(data, RT2880_PCI_REG_CONFIG_DATA); | ||
| 125 | spin_unlock_irqrestore(&rt2880_pci_lock, flags); | ||
| 126 | |||
| 127 | return PCIBIOS_SUCCESSFUL; | ||
| 128 | } | ||
| 129 | |||
| 130 | static struct pci_ops rt2880_pci_ops = { | ||
| 131 | .read = rt2880_pci_config_read, | ||
| 132 | .write = rt2880_pci_config_write, | ||
| 133 | }; | ||
| 134 | |||
| 135 | static struct resource rt2880_pci_mem_resource = { | ||
| 136 | .name = "PCI MEM space", | ||
| 137 | .start = RT2880_PCI_MEM_BASE, | ||
| 138 | .end = RT2880_PCI_MEM_BASE + RT2880_PCI_MEM_SIZE - 1, | ||
| 139 | .flags = IORESOURCE_MEM, | ||
| 140 | }; | ||
| 141 | |||
| 142 | static struct resource rt2880_pci_io_resource = { | ||
| 143 | .name = "PCI IO space", | ||
| 144 | .start = RT2880_PCI_IO_BASE, | ||
| 145 | .end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1, | ||
| 146 | .flags = IORESOURCE_IO, | ||
| 147 | }; | ||
| 148 | |||
| 149 | static struct pci_controller rt2880_pci_controller = { | ||
| 150 | .pci_ops = &rt2880_pci_ops, | ||
| 151 | .mem_resource = &rt2880_pci_mem_resource, | ||
| 152 | .io_resource = &rt2880_pci_io_resource, | ||
| 153 | }; | ||
| 154 | |||
| 155 | static inline u32 rt2880_pci_read_u32(unsigned long reg) | ||
| 156 | { | ||
| 157 | unsigned long flags; | ||
| 158 | u32 address; | ||
| 159 | u32 ret; | ||
| 160 | |||
| 161 | address = rt2880_pci_get_cfgaddr(0, 0, 0, reg); | ||
| 162 | |||
| 163 | spin_lock_irqsave(&rt2880_pci_lock, flags); | ||
| 164 | rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); | ||
| 165 | ret = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA); | ||
| 166 | spin_unlock_irqrestore(&rt2880_pci_lock, flags); | ||
| 167 | |||
| 168 | return ret; | ||
| 169 | } | ||
| 170 | |||
| 171 | static inline void rt2880_pci_write_u32(unsigned long reg, u32 val) | ||
| 172 | { | ||
| 173 | unsigned long flags; | ||
| 174 | u32 address; | ||
| 175 | |||
| 176 | address = rt2880_pci_get_cfgaddr(0, 0, 0, reg); | ||
| 177 | |||
| 178 | spin_lock_irqsave(&rt2880_pci_lock, flags); | ||
| 179 | rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); | ||
| 180 | rt2880_pci_reg_write(val, RT2880_PCI_REG_CONFIG_DATA); | ||
| 181 | spin_unlock_irqrestore(&rt2880_pci_lock, flags); | ||
| 182 | } | ||
| 183 | |||
| 184 | int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | ||
| 185 | { | ||
| 186 | u16 cmd; | ||
| 187 | int irq = -1; | ||
| 188 | |||
| 189 | if (dev->bus->number != 0) | ||
| 190 | return irq; | ||
| 191 | |||
| 192 | switch (PCI_SLOT(dev->devfn)) { | ||
| 193 | case 0x00: | ||
| 194 | rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000); | ||
| 195 | (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0); | ||
| 196 | break; | ||
| 197 | case 0x11: | ||
| 198 | irq = RT288X_CPU_IRQ_PCI; | ||
| 199 | break; | ||
| 200 | default: | ||
| 201 | pr_err("%s:%s[%d] trying to alloc unknown pci irq\n", | ||
| 202 | __FILE__, __func__, __LINE__); | ||
| 203 | BUG(); | ||
| 204 | break; | ||
| 205 | } | ||
| 206 | |||
| 207 | pci_write_config_byte((struct pci_dev *) dev, | ||
| 208 | PCI_CACHE_LINE_SIZE, 0x14); | ||
| 209 | pci_write_config_byte((struct pci_dev *) dev, PCI_LATENCY_TIMER, 0xFF); | ||
| 210 | pci_read_config_word((struct pci_dev *) dev, PCI_COMMAND, &cmd); | ||
| 211 | cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | | ||
| 212 | PCI_COMMAND_INVALIDATE | PCI_COMMAND_FAST_BACK | | ||
| 213 | PCI_COMMAND_SERR | PCI_COMMAND_WAIT | PCI_COMMAND_PARITY; | ||
| 214 | pci_write_config_word((struct pci_dev *) dev, PCI_COMMAND, cmd); | ||
| 215 | pci_write_config_byte((struct pci_dev *) dev, PCI_INTERRUPT_LINE, | ||
| 216 | dev->irq); | ||
| 217 | return irq; | ||
| 218 | } | ||
| 219 | |||
| 220 | static int rt288x_pci_probe(struct platform_device *pdev) | ||
| 221 | { | ||
| 222 | void __iomem *io_map_base; | ||
| 223 | int i; | ||
| 224 | |||
| 225 | rt2880_pci_base = ioremap_nocache(RT2880_PCI_BASE, PAGE_SIZE); | ||
| 226 | |||
| 227 | io_map_base = ioremap(RT2880_PCI_IO_BASE, RT2880_PCI_IO_SIZE); | ||
| 228 | rt2880_pci_controller.io_map_base = (unsigned long) io_map_base; | ||
| 229 | set_io_port_base((unsigned long) io_map_base); | ||
| 230 | |||
| 231 | ioport_resource.start = RT2880_PCI_IO_BASE; | ||
| 232 | ioport_resource.end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1; | ||
| 233 | |||
| 234 | rt2880_pci_reg_write(0, RT2880_PCI_REG_PCICFG_ADDR); | ||
| 235 | for (i = 0; i < 0xfffff; i++) | ||
| 236 | ; | ||
| 237 | |||
| 238 | rt2880_pci_reg_write(0x79, RT2880_PCI_REG_ARBCTL); | ||
| 239 | rt2880_pci_reg_write(0x07FF0001, RT2880_PCI_REG_BAR0SETUP_ADDR); | ||
| 240 | rt2880_pci_reg_write(RT2880_PCI_MEM_BASE, RT2880_PCI_REG_MEMBASE); | ||
| 241 | rt2880_pci_reg_write(RT2880_PCI_IO_BASE, RT2880_PCI_REG_IOBASE); | ||
| 242 | rt2880_pci_reg_write(0x08000000, RT2880_PCI_REG_IMBASEBAR0_ADDR); | ||
| 243 | rt2880_pci_reg_write(0x08021814, RT2880_PCI_REG_ID); | ||
| 244 | rt2880_pci_reg_write(0x00800001, RT2880_PCI_REG_CLASS); | ||
| 245 | rt2880_pci_reg_write(0x28801814, RT2880_PCI_REG_SUBID); | ||
| 246 | rt2880_pci_reg_write(0x000c0000, RT2880_PCI_REG_PCIMSK_ADDR); | ||
| 247 | |||
| 248 | rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000); | ||
| 249 | (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0); | ||
| 250 | |||
| 251 | register_pci_controller(&rt2880_pci_controller); | ||
| 252 | return 0; | ||
| 253 | } | ||
| 254 | |||
| 255 | int pcibios_plat_dev_init(struct pci_dev *dev) | ||
| 256 | { | ||
| 257 | return 0; | ||
| 258 | } | ||
| 259 | |||
| 260 | static const struct of_device_id rt288x_pci_match[] = { | ||
| 261 | { .compatible = "ralink,rt288x-pci" }, | ||
| 262 | {}, | ||
| 263 | }; | ||
| 264 | MODULE_DEVICE_TABLE(of, rt288x_pci_match); | ||
| 265 | |||
| 266 | static struct platform_driver rt288x_pci_driver = { | ||
| 267 | .probe = rt288x_pci_probe, | ||
| 268 | .driver = { | ||
| 269 | .name = "rt288x-pci", | ||
| 270 | .owner = THIS_MODULE, | ||
| 271 | .of_match_table = rt288x_pci_match, | ||
| 272 | }, | ||
| 273 | }; | ||
| 274 | |||
| 275 | int __init pcibios_init(void) | ||
| 276 | { | ||
| 277 | int ret = platform_driver_register(&rt288x_pci_driver); | ||
| 278 | |||
| 279 | if (ret) | ||
| 280 | pr_info("rt288x-pci: Error registering platform driver!"); | ||
| 281 | |||
| 282 | return ret; | ||
| 283 | } | ||
| 284 | |||
| 285 | arch_initcall(pcibios_init); | ||
diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c index 72919aeef42b..0bcc0b1cfddc 100644 --- a/arch/mips/pci/pci-rt3883.c +++ b/arch/mips/pci/pci-rt3883.c | |||
| @@ -61,7 +61,6 @@ | |||
| 61 | 61 | ||
| 62 | struct rt3883_pci_controller { | 62 | struct rt3883_pci_controller { |
| 63 | void __iomem *base; | 63 | void __iomem *base; |
| 64 | spinlock_t lock; | ||
| 65 | 64 | ||
| 66 | struct device_node *intc_of_node; | 65 | struct device_node *intc_of_node; |
| 67 | struct irq_domain *irq_domain; | 66 | struct irq_domain *irq_domain; |
| @@ -111,10 +110,8 @@ static u32 rt3883_pci_read_cfg32(struct rt3883_pci_controller *rpc, | |||
| 111 | 110 | ||
| 112 | address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); | 111 | address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); |
| 113 | 112 | ||
| 114 | spin_lock_irqsave(&rpc->lock, flags); | ||
| 115 | rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); | 113 | rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); |
| 116 | ret = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); | 114 | ret = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); |
| 117 | spin_unlock_irqrestore(&rpc->lock, flags); | ||
| 118 | 115 | ||
| 119 | return ret; | 116 | return ret; |
| 120 | } | 117 | } |
| @@ -128,10 +125,8 @@ static void rt3883_pci_write_cfg32(struct rt3883_pci_controller *rpc, | |||
| 128 | 125 | ||
| 129 | address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); | 126 | address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); |
| 130 | 127 | ||
| 131 | spin_lock_irqsave(&rpc->lock, flags); | ||
| 132 | rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); | 128 | rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); |
| 133 | rt3883_pci_w32(rpc, val, RT3883_PCI_REG_CFGDATA); | 129 | rt3883_pci_w32(rpc, val, RT3883_PCI_REG_CFGDATA); |
| 134 | spin_unlock_irqrestore(&rpc->lock, flags); | ||
| 135 | } | 130 | } |
| 136 | 131 | ||
| 137 | static void rt3883_pci_irq_handler(unsigned int irq, struct irq_desc *desc) | 132 | static void rt3883_pci_irq_handler(unsigned int irq, struct irq_desc *desc) |
| @@ -252,10 +247,8 @@ static int rt3883_pci_config_read(struct pci_bus *bus, unsigned int devfn, | |||
| 252 | address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), | 247 | address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), |
| 253 | PCI_FUNC(devfn), where); | 248 | PCI_FUNC(devfn), where); |
| 254 | 249 | ||
| 255 | spin_lock_irqsave(&rpc->lock, flags); | ||
| 256 | rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); | 250 | rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); |
| 257 | data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); | 251 | data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); |
| 258 | spin_unlock_irqrestore(&rpc->lock, flags); | ||
| 259 | 252 | ||
| 260 | switch (size) { | 253 | switch (size) { |
| 261 | case 1: | 254 | case 1: |
| @@ -288,7 +281,6 @@ static int rt3883_pci_config_write(struct pci_bus *bus, unsigned int devfn, | |||
| 288 | address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), | 281 | address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), |
| 289 | PCI_FUNC(devfn), where); | 282 | PCI_FUNC(devfn), where); |
| 290 | 283 | ||
| 291 | spin_lock_irqsave(&rpc->lock, flags); | ||
| 292 | rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); | 284 | rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); |
| 293 | data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); | 285 | data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); |
| 294 | 286 | ||
| @@ -307,7 +299,6 @@ static int rt3883_pci_config_write(struct pci_bus *bus, unsigned int devfn, | |||
| 307 | } | 299 | } |
| 308 | 300 | ||
| 309 | rt3883_pci_w32(rpc, data, RT3883_PCI_REG_CFGDATA); | 301 | rt3883_pci_w32(rpc, data, RT3883_PCI_REG_CFGDATA); |
| 310 | spin_unlock_irqrestore(&rpc->lock, flags); | ||
| 311 | 302 | ||
| 312 | return PCIBIOS_SUCCESSFUL; | 303 | return PCIBIOS_SUCCESSFUL; |
| 313 | } | 304 | } |
diff --git a/arch/mips/pci/pci-tx4939.c b/arch/mips/pci/pci-tx4939.c index c10fbf2a19dc..cd8ed09c4f53 100644 --- a/arch/mips/pci/pci-tx4939.c +++ b/arch/mips/pci/pci-tx4939.c | |||
| @@ -103,5 +103,5 @@ void __init tx4939_setup_pcierr_irq(void) | |||
| 103 | tx4927_pcierr_interrupt, | 103 | tx4927_pcierr_interrupt, |
| 104 | 0, "PCI error", | 104 | 0, "PCI error", |
| 105 | (void *)TX4939_PCIC_REG)) | 105 | (void *)TX4939_PCIC_REG)) |
| 106 | pr_warning("Failed to request irq for PCIERR\n"); | 106 | pr_warn("Failed to request irq for PCIERR\n"); |
| 107 | } | 107 | } |
diff --git a/arch/mips/pmcs-msp71xx/msp_prom.c b/arch/mips/pmcs-msp71xx/msp_prom.c index 1c9897531660..ef620a4c82a5 100644 --- a/arch/mips/pmcs-msp71xx/msp_prom.c +++ b/arch/mips/pmcs-msp71xx/msp_prom.c | |||
| @@ -295,7 +295,7 @@ char *prom_getenv(char *env_name) | |||
| 295 | 295 | ||
| 296 | while (*var) { | 296 | while (*var) { |
| 297 | if (strncmp(env_name, *var, i) == 0) { | 297 | if (strncmp(env_name, *var, i) == 0) { |
| 298 | return (*var + strlen(env_name) + 1); | 298 | return *var + strlen(env_name) + 1; |
| 299 | } | 299 | } |
| 300 | var++; | 300 | var++; |
| 301 | } | 301 | } |
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig index 77e8a9620e18..b1c52ca580f9 100644 --- a/arch/mips/ralink/Kconfig +++ b/arch/mips/ralink/Kconfig | |||
| @@ -16,6 +16,7 @@ choice | |||
| 16 | config SOC_RT288X | 16 | config SOC_RT288X |
| 17 | bool "RT288x" | 17 | bool "RT288x" |
| 18 | select MIPS_L1_CACHE_SHIFT_4 | 18 | select MIPS_L1_CACHE_SHIFT_4 |
| 19 | select HW_HAS_PCI | ||
| 19 | 20 | ||
| 20 | config SOC_RT305X | 21 | config SOC_RT305X |
| 21 | bool "RT305x" | 22 | bool "RT305x" |
| @@ -26,7 +27,7 @@ choice | |||
| 26 | select HW_HAS_PCI | 27 | select HW_HAS_PCI |
| 27 | 28 | ||
| 28 | config SOC_MT7620 | 29 | config SOC_MT7620 |
| 29 | bool "MT7620" | 30 | bool "MT7620/8" |
| 30 | 31 | ||
| 31 | endchoice | 32 | endchoice |
| 32 | 33 | ||
diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile index 2c09c8aa0ae2..a6c9d0061326 100644 --- a/arch/mips/ralink/Makefile +++ b/arch/mips/ralink/Makefile | |||
| @@ -10,9 +10,13 @@ obj-y := prom.o of.o reset.o clk.o irq.o timer.o | |||
| 10 | 10 | ||
| 11 | obj-$(CONFIG_CLKEVT_RT3352) += cevt-rt3352.o | 11 | obj-$(CONFIG_CLKEVT_RT3352) += cevt-rt3352.o |
| 12 | 12 | ||
| 13 | obj-$(CONFIG_RALINK_ILL_ACC) += ill_acc.o | ||
| 14 | |||
| 13 | obj-$(CONFIG_SOC_RT288X) += rt288x.o | 15 | obj-$(CONFIG_SOC_RT288X) += rt288x.o |
| 14 | obj-$(CONFIG_SOC_RT305X) += rt305x.o | 16 | obj-$(CONFIG_SOC_RT305X) += rt305x.o |
| 15 | obj-$(CONFIG_SOC_RT3883) += rt3883.o | 17 | obj-$(CONFIG_SOC_RT3883) += rt3883.o |
| 16 | obj-$(CONFIG_SOC_MT7620) += mt7620.o | 18 | obj-$(CONFIG_SOC_MT7620) += mt7620.o |
| 17 | 19 | ||
| 18 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 20 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
| 21 | |||
| 22 | obj-$(CONFIG_DEBUG_FS) += bootrom.o | ||
diff --git a/arch/mips/ralink/bootrom.c b/arch/mips/ralink/bootrom.c new file mode 100644 index 000000000000..5403468394fb --- /dev/null +++ b/arch/mips/ralink/bootrom.c | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/debugfs.h> | ||
| 10 | #include <linux/seq_file.h> | ||
| 11 | |||
| 12 | #define BOOTROM_OFFSET 0x10118000 | ||
| 13 | #define BOOTROM_SIZE 0x8000 | ||
| 14 | |||
| 15 | static void __iomem *membase = (void __iomem *) KSEG1ADDR(BOOTROM_OFFSET); | ||
| 16 | |||
| 17 | static int bootrom_show(struct seq_file *s, void *unused) | ||
| 18 | { | ||
| 19 | seq_write(s, membase, BOOTROM_SIZE); | ||
| 20 | |||
| 21 | return 0; | ||
| 22 | } | ||
| 23 | |||
| 24 | static int bootrom_open(struct inode *inode, struct file *file) | ||
| 25 | { | ||
| 26 | return single_open(file, bootrom_show, NULL); | ||
| 27 | } | ||
| 28 | |||
| 29 | static const struct file_operations bootrom_file_ops = { | ||
| 30 | .open = bootrom_open, | ||
| 31 | .read = seq_read, | ||
| 32 | .llseek = seq_lseek, | ||
| 33 | .release = single_release, | ||
| 34 | }; | ||
| 35 | |||
| 36 | static int bootrom_setup(void) | ||
| 37 | { | ||
| 38 | if (!debugfs_create_file("bootrom", 0444, | ||
| 39 | NULL, NULL, &bootrom_file_ops)) { | ||
| 40 | pr_err("Failed to create bootrom debugfs file\n"); | ||
| 41 | |||
| 42 | return -EINVAL; | ||
| 43 | } | ||
| 44 | |||
| 45 | return 0; | ||
| 46 | } | ||
| 47 | |||
| 48 | postcore_initcall(bootrom_setup); | ||
diff --git a/arch/mips/ralink/clk.c b/arch/mips/ralink/clk.c index 5d0983d47161..feb5a9bf98b4 100644 --- a/arch/mips/ralink/clk.c +++ b/arch/mips/ralink/clk.c | |||
| @@ -56,6 +56,12 @@ unsigned long clk_get_rate(struct clk *clk) | |||
| 56 | } | 56 | } |
| 57 | EXPORT_SYMBOL_GPL(clk_get_rate); | 57 | EXPORT_SYMBOL_GPL(clk_get_rate); |
| 58 | 58 | ||
| 59 | int clk_set_rate(struct clk *clk, unsigned long rate) | ||
| 60 | { | ||
| 61 | return -1; | ||
| 62 | } | ||
| 63 | EXPORT_SYMBOL_GPL(clk_set_rate); | ||
| 64 | |||
| 59 | void __init plat_time_init(void) | 65 | void __init plat_time_init(void) |
| 60 | { | 66 | { |
| 61 | struct clk *clk; | 67 | struct clk *clk; |
diff --git a/arch/mips/ralink/common.h b/arch/mips/ralink/common.h index 42dfd6100a2d..8e7d8e618fb9 100644 --- a/arch/mips/ralink/common.h +++ b/arch/mips/ralink/common.h | |||
| @@ -11,25 +11,6 @@ | |||
| 11 | 11 | ||
| 12 | #define RAMIPS_SYS_TYPE_LEN 32 | 12 | #define RAMIPS_SYS_TYPE_LEN 32 |
| 13 | 13 | ||
| 14 | struct ralink_pinmux_grp { | ||
| 15 | const char *name; | ||
| 16 | u32 mask; | ||
| 17 | int gpio_first; | ||
| 18 | int gpio_last; | ||
| 19 | }; | ||
| 20 | |||
| 21 | struct ralink_pinmux { | ||
| 22 | struct ralink_pinmux_grp *mode; | ||
| 23 | struct ralink_pinmux_grp *uart; | ||
| 24 | int uart_shift; | ||
| 25 | u32 uart_mask; | ||
| 26 | void (*wdt_reset)(void); | ||
| 27 | struct ralink_pinmux_grp *pci; | ||
| 28 | int pci_shift; | ||
| 29 | u32 pci_mask; | ||
| 30 | }; | ||
| 31 | extern struct ralink_pinmux rt_gpio_pinmux; | ||
| 32 | |||
| 33 | struct ralink_soc_info { | 14 | struct ralink_soc_info { |
| 34 | unsigned char sys_type[RAMIPS_SYS_TYPE_LEN]; | 15 | unsigned char sys_type[RAMIPS_SYS_TYPE_LEN]; |
| 35 | unsigned char *compatible; | 16 | unsigned char *compatible; |
diff --git a/arch/mips/ralink/early_printk.c b/arch/mips/ralink/early_printk.c index b46d0419d09b..255d695ec8c6 100644 --- a/arch/mips/ralink/early_printk.c +++ b/arch/mips/ralink/early_printk.c | |||
| @@ -12,21 +12,24 @@ | |||
| 12 | #include <asm/addrspace.h> | 12 | #include <asm/addrspace.h> |
| 13 | 13 | ||
| 14 | #ifdef CONFIG_SOC_RT288X | 14 | #ifdef CONFIG_SOC_RT288X |
| 15 | #define EARLY_UART_BASE 0x300c00 | 15 | #define EARLY_UART_BASE 0x300c00 |
| 16 | #define CHIPID_BASE 0x300004 | ||
| 17 | #elif defined(CONFIG_SOC_MT7621) | ||
| 18 | #define EARLY_UART_BASE 0x1E000c00 | ||
| 19 | #define CHIPID_BASE 0x1E000004 | ||
| 16 | #else | 20 | #else |
| 17 | #define EARLY_UART_BASE 0x10000c00 | 21 | #define EARLY_UART_BASE 0x10000c00 |
| 22 | #define CHIPID_BASE 0x10000004 | ||
| 18 | #endif | 23 | #endif |
| 19 | 24 | ||
| 20 | #define UART_REG_RX 0x00 | 25 | #define MT7628_CHIP_NAME1 0x20203832 |
| 21 | #define UART_REG_TX 0x04 | 26 | |
| 22 | #define UART_REG_IER 0x08 | 27 | #define UART_REG_TX 0x04 |
| 23 | #define UART_REG_IIR 0x0c | 28 | #define UART_REG_LSR 0x14 |
| 24 | #define UART_REG_FCR 0x10 | 29 | #define UART_REG_LSR_RT2880 0x1c |
| 25 | #define UART_REG_LCR 0x14 | ||
| 26 | #define UART_REG_MCR 0x18 | ||
| 27 | #define UART_REG_LSR 0x1c | ||
| 28 | 30 | ||
| 29 | static __iomem void *uart_membase = (__iomem void *) KSEG1ADDR(EARLY_UART_BASE); | 31 | static __iomem void *uart_membase = (__iomem void *) KSEG1ADDR(EARLY_UART_BASE); |
| 32 | static __iomem void *chipid_membase = (__iomem void *) KSEG1ADDR(CHIPID_BASE); | ||
| 30 | 33 | ||
| 31 | static inline void uart_w32(u32 val, unsigned reg) | 34 | static inline void uart_w32(u32 val, unsigned reg) |
| 32 | { | 35 | { |
| @@ -38,11 +41,23 @@ static inline u32 uart_r32(unsigned reg) | |||
| 38 | return __raw_readl(uart_membase + reg); | 41 | return __raw_readl(uart_membase + reg); |
| 39 | } | 42 | } |
| 40 | 43 | ||
| 44 | static inline int soc_is_mt7628(void) | ||
| 45 | { | ||
| 46 | return IS_ENABLED(CONFIG_SOC_MT7620) && | ||
| 47 | (__raw_readl(chipid_membase) == MT7628_CHIP_NAME1); | ||
| 48 | } | ||
| 49 | |||
| 41 | void prom_putchar(unsigned char ch) | 50 | void prom_putchar(unsigned char ch) |
| 42 | { | 51 | { |
| 43 | while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0) | 52 | if (IS_ENABLED(CONFIG_SOC_MT7621) || soc_is_mt7628()) { |
| 44 | ; | 53 | uart_w32(ch, UART_TX); |
| 45 | uart_w32(ch, UART_REG_TX); | 54 | while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0) |
| 46 | while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0) | 55 | ; |
| 47 | ; | 56 | } else { |
| 57 | while ((uart_r32(UART_REG_LSR_RT2880) & UART_LSR_THRE) == 0) | ||
| 58 | ; | ||
| 59 | uart_w32(ch, UART_REG_TX); | ||
| 60 | while ((uart_r32(UART_REG_LSR_RT2880) & UART_LSR_THRE) == 0) | ||
| 61 | ; | ||
| 62 | } | ||
| 48 | } | 63 | } |
diff --git a/arch/mips/ralink/ill_acc.c b/arch/mips/ralink/ill_acc.c new file mode 100644 index 000000000000..e20b02e3ae28 --- /dev/null +++ b/arch/mips/ralink/ill_acc.c | |||
| @@ -0,0 +1,87 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify it | ||
| 3 | * under the terms of the GNU General Public License version 2 as published | ||
| 4 | * by the Free Software Foundation. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/interrupt.h> | ||
| 10 | #include <linux/of_platform.h> | ||
| 11 | #include <linux/of_irq.h> | ||
| 12 | |||
| 13 | #include <asm/mach-ralink/ralink_regs.h> | ||
| 14 | |||
| 15 | #define REG_ILL_ACC_ADDR 0x10 | ||
| 16 | #define REG_ILL_ACC_TYPE 0x14 | ||
| 17 | |||
| 18 | #define ILL_INT_STATUS BIT(31) | ||
| 19 | #define ILL_ACC_WRITE BIT(30) | ||
| 20 | #define ILL_ACC_LEN_M 0xff | ||
| 21 | #define ILL_ACC_OFF_M 0xf | ||
| 22 | #define ILL_ACC_OFF_S 16 | ||
| 23 | #define ILL_ACC_ID_M 0x7 | ||
| 24 | #define ILL_ACC_ID_S 8 | ||
| 25 | |||
| 26 | #define DRV_NAME "ill_acc" | ||
| 27 | |||
| 28 | static const char * const ill_acc_ids[] = { | ||
| 29 | "cpu", "dma", "ppe", "pdma rx", "pdma tx", "pci/e", "wmac", "usb", | ||
| 30 | }; | ||
| 31 | |||
| 32 | static irqreturn_t ill_acc_irq_handler(int irq, void *_priv) | ||
| 33 | { | ||
| 34 | struct device *dev = (struct device *) _priv; | ||
| 35 | u32 addr = rt_memc_r32(REG_ILL_ACC_ADDR); | ||
| 36 | u32 type = rt_memc_r32(REG_ILL_ACC_TYPE); | ||
| 37 | |||
| 38 | dev_err(dev, "illegal %s access from %s - addr:0x%08x offset:%d len:%d\n", | ||
| 39 | (type & ILL_ACC_WRITE) ? ("write") : ("read"), | ||
| 40 | ill_acc_ids[(type >> ILL_ACC_ID_S) & ILL_ACC_ID_M], | ||
| 41 | addr, (type >> ILL_ACC_OFF_S) & ILL_ACC_OFF_M, | ||
| 42 | type & ILL_ACC_LEN_M); | ||
| 43 | |||
| 44 | rt_memc_w32(REG_ILL_ACC_TYPE, REG_ILL_ACC_TYPE); | ||
| 45 | |||
| 46 | return IRQ_HANDLED; | ||
| 47 | } | ||
| 48 | |||
| 49 | static int __init ill_acc_of_setup(void) | ||
| 50 | { | ||
| 51 | struct platform_device *pdev; | ||
| 52 | struct device_node *np; | ||
| 53 | int irq; | ||
| 54 | |||
| 55 | /* somehow this driver breaks on RT5350 */ | ||
| 56 | if (of_machine_is_compatible("ralink,rt5350-soc")) | ||
| 57 | return -EINVAL; | ||
| 58 | |||
| 59 | np = of_find_compatible_node(NULL, NULL, "ralink,rt3050-memc"); | ||
| 60 | if (!np) | ||
| 61 | return -EINVAL; | ||
| 62 | |||
| 63 | pdev = of_find_device_by_node(np); | ||
| 64 | if (!pdev) { | ||
| 65 | pr_err("%s: failed to lookup pdev\n", np->name); | ||
| 66 | return -EINVAL; | ||
| 67 | } | ||
| 68 | |||
| 69 | irq = irq_of_parse_and_map(np, 0); | ||
| 70 | if (!irq) { | ||
| 71 | dev_err(&pdev->dev, "failed to get irq\n"); | ||
| 72 | return -EINVAL; | ||
| 73 | } | ||
| 74 | |||
| 75 | if (request_irq(irq, ill_acc_irq_handler, 0, "ill_acc", &pdev->dev)) { | ||
| 76 | dev_err(&pdev->dev, "failed to request irq\n"); | ||
| 77 | return -EINVAL; | ||
| 78 | } | ||
| 79 | |||
| 80 | rt_memc_w32(ILL_INT_STATUS, REG_ILL_ACC_TYPE); | ||
| 81 | |||
| 82 | dev_info(&pdev->dev, "irq registered\n"); | ||
| 83 | |||
| 84 | return 0; | ||
| 85 | } | ||
| 86 | |||
| 87 | arch_initcall(ill_acc_of_setup); | ||
diff --git a/arch/mips/ralink/irq.c b/arch/mips/ralink/irq.c index 781b3d14a489..7cf91b92e9d1 100644 --- a/arch/mips/ralink/irq.c +++ b/arch/mips/ralink/irq.c | |||
| @@ -20,14 +20,6 @@ | |||
| 20 | 20 | ||
| 21 | #include "common.h" | 21 | #include "common.h" |
| 22 | 22 | ||
| 23 | /* INTC register offsets */ | ||
| 24 | #define INTC_REG_STATUS0 0x00 | ||
| 25 | #define INTC_REG_STATUS1 0x04 | ||
| 26 | #define INTC_REG_TYPE 0x20 | ||
| 27 | #define INTC_REG_RAW_STATUS 0x30 | ||
| 28 | #define INTC_REG_ENABLE 0x34 | ||
| 29 | #define INTC_REG_DISABLE 0x38 | ||
| 30 | |||
| 31 | #define INTC_INT_GLOBAL BIT(31) | 23 | #define INTC_INT_GLOBAL BIT(31) |
| 32 | 24 | ||
| 33 | #define RALINK_CPU_IRQ_INTC (MIPS_CPU_IRQ_BASE + 2) | 25 | #define RALINK_CPU_IRQ_INTC (MIPS_CPU_IRQ_BASE + 2) |
| @@ -44,16 +36,36 @@ | |||
| 44 | 36 | ||
| 45 | #define RALINK_INTC_IRQ_PERFC (RALINK_INTC_IRQ_BASE + 9) | 37 | #define RALINK_INTC_IRQ_PERFC (RALINK_INTC_IRQ_BASE + 9) |
| 46 | 38 | ||
| 39 | enum rt_intc_regs_enum { | ||
| 40 | INTC_REG_STATUS0 = 0, | ||
| 41 | INTC_REG_STATUS1, | ||
| 42 | INTC_REG_TYPE, | ||
| 43 | INTC_REG_RAW_STATUS, | ||
| 44 | INTC_REG_ENABLE, | ||
| 45 | INTC_REG_DISABLE, | ||
| 46 | }; | ||
| 47 | |||
| 48 | static u32 rt_intc_regs[] = { | ||
| 49 | [INTC_REG_STATUS0] = 0x00, | ||
| 50 | [INTC_REG_STATUS1] = 0x04, | ||
| 51 | [INTC_REG_TYPE] = 0x20, | ||
| 52 | [INTC_REG_RAW_STATUS] = 0x30, | ||
| 53 | [INTC_REG_ENABLE] = 0x34, | ||
| 54 | [INTC_REG_DISABLE] = 0x38, | ||
| 55 | }; | ||
| 56 | |||
| 47 | static void __iomem *rt_intc_membase; | 57 | static void __iomem *rt_intc_membase; |
| 48 | 58 | ||
| 59 | static int rt_perfcount_irq; | ||
| 60 | |||
| 49 | static inline void rt_intc_w32(u32 val, unsigned reg) | 61 | static inline void rt_intc_w32(u32 val, unsigned reg) |
| 50 | { | 62 | { |
| 51 | __raw_writel(val, rt_intc_membase + reg); | 63 | __raw_writel(val, rt_intc_membase + rt_intc_regs[reg]); |
| 52 | } | 64 | } |
| 53 | 65 | ||
| 54 | static inline u32 rt_intc_r32(unsigned reg) | 66 | static inline u32 rt_intc_r32(unsigned reg) |
| 55 | { | 67 | { |
| 56 | return __raw_readl(rt_intc_membase + reg); | 68 | return __raw_readl(rt_intc_membase + rt_intc_regs[reg]); |
| 57 | } | 69 | } |
| 58 | 70 | ||
| 59 | static void ralink_intc_irq_unmask(struct irq_data *d) | 71 | static void ralink_intc_irq_unmask(struct irq_data *d) |
| @@ -73,6 +85,11 @@ static struct irq_chip ralink_intc_irq_chip = { | |||
| 73 | .irq_mask_ack = ralink_intc_irq_mask, | 85 | .irq_mask_ack = ralink_intc_irq_mask, |
| 74 | }; | 86 | }; |
| 75 | 87 | ||
| 88 | int get_c0_perfcount_int(void) | ||
| 89 | { | ||
| 90 | return rt_perfcount_irq; | ||
| 91 | } | ||
| 92 | |||
| 76 | unsigned int get_c0_compare_int(void) | 93 | unsigned int get_c0_compare_int(void) |
| 77 | { | 94 | { |
| 78 | return CP0_LEGACY_COMPARE_IRQ; | 95 | return CP0_LEGACY_COMPARE_IRQ; |
| @@ -134,6 +151,10 @@ static int __init intc_of_init(struct device_node *node, | |||
| 134 | struct irq_domain *domain; | 151 | struct irq_domain *domain; |
| 135 | int irq; | 152 | int irq; |
| 136 | 153 | ||
| 154 | if (!of_property_read_u32_array(node, "ralink,intc-registers", | ||
| 155 | rt_intc_regs, 6)) | ||
| 156 | pr_info("intc: using register map from devicetree\n"); | ||
| 157 | |||
| 137 | irq = irq_of_parse_and_map(node, 0); | 158 | irq = irq_of_parse_and_map(node, 0); |
| 138 | if (!irq) | 159 | if (!irq) |
| 139 | panic("Failed to get INTC IRQ"); | 160 | panic("Failed to get INTC IRQ"); |
| @@ -167,13 +188,13 @@ static int __init intc_of_init(struct device_node *node, | |||
| 167 | irq_set_handler_data(irq, domain); | 188 | irq_set_handler_data(irq, domain); |
| 168 | 189 | ||
| 169 | /* tell the kernel which irq is used for performance monitoring */ | 190 | /* tell the kernel which irq is used for performance monitoring */ |
| 170 | cp0_perfcount_irq = irq_create_mapping(domain, 9); | 191 | rt_perfcount_irq = irq_create_mapping(domain, 9); |
| 171 | 192 | ||
| 172 | return 0; | 193 | return 0; |
| 173 | } | 194 | } |
| 174 | 195 | ||
| 175 | static struct of_device_id __initdata of_irq_ids[] = { | 196 | static struct of_device_id __initdata of_irq_ids[] = { |
| 176 | { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_intc_init }, | 197 | { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_irq_of_init }, |
| 177 | { .compatible = "ralink,rt2880-intc", .data = intc_of_init }, | 198 | { .compatible = "ralink,rt2880-intc", .data = intc_of_init }, |
| 178 | {}, | 199 | {}, |
| 179 | }; | 200 | }; |
diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c index a3ad56c2372d..2ea5ff6dc22e 100644 --- a/arch/mips/ralink/mt7620.c +++ b/arch/mips/ralink/mt7620.c | |||
| @@ -17,124 +17,214 @@ | |||
| 17 | #include <asm/mipsregs.h> | 17 | #include <asm/mipsregs.h> |
| 18 | #include <asm/mach-ralink/ralink_regs.h> | 18 | #include <asm/mach-ralink/ralink_regs.h> |
| 19 | #include <asm/mach-ralink/mt7620.h> | 19 | #include <asm/mach-ralink/mt7620.h> |
| 20 | #include <asm/mach-ralink/pinmux.h> | ||
| 20 | 21 | ||
| 21 | #include "common.h" | 22 | #include "common.h" |
| 22 | 23 | ||
| 24 | /* analog */ | ||
| 25 | #define PMU0_CFG 0x88 | ||
| 26 | #define PMU_SW_SET BIT(28) | ||
| 27 | #define A_DCDC_EN BIT(24) | ||
| 28 | #define A_SSC_PERI BIT(19) | ||
| 29 | #define A_SSC_GEN BIT(18) | ||
| 30 | #define A_SSC_M 0x3 | ||
| 31 | #define A_SSC_S 16 | ||
| 32 | #define A_DLY_M 0x7 | ||
| 33 | #define A_DLY_S 8 | ||
| 34 | #define A_VTUNE_M 0xff | ||
| 35 | |||
| 36 | /* digital */ | ||
| 37 | #define PMU1_CFG 0x8C | ||
| 38 | #define DIG_SW_SEL BIT(25) | ||
| 39 | |||
| 40 | /* is this a MT7620 or a MT7628 */ | ||
| 41 | enum mt762x_soc_type mt762x_soc; | ||
| 42 | |||
| 23 | /* does the board have sdram or ddram */ | 43 | /* does the board have sdram or ddram */ |
| 24 | static int dram_type; | 44 | static int dram_type; |
| 25 | 45 | ||
| 26 | static struct ralink_pinmux_grp mode_mux[] = { | 46 | static struct rt2880_pmx_func i2c_grp[] = { FUNC("i2c", 0, 1, 2) }; |
| 27 | { | 47 | static struct rt2880_pmx_func spi_grp[] = { FUNC("spi", 0, 3, 4) }; |
| 28 | .name = "i2c", | 48 | static struct rt2880_pmx_func uartlite_grp[] = { FUNC("uartlite", 0, 15, 2) }; |
| 29 | .mask = MT7620_GPIO_MODE_I2C, | 49 | static struct rt2880_pmx_func mdio_grp[] = { FUNC("mdio", 0, 22, 2) }; |
| 30 | .gpio_first = 1, | 50 | static struct rt2880_pmx_func rgmii1_grp[] = { FUNC("rgmii1", 0, 24, 12) }; |
| 31 | .gpio_last = 2, | 51 | static struct rt2880_pmx_func refclk_grp[] = { FUNC("spi refclk", 0, 37, 3) }; |
| 32 | }, { | 52 | static struct rt2880_pmx_func ephy_grp[] = { FUNC("ephy", 0, 40, 5) }; |
| 33 | .name = "spi", | 53 | static struct rt2880_pmx_func rgmii2_grp[] = { FUNC("rgmii2", 0, 60, 12) }; |
| 34 | .mask = MT7620_GPIO_MODE_SPI, | 54 | static struct rt2880_pmx_func wled_grp[] = { FUNC("wled", 0, 72, 1) }; |
| 35 | .gpio_first = 3, | 55 | static struct rt2880_pmx_func pa_grp[] = { FUNC("pa", 0, 18, 4) }; |
| 36 | .gpio_last = 6, | 56 | static struct rt2880_pmx_func uartf_grp[] = { |
| 37 | }, { | 57 | FUNC("uartf", MT7620_GPIO_MODE_UARTF, 7, 8), |
| 38 | .name = "uartlite", | 58 | FUNC("pcm uartf", MT7620_GPIO_MODE_PCM_UARTF, 7, 8), |
| 39 | .mask = MT7620_GPIO_MODE_UART1, | 59 | FUNC("pcm i2s", MT7620_GPIO_MODE_PCM_I2S, 7, 8), |
| 40 | .gpio_first = 15, | 60 | FUNC("i2s uartf", MT7620_GPIO_MODE_I2S_UARTF, 7, 8), |
| 41 | .gpio_last = 16, | 61 | FUNC("pcm gpio", MT7620_GPIO_MODE_PCM_GPIO, 11, 4), |
| 42 | }, { | 62 | FUNC("gpio uartf", MT7620_GPIO_MODE_GPIO_UARTF, 7, 4), |
| 43 | .name = "wdt", | 63 | FUNC("gpio i2s", MT7620_GPIO_MODE_GPIO_I2S, 7, 4), |
| 44 | .mask = MT7620_GPIO_MODE_WDT, | 64 | }; |
| 45 | .gpio_first = 17, | 65 | static struct rt2880_pmx_func wdt_grp[] = { |
| 46 | .gpio_last = 17, | 66 | FUNC("wdt rst", 0, 17, 1), |
| 47 | }, { | 67 | FUNC("wdt refclk", 0, 17, 1), |
| 48 | .name = "mdio", | 68 | }; |
| 49 | .mask = MT7620_GPIO_MODE_MDIO, | 69 | static struct rt2880_pmx_func pcie_rst_grp[] = { |
| 50 | .gpio_first = 22, | 70 | FUNC("pcie rst", MT7620_GPIO_MODE_PCIE_RST, 36, 1), |
| 51 | .gpio_last = 23, | 71 | FUNC("pcie refclk", MT7620_GPIO_MODE_PCIE_REF, 36, 1) |
| 52 | }, { | 72 | }; |
| 53 | .name = "rgmii1", | 73 | static struct rt2880_pmx_func nd_sd_grp[] = { |
| 54 | .mask = MT7620_GPIO_MODE_RGMII1, | 74 | FUNC("nand", MT7620_GPIO_MODE_NAND, 45, 15), |
| 55 | .gpio_first = 24, | 75 | FUNC("sd", MT7620_GPIO_MODE_SD, 45, 15) |
| 56 | .gpio_last = 35, | 76 | }; |
| 57 | }, { | 77 | |
| 58 | .name = "spi refclk", | 78 | static struct rt2880_pmx_group mt7620a_pinmux_data[] = { |
| 59 | .mask = MT7620_GPIO_MODE_SPI_REF_CLK, | 79 | GRP("i2c", i2c_grp, 1, MT7620_GPIO_MODE_I2C), |
| 60 | .gpio_first = 37, | 80 | GRP("uartf", uartf_grp, MT7620_GPIO_MODE_UART0_MASK, |
| 61 | .gpio_last = 39, | 81 | MT7620_GPIO_MODE_UART0_SHIFT), |
| 62 | }, { | 82 | GRP("spi", spi_grp, 1, MT7620_GPIO_MODE_SPI), |
| 63 | .name = "jtag", | 83 | GRP("uartlite", uartlite_grp, 1, MT7620_GPIO_MODE_UART1), |
| 64 | .mask = MT7620_GPIO_MODE_JTAG, | 84 | GRP_G("wdt", wdt_grp, MT7620_GPIO_MODE_WDT_MASK, |
| 65 | .gpio_first = 40, | 85 | MT7620_GPIO_MODE_WDT_GPIO, MT7620_GPIO_MODE_WDT_SHIFT), |
| 66 | .gpio_last = 44, | 86 | GRP("mdio", mdio_grp, 1, MT7620_GPIO_MODE_MDIO), |
| 67 | }, { | 87 | GRP("rgmii1", rgmii1_grp, 1, MT7620_GPIO_MODE_RGMII1), |
| 68 | /* shared lines with jtag */ | 88 | GRP("spi refclk", refclk_grp, 1, MT7620_GPIO_MODE_SPI_REF_CLK), |
| 69 | .name = "ephy", | 89 | GRP_G("pcie", pcie_rst_grp, MT7620_GPIO_MODE_PCIE_MASK, |
| 70 | .mask = MT7620_GPIO_MODE_EPHY, | 90 | MT7620_GPIO_MODE_PCIE_GPIO, MT7620_GPIO_MODE_PCIE_SHIFT), |
| 71 | .gpio_first = 40, | 91 | GRP_G("nd_sd", nd_sd_grp, MT7620_GPIO_MODE_ND_SD_MASK, |
| 72 | .gpio_last = 44, | 92 | MT7620_GPIO_MODE_ND_SD_GPIO, MT7620_GPIO_MODE_ND_SD_SHIFT), |
| 73 | }, { | 93 | GRP("rgmii2", rgmii2_grp, 1, MT7620_GPIO_MODE_RGMII2), |
| 74 | .name = "nand", | 94 | GRP("wled", wled_grp, 1, MT7620_GPIO_MODE_WLED), |
| 75 | .mask = MT7620_GPIO_MODE_JTAG, | 95 | GRP("ephy", ephy_grp, 1, MT7620_GPIO_MODE_EPHY), |
| 76 | .gpio_first = 45, | 96 | GRP("pa", pa_grp, 1, MT7620_GPIO_MODE_PA), |
| 77 | .gpio_last = 59, | 97 | { 0 } |
| 78 | }, { | 98 | }; |
| 79 | .name = "rgmii2", | 99 | |
| 80 | .mask = MT7620_GPIO_MODE_RGMII2, | 100 | static struct rt2880_pmx_func pwm1_grp_mt7628[] = { |
| 81 | .gpio_first = 60, | 101 | FUNC("sdcx", 3, 19, 1), |
| 82 | .gpio_last = 71, | 102 | FUNC("utif", 2, 19, 1), |
| 83 | }, { | 103 | FUNC("gpio", 1, 19, 1), |
| 84 | .name = "wled", | 104 | FUNC("pwm", 0, 19, 1), |
| 85 | .mask = MT7620_GPIO_MODE_WLED, | 105 | }; |
| 86 | .gpio_first = 72, | 106 | |
| 87 | .gpio_last = 72, | 107 | static struct rt2880_pmx_func pwm0_grp_mt7628[] = { |
| 88 | }, {0} | 108 | FUNC("sdcx", 3, 18, 1), |
| 109 | FUNC("utif", 2, 18, 1), | ||
| 110 | FUNC("gpio", 1, 18, 1), | ||
| 111 | FUNC("pwm", 0, 18, 1), | ||
| 112 | }; | ||
| 113 | |||
| 114 | static struct rt2880_pmx_func uart2_grp_mt7628[] = { | ||
| 115 | FUNC("sdcx", 3, 20, 2), | ||
| 116 | FUNC("pwm", 2, 20, 2), | ||
| 117 | FUNC("gpio", 1, 20, 2), | ||
| 118 | FUNC("uart", 0, 20, 2), | ||
| 119 | }; | ||
| 120 | |||
| 121 | static struct rt2880_pmx_func uart1_grp_mt7628[] = { | ||
| 122 | FUNC("sdcx", 3, 45, 2), | ||
| 123 | FUNC("pwm", 2, 45, 2), | ||
| 124 | FUNC("gpio", 1, 45, 2), | ||
| 125 | FUNC("uart", 0, 45, 2), | ||
| 126 | }; | ||
| 127 | |||
| 128 | static struct rt2880_pmx_func i2c_grp_mt7628[] = { | ||
| 129 | FUNC("-", 3, 4, 2), | ||
| 130 | FUNC("debug", 2, 4, 2), | ||
| 131 | FUNC("gpio", 1, 4, 2), | ||
| 132 | FUNC("i2c", 0, 4, 2), | ||
| 133 | }; | ||
| 134 | |||
| 135 | static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("reclk", 0, 36, 1) }; | ||
| 136 | static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 37, 1) }; | ||
| 137 | static struct rt2880_pmx_func wdt_grp_mt7628[] = { FUNC("wdt", 0, 15, 38) }; | ||
| 138 | static struct rt2880_pmx_func spi_grp_mt7628[] = { FUNC("spi", 0, 7, 4) }; | ||
| 139 | |||
| 140 | static struct rt2880_pmx_func sd_mode_grp_mt7628[] = { | ||
| 141 | FUNC("jtag", 3, 22, 8), | ||
| 142 | FUNC("utif", 2, 22, 8), | ||
| 143 | FUNC("gpio", 1, 22, 8), | ||
| 144 | FUNC("sdcx", 0, 22, 8), | ||
| 145 | }; | ||
| 146 | |||
| 147 | static struct rt2880_pmx_func uart0_grp_mt7628[] = { | ||
| 148 | FUNC("-", 3, 12, 2), | ||
| 149 | FUNC("-", 2, 12, 2), | ||
| 150 | FUNC("gpio", 1, 12, 2), | ||
| 151 | FUNC("uart", 0, 12, 2), | ||
| 152 | }; | ||
| 153 | |||
| 154 | static struct rt2880_pmx_func i2s_grp_mt7628[] = { | ||
| 155 | FUNC("antenna", 3, 0, 4), | ||
| 156 | FUNC("pcm", 2, 0, 4), | ||
| 157 | FUNC("gpio", 1, 0, 4), | ||
| 158 | FUNC("i2s", 0, 0, 4), | ||
| 159 | }; | ||
| 160 | |||
| 161 | static struct rt2880_pmx_func spi_cs1_grp_mt7628[] = { | ||
| 162 | FUNC("-", 3, 6, 1), | ||
| 163 | FUNC("refclk", 2, 6, 1), | ||
| 164 | FUNC("gpio", 1, 6, 1), | ||
| 165 | FUNC("spi", 0, 6, 1), | ||
| 166 | }; | ||
| 167 | |||
| 168 | static struct rt2880_pmx_func spis_grp_mt7628[] = { | ||
| 169 | FUNC("pwm", 3, 14, 4), | ||
| 170 | FUNC("util", 2, 14, 4), | ||
| 171 | FUNC("gpio", 1, 14, 4), | ||
| 172 | FUNC("spis", 0, 14, 4), | ||
| 89 | }; | 173 | }; |
| 90 | 174 | ||
| 91 | static struct ralink_pinmux_grp uart_mux[] = { | 175 | static struct rt2880_pmx_func gpio_grp_mt7628[] = { |
| 92 | { | 176 | FUNC("pcie", 3, 11, 1), |
| 93 | .name = "uartf", | 177 | FUNC("refclk", 2, 11, 1), |
| 94 | .mask = MT7620_GPIO_MODE_UARTF, | 178 | FUNC("gpio", 1, 11, 1), |
| 95 | .gpio_first = 7, | 179 | FUNC("gpio", 0, 11, 1), |
| 96 | .gpio_last = 14, | ||
| 97 | }, { | ||
| 98 | .name = "pcm uartf", | ||
| 99 | .mask = MT7620_GPIO_MODE_PCM_UARTF, | ||
| 100 | .gpio_first = 7, | ||
| 101 | .gpio_last = 14, | ||
| 102 | }, { | ||
| 103 | .name = "pcm i2s", | ||
| 104 | .mask = MT7620_GPIO_MODE_PCM_I2S, | ||
| 105 | .gpio_first = 7, | ||
| 106 | .gpio_last = 14, | ||
| 107 | }, { | ||
| 108 | .name = "i2s uartf", | ||
| 109 | .mask = MT7620_GPIO_MODE_I2S_UARTF, | ||
| 110 | .gpio_first = 7, | ||
| 111 | .gpio_last = 14, | ||
| 112 | }, { | ||
| 113 | .name = "pcm gpio", | ||
| 114 | .mask = MT7620_GPIO_MODE_PCM_GPIO, | ||
| 115 | .gpio_first = 11, | ||
| 116 | .gpio_last = 14, | ||
| 117 | }, { | ||
| 118 | .name = "gpio uartf", | ||
| 119 | .mask = MT7620_GPIO_MODE_GPIO_UARTF, | ||
| 120 | .gpio_first = 7, | ||
| 121 | .gpio_last = 10, | ||
| 122 | }, { | ||
| 123 | .name = "gpio i2s", | ||
| 124 | .mask = MT7620_GPIO_MODE_GPIO_I2S, | ||
| 125 | .gpio_first = 7, | ||
| 126 | .gpio_last = 10, | ||
| 127 | }, { | ||
| 128 | .name = "gpio", | ||
| 129 | .mask = MT7620_GPIO_MODE_GPIO, | ||
| 130 | }, {0} | ||
| 131 | }; | 180 | }; |
| 132 | 181 | ||
| 133 | struct ralink_pinmux rt_gpio_pinmux = { | 182 | #define MT7628_GPIO_MODE_MASK 0x3 |
| 134 | .mode = mode_mux, | 183 | |
| 135 | .uart = uart_mux, | 184 | #define MT7628_GPIO_MODE_PWM1 30 |
| 136 | .uart_shift = MT7620_GPIO_MODE_UART0_SHIFT, | 185 | #define MT7628_GPIO_MODE_PWM0 28 |
| 137 | .uart_mask = MT7620_GPIO_MODE_UART0_MASK, | 186 | #define MT7628_GPIO_MODE_UART2 26 |
| 187 | #define MT7628_GPIO_MODE_UART1 24 | ||
| 188 | #define MT7628_GPIO_MODE_I2C 20 | ||
| 189 | #define MT7628_GPIO_MODE_REFCLK 18 | ||
| 190 | #define MT7628_GPIO_MODE_PERST 16 | ||
| 191 | #define MT7628_GPIO_MODE_WDT 14 | ||
| 192 | #define MT7628_GPIO_MODE_SPI 12 | ||
| 193 | #define MT7628_GPIO_MODE_SDMODE 10 | ||
| 194 | #define MT7628_GPIO_MODE_UART0 8 | ||
| 195 | #define MT7628_GPIO_MODE_I2S 6 | ||
| 196 | #define MT7628_GPIO_MODE_CS1 4 | ||
| 197 | #define MT7628_GPIO_MODE_SPIS 2 | ||
| 198 | #define MT7628_GPIO_MODE_GPIO 0 | ||
| 199 | |||
| 200 | static struct rt2880_pmx_group mt7628an_pinmux_data[] = { | ||
| 201 | GRP_G("pmw1", pwm1_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
| 202 | 1, MT7628_GPIO_MODE_PWM1), | ||
| 203 | GRP_G("pmw1", pwm0_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
| 204 | 1, MT7628_GPIO_MODE_PWM0), | ||
| 205 | GRP_G("uart2", uart2_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
| 206 | 1, MT7628_GPIO_MODE_UART2), | ||
| 207 | GRP_G("uart1", uart1_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
| 208 | 1, MT7628_GPIO_MODE_UART1), | ||
| 209 | GRP_G("i2c", i2c_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
| 210 | 1, MT7628_GPIO_MODE_I2C), | ||
| 211 | GRP("refclk", refclk_grp_mt7628, 1, MT7628_GPIO_MODE_REFCLK), | ||
| 212 | GRP("perst", perst_grp_mt7628, 1, MT7628_GPIO_MODE_PERST), | ||
| 213 | GRP("wdt", wdt_grp_mt7628, 1, MT7628_GPIO_MODE_WDT), | ||
| 214 | GRP("spi", spi_grp_mt7628, 1, MT7628_GPIO_MODE_SPI), | ||
| 215 | GRP_G("sdmode", sd_mode_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
| 216 | 1, MT7628_GPIO_MODE_SDMODE), | ||
| 217 | GRP_G("uart0", uart0_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
| 218 | 1, MT7628_GPIO_MODE_UART0), | ||
| 219 | GRP_G("i2s", i2s_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
| 220 | 1, MT7628_GPIO_MODE_I2S), | ||
| 221 | GRP_G("spi cs1", spi_cs1_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
| 222 | 1, MT7628_GPIO_MODE_CS1), | ||
| 223 | GRP_G("spis", spis_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
| 224 | 1, MT7628_GPIO_MODE_SPIS), | ||
| 225 | GRP_G("gpio", gpio_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
| 226 | 1, MT7628_GPIO_MODE_GPIO), | ||
| 227 | { 0 } | ||
| 138 | }; | 228 | }; |
| 139 | 229 | ||
| 140 | static __init u32 | 230 | static __init u32 |
| @@ -287,29 +377,42 @@ void __init ralink_clk_init(void) | |||
| 287 | 377 | ||
| 288 | xtal_rate = mt7620_get_xtal_rate(); | 378 | xtal_rate = mt7620_get_xtal_rate(); |
| 289 | 379 | ||
| 290 | cpu_pll_rate = mt7620_get_cpu_pll_rate(xtal_rate); | ||
| 291 | pll_rate = mt7620_get_pll_rate(xtal_rate, cpu_pll_rate); | ||
| 292 | |||
| 293 | cpu_rate = mt7620_get_cpu_rate(pll_rate); | ||
| 294 | dram_rate = mt7620_get_dram_rate(pll_rate); | ||
| 295 | sys_rate = mt7620_get_sys_rate(cpu_rate); | ||
| 296 | periph_rate = mt7620_get_periph_rate(xtal_rate); | ||
| 297 | |||
| 298 | #define RFMT(label) label ":%lu.%03luMHz " | 380 | #define RFMT(label) label ":%lu.%03luMHz " |
| 299 | #define RINT(x) ((x) / 1000000) | 381 | #define RINT(x) ((x) / 1000000) |
| 300 | #define RFRAC(x) (((x) / 1000) % 1000) | 382 | #define RFRAC(x) (((x) / 1000) % 1000) |
| 301 | 383 | ||
| 302 | pr_debug(RFMT("XTAL") RFMT("CPU_PLL") RFMT("PLL"), | 384 | if (mt762x_soc == MT762X_SOC_MT7628AN) { |
| 303 | RINT(xtal_rate), RFRAC(xtal_rate), | 385 | if (xtal_rate == MHZ(40)) |
| 304 | RINT(cpu_pll_rate), RFRAC(cpu_pll_rate), | 386 | cpu_rate = MHZ(580); |
| 305 | RINT(pll_rate), RFRAC(pll_rate)); | 387 | else |
| 388 | cpu_rate = MHZ(575); | ||
| 389 | dram_rate = sys_rate = cpu_rate / 3; | ||
| 390 | periph_rate = MHZ(40); | ||
| 391 | |||
| 392 | ralink_clk_add("10000d00.uartlite", periph_rate); | ||
| 393 | ralink_clk_add("10000e00.uartlite", periph_rate); | ||
| 394 | } else { | ||
| 395 | cpu_pll_rate = mt7620_get_cpu_pll_rate(xtal_rate); | ||
| 396 | pll_rate = mt7620_get_pll_rate(xtal_rate, cpu_pll_rate); | ||
| 397 | |||
| 398 | cpu_rate = mt7620_get_cpu_rate(pll_rate); | ||
| 399 | dram_rate = mt7620_get_dram_rate(pll_rate); | ||
| 400 | sys_rate = mt7620_get_sys_rate(cpu_rate); | ||
| 401 | periph_rate = mt7620_get_periph_rate(xtal_rate); | ||
| 402 | |||
| 403 | pr_debug(RFMT("XTAL") RFMT("CPU_PLL") RFMT("PLL"), | ||
| 404 | RINT(xtal_rate), RFRAC(xtal_rate), | ||
| 405 | RINT(cpu_pll_rate), RFRAC(cpu_pll_rate), | ||
| 406 | RINT(pll_rate), RFRAC(pll_rate)); | ||
| 407 | |||
| 408 | ralink_clk_add("10000500.uart", periph_rate); | ||
| 409 | } | ||
| 306 | 410 | ||
| 307 | pr_debug(RFMT("CPU") RFMT("DRAM") RFMT("SYS") RFMT("PERIPH"), | 411 | pr_debug(RFMT("CPU") RFMT("DRAM") RFMT("SYS") RFMT("PERIPH"), |
| 308 | RINT(cpu_rate), RFRAC(cpu_rate), | 412 | RINT(cpu_rate), RFRAC(cpu_rate), |
| 309 | RINT(dram_rate), RFRAC(dram_rate), | 413 | RINT(dram_rate), RFRAC(dram_rate), |
| 310 | RINT(sys_rate), RFRAC(sys_rate), | 414 | RINT(sys_rate), RFRAC(sys_rate), |
| 311 | RINT(periph_rate), RFRAC(periph_rate)); | 415 | RINT(periph_rate), RFRAC(periph_rate)); |
| 312 | |||
| 313 | #undef RFRAC | 416 | #undef RFRAC |
| 314 | #undef RINT | 417 | #undef RINT |
| 315 | #undef RFMT | 418 | #undef RFMT |
| @@ -317,9 +420,9 @@ void __init ralink_clk_init(void) | |||
| 317 | ralink_clk_add("cpu", cpu_rate); | 420 | ralink_clk_add("cpu", cpu_rate); |
| 318 | ralink_clk_add("10000100.timer", periph_rate); | 421 | ralink_clk_add("10000100.timer", periph_rate); |
| 319 | ralink_clk_add("10000120.watchdog", periph_rate); | 422 | ralink_clk_add("10000120.watchdog", periph_rate); |
| 320 | ralink_clk_add("10000500.uart", periph_rate); | ||
| 321 | ralink_clk_add("10000b00.spi", sys_rate); | 423 | ralink_clk_add("10000b00.spi", sys_rate); |
| 322 | ralink_clk_add("10000c00.uartlite", periph_rate); | 424 | ralink_clk_add("10000c00.uartlite", periph_rate); |
| 425 | ralink_clk_add("10180000.wmac", xtal_rate); | ||
| 323 | } | 426 | } |
| 324 | 427 | ||
| 325 | void __init ralink_of_remap(void) | 428 | void __init ralink_of_remap(void) |
| @@ -331,6 +434,52 @@ void __init ralink_of_remap(void) | |||
| 331 | panic("Failed to remap core resources"); | 434 | panic("Failed to remap core resources"); |
| 332 | } | 435 | } |
| 333 | 436 | ||
| 437 | static __init void | ||
| 438 | mt7620_dram_init(struct ralink_soc_info *soc_info) | ||
| 439 | { | ||
| 440 | switch (dram_type) { | ||
| 441 | case SYSCFG0_DRAM_TYPE_SDRAM: | ||
| 442 | pr_info("Board has SDRAM\n"); | ||
| 443 | soc_info->mem_size_min = MT7620_SDRAM_SIZE_MIN; | ||
| 444 | soc_info->mem_size_max = MT7620_SDRAM_SIZE_MAX; | ||
| 445 | break; | ||
| 446 | |||
| 447 | case SYSCFG0_DRAM_TYPE_DDR1: | ||
| 448 | pr_info("Board has DDR1\n"); | ||
| 449 | soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN; | ||
| 450 | soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX; | ||
| 451 | break; | ||
| 452 | |||
| 453 | case SYSCFG0_DRAM_TYPE_DDR2: | ||
| 454 | pr_info("Board has DDR2\n"); | ||
| 455 | soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN; | ||
| 456 | soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX; | ||
| 457 | break; | ||
| 458 | default: | ||
| 459 | BUG(); | ||
| 460 | } | ||
| 461 | } | ||
| 462 | |||
| 463 | static __init void | ||
| 464 | mt7628_dram_init(struct ralink_soc_info *soc_info) | ||
| 465 | { | ||
| 466 | switch (dram_type) { | ||
| 467 | case SYSCFG0_DRAM_TYPE_DDR1_MT7628: | ||
| 468 | pr_info("Board has DDR1\n"); | ||
| 469 | soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN; | ||
| 470 | soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX; | ||
| 471 | break; | ||
| 472 | |||
| 473 | case SYSCFG0_DRAM_TYPE_DDR2_MT7628: | ||
| 474 | pr_info("Board has DDR2\n"); | ||
| 475 | soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN; | ||
| 476 | soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX; | ||
| 477 | break; | ||
| 478 | default: | ||
| 479 | BUG(); | ||
| 480 | } | ||
| 481 | } | ||
| 482 | |||
| 334 | void prom_soc_init(struct ralink_soc_info *soc_info) | 483 | void prom_soc_init(struct ralink_soc_info *soc_info) |
| 335 | { | 484 | { |
| 336 | void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7620_SYSC_BASE); | 485 | void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7620_SYSC_BASE); |
| @@ -339,22 +488,36 @@ void prom_soc_init(struct ralink_soc_info *soc_info) | |||
| 339 | u32 n1; | 488 | u32 n1; |
| 340 | u32 rev; | 489 | u32 rev; |
| 341 | u32 cfg0; | 490 | u32 cfg0; |
| 491 | u32 pmu0; | ||
| 492 | u32 pmu1; | ||
| 493 | u32 bga; | ||
| 342 | 494 | ||
| 343 | n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0); | 495 | n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0); |
| 344 | n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1); | 496 | n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1); |
| 345 | 497 | rev = __raw_readl(sysc + SYSC_REG_CHIP_REV); | |
| 346 | if (n0 == MT7620N_CHIP_NAME0 && n1 == MT7620N_CHIP_NAME1) { | 498 | bga = (rev >> CHIP_REV_PKG_SHIFT) & CHIP_REV_PKG_MASK; |
| 347 | name = "MT7620N"; | 499 | |
| 348 | soc_info->compatible = "ralink,mt7620n-soc"; | 500 | if (n0 == MT7620_CHIP_NAME0 && n1 == MT7620_CHIP_NAME1) { |
| 349 | } else if (n0 == MT7620A_CHIP_NAME0 && n1 == MT7620A_CHIP_NAME1) { | 501 | if (bga) { |
| 350 | name = "MT7620A"; | 502 | mt762x_soc = MT762X_SOC_MT7620A; |
| 351 | soc_info->compatible = "ralink,mt7620a-soc"; | 503 | name = "MT7620A"; |
| 504 | soc_info->compatible = "ralink,mt7620a-soc"; | ||
| 505 | } else { | ||
| 506 | mt762x_soc = MT762X_SOC_MT7620N; | ||
| 507 | name = "MT7620N"; | ||
| 508 | soc_info->compatible = "ralink,mt7620n-soc"; | ||
| 509 | #ifdef CONFIG_PCI | ||
| 510 | panic("mt7620n is only supported for non pci kernels"); | ||
| 511 | #endif | ||
| 512 | } | ||
| 513 | } else if (n0 == MT7620_CHIP_NAME0 && n1 == MT7628_CHIP_NAME1) { | ||
| 514 | mt762x_soc = MT762X_SOC_MT7628AN; | ||
| 515 | name = "MT7628AN"; | ||
| 516 | soc_info->compatible = "ralink,mt7628an-soc"; | ||
| 352 | } else { | 517 | } else { |
| 353 | panic("mt7620: unknown SoC, n0:%08x n1:%08x", n0, n1); | 518 | panic("mt762x: unknown SoC, n0:%08x n1:%08x\n", n0, n1); |
| 354 | } | 519 | } |
| 355 | 520 | ||
| 356 | rev = __raw_readl(sysc + SYSC_REG_CHIP_REV); | ||
| 357 | |||
| 358 | snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN, | 521 | snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN, |
| 359 | "Ralink %s ver:%u eco:%u", | 522 | "Ralink %s ver:%u eco:%u", |
| 360 | name, | 523 | name, |
| @@ -364,26 +527,22 @@ void prom_soc_init(struct ralink_soc_info *soc_info) | |||
| 364 | cfg0 = __raw_readl(sysc + SYSC_REG_SYSTEM_CONFIG0); | 527 | cfg0 = __raw_readl(sysc + SYSC_REG_SYSTEM_CONFIG0); |
| 365 | dram_type = (cfg0 >> SYSCFG0_DRAM_TYPE_SHIFT) & SYSCFG0_DRAM_TYPE_MASK; | 528 | dram_type = (cfg0 >> SYSCFG0_DRAM_TYPE_SHIFT) & SYSCFG0_DRAM_TYPE_MASK; |
| 366 | 529 | ||
| 367 | switch (dram_type) { | ||
| 368 | case SYSCFG0_DRAM_TYPE_SDRAM: | ||
| 369 | pr_info("Board has SDRAM\n"); | ||
| 370 | soc_info->mem_size_min = MT7620_SDRAM_SIZE_MIN; | ||
| 371 | soc_info->mem_size_max = MT7620_SDRAM_SIZE_MAX; | ||
| 372 | break; | ||
| 373 | |||
| 374 | case SYSCFG0_DRAM_TYPE_DDR1: | ||
| 375 | pr_info("Board has DDR1\n"); | ||
| 376 | soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN; | ||
| 377 | soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX; | ||
| 378 | break; | ||
| 379 | |||
| 380 | case SYSCFG0_DRAM_TYPE_DDR2: | ||
| 381 | pr_info("Board has DDR2\n"); | ||
| 382 | soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN; | ||
| 383 | soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX; | ||
| 384 | break; | ||
| 385 | default: | ||
| 386 | BUG(); | ||
| 387 | } | ||
| 388 | soc_info->mem_base = MT7620_DRAM_BASE; | 530 | soc_info->mem_base = MT7620_DRAM_BASE; |
| 531 | if (mt762x_soc == MT762X_SOC_MT7628AN) | ||
| 532 | mt7628_dram_init(soc_info); | ||
| 533 | else | ||
| 534 | mt7620_dram_init(soc_info); | ||
| 535 | |||
| 536 | pmu0 = __raw_readl(sysc + PMU0_CFG); | ||
| 537 | pmu1 = __raw_readl(sysc + PMU1_CFG); | ||
| 538 | |||
| 539 | pr_info("Analog PMU set to %s control\n", | ||
| 540 | (pmu0 & PMU_SW_SET) ? ("sw") : ("hw")); | ||
| 541 | pr_info("Digital PMU set to %s control\n", | ||
| 542 | (pmu1 & DIG_SW_SEL) ? ("sw") : ("hw")); | ||
| 543 | |||
| 544 | if (mt762x_soc == MT762X_SOC_MT7628AN) | ||
| 545 | rt2880_pinmux_data = mt7628an_pinmux_data; | ||
| 546 | else | ||
| 547 | rt2880_pinmux_data = mt7620a_pinmux_data; | ||
| 389 | } | 548 | } |
diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c index 7c4598cb6de8..0d30dcd63246 100644 --- a/arch/mips/ralink/of.c +++ b/arch/mips/ralink/of.c | |||
| @@ -53,6 +53,17 @@ void __init device_tree_init(void) | |||
| 53 | unflatten_and_copy_device_tree(); | 53 | unflatten_and_copy_device_tree(); |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | static int memory_dtb; | ||
| 57 | |||
| 58 | static int __init early_init_dt_find_memory(unsigned long node, | ||
| 59 | const char *uname, int depth, void *data) | ||
| 60 | { | ||
| 61 | if (depth == 1 && !strcmp(uname, "memory@0")) | ||
| 62 | memory_dtb = 1; | ||
| 63 | |||
| 64 | return 0; | ||
| 65 | } | ||
| 66 | |||
| 56 | void __init plat_mem_setup(void) | 67 | void __init plat_mem_setup(void) |
| 57 | { | 68 | { |
| 58 | set_io_port_base(KSEG1); | 69 | set_io_port_base(KSEG1); |
| @@ -63,7 +74,12 @@ void __init plat_mem_setup(void) | |||
| 63 | */ | 74 | */ |
| 64 | __dt_setup_arch(__dtb_start); | 75 | __dt_setup_arch(__dtb_start); |
| 65 | 76 | ||
| 66 | if (soc_info.mem_size) | 77 | strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); |
| 78 | |||
| 79 | of_scan_flat_dt(early_init_dt_find_memory, NULL); | ||
| 80 | if (memory_dtb) | ||
| 81 | of_scan_flat_dt(early_init_dt_scan_memory, NULL); | ||
| 82 | else if (soc_info.mem_size) | ||
| 67 | add_memory_region(soc_info.mem_base, soc_info.mem_size * SZ_1M, | 83 | add_memory_region(soc_info.mem_base, soc_info.mem_size * SZ_1M, |
| 68 | BOOT_MEM_RAM); | 84 | BOOT_MEM_RAM); |
| 69 | else | 85 | else |
| @@ -74,19 +90,9 @@ void __init plat_mem_setup(void) | |||
| 74 | 90 | ||
| 75 | static int __init plat_of_setup(void) | 91 | static int __init plat_of_setup(void) |
| 76 | { | 92 | { |
| 77 | static struct of_device_id of_ids[3]; | 93 | __dt_register_buses(soc_info.compatible, "palmbus"); |
| 78 | int len = sizeof(of_ids[0].compatible); | ||
| 79 | |||
| 80 | if (!of_have_populated_dt()) | ||
| 81 | panic("device tree not present"); | ||
| 82 | |||
| 83 | strlcpy(of_ids[0].compatible, soc_info.compatible, len); | ||
| 84 | strlcpy(of_ids[1].compatible, "palmbus", len); | ||
| 85 | |||
| 86 | if (of_platform_populate(NULL, of_ids, NULL, NULL)) | ||
| 87 | panic("failed to populate DT"); | ||
| 88 | 94 | ||
| 89 | /* make sure ithat the reset controller is setup early */ | 95 | /* make sure that the reset controller is setup early */ |
| 90 | ralink_rst_init(); | 96 | ralink_rst_init(); |
| 91 | 97 | ||
| 92 | return 0; | 98 | return 0; |
diff --git a/arch/mips/ralink/prom.c b/arch/mips/ralink/prom.c index 9c64f029d047..09419f67da39 100644 --- a/arch/mips/ralink/prom.c +++ b/arch/mips/ralink/prom.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include "common.h" | 18 | #include "common.h" |
| 19 | 19 | ||
| 20 | struct ralink_soc_info soc_info; | 20 | struct ralink_soc_info soc_info; |
| 21 | struct rt2880_pmx_group *rt2880_pinmux_data = NULL; | ||
| 21 | 22 | ||
| 22 | const char *get_system_type(void) | 23 | const char *get_system_type(void) |
| 23 | { | 24 | { |
diff --git a/arch/mips/ralink/rt288x.c b/arch/mips/ralink/rt288x.c index f87de1ab2198..738cec865f41 100644 --- a/arch/mips/ralink/rt288x.c +++ b/arch/mips/ralink/rt288x.c | |||
| @@ -17,46 +17,27 @@ | |||
| 17 | #include <asm/mipsregs.h> | 17 | #include <asm/mipsregs.h> |
| 18 | #include <asm/mach-ralink/ralink_regs.h> | 18 | #include <asm/mach-ralink/ralink_regs.h> |
| 19 | #include <asm/mach-ralink/rt288x.h> | 19 | #include <asm/mach-ralink/rt288x.h> |
| 20 | #include <asm/mach-ralink/pinmux.h> | ||
| 20 | 21 | ||
| 21 | #include "common.h" | 22 | #include "common.h" |
| 22 | 23 | ||
| 23 | static struct ralink_pinmux_grp mode_mux[] = { | 24 | static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) }; |
| 24 | { | 25 | static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) }; |
| 25 | .name = "i2c", | 26 | static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 7, 8) }; |
| 26 | .mask = RT2880_GPIO_MODE_I2C, | 27 | static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) }; |
| 27 | .gpio_first = 1, | 28 | static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) }; |
| 28 | .gpio_last = 2, | 29 | static struct rt2880_pmx_func sdram_func[] = { FUNC("sdram", 0, 24, 16) }; |
| 29 | }, { | 30 | static struct rt2880_pmx_func pci_func[] = { FUNC("pci", 0, 40, 32) }; |
| 30 | .name = "spi", | 31 | |
| 31 | .mask = RT2880_GPIO_MODE_SPI, | 32 | static struct rt2880_pmx_group rt2880_pinmux_data_act[] = { |
| 32 | .gpio_first = 3, | 33 | GRP("i2c", i2c_func, 1, RT2880_GPIO_MODE_I2C), |
| 33 | .gpio_last = 6, | 34 | GRP("spi", spi_func, 1, RT2880_GPIO_MODE_SPI), |
| 34 | }, { | 35 | GRP("uartlite", uartlite_func, 1, RT2880_GPIO_MODE_UART0), |
| 35 | .name = "uartlite", | 36 | GRP("jtag", jtag_func, 1, RT2880_GPIO_MODE_JTAG), |
| 36 | .mask = RT2880_GPIO_MODE_UART0, | 37 | GRP("mdio", mdio_func, 1, RT2880_GPIO_MODE_MDIO), |
| 37 | .gpio_first = 7, | 38 | GRP("sdram", sdram_func, 1, RT2880_GPIO_MODE_SDRAM), |
| 38 | .gpio_last = 14, | 39 | GRP("pci", pci_func, 1, RT2880_GPIO_MODE_PCI), |
| 39 | }, { | 40 | { 0 } |
| 40 | .name = "jtag", | ||
| 41 | .mask = RT2880_GPIO_MODE_JTAG, | ||
| 42 | .gpio_first = 17, | ||
| 43 | .gpio_last = 21, | ||
| 44 | }, { | ||
| 45 | .name = "mdio", | ||
| 46 | .mask = RT2880_GPIO_MODE_MDIO, | ||
| 47 | .gpio_first = 22, | ||
| 48 | .gpio_last = 23, | ||
| 49 | }, { | ||
| 50 | .name = "sdram", | ||
| 51 | .mask = RT2880_GPIO_MODE_SDRAM, | ||
| 52 | .gpio_first = 24, | ||
| 53 | .gpio_last = 39, | ||
| 54 | }, { | ||
| 55 | .name = "pci", | ||
| 56 | .mask = RT2880_GPIO_MODE_PCI, | ||
| 57 | .gpio_first = 40, | ||
| 58 | .gpio_last = 71, | ||
| 59 | }, {0} | ||
| 60 | }; | 41 | }; |
| 61 | 42 | ||
| 62 | static void rt288x_wdt_reset(void) | 43 | static void rt288x_wdt_reset(void) |
| @@ -69,14 +50,9 @@ static void rt288x_wdt_reset(void) | |||
| 69 | rt_sysc_w32(t, SYSC_REG_CLKCFG); | 50 | rt_sysc_w32(t, SYSC_REG_CLKCFG); |
| 70 | } | 51 | } |
| 71 | 52 | ||
| 72 | struct ralink_pinmux rt_gpio_pinmux = { | ||
| 73 | .mode = mode_mux, | ||
| 74 | .wdt_reset = rt288x_wdt_reset, | ||
| 75 | }; | ||
| 76 | |||
| 77 | void __init ralink_clk_init(void) | 53 | void __init ralink_clk_init(void) |
| 78 | { | 54 | { |
| 79 | unsigned long cpu_rate; | 55 | unsigned long cpu_rate, wmac_rate = 40000000; |
| 80 | u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG); | 56 | u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG); |
| 81 | t = ((t >> SYSTEM_CONFIG_CPUCLK_SHIFT) & SYSTEM_CONFIG_CPUCLK_MASK); | 57 | t = ((t >> SYSTEM_CONFIG_CPUCLK_SHIFT) & SYSTEM_CONFIG_CPUCLK_MASK); |
| 82 | 58 | ||
| @@ -101,6 +77,7 @@ void __init ralink_clk_init(void) | |||
| 101 | ralink_clk_add("300500.uart", cpu_rate / 2); | 77 | ralink_clk_add("300500.uart", cpu_rate / 2); |
| 102 | ralink_clk_add("300c00.uartlite", cpu_rate / 2); | 78 | ralink_clk_add("300c00.uartlite", cpu_rate / 2); |
| 103 | ralink_clk_add("400000.ethernet", cpu_rate / 2); | 79 | ralink_clk_add("400000.ethernet", cpu_rate / 2); |
| 80 | ralink_clk_add("480000.wmac", wmac_rate); | ||
| 104 | } | 81 | } |
| 105 | 82 | ||
| 106 | void __init ralink_of_remap(void) | 83 | void __init ralink_of_remap(void) |
| @@ -140,4 +117,6 @@ void prom_soc_init(struct ralink_soc_info *soc_info) | |||
| 140 | soc_info->mem_base = RT2880_SDRAM_BASE; | 117 | soc_info->mem_base = RT2880_SDRAM_BASE; |
| 141 | soc_info->mem_size_min = RT2880_MEM_SIZE_MIN; | 118 | soc_info->mem_size_min = RT2880_MEM_SIZE_MIN; |
| 142 | soc_info->mem_size_max = RT2880_MEM_SIZE_MAX; | 119 | soc_info->mem_size_max = RT2880_MEM_SIZE_MAX; |
| 120 | |||
| 121 | rt2880_pinmux_data = rt2880_pinmux_data_act; | ||
| 143 | } | 122 | } |
diff --git a/arch/mips/ralink/rt305x.c b/arch/mips/ralink/rt305x.c index bb82a82da9e7..c40776ab67db 100644 --- a/arch/mips/ralink/rt305x.c +++ b/arch/mips/ralink/rt305x.c | |||
| @@ -17,90 +17,78 @@ | |||
| 17 | #include <asm/mipsregs.h> | 17 | #include <asm/mipsregs.h> |
| 18 | #include <asm/mach-ralink/ralink_regs.h> | 18 | #include <asm/mach-ralink/ralink_regs.h> |
| 19 | #include <asm/mach-ralink/rt305x.h> | 19 | #include <asm/mach-ralink/rt305x.h> |
| 20 | #include <asm/mach-ralink/pinmux.h> | ||
| 20 | 21 | ||
| 21 | #include "common.h" | 22 | #include "common.h" |
| 22 | 23 | ||
| 23 | enum rt305x_soc_type rt305x_soc; | 24 | enum rt305x_soc_type rt305x_soc; |
| 24 | 25 | ||
| 25 | static struct ralink_pinmux_grp mode_mux[] = { | 26 | static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) }; |
| 26 | { | 27 | static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) }; |
| 27 | .name = "i2c", | 28 | static struct rt2880_pmx_func uartf_func[] = { |
| 28 | .mask = RT305X_GPIO_MODE_I2C, | 29 | FUNC("uartf", RT305X_GPIO_MODE_UARTF, 7, 8), |
| 29 | .gpio_first = RT305X_GPIO_I2C_SD, | 30 | FUNC("pcm uartf", RT305X_GPIO_MODE_PCM_UARTF, 7, 8), |
| 30 | .gpio_last = RT305X_GPIO_I2C_SCLK, | 31 | FUNC("pcm i2s", RT305X_GPIO_MODE_PCM_I2S, 7, 8), |
| 31 | }, { | 32 | FUNC("i2s uartf", RT305X_GPIO_MODE_I2S_UARTF, 7, 8), |
| 32 | .name = "spi", | 33 | FUNC("pcm gpio", RT305X_GPIO_MODE_PCM_GPIO, 11, 4), |
| 33 | .mask = RT305X_GPIO_MODE_SPI, | 34 | FUNC("gpio uartf", RT305X_GPIO_MODE_GPIO_UARTF, 7, 4), |
| 34 | .gpio_first = RT305X_GPIO_SPI_EN, | 35 | FUNC("gpio i2s", RT305X_GPIO_MODE_GPIO_I2S, 7, 4), |
| 35 | .gpio_last = RT305X_GPIO_SPI_CLK, | 36 | }; |
| 36 | }, { | 37 | static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) }; |
| 37 | .name = "uartlite", | 38 | static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) }; |
| 38 | .mask = RT305X_GPIO_MODE_UART1, | 39 | static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) }; |
| 39 | .gpio_first = RT305X_GPIO_UART1_TXD, | 40 | static struct rt2880_pmx_func rt5350_led_func[] = { FUNC("led", 0, 22, 5) }; |
| 40 | .gpio_last = RT305X_GPIO_UART1_RXD, | 41 | static struct rt2880_pmx_func rt5350_cs1_func[] = { |
| 41 | }, { | 42 | FUNC("spi_cs1", 0, 27, 1), |
| 42 | .name = "jtag", | 43 | FUNC("wdg_cs1", 1, 27, 1), |
| 43 | .mask = RT305X_GPIO_MODE_JTAG, | 44 | }; |
| 44 | .gpio_first = RT305X_GPIO_JTAG_TDO, | 45 | static struct rt2880_pmx_func sdram_func[] = { FUNC("sdram", 0, 24, 16) }; |
| 45 | .gpio_last = RT305X_GPIO_JTAG_TDI, | 46 | static struct rt2880_pmx_func rt3352_rgmii_func[] = { |
| 46 | }, { | 47 | FUNC("rgmii", 0, 24, 12) |
| 47 | .name = "mdio", | 48 | }; |
| 48 | .mask = RT305X_GPIO_MODE_MDIO, | 49 | static struct rt2880_pmx_func rgmii_func[] = { FUNC("rgmii", 0, 40, 12) }; |
| 49 | .gpio_first = RT305X_GPIO_MDIO_MDC, | 50 | static struct rt2880_pmx_func rt3352_lna_func[] = { FUNC("lna", 0, 36, 2) }; |
| 50 | .gpio_last = RT305X_GPIO_MDIO_MDIO, | 51 | static struct rt2880_pmx_func rt3352_pa_func[] = { FUNC("pa", 0, 38, 2) }; |
| 51 | }, { | 52 | static struct rt2880_pmx_func rt3352_led_func[] = { FUNC("led", 0, 40, 5) }; |
| 52 | .name = "sdram", | 53 | |
| 53 | .mask = RT305X_GPIO_MODE_SDRAM, | 54 | static struct rt2880_pmx_group rt3050_pinmux_data[] = { |
| 54 | .gpio_first = RT305X_GPIO_SDRAM_MD16, | 55 | GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C), |
| 55 | .gpio_last = RT305X_GPIO_SDRAM_MD31, | 56 | GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI), |
| 56 | }, { | 57 | GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK, |
| 57 | .name = "rgmii", | 58 | RT305X_GPIO_MODE_UART0_SHIFT), |
| 58 | .mask = RT305X_GPIO_MODE_RGMII, | 59 | GRP("uartlite", uartlite_func, 1, RT305X_GPIO_MODE_UART1), |
| 59 | .gpio_first = RT305X_GPIO_GE0_TXD0, | 60 | GRP("jtag", jtag_func, 1, RT305X_GPIO_MODE_JTAG), |
| 60 | .gpio_last = RT305X_GPIO_GE0_RXCLK, | 61 | GRP("mdio", mdio_func, 1, RT305X_GPIO_MODE_MDIO), |
| 61 | }, {0} | 62 | GRP("rgmii", rgmii_func, 1, RT305X_GPIO_MODE_RGMII), |
| 63 | GRP("sdram", sdram_func, 1, RT305X_GPIO_MODE_SDRAM), | ||
| 64 | { 0 } | ||
| 62 | }; | 65 | }; |
| 63 | 66 | ||
| 64 | static struct ralink_pinmux_grp uart_mux[] = { | 67 | static struct rt2880_pmx_group rt3352_pinmux_data[] = { |
| 65 | { | 68 | GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C), |
| 66 | .name = "uartf", | 69 | GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI), |
| 67 | .mask = RT305X_GPIO_MODE_UARTF, | 70 | GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK, |
| 68 | .gpio_first = RT305X_GPIO_7, | 71 | RT305X_GPIO_MODE_UART0_SHIFT), |
| 69 | .gpio_last = RT305X_GPIO_14, | 72 | GRP("uartlite", uartlite_func, 1, RT305X_GPIO_MODE_UART1), |
| 70 | }, { | 73 | GRP("jtag", jtag_func, 1, RT305X_GPIO_MODE_JTAG), |
| 71 | .name = "pcm uartf", | 74 | GRP("mdio", mdio_func, 1, RT305X_GPIO_MODE_MDIO), |
| 72 | .mask = RT305X_GPIO_MODE_PCM_UARTF, | 75 | GRP("rgmii", rt3352_rgmii_func, 1, RT305X_GPIO_MODE_RGMII), |
| 73 | .gpio_first = RT305X_GPIO_7, | 76 | GRP("lna", rt3352_lna_func, 1, RT3352_GPIO_MODE_LNA), |
| 74 | .gpio_last = RT305X_GPIO_14, | 77 | GRP("pa", rt3352_pa_func, 1, RT3352_GPIO_MODE_PA), |
| 75 | }, { | 78 | GRP("led", rt3352_led_func, 1, RT5350_GPIO_MODE_PHY_LED), |
| 76 | .name = "pcm i2s", | 79 | { 0 } |
| 77 | .mask = RT305X_GPIO_MODE_PCM_I2S, | 80 | }; |
| 78 | .gpio_first = RT305X_GPIO_7, | 81 | |
| 79 | .gpio_last = RT305X_GPIO_14, | 82 | static struct rt2880_pmx_group rt5350_pinmux_data[] = { |
| 80 | }, { | 83 | GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C), |
| 81 | .name = "i2s uartf", | 84 | GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI), |
| 82 | .mask = RT305X_GPIO_MODE_I2S_UARTF, | 85 | GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK, |
| 83 | .gpio_first = RT305X_GPIO_7, | 86 | RT305X_GPIO_MODE_UART0_SHIFT), |
| 84 | .gpio_last = RT305X_GPIO_14, | 87 | GRP("uartlite", uartlite_func, 1, RT305X_GPIO_MODE_UART1), |
| 85 | }, { | 88 | GRP("jtag", jtag_func, 1, RT305X_GPIO_MODE_JTAG), |
| 86 | .name = "pcm gpio", | 89 | GRP("led", rt5350_led_func, 1, RT5350_GPIO_MODE_PHY_LED), |
| 87 | .mask = RT305X_GPIO_MODE_PCM_GPIO, | 90 | GRP("spi_cs1", rt5350_cs1_func, 2, RT5350_GPIO_MODE_SPI_CS1), |
| 88 | .gpio_first = RT305X_GPIO_10, | 91 | { 0 } |
| 89 | .gpio_last = RT305X_GPIO_14, | ||
| 90 | }, { | ||
| 91 | .name = "gpio uartf", | ||
| 92 | .mask = RT305X_GPIO_MODE_GPIO_UARTF, | ||
| 93 | .gpio_first = RT305X_GPIO_7, | ||
| 94 | .gpio_last = RT305X_GPIO_10, | ||
| 95 | }, { | ||
| 96 | .name = "gpio i2s", | ||
| 97 | .mask = RT305X_GPIO_MODE_GPIO_I2S, | ||
| 98 | .gpio_first = RT305X_GPIO_7, | ||
| 99 | .gpio_last = RT305X_GPIO_10, | ||
| 100 | }, { | ||
| 101 | .name = "gpio", | ||
| 102 | .mask = RT305X_GPIO_MODE_GPIO, | ||
| 103 | }, {0} | ||
| 104 | }; | 92 | }; |
| 105 | 93 | ||
| 106 | static void rt305x_wdt_reset(void) | 94 | static void rt305x_wdt_reset(void) |
| @@ -114,14 +102,6 @@ static void rt305x_wdt_reset(void) | |||
| 114 | rt_sysc_w32(t, SYSC_REG_SYSTEM_CONFIG); | 102 | rt_sysc_w32(t, SYSC_REG_SYSTEM_CONFIG); |
| 115 | } | 103 | } |
| 116 | 104 | ||
| 117 | struct ralink_pinmux rt_gpio_pinmux = { | ||
| 118 | .mode = mode_mux, | ||
| 119 | .uart = uart_mux, | ||
| 120 | .uart_shift = RT305X_GPIO_MODE_UART0_SHIFT, | ||
| 121 | .uart_mask = RT305X_GPIO_MODE_UART0_MASK, | ||
| 122 | .wdt_reset = rt305x_wdt_reset, | ||
| 123 | }; | ||
| 124 | |||
| 125 | static unsigned long rt5350_get_mem_size(void) | 105 | static unsigned long rt5350_get_mem_size(void) |
| 126 | { | 106 | { |
| 127 | void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE); | 107 | void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE); |
| @@ -290,11 +270,14 @@ void prom_soc_init(struct ralink_soc_info *soc_info) | |||
| 290 | soc_info->mem_base = RT305X_SDRAM_BASE; | 270 | soc_info->mem_base = RT305X_SDRAM_BASE; |
| 291 | if (soc_is_rt5350()) { | 271 | if (soc_is_rt5350()) { |
| 292 | soc_info->mem_size = rt5350_get_mem_size(); | 272 | soc_info->mem_size = rt5350_get_mem_size(); |
| 273 | rt2880_pinmux_data = rt5350_pinmux_data; | ||
| 293 | } else if (soc_is_rt305x() || soc_is_rt3350()) { | 274 | } else if (soc_is_rt305x() || soc_is_rt3350()) { |
| 294 | soc_info->mem_size_min = RT305X_MEM_SIZE_MIN; | 275 | soc_info->mem_size_min = RT305X_MEM_SIZE_MIN; |
| 295 | soc_info->mem_size_max = RT305X_MEM_SIZE_MAX; | 276 | soc_info->mem_size_max = RT305X_MEM_SIZE_MAX; |
| 277 | rt2880_pinmux_data = rt3050_pinmux_data; | ||
| 296 | } else if (soc_is_rt3352()) { | 278 | } else if (soc_is_rt3352()) { |
| 297 | soc_info->mem_size_min = RT3352_MEM_SIZE_MIN; | 279 | soc_info->mem_size_min = RT3352_MEM_SIZE_MIN; |
| 298 | soc_info->mem_size_max = RT3352_MEM_SIZE_MAX; | 280 | soc_info->mem_size_max = RT3352_MEM_SIZE_MAX; |
| 281 | rt2880_pinmux_data = rt3352_pinmux_data; | ||
| 299 | } | 282 | } |
| 300 | } | 283 | } |
diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c index b474ac284b83..86a535c770d8 100644 --- a/arch/mips/ralink/rt3883.c +++ b/arch/mips/ralink/rt3883.c | |||
| @@ -17,132 +17,50 @@ | |||
| 17 | #include <asm/mipsregs.h> | 17 | #include <asm/mipsregs.h> |
| 18 | #include <asm/mach-ralink/ralink_regs.h> | 18 | #include <asm/mach-ralink/ralink_regs.h> |
| 19 | #include <asm/mach-ralink/rt3883.h> | 19 | #include <asm/mach-ralink/rt3883.h> |
| 20 | #include <asm/mach-ralink/pinmux.h> | ||
| 20 | 21 | ||
| 21 | #include "common.h" | 22 | #include "common.h" |
| 22 | 23 | ||
| 23 | static struct ralink_pinmux_grp mode_mux[] = { | 24 | static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) }; |
| 24 | { | 25 | static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) }; |
| 25 | .name = "i2c", | 26 | static struct rt2880_pmx_func uartf_func[] = { |
| 26 | .mask = RT3883_GPIO_MODE_I2C, | 27 | FUNC("uartf", RT3883_GPIO_MODE_UARTF, 7, 8), |
| 27 | .gpio_first = RT3883_GPIO_I2C_SD, | 28 | FUNC("pcm uartf", RT3883_GPIO_MODE_PCM_UARTF, 7, 8), |
| 28 | .gpio_last = RT3883_GPIO_I2C_SCLK, | 29 | FUNC("pcm i2s", RT3883_GPIO_MODE_PCM_I2S, 7, 8), |
| 29 | }, { | 30 | FUNC("i2s uartf", RT3883_GPIO_MODE_I2S_UARTF, 7, 8), |
| 30 | .name = "spi", | 31 | FUNC("pcm gpio", RT3883_GPIO_MODE_PCM_GPIO, 11, 4), |
| 31 | .mask = RT3883_GPIO_MODE_SPI, | 32 | FUNC("gpio uartf", RT3883_GPIO_MODE_GPIO_UARTF, 7, 4), |
| 32 | .gpio_first = RT3883_GPIO_SPI_CS0, | 33 | FUNC("gpio i2s", RT3883_GPIO_MODE_GPIO_I2S, 7, 4), |
| 33 | .gpio_last = RT3883_GPIO_SPI_MISO, | ||
| 34 | }, { | ||
| 35 | .name = "uartlite", | ||
| 36 | .mask = RT3883_GPIO_MODE_UART1, | ||
| 37 | .gpio_first = RT3883_GPIO_UART1_TXD, | ||
| 38 | .gpio_last = RT3883_GPIO_UART1_RXD, | ||
| 39 | }, { | ||
| 40 | .name = "jtag", | ||
| 41 | .mask = RT3883_GPIO_MODE_JTAG, | ||
| 42 | .gpio_first = RT3883_GPIO_JTAG_TDO, | ||
| 43 | .gpio_last = RT3883_GPIO_JTAG_TCLK, | ||
| 44 | }, { | ||
| 45 | .name = "mdio", | ||
| 46 | .mask = RT3883_GPIO_MODE_MDIO, | ||
| 47 | .gpio_first = RT3883_GPIO_MDIO_MDC, | ||
| 48 | .gpio_last = RT3883_GPIO_MDIO_MDIO, | ||
| 49 | }, { | ||
| 50 | .name = "ge1", | ||
| 51 | .mask = RT3883_GPIO_MODE_GE1, | ||
| 52 | .gpio_first = RT3883_GPIO_GE1_TXD0, | ||
| 53 | .gpio_last = RT3883_GPIO_GE1_RXCLK, | ||
| 54 | }, { | ||
| 55 | .name = "ge2", | ||
| 56 | .mask = RT3883_GPIO_MODE_GE2, | ||
| 57 | .gpio_first = RT3883_GPIO_GE2_TXD0, | ||
| 58 | .gpio_last = RT3883_GPIO_GE2_RXCLK, | ||
| 59 | }, { | ||
| 60 | .name = "pci", | ||
| 61 | .mask = RT3883_GPIO_MODE_PCI, | ||
| 62 | .gpio_first = RT3883_GPIO_PCI_AD0, | ||
| 63 | .gpio_last = RT3883_GPIO_PCI_AD31, | ||
| 64 | }, { | ||
| 65 | .name = "lna a", | ||
| 66 | .mask = RT3883_GPIO_MODE_LNA_A, | ||
| 67 | .gpio_first = RT3883_GPIO_LNA_PE_A0, | ||
| 68 | .gpio_last = RT3883_GPIO_LNA_PE_A2, | ||
| 69 | }, { | ||
| 70 | .name = "lna g", | ||
| 71 | .mask = RT3883_GPIO_MODE_LNA_G, | ||
| 72 | .gpio_first = RT3883_GPIO_LNA_PE_G0, | ||
| 73 | .gpio_last = RT3883_GPIO_LNA_PE_G2, | ||
| 74 | }, {0} | ||
| 75 | }; | 34 | }; |
| 76 | 35 | static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) }; | |
| 77 | static struct ralink_pinmux_grp uart_mux[] = { | 36 | static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) }; |
| 78 | { | 37 | static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) }; |
| 79 | .name = "uartf", | 38 | static struct rt2880_pmx_func lna_a_func[] = { FUNC("lna a", 0, 32, 3) }; |
| 80 | .mask = RT3883_GPIO_MODE_UARTF, | 39 | static struct rt2880_pmx_func lna_g_func[] = { FUNC("lna a", 0, 35, 3) }; |
| 81 | .gpio_first = RT3883_GPIO_7, | 40 | static struct rt2880_pmx_func pci_func[] = { |
| 82 | .gpio_last = RT3883_GPIO_14, | 41 | FUNC("pci-dev", 0, 40, 32), |
| 83 | }, { | 42 | FUNC("pci-host2", 1, 40, 32), |
| 84 | .name = "pcm uartf", | 43 | FUNC("pci-host1", 2, 40, 32), |
| 85 | .mask = RT3883_GPIO_MODE_PCM_UARTF, | 44 | FUNC("pci-fnc", 3, 40, 32) |
| 86 | .gpio_first = RT3883_GPIO_7, | ||
| 87 | .gpio_last = RT3883_GPIO_14, | ||
| 88 | }, { | ||
| 89 | .name = "pcm i2s", | ||
| 90 | .mask = RT3883_GPIO_MODE_PCM_I2S, | ||
| 91 | .gpio_first = RT3883_GPIO_7, | ||
| 92 | .gpio_last = RT3883_GPIO_14, | ||
| 93 | }, { | ||
| 94 | .name = "i2s uartf", | ||
| 95 | .mask = RT3883_GPIO_MODE_I2S_UARTF, | ||
| 96 | .gpio_first = RT3883_GPIO_7, | ||
| 97 | .gpio_last = RT3883_GPIO_14, | ||
| 98 | }, { | ||
| 99 | .name = "pcm gpio", | ||
| 100 | .mask = RT3883_GPIO_MODE_PCM_GPIO, | ||
| 101 | .gpio_first = RT3883_GPIO_11, | ||
| 102 | .gpio_last = RT3883_GPIO_14, | ||
| 103 | }, { | ||
| 104 | .name = "gpio uartf", | ||
| 105 | .mask = RT3883_GPIO_MODE_GPIO_UARTF, | ||
| 106 | .gpio_first = RT3883_GPIO_7, | ||
| 107 | .gpio_last = RT3883_GPIO_10, | ||
| 108 | }, { | ||
| 109 | .name = "gpio i2s", | ||
| 110 | .mask = RT3883_GPIO_MODE_GPIO_I2S, | ||
| 111 | .gpio_first = RT3883_GPIO_7, | ||
| 112 | .gpio_last = RT3883_GPIO_10, | ||
| 113 | }, { | ||
| 114 | .name = "gpio", | ||
| 115 | .mask = RT3883_GPIO_MODE_GPIO, | ||
| 116 | }, {0} | ||
| 117 | }; | 45 | }; |
| 118 | 46 | static struct rt2880_pmx_func ge1_func[] = { FUNC("ge1", 0, 72, 12) }; | |
| 119 | static struct ralink_pinmux_grp pci_mux[] = { | 47 | static struct rt2880_pmx_func ge2_func[] = { FUNC("ge1", 0, 84, 12) }; |
| 120 | { | 48 | |
| 121 | .name = "pci-dev", | 49 | static struct rt2880_pmx_group rt3883_pinmux_data[] = { |
| 122 | .mask = 0, | 50 | GRP("i2c", i2c_func, 1, RT3883_GPIO_MODE_I2C), |
| 123 | .gpio_first = RT3883_GPIO_PCI_AD0, | 51 | GRP("spi", spi_func, 1, RT3883_GPIO_MODE_SPI), |
| 124 | .gpio_last = RT3883_GPIO_PCI_AD31, | 52 | GRP("uartf", uartf_func, RT3883_GPIO_MODE_UART0_MASK, |
| 125 | }, { | 53 | RT3883_GPIO_MODE_UART0_SHIFT), |
| 126 | .name = "pci-host2", | 54 | GRP("uartlite", uartlite_func, 1, RT3883_GPIO_MODE_UART1), |
| 127 | .mask = 1, | 55 | GRP("jtag", jtag_func, 1, RT3883_GPIO_MODE_JTAG), |
| 128 | .gpio_first = RT3883_GPIO_PCI_AD0, | 56 | GRP("mdio", mdio_func, 1, RT3883_GPIO_MODE_MDIO), |
| 129 | .gpio_last = RT3883_GPIO_PCI_AD31, | 57 | GRP("lna a", lna_a_func, 1, RT3883_GPIO_MODE_LNA_A), |
| 130 | }, { | 58 | GRP("lna g", lna_g_func, 1, RT3883_GPIO_MODE_LNA_G), |
| 131 | .name = "pci-host1", | 59 | GRP("pci", pci_func, RT3883_GPIO_MODE_PCI_MASK, |
| 132 | .mask = 2, | 60 | RT3883_GPIO_MODE_PCI_SHIFT), |
| 133 | .gpio_first = RT3883_GPIO_PCI_AD0, | 61 | GRP("ge1", ge1_func, 1, RT3883_GPIO_MODE_GE1), |
| 134 | .gpio_last = RT3883_GPIO_PCI_AD31, | 62 | GRP("ge2", ge2_func, 1, RT3883_GPIO_MODE_GE2), |
| 135 | }, { | 63 | { 0 } |
| 136 | .name = "pci-fnc", | ||
| 137 | .mask = 3, | ||
| 138 | .gpio_first = RT3883_GPIO_PCI_AD0, | ||
| 139 | .gpio_last = RT3883_GPIO_PCI_AD31, | ||
| 140 | }, { | ||
| 141 | .name = "pci-gpio", | ||
| 142 | .mask = 7, | ||
| 143 | .gpio_first = RT3883_GPIO_PCI_AD0, | ||
| 144 | .gpio_last = RT3883_GPIO_PCI_AD31, | ||
| 145 | }, {0} | ||
| 146 | }; | 64 | }; |
| 147 | 65 | ||
| 148 | static void rt3883_wdt_reset(void) | 66 | static void rt3883_wdt_reset(void) |
| @@ -155,17 +73,6 @@ static void rt3883_wdt_reset(void) | |||
| 155 | rt_sysc_w32(t, RT3883_SYSC_REG_SYSCFG1); | 73 | rt_sysc_w32(t, RT3883_SYSC_REG_SYSCFG1); |
| 156 | } | 74 | } |
| 157 | 75 | ||
| 158 | struct ralink_pinmux rt_gpio_pinmux = { | ||
| 159 | .mode = mode_mux, | ||
| 160 | .uart = uart_mux, | ||
| 161 | .uart_shift = RT3883_GPIO_MODE_UART0_SHIFT, | ||
| 162 | .uart_mask = RT3883_GPIO_MODE_UART0_MASK, | ||
| 163 | .wdt_reset = rt3883_wdt_reset, | ||
| 164 | .pci = pci_mux, | ||
| 165 | .pci_shift = RT3883_GPIO_MODE_PCI_SHIFT, | ||
| 166 | .pci_mask = RT3883_GPIO_MODE_PCI_MASK, | ||
| 167 | }; | ||
| 168 | |||
| 169 | void __init ralink_clk_init(void) | 76 | void __init ralink_clk_init(void) |
| 170 | { | 77 | { |
| 171 | unsigned long cpu_rate, sys_rate; | 78 | unsigned long cpu_rate, sys_rate; |
| @@ -204,6 +111,7 @@ void __init ralink_clk_init(void) | |||
| 204 | ralink_clk_add("10000b00.spi", sys_rate); | 111 | ralink_clk_add("10000b00.spi", sys_rate); |
| 205 | ralink_clk_add("10000c00.uartlite", 40000000); | 112 | ralink_clk_add("10000c00.uartlite", 40000000); |
| 206 | ralink_clk_add("10100000.ethernet", sys_rate); | 113 | ralink_clk_add("10100000.ethernet", sys_rate); |
| 114 | ralink_clk_add("10180000.wmac", 40000000); | ||
| 207 | } | 115 | } |
| 208 | 116 | ||
| 209 | void __init ralink_of_remap(void) | 117 | void __init ralink_of_remap(void) |
| @@ -243,4 +151,6 @@ void prom_soc_init(struct ralink_soc_info *soc_info) | |||
| 243 | soc_info->mem_base = RT3883_SDRAM_BASE; | 151 | soc_info->mem_base = RT3883_SDRAM_BASE; |
| 244 | soc_info->mem_size_min = RT3883_MEM_SIZE_MIN; | 152 | soc_info->mem_size_min = RT3883_MEM_SIZE_MIN; |
| 245 | soc_info->mem_size_max = RT3883_MEM_SIZE_MAX; | 153 | soc_info->mem_size_max = RT3883_MEM_SIZE_MAX; |
| 154 | |||
| 155 | rt2880_pinmux_data = rt3883_pinmux_data; | ||
| 246 | } | 156 | } |
diff --git a/arch/mips/rb532/gpio.c b/arch/mips/rb532/gpio.c index a18007613c30..5aa3df853082 100644 --- a/arch/mips/rb532/gpio.c +++ b/arch/mips/rb532/gpio.c | |||
| @@ -79,7 +79,7 @@ static inline void rb532_set_bit(unsigned bitval, | |||
| 79 | */ | 79 | */ |
| 80 | static inline int rb532_get_bit(unsigned offset, void __iomem *ioaddr) | 80 | static inline int rb532_get_bit(unsigned offset, void __iomem *ioaddr) |
| 81 | { | 81 | { |
| 82 | return (readl(ioaddr) & (1 << offset)); | 82 | return readl(ioaddr) & (1 << offset); |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | /* | 85 | /* |
diff --git a/arch/mips/rb532/prom.c b/arch/mips/rb532/prom.c index a757ded437cd..657210e767c2 100644 --- a/arch/mips/rb532/prom.c +++ b/arch/mips/rb532/prom.c | |||
| @@ -122,8 +122,8 @@ void __init prom_setup_cmdline(void) | |||
| 122 | void __init prom_init(void) | 122 | void __init prom_init(void) |
| 123 | { | 123 | { |
| 124 | struct ddr_ram __iomem *ddr; | 124 | struct ddr_ram __iomem *ddr; |
| 125 | phys_t memsize; | 125 | phys_addr_t memsize; |
| 126 | phys_t ddrbase; | 126 | phys_addr_t ddrbase; |
| 127 | 127 | ||
| 128 | ddr = ioremap_nocache(ddr_reg[0].start, | 128 | ddr = ioremap_nocache(ddr_reg[0].start, |
| 129 | ddr_reg[0].end - ddr_reg[0].start); | 129 | ddr_reg[0].end - ddr_reg[0].start); |
| @@ -133,8 +133,8 @@ void __init prom_init(void) | |||
| 133 | return; | 133 | return; |
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | ddrbase = (phys_t)&ddr->ddrbase; | 136 | ddrbase = (phys_addr_t)&ddr->ddrbase; |
| 137 | memsize = (phys_t)&ddr->ddrmask; | 137 | memsize = (phys_addr_t)&ddr->ddrmask; |
| 138 | memsize = 0 - memsize; | 138 | memsize = 0 - memsize; |
| 139 | 139 | ||
| 140 | prom_setup_cmdline(); | 140 | prom_setup_cmdline(); |
diff --git a/arch/mips/sgi-ip22/ip22-mc.c b/arch/mips/sgi-ip22/ip22-mc.c index 7cec0a4e527d..6b009c45abed 100644 --- a/arch/mips/sgi-ip22/ip22-mc.c +++ b/arch/mips/sgi-ip22/ip22-mc.c | |||
| @@ -24,14 +24,12 @@ EXPORT_SYMBOL(sgimc); | |||
| 24 | 24 | ||
| 25 | static inline unsigned long get_bank_addr(unsigned int memconfig) | 25 | static inline unsigned long get_bank_addr(unsigned int memconfig) |
| 26 | { | 26 | { |
| 27 | return ((memconfig & SGIMC_MCONFIG_BASEADDR) << | 27 | return (memconfig & SGIMC_MCONFIG_BASEADDR) << ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 24 : 22); |
| 28 | ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 24 : 22)); | ||
| 29 | } | 28 | } |
| 30 | 29 | ||
| 31 | static inline unsigned long get_bank_size(unsigned int memconfig) | 30 | static inline unsigned long get_bank_size(unsigned int memconfig) |
| 32 | { | 31 | { |
| 33 | return ((memconfig & SGIMC_MCONFIG_RMASK) + 0x0100) << | 32 | return ((memconfig & SGIMC_MCONFIG_RMASK) + 0x0100) << ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 16 : 14); |
| 34 | ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 16 : 14); | ||
| 35 | } | 33 | } |
| 36 | 34 | ||
| 37 | static inline unsigned int get_bank_config(int bank) | 35 | static inline unsigned int get_bank_config(int bank) |
diff --git a/arch/mips/sgi-ip22/ip28-berr.c b/arch/mips/sgi-ip22/ip28-berr.c index 3f47346608d7..712cc0f6a58d 100644 --- a/arch/mips/sgi-ip22/ip28-berr.c +++ b/arch/mips/sgi-ip22/ip28-berr.c | |||
| @@ -338,7 +338,7 @@ static int check_microtlb(u32 hi, u32 lo, unsigned long vaddr) | |||
| 338 | PHYS_TO_XKSEG_UNCACHED(pte); | 338 | PHYS_TO_XKSEG_UNCACHED(pte); |
| 339 | a = (a & 0x3f) << 6; /* PFN */ | 339 | a = (a & 0x3f) << 6; /* PFN */ |
| 340 | a += vaddr & ((1 << pgsz) - 1); | 340 | a += vaddr & ((1 << pgsz) - 1); |
| 341 | return (cpu_err_addr == a); | 341 | return cpu_err_addr == a; |
| 342 | } | 342 | } |
| 343 | } | 343 | } |
| 344 | } | 344 | } |
| @@ -351,7 +351,7 @@ static int check_vdma_memaddr(void) | |||
| 351 | u32 a = sgimc->maddronly; | 351 | u32 a = sgimc->maddronly; |
| 352 | 352 | ||
| 353 | if (!(sgimc->dma_ctrl & 0x100)) /* Xlate-bit clear ? */ | 353 | if (!(sgimc->dma_ctrl & 0x100)) /* Xlate-bit clear ? */ |
| 354 | return (cpu_err_addr == a); | 354 | return cpu_err_addr == a; |
| 355 | 355 | ||
| 356 | if (check_microtlb(sgimc->dtlb_hi0, sgimc->dtlb_lo0, a) || | 356 | if (check_microtlb(sgimc->dtlb_hi0, sgimc->dtlb_lo0, a) || |
| 357 | check_microtlb(sgimc->dtlb_hi1, sgimc->dtlb_lo1, a) || | 357 | check_microtlb(sgimc->dtlb_hi1, sgimc->dtlb_lo1, a) || |
| @@ -367,7 +367,7 @@ static int check_vdma_gioaddr(void) | |||
| 367 | if (gio_err_stat & GIO_ERRMASK) { | 367 | if (gio_err_stat & GIO_ERRMASK) { |
| 368 | u32 a = sgimc->gio_dma_trans; | 368 | u32 a = sgimc->gio_dma_trans; |
| 369 | a = (sgimc->gmaddronly & ~a) | (sgimc->gio_dma_sbits & a); | 369 | a = (sgimc->gmaddronly & ~a) | (sgimc->gio_dma_sbits & a); |
| 370 | return (gio_err_addr == a); | 370 | return gio_err_addr == a; |
| 371 | } | 371 | } |
| 372 | return 0; | 372 | return 0; |
| 373 | } | 373 | } |
diff --git a/arch/mips/sgi-ip27/ip27-klnuma.c b/arch/mips/sgi-ip27/ip27-klnuma.c index 7a53b1e28a93..ecbb62f339c5 100644 --- a/arch/mips/sgi-ip27/ip27-klnuma.c +++ b/arch/mips/sgi-ip27/ip27-klnuma.c | |||
| @@ -125,8 +125,7 @@ unsigned long node_getfirstfree(cnodeid_t cnode) | |||
| 125 | #endif | 125 | #endif |
| 126 | offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase; | 126 | offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase; |
| 127 | if ((cnode == 0) || (cpu_isset(cnode, ktext_repmask))) | 127 | if ((cnode == 0) || (cpu_isset(cnode, ktext_repmask))) |
| 128 | return (TO_NODE(nasid, offset) >> PAGE_SHIFT); | 128 | return TO_NODE(nasid, offset) >> PAGE_SHIFT; |
| 129 | else | 129 | else |
| 130 | return (KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >> | 130 | return KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >> PAGE_SHIFT; |
| 131 | PAGE_SHIFT); | ||
| 132 | } | 131 | } |
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c index a304bcc37e4f..0b68469e063f 100644 --- a/arch/mips/sgi-ip27/ip27-memory.c +++ b/arch/mips/sgi-ip27/ip27-memory.c | |||
| @@ -42,8 +42,7 @@ static int fine_mode; | |||
| 42 | 42 | ||
| 43 | static int is_fine_dirmode(void) | 43 | static int is_fine_dirmode(void) |
| 44 | { | 44 | { |
| 45 | return (((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK) | 45 | return ((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK) >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE; |
| 46 | >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE); | ||
| 47 | } | 46 | } |
| 48 | 47 | ||
| 49 | static hubreg_t get_region(cnodeid_t cnode) | 48 | static hubreg_t get_region(cnodeid_t cnode) |
| @@ -288,7 +287,7 @@ static unsigned long __init slot_psize_compute(cnodeid_t node, int slot) | |||
| 288 | if (size <= 128) { | 287 | if (size <= 128) { |
| 289 | if (slot % 4 == 0) { | 288 | if (slot % 4 == 0) { |
| 290 | size <<= 20; /* size in bytes */ | 289 | size <<= 20; /* size in bytes */ |
| 291 | return(size >> PAGE_SHIFT); | 290 | return size >> PAGE_SHIFT; |
| 292 | } else | 291 | } else |
| 293 | return 0; | 292 | return 0; |
| 294 | } else { | 293 | } else { |
diff --git a/arch/mips/sibyte/common/cfe.c b/arch/mips/sibyte/common/cfe.c index 588e1806a1a3..c1a11a11db7f 100644 --- a/arch/mips/sibyte/common/cfe.c +++ b/arch/mips/sibyte/common/cfe.c | |||
| @@ -38,7 +38,7 @@ | |||
| 38 | #define MAX_RAM_SIZE (~0ULL) | 38 | #define MAX_RAM_SIZE (~0ULL) |
| 39 | #else | 39 | #else |
| 40 | #ifdef CONFIG_HIGHMEM | 40 | #ifdef CONFIG_HIGHMEM |
| 41 | #ifdef CONFIG_64BIT_PHYS_ADDR | 41 | #ifdef CONFIG_PHYS_ADDR_T_64BIT |
| 42 | #define MAX_RAM_SIZE (~0ULL) | 42 | #define MAX_RAM_SIZE (~0ULL) |
| 43 | #else | 43 | #else |
| 44 | #define MAX_RAM_SIZE (0xffffffffULL) | 44 | #define MAX_RAM_SIZE (0xffffffffULL) |
| @@ -49,8 +49,8 @@ | |||
| 49 | #endif | 49 | #endif |
| 50 | 50 | ||
| 51 | #define SIBYTE_MAX_MEM_REGIONS 8 | 51 | #define SIBYTE_MAX_MEM_REGIONS 8 |
| 52 | phys_t board_mem_region_addrs[SIBYTE_MAX_MEM_REGIONS]; | 52 | phys_addr_t board_mem_region_addrs[SIBYTE_MAX_MEM_REGIONS]; |
| 53 | phys_t board_mem_region_sizes[SIBYTE_MAX_MEM_REGIONS]; | 53 | phys_addr_t board_mem_region_sizes[SIBYTE_MAX_MEM_REGIONS]; |
| 54 | unsigned int board_mem_region_count; | 54 | unsigned int board_mem_region_count; |
| 55 | 55 | ||
| 56 | int cfe_cons_handle; | 56 | int cfe_cons_handle; |
| @@ -96,7 +96,7 @@ static void __noreturn cfe_linux_halt(void) | |||
| 96 | 96 | ||
| 97 | static __init void prom_meminit(void) | 97 | static __init void prom_meminit(void) |
| 98 | { | 98 | { |
| 99 | u64 addr, size, type; /* regardless of 64BIT_PHYS_ADDR */ | 99 | u64 addr, size, type; /* regardless of PHYS_ADDR_T_64BIT */ |
| 100 | int mem_flags = 0; | 100 | int mem_flags = 0; |
| 101 | unsigned int idx; | 101 | unsigned int idx; |
| 102 | int rd_flag; | 102 | int rd_flag; |
diff --git a/arch/mips/sibyte/swarm/platform.c b/arch/mips/sibyte/swarm/platform.c index 9480c14ec66a..1cecdcf85cf1 100644 --- a/arch/mips/sibyte/swarm/platform.c +++ b/arch/mips/sibyte/swarm/platform.c | |||
| @@ -50,7 +50,7 @@ static struct platform_device swarm_pata_device = { | |||
| 50 | static int __init swarm_pata_init(void) | 50 | static int __init swarm_pata_init(void) |
| 51 | { | 51 | { |
| 52 | u8 __iomem *base; | 52 | u8 __iomem *base; |
| 53 | phys_t offset, size; | 53 | phys_addr_t offset, size; |
| 54 | struct resource *r; | 54 | struct resource *r; |
| 55 | 55 | ||
| 56 | if (!SIBYTE_HAVE_IDE) | 56 | if (!SIBYTE_HAVE_IDE) |
diff --git a/arch/mips/sibyte/swarm/rtc_m41t81.c b/arch/mips/sibyte/swarm/rtc_m41t81.c index b732600b47f5..e62466445f08 100644 --- a/arch/mips/sibyte/swarm/rtc_m41t81.c +++ b/arch/mips/sibyte/swarm/rtc_m41t81.c | |||
| @@ -109,7 +109,7 @@ static int m41t81_read(uint8_t addr) | |||
| 109 | return -1; | 109 | return -1; |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff); | 112 | return __raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff; |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | static int m41t81_write(uint8_t addr, int b) | 115 | static int m41t81_write(uint8_t addr, int b) |
| @@ -229,5 +229,5 @@ int m41t81_probe(void) | |||
| 229 | tmp = m41t81_read(M41T81REG_SC); | 229 | tmp = m41t81_read(M41T81REG_SC); |
| 230 | m41t81_write(M41T81REG_SC, tmp & 0x7f); | 230 | m41t81_write(M41T81REG_SC, tmp & 0x7f); |
| 231 | 231 | ||
| 232 | return (m41t81_read(M41T81REG_SC) != -1); | 232 | return m41t81_read(M41T81REG_SC) != -1; |
| 233 | } | 233 | } |
diff --git a/arch/mips/sibyte/swarm/rtc_xicor1241.c b/arch/mips/sibyte/swarm/rtc_xicor1241.c index 178a824b28d4..50a82c495427 100644 --- a/arch/mips/sibyte/swarm/rtc_xicor1241.c +++ b/arch/mips/sibyte/swarm/rtc_xicor1241.c | |||
| @@ -84,7 +84,7 @@ static int xicor_read(uint8_t addr) | |||
| 84 | return -1; | 84 | return -1; |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff); | 87 | return __raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff; |
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | static int xicor_write(uint8_t addr, int b) | 90 | static int xicor_write(uint8_t addr, int b) |
| @@ -206,5 +206,5 @@ unsigned long xicor_get_time(void) | |||
| 206 | 206 | ||
| 207 | int xicor_probe(void) | 207 | int xicor_probe(void) |
| 208 | { | 208 | { |
| 209 | return (xicor_read(X1241REG_SC) != -1); | 209 | return xicor_read(X1241REG_SC) != -1; |
| 210 | } | 210 | } |
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c index 3462c831d0ea..494fb0a475ac 100644 --- a/arch/mips/sibyte/swarm/setup.c +++ b/arch/mips/sibyte/swarm/setup.c | |||
| @@ -76,7 +76,7 @@ int swarm_be_handler(struct pt_regs *regs, int is_fixup) | |||
| 76 | printk("DBE physical address: %010Lx\n", | 76 | printk("DBE physical address: %010Lx\n", |
| 77 | __read_64bit_c0_register($26, 1)); | 77 | __read_64bit_c0_register($26, 1)); |
| 78 | } | 78 | } |
| 79 | return (is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL); | 79 | return is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL; |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | enum swarm_rtc_type { | 82 | enum swarm_rtc_type { |
diff --git a/arch/mips/txx9/generic/setup_tx4927.c b/arch/mips/txx9/generic/setup_tx4927.c index e714d6ce9a82..a4664cb6c1e1 100644 --- a/arch/mips/txx9/generic/setup_tx4927.c +++ b/arch/mips/txx9/generic/setup_tx4927.c | |||
| @@ -29,8 +29,8 @@ static void __init tx4927_wdr_init(void) | |||
| 29 | { | 29 | { |
| 30 | /* report watchdog reset status */ | 30 | /* report watchdog reset status */ |
| 31 | if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDRST) | 31 | if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDRST) |
| 32 | pr_warning("Watchdog reset detected at 0x%lx\n", | 32 | pr_warn("Watchdog reset detected at 0x%lx\n", |
| 33 | read_c0_errorepc()); | 33 | read_c0_errorepc()); |
| 34 | /* clear WatchDogReset (W1C) */ | 34 | /* clear WatchDogReset (W1C) */ |
| 35 | tx4927_ccfg_set(TX4927_CCFG_WDRST); | 35 | tx4927_ccfg_set(TX4927_CCFG_WDRST); |
| 36 | /* do reset on watchdog */ | 36 | /* do reset on watchdog */ |
diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c index 0a3bf2dfaba1..58cdb2aba5e1 100644 --- a/arch/mips/txx9/generic/setup_tx4938.c +++ b/arch/mips/txx9/generic/setup_tx4938.c | |||
| @@ -31,8 +31,8 @@ static void __init tx4938_wdr_init(void) | |||
| 31 | { | 31 | { |
| 32 | /* report watchdog reset status */ | 32 | /* report watchdog reset status */ |
| 33 | if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDRST) | 33 | if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDRST) |
| 34 | pr_warning("Watchdog reset detected at 0x%lx\n", | 34 | pr_warn("Watchdog reset detected at 0x%lx\n", |
| 35 | read_c0_errorepc()); | 35 | read_c0_errorepc()); |
| 36 | /* clear WatchDogReset (W1C) */ | 36 | /* clear WatchDogReset (W1C) */ |
| 37 | tx4938_ccfg_set(TX4938_CCFG_WDRST); | 37 | tx4938_ccfg_set(TX4938_CCFG_WDRST); |
| 38 | /* do reset on watchdog */ | 38 | /* do reset on watchdog */ |
diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c index b7eccbd17bf7..e3733cde50d6 100644 --- a/arch/mips/txx9/generic/setup_tx4939.c +++ b/arch/mips/txx9/generic/setup_tx4939.c | |||
| @@ -35,8 +35,8 @@ static void __init tx4939_wdr_init(void) | |||
| 35 | { | 35 | { |
| 36 | /* report watchdog reset status */ | 36 | /* report watchdog reset status */ |
| 37 | if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDRST) | 37 | if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDRST) |
| 38 | pr_warning("Watchdog reset detected at 0x%lx\n", | 38 | pr_warn("Watchdog reset detected at 0x%lx\n", |
| 39 | read_c0_errorepc()); | 39 | read_c0_errorepc()); |
| 40 | /* clear WatchDogReset (W1C) */ | 40 | /* clear WatchDogReset (W1C) */ |
| 41 | tx4939_ccfg_set(TX4939_CCFG_WDRST); | 41 | tx4939_ccfg_set(TX4939_CCFG_WDRST); |
| 42 | /* do reset on watchdog */ | 42 | /* do reset on watchdog */ |
diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c index 5ec69c3d409d..04faf6df959f 100644 --- a/drivers/bcma/driver_mips.c +++ b/drivers/bcma/driver_mips.c | |||
| @@ -20,6 +20,9 @@ | |||
| 20 | #include <linux/serial_core.h> | 20 | #include <linux/serial_core.h> |
| 21 | #include <linux/serial_reg.h> | 21 | #include <linux/serial_reg.h> |
| 22 | #include <linux/time.h> | 22 | #include <linux/time.h> |
| 23 | #ifdef CONFIG_BCM47XX | ||
| 24 | #include <bcm47xx_nvram.h> | ||
| 25 | #endif | ||
| 23 | 26 | ||
| 24 | enum bcma_boot_dev { | 27 | enum bcma_boot_dev { |
| 25 | BCMA_BOOT_DEV_UNK = 0, | 28 | BCMA_BOOT_DEV_UNK = 0, |
| @@ -316,10 +319,16 @@ static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore) | |||
| 316 | switch (boot_dev) { | 319 | switch (boot_dev) { |
| 317 | case BCMA_BOOT_DEV_PARALLEL: | 320 | case BCMA_BOOT_DEV_PARALLEL: |
| 318 | case BCMA_BOOT_DEV_SERIAL: | 321 | case BCMA_BOOT_DEV_SERIAL: |
| 319 | /* TODO: Init NVRAM using BCMA_SOC_FLASH2 window */ | 322 | #ifdef CONFIG_BCM47XX |
| 323 | bcm47xx_nvram_init_from_mem(BCMA_SOC_FLASH2, | ||
| 324 | BCMA_SOC_FLASH2_SZ); | ||
| 325 | #endif | ||
| 320 | break; | 326 | break; |
| 321 | case BCMA_BOOT_DEV_NAND: | 327 | case BCMA_BOOT_DEV_NAND: |
| 322 | /* TODO: Init NVRAM using BCMA_SOC_FLASH1 window */ | 328 | #ifdef CONFIG_BCM47XX |
| 329 | bcm47xx_nvram_init_from_mem(BCMA_SOC_FLASH1, | ||
| 330 | BCMA_SOC_FLASH1_SZ); | ||
| 331 | #endif | ||
| 323 | break; | 332 | break; |
| 324 | default: | 333 | default: |
| 325 | break; | 334 | break; |
diff --git a/drivers/clk/clk-ls1x.c b/drivers/clk/clk-ls1x.c index f20b750235f6..ca80103ac188 100644 --- a/drivers/clk/clk-ls1x.c +++ b/drivers/clk/clk-ls1x.c | |||
| @@ -15,7 +15,8 @@ | |||
| 15 | 15 | ||
| 16 | #include <loongson1.h> | 16 | #include <loongson1.h> |
| 17 | 17 | ||
| 18 | #define OSC 33 | 18 | #define OSC (33 * 1000000) |
| 19 | #define DIV_APB 2 | ||
| 19 | 20 | ||
| 20 | static DEFINE_SPINLOCK(_lock); | 21 | static DEFINE_SPINLOCK(_lock); |
| 21 | 22 | ||
| @@ -29,13 +30,12 @@ static void ls1x_pll_clk_disable(struct clk_hw *hw) | |||
| 29 | } | 30 | } |
| 30 | 31 | ||
| 31 | static unsigned long ls1x_pll_recalc_rate(struct clk_hw *hw, | 32 | static unsigned long ls1x_pll_recalc_rate(struct clk_hw *hw, |
| 32 | unsigned long parent_rate) | 33 | unsigned long parent_rate) |
| 33 | { | 34 | { |
| 34 | u32 pll, rate; | 35 | u32 pll, rate; |
| 35 | 36 | ||
| 36 | pll = __raw_readl(LS1X_CLK_PLL_FREQ); | 37 | pll = __raw_readl(LS1X_CLK_PLL_FREQ); |
| 37 | rate = ((12 + (pll & 0x3f)) * 1000000) + | 38 | rate = 12 + (pll & 0x3f) + (((pll >> 8) & 0x3ff) >> 10); |
| 38 | ((((pll >> 8) & 0x3ff) * 1000000) >> 10); | ||
| 39 | rate *= OSC; | 39 | rate *= OSC; |
| 40 | rate >>= 1; | 40 | rate >>= 1; |
| 41 | 41 | ||
| @@ -48,8 +48,10 @@ static const struct clk_ops ls1x_pll_clk_ops = { | |||
| 48 | .recalc_rate = ls1x_pll_recalc_rate, | 48 | .recalc_rate = ls1x_pll_recalc_rate, |
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | static struct clk * __init clk_register_pll(struct device *dev, | 51 | static struct clk *__init clk_register_pll(struct device *dev, |
| 52 | const char *name, const char *parent_name, unsigned long flags) | 52 | const char *name, |
| 53 | const char *parent_name, | ||
| 54 | unsigned long flags) | ||
| 53 | { | 55 | { |
| 54 | struct clk_hw *hw; | 56 | struct clk_hw *hw; |
| 55 | struct clk *clk; | 57 | struct clk *clk; |
| @@ -78,34 +80,83 @@ static struct clk * __init clk_register_pll(struct device *dev, | |||
| 78 | return clk; | 80 | return clk; |
| 79 | } | 81 | } |
| 80 | 82 | ||
| 83 | static const char const *cpu_parents[] = { "cpu_clk_div", "osc_33m_clk", }; | ||
| 84 | static const char const *ahb_parents[] = { "ahb_clk_div", "osc_33m_clk", }; | ||
| 85 | static const char const *dc_parents[] = { "dc_clk_div", "osc_33m_clk", }; | ||
| 86 | |||
| 81 | void __init ls1x_clk_init(void) | 87 | void __init ls1x_clk_init(void) |
| 82 | { | 88 | { |
| 83 | struct clk *clk; | 89 | struct clk *clk; |
| 84 | 90 | ||
| 85 | clk = clk_register_pll(NULL, "pll_clk", NULL, CLK_IS_ROOT); | 91 | clk = clk_register_fixed_rate(NULL, "osc_33m_clk", NULL, CLK_IS_ROOT, |
| 86 | clk_prepare_enable(clk); | 92 | OSC); |
| 87 | 93 | clk_register_clkdev(clk, "osc_33m_clk", NULL); | |
| 88 | clk = clk_register_divider(NULL, "cpu_clk", "pll_clk", | 94 | |
| 89 | CLK_SET_RATE_PARENT, LS1X_CLK_PLL_DIV, DIV_CPU_SHIFT, | 95 | /* clock derived from 33 MHz OSC clk */ |
| 90 | DIV_CPU_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock); | 96 | clk = clk_register_pll(NULL, "pll_clk", "osc_33m_clk", 0); |
| 91 | clk_prepare_enable(clk); | 97 | clk_register_clkdev(clk, "pll_clk", NULL); |
| 92 | clk_register_clkdev(clk, "cpu", NULL); | 98 | |
| 93 | 99 | /* clock derived from PLL clk */ | |
| 94 | clk = clk_register_divider(NULL, "dc_clk", "pll_clk", | 100 | /* _____ |
| 95 | CLK_SET_RATE_PARENT, LS1X_CLK_PLL_DIV, DIV_DC_SHIFT, | 101 | * _______________________| | |
| 96 | DIV_DC_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock); | 102 | * OSC ___/ | MUX |___ CPU CLK |
| 97 | clk_prepare_enable(clk); | 103 | * \___ PLL ___ CPU DIV ___| | |
| 98 | clk_register_clkdev(clk, "dc", NULL); | 104 | * |_____| |
| 99 | 105 | */ | |
| 100 | clk = clk_register_divider(NULL, "ahb_clk", "pll_clk", | 106 | clk = clk_register_divider(NULL, "cpu_clk_div", "pll_clk", |
| 101 | CLK_SET_RATE_PARENT, LS1X_CLK_PLL_DIV, DIV_DDR_SHIFT, | 107 | CLK_GET_RATE_NOCACHE, LS1X_CLK_PLL_DIV, |
| 102 | DIV_DDR_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock); | 108 | DIV_CPU_SHIFT, DIV_CPU_WIDTH, |
| 103 | clk_prepare_enable(clk); | 109 | CLK_DIVIDER_ONE_BASED | |
| 104 | clk_register_clkdev(clk, "ahb", NULL); | 110 | CLK_DIVIDER_ROUND_CLOSEST, &_lock); |
| 111 | clk_register_clkdev(clk, "cpu_clk_div", NULL); | ||
| 112 | clk = clk_register_mux(NULL, "cpu_clk", cpu_parents, | ||
| 113 | ARRAY_SIZE(cpu_parents), | ||
| 114 | CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV, | ||
| 115 | BYPASS_CPU_SHIFT, BYPASS_CPU_WIDTH, 0, &_lock); | ||
| 116 | clk_register_clkdev(clk, "cpu_clk", NULL); | ||
| 117 | |||
| 118 | /* _____ | ||
| 119 | * _______________________| | | ||
| 120 | * OSC ___/ | MUX |___ DC CLK | ||
| 121 | * \___ PLL ___ DC DIV ___| | | ||
| 122 | * |_____| | ||
| 123 | */ | ||
| 124 | clk = clk_register_divider(NULL, "dc_clk_div", "pll_clk", | ||
| 125 | 0, LS1X_CLK_PLL_DIV, DIV_DC_SHIFT, | ||
| 126 | DIV_DC_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock); | ||
| 127 | clk_register_clkdev(clk, "dc_clk_div", NULL); | ||
| 128 | clk = clk_register_mux(NULL, "dc_clk", dc_parents, | ||
| 129 | ARRAY_SIZE(dc_parents), | ||
| 130 | CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV, | ||
| 131 | BYPASS_DC_SHIFT, BYPASS_DC_WIDTH, 0, &_lock); | ||
| 132 | clk_register_clkdev(clk, "dc_clk", NULL); | ||
| 133 | |||
| 134 | /* _____ | ||
| 135 | * _______________________| | | ||
| 136 | * OSC ___/ | MUX |___ DDR CLK | ||
| 137 | * \___ PLL ___ DDR DIV ___| | | ||
| 138 | * |_____| | ||
| 139 | */ | ||
| 140 | clk = clk_register_divider(NULL, "ahb_clk_div", "pll_clk", | ||
| 141 | 0, LS1X_CLK_PLL_DIV, DIV_DDR_SHIFT, | ||
| 142 | DIV_DDR_WIDTH, CLK_DIVIDER_ONE_BASED, | ||
| 143 | &_lock); | ||
| 144 | clk_register_clkdev(clk, "ahb_clk_div", NULL); | ||
| 145 | clk = clk_register_mux(NULL, "ahb_clk", ahb_parents, | ||
| 146 | ARRAY_SIZE(ahb_parents), | ||
| 147 | CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV, | ||
| 148 | BYPASS_DDR_SHIFT, BYPASS_DDR_WIDTH, 0, &_lock); | ||
| 149 | clk_register_clkdev(clk, "ahb_clk", NULL); | ||
| 105 | clk_register_clkdev(clk, "stmmaceth", NULL); | 150 | clk_register_clkdev(clk, "stmmaceth", NULL); |
| 106 | 151 | ||
| 107 | clk = clk_register_fixed_factor(NULL, "apb_clk", "ahb_clk", 0, 1, 2); | 152 | /* clock derived from AHB clk */ |
| 108 | clk_prepare_enable(clk); | 153 | /* APB clk is always half of the AHB clk */ |
| 109 | clk_register_clkdev(clk, "apb", NULL); | 154 | clk = clk_register_fixed_factor(NULL, "apb_clk", "ahb_clk", 0, 1, |
| 155 | DIV_APB); | ||
| 156 | clk_register_clkdev(clk, "apb_clk", NULL); | ||
| 157 | clk_register_clkdev(clk, "ls1x_i2c", NULL); | ||
| 158 | clk_register_clkdev(clk, "ls1x_pwmtimer", NULL); | ||
| 159 | clk_register_clkdev(clk, "ls1x_spi", NULL); | ||
| 160 | clk_register_clkdev(clk, "ls1x_wdt", NULL); | ||
| 110 | clk_register_clkdev(clk, "serial8250", NULL); | 161 | clk_register_clkdev(clk, "serial8250", NULL); |
| 111 | } | 162 | } |
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index f657a48d20eb..fc01ec27d3c8 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig | |||
| @@ -224,4 +224,9 @@ config CLKSRC_VERSATILE | |||
| 224 | ARM Versatile, RealView and Versatile Express reference | 224 | ARM Versatile, RealView and Versatile Express reference |
| 225 | platforms. | 225 | platforms. |
| 226 | 226 | ||
| 227 | config CLKSRC_MIPS_GIC | ||
| 228 | bool | ||
| 229 | depends on MIPS_GIC | ||
| 230 | select CLKSRC_OF | ||
| 231 | |||
| 227 | endmenu | 232 | endmenu |
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index fae0435cc23d..94d90b24b56b 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile | |||
| @@ -47,3 +47,4 @@ obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST) += dummy_timer.o | |||
| 47 | obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o | 47 | obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o |
| 48 | obj-$(CONFIG_ARCH_INTEGRATOR_AP) += timer-integrator-ap.o | 48 | obj-$(CONFIG_ARCH_INTEGRATOR_AP) += timer-integrator-ap.o |
| 49 | obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o | 49 | obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o |
| 50 | obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o | ||
diff --git a/drivers/clocksource/mips-gic-timer.c b/drivers/clocksource/mips-gic-timer.c new file mode 100644 index 000000000000..3bd31b1321f6 --- /dev/null +++ b/drivers/clocksource/mips-gic-timer.c | |||
| @@ -0,0 +1,166 @@ | |||
| 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 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. | ||
| 7 | */ | ||
| 8 | #include <linux/clockchips.h> | ||
| 9 | #include <linux/cpu.h> | ||
| 10 | #include <linux/init.h> | ||
| 11 | #include <linux/interrupt.h> | ||
| 12 | #include <linux/irqchip/mips-gic.h> | ||
| 13 | #include <linux/notifier.h> | ||
| 14 | #include <linux/of_irq.h> | ||
| 15 | #include <linux/percpu.h> | ||
| 16 | #include <linux/smp.h> | ||
| 17 | #include <linux/time.h> | ||
| 18 | |||
| 19 | static DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); | ||
| 20 | static int gic_timer_irq; | ||
| 21 | static unsigned int gic_frequency; | ||
| 22 | |||
| 23 | static int gic_next_event(unsigned long delta, struct clock_event_device *evt) | ||
| 24 | { | ||
| 25 | u64 cnt; | ||
| 26 | int res; | ||
| 27 | |||
| 28 | cnt = gic_read_count(); | ||
| 29 | cnt += (u64)delta; | ||
| 30 | gic_write_cpu_compare(cnt, cpumask_first(evt->cpumask)); | ||
| 31 | res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0; | ||
| 32 | return res; | ||
| 33 | } | ||
| 34 | |||
| 35 | static void gic_set_clock_mode(enum clock_event_mode mode, | ||
| 36 | struct clock_event_device *evt) | ||
| 37 | { | ||
| 38 | /* Nothing to do ... */ | ||
| 39 | } | ||
| 40 | |||
| 41 | static irqreturn_t gic_compare_interrupt(int irq, void *dev_id) | ||
| 42 | { | ||
| 43 | struct clock_event_device *cd = dev_id; | ||
| 44 | |||
| 45 | gic_write_compare(gic_read_compare()); | ||
| 46 | cd->event_handler(cd); | ||
| 47 | return IRQ_HANDLED; | ||
| 48 | } | ||
| 49 | |||
| 50 | struct irqaction gic_compare_irqaction = { | ||
| 51 | .handler = gic_compare_interrupt, | ||
| 52 | .percpu_dev_id = &gic_clockevent_device, | ||
| 53 | .flags = IRQF_PERCPU | IRQF_TIMER, | ||
| 54 | .name = "timer", | ||
| 55 | }; | ||
| 56 | |||
| 57 | static void gic_clockevent_cpu_init(struct clock_event_device *cd) | ||
| 58 | { | ||
| 59 | unsigned int cpu = smp_processor_id(); | ||
| 60 | |||
| 61 | cd->name = "MIPS GIC"; | ||
| 62 | cd->features = CLOCK_EVT_FEAT_ONESHOT | | ||
| 63 | CLOCK_EVT_FEAT_C3STOP; | ||
| 64 | |||
| 65 | cd->rating = 350; | ||
| 66 | cd->irq = gic_timer_irq; | ||
| 67 | cd->cpumask = cpumask_of(cpu); | ||
| 68 | cd->set_next_event = gic_next_event; | ||
| 69 | cd->set_mode = gic_set_clock_mode; | ||
| 70 | |||
| 71 | clockevents_config_and_register(cd, gic_frequency, 0x300, 0x7fffffff); | ||
| 72 | |||
| 73 | enable_percpu_irq(gic_timer_irq, IRQ_TYPE_NONE); | ||
| 74 | } | ||
| 75 | |||
| 76 | static void gic_clockevent_cpu_exit(struct clock_event_device *cd) | ||
| 77 | { | ||
| 78 | disable_percpu_irq(gic_timer_irq); | ||
| 79 | } | ||
| 80 | |||
| 81 | static int gic_cpu_notifier(struct notifier_block *nb, unsigned long action, | ||
| 82 | void *data) | ||
| 83 | { | ||
| 84 | switch (action & ~CPU_TASKS_FROZEN) { | ||
| 85 | case CPU_STARTING: | ||
| 86 | gic_clockevent_cpu_init(this_cpu_ptr(&gic_clockevent_device)); | ||
| 87 | break; | ||
| 88 | case CPU_DYING: | ||
| 89 | gic_clockevent_cpu_exit(this_cpu_ptr(&gic_clockevent_device)); | ||
| 90 | break; | ||
| 91 | } | ||
| 92 | |||
| 93 | return NOTIFY_OK; | ||
| 94 | } | ||
| 95 | |||
| 96 | static struct notifier_block gic_cpu_nb = { | ||
| 97 | .notifier_call = gic_cpu_notifier, | ||
| 98 | }; | ||
| 99 | |||
| 100 | static int gic_clockevent_init(void) | ||
| 101 | { | ||
| 102 | if (!cpu_has_counter || !gic_frequency) | ||
| 103 | return -ENXIO; | ||
| 104 | |||
| 105 | setup_percpu_irq(gic_timer_irq, &gic_compare_irqaction); | ||
| 106 | |||
| 107 | register_cpu_notifier(&gic_cpu_nb); | ||
| 108 | |||
| 109 | gic_clockevent_cpu_init(this_cpu_ptr(&gic_clockevent_device)); | ||
| 110 | |||
| 111 | return 0; | ||
| 112 | } | ||
| 113 | |||
| 114 | static cycle_t gic_hpt_read(struct clocksource *cs) | ||
| 115 | { | ||
| 116 | return gic_read_count(); | ||
| 117 | } | ||
| 118 | |||
| 119 | static struct clocksource gic_clocksource = { | ||
| 120 | .name = "GIC", | ||
| 121 | .read = gic_hpt_read, | ||
| 122 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
| 123 | }; | ||
| 124 | |||
| 125 | static void __init __gic_clocksource_init(void) | ||
| 126 | { | ||
| 127 | /* Set clocksource mask. */ | ||
| 128 | gic_clocksource.mask = CLOCKSOURCE_MASK(gic_get_count_width()); | ||
| 129 | |||
| 130 | /* Calculate a somewhat reasonable rating value. */ | ||
| 131 | gic_clocksource.rating = 200 + gic_frequency / 10000000; | ||
| 132 | |||
| 133 | clocksource_register_hz(&gic_clocksource, gic_frequency); | ||
| 134 | |||
| 135 | gic_clockevent_init(); | ||
| 136 | } | ||
| 137 | |||
| 138 | void __init gic_clocksource_init(unsigned int frequency) | ||
| 139 | { | ||
| 140 | gic_frequency = frequency; | ||
| 141 | gic_timer_irq = MIPS_GIC_IRQ_BASE + | ||
| 142 | GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE); | ||
| 143 | |||
| 144 | __gic_clocksource_init(); | ||
| 145 | } | ||
| 146 | |||
| 147 | static void __init gic_clocksource_of_init(struct device_node *node) | ||
| 148 | { | ||
| 149 | if (WARN_ON(!gic_present || !node->parent || | ||
| 150 | !of_device_is_compatible(node->parent, "mti,gic"))) | ||
| 151 | return; | ||
| 152 | |||
| 153 | if (of_property_read_u32(node, "clock-frequency", &gic_frequency)) { | ||
| 154 | pr_err("GIC frequency not specified.\n"); | ||
| 155 | return; | ||
| 156 | } | ||
| 157 | gic_timer_irq = irq_of_parse_and_map(node, 0); | ||
| 158 | if (!gic_timer_irq) { | ||
| 159 | pr_err("GIC timer IRQ not specified.\n"); | ||
| 160 | return; | ||
| 161 | } | ||
| 162 | |||
| 163 | __gic_clocksource_init(); | ||
| 164 | } | ||
| 165 | CLOCKSOURCE_OF_DECLARE(mips_gic_timer, "mti,gic-timer", | ||
| 166 | gic_clocksource_of_init); | ||
diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c index 17686caf64d5..0659ec9c4488 100644 --- a/drivers/dma/txx9dmac.c +++ b/drivers/dma/txx9dmac.c | |||
| @@ -76,7 +76,7 @@ static void channel64_write_CHAR(const struct txx9dmac_chan *dc, dma_addr_t val) | |||
| 76 | 76 | ||
| 77 | static void channel64_clear_CHAR(const struct txx9dmac_chan *dc) | 77 | static void channel64_clear_CHAR(const struct txx9dmac_chan *dc) |
| 78 | { | 78 | { |
| 79 | #if defined(CONFIG_32BIT) && !defined(CONFIG_64BIT_PHYS_ADDR) | 79 | #if defined(CONFIG_32BIT) && !defined(CONFIG_PHYS_ADDR_T_64BIT) |
| 80 | channel64_writel(dc, CHAR, 0); | 80 | channel64_writel(dc, CHAR, 0); |
| 81 | channel64_writel(dc, __pad_CHAR, 0); | 81 | channel64_writel(dc, __pad_CHAR, 0); |
| 82 | #else | 82 | #else |
diff --git a/drivers/dma/txx9dmac.h b/drivers/dma/txx9dmac.h index f5a760598882..f6517b928bab 100644 --- a/drivers/dma/txx9dmac.h +++ b/drivers/dma/txx9dmac.h | |||
| @@ -67,7 +67,7 @@ static inline bool txx9_dma_have_SMPCHN(void) | |||
| 67 | 67 | ||
| 68 | /* Hardware register definitions. */ | 68 | /* Hardware register definitions. */ |
| 69 | struct txx9dmac_cregs { | 69 | struct txx9dmac_cregs { |
| 70 | #if defined(CONFIG_32BIT) && !defined(CONFIG_64BIT_PHYS_ADDR) | 70 | #if defined(CONFIG_32BIT) && !defined(CONFIG_PHYS_ADDR_T_64BIT) |
| 71 | TXX9_DMA_REG32(CHAR); /* Chain Address Register */ | 71 | TXX9_DMA_REG32(CHAR); /* Chain Address Register */ |
| 72 | #else | 72 | #else |
| 73 | u64 CHAR; /* Chain Address Register */ | 73 | u64 CHAR; /* Chain Address Register */ |
| @@ -201,7 +201,7 @@ static inline bool is_dmac64(const struct txx9dmac_chan *dc) | |||
| 201 | #ifdef TXX9_DMA_USE_SIMPLE_CHAIN | 201 | #ifdef TXX9_DMA_USE_SIMPLE_CHAIN |
| 202 | /* Hardware descriptor definition. (for simple-chain) */ | 202 | /* Hardware descriptor definition. (for simple-chain) */ |
| 203 | struct txx9dmac_hwdesc { | 203 | struct txx9dmac_hwdesc { |
| 204 | #if defined(CONFIG_32BIT) && !defined(CONFIG_64BIT_PHYS_ADDR) | 204 | #if defined(CONFIG_32BIT) && !defined(CONFIG_PHYS_ADDR_T_64BIT) |
| 205 | TXX9_DMA_REG32(CHAR); | 205 | TXX9_DMA_REG32(CHAR); |
| 206 | #else | 206 | #else |
| 207 | u64 CHAR; | 207 | u64 CHAR; |
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 9efe5f10f97b..e12cb23d786c 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig | |||
| @@ -130,3 +130,7 @@ config KEYSTONE_IRQ | |||
| 130 | help | 130 | help |
| 131 | Support for Texas Instruments Keystone 2 IRQ controller IP which | 131 | Support for Texas Instruments Keystone 2 IRQ controller IP which |
| 132 | is part of the Keystone 2 IPC mechanism | 132 | is part of the Keystone 2 IPC mechanism |
| 133 | |||
| 134 | config MIPS_GIC | ||
| 135 | bool | ||
| 136 | select MIPS_CM | ||
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index f0909d05eae3..4954a314c31e 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile | |||
| @@ -38,3 +38,4 @@ obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o | |||
| 38 | obj-$(CONFIG_BCM7120_L2_IRQ) += irq-bcm7120-l2.o | 38 | obj-$(CONFIG_BCM7120_L2_IRQ) += irq-bcm7120-l2.o |
| 39 | obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o | 39 | obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o |
| 40 | obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o | 40 | obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o |
| 41 | obj-$(CONFIG_MIPS_GIC) += irq-mips-gic.o | ||
diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c new file mode 100644 index 000000000000..2b0468e3df6a --- /dev/null +++ b/drivers/irqchip/irq-mips-gic.c | |||
| @@ -0,0 +1,789 @@ | |||
| 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 | * Copyright (C) 2008 Ralf Baechle (ralf@linux-mips.org) | ||
| 7 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. | ||
| 8 | */ | ||
| 9 | #include <linux/bitmap.h> | ||
| 10 | #include <linux/clocksource.h> | ||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/interrupt.h> | ||
| 13 | #include <linux/irq.h> | ||
| 14 | #include <linux/irqchip/mips-gic.h> | ||
| 15 | #include <linux/of_address.h> | ||
| 16 | #include <linux/sched.h> | ||
| 17 | #include <linux/smp.h> | ||
| 18 | |||
| 19 | #include <asm/mips-cm.h> | ||
| 20 | #include <asm/setup.h> | ||
| 21 | #include <asm/traps.h> | ||
| 22 | |||
| 23 | #include <dt-bindings/interrupt-controller/mips-gic.h> | ||
| 24 | |||
| 25 | #include "irqchip.h" | ||
| 26 | |||
| 27 | unsigned int gic_present; | ||
| 28 | |||
| 29 | struct gic_pcpu_mask { | ||
| 30 | DECLARE_BITMAP(pcpu_mask, GIC_MAX_INTRS); | ||
| 31 | }; | ||
| 32 | |||
| 33 | static void __iomem *gic_base; | ||
| 34 | static struct gic_pcpu_mask pcpu_masks[NR_CPUS]; | ||
| 35 | static DEFINE_SPINLOCK(gic_lock); | ||
| 36 | static struct irq_domain *gic_irq_domain; | ||
| 37 | static int gic_shared_intrs; | ||
| 38 | static int gic_vpes; | ||
| 39 | static unsigned int gic_cpu_pin; | ||
| 40 | static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller; | ||
| 41 | |||
| 42 | static void __gic_irq_dispatch(void); | ||
| 43 | |||
| 44 | static inline unsigned int gic_read(unsigned int reg) | ||
| 45 | { | ||
| 46 | return __raw_readl(gic_base + reg); | ||
| 47 | } | ||
| 48 | |||
| 49 | static inline void gic_write(unsigned int reg, unsigned int val) | ||
| 50 | { | ||
| 51 | __raw_writel(val, gic_base + reg); | ||
| 52 | } | ||
| 53 | |||
| 54 | static inline void gic_update_bits(unsigned int reg, unsigned int mask, | ||
| 55 | unsigned int val) | ||
| 56 | { | ||
| 57 | unsigned int regval; | ||
| 58 | |||
| 59 | regval = gic_read(reg); | ||
| 60 | regval &= ~mask; | ||
| 61 | regval |= val; | ||
| 62 | gic_write(reg, regval); | ||
| 63 | } | ||
| 64 | |||
| 65 | static inline void gic_reset_mask(unsigned int intr) | ||
| 66 | { | ||
| 67 | gic_write(GIC_REG(SHARED, GIC_SH_RMASK) + GIC_INTR_OFS(intr), | ||
| 68 | 1 << GIC_INTR_BIT(intr)); | ||
| 69 | } | ||
| 70 | |||
| 71 | static inline void gic_set_mask(unsigned int intr) | ||
| 72 | { | ||
| 73 | gic_write(GIC_REG(SHARED, GIC_SH_SMASK) + GIC_INTR_OFS(intr), | ||
| 74 | 1 << GIC_INTR_BIT(intr)); | ||
| 75 | } | ||
| 76 | |||
| 77 | static inline void gic_set_polarity(unsigned int intr, unsigned int pol) | ||
| 78 | { | ||
| 79 | gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_POLARITY) + | ||
| 80 | GIC_INTR_OFS(intr), 1 << GIC_INTR_BIT(intr), | ||
| 81 | pol << GIC_INTR_BIT(intr)); | ||
| 82 | } | ||
| 83 | |||
| 84 | static inline void gic_set_trigger(unsigned int intr, unsigned int trig) | ||
| 85 | { | ||
| 86 | gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_TRIGGER) + | ||
| 87 | GIC_INTR_OFS(intr), 1 << GIC_INTR_BIT(intr), | ||
| 88 | trig << GIC_INTR_BIT(intr)); | ||
| 89 | } | ||
| 90 | |||
| 91 | static inline void gic_set_dual_edge(unsigned int intr, unsigned int dual) | ||
| 92 | { | ||
| 93 | gic_update_bits(GIC_REG(SHARED, GIC_SH_SET_DUAL) + GIC_INTR_OFS(intr), | ||
| 94 | 1 << GIC_INTR_BIT(intr), | ||
| 95 | dual << GIC_INTR_BIT(intr)); | ||
| 96 | } | ||
| 97 | |||
| 98 | static inline void gic_map_to_pin(unsigned int intr, unsigned int pin) | ||
| 99 | { | ||
| 100 | gic_write(GIC_REG(SHARED, GIC_SH_INTR_MAP_TO_PIN_BASE) + | ||
| 101 | GIC_SH_MAP_TO_PIN(intr), GIC_MAP_TO_PIN_MSK | pin); | ||
| 102 | } | ||
| 103 | |||
| 104 | static inline void gic_map_to_vpe(unsigned int intr, unsigned int vpe) | ||
| 105 | { | ||
| 106 | gic_write(GIC_REG(SHARED, GIC_SH_INTR_MAP_TO_VPE_BASE) + | ||
| 107 | GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe), | ||
| 108 | GIC_SH_MAP_TO_VPE_REG_BIT(vpe)); | ||
| 109 | } | ||
| 110 | |||
| 111 | #ifdef CONFIG_CLKSRC_MIPS_GIC | ||
| 112 | cycle_t gic_read_count(void) | ||
| 113 | { | ||
| 114 | unsigned int hi, hi2, lo; | ||
| 115 | |||
| 116 | do { | ||
| 117 | hi = gic_read(GIC_REG(SHARED, GIC_SH_COUNTER_63_32)); | ||
| 118 | lo = gic_read(GIC_REG(SHARED, GIC_SH_COUNTER_31_00)); | ||
| 119 | hi2 = gic_read(GIC_REG(SHARED, GIC_SH_COUNTER_63_32)); | ||
| 120 | } while (hi2 != hi); | ||
| 121 | |||
| 122 | return (((cycle_t) hi) << 32) + lo; | ||
| 123 | } | ||
| 124 | |||
| 125 | unsigned int gic_get_count_width(void) | ||
| 126 | { | ||
| 127 | unsigned int bits, config; | ||
| 128 | |||
| 129 | config = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG)); | ||
| 130 | bits = 32 + 4 * ((config & GIC_SH_CONFIG_COUNTBITS_MSK) >> | ||
| 131 | GIC_SH_CONFIG_COUNTBITS_SHF); | ||
| 132 | |||
| 133 | return bits; | ||
| 134 | } | ||
| 135 | |||
| 136 | void gic_write_compare(cycle_t cnt) | ||
| 137 | { | ||
| 138 | gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI), | ||
| 139 | (int)(cnt >> 32)); | ||
| 140 | gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO), | ||
| 141 | (int)(cnt & 0xffffffff)); | ||
| 142 | } | ||
| 143 | |||
| 144 | void gic_write_cpu_compare(cycle_t cnt, int cpu) | ||
| 145 | { | ||
| 146 | unsigned long flags; | ||
| 147 | |||
| 148 | local_irq_save(flags); | ||
| 149 | |||
| 150 | gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), cpu); | ||
| 151 | gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_HI), | ||
| 152 | (int)(cnt >> 32)); | ||
| 153 | gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_LO), | ||
| 154 | (int)(cnt & 0xffffffff)); | ||
| 155 | |||
| 156 | local_irq_restore(flags); | ||
| 157 | } | ||
| 158 | |||
| 159 | cycle_t gic_read_compare(void) | ||
| 160 | { | ||
| 161 | unsigned int hi, lo; | ||
| 162 | |||
| 163 | hi = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI)); | ||
| 164 | lo = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO)); | ||
| 165 | |||
| 166 | return (((cycle_t) hi) << 32) + lo; | ||
| 167 | } | ||
| 168 | #endif | ||
| 169 | |||
| 170 | static bool gic_local_irq_is_routable(int intr) | ||
| 171 | { | ||
| 172 | u32 vpe_ctl; | ||
| 173 | |||
| 174 | /* All local interrupts are routable in EIC mode. */ | ||
| 175 | if (cpu_has_veic) | ||
| 176 | return true; | ||
| 177 | |||
| 178 | vpe_ctl = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_CTL)); | ||
| 179 | switch (intr) { | ||
| 180 | case GIC_LOCAL_INT_TIMER: | ||
| 181 | return vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK; | ||
| 182 | case GIC_LOCAL_INT_PERFCTR: | ||
| 183 | return vpe_ctl & GIC_VPE_CTL_PERFCNT_RTBL_MSK; | ||
| 184 | case GIC_LOCAL_INT_FDC: | ||
| 185 | return vpe_ctl & GIC_VPE_CTL_FDC_RTBL_MSK; | ||
| 186 | case GIC_LOCAL_INT_SWINT0: | ||
| 187 | case GIC_LOCAL_INT_SWINT1: | ||
| 188 | return vpe_ctl & GIC_VPE_CTL_SWINT_RTBL_MSK; | ||
| 189 | default: | ||
| 190 | return true; | ||
| 191 | } | ||
| 192 | } | ||
| 193 | |||
| 194 | unsigned int gic_get_timer_pending(void) | ||
| 195 | { | ||
| 196 | unsigned int vpe_pending; | ||
| 197 | |||
| 198 | vpe_pending = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_PEND)); | ||
| 199 | return vpe_pending & GIC_VPE_PEND_TIMER_MSK; | ||
| 200 | } | ||
| 201 | |||
| 202 | static void gic_bind_eic_interrupt(int irq, int set) | ||
| 203 | { | ||
| 204 | /* Convert irq vector # to hw int # */ | ||
| 205 | irq -= GIC_PIN_TO_VEC_OFFSET; | ||
| 206 | |||
| 207 | /* Set irq to use shadow set */ | ||
| 208 | gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_EIC_SHADOW_SET_BASE) + | ||
| 209 | GIC_VPE_EIC_SS(irq), set); | ||
| 210 | } | ||
| 211 | |||
| 212 | void gic_send_ipi(unsigned int intr) | ||
| 213 | { | ||
| 214 | gic_write(GIC_REG(SHARED, GIC_SH_WEDGE), GIC_SH_WEDGE_SET(intr)); | ||
| 215 | } | ||
| 216 | |||
| 217 | int gic_get_c0_compare_int(void) | ||
| 218 | { | ||
| 219 | if (!gic_local_irq_is_routable(GIC_LOCAL_INT_TIMER)) | ||
| 220 | return MIPS_CPU_IRQ_BASE + cp0_compare_irq; | ||
| 221 | return irq_create_mapping(gic_irq_domain, | ||
| 222 | GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_TIMER)); | ||
| 223 | } | ||
| 224 | |||
| 225 | int gic_get_c0_perfcount_int(void) | ||
| 226 | { | ||
| 227 | if (!gic_local_irq_is_routable(GIC_LOCAL_INT_PERFCTR)) { | ||
| 228 | /* Is the erformance counter shared with the timer? */ | ||
| 229 | if (cp0_perfcount_irq < 0) | ||
| 230 | return -1; | ||
| 231 | return MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; | ||
| 232 | } | ||
| 233 | return irq_create_mapping(gic_irq_domain, | ||
| 234 | GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_PERFCTR)); | ||
| 235 | } | ||
| 236 | |||
| 237 | static unsigned int gic_get_int(void) | ||
| 238 | { | ||
| 239 | unsigned int i; | ||
| 240 | unsigned long *pcpu_mask; | ||
| 241 | unsigned long pending_reg, intrmask_reg; | ||
| 242 | DECLARE_BITMAP(pending, GIC_MAX_INTRS); | ||
| 243 | DECLARE_BITMAP(intrmask, GIC_MAX_INTRS); | ||
| 244 | |||
| 245 | /* Get per-cpu bitmaps */ | ||
| 246 | pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask; | ||
| 247 | |||
| 248 | pending_reg = GIC_REG(SHARED, GIC_SH_PEND); | ||
| 249 | intrmask_reg = GIC_REG(SHARED, GIC_SH_MASK); | ||
| 250 | |||
| 251 | for (i = 0; i < BITS_TO_LONGS(gic_shared_intrs); i++) { | ||
| 252 | pending[i] = gic_read(pending_reg); | ||
| 253 | intrmask[i] = gic_read(intrmask_reg); | ||
| 254 | pending_reg += 0x4; | ||
| 255 | intrmask_reg += 0x4; | ||
| 256 | } | ||
| 257 | |||
| 258 | bitmap_and(pending, pending, intrmask, gic_shared_intrs); | ||
| 259 | bitmap_and(pending, pending, pcpu_mask, gic_shared_intrs); | ||
| 260 | |||
| 261 | return find_first_bit(pending, gic_shared_intrs); | ||
| 262 | } | ||
| 263 | |||
| 264 | static void gic_mask_irq(struct irq_data *d) | ||
| 265 | { | ||
| 266 | gic_reset_mask(GIC_HWIRQ_TO_SHARED(d->hwirq)); | ||
| 267 | } | ||
| 268 | |||
| 269 | static void gic_unmask_irq(struct irq_data *d) | ||
| 270 | { | ||
| 271 | gic_set_mask(GIC_HWIRQ_TO_SHARED(d->hwirq)); | ||
| 272 | } | ||
| 273 | |||
| 274 | static void gic_ack_irq(struct irq_data *d) | ||
| 275 | { | ||
| 276 | unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq); | ||
| 277 | |||
| 278 | gic_write(GIC_REG(SHARED, GIC_SH_WEDGE), GIC_SH_WEDGE_CLR(irq)); | ||
| 279 | } | ||
| 280 | |||
| 281 | static int gic_set_type(struct irq_data *d, unsigned int type) | ||
| 282 | { | ||
| 283 | unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq); | ||
| 284 | unsigned long flags; | ||
| 285 | bool is_edge; | ||
| 286 | |||
| 287 | spin_lock_irqsave(&gic_lock, flags); | ||
| 288 | switch (type & IRQ_TYPE_SENSE_MASK) { | ||
| 289 | case IRQ_TYPE_EDGE_FALLING: | ||
| 290 | gic_set_polarity(irq, GIC_POL_NEG); | ||
| 291 | gic_set_trigger(irq, GIC_TRIG_EDGE); | ||
| 292 | gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE); | ||
| 293 | is_edge = true; | ||
| 294 | break; | ||
| 295 | case IRQ_TYPE_EDGE_RISING: | ||
| 296 | gic_set_polarity(irq, GIC_POL_POS); | ||
| 297 | gic_set_trigger(irq, GIC_TRIG_EDGE); | ||
| 298 | gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE); | ||
| 299 | is_edge = true; | ||
| 300 | break; | ||
| 301 | case IRQ_TYPE_EDGE_BOTH: | ||
| 302 | /* polarity is irrelevant in this case */ | ||
| 303 | gic_set_trigger(irq, GIC_TRIG_EDGE); | ||
| 304 | gic_set_dual_edge(irq, GIC_TRIG_DUAL_ENABLE); | ||
| 305 | is_edge = true; | ||
| 306 | break; | ||
| 307 | case IRQ_TYPE_LEVEL_LOW: | ||
| 308 | gic_set_polarity(irq, GIC_POL_NEG); | ||
| 309 | gic_set_trigger(irq, GIC_TRIG_LEVEL); | ||
| 310 | gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE); | ||
| 311 | is_edge = false; | ||
| 312 | break; | ||
| 313 | case IRQ_TYPE_LEVEL_HIGH: | ||
| 314 | default: | ||
| 315 | gic_set_polarity(irq, GIC_POL_POS); | ||
| 316 | gic_set_trigger(irq, GIC_TRIG_LEVEL); | ||
| 317 | gic_set_dual_edge(irq, GIC_TRIG_DUAL_DISABLE); | ||
| 318 | is_edge = false; | ||
| 319 | break; | ||
| 320 | } | ||
| 321 | |||
| 322 | if (is_edge) { | ||
| 323 | __irq_set_chip_handler_name_locked(d->irq, | ||
| 324 | &gic_edge_irq_controller, | ||
| 325 | handle_edge_irq, NULL); | ||
| 326 | } else { | ||
| 327 | __irq_set_chip_handler_name_locked(d->irq, | ||
| 328 | &gic_level_irq_controller, | ||
| 329 | handle_level_irq, NULL); | ||
| 330 | } | ||
| 331 | spin_unlock_irqrestore(&gic_lock, flags); | ||
| 332 | |||
| 333 | return 0; | ||
| 334 | } | ||
| 335 | |||
| 336 | #ifdef CONFIG_SMP | ||
| 337 | static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, | ||
| 338 | bool force) | ||
| 339 | { | ||
| 340 | unsigned int irq = GIC_HWIRQ_TO_SHARED(d->hwirq); | ||
| 341 | cpumask_t tmp = CPU_MASK_NONE; | ||
| 342 | unsigned long flags; | ||
| 343 | int i; | ||
| 344 | |||
| 345 | cpumask_and(&tmp, cpumask, cpu_online_mask); | ||
| 346 | if (cpus_empty(tmp)) | ||
| 347 | return -EINVAL; | ||
| 348 | |||
| 349 | /* Assumption : cpumask refers to a single CPU */ | ||
| 350 | spin_lock_irqsave(&gic_lock, flags); | ||
| 351 | |||
| 352 | /* Re-route this IRQ */ | ||
| 353 | gic_map_to_vpe(irq, first_cpu(tmp)); | ||
| 354 | |||
| 355 | /* Update the pcpu_masks */ | ||
| 356 | for (i = 0; i < NR_CPUS; i++) | ||
| 357 | clear_bit(irq, pcpu_masks[i].pcpu_mask); | ||
| 358 | set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask); | ||
| 359 | |||
| 360 | cpumask_copy(d->affinity, cpumask); | ||
| 361 | spin_unlock_irqrestore(&gic_lock, flags); | ||
| 362 | |||
| 363 | return IRQ_SET_MASK_OK_NOCOPY; | ||
| 364 | } | ||
| 365 | #endif | ||
| 366 | |||
| 367 | static struct irq_chip gic_level_irq_controller = { | ||
| 368 | .name = "MIPS GIC", | ||
| 369 | .irq_mask = gic_mask_irq, | ||
| 370 | .irq_unmask = gic_unmask_irq, | ||
| 371 | .irq_set_type = gic_set_type, | ||
| 372 | #ifdef CONFIG_SMP | ||
| 373 | .irq_set_affinity = gic_set_affinity, | ||
| 374 | #endif | ||
| 375 | }; | ||
| 376 | |||
| 377 | static struct irq_chip gic_edge_irq_controller = { | ||
| 378 | .name = "MIPS GIC", | ||
| 379 | .irq_ack = gic_ack_irq, | ||
| 380 | .irq_mask = gic_mask_irq, | ||
| 381 | .irq_unmask = gic_unmask_irq, | ||
| 382 | .irq_set_type = gic_set_type, | ||
| 383 | #ifdef CONFIG_SMP | ||
| 384 | .irq_set_affinity = gic_set_affinity, | ||
| 385 | #endif | ||
| 386 | }; | ||
| 387 | |||
| 388 | static unsigned int gic_get_local_int(void) | ||
| 389 | { | ||
| 390 | unsigned long pending, masked; | ||
| 391 | |||
| 392 | pending = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_PEND)); | ||
| 393 | masked = gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_MASK)); | ||
| 394 | |||
| 395 | bitmap_and(&pending, &pending, &masked, GIC_NUM_LOCAL_INTRS); | ||
| 396 | |||
| 397 | return find_first_bit(&pending, GIC_NUM_LOCAL_INTRS); | ||
| 398 | } | ||
| 399 | |||
| 400 | static void gic_mask_local_irq(struct irq_data *d) | ||
| 401 | { | ||
| 402 | int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq); | ||
| 403 | |||
| 404 | gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_RMASK), 1 << intr); | ||
| 405 | } | ||
| 406 | |||
| 407 | static void gic_unmask_local_irq(struct irq_data *d) | ||
| 408 | { | ||
| 409 | int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq); | ||
| 410 | |||
| 411 | gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), 1 << intr); | ||
| 412 | } | ||
| 413 | |||
| 414 | static struct irq_chip gic_local_irq_controller = { | ||
| 415 | .name = "MIPS GIC Local", | ||
| 416 | .irq_mask = gic_mask_local_irq, | ||
| 417 | .irq_unmask = gic_unmask_local_irq, | ||
| 418 | }; | ||
| 419 | |||
| 420 | static void gic_mask_local_irq_all_vpes(struct irq_data *d) | ||
| 421 | { | ||
| 422 | int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq); | ||
| 423 | int i; | ||
| 424 | unsigned long flags; | ||
| 425 | |||
| 426 | spin_lock_irqsave(&gic_lock, flags); | ||
| 427 | for (i = 0; i < gic_vpes; i++) { | ||
| 428 | gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); | ||
| 429 | gic_write(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << intr); | ||
| 430 | } | ||
| 431 | spin_unlock_irqrestore(&gic_lock, flags); | ||
| 432 | } | ||
| 433 | |||
| 434 | static void gic_unmask_local_irq_all_vpes(struct irq_data *d) | ||
| 435 | { | ||
| 436 | int intr = GIC_HWIRQ_TO_LOCAL(d->hwirq); | ||
| 437 | int i; | ||
| 438 | unsigned long flags; | ||
| 439 | |||
| 440 | spin_lock_irqsave(&gic_lock, flags); | ||
| 441 | for (i = 0; i < gic_vpes; i++) { | ||
| 442 | gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); | ||
| 443 | gic_write(GIC_REG(VPE_OTHER, GIC_VPE_SMASK), 1 << intr); | ||
| 444 | } | ||
| 445 | spin_unlock_irqrestore(&gic_lock, flags); | ||
| 446 | } | ||
| 447 | |||
| 448 | static struct irq_chip gic_all_vpes_local_irq_controller = { | ||
| 449 | .name = "MIPS GIC Local", | ||
| 450 | .irq_mask = gic_mask_local_irq_all_vpes, | ||
| 451 | .irq_unmask = gic_unmask_local_irq_all_vpes, | ||
| 452 | }; | ||
| 453 | |||
| 454 | static void __gic_irq_dispatch(void) | ||
| 455 | { | ||
| 456 | unsigned int intr, virq; | ||
| 457 | |||
| 458 | while ((intr = gic_get_local_int()) != GIC_NUM_LOCAL_INTRS) { | ||
| 459 | virq = irq_linear_revmap(gic_irq_domain, | ||
| 460 | GIC_LOCAL_TO_HWIRQ(intr)); | ||
| 461 | do_IRQ(virq); | ||
| 462 | } | ||
| 463 | |||
| 464 | while ((intr = gic_get_int()) != gic_shared_intrs) { | ||
| 465 | virq = irq_linear_revmap(gic_irq_domain, | ||
| 466 | GIC_SHARED_TO_HWIRQ(intr)); | ||
| 467 | do_IRQ(virq); | ||
| 468 | } | ||
| 469 | } | ||
| 470 | |||
| 471 | static void gic_irq_dispatch(unsigned int irq, struct irq_desc *desc) | ||
| 472 | { | ||
| 473 | __gic_irq_dispatch(); | ||
| 474 | } | ||
| 475 | |||
| 476 | #ifdef CONFIG_MIPS_GIC_IPI | ||
| 477 | static int gic_resched_int_base; | ||
| 478 | static int gic_call_int_base; | ||
| 479 | |||
| 480 | unsigned int plat_ipi_resched_int_xlate(unsigned int cpu) | ||
| 481 | { | ||
| 482 | return gic_resched_int_base + cpu; | ||
| 483 | } | ||
| 484 | |||
| 485 | unsigned int plat_ipi_call_int_xlate(unsigned int cpu) | ||
| 486 | { | ||
| 487 | return gic_call_int_base + cpu; | ||
| 488 | } | ||
| 489 | |||
| 490 | static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) | ||
| 491 | { | ||
| 492 | scheduler_ipi(); | ||
| 493 | |||
| 494 | return IRQ_HANDLED; | ||
| 495 | } | ||
| 496 | |||
| 497 | static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) | ||
| 498 | { | ||
| 499 | smp_call_function_interrupt(); | ||
| 500 | |||
| 501 | return IRQ_HANDLED; | ||
| 502 | } | ||
| 503 | |||
| 504 | static struct irqaction irq_resched = { | ||
| 505 | .handler = ipi_resched_interrupt, | ||
| 506 | .flags = IRQF_PERCPU, | ||
| 507 | .name = "IPI resched" | ||
| 508 | }; | ||
| 509 | |||
| 510 | static struct irqaction irq_call = { | ||
| 511 | .handler = ipi_call_interrupt, | ||
| 512 | .flags = IRQF_PERCPU, | ||
| 513 | .name = "IPI call" | ||
| 514 | }; | ||
| 515 | |||
| 516 | static __init void gic_ipi_init_one(unsigned int intr, int cpu, | ||
| 517 | struct irqaction *action) | ||
| 518 | { | ||
| 519 | int virq = irq_create_mapping(gic_irq_domain, | ||
| 520 | GIC_SHARED_TO_HWIRQ(intr)); | ||
| 521 | int i; | ||
| 522 | |||
| 523 | gic_map_to_vpe(intr, cpu); | ||
| 524 | for (i = 0; i < NR_CPUS; i++) | ||
| 525 | clear_bit(intr, pcpu_masks[i].pcpu_mask); | ||
| 526 | set_bit(intr, pcpu_masks[cpu].pcpu_mask); | ||
| 527 | |||
| 528 | irq_set_irq_type(virq, IRQ_TYPE_EDGE_RISING); | ||
| 529 | |||
| 530 | irq_set_handler(virq, handle_percpu_irq); | ||
| 531 | setup_irq(virq, action); | ||
| 532 | } | ||
| 533 | |||
| 534 | static __init void gic_ipi_init(void) | ||
| 535 | { | ||
| 536 | int i; | ||
| 537 | |||
| 538 | /* Use last 2 * NR_CPUS interrupts as IPIs */ | ||
| 539 | gic_resched_int_base = gic_shared_intrs - nr_cpu_ids; | ||
| 540 | gic_call_int_base = gic_resched_int_base - nr_cpu_ids; | ||
| 541 | |||
| 542 | for (i = 0; i < nr_cpu_ids; i++) { | ||
| 543 | gic_ipi_init_one(gic_call_int_base + i, i, &irq_call); | ||
| 544 | gic_ipi_init_one(gic_resched_int_base + i, i, &irq_resched); | ||
| 545 | } | ||
| 546 | } | ||
| 547 | #else | ||
| 548 | static inline void gic_ipi_init(void) | ||
| 549 | { | ||
| 550 | } | ||
| 551 | #endif | ||
| 552 | |||
| 553 | static void __init gic_basic_init(void) | ||
| 554 | { | ||
| 555 | unsigned int i; | ||
| 556 | |||
| 557 | board_bind_eic_interrupt = &gic_bind_eic_interrupt; | ||
| 558 | |||
| 559 | /* Setup defaults */ | ||
| 560 | for (i = 0; i < gic_shared_intrs; i++) { | ||
| 561 | gic_set_polarity(i, GIC_POL_POS); | ||
| 562 | gic_set_trigger(i, GIC_TRIG_LEVEL); | ||
| 563 | gic_reset_mask(i); | ||
| 564 | } | ||
| 565 | |||
| 566 | for (i = 0; i < gic_vpes; i++) { | ||
| 567 | unsigned int j; | ||
| 568 | |||
| 569 | gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); | ||
| 570 | for (j = 0; j < GIC_NUM_LOCAL_INTRS; j++) { | ||
| 571 | if (!gic_local_irq_is_routable(j)) | ||
| 572 | continue; | ||
| 573 | gic_write(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), 1 << j); | ||
| 574 | } | ||
| 575 | } | ||
| 576 | } | ||
| 577 | |||
| 578 | static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq, | ||
| 579 | irq_hw_number_t hw) | ||
| 580 | { | ||
| 581 | int intr = GIC_HWIRQ_TO_LOCAL(hw); | ||
| 582 | int ret = 0; | ||
| 583 | int i; | ||
| 584 | unsigned long flags; | ||
| 585 | |||
| 586 | if (!gic_local_irq_is_routable(intr)) | ||
| 587 | return -EPERM; | ||
| 588 | |||
| 589 | /* | ||
| 590 | * HACK: These are all really percpu interrupts, but the rest | ||
| 591 | * of the MIPS kernel code does not use the percpu IRQ API for | ||
| 592 | * the CP0 timer and performance counter interrupts. | ||
| 593 | */ | ||
| 594 | if (intr != GIC_LOCAL_INT_TIMER && intr != GIC_LOCAL_INT_PERFCTR) { | ||
| 595 | irq_set_chip_and_handler(virq, | ||
| 596 | &gic_local_irq_controller, | ||
| 597 | handle_percpu_devid_irq); | ||
| 598 | irq_set_percpu_devid(virq); | ||
| 599 | } else { | ||
| 600 | irq_set_chip_and_handler(virq, | ||
| 601 | &gic_all_vpes_local_irq_controller, | ||
| 602 | handle_percpu_irq); | ||
| 603 | } | ||
| 604 | |||
| 605 | spin_lock_irqsave(&gic_lock, flags); | ||
| 606 | for (i = 0; i < gic_vpes; i++) { | ||
| 607 | u32 val = GIC_MAP_TO_PIN_MSK | gic_cpu_pin; | ||
| 608 | |||
| 609 | gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); | ||
| 610 | |||
| 611 | switch (intr) { | ||
| 612 | case GIC_LOCAL_INT_WD: | ||
| 613 | gic_write(GIC_REG(VPE_OTHER, GIC_VPE_WD_MAP), val); | ||
| 614 | break; | ||
| 615 | case GIC_LOCAL_INT_COMPARE: | ||
| 616 | gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_MAP), val); | ||
| 617 | break; | ||
| 618 | case GIC_LOCAL_INT_TIMER: | ||
| 619 | gic_write(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP), val); | ||
| 620 | break; | ||
| 621 | case GIC_LOCAL_INT_PERFCTR: | ||
| 622 | gic_write(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP), val); | ||
| 623 | break; | ||
| 624 | case GIC_LOCAL_INT_SWINT0: | ||
| 625 | gic_write(GIC_REG(VPE_OTHER, GIC_VPE_SWINT0_MAP), val); | ||
| 626 | break; | ||
| 627 | case GIC_LOCAL_INT_SWINT1: | ||
| 628 | gic_write(GIC_REG(VPE_OTHER, GIC_VPE_SWINT1_MAP), val); | ||
| 629 | break; | ||
| 630 | case GIC_LOCAL_INT_FDC: | ||
| 631 | gic_write(GIC_REG(VPE_OTHER, GIC_VPE_FDC_MAP), val); | ||
| 632 | break; | ||
| 633 | default: | ||
| 634 | pr_err("Invalid local IRQ %d\n", intr); | ||
| 635 | ret = -EINVAL; | ||
| 636 | break; | ||
| 637 | } | ||
| 638 | } | ||
| 639 | spin_unlock_irqrestore(&gic_lock, flags); | ||
| 640 | |||
| 641 | return ret; | ||
| 642 | } | ||
| 643 | |||
| 644 | static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, | ||
| 645 | irq_hw_number_t hw) | ||
| 646 | { | ||
| 647 | int intr = GIC_HWIRQ_TO_SHARED(hw); | ||
| 648 | unsigned long flags; | ||
| 649 | |||
| 650 | irq_set_chip_and_handler(virq, &gic_level_irq_controller, | ||
| 651 | handle_level_irq); | ||
| 652 | |||
| 653 | spin_lock_irqsave(&gic_lock, flags); | ||
| 654 | gic_map_to_pin(intr, gic_cpu_pin); | ||
| 655 | /* Map to VPE 0 by default */ | ||
| 656 | gic_map_to_vpe(intr, 0); | ||
| 657 | set_bit(intr, pcpu_masks[0].pcpu_mask); | ||
| 658 | spin_unlock_irqrestore(&gic_lock, flags); | ||
| 659 | |||
| 660 | return 0; | ||
| 661 | } | ||
| 662 | |||
| 663 | static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq, | ||
| 664 | irq_hw_number_t hw) | ||
| 665 | { | ||
| 666 | if (GIC_HWIRQ_TO_LOCAL(hw) < GIC_NUM_LOCAL_INTRS) | ||
| 667 | return gic_local_irq_domain_map(d, virq, hw); | ||
| 668 | return gic_shared_irq_domain_map(d, virq, hw); | ||
| 669 | } | ||
| 670 | |||
| 671 | static int gic_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr, | ||
| 672 | const u32 *intspec, unsigned int intsize, | ||
| 673 | irq_hw_number_t *out_hwirq, | ||
| 674 | unsigned int *out_type) | ||
| 675 | { | ||
| 676 | if (intsize != 3) | ||
| 677 | return -EINVAL; | ||
| 678 | |||
| 679 | if (intspec[0] == GIC_SHARED) | ||
| 680 | *out_hwirq = GIC_SHARED_TO_HWIRQ(intspec[1]); | ||
| 681 | else if (intspec[0] == GIC_LOCAL) | ||
| 682 | *out_hwirq = GIC_LOCAL_TO_HWIRQ(intspec[1]); | ||
| 683 | else | ||
| 684 | return -EINVAL; | ||
| 685 | *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; | ||
| 686 | |||
| 687 | return 0; | ||
| 688 | } | ||
| 689 | |||
| 690 | static struct irq_domain_ops gic_irq_domain_ops = { | ||
| 691 | .map = gic_irq_domain_map, | ||
| 692 | .xlate = gic_irq_domain_xlate, | ||
| 693 | }; | ||
| 694 | |||
| 695 | static void __init __gic_init(unsigned long gic_base_addr, | ||
| 696 | unsigned long gic_addrspace_size, | ||
| 697 | unsigned int cpu_vec, unsigned int irqbase, | ||
| 698 | struct device_node *node) | ||
| 699 | { | ||
| 700 | unsigned int gicconfig; | ||
| 701 | |||
| 702 | gic_base = ioremap_nocache(gic_base_addr, gic_addrspace_size); | ||
| 703 | |||
| 704 | gicconfig = gic_read(GIC_REG(SHARED, GIC_SH_CONFIG)); | ||
| 705 | gic_shared_intrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >> | ||
| 706 | GIC_SH_CONFIG_NUMINTRS_SHF; | ||
| 707 | gic_shared_intrs = ((gic_shared_intrs + 1) * 8); | ||
| 708 | |||
| 709 | gic_vpes = (gicconfig & GIC_SH_CONFIG_NUMVPES_MSK) >> | ||
| 710 | GIC_SH_CONFIG_NUMVPES_SHF; | ||
| 711 | gic_vpes = gic_vpes + 1; | ||
| 712 | |||
| 713 | if (cpu_has_veic) { | ||
| 714 | /* Always use vector 1 in EIC mode */ | ||
| 715 | gic_cpu_pin = 0; | ||
| 716 | set_vi_handler(gic_cpu_pin + GIC_PIN_TO_VEC_OFFSET, | ||
| 717 | __gic_irq_dispatch); | ||
| 718 | } else { | ||
| 719 | gic_cpu_pin = cpu_vec - GIC_CPU_PIN_OFFSET; | ||
| 720 | irq_set_chained_handler(MIPS_CPU_IRQ_BASE + cpu_vec, | ||
| 721 | gic_irq_dispatch); | ||
| 722 | } | ||
| 723 | |||
| 724 | gic_irq_domain = irq_domain_add_simple(node, GIC_NUM_LOCAL_INTRS + | ||
| 725 | gic_shared_intrs, irqbase, | ||
| 726 | &gic_irq_domain_ops, NULL); | ||
| 727 | if (!gic_irq_domain) | ||
| 728 | panic("Failed to add GIC IRQ domain"); | ||
| 729 | |||
| 730 | gic_basic_init(); | ||
| 731 | |||
| 732 | gic_ipi_init(); | ||
| 733 | } | ||
| 734 | |||
| 735 | void __init gic_init(unsigned long gic_base_addr, | ||
| 736 | unsigned long gic_addrspace_size, | ||
| 737 | unsigned int cpu_vec, unsigned int irqbase) | ||
| 738 | { | ||
| 739 | __gic_init(gic_base_addr, gic_addrspace_size, cpu_vec, irqbase, NULL); | ||
| 740 | } | ||
| 741 | |||
| 742 | static int __init gic_of_init(struct device_node *node, | ||
| 743 | struct device_node *parent) | ||
| 744 | { | ||
| 745 | struct resource res; | ||
| 746 | unsigned int cpu_vec, i = 0, reserved = 0; | ||
| 747 | phys_addr_t gic_base; | ||
| 748 | size_t gic_len; | ||
| 749 | |||
| 750 | /* Find the first available CPU vector. */ | ||
| 751 | while (!of_property_read_u32_index(node, "mti,reserved-cpu-vectors", | ||
| 752 | i++, &cpu_vec)) | ||
| 753 | reserved |= BIT(cpu_vec); | ||
| 754 | for (cpu_vec = 2; cpu_vec < 8; cpu_vec++) { | ||
| 755 | if (!(reserved & BIT(cpu_vec))) | ||
| 756 | break; | ||
| 757 | } | ||
| 758 | if (cpu_vec == 8) { | ||
| 759 | pr_err("No CPU vectors available for GIC\n"); | ||
| 760 | return -ENODEV; | ||
| 761 | } | ||
| 762 | |||
| 763 | if (of_address_to_resource(node, 0, &res)) { | ||
| 764 | /* | ||
| 765 | * Probe the CM for the GIC base address if not specified | ||
| 766 | * in the device-tree. | ||
| 767 | */ | ||
| 768 | if (mips_cm_present()) { | ||
| 769 | gic_base = read_gcr_gic_base() & | ||
| 770 | ~CM_GCR_GIC_BASE_GICEN_MSK; | ||
| 771 | gic_len = 0x20000; | ||
| 772 | } else { | ||
| 773 | pr_err("Failed to get GIC memory range\n"); | ||
| 774 | return -ENODEV; | ||
| 775 | } | ||
| 776 | } else { | ||
| 777 | gic_base = res.start; | ||
| 778 | gic_len = resource_size(&res); | ||
| 779 | } | ||
| 780 | |||
| 781 | if (mips_cm_present()) | ||
| 782 | write_gcr_gic_base(gic_base | CM_GCR_GIC_BASE_GICEN_MSK); | ||
| 783 | gic_present = true; | ||
| 784 | |||
| 785 | __gic_init(gic_base, gic_len, cpu_vec, 0, node); | ||
| 786 | |||
| 787 | return 0; | ||
| 788 | } | ||
| 789 | IRQCHIP_DECLARE(mips_gic, "mti,gic", gic_of_init); | ||
diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig index 93caf8e68901..2399a3921762 100644 --- a/drivers/net/wireless/ath/ath5k/Kconfig +++ b/drivers/net/wireless/ath/ath5k/Kconfig | |||
| @@ -1,12 +1,13 @@ | |||
| 1 | config ATH5K | 1 | config ATH5K |
| 2 | tristate "Atheros 5xxx wireless cards support" | 2 | tristate "Atheros 5xxx wireless cards support" |
| 3 | depends on PCI && MAC80211 | 3 | depends on (PCI || ATH25) && MAC80211 |
| 4 | select ATH_COMMON | 4 | select ATH_COMMON |
| 5 | select MAC80211_LEDS | 5 | select MAC80211_LEDS |
| 6 | select LEDS_CLASS | 6 | select LEDS_CLASS |
| 7 | select NEW_LEDS | 7 | select NEW_LEDS |
| 8 | select AVERAGE | 8 | select AVERAGE |
| 9 | select ATH5K_PCI | 9 | select ATH5K_AHB if ATH25 |
| 10 | select ATH5K_PCI if !ATH25 | ||
| 10 | ---help--- | 11 | ---help--- |
| 11 | This module adds support for wireless adapters based on | 12 | This module adds support for wireless adapters based on |
| 12 | Atheros 5xxx chipset. | 13 | Atheros 5xxx chipset. |
| @@ -51,9 +52,16 @@ config ATH5K_TRACER | |||
| 51 | 52 | ||
| 52 | If unsure, say N. | 53 | If unsure, say N. |
| 53 | 54 | ||
| 55 | config ATH5K_AHB | ||
| 56 | bool "Atheros 5xxx AHB bus support" | ||
| 57 | depends on ATH25 | ||
| 58 | ---help--- | ||
| 59 | This adds support for WiSoC type chipsets of the 5xxx Atheros | ||
| 60 | family. | ||
| 61 | |||
| 54 | config ATH5K_PCI | 62 | config ATH5K_PCI |
| 55 | bool "Atheros 5xxx PCI bus support" | 63 | bool "Atheros 5xxx PCI bus support" |
| 56 | depends on PCI | 64 | depends on (!ATH25 && PCI) |
| 57 | ---help--- | 65 | ---help--- |
| 58 | This adds support for PCI type chipsets of the 5xxx Atheros | 66 | This adds support for PCI type chipsets of the 5xxx Atheros |
| 59 | family. | 67 | family. |
diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile index 51e2d8668041..1b3a34f7f224 100644 --- a/drivers/net/wireless/ath/ath5k/Makefile +++ b/drivers/net/wireless/ath/ath5k/Makefile | |||
| @@ -17,5 +17,6 @@ ath5k-y += ani.o | |||
| 17 | ath5k-y += sysfs.o | 17 | ath5k-y += sysfs.o |
| 18 | ath5k-y += mac80211-ops.o | 18 | ath5k-y += mac80211-ops.o |
| 19 | ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o | 19 | ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o |
| 20 | ath5k-$(CONFIG_ATH5K_AHB) += ahb.o | ||
| 20 | ath5k-$(CONFIG_ATH5K_PCI) += pci.o | 21 | ath5k-$(CONFIG_ATH5K_PCI) += pci.o |
| 21 | obj-$(CONFIG_ATH5K) += ath5k.o | 22 | obj-$(CONFIG_ATH5K) += ath5k.o |
diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c new file mode 100644 index 000000000000..8f387cf67340 --- /dev/null +++ b/drivers/net/wireless/ath/ath5k/ahb.c | |||
| @@ -0,0 +1,234 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | ||
| 3 | * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org> | ||
| 4 | * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org> | ||
| 5 | * | ||
| 6 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 7 | * purpose with or without fee is hereby granted, provided that the above | ||
| 8 | * copyright notice and this permission notice appear in all copies. | ||
| 9 | * | ||
| 10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/nl80211.h> | ||
| 20 | #include <linux/platform_device.h> | ||
| 21 | #include <linux/etherdevice.h> | ||
| 22 | #include <linux/export.h> | ||
| 23 | #include <ath25_platform.h> | ||
| 24 | #include "ath5k.h" | ||
| 25 | #include "debug.h" | ||
| 26 | #include "base.h" | ||
| 27 | #include "reg.h" | ||
| 28 | |||
| 29 | /* return bus cachesize in 4B word units */ | ||
| 30 | static void ath5k_ahb_read_cachesize(struct ath_common *common, int *csz) | ||
| 31 | { | ||
| 32 | *csz = L1_CACHE_BYTES >> 2; | ||
| 33 | } | ||
| 34 | |||
| 35 | static bool | ||
| 36 | ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) | ||
| 37 | { | ||
| 38 | struct ath5k_hw *ah = common->priv; | ||
| 39 | struct platform_device *pdev = to_platform_device(ah->dev); | ||
| 40 | struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev); | ||
| 41 | u16 *eeprom, *eeprom_end; | ||
| 42 | |||
| 43 | eeprom = (u16 *) bcfg->radio; | ||
| 44 | eeprom_end = ((void *) bcfg->config) + BOARD_CONFIG_BUFSZ; | ||
| 45 | |||
| 46 | eeprom += off; | ||
| 47 | if (eeprom > eeprom_end) | ||
| 48 | return false; | ||
| 49 | |||
| 50 | *data = *eeprom; | ||
| 51 | return true; | ||
| 52 | } | ||
| 53 | |||
| 54 | int ath5k_hw_read_srev(struct ath5k_hw *ah) | ||
| 55 | { | ||
| 56 | struct platform_device *pdev = to_platform_device(ah->dev); | ||
| 57 | struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev); | ||
| 58 | ah->ah_mac_srev = bcfg->devid; | ||
| 59 | return 0; | ||
| 60 | } | ||
| 61 | |||
| 62 | static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) | ||
| 63 | { | ||
| 64 | struct platform_device *pdev = to_platform_device(ah->dev); | ||
| 65 | struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev); | ||
| 66 | u8 *cfg_mac; | ||
| 67 | |||
| 68 | if (to_platform_device(ah->dev)->id == 0) | ||
| 69 | cfg_mac = bcfg->config->wlan0_mac; | ||
| 70 | else | ||
| 71 | cfg_mac = bcfg->config->wlan1_mac; | ||
| 72 | |||
| 73 | memcpy(mac, cfg_mac, ETH_ALEN); | ||
| 74 | return 0; | ||
| 75 | } | ||
| 76 | |||
| 77 | static const struct ath_bus_ops ath_ahb_bus_ops = { | ||
| 78 | .ath_bus_type = ATH_AHB, | ||
| 79 | .read_cachesize = ath5k_ahb_read_cachesize, | ||
| 80 | .eeprom_read = ath5k_ahb_eeprom_read, | ||
| 81 | .eeprom_read_mac = ath5k_ahb_eeprom_read_mac, | ||
| 82 | }; | ||
| 83 | |||
| 84 | /*Initialization*/ | ||
| 85 | static int ath_ahb_probe(struct platform_device *pdev) | ||
| 86 | { | ||
| 87 | struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev); | ||
| 88 | struct ath5k_hw *ah; | ||
| 89 | struct ieee80211_hw *hw; | ||
| 90 | struct resource *res; | ||
| 91 | void __iomem *mem; | ||
| 92 | int irq; | ||
| 93 | int ret = 0; | ||
| 94 | u32 reg; | ||
| 95 | |||
| 96 | if (!dev_get_platdata(&pdev->dev)) { | ||
| 97 | dev_err(&pdev->dev, "no platform data specified\n"); | ||
| 98 | ret = -EINVAL; | ||
| 99 | goto err_out; | ||
| 100 | } | ||
| 101 | |||
| 102 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 103 | if (res == NULL) { | ||
| 104 | dev_err(&pdev->dev, "no memory resource found\n"); | ||
| 105 | ret = -ENXIO; | ||
| 106 | goto err_out; | ||
| 107 | } | ||
| 108 | |||
| 109 | mem = ioremap_nocache(res->start, resource_size(res)); | ||
| 110 | if (mem == NULL) { | ||
| 111 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
| 112 | ret = -ENOMEM; | ||
| 113 | goto err_out; | ||
| 114 | } | ||
| 115 | |||
| 116 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
| 117 | if (res == NULL) { | ||
| 118 | dev_err(&pdev->dev, "no IRQ resource found\n"); | ||
| 119 | ret = -ENXIO; | ||
| 120 | goto err_iounmap; | ||
| 121 | } | ||
| 122 | |||
| 123 | irq = res->start; | ||
| 124 | |||
| 125 | hw = ieee80211_alloc_hw(sizeof(struct ath5k_hw), &ath5k_hw_ops); | ||
| 126 | if (hw == NULL) { | ||
| 127 | dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); | ||
| 128 | ret = -ENOMEM; | ||
| 129 | goto err_iounmap; | ||
| 130 | } | ||
| 131 | |||
| 132 | ah = hw->priv; | ||
| 133 | ah->hw = hw; | ||
| 134 | ah->dev = &pdev->dev; | ||
| 135 | ah->iobase = mem; | ||
| 136 | ah->irq = irq; | ||
| 137 | ah->devid = bcfg->devid; | ||
| 138 | |||
| 139 | if (bcfg->devid >= AR5K_SREV_AR2315_R6) { | ||
| 140 | /* Enable WMAC AHB arbitration */ | ||
| 141 | reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL); | ||
| 142 | reg |= AR5K_AR2315_AHB_ARB_CTL_WLAN; | ||
| 143 | iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL); | ||
| 144 | |||
| 145 | /* Enable global WMAC swapping */ | ||
| 146 | reg = ioread32((void __iomem *) AR5K_AR2315_BYTESWAP); | ||
| 147 | reg |= AR5K_AR2315_BYTESWAP_WMAC; | ||
| 148 | iowrite32(reg, (void __iomem *) AR5K_AR2315_BYTESWAP); | ||
| 149 | } else { | ||
| 150 | /* Enable WMAC DMA access (assuming 5312 or 231x*/ | ||
| 151 | /* TODO: check other platforms */ | ||
| 152 | reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE); | ||
| 153 | if (to_platform_device(ah->dev)->id == 0) | ||
| 154 | reg |= AR5K_AR5312_ENABLE_WLAN0; | ||
| 155 | else | ||
| 156 | reg |= AR5K_AR5312_ENABLE_WLAN1; | ||
| 157 | iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE); | ||
| 158 | |||
| 159 | /* | ||
| 160 | * On a dual-band AR5312, the multiband radio is only | ||
| 161 | * used as pass-through. Disable 2 GHz support in the | ||
| 162 | * driver for it | ||
| 163 | */ | ||
| 164 | if (to_platform_device(ah->dev)->id == 0 && | ||
| 165 | (bcfg->config->flags & (BD_WLAN0 | BD_WLAN1)) == | ||
| 166 | (BD_WLAN1 | BD_WLAN0)) | ||
| 167 | ah->ah_capabilities.cap_needs_2GHz_ovr = true; | ||
| 168 | else | ||
| 169 | ah->ah_capabilities.cap_needs_2GHz_ovr = false; | ||
| 170 | } | ||
| 171 | |||
| 172 | ret = ath5k_init_ah(ah, &ath_ahb_bus_ops); | ||
| 173 | if (ret != 0) { | ||
| 174 | dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret); | ||
| 175 | ret = -ENODEV; | ||
| 176 | goto err_free_hw; | ||
| 177 | } | ||
| 178 | |||
| 179 | platform_set_drvdata(pdev, hw); | ||
| 180 | |||
| 181 | return 0; | ||
| 182 | |||
| 183 | err_free_hw: | ||
| 184 | ieee80211_free_hw(hw); | ||
| 185 | err_iounmap: | ||
| 186 | iounmap(mem); | ||
| 187 | err_out: | ||
| 188 | return ret; | ||
| 189 | } | ||
| 190 | |||
| 191 | static int ath_ahb_remove(struct platform_device *pdev) | ||
| 192 | { | ||
| 193 | struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev); | ||
| 194 | struct ieee80211_hw *hw = platform_get_drvdata(pdev); | ||
| 195 | struct ath5k_hw *ah; | ||
| 196 | u32 reg; | ||
| 197 | |||
| 198 | if (!hw) | ||
| 199 | return 0; | ||
| 200 | |||
| 201 | ah = hw->priv; | ||
| 202 | |||
| 203 | if (bcfg->devid >= AR5K_SREV_AR2315_R6) { | ||
| 204 | /* Disable WMAC AHB arbitration */ | ||
| 205 | reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL); | ||
| 206 | reg &= ~AR5K_AR2315_AHB_ARB_CTL_WLAN; | ||
| 207 | iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL); | ||
| 208 | } else { | ||
| 209 | /*Stop DMA access */ | ||
| 210 | reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE); | ||
| 211 | if (to_platform_device(ah->dev)->id == 0) | ||
| 212 | reg &= ~AR5K_AR5312_ENABLE_WLAN0; | ||
| 213 | else | ||
| 214 | reg &= ~AR5K_AR5312_ENABLE_WLAN1; | ||
| 215 | iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE); | ||
| 216 | } | ||
| 217 | |||
| 218 | ath5k_deinit_ah(ah); | ||
| 219 | iounmap(ah->iobase); | ||
| 220 | ieee80211_free_hw(hw); | ||
| 221 | |||
| 222 | return 0; | ||
| 223 | } | ||
| 224 | |||
| 225 | static struct platform_driver ath_ahb_driver = { | ||
| 226 | .probe = ath_ahb_probe, | ||
| 227 | .remove = ath_ahb_remove, | ||
| 228 | .driver = { | ||
| 229 | .name = "ar231x-wmac", | ||
| 230 | .owner = THIS_MODULE, | ||
| 231 | }, | ||
| 232 | }; | ||
| 233 | |||
| 234 | module_platform_driver(ath_ahb_driver); | ||
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index ed2468220216..1ed7a88aeea9 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
| @@ -1647,6 +1647,32 @@ static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah) | |||
| 1647 | return &(ath5k_hw_common(ah)->regulatory); | 1647 | return &(ath5k_hw_common(ah)->regulatory); |
| 1648 | } | 1648 | } |
| 1649 | 1649 | ||
| 1650 | #ifdef CONFIG_ATH5K_AHB | ||
| 1651 | #define AR5K_AR2315_PCI_BASE ((void __iomem *)0xb0100000) | ||
| 1652 | |||
| 1653 | static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg) | ||
| 1654 | { | ||
| 1655 | /* On AR2315 and AR2317 the PCI clock domain registers | ||
| 1656 | * are outside of the WMAC register space */ | ||
| 1657 | if (unlikely((reg >= 0x4000) && (reg < 0x5000) && | ||
| 1658 | (ah->ah_mac_srev >= AR5K_SREV_AR2315_R6))) | ||
| 1659 | return AR5K_AR2315_PCI_BASE + reg; | ||
| 1660 | |||
| 1661 | return ah->iobase + reg; | ||
| 1662 | } | ||
| 1663 | |||
| 1664 | static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg) | ||
| 1665 | { | ||
| 1666 | return ioread32(ath5k_ahb_reg(ah, reg)); | ||
| 1667 | } | ||
| 1668 | |||
| 1669 | static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) | ||
| 1670 | { | ||
| 1671 | iowrite32(val, ath5k_ahb_reg(ah, reg)); | ||
| 1672 | } | ||
| 1673 | |||
| 1674 | #else | ||
| 1675 | |||
| 1650 | static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg) | 1676 | static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg) |
| 1651 | { | 1677 | { |
| 1652 | return ioread32(ah->iobase + reg); | 1678 | return ioread32(ah->iobase + reg); |
| @@ -1657,6 +1683,8 @@ static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) | |||
| 1657 | iowrite32(val, ah->iobase + reg); | 1683 | iowrite32(val, ah->iobase + reg); |
| 1658 | } | 1684 | } |
| 1659 | 1685 | ||
| 1686 | #endif | ||
| 1687 | |||
| 1660 | static inline enum ath_bus_type ath5k_get_bus_type(struct ath5k_hw *ah) | 1688 | static inline enum ath_bus_type ath5k_get_bus_type(struct ath5k_hw *ah) |
| 1661 | { | 1689 | { |
| 1662 | return ath5k_hw_common(ah)->bus_ops->ath_bus_type; | 1690 | return ath5k_hw_common(ah)->bus_ops->ath_bus_type; |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index a4a09bb8f2f3..bc9cb356fa69 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
| @@ -99,6 +99,15 @@ static int ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan, | |||
| 99 | 99 | ||
| 100 | /* Known SREVs */ | 100 | /* Known SREVs */ |
| 101 | static const struct ath5k_srev_name srev_names[] = { | 101 | static const struct ath5k_srev_name srev_names[] = { |
| 102 | #ifdef CONFIG_ATH5K_AHB | ||
| 103 | { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R2 }, | ||
| 104 | { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R7 }, | ||
| 105 | { "2313", AR5K_VERSION_MAC, AR5K_SREV_AR2313_R8 }, | ||
| 106 | { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R6 }, | ||
| 107 | { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R7 }, | ||
| 108 | { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R1 }, | ||
| 109 | { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R2 }, | ||
| 110 | #else | ||
| 102 | { "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 }, | 111 | { "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 }, |
| 103 | { "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 }, | 112 | { "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 }, |
| 104 | { "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A }, | 113 | { "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A }, |
| @@ -117,6 +126,7 @@ static const struct ath5k_srev_name srev_names[] = { | |||
| 117 | { "5418", AR5K_VERSION_MAC, AR5K_SREV_AR5418 }, | 126 | { "5418", AR5K_VERSION_MAC, AR5K_SREV_AR5418 }, |
| 118 | { "2425", AR5K_VERSION_MAC, AR5K_SREV_AR2425 }, | 127 | { "2425", AR5K_VERSION_MAC, AR5K_SREV_AR2425 }, |
| 119 | { "2417", AR5K_VERSION_MAC, AR5K_SREV_AR2417 }, | 128 | { "2417", AR5K_VERSION_MAC, AR5K_SREV_AR2417 }, |
| 129 | #endif | ||
| 120 | { "xxxxx", AR5K_VERSION_MAC, AR5K_SREV_UNKNOWN }, | 130 | { "xxxxx", AR5K_VERSION_MAC, AR5K_SREV_UNKNOWN }, |
| 121 | { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 }, | 131 | { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 }, |
| 122 | { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 }, | 132 | { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 }, |
| @@ -132,6 +142,10 @@ static const struct ath5k_srev_name srev_names[] = { | |||
| 132 | { "5413", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 }, | 142 | { "5413", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 }, |
| 133 | { "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 }, | 143 | { "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 }, |
| 134 | { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 }, | 144 | { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 }, |
| 145 | #ifdef CONFIG_ATH5K_AHB | ||
| 146 | { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 }, | ||
| 147 | { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 }, | ||
| 148 | #endif | ||
| 135 | { "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN }, | 149 | { "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN }, |
| 136 | }; | 150 | }; |
| 137 | 151 | ||
diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c index 0beb7e7d6075..ca4b7ccd697f 100644 --- a/drivers/net/wireless/ath/ath5k/led.c +++ b/drivers/net/wireless/ath/ath5k/led.c | |||
| @@ -163,14 +163,20 @@ int ath5k_init_leds(struct ath5k_hw *ah) | |||
| 163 | { | 163 | { |
| 164 | int ret = 0; | 164 | int ret = 0; |
| 165 | struct ieee80211_hw *hw = ah->hw; | 165 | struct ieee80211_hw *hw = ah->hw; |
| 166 | #ifndef CONFIG_ATH5K_AHB | ||
| 166 | struct pci_dev *pdev = ah->pdev; | 167 | struct pci_dev *pdev = ah->pdev; |
| 168 | #endif | ||
| 167 | char name[ATH5K_LED_MAX_NAME_LEN + 1]; | 169 | char name[ATH5K_LED_MAX_NAME_LEN + 1]; |
| 168 | const struct pci_device_id *match; | 170 | const struct pci_device_id *match; |
| 169 | 171 | ||
| 170 | if (!ah->pdev) | 172 | if (!ah->pdev) |
| 171 | return 0; | 173 | return 0; |
| 172 | 174 | ||
| 175 | #ifdef CONFIG_ATH5K_AHB | ||
| 176 | match = NULL; | ||
| 177 | #else | ||
| 173 | match = pci_match_id(&ath5k_led_devices[0], pdev); | 178 | match = pci_match_id(&ath5k_led_devices[0], pdev); |
| 179 | #endif | ||
| 174 | if (match) { | 180 | if (match) { |
| 175 | __set_bit(ATH_STAT_LEDSOFT, ah->status); | 181 | __set_bit(ATH_STAT_LEDSOFT, ah->status); |
| 176 | ah->led_pin = ATH_PIN(match->driver_data); | 182 | ah->led_pin = ATH_PIN(match->driver_data); |
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index b0ce7cdee0c2..910e90bf16c6 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig | |||
| @@ -147,7 +147,6 @@ config TCIC | |||
| 147 | config PCMCIA_ALCHEMY_DEVBOARD | 147 | config PCMCIA_ALCHEMY_DEVBOARD |
| 148 | tristate "Alchemy Db/Pb1xxx PCMCIA socket services" | 148 | tristate "Alchemy Db/Pb1xxx PCMCIA socket services" |
| 149 | depends on MIPS_ALCHEMY && PCMCIA | 149 | depends on MIPS_ALCHEMY && PCMCIA |
| 150 | select 64BIT_PHYS_ADDR | ||
| 151 | help | 150 | help |
| 152 | Enable this driver of you want PCMCIA support on your Alchemy | 151 | Enable this driver of you want PCMCIA support on your Alchemy |
| 153 | Db1000, Db/Pb1100, Db/Pb1500, Db/Pb1550, Db/Pb1200, DB1300 | 152 | Db1000, Db/Pb1100, Db/Pb1500, Db/Pb1550, Db/Pb1200, DB1300 |
| @@ -158,7 +157,6 @@ config PCMCIA_ALCHEMY_DEVBOARD | |||
| 158 | config PCMCIA_XXS1500 | 157 | config PCMCIA_XXS1500 |
| 159 | tristate "MyCable XXS1500 PCMCIA socket support" | 158 | tristate "MyCable XXS1500 PCMCIA socket support" |
| 160 | depends on PCMCIA && MIPS_XXS1500 | 159 | depends on PCMCIA && MIPS_XXS1500 |
| 161 | select 64BIT_PHYS_ADDR | ||
| 162 | help | 160 | help |
| 163 | Support for the PCMCIA/CF socket interface on MyCable XXS1500 | 161 | Support for the PCMCIA/CF socket interface on MyCable XXS1500 |
| 164 | systems. | 162 | systems. |
diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c index 09077067b0c8..7b986f9f213f 100644 --- a/drivers/ssb/driver_mipscore.c +++ b/drivers/ssb/driver_mipscore.c | |||
| @@ -15,6 +15,9 @@ | |||
| 15 | #include <linux/serial_core.h> | 15 | #include <linux/serial_core.h> |
| 16 | #include <linux/serial_reg.h> | 16 | #include <linux/serial_reg.h> |
| 17 | #include <linux/time.h> | 17 | #include <linux/time.h> |
| 18 | #ifdef CONFIG_BCM47XX | ||
| 19 | #include <bcm47xx_nvram.h> | ||
| 20 | #endif | ||
| 18 | 21 | ||
| 19 | #include "ssb_private.h" | 22 | #include "ssb_private.h" |
| 20 | 23 | ||
| @@ -210,6 +213,7 @@ static void ssb_mips_serial_init(struct ssb_mipscore *mcore) | |||
| 210 | static void ssb_mips_flash_detect(struct ssb_mipscore *mcore) | 213 | static void ssb_mips_flash_detect(struct ssb_mipscore *mcore) |
| 211 | { | 214 | { |
| 212 | struct ssb_bus *bus = mcore->dev->bus; | 215 | struct ssb_bus *bus = mcore->dev->bus; |
| 216 | struct ssb_sflash *sflash = &mcore->sflash; | ||
| 213 | struct ssb_pflash *pflash = &mcore->pflash; | 217 | struct ssb_pflash *pflash = &mcore->pflash; |
| 214 | 218 | ||
| 215 | /* When there is no chipcommon on the bus there is 4MB flash */ | 219 | /* When there is no chipcommon on the bus there is 4MB flash */ |
| @@ -242,7 +246,15 @@ static void ssb_mips_flash_detect(struct ssb_mipscore *mcore) | |||
| 242 | } | 246 | } |
| 243 | 247 | ||
| 244 | ssb_pflash: | 248 | ssb_pflash: |
| 245 | if (pflash->present) { | 249 | if (sflash->present) { |
| 250 | #ifdef CONFIG_BCM47XX | ||
| 251 | bcm47xx_nvram_init_from_mem(sflash->window, sflash->size); | ||
| 252 | #endif | ||
| 253 | } else if (pflash->present) { | ||
| 254 | #ifdef CONFIG_BCM47XX | ||
| 255 | bcm47xx_nvram_init_from_mem(pflash->window, pflash->window_size); | ||
| 256 | #endif | ||
| 257 | |||
| 246 | ssb_pflash_data.width = pflash->buswidth; | 258 | ssb_pflash_data.width = pflash->buswidth; |
| 247 | ssb_pflash_resource.start = pflash->window; | 259 | ssb_pflash_resource.start = pflash->window; |
| 248 | ssb_pflash_resource.end = pflash->window + pflash->window_size; | 260 | ssb_pflash_resource.end = pflash->window + pflash->window_size; |
diff --git a/drivers/tc/tc.c b/drivers/tc/tc.c index 946562389ca8..3be9519654e5 100644 --- a/drivers/tc/tc.c +++ b/drivers/tc/tc.c | |||
| @@ -83,8 +83,7 @@ static void __init tc_bus_add_devices(struct tc_bus *tbus) | |||
| 83 | /* Found a board, allocate it an entry in the list */ | 83 | /* Found a board, allocate it an entry in the list */ |
| 84 | tdev = kzalloc(sizeof(*tdev), GFP_KERNEL); | 84 | tdev = kzalloc(sizeof(*tdev), GFP_KERNEL); |
| 85 | if (!tdev) { | 85 | if (!tdev) { |
| 86 | printk(KERN_ERR "tc%x: unable to allocate tc_dev\n", | 86 | pr_err("tc%x: unable to allocate tc_dev\n", slot); |
| 87 | slot); | ||
| 88 | goto out_err; | 87 | goto out_err; |
| 89 | } | 88 | } |
| 90 | dev_set_name(&tdev->dev, "tc%x", slot); | 89 | dev_set_name(&tdev->dev, "tc%x", slot); |
| @@ -117,10 +116,10 @@ static void __init tc_bus_add_devices(struct tc_bus *tbus) | |||
| 117 | tdev->resource.start = extslotaddr; | 116 | tdev->resource.start = extslotaddr; |
| 118 | tdev->resource.end = extslotaddr + devsize - 1; | 117 | tdev->resource.end = extslotaddr + devsize - 1; |
| 119 | } else { | 118 | } else { |
| 120 | printk(KERN_ERR "%s: Cannot provide slot space " | 119 | pr_err("%s: Cannot provide slot space " |
| 121 | "(%dMiB required, up to %dMiB supported)\n", | 120 | "(%ldMiB required, up to %ldMiB supported)\n", |
| 122 | dev_name(&tdev->dev), devsize >> 20, | 121 | dev_name(&tdev->dev), (long)(devsize >> 20), |
| 123 | max(slotsize, extslotsize) >> 20); | 122 | (long)(max(slotsize, extslotsize) >> 20)); |
| 124 | kfree(tdev); | 123 | kfree(tdev); |
| 125 | goto out_err; | 124 | goto out_err; |
| 126 | } | 125 | } |
| @@ -147,14 +146,12 @@ static int __init tc_init(void) | |||
| 147 | { | 146 | { |
| 148 | /* Initialize the TURBOchannel bus */ | 147 | /* Initialize the TURBOchannel bus */ |
| 149 | if (tc_bus_get_info(&tc_bus)) | 148 | if (tc_bus_get_info(&tc_bus)) |
| 150 | return 0; | 149 | goto out_err; |
| 151 | 150 | ||
| 152 | INIT_LIST_HEAD(&tc_bus.devices); | 151 | INIT_LIST_HEAD(&tc_bus.devices); |
| 153 | dev_set_name(&tc_bus.dev, "tc"); | 152 | dev_set_name(&tc_bus.dev, "tc"); |
| 154 | if (device_register(&tc_bus.dev)) { | 153 | if (device_register(&tc_bus.dev)) |
| 155 | put_device(&tc_bus.dev); | 154 | goto out_err_device; |
| 156 | return 0; | ||
| 157 | } | ||
| 158 | 155 | ||
| 159 | if (tc_bus.info.slot_size) { | 156 | if (tc_bus.info.slot_size) { |
| 160 | unsigned int tc_clock = tc_get_speed(&tc_bus) / 100000; | 157 | unsigned int tc_clock = tc_get_speed(&tc_bus) / 100000; |
| @@ -172,8 +169,8 @@ static int __init tc_init(void) | |||
| 172 | tc_bus.resource[0].flags = IORESOURCE_MEM; | 169 | tc_bus.resource[0].flags = IORESOURCE_MEM; |
| 173 | if (request_resource(&iomem_resource, | 170 | if (request_resource(&iomem_resource, |
| 174 | &tc_bus.resource[0]) < 0) { | 171 | &tc_bus.resource[0]) < 0) { |
| 175 | printk(KERN_ERR "tc: Cannot reserve resource\n"); | 172 | pr_err("tc: Cannot reserve resource\n"); |
| 176 | return 0; | 173 | goto out_err_device; |
| 177 | } | 174 | } |
| 178 | if (tc_bus.ext_slot_size) { | 175 | if (tc_bus.ext_slot_size) { |
| 179 | tc_bus.resource[1].start = tc_bus.ext_slot_base; | 176 | tc_bus.resource[1].start = tc_bus.ext_slot_base; |
| @@ -184,10 +181,8 @@ static int __init tc_init(void) | |||
| 184 | tc_bus.resource[1].flags = IORESOURCE_MEM; | 181 | tc_bus.resource[1].flags = IORESOURCE_MEM; |
| 185 | if (request_resource(&iomem_resource, | 182 | if (request_resource(&iomem_resource, |
| 186 | &tc_bus.resource[1]) < 0) { | 183 | &tc_bus.resource[1]) < 0) { |
| 187 | printk(KERN_ERR | 184 | pr_err("tc: Cannot reserve resource\n"); |
| 188 | "tc: Cannot reserve resource\n"); | 185 | goto out_err_resource; |
| 189 | release_resource(&tc_bus.resource[0]); | ||
| 190 | return 0; | ||
| 191 | } | 186 | } |
| 192 | } | 187 | } |
| 193 | 188 | ||
| @@ -195,6 +190,13 @@ static int __init tc_init(void) | |||
| 195 | } | 190 | } |
| 196 | 191 | ||
| 197 | return 0; | 192 | return 0; |
| 193 | |||
| 194 | out_err_resource: | ||
| 195 | release_resource(&tc_bus.resource[0]); | ||
| 196 | out_err_device: | ||
| 197 | put_device(&tc_bus.dev); | ||
| 198 | out_err: | ||
| 199 | return 0; | ||
| 198 | } | 200 | } |
| 199 | 201 | ||
| 200 | subsys_initcall(tc_init); | 202 | subsys_initcall(tc_init); |
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt index 370b24cee4d8..c055d56ec63d 100644 --- a/fs/Kconfig.binfmt +++ b/fs/Kconfig.binfmt | |||
| @@ -30,6 +30,9 @@ config COMPAT_BINFMT_ELF | |||
| 30 | config ARCH_BINFMT_ELF_RANDOMIZE_PIE | 30 | config ARCH_BINFMT_ELF_RANDOMIZE_PIE |
| 31 | bool | 31 | bool |
| 32 | 32 | ||
| 33 | config ARCH_BINFMT_ELF_STATE | ||
| 34 | bool | ||
| 35 | |||
| 33 | config BINFMT_ELF_FDPIC | 36 | config BINFMT_ELF_FDPIC |
| 34 | bool "Kernel support for FDPIC ELF binaries" | 37 | bool "Kernel support for FDPIC ELF binaries" |
| 35 | default y | 38 | default y |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 3a6175fe10c0..02b16910f4c9 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
| @@ -386,6 +386,127 @@ static unsigned long total_mapping_size(struct elf_phdr *cmds, int nr) | |||
| 386 | ELF_PAGESTART(cmds[first_idx].p_vaddr); | 386 | ELF_PAGESTART(cmds[first_idx].p_vaddr); |
| 387 | } | 387 | } |
| 388 | 388 | ||
| 389 | /** | ||
| 390 | * load_elf_phdrs() - load ELF program headers | ||
| 391 | * @elf_ex: ELF header of the binary whose program headers should be loaded | ||
| 392 | * @elf_file: the opened ELF binary file | ||
| 393 | * | ||
| 394 | * Loads ELF program headers from the binary file elf_file, which has the ELF | ||
| 395 | * header pointed to by elf_ex, into a newly allocated array. The caller is | ||
| 396 | * responsible for freeing the allocated data. Returns an ERR_PTR upon failure. | ||
| 397 | */ | ||
| 398 | static struct elf_phdr *load_elf_phdrs(struct elfhdr *elf_ex, | ||
| 399 | struct file *elf_file) | ||
| 400 | { | ||
| 401 | struct elf_phdr *elf_phdata = NULL; | ||
| 402 | int retval, size, err = -1; | ||
| 403 | |||
| 404 | /* | ||
| 405 | * If the size of this structure has changed, then punt, since | ||
| 406 | * we will be doing the wrong thing. | ||
| 407 | */ | ||
| 408 | if (elf_ex->e_phentsize != sizeof(struct elf_phdr)) | ||
| 409 | goto out; | ||
| 410 | |||
| 411 | /* Sanity check the number of program headers... */ | ||
| 412 | if (elf_ex->e_phnum < 1 || | ||
| 413 | elf_ex->e_phnum > 65536U / sizeof(struct elf_phdr)) | ||
| 414 | goto out; | ||
| 415 | |||
| 416 | /* ...and their total size. */ | ||
| 417 | size = sizeof(struct elf_phdr) * elf_ex->e_phnum; | ||
| 418 | if (size > ELF_MIN_ALIGN) | ||
| 419 | goto out; | ||
| 420 | |||
| 421 | elf_phdata = kmalloc(size, GFP_KERNEL); | ||
| 422 | if (!elf_phdata) | ||
| 423 | goto out; | ||
| 424 | |||
| 425 | /* Read in the program headers */ | ||
| 426 | retval = kernel_read(elf_file, elf_ex->e_phoff, | ||
| 427 | (char *)elf_phdata, size); | ||
| 428 | if (retval != size) { | ||
| 429 | err = (retval < 0) ? retval : -EIO; | ||
| 430 | goto out; | ||
| 431 | } | ||
| 432 | |||
| 433 | /* Success! */ | ||
| 434 | err = 0; | ||
| 435 | out: | ||
| 436 | if (err) { | ||
| 437 | kfree(elf_phdata); | ||
| 438 | elf_phdata = NULL; | ||
| 439 | } | ||
| 440 | return elf_phdata; | ||
| 441 | } | ||
| 442 | |||
| 443 | #ifndef CONFIG_ARCH_BINFMT_ELF_STATE | ||
| 444 | |||
| 445 | /** | ||
| 446 | * struct arch_elf_state - arch-specific ELF loading state | ||
| 447 | * | ||
| 448 | * This structure is used to preserve architecture specific data during | ||
| 449 | * the loading of an ELF file, throughout the checking of architecture | ||
| 450 | * specific ELF headers & through to the point where the ELF load is | ||
| 451 | * known to be proceeding (ie. SET_PERSONALITY). | ||
| 452 | * | ||
| 453 | * This implementation is a dummy for architectures which require no | ||
| 454 | * specific state. | ||
| 455 | */ | ||
| 456 | struct arch_elf_state { | ||
| 457 | }; | ||
| 458 | |||
| 459 | #define INIT_ARCH_ELF_STATE {} | ||
| 460 | |||
| 461 | /** | ||
| 462 | * arch_elf_pt_proc() - check a PT_LOPROC..PT_HIPROC ELF program header | ||
| 463 | * @ehdr: The main ELF header | ||
| 464 | * @phdr: The program header to check | ||
| 465 | * @elf: The open ELF file | ||
| 466 | * @is_interp: True if the phdr is from the interpreter of the ELF being | ||
| 467 | * loaded, else false. | ||
| 468 | * @state: Architecture-specific state preserved throughout the process | ||
| 469 | * of loading the ELF. | ||
| 470 | * | ||
| 471 | * Inspects the program header phdr to validate its correctness and/or | ||
| 472 | * suitability for the system. Called once per ELF program header in the | ||
| 473 | * range PT_LOPROC to PT_HIPROC, for both the ELF being loaded and its | ||
| 474 | * interpreter. | ||
| 475 | * | ||
| 476 | * Return: Zero to proceed with the ELF load, non-zero to fail the ELF load | ||
| 477 | * with that return code. | ||
| 478 | */ | ||
| 479 | static inline int arch_elf_pt_proc(struct elfhdr *ehdr, | ||
| 480 | struct elf_phdr *phdr, | ||
| 481 | struct file *elf, bool is_interp, | ||
| 482 | struct arch_elf_state *state) | ||
| 483 | { | ||
| 484 | /* Dummy implementation, always proceed */ | ||
| 485 | return 0; | ||
| 486 | } | ||
| 487 | |||
| 488 | /** | ||
| 489 | * arch_check_elf() - check a PT_LOPROC..PT_HIPROC ELF program header | ||
| 490 | * @ehdr: The main ELF header | ||
| 491 | * @has_interp: True if the ELF has an interpreter, else false. | ||
| 492 | * @state: Architecture-specific state preserved throughout the process | ||
| 493 | * of loading the ELF. | ||
| 494 | * | ||
| 495 | * Provides a final opportunity for architecture code to reject the loading | ||
| 496 | * of the ELF & cause an exec syscall to return an error. This is called after | ||
| 497 | * all program headers to be checked by arch_elf_pt_proc have been. | ||
| 498 | * | ||
| 499 | * Return: Zero to proceed with the ELF load, non-zero to fail the ELF load | ||
| 500 | * with that return code. | ||
| 501 | */ | ||
| 502 | static inline int arch_check_elf(struct elfhdr *ehdr, bool has_interp, | ||
| 503 | struct arch_elf_state *state) | ||
| 504 | { | ||
| 505 | /* Dummy implementation, always proceed */ | ||
| 506 | return 0; | ||
| 507 | } | ||
| 508 | |||
| 509 | #endif /* !CONFIG_ARCH_BINFMT_ELF_STATE */ | ||
| 389 | 510 | ||
| 390 | /* This is much more generalized than the library routine read function, | 511 | /* This is much more generalized than the library routine read function, |
| 391 | so we keep this separate. Technically the library read function | 512 | so we keep this separate. Technically the library read function |
| @@ -394,16 +515,15 @@ static unsigned long total_mapping_size(struct elf_phdr *cmds, int nr) | |||
| 394 | 515 | ||
| 395 | static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, | 516 | static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, |
| 396 | struct file *interpreter, unsigned long *interp_map_addr, | 517 | struct file *interpreter, unsigned long *interp_map_addr, |
| 397 | unsigned long no_base) | 518 | unsigned long no_base, struct elf_phdr *interp_elf_phdata) |
| 398 | { | 519 | { |
| 399 | struct elf_phdr *elf_phdata; | ||
| 400 | struct elf_phdr *eppnt; | 520 | struct elf_phdr *eppnt; |
| 401 | unsigned long load_addr = 0; | 521 | unsigned long load_addr = 0; |
| 402 | int load_addr_set = 0; | 522 | int load_addr_set = 0; |
| 403 | unsigned long last_bss = 0, elf_bss = 0; | 523 | unsigned long last_bss = 0, elf_bss = 0; |
| 404 | unsigned long error = ~0UL; | 524 | unsigned long error = ~0UL; |
| 405 | unsigned long total_size; | 525 | unsigned long total_size; |
| 406 | int retval, i, size; | 526 | int i; |
| 407 | 527 | ||
| 408 | /* First of all, some simple consistency checks */ | 528 | /* First of all, some simple consistency checks */ |
| 409 | if (interp_elf_ex->e_type != ET_EXEC && | 529 | if (interp_elf_ex->e_type != ET_EXEC && |
| @@ -414,40 +534,14 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, | |||
| 414 | if (!interpreter->f_op->mmap) | 534 | if (!interpreter->f_op->mmap) |
| 415 | goto out; | 535 | goto out; |
| 416 | 536 | ||
| 417 | /* | 537 | total_size = total_mapping_size(interp_elf_phdata, |
| 418 | * If the size of this structure has changed, then punt, since | 538 | interp_elf_ex->e_phnum); |
| 419 | * we will be doing the wrong thing. | ||
| 420 | */ | ||
| 421 | if (interp_elf_ex->e_phentsize != sizeof(struct elf_phdr)) | ||
| 422 | goto out; | ||
| 423 | if (interp_elf_ex->e_phnum < 1 || | ||
| 424 | interp_elf_ex->e_phnum > 65536U / sizeof(struct elf_phdr)) | ||
| 425 | goto out; | ||
| 426 | |||
| 427 | /* Now read in all of the header information */ | ||
| 428 | size = sizeof(struct elf_phdr) * interp_elf_ex->e_phnum; | ||
| 429 | if (size > ELF_MIN_ALIGN) | ||
| 430 | goto out; | ||
| 431 | elf_phdata = kmalloc(size, GFP_KERNEL); | ||
| 432 | if (!elf_phdata) | ||
| 433 | goto out; | ||
| 434 | |||
| 435 | retval = kernel_read(interpreter, interp_elf_ex->e_phoff, | ||
| 436 | (char *)elf_phdata, size); | ||
| 437 | error = -EIO; | ||
| 438 | if (retval != size) { | ||
| 439 | if (retval < 0) | ||
| 440 | error = retval; | ||
| 441 | goto out_close; | ||
| 442 | } | ||
| 443 | |||
| 444 | total_size = total_mapping_size(elf_phdata, interp_elf_ex->e_phnum); | ||
| 445 | if (!total_size) { | 539 | if (!total_size) { |
| 446 | error = -EINVAL; | 540 | error = -EINVAL; |
| 447 | goto out_close; | 541 | goto out; |
| 448 | } | 542 | } |
| 449 | 543 | ||
| 450 | eppnt = elf_phdata; | 544 | eppnt = interp_elf_phdata; |
| 451 | for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) { | 545 | for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) { |
| 452 | if (eppnt->p_type == PT_LOAD) { | 546 | if (eppnt->p_type == PT_LOAD) { |
| 453 | int elf_type = MAP_PRIVATE | MAP_DENYWRITE; | 547 | int elf_type = MAP_PRIVATE | MAP_DENYWRITE; |
| @@ -474,7 +568,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, | |||
| 474 | *interp_map_addr = map_addr; | 568 | *interp_map_addr = map_addr; |
| 475 | error = map_addr; | 569 | error = map_addr; |
| 476 | if (BAD_ADDR(map_addr)) | 570 | if (BAD_ADDR(map_addr)) |
| 477 | goto out_close; | 571 | goto out; |
| 478 | 572 | ||
| 479 | if (!load_addr_set && | 573 | if (!load_addr_set && |
| 480 | interp_elf_ex->e_type == ET_DYN) { | 574 | interp_elf_ex->e_type == ET_DYN) { |
| @@ -493,7 +587,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, | |||
| 493 | eppnt->p_memsz > TASK_SIZE || | 587 | eppnt->p_memsz > TASK_SIZE || |
| 494 | TASK_SIZE - eppnt->p_memsz < k) { | 588 | TASK_SIZE - eppnt->p_memsz < k) { |
| 495 | error = -ENOMEM; | 589 | error = -ENOMEM; |
| 496 | goto out_close; | 590 | goto out; |
| 497 | } | 591 | } |
| 498 | 592 | ||
| 499 | /* | 593 | /* |
| @@ -523,7 +617,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, | |||
| 523 | */ | 617 | */ |
| 524 | if (padzero(elf_bss)) { | 618 | if (padzero(elf_bss)) { |
| 525 | error = -EFAULT; | 619 | error = -EFAULT; |
| 526 | goto out_close; | 620 | goto out; |
| 527 | } | 621 | } |
| 528 | 622 | ||
| 529 | /* What we have mapped so far */ | 623 | /* What we have mapped so far */ |
| @@ -532,13 +626,10 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, | |||
| 532 | /* Map the last of the bss segment */ | 626 | /* Map the last of the bss segment */ |
| 533 | error = vm_brk(elf_bss, last_bss - elf_bss); | 627 | error = vm_brk(elf_bss, last_bss - elf_bss); |
| 534 | if (BAD_ADDR(error)) | 628 | if (BAD_ADDR(error)) |
| 535 | goto out_close; | 629 | goto out; |
| 536 | } | 630 | } |
| 537 | 631 | ||
| 538 | error = load_addr; | 632 | error = load_addr; |
| 539 | |||
| 540 | out_close: | ||
| 541 | kfree(elf_phdata); | ||
| 542 | out: | 633 | out: |
| 543 | return error; | 634 | return error; |
| 544 | } | 635 | } |
| @@ -575,10 +666,9 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
| 575 | int load_addr_set = 0; | 666 | int load_addr_set = 0; |
| 576 | char * elf_interpreter = NULL; | 667 | char * elf_interpreter = NULL; |
| 577 | unsigned long error; | 668 | unsigned long error; |
| 578 | struct elf_phdr *elf_ppnt, *elf_phdata; | 669 | struct elf_phdr *elf_ppnt, *elf_phdata, *interp_elf_phdata = NULL; |
| 579 | unsigned long elf_bss, elf_brk; | 670 | unsigned long elf_bss, elf_brk; |
| 580 | int retval, i; | 671 | int retval, i; |
| 581 | unsigned int size; | ||
| 582 | unsigned long elf_entry; | 672 | unsigned long elf_entry; |
| 583 | unsigned long interp_load_addr = 0; | 673 | unsigned long interp_load_addr = 0; |
| 584 | unsigned long start_code, end_code, start_data, end_data; | 674 | unsigned long start_code, end_code, start_data, end_data; |
| @@ -589,6 +679,7 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
| 589 | struct elfhdr elf_ex; | 679 | struct elfhdr elf_ex; |
| 590 | struct elfhdr interp_elf_ex; | 680 | struct elfhdr interp_elf_ex; |
| 591 | } *loc; | 681 | } *loc; |
| 682 | struct arch_elf_state arch_state = INIT_ARCH_ELF_STATE; | ||
| 592 | 683 | ||
| 593 | loc = kmalloc(sizeof(*loc), GFP_KERNEL); | 684 | loc = kmalloc(sizeof(*loc), GFP_KERNEL); |
| 594 | if (!loc) { | 685 | if (!loc) { |
| @@ -611,26 +702,10 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
| 611 | if (!bprm->file->f_op->mmap) | 702 | if (!bprm->file->f_op->mmap) |
| 612 | goto out; | 703 | goto out; |
| 613 | 704 | ||
| 614 | /* Now read in all of the header information */ | 705 | elf_phdata = load_elf_phdrs(&loc->elf_ex, bprm->file); |
| 615 | if (loc->elf_ex.e_phentsize != sizeof(struct elf_phdr)) | ||
| 616 | goto out; | ||
| 617 | if (loc->elf_ex.e_phnum < 1 || | ||
| 618 | loc->elf_ex.e_phnum > 65536U / sizeof(struct elf_phdr)) | ||
| 619 | goto out; | ||
| 620 | size = loc->elf_ex.e_phnum * sizeof(struct elf_phdr); | ||
| 621 | retval = -ENOMEM; | ||
| 622 | elf_phdata = kmalloc(size, GFP_KERNEL); | ||
| 623 | if (!elf_phdata) | 706 | if (!elf_phdata) |
| 624 | goto out; | 707 | goto out; |
| 625 | 708 | ||
| 626 | retval = kernel_read(bprm->file, loc->elf_ex.e_phoff, | ||
| 627 | (char *)elf_phdata, size); | ||
| 628 | if (retval != size) { | ||
| 629 | if (retval >= 0) | ||
| 630 | retval = -EIO; | ||
| 631 | goto out_free_ph; | ||
| 632 | } | ||
| 633 | |||
| 634 | elf_ppnt = elf_phdata; | 709 | elf_ppnt = elf_phdata; |
| 635 | elf_bss = 0; | 710 | elf_bss = 0; |
| 636 | elf_brk = 0; | 711 | elf_brk = 0; |
| @@ -699,12 +774,21 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
| 699 | 774 | ||
| 700 | elf_ppnt = elf_phdata; | 775 | elf_ppnt = elf_phdata; |
| 701 | for (i = 0; i < loc->elf_ex.e_phnum; i++, elf_ppnt++) | 776 | for (i = 0; i < loc->elf_ex.e_phnum; i++, elf_ppnt++) |
| 702 | if (elf_ppnt->p_type == PT_GNU_STACK) { | 777 | switch (elf_ppnt->p_type) { |
| 778 | case PT_GNU_STACK: | ||
| 703 | if (elf_ppnt->p_flags & PF_X) | 779 | if (elf_ppnt->p_flags & PF_X) |
| 704 | executable_stack = EXSTACK_ENABLE_X; | 780 | executable_stack = EXSTACK_ENABLE_X; |
| 705 | else | 781 | else |
| 706 | executable_stack = EXSTACK_DISABLE_X; | 782 | executable_stack = EXSTACK_DISABLE_X; |
| 707 | break; | 783 | break; |
| 784 | |||
| 785 | case PT_LOPROC ... PT_HIPROC: | ||
| 786 | retval = arch_elf_pt_proc(&loc->elf_ex, elf_ppnt, | ||
| 787 | bprm->file, false, | ||
| 788 | &arch_state); | ||
| 789 | if (retval) | ||
| 790 | goto out_free_dentry; | ||
| 791 | break; | ||
| 708 | } | 792 | } |
| 709 | 793 | ||
| 710 | /* Some simple consistency checks for the interpreter */ | 794 | /* Some simple consistency checks for the interpreter */ |
| @@ -716,8 +800,36 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
| 716 | /* Verify the interpreter has a valid arch */ | 800 | /* Verify the interpreter has a valid arch */ |
| 717 | if (!elf_check_arch(&loc->interp_elf_ex)) | 801 | if (!elf_check_arch(&loc->interp_elf_ex)) |
| 718 | goto out_free_dentry; | 802 | goto out_free_dentry; |
| 803 | |||
| 804 | /* Load the interpreter program headers */ | ||
| 805 | interp_elf_phdata = load_elf_phdrs(&loc->interp_elf_ex, | ||
| 806 | interpreter); | ||
| 807 | if (!interp_elf_phdata) | ||
| 808 | goto out_free_dentry; | ||
| 809 | |||
| 810 | /* Pass PT_LOPROC..PT_HIPROC headers to arch code */ | ||
| 811 | elf_ppnt = interp_elf_phdata; | ||
| 812 | for (i = 0; i < loc->interp_elf_ex.e_phnum; i++, elf_ppnt++) | ||
| 813 | switch (elf_ppnt->p_type) { | ||
| 814 | case PT_LOPROC ... PT_HIPROC: | ||
| 815 | retval = arch_elf_pt_proc(&loc->interp_elf_ex, | ||
| 816 | elf_ppnt, interpreter, | ||
| 817 | true, &arch_state); | ||
| 818 | if (retval) | ||
| 819 | goto out_free_dentry; | ||
| 820 | break; | ||
| 821 | } | ||
| 719 | } | 822 | } |
| 720 | 823 | ||
| 824 | /* | ||
| 825 | * Allow arch code to reject the ELF at this point, whilst it's | ||
| 826 | * still possible to return an error to the code that invoked | ||
| 827 | * the exec syscall. | ||
| 828 | */ | ||
| 829 | retval = arch_check_elf(&loc->elf_ex, !!interpreter, &arch_state); | ||
| 830 | if (retval) | ||
| 831 | goto out_free_dentry; | ||
| 832 | |||
| 721 | /* Flush all traces of the currently running executable */ | 833 | /* Flush all traces of the currently running executable */ |
| 722 | retval = flush_old_exec(bprm); | 834 | retval = flush_old_exec(bprm); |
| 723 | if (retval) | 835 | if (retval) |
| @@ -725,7 +837,7 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
| 725 | 837 | ||
| 726 | /* Do this immediately, since STACK_TOP as used in setup_arg_pages | 838 | /* Do this immediately, since STACK_TOP as used in setup_arg_pages |
| 727 | may depend on the personality. */ | 839 | may depend on the personality. */ |
| 728 | SET_PERSONALITY(loc->elf_ex); | 840 | SET_PERSONALITY2(loc->elf_ex, &arch_state); |
| 729 | if (elf_read_implies_exec(loc->elf_ex, executable_stack)) | 841 | if (elf_read_implies_exec(loc->elf_ex, executable_stack)) |
| 730 | current->personality |= READ_IMPLIES_EXEC; | 842 | current->personality |= READ_IMPLIES_EXEC; |
| 731 | 843 | ||
| @@ -890,7 +1002,7 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
| 890 | elf_entry = load_elf_interp(&loc->interp_elf_ex, | 1002 | elf_entry = load_elf_interp(&loc->interp_elf_ex, |
| 891 | interpreter, | 1003 | interpreter, |
| 892 | &interp_map_addr, | 1004 | &interp_map_addr, |
| 893 | load_bias); | 1005 | load_bias, interp_elf_phdata); |
| 894 | if (!IS_ERR((void *)elf_entry)) { | 1006 | if (!IS_ERR((void *)elf_entry)) { |
| 895 | /* | 1007 | /* |
| 896 | * load_elf_interp() returns relocation | 1008 | * load_elf_interp() returns relocation |
| @@ -917,6 +1029,7 @@ static int load_elf_binary(struct linux_binprm *bprm) | |||
| 917 | } | 1029 | } |
| 918 | } | 1030 | } |
| 919 | 1031 | ||
| 1032 | kfree(interp_elf_phdata); | ||
| 920 | kfree(elf_phdata); | 1033 | kfree(elf_phdata); |
| 921 | 1034 | ||
| 922 | set_binfmt(&elf_format); | 1035 | set_binfmt(&elf_format); |
| @@ -981,6 +1094,7 @@ out_ret: | |||
| 981 | 1094 | ||
| 982 | /* error cleanup */ | 1095 | /* error cleanup */ |
| 983 | out_free_dentry: | 1096 | out_free_dentry: |
| 1097 | kfree(interp_elf_phdata); | ||
| 984 | allow_write_access(interpreter); | 1098 | allow_write_access(interpreter); |
| 985 | if (interpreter) | 1099 | if (interpreter) |
| 986 | fput(interpreter); | 1100 | fput(interpreter); |
diff --git a/include/dt-bindings/interrupt-controller/mips-gic.h b/include/dt-bindings/interrupt-controller/mips-gic.h new file mode 100644 index 000000000000..cf35a577e371 --- /dev/null +++ b/include/dt-bindings/interrupt-controller/mips-gic.h | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | #ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_MIPS_GIC_H | ||
| 2 | #define _DT_BINDINGS_INTERRUPT_CONTROLLER_MIPS_GIC_H | ||
| 3 | |||
| 4 | #include <dt-bindings/interrupt-controller/irq.h> | ||
| 5 | |||
| 6 | #define GIC_SHARED 0 | ||
| 7 | #define GIC_LOCAL 1 | ||
| 8 | |||
| 9 | #endif | ||
diff --git a/include/linux/elf.h b/include/linux/elf.h index 67a5fa7830c4..20fa8d8ae313 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h | |||
| @@ -15,6 +15,11 @@ | |||
| 15 | set_personality(PER_LINUX | (current->personality & (~PER_MASK))) | 15 | set_personality(PER_LINUX | (current->personality & (~PER_MASK))) |
| 16 | #endif | 16 | #endif |
| 17 | 17 | ||
| 18 | #ifndef SET_PERSONALITY2 | ||
| 19 | #define SET_PERSONALITY2(ex, state) \ | ||
| 20 | SET_PERSONALITY(ex) | ||
| 21 | #endif | ||
| 22 | |||
| 18 | #if ELF_CLASS == ELFCLASS32 | 23 | #if ELF_CLASS == ELFCLASS32 |
| 19 | 24 | ||
| 20 | extern Elf32_Dyn _DYNAMIC []; | 25 | extern Elf32_Dyn _DYNAMIC []; |
diff --git a/arch/mips/include/asm/gic.h b/include/linux/irqchip/mips-gic.h index d7699cf7e135..420f77b34d02 100644 --- a/arch/mips/include/asm/gic.h +++ b/include/linux/irqchip/mips-gic.h | |||
| @@ -4,57 +4,26 @@ | |||
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2000, 07 MIPS Technologies, Inc. | 6 | * Copyright (C) 2000, 07 MIPS Technologies, Inc. |
| 7 | * | ||
| 8 | * GIC Register Definitions | ||
| 9 | * | ||
| 10 | */ | 7 | */ |
| 11 | #ifndef _ASM_GICREGS_H | 8 | #ifndef __LINUX_IRQCHIP_MIPS_GIC_H |
| 12 | #define _ASM_GICREGS_H | 9 | #define __LINUX_IRQCHIP_MIPS_GIC_H |
| 13 | |||
| 14 | #include <linux/bitmap.h> | ||
| 15 | #include <linux/threads.h> | ||
| 16 | 10 | ||
| 17 | #include <irq.h> | 11 | #include <linux/clocksource.h> |
| 18 | 12 | ||
| 19 | #undef GICISBYTELITTLEENDIAN | 13 | #define GIC_MAX_INTRS 256 |
| 20 | 14 | ||
| 21 | /* Constants */ | 15 | /* Constants */ |
| 22 | #define GIC_POL_POS 1 | 16 | #define GIC_POL_POS 1 |
| 23 | #define GIC_POL_NEG 0 | 17 | #define GIC_POL_NEG 0 |
| 24 | #define GIC_TRIG_EDGE 1 | 18 | #define GIC_TRIG_EDGE 1 |
| 25 | #define GIC_TRIG_LEVEL 0 | 19 | #define GIC_TRIG_LEVEL 0 |
| 20 | #define GIC_TRIG_DUAL_ENABLE 1 | ||
| 21 | #define GIC_TRIG_DUAL_DISABLE 0 | ||
| 26 | 22 | ||
| 27 | #define MSK(n) ((1 << (n)) - 1) | 23 | #define MSK(n) ((1 << (n)) - 1) |
| 28 | #define REG32(addr) (*(volatile unsigned int *) (addr)) | ||
| 29 | #define REG(base, offs) REG32((unsigned long)(base) + offs##_##OFS) | ||
| 30 | #define REGP(base, phys) REG32((unsigned long)(base) + (phys)) | ||
| 31 | 24 | ||
| 32 | /* Accessors */ | 25 | /* Accessors */ |
| 33 | #define GIC_REG(segment, offset) \ | 26 | #define GIC_REG(segment, offset) (segment##_##SECTION_OFS + offset##_##OFS) |
| 34 | REG32(_gic_base + segment##_##SECTION_OFS + offset##_##OFS) | ||
| 35 | #define GIC_REG_ADDR(segment, offset) \ | ||
| 36 | REG32(_gic_base + segment##_##SECTION_OFS + offset) | ||
| 37 | |||
| 38 | #define GIC_ABS_REG(segment, offset) \ | ||
| 39 | (_gic_base + segment##_##SECTION_OFS + offset##_##OFS) | ||
| 40 | #define GIC_REG_ABS_ADDR(segment, offset) \ | ||
| 41 | (_gic_base + segment##_##SECTION_OFS + offset) | ||
| 42 | |||
| 43 | #ifdef GICISBYTELITTLEENDIAN | ||
| 44 | #define GICREAD(reg, data) ((data) = (reg), (data) = le32_to_cpu(data)) | ||
| 45 | #define GICWRITE(reg, data) ((reg) = cpu_to_le32(data)) | ||
| 46 | #else | ||
| 47 | #define GICREAD(reg, data) ((data) = (reg)) | ||
| 48 | #define GICWRITE(reg, data) ((reg) = (data)) | ||
| 49 | #endif | ||
| 50 | #define GICBIS(reg, mask, bits) \ | ||
| 51 | do { u32 data; \ | ||
| 52 | GICREAD(reg, data); \ | ||
| 53 | data &= ~(mask); \ | ||
| 54 | data |= ((bits) & (mask)); \ | ||
| 55 | GICWRITE((reg), data); \ | ||
| 56 | } while (0) | ||
| 57 | |||
| 58 | 27 | ||
| 59 | /* GIC Address Space */ | 28 | /* GIC Address Space */ |
| 60 | #define SHARED_SECTION_OFS 0x0000 | 29 | #define SHARED_SECTION_OFS 0x0000 |
| @@ -75,120 +44,42 @@ | |||
| 75 | #define GIC_SH_COUNTER_63_32_OFS 0x0014 | 44 | #define GIC_SH_COUNTER_63_32_OFS 0x0014 |
| 76 | #define GIC_SH_REVISIONID_OFS 0x0020 | 45 | #define GIC_SH_REVISIONID_OFS 0x0020 |
| 77 | 46 | ||
| 78 | /* Interrupt Polarity */ | 47 | /* Convert an interrupt number to a byte offset/bit for multi-word registers */ |
| 79 | #define GIC_SH_POL_31_0_OFS 0x0100 | 48 | #define GIC_INTR_OFS(intr) (((intr) / 32) * 4) |
| 80 | #define GIC_SH_POL_63_32_OFS 0x0104 | 49 | #define GIC_INTR_BIT(intr) ((intr) % 32) |
| 81 | #define GIC_SH_POL_95_64_OFS 0x0108 | 50 | |
| 82 | #define GIC_SH_POL_127_96_OFS 0x010c | 51 | /* Polarity : Reset Value is always 0 */ |
| 83 | #define GIC_SH_POL_159_128_OFS 0x0110 | 52 | #define GIC_SH_SET_POLARITY_OFS 0x0100 |
| 84 | #define GIC_SH_POL_191_160_OFS 0x0114 | 53 | |
| 85 | #define GIC_SH_POL_223_192_OFS 0x0118 | 54 | /* Triggering : Reset Value is always 0 */ |
| 86 | #define GIC_SH_POL_255_224_OFS 0x011c | 55 | #define GIC_SH_SET_TRIGGER_OFS 0x0180 |
| 87 | 56 | ||
| 88 | /* Edge/Level Triggering */ | 57 | /* Dual edge triggering : Reset Value is always 0 */ |
| 89 | #define GIC_SH_TRIG_31_0_OFS 0x0180 | 58 | #define GIC_SH_SET_DUAL_OFS 0x0200 |
| 90 | #define GIC_SH_TRIG_63_32_OFS 0x0184 | ||
| 91 | #define GIC_SH_TRIG_95_64_OFS 0x0188 | ||
| 92 | #define GIC_SH_TRIG_127_96_OFS 0x018c | ||
| 93 | #define GIC_SH_TRIG_159_128_OFS 0x0190 | ||
| 94 | #define GIC_SH_TRIG_191_160_OFS 0x0194 | ||
| 95 | #define GIC_SH_TRIG_223_192_OFS 0x0198 | ||
| 96 | #define GIC_SH_TRIG_255_224_OFS 0x019c | ||
| 97 | |||
| 98 | /* Dual Edge Triggering */ | ||
| 99 | #define GIC_SH_DUAL_31_0_OFS 0x0200 | ||
| 100 | #define GIC_SH_DUAL_63_32_OFS 0x0204 | ||
| 101 | #define GIC_SH_DUAL_95_64_OFS 0x0208 | ||
| 102 | #define GIC_SH_DUAL_127_96_OFS 0x020c | ||
| 103 | #define GIC_SH_DUAL_159_128_OFS 0x0210 | ||
| 104 | #define GIC_SH_DUAL_191_160_OFS 0x0214 | ||
| 105 | #define GIC_SH_DUAL_223_192_OFS 0x0218 | ||
| 106 | #define GIC_SH_DUAL_255_224_OFS 0x021c | ||
| 107 | 59 | ||
| 108 | /* Set/Clear corresponding bit in Edge Detect Register */ | 60 | /* Set/Clear corresponding bit in Edge Detect Register */ |
| 109 | #define GIC_SH_WEDGE_OFS 0x0280 | 61 | #define GIC_SH_WEDGE_OFS 0x0280 |
| 110 | 62 | ||
| 111 | /* Reset Mask - Disables Interrupt */ | 63 | /* Mask manipulation */ |
| 112 | #define GIC_SH_RMASK_31_0_OFS 0x0300 | 64 | #define GIC_SH_RMASK_OFS 0x0300 |
| 113 | #define GIC_SH_RMASK_63_32_OFS 0x0304 | 65 | #define GIC_SH_SMASK_OFS 0x0380 |
| 114 | #define GIC_SH_RMASK_95_64_OFS 0x0308 | ||
| 115 | #define GIC_SH_RMASK_127_96_OFS 0x030c | ||
| 116 | #define GIC_SH_RMASK_159_128_OFS 0x0310 | ||
| 117 | #define GIC_SH_RMASK_191_160_OFS 0x0314 | ||
| 118 | #define GIC_SH_RMASK_223_192_OFS 0x0318 | ||
| 119 | #define GIC_SH_RMASK_255_224_OFS 0x031c | ||
| 120 | |||
| 121 | /* Set Mask (WO) - Enables Interrupt */ | ||
| 122 | #define GIC_SH_SMASK_31_0_OFS 0x0380 | ||
| 123 | #define GIC_SH_SMASK_63_32_OFS 0x0384 | ||
| 124 | #define GIC_SH_SMASK_95_64_OFS 0x0388 | ||
| 125 | #define GIC_SH_SMASK_127_96_OFS 0x038c | ||
| 126 | #define GIC_SH_SMASK_159_128_OFS 0x0390 | ||
| 127 | #define GIC_SH_SMASK_191_160_OFS 0x0394 | ||
| 128 | #define GIC_SH_SMASK_223_192_OFS 0x0398 | ||
| 129 | #define GIC_SH_SMASK_255_224_OFS 0x039c | ||
| 130 | 66 | ||
| 131 | /* Global Interrupt Mask Register (RO) - Bit Set == Interrupt enabled */ | 67 | /* Global Interrupt Mask Register (RO) - Bit Set == Interrupt enabled */ |
| 132 | #define GIC_SH_MASK_31_0_OFS 0x0400 | 68 | #define GIC_SH_MASK_OFS 0x0400 |
| 133 | #define GIC_SH_MASK_63_32_OFS 0x0404 | ||
| 134 | #define GIC_SH_MASK_95_64_OFS 0x0408 | ||
| 135 | #define GIC_SH_MASK_127_96_OFS 0x040c | ||
| 136 | #define GIC_SH_MASK_159_128_OFS 0x0410 | ||
| 137 | #define GIC_SH_MASK_191_160_OFS 0x0414 | ||
| 138 | #define GIC_SH_MASK_223_192_OFS 0x0418 | ||
| 139 | #define GIC_SH_MASK_255_224_OFS 0x041c | ||
| 140 | 69 | ||
| 141 | /* Pending Global Interrupts (RO) */ | 70 | /* Pending Global Interrupts (RO) */ |
| 142 | #define GIC_SH_PEND_31_0_OFS 0x0480 | 71 | #define GIC_SH_PEND_OFS 0x0480 |
| 143 | #define GIC_SH_PEND_63_32_OFS 0x0484 | ||
| 144 | #define GIC_SH_PEND_95_64_OFS 0x0488 | ||
| 145 | #define GIC_SH_PEND_127_96_OFS 0x048c | ||
| 146 | #define GIC_SH_PEND_159_128_OFS 0x0490 | ||
| 147 | #define GIC_SH_PEND_191_160_OFS 0x0494 | ||
| 148 | #define GIC_SH_PEND_223_192_OFS 0x0498 | ||
| 149 | #define GIC_SH_PEND_255_224_OFS 0x049c | ||
| 150 | |||
| 151 | #define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500 | ||
| 152 | 72 | ||
| 153 | /* Maps Interrupt X to a Pin */ | 73 | /* Maps Interrupt X to a Pin */ |
| 154 | #define GIC_SH_MAP_TO_PIN(intr) \ | 74 | #define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500 |
| 155 | (GIC_SH_INTR_MAP_TO_PIN_BASE_OFS + (4 * intr)) | 75 | #define GIC_SH_MAP_TO_PIN(intr) (4 * (intr)) |
| 156 | |||
| 157 | #define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2000 | ||
| 158 | 76 | ||
| 159 | /* Maps Interrupt X to a VPE */ | 77 | /* Maps Interrupt X to a VPE */ |
| 78 | #define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2000 | ||
| 160 | #define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \ | 79 | #define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \ |
| 161 | (GIC_SH_INTR_MAP_TO_VPE_BASE_OFS + (32 * (intr)) + (((vpe) / 32) * 4)) | 80 | ((32 * (intr)) + (((vpe) / 32) * 4)) |
| 162 | #define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32)) | 81 | #define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32)) |
| 163 | 82 | ||
| 164 | /* Convert an interrupt number to a byte offset/bit for multi-word registers */ | ||
| 165 | #define GIC_INTR_OFS(intr) (((intr) / 32)*4) | ||
| 166 | #define GIC_INTR_BIT(intr) ((intr) % 32) | ||
| 167 | |||
| 168 | /* Polarity : Reset Value is always 0 */ | ||
| 169 | #define GIC_SH_SET_POLARITY_OFS 0x0100 | ||
| 170 | #define GIC_SET_POLARITY(intr, pol) \ | ||
| 171 | GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + \ | ||
| 172 | GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \ | ||
| 173 | (pol) << GIC_INTR_BIT(intr)) | ||
| 174 | |||
| 175 | /* Triggering : Reset Value is always 0 */ | ||
| 176 | #define GIC_SH_SET_TRIGGER_OFS 0x0180 | ||
| 177 | #define GIC_SET_TRIGGER(intr, trig) \ | ||
| 178 | GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + \ | ||
| 179 | GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \ | ||
| 180 | (trig) << GIC_INTR_BIT(intr)) | ||
| 181 | |||
| 182 | /* Mask manipulation */ | ||
| 183 | #define GIC_SH_SMASK_OFS 0x0380 | ||
| 184 | #define GIC_SET_INTR_MASK(intr) \ | ||
| 185 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + \ | ||
| 186 | GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr)) | ||
| 187 | #define GIC_SH_RMASK_OFS 0x0300 | ||
| 188 | #define GIC_CLR_INTR_MASK(intr) \ | ||
| 189 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + \ | ||
| 190 | GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr)) | ||
| 191 | |||
| 192 | /* Register Map for Local Section */ | 83 | /* Register Map for Local Section */ |
| 193 | #define GIC_VPE_CTL_OFS 0x0000 | 84 | #define GIC_VPE_CTL_OFS 0x0000 |
| 194 | #define GIC_VPE_PEND_OFS 0x0004 | 85 | #define GIC_VPE_PEND_OFS 0x0004 |
| @@ -198,6 +89,7 @@ | |||
| 198 | #define GIC_VPE_WD_MAP_OFS 0x0040 | 89 | #define GIC_VPE_WD_MAP_OFS 0x0040 |
| 199 | #define GIC_VPE_COMPARE_MAP_OFS 0x0044 | 90 | #define GIC_VPE_COMPARE_MAP_OFS 0x0044 |
| 200 | #define GIC_VPE_TIMER_MAP_OFS 0x0048 | 91 | #define GIC_VPE_TIMER_MAP_OFS 0x0048 |
| 92 | #define GIC_VPE_FDC_MAP_OFS 0x004c | ||
| 201 | #define GIC_VPE_PERFCTR_MAP_OFS 0x0050 | 93 | #define GIC_VPE_PERFCTR_MAP_OFS 0x0050 |
| 202 | #define GIC_VPE_SWINT0_MAP_OFS 0x0054 | 94 | #define GIC_VPE_SWINT0_MAP_OFS 0x0054 |
| 203 | #define GIC_VPE_SWINT1_MAP_OFS 0x0058 | 95 | #define GIC_VPE_SWINT1_MAP_OFS 0x0058 |
| @@ -208,13 +100,11 @@ | |||
| 208 | #define GIC_VPE_COMPARE_LO_OFS 0x00a0 | 100 | #define GIC_VPE_COMPARE_LO_OFS 0x00a0 |
| 209 | #define GIC_VPE_COMPARE_HI_OFS 0x00a4 | 101 | #define GIC_VPE_COMPARE_HI_OFS 0x00a4 |
| 210 | 102 | ||
| 211 | #define GIC_VPE_EIC_SHADOW_SET_BASE 0x0100 | 103 | #define GIC_VPE_EIC_SHADOW_SET_BASE_OFS 0x0100 |
| 212 | #define GIC_VPE_EIC_SS(intr) \ | 104 | #define GIC_VPE_EIC_SS(intr) (4 * (intr)) |
| 213 | (GIC_VPE_EIC_SHADOW_SET_BASE + (4 * intr)) | ||
| 214 | 105 | ||
| 215 | #define GIC_VPE_EIC_VEC_BASE 0x0800 | 106 | #define GIC_VPE_EIC_VEC_BASE_OFS 0x0800 |
| 216 | #define GIC_VPE_EIC_VEC(intr) \ | 107 | #define GIC_VPE_EIC_VEC(intr) (4 * (intr)) |
| 217 | (GIC_VPE_EIC_VEC_BASE + (4 * intr)) | ||
| 218 | 108 | ||
| 219 | #define GIC_VPE_TENABLE_NMI_OFS 0x1000 | 109 | #define GIC_VPE_TENABLE_NMI_OFS 0x1000 |
| 220 | #define GIC_VPE_TENABLE_YQ_OFS 0x1004 | 110 | #define GIC_VPE_TENABLE_YQ_OFS 0x1004 |
| @@ -238,8 +128,8 @@ | |||
| 238 | #define GIC_SH_CONFIG_NUMVPES_SHF 0 | 128 | #define GIC_SH_CONFIG_NUMVPES_SHF 0 |
| 239 | #define GIC_SH_CONFIG_NUMVPES_MSK (MSK(8) << GIC_SH_CONFIG_NUMVPES_SHF) | 129 | #define GIC_SH_CONFIG_NUMVPES_MSK (MSK(8) << GIC_SH_CONFIG_NUMVPES_SHF) |
| 240 | 130 | ||
| 241 | #define GIC_SH_WEDGE_SET(intr) (intr | (0x1 << 31)) | 131 | #define GIC_SH_WEDGE_SET(intr) ((intr) | (0x1 << 31)) |
| 242 | #define GIC_SH_WEDGE_CLR(intr) (intr & ~(0x1 << 31)) | 132 | #define GIC_SH_WEDGE_CLR(intr) ((intr) & ~(0x1 << 31)) |
| 243 | 133 | ||
| 244 | #define GIC_MAP_TO_PIN_SHF 31 | 134 | #define GIC_MAP_TO_PIN_SHF 31 |
| 245 | #define GIC_MAP_TO_PIN_MSK (MSK(1) << GIC_MAP_TO_PIN_SHF) | 135 | #define GIC_MAP_TO_PIN_MSK (MSK(1) << GIC_MAP_TO_PIN_SHF) |
| @@ -251,6 +141,10 @@ | |||
| 251 | #define GIC_MAP_MSK (MSK(6) << GIC_MAP_SHF) | 141 | #define GIC_MAP_MSK (MSK(6) << GIC_MAP_SHF) |
| 252 | 142 | ||
| 253 | /* GIC_VPE_CTL Masks */ | 143 | /* GIC_VPE_CTL Masks */ |
| 144 | #define GIC_VPE_CTL_FDC_RTBL_SHF 4 | ||
| 145 | #define GIC_VPE_CTL_FDC_RTBL_MSK (MSK(1) << GIC_VPE_CTL_FDC_RTBL_SHF) | ||
| 146 | #define GIC_VPE_CTL_SWINT_RTBL_SHF 3 | ||
| 147 | #define GIC_VPE_CTL_SWINT_RTBL_MSK (MSK(1) << GIC_VPE_CTL_SWINT_RTBL_SHF) | ||
| 254 | #define GIC_VPE_CTL_PERFCNT_RTBL_SHF 2 | 148 | #define GIC_VPE_CTL_PERFCNT_RTBL_SHF 2 |
| 255 | #define GIC_VPE_CTL_PERFCNT_RTBL_MSK (MSK(1) << GIC_VPE_CTL_PERFCNT_RTBL_SHF) | 149 | #define GIC_VPE_CTL_PERFCNT_RTBL_MSK (MSK(1) << GIC_VPE_CTL_PERFCNT_RTBL_SHF) |
| 256 | #define GIC_VPE_CTL_TIMER_RTBL_SHF 1 | 150 | #define GIC_VPE_CTL_TIMER_RTBL_SHF 1 |
| @@ -300,38 +194,6 @@ | |||
| 300 | #define GIC_VPE_SMASK_SWINT1_SHF 5 | 194 | #define GIC_VPE_SMASK_SWINT1_SHF 5 |
| 301 | #define GIC_VPE_SMASK_SWINT1_MSK (MSK(1) << GIC_VPE_SMASK_SWINT1_SHF) | 195 | #define GIC_VPE_SMASK_SWINT1_MSK (MSK(1) << GIC_VPE_SMASK_SWINT1_SHF) |
| 302 | 196 | ||
| 303 | /* | ||
| 304 | * Set the Mapping of Interrupt X to a VPE. | ||
| 305 | */ | ||
| 306 | #define GIC_SH_MAP_TO_VPE_SMASK(intr, vpe) \ | ||
| 307 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe)), \ | ||
| 308 | GIC_SH_MAP_TO_VPE_REG_BIT(vpe)) | ||
| 309 | |||
| 310 | /* | ||
| 311 | * Interrupt Meta-data specification. The ipiflag helps | ||
| 312 | * in building ipi_map. | ||
| 313 | */ | ||
| 314 | struct gic_intr_map { | ||
| 315 | unsigned int cpunum; /* Directed to this CPU */ | ||
| 316 | #define GIC_UNUSED 0xdead /* Dummy data */ | ||
| 317 | unsigned int pin; /* Directed to this Pin */ | ||
| 318 | unsigned int polarity; /* Polarity : +/- */ | ||
| 319 | unsigned int trigtype; /* Trigger : Edge/Levl */ | ||
| 320 | unsigned int flags; /* Misc flags */ | ||
| 321 | #define GIC_FLAG_TRANSPARENT 0x01 | ||
| 322 | }; | ||
| 323 | |||
| 324 | /* | ||
| 325 | * This is only used in EIC mode. This helps to figure out which | ||
| 326 | * shared interrupts we need to process when we get a vector interrupt. | ||
| 327 | */ | ||
| 328 | #define GIC_MAX_SHARED_INTR 0x5 | ||
| 329 | struct gic_shared_intr_map { | ||
| 330 | unsigned int num_shared_intr; | ||
| 331 | unsigned int intr_list[GIC_MAX_SHARED_INTR]; | ||
| 332 | unsigned int local_intr_mask; | ||
| 333 | }; | ||
| 334 | |||
| 335 | /* GIC nomenclature for Core Interrupt Pins. */ | 197 | /* GIC nomenclature for Core Interrupt Pins. */ |
| 336 | #define GIC_CPU_INT0 0 /* Core Interrupt 2 */ | 198 | #define GIC_CPU_INT0 0 /* Core Interrupt 2 */ |
| 337 | #define GIC_CPU_INT1 1 /* . */ | 199 | #define GIC_CPU_INT1 1 /* . */ |
| @@ -340,45 +202,48 @@ struct gic_shared_intr_map { | |||
| 340 | #define GIC_CPU_INT4 4 /* . */ | 202 | #define GIC_CPU_INT4 4 /* . */ |
| 341 | #define GIC_CPU_INT5 5 /* Core Interrupt 7 */ | 203 | #define GIC_CPU_INT5 5 /* Core Interrupt 7 */ |
| 342 | 204 | ||
| 343 | /* Local GIC interrupts. */ | 205 | /* Add 2 to convert GIC CPU pin to core interrupt */ |
| 344 | #define GIC_INT_TMR (GIC_CPU_INT5) | 206 | #define GIC_CPU_PIN_OFFSET 2 |
| 345 | #define GIC_INT_PERFCTR (GIC_CPU_INT5) | ||
| 346 | 207 | ||
| 347 | /* Add 2 to convert non-EIC hardware interrupt to EIC vector number. */ | 208 | /* Add 2 to convert non-EIC hardware interrupt to EIC vector number. */ |
| 348 | #define GIC_CPU_TO_VEC_OFFSET (2) | 209 | #define GIC_CPU_TO_VEC_OFFSET 2 |
| 349 | 210 | ||
| 350 | /* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */ | 211 | /* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */ |
| 351 | #define GIC_PIN_TO_VEC_OFFSET (1) | 212 | #define GIC_PIN_TO_VEC_OFFSET 1 |
| 352 | 213 | ||
| 353 | #include <linux/clocksource.h> | 214 | /* Local GIC interrupts. */ |
| 354 | #include <linux/irq.h> | 215 | #define GIC_LOCAL_INT_WD 0 /* GIC watchdog */ |
| 216 | #define GIC_LOCAL_INT_COMPARE 1 /* GIC count and compare timer */ | ||
| 217 | #define GIC_LOCAL_INT_TIMER 2 /* CPU timer interrupt */ | ||
| 218 | #define GIC_LOCAL_INT_PERFCTR 3 /* CPU performance counter */ | ||
| 219 | #define GIC_LOCAL_INT_SWINT0 4 /* CPU software interrupt 0 */ | ||
| 220 | #define GIC_LOCAL_INT_SWINT1 5 /* CPU software interrupt 1 */ | ||
| 221 | #define GIC_LOCAL_INT_FDC 6 /* CPU fast debug channel */ | ||
| 222 | #define GIC_NUM_LOCAL_INTRS 7 | ||
| 223 | |||
| 224 | /* Convert between local/shared IRQ number and GIC HW IRQ number. */ | ||
| 225 | #define GIC_LOCAL_HWIRQ_BASE 0 | ||
| 226 | #define GIC_LOCAL_TO_HWIRQ(x) (GIC_LOCAL_HWIRQ_BASE + (x)) | ||
| 227 | #define GIC_HWIRQ_TO_LOCAL(x) ((x) - GIC_LOCAL_HWIRQ_BASE) | ||
| 228 | #define GIC_SHARED_HWIRQ_BASE GIC_NUM_LOCAL_INTRS | ||
| 229 | #define GIC_SHARED_TO_HWIRQ(x) (GIC_SHARED_HWIRQ_BASE + (x)) | ||
| 230 | #define GIC_HWIRQ_TO_SHARED(x) ((x) - GIC_SHARED_HWIRQ_BASE) | ||
| 355 | 231 | ||
| 356 | extern unsigned int gic_present; | 232 | extern unsigned int gic_present; |
| 357 | extern unsigned int gic_frequency; | ||
| 358 | extern unsigned long _gic_base; | ||
| 359 | extern unsigned int gic_irq_base; | ||
| 360 | extern unsigned int gic_irq_flags[]; | ||
| 361 | extern struct gic_shared_intr_map gic_shared_intr_map[]; | ||
| 362 | 233 | ||
| 363 | extern void gic_init(unsigned long gic_base_addr, | 234 | extern void gic_init(unsigned long gic_base_addr, |
| 364 | unsigned long gic_addrspace_size, struct gic_intr_map *intrmap, | 235 | unsigned long gic_addrspace_size, unsigned int cpu_vec, |
| 365 | unsigned int intrmap_size, unsigned int irqbase); | 236 | unsigned int irqbase); |
| 366 | extern void gic_clocksource_init(unsigned int); | 237 | extern void gic_clocksource_init(unsigned int); |
| 367 | extern unsigned int gic_compare_int (void); | ||
| 368 | extern cycle_t gic_read_count(void); | 238 | extern cycle_t gic_read_count(void); |
| 239 | extern unsigned int gic_get_count_width(void); | ||
| 369 | extern cycle_t gic_read_compare(void); | 240 | extern cycle_t gic_read_compare(void); |
| 370 | extern void gic_write_compare(cycle_t cnt); | 241 | extern void gic_write_compare(cycle_t cnt); |
| 371 | extern void gic_write_cpu_compare(cycle_t cnt, int cpu); | 242 | extern void gic_write_cpu_compare(cycle_t cnt, int cpu); |
| 372 | extern void gic_send_ipi(unsigned int intr); | 243 | extern void gic_send_ipi(unsigned int intr); |
| 373 | extern unsigned int plat_ipi_call_int_xlate(unsigned int); | 244 | extern unsigned int plat_ipi_call_int_xlate(unsigned int); |
| 374 | extern unsigned int plat_ipi_resched_int_xlate(unsigned int); | 245 | extern unsigned int plat_ipi_resched_int_xlate(unsigned int); |
| 375 | extern void gic_bind_eic_interrupt(int irq, int set); | ||
| 376 | extern unsigned int gic_get_timer_pending(void); | 246 | extern unsigned int gic_get_timer_pending(void); |
| 377 | extern void gic_get_int_mask(unsigned long *dst, const unsigned long *src); | 247 | extern int gic_get_c0_compare_int(void); |
| 378 | extern unsigned int gic_get_int(void); | 248 | extern int gic_get_c0_perfcount_int(void); |
| 379 | extern void gic_enable_interrupt(int irq_vec); | 249 | #endif /* __LINUX_IRQCHIP_MIPS_GIC_H */ |
| 380 | extern void gic_disable_interrupt(int irq_vec); | ||
| 381 | extern void gic_irq_ack(struct irq_data *d); | ||
| 382 | extern void gic_finish_irq(struct irq_data *d); | ||
| 383 | extern void gic_platform_init(int irqs, struct irq_chip *irq_controller); | ||
| 384 | #endif /* _ASM_GICREGS_H */ | ||
