diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-05 14:28:25 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-05 14:28:25 -0500 |
| commit | d9862cfbe2099deb83f0e9c1932c91f2d9c50464 (patch) | |
| tree | 7092ef41113269f30b5429868a9d161e171c746d | |
| parent | 8feed3efa8022107bcb3432ac3ec9917e078ae70 (diff) | |
| parent | aeb669d41ffabb91b1542f1f802cb12a989fced0 (diff) | |
Merge tag 'mips_5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux
Pull MIPS updates from Paul Burton:
- Support for the MIPSr6 MemoryMapID register & Global INValidate TLB
(GINVT) instructions, allowing for more efficient TLB maintenance
when running on a CPU such as the I6500 that supports these.
- Enable huge page support for MIPS64r6.
- Optimize post-DMA cache sync by removing that code entirely for
kernel configurations in which we know it won't be needed.
- The number of pages allocated for interrupt stacks is now calculated
correctly, where before we would wastefully allocate too much memory
in some configurations.
- The ath79 platform migrates to devicetree.
- The bcm47xx platform sees fixes for the Buffalo WHR-G54S board.
- The ingenic/jz4740 platform gains support for appended devicetrees.
- The cavium_octeon, lantiq, loongson32 & sgi-ip27 platforms all see
cleanups as do various pieces of core architecture code.
* tag 'mips_5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux: (66 commits)
MIPS: lantiq: Remove separate GPHY Firmware loader
MIPS: ingenic: Add support for appended devicetree
MIPS: SGI-IP27: rework HUB interrupts
MIPS: SGI-IP27: do boot CPU init later
MIPS: SGI-IP27: do xtalk scanning later
MIPS: SGI-IP27: use pr_info/pr_emerg and pr_cont to fix output
MIPS: SGI-IP27: clean up bridge access and header files
MIPS: SGI-IP27: get rid of volatile and hubreg_t
MIPS: irq: Allocate accurate order pages for irq stack
MIPS: dma-noncoherent: Remove bogus condition in dma_sync_phys()
MIPS: eBPF: Remove REG_32BIT_ZERO_EX
MIPS: eBPF: Always return sign extended 32b values
MIPS: CM: Fix indentation
MIPS: BCM47XX: Fix/improve Buffalo WHR-G54S support
MIPS: OCTEON: program rx/tx-delay always from DT
MIPS: OCTEON: delete board-specific link status
MIPS: OCTEON: don't lie about interface type of CN3005 board
MIPS: OCTEON: warn if deprecated link status is being used
MIPS: OCTEON: add fixed-link nodes to in-kernel device tree
MIPS: Delete unused flush_cache_sigtramp()
...
119 files changed, 1610 insertions, 4615 deletions
diff --git a/Documentation/devicetree/bindings/mips/lantiq/rcu-gphy.txt b/Documentation/devicetree/bindings/mips/lantiq/rcu-gphy.txt deleted file mode 100644 index a0c19bd1ce66..000000000000 --- a/Documentation/devicetree/bindings/mips/lantiq/rcu-gphy.txt +++ /dev/null | |||
| @@ -1,36 +0,0 @@ | |||
| 1 | Lantiq XWAY SoC GPHY binding | ||
| 2 | ============================ | ||
| 3 | |||
| 4 | This binding describes a software-defined ethernet PHY, provided by the RCU | ||
| 5 | module on newer Lantiq XWAY SoCs (xRX200 and newer). | ||
| 6 | |||
| 7 | ------------------------------------------------------------------------------- | ||
| 8 | Required properties: | ||
| 9 | - compatible : Should be one of | ||
| 10 | "lantiq,xrx200a1x-gphy" | ||
| 11 | "lantiq,xrx200a2x-gphy" | ||
| 12 | "lantiq,xrx300-gphy" | ||
| 13 | "lantiq,xrx330-gphy" | ||
| 14 | - reg : Addrress of the GPHY FW load address register | ||
| 15 | - resets : Must reference the RCU GPHY reset bit | ||
| 16 | - reset-names : One entry, value must be "gphy" or optional "gphy2" | ||
| 17 | - clocks : A reference to the (PMU) GPHY clock gate | ||
| 18 | |||
| 19 | Optional properties: | ||
| 20 | - lantiq,gphy-mode : GPHY_MODE_GE (default) or GPHY_MODE_FE as defined in | ||
| 21 | <dt-bindings/mips/lantiq_xway_gphy.h> | ||
| 22 | |||
| 23 | |||
| 24 | ------------------------------------------------------------------------------- | ||
| 25 | Example for the GPHys on the xRX200 SoCs: | ||
| 26 | |||
| 27 | #include <dt-bindings/mips/lantiq_rcu_gphy.h> | ||
| 28 | gphy0: gphy@20 { | ||
| 29 | compatible = "lantiq,xrx200a2x-gphy"; | ||
| 30 | reg = <0x20 0x4>; | ||
| 31 | |||
| 32 | resets = <&reset0 31 30>, <&reset1 7 7>; | ||
| 33 | reset-names = "gphy", "gphy2"; | ||
| 34 | clocks = <&pmu0 XRX200_PMU_GATE_GPHY>; | ||
| 35 | lantiq,gphy-mode = <GPHY_MODE_GE>; | ||
| 36 | }; | ||
diff --git a/Documentation/devicetree/bindings/mips/lantiq/rcu.txt b/Documentation/devicetree/bindings/mips/lantiq/rcu.txt index 7f0822b4beae..58d51f480c9e 100644 --- a/Documentation/devicetree/bindings/mips/lantiq/rcu.txt +++ b/Documentation/devicetree/bindings/mips/lantiq/rcu.txt | |||
| @@ -26,24 +26,6 @@ Example of the RCU bindings on a xRX200 SoC: | |||
| 26 | ranges = <0x0 0x203000 0x100>; | 26 | ranges = <0x0 0x203000 0x100>; |
| 27 | big-endian; | 27 | big-endian; |
| 28 | 28 | ||
| 29 | gphy0: gphy@20 { | ||
| 30 | compatible = "lantiq,xrx200a2x-gphy"; | ||
| 31 | reg = <0x20 0x4>; | ||
| 32 | |||
| 33 | resets = <&reset0 31 30>, <&reset1 7 7>; | ||
| 34 | reset-names = "gphy", "gphy2"; | ||
| 35 | lantiq,gphy-mode = <GPHY_MODE_GE>; | ||
| 36 | }; | ||
| 37 | |||
| 38 | gphy1: gphy@68 { | ||
| 39 | compatible = "lantiq,xrx200a2x-gphy"; | ||
| 40 | reg = <0x68 0x4>; | ||
| 41 | |||
| 42 | resets = <&reset0 29 28>, <&reset1 6 6>; | ||
| 43 | reset-names = "gphy", "gphy2"; | ||
| 44 | lantiq,gphy-mode = <GPHY_MODE_GE>; | ||
| 45 | }; | ||
| 46 | |||
| 47 | reset0: reset-controller@10 { | 29 | reset0: reset-controller@10 { |
| 48 | compatible = "lantiq,xrx200-reset"; | 30 | compatible = "lantiq,xrx200-reset"; |
| 49 | reg = <0x10 4>, <0x14 4>; | 31 | reg = <0x10 4>, <0x14 4>; |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index a84c24d894aa..9036ef9ec74a 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
| @@ -206,7 +206,6 @@ config ATH79 | |||
| 206 | select COMMON_CLK | 206 | select COMMON_CLK |
| 207 | select CLKDEV_LOOKUP | 207 | select CLKDEV_LOOKUP |
| 208 | select IRQ_MIPS_CPU | 208 | select IRQ_MIPS_CPU |
| 209 | select MIPS_MACHINE | ||
| 210 | select SYS_HAS_CPU_MIPS32_R2 | 209 | select SYS_HAS_CPU_MIPS32_R2 |
| 211 | select SYS_HAS_EARLY_PRINTK | 210 | select SYS_HAS_EARLY_PRINTK |
| 212 | select SYS_SUPPORTS_32BIT_KERNEL | 211 | select SYS_SUPPORTS_32BIT_KERNEL |
| @@ -391,7 +390,7 @@ config MACH_INGENIC | |||
| 391 | select GPIOLIB | 390 | select GPIOLIB |
| 392 | select COMMON_CLK | 391 | select COMMON_CLK |
| 393 | select GENERIC_IRQ_CHIP | 392 | select GENERIC_IRQ_CHIP |
| 394 | select BUILTIN_DTB | 393 | select BUILTIN_DTB if MIPS_NO_APPENDED_DTB |
| 395 | select USE_OF | 394 | select USE_OF |
| 396 | select LIBFDT | 395 | select LIBFDT |
| 397 | 396 | ||
| @@ -676,6 +675,7 @@ config SGI_IP27 | |||
| 676 | select DEFAULT_SGI_PARTITION | 675 | select DEFAULT_SGI_PARTITION |
| 677 | select SYS_HAS_EARLY_PRINTK | 676 | select SYS_HAS_EARLY_PRINTK |
| 678 | select HAVE_PCI | 677 | select HAVE_PCI |
| 678 | select IRQ_MIPS_CPU | ||
| 679 | select NR_CPUS_DEFAULT_64 | 679 | select NR_CPUS_DEFAULT_64 |
| 680 | select SYS_HAS_CPU_R10000 | 680 | select SYS_HAS_CPU_R10000 |
| 681 | select SYS_SUPPORTS_64BIT_KERNEL | 681 | select SYS_SUPPORTS_64BIT_KERNEL |
| @@ -1124,7 +1124,6 @@ config DMA_NONCOHERENT | |||
| 1124 | bool | 1124 | bool |
| 1125 | select ARCH_HAS_DMA_MMAP_PGPROT | 1125 | select ARCH_HAS_DMA_MMAP_PGPROT |
| 1126 | select ARCH_HAS_SYNC_DMA_FOR_DEVICE | 1126 | select ARCH_HAS_SYNC_DMA_FOR_DEVICE |
| 1127 | select ARCH_HAS_SYNC_DMA_FOR_CPU | ||
| 1128 | select NEED_DMA_MAP_STATE | 1127 | select NEED_DMA_MAP_STATE |
| 1129 | select ARCH_HAS_DMA_COHERENT_TO_PFN | 1128 | select ARCH_HAS_DMA_COHERENT_TO_PFN |
| 1130 | select DMA_NONCOHERENT_CACHE_SYNC | 1129 | select DMA_NONCOHERENT_CACHE_SYNC |
| @@ -1556,6 +1555,7 @@ config CPU_MIPS64_R6 | |||
| 1556 | select CPU_SUPPORTS_32BIT_KERNEL | 1555 | select CPU_SUPPORTS_32BIT_KERNEL |
| 1557 | select CPU_SUPPORTS_64BIT_KERNEL | 1556 | select CPU_SUPPORTS_64BIT_KERNEL |
| 1558 | select CPU_SUPPORTS_HIGHMEM | 1557 | select CPU_SUPPORTS_HIGHMEM |
| 1558 | select CPU_SUPPORTS_HUGEPAGES | ||
| 1559 | select CPU_SUPPORTS_MSA | 1559 | select CPU_SUPPORTS_MSA |
| 1560 | select MIPS_O32_FP64_SUPPORT if 32BIT || MIPS32_O32 | 1560 | select MIPS_O32_FP64_SUPPORT if 32BIT || MIPS32_O32 |
| 1561 | select HAVE_KVM | 1561 | select HAVE_KVM |
| @@ -1881,7 +1881,7 @@ config CPU_LOONGSON2 | |||
| 1881 | config CPU_LOONGSON1 | 1881 | config CPU_LOONGSON1 |
| 1882 | bool | 1882 | bool |
| 1883 | select CPU_MIPS32 | 1883 | select CPU_MIPS32 |
| 1884 | select CPU_MIPSR1 | 1884 | select CPU_MIPSR2 |
| 1885 | select CPU_HAS_PREFETCH | 1885 | select CPU_HAS_PREFETCH |
| 1886 | select CPU_HAS_LOAD_STORE_LR | 1886 | select CPU_HAS_LOAD_STORE_LR |
| 1887 | select CPU_SUPPORTS_32BIT_KERNEL | 1887 | select CPU_SUPPORTS_32BIT_KERNEL |
| @@ -1943,9 +1943,11 @@ config SYS_HAS_CPU_MIPS32_R3_5 | |||
| 1943 | 1943 | ||
| 1944 | config SYS_HAS_CPU_MIPS32_R5 | 1944 | config SYS_HAS_CPU_MIPS32_R5 |
| 1945 | bool | 1945 | bool |
| 1946 | select ARCH_HAS_SYNC_DMA_FOR_CPU if DMA_NONCOHERENT | ||
| 1946 | 1947 | ||
| 1947 | config SYS_HAS_CPU_MIPS32_R6 | 1948 | config SYS_HAS_CPU_MIPS32_R6 |
| 1948 | bool | 1949 | bool |
| 1950 | select ARCH_HAS_SYNC_DMA_FOR_CPU if DMA_NONCOHERENT | ||
| 1949 | 1951 | ||
| 1950 | config SYS_HAS_CPU_MIPS64_R1 | 1952 | config SYS_HAS_CPU_MIPS64_R1 |
| 1951 | bool | 1953 | bool |
| @@ -1955,6 +1957,7 @@ config SYS_HAS_CPU_MIPS64_R2 | |||
| 1955 | 1957 | ||
| 1956 | config SYS_HAS_CPU_MIPS64_R6 | 1958 | config SYS_HAS_CPU_MIPS64_R6 |
| 1957 | bool | 1959 | bool |
| 1960 | select ARCH_HAS_SYNC_DMA_FOR_CPU if DMA_NONCOHERENT | ||
| 1958 | 1961 | ||
| 1959 | config SYS_HAS_CPU_R3000 | 1962 | config SYS_HAS_CPU_R3000 |
| 1960 | bool | 1963 | bool |
| @@ -1991,6 +1994,7 @@ config SYS_HAS_CPU_R8000 | |||
| 1991 | 1994 | ||
| 1992 | config SYS_HAS_CPU_R10000 | 1995 | config SYS_HAS_CPU_R10000 |
| 1993 | bool | 1996 | bool |
| 1997 | select ARCH_HAS_SYNC_DMA_FOR_CPU if DMA_NONCOHERENT | ||
| 1994 | 1998 | ||
| 1995 | config SYS_HAS_CPU_RM7000 | 1999 | config SYS_HAS_CPU_RM7000 |
| 1996 | bool | 2000 | bool |
| @@ -2019,6 +2023,7 @@ config SYS_HAS_CPU_BMIPS4380 | |||
| 2019 | config SYS_HAS_CPU_BMIPS5000 | 2023 | config SYS_HAS_CPU_BMIPS5000 |
| 2020 | bool | 2024 | bool |
| 2021 | select SYS_HAS_CPU_BMIPS | 2025 | select SYS_HAS_CPU_BMIPS |
| 2026 | select ARCH_HAS_SYNC_DMA_FOR_CPU | ||
| 2022 | 2027 | ||
| 2023 | config SYS_HAS_CPU_XLR | 2028 | config SYS_HAS_CPU_XLR |
| 2024 | bool | 2029 | bool |
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 5b174c3d0de3..8f4486c4415b 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
| @@ -233,6 +233,8 @@ toolchain-crc := $(call cc-option-yn,$(mips-cflags) -Wa$(comma)-mcrc) | |||
| 233 | cflags-$(toolchain-crc) += -DTOOLCHAIN_SUPPORTS_CRC | 233 | cflags-$(toolchain-crc) += -DTOOLCHAIN_SUPPORTS_CRC |
| 234 | toolchain-dsp := $(call cc-option-yn,$(mips-cflags) -Wa$(comma)-mdsp) | 234 | toolchain-dsp := $(call cc-option-yn,$(mips-cflags) -Wa$(comma)-mdsp) |
| 235 | cflags-$(toolchain-dsp) += -DTOOLCHAIN_SUPPORTS_DSP | 235 | cflags-$(toolchain-dsp) += -DTOOLCHAIN_SUPPORTS_DSP |
| 236 | toolchain-ginv := $(call cc-option-yn,$(mips-cflags) -Wa$(comma)-mginv) | ||
| 237 | cflags-$(toolchain-ginv) += -DTOOLCHAIN_SUPPORTS_GINV | ||
| 236 | 238 | ||
| 237 | # | 239 | # |
| 238 | # Firmware support | 240 | # Firmware support |
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig index 191c3910eac5..7367416642cb 100644 --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig | |||
| @@ -1,79 +1,6 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | if ATH79 | 2 | if ATH79 |
| 3 | 3 | ||
| 4 | menu "Atheros AR71XX/AR724X/AR913X machine selection" | ||
| 5 | |||
| 6 | config ATH79_MACH_AP121 | ||
| 7 | bool "Atheros AP121 reference board" | ||
| 8 | select SOC_AR933X | ||
| 9 | select ATH79_DEV_GPIO_BUTTONS | ||
| 10 | select ATH79_DEV_LEDS_GPIO | ||
| 11 | select ATH79_DEV_SPI | ||
| 12 | select ATH79_DEV_USB | ||
| 13 | select ATH79_DEV_WMAC | ||
| 14 | help | ||
| 15 | Say 'Y' here if you want your kernel to support the | ||
| 16 | Atheros AP121 reference board. | ||
| 17 | |||
| 18 | config ATH79_MACH_AP136 | ||
| 19 | bool "Atheros AP136 reference board" | ||
| 20 | select SOC_QCA955X | ||
| 21 | select ATH79_DEV_GPIO_BUTTONS | ||
| 22 | select ATH79_DEV_LEDS_GPIO | ||
| 23 | select ATH79_DEV_SPI | ||
| 24 | select ATH79_DEV_USB | ||
| 25 | select ATH79_DEV_WMAC | ||
| 26 | help | ||
| 27 | Say 'Y' here if you want your kernel to support the | ||
| 28 | Atheros AP136 reference board. | ||
| 29 | |||
| 30 | config ATH79_MACH_AP81 | ||
| 31 | bool "Atheros AP81 reference board" | ||
| 32 | select SOC_AR913X | ||
| 33 | select ATH79_DEV_GPIO_BUTTONS | ||
| 34 | select ATH79_DEV_LEDS_GPIO | ||
| 35 | select ATH79_DEV_SPI | ||
| 36 | select ATH79_DEV_USB | ||
| 37 | select ATH79_DEV_WMAC | ||
| 38 | help | ||
| 39 | Say 'Y' here if you want your kernel to support the | ||
| 40 | Atheros AP81 reference board. | ||
| 41 | |||
| 42 | config ATH79_MACH_DB120 | ||
| 43 | bool "Atheros DB120 reference board" | ||
| 44 | select SOC_AR934X | ||
| 45 | select ATH79_DEV_GPIO_BUTTONS | ||
| 46 | select ATH79_DEV_LEDS_GPIO | ||
| 47 | select ATH79_DEV_SPI | ||
| 48 | select ATH79_DEV_USB | ||
| 49 | select ATH79_DEV_WMAC | ||
| 50 | help | ||
| 51 | Say 'Y' here if you want your kernel to support the | ||
| 52 | Atheros DB120 reference board. | ||
| 53 | |||
| 54 | config ATH79_MACH_PB44 | ||
| 55 | bool "Atheros PB44 reference board" | ||
| 56 | select SOC_AR71XX | ||
| 57 | select ATH79_DEV_GPIO_BUTTONS | ||
| 58 | select ATH79_DEV_LEDS_GPIO | ||
| 59 | select ATH79_DEV_SPI | ||
| 60 | select ATH79_DEV_USB | ||
| 61 | help | ||
| 62 | Say 'Y' here if you want your kernel to support the | ||
| 63 | Atheros PB44 reference board. | ||
| 64 | |||
| 65 | config ATH79_MACH_UBNT_XM | ||
| 66 | bool "Ubiquiti Networks XM (rev 1.0) board" | ||
| 67 | select SOC_AR724X | ||
| 68 | select ATH79_DEV_GPIO_BUTTONS | ||
| 69 | select ATH79_DEV_LEDS_GPIO | ||
| 70 | select ATH79_DEV_SPI | ||
| 71 | help | ||
| 72 | Say 'Y' here if you want your kernel to support the | ||
| 73 | Ubiquiti Networks XM (rev 1.0) board. | ||
| 74 | |||
| 75 | endmenu | ||
| 76 | |||
| 77 | config SOC_AR71XX | 4 | config SOC_AR71XX |
| 78 | select HAVE_PCI | 5 | select HAVE_PCI |
| 79 | def_bool n | 6 | def_bool n |
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile index fcc382cfc770..e18d9a2ecf62 100644 --- a/arch/mips/ath79/Makefile +++ b/arch/mips/ath79/Makefile | |||
| @@ -8,27 +8,6 @@ | |||
| 8 | # under the terms of the GNU General Public License version 2 as published | 8 | # under the terms of the GNU General Public License version 2 as published |
| 9 | # by the Free Software Foundation. | 9 | # by the Free Software Foundation. |
| 10 | 10 | ||
| 11 | obj-y := prom.o setup.o irq.o common.o clock.o | 11 | obj-y := prom.o setup.o common.o clock.o |
| 12 | 12 | ||
| 13 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 13 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
| 14 | obj-$(CONFIG_PCI) += pci.o | ||
| 15 | |||
| 16 | # | ||
| 17 | # Devices | ||
| 18 | # | ||
| 19 | obj-y += dev-common.o | ||
| 20 | obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS) += dev-gpio-buttons.o | ||
| 21 | obj-$(CONFIG_ATH79_DEV_LEDS_GPIO) += dev-leds-gpio.o | ||
| 22 | obj-$(CONFIG_ATH79_DEV_SPI) += dev-spi.o | ||
| 23 | obj-$(CONFIG_ATH79_DEV_USB) += dev-usb.o | ||
| 24 | obj-$(CONFIG_ATH79_DEV_WMAC) += dev-wmac.o | ||
| 25 | |||
| 26 | # | ||
| 27 | # Machines | ||
| 28 | # | ||
| 29 | obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o | ||
| 30 | obj-$(CONFIG_ATH79_MACH_AP136) += mach-ap136.o | ||
| 31 | obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o | ||
| 32 | obj-$(CONFIG_ATH79_MACH_DB120) += mach-db120.o | ||
| 33 | obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o | ||
| 34 | obj-$(CONFIG_ATH79_MACH_UBNT_XM) += mach-ubnt-xm.o | ||
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c index cf9158e3c2d9..d4ca97e2ec6c 100644 --- a/arch/mips/ath79/clock.c +++ b/arch/mips/ath79/clock.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | #include <asm/mach-ath79/ath79.h> | 26 | #include <asm/mach-ath79/ath79.h> |
| 27 | #include <asm/mach-ath79/ar71xx_regs.h> | 27 | #include <asm/mach-ath79/ar71xx_regs.h> |
| 28 | #include "common.h" | 28 | #include "common.h" |
| 29 | #include "machtypes.h" | ||
| 30 | 29 | ||
| 31 | #define AR71XX_BASE_FREQ 40000000 | 30 | #define AR71XX_BASE_FREQ 40000000 |
| 32 | #define AR724X_BASE_FREQ 40000000 | 31 | #define AR724X_BASE_FREQ 40000000 |
| @@ -37,24 +36,63 @@ static struct clk_onecell_data clk_data = { | |||
| 37 | .clk_num = ARRAY_SIZE(clks), | 36 | .clk_num = ARRAY_SIZE(clks), |
| 38 | }; | 37 | }; |
| 39 | 38 | ||
| 40 | static struct clk *__init ath79_add_sys_clkdev( | 39 | static const char * const clk_names[ATH79_CLK_END] = { |
| 41 | const char *id, unsigned long rate) | 40 | [ATH79_CLK_CPU] = "cpu", |
| 41 | [ATH79_CLK_DDR] = "ddr", | ||
| 42 | [ATH79_CLK_AHB] = "ahb", | ||
| 43 | [ATH79_CLK_REF] = "ref", | ||
| 44 | [ATH79_CLK_MDIO] = "mdio", | ||
| 45 | }; | ||
| 46 | |||
| 47 | static const char * __init ath79_clk_name(int type) | ||
| 42 | { | 48 | { |
| 43 | struct clk *clk; | 49 | BUG_ON(type >= ARRAY_SIZE(clk_names) || !clk_names[type]); |
| 44 | int err; | 50 | return clk_names[type]; |
| 51 | } | ||
| 45 | 52 | ||
| 46 | clk = clk_register_fixed_rate(NULL, id, NULL, 0, rate); | 53 | static void __init __ath79_set_clk(int type, const char *name, struct clk *clk) |
| 54 | { | ||
| 47 | if (IS_ERR(clk)) | 55 | if (IS_ERR(clk)) |
| 48 | panic("failed to allocate %s clock structure", id); | 56 | panic("failed to allocate %s clock structure", clk_names[type]); |
| 49 | 57 | ||
| 50 | err = clk_register_clkdev(clk, id, NULL); | 58 | clks[type] = clk; |
| 51 | if (err) | 59 | clk_register_clkdev(clk, name, NULL); |
| 52 | panic("unable to register %s clock device", id); | 60 | } |
| 53 | 61 | ||
| 62 | static struct clk * __init ath79_set_clk(int type, unsigned long rate) | ||
| 63 | { | ||
| 64 | const char *name = ath79_clk_name(type); | ||
| 65 | struct clk *clk; | ||
| 66 | |||
| 67 | clk = clk_register_fixed_rate(NULL, name, NULL, 0, rate); | ||
| 68 | __ath79_set_clk(type, name, clk); | ||
| 54 | return clk; | 69 | return clk; |
| 55 | } | 70 | } |
| 56 | 71 | ||
| 57 | static void __init ar71xx_clocks_init(void) | 72 | static struct clk * __init ath79_set_ff_clk(int type, const char *parent, |
| 73 | unsigned int mult, unsigned int div) | ||
| 74 | { | ||
| 75 | const char *name = ath79_clk_name(type); | ||
| 76 | struct clk *clk; | ||
| 77 | |||
| 78 | clk = clk_register_fixed_factor(NULL, name, parent, 0, mult, div); | ||
| 79 | __ath79_set_clk(type, name, clk); | ||
| 80 | return clk; | ||
| 81 | } | ||
| 82 | |||
| 83 | static unsigned long __init ath79_setup_ref_clk(unsigned long rate) | ||
| 84 | { | ||
| 85 | struct clk *clk = clks[ATH79_CLK_REF]; | ||
| 86 | |||
| 87 | if (clk) | ||
| 88 | rate = clk_get_rate(clk); | ||
| 89 | else | ||
| 90 | clk = ath79_set_clk(ATH79_CLK_REF, rate); | ||
| 91 | |||
| 92 | return rate; | ||
| 93 | } | ||
| 94 | |||
| 95 | static void __init ar71xx_clocks_init(void __iomem *pll_base) | ||
| 58 | { | 96 | { |
| 59 | unsigned long ref_rate; | 97 | unsigned long ref_rate; |
| 60 | unsigned long cpu_rate; | 98 | unsigned long cpu_rate; |
| @@ -64,9 +102,9 @@ static void __init ar71xx_clocks_init(void) | |||
| 64 | u32 freq; | 102 | u32 freq; |
| 65 | u32 div; | 103 | u32 div; |
| 66 | 104 | ||
| 67 | ref_rate = AR71XX_BASE_FREQ; | 105 | ref_rate = ath79_setup_ref_clk(AR71XX_BASE_FREQ); |
| 68 | 106 | ||
| 69 | pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG); | 107 | pll = __raw_readl(pll_base + AR71XX_PLL_REG_CPU_CONFIG); |
| 70 | 108 | ||
| 71 | div = ((pll >> AR71XX_PLL_FB_SHIFT) & AR71XX_PLL_FB_MASK) + 1; | 109 | div = ((pll >> AR71XX_PLL_FB_SHIFT) & AR71XX_PLL_FB_MASK) + 1; |
| 72 | freq = div * ref_rate; | 110 | freq = div * ref_rate; |
| @@ -80,31 +118,17 @@ static void __init ar71xx_clocks_init(void) | |||
| 80 | div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2; | 118 | div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2; |
| 81 | ahb_rate = cpu_rate / div; | 119 | ahb_rate = cpu_rate / div; |
| 82 | 120 | ||
| 83 | ath79_add_sys_clkdev("ref", ref_rate); | 121 | ath79_set_clk(ATH79_CLK_CPU, cpu_rate); |
| 84 | clks[ATH79_CLK_CPU] = ath79_add_sys_clkdev("cpu", cpu_rate); | 122 | ath79_set_clk(ATH79_CLK_DDR, ddr_rate); |
| 85 | clks[ATH79_CLK_DDR] = ath79_add_sys_clkdev("ddr", ddr_rate); | 123 | ath79_set_clk(ATH79_CLK_AHB, ahb_rate); |
| 86 | clks[ATH79_CLK_AHB] = ath79_add_sys_clkdev("ahb", ahb_rate); | ||
| 87 | |||
| 88 | clk_add_alias("wdt", NULL, "ahb", NULL); | ||
| 89 | clk_add_alias("uart", NULL, "ahb", NULL); | ||
| 90 | } | 124 | } |
| 91 | 125 | ||
| 92 | static struct clk * __init ath79_reg_ffclk(const char *name, | 126 | static void __init ar724x_clocks_init(void __iomem *pll_base) |
| 93 | const char *parent_name, unsigned int mult, unsigned int div) | ||
| 94 | { | 127 | { |
| 95 | struct clk *clk; | ||
| 96 | |||
| 97 | clk = clk_register_fixed_factor(NULL, name, parent_name, 0, mult, div); | ||
| 98 | if (IS_ERR(clk)) | ||
| 99 | panic("failed to allocate %s clock structure", name); | ||
| 100 | |||
| 101 | return clk; | ||
| 102 | } | ||
| 103 | |||
| 104 | static void __init ar724x_clk_init(struct clk *ref_clk, void __iomem *pll_base) | ||
| 105 | { | ||
| 106 | u32 pll; | ||
| 107 | u32 mult, div, ddr_div, ahb_div; | 128 | u32 mult, div, ddr_div, ahb_div; |
| 129 | u32 pll; | ||
| 130 | |||
| 131 | ath79_setup_ref_clk(AR71XX_BASE_FREQ); | ||
| 108 | 132 | ||
| 109 | pll = __raw_readl(pll_base + AR724X_PLL_REG_CPU_CONFIG); | 133 | pll = __raw_readl(pll_base + AR724X_PLL_REG_CPU_CONFIG); |
| 110 | 134 | ||
| @@ -114,30 +138,14 @@ static void __init ar724x_clk_init(struct clk *ref_clk, void __iomem *pll_base) | |||
| 114 | ddr_div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; | 138 | ddr_div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; |
| 115 | ahb_div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; | 139 | ahb_div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; |
| 116 | 140 | ||
| 117 | clks[ATH79_CLK_CPU] = ath79_reg_ffclk("cpu", "ref", mult, div); | 141 | ath79_set_ff_clk(ATH79_CLK_CPU, "ref", mult, div); |
| 118 | clks[ATH79_CLK_DDR] = ath79_reg_ffclk("ddr", "ref", mult, div * ddr_div); | 142 | ath79_set_ff_clk(ATH79_CLK_DDR, "ref", mult, div * ddr_div); |
| 119 | clks[ATH79_CLK_AHB] = ath79_reg_ffclk("ahb", "ref", mult, div * ahb_div); | 143 | ath79_set_ff_clk(ATH79_CLK_AHB, "ref", mult, div * ahb_div); |
| 120 | } | ||
| 121 | |||
| 122 | static void __init ar724x_clocks_init(void) | ||
| 123 | { | ||
| 124 | struct clk *ref_clk; | ||
| 125 | |||
| 126 | ref_clk = ath79_add_sys_clkdev("ref", AR724X_BASE_FREQ); | ||
| 127 | |||
| 128 | ar724x_clk_init(ref_clk, ath79_pll_base); | ||
| 129 | |||
| 130 | /* just make happy plat_time_init() from arch/mips/ath79/setup.c */ | ||
| 131 | clk_register_clkdev(clks[ATH79_CLK_CPU], "cpu", NULL); | ||
| 132 | clk_register_clkdev(clks[ATH79_CLK_DDR], "ddr", NULL); | ||
| 133 | clk_register_clkdev(clks[ATH79_CLK_AHB], "ahb", NULL); | ||
| 134 | |||
| 135 | clk_add_alias("wdt", NULL, "ahb", NULL); | ||
| 136 | clk_add_alias("uart", NULL, "ahb", NULL); | ||
| 137 | } | 144 | } |
| 138 | 145 | ||
| 139 | static void __init ar9330_clk_init(struct clk *ref_clk, void __iomem *pll_base) | 146 | static void __init ar933x_clocks_init(void __iomem *pll_base) |
| 140 | { | 147 | { |
| 148 | unsigned long ref_rate; | ||
| 141 | u32 clock_ctrl; | 149 | u32 clock_ctrl; |
| 142 | u32 ref_div; | 150 | u32 ref_div; |
| 143 | u32 ninit_mul; | 151 | u32 ninit_mul; |
| @@ -146,6 +154,15 @@ static void __init ar9330_clk_init(struct clk *ref_clk, void __iomem *pll_base) | |||
| 146 | u32 cpu_div; | 154 | u32 cpu_div; |
| 147 | u32 ddr_div; | 155 | u32 ddr_div; |
| 148 | u32 ahb_div; | 156 | u32 ahb_div; |
| 157 | u32 t; | ||
| 158 | |||
| 159 | t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); | ||
| 160 | if (t & AR933X_BOOTSTRAP_REF_CLK_40) | ||
| 161 | ref_rate = (40 * 1000 * 1000); | ||
| 162 | else | ||
| 163 | ref_rate = (25 * 1000 * 1000); | ||
| 164 | |||
| 165 | ath79_setup_ref_clk(ref_rate); | ||
| 149 | 166 | ||
| 150 | clock_ctrl = __raw_readl(pll_base + AR933X_PLL_CLOCK_CTRL_REG); | 167 | clock_ctrl = __raw_readl(pll_base + AR933X_PLL_CLOCK_CTRL_REG); |
| 151 | if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { | 168 | if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { |
| @@ -186,37 +203,12 @@ static void __init ar9330_clk_init(struct clk *ref_clk, void __iomem *pll_base) | |||
| 186 | AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1; | 203 | AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1; |
| 187 | } | 204 | } |
| 188 | 205 | ||
| 189 | clks[ATH79_CLK_CPU] = ath79_reg_ffclk("cpu", "ref", | 206 | ath79_set_ff_clk(ATH79_CLK_CPU, "ref", ninit_mul, |
| 190 | ninit_mul, ref_div * out_div * cpu_div); | 207 | ref_div * out_div * cpu_div); |
| 191 | clks[ATH79_CLK_DDR] = ath79_reg_ffclk("ddr", "ref", | 208 | ath79_set_ff_clk(ATH79_CLK_DDR, "ref", ninit_mul, |
| 192 | ninit_mul, ref_div * out_div * ddr_div); | 209 | ref_div * out_div * ddr_div); |
| 193 | clks[ATH79_CLK_AHB] = ath79_reg_ffclk("ahb", "ref", | 210 | ath79_set_ff_clk(ATH79_CLK_AHB, "ref", ninit_mul, |
| 194 | ninit_mul, ref_div * out_div * ahb_div); | 211 | ref_div * out_div * ahb_div); |
| 195 | } | ||
| 196 | |||
| 197 | static void __init ar933x_clocks_init(void) | ||
| 198 | { | ||
| 199 | struct clk *ref_clk; | ||
| 200 | unsigned long ref_rate; | ||
| 201 | u32 t; | ||
| 202 | |||
| 203 | t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); | ||
| 204 | if (t & AR933X_BOOTSTRAP_REF_CLK_40) | ||
| 205 | ref_rate = (40 * 1000 * 1000); | ||
| 206 | else | ||
| 207 | ref_rate = (25 * 1000 * 1000); | ||
| 208 | |||
| 209 | ref_clk = ath79_add_sys_clkdev("ref", ref_rate); | ||
| 210 | |||
| 211 | ar9330_clk_init(ref_clk, ath79_pll_base); | ||
| 212 | |||
| 213 | /* just make happy plat_time_init() from arch/mips/ath79/setup.c */ | ||
| 214 | clk_register_clkdev(clks[ATH79_CLK_CPU], "cpu", NULL); | ||
| 215 | clk_register_clkdev(clks[ATH79_CLK_DDR], "ddr", NULL); | ||
| 216 | clk_register_clkdev(clks[ATH79_CLK_AHB], "ahb", NULL); | ||
| 217 | |||
| 218 | clk_add_alias("wdt", NULL, "ahb", NULL); | ||
| 219 | clk_add_alias("uart", NULL, "ref", NULL); | ||
| 220 | } | 212 | } |
| 221 | 213 | ||
| 222 | static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac, | 214 | static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac, |
| @@ -239,7 +231,7 @@ static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac, | |||
| 239 | return ret; | 231 | return ret; |
| 240 | } | 232 | } |
| 241 | 233 | ||
| 242 | static void __init ar934x_clocks_init(void) | 234 | static void __init ar934x_clocks_init(void __iomem *pll_base) |
| 243 | { | 235 | { |
| 244 | unsigned long ref_rate; | 236 | unsigned long ref_rate; |
| 245 | unsigned long cpu_rate; | 237 | unsigned long cpu_rate; |
| @@ -258,6 +250,8 @@ static void __init ar934x_clocks_init(void) | |||
| 258 | else | 250 | else |
| 259 | ref_rate = 25 * 1000 * 1000; | 251 | ref_rate = 25 * 1000 * 1000; |
| 260 | 252 | ||
| 253 | ref_rate = ath79_setup_ref_clk(ref_rate); | ||
| 254 | |||
| 261 | pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG); | 255 | pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG); |
| 262 | if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { | 256 | if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { |
| 263 | out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & | 257 | out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & |
| @@ -270,7 +264,7 @@ static void __init ar934x_clocks_init(void) | |||
| 270 | AR934X_SRIF_DPLL1_REFDIV_MASK; | 264 | AR934X_SRIF_DPLL1_REFDIV_MASK; |
| 271 | frac = 1 << 18; | 265 | frac = 1 << 18; |
| 272 | } else { | 266 | } else { |
| 273 | pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG); | 267 | pll = __raw_readl(pll_base + AR934X_PLL_CPU_CONFIG_REG); |
| 274 | out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & | 268 | out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & |
| 275 | AR934X_PLL_CPU_CONFIG_OUTDIV_MASK; | 269 | AR934X_PLL_CPU_CONFIG_OUTDIV_MASK; |
| 276 | ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) & | 270 | ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) & |
| @@ -297,7 +291,7 @@ static void __init ar934x_clocks_init(void) | |||
| 297 | AR934X_SRIF_DPLL1_REFDIV_MASK; | 291 | AR934X_SRIF_DPLL1_REFDIV_MASK; |
| 298 | frac = 1 << 18; | 292 | frac = 1 << 18; |
| 299 | } else { | 293 | } else { |
| 300 | pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG); | 294 | pll = __raw_readl(pll_base + AR934X_PLL_DDR_CONFIG_REG); |
| 301 | out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & | 295 | out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & |
| 302 | AR934X_PLL_DDR_CONFIG_OUTDIV_MASK; | 296 | AR934X_PLL_DDR_CONFIG_OUTDIV_MASK; |
| 303 | ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) & | 297 | ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) & |
| @@ -312,7 +306,7 @@ static void __init ar934x_clocks_init(void) | |||
| 312 | ddr_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint, | 306 | ddr_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint, |
| 313 | nfrac, frac, out_div); | 307 | nfrac, frac, out_div); |
| 314 | 308 | ||
| 315 | clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG); | 309 | clk_ctrl = __raw_readl(pll_base + AR934X_PLL_CPU_DDR_CLK_CTRL_REG); |
| 316 | 310 | ||
| 317 | postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) & | 311 | postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) & |
| 318 | AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK; | 312 | AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK; |
| @@ -344,18 +338,18 @@ static void __init ar934x_clocks_init(void) | |||
| 344 | else | 338 | else |
| 345 | ahb_rate = cpu_pll / (postdiv + 1); | 339 | ahb_rate = cpu_pll / (postdiv + 1); |
| 346 | 340 | ||
| 347 | ath79_add_sys_clkdev("ref", ref_rate); | 341 | ath79_set_clk(ATH79_CLK_CPU, cpu_rate); |
| 348 | clks[ATH79_CLK_CPU] = ath79_add_sys_clkdev("cpu", cpu_rate); | 342 | ath79_set_clk(ATH79_CLK_DDR, ddr_rate); |
| 349 | clks[ATH79_CLK_DDR] = ath79_add_sys_clkdev("ddr", ddr_rate); | 343 | ath79_set_clk(ATH79_CLK_AHB, ahb_rate); |
| 350 | clks[ATH79_CLK_AHB] = ath79_add_sys_clkdev("ahb", ahb_rate); | ||
| 351 | 344 | ||
| 352 | clk_add_alias("wdt", NULL, "ref", NULL); | 345 | clk_ctrl = __raw_readl(pll_base + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG); |
| 353 | clk_add_alias("uart", NULL, "ref", NULL); | 346 | if (clk_ctrl & AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL) |
| 347 | ath79_set_clk(ATH79_CLK_MDIO, 100 * 1000 * 1000); | ||
| 354 | 348 | ||
| 355 | iounmap(dpll_base); | 349 | iounmap(dpll_base); |
| 356 | } | 350 | } |
| 357 | 351 | ||
| 358 | static void __init qca953x_clocks_init(void) | 352 | static void __init qca953x_clocks_init(void __iomem *pll_base) |
| 359 | { | 353 | { |
| 360 | unsigned long ref_rate; | 354 | unsigned long ref_rate; |
| 361 | unsigned long cpu_rate; | 355 | unsigned long cpu_rate; |
| @@ -371,7 +365,9 @@ static void __init qca953x_clocks_init(void) | |||
| 371 | else | 365 | else |
| 372 | ref_rate = 25 * 1000 * 1000; | 366 | ref_rate = 25 * 1000 * 1000; |
| 373 | 367 | ||
| 374 | pll = ath79_pll_rr(QCA953X_PLL_CPU_CONFIG_REG); | 368 | ref_rate = ath79_setup_ref_clk(ref_rate); |
| 369 | |||
| 370 | pll = __raw_readl(pll_base + QCA953X_PLL_CPU_CONFIG_REG); | ||
| 375 | out_div = (pll >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & | 371 | out_div = (pll >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & |
| 376 | QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK; | 372 | QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK; |
| 377 | ref_div = (pll >> QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT) & | 373 | ref_div = (pll >> QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT) & |
| @@ -385,7 +381,7 @@ static void __init qca953x_clocks_init(void) | |||
| 385 | cpu_pll += frac * (ref_rate >> 6) / ref_div; | 381 | cpu_pll += frac * (ref_rate >> 6) / ref_div; |
| 386 | cpu_pll /= (1 << out_div); | 382 | cpu_pll /= (1 << out_div); |
| 387 | 383 | ||
| 388 | pll = ath79_pll_rr(QCA953X_PLL_DDR_CONFIG_REG); | 384 | pll = __raw_readl(pll_base + QCA953X_PLL_DDR_CONFIG_REG); |
| 389 | out_div = (pll >> QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & | 385 | out_div = (pll >> QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & |
| 390 | QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK; | 386 | QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK; |
| 391 | ref_div = (pll >> QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT) & | 387 | ref_div = (pll >> QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT) & |
| @@ -399,7 +395,7 @@ static void __init qca953x_clocks_init(void) | |||
| 399 | ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4); | 395 | ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4); |
| 400 | ddr_pll /= (1 << out_div); | 396 | ddr_pll /= (1 << out_div); |
| 401 | 397 | ||
| 402 | clk_ctrl = ath79_pll_rr(QCA953X_PLL_CLK_CTRL_REG); | 398 | clk_ctrl = __raw_readl(pll_base + QCA953X_PLL_CLK_CTRL_REG); |
| 403 | 399 | ||
| 404 | postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & | 400 | postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & |
| 405 | QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; | 401 | QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; |
| @@ -431,16 +427,12 @@ static void __init qca953x_clocks_init(void) | |||
| 431 | else | 427 | else |
| 432 | ahb_rate = cpu_pll / (postdiv + 1); | 428 | ahb_rate = cpu_pll / (postdiv + 1); |
| 433 | 429 | ||
| 434 | ath79_add_sys_clkdev("ref", ref_rate); | 430 | ath79_set_clk(ATH79_CLK_CPU, cpu_rate); |
| 435 | ath79_add_sys_clkdev("cpu", cpu_rate); | 431 | ath79_set_clk(ATH79_CLK_DDR, ddr_rate); |
| 436 | ath79_add_sys_clkdev("ddr", ddr_rate); | 432 | ath79_set_clk(ATH79_CLK_AHB, ahb_rate); |
| 437 | ath79_add_sys_clkdev("ahb", ahb_rate); | ||
| 438 | |||
| 439 | clk_add_alias("wdt", NULL, "ref", NULL); | ||
| 440 | clk_add_alias("uart", NULL, "ref", NULL); | ||
| 441 | } | 433 | } |
| 442 | 434 | ||
| 443 | static void __init qca955x_clocks_init(void) | 435 | static void __init qca955x_clocks_init(void __iomem *pll_base) |
| 444 | { | 436 | { |
| 445 | unsigned long ref_rate; | 437 | unsigned long ref_rate; |
| 446 | unsigned long cpu_rate; | 438 | unsigned long cpu_rate; |
| @@ -456,7 +448,9 @@ static void __init qca955x_clocks_init(void) | |||
| 456 | else | 448 | else |
| 457 | ref_rate = 25 * 1000 * 1000; | 449 | ref_rate = 25 * 1000 * 1000; |
| 458 | 450 | ||
| 459 | pll = ath79_pll_rr(QCA955X_PLL_CPU_CONFIG_REG); | 451 | ref_rate = ath79_setup_ref_clk(ref_rate); |
| 452 | |||
| 453 | pll = __raw_readl(pll_base + QCA955X_PLL_CPU_CONFIG_REG); | ||
| 460 | out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & | 454 | out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & |
| 461 | QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK; | 455 | QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK; |
| 462 | ref_div = (pll >> QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT) & | 456 | ref_div = (pll >> QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT) & |
| @@ -470,7 +464,7 @@ static void __init qca955x_clocks_init(void) | |||
| 470 | cpu_pll += frac * ref_rate / (ref_div * (1 << 6)); | 464 | cpu_pll += frac * ref_rate / (ref_div * (1 << 6)); |
| 471 | cpu_pll /= (1 << out_div); | 465 | cpu_pll /= (1 << out_div); |
| 472 | 466 | ||
| 473 | pll = ath79_pll_rr(QCA955X_PLL_DDR_CONFIG_REG); | 467 | pll = __raw_readl(pll_base + QCA955X_PLL_DDR_CONFIG_REG); |
| 474 | out_div = (pll >> QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & | 468 | out_div = (pll >> QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & |
| 475 | QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK; | 469 | QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK; |
| 476 | ref_div = (pll >> QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT) & | 470 | ref_div = (pll >> QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT) & |
| @@ -484,7 +478,7 @@ static void __init qca955x_clocks_init(void) | |||
| 484 | ddr_pll += frac * ref_rate / (ref_div * (1 << 10)); | 478 | ddr_pll += frac * ref_rate / (ref_div * (1 << 10)); |
| 485 | ddr_pll /= (1 << out_div); | 479 | ddr_pll /= (1 << out_div); |
| 486 | 480 | ||
| 487 | clk_ctrl = ath79_pll_rr(QCA955X_PLL_CLK_CTRL_REG); | 481 | clk_ctrl = __raw_readl(pll_base + QCA955X_PLL_CLK_CTRL_REG); |
| 488 | 482 | ||
| 489 | postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & | 483 | postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & |
| 490 | QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; | 484 | QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; |
| @@ -516,16 +510,12 @@ static void __init qca955x_clocks_init(void) | |||
| 516 | else | 510 | else |
| 517 | ahb_rate = cpu_pll / (postdiv + 1); | 511 | ahb_rate = cpu_pll / (postdiv + 1); |
| 518 | 512 | ||
| 519 | ath79_add_sys_clkdev("ref", ref_rate); | 513 | ath79_set_clk(ATH79_CLK_CPU, cpu_rate); |
| 520 | clks[ATH79_CLK_CPU] = ath79_add_sys_clkdev("cpu", cpu_rate); | 514 | ath79_set_clk(ATH79_CLK_DDR, ddr_rate); |
| 521 | clks[ATH79_CLK_DDR] = ath79_add_sys_clkdev("ddr", ddr_rate); | 515 | ath79_set_clk(ATH79_CLK_AHB, ahb_rate); |
| 522 | clks[ATH79_CLK_AHB] = ath79_add_sys_clkdev("ahb", ahb_rate); | ||
| 523 | |||
| 524 | clk_add_alias("wdt", NULL, "ref", NULL); | ||
| 525 | clk_add_alias("uart", NULL, "ref", NULL); | ||
| 526 | } | 516 | } |
| 527 | 517 | ||
| 528 | static void __init qca956x_clocks_init(void) | 518 | static void __init qca956x_clocks_init(void __iomem *pll_base) |
| 529 | { | 519 | { |
| 530 | unsigned long ref_rate; | 520 | unsigned long ref_rate; |
| 531 | unsigned long cpu_rate; | 521 | unsigned long cpu_rate; |
| @@ -551,13 +541,15 @@ static void __init qca956x_clocks_init(void) | |||
| 551 | else | 541 | else |
| 552 | ref_rate = 25 * 1000 * 1000; | 542 | ref_rate = 25 * 1000 * 1000; |
| 553 | 543 | ||
| 554 | pll = ath79_pll_rr(QCA956X_PLL_CPU_CONFIG_REG); | 544 | ref_rate = ath79_setup_ref_clk(ref_rate); |
| 545 | |||
| 546 | pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG_REG); | ||
| 555 | out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & | 547 | out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & |
| 556 | QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK; | 548 | QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK; |
| 557 | ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) & | 549 | ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) & |
| 558 | QCA956X_PLL_CPU_CONFIG_REFDIV_MASK; | 550 | QCA956X_PLL_CPU_CONFIG_REFDIV_MASK; |
| 559 | 551 | ||
| 560 | pll = ath79_pll_rr(QCA956X_PLL_CPU_CONFIG1_REG); | 552 | pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG1_REG); |
| 561 | nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) & | 553 | nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) & |
| 562 | QCA956X_PLL_CPU_CONFIG1_NINT_MASK; | 554 | QCA956X_PLL_CPU_CONFIG1_NINT_MASK; |
| 563 | hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) & | 555 | hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) & |
| @@ -570,12 +562,12 @@ static void __init qca956x_clocks_init(void) | |||
| 570 | cpu_pll += (hfrac >> 13) * ref_rate / ref_div; | 562 | cpu_pll += (hfrac >> 13) * ref_rate / ref_div; |
| 571 | cpu_pll /= (1 << out_div); | 563 | cpu_pll /= (1 << out_div); |
| 572 | 564 | ||
| 573 | pll = ath79_pll_rr(QCA956X_PLL_DDR_CONFIG_REG); | 565 | pll = __raw_readl(pll_base + QCA956X_PLL_DDR_CONFIG_REG); |
| 574 | out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & | 566 | out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & |
| 575 | QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK; | 567 | QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK; |
| 576 | ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) & | 568 | ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) & |
| 577 | QCA956X_PLL_DDR_CONFIG_REFDIV_MASK; | 569 | QCA956X_PLL_DDR_CONFIG_REFDIV_MASK; |
| 578 | pll = ath79_pll_rr(QCA956X_PLL_DDR_CONFIG1_REG); | 570 | pll = __raw_readl(pll_base + QCA956X_PLL_DDR_CONFIG1_REG); |
| 579 | nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) & | 571 | nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) & |
| 580 | QCA956X_PLL_DDR_CONFIG1_NINT_MASK; | 572 | QCA956X_PLL_DDR_CONFIG1_NINT_MASK; |
| 581 | hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) & | 573 | hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) & |
| @@ -588,7 +580,7 @@ static void __init qca956x_clocks_init(void) | |||
| 588 | ddr_pll += (hfrac >> 13) * ref_rate / ref_div; | 580 | ddr_pll += (hfrac >> 13) * ref_rate / ref_div; |
| 589 | ddr_pll /= (1 << out_div); | 581 | ddr_pll /= (1 << out_div); |
| 590 | 582 | ||
| 591 | clk_ctrl = ath79_pll_rr(QCA956X_PLL_CLK_CTRL_REG); | 583 | clk_ctrl = __raw_readl(pll_base + QCA956X_PLL_CLK_CTRL_REG); |
| 592 | 584 | ||
| 593 | postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & | 585 | postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & |
| 594 | QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; | 586 | QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; |
| @@ -620,72 +612,19 @@ static void __init qca956x_clocks_init(void) | |||
| 620 | else | 612 | else |
| 621 | ahb_rate = cpu_pll / (postdiv + 1); | 613 | ahb_rate = cpu_pll / (postdiv + 1); |
| 622 | 614 | ||
| 623 | ath79_add_sys_clkdev("ref", ref_rate); | 615 | ath79_set_clk(ATH79_CLK_CPU, cpu_rate); |
| 624 | ath79_add_sys_clkdev("cpu", cpu_rate); | 616 | ath79_set_clk(ATH79_CLK_DDR, ddr_rate); |
| 625 | ath79_add_sys_clkdev("ddr", ddr_rate); | 617 | ath79_set_clk(ATH79_CLK_AHB, ahb_rate); |
| 626 | ath79_add_sys_clkdev("ahb", ahb_rate); | ||
| 627 | |||
| 628 | clk_add_alias("wdt", NULL, "ref", NULL); | ||
| 629 | clk_add_alias("uart", NULL, "ref", NULL); | ||
| 630 | } | ||
| 631 | |||
| 632 | void __init ath79_clocks_init(void) | ||
| 633 | { | ||
| 634 | if (soc_is_ar71xx()) | ||
| 635 | ar71xx_clocks_init(); | ||
| 636 | else if (soc_is_ar724x() || soc_is_ar913x()) | ||
| 637 | ar724x_clocks_init(); | ||
| 638 | else if (soc_is_ar933x()) | ||
| 639 | ar933x_clocks_init(); | ||
| 640 | else if (soc_is_ar934x()) | ||
| 641 | ar934x_clocks_init(); | ||
| 642 | else if (soc_is_qca953x()) | ||
| 643 | qca953x_clocks_init(); | ||
| 644 | else if (soc_is_qca955x()) | ||
| 645 | qca955x_clocks_init(); | ||
| 646 | else if (soc_is_qca956x() || soc_is_tp9343()) | ||
| 647 | qca956x_clocks_init(); | ||
| 648 | else | ||
| 649 | BUG(); | ||
| 650 | } | ||
| 651 | |||
| 652 | unsigned long __init | ||
| 653 | ath79_get_sys_clk_rate(const char *id) | ||
| 654 | { | ||
| 655 | struct clk *clk; | ||
| 656 | unsigned long rate; | ||
| 657 | |||
| 658 | clk = clk_get(NULL, id); | ||
| 659 | if (IS_ERR(clk)) | ||
| 660 | panic("unable to get %s clock, err=%d", id, (int) PTR_ERR(clk)); | ||
| 661 | |||
| 662 | rate = clk_get_rate(clk); | ||
| 663 | clk_put(clk); | ||
| 664 | |||
| 665 | return rate; | ||
| 666 | } | 618 | } |
| 667 | 619 | ||
| 668 | #ifdef CONFIG_OF | ||
| 669 | static void __init ath79_clocks_init_dt(struct device_node *np) | 620 | static void __init ath79_clocks_init_dt(struct device_node *np) |
| 670 | { | 621 | { |
| 671 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | ||
| 672 | } | ||
| 673 | |||
| 674 | CLK_OF_DECLARE(ar7100, "qca,ar7100-pll", ath79_clocks_init_dt); | ||
| 675 | CLK_OF_DECLARE(ar7240, "qca,ar7240-pll", ath79_clocks_init_dt); | ||
| 676 | CLK_OF_DECLARE(ar9340, "qca,ar9340-pll", ath79_clocks_init_dt); | ||
| 677 | CLK_OF_DECLARE(ar9550, "qca,qca9550-pll", ath79_clocks_init_dt); | ||
| 678 | |||
| 679 | static void __init ath79_clocks_init_dt_ng(struct device_node *np) | ||
| 680 | { | ||
| 681 | struct clk *ref_clk; | 622 | struct clk *ref_clk; |
| 682 | void __iomem *pll_base; | 623 | void __iomem *pll_base; |
| 683 | 624 | ||
| 684 | ref_clk = of_clk_get(np, 0); | 625 | ref_clk = of_clk_get(np, 0); |
| 685 | if (IS_ERR(ref_clk)) { | 626 | if (!IS_ERR(ref_clk)) |
| 686 | pr_err("%pOF: of_clk_get failed\n", np); | 627 | clks[ATH79_CLK_REF] = ref_clk; |
| 687 | goto err; | ||
| 688 | } | ||
| 689 | 628 | ||
| 690 | pll_base = of_iomap(np, 0); | 629 | pll_base = of_iomap(np, 0); |
| 691 | if (!pll_base) { | 630 | if (!pll_base) { |
| @@ -693,14 +632,24 @@ static void __init ath79_clocks_init_dt_ng(struct device_node *np) | |||
| 693 | goto err_clk; | 632 | goto err_clk; |
| 694 | } | 633 | } |
| 695 | 634 | ||
| 696 | if (of_device_is_compatible(np, "qca,ar9130-pll")) | 635 | if (of_device_is_compatible(np, "qca,ar7100-pll")) |
| 697 | ar724x_clk_init(ref_clk, pll_base); | 636 | ar71xx_clocks_init(pll_base); |
| 637 | else if (of_device_is_compatible(np, "qca,ar7240-pll") || | ||
| 638 | of_device_is_compatible(np, "qca,ar9130-pll")) | ||
| 639 | ar724x_clocks_init(pll_base); | ||
| 698 | else if (of_device_is_compatible(np, "qca,ar9330-pll")) | 640 | else if (of_device_is_compatible(np, "qca,ar9330-pll")) |
| 699 | ar9330_clk_init(ref_clk, pll_base); | 641 | ar933x_clocks_init(pll_base); |
| 700 | else { | 642 | else if (of_device_is_compatible(np, "qca,ar9340-pll")) |
| 701 | pr_err("%pOF: could not find any appropriate clk_init()\n", np); | 643 | ar934x_clocks_init(pll_base); |
| 702 | goto err_iounmap; | 644 | else if (of_device_is_compatible(np, "qca,qca9530-pll")) |
| 703 | } | 645 | qca953x_clocks_init(pll_base); |
| 646 | else if (of_device_is_compatible(np, "qca,qca9550-pll")) | ||
| 647 | qca955x_clocks_init(pll_base); | ||
| 648 | else if (of_device_is_compatible(np, "qca,qca9560-pll")) | ||
| 649 | qca956x_clocks_init(pll_base); | ||
| 650 | |||
| 651 | if (!clks[ATH79_CLK_MDIO]) | ||
| 652 | clks[ATH79_CLK_MDIO] = clks[ATH79_CLK_REF]; | ||
| 704 | 653 | ||
| 705 | if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) { | 654 | if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) { |
| 706 | pr_err("%pOF: could not register clk provider\n", np); | 655 | pr_err("%pOF: could not register clk provider\n", np); |
| @@ -714,10 +663,13 @@ err_iounmap: | |||
| 714 | 663 | ||
| 715 | err_clk: | 664 | err_clk: |
| 716 | clk_put(ref_clk); | 665 | clk_put(ref_clk); |
| 717 | |||
| 718 | err: | ||
| 719 | return; | ||
| 720 | } | 666 | } |
| 721 | CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt_ng); | 667 | |
| 722 | CLK_OF_DECLARE(ar9330_clk, "qca,ar9330-pll", ath79_clocks_init_dt_ng); | 668 | CLK_OF_DECLARE(ar7100_clk, "qca,ar7100-pll", ath79_clocks_init_dt); |
| 723 | #endif | 669 | CLK_OF_DECLARE(ar7240_clk, "qca,ar7240-pll", ath79_clocks_init_dt); |
| 670 | CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt); | ||
| 671 | CLK_OF_DECLARE(ar9330_clk, "qca,ar9330-pll", ath79_clocks_init_dt); | ||
| 672 | CLK_OF_DECLARE(ar9340_clk, "qca,ar9340-pll", ath79_clocks_init_dt); | ||
| 673 | CLK_OF_DECLARE(ar9530_clk, "qca,qca9530-pll", ath79_clocks_init_dt); | ||
| 674 | CLK_OF_DECLARE(ar9550_clk, "qca,qca9550-pll", ath79_clocks_init_dt); | ||
| 675 | CLK_OF_DECLARE(ar9560_clk, "qca,qca9560-pll", ath79_clocks_init_dt); | ||
diff --git a/arch/mips/ath79/common.h b/arch/mips/ath79/common.h index 870c6b2e97e8..25b96f59e8e8 100644 --- a/arch/mips/ath79/common.h +++ b/arch/mips/ath79/common.h | |||
| @@ -19,11 +19,6 @@ | |||
| 19 | #define ATH79_MEM_SIZE_MIN (2 * 1024 * 1024) | 19 | #define ATH79_MEM_SIZE_MIN (2 * 1024 * 1024) |
| 20 | #define ATH79_MEM_SIZE_MAX (256 * 1024 * 1024) | 20 | #define ATH79_MEM_SIZE_MAX (256 * 1024 * 1024) |
| 21 | 21 | ||
| 22 | void ath79_clocks_init(void); | ||
| 23 | unsigned long ath79_get_sys_clk_rate(const char *id); | ||
| 24 | |||
| 25 | void ath79_ddr_ctrl_init(void); | 22 | void ath79_ddr_ctrl_init(void); |
| 26 | 23 | ||
| 27 | void ath79_gpio_init(void); | ||
| 28 | |||
| 29 | #endif /* __ATH79_COMMON_H */ | 24 | #endif /* __ATH79_COMMON_H */ |
diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c deleted file mode 100644 index 9d0172a4dc69..000000000000 --- a/arch/mips/ath79/dev-common.c +++ /dev/null | |||
| @@ -1,159 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Atheros AR71XX/AR724X/AR913X common devices | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
| 5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
| 6 | * | ||
| 7 | * Parts of this file are based on Atheros' 2.6.15 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/kernel.h> | ||
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/platform_device.h> | ||
| 17 | #include <linux/platform_data/gpio-ath79.h> | ||
| 18 | #include <linux/serial_8250.h> | ||
| 19 | #include <linux/clk.h> | ||
| 20 | #include <linux/err.h> | ||
| 21 | |||
| 22 | #include <asm/mach-ath79/ath79.h> | ||
| 23 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
| 24 | #include "common.h" | ||
| 25 | #include "dev-common.h" | ||
| 26 | |||
| 27 | static struct resource ath79_uart_resources[] = { | ||
| 28 | { | ||
| 29 | .start = AR71XX_UART_BASE, | ||
| 30 | .end = AR71XX_UART_BASE + AR71XX_UART_SIZE - 1, | ||
| 31 | .flags = IORESOURCE_MEM, | ||
| 32 | }, | ||
| 33 | }; | ||
| 34 | |||
| 35 | #define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP) | ||
| 36 | static struct plat_serial8250_port ath79_uart_data[] = { | ||
| 37 | { | ||
| 38 | .mapbase = AR71XX_UART_BASE, | ||
| 39 | .irq = ATH79_MISC_IRQ(3), | ||
| 40 | .flags = AR71XX_UART_FLAGS, | ||
| 41 | .iotype = UPIO_MEM32, | ||
| 42 | .regshift = 2, | ||
| 43 | }, { | ||
| 44 | /* terminating entry */ | ||
| 45 | } | ||
| 46 | }; | ||
| 47 | |||
| 48 | static struct platform_device ath79_uart_device = { | ||
| 49 | .name = "serial8250", | ||
| 50 | .id = PLAT8250_DEV_PLATFORM, | ||
| 51 | .resource = ath79_uart_resources, | ||
| 52 | .num_resources = ARRAY_SIZE(ath79_uart_resources), | ||
| 53 | .dev = { | ||
| 54 | .platform_data = ath79_uart_data | ||
| 55 | }, | ||
| 56 | }; | ||
| 57 | |||
| 58 | static struct resource ar933x_uart_resources[] = { | ||
| 59 | { | ||
| 60 | .start = AR933X_UART_BASE, | ||
| 61 | .end = AR933X_UART_BASE + AR71XX_UART_SIZE - 1, | ||
| 62 | .flags = IORESOURCE_MEM, | ||
| 63 | }, | ||
| 64 | { | ||
| 65 | .start = ATH79_MISC_IRQ(3), | ||
| 66 | .end = ATH79_MISC_IRQ(3), | ||
| 67 | .flags = IORESOURCE_IRQ, | ||
| 68 | }, | ||
| 69 | }; | ||
| 70 | |||
| 71 | static struct platform_device ar933x_uart_device = { | ||
| 72 | .name = "ar933x-uart", | ||
| 73 | .id = -1, | ||
| 74 | .resource = ar933x_uart_resources, | ||
| 75 | .num_resources = ARRAY_SIZE(ar933x_uart_resources), | ||
| 76 | }; | ||
| 77 | |||
| 78 | void __init ath79_register_uart(void) | ||
| 79 | { | ||
| 80 | unsigned long uart_clk_rate; | ||
| 81 | |||
| 82 | uart_clk_rate = ath79_get_sys_clk_rate("uart"); | ||
| 83 | |||
| 84 | if (soc_is_ar71xx() || | ||
| 85 | soc_is_ar724x() || | ||
| 86 | soc_is_ar913x() || | ||
| 87 | soc_is_ar934x() || | ||
| 88 | soc_is_qca955x()) { | ||
| 89 | ath79_uart_data[0].uartclk = uart_clk_rate; | ||
| 90 | platform_device_register(&ath79_uart_device); | ||
| 91 | } else if (soc_is_ar933x()) { | ||
| 92 | platform_device_register(&ar933x_uart_device); | ||
| 93 | } else { | ||
| 94 | BUG(); | ||
| 95 | } | ||
| 96 | } | ||
| 97 | |||
| 98 | void __init ath79_register_wdt(void) | ||
| 99 | { | ||
| 100 | struct resource res; | ||
| 101 | |||
| 102 | memset(&res, 0, sizeof(res)); | ||
| 103 | |||
| 104 | res.flags = IORESOURCE_MEM; | ||
| 105 | res.start = AR71XX_RESET_BASE + AR71XX_RESET_REG_WDOG_CTRL; | ||
| 106 | res.end = res.start + 0x8 - 1; | ||
| 107 | |||
| 108 | platform_device_register_simple("ath79-wdt", -1, &res, 1); | ||
| 109 | } | ||
| 110 | |||
| 111 | static struct ath79_gpio_platform_data ath79_gpio_pdata; | ||
| 112 | |||
| 113 | static struct resource ath79_gpio_resources[] = { | ||
| 114 | { | ||
| 115 | .flags = IORESOURCE_MEM, | ||
| 116 | .start = AR71XX_GPIO_BASE, | ||
| 117 | .end = AR71XX_GPIO_BASE + AR71XX_GPIO_SIZE - 1, | ||
| 118 | }, | ||
| 119 | { | ||
| 120 | .start = ATH79_MISC_IRQ(2), | ||
| 121 | .end = ATH79_MISC_IRQ(2), | ||
| 122 | .flags = IORESOURCE_IRQ, | ||
| 123 | }, | ||
| 124 | }; | ||
| 125 | |||
| 126 | static struct platform_device ath79_gpio_device = { | ||
| 127 | .name = "ath79-gpio", | ||
| 128 | .id = -1, | ||
| 129 | .resource = ath79_gpio_resources, | ||
| 130 | .num_resources = ARRAY_SIZE(ath79_gpio_resources), | ||
| 131 | .dev = { | ||
| 132 | .platform_data = &ath79_gpio_pdata | ||
| 133 | }, | ||
| 134 | }; | ||
| 135 | |||
| 136 | void __init ath79_gpio_init(void) | ||
| 137 | { | ||
| 138 | if (soc_is_ar71xx()) { | ||
| 139 | ath79_gpio_pdata.ngpios = AR71XX_GPIO_COUNT; | ||
| 140 | } else if (soc_is_ar7240()) { | ||
| 141 | ath79_gpio_pdata.ngpios = AR7240_GPIO_COUNT; | ||
| 142 | } else if (soc_is_ar7241() || soc_is_ar7242()) { | ||
| 143 | ath79_gpio_pdata.ngpios = AR7241_GPIO_COUNT; | ||
| 144 | } else if (soc_is_ar913x()) { | ||
| 145 | ath79_gpio_pdata.ngpios = AR913X_GPIO_COUNT; | ||
| 146 | } else if (soc_is_ar933x()) { | ||
| 147 | ath79_gpio_pdata.ngpios = AR933X_GPIO_COUNT; | ||
| 148 | } else if (soc_is_ar934x()) { | ||
| 149 | ath79_gpio_pdata.ngpios = AR934X_GPIO_COUNT; | ||
| 150 | ath79_gpio_pdata.oe_inverted = 1; | ||
| 151 | } else if (soc_is_qca955x()) { | ||
| 152 | ath79_gpio_pdata.ngpios = QCA955X_GPIO_COUNT; | ||
| 153 | ath79_gpio_pdata.oe_inverted = 1; | ||
| 154 | } else { | ||
| 155 | BUG(); | ||
| 156 | } | ||
| 157 | |||
| 158 | platform_device_register(&ath79_gpio_device); | ||
| 159 | } | ||
diff --git a/arch/mips/ath79/dev-common.h b/arch/mips/ath79/dev-common.h deleted file mode 100644 index 0f514e1affce..000000000000 --- a/arch/mips/ath79/dev-common.h +++ /dev/null | |||
| @@ -1,18 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Atheros AR71XX/AR724X/AR913X common devices | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
| 5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
| 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 version 2 as published | ||
| 9 | * by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef _ATH79_DEV_COMMON_H | ||
| 13 | #define _ATH79_DEV_COMMON_H | ||
| 14 | |||
| 15 | void ath79_register_uart(void); | ||
| 16 | void ath79_register_wdt(void); | ||
| 17 | |||
| 18 | #endif /* _ATH79_DEV_COMMON_H */ | ||
diff --git a/arch/mips/ath79/dev-gpio-buttons.c b/arch/mips/ath79/dev-gpio-buttons.c deleted file mode 100644 index 366b35fb164d..000000000000 --- a/arch/mips/ath79/dev-gpio-buttons.c +++ /dev/null | |||
| @@ -1,56 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Atheros AR71XX/AR724X/AR913X GPIO button support | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
| 5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
| 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 version 2 as published | ||
| 9 | * by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include "linux/init.h" | ||
| 13 | #include "linux/slab.h" | ||
| 14 | #include <linux/platform_device.h> | ||
| 15 | |||
| 16 | #include "dev-gpio-buttons.h" | ||
| 17 | |||
| 18 | void __init ath79_register_gpio_keys_polled(int id, | ||
| 19 | unsigned poll_interval, | ||
| 20 | unsigned nbuttons, | ||
| 21 | struct gpio_keys_button *buttons) | ||
| 22 | { | ||
| 23 | struct platform_device *pdev; | ||
| 24 | struct gpio_keys_platform_data pdata; | ||
| 25 | struct gpio_keys_button *p; | ||
| 26 | int err; | ||
| 27 | |||
| 28 | p = kmemdup(buttons, nbuttons * sizeof(*p), GFP_KERNEL); | ||
| 29 | if (!p) | ||
| 30 | return; | ||
| 31 | |||
| 32 | pdev = platform_device_alloc("gpio-keys-polled", id); | ||
| 33 | if (!pdev) | ||
| 34 | goto err_free_buttons; | ||
| 35 | |||
| 36 | memset(&pdata, 0, sizeof(pdata)); | ||
| 37 | pdata.poll_interval = poll_interval; | ||
| 38 | pdata.nbuttons = nbuttons; | ||
| 39 | pdata.buttons = p; | ||
| 40 | |||
| 41 | err = platform_device_add_data(pdev, &pdata, sizeof(pdata)); | ||
| 42 | if (err) | ||
| 43 | goto err_put_pdev; | ||
| 44 | |||
| 45 | err = platform_device_add(pdev); | ||
| 46 | if (err) | ||
| 47 | goto err_put_pdev; | ||
| 48 | |||
| 49 | return; | ||
| 50 | |||
| 51 | err_put_pdev: | ||
| 52 | platform_device_put(pdev); | ||
| 53 | |||
| 54 | err_free_buttons: | ||
| 55 | kfree(p); | ||
| 56 | } | ||
diff --git a/arch/mips/ath79/dev-gpio-buttons.h b/arch/mips/ath79/dev-gpio-buttons.h deleted file mode 100644 index 481847ac1cba..000000000000 --- a/arch/mips/ath79/dev-gpio-buttons.h +++ /dev/null | |||
| @@ -1,23 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Atheros AR71XX/AR724X/AR913X GPIO button support | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
| 5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
| 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 version 2 as published | ||
| 9 | * by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef _ATH79_DEV_GPIO_BUTTONS_H | ||
| 13 | #define _ATH79_DEV_GPIO_BUTTONS_H | ||
| 14 | |||
| 15 | #include <linux/input.h> | ||
| 16 | #include <linux/gpio_keys.h> | ||
| 17 | |||
| 18 | void ath79_register_gpio_keys_polled(int id, | ||
| 19 | unsigned poll_interval, | ||
| 20 | unsigned nbuttons, | ||
| 21 | struct gpio_keys_button *buttons); | ||
| 22 | |||
| 23 | #endif /* _ATH79_DEV_GPIO_BUTTONS_H */ | ||
diff --git a/arch/mips/ath79/dev-leds-gpio.c b/arch/mips/ath79/dev-leds-gpio.c deleted file mode 100644 index dcb1debcefb8..000000000000 --- a/arch/mips/ath79/dev-leds-gpio.c +++ /dev/null | |||
| @@ -1,54 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Atheros AR71XX/AR724X/AR913X common GPIO LEDs support | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
| 5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
| 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 version 2 as published | ||
| 9 | * by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/init.h> | ||
| 13 | #include <linux/slab.h> | ||
| 14 | #include <linux/platform_device.h> | ||
| 15 | |||
| 16 | #include "dev-leds-gpio.h" | ||
| 17 | |||
| 18 | void __init ath79_register_leds_gpio(int id, | ||
| 19 | unsigned num_leds, | ||
| 20 | struct gpio_led *leds) | ||
| 21 | { | ||
| 22 | struct platform_device *pdev; | ||
| 23 | struct gpio_led_platform_data pdata; | ||
| 24 | struct gpio_led *p; | ||
| 25 | int err; | ||
| 26 | |||
| 27 | p = kmemdup(leds, num_leds * sizeof(*p), GFP_KERNEL); | ||
| 28 | if (!p) | ||
| 29 | return; | ||
| 30 | |||
| 31 | pdev = platform_device_alloc("leds-gpio", id); | ||
| 32 | if (!pdev) | ||
| 33 | goto err_free_leds; | ||
| 34 | |||
| 35 | memset(&pdata, 0, sizeof(pdata)); | ||
| 36 | pdata.num_leds = num_leds; | ||
| 37 | pdata.leds = p; | ||
| 38 | |||
| 39 | err = platform_device_add_data(pdev, &pdata, sizeof(pdata)); | ||
| 40 | if (err) | ||
| 41 | goto err_put_pdev; | ||
| 42 | |||
| 43 | err = platform_device_add(pdev); | ||
| 44 | if (err) | ||
| 45 | goto err_put_pdev; | ||
| 46 | |||
| 47 | return; | ||
| 48 | |||
| 49 | err_put_pdev: | ||
| 50 | platform_device_put(pdev); | ||
| 51 | |||
| 52 | err_free_leds: | ||
| 53 | kfree(p); | ||
| 54 | } | ||
diff --git a/arch/mips/ath79/dev-leds-gpio.h b/arch/mips/ath79/dev-leds-gpio.h deleted file mode 100644 index 6e5d8851ebcf..000000000000 --- a/arch/mips/ath79/dev-leds-gpio.h +++ /dev/null | |||
| @@ -1,21 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Atheros AR71XX/AR724X/AR913X common GPIO LEDs support | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
| 5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
| 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 version 2 as published | ||
| 9 | * by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef _ATH79_DEV_LEDS_GPIO_H | ||
| 13 | #define _ATH79_DEV_LEDS_GPIO_H | ||
| 14 | |||
| 15 | #include <linux/leds.h> | ||
| 16 | |||
| 17 | void ath79_register_leds_gpio(int id, | ||
| 18 | unsigned num_leds, | ||
| 19 | struct gpio_led *leds); | ||
| 20 | |||
| 21 | #endif /* _ATH79_DEV_LEDS_GPIO_H */ | ||
diff --git a/arch/mips/ath79/dev-spi.c b/arch/mips/ath79/dev-spi.c deleted file mode 100644 index aa30163efbfd..000000000000 --- a/arch/mips/ath79/dev-spi.c +++ /dev/null | |||
| @@ -1,38 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Atheros AR71XX/AR724X/AR913X SPI controller device | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
| 5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
| 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 version 2 as published | ||
| 9 | * by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/platform_device.h> | ||
| 13 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
| 14 | #include "dev-spi.h" | ||
| 15 | |||
| 16 | static struct resource ath79_spi_resources[] = { | ||
| 17 | { | ||
| 18 | .start = AR71XX_SPI_BASE, | ||
| 19 | .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, | ||
| 20 | .flags = IORESOURCE_MEM, | ||
| 21 | }, | ||
| 22 | }; | ||
| 23 | |||
| 24 | static struct platform_device ath79_spi_device = { | ||
| 25 | .name = "ath79-spi", | ||
| 26 | .id = -1, | ||
| 27 | .resource = ath79_spi_resources, | ||
| 28 | .num_resources = ARRAY_SIZE(ath79_spi_resources), | ||
| 29 | }; | ||
| 30 | |||
| 31 | void __init ath79_register_spi(struct ath79_spi_platform_data *pdata, | ||
| 32 | struct spi_board_info const *info, | ||
| 33 | unsigned n) | ||
| 34 | { | ||
| 35 | spi_register_board_info(info, n); | ||
| 36 | ath79_spi_device.dev.platform_data = pdata; | ||
| 37 | platform_device_register(&ath79_spi_device); | ||
| 38 | } | ||
diff --git a/arch/mips/ath79/dev-spi.h b/arch/mips/ath79/dev-spi.h deleted file mode 100644 index 6e15bc8651be..000000000000 --- a/arch/mips/ath79/dev-spi.h +++ /dev/null | |||
| @@ -1,22 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Atheros AR71XX/AR724X/AR913X SPI controller device | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
| 5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
| 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 version 2 as published | ||
| 9 | * by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef _ATH79_DEV_SPI_H | ||
| 13 | #define _ATH79_DEV_SPI_H | ||
| 14 | |||
| 15 | #include <linux/spi/spi.h> | ||
| 16 | #include <linux/platform_data/spi-ath79.h> | ||
| 17 | |||
| 18 | void ath79_register_spi(struct ath79_spi_platform_data *pdata, | ||
| 19 | struct spi_board_info const *info, | ||
| 20 | unsigned n); | ||
| 21 | |||
| 22 | #endif /* _ATH79_DEV_SPI_H */ | ||
diff --git a/arch/mips/ath79/dev-usb.c b/arch/mips/ath79/dev-usb.c deleted file mode 100644 index 8227265bcc2d..000000000000 --- a/arch/mips/ath79/dev-usb.c +++ /dev/null | |||
| @@ -1,242 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Atheros AR7XXX/AR9XXX USB Host Controller device | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
| 5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
| 6 | * | ||
| 7 | * Parts of this file are based on Atheros' 2.6.15 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/kernel.h> | ||
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/delay.h> | ||
| 17 | #include <linux/irq.h> | ||
| 18 | #include <linux/dma-mapping.h> | ||
| 19 | #include <linux/platform_device.h> | ||
| 20 | #include <linux/usb/ehci_pdriver.h> | ||
| 21 | #include <linux/usb/ohci_pdriver.h> | ||
| 22 | |||
| 23 | #include <asm/mach-ath79/ath79.h> | ||
| 24 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
| 25 | #include "common.h" | ||
| 26 | #include "dev-usb.h" | ||
| 27 | |||
| 28 | static u64 ath79_usb_dmamask = DMA_BIT_MASK(32); | ||
| 29 | |||
| 30 | static struct usb_ohci_pdata ath79_ohci_pdata = { | ||
| 31 | }; | ||
| 32 | |||
| 33 | static struct usb_ehci_pdata ath79_ehci_pdata_v1 = { | ||
| 34 | .has_synopsys_hc_bug = 1, | ||
| 35 | }; | ||
| 36 | |||
| 37 | static struct usb_ehci_pdata ath79_ehci_pdata_v2 = { | ||
| 38 | .caps_offset = 0x100, | ||
| 39 | .has_tt = 1, | ||
| 40 | }; | ||
| 41 | |||
| 42 | static void __init ath79_usb_register(const char *name, int id, | ||
| 43 | unsigned long base, unsigned long size, | ||
| 44 | int irq, const void *data, | ||
| 45 | size_t data_size) | ||
| 46 | { | ||
| 47 | struct resource res[2]; | ||
| 48 | struct platform_device *pdev; | ||
| 49 | |||
| 50 | memset(res, 0, sizeof(res)); | ||
| 51 | |||
| 52 | res[0].flags = IORESOURCE_MEM; | ||
| 53 | res[0].start = base; | ||
| 54 | res[0].end = base + size - 1; | ||
| 55 | |||
| 56 | res[1].flags = IORESOURCE_IRQ; | ||
| 57 | res[1].start = irq; | ||
| 58 | res[1].end = irq; | ||
| 59 | |||
| 60 | pdev = platform_device_register_resndata(NULL, name, id, | ||
| 61 | res, ARRAY_SIZE(res), | ||
| 62 | data, data_size); | ||
| 63 | |||
| 64 | if (IS_ERR(pdev)) { | ||
| 65 | pr_err("ath79: unable to register USB at %08lx, err=%d\n", | ||
| 66 | base, (int) PTR_ERR(pdev)); | ||
| 67 | return; | ||
| 68 | } | ||
| 69 | |||
| 70 | pdev->dev.dma_mask = &ath79_usb_dmamask; | ||
| 71 | pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); | ||
| 72 | } | ||
| 73 | |||
| 74 | #define AR71XX_USB_RESET_MASK (AR71XX_RESET_USB_HOST | \ | ||
| 75 | AR71XX_RESET_USB_PHY | \ | ||
| 76 | AR71XX_RESET_USB_OHCI_DLL) | ||
| 77 | |||
| 78 | static void __init ath79_usb_setup(void) | ||
| 79 | { | ||
| 80 | void __iomem *usb_ctrl_base; | ||
| 81 | |||
| 82 | ath79_device_reset_set(AR71XX_USB_RESET_MASK); | ||
| 83 | mdelay(1000); | ||
| 84 | ath79_device_reset_clear(AR71XX_USB_RESET_MASK); | ||
| 85 | |||
| 86 | usb_ctrl_base = ioremap(AR71XX_USB_CTRL_BASE, AR71XX_USB_CTRL_SIZE); | ||
| 87 | |||
| 88 | /* Turning on the Buff and Desc swap bits */ | ||
| 89 | __raw_writel(0xf0000, usb_ctrl_base + AR71XX_USB_CTRL_REG_CONFIG); | ||
| 90 | |||
| 91 | /* WAR for HW bug. Here it adjusts the duration between two SOFS */ | ||
| 92 | __raw_writel(0x20c00, usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ); | ||
| 93 | |||
| 94 | iounmap(usb_ctrl_base); | ||
| 95 | |||
| 96 | mdelay(900); | ||
| 97 | |||
| 98 | ath79_usb_register("ohci-platform", -1, | ||
| 99 | AR71XX_OHCI_BASE, AR71XX_OHCI_SIZE, | ||
| 100 | ATH79_MISC_IRQ(6), | ||
| 101 | &ath79_ohci_pdata, sizeof(ath79_ohci_pdata)); | ||
| 102 | |||
| 103 | ath79_usb_register("ehci-platform", -1, | ||
| 104 | AR71XX_EHCI_BASE, AR71XX_EHCI_SIZE, | ||
| 105 | ATH79_CPU_IRQ(3), | ||
| 106 | &ath79_ehci_pdata_v1, sizeof(ath79_ehci_pdata_v1)); | ||
| 107 | } | ||
| 108 | |||
| 109 | static void __init ar7240_usb_setup(void) | ||
| 110 | { | ||
| 111 | void __iomem *usb_ctrl_base; | ||
| 112 | |||
| 113 | ath79_device_reset_clear(AR7240_RESET_OHCI_DLL); | ||
| 114 | ath79_device_reset_set(AR7240_RESET_USB_HOST); | ||
| 115 | |||
| 116 | mdelay(1000); | ||
| 117 | |||
| 118 | ath79_device_reset_set(AR7240_RESET_OHCI_DLL); | ||
| 119 | ath79_device_reset_clear(AR7240_RESET_USB_HOST); | ||
| 120 | |||
| 121 | usb_ctrl_base = ioremap(AR7240_USB_CTRL_BASE, AR7240_USB_CTRL_SIZE); | ||
| 122 | |||
| 123 | /* WAR for HW bug. Here it adjusts the duration between two SOFS */ | ||
| 124 | __raw_writel(0x3, usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ); | ||
| 125 | |||
| 126 | iounmap(usb_ctrl_base); | ||
| 127 | |||
| 128 | ath79_usb_register("ohci-platform", -1, | ||
| 129 | AR7240_OHCI_BASE, AR7240_OHCI_SIZE, | ||
| 130 | ATH79_CPU_IRQ(3), | ||
| 131 | &ath79_ohci_pdata, sizeof(ath79_ohci_pdata)); | ||
| 132 | } | ||
| 133 | |||
| 134 | static void __init ar724x_usb_setup(void) | ||
| 135 | { | ||
| 136 | ath79_device_reset_set(AR724X_RESET_USBSUS_OVERRIDE); | ||
| 137 | mdelay(10); | ||
| 138 | |||
| 139 | ath79_device_reset_clear(AR724X_RESET_USB_HOST); | ||
| 140 | mdelay(10); | ||
| 141 | |||
| 142 | ath79_device_reset_clear(AR724X_RESET_USB_PHY); | ||
| 143 | mdelay(10); | ||
| 144 | |||
| 145 | ath79_usb_register("ehci-platform", -1, | ||
| 146 | AR724X_EHCI_BASE, AR724X_EHCI_SIZE, | ||
| 147 | ATH79_CPU_IRQ(3), | ||
| 148 | &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); | ||
| 149 | } | ||
| 150 | |||
| 151 | static void __init ar913x_usb_setup(void) | ||
| 152 | { | ||
| 153 | ath79_device_reset_set(AR913X_RESET_USBSUS_OVERRIDE); | ||
| 154 | mdelay(10); | ||
| 155 | |||
| 156 | ath79_device_reset_clear(AR913X_RESET_USB_HOST); | ||
| 157 | mdelay(10); | ||
| 158 | |||
| 159 | ath79_device_reset_clear(AR913X_RESET_USB_PHY); | ||
| 160 | mdelay(10); | ||
| 161 | |||
| 162 | ath79_usb_register("ehci-platform", -1, | ||
| 163 | AR913X_EHCI_BASE, AR913X_EHCI_SIZE, | ||
| 164 | ATH79_CPU_IRQ(3), | ||
| 165 | &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); | ||
| 166 | } | ||
| 167 | |||
| 168 | static void __init ar933x_usb_setup(void) | ||
| 169 | { | ||
| 170 | ath79_device_reset_set(AR933X_RESET_USBSUS_OVERRIDE); | ||
| 171 | mdelay(10); | ||
| 172 | |||
| 173 | ath79_device_reset_clear(AR933X_RESET_USB_HOST); | ||
| 174 | mdelay(10); | ||
| 175 | |||
| 176 | ath79_device_reset_clear(AR933X_RESET_USB_PHY); | ||
| 177 | mdelay(10); | ||
| 178 | |||
| 179 | ath79_usb_register("ehci-platform", -1, | ||
| 180 | AR933X_EHCI_BASE, AR933X_EHCI_SIZE, | ||
| 181 | ATH79_CPU_IRQ(3), | ||
| 182 | &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); | ||
| 183 | } | ||
| 184 | |||
| 185 | static void __init ar934x_usb_setup(void) | ||
| 186 | { | ||
| 187 | u32 bootstrap; | ||
| 188 | |||
| 189 | bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); | ||
| 190 | if (bootstrap & AR934X_BOOTSTRAP_USB_MODE_DEVICE) | ||
| 191 | return; | ||
| 192 | |||
| 193 | ath79_device_reset_set(AR934X_RESET_USBSUS_OVERRIDE); | ||
| 194 | udelay(1000); | ||
| 195 | |||
| 196 | ath79_device_reset_clear(AR934X_RESET_USB_PHY); | ||
| 197 | udelay(1000); | ||
| 198 | |||
| 199 | ath79_device_reset_clear(AR934X_RESET_USB_PHY_ANALOG); | ||
| 200 | udelay(1000); | ||
| 201 | |||
| 202 | ath79_device_reset_clear(AR934X_RESET_USB_HOST); | ||
| 203 | udelay(1000); | ||
| 204 | |||
| 205 | ath79_usb_register("ehci-platform", -1, | ||
| 206 | AR934X_EHCI_BASE, AR934X_EHCI_SIZE, | ||
| 207 | ATH79_CPU_IRQ(3), | ||
| 208 | &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); | ||
| 209 | } | ||
| 210 | |||
| 211 | static void __init qca955x_usb_setup(void) | ||
| 212 | { | ||
| 213 | ath79_usb_register("ehci-platform", 0, | ||
| 214 | QCA955X_EHCI0_BASE, QCA955X_EHCI_SIZE, | ||
| 215 | ATH79_IP3_IRQ(0), | ||
| 216 | &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); | ||
| 217 | |||
| 218 | ath79_usb_register("ehci-platform", 1, | ||
| 219 | QCA955X_EHCI1_BASE, QCA955X_EHCI_SIZE, | ||
| 220 | ATH79_IP3_IRQ(1), | ||
| 221 | &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2)); | ||
| 222 | } | ||
| 223 | |||
| 224 | void __init ath79_register_usb(void) | ||
| 225 | { | ||
| 226 | if (soc_is_ar71xx()) | ||
| 227 | ath79_usb_setup(); | ||
| 228 | else if (soc_is_ar7240()) | ||
| 229 | ar7240_usb_setup(); | ||
| 230 | else if (soc_is_ar7241() || soc_is_ar7242()) | ||
| 231 | ar724x_usb_setup(); | ||
| 232 | else if (soc_is_ar913x()) | ||
| 233 | ar913x_usb_setup(); | ||
| 234 | else if (soc_is_ar933x()) | ||
| 235 | ar933x_usb_setup(); | ||
| 236 | else if (soc_is_ar934x()) | ||
| 237 | ar934x_usb_setup(); | ||
| 238 | else if (soc_is_qca955x()) | ||
| 239 | qca955x_usb_setup(); | ||
| 240 | else | ||
| 241 | BUG(); | ||
| 242 | } | ||
diff --git a/arch/mips/ath79/dev-usb.h b/arch/mips/ath79/dev-usb.h deleted file mode 100644 index 4b86a69ca080..000000000000 --- a/arch/mips/ath79/dev-usb.h +++ /dev/null | |||
| @@ -1,17 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Atheros AR71XX/AR724X/AR913X USB Host Controller support | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
| 5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
| 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 version 2 as published | ||
| 9 | * by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef _ATH79_DEV_USB_H | ||
| 13 | #define _ATH79_DEV_USB_H | ||
| 14 | |||
| 15 | void ath79_register_usb(void); | ||
| 16 | |||
| 17 | #endif /* _ATH79_DEV_USB_H */ | ||
diff --git a/arch/mips/ath79/dev-wmac.c b/arch/mips/ath79/dev-wmac.c deleted file mode 100644 index da190b1b87ce..000000000000 --- a/arch/mips/ath79/dev-wmac.c +++ /dev/null | |||
| @@ -1,155 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Atheros AR913X/AR933X SoC built-in WMAC device support | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> | ||
| 5 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
| 6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
| 7 | * | ||
| 8 | * Parts of this file are based on Atheros 2.6.15/2.6.31 BSP | ||
| 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 | #include <linux/init.h> | ||
| 16 | #include <linux/delay.h> | ||
| 17 | #include <linux/irq.h> | ||
| 18 | #include <linux/platform_device.h> | ||
| 19 | #include <linux/ath9k_platform.h> | ||
| 20 | |||
| 21 | #include <asm/mach-ath79/ath79.h> | ||
| 22 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
| 23 | #include "dev-wmac.h" | ||
| 24 | |||
| 25 | static struct ath9k_platform_data ath79_wmac_data; | ||
| 26 | |||
| 27 | static struct resource ath79_wmac_resources[] = { | ||
| 28 | { | ||
| 29 | /* .start and .end fields are filled dynamically */ | ||
| 30 | .flags = IORESOURCE_MEM, | ||
| 31 | }, { | ||
| 32 | /* .start and .end fields are filled dynamically */ | ||
| 33 | .flags = IORESOURCE_IRQ, | ||
| 34 | }, | ||
| 35 | }; | ||
| 36 | |||
| 37 | static struct platform_device ath79_wmac_device = { | ||
| 38 | .name = "ath9k", | ||
| 39 | .id = -1, | ||
| 40 | .resource = ath79_wmac_resources, | ||
| 41 | .num_resources = ARRAY_SIZE(ath79_wmac_resources), | ||
| 42 | .dev = { | ||
| 43 | .platform_data = &ath79_wmac_data, | ||
| 44 | }, | ||
| 45 | }; | ||
| 46 | |||
| 47 | static void __init ar913x_wmac_setup(void) | ||
| 48 | { | ||
| 49 | /* reset the WMAC */ | ||
| 50 | ath79_device_reset_set(AR913X_RESET_AMBA2WMAC); | ||
| 51 | mdelay(10); | ||
| 52 | |||
| 53 | ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC); | ||
| 54 | mdelay(10); | ||
| 55 | |||
| 56 | ath79_wmac_resources[0].start = AR913X_WMAC_BASE; | ||
| 57 | ath79_wmac_resources[0].end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1; | ||
| 58 | ath79_wmac_resources[1].start = ATH79_CPU_IRQ(2); | ||
| 59 | ath79_wmac_resources[1].end = ATH79_CPU_IRQ(2); | ||
| 60 | } | ||
| 61 | |||
| 62 | |||
| 63 | static int ar933x_wmac_reset(void) | ||
| 64 | { | ||
| 65 | ath79_device_reset_set(AR933X_RESET_WMAC); | ||
| 66 | ath79_device_reset_clear(AR933X_RESET_WMAC); | ||
| 67 | |||
| 68 | return 0; | ||
| 69 | } | ||
| 70 | |||
| 71 | static int ar933x_r1_get_wmac_revision(void) | ||
| 72 | { | ||
| 73 | return ath79_soc_rev; | ||
| 74 | } | ||
| 75 | |||
| 76 | static void __init ar933x_wmac_setup(void) | ||
| 77 | { | ||
| 78 | u32 t; | ||
| 79 | |||
| 80 | ar933x_wmac_reset(); | ||
| 81 | |||
| 82 | ath79_wmac_device.name = "ar933x_wmac"; | ||
| 83 | |||
| 84 | ath79_wmac_resources[0].start = AR933X_WMAC_BASE; | ||
| 85 | ath79_wmac_resources[0].end = AR933X_WMAC_BASE + AR933X_WMAC_SIZE - 1; | ||
| 86 | ath79_wmac_resources[1].start = ATH79_CPU_IRQ(2); | ||
| 87 | ath79_wmac_resources[1].end = ATH79_CPU_IRQ(2); | ||
| 88 | |||
| 89 | t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); | ||
| 90 | if (t & AR933X_BOOTSTRAP_REF_CLK_40) | ||
| 91 | ath79_wmac_data.is_clk_25mhz = false; | ||
| 92 | else | ||
| 93 | ath79_wmac_data.is_clk_25mhz = true; | ||
| 94 | |||
| 95 | if (ath79_soc_rev == 1) | ||
| 96 | ath79_wmac_data.get_mac_revision = ar933x_r1_get_wmac_revision; | ||
| 97 | |||
| 98 | ath79_wmac_data.external_reset = ar933x_wmac_reset; | ||
| 99 | } | ||
| 100 | |||
| 101 | static void ar934x_wmac_setup(void) | ||
| 102 | { | ||
| 103 | u32 t; | ||
| 104 | |||
| 105 | ath79_wmac_device.name = "ar934x_wmac"; | ||
| 106 | |||
| 107 | ath79_wmac_resources[0].start = AR934X_WMAC_BASE; | ||
| 108 | ath79_wmac_resources[0].end = AR934X_WMAC_BASE + AR934X_WMAC_SIZE - 1; | ||
| 109 | ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1); | ||
| 110 | ath79_wmac_resources[1].end = ATH79_IP2_IRQ(1); | ||
| 111 | |||
| 112 | t = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); | ||
| 113 | if (t & AR934X_BOOTSTRAP_REF_CLK_40) | ||
| 114 | ath79_wmac_data.is_clk_25mhz = false; | ||
| 115 | else | ||
| 116 | ath79_wmac_data.is_clk_25mhz = true; | ||
| 117 | } | ||
| 118 | |||
| 119 | static void qca955x_wmac_setup(void) | ||
| 120 | { | ||
| 121 | u32 t; | ||
| 122 | |||
| 123 | ath79_wmac_device.name = "qca955x_wmac"; | ||
| 124 | |||
| 125 | ath79_wmac_resources[0].start = QCA955X_WMAC_BASE; | ||
| 126 | ath79_wmac_resources[0].end = QCA955X_WMAC_BASE + QCA955X_WMAC_SIZE - 1; | ||
| 127 | ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1); | ||
| 128 | ath79_wmac_resources[1].end = ATH79_IP2_IRQ(1); | ||
| 129 | |||
| 130 | t = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP); | ||
| 131 | if (t & QCA955X_BOOTSTRAP_REF_CLK_40) | ||
| 132 | ath79_wmac_data.is_clk_25mhz = false; | ||
| 133 | else | ||
| 134 | ath79_wmac_data.is_clk_25mhz = true; | ||
| 135 | } | ||
| 136 | |||
| 137 | void __init ath79_register_wmac(u8 *cal_data) | ||
| 138 | { | ||
| 139 | if (soc_is_ar913x()) | ||
| 140 | ar913x_wmac_setup(); | ||
| 141 | else if (soc_is_ar933x()) | ||
| 142 | ar933x_wmac_setup(); | ||
| 143 | else if (soc_is_ar934x()) | ||
| 144 | ar934x_wmac_setup(); | ||
| 145 | else if (soc_is_qca955x()) | ||
| 146 | qca955x_wmac_setup(); | ||
| 147 | else | ||
| 148 | BUG(); | ||
| 149 | |||
| 150 | if (cal_data) | ||
| 151 | memcpy(ath79_wmac_data.eeprom_data, cal_data, | ||
| 152 | sizeof(ath79_wmac_data.eeprom_data)); | ||
| 153 | |||
| 154 | platform_device_register(&ath79_wmac_device); | ||
| 155 | } | ||
diff --git a/arch/mips/ath79/dev-wmac.h b/arch/mips/ath79/dev-wmac.h deleted file mode 100644 index c9cd8709f090..000000000000 --- a/arch/mips/ath79/dev-wmac.h +++ /dev/null | |||
| @@ -1,17 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Atheros AR913X/AR933X SoC built-in WMAC device support | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
| 5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
| 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 version 2 as published | ||
| 9 | * by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef _ATH79_DEV_WMAC_H | ||
| 13 | #define _ATH79_DEV_WMAC_H | ||
| 14 | |||
| 15 | void ath79_register_wmac(u8 *cal_data); | ||
| 16 | |||
| 17 | #endif /* _ATH79_DEV_WMAC_H */ | ||
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c deleted file mode 100644 index 2dfff1f19004..000000000000 --- a/arch/mips/ath79/irq.c +++ /dev/null | |||
| @@ -1,169 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Atheros AR71xx/AR724x/AR913x specific interrupt handling | ||
| 3 | * | ||
| 4 | * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> | ||
| 5 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
| 6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
| 7 | * | ||
| 8 | * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP | ||
| 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 | #include <linux/kernel.h> | ||
| 16 | #include <linux/init.h> | ||
| 17 | #include <linux/interrupt.h> | ||
| 18 | #include <linux/irqchip.h> | ||
| 19 | #include <linux/of_irq.h> | ||
| 20 | |||
| 21 | #include <asm/irq_cpu.h> | ||
| 22 | #include <asm/mipsregs.h> | ||
| 23 | |||
| 24 | #include <asm/mach-ath79/ath79.h> | ||
| 25 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
| 26 | #include "common.h" | ||
| 27 | #include "machtypes.h" | ||
| 28 | |||
| 29 | |||
| 30 | static void ar934x_ip2_irq_dispatch(struct irq_desc *desc) | ||
| 31 | { | ||
| 32 | u32 status; | ||
| 33 | |||
| 34 | status = ath79_reset_rr(AR934X_RESET_REG_PCIE_WMAC_INT_STATUS); | ||
| 35 | |||
| 36 | if (status & AR934X_PCIE_WMAC_INT_PCIE_ALL) { | ||
| 37 | ath79_ddr_wb_flush(3); | ||
| 38 | generic_handle_irq(ATH79_IP2_IRQ(0)); | ||
| 39 | } else if (status & AR934X_PCIE_WMAC_INT_WMAC_ALL) { | ||
| 40 | ath79_ddr_wb_flush(4); | ||
| 41 | generic_handle_irq(ATH79_IP2_IRQ(1)); | ||
| 42 | } else { | ||
| 43 | spurious_interrupt(); | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | static void ar934x_ip2_irq_init(void) | ||
| 48 | { | ||
| 49 | int i; | ||
| 50 | |||
| 51 | for (i = ATH79_IP2_IRQ_BASE; | ||
| 52 | i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++) | ||
| 53 | irq_set_chip_and_handler(i, &dummy_irq_chip, | ||
| 54 | handle_level_irq); | ||
| 55 | |||
| 56 | irq_set_chained_handler(ATH79_CPU_IRQ(2), ar934x_ip2_irq_dispatch); | ||
| 57 | } | ||
| 58 | |||
| 59 | static void qca955x_ip2_irq_dispatch(struct irq_desc *desc) | ||
| 60 | { | ||
| 61 | u32 status; | ||
| 62 | |||
| 63 | status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS); | ||
| 64 | status &= QCA955X_EXT_INT_PCIE_RC1_ALL | QCA955X_EXT_INT_WMAC_ALL; | ||
| 65 | |||
| 66 | if (status == 0) { | ||
| 67 | spurious_interrupt(); | ||
| 68 | return; | ||
| 69 | } | ||
| 70 | |||
| 71 | if (status & QCA955X_EXT_INT_PCIE_RC1_ALL) { | ||
| 72 | /* TODO: flush DDR? */ | ||
| 73 | generic_handle_irq(ATH79_IP2_IRQ(0)); | ||
| 74 | } | ||
| 75 | |||
| 76 | if (status & QCA955X_EXT_INT_WMAC_ALL) { | ||
| 77 | /* TODO: flush DDR? */ | ||
| 78 | generic_handle_irq(ATH79_IP2_IRQ(1)); | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | static void qca955x_ip3_irq_dispatch(struct irq_desc *desc) | ||
| 83 | { | ||
| 84 | u32 status; | ||
| 85 | |||
| 86 | status = ath79_reset_rr(QCA955X_RESET_REG_EXT_INT_STATUS); | ||
| 87 | status &= QCA955X_EXT_INT_PCIE_RC2_ALL | | ||
| 88 | QCA955X_EXT_INT_USB1 | | ||
| 89 | QCA955X_EXT_INT_USB2; | ||
| 90 | |||
| 91 | if (status == 0) { | ||
| 92 | spurious_interrupt(); | ||
| 93 | return; | ||
| 94 | } | ||
| 95 | |||
| 96 | if (status & QCA955X_EXT_INT_USB1) { | ||
| 97 | /* TODO: flush DDR? */ | ||
| 98 | generic_handle_irq(ATH79_IP3_IRQ(0)); | ||
| 99 | } | ||
| 100 | |||
| 101 | if (status & QCA955X_EXT_INT_USB2) { | ||
| 102 | /* TODO: flush DDR? */ | ||
| 103 | generic_handle_irq(ATH79_IP3_IRQ(1)); | ||
| 104 | } | ||
| 105 | |||
| 106 | if (status & QCA955X_EXT_INT_PCIE_RC2_ALL) { | ||
| 107 | /* TODO: flush DDR? */ | ||
| 108 | generic_handle_irq(ATH79_IP3_IRQ(2)); | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 | static void qca955x_irq_init(void) | ||
| 113 | { | ||
| 114 | int i; | ||
| 115 | |||
| 116 | for (i = ATH79_IP2_IRQ_BASE; | ||
| 117 | i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++) | ||
| 118 | irq_set_chip_and_handler(i, &dummy_irq_chip, | ||
| 119 | handle_level_irq); | ||
| 120 | |||
| 121 | irq_set_chained_handler(ATH79_CPU_IRQ(2), qca955x_ip2_irq_dispatch); | ||
| 122 | |||
| 123 | for (i = ATH79_IP3_IRQ_BASE; | ||
| 124 | i < ATH79_IP3_IRQ_BASE + ATH79_IP3_IRQ_COUNT; i++) | ||
| 125 | irq_set_chip_and_handler(i, &dummy_irq_chip, | ||
| 126 | handle_level_irq); | ||
| 127 | |||
| 128 | irq_set_chained_handler(ATH79_CPU_IRQ(3), qca955x_ip3_irq_dispatch); | ||
| 129 | } | ||
| 130 | |||
| 131 | void __init arch_init_irq(void) | ||
| 132 | { | ||
| 133 | unsigned irq_wb_chan2 = -1; | ||
| 134 | unsigned irq_wb_chan3 = -1; | ||
| 135 | bool misc_is_ar71xx; | ||
| 136 | |||
| 137 | if (mips_machtype == ATH79_MACH_GENERIC_OF) { | ||
| 138 | irqchip_init(); | ||
| 139 | return; | ||
| 140 | } | ||
| 141 | |||
| 142 | if (soc_is_ar71xx() || soc_is_ar724x() || | ||
| 143 | soc_is_ar913x() || soc_is_ar933x()) { | ||
| 144 | irq_wb_chan2 = 3; | ||
| 145 | irq_wb_chan3 = 2; | ||
| 146 | } else if (soc_is_ar934x()) { | ||
| 147 | irq_wb_chan3 = 2; | ||
| 148 | } | ||
| 149 | |||
| 150 | ath79_cpu_irq_init(irq_wb_chan2, irq_wb_chan3); | ||
| 151 | |||
| 152 | if (soc_is_ar71xx() || soc_is_ar913x()) | ||
| 153 | misc_is_ar71xx = true; | ||
| 154 | else if (soc_is_ar724x() || | ||
| 155 | soc_is_ar933x() || | ||
| 156 | soc_is_ar934x() || | ||
| 157 | soc_is_qca955x()) | ||
| 158 | misc_is_ar71xx = false; | ||
| 159 | else | ||
| 160 | BUG(); | ||
| 161 | ath79_misc_irq_init( | ||
| 162 | ath79_reset_base + AR71XX_RESET_REG_MISC_INT_STATUS, | ||
| 163 | ATH79_CPU_IRQ(6), ATH79_MISC_IRQ_BASE, misc_is_ar71xx); | ||
| 164 | |||
| 165 | if (soc_is_ar934x()) | ||
| 166 | ar934x_ip2_irq_init(); | ||
| 167 | else if (soc_is_qca955x()) | ||
| 168 | qca955x_irq_init(); | ||
| 169 | } | ||
diff --git a/arch/mips/ath79/mach-ap121.c b/arch/mips/ath79/mach-ap121.c deleted file mode 100644 index 1bf73f2a069d..000000000000 --- a/arch/mips/ath79/mach-ap121.c +++ /dev/null | |||
| @@ -1,92 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Atheros AP121 board support | ||
| 3 | * | ||
| 4 | * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||
| 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 version 2 as published | ||
| 8 | * by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include "machtypes.h" | ||
| 12 | #include "dev-gpio-buttons.h" | ||
| 13 | #include "dev-leds-gpio.h" | ||
| 14 | #include "dev-spi.h" | ||
| 15 | #include "dev-usb.h" | ||
| 16 | #include "dev-wmac.h" | ||
| 17 | |||
| 18 | #define AP121_GPIO_LED_WLAN 0 | ||
| 19 | #define AP121_GPIO_LED_USB 1 | ||
| 20 | |||
| 21 | #define AP121_GPIO_BTN_JUMPSTART 11 | ||
| 22 | #define AP121_GPIO_BTN_RESET 12 | ||
| 23 | |||
| 24 | #define AP121_KEYS_POLL_INTERVAL 20 /* msecs */ | ||
| 25 | #define AP121_KEYS_DEBOUNCE_INTERVAL (3 * AP121_KEYS_POLL_INTERVAL) | ||
| 26 | |||
| 27 | #define AP121_CAL_DATA_ADDR 0x1fff1000 | ||
| 28 | |||
| 29 | static struct gpio_led ap121_leds_gpio[] __initdata = { | ||
| 30 | { | ||
| 31 | .name = "ap121:green:usb", | ||
| 32 | .gpio = AP121_GPIO_LED_USB, | ||
| 33 | .active_low = 0, | ||
| 34 | }, | ||
| 35 | { | ||
| 36 | .name = "ap121:green:wlan", | ||
| 37 | .gpio = AP121_GPIO_LED_WLAN, | ||
| 38 | .active_low = 0, | ||
| 39 | }, | ||
| 40 | }; | ||
| 41 | |||
| 42 | static struct gpio_keys_button ap121_gpio_keys[] __initdata = { | ||
| 43 | { | ||
| 44 | .desc = "jumpstart button", | ||
| 45 | .type = EV_KEY, | ||
| 46 | .code = KEY_WPS_BUTTON, | ||
| 47 | .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL, | ||
| 48 | .gpio = AP121_GPIO_BTN_JUMPSTART, | ||
| 49 | .active_low = 1, | ||
| 50 | }, | ||
| 51 | { | ||
| 52 | .desc = "reset button", | ||
| 53 | .type = EV_KEY, | ||
| 54 | .code = KEY_RESTART, | ||
| 55 | .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL, | ||
| 56 | .gpio = AP121_GPIO_BTN_RESET, | ||
| 57 | .active_low = 1, | ||
| 58 | } | ||
| 59 | }; | ||
| 60 | |||
| 61 | static struct spi_board_info ap121_spi_info[] = { | ||
| 62 | { | ||
| 63 | .bus_num = 0, | ||
| 64 | .chip_select = 0, | ||
| 65 | .max_speed_hz = 25000000, | ||
| 66 | .modalias = "mx25l1606e", | ||
| 67 | } | ||
| 68 | }; | ||
| 69 | |||
| 70 | static struct ath79_spi_platform_data ap121_spi_data = { | ||
| 71 | .bus_num = 0, | ||
| 72 | .num_chipselect = 1, | ||
| 73 | }; | ||
| 74 | |||
| 75 | static void __init ap121_setup(void) | ||
| 76 | { | ||
| 77 | u8 *cal_data = (u8 *) KSEG1ADDR(AP121_CAL_DATA_ADDR); | ||
| 78 | |||
| 79 | ath79_register_leds_gpio(-1, ARRAY_SIZE(ap121_leds_gpio), | ||
| 80 | ap121_leds_gpio); | ||
| 81 | ath79_register_gpio_keys_polled(-1, AP121_KEYS_POLL_INTERVAL, | ||
| 82 | ARRAY_SIZE(ap121_gpio_keys), | ||
| 83 | ap121_gpio_keys); | ||
| 84 | |||
| 85 | ath79_register_spi(&ap121_spi_data, ap121_spi_info, | ||
| 86 | ARRAY_SIZE(ap121_spi_info)); | ||
| 87 | ath79_register_usb(); | ||
| 88 | ath79_register_wmac(cal_data); | ||
| 89 | } | ||
| 90 | |||
| 91 | MIPS_MACHINE(ATH79_MACH_AP121, "AP121", "Atheros AP121 reference board", | ||
| 92 | ap121_setup); | ||
diff --git a/arch/mips/ath79/mach-ap136.c b/arch/mips/ath79/mach-ap136.c deleted file mode 100644 index 07eac58c3641..000000000000 --- a/arch/mips/ath79/mach-ap136.c +++ /dev/null | |||
| @@ -1,156 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Qualcomm Atheros AP136 reference board support | ||
| 3 | * | ||
| 4 | * Copyright (c) 2012 Qualcomm Atheros | ||
| 5 | * Copyright (c) 2012-2013 Gabor Juhos <juhosg@openwrt.org> | ||
| 6 | * | ||
| 7 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 8 | * purpose with or without fee is hereby granted, provided that the above | ||
| 9 | * copyright notice and this permission notice appear in all copies. | ||
| 10 | * | ||
| 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 18 | * | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/pci.h> | ||
| 22 | #include <linux/ath9k_platform.h> | ||
| 23 | |||
| 24 | #include "machtypes.h" | ||
| 25 | #include "dev-gpio-buttons.h" | ||
| 26 | #include "dev-leds-gpio.h" | ||
| 27 | #include "dev-spi.h" | ||
| 28 | #include "dev-usb.h" | ||
| 29 | #include "dev-wmac.h" | ||
| 30 | #include "pci.h" | ||
| 31 | |||
| 32 | #define AP136_GPIO_LED_STATUS_RED 14 | ||
| 33 | #define AP136_GPIO_LED_STATUS_GREEN 19 | ||
| 34 | #define AP136_GPIO_LED_USB 4 | ||
| 35 | #define AP136_GPIO_LED_WLAN_2G 13 | ||
| 36 | #define AP136_GPIO_LED_WLAN_5G 12 | ||
| 37 | #define AP136_GPIO_LED_WPS_RED 15 | ||
| 38 | #define AP136_GPIO_LED_WPS_GREEN 20 | ||
| 39 | |||
| 40 | #define AP136_GPIO_BTN_WPS 16 | ||
| 41 | #define AP136_GPIO_BTN_RFKILL 21 | ||
| 42 | |||
| 43 | #define AP136_KEYS_POLL_INTERVAL 20 /* msecs */ | ||
| 44 | #define AP136_KEYS_DEBOUNCE_INTERVAL (3 * AP136_KEYS_POLL_INTERVAL) | ||
| 45 | |||
| 46 | #define AP136_WMAC_CALDATA_OFFSET 0x1000 | ||
| 47 | #define AP136_PCIE_CALDATA_OFFSET 0x5000 | ||
| 48 | |||
| 49 | static struct gpio_led ap136_leds_gpio[] __initdata = { | ||
| 50 | { | ||
| 51 | .name = "qca:green:status", | ||
| 52 | .gpio = AP136_GPIO_LED_STATUS_GREEN, | ||
| 53 | .active_low = 1, | ||
| 54 | }, | ||
| 55 | { | ||
| 56 | .name = "qca:red:status", | ||
| 57 | .gpio = AP136_GPIO_LED_STATUS_RED, | ||
| 58 | .active_low = 1, | ||
| 59 | }, | ||
| 60 | { | ||
| 61 | .name = "qca:green:wps", | ||
| 62 | .gpio = AP136_GPIO_LED_WPS_GREEN, | ||
| 63 | .active_low = 1, | ||
| 64 | }, | ||
| 65 | { | ||
| 66 | .name = "qca:red:wps", | ||
| 67 | .gpio = AP136_GPIO_LED_WPS_RED, | ||
| 68 | .active_low = 1, | ||
| 69 | }, | ||
| 70 | { | ||
| 71 | .name = "qca:red:wlan-2g", | ||
| 72 | .gpio = AP136_GPIO_LED_WLAN_2G, | ||
| 73 | .active_low = 1, | ||
| 74 | }, | ||
| 75 | { | ||
| 76 | .name = "qca:red:usb", | ||
| 77 | .gpio = AP136_GPIO_LED_USB, | ||
| 78 | .active_low = 1, | ||
| 79 | } | ||
| 80 | }; | ||
| 81 | |||
| 82 | static struct gpio_keys_button ap136_gpio_keys[] __initdata = { | ||
| 83 | { | ||
| 84 | .desc = "WPS button", | ||
| 85 | .type = EV_KEY, | ||
| 86 | .code = KEY_WPS_BUTTON, | ||
| 87 | .debounce_interval = AP136_KEYS_DEBOUNCE_INTERVAL, | ||
| 88 | .gpio = AP136_GPIO_BTN_WPS, | ||
| 89 | .active_low = 1, | ||
| 90 | }, | ||
| 91 | { | ||
| 92 | .desc = "RFKILL button", | ||
| 93 | .type = EV_KEY, | ||
| 94 | .code = KEY_RFKILL, | ||
| 95 | .debounce_interval = AP136_KEYS_DEBOUNCE_INTERVAL, | ||
| 96 | .gpio = AP136_GPIO_BTN_RFKILL, | ||
| 97 | .active_low = 1, | ||
| 98 | }, | ||
| 99 | }; | ||
| 100 | |||
| 101 | static struct spi_board_info ap136_spi_info[] = { | ||
| 102 | { | ||
| 103 | .bus_num = 0, | ||
| 104 | .chip_select = 0, | ||
| 105 | .max_speed_hz = 25000000, | ||
| 106 | .modalias = "mx25l6405d", | ||
| 107 | } | ||
| 108 | }; | ||
| 109 | |||
| 110 | static struct ath79_spi_platform_data ap136_spi_data = { | ||
| 111 | .bus_num = 0, | ||
| 112 | .num_chipselect = 1, | ||
| 113 | }; | ||
| 114 | |||
| 115 | #ifdef CONFIG_PCI | ||
| 116 | static struct ath9k_platform_data ap136_ath9k_data; | ||
| 117 | |||
| 118 | static int ap136_pci_plat_dev_init(struct pci_dev *dev) | ||
| 119 | { | ||
| 120 | if (dev->bus->number == 1 && (PCI_SLOT(dev->devfn)) == 0) | ||
| 121 | dev->dev.platform_data = &ap136_ath9k_data; | ||
| 122 | |||
| 123 | return 0; | ||
| 124 | } | ||
| 125 | |||
| 126 | static void __init ap136_pci_init(u8 *eeprom) | ||
| 127 | { | ||
| 128 | memcpy(ap136_ath9k_data.eeprom_data, eeprom, | ||
| 129 | sizeof(ap136_ath9k_data.eeprom_data)); | ||
| 130 | |||
| 131 | ath79_pci_set_plat_dev_init(ap136_pci_plat_dev_init); | ||
| 132 | ath79_register_pci(); | ||
| 133 | } | ||
| 134 | #else | ||
| 135 | static inline void ap136_pci_init(u8 *eeprom) {} | ||
| 136 | #endif /* CONFIG_PCI */ | ||
| 137 | |||
| 138 | static void __init ap136_setup(void) | ||
| 139 | { | ||
| 140 | u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); | ||
| 141 | |||
| 142 | ath79_register_leds_gpio(-1, ARRAY_SIZE(ap136_leds_gpio), | ||
| 143 | ap136_leds_gpio); | ||
| 144 | ath79_register_gpio_keys_polled(-1, AP136_KEYS_POLL_INTERVAL, | ||
| 145 | ARRAY_SIZE(ap136_gpio_keys), | ||
| 146 | ap136_gpio_keys); | ||
| 147 | ath79_register_spi(&ap136_spi_data, ap136_spi_info, | ||
| 148 | ARRAY_SIZE(ap136_spi_info)); | ||
| 149 | ath79_register_usb(); | ||
| 150 | ath79_register_wmac(art + AP136_WMAC_CALDATA_OFFSET); | ||
| 151 | ap136_pci_init(art + AP136_PCIE_CALDATA_OFFSET); | ||
| 152 | } | ||
| 153 | |||
| 154 | MIPS_MACHINE(ATH79_MACH_AP136_010, "AP136-010", | ||
| 155 | "Atheros AP136-010 reference board", | ||
| 156 | ap136_setup); | ||
diff --git a/arch/mips/ath79/mach-ap81.c b/arch/mips/ath79/mach-ap81.c deleted file mode 100644 index 1c78d497f930..000000000000 --- a/arch/mips/ath79/mach-ap81.c +++ /dev/null | |||
| @@ -1,100 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Atheros AP81 board support | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org> | ||
| 5 | * Copyright (C) 2009 Imre Kaloz <kaloz@openwrt.org> | ||
| 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 version 2 as published | ||
| 9 | * by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include "machtypes.h" | ||
| 13 | #include "dev-wmac.h" | ||
| 14 | #include "dev-gpio-buttons.h" | ||
| 15 | #include "dev-leds-gpio.h" | ||
| 16 | #include "dev-spi.h" | ||
| 17 | #include "dev-usb.h" | ||
| 18 | |||
| 19 | #define AP81_GPIO_LED_STATUS 1 | ||
| 20 | #define AP81_GPIO_LED_AOSS 3 | ||
| 21 | #define AP81_GPIO_LED_WLAN 6 | ||
| 22 | #define AP81_GPIO_LED_POWER 14 | ||
| 23 | |||
| 24 | #define AP81_GPIO_BTN_SW4 12 | ||
| 25 | #define AP81_GPIO_BTN_SW1 21 | ||
| 26 | |||
| 27 | #define AP81_KEYS_POLL_INTERVAL 20 /* msecs */ | ||
| 28 | #define AP81_KEYS_DEBOUNCE_INTERVAL (3 * AP81_KEYS_POLL_INTERVAL) | ||
| 29 | |||
| 30 | #define AP81_CAL_DATA_ADDR 0x1fff1000 | ||
| 31 | |||
| 32 | static struct gpio_led ap81_leds_gpio[] __initdata = { | ||
| 33 | { | ||
| 34 | .name = "ap81:green:status", | ||
| 35 | .gpio = AP81_GPIO_LED_STATUS, | ||
| 36 | .active_low = 1, | ||
| 37 | }, { | ||
| 38 | .name = "ap81:amber:aoss", | ||
| 39 | .gpio = AP81_GPIO_LED_AOSS, | ||
| 40 | .active_low = 1, | ||
| 41 | }, { | ||
| 42 | .name = "ap81:green:wlan", | ||
| 43 | .gpio = AP81_GPIO_LED_WLAN, | ||
| 44 | .active_low = 1, | ||
| 45 | }, { | ||
| 46 | .name = "ap81:green:power", | ||
| 47 | .gpio = AP81_GPIO_LED_POWER, | ||
| 48 | .active_low = 1, | ||
| 49 | } | ||
| 50 | }; | ||
| 51 | |||
| 52 | static struct gpio_keys_button ap81_gpio_keys[] __initdata = { | ||
| 53 | { | ||
| 54 | .desc = "sw1", | ||
| 55 | .type = EV_KEY, | ||
| 56 | .code = BTN_0, | ||
| 57 | .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL, | ||
| 58 | .gpio = AP81_GPIO_BTN_SW1, | ||
| 59 | .active_low = 1, | ||
| 60 | } , { | ||
| 61 | .desc = "sw4", | ||
| 62 | .type = EV_KEY, | ||
| 63 | .code = BTN_1, | ||
| 64 | .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL, | ||
| 65 | .gpio = AP81_GPIO_BTN_SW4, | ||
| 66 | .active_low = 1, | ||
| 67 | } | ||
| 68 | }; | ||
| 69 | |||
| 70 | static struct spi_board_info ap81_spi_info[] = { | ||
| 71 | { | ||
| 72 | .bus_num = 0, | ||
| 73 | .chip_select = 0, | ||
| 74 | .max_speed_hz = 25000000, | ||
| 75 | .modalias = "m25p64", | ||
| 76 | } | ||
| 77 | }; | ||
| 78 | |||
| 79 | static struct ath79_spi_platform_data ap81_spi_data = { | ||
| 80 | .bus_num = 0, | ||
| 81 | .num_chipselect = 1, | ||
| 82 | }; | ||
| 83 | |||
| 84 | static void __init ap81_setup(void) | ||
| 85 | { | ||
| 86 | u8 *cal_data = (u8 *) KSEG1ADDR(AP81_CAL_DATA_ADDR); | ||
| 87 | |||
| 88 | ath79_register_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio), | ||
| 89 | ap81_leds_gpio); | ||
| 90 | ath79_register_gpio_keys_polled(-1, AP81_KEYS_POLL_INTERVAL, | ||
| 91 | ARRAY_SIZE(ap81_gpio_keys), | ||
| 92 | ap81_gpio_keys); | ||
| 93 | ath79_register_spi(&ap81_spi_data, ap81_spi_info, | ||
| 94 | ARRAY_SIZE(ap81_spi_info)); | ||
| 95 | ath79_register_wmac(cal_data); | ||
| 96 | ath79_register_usb(); | ||
| 97 | } | ||
| 98 | |||
| 99 | MIPS_MACHINE(ATH79_MACH_AP81, "AP81", "Atheros AP81 reference board", | ||
| 100 | ap81_setup); | ||
diff --git a/arch/mips/ath79/mach-db120.c b/arch/mips/ath79/mach-db120.c deleted file mode 100644 index 9423f5aed287..000000000000 --- a/arch/mips/ath79/mach-db120.c +++ /dev/null | |||
| @@ -1,136 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Atheros DB120 reference board support | ||
| 3 | * | ||
| 4 | * Copyright (c) 2011 Qualcomm Atheros | ||
| 5 | * Copyright (c) 2011 Gabor Juhos <juhosg@openwrt.org> | ||
| 6 | * | ||
| 7 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 8 | * purpose with or without fee is hereby granted, provided that the above | ||
| 9 | * copyright notice and this permission notice appear in all copies. | ||
| 10 | * | ||
| 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 18 | * | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/pci.h> | ||
| 22 | #include <linux/ath9k_platform.h> | ||
| 23 | |||
| 24 | #include "machtypes.h" | ||
| 25 | #include "dev-gpio-buttons.h" | ||
| 26 | #include "dev-leds-gpio.h" | ||
| 27 | #include "dev-spi.h" | ||
| 28 | #include "dev-usb.h" | ||
| 29 | #include "dev-wmac.h" | ||
| 30 | #include "pci.h" | ||
| 31 | |||
| 32 | #define DB120_GPIO_LED_WLAN_5G 12 | ||
| 33 | #define DB120_GPIO_LED_WLAN_2G 13 | ||
| 34 | #define DB120_GPIO_LED_STATUS 14 | ||
| 35 | #define DB120_GPIO_LED_WPS 15 | ||
| 36 | |||
| 37 | #define DB120_GPIO_BTN_WPS 16 | ||
| 38 | |||
| 39 | #define DB120_KEYS_POLL_INTERVAL 20 /* msecs */ | ||
| 40 | #define DB120_KEYS_DEBOUNCE_INTERVAL (3 * DB120_KEYS_POLL_INTERVAL) | ||
| 41 | |||
| 42 | #define DB120_WMAC_CALDATA_OFFSET 0x1000 | ||
| 43 | #define DB120_PCIE_CALDATA_OFFSET 0x5000 | ||
| 44 | |||
| 45 | static struct gpio_led db120_leds_gpio[] __initdata = { | ||
| 46 | { | ||
| 47 | .name = "db120:green:status", | ||
| 48 | .gpio = DB120_GPIO_LED_STATUS, | ||
| 49 | .active_low = 1, | ||
| 50 | }, | ||
| 51 | { | ||
| 52 | .name = "db120:green:wps", | ||
| 53 | .gpio = DB120_GPIO_LED_WPS, | ||
| 54 | .active_low = 1, | ||
| 55 | }, | ||
| 56 | { | ||
| 57 | .name = "db120:green:wlan-5g", | ||
| 58 | .gpio = DB120_GPIO_LED_WLAN_5G, | ||
| 59 | .active_low = 1, | ||
| 60 | }, | ||
| 61 | { | ||
| 62 | .name = "db120:green:wlan-2g", | ||
| 63 | .gpio = DB120_GPIO_LED_WLAN_2G, | ||
| 64 | .active_low = 1, | ||
| 65 | }, | ||
| 66 | }; | ||
| 67 | |||
| 68 | static struct gpio_keys_button db120_gpio_keys[] __initdata = { | ||
| 69 | { | ||
| 70 | .desc = "WPS button", | ||
| 71 | .type = EV_KEY, | ||
| 72 | .code = KEY_WPS_BUTTON, | ||
| 73 | .debounce_interval = DB120_KEYS_DEBOUNCE_INTERVAL, | ||
| 74 | .gpio = DB120_GPIO_BTN_WPS, | ||
| 75 | .active_low = 1, | ||
| 76 | }, | ||
| 77 | }; | ||
| 78 | |||
| 79 | static struct spi_board_info db120_spi_info[] = { | ||
| 80 | { | ||
| 81 | .bus_num = 0, | ||
| 82 | .chip_select = 0, | ||
| 83 | .max_speed_hz = 25000000, | ||
| 84 | .modalias = "s25sl064a", | ||
| 85 | } | ||
| 86 | }; | ||
| 87 | |||
| 88 | static struct ath79_spi_platform_data db120_spi_data = { | ||
| 89 | .bus_num = 0, | ||
| 90 | .num_chipselect = 1, | ||
| 91 | }; | ||
| 92 | |||
| 93 | #ifdef CONFIG_PCI | ||
| 94 | static struct ath9k_platform_data db120_ath9k_data; | ||
| 95 | |||
| 96 | static int db120_pci_plat_dev_init(struct pci_dev *dev) | ||
| 97 | { | ||
| 98 | switch (PCI_SLOT(dev->devfn)) { | ||
| 99 | case 0: | ||
| 100 | dev->dev.platform_data = &db120_ath9k_data; | ||
| 101 | break; | ||
| 102 | } | ||
| 103 | |||
| 104 | return 0; | ||
| 105 | } | ||
| 106 | |||
| 107 | static void __init db120_pci_init(u8 *eeprom) | ||
| 108 | { | ||
| 109 | memcpy(db120_ath9k_data.eeprom_data, eeprom, | ||
| 110 | sizeof(db120_ath9k_data.eeprom_data)); | ||
| 111 | |||
| 112 | ath79_pci_set_plat_dev_init(db120_pci_plat_dev_init); | ||
| 113 | ath79_register_pci(); | ||
| 114 | } | ||
| 115 | #else | ||
| 116 | static inline void db120_pci_init(u8 *eeprom) {} | ||
| 117 | #endif /* CONFIG_PCI */ | ||
| 118 | |||
| 119 | static void __init db120_setup(void) | ||
| 120 | { | ||
| 121 | u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); | ||
| 122 | |||
| 123 | ath79_register_leds_gpio(-1, ARRAY_SIZE(db120_leds_gpio), | ||
| 124 | db120_leds_gpio); | ||
| 125 | ath79_register_gpio_keys_polled(-1, DB120_KEYS_POLL_INTERVAL, | ||
| 126 | ARRAY_SIZE(db120_gpio_keys), | ||
| 127 | db120_gpio_keys); | ||
| 128 | ath79_register_spi(&db120_spi_data, db120_spi_info, | ||
| 129 | ARRAY_SIZE(db120_spi_info)); | ||
| 130 | ath79_register_usb(); | ||
| 131 | ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET); | ||
| 132 | db120_pci_init(art + DB120_PCIE_CALDATA_OFFSET); | ||
| 133 | } | ||
| 134 | |||
| 135 | MIPS_MACHINE(ATH79_MACH_DB120, "DB120", "Atheros DB120 reference board", | ||
| 136 | db120_setup); | ||
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c deleted file mode 100644 index 75fb96ca61db..000000000000 --- a/arch/mips/ath79/mach-pb44.c +++ /dev/null | |||
| @@ -1,128 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Atheros PB44 reference board support | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org> | ||
| 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 version 2 as published | ||
| 8 | * by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/platform_device.h> | ||
| 13 | #include <linux/i2c.h> | ||
| 14 | #include <linux/gpio/machine.h> | ||
| 15 | #include <linux/platform_data/pcf857x.h> | ||
| 16 | |||
| 17 | #include "machtypes.h" | ||
| 18 | #include "dev-gpio-buttons.h" | ||
| 19 | #include "dev-leds-gpio.h" | ||
| 20 | #include "dev-spi.h" | ||
| 21 | #include "dev-usb.h" | ||
| 22 | #include "pci.h" | ||
| 23 | |||
| 24 | #define PB44_GPIO_I2C_SCL 0 | ||
| 25 | #define PB44_GPIO_I2C_SDA 1 | ||
| 26 | |||
| 27 | #define PB44_GPIO_EXP_BASE 16 | ||
| 28 | #define PB44_GPIO_SW_RESET (PB44_GPIO_EXP_BASE + 6) | ||
| 29 | #define PB44_GPIO_SW_JUMP (PB44_GPIO_EXP_BASE + 8) | ||
| 30 | #define PB44_GPIO_LED_JUMP1 (PB44_GPIO_EXP_BASE + 9) | ||
| 31 | #define PB44_GPIO_LED_JUMP2 (PB44_GPIO_EXP_BASE + 10) | ||
| 32 | |||
| 33 | #define PB44_KEYS_POLL_INTERVAL 20 /* msecs */ | ||
| 34 | #define PB44_KEYS_DEBOUNCE_INTERVAL (3 * PB44_KEYS_POLL_INTERVAL) | ||
| 35 | |||
| 36 | static struct gpiod_lookup_table pb44_i2c_gpiod_table = { | ||
| 37 | .dev_id = "i2c-gpio.0", | ||
| 38 | .table = { | ||
| 39 | GPIO_LOOKUP_IDX("ath79-gpio", PB44_GPIO_I2C_SDA, | ||
| 40 | NULL, 0, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), | ||
| 41 | GPIO_LOOKUP_IDX("ath79-gpio", PB44_GPIO_I2C_SCL, | ||
| 42 | NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN), | ||
| 43 | }, | ||
| 44 | }; | ||
| 45 | |||
| 46 | static struct platform_device pb44_i2c_gpio_device = { | ||
| 47 | .name = "i2c-gpio", | ||
| 48 | .id = 0, | ||
| 49 | .dev = { | ||
| 50 | .platform_data = NULL, | ||
| 51 | } | ||
| 52 | }; | ||
| 53 | |||
| 54 | static struct pcf857x_platform_data pb44_pcf857x_data = { | ||
| 55 | .gpio_base = PB44_GPIO_EXP_BASE, | ||
| 56 | }; | ||
| 57 | |||
| 58 | static struct i2c_board_info pb44_i2c_board_info[] __initdata = { | ||
| 59 | { | ||
| 60 | I2C_BOARD_INFO("pcf8575", 0x20), | ||
| 61 | .platform_data = &pb44_pcf857x_data, | ||
| 62 | }, | ||
| 63 | }; | ||
| 64 | |||
| 65 | static struct gpio_led pb44_leds_gpio[] __initdata = { | ||
| 66 | { | ||
| 67 | .name = "pb44:amber:jump1", | ||
| 68 | .gpio = PB44_GPIO_LED_JUMP1, | ||
| 69 | .active_low = 1, | ||
| 70 | }, { | ||
| 71 | .name = "pb44:green:jump2", | ||
| 72 | .gpio = PB44_GPIO_LED_JUMP2, | ||
| 73 | .active_low = 1, | ||
| 74 | }, | ||
| 75 | }; | ||
| 76 | |||
| 77 | static struct gpio_keys_button pb44_gpio_keys[] __initdata = { | ||
| 78 | { | ||
| 79 | .desc = "soft_reset", | ||
| 80 | .type = EV_KEY, | ||
| 81 | .code = KEY_RESTART, | ||
| 82 | .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL, | ||
| 83 | .gpio = PB44_GPIO_SW_RESET, | ||
| 84 | .active_low = 1, | ||
| 85 | } , { | ||
| 86 | .desc = "jumpstart", | ||
| 87 | .type = EV_KEY, | ||
| 88 | .code = KEY_WPS_BUTTON, | ||
| 89 | .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL, | ||
| 90 | .gpio = PB44_GPIO_SW_JUMP, | ||
| 91 | .active_low = 1, | ||
| 92 | } | ||
| 93 | }; | ||
| 94 | |||
| 95 | static struct spi_board_info pb44_spi_info[] = { | ||
| 96 | { | ||
| 97 | .bus_num = 0, | ||
| 98 | .chip_select = 0, | ||
| 99 | .max_speed_hz = 25000000, | ||
| 100 | .modalias = "m25p64", | ||
| 101 | }, | ||
| 102 | }; | ||
| 103 | |||
| 104 | static struct ath79_spi_platform_data pb44_spi_data = { | ||
| 105 | .bus_num = 0, | ||
| 106 | .num_chipselect = 1, | ||
| 107 | }; | ||
| 108 | |||
| 109 | static void __init pb44_init(void) | ||
| 110 | { | ||
| 111 | gpiod_add_lookup_table(&pb44_i2c_gpiod_table); | ||
| 112 | i2c_register_board_info(0, pb44_i2c_board_info, | ||
| 113 | ARRAY_SIZE(pb44_i2c_board_info)); | ||
| 114 | platform_device_register(&pb44_i2c_gpio_device); | ||
| 115 | |||
| 116 | ath79_register_leds_gpio(-1, ARRAY_SIZE(pb44_leds_gpio), | ||
| 117 | pb44_leds_gpio); | ||
| 118 | ath79_register_gpio_keys_polled(-1, PB44_KEYS_POLL_INTERVAL, | ||
| 119 | ARRAY_SIZE(pb44_gpio_keys), | ||
| 120 | pb44_gpio_keys); | ||
| 121 | ath79_register_spi(&pb44_spi_data, pb44_spi_info, | ||
| 122 | ARRAY_SIZE(pb44_spi_info)); | ||
| 123 | ath79_register_usb(); | ||
| 124 | ath79_register_pci(); | ||
| 125 | } | ||
| 126 | |||
| 127 | MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board", | ||
| 128 | pb44_init); | ||
diff --git a/arch/mips/ath79/mach-ubnt-xm.c b/arch/mips/ath79/mach-ubnt-xm.c deleted file mode 100644 index 4a3c60694c75..000000000000 --- a/arch/mips/ath79/mach-ubnt-xm.c +++ /dev/null | |||
| @@ -1,126 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Ubiquiti Networks XM (rev 1.0) board support | ||
| 3 | * | ||
| 4 | * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com> | ||
| 5 | * | ||
| 6 | * Derived from: mach-pb44.c | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License version 2 as published | ||
| 10 | * by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/pci.h> | ||
| 15 | #include <linux/ath9k_platform.h> | ||
| 16 | |||
| 17 | #include <asm/mach-ath79/irq.h> | ||
| 18 | |||
| 19 | #include "machtypes.h" | ||
| 20 | #include "dev-gpio-buttons.h" | ||
| 21 | #include "dev-leds-gpio.h" | ||
| 22 | #include "dev-spi.h" | ||
| 23 | #include "pci.h" | ||
| 24 | |||
| 25 | #define UBNT_XM_GPIO_LED_L1 0 | ||
| 26 | #define UBNT_XM_GPIO_LED_L2 1 | ||
| 27 | #define UBNT_XM_GPIO_LED_L3 11 | ||
| 28 | #define UBNT_XM_GPIO_LED_L4 7 | ||
| 29 | |||
| 30 | #define UBNT_XM_GPIO_BTN_RESET 12 | ||
| 31 | |||
| 32 | #define UBNT_XM_KEYS_POLL_INTERVAL 20 | ||
| 33 | #define UBNT_XM_KEYS_DEBOUNCE_INTERVAL (3 * UBNT_XM_KEYS_POLL_INTERVAL) | ||
| 34 | |||
| 35 | #define UBNT_XM_EEPROM_ADDR (u8 *) KSEG1ADDR(0x1fff1000) | ||
| 36 | |||
| 37 | static struct gpio_led ubnt_xm_leds_gpio[] __initdata = { | ||
| 38 | { | ||
| 39 | .name = "ubnt-xm:red:link1", | ||
| 40 | .gpio = UBNT_XM_GPIO_LED_L1, | ||
| 41 | .active_low = 0, | ||
| 42 | }, { | ||
| 43 | .name = "ubnt-xm:orange:link2", | ||
| 44 | .gpio = UBNT_XM_GPIO_LED_L2, | ||
| 45 | .active_low = 0, | ||
| 46 | }, { | ||
| 47 | .name = "ubnt-xm:green:link3", | ||
| 48 | .gpio = UBNT_XM_GPIO_LED_L3, | ||
| 49 | .active_low = 0, | ||
| 50 | }, { | ||
| 51 | .name = "ubnt-xm:green:link4", | ||
| 52 | .gpio = UBNT_XM_GPIO_LED_L4, | ||
| 53 | .active_low = 0, | ||
| 54 | }, | ||
| 55 | }; | ||
| 56 | |||
| 57 | static struct gpio_keys_button ubnt_xm_gpio_keys[] __initdata = { | ||
| 58 | { | ||
| 59 | .desc = "reset", | ||
| 60 | .type = EV_KEY, | ||
| 61 | .code = KEY_RESTART, | ||
| 62 | .debounce_interval = UBNT_XM_KEYS_DEBOUNCE_INTERVAL, | ||
| 63 | .gpio = UBNT_XM_GPIO_BTN_RESET, | ||
| 64 | .active_low = 1, | ||
| 65 | } | ||
| 66 | }; | ||
| 67 | |||
| 68 | static struct spi_board_info ubnt_xm_spi_info[] = { | ||
| 69 | { | ||
| 70 | .bus_num = 0, | ||
| 71 | .chip_select = 0, | ||
| 72 | .max_speed_hz = 25000000, | ||
| 73 | .modalias = "mx25l6405d", | ||
| 74 | } | ||
| 75 | }; | ||
| 76 | |||
| 77 | static struct ath79_spi_platform_data ubnt_xm_spi_data = { | ||
| 78 | .bus_num = 0, | ||
| 79 | .num_chipselect = 1, | ||
| 80 | }; | ||
| 81 | |||
| 82 | #ifdef CONFIG_PCI | ||
| 83 | static struct ath9k_platform_data ubnt_xm_eeprom_data; | ||
| 84 | |||
| 85 | static int ubnt_xm_pci_plat_dev_init(struct pci_dev *dev) | ||
| 86 | { | ||
| 87 | switch (PCI_SLOT(dev->devfn)) { | ||
| 88 | case 0: | ||
| 89 | dev->dev.platform_data = &ubnt_xm_eeprom_data; | ||
| 90 | break; | ||
| 91 | } | ||
| 92 | |||
| 93 | return 0; | ||
| 94 | } | ||
| 95 | |||
| 96 | static void __init ubnt_xm_pci_init(void) | ||
| 97 | { | ||
| 98 | memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR, | ||
| 99 | sizeof(ubnt_xm_eeprom_data.eeprom_data)); | ||
| 100 | |||
| 101 | ath79_pci_set_plat_dev_init(ubnt_xm_pci_plat_dev_init); | ||
| 102 | ath79_register_pci(); | ||
| 103 | } | ||
| 104 | #else | ||
| 105 | static inline void ubnt_xm_pci_init(void) {} | ||
| 106 | #endif /* CONFIG_PCI */ | ||
| 107 | |||
| 108 | static void __init ubnt_xm_init(void) | ||
| 109 | { | ||
| 110 | ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_xm_leds_gpio), | ||
| 111 | ubnt_xm_leds_gpio); | ||
| 112 | |||
| 113 | ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL, | ||
| 114 | ARRAY_SIZE(ubnt_xm_gpio_keys), | ||
| 115 | ubnt_xm_gpio_keys); | ||
| 116 | |||
| 117 | ath79_register_spi(&ubnt_xm_spi_data, ubnt_xm_spi_info, | ||
| 118 | ARRAY_SIZE(ubnt_xm_spi_info)); | ||
| 119 | |||
| 120 | ubnt_xm_pci_init(); | ||
| 121 | } | ||
| 122 | |||
| 123 | MIPS_MACHINE(ATH79_MACH_UBNT_XM, | ||
| 124 | "UBNT-XM", | ||
| 125 | "Ubiquiti Networks XM (rev 1.0) board", | ||
| 126 | ubnt_xm_init); | ||
diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h deleted file mode 100644 index a13db3d15c8f..000000000000 --- a/arch/mips/ath79/machtypes.h +++ /dev/null | |||
| @@ -1,28 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Atheros AR71XX/AR724X/AR913X machine type definitions | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
| 5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
| 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 version 2 as published | ||
| 9 | * by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #ifndef _ATH79_MACHTYPE_H | ||
| 13 | #define _ATH79_MACHTYPE_H | ||
| 14 | |||
| 15 | #include <asm/mips_machine.h> | ||
| 16 | |||
| 17 | enum ath79_mach_type { | ||
| 18 | ATH79_MACH_GENERIC_OF = -1, /* Device tree board */ | ||
| 19 | ATH79_MACH_GENERIC = 0, | ||
| 20 | ATH79_MACH_AP121, /* Atheros AP121 reference board */ | ||
| 21 | ATH79_MACH_AP136_010, /* Atheros AP136-010 reference board */ | ||
| 22 | ATH79_MACH_AP81, /* Atheros AP81 reference board */ | ||
| 23 | ATH79_MACH_DB120, /* Atheros DB120 reference board */ | ||
| 24 | ATH79_MACH_PB44, /* Atheros PB44 reference board */ | ||
| 25 | ATH79_MACH_UBNT_XM, /* Ubiquiti Networks XM board rev 1.0 */ | ||
| 26 | }; | ||
| 27 | |||
| 28 | #endif /* _ATH79_MACHTYPE_H */ | ||
diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c deleted file mode 100644 index b816cb4a25ff..000000000000 --- a/arch/mips/ath79/pci.c +++ /dev/null | |||
| @@ -1,273 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Atheros AR71XX/AR724X specific PCI setup code | ||
| 3 | * | ||
| 4 | * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com> | ||
| 5 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
| 6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
| 7 | * | ||
| 8 | * Parts of this file are based on Atheros' 2.6.15 BSP | ||
| 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 | #include <linux/init.h> | ||
| 16 | #include <linux/pci.h> | ||
| 17 | #include <linux/resource.h> | ||
| 18 | #include <linux/platform_device.h> | ||
| 19 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
| 20 | #include <asm/mach-ath79/ath79.h> | ||
| 21 | #include <asm/mach-ath79/irq.h> | ||
| 22 | #include "pci.h" | ||
| 23 | |||
| 24 | static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev); | ||
| 25 | static const struct ath79_pci_irq *ath79_pci_irq_map; | ||
| 26 | static unsigned ath79_pci_nr_irqs; | ||
| 27 | |||
| 28 | static const struct ath79_pci_irq ar71xx_pci_irq_map[] = { | ||
| 29 | { | ||
| 30 | .slot = 17, | ||
| 31 | .pin = 1, | ||
| 32 | .irq = ATH79_PCI_IRQ(0), | ||
| 33 | }, { | ||
| 34 | .slot = 18, | ||
| 35 | .pin = 1, | ||
| 36 | .irq = ATH79_PCI_IRQ(1), | ||
| 37 | }, { | ||
| 38 | .slot = 19, | ||
| 39 | .pin = 1, | ||
| 40 | .irq = ATH79_PCI_IRQ(2), | ||
| 41 | } | ||
| 42 | }; | ||
| 43 | |||
| 44 | static const struct ath79_pci_irq ar724x_pci_irq_map[] = { | ||
| 45 | { | ||
| 46 | .slot = 0, | ||
| 47 | .pin = 1, | ||
| 48 | .irq = ATH79_PCI_IRQ(0), | ||
| 49 | } | ||
| 50 | }; | ||
| 51 | |||
| 52 | static const struct ath79_pci_irq qca955x_pci_irq_map[] = { | ||
| 53 | { | ||
| 54 | .bus = 0, | ||
| 55 | .slot = 0, | ||
| 56 | .pin = 1, | ||
| 57 | .irq = ATH79_PCI_IRQ(0), | ||
| 58 | }, | ||
| 59 | { | ||
| 60 | .bus = 1, | ||
| 61 | .slot = 0, | ||
| 62 | .pin = 1, | ||
| 63 | .irq = ATH79_PCI_IRQ(1), | ||
| 64 | }, | ||
| 65 | }; | ||
| 66 | |||
| 67 | int pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) | ||
| 68 | { | ||
| 69 | int irq = -1; | ||
| 70 | int i; | ||
| 71 | |||
| 72 | if (ath79_pci_nr_irqs == 0 || | ||
| 73 | ath79_pci_irq_map == NULL) { | ||
| 74 | if (soc_is_ar71xx()) { | ||
| 75 | ath79_pci_irq_map = ar71xx_pci_irq_map; | ||
| 76 | ath79_pci_nr_irqs = ARRAY_SIZE(ar71xx_pci_irq_map); | ||
| 77 | } else if (soc_is_ar724x() || | ||
| 78 | soc_is_ar9342() || | ||
| 79 | soc_is_ar9344()) { | ||
| 80 | ath79_pci_irq_map = ar724x_pci_irq_map; | ||
| 81 | ath79_pci_nr_irqs = ARRAY_SIZE(ar724x_pci_irq_map); | ||
| 82 | } else if (soc_is_qca955x()) { | ||
| 83 | ath79_pci_irq_map = qca955x_pci_irq_map; | ||
| 84 | ath79_pci_nr_irqs = ARRAY_SIZE(qca955x_pci_irq_map); | ||
| 85 | } else { | ||
| 86 | pr_crit("pci %s: invalid irq map\n", | ||
| 87 | pci_name((struct pci_dev *) dev)); | ||
| 88 | return irq; | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 92 | for (i = 0; i < ath79_pci_nr_irqs; i++) { | ||
| 93 | const struct ath79_pci_irq *entry; | ||
| 94 | |||
| 95 | entry = &ath79_pci_irq_map[i]; | ||
| 96 | if (entry->bus == dev->bus->number && | ||
| 97 | entry->slot == slot && | ||
| 98 | entry->pin == pin) { | ||
| 99 | irq = entry->irq; | ||
| 100 | break; | ||
| 101 | } | ||
| 102 | } | ||
| 103 | |||
| 104 | if (irq < 0) | ||
| 105 | pr_crit("pci %s: no irq found for pin %u\n", | ||
| 106 | pci_name((struct pci_dev *) dev), pin); | ||
| 107 | else | ||
| 108 | pr_info("pci %s: using irq %d for pin %u\n", | ||
| 109 | pci_name((struct pci_dev *) dev), irq, pin); | ||
| 110 | |||
| 111 | return irq; | ||
| 112 | } | ||
| 113 | |||
| 114 | int pcibios_plat_dev_init(struct pci_dev *dev) | ||
| 115 | { | ||
| 116 | if (ath79_pci_plat_dev_init) | ||
| 117 | return ath79_pci_plat_dev_init(dev); | ||
| 118 | |||
| 119 | return 0; | ||
| 120 | } | ||
| 121 | |||
| 122 | void __init ath79_pci_set_irq_map(unsigned nr_irqs, | ||
| 123 | const struct ath79_pci_irq *map) | ||
| 124 | { | ||
| 125 | ath79_pci_nr_irqs = nr_irqs; | ||
| 126 | ath79_pci_irq_map = map; | ||
| 127 | } | ||
| 128 | |||
| 129 | void __init ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev)) | ||
| 130 | { | ||
| 131 | ath79_pci_plat_dev_init = func; | ||
| 132 | } | ||
| 133 | |||
| 134 | static struct platform_device * | ||
| 135 | ath79_register_pci_ar71xx(void) | ||
| 136 | { | ||
| 137 | struct platform_device *pdev; | ||
| 138 | struct resource res[4]; | ||
| 139 | |||
| 140 | memset(res, 0, sizeof(res)); | ||
| 141 | |||
| 142 | res[0].name = "cfg_base"; | ||
| 143 | res[0].flags = IORESOURCE_MEM; | ||
| 144 | res[0].start = AR71XX_PCI_CFG_BASE; | ||
| 145 | res[0].end = AR71XX_PCI_CFG_BASE + AR71XX_PCI_CFG_SIZE - 1; | ||
| 146 | |||
| 147 | res[1].flags = IORESOURCE_IRQ; | ||
| 148 | res[1].start = ATH79_CPU_IRQ(2); | ||
| 149 | res[1].end = ATH79_CPU_IRQ(2); | ||
| 150 | |||
| 151 | res[2].name = "io_base"; | ||
| 152 | res[2].flags = IORESOURCE_IO; | ||
| 153 | res[2].start = 0; | ||
| 154 | res[2].end = 0; | ||
| 155 | |||
| 156 | res[3].name = "mem_base"; | ||
| 157 | res[3].flags = IORESOURCE_MEM; | ||
| 158 | res[3].start = AR71XX_PCI_MEM_BASE; | ||
| 159 | res[3].end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1; | ||
| 160 | |||
| 161 | pdev = platform_device_register_simple("ar71xx-pci", -1, | ||
| 162 | res, ARRAY_SIZE(res)); | ||
| 163 | return pdev; | ||
| 164 | } | ||
| 165 | |||
| 166 | static struct platform_device * | ||
| 167 | ath79_register_pci_ar724x(int id, | ||
| 168 | unsigned long cfg_base, | ||
| 169 | unsigned long ctrl_base, | ||
| 170 | unsigned long crp_base, | ||
| 171 | unsigned long mem_base, | ||
| 172 | unsigned long mem_size, | ||
| 173 | unsigned long io_base, | ||
| 174 | int irq) | ||
| 175 | { | ||
| 176 | struct platform_device *pdev; | ||
| 177 | struct resource res[6]; | ||
| 178 | |||
| 179 | memset(res, 0, sizeof(res)); | ||
| 180 | |||
| 181 | res[0].name = "cfg_base"; | ||
| 182 | res[0].flags = IORESOURCE_MEM; | ||
| 183 | res[0].start = cfg_base; | ||
| 184 | res[0].end = cfg_base + AR724X_PCI_CFG_SIZE - 1; | ||
| 185 | |||
| 186 | res[1].name = "ctrl_base"; | ||
| 187 | res[1].flags = IORESOURCE_MEM; | ||
| 188 | res[1].start = ctrl_base; | ||
| 189 | res[1].end = ctrl_base + AR724X_PCI_CTRL_SIZE - 1; | ||
| 190 | |||
| 191 | res[2].flags = IORESOURCE_IRQ; | ||
| 192 | res[2].start = irq; | ||
| 193 | res[2].end = irq; | ||
| 194 | |||
| 195 | res[3].name = "mem_base"; | ||
| 196 | res[3].flags = IORESOURCE_MEM; | ||
| 197 | res[3].start = mem_base; | ||
| 198 | res[3].end = mem_base + mem_size - 1; | ||
| 199 | |||
| 200 | res[4].name = "io_base"; | ||
| 201 | res[4].flags = IORESOURCE_IO; | ||
| 202 | res[4].start = io_base; | ||
| 203 | res[4].end = io_base; | ||
| 204 | |||
| 205 | res[5].name = "crp_base"; | ||
| 206 | res[5].flags = IORESOURCE_MEM; | ||
| 207 | res[5].start = crp_base; | ||
| 208 | res[5].end = crp_base + AR724X_PCI_CRP_SIZE - 1; | ||
| 209 | |||
| 210 | pdev = platform_device_register_simple("ar724x-pci", id, | ||
| 211 | res, ARRAY_SIZE(res)); | ||
| 212 | return pdev; | ||
| 213 | } | ||
| 214 | |||
| 215 | int __init ath79_register_pci(void) | ||
| 216 | { | ||
| 217 | struct platform_device *pdev = NULL; | ||
| 218 | |||
| 219 | if (soc_is_ar71xx()) { | ||
| 220 | pdev = ath79_register_pci_ar71xx(); | ||
| 221 | } else if (soc_is_ar724x()) { | ||
| 222 | pdev = ath79_register_pci_ar724x(-1, | ||
| 223 | AR724X_PCI_CFG_BASE, | ||
| 224 | AR724X_PCI_CTRL_BASE, | ||
| 225 | AR724X_PCI_CRP_BASE, | ||
| 226 | AR724X_PCI_MEM_BASE, | ||
| 227 | AR724X_PCI_MEM_SIZE, | ||
| 228 | 0, | ||
| 229 | ATH79_CPU_IRQ(2)); | ||
| 230 | } else if (soc_is_ar9342() || | ||
| 231 | soc_is_ar9344()) { | ||
| 232 | u32 bootstrap; | ||
| 233 | |||
| 234 | bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); | ||
| 235 | if ((bootstrap & AR934X_BOOTSTRAP_PCIE_RC) == 0) | ||
| 236 | return -ENODEV; | ||
| 237 | |||
| 238 | pdev = ath79_register_pci_ar724x(-1, | ||
| 239 | AR724X_PCI_CFG_BASE, | ||
| 240 | AR724X_PCI_CTRL_BASE, | ||
| 241 | AR724X_PCI_CRP_BASE, | ||
| 242 | AR724X_PCI_MEM_BASE, | ||
| 243 | AR724X_PCI_MEM_SIZE, | ||
| 244 | 0, | ||
| 245 | ATH79_IP2_IRQ(0)); | ||
| 246 | } else if (soc_is_qca9558()) { | ||
| 247 | pdev = ath79_register_pci_ar724x(0, | ||
| 248 | QCA955X_PCI_CFG_BASE0, | ||
| 249 | QCA955X_PCI_CTRL_BASE0, | ||
| 250 | QCA955X_PCI_CRP_BASE0, | ||
| 251 | QCA955X_PCI_MEM_BASE0, | ||
| 252 | QCA955X_PCI_MEM_SIZE, | ||
| 253 | 0, | ||
| 254 | ATH79_IP2_IRQ(0)); | ||
| 255 | |||
| 256 | pdev = ath79_register_pci_ar724x(1, | ||
| 257 | QCA955X_PCI_CFG_BASE1, | ||
| 258 | QCA955X_PCI_CTRL_BASE1, | ||
| 259 | QCA955X_PCI_CRP_BASE1, | ||
| 260 | QCA955X_PCI_MEM_BASE1, | ||
| 261 | QCA955X_PCI_MEM_SIZE, | ||
| 262 | 1, | ||
| 263 | ATH79_IP3_IRQ(2)); | ||
| 264 | } else { | ||
| 265 | /* No PCI support */ | ||
| 266 | return -ENODEV; | ||
| 267 | } | ||
| 268 | |||
| 269 | if (!pdev) | ||
| 270 | pr_err("unable to register PCI controller device\n"); | ||
| 271 | |||
| 272 | return pdev ? 0 : -ENODEV; | ||
| 273 | } | ||
diff --git a/arch/mips/ath79/pci.h b/arch/mips/ath79/pci.h deleted file mode 100644 index 1d00a3803c37..000000000000 --- a/arch/mips/ath79/pci.h +++ /dev/null | |||
| @@ -1,35 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Atheros AR71XX/AR724X PCI support | ||
| 3 | * | ||
| 4 | * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com> | ||
| 5 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
| 6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License version 2 as published | ||
| 10 | * by the Free Software Foundation. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #ifndef _ATH79_PCI_H | ||
| 14 | #define _ATH79_PCI_H | ||
| 15 | |||
| 16 | struct ath79_pci_irq { | ||
| 17 | int bus; | ||
| 18 | u8 slot; | ||
| 19 | u8 pin; | ||
| 20 | int irq; | ||
| 21 | }; | ||
| 22 | |||
| 23 | #ifdef CONFIG_PCI | ||
| 24 | void ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map); | ||
| 25 | void ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev)); | ||
| 26 | int ath79_register_pci(void); | ||
| 27 | #else | ||
| 28 | static inline void | ||
| 29 | ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map) {} | ||
| 30 | static inline void | ||
| 31 | ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *)) {} | ||
| 32 | static inline int ath79_register_pci(void) { return 0; } | ||
| 33 | #endif | ||
| 34 | |||
| 35 | #endif /* _ATH79_PCI_H */ | ||
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c index 9728abcb18fa..4a70c5de8c92 100644 --- a/arch/mips/ath79/setup.c +++ b/arch/mips/ath79/setup.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
| 20 | #include <linux/clk-provider.h> | 20 | #include <linux/clk-provider.h> |
| 21 | #include <linux/of_fdt.h> | 21 | #include <linux/of_fdt.h> |
| 22 | #include <linux/irqchip.h> | ||
| 22 | 23 | ||
| 23 | #include <asm/bootinfo.h> | 24 | #include <asm/bootinfo.h> |
| 24 | #include <asm/idle.h> | 25 | #include <asm/idle.h> |
| @@ -31,8 +32,6 @@ | |||
| 31 | #include <asm/mach-ath79/ath79.h> | 32 | #include <asm/mach-ath79/ath79.h> |
| 32 | #include <asm/mach-ath79/ar71xx_regs.h> | 33 | #include <asm/mach-ath79/ar71xx_regs.h> |
| 33 | #include "common.h" | 34 | #include "common.h" |
| 34 | #include "dev-common.h" | ||
| 35 | #include "machtypes.h" | ||
| 36 | 35 | ||
| 37 | #define ATH79_SYS_TYPE_LEN 64 | 36 | #define ATH79_SYS_TYPE_LEN 64 |
| 38 | 37 | ||
| @@ -235,25 +234,21 @@ void __init plat_mem_setup(void) | |||
| 235 | else if (fw_passed_dtb) | 234 | else if (fw_passed_dtb) |
| 236 | __dt_setup_arch((void *)KSEG0ADDR(fw_passed_dtb)); | 235 | __dt_setup_arch((void *)KSEG0ADDR(fw_passed_dtb)); |
| 237 | 236 | ||
| 238 | if (mips_machtype != ATH79_MACH_GENERIC_OF) { | 237 | ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE, |
| 239 | ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE, | 238 | AR71XX_RESET_SIZE); |
| 240 | AR71XX_RESET_SIZE); | 239 | ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE, |
| 241 | ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE, | 240 | AR71XX_PLL_SIZE); |
| 242 | AR71XX_PLL_SIZE); | 241 | ath79_detect_sys_type(); |
| 243 | ath79_detect_sys_type(); | 242 | ath79_ddr_ctrl_init(); |
| 244 | ath79_ddr_ctrl_init(); | ||
| 245 | 243 | ||
| 246 | detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX); | 244 | detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX); |
| 247 | |||
| 248 | /* OF machines should use the reset driver */ | ||
| 249 | _machine_restart = ath79_restart; | ||
| 250 | } | ||
| 251 | 245 | ||
| 246 | _machine_restart = ath79_restart; | ||
| 252 | _machine_halt = ath79_halt; | 247 | _machine_halt = ath79_halt; |
| 253 | pm_power_off = ath79_halt; | 248 | pm_power_off = ath79_halt; |
| 254 | } | 249 | } |
| 255 | 250 | ||
| 256 | static void __init ath79_of_plat_time_init(void) | 251 | void __init plat_time_init(void) |
| 257 | { | 252 | { |
| 258 | struct device_node *np; | 253 | struct device_node *np; |
| 259 | struct clk *clk; | 254 | struct clk *clk; |
| @@ -283,61 +278,12 @@ static void __init ath79_of_plat_time_init(void) | |||
| 283 | clk_put(clk); | 278 | clk_put(clk); |
| 284 | } | 279 | } |
| 285 | 280 | ||
| 286 | void __init plat_time_init(void) | 281 | void __init arch_init_irq(void) |
| 287 | { | ||
| 288 | unsigned long cpu_clk_rate; | ||
| 289 | unsigned long ahb_clk_rate; | ||
| 290 | unsigned long ddr_clk_rate; | ||
| 291 | unsigned long ref_clk_rate; | ||
| 292 | |||
| 293 | if (IS_ENABLED(CONFIG_OF) && mips_machtype == ATH79_MACH_GENERIC_OF) { | ||
| 294 | ath79_of_plat_time_init(); | ||
| 295 | return; | ||
| 296 | } | ||
| 297 | |||
| 298 | ath79_clocks_init(); | ||
| 299 | |||
| 300 | cpu_clk_rate = ath79_get_sys_clk_rate("cpu"); | ||
| 301 | ahb_clk_rate = ath79_get_sys_clk_rate("ahb"); | ||
| 302 | ddr_clk_rate = ath79_get_sys_clk_rate("ddr"); | ||
| 303 | ref_clk_rate = ath79_get_sys_clk_rate("ref"); | ||
| 304 | |||
| 305 | pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, Ref:%lu.%03luMHz\n", | ||
| 306 | cpu_clk_rate / 1000000, (cpu_clk_rate / 1000) % 1000, | ||
| 307 | ddr_clk_rate / 1000000, (ddr_clk_rate / 1000) % 1000, | ||
| 308 | ahb_clk_rate / 1000000, (ahb_clk_rate / 1000) % 1000, | ||
| 309 | ref_clk_rate / 1000000, (ref_clk_rate / 1000) % 1000); | ||
| 310 | |||
| 311 | mips_hpt_frequency = cpu_clk_rate / 2; | ||
| 312 | } | ||
| 313 | |||
| 314 | static int __init ath79_setup(void) | ||
| 315 | { | 282 | { |
| 316 | if (mips_machtype == ATH79_MACH_GENERIC_OF) | 283 | irqchip_init(); |
| 317 | return 0; | ||
| 318 | |||
| 319 | ath79_gpio_init(); | ||
| 320 | ath79_register_uart(); | ||
| 321 | ath79_register_wdt(); | ||
| 322 | |||
| 323 | mips_machine_setup(); | ||
| 324 | |||
| 325 | return 0; | ||
| 326 | } | 284 | } |
| 327 | 285 | ||
| 328 | arch_initcall(ath79_setup); | ||
| 329 | |||
| 330 | void __init device_tree_init(void) | 286 | void __init device_tree_init(void) |
| 331 | { | 287 | { |
| 332 | unflatten_and_copy_device_tree(); | 288 | unflatten_and_copy_device_tree(); |
| 333 | } | 289 | } |
| 334 | |||
| 335 | MIPS_MACHINE(ATH79_MACH_GENERIC, | ||
| 336 | "Generic", | ||
| 337 | "Generic AR71XX/AR724X/AR913X based board", | ||
| 338 | NULL); | ||
| 339 | |||
| 340 | MIPS_MACHINE(ATH79_MACH_GENERIC_OF, | ||
| 341 | "DTB", | ||
| 342 | "Generic AR71XX/AR724X/AR913X based board (DT)", | ||
| 343 | NULL); | ||
diff --git a/arch/mips/bcm47xx/buttons.c b/arch/mips/bcm47xx/buttons.c index 977990a609ba..67b6a78d670b 100644 --- a/arch/mips/bcm47xx/buttons.c +++ b/arch/mips/bcm47xx/buttons.c | |||
| @@ -147,7 +147,7 @@ bcm47xx_buttons_buffalo_whr_g125[] __initconst = { | |||
| 147 | static const struct gpio_keys_button | 147 | static const struct gpio_keys_button |
| 148 | bcm47xx_buttons_buffalo_whr_g54s[] __initconst = { | 148 | bcm47xx_buttons_buffalo_whr_g54s[] __initconst = { |
| 149 | BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON), | 149 | BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON), |
| 150 | BCM47XX_GPIO_KEY(4, KEY_RESTART), | 150 | BCM47XX_GPIO_KEY_H(4, KEY_RESTART), |
| 151 | BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode swtich */ | 151 | BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode swtich */ |
| 152 | }; | 152 | }; |
| 153 | 153 | ||
diff --git a/arch/mips/bcm47xx/leds.c b/arch/mips/bcm47xx/leds.c index d85fcdac8bf0..167c42c71e79 100644 --- a/arch/mips/bcm47xx/leds.c +++ b/arch/mips/bcm47xx/leds.c | |||
| @@ -152,11 +152,11 @@ bcm47xx_leds_buffalo_whr_g125[] __initconst = { | |||
| 152 | 152 | ||
| 153 | static const struct gpio_led | 153 | static const struct gpio_led |
| 154 | bcm47xx_leds_buffalo_whr_g54s[] __initconst = { | 154 | bcm47xx_leds_buffalo_whr_g54s[] __initconst = { |
| 155 | BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF), | 155 | BCM47XX_GPIO_LED(1, "green", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF), |
| 156 | BCM47XX_GPIO_LED(2, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | 156 | BCM47XX_GPIO_LED(2, "green", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), |
| 157 | BCM47XX_GPIO_LED(3, "unk", "internal", 1, LEDS_GPIO_DEFSTATE_OFF), | 157 | BCM47XX_GPIO_LED(3, "green", "internal", 1, LEDS_GPIO_DEFSTATE_OFF), |
| 158 | BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | 158 | BCM47XX_GPIO_LED(6, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), |
| 159 | BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF), | 159 | BCM47XX_GPIO_LED(7, "red", "diag", 1, LEDS_GPIO_DEFSTATE_OFF), |
| 160 | }; | 160 | }; |
| 161 | 161 | ||
| 162 | static const struct gpio_led | 162 | static const struct gpio_led |
diff --git a/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dts b/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dts index 0fa3dd1819ff..dda0559cef50 100644 --- a/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dts +++ b/arch/mips/boot/dts/cavium-octeon/octeon_3xxx.dts | |||
| @@ -180,14 +180,28 @@ | |||
| 180 | ethernet@0 { | 180 | ethernet@0 { |
| 181 | phy-handle = <&phy2>; | 181 | phy-handle = <&phy2>; |
| 182 | cavium,alt-phy-handle = <&phy100>; | 182 | cavium,alt-phy-handle = <&phy100>; |
| 183 | rx-delay = <0>; | ||
| 184 | tx-delay = <0>; | ||
| 185 | fixed-link { | ||
| 186 | speed = <1000>; | ||
| 187 | full-duplex; | ||
| 188 | }; | ||
| 183 | }; | 189 | }; |
| 184 | ethernet@1 { | 190 | ethernet@1 { |
| 185 | phy-handle = <&phy3>; | 191 | phy-handle = <&phy3>; |
| 186 | cavium,alt-phy-handle = <&phy101>; | 192 | cavium,alt-phy-handle = <&phy101>; |
| 193 | rx-delay = <0>; | ||
| 194 | tx-delay = <0>; | ||
| 195 | fixed-link { | ||
| 196 | speed = <1000>; | ||
| 197 | full-duplex; | ||
| 198 | }; | ||
| 187 | }; | 199 | }; |
| 188 | ethernet@2 { | 200 | ethernet@2 { |
| 189 | phy-handle = <&phy4>; | 201 | phy-handle = <&phy4>; |
| 190 | cavium,alt-phy-handle = <&phy102>; | 202 | cavium,alt-phy-handle = <&phy102>; |
| 203 | rx-delay = <0>; | ||
| 204 | tx-delay = <0>; | ||
| 191 | }; | 205 | }; |
| 192 | ethernet@3 { | 206 | ethernet@3 { |
| 193 | compatible = "cavium,octeon-3860-pip-port"; | 207 | compatible = "cavium,octeon-3860-pip-port"; |
diff --git a/arch/mips/boot/dts/cavium-octeon/ubnt_e100.dts b/arch/mips/boot/dts/cavium-octeon/ubnt_e100.dts index 243e5dc444fb..962f37fbc7db 100644 --- a/arch/mips/boot/dts/cavium-octeon/ubnt_e100.dts +++ b/arch/mips/boot/dts/cavium-octeon/ubnt_e100.dts | |||
| @@ -33,12 +33,18 @@ | |||
| 33 | interface@0 { | 33 | interface@0 { |
| 34 | ethernet@0 { | 34 | ethernet@0 { |
| 35 | phy-handle = <&phy7>; | 35 | phy-handle = <&phy7>; |
| 36 | rx-delay = <0>; | ||
| 37 | tx-delay = <0x10>; | ||
| 36 | }; | 38 | }; |
| 37 | ethernet@1 { | 39 | ethernet@1 { |
| 38 | phy-handle = <&phy6>; | 40 | phy-handle = <&phy6>; |
| 41 | rx-delay = <0>; | ||
| 42 | tx-delay = <0x10>; | ||
| 39 | }; | 43 | }; |
| 40 | ethernet@2 { | 44 | ethernet@2 { |
| 41 | phy-handle = <&phy5>; | 45 | phy-handle = <&phy5>; |
| 46 | rx-delay = <0>; | ||
| 47 | tx-delay = <0x10>; | ||
| 42 | }; | 48 | }; |
| 43 | }; | 49 | }; |
| 44 | }; | 50 | }; |
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c index ab8362e04461..2e2d45bc850d 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | * network ports from the rest of the cvmx-helper files. | 31 | * network ports from the rest of the cvmx-helper files. |
| 32 | */ | 32 | */ |
| 33 | 33 | ||
| 34 | #include <linux/bug.h> | ||
| 34 | #include <asm/octeon/octeon.h> | 35 | #include <asm/octeon/octeon.h> |
| 35 | #include <asm/octeon/cvmx-bootinfo.h> | 36 | #include <asm/octeon/cvmx-bootinfo.h> |
| 36 | 37 | ||
| @@ -210,56 +211,18 @@ cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port) | |||
| 210 | { | 211 | { |
| 211 | cvmx_helper_link_info_t result; | 212 | cvmx_helper_link_info_t result; |
| 212 | 213 | ||
| 214 | WARN(!octeon_is_simulation(), | ||
| 215 | "Using deprecated link status - please update your DT"); | ||
| 216 | |||
| 213 | /* Unless we fix it later, all links are defaulted to down */ | 217 | /* Unless we fix it later, all links are defaulted to down */ |
| 214 | result.u64 = 0; | 218 | result.u64 = 0; |
| 215 | 219 | ||
| 216 | /* | 220 | if (octeon_is_simulation()) { |
| 217 | * This switch statement should handle all ports that either don't use | ||
| 218 | * Marvell PHYS, or don't support in-band status. | ||
| 219 | */ | ||
| 220 | switch (cvmx_sysinfo_get()->board_type) { | ||
| 221 | case CVMX_BOARD_TYPE_SIM: | ||
| 222 | /* The simulator gives you a simulated 1Gbps full duplex link */ | 221 | /* The simulator gives you a simulated 1Gbps full duplex link */ |
| 223 | result.s.link_up = 1; | 222 | result.s.link_up = 1; |
| 224 | result.s.full_duplex = 1; | 223 | result.s.full_duplex = 1; |
| 225 | result.s.speed = 1000; | 224 | result.s.speed = 1000; |
| 226 | return result; | 225 | return result; |
| 227 | case CVMX_BOARD_TYPE_EBH3100: | ||
| 228 | case CVMX_BOARD_TYPE_CN3010_EVB_HS5: | ||
| 229 | case CVMX_BOARD_TYPE_CN3005_EVB_HS5: | ||
| 230 | case CVMX_BOARD_TYPE_CN3020_EVB_HS5: | ||
| 231 | /* Port 1 on these boards is always Gigabit */ | ||
| 232 | if (ipd_port == 1) { | ||
| 233 | result.s.link_up = 1; | ||
| 234 | result.s.full_duplex = 1; | ||
| 235 | result.s.speed = 1000; | ||
| 236 | return result; | ||
| 237 | } | ||
| 238 | /* Fall through to the generic code below */ | ||
| 239 | break; | ||
| 240 | case CVMX_BOARD_TYPE_CUST_NB5: | ||
| 241 | /* Port 1 on these boards is always Gigabit */ | ||
| 242 | if (ipd_port == 1) { | ||
| 243 | result.s.link_up = 1; | ||
| 244 | result.s.full_duplex = 1; | ||
| 245 | result.s.speed = 1000; | ||
| 246 | return result; | ||
| 247 | } | ||
| 248 | break; | ||
| 249 | case CVMX_BOARD_TYPE_BBGW_REF: | ||
| 250 | /* Port 1 on these boards is always Gigabit */ | ||
| 251 | if (ipd_port == 2) { | ||
| 252 | /* Port 2 is not hooked up */ | ||
| 253 | result.u64 = 0; | ||
| 254 | return result; | ||
| 255 | } else { | ||
| 256 | /* Ports 0 and 1 connect to the switch */ | ||
| 257 | result.s.link_up = 1; | ||
| 258 | result.s.full_duplex = 1; | ||
| 259 | result.s.speed = 1000; | ||
| 260 | return result; | ||
| 261 | } | ||
| 262 | break; | ||
| 263 | } | 226 | } |
| 264 | 227 | ||
| 265 | if (OCTEON_IS_MODEL(OCTEON_CN3XXX) | 228 | if (OCTEON_IS_MODEL(OCTEON_CN3XXX) |
| @@ -358,45 +321,6 @@ int __cvmx_helper_board_interface_probe(int interface, int supported_ports) | |||
| 358 | } | 321 | } |
| 359 | 322 | ||
| 360 | /** | 323 | /** |
| 361 | * Enable packet input/output from the hardware. This function is | ||
| 362 | * called after by cvmx_helper_packet_hardware_enable() to | ||
| 363 | * perform board specific initialization. For most boards | ||
| 364 | * nothing is needed. | ||
| 365 | * | ||
| 366 | * @interface: Interface to enable | ||
| 367 | * | ||
| 368 | * Returns Zero on success, negative on failure | ||
| 369 | */ | ||
| 370 | int __cvmx_helper_board_hardware_enable(int interface) | ||
| 371 | { | ||
| 372 | if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5) { | ||
| 373 | if (interface == 0) { | ||
| 374 | /* Different config for switch port */ | ||
| 375 | cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(1, interface), 0); | ||
| 376 | cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(1, interface), 0); | ||
| 377 | /* | ||
| 378 | * Boards with gigabit WAN ports need a | ||
| 379 | * different setting that is compatible with | ||
| 380 | * 100 Mbit settings | ||
| 381 | */ | ||
| 382 | cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(0, interface), | ||
| 383 | 0xc); | ||
| 384 | cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(0, interface), | ||
| 385 | 0xc); | ||
| 386 | } | ||
| 387 | } else if (cvmx_sysinfo_get()->board_type == | ||
| 388 | CVMX_BOARD_TYPE_UBNT_E100) { | ||
| 389 | cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(0, interface), 0); | ||
| 390 | cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(0, interface), 0x10); | ||
| 391 | cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(1, interface), 0); | ||
| 392 | cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(1, interface), 0x10); | ||
| 393 | cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(2, interface), 0); | ||
| 394 | cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(2, interface), 0x10); | ||
| 395 | } | ||
| 396 | return 0; | ||
| 397 | } | ||
| 398 | |||
| 399 | /** | ||
| 400 | * Get the clock type used for the USB block based on board type. | 324 | * Get the clock type used for the USB block based on board type. |
| 401 | * Used by the USB code for auto configuration of clock type. | 325 | * Used by the USB code for auto configuration of clock type. |
| 402 | * | 326 | * |
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper.c b/arch/mips/cavium-octeon/executive/cvmx-helper.c index 38e0444e57e8..de391541d6f7 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | * Helper functions for common, but complicated tasks. | 30 | * Helper functions for common, but complicated tasks. |
| 31 | * | 31 | * |
| 32 | */ | 32 | */ |
| 33 | #include <linux/bug.h> | ||
| 33 | #include <asm/octeon/octeon.h> | 34 | #include <asm/octeon/octeon.h> |
| 34 | 35 | ||
| 35 | #include <asm/octeon/cvmx-config.h> | 36 | #include <asm/octeon/cvmx-config.h> |
| @@ -43,7 +44,6 @@ | |||
| 43 | #include <asm/octeon/cvmx-helper-board.h> | 44 | #include <asm/octeon/cvmx-helper-board.h> |
| 44 | 45 | ||
| 45 | #include <asm/octeon/cvmx-pip-defs.h> | 46 | #include <asm/octeon/cvmx-pip-defs.h> |
| 46 | #include <asm/octeon/cvmx-smix-defs.h> | ||
| 47 | #include <asm/octeon/cvmx-asxx-defs.h> | 47 | #include <asm/octeon/cvmx-asxx-defs.h> |
| 48 | 48 | ||
| 49 | /* Port count per interface */ | 49 | /* Port count per interface */ |
| @@ -317,22 +317,6 @@ cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface) | |||
| 317 | return CVMX_HELPER_INTERFACE_MODE_DISABLED; | 317 | return CVMX_HELPER_INTERFACE_MODE_DISABLED; |
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | if (interface == 0 | ||
| 321 | && cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_CN3005_EVB_HS5 | ||
| 322 | && cvmx_sysinfo_get()->board_rev_major == 1) { | ||
| 323 | /* | ||
| 324 | * Lie about interface type of CN3005 board. This | ||
| 325 | * board has a switch on port 1 like the other | ||
| 326 | * evaluation boards, but it is connected over RGMII | ||
| 327 | * instead of GMII. Report GMII mode so that the | ||
| 328 | * speed is forced to 1 Gbit full duplex. Other than | ||
| 329 | * some initial configuration (which does not use the | ||
| 330 | * output of this function) there is no difference in | ||
| 331 | * setup between GMII and RGMII modes. | ||
| 332 | */ | ||
| 333 | return CVMX_HELPER_INTERFACE_MODE_GMII; | ||
| 334 | } | ||
| 335 | |||
| 336 | /* Interface 1 is always disabled on CN31XX and CN30XX */ | 320 | /* Interface 1 is always disabled on CN31XX and CN30XX */ |
| 337 | if ((interface == 1) | 321 | if ((interface == 1) |
| 338 | && (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN30XX) | 322 | && (OCTEON_IS_MODEL(OCTEON_CN31XX) || OCTEON_IS_MODEL(OCTEON_CN30XX) |
| @@ -778,7 +762,6 @@ static int __cvmx_helper_packet_hardware_enable(int interface) | |||
| 778 | result = __cvmx_helper_loop_enable(interface); | 762 | result = __cvmx_helper_loop_enable(interface); |
| 779 | break; | 763 | break; |
| 780 | } | 764 | } |
| 781 | result |= __cvmx_helper_board_hardware_enable(interface); | ||
| 782 | return result; | 765 | return result; |
| 783 | } | 766 | } |
| 784 | 767 | ||
| @@ -1026,7 +1009,6 @@ int cvmx_helper_initialize_packet_io_global(void) | |||
| 1026 | int result = 0; | 1009 | int result = 0; |
| 1027 | int interface; | 1010 | int interface; |
| 1028 | union cvmx_l2c_cfg l2c_cfg; | 1011 | union cvmx_l2c_cfg l2c_cfg; |
| 1029 | union cvmx_smix_en smix_en; | ||
| 1030 | const int num_interfaces = cvmx_helper_get_number_of_interfaces(); | 1012 | const int num_interfaces = cvmx_helper_get_number_of_interfaces(); |
| 1031 | 1013 | ||
| 1032 | /* | 1014 | /* |
| @@ -1046,24 +1028,6 @@ int cvmx_helper_initialize_packet_io_global(void) | |||
| 1046 | l2c_cfg.s.rfb_arb_mode = 0; | 1028 | l2c_cfg.s.rfb_arb_mode = 0; |
| 1047 | cvmx_write_csr(CVMX_L2C_CFG, l2c_cfg.u64); | 1029 | cvmx_write_csr(CVMX_L2C_CFG, l2c_cfg.u64); |
| 1048 | 1030 | ||
| 1049 | /* Make sure SMI/MDIO is enabled so we can query PHYs */ | ||
| 1050 | smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(0)); | ||
| 1051 | if (!smix_en.s.en) { | ||
| 1052 | smix_en.s.en = 1; | ||
| 1053 | cvmx_write_csr(CVMX_SMIX_EN(0), smix_en.u64); | ||
| 1054 | } | ||
| 1055 | |||
| 1056 | /* Newer chips actually have two SMI/MDIO interfaces */ | ||
| 1057 | if (!OCTEON_IS_MODEL(OCTEON_CN3XXX) && | ||
| 1058 | !OCTEON_IS_MODEL(OCTEON_CN58XX) && | ||
| 1059 | !OCTEON_IS_MODEL(OCTEON_CN50XX)) { | ||
| 1060 | smix_en.u64 = cvmx_read_csr(CVMX_SMIX_EN(1)); | ||
| 1061 | if (!smix_en.s.en) { | ||
| 1062 | smix_en.s.en = 1; | ||
| 1063 | cvmx_write_csr(CVMX_SMIX_EN(1), smix_en.u64); | ||
| 1064 | } | ||
| 1065 | } | ||
| 1066 | |||
| 1067 | cvmx_pko_initialize_global(); | 1031 | cvmx_pko_initialize_global(); |
| 1068 | for (interface = 0; interface < num_interfaces; interface++) { | 1032 | for (interface = 0; interface < num_interfaces; interface++) { |
| 1069 | result |= cvmx_helper_interface_probe(interface); | 1033 | result |= cvmx_helper_interface_probe(interface); |
| @@ -1136,6 +1100,7 @@ cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port) | |||
| 1136 | if (index == 0) | 1100 | if (index == 0) |
| 1137 | result = __cvmx_helper_rgmii_link_get(ipd_port); | 1101 | result = __cvmx_helper_rgmii_link_get(ipd_port); |
| 1138 | else { | 1102 | else { |
| 1103 | WARN(1, "Using deprecated link status - please update your DT"); | ||
| 1139 | result.s.full_duplex = 1; | 1104 | result.s.full_duplex = 1; |
| 1140 | result.s.link_up = 1; | 1105 | result.s.link_up = 1; |
| 1141 | result.s.speed = 1000; | 1106 | result.s.speed = 1000; |
diff --git a/arch/mips/cavium-octeon/oct_ilm.c b/arch/mips/cavium-octeon/oct_ilm.c index 2d68a39f1443..13f6c7716b1e 100644 --- a/arch/mips/cavium-octeon/oct_ilm.c +++ b/arch/mips/cavium-octeon/oct_ilm.c | |||
| @@ -63,31 +63,11 @@ static int reset_statistics(void *data, u64 value) | |||
| 63 | 63 | ||
| 64 | DEFINE_SIMPLE_ATTRIBUTE(reset_statistics_ops, NULL, reset_statistics, "%llu\n"); | 64 | DEFINE_SIMPLE_ATTRIBUTE(reset_statistics_ops, NULL, reset_statistics, "%llu\n"); |
| 65 | 65 | ||
| 66 | static int init_debufs(void) | 66 | static void init_debugfs(void) |
| 67 | { | 67 | { |
| 68 | struct dentry *show_dentry; | ||
| 69 | dir = debugfs_create_dir("oct_ilm", 0); | 68 | dir = debugfs_create_dir("oct_ilm", 0); |
| 70 | if (!dir) { | 69 | debugfs_create_file("statistics", 0222, dir, NULL, &oct_ilm_ops); |
| 71 | pr_err("oct_ilm: failed to create debugfs entry oct_ilm\n"); | 70 | debugfs_create_file("reset", 0222, dir, NULL, &reset_statistics_ops); |
| 72 | return -1; | ||
| 73 | } | ||
| 74 | |||
| 75 | show_dentry = debugfs_create_file("statistics", 0222, dir, NULL, | ||
| 76 | &oct_ilm_ops); | ||
| 77 | if (!show_dentry) { | ||
| 78 | pr_err("oct_ilm: failed to create debugfs entry oct_ilm/statistics\n"); | ||
| 79 | return -1; | ||
| 80 | } | ||
| 81 | |||
| 82 | show_dentry = debugfs_create_file("reset", 0222, dir, NULL, | ||
| 83 | &reset_statistics_ops); | ||
| 84 | if (!show_dentry) { | ||
| 85 | pr_err("oct_ilm: failed to create debugfs entry oct_ilm/reset\n"); | ||
| 86 | return -1; | ||
| 87 | } | ||
| 88 | |||
| 89 | return 0; | ||
| 90 | |||
| 91 | } | 71 | } |
| 92 | 72 | ||
| 93 | static void init_latency_info(struct latency_info *li, int startup) | 73 | static void init_latency_info(struct latency_info *li, int startup) |
| @@ -169,11 +149,7 @@ static __init int oct_ilm_module_init(void) | |||
| 169 | int rc; | 149 | int rc; |
| 170 | int irq = OCTEON_IRQ_TIMER0 + TIMER_NUM; | 150 | int irq = OCTEON_IRQ_TIMER0 + TIMER_NUM; |
| 171 | 151 | ||
| 172 | rc = init_debufs(); | 152 | init_debugfs(); |
| 173 | if (rc) { | ||
| 174 | WARN(1, "Could not create debugfs entries"); | ||
| 175 | return rc; | ||
| 176 | } | ||
| 177 | 153 | ||
| 178 | rc = request_irq(irq, cvm_oct_ciu_timer_interrupt, IRQF_NO_THREAD, | 154 | rc = request_irq(irq, cvm_oct_ciu_timer_interrupt, IRQF_NO_THREAD, |
| 179 | "oct_ilm", 0); | 155 | "oct_ilm", 0); |
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c index 1f9ba60f7375..51685f893eab 100644 --- a/arch/mips/cavium-octeon/octeon-platform.c +++ b/arch/mips/cavium-octeon/octeon-platform.c | |||
| @@ -458,6 +458,23 @@ static bool __init octeon_has_88e1145(void) | |||
| 458 | !OCTEON_IS_MODEL(OCTEON_CN56XX); | 458 | !OCTEON_IS_MODEL(OCTEON_CN56XX); |
| 459 | } | 459 | } |
| 460 | 460 | ||
| 461 | static bool __init octeon_has_fixed_link(int ipd_port) | ||
| 462 | { | ||
| 463 | switch (cvmx_sysinfo_get()->board_type) { | ||
| 464 | case CVMX_BOARD_TYPE_CN3005_EVB_HS5: | ||
| 465 | case CVMX_BOARD_TYPE_CN3010_EVB_HS5: | ||
| 466 | case CVMX_BOARD_TYPE_CN3020_EVB_HS5: | ||
| 467 | case CVMX_BOARD_TYPE_CUST_NB5: | ||
| 468 | case CVMX_BOARD_TYPE_EBH3100: | ||
| 469 | /* Port 1 on these boards is always gigabit. */ | ||
| 470 | return ipd_port == 1; | ||
| 471 | case CVMX_BOARD_TYPE_BBGW_REF: | ||
| 472 | /* Ports 0 and 1 connect to the switch. */ | ||
| 473 | return ipd_port == 0 || ipd_port == 1; | ||
| 474 | } | ||
| 475 | return false; | ||
| 476 | } | ||
| 477 | |||
| 461 | static void __init octeon_fdt_set_phy(int eth, int phy_addr) | 478 | static void __init octeon_fdt_set_phy(int eth, int phy_addr) |
| 462 | { | 479 | { |
| 463 | const __be32 *phy_handle; | 480 | const __be32 *phy_handle; |
| @@ -586,12 +603,52 @@ static void __init octeon_fdt_rm_ethernet(int node) | |||
| 586 | fdt_nop_node(initial_boot_params, node); | 603 | fdt_nop_node(initial_boot_params, node); |
| 587 | } | 604 | } |
| 588 | 605 | ||
| 606 | static void __init _octeon_rx_tx_delay(int eth, int rx_delay, int tx_delay) | ||
| 607 | { | ||
| 608 | fdt_setprop_inplace_cell(initial_boot_params, eth, "rx-delay", | ||
| 609 | rx_delay); | ||
| 610 | fdt_setprop_inplace_cell(initial_boot_params, eth, "tx-delay", | ||
| 611 | tx_delay); | ||
| 612 | } | ||
| 613 | |||
| 614 | static void __init octeon_rx_tx_delay(int eth, int iface, int port) | ||
| 615 | { | ||
| 616 | switch (cvmx_sysinfo_get()->board_type) { | ||
| 617 | case CVMX_BOARD_TYPE_CN3005_EVB_HS5: | ||
| 618 | if (iface == 0) { | ||
| 619 | if (port == 0) { | ||
| 620 | /* | ||
| 621 | * Boards with gigabit WAN ports need a | ||
| 622 | * different setting that is compatible with | ||
| 623 | * 100 Mbit settings | ||
| 624 | */ | ||
| 625 | _octeon_rx_tx_delay(eth, 0xc, 0x0c); | ||
| 626 | return; | ||
| 627 | } else if (port == 1) { | ||
| 628 | /* Different config for switch port. */ | ||
| 629 | _octeon_rx_tx_delay(eth, 0x0, 0x0); | ||
| 630 | return; | ||
| 631 | } | ||
| 632 | } | ||
| 633 | break; | ||
| 634 | case CVMX_BOARD_TYPE_UBNT_E100: | ||
| 635 | if (iface == 0 && port <= 2) { | ||
| 636 | _octeon_rx_tx_delay(eth, 0x0, 0x10); | ||
| 637 | return; | ||
| 638 | } | ||
| 639 | break; | ||
| 640 | } | ||
| 641 | fdt_nop_property(initial_boot_params, eth, "rx-delay"); | ||
| 642 | fdt_nop_property(initial_boot_params, eth, "tx-delay"); | ||
| 643 | } | ||
| 644 | |||
| 589 | static void __init octeon_fdt_pip_port(int iface, int i, int p, int max) | 645 | static void __init octeon_fdt_pip_port(int iface, int i, int p, int max) |
| 590 | { | 646 | { |
| 591 | char name_buffer[20]; | 647 | char name_buffer[20]; |
| 592 | int eth; | 648 | int eth; |
| 593 | int phy_addr; | 649 | int phy_addr; |
| 594 | int ipd_port; | 650 | int ipd_port; |
| 651 | int fixed_link; | ||
| 595 | 652 | ||
| 596 | snprintf(name_buffer, sizeof(name_buffer), "ethernet@%x", p); | 653 | snprintf(name_buffer, sizeof(name_buffer), "ethernet@%x", p); |
| 597 | eth = fdt_subnode_offset(initial_boot_params, iface, name_buffer); | 654 | eth = fdt_subnode_offset(initial_boot_params, iface, name_buffer); |
| @@ -609,6 +666,13 @@ static void __init octeon_fdt_pip_port(int iface, int i, int p, int max) | |||
| 609 | 666 | ||
| 610 | phy_addr = cvmx_helper_board_get_mii_address(ipd_port); | 667 | phy_addr = cvmx_helper_board_get_mii_address(ipd_port); |
| 611 | octeon_fdt_set_phy(eth, phy_addr); | 668 | octeon_fdt_set_phy(eth, phy_addr); |
| 669 | |||
| 670 | fixed_link = fdt_subnode_offset(initial_boot_params, eth, "fixed-link"); | ||
| 671 | if (fixed_link < 0) | ||
| 672 | WARN_ON(octeon_has_fixed_link(ipd_port)); | ||
| 673 | else if (!octeon_has_fixed_link(ipd_port)) | ||
| 674 | fdt_nop_node(initial_boot_params, fixed_link); | ||
| 675 | octeon_rx_tx_delay(eth, i, p); | ||
| 612 | } | 676 | } |
| 613 | 677 | ||
| 614 | static void __init octeon_fdt_pip_iface(int pip, int idx) | 678 | static void __init octeon_fdt_pip_iface(int pip, int idx) |
diff --git a/arch/mips/configs/xway_defconfig b/arch/mips/configs/xway_defconfig index c3cac29e8414..2bb02ea9fb4e 100644 --- a/arch/mips/configs/xway_defconfig +++ b/arch/mips/configs/xway_defconfig | |||
| @@ -13,7 +13,6 @@ CONFIG_EMBEDDED=y | |||
| 13 | # CONFIG_COMPAT_BRK is not set | 13 | # CONFIG_COMPAT_BRK is not set |
| 14 | CONFIG_LANTIQ=y | 14 | CONFIG_LANTIQ=y |
| 15 | CONFIG_PCI_LANTIQ=y | 15 | CONFIG_PCI_LANTIQ=y |
| 16 | CONFIG_XRX200_PHY_FW=y | ||
| 17 | CONFIG_CPU_MIPS32_R2=y | 16 | CONFIG_CPU_MIPS32_R2=y |
| 18 | CONFIG_MIPS_VPE_LOADER=y | 17 | CONFIG_MIPS_VPE_LOADER=y |
| 19 | CONFIG_NR_CPUS=2 | 18 | CONFIG_NR_CPUS=2 |
diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild index f15d5db5dd67..87b86cdf126a 100644 --- a/arch/mips/include/asm/Kbuild +++ b/arch/mips/include/asm/Kbuild | |||
| @@ -3,7 +3,6 @@ generated-y += syscall_table_32_o32.h | |||
| 3 | generated-y += syscall_table_64_n32.h | 3 | generated-y += syscall_table_64_n32.h |
| 4 | generated-y += syscall_table_64_n64.h | 4 | generated-y += syscall_table_64_n64.h |
| 5 | generated-y += syscall_table_64_o32.h | 5 | generated-y += syscall_table_64_o32.h |
| 6 | generic-(CONFIG_GENERIC_CSUM) += checksum.h | ||
| 7 | generic-y += current.h | 6 | generic-y += current.h |
| 8 | generic-y += device.h | 7 | generic-y += device.h |
| 9 | generic-y += dma-contiguous.h | 8 | generic-y += dma-contiguous.h |
diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h index b7f6ac5e513c..b865e317a14f 100644 --- a/arch/mips/include/asm/barrier.h +++ b/arch/mips/include/asm/barrier.h | |||
| @@ -105,6 +105,20 @@ | |||
| 105 | */ | 105 | */ |
| 106 | #define STYPE_SYNC_MB 0x10 | 106 | #define STYPE_SYNC_MB 0x10 |
| 107 | 107 | ||
| 108 | /* | ||
| 109 | * stype 0x14 - A completion barrier specific to global invalidations | ||
| 110 | * | ||
| 111 | * When a sync instruction of this type completes any preceding GINVI or GINVT | ||
| 112 | * operation has been globalized & completed on all coherent CPUs. Anything | ||
| 113 | * that the GINV* instruction should invalidate will have been invalidated on | ||
| 114 | * all coherent CPUs when this instruction completes. It is implementation | ||
| 115 | * specific whether the GINV* instructions themselves will ensure completion, | ||
| 116 | * or this sync type will. | ||
| 117 | * | ||
| 118 | * In systems implementing global invalidates (ie. with Config5.GI == 2 or 3) | ||
| 119 | * this sync type also requires that previous SYNCI operations have completed. | ||
| 120 | */ | ||
| 121 | #define STYPE_GINV 0x14 | ||
| 108 | 122 | ||
| 109 | #ifdef CONFIG_CPU_HAS_SYNC | 123 | #ifdef CONFIG_CPU_HAS_SYNC |
| 110 | #define __sync() \ | 124 | #define __sync() \ |
| @@ -258,6 +272,11 @@ | |||
| 258 | #define loongson_llsc_mb() do { } while (0) | 272 | #define loongson_llsc_mb() do { } while (0) |
| 259 | #endif | 273 | #endif |
| 260 | 274 | ||
| 275 | static inline void sync_ginv(void) | ||
| 276 | { | ||
| 277 | asm volatile("sync\t%0" :: "i"(STYPE_GINV)); | ||
| 278 | } | ||
| 279 | |||
| 261 | #include <asm-generic/barrier.h> | 280 | #include <asm-generic/barrier.h> |
| 262 | 281 | ||
| 263 | #endif /* __ASM_BARRIER_H */ | 282 | #endif /* __ASM_BARRIER_H */ |
diff --git a/arch/mips/include/asm/cacheflush.h b/arch/mips/include/asm/cacheflush.h index 4812d1fed0c2..d687b40b9fbb 100644 --- a/arch/mips/include/asm/cacheflush.h +++ b/arch/mips/include/asm/cacheflush.h | |||
| @@ -25,7 +25,6 @@ | |||
| 25 | * | 25 | * |
| 26 | * MIPS specific flush operations: | 26 | * MIPS specific flush operations: |
| 27 | * | 27 | * |
| 28 | * - flush_cache_sigtramp() flush signal trampoline | ||
| 29 | * - flush_icache_all() flush the entire instruction cache | 28 | * - flush_icache_all() flush the entire instruction cache |
| 30 | * - flush_data_cache_page() flushes a page from the data cache | 29 | * - flush_data_cache_page() flushes a page from the data cache |
| 31 | * - __flush_icache_user_range(start, end) flushes range of user instructions | 30 | * - __flush_icache_user_range(start, end) flushes range of user instructions |
| @@ -110,7 +109,6 @@ extern void copy_from_user_page(struct vm_area_struct *vma, | |||
| 110 | struct page *page, unsigned long vaddr, void *dst, const void *src, | 109 | struct page *page, unsigned long vaddr, void *dst, const void *src, |
| 111 | unsigned long len); | 110 | unsigned long len); |
| 112 | 111 | ||
| 113 | extern void (*flush_cache_sigtramp)(unsigned long addr); | ||
| 114 | extern void (*flush_icache_all)(void); | 112 | extern void (*flush_icache_all)(void); |
| 115 | extern void (*local_flush_data_cache_page)(void * addr); | 113 | extern void (*local_flush_data_cache_page)(void * addr); |
| 116 | extern void (*flush_data_cache_page)(unsigned long addr); | 114 | extern void (*flush_data_cache_page)(unsigned long addr); |
diff --git a/arch/mips/include/asm/cmpxchg.h b/arch/mips/include/asm/cmpxchg.h index 638de0c25249..f345a873742d 100644 --- a/arch/mips/include/asm/cmpxchg.h +++ b/arch/mips/include/asm/cmpxchg.h | |||
| @@ -36,6 +36,8 @@ | |||
| 36 | */ | 36 | */ |
| 37 | extern unsigned long __cmpxchg_called_with_bad_pointer(void) | 37 | extern unsigned long __cmpxchg_called_with_bad_pointer(void) |
| 38 | __compiletime_error("Bad argument size for cmpxchg"); | 38 | __compiletime_error("Bad argument size for cmpxchg"); |
| 39 | extern unsigned long __cmpxchg64_unsupported(void) | ||
| 40 | __compiletime_error("cmpxchg64 not available; cpu_has_64bits may be false"); | ||
| 39 | extern unsigned long __xchg_called_with_bad_pointer(void) | 41 | extern unsigned long __xchg_called_with_bad_pointer(void) |
| 40 | __compiletime_error("Bad argument size for xchg"); | 42 | __compiletime_error("Bad argument size for xchg"); |
| 41 | 43 | ||
| @@ -204,12 +206,102 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, | |||
| 204 | cmpxchg((ptr), (o), (n)); \ | 206 | cmpxchg((ptr), (o), (n)); \ |
| 205 | }) | 207 | }) |
| 206 | #else | 208 | #else |
| 207 | #include <asm-generic/cmpxchg-local.h> | 209 | |
| 208 | #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) | 210 | # include <asm-generic/cmpxchg-local.h> |
| 209 | #ifndef CONFIG_SMP | 211 | # define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) |
| 210 | #define cmpxchg64(ptr, o, n) cmpxchg64_local((ptr), (o), (n)) | 212 | |
| 211 | #endif | 213 | # ifdef CONFIG_SMP |
| 212 | #endif | 214 | |
| 215 | static inline unsigned long __cmpxchg64(volatile void *ptr, | ||
| 216 | unsigned long long old, | ||
| 217 | unsigned long long new) | ||
| 218 | { | ||
| 219 | unsigned long long tmp, ret; | ||
| 220 | unsigned long flags; | ||
| 221 | |||
| 222 | /* | ||
| 223 | * The assembly below has to combine 32 bit values into a 64 bit | ||
| 224 | * register, and split 64 bit values from one register into two. If we | ||
| 225 | * were to take an interrupt in the middle of this we'd only save the | ||
| 226 | * least significant 32 bits of each register & probably clobber the | ||
| 227 | * most significant 32 bits of the 64 bit values we're using. In order | ||
| 228 | * to avoid this we must disable interrupts. | ||
| 229 | */ | ||
| 230 | local_irq_save(flags); | ||
| 231 | |||
| 232 | asm volatile( | ||
| 233 | " .set push \n" | ||
| 234 | " .set " MIPS_ISA_ARCH_LEVEL " \n" | ||
| 235 | /* Load 64 bits from ptr */ | ||
| 236 | "1: lld %L0, %3 # __cmpxchg64 \n" | ||
| 237 | /* | ||
| 238 | * Split the 64 bit value we loaded into the 2 registers that hold the | ||
| 239 | * ret variable. | ||
| 240 | */ | ||
| 241 | " dsra %M0, %L0, 32 \n" | ||
| 242 | " sll %L0, %L0, 0 \n" | ||
| 243 | /* | ||
| 244 | * Compare ret against old, breaking out of the loop if they don't | ||
| 245 | * match. | ||
| 246 | */ | ||
| 247 | " bne %M0, %M4, 2f \n" | ||
| 248 | " bne %L0, %L4, 2f \n" | ||
| 249 | /* | ||
| 250 | * Combine the 32 bit halves from the 2 registers that hold the new | ||
| 251 | * variable into a single 64 bit register. | ||
| 252 | */ | ||
| 253 | # if MIPS_ISA_REV >= 2 | ||
| 254 | " move %L1, %L5 \n" | ||
| 255 | " dins %L1, %M5, 32, 32 \n" | ||
| 256 | # else | ||
| 257 | " dsll %L1, %L5, 32 \n" | ||
| 258 | " dsrl %L1, %L1, 32 \n" | ||
| 259 | " .set noat \n" | ||
| 260 | " dsll $at, %M5, 32 \n" | ||
| 261 | " or %L1, %L1, $at \n" | ||
| 262 | " .set at \n" | ||
| 263 | # endif | ||
| 264 | /* Attempt to store new at ptr */ | ||
| 265 | " scd %L1, %2 \n" | ||
| 266 | /* If we failed, loop! */ | ||
| 267 | "\t" __scbeqz " %L1, 1b \n" | ||
| 268 | " .set pop \n" | ||
| 269 | "2: \n" | ||
| 270 | : "=&r"(ret), | ||
| 271 | "=&r"(tmp), | ||
| 272 | "=" GCC_OFF_SMALL_ASM() (*(unsigned long long *)ptr) | ||
| 273 | : GCC_OFF_SMALL_ASM() (*(unsigned long long *)ptr), | ||
| 274 | "r" (old), | ||
| 275 | "r" (new) | ||
| 276 | : "memory"); | ||
| 277 | |||
| 278 | local_irq_restore(flags); | ||
| 279 | return ret; | ||
| 280 | } | ||
| 281 | |||
| 282 | # define cmpxchg64(ptr, o, n) ({ \ | ||
| 283 | unsigned long long __old = (__typeof__(*(ptr)))(o); \ | ||
| 284 | unsigned long long __new = (__typeof__(*(ptr)))(n); \ | ||
| 285 | __typeof__(*(ptr)) __res; \ | ||
| 286 | \ | ||
| 287 | /* \ | ||
| 288 | * We can only use cmpxchg64 if we know that the CPU supports \ | ||
| 289 | * 64-bits, ie. lld & scd. Our call to __cmpxchg64_unsupported \ | ||
| 290 | * will cause a build error unless cpu_has_64bits is a \ | ||
| 291 | * compile-time constant 1. \ | ||
| 292 | */ \ | ||
| 293 | if (cpu_has_64bits && kernel_uses_llsc) \ | ||
| 294 | __res = __cmpxchg64((ptr), __old, __new); \ | ||
| 295 | else \ | ||
| 296 | __res = __cmpxchg64_unsupported(); \ | ||
| 297 | \ | ||
| 298 | __res; \ | ||
| 299 | }) | ||
| 300 | |||
| 301 | # else /* !CONFIG_SMP */ | ||
| 302 | # define cmpxchg64(ptr, o, n) cmpxchg64_local((ptr), (o), (n)) | ||
| 303 | # endif /* !CONFIG_SMP */ | ||
| 304 | #endif /* !CONFIG_64BIT */ | ||
| 213 | 305 | ||
| 214 | #undef __scbeqz | 306 | #undef __scbeqz |
| 215 | 307 | ||
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index 701e525641b8..6998a9796499 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h | |||
| @@ -591,6 +591,19 @@ | |||
| 591 | #endif /* CONFIG_MIPS_MT_SMP */ | 591 | #endif /* CONFIG_MIPS_MT_SMP */ |
| 592 | 592 | ||
| 593 | /* | 593 | /* |
| 594 | * We only enable MMID support for configurations which natively support 64 bit | ||
| 595 | * atomics because getting good performance from the allocator relies upon | ||
| 596 | * efficient atomic64_*() functions. | ||
| 597 | */ | ||
| 598 | #ifndef cpu_has_mmid | ||
| 599 | # ifdef CONFIG_GENERIC_ATOMIC64 | ||
| 600 | # define cpu_has_mmid 0 | ||
| 601 | # else | ||
| 602 | # define cpu_has_mmid __isa_ge_and_opt(6, MIPS_CPU_MMID) | ||
| 603 | # endif | ||
| 604 | #endif | ||
| 605 | |||
| 606 | /* | ||
| 594 | * Guest capabilities | 607 | * Guest capabilities |
| 595 | */ | 608 | */ |
| 596 | #ifndef cpu_guest_has_conf1 | 609 | #ifndef cpu_guest_has_conf1 |
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 532b49b1dbb3..6ad7d3cabd91 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h | |||
| @@ -422,6 +422,7 @@ enum cpu_type_enum { | |||
| 422 | MBIT_ULL(55) /* CPU shares FTLB entries with another */ | 422 | MBIT_ULL(55) /* CPU shares FTLB entries with another */ |
| 423 | #define MIPS_CPU_MT_PER_TC_PERF_COUNTERS \ | 423 | #define MIPS_CPU_MT_PER_TC_PERF_COUNTERS \ |
| 424 | MBIT_ULL(56) /* CPU has perf counters implemented per TC (MIPSMT ASE) */ | 424 | MBIT_ULL(56) /* CPU has perf counters implemented per TC (MIPSMT ASE) */ |
| 425 | #define MIPS_CPU_MMID MBIT_ULL(57) /* CPU supports MemoryMapIDs */ | ||
| 425 | 426 | ||
| 426 | /* | 427 | /* |
| 427 | * CPU ASE encodings | 428 | * CPU ASE encodings |
diff --git a/arch/mips/include/asm/ginvt.h b/arch/mips/include/asm/ginvt.h new file mode 100644 index 000000000000..49c6dbe37338 --- /dev/null +++ b/arch/mips/include/asm/ginvt.h | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | #ifndef __MIPS_ASM_GINVT_H__ | ||
| 3 | #define __MIPS_ASM_GINVT_H__ | ||
| 4 | |||
| 5 | #include <asm/mipsregs.h> | ||
| 6 | |||
| 7 | enum ginvt_type { | ||
| 8 | GINVT_FULL, | ||
| 9 | GINVT_VA, | ||
| 10 | GINVT_MMID, | ||
| 11 | }; | ||
| 12 | |||
| 13 | #ifdef TOOLCHAIN_SUPPORTS_GINV | ||
| 14 | # define _ASM_SET_GINV ".set ginv\n" | ||
| 15 | #else | ||
| 16 | _ASM_MACRO_1R1I(ginvt, rs, type, | ||
| 17 | _ASM_INSN_IF_MIPS(0x7c0000bd | (__rs << 21) | (\\type << 8)) | ||
| 18 | _ASM_INSN32_IF_MM(0x0000717c | (__rs << 16) | (\\type << 9))); | ||
| 19 | # define _ASM_SET_GINV | ||
| 20 | #endif | ||
| 21 | |||
| 22 | static inline void ginvt(unsigned long addr, enum ginvt_type type) | ||
| 23 | { | ||
| 24 | asm volatile( | ||
| 25 | ".set push\n" | ||
| 26 | _ASM_SET_GINV | ||
| 27 | " ginvt %0, %1\n" | ||
| 28 | ".set pop" | ||
| 29 | : /* no outputs */ | ||
| 30 | : "r"(addr), "i"(type) | ||
| 31 | : "memory"); | ||
| 32 | } | ||
| 33 | |||
| 34 | static inline void ginvt_full(void) | ||
| 35 | { | ||
| 36 | ginvt(0, GINVT_FULL); | ||
| 37 | } | ||
| 38 | |||
| 39 | static inline void ginvt_va(unsigned long addr) | ||
| 40 | { | ||
| 41 | addr &= PAGE_MASK << 1; | ||
| 42 | ginvt(addr, GINVT_VA); | ||
| 43 | } | ||
| 44 | |||
| 45 | static inline void ginvt_mmid(void) | ||
| 46 | { | ||
| 47 | ginvt(0, GINVT_MMID); | ||
| 48 | } | ||
| 49 | |||
| 50 | static inline void ginvt_va_mmid(unsigned long addr) | ||
| 51 | { | ||
| 52 | addr &= PAGE_MASK << 1; | ||
| 53 | ginvt(addr, GINVT_VA | GINVT_MMID); | ||
| 54 | } | ||
| 55 | |||
| 56 | #endif /* __MIPS_ASM_GINVT_H__ */ | ||
diff --git a/arch/mips/include/asm/irqflags.h b/arch/mips/include/asm/irqflags.h index 9d3610be2323..f0b862a83816 100644 --- a/arch/mips/include/asm/irqflags.h +++ b/arch/mips/include/asm/irqflags.h | |||
| @@ -41,7 +41,7 @@ static inline unsigned long arch_local_irq_save(void) | |||
| 41 | " .set push \n" | 41 | " .set push \n" |
| 42 | " .set reorder \n" | 42 | " .set reorder \n" |
| 43 | " .set noat \n" | 43 | " .set noat \n" |
| 44 | #if defined(CONFIG_CPU_LOONGSON3) | 44 | #if defined(CONFIG_CPU_LOONGSON3) || defined (CONFIG_CPU_LOONGSON1) |
| 45 | " mfc0 %[flags], $12 \n" | 45 | " mfc0 %[flags], $12 \n" |
| 46 | " di \n" | 46 | " di \n" |
| 47 | #else | 47 | #else |
diff --git a/arch/mips/include/asm/mach-ath79/ath79.h b/arch/mips/include/asm/mach-ath79/ath79.h index 73dcd63b8243..47e8827e9564 100644 --- a/arch/mips/include/asm/mach-ath79/ath79.h +++ b/arch/mips/include/asm/mach-ath79/ath79.h | |||
| @@ -178,8 +178,4 @@ static inline u32 ath79_reset_rr(unsigned reg) | |||
| 178 | void ath79_device_reset_set(u32 mask); | 178 | void ath79_device_reset_set(u32 mask); |
| 179 | void ath79_device_reset_clear(u32 mask); | 179 | void ath79_device_reset_clear(u32 mask); |
| 180 | 180 | ||
| 181 | void ath79_cpu_irq_init(unsigned irq_wb_chan2, unsigned irq_wb_chan3); | ||
| 182 | void ath79_misc_irq_init(void __iomem *regs, int irq, | ||
| 183 | int irq_base, bool is_ar71xx); | ||
| 184 | |||
| 185 | #endif /* __ASM_MACH_ATH79_H */ | 181 | #endif /* __ASM_MACH_ATH79_H */ |
diff --git a/arch/mips/include/asm/mach-ip27/irq.h b/arch/mips/include/asm/mach-ip27/irq.h index b0b7261ff3ad..fd91c58aaf7d 100644 --- a/arch/mips/include/asm/mach-ip27/irq.h +++ b/arch/mips/include/asm/mach-ip27/irq.h | |||
| @@ -10,13 +10,15 @@ | |||
| 10 | #ifndef __ASM_MACH_IP27_IRQ_H | 10 | #ifndef __ASM_MACH_IP27_IRQ_H |
| 11 | #define __ASM_MACH_IP27_IRQ_H | 11 | #define __ASM_MACH_IP27_IRQ_H |
| 12 | 12 | ||
| 13 | /* | ||
| 14 | * A hardwired interrupt number is completely stupid for this system - a | ||
| 15 | * large configuration might have thousands if not tenthousands of | ||
| 16 | * interrupts. | ||
| 17 | */ | ||
| 18 | #define NR_IRQS 256 | 13 | #define NR_IRQS 256 |
| 19 | 14 | ||
| 20 | #include_next <irq.h> | 15 | #include_next <irq.h> |
| 21 | 16 | ||
| 17 | #define IP27_HUB_PEND0_IRQ (MIPS_CPU_IRQ_BASE + 2) | ||
| 18 | #define IP27_HUB_PEND1_IRQ (MIPS_CPU_IRQ_BASE + 3) | ||
| 19 | #define IP27_RT_TIMER_IRQ (MIPS_CPU_IRQ_BASE + 4) | ||
| 20 | |||
| 21 | #define IP27_HUB_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8) | ||
| 22 | #define IP27_HUB_IRQ_COUNT 128 | ||
| 23 | |||
| 22 | #endif /* __ASM_MACH_IP27_IRQ_H */ | 24 | #endif /* __ASM_MACH_IP27_IRQ_H */ |
diff --git a/arch/mips/include/asm/mach-ip27/mmzone.h b/arch/mips/include/asm/mach-ip27/mmzone.h index 2ed3094dee07..1cd6a23a84f2 100644 --- a/arch/mips/include/asm/mach-ip27/mmzone.h +++ b/arch/mips/include/asm/mach-ip27/mmzone.h | |||
| @@ -8,20 +8,11 @@ | |||
| 8 | 8 | ||
| 9 | #define pa_to_nid(addr) NASID_TO_COMPACT_NODEID(NASID_GET(addr)) | 9 | #define pa_to_nid(addr) NASID_TO_COMPACT_NODEID(NASID_GET(addr)) |
| 10 | 10 | ||
| 11 | #define LEVELS_PER_SLICE 128 | ||
| 12 | |||
| 13 | struct slice_data { | ||
| 14 | unsigned long irq_enable_mask[2]; | ||
| 15 | int level_to_irq[LEVELS_PER_SLICE]; | ||
| 16 | }; | ||
| 17 | |||
| 18 | struct hub_data { | 11 | struct hub_data { |
| 19 | kern_vars_t kern_vars; | 12 | kern_vars_t kern_vars; |
| 20 | DECLARE_BITMAP(h_bigwin_used, HUB_NUM_BIG_WINDOW); | 13 | DECLARE_BITMAP(h_bigwin_used, HUB_NUM_BIG_WINDOW); |
| 21 | cpumask_t h_cpus; | 14 | cpumask_t h_cpus; |
| 22 | unsigned long slice_map; | 15 | unsigned long slice_map; |
| 23 | unsigned long irq_alloc_mask[2]; | ||
| 24 | struct slice_data slice[2]; | ||
| 25 | }; | 16 | }; |
| 26 | 17 | ||
| 27 | struct node_data { | 18 | struct node_data { |
diff --git a/arch/mips/include/asm/mach-loongson32/platform.h b/arch/mips/include/asm/mach-loongson32/platform.h index 8f8fa43ba095..15d1de2300fe 100644 --- a/arch/mips/include/asm/mach-loongson32/platform.h +++ b/arch/mips/include/asm/mach-loongson32/platform.h | |||
| @@ -17,19 +17,15 @@ | |||
| 17 | 17 | ||
| 18 | extern struct platform_device ls1x_uart_pdev; | 18 | extern struct platform_device ls1x_uart_pdev; |
| 19 | extern struct platform_device ls1x_cpufreq_pdev; | 19 | extern struct platform_device ls1x_cpufreq_pdev; |
| 20 | extern struct platform_device ls1x_dma_pdev; | ||
| 21 | extern struct platform_device ls1x_eth0_pdev; | 20 | extern struct platform_device ls1x_eth0_pdev; |
| 22 | extern struct platform_device ls1x_eth1_pdev; | 21 | extern struct platform_device ls1x_eth1_pdev; |
| 23 | extern struct platform_device ls1x_ehci_pdev; | 22 | extern struct platform_device ls1x_ehci_pdev; |
| 24 | extern struct platform_device ls1x_gpio0_pdev; | 23 | extern struct platform_device ls1x_gpio0_pdev; |
| 25 | extern struct platform_device ls1x_gpio1_pdev; | 24 | extern struct platform_device ls1x_gpio1_pdev; |
| 26 | extern struct platform_device ls1x_nand_pdev; | ||
| 27 | extern struct platform_device ls1x_rtc_pdev; | 25 | extern struct platform_device ls1x_rtc_pdev; |
| 28 | extern struct platform_device ls1x_wdt_pdev; | 26 | extern struct platform_device ls1x_wdt_pdev; |
| 29 | 27 | ||
| 30 | void __init ls1x_clk_init(void); | 28 | void __init ls1x_clk_init(void); |
| 31 | void __init ls1x_dma_set_platdata(struct plat_ls1x_dma *pdata); | ||
| 32 | void __init ls1x_nand_set_platdata(struct plat_ls1x_nand *pdata); | ||
| 33 | void __init ls1x_rtc_set_extclk(struct platform_device *pdev); | 29 | void __init ls1x_rtc_set_extclk(struct platform_device *pdev); |
| 34 | void __init ls1x_serial_set_uartclk(struct platform_device *pdev); | 30 | void __init ls1x_serial_set_uartclk(struct platform_device *pdev); |
| 35 | 31 | ||
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 402b80af91aa..1e6966e8527e 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h | |||
| @@ -667,6 +667,7 @@ | |||
| 667 | #define MIPS_CONF5_FRE (_ULCAST_(1) << 8) | 667 | #define MIPS_CONF5_FRE (_ULCAST_(1) << 8) |
| 668 | #define MIPS_CONF5_UFE (_ULCAST_(1) << 9) | 668 | #define MIPS_CONF5_UFE (_ULCAST_(1) << 9) |
| 669 | #define MIPS_CONF5_CA2 (_ULCAST_(1) << 14) | 669 | #define MIPS_CONF5_CA2 (_ULCAST_(1) << 14) |
| 670 | #define MIPS_CONF5_MI (_ULCAST_(1) << 17) | ||
| 670 | #define MIPS_CONF5_CRCP (_ULCAST_(1) << 18) | 671 | #define MIPS_CONF5_CRCP (_ULCAST_(1) << 18) |
| 671 | #define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27) | 672 | #define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27) |
| 672 | #define MIPS_CONF5_EVA (_ULCAST_(1) << 28) | 673 | #define MIPS_CONF5_EVA (_ULCAST_(1) << 28) |
| @@ -1247,6 +1248,13 @@ __asm__(".macro parse_r var r\n\t" | |||
| 1247 | ENC \ | 1248 | ENC \ |
| 1248 | ".endm") | 1249 | ".endm") |
| 1249 | 1250 | ||
| 1251 | /* Instructions with 1 register operand & 1 immediate operand */ | ||
| 1252 | #define _ASM_MACRO_1R1I(OP, R1, I2, ENC) \ | ||
| 1253 | __asm__(".macro " #OP " " #R1 ", " #I2 "\n\t" \ | ||
| 1254 | "parse_r __" #R1 ", \\" #R1 "\n\t" \ | ||
| 1255 | ENC \ | ||
| 1256 | ".endm") | ||
| 1257 | |||
| 1250 | /* Instructions with 2 register operands */ | 1258 | /* Instructions with 2 register operands */ |
| 1251 | #define _ASM_MACRO_2R(OP, R1, R2, ENC) \ | 1259 | #define _ASM_MACRO_2R(OP, R1, R2, ENC) \ |
| 1252 | __asm__(".macro " #OP " " #R1 ", " #R2 "\n\t" \ | 1260 | __asm__(".macro " #OP " " #R1 ", " #R2 "\n\t" \ |
| @@ -1603,6 +1611,9 @@ do { \ | |||
| 1603 | #define read_c0_xcontextconfig() __read_ulong_c0_register($4, 3) | 1611 | #define read_c0_xcontextconfig() __read_ulong_c0_register($4, 3) |
| 1604 | #define write_c0_xcontextconfig(val) __write_ulong_c0_register($4, 3, val) | 1612 | #define write_c0_xcontextconfig(val) __write_ulong_c0_register($4, 3, val) |
| 1605 | 1613 | ||
| 1614 | #define read_c0_memorymapid() __read_32bit_c0_register($4, 5) | ||
| 1615 | #define write_c0_memorymapid(val) __write_32bit_c0_register($4, 5, val) | ||
| 1616 | |||
| 1606 | #define read_c0_pagemask() __read_32bit_c0_register($5, 0) | 1617 | #define read_c0_pagemask() __read_32bit_c0_register($5, 0) |
| 1607 | #define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val) | 1618 | #define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val) |
| 1608 | 1619 | ||
diff --git a/arch/mips/include/asm/mmu.h b/arch/mips/include/asm/mmu.h index 88a108ce62c1..5df0238f639b 100644 --- a/arch/mips/include/asm/mmu.h +++ b/arch/mips/include/asm/mmu.h | |||
| @@ -7,7 +7,11 @@ | |||
| 7 | #include <linux/wait.h> | 7 | #include <linux/wait.h> |
| 8 | 8 | ||
| 9 | typedef struct { | 9 | typedef struct { |
| 10 | u64 asid[NR_CPUS]; | 10 | union { |
| 11 | u64 asid[NR_CPUS]; | ||
| 12 | atomic64_t mmid; | ||
| 13 | }; | ||
| 14 | |||
| 11 | void *vdso; | 15 | void *vdso; |
| 12 | 16 | ||
| 13 | /* lock to be held whilst modifying fp_bd_emupage_allocmap */ | 17 | /* lock to be held whilst modifying fp_bd_emupage_allocmap */ |
diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h index a589585be21b..cddead91acd4 100644 --- a/arch/mips/include/asm/mmu_context.h +++ b/arch/mips/include/asm/mmu_context.h | |||
| @@ -17,8 +17,10 @@ | |||
| 17 | #include <linux/smp.h> | 17 | #include <linux/smp.h> |
| 18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
| 19 | 19 | ||
| 20 | #include <asm/barrier.h> | ||
| 20 | #include <asm/cacheflush.h> | 21 | #include <asm/cacheflush.h> |
| 21 | #include <asm/dsemul.h> | 22 | #include <asm/dsemul.h> |
| 23 | #include <asm/ginvt.h> | ||
| 22 | #include <asm/hazards.h> | 24 | #include <asm/hazards.h> |
| 23 | #include <asm/tlbflush.h> | 25 | #include <asm/tlbflush.h> |
| 24 | #include <asm-generic/mm_hooks.h> | 26 | #include <asm-generic/mm_hooks.h> |
| @@ -73,6 +75,19 @@ extern unsigned long pgd_current[]; | |||
| 73 | #endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/ | 75 | #endif /* CONFIG_MIPS_PGD_C0_CONTEXT*/ |
| 74 | 76 | ||
| 75 | /* | 77 | /* |
| 78 | * The ginvt instruction will invalidate wired entries when its type field | ||
| 79 | * targets anything other than the entire TLB. That means that if we were to | ||
| 80 | * allow the kernel to create wired entries with the MMID of current->active_mm | ||
| 81 | * then those wired entries could be invalidated when we later use ginvt to | ||
| 82 | * invalidate TLB entries with that MMID. | ||
| 83 | * | ||
| 84 | * In order to prevent ginvt from trashing wired entries, we reserve one MMID | ||
| 85 | * for use by the kernel when creating wired entries. This MMID will never be | ||
| 86 | * assigned to a struct mm, and we'll never target it with a ginvt instruction. | ||
| 87 | */ | ||
| 88 | #define MMID_KERNEL_WIRED 0 | ||
| 89 | |||
| 90 | /* | ||
| 76 | * All unused by hardware upper bits will be considered | 91 | * All unused by hardware upper bits will be considered |
| 77 | * as a software asid extension. | 92 | * as a software asid extension. |
| 78 | */ | 93 | */ |
| @@ -88,7 +103,23 @@ static inline u64 asid_first_version(unsigned int cpu) | |||
| 88 | return ~asid_version_mask(cpu) + 1; | 103 | return ~asid_version_mask(cpu) + 1; |
| 89 | } | 104 | } |
| 90 | 105 | ||
| 91 | #define cpu_context(cpu, mm) ((mm)->context.asid[cpu]) | 106 | static inline u64 cpu_context(unsigned int cpu, const struct mm_struct *mm) |
| 107 | { | ||
| 108 | if (cpu_has_mmid) | ||
| 109 | return atomic64_read(&mm->context.mmid); | ||
| 110 | |||
| 111 | return mm->context.asid[cpu]; | ||
| 112 | } | ||
| 113 | |||
| 114 | static inline void set_cpu_context(unsigned int cpu, | ||
| 115 | struct mm_struct *mm, u64 ctx) | ||
| 116 | { | ||
| 117 | if (cpu_has_mmid) | ||
| 118 | atomic64_set(&mm->context.mmid, ctx); | ||
| 119 | else | ||
| 120 | mm->context.asid[cpu] = ctx; | ||
| 121 | } | ||
| 122 | |||
| 92 | #define asid_cache(cpu) (cpu_data[cpu].asid_cache) | 123 | #define asid_cache(cpu) (cpu_data[cpu].asid_cache) |
| 93 | #define cpu_asid(cpu, mm) \ | 124 | #define cpu_asid(cpu, mm) \ |
| 94 | (cpu_context((cpu), (mm)) & cpu_asid_mask(&cpu_data[cpu])) | 125 | (cpu_context((cpu), (mm)) & cpu_asid_mask(&cpu_data[cpu])) |
| @@ -97,21 +128,9 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) | |||
| 97 | { | 128 | { |
| 98 | } | 129 | } |
| 99 | 130 | ||
| 100 | 131 | extern void get_new_mmu_context(struct mm_struct *mm); | |
| 101 | /* Normal, classic MIPS get_new_mmu_context */ | 132 | extern void check_mmu_context(struct mm_struct *mm); |
| 102 | static inline void | 133 | extern void check_switch_mmu_context(struct mm_struct *mm); |
| 103 | get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) | ||
| 104 | { | ||
| 105 | u64 asid = asid_cache(cpu); | ||
| 106 | |||
| 107 | if (!((asid += cpu_asid_inc()) & cpu_asid_mask(&cpu_data[cpu]))) { | ||
| 108 | if (cpu_has_vtag_icache) | ||
| 109 | flush_icache_all(); | ||
| 110 | local_flush_tlb_all(); /* start new asid cycle */ | ||
| 111 | } | ||
| 112 | |||
| 113 | cpu_context(cpu, mm) = asid_cache(cpu) = asid; | ||
| 114 | } | ||
| 115 | 134 | ||
| 116 | /* | 135 | /* |
| 117 | * Initialize the context related info for a new mm_struct | 136 | * Initialize the context related info for a new mm_struct |
| @@ -122,8 +141,12 @@ init_new_context(struct task_struct *tsk, struct mm_struct *mm) | |||
| 122 | { | 141 | { |
| 123 | int i; | 142 | int i; |
| 124 | 143 | ||
| 125 | for_each_possible_cpu(i) | 144 | if (cpu_has_mmid) { |
| 126 | cpu_context(i, mm) = 0; | 145 | set_cpu_context(0, mm, 0); |
| 146 | } else { | ||
| 147 | for_each_possible_cpu(i) | ||
| 148 | set_cpu_context(i, mm, 0); | ||
| 149 | } | ||
| 127 | 150 | ||
| 128 | mm->context.bd_emupage_allocmap = NULL; | 151 | mm->context.bd_emupage_allocmap = NULL; |
| 129 | spin_lock_init(&mm->context.bd_emupage_lock); | 152 | spin_lock_init(&mm->context.bd_emupage_lock); |
| @@ -140,11 +163,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | |||
| 140 | local_irq_save(flags); | 163 | local_irq_save(flags); |
| 141 | 164 | ||
| 142 | htw_stop(); | 165 | htw_stop(); |
| 143 | /* Check if our ASID is of an older version and thus invalid */ | 166 | check_switch_mmu_context(next); |
| 144 | if ((cpu_context(cpu, next) ^ asid_cache(cpu)) & asid_version_mask(cpu)) | ||
| 145 | get_new_mmu_context(next, cpu); | ||
| 146 | write_c0_entryhi(cpu_asid(cpu, next)); | ||
| 147 | TLBMISS_HANDLER_SETUP_PGD(next->pgd); | ||
| 148 | 167 | ||
| 149 | /* | 168 | /* |
| 150 | * Mark current->active_mm as not "active" anymore. | 169 | * Mark current->active_mm as not "active" anymore. |
| @@ -166,55 +185,55 @@ static inline void destroy_context(struct mm_struct *mm) | |||
| 166 | dsemul_mm_cleanup(mm); | 185 | dsemul_mm_cleanup(mm); |
| 167 | } | 186 | } |
| 168 | 187 | ||
| 188 | #define activate_mm(prev, next) switch_mm(prev, next, current) | ||
| 169 | #define deactivate_mm(tsk, mm) do { } while (0) | 189 | #define deactivate_mm(tsk, mm) do { } while (0) |
| 170 | 190 | ||
| 171 | /* | ||
| 172 | * After we have set current->mm to a new value, this activates | ||
| 173 | * the context for the new mm so we see the new mappings. | ||
| 174 | */ | ||
| 175 | static inline void | ||
| 176 | activate_mm(struct mm_struct *prev, struct mm_struct *next) | ||
| 177 | { | ||
| 178 | unsigned long flags; | ||
| 179 | unsigned int cpu = smp_processor_id(); | ||
| 180 | |||
| 181 | local_irq_save(flags); | ||
| 182 | |||
| 183 | htw_stop(); | ||
| 184 | /* Unconditionally get a new ASID. */ | ||
| 185 | get_new_mmu_context(next, cpu); | ||
| 186 | |||
| 187 | write_c0_entryhi(cpu_asid(cpu, next)); | ||
| 188 | TLBMISS_HANDLER_SETUP_PGD(next->pgd); | ||
| 189 | |||
| 190 | /* mark mmu ownership change */ | ||
| 191 | cpumask_clear_cpu(cpu, mm_cpumask(prev)); | ||
| 192 | cpumask_set_cpu(cpu, mm_cpumask(next)); | ||
| 193 | htw_start(); | ||
| 194 | |||
| 195 | local_irq_restore(flags); | ||
| 196 | } | ||
| 197 | |||
| 198 | /* | ||
| 199 | * If mm is currently active_mm, we can't really drop it. Instead, | ||
| 200 | * we will get a new one for it. | ||
| 201 | */ | ||
| 202 | static inline void | 191 | static inline void |
| 203 | drop_mmu_context(struct mm_struct *mm, unsigned cpu) | 192 | drop_mmu_context(struct mm_struct *mm) |
| 204 | { | 193 | { |
| 205 | unsigned long flags; | 194 | unsigned long flags; |
| 195 | unsigned int cpu; | ||
| 196 | u32 old_mmid; | ||
| 197 | u64 ctx; | ||
| 206 | 198 | ||
| 207 | local_irq_save(flags); | 199 | local_irq_save(flags); |
| 208 | htw_stop(); | ||
| 209 | 200 | ||
| 210 | if (cpumask_test_cpu(cpu, mm_cpumask(mm))) { | 201 | cpu = smp_processor_id(); |
| 211 | get_new_mmu_context(mm, cpu); | 202 | ctx = cpu_context(cpu, mm); |
| 203 | |||
| 204 | if (!ctx) { | ||
| 205 | /* no-op */ | ||
| 206 | } else if (cpu_has_mmid) { | ||
| 207 | /* | ||
| 208 | * Globally invalidating TLB entries associated with the MMID | ||
| 209 | * is pretty cheap using the GINVT instruction, so we'll do | ||
| 210 | * that rather than incur the overhead of allocating a new | ||
| 211 | * MMID. The latter would be especially difficult since MMIDs | ||
| 212 | * are global & other CPUs may be actively using ctx. | ||
| 213 | */ | ||
| 214 | htw_stop(); | ||
| 215 | old_mmid = read_c0_memorymapid(); | ||
| 216 | write_c0_memorymapid(ctx & cpu_asid_mask(&cpu_data[cpu])); | ||
| 217 | mtc0_tlbw_hazard(); | ||
| 218 | ginvt_mmid(); | ||
| 219 | sync_ginv(); | ||
| 220 | write_c0_memorymapid(old_mmid); | ||
| 221 | instruction_hazard(); | ||
| 222 | htw_start(); | ||
| 223 | } else if (cpumask_test_cpu(cpu, mm_cpumask(mm))) { | ||
| 224 | /* | ||
| 225 | * mm is currently active, so we can't really drop it. | ||
| 226 | * Instead we bump the ASID. | ||
| 227 | */ | ||
| 228 | htw_stop(); | ||
| 229 | get_new_mmu_context(mm); | ||
| 212 | write_c0_entryhi(cpu_asid(cpu, mm)); | 230 | write_c0_entryhi(cpu_asid(cpu, mm)); |
| 231 | htw_start(); | ||
| 213 | } else { | 232 | } else { |
| 214 | /* will get a new context next time */ | 233 | /* will get a new context next time */ |
| 215 | cpu_context(cpu, mm) = 0; | 234 | set_cpu_context(cpu, mm, 0); |
| 216 | } | 235 | } |
| 217 | htw_start(); | 236 | |
| 218 | local_irq_restore(flags); | 237 | local_irq_restore(flags); |
| 219 | } | 238 | } |
| 220 | 239 | ||
diff --git a/arch/mips/include/asm/octeon/cvmx-helper-board.h b/arch/mips/include/asm/octeon/cvmx-helper-board.h index b4d19c21b62c..d7fdcf0a0088 100644 --- a/arch/mips/include/asm/octeon/cvmx-helper-board.h +++ b/arch/mips/include/asm/octeon/cvmx-helper-board.h | |||
| @@ -119,18 +119,6 @@ extern cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port); | |||
| 119 | extern int __cvmx_helper_board_interface_probe(int interface, | 119 | extern int __cvmx_helper_board_interface_probe(int interface, |
| 120 | int supported_ports); | 120 | int supported_ports); |
| 121 | 121 | ||
| 122 | /** | ||
| 123 | * Enable packet input/output from the hardware. This function is | ||
| 124 | * called after by cvmx_helper_packet_hardware_enable() to | ||
| 125 | * perform board specific initialization. For most boards | ||
| 126 | * nothing is needed. | ||
| 127 | * | ||
| 128 | * @interface: Interface to enable | ||
| 129 | * | ||
| 130 | * Returns Zero on success, negative on failure | ||
| 131 | */ | ||
| 132 | extern int __cvmx_helper_board_hardware_enable(int interface); | ||
| 133 | |||
| 134 | enum cvmx_helper_board_usb_clock_types __cvmx_helper_board_usb_get_clock_type(void); | 122 | enum cvmx_helper_board_usb_clock_types __cvmx_helper_board_usb_get_clock_type(void); |
| 135 | 123 | ||
| 136 | #endif /* __CVMX_HELPER_BOARD_H__ */ | 124 | #endif /* __CVMX_HELPER_BOARD_H__ */ |
diff --git a/arch/mips/include/asm/octeon/cvmx-smix-defs.h b/arch/mips/include/asm/octeon/cvmx-smix-defs.h deleted file mode 100644 index 7a928230b0c0..000000000000 --- a/arch/mips/include/asm/octeon/cvmx-smix-defs.h +++ /dev/null | |||
| @@ -1,276 +0,0 @@ | |||
| 1 | /***********************license start*************** | ||
| 2 | * Author: Cavium Networks | ||
| 3 | * | ||
| 4 | * Contact: support@caviumnetworks.com | ||
| 5 | * This file is part of the OCTEON SDK | ||
| 6 | * | ||
| 7 | * Copyright (c) 2003-2012 Cavium Networks | ||
| 8 | * | ||
| 9 | * This file is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License, Version 2, as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | * | ||
| 13 | * This file is distributed in the hope that it will be useful, but | ||
| 14 | * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty | ||
| 15 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or | ||
| 16 | * NONINFRINGEMENT. See the GNU General Public License for more | ||
| 17 | * details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this file; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 22 | * or visit http://www.gnu.org/licenses/. | ||
| 23 | * | ||
| 24 | * This file may also be available under a different license from Cavium. | ||
| 25 | * Contact Cavium Networks for more information | ||
| 26 | ***********************license end**************************************/ | ||
| 27 | |||
| 28 | #ifndef __CVMX_SMIX_DEFS_H__ | ||
| 29 | #define __CVMX_SMIX_DEFS_H__ | ||
| 30 | |||
| 31 | static inline uint64_t CVMX_SMIX_CLK(unsigned long offset) | ||
| 32 | { | ||
| 33 | switch (cvmx_get_octeon_family()) { | ||
| 34 | case OCTEON_CN30XX & OCTEON_FAMILY_MASK: | ||
| 35 | case OCTEON_CN50XX & OCTEON_FAMILY_MASK: | ||
| 36 | case OCTEON_CN38XX & OCTEON_FAMILY_MASK: | ||
| 37 | case OCTEON_CN31XX & OCTEON_FAMILY_MASK: | ||
| 38 | case OCTEON_CN58XX & OCTEON_FAMILY_MASK: | ||
| 39 | return CVMX_ADD_IO_SEG(0x0001180000001818ull) + (offset) * 256; | ||
| 40 | case OCTEON_CNF71XX & OCTEON_FAMILY_MASK: | ||
| 41 | case OCTEON_CN61XX & OCTEON_FAMILY_MASK: | ||
| 42 | case OCTEON_CN56XX & OCTEON_FAMILY_MASK: | ||
| 43 | case OCTEON_CN66XX & OCTEON_FAMILY_MASK: | ||
| 44 | case OCTEON_CN52XX & OCTEON_FAMILY_MASK: | ||
| 45 | case OCTEON_CN63XX & OCTEON_FAMILY_MASK: | ||
| 46 | return CVMX_ADD_IO_SEG(0x0001180000001818ull) + (offset) * 256; | ||
| 47 | case OCTEON_CN68XX & OCTEON_FAMILY_MASK: | ||
| 48 | return CVMX_ADD_IO_SEG(0x0001180000003818ull) + (offset) * 128; | ||
| 49 | } | ||
| 50 | return CVMX_ADD_IO_SEG(0x0001180000001818ull) + (offset) * 256; | ||
| 51 | } | ||
| 52 | |||
| 53 | static inline uint64_t CVMX_SMIX_CMD(unsigned long offset) | ||
| 54 | { | ||
| 55 | switch (cvmx_get_octeon_family()) { | ||
| 56 | case OCTEON_CN30XX & OCTEON_FAMILY_MASK: | ||
| 57 | case OCTEON_CN50XX & OCTEON_FAMILY_MASK: | ||
| 58 | case OCTEON_CN38XX & OCTEON_FAMILY_MASK: | ||
| 59 | case OCTEON_CN31XX & OCTEON_FAMILY_MASK: | ||
| 60 | case OCTEON_CN58XX & OCTEON_FAMILY_MASK: | ||
| 61 | return CVMX_ADD_IO_SEG(0x0001180000001800ull) + (offset) * 256; | ||
| 62 | case OCTEON_CNF71XX & OCTEON_FAMILY_MASK: | ||
| 63 | case OCTEON_CN61XX & OCTEON_FAMILY_MASK: | ||
| 64 | case OCTEON_CN56XX & OCTEON_FAMILY_MASK: | ||
| 65 | case OCTEON_CN66XX & OCTEON_FAMILY_MASK: | ||
| 66 | case OCTEON_CN52XX & OCTEON_FAMILY_MASK: | ||
| 67 | case OCTEON_CN63XX & OCTEON_FAMILY_MASK: | ||
| 68 | return CVMX_ADD_IO_SEG(0x0001180000001800ull) + (offset) * 256; | ||
| 69 | case OCTEON_CN68XX & OCTEON_FAMILY_MASK: | ||
| 70 | return CVMX_ADD_IO_SEG(0x0001180000003800ull) + (offset) * 128; | ||
| 71 | } | ||
| 72 | return CVMX_ADD_IO_SEG(0x0001180000001800ull) + (offset) * 256; | ||
| 73 | } | ||
| 74 | |||
| 75 | static inline uint64_t CVMX_SMIX_EN(unsigned long offset) | ||
| 76 | { | ||
| 77 | switch (cvmx_get_octeon_family()) { | ||
| 78 | case OCTEON_CN30XX & OCTEON_FAMILY_MASK: | ||
| 79 | case OCTEON_CN50XX & OCTEON_FAMILY_MASK: | ||
| 80 | case OCTEON_CN38XX & OCTEON_FAMILY_MASK: | ||
| 81 | case OCTEON_CN31XX & OCTEON_FAMILY_MASK: | ||
| 82 | case OCTEON_CN58XX & OCTEON_FAMILY_MASK: | ||
| 83 | return CVMX_ADD_IO_SEG(0x0001180000001820ull) + (offset) * 256; | ||
| 84 | case OCTEON_CNF71XX & OCTEON_FAMILY_MASK: | ||
| 85 | case OCTEON_CN61XX & OCTEON_FAMILY_MASK: | ||
| 86 | case OCTEON_CN56XX & OCTEON_FAMILY_MASK: | ||
| 87 | case OCTEON_CN66XX & OCTEON_FAMILY_MASK: | ||
| 88 | case OCTEON_CN52XX & OCTEON_FAMILY_MASK: | ||
| 89 | case OCTEON_CN63XX & OCTEON_FAMILY_MASK: | ||
| 90 | return CVMX_ADD_IO_SEG(0x0001180000001820ull) + (offset) * 256; | ||
| 91 | case OCTEON_CN68XX & OCTEON_FAMILY_MASK: | ||
| 92 | return CVMX_ADD_IO_SEG(0x0001180000003820ull) + (offset) * 128; | ||
| 93 | } | ||
| 94 | return CVMX_ADD_IO_SEG(0x0001180000001820ull) + (offset) * 256; | ||
| 95 | } | ||
| 96 | |||
| 97 | static inline uint64_t CVMX_SMIX_RD_DAT(unsigned long offset) | ||
| 98 | { | ||
| 99 | switch (cvmx_get_octeon_family()) { | ||
| 100 | case OCTEON_CN30XX & OCTEON_FAMILY_MASK: | ||
| 101 | case OCTEON_CN50XX & OCTEON_FAMILY_MASK: | ||
| 102 | case OCTEON_CN38XX & OCTEON_FAMILY_MASK: | ||
| 103 | case OCTEON_CN31XX & OCTEON_FAMILY_MASK: | ||
| 104 | case OCTEON_CN58XX & OCTEON_FAMILY_MASK: | ||
| 105 | return CVMX_ADD_IO_SEG(0x0001180000001810ull) + (offset) * 256; | ||
| 106 | case OCTEON_CNF71XX & OCTEON_FAMILY_MASK: | ||
| 107 | case OCTEON_CN61XX & OCTEON_FAMILY_MASK: | ||
| 108 | case OCTEON_CN56XX & OCTEON_FAMILY_MASK: | ||
| 109 | case OCTEON_CN66XX & OCTEON_FAMILY_MASK: | ||
| 110 | case OCTEON_CN52XX & OCTEON_FAMILY_MASK: | ||
| 111 | case OCTEON_CN63XX & OCTEON_FAMILY_MASK: | ||
| 112 | return CVMX_ADD_IO_SEG(0x0001180000001810ull) + (offset) * 256; | ||
| 113 | case OCTEON_CN68XX & OCTEON_FAMILY_MASK: | ||
| 114 | return CVMX_ADD_IO_SEG(0x0001180000003810ull) + (offset) * 128; | ||
| 115 | } | ||
| 116 | return CVMX_ADD_IO_SEG(0x0001180000001810ull) + (offset) * 256; | ||
| 117 | } | ||
| 118 | |||
| 119 | static inline uint64_t CVMX_SMIX_WR_DAT(unsigned long offset) | ||
| 120 | { | ||
| 121 | switch (cvmx_get_octeon_family()) { | ||
| 122 | case OCTEON_CN30XX & OCTEON_FAMILY_MASK: | ||
| 123 | case OCTEON_CN50XX & OCTEON_FAMILY_MASK: | ||
| 124 | case OCTEON_CN38XX & OCTEON_FAMILY_MASK: | ||
| 125 | case OCTEON_CN31XX & OCTEON_FAMILY_MASK: | ||
| 126 | case OCTEON_CN58XX & OCTEON_FAMILY_MASK: | ||
| 127 | return CVMX_ADD_IO_SEG(0x0001180000001808ull) + (offset) * 256; | ||
| 128 | case OCTEON_CNF71XX & OCTEON_FAMILY_MASK: | ||
| 129 | case OCTEON_CN61XX & OCTEON_FAMILY_MASK: | ||
| 130 | case OCTEON_CN56XX & OCTEON_FAMILY_MASK: | ||
| 131 | case OCTEON_CN66XX & OCTEON_FAMILY_MASK: | ||
| 132 | case OCTEON_CN52XX & OCTEON_FAMILY_MASK: | ||
| 133 | case OCTEON_CN63XX & OCTEON_FAMILY_MASK: | ||
| 134 | return CVMX_ADD_IO_SEG(0x0001180000001808ull) + (offset) * 256; | ||
| 135 | case OCTEON_CN68XX & OCTEON_FAMILY_MASK: | ||
| 136 | return CVMX_ADD_IO_SEG(0x0001180000003808ull) + (offset) * 128; | ||
| 137 | } | ||
| 138 | return CVMX_ADD_IO_SEG(0x0001180000001808ull) + (offset) * 256; | ||
| 139 | } | ||
| 140 | |||
| 141 | union cvmx_smix_clk { | ||
| 142 | uint64_t u64; | ||
| 143 | struct cvmx_smix_clk_s { | ||
| 144 | #ifdef __BIG_ENDIAN_BITFIELD | ||
| 145 | uint64_t reserved_25_63:39; | ||
| 146 | uint64_t mode:1; | ||
| 147 | uint64_t reserved_21_23:3; | ||
| 148 | uint64_t sample_hi:5; | ||
| 149 | uint64_t sample_mode:1; | ||
| 150 | uint64_t reserved_14_14:1; | ||
| 151 | uint64_t clk_idle:1; | ||
| 152 | uint64_t preamble:1; | ||
| 153 | uint64_t sample:4; | ||
| 154 | uint64_t phase:8; | ||
| 155 | #else | ||
| 156 | uint64_t phase:8; | ||
| 157 | uint64_t sample:4; | ||
| 158 | uint64_t preamble:1; | ||
| 159 | uint64_t clk_idle:1; | ||
| 160 | uint64_t reserved_14_14:1; | ||
| 161 | uint64_t sample_mode:1; | ||
| 162 | uint64_t sample_hi:5; | ||
| 163 | uint64_t reserved_21_23:3; | ||
| 164 | uint64_t mode:1; | ||
| 165 | uint64_t reserved_25_63:39; | ||
| 166 | #endif | ||
| 167 | } s; | ||
| 168 | struct cvmx_smix_clk_cn30xx { | ||
| 169 | #ifdef __BIG_ENDIAN_BITFIELD | ||
| 170 | uint64_t reserved_21_63:43; | ||
| 171 | uint64_t sample_hi:5; | ||
| 172 | uint64_t sample_mode:1; | ||
| 173 | uint64_t reserved_14_14:1; | ||
| 174 | uint64_t clk_idle:1; | ||
| 175 | uint64_t preamble:1; | ||
| 176 | uint64_t sample:4; | ||
| 177 | uint64_t phase:8; | ||
| 178 | #else | ||
| 179 | uint64_t phase:8; | ||
| 180 | uint64_t sample:4; | ||
| 181 | uint64_t preamble:1; | ||
| 182 | uint64_t clk_idle:1; | ||
| 183 | uint64_t reserved_14_14:1; | ||
| 184 | uint64_t sample_mode:1; | ||
| 185 | uint64_t sample_hi:5; | ||
| 186 | uint64_t reserved_21_63:43; | ||
| 187 | #endif | ||
| 188 | } cn30xx; | ||
| 189 | }; | ||
| 190 | |||
| 191 | union cvmx_smix_cmd { | ||
| 192 | uint64_t u64; | ||
| 193 | struct cvmx_smix_cmd_s { | ||
| 194 | #ifdef __BIG_ENDIAN_BITFIELD | ||
| 195 | uint64_t reserved_18_63:46; | ||
| 196 | uint64_t phy_op:2; | ||
| 197 | uint64_t reserved_13_15:3; | ||
| 198 | uint64_t phy_adr:5; | ||
| 199 | uint64_t reserved_5_7:3; | ||
| 200 | uint64_t reg_adr:5; | ||
| 201 | #else | ||
| 202 | uint64_t reg_adr:5; | ||
| 203 | uint64_t reserved_5_7:3; | ||
| 204 | uint64_t phy_adr:5; | ||
| 205 | uint64_t reserved_13_15:3; | ||
| 206 | uint64_t phy_op:2; | ||
| 207 | uint64_t reserved_18_63:46; | ||
| 208 | #endif | ||
| 209 | } s; | ||
| 210 | struct cvmx_smix_cmd_cn30xx { | ||
| 211 | #ifdef __BIG_ENDIAN_BITFIELD | ||
| 212 | uint64_t reserved_17_63:47; | ||
| 213 | uint64_t phy_op:1; | ||
| 214 | uint64_t reserved_13_15:3; | ||
| 215 | uint64_t phy_adr:5; | ||
| 216 | uint64_t reserved_5_7:3; | ||
| 217 | uint64_t reg_adr:5; | ||
| 218 | #else | ||
| 219 | uint64_t reg_adr:5; | ||
| 220 | uint64_t reserved_5_7:3; | ||
| 221 | uint64_t phy_adr:5; | ||
| 222 | uint64_t reserved_13_15:3; | ||
| 223 | uint64_t phy_op:1; | ||
| 224 | uint64_t reserved_17_63:47; | ||
| 225 | #endif | ||
| 226 | } cn30xx; | ||
| 227 | }; | ||
| 228 | |||
| 229 | union cvmx_smix_en { | ||
| 230 | uint64_t u64; | ||
| 231 | struct cvmx_smix_en_s { | ||
| 232 | #ifdef __BIG_ENDIAN_BITFIELD | ||
| 233 | uint64_t reserved_1_63:63; | ||
| 234 | uint64_t en:1; | ||
| 235 | #else | ||
| 236 | uint64_t en:1; | ||
| 237 | uint64_t reserved_1_63:63; | ||
| 238 | #endif | ||
| 239 | } s; | ||
| 240 | }; | ||
| 241 | |||
| 242 | union cvmx_smix_rd_dat { | ||
| 243 | uint64_t u64; | ||
| 244 | struct cvmx_smix_rd_dat_s { | ||
| 245 | #ifdef __BIG_ENDIAN_BITFIELD | ||
| 246 | uint64_t reserved_18_63:46; | ||
| 247 | uint64_t pending:1; | ||
| 248 | uint64_t val:1; | ||
| 249 | uint64_t dat:16; | ||
| 250 | #else | ||
| 251 | uint64_t dat:16; | ||
| 252 | uint64_t val:1; | ||
| 253 | uint64_t pending:1; | ||
| 254 | uint64_t reserved_18_63:46; | ||
| 255 | #endif | ||
| 256 | } s; | ||
| 257 | }; | ||
| 258 | |||
| 259 | union cvmx_smix_wr_dat { | ||
| 260 | uint64_t u64; | ||
| 261 | struct cvmx_smix_wr_dat_s { | ||
| 262 | #ifdef __BIG_ENDIAN_BITFIELD | ||
| 263 | uint64_t reserved_18_63:46; | ||
| 264 | uint64_t pending:1; | ||
| 265 | uint64_t val:1; | ||
| 266 | uint64_t dat:16; | ||
| 267 | #else | ||
| 268 | uint64_t dat:16; | ||
| 269 | uint64_t val:1; | ||
| 270 | uint64_t pending:1; | ||
| 271 | uint64_t reserved_18_63:46; | ||
| 272 | #endif | ||
| 273 | } s; | ||
| 274 | }; | ||
| 275 | |||
| 276 | #endif | ||
diff --git a/arch/mips/include/asm/pci/bridge.h b/arch/mips/include/asm/pci/bridge.h index 3206245d1ed6..23574c27eb40 100644 --- a/arch/mips/include/asm/pci/bridge.h +++ b/arch/mips/include/asm/pci/bridge.h | |||
| @@ -45,18 +45,21 @@ | |||
| 45 | 45 | ||
| 46 | #ifndef __ASSEMBLY__ | 46 | #ifndef __ASSEMBLY__ |
| 47 | 47 | ||
| 48 | /* | 48 | #define ATE_V 0x01 |
| 49 | * All accesses to bridge hardware registers must be done | 49 | #define ATE_CO 0x02 |
| 50 | * using 32-bit loads and stores. | 50 | #define ATE_PREC 0x04 |
| 51 | */ | 51 | #define ATE_PREF 0x08 |
| 52 | typedef u32 bridgereg_t; | 52 | #define ATE_BAR 0x10 |
| 53 | |||
| 54 | #define ATE_PFNSHIFT 12 | ||
| 55 | #define ATE_TIDSHIFT 8 | ||
| 56 | #define ATE_RMFSHIFT 48 | ||
| 53 | 57 | ||
| 54 | typedef u64 bridge_ate_t; | 58 | #define mkate(xaddr, xid, attr) (((xaddr) & 0x0000fffffffff000ULL) | \ |
| 59 | ((xid)<<ATE_TIDSHIFT) | \ | ||
| 60 | (attr)) | ||
| 55 | 61 | ||
| 56 | /* pointers to bridge ATEs | 62 | #define BRIDGE_INTERNAL_ATES 128 |
| 57 | * are always "pointer to volatile" | ||
| 58 | */ | ||
| 59 | typedef volatile bridge_ate_t *bridge_ate_p; | ||
| 60 | 63 | ||
| 61 | /* | 64 | /* |
| 62 | * It is generally preferred that hardware registers on the bridge | 65 | * It is generally preferred that hardware registers on the bridge |
| @@ -65,7 +68,7 @@ typedef volatile bridge_ate_t *bridge_ate_p; | |||
| 65 | * Generated from Bridge spec dated 04oct95 | 68 | * Generated from Bridge spec dated 04oct95 |
| 66 | */ | 69 | */ |
| 67 | 70 | ||
| 68 | typedef volatile struct bridge_s { | 71 | struct bridge_regs { |
| 69 | /* Local Registers 0x000000-0x00FFFF */ | 72 | /* Local Registers 0x000000-0x00FFFF */ |
| 70 | 73 | ||
| 71 | /* standard widget configuration 0x000000-0x000057 */ | 74 | /* standard widget configuration 0x000000-0x000057 */ |
| @@ -86,105 +89,105 @@ typedef volatile struct bridge_s { | |||
| 86 | #define b_wid_tflush b_widget.w_tflush | 89 | #define b_wid_tflush b_widget.w_tflush |
| 87 | 90 | ||
| 88 | /* bridge-specific widget configuration 0x000058-0x00007F */ | 91 | /* bridge-specific widget configuration 0x000058-0x00007F */ |
| 89 | bridgereg_t _pad_000058; | 92 | u32 _pad_000058; |
| 90 | bridgereg_t b_wid_aux_err; /* 0x00005C */ | 93 | u32 b_wid_aux_err; /* 0x00005C */ |
| 91 | bridgereg_t _pad_000060; | 94 | u32 _pad_000060; |
| 92 | bridgereg_t b_wid_resp_upper; /* 0x000064 */ | 95 | u32 b_wid_resp_upper; /* 0x000064 */ |
| 93 | bridgereg_t _pad_000068; | 96 | u32 _pad_000068; |
| 94 | bridgereg_t b_wid_resp_lower; /* 0x00006C */ | 97 | u32 b_wid_resp_lower; /* 0x00006C */ |
| 95 | bridgereg_t _pad_000070; | 98 | u32 _pad_000070; |
| 96 | bridgereg_t b_wid_tst_pin_ctrl; /* 0x000074 */ | 99 | u32 b_wid_tst_pin_ctrl; /* 0x000074 */ |
| 97 | bridgereg_t _pad_000078[2]; | 100 | u32 _pad_000078[2]; |
| 98 | 101 | ||
| 99 | /* PMU & Map 0x000080-0x00008F */ | 102 | /* PMU & Map 0x000080-0x00008F */ |
| 100 | bridgereg_t _pad_000080; | 103 | u32 _pad_000080; |
| 101 | bridgereg_t b_dir_map; /* 0x000084 */ | 104 | u32 b_dir_map; /* 0x000084 */ |
| 102 | bridgereg_t _pad_000088[2]; | 105 | u32 _pad_000088[2]; |
| 103 | 106 | ||
| 104 | /* SSRAM 0x000090-0x00009F */ | 107 | /* SSRAM 0x000090-0x00009F */ |
| 105 | bridgereg_t _pad_000090; | 108 | u32 _pad_000090; |
| 106 | bridgereg_t b_ram_perr; /* 0x000094 */ | 109 | u32 b_ram_perr; /* 0x000094 */ |
| 107 | bridgereg_t _pad_000098[2]; | 110 | u32 _pad_000098[2]; |
| 108 | 111 | ||
| 109 | /* Arbitration 0x0000A0-0x0000AF */ | 112 | /* Arbitration 0x0000A0-0x0000AF */ |
| 110 | bridgereg_t _pad_0000A0; | 113 | u32 _pad_0000A0; |
| 111 | bridgereg_t b_arb; /* 0x0000A4 */ | 114 | u32 b_arb; /* 0x0000A4 */ |
| 112 | bridgereg_t _pad_0000A8[2]; | 115 | u32 _pad_0000A8[2]; |
| 113 | 116 | ||
| 114 | /* Number In A Can 0x0000B0-0x0000BF */ | 117 | /* Number In A Can 0x0000B0-0x0000BF */ |
| 115 | bridgereg_t _pad_0000B0; | 118 | u32 _pad_0000B0; |
| 116 | bridgereg_t b_nic; /* 0x0000B4 */ | 119 | u32 b_nic; /* 0x0000B4 */ |
| 117 | bridgereg_t _pad_0000B8[2]; | 120 | u32 _pad_0000B8[2]; |
| 118 | 121 | ||
| 119 | /* PCI/GIO 0x0000C0-0x0000FF */ | 122 | /* PCI/GIO 0x0000C0-0x0000FF */ |
| 120 | bridgereg_t _pad_0000C0; | 123 | u32 _pad_0000C0; |
| 121 | bridgereg_t b_bus_timeout; /* 0x0000C4 */ | 124 | u32 b_bus_timeout; /* 0x0000C4 */ |
| 122 | #define b_pci_bus_timeout b_bus_timeout | 125 | #define b_pci_bus_timeout b_bus_timeout |
| 123 | 126 | ||
| 124 | bridgereg_t _pad_0000C8; | 127 | u32 _pad_0000C8; |
| 125 | bridgereg_t b_pci_cfg; /* 0x0000CC */ | 128 | u32 b_pci_cfg; /* 0x0000CC */ |
| 126 | bridgereg_t _pad_0000D0; | 129 | u32 _pad_0000D0; |
| 127 | bridgereg_t b_pci_err_upper; /* 0x0000D4 */ | 130 | u32 b_pci_err_upper; /* 0x0000D4 */ |
| 128 | bridgereg_t _pad_0000D8; | 131 | u32 _pad_0000D8; |
| 129 | bridgereg_t b_pci_err_lower; /* 0x0000DC */ | 132 | u32 b_pci_err_lower; /* 0x0000DC */ |
| 130 | bridgereg_t _pad_0000E0[8]; | 133 | u32 _pad_0000E0[8]; |
| 131 | #define b_gio_err_lower b_pci_err_lower | 134 | #define b_gio_err_lower b_pci_err_lower |
| 132 | #define b_gio_err_upper b_pci_err_upper | 135 | #define b_gio_err_upper b_pci_err_upper |
| 133 | 136 | ||
| 134 | /* Interrupt 0x000100-0x0001FF */ | 137 | /* Interrupt 0x000100-0x0001FF */ |
| 135 | bridgereg_t _pad_000100; | 138 | u32 _pad_000100; |
| 136 | bridgereg_t b_int_status; /* 0x000104 */ | 139 | u32 b_int_status; /* 0x000104 */ |
| 137 | bridgereg_t _pad_000108; | 140 | u32 _pad_000108; |
| 138 | bridgereg_t b_int_enable; /* 0x00010C */ | 141 | u32 b_int_enable; /* 0x00010C */ |
| 139 | bridgereg_t _pad_000110; | 142 | u32 _pad_000110; |
| 140 | bridgereg_t b_int_rst_stat; /* 0x000114 */ | 143 | u32 b_int_rst_stat; /* 0x000114 */ |
| 141 | bridgereg_t _pad_000118; | 144 | u32 _pad_000118; |
| 142 | bridgereg_t b_int_mode; /* 0x00011C */ | 145 | u32 b_int_mode; /* 0x00011C */ |
| 143 | bridgereg_t _pad_000120; | 146 | u32 _pad_000120; |
| 144 | bridgereg_t b_int_device; /* 0x000124 */ | 147 | u32 b_int_device; /* 0x000124 */ |
| 145 | bridgereg_t _pad_000128; | 148 | u32 _pad_000128; |
| 146 | bridgereg_t b_int_host_err; /* 0x00012C */ | 149 | u32 b_int_host_err; /* 0x00012C */ |
| 147 | 150 | ||
| 148 | struct { | 151 | struct { |
| 149 | bridgereg_t __pad; /* 0x0001{30,,,68} */ | 152 | u32 __pad; /* 0x0001{30,,,68} */ |
| 150 | bridgereg_t addr; /* 0x0001{34,,,6C} */ | 153 | u32 addr; /* 0x0001{34,,,6C} */ |
| 151 | } b_int_addr[8]; /* 0x000130 */ | 154 | } b_int_addr[8]; /* 0x000130 */ |
| 152 | 155 | ||
| 153 | bridgereg_t _pad_000170[36]; | 156 | u32 _pad_000170[36]; |
| 154 | 157 | ||
| 155 | /* Device 0x000200-0x0003FF */ | 158 | /* Device 0x000200-0x0003FF */ |
| 156 | struct { | 159 | struct { |
| 157 | bridgereg_t __pad; /* 0x0002{00,,,38} */ | 160 | u32 __pad; /* 0x0002{00,,,38} */ |
| 158 | bridgereg_t reg; /* 0x0002{04,,,3C} */ | 161 | u32 reg; /* 0x0002{04,,,3C} */ |
| 159 | } b_device[8]; /* 0x000200 */ | 162 | } b_device[8]; /* 0x000200 */ |
| 160 | 163 | ||
| 161 | struct { | 164 | struct { |
| 162 | bridgereg_t __pad; /* 0x0002{40,,,78} */ | 165 | u32 __pad; /* 0x0002{40,,,78} */ |
| 163 | bridgereg_t reg; /* 0x0002{44,,,7C} */ | 166 | u32 reg; /* 0x0002{44,,,7C} */ |
| 164 | } b_wr_req_buf[8]; /* 0x000240 */ | 167 | } b_wr_req_buf[8]; /* 0x000240 */ |
| 165 | 168 | ||
| 166 | struct { | 169 | struct { |
| 167 | bridgereg_t __pad; /* 0x0002{80,,,88} */ | 170 | u32 __pad; /* 0x0002{80,,,88} */ |
| 168 | bridgereg_t reg; /* 0x0002{84,,,8C} */ | 171 | u32 reg; /* 0x0002{84,,,8C} */ |
| 169 | } b_rrb_map[2]; /* 0x000280 */ | 172 | } b_rrb_map[2]; /* 0x000280 */ |
| 170 | #define b_even_resp b_rrb_map[0].reg /* 0x000284 */ | 173 | #define b_even_resp b_rrb_map[0].reg /* 0x000284 */ |
| 171 | #define b_odd_resp b_rrb_map[1].reg /* 0x00028C */ | 174 | #define b_odd_resp b_rrb_map[1].reg /* 0x00028C */ |
| 172 | 175 | ||
| 173 | bridgereg_t _pad_000290; | 176 | u32 _pad_000290; |
| 174 | bridgereg_t b_resp_status; /* 0x000294 */ | 177 | u32 b_resp_status; /* 0x000294 */ |
| 175 | bridgereg_t _pad_000298; | 178 | u32 _pad_000298; |
| 176 | bridgereg_t b_resp_clear; /* 0x00029C */ | 179 | u32 b_resp_clear; /* 0x00029C */ |
| 177 | 180 | ||
| 178 | bridgereg_t _pad_0002A0[24]; | 181 | u32 _pad_0002A0[24]; |
| 179 | 182 | ||
| 180 | char _pad_000300[0x10000 - 0x000300]; | 183 | char _pad_000300[0x10000 - 0x000300]; |
| 181 | 184 | ||
| 182 | /* Internal Address Translation Entry RAM 0x010000-0x0103FF */ | 185 | /* Internal Address Translation Entry RAM 0x010000-0x0103FF */ |
| 183 | union { | 186 | union { |
| 184 | bridge_ate_t wr; /* write-only */ | 187 | u64 wr; /* write-only */ |
| 185 | struct { | 188 | struct { |
| 186 | bridgereg_t _p_pad; | 189 | u32 _p_pad; |
| 187 | bridgereg_t rd; /* read-only */ | 190 | u32 rd; /* read-only */ |
| 188 | } hi; | 191 | } hi; |
| 189 | } b_int_ate_ram[128]; | 192 | } b_int_ate_ram[128]; |
| 190 | 193 | ||
| @@ -192,8 +195,8 @@ typedef volatile struct bridge_s { | |||
| 192 | 195 | ||
| 193 | /* Internal Address Translation Entry RAM LOW 0x011000-0x0113FF */ | 196 | /* Internal Address Translation Entry RAM LOW 0x011000-0x0113FF */ |
| 194 | struct { | 197 | struct { |
| 195 | bridgereg_t _p_pad; | 198 | u32 _p_pad; |
| 196 | bridgereg_t rd; /* read-only */ | 199 | u32 rd; /* read-only */ |
| 197 | } b_int_ate_ram_lo[128]; | 200 | } b_int_ate_ram_lo[128]; |
| 198 | 201 | ||
| 199 | char _pad_011400[0x20000 - 0x011400]; | 202 | char _pad_011400[0x20000 - 0x011400]; |
| @@ -212,7 +215,7 @@ typedef volatile struct bridge_s { | |||
| 212 | } f[8]; | 215 | } f[8]; |
| 213 | } b_type0_cfg_dev[8]; /* 0x020000 */ | 216 | } b_type0_cfg_dev[8]; /* 0x020000 */ |
| 214 | 217 | ||
| 215 | /* PCI Type 1 Configuration Space 0x028000-0x028FFF */ | 218 | /* PCI Type 1 Configuration Space 0x028000-0x028FFF */ |
| 216 | union { /* make all access sizes available. */ | 219 | union { /* make all access sizes available. */ |
| 217 | u8 c[0x1000 / 1]; | 220 | u8 c[0x1000 / 1]; |
| 218 | u16 s[0x1000 / 2]; | 221 | u16 s[0x1000 / 2]; |
| @@ -233,7 +236,7 @@ typedef volatile struct bridge_s { | |||
| 233 | u8 _pad_030007[0x04fff8]; /* 0x030008-0x07FFFF */ | 236 | u8 _pad_030007[0x04fff8]; /* 0x030008-0x07FFFF */ |
| 234 | 237 | ||
| 235 | /* External Address Translation Entry RAM 0x080000-0x0FFFFF */ | 238 | /* External Address Translation Entry RAM 0x080000-0x0FFFFF */ |
| 236 | bridge_ate_t b_ext_ate_ram[0x10000]; | 239 | u64 b_ext_ate_ram[0x10000]; |
| 237 | 240 | ||
| 238 | /* Reserved 0x100000-0x1FFFFF */ | 241 | /* Reserved 0x100000-0x1FFFFF */ |
| 239 | char _pad_100000[0x200000-0x100000]; | 242 | char _pad_100000[0x200000-0x100000]; |
| @@ -259,13 +262,13 @@ typedef volatile struct bridge_s { | |||
| 259 | u32 l[0x400000 / 4]; /* read-only */ | 262 | u32 l[0x400000 / 4]; /* read-only */ |
| 260 | u64 d[0x400000 / 8]; /* read-only */ | 263 | u64 d[0x400000 / 8]; /* read-only */ |
| 261 | } b_external_flash; /* 0xC00000 */ | 264 | } b_external_flash; /* 0xC00000 */ |
| 262 | } bridge_t; | 265 | }; |
| 263 | 266 | ||
| 264 | /* | 267 | /* |
| 265 | * Field formats for Error Command Word and Auxiliary Error Command Word | 268 | * Field formats for Error Command Word and Auxiliary Error Command Word |
| 266 | * of bridge. | 269 | * of bridge. |
| 267 | */ | 270 | */ |
| 268 | typedef struct bridge_err_cmdword_s { | 271 | struct bridge_err_cmdword { |
| 269 | union { | 272 | union { |
| 270 | u32 cmd_word; | 273 | u32 cmd_word; |
| 271 | struct { | 274 | struct { |
| @@ -282,7 +285,7 @@ typedef struct bridge_err_cmdword_s { | |||
| 282 | rsvd:8; | 285 | rsvd:8; |
| 283 | } berr_st; | 286 | } berr_st; |
| 284 | } berr_un; | 287 | } berr_un; |
| 285 | } bridge_err_cmdword_t; | 288 | }; |
| 286 | 289 | ||
| 287 | #define berr_field berr_un.berr_st | 290 | #define berr_field berr_un.berr_st |
| 288 | #endif /* !__ASSEMBLY__ */ | 291 | #endif /* !__ASSEMBLY__ */ |
| @@ -290,7 +293,7 @@ typedef struct bridge_err_cmdword_s { | |||
| 290 | /* | 293 | /* |
| 291 | * The values of these macros can and should be crosschecked | 294 | * The values of these macros can and should be crosschecked |
| 292 | * regularly against the offsets of the like-named fields | 295 | * regularly against the offsets of the like-named fields |
| 293 | * within the "bridge_t" structure above. | 296 | * within the bridge_regs structure above. |
| 294 | */ | 297 | */ |
| 295 | 298 | ||
| 296 | /* Byte offset macros for Bridge internal registers */ | 299 | /* Byte offset macros for Bridge internal registers */ |
| @@ -797,49 +800,14 @@ typedef struct bridge_err_cmdword_s { | |||
| 797 | #define PCI64_ATTR_RMF_MASK 0x00ff000000000000 | 800 | #define PCI64_ATTR_RMF_MASK 0x00ff000000000000 |
| 798 | #define PCI64_ATTR_RMF_SHFT 48 | 801 | #define PCI64_ATTR_RMF_SHFT 48 |
| 799 | 802 | ||
| 800 | #ifndef __ASSEMBLY__ | ||
| 801 | /* Address translation entry for mapped pci32 accesses */ | ||
| 802 | typedef union ate_u { | ||
| 803 | u64 ent; | ||
| 804 | struct ate_s { | ||
| 805 | u64 rmf:16; | ||
| 806 | u64 addr:36; | ||
| 807 | u64 targ:4; | ||
| 808 | u64 reserved:3; | ||
| 809 | u64 barrier:1; | ||
| 810 | u64 prefetch:1; | ||
| 811 | u64 precise:1; | ||
| 812 | u64 coherent:1; | ||
| 813 | u64 valid:1; | ||
| 814 | } field; | ||
| 815 | } ate_t; | ||
| 816 | #endif /* !__ASSEMBLY__ */ | ||
| 817 | |||
| 818 | #define ATE_V 0x01 | ||
| 819 | #define ATE_CO 0x02 | ||
| 820 | #define ATE_PREC 0x04 | ||
| 821 | #define ATE_PREF 0x08 | ||
| 822 | #define ATE_BAR 0x10 | ||
| 823 | |||
| 824 | #define ATE_PFNSHIFT 12 | ||
| 825 | #define ATE_TIDSHIFT 8 | ||
| 826 | #define ATE_RMFSHIFT 48 | ||
| 827 | |||
| 828 | #define mkate(xaddr, xid, attr) ((xaddr) & 0x0000fffffffff000ULL) | \ | ||
| 829 | ((xid)<<ATE_TIDSHIFT) | \ | ||
| 830 | (attr) | ||
| 831 | |||
| 832 | #define BRIDGE_INTERNAL_ATES 128 | ||
| 833 | |||
| 834 | struct bridge_controller { | 803 | struct bridge_controller { |
| 835 | struct pci_controller pc; | 804 | struct pci_controller pc; |
| 836 | struct resource mem; | 805 | struct resource mem; |
| 837 | struct resource io; | 806 | struct resource io; |
| 838 | struct resource busn; | 807 | struct resource busn; |
| 839 | bridge_t *base; | 808 | struct bridge_regs *base; |
| 840 | nasid_t nasid; | 809 | nasid_t nasid; |
| 841 | unsigned int widget_id; | 810 | unsigned int widget_id; |
| 842 | unsigned int irq_cpu; | ||
| 843 | u64 baddr; | 811 | u64 baddr; |
| 844 | unsigned int pci_int[8]; | 812 | unsigned int pci_int[8]; |
| 845 | }; | 813 | }; |
| @@ -847,8 +815,14 @@ struct bridge_controller { | |||
| 847 | #define BRIDGE_CONTROLLER(bus) \ | 815 | #define BRIDGE_CONTROLLER(bus) \ |
| 848 | ((struct bridge_controller *)((bus)->sysdata)) | 816 | ((struct bridge_controller *)((bus)->sysdata)) |
| 849 | 817 | ||
| 850 | extern void register_bridge_irq(unsigned int irq); | 818 | #define bridge_read(bc, reg) __raw_readl(&bc->base->reg) |
| 851 | extern int request_bridge_irq(struct bridge_controller *bc); | 819 | #define bridge_write(bc, reg, val) __raw_writel(val, &bc->base->reg) |
| 820 | #define bridge_set(bc, reg, val) \ | ||
| 821 | __raw_writel(__raw_readl(&bc->base->reg) | (val), &bc->base->reg) | ||
| 822 | #define bridge_clr(bc, reg, val) \ | ||
| 823 | __raw_writel(__raw_readl(&bc->base->reg) & ~(val), &bc->base->reg) | ||
| 824 | |||
| 825 | extern int request_bridge_irq(struct bridge_controller *bc, int pin); | ||
| 852 | 826 | ||
| 853 | extern struct pci_ops bridge_pci_ops; | 827 | extern struct pci_ops bridge_pci_ops; |
| 854 | 828 | ||
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index 910851c62db3..4ccb465ef3f2 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <asm/pgtable-64.h> | 17 | #include <asm/pgtable-64.h> |
| 18 | #endif | 18 | #endif |
| 19 | 19 | ||
| 20 | #include <asm/cmpxchg.h> | ||
| 20 | #include <asm/io.h> | 21 | #include <asm/io.h> |
| 21 | #include <asm/pgtable-bits.h> | 22 | #include <asm/pgtable-bits.h> |
| 22 | 23 | ||
| @@ -204,51 +205,11 @@ static inline void set_pte(pte_t *ptep, pte_t pteval) | |||
| 204 | * Make sure the buddy is global too (if it's !none, | 205 | * Make sure the buddy is global too (if it's !none, |
| 205 | * it better already be global) | 206 | * it better already be global) |
| 206 | */ | 207 | */ |
| 207 | #ifdef CONFIG_SMP | 208 | # if defined(CONFIG_PHYS_ADDR_T_64BIT) && !defined(CONFIG_CPU_MIPS32) |
| 208 | /* | 209 | cmpxchg64(&buddy->pte, 0, _PAGE_GLOBAL); |
| 209 | * For SMP, multiple CPUs can race, so we need to do | 210 | # else |
| 210 | * this atomically. | 211 | cmpxchg(&buddy->pte, 0, _PAGE_GLOBAL); |
| 211 | */ | 212 | # endif |
| 212 | unsigned long page_global = _PAGE_GLOBAL; | ||
| 213 | unsigned long tmp; | ||
| 214 | |||
| 215 | if (kernel_uses_llsc && R10000_LLSC_WAR) { | ||
| 216 | __asm__ __volatile__ ( | ||
| 217 | " .set push \n" | ||
| 218 | " .set arch=r4000 \n" | ||
| 219 | " .set noreorder \n" | ||
| 220 | "1:" __LL "%[tmp], %[buddy] \n" | ||
| 221 | " bnez %[tmp], 2f \n" | ||
| 222 | " or %[tmp], %[tmp], %[global] \n" | ||
| 223 | __SC "%[tmp], %[buddy] \n" | ||
| 224 | " beqzl %[tmp], 1b \n" | ||
| 225 | " nop \n" | ||
| 226 | "2: \n" | ||
| 227 | " .set pop \n" | ||
| 228 | : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp) | ||
| 229 | : [global] "r" (page_global)); | ||
| 230 | } else if (kernel_uses_llsc) { | ||
| 231 | loongson_llsc_mb(); | ||
| 232 | __asm__ __volatile__ ( | ||
| 233 | " .set push \n" | ||
| 234 | " .set "MIPS_ISA_ARCH_LEVEL" \n" | ||
| 235 | " .set noreorder \n" | ||
| 236 | "1:" __LL "%[tmp], %[buddy] \n" | ||
| 237 | " bnez %[tmp], 2f \n" | ||
| 238 | " or %[tmp], %[tmp], %[global] \n" | ||
| 239 | __SC "%[tmp], %[buddy] \n" | ||
| 240 | " beqz %[tmp], 1b \n" | ||
| 241 | " nop \n" | ||
| 242 | "2: \n" | ||
| 243 | " .set pop \n" | ||
| 244 | : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp) | ||
| 245 | : [global] "r" (page_global)); | ||
| 246 | loongson_llsc_mb(); | ||
| 247 | } | ||
| 248 | #else /* !CONFIG_SMP */ | ||
| 249 | if (pte_none(*buddy)) | ||
| 250 | pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL; | ||
| 251 | #endif /* CONFIG_SMP */ | ||
| 252 | } | 213 | } |
| 253 | #endif | 214 | #endif |
| 254 | } | 215 | } |
diff --git a/arch/mips/include/asm/smp-ops.h b/arch/mips/include/asm/smp-ops.h index b7123f9c0785..65618ff1280c 100644 --- a/arch/mips/include/asm/smp-ops.h +++ b/arch/mips/include/asm/smp-ops.h | |||
| @@ -29,6 +29,7 @@ struct plat_smp_ops { | |||
| 29 | int (*boot_secondary)(int cpu, struct task_struct *idle); | 29 | int (*boot_secondary)(int cpu, struct task_struct *idle); |
| 30 | void (*smp_setup)(void); | 30 | void (*smp_setup)(void); |
| 31 | void (*prepare_cpus)(unsigned int max_cpus); | 31 | void (*prepare_cpus)(unsigned int max_cpus); |
| 32 | void (*prepare_boot_cpu)(void); | ||
| 32 | #ifdef CONFIG_HOTPLUG_CPU | 33 | #ifdef CONFIG_HOTPLUG_CPU |
| 33 | int (*cpu_disable)(void); | 34 | int (*cpu_disable)(void); |
| 34 | void (*cpu_die)(unsigned int cpu); | 35 | void (*cpu_die)(unsigned int cpu); |
diff --git a/arch/mips/include/asm/sn/addrs.h b/arch/mips/include/asm/sn/addrs.h index 66814f8ba8e8..837d23e24976 100644 --- a/arch/mips/include/asm/sn/addrs.h +++ b/arch/mips/include/asm/sn/addrs.h | |||
| @@ -27,16 +27,11 @@ | |||
| 27 | 27 | ||
| 28 | #ifndef __ASSEMBLY__ | 28 | #ifndef __ASSEMBLY__ |
| 29 | 29 | ||
| 30 | #define PS_UINT_CAST (unsigned long) | ||
| 31 | #define UINT64_CAST (unsigned long) | 30 | #define UINT64_CAST (unsigned long) |
| 32 | 31 | ||
| 33 | #define HUBREG_CAST (volatile hubreg_t *) | ||
| 34 | |||
| 35 | #else /* __ASSEMBLY__ */ | 32 | #else /* __ASSEMBLY__ */ |
| 36 | 33 | ||
| 37 | #define PS_UINT_CAST | ||
| 38 | #define UINT64_CAST | 34 | #define UINT64_CAST |
| 39 | #define HUBREG_CAST | ||
| 40 | 35 | ||
| 41 | #endif /* __ASSEMBLY__ */ | 36 | #endif /* __ASSEMBLY__ */ |
| 42 | 37 | ||
| @@ -256,42 +251,23 @@ | |||
| 256 | * Otherwise, the recommended approach is to use *_HUB_L() and *_HUB_S(). | 251 | * Otherwise, the recommended approach is to use *_HUB_L() and *_HUB_S(). |
| 257 | * They're always safe. | 252 | * They're always safe. |
| 258 | */ | 253 | */ |
| 259 | #define LOCAL_HUB_ADDR(_x) (HUBREG_CAST (IALIAS_BASE + (_x))) | 254 | #define LOCAL_HUB_ADDR(_x) (IALIAS_BASE + (_x)) |
| 260 | #define REMOTE_HUB_ADDR(_n, _x) (HUBREG_CAST (NODE_SWIN_BASE(_n, 1) + \ | 255 | #define REMOTE_HUB_ADDR(_n, _x) ((NODE_SWIN_BASE(_n, 1) + 0x800000 + (_x))) |
| 261 | 0x800000 + (_x))) | ||
| 262 | #ifdef CONFIG_SGI_IP27 | ||
| 263 | #define REMOTE_HUB_PI_ADDR(_n, _sn, _x) (HUBREG_CAST (NODE_SWIN_BASE(_n, 1) + \ | ||
| 264 | 0x800000 + (_x))) | ||
| 265 | #endif /* CONFIG_SGI_IP27 */ | ||
| 266 | 256 | ||
| 267 | #ifndef __ASSEMBLY__ | 257 | #ifndef __ASSEMBLY__ |
| 268 | 258 | ||
| 269 | #define HUB_L(_a) *(_a) | 259 | #define LOCAL_HUB_PTR(_x) ((u64 *)LOCAL_HUB_ADDR((_x))) |
| 270 | #define HUB_S(_a, _d) *(_a) = (_d) | 260 | #define REMOTE_HUB_PTR(_n, _x) ((u64 *)REMOTE_HUB_ADDR((_n), (_x))) |
| 271 | 261 | ||
| 272 | #define LOCAL_HUB_L(_r) HUB_L(LOCAL_HUB_ADDR(_r)) | 262 | #define LOCAL_HUB_L(_r) __raw_readq(LOCAL_HUB_PTR(_r)) |
| 273 | #define LOCAL_HUB_S(_r, _d) HUB_S(LOCAL_HUB_ADDR(_r), (_d)) | 263 | #define LOCAL_HUB_S(_r, _d) __raw_writeq((_d), LOCAL_HUB_PTR(_r)) |
| 274 | #define REMOTE_HUB_L(_n, _r) HUB_L(REMOTE_HUB_ADDR((_n), (_r))) | 264 | #define REMOTE_HUB_L(_n, _r) __raw_readq(REMOTE_HUB_PTR((_n), (_r))) |
| 275 | #define REMOTE_HUB_S(_n, _r, _d) HUB_S(REMOTE_HUB_ADDR((_n), (_r)), (_d)) | 265 | #define REMOTE_HUB_S(_n, _r, _d) __raw_writeq((_d), \ |
| 276 | #define REMOTE_HUB_PI_L(_n, _sn, _r) HUB_L(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r))) | 266 | REMOTE_HUB_PTR((_n), (_r))) |
| 277 | #define REMOTE_HUB_PI_S(_n, _sn, _r, _d) HUB_S(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)), (_d)) | ||
| 278 | 267 | ||
| 279 | #endif /* !__ASSEMBLY__ */ | 268 | #endif /* !__ASSEMBLY__ */ |
| 280 | 269 | ||
| 281 | /* | 270 | /* |
| 282 | * The following macros are used to get to a hub/bridge register, given | ||
| 283 | * the base of the register space. | ||
| 284 | */ | ||
| 285 | #define HUB_REG_PTR(_base, _off) \ | ||
| 286 | (HUBREG_CAST((__psunsigned_t)(_base) + (__psunsigned_t)(_off))) | ||
| 287 | |||
| 288 | #define HUB_REG_PTR_L(_base, _off) \ | ||
| 289 | HUB_L(HUB_REG_PTR((_base), (_off))) | ||
| 290 | |||
| 291 | #define HUB_REG_PTR_S(_base, _off, _data) \ | ||
| 292 | HUB_S(HUB_REG_PTR((_base), (_off)), (_data)) | ||
| 293 | |||
| 294 | /* | ||
| 295 | * Software structure locations -- permanently fixed | 271 | * Software structure locations -- permanently fixed |
| 296 | * See diagram in kldir.h | 272 | * See diagram in kldir.h |
| 297 | */ | 273 | */ |
| @@ -387,44 +363,14 @@ | |||
| 387 | 363 | ||
| 388 | #define SYMMON_STK_END(nasid) (SYMMON_STK_ADDR(nasid, 0) + KLD_SYMMON_STK(nasid)->size) | 364 | #define SYMMON_STK_END(nasid) (SYMMON_STK_ADDR(nasid, 0) + KLD_SYMMON_STK(nasid)->size) |
| 389 | 365 | ||
| 390 | /* loading symmon 4k below UNIX. the arcs loader needs the topaddr for a | ||
| 391 | * relocatable program | ||
| 392 | */ | ||
| 393 | #define UNIX_DEBUG_LOADADDR 0x300000 | ||
| 394 | #define SYMMON_LOADADDR(nasid) \ | ||
| 395 | TO_NODE(nasid, PHYS_TO_K0(UNIX_DEBUG_LOADADDR - 0x1000)) | ||
| 396 | |||
| 397 | #define FREEMEM_OFFSET(nasid) KLD_FREEMEM(nasid)->offset | ||
| 398 | #define FREEMEM_ADDR(nasid) SYMMON_STK_END(nasid) | ||
| 399 | /* | ||
| 400 | * XXX | ||
| 401 | * Fix this. FREEMEM_ADDR should be aware of if symmon is loaded. | ||
| 402 | * Also, it should take into account what prom thinks to be a safe | ||
| 403 | * address | ||
| 404 | PHYS_TO_K0(NODE_OFFSET(nasid) + FREEMEM_OFFSET(nasid)) | ||
| 405 | */ | ||
| 406 | #define FREEMEM_SIZE(nasid) KLD_FREEMEM(nasid)->size | ||
| 407 | |||
| 408 | #define PI_ERROR_OFFSET(nasid) KLD_PI_ERROR(nasid)->offset | ||
| 409 | #define PI_ERROR_ADDR(nasid) \ | ||
| 410 | TO_NODE_UNCAC((nasid), PI_ERROR_OFFSET(nasid)) | ||
| 411 | #define PI_ERROR_SIZE(nasid) KLD_PI_ERROR(nasid)->size | ||
| 412 | |||
| 413 | #define NODE_OFFSET_TO_K0(_nasid, _off) \ | 366 | #define NODE_OFFSET_TO_K0(_nasid, _off) \ |
| 414 | PHYS_TO_K0((NODE_OFFSET(_nasid) + (_off)) | CAC_BASE) | 367 | PHYS_TO_K0((NODE_OFFSET(_nasid) + (_off)) | CAC_BASE) |
| 415 | #define NODE_OFFSET_TO_K1(_nasid, _off) \ | 368 | #define NODE_OFFSET_TO_K1(_nasid, _off) \ |
| 416 | TO_UNCAC((NODE_OFFSET(_nasid) + (_off)) | UNCAC_BASE) | 369 | TO_UNCAC((NODE_OFFSET(_nasid) + (_off)) | UNCAC_BASE) |
| 417 | #define K0_TO_NODE_OFFSET(_k0addr) \ | ||
| 418 | ((__psunsigned_t)(_k0addr) & NODE_ADDRSPACE_MASK) | ||
| 419 | 370 | ||
| 420 | #define KERN_VARS_ADDR(nasid) KLD_KERN_VARS(nasid)->pointer | 371 | #define KERN_VARS_ADDR(nasid) KLD_KERN_VARS(nasid)->pointer |
| 421 | #define KERN_VARS_SIZE(nasid) KLD_KERN_VARS(nasid)->size | 372 | #define KERN_VARS_SIZE(nasid) KLD_KERN_VARS(nasid)->size |
| 422 | 373 | ||
| 423 | #define KERN_XP_ADDR(nasid) KLD_KERN_XP(nasid)->pointer | ||
| 424 | #define KERN_XP_SIZE(nasid) KLD_KERN_XP(nasid)->size | ||
| 425 | |||
| 426 | #define GPDA_ADDR(nasid) TO_NODE_CAC(nasid, GPDA_OFFSET) | ||
| 427 | |||
| 428 | #endif /* !__ASSEMBLY__ */ | 374 | #endif /* !__ASSEMBLY__ */ |
| 429 | 375 | ||
| 430 | 376 | ||
diff --git a/arch/mips/include/asm/sn/arch.h b/arch/mips/include/asm/sn/arch.h index 471e6870d876..3f1fb1454749 100644 --- a/arch/mips/include/asm/sn/arch.h +++ b/arch/mips/include/asm/sn/arch.h | |||
| @@ -17,8 +17,6 @@ | |||
| 17 | #include <asm/sn/sn0/arch.h> | 17 | #include <asm/sn/sn0/arch.h> |
| 18 | #endif | 18 | #endif |
| 19 | 19 | ||
| 20 | typedef u64 hubreg_t; | ||
| 21 | |||
| 22 | #define cputonasid(cpu) (sn_cpu_info[(cpu)].p_nasid) | 20 | #define cputonasid(cpu) (sn_cpu_info[(cpu)].p_nasid) |
| 23 | #define cputoslice(cpu) (sn_cpu_info[(cpu)].p_slice) | 21 | #define cputoslice(cpu) (sn_cpu_info[(cpu)].p_slice) |
| 24 | #define makespnum(_nasid, _slice) \ | 22 | #define makespnum(_nasid, _slice) \ |
diff --git a/arch/mips/include/asm/sn/io.h b/arch/mips/include/asm/sn/io.h index d5174d04538c..211f1e83b523 100644 --- a/arch/mips/include/asm/sn/io.h +++ b/arch/mips/include/asm/sn/io.h | |||
| @@ -44,7 +44,7 @@ | |||
| 44 | IIO_ITTE_PUT((nasid), HUB_PIO_MAP_TO_MEM, \ | 44 | IIO_ITTE_PUT((nasid), HUB_PIO_MAP_TO_MEM, \ |
| 45 | (bigwin), IIO_ITTE_INVALID_WIDGET, 0) | 45 | (bigwin), IIO_ITTE_INVALID_WIDGET, 0) |
| 46 | 46 | ||
| 47 | #define IIO_ITTE_GET(nasid, bigwin) REMOTE_HUB_ADDR((nasid), IIO_ITTE(bigwin)) | 47 | #define IIO_ITTE_GET(nasid, bigwin) REMOTE_HUB_PTR((nasid), IIO_ITTE(bigwin)) |
| 48 | 48 | ||
| 49 | /* | 49 | /* |
| 50 | * Macro which takes the widget number, and returns the | 50 | * Macro which takes the widget number, and returns the |
diff --git a/arch/mips/include/asm/sn/sn0/addrs.h b/arch/mips/include/asm/sn/sn0/addrs.h index 6b53070f400f..f13df84edfdd 100644 --- a/arch/mips/include/asm/sn/sn0/addrs.h +++ b/arch/mips/include/asm/sn/sn0/addrs.h | |||
| @@ -134,11 +134,6 @@ | |||
| 134 | 134 | ||
| 135 | #define CALIAS_BASE CAC_BASE | 135 | #define CALIAS_BASE CAC_BASE |
| 136 | 136 | ||
| 137 | |||
| 138 | |||
| 139 | #define BRIDGE_REG_PTR(_base, _off) ((volatile bridgereg_t *) \ | ||
| 140 | ((__psunsigned_t)(_base) + (__psunsigned_t)(_off))) | ||
| 141 | |||
| 142 | #define SN0_WIDGET_BASE(_nasid, _wid) (NODE_SWIN_BASE((_nasid), (_wid))) | 137 | #define SN0_WIDGET_BASE(_nasid, _wid) (NODE_SWIN_BASE((_nasid), (_wid))) |
| 143 | 138 | ||
| 144 | /* Turn on sable logging for the processors whose bits are set. */ | 139 | /* Turn on sable logging for the processors whose bits are set. */ |
diff --git a/arch/mips/include/asm/tlbflush.h b/arch/mips/include/asm/tlbflush.h index 40a361092491..9789e7a32def 100644 --- a/arch/mips/include/asm/tlbflush.h +++ b/arch/mips/include/asm/tlbflush.h | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages | 14 | * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages |
| 15 | */ | 15 | */ |
| 16 | extern void local_flush_tlb_all(void); | 16 | extern void local_flush_tlb_all(void); |
| 17 | extern void local_flush_tlb_mm(struct mm_struct *mm); | ||
| 18 | extern void local_flush_tlb_range(struct vm_area_struct *vma, | 17 | extern void local_flush_tlb_range(struct vm_area_struct *vma, |
| 19 | unsigned long start, unsigned long end); | 18 | unsigned long start, unsigned long end); |
| 20 | extern void local_flush_tlb_kernel_range(unsigned long start, | 19 | extern void local_flush_tlb_kernel_range(unsigned long start, |
| @@ -23,6 +22,8 @@ extern void local_flush_tlb_page(struct vm_area_struct *vma, | |||
| 23 | unsigned long page); | 22 | unsigned long page); |
| 24 | extern void local_flush_tlb_one(unsigned long vaddr); | 23 | extern void local_flush_tlb_one(unsigned long vaddr); |
| 25 | 24 | ||
| 25 | #include <asm/mmu_context.h> | ||
| 26 | |||
| 26 | #ifdef CONFIG_SMP | 27 | #ifdef CONFIG_SMP |
| 27 | 28 | ||
| 28 | extern void flush_tlb_all(void); | 29 | extern void flush_tlb_all(void); |
| @@ -36,7 +37,7 @@ extern void flush_tlb_one(unsigned long vaddr); | |||
| 36 | #else /* CONFIG_SMP */ | 37 | #else /* CONFIG_SMP */ |
| 37 | 38 | ||
| 38 | #define flush_tlb_all() local_flush_tlb_all() | 39 | #define flush_tlb_all() local_flush_tlb_all() |
| 39 | #define flush_tlb_mm(mm) local_flush_tlb_mm(mm) | 40 | #define flush_tlb_mm(mm) drop_mmu_context(mm) |
| 40 | #define flush_tlb_range(vma, vmaddr, end) local_flush_tlb_range(vma, vmaddr, end) | 41 | #define flush_tlb_range(vma, vmaddr, end) local_flush_tlb_range(vma, vmaddr, end) |
| 41 | #define flush_tlb_kernel_range(vmaddr,end) \ | 42 | #define flush_tlb_kernel_range(vmaddr,end) \ |
| 42 | local_flush_tlb_kernel_range(vmaddr, end) | 43 | local_flush_tlb_kernel_range(vmaddr, end) |
diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c index afb40f8bce96..7e63c54eb8d2 100644 --- a/arch/mips/jz4740/setup.c +++ b/arch/mips/jz4740/setup.c | |||
| @@ -31,7 +31,6 @@ | |||
| 31 | 31 | ||
| 32 | #define JZ4740_EMC_SDRAM_CTRL 0x80 | 32 | #define JZ4740_EMC_SDRAM_CTRL 0x80 |
| 33 | 33 | ||
| 34 | |||
| 35 | static void __init jz4740_detect_mem(void) | 34 | static void __init jz4740_detect_mem(void) |
| 36 | { | 35 | { |
| 37 | void __iomem *jz_emc_base; | 36 | void __iomem *jz_emc_base; |
| @@ -66,15 +65,22 @@ static unsigned long __init get_board_mach_type(const void *fdt) | |||
| 66 | void __init plat_mem_setup(void) | 65 | void __init plat_mem_setup(void) |
| 67 | { | 66 | { |
| 68 | int offset; | 67 | int offset; |
| 68 | void *dtb; | ||
| 69 | 69 | ||
| 70 | jz4740_reset_init(); | 70 | jz4740_reset_init(); |
| 71 | __dt_setup_arch(__dtb_start); | ||
| 72 | 71 | ||
| 73 | offset = fdt_path_offset(__dtb_start, "/memory"); | 72 | if (__dtb_start != __dtb_end) |
| 73 | dtb = __dtb_start; | ||
| 74 | else | ||
| 75 | dtb = (void *)fw_passed_dtb; | ||
| 76 | |||
| 77 | __dt_setup_arch(dtb); | ||
| 78 | |||
| 79 | offset = fdt_path_offset(dtb, "/memory"); | ||
| 74 | if (offset < 0) | 80 | if (offset < 0) |
| 75 | jz4740_detect_mem(); | 81 | jz4740_detect_mem(); |
| 76 | 82 | ||
| 77 | mips_machtype = get_board_mach_type(__dtb_start); | 83 | mips_machtype = get_board_mach_type(dtb); |
| 78 | } | 84 | } |
| 79 | 85 | ||
| 80 | void __init device_tree_init(void) | 86 | void __init device_tree_init(void) |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 95b18a194f53..d5e335e6846a 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
| @@ -872,10 +872,19 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c) | |||
| 872 | 872 | ||
| 873 | static inline unsigned int decode_config5(struct cpuinfo_mips *c) | 873 | static inline unsigned int decode_config5(struct cpuinfo_mips *c) |
| 874 | { | 874 | { |
| 875 | unsigned int config5; | 875 | unsigned int config5, max_mmid_width; |
| 876 | unsigned long asid_mask; | ||
| 876 | 877 | ||
| 877 | config5 = read_c0_config5(); | 878 | config5 = read_c0_config5(); |
| 878 | config5 &= ~(MIPS_CONF5_UFR | MIPS_CONF5_UFE); | 879 | config5 &= ~(MIPS_CONF5_UFR | MIPS_CONF5_UFE); |
| 880 | |||
| 881 | if (cpu_has_mips_r6) { | ||
| 882 | if (!__builtin_constant_p(cpu_has_mmid) || cpu_has_mmid) | ||
| 883 | config5 |= MIPS_CONF5_MI; | ||
| 884 | else | ||
| 885 | config5 &= ~MIPS_CONF5_MI; | ||
| 886 | } | ||
| 887 | |||
| 879 | write_c0_config5(config5); | 888 | write_c0_config5(config5); |
| 880 | 889 | ||
| 881 | if (config5 & MIPS_CONF5_EVA) | 890 | if (config5 & MIPS_CONF5_EVA) |
| @@ -894,6 +903,50 @@ static inline unsigned int decode_config5(struct cpuinfo_mips *c) | |||
| 894 | if (config5 & MIPS_CONF5_CRCP) | 903 | if (config5 & MIPS_CONF5_CRCP) |
| 895 | elf_hwcap |= HWCAP_MIPS_CRC32; | 904 | elf_hwcap |= HWCAP_MIPS_CRC32; |
| 896 | 905 | ||
| 906 | if (cpu_has_mips_r6) { | ||
| 907 | /* Ensure the write to config5 above takes effect */ | ||
| 908 | back_to_back_c0_hazard(); | ||
| 909 | |||
| 910 | /* Check whether we successfully enabled MMID support */ | ||
| 911 | config5 = read_c0_config5(); | ||
| 912 | if (config5 & MIPS_CONF5_MI) | ||
| 913 | c->options |= MIPS_CPU_MMID; | ||
| 914 | |||
| 915 | /* | ||
| 916 | * Warn if we've hardcoded cpu_has_mmid to a value unsuitable | ||
| 917 | * for the CPU we're running on, or if CPUs in an SMP system | ||
| 918 | * have inconsistent MMID support. | ||
| 919 | */ | ||
| 920 | WARN_ON(!!cpu_has_mmid != !!(config5 & MIPS_CONF5_MI)); | ||
| 921 | |||
| 922 | if (cpu_has_mmid) { | ||
| 923 | write_c0_memorymapid(~0ul); | ||
| 924 | back_to_back_c0_hazard(); | ||
| 925 | asid_mask = read_c0_memorymapid(); | ||
| 926 | |||
| 927 | /* | ||
| 928 | * We maintain a bitmap to track MMID allocation, and | ||
| 929 | * need a sensible upper bound on the size of that | ||
| 930 | * bitmap. The initial CPU with MMID support (I6500) | ||
| 931 | * supports 16 bit MMIDs, which gives us an 8KiB | ||
| 932 | * bitmap. The architecture recommends that hardware | ||
| 933 | * support 32 bit MMIDs, which would give us a 512MiB | ||
| 934 | * bitmap - that's too big in most cases. | ||
| 935 | * | ||
| 936 | * Cap MMID width at 16 bits for now & we can revisit | ||
| 937 | * this if & when hardware supports anything wider. | ||
| 938 | */ | ||
| 939 | max_mmid_width = 16; | ||
| 940 | if (asid_mask > GENMASK(max_mmid_width - 1, 0)) { | ||
| 941 | pr_info("Capping MMID width at %d bits", | ||
| 942 | max_mmid_width); | ||
| 943 | asid_mask = GENMASK(max_mmid_width - 1, 0); | ||
| 944 | } | ||
| 945 | |||
| 946 | set_cpu_asid_mask(c, asid_mask); | ||
| 947 | } | ||
| 948 | } | ||
| 949 | |||
| 897 | return config5 & MIPS_CONF_M; | 950 | return config5 & MIPS_CONF_M; |
| 898 | } | 951 | } |
| 899 | 952 | ||
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index ba150c755fcc..85b6c60f285d 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c | |||
| @@ -52,6 +52,7 @@ asmlinkage void spurious_interrupt(void) | |||
| 52 | void __init init_IRQ(void) | 52 | void __init init_IRQ(void) |
| 53 | { | 53 | { |
| 54 | int i; | 54 | int i; |
| 55 | unsigned int order = get_order(IRQ_STACK_SIZE); | ||
| 55 | 56 | ||
| 56 | for (i = 0; i < NR_IRQS; i++) | 57 | for (i = 0; i < NR_IRQS; i++) |
| 57 | irq_set_noprobe(i); | 58 | irq_set_noprobe(i); |
| @@ -62,8 +63,7 @@ void __init init_IRQ(void) | |||
| 62 | arch_init_irq(); | 63 | arch_init_irq(); |
| 63 | 64 | ||
| 64 | for_each_possible_cpu(i) { | 65 | for_each_possible_cpu(i) { |
| 65 | int irq_pages = IRQ_STACK_SIZE / PAGE_SIZE; | 66 | void *s = (void *)__get_free_pages(GFP_KERNEL, order); |
| 66 | void *s = (void *)__get_free_pages(GFP_KERNEL, irq_pages); | ||
| 67 | 67 | ||
| 68 | irq_stack[i] = s; | 68 | irq_stack[i] = s; |
| 69 | pr_debug("CPU%d IRQ stack at 0x%p - 0x%p\n", i, | 69 | pr_debug("CPU%d IRQ stack at 0x%p - 0x%p\n", i, |
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c index 7f3f136572de..537e8d091874 100644 --- a/arch/mips/kernel/mips-cm.c +++ b/arch/mips/kernel/mips-cm.c | |||
| @@ -382,8 +382,8 @@ void mips_cm_error_report(void) | |||
| 382 | sc_bit ? "True" : "False", | 382 | sc_bit ? "True" : "False", |
| 383 | cm2_cmd[cmd_bits], sport_bits); | 383 | cm2_cmd[cmd_bits], sport_bits); |
| 384 | } | 384 | } |
| 385 | pr_err("CM_ERROR=%08llx %s <%s>\n", cm_error, | 385 | pr_err("CM_ERROR=%08llx %s <%s>\n", cm_error, |
| 386 | cm2_causes[cause], buf); | 386 | cm2_causes[cause], buf); |
| 387 | pr_err("CM_ADDR =%08llx\n", cm_addr); | 387 | pr_err("CM_ADDR =%08llx\n", cm_addr); |
| 388 | pr_err("CM_OTHER=%08llx %s\n", cm_other, cm2_causes[ocause]); | 388 | pr_err("CM_OTHER=%08llx %s\n", cm_other, cm2_causes[ocause]); |
| 389 | } else { /* CM3 */ | 389 | } else { /* CM3 */ |
diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c index c50c89a978f1..b4d210bfcdae 100644 --- a/arch/mips/kernel/mips-r2-to-r6-emul.c +++ b/arch/mips/kernel/mips-r2-to-r6-emul.c | |||
| @@ -2351,23 +2351,10 @@ DEFINE_SHOW_ATTRIBUTE(mipsr2_clear); | |||
| 2351 | 2351 | ||
| 2352 | static int __init mipsr2_init_debugfs(void) | 2352 | static int __init mipsr2_init_debugfs(void) |
| 2353 | { | 2353 | { |
| 2354 | struct dentry *mipsr2_emul; | 2354 | debugfs_create_file("r2_emul_stats", S_IRUGO, mips_debugfs_dir, NULL, |
| 2355 | 2355 | &mipsr2_emul_fops); | |
| 2356 | if (!mips_debugfs_dir) | 2356 | debugfs_create_file("r2_emul_stats_clear", S_IRUGO, mips_debugfs_dir, |
| 2357 | return -ENODEV; | 2357 | NULL, &mipsr2_clear_fops); |
| 2358 | |||
| 2359 | mipsr2_emul = debugfs_create_file("r2_emul_stats", S_IRUGO, | ||
| 2360 | mips_debugfs_dir, NULL, | ||
| 2361 | &mipsr2_emul_fops); | ||
| 2362 | if (!mipsr2_emul) | ||
| 2363 | return -ENOMEM; | ||
| 2364 | |||
| 2365 | mipsr2_emul = debugfs_create_file("r2_emul_stats_clear", S_IRUGO, | ||
| 2366 | mips_debugfs_dir, NULL, | ||
| 2367 | &mipsr2_clear_fops); | ||
| 2368 | if (!mipsr2_emul) | ||
| 2369 | return -ENOMEM; | ||
| 2370 | |||
| 2371 | return 0; | 2358 | return 0; |
| 2372 | } | 2359 | } |
| 2373 | 2360 | ||
diff --git a/arch/mips/kernel/segment.c b/arch/mips/kernel/segment.c index 2703f218202e..0a9bd7b0983b 100644 --- a/arch/mips/kernel/segment.c +++ b/arch/mips/kernel/segment.c | |||
| @@ -95,18 +95,9 @@ static const struct file_operations segments_fops = { | |||
| 95 | 95 | ||
| 96 | static int __init segments_info(void) | 96 | static int __init segments_info(void) |
| 97 | { | 97 | { |
| 98 | struct dentry *segments; | 98 | if (cpu_has_segments) |
| 99 | 99 | debugfs_create_file("segments", S_IRUGO, mips_debugfs_dir, NULL, | |
| 100 | if (cpu_has_segments) { | 100 | &segments_fops); |
| 101 | if (!mips_debugfs_dir) | ||
| 102 | return -ENODEV; | ||
| 103 | |||
| 104 | segments = debugfs_create_file("segments", S_IRUGO, | ||
| 105 | mips_debugfs_dir, NULL, | ||
| 106 | &segments_fops); | ||
| 107 | if (!segments) | ||
| 108 | return -ENOMEM; | ||
| 109 | } | ||
| 110 | return 0; | 101 | return 0; |
| 111 | } | 102 | } |
| 112 | 103 | ||
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index d2e5a5ad0e6f..5151532ad959 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c | |||
| @@ -1011,12 +1011,7 @@ unsigned long fw_passed_dtb; | |||
| 1011 | struct dentry *mips_debugfs_dir; | 1011 | struct dentry *mips_debugfs_dir; |
| 1012 | static int __init debugfs_mips(void) | 1012 | static int __init debugfs_mips(void) |
| 1013 | { | 1013 | { |
| 1014 | struct dentry *d; | 1014 | mips_debugfs_dir = debugfs_create_dir("mips", NULL); |
| 1015 | |||
| 1016 | d = debugfs_create_dir("mips", NULL); | ||
| 1017 | if (!d) | ||
| 1018 | return -ENOMEM; | ||
| 1019 | mips_debugfs_dir = d; | ||
| 1020 | return 0; | 1015 | return 0; |
| 1021 | } | 1016 | } |
| 1022 | arch_initcall(debugfs_mips); | 1017 | arch_initcall(debugfs_mips); |
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index d84b9066b465..bc4bb3c6bd00 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | 39 | ||
| 40 | #include <linux/atomic.h> | 40 | #include <linux/atomic.h> |
| 41 | #include <asm/cpu.h> | 41 | #include <asm/cpu.h> |
| 42 | #include <asm/ginvt.h> | ||
| 42 | #include <asm/processor.h> | 43 | #include <asm/processor.h> |
| 43 | #include <asm/idle.h> | 44 | #include <asm/idle.h> |
| 44 | #include <asm/r4k-timer.h> | 45 | #include <asm/r4k-timer.h> |
| @@ -443,6 +444,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
| 443 | /* preload SMP state for boot cpu */ | 444 | /* preload SMP state for boot cpu */ |
| 444 | void smp_prepare_boot_cpu(void) | 445 | void smp_prepare_boot_cpu(void) |
| 445 | { | 446 | { |
| 447 | if (mp_ops->prepare_boot_cpu) | ||
| 448 | mp_ops->prepare_boot_cpu(); | ||
| 446 | set_cpu_possible(0, true); | 449 | set_cpu_possible(0, true); |
| 447 | set_cpu_online(0, true); | 450 | set_cpu_online(0, true); |
| 448 | } | 451 | } |
| @@ -482,12 +485,21 @@ static void flush_tlb_all_ipi(void *info) | |||
| 482 | 485 | ||
| 483 | void flush_tlb_all(void) | 486 | void flush_tlb_all(void) |
| 484 | { | 487 | { |
| 488 | if (cpu_has_mmid) { | ||
| 489 | htw_stop(); | ||
| 490 | ginvt_full(); | ||
| 491 | sync_ginv(); | ||
| 492 | instruction_hazard(); | ||
| 493 | htw_start(); | ||
| 494 | return; | ||
| 495 | } | ||
| 496 | |||
| 485 | on_each_cpu(flush_tlb_all_ipi, NULL, 1); | 497 | on_each_cpu(flush_tlb_all_ipi, NULL, 1); |
| 486 | } | 498 | } |
| 487 | 499 | ||
| 488 | static void flush_tlb_mm_ipi(void *mm) | 500 | static void flush_tlb_mm_ipi(void *mm) |
| 489 | { | 501 | { |
| 490 | local_flush_tlb_mm((struct mm_struct *)mm); | 502 | drop_mmu_context((struct mm_struct *)mm); |
| 491 | } | 503 | } |
| 492 | 504 | ||
| 493 | /* | 505 | /* |
| @@ -530,17 +542,22 @@ void flush_tlb_mm(struct mm_struct *mm) | |||
| 530 | { | 542 | { |
| 531 | preempt_disable(); | 543 | preempt_disable(); |
| 532 | 544 | ||
| 533 | if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { | 545 | if (cpu_has_mmid) { |
| 546 | /* | ||
| 547 | * No need to worry about other CPUs - the ginvt in | ||
| 548 | * drop_mmu_context() will be globalized. | ||
| 549 | */ | ||
| 550 | } else if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { | ||
| 534 | smp_on_other_tlbs(flush_tlb_mm_ipi, mm); | 551 | smp_on_other_tlbs(flush_tlb_mm_ipi, mm); |
| 535 | } else { | 552 | } else { |
| 536 | unsigned int cpu; | 553 | unsigned int cpu; |
| 537 | 554 | ||
| 538 | for_each_online_cpu(cpu) { | 555 | for_each_online_cpu(cpu) { |
| 539 | if (cpu != smp_processor_id() && cpu_context(cpu, mm)) | 556 | if (cpu != smp_processor_id() && cpu_context(cpu, mm)) |
| 540 | cpu_context(cpu, mm) = 0; | 557 | set_cpu_context(cpu, mm, 0); |
| 541 | } | 558 | } |
| 542 | } | 559 | } |
| 543 | local_flush_tlb_mm(mm); | 560 | drop_mmu_context(mm); |
| 544 | 561 | ||
| 545 | preempt_enable(); | 562 | preempt_enable(); |
| 546 | } | 563 | } |
| @@ -561,9 +578,26 @@ static void flush_tlb_range_ipi(void *info) | |||
| 561 | void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) | 578 | void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) |
| 562 | { | 579 | { |
| 563 | struct mm_struct *mm = vma->vm_mm; | 580 | struct mm_struct *mm = vma->vm_mm; |
| 581 | unsigned long addr; | ||
| 582 | u32 old_mmid; | ||
| 564 | 583 | ||
| 565 | preempt_disable(); | 584 | preempt_disable(); |
| 566 | if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { | 585 | if (cpu_has_mmid) { |
| 586 | htw_stop(); | ||
| 587 | old_mmid = read_c0_memorymapid(); | ||
| 588 | write_c0_memorymapid(cpu_asid(0, mm)); | ||
| 589 | mtc0_tlbw_hazard(); | ||
| 590 | addr = round_down(start, PAGE_SIZE * 2); | ||
| 591 | end = round_up(end, PAGE_SIZE * 2); | ||
| 592 | do { | ||
| 593 | ginvt_va_mmid(addr); | ||
| 594 | sync_ginv(); | ||
| 595 | addr += PAGE_SIZE * 2; | ||
| 596 | } while (addr < end); | ||
| 597 | write_c0_memorymapid(old_mmid); | ||
| 598 | instruction_hazard(); | ||
| 599 | htw_start(); | ||
| 600 | } else if ((atomic_read(&mm->mm_users) != 1) || (current->mm != mm)) { | ||
| 567 | struct flush_tlb_data fd = { | 601 | struct flush_tlb_data fd = { |
| 568 | .vma = vma, | 602 | .vma = vma, |
| 569 | .addr1 = start, | 603 | .addr1 = start, |
| @@ -571,6 +605,7 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned l | |||
| 571 | }; | 605 | }; |
| 572 | 606 | ||
| 573 | smp_on_other_tlbs(flush_tlb_range_ipi, &fd); | 607 | smp_on_other_tlbs(flush_tlb_range_ipi, &fd); |
| 608 | local_flush_tlb_range(vma, start, end); | ||
| 574 | } else { | 609 | } else { |
| 575 | unsigned int cpu; | 610 | unsigned int cpu; |
| 576 | int exec = vma->vm_flags & VM_EXEC; | 611 | int exec = vma->vm_flags & VM_EXEC; |
| @@ -583,10 +618,10 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned l | |||
| 583 | * mm has been completely unused by that CPU. | 618 | * mm has been completely unused by that CPU. |
| 584 | */ | 619 | */ |
| 585 | if (cpu != smp_processor_id() && cpu_context(cpu, mm)) | 620 | if (cpu != smp_processor_id() && cpu_context(cpu, mm)) |
| 586 | cpu_context(cpu, mm) = !exec; | 621 | set_cpu_context(cpu, mm, !exec); |
| 587 | } | 622 | } |
| 623 | local_flush_tlb_range(vma, start, end); | ||
| 588 | } | 624 | } |
| 589 | local_flush_tlb_range(vma, start, end); | ||
| 590 | preempt_enable(); | 625 | preempt_enable(); |
| 591 | } | 626 | } |
| 592 | 627 | ||
| @@ -616,14 +651,28 @@ static void flush_tlb_page_ipi(void *info) | |||
| 616 | 651 | ||
| 617 | void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | 652 | void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) |
| 618 | { | 653 | { |
| 654 | u32 old_mmid; | ||
| 655 | |||
| 619 | preempt_disable(); | 656 | preempt_disable(); |
| 620 | if ((atomic_read(&vma->vm_mm->mm_users) != 1) || (current->mm != vma->vm_mm)) { | 657 | if (cpu_has_mmid) { |
| 658 | htw_stop(); | ||
| 659 | old_mmid = read_c0_memorymapid(); | ||
| 660 | write_c0_memorymapid(cpu_asid(0, vma->vm_mm)); | ||
| 661 | mtc0_tlbw_hazard(); | ||
| 662 | ginvt_va_mmid(page); | ||
| 663 | sync_ginv(); | ||
| 664 | write_c0_memorymapid(old_mmid); | ||
| 665 | instruction_hazard(); | ||
| 666 | htw_start(); | ||
| 667 | } else if ((atomic_read(&vma->vm_mm->mm_users) != 1) || | ||
| 668 | (current->mm != vma->vm_mm)) { | ||
| 621 | struct flush_tlb_data fd = { | 669 | struct flush_tlb_data fd = { |
| 622 | .vma = vma, | 670 | .vma = vma, |
| 623 | .addr1 = page, | 671 | .addr1 = page, |
| 624 | }; | 672 | }; |
| 625 | 673 | ||
| 626 | smp_on_other_tlbs(flush_tlb_page_ipi, &fd); | 674 | smp_on_other_tlbs(flush_tlb_page_ipi, &fd); |
| 675 | local_flush_tlb_page(vma, page); | ||
| 627 | } else { | 676 | } else { |
| 628 | unsigned int cpu; | 677 | unsigned int cpu; |
| 629 | 678 | ||
| @@ -635,10 +684,10 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | |||
| 635 | * by that CPU. | 684 | * by that CPU. |
| 636 | */ | 685 | */ |
| 637 | if (cpu != smp_processor_id() && cpu_context(cpu, vma->vm_mm)) | 686 | if (cpu != smp_processor_id() && cpu_context(cpu, vma->vm_mm)) |
| 638 | cpu_context(cpu, vma->vm_mm) = 1; | 687 | set_cpu_context(cpu, vma->vm_mm, 1); |
| 639 | } | 688 | } |
| 689 | local_flush_tlb_page(vma, page); | ||
| 640 | } | 690 | } |
| 641 | local_flush_tlb_page(vma, page); | ||
| 642 | preempt_enable(); | 691 | preempt_enable(); |
| 643 | } | 692 | } |
| 644 | 693 | ||
diff --git a/arch/mips/kernel/spinlock_test.c b/arch/mips/kernel/spinlock_test.c index eaed550e79a2..ab4e3e1b138d 100644 --- a/arch/mips/kernel/spinlock_test.c +++ b/arch/mips/kernel/spinlock_test.c | |||
| @@ -118,23 +118,10 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_multi, multi_get, NULL, "%llu\n"); | |||
| 118 | 118 | ||
| 119 | static int __init spinlock_test(void) | 119 | static int __init spinlock_test(void) |
| 120 | { | 120 | { |
| 121 | struct dentry *d; | 121 | debugfs_create_file("spin_single", S_IRUGO, mips_debugfs_dir, NULL, |
| 122 | 122 | &fops_ss); | |
| 123 | if (!mips_debugfs_dir) | 123 | debugfs_create_file("spin_multi", S_IRUGO, mips_debugfs_dir, NULL, |
| 124 | return -ENODEV; | 124 | &fops_multi); |
| 125 | |||
| 126 | d = debugfs_create_file("spin_single", S_IRUGO, | ||
| 127 | mips_debugfs_dir, NULL, | ||
| 128 | &fops_ss); | ||
| 129 | if (!d) | ||
| 130 | return -ENOMEM; | ||
| 131 | |||
| 132 | d = debugfs_create_file("spin_multi", S_IRUGO, | ||
| 133 | mips_debugfs_dir, NULL, | ||
| 134 | &fops_multi); | ||
| 135 | if (!d) | ||
| 136 | return -ENOMEM; | ||
| 137 | |||
| 138 | return 0; | 125 | return 0; |
| 139 | } | 126 | } |
| 140 | device_initcall(spinlock_test); | 127 | device_initcall(spinlock_test); |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index cbab46004e99..42d411125690 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
| @@ -2223,7 +2223,9 @@ void per_cpu_trap_init(bool is_boot_cpu) | |||
| 2223 | cp0_fdc_irq = -1; | 2223 | cp0_fdc_irq = -1; |
| 2224 | } | 2224 | } |
| 2225 | 2225 | ||
| 2226 | if (!cpu_data[cpu].asid_cache) | 2226 | if (cpu_has_mmid) |
| 2227 | cpu_data[cpu].asid_cache = 0; | ||
| 2228 | else if (!cpu_data[cpu].asid_cache) | ||
| 2227 | cpu_data[cpu].asid_cache = asid_first_version(cpu); | 2229 | cpu_data[cpu].asid_cache = asid_first_version(cpu); |
| 2228 | 2230 | ||
| 2229 | mmgrab(&init_mm); | 2231 | mmgrab(&init_mm); |
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c index 595ca9c85111..76e33f940971 100644 --- a/arch/mips/kernel/unaligned.c +++ b/arch/mips/kernel/unaligned.c | |||
| @@ -89,6 +89,7 @@ | |||
| 89 | #include <asm/fpu.h> | 89 | #include <asm/fpu.h> |
| 90 | #include <asm/fpu_emulator.h> | 90 | #include <asm/fpu_emulator.h> |
| 91 | #include <asm/inst.h> | 91 | #include <asm/inst.h> |
| 92 | #include <asm/mmu_context.h> | ||
| 92 | #include <linux/uaccess.h> | 93 | #include <linux/uaccess.h> |
| 93 | 94 | ||
| 94 | #define STR(x) __STR(x) | 95 | #define STR(x) __STR(x) |
| @@ -2374,18 +2375,10 @@ sigbus: | |||
| 2374 | #ifdef CONFIG_DEBUG_FS | 2375 | #ifdef CONFIG_DEBUG_FS |
| 2375 | static int __init debugfs_unaligned(void) | 2376 | static int __init debugfs_unaligned(void) |
| 2376 | { | 2377 | { |
| 2377 | struct dentry *d; | 2378 | debugfs_create_u32("unaligned_instructions", S_IRUGO, mips_debugfs_dir, |
| 2378 | 2379 | &unaligned_instructions); | |
| 2379 | if (!mips_debugfs_dir) | 2380 | debugfs_create_u32("unaligned_action", S_IRUGO | S_IWUSR, |
| 2380 | return -ENODEV; | 2381 | mips_debugfs_dir, &unaligned_action); |
| 2381 | d = debugfs_create_u32("unaligned_instructions", S_IRUGO, | ||
| 2382 | mips_debugfs_dir, &unaligned_instructions); | ||
| 2383 | if (!d) | ||
| 2384 | return -ENOMEM; | ||
| 2385 | d = debugfs_create_u32("unaligned_action", S_IRUGO | S_IWUSR, | ||
| 2386 | mips_debugfs_dir, &unaligned_action); | ||
| 2387 | if (!d) | ||
| 2388 | return -ENOMEM; | ||
| 2389 | return 0; | 2382 | return 0; |
| 2390 | } | 2383 | } |
| 2391 | arch_initcall(debugfs_unaligned); | 2384 | arch_initcall(debugfs_unaligned); |
diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c index ec9ed23bca7f..0074427b04fb 100644 --- a/arch/mips/kvm/emulate.c +++ b/arch/mips/kvm/emulate.c | |||
| @@ -1016,10 +1016,10 @@ static void kvm_mips_change_entryhi(struct kvm_vcpu *vcpu, | |||
| 1016 | */ | 1016 | */ |
| 1017 | preempt_disable(); | 1017 | preempt_disable(); |
| 1018 | cpu = smp_processor_id(); | 1018 | cpu = smp_processor_id(); |
| 1019 | get_new_mmu_context(kern_mm, cpu); | 1019 | get_new_mmu_context(kern_mm); |
| 1020 | for_each_possible_cpu(i) | 1020 | for_each_possible_cpu(i) |
| 1021 | if (i != cpu) | 1021 | if (i != cpu) |
| 1022 | cpu_context(i, kern_mm) = 0; | 1022 | set_cpu_context(i, kern_mm, 0); |
| 1023 | preempt_enable(); | 1023 | preempt_enable(); |
| 1024 | } | 1024 | } |
| 1025 | kvm_write_c0_guest_entryhi(cop0, entryhi); | 1025 | kvm_write_c0_guest_entryhi(cop0, entryhi); |
| @@ -1090,8 +1090,8 @@ static void kvm_mips_invalidate_guest_tlb(struct kvm_vcpu *vcpu, | |||
| 1090 | if (i == cpu) | 1090 | if (i == cpu) |
| 1091 | continue; | 1091 | continue; |
| 1092 | if (user) | 1092 | if (user) |
| 1093 | cpu_context(i, user_mm) = 0; | 1093 | set_cpu_context(i, user_mm, 0); |
| 1094 | cpu_context(i, kern_mm) = 0; | 1094 | set_cpu_context(i, kern_mm, 0); |
| 1095 | } | 1095 | } |
| 1096 | 1096 | ||
| 1097 | preempt_enable(); | 1097 | preempt_enable(); |
diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index 3734cd58895e..6d0517ac18e5 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c | |||
| @@ -1723,6 +1723,11 @@ static int __init kvm_mips_init(void) | |||
| 1723 | { | 1723 | { |
| 1724 | int ret; | 1724 | int ret; |
| 1725 | 1725 | ||
| 1726 | if (cpu_has_mmid) { | ||
| 1727 | pr_warn("KVM does not yet support MMIDs. KVM Disabled\n"); | ||
| 1728 | return -EOPNOTSUPP; | ||
| 1729 | } | ||
| 1730 | |||
| 1726 | ret = kvm_mips_entry_setup(); | 1731 | ret = kvm_mips_entry_setup(); |
| 1727 | if (ret) | 1732 | if (ret) |
| 1728 | return ret; | 1733 | return ret; |
diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c index 6a0d7040d882..73daa6ad33af 100644 --- a/arch/mips/kvm/trap_emul.c +++ b/arch/mips/kvm/trap_emul.c | |||
| @@ -1056,11 +1056,7 @@ static int kvm_trap_emul_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
| 1056 | */ | 1056 | */ |
| 1057 | if (current->flags & PF_VCPU) { | 1057 | if (current->flags & PF_VCPU) { |
| 1058 | mm = KVM_GUEST_KERNEL_MODE(vcpu) ? kern_mm : user_mm; | 1058 | mm = KVM_GUEST_KERNEL_MODE(vcpu) ? kern_mm : user_mm; |
| 1059 | if ((cpu_context(cpu, mm) ^ asid_cache(cpu)) & | 1059 | check_switch_mmu_context(mm); |
| 1060 | asid_version_mask(cpu)) | ||
| 1061 | get_new_mmu_context(mm, cpu); | ||
| 1062 | write_c0_entryhi(cpu_asid(cpu, mm)); | ||
| 1063 | TLBMISS_HANDLER_SETUP_PGD(mm->pgd); | ||
| 1064 | kvm_mips_suspend_mm(cpu); | 1060 | kvm_mips_suspend_mm(cpu); |
| 1065 | ehb(); | 1061 | ehb(); |
| 1066 | } | 1062 | } |
| @@ -1074,11 +1070,7 @@ static int kvm_trap_emul_vcpu_put(struct kvm_vcpu *vcpu, int cpu) | |||
| 1074 | 1070 | ||
| 1075 | if (current->flags & PF_VCPU) { | 1071 | if (current->flags & PF_VCPU) { |
| 1076 | /* Restore normal Linux process memory map */ | 1072 | /* Restore normal Linux process memory map */ |
| 1077 | if (((cpu_context(cpu, current->mm) ^ asid_cache(cpu)) & | 1073 | check_switch_mmu_context(current->mm); |
| 1078 | asid_version_mask(cpu))) | ||
| 1079 | get_new_mmu_context(current->mm, cpu); | ||
| 1080 | write_c0_entryhi(cpu_asid(cpu, current->mm)); | ||
| 1081 | TLBMISS_HANDLER_SETUP_PGD(current->mm->pgd); | ||
| 1082 | kvm_mips_resume_mm(cpu); | 1074 | kvm_mips_resume_mm(cpu); |
| 1083 | ehb(); | 1075 | ehb(); |
| 1084 | } | 1076 | } |
| @@ -1106,14 +1098,14 @@ static void kvm_trap_emul_check_requests(struct kvm_vcpu *vcpu, int cpu, | |||
| 1106 | kvm_mips_flush_gva_pt(kern_mm->pgd, KMF_GPA | KMF_KERN); | 1098 | kvm_mips_flush_gva_pt(kern_mm->pgd, KMF_GPA | KMF_KERN); |
| 1107 | kvm_mips_flush_gva_pt(user_mm->pgd, KMF_GPA | KMF_USER); | 1099 | kvm_mips_flush_gva_pt(user_mm->pgd, KMF_GPA | KMF_USER); |
| 1108 | for_each_possible_cpu(i) { | 1100 | for_each_possible_cpu(i) { |
| 1109 | cpu_context(i, kern_mm) = 0; | 1101 | set_cpu_context(i, kern_mm, 0); |
| 1110 | cpu_context(i, user_mm) = 0; | 1102 | set_cpu_context(i, user_mm, 0); |
| 1111 | } | 1103 | } |
| 1112 | 1104 | ||
| 1113 | /* Generate new ASID for current mode */ | 1105 | /* Generate new ASID for current mode */ |
| 1114 | if (reload_asid) { | 1106 | if (reload_asid) { |
| 1115 | mm = KVM_GUEST_KERNEL_MODE(vcpu) ? kern_mm : user_mm; | 1107 | mm = KVM_GUEST_KERNEL_MODE(vcpu) ? kern_mm : user_mm; |
| 1116 | get_new_mmu_context(mm, cpu); | 1108 | get_new_mmu_context(mm); |
| 1117 | htw_stop(); | 1109 | htw_stop(); |
| 1118 | write_c0_entryhi(cpu_asid(cpu, mm)); | 1110 | write_c0_entryhi(cpu_asid(cpu, mm)); |
| 1119 | TLBMISS_HANDLER_SETUP_PGD(mm->pgd); | 1111 | TLBMISS_HANDLER_SETUP_PGD(mm->pgd); |
| @@ -1219,7 +1211,7 @@ static void kvm_trap_emul_vcpu_reenter(struct kvm_run *run, | |||
| 1219 | if (gasid != vcpu->arch.last_user_gasid) { | 1211 | if (gasid != vcpu->arch.last_user_gasid) { |
| 1220 | kvm_mips_flush_gva_pt(user_mm->pgd, KMF_USER); | 1212 | kvm_mips_flush_gva_pt(user_mm->pgd, KMF_USER); |
| 1221 | for_each_possible_cpu(i) | 1213 | for_each_possible_cpu(i) |
| 1222 | cpu_context(i, user_mm) = 0; | 1214 | set_cpu_context(i, user_mm, 0); |
| 1223 | vcpu->arch.last_user_gasid = gasid; | 1215 | vcpu->arch.last_user_gasid = gasid; |
| 1224 | } | 1216 | } |
| 1225 | } | 1217 | } |
| @@ -1228,9 +1220,7 @@ static void kvm_trap_emul_vcpu_reenter(struct kvm_run *run, | |||
| 1228 | * Check if ASID is stale. This may happen due to a TLB flush request or | 1220 | * Check if ASID is stale. This may happen due to a TLB flush request or |
| 1229 | * a lazy user MM invalidation. | 1221 | * a lazy user MM invalidation. |
| 1230 | */ | 1222 | */ |
| 1231 | if ((cpu_context(cpu, mm) ^ asid_cache(cpu)) & | 1223 | check_mmu_context(mm); |
| 1232 | asid_version_mask(cpu)) | ||
| 1233 | get_new_mmu_context(mm, cpu); | ||
| 1234 | } | 1224 | } |
| 1235 | 1225 | ||
| 1236 | static int kvm_trap_emul_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu) | 1226 | static int kvm_trap_emul_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu) |
| @@ -1266,11 +1256,7 @@ static int kvm_trap_emul_vcpu_run(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
| 1266 | cpu = smp_processor_id(); | 1256 | cpu = smp_processor_id(); |
| 1267 | 1257 | ||
| 1268 | /* Restore normal Linux process memory map */ | 1258 | /* Restore normal Linux process memory map */ |
| 1269 | if (((cpu_context(cpu, current->mm) ^ asid_cache(cpu)) & | 1259 | check_switch_mmu_context(current->mm); |
| 1270 | asid_version_mask(cpu))) | ||
| 1271 | get_new_mmu_context(current->mm, cpu); | ||
| 1272 | write_c0_entryhi(cpu_asid(cpu, current->mm)); | ||
| 1273 | TLBMISS_HANDLER_SETUP_PGD(current->mm->pgd); | ||
| 1274 | kvm_mips_resume_mm(cpu); | 1260 | kvm_mips_resume_mm(cpu); |
| 1275 | 1261 | ||
| 1276 | htw_start(); | 1262 | htw_start(); |
diff --git a/arch/mips/kvm/vz.c b/arch/mips/kvm/vz.c index 74805035edc8..dde20887a70d 100644 --- a/arch/mips/kvm/vz.c +++ b/arch/mips/kvm/vz.c | |||
| @@ -2454,10 +2454,10 @@ static void kvm_vz_vcpu_load_tlb(struct kvm_vcpu *vcpu, int cpu) | |||
| 2454 | * Root ASID dealiases guest GPA mappings in the root TLB. | 2454 | * Root ASID dealiases guest GPA mappings in the root TLB. |
| 2455 | * Allocate new root ASID if needed. | 2455 | * Allocate new root ASID if needed. |
| 2456 | */ | 2456 | */ |
| 2457 | if (cpumask_test_and_clear_cpu(cpu, &kvm->arch.asid_flush_mask) | 2457 | if (cpumask_test_and_clear_cpu(cpu, &kvm->arch.asid_flush_mask)) |
| 2458 | || (cpu_context(cpu, gpa_mm) ^ asid_cache(cpu)) & | 2458 | get_new_mmu_context(gpa_mm); |
| 2459 | asid_version_mask(cpu)) | 2459 | else |
| 2460 | get_new_mmu_context(gpa_mm, cpu); | 2460 | check_mmu_context(gpa_mm); |
| 2461 | } | 2461 | } |
| 2462 | } | 2462 | } |
| 2463 | 2463 | ||
diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig index 188de95d6dbd..6c6802e482c9 100644 --- a/arch/mips/lantiq/Kconfig +++ b/arch/mips/lantiq/Kconfig | |||
| @@ -52,8 +52,4 @@ config PCI_LANTIQ | |||
| 52 | bool "PCI Support" | 52 | bool "PCI Support" |
| 53 | depends on SOC_XWAY && PCI | 53 | depends on SOC_XWAY && PCI |
| 54 | 54 | ||
| 55 | config XRX200_PHY_FW | ||
| 56 | bool "XRX200 PHY firmware loader" | ||
| 57 | depends on SOC_XWAY | ||
| 58 | |||
| 59 | endif | 55 | endif |
diff --git a/arch/mips/lib/dump_tlb.c b/arch/mips/lib/dump_tlb.c index 781ad96b78c4..83ed37298e66 100644 --- a/arch/mips/lib/dump_tlb.c +++ b/arch/mips/lib/dump_tlb.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | #include <asm/hazards.h> | 11 | #include <asm/hazards.h> |
| 12 | #include <asm/mipsregs.h> | 12 | #include <asm/mipsregs.h> |
| 13 | #include <asm/mmu_context.h> | ||
| 13 | #include <asm/page.h> | 14 | #include <asm/page.h> |
| 14 | #include <asm/pgtable.h> | 15 | #include <asm/pgtable.h> |
| 15 | #include <asm/tlbdebug.h> | 16 | #include <asm/tlbdebug.h> |
| @@ -73,12 +74,13 @@ static inline const char *msk2str(unsigned int mask) | |||
| 73 | 74 | ||
| 74 | static void dump_tlb(int first, int last) | 75 | static void dump_tlb(int first, int last) |
| 75 | { | 76 | { |
| 76 | unsigned long s_entryhi, entryhi, asid; | 77 | unsigned long s_entryhi, entryhi, asid, mmid; |
| 77 | unsigned long long entrylo0, entrylo1, pa; | 78 | unsigned long long entrylo0, entrylo1, pa; |
| 78 | unsigned int s_index, s_pagemask, s_guestctl1 = 0; | 79 | unsigned int s_index, s_pagemask, s_guestctl1 = 0; |
| 79 | unsigned int pagemask, guestctl1 = 0, c0, c1, i; | 80 | unsigned int pagemask, guestctl1 = 0, c0, c1, i; |
| 80 | unsigned long asidmask = cpu_asid_mask(¤t_cpu_data); | 81 | unsigned long asidmask = cpu_asid_mask(¤t_cpu_data); |
| 81 | int asidwidth = DIV_ROUND_UP(ilog2(asidmask) + 1, 4); | 82 | int asidwidth = DIV_ROUND_UP(ilog2(asidmask) + 1, 4); |
| 83 | unsigned long uninitialized_var(s_mmid); | ||
| 82 | #ifdef CONFIG_32BIT | 84 | #ifdef CONFIG_32BIT |
| 83 | bool xpa = cpu_has_xpa && (read_c0_pagegrain() & PG_ELPA); | 85 | bool xpa = cpu_has_xpa && (read_c0_pagegrain() & PG_ELPA); |
| 84 | int pwidth = xpa ? 11 : 8; | 86 | int pwidth = xpa ? 11 : 8; |
| @@ -92,7 +94,12 @@ static void dump_tlb(int first, int last) | |||
| 92 | s_pagemask = read_c0_pagemask(); | 94 | s_pagemask = read_c0_pagemask(); |
| 93 | s_entryhi = read_c0_entryhi(); | 95 | s_entryhi = read_c0_entryhi(); |
| 94 | s_index = read_c0_index(); | 96 | s_index = read_c0_index(); |
| 95 | asid = s_entryhi & asidmask; | 97 | |
| 98 | if (cpu_has_mmid) | ||
| 99 | asid = s_mmid = read_c0_memorymapid(); | ||
| 100 | else | ||
| 101 | asid = s_entryhi & asidmask; | ||
| 102 | |||
| 96 | if (cpu_has_guestid) | 103 | if (cpu_has_guestid) |
| 97 | s_guestctl1 = read_c0_guestctl1(); | 104 | s_guestctl1 = read_c0_guestctl1(); |
| 98 | 105 | ||
| @@ -105,6 +112,12 @@ static void dump_tlb(int first, int last) | |||
| 105 | entryhi = read_c0_entryhi(); | 112 | entryhi = read_c0_entryhi(); |
| 106 | entrylo0 = read_c0_entrylo0(); | 113 | entrylo0 = read_c0_entrylo0(); |
| 107 | entrylo1 = read_c0_entrylo1(); | 114 | entrylo1 = read_c0_entrylo1(); |
| 115 | |||
| 116 | if (cpu_has_mmid) | ||
| 117 | mmid = read_c0_memorymapid(); | ||
| 118 | else | ||
| 119 | mmid = entryhi & asidmask; | ||
| 120 | |||
| 108 | if (cpu_has_guestid) | 121 | if (cpu_has_guestid) |
| 109 | guestctl1 = read_c0_guestctl1(); | 122 | guestctl1 = read_c0_guestctl1(); |
| 110 | 123 | ||
| @@ -124,8 +137,7 @@ static void dump_tlb(int first, int last) | |||
| 124 | * leave only a single G bit set after a machine check exception | 137 | * leave only a single G bit set after a machine check exception |
| 125 | * due to duplicate TLB entry. | 138 | * due to duplicate TLB entry. |
| 126 | */ | 139 | */ |
| 127 | if (!((entrylo0 | entrylo1) & ENTRYLO_G) && | 140 | if (!((entrylo0 | entrylo1) & ENTRYLO_G) && (mmid != asid)) |
| 128 | (entryhi & asidmask) != asid) | ||
| 129 | continue; | 141 | continue; |
| 130 | 142 | ||
| 131 | /* | 143 | /* |
| @@ -138,7 +150,7 @@ static void dump_tlb(int first, int last) | |||
| 138 | 150 | ||
| 139 | pr_cont("va=%0*lx asid=%0*lx", | 151 | pr_cont("va=%0*lx asid=%0*lx", |
| 140 | vwidth, (entryhi & ~0x1fffUL), | 152 | vwidth, (entryhi & ~0x1fffUL), |
| 141 | asidwidth, entryhi & asidmask); | 153 | asidwidth, mmid); |
| 142 | if (cpu_has_guestid) | 154 | if (cpu_has_guestid) |
| 143 | pr_cont(" gid=%02lx", | 155 | pr_cont(" gid=%02lx", |
| 144 | (guestctl1 & MIPS_GCTL1_RID) | 156 | (guestctl1 & MIPS_GCTL1_RID) |
diff --git a/arch/mips/loongson32/Kconfig b/arch/mips/loongson32/Kconfig index 462b126f45aa..6dacc1438906 100644 --- a/arch/mips/loongson32/Kconfig +++ b/arch/mips/loongson32/Kconfig | |||
| @@ -15,7 +15,6 @@ config LOONGSON1_LS1B | |||
| 15 | select SYS_SUPPORTS_32BIT_KERNEL | 15 | select SYS_SUPPORTS_32BIT_KERNEL |
| 16 | select SYS_SUPPORTS_LITTLE_ENDIAN | 16 | select SYS_SUPPORTS_LITTLE_ENDIAN |
| 17 | select SYS_SUPPORTS_HIGHMEM | 17 | select SYS_SUPPORTS_HIGHMEM |
| 18 | select SYS_SUPPORTS_MIPS16 | ||
| 19 | select SYS_HAS_EARLY_PRINTK | 18 | select SYS_HAS_EARLY_PRINTK |
| 20 | select USE_GENERIC_EARLY_PRINTK_8250 | 19 | select USE_GENERIC_EARLY_PRINTK_8250 |
| 21 | select COMMON_CLK | 20 | select COMMON_CLK |
| @@ -31,7 +30,6 @@ config LOONGSON1_LS1C | |||
| 31 | select SYS_SUPPORTS_32BIT_KERNEL | 30 | select SYS_SUPPORTS_32BIT_KERNEL |
| 32 | select SYS_SUPPORTS_LITTLE_ENDIAN | 31 | select SYS_SUPPORTS_LITTLE_ENDIAN |
| 33 | select SYS_SUPPORTS_HIGHMEM | 32 | select SYS_SUPPORTS_HIGHMEM |
| 34 | select SYS_SUPPORTS_MIPS16 | ||
| 35 | select SYS_HAS_EARLY_PRINTK | 33 | select SYS_HAS_EARLY_PRINTK |
| 36 | select USE_GENERIC_EARLY_PRINTK_8250 | 34 | select USE_GENERIC_EARLY_PRINTK_8250 |
| 37 | select COMMON_CLK | 35 | select COMMON_CLK |
diff --git a/arch/mips/loongson32/Platform b/arch/mips/loongson32/Platform index a0dbb3b2f2de..333215593092 100644 --- a/arch/mips/loongson32/Platform +++ b/arch/mips/loongson32/Platform | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | cflags-$(CONFIG_CPU_LOONGSON1) += -march=mips32 -Wa,--trap | 1 | cflags-$(CONFIG_CPU_LOONGSON1) += -march=mips32r2 -Wa,--trap |
| 2 | platform-$(CONFIG_MACH_LOONGSON32) += loongson32/ | 2 | platform-$(CONFIG_MACH_LOONGSON32) += loongson32/ |
| 3 | cflags-$(CONFIG_MACH_LOONGSON32) += -I$(srctree)/arch/mips/include/asm/mach-loongson32 | 3 | cflags-$(CONFIG_MACH_LOONGSON32) += -I$(srctree)/arch/mips/include/asm/mach-loongson32 |
| 4 | load-$(CONFIG_CPU_LOONGSON1) += 0xffffffff80100000 | 4 | load-$(CONFIG_CPU_LOONGSON1) += 0xffffffff80200000 |
diff --git a/arch/mips/loongson32/common/platform.c b/arch/mips/loongson32/common/platform.c index ac584c5823d0..0bf355c8bcb2 100644 --- a/arch/mips/loongson32/common/platform.c +++ b/arch/mips/loongson32/common/platform.c | |||
| @@ -81,42 +81,6 @@ struct platform_device ls1x_cpufreq_pdev = { | |||
| 81 | }, | 81 | }, |
| 82 | }; | 82 | }; |
| 83 | 83 | ||
| 84 | /* DMA */ | ||
| 85 | static struct resource ls1x_dma_resources[] = { | ||
| 86 | [0] = { | ||
| 87 | .start = LS1X_DMAC_BASE, | ||
| 88 | .end = LS1X_DMAC_BASE + SZ_4 - 1, | ||
| 89 | .flags = IORESOURCE_MEM, | ||
| 90 | }, | ||
| 91 | [1] = { | ||
| 92 | .start = LS1X_DMA0_IRQ, | ||
| 93 | .end = LS1X_DMA0_IRQ, | ||
| 94 | .flags = IORESOURCE_IRQ, | ||
| 95 | }, | ||
| 96 | [2] = { | ||
| 97 | .start = LS1X_DMA1_IRQ, | ||
| 98 | .end = LS1X_DMA1_IRQ, | ||
| 99 | .flags = IORESOURCE_IRQ, | ||
| 100 | }, | ||
| 101 | [3] = { | ||
| 102 | .start = LS1X_DMA2_IRQ, | ||
| 103 | .end = LS1X_DMA2_IRQ, | ||
| 104 | .flags = IORESOURCE_IRQ, | ||
| 105 | }, | ||
| 106 | }; | ||
| 107 | |||
| 108 | struct platform_device ls1x_dma_pdev = { | ||
| 109 | .name = "ls1x-dma", | ||
| 110 | .id = -1, | ||
| 111 | .num_resources = ARRAY_SIZE(ls1x_dma_resources), | ||
| 112 | .resource = ls1x_dma_resources, | ||
| 113 | }; | ||
| 114 | |||
| 115 | void __init ls1x_dma_set_platdata(struct plat_ls1x_dma *pdata) | ||
| 116 | { | ||
| 117 | ls1x_dma_pdev.dev.platform_data = pdata; | ||
| 118 | } | ||
| 119 | |||
| 120 | /* Synopsys Ethernet GMAC */ | 84 | /* Synopsys Ethernet GMAC */ |
| 121 | static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = { | 85 | static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = { |
| 122 | .phy_mask = 0, | 86 | .phy_mask = 0, |
| @@ -291,33 +255,6 @@ struct platform_device ls1x_gpio1_pdev = { | |||
| 291 | .resource = ls1x_gpio1_resources, | 255 | .resource = ls1x_gpio1_resources, |
| 292 | }; | 256 | }; |
| 293 | 257 | ||
| 294 | /* NAND Flash */ | ||
| 295 | static struct resource ls1x_nand_resources[] = { | ||
| 296 | [0] = { | ||
| 297 | .start = LS1X_NAND_BASE, | ||
| 298 | .end = LS1X_NAND_BASE + SZ_32 - 1, | ||
| 299 | .flags = IORESOURCE_MEM, | ||
| 300 | }, | ||
| 301 | [1] = { | ||
| 302 | /* DMA channel 0 is dedicated to NAND */ | ||
| 303 | .start = LS1X_DMA_CHANNEL0, | ||
| 304 | .end = LS1X_DMA_CHANNEL0, | ||
| 305 | .flags = IORESOURCE_DMA, | ||
| 306 | }, | ||
| 307 | }; | ||
| 308 | |||
| 309 | struct platform_device ls1x_nand_pdev = { | ||
| 310 | .name = "ls1x-nand", | ||
| 311 | .id = -1, | ||
| 312 | .num_resources = ARRAY_SIZE(ls1x_nand_resources), | ||
| 313 | .resource = ls1x_nand_resources, | ||
| 314 | }; | ||
| 315 | |||
| 316 | void __init ls1x_nand_set_platdata(struct plat_ls1x_nand *pdata) | ||
| 317 | { | ||
| 318 | ls1x_nand_pdev.dev.platform_data = pdata; | ||
| 319 | } | ||
| 320 | |||
| 321 | /* USB EHCI */ | 258 | /* USB EHCI */ |
| 322 | static u64 ls1x_ehci_dmamask = DMA_BIT_MASK(32); | 259 | static u64 ls1x_ehci_dmamask = DMA_BIT_MASK(32); |
| 323 | 260 | ||
diff --git a/arch/mips/loongson32/ls1b/board.c b/arch/mips/loongson32/ls1b/board.c index 01aceaace314..447b15fc0a2b 100644 --- a/arch/mips/loongson32/ls1b/board.c +++ b/arch/mips/loongson32/ls1b/board.c | |||
| @@ -16,30 +16,6 @@ | |||
| 16 | #include <nand.h> | 16 | #include <nand.h> |
| 17 | #include <platform.h> | 17 | #include <platform.h> |
| 18 | 18 | ||
| 19 | struct plat_ls1x_dma ls1x_dma_pdata = { | ||
| 20 | .nr_channels = 3, | ||
| 21 | }; | ||
| 22 | |||
| 23 | static struct mtd_partition ls1x_nand_parts[] = { | ||
| 24 | { | ||
| 25 | .name = "kernel", | ||
| 26 | .offset = 0, | ||
| 27 | .size = SZ_16M, | ||
| 28 | }, | ||
| 29 | { | ||
| 30 | .name = "rootfs", | ||
| 31 | .offset = MTDPART_OFS_APPEND, | ||
| 32 | .size = MTDPART_SIZ_FULL, | ||
| 33 | }, | ||
| 34 | }; | ||
| 35 | |||
| 36 | struct plat_ls1x_nand ls1x_nand_pdata = { | ||
| 37 | .parts = ls1x_nand_parts, | ||
| 38 | .nr_parts = ARRAY_SIZE(ls1x_nand_parts), | ||
| 39 | .hold_cycle = 0x2, | ||
| 40 | .wait_cycle = 0xc, | ||
| 41 | }; | ||
| 42 | |||
| 43 | static const struct gpio_led ls1x_gpio_leds[] __initconst = { | 19 | static const struct gpio_led ls1x_gpio_leds[] __initconst = { |
| 44 | { | 20 | { |
| 45 | .name = "LED9", | 21 | .name = "LED9", |
| @@ -64,13 +40,11 @@ static const struct gpio_led_platform_data ls1x_led_pdata __initconst = { | |||
| 64 | static struct platform_device *ls1b_platform_devices[] __initdata = { | 40 | static struct platform_device *ls1b_platform_devices[] __initdata = { |
| 65 | &ls1x_uart_pdev, | 41 | &ls1x_uart_pdev, |
| 66 | &ls1x_cpufreq_pdev, | 42 | &ls1x_cpufreq_pdev, |
| 67 | &ls1x_dma_pdev, | ||
| 68 | &ls1x_eth0_pdev, | 43 | &ls1x_eth0_pdev, |
| 69 | &ls1x_eth1_pdev, | 44 | &ls1x_eth1_pdev, |
| 70 | &ls1x_ehci_pdev, | 45 | &ls1x_ehci_pdev, |
| 71 | &ls1x_gpio0_pdev, | 46 | &ls1x_gpio0_pdev, |
| 72 | &ls1x_gpio1_pdev, | 47 | &ls1x_gpio1_pdev, |
| 73 | &ls1x_nand_pdev, | ||
| 74 | &ls1x_rtc_pdev, | 48 | &ls1x_rtc_pdev, |
| 75 | &ls1x_wdt_pdev, | 49 | &ls1x_wdt_pdev, |
| 76 | }; | 50 | }; |
| @@ -78,8 +52,6 @@ static struct platform_device *ls1b_platform_devices[] __initdata = { | |||
| 78 | static int __init ls1b_platform_init(void) | 52 | static int __init ls1b_platform_init(void) |
| 79 | { | 53 | { |
| 80 | ls1x_serial_set_uartclk(&ls1x_uart_pdev); | 54 | ls1x_serial_set_uartclk(&ls1x_uart_pdev); |
| 81 | ls1x_dma_set_platdata(&ls1x_dma_pdata); | ||
| 82 | ls1x_nand_set_platdata(&ls1x_nand_pdata); | ||
| 83 | 55 | ||
| 84 | gpio_led_register_device(-1, &ls1x_led_pdata); | 56 | gpio_led_register_device(-1, &ls1x_led_pdata); |
| 85 | 57 | ||
diff --git a/arch/mips/math-emu/me-debugfs.c b/arch/mips/math-emu/me-debugfs.c index 58798f527356..387724860fa6 100644 --- a/arch/mips/math-emu/me-debugfs.c +++ b/arch/mips/math-emu/me-debugfs.c | |||
| @@ -189,32 +189,21 @@ static int __init debugfs_fpuemu(void) | |||
| 189 | { | 189 | { |
| 190 | struct dentry *fpuemu_debugfs_base_dir; | 190 | struct dentry *fpuemu_debugfs_base_dir; |
| 191 | struct dentry *fpuemu_debugfs_inst_dir; | 191 | struct dentry *fpuemu_debugfs_inst_dir; |
| 192 | struct dentry *d, *reset_file; | ||
| 193 | |||
| 194 | if (!mips_debugfs_dir) | ||
| 195 | return -ENODEV; | ||
| 196 | 192 | ||
| 197 | fpuemu_debugfs_base_dir = debugfs_create_dir("fpuemustats", | 193 | fpuemu_debugfs_base_dir = debugfs_create_dir("fpuemustats", |
| 198 | mips_debugfs_dir); | 194 | mips_debugfs_dir); |
| 199 | if (!fpuemu_debugfs_base_dir) | ||
| 200 | return -ENOMEM; | ||
| 201 | 195 | ||
| 202 | reset_file = debugfs_create_file("fpuemustats_clear", 0444, | 196 | debugfs_create_file("fpuemustats_clear", 0444, mips_debugfs_dir, NULL, |
| 203 | mips_debugfs_dir, NULL, | 197 | &fpuemustats_clear_fops); |
| 204 | &fpuemustats_clear_fops); | ||
| 205 | if (!reset_file) | ||
| 206 | return -ENOMEM; | ||
| 207 | 198 | ||
| 208 | #define FPU_EMU_STAT_OFFSET(m) \ | 199 | #define FPU_EMU_STAT_OFFSET(m) \ |
| 209 | offsetof(struct mips_fpu_emulator_stats, m) | 200 | offsetof(struct mips_fpu_emulator_stats, m) |
| 210 | 201 | ||
| 211 | #define FPU_STAT_CREATE(m) \ | 202 | #define FPU_STAT_CREATE(m) \ |
| 212 | do { \ | 203 | do { \ |
| 213 | d = debugfs_create_file(#m, 0444, fpuemu_debugfs_base_dir, \ | 204 | debugfs_create_file(#m, 0444, fpuemu_debugfs_base_dir, \ |
| 214 | (void *)FPU_EMU_STAT_OFFSET(m), \ | 205 | (void *)FPU_EMU_STAT_OFFSET(m), \ |
| 215 | &fops_fpuemu_stat); \ | 206 | &fops_fpuemu_stat); \ |
| 216 | if (!d) \ | ||
| 217 | return -ENOMEM; \ | ||
| 218 | } while (0) | 207 | } while (0) |
| 219 | 208 | ||
| 220 | FPU_STAT_CREATE(emulated); | 209 | FPU_STAT_CREATE(emulated); |
| @@ -233,8 +222,6 @@ do { \ | |||
| 233 | 222 | ||
| 234 | fpuemu_debugfs_inst_dir = debugfs_create_dir("instructions", | 223 | fpuemu_debugfs_inst_dir = debugfs_create_dir("instructions", |
| 235 | fpuemu_debugfs_base_dir); | 224 | fpuemu_debugfs_base_dir); |
| 236 | if (!fpuemu_debugfs_inst_dir) | ||
| 237 | return -ENOMEM; | ||
| 238 | 225 | ||
| 239 | #define FPU_STAT_CREATE_EX(m) \ | 226 | #define FPU_STAT_CREATE_EX(m) \ |
| 240 | do { \ | 227 | do { \ |
| @@ -242,11 +229,9 @@ do { \ | |||
| 242 | \ | 229 | \ |
| 243 | adjust_instruction_counter_name(name, #m); \ | 230 | adjust_instruction_counter_name(name, #m); \ |
| 244 | \ | 231 | \ |
| 245 | d = debugfs_create_file(name, 0444, fpuemu_debugfs_inst_dir, \ | 232 | debugfs_create_file(name, 0444, fpuemu_debugfs_inst_dir, \ |
| 246 | (void *)FPU_EMU_STAT_OFFSET(m), \ | 233 | (void *)FPU_EMU_STAT_OFFSET(m), \ |
| 247 | &fops_fpuemu_stat); \ | 234 | &fops_fpuemu_stat); \ |
| 248 | if (!d) \ | ||
| 249 | return -ENOMEM; \ | ||
| 250 | } while (0) | 235 | } while (0) |
| 251 | 236 | ||
| 252 | FPU_STAT_CREATE_EX(abs_s); | 237 | FPU_STAT_CREATE_EX(abs_s); |
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index 3e5bb203c95a..f34d7ff5eb60 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile | |||
| @@ -3,9 +3,19 @@ | |||
| 3 | # Makefile for the Linux/MIPS-specific parts of the memory manager. | 3 | # Makefile for the Linux/MIPS-specific parts of the memory manager. |
| 4 | # | 4 | # |
| 5 | 5 | ||
| 6 | obj-y += cache.o extable.o fault.o \ | 6 | obj-y += cache.o |
| 7 | gup.o init.o mmap.o page.o page-funcs.o \ | 7 | obj-y += context.o |
| 8 | pgtable.o tlbex.o tlbex-fault.o tlb-funcs.o | 8 | obj-y += extable.o |
| 9 | obj-y += fault.o | ||
| 10 | obj-y += gup.o | ||
| 11 | obj-y += init.o | ||
| 12 | obj-y += mmap.o | ||
| 13 | obj-y += page.o | ||
| 14 | obj-y += page-funcs.o | ||
| 15 | obj-y += pgtable.o | ||
| 16 | obj-y += tlbex.o | ||
| 17 | obj-y += tlbex-fault.o | ||
| 18 | obj-y += tlb-funcs.o | ||
| 9 | 19 | ||
| 10 | ifdef CONFIG_CPU_MICROMIPS | 20 | ifdef CONFIG_CPU_MICROMIPS |
| 11 | obj-y += uasm-micromips.o | 21 | obj-y += uasm-micromips.o |
diff --git a/arch/mips/mm/c-octeon.c b/arch/mips/mm/c-octeon.c index 0e45b061e514..8064821e9805 100644 --- a/arch/mips/mm/c-octeon.c +++ b/arch/mips/mm/c-octeon.c | |||
| @@ -128,23 +128,6 @@ static void octeon_flush_icache_range(unsigned long start, unsigned long end) | |||
| 128 | 128 | ||
| 129 | 129 | ||
| 130 | /** | 130 | /** |
| 131 | * Flush the icache for a trampoline. These are used for interrupt | ||
| 132 | * and exception hooking. | ||
| 133 | * | ||
| 134 | * @addr: Address to flush | ||
| 135 | */ | ||
| 136 | static void octeon_flush_cache_sigtramp(unsigned long addr) | ||
| 137 | { | ||
| 138 | struct vm_area_struct *vma; | ||
| 139 | |||
| 140 | down_read(¤t->mm->mmap_sem); | ||
| 141 | vma = find_vma(current->mm, addr); | ||
| 142 | octeon_flush_icache_all_cores(vma); | ||
| 143 | up_read(¤t->mm->mmap_sem); | ||
| 144 | } | ||
| 145 | |||
| 146 | |||
| 147 | /** | ||
| 148 | * Flush a range out of a vma | 131 | * Flush a range out of a vma |
| 149 | * | 132 | * |
| 150 | * @vma: VMA to flush | 133 | * @vma: VMA to flush |
| @@ -289,7 +272,6 @@ void octeon_cache_init(void) | |||
| 289 | flush_cache_mm = octeon_flush_cache_mm; | 272 | flush_cache_mm = octeon_flush_cache_mm; |
| 290 | flush_cache_page = octeon_flush_cache_page; | 273 | flush_cache_page = octeon_flush_cache_page; |
| 291 | flush_cache_range = octeon_flush_cache_range; | 274 | flush_cache_range = octeon_flush_cache_range; |
| 292 | flush_cache_sigtramp = octeon_flush_cache_sigtramp; | ||
| 293 | flush_icache_all = octeon_flush_icache_all; | 275 | flush_icache_all = octeon_flush_icache_all; |
| 294 | flush_data_cache_page = octeon_flush_data_cache_page; | 276 | flush_data_cache_page = octeon_flush_data_cache_page; |
| 295 | flush_icache_range = octeon_flush_icache_range; | 277 | flush_icache_range = octeon_flush_icache_range; |
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c index 01848cdf2074..0ca401ddf3b7 100644 --- a/arch/mips/mm/c-r3k.c +++ b/arch/mips/mm/c-r3k.c | |||
| @@ -274,30 +274,6 @@ static void r3k_flush_data_cache_page(unsigned long addr) | |||
| 274 | { | 274 | { |
| 275 | } | 275 | } |
| 276 | 276 | ||
| 277 | static void r3k_flush_cache_sigtramp(unsigned long addr) | ||
| 278 | { | ||
| 279 | unsigned long flags; | ||
| 280 | |||
| 281 | pr_debug("csigtramp[%08lx]\n", addr); | ||
| 282 | |||
| 283 | flags = read_c0_status(); | ||
| 284 | |||
| 285 | write_c0_status(flags&~ST0_IEC); | ||
| 286 | |||
| 287 | /* Fill the TLB to avoid an exception with caches isolated. */ | ||
| 288 | asm( "lw\t$0, 0x000(%0)\n\t" | ||
| 289 | "lw\t$0, 0x004(%0)\n\t" | ||
| 290 | : : "r" (addr) ); | ||
| 291 | |||
| 292 | write_c0_status((ST0_ISC|ST0_SWC|flags)&~ST0_IEC); | ||
| 293 | |||
| 294 | asm( "sb\t$0, 0x000(%0)\n\t" | ||
| 295 | "sb\t$0, 0x004(%0)\n\t" | ||
| 296 | : : "r" (addr) ); | ||
| 297 | |||
| 298 | write_c0_status(flags); | ||
| 299 | } | ||
| 300 | |||
| 301 | static void r3k_flush_kernel_vmap_range(unsigned long vaddr, int size) | 277 | static void r3k_flush_kernel_vmap_range(unsigned long vaddr, int size) |
| 302 | { | 278 | { |
| 303 | BUG(); | 279 | BUG(); |
| @@ -331,7 +307,6 @@ void r3k_cache_init(void) | |||
| 331 | 307 | ||
| 332 | __flush_kernel_vmap_range = r3k_flush_kernel_vmap_range; | 308 | __flush_kernel_vmap_range = r3k_flush_kernel_vmap_range; |
| 333 | 309 | ||
| 334 | flush_cache_sigtramp = r3k_flush_cache_sigtramp; | ||
| 335 | local_flush_data_cache_page = local_r3k_flush_data_cache_page; | 310 | local_flush_data_cache_page = local_r3k_flush_data_cache_page; |
| 336 | flush_data_cache_page = r3k_flush_data_cache_page; | 311 | flush_data_cache_page = r3k_flush_data_cache_page; |
| 337 | 312 | ||
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index d0b64df51eb2..5166e38cd1c6 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
| @@ -540,6 +540,9 @@ static inline int has_valid_asid(const struct mm_struct *mm, unsigned int type) | |||
| 540 | unsigned int i; | 540 | unsigned int i; |
| 541 | const cpumask_t *mask = cpu_present_mask; | 541 | const cpumask_t *mask = cpu_present_mask; |
| 542 | 542 | ||
| 543 | if (cpu_has_mmid) | ||
| 544 | return cpu_context(0, mm) != 0; | ||
| 545 | |||
| 543 | /* cpu_sibling_map[] undeclared when !CONFIG_SMP */ | 546 | /* cpu_sibling_map[] undeclared when !CONFIG_SMP */ |
| 544 | #ifdef CONFIG_SMP | 547 | #ifdef CONFIG_SMP |
| 545 | /* | 548 | /* |
| @@ -697,10 +700,7 @@ static inline void local_r4k_flush_cache_page(void *args) | |||
| 697 | } | 700 | } |
| 698 | if (exec) { | 701 | if (exec) { |
| 699 | if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) { | 702 | if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) { |
| 700 | int cpu = smp_processor_id(); | 703 | drop_mmu_context(mm); |
| 701 | |||
| 702 | if (cpu_context(cpu, mm) != 0) | ||
| 703 | drop_mmu_context(mm, cpu); | ||
| 704 | } else | 704 | } else |
| 705 | vaddr ? r4k_blast_icache_page(addr) : | 705 | vaddr ? r4k_blast_icache_page(addr) : |
| 706 | r4k_blast_icache_user_page(addr); | 706 | r4k_blast_icache_user_page(addr); |
| @@ -937,119 +937,6 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) | |||
| 937 | } | 937 | } |
| 938 | #endif /* CONFIG_DMA_NONCOHERENT */ | 938 | #endif /* CONFIG_DMA_NONCOHERENT */ |
| 939 | 939 | ||
| 940 | struct flush_cache_sigtramp_args { | ||
| 941 | struct mm_struct *mm; | ||
| 942 | struct page *page; | ||
| 943 | unsigned long addr; | ||
| 944 | }; | ||
| 945 | |||
| 946 | /* | ||
| 947 | * While we're protected against bad userland addresses we don't care | ||
| 948 | * very much about what happens in that case. Usually a segmentation | ||
| 949 | * fault will dump the process later on anyway ... | ||
| 950 | */ | ||
| 951 | static void local_r4k_flush_cache_sigtramp(void *args) | ||
| 952 | { | ||
| 953 | struct flush_cache_sigtramp_args *fcs_args = args; | ||
| 954 | unsigned long addr = fcs_args->addr; | ||
| 955 | struct page *page = fcs_args->page; | ||
| 956 | struct mm_struct *mm = fcs_args->mm; | ||
| 957 | int map_coherent = 0; | ||
| 958 | void *vaddr; | ||
| 959 | |||
| 960 | unsigned long ic_lsize = cpu_icache_line_size(); | ||
| 961 | unsigned long dc_lsize = cpu_dcache_line_size(); | ||
| 962 | unsigned long sc_lsize = cpu_scache_line_size(); | ||
| 963 | |||
| 964 | /* | ||
| 965 | * If owns no valid ASID yet, cannot possibly have gotten | ||
| 966 | * this page into the cache. | ||
| 967 | */ | ||
| 968 | if (!has_valid_asid(mm, R4K_HIT)) | ||
| 969 | return; | ||
| 970 | |||
| 971 | if (mm == current->active_mm) { | ||
| 972 | vaddr = NULL; | ||
| 973 | } else { | ||
| 974 | /* | ||
| 975 | * Use kmap_coherent or kmap_atomic to do flushes for | ||
| 976 | * another ASID than the current one. | ||
| 977 | */ | ||
| 978 | map_coherent = (cpu_has_dc_aliases && | ||
| 979 | page_mapcount(page) && | ||
| 980 | !Page_dcache_dirty(page)); | ||
| 981 | if (map_coherent) | ||
| 982 | vaddr = kmap_coherent(page, addr); | ||
| 983 | else | ||
| 984 | vaddr = kmap_atomic(page); | ||
| 985 | addr = (unsigned long)vaddr + (addr & ~PAGE_MASK); | ||
| 986 | } | ||
| 987 | |||
| 988 | R4600_HIT_CACHEOP_WAR_IMPL; | ||
| 989 | if (!cpu_has_ic_fills_f_dc) { | ||
| 990 | if (dc_lsize) | ||
| 991 | vaddr ? flush_dcache_line(addr & ~(dc_lsize - 1)) | ||
| 992 | : protected_writeback_dcache_line( | ||
| 993 | addr & ~(dc_lsize - 1)); | ||
| 994 | if (!cpu_icache_snoops_remote_store && scache_size) | ||
| 995 | vaddr ? flush_scache_line(addr & ~(sc_lsize - 1)) | ||
| 996 | : protected_writeback_scache_line( | ||
| 997 | addr & ~(sc_lsize - 1)); | ||
| 998 | } | ||
| 999 | if (ic_lsize) | ||
| 1000 | vaddr ? flush_icache_line(addr & ~(ic_lsize - 1)) | ||
| 1001 | : protected_flush_icache_line(addr & ~(ic_lsize - 1)); | ||
| 1002 | |||
| 1003 | if (vaddr) { | ||
| 1004 | if (map_coherent) | ||
| 1005 | kunmap_coherent(); | ||
| 1006 | else | ||
| 1007 | kunmap_atomic(vaddr); | ||
| 1008 | } | ||
| 1009 | |||
| 1010 | if (MIPS4K_ICACHE_REFILL_WAR) { | ||
| 1011 | __asm__ __volatile__ ( | ||
| 1012 | ".set push\n\t" | ||
| 1013 | ".set noat\n\t" | ||
| 1014 | ".set "MIPS_ISA_LEVEL"\n\t" | ||
| 1015 | #ifdef CONFIG_32BIT | ||
| 1016 | "la $at,1f\n\t" | ||
| 1017 | #endif | ||
| 1018 | #ifdef CONFIG_64BIT | ||
| 1019 | "dla $at,1f\n\t" | ||
| 1020 | #endif | ||
| 1021 | "cache %0,($at)\n\t" | ||
| 1022 | "nop; nop; nop\n" | ||
| 1023 | "1:\n\t" | ||
| 1024 | ".set pop" | ||
| 1025 | : | ||
| 1026 | : "i" (Hit_Invalidate_I)); | ||
| 1027 | } | ||
| 1028 | if (MIPS_CACHE_SYNC_WAR) | ||
| 1029 | __asm__ __volatile__ ("sync"); | ||
| 1030 | } | ||
| 1031 | |||
| 1032 | static void r4k_flush_cache_sigtramp(unsigned long addr) | ||
| 1033 | { | ||
| 1034 | struct flush_cache_sigtramp_args args; | ||
| 1035 | int npages; | ||
| 1036 | |||
| 1037 | down_read(¤t->mm->mmap_sem); | ||
| 1038 | |||
| 1039 | npages = get_user_pages_fast(addr, 1, 0, &args.page); | ||
| 1040 | if (npages < 1) | ||
| 1041 | goto out; | ||
| 1042 | |||
| 1043 | args.mm = current->mm; | ||
| 1044 | args.addr = addr; | ||
| 1045 | |||
| 1046 | r4k_on_each_cpu(R4K_HIT, local_r4k_flush_cache_sigtramp, &args); | ||
| 1047 | |||
| 1048 | put_page(args.page); | ||
| 1049 | out: | ||
| 1050 | up_read(¤t->mm->mmap_sem); | ||
| 1051 | } | ||
| 1052 | |||
| 1053 | static void r4k_flush_icache_all(void) | 940 | static void r4k_flush_icache_all(void) |
| 1054 | { | 941 | { |
| 1055 | if (cpu_has_vtag_icache) | 942 | if (cpu_has_vtag_icache) |
| @@ -1978,7 +1865,6 @@ void r4k_cache_init(void) | |||
| 1978 | 1865 | ||
| 1979 | __flush_kernel_vmap_range = r4k_flush_kernel_vmap_range; | 1866 | __flush_kernel_vmap_range = r4k_flush_kernel_vmap_range; |
| 1980 | 1867 | ||
| 1981 | flush_cache_sigtramp = r4k_flush_cache_sigtramp; | ||
| 1982 | flush_icache_all = r4k_flush_icache_all; | 1868 | flush_icache_all = r4k_flush_icache_all; |
| 1983 | local_flush_data_cache_page = local_r4k_flush_data_cache_page; | 1869 | local_flush_data_cache_page = local_r4k_flush_data_cache_page; |
| 1984 | flush_data_cache_page = r4k_flush_data_cache_page; | 1870 | flush_data_cache_page = r4k_flush_data_cache_page; |
| @@ -2033,7 +1919,6 @@ void r4k_cache_init(void) | |||
| 2033 | /* I$ fills from D$ just by emptying the write buffers */ | 1919 | /* I$ fills from D$ just by emptying the write buffers */ |
| 2034 | flush_cache_page = (void *)b5k_instruction_hazard; | 1920 | flush_cache_page = (void *)b5k_instruction_hazard; |
| 2035 | flush_cache_range = (void *)b5k_instruction_hazard; | 1921 | flush_cache_range = (void *)b5k_instruction_hazard; |
| 2036 | flush_cache_sigtramp = (void *)b5k_instruction_hazard; | ||
| 2037 | local_flush_data_cache_page = (void *)b5k_instruction_hazard; | 1922 | local_flush_data_cache_page = (void *)b5k_instruction_hazard; |
| 2038 | flush_data_cache_page = (void *)b5k_instruction_hazard; | 1923 | flush_data_cache_page = (void *)b5k_instruction_hazard; |
| 2039 | flush_icache_range = (void *)b5k_instruction_hazard; | 1924 | flush_icache_range = (void *)b5k_instruction_hazard; |
| @@ -2052,7 +1937,6 @@ void r4k_cache_init(void) | |||
| 2052 | flush_cache_mm = (void *)cache_noop; | 1937 | flush_cache_mm = (void *)cache_noop; |
| 2053 | flush_cache_page = (void *)cache_noop; | 1938 | flush_cache_page = (void *)cache_noop; |
| 2054 | flush_cache_range = (void *)cache_noop; | 1939 | flush_cache_range = (void *)cache_noop; |
| 2055 | flush_cache_sigtramp = (void *)cache_noop; | ||
| 2056 | flush_icache_all = (void *)cache_noop; | 1940 | flush_icache_all = (void *)cache_noop; |
| 2057 | flush_data_cache_page = (void *)cache_noop; | 1941 | flush_data_cache_page = (void *)cache_noop; |
| 2058 | local_flush_data_cache_page = (void *)cache_noop; | 1942 | local_flush_data_cache_page = (void *)cache_noop; |
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c index 5f6c099a9457..b7c8a9d79c35 100644 --- a/arch/mips/mm/c-tx39.c +++ b/arch/mips/mm/c-tx39.c | |||
| @@ -290,25 +290,6 @@ static void tx39_dma_cache_inv(unsigned long addr, unsigned long size) | |||
| 290 | } | 290 | } |
| 291 | } | 291 | } |
| 292 | 292 | ||
| 293 | static void tx39_flush_cache_sigtramp(unsigned long addr) | ||
| 294 | { | ||
| 295 | unsigned long ic_lsize = current_cpu_data.icache.linesz; | ||
| 296 | unsigned long dc_lsize = current_cpu_data.dcache.linesz; | ||
| 297 | unsigned long config; | ||
| 298 | unsigned long flags; | ||
| 299 | |||
| 300 | protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); | ||
| 301 | |||
| 302 | /* disable icache (set ICE#) */ | ||
| 303 | local_irq_save(flags); | ||
| 304 | config = read_c0_conf(); | ||
| 305 | write_c0_conf(config & ~TX39_CONF_ICE); | ||
| 306 | TX39_STOP_STREAMING(); | ||
| 307 | protected_flush_icache_line(addr & ~(ic_lsize - 1)); | ||
| 308 | write_c0_conf(config); | ||
| 309 | local_irq_restore(flags); | ||
| 310 | } | ||
| 311 | |||
| 312 | static __init void tx39_probe_cache(void) | 293 | static __init void tx39_probe_cache(void) |
| 313 | { | 294 | { |
| 314 | unsigned long config; | 295 | unsigned long config; |
| @@ -368,7 +349,6 @@ void tx39_cache_init(void) | |||
| 368 | flush_icache_range = (void *) tx39h_flush_icache_all; | 349 | flush_icache_range = (void *) tx39h_flush_icache_all; |
| 369 | local_flush_icache_range = (void *) tx39h_flush_icache_all; | 350 | local_flush_icache_range = (void *) tx39h_flush_icache_all; |
| 370 | 351 | ||
| 371 | flush_cache_sigtramp = (void *) tx39h_flush_icache_all; | ||
| 372 | local_flush_data_cache_page = (void *) tx39h_flush_icache_all; | 352 | local_flush_data_cache_page = (void *) tx39h_flush_icache_all; |
| 373 | flush_data_cache_page = (void *) tx39h_flush_icache_all; | 353 | flush_data_cache_page = (void *) tx39h_flush_icache_all; |
| 374 | 354 | ||
| @@ -397,7 +377,6 @@ void tx39_cache_init(void) | |||
| 397 | 377 | ||
| 398 | __flush_kernel_vmap_range = tx39_flush_kernel_vmap_range; | 378 | __flush_kernel_vmap_range = tx39_flush_kernel_vmap_range; |
| 399 | 379 | ||
| 400 | flush_cache_sigtramp = tx39_flush_cache_sigtramp; | ||
| 401 | local_flush_data_cache_page = local_tx39_flush_data_cache_page; | 380 | local_flush_data_cache_page = local_tx39_flush_data_cache_page; |
| 402 | flush_data_cache_page = tx39_flush_data_cache_page; | 381 | flush_data_cache_page = tx39_flush_data_cache_page; |
| 403 | 382 | ||
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 55099fbff4e6..3da216988672 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c | |||
| @@ -47,7 +47,6 @@ void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size); | |||
| 47 | EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range); | 47 | EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range); |
| 48 | 48 | ||
| 49 | /* MIPS specific cache operations */ | 49 | /* MIPS specific cache operations */ |
| 50 | void (*flush_cache_sigtramp)(unsigned long addr); | ||
| 51 | void (*local_flush_data_cache_page)(void * addr); | 50 | void (*local_flush_data_cache_page)(void * addr); |
| 52 | void (*flush_data_cache_page)(unsigned long addr); | 51 | void (*flush_data_cache_page)(unsigned long addr); |
| 53 | void (*flush_icache_all)(void); | 52 | void (*flush_icache_all)(void); |
diff --git a/arch/mips/mm/context.c b/arch/mips/mm/context.c new file mode 100644 index 000000000000..b25564090939 --- /dev/null +++ b/arch/mips/mm/context.c | |||
| @@ -0,0 +1,291 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | #include <linux/atomic.h> | ||
| 3 | #include <linux/mmu_context.h> | ||
| 4 | #include <linux/percpu.h> | ||
| 5 | #include <linux/spinlock.h> | ||
| 6 | |||
| 7 | static DEFINE_RAW_SPINLOCK(cpu_mmid_lock); | ||
| 8 | |||
| 9 | static atomic64_t mmid_version; | ||
| 10 | static unsigned int num_mmids; | ||
| 11 | static unsigned long *mmid_map; | ||
| 12 | |||
| 13 | static DEFINE_PER_CPU(u64, reserved_mmids); | ||
| 14 | static cpumask_t tlb_flush_pending; | ||
| 15 | |||
| 16 | static bool asid_versions_eq(int cpu, u64 a, u64 b) | ||
| 17 | { | ||
| 18 | return ((a ^ b) & asid_version_mask(cpu)) == 0; | ||
| 19 | } | ||
| 20 | |||
| 21 | void get_new_mmu_context(struct mm_struct *mm) | ||
| 22 | { | ||
| 23 | unsigned int cpu; | ||
| 24 | u64 asid; | ||
| 25 | |||
| 26 | /* | ||
| 27 | * This function is specific to ASIDs, and should not be called when | ||
| 28 | * MMIDs are in use. | ||
| 29 | */ | ||
| 30 | if (WARN_ON(IS_ENABLED(CONFIG_DEBUG_VM) && cpu_has_mmid)) | ||
| 31 | return; | ||
| 32 | |||
| 33 | cpu = smp_processor_id(); | ||
| 34 | asid = asid_cache(cpu); | ||
| 35 | |||
| 36 | if (!((asid += cpu_asid_inc()) & cpu_asid_mask(&cpu_data[cpu]))) { | ||
| 37 | if (cpu_has_vtag_icache) | ||
| 38 | flush_icache_all(); | ||
| 39 | local_flush_tlb_all(); /* start new asid cycle */ | ||
| 40 | } | ||
| 41 | |||
| 42 | set_cpu_context(cpu, mm, asid); | ||
| 43 | asid_cache(cpu) = asid; | ||
| 44 | } | ||
| 45 | EXPORT_SYMBOL_GPL(get_new_mmu_context); | ||
| 46 | |||
| 47 | void check_mmu_context(struct mm_struct *mm) | ||
| 48 | { | ||
| 49 | unsigned int cpu = smp_processor_id(); | ||
| 50 | |||
| 51 | /* | ||
| 52 | * This function is specific to ASIDs, and should not be called when | ||
| 53 | * MMIDs are in use. | ||
| 54 | */ | ||
| 55 | if (WARN_ON(IS_ENABLED(CONFIG_DEBUG_VM) && cpu_has_mmid)) | ||
| 56 | return; | ||
| 57 | |||
| 58 | /* Check if our ASID is of an older version and thus invalid */ | ||
| 59 | if (!asid_versions_eq(cpu, cpu_context(cpu, mm), asid_cache(cpu))) | ||
| 60 | get_new_mmu_context(mm); | ||
| 61 | } | ||
| 62 | EXPORT_SYMBOL_GPL(check_mmu_context); | ||
| 63 | |||
| 64 | static void flush_context(void) | ||
| 65 | { | ||
| 66 | u64 mmid; | ||
| 67 | int cpu; | ||
| 68 | |||
| 69 | /* Update the list of reserved MMIDs and the MMID bitmap */ | ||
| 70 | bitmap_clear(mmid_map, 0, num_mmids); | ||
| 71 | |||
| 72 | /* Reserve an MMID for kmap/wired entries */ | ||
| 73 | __set_bit(MMID_KERNEL_WIRED, mmid_map); | ||
| 74 | |||
| 75 | for_each_possible_cpu(cpu) { | ||
| 76 | mmid = xchg_relaxed(&cpu_data[cpu].asid_cache, 0); | ||
| 77 | |||
| 78 | /* | ||
| 79 | * If this CPU has already been through a | ||
| 80 | * rollover, but hasn't run another task in | ||
| 81 | * the meantime, we must preserve its reserved | ||
| 82 | * MMID, as this is the only trace we have of | ||
| 83 | * the process it is still running. | ||
| 84 | */ | ||
| 85 | if (mmid == 0) | ||
| 86 | mmid = per_cpu(reserved_mmids, cpu); | ||
| 87 | |||
| 88 | __set_bit(mmid & cpu_asid_mask(&cpu_data[cpu]), mmid_map); | ||
| 89 | per_cpu(reserved_mmids, cpu) = mmid; | ||
| 90 | } | ||
| 91 | |||
| 92 | /* | ||
| 93 | * Queue a TLB invalidation for each CPU to perform on next | ||
| 94 | * context-switch | ||
| 95 | */ | ||
| 96 | cpumask_setall(&tlb_flush_pending); | ||
| 97 | } | ||
| 98 | |||
| 99 | static bool check_update_reserved_mmid(u64 mmid, u64 newmmid) | ||
| 100 | { | ||
| 101 | bool hit; | ||
| 102 | int cpu; | ||
| 103 | |||
| 104 | /* | ||
| 105 | * Iterate over the set of reserved MMIDs looking for a match. | ||
| 106 | * If we find one, then we can update our mm to use newmmid | ||
| 107 | * (i.e. the same MMID in the current generation) but we can't | ||
| 108 | * exit the loop early, since we need to ensure that all copies | ||
| 109 | * of the old MMID are updated to reflect the mm. Failure to do | ||
| 110 | * so could result in us missing the reserved MMID in a future | ||
| 111 | * generation. | ||
| 112 | */ | ||
| 113 | hit = false; | ||
| 114 | for_each_possible_cpu(cpu) { | ||
| 115 | if (per_cpu(reserved_mmids, cpu) == mmid) { | ||
| 116 | hit = true; | ||
| 117 | per_cpu(reserved_mmids, cpu) = newmmid; | ||
| 118 | } | ||
| 119 | } | ||
| 120 | |||
| 121 | return hit; | ||
| 122 | } | ||
| 123 | |||
| 124 | static u64 get_new_mmid(struct mm_struct *mm) | ||
| 125 | { | ||
| 126 | static u32 cur_idx = MMID_KERNEL_WIRED + 1; | ||
| 127 | u64 mmid, version, mmid_mask; | ||
| 128 | |||
| 129 | mmid = cpu_context(0, mm); | ||
| 130 | version = atomic64_read(&mmid_version); | ||
| 131 | mmid_mask = cpu_asid_mask(&boot_cpu_data); | ||
| 132 | |||
| 133 | if (!asid_versions_eq(0, mmid, 0)) { | ||
| 134 | u64 newmmid = version | (mmid & mmid_mask); | ||
| 135 | |||
| 136 | /* | ||
| 137 | * If our current MMID was active during a rollover, we | ||
| 138 | * can continue to use it and this was just a false alarm. | ||
| 139 | */ | ||
| 140 | if (check_update_reserved_mmid(mmid, newmmid)) { | ||
| 141 | mmid = newmmid; | ||
| 142 | goto set_context; | ||
| 143 | } | ||
| 144 | |||
| 145 | /* | ||
| 146 | * We had a valid MMID in a previous life, so try to re-use | ||
| 147 | * it if possible. | ||
| 148 | */ | ||
| 149 | if (!__test_and_set_bit(mmid & mmid_mask, mmid_map)) { | ||
| 150 | mmid = newmmid; | ||
| 151 | goto set_context; | ||
| 152 | } | ||
| 153 | } | ||
| 154 | |||
| 155 | /* Allocate a free MMID */ | ||
| 156 | mmid = find_next_zero_bit(mmid_map, num_mmids, cur_idx); | ||
| 157 | if (mmid != num_mmids) | ||
| 158 | goto reserve_mmid; | ||
| 159 | |||
| 160 | /* We're out of MMIDs, so increment the global version */ | ||
| 161 | version = atomic64_add_return_relaxed(asid_first_version(0), | ||
| 162 | &mmid_version); | ||
| 163 | |||
| 164 | /* Note currently active MMIDs & mark TLBs as requiring flushes */ | ||
| 165 | flush_context(); | ||
| 166 | |||
| 167 | /* We have more MMIDs than CPUs, so this will always succeed */ | ||
| 168 | mmid = find_first_zero_bit(mmid_map, num_mmids); | ||
| 169 | |||
| 170 | reserve_mmid: | ||
| 171 | __set_bit(mmid, mmid_map); | ||
| 172 | cur_idx = mmid; | ||
| 173 | mmid |= version; | ||
| 174 | set_context: | ||
| 175 | set_cpu_context(0, mm, mmid); | ||
| 176 | return mmid; | ||
| 177 | } | ||
| 178 | |||
| 179 | void check_switch_mmu_context(struct mm_struct *mm) | ||
| 180 | { | ||
| 181 | unsigned int cpu = smp_processor_id(); | ||
| 182 | u64 ctx, old_active_mmid; | ||
| 183 | unsigned long flags; | ||
| 184 | |||
| 185 | if (!cpu_has_mmid) { | ||
| 186 | check_mmu_context(mm); | ||
| 187 | write_c0_entryhi(cpu_asid(cpu, mm)); | ||
| 188 | goto setup_pgd; | ||
| 189 | } | ||
| 190 | |||
| 191 | /* | ||
| 192 | * MMID switch fast-path, to avoid acquiring cpu_mmid_lock when it's | ||
| 193 | * unnecessary. | ||
| 194 | * | ||
| 195 | * The memory ordering here is subtle. If our active_mmids is non-zero | ||
| 196 | * and the MMID matches the current version, then we update the CPU's | ||
| 197 | * asid_cache with a relaxed cmpxchg. Racing with a concurrent rollover | ||
| 198 | * means that either: | ||
| 199 | * | ||
| 200 | * - We get a zero back from the cmpxchg and end up waiting on | ||
| 201 | * cpu_mmid_lock in check_mmu_context(). Taking the lock synchronises | ||
| 202 | * with the rollover and so we are forced to see the updated | ||
| 203 | * generation. | ||
| 204 | * | ||
| 205 | * - We get a valid MMID back from the cmpxchg, which means the | ||
| 206 | * relaxed xchg in flush_context will treat us as reserved | ||
| 207 | * because atomic RmWs are totally ordered for a given location. | ||
| 208 | */ | ||
| 209 | ctx = cpu_context(cpu, mm); | ||
| 210 | old_active_mmid = READ_ONCE(cpu_data[cpu].asid_cache); | ||
| 211 | if (!old_active_mmid || | ||
| 212 | !asid_versions_eq(cpu, ctx, atomic64_read(&mmid_version)) || | ||
| 213 | !cmpxchg_relaxed(&cpu_data[cpu].asid_cache, old_active_mmid, ctx)) { | ||
| 214 | raw_spin_lock_irqsave(&cpu_mmid_lock, flags); | ||
| 215 | |||
| 216 | ctx = cpu_context(cpu, mm); | ||
| 217 | if (!asid_versions_eq(cpu, ctx, atomic64_read(&mmid_version))) | ||
| 218 | ctx = get_new_mmid(mm); | ||
| 219 | |||
| 220 | WRITE_ONCE(cpu_data[cpu].asid_cache, ctx); | ||
| 221 | raw_spin_unlock_irqrestore(&cpu_mmid_lock, flags); | ||
| 222 | } | ||
| 223 | |||
| 224 | /* | ||
| 225 | * Invalidate the local TLB if needed. Note that we must only clear our | ||
| 226 | * bit in tlb_flush_pending after this is complete, so that the | ||
| 227 | * cpu_has_shared_ftlb_entries case below isn't misled. | ||
| 228 | */ | ||
| 229 | if (cpumask_test_cpu(cpu, &tlb_flush_pending)) { | ||
| 230 | if (cpu_has_vtag_icache) | ||
| 231 | flush_icache_all(); | ||
| 232 | local_flush_tlb_all(); | ||
| 233 | cpumask_clear_cpu(cpu, &tlb_flush_pending); | ||
| 234 | } | ||
| 235 | |||
| 236 | write_c0_memorymapid(ctx & cpu_asid_mask(&boot_cpu_data)); | ||
| 237 | |||
| 238 | /* | ||
| 239 | * If this CPU shares FTLB entries with its siblings and one or more of | ||
| 240 | * those siblings hasn't yet invalidated its TLB following a version | ||
| 241 | * increase then we need to invalidate any TLB entries for our MMID | ||
| 242 | * that we might otherwise pick up from a sibling. | ||
| 243 | * | ||
| 244 | * We ifdef on CONFIG_SMP because cpu_sibling_map isn't defined in | ||
| 245 | * CONFIG_SMP=n kernels. | ||
| 246 | */ | ||
| 247 | #ifdef CONFIG_SMP | ||
| 248 | if (cpu_has_shared_ftlb_entries && | ||
| 249 | cpumask_intersects(&tlb_flush_pending, &cpu_sibling_map[cpu])) { | ||
| 250 | /* Ensure we operate on the new MMID */ | ||
| 251 | mtc0_tlbw_hazard(); | ||
| 252 | |||
| 253 | /* | ||
| 254 | * Invalidate all TLB entries associated with the new | ||
| 255 | * MMID, and wait for the invalidation to complete. | ||
| 256 | */ | ||
| 257 | ginvt_mmid(); | ||
| 258 | sync_ginv(); | ||
| 259 | } | ||
| 260 | #endif | ||
| 261 | |||
| 262 | setup_pgd: | ||
| 263 | TLBMISS_HANDLER_SETUP_PGD(mm->pgd); | ||
| 264 | } | ||
| 265 | EXPORT_SYMBOL_GPL(check_switch_mmu_context); | ||
| 266 | |||
| 267 | static int mmid_init(void) | ||
| 268 | { | ||
| 269 | if (!cpu_has_mmid) | ||
| 270 | return 0; | ||
| 271 | |||
| 272 | /* | ||
| 273 | * Expect allocation after rollover to fail if we don't have at least | ||
| 274 | * one more MMID than CPUs. | ||
| 275 | */ | ||
| 276 | num_mmids = asid_first_version(0); | ||
| 277 | WARN_ON(num_mmids <= num_possible_cpus()); | ||
| 278 | |||
| 279 | atomic64_set(&mmid_version, asid_first_version(0)); | ||
| 280 | mmid_map = kcalloc(BITS_TO_LONGS(num_mmids), sizeof(*mmid_map), | ||
| 281 | GFP_KERNEL); | ||
| 282 | if (!mmid_map) | ||
| 283 | panic("Failed to allocate bitmap for %u MMIDs\n", num_mmids); | ||
| 284 | |||
| 285 | /* Reserve an MMID for kmap/wired entries */ | ||
| 286 | __set_bit(MMID_KERNEL_WIRED, mmid_map); | ||
| 287 | |||
| 288 | pr_info("MMID allocator initialised with %u entries\n", num_mmids); | ||
| 289 | return 0; | ||
| 290 | } | ||
| 291 | early_initcall(mmid_init); | ||
diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c index cb38461391cb..b57465733e87 100644 --- a/arch/mips/mm/dma-noncoherent.c +++ b/arch/mips/mm/dma-noncoherent.c | |||
| @@ -120,13 +120,8 @@ static inline void dma_sync_phys(phys_addr_t paddr, size_t size, | |||
| 120 | if (PageHighMem(page)) { | 120 | if (PageHighMem(page)) { |
| 121 | void *addr; | 121 | void *addr; |
| 122 | 122 | ||
| 123 | if (offset + len > PAGE_SIZE) { | 123 | if (offset + len > PAGE_SIZE) |
| 124 | if (offset >= PAGE_SIZE) { | ||
| 125 | page += offset >> PAGE_SHIFT; | ||
| 126 | offset &= ~PAGE_MASK; | ||
| 127 | } | ||
| 128 | len = PAGE_SIZE - offset; | 124 | len = PAGE_SIZE - offset; |
| 129 | } | ||
| 130 | 125 | ||
| 131 | addr = kmap_atomic(page); | 126 | addr = kmap_atomic(page); |
| 132 | dma_sync_virt(addr + offset, len, dir); | 127 | dma_sync_virt(addr + offset, len, dir); |
| @@ -145,12 +140,14 @@ void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr, | |||
| 145 | dma_sync_phys(paddr, size, dir); | 140 | dma_sync_phys(paddr, size, dir); |
| 146 | } | 141 | } |
| 147 | 142 | ||
| 143 | #ifdef CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU | ||
| 148 | void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, | 144 | void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, |
| 149 | size_t size, enum dma_data_direction dir) | 145 | size_t size, enum dma_data_direction dir) |
| 150 | { | 146 | { |
| 151 | if (cpu_needs_post_dma_flush(dev)) | 147 | if (cpu_needs_post_dma_flush(dev)) |
| 152 | dma_sync_phys(paddr, size, dir); | 148 | dma_sync_phys(paddr, size, dir); |
| 153 | } | 149 | } |
| 150 | #endif | ||
| 154 | 151 | ||
| 155 | void arch_dma_cache_sync(struct device *dev, void *vaddr, size_t size, | 152 | void arch_dma_cache_sync(struct device *dev, void *vaddr, size_t size, |
| 156 | enum dma_data_direction direction) | 153 | enum dma_data_direction direction) |
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index b521d8e2d359..c3b45e248806 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
| @@ -84,6 +84,7 @@ void setup_zero_pages(void) | |||
| 84 | static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot) | 84 | static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot) |
| 85 | { | 85 | { |
| 86 | enum fixed_addresses idx; | 86 | enum fixed_addresses idx; |
| 87 | unsigned int uninitialized_var(old_mmid); | ||
| 87 | unsigned long vaddr, flags, entrylo; | 88 | unsigned long vaddr, flags, entrylo; |
| 88 | unsigned long old_ctx; | 89 | unsigned long old_ctx; |
| 89 | pte_t pte; | 90 | pte_t pte; |
| @@ -110,6 +111,10 @@ static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot) | |||
| 110 | write_c0_entryhi(vaddr & (PAGE_MASK << 1)); | 111 | write_c0_entryhi(vaddr & (PAGE_MASK << 1)); |
| 111 | write_c0_entrylo0(entrylo); | 112 | write_c0_entrylo0(entrylo); |
| 112 | write_c0_entrylo1(entrylo); | 113 | write_c0_entrylo1(entrylo); |
| 114 | if (cpu_has_mmid) { | ||
| 115 | old_mmid = read_c0_memorymapid(); | ||
| 116 | write_c0_memorymapid(MMID_KERNEL_WIRED); | ||
| 117 | } | ||
| 113 | #ifdef CONFIG_XPA | 118 | #ifdef CONFIG_XPA |
| 114 | if (cpu_has_xpa) { | 119 | if (cpu_has_xpa) { |
| 115 | entrylo = (pte.pte_low & _PFNX_MASK); | 120 | entrylo = (pte.pte_low & _PFNX_MASK); |
| @@ -124,6 +129,8 @@ static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot) | |||
| 124 | tlb_write_indexed(); | 129 | tlb_write_indexed(); |
| 125 | tlbw_use_hazard(); | 130 | tlbw_use_hazard(); |
| 126 | write_c0_entryhi(old_ctx); | 131 | write_c0_entryhi(old_ctx); |
| 132 | if (cpu_has_mmid) | ||
| 133 | write_c0_memorymapid(old_mmid); | ||
| 127 | local_irq_restore(flags); | 134 | local_irq_restore(flags); |
| 128 | 135 | ||
| 129 | return (void*) vaddr; | 136 | return (void*) vaddr; |
diff --git a/arch/mips/mm/sc-debugfs.c b/arch/mips/mm/sc-debugfs.c index 2a116084216f..9507421de335 100644 --- a/arch/mips/mm/sc-debugfs.c +++ b/arch/mips/mm/sc-debugfs.c | |||
| @@ -55,20 +55,11 @@ static const struct file_operations sc_prefetch_fops = { | |||
| 55 | 55 | ||
| 56 | static int __init sc_debugfs_init(void) | 56 | static int __init sc_debugfs_init(void) |
| 57 | { | 57 | { |
| 58 | struct dentry *dir, *file; | 58 | struct dentry *dir; |
| 59 | |||
| 60 | if (!mips_debugfs_dir) | ||
| 61 | return -ENODEV; | ||
| 62 | 59 | ||
| 63 | dir = debugfs_create_dir("l2cache", mips_debugfs_dir); | 60 | dir = debugfs_create_dir("l2cache", mips_debugfs_dir); |
| 64 | if (IS_ERR(dir)) | 61 | debugfs_create_file("prefetch", S_IRUGO | S_IWUSR, dir, NULL, |
| 65 | return PTR_ERR(dir); | 62 | &sc_prefetch_fops); |
| 66 | |||
| 67 | file = debugfs_create_file("prefetch", S_IRUGO | S_IWUSR, dir, | ||
| 68 | NULL, &sc_prefetch_fops); | ||
| 69 | if (!file) | ||
| 70 | return -ENOMEM; | ||
| 71 | |||
| 72 | return 0; | 63 | return 0; |
| 73 | } | 64 | } |
| 74 | late_initcall(sc_debugfs_init); | 65 | late_initcall(sc_debugfs_init); |
diff --git a/arch/mips/mm/tlb-r3k.c b/arch/mips/mm/tlb-r3k.c index 6f589e0112ce..50f207591b6d 100644 --- a/arch/mips/mm/tlb-r3k.c +++ b/arch/mips/mm/tlb-r3k.c | |||
| @@ -67,18 +67,6 @@ void local_flush_tlb_all(void) | |||
| 67 | local_irq_restore(flags); | 67 | local_irq_restore(flags); |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | void local_flush_tlb_mm(struct mm_struct *mm) | ||
| 71 | { | ||
| 72 | int cpu = smp_processor_id(); | ||
| 73 | |||
| 74 | if (cpu_context(cpu, mm) != 0) { | ||
| 75 | #ifdef DEBUG_TLB | ||
| 76 | printk("[tlbmm<%lu>]", (unsigned long)cpu_context(cpu, mm)); | ||
| 77 | #endif | ||
| 78 | drop_mmu_context(mm, cpu); | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | 70 | void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, |
| 83 | unsigned long end) | 71 | unsigned long end) |
| 84 | { | 72 | { |
| @@ -117,7 +105,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
| 117 | } | 105 | } |
| 118 | write_c0_entryhi(oldpid); | 106 | write_c0_entryhi(oldpid); |
| 119 | } else { | 107 | } else { |
| 120 | drop_mmu_context(mm, cpu); | 108 | drop_mmu_context(mm); |
| 121 | } | 109 | } |
| 122 | local_irq_restore(flags); | 110 | local_irq_restore(flags); |
| 123 | } | 111 | } |
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 0596505770db..c13e46ced425 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c | |||
| @@ -104,23 +104,6 @@ void local_flush_tlb_all(void) | |||
| 104 | } | 104 | } |
| 105 | EXPORT_SYMBOL(local_flush_tlb_all); | 105 | EXPORT_SYMBOL(local_flush_tlb_all); |
| 106 | 106 | ||
| 107 | /* All entries common to a mm share an asid. To effectively flush | ||
| 108 | these entries, we just bump the asid. */ | ||
| 109 | void local_flush_tlb_mm(struct mm_struct *mm) | ||
| 110 | { | ||
| 111 | int cpu; | ||
| 112 | |||
| 113 | preempt_disable(); | ||
| 114 | |||
| 115 | cpu = smp_processor_id(); | ||
| 116 | |||
| 117 | if (cpu_context(cpu, mm) != 0) { | ||
| 118 | drop_mmu_context(mm, cpu); | ||
| 119 | } | ||
| 120 | |||
| 121 | preempt_enable(); | ||
| 122 | } | ||
| 123 | |||
| 124 | void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | 107 | void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, |
| 125 | unsigned long end) | 108 | unsigned long end) |
| 126 | { | 109 | { |
| @@ -137,14 +120,23 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
| 137 | if (size <= (current_cpu_data.tlbsizeftlbsets ? | 120 | if (size <= (current_cpu_data.tlbsizeftlbsets ? |
| 138 | current_cpu_data.tlbsize / 8 : | 121 | current_cpu_data.tlbsize / 8 : |
| 139 | current_cpu_data.tlbsize / 2)) { | 122 | current_cpu_data.tlbsize / 2)) { |
| 140 | int oldpid = read_c0_entryhi(); | 123 | unsigned long old_entryhi, uninitialized_var(old_mmid); |
| 141 | int newpid = cpu_asid(cpu, mm); | 124 | int newpid = cpu_asid(cpu, mm); |
| 142 | 125 | ||
| 126 | old_entryhi = read_c0_entryhi(); | ||
| 127 | if (cpu_has_mmid) { | ||
| 128 | old_mmid = read_c0_memorymapid(); | ||
| 129 | write_c0_memorymapid(newpid); | ||
| 130 | } | ||
| 131 | |||
| 143 | htw_stop(); | 132 | htw_stop(); |
| 144 | while (start < end) { | 133 | while (start < end) { |
| 145 | int idx; | 134 | int idx; |
| 146 | 135 | ||
| 147 | write_c0_entryhi(start | newpid); | 136 | if (cpu_has_mmid) |
| 137 | write_c0_entryhi(start); | ||
| 138 | else | ||
| 139 | write_c0_entryhi(start | newpid); | ||
| 148 | start += (PAGE_SIZE << 1); | 140 | start += (PAGE_SIZE << 1); |
| 149 | mtc0_tlbw_hazard(); | 141 | mtc0_tlbw_hazard(); |
| 150 | tlb_probe(); | 142 | tlb_probe(); |
| @@ -160,10 +152,12 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
| 160 | tlb_write_indexed(); | 152 | tlb_write_indexed(); |
| 161 | } | 153 | } |
| 162 | tlbw_use_hazard(); | 154 | tlbw_use_hazard(); |
| 163 | write_c0_entryhi(oldpid); | 155 | write_c0_entryhi(old_entryhi); |
| 156 | if (cpu_has_mmid) | ||
| 157 | write_c0_memorymapid(old_mmid); | ||
| 164 | htw_start(); | 158 | htw_start(); |
| 165 | } else { | 159 | } else { |
| 166 | drop_mmu_context(mm, cpu); | 160 | drop_mmu_context(mm); |
| 167 | } | 161 | } |
| 168 | flush_micro_tlb(); | 162 | flush_micro_tlb(); |
| 169 | local_irq_restore(flags); | 163 | local_irq_restore(flags); |
| @@ -220,15 +214,21 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | |||
| 220 | int cpu = smp_processor_id(); | 214 | int cpu = smp_processor_id(); |
| 221 | 215 | ||
| 222 | if (cpu_context(cpu, vma->vm_mm) != 0) { | 216 | if (cpu_context(cpu, vma->vm_mm) != 0) { |
| 223 | unsigned long flags; | 217 | unsigned long uninitialized_var(old_mmid); |
| 224 | int oldpid, newpid, idx; | 218 | unsigned long flags, old_entryhi; |
| 219 | int idx; | ||
| 225 | 220 | ||
| 226 | newpid = cpu_asid(cpu, vma->vm_mm); | ||
| 227 | page &= (PAGE_MASK << 1); | 221 | page &= (PAGE_MASK << 1); |
| 228 | local_irq_save(flags); | 222 | local_irq_save(flags); |
| 229 | oldpid = read_c0_entryhi(); | 223 | old_entryhi = read_c0_entryhi(); |
| 230 | htw_stop(); | 224 | htw_stop(); |
| 231 | write_c0_entryhi(page | newpid); | 225 | if (cpu_has_mmid) { |
| 226 | old_mmid = read_c0_memorymapid(); | ||
| 227 | write_c0_entryhi(page); | ||
| 228 | write_c0_memorymapid(cpu_asid(cpu, vma->vm_mm)); | ||
| 229 | } else { | ||
| 230 | write_c0_entryhi(page | cpu_asid(cpu, vma->vm_mm)); | ||
| 231 | } | ||
| 232 | mtc0_tlbw_hazard(); | 232 | mtc0_tlbw_hazard(); |
| 233 | tlb_probe(); | 233 | tlb_probe(); |
| 234 | tlb_probe_hazard(); | 234 | tlb_probe_hazard(); |
| @@ -244,7 +244,9 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | |||
| 244 | tlbw_use_hazard(); | 244 | tlbw_use_hazard(); |
| 245 | 245 | ||
| 246 | finish: | 246 | finish: |
| 247 | write_c0_entryhi(oldpid); | 247 | write_c0_entryhi(old_entryhi); |
| 248 | if (cpu_has_mmid) | ||
| 249 | write_c0_memorymapid(old_mmid); | ||
| 248 | htw_start(); | 250 | htw_start(); |
| 249 | flush_micro_tlb_vm(vma); | 251 | flush_micro_tlb_vm(vma); |
| 250 | local_irq_restore(flags); | 252 | local_irq_restore(flags); |
| @@ -307,9 +309,13 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
| 307 | local_irq_save(flags); | 309 | local_irq_save(flags); |
| 308 | 310 | ||
| 309 | htw_stop(); | 311 | htw_stop(); |
| 310 | pid = read_c0_entryhi() & cpu_asid_mask(¤t_cpu_data); | ||
| 311 | address &= (PAGE_MASK << 1); | 312 | address &= (PAGE_MASK << 1); |
| 312 | write_c0_entryhi(address | pid); | 313 | if (cpu_has_mmid) { |
| 314 | write_c0_entryhi(address); | ||
| 315 | } else { | ||
| 316 | pid = read_c0_entryhi() & cpu_asid_mask(¤t_cpu_data); | ||
| 317 | write_c0_entryhi(address | pid); | ||
| 318 | } | ||
| 313 | pgdp = pgd_offset(vma->vm_mm, address); | 319 | pgdp = pgd_offset(vma->vm_mm, address); |
| 314 | mtc0_tlbw_hazard(); | 320 | mtc0_tlbw_hazard(); |
| 315 | tlb_probe(); | 321 | tlb_probe(); |
| @@ -375,12 +381,17 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
| 375 | #ifdef CONFIG_XPA | 381 | #ifdef CONFIG_XPA |
| 376 | panic("Broken for XPA kernels"); | 382 | panic("Broken for XPA kernels"); |
| 377 | #else | 383 | #else |
| 384 | unsigned int uninitialized_var(old_mmid); | ||
| 378 | unsigned long flags; | 385 | unsigned long flags; |
| 379 | unsigned long wired; | 386 | unsigned long wired; |
| 380 | unsigned long old_pagemask; | 387 | unsigned long old_pagemask; |
| 381 | unsigned long old_ctx; | 388 | unsigned long old_ctx; |
| 382 | 389 | ||
| 383 | local_irq_save(flags); | 390 | local_irq_save(flags); |
| 391 | if (cpu_has_mmid) { | ||
| 392 | old_mmid = read_c0_memorymapid(); | ||
| 393 | write_c0_memorymapid(MMID_KERNEL_WIRED); | ||
| 394 | } | ||
| 384 | /* Save old context and create impossible VPN2 value */ | 395 | /* Save old context and create impossible VPN2 value */ |
| 385 | old_ctx = read_c0_entryhi(); | 396 | old_ctx = read_c0_entryhi(); |
| 386 | htw_stop(); | 397 | htw_stop(); |
| @@ -398,6 +409,8 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
| 398 | tlbw_use_hazard(); | 409 | tlbw_use_hazard(); |
| 399 | 410 | ||
| 400 | write_c0_entryhi(old_ctx); | 411 | write_c0_entryhi(old_ctx); |
| 412 | if (cpu_has_mmid) | ||
| 413 | write_c0_memorymapid(old_mmid); | ||
| 401 | tlbw_use_hazard(); /* What is the hazard here? */ | 414 | tlbw_use_hazard(); /* What is the hazard here? */ |
| 402 | htw_start(); | 415 | htw_start(); |
| 403 | write_c0_pagemask(old_pagemask); | 416 | write_c0_pagemask(old_pagemask); |
diff --git a/arch/mips/mm/tlb-r8k.c b/arch/mips/mm/tlb-r8k.c index e86e2e55ad3e..c1e9e144007e 100644 --- a/arch/mips/mm/tlb-r8k.c +++ b/arch/mips/mm/tlb-r8k.c | |||
| @@ -50,14 +50,6 @@ void local_flush_tlb_all(void) | |||
| 50 | local_irq_restore(flags); | 50 | local_irq_restore(flags); |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | void local_flush_tlb_mm(struct mm_struct *mm) | ||
| 54 | { | ||
| 55 | int cpu = smp_processor_id(); | ||
| 56 | |||
| 57 | if (cpu_context(cpu, mm) != 0) | ||
| 58 | drop_mmu_context(mm, cpu); | ||
| 59 | } | ||
| 60 | |||
| 61 | void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | 53 | void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, |
| 62 | unsigned long end) | 54 | unsigned long end) |
| 63 | { | 55 | { |
| @@ -75,7 +67,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
| 75 | local_irq_save(flags); | 67 | local_irq_save(flags); |
| 76 | 68 | ||
| 77 | if (size > TFP_TLB_SIZE / 2) { | 69 | if (size > TFP_TLB_SIZE / 2) { |
| 78 | drop_mmu_context(mm, cpu); | 70 | drop_mmu_context(mm); |
| 79 | goto out_restore; | 71 | goto out_restore; |
| 80 | } | 72 | } |
| 81 | 73 | ||
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 8185a2bfaf09..c4f976593061 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile | |||
| @@ -29,6 +29,7 @@ obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o | |||
| 29 | # | 29 | # |
| 30 | # These are still pretty much in the old state, watch, go blind. | 30 | # These are still pretty much in the old state, watch, go blind. |
| 31 | # | 31 | # |
| 32 | obj-$(CONFIG_ATH79) += fixup-ath79.o | ||
| 32 | obj-$(CONFIG_LASAT) += pci-lasat.o | 33 | obj-$(CONFIG_LASAT) += pci-lasat.o |
| 33 | obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o | 34 | obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o |
| 34 | obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o | 35 | obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o |
diff --git a/arch/mips/pci/fixup-ath79.c b/arch/mips/pci/fixup-ath79.c new file mode 100644 index 000000000000..9e651a4af05e --- /dev/null +++ b/arch/mips/pci/fixup-ath79.c | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2018 John Crispin <john@phrozen.org> | ||
| 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 version 2 as published | ||
| 6 | * by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/pci.h> | ||
| 10 | //#include <linux/of_irq.h> | ||
| 11 | #include <linux/of_pci.h> | ||
| 12 | |||
| 13 | int pcibios_plat_dev_init(struct pci_dev *dev) | ||
| 14 | { | ||
| 15 | return PCIBIOS_SUCCESSFUL; | ||
| 16 | } | ||
| 17 | |||
| 18 | int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | ||
| 19 | { | ||
| 20 | return of_irq_parse_and_map_pci(dev, slot, pin); | ||
| 21 | } | ||
diff --git a/arch/mips/pci/ops-bridge.c b/arch/mips/pci/ops-bridge.c index a1d2c4ae0d1b..df95b0da08f2 100644 --- a/arch/mips/pci/ops-bridge.c +++ b/arch/mips/pci/ops-bridge.c | |||
| @@ -44,7 +44,7 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn, | |||
| 44 | int where, int size, u32 * value) | 44 | int where, int size, u32 * value) |
| 45 | { | 45 | { |
| 46 | struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); | 46 | struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); |
| 47 | bridge_t *bridge = bc->base; | 47 | struct bridge_regs *bridge = bc->base; |
| 48 | int slot = PCI_SLOT(devfn); | 48 | int slot = PCI_SLOT(devfn); |
| 49 | int fn = PCI_FUNC(devfn); | 49 | int fn = PCI_FUNC(devfn); |
| 50 | volatile void *addr; | 50 | volatile void *addr; |
| @@ -56,11 +56,11 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn, | |||
| 56 | return PCIBIOS_DEVICE_NOT_FOUND; | 56 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 57 | 57 | ||
| 58 | /* | 58 | /* |
| 59 | * IOC3 is fucking fucked beyond belief ... Don't even give the | 59 | * IOC3 is broken beyond belief ... Don't even give the |
| 60 | * generic PCI code a chance to look at it for real ... | 60 | * generic PCI code a chance to look at it for real ... |
| 61 | */ | 61 | */ |
| 62 | if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) | 62 | if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) |
| 63 | goto oh_my_gawd; | 63 | goto is_ioc3; |
| 64 | 64 | ||
| 65 | addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)]; | 65 | addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)]; |
| 66 | 66 | ||
| @@ -73,21 +73,16 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn, | |||
| 73 | 73 | ||
| 74 | return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; | 74 | return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; |
| 75 | 75 | ||
| 76 | oh_my_gawd: | 76 | is_ioc3: |
| 77 | 77 | ||
| 78 | /* | 78 | /* |
| 79 | * IOC3 is fucking fucked beyond belief ... Don't even give the | 79 | * IOC3 special handling |
| 80 | * generic PCI code a chance to look at the wrong register. | ||
| 81 | */ | 80 | */ |
| 82 | if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { | 81 | if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { |
| 83 | *value = emulate_ioc3_cfg(where, size); | 82 | *value = emulate_ioc3_cfg(where, size); |
| 84 | return PCIBIOS_SUCCESSFUL; | 83 | return PCIBIOS_SUCCESSFUL; |
| 85 | } | 84 | } |
| 86 | 85 | ||
| 87 | /* | ||
| 88 | * IOC3 is fucking fucked beyond belief ... Don't try to access | ||
| 89 | * anything but 32-bit words ... | ||
| 90 | */ | ||
| 91 | addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; | 86 | addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; |
| 92 | 87 | ||
| 93 | if (get_dbe(cf, (u32 *) addr)) | 88 | if (get_dbe(cf, (u32 *) addr)) |
| @@ -104,7 +99,7 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn, | |||
| 104 | int where, int size, u32 * value) | 99 | int where, int size, u32 * value) |
| 105 | { | 100 | { |
| 106 | struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); | 101 | struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); |
| 107 | bridge_t *bridge = bc->base; | 102 | struct bridge_regs *bridge = bc->base; |
| 108 | int busno = bus->number; | 103 | int busno = bus->number; |
| 109 | int slot = PCI_SLOT(devfn); | 104 | int slot = PCI_SLOT(devfn); |
| 110 | int fn = PCI_FUNC(devfn); | 105 | int fn = PCI_FUNC(devfn); |
| @@ -112,19 +107,19 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn, | |||
| 112 | u32 cf, shift, mask; | 107 | u32 cf, shift, mask; |
| 113 | int res; | 108 | int res; |
| 114 | 109 | ||
| 115 | bridge->b_pci_cfg = (busno << 16) | (slot << 11); | 110 | bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11)); |
| 116 | addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID]; | 111 | addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID]; |
| 117 | if (get_dbe(cf, (u32 *) addr)) | 112 | if (get_dbe(cf, (u32 *) addr)) |
| 118 | return PCIBIOS_DEVICE_NOT_FOUND; | 113 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 119 | 114 | ||
| 120 | /* | 115 | /* |
| 121 | * IOC3 is fucking fucked beyond belief ... Don't even give the | 116 | * IOC3 is broken beyond belief ... Don't even give the |
| 122 | * generic PCI code a chance to look at it for real ... | 117 | * generic PCI code a chance to look at it for real ... |
| 123 | */ | 118 | */ |
| 124 | if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) | 119 | if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) |
| 125 | goto oh_my_gawd; | 120 | goto is_ioc3; |
| 126 | 121 | ||
| 127 | bridge->b_pci_cfg = (busno << 16) | (slot << 11); | 122 | bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11)); |
| 128 | addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))]; | 123 | addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))]; |
| 129 | 124 | ||
| 130 | if (size == 1) | 125 | if (size == 1) |
| @@ -136,22 +131,17 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn, | |||
| 136 | 131 | ||
| 137 | return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; | 132 | return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; |
| 138 | 133 | ||
| 139 | oh_my_gawd: | 134 | is_ioc3: |
| 140 | 135 | ||
| 141 | /* | 136 | /* |
| 142 | * IOC3 is fucking fucked beyond belief ... Don't even give the | 137 | * IOC3 special handling |
| 143 | * generic PCI code a chance to look at the wrong register. | ||
| 144 | */ | 138 | */ |
| 145 | if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { | 139 | if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { |
| 146 | *value = emulate_ioc3_cfg(where, size); | 140 | *value = emulate_ioc3_cfg(where, size); |
| 147 | return PCIBIOS_SUCCESSFUL; | 141 | return PCIBIOS_SUCCESSFUL; |
| 148 | } | 142 | } |
| 149 | 143 | ||
| 150 | /* | 144 | bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11)); |
| 151 | * IOC3 is fucking fucked beyond belief ... Don't try to access | ||
| 152 | * anything but 32-bit words ... | ||
| 153 | */ | ||
| 154 | bridge->b_pci_cfg = (busno << 16) | (slot << 11); | ||
| 155 | addr = &bridge->b_type1_cfg.c[(fn << 8) | where]; | 145 | addr = &bridge->b_type1_cfg.c[(fn << 8) | where]; |
| 156 | 146 | ||
| 157 | if (get_dbe(cf, (u32 *) addr)) | 147 | if (get_dbe(cf, (u32 *) addr)) |
| @@ -177,7 +167,7 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn, | |||
| 177 | int where, int size, u32 value) | 167 | int where, int size, u32 value) |
| 178 | { | 168 | { |
| 179 | struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); | 169 | struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); |
| 180 | bridge_t *bridge = bc->base; | 170 | struct bridge_regs *bridge = bc->base; |
| 181 | int slot = PCI_SLOT(devfn); | 171 | int slot = PCI_SLOT(devfn); |
| 182 | int fn = PCI_FUNC(devfn); | 172 | int fn = PCI_FUNC(devfn); |
| 183 | volatile void *addr; | 173 | volatile void *addr; |
| @@ -189,11 +179,11 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn, | |||
| 189 | return PCIBIOS_DEVICE_NOT_FOUND; | 179 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 190 | 180 | ||
| 191 | /* | 181 | /* |
| 192 | * IOC3 is fucking fucked beyond belief ... Don't even give the | 182 | * IOC3 is broken beyond belief ... Don't even give the |
| 193 | * generic PCI code a chance to look at it for real ... | 183 | * generic PCI code a chance to look at it for real ... |
| 194 | */ | 184 | */ |
| 195 | if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) | 185 | if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) |
| 196 | goto oh_my_gawd; | 186 | goto is_ioc3; |
| 197 | 187 | ||
| 198 | addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)]; | 188 | addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)]; |
| 199 | 189 | ||
| @@ -210,19 +200,14 @@ static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn, | |||
| 210 | 200 | ||
| 211 | return PCIBIOS_SUCCESSFUL; | 201 | return PCIBIOS_SUCCESSFUL; |
| 212 | 202 | ||
| 213 | oh_my_gawd: | 203 | is_ioc3: |
| 214 | 204 | ||
| 215 | /* | 205 | /* |
| 216 | * IOC3 is fucking fucked beyond belief ... Don't even give the | 206 | * IOC3 special handling |
| 217 | * generic PCI code a chance to touch the wrong register. | ||
| 218 | */ | 207 | */ |
| 219 | if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) | 208 | if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) |
| 220 | return PCIBIOS_SUCCESSFUL; | 209 | return PCIBIOS_SUCCESSFUL; |
| 221 | 210 | ||
| 222 | /* | ||
| 223 | * IOC3 is fucking fucked beyond belief ... Don't try to access | ||
| 224 | * anything but 32-bit words ... | ||
| 225 | */ | ||
| 226 | addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; | 211 | addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; |
| 227 | 212 | ||
| 228 | if (get_dbe(cf, (u32 *) addr)) | 213 | if (get_dbe(cf, (u32 *) addr)) |
| @@ -243,7 +228,7 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn, | |||
| 243 | int where, int size, u32 value) | 228 | int where, int size, u32 value) |
| 244 | { | 229 | { |
| 245 | struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); | 230 | struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); |
| 246 | bridge_t *bridge = bc->base; | 231 | struct bridge_regs *bridge = bc->base; |
| 247 | int slot = PCI_SLOT(devfn); | 232 | int slot = PCI_SLOT(devfn); |
| 248 | int fn = PCI_FUNC(devfn); | 233 | int fn = PCI_FUNC(devfn); |
| 249 | int busno = bus->number; | 234 | int busno = bus->number; |
| @@ -251,17 +236,17 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn, | |||
| 251 | u32 cf, shift, mask, smask; | 236 | u32 cf, shift, mask, smask; |
| 252 | int res; | 237 | int res; |
| 253 | 238 | ||
| 254 | bridge->b_pci_cfg = (busno << 16) | (slot << 11); | 239 | bridge_write(bc, b_pci_cfg, (busno << 16) | (slot << 11)); |
| 255 | addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID]; | 240 | addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID]; |
| 256 | if (get_dbe(cf, (u32 *) addr)) | 241 | if (get_dbe(cf, (u32 *) addr)) |
| 257 | return PCIBIOS_DEVICE_NOT_FOUND; | 242 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 258 | 243 | ||
| 259 | /* | 244 | /* |
| 260 | * IOC3 is fucking fucked beyond belief ... Don't even give the | 245 | * IOC3 is broken beyond belief ... Don't even give the |
| 261 | * generic PCI code a chance to look at it for real ... | 246 | * generic PCI code a chance to look at it for real ... |
| 262 | */ | 247 | */ |
| 263 | if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) | 248 | if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) |
| 264 | goto oh_my_gawd; | 249 | goto is_ioc3; |
| 265 | 250 | ||
| 266 | addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))]; | 251 | addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))]; |
| 267 | 252 | ||
| @@ -278,19 +263,14 @@ static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn, | |||
| 278 | 263 | ||
| 279 | return PCIBIOS_SUCCESSFUL; | 264 | return PCIBIOS_SUCCESSFUL; |
| 280 | 265 | ||
| 281 | oh_my_gawd: | 266 | is_ioc3: |
| 282 | 267 | ||
| 283 | /* | 268 | /* |
| 284 | * IOC3 is fucking fucked beyond belief ... Don't even give the | 269 | * IOC3 special handling |
| 285 | * generic PCI code a chance to touch the wrong register. | ||
| 286 | */ | 270 | */ |
| 287 | if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) | 271 | if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) |
| 288 | return PCIBIOS_SUCCESSFUL; | 272 | return PCIBIOS_SUCCESSFUL; |
| 289 | 273 | ||
| 290 | /* | ||
| 291 | * IOC3 is fucking fucked beyond belief ... Don't try to access | ||
| 292 | * anything but 32-bit words ... | ||
| 293 | */ | ||
| 294 | addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; | 274 | addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; |
| 295 | 275 | ||
| 296 | if (get_dbe(cf, (u32 *) addr)) | 276 | if (get_dbe(cf, (u32 *) addr)) |
diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c index c94a66070a60..3c177b4d0609 100644 --- a/arch/mips/pci/pci-ip27.c +++ b/arch/mips/pci/pci-ip27.c | |||
| @@ -24,22 +24,11 @@ | |||
| 24 | #define MAX_PCI_BUSSES 40 | 24 | #define MAX_PCI_BUSSES 40 |
| 25 | 25 | ||
| 26 | /* | 26 | /* |
| 27 | * Max #PCI devices (like scsi controllers) we handle on a bus. | ||
| 28 | */ | ||
| 29 | #define MAX_DEVICES_PER_PCIBUS 8 | ||
| 30 | |||
| 31 | /* | ||
| 32 | * XXX: No kmalloc available when we do our crosstalk scan, | 27 | * XXX: No kmalloc available when we do our crosstalk scan, |
| 33 | * we should try to move it later in the boot process. | 28 | * we should try to move it later in the boot process. |
| 34 | */ | 29 | */ |
| 35 | static struct bridge_controller bridges[MAX_PCI_BUSSES]; | 30 | static struct bridge_controller bridges[MAX_PCI_BUSSES]; |
| 36 | 31 | ||
| 37 | /* | ||
| 38 | * Translate from irq to software PCI bus number and PCI slot. | ||
| 39 | */ | ||
| 40 | struct bridge_controller *irq_to_bridge[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS]; | ||
| 41 | int irq_to_slot[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS]; | ||
| 42 | |||
| 43 | extern struct pci_ops bridge_pci_ops; | 32 | extern struct pci_ops bridge_pci_ops; |
| 44 | 33 | ||
| 45 | int bridge_probe(nasid_t nasid, int widget_id, int masterwid) | 34 | int bridge_probe(nasid_t nasid, int widget_id, int masterwid) |
| @@ -47,7 +36,6 @@ int bridge_probe(nasid_t nasid, int widget_id, int masterwid) | |||
| 47 | unsigned long offset = NODE_OFFSET(nasid); | 36 | unsigned long offset = NODE_OFFSET(nasid); |
| 48 | struct bridge_controller *bc; | 37 | struct bridge_controller *bc; |
| 49 | static int num_bridges = 0; | 38 | static int num_bridges = 0; |
| 50 | bridge_t *bridge; | ||
| 51 | int slot; | 39 | int slot; |
| 52 | 40 | ||
| 53 | pci_set_flags(PCI_PROBE_ONLY); | 41 | pci_set_flags(PCI_PROBE_ONLY); |
| @@ -78,7 +66,6 @@ int bridge_probe(nasid_t nasid, int widget_id, int masterwid) | |||
| 78 | bc->io.end = ~0UL; | 66 | bc->io.end = ~0UL; |
| 79 | bc->io.flags = IORESOURCE_IO; | 67 | bc->io.flags = IORESOURCE_IO; |
| 80 | 68 | ||
| 81 | bc->irq_cpu = smp_processor_id(); | ||
| 82 | bc->widget_id = widget_id; | 69 | bc->widget_id = widget_id; |
| 83 | bc->nasid = nasid; | 70 | bc->nasid = nasid; |
| 84 | 71 | ||
| @@ -87,45 +74,43 @@ int bridge_probe(nasid_t nasid, int widget_id, int masterwid) | |||
| 87 | /* | 74 | /* |
| 88 | * point to this bridge | 75 | * point to this bridge |
| 89 | */ | 76 | */ |
| 90 | bridge = (bridge_t *) RAW_NODE_SWIN_BASE(nasid, widget_id); | 77 | bc->base = (struct bridge_regs *)RAW_NODE_SWIN_BASE(nasid, widget_id); |
| 91 | 78 | ||
| 92 | /* | 79 | /* |
| 93 | * Clear all pending interrupts. | 80 | * Clear all pending interrupts. |
| 94 | */ | 81 | */ |
| 95 | bridge->b_int_rst_stat = BRIDGE_IRR_ALL_CLR; | 82 | bridge_write(bc, b_int_rst_stat, BRIDGE_IRR_ALL_CLR); |
| 96 | 83 | ||
| 97 | /* | 84 | /* |
| 98 | * Until otherwise set up, assume all interrupts are from slot 0 | 85 | * Until otherwise set up, assume all interrupts are from slot 0 |
| 99 | */ | 86 | */ |
| 100 | bridge->b_int_device = 0x0; | 87 | bridge_write(bc, b_int_device, 0x0); |
| 101 | 88 | ||
| 102 | /* | 89 | /* |
| 103 | * swap pio's to pci mem and io space (big windows) | 90 | * swap pio's to pci mem and io space (big windows) |
| 104 | */ | 91 | */ |
| 105 | bridge->b_wid_control |= BRIDGE_CTRL_IO_SWAP | | 92 | bridge_set(bc, b_wid_control, BRIDGE_CTRL_IO_SWAP | |
| 106 | BRIDGE_CTRL_MEM_SWAP; | 93 | BRIDGE_CTRL_MEM_SWAP); |
| 107 | #ifdef CONFIG_PAGE_SIZE_4KB | 94 | #ifdef CONFIG_PAGE_SIZE_4KB |
| 108 | bridge->b_wid_control &= ~BRIDGE_CTRL_PAGE_SIZE; | 95 | bridge_clr(bc, b_wid_control, BRIDGE_CTRL_PAGE_SIZE); |
| 109 | #else /* 16kB or larger */ | 96 | #else /* 16kB or larger */ |
| 110 | bridge->b_wid_control |= BRIDGE_CTRL_PAGE_SIZE; | 97 | bridge_set(bc, b_wid_control, BRIDGE_CTRL_PAGE_SIZE); |
| 111 | #endif | 98 | #endif |
| 112 | 99 | ||
| 113 | /* | 100 | /* |
| 114 | * Hmm... IRIX sets additional bits in the address which | 101 | * Hmm... IRIX sets additional bits in the address which |
| 115 | * are documented as reserved in the bridge docs. | 102 | * are documented as reserved in the bridge docs. |
| 116 | */ | 103 | */ |
| 117 | bridge->b_wid_int_upper = 0x8000 | (masterwid << 16); | 104 | bridge_write(bc, b_wid_int_upper, 0x8000 | (masterwid << 16)); |
| 118 | bridge->b_wid_int_lower = 0x01800090; /* PI_INT_PEND_MOD off*/ | 105 | bridge_write(bc, b_wid_int_lower, 0x01800090); /* PI_INT_PEND_MOD off*/ |
| 119 | bridge->b_dir_map = (masterwid << 20); /* DMA */ | 106 | bridge_write(bc, b_dir_map, (masterwid << 20)); /* DMA */ |
| 120 | bridge->b_int_enable = 0; | 107 | bridge_write(bc, b_int_enable, 0); |
| 121 | 108 | ||
| 122 | for (slot = 0; slot < 8; slot ++) { | 109 | for (slot = 0; slot < 8; slot ++) { |
| 123 | bridge->b_device[slot].reg |= BRIDGE_DEV_SWAP_DIR; | 110 | bridge_set(bc, b_device[slot].reg, BRIDGE_DEV_SWAP_DIR); |
| 124 | bc->pci_int[slot] = -1; | 111 | bc->pci_int[slot] = -1; |
| 125 | } | 112 | } |
| 126 | bridge->b_wid_tflush; /* wait until Bridge PIO complete */ | 113 | bridge_read(bc, b_wid_tflush); /* wait until Bridge PIO complete */ |
| 127 | |||
| 128 | bc->base = bridge; | ||
| 129 | 114 | ||
| 130 | register_pci_controller(&bc->pc); | 115 | register_pci_controller(&bc->pc); |
| 131 | 116 | ||
| @@ -168,16 +153,12 @@ int pcibios_plat_dev_init(struct pci_dev *dev) | |||
| 168 | 153 | ||
| 169 | irq = bc->pci_int[slot]; | 154 | irq = bc->pci_int[slot]; |
| 170 | if (irq == -1) { | 155 | if (irq == -1) { |
| 171 | irq = request_bridge_irq(bc); | 156 | irq = request_bridge_irq(bc, slot); |
| 172 | if (irq < 0) | 157 | if (irq < 0) |
| 173 | return irq; | 158 | return irq; |
| 174 | 159 | ||
| 175 | bc->pci_int[slot] = irq; | 160 | bc->pci_int[slot] = irq; |
| 176 | } | 161 | } |
| 177 | |||
| 178 | irq_to_bridge[irq] = bc; | ||
| 179 | irq_to_slot[irq] = slot; | ||
| 180 | |||
| 181 | dev->irq = irq; | 162 | dev->irq = irq; |
| 182 | 163 | ||
| 183 | return 0; | 164 | return 0; |
| @@ -206,7 +187,7 @@ phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr) | |||
| 206 | static inline void pci_disable_swapping(struct pci_dev *dev) | 187 | static inline void pci_disable_swapping(struct pci_dev *dev) |
| 207 | { | 188 | { |
| 208 | struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus); | 189 | struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus); |
| 209 | bridge_t *bridge = bc->base; | 190 | struct bridge_regs *bridge = bc->base; |
| 210 | int slot = PCI_SLOT(dev->devfn); | 191 | int slot = PCI_SLOT(dev->devfn); |
| 211 | 192 | ||
| 212 | /* Turn off byte swapping */ | 193 | /* Turn off byte swapping */ |
diff --git a/arch/mips/ralink/bootrom.c b/arch/mips/ralink/bootrom.c index e1fa5972a81d..648f5eb2ba68 100644 --- a/arch/mips/ralink/bootrom.c +++ b/arch/mips/ralink/bootrom.c | |||
| @@ -35,13 +35,7 @@ static const struct file_operations bootrom_file_ops = { | |||
| 35 | 35 | ||
| 36 | static int bootrom_setup(void) | 36 | static int bootrom_setup(void) |
| 37 | { | 37 | { |
| 38 | if (!debugfs_create_file("bootrom", 0444, | 38 | debugfs_create_file("bootrom", 0444, NULL, NULL, &bootrom_file_ops); |
| 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; | 39 | return 0; |
| 46 | } | 40 | } |
| 47 | 41 | ||
diff --git a/arch/mips/sgi-ip27/Makefile b/arch/mips/sgi-ip27/Makefile index 73502fda13ee..27c14ede191e 100644 --- a/arch/mips/sgi-ip27/Makefile +++ b/arch/mips/sgi-ip27/Makefile | |||
| @@ -3,10 +3,9 @@ | |||
| 3 | # Makefile for the IP27 specific kernel interface routines under Linux. | 3 | # Makefile for the IP27 specific kernel interface routines under Linux. |
| 4 | # | 4 | # |
| 5 | 5 | ||
| 6 | obj-y := ip27-berr.o ip27-irq.o ip27-irqno.o ip27-init.o ip27-klconfig.o \ | 6 | obj-y := ip27-berr.o ip27-irq.o ip27-init.o ip27-klconfig.o \ |
| 7 | ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o ip27-timer.o \ | 7 | ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o ip27-timer.o \ |
| 8 | ip27-hubio.o ip27-xtalk.o | 8 | ip27-hubio.o ip27-xtalk.o |
| 9 | 9 | ||
| 10 | obj-$(CONFIG_EARLY_PRINTK) += ip27-console.o | 10 | obj-$(CONFIG_EARLY_PRINTK) += ip27-console.o |
| 11 | obj-$(CONFIG_PCI) += ip27-irq-pci.o | ||
| 12 | obj-$(CONFIG_SMP) += ip27-smp.o | 11 | obj-$(CONFIG_SMP) += ip27-smp.o |
diff --git a/arch/mips/sgi-ip27/ip27-hubio.c b/arch/mips/sgi-ip27/ip27-hubio.c index 2abe016a0ffc..68fb0cb89d9d 100644 --- a/arch/mips/sgi-ip27/ip27-hubio.c +++ b/arch/mips/sgi-ip27/ip27-hubio.c | |||
| @@ -63,7 +63,7 @@ unsigned long hub_pio_map(cnodeid_t cnode, xwidgetnum_t widget, | |||
| 63 | * after we write it. | 63 | * after we write it. |
| 64 | */ | 64 | */ |
| 65 | IIO_ITTE_PUT(nasid, i, HUB_PIO_MAP_TO_MEM, widget, xtalk_addr); | 65 | IIO_ITTE_PUT(nasid, i, HUB_PIO_MAP_TO_MEM, widget, xtalk_addr); |
| 66 | (void) HUB_L(IIO_ITTE_GET(nasid, i)); | 66 | __raw_readq(IIO_ITTE_GET(nasid, i)); |
| 67 | 67 | ||
| 68 | return NODE_BWIN_BASE(nasid, widget) + (xtalk_addr % BWIN_SIZE); | 68 | return NODE_BWIN_BASE(nasid, widget) + (xtalk_addr % BWIN_SIZE); |
| 69 | } | 69 | } |
| @@ -135,7 +135,7 @@ static void hub_setup_prb(nasid_t nasid, int prbnum, int credits) | |||
| 135 | **/ | 135 | **/ |
| 136 | static void hub_set_piomode(nasid_t nasid) | 136 | static void hub_set_piomode(nasid_t nasid) |
| 137 | { | 137 | { |
| 138 | hubreg_t ii_iowa; | 138 | u64 ii_iowa; |
| 139 | hubii_wcr_t ii_wcr; | 139 | hubii_wcr_t ii_wcr; |
| 140 | unsigned i; | 140 | unsigned i; |
| 141 | 141 | ||
diff --git a/arch/mips/sgi-ip27/ip27-init.c b/arch/mips/sgi-ip27/ip27-init.c index e501c43c02db..6074efeff894 100644 --- a/arch/mips/sgi-ip27/ip27-init.c +++ b/arch/mips/sgi-ip27/ip27-init.c | |||
| @@ -52,13 +52,10 @@ EXPORT_SYMBOL_GPL(sn_cpu_info); | |||
| 52 | 52 | ||
| 53 | extern void pcibr_setup(cnodeid_t); | 53 | extern void pcibr_setup(cnodeid_t); |
| 54 | 54 | ||
| 55 | extern void xtalk_probe_node(cnodeid_t nid); | ||
| 56 | |||
| 57 | static void per_hub_init(cnodeid_t cnode) | 55 | static void per_hub_init(cnodeid_t cnode) |
| 58 | { | 56 | { |
| 59 | struct hub_data *hub = hub_data(cnode); | 57 | struct hub_data *hub = hub_data(cnode); |
| 60 | nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode); | 58 | nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode); |
| 61 | int i; | ||
| 62 | 59 | ||
| 63 | cpumask_set_cpu(smp_processor_id(), &hub->h_cpus); | 60 | cpumask_set_cpu(smp_processor_id(), &hub->h_cpus); |
| 64 | 61 | ||
| @@ -71,7 +68,6 @@ static void per_hub_init(cnodeid_t cnode) | |||
| 71 | REMOTE_HUB_S(nasid, IIO_ICTO, 0xff); | 68 | REMOTE_HUB_S(nasid, IIO_ICTO, 0xff); |
| 72 | 69 | ||
| 73 | hub_rtc_init(cnode); | 70 | hub_rtc_init(cnode); |
| 74 | xtalk_probe_node(cnode); | ||
| 75 | 71 | ||
| 76 | #ifdef CONFIG_REPLICATE_EXHANDLERS | 72 | #ifdef CONFIG_REPLICATE_EXHANDLERS |
| 77 | /* | 73 | /* |
| @@ -90,24 +86,6 @@ static void per_hub_init(cnodeid_t cnode) | |||
| 90 | __flush_cache_all(); | 86 | __flush_cache_all(); |
| 91 | } | 87 | } |
| 92 | #endif | 88 | #endif |
| 93 | |||
| 94 | /* | ||
| 95 | * Some interrupts are reserved by hardware or by software convention. | ||
| 96 | * Mark these as reserved right away so they won't be used accidentally | ||
| 97 | * later. | ||
| 98 | */ | ||
| 99 | for (i = 0; i <= BASE_PCI_IRQ; i++) { | ||
| 100 | __set_bit(i, hub->irq_alloc_mask); | ||
| 101 | LOCAL_HUB_CLR_INTR(INT_PEND0_BASELVL + i); | ||
| 102 | } | ||
| 103 | |||
| 104 | __set_bit(IP_PEND0_6_63, hub->irq_alloc_mask); | ||
| 105 | LOCAL_HUB_S(PI_INT_PEND_MOD, IP_PEND0_6_63); | ||
| 106 | |||
| 107 | for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++) { | ||
| 108 | __set_bit(i, hub->irq_alloc_mask); | ||
| 109 | LOCAL_HUB_CLR_INTR(INT_PEND1_BASELVL + i); | ||
| 110 | } | ||
| 111 | } | 89 | } |
| 112 | 90 | ||
| 113 | void per_cpu_init(void) | 91 | void per_cpu_init(void) |
| @@ -116,8 +94,6 @@ void per_cpu_init(void) | |||
| 116 | int slice = LOCAL_HUB_L(PI_CPU_NUM); | 94 | int slice = LOCAL_HUB_L(PI_CPU_NUM); |
| 117 | cnodeid_t cnode = get_compact_nodeid(); | 95 | cnodeid_t cnode = get_compact_nodeid(); |
| 118 | struct hub_data *hub = hub_data(cnode); | 96 | struct hub_data *hub = hub_data(cnode); |
| 119 | struct slice_data *si = hub->slice + slice; | ||
| 120 | int i; | ||
| 121 | 97 | ||
| 122 | if (test_and_set_bit(slice, &hub->slice_map)) | 98 | if (test_and_set_bit(slice, &hub->slice_map)) |
| 123 | return; | 99 | return; |
| @@ -126,22 +102,14 @@ void per_cpu_init(void) | |||
| 126 | 102 | ||
| 127 | per_hub_init(cnode); | 103 | per_hub_init(cnode); |
| 128 | 104 | ||
| 129 | for (i = 0; i < LEVELS_PER_SLICE; i++) | ||
| 130 | si->level_to_irq[i] = -1; | ||
| 131 | |||
| 132 | /* | ||
| 133 | * We use this so we can find the local hub's data as fast as only | ||
| 134 | * possible. | ||
| 135 | */ | ||
| 136 | cpu_data[cpu].data = si; | ||
| 137 | |||
| 138 | cpu_time_init(); | 105 | cpu_time_init(); |
| 139 | install_ipi(); | 106 | install_ipi(); |
| 140 | 107 | ||
| 141 | /* Install our NMI handler if symmon hasn't installed one. */ | 108 | /* Install our NMI handler if symmon hasn't installed one. */ |
| 142 | install_cpu_nmi_handler(cputoslice(cpu)); | 109 | install_cpu_nmi_handler(cputoslice(cpu)); |
| 143 | 110 | ||
| 144 | set_c0_status(SRB_DEV0 | SRB_DEV1); | 111 | enable_percpu_irq(IP27_HUB_PEND0_IRQ, IRQ_TYPE_NONE); |
| 112 | enable_percpu_irq(IP27_HUB_PEND1_IRQ, IRQ_TYPE_NONE); | ||
| 145 | } | 113 | } |
| 146 | 114 | ||
| 147 | /* | 115 | /* |
| @@ -177,7 +145,7 @@ extern void ip27_reboot_setup(void); | |||
| 177 | 145 | ||
| 178 | void __init plat_mem_setup(void) | 146 | void __init plat_mem_setup(void) |
| 179 | { | 147 | { |
| 180 | hubreg_t p, e, n_mode; | 148 | u64 p, e, n_mode; |
| 181 | nasid_t nid; | 149 | nasid_t nid; |
| 182 | 150 | ||
| 183 | ip27_reboot_setup(); | 151 | ip27_reboot_setup(); |
| @@ -215,7 +183,6 @@ void __init plat_mem_setup(void) | |||
| 215 | #endif | 183 | #endif |
| 216 | 184 | ||
| 217 | ioc3_eth_init(); | 185 | ioc3_eth_init(); |
| 218 | per_cpu_init(); | ||
| 219 | 186 | ||
| 220 | set_io_port_base(IO_BASE); | 187 | set_io_port_base(IO_BASE); |
| 221 | } | 188 | } |
diff --git a/arch/mips/sgi-ip27/ip27-irq-pci.c b/arch/mips/sgi-ip27/ip27-irq-pci.c deleted file mode 100644 index cd449e90b917..000000000000 --- a/arch/mips/sgi-ip27/ip27-irq-pci.c +++ /dev/null | |||
| @@ -1,266 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * ip27-irq.c: Highlevel interrupt handling for IP27 architecture. | ||
| 4 | * | ||
| 5 | * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org) | ||
| 6 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. | ||
| 7 | * Copyright (C) 1999 - 2001 Kanoj Sarcar | ||
| 8 | */ | ||
| 9 | |||
| 10 | #undef DEBUG | ||
| 11 | |||
| 12 | #include <linux/irq.h> | ||
| 13 | #include <linux/errno.h> | ||
| 14 | #include <linux/signal.h> | ||
| 15 | #include <linux/sched.h> | ||
| 16 | #include <linux/types.h> | ||
| 17 | #include <linux/interrupt.h> | ||
| 18 | #include <linux/ioport.h> | ||
| 19 | #include <linux/timex.h> | ||
| 20 | #include <linux/smp.h> | ||
| 21 | #include <linux/random.h> | ||
| 22 | #include <linux/kernel.h> | ||
| 23 | #include <linux/kernel_stat.h> | ||
| 24 | #include <linux/delay.h> | ||
| 25 | #include <linux/bitops.h> | ||
| 26 | |||
| 27 | #include <asm/bootinfo.h> | ||
| 28 | #include <asm/io.h> | ||
| 29 | #include <asm/mipsregs.h> | ||
| 30 | |||
| 31 | #include <asm/processor.h> | ||
| 32 | #include <asm/pci/bridge.h> | ||
| 33 | #include <asm/sn/addrs.h> | ||
| 34 | #include <asm/sn/agent.h> | ||
| 35 | #include <asm/sn/arch.h> | ||
| 36 | #include <asm/sn/hub.h> | ||
| 37 | #include <asm/sn/intr.h> | ||
| 38 | |||
| 39 | /* | ||
| 40 | * Linux has a controller-independent x86 interrupt architecture. | ||
| 41 | * every controller has a 'controller-template', that is used | ||
| 42 | * by the main code to do the right thing. Each driver-visible | ||
| 43 | * interrupt source is transparently wired to the appropriate | ||
| 44 | * controller. Thus drivers need not be aware of the | ||
| 45 | * interrupt-controller. | ||
| 46 | * | ||
| 47 | * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC, | ||
| 48 | * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC. | ||
| 49 | * (IO-APICs assumed to be messaging to Pentium local-APICs) | ||
| 50 | * | ||
| 51 | * the code is designed to be easily extended with new/different | ||
| 52 | * interrupt controllers, without having to do assembly magic. | ||
| 53 | */ | ||
| 54 | |||
| 55 | extern struct bridge_controller *irq_to_bridge[]; | ||
| 56 | extern int irq_to_slot[]; | ||
| 57 | |||
| 58 | /* | ||
| 59 | * use these macros to get the encoded nasid and widget id | ||
| 60 | * from the irq value | ||
| 61 | */ | ||
| 62 | #define IRQ_TO_BRIDGE(i) irq_to_bridge[(i)] | ||
| 63 | #define SLOT_FROM_PCI_IRQ(i) irq_to_slot[i] | ||
| 64 | |||
| 65 | static inline int alloc_level(int cpu, int irq) | ||
| 66 | { | ||
| 67 | struct hub_data *hub = hub_data(cpu_to_node(cpu)); | ||
| 68 | struct slice_data *si = cpu_data[cpu].data; | ||
| 69 | int level; | ||
| 70 | |||
| 71 | level = find_first_zero_bit(hub->irq_alloc_mask, LEVELS_PER_SLICE); | ||
| 72 | if (level >= LEVELS_PER_SLICE) | ||
| 73 | panic("Cpu %d flooded with devices", cpu); | ||
| 74 | |||
| 75 | __set_bit(level, hub->irq_alloc_mask); | ||
| 76 | si->level_to_irq[level] = irq; | ||
| 77 | |||
| 78 | return level; | ||
| 79 | } | ||
| 80 | |||
| 81 | static inline int find_level(cpuid_t *cpunum, int irq) | ||
| 82 | { | ||
| 83 | int cpu, i; | ||
| 84 | |||
| 85 | for_each_online_cpu(cpu) { | ||
| 86 | struct slice_data *si = cpu_data[cpu].data; | ||
| 87 | |||
| 88 | for (i = BASE_PCI_IRQ; i < LEVELS_PER_SLICE; i++) | ||
| 89 | if (si->level_to_irq[i] == irq) { | ||
| 90 | *cpunum = cpu; | ||
| 91 | |||
| 92 | return i; | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | panic("Could not identify cpu/level for irq %d", irq); | ||
| 97 | } | ||
| 98 | |||
| 99 | static int intr_connect_level(int cpu, int bit) | ||
| 100 | { | ||
| 101 | nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu)); | ||
| 102 | struct slice_data *si = cpu_data[cpu].data; | ||
| 103 | |||
| 104 | set_bit(bit, si->irq_enable_mask); | ||
| 105 | |||
| 106 | if (!cputoslice(cpu)) { | ||
| 107 | REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]); | ||
| 108 | REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]); | ||
| 109 | } else { | ||
| 110 | REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]); | ||
| 111 | REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]); | ||
| 112 | } | ||
| 113 | |||
| 114 | return 0; | ||
| 115 | } | ||
| 116 | |||
| 117 | static int intr_disconnect_level(int cpu, int bit) | ||
| 118 | { | ||
| 119 | nasid_t nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu)); | ||
| 120 | struct slice_data *si = cpu_data[cpu].data; | ||
| 121 | |||
| 122 | clear_bit(bit, si->irq_enable_mask); | ||
| 123 | |||
| 124 | if (!cputoslice(cpu)) { | ||
| 125 | REMOTE_HUB_S(nasid, PI_INT_MASK0_A, si->irq_enable_mask[0]); | ||
| 126 | REMOTE_HUB_S(nasid, PI_INT_MASK1_A, si->irq_enable_mask[1]); | ||
| 127 | } else { | ||
| 128 | REMOTE_HUB_S(nasid, PI_INT_MASK0_B, si->irq_enable_mask[0]); | ||
| 129 | REMOTE_HUB_S(nasid, PI_INT_MASK1_B, si->irq_enable_mask[1]); | ||
| 130 | } | ||
| 131 | |||
| 132 | return 0; | ||
| 133 | } | ||
| 134 | |||
| 135 | /* Startup one of the (PCI ...) IRQs routes over a bridge. */ | ||
| 136 | static unsigned int startup_bridge_irq(struct irq_data *d) | ||
| 137 | { | ||
| 138 | struct bridge_controller *bc; | ||
| 139 | bridgereg_t device; | ||
| 140 | bridge_t *bridge; | ||
| 141 | int pin, swlevel; | ||
| 142 | cpuid_t cpu; | ||
| 143 | |||
| 144 | pin = SLOT_FROM_PCI_IRQ(d->irq); | ||
| 145 | bc = IRQ_TO_BRIDGE(d->irq); | ||
| 146 | bridge = bc->base; | ||
| 147 | |||
| 148 | pr_debug("bridge_startup(): irq= 0x%x pin=%d\n", d->irq, pin); | ||
| 149 | /* | ||
| 150 | * "map" irq to a swlevel greater than 6 since the first 6 bits | ||
| 151 | * of INT_PEND0 are taken | ||
| 152 | */ | ||
| 153 | swlevel = find_level(&cpu, d->irq); | ||
| 154 | bridge->b_int_addr[pin].addr = (0x20000 | swlevel | (bc->nasid << 8)); | ||
| 155 | bridge->b_int_enable |= (1 << pin); | ||
| 156 | bridge->b_int_enable |= 0x7ffffe00; /* more stuff in int_enable */ | ||
| 157 | |||
| 158 | /* | ||
| 159 | * Enable sending of an interrupt clear packt to the hub on a high to | ||
| 160 | * low transition of the interrupt pin. | ||
| 161 | * | ||
| 162 | * IRIX sets additional bits in the address which are documented as | ||
| 163 | * reserved in the bridge docs. | ||
| 164 | */ | ||
| 165 | bridge->b_int_mode |= (1UL << pin); | ||
| 166 | |||
| 167 | /* | ||
| 168 | * We assume the bridge to have a 1:1 mapping between devices | ||
| 169 | * (slots) and intr pins. | ||
| 170 | */ | ||
| 171 | device = bridge->b_int_device; | ||
| 172 | device &= ~(7 << (pin*3)); | ||
| 173 | device |= (pin << (pin*3)); | ||
| 174 | bridge->b_int_device = device; | ||
| 175 | |||
| 176 | bridge->b_wid_tflush; | ||
| 177 | |||
| 178 | intr_connect_level(cpu, swlevel); | ||
| 179 | |||
| 180 | return 0; /* Never anything pending. */ | ||
| 181 | } | ||
| 182 | |||
| 183 | /* Shutdown one of the (PCI ...) IRQs routes over a bridge. */ | ||
| 184 | static void shutdown_bridge_irq(struct irq_data *d) | ||
| 185 | { | ||
| 186 | struct bridge_controller *bc = IRQ_TO_BRIDGE(d->irq); | ||
| 187 | bridge_t *bridge = bc->base; | ||
| 188 | int pin, swlevel; | ||
| 189 | cpuid_t cpu; | ||
| 190 | |||
| 191 | pr_debug("bridge_shutdown: irq 0x%x\n", d->irq); | ||
| 192 | pin = SLOT_FROM_PCI_IRQ(d->irq); | ||
| 193 | |||
| 194 | /* | ||
| 195 | * map irq to a swlevel greater than 6 since the first 6 bits | ||
| 196 | * of INT_PEND0 are taken | ||
| 197 | */ | ||
| 198 | swlevel = find_level(&cpu, d->irq); | ||
| 199 | intr_disconnect_level(cpu, swlevel); | ||
| 200 | |||
| 201 | bridge->b_int_enable &= ~(1 << pin); | ||
| 202 | bridge->b_wid_tflush; | ||
| 203 | } | ||
| 204 | |||
| 205 | static inline void enable_bridge_irq(struct irq_data *d) | ||
| 206 | { | ||
| 207 | cpuid_t cpu; | ||
| 208 | int swlevel; | ||
| 209 | |||
| 210 | swlevel = find_level(&cpu, d->irq); /* Criminal offence */ | ||
| 211 | intr_connect_level(cpu, swlevel); | ||
| 212 | } | ||
| 213 | |||
| 214 | static inline void disable_bridge_irq(struct irq_data *d) | ||
| 215 | { | ||
| 216 | cpuid_t cpu; | ||
| 217 | int swlevel; | ||
| 218 | |||
| 219 | swlevel = find_level(&cpu, d->irq); /* Criminal offence */ | ||
| 220 | intr_disconnect_level(cpu, swlevel); | ||
| 221 | } | ||
| 222 | |||
| 223 | static struct irq_chip bridge_irq_type = { | ||
| 224 | .name = "bridge", | ||
| 225 | .irq_startup = startup_bridge_irq, | ||
| 226 | .irq_shutdown = shutdown_bridge_irq, | ||
| 227 | .irq_mask = disable_bridge_irq, | ||
| 228 | .irq_unmask = enable_bridge_irq, | ||
| 229 | }; | ||
| 230 | |||
| 231 | void register_bridge_irq(unsigned int irq) | ||
| 232 | { | ||
| 233 | irq_set_chip_and_handler(irq, &bridge_irq_type, handle_level_irq); | ||
| 234 | } | ||
| 235 | |||
| 236 | int request_bridge_irq(struct bridge_controller *bc) | ||
| 237 | { | ||
| 238 | int irq = allocate_irqno(); | ||
| 239 | int swlevel, cpu; | ||
| 240 | nasid_t nasid; | ||
| 241 | |||
| 242 | if (irq < 0) | ||
| 243 | return irq; | ||
| 244 | |||
| 245 | /* | ||
| 246 | * "map" irq to a swlevel greater than 6 since the first 6 bits | ||
| 247 | * of INT_PEND0 are taken | ||
| 248 | */ | ||
| 249 | cpu = bc->irq_cpu; | ||
| 250 | swlevel = alloc_level(cpu, irq); | ||
| 251 | if (unlikely(swlevel < 0)) { | ||
| 252 | free_irqno(irq); | ||
| 253 | |||
| 254 | return -EAGAIN; | ||
| 255 | } | ||
| 256 | |||
| 257 | /* Make sure it's not already pending when we connect it. */ | ||
| 258 | nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu)); | ||
| 259 | REMOTE_HUB_CLR_INTR(nasid, swlevel); | ||
| 260 | |||
| 261 | intr_connect_level(cpu, swlevel); | ||
| 262 | |||
| 263 | register_bridge_irq(irq); | ||
| 264 | |||
| 265 | return irq; | ||
| 266 | } | ||
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index 0dde6164a06f..710a59764b01 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c | |||
| @@ -7,67 +7,234 @@ | |||
| 7 | * Copyright (C) 1999 - 2001 Kanoj Sarcar | 7 | * Copyright (C) 1999 - 2001 Kanoj Sarcar |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #undef DEBUG | ||
| 11 | |||
| 12 | #include <linux/init.h> | ||
| 13 | #include <linux/irq.h> | ||
| 14 | #include <linux/errno.h> | ||
| 15 | #include <linux/signal.h> | ||
| 16 | #include <linux/sched.h> | ||
| 17 | #include <linux/types.h> | ||
| 18 | #include <linux/interrupt.h> | 10 | #include <linux/interrupt.h> |
| 11 | #include <linux/irq.h> | ||
| 19 | #include <linux/ioport.h> | 12 | #include <linux/ioport.h> |
| 20 | #include <linux/timex.h> | ||
| 21 | #include <linux/smp.h> | ||
| 22 | #include <linux/random.h> | ||
| 23 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| 24 | #include <linux/kernel_stat.h> | ||
| 25 | #include <linux/delay.h> | ||
| 26 | #include <linux/bitops.h> | 14 | #include <linux/bitops.h> |
| 27 | 15 | ||
| 28 | #include <asm/bootinfo.h> | ||
| 29 | #include <asm/io.h> | 16 | #include <asm/io.h> |
| 30 | #include <asm/mipsregs.h> | 17 | #include <asm/irq_cpu.h> |
| 31 | 18 | #include <asm/pci/bridge.h> | |
| 32 | #include <asm/processor.h> | ||
| 33 | #include <asm/sn/addrs.h> | 19 | #include <asm/sn/addrs.h> |
| 34 | #include <asm/sn/agent.h> | 20 | #include <asm/sn/agent.h> |
| 35 | #include <asm/sn/arch.h> | 21 | #include <asm/sn/arch.h> |
| 36 | #include <asm/sn/hub.h> | 22 | #include <asm/sn/hub.h> |
| 37 | #include <asm/sn/intr.h> | 23 | #include <asm/sn/intr.h> |
| 38 | 24 | ||
| 39 | /* | 25 | struct hub_irq_data { |
| 40 | * Linux has a controller-independent x86 interrupt architecture. | 26 | struct bridge_controller *bc; |
| 41 | * every controller has a 'controller-template', that is used | 27 | u64 *irq_mask[2]; |
| 42 | * by the main code to do the right thing. Each driver-visible | 28 | cpuid_t cpu; |
| 43 | * interrupt source is transparently wired to the appropriate | 29 | int bit; |
| 44 | * controller. Thus drivers need not be aware of the | 30 | int pin; |
| 45 | * interrupt-controller. | 31 | }; |
| 46 | * | ||
| 47 | * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC, | ||
| 48 | * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC. | ||
| 49 | * (IO-APICs assumed to be messaging to Pentium local-APICs) | ||
| 50 | * | ||
| 51 | * the code is designed to be easily extended with new/different | ||
| 52 | * interrupt controllers, without having to do assembly magic. | ||
| 53 | */ | ||
| 54 | 32 | ||
| 55 | extern asmlinkage void ip27_irq(void); | 33 | static DECLARE_BITMAP(hub_irq_map, IP27_HUB_IRQ_COUNT); |
| 56 | 34 | ||
| 57 | /* | 35 | static DEFINE_PER_CPU(unsigned long [2], irq_enable_mask); |
| 58 | * Find first bit set | 36 | |
| 59 | */ | 37 | static inline int alloc_level(void) |
| 60 | static int ms1bit(unsigned long x) | 38 | { |
| 39 | int level; | ||
| 40 | |||
| 41 | again: | ||
| 42 | level = find_first_zero_bit(hub_irq_map, IP27_HUB_IRQ_COUNT); | ||
| 43 | if (level >= IP27_HUB_IRQ_COUNT) | ||
| 44 | return -ENOSPC; | ||
| 45 | |||
| 46 | if (test_and_set_bit(level, hub_irq_map)) | ||
| 47 | goto again; | ||
| 48 | |||
| 49 | return level; | ||
| 50 | } | ||
| 51 | |||
| 52 | static void enable_hub_irq(struct irq_data *d) | ||
| 53 | { | ||
| 54 | struct hub_irq_data *hd = irq_data_get_irq_chip_data(d); | ||
| 55 | unsigned long *mask = per_cpu(irq_enable_mask, hd->cpu); | ||
| 56 | |||
| 57 | set_bit(hd->bit, mask); | ||
| 58 | __raw_writeq(mask[0], hd->irq_mask[0]); | ||
| 59 | __raw_writeq(mask[1], hd->irq_mask[1]); | ||
| 60 | } | ||
| 61 | |||
| 62 | static void disable_hub_irq(struct irq_data *d) | ||
| 63 | { | ||
| 64 | struct hub_irq_data *hd = irq_data_get_irq_chip_data(d); | ||
| 65 | unsigned long *mask = per_cpu(irq_enable_mask, hd->cpu); | ||
| 66 | |||
| 67 | clear_bit(hd->bit, mask); | ||
| 68 | __raw_writeq(mask[0], hd->irq_mask[0]); | ||
| 69 | __raw_writeq(mask[1], hd->irq_mask[1]); | ||
| 70 | } | ||
| 71 | |||
| 72 | static unsigned int startup_bridge_irq(struct irq_data *d) | ||
| 73 | { | ||
| 74 | struct hub_irq_data *hd = irq_data_get_irq_chip_data(d); | ||
| 75 | struct bridge_controller *bc; | ||
| 76 | nasid_t nasid; | ||
| 77 | u32 device; | ||
| 78 | int pin; | ||
| 79 | |||
| 80 | if (!hd) | ||
| 81 | return -EINVAL; | ||
| 82 | |||
| 83 | pin = hd->pin; | ||
| 84 | bc = hd->bc; | ||
| 85 | |||
| 86 | nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(hd->cpu)); | ||
| 87 | bridge_write(bc, b_int_addr[pin].addr, | ||
| 88 | (0x20000 | hd->bit | (nasid << 8))); | ||
| 89 | bridge_set(bc, b_int_enable, (1 << pin)); | ||
| 90 | bridge_set(bc, b_int_enable, 0x7ffffe00); /* more stuff in int_enable */ | ||
| 91 | |||
| 92 | /* | ||
| 93 | * Enable sending of an interrupt clear packt to the hub on a high to | ||
| 94 | * low transition of the interrupt pin. | ||
| 95 | * | ||
| 96 | * IRIX sets additional bits in the address which are documented as | ||
| 97 | * reserved in the bridge docs. | ||
| 98 | */ | ||
| 99 | bridge_set(bc, b_int_mode, (1UL << pin)); | ||
| 100 | |||
| 101 | /* | ||
| 102 | * We assume the bridge to have a 1:1 mapping between devices | ||
| 103 | * (slots) and intr pins. | ||
| 104 | */ | ||
| 105 | device = bridge_read(bc, b_int_device); | ||
| 106 | device &= ~(7 << (pin*3)); | ||
| 107 | device |= (pin << (pin*3)); | ||
| 108 | bridge_write(bc, b_int_device, device); | ||
| 109 | |||
| 110 | bridge_read(bc, b_wid_tflush); | ||
| 111 | |||
| 112 | enable_hub_irq(d); | ||
| 113 | |||
| 114 | return 0; /* Never anything pending. */ | ||
| 115 | } | ||
| 116 | |||
| 117 | static void shutdown_bridge_irq(struct irq_data *d) | ||
| 118 | { | ||
| 119 | struct hub_irq_data *hd = irq_data_get_irq_chip_data(d); | ||
| 120 | struct bridge_controller *bc; | ||
| 121 | int pin = hd->pin; | ||
| 122 | |||
| 123 | if (!hd) | ||
| 124 | return; | ||
| 125 | |||
| 126 | disable_hub_irq(d); | ||
| 127 | |||
| 128 | bc = hd->bc; | ||
| 129 | bridge_clr(bc, b_int_enable, (1 << pin)); | ||
| 130 | bridge_read(bc, b_wid_tflush); | ||
| 131 | } | ||
| 132 | |||
| 133 | static void setup_hub_mask(struct hub_irq_data *hd, const struct cpumask *mask) | ||
| 134 | { | ||
| 135 | nasid_t nasid; | ||
| 136 | int cpu; | ||
| 137 | |||
| 138 | cpu = cpumask_first_and(mask, cpu_online_mask); | ||
| 139 | nasid = COMPACT_TO_NASID_NODEID(cpu_to_node(cpu)); | ||
| 140 | hd->cpu = cpu; | ||
| 141 | if (!cputoslice(cpu)) { | ||
| 142 | hd->irq_mask[0] = REMOTE_HUB_PTR(nasid, PI_INT_MASK0_A); | ||
| 143 | hd->irq_mask[1] = REMOTE_HUB_PTR(nasid, PI_INT_MASK1_A); | ||
| 144 | } else { | ||
| 145 | hd->irq_mask[0] = REMOTE_HUB_PTR(nasid, PI_INT_MASK0_B); | ||
| 146 | hd->irq_mask[1] = REMOTE_HUB_PTR(nasid, PI_INT_MASK1_B); | ||
| 147 | } | ||
| 148 | |||
| 149 | /* Make sure it's not already pending when we connect it. */ | ||
| 150 | REMOTE_HUB_CLR_INTR(nasid, hd->bit); | ||
| 151 | } | ||
| 152 | |||
| 153 | static int set_affinity_hub_irq(struct irq_data *d, const struct cpumask *mask, | ||
| 154 | bool force) | ||
| 155 | { | ||
| 156 | struct hub_irq_data *hd = irq_data_get_irq_chip_data(d); | ||
| 157 | |||
| 158 | if (!hd) | ||
| 159 | return -EINVAL; | ||
| 160 | |||
| 161 | if (irqd_is_started(d)) | ||
| 162 | disable_hub_irq(d); | ||
| 163 | |||
| 164 | setup_hub_mask(hd, mask); | ||
| 165 | |||
| 166 | if (irqd_is_started(d)) | ||
| 167 | startup_bridge_irq(d); | ||
| 168 | |||
| 169 | irq_data_update_effective_affinity(d, cpumask_of(hd->cpu)); | ||
| 170 | |||
| 171 | return 0; | ||
| 172 | } | ||
| 173 | |||
| 174 | static struct irq_chip hub_irq_type = { | ||
| 175 | .name = "HUB", | ||
| 176 | .irq_startup = startup_bridge_irq, | ||
| 177 | .irq_shutdown = shutdown_bridge_irq, | ||
| 178 | .irq_mask = disable_hub_irq, | ||
| 179 | .irq_unmask = enable_hub_irq, | ||
| 180 | .irq_set_affinity = set_affinity_hub_irq, | ||
| 181 | }; | ||
| 182 | |||
| 183 | int request_bridge_irq(struct bridge_controller *bc, int pin) | ||
| 61 | { | 184 | { |
| 62 | int b = 0, s; | 185 | struct hub_irq_data *hd; |
| 186 | struct hub_data *hub; | ||
| 187 | struct irq_desc *desc; | ||
| 188 | int swlevel; | ||
| 189 | int irq; | ||
| 190 | |||
| 191 | hd = kzalloc(sizeof(*hd), GFP_KERNEL); | ||
| 192 | if (!hd) | ||
| 193 | return -ENOMEM; | ||
| 194 | |||
| 195 | swlevel = alloc_level(); | ||
| 196 | if (unlikely(swlevel < 0)) { | ||
| 197 | kfree(hd); | ||
| 198 | return -EAGAIN; | ||
| 199 | } | ||
| 200 | irq = swlevel + IP27_HUB_IRQ_BASE; | ||
| 201 | |||
| 202 | hd->bc = bc; | ||
| 203 | hd->bit = swlevel; | ||
| 204 | hd->pin = pin; | ||
| 205 | irq_set_chip_data(irq, hd); | ||
| 206 | |||
| 207 | /* use CPU connected to nearest hub */ | ||
| 208 | hub = hub_data(NASID_TO_COMPACT_NODEID(bc->nasid)); | ||
| 209 | setup_hub_mask(hd, &hub->h_cpus); | ||
| 63 | 210 | ||
| 64 | s = 16; if (x >> 16 == 0) s = 0; b += s; x >>= s; | 211 | desc = irq_to_desc(irq); |
| 65 | s = 8; if (x >> 8 == 0) s = 0; b += s; x >>= s; | 212 | desc->irq_common_data.node = bc->nasid; |
| 66 | s = 4; if (x >> 4 == 0) s = 0; b += s; x >>= s; | 213 | cpumask_copy(desc->irq_common_data.affinity, &hub->h_cpus); |
| 67 | s = 2; if (x >> 2 == 0) s = 0; b += s; x >>= s; | ||
| 68 | s = 1; if (x >> 1 == 0) s = 0; b += s; | ||
| 69 | 214 | ||
| 70 | return b; | 215 | return irq; |
| 216 | } | ||
| 217 | |||
| 218 | void ip27_hub_irq_init(void) | ||
| 219 | { | ||
| 220 | int i; | ||
| 221 | |||
| 222 | for (i = IP27_HUB_IRQ_BASE; | ||
| 223 | i < (IP27_HUB_IRQ_BASE + IP27_HUB_IRQ_COUNT); i++) | ||
| 224 | irq_set_chip_and_handler(i, &hub_irq_type, handle_level_irq); | ||
| 225 | |||
| 226 | /* | ||
| 227 | * Some interrupts are reserved by hardware or by software convention. | ||
| 228 | * Mark these as reserved right away so they won't be used accidentally | ||
| 229 | * later. | ||
| 230 | */ | ||
| 231 | for (i = 0; i <= BASE_PCI_IRQ; i++) | ||
| 232 | set_bit(i, hub_irq_map); | ||
| 233 | |||
| 234 | set_bit(IP_PEND0_6_63, hub_irq_map); | ||
| 235 | |||
| 236 | for (i = NI_BRDCAST_ERR_A; i <= MSC_PANIC_INTR; i++) | ||
| 237 | set_bit(i, hub_irq_map); | ||
| 71 | } | 238 | } |
| 72 | 239 | ||
| 73 | /* | 240 | /* |
| @@ -82,23 +249,19 @@ static int ms1bit(unsigned long x) | |||
| 82 | * Kanoj 05.13.00 | 249 | * Kanoj 05.13.00 |
| 83 | */ | 250 | */ |
| 84 | 251 | ||
| 85 | static void ip27_do_irq_mask0(void) | 252 | static void ip27_do_irq_mask0(struct irq_desc *desc) |
| 86 | { | 253 | { |
| 87 | int irq, swlevel; | ||
| 88 | hubreg_t pend0, mask0; | ||
| 89 | cpuid_t cpu = smp_processor_id(); | 254 | cpuid_t cpu = smp_processor_id(); |
| 90 | int pi_int_mask0 = | 255 | unsigned long *mask = per_cpu(irq_enable_mask, cpu); |
| 91 | (cputoslice(cpu) == 0) ? PI_INT_MASK0_A : PI_INT_MASK0_B; | 256 | u64 pend0; |
| 92 | 257 | ||
| 93 | /* copied from Irix intpend0() */ | 258 | /* copied from Irix intpend0() */ |
| 94 | pend0 = LOCAL_HUB_L(PI_INT_PEND0); | 259 | pend0 = LOCAL_HUB_L(PI_INT_PEND0); |
| 95 | mask0 = LOCAL_HUB_L(pi_int_mask0); | ||
| 96 | 260 | ||
| 97 | pend0 &= mask0; /* Pick intrs we should look at */ | 261 | pend0 &= mask[0]; /* Pick intrs we should look at */ |
| 98 | if (!pend0) | 262 | if (!pend0) |
| 99 | return; | 263 | return; |
| 100 | 264 | ||
| 101 | swlevel = ms1bit(pend0); | ||
| 102 | #ifdef CONFIG_SMP | 265 | #ifdef CONFIG_SMP |
| 103 | if (pend0 & (1UL << CPU_RESCHED_A_IRQ)) { | 266 | if (pend0 & (1UL << CPU_RESCHED_A_IRQ)) { |
| 104 | LOCAL_HUB_CLR_INTR(CPU_RESCHED_A_IRQ); | 267 | LOCAL_HUB_CLR_INTR(CPU_RESCHED_A_IRQ); |
| @@ -108,106 +271,66 @@ static void ip27_do_irq_mask0(void) | |||
| 108 | scheduler_ipi(); | 271 | scheduler_ipi(); |
| 109 | } else if (pend0 & (1UL << CPU_CALL_A_IRQ)) { | 272 | } else if (pend0 & (1UL << CPU_CALL_A_IRQ)) { |
| 110 | LOCAL_HUB_CLR_INTR(CPU_CALL_A_IRQ); | 273 | LOCAL_HUB_CLR_INTR(CPU_CALL_A_IRQ); |
| 111 | irq_enter(); | ||
| 112 | generic_smp_call_function_interrupt(); | 274 | generic_smp_call_function_interrupt(); |
| 113 | irq_exit(); | ||
| 114 | } else if (pend0 & (1UL << CPU_CALL_B_IRQ)) { | 275 | } else if (pend0 & (1UL << CPU_CALL_B_IRQ)) { |
| 115 | LOCAL_HUB_CLR_INTR(CPU_CALL_B_IRQ); | 276 | LOCAL_HUB_CLR_INTR(CPU_CALL_B_IRQ); |
| 116 | irq_enter(); | ||
| 117 | generic_smp_call_function_interrupt(); | 277 | generic_smp_call_function_interrupt(); |
| 118 | irq_exit(); | ||
| 119 | } else | 278 | } else |
| 120 | #endif | 279 | #endif |
| 121 | { | 280 | generic_handle_irq(__ffs(pend0) + IP27_HUB_IRQ_BASE); |
| 122 | /* "map" swlevel to irq */ | ||
| 123 | struct slice_data *si = cpu_data[cpu].data; | ||
| 124 | |||
| 125 | irq = si->level_to_irq[swlevel]; | ||
| 126 | do_IRQ(irq); | ||
| 127 | } | ||
| 128 | 281 | ||
| 129 | LOCAL_HUB_L(PI_INT_PEND0); | 282 | LOCAL_HUB_L(PI_INT_PEND0); |
| 130 | } | 283 | } |
| 131 | 284 | ||
| 132 | static void ip27_do_irq_mask1(void) | 285 | static void ip27_do_irq_mask1(struct irq_desc *desc) |
| 133 | { | 286 | { |
| 134 | int irq, swlevel; | ||
| 135 | hubreg_t pend1, mask1; | ||
| 136 | cpuid_t cpu = smp_processor_id(); | 287 | cpuid_t cpu = smp_processor_id(); |
| 137 | int pi_int_mask1 = (cputoslice(cpu) == 0) ? PI_INT_MASK1_A : PI_INT_MASK1_B; | 288 | unsigned long *mask = per_cpu(irq_enable_mask, cpu); |
| 138 | struct slice_data *si = cpu_data[cpu].data; | 289 | u64 pend1; |
| 139 | 290 | ||
| 140 | /* copied from Irix intpend0() */ | 291 | /* copied from Irix intpend0() */ |
| 141 | pend1 = LOCAL_HUB_L(PI_INT_PEND1); | 292 | pend1 = LOCAL_HUB_L(PI_INT_PEND1); |
| 142 | mask1 = LOCAL_HUB_L(pi_int_mask1); | ||
| 143 | 293 | ||
| 144 | pend1 &= mask1; /* Pick intrs we should look at */ | 294 | pend1 &= mask[1]; /* Pick intrs we should look at */ |
| 145 | if (!pend1) | 295 | if (!pend1) |
| 146 | return; | 296 | return; |
| 147 | 297 | ||
| 148 | swlevel = ms1bit(pend1); | 298 | generic_handle_irq(__ffs(pend1) + IP27_HUB_IRQ_BASE + 64); |
| 149 | /* "map" swlevel to irq */ | ||
| 150 | irq = si->level_to_irq[swlevel]; | ||
| 151 | LOCAL_HUB_CLR_INTR(swlevel); | ||
| 152 | do_IRQ(irq); | ||
| 153 | 299 | ||
| 154 | LOCAL_HUB_L(PI_INT_PEND1); | 300 | LOCAL_HUB_L(PI_INT_PEND1); |
| 155 | } | 301 | } |
| 156 | 302 | ||
| 157 | static void ip27_prof_timer(void) | ||
| 158 | { | ||
| 159 | panic("CPU %d got a profiling interrupt", smp_processor_id()); | ||
| 160 | } | ||
| 161 | |||
| 162 | static void ip27_hub_error(void) | ||
| 163 | { | ||
| 164 | panic("CPU %d got a hub error interrupt", smp_processor_id()); | ||
| 165 | } | ||
| 166 | |||
| 167 | asmlinkage void plat_irq_dispatch(void) | ||
| 168 | { | ||
| 169 | unsigned long pending = read_c0_cause() & read_c0_status(); | ||
| 170 | extern unsigned int rt_timer_irq; | ||
| 171 | |||
| 172 | if (pending & CAUSEF_IP4) | ||
| 173 | do_IRQ(rt_timer_irq); | ||
| 174 | else if (pending & CAUSEF_IP2) /* PI_INT_PEND_0 or CC_PEND_{A|B} */ | ||
| 175 | ip27_do_irq_mask0(); | ||
| 176 | else if (pending & CAUSEF_IP3) /* PI_INT_PEND_1 */ | ||
| 177 | ip27_do_irq_mask1(); | ||
| 178 | else if (pending & CAUSEF_IP5) | ||
| 179 | ip27_prof_timer(); | ||
| 180 | else if (pending & CAUSEF_IP6) | ||
| 181 | ip27_hub_error(); | ||
| 182 | } | ||
| 183 | |||
| 184 | void __init arch_init_irq(void) | ||
| 185 | { | ||
| 186 | } | ||
| 187 | |||
| 188 | void install_ipi(void) | 303 | void install_ipi(void) |
| 189 | { | 304 | { |
| 190 | int slice = LOCAL_HUB_L(PI_CPU_NUM); | ||
| 191 | int cpu = smp_processor_id(); | 305 | int cpu = smp_processor_id(); |
| 192 | struct slice_data *si = cpu_data[cpu].data; | 306 | unsigned long *mask = per_cpu(irq_enable_mask, cpu); |
| 193 | struct hub_data *hub = hub_data(cpu_to_node(cpu)); | 307 | int slice = LOCAL_HUB_L(PI_CPU_NUM); |
| 194 | int resched, call; | 308 | int resched, call; |
| 195 | 309 | ||
| 196 | resched = CPU_RESCHED_A_IRQ + slice; | 310 | resched = CPU_RESCHED_A_IRQ + slice; |
| 197 | __set_bit(resched, hub->irq_alloc_mask); | 311 | set_bit(resched, mask); |
| 198 | __set_bit(resched, si->irq_enable_mask); | ||
| 199 | LOCAL_HUB_CLR_INTR(resched); | 312 | LOCAL_HUB_CLR_INTR(resched); |
| 200 | 313 | ||
| 201 | call = CPU_CALL_A_IRQ + slice; | 314 | call = CPU_CALL_A_IRQ + slice; |
| 202 | __set_bit(call, hub->irq_alloc_mask); | 315 | set_bit(call, mask); |
| 203 | __set_bit(call, si->irq_enable_mask); | ||
| 204 | LOCAL_HUB_CLR_INTR(call); | 316 | LOCAL_HUB_CLR_INTR(call); |
| 205 | 317 | ||
| 206 | if (slice == 0) { | 318 | if (slice == 0) { |
| 207 | LOCAL_HUB_S(PI_INT_MASK0_A, si->irq_enable_mask[0]); | 319 | LOCAL_HUB_S(PI_INT_MASK0_A, mask[0]); |
| 208 | LOCAL_HUB_S(PI_INT_MASK1_A, si->irq_enable_mask[1]); | 320 | LOCAL_HUB_S(PI_INT_MASK1_A, mask[1]); |
| 209 | } else { | 321 | } else { |
| 210 | LOCAL_HUB_S(PI_INT_MASK0_B, si->irq_enable_mask[0]); | 322 | LOCAL_HUB_S(PI_INT_MASK0_B, mask[0]); |
| 211 | LOCAL_HUB_S(PI_INT_MASK1_B, si->irq_enable_mask[1]); | 323 | LOCAL_HUB_S(PI_INT_MASK1_B, mask[1]); |
| 212 | } | 324 | } |
| 213 | } | 325 | } |
| 326 | |||
| 327 | void __init arch_init_irq(void) | ||
| 328 | { | ||
| 329 | mips_cpu_irq_init(); | ||
| 330 | ip27_hub_irq_init(); | ||
| 331 | |||
| 332 | irq_set_percpu_devid(IP27_HUB_PEND0_IRQ); | ||
| 333 | irq_set_chained_handler(IP27_HUB_PEND0_IRQ, ip27_do_irq_mask0); | ||
| 334 | irq_set_percpu_devid(IP27_HUB_PEND1_IRQ); | ||
| 335 | irq_set_chained_handler(IP27_HUB_PEND1_IRQ, ip27_do_irq_mask1); | ||
| 336 | } | ||
diff --git a/arch/mips/sgi-ip27/ip27-irqno.c b/arch/mips/sgi-ip27/ip27-irqno.c deleted file mode 100644 index 957ab58e1c00..000000000000 --- a/arch/mips/sgi-ip27/ip27-irqno.c +++ /dev/null | |||
| @@ -1,48 +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 | #include <linux/init.h> | ||
| 7 | #include <linux/irq.h> | ||
| 8 | #include <linux/types.h> | ||
| 9 | |||
| 10 | #include <asm/barrier.h> | ||
| 11 | |||
| 12 | static DECLARE_BITMAP(irq_map, NR_IRQS); | ||
| 13 | |||
| 14 | int allocate_irqno(void) | ||
| 15 | { | ||
| 16 | int irq; | ||
| 17 | |||
| 18 | again: | ||
| 19 | irq = find_first_zero_bit(irq_map, NR_IRQS); | ||
| 20 | |||
| 21 | if (irq >= NR_IRQS) | ||
| 22 | return -ENOSPC; | ||
| 23 | |||
| 24 | if (test_and_set_bit(irq, irq_map)) | ||
| 25 | goto again; | ||
| 26 | |||
| 27 | return irq; | ||
| 28 | } | ||
| 29 | |||
| 30 | /* | ||
| 31 | * Allocate the 16 legacy interrupts for i8259 devices. This happens early | ||
| 32 | * in the kernel initialization so treating allocation failure as BUG() is | ||
| 33 | * ok. | ||
| 34 | */ | ||
| 35 | void __init alloc_legacy_irqno(void) | ||
| 36 | { | ||
| 37 | int i; | ||
| 38 | |||
| 39 | for (i = 0; i <= 16; i++) | ||
| 40 | BUG_ON(test_and_set_bit(i, irq_map)); | ||
| 41 | } | ||
| 42 | |||
| 43 | void free_irqno(unsigned int irq) | ||
| 44 | { | ||
| 45 | smp_mb__before_atomic(); | ||
| 46 | clear_bit(irq, irq_map); | ||
| 47 | smp_mb__after_atomic(); | ||
| 48 | } | ||
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c index 813d13f92957..fb077a947575 100644 --- a/arch/mips/sgi-ip27/ip27-memory.c +++ b/arch/mips/sgi-ip27/ip27-memory.c | |||
| @@ -44,7 +44,7 @@ static int is_fine_dirmode(void) | |||
| 44 | return ((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK) >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE; | 44 | return ((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK) >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE; |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | static hubreg_t get_region(cnodeid_t cnode) | 47 | static u64 get_region(cnodeid_t cnode) |
| 48 | { | 48 | { |
| 49 | if (fine_mode) | 49 | if (fine_mode) |
| 50 | return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_FINEREG_SHFT; | 50 | return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_FINEREG_SHFT; |
| @@ -52,9 +52,9 @@ static hubreg_t get_region(cnodeid_t cnode) | |||
| 52 | return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_COARSEREG_SHFT; | 52 | return COMPACT_TO_NASID_NODEID(cnode) >> NASID_TO_COARSEREG_SHFT; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | static hubreg_t region_mask; | 55 | static u64 region_mask; |
| 56 | 56 | ||
| 57 | static void gen_region_mask(hubreg_t *region_mask) | 57 | static void gen_region_mask(u64 *region_mask) |
| 58 | { | 58 | { |
| 59 | cnodeid_t cnode; | 59 | cnodeid_t cnode; |
| 60 | 60 | ||
| @@ -154,11 +154,11 @@ static int __init compute_node_distance(nasid_t nasid_a, nasid_t nasid_b) | |||
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | if (router_a == NULL) { | 156 | if (router_a == NULL) { |
| 157 | printk("node_distance: router_a NULL\n"); | 157 | pr_info("node_distance: router_a NULL\n"); |
| 158 | return -1; | 158 | return -1; |
| 159 | } | 159 | } |
| 160 | if (router_b == NULL) { | 160 | if (router_b == NULL) { |
| 161 | printk("node_distance: router_b NULL\n"); | 161 | pr_info("node_distance: router_b NULL\n"); |
| 162 | return -1; | 162 | return -1; |
| 163 | } | 163 | } |
| 164 | 164 | ||
| @@ -203,17 +203,17 @@ static void __init dump_topology(void) | |||
| 203 | klrou_t *router; | 203 | klrou_t *router; |
| 204 | cnodeid_t row, col; | 204 | cnodeid_t row, col; |
| 205 | 205 | ||
| 206 | printk("************** Topology ********************\n"); | 206 | pr_info("************** Topology ********************\n"); |
| 207 | 207 | ||
| 208 | printk(" "); | 208 | pr_info(" "); |
| 209 | for_each_online_node(col) | 209 | for_each_online_node(col) |
| 210 | printk("%02d ", col); | 210 | pr_cont("%02d ", col); |
| 211 | printk("\n"); | 211 | pr_cont("\n"); |
| 212 | for_each_online_node(row) { | 212 | for_each_online_node(row) { |
| 213 | printk("%02d ", row); | 213 | pr_info("%02d ", row); |
| 214 | for_each_online_node(col) | 214 | for_each_online_node(col) |
| 215 | printk("%2d ", node_distance(row, col)); | 215 | pr_cont("%2d ", node_distance(row, col)); |
| 216 | printk("\n"); | 216 | pr_cont("\n"); |
| 217 | } | 217 | } |
| 218 | 218 | ||
| 219 | for_each_online_node(cnode) { | 219 | for_each_online_node(cnode) { |
| @@ -230,7 +230,7 @@ static void __init dump_topology(void) | |||
| 230 | do { | 230 | do { |
| 231 | if (brd->brd_flags & DUPLICATE_BOARD) | 231 | if (brd->brd_flags & DUPLICATE_BOARD) |
| 232 | continue; | 232 | continue; |
| 233 | printk("Router %d:", router_num); | 233 | pr_cont("Router %d:", router_num); |
| 234 | router_num++; | 234 | router_num++; |
| 235 | 235 | ||
| 236 | router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]); | 236 | router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd), brd->brd_compts[0]); |
| @@ -244,11 +244,11 @@ static void __init dump_topology(void) | |||
| 244 | router->rou_port[port].port_offset); | 244 | router->rou_port[port].port_offset); |
| 245 | 245 | ||
| 246 | if (dest_brd->brd_type == KLTYPE_IP27) | 246 | if (dest_brd->brd_type == KLTYPE_IP27) |
| 247 | printk(" %d", dest_brd->brd_nasid); | 247 | pr_cont(" %d", dest_brd->brd_nasid); |
| 248 | if (dest_brd->brd_type == KLTYPE_ROUTER) | 248 | if (dest_brd->brd_type == KLTYPE_ROUTER) |
| 249 | printk(" r"); | 249 | pr_cont(" r"); |
| 250 | } | 250 | } |
| 251 | printk("\n"); | 251 | pr_cont("\n"); |
| 252 | 252 | ||
| 253 | } while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) ); | 253 | } while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) ); |
| 254 | } | 254 | } |
| @@ -373,7 +373,7 @@ static void __init szmem(void) | |||
| 373 | 373 | ||
| 374 | if ((nodebytes >> PAGE_SHIFT) * (sizeof(struct page)) > | 374 | if ((nodebytes >> PAGE_SHIFT) * (sizeof(struct page)) > |
| 375 | (slot0sz << PAGE_SHIFT)) { | 375 | (slot0sz << PAGE_SHIFT)) { |
| 376 | printk("Ignoring slot %d onwards on node %d\n", | 376 | pr_info("Ignoring slot %d onwards on node %d\n", |
| 377 | slot, node); | 377 | slot, node); |
| 378 | slot = MAX_MEM_SLOTS; | 378 | slot = MAX_MEM_SLOTS; |
| 379 | continue; | 379 | continue; |
diff --git a/arch/mips/sgi-ip27/ip27-nmi.c b/arch/mips/sgi-ip27/ip27-nmi.c index 8ac2bfa35fb6..3aae388561d9 100644 --- a/arch/mips/sgi-ip27/ip27-nmi.c +++ b/arch/mips/sgi-ip27/ip27-nmi.c | |||
| @@ -62,75 +62,75 @@ void nmi_cpu_eframe_save(nasid_t nasid, int slice) | |||
| 62 | (TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) + | 62 | (TO_UNCAC(TO_NODE(nasid, IP27_NMI_KREGS_OFFSET)) + |
| 63 | slice * IP27_NMI_KREGS_CPU_SIZE); | 63 | slice * IP27_NMI_KREGS_CPU_SIZE); |
| 64 | 64 | ||
| 65 | printk("NMI nasid %d: slice %d\n", nasid, slice); | 65 | pr_emerg("NMI nasid %d: slice %d\n", nasid, slice); |
| 66 | 66 | ||
| 67 | /* | 67 | /* |
| 68 | * Saved main processor registers | 68 | * Saved main processor registers |
| 69 | */ | 69 | */ |
| 70 | for (i = 0; i < 32; ) { | 70 | for (i = 0; i < 32; ) { |
| 71 | if ((i % 4) == 0) | 71 | if ((i % 4) == 0) |
| 72 | printk("$%2d :", i); | 72 | pr_emerg("$%2d :", i); |
| 73 | printk(" %016lx", nr->gpr[i]); | 73 | pr_cont(" %016lx", nr->gpr[i]); |
| 74 | 74 | ||
| 75 | i++; | 75 | i++; |
| 76 | if ((i % 4) == 0) | 76 | if ((i % 4) == 0) |
| 77 | printk("\n"); | 77 | pr_cont("\n"); |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | printk("Hi : (value lost)\n"); | 80 | pr_emerg("Hi : (value lost)\n"); |
| 81 | printk("Lo : (value lost)\n"); | 81 | pr_emerg("Lo : (value lost)\n"); |
| 82 | 82 | ||
| 83 | /* | 83 | /* |
| 84 | * Saved cp0 registers | 84 | * Saved cp0 registers |
| 85 | */ | 85 | */ |
| 86 | printk("epc : %016lx %pS\n", nr->epc, (void *) nr->epc); | 86 | pr_emerg("epc : %016lx %pS\n", nr->epc, (void *)nr->epc); |
| 87 | printk("%s\n", print_tainted()); | 87 | pr_emerg("%s\n", print_tainted()); |
| 88 | printk("ErrEPC: %016lx %pS\n", nr->error_epc, (void *) nr->error_epc); | 88 | pr_emerg("ErrEPC: %016lx %pS\n", nr->error_epc, (void *)nr->error_epc); |
| 89 | printk("ra : %016lx %pS\n", nr->gpr[31], (void *) nr->gpr[31]); | 89 | pr_emerg("ra : %016lx %pS\n", nr->gpr[31], (void *)nr->gpr[31]); |
| 90 | printk("Status: %08lx ", nr->sr); | 90 | pr_emerg("Status: %08lx ", nr->sr); |
| 91 | 91 | ||
| 92 | if (nr->sr & ST0_KX) | 92 | if (nr->sr & ST0_KX) |
| 93 | printk("KX "); | 93 | pr_cont("KX "); |
| 94 | if (nr->sr & ST0_SX) | 94 | if (nr->sr & ST0_SX) |
| 95 | printk("SX "); | 95 | pr_cont("SX "); |
| 96 | if (nr->sr & ST0_UX) | 96 | if (nr->sr & ST0_UX) |
| 97 | printk("UX "); | 97 | pr_cont("UX "); |
| 98 | 98 | ||
| 99 | switch (nr->sr & ST0_KSU) { | 99 | switch (nr->sr & ST0_KSU) { |
| 100 | case KSU_USER: | 100 | case KSU_USER: |
| 101 | printk("USER "); | 101 | pr_cont("USER "); |
| 102 | break; | 102 | break; |
| 103 | case KSU_SUPERVISOR: | 103 | case KSU_SUPERVISOR: |
| 104 | printk("SUPERVISOR "); | 104 | pr_cont("SUPERVISOR "); |
| 105 | break; | 105 | break; |
| 106 | case KSU_KERNEL: | 106 | case KSU_KERNEL: |
| 107 | printk("KERNEL "); | 107 | pr_cont("KERNEL "); |
| 108 | break; | 108 | break; |
| 109 | default: | 109 | default: |
| 110 | printk("BAD_MODE "); | 110 | pr_cont("BAD_MODE "); |
| 111 | break; | 111 | break; |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | if (nr->sr & ST0_ERL) | 114 | if (nr->sr & ST0_ERL) |
| 115 | printk("ERL "); | 115 | pr_cont("ERL "); |
| 116 | if (nr->sr & ST0_EXL) | 116 | if (nr->sr & ST0_EXL) |
| 117 | printk("EXL "); | 117 | pr_cont("EXL "); |
| 118 | if (nr->sr & ST0_IE) | 118 | if (nr->sr & ST0_IE) |
| 119 | printk("IE "); | 119 | pr_cont("IE "); |
| 120 | printk("\n"); | 120 | pr_cont("\n"); |
| 121 | 121 | ||
| 122 | printk("Cause : %08lx\n", nr->cause); | 122 | pr_emerg("Cause : %08lx\n", nr->cause); |
| 123 | printk("PrId : %08x\n", read_c0_prid()); | 123 | pr_emerg("PrId : %08x\n", read_c0_prid()); |
| 124 | printk("BadVA : %016lx\n", nr->badva); | 124 | pr_emerg("BadVA : %016lx\n", nr->badva); |
| 125 | printk("CErr : %016lx\n", nr->cache_err); | 125 | pr_emerg("CErr : %016lx\n", nr->cache_err); |
| 126 | printk("NMI_SR: %016lx\n", nr->nmi_sr); | 126 | pr_emerg("NMI_SR: %016lx\n", nr->nmi_sr); |
| 127 | 127 | ||
| 128 | printk("\n"); | 128 | pr_emerg("\n"); |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | void nmi_dump_hub_irq(nasid_t nasid, int slice) | 131 | void nmi_dump_hub_irq(nasid_t nasid, int slice) |
| 132 | { | 132 | { |
| 133 | hubreg_t mask0, mask1, pend0, pend1; | 133 | u64 mask0, mask1, pend0, pend1; |
| 134 | 134 | ||
| 135 | if (slice == 0) { /* Slice A */ | 135 | if (slice == 0) { /* Slice A */ |
| 136 | mask0 = REMOTE_HUB_L(nasid, PI_INT_MASK0_A); | 136 | mask0 = REMOTE_HUB_L(nasid, PI_INT_MASK0_A); |
| @@ -143,9 +143,9 @@ void nmi_dump_hub_irq(nasid_t nasid, int slice) | |||
| 143 | pend0 = REMOTE_HUB_L(nasid, PI_INT_PEND0); | 143 | pend0 = REMOTE_HUB_L(nasid, PI_INT_PEND0); |
| 144 | pend1 = REMOTE_HUB_L(nasid, PI_INT_PEND1); | 144 | pend1 = REMOTE_HUB_L(nasid, PI_INT_PEND1); |
| 145 | 145 | ||
| 146 | printk("PI_INT_MASK0: %16Lx PI_INT_MASK1: %16Lx\n", mask0, mask1); | 146 | pr_emerg("PI_INT_MASK0: %16llx PI_INT_MASK1: %16llx\n", mask0, mask1); |
| 147 | printk("PI_INT_PEND0: %16Lx PI_INT_PEND1: %16Lx\n", pend0, pend1); | 147 | pr_emerg("PI_INT_PEND0: %16llx PI_INT_PEND1: %16llx\n", pend0, pend1); |
| 148 | printk("\n\n"); | 148 | pr_emerg("\n\n"); |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | /* | 151 | /* |
diff --git a/arch/mips/sgi-ip27/ip27-smp.c b/arch/mips/sgi-ip27/ip27-smp.c index 545446dfe7fa..20b81209c6b8 100644 --- a/arch/mips/sgi-ip27/ip27-smp.c +++ b/arch/mips/sgi-ip27/ip27-smp.c | |||
| @@ -177,7 +177,7 @@ static void ip27_send_ipi_mask(const struct cpumask *mask, unsigned int action) | |||
| 177 | ip27_send_ipi_single(i, action); | 177 | ip27_send_ipi_single(i, action); |
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | static void ip27_init_secondary(void) | 180 | static void ip27_init_cpu(void) |
| 181 | { | 181 | { |
| 182 | per_cpu_init(); | 182 | per_cpu_init(); |
| 183 | } | 183 | } |
| @@ -235,9 +235,10 @@ static void __init ip27_prepare_cpus(unsigned int max_cpus) | |||
| 235 | const struct plat_smp_ops ip27_smp_ops = { | 235 | const struct plat_smp_ops ip27_smp_ops = { |
| 236 | .send_ipi_single = ip27_send_ipi_single, | 236 | .send_ipi_single = ip27_send_ipi_single, |
| 237 | .send_ipi_mask = ip27_send_ipi_mask, | 237 | .send_ipi_mask = ip27_send_ipi_mask, |
| 238 | .init_secondary = ip27_init_secondary, | 238 | .init_secondary = ip27_init_cpu, |
| 239 | .smp_finish = ip27_smp_finish, | 239 | .smp_finish = ip27_smp_finish, |
| 240 | .boot_secondary = ip27_boot_secondary, | 240 | .boot_secondary = ip27_boot_secondary, |
| 241 | .smp_setup = ip27_smp_setup, | 241 | .smp_setup = ip27_smp_setup, |
| 242 | .prepare_cpus = ip27_prepare_cpus, | 242 | .prepare_cpus = ip27_prepare_cpus, |
| 243 | .prepare_boot_cpu = ip27_init_cpu, | ||
| 243 | }; | 244 | }; |
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c index 9d55247533a5..9b4b9ac621a3 100644 --- a/arch/mips/sgi-ip27/ip27-timer.c +++ b/arch/mips/sgi-ip27/ip27-timer.c | |||
| @@ -38,20 +38,6 @@ | |||
| 38 | #include <asm/sn/sn0/hubio.h> | 38 | #include <asm/sn/sn0/hubio.h> |
| 39 | #include <asm/pci/bridge.h> | 39 | #include <asm/pci/bridge.h> |
| 40 | 40 | ||
| 41 | static void enable_rt_irq(struct irq_data *d) | ||
| 42 | { | ||
| 43 | } | ||
| 44 | |||
| 45 | static void disable_rt_irq(struct irq_data *d) | ||
| 46 | { | ||
| 47 | } | ||
| 48 | |||
| 49 | static struct irq_chip rt_irq_type = { | ||
| 50 | .name = "SN HUB RT timer", | ||
| 51 | .irq_mask = disable_rt_irq, | ||
| 52 | .irq_unmask = enable_rt_irq, | ||
| 53 | }; | ||
| 54 | |||
| 55 | static int rt_next_event(unsigned long delta, struct clock_event_device *evt) | 41 | static int rt_next_event(unsigned long delta, struct clock_event_device *evt) |
| 56 | { | 42 | { |
| 57 | unsigned int cpu = smp_processor_id(); | 43 | unsigned int cpu = smp_processor_id(); |
| @@ -65,8 +51,6 @@ static int rt_next_event(unsigned long delta, struct clock_event_device *evt) | |||
| 65 | return LOCAL_HUB_L(PI_RT_COUNT) >= cnt ? -ETIME : 0; | 51 | return LOCAL_HUB_L(PI_RT_COUNT) >= cnt ? -ETIME : 0; |
| 66 | } | 52 | } |
| 67 | 53 | ||
| 68 | unsigned int rt_timer_irq; | ||
| 69 | |||
| 70 | static DEFINE_PER_CPU(struct clock_event_device, hub_rt_clockevent); | 54 | static DEFINE_PER_CPU(struct clock_event_device, hub_rt_clockevent); |
| 71 | static DEFINE_PER_CPU(char [11], hub_rt_name); | 55 | static DEFINE_PER_CPU(char [11], hub_rt_name); |
| 72 | 56 | ||
| @@ -87,6 +71,7 @@ static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id) | |||
| 87 | 71 | ||
| 88 | struct irqaction hub_rt_irqaction = { | 72 | struct irqaction hub_rt_irqaction = { |
| 89 | .handler = hub_rt_counter_handler, | 73 | .handler = hub_rt_counter_handler, |
| 74 | .percpu_dev_id = &hub_rt_clockevent, | ||
| 90 | .flags = IRQF_PERCPU | IRQF_TIMER, | 75 | .flags = IRQF_PERCPU | IRQF_TIMER, |
| 91 | .name = "hub-rt", | 76 | .name = "hub-rt", |
| 92 | }; | 77 | }; |
| @@ -107,7 +92,6 @@ void hub_rt_clock_event_init(void) | |||
| 107 | unsigned int cpu = smp_processor_id(); | 92 | unsigned int cpu = smp_processor_id(); |
| 108 | struct clock_event_device *cd = &per_cpu(hub_rt_clockevent, cpu); | 93 | struct clock_event_device *cd = &per_cpu(hub_rt_clockevent, cpu); |
| 109 | unsigned char *name = per_cpu(hub_rt_name, cpu); | 94 | unsigned char *name = per_cpu(hub_rt_name, cpu); |
| 110 | int irq = rt_timer_irq; | ||
| 111 | 95 | ||
| 112 | sprintf(name, "hub-rt %d", cpu); | 96 | sprintf(name, "hub-rt %d", cpu); |
| 113 | cd->name = name; | 97 | cd->name = name; |
| @@ -118,29 +102,19 @@ void hub_rt_clock_event_init(void) | |||
| 118 | cd->min_delta_ns = clockevent_delta2ns(0x300, cd); | 102 | cd->min_delta_ns = clockevent_delta2ns(0x300, cd); |
| 119 | cd->min_delta_ticks = 0x300; | 103 | cd->min_delta_ticks = 0x300; |
| 120 | cd->rating = 200; | 104 | cd->rating = 200; |
| 121 | cd->irq = irq; | 105 | cd->irq = IP27_RT_TIMER_IRQ; |
| 122 | cd->cpumask = cpumask_of(cpu); | 106 | cd->cpumask = cpumask_of(cpu); |
| 123 | cd->set_next_event = rt_next_event; | 107 | cd->set_next_event = rt_next_event; |
| 124 | clockevents_register_device(cd); | 108 | clockevents_register_device(cd); |
| 109 | |||
| 110 | enable_percpu_irq(IP27_RT_TIMER_IRQ, IRQ_TYPE_NONE); | ||
| 125 | } | 111 | } |
| 126 | 112 | ||
| 127 | static void __init hub_rt_clock_event_global_init(void) | 113 | static void __init hub_rt_clock_event_global_init(void) |
| 128 | { | 114 | { |
| 129 | int irq; | 115 | irq_set_handler(IP27_RT_TIMER_IRQ, handle_percpu_devid_irq); |
| 130 | 116 | irq_set_percpu_devid(IP27_RT_TIMER_IRQ); | |
| 131 | do { | 117 | setup_percpu_irq(IP27_RT_TIMER_IRQ, &hub_rt_irqaction); |
| 132 | smp_wmb(); | ||
| 133 | irq = rt_timer_irq; | ||
| 134 | if (irq) | ||
| 135 | break; | ||
| 136 | |||
| 137 | irq = allocate_irqno(); | ||
| 138 | if (irq < 0) | ||
| 139 | panic("Allocation of irq number for timer failed"); | ||
| 140 | } while (xchg(&rt_timer_irq, irq)); | ||
| 141 | |||
| 142 | irq_set_chip_and_handler(irq, &rt_irq_type, handle_percpu_irq); | ||
| 143 | setup_irq(irq, &hub_rt_irqaction); | ||
| 144 | } | 118 | } |
| 145 | 119 | ||
| 146 | static u64 hub_rt_read(struct clocksource *cs) | 120 | static u64 hub_rt_read(struct clocksource *cs) |
| @@ -194,8 +168,6 @@ void cpu_time_init(void) | |||
| 194 | panic("No information about myself?"); | 168 | panic("No information about myself?"); |
| 195 | 169 | ||
| 196 | printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed); | 170 | printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed); |
| 197 | |||
| 198 | set_c0_status(SRB_TIMOCLK); | ||
| 199 | } | 171 | } |
| 200 | 172 | ||
| 201 | void hub_rtc_init(cnodeid_t cnode) | 173 | void hub_rtc_init(cnodeid_t cnode) |
diff --git a/arch/mips/sgi-ip27/ip27-xtalk.c b/arch/mips/sgi-ip27/ip27-xtalk.c index 4fe5678ba74d..ce06aaa115ae 100644 --- a/arch/mips/sgi-ip27/ip27-xtalk.c +++ b/arch/mips/sgi-ip27/ip27-xtalk.c | |||
| @@ -99,7 +99,7 @@ static int xbow_probe(nasid_t nasid) | |||
| 99 | return 0; | 99 | return 0; |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | void xtalk_probe_node(cnodeid_t nid) | 102 | static void xtalk_probe_node(cnodeid_t nid) |
| 103 | { | 103 | { |
| 104 | volatile u64 hubreg; | 104 | volatile u64 hubreg; |
| 105 | nasid_t nasid; | 105 | nasid_t nasid; |
| @@ -133,3 +133,14 @@ void xtalk_probe_node(cnodeid_t nid) | |||
| 133 | break; | 133 | break; |
| 134 | } | 134 | } |
| 135 | } | 135 | } |
| 136 | |||
| 137 | static int __init xtalk_init(void) | ||
| 138 | { | ||
| 139 | cnodeid_t cnode; | ||
| 140 | |||
| 141 | for_each_online_node(cnode) | ||
| 142 | xtalk_probe_node(cnode); | ||
| 143 | |||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | arch_initcall(xtalk_init); | ||
diff --git a/drivers/soc/lantiq/Makefile b/drivers/soc/lantiq/Makefile index be9e866d53e5..35aa86bd1023 100644 --- a/drivers/soc/lantiq/Makefile +++ b/drivers/soc/lantiq/Makefile | |||
| @@ -1,2 +1 @@ | |||
| 1 | obj-y += fpi-bus.o | obj-y += fpi-bus.o | |
| 2 | obj-$(CONFIG_XRX200_PHY_FW) += gphy.o | ||
diff --git a/drivers/soc/lantiq/gphy.c b/drivers/soc/lantiq/gphy.c deleted file mode 100644 index feeb17cebc25..000000000000 --- a/drivers/soc/lantiq/gphy.c +++ /dev/null | |||
| @@ -1,224 +0,0 @@ | |||
| 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@phrozen.org> | ||
| 7 | * Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com> | ||
| 8 | * Copyright (C) 2017 Hauke Mehrtens <hauke@hauke-m.de> | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/clk.h> | ||
| 12 | #include <linux/delay.h> | ||
| 13 | #include <linux/dma-mapping.h> | ||
| 14 | #include <linux/firmware.h> | ||
| 15 | #include <linux/mfd/syscon.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/reboot.h> | ||
| 18 | #include <linux/regmap.h> | ||
| 19 | #include <linux/reset.h> | ||
| 20 | #include <linux/of_device.h> | ||
| 21 | #include <linux/of_platform.h> | ||
| 22 | #include <linux/property.h> | ||
| 23 | #include <dt-bindings/mips/lantiq_rcu_gphy.h> | ||
| 24 | |||
| 25 | #include <lantiq_soc.h> | ||
| 26 | |||
| 27 | #define XRX200_GPHY_FW_ALIGN (16 * 1024) | ||
| 28 | |||
| 29 | struct xway_gphy_priv { | ||
| 30 | struct clk *gphy_clk_gate; | ||
| 31 | struct reset_control *gphy_reset; | ||
| 32 | struct reset_control *gphy_reset2; | ||
| 33 | void __iomem *membase; | ||
| 34 | char *fw_name; | ||
| 35 | }; | ||
| 36 | |||
| 37 | struct xway_gphy_match_data { | ||
| 38 | char *fe_firmware_name; | ||
| 39 | char *ge_firmware_name; | ||
| 40 | }; | ||
| 41 | |||
| 42 | static const struct xway_gphy_match_data xrx200a1x_gphy_data = { | ||
| 43 | .fe_firmware_name = "lantiq/xrx200_phy22f_a14.bin", | ||
| 44 | .ge_firmware_name = "lantiq/xrx200_phy11g_a14.bin", | ||
| 45 | }; | ||
| 46 | |||
| 47 | static const struct xway_gphy_match_data xrx200a2x_gphy_data = { | ||
| 48 | .fe_firmware_name = "lantiq/xrx200_phy22f_a22.bin", | ||
| 49 | .ge_firmware_name = "lantiq/xrx200_phy11g_a22.bin", | ||
| 50 | }; | ||
| 51 | |||
| 52 | static const struct xway_gphy_match_data xrx300_gphy_data = { | ||
| 53 | .fe_firmware_name = "lantiq/xrx300_phy22f_a21.bin", | ||
| 54 | .ge_firmware_name = "lantiq/xrx300_phy11g_a21.bin", | ||
| 55 | }; | ||
| 56 | |||
| 57 | static const struct of_device_id xway_gphy_match[] = { | ||
| 58 | { .compatible = "lantiq,xrx200a1x-gphy", .data = &xrx200a1x_gphy_data }, | ||
| 59 | { .compatible = "lantiq,xrx200a2x-gphy", .data = &xrx200a2x_gphy_data }, | ||
| 60 | { .compatible = "lantiq,xrx300-gphy", .data = &xrx300_gphy_data }, | ||
| 61 | { .compatible = "lantiq,xrx330-gphy", .data = &xrx300_gphy_data }, | ||
| 62 | {}, | ||
| 63 | }; | ||
| 64 | MODULE_DEVICE_TABLE(of, xway_gphy_match); | ||
| 65 | |||
| 66 | static int xway_gphy_load(struct device *dev, struct xway_gphy_priv *priv, | ||
| 67 | dma_addr_t *dev_addr) | ||
| 68 | { | ||
| 69 | const struct firmware *fw; | ||
| 70 | void *fw_addr; | ||
| 71 | dma_addr_t dma_addr; | ||
| 72 | size_t size; | ||
| 73 | int ret; | ||
| 74 | |||
| 75 | ret = request_firmware(&fw, priv->fw_name, dev); | ||
| 76 | if (ret) { | ||
| 77 | dev_err(dev, "failed to load firmware: %s, error: %i\n", | ||
| 78 | priv->fw_name, ret); | ||
| 79 | return ret; | ||
| 80 | } | ||
| 81 | |||
| 82 | /* | ||
| 83 | * GPHY cores need the firmware code in a persistent and contiguous | ||
| 84 | * memory area with a 16 kB boundary aligned start address. | ||
| 85 | */ | ||
| 86 | size = fw->size + XRX200_GPHY_FW_ALIGN; | ||
| 87 | |||
| 88 | fw_addr = dmam_alloc_coherent(dev, size, &dma_addr, GFP_KERNEL); | ||
| 89 | if (fw_addr) { | ||
| 90 | fw_addr = PTR_ALIGN(fw_addr, XRX200_GPHY_FW_ALIGN); | ||
| 91 | *dev_addr = ALIGN(dma_addr, XRX200_GPHY_FW_ALIGN); | ||
| 92 | memcpy(fw_addr, fw->data, fw->size); | ||
| 93 | } else { | ||
| 94 | dev_err(dev, "failed to alloc firmware memory\n"); | ||
| 95 | ret = -ENOMEM; | ||
| 96 | } | ||
| 97 | |||
| 98 | release_firmware(fw); | ||
| 99 | |||
| 100 | return ret; | ||
| 101 | } | ||
| 102 | |||
| 103 | static int xway_gphy_of_probe(struct platform_device *pdev, | ||
| 104 | struct xway_gphy_priv *priv) | ||
| 105 | { | ||
| 106 | struct device *dev = &pdev->dev; | ||
| 107 | const struct xway_gphy_match_data *gphy_fw_name_cfg; | ||
| 108 | u32 gphy_mode; | ||
| 109 | int ret; | ||
| 110 | struct resource *res_gphy; | ||
| 111 | |||
| 112 | gphy_fw_name_cfg = of_device_get_match_data(dev); | ||
| 113 | |||
| 114 | priv->gphy_clk_gate = devm_clk_get(dev, NULL); | ||
| 115 | if (IS_ERR(priv->gphy_clk_gate)) { | ||
| 116 | dev_err(dev, "Failed to lookup gate clock\n"); | ||
| 117 | return PTR_ERR(priv->gphy_clk_gate); | ||
| 118 | } | ||
| 119 | |||
| 120 | res_gphy = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 121 | priv->membase = devm_ioremap_resource(dev, res_gphy); | ||
| 122 | if (IS_ERR(priv->membase)) | ||
| 123 | return PTR_ERR(priv->membase); | ||
| 124 | |||
| 125 | priv->gphy_reset = devm_reset_control_get(dev, "gphy"); | ||
| 126 | if (IS_ERR(priv->gphy_reset)) { | ||
| 127 | if (PTR_ERR(priv->gphy_reset) != -EPROBE_DEFER) | ||
| 128 | dev_err(dev, "Failed to lookup gphy reset\n"); | ||
| 129 | return PTR_ERR(priv->gphy_reset); | ||
| 130 | } | ||
| 131 | |||
| 132 | priv->gphy_reset2 = devm_reset_control_get_optional(dev, "gphy2"); | ||
| 133 | if (IS_ERR(priv->gphy_reset2)) | ||
| 134 | return PTR_ERR(priv->gphy_reset2); | ||
| 135 | |||
| 136 | ret = device_property_read_u32(dev, "lantiq,gphy-mode", &gphy_mode); | ||
| 137 | /* Default to GE mode */ | ||
| 138 | if (ret) | ||
| 139 | gphy_mode = GPHY_MODE_GE; | ||
| 140 | |||
| 141 | switch (gphy_mode) { | ||
| 142 | case GPHY_MODE_FE: | ||
| 143 | priv->fw_name = gphy_fw_name_cfg->fe_firmware_name; | ||
| 144 | break; | ||
| 145 | case GPHY_MODE_GE: | ||
| 146 | priv->fw_name = gphy_fw_name_cfg->ge_firmware_name; | ||
| 147 | break; | ||
| 148 | default: | ||
| 149 | dev_err(dev, "Unknown GPHY mode %d\n", gphy_mode); | ||
| 150 | return -EINVAL; | ||
| 151 | } | ||
| 152 | |||
| 153 | return 0; | ||
| 154 | } | ||
| 155 | |||
| 156 | static int xway_gphy_probe(struct platform_device *pdev) | ||
| 157 | { | ||
| 158 | struct device *dev = &pdev->dev; | ||
| 159 | struct xway_gphy_priv *priv; | ||
| 160 | dma_addr_t fw_addr = 0; | ||
| 161 | int ret; | ||
| 162 | |||
| 163 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
| 164 | if (!priv) | ||
| 165 | return -ENOMEM; | ||
| 166 | |||
| 167 | ret = xway_gphy_of_probe(pdev, priv); | ||
| 168 | if (ret) | ||
| 169 | return ret; | ||
| 170 | |||
| 171 | ret = clk_prepare_enable(priv->gphy_clk_gate); | ||
| 172 | if (ret) | ||
| 173 | return ret; | ||
| 174 | |||
| 175 | ret = xway_gphy_load(dev, priv, &fw_addr); | ||
| 176 | if (ret) { | ||
| 177 | clk_disable_unprepare(priv->gphy_clk_gate); | ||
| 178 | return ret; | ||
| 179 | } | ||
| 180 | |||
| 181 | reset_control_assert(priv->gphy_reset); | ||
| 182 | reset_control_assert(priv->gphy_reset2); | ||
| 183 | |||
| 184 | iowrite32be(fw_addr, priv->membase); | ||
| 185 | |||
| 186 | reset_control_deassert(priv->gphy_reset); | ||
| 187 | reset_control_deassert(priv->gphy_reset2); | ||
| 188 | |||
| 189 | platform_set_drvdata(pdev, priv); | ||
| 190 | |||
| 191 | return ret; | ||
| 192 | } | ||
| 193 | |||
| 194 | static int xway_gphy_remove(struct platform_device *pdev) | ||
| 195 | { | ||
| 196 | struct xway_gphy_priv *priv = platform_get_drvdata(pdev); | ||
| 197 | |||
| 198 | iowrite32be(0, priv->membase); | ||
| 199 | |||
| 200 | clk_disable_unprepare(priv->gphy_clk_gate); | ||
| 201 | |||
| 202 | return 0; | ||
| 203 | } | ||
| 204 | |||
| 205 | static struct platform_driver xway_gphy_driver = { | ||
| 206 | .probe = xway_gphy_probe, | ||
| 207 | .remove = xway_gphy_remove, | ||
| 208 | .driver = { | ||
| 209 | .name = "xway-rcu-gphy", | ||
| 210 | .of_match_table = xway_gphy_match, | ||
| 211 | }, | ||
| 212 | }; | ||
| 213 | |||
| 214 | module_platform_driver(xway_gphy_driver); | ||
| 215 | |||
| 216 | MODULE_FIRMWARE("lantiq/xrx300_phy11g_a21.bin"); | ||
| 217 | MODULE_FIRMWARE("lantiq/xrx300_phy22f_a21.bin"); | ||
| 218 | MODULE_FIRMWARE("lantiq/xrx200_phy11g_a14.bin"); | ||
| 219 | MODULE_FIRMWARE("lantiq/xrx200_phy11g_a22.bin"); | ||
| 220 | MODULE_FIRMWARE("lantiq/xrx200_phy22f_a14.bin"); | ||
| 221 | MODULE_FIRMWARE("lantiq/xrx200_phy22f_a22.bin"); | ||
| 222 | MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>"); | ||
| 223 | MODULE_DESCRIPTION("Lantiq XWAY GPHY Firmware Loader"); | ||
| 224 | MODULE_LICENSE("GPL"); | ||
diff --git a/include/dt-bindings/clock/ath79-clk.h b/include/dt-bindings/clock/ath79-clk.h index 27359ad83904..dcc679a7ad85 100644 --- a/include/dt-bindings/clock/ath79-clk.h +++ b/include/dt-bindings/clock/ath79-clk.h | |||
| @@ -13,7 +13,9 @@ | |||
| 13 | #define ATH79_CLK_CPU 0 | 13 | #define ATH79_CLK_CPU 0 |
| 14 | #define ATH79_CLK_DDR 1 | 14 | #define ATH79_CLK_DDR 1 |
| 15 | #define ATH79_CLK_AHB 2 | 15 | #define ATH79_CLK_AHB 2 |
| 16 | #define ATH79_CLK_REF 3 | ||
| 17 | #define ATH79_CLK_MDIO 4 | ||
| 16 | 18 | ||
| 17 | #define ATH79_CLK_END 3 | 19 | #define ATH79_CLK_END 5 |
| 18 | 20 | ||
| 19 | #endif /* __DT_BINDINGS_ATH79_CLK_H */ | 21 | #endif /* __DT_BINDINGS_ATH79_CLK_H */ |
