diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-11 20:56:37 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-11 20:56:37 -0500 |
commit | c0222ac086669a631814bbf857f8c8023452a4d7 (patch) | |
tree | bb1d9908031fcf69016eeefa7b35a4f68f414333 /arch/mips | |
parent | 140cd7fb04a4a2bc09a30980bc8104cc89e09330 (diff) | |
parent | e2965cd0003f222bd49f67907c2bc6ed691c6d20 (diff) |
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS updates from Ralf Baechle:
"This is an unusually large pull request for MIPS - in parts because
lots of patches missed the 3.18 deadline but primarily because some
folks opened the flood gates.
- Retire the MIPS-specific phys_t with the generic phys_addr_t.
- Improvments for the backtrace code used by oprofile.
- Better backtraces on SMP systems.
- Cleanups for the Octeon platform code.
- Cleanups and fixes for the Loongson platform code.
- Cleanups and fixes to the firmware library.
- Switch ATH79 platform to use the firmware library.
- Grand overhault to the SEAD3 and Malta interrupt code.
- Move the GIC interrupt code to drivers/irqchip
- Lots of GIC cleanups and updates to the GIC code to use modern IRQ
infrastructures and features of the kernel.
- OF documentation updates for the GIC bindings
- Move GIC clocksource driver to drivers/clocksource
- Merge GIC clocksource driver with clockevent driver.
- Further updates to bring the GIC clocksource driver up to date.
- R3000 TLB code cleanups
- Improvments to the Loongson 3 platform code.
- Convert pr_warning to pr_warn.
- Merge a bunch of small lantiq and ralink fixes that have been
staged/lingering inside the openwrt tree for a while.
- Update archhelp for IP22/IP32
- Fix a number of issues for Loongson 1B.
- New clocksource and clockevent driver for Loongson 1B.
- Further work on clk handling for Loongson 1B.
- Platform work for Broadcom BMIPS.
- Error handling cleanups for TurboChannel.
- Fixes and optimization to the microMIPS support.
- Option to disable the FTLB.
- Dump more relevant information on machine check exception
- Change binfmt to allow arch to examine PT_*PROC headers
- Support for new style FPU register model in O32
- VDSO randomization.
- BCM47xx cleanups
- BCM47xx reimplement the way the kernel accesses NVRAM information.
- Random cleanups
- Add support for ATH25 platforms
- Remove pointless locking code in some PCI platforms.
- Some improvments to EVA support
- Minor Alchemy cleanup"
* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (185 commits)
MIPS: Add MFHC0 and MTHC0 instructions to uasm.
MIPS: Cosmetic cleanups of page table headers.
MIPS: Add CP0 macros for extended EntryLo registers
MIPS: Remove now unused definition of phys_t.
MIPS: Replace use of phys_t with phys_addr_t.
MIPS: Replace MIPS-specific 64BIT_PHYS_ADDR with generic PHYS_ADDR_T_64BIT
PCMCIA: Alchemy Don't select 64BIT_PHYS_ADDR in Kconfig.
MIPS: lib: memset: Clean up some MIPS{EL,EB} ifdefery
MIPS: iomap: Use __mem_{read,write}{b,w,l} for MMIO
MIPS: <asm/types.h> fix indentation.
MAINTAINERS: Add entry for BMIPS multiplatform kernel
MIPS: Enable VDSO randomization
MIPS: Remove a temporary hack for debugging cache flushes in SMTC configuration
MIPS: Remove declaration of obsolete arch_init_clk_ops()
MIPS: atomic.h: Reformat to fit in 79 columns
MIPS: Apply `.insn' to fixup labels throughout
MIPS: Fix microMIPS LL/SC immediate offsets
MIPS: Kconfig: Only allow 32-bit microMIPS builds
MIPS: signal.c: Fix an invalid cast in ISA mode bit handling
MIPS: mm: Only build one microassembler that is suitable
...
Diffstat (limited to 'arch/mips')
258 files changed, 8039 insertions, 3505 deletions
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index f5e18bf3275e..e5fc463b36d0 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms | |||
@@ -2,7 +2,9 @@ | |||
2 | 2 | ||
3 | platforms += alchemy | 3 | platforms += alchemy |
4 | platforms += ar7 | 4 | platforms += ar7 |
5 | platforms += ath25 | ||
5 | platforms += ath79 | 6 | platforms += ath79 |
7 | platforms += bcm3384 | ||
6 | platforms += bcm47xx | 8 | platforms += bcm47xx |
7 | platforms += bcm63xx | 9 | platforms += bcm63xx |
8 | platforms += cavium-octeon | 10 | platforms += cavium-octeon |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 9536ef912f59..3289969ee423 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -53,6 +53,7 @@ config MIPS | |||
53 | select HAVE_CC_STACKPROTECTOR | 53 | select HAVE_CC_STACKPROTECTOR |
54 | select CPU_PM if CPU_IDLE | 54 | select CPU_PM if CPU_IDLE |
55 | select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST | 55 | select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST |
56 | select ARCH_BINFMT_ELF_STATE | ||
56 | 57 | ||
57 | menu "Machine selection" | 58 | menu "Machine selection" |
58 | 59 | ||
@@ -62,7 +63,7 @@ choice | |||
62 | 63 | ||
63 | config MIPS_ALCHEMY | 64 | config MIPS_ALCHEMY |
64 | bool "Alchemy processor based machines" | 65 | bool "Alchemy processor based machines" |
65 | select 64BIT_PHYS_ADDR | 66 | select ARCH_PHYS_ADDR_T_64BIT |
66 | select CEVT_R4K | 67 | select CEVT_R4K |
67 | select CSRC_R4K | 68 | select CSRC_R4K |
68 | select IRQ_CPU | 69 | select IRQ_CPU |
@@ -96,6 +97,20 @@ config AR7 | |||
96 | Support for the Texas Instruments AR7 System-on-a-Chip | 97 | Support for the Texas Instruments AR7 System-on-a-Chip |
97 | family: TNETD7100, 7200 and 7300. | 98 | family: TNETD7100, 7200 and 7300. |
98 | 99 | ||
100 | config ATH25 | ||
101 | bool "Atheros AR231x/AR531x SoC support" | ||
102 | select CEVT_R4K | ||
103 | select CSRC_R4K | ||
104 | select DMA_NONCOHERENT | ||
105 | select IRQ_CPU | ||
106 | select IRQ_DOMAIN | ||
107 | select SYS_HAS_CPU_MIPS32_R1 | ||
108 | select SYS_SUPPORTS_BIG_ENDIAN | ||
109 | select SYS_SUPPORTS_32BIT_KERNEL | ||
110 | select SYS_HAS_EARLY_PRINTK | ||
111 | help | ||
112 | Support for Atheros AR231x and Atheros AR531x based boards | ||
113 | |||
99 | config ATH79 | 114 | config ATH79 |
100 | bool "Atheros AR71XX/AR724X/AR913X based boards" | 115 | bool "Atheros AR71XX/AR724X/AR913X based boards" |
101 | select ARCH_REQUIRE_GPIOLIB | 116 | select ARCH_REQUIRE_GPIOLIB |
@@ -115,6 +130,32 @@ config ATH79 | |||
115 | help | 130 | help |
116 | Support for the Atheros AR71XX/AR724X/AR913X SoCs. | 131 | Support for the Atheros AR71XX/AR724X/AR913X SoCs. |
117 | 132 | ||
133 | config BCM3384 | ||
134 | bool "Broadcom BCM3384 based boards" | ||
135 | select BOOT_RAW | ||
136 | select NO_EXCEPT_FILL | ||
137 | select USE_OF | ||
138 | select CEVT_R4K | ||
139 | select CSRC_R4K | ||
140 | select SYNC_R4K | ||
141 | select COMMON_CLK | ||
142 | select DMA_NONCOHERENT | ||
143 | select IRQ_CPU | ||
144 | select SYS_SUPPORTS_32BIT_KERNEL | ||
145 | select SYS_SUPPORTS_BIG_ENDIAN | ||
146 | select SYS_SUPPORTS_HIGHMEM | ||
147 | select SYS_HAS_CPU_BMIPS5000 | ||
148 | select SWAP_IO_SPACE | ||
149 | select USB_EHCI_BIG_ENDIAN_DESC | ||
150 | select USB_EHCI_BIG_ENDIAN_MMIO | ||
151 | select USB_OHCI_BIG_ENDIAN_DESC | ||
152 | select USB_OHCI_BIG_ENDIAN_MMIO | ||
153 | help | ||
154 | Support for BCM3384 based boards. BCM3384/BCM33843 is a cable modem | ||
155 | chipset with a Linux application processor that is often used to | ||
156 | provide Samba services, a CUPS print server, and/or advanced routing | ||
157 | features. | ||
158 | |||
118 | config BCM47XX | 159 | config BCM47XX |
119 | bool "Broadcom BCM47XX based boards" | 160 | bool "Broadcom BCM47XX based boards" |
120 | select ARCH_WANT_OPTIONAL_GPIOLIB | 161 | select ARCH_WANT_OPTIONAL_GPIOLIB |
@@ -269,6 +310,8 @@ config LANTIQ | |||
269 | select USE_OF | 310 | select USE_OF |
270 | select PINCTRL | 311 | select PINCTRL |
271 | select PINCTRL_LANTIQ | 312 | select PINCTRL_LANTIQ |
313 | select ARCH_HAS_RESET_CONTROLLER | ||
314 | select RESET_CONTROLLER | ||
272 | 315 | ||
273 | config LASAT | 316 | config LASAT |
274 | bool "LASAT Networks platforms" | 317 | bool "LASAT Networks platforms" |
@@ -315,17 +358,18 @@ config MIPS_MALTA | |||
315 | select BOOT_RAW | 358 | select BOOT_RAW |
316 | select CEVT_R4K | 359 | select CEVT_R4K |
317 | select CSRC_R4K | 360 | select CSRC_R4K |
318 | select CSRC_GIC | 361 | select CLKSRC_MIPS_GIC |
319 | select DMA_MAYBE_COHERENT | 362 | select DMA_MAYBE_COHERENT |
320 | select GENERIC_ISA_DMA | 363 | select GENERIC_ISA_DMA |
321 | select HAVE_PCSPKR_PLATFORM | 364 | select HAVE_PCSPKR_PLATFORM |
322 | select IRQ_CPU | 365 | select IRQ_CPU |
323 | select IRQ_GIC | 366 | select MIPS_GIC |
324 | select HW_HAS_PCI | 367 | select HW_HAS_PCI |
325 | select I8253 | 368 | select I8253 |
326 | select I8259 | 369 | select I8259 |
327 | select MIPS_BONITO64 | 370 | select MIPS_BONITO64 |
328 | select MIPS_CPU_SCACHE | 371 | select MIPS_CPU_SCACHE |
372 | select MIPS_L1_CACHE_SHIFT_6 | ||
329 | select PCI_GT64XXX_PCI0 | 373 | select PCI_GT64XXX_PCI0 |
330 | select MIPS_MSC | 374 | select MIPS_MSC |
331 | select SWAP_IO_SPACE | 375 | select SWAP_IO_SPACE |
@@ -340,6 +384,7 @@ config MIPS_MALTA | |||
340 | select SYS_SUPPORTS_64BIT_KERNEL | 384 | select SYS_SUPPORTS_64BIT_KERNEL |
341 | select SYS_SUPPORTS_BIG_ENDIAN | 385 | select SYS_SUPPORTS_BIG_ENDIAN |
342 | select SYS_SUPPORTS_LITTLE_ENDIAN | 386 | select SYS_SUPPORTS_LITTLE_ENDIAN |
387 | select SYS_SUPPORTS_MICROMIPS | ||
343 | select SYS_SUPPORTS_MIPS_CMP | 388 | select SYS_SUPPORTS_MIPS_CMP |
344 | select SYS_SUPPORTS_MIPS_CPS | 389 | select SYS_SUPPORTS_MIPS_CPS |
345 | select SYS_SUPPORTS_MIPS16 | 390 | select SYS_SUPPORTS_MIPS16 |
@@ -357,12 +402,12 @@ config MIPS_SEAD3 | |||
357 | select BUILTIN_DTB | 402 | select BUILTIN_DTB |
358 | select CEVT_R4K | 403 | select CEVT_R4K |
359 | select CSRC_R4K | 404 | select CSRC_R4K |
360 | select CSRC_GIC | 405 | select CLKSRC_MIPS_GIC |
361 | select CPU_MIPSR2_IRQ_VI | 406 | select CPU_MIPSR2_IRQ_VI |
362 | select CPU_MIPSR2_IRQ_EI | 407 | select CPU_MIPSR2_IRQ_EI |
363 | select DMA_NONCOHERENT | 408 | select DMA_NONCOHERENT |
364 | select IRQ_CPU | 409 | select IRQ_CPU |
365 | select IRQ_GIC | 410 | select MIPS_GIC |
366 | select LIBFDT | 411 | select LIBFDT |
367 | select MIPS_MSC | 412 | select MIPS_MSC |
368 | select SYS_HAS_CPU_MIPS32_R1 | 413 | select SYS_HAS_CPU_MIPS32_R1 |
@@ -726,7 +771,7 @@ config MIKROTIK_RB532 | |||
726 | config CAVIUM_OCTEON_SOC | 771 | config CAVIUM_OCTEON_SOC |
727 | bool "Cavium Networks Octeon SoC based boards" | 772 | bool "Cavium Networks Octeon SoC based boards" |
728 | select CEVT_R4K | 773 | select CEVT_R4K |
729 | select 64BIT_PHYS_ADDR | 774 | select ARCH_PHYS_ADDR_T_64BIT |
730 | select DMA_COHERENT | 775 | select DMA_COHERENT |
731 | select SYS_SUPPORTS_64BIT_KERNEL | 776 | select SYS_SUPPORTS_64BIT_KERNEL |
732 | select SYS_SUPPORTS_BIG_ENDIAN | 777 | select SYS_SUPPORTS_BIG_ENDIAN |
@@ -768,7 +813,7 @@ config NLM_XLR_BOARD | |||
768 | select SWAP_IO_SPACE | 813 | select SWAP_IO_SPACE |
769 | select SYS_SUPPORTS_32BIT_KERNEL | 814 | select SYS_SUPPORTS_32BIT_KERNEL |
770 | select SYS_SUPPORTS_64BIT_KERNEL | 815 | select SYS_SUPPORTS_64BIT_KERNEL |
771 | select 64BIT_PHYS_ADDR | 816 | select ARCH_PHYS_ADDR_T_64BIT |
772 | select SYS_SUPPORTS_BIG_ENDIAN | 817 | select SYS_SUPPORTS_BIG_ENDIAN |
773 | select SYS_SUPPORTS_HIGHMEM | 818 | select SYS_SUPPORTS_HIGHMEM |
774 | select DMA_COHERENT | 819 | select DMA_COHERENT |
@@ -794,7 +839,7 @@ config NLM_XLP_BOARD | |||
794 | select HW_HAS_PCI | 839 | select HW_HAS_PCI |
795 | select SYS_SUPPORTS_32BIT_KERNEL | 840 | select SYS_SUPPORTS_32BIT_KERNEL |
796 | select SYS_SUPPORTS_64BIT_KERNEL | 841 | select SYS_SUPPORTS_64BIT_KERNEL |
797 | select 64BIT_PHYS_ADDR | 842 | select ARCH_PHYS_ADDR_T_64BIT |
798 | select SYS_SUPPORTS_BIG_ENDIAN | 843 | select SYS_SUPPORTS_BIG_ENDIAN |
799 | select SYS_SUPPORTS_LITTLE_ENDIAN | 844 | select SYS_SUPPORTS_LITTLE_ENDIAN |
800 | select SYS_SUPPORTS_HIGHMEM | 845 | select SYS_SUPPORTS_HIGHMEM |
@@ -835,6 +880,7 @@ config MIPS_PARAVIRT | |||
835 | endchoice | 880 | endchoice |
836 | 881 | ||
837 | source "arch/mips/alchemy/Kconfig" | 882 | source "arch/mips/alchemy/Kconfig" |
883 | source "arch/mips/ath25/Kconfig" | ||
838 | source "arch/mips/ath79/Kconfig" | 884 | source "arch/mips/ath79/Kconfig" |
839 | source "arch/mips/bcm47xx/Kconfig" | 885 | source "arch/mips/bcm47xx/Kconfig" |
840 | source "arch/mips/bcm63xx/Kconfig" | 886 | source "arch/mips/bcm63xx/Kconfig" |
@@ -907,10 +953,6 @@ config CEVT_GT641XX | |||
907 | config CEVT_R4K | 953 | config CEVT_R4K |
908 | bool | 954 | bool |
909 | 955 | ||
910 | config CEVT_GIC | ||
911 | select MIPS_CM | ||
912 | bool | ||
913 | |||
914 | config CEVT_SB1250 | 956 | config CEVT_SB1250 |
915 | bool | 957 | bool |
916 | 958 | ||
@@ -926,10 +968,6 @@ config CSRC_IOASIC | |||
926 | config CSRC_R4K | 968 | config CSRC_R4K |
927 | bool | 969 | bool |
928 | 970 | ||
929 | config CSRC_GIC | ||
930 | select MIPS_CM | ||
931 | bool | ||
932 | |||
933 | config CSRC_SB1250 | 971 | config CSRC_SB1250 |
934 | bool | 972 | bool |
935 | 973 | ||
@@ -941,7 +979,7 @@ config FW_CFE | |||
941 | bool | 979 | bool |
942 | 980 | ||
943 | config ARCH_DMA_ADDR_T_64BIT | 981 | config ARCH_DMA_ADDR_T_64BIT |
944 | def_bool (HIGHMEM && 64BIT_PHYS_ADDR) || 64BIT | 982 | def_bool (HIGHMEM && ARCH_PHYS_ADDR_T_64BIT) || 64BIT |
945 | 983 | ||
946 | config DMA_MAYBE_COHERENT | 984 | config DMA_MAYBE_COHERENT |
947 | select DMA_NONCOHERENT | 985 | select DMA_NONCOHERENT |
@@ -975,6 +1013,7 @@ config SYS_SUPPORTS_HOTPLUG_CPU | |||
975 | 1013 | ||
976 | config I8259 | 1014 | config I8259 |
977 | bool | 1015 | bool |
1016 | select IRQ_DOMAIN | ||
978 | 1017 | ||
979 | config MIPS_BONITO64 | 1018 | config MIPS_BONITO64 |
980 | bool | 1019 | bool |
@@ -1055,6 +1094,7 @@ config MIPS_HUGE_TLB_SUPPORT | |||
1055 | 1094 | ||
1056 | config IRQ_CPU | 1095 | config IRQ_CPU |
1057 | bool | 1096 | bool |
1097 | select IRQ_DOMAIN | ||
1058 | 1098 | ||
1059 | config IRQ_CPU_RM7K | 1099 | config IRQ_CPU_RM7K |
1060 | bool | 1100 | bool |
@@ -1071,10 +1111,6 @@ config IRQ_TXX9 | |||
1071 | config IRQ_GT641XX | 1111 | config IRQ_GT641XX |
1072 | bool | 1112 | bool |
1073 | 1113 | ||
1074 | config IRQ_GIC | ||
1075 | select MIPS_CM | ||
1076 | bool | ||
1077 | |||
1078 | config PCI_GT64XXX_PCI0 | 1114 | config PCI_GT64XXX_PCI0 |
1079 | bool | 1115 | bool |
1080 | 1116 | ||
@@ -1574,6 +1610,7 @@ config CPU_LOONGSON1 | |||
1574 | select CPU_HAS_PREFETCH | 1610 | select CPU_HAS_PREFETCH |
1575 | select CPU_SUPPORTS_32BIT_KERNEL | 1611 | select CPU_SUPPORTS_32BIT_KERNEL |
1576 | select CPU_SUPPORTS_HIGHMEM | 1612 | select CPU_SUPPORTS_HIGHMEM |
1613 | select CPU_SUPPORTS_CPUFREQ | ||
1577 | 1614 | ||
1578 | config CPU_BMIPS32_3300 | 1615 | config CPU_BMIPS32_3300 |
1579 | select SMP_UP if SMP | 1616 | select SMP_UP if SMP |
@@ -1586,12 +1623,14 @@ config CPU_BMIPS4350 | |||
1586 | 1623 | ||
1587 | config CPU_BMIPS4380 | 1624 | config CPU_BMIPS4380 |
1588 | bool | 1625 | bool |
1626 | select MIPS_L1_CACHE_SHIFT_6 | ||
1589 | select SYS_SUPPORTS_SMP | 1627 | select SYS_SUPPORTS_SMP |
1590 | select SYS_SUPPORTS_HOTPLUG_CPU | 1628 | select SYS_SUPPORTS_HOTPLUG_CPU |
1591 | 1629 | ||
1592 | config CPU_BMIPS5000 | 1630 | config CPU_BMIPS5000 |
1593 | bool | 1631 | bool |
1594 | select MIPS_CPU_SCACHE | 1632 | select MIPS_CPU_SCACHE |
1633 | select MIPS_L1_CACHE_SHIFT_7 | ||
1595 | select SYS_SUPPORTS_SMP | 1634 | select SYS_SUPPORTS_SMP |
1596 | select SYS_SUPPORTS_HOTPLUG_CPU | 1635 | select SYS_SUPPORTS_HOTPLUG_CPU |
1597 | 1636 | ||
@@ -1886,15 +1925,6 @@ config FORCE_MAX_ZONEORDER | |||
1886 | The page size is not necessarily 4KB. Keep this in mind | 1925 | The page size is not necessarily 4KB. Keep this in mind |
1887 | when choosing a value for this option. | 1926 | when choosing a value for this option. |
1888 | 1927 | ||
1889 | config CEVT_GIC | ||
1890 | bool "Use GIC global counter for clock events" | ||
1891 | depends on IRQ_GIC && !MIPS_SEAD3 | ||
1892 | help | ||
1893 | Use the GIC global counter for the clock events. The R4K clock | ||
1894 | event driver is always present, so if the platform ends up not | ||
1895 | detecting a GIC, it will fall back to the R4K timer for the | ||
1896 | generation of clock events. | ||
1897 | |||
1898 | config BOARD_SCACHE | 1928 | config BOARD_SCACHE |
1899 | bool | 1929 | bool |
1900 | 1930 | ||
@@ -1908,7 +1938,6 @@ config IP22_CPU_SCACHE | |||
1908 | config MIPS_CPU_SCACHE | 1938 | config MIPS_CPU_SCACHE |
1909 | bool | 1939 | bool |
1910 | select BOARD_SCACHE | 1940 | select BOARD_SCACHE |
1911 | select MIPS_L1_CACHE_SHIFT_6 | ||
1912 | 1941 | ||
1913 | config R5000_CPU_SCACHE | 1942 | config R5000_CPU_SCACHE |
1914 | bool | 1943 | bool |
@@ -2095,11 +2124,8 @@ config SB1_PASS_2_1_WORKAROUNDS | |||
2095 | default y | 2124 | default y |
2096 | 2125 | ||
2097 | 2126 | ||
2098 | config 64BIT_PHYS_ADDR | ||
2099 | bool | ||
2100 | |||
2101 | config ARCH_PHYS_ADDR_T_64BIT | 2127 | config ARCH_PHYS_ADDR_T_64BIT |
2102 | def_bool 64BIT_PHYS_ADDR | 2128 | bool |
2103 | 2129 | ||
2104 | choice | 2130 | choice |
2105 | prompt "SmartMIPS or microMIPS ASE support" | 2131 | prompt "SmartMIPS or microMIPS ASE support" |
@@ -2122,7 +2148,7 @@ config CPU_HAS_SMARTMIPS | |||
2122 | here. | 2148 | here. |
2123 | 2149 | ||
2124 | config CPU_MICROMIPS | 2150 | config CPU_MICROMIPS |
2125 | depends on SYS_SUPPORTS_MICROMIPS | 2151 | depends on 32BIT && SYS_SUPPORTS_MICROMIPS |
2126 | bool "microMIPS" | 2152 | bool "microMIPS" |
2127 | help | 2153 | help |
2128 | When this option is enabled the kernel will be built using the | 2154 | When this option is enabled the kernel will be built using the |
diff --git a/arch/mips/Kconfig.debug b/arch/mips/Kconfig.debug index 3a2b775e8458..88a9f433f6fc 100644 --- a/arch/mips/Kconfig.debug +++ b/arch/mips/Kconfig.debug | |||
@@ -122,4 +122,17 @@ config SPINLOCK_TEST | |||
122 | help | 122 | help |
123 | Add several files to the debugfs to test spinlock speed. | 123 | Add several files to the debugfs to test spinlock speed. |
124 | 124 | ||
125 | config FP32XX_HYBRID_FPRS | ||
126 | bool "Run FP32 & FPXX code with hybrid FPRs" | ||
127 | depends on MIPS_O32_FP64_SUPPORT | ||
128 | help | ||
129 | The hybrid FPR scheme is normally used only when a program needs to | ||
130 | execute a mix of FP32 & FP64A code, since the trapping & emulation | ||
131 | that it entails is expensive. When enabled, this option will lead | ||
132 | to the kernel running programs which use the FP32 & FPXX FP ABIs | ||
133 | using the hybrid FPR scheme, which can be useful for debugging | ||
134 | purposes. | ||
135 | |||
136 | If unsure, say N. | ||
137 | |||
125 | endmenu | 138 | endmenu |
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 58076472bdd8..2563a088d3b8 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
@@ -380,6 +380,7 @@ define archhelp | |||
380 | echo ' vmlinux.ecoff - ECOFF boot image' | 380 | echo ' vmlinux.ecoff - ECOFF boot image' |
381 | echo ' vmlinux.bin - Raw binary boot image' | 381 | echo ' vmlinux.bin - Raw binary boot image' |
382 | echo ' vmlinux.srec - SREC boot image' | 382 | echo ' vmlinux.srec - SREC boot image' |
383 | echo ' vmlinux.32 - 64-bit boot image wrapped in 32bits (IP22/IP32)' | ||
383 | echo ' vmlinuz - Compressed boot(zboot) image' | 384 | echo ' vmlinuz - Compressed boot(zboot) image' |
384 | echo ' vmlinuz.ecoff - ECOFF zboot image' | 385 | echo ' vmlinuz.ecoff - ECOFF zboot image' |
385 | echo ' vmlinuz.bin - Raw binary zboot image' | 386 | echo ' vmlinuz.bin - Raw binary zboot image' |
diff --git a/arch/mips/alchemy/common/clock.c b/arch/mips/alchemy/common/clock.c index d7557cde271a..203e4403c366 100644 --- a/arch/mips/alchemy/common/clock.c +++ b/arch/mips/alchemy/common/clock.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include <linux/io.h> | 37 | #include <linux/io.h> |
38 | #include <linux/clk-provider.h> | 38 | #include <linux/clk-provider.h> |
39 | #include <linux/clkdev.h> | 39 | #include <linux/clkdev.h> |
40 | #include <linux/clk-private.h> | ||
41 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
42 | #include <linux/spinlock.h> | 41 | #include <linux/spinlock.h> |
43 | #include <linux/types.h> | 42 | #include <linux/types.h> |
@@ -397,10 +396,10 @@ static long alchemy_clk_fgcs_detr(struct clk_hw *hw, unsigned long rate, | |||
397 | break; | 396 | break; |
398 | 397 | ||
399 | /* if this parent is currently unused, remember it. | 398 | /* if this parent is currently unused, remember it. |
400 | * XXX: I know it's a layering violation, but it works | 399 | * XXX: we would actually want clk_has_active_children() |
401 | * so well.. (if (!clk_has_active_children(pc)) ) | 400 | * but this is a good-enough approximation for now. |
402 | */ | 401 | */ |
403 | if (pc->prepare_count == 0) { | 402 | if (!__clk_is_prepared(pc)) { |
404 | if (!free) | 403 | if (!free) |
405 | free = pc; | 404 | free = pc; |
406 | } | 405 | } |
diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c index ea8f41869e56..4e72daf12c32 100644 --- a/arch/mips/alchemy/common/setup.c +++ b/arch/mips/alchemy/common/setup.c | |||
@@ -70,9 +70,9 @@ void __init plat_mem_setup(void) | |||
70 | iomem_resource.end = IOMEM_RESOURCE_END; | 70 | iomem_resource.end = IOMEM_RESOURCE_END; |
71 | } | 71 | } |
72 | 72 | ||
73 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_PCI) | 73 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_PCI) |
74 | /* This routine should be valid for all Au1x based boards */ | 74 | /* This routine should be valid for all Au1x based boards */ |
75 | phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) | 75 | phys_addr_t __fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) |
76 | { | 76 | { |
77 | unsigned long start = ALCHEMY_PCI_MEMWIN_START; | 77 | unsigned long start = ALCHEMY_PCI_MEMWIN_START; |
78 | unsigned long end = ALCHEMY_PCI_MEMWIN_END; | 78 | unsigned long end = ALCHEMY_PCI_MEMWIN_END; |
@@ -83,7 +83,7 @@ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) | |||
83 | 83 | ||
84 | /* Check for PCI memory window */ | 84 | /* Check for PCI memory window */ |
85 | if (phys_addr >= start && (phys_addr + size - 1) <= end) | 85 | if (phys_addr >= start && (phys_addr + size - 1) <= end) |
86 | return (phys_t)(AU1500_PCI_MEM_PHYS_ADDR + phys_addr); | 86 | return (phys_addr_t)(AU1500_PCI_MEM_PHYS_ADDR + phys_addr); |
87 | 87 | ||
88 | /* default nop */ | 88 | /* default nop */ |
89 | return phys_addr; | 89 | return phys_addr; |
diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c index 7e2356fd5fd6..af2441dbfc12 100644 --- a/arch/mips/ar7/platform.c +++ b/arch/mips/ar7/platform.c | |||
@@ -311,8 +311,7 @@ static void __init cpmac_get_mac(int instance, unsigned char *dev_addr) | |||
311 | &dev_addr[0], &dev_addr[1], | 311 | &dev_addr[0], &dev_addr[1], |
312 | &dev_addr[2], &dev_addr[3], | 312 | &dev_addr[2], &dev_addr[3], |
313 | &dev_addr[4], &dev_addr[5]) != 6) { | 313 | &dev_addr[4], &dev_addr[5]) != 6) { |
314 | pr_warning("cannot parse mac address, " | 314 | pr_warn("cannot parse mac address, using random address\n"); |
315 | "using random address\n"); | ||
316 | eth_random_addr(dev_addr); | 315 | eth_random_addr(dev_addr); |
317 | } | 316 | } |
318 | } else | 317 | } else |
@@ -665,7 +664,7 @@ static int __init ar7_register_devices(void) | |||
665 | 664 | ||
666 | res = platform_device_register(&physmap_flash); | 665 | res = platform_device_register(&physmap_flash); |
667 | if (res) | 666 | if (res) |
668 | pr_warning("unable to register physmap-flash: %d\n", res); | 667 | pr_warn("unable to register physmap-flash: %d\n", res); |
669 | 668 | ||
670 | if (ar7_is_titan()) | 669 | if (ar7_is_titan()) |
671 | titan_fixup_devices(); | 670 | titan_fixup_devices(); |
@@ -673,13 +672,13 @@ static int __init ar7_register_devices(void) | |||
673 | ar7_device_disable(vlynq_low_data.reset_bit); | 672 | ar7_device_disable(vlynq_low_data.reset_bit); |
674 | res = platform_device_register(&vlynq_low); | 673 | res = platform_device_register(&vlynq_low); |
675 | if (res) | 674 | if (res) |
676 | pr_warning("unable to register vlynq-low: %d\n", res); | 675 | pr_warn("unable to register vlynq-low: %d\n", res); |
677 | 676 | ||
678 | if (ar7_has_high_vlynq()) { | 677 | if (ar7_has_high_vlynq()) { |
679 | ar7_device_disable(vlynq_high_data.reset_bit); | 678 | ar7_device_disable(vlynq_high_data.reset_bit); |
680 | res = platform_device_register(&vlynq_high); | 679 | res = platform_device_register(&vlynq_high); |
681 | if (res) | 680 | if (res) |
682 | pr_warning("unable to register vlynq-high: %d\n", res); | 681 | pr_warn("unable to register vlynq-high: %d\n", res); |
683 | } | 682 | } |
684 | 683 | ||
685 | if (ar7_has_high_cpmac()) { | 684 | if (ar7_has_high_cpmac()) { |
@@ -689,9 +688,10 @@ static int __init ar7_register_devices(void) | |||
689 | 688 | ||
690 | res = platform_device_register(&cpmac_high); | 689 | res = platform_device_register(&cpmac_high); |
691 | if (res) | 690 | if (res) |
692 | pr_warning("unable to register cpmac-high: %d\n", res); | 691 | pr_warn("unable to register cpmac-high: %d\n", |
692 | res); | ||
693 | } else | 693 | } else |
694 | pr_warning("unable to add cpmac-high phy: %d\n", res); | 694 | pr_warn("unable to add cpmac-high phy: %d\n", res); |
695 | } else | 695 | } else |
696 | cpmac_low_data.phy_mask = 0xffffffff; | 696 | cpmac_low_data.phy_mask = 0xffffffff; |
697 | 697 | ||
@@ -700,18 +700,18 @@ static int __init ar7_register_devices(void) | |||
700 | cpmac_get_mac(0, cpmac_low_data.dev_addr); | 700 | cpmac_get_mac(0, cpmac_low_data.dev_addr); |
701 | res = platform_device_register(&cpmac_low); | 701 | res = platform_device_register(&cpmac_low); |
702 | if (res) | 702 | if (res) |
703 | pr_warning("unable to register cpmac-low: %d\n", res); | 703 | pr_warn("unable to register cpmac-low: %d\n", res); |
704 | } else | 704 | } else |
705 | pr_warning("unable to add cpmac-low phy: %d\n", res); | 705 | pr_warn("unable to add cpmac-low phy: %d\n", res); |
706 | 706 | ||
707 | detect_leds(); | 707 | detect_leds(); |
708 | res = platform_device_register(&ar7_gpio_leds); | 708 | res = platform_device_register(&ar7_gpio_leds); |
709 | if (res) | 709 | if (res) |
710 | pr_warning("unable to register leds: %d\n", res); | 710 | pr_warn("unable to register leds: %d\n", res); |
711 | 711 | ||
712 | res = platform_device_register(&ar7_udc); | 712 | res = platform_device_register(&ar7_udc); |
713 | if (res) | 713 | if (res) |
714 | pr_warning("unable to register usb slave: %d\n", res); | 714 | pr_warn("unable to register usb slave: %d\n", res); |
715 | 715 | ||
716 | /* Register watchdog only if enabled in hardware */ | 716 | /* Register watchdog only if enabled in hardware */ |
717 | bootcr = ioremap_nocache(AR7_REGS_DCL, 4); | 717 | bootcr = ioremap_nocache(AR7_REGS_DCL, 4); |
@@ -726,7 +726,7 @@ static int __init ar7_register_devices(void) | |||
726 | ar7_wdt_res.end = ar7_wdt_res.start + 0x20; | 726 | ar7_wdt_res.end = ar7_wdt_res.start + 0x20; |
727 | res = platform_device_register(&ar7_wdt); | 727 | res = platform_device_register(&ar7_wdt); |
728 | if (res) | 728 | if (res) |
729 | pr_warning("unable to register watchdog: %d\n", res); | 729 | pr_warn("unable to register watchdog: %d\n", res); |
730 | } | 730 | } |
731 | 731 | ||
732 | return 0; | 732 | return 0; |
diff --git a/arch/mips/ath25/Kconfig b/arch/mips/ath25/Kconfig new file mode 100644 index 000000000000..fc19dd57e42d --- /dev/null +++ b/arch/mips/ath25/Kconfig | |||
@@ -0,0 +1,16 @@ | |||
1 | config SOC_AR5312 | ||
2 | bool "Atheros AR5312/AR2312+ SoC support" | ||
3 | depends on ATH25 | ||
4 | default y | ||
5 | |||
6 | config SOC_AR2315 | ||
7 | bool "Atheros AR2315+ SoC support" | ||
8 | depends on ATH25 | ||
9 | default y | ||
10 | |||
11 | config PCI_AR2315 | ||
12 | bool "Atheros AR2315 PCI controller support" | ||
13 | depends on SOC_AR2315 | ||
14 | select HW_HAS_PCI | ||
15 | select PCI | ||
16 | default y | ||
diff --git a/arch/mips/ath25/Makefile b/arch/mips/ath25/Makefile new file mode 100644 index 000000000000..eabad7da446a --- /dev/null +++ b/arch/mips/ath25/Makefile | |||
@@ -0,0 +1,16 @@ | |||
1 | # | ||
2 | # This file is subject to the terms and conditions of the GNU General Public | ||
3 | # License. See the file "COPYING" in the main directory of this archive | ||
4 | # for more details. | ||
5 | # | ||
6 | # Copyright (C) 2006 FON Technology, SL. | ||
7 | # Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> | ||
8 | # Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org> | ||
9 | # | ||
10 | |||
11 | obj-y += board.o prom.o devices.o | ||
12 | |||
13 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | ||
14 | |||
15 | obj-$(CONFIG_SOC_AR5312) += ar5312.o | ||
16 | obj-$(CONFIG_SOC_AR2315) += ar2315.o | ||
diff --git a/arch/mips/ath25/Platform b/arch/mips/ath25/Platform new file mode 100644 index 000000000000..ef3f81fa080b --- /dev/null +++ b/arch/mips/ath25/Platform | |||
@@ -0,0 +1,6 @@ | |||
1 | # | ||
2 | # Atheros AR531X/AR231X WiSoC | ||
3 | # | ||
4 | platform-$(CONFIG_ATH25) += ath25/ | ||
5 | cflags-$(CONFIG_ATH25) += -I$(srctree)/arch/mips/include/asm/mach-ath25 | ||
6 | load-$(CONFIG_ATH25) += 0xffffffff80041000 | ||
diff --git a/arch/mips/ath25/ar2315.c b/arch/mips/ath25/ar2315.c new file mode 100644 index 000000000000..2befa7d766a6 --- /dev/null +++ b/arch/mips/ath25/ar2315.c | |||
@@ -0,0 +1,364 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. | ||
7 | * Copyright (C) 2006 FON Technology, SL. | ||
8 | * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> | ||
9 | * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> | ||
10 | * Copyright (C) 2012 Alexandros C. Couloumbis <alex@ozo.com> | ||
11 | */ | ||
12 | |||
13 | /* | ||
14 | * Platform devices for Atheros AR2315 SoCs | ||
15 | */ | ||
16 | |||
17 | #include <linux/init.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/bitops.h> | ||
20 | #include <linux/irqdomain.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/reboot.h> | ||
24 | #include <asm/bootinfo.h> | ||
25 | #include <asm/reboot.h> | ||
26 | #include <asm/time.h> | ||
27 | |||
28 | #include <ath25_platform.h> | ||
29 | |||
30 | #include "devices.h" | ||
31 | #include "ar2315.h" | ||
32 | #include "ar2315_regs.h" | ||
33 | |||
34 | static void __iomem *ar2315_rst_base; | ||
35 | static struct irq_domain *ar2315_misc_irq_domain; | ||
36 | |||
37 | static inline u32 ar2315_rst_reg_read(u32 reg) | ||
38 | { | ||
39 | return __raw_readl(ar2315_rst_base + reg); | ||
40 | } | ||
41 | |||
42 | static inline void ar2315_rst_reg_write(u32 reg, u32 val) | ||
43 | { | ||
44 | __raw_writel(val, ar2315_rst_base + reg); | ||
45 | } | ||
46 | |||
47 | static inline void ar2315_rst_reg_mask(u32 reg, u32 mask, u32 val) | ||
48 | { | ||
49 | u32 ret = ar2315_rst_reg_read(reg); | ||
50 | |||
51 | ret &= ~mask; | ||
52 | ret |= val; | ||
53 | ar2315_rst_reg_write(reg, ret); | ||
54 | } | ||
55 | |||
56 | static irqreturn_t ar2315_ahb_err_handler(int cpl, void *dev_id) | ||
57 | { | ||
58 | ar2315_rst_reg_write(AR2315_AHB_ERR0, AR2315_AHB_ERROR_DET); | ||
59 | ar2315_rst_reg_read(AR2315_AHB_ERR1); | ||
60 | |||
61 | pr_emerg("AHB fatal error\n"); | ||
62 | machine_restart("AHB error"); /* Catastrophic failure */ | ||
63 | |||
64 | return IRQ_HANDLED; | ||
65 | } | ||
66 | |||
67 | static struct irqaction ar2315_ahb_err_interrupt = { | ||
68 | .handler = ar2315_ahb_err_handler, | ||
69 | .name = "ar2315-ahb-error", | ||
70 | }; | ||
71 | |||
72 | static void ar2315_misc_irq_handler(unsigned irq, struct irq_desc *desc) | ||
73 | { | ||
74 | u32 pending = ar2315_rst_reg_read(AR2315_ISR) & | ||
75 | ar2315_rst_reg_read(AR2315_IMR); | ||
76 | unsigned nr, misc_irq = 0; | ||
77 | |||
78 | if (pending) { | ||
79 | struct irq_domain *domain = irq_get_handler_data(irq); | ||
80 | |||
81 | nr = __ffs(pending); | ||
82 | misc_irq = irq_find_mapping(domain, nr); | ||
83 | } | ||
84 | |||
85 | if (misc_irq) { | ||
86 | if (nr == AR2315_MISC_IRQ_GPIO) | ||
87 | ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_GPIO); | ||
88 | else if (nr == AR2315_MISC_IRQ_WATCHDOG) | ||
89 | ar2315_rst_reg_write(AR2315_ISR, AR2315_ISR_WD); | ||
90 | generic_handle_irq(misc_irq); | ||
91 | } else { | ||
92 | spurious_interrupt(); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | static void ar2315_misc_irq_unmask(struct irq_data *d) | ||
97 | { | ||
98 | ar2315_rst_reg_mask(AR2315_IMR, 0, BIT(d->hwirq)); | ||
99 | } | ||
100 | |||
101 | static void ar2315_misc_irq_mask(struct irq_data *d) | ||
102 | { | ||
103 | ar2315_rst_reg_mask(AR2315_IMR, BIT(d->hwirq), 0); | ||
104 | } | ||
105 | |||
106 | static struct irq_chip ar2315_misc_irq_chip = { | ||
107 | .name = "ar2315-misc", | ||
108 | .irq_unmask = ar2315_misc_irq_unmask, | ||
109 | .irq_mask = ar2315_misc_irq_mask, | ||
110 | }; | ||
111 | |||
112 | static int ar2315_misc_irq_map(struct irq_domain *d, unsigned irq, | ||
113 | irq_hw_number_t hw) | ||
114 | { | ||
115 | irq_set_chip_and_handler(irq, &ar2315_misc_irq_chip, handle_level_irq); | ||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static struct irq_domain_ops ar2315_misc_irq_domain_ops = { | ||
120 | .map = ar2315_misc_irq_map, | ||
121 | }; | ||
122 | |||
123 | /* | ||
124 | * Called when an interrupt is received, this function | ||
125 | * determines exactly which interrupt it was, and it | ||
126 | * invokes the appropriate handler. | ||
127 | * | ||
128 | * Implicitly, we also define interrupt priority by | ||
129 | * choosing which to dispatch first. | ||
130 | */ | ||
131 | static void ar2315_irq_dispatch(void) | ||
132 | { | ||
133 | u32 pending = read_c0_status() & read_c0_cause(); | ||
134 | |||
135 | if (pending & CAUSEF_IP3) | ||
136 | do_IRQ(AR2315_IRQ_WLAN0); | ||
137 | #ifdef CONFIG_PCI_AR2315 | ||
138 | else if (pending & CAUSEF_IP5) | ||
139 | do_IRQ(AR2315_IRQ_LCBUS_PCI); | ||
140 | #endif | ||
141 | else if (pending & CAUSEF_IP2) | ||
142 | do_IRQ(AR2315_IRQ_MISC); | ||
143 | else if (pending & CAUSEF_IP7) | ||
144 | do_IRQ(ATH25_IRQ_CPU_CLOCK); | ||
145 | else | ||
146 | spurious_interrupt(); | ||
147 | } | ||
148 | |||
149 | void __init ar2315_arch_init_irq(void) | ||
150 | { | ||
151 | struct irq_domain *domain; | ||
152 | unsigned irq; | ||
153 | |||
154 | ath25_irq_dispatch = ar2315_irq_dispatch; | ||
155 | |||
156 | domain = irq_domain_add_linear(NULL, AR2315_MISC_IRQ_COUNT, | ||
157 | &ar2315_misc_irq_domain_ops, NULL); | ||
158 | if (!domain) | ||
159 | panic("Failed to add IRQ domain"); | ||
160 | |||
161 | irq = irq_create_mapping(domain, AR2315_MISC_IRQ_AHB); | ||
162 | setup_irq(irq, &ar2315_ahb_err_interrupt); | ||
163 | |||
164 | irq_set_chained_handler(AR2315_IRQ_MISC, ar2315_misc_irq_handler); | ||
165 | irq_set_handler_data(AR2315_IRQ_MISC, domain); | ||
166 | |||
167 | ar2315_misc_irq_domain = domain; | ||
168 | } | ||
169 | |||
170 | void __init ar2315_init_devices(void) | ||
171 | { | ||
172 | /* Find board configuration */ | ||
173 | ath25_find_config(AR2315_SPI_READ_BASE, AR2315_SPI_READ_SIZE); | ||
174 | |||
175 | ath25_add_wmac(0, AR2315_WLAN0_BASE, AR2315_IRQ_WLAN0); | ||
176 | } | ||
177 | |||
178 | static void ar2315_restart(char *command) | ||
179 | { | ||
180 | void (*mips_reset_vec)(void) = (void *)0xbfc00000; | ||
181 | |||
182 | local_irq_disable(); | ||
183 | |||
184 | /* try reset the system via reset control */ | ||
185 | ar2315_rst_reg_write(AR2315_COLD_RESET, AR2317_RESET_SYSTEM); | ||
186 | |||
187 | /* Cold reset does not work on the AR2315/6, use the GPIO reset bits | ||
188 | * a workaround. Give it some time to attempt a gpio based hardware | ||
189 | * reset (atheros reference design workaround) */ | ||
190 | |||
191 | /* TODO: implement the GPIO reset workaround */ | ||
192 | |||
193 | /* Some boards (e.g. Senao EOC-2610) don't implement the reset logic | ||
194 | * workaround. Attempt to jump to the mips reset location - | ||
195 | * the boot loader itself might be able to recover the system */ | ||
196 | mips_reset_vec(); | ||
197 | } | ||
198 | |||
199 | /* | ||
200 | * This table is indexed by bits 5..4 of the CLOCKCTL1 register | ||
201 | * to determine the predevisor value. | ||
202 | */ | ||
203 | static int clockctl1_predivide_table[4] __initdata = { 1, 2, 4, 5 }; | ||
204 | static int pllc_divide_table[5] __initdata = { 2, 3, 4, 6, 3 }; | ||
205 | |||
206 | static unsigned __init ar2315_sys_clk(u32 clock_ctl) | ||
207 | { | ||
208 | unsigned int pllc_ctrl, cpu_div; | ||
209 | unsigned int pllc_out, refdiv, fdiv, divby2; | ||
210 | unsigned int clk_div; | ||
211 | |||
212 | pllc_ctrl = ar2315_rst_reg_read(AR2315_PLLC_CTL); | ||
213 | refdiv = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_REF_DIV); | ||
214 | refdiv = clockctl1_predivide_table[refdiv]; | ||
215 | fdiv = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_FDBACK_DIV); | ||
216 | divby2 = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_ADD_FDBACK_DIV) + 1; | ||
217 | pllc_out = (40000000 / refdiv) * (2 * divby2) * fdiv; | ||
218 | |||
219 | /* clkm input selected */ | ||
220 | switch (clock_ctl & AR2315_CPUCLK_CLK_SEL_M) { | ||
221 | case 0: | ||
222 | case 1: | ||
223 | clk_div = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_CLKM_DIV); | ||
224 | clk_div = pllc_divide_table[clk_div]; | ||
225 | break; | ||
226 | case 2: | ||
227 | clk_div = ATH25_REG_MS(pllc_ctrl, AR2315_PLLC_CLKC_DIV); | ||
228 | clk_div = pllc_divide_table[clk_div]; | ||
229 | break; | ||
230 | default: | ||
231 | pllc_out = 40000000; | ||
232 | clk_div = 1; | ||
233 | break; | ||
234 | } | ||
235 | |||
236 | cpu_div = ATH25_REG_MS(clock_ctl, AR2315_CPUCLK_CLK_DIV); | ||
237 | cpu_div = cpu_div * 2 ?: 1; | ||
238 | |||
239 | return pllc_out / (clk_div * cpu_div); | ||
240 | } | ||
241 | |||
242 | static inline unsigned ar2315_cpu_frequency(void) | ||
243 | { | ||
244 | return ar2315_sys_clk(ar2315_rst_reg_read(AR2315_CPUCLK)); | ||
245 | } | ||
246 | |||
247 | static inline unsigned ar2315_apb_frequency(void) | ||
248 | { | ||
249 | return ar2315_sys_clk(ar2315_rst_reg_read(AR2315_AMBACLK)); | ||
250 | } | ||
251 | |||
252 | void __init ar2315_plat_time_init(void) | ||
253 | { | ||
254 | mips_hpt_frequency = ar2315_cpu_frequency() / 2; | ||
255 | } | ||
256 | |||
257 | void __init ar2315_plat_mem_setup(void) | ||
258 | { | ||
259 | void __iomem *sdram_base; | ||
260 | u32 memsize, memcfg; | ||
261 | u32 devid; | ||
262 | u32 config; | ||
263 | |||
264 | /* Detect memory size */ | ||
265 | sdram_base = ioremap_nocache(AR2315_SDRAMCTL_BASE, | ||
266 | AR2315_SDRAMCTL_SIZE); | ||
267 | memcfg = __raw_readl(sdram_base + AR2315_MEM_CFG); | ||
268 | memsize = 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_DATA_WIDTH); | ||
269 | memsize <<= 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_COL_WIDTH); | ||
270 | memsize <<= 1 + ATH25_REG_MS(memcfg, AR2315_MEM_CFG_ROW_WIDTH); | ||
271 | memsize <<= 3; | ||
272 | add_memory_region(0, memsize, BOOT_MEM_RAM); | ||
273 | iounmap(sdram_base); | ||
274 | |||
275 | ar2315_rst_base = ioremap_nocache(AR2315_RST_BASE, AR2315_RST_SIZE); | ||
276 | |||
277 | /* Detect the hardware based on the device ID */ | ||
278 | devid = ar2315_rst_reg_read(AR2315_SREV) & AR2315_REV_CHIP; | ||
279 | switch (devid) { | ||
280 | case 0x91: /* Need to check */ | ||
281 | ath25_soc = ATH25_SOC_AR2318; | ||
282 | break; | ||
283 | case 0x90: | ||
284 | ath25_soc = ATH25_SOC_AR2317; | ||
285 | break; | ||
286 | case 0x87: | ||
287 | ath25_soc = ATH25_SOC_AR2316; | ||
288 | break; | ||
289 | case 0x86: | ||
290 | default: | ||
291 | ath25_soc = ATH25_SOC_AR2315; | ||
292 | break; | ||
293 | } | ||
294 | ath25_board.devid = devid; | ||
295 | |||
296 | /* Clear any lingering AHB errors */ | ||
297 | config = read_c0_config(); | ||
298 | write_c0_config(config & ~0x3); | ||
299 | ar2315_rst_reg_write(AR2315_AHB_ERR0, AR2315_AHB_ERROR_DET); | ||
300 | ar2315_rst_reg_read(AR2315_AHB_ERR1); | ||
301 | ar2315_rst_reg_write(AR2315_WDT_CTRL, AR2315_WDT_CTRL_IGNORE); | ||
302 | |||
303 | _machine_restart = ar2315_restart; | ||
304 | } | ||
305 | |||
306 | #ifdef CONFIG_PCI_AR2315 | ||
307 | static struct resource ar2315_pci_res[] = { | ||
308 | { | ||
309 | .name = "ar2315-pci-ctrl", | ||
310 | .flags = IORESOURCE_MEM, | ||
311 | .start = AR2315_PCI_BASE, | ||
312 | .end = AR2315_PCI_BASE + AR2315_PCI_SIZE - 1, | ||
313 | }, | ||
314 | { | ||
315 | .name = "ar2315-pci-ext", | ||
316 | .flags = IORESOURCE_MEM, | ||
317 | .start = AR2315_PCI_EXT_BASE, | ||
318 | .end = AR2315_PCI_EXT_BASE + AR2315_PCI_EXT_SIZE - 1, | ||
319 | }, | ||
320 | { | ||
321 | .name = "ar2315-pci", | ||
322 | .flags = IORESOURCE_IRQ, | ||
323 | .start = AR2315_IRQ_LCBUS_PCI, | ||
324 | .end = AR2315_IRQ_LCBUS_PCI, | ||
325 | }, | ||
326 | }; | ||
327 | #endif | ||
328 | |||
329 | void __init ar2315_arch_init(void) | ||
330 | { | ||
331 | unsigned irq = irq_create_mapping(ar2315_misc_irq_domain, | ||
332 | AR2315_MISC_IRQ_UART0); | ||
333 | |||
334 | ath25_serial_setup(AR2315_UART0_BASE, irq, ar2315_apb_frequency()); | ||
335 | |||
336 | #ifdef CONFIG_PCI_AR2315 | ||
337 | if (ath25_soc == ATH25_SOC_AR2315) { | ||
338 | /* Reset PCI DMA logic */ | ||
339 | ar2315_rst_reg_mask(AR2315_RESET, 0, AR2315_RESET_PCIDMA); | ||
340 | msleep(20); | ||
341 | ar2315_rst_reg_mask(AR2315_RESET, AR2315_RESET_PCIDMA, 0); | ||
342 | msleep(20); | ||
343 | |||
344 | /* Configure endians */ | ||
345 | ar2315_rst_reg_mask(AR2315_ENDIAN_CTL, 0, AR2315_CONFIG_PCIAHB | | ||
346 | AR2315_CONFIG_PCIAHB_BRIDGE); | ||
347 | |||
348 | /* Configure as PCI host with DMA */ | ||
349 | ar2315_rst_reg_write(AR2315_PCICLK, AR2315_PCICLK_PLLC_CLKM | | ||
350 | (AR2315_PCICLK_IN_FREQ_DIV_6 << | ||
351 | AR2315_PCICLK_DIV_S)); | ||
352 | ar2315_rst_reg_mask(AR2315_AHB_ARB_CTL, 0, AR2315_ARB_PCI); | ||
353 | ar2315_rst_reg_mask(AR2315_IF_CTL, AR2315_IF_PCI_CLK_MASK | | ||
354 | AR2315_IF_MASK, AR2315_IF_PCI | | ||
355 | AR2315_IF_PCI_HOST | AR2315_IF_PCI_INTR | | ||
356 | (AR2315_IF_PCI_CLK_OUTPUT_CLK << | ||
357 | AR2315_IF_PCI_CLK_SHIFT)); | ||
358 | |||
359 | platform_device_register_simple("ar2315-pci", -1, | ||
360 | ar2315_pci_res, | ||
361 | ARRAY_SIZE(ar2315_pci_res)); | ||
362 | } | ||
363 | #endif | ||
364 | } | ||
diff --git a/arch/mips/ath25/ar2315.h b/arch/mips/ath25/ar2315.h new file mode 100644 index 000000000000..877afe63eed5 --- /dev/null +++ b/arch/mips/ath25/ar2315.h | |||
@@ -0,0 +1,22 @@ | |||
1 | #ifndef __AR2315_H | ||
2 | #define __AR2315_H | ||
3 | |||
4 | #ifdef CONFIG_SOC_AR2315 | ||
5 | |||
6 | void ar2315_arch_init_irq(void); | ||
7 | void ar2315_init_devices(void); | ||
8 | void ar2315_plat_time_init(void); | ||
9 | void ar2315_plat_mem_setup(void); | ||
10 | void ar2315_arch_init(void); | ||
11 | |||
12 | #else | ||
13 | |||
14 | static inline void ar2315_arch_init_irq(void) {} | ||
15 | static inline void ar2315_init_devices(void) {} | ||
16 | static inline void ar2315_plat_time_init(void) {} | ||
17 | static inline void ar2315_plat_mem_setup(void) {} | ||
18 | static inline void ar2315_arch_init(void) {} | ||
19 | |||
20 | #endif | ||
21 | |||
22 | #endif /* __AR2315_H */ | ||
diff --git a/arch/mips/ath25/ar2315_regs.h b/arch/mips/ath25/ar2315_regs.h new file mode 100644 index 000000000000..16e86149cb74 --- /dev/null +++ b/arch/mips/ath25/ar2315_regs.h | |||
@@ -0,0 +1,410 @@ | |||
1 | /* | ||
2 | * Register definitions for AR2315+ | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. | ||
9 | * Copyright (C) 2006 FON Technology, SL. | ||
10 | * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> | ||
11 | * Copyright (C) 2006-2008 Felix Fietkau <nbd@openwrt.org> | ||
12 | */ | ||
13 | |||
14 | #ifndef __ASM_MACH_ATH25_AR2315_REGS_H | ||
15 | #define __ASM_MACH_ATH25_AR2315_REGS_H | ||
16 | |||
17 | /* | ||
18 | * IRQs | ||
19 | */ | ||
20 | #define AR2315_IRQ_MISC (MIPS_CPU_IRQ_BASE + 2) /* C0_CAUSE: 0x0400 */ | ||
21 | #define AR2315_IRQ_WLAN0 (MIPS_CPU_IRQ_BASE + 3) /* C0_CAUSE: 0x0800 */ | ||
22 | #define AR2315_IRQ_ENET0 (MIPS_CPU_IRQ_BASE + 4) /* C0_CAUSE: 0x1000 */ | ||
23 | #define AR2315_IRQ_LCBUS_PCI (MIPS_CPU_IRQ_BASE + 5) /* C0_CAUSE: 0x2000 */ | ||
24 | #define AR2315_IRQ_WLAN0_POLL (MIPS_CPU_IRQ_BASE + 6) /* C0_CAUSE: 0x4000 */ | ||
25 | |||
26 | /* | ||
27 | * Miscellaneous interrupts, which share IP2. | ||
28 | */ | ||
29 | #define AR2315_MISC_IRQ_UART0 0 | ||
30 | #define AR2315_MISC_IRQ_I2C_RSVD 1 | ||
31 | #define AR2315_MISC_IRQ_SPI 2 | ||
32 | #define AR2315_MISC_IRQ_AHB 3 | ||
33 | #define AR2315_MISC_IRQ_APB 4 | ||
34 | #define AR2315_MISC_IRQ_TIMER 5 | ||
35 | #define AR2315_MISC_IRQ_GPIO 6 | ||
36 | #define AR2315_MISC_IRQ_WATCHDOG 7 | ||
37 | #define AR2315_MISC_IRQ_IR_RSVD 8 | ||
38 | #define AR2315_MISC_IRQ_COUNT 9 | ||
39 | |||
40 | /* | ||
41 | * Address map | ||
42 | */ | ||
43 | #define AR2315_SPI_READ_BASE 0x08000000 /* SPI flash */ | ||
44 | #define AR2315_SPI_READ_SIZE 0x01000000 | ||
45 | #define AR2315_WLAN0_BASE 0x10000000 /* Wireless MMR */ | ||
46 | #define AR2315_PCI_BASE 0x10100000 /* PCI MMR */ | ||
47 | #define AR2315_PCI_SIZE 0x00001000 | ||
48 | #define AR2315_SDRAMCTL_BASE 0x10300000 /* SDRAM MMR */ | ||
49 | #define AR2315_SDRAMCTL_SIZE 0x00000020 | ||
50 | #define AR2315_LOCAL_BASE 0x10400000 /* Local bus MMR */ | ||
51 | #define AR2315_ENET0_BASE 0x10500000 /* Ethernet MMR */ | ||
52 | #define AR2315_RST_BASE 0x11000000 /* Reset control MMR */ | ||
53 | #define AR2315_RST_SIZE 0x00000100 | ||
54 | #define AR2315_UART0_BASE 0x11100000 /* UART MMR */ | ||
55 | #define AR2315_SPI_MMR_BASE 0x11300000 /* SPI flash MMR */ | ||
56 | #define AR2315_SPI_MMR_SIZE 0x00000010 | ||
57 | #define AR2315_PCI_EXT_BASE 0x80000000 /* PCI external */ | ||
58 | #define AR2315_PCI_EXT_SIZE 0x40000000 | ||
59 | |||
60 | /* | ||
61 | * Configuration registers | ||
62 | */ | ||
63 | |||
64 | /* Cold reset register */ | ||
65 | #define AR2315_COLD_RESET 0x0000 | ||
66 | |||
67 | #define AR2315_RESET_COLD_AHB 0x00000001 | ||
68 | #define AR2315_RESET_COLD_APB 0x00000002 | ||
69 | #define AR2315_RESET_COLD_CPU 0x00000004 | ||
70 | #define AR2315_RESET_COLD_CPUWARM 0x00000008 | ||
71 | #define AR2315_RESET_SYSTEM (RESET_COLD_CPU |\ | ||
72 | RESET_COLD_APB |\ | ||
73 | RESET_COLD_AHB) /* full system */ | ||
74 | #define AR2317_RESET_SYSTEM 0x00000010 | ||
75 | |||
76 | /* Reset register */ | ||
77 | #define AR2315_RESET 0x0004 | ||
78 | |||
79 | #define AR2315_RESET_WARM_WLAN0_MAC 0x00000001 /* warm reset WLAN0 MAC */ | ||
80 | #define AR2315_RESET_WARM_WLAN0_BB 0x00000002 /* warm reset WLAN0 BB */ | ||
81 | #define AR2315_RESET_MPEGTS_RSVD 0x00000004 /* warm reset MPEG-TS */ | ||
82 | #define AR2315_RESET_PCIDMA 0x00000008 /* warm reset PCI ahb/dma */ | ||
83 | #define AR2315_RESET_MEMCTL 0x00000010 /* warm reset mem control */ | ||
84 | #define AR2315_RESET_LOCAL 0x00000020 /* warm reset local bus */ | ||
85 | #define AR2315_RESET_I2C_RSVD 0x00000040 /* warm reset I2C bus */ | ||
86 | #define AR2315_RESET_SPI 0x00000080 /* warm reset SPI iface */ | ||
87 | #define AR2315_RESET_UART0 0x00000100 /* warm reset UART0 */ | ||
88 | #define AR2315_RESET_IR_RSVD 0x00000200 /* warm reset IR iface */ | ||
89 | #define AR2315_RESET_EPHY0 0x00000400 /* cold reset ENET0 phy */ | ||
90 | #define AR2315_RESET_ENET0 0x00000800 /* cold reset ENET0 MAC */ | ||
91 | |||
92 | /* AHB master arbitration control */ | ||
93 | #define AR2315_AHB_ARB_CTL 0x0008 | ||
94 | |||
95 | #define AR2315_ARB_CPU 0x00000001 /* CPU, default */ | ||
96 | #define AR2315_ARB_WLAN 0x00000002 /* WLAN */ | ||
97 | #define AR2315_ARB_MPEGTS_RSVD 0x00000004 /* MPEG-TS */ | ||
98 | #define AR2315_ARB_LOCAL 0x00000008 /* Local bus */ | ||
99 | #define AR2315_ARB_PCI 0x00000010 /* PCI bus */ | ||
100 | #define AR2315_ARB_ETHERNET 0x00000020 /* Ethernet */ | ||
101 | #define AR2315_ARB_RETRY 0x00000100 /* Retry policy (debug) */ | ||
102 | |||
103 | /* Config Register */ | ||
104 | #define AR2315_ENDIAN_CTL 0x000c | ||
105 | |||
106 | #define AR2315_CONFIG_AHB 0x00000001 /* EC-AHB bridge endian */ | ||
107 | #define AR2315_CONFIG_WLAN 0x00000002 /* WLAN byteswap */ | ||
108 | #define AR2315_CONFIG_MPEGTS_RSVD 0x00000004 /* MPEG-TS byteswap */ | ||
109 | #define AR2315_CONFIG_PCI 0x00000008 /* PCI byteswap */ | ||
110 | #define AR2315_CONFIG_MEMCTL 0x00000010 /* Mem controller endian */ | ||
111 | #define AR2315_CONFIG_LOCAL 0x00000020 /* Local bus byteswap */ | ||
112 | #define AR2315_CONFIG_ETHERNET 0x00000040 /* Ethernet byteswap */ | ||
113 | #define AR2315_CONFIG_MERGE 0x00000200 /* CPU write buffer merge */ | ||
114 | #define AR2315_CONFIG_CPU 0x00000400 /* CPU big endian */ | ||
115 | #define AR2315_CONFIG_BIG 0x00000400 | ||
116 | #define AR2315_CONFIG_PCIAHB 0x00000800 | ||
117 | #define AR2315_CONFIG_PCIAHB_BRIDGE 0x00001000 | ||
118 | #define AR2315_CONFIG_SPI 0x00008000 /* SPI byteswap */ | ||
119 | #define AR2315_CONFIG_CPU_DRAM 0x00010000 | ||
120 | #define AR2315_CONFIG_CPU_PCI 0x00020000 | ||
121 | #define AR2315_CONFIG_CPU_MMR 0x00040000 | ||
122 | |||
123 | /* NMI control */ | ||
124 | #define AR2315_NMI_CTL 0x0010 | ||
125 | |||
126 | #define AR2315_NMI_EN 1 | ||
127 | |||
128 | /* Revision Register - Initial value is 0x3010 (WMAC 3.0, AR231X 1.0). */ | ||
129 | #define AR2315_SREV 0x0014 | ||
130 | |||
131 | #define AR2315_REV_MAJ 0x000000f0 | ||
132 | #define AR2315_REV_MAJ_S 4 | ||
133 | #define AR2315_REV_MIN 0x0000000f | ||
134 | #define AR2315_REV_MIN_S 0 | ||
135 | #define AR2315_REV_CHIP (AR2315_REV_MAJ | AR2315_REV_MIN) | ||
136 | |||
137 | /* Interface Enable */ | ||
138 | #define AR2315_IF_CTL 0x0018 | ||
139 | |||
140 | #define AR2315_IF_MASK 0x00000007 | ||
141 | #define AR2315_IF_DISABLED 0 /* Disable all */ | ||
142 | #define AR2315_IF_PCI 1 /* PCI */ | ||
143 | #define AR2315_IF_TS_LOCAL 2 /* Local bus */ | ||
144 | #define AR2315_IF_ALL 3 /* Emulation only */ | ||
145 | #define AR2315_IF_LOCAL_HOST 0x00000008 | ||
146 | #define AR2315_IF_PCI_HOST 0x00000010 | ||
147 | #define AR2315_IF_PCI_INTR 0x00000020 | ||
148 | #define AR2315_IF_PCI_CLK_MASK 0x00030000 | ||
149 | #define AR2315_IF_PCI_CLK_INPUT 0 | ||
150 | #define AR2315_IF_PCI_CLK_OUTPUT_LOW 1 | ||
151 | #define AR2315_IF_PCI_CLK_OUTPUT_CLK 2 | ||
152 | #define AR2315_IF_PCI_CLK_OUTPUT_HIGH 3 | ||
153 | #define AR2315_IF_PCI_CLK_SHIFT 16 | ||
154 | |||
155 | /* APB Interrupt control */ | ||
156 | #define AR2315_ISR 0x0020 | ||
157 | #define AR2315_IMR 0x0024 | ||
158 | #define AR2315_GISR 0x0028 | ||
159 | |||
160 | #define AR2315_ISR_UART0 0x00000001 /* high speed UART */ | ||
161 | #define AR2315_ISR_I2C_RSVD 0x00000002 /* I2C bus */ | ||
162 | #define AR2315_ISR_SPI 0x00000004 /* SPI bus */ | ||
163 | #define AR2315_ISR_AHB 0x00000008 /* AHB error */ | ||
164 | #define AR2315_ISR_APB 0x00000010 /* APB error */ | ||
165 | #define AR2315_ISR_TIMER 0x00000020 /* Timer */ | ||
166 | #define AR2315_ISR_GPIO 0x00000040 /* GPIO */ | ||
167 | #define AR2315_ISR_WD 0x00000080 /* Watchdog */ | ||
168 | #define AR2315_ISR_IR_RSVD 0x00000100 /* IR */ | ||
169 | |||
170 | #define AR2315_GISR_MISC 0x00000001 /* Misc */ | ||
171 | #define AR2315_GISR_WLAN0 0x00000002 /* WLAN0 */ | ||
172 | #define AR2315_GISR_MPEGTS_RSVD 0x00000004 /* MPEG-TS */ | ||
173 | #define AR2315_GISR_LOCALPCI 0x00000008 /* Local/PCI bus */ | ||
174 | #define AR2315_GISR_WMACPOLL 0x00000010 | ||
175 | #define AR2315_GISR_TIMER 0x00000020 | ||
176 | #define AR2315_GISR_ETHERNET 0x00000040 /* Ethernet */ | ||
177 | |||
178 | /* Generic timer */ | ||
179 | #define AR2315_TIMER 0x0030 | ||
180 | #define AR2315_RELOAD 0x0034 | ||
181 | |||
182 | /* Watchdog timer */ | ||
183 | #define AR2315_WDT_TIMER 0x0038 | ||
184 | #define AR2315_WDT_CTRL 0x003c | ||
185 | |||
186 | #define AR2315_WDT_CTRL_IGNORE 0x00000000 /* ignore expiration */ | ||
187 | #define AR2315_WDT_CTRL_NMI 0x00000001 /* NMI on watchdog */ | ||
188 | #define AR2315_WDT_CTRL_RESET 0x00000002 /* reset on watchdog */ | ||
189 | |||
190 | /* CPU Performance Counters */ | ||
191 | #define AR2315_PERFCNT0 0x0048 | ||
192 | #define AR2315_PERFCNT1 0x004c | ||
193 | |||
194 | #define AR2315_PERF0_DATAHIT 0x00000001 /* Count Data Cache Hits */ | ||
195 | #define AR2315_PERF0_DATAMISS 0x00000002 /* Count Data Cache Misses */ | ||
196 | #define AR2315_PERF0_INSTHIT 0x00000004 /* Count Instruction Cache Hits */ | ||
197 | #define AR2315_PERF0_INSTMISS 0x00000008 /* Count Instruction Cache Misses */ | ||
198 | #define AR2315_PERF0_ACTIVE 0x00000010 /* Count Active Processor Cycles */ | ||
199 | #define AR2315_PERF0_WBHIT 0x00000020 /* Count CPU Write Buffer Hits */ | ||
200 | #define AR2315_PERF0_WBMISS 0x00000040 /* Count CPU Write Buffer Misses */ | ||
201 | |||
202 | #define AR2315_PERF1_EB_ARDY 0x00000001 /* Count EB_ARdy signal */ | ||
203 | #define AR2315_PERF1_EB_AVALID 0x00000002 /* Count EB_AValid signal */ | ||
204 | #define AR2315_PERF1_EB_WDRDY 0x00000004 /* Count EB_WDRdy signal */ | ||
205 | #define AR2315_PERF1_EB_RDVAL 0x00000008 /* Count EB_RdVal signal */ | ||
206 | #define AR2315_PERF1_VRADDR 0x00000010 /* Count valid read address cycles*/ | ||
207 | #define AR2315_PERF1_VWADDR 0x00000020 /* Count valid write address cycl.*/ | ||
208 | #define AR2315_PERF1_VWDATA 0x00000040 /* Count valid write data cycles */ | ||
209 | |||
210 | /* AHB Error Reporting */ | ||
211 | #define AR2315_AHB_ERR0 0x0050 /* error */ | ||
212 | #define AR2315_AHB_ERR1 0x0054 /* haddr */ | ||
213 | #define AR2315_AHB_ERR2 0x0058 /* hwdata */ | ||
214 | #define AR2315_AHB_ERR3 0x005c /* hrdata */ | ||
215 | #define AR2315_AHB_ERR4 0x0060 /* status */ | ||
216 | |||
217 | #define AR2315_AHB_ERROR_DET 1 /* AHB Error has been detected, */ | ||
218 | /* write 1 to clear all bits in ERR0 */ | ||
219 | #define AR2315_AHB_ERROR_OVR 2 /* AHB Error overflow has been detected */ | ||
220 | #define AR2315_AHB_ERROR_WDT 4 /* AHB Error due to wdt instead of hresp */ | ||
221 | |||
222 | #define AR2315_PROCERR_HMAST 0x0000000f | ||
223 | #define AR2315_PROCERR_HMAST_DFLT 0 | ||
224 | #define AR2315_PROCERR_HMAST_WMAC 1 | ||
225 | #define AR2315_PROCERR_HMAST_ENET 2 | ||
226 | #define AR2315_PROCERR_HMAST_PCIENDPT 3 | ||
227 | #define AR2315_PROCERR_HMAST_LOCAL 4 | ||
228 | #define AR2315_PROCERR_HMAST_CPU 5 | ||
229 | #define AR2315_PROCERR_HMAST_PCITGT 6 | ||
230 | #define AR2315_PROCERR_HMAST_S 0 | ||
231 | #define AR2315_PROCERR_HWRITE 0x00000010 | ||
232 | #define AR2315_PROCERR_HSIZE 0x00000060 | ||
233 | #define AR2315_PROCERR_HSIZE_S 5 | ||
234 | #define AR2315_PROCERR_HTRANS 0x00000180 | ||
235 | #define AR2315_PROCERR_HTRANS_S 7 | ||
236 | #define AR2315_PROCERR_HBURST 0x00000e00 | ||
237 | #define AR2315_PROCERR_HBURST_S 9 | ||
238 | |||
239 | /* Clock Control */ | ||
240 | #define AR2315_PLLC_CTL 0x0064 | ||
241 | #define AR2315_PLLV_CTL 0x0068 | ||
242 | #define AR2315_CPUCLK 0x006c | ||
243 | #define AR2315_AMBACLK 0x0070 | ||
244 | #define AR2315_SYNCCLK 0x0074 | ||
245 | #define AR2315_DSL_SLEEP_CTL 0x0080 | ||
246 | #define AR2315_DSL_SLEEP_DUR 0x0084 | ||
247 | |||
248 | /* PLLc Control fields */ | ||
249 | #define AR2315_PLLC_REF_DIV_M 0x00000003 | ||
250 | #define AR2315_PLLC_REF_DIV_S 0 | ||
251 | #define AR2315_PLLC_FDBACK_DIV_M 0x0000007c | ||
252 | #define AR2315_PLLC_FDBACK_DIV_S 2 | ||
253 | #define AR2315_PLLC_ADD_FDBACK_DIV_M 0x00000080 | ||
254 | #define AR2315_PLLC_ADD_FDBACK_DIV_S 7 | ||
255 | #define AR2315_PLLC_CLKC_DIV_M 0x0001c000 | ||
256 | #define AR2315_PLLC_CLKC_DIV_S 14 | ||
257 | #define AR2315_PLLC_CLKM_DIV_M 0x00700000 | ||
258 | #define AR2315_PLLC_CLKM_DIV_S 20 | ||
259 | |||
260 | /* CPU CLK Control fields */ | ||
261 | #define AR2315_CPUCLK_CLK_SEL_M 0x00000003 | ||
262 | #define AR2315_CPUCLK_CLK_SEL_S 0 | ||
263 | #define AR2315_CPUCLK_CLK_DIV_M 0x0000000c | ||
264 | #define AR2315_CPUCLK_CLK_DIV_S 2 | ||
265 | |||
266 | /* AMBA CLK Control fields */ | ||
267 | #define AR2315_AMBACLK_CLK_SEL_M 0x00000003 | ||
268 | #define AR2315_AMBACLK_CLK_SEL_S 0 | ||
269 | #define AR2315_AMBACLK_CLK_DIV_M 0x0000000c | ||
270 | #define AR2315_AMBACLK_CLK_DIV_S 2 | ||
271 | |||
272 | /* PCI Clock Control */ | ||
273 | #define AR2315_PCICLK 0x00a4 | ||
274 | |||
275 | #define AR2315_PCICLK_INPUT_M 0x00000003 | ||
276 | #define AR2315_PCICLK_INPUT_S 0 | ||
277 | #define AR2315_PCICLK_PLLC_CLKM 0 | ||
278 | #define AR2315_PCICLK_PLLC_CLKM1 1 | ||
279 | #define AR2315_PCICLK_PLLC_CLKC 2 | ||
280 | #define AR2315_PCICLK_REF_CLK 3 | ||
281 | #define AR2315_PCICLK_DIV_M 0x0000000c | ||
282 | #define AR2315_PCICLK_DIV_S 2 | ||
283 | #define AR2315_PCICLK_IN_FREQ 0 | ||
284 | #define AR2315_PCICLK_IN_FREQ_DIV_6 1 | ||
285 | #define AR2315_PCICLK_IN_FREQ_DIV_8 2 | ||
286 | #define AR2315_PCICLK_IN_FREQ_DIV_10 3 | ||
287 | |||
288 | /* Observation Control Register */ | ||
289 | #define AR2315_OCR 0x00b0 | ||
290 | |||
291 | #define AR2315_OCR_GPIO0_IRIN 0x00000040 | ||
292 | #define AR2315_OCR_GPIO1_IROUT 0x00000080 | ||
293 | #define AR2315_OCR_GPIO3_RXCLR 0x00000200 | ||
294 | |||
295 | /* General Clock Control */ | ||
296 | #define AR2315_MISCCLK 0x00b4 | ||
297 | |||
298 | #define AR2315_MISCCLK_PLLBYPASS_EN 0x00000001 | ||
299 | #define AR2315_MISCCLK_PROCREFCLK 0x00000002 | ||
300 | |||
301 | /* | ||
302 | * SDRAM Controller | ||
303 | * - No read or write buffers are included. | ||
304 | */ | ||
305 | #define AR2315_MEM_CFG 0x0000 | ||
306 | #define AR2315_MEM_CTRL 0x000c | ||
307 | #define AR2315_MEM_REF 0x0010 | ||
308 | |||
309 | #define AR2315_MEM_CFG_DATA_WIDTH_M 0x00006000 | ||
310 | #define AR2315_MEM_CFG_DATA_WIDTH_S 13 | ||
311 | #define AR2315_MEM_CFG_COL_WIDTH_M 0x00001e00 | ||
312 | #define AR2315_MEM_CFG_COL_WIDTH_S 9 | ||
313 | #define AR2315_MEM_CFG_ROW_WIDTH_M 0x000001e0 | ||
314 | #define AR2315_MEM_CFG_ROW_WIDTH_S 5 | ||
315 | #define AR2315_MEM_CFG_BANKADDR_BITS_M 0x00000018 | ||
316 | #define AR2315_MEM_CFG_BANKADDR_BITS_S 3 | ||
317 | |||
318 | /* | ||
319 | * Local Bus Interface Registers | ||
320 | */ | ||
321 | #define AR2315_LB_CONFIG 0x0000 | ||
322 | |||
323 | #define AR2315_LBCONF_OE 0x00000001 /* =1 OE is low-true */ | ||
324 | #define AR2315_LBCONF_CS0 0x00000002 /* =1 first CS is low-true */ | ||
325 | #define AR2315_LBCONF_CS1 0x00000004 /* =1 2nd CS is low-true */ | ||
326 | #define AR2315_LBCONF_RDY 0x00000008 /* =1 RDY is low-true */ | ||
327 | #define AR2315_LBCONF_WE 0x00000010 /* =1 Write En is low-true */ | ||
328 | #define AR2315_LBCONF_WAIT 0x00000020 /* =1 WAIT is low-true */ | ||
329 | #define AR2315_LBCONF_ADS 0x00000040 /* =1 Adr Strobe is low-true */ | ||
330 | #define AR2315_LBCONF_MOT 0x00000080 /* =0 Intel, =1 Motorola */ | ||
331 | #define AR2315_LBCONF_8CS 0x00000100 /* =1 8 bits CS, 0= 16bits */ | ||
332 | #define AR2315_LBCONF_8DS 0x00000200 /* =1 8 bits Data S, 0=16bits */ | ||
333 | #define AR2315_LBCONF_ADS_EN 0x00000400 /* =1 Enable ADS */ | ||
334 | #define AR2315_LBCONF_ADR_OE 0x00000800 /* =1 Adr cap on OE, WE or DS */ | ||
335 | #define AR2315_LBCONF_ADDT_MUX 0x00001000 /* =1 Adr and Data share bus */ | ||
336 | #define AR2315_LBCONF_DATA_OE 0x00002000 /* =1 Data cap on OE, WE, DS */ | ||
337 | #define AR2315_LBCONF_16DATA 0x00004000 /* =1 Data is 16 bits wide */ | ||
338 | #define AR2315_LBCONF_SWAPDT 0x00008000 /* =1 Byte swap data */ | ||
339 | #define AR2315_LBCONF_SYNC 0x00010000 /* =1 Bus synchronous to clk */ | ||
340 | #define AR2315_LBCONF_INT 0x00020000 /* =1 Intr is low true */ | ||
341 | #define AR2315_LBCONF_INT_CTR0 0x00000000 /* GND high-Z, Vdd is high-Z */ | ||
342 | #define AR2315_LBCONF_INT_CTR1 0x00040000 /* GND drive, Vdd is high-Z */ | ||
343 | #define AR2315_LBCONF_INT_CTR2 0x00080000 /* GND high-Z, Vdd drive */ | ||
344 | #define AR2315_LBCONF_INT_CTR3 0x000c0000 /* GND drive, Vdd drive */ | ||
345 | #define AR2315_LBCONF_RDY_WAIT 0x00100000 /* =1 RDY is negative of WAIT */ | ||
346 | #define AR2315_LBCONF_INT_PULSE 0x00200000 /* =1 Interrupt is a pulse */ | ||
347 | #define AR2315_LBCONF_ENABLE 0x00400000 /* =1 Falcon respond to LB */ | ||
348 | |||
349 | #define AR2315_LB_CLKSEL 0x0004 | ||
350 | |||
351 | #define AR2315_LBCLK_EXT 0x00000001 /* use external clk for lb */ | ||
352 | |||
353 | #define AR2315_LB_1MS 0x0008 | ||
354 | |||
355 | #define AR2315_LB1MS_MASK 0x0003ffff /* # of AHB clk cycles in 1ms */ | ||
356 | |||
357 | #define AR2315_LB_MISCCFG 0x000c | ||
358 | |||
359 | #define AR2315_LBM_TXD_EN 0x00000001 /* Enable TXD for fragments */ | ||
360 | #define AR2315_LBM_RX_INTEN 0x00000002 /* Enable LB ints on RX ready */ | ||
361 | #define AR2315_LBM_MBOXWR_INTEN 0x00000004 /* Enable LB ints on mbox wr */ | ||
362 | #define AR2315_LBM_MBOXRD_INTEN 0x00000008 /* Enable LB ints on mbox rd */ | ||
363 | #define AR2315_LMB_DESCSWAP_EN 0x00000010 /* Byte swap desc enable */ | ||
364 | #define AR2315_LBM_TIMEOUT_M 0x00ffff80 | ||
365 | #define AR2315_LBM_TIMEOUT_S 7 | ||
366 | #define AR2315_LBM_PORTMUX 0x07000000 | ||
367 | |||
368 | #define AR2315_LB_RXTSOFF 0x0010 | ||
369 | |||
370 | #define AR2315_LB_TX_CHAIN_EN 0x0100 | ||
371 | |||
372 | #define AR2315_LB_TXEN_0 0x00000001 | ||
373 | #define AR2315_LB_TXEN_1 0x00000002 | ||
374 | #define AR2315_LB_TXEN_2 0x00000004 | ||
375 | #define AR2315_LB_TXEN_3 0x00000008 | ||
376 | |||
377 | #define AR2315_LB_TX_CHAIN_DIS 0x0104 | ||
378 | #define AR2315_LB_TX_DESC_PTR 0x0200 | ||
379 | |||
380 | #define AR2315_LB_RX_CHAIN_EN 0x0400 | ||
381 | |||
382 | #define AR2315_LB_RXEN 0x00000001 | ||
383 | |||
384 | #define AR2315_LB_RX_CHAIN_DIS 0x0404 | ||
385 | #define AR2315_LB_RX_DESC_PTR 0x0408 | ||
386 | |||
387 | #define AR2315_LB_INT_STATUS 0x0500 | ||
388 | |||
389 | #define AR2315_LB_INT_TX_DESC 0x00000001 | ||
390 | #define AR2315_LB_INT_TX_OK 0x00000002 | ||
391 | #define AR2315_LB_INT_TX_ERR 0x00000004 | ||
392 | #define AR2315_LB_INT_TX_EOF 0x00000008 | ||
393 | #define AR2315_LB_INT_RX_DESC 0x00000010 | ||
394 | #define AR2315_LB_INT_RX_OK 0x00000020 | ||
395 | #define AR2315_LB_INT_RX_ERR 0x00000040 | ||
396 | #define AR2315_LB_INT_RX_EOF 0x00000080 | ||
397 | #define AR2315_LB_INT_TX_TRUNC 0x00000100 | ||
398 | #define AR2315_LB_INT_TX_STARVE 0x00000200 | ||
399 | #define AR2315_LB_INT_LB_TIMEOUT 0x00000400 | ||
400 | #define AR2315_LB_INT_LB_ERR 0x00000800 | ||
401 | #define AR2315_LB_INT_MBOX_WR 0x00001000 | ||
402 | #define AR2315_LB_INT_MBOX_RD 0x00002000 | ||
403 | |||
404 | /* Bit definitions for INT MASK are the same as INT_STATUS */ | ||
405 | #define AR2315_LB_INT_MASK 0x0504 | ||
406 | |||
407 | #define AR2315_LB_INT_EN 0x0508 | ||
408 | #define AR2315_LB_MBOX 0x0600 | ||
409 | |||
410 | #endif /* __ASM_MACH_ATH25_AR2315_REGS_H */ | ||
diff --git a/arch/mips/ath25/ar5312.c b/arch/mips/ath25/ar5312.c new file mode 100644 index 000000000000..b6887f75144c --- /dev/null +++ b/arch/mips/ath25/ar5312.c | |||
@@ -0,0 +1,393 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. | ||
7 | * Copyright (C) 2006 FON Technology, SL. | ||
8 | * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> | ||
9 | * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org> | ||
10 | * Copyright (C) 2012 Alexandros C. Couloumbis <alex@ozo.com> | ||
11 | */ | ||
12 | |||
13 | /* | ||
14 | * Platform devices for Atheros AR5312 SoCs | ||
15 | */ | ||
16 | |||
17 | #include <linux/init.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/bitops.h> | ||
20 | #include <linux/irqdomain.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/mtd/physmap.h> | ||
24 | #include <linux/reboot.h> | ||
25 | #include <asm/bootinfo.h> | ||
26 | #include <asm/reboot.h> | ||
27 | #include <asm/time.h> | ||
28 | |||
29 | #include <ath25_platform.h> | ||
30 | |||
31 | #include "devices.h" | ||
32 | #include "ar5312.h" | ||
33 | #include "ar5312_regs.h" | ||
34 | |||
35 | static void __iomem *ar5312_rst_base; | ||
36 | static struct irq_domain *ar5312_misc_irq_domain; | ||
37 | |||
38 | static inline u32 ar5312_rst_reg_read(u32 reg) | ||
39 | { | ||
40 | return __raw_readl(ar5312_rst_base + reg); | ||
41 | } | ||
42 | |||
43 | static inline void ar5312_rst_reg_write(u32 reg, u32 val) | ||
44 | { | ||
45 | __raw_writel(val, ar5312_rst_base + reg); | ||
46 | } | ||
47 | |||
48 | static inline void ar5312_rst_reg_mask(u32 reg, u32 mask, u32 val) | ||
49 | { | ||
50 | u32 ret = ar5312_rst_reg_read(reg); | ||
51 | |||
52 | ret &= ~mask; | ||
53 | ret |= val; | ||
54 | ar5312_rst_reg_write(reg, ret); | ||
55 | } | ||
56 | |||
57 | static irqreturn_t ar5312_ahb_err_handler(int cpl, void *dev_id) | ||
58 | { | ||
59 | u32 proc1 = ar5312_rst_reg_read(AR5312_PROC1); | ||
60 | u32 proc_addr = ar5312_rst_reg_read(AR5312_PROCADDR); /* clears error */ | ||
61 | u32 dma1 = ar5312_rst_reg_read(AR5312_DMA1); | ||
62 | u32 dma_addr = ar5312_rst_reg_read(AR5312_DMAADDR); /* clears error */ | ||
63 | |||
64 | pr_emerg("AHB interrupt: PROCADDR=0x%8.8x PROC1=0x%8.8x DMAADDR=0x%8.8x DMA1=0x%8.8x\n", | ||
65 | proc_addr, proc1, dma_addr, dma1); | ||
66 | |||
67 | machine_restart("AHB error"); /* Catastrophic failure */ | ||
68 | return IRQ_HANDLED; | ||
69 | } | ||
70 | |||
71 | static struct irqaction ar5312_ahb_err_interrupt = { | ||
72 | .handler = ar5312_ahb_err_handler, | ||
73 | .name = "ar5312-ahb-error", | ||
74 | }; | ||
75 | |||
76 | static void ar5312_misc_irq_handler(unsigned irq, struct irq_desc *desc) | ||
77 | { | ||
78 | u32 pending = ar5312_rst_reg_read(AR5312_ISR) & | ||
79 | ar5312_rst_reg_read(AR5312_IMR); | ||
80 | unsigned nr, misc_irq = 0; | ||
81 | |||
82 | if (pending) { | ||
83 | struct irq_domain *domain = irq_get_handler_data(irq); | ||
84 | |||
85 | nr = __ffs(pending); | ||
86 | misc_irq = irq_find_mapping(domain, nr); | ||
87 | } | ||
88 | |||
89 | if (misc_irq) { | ||
90 | generic_handle_irq(misc_irq); | ||
91 | if (nr == AR5312_MISC_IRQ_TIMER) | ||
92 | ar5312_rst_reg_read(AR5312_TIMER); | ||
93 | } else { | ||
94 | spurious_interrupt(); | ||
95 | } | ||
96 | } | ||
97 | |||
98 | /* Enable the specified AR5312_MISC_IRQ interrupt */ | ||
99 | static void ar5312_misc_irq_unmask(struct irq_data *d) | ||
100 | { | ||
101 | ar5312_rst_reg_mask(AR5312_IMR, 0, BIT(d->hwirq)); | ||
102 | } | ||
103 | |||
104 | /* Disable the specified AR5312_MISC_IRQ interrupt */ | ||
105 | static void ar5312_misc_irq_mask(struct irq_data *d) | ||
106 | { | ||
107 | ar5312_rst_reg_mask(AR5312_IMR, BIT(d->hwirq), 0); | ||
108 | ar5312_rst_reg_read(AR5312_IMR); /* flush write buffer */ | ||
109 | } | ||
110 | |||
111 | static struct irq_chip ar5312_misc_irq_chip = { | ||
112 | .name = "ar5312-misc", | ||
113 | .irq_unmask = ar5312_misc_irq_unmask, | ||
114 | .irq_mask = ar5312_misc_irq_mask, | ||
115 | }; | ||
116 | |||
117 | static int ar5312_misc_irq_map(struct irq_domain *d, unsigned irq, | ||
118 | irq_hw_number_t hw) | ||
119 | { | ||
120 | irq_set_chip_and_handler(irq, &ar5312_misc_irq_chip, handle_level_irq); | ||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | static struct irq_domain_ops ar5312_misc_irq_domain_ops = { | ||
125 | .map = ar5312_misc_irq_map, | ||
126 | }; | ||
127 | |||
128 | static void ar5312_irq_dispatch(void) | ||
129 | { | ||
130 | u32 pending = read_c0_status() & read_c0_cause(); | ||
131 | |||
132 | if (pending & CAUSEF_IP2) | ||
133 | do_IRQ(AR5312_IRQ_WLAN0); | ||
134 | else if (pending & CAUSEF_IP5) | ||
135 | do_IRQ(AR5312_IRQ_WLAN1); | ||
136 | else if (pending & CAUSEF_IP6) | ||
137 | do_IRQ(AR5312_IRQ_MISC); | ||
138 | else if (pending & CAUSEF_IP7) | ||
139 | do_IRQ(ATH25_IRQ_CPU_CLOCK); | ||
140 | else | ||
141 | spurious_interrupt(); | ||
142 | } | ||
143 | |||
144 | void __init ar5312_arch_init_irq(void) | ||
145 | { | ||
146 | struct irq_domain *domain; | ||
147 | unsigned irq; | ||
148 | |||
149 | ath25_irq_dispatch = ar5312_irq_dispatch; | ||
150 | |||
151 | domain = irq_domain_add_linear(NULL, AR5312_MISC_IRQ_COUNT, | ||
152 | &ar5312_misc_irq_domain_ops, NULL); | ||
153 | if (!domain) | ||
154 | panic("Failed to add IRQ domain"); | ||
155 | |||
156 | irq = irq_create_mapping(domain, AR5312_MISC_IRQ_AHB_PROC); | ||
157 | setup_irq(irq, &ar5312_ahb_err_interrupt); | ||
158 | |||
159 | irq_set_chained_handler(AR5312_IRQ_MISC, ar5312_misc_irq_handler); | ||
160 | irq_set_handler_data(AR5312_IRQ_MISC, domain); | ||
161 | |||
162 | ar5312_misc_irq_domain = domain; | ||
163 | } | ||
164 | |||
165 | static struct physmap_flash_data ar5312_flash_data = { | ||
166 | .width = 2, | ||
167 | }; | ||
168 | |||
169 | static struct resource ar5312_flash_resource = { | ||
170 | .start = AR5312_FLASH_BASE, | ||
171 | .end = AR5312_FLASH_BASE + AR5312_FLASH_SIZE - 1, | ||
172 | .flags = IORESOURCE_MEM, | ||
173 | }; | ||
174 | |||
175 | static struct platform_device ar5312_physmap_flash = { | ||
176 | .name = "physmap-flash", | ||
177 | .id = 0, | ||
178 | .dev.platform_data = &ar5312_flash_data, | ||
179 | .resource = &ar5312_flash_resource, | ||
180 | .num_resources = 1, | ||
181 | }; | ||
182 | |||
183 | static void __init ar5312_flash_init(void) | ||
184 | { | ||
185 | void __iomem *flashctl_base; | ||
186 | u32 ctl; | ||
187 | |||
188 | flashctl_base = ioremap_nocache(AR5312_FLASHCTL_BASE, | ||
189 | AR5312_FLASHCTL_SIZE); | ||
190 | |||
191 | ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL0); | ||
192 | ctl &= AR5312_FLASHCTL_MW; | ||
193 | |||
194 | /* fixup flash width */ | ||
195 | switch (ctl) { | ||
196 | case AR5312_FLASHCTL_MW16: | ||
197 | ar5312_flash_data.width = 2; | ||
198 | break; | ||
199 | case AR5312_FLASHCTL_MW8: | ||
200 | default: | ||
201 | ar5312_flash_data.width = 1; | ||
202 | break; | ||
203 | } | ||
204 | |||
205 | /* | ||
206 | * Configure flash bank 0. | ||
207 | * Assume 8M window size. Flash will be aliased if it's smaller | ||
208 | */ | ||
209 | ctl |= AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC_8M | AR5312_FLASHCTL_RBLE; | ||
210 | ctl |= 0x01 << AR5312_FLASHCTL_IDCY_S; | ||
211 | ctl |= 0x07 << AR5312_FLASHCTL_WST1_S; | ||
212 | ctl |= 0x07 << AR5312_FLASHCTL_WST2_S; | ||
213 | __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL0); | ||
214 | |||
215 | /* Disable other flash banks */ | ||
216 | ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL1); | ||
217 | ctl &= ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC); | ||
218 | __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL1); | ||
219 | ctl = __raw_readl(flashctl_base + AR5312_FLASHCTL2); | ||
220 | ctl &= ~(AR5312_FLASHCTL_E | AR5312_FLASHCTL_AC); | ||
221 | __raw_writel(ctl, flashctl_base + AR5312_FLASHCTL2); | ||
222 | |||
223 | iounmap(flashctl_base); | ||
224 | } | ||
225 | |||
226 | void __init ar5312_init_devices(void) | ||
227 | { | ||
228 | struct ath25_boarddata *config; | ||
229 | |||
230 | ar5312_flash_init(); | ||
231 | |||
232 | /* Locate board/radio config data */ | ||
233 | ath25_find_config(AR5312_FLASH_BASE, AR5312_FLASH_SIZE); | ||
234 | config = ath25_board.config; | ||
235 | |||
236 | /* AR2313 has CPU minor rev. 10 */ | ||
237 | if ((current_cpu_data.processor_id & 0xff) == 0x0a) | ||
238 | ath25_soc = ATH25_SOC_AR2313; | ||
239 | |||
240 | /* AR2312 shares the same Silicon ID as AR5312 */ | ||
241 | else if (config->flags & BD_ISCASPER) | ||
242 | ath25_soc = ATH25_SOC_AR2312; | ||
243 | |||
244 | /* Everything else is probably AR5312 or compatible */ | ||
245 | else | ||
246 | ath25_soc = ATH25_SOC_AR5312; | ||
247 | |||
248 | platform_device_register(&ar5312_physmap_flash); | ||
249 | |||
250 | switch (ath25_soc) { | ||
251 | case ATH25_SOC_AR5312: | ||
252 | if (!ath25_board.radio) | ||
253 | return; | ||
254 | |||
255 | if (!(config->flags & BD_WLAN0)) | ||
256 | break; | ||
257 | |||
258 | ath25_add_wmac(0, AR5312_WLAN0_BASE, AR5312_IRQ_WLAN0); | ||
259 | break; | ||
260 | case ATH25_SOC_AR2312: | ||
261 | case ATH25_SOC_AR2313: | ||
262 | if (!ath25_board.radio) | ||
263 | return; | ||
264 | break; | ||
265 | default: | ||
266 | break; | ||
267 | } | ||
268 | |||
269 | if (config->flags & BD_WLAN1) | ||
270 | ath25_add_wmac(1, AR5312_WLAN1_BASE, AR5312_IRQ_WLAN1); | ||
271 | } | ||
272 | |||
273 | static void ar5312_restart(char *command) | ||
274 | { | ||
275 | /* reset the system */ | ||
276 | local_irq_disable(); | ||
277 | while (1) | ||
278 | ar5312_rst_reg_write(AR5312_RESET, AR5312_RESET_SYSTEM); | ||
279 | } | ||
280 | |||
281 | /* | ||
282 | * This table is indexed by bits 5..4 of the CLOCKCTL1 register | ||
283 | * to determine the predevisor value. | ||
284 | */ | ||
285 | static unsigned clockctl1_predivide_table[4] __initdata = { 1, 2, 4, 5 }; | ||
286 | |||
287 | static unsigned __init ar5312_cpu_frequency(void) | ||
288 | { | ||
289 | u32 scratch, devid, clock_ctl1; | ||
290 | u32 predivide_mask, multiplier_mask, doubler_mask; | ||
291 | unsigned predivide_shift, multiplier_shift; | ||
292 | unsigned predivide_select, predivisor, multiplier; | ||
293 | |||
294 | /* Trust the bootrom's idea of cpu frequency. */ | ||
295 | scratch = ar5312_rst_reg_read(AR5312_SCRATCH); | ||
296 | if (scratch) | ||
297 | return scratch; | ||
298 | |||
299 | devid = ar5312_rst_reg_read(AR5312_REV); | ||
300 | devid = (devid & AR5312_REV_MAJ) >> AR5312_REV_MAJ_S; | ||
301 | if (devid == AR5312_REV_MAJ_AR2313) { | ||
302 | predivide_mask = AR2313_CLOCKCTL1_PREDIVIDE_MASK; | ||
303 | predivide_shift = AR2313_CLOCKCTL1_PREDIVIDE_SHIFT; | ||
304 | multiplier_mask = AR2313_CLOCKCTL1_MULTIPLIER_MASK; | ||
305 | multiplier_shift = AR2313_CLOCKCTL1_MULTIPLIER_SHIFT; | ||
306 | doubler_mask = AR2313_CLOCKCTL1_DOUBLER_MASK; | ||
307 | } else { /* AR5312 and AR2312 */ | ||
308 | predivide_mask = AR5312_CLOCKCTL1_PREDIVIDE_MASK; | ||
309 | predivide_shift = AR5312_CLOCKCTL1_PREDIVIDE_SHIFT; | ||
310 | multiplier_mask = AR5312_CLOCKCTL1_MULTIPLIER_MASK; | ||
311 | multiplier_shift = AR5312_CLOCKCTL1_MULTIPLIER_SHIFT; | ||
312 | doubler_mask = AR5312_CLOCKCTL1_DOUBLER_MASK; | ||
313 | } | ||
314 | |||
315 | /* | ||
316 | * Clocking is derived from a fixed 40MHz input clock. | ||
317 | * | ||
318 | * cpu_freq = input_clock * MULT (where MULT is PLL multiplier) | ||
319 | * sys_freq = cpu_freq / 4 (used for APB clock, serial, | ||
320 | * flash, Timer, Watchdog Timer) | ||
321 | * | ||
322 | * cnt_freq = cpu_freq / 2 (use for CPU count/compare) | ||
323 | * | ||
324 | * So, for example, with a PLL multiplier of 5, we have | ||
325 | * | ||
326 | * cpu_freq = 200MHz | ||
327 | * sys_freq = 50MHz | ||
328 | * cnt_freq = 100MHz | ||
329 | * | ||
330 | * We compute the CPU frequency, based on PLL settings. | ||
331 | */ | ||
332 | |||
333 | clock_ctl1 = ar5312_rst_reg_read(AR5312_CLOCKCTL1); | ||
334 | predivide_select = (clock_ctl1 & predivide_mask) >> predivide_shift; | ||
335 | predivisor = clockctl1_predivide_table[predivide_select]; | ||
336 | multiplier = (clock_ctl1 & multiplier_mask) >> multiplier_shift; | ||
337 | |||
338 | if (clock_ctl1 & doubler_mask) | ||
339 | multiplier <<= 1; | ||
340 | |||
341 | return (40000000 / predivisor) * multiplier; | ||
342 | } | ||
343 | |||
344 | static inline unsigned ar5312_sys_frequency(void) | ||
345 | { | ||
346 | return ar5312_cpu_frequency() / 4; | ||
347 | } | ||
348 | |||
349 | void __init ar5312_plat_time_init(void) | ||
350 | { | ||
351 | mips_hpt_frequency = ar5312_cpu_frequency() / 2; | ||
352 | } | ||
353 | |||
354 | void __init ar5312_plat_mem_setup(void) | ||
355 | { | ||
356 | void __iomem *sdram_base; | ||
357 | u32 memsize, memcfg, bank0_ac, bank1_ac; | ||
358 | u32 devid; | ||
359 | |||
360 | /* Detect memory size */ | ||
361 | sdram_base = ioremap_nocache(AR5312_SDRAMCTL_BASE, | ||
362 | AR5312_SDRAMCTL_SIZE); | ||
363 | memcfg = __raw_readl(sdram_base + AR5312_MEM_CFG1); | ||
364 | bank0_ac = ATH25_REG_MS(memcfg, AR5312_MEM_CFG1_AC0); | ||
365 | bank1_ac = ATH25_REG_MS(memcfg, AR5312_MEM_CFG1_AC1); | ||
366 | memsize = (bank0_ac ? (1 << (bank0_ac + 1)) : 0) + | ||
367 | (bank1_ac ? (1 << (bank1_ac + 1)) : 0); | ||
368 | memsize <<= 20; | ||
369 | add_memory_region(0, memsize, BOOT_MEM_RAM); | ||
370 | iounmap(sdram_base); | ||
371 | |||
372 | ar5312_rst_base = ioremap_nocache(AR5312_RST_BASE, AR5312_RST_SIZE); | ||
373 | |||
374 | devid = ar5312_rst_reg_read(AR5312_REV); | ||
375 | devid >>= AR5312_REV_WMAC_MIN_S; | ||
376 | devid &= AR5312_REV_CHIP; | ||
377 | ath25_board.devid = (u16)devid; | ||
378 | |||
379 | /* Clear any lingering AHB errors */ | ||
380 | ar5312_rst_reg_read(AR5312_PROCADDR); | ||
381 | ar5312_rst_reg_read(AR5312_DMAADDR); | ||
382 | ar5312_rst_reg_write(AR5312_WDT_CTRL, AR5312_WDT_CTRL_IGNORE); | ||
383 | |||
384 | _machine_restart = ar5312_restart; | ||
385 | } | ||
386 | |||
387 | void __init ar5312_arch_init(void) | ||
388 | { | ||
389 | unsigned irq = irq_create_mapping(ar5312_misc_irq_domain, | ||
390 | AR5312_MISC_IRQ_UART0); | ||
391 | |||
392 | ath25_serial_setup(AR5312_UART0_BASE, irq, ar5312_sys_frequency()); | ||
393 | } | ||
diff --git a/arch/mips/ath25/ar5312.h b/arch/mips/ath25/ar5312.h new file mode 100644 index 000000000000..470abb0052bd --- /dev/null +++ b/arch/mips/ath25/ar5312.h | |||
@@ -0,0 +1,22 @@ | |||
1 | #ifndef __AR5312_H | ||
2 | #define __AR5312_H | ||
3 | |||
4 | #ifdef CONFIG_SOC_AR5312 | ||
5 | |||
6 | void ar5312_arch_init_irq(void); | ||
7 | void ar5312_init_devices(void); | ||
8 | void ar5312_plat_time_init(void); | ||
9 | void ar5312_plat_mem_setup(void); | ||
10 | void ar5312_arch_init(void); | ||
11 | |||
12 | #else | ||
13 | |||
14 | static inline void ar5312_arch_init_irq(void) {} | ||
15 | static inline void ar5312_init_devices(void) {} | ||
16 | static inline void ar5312_plat_time_init(void) {} | ||
17 | static inline void ar5312_plat_mem_setup(void) {} | ||
18 | static inline void ar5312_arch_init(void) {} | ||
19 | |||
20 | #endif | ||
21 | |||
22 | #endif /* __AR5312_H */ | ||
diff --git a/arch/mips/ath25/ar5312_regs.h b/arch/mips/ath25/ar5312_regs.h new file mode 100644 index 000000000000..4b947f967439 --- /dev/null +++ b/arch/mips/ath25/ar5312_regs.h | |||
@@ -0,0 +1,224 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. | ||
7 | * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> | ||
8 | * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> | ||
9 | */ | ||
10 | |||
11 | #ifndef __ASM_MACH_ATH25_AR5312_REGS_H | ||
12 | #define __ASM_MACH_ATH25_AR5312_REGS_H | ||
13 | |||
14 | /* | ||
15 | * IRQs | ||
16 | */ | ||
17 | #define AR5312_IRQ_WLAN0 (MIPS_CPU_IRQ_BASE + 2) /* C0_CAUSE: 0x0400 */ | ||
18 | #define AR5312_IRQ_ENET0 (MIPS_CPU_IRQ_BASE + 3) /* C0_CAUSE: 0x0800 */ | ||
19 | #define AR5312_IRQ_ENET1 (MIPS_CPU_IRQ_BASE + 4) /* C0_CAUSE: 0x1000 */ | ||
20 | #define AR5312_IRQ_WLAN1 (MIPS_CPU_IRQ_BASE + 5) /* C0_CAUSE: 0x2000 */ | ||
21 | #define AR5312_IRQ_MISC (MIPS_CPU_IRQ_BASE + 6) /* C0_CAUSE: 0x4000 */ | ||
22 | |||
23 | /* | ||
24 | * Miscellaneous interrupts, which share IP6. | ||
25 | */ | ||
26 | #define AR5312_MISC_IRQ_TIMER 0 | ||
27 | #define AR5312_MISC_IRQ_AHB_PROC 1 | ||
28 | #define AR5312_MISC_IRQ_AHB_DMA 2 | ||
29 | #define AR5312_MISC_IRQ_GPIO 3 | ||
30 | #define AR5312_MISC_IRQ_UART0 4 | ||
31 | #define AR5312_MISC_IRQ_UART0_DMA 5 | ||
32 | #define AR5312_MISC_IRQ_WATCHDOG 6 | ||
33 | #define AR5312_MISC_IRQ_LOCAL 7 | ||
34 | #define AR5312_MISC_IRQ_SPI 8 | ||
35 | #define AR5312_MISC_IRQ_COUNT 9 | ||
36 | |||
37 | /* | ||
38 | * Address Map | ||
39 | * | ||
40 | * The AR5312 supports 2 enet MACS, even though many reference boards only | ||
41 | * actually use 1 of them (i.e. Only MAC 0 is actually connected to an enet | ||
42 | * PHY or PHY switch. The AR2312 supports 1 enet MAC. | ||
43 | */ | ||
44 | #define AR5312_WLAN0_BASE 0x18000000 | ||
45 | #define AR5312_ENET0_BASE 0x18100000 | ||
46 | #define AR5312_ENET1_BASE 0x18200000 | ||
47 | #define AR5312_SDRAMCTL_BASE 0x18300000 | ||
48 | #define AR5312_SDRAMCTL_SIZE 0x00000010 | ||
49 | #define AR5312_FLASHCTL_BASE 0x18400000 | ||
50 | #define AR5312_FLASHCTL_SIZE 0x00000010 | ||
51 | #define AR5312_WLAN1_BASE 0x18500000 | ||
52 | #define AR5312_UART0_BASE 0x1c000000 /* UART MMR */ | ||
53 | #define AR5312_GPIO_BASE 0x1c002000 | ||
54 | #define AR5312_GPIO_SIZE 0x00000010 | ||
55 | #define AR5312_RST_BASE 0x1c003000 | ||
56 | #define AR5312_RST_SIZE 0x00000100 | ||
57 | #define AR5312_FLASH_BASE 0x1e000000 | ||
58 | #define AR5312_FLASH_SIZE 0x00800000 | ||
59 | |||
60 | /* | ||
61 | * Need these defines to determine true number of ethernet MACs | ||
62 | */ | ||
63 | #define AR5312_AR5312_REV2 0x0052 /* AR5312 WMAC (AP31) */ | ||
64 | #define AR5312_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */ | ||
65 | #define AR5312_AR2313_REV8 0x0058 /* AR2313 WMAC (AP43-030) */ | ||
66 | |||
67 | /* Reset/Timer Block Address Map */ | ||
68 | #define AR5312_TIMER 0x0000 /* countdown timer */ | ||
69 | #define AR5312_RELOAD 0x0004 /* timer reload value */ | ||
70 | #define AR5312_WDT_CTRL 0x0008 /* watchdog cntrl */ | ||
71 | #define AR5312_WDT_TIMER 0x000c /* watchdog timer */ | ||
72 | #define AR5312_ISR 0x0010 /* Intr Status Reg */ | ||
73 | #define AR5312_IMR 0x0014 /* Intr Mask Reg */ | ||
74 | #define AR5312_RESET 0x0020 | ||
75 | #define AR5312_CLOCKCTL1 0x0064 | ||
76 | #define AR5312_SCRATCH 0x006c | ||
77 | #define AR5312_PROCADDR 0x0070 | ||
78 | #define AR5312_PROC1 0x0074 | ||
79 | #define AR5312_DMAADDR 0x0078 | ||
80 | #define AR5312_DMA1 0x007c | ||
81 | #define AR5312_ENABLE 0x0080 /* interface enb */ | ||
82 | #define AR5312_REV 0x0090 /* revision */ | ||
83 | |||
84 | /* AR5312_WDT_CTRL register bit field definitions */ | ||
85 | #define AR5312_WDT_CTRL_IGNORE 0x00000000 /* ignore expiration */ | ||
86 | #define AR5312_WDT_CTRL_NMI 0x00000001 | ||
87 | #define AR5312_WDT_CTRL_RESET 0x00000002 | ||
88 | |||
89 | /* AR5312_ISR register bit field definitions */ | ||
90 | #define AR5312_ISR_TIMER 0x00000001 | ||
91 | #define AR5312_ISR_AHBPROC 0x00000002 | ||
92 | #define AR5312_ISR_AHBDMA 0x00000004 | ||
93 | #define AR5312_ISR_GPIO 0x00000008 | ||
94 | #define AR5312_ISR_UART0 0x00000010 | ||
95 | #define AR5312_ISR_UART0DMA 0x00000020 | ||
96 | #define AR5312_ISR_WD 0x00000040 | ||
97 | #define AR5312_ISR_LOCAL 0x00000080 | ||
98 | |||
99 | /* AR5312_RESET register bit field definitions */ | ||
100 | #define AR5312_RESET_SYSTEM 0x00000001 /* cold reset full system */ | ||
101 | #define AR5312_RESET_PROC 0x00000002 /* cold reset MIPS core */ | ||
102 | #define AR5312_RESET_WLAN0 0x00000004 /* cold reset WLAN MAC/BB */ | ||
103 | #define AR5312_RESET_EPHY0 0x00000008 /* cold reset ENET0 phy */ | ||
104 | #define AR5312_RESET_EPHY1 0x00000010 /* cold reset ENET1 phy */ | ||
105 | #define AR5312_RESET_ENET0 0x00000020 /* cold reset ENET0 MAC */ | ||
106 | #define AR5312_RESET_ENET1 0x00000040 /* cold reset ENET1 MAC */ | ||
107 | #define AR5312_RESET_UART0 0x00000100 /* cold reset UART0 */ | ||
108 | #define AR5312_RESET_WLAN1 0x00000200 /* cold reset WLAN MAC/BB */ | ||
109 | #define AR5312_RESET_APB 0x00000400 /* cold reset APB ar5312 */ | ||
110 | #define AR5312_RESET_WARM_PROC 0x00001000 /* warm reset MIPS core */ | ||
111 | #define AR5312_RESET_WARM_WLAN0_MAC 0x00002000 /* warm reset WLAN0 MAC */ | ||
112 | #define AR5312_RESET_WARM_WLAN0_BB 0x00004000 /* warm reset WLAN0 BB */ | ||
113 | #define AR5312_RESET_NMI 0x00010000 /* send an NMI to the CPU */ | ||
114 | #define AR5312_RESET_WARM_WLAN1_MAC 0x00020000 /* warm reset WLAN1 MAC */ | ||
115 | #define AR5312_RESET_WARM_WLAN1_BB 0x00040000 /* warm reset WLAN1 BB */ | ||
116 | #define AR5312_RESET_LOCAL_BUS 0x00080000 /* reset local bus */ | ||
117 | #define AR5312_RESET_WDOG 0x00100000 /* last reset was a wdt */ | ||
118 | |||
119 | #define AR5312_RESET_WMAC0_BITS (AR5312_RESET_WLAN0 |\ | ||
120 | AR5312_RESET_WARM_WLAN0_MAC |\ | ||
121 | AR5312_RESET_WARM_WLAN0_BB) | ||
122 | |||
123 | #define AR5312_RESET_WMAC1_BITS (AR5312_RESET_WLAN1 |\ | ||
124 | AR5312_RESET_WARM_WLAN1_MAC |\ | ||
125 | AR5312_RESET_WARM_WLAN1_BB) | ||
126 | |||
127 | /* AR5312_CLOCKCTL1 register bit field definitions */ | ||
128 | #define AR5312_CLOCKCTL1_PREDIVIDE_MASK 0x00000030 | ||
129 | #define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT 4 | ||
130 | #define AR5312_CLOCKCTL1_MULTIPLIER_MASK 0x00001f00 | ||
131 | #define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT 8 | ||
132 | #define AR5312_CLOCKCTL1_DOUBLER_MASK 0x00010000 | ||
133 | |||
134 | /* Valid for AR5312 and AR2312 */ | ||
135 | #define AR5312_CLOCKCTL1_PREDIVIDE_MASK 0x00000030 | ||
136 | #define AR5312_CLOCKCTL1_PREDIVIDE_SHIFT 4 | ||
137 | #define AR5312_CLOCKCTL1_MULTIPLIER_MASK 0x00001f00 | ||
138 | #define AR5312_CLOCKCTL1_MULTIPLIER_SHIFT 8 | ||
139 | #define AR5312_CLOCKCTL1_DOUBLER_MASK 0x00010000 | ||
140 | |||
141 | /* Valid for AR2313 */ | ||
142 | #define AR2313_CLOCKCTL1_PREDIVIDE_MASK 0x00003000 | ||
143 | #define AR2313_CLOCKCTL1_PREDIVIDE_SHIFT 12 | ||
144 | #define AR2313_CLOCKCTL1_MULTIPLIER_MASK 0x001f0000 | ||
145 | #define AR2313_CLOCKCTL1_MULTIPLIER_SHIFT 16 | ||
146 | #define AR2313_CLOCKCTL1_DOUBLER_MASK 0x00000000 | ||
147 | |||
148 | /* AR5312_ENABLE register bit field definitions */ | ||
149 | #define AR5312_ENABLE_WLAN0 0x00000001 | ||
150 | #define AR5312_ENABLE_ENET0 0x00000002 | ||
151 | #define AR5312_ENABLE_ENET1 0x00000004 | ||
152 | #define AR5312_ENABLE_UART_AND_WLAN1_PIO 0x00000008/* UART & WLAN1 PIO */ | ||
153 | #define AR5312_ENABLE_WLAN1_DMA 0x00000010/* WLAN1 DMAs */ | ||
154 | #define AR5312_ENABLE_WLAN1 (AR5312_ENABLE_UART_AND_WLAN1_PIO |\ | ||
155 | AR5312_ENABLE_WLAN1_DMA) | ||
156 | |||
157 | /* AR5312_REV register bit field definitions */ | ||
158 | #define AR5312_REV_WMAC_MAJ 0x0000f000 | ||
159 | #define AR5312_REV_WMAC_MAJ_S 12 | ||
160 | #define AR5312_REV_WMAC_MIN 0x00000f00 | ||
161 | #define AR5312_REV_WMAC_MIN_S 8 | ||
162 | #define AR5312_REV_MAJ 0x000000f0 | ||
163 | #define AR5312_REV_MAJ_S 4 | ||
164 | #define AR5312_REV_MIN 0x0000000f | ||
165 | #define AR5312_REV_MIN_S 0 | ||
166 | #define AR5312_REV_CHIP (AR5312_REV_MAJ|AR5312_REV_MIN) | ||
167 | |||
168 | /* Major revision numbers, bits 7..4 of Revision ID register */ | ||
169 | #define AR5312_REV_MAJ_AR5312 0x4 | ||
170 | #define AR5312_REV_MAJ_AR2313 0x5 | ||
171 | |||
172 | /* Minor revision numbers, bits 3..0 of Revision ID register */ | ||
173 | #define AR5312_REV_MIN_DUAL 0x0 /* Dual WLAN version */ | ||
174 | #define AR5312_REV_MIN_SINGLE 0x1 /* Single WLAN version */ | ||
175 | |||
176 | /* | ||
177 | * ARM Flash Controller -- 3 flash banks with either x8 or x16 devices | ||
178 | */ | ||
179 | #define AR5312_FLASHCTL0 0x0000 | ||
180 | #define AR5312_FLASHCTL1 0x0004 | ||
181 | #define AR5312_FLASHCTL2 0x0008 | ||
182 | |||
183 | /* AR5312_FLASHCTL register bit field definitions */ | ||
184 | #define AR5312_FLASHCTL_IDCY 0x0000000f /* Idle cycle turnaround time */ | ||
185 | #define AR5312_FLASHCTL_IDCY_S 0 | ||
186 | #define AR5312_FLASHCTL_WST1 0x000003e0 /* Wait state 1 */ | ||
187 | #define AR5312_FLASHCTL_WST1_S 5 | ||
188 | #define AR5312_FLASHCTL_RBLE 0x00000400 /* Read byte lane enable */ | ||
189 | #define AR5312_FLASHCTL_WST2 0x0000f800 /* Wait state 2 */ | ||
190 | #define AR5312_FLASHCTL_WST2_S 11 | ||
191 | #define AR5312_FLASHCTL_AC 0x00070000 /* Flash addr check (added) */ | ||
192 | #define AR5312_FLASHCTL_AC_S 16 | ||
193 | #define AR5312_FLASHCTL_AC_128K 0x00000000 | ||
194 | #define AR5312_FLASHCTL_AC_256K 0x00010000 | ||
195 | #define AR5312_FLASHCTL_AC_512K 0x00020000 | ||
196 | #define AR5312_FLASHCTL_AC_1M 0x00030000 | ||
197 | #define AR5312_FLASHCTL_AC_2M 0x00040000 | ||
198 | #define AR5312_FLASHCTL_AC_4M 0x00050000 | ||
199 | #define AR5312_FLASHCTL_AC_8M 0x00060000 | ||
200 | #define AR5312_FLASHCTL_AC_RES 0x00070000 /* 16MB is not supported */ | ||
201 | #define AR5312_FLASHCTL_E 0x00080000 /* Flash bank enable (added) */ | ||
202 | #define AR5312_FLASHCTL_BUSERR 0x01000000 /* Bus transfer error flag */ | ||
203 | #define AR5312_FLASHCTL_WPERR 0x02000000 /* Write protect error flag */ | ||
204 | #define AR5312_FLASHCTL_WP 0x04000000 /* Write protect */ | ||
205 | #define AR5312_FLASHCTL_BM 0x08000000 /* Burst mode */ | ||
206 | #define AR5312_FLASHCTL_MW 0x30000000 /* Mem width */ | ||
207 | #define AR5312_FLASHCTL_MW8 0x00000000 /* Mem width x8 */ | ||
208 | #define AR5312_FLASHCTL_MW16 0x10000000 /* Mem width x16 */ | ||
209 | #define AR5312_FLASHCTL_MW32 0x20000000 /* Mem width x32 (not supp) */ | ||
210 | #define AR5312_FLASHCTL_ATNR 0x00000000 /* Access == no retry */ | ||
211 | #define AR5312_FLASHCTL_ATR 0x80000000 /* Access == retry every */ | ||
212 | #define AR5312_FLASHCTL_ATR4 0xc0000000 /* Access == retry every 4 */ | ||
213 | |||
214 | /* | ||
215 | * ARM SDRAM Controller -- just enough to determine memory size | ||
216 | */ | ||
217 | #define AR5312_MEM_CFG1 0x0004 | ||
218 | |||
219 | #define AR5312_MEM_CFG1_AC0_M 0x00000700 /* bank 0: SDRAM addr check */ | ||
220 | #define AR5312_MEM_CFG1_AC0_S 8 | ||
221 | #define AR5312_MEM_CFG1_AC1_M 0x00007000 /* bank 1: SDRAM addr check */ | ||
222 | #define AR5312_MEM_CFG1_AC1_S 12 | ||
223 | |||
224 | #endif /* __ASM_MACH_ATH25_AR5312_REGS_H */ | ||
diff --git a/arch/mips/ath25/board.c b/arch/mips/ath25/board.c new file mode 100644 index 000000000000..b8bb78282d6a --- /dev/null +++ b/arch/mips/ath25/board.c | |||
@@ -0,0 +1,234 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. | ||
7 | * Copyright (C) 2006 FON Technology, SL. | ||
8 | * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> | ||
9 | * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org> | ||
10 | */ | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <asm/irq_cpu.h> | ||
15 | #include <asm/reboot.h> | ||
16 | #include <asm/bootinfo.h> | ||
17 | #include <asm/time.h> | ||
18 | |||
19 | #include <ath25_platform.h> | ||
20 | #include "devices.h" | ||
21 | #include "ar5312.h" | ||
22 | #include "ar2315.h" | ||
23 | |||
24 | void (*ath25_irq_dispatch)(void); | ||
25 | |||
26 | static inline bool check_radio_magic(const void __iomem *addr) | ||
27 | { | ||
28 | addr += 0x7a; /* offset for flash magic */ | ||
29 | return (__raw_readb(addr) == 0x5a) && (__raw_readb(addr + 1) == 0xa5); | ||
30 | } | ||
31 | |||
32 | static inline bool check_notempty(const void __iomem *addr) | ||
33 | { | ||
34 | return __raw_readl(addr) != 0xffffffff; | ||
35 | } | ||
36 | |||
37 | static inline bool check_board_data(const void __iomem *addr, bool broken) | ||
38 | { | ||
39 | /* config magic found */ | ||
40 | if (__raw_readl(addr) == ATH25_BD_MAGIC) | ||
41 | return true; | ||
42 | |||
43 | if (!broken) | ||
44 | return false; | ||
45 | |||
46 | /* broken board data detected, use radio data to find the | ||
47 | * offset, user will fix this */ | ||
48 | |||
49 | if (check_radio_magic(addr + 0x1000)) | ||
50 | return true; | ||
51 | if (check_radio_magic(addr + 0xf8)) | ||
52 | return true; | ||
53 | |||
54 | return false; | ||
55 | } | ||
56 | |||
57 | static const void __iomem * __init find_board_config(const void __iomem *limit, | ||
58 | const bool broken) | ||
59 | { | ||
60 | const void __iomem *addr; | ||
61 | const void __iomem *begin = limit - 0x1000; | ||
62 | const void __iomem *end = limit - 0x30000; | ||
63 | |||
64 | for (addr = begin; addr >= end; addr -= 0x1000) | ||
65 | if (check_board_data(addr, broken)) | ||
66 | return addr; | ||
67 | |||
68 | return NULL; | ||
69 | } | ||
70 | |||
71 | static const void __iomem * __init find_radio_config(const void __iomem *limit, | ||
72 | const void __iomem *bcfg) | ||
73 | { | ||
74 | const void __iomem *rcfg, *begin, *end; | ||
75 | |||
76 | /* | ||
77 | * Now find the start of Radio Configuration data, using heuristics: | ||
78 | * Search forward from Board Configuration data by 0x1000 bytes | ||
79 | * at a time until we find non-0xffffffff. | ||
80 | */ | ||
81 | begin = bcfg + 0x1000; | ||
82 | end = limit; | ||
83 | for (rcfg = begin; rcfg < end; rcfg += 0x1000) | ||
84 | if (check_notempty(rcfg) && check_radio_magic(rcfg)) | ||
85 | return rcfg; | ||
86 | |||
87 | /* AR2316 relocates radio config to new location */ | ||
88 | begin = bcfg + 0xf8; | ||
89 | end = limit - 0x1000 + 0xf8; | ||
90 | for (rcfg = begin; rcfg < end; rcfg += 0x1000) | ||
91 | if (check_notempty(rcfg) && check_radio_magic(rcfg)) | ||
92 | return rcfg; | ||
93 | |||
94 | return NULL; | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | * NB: Search region size could be larger than the actual flash size, | ||
99 | * but this shouldn't be a problem here, because the flash | ||
100 | * will simply be mapped multiple times. | ||
101 | */ | ||
102 | int __init ath25_find_config(phys_addr_t base, unsigned long size) | ||
103 | { | ||
104 | const void __iomem *flash_base, *flash_limit; | ||
105 | struct ath25_boarddata *config; | ||
106 | unsigned int rcfg_size; | ||
107 | int broken_boarddata = 0; | ||
108 | const void __iomem *bcfg, *rcfg; | ||
109 | u8 *board_data; | ||
110 | u8 *radio_data; | ||
111 | u8 *mac_addr; | ||
112 | u32 offset; | ||
113 | |||
114 | flash_base = ioremap_nocache(base, size); | ||
115 | flash_limit = flash_base + size; | ||
116 | |||
117 | ath25_board.config = NULL; | ||
118 | ath25_board.radio = NULL; | ||
119 | |||
120 | /* Copy the board and radio data to RAM, because accessing the mapped | ||
121 | * memory of the flash directly after booting is not safe */ | ||
122 | |||
123 | /* Try to find valid board and radio data */ | ||
124 | bcfg = find_board_config(flash_limit, false); | ||
125 | |||
126 | /* If that fails, try to at least find valid radio data */ | ||
127 | if (!bcfg) { | ||
128 | bcfg = find_board_config(flash_limit, true); | ||
129 | broken_boarddata = 1; | ||
130 | } | ||
131 | |||
132 | if (!bcfg) { | ||
133 | pr_warn("WARNING: No board configuration data found!\n"); | ||
134 | goto error; | ||
135 | } | ||
136 | |||
137 | board_data = kzalloc(BOARD_CONFIG_BUFSZ, GFP_KERNEL); | ||
138 | ath25_board.config = (struct ath25_boarddata *)board_data; | ||
139 | memcpy_fromio(board_data, bcfg, 0x100); | ||
140 | if (broken_boarddata) { | ||
141 | pr_warn("WARNING: broken board data detected\n"); | ||
142 | config = ath25_board.config; | ||
143 | if (is_zero_ether_addr(config->enet0_mac)) { | ||
144 | pr_info("Fixing up empty mac addresses\n"); | ||
145 | config->reset_config_gpio = 0xffff; | ||
146 | config->sys_led_gpio = 0xffff; | ||
147 | random_ether_addr(config->wlan0_mac); | ||
148 | config->wlan0_mac[0] &= ~0x06; | ||
149 | random_ether_addr(config->enet0_mac); | ||
150 | random_ether_addr(config->enet1_mac); | ||
151 | } | ||
152 | } | ||
153 | |||
154 | /* Radio config starts 0x100 bytes after board config, regardless | ||
155 | * of what the physical layout on the flash chip looks like */ | ||
156 | |||
157 | rcfg = find_radio_config(flash_limit, bcfg); | ||
158 | if (!rcfg) { | ||
159 | pr_warn("WARNING: Could not find Radio Configuration data\n"); | ||
160 | goto error; | ||
161 | } | ||
162 | |||
163 | radio_data = board_data + 0x100 + ((rcfg - bcfg) & 0xfff); | ||
164 | ath25_board.radio = radio_data; | ||
165 | offset = radio_data - board_data; | ||
166 | pr_info("Radio config found at offset 0x%x (0x%x)\n", rcfg - bcfg, | ||
167 | offset); | ||
168 | rcfg_size = BOARD_CONFIG_BUFSZ - offset; | ||
169 | memcpy_fromio(radio_data, rcfg, rcfg_size); | ||
170 | |||
171 | mac_addr = &radio_data[0x1d * 2]; | ||
172 | if (is_broadcast_ether_addr(mac_addr)) { | ||
173 | pr_info("Radio MAC is blank; using board-data\n"); | ||
174 | ether_addr_copy(mac_addr, ath25_board.config->wlan0_mac); | ||
175 | } | ||
176 | |||
177 | iounmap(flash_base); | ||
178 | |||
179 | return 0; | ||
180 | |||
181 | error: | ||
182 | iounmap(flash_base); | ||
183 | return -ENODEV; | ||
184 | } | ||
185 | |||
186 | static void ath25_halt(void) | ||
187 | { | ||
188 | local_irq_disable(); | ||
189 | unreachable(); | ||
190 | } | ||
191 | |||
192 | void __init plat_mem_setup(void) | ||
193 | { | ||
194 | _machine_halt = ath25_halt; | ||
195 | pm_power_off = ath25_halt; | ||
196 | |||
197 | if (is_ar5312()) | ||
198 | ar5312_plat_mem_setup(); | ||
199 | else | ||
200 | ar2315_plat_mem_setup(); | ||
201 | |||
202 | /* Disable data watchpoints */ | ||
203 | write_c0_watchlo0(0); | ||
204 | } | ||
205 | |||
206 | asmlinkage void plat_irq_dispatch(void) | ||
207 | { | ||
208 | ath25_irq_dispatch(); | ||
209 | } | ||
210 | |||
211 | void __init plat_time_init(void) | ||
212 | { | ||
213 | if (is_ar5312()) | ||
214 | ar5312_plat_time_init(); | ||
215 | else | ||
216 | ar2315_plat_time_init(); | ||
217 | } | ||
218 | |||
219 | unsigned int __cpuinit get_c0_compare_int(void) | ||
220 | { | ||
221 | return CP0_LEGACY_COMPARE_IRQ; | ||
222 | } | ||
223 | |||
224 | void __init arch_init_irq(void) | ||
225 | { | ||
226 | clear_c0_status(ST0_IM); | ||
227 | mips_cpu_irq_init(); | ||
228 | |||
229 | /* Initialize interrupt controllers */ | ||
230 | if (is_ar5312()) | ||
231 | ar5312_arch_init_irq(); | ||
232 | else | ||
233 | ar2315_arch_init_irq(); | ||
234 | } | ||
diff --git a/arch/mips/ath25/devices.c b/arch/mips/ath25/devices.c new file mode 100644 index 000000000000..7a64567d1ac3 --- /dev/null +++ b/arch/mips/ath25/devices.c | |||
@@ -0,0 +1,125 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | #include <linux/init.h> | ||
3 | #include <linux/serial_8250.h> | ||
4 | #include <linux/platform_device.h> | ||
5 | #include <asm/bootinfo.h> | ||
6 | |||
7 | #include <ath25_platform.h> | ||
8 | #include "devices.h" | ||
9 | #include "ar5312.h" | ||
10 | #include "ar2315.h" | ||
11 | |||
12 | struct ar231x_board_config ath25_board; | ||
13 | enum ath25_soc_type ath25_soc = ATH25_SOC_UNKNOWN; | ||
14 | |||
15 | static struct resource ath25_wmac0_res[] = { | ||
16 | { | ||
17 | .name = "wmac0_membase", | ||
18 | .flags = IORESOURCE_MEM, | ||
19 | }, | ||
20 | { | ||
21 | .name = "wmac0_irq", | ||
22 | .flags = IORESOURCE_IRQ, | ||
23 | } | ||
24 | }; | ||
25 | |||
26 | static struct resource ath25_wmac1_res[] = { | ||
27 | { | ||
28 | .name = "wmac1_membase", | ||
29 | .flags = IORESOURCE_MEM, | ||
30 | }, | ||
31 | { | ||
32 | .name = "wmac1_irq", | ||
33 | .flags = IORESOURCE_IRQ, | ||
34 | } | ||
35 | }; | ||
36 | |||
37 | static struct platform_device ath25_wmac[] = { | ||
38 | { | ||
39 | .id = 0, | ||
40 | .name = "ar231x-wmac", | ||
41 | .resource = ath25_wmac0_res, | ||
42 | .num_resources = ARRAY_SIZE(ath25_wmac0_res), | ||
43 | .dev.platform_data = &ath25_board, | ||
44 | }, | ||
45 | { | ||
46 | .id = 1, | ||
47 | .name = "ar231x-wmac", | ||
48 | .resource = ath25_wmac1_res, | ||
49 | .num_resources = ARRAY_SIZE(ath25_wmac1_res), | ||
50 | .dev.platform_data = &ath25_board, | ||
51 | }, | ||
52 | }; | ||
53 | |||
54 | static const char * const soc_type_strings[] = { | ||
55 | [ATH25_SOC_AR5312] = "Atheros AR5312", | ||
56 | [ATH25_SOC_AR2312] = "Atheros AR2312", | ||
57 | [ATH25_SOC_AR2313] = "Atheros AR2313", | ||
58 | [ATH25_SOC_AR2315] = "Atheros AR2315", | ||
59 | [ATH25_SOC_AR2316] = "Atheros AR2316", | ||
60 | [ATH25_SOC_AR2317] = "Atheros AR2317", | ||
61 | [ATH25_SOC_AR2318] = "Atheros AR2318", | ||
62 | [ATH25_SOC_UNKNOWN] = "Atheros (unknown)", | ||
63 | }; | ||
64 | |||
65 | const char *get_system_type(void) | ||
66 | { | ||
67 | if ((ath25_soc >= ARRAY_SIZE(soc_type_strings)) || | ||
68 | !soc_type_strings[ath25_soc]) | ||
69 | return soc_type_strings[ATH25_SOC_UNKNOWN]; | ||
70 | return soc_type_strings[ath25_soc]; | ||
71 | } | ||
72 | |||
73 | void __init ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk) | ||
74 | { | ||
75 | struct uart_port s; | ||
76 | |||
77 | memset(&s, 0, sizeof(s)); | ||
78 | |||
79 | s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP; | ||
80 | s.iotype = UPIO_MEM32; | ||
81 | s.irq = irq; | ||
82 | s.regshift = 2; | ||
83 | s.mapbase = mapbase; | ||
84 | s.uartclk = uartclk; | ||
85 | |||
86 | early_serial_setup(&s); | ||
87 | } | ||
88 | |||
89 | int __init ath25_add_wmac(int nr, u32 base, int irq) | ||
90 | { | ||
91 | struct resource *res; | ||
92 | |||
93 | ath25_wmac[nr].dev.platform_data = &ath25_board; | ||
94 | res = &ath25_wmac[nr].resource[0]; | ||
95 | res->start = base; | ||
96 | res->end = base + 0x10000 - 1; | ||
97 | res++; | ||
98 | res->start = irq; | ||
99 | res->end = irq; | ||
100 | return platform_device_register(&ath25_wmac[nr]); | ||
101 | } | ||
102 | |||
103 | static int __init ath25_register_devices(void) | ||
104 | { | ||
105 | if (is_ar5312()) | ||
106 | ar5312_init_devices(); | ||
107 | else | ||
108 | ar2315_init_devices(); | ||
109 | |||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | device_initcall(ath25_register_devices); | ||
114 | |||
115 | static int __init ath25_arch_init(void) | ||
116 | { | ||
117 | if (is_ar5312()) | ||
118 | ar5312_arch_init(); | ||
119 | else | ||
120 | ar2315_arch_init(); | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | arch_initcall(ath25_arch_init); | ||
diff --git a/arch/mips/ath25/devices.h b/arch/mips/ath25/devices.h new file mode 100644 index 000000000000..04d414115356 --- /dev/null +++ b/arch/mips/ath25/devices.h | |||
@@ -0,0 +1,43 @@ | |||
1 | #ifndef __ATH25_DEVICES_H | ||
2 | #define __ATH25_DEVICES_H | ||
3 | |||
4 | #include <linux/cpu.h> | ||
5 | |||
6 | #define ATH25_REG_MS(_val, _field) (((_val) & _field##_M) >> _field##_S) | ||
7 | |||
8 | #define ATH25_IRQ_CPU_CLOCK (MIPS_CPU_IRQ_BASE + 7) /* C0_CAUSE: 0x8000 */ | ||
9 | |||
10 | enum ath25_soc_type { | ||
11 | /* handled by ar5312.c */ | ||
12 | ATH25_SOC_AR2312, | ||
13 | ATH25_SOC_AR2313, | ||
14 | ATH25_SOC_AR5312, | ||
15 | |||
16 | /* handled by ar2315.c */ | ||
17 | ATH25_SOC_AR2315, | ||
18 | ATH25_SOC_AR2316, | ||
19 | ATH25_SOC_AR2317, | ||
20 | ATH25_SOC_AR2318, | ||
21 | |||
22 | ATH25_SOC_UNKNOWN | ||
23 | }; | ||
24 | |||
25 | extern enum ath25_soc_type ath25_soc; | ||
26 | extern struct ar231x_board_config ath25_board; | ||
27 | extern void (*ath25_irq_dispatch)(void); | ||
28 | |||
29 | int ath25_find_config(phys_addr_t offset, unsigned long size); | ||
30 | void ath25_serial_setup(u32 mapbase, int irq, unsigned int uartclk); | ||
31 | int ath25_add_wmac(int nr, u32 base, int irq); | ||
32 | |||
33 | static inline bool is_ar2315(void) | ||
34 | { | ||
35 | return (current_cpu_data.cputype == CPU_4KEC); | ||
36 | } | ||
37 | |||
38 | static inline bool is_ar5312(void) | ||
39 | { | ||
40 | return !is_ar2315(); | ||
41 | } | ||
42 | |||
43 | #endif | ||
diff --git a/arch/mips/ath25/early_printk.c b/arch/mips/ath25/early_printk.c new file mode 100644 index 000000000000..36035b628161 --- /dev/null +++ b/arch/mips/ath25/early_printk.c | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/mm.h> | ||
10 | #include <linux/io.h> | ||
11 | #include <linux/serial_reg.h> | ||
12 | |||
13 | #include "devices.h" | ||
14 | #include "ar2315_regs.h" | ||
15 | #include "ar5312_regs.h" | ||
16 | |||
17 | static inline void prom_uart_wr(void __iomem *base, unsigned reg, | ||
18 | unsigned char ch) | ||
19 | { | ||
20 | __raw_writel(ch, base + 4 * reg); | ||
21 | } | ||
22 | |||
23 | static inline unsigned char prom_uart_rr(void __iomem *base, unsigned reg) | ||
24 | { | ||
25 | return __raw_readl(base + 4 * reg); | ||
26 | } | ||
27 | |||
28 | void prom_putchar(unsigned char ch) | ||
29 | { | ||
30 | static void __iomem *base; | ||
31 | |||
32 | if (unlikely(base == NULL)) { | ||
33 | if (is_ar2315()) | ||
34 | base = (void __iomem *)(KSEG1ADDR(AR2315_UART0_BASE)); | ||
35 | else | ||
36 | base = (void __iomem *)(KSEG1ADDR(AR5312_UART0_BASE)); | ||
37 | } | ||
38 | |||
39 | while ((prom_uart_rr(base, UART_LSR) & UART_LSR_THRE) == 0) | ||
40 | ; | ||
41 | prom_uart_wr(base, UART_TX, ch); | ||
42 | while ((prom_uart_rr(base, UART_LSR) & UART_LSR_THRE) == 0) | ||
43 | ; | ||
44 | } | ||
diff --git a/arch/mips/ath25/prom.c b/arch/mips/ath25/prom.c new file mode 100644 index 000000000000..edf82be8870d --- /dev/null +++ b/arch/mips/ath25/prom.c | |||
@@ -0,0 +1,26 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright MontaVista Software Inc | ||
7 | * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved. | ||
8 | * Copyright (C) 2006 FON Technology, SL. | ||
9 | * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org> | ||
10 | * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> | ||
11 | */ | ||
12 | |||
13 | /* | ||
14 | * Prom setup file for AR5312/AR231x SoCs | ||
15 | */ | ||
16 | |||
17 | #include <linux/init.h> | ||
18 | #include <asm/bootinfo.h> | ||
19 | |||
20 | void __init prom_init(void) | ||
21 | { | ||
22 | } | ||
23 | |||
24 | void __init prom_free_prom_memory(void) | ||
25 | { | ||
26 | } | ||
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c index 9c0e1761773f..6adae366f11a 100644 --- a/arch/mips/ath79/irq.c +++ b/arch/mips/ath79/irq.c | |||
@@ -359,7 +359,6 @@ void __init arch_init_irq(void) | |||
359 | BUG(); | 359 | BUG(); |
360 | } | 360 | } |
361 | 361 | ||
362 | cp0_perfcount_irq = ATH79_MISC_IRQ(5); | ||
363 | mips_cpu_irq_init(); | 362 | mips_cpu_irq_init(); |
364 | ath79_misc_irq_init(); | 363 | ath79_misc_irq_init(); |
365 | 364 | ||
diff --git a/arch/mips/ath79/prom.c b/arch/mips/ath79/prom.c index e9cbd7c2918f..e1fe63051136 100644 --- a/arch/mips/ath79/prom.c +++ b/arch/mips/ath79/prom.c | |||
@@ -13,42 +13,24 @@ | |||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <linux/string.h> | 15 | #include <linux/string.h> |
16 | #include <linux/initrd.h> | ||
16 | 17 | ||
17 | #include <asm/bootinfo.h> | 18 | #include <asm/bootinfo.h> |
18 | #include <asm/addrspace.h> | 19 | #include <asm/addrspace.h> |
20 | #include <asm/fw/fw.h> | ||
19 | 21 | ||
20 | #include "common.h" | 22 | #include "common.h" |
21 | 23 | ||
22 | static inline int is_valid_ram_addr(void *addr) | ||
23 | { | ||
24 | if (((u32) addr > KSEG0) && | ||
25 | ((u32) addr < (KSEG0 + ATH79_MEM_SIZE_MAX))) | ||
26 | return 1; | ||
27 | |||
28 | if (((u32) addr > KSEG1) && | ||
29 | ((u32) addr < (KSEG1 + ATH79_MEM_SIZE_MAX))) | ||
30 | return 1; | ||
31 | |||
32 | return 0; | ||
33 | } | ||
34 | |||
35 | static __init void ath79_prom_init_cmdline(int argc, char **argv) | ||
36 | { | ||
37 | int i; | ||
38 | |||
39 | if (!is_valid_ram_addr(argv)) | ||
40 | return; | ||
41 | |||
42 | for (i = 0; i < argc; i++) | ||
43 | if (is_valid_ram_addr(argv[i])) { | ||
44 | strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); | ||
45 | strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline)); | ||
46 | } | ||
47 | } | ||
48 | |||
49 | void __init prom_init(void) | 24 | void __init prom_init(void) |
50 | { | 25 | { |
51 | ath79_prom_init_cmdline(fw_arg0, (char **)fw_arg1); | 26 | fw_init_cmdline(); |
27 | |||
28 | /* Read the initrd address from the firmware environment */ | ||
29 | initrd_start = fw_getenvl("initrd_start"); | ||
30 | if (initrd_start) { | ||
31 | initrd_start = KSEG0ADDR(initrd_start); | ||
32 | initrd_end = initrd_start + fw_getenvl("initrd_size"); | ||
33 | } | ||
52 | } | 34 | } |
53 | 35 | ||
54 | void __init prom_free_prom_memory(void) | 36 | void __init prom_free_prom_memory(void) |
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c index 64807a4809d0..a73c93c3d44a 100644 --- a/arch/mips/ath79/setup.c +++ b/arch/mips/ath79/setup.c | |||
@@ -182,6 +182,11 @@ const char *get_system_type(void) | |||
182 | return ath79_sys_type; | 182 | return ath79_sys_type; |
183 | } | 183 | } |
184 | 184 | ||
185 | int get_c0_perfcount_int(void) | ||
186 | { | ||
187 | return ATH79_MISC_IRQ(5); | ||
188 | } | ||
189 | |||
185 | unsigned int get_c0_compare_int(void) | 190 | unsigned int get_c0_compare_int(void) |
186 | { | 191 | { |
187 | return CP0_LEGACY_COMPARE_IRQ; | 192 | return CP0_LEGACY_COMPARE_IRQ; |
diff --git a/arch/mips/bcm3384/Makefile b/arch/mips/bcm3384/Makefile new file mode 100644 index 000000000000..a393955cba08 --- /dev/null +++ b/arch/mips/bcm3384/Makefile | |||
@@ -0,0 +1 @@ | |||
obj-y += setup.o irq.o dma.o | |||
diff --git a/arch/mips/bcm3384/Platform b/arch/mips/bcm3384/Platform new file mode 100644 index 000000000000..8e1ca0819e1b --- /dev/null +++ b/arch/mips/bcm3384/Platform | |||
@@ -0,0 +1,7 @@ | |||
1 | # | ||
2 | # Broadcom BCM3384 boards | ||
3 | # | ||
4 | platform-$(CONFIG_BCM3384) += bcm3384/ | ||
5 | cflags-$(CONFIG_BCM3384) += \ | ||
6 | -I$(srctree)/arch/mips/include/asm/mach-bcm3384/ | ||
7 | load-$(CONFIG_BCM3384) := 0xffffffff80010000 | ||
diff --git a/arch/mips/bcm3384/dma.c b/arch/mips/bcm3384/dma.c new file mode 100644 index 000000000000..ea42012fd4f5 --- /dev/null +++ b/arch/mips/bcm3384/dma.c | |||
@@ -0,0 +1,81 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com> | ||
7 | */ | ||
8 | |||
9 | #include <linux/device.h> | ||
10 | #include <linux/dma-direction.h> | ||
11 | #include <linux/dma-mapping.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/mm.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/pci.h> | ||
16 | #include <linux/types.h> | ||
17 | #include <dma-coherence.h> | ||
18 | |||
19 | /* | ||
20 | * BCM3384 has configurable address translation windows which allow the | ||
21 | * peripherals' DMA addresses to be different from the Zephyr-visible | ||
22 | * physical addresses. e.g. usb_dma_addr = zephyr_pa ^ 0x08000000 | ||
23 | * | ||
24 | * If our DT "memory" node has a "dma-xor-mask" property we will enable this | ||
25 | * translation using the provided offset. | ||
26 | */ | ||
27 | static u32 bcm3384_dma_xor_mask; | ||
28 | static u32 bcm3384_dma_xor_limit = 0xffffffff; | ||
29 | |||
30 | /* | ||
31 | * PCI collapses the memory hole at 0x10000000 - 0x1fffffff. | ||
32 | * On systems with a dma-xor-mask, this range is guaranteed to live above | ||
33 | * the dma-xor-limit. | ||
34 | */ | ||
35 | #define BCM3384_MEM_HOLE_PA 0x10000000 | ||
36 | #define BCM3384_MEM_HOLE_SIZE 0x10000000 | ||
37 | |||
38 | static dma_addr_t bcm3384_phys_to_dma(struct device *dev, phys_addr_t pa) | ||
39 | { | ||
40 | if (dev && dev_is_pci(dev) && | ||
41 | pa >= (BCM3384_MEM_HOLE_PA + BCM3384_MEM_HOLE_SIZE)) | ||
42 | return pa - BCM3384_MEM_HOLE_SIZE; | ||
43 | if (pa <= bcm3384_dma_xor_limit) | ||
44 | return pa ^ bcm3384_dma_xor_mask; | ||
45 | return pa; | ||
46 | } | ||
47 | |||
48 | dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size) | ||
49 | { | ||
50 | return bcm3384_phys_to_dma(dev, virt_to_phys(addr)); | ||
51 | } | ||
52 | |||
53 | dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page) | ||
54 | { | ||
55 | return bcm3384_phys_to_dma(dev, page_to_phys(page)); | ||
56 | } | ||
57 | |||
58 | unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) | ||
59 | { | ||
60 | if (dev && dev_is_pci(dev) && | ||
61 | dma_addr >= BCM3384_MEM_HOLE_PA) | ||
62 | return dma_addr + BCM3384_MEM_HOLE_SIZE; | ||
63 | if ((dma_addr ^ bcm3384_dma_xor_mask) <= bcm3384_dma_xor_limit) | ||
64 | return dma_addr ^ bcm3384_dma_xor_mask; | ||
65 | return dma_addr; | ||
66 | } | ||
67 | |||
68 | static int __init bcm3384_init_dma_xor(void) | ||
69 | { | ||
70 | struct device_node *np = of_find_node_by_type(NULL, "memory"); | ||
71 | |||
72 | if (!np) | ||
73 | return 0; | ||
74 | |||
75 | of_property_read_u32(np, "dma-xor-mask", &bcm3384_dma_xor_mask); | ||
76 | of_property_read_u32(np, "dma-xor-limit", &bcm3384_dma_xor_limit); | ||
77 | |||
78 | of_node_put(np); | ||
79 | return 0; | ||
80 | } | ||
81 | arch_initcall(bcm3384_init_dma_xor); | ||
diff --git a/arch/mips/bcm3384/irq.c b/arch/mips/bcm3384/irq.c new file mode 100644 index 000000000000..0fb5134fb832 --- /dev/null +++ b/arch/mips/bcm3384/irq.c | |||
@@ -0,0 +1,193 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Partially based on arch/mips/ralink/irq.c | ||
7 | * | ||
8 | * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> | ||
9 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | ||
10 | * Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com> | ||
11 | */ | ||
12 | |||
13 | #include <linux/io.h> | ||
14 | #include <linux/bitops.h> | ||
15 | #include <linux/of_platform.h> | ||
16 | #include <linux/of_address.h> | ||
17 | #include <linux/of_irq.h> | ||
18 | #include <linux/irqdomain.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/spinlock.h> | ||
22 | |||
23 | #include <asm/bmips.h> | ||
24 | #include <asm/irq_cpu.h> | ||
25 | #include <asm/mipsregs.h> | ||
26 | |||
27 | /* INTC register offsets */ | ||
28 | #define INTC_REG_ENABLE 0x00 | ||
29 | #define INTC_REG_STATUS 0x04 | ||
30 | |||
31 | #define MAX_WORDS 2 | ||
32 | #define IRQS_PER_WORD 32 | ||
33 | |||
34 | struct bcm3384_intc { | ||
35 | int n_words; | ||
36 | void __iomem *reg[MAX_WORDS]; | ||
37 | u32 enable[MAX_WORDS]; | ||
38 | spinlock_t lock; | ||
39 | }; | ||
40 | |||
41 | static void bcm3384_intc_irq_unmask(struct irq_data *d) | ||
42 | { | ||
43 | struct bcm3384_intc *priv = d->domain->host_data; | ||
44 | unsigned long flags; | ||
45 | int idx = d->hwirq / IRQS_PER_WORD; | ||
46 | int bit = d->hwirq % IRQS_PER_WORD; | ||
47 | |||
48 | spin_lock_irqsave(&priv->lock, flags); | ||
49 | priv->enable[idx] |= BIT(bit); | ||
50 | __raw_writel(priv->enable[idx], priv->reg[idx] + INTC_REG_ENABLE); | ||
51 | spin_unlock_irqrestore(&priv->lock, flags); | ||
52 | } | ||
53 | |||
54 | static void bcm3384_intc_irq_mask(struct irq_data *d) | ||
55 | { | ||
56 | struct bcm3384_intc *priv = d->domain->host_data; | ||
57 | unsigned long flags; | ||
58 | int idx = d->hwirq / IRQS_PER_WORD; | ||
59 | int bit = d->hwirq % IRQS_PER_WORD; | ||
60 | |||
61 | spin_lock_irqsave(&priv->lock, flags); | ||
62 | priv->enable[idx] &= ~BIT(bit); | ||
63 | __raw_writel(priv->enable[idx], priv->reg[idx] + INTC_REG_ENABLE); | ||
64 | spin_unlock_irqrestore(&priv->lock, flags); | ||
65 | } | ||
66 | |||
67 | static struct irq_chip bcm3384_intc_irq_chip = { | ||
68 | .name = "INTC", | ||
69 | .irq_unmask = bcm3384_intc_irq_unmask, | ||
70 | .irq_mask = bcm3384_intc_irq_mask, | ||
71 | .irq_mask_ack = bcm3384_intc_irq_mask, | ||
72 | }; | ||
73 | |||
74 | unsigned int get_c0_compare_int(void) | ||
75 | { | ||
76 | return CP0_LEGACY_COMPARE_IRQ; | ||
77 | } | ||
78 | |||
79 | static void bcm3384_intc_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
80 | { | ||
81 | struct irq_domain *domain = irq_get_handler_data(irq); | ||
82 | struct bcm3384_intc *priv = domain->host_data; | ||
83 | unsigned long flags; | ||
84 | unsigned int idx; | ||
85 | |||
86 | for (idx = 0; idx < priv->n_words; idx++) { | ||
87 | unsigned long pending; | ||
88 | int hwirq; | ||
89 | |||
90 | spin_lock_irqsave(&priv->lock, flags); | ||
91 | pending = __raw_readl(priv->reg[idx] + INTC_REG_STATUS) & | ||
92 | priv->enable[idx]; | ||
93 | spin_unlock_irqrestore(&priv->lock, flags); | ||
94 | |||
95 | for_each_set_bit(hwirq, &pending, IRQS_PER_WORD) { | ||
96 | generic_handle_irq(irq_find_mapping(domain, | ||
97 | hwirq + idx * IRQS_PER_WORD)); | ||
98 | } | ||
99 | } | ||
100 | } | ||
101 | |||
102 | asmlinkage void plat_irq_dispatch(void) | ||
103 | { | ||
104 | unsigned long pending = | ||
105 | (read_c0_status() & read_c0_cause() & ST0_IM) >> STATUSB_IP0; | ||
106 | int bit; | ||
107 | |||
108 | for_each_set_bit(bit, &pending, 8) | ||
109 | do_IRQ(MIPS_CPU_IRQ_BASE + bit); | ||
110 | } | ||
111 | |||
112 | static int intc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) | ||
113 | { | ||
114 | irq_set_chip_and_handler(irq, &bcm3384_intc_irq_chip, handle_level_irq); | ||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static const struct irq_domain_ops irq_domain_ops = { | ||
119 | .xlate = irq_domain_xlate_onecell, | ||
120 | .map = intc_map, | ||
121 | }; | ||
122 | |||
123 | static int __init ioremap_one_pair(struct bcm3384_intc *priv, | ||
124 | struct device_node *node, | ||
125 | int idx) | ||
126 | { | ||
127 | struct resource res; | ||
128 | |||
129 | if (of_address_to_resource(node, idx, &res)) | ||
130 | return 0; | ||
131 | |||
132 | if (request_mem_region(res.start, resource_size(&res), | ||
133 | res.name) < 0) | ||
134 | pr_err("Failed to request INTC register region\n"); | ||
135 | |||
136 | priv->reg[idx] = ioremap_nocache(res.start, resource_size(&res)); | ||
137 | if (!priv->reg[idx]) | ||
138 | panic("Failed to ioremap INTC register range"); | ||
139 | |||
140 | /* start up with everything masked before we hook the parent IRQ */ | ||
141 | __raw_writel(0, priv->reg[idx] + INTC_REG_ENABLE); | ||
142 | priv->enable[idx] = 0; | ||
143 | |||
144 | return IRQS_PER_WORD; | ||
145 | } | ||
146 | |||
147 | static int __init intc_of_init(struct device_node *node, | ||
148 | struct device_node *parent) | ||
149 | { | ||
150 | struct irq_domain *domain; | ||
151 | unsigned int parent_irq, n_irqs = 0; | ||
152 | struct bcm3384_intc *priv; | ||
153 | |||
154 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
155 | if (!priv) | ||
156 | panic("Failed to allocate bcm3384_intc struct"); | ||
157 | |||
158 | spin_lock_init(&priv->lock); | ||
159 | |||
160 | parent_irq = irq_of_parse_and_map(node, 0); | ||
161 | if (!parent_irq) | ||
162 | panic("Failed to get INTC IRQ"); | ||
163 | |||
164 | n_irqs += ioremap_one_pair(priv, node, 0); | ||
165 | n_irqs += ioremap_one_pair(priv, node, 1); | ||
166 | |||
167 | if (!n_irqs) | ||
168 | panic("Failed to map INTC registers"); | ||
169 | |||
170 | priv->n_words = n_irqs / IRQS_PER_WORD; | ||
171 | domain = irq_domain_add_linear(node, n_irqs, &irq_domain_ops, priv); | ||
172 | if (!domain) | ||
173 | panic("Failed to add irqdomain"); | ||
174 | |||
175 | irq_set_chained_handler(parent_irq, bcm3384_intc_irq_handler); | ||
176 | irq_set_handler_data(parent_irq, domain); | ||
177 | |||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | static struct of_device_id of_irq_ids[] __initdata = { | ||
182 | { .compatible = "mti,cpu-interrupt-controller", | ||
183 | .data = mips_cpu_intc_init }, | ||
184 | { .compatible = "brcm,bcm3384-intc", | ||
185 | .data = intc_of_init }, | ||
186 | {}, | ||
187 | }; | ||
188 | |||
189 | void __init arch_init_irq(void) | ||
190 | { | ||
191 | bmips_tp1_irqs = 0; | ||
192 | of_irq_init(of_irq_ids); | ||
193 | } | ||
diff --git a/arch/mips/bcm3384/setup.c b/arch/mips/bcm3384/setup.c new file mode 100644 index 000000000000..d84b8400b874 --- /dev/null +++ b/arch/mips/bcm3384/setup.c | |||
@@ -0,0 +1,97 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> | ||
7 | * Copyright (C) 2014 Kevin Cernekee <cernekee@gmail.com> | ||
8 | */ | ||
9 | |||
10 | #include <linux/init.h> | ||
11 | #include <linux/bootmem.h> | ||
12 | #include <linux/clk-provider.h> | ||
13 | #include <linux/ioport.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/of_fdt.h> | ||
16 | #include <linux/of_platform.h> | ||
17 | #include <linux/smp.h> | ||
18 | #include <asm/addrspace.h> | ||
19 | #include <asm/bmips.h> | ||
20 | #include <asm/bootinfo.h> | ||
21 | #include <asm/prom.h> | ||
22 | #include <asm/smp-ops.h> | ||
23 | #include <asm/time.h> | ||
24 | |||
25 | void __init prom_init(void) | ||
26 | { | ||
27 | register_bmips_smp_ops(); | ||
28 | } | ||
29 | |||
30 | void __init prom_free_prom_memory(void) | ||
31 | { | ||
32 | } | ||
33 | |||
34 | const char *get_system_type(void) | ||
35 | { | ||
36 | return "BCM3384"; | ||
37 | } | ||
38 | |||
39 | void __init plat_time_init(void) | ||
40 | { | ||
41 | struct device_node *np; | ||
42 | u32 freq; | ||
43 | |||
44 | np = of_find_node_by_name(NULL, "cpus"); | ||
45 | if (!np) | ||
46 | panic("missing 'cpus' DT node"); | ||
47 | if (of_property_read_u32(np, "mips-hpt-frequency", &freq) < 0) | ||
48 | panic("missing 'mips-hpt-frequency' property"); | ||
49 | of_node_put(np); | ||
50 | |||
51 | mips_hpt_frequency = freq; | ||
52 | } | ||
53 | |||
54 | void __init plat_mem_setup(void) | ||
55 | { | ||
56 | void *dtb = __dtb_start; | ||
57 | |||
58 | set_io_port_base(0); | ||
59 | ioport_resource.start = 0; | ||
60 | ioport_resource.end = ~0; | ||
61 | |||
62 | /* intended to somewhat resemble ARM; see Documentation/arm/Booting */ | ||
63 | if (fw_arg0 == 0 && fw_arg1 == 0xffffffff) | ||
64 | dtb = phys_to_virt(fw_arg2); | ||
65 | |||
66 | __dt_setup_arch(dtb); | ||
67 | |||
68 | strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); | ||
69 | } | ||
70 | |||
71 | void __init device_tree_init(void) | ||
72 | { | ||
73 | struct device_node *np; | ||
74 | |||
75 | unflatten_and_copy_device_tree(); | ||
76 | |||
77 | /* Disable SMP boot unless both CPUs are listed in DT and !disabled */ | ||
78 | np = of_find_node_by_name(NULL, "cpus"); | ||
79 | if (np && of_get_available_child_count(np) <= 1) | ||
80 | bmips_smp_enabled = 0; | ||
81 | of_node_put(np); | ||
82 | } | ||
83 | |||
84 | int __init plat_of_setup(void) | ||
85 | { | ||
86 | return __dt_register_buses("brcm,bcm3384", "simple-bus"); | ||
87 | } | ||
88 | |||
89 | arch_initcall(plat_of_setup); | ||
90 | |||
91 | static int __init plat_dev_init(void) | ||
92 | { | ||
93 | of_clk_init(NULL); | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | device_initcall(plat_dev_init); | ||
diff --git a/arch/mips/bcm47xx/bcm47xx_private.h b/arch/mips/bcm47xx/bcm47xx_private.h index f1cc9d0495d8..ea909a56a3ee 100644 --- a/arch/mips/bcm47xx/bcm47xx_private.h +++ b/arch/mips/bcm47xx/bcm47xx_private.h | |||
@@ -6,12 +6,18 @@ | |||
6 | /* prom.c */ | 6 | /* prom.c */ |
7 | void __init bcm47xx_prom_highmem_init(void); | 7 | void __init bcm47xx_prom_highmem_init(void); |
8 | 8 | ||
9 | /* sprom.c */ | ||
10 | void bcm47xx_sprom_register_fallbacks(void); | ||
11 | |||
9 | /* buttons.c */ | 12 | /* buttons.c */ |
10 | int __init bcm47xx_buttons_register(void); | 13 | int __init bcm47xx_buttons_register(void); |
11 | 14 | ||
12 | /* leds.c */ | 15 | /* leds.c */ |
13 | void __init bcm47xx_leds_register(void); | 16 | void __init bcm47xx_leds_register(void); |
14 | 17 | ||
18 | /* setup.c */ | ||
19 | void __init bcm47xx_bus_setup(void); | ||
20 | |||
15 | /* workarounds.c */ | 21 | /* workarounds.c */ |
16 | void __init bcm47xx_workarounds(void); | 22 | void __init bcm47xx_workarounds(void); |
17 | 23 | ||
diff --git a/arch/mips/bcm47xx/irq.c b/arch/mips/bcm47xx/irq.c index e0585b76ec19..21b4497f09be 100644 --- a/arch/mips/bcm47xx/irq.c +++ b/arch/mips/bcm47xx/irq.c | |||
@@ -22,6 +22,8 @@ | |||
22 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 22 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "bcm47xx_private.h" | ||
26 | |||
25 | #include <linux/types.h> | 27 | #include <linux/types.h> |
26 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
27 | #include <linux/irq.h> | 29 | #include <linux/irq.h> |
@@ -65,6 +67,12 @@ DEFINE_HWx_IRQDISPATCH(7) | |||
65 | 67 | ||
66 | void __init arch_init_irq(void) | 68 | void __init arch_init_irq(void) |
67 | { | 69 | { |
70 | /* | ||
71 | * This is the first arch callback after mm_init (we can use kmalloc), | ||
72 | * so let's finish bus initialization now. | ||
73 | */ | ||
74 | bcm47xx_bus_setup(); | ||
75 | |||
68 | #ifdef CONFIG_BCM47XX_BCMA | 76 | #ifdef CONFIG_BCM47XX_BCMA |
69 | if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) { | 77 | if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) { |
70 | bcma_write32(bcm47xx_bus.bcma.bus.drv_mips.core, | 78 | bcma_write32(bcm47xx_bus.bcma.bus.drv_mips.core, |
diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c index 2bed73a684ae..c5c381c43f17 100644 --- a/arch/mips/bcm47xx/nvram.c +++ b/arch/mips/bcm47xx/nvram.c | |||
@@ -13,24 +13,35 @@ | |||
13 | 13 | ||
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/ssb/ssb.h> | ||
17 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
18 | #include <linux/string.h> | 17 | #include <linux/string.h> |
19 | #include <asm/addrspace.h> | 18 | #include <linux/mtd/mtd.h> |
20 | #include <bcm47xx_nvram.h> | 19 | #include <bcm47xx_nvram.h> |
21 | #include <asm/mach-bcm47xx/bcm47xx.h> | 20 | |
21 | #define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */ | ||
22 | #define NVRAM_SPACE 0x8000 | ||
23 | |||
24 | #define FLASH_MIN 0x00020000 /* Minimum flash size */ | ||
25 | |||
26 | struct nvram_header { | ||
27 | u32 magic; | ||
28 | u32 len; | ||
29 | u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */ | ||
30 | u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */ | ||
31 | u32 config_ncdl; /* ncdl values for memc */ | ||
32 | }; | ||
22 | 33 | ||
23 | static char nvram_buf[NVRAM_SPACE]; | 34 | static char nvram_buf[NVRAM_SPACE]; |
24 | static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000}; | 35 | static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000}; |
25 | 36 | ||
26 | static u32 find_nvram_size(u32 end) | 37 | static u32 find_nvram_size(void __iomem *end) |
27 | { | 38 | { |
28 | struct nvram_header *header; | 39 | struct nvram_header __iomem *header; |
29 | int i; | 40 | int i; |
30 | 41 | ||
31 | for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) { | 42 | for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) { |
32 | header = (struct nvram_header *)KSEG1ADDR(end - nvram_sizes[i]); | 43 | header = (struct nvram_header *)(end - nvram_sizes[i]); |
33 | if (header->magic == NVRAM_HEADER) | 44 | if (header->magic == NVRAM_MAGIC) |
34 | return nvram_sizes[i]; | 45 | return nvram_sizes[i]; |
35 | } | 46 | } |
36 | 47 | ||
@@ -38,36 +49,40 @@ static u32 find_nvram_size(u32 end) | |||
38 | } | 49 | } |
39 | 50 | ||
40 | /* Probe for NVRAM header */ | 51 | /* Probe for NVRAM header */ |
41 | static int nvram_find_and_copy(u32 base, u32 lim) | 52 | static int nvram_find_and_copy(void __iomem *iobase, u32 lim) |
42 | { | 53 | { |
43 | struct nvram_header *header; | 54 | struct nvram_header __iomem *header; |
44 | int i; | 55 | int i; |
45 | u32 off; | 56 | u32 off; |
46 | u32 *src, *dst; | 57 | u32 *src, *dst; |
47 | u32 size; | 58 | u32 size; |
48 | 59 | ||
60 | if (nvram_buf[0]) { | ||
61 | pr_warn("nvram already initialized\n"); | ||
62 | return -EEXIST; | ||
63 | } | ||
64 | |||
49 | /* TODO: when nvram is on nand flash check for bad blocks first. */ | 65 | /* TODO: when nvram is on nand flash check for bad blocks first. */ |
50 | off = FLASH_MIN; | 66 | off = FLASH_MIN; |
51 | while (off <= lim) { | 67 | while (off <= lim) { |
52 | /* Windowed flash access */ | 68 | /* Windowed flash access */ |
53 | size = find_nvram_size(base + off); | 69 | size = find_nvram_size(iobase + off); |
54 | if (size) { | 70 | if (size) { |
55 | header = (struct nvram_header *)KSEG1ADDR(base + off - | 71 | header = (struct nvram_header *)(iobase + off - size); |
56 | size); | ||
57 | goto found; | 72 | goto found; |
58 | } | 73 | } |
59 | off <<= 1; | 74 | off <<= 1; |
60 | } | 75 | } |
61 | 76 | ||
62 | /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ | 77 | /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ |
63 | header = (struct nvram_header *) KSEG1ADDR(base + 4096); | 78 | header = (struct nvram_header *)(iobase + 4096); |
64 | if (header->magic == NVRAM_HEADER) { | 79 | if (header->magic == NVRAM_MAGIC) { |
65 | size = NVRAM_SPACE; | 80 | size = NVRAM_SPACE; |
66 | goto found; | 81 | goto found; |
67 | } | 82 | } |
68 | 83 | ||
69 | header = (struct nvram_header *) KSEG1ADDR(base + 1024); | 84 | header = (struct nvram_header *)(iobase + 1024); |
70 | if (header->magic == NVRAM_HEADER) { | 85 | if (header->magic == NVRAM_MAGIC) { |
71 | size = NVRAM_SPACE; | 86 | size = NVRAM_SPACE; |
72 | goto found; | 87 | goto found; |
73 | } | 88 | } |
@@ -94,71 +109,73 @@ found: | |||
94 | return 0; | 109 | return 0; |
95 | } | 110 | } |
96 | 111 | ||
97 | #ifdef CONFIG_BCM47XX_SSB | 112 | /* |
98 | static int nvram_init_ssb(void) | 113 | * On bcm47xx we need access to the NVRAM very early, so we can't use mtd |
114 | * subsystem to access flash. We can't even use platform device / driver to | ||
115 | * store memory offset. | ||
116 | * To handle this we provide following symbol. It's supposed to be called as | ||
117 | * soon as we get info about flash device, before any NVRAM entry is needed. | ||
118 | */ | ||
119 | int bcm47xx_nvram_init_from_mem(u32 base, u32 lim) | ||
99 | { | 120 | { |
100 | struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore; | 121 | void __iomem *iobase; |
101 | u32 base; | 122 | int err; |
102 | u32 lim; | ||
103 | |||
104 | if (mcore->pflash.present) { | ||
105 | base = mcore->pflash.window; | ||
106 | lim = mcore->pflash.window_size; | ||
107 | } else { | ||
108 | pr_err("Couldn't find supported flash memory\n"); | ||
109 | return -ENXIO; | ||
110 | } | ||
111 | 123 | ||
112 | return nvram_find_and_copy(base, lim); | 124 | iobase = ioremap_nocache(base, lim); |
113 | } | 125 | if (!iobase) |
114 | #endif | 126 | return -ENOMEM; |
115 | 127 | ||
116 | #ifdef CONFIG_BCM47XX_BCMA | 128 | err = nvram_find_and_copy(iobase, lim); |
117 | static int nvram_init_bcma(void) | 129 | |
118 | { | 130 | iounmap(iobase); |
119 | struct bcma_drv_cc *cc = &bcm47xx_bus.bcma.bus.drv_cc; | ||
120 | u32 base; | ||
121 | u32 lim; | ||
122 | |||
123 | #ifdef CONFIG_BCMA_NFLASH | ||
124 | if (cc->nflash.boot) { | ||
125 | base = BCMA_SOC_FLASH1; | ||
126 | lim = BCMA_SOC_FLASH1_SZ; | ||
127 | } else | ||
128 | #endif | ||
129 | if (cc->pflash.present) { | ||
130 | base = cc->pflash.window; | ||
131 | lim = cc->pflash.window_size; | ||
132 | #ifdef CONFIG_BCMA_SFLASH | ||
133 | } else if (cc->sflash.present) { | ||
134 | base = cc->sflash.window; | ||
135 | lim = cc->sflash.size; | ||
136 | #endif | ||
137 | } else { | ||
138 | pr_err("Couldn't find supported flash memory\n"); | ||
139 | return -ENXIO; | ||
140 | } | ||
141 | 131 | ||
142 | return nvram_find_and_copy(base, lim); | 132 | return err; |
143 | } | 133 | } |
144 | #endif | ||
145 | 134 | ||
146 | static int nvram_init(void) | 135 | static int nvram_init(void) |
147 | { | 136 | { |
148 | switch (bcm47xx_bus_type) { | 137 | #ifdef CONFIG_MTD |
149 | #ifdef CONFIG_BCM47XX_SSB | 138 | struct mtd_info *mtd; |
150 | case BCM47XX_BUS_TYPE_SSB: | 139 | struct nvram_header header; |
151 | return nvram_init_ssb(); | 140 | size_t bytes_read; |
152 | #endif | 141 | int err, i; |
153 | #ifdef CONFIG_BCM47XX_BCMA | 142 | |
154 | case BCM47XX_BUS_TYPE_BCMA: | 143 | mtd = get_mtd_device_nm("nvram"); |
155 | return nvram_init_bcma(); | 144 | if (IS_ERR(mtd)) |
156 | #endif | 145 | return -ENODEV; |
146 | |||
147 | for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) { | ||
148 | loff_t from = mtd->size - nvram_sizes[i]; | ||
149 | |||
150 | if (from < 0) | ||
151 | continue; | ||
152 | |||
153 | err = mtd_read(mtd, from, sizeof(header), &bytes_read, | ||
154 | (uint8_t *)&header); | ||
155 | if (!err && header.magic == NVRAM_MAGIC) { | ||
156 | u8 *dst = (uint8_t *)nvram_buf; | ||
157 | size_t len = header.len; | ||
158 | |||
159 | if (header.len > NVRAM_SPACE) { | ||
160 | pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n", | ||
161 | header.len, NVRAM_SPACE); | ||
162 | len = NVRAM_SPACE; | ||
163 | } | ||
164 | |||
165 | err = mtd_read(mtd, from, len, &bytes_read, dst); | ||
166 | if (err) | ||
167 | return err; | ||
168 | memset(dst + bytes_read, 0x0, NVRAM_SPACE - bytes_read); | ||
169 | |||
170 | return 0; | ||
171 | } | ||
157 | } | 172 | } |
173 | #endif | ||
174 | |||
158 | return -ENXIO; | 175 | return -ENXIO; |
159 | } | 176 | } |
160 | 177 | ||
161 | int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len) | 178 | int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len) |
162 | { | 179 | { |
163 | char *var, *value, *end, *eq; | 180 | char *var, *value, *end, *eq; |
164 | int err; | 181 | int err; |
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index c00585d915bc..e43b5046cb30 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c | |||
@@ -102,23 +102,6 @@ static void bcm47xx_machine_halt(void) | |||
102 | } | 102 | } |
103 | 103 | ||
104 | #ifdef CONFIG_BCM47XX_SSB | 104 | #ifdef CONFIG_BCM47XX_SSB |
105 | static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out) | ||
106 | { | ||
107 | char prefix[10]; | ||
108 | |||
109 | if (bus->bustype == SSB_BUSTYPE_PCI) { | ||
110 | memset(out, 0, sizeof(struct ssb_sprom)); | ||
111 | snprintf(prefix, sizeof(prefix), "pci/%u/%u/", | ||
112 | bus->host_pci->bus->number + 1, | ||
113 | PCI_SLOT(bus->host_pci->devfn)); | ||
114 | bcm47xx_fill_sprom(out, prefix, false); | ||
115 | return 0; | ||
116 | } else { | ||
117 | printk(KERN_WARNING "bcm47xx: unable to fill SPROM for given bustype.\n"); | ||
118 | return -EINVAL; | ||
119 | } | ||
120 | } | ||
121 | |||
122 | static int bcm47xx_get_invariants(struct ssb_bus *bus, | 105 | static int bcm47xx_get_invariants(struct ssb_bus *bus, |
123 | struct ssb_init_invariants *iv) | 106 | struct ssb_init_invariants *iv) |
124 | { | 107 | { |
@@ -144,11 +127,6 @@ static void __init bcm47xx_register_ssb(void) | |||
144 | char buf[100]; | 127 | char buf[100]; |
145 | struct ssb_mipscore *mcore; | 128 | struct ssb_mipscore *mcore; |
146 | 129 | ||
147 | err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb); | ||
148 | if (err) | ||
149 | printk(KERN_WARNING "bcm47xx: someone else already registered" | ||
150 | " a ssb SPROM callback handler (err %d)\n", err); | ||
151 | |||
152 | err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE, | 130 | err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE, |
153 | bcm47xx_get_invariants); | 131 | bcm47xx_get_invariants); |
154 | if (err) | 132 | if (err) |
@@ -171,56 +149,21 @@ static void __init bcm47xx_register_ssb(void) | |||
171 | #endif | 149 | #endif |
172 | 150 | ||
173 | #ifdef CONFIG_BCM47XX_BCMA | 151 | #ifdef CONFIG_BCM47XX_BCMA |
174 | static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out) | ||
175 | { | ||
176 | char prefix[10]; | ||
177 | struct bcma_device *core; | ||
178 | |||
179 | switch (bus->hosttype) { | ||
180 | case BCMA_HOSTTYPE_PCI: | ||
181 | memset(out, 0, sizeof(struct ssb_sprom)); | ||
182 | snprintf(prefix, sizeof(prefix), "pci/%u/%u/", | ||
183 | bus->host_pci->bus->number + 1, | ||
184 | PCI_SLOT(bus->host_pci->devfn)); | ||
185 | bcm47xx_fill_sprom(out, prefix, false); | ||
186 | return 0; | ||
187 | case BCMA_HOSTTYPE_SOC: | ||
188 | memset(out, 0, sizeof(struct ssb_sprom)); | ||
189 | core = bcma_find_core(bus, BCMA_CORE_80211); | ||
190 | if (core) { | ||
191 | snprintf(prefix, sizeof(prefix), "sb/%u/", | ||
192 | core->core_index); | ||
193 | bcm47xx_fill_sprom(out, prefix, true); | ||
194 | } else { | ||
195 | bcm47xx_fill_sprom(out, NULL, false); | ||
196 | } | ||
197 | return 0; | ||
198 | default: | ||
199 | pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n"); | ||
200 | return -EINVAL; | ||
201 | } | ||
202 | } | ||
203 | |||
204 | static void __init bcm47xx_register_bcma(void) | 152 | static void __init bcm47xx_register_bcma(void) |
205 | { | 153 | { |
206 | int err; | 154 | int err; |
207 | 155 | ||
208 | err = bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma); | ||
209 | if (err) | ||
210 | pr_warn("bcm47xx: someone else already registered a bcma SPROM callback handler (err %d)\n", err); | ||
211 | |||
212 | err = bcma_host_soc_register(&bcm47xx_bus.bcma); | 156 | err = bcma_host_soc_register(&bcm47xx_bus.bcma); |
213 | if (err) | 157 | if (err) |
214 | panic("Failed to register BCMA bus (err %d)", err); | 158 | panic("Failed to register BCMA bus (err %d)", err); |
215 | |||
216 | err = bcma_host_soc_init(&bcm47xx_bus.bcma); | ||
217 | if (err) | ||
218 | panic("Failed to initialize BCMA bus (err %d)", err); | ||
219 | |||
220 | bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, NULL); | ||
221 | } | 159 | } |
222 | #endif | 160 | #endif |
223 | 161 | ||
162 | /* | ||
163 | * Memory setup is done in the early part of MIPS's arch_mem_init. It's supposed | ||
164 | * to detect memory and record it with add_memory_region. | ||
165 | * Any extra initializaion performed here must not use kmalloc or bootmem. | ||
166 | */ | ||
224 | void __init plat_mem_setup(void) | 167 | void __init plat_mem_setup(void) |
225 | { | 168 | { |
226 | struct cpuinfo_mips *c = ¤t_cpu_data; | 169 | struct cpuinfo_mips *c = ¤t_cpu_data; |
@@ -229,6 +172,7 @@ void __init plat_mem_setup(void) | |||
229 | printk(KERN_INFO "bcm47xx: using bcma bus\n"); | 172 | printk(KERN_INFO "bcm47xx: using bcma bus\n"); |
230 | #ifdef CONFIG_BCM47XX_BCMA | 173 | #ifdef CONFIG_BCM47XX_BCMA |
231 | bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA; | 174 | bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA; |
175 | bcm47xx_sprom_register_fallbacks(); | ||
232 | bcm47xx_register_bcma(); | 176 | bcm47xx_register_bcma(); |
233 | bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id); | 177 | bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id); |
234 | #ifdef CONFIG_HIGHMEM | 178 | #ifdef CONFIG_HIGHMEM |
@@ -239,6 +183,7 @@ void __init plat_mem_setup(void) | |||
239 | printk(KERN_INFO "bcm47xx: using ssb bus\n"); | 183 | printk(KERN_INFO "bcm47xx: using ssb bus\n"); |
240 | #ifdef CONFIG_BCM47XX_SSB | 184 | #ifdef CONFIG_BCM47XX_SSB |
241 | bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB; | 185 | bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB; |
186 | bcm47xx_sprom_register_fallbacks(); | ||
242 | bcm47xx_register_ssb(); | 187 | bcm47xx_register_ssb(); |
243 | bcm47xx_set_system_type(bcm47xx_bus.ssb.chip_id); | 188 | bcm47xx_set_system_type(bcm47xx_bus.ssb.chip_id); |
244 | #endif | 189 | #endif |
@@ -247,6 +192,28 @@ void __init plat_mem_setup(void) | |||
247 | _machine_restart = bcm47xx_machine_restart; | 192 | _machine_restart = bcm47xx_machine_restart; |
248 | _machine_halt = bcm47xx_machine_halt; | 193 | _machine_halt = bcm47xx_machine_halt; |
249 | pm_power_off = bcm47xx_machine_halt; | 194 | pm_power_off = bcm47xx_machine_halt; |
195 | } | ||
196 | |||
197 | /* | ||
198 | * This finishes bus initialization doing things that were not possible without | ||
199 | * kmalloc. Make sure to call it late enough (after mm_init). | ||
200 | */ | ||
201 | void __init bcm47xx_bus_setup(void) | ||
202 | { | ||
203 | #ifdef CONFIG_BCM47XX_BCMA | ||
204 | if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) { | ||
205 | int err; | ||
206 | |||
207 | err = bcma_host_soc_init(&bcm47xx_bus.bcma); | ||
208 | if (err) | ||
209 | panic("Failed to initialize BCMA bus (err %d)", err); | ||
210 | |||
211 | bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, | ||
212 | NULL); | ||
213 | } | ||
214 | #endif | ||
215 | |||
216 | /* With bus initialized we can access NVRAM and detect the board */ | ||
250 | bcm47xx_board_detect(); | 217 | bcm47xx_board_detect(); |
251 | mips_set_machine_name(bcm47xx_board_get_name()); | 218 | mips_set_machine_name(bcm47xx_board_get_name()); |
252 | } | 219 | } |
diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c index 41226b68de3d..2eff7fe99c6b 100644 --- a/arch/mips/bcm47xx/sprom.c +++ b/arch/mips/bcm47xx/sprom.c | |||
@@ -136,6 +136,20 @@ static void nvram_read_leddc(const char *prefix, const char *name, | |||
136 | *leddc_off_time = (val >> 16) & 0xff; | 136 | *leddc_off_time = (val >> 16) & 0xff; |
137 | } | 137 | } |
138 | 138 | ||
139 | static void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6]) | ||
140 | { | ||
141 | if (strchr(buf, ':')) | ||
142 | sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], | ||
143 | &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4], | ||
144 | &macaddr[5]); | ||
145 | else if (strchr(buf, '-')) | ||
146 | sscanf(buf, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &macaddr[0], | ||
147 | &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4], | ||
148 | &macaddr[5]); | ||
149 | else | ||
150 | pr_warn("Can not parse mac address: %s\n", buf); | ||
151 | } | ||
152 | |||
139 | static void nvram_read_macaddr(const char *prefix, const char *name, | 153 | static void nvram_read_macaddr(const char *prefix, const char *name, |
140 | u8 val[6], bool fallback) | 154 | u8 val[6], bool fallback) |
141 | { | 155 | { |
@@ -801,3 +815,71 @@ void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo, | |||
801 | nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true); | 815 | nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true); |
802 | } | 816 | } |
803 | #endif | 817 | #endif |
818 | |||
819 | #if defined(CONFIG_BCM47XX_SSB) | ||
820 | static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out) | ||
821 | { | ||
822 | char prefix[10]; | ||
823 | |||
824 | if (bus->bustype == SSB_BUSTYPE_PCI) { | ||
825 | memset(out, 0, sizeof(struct ssb_sprom)); | ||
826 | snprintf(prefix, sizeof(prefix), "pci/%u/%u/", | ||
827 | bus->host_pci->bus->number + 1, | ||
828 | PCI_SLOT(bus->host_pci->devfn)); | ||
829 | bcm47xx_fill_sprom(out, prefix, false); | ||
830 | return 0; | ||
831 | } else { | ||
832 | pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n"); | ||
833 | return -EINVAL; | ||
834 | } | ||
835 | } | ||
836 | #endif | ||
837 | |||
838 | #if defined(CONFIG_BCM47XX_BCMA) | ||
839 | static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out) | ||
840 | { | ||
841 | char prefix[10]; | ||
842 | struct bcma_device *core; | ||
843 | |||
844 | switch (bus->hosttype) { | ||
845 | case BCMA_HOSTTYPE_PCI: | ||
846 | memset(out, 0, sizeof(struct ssb_sprom)); | ||
847 | snprintf(prefix, sizeof(prefix), "pci/%u/%u/", | ||
848 | bus->host_pci->bus->number + 1, | ||
849 | PCI_SLOT(bus->host_pci->devfn)); | ||
850 | bcm47xx_fill_sprom(out, prefix, false); | ||
851 | return 0; | ||
852 | case BCMA_HOSTTYPE_SOC: | ||
853 | memset(out, 0, sizeof(struct ssb_sprom)); | ||
854 | core = bcma_find_core(bus, BCMA_CORE_80211); | ||
855 | if (core) { | ||
856 | snprintf(prefix, sizeof(prefix), "sb/%u/", | ||
857 | core->core_index); | ||
858 | bcm47xx_fill_sprom(out, prefix, true); | ||
859 | } else { | ||
860 | bcm47xx_fill_sprom(out, NULL, false); | ||
861 | } | ||
862 | return 0; | ||
863 | default: | ||
864 | pr_warn("bcm47xx: unable to fill SPROM for given bustype.\n"); | ||
865 | return -EINVAL; | ||
866 | } | ||
867 | } | ||
868 | #endif | ||
869 | |||
870 | /* | ||
871 | * On bcm47xx we need to register SPROM fallback handler very early, so we can't | ||
872 | * use anything like platform device / driver for this. | ||
873 | */ | ||
874 | void bcm47xx_sprom_register_fallbacks(void) | ||
875 | { | ||
876 | #if defined(CONFIG_BCM47XX_SSB) | ||
877 | if (ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom_ssb)) | ||
878 | pr_warn("Failed to registered ssb SPROM handler\n"); | ||
879 | #endif | ||
880 | |||
881 | #if defined(CONFIG_BCM47XX_BCMA) | ||
882 | if (bcma_arch_register_fallback_sprom(&bcm47xx_get_sprom_bcma)) | ||
883 | pr_warn("Failed to registered bcma SPROM handler\n"); | ||
884 | #endif | ||
885 | } | ||
diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c index 536f64443031..307ec8b8e41c 100644 --- a/arch/mips/bcm63xx/cpu.c +++ b/arch/mips/bcm63xx/cpu.c | |||
@@ -263,7 +263,7 @@ static unsigned int detect_memory_size(void) | |||
263 | 263 | ||
264 | if (BCMCPU_IS_6345()) { | 264 | if (BCMCPU_IS_6345()) { |
265 | val = bcm_sdram_readl(SDRAM_MBASE_REG); | 265 | val = bcm_sdram_readl(SDRAM_MBASE_REG); |
266 | return (val * 8 * 1024 * 1024); | 266 | return val * 8 * 1024 * 1024; |
267 | } | 267 | } |
268 | 268 | ||
269 | if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) { | 269 | if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) { |
diff --git a/arch/mips/boot/dts/Makefile b/arch/mips/boot/dts/Makefile index ca9c90e2cabf..4f49fa477f14 100644 --- a/arch/mips/boot/dts/Makefile +++ b/arch/mips/boot/dts/Makefile | |||
@@ -1,3 +1,4 @@ | |||
1 | dtb-$(CONFIG_BCM3384) += bcm93384wvg.dtb | ||
1 | dtb-$(CONFIG_CAVIUM_OCTEON_SOC) += octeon_3xxx.dtb octeon_68xx.dtb | 2 | dtb-$(CONFIG_CAVIUM_OCTEON_SOC) += octeon_3xxx.dtb octeon_68xx.dtb |
2 | dtb-$(CONFIG_DT_EASY50712) += easy50712.dtb | 3 | dtb-$(CONFIG_DT_EASY50712) += easy50712.dtb |
3 | dtb-$(CONFIG_DT_XLP_EVP) += xlp_evp.dtb | 4 | dtb-$(CONFIG_DT_XLP_EVP) += xlp_evp.dtb |
diff --git a/arch/mips/boot/dts/bcm3384.dtsi b/arch/mips/boot/dts/bcm3384.dtsi new file mode 100644 index 000000000000..21b074a99c94 --- /dev/null +++ b/arch/mips/boot/dts/bcm3384.dtsi | |||
@@ -0,0 +1,109 @@ | |||
1 | / { | ||
2 | #address-cells = <1>; | ||
3 | #size-cells = <1>; | ||
4 | compatible = "brcm,bcm3384", "brcm,bcm33843"; | ||
5 | |||
6 | cpus { | ||
7 | #address-cells = <1>; | ||
8 | #size-cells = <0>; | ||
9 | |||
10 | /* On BMIPS5000 this is 1/8th of the CPU core clock */ | ||
11 | mips-hpt-frequency = <100000000>; | ||
12 | |||
13 | cpu@0 { | ||
14 | compatible = "brcm,bmips5000"; | ||
15 | device_type = "cpu"; | ||
16 | reg = <0>; | ||
17 | }; | ||
18 | |||
19 | cpu@1 { | ||
20 | compatible = "brcm,bmips5000"; | ||
21 | device_type = "cpu"; | ||
22 | reg = <1>; | ||
23 | }; | ||
24 | }; | ||
25 | |||
26 | clocks { | ||
27 | #address-cells = <1>; | ||
28 | #size-cells = <0>; | ||
29 | |||
30 | periph_clk: periph_clk@0 { | ||
31 | compatible = "fixed-clock"; | ||
32 | #clock-cells = <0>; | ||
33 | clock-frequency = <54000000>; | ||
34 | }; | ||
35 | }; | ||
36 | |||
37 | aliases { | ||
38 | uart0 = &uart0; | ||
39 | }; | ||
40 | |||
41 | cpu_intc: cpu_intc@0 { | ||
42 | #address-cells = <0>; | ||
43 | compatible = "mti,cpu-interrupt-controller"; | ||
44 | |||
45 | interrupt-controller; | ||
46 | #interrupt-cells = <1>; | ||
47 | }; | ||
48 | |||
49 | periph_intc: periph_intc@14e00038 { | ||
50 | compatible = "brcm,bcm3384-intc"; | ||
51 | reg = <0x14e00038 0x8 0x14e00340 0x8>; | ||
52 | |||
53 | interrupt-controller; | ||
54 | #interrupt-cells = <1>; | ||
55 | |||
56 | interrupt-parent = <&cpu_intc>; | ||
57 | interrupts = <4>; | ||
58 | }; | ||
59 | |||
60 | zmips_intc: zmips_intc@104b0060 { | ||
61 | compatible = "brcm,bcm3384-intc"; | ||
62 | reg = <0x104b0060 0x8>; | ||
63 | |||
64 | interrupt-controller; | ||
65 | #interrupt-cells = <1>; | ||
66 | |||
67 | interrupt-parent = <&periph_intc>; | ||
68 | interrupts = <29>; | ||
69 | }; | ||
70 | |||
71 | iop_intc: iop_intc@14e00058 { | ||
72 | compatible = "brcm,bcm3384-intc"; | ||
73 | reg = <0x14e00058 0x8>; | ||
74 | |||
75 | interrupt-controller; | ||
76 | #interrupt-cells = <1>; | ||
77 | |||
78 | interrupt-parent = <&cpu_intc>; | ||
79 | interrupts = <6>; | ||
80 | }; | ||
81 | |||
82 | uart0: serial@14e00520 { | ||
83 | compatible = "brcm,bcm6345-uart"; | ||
84 | reg = <0x14e00520 0x18>; | ||
85 | interrupt-parent = <&periph_intc>; | ||
86 | interrupts = <2>; | ||
87 | clocks = <&periph_clk>; | ||
88 | status = "disabled"; | ||
89 | }; | ||
90 | |||
91 | ehci0: usb@15400300 { | ||
92 | compatible = "brcm,bcm3384-ehci", "generic-ehci"; | ||
93 | reg = <0x15400300 0x100>; | ||
94 | big-endian; | ||
95 | interrupt-parent = <&periph_intc>; | ||
96 | interrupts = <41>; | ||
97 | status = "disabled"; | ||
98 | }; | ||
99 | |||
100 | ohci0: usb@15400400 { | ||
101 | compatible = "brcm,bcm3384-ohci", "generic-ohci"; | ||
102 | reg = <0x15400400 0x100>; | ||
103 | big-endian; | ||
104 | no-big-frame-no; | ||
105 | interrupt-parent = <&periph_intc>; | ||
106 | interrupts = <40>; | ||
107 | status = "disabled"; | ||
108 | }; | ||
109 | }; | ||
diff --git a/arch/mips/boot/dts/bcm93384wvg.dts b/arch/mips/boot/dts/bcm93384wvg.dts new file mode 100644 index 000000000000..831741179212 --- /dev/null +++ b/arch/mips/boot/dts/bcm93384wvg.dts | |||
@@ -0,0 +1,32 @@ | |||
1 | /dts-v1/; | ||
2 | |||
3 | /include/ "bcm3384.dtsi" | ||
4 | |||
5 | / { | ||
6 | compatible = "brcm,bcm93384wvg", "brcm,bcm3384"; | ||
7 | model = "Broadcom BCM93384WVG"; | ||
8 | |||
9 | chosen { | ||
10 | bootargs = "console=ttyS0,115200"; | ||
11 | stdout-path = &uart0; | ||
12 | }; | ||
13 | |||
14 | memory@0 { | ||
15 | device_type = "memory"; | ||
16 | reg = <0x0 0x04000000>; | ||
17 | dma-xor-mask = <0x08000000>; | ||
18 | dma-xor-limit = <0x0fffffff>; | ||
19 | }; | ||
20 | }; | ||
21 | |||
22 | &uart0 { | ||
23 | status = "okay"; | ||
24 | }; | ||
25 | |||
26 | &ehci0 { | ||
27 | status = "okay"; | ||
28 | }; | ||
29 | |||
30 | &ohci0 { | ||
31 | status = "okay"; | ||
32 | }; | ||
diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c index 02f244475207..3778655c4a37 100644 --- a/arch/mips/cavium-octeon/dma-octeon.c +++ b/arch/mips/cavium-octeon/dma-octeon.c | |||
@@ -262,8 +262,8 @@ char *octeon_swiotlb; | |||
262 | void __init plat_swiotlb_setup(void) | 262 | void __init plat_swiotlb_setup(void) |
263 | { | 263 | { |
264 | int i; | 264 | int i; |
265 | phys_t max_addr; | 265 | phys_addr_t max_addr; |
266 | phys_t addr_size; | 266 | phys_addr_t addr_size; |
267 | size_t swiotlbsize; | 267 | size_t swiotlbsize; |
268 | unsigned long swiotlb_nslabs; | 268 | unsigned long swiotlb_nslabs; |
269 | 269 | ||
diff --git a/arch/mips/cavium-octeon/executive/octeon-model.c b/arch/mips/cavium-octeon/executive/octeon-model.c index f4c1b36fdf65..e15b049b3bd7 100644 --- a/arch/mips/cavium-octeon/executive/octeon-model.c +++ b/arch/mips/cavium-octeon/executive/octeon-model.c | |||
@@ -28,22 +28,23 @@ | |||
28 | #include <asm/octeon/octeon.h> | 28 | #include <asm/octeon/octeon.h> |
29 | 29 | ||
30 | /** | 30 | /** |
31 | * Given the chip processor ID from COP0, this function returns a | 31 | * Read a byte of fuse data |
32 | * string representing the chip model number. The string is of the | 32 | * @byte_addr: address to read |
33 | * form CNXXXXpX.X-FREQ-SUFFIX. | ||
34 | * - XXXX = The chip model number | ||
35 | * - X.X = Chip pass number | ||
36 | * - FREQ = Current frequency in Mhz | ||
37 | * - SUFFIX = NSP, EXP, SCP, SSP, or CP | ||
38 | * | ||
39 | * @chip_id: Chip ID | ||
40 | * | 33 | * |
41 | * Returns Model string | 34 | * Returns fuse value: 0 or 1 |
42 | */ | 35 | */ |
43 | const char *octeon_model_get_string(uint32_t chip_id) | 36 | static uint8_t __init cvmx_fuse_read_byte(int byte_addr) |
44 | { | 37 | { |
45 | static char buffer[32]; | 38 | union cvmx_mio_fus_rcmd read_cmd; |
46 | return octeon_model_get_string_buffer(chip_id, buffer); | 39 | |
40 | read_cmd.u64 = 0; | ||
41 | read_cmd.s.addr = byte_addr; | ||
42 | read_cmd.s.pend = 1; | ||
43 | cvmx_write_csr(CVMX_MIO_FUS_RCMD, read_cmd.u64); | ||
44 | while ((read_cmd.u64 = cvmx_read_csr(CVMX_MIO_FUS_RCMD)) | ||
45 | && read_cmd.s.pend) | ||
46 | ; | ||
47 | return read_cmd.s.dat; | ||
47 | } | 48 | } |
48 | 49 | ||
49 | /* | 50 | /* |
@@ -51,7 +52,8 @@ const char *octeon_model_get_string(uint32_t chip_id) | |||
51 | * as running early in u-boot static/global variables don't work when | 52 | * as running early in u-boot static/global variables don't work when |
52 | * running from flash. | 53 | * running from flash. |
53 | */ | 54 | */ |
54 | const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer) | 55 | static const char *__init octeon_model_get_string_buffer(uint32_t chip_id, |
56 | char *buffer) | ||
55 | { | 57 | { |
56 | const char *family; | 58 | const char *family; |
57 | const char *core_model; | 59 | const char *core_model; |
@@ -407,3 +409,22 @@ const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer) | |||
407 | sprintf(buffer, "CN%s%sp%s-%d-%s", family, core_model, pass, clock_mhz, suffix); | 409 | sprintf(buffer, "CN%s%sp%s-%d-%s", family, core_model, pass, clock_mhz, suffix); |
408 | return buffer; | 410 | return buffer; |
409 | } | 411 | } |
412 | |||
413 | /** | ||
414 | * Given the chip processor ID from COP0, this function returns a | ||
415 | * string representing the chip model number. The string is of the | ||
416 | * form CNXXXXpX.X-FREQ-SUFFIX. | ||
417 | * - XXXX = The chip model number | ||
418 | * - X.X = Chip pass number | ||
419 | * - FREQ = Current frequency in Mhz | ||
420 | * - SUFFIX = NSP, EXP, SCP, SSP, or CP | ||
421 | * | ||
422 | * @chip_id: Chip ID | ||
423 | * | ||
424 | * Returns Model string | ||
425 | */ | ||
426 | const char *__init octeon_model_get_string(uint32_t chip_id) | ||
427 | { | ||
428 | static char buffer[32]; | ||
429 | return octeon_model_get_string_buffer(chip_id, buffer); | ||
430 | } | ||
diff --git a/arch/mips/configs/bcm3384_defconfig b/arch/mips/configs/bcm3384_defconfig new file mode 100644 index 000000000000..88711c28ff32 --- /dev/null +++ b/arch/mips/configs/bcm3384_defconfig | |||
@@ -0,0 +1,78 @@ | |||
1 | CONFIG_BCM3384=y | ||
2 | CONFIG_HIGHMEM=y | ||
3 | CONFIG_SMP=y | ||
4 | CONFIG_NR_CPUS=4 | ||
5 | # CONFIG_SECCOMP is not set | ||
6 | CONFIG_MIPS_O32_FP64_SUPPORT=y | ||
7 | # CONFIG_LOCALVERSION_AUTO is not set | ||
8 | # CONFIG_SWAP is not set | ||
9 | CONFIG_NO_HZ=y | ||
10 | CONFIG_BLK_DEV_INITRD=y | ||
11 | # CONFIG_RD_GZIP is not set | ||
12 | CONFIG_EXPERT=y | ||
13 | # CONFIG_VM_EVENT_COUNTERS is not set | ||
14 | # CONFIG_SLUB_DEBUG is not set | ||
15 | # CONFIG_BLK_DEV_BSG is not set | ||
16 | # CONFIG_IOSCHED_DEADLINE is not set | ||
17 | # CONFIG_IOSCHED_CFQ is not set | ||
18 | CONFIG_NET=y | ||
19 | CONFIG_PACKET=y | ||
20 | CONFIG_PACKET_DIAG=y | ||
21 | CONFIG_UNIX=y | ||
22 | CONFIG_INET=y | ||
23 | # CONFIG_INET_XFRM_MODE_TRANSPORT is not set | ||
24 | # CONFIG_INET_XFRM_MODE_TUNNEL is not set | ||
25 | # CONFIG_INET_XFRM_MODE_BEET is not set | ||
26 | # CONFIG_INET_LRO is not set | ||
27 | # CONFIG_INET_DIAG is not set | ||
28 | CONFIG_CFG80211=y | ||
29 | CONFIG_NL80211_TESTMODE=y | ||
30 | CONFIG_MAC80211=y | ||
31 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
32 | CONFIG_DEVTMPFS=y | ||
33 | CONFIG_DEVTMPFS_MOUNT=y | ||
34 | # CONFIG_STANDALONE is not set | ||
35 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set | ||
36 | CONFIG_MTD=y | ||
37 | CONFIG_MTD_CFI=y | ||
38 | CONFIG_MTD_CFI_INTELEXT=y | ||
39 | CONFIG_MTD_CFI_AMDSTD=y | ||
40 | CONFIG_MTD_PHYSMAP=y | ||
41 | # CONFIG_BLK_DEV is not set | ||
42 | CONFIG_SCSI=y | ||
43 | CONFIG_BLK_DEV_SD=y | ||
44 | # CONFIG_SCSI_LOWLEVEL is not set | ||
45 | CONFIG_NETDEVICES=y | ||
46 | CONFIG_USB_USBNET=y | ||
47 | # CONFIG_INPUT is not set | ||
48 | # CONFIG_SERIO is not set | ||
49 | # CONFIG_VT is not set | ||
50 | # CONFIG_DEVKMEM is not set | ||
51 | CONFIG_SERIAL_EARLYCON_FORCE=y | ||
52 | CONFIG_SERIAL_BCM63XX=y | ||
53 | CONFIG_SERIAL_BCM63XX_CONSOLE=y | ||
54 | # CONFIG_HW_RANDOM is not set | ||
55 | # CONFIG_HWMON is not set | ||
56 | CONFIG_USB=y | ||
57 | CONFIG_USB_EHCI_HCD=y | ||
58 | # CONFIG_USB_EHCI_TT_NEWSCHED is not set | ||
59 | CONFIG_USB_EHCI_HCD_PLATFORM=y | ||
60 | CONFIG_USB_OHCI_HCD=y | ||
61 | CONFIG_USB_OHCI_HCD_PLATFORM=y | ||
62 | CONFIG_USB_STORAGE=y | ||
63 | CONFIG_EXT4_FS=y | ||
64 | CONFIG_EXT4_FS_POSIX_ACL=y | ||
65 | CONFIG_EXT4_FS_SECURITY=y | ||
66 | # CONFIG_DNOTIFY is not set | ||
67 | CONFIG_FUSE_FS=y | ||
68 | CONFIG_VFAT_FS=y | ||
69 | CONFIG_PROC_KCORE=y | ||
70 | CONFIG_TMPFS=y | ||
71 | CONFIG_NFS_FS=y | ||
72 | CONFIG_CIFS=y | ||
73 | CONFIG_NLS_CODEPAGE_437=y | ||
74 | CONFIG_NLS_ASCII=y | ||
75 | CONFIG_NLS_ISO8859_1=y | ||
76 | CONFIG_DEBUG_FS=y | ||
77 | CONFIG_MAGIC_SYSRQ=y | ||
78 | # CONFIG_CRYPTO_HW is not set | ||
diff --git a/arch/mips/fw/lib/cmdline.c b/arch/mips/fw/lib/cmdline.c index ffd0345780ae..6ecda64ad184 100644 --- a/arch/mips/fw/lib/cmdline.c +++ b/arch/mips/fw/lib/cmdline.c | |||
@@ -68,7 +68,7 @@ char *fw_getenv(char *envname) | |||
68 | result = fw_envp(index + 1); | 68 | result = fw_envp(index + 1); |
69 | break; | 69 | break; |
70 | } else if (fw_envp(index)[i] == '=') { | 70 | } else if (fw_envp(index)[i] == '=') { |
71 | result = (fw_envp(index + 1) + i); | 71 | result = fw_envp(index) + i + 1; |
72 | break; | 72 | break; |
73 | } | 73 | } |
74 | } | 74 | } |
@@ -88,13 +88,13 @@ unsigned long fw_getenvl(char *envname) | |||
88 | { | 88 | { |
89 | unsigned long envl = 0UL; | 89 | unsigned long envl = 0UL; |
90 | char *str; | 90 | char *str; |
91 | long val; | ||
92 | int tmp; | 91 | int tmp; |
93 | 92 | ||
94 | str = fw_getenv(envname); | 93 | str = fw_getenv(envname); |
95 | if (str) { | 94 | if (str) { |
96 | tmp = kstrtol(str, 0, &val); | 95 | tmp = kstrtoul(str, 0, &envl); |
97 | envl = (unsigned long)val; | 96 | if (tmp) |
97 | envl = 0; | ||
98 | } | 98 | } |
99 | 99 | ||
100 | return envl; | 100 | return envl; |
diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h index 6dd6bfc607e9..857da84cfc92 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/irqflags.h> | 17 | #include <linux/irqflags.h> |
18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
19 | #include <asm/barrier.h> | 19 | #include <asm/barrier.h> |
20 | #include <asm/compiler.h> | ||
20 | #include <asm/cpu-features.h> | 21 | #include <asm/cpu-features.h> |
21 | #include <asm/cmpxchg.h> | 22 | #include <asm/cmpxchg.h> |
22 | #include <asm/war.h> | 23 | #include <asm/war.h> |
@@ -40,95 +41,97 @@ | |||
40 | */ | 41 | */ |
41 | #define atomic_set(v, i) ((v)->counter = (i)) | 42 | #define atomic_set(v, i) ((v)->counter = (i)) |
42 | 43 | ||
43 | #define ATOMIC_OP(op, c_op, asm_op) \ | 44 | #define ATOMIC_OP(op, c_op, asm_op) \ |
44 | static __inline__ void atomic_##op(int i, atomic_t * v) \ | 45 | static __inline__ void atomic_##op(int i, atomic_t * v) \ |
45 | { \ | 46 | { \ |
46 | if (kernel_uses_llsc && R10000_LLSC_WAR) { \ | 47 | if (kernel_uses_llsc && R10000_LLSC_WAR) { \ |
47 | int temp; \ | 48 | int temp; \ |
48 | \ | 49 | \ |
49 | __asm__ __volatile__( \ | 50 | __asm__ __volatile__( \ |
50 | " .set arch=r4000 \n" \ | 51 | " .set arch=r4000 \n" \ |
51 | "1: ll %0, %1 # atomic_" #op " \n" \ | 52 | "1: ll %0, %1 # atomic_" #op " \n" \ |
52 | " " #asm_op " %0, %2 \n" \ | 53 | " " #asm_op " %0, %2 \n" \ |
53 | " sc %0, %1 \n" \ | 54 | " sc %0, %1 \n" \ |
54 | " beqzl %0, 1b \n" \ | 55 | " beqzl %0, 1b \n" \ |
55 | " .set mips0 \n" \ | 56 | " .set mips0 \n" \ |
56 | : "=&r" (temp), "+m" (v->counter) \ | 57 | : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \ |
57 | : "Ir" (i)); \ | 58 | : "Ir" (i)); \ |
58 | } else if (kernel_uses_llsc) { \ | 59 | } else if (kernel_uses_llsc) { \ |
59 | int temp; \ | 60 | int temp; \ |
60 | \ | 61 | \ |
61 | do { \ | 62 | do { \ |
62 | __asm__ __volatile__( \ | 63 | __asm__ __volatile__( \ |
63 | " .set arch=r4000 \n" \ | 64 | " .set arch=r4000 \n" \ |
64 | " ll %0, %1 # atomic_" #op "\n" \ | 65 | " ll %0, %1 # atomic_" #op "\n" \ |
65 | " " #asm_op " %0, %2 \n" \ | 66 | " " #asm_op " %0, %2 \n" \ |
66 | " sc %0, %1 \n" \ | 67 | " sc %0, %1 \n" \ |
67 | " .set mips0 \n" \ | 68 | " .set mips0 \n" \ |
68 | : "=&r" (temp), "+m" (v->counter) \ | 69 | : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \ |
69 | : "Ir" (i)); \ | 70 | : "Ir" (i)); \ |
70 | } while (unlikely(!temp)); \ | 71 | } while (unlikely(!temp)); \ |
71 | } else { \ | 72 | } else { \ |
72 | unsigned long flags; \ | 73 | unsigned long flags; \ |
73 | \ | 74 | \ |
74 | raw_local_irq_save(flags); \ | 75 | raw_local_irq_save(flags); \ |
75 | v->counter c_op i; \ | 76 | v->counter c_op i; \ |
76 | raw_local_irq_restore(flags); \ | 77 | raw_local_irq_restore(flags); \ |
77 | } \ | 78 | } \ |
78 | } \ | ||
79 | |||
80 | #define ATOMIC_OP_RETURN(op, c_op, asm_op) \ | ||
81 | static __inline__ int atomic_##op##_return(int i, atomic_t * v) \ | ||
82 | { \ | ||
83 | int result; \ | ||
84 | \ | ||
85 | smp_mb__before_llsc(); \ | ||
86 | \ | ||
87 | if (kernel_uses_llsc && R10000_LLSC_WAR) { \ | ||
88 | int temp; \ | ||
89 | \ | ||
90 | __asm__ __volatile__( \ | ||
91 | " .set arch=r4000 \n" \ | ||
92 | "1: ll %1, %2 # atomic_" #op "_return \n" \ | ||
93 | " " #asm_op " %0, %1, %3 \n" \ | ||
94 | " sc %0, %2 \n" \ | ||
95 | " beqzl %0, 1b \n" \ | ||
96 | " " #asm_op " %0, %1, %3 \n" \ | ||
97 | " .set mips0 \n" \ | ||
98 | : "=&r" (result), "=&r" (temp), "+m" (v->counter) \ | ||
99 | : "Ir" (i)); \ | ||
100 | } else if (kernel_uses_llsc) { \ | ||
101 | int temp; \ | ||
102 | \ | ||
103 | do { \ | ||
104 | __asm__ __volatile__( \ | ||
105 | " .set arch=r4000 \n" \ | ||
106 | " ll %1, %2 # atomic_" #op "_return \n" \ | ||
107 | " " #asm_op " %0, %1, %3 \n" \ | ||
108 | " sc %0, %2 \n" \ | ||
109 | " .set mips0 \n" \ | ||
110 | : "=&r" (result), "=&r" (temp), "+m" (v->counter) \ | ||
111 | : "Ir" (i)); \ | ||
112 | } while (unlikely(!result)); \ | ||
113 | \ | ||
114 | result = temp; result c_op i; \ | ||
115 | } else { \ | ||
116 | unsigned long flags; \ | ||
117 | \ | ||
118 | raw_local_irq_save(flags); \ | ||
119 | result = v->counter; \ | ||
120 | result c_op i; \ | ||
121 | v->counter = result; \ | ||
122 | raw_local_irq_restore(flags); \ | ||
123 | } \ | ||
124 | \ | ||
125 | smp_llsc_mb(); \ | ||
126 | \ | ||
127 | return result; \ | ||
128 | } | 79 | } |
129 | 80 | ||
130 | #define ATOMIC_OPS(op, c_op, asm_op) \ | 81 | #define ATOMIC_OP_RETURN(op, c_op, asm_op) \ |
131 | ATOMIC_OP(op, c_op, asm_op) \ | 82 | static __inline__ int atomic_##op##_return(int i, atomic_t * v) \ |
83 | { \ | ||
84 | int result; \ | ||
85 | \ | ||
86 | smp_mb__before_llsc(); \ | ||
87 | \ | ||
88 | if (kernel_uses_llsc && R10000_LLSC_WAR) { \ | ||
89 | int temp; \ | ||
90 | \ | ||
91 | __asm__ __volatile__( \ | ||
92 | " .set arch=r4000 \n" \ | ||
93 | "1: ll %1, %2 # atomic_" #op "_return \n" \ | ||
94 | " " #asm_op " %0, %1, %3 \n" \ | ||
95 | " sc %0, %2 \n" \ | ||
96 | " beqzl %0, 1b \n" \ | ||
97 | " " #asm_op " %0, %1, %3 \n" \ | ||
98 | " .set mips0 \n" \ | ||
99 | : "=&r" (result), "=&r" (temp), \ | ||
100 | "+" GCC_OFF12_ASM() (v->counter) \ | ||
101 | : "Ir" (i)); \ | ||
102 | } else if (kernel_uses_llsc) { \ | ||
103 | int temp; \ | ||
104 | \ | ||
105 | do { \ | ||
106 | __asm__ __volatile__( \ | ||
107 | " .set arch=r4000 \n" \ | ||
108 | " ll %1, %2 # atomic_" #op "_return \n" \ | ||
109 | " " #asm_op " %0, %1, %3 \n" \ | ||
110 | " sc %0, %2 \n" \ | ||
111 | " .set mips0 \n" \ | ||
112 | : "=&r" (result), "=&r" (temp), \ | ||
113 | "+" GCC_OFF12_ASM() (v->counter) \ | ||
114 | : "Ir" (i)); \ | ||
115 | } while (unlikely(!result)); \ | ||
116 | \ | ||
117 | result = temp; result c_op i; \ | ||
118 | } else { \ | ||
119 | unsigned long flags; \ | ||
120 | \ | ||
121 | raw_local_irq_save(flags); \ | ||
122 | result = v->counter; \ | ||
123 | result c_op i; \ | ||
124 | v->counter = result; \ | ||
125 | raw_local_irq_restore(flags); \ | ||
126 | } \ | ||
127 | \ | ||
128 | smp_llsc_mb(); \ | ||
129 | \ | ||
130 | return result; \ | ||
131 | } | ||
132 | |||
133 | #define ATOMIC_OPS(op, c_op, asm_op) \ | ||
134 | ATOMIC_OP(op, c_op, asm_op) \ | ||
132 | ATOMIC_OP_RETURN(op, c_op, asm_op) | 135 | ATOMIC_OP_RETURN(op, c_op, asm_op) |
133 | 136 | ||
134 | ATOMIC_OPS(add, +=, addu) | 137 | ATOMIC_OPS(add, +=, addu) |
@@ -167,8 +170,9 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) | |||
167 | " .set reorder \n" | 170 | " .set reorder \n" |
168 | "1: \n" | 171 | "1: \n" |
169 | " .set mips0 \n" | 172 | " .set mips0 \n" |
170 | : "=&r" (result), "=&r" (temp), "+m" (v->counter) | 173 | : "=&r" (result), "=&r" (temp), |
171 | : "Ir" (i), "m" (v->counter) | 174 | "+" GCC_OFF12_ASM() (v->counter) |
175 | : "Ir" (i), GCC_OFF12_ASM() (v->counter) | ||
172 | : "memory"); | 176 | : "memory"); |
173 | } else if (kernel_uses_llsc) { | 177 | } else if (kernel_uses_llsc) { |
174 | int temp; | 178 | int temp; |
@@ -185,7 +189,8 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v) | |||
185 | " .set reorder \n" | 189 | " .set reorder \n" |
186 | "1: \n" | 190 | "1: \n" |
187 | " .set mips0 \n" | 191 | " .set mips0 \n" |
188 | : "=&r" (result), "=&r" (temp), "+m" (v->counter) | 192 | : "=&r" (result), "=&r" (temp), |
193 | "+" GCC_OFF12_ASM() (v->counter) | ||
189 | : "Ir" (i)); | 194 | : "Ir" (i)); |
190 | } else { | 195 | } else { |
191 | unsigned long flags; | 196 | unsigned long flags; |
@@ -315,96 +320,98 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) | |||
315 | */ | 320 | */ |
316 | #define atomic64_set(v, i) ((v)->counter = (i)) | 321 | #define atomic64_set(v, i) ((v)->counter = (i)) |
317 | 322 | ||
318 | #define ATOMIC64_OP(op, c_op, asm_op) \ | 323 | #define ATOMIC64_OP(op, c_op, asm_op) \ |
319 | static __inline__ void atomic64_##op(long i, atomic64_t * v) \ | 324 | static __inline__ void atomic64_##op(long i, atomic64_t * v) \ |
320 | { \ | 325 | { \ |
321 | if (kernel_uses_llsc && R10000_LLSC_WAR) { \ | 326 | if (kernel_uses_llsc && R10000_LLSC_WAR) { \ |
322 | long temp; \ | 327 | long temp; \ |
323 | \ | 328 | \ |
324 | __asm__ __volatile__( \ | 329 | __asm__ __volatile__( \ |
325 | " .set arch=r4000 \n" \ | 330 | " .set arch=r4000 \n" \ |
326 | "1: lld %0, %1 # atomic64_" #op " \n" \ | 331 | "1: lld %0, %1 # atomic64_" #op " \n" \ |
327 | " " #asm_op " %0, %2 \n" \ | 332 | " " #asm_op " %0, %2 \n" \ |
328 | " scd %0, %1 \n" \ | 333 | " scd %0, %1 \n" \ |
329 | " beqzl %0, 1b \n" \ | 334 | " beqzl %0, 1b \n" \ |
330 | " .set mips0 \n" \ | 335 | " .set mips0 \n" \ |
331 | : "=&r" (temp), "+m" (v->counter) \ | 336 | : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \ |
332 | : "Ir" (i)); \ | 337 | : "Ir" (i)); \ |
333 | } else if (kernel_uses_llsc) { \ | 338 | } else if (kernel_uses_llsc) { \ |
334 | long temp; \ | 339 | long temp; \ |
335 | \ | 340 | \ |
336 | do { \ | 341 | do { \ |
337 | __asm__ __volatile__( \ | 342 | __asm__ __volatile__( \ |
338 | " .set arch=r4000 \n" \ | 343 | " .set arch=r4000 \n" \ |
339 | " lld %0, %1 # atomic64_" #op "\n" \ | 344 | " lld %0, %1 # atomic64_" #op "\n" \ |
340 | " " #asm_op " %0, %2 \n" \ | 345 | " " #asm_op " %0, %2 \n" \ |
341 | " scd %0, %1 \n" \ | 346 | " scd %0, %1 \n" \ |
342 | " .set mips0 \n" \ | 347 | " .set mips0 \n" \ |
343 | : "=&r" (temp), "+m" (v->counter) \ | 348 | : "=&r" (temp), "+" GCC_OFF12_ASM() (v->counter) \ |
344 | : "Ir" (i)); \ | 349 | : "Ir" (i)); \ |
345 | } while (unlikely(!temp)); \ | 350 | } while (unlikely(!temp)); \ |
346 | } else { \ | 351 | } else { \ |
347 | unsigned long flags; \ | 352 | unsigned long flags; \ |
348 | \ | 353 | \ |
349 | raw_local_irq_save(flags); \ | 354 | raw_local_irq_save(flags); \ |
350 | v->counter c_op i; \ | 355 | v->counter c_op i; \ |
351 | raw_local_irq_restore(flags); \ | 356 | raw_local_irq_restore(flags); \ |
352 | } \ | 357 | } \ |
353 | } \ | 358 | } |
354 | 359 | ||
355 | #define ATOMIC64_OP_RETURN(op, c_op, asm_op) \ | 360 | #define ATOMIC64_OP_RETURN(op, c_op, asm_op) \ |
356 | static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \ | 361 | static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \ |
357 | { \ | 362 | { \ |
358 | long result; \ | 363 | long result; \ |
359 | \ | 364 | \ |
360 | smp_mb__before_llsc(); \ | 365 | smp_mb__before_llsc(); \ |
361 | \ | 366 | \ |
362 | if (kernel_uses_llsc && R10000_LLSC_WAR) { \ | 367 | if (kernel_uses_llsc && R10000_LLSC_WAR) { \ |
363 | long temp; \ | 368 | long temp; \ |
364 | \ | 369 | \ |
365 | __asm__ __volatile__( \ | 370 | __asm__ __volatile__( \ |
366 | " .set arch=r4000 \n" \ | 371 | " .set arch=r4000 \n" \ |
367 | "1: lld %1, %2 # atomic64_" #op "_return\n" \ | 372 | "1: lld %1, %2 # atomic64_" #op "_return\n" \ |
368 | " " #asm_op " %0, %1, %3 \n" \ | 373 | " " #asm_op " %0, %1, %3 \n" \ |
369 | " scd %0, %2 \n" \ | 374 | " scd %0, %2 \n" \ |
370 | " beqzl %0, 1b \n" \ | 375 | " beqzl %0, 1b \n" \ |
371 | " " #asm_op " %0, %1, %3 \n" \ | 376 | " " #asm_op " %0, %1, %3 \n" \ |
372 | " .set mips0 \n" \ | 377 | " .set mips0 \n" \ |
373 | : "=&r" (result), "=&r" (temp), "+m" (v->counter) \ | 378 | : "=&r" (result), "=&r" (temp), \ |
374 | : "Ir" (i)); \ | 379 | "+" GCC_OFF12_ASM() (v->counter) \ |
375 | } else if (kernel_uses_llsc) { \ | 380 | : "Ir" (i)); \ |
376 | long temp; \ | 381 | } else if (kernel_uses_llsc) { \ |
377 | \ | 382 | long temp; \ |
378 | do { \ | 383 | \ |
379 | __asm__ __volatile__( \ | 384 | do { \ |
380 | " .set arch=r4000 \n" \ | 385 | __asm__ __volatile__( \ |
381 | " lld %1, %2 # atomic64_" #op "_return\n" \ | 386 | " .set arch=r4000 \n" \ |
382 | " " #asm_op " %0, %1, %3 \n" \ | 387 | " lld %1, %2 # atomic64_" #op "_return\n" \ |
383 | " scd %0, %2 \n" \ | 388 | " " #asm_op " %0, %1, %3 \n" \ |
384 | " .set mips0 \n" \ | 389 | " scd %0, %2 \n" \ |
385 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) \ | 390 | " .set mips0 \n" \ |
386 | : "Ir" (i), "m" (v->counter) \ | 391 | : "=&r" (result), "=&r" (temp), \ |
387 | : "memory"); \ | 392 | "=" GCC_OFF12_ASM() (v->counter) \ |
388 | } while (unlikely(!result)); \ | 393 | : "Ir" (i), GCC_OFF12_ASM() (v->counter) \ |
389 | \ | 394 | : "memory"); \ |
390 | result = temp; result c_op i; \ | 395 | } while (unlikely(!result)); \ |
391 | } else { \ | 396 | \ |
392 | unsigned long flags; \ | 397 | result = temp; result c_op i; \ |
393 | \ | 398 | } else { \ |
394 | raw_local_irq_save(flags); \ | 399 | unsigned long flags; \ |
395 | result = v->counter; \ | 400 | \ |
396 | result c_op i; \ | 401 | raw_local_irq_save(flags); \ |
397 | v->counter = result; \ | 402 | result = v->counter; \ |
398 | raw_local_irq_restore(flags); \ | 403 | result c_op i; \ |
399 | } \ | 404 | v->counter = result; \ |
400 | \ | 405 | raw_local_irq_restore(flags); \ |
401 | smp_llsc_mb(); \ | 406 | } \ |
402 | \ | 407 | \ |
403 | return result; \ | 408 | smp_llsc_mb(); \ |
409 | \ | ||
410 | return result; \ | ||
404 | } | 411 | } |
405 | 412 | ||
406 | #define ATOMIC64_OPS(op, c_op, asm_op) \ | 413 | #define ATOMIC64_OPS(op, c_op, asm_op) \ |
407 | ATOMIC64_OP(op, c_op, asm_op) \ | 414 | ATOMIC64_OP(op, c_op, asm_op) \ |
408 | ATOMIC64_OP_RETURN(op, c_op, asm_op) | 415 | ATOMIC64_OP_RETURN(op, c_op, asm_op) |
409 | 416 | ||
410 | ATOMIC64_OPS(add, +=, daddu) | 417 | ATOMIC64_OPS(add, +=, daddu) |
@@ -415,7 +422,8 @@ ATOMIC64_OPS(sub, -=, dsubu) | |||
415 | #undef ATOMIC64_OP | 422 | #undef ATOMIC64_OP |
416 | 423 | ||
417 | /* | 424 | /* |
418 | * atomic64_sub_if_positive - conditionally subtract integer from atomic variable | 425 | * atomic64_sub_if_positive - conditionally subtract integer from atomic |
426 | * variable | ||
419 | * @i: integer value to subtract | 427 | * @i: integer value to subtract |
420 | * @v: pointer of type atomic64_t | 428 | * @v: pointer of type atomic64_t |
421 | * | 429 | * |
@@ -443,8 +451,9 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) | |||
443 | " .set reorder \n" | 451 | " .set reorder \n" |
444 | "1: \n" | 452 | "1: \n" |
445 | " .set mips0 \n" | 453 | " .set mips0 \n" |
446 | : "=&r" (result), "=&r" (temp), "=m" (v->counter) | 454 | : "=&r" (result), "=&r" (temp), |
447 | : "Ir" (i), "m" (v->counter) | 455 | "=" GCC_OFF12_ASM() (v->counter) |
456 | : "Ir" (i), GCC_OFF12_ASM() (v->counter) | ||
448 | : "memory"); | 457 | : "memory"); |
449 | } else if (kernel_uses_llsc) { | 458 | } else if (kernel_uses_llsc) { |
450 | long temp; | 459 | long temp; |
@@ -461,7 +470,8 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v) | |||
461 | " .set reorder \n" | 470 | " .set reorder \n" |
462 | "1: \n" | 471 | "1: \n" |
463 | " .set mips0 \n" | 472 | " .set mips0 \n" |
464 | : "=&r" (result), "=&r" (temp), "+m" (v->counter) | 473 | : "=&r" (result), "=&r" (temp), |
474 | "+" GCC_OFF12_ASM() (v->counter) | ||
465 | : "Ir" (i)); | 475 | : "Ir" (i)); |
466 | } else { | 476 | } else { |
467 | unsigned long flags; | 477 | unsigned long flags; |
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h index bae6b0fa8ab5..6663bcca9d0c 100644 --- a/arch/mips/include/asm/bitops.h +++ b/arch/mips/include/asm/bitops.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | #include <asm/barrier.h> | 18 | #include <asm/barrier.h> |
19 | #include <asm/byteorder.h> /* sigh ... */ | 19 | #include <asm/byteorder.h> /* sigh ... */ |
20 | #include <asm/compiler.h> | ||
20 | #include <asm/cpu-features.h> | 21 | #include <asm/cpu-features.h> |
21 | #include <asm/sgidefs.h> | 22 | #include <asm/sgidefs.h> |
22 | #include <asm/war.h> | 23 | #include <asm/war.h> |
@@ -78,8 +79,8 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) | |||
78 | " " __SC "%0, %1 \n" | 79 | " " __SC "%0, %1 \n" |
79 | " beqzl %0, 1b \n" | 80 | " beqzl %0, 1b \n" |
80 | " .set mips0 \n" | 81 | " .set mips0 \n" |
81 | : "=&r" (temp), "=m" (*m) | 82 | : "=&r" (temp), "=" GCC_OFF12_ASM() (*m) |
82 | : "ir" (1UL << bit), "m" (*m)); | 83 | : "ir" (1UL << bit), GCC_OFF12_ASM() (*m)); |
83 | #ifdef CONFIG_CPU_MIPSR2 | 84 | #ifdef CONFIG_CPU_MIPSR2 |
84 | } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { | 85 | } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { |
85 | do { | 86 | do { |
@@ -87,7 +88,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) | |||
87 | " " __LL "%0, %1 # set_bit \n" | 88 | " " __LL "%0, %1 # set_bit \n" |
88 | " " __INS "%0, %3, %2, 1 \n" | 89 | " " __INS "%0, %3, %2, 1 \n" |
89 | " " __SC "%0, %1 \n" | 90 | " " __SC "%0, %1 \n" |
90 | : "=&r" (temp), "+m" (*m) | 91 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m) |
91 | : "ir" (bit), "r" (~0)); | 92 | : "ir" (bit), "r" (~0)); |
92 | } while (unlikely(!temp)); | 93 | } while (unlikely(!temp)); |
93 | #endif /* CONFIG_CPU_MIPSR2 */ | 94 | #endif /* CONFIG_CPU_MIPSR2 */ |
@@ -99,7 +100,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) | |||
99 | " or %0, %2 \n" | 100 | " or %0, %2 \n" |
100 | " " __SC "%0, %1 \n" | 101 | " " __SC "%0, %1 \n" |
101 | " .set mips0 \n" | 102 | " .set mips0 \n" |
102 | : "=&r" (temp), "+m" (*m) | 103 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m) |
103 | : "ir" (1UL << bit)); | 104 | : "ir" (1UL << bit)); |
104 | } while (unlikely(!temp)); | 105 | } while (unlikely(!temp)); |
105 | } else | 106 | } else |
@@ -130,7 +131,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) | |||
130 | " " __SC "%0, %1 \n" | 131 | " " __SC "%0, %1 \n" |
131 | " beqzl %0, 1b \n" | 132 | " beqzl %0, 1b \n" |
132 | " .set mips0 \n" | 133 | " .set mips0 \n" |
133 | : "=&r" (temp), "+m" (*m) | 134 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m) |
134 | : "ir" (~(1UL << bit))); | 135 | : "ir" (~(1UL << bit))); |
135 | #ifdef CONFIG_CPU_MIPSR2 | 136 | #ifdef CONFIG_CPU_MIPSR2 |
136 | } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { | 137 | } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { |
@@ -139,7 +140,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) | |||
139 | " " __LL "%0, %1 # clear_bit \n" | 140 | " " __LL "%0, %1 # clear_bit \n" |
140 | " " __INS "%0, $0, %2, 1 \n" | 141 | " " __INS "%0, $0, %2, 1 \n" |
141 | " " __SC "%0, %1 \n" | 142 | " " __SC "%0, %1 \n" |
142 | : "=&r" (temp), "+m" (*m) | 143 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m) |
143 | : "ir" (bit)); | 144 | : "ir" (bit)); |
144 | } while (unlikely(!temp)); | 145 | } while (unlikely(!temp)); |
145 | #endif /* CONFIG_CPU_MIPSR2 */ | 146 | #endif /* CONFIG_CPU_MIPSR2 */ |
@@ -151,7 +152,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) | |||
151 | " and %0, %2 \n" | 152 | " and %0, %2 \n" |
152 | " " __SC "%0, %1 \n" | 153 | " " __SC "%0, %1 \n" |
153 | " .set mips0 \n" | 154 | " .set mips0 \n" |
154 | : "=&r" (temp), "+m" (*m) | 155 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m) |
155 | : "ir" (~(1UL << bit))); | 156 | : "ir" (~(1UL << bit))); |
156 | } while (unlikely(!temp)); | 157 | } while (unlikely(!temp)); |
157 | } else | 158 | } else |
@@ -196,7 +197,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) | |||
196 | " " __SC "%0, %1 \n" | 197 | " " __SC "%0, %1 \n" |
197 | " beqzl %0, 1b \n" | 198 | " beqzl %0, 1b \n" |
198 | " .set mips0 \n" | 199 | " .set mips0 \n" |
199 | : "=&r" (temp), "+m" (*m) | 200 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m) |
200 | : "ir" (1UL << bit)); | 201 | : "ir" (1UL << bit)); |
201 | } else if (kernel_uses_llsc) { | 202 | } else if (kernel_uses_llsc) { |
202 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); | 203 | unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); |
@@ -209,7 +210,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) | |||
209 | " xor %0, %2 \n" | 210 | " xor %0, %2 \n" |
210 | " " __SC "%0, %1 \n" | 211 | " " __SC "%0, %1 \n" |
211 | " .set mips0 \n" | 212 | " .set mips0 \n" |
212 | : "=&r" (temp), "+m" (*m) | 213 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m) |
213 | : "ir" (1UL << bit)); | 214 | : "ir" (1UL << bit)); |
214 | } while (unlikely(!temp)); | 215 | } while (unlikely(!temp)); |
215 | } else | 216 | } else |
@@ -244,7 +245,7 @@ static inline int test_and_set_bit(unsigned long nr, | |||
244 | " beqzl %2, 1b \n" | 245 | " beqzl %2, 1b \n" |
245 | " and %2, %0, %3 \n" | 246 | " and %2, %0, %3 \n" |
246 | " .set mips0 \n" | 247 | " .set mips0 \n" |
247 | : "=&r" (temp), "+m" (*m), "=&r" (res) | 248 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) |
248 | : "r" (1UL << bit) | 249 | : "r" (1UL << bit) |
249 | : "memory"); | 250 | : "memory"); |
250 | } else if (kernel_uses_llsc) { | 251 | } else if (kernel_uses_llsc) { |
@@ -258,7 +259,7 @@ static inline int test_and_set_bit(unsigned long nr, | |||
258 | " or %2, %0, %3 \n" | 259 | " or %2, %0, %3 \n" |
259 | " " __SC "%2, %1 \n" | 260 | " " __SC "%2, %1 \n" |
260 | " .set mips0 \n" | 261 | " .set mips0 \n" |
261 | : "=&r" (temp), "+m" (*m), "=&r" (res) | 262 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) |
262 | : "r" (1UL << bit) | 263 | : "r" (1UL << bit) |
263 | : "memory"); | 264 | : "memory"); |
264 | } while (unlikely(!res)); | 265 | } while (unlikely(!res)); |
@@ -312,7 +313,7 @@ static inline int test_and_set_bit_lock(unsigned long nr, | |||
312 | " or %2, %0, %3 \n" | 313 | " or %2, %0, %3 \n" |
313 | " " __SC "%2, %1 \n" | 314 | " " __SC "%2, %1 \n" |
314 | " .set mips0 \n" | 315 | " .set mips0 \n" |
315 | : "=&r" (temp), "+m" (*m), "=&r" (res) | 316 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) |
316 | : "r" (1UL << bit) | 317 | : "r" (1UL << bit) |
317 | : "memory"); | 318 | : "memory"); |
318 | } while (unlikely(!res)); | 319 | } while (unlikely(!res)); |
@@ -354,7 +355,7 @@ static inline int test_and_clear_bit(unsigned long nr, | |||
354 | " beqzl %2, 1b \n" | 355 | " beqzl %2, 1b \n" |
355 | " and %2, %0, %3 \n" | 356 | " and %2, %0, %3 \n" |
356 | " .set mips0 \n" | 357 | " .set mips0 \n" |
357 | : "=&r" (temp), "+m" (*m), "=&r" (res) | 358 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) |
358 | : "r" (1UL << bit) | 359 | : "r" (1UL << bit) |
359 | : "memory"); | 360 | : "memory"); |
360 | #ifdef CONFIG_CPU_MIPSR2 | 361 | #ifdef CONFIG_CPU_MIPSR2 |
@@ -368,7 +369,7 @@ static inline int test_and_clear_bit(unsigned long nr, | |||
368 | " " __EXT "%2, %0, %3, 1 \n" | 369 | " " __EXT "%2, %0, %3, 1 \n" |
369 | " " __INS "%0, $0, %3, 1 \n" | 370 | " " __INS "%0, $0, %3, 1 \n" |
370 | " " __SC "%0, %1 \n" | 371 | " " __SC "%0, %1 \n" |
371 | : "=&r" (temp), "+m" (*m), "=&r" (res) | 372 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) |
372 | : "ir" (bit) | 373 | : "ir" (bit) |
373 | : "memory"); | 374 | : "memory"); |
374 | } while (unlikely(!temp)); | 375 | } while (unlikely(!temp)); |
@@ -385,7 +386,7 @@ static inline int test_and_clear_bit(unsigned long nr, | |||
385 | " xor %2, %3 \n" | 386 | " xor %2, %3 \n" |
386 | " " __SC "%2, %1 \n" | 387 | " " __SC "%2, %1 \n" |
387 | " .set mips0 \n" | 388 | " .set mips0 \n" |
388 | : "=&r" (temp), "+m" (*m), "=&r" (res) | 389 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) |
389 | : "r" (1UL << bit) | 390 | : "r" (1UL << bit) |
390 | : "memory"); | 391 | : "memory"); |
391 | } while (unlikely(!res)); | 392 | } while (unlikely(!res)); |
@@ -427,7 +428,7 @@ static inline int test_and_change_bit(unsigned long nr, | |||
427 | " beqzl %2, 1b \n" | 428 | " beqzl %2, 1b \n" |
428 | " and %2, %0, %3 \n" | 429 | " and %2, %0, %3 \n" |
429 | " .set mips0 \n" | 430 | " .set mips0 \n" |
430 | : "=&r" (temp), "+m" (*m), "=&r" (res) | 431 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) |
431 | : "r" (1UL << bit) | 432 | : "r" (1UL << bit) |
432 | : "memory"); | 433 | : "memory"); |
433 | } else if (kernel_uses_llsc) { | 434 | } else if (kernel_uses_llsc) { |
@@ -441,7 +442,7 @@ static inline int test_and_change_bit(unsigned long nr, | |||
441 | " xor %2, %0, %3 \n" | 442 | " xor %2, %0, %3 \n" |
442 | " " __SC "\t%2, %1 \n" | 443 | " " __SC "\t%2, %1 \n" |
443 | " .set mips0 \n" | 444 | " .set mips0 \n" |
444 | : "=&r" (temp), "+m" (*m), "=&r" (res) | 445 | : "=&r" (temp), "+" GCC_OFF12_ASM() (*m), "=&r" (res) |
445 | : "r" (1UL << bit) | 446 | : "r" (1UL << bit) |
446 | : "memory"); | 447 | : "memory"); |
447 | } while (unlikely(!res)); | 448 | } while (unlikely(!res)); |
diff --git a/arch/mips/include/asm/bmips.h b/arch/mips/include/asm/bmips.h index cbaccebf5065..30939b02e3ff 100644 --- a/arch/mips/include/asm/bmips.h +++ b/arch/mips/include/asm/bmips.h | |||
@@ -84,6 +84,7 @@ extern char bmips_smp_int_vec_end; | |||
84 | extern int bmips_smp_enabled; | 84 | extern int bmips_smp_enabled; |
85 | extern int bmips_cpu_offset; | 85 | extern int bmips_cpu_offset; |
86 | extern cpumask_t bmips_booted_mask; | 86 | extern cpumask_t bmips_booted_mask; |
87 | extern unsigned long bmips_tp1_irqs; | ||
87 | 88 | ||
88 | extern void bmips_ebase_setup(void); | 89 | extern void bmips_ebase_setup(void); |
89 | extern asmlinkage void plat_wired_tlb_setup(void); | 90 | extern asmlinkage void plat_wired_tlb_setup(void); |
diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h index 1f7ca8b00404..b603804caac5 100644 --- a/arch/mips/include/asm/bootinfo.h +++ b/arch/mips/include/asm/bootinfo.h | |||
@@ -70,10 +70,7 @@ enum loongson_machine_type { | |||
70 | MACH_DEXXON_GDIUM2F10, | 70 | MACH_DEXXON_GDIUM2F10, |
71 | MACH_LEMOTE_NAS, | 71 | MACH_LEMOTE_NAS, |
72 | MACH_LEMOTE_LL2F, | 72 | MACH_LEMOTE_LL2F, |
73 | MACH_LEMOTE_A1004, | 73 | MACH_LOONGSON_GENERIC, |
74 | MACH_LEMOTE_A1101, | ||
75 | MACH_LEMOTE_A1201, | ||
76 | MACH_LEMOTE_A1205, | ||
77 | MACH_LOONGSON_END | 74 | MACH_LOONGSON_END |
78 | }; | 75 | }; |
79 | 76 | ||
@@ -101,16 +98,16 @@ extern unsigned long mips_machtype; | |||
101 | struct boot_mem_map { | 98 | struct boot_mem_map { |
102 | int nr_map; | 99 | int nr_map; |
103 | struct boot_mem_map_entry { | 100 | struct boot_mem_map_entry { |
104 | phys_t addr; /* start of memory segment */ | 101 | phys_addr_t addr; /* start of memory segment */ |
105 | phys_t size; /* size of memory segment */ | 102 | phys_addr_t size; /* size of memory segment */ |
106 | long type; /* type of memory segment */ | 103 | long type; /* type of memory segment */ |
107 | } map[BOOT_MEM_MAP_MAX]; | 104 | } map[BOOT_MEM_MAP_MAX]; |
108 | }; | 105 | }; |
109 | 106 | ||
110 | extern struct boot_mem_map boot_mem_map; | 107 | extern struct boot_mem_map boot_mem_map; |
111 | 108 | ||
112 | extern void add_memory_region(phys_t start, phys_t size, long type); | 109 | extern void add_memory_region(phys_addr_t start, phys_addr_t size, long type); |
113 | extern void detect_memory_region(phys_t start, phys_t sz_min, phys_t sz_max); | 110 | extern void detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max); |
114 | 111 | ||
115 | extern void prom_init(void); | 112 | extern void prom_init(void); |
116 | extern void prom_free_prom_memory(void); | 113 | extern void prom_free_prom_memory(void); |
diff --git a/arch/mips/include/asm/clock.h b/arch/mips/include/asm/clock.h index 778e32d817bc..4809c29a4890 100644 --- a/arch/mips/include/asm/clock.h +++ b/arch/mips/include/asm/clock.h | |||
@@ -35,9 +35,6 @@ struct clk { | |||
35 | #define CLK_ALWAYS_ENABLED (1 << 0) | 35 | #define CLK_ALWAYS_ENABLED (1 << 0) |
36 | #define CLK_RATE_PROPAGATES (1 << 1) | 36 | #define CLK_RATE_PROPAGATES (1 << 1) |
37 | 37 | ||
38 | /* Should be defined by processor-specific code */ | ||
39 | void arch_init_clk_ops(struct clk_ops **, int type); | ||
40 | |||
41 | int clk_init(void); | 38 | int clk_init(void); |
42 | 39 | ||
43 | int __clk_enable(struct clk *); | 40 | int __clk_enable(struct clk *); |
diff --git a/arch/mips/include/asm/cmpxchg.h b/arch/mips/include/asm/cmpxchg.h index eefcaa363a87..28b1edf19501 100644 --- a/arch/mips/include/asm/cmpxchg.h +++ b/arch/mips/include/asm/cmpxchg.h | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #include <linux/bug.h> | 11 | #include <linux/bug.h> |
12 | #include <linux/irqflags.h> | 12 | #include <linux/irqflags.h> |
13 | #include <asm/compiler.h> | ||
13 | #include <asm/war.h> | 14 | #include <asm/war.h> |
14 | 15 | ||
15 | static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) | 16 | static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) |
@@ -30,8 +31,8 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) | |||
30 | " sc %2, %1 \n" | 31 | " sc %2, %1 \n" |
31 | " beqzl %2, 1b \n" | 32 | " beqzl %2, 1b \n" |
32 | " .set mips0 \n" | 33 | " .set mips0 \n" |
33 | : "=&r" (retval), "=m" (*m), "=&r" (dummy) | 34 | : "=&r" (retval), "=" GCC_OFF12_ASM() (*m), "=&r" (dummy) |
34 | : "R" (*m), "Jr" (val) | 35 | : GCC_OFF12_ASM() (*m), "Jr" (val) |
35 | : "memory"); | 36 | : "memory"); |
36 | } else if (kernel_uses_llsc) { | 37 | } else if (kernel_uses_llsc) { |
37 | unsigned long dummy; | 38 | unsigned long dummy; |
@@ -45,8 +46,9 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) | |||
45 | " .set arch=r4000 \n" | 46 | " .set arch=r4000 \n" |
46 | " sc %2, %1 \n" | 47 | " sc %2, %1 \n" |
47 | " .set mips0 \n" | 48 | " .set mips0 \n" |
48 | : "=&r" (retval), "=m" (*m), "=&r" (dummy) | 49 | : "=&r" (retval), "=" GCC_OFF12_ASM() (*m), |
49 | : "R" (*m), "Jr" (val) | 50 | "=&r" (dummy) |
51 | : GCC_OFF12_ASM() (*m), "Jr" (val) | ||
50 | : "memory"); | 52 | : "memory"); |
51 | } while (unlikely(!dummy)); | 53 | } while (unlikely(!dummy)); |
52 | } else { | 54 | } else { |
@@ -80,8 +82,8 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val) | |||
80 | " scd %2, %1 \n" | 82 | " scd %2, %1 \n" |
81 | " beqzl %2, 1b \n" | 83 | " beqzl %2, 1b \n" |
82 | " .set mips0 \n" | 84 | " .set mips0 \n" |
83 | : "=&r" (retval), "=m" (*m), "=&r" (dummy) | 85 | : "=&r" (retval), "=" GCC_OFF12_ASM() (*m), "=&r" (dummy) |
84 | : "R" (*m), "Jr" (val) | 86 | : GCC_OFF12_ASM() (*m), "Jr" (val) |
85 | : "memory"); | 87 | : "memory"); |
86 | } else if (kernel_uses_llsc) { | 88 | } else if (kernel_uses_llsc) { |
87 | unsigned long dummy; | 89 | unsigned long dummy; |
@@ -93,8 +95,9 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val) | |||
93 | " move %2, %z4 \n" | 95 | " move %2, %z4 \n" |
94 | " scd %2, %1 \n" | 96 | " scd %2, %1 \n" |
95 | " .set mips0 \n" | 97 | " .set mips0 \n" |
96 | : "=&r" (retval), "=m" (*m), "=&r" (dummy) | 98 | : "=&r" (retval), "=" GCC_OFF12_ASM() (*m), |
97 | : "R" (*m), "Jr" (val) | 99 | "=&r" (dummy) |
100 | : GCC_OFF12_ASM() (*m), "Jr" (val) | ||
98 | : "memory"); | 101 | : "memory"); |
99 | } while (unlikely(!dummy)); | 102 | } while (unlikely(!dummy)); |
100 | } else { | 103 | } else { |
@@ -155,8 +158,8 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz | |||
155 | " beqzl $1, 1b \n" \ | 158 | " beqzl $1, 1b \n" \ |
156 | "2: \n" \ | 159 | "2: \n" \ |
157 | " .set pop \n" \ | 160 | " .set pop \n" \ |
158 | : "=&r" (__ret), "=R" (*m) \ | 161 | : "=&r" (__ret), "=" GCC_OFF12_ASM() (*m) \ |
159 | : "R" (*m), "Jr" (old), "Jr" (new) \ | 162 | : GCC_OFF12_ASM() (*m), "Jr" (old), "Jr" (new) \ |
160 | : "memory"); \ | 163 | : "memory"); \ |
161 | } else if (kernel_uses_llsc) { \ | 164 | } else if (kernel_uses_llsc) { \ |
162 | __asm__ __volatile__( \ | 165 | __asm__ __volatile__( \ |
@@ -172,8 +175,8 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz | |||
172 | " beqz $1, 1b \n" \ | 175 | " beqz $1, 1b \n" \ |
173 | " .set pop \n" \ | 176 | " .set pop \n" \ |
174 | "2: \n" \ | 177 | "2: \n" \ |
175 | : "=&r" (__ret), "=R" (*m) \ | 178 | : "=&r" (__ret), "=" GCC_OFF12_ASM() (*m) \ |
176 | : "R" (*m), "Jr" (old), "Jr" (new) \ | 179 | : GCC_OFF12_ASM() (*m), "Jr" (old), "Jr" (new) \ |
177 | : "memory"); \ | 180 | : "memory"); \ |
178 | } else { \ | 181 | } else { \ |
179 | unsigned long __flags; \ | 182 | unsigned long __flags; \ |
diff --git a/arch/mips/include/asm/compiler.h b/arch/mips/include/asm/compiler.h index 71f5c5cfc58a..c73815e0123a 100644 --- a/arch/mips/include/asm/compiler.h +++ b/arch/mips/include/asm/compiler.h | |||
@@ -16,4 +16,12 @@ | |||
16 | #define GCC_REG_ACCUM "accum" | 16 | #define GCC_REG_ACCUM "accum" |
17 | #endif | 17 | #endif |
18 | 18 | ||
19 | #ifndef CONFIG_CPU_MICROMIPS | ||
20 | #define GCC_OFF12_ASM() "R" | ||
21 | #elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9) | ||
22 | #define GCC_OFF12_ASM() "ZC" | ||
23 | #else | ||
24 | #error "microMIPS compilation unsupported with GCC older than 4.9" | ||
25 | #endif | ||
26 | |||
19 | #endif /* _ASM_COMPILER_H */ | 27 | #endif /* _ASM_COMPILER_H */ |
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index 3325f3eb248c..2897cfafcaf0 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h | |||
@@ -344,4 +344,8 @@ | |||
344 | # define cpu_has_msa 0 | 344 | # define cpu_has_msa 0 |
345 | #endif | 345 | #endif |
346 | 346 | ||
347 | #ifndef cpu_has_fre | ||
348 | # define cpu_has_fre (cpu_data[0].options & MIPS_CPU_FRE) | ||
349 | #endif | ||
350 | |||
347 | #endif /* __ASM_CPU_FEATURES_H */ | 351 | #endif /* __ASM_CPU_FEATURES_H */ |
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index dfdc77ed1839..33866fce4d63 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h | |||
@@ -142,6 +142,7 @@ | |||
142 | #define PRID_IMP_BMIPS3300_BUG 0x0000 | 142 | #define PRID_IMP_BMIPS3300_BUG 0x0000 |
143 | #define PRID_IMP_BMIPS43XX 0xa000 | 143 | #define PRID_IMP_BMIPS43XX 0xa000 |
144 | #define PRID_IMP_BMIPS5000 0x5a00 | 144 | #define PRID_IMP_BMIPS5000 0x5a00 |
145 | #define PRID_IMP_BMIPS5200 0x5b00 | ||
145 | 146 | ||
146 | #define PRID_REV_BMIPS4380_LO 0x0040 | 147 | #define PRID_REV_BMIPS4380_LO 0x0040 |
147 | #define PRID_REV_BMIPS4380_HI 0x006f | 148 | #define PRID_REV_BMIPS4380_HI 0x006f |
@@ -368,6 +369,7 @@ enum cpu_type_enum { | |||
368 | #define MIPS_CPU_HTW 0x100000000ull /* CPU support Hardware Page Table Walker */ | 369 | #define MIPS_CPU_HTW 0x100000000ull /* CPU support Hardware Page Table Walker */ |
369 | #define MIPS_CPU_RIXIEX 0x200000000ull /* CPU has unique exception codes for {Read, Execute}-Inhibit exceptions */ | 370 | #define MIPS_CPU_RIXIEX 0x200000000ull /* CPU has unique exception codes for {Read, Execute}-Inhibit exceptions */ |
370 | #define MIPS_CPU_MAAR 0x400000000ull /* MAAR(I) registers are present */ | 371 | #define MIPS_CPU_MAAR 0x400000000ull /* MAAR(I) registers are present */ |
372 | #define MIPS_CPU_FRE 0x800000000ull /* FRE & UFE bits implemented */ | ||
371 | 373 | ||
372 | /* | 374 | /* |
373 | * CPU ASE encodings | 375 | * CPU ASE encodings |
diff --git a/arch/mips/include/asm/edac.h b/arch/mips/include/asm/edac.h index 4da0c1fe30d9..ae6fedcb0060 100644 --- a/arch/mips/include/asm/edac.h +++ b/arch/mips/include/asm/edac.h | |||
@@ -1,6 +1,8 @@ | |||
1 | #ifndef ASM_EDAC_H | 1 | #ifndef ASM_EDAC_H |
2 | #define ASM_EDAC_H | 2 | #define ASM_EDAC_H |
3 | 3 | ||
4 | #include <asm/compiler.h> | ||
5 | |||
4 | /* ECC atomic, DMA, SMP and interrupt safe scrub function */ | 6 | /* ECC atomic, DMA, SMP and interrupt safe scrub function */ |
5 | 7 | ||
6 | static inline void atomic_scrub(void *va, u32 size) | 8 | static inline void atomic_scrub(void *va, u32 size) |
@@ -24,8 +26,8 @@ static inline void atomic_scrub(void *va, u32 size) | |||
24 | " sc %0, %1 \n" | 26 | " sc %0, %1 \n" |
25 | " beqz %0, 1b \n" | 27 | " beqz %0, 1b \n" |
26 | " .set mips0 \n" | 28 | " .set mips0 \n" |
27 | : "=&r" (temp), "=m" (*virt_addr) | 29 | : "=&r" (temp), "=" GCC_OFF12_ASM() (*virt_addr) |
28 | : "m" (*virt_addr)); | 30 | : GCC_OFF12_ASM() (*virt_addr)); |
29 | 31 | ||
30 | virt_addr++; | 32 | virt_addr++; |
31 | } | 33 | } |
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index 1d38fe0edd2d..eb4d95de619c 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h | |||
@@ -8,6 +8,8 @@ | |||
8 | #ifndef _ASM_ELF_H | 8 | #ifndef _ASM_ELF_H |
9 | #define _ASM_ELF_H | 9 | #define _ASM_ELF_H |
10 | 10 | ||
11 | #include <linux/fs.h> | ||
12 | #include <uapi/linux/elf.h> | ||
11 | 13 | ||
12 | /* ELF header e_flags defines. */ | 14 | /* ELF header e_flags defines. */ |
13 | /* MIPS architecture level. */ | 15 | /* MIPS architecture level. */ |
@@ -28,6 +30,7 @@ | |||
28 | #define PT_MIPS_REGINFO 0x70000000 | 30 | #define PT_MIPS_REGINFO 0x70000000 |
29 | #define PT_MIPS_RTPROC 0x70000001 | 31 | #define PT_MIPS_RTPROC 0x70000001 |
30 | #define PT_MIPS_OPTIONS 0x70000002 | 32 | #define PT_MIPS_OPTIONS 0x70000002 |
33 | #define PT_MIPS_ABIFLAGS 0x70000003 | ||
31 | 34 | ||
32 | /* Flags in the e_flags field of the header */ | 35 | /* Flags in the e_flags field of the header */ |
33 | #define EF_MIPS_NOREORDER 0x00000001 | 36 | #define EF_MIPS_NOREORDER 0x00000001 |
@@ -174,6 +177,30 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | |||
174 | typedef double elf_fpreg_t; | 177 | typedef double elf_fpreg_t; |
175 | typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; | 178 | typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; |
176 | 179 | ||
180 | struct mips_elf_abiflags_v0 { | ||
181 | uint16_t version; /* Version of flags structure */ | ||
182 | uint8_t isa_level; /* The level of the ISA: 1-5, 32, 64 */ | ||
183 | uint8_t isa_rev; /* The revision of ISA: 0 for MIPS V and below, | ||
184 | 1-n otherwise */ | ||
185 | uint8_t gpr_size; /* The size of general purpose registers */ | ||
186 | uint8_t cpr1_size; /* The size of co-processor 1 registers */ | ||
187 | uint8_t cpr2_size; /* The size of co-processor 2 registers */ | ||
188 | uint8_t fp_abi; /* The floating-point ABI */ | ||
189 | uint32_t isa_ext; /* Mask of processor-specific extensions */ | ||
190 | uint32_t ases; /* Mask of ASEs used */ | ||
191 | uint32_t flags1; /* Mask of general flags */ | ||
192 | uint32_t flags2; | ||
193 | }; | ||
194 | |||
195 | #define MIPS_ABI_FP_ANY 0 /* FP ABI doesn't matter */ | ||
196 | #define MIPS_ABI_FP_DOUBLE 1 /* -mdouble-float */ | ||
197 | #define MIPS_ABI_FP_SINGLE 2 /* -msingle-float */ | ||
198 | #define MIPS_ABI_FP_SOFT 3 /* -msoft-float */ | ||
199 | #define MIPS_ABI_FP_OLD_64 4 /* -mips32r2 -mfp64 */ | ||
200 | #define MIPS_ABI_FP_XX 5 /* -mfpxx */ | ||
201 | #define MIPS_ABI_FP_64 6 /* -mips32r2 -mfp64 */ | ||
202 | #define MIPS_ABI_FP_64A 7 /* -mips32r2 -mfp64 -mno-odd-spreg */ | ||
203 | |||
177 | #ifdef CONFIG_32BIT | 204 | #ifdef CONFIG_32BIT |
178 | 205 | ||
179 | /* | 206 | /* |
@@ -262,16 +289,13 @@ extern struct mips_abi mips_abi_n32; | |||
262 | 289 | ||
263 | #ifdef CONFIG_32BIT | 290 | #ifdef CONFIG_32BIT |
264 | 291 | ||
265 | #define SET_PERSONALITY(ex) \ | 292 | #define SET_PERSONALITY2(ex, state) \ |
266 | do { \ | 293 | do { \ |
267 | if ((ex).e_flags & EF_MIPS_FP64) \ | ||
268 | clear_thread_flag(TIF_32BIT_FPREGS); \ | ||
269 | else \ | ||
270 | set_thread_flag(TIF_32BIT_FPREGS); \ | ||
271 | \ | ||
272 | if (personality(current->personality) != PER_LINUX) \ | 294 | if (personality(current->personality) != PER_LINUX) \ |
273 | set_personality(PER_LINUX); \ | 295 | set_personality(PER_LINUX); \ |
274 | \ | 296 | \ |
297 | mips_set_personality_fp(state); \ | ||
298 | \ | ||
275 | current->thread.abi = &mips_abi; \ | 299 | current->thread.abi = &mips_abi; \ |
276 | } while (0) | 300 | } while (0) |
277 | 301 | ||
@@ -291,44 +315,44 @@ do { \ | |||
291 | #endif | 315 | #endif |
292 | 316 | ||
293 | #ifdef CONFIG_MIPS32_O32 | 317 | #ifdef CONFIG_MIPS32_O32 |
294 | #define __SET_PERSONALITY32_O32(ex) \ | 318 | #define __SET_PERSONALITY32_O32(ex, state) \ |
295 | do { \ | 319 | do { \ |
296 | set_thread_flag(TIF_32BIT_REGS); \ | 320 | set_thread_flag(TIF_32BIT_REGS); \ |
297 | set_thread_flag(TIF_32BIT_ADDR); \ | 321 | set_thread_flag(TIF_32BIT_ADDR); \ |
298 | \ | 322 | \ |
299 | if (!((ex).e_flags & EF_MIPS_FP64)) \ | 323 | mips_set_personality_fp(state); \ |
300 | set_thread_flag(TIF_32BIT_FPREGS); \ | ||
301 | \ | 324 | \ |
302 | current->thread.abi = &mips_abi_32; \ | 325 | current->thread.abi = &mips_abi_32; \ |
303 | } while (0) | 326 | } while (0) |
304 | #else | 327 | #else |
305 | #define __SET_PERSONALITY32_O32(ex) \ | 328 | #define __SET_PERSONALITY32_O32(ex, state) \ |
306 | do { } while (0) | 329 | do { } while (0) |
307 | #endif | 330 | #endif |
308 | 331 | ||
309 | #ifdef CONFIG_MIPS32_COMPAT | 332 | #ifdef CONFIG_MIPS32_COMPAT |
310 | #define __SET_PERSONALITY32(ex) \ | 333 | #define __SET_PERSONALITY32(ex, state) \ |
311 | do { \ | 334 | do { \ |
312 | if ((((ex).e_flags & EF_MIPS_ABI2) != 0) && \ | 335 | if ((((ex).e_flags & EF_MIPS_ABI2) != 0) && \ |
313 | ((ex).e_flags & EF_MIPS_ABI) == 0) \ | 336 | ((ex).e_flags & EF_MIPS_ABI) == 0) \ |
314 | __SET_PERSONALITY32_N32(); \ | 337 | __SET_PERSONALITY32_N32(); \ |
315 | else \ | 338 | else \ |
316 | __SET_PERSONALITY32_O32(ex); \ | 339 | __SET_PERSONALITY32_O32(ex, state); \ |
317 | } while (0) | 340 | } while (0) |
318 | #else | 341 | #else |
319 | #define __SET_PERSONALITY32(ex) do { } while (0) | 342 | #define __SET_PERSONALITY32(ex, state) do { } while (0) |
320 | #endif | 343 | #endif |
321 | 344 | ||
322 | #define SET_PERSONALITY(ex) \ | 345 | #define SET_PERSONALITY2(ex, state) \ |
323 | do { \ | 346 | do { \ |
324 | unsigned int p; \ | 347 | unsigned int p; \ |
325 | \ | 348 | \ |
326 | clear_thread_flag(TIF_32BIT_REGS); \ | 349 | clear_thread_flag(TIF_32BIT_REGS); \ |
327 | clear_thread_flag(TIF_32BIT_FPREGS); \ | 350 | clear_thread_flag(TIF_32BIT_FPREGS); \ |
351 | clear_thread_flag(TIF_HYBRID_FPREGS); \ | ||
328 | clear_thread_flag(TIF_32BIT_ADDR); \ | 352 | clear_thread_flag(TIF_32BIT_ADDR); \ |
329 | \ | 353 | \ |
330 | if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ | 354 | if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ |
331 | __SET_PERSONALITY32(ex); \ | 355 | __SET_PERSONALITY32(ex, state); \ |
332 | else \ | 356 | else \ |
333 | current->thread.abi = &mips_abi; \ | 357 | current->thread.abi = &mips_abi; \ |
334 | \ | 358 | \ |
@@ -390,4 +414,24 @@ struct mm_struct; | |||
390 | extern unsigned long arch_randomize_brk(struct mm_struct *mm); | 414 | extern unsigned long arch_randomize_brk(struct mm_struct *mm); |
391 | #define arch_randomize_brk arch_randomize_brk | 415 | #define arch_randomize_brk arch_randomize_brk |
392 | 416 | ||
417 | struct arch_elf_state { | ||
418 | int fp_abi; | ||
419 | int interp_fp_abi; | ||
420 | int overall_abi; | ||
421 | }; | ||
422 | |||
423 | #define INIT_ARCH_ELF_STATE { \ | ||
424 | .fp_abi = -1, \ | ||
425 | .interp_fp_abi = -1, \ | ||
426 | .overall_abi = -1, \ | ||
427 | } | ||
428 | |||
429 | extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf, | ||
430 | bool is_interp, struct arch_elf_state *state); | ||
431 | |||
432 | extern int arch_check_elf(void *ehdr, bool has_interpreter, | ||
433 | struct arch_elf_state *state); | ||
434 | |||
435 | extern void mips_set_personality_fp(struct arch_elf_state *state); | ||
436 | |||
393 | #endif /* _ASM_ELF_H */ | 437 | #endif /* _ASM_ELF_H */ |
diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h index dd562414cd5e..994d21939676 100644 --- a/arch/mips/include/asm/fpu.h +++ b/arch/mips/include/asm/fpu.h | |||
@@ -36,14 +36,16 @@ extern void _restore_fp(struct task_struct *); | |||
36 | 36 | ||
37 | /* | 37 | /* |
38 | * This enum specifies a mode in which we want the FPU to operate, for cores | 38 | * This enum specifies a mode in which we want the FPU to operate, for cores |
39 | * which implement the Status.FR bit. Note that FPU_32BIT & FPU_64BIT | 39 | * which implement the Status.FR bit. Note that the bottom bit of the value |
40 | * purposefully have the values 0 & 1 respectively, so that an integer value | 40 | * purposefully matches the desired value of the Status.FR bit. |
41 | * of Status.FR can be trivially casted to the corresponding enum fpu_mode. | ||
42 | */ | 41 | */ |
43 | enum fpu_mode { | 42 | enum fpu_mode { |
44 | FPU_32BIT = 0, /* FR = 0 */ | 43 | FPU_32BIT = 0, /* FR = 0 */ |
45 | FPU_64BIT, /* FR = 1 */ | 44 | FPU_64BIT, /* FR = 1, FRE = 0 */ |
46 | FPU_AS_IS, | 45 | FPU_AS_IS, |
46 | FPU_HYBRID, /* FR = 1, FRE = 1 */ | ||
47 | |||
48 | #define FPU_FR_MASK 0x1 | ||
47 | }; | 49 | }; |
48 | 50 | ||
49 | static inline int __enable_fpu(enum fpu_mode mode) | 51 | static inline int __enable_fpu(enum fpu_mode mode) |
@@ -57,6 +59,14 @@ static inline int __enable_fpu(enum fpu_mode mode) | |||
57 | enable_fpu_hazard(); | 59 | enable_fpu_hazard(); |
58 | return 0; | 60 | return 0; |
59 | 61 | ||
62 | case FPU_HYBRID: | ||
63 | if (!cpu_has_fre) | ||
64 | return SIGFPE; | ||
65 | |||
66 | /* set FRE */ | ||
67 | write_c0_config5(read_c0_config5() | MIPS_CONF5_FRE); | ||
68 | goto fr_common; | ||
69 | |||
60 | case FPU_64BIT: | 70 | case FPU_64BIT: |
61 | #if !(defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_64BIT)) | 71 | #if !(defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_64BIT)) |
62 | /* we only have a 32-bit FPU */ | 72 | /* we only have a 32-bit FPU */ |
@@ -64,8 +74,11 @@ static inline int __enable_fpu(enum fpu_mode mode) | |||
64 | #endif | 74 | #endif |
65 | /* fall through */ | 75 | /* fall through */ |
66 | case FPU_32BIT: | 76 | case FPU_32BIT: |
77 | /* clear FRE */ | ||
78 | write_c0_config5(read_c0_config5() & ~MIPS_CONF5_FRE); | ||
79 | fr_common: | ||
67 | /* set CU1 & change FR appropriately */ | 80 | /* set CU1 & change FR appropriately */ |
68 | fr = (int)mode; | 81 | fr = (int)mode & FPU_FR_MASK; |
69 | change_c0_status(ST0_CU1 | ST0_FR, ST0_CU1 | (fr ? ST0_FR : 0)); | 82 | change_c0_status(ST0_CU1 | ST0_FR, ST0_CU1 | (fr ? ST0_FR : 0)); |
70 | enable_fpu_hazard(); | 83 | enable_fpu_hazard(); |
71 | 84 | ||
@@ -102,13 +115,17 @@ static inline int __own_fpu(void) | |||
102 | enum fpu_mode mode; | 115 | enum fpu_mode mode; |
103 | int ret; | 116 | int ret; |
104 | 117 | ||
105 | mode = !test_thread_flag(TIF_32BIT_FPREGS); | 118 | if (test_thread_flag(TIF_HYBRID_FPREGS)) |
119 | mode = FPU_HYBRID; | ||
120 | else | ||
121 | mode = !test_thread_flag(TIF_32BIT_FPREGS); | ||
122 | |||
106 | ret = __enable_fpu(mode); | 123 | ret = __enable_fpu(mode); |
107 | if (ret) | 124 | if (ret) |
108 | return ret; | 125 | return ret; |
109 | 126 | ||
110 | KSTK_STATUS(current) |= ST0_CU1; | 127 | KSTK_STATUS(current) |= ST0_CU1; |
111 | if (mode == FPU_64BIT) | 128 | if (mode == FPU_64BIT || mode == FPU_HYBRID) |
112 | KSTK_STATUS(current) |= ST0_FR; | 129 | KSTK_STATUS(current) |= ST0_FR; |
113 | else /* mode == FPU_32BIT */ | 130 | else /* mode == FPU_32BIT */ |
114 | KSTK_STATUS(current) &= ~ST0_FR; | 131 | KSTK_STATUS(current) &= ~ST0_FR; |
@@ -166,8 +183,24 @@ static inline int init_fpu(void) | |||
166 | 183 | ||
167 | if (cpu_has_fpu) { | 184 | if (cpu_has_fpu) { |
168 | ret = __own_fpu(); | 185 | ret = __own_fpu(); |
169 | if (!ret) | 186 | if (!ret) { |
187 | unsigned int config5 = read_c0_config5(); | ||
188 | |||
189 | /* | ||
190 | * Ensure FRE is clear whilst running _init_fpu, since | ||
191 | * single precision FP instructions are used. If FRE | ||
192 | * was set then we'll just end up initialising all 32 | ||
193 | * 64b registers. | ||
194 | */ | ||
195 | write_c0_config5(config5 & ~MIPS_CONF5_FRE); | ||
196 | enable_fpu_hazard(); | ||
197 | |||
170 | _init_fpu(); | 198 | _init_fpu(); |
199 | |||
200 | /* Restore FRE */ | ||
201 | write_c0_config5(config5); | ||
202 | enable_fpu_hazard(); | ||
203 | } | ||
171 | } else | 204 | } else |
172 | fpu_emulator_init_fpu(); | 205 | fpu_emulator_init_fpu(); |
173 | 206 | ||
diff --git a/arch/mips/include/asm/futex.h b/arch/mips/include/asm/futex.h index 194cda0396a3..ef9987a61d88 100644 --- a/arch/mips/include/asm/futex.h +++ b/arch/mips/include/asm/futex.h | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/uaccess.h> | 14 | #include <linux/uaccess.h> |
15 | #include <asm/asm-eva.h> | 15 | #include <asm/asm-eva.h> |
16 | #include <asm/barrier.h> | 16 | #include <asm/barrier.h> |
17 | #include <asm/compiler.h> | ||
17 | #include <asm/errno.h> | 18 | #include <asm/errno.h> |
18 | #include <asm/war.h> | 19 | #include <asm/war.h> |
19 | 20 | ||
@@ -32,6 +33,7 @@ | |||
32 | " beqzl $1, 1b \n" \ | 33 | " beqzl $1, 1b \n" \ |
33 | __WEAK_LLSC_MB \ | 34 | __WEAK_LLSC_MB \ |
34 | "3: \n" \ | 35 | "3: \n" \ |
36 | " .insn \n" \ | ||
35 | " .set pop \n" \ | 37 | " .set pop \n" \ |
36 | " .set mips0 \n" \ | 38 | " .set mips0 \n" \ |
37 | " .section .fixup,\"ax\" \n" \ | 39 | " .section .fixup,\"ax\" \n" \ |
@@ -42,8 +44,10 @@ | |||
42 | " "__UA_ADDR "\t1b, 4b \n" \ | 44 | " "__UA_ADDR "\t1b, 4b \n" \ |
43 | " "__UA_ADDR "\t2b, 4b \n" \ | 45 | " "__UA_ADDR "\t2b, 4b \n" \ |
44 | " .previous \n" \ | 46 | " .previous \n" \ |
45 | : "=r" (ret), "=&r" (oldval), "=R" (*uaddr) \ | 47 | : "=r" (ret), "=&r" (oldval), \ |
46 | : "0" (0), "R" (*uaddr), "Jr" (oparg), "i" (-EFAULT) \ | 48 | "=" GCC_OFF12_ASM() (*uaddr) \ |
49 | : "0" (0), GCC_OFF12_ASM() (*uaddr), "Jr" (oparg), \ | ||
50 | "i" (-EFAULT) \ | ||
47 | : "memory"); \ | 51 | : "memory"); \ |
48 | } else if (cpu_has_llsc) { \ | 52 | } else if (cpu_has_llsc) { \ |
49 | __asm__ __volatile__( \ | 53 | __asm__ __volatile__( \ |
@@ -58,6 +62,7 @@ | |||
58 | " beqz $1, 1b \n" \ | 62 | " beqz $1, 1b \n" \ |
59 | __WEAK_LLSC_MB \ | 63 | __WEAK_LLSC_MB \ |
60 | "3: \n" \ | 64 | "3: \n" \ |
65 | " .insn \n" \ | ||
61 | " .set pop \n" \ | 66 | " .set pop \n" \ |
62 | " .set mips0 \n" \ | 67 | " .set mips0 \n" \ |
63 | " .section .fixup,\"ax\" \n" \ | 68 | " .section .fixup,\"ax\" \n" \ |
@@ -68,8 +73,10 @@ | |||
68 | " "__UA_ADDR "\t1b, 4b \n" \ | 73 | " "__UA_ADDR "\t1b, 4b \n" \ |
69 | " "__UA_ADDR "\t2b, 4b \n" \ | 74 | " "__UA_ADDR "\t2b, 4b \n" \ |
70 | " .previous \n" \ | 75 | " .previous \n" \ |
71 | : "=r" (ret), "=&r" (oldval), "=R" (*uaddr) \ | 76 | : "=r" (ret), "=&r" (oldval), \ |
72 | : "0" (0), "R" (*uaddr), "Jr" (oparg), "i" (-EFAULT) \ | 77 | "=" GCC_OFF12_ASM() (*uaddr) \ |
78 | : "0" (0), GCC_OFF12_ASM() (*uaddr), "Jr" (oparg), \ | ||
79 | "i" (-EFAULT) \ | ||
73 | : "memory"); \ | 80 | : "memory"); \ |
74 | } else \ | 81 | } else \ |
75 | ret = -ENOSYS; \ | 82 | ret = -ENOSYS; \ |
@@ -157,6 +164,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | |||
157 | " beqzl $1, 1b \n" | 164 | " beqzl $1, 1b \n" |
158 | __WEAK_LLSC_MB | 165 | __WEAK_LLSC_MB |
159 | "3: \n" | 166 | "3: \n" |
167 | " .insn \n" | ||
160 | " .set pop \n" | 168 | " .set pop \n" |
161 | " .section .fixup,\"ax\" \n" | 169 | " .section .fixup,\"ax\" \n" |
162 | "4: li %0, %6 \n" | 170 | "4: li %0, %6 \n" |
@@ -166,8 +174,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | |||
166 | " "__UA_ADDR "\t1b, 4b \n" | 174 | " "__UA_ADDR "\t1b, 4b \n" |
167 | " "__UA_ADDR "\t2b, 4b \n" | 175 | " "__UA_ADDR "\t2b, 4b \n" |
168 | " .previous \n" | 176 | " .previous \n" |
169 | : "+r" (ret), "=&r" (val), "=R" (*uaddr) | 177 | : "+r" (ret), "=&r" (val), "=" GCC_OFF12_ASM() (*uaddr) |
170 | : "R" (*uaddr), "Jr" (oldval), "Jr" (newval), "i" (-EFAULT) | 178 | : GCC_OFF12_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval), |
179 | "i" (-EFAULT) | ||
171 | : "memory"); | 180 | : "memory"); |
172 | } else if (cpu_has_llsc) { | 181 | } else if (cpu_has_llsc) { |
173 | __asm__ __volatile__( | 182 | __asm__ __volatile__( |
@@ -184,6 +193,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | |||
184 | " beqz $1, 1b \n" | 193 | " beqz $1, 1b \n" |
185 | __WEAK_LLSC_MB | 194 | __WEAK_LLSC_MB |
186 | "3: \n" | 195 | "3: \n" |
196 | " .insn \n" | ||
187 | " .set pop \n" | 197 | " .set pop \n" |
188 | " .section .fixup,\"ax\" \n" | 198 | " .section .fixup,\"ax\" \n" |
189 | "4: li %0, %6 \n" | 199 | "4: li %0, %6 \n" |
@@ -193,8 +203,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | |||
193 | " "__UA_ADDR "\t1b, 4b \n" | 203 | " "__UA_ADDR "\t1b, 4b \n" |
194 | " "__UA_ADDR "\t2b, 4b \n" | 204 | " "__UA_ADDR "\t2b, 4b \n" |
195 | " .previous \n" | 205 | " .previous \n" |
196 | : "+r" (ret), "=&r" (val), "=R" (*uaddr) | 206 | : "+r" (ret), "=&r" (val), "=" GCC_OFF12_ASM() (*uaddr) |
197 | : "R" (*uaddr), "Jr" (oldval), "Jr" (newval), "i" (-EFAULT) | 207 | : GCC_OFF12_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval), |
208 | "i" (-EFAULT) | ||
198 | : "memory"); | 209 | : "memory"); |
199 | } else | 210 | } else |
200 | return -ENOSYS; | 211 | return -ENOSYS; |
diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h deleted file mode 100644 index d7699cf7e135..000000000000 --- a/arch/mips/include/asm/gic.h +++ /dev/null | |||
@@ -1,384 +0,0 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2000, 07 MIPS Technologies, Inc. | ||
7 | * | ||
8 | * GIC Register Definitions | ||
9 | * | ||
10 | */ | ||
11 | #ifndef _ASM_GICREGS_H | ||
12 | #define _ASM_GICREGS_H | ||
13 | |||
14 | #include <linux/bitmap.h> | ||
15 | #include <linux/threads.h> | ||
16 | |||
17 | #include <irq.h> | ||
18 | |||
19 | #undef GICISBYTELITTLEENDIAN | ||
20 | |||
21 | /* Constants */ | ||
22 | #define GIC_POL_POS 1 | ||
23 | #define GIC_POL_NEG 0 | ||
24 | #define GIC_TRIG_EDGE 1 | ||
25 | #define GIC_TRIG_LEVEL 0 | ||
26 | |||
27 | #define MSK(n) ((1 << (n)) - 1) | ||
28 | #define REG32(addr) (*(volatile unsigned int *) (addr)) | ||
29 | #define REG(base, offs) REG32((unsigned long)(base) + offs##_##OFS) | ||
30 | #define REGP(base, phys) REG32((unsigned long)(base) + (phys)) | ||
31 | |||
32 | /* Accessors */ | ||
33 | #define GIC_REG(segment, offset) \ | ||
34 | REG32(_gic_base + segment##_##SECTION_OFS + offset##_##OFS) | ||
35 | #define GIC_REG_ADDR(segment, offset) \ | ||
36 | REG32(_gic_base + segment##_##SECTION_OFS + offset) | ||
37 | |||
38 | #define GIC_ABS_REG(segment, offset) \ | ||
39 | (_gic_base + segment##_##SECTION_OFS + offset##_##OFS) | ||
40 | #define GIC_REG_ABS_ADDR(segment, offset) \ | ||
41 | (_gic_base + segment##_##SECTION_OFS + offset) | ||
42 | |||
43 | #ifdef GICISBYTELITTLEENDIAN | ||
44 | #define GICREAD(reg, data) ((data) = (reg), (data) = le32_to_cpu(data)) | ||
45 | #define GICWRITE(reg, data) ((reg) = cpu_to_le32(data)) | ||
46 | #else | ||
47 | #define GICREAD(reg, data) ((data) = (reg)) | ||
48 | #define GICWRITE(reg, data) ((reg) = (data)) | ||
49 | #endif | ||
50 | #define GICBIS(reg, mask, bits) \ | ||
51 | do { u32 data; \ | ||
52 | GICREAD(reg, data); \ | ||
53 | data &= ~(mask); \ | ||
54 | data |= ((bits) & (mask)); \ | ||
55 | GICWRITE((reg), data); \ | ||
56 | } while (0) | ||
57 | |||
58 | |||
59 | /* GIC Address Space */ | ||
60 | #define SHARED_SECTION_OFS 0x0000 | ||
61 | #define SHARED_SECTION_SIZE 0x8000 | ||
62 | #define VPE_LOCAL_SECTION_OFS 0x8000 | ||
63 | #define VPE_LOCAL_SECTION_SIZE 0x4000 | ||
64 | #define VPE_OTHER_SECTION_OFS 0xc000 | ||
65 | #define VPE_OTHER_SECTION_SIZE 0x4000 | ||
66 | #define USM_VISIBLE_SECTION_OFS 0x10000 | ||
67 | #define USM_VISIBLE_SECTION_SIZE 0x10000 | ||
68 | |||
69 | /* Register Map for Shared Section */ | ||
70 | |||
71 | #define GIC_SH_CONFIG_OFS 0x0000 | ||
72 | |||
73 | /* Shared Global Counter */ | ||
74 | #define GIC_SH_COUNTER_31_00_OFS 0x0010 | ||
75 | #define GIC_SH_COUNTER_63_32_OFS 0x0014 | ||
76 | #define GIC_SH_REVISIONID_OFS 0x0020 | ||
77 | |||
78 | /* Interrupt Polarity */ | ||
79 | #define GIC_SH_POL_31_0_OFS 0x0100 | ||
80 | #define GIC_SH_POL_63_32_OFS 0x0104 | ||
81 | #define GIC_SH_POL_95_64_OFS 0x0108 | ||
82 | #define GIC_SH_POL_127_96_OFS 0x010c | ||
83 | #define GIC_SH_POL_159_128_OFS 0x0110 | ||
84 | #define GIC_SH_POL_191_160_OFS 0x0114 | ||
85 | #define GIC_SH_POL_223_192_OFS 0x0118 | ||
86 | #define GIC_SH_POL_255_224_OFS 0x011c | ||
87 | |||
88 | /* Edge/Level Triggering */ | ||
89 | #define GIC_SH_TRIG_31_0_OFS 0x0180 | ||
90 | #define GIC_SH_TRIG_63_32_OFS 0x0184 | ||
91 | #define GIC_SH_TRIG_95_64_OFS 0x0188 | ||
92 | #define GIC_SH_TRIG_127_96_OFS 0x018c | ||
93 | #define GIC_SH_TRIG_159_128_OFS 0x0190 | ||
94 | #define GIC_SH_TRIG_191_160_OFS 0x0194 | ||
95 | #define GIC_SH_TRIG_223_192_OFS 0x0198 | ||
96 | #define GIC_SH_TRIG_255_224_OFS 0x019c | ||
97 | |||
98 | /* Dual Edge Triggering */ | ||
99 | #define GIC_SH_DUAL_31_0_OFS 0x0200 | ||
100 | #define GIC_SH_DUAL_63_32_OFS 0x0204 | ||
101 | #define GIC_SH_DUAL_95_64_OFS 0x0208 | ||
102 | #define GIC_SH_DUAL_127_96_OFS 0x020c | ||
103 | #define GIC_SH_DUAL_159_128_OFS 0x0210 | ||
104 | #define GIC_SH_DUAL_191_160_OFS 0x0214 | ||
105 | #define GIC_SH_DUAL_223_192_OFS 0x0218 | ||
106 | #define GIC_SH_DUAL_255_224_OFS 0x021c | ||
107 | |||
108 | /* Set/Clear corresponding bit in Edge Detect Register */ | ||
109 | #define GIC_SH_WEDGE_OFS 0x0280 | ||
110 | |||
111 | /* Reset Mask - Disables Interrupt */ | ||
112 | #define GIC_SH_RMASK_31_0_OFS 0x0300 | ||
113 | #define GIC_SH_RMASK_63_32_OFS 0x0304 | ||
114 | #define GIC_SH_RMASK_95_64_OFS 0x0308 | ||
115 | #define GIC_SH_RMASK_127_96_OFS 0x030c | ||
116 | #define GIC_SH_RMASK_159_128_OFS 0x0310 | ||
117 | #define GIC_SH_RMASK_191_160_OFS 0x0314 | ||
118 | #define GIC_SH_RMASK_223_192_OFS 0x0318 | ||
119 | #define GIC_SH_RMASK_255_224_OFS 0x031c | ||
120 | |||
121 | /* Set Mask (WO) - Enables Interrupt */ | ||
122 | #define GIC_SH_SMASK_31_0_OFS 0x0380 | ||
123 | #define GIC_SH_SMASK_63_32_OFS 0x0384 | ||
124 | #define GIC_SH_SMASK_95_64_OFS 0x0388 | ||
125 | #define GIC_SH_SMASK_127_96_OFS 0x038c | ||
126 | #define GIC_SH_SMASK_159_128_OFS 0x0390 | ||
127 | #define GIC_SH_SMASK_191_160_OFS 0x0394 | ||
128 | #define GIC_SH_SMASK_223_192_OFS 0x0398 | ||
129 | #define GIC_SH_SMASK_255_224_OFS 0x039c | ||
130 | |||
131 | /* Global Interrupt Mask Register (RO) - Bit Set == Interrupt enabled */ | ||
132 | #define GIC_SH_MASK_31_0_OFS 0x0400 | ||
133 | #define GIC_SH_MASK_63_32_OFS 0x0404 | ||
134 | #define GIC_SH_MASK_95_64_OFS 0x0408 | ||
135 | #define GIC_SH_MASK_127_96_OFS 0x040c | ||
136 | #define GIC_SH_MASK_159_128_OFS 0x0410 | ||
137 | #define GIC_SH_MASK_191_160_OFS 0x0414 | ||
138 | #define GIC_SH_MASK_223_192_OFS 0x0418 | ||
139 | #define GIC_SH_MASK_255_224_OFS 0x041c | ||
140 | |||
141 | /* Pending Global Interrupts (RO) */ | ||
142 | #define GIC_SH_PEND_31_0_OFS 0x0480 | ||
143 | #define GIC_SH_PEND_63_32_OFS 0x0484 | ||
144 | #define GIC_SH_PEND_95_64_OFS 0x0488 | ||
145 | #define GIC_SH_PEND_127_96_OFS 0x048c | ||
146 | #define GIC_SH_PEND_159_128_OFS 0x0490 | ||
147 | #define GIC_SH_PEND_191_160_OFS 0x0494 | ||
148 | #define GIC_SH_PEND_223_192_OFS 0x0498 | ||
149 | #define GIC_SH_PEND_255_224_OFS 0x049c | ||
150 | |||
151 | #define GIC_SH_INTR_MAP_TO_PIN_BASE_OFS 0x0500 | ||
152 | |||
153 | /* Maps Interrupt X to a Pin */ | ||
154 | #define GIC_SH_MAP_TO_PIN(intr) \ | ||
155 | (GIC_SH_INTR_MAP_TO_PIN_BASE_OFS + (4 * intr)) | ||
156 | |||
157 | #define GIC_SH_INTR_MAP_TO_VPE_BASE_OFS 0x2000 | ||
158 | |||
159 | /* Maps Interrupt X to a VPE */ | ||
160 | #define GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe) \ | ||
161 | (GIC_SH_INTR_MAP_TO_VPE_BASE_OFS + (32 * (intr)) + (((vpe) / 32) * 4)) | ||
162 | #define GIC_SH_MAP_TO_VPE_REG_BIT(vpe) (1 << ((vpe) % 32)) | ||
163 | |||
164 | /* Convert an interrupt number to a byte offset/bit for multi-word registers */ | ||
165 | #define GIC_INTR_OFS(intr) (((intr) / 32)*4) | ||
166 | #define GIC_INTR_BIT(intr) ((intr) % 32) | ||
167 | |||
168 | /* Polarity : Reset Value is always 0 */ | ||
169 | #define GIC_SH_SET_POLARITY_OFS 0x0100 | ||
170 | #define GIC_SET_POLARITY(intr, pol) \ | ||
171 | GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + \ | ||
172 | GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \ | ||
173 | (pol) << GIC_INTR_BIT(intr)) | ||
174 | |||
175 | /* Triggering : Reset Value is always 0 */ | ||
176 | #define GIC_SH_SET_TRIGGER_OFS 0x0180 | ||
177 | #define GIC_SET_TRIGGER(intr, trig) \ | ||
178 | GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + \ | ||
179 | GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \ | ||
180 | (trig) << GIC_INTR_BIT(intr)) | ||
181 | |||
182 | /* Mask manipulation */ | ||
183 | #define GIC_SH_SMASK_OFS 0x0380 | ||
184 | #define GIC_SET_INTR_MASK(intr) \ | ||
185 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_SMASK_OFS + \ | ||
186 | GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr)) | ||
187 | #define GIC_SH_RMASK_OFS 0x0300 | ||
188 | #define GIC_CLR_INTR_MASK(intr) \ | ||
189 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_RMASK_OFS + \ | ||
190 | GIC_INTR_OFS(intr)), 1 << GIC_INTR_BIT(intr)) | ||
191 | |||
192 | /* Register Map for Local Section */ | ||
193 | #define GIC_VPE_CTL_OFS 0x0000 | ||
194 | #define GIC_VPE_PEND_OFS 0x0004 | ||
195 | #define GIC_VPE_MASK_OFS 0x0008 | ||
196 | #define GIC_VPE_RMASK_OFS 0x000c | ||
197 | #define GIC_VPE_SMASK_OFS 0x0010 | ||
198 | #define GIC_VPE_WD_MAP_OFS 0x0040 | ||
199 | #define GIC_VPE_COMPARE_MAP_OFS 0x0044 | ||
200 | #define GIC_VPE_TIMER_MAP_OFS 0x0048 | ||
201 | #define GIC_VPE_PERFCTR_MAP_OFS 0x0050 | ||
202 | #define GIC_VPE_SWINT0_MAP_OFS 0x0054 | ||
203 | #define GIC_VPE_SWINT1_MAP_OFS 0x0058 | ||
204 | #define GIC_VPE_OTHER_ADDR_OFS 0x0080 | ||
205 | #define GIC_VPE_WD_CONFIG0_OFS 0x0090 | ||
206 | #define GIC_VPE_WD_COUNT0_OFS 0x0094 | ||
207 | #define GIC_VPE_WD_INITIAL0_OFS 0x0098 | ||
208 | #define GIC_VPE_COMPARE_LO_OFS 0x00a0 | ||
209 | #define GIC_VPE_COMPARE_HI_OFS 0x00a4 | ||
210 | |||
211 | #define GIC_VPE_EIC_SHADOW_SET_BASE 0x0100 | ||
212 | #define GIC_VPE_EIC_SS(intr) \ | ||
213 | (GIC_VPE_EIC_SHADOW_SET_BASE + (4 * intr)) | ||
214 | |||
215 | #define GIC_VPE_EIC_VEC_BASE 0x0800 | ||
216 | #define GIC_VPE_EIC_VEC(intr) \ | ||
217 | (GIC_VPE_EIC_VEC_BASE + (4 * intr)) | ||
218 | |||
219 | #define GIC_VPE_TENABLE_NMI_OFS 0x1000 | ||
220 | #define GIC_VPE_TENABLE_YQ_OFS 0x1004 | ||
221 | #define GIC_VPE_TENABLE_INT_31_0_OFS 0x1080 | ||
222 | #define GIC_VPE_TENABLE_INT_63_32_OFS 0x1084 | ||
223 | |||
224 | /* User Mode Visible Section Register Map */ | ||
225 | #define GIC_UMV_SH_COUNTER_31_00_OFS 0x0000 | ||
226 | #define GIC_UMV_SH_COUNTER_63_32_OFS 0x0004 | ||
227 | |||
228 | /* Masks */ | ||
229 | #define GIC_SH_CONFIG_COUNTSTOP_SHF 28 | ||
230 | #define GIC_SH_CONFIG_COUNTSTOP_MSK (MSK(1) << GIC_SH_CONFIG_COUNTSTOP_SHF) | ||
231 | |||
232 | #define GIC_SH_CONFIG_COUNTBITS_SHF 24 | ||
233 | #define GIC_SH_CONFIG_COUNTBITS_MSK (MSK(4) << GIC_SH_CONFIG_COUNTBITS_SHF) | ||
234 | |||
235 | #define GIC_SH_CONFIG_NUMINTRS_SHF 16 | ||
236 | #define GIC_SH_CONFIG_NUMINTRS_MSK (MSK(8) << GIC_SH_CONFIG_NUMINTRS_SHF) | ||
237 | |||
238 | #define GIC_SH_CONFIG_NUMVPES_SHF 0 | ||
239 | #define GIC_SH_CONFIG_NUMVPES_MSK (MSK(8) << GIC_SH_CONFIG_NUMVPES_SHF) | ||
240 | |||
241 | #define GIC_SH_WEDGE_SET(intr) (intr | (0x1 << 31)) | ||
242 | #define GIC_SH_WEDGE_CLR(intr) (intr & ~(0x1 << 31)) | ||
243 | |||
244 | #define GIC_MAP_TO_PIN_SHF 31 | ||
245 | #define GIC_MAP_TO_PIN_MSK (MSK(1) << GIC_MAP_TO_PIN_SHF) | ||
246 | #define GIC_MAP_TO_NMI_SHF 30 | ||
247 | #define GIC_MAP_TO_NMI_MSK (MSK(1) << GIC_MAP_TO_NMI_SHF) | ||
248 | #define GIC_MAP_TO_YQ_SHF 29 | ||
249 | #define GIC_MAP_TO_YQ_MSK (MSK(1) << GIC_MAP_TO_YQ_SHF) | ||
250 | #define GIC_MAP_SHF 0 | ||
251 | #define GIC_MAP_MSK (MSK(6) << GIC_MAP_SHF) | ||
252 | |||
253 | /* GIC_VPE_CTL Masks */ | ||
254 | #define GIC_VPE_CTL_PERFCNT_RTBL_SHF 2 | ||
255 | #define GIC_VPE_CTL_PERFCNT_RTBL_MSK (MSK(1) << GIC_VPE_CTL_PERFCNT_RTBL_SHF) | ||
256 | #define GIC_VPE_CTL_TIMER_RTBL_SHF 1 | ||
257 | #define GIC_VPE_CTL_TIMER_RTBL_MSK (MSK(1) << GIC_VPE_CTL_TIMER_RTBL_SHF) | ||
258 | #define GIC_VPE_CTL_EIC_MODE_SHF 0 | ||
259 | #define GIC_VPE_CTL_EIC_MODE_MSK (MSK(1) << GIC_VPE_CTL_EIC_MODE_SHF) | ||
260 | |||
261 | /* GIC_VPE_PEND Masks */ | ||
262 | #define GIC_VPE_PEND_WD_SHF 0 | ||
263 | #define GIC_VPE_PEND_WD_MSK (MSK(1) << GIC_VPE_PEND_WD_SHF) | ||
264 | #define GIC_VPE_PEND_CMP_SHF 1 | ||
265 | #define GIC_VPE_PEND_CMP_MSK (MSK(1) << GIC_VPE_PEND_CMP_SHF) | ||
266 | #define GIC_VPE_PEND_TIMER_SHF 2 | ||
267 | #define GIC_VPE_PEND_TIMER_MSK (MSK(1) << GIC_VPE_PEND_TIMER_SHF) | ||
268 | #define GIC_VPE_PEND_PERFCOUNT_SHF 3 | ||
269 | #define GIC_VPE_PEND_PERFCOUNT_MSK (MSK(1) << GIC_VPE_PEND_PERFCOUNT_SHF) | ||
270 | #define GIC_VPE_PEND_SWINT0_SHF 4 | ||
271 | #define GIC_VPE_PEND_SWINT0_MSK (MSK(1) << GIC_VPE_PEND_SWINT0_SHF) | ||
272 | #define GIC_VPE_PEND_SWINT1_SHF 5 | ||
273 | #define GIC_VPE_PEND_SWINT1_MSK (MSK(1) << GIC_VPE_PEND_SWINT1_SHF) | ||
274 | |||
275 | /* GIC_VPE_RMASK Masks */ | ||
276 | #define GIC_VPE_RMASK_WD_SHF 0 | ||
277 | #define GIC_VPE_RMASK_WD_MSK (MSK(1) << GIC_VPE_RMASK_WD_SHF) | ||
278 | #define GIC_VPE_RMASK_CMP_SHF 1 | ||
279 | #define GIC_VPE_RMASK_CMP_MSK (MSK(1) << GIC_VPE_RMASK_CMP_SHF) | ||
280 | #define GIC_VPE_RMASK_TIMER_SHF 2 | ||
281 | #define GIC_VPE_RMASK_TIMER_MSK (MSK(1) << GIC_VPE_RMASK_TIMER_SHF) | ||
282 | #define GIC_VPE_RMASK_PERFCNT_SHF 3 | ||
283 | #define GIC_VPE_RMASK_PERFCNT_MSK (MSK(1) << GIC_VPE_RMASK_PERFCNT_SHF) | ||
284 | #define GIC_VPE_RMASK_SWINT0_SHF 4 | ||
285 | #define GIC_VPE_RMASK_SWINT0_MSK (MSK(1) << GIC_VPE_RMASK_SWINT0_SHF) | ||
286 | #define GIC_VPE_RMASK_SWINT1_SHF 5 | ||
287 | #define GIC_VPE_RMASK_SWINT1_MSK (MSK(1) << GIC_VPE_RMASK_SWINT1_SHF) | ||
288 | |||
289 | /* GIC_VPE_SMASK Masks */ | ||
290 | #define GIC_VPE_SMASK_WD_SHF 0 | ||
291 | #define GIC_VPE_SMASK_WD_MSK (MSK(1) << GIC_VPE_SMASK_WD_SHF) | ||
292 | #define GIC_VPE_SMASK_CMP_SHF 1 | ||
293 | #define GIC_VPE_SMASK_CMP_MSK (MSK(1) << GIC_VPE_SMASK_CMP_SHF) | ||
294 | #define GIC_VPE_SMASK_TIMER_SHF 2 | ||
295 | #define GIC_VPE_SMASK_TIMER_MSK (MSK(1) << GIC_VPE_SMASK_TIMER_SHF) | ||
296 | #define GIC_VPE_SMASK_PERFCNT_SHF 3 | ||
297 | #define GIC_VPE_SMASK_PERFCNT_MSK (MSK(1) << GIC_VPE_SMASK_PERFCNT_SHF) | ||
298 | #define GIC_VPE_SMASK_SWINT0_SHF 4 | ||
299 | #define GIC_VPE_SMASK_SWINT0_MSK (MSK(1) << GIC_VPE_SMASK_SWINT0_SHF) | ||
300 | #define GIC_VPE_SMASK_SWINT1_SHF 5 | ||
301 | #define GIC_VPE_SMASK_SWINT1_MSK (MSK(1) << GIC_VPE_SMASK_SWINT1_SHF) | ||
302 | |||
303 | /* | ||
304 | * Set the Mapping of Interrupt X to a VPE. | ||
305 | */ | ||
306 | #define GIC_SH_MAP_TO_VPE_SMASK(intr, vpe) \ | ||
307 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe)), \ | ||
308 | GIC_SH_MAP_TO_VPE_REG_BIT(vpe)) | ||
309 | |||
310 | /* | ||
311 | * Interrupt Meta-data specification. The ipiflag helps | ||
312 | * in building ipi_map. | ||
313 | */ | ||
314 | struct gic_intr_map { | ||
315 | unsigned int cpunum; /* Directed to this CPU */ | ||
316 | #define GIC_UNUSED 0xdead /* Dummy data */ | ||
317 | unsigned int pin; /* Directed to this Pin */ | ||
318 | unsigned int polarity; /* Polarity : +/- */ | ||
319 | unsigned int trigtype; /* Trigger : Edge/Levl */ | ||
320 | unsigned int flags; /* Misc flags */ | ||
321 | #define GIC_FLAG_TRANSPARENT 0x01 | ||
322 | }; | ||
323 | |||
324 | /* | ||
325 | * This is only used in EIC mode. This helps to figure out which | ||
326 | * shared interrupts we need to process when we get a vector interrupt. | ||
327 | */ | ||
328 | #define GIC_MAX_SHARED_INTR 0x5 | ||
329 | struct gic_shared_intr_map { | ||
330 | unsigned int num_shared_intr; | ||
331 | unsigned int intr_list[GIC_MAX_SHARED_INTR]; | ||
332 | unsigned int local_intr_mask; | ||
333 | }; | ||
334 | |||
335 | /* GIC nomenclature for Core Interrupt Pins. */ | ||
336 | #define GIC_CPU_INT0 0 /* Core Interrupt 2 */ | ||
337 | #define GIC_CPU_INT1 1 /* . */ | ||
338 | #define GIC_CPU_INT2 2 /* . */ | ||
339 | #define GIC_CPU_INT3 3 /* . */ | ||
340 | #define GIC_CPU_INT4 4 /* . */ | ||
341 | #define GIC_CPU_INT5 5 /* Core Interrupt 7 */ | ||
342 | |||
343 | /* Local GIC interrupts. */ | ||
344 | #define GIC_INT_TMR (GIC_CPU_INT5) | ||
345 | #define GIC_INT_PERFCTR (GIC_CPU_INT5) | ||
346 | |||
347 | /* Add 2 to convert non-EIC hardware interrupt to EIC vector number. */ | ||
348 | #define GIC_CPU_TO_VEC_OFFSET (2) | ||
349 | |||
350 | /* Mapped interrupt to pin X, then GIC will generate the vector (X+1). */ | ||
351 | #define GIC_PIN_TO_VEC_OFFSET (1) | ||
352 | |||
353 | #include <linux/clocksource.h> | ||
354 | #include <linux/irq.h> | ||
355 | |||
356 | extern unsigned int gic_present; | ||
357 | extern unsigned int gic_frequency; | ||
358 | extern unsigned long _gic_base; | ||
359 | extern unsigned int gic_irq_base; | ||
360 | extern unsigned int gic_irq_flags[]; | ||
361 | extern struct gic_shared_intr_map gic_shared_intr_map[]; | ||
362 | |||
363 | extern void gic_init(unsigned long gic_base_addr, | ||
364 | unsigned long gic_addrspace_size, struct gic_intr_map *intrmap, | ||
365 | unsigned int intrmap_size, unsigned int irqbase); | ||
366 | extern void gic_clocksource_init(unsigned int); | ||
367 | extern unsigned int gic_compare_int (void); | ||
368 | extern cycle_t gic_read_count(void); | ||
369 | extern cycle_t gic_read_compare(void); | ||
370 | extern void gic_write_compare(cycle_t cnt); | ||
371 | extern void gic_write_cpu_compare(cycle_t cnt, int cpu); | ||
372 | extern void gic_send_ipi(unsigned int intr); | ||
373 | extern unsigned int plat_ipi_call_int_xlate(unsigned int); | ||
374 | extern unsigned int plat_ipi_resched_int_xlate(unsigned int); | ||
375 | extern void gic_bind_eic_interrupt(int irq, int set); | ||
376 | extern unsigned int gic_get_timer_pending(void); | ||
377 | extern void gic_get_int_mask(unsigned long *dst, const unsigned long *src); | ||
378 | extern unsigned int gic_get_int(void); | ||
379 | extern void gic_enable_interrupt(int irq_vec); | ||
380 | extern void gic_disable_interrupt(int irq_vec); | ||
381 | extern void gic_irq_ack(struct irq_data *d); | ||
382 | extern void gic_finish_irq(struct irq_data *d); | ||
383 | extern void gic_platform_init(int irqs, struct irq_chip *irq_controller); | ||
384 | #endif /* _ASM_GICREGS_H */ | ||
diff --git a/arch/mips/include/asm/hpet.h b/arch/mips/include/asm/hpet.h new file mode 100644 index 000000000000..18a8f778bfaa --- /dev/null +++ b/arch/mips/include/asm/hpet.h | |||
@@ -0,0 +1,73 @@ | |||
1 | #ifndef _ASM_HPET_H | ||
2 | #define _ASM_HPET_H | ||
3 | |||
4 | #ifdef CONFIG_RS780_HPET | ||
5 | |||
6 | #define HPET_MMAP_SIZE 1024 | ||
7 | |||
8 | #define HPET_ID 0x000 | ||
9 | #define HPET_PERIOD 0x004 | ||
10 | #define HPET_CFG 0x010 | ||
11 | #define HPET_STATUS 0x020 | ||
12 | #define HPET_COUNTER 0x0f0 | ||
13 | |||
14 | #define HPET_Tn_CFG(n) (0x100 + 0x20 * n) | ||
15 | #define HPET_Tn_CMP(n) (0x108 + 0x20 * n) | ||
16 | #define HPET_Tn_ROUTE(n) (0x110 + 0x20 * n) | ||
17 | |||
18 | #define HPET_T0_IRS 0x001 | ||
19 | #define HPET_T1_IRS 0x002 | ||
20 | #define HPET_T3_IRS 0x004 | ||
21 | |||
22 | #define HPET_T0_CFG 0x100 | ||
23 | #define HPET_T0_CMP 0x108 | ||
24 | #define HPET_T0_ROUTE 0x110 | ||
25 | #define HPET_T1_CFG 0x120 | ||
26 | #define HPET_T1_CMP 0x128 | ||
27 | #define HPET_T1_ROUTE 0x130 | ||
28 | #define HPET_T2_CFG 0x140 | ||
29 | #define HPET_T2_CMP 0x148 | ||
30 | #define HPET_T2_ROUTE 0x150 | ||
31 | |||
32 | #define HPET_ID_REV 0x000000ff | ||
33 | #define HPET_ID_NUMBER 0x00001f00 | ||
34 | #define HPET_ID_64BIT 0x00002000 | ||
35 | #define HPET_ID_LEGSUP 0x00008000 | ||
36 | #define HPET_ID_VENDOR 0xffff0000 | ||
37 | #define HPET_ID_NUMBER_SHIFT 8 | ||
38 | #define HPET_ID_VENDOR_SHIFT 16 | ||
39 | |||
40 | #define HPET_CFG_ENABLE 0x001 | ||
41 | #define HPET_CFG_LEGACY 0x002 | ||
42 | #define HPET_LEGACY_8254 2 | ||
43 | #define HPET_LEGACY_RTC 8 | ||
44 | |||
45 | #define HPET_TN_LEVEL 0x0002 | ||
46 | #define HPET_TN_ENABLE 0x0004 | ||
47 | #define HPET_TN_PERIODIC 0x0008 | ||
48 | #define HPET_TN_PERIODIC_CAP 0x0010 | ||
49 | #define HPET_TN_64BIT_CAP 0x0020 | ||
50 | #define HPET_TN_SETVAL 0x0040 | ||
51 | #define HPET_TN_32BIT 0x0100 | ||
52 | #define HPET_TN_ROUTE 0x3e00 | ||
53 | #define HPET_TN_FSB 0x4000 | ||
54 | #define HPET_TN_FSB_CAP 0x8000 | ||
55 | #define HPET_TN_ROUTE_SHIFT 9 | ||
56 | |||
57 | /* Max HPET Period is 10^8 femto sec as in HPET spec */ | ||
58 | #define HPET_MAX_PERIOD 100000000UL | ||
59 | /* | ||
60 | * Min HPET period is 10^5 femto sec just for safety. If it is less than this, | ||
61 | * then 32 bit HPET counter wrapsaround in less than 0.5 sec. | ||
62 | */ | ||
63 | #define HPET_MIN_PERIOD 100000UL | ||
64 | |||
65 | #define HPET_ADDR 0x20000 | ||
66 | #define HPET_MMIO_ADDR 0x90000e0000020000 | ||
67 | #define HPET_FREQ 14318780 | ||
68 | #define HPET_COMPARE_VAL ((HPET_FREQ + HZ / 2) / HZ) | ||
69 | #define HPET_T0_IRQ 0 | ||
70 | |||
71 | extern void __init setup_hpet_timer(void); | ||
72 | #endif /* CONFIG_RS780_HPET */ | ||
73 | #endif /* _ASM_HPET_H */ | ||
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index 933b50e125a0..9e777cd42b67 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h | |||
@@ -167,7 +167,7 @@ static inline void * isa_bus_to_virt(unsigned long address) | |||
167 | */ | 167 | */ |
168 | #define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) | 168 | #define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT) |
169 | 169 | ||
170 | extern void __iomem * __ioremap(phys_t offset, phys_t size, unsigned long flags); | 170 | extern void __iomem * __ioremap(phys_addr_t offset, phys_addr_t size, unsigned long flags); |
171 | extern void __iounmap(const volatile void __iomem *addr); | 171 | extern void __iounmap(const volatile void __iomem *addr); |
172 | 172 | ||
173 | #ifndef CONFIG_PCI | 173 | #ifndef CONFIG_PCI |
@@ -175,7 +175,7 @@ struct pci_dev; | |||
175 | static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {} | 175 | static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {} |
176 | #endif | 176 | #endif |
177 | 177 | ||
178 | static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, | 178 | static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long size, |
179 | unsigned long flags) | 179 | unsigned long flags) |
180 | { | 180 | { |
181 | void __iomem *addr = plat_ioremap(offset, size, flags); | 181 | void __iomem *addr = plat_ioremap(offset, size, flags); |
@@ -183,7 +183,7 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, | |||
183 | if (addr) | 183 | if (addr) |
184 | return addr; | 184 | return addr; |
185 | 185 | ||
186 | #define __IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL)) | 186 | #define __IS_LOW512(addr) (!((phys_addr_t)(addr) & (phys_addr_t) ~0x1fffffffULL)) |
187 | 187 | ||
188 | if (cpu_has_64bit_addresses) { | 188 | if (cpu_has_64bit_addresses) { |
189 | u64 base = UNCAC_BASE; | 189 | u64 base = UNCAC_BASE; |
@@ -197,7 +197,7 @@ static inline void __iomem * __ioremap_mode(phys_t offset, unsigned long size, | |||
197 | return (void __iomem *) (unsigned long) (base + offset); | 197 | return (void __iomem *) (unsigned long) (base + offset); |
198 | } else if (__builtin_constant_p(offset) && | 198 | } else if (__builtin_constant_p(offset) && |
199 | __builtin_constant_p(size) && __builtin_constant_p(flags)) { | 199 | __builtin_constant_p(size) && __builtin_constant_p(flags)) { |
200 | phys_t phys_addr, last_addr; | 200 | phys_addr_t phys_addr, last_addr; |
201 | 201 | ||
202 | phys_addr = fixup_bigphys_addr(offset, size); | 202 | phys_addr = fixup_bigphys_addr(offset, size); |
203 | 203 | ||
diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h index 39f07aec640c..5a4e1bb8fb1b 100644 --- a/arch/mips/include/asm/irq.h +++ b/arch/mips/include/asm/irq.h | |||
@@ -48,4 +48,7 @@ extern int cp0_compare_irq; | |||
48 | extern int cp0_compare_irq_shift; | 48 | extern int cp0_compare_irq_shift; |
49 | extern int cp0_perfcount_irq; | 49 | extern int cp0_perfcount_irq; |
50 | 50 | ||
51 | void arch_trigger_all_cpu_backtrace(bool); | ||
52 | #define arch_trigger_all_cpu_backtrace arch_trigger_all_cpu_backtrace | ||
53 | |||
51 | #endif /* _ASM_IRQ_H */ | 54 | #endif /* _ASM_IRQ_H */ |
diff --git a/arch/mips/include/asm/irq_cpu.h b/arch/mips/include/asm/irq_cpu.h index 3f11fdb3ed8c..39a160bb41dc 100644 --- a/arch/mips/include/asm/irq_cpu.h +++ b/arch/mips/include/asm/irq_cpu.h | |||
@@ -19,8 +19,8 @@ extern void rm9k_cpu_irq_init(void); | |||
19 | 19 | ||
20 | #ifdef CONFIG_IRQ_DOMAIN | 20 | #ifdef CONFIG_IRQ_DOMAIN |
21 | struct device_node; | 21 | struct device_node; |
22 | extern int mips_cpu_intc_init(struct device_node *of_node, | 22 | extern int mips_cpu_irq_of_init(struct device_node *of_node, |
23 | struct device_node *parent); | 23 | struct device_node *parent); |
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | #endif /* _ASM_IRQ_CPU_H */ | 26 | #endif /* _ASM_IRQ_CPU_H */ |
diff --git a/arch/mips/include/asm/mach-ath25/ath25_platform.h b/arch/mips/include/asm/mach-ath25/ath25_platform.h new file mode 100644 index 000000000000..4f4ee4f9e5ec --- /dev/null +++ b/arch/mips/include/asm/mach-ath25/ath25_platform.h | |||
@@ -0,0 +1,73 @@ | |||
1 | #ifndef __ASM_MACH_ATH25_PLATFORM_H | ||
2 | #define __ASM_MACH_ATH25_PLATFORM_H | ||
3 | |||
4 | #include <linux/etherdevice.h> | ||
5 | |||
6 | /* | ||
7 | * This is board-specific data that is stored in a "fixed" location in flash. | ||
8 | * It is shared across operating systems, so it should not be changed lightly. | ||
9 | * The main reason we need it is in order to extract the ethernet MAC | ||
10 | * address(es). | ||
11 | */ | ||
12 | struct ath25_boarddata { | ||
13 | u32 magic; /* board data is valid */ | ||
14 | #define ATH25_BD_MAGIC 0x35333131 /* "5311", for all 531x/231x platforms */ | ||
15 | u16 cksum; /* checksum (starting with BD_REV 2) */ | ||
16 | u16 rev; /* revision of this struct */ | ||
17 | #define BD_REV 4 | ||
18 | char board_name[64]; /* Name of board */ | ||
19 | u16 major; /* Board major number */ | ||
20 | u16 minor; /* Board minor number */ | ||
21 | u32 flags; /* Board configuration */ | ||
22 | #define BD_ENET0 0x00000001 /* ENET0 is stuffed */ | ||
23 | #define BD_ENET1 0x00000002 /* ENET1 is stuffed */ | ||
24 | #define BD_UART1 0x00000004 /* UART1 is stuffed */ | ||
25 | #define BD_UART0 0x00000008 /* UART0 is stuffed (dma) */ | ||
26 | #define BD_RSTFACTORY 0x00000010 /* Reset factory defaults stuffed */ | ||
27 | #define BD_SYSLED 0x00000020 /* System LED stuffed */ | ||
28 | #define BD_EXTUARTCLK 0x00000040 /* External UART clock */ | ||
29 | #define BD_CPUFREQ 0x00000080 /* cpu freq is valid in nvram */ | ||
30 | #define BD_SYSFREQ 0x00000100 /* sys freq is set in nvram */ | ||
31 | #define BD_WLAN0 0x00000200 /* Enable WLAN0 */ | ||
32 | #define BD_MEMCAP 0x00000400 /* CAP SDRAM @ mem_cap for testing */ | ||
33 | #define BD_DISWATCHDOG 0x00000800 /* disable system watchdog */ | ||
34 | #define BD_WLAN1 0x00001000 /* Enable WLAN1 (ar5212) */ | ||
35 | #define BD_ISCASPER 0x00002000 /* FLAG for AR2312 */ | ||
36 | #define BD_WLAN0_2G_EN 0x00004000 /* FLAG for radio0_2G */ | ||
37 | #define BD_WLAN0_5G_EN 0x00008000 /* FLAG for radio0_2G */ | ||
38 | #define BD_WLAN1_2G_EN 0x00020000 /* FLAG for radio0_2G */ | ||
39 | #define BD_WLAN1_5G_EN 0x00040000 /* FLAG for radio0_2G */ | ||
40 | u16 reset_config_gpio; /* Reset factory GPIO pin */ | ||
41 | u16 sys_led_gpio; /* System LED GPIO pin */ | ||
42 | |||
43 | u32 cpu_freq; /* CPU core frequency in Hz */ | ||
44 | u32 sys_freq; /* System frequency in Hz */ | ||
45 | u32 cnt_freq; /* Calculated C0_COUNT frequency */ | ||
46 | |||
47 | u8 wlan0_mac[ETH_ALEN]; | ||
48 | u8 enet0_mac[ETH_ALEN]; | ||
49 | u8 enet1_mac[ETH_ALEN]; | ||
50 | |||
51 | u16 pci_id; /* Pseudo PCIID for common code */ | ||
52 | u16 mem_cap; /* cap bank1 in MB */ | ||
53 | |||
54 | /* version 3 */ | ||
55 | u8 wlan1_mac[ETH_ALEN]; /* (ar5212) */ | ||
56 | }; | ||
57 | |||
58 | #define BOARD_CONFIG_BUFSZ 0x1000 | ||
59 | |||
60 | /* | ||
61 | * Platform device information for the Wireless MAC | ||
62 | */ | ||
63 | struct ar231x_board_config { | ||
64 | u16 devid; | ||
65 | |||
66 | /* board config data */ | ||
67 | struct ath25_boarddata *config; | ||
68 | |||
69 | /* radio calibration data */ | ||
70 | const char *radio; | ||
71 | }; | ||
72 | |||
73 | #endif /* __ASM_MACH_ATH25_PLATFORM_H */ | ||
diff --git a/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h new file mode 100644 index 000000000000..ade0356df257 --- /dev/null +++ b/arch/mips/include/asm/mach-ath25/cpu-feature-overrides.h | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * Atheros AR231x/AR531x SoC specific CPU feature overrides | ||
3 | * | ||
4 | * Copyright (C) 2008 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * | ||
6 | * This file was derived from: include/asm-mips/cpu-features.h | ||
7 | * Copyright (C) 2003, 2004 Ralf Baechle | ||
8 | * Copyright (C) 2004 Maciej W. Rozycki | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License version 2 as published | ||
12 | * by the Free Software Foundation. | ||
13 | * | ||
14 | */ | ||
15 | #ifndef __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H | ||
16 | #define __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H | ||
17 | |||
18 | /* | ||
19 | * The Atheros AR531x/AR231x SoCs have MIPS 4Kc/4KEc core. | ||
20 | */ | ||
21 | #define cpu_has_tlb 1 | ||
22 | #define cpu_has_4kex 1 | ||
23 | #define cpu_has_3k_cache 0 | ||
24 | #define cpu_has_4k_cache 1 | ||
25 | #define cpu_has_tx39_cache 0 | ||
26 | #define cpu_has_sb1_cache 0 | ||
27 | #define cpu_has_fpu 0 | ||
28 | #define cpu_has_32fpr 0 | ||
29 | #define cpu_has_counter 1 | ||
30 | #define cpu_has_ejtag 1 | ||
31 | |||
32 | #if !defined(CONFIG_SOC_AR5312) | ||
33 | # define cpu_has_llsc 1 | ||
34 | #else | ||
35 | /* | ||
36 | * The MIPS 4Kc V0.9 core in the AR5312/AR2312 have problems with the | ||
37 | * ll/sc instructions. | ||
38 | */ | ||
39 | # define cpu_has_llsc 0 | ||
40 | #endif | ||
41 | |||
42 | #define cpu_has_mips16 0 | ||
43 | #define cpu_has_mdmx 0 | ||
44 | #define cpu_has_mips3d 0 | ||
45 | #define cpu_has_smartmips 0 | ||
46 | |||
47 | #define cpu_has_mips32r1 1 | ||
48 | |||
49 | #if !defined(CONFIG_SOC_AR5312) | ||
50 | # define cpu_has_mips32r2 1 | ||
51 | #endif | ||
52 | |||
53 | #define cpu_has_mips64r1 0 | ||
54 | #define cpu_has_mips64r2 0 | ||
55 | |||
56 | #define cpu_has_dsp 0 | ||
57 | #define cpu_has_mipsmt 0 | ||
58 | |||
59 | #define cpu_has_64bits 0 | ||
60 | #define cpu_has_64bit_zero_reg 0 | ||
61 | #define cpu_has_64bit_gp_regs 0 | ||
62 | #define cpu_has_64bit_addresses 0 | ||
63 | |||
64 | #endif /* __ASM_MACH_ATH25_CPU_FEATURE_OVERRIDES_H */ | ||
diff --git a/arch/mips/include/asm/mach-ath25/dma-coherence.h b/arch/mips/include/asm/mach-ath25/dma-coherence.h new file mode 100644 index 000000000000..d8009c93a465 --- /dev/null +++ b/arch/mips/include/asm/mach-ath25/dma-coherence.h | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org> | ||
7 | * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org> | ||
8 | * | ||
9 | */ | ||
10 | #ifndef __ASM_MACH_ATH25_DMA_COHERENCE_H | ||
11 | #define __ASM_MACH_ATH25_DMA_COHERENCE_H | ||
12 | |||
13 | #include <linux/device.h> | ||
14 | |||
15 | /* | ||
16 | * We need some arbitrary non-zero value to be programmed to the BAR1 register | ||
17 | * of PCI host controller to enable DMA. The same value should be used as the | ||
18 | * offset to calculate the physical address of DMA buffer for PCI devices. | ||
19 | */ | ||
20 | #define AR2315_PCI_HOST_SDRAM_BASEADDR 0x20000000 | ||
21 | |||
22 | static inline dma_addr_t ath25_dev_offset(struct device *dev) | ||
23 | { | ||
24 | #ifdef CONFIG_PCI | ||
25 | extern struct bus_type pci_bus_type; | ||
26 | |||
27 | if (dev && dev->bus == &pci_bus_type) | ||
28 | return AR2315_PCI_HOST_SDRAM_BASEADDR; | ||
29 | #endif | ||
30 | return 0; | ||
31 | } | ||
32 | |||
33 | static inline dma_addr_t | ||
34 | plat_map_dma_mem(struct device *dev, void *addr, size_t size) | ||
35 | { | ||
36 | return virt_to_phys(addr) + ath25_dev_offset(dev); | ||
37 | } | ||
38 | |||
39 | static inline dma_addr_t | ||
40 | plat_map_dma_mem_page(struct device *dev, struct page *page) | ||
41 | { | ||
42 | return page_to_phys(page) + ath25_dev_offset(dev); | ||
43 | } | ||
44 | |||
45 | static inline unsigned long | ||
46 | plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) | ||
47 | { | ||
48 | return dma_addr - ath25_dev_offset(dev); | ||
49 | } | ||
50 | |||
51 | static inline void | ||
52 | plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, size_t size, | ||
53 | enum dma_data_direction direction) | ||
54 | { | ||
55 | } | ||
56 | |||
57 | static inline int plat_dma_supported(struct device *dev, u64 mask) | ||
58 | { | ||
59 | return 1; | ||
60 | } | ||
61 | |||
62 | static inline void plat_extra_sync_for_device(struct device *dev) | ||
63 | { | ||
64 | } | ||
65 | |||
66 | static inline int plat_dma_mapping_error(struct device *dev, | ||
67 | dma_addr_t dma_addr) | ||
68 | { | ||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static inline int plat_device_is_coherent(struct device *dev) | ||
73 | { | ||
74 | #ifdef CONFIG_DMA_COHERENT | ||
75 | return 1; | ||
76 | #endif | ||
77 | #ifdef CONFIG_DMA_NONCOHERENT | ||
78 | return 0; | ||
79 | #endif | ||
80 | } | ||
81 | |||
82 | #endif /* __ASM_MACH_ATH25_DMA_COHERENCE_H */ | ||
diff --git a/arch/mips/include/asm/mach-ath25/gpio.h b/arch/mips/include/asm/mach-ath25/gpio.h new file mode 100644 index 000000000000..713564b8e8ef --- /dev/null +++ b/arch/mips/include/asm/mach-ath25/gpio.h | |||
@@ -0,0 +1,16 @@ | |||
1 | #ifndef __ASM_MACH_ATH25_GPIO_H | ||
2 | #define __ASM_MACH_ATH25_GPIO_H | ||
3 | |||
4 | #include <asm-generic/gpio.h> | ||
5 | |||
6 | #define gpio_get_value __gpio_get_value | ||
7 | #define gpio_set_value __gpio_set_value | ||
8 | #define gpio_cansleep __gpio_cansleep | ||
9 | #define gpio_to_irq __gpio_to_irq | ||
10 | |||
11 | static inline int irq_to_gpio(unsigned irq) | ||
12 | { | ||
13 | return -EINVAL; | ||
14 | } | ||
15 | |||
16 | #endif /* __ASM_MACH_ATH25_GPIO_H */ | ||
diff --git a/arch/mips/include/asm/mach-ath25/war.h b/arch/mips/include/asm/mach-ath25/war.h new file mode 100644 index 000000000000..e3a5250ebd67 --- /dev/null +++ b/arch/mips/include/asm/mach-ath25/war.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org> | ||
7 | */ | ||
8 | #ifndef __ASM_MACH_ATH25_WAR_H | ||
9 | #define __ASM_MACH_ATH25_WAR_H | ||
10 | |||
11 | #define R4600_V1_INDEX_ICACHEOP_WAR 0 | ||
12 | #define R4600_V1_HIT_CACHEOP_WAR 0 | ||
13 | #define R4600_V2_HIT_CACHEOP_WAR 0 | ||
14 | #define R5432_CP0_INTERRUPT_WAR 0 | ||
15 | #define BCM1250_M3_WAR 0 | ||
16 | #define SIBYTE_1956_WAR 0 | ||
17 | #define MIPS4K_ICACHE_REFILL_WAR 0 | ||
18 | #define MIPS_CACHE_SYNC_WAR 0 | ||
19 | #define TX49XX_ICACHE_INDEX_INV_WAR 0 | ||
20 | #define RM9000_CDEX_SMP_WAR 0 | ||
21 | #define ICACHE_REFILLS_WORKAROUND_WAR 0 | ||
22 | #define R10000_LLSC_WAR 0 | ||
23 | #define MIPS34K_MISSED_ITLB_WAR 0 | ||
24 | |||
25 | #endif /* __ASM_MACH_ATH25_WAR_H */ | ||
diff --git a/arch/mips/include/asm/mach-au1x00/ioremap.h b/arch/mips/include/asm/mach-au1x00/ioremap.h index 75a94ad3ac91..99fea1fbb4f5 100644 --- a/arch/mips/include/asm/mach-au1x00/ioremap.h +++ b/arch/mips/include/asm/mach-au1x00/ioremap.h | |||
@@ -11,10 +11,10 @@ | |||
11 | 11 | ||
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | 13 | ||
14 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_PCI) | 14 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_PCI) |
15 | extern phys_t __fixup_bigphys_addr(phys_t, phys_t); | 15 | extern phys_addr_t __fixup_bigphys_addr(phys_addr_t, phys_addr_t); |
16 | #else | 16 | #else |
17 | static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) | 17 | static inline phys_addr_t __fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) |
18 | { | 18 | { |
19 | return phys_addr; | 19 | return phys_addr; |
20 | } | 20 | } |
@@ -23,12 +23,12 @@ static inline phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) | |||
23 | /* | 23 | /* |
24 | * Allow physical addresses to be fixed up to help 36-bit peripherals. | 24 | * Allow physical addresses to be fixed up to help 36-bit peripherals. |
25 | */ | 25 | */ |
26 | static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) | 26 | static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) |
27 | { | 27 | { |
28 | return __fixup_bigphys_addr(phys_addr, size); | 28 | return __fixup_bigphys_addr(phys_addr, size); |
29 | } | 29 | } |
30 | 30 | ||
31 | static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, | 31 | static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, |
32 | unsigned long flags) | 32 | unsigned long flags) |
33 | { | 33 | { |
34 | return NULL; | 34 | return NULL; |
diff --git a/arch/mips/include/asm/mach-bcm3384/dma-coherence.h b/arch/mips/include/asm/mach-bcm3384/dma-coherence.h new file mode 100644 index 000000000000..a3be8e50e1f0 --- /dev/null +++ b/arch/mips/include/asm/mach-bcm3384/dma-coherence.h | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org> | ||
3 | * Copyright (C) 2009 Broadcom Corporation | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __ASM_MACH_BCM3384_DMA_COHERENCE_H | ||
16 | #define __ASM_MACH_BCM3384_DMA_COHERENCE_H | ||
17 | |||
18 | struct device; | ||
19 | |||
20 | extern dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size); | ||
21 | extern dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page); | ||
22 | extern unsigned long plat_dma_addr_to_phys(struct device *dev, | ||
23 | dma_addr_t dma_addr); | ||
24 | |||
25 | static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, | ||
26 | size_t size, enum dma_data_direction direction) | ||
27 | { | ||
28 | } | ||
29 | |||
30 | static inline int plat_dma_supported(struct device *dev, u64 mask) | ||
31 | { | ||
32 | /* | ||
33 | * we fall back to GFP_DMA when the mask isn't all 1s, | ||
34 | * so we can't guarantee allocations that must be | ||
35 | * within a tighter range than GFP_DMA.. | ||
36 | */ | ||
37 | if (mask < DMA_BIT_MASK(24)) | ||
38 | return 0; | ||
39 | |||
40 | return 1; | ||
41 | } | ||
42 | |||
43 | static inline int plat_device_is_coherent(struct device *dev) | ||
44 | { | ||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | #endif /* __ASM_MACH_BCM3384_DMA_COHERENCE_H */ | ||
diff --git a/arch/mips/include/asm/mach-bcm3384/war.h b/arch/mips/include/asm/mach-bcm3384/war.h new file mode 100644 index 000000000000..59d7599059b0 --- /dev/null +++ b/arch/mips/include/asm/mach-bcm3384/war.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> | ||
7 | */ | ||
8 | #ifndef __ASM_MIPS_MACH_BCM3384_WAR_H | ||
9 | #define __ASM_MIPS_MACH_BCM3384_WAR_H | ||
10 | |||
11 | #define R4600_V1_INDEX_ICACHEOP_WAR 0 | ||
12 | #define R4600_V1_HIT_CACHEOP_WAR 0 | ||
13 | #define R4600_V2_HIT_CACHEOP_WAR 0 | ||
14 | #define R5432_CP0_INTERRUPT_WAR 0 | ||
15 | #define BCM1250_M3_WAR 0 | ||
16 | #define SIBYTE_1956_WAR 0 | ||
17 | #define MIPS4K_ICACHE_REFILL_WAR 0 | ||
18 | #define MIPS_CACHE_SYNC_WAR 0 | ||
19 | #define TX49XX_ICACHE_INDEX_INV_WAR 0 | ||
20 | #define ICACHE_REFILLS_WORKAROUND_WAR 0 | ||
21 | #define R10000_LLSC_WAR 0 | ||
22 | #define MIPS34K_MISSED_ITLB_WAR 0 | ||
23 | |||
24 | #endif /* __ASM_MIPS_MACH_BCM3384_WAR_H */ | ||
diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h index 36a3fc1aa3ae..ee59ffe99922 100644 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_nvram.h | |||
@@ -14,40 +14,8 @@ | |||
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | 16 | ||
17 | struct nvram_header { | 17 | int bcm47xx_nvram_init_from_mem(u32 base, u32 lim); |
18 | u32 magic; | 18 | int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len); |
19 | u32 len; | ||
20 | u32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */ | ||
21 | u32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */ | ||
22 | u32 config_ncdl; /* ncdl values for memc */ | ||
23 | }; | ||
24 | |||
25 | #define NVRAM_HEADER 0x48534C46 /* 'FLSH' */ | ||
26 | #define NVRAM_VERSION 1 | ||
27 | #define NVRAM_HEADER_SIZE 20 | ||
28 | #define NVRAM_SPACE 0x8000 | ||
29 | |||
30 | #define FLASH_MIN 0x00020000 /* Minimum flash size */ | ||
31 | |||
32 | #define NVRAM_MAX_VALUE_LEN 255 | ||
33 | #define NVRAM_MAX_PARAM_LEN 64 | ||
34 | |||
35 | extern int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len); | ||
36 | |||
37 | static inline void bcm47xx_nvram_parse_macaddr(char *buf, u8 macaddr[6]) | ||
38 | { | ||
39 | if (strchr(buf, ':')) | ||
40 | sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], | ||
41 | &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4], | ||
42 | &macaddr[5]); | ||
43 | else if (strchr(buf, '-')) | ||
44 | sscanf(buf, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &macaddr[0], | ||
45 | &macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4], | ||
46 | &macaddr[5]); | ||
47 | else | ||
48 | printk(KERN_WARNING "Can not parse mac address: %s\n", buf); | ||
49 | } | ||
50 | |||
51 | int bcm47xx_nvram_gpio_pin(const char *name); | 19 | int bcm47xx_nvram_gpio_pin(const char *name); |
52 | 20 | ||
53 | #endif /* __BCM47XX_NVRAM_H */ | 21 | #endif /* __BCM47XX_NVRAM_H */ |
diff --git a/arch/mips/include/asm/mach-bcm63xx/ioremap.h b/arch/mips/include/asm/mach-bcm63xx/ioremap.h index ff15e3b14e7a..aea6e64b828f 100644 --- a/arch/mips/include/asm/mach-bcm63xx/ioremap.h +++ b/arch/mips/include/asm/mach-bcm63xx/ioremap.h | |||
@@ -3,12 +3,12 @@ | |||
3 | 3 | ||
4 | #include <bcm63xx_cpu.h> | 4 | #include <bcm63xx_cpu.h> |
5 | 5 | ||
6 | static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) | 6 | static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) |
7 | { | 7 | { |
8 | return phys_addr; | 8 | return phys_addr; |
9 | } | 9 | } |
10 | 10 | ||
11 | static inline int is_bcm63xx_internal_registers(phys_t offset) | 11 | static inline int is_bcm63xx_internal_registers(phys_addr_t offset) |
12 | { | 12 | { |
13 | switch (bcm63xx_get_cpu_id()) { | 13 | switch (bcm63xx_get_cpu_id()) { |
14 | case BCM3368_CPU_ID: | 14 | case BCM3368_CPU_ID: |
@@ -32,7 +32,7 @@ static inline int is_bcm63xx_internal_registers(phys_t offset) | |||
32 | return 0; | 32 | return 0; |
33 | } | 33 | } |
34 | 34 | ||
35 | static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, | 35 | static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, |
36 | unsigned long flags) | 36 | unsigned long flags) |
37 | { | 37 | { |
38 | if (is_bcm63xx_internal_registers(offset)) | 38 | if (is_bcm63xx_internal_registers(offset)) |
diff --git a/arch/mips/include/asm/mach-generic/ioremap.h b/arch/mips/include/asm/mach-generic/ioremap.h index b379938d47f0..513371f7c39c 100644 --- a/arch/mips/include/asm/mach-generic/ioremap.h +++ b/arch/mips/include/asm/mach-generic/ioremap.h | |||
@@ -15,12 +15,12 @@ | |||
15 | * Allow physical addresses to be fixed up to help peripherals located | 15 | * Allow physical addresses to be fixed up to help peripherals located |
16 | * outside the low 32-bit range -- generic pass-through version. | 16 | * outside the low 32-bit range -- generic pass-through version. |
17 | */ | 17 | */ |
18 | static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) | 18 | static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) |
19 | { | 19 | { |
20 | return phys_addr; | 20 | return phys_addr; |
21 | } | 21 | } |
22 | 22 | ||
23 | static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, | 23 | static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, |
24 | unsigned long flags) | 24 | unsigned long flags) |
25 | { | 25 | { |
26 | return NULL; | 26 | return NULL; |
diff --git a/arch/mips/include/asm/mach-generic/irq.h b/arch/mips/include/asm/mach-generic/irq.h index 139cd200e79d..050e18bb1a04 100644 --- a/arch/mips/include/asm/mach-generic/irq.h +++ b/arch/mips/include/asm/mach-generic/irq.h | |||
@@ -36,4 +36,10 @@ | |||
36 | 36 | ||
37 | #endif /* CONFIG_IRQ_CPU */ | 37 | #endif /* CONFIG_IRQ_CPU */ |
38 | 38 | ||
39 | #ifdef CONFIG_MIPS_GIC | ||
40 | #ifndef MIPS_GIC_IRQ_BASE | ||
41 | #define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8) | ||
42 | #endif | ||
43 | #endif /* CONFIG_MIPS_GIC */ | ||
44 | |||
39 | #endif /* __ASM_MACH_GENERIC_IRQ_H */ | 45 | #endif /* __ASM_MACH_GENERIC_IRQ_H */ |
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq.h b/arch/mips/include/asm/mach-lantiq/lantiq.h index f196cceb7322..4e5ae6523cb4 100644 --- a/arch/mips/include/asm/mach-lantiq/lantiq.h +++ b/arch/mips/include/asm/mach-lantiq/lantiq.h | |||
@@ -48,6 +48,8 @@ extern struct clk *clk_get_ppe(void); | |||
48 | extern unsigned char ltq_boot_select(void); | 48 | extern unsigned char ltq_boot_select(void); |
49 | /* find out what caused the last cpu reset */ | 49 | /* find out what caused the last cpu reset */ |
50 | extern int ltq_reset_cause(void); | 50 | extern int ltq_reset_cause(void); |
51 | /* find out the soc type */ | ||
52 | extern int ltq_soc_type(void); | ||
51 | 53 | ||
52 | #define IOPORT_RESOURCE_START 0x10000000 | 54 | #define IOPORT_RESOURCE_START 0x10000000 |
53 | #define IOPORT_RESOURCE_END 0xffffffff | 55 | #define IOPORT_RESOURCE_END 0xffffffff |
diff --git a/arch/mips/include/asm/mach-loongson/boot_param.h b/arch/mips/include/asm/mach-loongson/boot_param.h index 3388fc53599e..fa802926523f 100644 --- a/arch/mips/include/asm/mach-loongson/boot_param.h +++ b/arch/mips/include/asm/mach-loongson/boot_param.h | |||
@@ -10,7 +10,8 @@ | |||
10 | #define VIDEO_ROM 7 | 10 | #define VIDEO_ROM 7 |
11 | #define ADAPTER_ROM 8 | 11 | #define ADAPTER_ROM 8 |
12 | #define ACPI_TABLE 9 | 12 | #define ACPI_TABLE 9 |
13 | #define MAX_MEMORY_TYPE 10 | 13 | #define SMBIOS_TABLE 10 |
14 | #define MAX_MEMORY_TYPE 11 | ||
14 | 15 | ||
15 | #define LOONGSON3_BOOT_MEM_MAP_MAX 128 | 16 | #define LOONGSON3_BOOT_MEM_MAP_MAX 128 |
16 | struct efi_memory_map_loongson { | 17 | struct efi_memory_map_loongson { |
@@ -42,15 +43,49 @@ struct efi_cpuinfo_loongson { | |||
42 | u32 processor_id; /* PRID, e.g. 6305, 6306 */ | 43 | u32 processor_id; /* PRID, e.g. 6305, 6306 */ |
43 | u32 cputype; /* Loongson_3A/3B, etc. */ | 44 | u32 cputype; /* Loongson_3A/3B, etc. */ |
44 | u32 total_node; /* num of total numa nodes */ | 45 | u32 total_node; /* num of total numa nodes */ |
45 | u32 cpu_startup_core_id; /* Core id */ | 46 | u16 cpu_startup_core_id; /* Boot core id */ |
47 | u16 reserved_cores_mask; | ||
46 | u32 cpu_clock_freq; /* cpu_clock */ | 48 | u32 cpu_clock_freq; /* cpu_clock */ |
47 | u32 nr_cpus; | 49 | u32 nr_cpus; |
48 | } __packed; | 50 | } __packed; |
49 | 51 | ||
52 | #define MAX_UARTS 64 | ||
53 | struct uart_device { | ||
54 | u32 iotype; /* see include/linux/serial_core.h */ | ||
55 | u32 uartclk; | ||
56 | u32 int_offset; | ||
57 | u64 uart_base; | ||
58 | } __packed; | ||
59 | |||
60 | #define MAX_SENSORS 64 | ||
61 | #define SENSOR_TEMPER 0x00000001 | ||
62 | #define SENSOR_VOLTAGE 0x00000002 | ||
63 | #define SENSOR_FAN 0x00000004 | ||
64 | struct sensor_device { | ||
65 | char name[32]; /* a formal name */ | ||
66 | char label[64]; /* a flexible description */ | ||
67 | u32 type; /* SENSOR_* */ | ||
68 | u32 id; /* instance id of a sensor-class */ | ||
69 | u32 fan_policy; /* see loongson_hwmon.h */ | ||
70 | u32 fan_percent;/* only for constant speed policy */ | ||
71 | u64 base_addr; /* base address of device registers */ | ||
72 | } __packed; | ||
73 | |||
50 | struct system_loongson { | 74 | struct system_loongson { |
51 | u16 vers; /* version of system_loongson */ | 75 | u16 vers; /* version of system_loongson */ |
52 | u32 ccnuma_smp; /* 0: no numa; 1: has numa */ | 76 | u32 ccnuma_smp; /* 0: no numa; 1: has numa */ |
53 | u32 sing_double_channel; /* 1:single; 2:double */ | 77 | u32 sing_double_channel; /* 1:single; 2:double */ |
78 | u32 nr_uarts; | ||
79 | struct uart_device uarts[MAX_UARTS]; | ||
80 | u32 nr_sensors; | ||
81 | struct sensor_device sensors[MAX_SENSORS]; | ||
82 | char has_ec; | ||
83 | char ec_name[32]; | ||
84 | u64 ec_base_addr; | ||
85 | char has_tcm; | ||
86 | char tcm_name[32]; | ||
87 | u64 tcm_base_addr; | ||
88 | u64 workarounds; /* see workarounds.h */ | ||
54 | } __packed; | 89 | } __packed; |
55 | 90 | ||
56 | struct irq_source_routing_table { | 91 | struct irq_source_routing_table { |
@@ -149,6 +184,8 @@ struct loongson_system_configuration { | |||
149 | u32 nr_nodes; | 184 | u32 nr_nodes; |
150 | int cores_per_node; | 185 | int cores_per_node; |
151 | int cores_per_package; | 186 | int cores_per_package; |
187 | u16 boot_cpu_id; | ||
188 | u16 reserved_cpus_mask; | ||
152 | enum loongson_cpu_type cputype; | 189 | enum loongson_cpu_type cputype; |
153 | u64 ht_control_base; | 190 | u64 ht_control_base; |
154 | u64 pci_mem_start_addr; | 191 | u64 pci_mem_start_addr; |
@@ -159,9 +196,15 @@ struct loongson_system_configuration { | |||
159 | u64 suspend_addr; | 196 | u64 suspend_addr; |
160 | u64 vgabios_addr; | 197 | u64 vgabios_addr; |
161 | u32 dma_mask_bits; | 198 | u32 dma_mask_bits; |
199 | char ecname[32]; | ||
200 | u32 nr_uarts; | ||
201 | struct uart_device uarts[MAX_UARTS]; | ||
202 | u32 nr_sensors; | ||
203 | struct sensor_device sensors[MAX_SENSORS]; | ||
204 | u64 workarounds; | ||
162 | }; | 205 | }; |
163 | 206 | ||
164 | extern struct efi_memory_map_loongson *loongson_memmap; | 207 | extern struct efi_memory_map_loongson *loongson_memmap; |
165 | extern struct loongson_system_configuration loongson_sysconf; | 208 | extern struct loongson_system_configuration loongson_sysconf; |
166 | extern int cpuhotplug_workaround; | 209 | |
167 | #endif | 210 | #endif |
diff --git a/arch/mips/include/asm/mach-loongson/dma-coherence.h b/arch/mips/include/asm/mach-loongson/dma-coherence.h index 6a902751cc7f..a90534161bd2 100644 --- a/arch/mips/include/asm/mach-loongson/dma-coherence.h +++ b/arch/mips/include/asm/mach-loongson/dma-coherence.h | |||
@@ -23,7 +23,7 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, | |||
23 | size_t size) | 23 | size_t size) |
24 | { | 24 | { |
25 | #ifdef CONFIG_CPU_LOONGSON3 | 25 | #ifdef CONFIG_CPU_LOONGSON3 |
26 | return virt_to_phys(addr); | 26 | return phys_to_dma(dev, virt_to_phys(addr)); |
27 | #else | 27 | #else |
28 | return virt_to_phys(addr) | 0x80000000; | 28 | return virt_to_phys(addr) | 0x80000000; |
29 | #endif | 29 | #endif |
@@ -33,7 +33,7 @@ static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, | |||
33 | struct page *page) | 33 | struct page *page) |
34 | { | 34 | { |
35 | #ifdef CONFIG_CPU_LOONGSON3 | 35 | #ifdef CONFIG_CPU_LOONGSON3 |
36 | return page_to_phys(page); | 36 | return phys_to_dma(dev, page_to_phys(page)); |
37 | #else | 37 | #else |
38 | return page_to_phys(page) | 0x80000000; | 38 | return page_to_phys(page) | 0x80000000; |
39 | #endif | 39 | #endif |
@@ -43,7 +43,7 @@ static inline unsigned long plat_dma_addr_to_phys(struct device *dev, | |||
43 | dma_addr_t dma_addr) | 43 | dma_addr_t dma_addr) |
44 | { | 44 | { |
45 | #if defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_64BIT) | 45 | #if defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_64BIT) |
46 | return dma_addr; | 46 | return dma_to_phys(dev, dma_addr); |
47 | #elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) | 47 | #elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) |
48 | return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff); | 48 | return (dma_addr > 0x8fffffff) ? dma_addr : (dma_addr & 0x0fffffff); |
49 | #else | 49 | #else |
diff --git a/arch/mips/include/asm/mach-loongson/irq.h b/arch/mips/include/asm/mach-loongson/irq.h index 34560bda6626..a281cca5f2fb 100644 --- a/arch/mips/include/asm/mach-loongson/irq.h +++ b/arch/mips/include/asm/mach-loongson/irq.h | |||
@@ -32,8 +32,7 @@ | |||
32 | #define LOONGSON_INT_ROUTER_LPC LOONGSON_INT_ROUTER_ENTRY(0x0a) | 32 | #define LOONGSON_INT_ROUTER_LPC LOONGSON_INT_ROUTER_ENTRY(0x0a) |
33 | #define LOONGSON_INT_ROUTER_HT1(n) LOONGSON_INT_ROUTER_ENTRY(n + 0x18) | 33 | #define LOONGSON_INT_ROUTER_HT1(n) LOONGSON_INT_ROUTER_ENTRY(n + 0x18) |
34 | 34 | ||
35 | #define LOONGSON_INT_CORE0_INT0 0x11 /* route to int 0 of core 0 */ | 35 | #define LOONGSON_INT_COREx_INTy(x, y) (1<<(x) | 1<<(y+4)) /* route to int y of core x */ |
36 | #define LOONGSON_INT_CORE0_INT1 0x21 /* route to int 1 of core 0 */ | ||
37 | 36 | ||
38 | #endif | 37 | #endif |
39 | 38 | ||
diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h index 92bf76c21441..5459ac09679f 100644 --- a/arch/mips/include/asm/mach-loongson/loongson.h +++ b/arch/mips/include/asm/mach-loongson/loongson.h | |||
@@ -35,7 +35,7 @@ extern void __init prom_init_cmdline(void); | |||
35 | extern void __init prom_init_machtype(void); | 35 | extern void __init prom_init_machtype(void); |
36 | extern void __init prom_init_env(void); | 36 | extern void __init prom_init_env(void); |
37 | #ifdef CONFIG_LOONGSON_UART_BASE | 37 | #ifdef CONFIG_LOONGSON_UART_BASE |
38 | extern unsigned long _loongson_uart_base, loongson_uart_base; | 38 | extern unsigned long _loongson_uart_base[], loongson_uart_base[]; |
39 | extern void prom_init_loongson_uart_base(void); | 39 | extern void prom_init_loongson_uart_base(void); |
40 | #endif | 40 | #endif |
41 | 41 | ||
diff --git a/arch/mips/include/asm/mach-loongson/loongson_hwmon.h b/arch/mips/include/asm/mach-loongson/loongson_hwmon.h new file mode 100644 index 000000000000..4431fc54a36c --- /dev/null +++ b/arch/mips/include/asm/mach-loongson/loongson_hwmon.h | |||
@@ -0,0 +1,55 @@ | |||
1 | #ifndef __LOONGSON_HWMON_H_ | ||
2 | #define __LOONGSON_HWMON_H_ | ||
3 | |||
4 | #include <linux/types.h> | ||
5 | |||
6 | #define MIN_TEMP 0 | ||
7 | #define MAX_TEMP 255 | ||
8 | #define NOT_VALID_TEMP 999 | ||
9 | |||
10 | typedef int (*get_temp_fun)(int); | ||
11 | extern int loongson3_cpu_temp(int); | ||
12 | |||
13 | /* 0:Max speed, 1:Manual, 2:Auto */ | ||
14 | enum fan_control_mode { | ||
15 | FAN_FULL_MODE = 0, | ||
16 | FAN_MANUAL_MODE = 1, | ||
17 | FAN_AUTO_MODE = 2, | ||
18 | FAN_MODE_END | ||
19 | }; | ||
20 | |||
21 | struct temp_range { | ||
22 | u8 low; | ||
23 | u8 high; | ||
24 | u8 level; | ||
25 | }; | ||
26 | |||
27 | #define CONSTANT_SPEED_POLICY 0 /* at constent speed */ | ||
28 | #define STEP_SPEED_POLICY 1 /* use up/down arrays to describe policy */ | ||
29 | #define KERNEL_HELPER_POLICY 2 /* kernel as a helper to fan control */ | ||
30 | |||
31 | #define MAX_STEP_NUM 16 | ||
32 | #define MAX_FAN_LEVEL 255 | ||
33 | |||
34 | /* loongson_fan_policy works when fan work at FAN_AUTO_MODE */ | ||
35 | struct loongson_fan_policy { | ||
36 | u8 type; | ||
37 | |||
38 | /* percent only used when type is CONSTANT_SPEED_POLICY */ | ||
39 | u8 percent; | ||
40 | |||
41 | /* period between two check. (Unit: S) */ | ||
42 | u8 adjust_period; | ||
43 | |||
44 | /* fan adjust usually depend on a temprature input */ | ||
45 | get_temp_fun depend_temp; | ||
46 | |||
47 | /* up_step/down_step used when type is STEP_SPEED_POLICY */ | ||
48 | u8 up_step_num; | ||
49 | u8 down_step_num; | ||
50 | struct temp_range up_step[MAX_STEP_NUM]; | ||
51 | struct temp_range down_step[MAX_STEP_NUM]; | ||
52 | struct delayed_work work; | ||
53 | }; | ||
54 | |||
55 | #endif /* __LOONGSON_HWMON_H_*/ | ||
diff --git a/arch/mips/include/asm/mach-loongson/machine.h b/arch/mips/include/asm/mach-loongson/machine.h index 228e37847a36..cb2b60249cd2 100644 --- a/arch/mips/include/asm/mach-loongson/machine.h +++ b/arch/mips/include/asm/mach-loongson/machine.h | |||
@@ -26,7 +26,7 @@ | |||
26 | 26 | ||
27 | #ifdef CONFIG_LOONGSON_MACH3X | 27 | #ifdef CONFIG_LOONGSON_MACH3X |
28 | 28 | ||
29 | #define LOONGSON_MACHTYPE MACH_LEMOTE_A1101 | 29 | #define LOONGSON_MACHTYPE MACH_LOONGSON_GENERIC |
30 | 30 | ||
31 | #endif /* CONFIG_LOONGSON_MACH3X */ | 31 | #endif /* CONFIG_LOONGSON_MACH3X */ |
32 | 32 | ||
diff --git a/arch/mips/include/asm/mach-loongson/topology.h b/arch/mips/include/asm/mach-loongson/topology.h index 5598ba77d2ef..0d8f3b55bdbc 100644 --- a/arch/mips/include/asm/mach-loongson/topology.h +++ b/arch/mips/include/asm/mach-loongson/topology.h | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | #ifdef CONFIG_NUMA | 4 | #ifdef CONFIG_NUMA |
5 | 5 | ||
6 | #define cpu_to_node(cpu) ((cpu) >> 2) | 6 | #define cpu_to_node(cpu) (cpu_logical_map(cpu) >> 2) |
7 | #define parent_node(node) (node) | 7 | #define parent_node(node) (node) |
8 | #define cpumask_of_node(node) (&__node_data[(node)]->cpumask) | 8 | #define cpumask_of_node(node) (&__node_data[(node)]->cpumask) |
9 | 9 | ||
diff --git a/arch/mips/include/asm/mach-loongson/workarounds.h b/arch/mips/include/asm/mach-loongson/workarounds.h new file mode 100644 index 000000000000..e180c1422eae --- /dev/null +++ b/arch/mips/include/asm/mach-loongson/workarounds.h | |||
@@ -0,0 +1,7 @@ | |||
1 | #ifndef __ASM_MACH_LOONGSON_WORKAROUNDS_H_ | ||
2 | #define __ASM_MACH_LOONGSON_WORKAROUNDS_H_ | ||
3 | |||
4 | #define WORKAROUND_CPUFREQ 0x00000001 | ||
5 | #define WORKAROUND_CPUHOTPLUG 0x00000002 | ||
6 | |||
7 | #endif | ||
diff --git a/arch/mips/include/asm/mach-loongson1/cpufreq.h b/arch/mips/include/asm/mach-loongson1/cpufreq.h new file mode 100644 index 000000000000..e7765ce30bcf --- /dev/null +++ b/arch/mips/include/asm/mach-loongson1/cpufreq.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com> | ||
3 | * | ||
4 | * Loongson 1 CPUFreq platform support. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | |||
13 | #ifndef __ASM_MACH_LOONGSON1_CPUFREQ_H | ||
14 | #define __ASM_MACH_LOONGSON1_CPUFREQ_H | ||
15 | |||
16 | struct plat_ls1x_cpufreq { | ||
17 | const char *clk_name; /* CPU clk */ | ||
18 | const char *osc_clk_name; /* OSC clk */ | ||
19 | unsigned int max_freq; /* in kHz */ | ||
20 | unsigned int min_freq; /* in kHz */ | ||
21 | }; | ||
22 | |||
23 | #endif /* __ASM_MACH_LOONGSON1_CPUFREQ_H */ | ||
diff --git a/arch/mips/include/asm/mach-loongson1/loongson1.h b/arch/mips/include/asm/mach-loongson1/loongson1.h index 5c437c2ba6b3..20e0c2b155dd 100644 --- a/arch/mips/include/asm/mach-loongson1/loongson1.h +++ b/arch/mips/include/asm/mach-loongson1/loongson1.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #define DEFAULT_MEMSIZE 256 /* If no memsize provided */ | 16 | #define DEFAULT_MEMSIZE 256 /* If no memsize provided */ |
17 | 17 | ||
18 | /* Loongson 1 Register Bases */ | 18 | /* Loongson 1 Register Bases */ |
19 | #define LS1X_MUX_BASE 0x1fd00420 | ||
19 | #define LS1X_INTC_BASE 0x1fd01040 | 20 | #define LS1X_INTC_BASE 0x1fd01040 |
20 | #define LS1X_EHCI_BASE 0x1fe00000 | 21 | #define LS1X_EHCI_BASE 0x1fe00000 |
21 | #define LS1X_OHCI_BASE 0x1fe08000 | 22 | #define LS1X_OHCI_BASE 0x1fe08000 |
@@ -31,7 +32,10 @@ | |||
31 | #define LS1X_I2C0_BASE 0x1fe58000 | 32 | #define LS1X_I2C0_BASE 0x1fe58000 |
32 | #define LS1X_I2C1_BASE 0x1fe68000 | 33 | #define LS1X_I2C1_BASE 0x1fe68000 |
33 | #define LS1X_I2C2_BASE 0x1fe70000 | 34 | #define LS1X_I2C2_BASE 0x1fe70000 |
34 | #define LS1X_PWM_BASE 0x1fe5c000 | 35 | #define LS1X_PWM0_BASE 0x1fe5c000 |
36 | #define LS1X_PWM1_BASE 0x1fe5c010 | ||
37 | #define LS1X_PWM2_BASE 0x1fe5c020 | ||
38 | #define LS1X_PWM3_BASE 0x1fe5c030 | ||
35 | #define LS1X_WDT_BASE 0x1fe5c060 | 39 | #define LS1X_WDT_BASE 0x1fe5c060 |
36 | #define LS1X_RTC_BASE 0x1fe64000 | 40 | #define LS1X_RTC_BASE 0x1fe64000 |
37 | #define LS1X_AC97_BASE 0x1fe74000 | 41 | #define LS1X_AC97_BASE 0x1fe74000 |
@@ -39,6 +43,8 @@ | |||
39 | #define LS1X_CLK_BASE 0x1fe78030 | 43 | #define LS1X_CLK_BASE 0x1fe78030 |
40 | 44 | ||
41 | #include <regs-clk.h> | 45 | #include <regs-clk.h> |
46 | #include <regs-mux.h> | ||
47 | #include <regs-pwm.h> | ||
42 | #include <regs-wdt.h> | 48 | #include <regs-wdt.h> |
43 | 49 | ||
44 | #endif /* __ASM_MACH_LOONGSON1_LOONGSON1_H */ | 50 | #endif /* __ASM_MACH_LOONGSON1_LOONGSON1_H */ |
diff --git a/arch/mips/include/asm/mach-loongson1/platform.h b/arch/mips/include/asm/mach-loongson1/platform.h index 30c13e508fff..47de55e0c835 100644 --- a/arch/mips/include/asm/mach-loongson1/platform.h +++ b/arch/mips/include/asm/mach-loongson1/platform.h | |||
@@ -13,10 +13,12 @@ | |||
13 | 13 | ||
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | 15 | ||
16 | extern struct platform_device ls1x_uart_device; | 16 | extern struct platform_device ls1x_uart_pdev; |
17 | extern struct platform_device ls1x_eth0_device; | 17 | extern struct platform_device ls1x_cpufreq_pdev; |
18 | extern struct platform_device ls1x_ehci_device; | 18 | extern struct platform_device ls1x_eth0_pdev; |
19 | extern struct platform_device ls1x_rtc_device; | 19 | extern struct platform_device ls1x_eth1_pdev; |
20 | extern struct platform_device ls1x_ehci_pdev; | ||
21 | extern struct platform_device ls1x_rtc_pdev; | ||
20 | 22 | ||
21 | extern void __init ls1x_clk_init(void); | 23 | extern void __init ls1x_clk_init(void); |
22 | extern void __init ls1x_serial_setup(struct platform_device *pdev); | 24 | extern void __init ls1x_serial_setup(struct platform_device *pdev); |
diff --git a/arch/mips/include/asm/mach-loongson1/regs-clk.h b/arch/mips/include/asm/mach-loongson1/regs-clk.h index fb6a3ff9318f..ee2445b10fc3 100644 --- a/arch/mips/include/asm/mach-loongson1/regs-clk.h +++ b/arch/mips/include/asm/mach-loongson1/regs-clk.h | |||
@@ -20,15 +20,32 @@ | |||
20 | 20 | ||
21 | /* Clock PLL Divisor Register Bits */ | 21 | /* Clock PLL Divisor Register Bits */ |
22 | #define DIV_DC_EN (0x1 << 31) | 22 | #define DIV_DC_EN (0x1 << 31) |
23 | #define DIV_DC_RST (0x1 << 30) | ||
23 | #define DIV_CPU_EN (0x1 << 25) | 24 | #define DIV_CPU_EN (0x1 << 25) |
25 | #define DIV_CPU_RST (0x1 << 24) | ||
24 | #define DIV_DDR_EN (0x1 << 19) | 26 | #define DIV_DDR_EN (0x1 << 19) |
27 | #define DIV_DDR_RST (0x1 << 18) | ||
28 | #define RST_DC_EN (0x1 << 5) | ||
29 | #define RST_DC (0x1 << 4) | ||
30 | #define RST_DDR_EN (0x1 << 3) | ||
31 | #define RST_DDR (0x1 << 2) | ||
32 | #define RST_CPU_EN (0x1 << 1) | ||
33 | #define RST_CPU 0x1 | ||
25 | 34 | ||
26 | #define DIV_DC_SHIFT 26 | 35 | #define DIV_DC_SHIFT 26 |
27 | #define DIV_CPU_SHIFT 20 | 36 | #define DIV_CPU_SHIFT 20 |
28 | #define DIV_DDR_SHIFT 14 | 37 | #define DIV_DDR_SHIFT 14 |
29 | 38 | ||
30 | #define DIV_DC_WIDTH 5 | 39 | #define DIV_DC_WIDTH 4 |
31 | #define DIV_CPU_WIDTH 5 | 40 | #define DIV_CPU_WIDTH 4 |
32 | #define DIV_DDR_WIDTH 5 | 41 | #define DIV_DDR_WIDTH 4 |
42 | |||
43 | #define BYPASS_DC_SHIFT 12 | ||
44 | #define BYPASS_DDR_SHIFT 10 | ||
45 | #define BYPASS_CPU_SHIFT 8 | ||
46 | |||
47 | #define BYPASS_DC_WIDTH 1 | ||
48 | #define BYPASS_DDR_WIDTH 1 | ||
49 | #define BYPASS_CPU_WIDTH 1 | ||
33 | 50 | ||
34 | #endif /* __ASM_MACH_LOONGSON1_REGS_CLK_H */ | 51 | #endif /* __ASM_MACH_LOONGSON1_REGS_CLK_H */ |
diff --git a/arch/mips/include/asm/mach-loongson1/regs-mux.h b/arch/mips/include/asm/mach-loongson1/regs-mux.h new file mode 100644 index 000000000000..fb1e36efaa19 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson1/regs-mux.h | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com> | ||
3 | * | ||
4 | * Loongson 1 MUX Register Definitions. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | #ifndef __ASM_MACH_LOONGSON1_REGS_MUX_H | ||
13 | #define __ASM_MACH_LOONGSON1_REGS_MUX_H | ||
14 | |||
15 | #define LS1X_MUX_REG(x) \ | ||
16 | ((void __iomem *)KSEG1ADDR(LS1X_MUX_BASE + (x))) | ||
17 | |||
18 | #define LS1X_MUX_CTRL0 LS1X_MUX_REG(0x0) | ||
19 | #define LS1X_MUX_CTRL1 LS1X_MUX_REG(0x4) | ||
20 | |||
21 | /* MUX CTRL0 Register Bits */ | ||
22 | #define UART0_USE_PWM23 (0x1 << 28) | ||
23 | #define UART0_USE_PWM01 (0x1 << 27) | ||
24 | #define UART1_USE_LCD0_5_6_11 (0x1 << 26) | ||
25 | #define I2C2_USE_CAN1 (0x1 << 25) | ||
26 | #define I2C1_USE_CAN0 (0x1 << 24) | ||
27 | #define NAND3_USE_UART5 (0x1 << 23) | ||
28 | #define NAND3_USE_UART4 (0x1 << 22) | ||
29 | #define NAND3_USE_UART1_DAT (0x1 << 21) | ||
30 | #define NAND3_USE_UART1_CTS (0x1 << 20) | ||
31 | #define NAND3_USE_PWM23 (0x1 << 19) | ||
32 | #define NAND3_USE_PWM01 (0x1 << 18) | ||
33 | #define NAND2_USE_UART5 (0x1 << 17) | ||
34 | #define NAND2_USE_UART4 (0x1 << 16) | ||
35 | #define NAND2_USE_UART1_DAT (0x1 << 15) | ||
36 | #define NAND2_USE_UART1_CTS (0x1 << 14) | ||
37 | #define NAND2_USE_PWM23 (0x1 << 13) | ||
38 | #define NAND2_USE_PWM01 (0x1 << 12) | ||
39 | #define NAND1_USE_UART5 (0x1 << 11) | ||
40 | #define NAND1_USE_UART4 (0x1 << 10) | ||
41 | #define NAND1_USE_UART1_DAT (0x1 << 9) | ||
42 | #define NAND1_USE_UART1_CTS (0x1 << 8) | ||
43 | #define NAND1_USE_PWM23 (0x1 << 7) | ||
44 | #define NAND1_USE_PWM01 (0x1 << 6) | ||
45 | #define GMAC1_USE_UART1 (0x1 << 4) | ||
46 | #define GMAC1_USE_UART0 (0x1 << 3) | ||
47 | #define LCD_USE_UART0_DAT (0x1 << 2) | ||
48 | #define LCD_USE_UART15 (0x1 << 1) | ||
49 | #define LCD_USE_UART0 0x1 | ||
50 | |||
51 | /* MUX CTRL1 Register Bits */ | ||
52 | #define USB_RESET (0x1 << 31) | ||
53 | #define SPI1_CS_USE_PWM01 (0x1 << 24) | ||
54 | #define SPI1_USE_CAN (0x1 << 23) | ||
55 | #define DISABLE_DDR_CONFSPACE (0x1 << 20) | ||
56 | #define DDR32TO16EN (0x1 << 16) | ||
57 | #define GMAC1_SHUT (0x1 << 13) | ||
58 | #define GMAC0_SHUT (0x1 << 12) | ||
59 | #define USB_SHUT (0x1 << 11) | ||
60 | #define UART1_3_USE_CAN1 (0x1 << 5) | ||
61 | #define UART1_2_USE_CAN0 (0x1 << 4) | ||
62 | #define GMAC1_USE_TXCLK (0x1 << 3) | ||
63 | #define GMAC0_USE_TXCLK (0x1 << 2) | ||
64 | #define GMAC1_USE_PWM23 (0x1 << 1) | ||
65 | #define GMAC0_USE_PWM01 0x1 | ||
66 | |||
67 | #endif /* __ASM_MACH_LOONGSON1_REGS_MUX_H */ | ||
diff --git a/arch/mips/include/asm/mach-loongson1/regs-pwm.h b/arch/mips/include/asm/mach-loongson1/regs-pwm.h new file mode 100644 index 000000000000..99f2bcc586f0 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson1/regs-pwm.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com> | ||
3 | * | ||
4 | * Loongson 1 PWM Register Definitions. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | #ifndef __ASM_MACH_LOONGSON1_REGS_PWM_H | ||
13 | #define __ASM_MACH_LOONGSON1_REGS_PWM_H | ||
14 | |||
15 | /* Loongson 1 PWM Timer Register Definitions */ | ||
16 | #define PWM_CNT 0x0 | ||
17 | #define PWM_HRC 0x4 | ||
18 | #define PWM_LRC 0x8 | ||
19 | #define PWM_CTRL 0xc | ||
20 | |||
21 | /* PWM Control Register Bits */ | ||
22 | #define CNT_RST (0x1 << 7) | ||
23 | #define INT_SR (0x1 << 6) | ||
24 | #define INT_EN (0x1 << 5) | ||
25 | #define PWM_SINGLE (0x1 << 4) | ||
26 | #define PWM_OE (0x1 << 3) | ||
27 | #define CNT_EN 0x1 | ||
28 | |||
29 | #endif /* __ASM_MACH_LOONGSON1_REGS_PWM_H */ | ||
diff --git a/arch/mips/include/asm/mach-loongson1/regs-wdt.h b/arch/mips/include/asm/mach-loongson1/regs-wdt.h index 6574568c2084..c39ee982ad3b 100644 --- a/arch/mips/include/asm/mach-loongson1/regs-wdt.h +++ b/arch/mips/include/asm/mach-loongson1/regs-wdt.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> | 2 | * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> |
3 | * | 3 | * |
4 | * Loongson 1 watchdog register definitions. | 4 | * Loongson 1 Watchdog Register Definitions. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License as published by the | 7 | * under the terms of the GNU General Public License as published by the |
@@ -12,11 +12,8 @@ | |||
12 | #ifndef __ASM_MACH_LOONGSON1_REGS_WDT_H | 12 | #ifndef __ASM_MACH_LOONGSON1_REGS_WDT_H |
13 | #define __ASM_MACH_LOONGSON1_REGS_WDT_H | 13 | #define __ASM_MACH_LOONGSON1_REGS_WDT_H |
14 | 14 | ||
15 | #define LS1X_WDT_REG(x) \ | 15 | #define WDT_EN 0x0 |
16 | ((void __iomem *)KSEG1ADDR(LS1X_WDT_BASE + (x))) | 16 | #define WDT_TIMER 0x4 |
17 | 17 | #define WDT_SET 0x8 | |
18 | #define LS1X_WDT_EN LS1X_WDT_REG(0x0) | ||
19 | #define LS1X_WDT_SET LS1X_WDT_REG(0x4) | ||
20 | #define LS1X_WDT_TIMER LS1X_WDT_REG(0x8) | ||
21 | 18 | ||
22 | #endif /* __ASM_MACH_LOONGSON1_REGS_WDT_H */ | 19 | #endif /* __ASM_MACH_LOONGSON1_REGS_WDT_H */ |
diff --git a/arch/mips/include/asm/mach-malta/irq.h b/arch/mips/include/asm/mach-malta/irq.h index f2c13d211abb..47cfe64efbb0 100644 --- a/arch/mips/include/asm/mach-malta/irq.h +++ b/arch/mips/include/asm/mach-malta/irq.h | |||
@@ -2,7 +2,6 @@ | |||
2 | #define __ASM_MACH_MIPS_IRQ_H | 2 | #define __ASM_MACH_MIPS_IRQ_H |
3 | 3 | ||
4 | 4 | ||
5 | #define GIC_NUM_INTRS (24 + NR_CPUS * 2) | ||
6 | #define NR_IRQS 256 | 5 | #define NR_IRQS 256 |
7 | 6 | ||
8 | #include_next <irq.h> | 7 | #include_next <irq.h> |
diff --git a/arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h b/arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h index fc946c835995..2e54b4bff5cf 100644 --- a/arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h +++ b/arch/mips/include/asm/mach-pmcs-msp71xx/msp_regops.h | |||
@@ -49,6 +49,7 @@ | |||
49 | 49 | ||
50 | #include <linux/types.h> | 50 | #include <linux/types.h> |
51 | 51 | ||
52 | #include <asm/compiler.h> | ||
52 | #include <asm/war.h> | 53 | #include <asm/war.h> |
53 | 54 | ||
54 | #ifndef R10000_LLSC_WAR | 55 | #ifndef R10000_LLSC_WAR |
@@ -84,8 +85,8 @@ static inline void set_value_reg32(volatile u32 *const addr, | |||
84 | " "__beqz"%0, 1b \n" | 85 | " "__beqz"%0, 1b \n" |
85 | " nop \n" | 86 | " nop \n" |
86 | " .set pop \n" | 87 | " .set pop \n" |
87 | : "=&r" (temp), "=m" (*addr) | 88 | : "=&r" (temp), "=" GCC_OFF12_ASM() (*addr) |
88 | : "ir" (~mask), "ir" (value), "m" (*addr)); | 89 | : "ir" (~mask), "ir" (value), GCC_OFF12_ASM() (*addr)); |
89 | } | 90 | } |
90 | 91 | ||
91 | /* | 92 | /* |
@@ -105,8 +106,8 @@ static inline void set_reg32(volatile u32 *const addr, | |||
105 | " "__beqz"%0, 1b \n" | 106 | " "__beqz"%0, 1b \n" |
106 | " nop \n" | 107 | " nop \n" |
107 | " .set pop \n" | 108 | " .set pop \n" |
108 | : "=&r" (temp), "=m" (*addr) | 109 | : "=&r" (temp), "=" GCC_OFF12_ASM() (*addr) |
109 | : "ir" (mask), "m" (*addr)); | 110 | : "ir" (mask), GCC_OFF12_ASM() (*addr)); |
110 | } | 111 | } |
111 | 112 | ||
112 | /* | 113 | /* |
@@ -126,8 +127,8 @@ static inline void clear_reg32(volatile u32 *const addr, | |||
126 | " "__beqz"%0, 1b \n" | 127 | " "__beqz"%0, 1b \n" |
127 | " nop \n" | 128 | " nop \n" |
128 | " .set pop \n" | 129 | " .set pop \n" |
129 | : "=&r" (temp), "=m" (*addr) | 130 | : "=&r" (temp), "=" GCC_OFF12_ASM() (*addr) |
130 | : "ir" (~mask), "m" (*addr)); | 131 | : "ir" (~mask), GCC_OFF12_ASM() (*addr)); |
131 | } | 132 | } |
132 | 133 | ||
133 | /* | 134 | /* |
@@ -147,8 +148,8 @@ static inline void toggle_reg32(volatile u32 *const addr, | |||
147 | " "__beqz"%0, 1b \n" | 148 | " "__beqz"%0, 1b \n" |
148 | " nop \n" | 149 | " nop \n" |
149 | " .set pop \n" | 150 | " .set pop \n" |
150 | : "=&r" (temp), "=m" (*addr) | 151 | : "=&r" (temp), "=" GCC_OFF12_ASM() (*addr) |
151 | : "ir" (mask), "m" (*addr)); | 152 | : "ir" (mask), GCC_OFF12_ASM() (*addr)); |
152 | } | 153 | } |
153 | 154 | ||
154 | /* | 155 | /* |
@@ -219,8 +220,8 @@ static inline u32 blocking_read_reg32(volatile u32 *const addr) | |||
219 | " .set arch=r4000 \n" \ | 220 | " .set arch=r4000 \n" \ |
220 | "1: ll %0, %1 #custom_read_reg32 \n" \ | 221 | "1: ll %0, %1 #custom_read_reg32 \n" \ |
221 | " .set pop \n" \ | 222 | " .set pop \n" \ |
222 | : "=r" (tmp), "=m" (*address) \ | 223 | : "=r" (tmp), "=" GCC_OFF12_ASM() (*address) \ |
223 | : "m" (*address)) | 224 | : GCC_OFF12_ASM() (*address)) |
224 | 225 | ||
225 | #define custom_write_reg32(address, tmp) \ | 226 | #define custom_write_reg32(address, tmp) \ |
226 | __asm__ __volatile__( \ | 227 | __asm__ __volatile__( \ |
@@ -230,7 +231,7 @@ static inline u32 blocking_read_reg32(volatile u32 *const addr) | |||
230 | " "__beqz"%0, 1b \n" \ | 231 | " "__beqz"%0, 1b \n" \ |
231 | " nop \n" \ | 232 | " nop \n" \ |
232 | " .set pop \n" \ | 233 | " .set pop \n" \ |
233 | : "=&r" (tmp), "=m" (*address) \ | 234 | : "=&r" (tmp), "=" GCC_OFF12_ASM() (*address) \ |
234 | : "0" (tmp), "m" (*address)) | 235 | : "0" (tmp), GCC_OFF12_ASM() (*address)) |
235 | 236 | ||
236 | #endif /* __ASM_REGOPS_H__ */ | 237 | #endif /* __ASM_REGOPS_H__ */ |
diff --git a/arch/mips/include/asm/mach-ralink/mt7620.h b/arch/mips/include/asm/mach-ralink/mt7620.h index 6f9b24f51157..1976fb815fd1 100644 --- a/arch/mips/include/asm/mach-ralink/mt7620.h +++ b/arch/mips/include/asm/mach-ralink/mt7620.h | |||
@@ -13,6 +13,13 @@ | |||
13 | #ifndef _MT7620_REGS_H_ | 13 | #ifndef _MT7620_REGS_H_ |
14 | #define _MT7620_REGS_H_ | 14 | #define _MT7620_REGS_H_ |
15 | 15 | ||
16 | enum mt762x_soc_type { | ||
17 | MT762X_SOC_UNKNOWN = 0, | ||
18 | MT762X_SOC_MT7620A, | ||
19 | MT762X_SOC_MT7620N, | ||
20 | MT762X_SOC_MT7628AN, | ||
21 | }; | ||
22 | |||
16 | #define MT7620_SYSC_BASE 0x10000000 | 23 | #define MT7620_SYSC_BASE 0x10000000 |
17 | 24 | ||
18 | #define SYSC_REG_CHIP_NAME0 0x00 | 25 | #define SYSC_REG_CHIP_NAME0 0x00 |
@@ -25,11 +32,9 @@ | |||
25 | #define SYSC_REG_CPLL_CONFIG0 0x54 | 32 | #define SYSC_REG_CPLL_CONFIG0 0x54 |
26 | #define SYSC_REG_CPLL_CONFIG1 0x58 | 33 | #define SYSC_REG_CPLL_CONFIG1 0x58 |
27 | 34 | ||
28 | #define MT7620N_CHIP_NAME0 0x33365452 | 35 | #define MT7620_CHIP_NAME0 0x3637544d |
29 | #define MT7620N_CHIP_NAME1 0x20203235 | 36 | #define MT7620_CHIP_NAME1 0x20203032 |
30 | 37 | #define MT7628_CHIP_NAME1 0x20203832 | |
31 | #define MT7620A_CHIP_NAME0 0x3637544d | ||
32 | #define MT7620A_CHIP_NAME1 0x20203032 | ||
33 | 38 | ||
34 | #define SYSCFG0_XTAL_FREQ_SEL BIT(6) | 39 | #define SYSCFG0_XTAL_FREQ_SEL BIT(6) |
35 | 40 | ||
@@ -74,6 +79,9 @@ | |||
74 | #define SYSCFG0_DRAM_TYPE_DDR1 1 | 79 | #define SYSCFG0_DRAM_TYPE_DDR1 1 |
75 | #define SYSCFG0_DRAM_TYPE_DDR2 2 | 80 | #define SYSCFG0_DRAM_TYPE_DDR2 2 |
76 | 81 | ||
82 | #define SYSCFG0_DRAM_TYPE_DDR2_MT7628 0 | ||
83 | #define SYSCFG0_DRAM_TYPE_DDR1_MT7628 1 | ||
84 | |||
77 | #define MT7620_DRAM_BASE 0x0 | 85 | #define MT7620_DRAM_BASE 0x0 |
78 | #define MT7620_SDRAM_SIZE_MIN 2 | 86 | #define MT7620_SDRAM_SIZE_MIN 2 |
79 | #define MT7620_SDRAM_SIZE_MAX 64 | 87 | #define MT7620_SDRAM_SIZE_MAX 64 |
@@ -82,7 +90,6 @@ | |||
82 | #define MT7620_DDR2_SIZE_MIN 32 | 90 | #define MT7620_DDR2_SIZE_MIN 32 |
83 | #define MT7620_DDR2_SIZE_MAX 256 | 91 | #define MT7620_DDR2_SIZE_MAX 256 |
84 | 92 | ||
85 | #define MT7620_GPIO_MODE_I2C BIT(0) | ||
86 | #define MT7620_GPIO_MODE_UART0_SHIFT 2 | 93 | #define MT7620_GPIO_MODE_UART0_SHIFT 2 |
87 | #define MT7620_GPIO_MODE_UART0_MASK 0x7 | 94 | #define MT7620_GPIO_MODE_UART0_MASK 0x7 |
88 | #define MT7620_GPIO_MODE_UART0(x) ((x) << MT7620_GPIO_MODE_UART0_SHIFT) | 95 | #define MT7620_GPIO_MODE_UART0(x) ((x) << MT7620_GPIO_MODE_UART0_SHIFT) |
@@ -94,15 +101,40 @@ | |||
94 | #define MT7620_GPIO_MODE_GPIO_UARTF 0x5 | 101 | #define MT7620_GPIO_MODE_GPIO_UARTF 0x5 |
95 | #define MT7620_GPIO_MODE_GPIO_I2S 0x6 | 102 | #define MT7620_GPIO_MODE_GPIO_I2S 0x6 |
96 | #define MT7620_GPIO_MODE_GPIO 0x7 | 103 | #define MT7620_GPIO_MODE_GPIO 0x7 |
97 | #define MT7620_GPIO_MODE_UART1 BIT(5) | 104 | |
98 | #define MT7620_GPIO_MODE_MDIO BIT(8) | 105 | #define MT7620_GPIO_MODE_NAND 0 |
99 | #define MT7620_GPIO_MODE_RGMII1 BIT(9) | 106 | #define MT7620_GPIO_MODE_SD 1 |
100 | #define MT7620_GPIO_MODE_RGMII2 BIT(10) | 107 | #define MT7620_GPIO_MODE_ND_SD_GPIO 2 |
101 | #define MT7620_GPIO_MODE_SPI BIT(11) | 108 | #define MT7620_GPIO_MODE_ND_SD_MASK 0x3 |
102 | #define MT7620_GPIO_MODE_SPI_REF_CLK BIT(12) | 109 | #define MT7620_GPIO_MODE_ND_SD_SHIFT 18 |
103 | #define MT7620_GPIO_MODE_WLED BIT(13) | 110 | |
104 | #define MT7620_GPIO_MODE_JTAG BIT(15) | 111 | #define MT7620_GPIO_MODE_PCIE_RST 0 |
105 | #define MT7620_GPIO_MODE_EPHY BIT(15) | 112 | #define MT7620_GPIO_MODE_PCIE_REF 1 |
106 | #define MT7620_GPIO_MODE_WDT BIT(22) | 113 | #define MT7620_GPIO_MODE_PCIE_GPIO 2 |
114 | #define MT7620_GPIO_MODE_PCIE_MASK 0x3 | ||
115 | #define MT7620_GPIO_MODE_PCIE_SHIFT 16 | ||
116 | |||
117 | #define MT7620_GPIO_MODE_WDT_RST 0 | ||
118 | #define MT7620_GPIO_MODE_WDT_REF 1 | ||
119 | #define MT7620_GPIO_MODE_WDT_GPIO 2 | ||
120 | #define MT7620_GPIO_MODE_WDT_MASK 0x3 | ||
121 | #define MT7620_GPIO_MODE_WDT_SHIFT 21 | ||
122 | |||
123 | #define MT7620_GPIO_MODE_I2C 0 | ||
124 | #define MT7620_GPIO_MODE_UART1 5 | ||
125 | #define MT7620_GPIO_MODE_MDIO 8 | ||
126 | #define MT7620_GPIO_MODE_RGMII1 9 | ||
127 | #define MT7620_GPIO_MODE_RGMII2 10 | ||
128 | #define MT7620_GPIO_MODE_SPI 11 | ||
129 | #define MT7620_GPIO_MODE_SPI_REF_CLK 12 | ||
130 | #define MT7620_GPIO_MODE_WLED 13 | ||
131 | #define MT7620_GPIO_MODE_JTAG 15 | ||
132 | #define MT7620_GPIO_MODE_EPHY 15 | ||
133 | #define MT7620_GPIO_MODE_PA 20 | ||
134 | |||
135 | static inline int mt7620_get_eco(void) | ||
136 | { | ||
137 | return rt_sysc_r32(SYSC_REG_CHIP_REV) & CHIP_REV_ECO_MASK; | ||
138 | } | ||
107 | 139 | ||
108 | #endif | 140 | #endif |
diff --git a/arch/mips/include/asm/mach-ralink/pinmux.h b/arch/mips/include/asm/mach-ralink/pinmux.h new file mode 100644 index 000000000000..be106cb2e26d --- /dev/null +++ b/arch/mips/include/asm/mach-ralink/pinmux.h | |||
@@ -0,0 +1,55 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License version 2 as | ||
4 | * publishhed by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2012 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #ifndef _RT288X_PINMUX_H__ | ||
10 | #define _RT288X_PINMUX_H__ | ||
11 | |||
12 | #define FUNC(name, value, pin_first, pin_count) \ | ||
13 | { name, value, pin_first, pin_count } | ||
14 | |||
15 | #define GRP(_name, _func, _mask, _shift) \ | ||
16 | { .name = _name, .mask = _mask, .shift = _shift, \ | ||
17 | .func = _func, .gpio = _mask, \ | ||
18 | .func_count = ARRAY_SIZE(_func) } | ||
19 | |||
20 | #define GRP_G(_name, _func, _mask, _gpio, _shift) \ | ||
21 | { .name = _name, .mask = _mask, .shift = _shift, \ | ||
22 | .func = _func, .gpio = _gpio, \ | ||
23 | .func_count = ARRAY_SIZE(_func) } | ||
24 | |||
25 | struct rt2880_pmx_group; | ||
26 | |||
27 | struct rt2880_pmx_func { | ||
28 | const char *name; | ||
29 | const char value; | ||
30 | |||
31 | int pin_first; | ||
32 | int pin_count; | ||
33 | int *pins; | ||
34 | |||
35 | int *groups; | ||
36 | int group_count; | ||
37 | |||
38 | int enabled; | ||
39 | }; | ||
40 | |||
41 | struct rt2880_pmx_group { | ||
42 | const char *name; | ||
43 | int enabled; | ||
44 | |||
45 | const u32 shift; | ||
46 | const char mask; | ||
47 | const char gpio; | ||
48 | |||
49 | struct rt2880_pmx_func *func; | ||
50 | int func_count; | ||
51 | }; | ||
52 | |||
53 | extern struct rt2880_pmx_group *rt2880_pinmux_data; | ||
54 | |||
55 | #endif | ||
diff --git a/arch/mips/include/asm/mach-ralink/ralink_regs.h b/arch/mips/include/asm/mach-ralink/ralink_regs.h index 5a508f9f9432..bd93014490df 100644 --- a/arch/mips/include/asm/mach-ralink/ralink_regs.h +++ b/arch/mips/include/asm/mach-ralink/ralink_regs.h | |||
@@ -26,6 +26,13 @@ static inline u32 rt_sysc_r32(unsigned reg) | |||
26 | return __raw_readl(rt_sysc_membase + reg); | 26 | return __raw_readl(rt_sysc_membase + reg); |
27 | } | 27 | } |
28 | 28 | ||
29 | static inline void rt_sysc_m32(u32 clr, u32 set, unsigned reg) | ||
30 | { | ||
31 | u32 val = rt_sysc_r32(reg) & ~clr; | ||
32 | |||
33 | __raw_writel(val | set, rt_sysc_membase + reg); | ||
34 | } | ||
35 | |||
29 | static inline void rt_memc_w32(u32 val, unsigned reg) | 36 | static inline void rt_memc_w32(u32 val, unsigned reg) |
30 | { | 37 | { |
31 | __raw_writel(val, rt_memc_membase + reg); | 38 | __raw_writel(val, rt_memc_membase + reg); |
diff --git a/arch/mips/include/asm/mach-ralink/rt305x.h b/arch/mips/include/asm/mach-ralink/rt305x.h index 069bf37a6010..96f731bac79a 100644 --- a/arch/mips/include/asm/mach-ralink/rt305x.h +++ b/arch/mips/include/asm/mach-ralink/rt305x.h | |||
@@ -125,24 +125,29 @@ static inline int soc_is_rt5350(void) | |||
125 | #define RT305X_GPIO_GE0_TXD0 40 | 125 | #define RT305X_GPIO_GE0_TXD0 40 |
126 | #define RT305X_GPIO_GE0_RXCLK 51 | 126 | #define RT305X_GPIO_GE0_RXCLK 51 |
127 | 127 | ||
128 | #define RT305X_GPIO_MODE_I2C BIT(0) | ||
129 | #define RT305X_GPIO_MODE_SPI BIT(1) | ||
130 | #define RT305X_GPIO_MODE_UART0_SHIFT 2 | 128 | #define RT305X_GPIO_MODE_UART0_SHIFT 2 |
131 | #define RT305X_GPIO_MODE_UART0_MASK 0x7 | 129 | #define RT305X_GPIO_MODE_UART0_MASK 0x7 |
132 | #define RT305X_GPIO_MODE_UART0(x) ((x) << RT305X_GPIO_MODE_UART0_SHIFT) | 130 | #define RT305X_GPIO_MODE_UART0(x) ((x) << RT305X_GPIO_MODE_UART0_SHIFT) |
133 | #define RT305X_GPIO_MODE_UARTF 0x0 | 131 | #define RT305X_GPIO_MODE_UARTF 0 |
134 | #define RT305X_GPIO_MODE_PCM_UARTF 0x1 | 132 | #define RT305X_GPIO_MODE_PCM_UARTF 1 |
135 | #define RT305X_GPIO_MODE_PCM_I2S 0x2 | 133 | #define RT305X_GPIO_MODE_PCM_I2S 2 |
136 | #define RT305X_GPIO_MODE_I2S_UARTF 0x3 | 134 | #define RT305X_GPIO_MODE_I2S_UARTF 3 |
137 | #define RT305X_GPIO_MODE_PCM_GPIO 0x4 | 135 | #define RT305X_GPIO_MODE_PCM_GPIO 4 |
138 | #define RT305X_GPIO_MODE_GPIO_UARTF 0x5 | 136 | #define RT305X_GPIO_MODE_GPIO_UARTF 5 |
139 | #define RT305X_GPIO_MODE_GPIO_I2S 0x6 | 137 | #define RT305X_GPIO_MODE_GPIO_I2S 6 |
140 | #define RT305X_GPIO_MODE_GPIO 0x7 | 138 | #define RT305X_GPIO_MODE_GPIO 7 |
141 | #define RT305X_GPIO_MODE_UART1 BIT(5) | 139 | |
142 | #define RT305X_GPIO_MODE_JTAG BIT(6) | 140 | #define RT305X_GPIO_MODE_I2C 0 |
143 | #define RT305X_GPIO_MODE_MDIO BIT(7) | 141 | #define RT305X_GPIO_MODE_SPI 1 |
144 | #define RT305X_GPIO_MODE_SDRAM BIT(8) | 142 | #define RT305X_GPIO_MODE_UART1 5 |
145 | #define RT305X_GPIO_MODE_RGMII BIT(9) | 143 | #define RT305X_GPIO_MODE_JTAG 6 |
144 | #define RT305X_GPIO_MODE_MDIO 7 | ||
145 | #define RT305X_GPIO_MODE_SDRAM 8 | ||
146 | #define RT305X_GPIO_MODE_RGMII 9 | ||
147 | #define RT5350_GPIO_MODE_PHY_LED 14 | ||
148 | #define RT5350_GPIO_MODE_SPI_CS1 21 | ||
149 | #define RT3352_GPIO_MODE_LNA 18 | ||
150 | #define RT3352_GPIO_MODE_PA 20 | ||
146 | 151 | ||
147 | #define RT3352_SYSC_REG_SYSCFG0 0x010 | 152 | #define RT3352_SYSC_REG_SYSCFG0 0x010 |
148 | #define RT3352_SYSC_REG_SYSCFG1 0x014 | 153 | #define RT3352_SYSC_REG_SYSCFG1 0x014 |
diff --git a/arch/mips/include/asm/mach-ralink/rt3883.h b/arch/mips/include/asm/mach-ralink/rt3883.h index 058382f37f92..0fbe6f9257cd 100644 --- a/arch/mips/include/asm/mach-ralink/rt3883.h +++ b/arch/mips/include/asm/mach-ralink/rt3883.h | |||
@@ -112,8 +112,6 @@ | |||
112 | #define RT3883_CLKCFG1_PCI_CLK_EN BIT(19) | 112 | #define RT3883_CLKCFG1_PCI_CLK_EN BIT(19) |
113 | #define RT3883_CLKCFG1_UPHY0_CLK_EN BIT(18) | 113 | #define RT3883_CLKCFG1_UPHY0_CLK_EN BIT(18) |
114 | 114 | ||
115 | #define RT3883_GPIO_MODE_I2C BIT(0) | ||
116 | #define RT3883_GPIO_MODE_SPI BIT(1) | ||
117 | #define RT3883_GPIO_MODE_UART0_SHIFT 2 | 115 | #define RT3883_GPIO_MODE_UART0_SHIFT 2 |
118 | #define RT3883_GPIO_MODE_UART0_MASK 0x7 | 116 | #define RT3883_GPIO_MODE_UART0_MASK 0x7 |
119 | #define RT3883_GPIO_MODE_UART0(x) ((x) << RT3883_GPIO_MODE_UART0_SHIFT) | 117 | #define RT3883_GPIO_MODE_UART0(x) ((x) << RT3883_GPIO_MODE_UART0_SHIFT) |
@@ -125,11 +123,15 @@ | |||
125 | #define RT3883_GPIO_MODE_GPIO_UARTF 0x5 | 123 | #define RT3883_GPIO_MODE_GPIO_UARTF 0x5 |
126 | #define RT3883_GPIO_MODE_GPIO_I2S 0x6 | 124 | #define RT3883_GPIO_MODE_GPIO_I2S 0x6 |
127 | #define RT3883_GPIO_MODE_GPIO 0x7 | 125 | #define RT3883_GPIO_MODE_GPIO 0x7 |
128 | #define RT3883_GPIO_MODE_UART1 BIT(5) | 126 | |
129 | #define RT3883_GPIO_MODE_JTAG BIT(6) | 127 | #define RT3883_GPIO_MODE_I2C 0 |
130 | #define RT3883_GPIO_MODE_MDIO BIT(7) | 128 | #define RT3883_GPIO_MODE_SPI 1 |
131 | #define RT3883_GPIO_MODE_GE1 BIT(9) | 129 | #define RT3883_GPIO_MODE_UART1 5 |
132 | #define RT3883_GPIO_MODE_GE2 BIT(10) | 130 | #define RT3883_GPIO_MODE_JTAG 6 |
131 | #define RT3883_GPIO_MODE_MDIO 7 | ||
132 | #define RT3883_GPIO_MODE_GE1 9 | ||
133 | #define RT3883_GPIO_MODE_GE2 10 | ||
134 | |||
133 | #define RT3883_GPIO_MODE_PCI_SHIFT 11 | 135 | #define RT3883_GPIO_MODE_PCI_SHIFT 11 |
134 | #define RT3883_GPIO_MODE_PCI_MASK 0x7 | 136 | #define RT3883_GPIO_MODE_PCI_MASK 0x7 |
135 | #define RT3883_GPIO_MODE_PCI (RT3883_GPIO_MODE_PCI_MASK << RT3883_GPIO_MODE_PCI_SHIFT) | 137 | #define RT3883_GPIO_MODE_PCI (RT3883_GPIO_MODE_PCI_MASK << RT3883_GPIO_MODE_PCI_SHIFT) |
diff --git a/arch/mips/include/asm/mach-sead3/irq.h b/arch/mips/include/asm/mach-sead3/irq.h index d8106f75b9af..5d154cfbcf4c 100644 --- a/arch/mips/include/asm/mach-sead3/irq.h +++ b/arch/mips/include/asm/mach-sead3/irq.h | |||
@@ -1,7 +1,6 @@ | |||
1 | #ifndef __ASM_MACH_MIPS_IRQ_H | 1 | #ifndef __ASM_MACH_MIPS_IRQ_H |
2 | #define __ASM_MACH_MIPS_IRQ_H | 2 | #define __ASM_MACH_MIPS_IRQ_H |
3 | 3 | ||
4 | #define GIC_NUM_INTRS (24 + NR_CPUS * 2) | ||
5 | #define NR_IRQS 256 | 4 | #define NR_IRQS 256 |
6 | 5 | ||
7 | 6 | ||
diff --git a/arch/mips/include/asm/mach-tx39xx/ioremap.h b/arch/mips/include/asm/mach-tx39xx/ioremap.h index 93c6c04ffda3..0874cd2b06d7 100644 --- a/arch/mips/include/asm/mach-tx39xx/ioremap.h +++ b/arch/mips/include/asm/mach-tx39xx/ioremap.h | |||
@@ -15,12 +15,12 @@ | |||
15 | * Allow physical addresses to be fixed up to help peripherals located | 15 | * Allow physical addresses to be fixed up to help peripherals located |
16 | * outside the low 32-bit range -- generic pass-through version. | 16 | * outside the low 32-bit range -- generic pass-through version. |
17 | */ | 17 | */ |
18 | static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) | 18 | static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) |
19 | { | 19 | { |
20 | return phys_addr; | 20 | return phys_addr; |
21 | } | 21 | } |
22 | 22 | ||
23 | static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, | 23 | static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, |
24 | unsigned long flags) | 24 | unsigned long flags) |
25 | { | 25 | { |
26 | #define TXX9_DIRECTMAP_BASE 0xff000000ul | 26 | #define TXX9_DIRECTMAP_BASE 0xff000000ul |
diff --git a/arch/mips/include/asm/mach-tx49xx/ioremap.h b/arch/mips/include/asm/mach-tx49xx/ioremap.h index 1e7beae72229..4b6a8441b25f 100644 --- a/arch/mips/include/asm/mach-tx49xx/ioremap.h +++ b/arch/mips/include/asm/mach-tx49xx/ioremap.h | |||
@@ -15,12 +15,12 @@ | |||
15 | * Allow physical addresses to be fixed up to help peripherals located | 15 | * Allow physical addresses to be fixed up to help peripherals located |
16 | * outside the low 32-bit range -- generic pass-through version. | 16 | * outside the low 32-bit range -- generic pass-through version. |
17 | */ | 17 | */ |
18 | static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size) | 18 | static inline phys_addr_t fixup_bigphys_addr(phys_addr_t phys_addr, phys_addr_t size) |
19 | { | 19 | { |
20 | return phys_addr; | 20 | return phys_addr; |
21 | } | 21 | } |
22 | 22 | ||
23 | static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size, | 23 | static inline void __iomem *plat_ioremap(phys_addr_t offset, unsigned long size, |
24 | unsigned long flags) | 24 | unsigned long flags) |
25 | { | 25 | { |
26 | #ifdef CONFIG_64BIT | 26 | #ifdef CONFIG_64BIT |
diff --git a/arch/mips/include/asm/mips-boards/maltaint.h b/arch/mips/include/asm/mips-boards/maltaint.h index e330732ddf98..987ff580466b 100644 --- a/arch/mips/include/asm/mips-boards/maltaint.h +++ b/arch/mips/include/asm/mips-boards/maltaint.h | |||
@@ -10,7 +10,7 @@ | |||
10 | #ifndef _MIPS_MALTAINT_H | 10 | #ifndef _MIPS_MALTAINT_H |
11 | #define _MIPS_MALTAINT_H | 11 | #define _MIPS_MALTAINT_H |
12 | 12 | ||
13 | #define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8) | 13 | #include <linux/irqchip/mips-gic.h> |
14 | 14 | ||
15 | /* | 15 | /* |
16 | * Interrupts 0..15 are used for Malta ISA compatible interrupts | 16 | * Interrupts 0..15 are used for Malta ISA compatible interrupts |
@@ -22,29 +22,28 @@ | |||
22 | #define MIPSCPU_INT_SW1 1 | 22 | #define MIPSCPU_INT_SW1 1 |
23 | #define MIPSCPU_INT_MB0 2 | 23 | #define MIPSCPU_INT_MB0 2 |
24 | #define MIPSCPU_INT_I8259A MIPSCPU_INT_MB0 | 24 | #define MIPSCPU_INT_I8259A MIPSCPU_INT_MB0 |
25 | #define MIPSCPU_INT_GIC MIPSCPU_INT_MB0 /* GIC chained interrupt */ | ||
25 | #define MIPSCPU_INT_MB1 3 | 26 | #define MIPSCPU_INT_MB1 3 |
26 | #define MIPSCPU_INT_SMI MIPSCPU_INT_MB1 | 27 | #define MIPSCPU_INT_SMI MIPSCPU_INT_MB1 |
27 | #define MIPSCPU_INT_IPI0 MIPSCPU_INT_MB1 /* GIC IPI */ | ||
28 | #define MIPSCPU_INT_MB2 4 | 28 | #define MIPSCPU_INT_MB2 4 |
29 | #define MIPSCPU_INT_IPI1 MIPSCPU_INT_MB2 /* GIC IPI */ | ||
30 | #define MIPSCPU_INT_MB3 5 | 29 | #define MIPSCPU_INT_MB3 5 |
31 | #define MIPSCPU_INT_COREHI MIPSCPU_INT_MB3 | 30 | #define MIPSCPU_INT_COREHI MIPSCPU_INT_MB3 |
32 | #define MIPSCPU_INT_MB4 6 | 31 | #define MIPSCPU_INT_MB4 6 |
33 | #define MIPSCPU_INT_CORELO MIPSCPU_INT_MB4 | 32 | #define MIPSCPU_INT_CORELO MIPSCPU_INT_MB4 |
34 | 33 | ||
35 | /* | 34 | /* |
36 | * Interrupts 64..127 are used for Soc-it Classic interrupts | 35 | * Interrupts 96..127 are used for Soc-it Classic interrupts |
37 | */ | 36 | */ |
38 | #define MSC01C_INT_BASE 64 | 37 | #define MSC01C_INT_BASE 96 |
39 | 38 | ||
40 | /* SOC-it Classic interrupt offsets */ | 39 | /* SOC-it Classic interrupt offsets */ |
41 | #define MSC01C_INT_TMR 0 | 40 | #define MSC01C_INT_TMR 0 |
42 | #define MSC01C_INT_PCI 1 | 41 | #define MSC01C_INT_PCI 1 |
43 | 42 | ||
44 | /* | 43 | /* |
45 | * Interrupts 64..127 are used for Soc-it EIC interrupts | 44 | * Interrupts 96..127 are used for Soc-it EIC interrupts |
46 | */ | 45 | */ |
47 | #define MSC01E_INT_BASE 64 | 46 | #define MSC01E_INT_BASE 96 |
48 | 47 | ||
49 | /* SOC-it EIC interrupt offsets */ | 48 | /* SOC-it EIC interrupt offsets */ |
50 | #define MSC01E_INT_SW0 1 | 49 | #define MSC01E_INT_SW0 1 |
@@ -63,14 +62,7 @@ | |||
63 | #define MSC01E_INT_PERFCTR 10 | 62 | #define MSC01E_INT_PERFCTR 10 |
64 | #define MSC01E_INT_CPUCTR 11 | 63 | #define MSC01E_INT_CPUCTR 11 |
65 | 64 | ||
66 | /* External Interrupts used for IPI */ | 65 | /* GIC external interrupts */ |
67 | #define GIC_IPI_EXT_INTR_RESCHED_VPE0 16 | 66 | #define GIC_INT_I8259A GIC_SHARED_TO_HWIRQ(3) |
68 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE0 17 | ||
69 | #define GIC_IPI_EXT_INTR_RESCHED_VPE1 18 | ||
70 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE1 19 | ||
71 | #define GIC_IPI_EXT_INTR_RESCHED_VPE2 20 | ||
72 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE2 21 | ||
73 | #define GIC_IPI_EXT_INTR_RESCHED_VPE3 22 | ||
74 | #define GIC_IPI_EXT_INTR_CALLFNC_VPE3 23 | ||
75 | 67 | ||
76 | #endif /* !(_MIPS_MALTAINT_H) */ | 68 | #endif /* !(_MIPS_MALTAINT_H) */ |
diff --git a/arch/mips/include/asm/mips-boards/sead3int.h b/arch/mips/include/asm/mips-boards/sead3int.h index 6b17aaf7d901..8932c7de0419 100644 --- a/arch/mips/include/asm/mips-boards/sead3int.h +++ b/arch/mips/include/asm/mips-boards/sead3int.h | |||
@@ -10,10 +10,23 @@ | |||
10 | #ifndef _MIPS_SEAD3INT_H | 10 | #ifndef _MIPS_SEAD3INT_H |
11 | #define _MIPS_SEAD3INT_H | 11 | #define _MIPS_SEAD3INT_H |
12 | 12 | ||
13 | #include <linux/irqchip/mips-gic.h> | ||
14 | |||
13 | /* SEAD-3 GIC address space definitions. */ | 15 | /* SEAD-3 GIC address space definitions. */ |
14 | #define GIC_BASE_ADDR 0x1b1c0000 | 16 | #define GIC_BASE_ADDR 0x1b1c0000 |
15 | #define GIC_ADDRSPACE_SZ (128 * 1024) | 17 | #define GIC_ADDRSPACE_SZ (128 * 1024) |
16 | 18 | ||
17 | #define MIPS_GIC_IRQ_BASE (MIPS_CPU_IRQ_BASE + 0) | 19 | /* CPU interrupt offsets */ |
20 | #define CPU_INT_GIC 2 | ||
21 | #define CPU_INT_EHCI 2 | ||
22 | #define CPU_INT_UART0 4 | ||
23 | #define CPU_INT_UART1 4 | ||
24 | #define CPU_INT_NET 6 | ||
25 | |||
26 | /* GIC interrupt offsets */ | ||
27 | #define GIC_INT_NET GIC_SHARED_TO_HWIRQ(0) | ||
28 | #define GIC_INT_UART1 GIC_SHARED_TO_HWIRQ(2) | ||
29 | #define GIC_INT_UART0 GIC_SHARED_TO_HWIRQ(3) | ||
30 | #define GIC_INT_EHCI GIC_SHARED_TO_HWIRQ(5) | ||
18 | 31 | ||
19 | #endif /* !(_MIPS_SEAD3INT_H) */ | 32 | #endif /* !(_MIPS_SEAD3INT_H) */ |
diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h index 6a9d2dd005ca..b95a827d763e 100644 --- a/arch/mips/include/asm/mips-cm.h +++ b/arch/mips/include/asm/mips-cm.h | |||
@@ -30,7 +30,7 @@ extern void __iomem *mips_cm_l2sync_base; | |||
30 | * different way by defining a function with the same prototype except for the | 30 | * different way by defining a function with the same prototype except for the |
31 | * name mips_cm_phys_base (without underscores). | 31 | * name mips_cm_phys_base (without underscores). |
32 | */ | 32 | */ |
33 | extern phys_t __mips_cm_phys_base(void); | 33 | extern phys_addr_t __mips_cm_phys_base(void); |
34 | 34 | ||
35 | /** | 35 | /** |
36 | * mips_cm_probe - probe for a Coherence Manager | 36 | * mips_cm_probe - probe for a Coherence Manager |
diff --git a/arch/mips/include/asm/mips-cpc.h b/arch/mips/include/asm/mips-cpc.h index e139a534e0fd..1cebe8c79051 100644 --- a/arch/mips/include/asm/mips-cpc.h +++ b/arch/mips/include/asm/mips-cpc.h | |||
@@ -25,7 +25,7 @@ extern void __iomem *mips_cpc_base; | |||
25 | * memory mapped registers. This is platform dependant & must therefore be | 25 | * memory mapped registers. This is platform dependant & must therefore be |
26 | * implemented per-platform. | 26 | * implemented per-platform. |
27 | */ | 27 | */ |
28 | extern phys_t mips_cpc_default_phys_base(void); | 28 | extern phys_addr_t mips_cpc_default_phys_base(void); |
29 | 29 | ||
30 | /** | 30 | /** |
31 | * mips_cpc_phys_base - retrieve the physical base address of the CPC | 31 | * mips_cpc_phys_base - retrieve the physical base address of the CPC |
@@ -35,7 +35,7 @@ extern phys_t mips_cpc_default_phys_base(void); | |||
35 | * is present. It may be overriden by individual platforms which determine | 35 | * is present. It may be overriden by individual platforms which determine |
36 | * this address in a different way. | 36 | * this address in a different way. |
37 | */ | 37 | */ |
38 | extern phys_t __weak mips_cpc_phys_base(void); | 38 | extern phys_addr_t __weak mips_cpc_phys_base(void); |
39 | 39 | ||
40 | /** | 40 | /** |
41 | * mips_cpc_probe - probe for a Cluster Power Controller | 41 | * mips_cpc_probe - probe for a Cluster Power Controller |
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 22a135ac91de..5e4aef304b02 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h | |||
@@ -653,6 +653,9 @@ | |||
653 | #define MIPS_CONF5_NF (_ULCAST_(1) << 0) | 653 | #define MIPS_CONF5_NF (_ULCAST_(1) << 0) |
654 | #define MIPS_CONF5_UFR (_ULCAST_(1) << 2) | 654 | #define MIPS_CONF5_UFR (_ULCAST_(1) << 2) |
655 | #define MIPS_CONF5_MRP (_ULCAST_(1) << 3) | 655 | #define MIPS_CONF5_MRP (_ULCAST_(1) << 3) |
656 | #define MIPS_CONF5_MVH (_ULCAST_(1) << 5) | ||
657 | #define MIPS_CONF5_FRE (_ULCAST_(1) << 8) | ||
658 | #define MIPS_CONF5_UFE (_ULCAST_(1) << 9) | ||
656 | #define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27) | 659 | #define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27) |
657 | #define MIPS_CONF5_EVA (_ULCAST_(1) << 28) | 660 | #define MIPS_CONF5_EVA (_ULCAST_(1) << 28) |
658 | #define MIPS_CONF5_CV (_ULCAST_(1) << 29) | 661 | #define MIPS_CONF5_CV (_ULCAST_(1) << 29) |
@@ -694,6 +697,7 @@ | |||
694 | #define MIPS_FPIR_W (_ULCAST_(1) << 20) | 697 | #define MIPS_FPIR_W (_ULCAST_(1) << 20) |
695 | #define MIPS_FPIR_L (_ULCAST_(1) << 21) | 698 | #define MIPS_FPIR_L (_ULCAST_(1) << 21) |
696 | #define MIPS_FPIR_F64 (_ULCAST_(1) << 22) | 699 | #define MIPS_FPIR_F64 (_ULCAST_(1) << 22) |
700 | #define MIPS_FPIR_FREP (_ULCAST_(1) << 29) | ||
697 | 701 | ||
698 | /* | 702 | /* |
699 | * Bits in the MIPS32 Memory Segmentation registers. | 703 | * Bits in the MIPS32 Memory Segmentation registers. |
@@ -994,6 +998,39 @@ do { \ | |||
994 | local_irq_restore(__flags); \ | 998 | local_irq_restore(__flags); \ |
995 | } while (0) | 999 | } while (0) |
996 | 1000 | ||
1001 | #define __readx_32bit_c0_register(source) \ | ||
1002 | ({ \ | ||
1003 | unsigned int __res; \ | ||
1004 | \ | ||
1005 | __asm__ __volatile__( \ | ||
1006 | " .set push \n" \ | ||
1007 | " .set noat \n" \ | ||
1008 | " .set mips32r2 \n" \ | ||
1009 | " .insn \n" \ | ||
1010 | " # mfhc0 $1, %1 \n" \ | ||
1011 | " .word (0x40410000 | ((%1 & 0x1f) << 11)) \n" \ | ||
1012 | " move %0, $1 \n" \ | ||
1013 | " .set pop \n" \ | ||
1014 | : "=r" (__res) \ | ||
1015 | : "i" (source)); \ | ||
1016 | __res; \ | ||
1017 | }) | ||
1018 | |||
1019 | #define __writex_32bit_c0_register(register, value) \ | ||
1020 | do { \ | ||
1021 | __asm__ __volatile__( \ | ||
1022 | " .set push \n" \ | ||
1023 | " .set noat \n" \ | ||
1024 | " .set mips32r2 \n" \ | ||
1025 | " move $1, %0 \n" \ | ||
1026 | " # mthc0 $1, %1 \n" \ | ||
1027 | " .insn \n" \ | ||
1028 | " .word (0x40c10000 | ((%1 & 0x1f) << 11)) \n" \ | ||
1029 | " .set pop \n" \ | ||
1030 | : \ | ||
1031 | : "r" (value), "i" (register)); \ | ||
1032 | } while (0) | ||
1033 | |||
997 | #define read_c0_index() __read_32bit_c0_register($0, 0) | 1034 | #define read_c0_index() __read_32bit_c0_register($0, 0) |
998 | #define write_c0_index(val) __write_32bit_c0_register($0, 0, val) | 1035 | #define write_c0_index(val) __write_32bit_c0_register($0, 0, val) |
999 | 1036 | ||
@@ -1003,9 +1040,15 @@ do { \ | |||
1003 | #define read_c0_entrylo0() __read_ulong_c0_register($2, 0) | 1040 | #define read_c0_entrylo0() __read_ulong_c0_register($2, 0) |
1004 | #define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val) | 1041 | #define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val) |
1005 | 1042 | ||
1043 | #define readx_c0_entrylo0() __readx_32bit_c0_register(2) | ||
1044 | #define writex_c0_entrylo0(val) __writex_32bit_c0_register(2, val) | ||
1045 | |||
1006 | #define read_c0_entrylo1() __read_ulong_c0_register($3, 0) | 1046 | #define read_c0_entrylo1() __read_ulong_c0_register($3, 0) |
1007 | #define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val) | 1047 | #define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val) |
1008 | 1048 | ||
1049 | #define readx_c0_entrylo1() __readx_32bit_c0_register(3) | ||
1050 | #define writex_c0_entrylo1(val) __writex_32bit_c0_register(3, val) | ||
1051 | |||
1009 | #define read_c0_conf() __read_32bit_c0_register($3, 0) | 1052 | #define read_c0_conf() __read_32bit_c0_register($3, 0) |
1010 | #define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) | 1053 | #define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) |
1011 | 1054 | ||
diff --git a/arch/mips/include/asm/octeon/cvmx-cmd-queue.h b/arch/mips/include/asm/octeon/cvmx-cmd-queue.h index 024a71b2bff9..75739c83f07e 100644 --- a/arch/mips/include/asm/octeon/cvmx-cmd-queue.h +++ b/arch/mips/include/asm/octeon/cvmx-cmd-queue.h | |||
@@ -76,6 +76,8 @@ | |||
76 | 76 | ||
77 | #include <linux/prefetch.h> | 77 | #include <linux/prefetch.h> |
78 | 78 | ||
79 | #include <asm/compiler.h> | ||
80 | |||
79 | #include <asm/octeon/cvmx-fpa.h> | 81 | #include <asm/octeon/cvmx-fpa.h> |
80 | /** | 82 | /** |
81 | * By default we disable the max depth support. Most programs | 83 | * By default we disable the max depth support. Most programs |
@@ -273,7 +275,7 @@ static inline void __cvmx_cmd_queue_lock(cvmx_cmd_queue_id_t queue_id, | |||
273 | " lbu %[ticket], %[now_serving]\n" | 275 | " lbu %[ticket], %[now_serving]\n" |
274 | "4:\n" | 276 | "4:\n" |
275 | ".set pop\n" : | 277 | ".set pop\n" : |
276 | [ticket_ptr] "=m"(__cvmx_cmd_queue_state_ptr->ticket[__cvmx_cmd_queue_get_index(queue_id)]), | 278 | [ticket_ptr] "=" GCC_OFF12_ASM()(__cvmx_cmd_queue_state_ptr->ticket[__cvmx_cmd_queue_get_index(queue_id)]), |
277 | [now_serving] "=m"(qptr->now_serving), [ticket] "=r"(tmp), | 279 | [now_serving] "=m"(qptr->now_serving), [ticket] "=r"(tmp), |
278 | [my_ticket] "=r"(my_ticket) | 280 | [my_ticket] "=r"(my_ticket) |
279 | ); | 281 | ); |
diff --git a/arch/mips/include/asm/octeon/cvmx-pow.h b/arch/mips/include/asm/octeon/cvmx-pow.h index 4b4d0ecfd9eb..2188e65afb86 100644 --- a/arch/mips/include/asm/octeon/cvmx-pow.h +++ b/arch/mips/include/asm/octeon/cvmx-pow.h | |||
@@ -1066,7 +1066,7 @@ static inline void __cvmx_pow_warn_if_pending_switch(const char *function) | |||
1066 | uint64_t switch_complete; | 1066 | uint64_t switch_complete; |
1067 | CVMX_MF_CHORD(switch_complete); | 1067 | CVMX_MF_CHORD(switch_complete); |
1068 | if (!switch_complete) | 1068 | if (!switch_complete) |
1069 | pr_warning("%s called with tag switch in progress\n", function); | 1069 | pr_warn("%s called with tag switch in progress\n", function); |
1070 | } | 1070 | } |
1071 | 1071 | ||
1072 | /** | 1072 | /** |
@@ -1084,8 +1084,7 @@ static inline void cvmx_pow_tag_sw_wait(void) | |||
1084 | if (unlikely(switch_complete)) | 1084 | if (unlikely(switch_complete)) |
1085 | break; | 1085 | break; |
1086 | if (unlikely(cvmx_get_cycle() > start_cycle + MAX_CYCLES)) { | 1086 | if (unlikely(cvmx_get_cycle() > start_cycle + MAX_CYCLES)) { |
1087 | pr_warning("Tag switch is taking a long time, " | 1087 | pr_warn("Tag switch is taking a long time, possible deadlock\n"); |
1088 | "possible deadlock\n"); | ||
1089 | start_cycle = -MAX_CYCLES - 1; | 1088 | start_cycle = -MAX_CYCLES - 1; |
1090 | } | 1089 | } |
1091 | } | 1090 | } |
@@ -1296,19 +1295,16 @@ static inline void cvmx_pow_tag_sw_nocheck(uint32_t tag, | |||
1296 | __cvmx_pow_warn_if_pending_switch(__func__); | 1295 | __cvmx_pow_warn_if_pending_switch(__func__); |
1297 | current_tag = cvmx_pow_get_current_tag(); | 1296 | current_tag = cvmx_pow_get_current_tag(); |
1298 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) | 1297 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) |
1299 | pr_warning("%s called with NULL_NULL tag\n", | 1298 | pr_warn("%s called with NULL_NULL tag\n", __func__); |
1300 | __func__); | ||
1301 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) | 1299 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) |
1302 | pr_warning("%s called with NULL tag\n", __func__); | 1300 | pr_warn("%s called with NULL tag\n", __func__); |
1303 | if ((current_tag.s.type == tag_type) | 1301 | if ((current_tag.s.type == tag_type) |
1304 | && (current_tag.s.tag == tag)) | 1302 | && (current_tag.s.tag == tag)) |
1305 | pr_warning("%s called to perform a tag switch to the " | 1303 | pr_warn("%s called to perform a tag switch to the same tag\n", |
1306 | "same tag\n", | 1304 | __func__); |
1307 | __func__); | ||
1308 | if (tag_type == CVMX_POW_TAG_TYPE_NULL) | 1305 | if (tag_type == CVMX_POW_TAG_TYPE_NULL) |
1309 | pr_warning("%s called to perform a tag switch to " | 1306 | pr_warn("%s called to perform a tag switch to NULL. Use cvmx_pow_tag_sw_null() instead\n", |
1310 | "NULL. Use cvmx_pow_tag_sw_null() instead\n", | 1307 | __func__); |
1311 | __func__); | ||
1312 | } | 1308 | } |
1313 | 1309 | ||
1314 | /* | 1310 | /* |
@@ -1407,23 +1403,19 @@ static inline void cvmx_pow_tag_sw_full_nocheck(cvmx_wqe_t *wqp, uint32_t tag, | |||
1407 | __cvmx_pow_warn_if_pending_switch(__func__); | 1403 | __cvmx_pow_warn_if_pending_switch(__func__); |
1408 | current_tag = cvmx_pow_get_current_tag(); | 1404 | current_tag = cvmx_pow_get_current_tag(); |
1409 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) | 1405 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) |
1410 | pr_warning("%s called with NULL_NULL tag\n", | 1406 | pr_warn("%s called with NULL_NULL tag\n", __func__); |
1411 | __func__); | ||
1412 | if ((current_tag.s.type == tag_type) | 1407 | if ((current_tag.s.type == tag_type) |
1413 | && (current_tag.s.tag == tag)) | 1408 | && (current_tag.s.tag == tag)) |
1414 | pr_warning("%s called to perform a tag switch to " | 1409 | pr_warn("%s called to perform a tag switch to the same tag\n", |
1415 | "the same tag\n", | 1410 | __func__); |
1416 | __func__); | ||
1417 | if (tag_type == CVMX_POW_TAG_TYPE_NULL) | 1411 | if (tag_type == CVMX_POW_TAG_TYPE_NULL) |
1418 | pr_warning("%s called to perform a tag switch to " | 1412 | pr_warn("%s called to perform a tag switch to NULL. Use cvmx_pow_tag_sw_null() instead\n", |
1419 | "NULL. Use cvmx_pow_tag_sw_null() instead\n", | 1413 | __func__); |
1420 | __func__); | ||
1421 | if (wqp != cvmx_phys_to_ptr(0x80)) | 1414 | if (wqp != cvmx_phys_to_ptr(0x80)) |
1422 | if (wqp != cvmx_pow_get_current_wqp()) | 1415 | if (wqp != cvmx_pow_get_current_wqp()) |
1423 | pr_warning("%s passed WQE(%p) doesn't match " | 1416 | pr_warn("%s passed WQE(%p) doesn't match the address in the POW(%p)\n", |
1424 | "the address in the POW(%p)\n", | 1417 | __func__, wqp, |
1425 | __func__, wqp, | 1418 | cvmx_pow_get_current_wqp()); |
1426 | cvmx_pow_get_current_wqp()); | ||
1427 | } | 1419 | } |
1428 | 1420 | ||
1429 | /* | 1421 | /* |
@@ -1507,12 +1499,10 @@ static inline void cvmx_pow_tag_sw_null_nocheck(void) | |||
1507 | __cvmx_pow_warn_if_pending_switch(__func__); | 1499 | __cvmx_pow_warn_if_pending_switch(__func__); |
1508 | current_tag = cvmx_pow_get_current_tag(); | 1500 | current_tag = cvmx_pow_get_current_tag(); |
1509 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) | 1501 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) |
1510 | pr_warning("%s called with NULL_NULL tag\n", | 1502 | pr_warn("%s called with NULL_NULL tag\n", __func__); |
1511 | __func__); | ||
1512 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) | 1503 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) |
1513 | pr_warning("%s called when we already have a " | 1504 | pr_warn("%s called when we already have a NULL tag\n", |
1514 | "NULL tag\n", | 1505 | __func__); |
1515 | __func__); | ||
1516 | } | 1506 | } |
1517 | 1507 | ||
1518 | tag_req.u64 = 0; | 1508 | tag_req.u64 = 0; |
@@ -1725,17 +1715,14 @@ static inline void cvmx_pow_tag_sw_desched_nocheck( | |||
1725 | __cvmx_pow_warn_if_pending_switch(__func__); | 1715 | __cvmx_pow_warn_if_pending_switch(__func__); |
1726 | current_tag = cvmx_pow_get_current_tag(); | 1716 | current_tag = cvmx_pow_get_current_tag(); |
1727 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) | 1717 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) |
1728 | pr_warning("%s called with NULL_NULL tag\n", | 1718 | pr_warn("%s called with NULL_NULL tag\n", __func__); |
1729 | __func__); | ||
1730 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) | 1719 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) |
1731 | pr_warning("%s called with NULL tag. Deschedule not " | 1720 | pr_warn("%s called with NULL tag. Deschedule not allowed from NULL state\n", |
1732 | "allowed from NULL state\n", | 1721 | __func__); |
1733 | __func__); | ||
1734 | if ((current_tag.s.type != CVMX_POW_TAG_TYPE_ATOMIC) | 1722 | if ((current_tag.s.type != CVMX_POW_TAG_TYPE_ATOMIC) |
1735 | && (tag_type != CVMX_POW_TAG_TYPE_ATOMIC)) | 1723 | && (tag_type != CVMX_POW_TAG_TYPE_ATOMIC)) |
1736 | pr_warning("%s called where neither the before or " | 1724 | pr_warn("%s called where neither the before or after tag is ATOMIC\n", |
1737 | "after tag is ATOMIC\n", | 1725 | __func__); |
1738 | __func__); | ||
1739 | } | 1726 | } |
1740 | 1727 | ||
1741 | tag_req.u64 = 0; | 1728 | tag_req.u64 = 0; |
@@ -1832,12 +1819,10 @@ static inline void cvmx_pow_desched(uint64_t no_sched) | |||
1832 | __cvmx_pow_warn_if_pending_switch(__func__); | 1819 | __cvmx_pow_warn_if_pending_switch(__func__); |
1833 | current_tag = cvmx_pow_get_current_tag(); | 1820 | current_tag = cvmx_pow_get_current_tag(); |
1834 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) | 1821 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL_NULL) |
1835 | pr_warning("%s called with NULL_NULL tag\n", | 1822 | pr_warn("%s called with NULL_NULL tag\n", __func__); |
1836 | __func__); | ||
1837 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) | 1823 | if (current_tag.s.type == CVMX_POW_TAG_TYPE_NULL) |
1838 | pr_warning("%s called with NULL tag. Deschedule not " | 1824 | pr_warn("%s called with NULL tag. Deschedule not expected from NULL state\n", |
1839 | "expected from NULL state\n", | 1825 | __func__); |
1840 | __func__); | ||
1841 | } | 1826 | } |
1842 | 1827 | ||
1843 | /* Need to make sure any writes to the work queue entry are complete */ | 1828 | /* Need to make sure any writes to the work queue entry are complete */ |
diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h index f991e7701d3d..33db1c806b01 100644 --- a/arch/mips/include/asm/octeon/cvmx.h +++ b/arch/mips/include/asm/octeon/cvmx.h | |||
@@ -451,67 +451,4 @@ static inline uint32_t cvmx_octeon_num_cores(void) | |||
451 | return cvmx_pop(ciu_fuse); | 451 | return cvmx_pop(ciu_fuse); |
452 | } | 452 | } |
453 | 453 | ||
454 | /** | ||
455 | * Read a byte of fuse data | ||
456 | * @byte_addr: address to read | ||
457 | * | ||
458 | * Returns fuse value: 0 or 1 | ||
459 | */ | ||
460 | static uint8_t cvmx_fuse_read_byte(int byte_addr) | ||
461 | { | ||
462 | union cvmx_mio_fus_rcmd read_cmd; | ||
463 | |||
464 | read_cmd.u64 = 0; | ||
465 | read_cmd.s.addr = byte_addr; | ||
466 | read_cmd.s.pend = 1; | ||
467 | cvmx_write_csr(CVMX_MIO_FUS_RCMD, read_cmd.u64); | ||
468 | while ((read_cmd.u64 = cvmx_read_csr(CVMX_MIO_FUS_RCMD)) | ||
469 | && read_cmd.s.pend) | ||
470 | ; | ||
471 | return read_cmd.s.dat; | ||
472 | } | ||
473 | |||
474 | /** | ||
475 | * Read a single fuse bit | ||
476 | * | ||
477 | * @fuse: Fuse number (0-1024) | ||
478 | * | ||
479 | * Returns fuse value: 0 or 1 | ||
480 | */ | ||
481 | static inline int cvmx_fuse_read(int fuse) | ||
482 | { | ||
483 | return (cvmx_fuse_read_byte(fuse >> 3) >> (fuse & 0x7)) & 1; | ||
484 | } | ||
485 | |||
486 | static inline int cvmx_octeon_model_CN36XX(void) | ||
487 | { | ||
488 | return OCTEON_IS_MODEL(OCTEON_CN38XX) | ||
489 | && !cvmx_octeon_is_pass1() | ||
490 | && cvmx_fuse_read(264); | ||
491 | } | ||
492 | |||
493 | static inline int cvmx_octeon_zip_present(void) | ||
494 | { | ||
495 | return octeon_has_feature(OCTEON_FEATURE_ZIP); | ||
496 | } | ||
497 | |||
498 | static inline int cvmx_octeon_dfa_present(void) | ||
499 | { | ||
500 | if (!OCTEON_IS_MODEL(OCTEON_CN38XX) | ||
501 | && !OCTEON_IS_MODEL(OCTEON_CN31XX) | ||
502 | && !OCTEON_IS_MODEL(OCTEON_CN58XX)) | ||
503 | return 0; | ||
504 | else if (OCTEON_IS_MODEL(OCTEON_CN3020)) | ||
505 | return 0; | ||
506 | else if (cvmx_octeon_is_pass1()) | ||
507 | return 1; | ||
508 | else | ||
509 | return !cvmx_fuse_read(120); | ||
510 | } | ||
511 | |||
512 | static inline int cvmx_octeon_crypto_present(void) | ||
513 | { | ||
514 | return octeon_has_feature(OCTEON_FEATURE_CRYPTO); | ||
515 | } | ||
516 | |||
517 | #endif /* __CVMX_H__ */ | 454 | #endif /* __CVMX_H__ */ |
diff --git a/arch/mips/include/asm/octeon/octeon-feature.h b/arch/mips/include/asm/octeon/octeon-feature.h index 90e05a8d4b15..c4fe81f47f53 100644 --- a/arch/mips/include/asm/octeon/octeon-feature.h +++ b/arch/mips/include/asm/octeon/octeon-feature.h | |||
@@ -86,8 +86,6 @@ enum octeon_feature { | |||
86 | OCTEON_MAX_FEATURE | 86 | OCTEON_MAX_FEATURE |
87 | }; | 87 | }; |
88 | 88 | ||
89 | static inline int cvmx_fuse_read(int fuse); | ||
90 | |||
91 | /** | 89 | /** |
92 | * Determine if the current Octeon supports a specific feature. These | 90 | * Determine if the current Octeon supports a specific feature. These |
93 | * checks have been optimized to be fairly quick, but they should still | 91 | * checks have been optimized to be fairly quick, but they should still |
@@ -105,33 +103,6 @@ static inline int octeon_has_feature(enum octeon_feature feature) | |||
105 | case OCTEON_FEATURE_SAAD: | 103 | case OCTEON_FEATURE_SAAD: |
106 | return !OCTEON_IS_MODEL(OCTEON_CN3XXX); | 104 | return !OCTEON_IS_MODEL(OCTEON_CN3XXX); |
107 | 105 | ||
108 | case OCTEON_FEATURE_ZIP: | ||
109 | if (OCTEON_IS_MODEL(OCTEON_CN30XX) | ||
110 | || OCTEON_IS_MODEL(OCTEON_CN50XX) | ||
111 | || OCTEON_IS_MODEL(OCTEON_CN52XX)) | ||
112 | return 0; | ||
113 | else if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1)) | ||
114 | return 1; | ||
115 | else | ||
116 | return !cvmx_fuse_read(121); | ||
117 | |||
118 | case OCTEON_FEATURE_CRYPTO: | ||
119 | if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) { | ||
120 | union cvmx_mio_fus_dat2 fus_2; | ||
121 | fus_2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2); | ||
122 | if (fus_2.s.nocrypto || fus_2.s.nomul) { | ||
123 | return 0; | ||
124 | } else if (!fus_2.s.dorm_crypto) { | ||
125 | return 1; | ||
126 | } else { | ||
127 | union cvmx_rnm_ctl_status st; | ||
128 | st.u64 = cvmx_read_csr(CVMX_RNM_CTL_STATUS); | ||
129 | return st.s.eer_val; | ||
130 | } | ||
131 | } else { | ||
132 | return !cvmx_fuse_read(90); | ||
133 | } | ||
134 | |||
135 | case OCTEON_FEATURE_DORM_CRYPTO: | 106 | case OCTEON_FEATURE_DORM_CRYPTO: |
136 | if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) { | 107 | if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) { |
137 | union cvmx_mio_fus_dat2 fus_2; | 108 | union cvmx_mio_fus_dat2 fus_2; |
@@ -188,29 +159,6 @@ static inline int octeon_has_feature(enum octeon_feature feature) | |||
188 | && !OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X) | 159 | && !OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X) |
189 | && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X); | 160 | && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X); |
190 | 161 | ||
191 | case OCTEON_FEATURE_DFA: | ||
192 | if (!OCTEON_IS_MODEL(OCTEON_CN38XX) | ||
193 | && !OCTEON_IS_MODEL(OCTEON_CN31XX) | ||
194 | && !OCTEON_IS_MODEL(OCTEON_CN58XX)) | ||
195 | return 0; | ||
196 | else if (OCTEON_IS_MODEL(OCTEON_CN3020)) | ||
197 | return 0; | ||
198 | else | ||
199 | return !cvmx_fuse_read(120); | ||
200 | |||
201 | case OCTEON_FEATURE_HFA: | ||
202 | if (!OCTEON_IS_MODEL(OCTEON_CN6XXX)) | ||
203 | return 0; | ||
204 | else | ||
205 | return !cvmx_fuse_read(90); | ||
206 | |||
207 | case OCTEON_FEATURE_DFM: | ||
208 | if (!(OCTEON_IS_MODEL(OCTEON_CN63XX) | ||
209 | || OCTEON_IS_MODEL(OCTEON_CN66XX))) | ||
210 | return 0; | ||
211 | else | ||
212 | return !cvmx_fuse_read(90); | ||
213 | |||
214 | case OCTEON_FEATURE_MDIO_CLAUSE_45: | 162 | case OCTEON_FEATURE_MDIO_CLAUSE_45: |
215 | return !(OCTEON_IS_MODEL(OCTEON_CN3XXX) | 163 | return !(OCTEON_IS_MODEL(OCTEON_CN3XXX) |
216 | || OCTEON_IS_MODEL(OCTEON_CN58XX) | 164 | || OCTEON_IS_MODEL(OCTEON_CN58XX) |
diff --git a/arch/mips/include/asm/octeon/octeon-model.h b/arch/mips/include/asm/octeon/octeon-model.h index e2c122c6a657..e8a1c2fd52cd 100644 --- a/arch/mips/include/asm/octeon/octeon-model.h +++ b/arch/mips/include/asm/octeon/octeon-model.h | |||
@@ -326,8 +326,7 @@ static inline int __octeon_is_model_runtime__(uint32_t model) | |||
326 | #define OCTEON_IS_COMMON_BINARY() 1 | 326 | #define OCTEON_IS_COMMON_BINARY() 1 |
327 | #undef OCTEON_MODEL | 327 | #undef OCTEON_MODEL |
328 | 328 | ||
329 | const char *octeon_model_get_string(uint32_t chip_id); | 329 | const char *__init octeon_model_get_string(uint32_t chip_id); |
330 | const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer); | ||
331 | 330 | ||
332 | /* | 331 | /* |
333 | * Return the octeon family, i.e., ProcessorID of the PrID register. | 332 | * Return the octeon family, i.e., ProcessorID of the PrID register. |
diff --git a/arch/mips/include/asm/paccess.h b/arch/mips/include/asm/paccess.h index 2474fc5d1751..af81ab0da55f 100644 --- a/arch/mips/include/asm/paccess.h +++ b/arch/mips/include/asm/paccess.h | |||
@@ -56,6 +56,7 @@ struct __large_pstruct { unsigned long buf[100]; }; | |||
56 | "1:\t" insn "\t%1,%2\n\t" \ | 56 | "1:\t" insn "\t%1,%2\n\t" \ |
57 | "move\t%0,$0\n" \ | 57 | "move\t%0,$0\n" \ |
58 | "2:\n\t" \ | 58 | "2:\n\t" \ |
59 | ".insn\n\t" \ | ||
59 | ".section\t.fixup,\"ax\"\n" \ | 60 | ".section\t.fixup,\"ax\"\n" \ |
60 | "3:\tli\t%0,%3\n\t" \ | 61 | "3:\tli\t%0,%3\n\t" \ |
61 | "move\t%1,$0\n\t" \ | 62 | "move\t%1,$0\n\t" \ |
@@ -94,6 +95,7 @@ extern void __get_dbe_unknown(void); | |||
94 | "1:\t" insn "\t%1,%2\n\t" \ | 95 | "1:\t" insn "\t%1,%2\n\t" \ |
95 | "move\t%0,$0\n" \ | 96 | "move\t%0,$0\n" \ |
96 | "2:\n\t" \ | 97 | "2:\n\t" \ |
98 | ".insn\n\t" \ | ||
97 | ".section\t.fixup,\"ax\"\n" \ | 99 | ".section\t.fixup,\"ax\"\n" \ |
98 | "3:\tli\t%0,%3\n\t" \ | 100 | "3:\tli\t%0,%3\n\t" \ |
99 | "j\t2b\n\t" \ | 101 | "j\t2b\n\t" \ |
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h index 3be81803595d..154b70a10483 100644 --- a/arch/mips/include/asm/page.h +++ b/arch/mips/include/asm/page.h | |||
@@ -116,7 +116,7 @@ extern void copy_user_highpage(struct page *to, struct page *from, | |||
116 | /* | 116 | /* |
117 | * These are used to make use of C type-checking.. | 117 | * These are used to make use of C type-checking.. |
118 | */ | 118 | */ |
119 | #ifdef CONFIG_64BIT_PHYS_ADDR | 119 | #ifdef CONFIG_PHYS_ADDR_T_64BIT |
120 | #ifdef CONFIG_CPU_MIPS32 | 120 | #ifdef CONFIG_CPU_MIPS32 |
121 | typedef struct { unsigned long pte_low, pte_high; } pte_t; | 121 | typedef struct { unsigned long pte_low, pte_high; } pte_t; |
122 | #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) | 122 | #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32)) |
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index 974b0e308963..69529624a005 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h | |||
@@ -84,7 +84,7 @@ static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, | |||
84 | const struct resource *rsrc, resource_size_t *start, | 84 | const struct resource *rsrc, resource_size_t *start, |
85 | resource_size_t *end) | 85 | resource_size_t *end) |
86 | { | 86 | { |
87 | phys_t size = resource_size(rsrc); | 87 | phys_addr_t size = resource_size(rsrc); |
88 | 88 | ||
89 | *start = fixup_bigphys_addr(rsrc->start, size); | 89 | *start = fixup_bigphys_addr(rsrc->start, size); |
90 | *end = rsrc->start + size; | 90 | *end = rsrc->start + size; |
diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h index cd7d6064bcbe..68984b612f9d 100644 --- a/arch/mips/include/asm/pgtable-32.h +++ b/arch/mips/include/asm/pgtable-32.h | |||
@@ -69,7 +69,7 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
69 | # define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE) | 69 | # define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE) |
70 | #endif | 70 | #endif |
71 | 71 | ||
72 | #ifdef CONFIG_64BIT_PHYS_ADDR | 72 | #ifdef CONFIG_PHYS_ADDR_T_64BIT |
73 | #define pte_ERROR(e) \ | 73 | #define pte_ERROR(e) \ |
74 | printk("%s:%d: bad pte %016Lx.\n", __FILE__, __LINE__, pte_val(e)) | 74 | printk("%s:%d: bad pte %016Lx.\n", __FILE__, __LINE__, pte_val(e)) |
75 | #else | 75 | #else |
@@ -103,7 +103,7 @@ static inline void pmd_clear(pmd_t *pmdp) | |||
103 | pmd_val(*pmdp) = ((unsigned long) invalid_pte_table); | 103 | pmd_val(*pmdp) = ((unsigned long) invalid_pte_table); |
104 | } | 104 | } |
105 | 105 | ||
106 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 106 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
107 | #define pte_page(x) pfn_to_page(pte_pfn(x)) | 107 | #define pte_page(x) pfn_to_page(pte_pfn(x)) |
108 | #define pte_pfn(x) ((unsigned long)((x).pte_high >> 6)) | 108 | #define pte_pfn(x) ((unsigned long)((x).pte_high >> 6)) |
109 | static inline pte_t | 109 | static inline pte_t |
@@ -126,7 +126,7 @@ pfn_pte(unsigned long pfn, pgprot_t prot) | |||
126 | #define pte_pfn(x) ((unsigned long)((x).pte >> _PFN_SHIFT)) | 126 | #define pte_pfn(x) ((unsigned long)((x).pte >> _PFN_SHIFT)) |
127 | #define pfn_pte(pfn, prot) __pte(((unsigned long long)(pfn) << _PFN_SHIFT) | pgprot_val(prot)) | 127 | #define pfn_pte(pfn, prot) __pte(((unsigned long long)(pfn) << _PFN_SHIFT) | pgprot_val(prot)) |
128 | #endif | 128 | #endif |
129 | #endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */ | 129 | #endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */ |
130 | 130 | ||
131 | #define __pgd_offset(address) pgd_index(address) | 131 | #define __pgd_offset(address) pgd_index(address) |
132 | #define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) | 132 | #define __pud_offset(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) |
@@ -155,73 +155,75 @@ pfn_pte(unsigned long pfn, pgprot_t prot) | |||
155 | #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) | 155 | #if defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) |
156 | 156 | ||
157 | /* Swap entries must have VALID bit cleared. */ | 157 | /* Swap entries must have VALID bit cleared. */ |
158 | #define __swp_type(x) (((x).val >> 10) & 0x1f) | 158 | #define __swp_type(x) (((x).val >> 10) & 0x1f) |
159 | #define __swp_offset(x) ((x).val >> 15) | 159 | #define __swp_offset(x) ((x).val >> 15) |
160 | #define __swp_entry(type,offset) \ | 160 | #define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 10) | ((offset) << 15) }) |
161 | ((swp_entry_t) { ((type) << 10) | ((offset) << 15) }) | 161 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) |
162 | #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) | ||
162 | 163 | ||
163 | /* | 164 | /* |
164 | * Bits 0, 4, 8, and 9 are taken, split up 28 bits of offset into this range: | 165 | * Encode and decode a nonlinear file mapping entry |
165 | */ | 166 | */ |
166 | #define PTE_FILE_MAX_BITS 28 | 167 | #define pte_to_pgoff(_pte) ((((_pte).pte >> 1 ) & 0x07) | \ |
167 | 168 | (((_pte).pte >> 2 ) & 0x38) | \ | |
168 | #define pte_to_pgoff(_pte) ((((_pte).pte >> 1 ) & 0x07) | \ | 169 | (((_pte).pte >> 10) << 6 )) |
169 | (((_pte).pte >> 2 ) & 0x38) | \ | ||
170 | (((_pte).pte >> 10) << 6 )) | ||
171 | 170 | ||
172 | #define pgoff_to_pte(off) ((pte_t) { (((off) & 0x07) << 1 ) | \ | 171 | #define pgoff_to_pte(off) ((pte_t) { (((off) & 0x07) << 1 ) | \ |
173 | (((off) & 0x38) << 2 ) | \ | 172 | (((off) & 0x38) << 2 ) | \ |
174 | (((off) >> 6 ) << 10) | \ | 173 | (((off) >> 6 ) << 10) | \ |
175 | _PAGE_FILE }) | 174 | _PAGE_FILE }) |
176 | 175 | ||
176 | /* | ||
177 | * Bits 0, 4, 8, and 9 are taken, split up 28 bits of offset into this range: | ||
178 | */ | ||
179 | #define PTE_FILE_MAX_BITS 28 | ||
177 | #else | 180 | #else |
178 | 181 | ||
182 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) | ||
183 | |||
179 | /* Swap entries must have VALID and GLOBAL bits cleared. */ | 184 | /* Swap entries must have VALID and GLOBAL bits cleared. */ |
180 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 185 | #define __swp_type(x) (((x).val >> 2) & 0x1f) |
181 | #define __swp_type(x) (((x).val >> 2) & 0x1f) | 186 | #define __swp_offset(x) ((x).val >> 7) |
182 | #define __swp_offset(x) ((x).val >> 7) | 187 | #define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 7) }) |
183 | #define __swp_entry(type,offset) \ | 188 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high }) |
184 | ((swp_entry_t) { ((type) << 2) | ((offset) << 7) }) | 189 | #define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val }) |
185 | #else | ||
186 | #define __swp_type(x) (((x).val >> 8) & 0x1f) | ||
187 | #define __swp_offset(x) ((x).val >> 13) | ||
188 | #define __swp_entry(type,offset) \ | ||
189 | ((swp_entry_t) { ((type) << 8) | ((offset) << 13) }) | ||
190 | #endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */ | ||
191 | 190 | ||
192 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | ||
193 | /* | 191 | /* |
194 | * Bits 0 and 1 of pte_high are taken, use the rest for the page offset... | 192 | * Bits 0 and 1 of pte_high are taken, use the rest for the page offset... |
195 | */ | 193 | */ |
196 | #define PTE_FILE_MAX_BITS 30 | 194 | #define pte_to_pgoff(_pte) ((_pte).pte_high >> 2) |
197 | 195 | #define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) << 2 }) | |
198 | #define pte_to_pgoff(_pte) ((_pte).pte_high >> 2) | ||
199 | #define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) << 2 }) | ||
200 | 196 | ||
197 | #define PTE_FILE_MAX_BITS 30 | ||
201 | #else | 198 | #else |
202 | /* | 199 | /* |
203 | * Bits 0, 4, 6, and 7 are taken, split up 28 bits of offset into this range: | 200 | * Constraints: |
201 | * _PAGE_PRESENT at bit 0 | ||
202 | * _PAGE_MODIFIED at bit 4 | ||
203 | * _PAGE_GLOBAL at bit 6 | ||
204 | * _PAGE_VALID at bit 7 | ||
204 | */ | 205 | */ |
205 | #define PTE_FILE_MAX_BITS 28 | 206 | #define __swp_type(x) (((x).val >> 8) & 0x1f) |
207 | #define __swp_offset(x) ((x).val >> 13) | ||
208 | #define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 8) | ((offset) << 13) }) | ||
209 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) | ||
210 | #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) | ||
206 | 211 | ||
207 | #define pte_to_pgoff(_pte) ((((_pte).pte >> 1) & 0x7) | \ | 212 | /* |
208 | (((_pte).pte >> 2) & 0x8) | \ | 213 | * Encode and decode a nonlinear file mapping entry |
209 | (((_pte).pte >> 8) << 4)) | 214 | */ |
215 | #define pte_to_pgoff(_pte) ((((_pte).pte >> 1) & 0x7) | \ | ||
216 | (((_pte).pte >> 2) & 0x8) | \ | ||
217 | (((_pte).pte >> 8) << 4)) | ||
210 | 218 | ||
211 | #define pgoff_to_pte(off) ((pte_t) { (((off) & 0x7) << 1) | \ | 219 | #define pgoff_to_pte(off) ((pte_t) { (((off) & 0x7) << 1) | \ |
212 | (((off) & 0x8) << 2) | \ | 220 | (((off) & 0x8) << 2) | \ |
213 | (((off) >> 4) << 8) | \ | 221 | (((off) >> 4) << 8) | \ |
214 | _PAGE_FILE }) | 222 | _PAGE_FILE }) |
215 | #endif | ||
216 | 223 | ||
217 | #endif | 224 | #define PTE_FILE_MAX_BITS 28 |
225 | #endif /* defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) */ | ||
218 | 226 | ||
219 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 227 | #endif /* defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) */ |
220 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high }) | ||
221 | #define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val }) | ||
222 | #else | ||
223 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) | ||
224 | #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) | ||
225 | #endif | ||
226 | 228 | ||
227 | #endif /* _ASM_PGTABLE_32_H */ | 229 | #endif /* _ASM_PGTABLE_32_H */ |
diff --git a/arch/mips/include/asm/pgtable-bits.h b/arch/mips/include/asm/pgtable-bits.h index e747bfa0be7e..ca11f14f40a3 100644 --- a/arch/mips/include/asm/pgtable-bits.h +++ b/arch/mips/include/asm/pgtable-bits.h | |||
@@ -32,39 +32,41 @@ | |||
32 | * unpredictable things. The code (when it is written) to deal with | 32 | * unpredictable things. The code (when it is written) to deal with |
33 | * this problem will be in the update_mmu_cache() code for the r4k. | 33 | * this problem will be in the update_mmu_cache() code for the r4k. |
34 | */ | 34 | */ |
35 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 35 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
36 | 36 | ||
37 | /* | 37 | /* |
38 | * The following bits are directly used by the TLB hardware | 38 | * The following bits are directly used by the TLB hardware |
39 | */ | 39 | */ |
40 | #define _PAGE_R4KBUG (1 << 0) /* workaround for r4k bug */ | 40 | #define _PAGE_GLOBAL_SHIFT 0 |
41 | #define _PAGE_GLOBAL (1 << 0) | 41 | #define _PAGE_GLOBAL (1 << _PAGE_GLOBAL_SHIFT) |
42 | #define _PAGE_VALID_SHIFT 1 | 42 | #define _PAGE_VALID_SHIFT (_PAGE_GLOBAL_SHIFT + 1) |
43 | #define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) | 43 | #define _PAGE_VALID (1 << _PAGE_VALID_SHIFT) |
44 | #define _PAGE_SILENT_READ (1 << 1) /* synonym */ | 44 | #define _PAGE_DIRTY_SHIFT (_PAGE_VALID_SHIFT + 1) |
45 | #define _PAGE_DIRTY_SHIFT 2 | 45 | #define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT) |
46 | #define _PAGE_DIRTY (1 << _PAGE_DIRTY_SHIFT) /* The MIPS dirty bit */ | 46 | #define _CACHE_SHIFT (_PAGE_DIRTY_SHIFT + 1) |
47 | #define _PAGE_SILENT_WRITE (1 << 2) | 47 | #define _CACHE_MASK (7 << _CACHE_SHIFT) |
48 | #define _CACHE_SHIFT 3 | ||
49 | #define _CACHE_MASK (7 << 3) | ||
50 | 48 | ||
51 | /* | 49 | /* |
52 | * The following bits are implemented in software | 50 | * The following bits are implemented in software |
53 | * | 51 | * |
54 | * _PAGE_FILE semantics: set:pagecache unset:swap | 52 | * _PAGE_FILE semantics: set:pagecache unset:swap |
55 | */ | 53 | */ |
56 | #define _PAGE_PRESENT_SHIFT 6 | 54 | #define _PAGE_PRESENT_SHIFT (_CACHE_SHIFT + 3) |
57 | #define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) | 55 | #define _PAGE_PRESENT (1 << _PAGE_PRESENT_SHIFT) |
58 | #define _PAGE_READ_SHIFT 7 | 56 | #define _PAGE_READ_SHIFT (_PAGE_PRESENT_SHIFT + 1) |
59 | #define _PAGE_READ (1 << _PAGE_READ_SHIFT) | 57 | #define _PAGE_READ (1 << _PAGE_READ_SHIFT) |
60 | #define _PAGE_WRITE_SHIFT 8 | 58 | #define _PAGE_WRITE_SHIFT (_PAGE_READ_SHIFT + 1) |
61 | #define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) | 59 | #define _PAGE_WRITE (1 << _PAGE_WRITE_SHIFT) |
62 | #define _PAGE_ACCESSED_SHIFT 9 | 60 | #define _PAGE_ACCESSED_SHIFT (_PAGE_WRITE_SHIFT + 1) |
63 | #define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) | 61 | #define _PAGE_ACCESSED (1 << _PAGE_ACCESSED_SHIFT) |
64 | #define _PAGE_MODIFIED_SHIFT 10 | 62 | #define _PAGE_MODIFIED_SHIFT (_PAGE_ACCESSED_SHIFT + 1) |
65 | #define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) | 63 | #define _PAGE_MODIFIED (1 << _PAGE_MODIFIED_SHIFT) |
66 | 64 | ||
67 | #define _PAGE_FILE (1 << 10) | 65 | #define _PAGE_SILENT_READ _PAGE_VALID |
66 | #define _PAGE_SILENT_WRITE _PAGE_DIRTY | ||
67 | #define _PAGE_FILE _PAGE_MODIFIED | ||
68 | |||
69 | #define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3) | ||
68 | 70 | ||
69 | #elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) | 71 | #elif defined(CONFIG_CPU_R3000) || defined(CONFIG_CPU_TX39XX) |
70 | 72 | ||
@@ -172,7 +174,7 @@ | |||
172 | 174 | ||
173 | #define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3) | 175 | #define _PFN_SHIFT (PAGE_SHIFT - 12 + _CACHE_SHIFT + 3) |
174 | 176 | ||
175 | #endif /* defined(CONFIG_64BIT_PHYS_ADDR && defined(CONFIG_CPU_MIPS32) */ | 177 | #endif /* defined(CONFIG_PHYS_ADDR_T_64BIT && defined(CONFIG_CPU_MIPS32) */ |
176 | 178 | ||
177 | #ifndef _PFN_SHIFT | 179 | #ifndef _PFN_SHIFT |
178 | #define _PFN_SHIFT PAGE_SHIFT | 180 | #define _PFN_SHIFT PAGE_SHIFT |
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index d6d1928539b1..62a6ba383d4f 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h | |||
@@ -125,7 +125,7 @@ do { \ | |||
125 | extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, | 125 | extern void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, |
126 | pte_t pteval); | 126 | pte_t pteval); |
127 | 127 | ||
128 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 128 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
129 | 129 | ||
130 | #define pte_none(pte) (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL)) | 130 | #define pte_none(pte) (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL)) |
131 | #define pte_present(pte) ((pte).pte_low & _PAGE_PRESENT) | 131 | #define pte_present(pte) ((pte).pte_low & _PAGE_PRESENT) |
@@ -227,7 +227,7 @@ extern pgd_t swapper_pg_dir[]; | |||
227 | * The following only work if pte_present() is true. | 227 | * The following only work if pte_present() is true. |
228 | * Undefined behaviour if not.. | 228 | * Undefined behaviour if not.. |
229 | */ | 229 | */ |
230 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 230 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
231 | static inline int pte_write(pte_t pte) { return pte.pte_low & _PAGE_WRITE; } | 231 | static inline int pte_write(pte_t pte) { return pte.pte_low & _PAGE_WRITE; } |
232 | static inline int pte_dirty(pte_t pte) { return pte.pte_low & _PAGE_MODIFIED; } | 232 | static inline int pte_dirty(pte_t pte) { return pte.pte_low & _PAGE_MODIFIED; } |
233 | static inline int pte_young(pte_t pte) { return pte.pte_low & _PAGE_ACCESSED; } | 233 | static inline int pte_young(pte_t pte) { return pte.pte_low & _PAGE_ACCESSED; } |
@@ -297,13 +297,13 @@ static inline pte_t pte_wrprotect(pte_t pte) | |||
297 | 297 | ||
298 | static inline pte_t pte_mkclean(pte_t pte) | 298 | static inline pte_t pte_mkclean(pte_t pte) |
299 | { | 299 | { |
300 | pte_val(pte) &= ~(_PAGE_MODIFIED|_PAGE_SILENT_WRITE); | 300 | pte_val(pte) &= ~(_PAGE_MODIFIED | _PAGE_SILENT_WRITE); |
301 | return pte; | 301 | return pte; |
302 | } | 302 | } |
303 | 303 | ||
304 | static inline pte_t pte_mkold(pte_t pte) | 304 | static inline pte_t pte_mkold(pte_t pte) |
305 | { | 305 | { |
306 | pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_SILENT_READ); | 306 | pte_val(pte) &= ~(_PAGE_ACCESSED | _PAGE_SILENT_READ); |
307 | return pte; | 307 | return pte; |
308 | } | 308 | } |
309 | 309 | ||
@@ -382,13 +382,13 @@ static inline pgprot_t pgprot_writecombine(pgprot_t _prot) | |||
382 | */ | 382 | */ |
383 | #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) | 383 | #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) |
384 | 384 | ||
385 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 385 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
386 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | 386 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) |
387 | { | 387 | { |
388 | pte.pte_low &= _PAGE_CHG_MASK; | 388 | pte.pte_low &= _PAGE_CHG_MASK; |
389 | pte.pte_high &= ~0x3f; | 389 | pte.pte_high &= (_PFN_MASK | _CACHE_MASK); |
390 | pte.pte_low |= pgprot_val(newprot); | 390 | pte.pte_low |= pgprot_val(newprot); |
391 | pte.pte_high |= pgprot_val(newprot) & 0x3f; | 391 | pte.pte_high |= pgprot_val(newprot) & ~(_PFN_MASK | _CACHE_MASK); |
392 | return pte; | 392 | return pte; |
393 | } | 393 | } |
394 | #else | 394 | #else |
@@ -419,7 +419,7 @@ static inline void update_mmu_cache_pmd(struct vm_area_struct *vma, | |||
419 | 419 | ||
420 | #define kern_addr_valid(addr) (1) | 420 | #define kern_addr_valid(addr) (1) |
421 | 421 | ||
422 | #ifdef CONFIG_64BIT_PHYS_ADDR | 422 | #ifdef CONFIG_PHYS_ADDR_T_64BIT |
423 | extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot); | 423 | extern int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot); |
424 | 424 | ||
425 | static inline int io_remap_pfn_range(struct vm_area_struct *vma, | 425 | static inline int io_remap_pfn_range(struct vm_area_struct *vma, |
@@ -428,7 +428,7 @@ static inline int io_remap_pfn_range(struct vm_area_struct *vma, | |||
428 | unsigned long size, | 428 | unsigned long size, |
429 | pgprot_t prot) | 429 | pgprot_t prot) |
430 | { | 430 | { |
431 | phys_t phys_addr_high = fixup_bigphys_addr(pfn << PAGE_SHIFT, size); | 431 | phys_addr_t phys_addr_high = fixup_bigphys_addr(pfn << PAGE_SHIFT, size); |
432 | return remap_pfn_range(vma, vaddr, phys_addr_high >> PAGE_SHIFT, size, prot); | 432 | return remap_pfn_range(vma, vaddr, phys_addr_high >> PAGE_SHIFT, size, prot); |
433 | } | 433 | } |
434 | #define io_remap_pfn_range io_remap_pfn_range | 434 | #define io_remap_pfn_range io_remap_pfn_range |
diff --git a/arch/mips/include/asm/prom.h b/arch/mips/include/asm/prom.h index a9494c0141fb..eaa26270a5e5 100644 --- a/arch/mips/include/asm/prom.h +++ b/arch/mips/include/asm/prom.h | |||
@@ -22,6 +22,7 @@ extern void device_tree_init(void); | |||
22 | struct boot_param_header; | 22 | struct boot_param_header; |
23 | 23 | ||
24 | extern void __dt_setup_arch(void *bph); | 24 | extern void __dt_setup_arch(void *bph); |
25 | extern int __dt_register_buses(const char *bus0, const char *bus1); | ||
25 | 26 | ||
26 | #define dt_setup_arch(sym) \ | 27 | #define dt_setup_arch(sym) \ |
27 | ({ \ | 28 | ({ \ |
diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h index cd6e0afc6833..e293a8d89a6d 100644 --- a/arch/mips/include/asm/r4kcache.h +++ b/arch/mips/include/asm/r4kcache.h | |||
@@ -47,79 +47,20 @@ extern void (*r4k_blast_icache)(void); | |||
47 | 47 | ||
48 | #ifdef CONFIG_MIPS_MT | 48 | #ifdef CONFIG_MIPS_MT |
49 | 49 | ||
50 | /* | ||
51 | * Optionally force single-threaded execution during I-cache flushes. | ||
52 | */ | ||
53 | #define PROTECT_CACHE_FLUSHES 1 | ||
54 | |||
55 | #ifdef PROTECT_CACHE_FLUSHES | ||
56 | |||
57 | extern int mt_protiflush; | ||
58 | extern int mt_protdflush; | ||
59 | extern void mt_cflush_lockdown(void); | ||
60 | extern void mt_cflush_release(void); | ||
61 | |||
62 | #define BEGIN_MT_IPROT \ | ||
63 | unsigned long flags = 0; \ | ||
64 | unsigned long mtflags = 0; \ | ||
65 | if(mt_protiflush) { \ | ||
66 | local_irq_save(flags); \ | ||
67 | ehb(); \ | ||
68 | mtflags = dvpe(); \ | ||
69 | mt_cflush_lockdown(); \ | ||
70 | } | ||
71 | |||
72 | #define END_MT_IPROT \ | ||
73 | if(mt_protiflush) { \ | ||
74 | mt_cflush_release(); \ | ||
75 | evpe(mtflags); \ | ||
76 | local_irq_restore(flags); \ | ||
77 | } | ||
78 | |||
79 | #define BEGIN_MT_DPROT \ | ||
80 | unsigned long flags = 0; \ | ||
81 | unsigned long mtflags = 0; \ | ||
82 | if(mt_protdflush) { \ | ||
83 | local_irq_save(flags); \ | ||
84 | ehb(); \ | ||
85 | mtflags = dvpe(); \ | ||
86 | mt_cflush_lockdown(); \ | ||
87 | } | ||
88 | |||
89 | #define END_MT_DPROT \ | ||
90 | if(mt_protdflush) { \ | ||
91 | mt_cflush_release(); \ | ||
92 | evpe(mtflags); \ | ||
93 | local_irq_restore(flags); \ | ||
94 | } | ||
95 | |||
96 | #else | ||
97 | |||
98 | #define BEGIN_MT_IPROT | ||
99 | #define BEGIN_MT_DPROT | ||
100 | #define END_MT_IPROT | ||
101 | #define END_MT_DPROT | ||
102 | |||
103 | #endif /* PROTECT_CACHE_FLUSHES */ | ||
104 | |||
105 | #define __iflush_prologue \ | 50 | #define __iflush_prologue \ |
106 | unsigned long redundance; \ | 51 | unsigned long redundance; \ |
107 | extern int mt_n_iflushes; \ | 52 | extern int mt_n_iflushes; \ |
108 | BEGIN_MT_IPROT \ | ||
109 | for (redundance = 0; redundance < mt_n_iflushes; redundance++) { | 53 | for (redundance = 0; redundance < mt_n_iflushes; redundance++) { |
110 | 54 | ||
111 | #define __iflush_epilogue \ | 55 | #define __iflush_epilogue \ |
112 | END_MT_IPROT \ | ||
113 | } | 56 | } |
114 | 57 | ||
115 | #define __dflush_prologue \ | 58 | #define __dflush_prologue \ |
116 | unsigned long redundance; \ | 59 | unsigned long redundance; \ |
117 | extern int mt_n_dflushes; \ | 60 | extern int mt_n_dflushes; \ |
118 | BEGIN_MT_DPROT \ | ||
119 | for (redundance = 0; redundance < mt_n_dflushes; redundance++) { | 61 | for (redundance = 0; redundance < mt_n_dflushes; redundance++) { |
120 | 62 | ||
121 | #define __dflush_epilogue \ | 63 | #define __dflush_epilogue \ |
122 | END_MT_DPROT \ | ||
123 | } | 64 | } |
124 | 65 | ||
125 | #define __inv_dflush_prologue __dflush_prologue | 66 | #define __inv_dflush_prologue __dflush_prologue |
diff --git a/arch/mips/include/asm/spinlock.h b/arch/mips/include/asm/spinlock.h index 78d201fb6c87..c6d06d383ef9 100644 --- a/arch/mips/include/asm/spinlock.h +++ b/arch/mips/include/asm/spinlock.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/compiler.h> | 12 | #include <linux/compiler.h> |
13 | 13 | ||
14 | #include <asm/barrier.h> | 14 | #include <asm/barrier.h> |
15 | #include <asm/compiler.h> | ||
15 | #include <asm/war.h> | 16 | #include <asm/war.h> |
16 | 17 | ||
17 | /* | 18 | /* |
@@ -88,7 +89,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) | |||
88 | " subu %[ticket], %[ticket], 1 \n" | 89 | " subu %[ticket], %[ticket], 1 \n" |
89 | " .previous \n" | 90 | " .previous \n" |
90 | " .set pop \n" | 91 | " .set pop \n" |
91 | : [ticket_ptr] "+m" (lock->lock), | 92 | : [ticket_ptr] "+" GCC_OFF12_ASM() (lock->lock), |
92 | [serving_now_ptr] "+m" (lock->h.serving_now), | 93 | [serving_now_ptr] "+m" (lock->h.serving_now), |
93 | [ticket] "=&r" (tmp), | 94 | [ticket] "=&r" (tmp), |
94 | [my_ticket] "=&r" (my_ticket) | 95 | [my_ticket] "=&r" (my_ticket) |
@@ -121,7 +122,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) | |||
121 | " subu %[ticket], %[ticket], 1 \n" | 122 | " subu %[ticket], %[ticket], 1 \n" |
122 | " .previous \n" | 123 | " .previous \n" |
123 | " .set pop \n" | 124 | " .set pop \n" |
124 | : [ticket_ptr] "+m" (lock->lock), | 125 | : [ticket_ptr] "+" GCC_OFF12_ASM() (lock->lock), |
125 | [serving_now_ptr] "+m" (lock->h.serving_now), | 126 | [serving_now_ptr] "+m" (lock->h.serving_now), |
126 | [ticket] "=&r" (tmp), | 127 | [ticket] "=&r" (tmp), |
127 | [my_ticket] "=&r" (my_ticket) | 128 | [my_ticket] "=&r" (my_ticket) |
@@ -163,7 +164,7 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) | |||
163 | " li %[ticket], 0 \n" | 164 | " li %[ticket], 0 \n" |
164 | " .previous \n" | 165 | " .previous \n" |
165 | " .set pop \n" | 166 | " .set pop \n" |
166 | : [ticket_ptr] "+m" (lock->lock), | 167 | : [ticket_ptr] "+" GCC_OFF12_ASM() (lock->lock), |
167 | [ticket] "=&r" (tmp), | 168 | [ticket] "=&r" (tmp), |
168 | [my_ticket] "=&r" (tmp2), | 169 | [my_ticket] "=&r" (tmp2), |
169 | [now_serving] "=&r" (tmp3) | 170 | [now_serving] "=&r" (tmp3) |
@@ -187,7 +188,7 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) | |||
187 | " li %[ticket], 0 \n" | 188 | " li %[ticket], 0 \n" |
188 | " .previous \n" | 189 | " .previous \n" |
189 | " .set pop \n" | 190 | " .set pop \n" |
190 | : [ticket_ptr] "+m" (lock->lock), | 191 | : [ticket_ptr] "+" GCC_OFF12_ASM() (lock->lock), |
191 | [ticket] "=&r" (tmp), | 192 | [ticket] "=&r" (tmp), |
192 | [my_ticket] "=&r" (tmp2), | 193 | [my_ticket] "=&r" (tmp2), |
193 | [now_serving] "=&r" (tmp3) | 194 | [now_serving] "=&r" (tmp3) |
@@ -234,8 +235,8 @@ static inline void arch_read_lock(arch_rwlock_t *rw) | |||
234 | " beqzl %1, 1b \n" | 235 | " beqzl %1, 1b \n" |
235 | " nop \n" | 236 | " nop \n" |
236 | " .set reorder \n" | 237 | " .set reorder \n" |
237 | : "=m" (rw->lock), "=&r" (tmp) | 238 | : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp) |
238 | : "m" (rw->lock) | 239 | : GCC_OFF12_ASM() (rw->lock) |
239 | : "memory"); | 240 | : "memory"); |
240 | } else { | 241 | } else { |
241 | do { | 242 | do { |
@@ -244,8 +245,8 @@ static inline void arch_read_lock(arch_rwlock_t *rw) | |||
244 | " bltz %1, 1b \n" | 245 | " bltz %1, 1b \n" |
245 | " addu %1, 1 \n" | 246 | " addu %1, 1 \n" |
246 | "2: sc %1, %0 \n" | 247 | "2: sc %1, %0 \n" |
247 | : "=m" (rw->lock), "=&r" (tmp) | 248 | : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp) |
248 | : "m" (rw->lock) | 249 | : GCC_OFF12_ASM() (rw->lock) |
249 | : "memory"); | 250 | : "memory"); |
250 | } while (unlikely(!tmp)); | 251 | } while (unlikely(!tmp)); |
251 | } | 252 | } |
@@ -268,8 +269,8 @@ static inline void arch_read_unlock(arch_rwlock_t *rw) | |||
268 | " sub %1, 1 \n" | 269 | " sub %1, 1 \n" |
269 | " sc %1, %0 \n" | 270 | " sc %1, %0 \n" |
270 | " beqzl %1, 1b \n" | 271 | " beqzl %1, 1b \n" |
271 | : "=m" (rw->lock), "=&r" (tmp) | 272 | : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp) |
272 | : "m" (rw->lock) | 273 | : GCC_OFF12_ASM() (rw->lock) |
273 | : "memory"); | 274 | : "memory"); |
274 | } else { | 275 | } else { |
275 | do { | 276 | do { |
@@ -277,8 +278,8 @@ static inline void arch_read_unlock(arch_rwlock_t *rw) | |||
277 | "1: ll %1, %2 # arch_read_unlock \n" | 278 | "1: ll %1, %2 # arch_read_unlock \n" |
278 | " sub %1, 1 \n" | 279 | " sub %1, 1 \n" |
279 | " sc %1, %0 \n" | 280 | " sc %1, %0 \n" |
280 | : "=m" (rw->lock), "=&r" (tmp) | 281 | : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp) |
281 | : "m" (rw->lock) | 282 | : GCC_OFF12_ASM() (rw->lock) |
282 | : "memory"); | 283 | : "memory"); |
283 | } while (unlikely(!tmp)); | 284 | } while (unlikely(!tmp)); |
284 | } | 285 | } |
@@ -298,8 +299,8 @@ static inline void arch_write_lock(arch_rwlock_t *rw) | |||
298 | " beqzl %1, 1b \n" | 299 | " beqzl %1, 1b \n" |
299 | " nop \n" | 300 | " nop \n" |
300 | " .set reorder \n" | 301 | " .set reorder \n" |
301 | : "=m" (rw->lock), "=&r" (tmp) | 302 | : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp) |
302 | : "m" (rw->lock) | 303 | : GCC_OFF12_ASM() (rw->lock) |
303 | : "memory"); | 304 | : "memory"); |
304 | } else { | 305 | } else { |
305 | do { | 306 | do { |
@@ -308,8 +309,8 @@ static inline void arch_write_lock(arch_rwlock_t *rw) | |||
308 | " bnez %1, 1b \n" | 309 | " bnez %1, 1b \n" |
309 | " lui %1, 0x8000 \n" | 310 | " lui %1, 0x8000 \n" |
310 | "2: sc %1, %0 \n" | 311 | "2: sc %1, %0 \n" |
311 | : "=m" (rw->lock), "=&r" (tmp) | 312 | : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp) |
312 | : "m" (rw->lock) | 313 | : GCC_OFF12_ASM() (rw->lock) |
313 | : "memory"); | 314 | : "memory"); |
314 | } while (unlikely(!tmp)); | 315 | } while (unlikely(!tmp)); |
315 | } | 316 | } |
@@ -348,8 +349,8 @@ static inline int arch_read_trylock(arch_rwlock_t *rw) | |||
348 | __WEAK_LLSC_MB | 349 | __WEAK_LLSC_MB |
349 | " li %2, 1 \n" | 350 | " li %2, 1 \n" |
350 | "2: \n" | 351 | "2: \n" |
351 | : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) | 352 | : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret) |
352 | : "m" (rw->lock) | 353 | : GCC_OFF12_ASM() (rw->lock) |
353 | : "memory"); | 354 | : "memory"); |
354 | } else { | 355 | } else { |
355 | __asm__ __volatile__( | 356 | __asm__ __volatile__( |
@@ -365,8 +366,8 @@ static inline int arch_read_trylock(arch_rwlock_t *rw) | |||
365 | __WEAK_LLSC_MB | 366 | __WEAK_LLSC_MB |
366 | " li %2, 1 \n" | 367 | " li %2, 1 \n" |
367 | "2: \n" | 368 | "2: \n" |
368 | : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) | 369 | : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret) |
369 | : "m" (rw->lock) | 370 | : GCC_OFF12_ASM() (rw->lock) |
370 | : "memory"); | 371 | : "memory"); |
371 | } | 372 | } |
372 | 373 | ||
@@ -392,8 +393,8 @@ static inline int arch_write_trylock(arch_rwlock_t *rw) | |||
392 | " li %2, 1 \n" | 393 | " li %2, 1 \n" |
393 | " .set reorder \n" | 394 | " .set reorder \n" |
394 | "2: \n" | 395 | "2: \n" |
395 | : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) | 396 | : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret) |
396 | : "m" (rw->lock) | 397 | : GCC_OFF12_ASM() (rw->lock) |
397 | : "memory"); | 398 | : "memory"); |
398 | } else { | 399 | } else { |
399 | do { | 400 | do { |
@@ -405,8 +406,9 @@ static inline int arch_write_trylock(arch_rwlock_t *rw) | |||
405 | " sc %1, %0 \n" | 406 | " sc %1, %0 \n" |
406 | " li %2, 1 \n" | 407 | " li %2, 1 \n" |
407 | "2: \n" | 408 | "2: \n" |
408 | : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) | 409 | : "=" GCC_OFF12_ASM() (rw->lock), "=&r" (tmp), |
409 | : "m" (rw->lock) | 410 | "=&r" (ret) |
411 | : GCC_OFF12_ASM() (rw->lock) | ||
410 | : "memory"); | 412 | : "memory"); |
411 | } while (unlikely(!tmp)); | 413 | } while (unlikely(!tmp)); |
412 | 414 | ||
diff --git a/arch/mips/include/asm/thread_info.h b/arch/mips/include/asm/thread_info.h index 7de865805deb..99eea59604e9 100644 --- a/arch/mips/include/asm/thread_info.h +++ b/arch/mips/include/asm/thread_info.h | |||
@@ -116,6 +116,7 @@ static inline struct thread_info *current_thread_info(void) | |||
116 | #define TIF_LOAD_WATCH 25 /* If set, load watch registers */ | 116 | #define TIF_LOAD_WATCH 25 /* If set, load watch registers */ |
117 | #define TIF_SYSCALL_TRACEPOINT 26 /* syscall tracepoint instrumentation */ | 117 | #define TIF_SYSCALL_TRACEPOINT 26 /* syscall tracepoint instrumentation */ |
118 | #define TIF_32BIT_FPREGS 27 /* 32-bit floating point registers */ | 118 | #define TIF_32BIT_FPREGS 27 /* 32-bit floating point registers */ |
119 | #define TIF_HYBRID_FPREGS 28 /* 64b FP registers, odd singles in bits 63:32 of even doubles */ | ||
119 | #define TIF_USEDMSA 29 /* MSA has been used this quantum */ | 120 | #define TIF_USEDMSA 29 /* MSA has been used this quantum */ |
120 | #define TIF_MSA_CTX_LIVE 30 /* MSA context must be preserved */ | 121 | #define TIF_MSA_CTX_LIVE 30 /* MSA context must be preserved */ |
121 | #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ | 122 | #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ |
@@ -135,6 +136,7 @@ static inline struct thread_info *current_thread_info(void) | |||
135 | #define _TIF_FPUBOUND (1<<TIF_FPUBOUND) | 136 | #define _TIF_FPUBOUND (1<<TIF_FPUBOUND) |
136 | #define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH) | 137 | #define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH) |
137 | #define _TIF_32BIT_FPREGS (1<<TIF_32BIT_FPREGS) | 138 | #define _TIF_32BIT_FPREGS (1<<TIF_32BIT_FPREGS) |
139 | #define _TIF_HYBRID_FPREGS (1<<TIF_HYBRID_FPREGS) | ||
138 | #define _TIF_USEDMSA (1<<TIF_USEDMSA) | 140 | #define _TIF_USEDMSA (1<<TIF_USEDMSA) |
139 | #define _TIF_MSA_CTX_LIVE (1<<TIF_MSA_CTX_LIVE) | 141 | #define _TIF_MSA_CTX_LIVE (1<<TIF_MSA_CTX_LIVE) |
140 | #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) | 142 | #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) |
diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h index 8f3047d611ee..8ab2874225c4 100644 --- a/arch/mips/include/asm/time.h +++ b/arch/mips/include/asm/time.h | |||
@@ -46,19 +46,17 @@ extern unsigned int mips_hpt_frequency; | |||
46 | * so it lives here. | 46 | * so it lives here. |
47 | */ | 47 | */ |
48 | extern int (*perf_irq)(void); | 48 | extern int (*perf_irq)(void); |
49 | extern int __weak get_c0_perfcount_int(void); | ||
49 | 50 | ||
50 | /* | 51 | /* |
51 | * Initialize the calling CPU's compare interrupt as clockevent device | 52 | * Initialize the calling CPU's compare interrupt as clockevent device |
52 | */ | 53 | */ |
53 | extern unsigned int __weak get_c0_compare_int(void); | 54 | extern unsigned int __weak get_c0_compare_int(void); |
54 | extern int r4k_clockevent_init(void); | 55 | extern int r4k_clockevent_init(void); |
55 | extern int gic_clockevent_init(void); | ||
56 | 56 | ||
57 | static inline int mips_clockevent_init(void) | 57 | static inline int mips_clockevent_init(void) |
58 | { | 58 | { |
59 | #if defined(CONFIG_CEVT_GIC) | 59 | #ifdef CONFIG_CEVT_R4K |
60 | return (gic_clockevent_init() | r4k_clockevent_init()); | ||
61 | #elif defined(CONFIG_CEVT_R4K) | ||
62 | return r4k_clockevent_init(); | 60 | return r4k_clockevent_init(); |
63 | #else | 61 | #else |
64 | return -ENXIO; | 62 | return -ENXIO; |
diff --git a/arch/mips/include/asm/types.h b/arch/mips/include/asm/types.h index a845aafedee4..148d42a17f30 100644 --- a/arch/mips/include/asm/types.h +++ b/arch/mips/include/asm/types.h | |||
@@ -11,23 +11,7 @@ | |||
11 | #ifndef _ASM_TYPES_H | 11 | #ifndef _ASM_TYPES_H |
12 | #define _ASM_TYPES_H | 12 | #define _ASM_TYPES_H |
13 | 13 | ||
14 | # include <asm-generic/int-ll64.h> | 14 | #include <asm-generic/int-ll64.h> |
15 | #include <uapi/asm/types.h> | 15 | #include <uapi/asm/types.h> |
16 | 16 | ||
17 | /* | ||
18 | * These aren't exported outside the kernel to avoid name space clashes | ||
19 | */ | ||
20 | #ifndef __ASSEMBLY__ | ||
21 | |||
22 | /* | ||
23 | * Don't use phys_t. You've been warned. | ||
24 | */ | ||
25 | #ifdef CONFIG_64BIT_PHYS_ADDR | ||
26 | typedef unsigned long long phys_t; | ||
27 | #else | ||
28 | typedef unsigned long phys_t; | ||
29 | #endif | ||
30 | |||
31 | #endif /* __ASSEMBLY__ */ | ||
32 | |||
33 | #endif /* _ASM_TYPES_H */ | 17 | #endif /* _ASM_TYPES_H */ |
diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h index 22a5624e2fd2..bf8b32450ef6 100644 --- a/arch/mips/include/asm/uaccess.h +++ b/arch/mips/include/asm/uaccess.h | |||
@@ -1325,33 +1325,6 @@ strncpy_from_user(char *__to, const char __user *__from, long __len) | |||
1325 | return res; | 1325 | return res; |
1326 | } | 1326 | } |
1327 | 1327 | ||
1328 | /* Returns: 0 if bad, string length+1 (memory size) of string if ok */ | ||
1329 | static inline long __strlen_user(const char __user *s) | ||
1330 | { | ||
1331 | long res; | ||
1332 | |||
1333 | if (segment_eq(get_fs(), get_ds())) { | ||
1334 | __asm__ __volatile__( | ||
1335 | "move\t$4, %1\n\t" | ||
1336 | __MODULE_JAL(__strlen_kernel_nocheck_asm) | ||
1337 | "move\t%0, $2" | ||
1338 | : "=r" (res) | ||
1339 | : "r" (s) | ||
1340 | : "$2", "$4", __UA_t0, "$31"); | ||
1341 | } else { | ||
1342 | might_fault(); | ||
1343 | __asm__ __volatile__( | ||
1344 | "move\t$4, %1\n\t" | ||
1345 | __MODULE_JAL(__strlen_user_nocheck_asm) | ||
1346 | "move\t%0, $2" | ||
1347 | : "=r" (res) | ||
1348 | : "r" (s) | ||
1349 | : "$2", "$4", __UA_t0, "$31"); | ||
1350 | } | ||
1351 | |||
1352 | return res; | ||
1353 | } | ||
1354 | |||
1355 | /* | 1328 | /* |
1356 | * strlen_user: - Get the size of a string in user space. | 1329 | * strlen_user: - Get the size of a string in user space. |
1357 | * @str: The string to measure. | 1330 | * @str: The string to measure. |
diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h index 708c5d414905..fc1cdd25fcda 100644 --- a/arch/mips/include/asm/uasm.h +++ b/arch/mips/include/asm/uasm.h | |||
@@ -136,9 +136,11 @@ Ip_u1s2(_lui); | |||
136 | Ip_u2s3u1(_lw); | 136 | Ip_u2s3u1(_lw); |
137 | Ip_u3u1u2(_lwx); | 137 | Ip_u3u1u2(_lwx); |
138 | Ip_u1u2u3(_mfc0); | 138 | Ip_u1u2u3(_mfc0); |
139 | Ip_u1u2u3(_mfhc0); | ||
139 | Ip_u1(_mfhi); | 140 | Ip_u1(_mfhi); |
140 | Ip_u1(_mflo); | 141 | Ip_u1(_mflo); |
141 | Ip_u1u2u3(_mtc0); | 142 | Ip_u1u2u3(_mtc0); |
143 | Ip_u1u2u3(_mthc0); | ||
142 | Ip_u3u1u2(_mul); | 144 | Ip_u3u1u2(_mul); |
143 | Ip_u3u1u2(_or); | 145 | Ip_u3u1u2(_or); |
144 | Ip_u2u1u3(_ori); | 146 | Ip_u2u1u3(_ori); |
diff --git a/arch/mips/include/uapi/asm/inst.h b/arch/mips/include/uapi/asm/inst.h index 4bfdb9d4c186..89c22433b1c6 100644 --- a/arch/mips/include/uapi/asm/inst.h +++ b/arch/mips/include/uapi/asm/inst.h | |||
@@ -108,9 +108,10 @@ enum rt_op { | |||
108 | */ | 108 | */ |
109 | enum cop_op { | 109 | enum cop_op { |
110 | mfc_op = 0x00, dmfc_op = 0x01, | 110 | mfc_op = 0x00, dmfc_op = 0x01, |
111 | cfc_op = 0x02, mfhc_op = 0x03, | 111 | cfc_op = 0x02, mfhc0_op = 0x02, |
112 | mtc_op = 0x04, dmtc_op = 0x05, | 112 | mfhc_op = 0x03, mtc_op = 0x04, |
113 | ctc_op = 0x06, mthc_op = 0x07, | 113 | dmtc_op = 0x05, ctc_op = 0x06, |
114 | mthc0_op = 0x06, mthc_op = 0x07, | ||
114 | bc_op = 0x08, cop_op = 0x10, | 115 | bc_op = 0x08, cop_op = 0x10, |
115 | copm_op = 0x18 | 116 | copm_op = 0x18 |
116 | }; | 117 | }; |
diff --git a/arch/mips/jz4740/setup.c b/arch/mips/jz4740/setup.c index 76eafcb79c89..ef796f97b996 100644 --- a/arch/mips/jz4740/setup.c +++ b/arch/mips/jz4740/setup.c | |||
@@ -32,7 +32,7 @@ static void __init jz4740_detect_mem(void) | |||
32 | { | 32 | { |
33 | void __iomem *jz_emc_base; | 33 | void __iomem *jz_emc_base; |
34 | u32 ctrl, bus, bank, rows, cols; | 34 | u32 ctrl, bus, bank, rows, cols; |
35 | phys_t size; | 35 | phys_addr_t size; |
36 | 36 | ||
37 | jz_emc_base = ioremap(JZ4740_EMC_BASE_ADDR, 0x100); | 37 | jz_emc_base = ioremap(JZ4740_EMC_BASE_ADDR, 0x100); |
38 | ctrl = readl(jz_emc_base + JZ4740_EMC_SDRAM_CTRL); | 38 | ctrl = readl(jz_emc_base + JZ4740_EMC_SDRAM_CTRL); |
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 008a2fed0584..92987d1bbe5f 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile | |||
@@ -4,9 +4,10 @@ | |||
4 | 4 | ||
5 | extra-y := head.o vmlinux.lds | 5 | extra-y := head.o vmlinux.lds |
6 | 6 | ||
7 | obj-y += cpu-probe.o branch.o entry.o genex.o idle.o irq.o process.o \ | 7 | obj-y += cpu-probe.o branch.o elf.o entry.o genex.o idle.o irq.o \ |
8 | prom.o ptrace.o reset.o setup.o signal.o syscall.o \ | 8 | process.o prom.o ptrace.o reset.o setup.o signal.o \ |
9 | time.o topology.o traps.o unaligned.o watch.o vdso.o | 9 | syscall.o time.o topology.o traps.o unaligned.o watch.o \ |
10 | vdso.o | ||
10 | 11 | ||
11 | ifdef CONFIG_FUNCTION_TRACER | 12 | ifdef CONFIG_FUNCTION_TRACER |
12 | CFLAGS_REMOVE_ftrace.o = -pg | 13 | CFLAGS_REMOVE_ftrace.o = -pg |
@@ -18,12 +19,10 @@ endif | |||
18 | obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o | 19 | obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o |
19 | obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o | 20 | obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o |
20 | obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o | 21 | obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o |
21 | obj-$(CONFIG_CEVT_GIC) += cevt-gic.o | ||
22 | obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o | 22 | obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o |
23 | obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o | 23 | obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o |
24 | obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o | 24 | obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o |
25 | obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o | 25 | obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o |
26 | obj-$(CONFIG_CSRC_GIC) += csrc-gic.o | ||
27 | obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o | 26 | obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o |
28 | obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o | 27 | obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o |
29 | obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o | 28 | obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o |
@@ -68,7 +67,6 @@ obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o | |||
68 | obj-$(CONFIG_MIPS_MSC) += irq-msc01.o | 67 | obj-$(CONFIG_MIPS_MSC) += irq-msc01.o |
69 | obj-$(CONFIG_IRQ_TXX9) += irq_txx9.o | 68 | obj-$(CONFIG_IRQ_TXX9) += irq_txx9.o |
70 | obj-$(CONFIG_IRQ_GT641XX) += irq-gt641xx.o | 69 | obj-$(CONFIG_IRQ_GT641XX) += irq-gt641xx.o |
71 | obj-$(CONFIG_IRQ_GIC) += irq-gic.o | ||
72 | 70 | ||
73 | obj-$(CONFIG_KPROBES) += kprobes.o | 71 | obj-$(CONFIG_KPROBES) += kprobes.o |
74 | obj-$(CONFIG_32BIT) += scall32-o32.o | 72 | obj-$(CONFIG_32BIT) += scall32-o32.o |
diff --git a/arch/mips/kernel/cevt-gic.c b/arch/mips/kernel/cevt-gic.c deleted file mode 100644 index 6093716980b9..000000000000 --- a/arch/mips/kernel/cevt-gic.c +++ /dev/null | |||
@@ -1,105 +0,0 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2013 Imagination Technologies Ltd. | ||
7 | */ | ||
8 | #include <linux/clockchips.h> | ||
9 | #include <linux/interrupt.h> | ||
10 | #include <linux/percpu.h> | ||
11 | #include <linux/smp.h> | ||
12 | #include <linux/irq.h> | ||
13 | |||
14 | #include <asm/time.h> | ||
15 | #include <asm/gic.h> | ||
16 | #include <asm/mips-boards/maltaint.h> | ||
17 | |||
18 | DEFINE_PER_CPU(struct clock_event_device, gic_clockevent_device); | ||
19 | int gic_timer_irq_installed; | ||
20 | |||
21 | |||
22 | static int gic_next_event(unsigned long delta, struct clock_event_device *evt) | ||
23 | { | ||
24 | u64 cnt; | ||
25 | int res; | ||
26 | |||
27 | cnt = gic_read_count(); | ||
28 | cnt += (u64)delta; | ||
29 | gic_write_cpu_compare(cnt, cpumask_first(evt->cpumask)); | ||
30 | res = ((int)(gic_read_count() - cnt) >= 0) ? -ETIME : 0; | ||
31 | return res; | ||
32 | } | ||
33 | |||
34 | void gic_set_clock_mode(enum clock_event_mode mode, | ||
35 | struct clock_event_device *evt) | ||
36 | { | ||
37 | /* Nothing to do ... */ | ||
38 | } | ||
39 | |||
40 | irqreturn_t gic_compare_interrupt(int irq, void *dev_id) | ||
41 | { | ||
42 | struct clock_event_device *cd; | ||
43 | int cpu = smp_processor_id(); | ||
44 | |||
45 | gic_write_compare(gic_read_compare()); | ||
46 | cd = &per_cpu(gic_clockevent_device, cpu); | ||
47 | cd->event_handler(cd); | ||
48 | return IRQ_HANDLED; | ||
49 | } | ||
50 | |||
51 | struct irqaction gic_compare_irqaction = { | ||
52 | .handler = gic_compare_interrupt, | ||
53 | .flags = IRQF_PERCPU | IRQF_TIMER, | ||
54 | .name = "timer", | ||
55 | }; | ||
56 | |||
57 | |||
58 | void gic_event_handler(struct clock_event_device *dev) | ||
59 | { | ||
60 | } | ||
61 | |||
62 | int gic_clockevent_init(void) | ||
63 | { | ||
64 | unsigned int cpu = smp_processor_id(); | ||
65 | struct clock_event_device *cd; | ||
66 | unsigned int irq; | ||
67 | |||
68 | if (!cpu_has_counter || !gic_frequency) | ||
69 | return -ENXIO; | ||
70 | |||
71 | irq = MIPS_GIC_IRQ_BASE; | ||
72 | |||
73 | cd = &per_cpu(gic_clockevent_device, cpu); | ||
74 | |||
75 | cd->name = "MIPS GIC"; | ||
76 | cd->features = CLOCK_EVT_FEAT_ONESHOT | | ||
77 | CLOCK_EVT_FEAT_C3STOP; | ||
78 | |||
79 | clockevent_set_clock(cd, gic_frequency); | ||
80 | |||
81 | /* Calculate the min / max delta */ | ||
82 | cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); | ||
83 | cd->min_delta_ns = clockevent_delta2ns(0x300, cd); | ||
84 | |||
85 | cd->rating = 300; | ||
86 | cd->irq = irq; | ||
87 | cd->cpumask = cpumask_of(cpu); | ||
88 | cd->set_next_event = gic_next_event; | ||
89 | cd->set_mode = gic_set_clock_mode; | ||
90 | cd->event_handler = gic_event_handler; | ||
91 | |||
92 | clockevents_register_device(cd); | ||
93 | |||
94 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_MAP), 0x80000002); | ||
95 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_SMASK), GIC_VPE_SMASK_CMP_MSK); | ||
96 | |||
97 | if (gic_timer_irq_installed) | ||
98 | return 0; | ||
99 | |||
100 | gic_timer_irq_installed = 1; | ||
101 | |||
102 | setup_irq(irq, &gic_compare_irqaction); | ||
103 | irq_set_handler(irq, handle_percpu_irq); | ||
104 | return 0; | ||
105 | } | ||
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index bc127e22fdab..6acaad0480af 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c | |||
@@ -11,10 +11,10 @@ | |||
11 | #include <linux/percpu.h> | 11 | #include <linux/percpu.h> |
12 | #include <linux/smp.h> | 12 | #include <linux/smp.h> |
13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
14 | #include <linux/irqchip/mips-gic.h> | ||
14 | 15 | ||
15 | #include <asm/time.h> | 16 | #include <asm/time.h> |
16 | #include <asm/cevt-r4k.h> | 17 | #include <asm/cevt-r4k.h> |
17 | #include <asm/gic.h> | ||
18 | 18 | ||
19 | static int mips_next_event(unsigned long delta, | 19 | static int mips_next_event(unsigned long delta, |
20 | struct clock_event_device *evt) | 20 | struct clock_event_device *evt) |
@@ -85,8 +85,8 @@ void mips_event_handler(struct clock_event_device *dev) | |||
85 | */ | 85 | */ |
86 | static int c0_compare_int_pending(void) | 86 | static int c0_compare_int_pending(void) |
87 | { | 87 | { |
88 | #ifdef CONFIG_IRQ_GIC | 88 | #ifdef CONFIG_MIPS_GIC |
89 | if (cpu_has_veic) | 89 | if (gic_present) |
90 | return gic_get_timer_pending(); | 90 | return gic_get_timer_pending(); |
91 | #endif | 91 | #endif |
92 | return (read_c0_cause() >> cp0_compare_irq_shift) & (1ul << CAUSEB_IP); | 92 | return (read_c0_cause() >> cp0_compare_irq_shift) & (1ul << CAUSEB_IP); |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index dc49cf30c2db..5342674842f5 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -69,6 +69,63 @@ static int __init htw_disable(char *s) | |||
69 | 69 | ||
70 | __setup("nohtw", htw_disable); | 70 | __setup("nohtw", htw_disable); |
71 | 71 | ||
72 | static int mips_ftlb_disabled; | ||
73 | static int mips_has_ftlb_configured; | ||
74 | |||
75 | static void set_ftlb_enable(struct cpuinfo_mips *c, int enable); | ||
76 | |||
77 | static int __init ftlb_disable(char *s) | ||
78 | { | ||
79 | unsigned int config4, mmuextdef; | ||
80 | |||
81 | /* | ||
82 | * If the core hasn't done any FTLB configuration, there is nothing | ||
83 | * for us to do here. | ||
84 | */ | ||
85 | if (!mips_has_ftlb_configured) | ||
86 | return 1; | ||
87 | |||
88 | /* Disable it in the boot cpu */ | ||
89 | set_ftlb_enable(&cpu_data[0], 0); | ||
90 | |||
91 | back_to_back_c0_hazard(); | ||
92 | |||
93 | config4 = read_c0_config4(); | ||
94 | |||
95 | /* Check that FTLB has been disabled */ | ||
96 | mmuextdef = config4 & MIPS_CONF4_MMUEXTDEF; | ||
97 | /* MMUSIZEEXT == VTLB ON, FTLB OFF */ | ||
98 | if (mmuextdef == MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT) { | ||
99 | /* This should never happen */ | ||
100 | pr_warn("FTLB could not be disabled!\n"); | ||
101 | return 1; | ||
102 | } | ||
103 | |||
104 | mips_ftlb_disabled = 1; | ||
105 | mips_has_ftlb_configured = 0; | ||
106 | |||
107 | /* | ||
108 | * noftlb is mainly used for debug purposes so print | ||
109 | * an informative message instead of using pr_debug() | ||
110 | */ | ||
111 | pr_info("FTLB has been disabled\n"); | ||
112 | |||
113 | /* | ||
114 | * Some of these bits are duplicated in the decode_config4. | ||
115 | * MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT is the only possible case | ||
116 | * once FTLB has been disabled so undo what decode_config4 did. | ||
117 | */ | ||
118 | cpu_data[0].tlbsize -= cpu_data[0].tlbsizeftlbways * | ||
119 | cpu_data[0].tlbsizeftlbsets; | ||
120 | cpu_data[0].tlbsizeftlbsets = 0; | ||
121 | cpu_data[0].tlbsizeftlbways = 0; | ||
122 | |||
123 | return 1; | ||
124 | } | ||
125 | |||
126 | __setup("noftlb", ftlb_disable); | ||
127 | |||
128 | |||
72 | static inline void check_errata(void) | 129 | static inline void check_errata(void) |
73 | { | 130 | { |
74 | struct cpuinfo_mips *c = ¤t_cpu_data; | 131 | struct cpuinfo_mips *c = ¤t_cpu_data; |
@@ -140,7 +197,7 @@ static inline unsigned long cpu_get_fpu_id(void) | |||
140 | */ | 197 | */ |
141 | static inline int __cpu_has_fpu(void) | 198 | static inline int __cpu_has_fpu(void) |
142 | { | 199 | { |
143 | return ((cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE); | 200 | return (cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE; |
144 | } | 201 | } |
145 | 202 | ||
146 | static inline unsigned long cpu_get_msa_id(void) | 203 | static inline unsigned long cpu_get_msa_id(void) |
@@ -399,6 +456,8 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c) | |||
399 | ftlb_page = MIPS_CONF4_VFTLBPAGESIZE; | 456 | ftlb_page = MIPS_CONF4_VFTLBPAGESIZE; |
400 | /* fall through */ | 457 | /* fall through */ |
401 | case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT: | 458 | case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT: |
459 | if (mips_ftlb_disabled) | ||
460 | break; | ||
402 | newcf4 = (config4 & ~ftlb_page) | | 461 | newcf4 = (config4 & ~ftlb_page) | |
403 | (page_size_ftlb(mmuextdef) << | 462 | (page_size_ftlb(mmuextdef) << |
404 | MIPS_CONF4_FTLBPAGESIZE_SHIFT); | 463 | MIPS_CONF4_FTLBPAGESIZE_SHIFT); |
@@ -418,6 +477,7 @@ static inline unsigned int decode_config4(struct cpuinfo_mips *c) | |||
418 | c->tlbsizeftlbways = ((config4 & MIPS_CONF4_FTLBWAYS) >> | 477 | c->tlbsizeftlbways = ((config4 & MIPS_CONF4_FTLBWAYS) >> |
419 | MIPS_CONF4_FTLBWAYS_SHIFT) + 2; | 478 | MIPS_CONF4_FTLBWAYS_SHIFT) + 2; |
420 | c->tlbsize += c->tlbsizeftlbways * c->tlbsizeftlbsets; | 479 | c->tlbsize += c->tlbsizeftlbways * c->tlbsizeftlbsets; |
480 | mips_has_ftlb_configured = 1; | ||
421 | break; | 481 | break; |
422 | } | 482 | } |
423 | } | 483 | } |
@@ -432,7 +492,7 @@ static inline unsigned int decode_config5(struct cpuinfo_mips *c) | |||
432 | unsigned int config5; | 492 | unsigned int config5; |
433 | 493 | ||
434 | config5 = read_c0_config5(); | 494 | config5 = read_c0_config5(); |
435 | config5 &= ~MIPS_CONF5_UFR; | 495 | config5 &= ~(MIPS_CONF5_UFR | MIPS_CONF5_UFE); |
436 | write_c0_config5(config5); | 496 | write_c0_config5(config5); |
437 | 497 | ||
438 | if (config5 & MIPS_CONF5_EVA) | 498 | if (config5 & MIPS_CONF5_EVA) |
@@ -453,8 +513,8 @@ static void decode_configs(struct cpuinfo_mips *c) | |||
453 | 513 | ||
454 | c->scache.flags = MIPS_CACHE_NOT_PRESENT; | 514 | c->scache.flags = MIPS_CACHE_NOT_PRESENT; |
455 | 515 | ||
456 | /* Enable FTLB if present */ | 516 | /* Enable FTLB if present and not disabled */ |
457 | set_ftlb_enable(c, 1); | 517 | set_ftlb_enable(c, !mips_ftlb_disabled); |
458 | 518 | ||
459 | ok = decode_config0(c); /* Read Config registers. */ | 519 | ok = decode_config0(c); /* Read Config registers. */ |
460 | BUG_ON(!ok); /* Arch spec violation! */ | 520 | BUG_ON(!ok); /* Arch spec violation! */ |
@@ -1058,6 +1118,7 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu) | |||
1058 | break; | 1118 | break; |
1059 | } | 1119 | } |
1060 | case PRID_IMP_BMIPS5000: | 1120 | case PRID_IMP_BMIPS5000: |
1121 | case PRID_IMP_BMIPS5200: | ||
1061 | c->cputype = CPU_BMIPS5000; | 1122 | c->cputype = CPU_BMIPS5000; |
1062 | __cpu_name[cpu] = "Broadcom BMIPS5000"; | 1123 | __cpu_name[cpu] = "Broadcom BMIPS5000"; |
1063 | set_elf_platform(cpu, "bmips5000"); | 1124 | set_elf_platform(cpu, "bmips5000"); |
@@ -1288,6 +1349,8 @@ void cpu_probe(void) | |||
1288 | MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) { | 1349 | MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) { |
1289 | if (c->fpu_id & MIPS_FPIR_3D) | 1350 | if (c->fpu_id & MIPS_FPIR_3D) |
1290 | c->ases |= MIPS_ASE_MIPS3D; | 1351 | c->ases |= MIPS_ASE_MIPS3D; |
1352 | if (c->fpu_id & MIPS_FPIR_FREP) | ||
1353 | c->options |= MIPS_CPU_FRE; | ||
1291 | } | 1354 | } |
1292 | } | 1355 | } |
1293 | 1356 | ||
diff --git a/arch/mips/kernel/crash_dump.c b/arch/mips/kernel/crash_dump.c index f291cf99b03a..6fe7790e5868 100644 --- a/arch/mips/kernel/crash_dump.c +++ b/arch/mips/kernel/crash_dump.c | |||
@@ -38,7 +38,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, | |||
38 | kunmap_atomic(vaddr); | 38 | kunmap_atomic(vaddr); |
39 | } else { | 39 | } else { |
40 | if (!kdump_buf_page) { | 40 | if (!kdump_buf_page) { |
41 | pr_warning("Kdump: Kdump buffer page not allocated\n"); | 41 | pr_warn("Kdump: Kdump buffer page not allocated\n"); |
42 | 42 | ||
43 | return -EFAULT; | 43 | return -EFAULT; |
44 | } | 44 | } |
@@ -57,7 +57,7 @@ static int __init kdump_buf_page_init(void) | |||
57 | 57 | ||
58 | kdump_buf_page = kmalloc(PAGE_SIZE, GFP_KERNEL); | 58 | kdump_buf_page = kmalloc(PAGE_SIZE, GFP_KERNEL); |
59 | if (!kdump_buf_page) { | 59 | if (!kdump_buf_page) { |
60 | pr_warning("Kdump: Failed to allocate kdump buffer page\n"); | 60 | pr_warn("Kdump: Failed to allocate kdump buffer page\n"); |
61 | ret = -ENOMEM; | 61 | ret = -ENOMEM; |
62 | } | 62 | } |
63 | 63 | ||
diff --git a/arch/mips/kernel/csrc-gic.c b/arch/mips/kernel/csrc-gic.c deleted file mode 100644 index e02620901117..000000000000 --- a/arch/mips/kernel/csrc-gic.c +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. | ||
7 | */ | ||
8 | #include <linux/init.h> | ||
9 | #include <linux/time.h> | ||
10 | |||
11 | #include <asm/gic.h> | ||
12 | |||
13 | static cycle_t gic_hpt_read(struct clocksource *cs) | ||
14 | { | ||
15 | return gic_read_count(); | ||
16 | } | ||
17 | |||
18 | static struct clocksource gic_clocksource = { | ||
19 | .name = "GIC", | ||
20 | .read = gic_hpt_read, | ||
21 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
22 | }; | ||
23 | |||
24 | void __init gic_clocksource_init(unsigned int frequency) | ||
25 | { | ||
26 | unsigned int config, bits; | ||
27 | |||
28 | /* Calculate the clocksource mask. */ | ||
29 | GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), config); | ||
30 | bits = 32 + ((config & GIC_SH_CONFIG_COUNTBITS_MSK) >> | ||
31 | (GIC_SH_CONFIG_COUNTBITS_SHF - 2)); | ||
32 | |||
33 | /* Set clocksource mask. */ | ||
34 | gic_clocksource.mask = CLOCKSOURCE_MASK(bits); | ||
35 | |||
36 | /* Calculate a somewhat reasonable rating value. */ | ||
37 | gic_clocksource.rating = 200 + frequency / 10000000; | ||
38 | |||
39 | clocksource_register_hz(&gic_clocksource, frequency); | ||
40 | } | ||
diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c new file mode 100644 index 000000000000..c92b15df6893 --- /dev/null +++ b/arch/mips/kernel/elf.c | |||
@@ -0,0 +1,191 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Imagination Technologies | ||
3 | * Author: Paul Burton <paul.burton@imgtec.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the | ||
7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
8 | * option) any later version. | ||
9 | */ | ||
10 | |||
11 | #include <linux/elf.h> | ||
12 | #include <linux/sched.h> | ||
13 | |||
14 | enum { | ||
15 | FP_ERROR = -1, | ||
16 | FP_DOUBLE_64A = -2, | ||
17 | }; | ||
18 | |||
19 | int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf, | ||
20 | bool is_interp, struct arch_elf_state *state) | ||
21 | { | ||
22 | struct elfhdr *ehdr = _ehdr; | ||
23 | struct elf_phdr *phdr = _phdr; | ||
24 | struct mips_elf_abiflags_v0 abiflags; | ||
25 | int ret; | ||
26 | |||
27 | if (config_enabled(CONFIG_64BIT) && | ||
28 | (ehdr->e_ident[EI_CLASS] != ELFCLASS32)) | ||
29 | return 0; | ||
30 | if (phdr->p_type != PT_MIPS_ABIFLAGS) | ||
31 | return 0; | ||
32 | if (phdr->p_filesz < sizeof(abiflags)) | ||
33 | return -EINVAL; | ||
34 | |||
35 | ret = kernel_read(elf, phdr->p_offset, (char *)&abiflags, | ||
36 | sizeof(abiflags)); | ||
37 | if (ret < 0) | ||
38 | return ret; | ||
39 | if (ret != sizeof(abiflags)) | ||
40 | return -EIO; | ||
41 | |||
42 | /* Record the required FP ABIs for use by mips_check_elf */ | ||
43 | if (is_interp) | ||
44 | state->interp_fp_abi = abiflags.fp_abi; | ||
45 | else | ||
46 | state->fp_abi = abiflags.fp_abi; | ||
47 | |||
48 | return 0; | ||
49 | } | ||
50 | |||
51 | static inline unsigned get_fp_abi(struct elfhdr *ehdr, int in_abi) | ||
52 | { | ||
53 | /* If the ABI requirement is provided, simply return that */ | ||
54 | if (in_abi != -1) | ||
55 | return in_abi; | ||
56 | |||
57 | /* If the EF_MIPS_FP64 flag was set, return MIPS_ABI_FP_64 */ | ||
58 | if (ehdr->e_flags & EF_MIPS_FP64) | ||
59 | return MIPS_ABI_FP_64; | ||
60 | |||
61 | /* Default to MIPS_ABI_FP_DOUBLE */ | ||
62 | return MIPS_ABI_FP_DOUBLE; | ||
63 | } | ||
64 | |||
65 | int arch_check_elf(void *_ehdr, bool has_interpreter, | ||
66 | struct arch_elf_state *state) | ||
67 | { | ||
68 | struct elfhdr *ehdr = _ehdr; | ||
69 | unsigned fp_abi, interp_fp_abi, abi0, abi1; | ||
70 | |||
71 | /* Ignore non-O32 binaries */ | ||
72 | if (config_enabled(CONFIG_64BIT) && | ||
73 | (ehdr->e_ident[EI_CLASS] != ELFCLASS32)) | ||
74 | return 0; | ||
75 | |||
76 | fp_abi = get_fp_abi(ehdr, state->fp_abi); | ||
77 | |||
78 | if (has_interpreter) { | ||
79 | interp_fp_abi = get_fp_abi(ehdr, state->interp_fp_abi); | ||
80 | |||
81 | abi0 = min(fp_abi, interp_fp_abi); | ||
82 | abi1 = max(fp_abi, interp_fp_abi); | ||
83 | } else { | ||
84 | abi0 = abi1 = fp_abi; | ||
85 | } | ||
86 | |||
87 | state->overall_abi = FP_ERROR; | ||
88 | |||
89 | if (abi0 == abi1) { | ||
90 | state->overall_abi = abi0; | ||
91 | } else if (abi0 == MIPS_ABI_FP_ANY) { | ||
92 | state->overall_abi = abi1; | ||
93 | } else if (abi0 == MIPS_ABI_FP_DOUBLE) { | ||
94 | switch (abi1) { | ||
95 | case MIPS_ABI_FP_XX: | ||
96 | state->overall_abi = MIPS_ABI_FP_DOUBLE; | ||
97 | break; | ||
98 | |||
99 | case MIPS_ABI_FP_64A: | ||
100 | state->overall_abi = FP_DOUBLE_64A; | ||
101 | break; | ||
102 | } | ||
103 | } else if (abi0 == MIPS_ABI_FP_SINGLE || | ||
104 | abi0 == MIPS_ABI_FP_SOFT) { | ||
105 | /* Cannot link with other ABIs */ | ||
106 | } else if (abi0 == MIPS_ABI_FP_OLD_64) { | ||
107 | switch (abi1) { | ||
108 | case MIPS_ABI_FP_XX: | ||
109 | case MIPS_ABI_FP_64: | ||
110 | case MIPS_ABI_FP_64A: | ||
111 | state->overall_abi = MIPS_ABI_FP_64; | ||
112 | break; | ||
113 | } | ||
114 | } else if (abi0 == MIPS_ABI_FP_XX || | ||
115 | abi0 == MIPS_ABI_FP_64 || | ||
116 | abi0 == MIPS_ABI_FP_64A) { | ||
117 | state->overall_abi = MIPS_ABI_FP_64; | ||
118 | } | ||
119 | |||
120 | switch (state->overall_abi) { | ||
121 | case MIPS_ABI_FP_64: | ||
122 | case MIPS_ABI_FP_64A: | ||
123 | case FP_DOUBLE_64A: | ||
124 | if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT)) | ||
125 | return -ELIBBAD; | ||
126 | break; | ||
127 | |||
128 | case FP_ERROR: | ||
129 | return -ELIBBAD; | ||
130 | } | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | void mips_set_personality_fp(struct arch_elf_state *state) | ||
136 | { | ||
137 | if (config_enabled(CONFIG_FP32XX_HYBRID_FPRS)) { | ||
138 | /* | ||
139 | * Use hybrid FPRs for all code which can correctly execute | ||
140 | * with that mode. | ||
141 | */ | ||
142 | switch (state->overall_abi) { | ||
143 | case MIPS_ABI_FP_DOUBLE: | ||
144 | case MIPS_ABI_FP_SINGLE: | ||
145 | case MIPS_ABI_FP_SOFT: | ||
146 | case MIPS_ABI_FP_XX: | ||
147 | case MIPS_ABI_FP_ANY: | ||
148 | /* FR=1, FRE=1 */ | ||
149 | clear_thread_flag(TIF_32BIT_FPREGS); | ||
150 | set_thread_flag(TIF_HYBRID_FPREGS); | ||
151 | return; | ||
152 | } | ||
153 | } | ||
154 | |||
155 | switch (state->overall_abi) { | ||
156 | case MIPS_ABI_FP_DOUBLE: | ||
157 | case MIPS_ABI_FP_SINGLE: | ||
158 | case MIPS_ABI_FP_SOFT: | ||
159 | /* FR=0 */ | ||
160 | set_thread_flag(TIF_32BIT_FPREGS); | ||
161 | clear_thread_flag(TIF_HYBRID_FPREGS); | ||
162 | break; | ||
163 | |||
164 | case FP_DOUBLE_64A: | ||
165 | /* FR=1, FRE=1 */ | ||
166 | clear_thread_flag(TIF_32BIT_FPREGS); | ||
167 | set_thread_flag(TIF_HYBRID_FPREGS); | ||
168 | break; | ||
169 | |||
170 | case MIPS_ABI_FP_64: | ||
171 | case MIPS_ABI_FP_64A: | ||
172 | /* FR=1, FRE=0 */ | ||
173 | clear_thread_flag(TIF_32BIT_FPREGS); | ||
174 | clear_thread_flag(TIF_HYBRID_FPREGS); | ||
175 | break; | ||
176 | |||
177 | case MIPS_ABI_FP_XX: | ||
178 | case MIPS_ABI_FP_ANY: | ||
179 | if (!config_enabled(CONFIG_MIPS_O32_FP64_SUPPORT)) | ||
180 | set_thread_flag(TIF_32BIT_FPREGS); | ||
181 | else | ||
182 | clear_thread_flag(TIF_32BIT_FPREGS); | ||
183 | |||
184 | clear_thread_flag(TIF_HYBRID_FPREGS); | ||
185 | break; | ||
186 | |||
187 | default: | ||
188 | case FP_ERROR: | ||
189 | BUG(); | ||
190 | } | ||
191 | } | ||
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index 50b364897dda..a74ec3ae557c 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/ioport.h> | 13 | #include <linux/ioport.h> |
14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
15 | #include <linux/irqdomain.h> | ||
15 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
16 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
17 | #include <linux/syscore_ops.h> | 18 | #include <linux/syscore_ops.h> |
@@ -308,6 +309,19 @@ static struct resource pic2_io_resource = { | |||
308 | .flags = IORESOURCE_BUSY | 309 | .flags = IORESOURCE_BUSY |
309 | }; | 310 | }; |
310 | 311 | ||
312 | static int i8259A_irq_domain_map(struct irq_domain *d, unsigned int virq, | ||
313 | irq_hw_number_t hw) | ||
314 | { | ||
315 | irq_set_chip_and_handler(virq, &i8259A_chip, handle_level_irq); | ||
316 | irq_set_probe(virq); | ||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | static struct irq_domain_ops i8259A_ops = { | ||
321 | .map = i8259A_irq_domain_map, | ||
322 | .xlate = irq_domain_xlate_onecell, | ||
323 | }; | ||
324 | |||
311 | /* | 325 | /* |
312 | * On systems with i8259-style interrupt controllers we assume for | 326 | * On systems with i8259-style interrupt controllers we assume for |
313 | * driver compatibility reasons interrupts 0 - 15 to be the i8259 | 327 | * driver compatibility reasons interrupts 0 - 15 to be the i8259 |
@@ -315,17 +329,17 @@ static struct resource pic2_io_resource = { | |||
315 | */ | 329 | */ |
316 | void __init init_i8259_irqs(void) | 330 | void __init init_i8259_irqs(void) |
317 | { | 331 | { |
318 | int i; | 332 | struct irq_domain *domain; |
319 | 333 | ||
320 | insert_resource(&ioport_resource, &pic1_io_resource); | 334 | insert_resource(&ioport_resource, &pic1_io_resource); |
321 | insert_resource(&ioport_resource, &pic2_io_resource); | 335 | insert_resource(&ioport_resource, &pic2_io_resource); |
322 | 336 | ||
323 | init_8259A(0); | 337 | init_8259A(0); |
324 | 338 | ||
325 | for (i = I8259A_IRQ_BASE; i < I8259A_IRQ_BASE + 16; i++) { | 339 | domain = irq_domain_add_legacy(NULL, 16, I8259A_IRQ_BASE, 0, |
326 | irq_set_chip_and_handler(i, &i8259A_chip, handle_level_irq); | 340 | &i8259A_ops, NULL); |
327 | irq_set_probe(i); | 341 | if (!domain) |
328 | } | 342 | panic("Failed to add i8259 IRQ domain"); |
329 | 343 | ||
330 | setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2); | 344 | setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2); |
331 | } | 345 | } |
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c deleted file mode 100644 index 9e9d8b9a5b97..000000000000 --- a/arch/mips/kernel/irq-gic.c +++ /dev/null | |||
@@ -1,402 +0,0 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2008 Ralf Baechle (ralf@linux-mips.org) | ||
7 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. | ||
8 | */ | ||
9 | #include <linux/bitmap.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/smp.h> | ||
12 | #include <linux/irq.h> | ||
13 | #include <linux/clocksource.h> | ||
14 | |||
15 | #include <asm/io.h> | ||
16 | #include <asm/gic.h> | ||
17 | #include <asm/setup.h> | ||
18 | #include <asm/traps.h> | ||
19 | #include <linux/hardirq.h> | ||
20 | #include <asm-generic/bitops/find.h> | ||
21 | |||
22 | unsigned int gic_frequency; | ||
23 | unsigned int gic_present; | ||
24 | unsigned long _gic_base; | ||
25 | unsigned int gic_irq_base; | ||
26 | unsigned int gic_irq_flags[GIC_NUM_INTRS]; | ||
27 | |||
28 | /* The index into this array is the vector # of the interrupt. */ | ||
29 | struct gic_shared_intr_map gic_shared_intr_map[GIC_NUM_INTRS]; | ||
30 | |||
31 | struct gic_pcpu_mask { | ||
32 | DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS); | ||
33 | }; | ||
34 | |||
35 | struct gic_pending_regs { | ||
36 | DECLARE_BITMAP(pending, GIC_NUM_INTRS); | ||
37 | }; | ||
38 | |||
39 | struct gic_intrmask_regs { | ||
40 | DECLARE_BITMAP(intrmask, GIC_NUM_INTRS); | ||
41 | }; | ||
42 | |||
43 | static struct gic_pcpu_mask pcpu_masks[NR_CPUS]; | ||
44 | static struct gic_pending_regs pending_regs[NR_CPUS]; | ||
45 | static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; | ||
46 | |||
47 | #if defined(CONFIG_CSRC_GIC) || defined(CONFIG_CEVT_GIC) | ||
48 | cycle_t gic_read_count(void) | ||
49 | { | ||
50 | unsigned int hi, hi2, lo; | ||
51 | |||
52 | do { | ||
53 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi); | ||
54 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), lo); | ||
55 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_63_32), hi2); | ||
56 | } while (hi2 != hi); | ||
57 | |||
58 | return (((cycle_t) hi) << 32) + lo; | ||
59 | } | ||
60 | |||
61 | void gic_write_compare(cycle_t cnt) | ||
62 | { | ||
63 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI), | ||
64 | (int)(cnt >> 32)); | ||
65 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO), | ||
66 | (int)(cnt & 0xffffffff)); | ||
67 | } | ||
68 | |||
69 | void gic_write_cpu_compare(cycle_t cnt, int cpu) | ||
70 | { | ||
71 | unsigned long flags; | ||
72 | |||
73 | local_irq_save(flags); | ||
74 | |||
75 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), cpu); | ||
76 | GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_HI), | ||
77 | (int)(cnt >> 32)); | ||
78 | GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_LO), | ||
79 | (int)(cnt & 0xffffffff)); | ||
80 | |||
81 | local_irq_restore(flags); | ||
82 | } | ||
83 | |||
84 | cycle_t gic_read_compare(void) | ||
85 | { | ||
86 | unsigned int hi, lo; | ||
87 | |||
88 | GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI), hi); | ||
89 | GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO), lo); | ||
90 | |||
91 | return (((cycle_t) hi) << 32) + lo; | ||
92 | } | ||
93 | #endif | ||
94 | |||
95 | unsigned int gic_get_timer_pending(void) | ||
96 | { | ||
97 | unsigned int vpe_pending; | ||
98 | |||
99 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0); | ||
100 | GICREAD(GIC_REG(VPE_OTHER, GIC_VPE_PEND), vpe_pending); | ||
101 | return (vpe_pending & GIC_VPE_PEND_TIMER_MSK); | ||
102 | } | ||
103 | |||
104 | void gic_bind_eic_interrupt(int irq, int set) | ||
105 | { | ||
106 | /* Convert irq vector # to hw int # */ | ||
107 | irq -= GIC_PIN_TO_VEC_OFFSET; | ||
108 | |||
109 | /* Set irq to use shadow set */ | ||
110 | GICWRITE(GIC_REG_ADDR(VPE_LOCAL, GIC_VPE_EIC_SS(irq)), set); | ||
111 | } | ||
112 | |||
113 | void gic_send_ipi(unsigned int intr) | ||
114 | { | ||
115 | GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), 0x80000000 | intr); | ||
116 | } | ||
117 | |||
118 | static void gic_eic_irq_dispatch(void) | ||
119 | { | ||
120 | unsigned int cause = read_c0_cause(); | ||
121 | int irq; | ||
122 | |||
123 | irq = (cause & ST0_IM) >> STATUSB_IP2; | ||
124 | if (irq == 0) | ||
125 | irq = -1; | ||
126 | |||
127 | if (irq >= 0) | ||
128 | do_IRQ(gic_irq_base + irq); | ||
129 | else | ||
130 | spurious_interrupt(); | ||
131 | } | ||
132 | |||
133 | static void __init vpe_local_setup(unsigned int numvpes) | ||
134 | { | ||
135 | unsigned long timer_intr = GIC_INT_TMR; | ||
136 | unsigned long perf_intr = GIC_INT_PERFCTR; | ||
137 | unsigned int vpe_ctl; | ||
138 | int i; | ||
139 | |||
140 | if (cpu_has_veic) { | ||
141 | /* | ||
142 | * GIC timer interrupt -> CPU HW Int X (vector X+2) -> | ||
143 | * map to pin X+2-1 (since GIC adds 1) | ||
144 | */ | ||
145 | timer_intr += (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET); | ||
146 | /* | ||
147 | * GIC perfcnt interrupt -> CPU HW Int X (vector X+2) -> | ||
148 | * map to pin X+2-1 (since GIC adds 1) | ||
149 | */ | ||
150 | perf_intr += (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET); | ||
151 | } | ||
152 | |||
153 | /* | ||
154 | * Setup the default performance counter timer interrupts | ||
155 | * for all VPEs | ||
156 | */ | ||
157 | for (i = 0; i < numvpes; i++) { | ||
158 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), i); | ||
159 | |||
160 | /* Are Interrupts locally routable? */ | ||
161 | GICREAD(GIC_REG(VPE_OTHER, GIC_VPE_CTL), vpe_ctl); | ||
162 | if (vpe_ctl & GIC_VPE_CTL_TIMER_RTBL_MSK) | ||
163 | GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP), | ||
164 | GIC_MAP_TO_PIN_MSK | timer_intr); | ||
165 | if (cpu_has_veic) { | ||
166 | set_vi_handler(timer_intr + GIC_PIN_TO_VEC_OFFSET, | ||
167 | gic_eic_irq_dispatch); | ||
168 | gic_shared_intr_map[timer_intr + GIC_PIN_TO_VEC_OFFSET].local_intr_mask |= GIC_VPE_RMASK_TIMER_MSK; | ||
169 | } | ||
170 | |||
171 | if (vpe_ctl & GIC_VPE_CTL_PERFCNT_RTBL_MSK) | ||
172 | GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_PERFCTR_MAP), | ||
173 | GIC_MAP_TO_PIN_MSK | perf_intr); | ||
174 | if (cpu_has_veic) { | ||
175 | set_vi_handler(perf_intr + GIC_PIN_TO_VEC_OFFSET, gic_eic_irq_dispatch); | ||
176 | gic_shared_intr_map[perf_intr + GIC_PIN_TO_VEC_OFFSET].local_intr_mask |= GIC_VPE_RMASK_PERFCNT_MSK; | ||
177 | } | ||
178 | } | ||
179 | } | ||
180 | |||
181 | unsigned int gic_compare_int(void) | ||
182 | { | ||
183 | unsigned int pending; | ||
184 | |||
185 | GICREAD(GIC_REG(VPE_LOCAL, GIC_VPE_PEND), pending); | ||
186 | if (pending & GIC_VPE_PEND_CMP_MSK) | ||
187 | return 1; | ||
188 | else | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | void gic_get_int_mask(unsigned long *dst, const unsigned long *src) | ||
193 | { | ||
194 | unsigned int i; | ||
195 | unsigned long *pending, *intrmask, *pcpu_mask; | ||
196 | unsigned long *pending_abs, *intrmask_abs; | ||
197 | |||
198 | /* Get per-cpu bitmaps */ | ||
199 | pending = pending_regs[smp_processor_id()].pending; | ||
200 | intrmask = intrmask_regs[smp_processor_id()].intrmask; | ||
201 | pcpu_mask = pcpu_masks[smp_processor_id()].pcpu_mask; | ||
202 | |||
203 | pending_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED, | ||
204 | GIC_SH_PEND_31_0_OFS); | ||
205 | intrmask_abs = (unsigned long *) GIC_REG_ABS_ADDR(SHARED, | ||
206 | GIC_SH_MASK_31_0_OFS); | ||
207 | |||
208 | for (i = 0; i < BITS_TO_LONGS(GIC_NUM_INTRS); i++) { | ||
209 | GICREAD(*pending_abs, pending[i]); | ||
210 | GICREAD(*intrmask_abs, intrmask[i]); | ||
211 | pending_abs++; | ||
212 | intrmask_abs++; | ||
213 | } | ||
214 | |||
215 | bitmap_and(pending, pending, intrmask, GIC_NUM_INTRS); | ||
216 | bitmap_and(pending, pending, pcpu_mask, GIC_NUM_INTRS); | ||
217 | bitmap_and(dst, src, pending, GIC_NUM_INTRS); | ||
218 | } | ||
219 | |||
220 | unsigned int gic_get_int(void) | ||
221 | { | ||
222 | DECLARE_BITMAP(interrupts, GIC_NUM_INTRS); | ||
223 | |||
224 | bitmap_fill(interrupts, GIC_NUM_INTRS); | ||
225 | gic_get_int_mask(interrupts, interrupts); | ||
226 | |||
227 | return find_first_bit(interrupts, GIC_NUM_INTRS); | ||
228 | } | ||
229 | |||
230 | static void gic_mask_irq(struct irq_data *d) | ||
231 | { | ||
232 | GIC_CLR_INTR_MASK(d->irq - gic_irq_base); | ||
233 | } | ||
234 | |||
235 | static void gic_unmask_irq(struct irq_data *d) | ||
236 | { | ||
237 | GIC_SET_INTR_MASK(d->irq - gic_irq_base); | ||
238 | } | ||
239 | |||
240 | #ifdef CONFIG_SMP | ||
241 | static DEFINE_SPINLOCK(gic_lock); | ||
242 | |||
243 | static int gic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, | ||
244 | bool force) | ||
245 | { | ||
246 | unsigned int irq = (d->irq - gic_irq_base); | ||
247 | cpumask_t tmp = CPU_MASK_NONE; | ||
248 | unsigned long flags; | ||
249 | int i; | ||
250 | |||
251 | cpumask_and(&tmp, cpumask, cpu_online_mask); | ||
252 | if (cpus_empty(tmp)) | ||
253 | return -1; | ||
254 | |||
255 | /* Assumption : cpumask refers to a single CPU */ | ||
256 | spin_lock_irqsave(&gic_lock, flags); | ||
257 | |||
258 | /* Re-route this IRQ */ | ||
259 | GIC_SH_MAP_TO_VPE_SMASK(irq, first_cpu(tmp)); | ||
260 | |||
261 | /* Update the pcpu_masks */ | ||
262 | for (i = 0; i < NR_CPUS; i++) | ||
263 | clear_bit(irq, pcpu_masks[i].pcpu_mask); | ||
264 | set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask); | ||
265 | |||
266 | cpumask_copy(d->affinity, cpumask); | ||
267 | spin_unlock_irqrestore(&gic_lock, flags); | ||
268 | |||
269 | return IRQ_SET_MASK_OK_NOCOPY; | ||
270 | } | ||
271 | #endif | ||
272 | |||
273 | static struct irq_chip gic_irq_controller = { | ||
274 | .name = "MIPS GIC", | ||
275 | .irq_ack = gic_irq_ack, | ||
276 | .irq_mask = gic_mask_irq, | ||
277 | .irq_mask_ack = gic_mask_irq, | ||
278 | .irq_unmask = gic_unmask_irq, | ||
279 | .irq_eoi = gic_finish_irq, | ||
280 | #ifdef CONFIG_SMP | ||
281 | .irq_set_affinity = gic_set_affinity, | ||
282 | #endif | ||
283 | }; | ||
284 | |||
285 | static void __init gic_setup_intr(unsigned int intr, unsigned int cpu, | ||
286 | unsigned int pin, unsigned int polarity, unsigned int trigtype, | ||
287 | unsigned int flags) | ||
288 | { | ||
289 | struct gic_shared_intr_map *map_ptr; | ||
290 | |||
291 | /* Setup Intr to Pin mapping */ | ||
292 | if (pin & GIC_MAP_TO_NMI_MSK) { | ||
293 | int i; | ||
294 | |||
295 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), pin); | ||
296 | /* FIXME: hack to route NMI to all cpu's */ | ||
297 | for (i = 0; i < NR_CPUS; i += 32) { | ||
298 | GICWRITE(GIC_REG_ADDR(SHARED, | ||
299 | GIC_SH_MAP_TO_VPE_REG_OFF(intr, i)), | ||
300 | 0xffffffff); | ||
301 | } | ||
302 | } else { | ||
303 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), | ||
304 | GIC_MAP_TO_PIN_MSK | pin); | ||
305 | /* Setup Intr to CPU mapping */ | ||
306 | GIC_SH_MAP_TO_VPE_SMASK(intr, cpu); | ||
307 | if (cpu_has_veic) { | ||
308 | set_vi_handler(pin + GIC_PIN_TO_VEC_OFFSET, | ||
309 | gic_eic_irq_dispatch); | ||
310 | map_ptr = &gic_shared_intr_map[pin + GIC_PIN_TO_VEC_OFFSET]; | ||
311 | if (map_ptr->num_shared_intr >= GIC_MAX_SHARED_INTR) | ||
312 | BUG(); | ||
313 | map_ptr->intr_list[map_ptr->num_shared_intr++] = intr; | ||
314 | } | ||
315 | } | ||
316 | |||
317 | /* Setup Intr Polarity */ | ||
318 | GIC_SET_POLARITY(intr, polarity); | ||
319 | |||
320 | /* Setup Intr Trigger Type */ | ||
321 | GIC_SET_TRIGGER(intr, trigtype); | ||
322 | |||
323 | /* Init Intr Masks */ | ||
324 | GIC_CLR_INTR_MASK(intr); | ||
325 | |||
326 | /* Initialise per-cpu Interrupt software masks */ | ||
327 | set_bit(intr, pcpu_masks[cpu].pcpu_mask); | ||
328 | |||
329 | if ((flags & GIC_FLAG_TRANSPARENT) && (cpu_has_veic == 0)) | ||
330 | GIC_SET_INTR_MASK(intr); | ||
331 | if (trigtype == GIC_TRIG_EDGE) | ||
332 | gic_irq_flags[intr] |= GIC_TRIG_EDGE; | ||
333 | } | ||
334 | |||
335 | static void __init gic_basic_init(int numintrs, int numvpes, | ||
336 | struct gic_intr_map *intrmap, int mapsize) | ||
337 | { | ||
338 | unsigned int i, cpu; | ||
339 | unsigned int pin_offset = 0; | ||
340 | |||
341 | board_bind_eic_interrupt = &gic_bind_eic_interrupt; | ||
342 | |||
343 | /* Setup defaults */ | ||
344 | for (i = 0; i < numintrs; i++) { | ||
345 | GIC_SET_POLARITY(i, GIC_POL_POS); | ||
346 | GIC_SET_TRIGGER(i, GIC_TRIG_LEVEL); | ||
347 | GIC_CLR_INTR_MASK(i); | ||
348 | if (i < GIC_NUM_INTRS) { | ||
349 | gic_irq_flags[i] = 0; | ||
350 | gic_shared_intr_map[i].num_shared_intr = 0; | ||
351 | gic_shared_intr_map[i].local_intr_mask = 0; | ||
352 | } | ||
353 | } | ||
354 | |||
355 | /* | ||
356 | * In EIC mode, the HW_INT# is offset by (2-1). Need to subtract | ||
357 | * one because the GIC will add one (since 0=no intr). | ||
358 | */ | ||
359 | if (cpu_has_veic) | ||
360 | pin_offset = (GIC_CPU_TO_VEC_OFFSET - GIC_PIN_TO_VEC_OFFSET); | ||
361 | |||
362 | /* Setup specifics */ | ||
363 | for (i = 0; i < mapsize; i++) { | ||
364 | cpu = intrmap[i].cpunum; | ||
365 | if (cpu == GIC_UNUSED) | ||
366 | continue; | ||
367 | gic_setup_intr(i, | ||
368 | intrmap[i].cpunum, | ||
369 | intrmap[i].pin + pin_offset, | ||
370 | intrmap[i].polarity, | ||
371 | intrmap[i].trigtype, | ||
372 | intrmap[i].flags); | ||
373 | } | ||
374 | |||
375 | vpe_local_setup(numvpes); | ||
376 | } | ||
377 | |||
378 | void __init gic_init(unsigned long gic_base_addr, | ||
379 | unsigned long gic_addrspace_size, | ||
380 | struct gic_intr_map *intr_map, unsigned int intr_map_size, | ||
381 | unsigned int irqbase) | ||
382 | { | ||
383 | unsigned int gicconfig; | ||
384 | int numvpes, numintrs; | ||
385 | |||
386 | _gic_base = (unsigned long) ioremap_nocache(gic_base_addr, | ||
387 | gic_addrspace_size); | ||
388 | gic_irq_base = irqbase; | ||
389 | |||
390 | GICREAD(GIC_REG(SHARED, GIC_SH_CONFIG), gicconfig); | ||
391 | numintrs = (gicconfig & GIC_SH_CONFIG_NUMINTRS_MSK) >> | ||
392 | GIC_SH_CONFIG_NUMINTRS_SHF; | ||
393 | numintrs = ((numintrs + 1) * 8); | ||
394 | |||
395 | numvpes = (gicconfig & GIC_SH_CONFIG_NUMVPES_MSK) >> | ||
396 | GIC_SH_CONFIG_NUMVPES_SHF; | ||
397 | numvpes = numvpes + 1; | ||
398 | |||
399 | gic_basic_init(numintrs, numvpes, intr_map, intr_map_size); | ||
400 | |||
401 | gic_platform_init(numintrs, &gic_irq_controller); | ||
402 | } | ||
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c index e498f2b3646a..590c2c980fd3 100644 --- a/arch/mips/kernel/irq_cpu.c +++ b/arch/mips/kernel/irq_cpu.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <asm/irq_cpu.h> | 36 | #include <asm/irq_cpu.h> |
37 | #include <asm/mipsregs.h> | 37 | #include <asm/mipsregs.h> |
38 | #include <asm/mipsmtregs.h> | 38 | #include <asm/mipsmtregs.h> |
39 | #include <asm/setup.h> | ||
39 | 40 | ||
40 | static inline void unmask_mips_irq(struct irq_data *d) | 41 | static inline void unmask_mips_irq(struct irq_data *d) |
41 | { | 42 | { |
@@ -94,28 +95,24 @@ static struct irq_chip mips_mt_cpu_irq_controller = { | |||
94 | .irq_eoi = unmask_mips_irq, | 95 | .irq_eoi = unmask_mips_irq, |
95 | }; | 96 | }; |
96 | 97 | ||
97 | void __init mips_cpu_irq_init(void) | 98 | asmlinkage void __weak plat_irq_dispatch(void) |
98 | { | 99 | { |
99 | int irq_base = MIPS_CPU_IRQ_BASE; | 100 | unsigned long pending = read_c0_cause() & read_c0_status() & ST0_IM; |
100 | int i; | 101 | int irq; |
101 | 102 | ||
102 | /* Mask interrupts. */ | 103 | if (!pending) { |
103 | clear_c0_status(ST0_IM); | 104 | spurious_interrupt(); |
104 | clear_c0_cause(CAUSEF_IP); | 105 | return; |
105 | 106 | } | |
106 | /* Software interrupts are used for MT/CMT IPI */ | ||
107 | for (i = irq_base; i < irq_base + 2; i++) | ||
108 | irq_set_chip_and_handler(i, cpu_has_mipsmt ? | ||
109 | &mips_mt_cpu_irq_controller : | ||
110 | &mips_cpu_irq_controller, | ||
111 | handle_percpu_irq); | ||
112 | 107 | ||
113 | for (i = irq_base + 2; i < irq_base + 8; i++) | 108 | pending >>= CAUSEB_IP; |
114 | irq_set_chip_and_handler(i, &mips_cpu_irq_controller, | 109 | while (pending) { |
115 | handle_percpu_irq); | 110 | irq = fls(pending) - 1; |
111 | do_IRQ(MIPS_CPU_IRQ_BASE + irq); | ||
112 | pending &= ~BIT(irq); | ||
113 | } | ||
116 | } | 114 | } |
117 | 115 | ||
118 | #ifdef CONFIG_IRQ_DOMAIN | ||
119 | static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq, | 116 | static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq, |
120 | irq_hw_number_t hw) | 117 | irq_hw_number_t hw) |
121 | { | 118 | { |
@@ -128,6 +125,9 @@ static int mips_cpu_intc_map(struct irq_domain *d, unsigned int irq, | |||
128 | chip = &mips_cpu_irq_controller; | 125 | chip = &mips_cpu_irq_controller; |
129 | } | 126 | } |
130 | 127 | ||
128 | if (cpu_has_vint) | ||
129 | set_vi_handler(hw, plat_irq_dispatch); | ||
130 | |||
131 | irq_set_chip_and_handler(irq, chip, handle_percpu_irq); | 131 | irq_set_chip_and_handler(irq, chip, handle_percpu_irq); |
132 | 132 | ||
133 | return 0; | 133 | return 0; |
@@ -138,8 +138,7 @@ static const struct irq_domain_ops mips_cpu_intc_irq_domain_ops = { | |||
138 | .xlate = irq_domain_xlate_onecell, | 138 | .xlate = irq_domain_xlate_onecell, |
139 | }; | 139 | }; |
140 | 140 | ||
141 | int __init mips_cpu_intc_init(struct device_node *of_node, | 141 | static void __init __mips_cpu_irq_init(struct device_node *of_node) |
142 | struct device_node *parent) | ||
143 | { | 142 | { |
144 | struct irq_domain *domain; | 143 | struct irq_domain *domain; |
145 | 144 | ||
@@ -151,7 +150,16 @@ int __init mips_cpu_intc_init(struct device_node *of_node, | |||
151 | &mips_cpu_intc_irq_domain_ops, NULL); | 150 | &mips_cpu_intc_irq_domain_ops, NULL); |
152 | if (!domain) | 151 | if (!domain) |
153 | panic("Failed to add irqdomain for MIPS CPU"); | 152 | panic("Failed to add irqdomain for MIPS CPU"); |
153 | } | ||
154 | 154 | ||
155 | void __init mips_cpu_irq_init(void) | ||
156 | { | ||
157 | __mips_cpu_irq_init(NULL); | ||
158 | } | ||
159 | |||
160 | int __init mips_cpu_irq_of_init(struct device_node *of_node, | ||
161 | struct device_node *parent) | ||
162 | { | ||
163 | __mips_cpu_irq_init(of_node); | ||
155 | return 0; | 164 | return 0; |
156 | } | 165 | } |
157 | #endif /* CONFIG_IRQ_DOMAIN */ | ||
diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c index f76f7a08412d..85bbe9b96759 100644 --- a/arch/mips/kernel/mips-cm.c +++ b/arch/mips/kernel/mips-cm.c | |||
@@ -16,7 +16,7 @@ | |||
16 | void __iomem *mips_cm_base; | 16 | void __iomem *mips_cm_base; |
17 | void __iomem *mips_cm_l2sync_base; | 17 | void __iomem *mips_cm_l2sync_base; |
18 | 18 | ||
19 | phys_t __mips_cm_phys_base(void) | 19 | phys_addr_t __mips_cm_phys_base(void) |
20 | { | 20 | { |
21 | u32 config3 = read_c0_config3(); | 21 | u32 config3 = read_c0_config3(); |
22 | u32 cmgcr; | 22 | u32 cmgcr; |
@@ -30,10 +30,10 @@ phys_t __mips_cm_phys_base(void) | |||
30 | return (cmgcr & MIPS_CMGCRF_BASE) << (36 - 32); | 30 | return (cmgcr & MIPS_CMGCRF_BASE) << (36 - 32); |
31 | } | 31 | } |
32 | 32 | ||
33 | phys_t mips_cm_phys_base(void) | 33 | phys_addr_t mips_cm_phys_base(void) |
34 | __attribute__((weak, alias("__mips_cm_phys_base"))); | 34 | __attribute__((weak, alias("__mips_cm_phys_base"))); |
35 | 35 | ||
36 | phys_t __mips_cm_l2sync_phys_base(void) | 36 | phys_addr_t __mips_cm_l2sync_phys_base(void) |
37 | { | 37 | { |
38 | u32 base_reg; | 38 | u32 base_reg; |
39 | 39 | ||
@@ -49,13 +49,13 @@ phys_t __mips_cm_l2sync_phys_base(void) | |||
49 | return mips_cm_phys_base() + MIPS_CM_GCR_SIZE; | 49 | return mips_cm_phys_base() + MIPS_CM_GCR_SIZE; |
50 | } | 50 | } |
51 | 51 | ||
52 | phys_t mips_cm_l2sync_phys_base(void) | 52 | phys_addr_t mips_cm_l2sync_phys_base(void) |
53 | __attribute__((weak, alias("__mips_cm_l2sync_phys_base"))); | 53 | __attribute__((weak, alias("__mips_cm_l2sync_phys_base"))); |
54 | 54 | ||
55 | static void mips_cm_probe_l2sync(void) | 55 | static void mips_cm_probe_l2sync(void) |
56 | { | 56 | { |
57 | unsigned major_rev; | 57 | unsigned major_rev; |
58 | phys_t addr; | 58 | phys_addr_t addr; |
59 | 59 | ||
60 | /* L2-only sync was introduced with CM major revision 6 */ | 60 | /* L2-only sync was introduced with CM major revision 6 */ |
61 | major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR_MSK) >> | 61 | major_rev = (read_gcr_rev() & CM_GCR_REV_MAJOR_MSK) >> |
@@ -78,7 +78,7 @@ static void mips_cm_probe_l2sync(void) | |||
78 | 78 | ||
79 | int mips_cm_probe(void) | 79 | int mips_cm_probe(void) |
80 | { | 80 | { |
81 | phys_t addr; | 81 | phys_addr_t addr; |
82 | u32 base_reg; | 82 | u32 base_reg; |
83 | 83 | ||
84 | addr = mips_cm_phys_base(); | 84 | addr = mips_cm_phys_base(); |
diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c index ba473608a347..11964501c4b0 100644 --- a/arch/mips/kernel/mips-cpc.c +++ b/arch/mips/kernel/mips-cpc.c | |||
@@ -21,7 +21,7 @@ static DEFINE_PER_CPU_ALIGNED(spinlock_t, cpc_core_lock); | |||
21 | 21 | ||
22 | static DEFINE_PER_CPU_ALIGNED(unsigned long, cpc_core_lock_flags); | 22 | static DEFINE_PER_CPU_ALIGNED(unsigned long, cpc_core_lock_flags); |
23 | 23 | ||
24 | phys_t __weak mips_cpc_phys_base(void) | 24 | phys_addr_t __weak mips_cpc_phys_base(void) |
25 | { | 25 | { |
26 | u32 cpc_base; | 26 | u32 cpc_base; |
27 | 27 | ||
@@ -44,7 +44,7 @@ phys_t __weak mips_cpc_phys_base(void) | |||
44 | 44 | ||
45 | int mips_cpc_probe(void) | 45 | int mips_cpc_probe(void) |
46 | { | 46 | { |
47 | phys_t addr; | 47 | phys_addr_t addr; |
48 | unsigned cpu; | 48 | unsigned cpu; |
49 | 49 | ||
50 | for_each_possible_cpu(cpu) | 50 | for_each_possible_cpu(cpu) |
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c index 2607c3a4ff7e..17eaf0cf760c 100644 --- a/arch/mips/kernel/mips_ksyms.c +++ b/arch/mips/kernel/mips_ksyms.c | |||
@@ -24,9 +24,7 @@ extern long __strncpy_from_user_nocheck_asm(char *__to, | |||
24 | const char *__from, long __len); | 24 | const char *__from, long __len); |
25 | extern long __strncpy_from_user_asm(char *__to, const char *__from, | 25 | extern long __strncpy_from_user_asm(char *__to, const char *__from, |
26 | long __len); | 26 | long __len); |
27 | extern long __strlen_kernel_nocheck_asm(const char *s); | ||
28 | extern long __strlen_kernel_asm(const char *s); | 27 | extern long __strlen_kernel_asm(const char *s); |
29 | extern long __strlen_user_nocheck_asm(const char *s); | ||
30 | extern long __strlen_user_asm(const char *s); | 28 | extern long __strlen_user_asm(const char *s); |
31 | extern long __strnlen_kernel_nocheck_asm(const char *s); | 29 | extern long __strnlen_kernel_nocheck_asm(const char *s); |
32 | extern long __strnlen_kernel_asm(const char *s); | 30 | extern long __strnlen_kernel_asm(const char *s); |
@@ -62,9 +60,7 @@ EXPORT_SYMBOL(__strncpy_from_kernel_nocheck_asm); | |||
62 | EXPORT_SYMBOL(__strncpy_from_kernel_asm); | 60 | EXPORT_SYMBOL(__strncpy_from_kernel_asm); |
63 | EXPORT_SYMBOL(__strncpy_from_user_nocheck_asm); | 61 | EXPORT_SYMBOL(__strncpy_from_user_nocheck_asm); |
64 | EXPORT_SYMBOL(__strncpy_from_user_asm); | 62 | EXPORT_SYMBOL(__strncpy_from_user_asm); |
65 | EXPORT_SYMBOL(__strlen_kernel_nocheck_asm); | ||
66 | EXPORT_SYMBOL(__strlen_kernel_asm); | 63 | EXPORT_SYMBOL(__strlen_kernel_asm); |
67 | EXPORT_SYMBOL(__strlen_user_nocheck_asm); | ||
68 | EXPORT_SYMBOL(__strlen_user_asm); | 64 | EXPORT_SYMBOL(__strlen_user_asm); |
69 | EXPORT_SYMBOL(__strnlen_kernel_nocheck_asm); | 65 | EXPORT_SYMBOL(__strnlen_kernel_nocheck_asm); |
70 | EXPORT_SYMBOL(__strnlen_kernel_asm); | 66 | EXPORT_SYMBOL(__strnlen_kernel_asm); |
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index a8f9cdc6f8b0..9466184d0039 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c | |||
@@ -561,8 +561,8 @@ static int mipspmu_get_irq(void) | |||
561 | IRQF_PERCPU | IRQF_NOBALANCING | IRQF_NO_THREAD, | 561 | IRQF_PERCPU | IRQF_NOBALANCING | IRQF_NO_THREAD, |
562 | "mips_perf_pmu", NULL); | 562 | "mips_perf_pmu", NULL); |
563 | if (err) { | 563 | if (err) { |
564 | pr_warning("Unable to request IRQ%d for MIPS " | 564 | pr_warn("Unable to request IRQ%d for MIPS performance counters!\n", |
565 | "performance counters!\n", mipspmu.irq); | 565 | mipspmu.irq); |
566 | } | 566 | } |
567 | } else if (cp0_perfcount_irq < 0) { | 567 | } else if (cp0_perfcount_irq < 0) { |
568 | /* | 568 | /* |
@@ -572,8 +572,7 @@ static int mipspmu_get_irq(void) | |||
572 | perf_irq = mipsxx_pmu_handle_shared_irq; | 572 | perf_irq = mipsxx_pmu_handle_shared_irq; |
573 | err = 0; | 573 | err = 0; |
574 | } else { | 574 | } else { |
575 | pr_warning("The platform hasn't properly defined its " | 575 | pr_warn("The platform hasn't properly defined its interrupt controller\n"); |
576 | "interrupt controller.\n"); | ||
577 | err = -ENOENT; | 576 | err = -ENOENT; |
578 | } | 577 | } |
579 | 578 | ||
@@ -1614,22 +1613,13 @@ init_hw_perf_events(void) | |||
1614 | counters = counters_total_to_per_cpu(counters); | 1613 | counters = counters_total_to_per_cpu(counters); |
1615 | #endif | 1614 | #endif |
1616 | 1615 | ||
1617 | #ifdef MSC01E_INT_BASE | 1616 | if (get_c0_perfcount_int) |
1618 | if (cpu_has_veic) { | 1617 | irq = get_c0_perfcount_int(); |
1619 | /* | 1618 | else if ((cp0_perfcount_irq >= 0) && |
1620 | * Using platform specific interrupt controller defines. | 1619 | (cp0_compare_irq != cp0_perfcount_irq)) |
1621 | */ | 1620 | irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; |
1622 | irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; | 1621 | else |
1623 | } else { | 1622 | irq = -1; |
1624 | #endif | ||
1625 | if ((cp0_perfcount_irq >= 0) && | ||
1626 | (cp0_compare_irq != cp0_perfcount_irq)) | ||
1627 | irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; | ||
1628 | else | ||
1629 | irq = -1; | ||
1630 | #ifdef MSC01E_INT_BASE | ||
1631 | } | ||
1632 | #endif | ||
1633 | 1623 | ||
1634 | mipspmu.map_raw_event = mipsxx_pmu_map_raw_event; | 1624 | mipspmu.map_raw_event = mipsxx_pmu_map_raw_event; |
1635 | 1625 | ||
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 636b0745d7c7..eb76434828e8 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <asm/isadep.h> | 42 | #include <asm/isadep.h> |
43 | #include <asm/inst.h> | 43 | #include <asm/inst.h> |
44 | #include <asm/stacktrace.h> | 44 | #include <asm/stacktrace.h> |
45 | #include <asm/irq_regs.h> | ||
45 | 46 | ||
46 | #ifdef CONFIG_HOTPLUG_CPU | 47 | #ifdef CONFIG_HOTPLUG_CPU |
47 | void arch_cpu_idle_dead(void) | 48 | void arch_cpu_idle_dead(void) |
@@ -187,21 +188,21 @@ static inline int is_ra_save_ins(union mips_instruction *ip) | |||
187 | */ | 188 | */ |
188 | if (mm_insn_16bit(ip->halfword[0])) { | 189 | if (mm_insn_16bit(ip->halfword[0])) { |
189 | mmi.word = (ip->halfword[0] << 16); | 190 | mmi.word = (ip->halfword[0] << 16); |
190 | return ((mmi.mm16_r5_format.opcode == mm_swsp16_op && | 191 | return (mmi.mm16_r5_format.opcode == mm_swsp16_op && |
191 | mmi.mm16_r5_format.rt == 31) || | 192 | mmi.mm16_r5_format.rt == 31) || |
192 | (mmi.mm16_m_format.opcode == mm_pool16c_op && | 193 | (mmi.mm16_m_format.opcode == mm_pool16c_op && |
193 | mmi.mm16_m_format.func == mm_swm16_op)); | 194 | mmi.mm16_m_format.func == mm_swm16_op); |
194 | } | 195 | } |
195 | else { | 196 | else { |
196 | mmi.halfword[0] = ip->halfword[1]; | 197 | mmi.halfword[0] = ip->halfword[1]; |
197 | mmi.halfword[1] = ip->halfword[0]; | 198 | mmi.halfword[1] = ip->halfword[0]; |
198 | return ((mmi.mm_m_format.opcode == mm_pool32b_op && | 199 | return (mmi.mm_m_format.opcode == mm_pool32b_op && |
199 | mmi.mm_m_format.rd > 9 && | 200 | mmi.mm_m_format.rd > 9 && |
200 | mmi.mm_m_format.base == 29 && | 201 | mmi.mm_m_format.base == 29 && |
201 | mmi.mm_m_format.func == mm_swm32_func) || | 202 | mmi.mm_m_format.func == mm_swm32_func) || |
202 | (mmi.i_format.opcode == mm_sw32_op && | 203 | (mmi.i_format.opcode == mm_sw32_op && |
203 | mmi.i_format.rs == 29 && | 204 | mmi.i_format.rs == 29 && |
204 | mmi.i_format.rt == 31)); | 205 | mmi.i_format.rt == 31); |
205 | } | 206 | } |
206 | #else | 207 | #else |
207 | /* sw / sd $ra, offset($sp) */ | 208 | /* sw / sd $ra, offset($sp) */ |
@@ -233,7 +234,7 @@ static inline int is_jump_ins(union mips_instruction *ip) | |||
233 | if (ip->r_format.opcode != mm_pool32a_op || | 234 | if (ip->r_format.opcode != mm_pool32a_op || |
234 | ip->r_format.func != mm_pool32axf_op) | 235 | ip->r_format.func != mm_pool32axf_op) |
235 | return 0; | 236 | return 0; |
236 | return (((ip->u_format.uimmediate >> 6) & mm_jalr_op) == mm_jalr_op); | 237 | return ((ip->u_format.uimmediate >> 6) & mm_jalr_op) == mm_jalr_op; |
237 | #else | 238 | #else |
238 | if (ip->j_format.opcode == j_op) | 239 | if (ip->j_format.opcode == j_op) |
239 | return 1; | 240 | return 1; |
@@ -260,13 +261,13 @@ static inline int is_sp_move_ins(union mips_instruction *ip) | |||
260 | union mips_instruction mmi; | 261 | union mips_instruction mmi; |
261 | 262 | ||
262 | mmi.word = (ip->halfword[0] << 16); | 263 | mmi.word = (ip->halfword[0] << 16); |
263 | return ((mmi.mm16_r3_format.opcode == mm_pool16d_op && | 264 | return (mmi.mm16_r3_format.opcode == mm_pool16d_op && |
264 | mmi.mm16_r3_format.simmediate && mm_addiusp_func) || | 265 | mmi.mm16_r3_format.simmediate && mm_addiusp_func) || |
265 | (mmi.mm16_r5_format.opcode == mm_pool16d_op && | 266 | (mmi.mm16_r5_format.opcode == mm_pool16d_op && |
266 | mmi.mm16_r5_format.rt == 29)); | 267 | mmi.mm16_r5_format.rt == 29); |
267 | } | 268 | } |
268 | return (ip->mm_i_format.opcode == mm_addiu32_op && | 269 | return ip->mm_i_format.opcode == mm_addiu32_op && |
269 | ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29); | 270 | ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29; |
270 | #else | 271 | #else |
271 | /* addiu/daddiu sp,sp,-imm */ | 272 | /* addiu/daddiu sp,sp,-imm */ |
272 | if (ip->i_format.rs != 29 || ip->i_format.rt != 29) | 273 | if (ip->i_format.rs != 29 || ip->i_format.rt != 29) |
@@ -532,3 +533,20 @@ unsigned long arch_align_stack(unsigned long sp) | |||
532 | 533 | ||
533 | return sp & ALMASK; | 534 | return sp & ALMASK; |
534 | } | 535 | } |
536 | |||
537 | static void arch_dump_stack(void *info) | ||
538 | { | ||
539 | struct pt_regs *regs; | ||
540 | |||
541 | regs = get_irq_regs(); | ||
542 | |||
543 | if (regs) | ||
544 | show_regs(regs); | ||
545 | |||
546 | dump_stack(); | ||
547 | } | ||
548 | |||
549 | void arch_trigger_all_cpu_backtrace(bool include_self) | ||
550 | { | ||
551 | smp_call_function(arch_dump_stack, NULL, 1); | ||
552 | } | ||
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c index 5d39bb85bf35..452d4350ce42 100644 --- a/arch/mips/kernel/prom.c +++ b/arch/mips/kernel/prom.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/debugfs.h> | 16 | #include <linux/debugfs.h> |
17 | #include <linux/of.h> | 17 | #include <linux/of.h> |
18 | #include <linux/of_fdt.h> | 18 | #include <linux/of_fdt.h> |
19 | #include <linux/of_platform.h> | ||
19 | 20 | ||
20 | #include <asm/page.h> | 21 | #include <asm/page.h> |
21 | #include <asm/prom.h> | 22 | #include <asm/prom.h> |
@@ -54,4 +55,21 @@ void __init __dt_setup_arch(void *bph) | |||
54 | 55 | ||
55 | mips_set_machine_name(of_flat_dt_get_machine_name()); | 56 | mips_set_machine_name(of_flat_dt_get_machine_name()); |
56 | } | 57 | } |
58 | |||
59 | int __init __dt_register_buses(const char *bus0, const char *bus1) | ||
60 | { | ||
61 | static struct of_device_id of_ids[3]; | ||
62 | |||
63 | if (!of_have_populated_dt()) | ||
64 | panic("device tree not present"); | ||
65 | |||
66 | strlcpy(of_ids[0].compatible, bus0, sizeof(of_ids[0].compatible)); | ||
67 | strlcpy(of_ids[1].compatible, bus1, sizeof(of_ids[1].compatible)); | ||
68 | |||
69 | if (of_platform_populate(NULL, of_ids, NULL, NULL)) | ||
70 | panic("failed to populate DT"); | ||
71 | |||
72 | return 0; | ||
73 | } | ||
74 | |||
57 | #endif | 75 | #endif |
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index f3b635f86c39..a8c20afeb813 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c | |||
@@ -82,14 +82,14 @@ static struct resource data_resource = { .name = "Kernel data", }; | |||
82 | 82 | ||
83 | static void *detect_magic __initdata = detect_memory_region; | 83 | static void *detect_magic __initdata = detect_memory_region; |
84 | 84 | ||
85 | void __init add_memory_region(phys_t start, phys_t size, long type) | 85 | void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type) |
86 | { | 86 | { |
87 | int x = boot_mem_map.nr_map; | 87 | int x = boot_mem_map.nr_map; |
88 | int i; | 88 | int i; |
89 | 89 | ||
90 | /* Sanity check */ | 90 | /* Sanity check */ |
91 | if (start + size < start) { | 91 | if (start + size < start) { |
92 | pr_warning("Trying to add an invalid memory region, skipped\n"); | 92 | pr_warn("Trying to add an invalid memory region, skipped\n"); |
93 | return; | 93 | return; |
94 | } | 94 | } |
95 | 95 | ||
@@ -127,10 +127,10 @@ void __init add_memory_region(phys_t start, phys_t size, long type) | |||
127 | boot_mem_map.nr_map++; | 127 | boot_mem_map.nr_map++; |
128 | } | 128 | } |
129 | 129 | ||
130 | void __init detect_memory_region(phys_t start, phys_t sz_min, phys_t sz_max) | 130 | void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max) |
131 | { | 131 | { |
132 | void *dm = &detect_magic; | 132 | void *dm = &detect_magic; |
133 | phys_t size; | 133 | phys_addr_t size; |
134 | 134 | ||
135 | for (size = sz_min; size < sz_max; size <<= 1) { | 135 | for (size = sz_min; size < sz_max; size <<= 1) { |
136 | if (!memcmp(dm, dm + size, sizeof(detect_magic))) | 136 | if (!memcmp(dm, dm + size, sizeof(detect_magic))) |
@@ -545,9 +545,9 @@ static int __init early_parse_elfcorehdr(char *p) | |||
545 | early_param("elfcorehdr", early_parse_elfcorehdr); | 545 | early_param("elfcorehdr", early_parse_elfcorehdr); |
546 | #endif | 546 | #endif |
547 | 547 | ||
548 | static void __init arch_mem_addpart(phys_t mem, phys_t end, int type) | 548 | static void __init arch_mem_addpart(phys_addr_t mem, phys_addr_t end, int type) |
549 | { | 549 | { |
550 | phys_t size; | 550 | phys_addr_t size; |
551 | int i; | 551 | int i; |
552 | 552 | ||
553 | size = end - mem; | 553 | size = end - mem; |
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 16f1e4f2bf3c..545bf11bd2ed 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c | |||
@@ -530,7 +530,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) | |||
530 | struct mips_abi *abi = current->thread.abi; | 530 | struct mips_abi *abi = current->thread.abi; |
531 | #ifdef CONFIG_CPU_MICROMIPS | 531 | #ifdef CONFIG_CPU_MICROMIPS |
532 | void *vdso; | 532 | void *vdso; |
533 | unsigned int tmp = (unsigned int)current->mm->context.vdso; | 533 | unsigned long tmp = (unsigned long)current->mm->context.vdso; |
534 | 534 | ||
535 | set_isa16_mode(tmp); | 535 | set_isa16_mode(tmp); |
536 | vdso = (void *)tmp; | 536 | vdso = (void *)tmp; |
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c index 06bb5ed6d80a..b8bd9340c9c7 100644 --- a/arch/mips/kernel/smp-bmips.c +++ b/arch/mips/kernel/smp-bmips.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <asm/bmips.h> | 35 | #include <asm/bmips.h> |
36 | #include <asm/traps.h> | 36 | #include <asm/traps.h> |
37 | #include <asm/barrier.h> | 37 | #include <asm/barrier.h> |
38 | #include <asm/cpu-features.h> | ||
38 | 39 | ||
39 | static int __maybe_unused max_cpus = 1; | 40 | static int __maybe_unused max_cpus = 1; |
40 | 41 | ||
@@ -42,6 +43,12 @@ static int __maybe_unused max_cpus = 1; | |||
42 | int bmips_smp_enabled = 1; | 43 | int bmips_smp_enabled = 1; |
43 | int bmips_cpu_offset; | 44 | int bmips_cpu_offset; |
44 | cpumask_t bmips_booted_mask; | 45 | cpumask_t bmips_booted_mask; |
46 | unsigned long bmips_tp1_irqs = IE_IRQ1; | ||
47 | |||
48 | #define RESET_FROM_KSEG0 0x80080800 | ||
49 | #define RESET_FROM_KSEG1 0xa0080800 | ||
50 | |||
51 | static void bmips_set_reset_vec(int cpu, u32 val); | ||
45 | 52 | ||
46 | #ifdef CONFIG_SMP | 53 | #ifdef CONFIG_SMP |
47 | 54 | ||
@@ -194,6 +201,9 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) | |||
194 | pr_info("SMP: Booting CPU%d...\n", cpu); | 201 | pr_info("SMP: Booting CPU%d...\n", cpu); |
195 | 202 | ||
196 | if (cpumask_test_cpu(cpu, &bmips_booted_mask)) { | 203 | if (cpumask_test_cpu(cpu, &bmips_booted_mask)) { |
204 | /* kseg1 might not exist if this CPU enabled XKS01 */ | ||
205 | bmips_set_reset_vec(cpu, RESET_FROM_KSEG0); | ||
206 | |||
197 | switch (current_cpu_type()) { | 207 | switch (current_cpu_type()) { |
198 | case CPU_BMIPS4350: | 208 | case CPU_BMIPS4350: |
199 | case CPU_BMIPS4380: | 209 | case CPU_BMIPS4380: |
@@ -203,8 +213,9 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) | |||
203 | bmips5000_send_ipi_single(cpu, 0); | 213 | bmips5000_send_ipi_single(cpu, 0); |
204 | break; | 214 | break; |
205 | } | 215 | } |
206 | } | 216 | } else { |
207 | else { | 217 | bmips_set_reset_vec(cpu, RESET_FROM_KSEG1); |
218 | |||
208 | switch (current_cpu_type()) { | 219 | switch (current_cpu_type()) { |
209 | case CPU_BMIPS4350: | 220 | case CPU_BMIPS4350: |
210 | case CPU_BMIPS4380: | 221 | case CPU_BMIPS4380: |
@@ -213,17 +224,7 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) | |||
213 | set_c0_brcm_cmt_ctrl(0x01); | 224 | set_c0_brcm_cmt_ctrl(0x01); |
214 | break; | 225 | break; |
215 | case CPU_BMIPS5000: | 226 | case CPU_BMIPS5000: |
216 | if (cpu & 0x01) | 227 | write_c0_brcm_action(ACTION_BOOT_THREAD(cpu)); |
217 | write_c0_brcm_action(ACTION_BOOT_THREAD(cpu)); | ||
218 | else { | ||
219 | /* | ||
220 | * core N thread 0 was already booted; just | ||
221 | * pulse the NMI line | ||
222 | */ | ||
223 | bmips_write_zscm_reg(0x210, 0xc0000000); | ||
224 | udelay(10); | ||
225 | bmips_write_zscm_reg(0x210, 0x00); | ||
226 | } | ||
227 | break; | 228 | break; |
228 | } | 229 | } |
229 | cpumask_set_cpu(cpu, &bmips_booted_mask); | 230 | cpumask_set_cpu(cpu, &bmips_booted_mask); |
@@ -235,31 +236,12 @@ static void bmips_boot_secondary(int cpu, struct task_struct *idle) | |||
235 | */ | 236 | */ |
236 | static void bmips_init_secondary(void) | 237 | static void bmips_init_secondary(void) |
237 | { | 238 | { |
238 | /* move NMI vector to kseg0, in case XKS01 is enabled */ | ||
239 | |||
240 | void __iomem *cbr; | ||
241 | unsigned long old_vec; | ||
242 | unsigned long relo_vector; | ||
243 | int boot_cpu; | ||
244 | |||
245 | switch (current_cpu_type()) { | 239 | switch (current_cpu_type()) { |
246 | case CPU_BMIPS4350: | 240 | case CPU_BMIPS4350: |
247 | case CPU_BMIPS4380: | 241 | case CPU_BMIPS4380: |
248 | cbr = BMIPS_GET_CBR(); | ||
249 | |||
250 | boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31)); | ||
251 | relo_vector = boot_cpu ? BMIPS_RELO_VECTOR_CONTROL_0 : | ||
252 | BMIPS_RELO_VECTOR_CONTROL_1; | ||
253 | |||
254 | old_vec = __raw_readl(cbr + relo_vector); | ||
255 | __raw_writel(old_vec & ~0x20000000, cbr + relo_vector); | ||
256 | |||
257 | clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0); | 242 | clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0); |
258 | break; | 243 | break; |
259 | case CPU_BMIPS5000: | 244 | case CPU_BMIPS5000: |
260 | write_c0_brcm_bootvec(read_c0_brcm_bootvec() & | ||
261 | (smp_processor_id() & 0x01 ? ~0x20000000 : ~0x2000)); | ||
262 | |||
263 | write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0)); | 245 | write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0)); |
264 | break; | 246 | break; |
265 | } | 247 | } |
@@ -276,7 +258,7 @@ static void bmips_smp_finish(void) | |||
276 | write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ); | 258 | write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ); |
277 | 259 | ||
278 | irq_enable_hazard(); | 260 | irq_enable_hazard(); |
279 | set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ1 | IE_IRQ5 | ST0_IE); | 261 | set_c0_status(IE_SW0 | IE_SW1 | bmips_tp1_irqs | IE_IRQ5 | ST0_IE); |
280 | irq_enable_hazard(); | 262 | irq_enable_hazard(); |
281 | } | 263 | } |
282 | 264 | ||
@@ -381,6 +363,7 @@ static int bmips_cpu_disable(void) | |||
381 | 363 | ||
382 | set_cpu_online(cpu, false); | 364 | set_cpu_online(cpu, false); |
383 | cpu_clear(cpu, cpu_callin_map); | 365 | cpu_clear(cpu, cpu_callin_map); |
366 | clear_c0_status(IE_IRQ5); | ||
384 | 367 | ||
385 | local_flush_tlb_all(); | 368 | local_flush_tlb_all(); |
386 | local_flush_icache_range(0, ~0); | 369 | local_flush_icache_range(0, ~0); |
@@ -405,7 +388,8 @@ void __ref play_dead(void) | |||
405 | * IRQ handlers; this clears ST0_IE and returns immediately. | 388 | * IRQ handlers; this clears ST0_IE and returns immediately. |
406 | */ | 389 | */ |
407 | clear_c0_cause(CAUSEF_IV | C_SW0 | C_SW1); | 390 | clear_c0_cause(CAUSEF_IV | C_SW0 | C_SW1); |
408 | change_c0_status(IE_IRQ5 | IE_IRQ1 | IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV, | 391 | change_c0_status( |
392 | IE_IRQ5 | bmips_tp1_irqs | IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV, | ||
409 | IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV); | 393 | IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV); |
410 | irq_disable_hazard(); | 394 | irq_disable_hazard(); |
411 | 395 | ||
@@ -473,10 +457,61 @@ static inline void bmips_nmi_handler_setup(void) | |||
473 | &bmips_smp_int_vec_end); | 457 | &bmips_smp_int_vec_end); |
474 | } | 458 | } |
475 | 459 | ||
460 | struct reset_vec_info { | ||
461 | int cpu; | ||
462 | u32 val; | ||
463 | }; | ||
464 | |||
465 | static void bmips_set_reset_vec_remote(void *vinfo) | ||
466 | { | ||
467 | struct reset_vec_info *info = vinfo; | ||
468 | int shift = info->cpu & 0x01 ? 16 : 0; | ||
469 | u32 mask = ~(0xffff << shift), val = info->val >> 16; | ||
470 | |||
471 | preempt_disable(); | ||
472 | if (smp_processor_id() > 0) { | ||
473 | smp_call_function_single(0, &bmips_set_reset_vec_remote, | ||
474 | info, 1); | ||
475 | } else { | ||
476 | if (info->cpu & 0x02) { | ||
477 | /* BMIPS5200 "should" use mask/shift, but it's buggy */ | ||
478 | bmips_write_zscm_reg(0xa0, (val << 16) | val); | ||
479 | bmips_read_zscm_reg(0xa0); | ||
480 | } else { | ||
481 | write_c0_brcm_bootvec((read_c0_brcm_bootvec() & mask) | | ||
482 | (val << shift)); | ||
483 | } | ||
484 | } | ||
485 | preempt_enable(); | ||
486 | } | ||
487 | |||
488 | static void bmips_set_reset_vec(int cpu, u32 val) | ||
489 | { | ||
490 | struct reset_vec_info info; | ||
491 | |||
492 | if (current_cpu_type() == CPU_BMIPS5000) { | ||
493 | /* this needs to run from CPU0 (which is always online) */ | ||
494 | info.cpu = cpu; | ||
495 | info.val = val; | ||
496 | bmips_set_reset_vec_remote(&info); | ||
497 | } else { | ||
498 | void __iomem *cbr = BMIPS_GET_CBR(); | ||
499 | |||
500 | if (cpu == 0) | ||
501 | __raw_writel(val, cbr + BMIPS_RELO_VECTOR_CONTROL_0); | ||
502 | else { | ||
503 | if (current_cpu_type() != CPU_BMIPS4380) | ||
504 | return; | ||
505 | __raw_writel(val, cbr + BMIPS_RELO_VECTOR_CONTROL_1); | ||
506 | } | ||
507 | } | ||
508 | __sync(); | ||
509 | back_to_back_c0_hazard(); | ||
510 | } | ||
511 | |||
476 | void bmips_ebase_setup(void) | 512 | void bmips_ebase_setup(void) |
477 | { | 513 | { |
478 | unsigned long new_ebase = ebase; | 514 | unsigned long new_ebase = ebase; |
479 | void __iomem __maybe_unused *cbr; | ||
480 | 515 | ||
481 | BUG_ON(ebase != CKSEG0); | 516 | BUG_ON(ebase != CKSEG0); |
482 | 517 | ||
@@ -496,15 +531,14 @@ void bmips_ebase_setup(void) | |||
496 | &bmips_smp_int_vec, 0x80); | 531 | &bmips_smp_int_vec, 0x80); |
497 | __sync(); | 532 | __sync(); |
498 | return; | 533 | return; |
534 | case CPU_BMIPS3300: | ||
499 | case CPU_BMIPS4380: | 535 | case CPU_BMIPS4380: |
500 | /* | 536 | /* |
501 | * 0x8000_0000: reset/NMI (initially in kseg1) | 537 | * 0x8000_0000: reset/NMI (initially in kseg1) |
502 | * 0x8000_0400: normal vectors | 538 | * 0x8000_0400: normal vectors |
503 | */ | 539 | */ |
504 | new_ebase = 0x80000400; | 540 | new_ebase = 0x80000400; |
505 | cbr = BMIPS_GET_CBR(); | 541 | bmips_set_reset_vec(0, RESET_FROM_KSEG0); |
506 | __raw_writel(0x80080800, cbr + BMIPS_RELO_VECTOR_CONTROL_0); | ||
507 | __raw_writel(0xa0080800, cbr + BMIPS_RELO_VECTOR_CONTROL_1); | ||
508 | break; | 542 | break; |
509 | case CPU_BMIPS5000: | 543 | case CPU_BMIPS5000: |
510 | /* | 544 | /* |
@@ -512,10 +546,8 @@ void bmips_ebase_setup(void) | |||
512 | * 0x8000_1000: normal vectors | 546 | * 0x8000_1000: normal vectors |
513 | */ | 547 | */ |
514 | new_ebase = 0x80001000; | 548 | new_ebase = 0x80001000; |
515 | write_c0_brcm_bootvec(0xa0088008); | 549 | bmips_set_reset_vec(0, RESET_FROM_KSEG0); |
516 | write_c0_ebase(new_ebase); | 550 | write_c0_ebase(new_ebase); |
517 | if (max_cpus > 2) | ||
518 | bmips_write_zscm_reg(0xa0, 0xa008a008); | ||
519 | break; | 551 | break; |
520 | default: | 552 | default: |
521 | return; | 553 | return; |
diff --git a/arch/mips/kernel/smp-cmp.c b/arch/mips/kernel/smp-cmp.c index fc8a51553426..1e0a93c5a3e7 100644 --- a/arch/mips/kernel/smp-cmp.c +++ b/arch/mips/kernel/smp-cmp.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/cpumask.h> | 24 | #include <linux/cpumask.h> |
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/compiler.h> | 26 | #include <linux/compiler.h> |
27 | #include <linux/irqchip/mips-gic.h> | ||
27 | 28 | ||
28 | #include <linux/atomic.h> | 29 | #include <linux/atomic.h> |
29 | #include <asm/cacheflush.h> | 30 | #include <asm/cacheflush.h> |
@@ -37,7 +38,6 @@ | |||
37 | #include <asm/mipsmtregs.h> | 38 | #include <asm/mipsmtregs.h> |
38 | #include <asm/mips_mt.h> | 39 | #include <asm/mips_mt.h> |
39 | #include <asm/amon.h> | 40 | #include <asm/amon.h> |
40 | #include <asm/gic.h> | ||
41 | 41 | ||
42 | static void cmp_init_secondary(void) | 42 | static void cmp_init_secondary(void) |
43 | { | 43 | { |
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c index e6e16a1d4add..bed7590e475f 100644 --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c | |||
@@ -9,13 +9,13 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/io.h> | 11 | #include <linux/io.h> |
12 | #include <linux/irqchip/mips-gic.h> | ||
12 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
13 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
14 | #include <linux/smp.h> | 15 | #include <linux/smp.h> |
15 | #include <linux/types.h> | 16 | #include <linux/types.h> |
16 | 17 | ||
17 | #include <asm/bcache.h> | 18 | #include <asm/bcache.h> |
18 | #include <asm/gic.h> | ||
19 | #include <asm/mips-cm.h> | 19 | #include <asm/mips-cm.h> |
20 | #include <asm/mips-cpc.h> | 20 | #include <asm/mips-cpc.h> |
21 | #include <asm/mips_mt.h> | 21 | #include <asm/mips_mt.h> |
@@ -273,8 +273,8 @@ static void cps_init_secondary(void) | |||
273 | if (cpu_has_mipsmt) | 273 | if (cpu_has_mipsmt) |
274 | dmt(); | 274 | dmt(); |
275 | 275 | ||
276 | change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | | 276 | change_c0_status(ST0_IM, STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | |
277 | STATUSF_IP6 | STATUSF_IP7); | 277 | STATUSF_IP5 | STATUSF_IP6 | STATUSF_IP7); |
278 | } | 278 | } |
279 | 279 | ||
280 | static void cps_smp_finish(void) | 280 | static void cps_smp_finish(void) |
diff --git a/arch/mips/kernel/smp-gic.c b/arch/mips/kernel/smp-gic.c index 3b21a96d1ccb..5f0ab5bcd01e 100644 --- a/arch/mips/kernel/smp-gic.c +++ b/arch/mips/kernel/smp-gic.c | |||
@@ -12,9 +12,9 @@ | |||
12 | * option) any later version. | 12 | * option) any later version. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/irqchip/mips-gic.h> | ||
15 | #include <linux/printk.h> | 16 | #include <linux/printk.h> |
16 | 17 | ||
17 | #include <asm/gic.h> | ||
18 | #include <asm/mips-cpc.h> | 18 | #include <asm/mips-cpc.h> |
19 | #include <asm/smp-ops.h> | 19 | #include <asm/smp-ops.h> |
20 | 20 | ||
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 21f23add04f4..ad86951b73bd 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
22 | #include <linux/cpumask.h> | 22 | #include <linux/cpumask.h> |
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/irqchip/mips-gic.h> | ||
24 | #include <linux/compiler.h> | 25 | #include <linux/compiler.h> |
25 | #include <linux/smp.h> | 26 | #include <linux/smp.h> |
26 | 27 | ||
@@ -34,7 +35,6 @@ | |||
34 | #include <asm/mipsregs.h> | 35 | #include <asm/mipsregs.h> |
35 | #include <asm/mipsmtregs.h> | 36 | #include <asm/mipsmtregs.h> |
36 | #include <asm/mips_mt.h> | 37 | #include <asm/mips_mt.h> |
37 | #include <asm/gic.h> | ||
38 | 38 | ||
39 | static void __init smvp_copy_vpe_config(void) | 39 | static void __init smvp_copy_vpe_config(void) |
40 | { | 40 | { |
@@ -119,7 +119,7 @@ static void vsmp_send_ipi_single(int cpu, unsigned int action) | |||
119 | unsigned long flags; | 119 | unsigned long flags; |
120 | int vpflags; | 120 | int vpflags; |
121 | 121 | ||
122 | #ifdef CONFIG_IRQ_GIC | 122 | #ifdef CONFIG_MIPS_GIC |
123 | if (gic_present) { | 123 | if (gic_present) { |
124 | gic_send_ipi_single(cpu, action); | 124 | gic_send_ipi_single(cpu, action); |
125 | return; | 125 | return; |
@@ -158,7 +158,7 @@ static void vsmp_send_ipi_mask(const struct cpumask *mask, unsigned int action) | |||
158 | 158 | ||
159 | static void vsmp_init_secondary(void) | 159 | static void vsmp_init_secondary(void) |
160 | { | 160 | { |
161 | #ifdef CONFIG_IRQ_GIC | 161 | #ifdef CONFIG_MIPS_GIC |
162 | /* This is Malta specific: IPI,performance and timer interrupts */ | 162 | /* This is Malta specific: IPI,performance and timer interrupts */ |
163 | if (gic_present) | 163 | if (gic_present) |
164 | change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | | 164 | change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | |
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 4a4f9dda5658..604b558809c4 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c | |||
@@ -117,6 +117,7 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new) | |||
117 | "2: sc %[tmp], (%[addr]) \n" | 117 | "2: sc %[tmp], (%[addr]) \n" |
118 | " beqzl %[tmp], 1b \n" | 118 | " beqzl %[tmp], 1b \n" |
119 | "3: \n" | 119 | "3: \n" |
120 | " .insn \n" | ||
120 | " .section .fixup,\"ax\" \n" | 121 | " .section .fixup,\"ax\" \n" |
121 | "4: li %[err], %[efault] \n" | 122 | "4: li %[err], %[efault] \n" |
122 | " j 3b \n" | 123 | " j 3b \n" |
@@ -142,6 +143,7 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new) | |||
142 | "2: sc %[tmp], (%[addr]) \n" | 143 | "2: sc %[tmp], (%[addr]) \n" |
143 | " bnez %[tmp], 4f \n" | 144 | " bnez %[tmp], 4f \n" |
144 | "3: \n" | 145 | "3: \n" |
146 | " .insn \n" | ||
145 | " .subsection 2 \n" | 147 | " .subsection 2 \n" |
146 | "4: b 1b \n" | 148 | "4: b 1b \n" |
147 | " .previous \n" | 149 | " .previous \n" |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 22b19c275044..ad3d2031c327 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -724,6 +724,50 @@ int process_fpemu_return(int sig, void __user *fault_addr) | |||
724 | } | 724 | } |
725 | } | 725 | } |
726 | 726 | ||
727 | static int simulate_fp(struct pt_regs *regs, unsigned int opcode, | ||
728 | unsigned long old_epc, unsigned long old_ra) | ||
729 | { | ||
730 | union mips_instruction inst = { .word = opcode }; | ||
731 | void __user *fault_addr = NULL; | ||
732 | int sig; | ||
733 | |||
734 | /* If it's obviously not an FP instruction, skip it */ | ||
735 | switch (inst.i_format.opcode) { | ||
736 | case cop1_op: | ||
737 | case cop1x_op: | ||
738 | case lwc1_op: | ||
739 | case ldc1_op: | ||
740 | case swc1_op: | ||
741 | case sdc1_op: | ||
742 | break; | ||
743 | |||
744 | default: | ||
745 | return -1; | ||
746 | } | ||
747 | |||
748 | /* | ||
749 | * do_ri skipped over the instruction via compute_return_epc, undo | ||
750 | * that for the FPU emulator. | ||
751 | */ | ||
752 | regs->cp0_epc = old_epc; | ||
753 | regs->regs[31] = old_ra; | ||
754 | |||
755 | /* Save the FP context to struct thread_struct */ | ||
756 | lose_fpu(1); | ||
757 | |||
758 | /* Run the emulator */ | ||
759 | sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1, | ||
760 | &fault_addr); | ||
761 | |||
762 | /* If something went wrong, signal */ | ||
763 | process_fpemu_return(sig, fault_addr); | ||
764 | |||
765 | /* Restore the hardware register state */ | ||
766 | own_fpu(1); | ||
767 | |||
768 | return 0; | ||
769 | } | ||
770 | |||
727 | /* | 771 | /* |
728 | * XXX Delayed fp exceptions when doing a lazy ctx switch XXX | 772 | * XXX Delayed fp exceptions when doing a lazy ctx switch XXX |
729 | */ | 773 | */ |
@@ -1016,6 +1060,9 @@ asmlinkage void do_ri(struct pt_regs *regs) | |||
1016 | 1060 | ||
1017 | if (status < 0) | 1061 | if (status < 0) |
1018 | status = simulate_sync(regs, opcode); | 1062 | status = simulate_sync(regs, opcode); |
1063 | |||
1064 | if (status < 0) | ||
1065 | status = simulate_fp(regs, opcode, old_epc, old31); | ||
1019 | } | 1066 | } |
1020 | 1067 | ||
1021 | if (status < 0) | 1068 | if (status < 0) |
@@ -1380,12 +1427,19 @@ asmlinkage void do_mcheck(struct pt_regs *regs) | |||
1380 | show_regs(regs); | 1427 | show_regs(regs); |
1381 | 1428 | ||
1382 | if (multi_match) { | 1429 | if (multi_match) { |
1383 | printk("Index : %0x\n", read_c0_index()); | 1430 | pr_err("Index : %0x\n", read_c0_index()); |
1384 | printk("Pagemask: %0x\n", read_c0_pagemask()); | 1431 | pr_err("Pagemask: %0x\n", read_c0_pagemask()); |
1385 | printk("EntryHi : %0*lx\n", field, read_c0_entryhi()); | 1432 | pr_err("EntryHi : %0*lx\n", field, read_c0_entryhi()); |
1386 | printk("EntryLo0: %0*lx\n", field, read_c0_entrylo0()); | 1433 | pr_err("EntryLo0: %0*lx\n", field, read_c0_entrylo0()); |
1387 | printk("EntryLo1: %0*lx\n", field, read_c0_entrylo1()); | 1434 | pr_err("EntryLo1: %0*lx\n", field, read_c0_entrylo1()); |
1388 | printk("\n"); | 1435 | pr_err("Wired : %0x\n", read_c0_wired()); |
1436 | pr_err("Pagegrain: %0x\n", read_c0_pagegrain()); | ||
1437 | if (cpu_has_htw) { | ||
1438 | pr_err("PWField : %0*lx\n", field, read_c0_pwfield()); | ||
1439 | pr_err("PWSize : %0*lx\n", field, read_c0_pwsize()); | ||
1440 | pr_err("PWCtl : %0x\n", read_c0_pwctl()); | ||
1441 | } | ||
1442 | pr_err("\n"); | ||
1389 | dump_tlb_all(); | 1443 | dump_tlb_all(); |
1390 | } | 1444 | } |
1391 | 1445 | ||
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c index 0f1af58b036a..ed2a278722a9 100644 --- a/arch/mips/kernel/vdso.c +++ b/arch/mips/kernel/vdso.c | |||
@@ -16,9 +16,11 @@ | |||
16 | #include <linux/elf.h> | 16 | #include <linux/elf.h> |
17 | #include <linux/vmalloc.h> | 17 | #include <linux/vmalloc.h> |
18 | #include <linux/unistd.h> | 18 | #include <linux/unistd.h> |
19 | #include <linux/random.h> | ||
19 | 20 | ||
20 | #include <asm/vdso.h> | 21 | #include <asm/vdso.h> |
21 | #include <asm/uasm.h> | 22 | #include <asm/uasm.h> |
23 | #include <asm/processor.h> | ||
22 | 24 | ||
23 | /* | 25 | /* |
24 | * Including <asm/unistd.h> would give use the 64-bit syscall numbers ... | 26 | * Including <asm/unistd.h> would give use the 64-bit syscall numbers ... |
@@ -67,7 +69,18 @@ subsys_initcall(init_vdso); | |||
67 | 69 | ||
68 | static unsigned long vdso_addr(unsigned long start) | 70 | static unsigned long vdso_addr(unsigned long start) |
69 | { | 71 | { |
70 | return STACK_TOP; | 72 | unsigned long offset = 0UL; |
73 | |||
74 | if (current->flags & PF_RANDOMIZE) { | ||
75 | offset = get_random_int(); | ||
76 | offset <<= PAGE_SHIFT; | ||
77 | if (TASK_IS_32BIT_ADDR) | ||
78 | offset &= 0xfffffful; | ||
79 | else | ||
80 | offset &= 0xffffffful; | ||
81 | } | ||
82 | |||
83 | return STACK_TOP + offset; | ||
71 | } | 84 | } |
72 | 85 | ||
73 | int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) | 86 | int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) |
diff --git a/arch/mips/lantiq/falcon/sysctrl.c b/arch/mips/lantiq/falcon/sysctrl.c index 468ffa043607..7edcd4946fc1 100644 --- a/arch/mips/lantiq/falcon/sysctrl.c +++ b/arch/mips/lantiq/falcon/sysctrl.c | |||
@@ -49,6 +49,7 @@ | |||
49 | 49 | ||
50 | /* Activation Status Register */ | 50 | /* Activation Status Register */ |
51 | #define ACTS_ASC0_ACT 0x00001000 | 51 | #define ACTS_ASC0_ACT 0x00001000 |
52 | #define ACTS_SSC0 0x00002000 | ||
52 | #define ACTS_ASC1_ACT 0x00000800 | 53 | #define ACTS_ASC1_ACT 0x00000800 |
53 | #define ACTS_I2C_ACT 0x00004000 | 54 | #define ACTS_I2C_ACT 0x00004000 |
54 | #define ACTS_P0 0x00010000 | 55 | #define ACTS_P0 0x00010000 |
@@ -147,12 +148,11 @@ static void falcon_gpe_enable(void) | |||
147 | if (status & (1 << (GPPC_OFFSET + 1))) | 148 | if (status & (1 << (GPPC_OFFSET + 1))) |
148 | return; | 149 | return; |
149 | 150 | ||
150 | if (status_r32(STATUS_CONFIG) == 0) | 151 | freq = (status_r32(STATUS_CONFIG) & |
152 | GPEFREQ_MASK) >> | ||
153 | GPEFREQ_OFFSET; | ||
154 | if (freq == 0) | ||
151 | freq = 1; /* use 625MHz on unfused chip */ | 155 | freq = 1; /* use 625MHz on unfused chip */ |
152 | else | ||
153 | freq = (status_r32(STATUS_CONFIG) & | ||
154 | GPEFREQ_MASK) >> | ||
155 | GPEFREQ_OFFSET; | ||
156 | 156 | ||
157 | /* apply new frequency */ | 157 | /* apply new frequency */ |
158 | sysctl_w32_mask(SYSCTL_SYS1, 7 << (GPPC_OFFSET + 1), | 158 | sysctl_w32_mask(SYSCTL_SYS1, 7 << (GPPC_OFFSET + 1), |
@@ -260,5 +260,6 @@ void __init ltq_soc_init(void) | |||
260 | clkdev_add_sys("1e800600.pad", SYSCTL_SYS1, ACTS_PADCTRL4); | 260 | clkdev_add_sys("1e800600.pad", SYSCTL_SYS1, ACTS_PADCTRL4); |
261 | clkdev_add_sys("1e100b00.serial", SYSCTL_SYS1, ACTS_ASC1_ACT); | 261 | clkdev_add_sys("1e100b00.serial", SYSCTL_SYS1, ACTS_ASC1_ACT); |
262 | clkdev_add_sys("1e100c00.serial", SYSCTL_SYS1, ACTS_ASC0_ACT); | 262 | clkdev_add_sys("1e100c00.serial", SYSCTL_SYS1, ACTS_ASC0_ACT); |
263 | clkdev_add_sys("1e100d00.spi", SYSCTL_SYS1, ACTS_SSC0); | ||
263 | clkdev_add_sys("1e200000.i2c", SYSCTL_SYS1, ACTS_I2C_ACT); | 264 | clkdev_add_sys("1e200000.i2c", SYSCTL_SYS1, ACTS_I2C_ACT); |
264 | } | 265 | } |
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c index 030568a70ac4..6ab10573490d 100644 --- a/arch/mips/lantiq/irq.c +++ b/arch/mips/lantiq/irq.c | |||
@@ -70,6 +70,7 @@ static struct resource ltq_eiu_irq[MAX_EIU]; | |||
70 | static void __iomem *ltq_icu_membase[MAX_IM]; | 70 | static void __iomem *ltq_icu_membase[MAX_IM]; |
71 | static void __iomem *ltq_eiu_membase; | 71 | static void __iomem *ltq_eiu_membase; |
72 | static struct irq_domain *ltq_domain; | 72 | static struct irq_domain *ltq_domain; |
73 | static int ltq_perfcount_irq; | ||
73 | 74 | ||
74 | int ltq_eiu_get_irq(int exin) | 75 | int ltq_eiu_get_irq(int exin) |
75 | { | 76 | { |
@@ -378,30 +379,6 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) | |||
378 | panic("Failed to remap icu memory"); | 379 | panic("Failed to remap icu memory"); |
379 | } | 380 | } |
380 | 381 | ||
381 | /* the external interrupts are optional and xway only */ | ||
382 | eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu-xway"); | ||
383 | if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) { | ||
384 | /* find out how many external irq sources we have */ | ||
385 | exin_avail = of_irq_count(eiu_node); | ||
386 | |||
387 | if (exin_avail > MAX_EIU) | ||
388 | exin_avail = MAX_EIU; | ||
389 | |||
390 | ret = of_irq_to_resource_table(eiu_node, | ||
391 | ltq_eiu_irq, exin_avail); | ||
392 | if (ret != exin_avail) | ||
393 | panic("failed to load external irq resources"); | ||
394 | |||
395 | if (request_mem_region(res.start, resource_size(&res), | ||
396 | res.name) < 0) | ||
397 | pr_err("Failed to request eiu memory"); | ||
398 | |||
399 | ltq_eiu_membase = ioremap_nocache(res.start, | ||
400 | resource_size(&res)); | ||
401 | if (!ltq_eiu_membase) | ||
402 | panic("Failed to remap eiu memory"); | ||
403 | } | ||
404 | |||
405 | /* turn off all irqs by default */ | 382 | /* turn off all irqs by default */ |
406 | for (i = 0; i < MAX_IM; i++) { | 383 | for (i = 0; i < MAX_IM; i++) { |
407 | /* make sure all irqs are turned off by default */ | 384 | /* make sure all irqs are turned off by default */ |
@@ -449,7 +426,7 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) | |||
449 | #endif | 426 | #endif |
450 | 427 | ||
451 | /* tell oprofile which irq to use */ | 428 | /* tell oprofile which irq to use */ |
452 | cp0_perfcount_irq = irq_create_mapping(ltq_domain, LTQ_PERF_IRQ); | 429 | ltq_perfcount_irq = irq_create_mapping(ltq_domain, LTQ_PERF_IRQ); |
453 | 430 | ||
454 | /* | 431 | /* |
455 | * if the timer irq is not one of the mips irqs we need to | 432 | * if the timer irq is not one of the mips irqs we need to |
@@ -458,9 +435,38 @@ int __init icu_of_init(struct device_node *node, struct device_node *parent) | |||
458 | if (MIPS_CPU_TIMER_IRQ != 7) | 435 | if (MIPS_CPU_TIMER_IRQ != 7) |
459 | irq_create_mapping(ltq_domain, MIPS_CPU_TIMER_IRQ); | 436 | irq_create_mapping(ltq_domain, MIPS_CPU_TIMER_IRQ); |
460 | 437 | ||
438 | /* the external interrupts are optional and xway only */ | ||
439 | eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu-xway"); | ||
440 | if (eiu_node && !of_address_to_resource(eiu_node, 0, &res)) { | ||
441 | /* find out how many external irq sources we have */ | ||
442 | exin_avail = of_irq_count(eiu_node); | ||
443 | |||
444 | if (exin_avail > MAX_EIU) | ||
445 | exin_avail = MAX_EIU; | ||
446 | |||
447 | ret = of_irq_to_resource_table(eiu_node, | ||
448 | ltq_eiu_irq, exin_avail); | ||
449 | if (ret != exin_avail) | ||
450 | panic("failed to load external irq resources"); | ||
451 | |||
452 | if (request_mem_region(res.start, resource_size(&res), | ||
453 | res.name) < 0) | ||
454 | pr_err("Failed to request eiu memory"); | ||
455 | |||
456 | ltq_eiu_membase = ioremap_nocache(res.start, | ||
457 | resource_size(&res)); | ||
458 | if (!ltq_eiu_membase) | ||
459 | panic("Failed to remap eiu memory"); | ||
460 | } | ||
461 | |||
461 | return 0; | 462 | return 0; |
462 | } | 463 | } |
463 | 464 | ||
465 | int get_c0_perfcount_int(void) | ||
466 | { | ||
467 | return ltq_perfcount_irq; | ||
468 | } | ||
469 | |||
464 | unsigned int get_c0_compare_int(void) | 470 | unsigned int get_c0_compare_int(void) |
465 | { | 471 | { |
466 | return MIPS_CPU_TIMER_IRQ; | 472 | return MIPS_CPU_TIMER_IRQ; |
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c index 7447d322d14e..39ab3e786e59 100644 --- a/arch/mips/lantiq/prom.c +++ b/arch/mips/lantiq/prom.c | |||
@@ -36,6 +36,11 @@ const char *get_system_type(void) | |||
36 | return soc_info.sys_type; | 36 | return soc_info.sys_type; |
37 | } | 37 | } |
38 | 38 | ||
39 | int ltq_soc_type(void) | ||
40 | { | ||
41 | return soc_info.type; | ||
42 | } | ||
43 | |||
39 | void prom_free_prom_memory(void) | 44 | void prom_free_prom_memory(void) |
40 | { | 45 | { |
41 | } | 46 | } |
@@ -72,6 +77,8 @@ void __init plat_mem_setup(void) | |||
72 | * parsed resulting in our memory appearing | 77 | * parsed resulting in our memory appearing |
73 | */ | 78 | */ |
74 | __dt_setup_arch(__dtb_start); | 79 | __dt_setup_arch(__dtb_start); |
80 | |||
81 | strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); | ||
75 | } | 82 | } |
76 | 83 | ||
77 | void __init device_tree_init(void) | 84 | void __init device_tree_init(void) |
@@ -97,16 +104,7 @@ void __init prom_init(void) | |||
97 | 104 | ||
98 | int __init plat_of_setup(void) | 105 | int __init plat_of_setup(void) |
99 | { | 106 | { |
100 | static struct of_device_id of_ids[3]; | 107 | return __dt_register_buses(soc_info.compatible, "simple-bus"); |
101 | |||
102 | if (!of_have_populated_dt()) | ||
103 | panic("device tree not present"); | ||
104 | |||
105 | strlcpy(of_ids[0].compatible, soc_info.compatible, | ||
106 | sizeof(of_ids[0].compatible)); | ||
107 | strncpy(of_ids[1].compatible, "simple-bus", | ||
108 | sizeof(of_ids[1].compatible)); | ||
109 | return of_platform_populate(NULL, of_ids, NULL, NULL); | ||
110 | } | 108 | } |
111 | 109 | ||
112 | arch_initcall(plat_of_setup); | 110 | arch_initcall(plat_of_setup); |
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile index 087497d97357..a2edc538f477 100644 --- a/arch/mips/lantiq/xway/Makefile +++ b/arch/mips/lantiq/xway/Makefile | |||
@@ -1,3 +1,5 @@ | |||
1 | obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o dcdc.o | 1 | obj-y := prom.o sysctrl.o clk.o reset.o dma.o gptu.o dcdc.o |
2 | 2 | ||
3 | obj-y += vmmc.o | ||
4 | |||
3 | obj-$(CONFIG_XRX200_PHY_FW) += xrx200_phy_fw.o | 5 | obj-$(CONFIG_XRX200_PHY_FW) += xrx200_phy_fw.o |
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c index 1fa0f175357e..fe68f9ae47c1 100644 --- a/arch/mips/lantiq/xway/reset.c +++ b/arch/mips/lantiq/xway/reset.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <linux/of_address.h> | 15 | #include <linux/of_address.h> |
16 | #include <linux/of_platform.h> | 16 | #include <linux/of_platform.h> |
17 | #include <linux/reset-controller.h> | ||
17 | 18 | ||
18 | #include <asm/reboot.h> | 19 | #include <asm/reboot.h> |
19 | 20 | ||
@@ -113,10 +114,77 @@ void ltq_reset_once(unsigned int module, ulong u) | |||
113 | ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ); | 114 | ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ); |
114 | } | 115 | } |
115 | 116 | ||
117 | static int ltq_assert_device(struct reset_controller_dev *rcdev, | ||
118 | unsigned long id) | ||
119 | { | ||
120 | u32 val; | ||
121 | |||
122 | if (id < 8) | ||
123 | return -1; | ||
124 | |||
125 | val = ltq_rcu_r32(RCU_RST_REQ); | ||
126 | val |= BIT(id); | ||
127 | ltq_rcu_w32(val, RCU_RST_REQ); | ||
128 | |||
129 | return 0; | ||
130 | } | ||
131 | |||
132 | static int ltq_deassert_device(struct reset_controller_dev *rcdev, | ||
133 | unsigned long id) | ||
134 | { | ||
135 | u32 val; | ||
136 | |||
137 | if (id < 8) | ||
138 | return -1; | ||
139 | |||
140 | val = ltq_rcu_r32(RCU_RST_REQ); | ||
141 | val &= ~BIT(id); | ||
142 | ltq_rcu_w32(val, RCU_RST_REQ); | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | static int ltq_reset_device(struct reset_controller_dev *rcdev, | ||
148 | unsigned long id) | ||
149 | { | ||
150 | ltq_assert_device(rcdev, id); | ||
151 | return ltq_deassert_device(rcdev, id); | ||
152 | } | ||
153 | |||
154 | static struct reset_control_ops reset_ops = { | ||
155 | .reset = ltq_reset_device, | ||
156 | .assert = ltq_assert_device, | ||
157 | .deassert = ltq_deassert_device, | ||
158 | }; | ||
159 | |||
160 | static struct reset_controller_dev reset_dev = { | ||
161 | .ops = &reset_ops, | ||
162 | .owner = THIS_MODULE, | ||
163 | .nr_resets = 32, | ||
164 | .of_reset_n_cells = 1, | ||
165 | }; | ||
166 | |||
167 | void ltq_rst_init(void) | ||
168 | { | ||
169 | reset_dev.of_node = of_find_compatible_node(NULL, NULL, | ||
170 | "lantiq,xway-reset"); | ||
171 | if (!reset_dev.of_node) | ||
172 | pr_err("Failed to find reset controller node"); | ||
173 | else | ||
174 | reset_controller_register(&reset_dev); | ||
175 | } | ||
176 | |||
116 | static void ltq_machine_restart(char *command) | 177 | static void ltq_machine_restart(char *command) |
117 | { | 178 | { |
179 | u32 val = ltq_rcu_r32(RCU_RST_REQ); | ||
180 | |||
181 | if (of_device_is_compatible(ltq_rcu_np, "lantiq,rcu-xrx200")) | ||
182 | val |= RCU_RD_GPHY1_XRX200 | RCU_RD_GPHY0_XRX200; | ||
183 | |||
184 | val |= RCU_RD_SRST; | ||
185 | |||
118 | local_irq_disable(); | 186 | local_irq_disable(); |
119 | ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | RCU_RD_SRST, RCU_RST_REQ); | 187 | ltq_rcu_w32(val, RCU_RST_REQ); |
120 | unreachable(); | 188 | unreachable(); |
121 | } | 189 | } |
122 | 190 | ||
diff --git a/arch/mips/lantiq/xway/vmmc.c b/arch/mips/lantiq/xway/vmmc.c new file mode 100644 index 000000000000..696cd57f6f13 --- /dev/null +++ b/arch/mips/lantiq/xway/vmmc.c | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2012 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/of_platform.h> | ||
11 | #include <linux/of_gpio.h> | ||
12 | #include <linux/dma-mapping.h> | ||
13 | |||
14 | #include <lantiq_soc.h> | ||
15 | |||
16 | static unsigned int *cp1_base; | ||
17 | |||
18 | unsigned int *ltq_get_cp1_base(void) | ||
19 | { | ||
20 | if (!cp1_base) | ||
21 | panic("no cp1 base was set\n"); | ||
22 | |||
23 | return cp1_base; | ||
24 | } | ||
25 | EXPORT_SYMBOL(ltq_get_cp1_base); | ||
26 | |||
27 | static int vmmc_probe(struct platform_device *pdev) | ||
28 | { | ||
29 | #define CP1_SIZE (1 << 20) | ||
30 | int gpio_count; | ||
31 | dma_addr_t dma; | ||
32 | |||
33 | cp1_base = | ||
34 | (void *) CPHYSADDR(dma_alloc_coherent(NULL, CP1_SIZE, | ||
35 | &dma, GFP_ATOMIC)); | ||
36 | |||
37 | gpio_count = of_gpio_count(pdev->dev.of_node); | ||
38 | while (gpio_count > 0) { | ||
39 | enum of_gpio_flags flags; | ||
40 | int gpio = of_get_gpio_flags(pdev->dev.of_node, | ||
41 | --gpio_count, &flags); | ||
42 | if (gpio_request(gpio, "vmmc-relay")) | ||
43 | continue; | ||
44 | dev_info(&pdev->dev, "requested GPIO %d\n", gpio); | ||
45 | gpio_direction_output(gpio, | ||
46 | (flags & OF_GPIO_ACTIVE_LOW) ? (0) : (1)); | ||
47 | } | ||
48 | |||
49 | dev_info(&pdev->dev, "reserved %dMB at 0x%p", CP1_SIZE >> 20, cp1_base); | ||
50 | |||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | static const struct of_device_id vmmc_match[] = { | ||
55 | { .compatible = "lantiq,vmmc-xway" }, | ||
56 | {}, | ||
57 | }; | ||
58 | MODULE_DEVICE_TABLE(of, vmmc_match); | ||
59 | |||
60 | static struct platform_driver vmmc_driver = { | ||
61 | .probe = vmmc_probe, | ||
62 | .driver = { | ||
63 | .name = "lantiq,vmmc", | ||
64 | .owner = THIS_MODULE, | ||
65 | .of_match_table = vmmc_match, | ||
66 | }, | ||
67 | }; | ||
68 | |||
69 | module_platform_driver(vmmc_driver); | ||
diff --git a/arch/mips/lantiq/xway/xrx200_phy_fw.c b/arch/mips/lantiq/xway/xrx200_phy_fw.c index d4d9d31f152e..7c1e54c6a36c 100644 --- a/arch/mips/lantiq/xway/xrx200_phy_fw.c +++ b/arch/mips/lantiq/xway/xrx200_phy_fw.c | |||
@@ -24,7 +24,28 @@ static dma_addr_t xway_gphy_load(struct platform_device *pdev) | |||
24 | void *fw_addr; | 24 | void *fw_addr; |
25 | size_t size; | 25 | size_t size; |
26 | 26 | ||
27 | if (of_property_read_string(pdev->dev.of_node, "firmware", &fw_name)) { | 27 | if (of_get_property(pdev->dev.of_node, "firmware1", NULL) || |
28 | of_get_property(pdev->dev.of_node, "firmware2", NULL)) { | ||
29 | switch (ltq_soc_type()) { | ||
30 | case SOC_TYPE_VR9: | ||
31 | if (of_property_read_string(pdev->dev.of_node, | ||
32 | "firmware1", &fw_name)) { | ||
33 | dev_err(&pdev->dev, | ||
34 | "failed to load firmware filename\n"); | ||
35 | return 0; | ||
36 | } | ||
37 | break; | ||
38 | case SOC_TYPE_VR9_2: | ||
39 | if (of_property_read_string(pdev->dev.of_node, | ||
40 | "firmware2", &fw_name)) { | ||
41 | dev_err(&pdev->dev, | ||
42 | "failed to load firmware filename\n"); | ||
43 | return 0; | ||
44 | } | ||
45 | break; | ||
46 | } | ||
47 | } else if (of_property_read_string(pdev->dev.of_node, | ||
48 | "firmware", &fw_name)) { | ||
28 | dev_err(&pdev->dev, "failed to load firmware filename\n"); | 49 | dev_err(&pdev->dev, "failed to load firmware filename\n"); |
29 | return 0; | 50 | return 0; |
30 | } | 51 | } |
diff --git a/arch/mips/lib/iomap.c b/arch/mips/lib/iomap.c index e3acb2dad33a..8e7e378ce51c 100644 --- a/arch/mips/lib/iomap.c +++ b/arch/mips/lib/iomap.c | |||
@@ -97,14 +97,14 @@ EXPORT_SYMBOL(iowrite32be); | |||
97 | 97 | ||
98 | /* | 98 | /* |
99 | * These are the "repeat MMIO read/write" functions. | 99 | * These are the "repeat MMIO read/write" functions. |
100 | * Note the "__raw" accesses, since we don't want to | 100 | * Note the "__mem" accesses, since we want to convert |
101 | * convert to CPU byte order. We write in "IO byte | 101 | * to CPU byte order if the host bus happens to not match the |
102 | * order" (we also don't have IO barriers). | 102 | * endianness of PCI/ISA (see mach-generic/mangle-port.h). |
103 | */ | 103 | */ |
104 | static inline void mmio_insb(void __iomem *addr, u8 *dst, int count) | 104 | static inline void mmio_insb(void __iomem *addr, u8 *dst, int count) |
105 | { | 105 | { |
106 | while (--count >= 0) { | 106 | while (--count >= 0) { |
107 | u8 data = __raw_readb(addr); | 107 | u8 data = __mem_readb(addr); |
108 | *dst = data; | 108 | *dst = data; |
109 | dst++; | 109 | dst++; |
110 | } | 110 | } |
@@ -113,7 +113,7 @@ static inline void mmio_insb(void __iomem *addr, u8 *dst, int count) | |||
113 | static inline void mmio_insw(void __iomem *addr, u16 *dst, int count) | 113 | static inline void mmio_insw(void __iomem *addr, u16 *dst, int count) |
114 | { | 114 | { |
115 | while (--count >= 0) { | 115 | while (--count >= 0) { |
116 | u16 data = __raw_readw(addr); | 116 | u16 data = __mem_readw(addr); |
117 | *dst = data; | 117 | *dst = data; |
118 | dst++; | 118 | dst++; |
119 | } | 119 | } |
@@ -122,7 +122,7 @@ static inline void mmio_insw(void __iomem *addr, u16 *dst, int count) | |||
122 | static inline void mmio_insl(void __iomem *addr, u32 *dst, int count) | 122 | static inline void mmio_insl(void __iomem *addr, u32 *dst, int count) |
123 | { | 123 | { |
124 | while (--count >= 0) { | 124 | while (--count >= 0) { |
125 | u32 data = __raw_readl(addr); | 125 | u32 data = __mem_readl(addr); |
126 | *dst = data; | 126 | *dst = data; |
127 | dst++; | 127 | dst++; |
128 | } | 128 | } |
@@ -131,7 +131,7 @@ static inline void mmio_insl(void __iomem *addr, u32 *dst, int count) | |||
131 | static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count) | 131 | static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count) |
132 | { | 132 | { |
133 | while (--count >= 0) { | 133 | while (--count >= 0) { |
134 | __raw_writeb(*src, addr); | 134 | __mem_writeb(*src, addr); |
135 | src++; | 135 | src++; |
136 | } | 136 | } |
137 | } | 137 | } |
@@ -139,7 +139,7 @@ static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count) | |||
139 | static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count) | 139 | static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count) |
140 | { | 140 | { |
141 | while (--count >= 0) { | 141 | while (--count >= 0) { |
142 | __raw_writew(*src, addr); | 142 | __mem_writew(*src, addr); |
143 | src++; | 143 | src++; |
144 | } | 144 | } |
145 | } | 145 | } |
@@ -147,7 +147,7 @@ static inline void mmio_outsw(void __iomem *addr, const u16 *src, int count) | |||
147 | static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count) | 147 | static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count) |
148 | { | 148 | { |
149 | while (--count >= 0) { | 149 | while (--count >= 0) { |
150 | __raw_writel(*src, addr); | 150 | __mem_writel(*src, addr); |
151 | src++; | 151 | src++; |
152 | } | 152 | } |
153 | } | 153 | } |
diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S index 7b0e5462ca51..c8fe6b1968fb 100644 --- a/arch/mips/lib/memset.S +++ b/arch/mips/lib/memset.S | |||
@@ -114,8 +114,7 @@ | |||
114 | R10KCBARRIER(0(ra)) | 114 | R10KCBARRIER(0(ra)) |
115 | #ifdef __MIPSEB__ | 115 | #ifdef __MIPSEB__ |
116 | EX(LONG_S_L, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */ | 116 | EX(LONG_S_L, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */ |
117 | #endif | 117 | #else |
118 | #ifdef __MIPSEL__ | ||
119 | EX(LONG_S_R, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */ | 118 | EX(LONG_S_R, a1, (a0), .Lfirst_fixup\@) /* make word/dword aligned */ |
120 | #endif | 119 | #endif |
121 | PTR_SUBU a0, t0 /* long align ptr */ | 120 | PTR_SUBU a0, t0 /* long align ptr */ |
@@ -164,8 +163,7 @@ | |||
164 | R10KCBARRIER(0(ra)) | 163 | R10KCBARRIER(0(ra)) |
165 | #ifdef __MIPSEB__ | 164 | #ifdef __MIPSEB__ |
166 | EX(LONG_S_R, a1, -1(a0), .Llast_fixup\@) | 165 | EX(LONG_S_R, a1, -1(a0), .Llast_fixup\@) |
167 | #endif | 166 | #else |
168 | #ifdef __MIPSEL__ | ||
169 | EX(LONG_S_L, a1, -1(a0), .Llast_fixup\@) | 167 | EX(LONG_S_L, a1, -1(a0), .Llast_fixup\@) |
170 | #endif | 168 | #endif |
171 | 1: jr ra | 169 | 1: jr ra |
diff --git a/arch/mips/lib/mips-atomic.c b/arch/mips/lib/mips-atomic.c index 57bcdaf1f1c8..be777d9a3f85 100644 --- a/arch/mips/lib/mips-atomic.c +++ b/arch/mips/lib/mips-atomic.c | |||
@@ -42,15 +42,11 @@ notrace void arch_local_irq_disable(void) | |||
42 | __asm__ __volatile__( | 42 | __asm__ __volatile__( |
43 | " .set push \n" | 43 | " .set push \n" |
44 | " .set noat \n" | 44 | " .set noat \n" |
45 | #if defined(CONFIG_CPU_MIPSR2) | ||
46 | /* see irqflags.h for inline function */ | ||
47 | #else | ||
48 | " mfc0 $1,$12 \n" | 45 | " mfc0 $1,$12 \n" |
49 | " ori $1,0x1f \n" | 46 | " ori $1,0x1f \n" |
50 | " xori $1,0x1f \n" | 47 | " xori $1,0x1f \n" |
51 | " .set noreorder \n" | 48 | " .set noreorder \n" |
52 | " mtc0 $1,$12 \n" | 49 | " mtc0 $1,$12 \n" |
53 | #endif | ||
54 | " " __stringify(__irq_disable_hazard) " \n" | 50 | " " __stringify(__irq_disable_hazard) " \n" |
55 | " .set pop \n" | 51 | " .set pop \n" |
56 | : /* no outputs */ | 52 | : /* no outputs */ |
@@ -72,15 +68,11 @@ notrace unsigned long arch_local_irq_save(void) | |||
72 | " .set push \n" | 68 | " .set push \n" |
73 | " .set reorder \n" | 69 | " .set reorder \n" |
74 | " .set noat \n" | 70 | " .set noat \n" |
75 | #if defined(CONFIG_CPU_MIPSR2) | ||
76 | /* see irqflags.h for inline function */ | ||
77 | #else | ||
78 | " mfc0 %[flags], $12 \n" | 71 | " mfc0 %[flags], $12 \n" |
79 | " ori $1, %[flags], 0x1f \n" | 72 | " ori $1, %[flags], 0x1f \n" |
80 | " xori $1, 0x1f \n" | 73 | " xori $1, 0x1f \n" |
81 | " .set noreorder \n" | 74 | " .set noreorder \n" |
82 | " mtc0 $1, $12 \n" | 75 | " mtc0 $1, $12 \n" |
83 | #endif | ||
84 | " " __stringify(__irq_disable_hazard) " \n" | 76 | " " __stringify(__irq_disable_hazard) " \n" |
85 | " .set pop \n" | 77 | " .set pop \n" |
86 | : [flags] "=r" (flags) | 78 | : [flags] "=r" (flags) |
@@ -103,18 +95,12 @@ notrace void arch_local_irq_restore(unsigned long flags) | |||
103 | " .set push \n" | 95 | " .set push \n" |
104 | " .set noreorder \n" | 96 | " .set noreorder \n" |
105 | " .set noat \n" | 97 | " .set noat \n" |
106 | #if defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) | ||
107 | /* see irqflags.h for inline function */ | ||
108 | #elif defined(CONFIG_CPU_MIPSR2) | ||
109 | /* see irqflags.h for inline function */ | ||
110 | #else | ||
111 | " mfc0 $1, $12 \n" | 98 | " mfc0 $1, $12 \n" |
112 | " andi %[flags], 1 \n" | 99 | " andi %[flags], 1 \n" |
113 | " ori $1, 0x1f \n" | 100 | " ori $1, 0x1f \n" |
114 | " xori $1, 0x1f \n" | 101 | " xori $1, 0x1f \n" |
115 | " or %[flags], $1 \n" | 102 | " or %[flags], $1 \n" |
116 | " mtc0 %[flags], $12 \n" | 103 | " mtc0 %[flags], $12 \n" |
117 | #endif | ||
118 | " " __stringify(__irq_disable_hazard) " \n" | 104 | " " __stringify(__irq_disable_hazard) " \n" |
119 | " .set pop \n" | 105 | " .set pop \n" |
120 | : [flags] "=r" (__tmp1) | 106 | : [flags] "=r" (__tmp1) |
@@ -136,18 +122,12 @@ notrace void __arch_local_irq_restore(unsigned long flags) | |||
136 | " .set push \n" | 122 | " .set push \n" |
137 | " .set noreorder \n" | 123 | " .set noreorder \n" |
138 | " .set noat \n" | 124 | " .set noat \n" |
139 | #if defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) | ||
140 | /* see irqflags.h for inline function */ | ||
141 | #elif defined(CONFIG_CPU_MIPSR2) | ||
142 | /* see irqflags.h for inline function */ | ||
143 | #else | ||
144 | " mfc0 $1, $12 \n" | 125 | " mfc0 $1, $12 \n" |
145 | " andi %[flags], 1 \n" | 126 | " andi %[flags], 1 \n" |
146 | " ori $1, 0x1f \n" | 127 | " ori $1, 0x1f \n" |
147 | " xori $1, 0x1f \n" | 128 | " xori $1, 0x1f \n" |
148 | " or %[flags], $1 \n" | 129 | " or %[flags], $1 \n" |
149 | " mtc0 %[flags], $12 \n" | 130 | " mtc0 %[flags], $12 \n" |
150 | #endif | ||
151 | " " __stringify(__irq_disable_hazard) " \n" | 131 | " " __stringify(__irq_disable_hazard) " \n" |
152 | " .set pop \n" | 132 | " .set pop \n" |
153 | : [flags] "=r" (__tmp1) | 133 | : [flags] "=r" (__tmp1) |
diff --git a/arch/mips/lib/r3k_dump_tlb.c b/arch/mips/lib/r3k_dump_tlb.c index 1ef365ab3cd3..975a13855116 100644 --- a/arch/mips/lib/r3k_dump_tlb.c +++ b/arch/mips/lib/r3k_dump_tlb.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/mm.h> | 9 | #include <linux/mm.h> |
10 | 10 | ||
11 | #include <asm/mipsregs.h> | 11 | #include <asm/mipsregs.h> |
12 | #include <asm/mmu_context.h> | ||
12 | #include <asm/page.h> | 13 | #include <asm/page.h> |
13 | #include <asm/pgtable.h> | 14 | #include <asm/pgtable.h> |
14 | #include <asm/tlbdebug.h> | 15 | #include <asm/tlbdebug.h> |
@@ -21,7 +22,7 @@ static void dump_tlb(int first, int last) | |||
21 | unsigned int asid; | 22 | unsigned int asid; |
22 | unsigned long entryhi, entrylo0; | 23 | unsigned long entryhi, entrylo0; |
23 | 24 | ||
24 | asid = read_c0_entryhi() & 0xfc0; | 25 | asid = read_c0_entryhi() & ASID_MASK; |
25 | 26 | ||
26 | for (i = first; i <= last; i++) { | 27 | for (i = first; i <= last; i++) { |
27 | write_c0_index(i<<8); | 28 | write_c0_index(i<<8); |
@@ -34,8 +35,8 @@ static void dump_tlb(int first, int last) | |||
34 | entrylo0 = read_c0_entrylo0(); | 35 | entrylo0 = read_c0_entrylo0(); |
35 | 36 | ||
36 | /* Unused entries have a virtual address of KSEG0. */ | 37 | /* Unused entries have a virtual address of KSEG0. */ |
37 | if ((entryhi & 0xfffff000) != 0x80000000 | 38 | if ((entryhi & PAGE_MASK) != KSEG0 |
38 | && (entryhi & 0xfc0) == asid) { | 39 | && (entryhi & ASID_MASK) == asid) { |
39 | /* | 40 | /* |
40 | * Only print entries in use | 41 | * Only print entries in use |
41 | */ | 42 | */ |
@@ -43,8 +44,8 @@ static void dump_tlb(int first, int last) | |||
43 | 44 | ||
44 | printk("va=%08lx asid=%08lx" | 45 | printk("va=%08lx asid=%08lx" |
45 | " [pa=%06lx n=%d d=%d v=%d g=%d]", | 46 | " [pa=%06lx n=%d d=%d v=%d g=%d]", |
46 | (entryhi & 0xfffff000), | 47 | entryhi & PAGE_MASK, |
47 | entryhi & 0xfc0, | 48 | entryhi & ASID_MASK, |
48 | entrylo0 & PAGE_MASK, | 49 | entrylo0 & PAGE_MASK, |
49 | (entrylo0 & (1 << 11)) ? 1 : 0, | 50 | (entrylo0 & (1 << 11)) ? 1 : 0, |
50 | (entrylo0 & (1 << 10)) ? 1 : 0, | 51 | (entrylo0 & (1 << 10)) ? 1 : 0, |
diff --git a/arch/mips/lib/strlen_user.S b/arch/mips/lib/strlen_user.S index bef65c98df59..929bbacd697e 100644 --- a/arch/mips/lib/strlen_user.S +++ b/arch/mips/lib/strlen_user.S | |||
@@ -28,7 +28,6 @@ LEAF(__strlen_\func\()_asm) | |||
28 | and v0, a0 | 28 | and v0, a0 |
29 | bnez v0, .Lfault\@ | 29 | bnez v0, .Lfault\@ |
30 | 30 | ||
31 | FEXPORT(__strlen_\func\()_nocheck_asm) | ||
32 | move v0, a0 | 31 | move v0, a0 |
33 | .ifeqs "\func", "kernel" | 32 | .ifeqs "\func", "kernel" |
34 | 1: EX(lbu, v1, (v0), .Lfault\@) | 33 | 1: EX(lbu, v1, (v0), .Lfault\@) |
@@ -48,9 +47,7 @@ FEXPORT(__strlen_\func\()_nocheck_asm) | |||
48 | #ifndef CONFIG_EVA | 47 | #ifndef CONFIG_EVA |
49 | /* Set aliases */ | 48 | /* Set aliases */ |
50 | .global __strlen_user_asm | 49 | .global __strlen_user_asm |
51 | .global __strlen_user_nocheck_asm | ||
52 | .set __strlen_user_asm, __strlen_kernel_asm | 50 | .set __strlen_user_asm, __strlen_kernel_asm |
53 | .set __strlen_user_nocheck_asm, __strlen_kernel_nocheck_asm | ||
54 | #endif | 51 | #endif |
55 | 52 | ||
56 | __BUILD_STRLEN_ASM kernel | 53 | __BUILD_STRLEN_ASM kernel |
diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig index 1b91fc6a921b..156de85b82cd 100644 --- a/arch/mips/loongson/Kconfig +++ b/arch/mips/loongson/Kconfig | |||
@@ -86,6 +86,7 @@ config LOONGSON_MACH3X | |||
86 | select LOONGSON_MC146818 | 86 | select LOONGSON_MC146818 |
87 | select ZONE_DMA32 | 87 | select ZONE_DMA32 |
88 | select LEFI_FIRMWARE_INTERFACE | 88 | select LEFI_FIRMWARE_INTERFACE |
89 | select PHYS48_TO_HT40 | ||
89 | help | 90 | help |
90 | Generic Loongson 3 family machines utilize the 3A/3B revision | 91 | Generic Loongson 3 family machines utilize the 3A/3B revision |
91 | of Loongson processor and RS780/SBX00 chipset. | 92 | of Loongson processor and RS780/SBX00 chipset. |
@@ -107,6 +108,18 @@ config CS5536_MFGPT | |||
107 | 108 | ||
108 | If unsure, say Yes. | 109 | If unsure, say Yes. |
109 | 110 | ||
111 | config RS780_HPET | ||
112 | bool "RS780/SBX00 HPET Timer" | ||
113 | depends on LOONGSON_MACH3X | ||
114 | select MIPS_EXTERNAL_TIMER | ||
115 | help | ||
116 | This option enables the hpet timer of AMD RS780/SBX00. | ||
117 | |||
118 | If you want to enable the Loongson3 CPUFreq Driver, Please enable | ||
119 | this option at first, otherwise, You will get wrong system time. | ||
120 | |||
121 | If unsure, say Yes. | ||
122 | |||
110 | config LOONGSON_SUSPEND | 123 | config LOONGSON_SUSPEND |
111 | bool | 124 | bool |
112 | default y | 125 | default y |
@@ -131,6 +144,10 @@ config SWIOTLB | |||
131 | select NEED_SG_DMA_LENGTH | 144 | select NEED_SG_DMA_LENGTH |
132 | select NEED_DMA_MAP_STATE | 145 | select NEED_DMA_MAP_STATE |
133 | 146 | ||
147 | config PHYS48_TO_HT40 | ||
148 | bool | ||
149 | default y if CPU_LOONGSON3 | ||
150 | |||
134 | config LOONGSON_MC146818 | 151 | config LOONGSON_MC146818 |
135 | bool | 152 | bool |
136 | default n | 153 | default n |
diff --git a/arch/mips/loongson/common/cs5536/cs5536_pci.c b/arch/mips/loongson/common/cs5536/cs5536_pci.c index 81bed9d18061..b739723205f8 100644 --- a/arch/mips/loongson/common/cs5536/cs5536_pci.c +++ b/arch/mips/loongson/common/cs5536/cs5536_pci.c | |||
@@ -21,6 +21,7 @@ | |||
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
24 | #include <cs5536/cs5536_pci.h> | ||
24 | #include <cs5536/cs5536_vsm.h> | 25 | #include <cs5536/cs5536_vsm.h> |
25 | 26 | ||
26 | enum { | 27 | enum { |
@@ -35,21 +36,21 @@ enum { | |||
35 | }; | 36 | }; |
36 | 37 | ||
37 | static const cs5536_pci_vsm_write vsm_conf_write[] = { | 38 | static const cs5536_pci_vsm_write vsm_conf_write[] = { |
38 | [CS5536_ISA_FUNC] pci_isa_write_reg, | 39 | [CS5536_ISA_FUNC] = pci_isa_write_reg, |
39 | [reserved_func] NULL, | 40 | [reserved_func] = NULL, |
40 | [CS5536_IDE_FUNC] pci_ide_write_reg, | 41 | [CS5536_IDE_FUNC] = pci_ide_write_reg, |
41 | [CS5536_ACC_FUNC] pci_acc_write_reg, | 42 | [CS5536_ACC_FUNC] = pci_acc_write_reg, |
42 | [CS5536_OHCI_FUNC] pci_ohci_write_reg, | 43 | [CS5536_OHCI_FUNC] = pci_ohci_write_reg, |
43 | [CS5536_EHCI_FUNC] pci_ehci_write_reg, | 44 | [CS5536_EHCI_FUNC] = pci_ehci_write_reg, |
44 | }; | 45 | }; |
45 | 46 | ||
46 | static const cs5536_pci_vsm_read vsm_conf_read[] = { | 47 | static const cs5536_pci_vsm_read vsm_conf_read[] = { |
47 | [CS5536_ISA_FUNC] pci_isa_read_reg, | 48 | [CS5536_ISA_FUNC] = pci_isa_read_reg, |
48 | [reserved_func] NULL, | 49 | [reserved_func] = NULL, |
49 | [CS5536_IDE_FUNC] pci_ide_read_reg, | 50 | [CS5536_IDE_FUNC] = pci_ide_read_reg, |
50 | [CS5536_ACC_FUNC] pci_acc_read_reg, | 51 | [CS5536_ACC_FUNC] = pci_acc_read_reg, |
51 | [CS5536_OHCI_FUNC] pci_ohci_read_reg, | 52 | [CS5536_OHCI_FUNC] = pci_ohci_read_reg, |
52 | [CS5536_EHCI_FUNC] pci_ehci_read_reg, | 53 | [CS5536_EHCI_FUNC] = pci_ehci_read_reg, |
53 | }; | 54 | }; |
54 | 55 | ||
55 | /* | 56 | /* |
diff --git a/arch/mips/loongson/common/dma-swiotlb.c b/arch/mips/loongson/common/dma-swiotlb.c index c2be01f91575..2c6b989c1bc4 100644 --- a/arch/mips/loongson/common/dma-swiotlb.c +++ b/arch/mips/loongson/common/dma-swiotlb.c | |||
@@ -105,11 +105,25 @@ static int loongson_dma_set_mask(struct device *dev, u64 mask) | |||
105 | 105 | ||
106 | dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) | 106 | dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr) |
107 | { | 107 | { |
108 | long nid; | ||
109 | #ifdef CONFIG_PHYS48_TO_HT40 | ||
110 | /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from | ||
111 | * Loongson-3's 48bit address space and embed it into 40bit */ | ||
112 | nid = (paddr >> 44) & 0x3; | ||
113 | paddr = ((nid << 44) ^ paddr) | (nid << 37); | ||
114 | #endif | ||
108 | return paddr; | 115 | return paddr; |
109 | } | 116 | } |
110 | 117 | ||
111 | phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) | 118 | phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr) |
112 | { | 119 | { |
120 | long nid; | ||
121 | #ifdef CONFIG_PHYS48_TO_HT40 | ||
122 | /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from | ||
123 | * Loongson-3's 48bit address space and embed it into 40bit */ | ||
124 | nid = (daddr >> 37) & 0x3; | ||
125 | daddr = ((nid << 37) ^ daddr) | (nid << 44); | ||
126 | #endif | ||
113 | return daddr; | 127 | return daddr; |
114 | } | 128 | } |
115 | 129 | ||
diff --git a/arch/mips/loongson/common/early_printk.c b/arch/mips/loongson/common/early_printk.c index ced461b39069..6ca632e529dc 100644 --- a/arch/mips/loongson/common/early_printk.c +++ b/arch/mips/loongson/common/early_printk.c | |||
@@ -30,7 +30,7 @@ void prom_putchar(char c) | |||
30 | int timeout; | 30 | int timeout; |
31 | unsigned char *uart_base; | 31 | unsigned char *uart_base; |
32 | 32 | ||
33 | uart_base = (unsigned char *)_loongson_uart_base; | 33 | uart_base = (unsigned char *)_loongson_uart_base[0]; |
34 | timeout = 1024; | 34 | timeout = 1024; |
35 | 35 | ||
36 | while (((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) && | 36 | while (((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) && |
diff --git a/arch/mips/loongson/common/env.c b/arch/mips/loongson/common/env.c index f15228550a22..045ea3d47c87 100644 --- a/arch/mips/loongson/common/env.c +++ b/arch/mips/loongson/common/env.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/bootinfo.h> | 21 | #include <asm/bootinfo.h> |
22 | #include <loongson.h> | 22 | #include <loongson.h> |
23 | #include <boot_param.h> | 23 | #include <boot_param.h> |
24 | #include <workarounds.h> | ||
24 | 25 | ||
25 | u32 cpu_clock_freq; | 26 | u32 cpu_clock_freq; |
26 | EXPORT_SYMBOL(cpu_clock_freq); | 27 | EXPORT_SYMBOL(cpu_clock_freq); |
@@ -31,7 +32,6 @@ u64 loongson_chipcfg[MAX_PACKAGES] = {0xffffffffbfc00180}; | |||
31 | u64 loongson_freqctrl[MAX_PACKAGES]; | 32 | u64 loongson_freqctrl[MAX_PACKAGES]; |
32 | 33 | ||
33 | unsigned long long smp_group[4]; | 34 | unsigned long long smp_group[4]; |
34 | int cpuhotplug_workaround = 0; | ||
35 | 35 | ||
36 | #define parse_even_earlier(res, option, p) \ | 36 | #define parse_even_earlier(res, option, p) \ |
37 | do { \ | 37 | do { \ |
@@ -67,6 +67,7 @@ void __init prom_init_env(void) | |||
67 | #else | 67 | #else |
68 | struct boot_params *boot_p; | 68 | struct boot_params *boot_p; |
69 | struct loongson_params *loongson_p; | 69 | struct loongson_params *loongson_p; |
70 | struct system_loongson *esys; | ||
70 | struct efi_cpuinfo_loongson *ecpu; | 71 | struct efi_cpuinfo_loongson *ecpu; |
71 | struct irq_source_routing_table *eirq_source; | 72 | struct irq_source_routing_table *eirq_source; |
72 | 73 | ||
@@ -74,6 +75,8 @@ void __init prom_init_env(void) | |||
74 | boot_p = (struct boot_params *)fw_arg2; | 75 | boot_p = (struct boot_params *)fw_arg2; |
75 | loongson_p = &(boot_p->efi.smbios.lp); | 76 | loongson_p = &(boot_p->efi.smbios.lp); |
76 | 77 | ||
78 | esys = (struct system_loongson *) | ||
79 | ((u64)loongson_p + loongson_p->system_offset); | ||
77 | ecpu = (struct efi_cpuinfo_loongson *) | 80 | ecpu = (struct efi_cpuinfo_loongson *) |
78 | ((u64)loongson_p + loongson_p->cpu_offset); | 81 | ((u64)loongson_p + loongson_p->cpu_offset); |
79 | eirq_source = (struct irq_source_routing_table *) | 82 | eirq_source = (struct irq_source_routing_table *) |
@@ -95,6 +98,7 @@ void __init prom_init_env(void) | |||
95 | loongson_chipcfg[2] = 0x900020001fe00180; | 98 | loongson_chipcfg[2] = 0x900020001fe00180; |
96 | loongson_chipcfg[3] = 0x900030001fe00180; | 99 | loongson_chipcfg[3] = 0x900030001fe00180; |
97 | loongson_sysconf.ht_control_base = 0x90000EFDFB000000; | 100 | loongson_sysconf.ht_control_base = 0x90000EFDFB000000; |
101 | loongson_sysconf.workarounds = WORKAROUND_CPUFREQ; | ||
98 | } else if (ecpu->cputype == Loongson_3B) { | 102 | } else if (ecpu->cputype == Loongson_3B) { |
99 | loongson_sysconf.cores_per_node = 4; /* One chip has 2 nodes */ | 103 | loongson_sysconf.cores_per_node = 4; /* One chip has 2 nodes */ |
100 | loongson_sysconf.cores_per_package = 8; | 104 | loongson_sysconf.cores_per_package = 8; |
@@ -111,7 +115,7 @@ void __init prom_init_env(void) | |||
111 | loongson_freqctrl[2] = 0x900040001fe001d0; | 115 | loongson_freqctrl[2] = 0x900040001fe001d0; |
112 | loongson_freqctrl[3] = 0x900060001fe001d0; | 116 | loongson_freqctrl[3] = 0x900060001fe001d0; |
113 | loongson_sysconf.ht_control_base = 0x90001EFDFB000000; | 117 | loongson_sysconf.ht_control_base = 0x90001EFDFB000000; |
114 | cpuhotplug_workaround = 1; | 118 | loongson_sysconf.workarounds = WORKAROUND_CPUHOTPLUG; |
115 | } else { | 119 | } else { |
116 | loongson_sysconf.cores_per_node = 1; | 120 | loongson_sysconf.cores_per_node = 1; |
117 | loongson_sysconf.cores_per_package = 1; | 121 | loongson_sysconf.cores_per_package = 1; |
@@ -119,6 +123,8 @@ void __init prom_init_env(void) | |||
119 | } | 123 | } |
120 | 124 | ||
121 | loongson_sysconf.nr_cpus = ecpu->nr_cpus; | 125 | loongson_sysconf.nr_cpus = ecpu->nr_cpus; |
126 | loongson_sysconf.boot_cpu_id = ecpu->cpu_startup_core_id; | ||
127 | loongson_sysconf.reserved_cpus_mask = ecpu->reserved_cores_mask; | ||
122 | if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0) | 128 | if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0) |
123 | loongson_sysconf.nr_cpus = NR_CPUS; | 129 | loongson_sysconf.nr_cpus = NR_CPUS; |
124 | loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus + | 130 | loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus + |
@@ -141,6 +147,24 @@ void __init prom_init_env(void) | |||
141 | pr_debug("Shutdown Addr: %llx, Restart Addr: %llx, VBIOS Addr: %llx\n", | 147 | pr_debug("Shutdown Addr: %llx, Restart Addr: %llx, VBIOS Addr: %llx\n", |
142 | loongson_sysconf.poweroff_addr, loongson_sysconf.restart_addr, | 148 | loongson_sysconf.poweroff_addr, loongson_sysconf.restart_addr, |
143 | loongson_sysconf.vgabios_addr); | 149 | loongson_sysconf.vgabios_addr); |
150 | |||
151 | memset(loongson_sysconf.ecname, 0, 32); | ||
152 | if (esys->has_ec) | ||
153 | memcpy(loongson_sysconf.ecname, esys->ec_name, 32); | ||
154 | loongson_sysconf.workarounds |= esys->workarounds; | ||
155 | |||
156 | loongson_sysconf.nr_uarts = esys->nr_uarts; | ||
157 | if (esys->nr_uarts < 1 || esys->nr_uarts > MAX_UARTS) | ||
158 | loongson_sysconf.nr_uarts = 1; | ||
159 | memcpy(loongson_sysconf.uarts, esys->uarts, | ||
160 | sizeof(struct uart_device) * loongson_sysconf.nr_uarts); | ||
161 | |||
162 | loongson_sysconf.nr_sensors = esys->nr_sensors; | ||
163 | if (loongson_sysconf.nr_sensors > MAX_SENSORS) | ||
164 | loongson_sysconf.nr_sensors = 0; | ||
165 | if (loongson_sysconf.nr_sensors) | ||
166 | memcpy(loongson_sysconf.sensors, esys->sensors, | ||
167 | sizeof(struct sensor_device) * loongson_sysconf.nr_sensors); | ||
144 | #endif | 168 | #endif |
145 | if (cpu_clock_freq == 0) { | 169 | if (cpu_clock_freq == 0) { |
146 | processor_id = (¤t_cpu_data)->processor_id; | 170 | processor_id = (¤t_cpu_data)->processor_id; |
diff --git a/arch/mips/loongson/common/gpio.c b/arch/mips/loongson/common/gpio.c index 21869908aaa4..29dbaa253061 100644 --- a/arch/mips/loongson/common/gpio.c +++ b/arch/mips/loongson/common/gpio.c | |||
@@ -37,7 +37,7 @@ int gpio_get_value(unsigned gpio) | |||
37 | val = LOONGSON_GPIODATA; | 37 | val = LOONGSON_GPIODATA; |
38 | spin_unlock(&gpio_lock); | 38 | spin_unlock(&gpio_lock); |
39 | 39 | ||
40 | return ((val & mask) != 0); | 40 | return (val & mask) != 0; |
41 | } | 41 | } |
42 | EXPORT_SYMBOL(gpio_get_value); | 42 | EXPORT_SYMBOL(gpio_get_value); |
43 | 43 | ||
diff --git a/arch/mips/loongson/common/init.c b/arch/mips/loongson/common/init.c index f6af3aba4c86..9b987fe98b5b 100644 --- a/arch/mips/loongson/common/init.c +++ b/arch/mips/loongson/common/init.c | |||
@@ -9,6 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/bootmem.h> | 11 | #include <linux/bootmem.h> |
12 | #include <asm/bootinfo.h> | ||
12 | #include <asm/smp-ops.h> | 13 | #include <asm/smp-ops.h> |
13 | 14 | ||
14 | #include <loongson.h> | 15 | #include <loongson.h> |
diff --git a/arch/mips/loongson/common/machtype.c b/arch/mips/loongson/common/machtype.c index 1a4797984b8d..f2807bc662a3 100644 --- a/arch/mips/loongson/common/machtype.c +++ b/arch/mips/loongson/common/machtype.c | |||
@@ -19,19 +19,16 @@ | |||
19 | #define MACHTYPE_LEN 50 | 19 | #define MACHTYPE_LEN 50 |
20 | 20 | ||
21 | static const char *system_types[] = { | 21 | static const char *system_types[] = { |
22 | [MACH_LOONGSON_UNKNOWN] "unknown loongson machine", | 22 | [MACH_LOONGSON_UNKNOWN] = "unknown loongson machine", |
23 | [MACH_LEMOTE_FL2E] "lemote-fuloong-2e-box", | 23 | [MACH_LEMOTE_FL2E] = "lemote-fuloong-2e-box", |
24 | [MACH_LEMOTE_FL2F] "lemote-fuloong-2f-box", | 24 | [MACH_LEMOTE_FL2F] = "lemote-fuloong-2f-box", |
25 | [MACH_LEMOTE_ML2F7] "lemote-mengloong-2f-7inches", | 25 | [MACH_LEMOTE_ML2F7] = "lemote-mengloong-2f-7inches", |
26 | [MACH_LEMOTE_YL2F89] "lemote-yeeloong-2f-8.9inches", | 26 | [MACH_LEMOTE_YL2F89] = "lemote-yeeloong-2f-8.9inches", |
27 | [MACH_DEXXON_GDIUM2F10] "dexxon-gdium-2f", | 27 | [MACH_DEXXON_GDIUM2F10] = "dexxon-gdium-2f", |
28 | [MACH_LEMOTE_NAS] "lemote-nas-2f", | 28 | [MACH_LEMOTE_NAS] = "lemote-nas-2f", |
29 | [MACH_LEMOTE_LL2F] "lemote-lynloong-2f", | 29 | [MACH_LEMOTE_LL2F] = "lemote-lynloong-2f", |
30 | [MACH_LEMOTE_A1004] "lemote-3a-notebook-a1004", | 30 | [MACH_LOONGSON_GENERIC] = "generic-loongson-machine", |
31 | [MACH_LEMOTE_A1101] "lemote-3a-itx-a1101", | 31 | [MACH_LOONGSON_END] = NULL, |
32 | [MACH_LEMOTE_A1201] "lemote-2gq-notebook-a1201", | ||
33 | [MACH_LEMOTE_A1205] "lemote-2gq-aio-a1205", | ||
34 | [MACH_LOONGSON_END] NULL, | ||
35 | }; | 32 | }; |
36 | 33 | ||
37 | const char *get_system_type(void) | 34 | const char *get_system_type(void) |
diff --git a/arch/mips/loongson/common/rtc.c b/arch/mips/loongson/common/rtc.c index a90d87c01555..b5709af09f7f 100644 --- a/arch/mips/loongson/common/rtc.c +++ b/arch/mips/loongson/common/rtc.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/mc146818rtc.h> | 15 | #include <linux/mc146818rtc.h> |
16 | 16 | ||
17 | struct resource loongson_rtc_resources[] = { | 17 | static struct resource loongson_rtc_resources[] = { |
18 | { | 18 | { |
19 | .start = RTC_PORT(0), | 19 | .start = RTC_PORT(0), |
20 | .end = RTC_PORT(1), | 20 | .end = RTC_PORT(1), |
diff --git a/arch/mips/loongson/common/serial.c b/arch/mips/loongson/common/serial.c index bd2b7095b6dc..c23fa1373729 100644 --- a/arch/mips/loongson/common/serial.c +++ b/arch/mips/loongson/common/serial.c | |||
@@ -38,20 +38,17 @@ | |||
38 | .regshift = 0, \ | 38 | .regshift = 0, \ |
39 | } | 39 | } |
40 | 40 | ||
41 | static struct plat_serial8250_port uart8250_data[][2] = { | 41 | static struct plat_serial8250_port uart8250_data[][MAX_UARTS + 1] = { |
42 | [MACH_LOONGSON_UNKNOWN] {}, | 42 | [MACH_LOONGSON_UNKNOWN] = {}, |
43 | [MACH_LEMOTE_FL2E] {PORT(4, 1843200), {} }, | 43 | [MACH_LEMOTE_FL2E] = {PORT(4, 1843200), {} }, |
44 | [MACH_LEMOTE_FL2F] {PORT(3, 1843200), {} }, | 44 | [MACH_LEMOTE_FL2F] = {PORT(3, 1843200), {} }, |
45 | [MACH_LEMOTE_ML2F7] {PORT_M(3, 3686400), {} }, | 45 | [MACH_LEMOTE_ML2F7] = {PORT_M(3, 3686400), {} }, |
46 | [MACH_LEMOTE_YL2F89] {PORT_M(3, 3686400), {} }, | 46 | [MACH_LEMOTE_YL2F89] = {PORT_M(3, 3686400), {} }, |
47 | [MACH_DEXXON_GDIUM2F10] {PORT_M(3, 3686400), {} }, | 47 | [MACH_DEXXON_GDIUM2F10] = {PORT_M(3, 3686400), {} }, |
48 | [MACH_LEMOTE_NAS] {PORT_M(3, 3686400), {} }, | 48 | [MACH_LEMOTE_NAS] = {PORT_M(3, 3686400), {} }, |
49 | [MACH_LEMOTE_LL2F] {PORT(3, 1843200), {} }, | 49 | [MACH_LEMOTE_LL2F] = {PORT(3, 1843200), {} }, |
50 | [MACH_LEMOTE_A1004] {PORT_M(2, 33177600), {} }, | 50 | [MACH_LOONGSON_GENERIC] = {PORT_M(2, 25000000), {} }, |
51 | [MACH_LEMOTE_A1101] {PORT_M(2, 25000000), {} }, | 51 | [MACH_LOONGSON_END] = {}, |
52 | [MACH_LEMOTE_A1201] {PORT_M(2, 25000000), {} }, | ||
53 | [MACH_LEMOTE_A1205] {PORT_M(2, 25000000), {} }, | ||
54 | [MACH_LOONGSON_END] {}, | ||
55 | }; | 52 | }; |
56 | 53 | ||
57 | static struct platform_device uart8250_device = { | 54 | static struct platform_device uart8250_device = { |
@@ -61,17 +58,52 @@ static struct platform_device uart8250_device = { | |||
61 | 58 | ||
62 | static int __init serial_init(void) | 59 | static int __init serial_init(void) |
63 | { | 60 | { |
61 | int i; | ||
64 | unsigned char iotype; | 62 | unsigned char iotype; |
65 | 63 | ||
66 | iotype = uart8250_data[mips_machtype][0].iotype; | 64 | iotype = uart8250_data[mips_machtype][0].iotype; |
67 | 65 | ||
68 | if (UPIO_MEM == iotype) | 66 | if (UPIO_MEM == iotype) { |
67 | uart8250_data[mips_machtype][0].mapbase = | ||
68 | loongson_uart_base[0]; | ||
69 | uart8250_data[mips_machtype][0].membase = | 69 | uart8250_data[mips_machtype][0].membase = |
70 | (void __iomem *)_loongson_uart_base; | 70 | (void __iomem *)_loongson_uart_base[0]; |
71 | } | ||
71 | else if (UPIO_PORT == iotype) | 72 | else if (UPIO_PORT == iotype) |
72 | uart8250_data[mips_machtype][0].iobase = | 73 | uart8250_data[mips_machtype][0].iobase = |
73 | loongson_uart_base - LOONGSON_PCIIO_BASE; | 74 | loongson_uart_base[0] - LOONGSON_PCIIO_BASE; |
74 | 75 | ||
76 | if (loongson_sysconf.uarts[0].uartclk) | ||
77 | uart8250_data[mips_machtype][0].uartclk = | ||
78 | loongson_sysconf.uarts[0].uartclk; | ||
79 | |||
80 | for (i = 1; i < loongson_sysconf.nr_uarts; i++) { | ||
81 | iotype = loongson_sysconf.uarts[i].iotype; | ||
82 | uart8250_data[mips_machtype][i].iotype = iotype; | ||
83 | loongson_uart_base[i] = loongson_sysconf.uarts[i].uart_base; | ||
84 | |||
85 | if (UPIO_MEM == iotype) { | ||
86 | uart8250_data[mips_machtype][i].irq = | ||
87 | MIPS_CPU_IRQ_BASE + loongson_sysconf.uarts[i].int_offset; | ||
88 | uart8250_data[mips_machtype][i].mapbase = | ||
89 | loongson_uart_base[i]; | ||
90 | uart8250_data[mips_machtype][i].membase = | ||
91 | ioremap_nocache(loongson_uart_base[i], 8); | ||
92 | } else if (UPIO_PORT == iotype) { | ||
93 | uart8250_data[mips_machtype][i].irq = | ||
94 | loongson_sysconf.uarts[i].int_offset; | ||
95 | uart8250_data[mips_machtype][i].iobase = | ||
96 | loongson_uart_base[i] - LOONGSON_PCIIO_BASE; | ||
97 | } | ||
98 | |||
99 | uart8250_data[mips_machtype][i].uartclk = | ||
100 | loongson_sysconf.uarts[i].uartclk; | ||
101 | uart8250_data[mips_machtype][i].flags = | ||
102 | UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; | ||
103 | } | ||
104 | |||
105 | memset(&uart8250_data[mips_machtype][loongson_sysconf.nr_uarts], | ||
106 | 0, sizeof(struct plat_serial8250_port)); | ||
75 | uart8250_device.dev.platform_data = uart8250_data[mips_machtype]; | 107 | uart8250_device.dev.platform_data = uart8250_data[mips_machtype]; |
76 | 108 | ||
77 | return platform_device_register(&uart8250_device); | 109 | return platform_device_register(&uart8250_device); |
diff --git a/arch/mips/loongson/common/setup.c b/arch/mips/loongson/common/setup.c index bb4ac922e47a..d477dd6bb326 100644 --- a/arch/mips/loongson/common/setup.c +++ b/arch/mips/loongson/common/setup.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | 11 | ||
12 | #include <asm/wbflush.h> | 12 | #include <asm/wbflush.h> |
13 | #include <asm/bootinfo.h> | ||
13 | 14 | ||
14 | #include <loongson.h> | 15 | #include <loongson.h> |
15 | 16 | ||
diff --git a/arch/mips/loongson/common/time.c b/arch/mips/loongson/common/time.c index 262a1f65b05e..e1a5382ad47e 100644 --- a/arch/mips/loongson/common/time.c +++ b/arch/mips/loongson/common/time.c | |||
@@ -12,6 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | #include <asm/mc146818-time.h> | 13 | #include <asm/mc146818-time.h> |
14 | #include <asm/time.h> | 14 | #include <asm/time.h> |
15 | #include <asm/hpet.h> | ||
15 | 16 | ||
16 | #include <loongson.h> | 17 | #include <loongson.h> |
17 | #include <cs5536/cs5536_mfgpt.h> | 18 | #include <cs5536/cs5536_mfgpt.h> |
@@ -21,7 +22,11 @@ void __init plat_time_init(void) | |||
21 | /* setup mips r4k timer */ | 22 | /* setup mips r4k timer */ |
22 | mips_hpt_frequency = cpu_clock_freq / 2; | 23 | mips_hpt_frequency = cpu_clock_freq / 2; |
23 | 24 | ||
25 | #ifdef CONFIG_RS780_HPET | ||
26 | setup_hpet_timer(); | ||
27 | #else | ||
24 | setup_mfgpt0_timer(); | 28 | setup_mfgpt0_timer(); |
29 | #endif | ||
25 | } | 30 | } |
26 | 31 | ||
27 | void read_persistent_clock(struct timespec *ts) | 32 | void read_persistent_clock(struct timespec *ts) |
diff --git a/arch/mips/loongson/common/uart_base.c b/arch/mips/loongson/common/uart_base.c index 1e1eeea73fde..9de559d58e1f 100644 --- a/arch/mips/loongson/common/uart_base.c +++ b/arch/mips/loongson/common/uart_base.c | |||
@@ -13,22 +13,27 @@ | |||
13 | 13 | ||
14 | #include <loongson.h> | 14 | #include <loongson.h> |
15 | 15 | ||
16 | /* ioremapped */ | ||
17 | unsigned long _loongson_uart_base; | ||
18 | EXPORT_SYMBOL(_loongson_uart_base); | ||
19 | /* raw */ | 16 | /* raw */ |
20 | unsigned long loongson_uart_base; | 17 | unsigned long loongson_uart_base[MAX_UARTS] = {}; |
18 | /* ioremapped */ | ||
19 | unsigned long _loongson_uart_base[MAX_UARTS] = {}; | ||
20 | |||
21 | EXPORT_SYMBOL(loongson_uart_base); | 21 | EXPORT_SYMBOL(loongson_uart_base); |
22 | EXPORT_SYMBOL(_loongson_uart_base); | ||
22 | 23 | ||
23 | void prom_init_loongson_uart_base(void) | 24 | void prom_init_loongson_uart_base(void) |
24 | { | 25 | { |
25 | switch (mips_machtype) { | 26 | switch (mips_machtype) { |
27 | case MACH_LOONGSON_GENERIC: | ||
28 | /* The CPU provided serial port (CPU) */ | ||
29 | loongson_uart_base[0] = LOONGSON_REG_BASE + 0x1e0; | ||
30 | break; | ||
26 | case MACH_LEMOTE_FL2E: | 31 | case MACH_LEMOTE_FL2E: |
27 | loongson_uart_base = LOONGSON_PCIIO_BASE + 0x3f8; | 32 | loongson_uart_base[0] = LOONGSON_PCIIO_BASE + 0x3f8; |
28 | break; | 33 | break; |
29 | case MACH_LEMOTE_FL2F: | 34 | case MACH_LEMOTE_FL2F: |
30 | case MACH_LEMOTE_LL2F: | 35 | case MACH_LEMOTE_LL2F: |
31 | loongson_uart_base = LOONGSON_PCIIO_BASE + 0x2f8; | 36 | loongson_uart_base[0] = LOONGSON_PCIIO_BASE + 0x2f8; |
32 | break; | 37 | break; |
33 | case MACH_LEMOTE_ML2F7: | 38 | case MACH_LEMOTE_ML2F7: |
34 | case MACH_LEMOTE_YL2F89: | 39 | case MACH_LEMOTE_YL2F89: |
@@ -36,17 +41,10 @@ void prom_init_loongson_uart_base(void) | |||
36 | case MACH_LEMOTE_NAS: | 41 | case MACH_LEMOTE_NAS: |
37 | default: | 42 | default: |
38 | /* The CPU provided serial port (LPC) */ | 43 | /* The CPU provided serial port (LPC) */ |
39 | loongson_uart_base = LOONGSON_LIO1_BASE + 0x3f8; | 44 | loongson_uart_base[0] = LOONGSON_LIO1_BASE + 0x3f8; |
40 | break; | ||
41 | case MACH_LEMOTE_A1004: | ||
42 | case MACH_LEMOTE_A1101: | ||
43 | case MACH_LEMOTE_A1201: | ||
44 | case MACH_LEMOTE_A1205: | ||
45 | /* The CPU provided serial port (CPU) */ | ||
46 | loongson_uart_base = LOONGSON_REG_BASE + 0x1e0; | ||
47 | break; | 45 | break; |
48 | } | 46 | } |
49 | 47 | ||
50 | _loongson_uart_base = | 48 | _loongson_uart_base[0] = |
51 | (unsigned long)ioremap_nocache(loongson_uart_base, 8); | 49 | (unsigned long)ioremap_nocache(loongson_uart_base[0], 8); |
52 | } | 50 | } |
diff --git a/arch/mips/loongson/lemote-2f/irq.c b/arch/mips/loongson/lemote-2f/irq.c index 6f8682e44483..cab5f43e0e29 100644 --- a/arch/mips/loongson/lemote-2f/irq.c +++ b/arch/mips/loongson/lemote-2f/irq.c | |||
@@ -93,13 +93,13 @@ static irqreturn_t ip6_action(int cpl, void *dev_id) | |||
93 | return IRQ_HANDLED; | 93 | return IRQ_HANDLED; |
94 | } | 94 | } |
95 | 95 | ||
96 | struct irqaction ip6_irqaction = { | 96 | static struct irqaction ip6_irqaction = { |
97 | .handler = ip6_action, | 97 | .handler = ip6_action, |
98 | .name = "cascade", | 98 | .name = "cascade", |
99 | .flags = IRQF_SHARED | IRQF_NO_THREAD, | 99 | .flags = IRQF_SHARED | IRQF_NO_THREAD, |
100 | }; | 100 | }; |
101 | 101 | ||
102 | struct irqaction cascade_irqaction = { | 102 | static struct irqaction cascade_irqaction = { |
103 | .handler = no_action, | 103 | .handler = no_action, |
104 | .name = "cascade", | 104 | .name = "cascade", |
105 | .flags = IRQF_NO_THREAD, | 105 | .flags = IRQF_NO_THREAD, |
diff --git a/arch/mips/loongson/lemote-2f/reset.c b/arch/mips/loongson/lemote-2f/reset.c index 79ac694fe744..a26ca7fcd7e0 100644 --- a/arch/mips/loongson/lemote-2f/reset.c +++ b/arch/mips/loongson/lemote-2f/reset.c | |||
@@ -76,7 +76,7 @@ static void fl2f_shutdown(void) | |||
76 | 76 | ||
77 | /* reset support for yeeloong2f and mengloong2f notebook */ | 77 | /* reset support for yeeloong2f and mengloong2f notebook */ |
78 | 78 | ||
79 | void ml2f_reboot(void) | 79 | static void ml2f_reboot(void) |
80 | { | 80 | { |
81 | reset_cpu(); | 81 | reset_cpu(); |
82 | 82 | ||
diff --git a/arch/mips/loongson/loongson-3/Makefile b/arch/mips/loongson/loongson-3/Makefile index b4df775b9f30..622fead5ebc9 100644 --- a/arch/mips/loongson/loongson-3/Makefile +++ b/arch/mips/loongson/loongson-3/Makefile | |||
@@ -1,8 +1,10 @@ | |||
1 | # | 1 | # |
2 | # Makefile for Loongson-3 family machines | 2 | # Makefile for Loongson-3 family machines |
3 | # | 3 | # |
4 | obj-y += irq.o cop2-ex.o | 4 | obj-y += irq.o cop2-ex.o platform.o |
5 | 5 | ||
6 | obj-$(CONFIG_SMP) += smp.o | 6 | obj-$(CONFIG_SMP) += smp.o |
7 | 7 | ||
8 | obj-$(CONFIG_NUMA) += numa.o | 8 | obj-$(CONFIG_NUMA) += numa.o |
9 | |||
10 | obj-$(CONFIG_RS780_HPET) += hpet.o | ||
diff --git a/arch/mips/loongson/loongson-3/hpet.c b/arch/mips/loongson/loongson-3/hpet.c new file mode 100644 index 000000000000..e898d68668a9 --- /dev/null +++ b/arch/mips/loongson/loongson-3/hpet.c | |||
@@ -0,0 +1,257 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/pci.h> | ||
3 | #include <linux/percpu.h> | ||
4 | #include <linux/delay.h> | ||
5 | #include <linux/spinlock.h> | ||
6 | #include <linux/interrupt.h> | ||
7 | |||
8 | #include <asm/hpet.h> | ||
9 | #include <asm/time.h> | ||
10 | |||
11 | #define SMBUS_CFG_BASE (loongson_sysconf.ht_control_base + 0x0300a000) | ||
12 | #define SMBUS_PCI_REG40 0x40 | ||
13 | #define SMBUS_PCI_REG64 0x64 | ||
14 | #define SMBUS_PCI_REGB4 0xb4 | ||
15 | |||
16 | static DEFINE_SPINLOCK(hpet_lock); | ||
17 | DEFINE_PER_CPU(struct clock_event_device, hpet_clockevent_device); | ||
18 | |||
19 | static unsigned int smbus_read(int offset) | ||
20 | { | ||
21 | return *(volatile unsigned int *)(SMBUS_CFG_BASE + offset); | ||
22 | } | ||
23 | |||
24 | static void smbus_write(int offset, int data) | ||
25 | { | ||
26 | *(volatile unsigned int *)(SMBUS_CFG_BASE + offset) = data; | ||
27 | } | ||
28 | |||
29 | static void smbus_enable(int offset, int bit) | ||
30 | { | ||
31 | unsigned int cfg = smbus_read(offset); | ||
32 | |||
33 | cfg |= bit; | ||
34 | smbus_write(offset, cfg); | ||
35 | } | ||
36 | |||
37 | static int hpet_read(int offset) | ||
38 | { | ||
39 | return *(volatile unsigned int *)(HPET_MMIO_ADDR + offset); | ||
40 | } | ||
41 | |||
42 | static void hpet_write(int offset, int data) | ||
43 | { | ||
44 | *(volatile unsigned int *)(HPET_MMIO_ADDR + offset) = data; | ||
45 | } | ||
46 | |||
47 | static void hpet_start_counter(void) | ||
48 | { | ||
49 | unsigned int cfg = hpet_read(HPET_CFG); | ||
50 | |||
51 | cfg |= HPET_CFG_ENABLE; | ||
52 | hpet_write(HPET_CFG, cfg); | ||
53 | } | ||
54 | |||
55 | static void hpet_stop_counter(void) | ||
56 | { | ||
57 | unsigned int cfg = hpet_read(HPET_CFG); | ||
58 | |||
59 | cfg &= ~HPET_CFG_ENABLE; | ||
60 | hpet_write(HPET_CFG, cfg); | ||
61 | } | ||
62 | |||
63 | static void hpet_reset_counter(void) | ||
64 | { | ||
65 | hpet_write(HPET_COUNTER, 0); | ||
66 | hpet_write(HPET_COUNTER + 4, 0); | ||
67 | } | ||
68 | |||
69 | static void hpet_restart_counter(void) | ||
70 | { | ||
71 | hpet_stop_counter(); | ||
72 | hpet_reset_counter(); | ||
73 | hpet_start_counter(); | ||
74 | } | ||
75 | |||
76 | static void hpet_enable_legacy_int(void) | ||
77 | { | ||
78 | /* Do nothing on Loongson-3 */ | ||
79 | } | ||
80 | |||
81 | static void hpet_set_mode(enum clock_event_mode mode, | ||
82 | struct clock_event_device *evt) | ||
83 | { | ||
84 | int cfg = 0; | ||
85 | |||
86 | spin_lock(&hpet_lock); | ||
87 | switch (mode) { | ||
88 | case CLOCK_EVT_MODE_PERIODIC: | ||
89 | pr_info("set clock event to periodic mode!\n"); | ||
90 | /* stop counter */ | ||
91 | hpet_stop_counter(); | ||
92 | |||
93 | /* enables the timer0 to generate a periodic interrupt */ | ||
94 | cfg = hpet_read(HPET_T0_CFG); | ||
95 | cfg &= ~HPET_TN_LEVEL; | ||
96 | cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC | | ||
97 | HPET_TN_SETVAL | HPET_TN_32BIT; | ||
98 | hpet_write(HPET_T0_CFG, cfg); | ||
99 | |||
100 | /* set the comparator */ | ||
101 | hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL); | ||
102 | udelay(1); | ||
103 | hpet_write(HPET_T0_CMP, HPET_COMPARE_VAL); | ||
104 | |||
105 | /* start counter */ | ||
106 | hpet_start_counter(); | ||
107 | break; | ||
108 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
109 | case CLOCK_EVT_MODE_UNUSED: | ||
110 | cfg = hpet_read(HPET_T0_CFG); | ||
111 | cfg &= ~HPET_TN_ENABLE; | ||
112 | hpet_write(HPET_T0_CFG, cfg); | ||
113 | break; | ||
114 | case CLOCK_EVT_MODE_ONESHOT: | ||
115 | pr_info("set clock event to one shot mode!\n"); | ||
116 | cfg = hpet_read(HPET_T0_CFG); | ||
117 | /* set timer0 type | ||
118 | * 1 : periodic interrupt | ||
119 | * 0 : non-periodic(oneshot) interrupt | ||
120 | */ | ||
121 | cfg &= ~HPET_TN_PERIODIC; | ||
122 | cfg |= HPET_TN_ENABLE | HPET_TN_32BIT; | ||
123 | hpet_write(HPET_T0_CFG, cfg); | ||
124 | break; | ||
125 | case CLOCK_EVT_MODE_RESUME: | ||
126 | hpet_enable_legacy_int(); | ||
127 | break; | ||
128 | } | ||
129 | spin_unlock(&hpet_lock); | ||
130 | } | ||
131 | |||
132 | static int hpet_next_event(unsigned long delta, | ||
133 | struct clock_event_device *evt) | ||
134 | { | ||
135 | unsigned int cnt; | ||
136 | int res; | ||
137 | |||
138 | cnt = hpet_read(HPET_COUNTER); | ||
139 | cnt += delta; | ||
140 | hpet_write(HPET_T0_CMP, cnt); | ||
141 | |||
142 | res = ((int)(hpet_read(HPET_COUNTER) - cnt) > 0) ? -ETIME : 0; | ||
143 | return res; | ||
144 | } | ||
145 | |||
146 | static irqreturn_t hpet_irq_handler(int irq, void *data) | ||
147 | { | ||
148 | int is_irq; | ||
149 | struct clock_event_device *cd; | ||
150 | unsigned int cpu = smp_processor_id(); | ||
151 | |||
152 | is_irq = hpet_read(HPET_STATUS); | ||
153 | if (is_irq & HPET_T0_IRS) { | ||
154 | /* clear the TIMER0 irq status register */ | ||
155 | hpet_write(HPET_STATUS, HPET_T0_IRS); | ||
156 | cd = &per_cpu(hpet_clockevent_device, cpu); | ||
157 | cd->event_handler(cd); | ||
158 | return IRQ_HANDLED; | ||
159 | } | ||
160 | return IRQ_NONE; | ||
161 | } | ||
162 | |||
163 | static struct irqaction hpet_irq = { | ||
164 | .handler = hpet_irq_handler, | ||
165 | .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER, | ||
166 | .name = "hpet", | ||
167 | }; | ||
168 | |||
169 | /* | ||
170 | * hpet address assignation and irq setting should be done in bios. | ||
171 | * but pmon don't do this, we just setup here directly. | ||
172 | * The operation under is normal. unfortunately, hpet_setup process | ||
173 | * is before pci initialize. | ||
174 | * | ||
175 | * { | ||
176 | * struct pci_dev *pdev; | ||
177 | * | ||
178 | * pdev = pci_get_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL); | ||
179 | * pci_write_config_word(pdev, SMBUS_PCI_REGB4, HPET_ADDR); | ||
180 | * | ||
181 | * ... | ||
182 | * } | ||
183 | */ | ||
184 | static void hpet_setup(void) | ||
185 | { | ||
186 | /* set hpet base address */ | ||
187 | smbus_write(SMBUS_PCI_REGB4, HPET_ADDR); | ||
188 | |||
189 | /* enable decodeing of access to HPET MMIO*/ | ||
190 | smbus_enable(SMBUS_PCI_REG40, (1 << 28)); | ||
191 | |||
192 | /* HPET irq enable */ | ||
193 | smbus_enable(SMBUS_PCI_REG64, (1 << 10)); | ||
194 | |||
195 | hpet_enable_legacy_int(); | ||
196 | } | ||
197 | |||
198 | void __init setup_hpet_timer(void) | ||
199 | { | ||
200 | unsigned int cpu = smp_processor_id(); | ||
201 | struct clock_event_device *cd; | ||
202 | |||
203 | hpet_setup(); | ||
204 | |||
205 | cd = &per_cpu(hpet_clockevent_device, cpu); | ||
206 | cd->name = "hpet"; | ||
207 | cd->rating = 320; | ||
208 | cd->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; | ||
209 | cd->set_mode = hpet_set_mode; | ||
210 | cd->set_next_event = hpet_next_event; | ||
211 | cd->irq = HPET_T0_IRQ; | ||
212 | cd->cpumask = cpumask_of(cpu); | ||
213 | clockevent_set_clock(cd, HPET_FREQ); | ||
214 | cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); | ||
215 | cd->min_delta_ns = 5000; | ||
216 | |||
217 | clockevents_register_device(cd); | ||
218 | setup_irq(HPET_T0_IRQ, &hpet_irq); | ||
219 | pr_info("hpet clock event device register\n"); | ||
220 | } | ||
221 | |||
222 | static cycle_t hpet_read_counter(struct clocksource *cs) | ||
223 | { | ||
224 | return (cycle_t)hpet_read(HPET_COUNTER); | ||
225 | } | ||
226 | |||
227 | static void hpet_suspend(struct clocksource *cs) | ||
228 | { | ||
229 | } | ||
230 | |||
231 | static void hpet_resume(struct clocksource *cs) | ||
232 | { | ||
233 | hpet_setup(); | ||
234 | hpet_restart_counter(); | ||
235 | } | ||
236 | |||
237 | static struct clocksource csrc_hpet = { | ||
238 | .name = "hpet", | ||
239 | /* mips clocksource rating is less than 300, so hpet is better. */ | ||
240 | .rating = 300, | ||
241 | .read = hpet_read_counter, | ||
242 | .mask = CLOCKSOURCE_MASK(32), | ||
243 | /* oneshot mode work normal with this flag */ | ||
244 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
245 | .suspend = hpet_suspend, | ||
246 | .resume = hpet_resume, | ||
247 | .mult = 0, | ||
248 | .shift = 10, | ||
249 | }; | ||
250 | |||
251 | int __init init_hpet_clocksource(void) | ||
252 | { | ||
253 | csrc_hpet.mult = clocksource_hz2mult(HPET_FREQ, csrc_hpet.shift); | ||
254 | return clocksource_register_hz(&csrc_hpet, HPET_FREQ); | ||
255 | } | ||
256 | |||
257 | arch_initcall(init_hpet_clocksource); | ||
diff --git a/arch/mips/loongson/loongson-3/irq.c b/arch/mips/loongson/loongson-3/irq.c index ca1c62af5188..21221edda7a9 100644 --- a/arch/mips/loongson/loongson-3/irq.c +++ b/arch/mips/loongson/loongson-3/irq.c | |||
@@ -9,7 +9,7 @@ | |||
9 | 9 | ||
10 | #include "smp.h" | 10 | #include "smp.h" |
11 | 11 | ||
12 | unsigned int ht_irq[] = {1, 3, 4, 5, 6, 7, 8, 12, 14, 15}; | 12 | unsigned int ht_irq[] = {0, 1, 3, 4, 5, 6, 7, 8, 12, 14, 15}; |
13 | 13 | ||
14 | static void ht_irqdispatch(void) | 14 | static void ht_irqdispatch(void) |
15 | { | 15 | { |
@@ -55,8 +55,8 @@ static inline void mask_loongson_irq(struct irq_data *d) | |||
55 | /* Workaround: UART IRQ may deliver to any core */ | 55 | /* Workaround: UART IRQ may deliver to any core */ |
56 | if (d->irq == LOONGSON_UART_IRQ) { | 56 | if (d->irq == LOONGSON_UART_IRQ) { |
57 | int cpu = smp_processor_id(); | 57 | int cpu = smp_processor_id(); |
58 | int node_id = cpu / loongson_sysconf.cores_per_node; | 58 | int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node; |
59 | int core_id = cpu % loongson_sysconf.cores_per_node; | 59 | int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node; |
60 | u64 intenclr_addr = smp_group[node_id] | | 60 | u64 intenclr_addr = smp_group[node_id] | |
61 | (u64)(&LOONGSON_INT_ROUTER_INTENCLR); | 61 | (u64)(&LOONGSON_INT_ROUTER_INTENCLR); |
62 | u64 introuter_lpc_addr = smp_group[node_id] | | 62 | u64 introuter_lpc_addr = smp_group[node_id] | |
@@ -72,8 +72,8 @@ static inline void unmask_loongson_irq(struct irq_data *d) | |||
72 | /* Workaround: UART IRQ may deliver to any core */ | 72 | /* Workaround: UART IRQ may deliver to any core */ |
73 | if (d->irq == LOONGSON_UART_IRQ) { | 73 | if (d->irq == LOONGSON_UART_IRQ) { |
74 | int cpu = smp_processor_id(); | 74 | int cpu = smp_processor_id(); |
75 | int node_id = cpu / loongson_sysconf.cores_per_node; | 75 | int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node; |
76 | int core_id = cpu % loongson_sysconf.cores_per_node; | 76 | int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node; |
77 | u64 intenset_addr = smp_group[node_id] | | 77 | u64 intenset_addr = smp_group[node_id] | |
78 | (u64)(&LOONGSON_INT_ROUTER_INTENSET); | 78 | (u64)(&LOONGSON_INT_ROUTER_INTENSET); |
79 | u64 introuter_lpc_addr = smp_group[node_id] | | 79 | u64 introuter_lpc_addr = smp_group[node_id] | |
@@ -102,10 +102,12 @@ void irq_router_init(void) | |||
102 | int i; | 102 | int i; |
103 | 103 | ||
104 | /* route LPC int to cpu core0 int 0 */ | 104 | /* route LPC int to cpu core0 int 0 */ |
105 | LOONGSON_INT_ROUTER_LPC = LOONGSON_INT_CORE0_INT0; | 105 | LOONGSON_INT_ROUTER_LPC = |
106 | LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 0); | ||
106 | /* route HT1 int0 ~ int7 to cpu core0 INT1*/ | 107 | /* route HT1 int0 ~ int7 to cpu core0 INT1*/ |
107 | for (i = 0; i < 8; i++) | 108 | for (i = 0; i < 8; i++) |
108 | LOONGSON_INT_ROUTER_HT1(i) = LOONGSON_INT_CORE0_INT1; | 109 | LOONGSON_INT_ROUTER_HT1(i) = |
110 | LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 1); | ||
109 | /* enable HT1 interrupt */ | 111 | /* enable HT1 interrupt */ |
110 | LOONGSON_HT1_INTN_EN(0) = 0xffffffff; | 112 | LOONGSON_HT1_INTN_EN(0) = 0xffffffff; |
111 | /* enable router interrupt intenset */ | 113 | /* enable router interrupt intenset */ |
diff --git a/arch/mips/loongson/loongson-3/numa.c b/arch/mips/loongson/loongson-3/numa.c index 42323bcc5d28..6cae0e75de27 100644 --- a/arch/mips/loongson/loongson-3/numa.c +++ b/arch/mips/loongson/loongson-3/numa.c | |||
@@ -224,7 +224,7 @@ static void __init node_mem_init(unsigned int node) | |||
224 | 224 | ||
225 | static __init void prom_meminit(void) | 225 | static __init void prom_meminit(void) |
226 | { | 226 | { |
227 | unsigned int node, cpu; | 227 | unsigned int node, cpu, active_cpu = 0; |
228 | 228 | ||
229 | cpu_node_probe(); | 229 | cpu_node_probe(); |
230 | init_topology_matrix(); | 230 | init_topology_matrix(); |
@@ -240,8 +240,14 @@ static __init void prom_meminit(void) | |||
240 | node = cpu / loongson_sysconf.cores_per_node; | 240 | node = cpu / loongson_sysconf.cores_per_node; |
241 | if (node >= num_online_nodes()) | 241 | if (node >= num_online_nodes()) |
242 | node = 0; | 242 | node = 0; |
243 | pr_info("NUMA: set cpumask cpu %d on node %d\n", cpu, node); | 243 | |
244 | cpu_set(cpu, __node_data[(node)]->cpumask); | 244 | if (loongson_sysconf.reserved_cpus_mask & (1<<cpu)) |
245 | continue; | ||
246 | |||
247 | cpu_set(active_cpu, __node_data[(node)]->cpumask); | ||
248 | pr_info("NUMA: set cpumask cpu %d on node %d\n", active_cpu, node); | ||
249 | |||
250 | active_cpu++; | ||
245 | } | 251 | } |
246 | } | 252 | } |
247 | 253 | ||
diff --git a/arch/mips/loongson/loongson-3/platform.c b/arch/mips/loongson/loongson-3/platform.c new file mode 100644 index 000000000000..25a97cc0ee33 --- /dev/null +++ b/arch/mips/loongson/loongson-3/platform.c | |||
@@ -0,0 +1,43 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 Lemote Inc. | ||
3 | * Author: Wu Zhangjin, wuzhangjin@gmail.com | ||
4 | * Xiang Yu, xiangy@lemote.com | ||
5 | * Chen Huacai, chenhc@lemote.com | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/err.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <asm/bootinfo.h> | ||
17 | #include <boot_param.h> | ||
18 | #include <loongson_hwmon.h> | ||
19 | #include <workarounds.h> | ||
20 | |||
21 | static int __init loongson3_platform_init(void) | ||
22 | { | ||
23 | int i; | ||
24 | struct platform_device *pdev; | ||
25 | |||
26 | if (loongson_sysconf.ecname[0] != '\0') | ||
27 | platform_device_register_simple(loongson_sysconf.ecname, -1, NULL, 0); | ||
28 | |||
29 | for (i = 0; i < loongson_sysconf.nr_sensors; i++) { | ||
30 | if (loongson_sysconf.sensors[i].type > SENSOR_FAN) | ||
31 | continue; | ||
32 | |||
33 | pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL); | ||
34 | pdev->name = loongson_sysconf.sensors[i].name; | ||
35 | pdev->id = loongson_sysconf.sensors[i].id; | ||
36 | pdev->dev.platform_data = &loongson_sysconf.sensors[i]; | ||
37 | platform_device_register(pdev); | ||
38 | } | ||
39 | |||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | arch_initcall(loongson3_platform_init); | ||
diff --git a/arch/mips/loongson/loongson-3/smp.c b/arch/mips/loongson/loongson-3/smp.c index d8c63af6c7cc..e2eb688b5434 100644 --- a/arch/mips/loongson/loongson-3/smp.c +++ b/arch/mips/loongson/loongson-3/smp.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <asm/tlbflush.h> | 25 | #include <asm/tlbflush.h> |
26 | #include <asm/cacheflush.h> | 26 | #include <asm/cacheflush.h> |
27 | #include <loongson.h> | 27 | #include <loongson.h> |
28 | #include <workarounds.h> | ||
28 | 29 | ||
29 | #include "smp.h" | 30 | #include "smp.h" |
30 | 31 | ||
@@ -239,7 +240,7 @@ static void ipi_mailbox_buf_init(void) | |||
239 | */ | 240 | */ |
240 | static void loongson3_send_ipi_single(int cpu, unsigned int action) | 241 | static void loongson3_send_ipi_single(int cpu, unsigned int action) |
241 | { | 242 | { |
242 | loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu]); | 243 | loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(cpu)]); |
243 | } | 244 | } |
244 | 245 | ||
245 | static void | 246 | static void |
@@ -248,7 +249,7 @@ loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action) | |||
248 | unsigned int i; | 249 | unsigned int i; |
249 | 250 | ||
250 | for_each_cpu(i, mask) | 251 | for_each_cpu(i, mask) |
251 | loongson3_ipi_write32((u32)action, ipi_set0_regs[i]); | 252 | loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(i)]); |
252 | } | 253 | } |
253 | 254 | ||
254 | void loongson3_ipi_interrupt(struct pt_regs *regs) | 255 | void loongson3_ipi_interrupt(struct pt_regs *regs) |
@@ -257,10 +258,10 @@ void loongson3_ipi_interrupt(struct pt_regs *regs) | |||
257 | unsigned int action, c0count; | 258 | unsigned int action, c0count; |
258 | 259 | ||
259 | /* Load the ipi register to figure out what we're supposed to do */ | 260 | /* Load the ipi register to figure out what we're supposed to do */ |
260 | action = loongson3_ipi_read32(ipi_status0_regs[cpu]); | 261 | action = loongson3_ipi_read32(ipi_status0_regs[cpu_logical_map(cpu)]); |
261 | 262 | ||
262 | /* Clear the ipi register to clear the interrupt */ | 263 | /* Clear the ipi register to clear the interrupt */ |
263 | loongson3_ipi_write32((u32)action, ipi_clear0_regs[cpu]); | 264 | loongson3_ipi_write32((u32)action, ipi_clear0_regs[cpu_logical_map(cpu)]); |
264 | 265 | ||
265 | if (action & SMP_RESCHEDULE_YOURSELF) | 266 | if (action & SMP_RESCHEDULE_YOURSELF) |
266 | scheduler_ipi(); | 267 | scheduler_ipi(); |
@@ -291,12 +292,14 @@ static void loongson3_init_secondary(void) | |||
291 | /* Set interrupt mask, but don't enable */ | 292 | /* Set interrupt mask, but don't enable */ |
292 | change_c0_status(ST0_IM, imask); | 293 | change_c0_status(ST0_IM, imask); |
293 | 294 | ||
294 | for (i = 0; i < loongson_sysconf.nr_cpus; i++) | 295 | for (i = 0; i < num_possible_cpus(); i++) |
295 | loongson3_ipi_write32(0xffffffff, ipi_en0_regs[i]); | 296 | loongson3_ipi_write32(0xffffffff, ipi_en0_regs[cpu_logical_map(i)]); |
296 | 297 | ||
297 | cpu_data[cpu].package = cpu / loongson_sysconf.cores_per_package; | ||
298 | cpu_data[cpu].core = cpu % loongson_sysconf.cores_per_package; | ||
299 | per_cpu(cpu_state, cpu) = CPU_ONLINE; | 298 | per_cpu(cpu_state, cpu) = CPU_ONLINE; |
299 | cpu_data[cpu].core = | ||
300 | cpu_logical_map(cpu) % loongson_sysconf.cores_per_package; | ||
301 | cpu_data[cpu].package = | ||
302 | cpu_logical_map(cpu) / loongson_sysconf.cores_per_package; | ||
300 | 303 | ||
301 | i = 0; | 304 | i = 0; |
302 | __this_cpu_write(core0_c0count, 0); | 305 | __this_cpu_write(core0_c0count, 0); |
@@ -314,37 +317,50 @@ static void loongson3_init_secondary(void) | |||
314 | 317 | ||
315 | static void loongson3_smp_finish(void) | 318 | static void loongson3_smp_finish(void) |
316 | { | 319 | { |
320 | int cpu = smp_processor_id(); | ||
321 | |||
317 | write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ); | 322 | write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ); |
318 | local_irq_enable(); | 323 | local_irq_enable(); |
319 | loongson3_ipi_write64(0, | 324 | loongson3_ipi_write64(0, |
320 | (void *)(ipi_mailbox_buf[smp_processor_id()]+0x0)); | 325 | (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0)); |
321 | pr_info("CPU#%d finished, CP0_ST=%x\n", | 326 | pr_info("CPU#%d finished, CP0_ST=%x\n", |
322 | smp_processor_id(), read_c0_status()); | 327 | smp_processor_id(), read_c0_status()); |
323 | } | 328 | } |
324 | 329 | ||
325 | static void __init loongson3_smp_setup(void) | 330 | static void __init loongson3_smp_setup(void) |
326 | { | 331 | { |
327 | int i, num; | 332 | int i = 0, num = 0; /* i: physical id, num: logical id */ |
328 | 333 | ||
329 | init_cpu_possible(cpu_none_mask); | 334 | init_cpu_possible(cpu_none_mask); |
330 | set_cpu_possible(0, true); | ||
331 | |||
332 | __cpu_number_map[0] = 0; | ||
333 | __cpu_logical_map[0] = 0; | ||
334 | 335 | ||
335 | /* For unified kernel, NR_CPUS is the maximum possible value, | 336 | /* For unified kernel, NR_CPUS is the maximum possible value, |
336 | * loongson_sysconf.nr_cpus is the really present value */ | 337 | * loongson_sysconf.nr_cpus is the really present value */ |
337 | for (i = 1, num = 0; i < loongson_sysconf.nr_cpus; i++) { | 338 | while (i < loongson_sysconf.nr_cpus) { |
338 | set_cpu_possible(i, true); | 339 | if (loongson_sysconf.reserved_cpus_mask & (1<<i)) { |
339 | __cpu_number_map[i] = ++num; | 340 | /* Reserved physical CPU cores */ |
340 | __cpu_logical_map[num] = i; | 341 | __cpu_number_map[i] = -1; |
342 | } else { | ||
343 | __cpu_number_map[i] = num; | ||
344 | __cpu_logical_map[num] = i; | ||
345 | set_cpu_possible(num, true); | ||
346 | num++; | ||
347 | } | ||
348 | i++; | ||
341 | } | 349 | } |
350 | pr_info("Detected %i available CPU(s)\n", num); | ||
351 | |||
352 | while (num < loongson_sysconf.nr_cpus) { | ||
353 | __cpu_logical_map[num] = -1; | ||
354 | num++; | ||
355 | } | ||
356 | |||
342 | ipi_set0_regs_init(); | 357 | ipi_set0_regs_init(); |
343 | ipi_clear0_regs_init(); | 358 | ipi_clear0_regs_init(); |
344 | ipi_status0_regs_init(); | 359 | ipi_status0_regs_init(); |
345 | ipi_en0_regs_init(); | 360 | ipi_en0_regs_init(); |
346 | ipi_mailbox_buf_init(); | 361 | ipi_mailbox_buf_init(); |
347 | pr_info("Detected %i available secondary CPU(s)\n", num); | 362 | cpu_data[0].core = cpu_logical_map(0) % loongson_sysconf.cores_per_package; |
363 | cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package; | ||
348 | } | 364 | } |
349 | 365 | ||
350 | static void __init loongson3_prepare_cpus(unsigned int max_cpus) | 366 | static void __init loongson3_prepare_cpus(unsigned int max_cpus) |
@@ -371,10 +387,14 @@ static void loongson3_boot_secondary(int cpu, struct task_struct *idle) | |||
371 | pr_debug("CPU#%d, func_pc=%lx, sp=%lx, gp=%lx\n", | 387 | pr_debug("CPU#%d, func_pc=%lx, sp=%lx, gp=%lx\n", |
372 | cpu, startargs[0], startargs[1], startargs[2]); | 388 | cpu, startargs[0], startargs[1], startargs[2]); |
373 | 389 | ||
374 | loongson3_ipi_write64(startargs[3], (void *)(ipi_mailbox_buf[cpu]+0x18)); | 390 | loongson3_ipi_write64(startargs[3], |
375 | loongson3_ipi_write64(startargs[2], (void *)(ipi_mailbox_buf[cpu]+0x10)); | 391 | (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x18)); |
376 | loongson3_ipi_write64(startargs[1], (void *)(ipi_mailbox_buf[cpu]+0x8)); | 392 | loongson3_ipi_write64(startargs[2], |
377 | loongson3_ipi_write64(startargs[0], (void *)(ipi_mailbox_buf[cpu]+0x0)); | 393 | (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x10)); |
394 | loongson3_ipi_write64(startargs[1], | ||
395 | (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x8)); | ||
396 | loongson3_ipi_write64(startargs[0], | ||
397 | (void *)(ipi_mailbox_buf[cpu_logical_map(cpu)]+0x0)); | ||
378 | } | 398 | } |
379 | 399 | ||
380 | #ifdef CONFIG_HOTPLUG_CPU | 400 | #ifdef CONFIG_HOTPLUG_CPU |
@@ -568,7 +588,7 @@ void loongson3_disable_clock(int cpu) | |||
568 | if (loongson_sysconf.cputype == Loongson_3A) { | 588 | if (loongson_sysconf.cputype == Loongson_3A) { |
569 | LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id)); | 589 | LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id)); |
570 | } else if (loongson_sysconf.cputype == Loongson_3B) { | 590 | } else if (loongson_sysconf.cputype == Loongson_3B) { |
571 | if (!cpuhotplug_workaround) | 591 | if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG)) |
572 | LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3)); | 592 | LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3)); |
573 | } | 593 | } |
574 | } | 594 | } |
@@ -581,7 +601,7 @@ void loongson3_enable_clock(int cpu) | |||
581 | if (loongson_sysconf.cputype == Loongson_3A) { | 601 | if (loongson_sysconf.cputype == Loongson_3A) { |
582 | LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id); | 602 | LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id); |
583 | } else if (loongson_sysconf.cputype == Loongson_3B) { | 603 | } else if (loongson_sysconf.cputype == Loongson_3B) { |
584 | if (!cpuhotplug_workaround) | 604 | if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG)) |
585 | LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3); | 605 | LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3); |
586 | } | 606 | } |
587 | } | 607 | } |
diff --git a/arch/mips/loongson1/Kconfig b/arch/mips/loongson1/Kconfig index e23c25d09963..a2b796eaf3c3 100644 --- a/arch/mips/loongson1/Kconfig +++ b/arch/mips/loongson1/Kconfig | |||
@@ -5,8 +5,8 @@ choice | |||
5 | 5 | ||
6 | config LOONGSON1_LS1B | 6 | config LOONGSON1_LS1B |
7 | bool "Loongson LS1B board" | 7 | bool "Loongson LS1B board" |
8 | select CEVT_R4K | 8 | select CEVT_R4K if !MIPS_EXTERNAL_TIMER |
9 | select CSRC_R4K | 9 | select CSRC_R4K if !MIPS_EXTERNAL_TIMER |
10 | select SYS_HAS_CPU_LOONGSON1B | 10 | select SYS_HAS_CPU_LOONGSON1B |
11 | select DMA_NONCOHERENT | 11 | select DMA_NONCOHERENT |
12 | select BOOT_ELF32 | 12 | select BOOT_ELF32 |
@@ -16,8 +16,46 @@ config LOONGSON1_LS1B | |||
16 | select SYS_SUPPORTS_HIGHMEM | 16 | select SYS_SUPPORTS_HIGHMEM |
17 | select SYS_SUPPORTS_MIPS16 | 17 | select SYS_SUPPORTS_MIPS16 |
18 | select SYS_HAS_EARLY_PRINTK | 18 | select SYS_HAS_EARLY_PRINTK |
19 | select USE_GENERIC_EARLY_PRINTK_8250 | ||
19 | select COMMON_CLK | 20 | select COMMON_CLK |
20 | 21 | ||
21 | endchoice | 22 | endchoice |
22 | 23 | ||
24 | menuconfig CEVT_CSRC_LS1X | ||
25 | bool "Use PWM Timer for clockevent/clocksource" | ||
26 | select MIPS_EXTERNAL_TIMER | ||
27 | depends on CPU_LOONGSON1 | ||
28 | help | ||
29 | This option changes the default clockevent/clocksource to PWM Timer, | ||
30 | and is required by Loongson1 CPUFreq support. | ||
31 | |||
32 | If unsure, say N. | ||
33 | |||
34 | choice | ||
35 | prompt "Select clockevent/clocksource" | ||
36 | depends on CEVT_CSRC_LS1X | ||
37 | default TIMER_USE_PWM0 | ||
38 | |||
39 | config TIMER_USE_PWM0 | ||
40 | bool "Use PWM Timer 0" | ||
41 | help | ||
42 | Use PWM Timer 0 as the default clockevent/clocksourcer. | ||
43 | |||
44 | config TIMER_USE_PWM1 | ||
45 | bool "Use PWM Timer 1" | ||
46 | help | ||
47 | Use PWM Timer 1 as the default clockevent/clocksourcer. | ||
48 | |||
49 | config TIMER_USE_PWM2 | ||
50 | bool "Use PWM Timer 2" | ||
51 | help | ||
52 | Use PWM Timer 2 as the default clockevent/clocksourcer. | ||
53 | |||
54 | config TIMER_USE_PWM3 | ||
55 | bool "Use PWM Timer 3" | ||
56 | help | ||
57 | Use PWM Timer 3 as the default clockevent/clocksourcer. | ||
58 | |||
59 | endchoice | ||
60 | |||
23 | endif # MACH_LOONGSON1 | 61 | endif # MACH_LOONGSON1 |
diff --git a/arch/mips/loongson1/common/Makefile b/arch/mips/loongson1/common/Makefile index b2797709ef5b..723b4ce3b8f0 100644 --- a/arch/mips/loongson1/common/Makefile +++ b/arch/mips/loongson1/common/Makefile | |||
@@ -2,4 +2,4 @@ | |||
2 | # Makefile for common code of loongson1 based machines. | 2 | # Makefile for common code of loongson1 based machines. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += clock.o irq.o platform.o prom.o reset.o setup.o | 5 | obj-y += time.o irq.o platform.o prom.o reset.o setup.o |
diff --git a/arch/mips/loongson1/common/clock.c b/arch/mips/loongson1/common/clock.c deleted file mode 100644 index b4437f19c3d9..000000000000 --- a/arch/mips/loongson1/common/clock.c +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License as published by the | ||
6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
7 | * option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include <linux/clk.h> | ||
11 | #include <linux/err.h> | ||
12 | #include <asm/time.h> | ||
13 | #include <platform.h> | ||
14 | |||
15 | void __init plat_time_init(void) | ||
16 | { | ||
17 | struct clk *clk; | ||
18 | |||
19 | /* Initialize LS1X clocks */ | ||
20 | ls1x_clk_init(); | ||
21 | |||
22 | /* setup mips r4k timer */ | ||
23 | clk = clk_get(NULL, "cpu"); | ||
24 | if (IS_ERR(clk)) | ||
25 | panic("unable to get cpu clock, err=%ld", PTR_ERR(clk)); | ||
26 | |||
27 | mips_hpt_frequency = clk_get_rate(clk) / 2; | ||
28 | } | ||
diff --git a/arch/mips/loongson1/common/platform.c b/arch/mips/loongson1/common/platform.c index fdf8cb5987a4..ddf1d4cbf31e 100644 --- a/arch/mips/loongson1/common/platform.c +++ b/arch/mips/loongson1/common/platform.c | |||
@@ -16,8 +16,10 @@ | |||
16 | #include <linux/usb/ehci_pdriver.h> | 16 | #include <linux/usb/ehci_pdriver.h> |
17 | #include <asm-generic/sizes.h> | 17 | #include <asm-generic/sizes.h> |
18 | 18 | ||
19 | #include <cpufreq.h> | ||
19 | #include <loongson1.h> | 20 | #include <loongson1.h> |
20 | 21 | ||
22 | /* 8250/16550 compatible UART */ | ||
21 | #define LS1X_UART(_id) \ | 23 | #define LS1X_UART(_id) \ |
22 | { \ | 24 | { \ |
23 | .mapbase = LS1X_UART ## _id ## _BASE, \ | 25 | .mapbase = LS1X_UART ## _id ## _BASE, \ |
@@ -27,7 +29,7 @@ | |||
27 | .type = PORT_16550A, \ | 29 | .type = PORT_16550A, \ |
28 | } | 30 | } |
29 | 31 | ||
30 | static struct plat_serial8250_port ls1x_serial8250_port[] = { | 32 | static struct plat_serial8250_port ls1x_serial8250_pdata[] = { |
31 | LS1X_UART(0), | 33 | LS1X_UART(0), |
32 | LS1X_UART(1), | 34 | LS1X_UART(1), |
33 | LS1X_UART(2), | 35 | LS1X_UART(2), |
@@ -35,11 +37,11 @@ static struct plat_serial8250_port ls1x_serial8250_port[] = { | |||
35 | {}, | 37 | {}, |
36 | }; | 38 | }; |
37 | 39 | ||
38 | struct platform_device ls1x_uart_device = { | 40 | struct platform_device ls1x_uart_pdev = { |
39 | .name = "serial8250", | 41 | .name = "serial8250", |
40 | .id = PLAT8250_DEV_PLATFORM, | 42 | .id = PLAT8250_DEV_PLATFORM, |
41 | .dev = { | 43 | .dev = { |
42 | .platform_data = ls1x_serial8250_port, | 44 | .platform_data = ls1x_serial8250_pdata, |
43 | }, | 45 | }, |
44 | }; | 46 | }; |
45 | 47 | ||
@@ -48,16 +50,97 @@ void __init ls1x_serial_setup(struct platform_device *pdev) | |||
48 | struct clk *clk; | 50 | struct clk *clk; |
49 | struct plat_serial8250_port *p; | 51 | struct plat_serial8250_port *p; |
50 | 52 | ||
51 | clk = clk_get(NULL, pdev->name); | 53 | clk = clk_get(&pdev->dev, pdev->name); |
52 | if (IS_ERR(clk)) | 54 | if (IS_ERR(clk)) { |
53 | panic("unable to get %s clock, err=%ld", | 55 | pr_err("unable to get %s clock, err=%ld", |
54 | pdev->name, PTR_ERR(clk)); | 56 | pdev->name, PTR_ERR(clk)); |
57 | return; | ||
58 | } | ||
59 | clk_prepare_enable(clk); | ||
55 | 60 | ||
56 | for (p = pdev->dev.platform_data; p->flags != 0; ++p) | 61 | for (p = pdev->dev.platform_data; p->flags != 0; ++p) |
57 | p->uartclk = clk_get_rate(clk); | 62 | p->uartclk = clk_get_rate(clk); |
58 | } | 63 | } |
59 | 64 | ||
65 | /* CPUFreq */ | ||
66 | static struct plat_ls1x_cpufreq ls1x_cpufreq_pdata = { | ||
67 | .clk_name = "cpu_clk", | ||
68 | .osc_clk_name = "osc_33m_clk", | ||
69 | .max_freq = 266 * 1000, | ||
70 | .min_freq = 33 * 1000, | ||
71 | }; | ||
72 | |||
73 | struct platform_device ls1x_cpufreq_pdev = { | ||
74 | .name = "ls1x-cpufreq", | ||
75 | .dev = { | ||
76 | .platform_data = &ls1x_cpufreq_pdata, | ||
77 | }, | ||
78 | }; | ||
79 | |||
60 | /* Synopsys Ethernet GMAC */ | 80 | /* Synopsys Ethernet GMAC */ |
81 | static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = { | ||
82 | .phy_mask = 0, | ||
83 | }; | ||
84 | |||
85 | static struct stmmac_dma_cfg ls1x_eth_dma_cfg = { | ||
86 | .pbl = 1, | ||
87 | }; | ||
88 | |||
89 | int ls1x_eth_mux_init(struct platform_device *pdev, void *priv) | ||
90 | { | ||
91 | struct plat_stmmacenet_data *plat_dat = NULL; | ||
92 | u32 val; | ||
93 | |||
94 | val = __raw_readl(LS1X_MUX_CTRL1); | ||
95 | |||
96 | plat_dat = dev_get_platdata(&pdev->dev); | ||
97 | if (plat_dat->bus_id) { | ||
98 | __raw_writel(__raw_readl(LS1X_MUX_CTRL0) | GMAC1_USE_UART1 | | ||
99 | GMAC1_USE_UART0, LS1X_MUX_CTRL0); | ||
100 | switch (plat_dat->interface) { | ||
101 | case PHY_INTERFACE_MODE_RGMII: | ||
102 | val &= ~(GMAC1_USE_TXCLK | GMAC1_USE_PWM23); | ||
103 | break; | ||
104 | case PHY_INTERFACE_MODE_MII: | ||
105 | val |= (GMAC1_USE_TXCLK | GMAC1_USE_PWM23); | ||
106 | break; | ||
107 | default: | ||
108 | pr_err("unsupported mii mode %d\n", | ||
109 | plat_dat->interface); | ||
110 | return -ENOTSUPP; | ||
111 | } | ||
112 | val &= ~GMAC1_SHUT; | ||
113 | } else { | ||
114 | switch (plat_dat->interface) { | ||
115 | case PHY_INTERFACE_MODE_RGMII: | ||
116 | val &= ~(GMAC0_USE_TXCLK | GMAC0_USE_PWM01); | ||
117 | break; | ||
118 | case PHY_INTERFACE_MODE_MII: | ||
119 | val |= (GMAC0_USE_TXCLK | GMAC0_USE_PWM01); | ||
120 | break; | ||
121 | default: | ||
122 | pr_err("unsupported mii mode %d\n", | ||
123 | plat_dat->interface); | ||
124 | return -ENOTSUPP; | ||
125 | } | ||
126 | val &= ~GMAC0_SHUT; | ||
127 | } | ||
128 | __raw_writel(val, LS1X_MUX_CTRL1); | ||
129 | |||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | static struct plat_stmmacenet_data ls1x_eth0_pdata = { | ||
134 | .bus_id = 0, | ||
135 | .phy_addr = -1, | ||
136 | .interface = PHY_INTERFACE_MODE_MII, | ||
137 | .mdio_bus_data = &ls1x_mdio_bus_data, | ||
138 | .dma_cfg = &ls1x_eth_dma_cfg, | ||
139 | .has_gmac = 1, | ||
140 | .tx_coe = 1, | ||
141 | .init = ls1x_eth_mux_init, | ||
142 | }; | ||
143 | |||
61 | static struct resource ls1x_eth0_resources[] = { | 144 | static struct resource ls1x_eth0_resources[] = { |
62 | [0] = { | 145 | [0] = { |
63 | .start = LS1X_GMAC0_BASE, | 146 | .start = LS1X_GMAC0_BASE, |
@@ -71,25 +154,47 @@ static struct resource ls1x_eth0_resources[] = { | |||
71 | }, | 154 | }, |
72 | }; | 155 | }; |
73 | 156 | ||
74 | static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = { | 157 | struct platform_device ls1x_eth0_pdev = { |
75 | .phy_mask = 0, | 158 | .name = "stmmaceth", |
159 | .id = 0, | ||
160 | .num_resources = ARRAY_SIZE(ls1x_eth0_resources), | ||
161 | .resource = ls1x_eth0_resources, | ||
162 | .dev = { | ||
163 | .platform_data = &ls1x_eth0_pdata, | ||
164 | }, | ||
76 | }; | 165 | }; |
77 | 166 | ||
78 | static struct plat_stmmacenet_data ls1x_eth_data = { | 167 | static struct plat_stmmacenet_data ls1x_eth1_pdata = { |
79 | .bus_id = 0, | 168 | .bus_id = 1, |
80 | .phy_addr = -1, | 169 | .phy_addr = -1, |
170 | .interface = PHY_INTERFACE_MODE_MII, | ||
81 | .mdio_bus_data = &ls1x_mdio_bus_data, | 171 | .mdio_bus_data = &ls1x_mdio_bus_data, |
172 | .dma_cfg = &ls1x_eth_dma_cfg, | ||
82 | .has_gmac = 1, | 173 | .has_gmac = 1, |
83 | .tx_coe = 1, | 174 | .tx_coe = 1, |
175 | .init = ls1x_eth_mux_init, | ||
84 | }; | 176 | }; |
85 | 177 | ||
86 | struct platform_device ls1x_eth0_device = { | 178 | static struct resource ls1x_eth1_resources[] = { |
179 | [0] = { | ||
180 | .start = LS1X_GMAC1_BASE, | ||
181 | .end = LS1X_GMAC1_BASE + SZ_64K - 1, | ||
182 | .flags = IORESOURCE_MEM, | ||
183 | }, | ||
184 | [1] = { | ||
185 | .name = "macirq", | ||
186 | .start = LS1X_GMAC1_IRQ, | ||
187 | .flags = IORESOURCE_IRQ, | ||
188 | }, | ||
189 | }; | ||
190 | |||
191 | struct platform_device ls1x_eth1_pdev = { | ||
87 | .name = "stmmaceth", | 192 | .name = "stmmaceth", |
88 | .id = 0, | 193 | .id = 1, |
89 | .num_resources = ARRAY_SIZE(ls1x_eth0_resources), | 194 | .num_resources = ARRAY_SIZE(ls1x_eth1_resources), |
90 | .resource = ls1x_eth0_resources, | 195 | .resource = ls1x_eth1_resources, |
91 | .dev = { | 196 | .dev = { |
92 | .platform_data = &ls1x_eth_data, | 197 | .platform_data = &ls1x_eth1_pdata, |
93 | }, | 198 | }, |
94 | }; | 199 | }; |
95 | 200 | ||
@@ -111,7 +216,7 @@ static struct resource ls1x_ehci_resources[] = { | |||
111 | static struct usb_ehci_pdata ls1x_ehci_pdata = { | 216 | static struct usb_ehci_pdata ls1x_ehci_pdata = { |
112 | }; | 217 | }; |
113 | 218 | ||
114 | struct platform_device ls1x_ehci_device = { | 219 | struct platform_device ls1x_ehci_pdev = { |
115 | .name = "ehci-platform", | 220 | .name = "ehci-platform", |
116 | .id = -1, | 221 | .id = -1, |
117 | .num_resources = ARRAY_SIZE(ls1x_ehci_resources), | 222 | .num_resources = ARRAY_SIZE(ls1x_ehci_resources), |
@@ -123,7 +228,7 @@ struct platform_device ls1x_ehci_device = { | |||
123 | }; | 228 | }; |
124 | 229 | ||
125 | /* Real Time Clock */ | 230 | /* Real Time Clock */ |
126 | struct platform_device ls1x_rtc_device = { | 231 | struct platform_device ls1x_rtc_pdev = { |
127 | .name = "ls1x-rtc", | 232 | .name = "ls1x-rtc", |
128 | .id = -1, | 233 | .id = -1, |
129 | }; | 234 | }; |
diff --git a/arch/mips/loongson1/common/prom.c b/arch/mips/loongson1/common/prom.c index 2a47af5a55c3..68600980ea49 100644 --- a/arch/mips/loongson1/common/prom.c +++ b/arch/mips/loongson1/common/prom.c | |||
@@ -27,7 +27,7 @@ char *prom_getenv(char *envname) | |||
27 | i = strlen(envname); | 27 | i = strlen(envname); |
28 | 28 | ||
29 | while (*env) { | 29 | while (*env) { |
30 | if (strncmp(envname, *env, i) == 0 && *(*env+i) == '=') | 30 | if (strncmp(envname, *env, i) == 0 && *(*env + i) == '=') |
31 | return *env + i + 1; | 31 | return *env + i + 1; |
32 | env++; | 32 | env++; |
33 | } | 33 | } |
@@ -49,7 +49,7 @@ void __init prom_init_cmdline(void) | |||
49 | for (i = 1; i < prom_argc; i++) { | 49 | for (i = 1; i < prom_argc; i++) { |
50 | strcpy(c, prom_argv[i]); | 50 | strcpy(c, prom_argv[i]); |
51 | c += strlen(prom_argv[i]); | 51 | c += strlen(prom_argv[i]); |
52 | if (i < prom_argc-1) | 52 | if (i < prom_argc - 1) |
53 | *c++ = ' '; | 53 | *c++ = ' '; |
54 | } | 54 | } |
55 | *c = 0; | 55 | *c = 0; |
@@ -57,6 +57,7 @@ void __init prom_init_cmdline(void) | |||
57 | 57 | ||
58 | void __init prom_init(void) | 58 | void __init prom_init(void) |
59 | { | 59 | { |
60 | void __iomem *uart_base; | ||
60 | prom_argc = fw_arg0; | 61 | prom_argc = fw_arg0; |
61 | prom_argv = (char **)fw_arg1; | 62 | prom_argv = (char **)fw_arg1; |
62 | prom_envp = (char **)fw_arg2; | 63 | prom_envp = (char **)fw_arg2; |
@@ -65,23 +66,18 @@ void __init prom_init(void) | |||
65 | 66 | ||
66 | memsize = env_or_default("memsize", DEFAULT_MEMSIZE); | 67 | memsize = env_or_default("memsize", DEFAULT_MEMSIZE); |
67 | highmemsize = env_or_default("highmemsize", 0x0); | 68 | highmemsize = env_or_default("highmemsize", 0x0); |
68 | } | ||
69 | 69 | ||
70 | void __init prom_free_prom_memory(void) | 70 | if (strstr(arcs_cmdline, "console=ttyS3")) |
71 | { | 71 | uart_base = ioremap_nocache(LS1X_UART3_BASE, 0x0f); |
72 | else if (strstr(arcs_cmdline, "console=ttyS2")) | ||
73 | uart_base = ioremap_nocache(LS1X_UART2_BASE, 0x0f); | ||
74 | else if (strstr(arcs_cmdline, "console=ttyS1")) | ||
75 | uart_base = ioremap_nocache(LS1X_UART1_BASE, 0x0f); | ||
76 | else | ||
77 | uart_base = ioremap_nocache(LS1X_UART0_BASE, 0x0f); | ||
78 | setup_8250_early_printk_port((unsigned long)uart_base, 0, 0); | ||
72 | } | 79 | } |
73 | 80 | ||
74 | #define PORT(offset) (u8 *)(KSEG1ADDR(LS1X_UART0_BASE + offset)) | 81 | void __init prom_free_prom_memory(void) |
75 | |||
76 | void prom_putchar(char c) | ||
77 | { | 82 | { |
78 | int timeout; | ||
79 | |||
80 | timeout = 1024; | ||
81 | |||
82 | while (((readb(PORT(UART_LSR)) & UART_LSR_THRE) == 0) | ||
83 | && (timeout-- > 0)) | ||
84 | ; | ||
85 | |||
86 | writeb(c, PORT(UART_TX)); | ||
87 | } | 83 | } |
diff --git a/arch/mips/loongson1/common/reset.c b/arch/mips/loongson1/common/reset.c index 547f34b69e4c..c41e4ca56ab4 100644 --- a/arch/mips/loongson1/common/reset.c +++ b/arch/mips/loongson1/common/reset.c | |||
@@ -14,12 +14,7 @@ | |||
14 | 14 | ||
15 | #include <loongson1.h> | 15 | #include <loongson1.h> |
16 | 16 | ||
17 | static void ls1x_restart(char *command) | 17 | static void __iomem *wdt_base; |
18 | { | ||
19 | __raw_writel(0x1, LS1X_WDT_EN); | ||
20 | __raw_writel(0x5000000, LS1X_WDT_TIMER); | ||
21 | __raw_writel(0x1, LS1X_WDT_SET); | ||
22 | } | ||
23 | 18 | ||
24 | static void ls1x_halt(void) | 19 | static void ls1x_halt(void) |
25 | { | 20 | { |
@@ -29,6 +24,15 @@ static void ls1x_halt(void) | |||
29 | } | 24 | } |
30 | } | 25 | } |
31 | 26 | ||
27 | static void ls1x_restart(char *command) | ||
28 | { | ||
29 | __raw_writel(0x1, wdt_base + WDT_EN); | ||
30 | __raw_writel(0x1, wdt_base + WDT_TIMER); | ||
31 | __raw_writel(0x1, wdt_base + WDT_SET); | ||
32 | |||
33 | ls1x_halt(); | ||
34 | } | ||
35 | |||
32 | static void ls1x_power_off(void) | 36 | static void ls1x_power_off(void) |
33 | { | 37 | { |
34 | ls1x_halt(); | 38 | ls1x_halt(); |
@@ -36,6 +40,10 @@ static void ls1x_power_off(void) | |||
36 | 40 | ||
37 | static int __init ls1x_reboot_setup(void) | 41 | static int __init ls1x_reboot_setup(void) |
38 | { | 42 | { |
43 | wdt_base = ioremap_nocache(LS1X_WDT_BASE, 0x0f); | ||
44 | if (!wdt_base) | ||
45 | panic("Failed to remap watchdog registers"); | ||
46 | |||
39 | _machine_restart = ls1x_restart; | 47 | _machine_restart = ls1x_restart; |
40 | _machine_halt = ls1x_halt; | 48 | _machine_halt = ls1x_halt; |
41 | pm_power_off = ls1x_power_off; | 49 | pm_power_off = ls1x_power_off; |
diff --git a/arch/mips/loongson1/common/time.c b/arch/mips/loongson1/common/time.c new file mode 100644 index 000000000000..df0f850d6a5f --- /dev/null +++ b/arch/mips/loongson1/common/time.c | |||
@@ -0,0 +1,226 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Zhang, Keguang <keguang.zhang@gmail.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License as published by the | ||
6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
7 | * option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include <linux/clk.h> | ||
11 | #include <linux/interrupt.h> | ||
12 | #include <asm/time.h> | ||
13 | |||
14 | #include <loongson1.h> | ||
15 | #include <platform.h> | ||
16 | |||
17 | #ifdef CONFIG_CEVT_CSRC_LS1X | ||
18 | |||
19 | #if defined(CONFIG_TIMER_USE_PWM1) | ||
20 | #define LS1X_TIMER_BASE LS1X_PWM1_BASE | ||
21 | #define LS1X_TIMER_IRQ LS1X_PWM1_IRQ | ||
22 | |||
23 | #elif defined(CONFIG_TIMER_USE_PWM2) | ||
24 | #define LS1X_TIMER_BASE LS1X_PWM2_BASE | ||
25 | #define LS1X_TIMER_IRQ LS1X_PWM2_IRQ | ||
26 | |||
27 | #elif defined(CONFIG_TIMER_USE_PWM3) | ||
28 | #define LS1X_TIMER_BASE LS1X_PWM3_BASE | ||
29 | #define LS1X_TIMER_IRQ LS1X_PWM3_IRQ | ||
30 | |||
31 | #else | ||
32 | #define LS1X_TIMER_BASE LS1X_PWM0_BASE | ||
33 | #define LS1X_TIMER_IRQ LS1X_PWM0_IRQ | ||
34 | #endif | ||
35 | |||
36 | DEFINE_RAW_SPINLOCK(ls1x_timer_lock); | ||
37 | |||
38 | static void __iomem *timer_base; | ||
39 | static uint32_t ls1x_jiffies_per_tick; | ||
40 | |||
41 | static inline void ls1x_pwmtimer_set_period(uint32_t period) | ||
42 | { | ||
43 | __raw_writel(period, timer_base + PWM_HRC); | ||
44 | __raw_writel(period, timer_base + PWM_LRC); | ||
45 | } | ||
46 | |||
47 | static inline void ls1x_pwmtimer_restart(void) | ||
48 | { | ||
49 | __raw_writel(0x0, timer_base + PWM_CNT); | ||
50 | __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL); | ||
51 | } | ||
52 | |||
53 | void __init ls1x_pwmtimer_init(void) | ||
54 | { | ||
55 | timer_base = ioremap(LS1X_TIMER_BASE, 0xf); | ||
56 | if (!timer_base) | ||
57 | panic("Failed to remap timer registers"); | ||
58 | |||
59 | ls1x_jiffies_per_tick = DIV_ROUND_CLOSEST(mips_hpt_frequency, HZ); | ||
60 | |||
61 | ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick); | ||
62 | ls1x_pwmtimer_restart(); | ||
63 | } | ||
64 | |||
65 | static cycle_t ls1x_clocksource_read(struct clocksource *cs) | ||
66 | { | ||
67 | unsigned long flags; | ||
68 | int count; | ||
69 | u32 jifs; | ||
70 | static int old_count; | ||
71 | static u32 old_jifs; | ||
72 | |||
73 | raw_spin_lock_irqsave(&ls1x_timer_lock, flags); | ||
74 | /* | ||
75 | * Although our caller may have the read side of xtime_lock, | ||
76 | * this is now a seqlock, and we are cheating in this routine | ||
77 | * by having side effects on state that we cannot undo if | ||
78 | * there is a collision on the seqlock and our caller has to | ||
79 | * retry. (Namely, old_jifs and old_count.) So we must treat | ||
80 | * jiffies as volatile despite the lock. We read jiffies | ||
81 | * before latching the timer count to guarantee that although | ||
82 | * the jiffies value might be older than the count (that is, | ||
83 | * the counter may underflow between the last point where | ||
84 | * jiffies was incremented and the point where we latch the | ||
85 | * count), it cannot be newer. | ||
86 | */ | ||
87 | jifs = jiffies; | ||
88 | /* read the count */ | ||
89 | count = __raw_readl(timer_base + PWM_CNT); | ||
90 | |||
91 | /* | ||
92 | * It's possible for count to appear to go the wrong way for this | ||
93 | * reason: | ||
94 | * | ||
95 | * The timer counter underflows, but we haven't handled the resulting | ||
96 | * interrupt and incremented jiffies yet. | ||
97 | * | ||
98 | * Previous attempts to handle these cases intelligently were buggy, so | ||
99 | * we just do the simple thing now. | ||
100 | */ | ||
101 | if (count < old_count && jifs == old_jifs) | ||
102 | count = old_count; | ||
103 | |||
104 | old_count = count; | ||
105 | old_jifs = jifs; | ||
106 | |||
107 | raw_spin_unlock_irqrestore(&ls1x_timer_lock, flags); | ||
108 | |||
109 | return (cycle_t) (jifs * ls1x_jiffies_per_tick) + count; | ||
110 | } | ||
111 | |||
112 | static struct clocksource ls1x_clocksource = { | ||
113 | .name = "ls1x-pwmtimer", | ||
114 | .read = ls1x_clocksource_read, | ||
115 | .mask = CLOCKSOURCE_MASK(24), | ||
116 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
117 | }; | ||
118 | |||
119 | static irqreturn_t ls1x_clockevent_isr(int irq, void *devid) | ||
120 | { | ||
121 | struct clock_event_device *cd = devid; | ||
122 | |||
123 | ls1x_pwmtimer_restart(); | ||
124 | cd->event_handler(cd); | ||
125 | |||
126 | return IRQ_HANDLED; | ||
127 | } | ||
128 | |||
129 | static void ls1x_clockevent_set_mode(enum clock_event_mode mode, | ||
130 | struct clock_event_device *cd) | ||
131 | { | ||
132 | raw_spin_lock(&ls1x_timer_lock); | ||
133 | switch (mode) { | ||
134 | case CLOCK_EVT_MODE_PERIODIC: | ||
135 | ls1x_pwmtimer_set_period(ls1x_jiffies_per_tick); | ||
136 | ls1x_pwmtimer_restart(); | ||
137 | case CLOCK_EVT_MODE_RESUME: | ||
138 | __raw_writel(INT_EN | CNT_EN, timer_base + PWM_CTRL); | ||
139 | break; | ||
140 | case CLOCK_EVT_MODE_ONESHOT: | ||
141 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
142 | __raw_writel(__raw_readl(timer_base + PWM_CTRL) & ~CNT_EN, | ||
143 | timer_base + PWM_CTRL); | ||
144 | break; | ||
145 | default: | ||
146 | break; | ||
147 | } | ||
148 | raw_spin_unlock(&ls1x_timer_lock); | ||
149 | } | ||
150 | |||
151 | static int ls1x_clockevent_set_next(unsigned long evt, | ||
152 | struct clock_event_device *cd) | ||
153 | { | ||
154 | raw_spin_lock(&ls1x_timer_lock); | ||
155 | ls1x_pwmtimer_set_period(evt); | ||
156 | ls1x_pwmtimer_restart(); | ||
157 | raw_spin_unlock(&ls1x_timer_lock); | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | static struct clock_event_device ls1x_clockevent = { | ||
163 | .name = "ls1x-pwmtimer", | ||
164 | .features = CLOCK_EVT_FEAT_PERIODIC, | ||
165 | .rating = 300, | ||
166 | .irq = LS1X_TIMER_IRQ, | ||
167 | .set_next_event = ls1x_clockevent_set_next, | ||
168 | .set_mode = ls1x_clockevent_set_mode, | ||
169 | }; | ||
170 | |||
171 | static struct irqaction ls1x_pwmtimer_irqaction = { | ||
172 | .name = "ls1x-pwmtimer", | ||
173 | .handler = ls1x_clockevent_isr, | ||
174 | .dev_id = &ls1x_clockevent, | ||
175 | .flags = IRQF_PERCPU | IRQF_TIMER, | ||
176 | }; | ||
177 | |||
178 | static void __init ls1x_time_init(void) | ||
179 | { | ||
180 | struct clock_event_device *cd = &ls1x_clockevent; | ||
181 | int ret; | ||
182 | |||
183 | if (!mips_hpt_frequency) | ||
184 | panic("Invalid timer clock rate"); | ||
185 | |||
186 | ls1x_pwmtimer_init(); | ||
187 | |||
188 | clockevent_set_clock(cd, mips_hpt_frequency); | ||
189 | cd->max_delta_ns = clockevent_delta2ns(0xffffff, cd); | ||
190 | cd->min_delta_ns = clockevent_delta2ns(0x000300, cd); | ||
191 | cd->cpumask = cpumask_of(smp_processor_id()); | ||
192 | clockevents_register_device(cd); | ||
193 | |||
194 | ls1x_clocksource.rating = 200 + mips_hpt_frequency / 10000000; | ||
195 | ret = clocksource_register_hz(&ls1x_clocksource, mips_hpt_frequency); | ||
196 | if (ret) | ||
197 | panic(KERN_ERR "Failed to register clocksource: %d\n", ret); | ||
198 | |||
199 | setup_irq(LS1X_TIMER_IRQ, &ls1x_pwmtimer_irqaction); | ||
200 | } | ||
201 | #endif /* CONFIG_CEVT_CSRC_LS1X */ | ||
202 | |||
203 | void __init plat_time_init(void) | ||
204 | { | ||
205 | struct clk *clk = NULL; | ||
206 | |||
207 | /* initialize LS1X clocks */ | ||
208 | ls1x_clk_init(); | ||
209 | |||
210 | #ifdef CONFIG_CEVT_CSRC_LS1X | ||
211 | /* setup LS1X PWM timer */ | ||
212 | clk = clk_get(NULL, "ls1x_pwmtimer"); | ||
213 | if (IS_ERR(clk)) | ||
214 | panic("unable to get timer clock, err=%ld", PTR_ERR(clk)); | ||
215 | |||
216 | mips_hpt_frequency = clk_get_rate(clk); | ||
217 | ls1x_time_init(); | ||
218 | #else | ||
219 | /* setup mips r4k timer */ | ||
220 | clk = clk_get(NULL, "cpu_clk"); | ||
221 | if (IS_ERR(clk)) | ||
222 | panic("unable to get cpu clock, err=%ld", PTR_ERR(clk)); | ||
223 | |||
224 | mips_hpt_frequency = clk_get_rate(clk) / 2; | ||
225 | #endif /* CONFIG_CEVT_CSRC_LS1X */ | ||
226 | } | ||
diff --git a/arch/mips/loongson1/ls1b/board.c b/arch/mips/loongson1/ls1b/board.c index b26b10dac70a..58daeea25739 100644 --- a/arch/mips/loongson1/ls1b/board.c +++ b/arch/mips/loongson1/ls1b/board.c | |||
@@ -10,17 +10,19 @@ | |||
10 | #include <platform.h> | 10 | #include <platform.h> |
11 | 11 | ||
12 | static struct platform_device *ls1b_platform_devices[] __initdata = { | 12 | static struct platform_device *ls1b_platform_devices[] __initdata = { |
13 | &ls1x_uart_device, | 13 | &ls1x_uart_pdev, |
14 | &ls1x_eth0_device, | 14 | &ls1x_cpufreq_pdev, |
15 | &ls1x_ehci_device, | 15 | &ls1x_eth0_pdev, |
16 | &ls1x_rtc_device, | 16 | &ls1x_eth1_pdev, |
17 | &ls1x_ehci_pdev, | ||
18 | &ls1x_rtc_pdev, | ||
17 | }; | 19 | }; |
18 | 20 | ||
19 | static int __init ls1b_platform_init(void) | 21 | static int __init ls1b_platform_init(void) |
20 | { | 22 | { |
21 | int err; | 23 | int err; |
22 | 24 | ||
23 | ls1x_serial_setup(&ls1x_uart_device); | 25 | ls1x_serial_setup(&ls1x_uart_pdev); |
24 | 26 | ||
25 | err = platform_add_devices(ls1b_platform_devices, | 27 | err = platform_add_devices(ls1b_platform_devices, |
26 | ARRAY_SIZE(ls1b_platform_devices)); | 28 | ARRAY_SIZE(ls1b_platform_devices)); |
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index cac529a405b8..9dfcd7fc1bc3 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c | |||
@@ -643,9 +643,14 @@ static inline int cop1_64bit(struct pt_regs *xcp) | |||
643 | return !test_thread_flag(TIF_32BIT_FPREGS); | 643 | return !test_thread_flag(TIF_32BIT_FPREGS); |
644 | } | 644 | } |
645 | 645 | ||
646 | static inline bool hybrid_fprs(void) | ||
647 | { | ||
648 | return test_thread_flag(TIF_HYBRID_FPREGS); | ||
649 | } | ||
650 | |||
646 | #define SIFROMREG(si, x) \ | 651 | #define SIFROMREG(si, x) \ |
647 | do { \ | 652 | do { \ |
648 | if (cop1_64bit(xcp)) \ | 653 | if (cop1_64bit(xcp) && !hybrid_fprs()) \ |
649 | (si) = (int)get_fpr32(&ctx->fpr[x], 0); \ | 654 | (si) = (int)get_fpr32(&ctx->fpr[x], 0); \ |
650 | else \ | 655 | else \ |
651 | (si) = (int)get_fpr32(&ctx->fpr[(x) & ~1], (x) & 1); \ | 656 | (si) = (int)get_fpr32(&ctx->fpr[(x) & ~1], (x) & 1); \ |
@@ -653,7 +658,7 @@ do { \ | |||
653 | 658 | ||
654 | #define SITOREG(si, x) \ | 659 | #define SITOREG(si, x) \ |
655 | do { \ | 660 | do { \ |
656 | if (cop1_64bit(xcp)) { \ | 661 | if (cop1_64bit(xcp) && !hybrid_fprs()) { \ |
657 | unsigned i; \ | 662 | unsigned i; \ |
658 | set_fpr32(&ctx->fpr[x], 0, si); \ | 663 | set_fpr32(&ctx->fpr[x], 0, si); \ |
659 | for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val32); i++) \ | 664 | for (i = 1; i < ARRAY_SIZE(ctx->fpr[x].val32); i++) \ |
diff --git a/arch/mips/math-emu/ieee754dp.c b/arch/mips/math-emu/ieee754dp.c index fd134675fc2e..068f45a415fc 100644 --- a/arch/mips/math-emu/ieee754dp.c +++ b/arch/mips/math-emu/ieee754dp.c | |||
@@ -38,7 +38,7 @@ int ieee754dp_isnan(union ieee754dp x) | |||
38 | static inline int ieee754dp_issnan(union ieee754dp x) | 38 | static inline int ieee754dp_issnan(union ieee754dp x) |
39 | { | 39 | { |
40 | assert(ieee754dp_isnan(x)); | 40 | assert(ieee754dp_isnan(x)); |
41 | return ((DPMANT(x) & DP_MBIT(DP_FBITS-1)) == DP_MBIT(DP_FBITS-1)); | 41 | return (DPMANT(x) & DP_MBIT(DP_FBITS - 1)) == DP_MBIT(DP_FBITS - 1); |
42 | } | 42 | } |
43 | 43 | ||
44 | 44 | ||
diff --git a/arch/mips/math-emu/ieee754sp.c b/arch/mips/math-emu/ieee754sp.c index d348efe91445..ba88301579c2 100644 --- a/arch/mips/math-emu/ieee754sp.c +++ b/arch/mips/math-emu/ieee754sp.c | |||
@@ -38,7 +38,7 @@ int ieee754sp_isnan(union ieee754sp x) | |||
38 | static inline int ieee754sp_issnan(union ieee754sp x) | 38 | static inline int ieee754sp_issnan(union ieee754sp x) |
39 | { | 39 | { |
40 | assert(ieee754sp_isnan(x)); | 40 | assert(ieee754sp_isnan(x)); |
41 | return (SPMANT(x) & SP_MBIT(SP_FBITS-1)); | 41 | return SPMANT(x) & SP_MBIT(SP_FBITS - 1); |
42 | } | 42 | } |
43 | 43 | ||
44 | 44 | ||
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index 7f4f93ab22b7..67ede4ef9b8d 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile | |||
@@ -4,7 +4,13 @@ | |||
4 | 4 | ||
5 | obj-y += cache.o dma-default.o extable.o fault.o \ | 5 | obj-y += cache.o dma-default.o extable.o fault.o \ |
6 | gup.o init.o mmap.o page.o page-funcs.o \ | 6 | gup.o init.o mmap.o page.o page-funcs.o \ |
7 | tlbex.o tlbex-fault.o tlb-funcs.o uasm-mips.o | 7 | tlbex.o tlbex-fault.o tlb-funcs.o |
8 | |||
9 | ifdef CONFIG_CPU_MICROMIPS | ||
10 | obj-y += uasm-micromips.o | ||
11 | else | ||
12 | obj-y += uasm-mips.o | ||
13 | endif | ||
8 | 14 | ||
9 | obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o | 15 | obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o |
10 | obj-$(CONFIG_64BIT) += pgtable-64.o | 16 | obj-$(CONFIG_64BIT) += pgtable-64.o |
@@ -22,5 +28,3 @@ obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o | |||
22 | obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o | 28 | obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o |
23 | obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o | 29 | obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o |
24 | obj-$(CONFIG_MIPS_CPU_SCACHE) += sc-mips.o | 30 | obj-$(CONFIG_MIPS_CPU_SCACHE) += sc-mips.o |
25 | |||
26 | obj-$(CONFIG_SYS_SUPPORTS_MICROMIPS) += uasm-micromips.o | ||
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index fbcd8674ff1d..dd261df005c2 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
@@ -917,6 +917,18 @@ static inline void alias_74k_erratum(struct cpuinfo_mips *c) | |||
917 | } | 917 | } |
918 | } | 918 | } |
919 | 919 | ||
920 | static void b5k_instruction_hazard(void) | ||
921 | { | ||
922 | __sync(); | ||
923 | __sync(); | ||
924 | __asm__ __volatile__( | ||
925 | " nop; nop; nop; nop; nop; nop; nop; nop\n" | ||
926 | " nop; nop; nop; nop; nop; nop; nop; nop\n" | ||
927 | " nop; nop; nop; nop; nop; nop; nop; nop\n" | ||
928 | " nop; nop; nop; nop; nop; nop; nop; nop\n" | ||
929 | : : : "memory"); | ||
930 | } | ||
931 | |||
920 | static char *way_string[] = { NULL, "direct mapped", "2-way", | 932 | static char *way_string[] = { NULL, "direct mapped", "2-way", |
921 | "3-way", "4-way", "5-way", "6-way", "7-way", "8-way" | 933 | "3-way", "4-way", "5-way", "6-way", "7-way", "8-way" |
922 | }; | 934 | }; |
@@ -1683,6 +1695,37 @@ void r4k_cache_init(void) | |||
1683 | 1695 | ||
1684 | coherency_setup(); | 1696 | coherency_setup(); |
1685 | board_cache_error_setup = r4k_cache_error_setup; | 1697 | board_cache_error_setup = r4k_cache_error_setup; |
1698 | |||
1699 | /* | ||
1700 | * Per-CPU overrides | ||
1701 | */ | ||
1702 | switch (current_cpu_type()) { | ||
1703 | case CPU_BMIPS4350: | ||
1704 | case CPU_BMIPS4380: | ||
1705 | /* No IPI is needed because all CPUs share the same D$ */ | ||
1706 | flush_data_cache_page = r4k_blast_dcache_page; | ||
1707 | break; | ||
1708 | case CPU_BMIPS5000: | ||
1709 | /* We lose our superpowers if L2 is disabled */ | ||
1710 | if (c->scache.flags & MIPS_CACHE_NOT_PRESENT) | ||
1711 | break; | ||
1712 | |||
1713 | /* I$ fills from D$ just by emptying the write buffers */ | ||
1714 | flush_cache_page = (void *)b5k_instruction_hazard; | ||
1715 | flush_cache_range = (void *)b5k_instruction_hazard; | ||
1716 | flush_cache_sigtramp = (void *)b5k_instruction_hazard; | ||
1717 | local_flush_data_cache_page = (void *)b5k_instruction_hazard; | ||
1718 | flush_data_cache_page = (void *)b5k_instruction_hazard; | ||
1719 | flush_icache_range = (void *)b5k_instruction_hazard; | ||
1720 | local_flush_icache_range = (void *)b5k_instruction_hazard; | ||
1721 | |||
1722 | /* Cache aliases are handled in hardware; allow HIGHMEM */ | ||
1723 | current_cpu_data.dcache.flags &= ~MIPS_CACHE_ALIASES; | ||
1724 | |||
1725 | /* Optimization: an L2 flush implicitly flushes the L1 */ | ||
1726 | current_cpu_data.options |= MIPS_CPU_INCLUSIVE_CACHES; | ||
1727 | break; | ||
1728 | } | ||
1686 | } | 1729 | } |
1687 | 1730 | ||
1688 | static int r4k_cache_pm_notifier(struct notifier_block *self, unsigned long cmd, | 1731 | static int r4k_cache_pm_notifier(struct notifier_block *self, unsigned long cmd, |
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 33ba3c558fe4..af5f046e627e 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c | |||
@@ -61,6 +61,11 @@ static inline struct page *dma_addr_to_page(struct device *dev, | |||
61 | * Warning on the terminology - Linux calls an uncached area coherent; | 61 | * Warning on the terminology - Linux calls an uncached area coherent; |
62 | * MIPS terminology calls memory areas with hardware maintained coherency | 62 | * MIPS terminology calls memory areas with hardware maintained coherency |
63 | * coherent. | 63 | * coherent. |
64 | * | ||
65 | * Note that the R14000 and R16000 should also be checked for in this | ||
66 | * condition. However this function is only called on non-I/O-coherent | ||
67 | * systems and only the R10000 and R12000 are used in such systems, the | ||
68 | * SGI IP28 Indigo² rsp. SGI IP32 aka O2. | ||
64 | */ | 69 | */ |
65 | static inline int cpu_needs_post_dma_flush(struct device *dev) | 70 | static inline int cpu_needs_post_dma_flush(struct device *dev) |
66 | { | 71 | { |
diff --git a/arch/mips/mm/gup.c b/arch/mips/mm/gup.c index 06ce17c2a905..7cba480568c8 100644 --- a/arch/mips/mm/gup.c +++ b/arch/mips/mm/gup.c | |||
@@ -17,7 +17,7 @@ | |||
17 | 17 | ||
18 | static inline pte_t gup_get_pte(pte_t *ptep) | 18 | static inline pte_t gup_get_pte(pte_t *ptep) |
19 | { | 19 | { |
20 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 20 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
21 | pte_t pte; | 21 | pte_t pte; |
22 | 22 | ||
23 | retry: | 23 | retry: |
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index f42e35e42790..448cde372af0 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
@@ -95,7 +95,7 @@ static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot) | |||
95 | idx += in_interrupt() ? FIX_N_COLOURS : 0; | 95 | idx += in_interrupt() ? FIX_N_COLOURS : 0; |
96 | vaddr = __fix_to_virt(FIX_CMAP_END - idx); | 96 | vaddr = __fix_to_virt(FIX_CMAP_END - idx); |
97 | pte = mk_pte(page, prot); | 97 | pte = mk_pte(page, prot); |
98 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 98 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
99 | entrylo = pte.pte_high; | 99 | entrylo = pte.pte_high; |
100 | #else | 100 | #else |
101 | entrylo = pte_to_entrylo(pte_val(pte)); | 101 | entrylo = pte_to_entrylo(pte_val(pte)); |
diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c index 7f840bc08abf..8d5008cbdc0f 100644 --- a/arch/mips/mm/ioremap.c +++ b/arch/mips/mm/ioremap.c | |||
@@ -17,9 +17,9 @@ | |||
17 | #include <asm/tlbflush.h> | 17 | #include <asm/tlbflush.h> |
18 | 18 | ||
19 | static inline void remap_area_pte(pte_t * pte, unsigned long address, | 19 | static inline void remap_area_pte(pte_t * pte, unsigned long address, |
20 | phys_t size, phys_t phys_addr, unsigned long flags) | 20 | phys_addr_t size, phys_addr_t phys_addr, unsigned long flags) |
21 | { | 21 | { |
22 | phys_t end; | 22 | phys_addr_t end; |
23 | unsigned long pfn; | 23 | unsigned long pfn; |
24 | pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE | 24 | pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE |
25 | | __WRITEABLE | flags); | 25 | | __WRITEABLE | flags); |
@@ -43,9 +43,9 @@ static inline void remap_area_pte(pte_t * pte, unsigned long address, | |||
43 | } | 43 | } |
44 | 44 | ||
45 | static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, | 45 | static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, |
46 | phys_t size, phys_t phys_addr, unsigned long flags) | 46 | phys_addr_t size, phys_addr_t phys_addr, unsigned long flags) |
47 | { | 47 | { |
48 | phys_t end; | 48 | phys_addr_t end; |
49 | 49 | ||
50 | address &= ~PGDIR_MASK; | 50 | address &= ~PGDIR_MASK; |
51 | end = address + size; | 51 | end = address + size; |
@@ -64,8 +64,8 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, | |||
64 | return 0; | 64 | return 0; |
65 | } | 65 | } |
66 | 66 | ||
67 | static int remap_area_pages(unsigned long address, phys_t phys_addr, | 67 | static int remap_area_pages(unsigned long address, phys_addr_t phys_addr, |
68 | phys_t size, unsigned long flags) | 68 | phys_addr_t size, unsigned long flags) |
69 | { | 69 | { |
70 | int error; | 70 | int error; |
71 | pgd_t * dir; | 71 | pgd_t * dir; |
@@ -111,13 +111,13 @@ static int remap_area_pages(unsigned long address, phys_t phys_addr, | |||
111 | * caller shouldn't need to know that small detail. | 111 | * caller shouldn't need to know that small detail. |
112 | */ | 112 | */ |
113 | 113 | ||
114 | #define IS_LOW512(addr) (!((phys_t)(addr) & (phys_t) ~0x1fffffffULL)) | 114 | #define IS_LOW512(addr) (!((phys_addr_t)(addr) & (phys_addr_t) ~0x1fffffffULL)) |
115 | 115 | ||
116 | void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags) | 116 | void __iomem * __ioremap(phys_addr_t phys_addr, phys_addr_t size, unsigned long flags) |
117 | { | 117 | { |
118 | struct vm_struct * area; | 118 | struct vm_struct * area; |
119 | unsigned long offset; | 119 | unsigned long offset; |
120 | phys_t last_addr; | 120 | phys_addr_t last_addr; |
121 | void * addr; | 121 | void * addr; |
122 | 122 | ||
123 | phys_addr = fixup_bigphys_addr(phys_addr, size); | 123 | phys_addr = fixup_bigphys_addr(phys_addr, size); |
diff --git a/arch/mips/mm/sc-r5k.c b/arch/mips/mm/sc-r5k.c index 0216ed6eaa2a..751b5cd18bf2 100644 --- a/arch/mips/mm/sc-r5k.c +++ b/arch/mips/mm/sc-r5k.c | |||
@@ -81,7 +81,7 @@ static inline int __init r5k_sc_probe(void) | |||
81 | unsigned long config = read_c0_config(); | 81 | unsigned long config = read_c0_config(); |
82 | 82 | ||
83 | if (config & CONF_SC) | 83 | if (config & CONF_SC) |
84 | return(0); | 84 | return 0; |
85 | 85 | ||
86 | scache_size = (512 * 1024) << ((config & R5K_CONF_SS) >> 20); | 86 | scache_size = (512 * 1024) << ((config & R5K_CONF_SS) >> 20); |
87 | 87 | ||
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index c3917e251f59..e90b2e899291 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c | |||
@@ -332,7 +332,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
332 | { | 332 | { |
333 | ptep = pte_offset_map(pmdp, address); | 333 | ptep = pte_offset_map(pmdp, address); |
334 | 334 | ||
335 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 335 | #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32) |
336 | write_c0_entrylo0(ptep->pte_high); | 336 | write_c0_entrylo0(ptep->pte_high); |
337 | ptep++; | 337 | ptep++; |
338 | write_c0_entrylo1(ptep->pte_high); | 338 | write_c0_entrylo1(ptep->pte_high); |
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index e3328a96e809..3978a3d81366 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c | |||
@@ -637,7 +637,7 @@ static __maybe_unused void build_convert_pte_to_entrylo(u32 **p, | |||
637 | if (cpu_has_rixi) { | 637 | if (cpu_has_rixi) { |
638 | UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL)); | 638 | UASM_i_ROTR(p, reg, reg, ilog2(_PAGE_GLOBAL)); |
639 | } else { | 639 | } else { |
640 | #ifdef CONFIG_64BIT_PHYS_ADDR | 640 | #ifdef CONFIG_PHYS_ADDR_T_64BIT |
641 | uasm_i_dsrl_safe(p, reg, reg, ilog2(_PAGE_GLOBAL)); | 641 | uasm_i_dsrl_safe(p, reg, reg, ilog2(_PAGE_GLOBAL)); |
642 | #else | 642 | #else |
643 | UASM_i_SRL(p, reg, reg, ilog2(_PAGE_GLOBAL)); | 643 | UASM_i_SRL(p, reg, reg, ilog2(_PAGE_GLOBAL)); |
@@ -1009,7 +1009,7 @@ static void build_update_entries(u32 **p, unsigned int tmp, unsigned int ptep) | |||
1009 | * 64bit address support (36bit on a 32bit CPU) in a 32bit | 1009 | * 64bit address support (36bit on a 32bit CPU) in a 32bit |
1010 | * Kernel is a special case. Only a few CPUs use it. | 1010 | * Kernel is a special case. Only a few CPUs use it. |
1011 | */ | 1011 | */ |
1012 | #ifdef CONFIG_64BIT_PHYS_ADDR | 1012 | #ifdef CONFIG_PHYS_ADDR_T_64BIT |
1013 | if (cpu_has_64bits) { | 1013 | if (cpu_has_64bits) { |
1014 | uasm_i_ld(p, tmp, 0, ptep); /* get even pte */ | 1014 | uasm_i_ld(p, tmp, 0, ptep); /* get even pte */ |
1015 | uasm_i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */ | 1015 | uasm_i_ld(p, ptep, sizeof(pte_t), ptep); /* get odd pte */ |
@@ -1510,14 +1510,14 @@ static void | |||
1510 | iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr) | 1510 | iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr) |
1511 | { | 1511 | { |
1512 | #ifdef CONFIG_SMP | 1512 | #ifdef CONFIG_SMP |
1513 | # ifdef CONFIG_64BIT_PHYS_ADDR | 1513 | # ifdef CONFIG_PHYS_ADDR_T_64BIT |
1514 | if (cpu_has_64bits) | 1514 | if (cpu_has_64bits) |
1515 | uasm_i_lld(p, pte, 0, ptr); | 1515 | uasm_i_lld(p, pte, 0, ptr); |
1516 | else | 1516 | else |
1517 | # endif | 1517 | # endif |
1518 | UASM_i_LL(p, pte, 0, ptr); | 1518 | UASM_i_LL(p, pte, 0, ptr); |
1519 | #else | 1519 | #else |
1520 | # ifdef CONFIG_64BIT_PHYS_ADDR | 1520 | # ifdef CONFIG_PHYS_ADDR_T_64BIT |
1521 | if (cpu_has_64bits) | 1521 | if (cpu_has_64bits) |
1522 | uasm_i_ld(p, pte, 0, ptr); | 1522 | uasm_i_ld(p, pte, 0, ptr); |
1523 | else | 1523 | else |
@@ -1530,13 +1530,13 @@ static void | |||
1530 | iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, | 1530 | iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, |
1531 | unsigned int mode) | 1531 | unsigned int mode) |
1532 | { | 1532 | { |
1533 | #ifdef CONFIG_64BIT_PHYS_ADDR | 1533 | #ifdef CONFIG_PHYS_ADDR_T_64BIT |
1534 | unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY); | 1534 | unsigned int hwmode = mode & (_PAGE_VALID | _PAGE_DIRTY); |
1535 | #endif | 1535 | #endif |
1536 | 1536 | ||
1537 | uasm_i_ori(p, pte, pte, mode); | 1537 | uasm_i_ori(p, pte, pte, mode); |
1538 | #ifdef CONFIG_SMP | 1538 | #ifdef CONFIG_SMP |
1539 | # ifdef CONFIG_64BIT_PHYS_ADDR | 1539 | # ifdef CONFIG_PHYS_ADDR_T_64BIT |
1540 | if (cpu_has_64bits) | 1540 | if (cpu_has_64bits) |
1541 | uasm_i_scd(p, pte, 0, ptr); | 1541 | uasm_i_scd(p, pte, 0, ptr); |
1542 | else | 1542 | else |
@@ -1548,7 +1548,7 @@ iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, | |||
1548 | else | 1548 | else |
1549 | uasm_il_beqz(p, r, pte, label_smp_pgtable_change); | 1549 | uasm_il_beqz(p, r, pte, label_smp_pgtable_change); |
1550 | 1550 | ||
1551 | # ifdef CONFIG_64BIT_PHYS_ADDR | 1551 | # ifdef CONFIG_PHYS_ADDR_T_64BIT |
1552 | if (!cpu_has_64bits) { | 1552 | if (!cpu_has_64bits) { |
1553 | /* no uasm_i_nop needed */ | 1553 | /* no uasm_i_nop needed */ |
1554 | uasm_i_ll(p, pte, sizeof(pte_t) / 2, ptr); | 1554 | uasm_i_ll(p, pte, sizeof(pte_t) / 2, ptr); |
@@ -1563,14 +1563,14 @@ iPTE_SW(u32 **p, struct uasm_reloc **r, unsigned int pte, unsigned int ptr, | |||
1563 | uasm_i_nop(p); | 1563 | uasm_i_nop(p); |
1564 | # endif | 1564 | # endif |
1565 | #else | 1565 | #else |
1566 | # ifdef CONFIG_64BIT_PHYS_ADDR | 1566 | # ifdef CONFIG_PHYS_ADDR_T_64BIT |
1567 | if (cpu_has_64bits) | 1567 | if (cpu_has_64bits) |
1568 | uasm_i_sd(p, pte, 0, ptr); | 1568 | uasm_i_sd(p, pte, 0, ptr); |
1569 | else | 1569 | else |
1570 | # endif | 1570 | # endif |
1571 | UASM_i_SW(p, pte, 0, ptr); | 1571 | UASM_i_SW(p, pte, 0, ptr); |
1572 | 1572 | ||
1573 | # ifdef CONFIG_64BIT_PHYS_ADDR | 1573 | # ifdef CONFIG_PHYS_ADDR_T_64BIT |
1574 | if (!cpu_has_64bits) { | 1574 | if (!cpu_has_64bits) { |
1575 | uasm_i_lw(p, pte, sizeof(pte_t) / 2, ptr); | 1575 | uasm_i_lw(p, pte, sizeof(pte_t) / 2, ptr); |
1576 | uasm_i_ori(p, pte, pte, hwmode); | 1576 | uasm_i_ori(p, pte, pte, hwmode); |
diff --git a/arch/mips/mm/uasm-mips.c b/arch/mips/mm/uasm-mips.c index 6708a2dbf934..8e02291cfc0c 100644 --- a/arch/mips/mm/uasm-mips.c +++ b/arch/mips/mm/uasm-mips.c | |||
@@ -96,9 +96,11 @@ static struct insn insn_table[] = { | |||
96 | { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | 96 | { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, |
97 | { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD }, | 97 | { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD }, |
98 | { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET}, | 98 | { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET}, |
99 | { insn_mfhc0, M(cop0_op, mfhc0_op, 0, 0, 0, 0), RT | RD | SET}, | ||
99 | { insn_mfhi, M(spec_op, 0, 0, 0, 0, mfhi_op), RD }, | 100 | { insn_mfhi, M(spec_op, 0, 0, 0, 0, mfhi_op), RD }, |
100 | { insn_mflo, M(spec_op, 0, 0, 0, 0, mflo_op), RD }, | 101 | { insn_mflo, M(spec_op, 0, 0, 0, 0, mflo_op), RD }, |
101 | { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET}, | 102 | { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET}, |
103 | { insn_mthc0, M(cop0_op, mthc0_op, 0, 0, 0, 0), RT | RD | SET}, | ||
102 | { insn_mul, M(spec2_op, 0, 0, 0, 0, mul_op), RS | RT | RD}, | 104 | { insn_mul, M(spec2_op, 0, 0, 0, 0, mul_op), RS | RT | RD}, |
103 | { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, | 105 | { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, |
104 | { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD }, | 106 | { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD }, |
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c index a01b0d6cedd2..4adf30284813 100644 --- a/arch/mips/mm/uasm.c +++ b/arch/mips/mm/uasm.c | |||
@@ -51,12 +51,12 @@ enum opcode { | |||
51 | insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret, | 51 | insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret, |
52 | insn_ext, insn_ins, insn_j, insn_jal, insn_jalr, insn_jr, insn_lb, | 52 | insn_ext, insn_ins, insn_j, insn_jal, insn_jalr, insn_jr, insn_lb, |
53 | insn_ld, insn_ldx, insn_lh, insn_ll, insn_lld, insn_lui, insn_lw, | 53 | insn_ld, insn_ldx, insn_lh, insn_ll, insn_lld, insn_lui, insn_lw, |
54 | insn_lwx, insn_mfc0, insn_mfhi, insn_mflo, insn_mtc0, insn_mul, | 54 | insn_lwx, insn_mfc0, insn_mfhc0, insn_mfhi, insn_mflo, insn_mtc0, |
55 | insn_or, insn_ori, insn_pref, insn_rfe, insn_rotr, insn_sc, insn_scd, | 55 | insn_mthc0, insn_mul, insn_or, insn_ori, insn_pref, insn_rfe, |
56 | insn_sd, insn_sll, insn_sllv, insn_slt, insn_sltiu, insn_sltu, insn_sra, | 56 | insn_rotr, insn_sc, insn_scd, insn_sd, insn_sll, insn_sllv, insn_slt, |
57 | insn_srl, insn_srlv, insn_subu, insn_sw, insn_sync, insn_syscall, | 57 | insn_sltiu, insn_sltu, insn_sra, insn_srl, insn_srlv, insn_subu, |
58 | insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_wait, insn_wsbh, | 58 | insn_sw, insn_sync, insn_syscall, insn_tlbp, insn_tlbr, insn_tlbwi, |
59 | insn_xor, insn_xori, insn_yield, | 59 | insn_tlbwr, insn_wait, insn_wsbh, insn_xor, insn_xori, insn_yield, |
60 | }; | 60 | }; |
61 | 61 | ||
62 | struct insn { | 62 | struct insn { |
@@ -284,9 +284,11 @@ I_u2s3u1(_lld) | |||
284 | I_u1s2(_lui) | 284 | I_u1s2(_lui) |
285 | I_u2s3u1(_lw) | 285 | I_u2s3u1(_lw) |
286 | I_u1u2u3(_mfc0) | 286 | I_u1u2u3(_mfc0) |
287 | I_u1u2u3(_mfhc0) | ||
287 | I_u1(_mfhi) | 288 | I_u1(_mfhi) |
288 | I_u1(_mflo) | 289 | I_u1(_mflo) |
289 | I_u1u2u3(_mtc0) | 290 | I_u1u2u3(_mtc0) |
291 | I_u1u2u3(_mthc0) | ||
290 | I_u3u1u2(_mul) | 292 | I_u3u1u2(_mul) |
291 | I_u2u1u3(_ori) | 293 | I_u2u1u3(_ori) |
292 | I_u3u1u2(_or) | 294 | I_u3u1u2(_or) |
diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c index 0f60256d3784..6849f533154f 100644 --- a/arch/mips/mti-malta/malta-init.c +++ b/arch/mips/mti-malta/malta-init.c | |||
@@ -111,7 +111,7 @@ static void __init mips_ejtag_setup(void) | |||
111 | flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); | 111 | flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); |
112 | } | 112 | } |
113 | 113 | ||
114 | phys_t mips_cpc_default_phys_base(void) | 114 | phys_addr_t mips_cpc_default_phys_base(void) |
115 | { | 115 | { |
116 | return CPC_BASE_ADDR; | 116 | return CPC_BASE_ADDR; |
117 | } | 117 | } |
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index e4f43baa8f67..d1392f8f5811 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/smp.h> | 18 | #include <linux/smp.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/irqchip/mips-gic.h> | ||
21 | #include <linux/kernel_stat.h> | 22 | #include <linux/kernel_stat.h> |
22 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
23 | #include <linux/random.h> | 24 | #include <linux/random.h> |
@@ -33,19 +34,13 @@ | |||
33 | #include <asm/mips-boards/generic.h> | 34 | #include <asm/mips-boards/generic.h> |
34 | #include <asm/mips-boards/msc01_pci.h> | 35 | #include <asm/mips-boards/msc01_pci.h> |
35 | #include <asm/msc01_ic.h> | 36 | #include <asm/msc01_ic.h> |
36 | #include <asm/gic.h> | ||
37 | #include <asm/setup.h> | 37 | #include <asm/setup.h> |
38 | #include <asm/rtlx.h> | 38 | #include <asm/rtlx.h> |
39 | 39 | ||
40 | static unsigned long _msc01_biu_base; | 40 | static void __iomem *_msc01_biu_base; |
41 | static unsigned int ipi_map[NR_CPUS]; | ||
42 | 41 | ||
43 | static DEFINE_RAW_SPINLOCK(mips_irq_lock); | 42 | static DEFINE_RAW_SPINLOCK(mips_irq_lock); |
44 | 43 | ||
45 | #ifdef CONFIG_MIPS_GIC_IPI | ||
46 | DECLARE_BITMAP(ipi_ints, GIC_NUM_INTRS); | ||
47 | #endif | ||
48 | |||
49 | static inline int mips_pcibios_iack(void) | 44 | static inline int mips_pcibios_iack(void) |
50 | { | 45 | { |
51 | int irq; | 46 | int irq; |
@@ -127,24 +122,10 @@ static void malta_hw0_irqdispatch(void) | |||
127 | #endif | 122 | #endif |
128 | } | 123 | } |
129 | 124 | ||
130 | static void malta_ipi_irqdispatch(void) | 125 | static irqreturn_t i8259_handler(int irq, void *dev_id) |
131 | { | 126 | { |
132 | #ifdef CONFIG_MIPS_GIC_IPI | 127 | malta_hw0_irqdispatch(); |
133 | unsigned long irq; | 128 | return IRQ_HANDLED; |
134 | DECLARE_BITMAP(pending, GIC_NUM_INTRS); | ||
135 | |||
136 | gic_get_int_mask(pending, ipi_ints); | ||
137 | |||
138 | irq = find_first_bit(pending, GIC_NUM_INTRS); | ||
139 | |||
140 | while (irq < GIC_NUM_INTRS) { | ||
141 | do_IRQ(MIPS_GIC_IRQ_BASE + irq); | ||
142 | |||
143 | irq = find_next_bit(pending, GIC_NUM_INTRS, irq + 1); | ||
144 | } | ||
145 | #endif | ||
146 | if (gic_compare_int()) | ||
147 | do_IRQ(MIPS_GIC_IRQ_BASE); | ||
148 | } | 129 | } |
149 | 130 | ||
150 | static void corehi_irqdispatch(void) | 131 | static void corehi_irqdispatch(void) |
@@ -203,95 +184,10 @@ static void corehi_irqdispatch(void) | |||
203 | die("CoreHi interrupt", regs); | 184 | die("CoreHi interrupt", regs); |
204 | } | 185 | } |
205 | 186 | ||
206 | static inline int clz(unsigned long x) | 187 | static irqreturn_t corehi_handler(int irq, void *dev_id) |
207 | { | ||
208 | __asm__( | ||
209 | " .set push \n" | ||
210 | " .set mips32 \n" | ||
211 | " clz %0, %1 \n" | ||
212 | " .set pop \n" | ||
213 | : "=r" (x) | ||
214 | : "r" (x)); | ||
215 | |||
216 | return x; | ||
217 | } | ||
218 | |||
219 | /* | ||
220 | * Version of ffs that only looks at bits 12..15. | ||
221 | */ | ||
222 | static inline unsigned int irq_ffs(unsigned int pending) | ||
223 | { | ||
224 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) | ||
225 | return -clz(pending) + 31 - CAUSEB_IP; | ||
226 | #else | ||
227 | unsigned int a0 = 7; | ||
228 | unsigned int t0; | ||
229 | |||
230 | t0 = pending & 0xf000; | ||
231 | t0 = t0 < 1; | ||
232 | t0 = t0 << 2; | ||
233 | a0 = a0 - t0; | ||
234 | pending = pending << t0; | ||
235 | |||
236 | t0 = pending & 0xc000; | ||
237 | t0 = t0 < 1; | ||
238 | t0 = t0 << 1; | ||
239 | a0 = a0 - t0; | ||
240 | pending = pending << t0; | ||
241 | |||
242 | t0 = pending & 0x8000; | ||
243 | t0 = t0 < 1; | ||
244 | /* t0 = t0 << 2; */ | ||
245 | a0 = a0 - t0; | ||
246 | /* pending = pending << t0; */ | ||
247 | |||
248 | return a0; | ||
249 | #endif | ||
250 | } | ||
251 | |||
252 | /* | ||
253 | * IRQs on the Malta board look basically (barring software IRQs which we | ||
254 | * don't use at all and all external interrupt sources are combined together | ||
255 | * on hardware interrupt 0 (MIPS IRQ 2)) like: | ||
256 | * | ||
257 | * MIPS IRQ Source | ||
258 | * -------- ------ | ||
259 | * 0 Software (ignored) | ||
260 | * 1 Software (ignored) | ||
261 | * 2 Combined hardware interrupt (hw0) | ||
262 | * 3 Hardware (ignored) | ||
263 | * 4 Hardware (ignored) | ||
264 | * 5 Hardware (ignored) | ||
265 | * 6 Hardware (ignored) | ||
266 | * 7 R4k timer (what we use) | ||
267 | * | ||
268 | * We handle the IRQ according to _our_ priority which is: | ||
269 | * | ||
270 | * Highest ---- R4k Timer | ||
271 | * Lowest ---- Combined hardware interrupt | ||
272 | * | ||
273 | * then we just return, if multiple IRQs are pending then we will just take | ||
274 | * another exception, big deal. | ||
275 | */ | ||
276 | |||
277 | asmlinkage void plat_irq_dispatch(void) | ||
278 | { | 188 | { |
279 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; | 189 | corehi_irqdispatch(); |
280 | int irq; | 190 | return IRQ_HANDLED; |
281 | |||
282 | if (unlikely(!pending)) { | ||
283 | spurious_interrupt(); | ||
284 | return; | ||
285 | } | ||
286 | |||
287 | irq = irq_ffs(pending); | ||
288 | |||
289 | if (irq == MIPSCPU_INT_I8259A) | ||
290 | malta_hw0_irqdispatch(); | ||
291 | else if (gic_present && ((1 << irq) & ipi_map[smp_processor_id()])) | ||
292 | malta_ipi_irqdispatch(); | ||
293 | else | ||
294 | do_IRQ(MIPS_CPU_IRQ_BASE + irq); | ||
295 | } | 191 | } |
296 | 192 | ||
297 | #ifdef CONFIG_MIPS_MT_SMP | 193 | #ifdef CONFIG_MIPS_MT_SMP |
@@ -312,13 +208,6 @@ static void ipi_call_dispatch(void) | |||
312 | do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ); | 208 | do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ); |
313 | } | 209 | } |
314 | 210 | ||
315 | #endif /* CONFIG_MIPS_MT_SMP */ | ||
316 | |||
317 | #ifdef CONFIG_MIPS_GIC_IPI | ||
318 | |||
319 | #define GIC_MIPS_CPU_IPI_RESCHED_IRQ 3 | ||
320 | #define GIC_MIPS_CPU_IPI_CALL_IRQ 4 | ||
321 | |||
322 | static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) | 211 | static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) |
323 | { | 212 | { |
324 | #ifdef CONFIG_MIPS_VPE_APSP_API_CMP | 213 | #ifdef CONFIG_MIPS_VPE_APSP_API_CMP |
@@ -349,31 +238,16 @@ static struct irqaction irq_call = { | |||
349 | .flags = IRQF_PERCPU, | 238 | .flags = IRQF_PERCPU, |
350 | .name = "IPI_call" | 239 | .name = "IPI_call" |
351 | }; | 240 | }; |
352 | #endif /* CONFIG_MIPS_GIC_IPI */ | 241 | #endif /* CONFIG_MIPS_MT_SMP */ |
353 | |||
354 | static int gic_resched_int_base; | ||
355 | static int gic_call_int_base; | ||
356 | #define GIC_RESCHED_INT(cpu) (gic_resched_int_base+(cpu)) | ||
357 | #define GIC_CALL_INT(cpu) (gic_call_int_base+(cpu)) | ||
358 | |||
359 | unsigned int plat_ipi_call_int_xlate(unsigned int cpu) | ||
360 | { | ||
361 | return GIC_CALL_INT(cpu); | ||
362 | } | ||
363 | |||
364 | unsigned int plat_ipi_resched_int_xlate(unsigned int cpu) | ||
365 | { | ||
366 | return GIC_RESCHED_INT(cpu); | ||
367 | } | ||
368 | 242 | ||
369 | static struct irqaction i8259irq = { | 243 | static struct irqaction i8259irq = { |
370 | .handler = no_action, | 244 | .handler = i8259_handler, |
371 | .name = "XT-PIC cascade", | 245 | .name = "XT-PIC cascade", |
372 | .flags = IRQF_NO_THREAD, | 246 | .flags = IRQF_NO_THREAD, |
373 | }; | 247 | }; |
374 | 248 | ||
375 | static struct irqaction corehi_irqaction = { | 249 | static struct irqaction corehi_irqaction = { |
376 | .handler = no_action, | 250 | .handler = corehi_handler, |
377 | .name = "CoreHi", | 251 | .name = "CoreHi", |
378 | .flags = IRQF_NO_THREAD, | 252 | .flags = IRQF_NO_THREAD, |
379 | }; | 253 | }; |
@@ -399,60 +273,6 @@ static msc_irqmap_t msc_eicirqmap[] __initdata = { | |||
399 | 273 | ||
400 | static int msc_nr_eicirqs __initdata = ARRAY_SIZE(msc_eicirqmap); | 274 | static int msc_nr_eicirqs __initdata = ARRAY_SIZE(msc_eicirqmap); |
401 | 275 | ||
402 | /* | ||
403 | * This GIC specific tabular array defines the association between External | ||
404 | * Interrupts and CPUs/Core Interrupts. The nature of the External | ||
405 | * Interrupts is also defined here - polarity/trigger. | ||
406 | */ | ||
407 | |||
408 | #define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK | ||
409 | #define X GIC_UNUSED | ||
410 | |||
411 | static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { | ||
412 | { X, X, X, X, 0 }, | ||
413 | { X, X, X, X, 0 }, | ||
414 | { X, X, X, X, 0 }, | ||
415 | { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
416 | { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
417 | { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
418 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
419 | { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
420 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
421 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
422 | { X, X, X, X, 0 }, | ||
423 | { X, X, X, X, 0 }, | ||
424 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
425 | { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
426 | { 0, GIC_CPU_NMI, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
427 | { X, X, X, X, 0 }, | ||
428 | /* The remainder of this table is initialised by fill_ipi_map */ | ||
429 | }; | ||
430 | #undef X | ||
431 | |||
432 | #ifdef CONFIG_MIPS_GIC_IPI | ||
433 | static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin) | ||
434 | { | ||
435 | int intr = baseintr + cpu; | ||
436 | gic_intr_map[intr].cpunum = cpu; | ||
437 | gic_intr_map[intr].pin = cpupin; | ||
438 | gic_intr_map[intr].polarity = GIC_POL_POS; | ||
439 | gic_intr_map[intr].trigtype = GIC_TRIG_EDGE; | ||
440 | gic_intr_map[intr].flags = 0; | ||
441 | ipi_map[cpu] |= (1 << (cpupin + 2)); | ||
442 | bitmap_set(ipi_ints, intr, 1); | ||
443 | } | ||
444 | |||
445 | static void __init fill_ipi_map(void) | ||
446 | { | ||
447 | int cpu; | ||
448 | |||
449 | for (cpu = 0; cpu < nr_cpu_ids; cpu++) { | ||
450 | fill_ipi_map1(gic_resched_int_base, cpu, GIC_CPU_INT1); | ||
451 | fill_ipi_map1(gic_call_int_base, cpu, GIC_CPU_INT2); | ||
452 | } | ||
453 | } | ||
454 | #endif | ||
455 | |||
456 | void __init arch_init_ipiirq(int irq, struct irqaction *action) | 276 | void __init arch_init_ipiirq(int irq, struct irqaction *action) |
457 | { | 277 | { |
458 | setup_irq(irq, action); | 278 | setup_irq(irq, action); |
@@ -461,6 +281,8 @@ void __init arch_init_ipiirq(int irq, struct irqaction *action) | |||
461 | 281 | ||
462 | void __init arch_init_irq(void) | 282 | void __init arch_init_irq(void) |
463 | { | 283 | { |
284 | int corehi_irq, i8259_irq; | ||
285 | |||
464 | init_i8259_irqs(); | 286 | init_i8259_irqs(); |
465 | 287 | ||
466 | if (!cpu_has_veic) | 288 | if (!cpu_has_veic) |
@@ -471,12 +293,12 @@ void __init arch_init_irq(void) | |||
471 | gic_present = 1; | 293 | gic_present = 1; |
472 | } else { | 294 | } else { |
473 | if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) { | 295 | if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) { |
474 | _msc01_biu_base = (unsigned long) | 296 | _msc01_biu_base = ioremap_nocache(MSC01_BIU_REG_BASE, |
475 | ioremap_nocache(MSC01_BIU_REG_BASE, | ||
476 | MSC01_BIU_ADDRSPACE_SZ); | 297 | MSC01_BIU_ADDRSPACE_SZ); |
477 | gic_present = (REG(_msc01_biu_base, MSC01_SC_CFG) & | 298 | gic_present = |
478 | MSC01_SC_CFG_GICPRES_MSK) >> | 299 | (__raw_readl(_msc01_biu_base + MSC01_SC_CFG_OFS) & |
479 | MSC01_SC_CFG_GICPRES_SHF; | 300 | MSC01_SC_CFG_GICPRES_MSK) >> |
301 | MSC01_SC_CFG_GICPRES_SHF; | ||
480 | } | 302 | } |
481 | } | 303 | } |
482 | if (gic_present) | 304 | if (gic_present) |
@@ -507,63 +329,20 @@ void __init arch_init_irq(void) | |||
507 | msc_nr_irqs); | 329 | msc_nr_irqs); |
508 | } | 330 | } |
509 | 331 | ||
510 | if (cpu_has_veic) { | ||
511 | set_vi_handler(MSC01E_INT_I8259A, malta_hw0_irqdispatch); | ||
512 | set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch); | ||
513 | setup_irq(MSC01E_INT_BASE+MSC01E_INT_I8259A, &i8259irq); | ||
514 | setup_irq(MSC01E_INT_BASE+MSC01E_INT_COREHI, &corehi_irqaction); | ||
515 | } else if (cpu_has_vint) { | ||
516 | set_vi_handler(MIPSCPU_INT_I8259A, malta_hw0_irqdispatch); | ||
517 | set_vi_handler(MIPSCPU_INT_COREHI, corehi_irqdispatch); | ||
518 | setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); | ||
519 | setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, | ||
520 | &corehi_irqaction); | ||
521 | } else { | ||
522 | setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq); | ||
523 | setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI, | ||
524 | &corehi_irqaction); | ||
525 | } | ||
526 | |||
527 | if (gic_present) { | 332 | if (gic_present) { |
528 | /* FIXME */ | ||
529 | int i; | 333 | int i; |
530 | #if defined(CONFIG_MIPS_GIC_IPI) | 334 | |
531 | gic_call_int_base = GIC_NUM_INTRS - | 335 | gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, MIPSCPU_INT_GIC, |
532 | (NR_CPUS - nr_cpu_ids) * 2 - nr_cpu_ids; | 336 | MIPS_GIC_IRQ_BASE); |
533 | gic_resched_int_base = gic_call_int_base - nr_cpu_ids; | ||
534 | fill_ipi_map(); | ||
535 | #endif | ||
536 | gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, | ||
537 | ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); | ||
538 | if (!mips_cm_present()) { | 337 | if (!mips_cm_present()) { |
539 | /* Enable the GIC */ | 338 | /* Enable the GIC */ |
540 | i = REG(_msc01_biu_base, MSC01_SC_CFG); | 339 | i = __raw_readl(_msc01_biu_base + MSC01_SC_CFG_OFS); |
541 | REG(_msc01_biu_base, MSC01_SC_CFG) = | 340 | __raw_writel(i | (0x1 << MSC01_SC_CFG_GICENA_SHF), |
542 | (i | (0x1 << MSC01_SC_CFG_GICENA_SHF)); | 341 | _msc01_biu_base + MSC01_SC_CFG_OFS); |
543 | pr_debug("GIC Enabled\n"); | 342 | pr_debug("GIC Enabled\n"); |
544 | } | 343 | } |
545 | #if defined(CONFIG_MIPS_GIC_IPI) | 344 | i8259_irq = MIPS_GIC_IRQ_BASE + GIC_INT_I8259A; |
546 | /* set up ipi interrupts */ | 345 | corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI; |
547 | if (cpu_has_vint) { | ||
548 | set_vi_handler(MIPSCPU_INT_IPI0, malta_ipi_irqdispatch); | ||
549 | set_vi_handler(MIPSCPU_INT_IPI1, malta_ipi_irqdispatch); | ||
550 | } | ||
551 | /* Argh.. this really needs sorting out.. */ | ||
552 | pr_info("CPU%d: status register was %08x\n", | ||
553 | smp_processor_id(), read_c0_status()); | ||
554 | write_c0_status(read_c0_status() | STATUSF_IP3 | STATUSF_IP4); | ||
555 | pr_info("CPU%d: status register now %08x\n", | ||
556 | smp_processor_id(), read_c0_status()); | ||
557 | write_c0_status(0x1100dc00); | ||
558 | pr_info("CPU%d: status register frc %08x\n", | ||
559 | smp_processor_id(), read_c0_status()); | ||
560 | for (i = 0; i < nr_cpu_ids; i++) { | ||
561 | arch_init_ipiirq(MIPS_GIC_IRQ_BASE + | ||
562 | GIC_RESCHED_INT(i), &irq_resched); | ||
563 | arch_init_ipiirq(MIPS_GIC_IRQ_BASE + | ||
564 | GIC_CALL_INT(i), &irq_call); | ||
565 | } | ||
566 | #endif | ||
567 | } else { | 346 | } else { |
568 | #if defined(CONFIG_MIPS_MT_SMP) | 347 | #if defined(CONFIG_MIPS_MT_SMP) |
569 | /* set up ipi interrupts */ | 348 | /* set up ipi interrupts */ |
@@ -573,12 +352,6 @@ void __init arch_init_irq(void) | |||
573 | cpu_ipi_resched_irq = MSC01E_INT_SW0; | 352 | cpu_ipi_resched_irq = MSC01E_INT_SW0; |
574 | cpu_ipi_call_irq = MSC01E_INT_SW1; | 353 | cpu_ipi_call_irq = MSC01E_INT_SW1; |
575 | } else { | 354 | } else { |
576 | if (cpu_has_vint) { | ||
577 | set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, | ||
578 | ipi_resched_dispatch); | ||
579 | set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, | ||
580 | ipi_call_dispatch); | ||
581 | } | ||
582 | cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + | 355 | cpu_ipi_resched_irq = MIPS_CPU_IRQ_BASE + |
583 | MIPS_CPU_IPI_RESCHED_IRQ; | 356 | MIPS_CPU_IPI_RESCHED_IRQ; |
584 | cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + | 357 | cpu_ipi_call_irq = MIPS_CPU_IRQ_BASE + |
@@ -587,7 +360,21 @@ void __init arch_init_irq(void) | |||
587 | arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched); | 360 | arch_init_ipiirq(cpu_ipi_resched_irq, &irq_resched); |
588 | arch_init_ipiirq(cpu_ipi_call_irq, &irq_call); | 361 | arch_init_ipiirq(cpu_ipi_call_irq, &irq_call); |
589 | #endif | 362 | #endif |
363 | if (cpu_has_veic) { | ||
364 | set_vi_handler(MSC01E_INT_I8259A, | ||
365 | malta_hw0_irqdispatch); | ||
366 | set_vi_handler(MSC01E_INT_COREHI, | ||
367 | corehi_irqdispatch); | ||
368 | i8259_irq = MSC01E_INT_BASE + MSC01E_INT_I8259A; | ||
369 | corehi_irq = MSC01E_INT_BASE + MSC01E_INT_COREHI; | ||
370 | } else { | ||
371 | i8259_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_I8259A; | ||
372 | corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI; | ||
373 | } | ||
590 | } | 374 | } |
375 | |||
376 | setup_irq(i8259_irq, &i8259irq); | ||
377 | setup_irq(corehi_irq, &corehi_irqaction); | ||
591 | } | 378 | } |
592 | 379 | ||
593 | void malta_be_init(void) | 380 | void malta_be_init(void) |
@@ -714,37 +501,3 @@ int malta_be_handler(struct pt_regs *regs, int is_fixup) | |||
714 | 501 | ||
715 | return retval; | 502 | return retval; |
716 | } | 503 | } |
717 | |||
718 | void gic_enable_interrupt(int irq_vec) | ||
719 | { | ||
720 | GIC_SET_INTR_MASK(irq_vec); | ||
721 | } | ||
722 | |||
723 | void gic_disable_interrupt(int irq_vec) | ||
724 | { | ||
725 | GIC_CLR_INTR_MASK(irq_vec); | ||
726 | } | ||
727 | |||
728 | void gic_irq_ack(struct irq_data *d) | ||
729 | { | ||
730 | int irq = (d->irq - gic_irq_base); | ||
731 | |||
732 | GIC_CLR_INTR_MASK(irq); | ||
733 | |||
734 | if (gic_irq_flags[irq] & GIC_TRIG_EDGE) | ||
735 | GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq); | ||
736 | } | ||
737 | |||
738 | void gic_finish_irq(struct irq_data *d) | ||
739 | { | ||
740 | /* Enable interrupts. */ | ||
741 | GIC_SET_INTR_MASK(d->irq - gic_irq_base); | ||
742 | } | ||
743 | |||
744 | void __init gic_platform_init(int irqs, struct irq_chip *irq_controller) | ||
745 | { | ||
746 | int i; | ||
747 | |||
748 | for (i = gic_irq_base; i < (gic_irq_base + irqs); i++) | ||
749 | irq_set_chip(i, irq_controller); | ||
750 | } | ||
diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index 3778a359f3ad..ce02dbdedc62 100644 --- a/arch/mips/mti-malta/malta-time.c +++ b/arch/mips/mti-malta/malta-time.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
25 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/irqchip/mips-gic.h> | ||
27 | #include <linux/timex.h> | 28 | #include <linux/timex.h> |
28 | #include <linux/mc146818rtc.h> | 29 | #include <linux/mc146818rtc.h> |
29 | 30 | ||
@@ -37,7 +38,6 @@ | |||
37 | #include <asm/time.h> | 38 | #include <asm/time.h> |
38 | #include <asm/mc146818-time.h> | 39 | #include <asm/mc146818-time.h> |
39 | #include <asm/msc01_ic.h> | 40 | #include <asm/msc01_ic.h> |
40 | #include <asm/gic.h> | ||
41 | 41 | ||
42 | #include <asm/mips-boards/generic.h> | 42 | #include <asm/mips-boards/generic.h> |
43 | #include <asm/mips-boards/maltaint.h> | 43 | #include <asm/mips-boards/maltaint.h> |
@@ -46,6 +46,8 @@ static int mips_cpu_timer_irq; | |||
46 | static int mips_cpu_perf_irq; | 46 | static int mips_cpu_perf_irq; |
47 | extern int cp0_perfcount_irq; | 47 | extern int cp0_perfcount_irq; |
48 | 48 | ||
49 | static unsigned int gic_frequency; | ||
50 | |||
49 | static void mips_timer_dispatch(void) | 51 | static void mips_timer_dispatch(void) |
50 | { | 52 | { |
51 | do_IRQ(mips_cpu_timer_irq); | 53 | do_IRQ(mips_cpu_timer_irq); |
@@ -70,9 +72,7 @@ static void __init estimate_frequencies(void) | |||
70 | { | 72 | { |
71 | unsigned long flags; | 73 | unsigned long flags; |
72 | unsigned int count, start; | 74 | unsigned int count, start; |
73 | #ifdef CONFIG_IRQ_GIC | 75 | cycle_t giccount = 0, gicstart = 0; |
74 | unsigned int giccount = 0, gicstart = 0; | ||
75 | #endif | ||
76 | 76 | ||
77 | #if defined(CONFIG_KVM_GUEST) && CONFIG_KVM_GUEST_TIMER_FREQ | 77 | #if defined(CONFIG_KVM_GUEST) && CONFIG_KVM_GUEST_TIMER_FREQ |
78 | mips_hpt_frequency = CONFIG_KVM_GUEST_TIMER_FREQ * 1000000; | 78 | mips_hpt_frequency = CONFIG_KVM_GUEST_TIMER_FREQ * 1000000; |
@@ -87,32 +87,26 @@ static void __init estimate_frequencies(void) | |||
87 | 87 | ||
88 | /* Initialize counters. */ | 88 | /* Initialize counters. */ |
89 | start = read_c0_count(); | 89 | start = read_c0_count(); |
90 | #ifdef CONFIG_IRQ_GIC | ||
91 | if (gic_present) | 90 | if (gic_present) |
92 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), gicstart); | 91 | gicstart = gic_read_count(); |
93 | #endif | ||
94 | 92 | ||
95 | /* Read counter exactly on falling edge of update flag. */ | 93 | /* Read counter exactly on falling edge of update flag. */ |
96 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); | 94 | while (CMOS_READ(RTC_REG_A) & RTC_UIP); |
97 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); | 95 | while (!(CMOS_READ(RTC_REG_A) & RTC_UIP)); |
98 | 96 | ||
99 | count = read_c0_count(); | 97 | count = read_c0_count(); |
100 | #ifdef CONFIG_IRQ_GIC | ||
101 | if (gic_present) | 98 | if (gic_present) |
102 | GICREAD(GIC_REG(SHARED, GIC_SH_COUNTER_31_00), giccount); | 99 | giccount = gic_read_count(); |
103 | #endif | ||
104 | 100 | ||
105 | local_irq_restore(flags); | 101 | local_irq_restore(flags); |
106 | 102 | ||
107 | count -= start; | 103 | count -= start; |
108 | mips_hpt_frequency = count; | 104 | mips_hpt_frequency = count; |
109 | 105 | ||
110 | #ifdef CONFIG_IRQ_GIC | ||
111 | if (gic_present) { | 106 | if (gic_present) { |
112 | giccount -= gicstart; | 107 | giccount -= gicstart; |
113 | gic_frequency = giccount; | 108 | gic_frequency = giccount; |
114 | } | 109 | } |
115 | #endif | ||
116 | } | 110 | } |
117 | 111 | ||
118 | void read_persistent_clock(struct timespec *ts) | 112 | void read_persistent_clock(struct timespec *ts) |
@@ -121,35 +115,30 @@ void read_persistent_clock(struct timespec *ts) | |||
121 | ts->tv_nsec = 0; | 115 | ts->tv_nsec = 0; |
122 | } | 116 | } |
123 | 117 | ||
124 | static void __init plat_perf_setup(void) | 118 | int get_c0_perfcount_int(void) |
125 | { | 119 | { |
126 | #ifdef MSC01E_INT_BASE | ||
127 | if (cpu_has_veic) { | 120 | if (cpu_has_veic) { |
128 | set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch); | 121 | set_vi_handler(MSC01E_INT_PERFCTR, mips_perf_dispatch); |
129 | mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; | 122 | mips_cpu_perf_irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; |
130 | } else | 123 | } else if (gic_present) { |
131 | #endif | 124 | mips_cpu_perf_irq = gic_get_c0_perfcount_int(); |
132 | if (cp0_perfcount_irq >= 0) { | 125 | } else if (cp0_perfcount_irq >= 0) { |
133 | if (cpu_has_vint) | ||
134 | set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch); | ||
135 | mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; | 126 | mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; |
136 | #ifdef CONFIG_SMP | 127 | } else { |
137 | irq_set_handler(mips_cpu_perf_irq, handle_percpu_irq); | 128 | mips_cpu_perf_irq = -1; |
138 | #endif | ||
139 | } | 129 | } |
130 | |||
131 | return mips_cpu_perf_irq; | ||
140 | } | 132 | } |
141 | 133 | ||
142 | unsigned int get_c0_compare_int(void) | 134 | unsigned int get_c0_compare_int(void) |
143 | { | 135 | { |
144 | #ifdef MSC01E_INT_BASE | ||
145 | if (cpu_has_veic) { | 136 | if (cpu_has_veic) { |
146 | set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); | 137 | set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch); |
147 | mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; | 138 | mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR; |
148 | } else | 139 | } else if (gic_present) { |
149 | #endif | 140 | mips_cpu_timer_irq = gic_get_c0_compare_int(); |
150 | { | 141 | } else { |
151 | if (cpu_has_vint) | ||
152 | set_vi_handler(cp0_compare_irq, mips_timer_dispatch); | ||
153 | mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; | 142 | mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; |
154 | } | 143 | } |
155 | 144 | ||
@@ -191,16 +180,14 @@ void __init plat_time_init(void) | |||
191 | setup_pit_timer(); | 180 | setup_pit_timer(); |
192 | #endif | 181 | #endif |
193 | 182 | ||
194 | #ifdef CONFIG_IRQ_GIC | 183 | #ifdef CONFIG_MIPS_GIC |
195 | if (gic_present) { | 184 | if (gic_present) { |
196 | freq = freqround(gic_frequency, 5000); | 185 | freq = freqround(gic_frequency, 5000); |
197 | printk("GIC frequency %d.%02d MHz\n", freq/1000000, | 186 | printk("GIC frequency %d.%02d MHz\n", freq/1000000, |
198 | (freq%1000000)*100/1000000); | 187 | (freq%1000000)*100/1000000); |
199 | #ifdef CONFIG_CSRC_GIC | 188 | #ifdef CONFIG_CLKSRC_MIPS_GIC |
200 | gic_clocksource_init(gic_frequency); | 189 | gic_clocksource_init(gic_frequency); |
201 | #endif | 190 | #endif |
202 | } | 191 | } |
203 | #endif | 192 | #endif |
204 | |||
205 | plat_perf_setup(); | ||
206 | } | 193 | } |
diff --git a/arch/mips/mti-sead3/sead3-ehci.c b/arch/mips/mti-sead3/sead3-ehci.c index 772fc056a92d..014dd7ba4d68 100644 --- a/arch/mips/mti-sead3/sead3-ehci.c +++ b/arch/mips/mti-sead3/sead3-ehci.c | |||
@@ -9,6 +9,9 @@ | |||
9 | #include <linux/irq.h> | 9 | #include <linux/irq.h> |
10 | #include <linux/dma-mapping.h> | 10 | #include <linux/dma-mapping.h> |
11 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
12 | #include <linux/irqchip/mips-gic.h> | ||
13 | |||
14 | #include <asm/mips-boards/sead3int.h> | ||
12 | 15 | ||
13 | struct resource ehci_resources[] = { | 16 | struct resource ehci_resources[] = { |
14 | { | 17 | { |
@@ -17,7 +20,6 @@ struct resource ehci_resources[] = { | |||
17 | .flags = IORESOURCE_MEM | 20 | .flags = IORESOURCE_MEM |
18 | }, | 21 | }, |
19 | { | 22 | { |
20 | .start = MIPS_CPU_IRQ_BASE + 2, | ||
21 | .flags = IORESOURCE_IRQ | 23 | .flags = IORESOURCE_IRQ |
22 | } | 24 | } |
23 | }; | 25 | }; |
@@ -37,6 +39,10 @@ static struct platform_device ehci_device = { | |||
37 | 39 | ||
38 | static int __init ehci_init(void) | 40 | static int __init ehci_init(void) |
39 | { | 41 | { |
42 | if (gic_present) | ||
43 | ehci_resources[1].start = MIPS_GIC_IRQ_BASE + GIC_INT_EHCI; | ||
44 | else | ||
45 | ehci_resources[1].start = MIPS_CPU_IRQ_BASE + CPU_INT_EHCI; | ||
40 | return platform_device_register(&ehci_device); | 46 | return platform_device_register(&ehci_device); |
41 | } | 47 | } |
42 | 48 | ||
diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c index 6a560ac03def..e31e17f81eef 100644 --- a/arch/mips/mti-sead3/sead3-int.c +++ b/arch/mips/mti-sead3/sead3-int.c | |||
@@ -7,9 +7,9 @@ | |||
7 | */ | 7 | */ |
8 | #include <linux/init.h> | 8 | #include <linux/init.h> |
9 | #include <linux/irq.h> | 9 | #include <linux/irq.h> |
10 | #include <linux/irqchip/mips-gic.h> | ||
10 | #include <linux/io.h> | 11 | #include <linux/io.h> |
11 | 12 | ||
12 | #include <asm/gic.h> | ||
13 | #include <asm/irq_cpu.h> | 13 | #include <asm/irq_cpu.h> |
14 | #include <asm/setup.h> | 14 | #include <asm/setup.h> |
15 | 15 | ||
@@ -20,138 +20,23 @@ | |||
20 | #define SEAD_CONFIG_BASE 0x1b100110 | 20 | #define SEAD_CONFIG_BASE 0x1b100110 |
21 | #define SEAD_CONFIG_SIZE 4 | 21 | #define SEAD_CONFIG_SIZE 4 |
22 | 22 | ||
23 | static unsigned long sead3_config_reg; | 23 | static void __iomem *sead3_config_reg; |
24 | |||
25 | /* | ||
26 | * This table defines the setup for each external GIC interrupt. It is | ||
27 | * indexed by interrupt number. | ||
28 | */ | ||
29 | #define GIC_CPU_NMI GIC_MAP_TO_NMI_MSK | ||
30 | static struct gic_intr_map gic_intr_map[GIC_NUM_INTRS] = { | ||
31 | { 0, GIC_CPU_INT4, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
32 | { 0, GIC_CPU_INT3, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
33 | { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
34 | { 0, GIC_CPU_INT2, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
35 | { 0, GIC_CPU_INT1, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
36 | { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
37 | { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
38 | { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
39 | { 0, GIC_CPU_INT0, GIC_POL_POS, GIC_TRIG_LEVEL, GIC_FLAG_TRANSPARENT }, | ||
40 | { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED }, | ||
41 | { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED }, | ||
42 | { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED }, | ||
43 | { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED }, | ||
44 | { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED }, | ||
45 | { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED }, | ||
46 | { GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED, GIC_UNUSED }, | ||
47 | }; | ||
48 | |||
49 | asmlinkage void plat_irq_dispatch(void) | ||
50 | { | ||
51 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; | ||
52 | int irq; | ||
53 | |||
54 | irq = (fls(pending) - CAUSEB_IP - 1); | ||
55 | if (irq >= 0) | ||
56 | do_IRQ(MIPS_CPU_IRQ_BASE + irq); | ||
57 | else | ||
58 | spurious_interrupt(); | ||
59 | } | ||
60 | 24 | ||
61 | void __init arch_init_irq(void) | 25 | void __init arch_init_irq(void) |
62 | { | 26 | { |
63 | int i; | 27 | if (!cpu_has_veic) |
64 | |||
65 | if (!cpu_has_veic) { | ||
66 | mips_cpu_irq_init(); | 28 | mips_cpu_irq_init(); |
67 | 29 | ||
68 | if (cpu_has_vint) { | 30 | sead3_config_reg = ioremap_nocache(SEAD_CONFIG_BASE, SEAD_CONFIG_SIZE); |
69 | /* install generic handler */ | 31 | gic_present = (__raw_readl(sead3_config_reg) & |
70 | for (i = 0; i < 8; i++) | 32 | SEAD_CONFIG_GIC_PRESENT_MSK) >> |
71 | set_vi_handler(i, plat_irq_dispatch); | ||
72 | } | ||
73 | } | ||
74 | |||
75 | sead3_config_reg = (unsigned long)ioremap_nocache(SEAD_CONFIG_BASE, | ||
76 | SEAD_CONFIG_SIZE); | ||
77 | gic_present = (REG32(sead3_config_reg) & SEAD_CONFIG_GIC_PRESENT_MSK) >> | ||
78 | SEAD_CONFIG_GIC_PRESENT_SHF; | 33 | SEAD_CONFIG_GIC_PRESENT_SHF; |
79 | pr_info("GIC: %spresent\n", (gic_present) ? "" : "not "); | 34 | pr_info("GIC: %spresent\n", (gic_present) ? "" : "not "); |
80 | pr_info("EIC: %s\n", | 35 | pr_info("EIC: %s\n", |
81 | (current_cpu_data.options & MIPS_CPU_VEIC) ? "on" : "off"); | 36 | (current_cpu_data.options & MIPS_CPU_VEIC) ? "on" : "off"); |
82 | 37 | ||
83 | if (gic_present) | 38 | if (gic_present) |
84 | gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, gic_intr_map, | 39 | gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, CPU_INT_GIC, |
85 | ARRAY_SIZE(gic_intr_map), MIPS_GIC_IRQ_BASE); | 40 | MIPS_GIC_IRQ_BASE); |
86 | } | ||
87 | |||
88 | void gic_enable_interrupt(int irq_vec) | ||
89 | { | ||
90 | unsigned int i, irq_source; | ||
91 | |||
92 | /* enable all the interrupts associated with this vector */ | ||
93 | for (i = 0; i < gic_shared_intr_map[irq_vec].num_shared_intr; i++) { | ||
94 | irq_source = gic_shared_intr_map[irq_vec].intr_list[i]; | ||
95 | GIC_SET_INTR_MASK(irq_source); | ||
96 | } | ||
97 | /* enable all local interrupts associated with this vector */ | ||
98 | if (gic_shared_intr_map[irq_vec].local_intr_mask) { | ||
99 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0); | ||
100 | GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_SMASK), | ||
101 | gic_shared_intr_map[irq_vec].local_intr_mask); | ||
102 | } | ||
103 | } | 41 | } |
104 | 42 | ||
105 | void gic_disable_interrupt(int irq_vec) | ||
106 | { | ||
107 | unsigned int i, irq_source; | ||
108 | |||
109 | /* disable all the interrupts associated with this vector */ | ||
110 | for (i = 0; i < gic_shared_intr_map[irq_vec].num_shared_intr; i++) { | ||
111 | irq_source = gic_shared_intr_map[irq_vec].intr_list[i]; | ||
112 | GIC_CLR_INTR_MASK(irq_source); | ||
113 | } | ||
114 | /* disable all local interrupts associated with this vector */ | ||
115 | if (gic_shared_intr_map[irq_vec].local_intr_mask) { | ||
116 | GICWRITE(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), 0); | ||
117 | GICWRITE(GIC_REG(VPE_OTHER, GIC_VPE_RMASK), | ||
118 | gic_shared_intr_map[irq_vec].local_intr_mask); | ||
119 | } | ||
120 | } | ||
121 | |||
122 | void gic_irq_ack(struct irq_data *d) | ||
123 | { | ||
124 | GIC_CLR_INTR_MASK(d->irq - gic_irq_base); | ||
125 | } | ||
126 | |||
127 | void gic_finish_irq(struct irq_data *d) | ||
128 | { | ||
129 | unsigned int irq = (d->irq - gic_irq_base); | ||
130 | unsigned int i, irq_source; | ||
131 | |||
132 | /* Clear edge detectors. */ | ||
133 | for (i = 0; i < gic_shared_intr_map[irq].num_shared_intr; i++) { | ||
134 | irq_source = gic_shared_intr_map[irq].intr_list[i]; | ||
135 | if (gic_irq_flags[irq_source] & GIC_TRIG_EDGE) | ||
136 | GICWRITE(GIC_REG(SHARED, GIC_SH_WEDGE), irq_source); | ||
137 | } | ||
138 | |||
139 | /* Enable interrupts. */ | ||
140 | GIC_SET_INTR_MASK(irq); | ||
141 | } | ||
142 | |||
143 | void __init gic_platform_init(int irqs, struct irq_chip *irq_controller) | ||
144 | { | ||
145 | int i; | ||
146 | |||
147 | /* | ||
148 | * For non-EIC mode, we want to setup the GIC in pass-through | ||
149 | * mode, as if the GIC didn't exist. Do not map any interrupts | ||
150 | * for an external interrupt controller. | ||
151 | */ | ||
152 | if (!cpu_has_veic) | ||
153 | return; | ||
154 | |||
155 | for (i = gic_irq_base; i < (gic_irq_base + irqs); i++) | ||
156 | irq_set_chip_and_handler(i, irq_controller, handle_percpu_irq); | ||
157 | } | ||
diff --git a/arch/mips/mti-sead3/sead3-net.c b/arch/mips/mti-sead3/sead3-net.c index dd11e7eb771c..46176b804576 100644 --- a/arch/mips/mti-sead3/sead3-net.c +++ b/arch/mips/mti-sead3/sead3-net.c | |||
@@ -7,9 +7,12 @@ | |||
7 | */ | 7 | */ |
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/irq.h> | 9 | #include <linux/irq.h> |
10 | #include <linux/irqchip/mips-gic.h> | ||
10 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
11 | #include <linux/smsc911x.h> | 12 | #include <linux/smsc911x.h> |
12 | 13 | ||
14 | #include <asm/mips-boards/sead3int.h> | ||
15 | |||
13 | static struct smsc911x_platform_config sead3_smsc911x_data = { | 16 | static struct smsc911x_platform_config sead3_smsc911x_data = { |
14 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, | 17 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, |
15 | .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, | 18 | .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, |
@@ -17,14 +20,13 @@ static struct smsc911x_platform_config sead3_smsc911x_data = { | |||
17 | .phy_interface = PHY_INTERFACE_MODE_MII, | 20 | .phy_interface = PHY_INTERFACE_MODE_MII, |
18 | }; | 21 | }; |
19 | 22 | ||
20 | struct resource sead3_net_resourcess[] = { | 23 | struct resource sead3_net_resources[] = { |
21 | { | 24 | { |
22 | .start = 0x1f010000, | 25 | .start = 0x1f010000, |
23 | .end = 0x1f01ffff, | 26 | .end = 0x1f01ffff, |
24 | .flags = IORESOURCE_MEM | 27 | .flags = IORESOURCE_MEM |
25 | }, | 28 | }, |
26 | { | 29 | { |
27 | .start = MIPS_CPU_IRQ_BASE + 6, | ||
28 | .flags = IORESOURCE_IRQ | 30 | .flags = IORESOURCE_IRQ |
29 | } | 31 | } |
30 | }; | 32 | }; |
@@ -35,12 +37,16 @@ static struct platform_device sead3_net_device = { | |||
35 | .dev = { | 37 | .dev = { |
36 | .platform_data = &sead3_smsc911x_data, | 38 | .platform_data = &sead3_smsc911x_data, |
37 | }, | 39 | }, |
38 | .num_resources = ARRAY_SIZE(sead3_net_resourcess), | 40 | .num_resources = ARRAY_SIZE(sead3_net_resources), |
39 | .resource = sead3_net_resourcess | 41 | .resource = sead3_net_resources |
40 | }; | 42 | }; |
41 | 43 | ||
42 | static int __init sead3_net_init(void) | 44 | static int __init sead3_net_init(void) |
43 | { | 45 | { |
46 | if (gic_present) | ||
47 | sead3_net_resources[1].start = MIPS_GIC_IRQ_BASE + GIC_INT_NET; | ||
48 | else | ||
49 | sead3_net_resources[1].start = MIPS_CPU_IRQ_BASE + CPU_INT_NET; | ||
44 | return platform_device_register(&sead3_net_device); | 50 | return platform_device_register(&sead3_net_device); |
45 | } | 51 | } |
46 | 52 | ||
diff --git a/arch/mips/mti-sead3/sead3-platform.c b/arch/mips/mti-sead3/sead3-platform.c index 6c3b33dbed18..53ee6f1f018d 100644 --- a/arch/mips/mti-sead3/sead3-platform.c +++ b/arch/mips/mti-sead3/sead3-platform.c | |||
@@ -7,12 +7,15 @@ | |||
7 | */ | 7 | */ |
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/irqchip/mips-gic.h> | ||
10 | #include <linux/serial_8250.h> | 11 | #include <linux/serial_8250.h> |
11 | 12 | ||
12 | #define UART(base, int) \ | 13 | #include <asm/mips-boards/sead3int.h> |
14 | |||
15 | #define UART(base) \ | ||
13 | { \ | 16 | { \ |
14 | .mapbase = base, \ | 17 | .mapbase = base, \ |
15 | .irq = int, \ | 18 | .irq = -1, \ |
16 | .uartclk = 14745600, \ | 19 | .uartclk = 14745600, \ |
17 | .iotype = UPIO_MEM32, \ | 20 | .iotype = UPIO_MEM32, \ |
18 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \ | 21 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \ |
@@ -20,8 +23,8 @@ | |||
20 | } | 23 | } |
21 | 24 | ||
22 | static struct plat_serial8250_port uart8250_data[] = { | 25 | static struct plat_serial8250_port uart8250_data[] = { |
23 | UART(0x1f000900, MIPS_CPU_IRQ_BASE + 4), /* ttyS0 = USB */ | 26 | UART(0x1f000900), /* ttyS0 = USB */ |
24 | UART(0x1f000800, MIPS_CPU_IRQ_BASE + 4), /* ttyS1 = RS232 */ | 27 | UART(0x1f000800), /* ttyS1 = RS232 */ |
25 | { }, | 28 | { }, |
26 | }; | 29 | }; |
27 | 30 | ||
@@ -35,6 +38,13 @@ static struct platform_device uart8250_device = { | |||
35 | 38 | ||
36 | static int __init uart8250_init(void) | 39 | static int __init uart8250_init(void) |
37 | { | 40 | { |
41 | if (gic_present) { | ||
42 | uart8250_data[0].irq = MIPS_GIC_IRQ_BASE + GIC_INT_UART0; | ||
43 | uart8250_data[1].irq = MIPS_GIC_IRQ_BASE + GIC_INT_UART1; | ||
44 | } else { | ||
45 | uart8250_data[0].irq = MIPS_CPU_IRQ_BASE + CPU_INT_UART0; | ||
46 | uart8250_data[1].irq = MIPS_CPU_IRQ_BASE + CPU_INT_UART1; | ||
47 | } | ||
38 | return platform_device_register(&uart8250_device); | 48 | return platform_device_register(&uart8250_device); |
39 | } | 49 | } |
40 | 50 | ||
diff --git a/arch/mips/mti-sead3/sead3-serial.c b/arch/mips/mti-sead3/sead3-serial.c deleted file mode 100644 index bc52705bbee4..000000000000 --- a/arch/mips/mti-sead3/sead3-serial.c +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. | ||
7 | */ | ||
8 | #include <linux/module.h> | ||
9 | #include <linux/init.h> | ||
10 | #include <linux/serial_8250.h> | ||
11 | |||
12 | #define UART(base, int) \ | ||
13 | { \ | ||
14 | .mapbase = base, \ | ||
15 | .irq = int, \ | ||
16 | .uartclk = 14745600, \ | ||
17 | .iotype = UPIO_MEM32, \ | ||
18 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \ | ||
19 | .regshift = 2, \ | ||
20 | } | ||
21 | |||
22 | static struct plat_serial8250_port uart8250_data[] = { | ||
23 | UART(0x1f000900, MIPS_CPU_IRQ_BASE + 4), /* ttyS0 = USB */ | ||
24 | UART(0x1f000800, MIPS_CPU_IRQ_BASE + 4), /* ttyS1 = RS232 */ | ||
25 | { }, | ||
26 | }; | ||
27 | |||
28 | static struct platform_device uart8250_device = { | ||
29 | .name = "serial8250", | ||
30 | .id = PLAT8250_DEV_PLATFORM, | ||
31 | .dev = { | ||
32 | .platform_data = uart8250_data, | ||
33 | }, | ||
34 | }; | ||
35 | |||
36 | static int __init uart8250_init(void) | ||
37 | { | ||
38 | return platform_device_register(&uart8250_device); | ||
39 | } | ||
40 | |||
41 | module_init(uart8250_init); | ||
42 | |||
43 | MODULE_AUTHOR("Chris Dearman <chris@mips.com>"); | ||
44 | MODULE_LICENSE("GPL"); | ||
45 | MODULE_DESCRIPTION("8250 UART probe driver for the SEAD-3 platform"); | ||
diff --git a/arch/mips/mti-sead3/sead3-time.c b/arch/mips/mti-sead3/sead3-time.c index 678d03d53c60..ec1dd2491f96 100644 --- a/arch/mips/mti-sead3/sead3-time.c +++ b/arch/mips/mti-sead3/sead3-time.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. | 6 | * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. |
7 | */ | 7 | */ |
8 | #include <linux/init.h> | 8 | #include <linux/init.h> |
9 | #include <linux/irqchip/mips-gic.h> | ||
9 | 10 | ||
10 | #include <asm/cpu.h> | 11 | #include <asm/cpu.h> |
11 | #include <asm/setup.h> | 12 | #include <asm/setup.h> |
@@ -13,19 +14,6 @@ | |||
13 | #include <asm/irq.h> | 14 | #include <asm/irq.h> |
14 | #include <asm/mips-boards/generic.h> | 15 | #include <asm/mips-boards/generic.h> |
15 | 16 | ||
16 | static int mips_cpu_timer_irq; | ||
17 | static int mips_cpu_perf_irq; | ||
18 | |||
19 | static void mips_timer_dispatch(void) | ||
20 | { | ||
21 | do_IRQ(mips_cpu_timer_irq); | ||
22 | } | ||
23 | |||
24 | static void mips_perf_dispatch(void) | ||
25 | { | ||
26 | do_IRQ(mips_cpu_perf_irq); | ||
27 | } | ||
28 | |||
29 | static void __iomem *status_reg = (void __iomem *)0xbf000410; | 17 | static void __iomem *status_reg = (void __iomem *)0xbf000410; |
30 | 18 | ||
31 | /* | 19 | /* |
@@ -81,21 +69,20 @@ void read_persistent_clock(struct timespec *ts) | |||
81 | ts->tv_nsec = 0; | 69 | ts->tv_nsec = 0; |
82 | } | 70 | } |
83 | 71 | ||
84 | static void __init plat_perf_setup(void) | 72 | int get_c0_perfcount_int(void) |
85 | { | 73 | { |
86 | if (cp0_perfcount_irq >= 0) { | 74 | if (gic_present) |
87 | if (cpu_has_vint) | 75 | return gic_get_c0_compare_int(); |
88 | set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch); | 76 | if (cp0_perfcount_irq >= 0) |
89 | mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; | 77 | return MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; |
90 | } | 78 | return -1; |
91 | } | 79 | } |
92 | 80 | ||
93 | unsigned int get_c0_compare_int(void) | 81 | unsigned int get_c0_compare_int(void) |
94 | { | 82 | { |
95 | if (cpu_has_vint) | 83 | if (gic_present) |
96 | set_vi_handler(cp0_compare_irq, mips_timer_dispatch); | 84 | return gic_get_c0_compare_int(); |
97 | mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; | 85 | return MIPS_CPU_IRQ_BASE + cp0_compare_irq; |
98 | return mips_cpu_timer_irq; | ||
99 | } | 86 | } |
100 | 87 | ||
101 | void __init plat_time_init(void) | 88 | void __init plat_time_init(void) |
@@ -108,6 +95,4 @@ void __init plat_time_init(void) | |||
108 | (est_freq % 1000000) * 100 / 1000000); | 95 | (est_freq % 1000000) * 100 / 1000000); |
109 | 96 | ||
110 | mips_scroll_message(); | 97 | mips_scroll_message(); |
111 | |||
112 | plat_perf_setup(); | ||
113 | } | 98 | } |
diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile index 9c0a6782c091..070afdb297df 100644 --- a/arch/mips/oprofile/Makefile +++ b/arch/mips/oprofile/Makefile | |||
@@ -14,3 +14,4 @@ oprofile-$(CONFIG_CPU_R10000) += op_model_mipsxx.o | |||
14 | oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o | 14 | oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o |
15 | oprofile-$(CONFIG_CPU_XLR) += op_model_mipsxx.o | 15 | oprofile-$(CONFIG_CPU_XLR) += op_model_mipsxx.o |
16 | oprofile-$(CONFIG_CPU_LOONGSON2) += op_model_loongson2.o | 16 | oprofile-$(CONFIG_CPU_LOONGSON2) += op_model_loongson2.o |
17 | oprofile-$(CONFIG_CPU_LOONGSON3) += op_model_loongson3.o | ||
diff --git a/arch/mips/oprofile/backtrace.c b/arch/mips/oprofile/backtrace.c index 83a1dfd8f0e3..5e645c9a3162 100644 --- a/arch/mips/oprofile/backtrace.c +++ b/arch/mips/oprofile/backtrace.c | |||
@@ -65,7 +65,7 @@ static inline int is_end_of_function_marker(union mips_instruction *ip) | |||
65 | * - handle cases where the stack is adjusted inside a function | 65 | * - handle cases where the stack is adjusted inside a function |
66 | * (generally doesn't happen) | 66 | * (generally doesn't happen) |
67 | * - find optimal value for max_instr_check | 67 | * - find optimal value for max_instr_check |
68 | * - try to find a way to handle leaf functions | 68 | * - try to find a better way to handle leaf functions |
69 | */ | 69 | */ |
70 | 70 | ||
71 | static inline int unwind_user_frame(struct stackframe *old_frame, | 71 | static inline int unwind_user_frame(struct stackframe *old_frame, |
@@ -104,7 +104,7 @@ static inline int unwind_user_frame(struct stackframe *old_frame, | |||
104 | } | 104 | } |
105 | 105 | ||
106 | if (!ra_offset || !stack_size) | 106 | if (!ra_offset || !stack_size) |
107 | return -1; | 107 | goto done; |
108 | 108 | ||
109 | if (ra_offset) { | 109 | if (ra_offset) { |
110 | new_frame.ra = old_frame->sp + ra_offset; | 110 | new_frame.ra = old_frame->sp + ra_offset; |
@@ -121,6 +121,7 @@ static inline int unwind_user_frame(struct stackframe *old_frame, | |||
121 | if (new_frame.sp > old_frame->sp) | 121 | if (new_frame.sp > old_frame->sp) |
122 | return -2; | 122 | return -2; |
123 | 123 | ||
124 | done: | ||
124 | new_frame.pc = old_frame->ra; | 125 | new_frame.pc = old_frame->ra; |
125 | *old_frame = new_frame; | 126 | *old_frame = new_frame; |
126 | 127 | ||
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c index e74732449478..a26cbe372e06 100644 --- a/arch/mips/oprofile/common.c +++ b/arch/mips/oprofile/common.c | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | extern struct op_mips_model op_model_mipsxx_ops __weak; | 19 | extern struct op_mips_model op_model_mipsxx_ops __weak; |
20 | extern struct op_mips_model op_model_loongson2_ops __weak; | 20 | extern struct op_mips_model op_model_loongson2_ops __weak; |
21 | extern struct op_mips_model op_model_loongson3_ops __weak; | ||
21 | 22 | ||
22 | static struct op_mips_model *model; | 23 | static struct op_mips_model *model; |
23 | 24 | ||
@@ -104,8 +105,17 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
104 | case CPU_LOONGSON2: | 105 | case CPU_LOONGSON2: |
105 | lmodel = &op_model_loongson2_ops; | 106 | lmodel = &op_model_loongson2_ops; |
106 | break; | 107 | break; |
108 | case CPU_LOONGSON3: | ||
109 | lmodel = &op_model_loongson3_ops; | ||
110 | break; | ||
107 | }; | 111 | }; |
108 | 112 | ||
113 | /* | ||
114 | * Always set the backtrace. This allows unsupported CPU types to still | ||
115 | * use timer-based oprofile. | ||
116 | */ | ||
117 | ops->backtrace = op_mips_backtrace; | ||
118 | |||
109 | if (!lmodel) | 119 | if (!lmodel) |
110 | return -ENODEV; | 120 | return -ENODEV; |
111 | 121 | ||
@@ -121,7 +131,6 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
121 | ops->start = op_mips_start; | 131 | ops->start = op_mips_start; |
122 | ops->stop = op_mips_stop; | 132 | ops->stop = op_mips_stop; |
123 | ops->cpu_type = lmodel->cpu_type; | 133 | ops->cpu_type = lmodel->cpu_type; |
124 | ops->backtrace = op_mips_backtrace; | ||
125 | 134 | ||
126 | printk(KERN_INFO "oprofile: using %s performance monitoring.\n", | 135 | printk(KERN_INFO "oprofile: using %s performance monitoring.\n", |
127 | lmodel->cpu_type); | 136 | lmodel->cpu_type); |
diff --git a/arch/mips/oprofile/op_model_loongson3.c b/arch/mips/oprofile/op_model_loongson3.c new file mode 100644 index 000000000000..8bcf7fc40f0d --- /dev/null +++ b/arch/mips/oprofile/op_model_loongson3.c | |||
@@ -0,0 +1,220 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | */ | ||
7 | #include <linux/init.h> | ||
8 | #include <linux/cpu.h> | ||
9 | #include <linux/smp.h> | ||
10 | #include <linux/proc_fs.h> | ||
11 | #include <linux/oprofile.h> | ||
12 | #include <linux/spinlock.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <asm/uaccess.h> | ||
15 | #include <irq.h> | ||
16 | #include <loongson.h> | ||
17 | #include "op_impl.h" | ||
18 | |||
19 | #define LOONGSON3_PERFCNT_OVERFLOW (1ULL << 63) | ||
20 | |||
21 | #define LOONGSON3_PERFCTRL_EXL (1UL << 0) | ||
22 | #define LOONGSON3_PERFCTRL_KERNEL (1UL << 1) | ||
23 | #define LOONGSON3_PERFCTRL_SUPERVISOR (1UL << 2) | ||
24 | #define LOONGSON3_PERFCTRL_USER (1UL << 3) | ||
25 | #define LOONGSON3_PERFCTRL_ENABLE (1UL << 4) | ||
26 | #define LOONGSON3_PERFCTRL_W (1UL << 30) | ||
27 | #define LOONGSON3_PERFCTRL_M (1UL << 31) | ||
28 | #define LOONGSON3_PERFCTRL_EVENT(idx, event) \ | ||
29 | (((event) & (idx ? 0x0f : 0x3f)) << 5) | ||
30 | |||
31 | /* Loongson-3 PerfCount performance counter1 register */ | ||
32 | #define read_c0_perflo1() __read_64bit_c0_register($25, 0) | ||
33 | #define write_c0_perflo1(val) __write_64bit_c0_register($25, 0, val) | ||
34 | #define read_c0_perfhi1() __read_64bit_c0_register($25, 1) | ||
35 | #define write_c0_perfhi1(val) __write_64bit_c0_register($25, 1, val) | ||
36 | |||
37 | /* Loongson-3 PerfCount performance counter2 register */ | ||
38 | #define read_c0_perflo2() __read_64bit_c0_register($25, 2) | ||
39 | #define write_c0_perflo2(val) __write_64bit_c0_register($25, 2, val) | ||
40 | #define read_c0_perfhi2() __read_64bit_c0_register($25, 3) | ||
41 | #define write_c0_perfhi2(val) __write_64bit_c0_register($25, 3, val) | ||
42 | |||
43 | static int (*save_perf_irq)(void); | ||
44 | |||
45 | static struct loongson3_register_config { | ||
46 | unsigned int control1; | ||
47 | unsigned int control2; | ||
48 | unsigned long long reset_counter1; | ||
49 | unsigned long long reset_counter2; | ||
50 | int ctr1_enable, ctr2_enable; | ||
51 | } reg; | ||
52 | |||
53 | static void reset_counters(void *arg) | ||
54 | { | ||
55 | write_c0_perfhi1(0); | ||
56 | write_c0_perfhi2(0); | ||
57 | write_c0_perflo1(0xc0000000); | ||
58 | write_c0_perflo2(0x40000000); | ||
59 | } | ||
60 | |||
61 | /* Compute all of the registers in preparation for enabling profiling. */ | ||
62 | static void loongson3_reg_setup(struct op_counter_config *ctr) | ||
63 | { | ||
64 | unsigned int control1 = 0; | ||
65 | unsigned int control2 = 0; | ||
66 | |||
67 | reg.reset_counter1 = 0; | ||
68 | reg.reset_counter2 = 0; | ||
69 | /* Compute the performance counter control word. */ | ||
70 | /* For now count kernel and user mode */ | ||
71 | if (ctr[0].enabled) { | ||
72 | control1 |= LOONGSON3_PERFCTRL_EVENT(0, ctr[0].event) | | ||
73 | LOONGSON3_PERFCTRL_ENABLE; | ||
74 | if (ctr[0].kernel) | ||
75 | control1 |= LOONGSON3_PERFCTRL_KERNEL; | ||
76 | if (ctr[0].user) | ||
77 | control1 |= LOONGSON3_PERFCTRL_USER; | ||
78 | reg.reset_counter1 = 0x8000000000000000ULL - ctr[0].count; | ||
79 | } | ||
80 | |||
81 | if (ctr[1].enabled) { | ||
82 | control2 |= LOONGSON3_PERFCTRL_EVENT(1, ctr[1].event) | | ||
83 | LOONGSON3_PERFCTRL_ENABLE; | ||
84 | if (ctr[1].kernel) | ||
85 | control2 |= LOONGSON3_PERFCTRL_KERNEL; | ||
86 | if (ctr[1].user) | ||
87 | control2 |= LOONGSON3_PERFCTRL_USER; | ||
88 | reg.reset_counter2 = 0x8000000000000000ULL - ctr[1].count; | ||
89 | } | ||
90 | |||
91 | if (ctr[0].enabled) | ||
92 | control1 |= LOONGSON3_PERFCTRL_EXL; | ||
93 | if (ctr[1].enabled) | ||
94 | control2 |= LOONGSON3_PERFCTRL_EXL; | ||
95 | |||
96 | reg.control1 = control1; | ||
97 | reg.control2 = control2; | ||
98 | reg.ctr1_enable = ctr[0].enabled; | ||
99 | reg.ctr2_enable = ctr[1].enabled; | ||
100 | } | ||
101 | |||
102 | /* Program all of the registers in preparation for enabling profiling. */ | ||
103 | static void loongson3_cpu_setup(void *args) | ||
104 | { | ||
105 | uint64_t perfcount1, perfcount2; | ||
106 | |||
107 | perfcount1 = reg.reset_counter1; | ||
108 | perfcount2 = reg.reset_counter2; | ||
109 | write_c0_perfhi1(perfcount1); | ||
110 | write_c0_perfhi2(perfcount2); | ||
111 | } | ||
112 | |||
113 | static void loongson3_cpu_start(void *args) | ||
114 | { | ||
115 | /* Start all counters on current CPU */ | ||
116 | reg.control1 |= (LOONGSON3_PERFCTRL_W|LOONGSON3_PERFCTRL_M); | ||
117 | reg.control2 |= (LOONGSON3_PERFCTRL_W|LOONGSON3_PERFCTRL_M); | ||
118 | |||
119 | if (reg.ctr1_enable) | ||
120 | write_c0_perflo1(reg.control1); | ||
121 | if (reg.ctr2_enable) | ||
122 | write_c0_perflo2(reg.control2); | ||
123 | } | ||
124 | |||
125 | static void loongson3_cpu_stop(void *args) | ||
126 | { | ||
127 | /* Stop all counters on current CPU */ | ||
128 | write_c0_perflo1(0xc0000000); | ||
129 | write_c0_perflo2(0x40000000); | ||
130 | memset(®, 0, sizeof(reg)); | ||
131 | } | ||
132 | |||
133 | static int loongson3_perfcount_handler(void) | ||
134 | { | ||
135 | unsigned long flags; | ||
136 | uint64_t counter1, counter2; | ||
137 | uint32_t cause, handled = IRQ_NONE; | ||
138 | struct pt_regs *regs = get_irq_regs(); | ||
139 | |||
140 | cause = read_c0_cause(); | ||
141 | if (!(cause & CAUSEF_PCI)) | ||
142 | return handled; | ||
143 | |||
144 | counter1 = read_c0_perfhi1(); | ||
145 | counter2 = read_c0_perfhi2(); | ||
146 | |||
147 | local_irq_save(flags); | ||
148 | |||
149 | if (counter1 & LOONGSON3_PERFCNT_OVERFLOW) { | ||
150 | if (reg.ctr1_enable) | ||
151 | oprofile_add_sample(regs, 0); | ||
152 | counter1 = reg.reset_counter1; | ||
153 | } | ||
154 | if (counter2 & LOONGSON3_PERFCNT_OVERFLOW) { | ||
155 | if (reg.ctr2_enable) | ||
156 | oprofile_add_sample(regs, 1); | ||
157 | counter2 = reg.reset_counter2; | ||
158 | } | ||
159 | |||
160 | local_irq_restore(flags); | ||
161 | |||
162 | write_c0_perfhi1(counter1); | ||
163 | write_c0_perfhi2(counter2); | ||
164 | |||
165 | if (!(cause & CAUSEF_TI)) | ||
166 | handled = IRQ_HANDLED; | ||
167 | |||
168 | return handled; | ||
169 | } | ||
170 | |||
171 | static int loongson3_cpu_callback(struct notifier_block *nfb, | ||
172 | unsigned long action, void *hcpu) | ||
173 | { | ||
174 | switch (action) { | ||
175 | case CPU_STARTING: | ||
176 | case CPU_STARTING_FROZEN: | ||
177 | write_c0_perflo1(reg.control1); | ||
178 | write_c0_perflo2(reg.control2); | ||
179 | break; | ||
180 | case CPU_DYING: | ||
181 | case CPU_DYING_FROZEN: | ||
182 | write_c0_perflo1(0xc0000000); | ||
183 | write_c0_perflo2(0x40000000); | ||
184 | break; | ||
185 | } | ||
186 | |||
187 | return NOTIFY_OK; | ||
188 | } | ||
189 | |||
190 | static struct notifier_block loongson3_notifier_block = { | ||
191 | .notifier_call = loongson3_cpu_callback | ||
192 | }; | ||
193 | |||
194 | static int __init loongson3_init(void) | ||
195 | { | ||
196 | on_each_cpu(reset_counters, NULL, 1); | ||
197 | register_hotcpu_notifier(&loongson3_notifier_block); | ||
198 | save_perf_irq = perf_irq; | ||
199 | perf_irq = loongson3_perfcount_handler; | ||
200 | |||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static void loongson3_exit(void) | ||
205 | { | ||
206 | on_each_cpu(reset_counters, NULL, 1); | ||
207 | unregister_hotcpu_notifier(&loongson3_notifier_block); | ||
208 | perf_irq = save_perf_irq; | ||
209 | } | ||
210 | |||
211 | struct op_mips_model op_model_loongson3_ops = { | ||
212 | .reg_setup = loongson3_reg_setup, | ||
213 | .cpu_setup = loongson3_cpu_setup, | ||
214 | .init = loongson3_init, | ||
215 | .exit = loongson3_exit, | ||
216 | .cpu_start = loongson3_cpu_start, | ||
217 | .cpu_stop = loongson3_cpu_stop, | ||
218 | .cpu_type = "mips/loongson3", | ||
219 | .num_counters = 2 | ||
220 | }; | ||
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index 42821ae2d77e..01f721a85c5b 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
12 | #include <linux/smp.h> | 12 | #include <linux/smp.h> |
13 | #include <asm/irq_regs.h> | 13 | #include <asm/irq_regs.h> |
14 | #include <asm/time.h> | ||
14 | 15 | ||
15 | #include "op_impl.h" | 16 | #include "op_impl.h" |
16 | 17 | ||
@@ -35,6 +36,7 @@ | |||
35 | #define M_PERFCTL_COUNT_ALL_THREADS (1UL << 13) | 36 | #define M_PERFCTL_COUNT_ALL_THREADS (1UL << 13) |
36 | 37 | ||
37 | static int (*save_perf_irq)(void); | 38 | static int (*save_perf_irq)(void); |
39 | static int perfcount_irq; | ||
38 | 40 | ||
39 | /* | 41 | /* |
40 | * XLR has only one set of counters per core. Designate the | 42 | * XLR has only one set of counters per core. Designate the |
@@ -431,8 +433,16 @@ static int __init mipsxx_init(void) | |||
431 | save_perf_irq = perf_irq; | 433 | save_perf_irq = perf_irq; |
432 | perf_irq = mipsxx_perfcount_handler; | 434 | perf_irq = mipsxx_perfcount_handler; |
433 | 435 | ||
434 | if ((cp0_perfcount_irq >= 0) && (cp0_compare_irq != cp0_perfcount_irq)) | 436 | if (get_c0_perfcount_int) |
435 | return request_irq(cp0_perfcount_irq, mipsxx_perfcount_int, | 437 | perfcount_irq = get_c0_perfcount_int(); |
438 | else if ((cp0_perfcount_irq >= 0) && | ||
439 | (cp0_compare_irq != cp0_perfcount_irq)) | ||
440 | perfcount_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; | ||
441 | else | ||
442 | perfcount_irq = -1; | ||
443 | |||
444 | if (perfcount_irq >= 0) | ||
445 | return request_irq(perfcount_irq, mipsxx_perfcount_int, | ||
436 | 0, "Perfcounter", save_perf_irq); | 446 | 0, "Perfcounter", save_perf_irq); |
437 | 447 | ||
438 | return 0; | 448 | return 0; |
@@ -442,8 +452,8 @@ static void mipsxx_exit(void) | |||
442 | { | 452 | { |
443 | int counters = op_model_mipsxx_ops.num_counters; | 453 | int counters = op_model_mipsxx_ops.num_counters; |
444 | 454 | ||
445 | if ((cp0_perfcount_irq >= 0) && (cp0_compare_irq != cp0_perfcount_irq)) | 455 | if (perfcount_irq >= 0) |
446 | free_irq(cp0_perfcount_irq, save_perf_irq); | 456 | free_irq(perfcount_irq, save_perf_irq); |
447 | 457 | ||
448 | counters = counters_per_cpu_to_total(counters); | 458 | counters = counters_per_cpu_to_total(counters); |
449 | on_each_cpu(reset_counters, (void *)(long)counters, 1); | 459 | on_each_cpu(reset_counters, (void *)(long)counters, 1); |
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 6523d558ff5a..300591c6278d 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile | |||
@@ -19,6 +19,7 @@ obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o | |||
19 | obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ | 19 | obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ |
20 | ops-bcm63xx.o | 20 | ops-bcm63xx.o |
21 | obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o | 21 | obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o |
22 | obj-$(CONFIG_PCI_AR2315) += pci-ar2315.o | ||
22 | obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o | 23 | obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o |
23 | obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o | 24 | obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o |
24 | obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o | 25 | obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o |
@@ -42,6 +43,7 @@ obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o | |||
42 | obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o | 43 | obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o |
43 | obj-$(CONFIG_LANTIQ) += fixup-lantiq.o | 44 | obj-$(CONFIG_LANTIQ) += fixup-lantiq.o |
44 | obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o | 45 | obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o |
46 | obj-$(CONFIG_SOC_RT2880) += pci-rt2880.o | ||
45 | obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o | 47 | obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o |
46 | obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o | 48 | obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o |
47 | obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o | 49 | obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o |
diff --git a/arch/mips/pci/ops-bcm63xx.c b/arch/mips/pci/ops-bcm63xx.c index 13eea696bbe7..d02eb9d16b55 100644 --- a/arch/mips/pci/ops-bcm63xx.c +++ b/arch/mips/pci/ops-bcm63xx.c | |||
@@ -469,7 +469,7 @@ static int bcm63xx_pcie_can_access(struct pci_bus *bus, int devfn) | |||
469 | { | 469 | { |
470 | switch (bus->number) { | 470 | switch (bus->number) { |
471 | case PCIE_BUS_BRIDGE: | 471 | case PCIE_BUS_BRIDGE: |
472 | return (PCI_SLOT(devfn) == 0); | 472 | return PCI_SLOT(devfn) == 0; |
473 | case PCIE_BUS_DEVICE: | 473 | case PCIE_BUS_DEVICE: |
474 | if (PCI_SLOT(devfn) == 0) | 474 | if (PCI_SLOT(devfn) == 0) |
475 | return bcm_pcie_readl(PCIE_DLSTATUS_REG) | 475 | return bcm_pcie_readl(PCIE_DLSTATUS_REG) |
diff --git a/arch/mips/pci/ops-nile4.c b/arch/mips/pci/ops-nile4.c index a1a7c9f4096e..b9d1fd0ff7e2 100644 --- a/arch/mips/pci/ops-nile4.c +++ b/arch/mips/pci/ops-nile4.c | |||
@@ -13,8 +13,6 @@ | |||
13 | 13 | ||
14 | volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE; | 14 | volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE; |
15 | 15 | ||
16 | static DEFINE_SPINLOCK(nile4_pci_lock); | ||
17 | |||
18 | static int nile4_pcibios_config_access(unsigned char access_type, | 16 | static int nile4_pcibios_config_access(unsigned char access_type, |
19 | struct pci_bus *bus, unsigned int devfn, int where, u32 *val) | 17 | struct pci_bus *bus, unsigned int devfn, int where, u32 *val) |
20 | { | 18 | { |
@@ -76,7 +74,6 @@ static int nile4_pcibios_config_access(unsigned char access_type, | |||
76 | static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn, | 74 | static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn, |
77 | int where, int size, u32 *val) | 75 | int where, int size, u32 *val) |
78 | { | 76 | { |
79 | unsigned long flags; | ||
80 | u32 data = 0; | 77 | u32 data = 0; |
81 | int err; | 78 | int err; |
82 | 79 | ||
@@ -85,11 +82,8 @@ static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn, | |||
85 | else if ((size == 4) && (where & 3)) | 82 | else if ((size == 4) && (where & 3)) |
86 | return PCIBIOS_BAD_REGISTER_NUMBER; | 83 | return PCIBIOS_BAD_REGISTER_NUMBER; |
87 | 84 | ||
88 | spin_lock_irqsave(&nile4_pci_lock, flags); | ||
89 | err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, | 85 | err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, |
90 | &data); | 86 | &data); |
91 | spin_unlock_irqrestore(&nile4_pci_lock, flags); | ||
92 | |||
93 | if (err) | 87 | if (err) |
94 | return err; | 88 | return err; |
95 | 89 | ||
@@ -106,7 +100,6 @@ static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn, | |||
106 | static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn, | 100 | static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn, |
107 | int where, int size, u32 val) | 101 | int where, int size, u32 val) |
108 | { | 102 | { |
109 | unsigned long flags; | ||
110 | u32 data = 0; | 103 | u32 data = 0; |
111 | int err; | 104 | int err; |
112 | 105 | ||
@@ -115,11 +108,8 @@ static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn, | |||
115 | else if ((size == 4) && (where & 3)) | 108 | else if ((size == 4) && (where & 3)) |
116 | return PCIBIOS_BAD_REGISTER_NUMBER; | 109 | return PCIBIOS_BAD_REGISTER_NUMBER; |
117 | 110 | ||
118 | spin_lock_irqsave(&nile4_pci_lock, flags); | ||
119 | err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, | 111 | err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, |
120 | &data); | 112 | &data); |
121 | spin_unlock_irqrestore(&nile4_pci_lock, flags); | ||
122 | |||
123 | if (err) | 113 | if (err) |
124 | return err; | 114 | return err; |
125 | 115 | ||
diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c index 50034f985be1..dd2d9f7e9412 100644 --- a/arch/mips/pci/ops-pmcmsp.c +++ b/arch/mips/pci/ops-pmcmsp.c | |||
@@ -193,8 +193,6 @@ static void pci_proc_init(void) | |||
193 | } | 193 | } |
194 | #endif /* CONFIG_PROC_FS && PCI_COUNTERS */ | 194 | #endif /* CONFIG_PROC_FS && PCI_COUNTERS */ |
195 | 195 | ||
196 | static DEFINE_SPINLOCK(bpci_lock); | ||
197 | |||
198 | /***************************************************************************** | 196 | /***************************************************************************** |
199 | * | 197 | * |
200 | * STRUCT: pci_io_resource | 198 | * STRUCT: pci_io_resource |
@@ -368,7 +366,6 @@ int msp_pcibios_config_access(unsigned char access_type, | |||
368 | struct msp_pci_regs *preg = (void *)PCI_BASE_REG; | 366 | struct msp_pci_regs *preg = (void *)PCI_BASE_REG; |
369 | unsigned char bus_num = bus->number; | 367 | unsigned char bus_num = bus->number; |
370 | unsigned char dev_fn = (unsigned char)devfn; | 368 | unsigned char dev_fn = (unsigned char)devfn; |
371 | unsigned long flags; | ||
372 | unsigned long intr; | 369 | unsigned long intr; |
373 | unsigned long value; | 370 | unsigned long value; |
374 | static char pciirqflag; | 371 | static char pciirqflag; |
@@ -401,10 +398,7 @@ int msp_pcibios_config_access(unsigned char access_type, | |||
401 | } | 398 | } |
402 | 399 | ||
403 | #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) | 400 | #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) |
404 | local_irq_save(flags); | ||
405 | vpe_status = dvpe(); | 401 | vpe_status = dvpe(); |
406 | #else | ||
407 | spin_lock_irqsave(&bpci_lock, flags); | ||
408 | #endif | 402 | #endif |
409 | 403 | ||
410 | /* | 404 | /* |
@@ -457,9 +451,6 @@ int msp_pcibios_config_access(unsigned char access_type, | |||
457 | 451 | ||
458 | #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) | 452 | #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) |
459 | evpe(vpe_status); | 453 | evpe(vpe_status); |
460 | local_irq_restore(flags); | ||
461 | #else | ||
462 | spin_unlock_irqrestore(&bpci_lock, flags); | ||
463 | #endif | 454 | #endif |
464 | 455 | ||
465 | return -1; | 456 | return -1; |
@@ -467,9 +458,6 @@ int msp_pcibios_config_access(unsigned char access_type, | |||
467 | 458 | ||
468 | #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) | 459 | #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL) |
469 | evpe(vpe_status); | 460 | evpe(vpe_status); |
470 | local_irq_restore(flags); | ||
471 | #else | ||
472 | spin_unlock_irqrestore(&bpci_lock, flags); | ||
473 | #endif | 461 | #endif |
474 | 462 | ||
475 | return PCIBIOS_SUCCESSFUL; | 463 | return PCIBIOS_SUCCESSFUL; |
diff --git a/arch/mips/pci/pci-ar2315.c b/arch/mips/pci/pci-ar2315.c new file mode 100644 index 000000000000..bd2b3b60da83 --- /dev/null +++ b/arch/mips/pci/pci-ar2315.c | |||
@@ -0,0 +1,511 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or | ||
3 | * modify it under the terms of the GNU General Public License | ||
4 | * as published by the Free Software Foundation; either version 2 | ||
5 | * of the License, or (at your option) any later version. | ||
6 | * | ||
7 | * This program is distributed in the hope that it will be useful, | ||
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | * GNU General Public License for more details. | ||
11 | * | ||
12 | * You should have received a copy of the GNU General Public License | ||
13 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||
14 | */ | ||
15 | |||
16 | /** | ||
17 | * Both AR2315 and AR2316 chips have PCI interface unit, which supports DMA | ||
18 | * and interrupt. PCI interface supports MMIO access method, but does not | ||
19 | * seem to support I/O ports. | ||
20 | * | ||
21 | * Read/write operation in the region 0x80000000-0xBFFFFFFF causes | ||
22 | * a memory read/write command on the PCI bus. 30 LSBs of address on | ||
23 | * the bus are taken from memory read/write request and 2 MSBs are | ||
24 | * determined by PCI unit configuration. | ||
25 | * | ||
26 | * To work with the configuration space instead of memory is necessary set | ||
27 | * the CFG_SEL bit in the PCI_MISC_CONFIG register. | ||
28 | * | ||
29 | * Devices on the bus can perform DMA requests via chip BAR1. PCI host | ||
30 | * controller BARs are programmend as if an external device is programmed. | ||
31 | * Which means that during configuration, IDSEL pin of the chip should be | ||
32 | * asserted. | ||
33 | * | ||
34 | * We know (and support) only one board that uses the PCI interface - | ||
35 | * Fonera 2.0g (FON2202). It has a USB EHCI controller connected to the | ||
36 | * AR2315 PCI bus. IDSEL pin of USB controller is connected to AD[13] line | ||
37 | * and IDSEL pin of AR2315 is connected to AD[16] line. | ||
38 | */ | ||
39 | |||
40 | #include <linux/types.h> | ||
41 | #include <linux/pci.h> | ||
42 | #include <linux/platform_device.h> | ||
43 | #include <linux/kernel.h> | ||
44 | #include <linux/init.h> | ||
45 | #include <linux/mm.h> | ||
46 | #include <linux/delay.h> | ||
47 | #include <linux/bitops.h> | ||
48 | #include <linux/irq.h> | ||
49 | #include <linux/irqdomain.h> | ||
50 | #include <linux/io.h> | ||
51 | #include <asm/paccess.h> | ||
52 | |||
53 | /* | ||
54 | * PCI Bus Interface Registers | ||
55 | */ | ||
56 | #define AR2315_PCI_1MS_REG 0x0008 | ||
57 | |||
58 | #define AR2315_PCI_1MS_MASK 0x3FFFF /* # of AHB clk cycles in 1ms */ | ||
59 | |||
60 | #define AR2315_PCI_MISC_CONFIG 0x000c | ||
61 | |||
62 | #define AR2315_PCIMISC_TXD_EN 0x00000001 /* Enable TXD for fragments */ | ||
63 | #define AR2315_PCIMISC_CFG_SEL 0x00000002 /* Mem or Config cycles */ | ||
64 | #define AR2315_PCIMISC_GIG_MASK 0x0000000C /* bits 31-30 for pci req */ | ||
65 | #define AR2315_PCIMISC_RST_MODE 0x00000030 | ||
66 | #define AR2315_PCIRST_INPUT 0x00000000 /* 4:5=0 rst is input */ | ||
67 | #define AR2315_PCIRST_LOW 0x00000010 /* 4:5=1 rst to GND */ | ||
68 | #define AR2315_PCIRST_HIGH 0x00000020 /* 4:5=2 rst to VDD */ | ||
69 | #define AR2315_PCIGRANT_EN 0x00000000 /* 6:7=0 early grant en */ | ||
70 | #define AR2315_PCIGRANT_FRAME 0x00000040 /* 6:7=1 grant waits 4 frame */ | ||
71 | #define AR2315_PCIGRANT_IDLE 0x00000080 /* 6:7=2 grant waits 4 idle */ | ||
72 | #define AR2315_PCIGRANT_GAP 0x00000000 /* 6:7=2 grant waits 4 idle */ | ||
73 | #define AR2315_PCICACHE_DIS 0x00001000 /* PCI external access cache | ||
74 | * disable */ | ||
75 | |||
76 | #define AR2315_PCI_OUT_TSTAMP 0x0010 | ||
77 | |||
78 | #define AR2315_PCI_UNCACHE_CFG 0x0014 | ||
79 | |||
80 | #define AR2315_PCI_IN_EN 0x0100 | ||
81 | |||
82 | #define AR2315_PCI_IN_EN0 0x01 /* Enable chain 0 */ | ||
83 | #define AR2315_PCI_IN_EN1 0x02 /* Enable chain 1 */ | ||
84 | #define AR2315_PCI_IN_EN2 0x04 /* Enable chain 2 */ | ||
85 | #define AR2315_PCI_IN_EN3 0x08 /* Enable chain 3 */ | ||
86 | |||
87 | #define AR2315_PCI_IN_DIS 0x0104 | ||
88 | |||
89 | #define AR2315_PCI_IN_DIS0 0x01 /* Disable chain 0 */ | ||
90 | #define AR2315_PCI_IN_DIS1 0x02 /* Disable chain 1 */ | ||
91 | #define AR2315_PCI_IN_DIS2 0x04 /* Disable chain 2 */ | ||
92 | #define AR2315_PCI_IN_DIS3 0x08 /* Disable chain 3 */ | ||
93 | |||
94 | #define AR2315_PCI_IN_PTR 0x0200 | ||
95 | |||
96 | #define AR2315_PCI_OUT_EN 0x0400 | ||
97 | |||
98 | #define AR2315_PCI_OUT_EN0 0x01 /* Enable chain 0 */ | ||
99 | |||
100 | #define AR2315_PCI_OUT_DIS 0x0404 | ||
101 | |||
102 | #define AR2315_PCI_OUT_DIS0 0x01 /* Disable chain 0 */ | ||
103 | |||
104 | #define AR2315_PCI_OUT_PTR 0x0408 | ||
105 | |||
106 | /* PCI interrupt status (write one to clear) */ | ||
107 | #define AR2315_PCI_ISR 0x0500 | ||
108 | |||
109 | #define AR2315_PCI_INT_TX 0x00000001 /* Desc In Completed */ | ||
110 | #define AR2315_PCI_INT_TXOK 0x00000002 /* Desc In OK */ | ||
111 | #define AR2315_PCI_INT_TXERR 0x00000004 /* Desc In ERR */ | ||
112 | #define AR2315_PCI_INT_TXEOL 0x00000008 /* Desc In End-of-List */ | ||
113 | #define AR2315_PCI_INT_RX 0x00000010 /* Desc Out Completed */ | ||
114 | #define AR2315_PCI_INT_RXOK 0x00000020 /* Desc Out OK */ | ||
115 | #define AR2315_PCI_INT_RXERR 0x00000040 /* Desc Out ERR */ | ||
116 | #define AR2315_PCI_INT_RXEOL 0x00000080 /* Desc Out EOL */ | ||
117 | #define AR2315_PCI_INT_TXOOD 0x00000200 /* Desc In Out-of-Desc */ | ||
118 | #define AR2315_PCI_INT_DESCMASK 0x0000FFFF /* Desc Mask */ | ||
119 | #define AR2315_PCI_INT_EXT 0x02000000 /* Extern PCI INTA */ | ||
120 | #define AR2315_PCI_INT_ABORT 0x04000000 /* PCI bus abort event */ | ||
121 | |||
122 | /* PCI interrupt mask */ | ||
123 | #define AR2315_PCI_IMR 0x0504 | ||
124 | |||
125 | /* Global PCI interrupt enable */ | ||
126 | #define AR2315_PCI_IER 0x0508 | ||
127 | |||
128 | #define AR2315_PCI_IER_DISABLE 0x00 /* disable pci interrupts */ | ||
129 | #define AR2315_PCI_IER_ENABLE 0x01 /* enable pci interrupts */ | ||
130 | |||
131 | #define AR2315_PCI_HOST_IN_EN 0x0800 | ||
132 | #define AR2315_PCI_HOST_IN_DIS 0x0804 | ||
133 | #define AR2315_PCI_HOST_IN_PTR 0x0810 | ||
134 | #define AR2315_PCI_HOST_OUT_EN 0x0900 | ||
135 | #define AR2315_PCI_HOST_OUT_DIS 0x0904 | ||
136 | #define AR2315_PCI_HOST_OUT_PTR 0x0908 | ||
137 | |||
138 | /* | ||
139 | * PCI interrupts, which share IP5 | ||
140 | * Keep ordered according to AR2315_PCI_INT_XXX bits | ||
141 | */ | ||
142 | #define AR2315_PCI_IRQ_EXT 25 | ||
143 | #define AR2315_PCI_IRQ_ABORT 26 | ||
144 | #define AR2315_PCI_IRQ_COUNT 27 | ||
145 | |||
146 | /* Arbitrary size of memory region to access the configuration space */ | ||
147 | #define AR2315_PCI_CFG_SIZE 0x00100000 | ||
148 | |||
149 | #define AR2315_PCI_HOST_SLOT 3 | ||
150 | #define AR2315_PCI_HOST_DEVID ((0xff18 << 16) | PCI_VENDOR_ID_ATHEROS) | ||
151 | |||
152 | /* ??? access BAR */ | ||
153 | #define AR2315_PCI_HOST_MBAR0 0x10000000 | ||
154 | /* RAM access BAR */ | ||
155 | #define AR2315_PCI_HOST_MBAR1 AR2315_PCI_HOST_SDRAM_BASEADDR | ||
156 | /* ??? access BAR */ | ||
157 | #define AR2315_PCI_HOST_MBAR2 0x30000000 | ||
158 | |||
159 | struct ar2315_pci_ctrl { | ||
160 | void __iomem *cfg_mem; | ||
161 | void __iomem *mmr_mem; | ||
162 | unsigned irq; | ||
163 | unsigned irq_ext; | ||
164 | struct irq_domain *domain; | ||
165 | struct pci_controller pci_ctrl; | ||
166 | struct resource mem_res; | ||
167 | struct resource io_res; | ||
168 | }; | ||
169 | |||
170 | static inline struct ar2315_pci_ctrl *ar2315_pci_bus_to_apc(struct pci_bus *bus) | ||
171 | { | ||
172 | struct pci_controller *hose = bus->sysdata; | ||
173 | |||
174 | return container_of(hose, struct ar2315_pci_ctrl, pci_ctrl); | ||
175 | } | ||
176 | |||
177 | static inline u32 ar2315_pci_reg_read(struct ar2315_pci_ctrl *apc, u32 reg) | ||
178 | { | ||
179 | return __raw_readl(apc->mmr_mem + reg); | ||
180 | } | ||
181 | |||
182 | static inline void ar2315_pci_reg_write(struct ar2315_pci_ctrl *apc, u32 reg, | ||
183 | u32 val) | ||
184 | { | ||
185 | __raw_writel(val, apc->mmr_mem + reg); | ||
186 | } | ||
187 | |||
188 | static inline void ar2315_pci_reg_mask(struct ar2315_pci_ctrl *apc, u32 reg, | ||
189 | u32 mask, u32 val) | ||
190 | { | ||
191 | u32 ret = ar2315_pci_reg_read(apc, reg); | ||
192 | |||
193 | ret &= ~mask; | ||
194 | ret |= val; | ||
195 | ar2315_pci_reg_write(apc, reg, ret); | ||
196 | } | ||
197 | |||
198 | static int ar2315_pci_cfg_access(struct ar2315_pci_ctrl *apc, unsigned devfn, | ||
199 | int where, int size, u32 *ptr, bool write) | ||
200 | { | ||
201 | int func = PCI_FUNC(devfn); | ||
202 | int dev = PCI_SLOT(devfn); | ||
203 | u32 addr = (1 << (13 + dev)) | (func << 8) | (where & ~3); | ||
204 | u32 mask = 0xffffffff >> 8 * (4 - size); | ||
205 | u32 sh = (where & 3) * 8; | ||
206 | u32 value, isr; | ||
207 | |||
208 | /* Prevent access past the remapped area */ | ||
209 | if (addr >= AR2315_PCI_CFG_SIZE || dev > 18) | ||
210 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
211 | |||
212 | /* Clear pending errors */ | ||
213 | ar2315_pci_reg_write(apc, AR2315_PCI_ISR, AR2315_PCI_INT_ABORT); | ||
214 | /* Select Configuration access */ | ||
215 | ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG, 0, | ||
216 | AR2315_PCIMISC_CFG_SEL); | ||
217 | |||
218 | mb(); /* PCI must see space change before we begin */ | ||
219 | |||
220 | value = __raw_readl(apc->cfg_mem + addr); | ||
221 | |||
222 | isr = ar2315_pci_reg_read(apc, AR2315_PCI_ISR); | ||
223 | |||
224 | if (isr & AR2315_PCI_INT_ABORT) | ||
225 | goto exit_err; | ||
226 | |||
227 | if (write) { | ||
228 | value = (value & ~(mask << sh)) | *ptr << sh; | ||
229 | __raw_writel(value, apc->cfg_mem + addr); | ||
230 | isr = ar2315_pci_reg_read(apc, AR2315_PCI_ISR); | ||
231 | if (isr & AR2315_PCI_INT_ABORT) | ||
232 | goto exit_err; | ||
233 | } else { | ||
234 | *ptr = (value >> sh) & mask; | ||
235 | } | ||
236 | |||
237 | goto exit; | ||
238 | |||
239 | exit_err: | ||
240 | ar2315_pci_reg_write(apc, AR2315_PCI_ISR, AR2315_PCI_INT_ABORT); | ||
241 | if (!write) | ||
242 | *ptr = 0xffffffff; | ||
243 | |||
244 | exit: | ||
245 | /* Select Memory access */ | ||
246 | ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG, AR2315_PCIMISC_CFG_SEL, | ||
247 | 0); | ||
248 | |||
249 | return isr & AR2315_PCI_INT_ABORT ? PCIBIOS_DEVICE_NOT_FOUND : | ||
250 | PCIBIOS_SUCCESSFUL; | ||
251 | } | ||
252 | |||
253 | static inline int ar2315_pci_local_cfg_rd(struct ar2315_pci_ctrl *apc, | ||
254 | unsigned devfn, int where, u32 *val) | ||
255 | { | ||
256 | return ar2315_pci_cfg_access(apc, devfn, where, sizeof(u32), val, | ||
257 | false); | ||
258 | } | ||
259 | |||
260 | static inline int ar2315_pci_local_cfg_wr(struct ar2315_pci_ctrl *apc, | ||
261 | unsigned devfn, int where, u32 val) | ||
262 | { | ||
263 | return ar2315_pci_cfg_access(apc, devfn, where, sizeof(u32), &val, | ||
264 | true); | ||
265 | } | ||
266 | |||
267 | static int ar2315_pci_cfg_read(struct pci_bus *bus, unsigned devfn, int where, | ||
268 | int size, u32 *value) | ||
269 | { | ||
270 | struct ar2315_pci_ctrl *apc = ar2315_pci_bus_to_apc(bus); | ||
271 | |||
272 | if (PCI_SLOT(devfn) == AR2315_PCI_HOST_SLOT) | ||
273 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
274 | |||
275 | return ar2315_pci_cfg_access(apc, devfn, where, size, value, false); | ||
276 | } | ||
277 | |||
278 | static int ar2315_pci_cfg_write(struct pci_bus *bus, unsigned devfn, int where, | ||
279 | int size, u32 value) | ||
280 | { | ||
281 | struct ar2315_pci_ctrl *apc = ar2315_pci_bus_to_apc(bus); | ||
282 | |||
283 | if (PCI_SLOT(devfn) == AR2315_PCI_HOST_SLOT) | ||
284 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
285 | |||
286 | return ar2315_pci_cfg_access(apc, devfn, where, size, &value, true); | ||
287 | } | ||
288 | |||
289 | static struct pci_ops ar2315_pci_ops = { | ||
290 | .read = ar2315_pci_cfg_read, | ||
291 | .write = ar2315_pci_cfg_write, | ||
292 | }; | ||
293 | |||
294 | static int ar2315_pci_host_setup(struct ar2315_pci_ctrl *apc) | ||
295 | { | ||
296 | unsigned devfn = PCI_DEVFN(AR2315_PCI_HOST_SLOT, 0); | ||
297 | int res; | ||
298 | u32 id; | ||
299 | |||
300 | res = ar2315_pci_local_cfg_rd(apc, devfn, PCI_VENDOR_ID, &id); | ||
301 | if (res != PCIBIOS_SUCCESSFUL || id != AR2315_PCI_HOST_DEVID) | ||
302 | return -ENODEV; | ||
303 | |||
304 | /* Program MBARs */ | ||
305 | ar2315_pci_local_cfg_wr(apc, devfn, PCI_BASE_ADDRESS_0, | ||
306 | AR2315_PCI_HOST_MBAR0); | ||
307 | ar2315_pci_local_cfg_wr(apc, devfn, PCI_BASE_ADDRESS_1, | ||
308 | AR2315_PCI_HOST_MBAR1); | ||
309 | ar2315_pci_local_cfg_wr(apc, devfn, PCI_BASE_ADDRESS_2, | ||
310 | AR2315_PCI_HOST_MBAR2); | ||
311 | |||
312 | /* Run */ | ||
313 | ar2315_pci_local_cfg_wr(apc, devfn, PCI_COMMAND, PCI_COMMAND_MEMORY | | ||
314 | PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL | | ||
315 | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | | ||
316 | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK); | ||
317 | |||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | static void ar2315_pci_irq_handler(unsigned irq, struct irq_desc *desc) | ||
322 | { | ||
323 | struct ar2315_pci_ctrl *apc = irq_get_handler_data(irq); | ||
324 | u32 pending = ar2315_pci_reg_read(apc, AR2315_PCI_ISR) & | ||
325 | ar2315_pci_reg_read(apc, AR2315_PCI_IMR); | ||
326 | unsigned pci_irq = 0; | ||
327 | |||
328 | if (pending) | ||
329 | pci_irq = irq_find_mapping(apc->domain, __ffs(pending)); | ||
330 | |||
331 | if (pci_irq) | ||
332 | generic_handle_irq(pci_irq); | ||
333 | else | ||
334 | spurious_interrupt(); | ||
335 | } | ||
336 | |||
337 | static void ar2315_pci_irq_mask(struct irq_data *d) | ||
338 | { | ||
339 | struct ar2315_pci_ctrl *apc = irq_data_get_irq_chip_data(d); | ||
340 | |||
341 | ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, BIT(d->hwirq), 0); | ||
342 | } | ||
343 | |||
344 | static void ar2315_pci_irq_mask_ack(struct irq_data *d) | ||
345 | { | ||
346 | struct ar2315_pci_ctrl *apc = irq_data_get_irq_chip_data(d); | ||
347 | u32 m = BIT(d->hwirq); | ||
348 | |||
349 | ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, m, 0); | ||
350 | ar2315_pci_reg_write(apc, AR2315_PCI_ISR, m); | ||
351 | } | ||
352 | |||
353 | static void ar2315_pci_irq_unmask(struct irq_data *d) | ||
354 | { | ||
355 | struct ar2315_pci_ctrl *apc = irq_data_get_irq_chip_data(d); | ||
356 | |||
357 | ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, 0, BIT(d->hwirq)); | ||
358 | } | ||
359 | |||
360 | static struct irq_chip ar2315_pci_irq_chip = { | ||
361 | .name = "AR2315-PCI", | ||
362 | .irq_mask = ar2315_pci_irq_mask, | ||
363 | .irq_mask_ack = ar2315_pci_irq_mask_ack, | ||
364 | .irq_unmask = ar2315_pci_irq_unmask, | ||
365 | }; | ||
366 | |||
367 | static int ar2315_pci_irq_map(struct irq_domain *d, unsigned irq, | ||
368 | irq_hw_number_t hw) | ||
369 | { | ||
370 | irq_set_chip_and_handler(irq, &ar2315_pci_irq_chip, handle_level_irq); | ||
371 | irq_set_chip_data(irq, d->host_data); | ||
372 | return 0; | ||
373 | } | ||
374 | |||
375 | static struct irq_domain_ops ar2315_pci_irq_domain_ops = { | ||
376 | .map = ar2315_pci_irq_map, | ||
377 | }; | ||
378 | |||
379 | static void ar2315_pci_irq_init(struct ar2315_pci_ctrl *apc) | ||
380 | { | ||
381 | ar2315_pci_reg_mask(apc, AR2315_PCI_IER, AR2315_PCI_IER_ENABLE, 0); | ||
382 | ar2315_pci_reg_mask(apc, AR2315_PCI_IMR, (AR2315_PCI_INT_ABORT | | ||
383 | AR2315_PCI_INT_EXT), 0); | ||
384 | |||
385 | apc->irq_ext = irq_create_mapping(apc->domain, AR2315_PCI_IRQ_EXT); | ||
386 | |||
387 | irq_set_chained_handler(apc->irq, ar2315_pci_irq_handler); | ||
388 | irq_set_handler_data(apc->irq, apc); | ||
389 | |||
390 | /* Clear any pending Abort or external Interrupts | ||
391 | * and enable interrupt processing */ | ||
392 | ar2315_pci_reg_write(apc, AR2315_PCI_ISR, AR2315_PCI_INT_ABORT | | ||
393 | AR2315_PCI_INT_EXT); | ||
394 | ar2315_pci_reg_mask(apc, AR2315_PCI_IER, 0, AR2315_PCI_IER_ENABLE); | ||
395 | } | ||
396 | |||
397 | static int ar2315_pci_probe(struct platform_device *pdev) | ||
398 | { | ||
399 | struct ar2315_pci_ctrl *apc; | ||
400 | struct device *dev = &pdev->dev; | ||
401 | struct resource *res; | ||
402 | int irq, err; | ||
403 | |||
404 | apc = devm_kzalloc(dev, sizeof(*apc), GFP_KERNEL); | ||
405 | if (!apc) | ||
406 | return -ENOMEM; | ||
407 | |||
408 | irq = platform_get_irq(pdev, 0); | ||
409 | if (irq < 0) | ||
410 | return -EINVAL; | ||
411 | apc->irq = irq; | ||
412 | |||
413 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | ||
414 | "ar2315-pci-ctrl"); | ||
415 | apc->mmr_mem = devm_ioremap_resource(dev, res); | ||
416 | if (IS_ERR(apc->mmr_mem)) | ||
417 | return PTR_ERR(apc->mmr_mem); | ||
418 | |||
419 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | ||
420 | "ar2315-pci-ext"); | ||
421 | if (!res) | ||
422 | return -EINVAL; | ||
423 | |||
424 | apc->mem_res.name = "AR2315 PCI mem space"; | ||
425 | apc->mem_res.parent = res; | ||
426 | apc->mem_res.start = res->start; | ||
427 | apc->mem_res.end = res->end; | ||
428 | apc->mem_res.flags = IORESOURCE_MEM; | ||
429 | |||
430 | /* Remap PCI config space */ | ||
431 | apc->cfg_mem = devm_ioremap_nocache(dev, res->start, | ||
432 | AR2315_PCI_CFG_SIZE); | ||
433 | if (!apc->cfg_mem) { | ||
434 | dev_err(dev, "failed to remap PCI config space\n"); | ||
435 | return -ENOMEM; | ||
436 | } | ||
437 | |||
438 | /* Reset the PCI bus by setting bits 5-4 in PCI_MCFG */ | ||
439 | ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG, | ||
440 | AR2315_PCIMISC_RST_MODE, | ||
441 | AR2315_PCIRST_LOW); | ||
442 | msleep(100); | ||
443 | |||
444 | /* Bring the PCI out of reset */ | ||
445 | ar2315_pci_reg_mask(apc, AR2315_PCI_MISC_CONFIG, | ||
446 | AR2315_PCIMISC_RST_MODE, | ||
447 | AR2315_PCIRST_HIGH | AR2315_PCICACHE_DIS | 0x8); | ||
448 | |||
449 | ar2315_pci_reg_write(apc, AR2315_PCI_UNCACHE_CFG, | ||
450 | 0x1E | /* 1GB uncached */ | ||
451 | (1 << 5) | /* Enable uncached */ | ||
452 | (0x2 << 30) /* Base: 0x80000000 */); | ||
453 | ar2315_pci_reg_read(apc, AR2315_PCI_UNCACHE_CFG); | ||
454 | |||
455 | msleep(500); | ||
456 | |||
457 | err = ar2315_pci_host_setup(apc); | ||
458 | if (err) | ||
459 | return err; | ||
460 | |||
461 | apc->domain = irq_domain_add_linear(NULL, AR2315_PCI_IRQ_COUNT, | ||
462 | &ar2315_pci_irq_domain_ops, apc); | ||
463 | if (!apc->domain) { | ||
464 | dev_err(dev, "failed to add IRQ domain\n"); | ||
465 | return -ENOMEM; | ||
466 | } | ||
467 | |||
468 | ar2315_pci_irq_init(apc); | ||
469 | |||
470 | /* PCI controller does not support I/O ports */ | ||
471 | apc->io_res.name = "AR2315 IO space"; | ||
472 | apc->io_res.start = 0; | ||
473 | apc->io_res.end = 0; | ||
474 | apc->io_res.flags = IORESOURCE_IO, | ||
475 | |||
476 | apc->pci_ctrl.pci_ops = &ar2315_pci_ops; | ||
477 | apc->pci_ctrl.mem_resource = &apc->mem_res, | ||
478 | apc->pci_ctrl.io_resource = &apc->io_res, | ||
479 | |||
480 | register_pci_controller(&apc->pci_ctrl); | ||
481 | |||
482 | dev_info(dev, "register PCI controller\n"); | ||
483 | |||
484 | return 0; | ||
485 | } | ||
486 | |||
487 | static struct platform_driver ar2315_pci_driver = { | ||
488 | .probe = ar2315_pci_probe, | ||
489 | .driver = { | ||
490 | .name = "ar2315-pci", | ||
491 | .owner = THIS_MODULE, | ||
492 | }, | ||
493 | }; | ||
494 | |||
495 | static int __init ar2315_pci_init(void) | ||
496 | { | ||
497 | return platform_driver_register(&ar2315_pci_driver); | ||
498 | } | ||
499 | arch_initcall(ar2315_pci_init); | ||
500 | |||
501 | int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | ||
502 | { | ||
503 | struct ar2315_pci_ctrl *apc = ar2315_pci_bus_to_apc(dev->bus); | ||
504 | |||
505 | return slot ? 0 : apc->irq_ext; | ||
506 | } | ||
507 | |||
508 | int pcibios_plat_dev_init(struct pci_dev *dev) | ||
509 | { | ||
510 | return 0; | ||
511 | } | ||
diff --git a/arch/mips/pci/pci-ar71xx.c b/arch/mips/pci/pci-ar71xx.c index d471a26dd5f8..2b534aea20e4 100644 --- a/arch/mips/pci/pci-ar71xx.c +++ b/arch/mips/pci/pci-ar71xx.c | |||
@@ -50,7 +50,6 @@ | |||
50 | 50 | ||
51 | struct ar71xx_pci_controller { | 51 | struct ar71xx_pci_controller { |
52 | void __iomem *cfg_base; | 52 | void __iomem *cfg_base; |
53 | spinlock_t lock; | ||
54 | int irq; | 53 | int irq; |
55 | int irq_base; | 54 | int irq_base; |
56 | struct pci_controller pci_ctrl; | 55 | struct pci_controller pci_ctrl; |
@@ -182,7 +181,6 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, | |||
182 | { | 181 | { |
183 | struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus); | 182 | struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus); |
184 | void __iomem *base = apc->cfg_base; | 183 | void __iomem *base = apc->cfg_base; |
185 | unsigned long flags; | ||
186 | u32 data; | 184 | u32 data; |
187 | int err; | 185 | int err; |
188 | int ret; | 186 | int ret; |
@@ -190,8 +188,6 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, | |||
190 | ret = PCIBIOS_SUCCESSFUL; | 188 | ret = PCIBIOS_SUCCESSFUL; |
191 | data = ~0; | 189 | data = ~0; |
192 | 190 | ||
193 | spin_lock_irqsave(&apc->lock, flags); | ||
194 | |||
195 | err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, | 191 | err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, |
196 | AR71XX_PCI_CFG_CMD_READ); | 192 | AR71XX_PCI_CFG_CMD_READ); |
197 | if (err) | 193 | if (err) |
@@ -199,8 +195,6 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, | |||
199 | else | 195 | else |
200 | data = __raw_readl(base + AR71XX_PCI_REG_CFG_RDDATA); | 196 | data = __raw_readl(base + AR71XX_PCI_REG_CFG_RDDATA); |
201 | 197 | ||
202 | spin_unlock_irqrestore(&apc->lock, flags); | ||
203 | |||
204 | *value = (data >> (8 * (where & 3))) & ar71xx_pci_read_mask[size & 7]; | 198 | *value = (data >> (8 * (where & 3))) & ar71xx_pci_read_mask[size & 7]; |
205 | 199 | ||
206 | return ret; | 200 | return ret; |
@@ -211,15 +205,12 @@ static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, | |||
211 | { | 205 | { |
212 | struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus); | 206 | struct ar71xx_pci_controller *apc = pci_bus_to_ar71xx_controller(bus); |
213 | void __iomem *base = apc->cfg_base; | 207 | void __iomem *base = apc->cfg_base; |
214 | unsigned long flags; | ||
215 | int err; | 208 | int err; |
216 | int ret; | 209 | int ret; |
217 | 210 | ||
218 | value = value << (8 * (where & 3)); | 211 | value = value << (8 * (where & 3)); |
219 | ret = PCIBIOS_SUCCESSFUL; | 212 | ret = PCIBIOS_SUCCESSFUL; |
220 | 213 | ||
221 | spin_lock_irqsave(&apc->lock, flags); | ||
222 | |||
223 | err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, | 214 | err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, |
224 | AR71XX_PCI_CFG_CMD_WRITE); | 215 | AR71XX_PCI_CFG_CMD_WRITE); |
225 | if (err) | 216 | if (err) |
@@ -227,8 +218,6 @@ static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, | |||
227 | else | 218 | else |
228 | __raw_writel(value, base + AR71XX_PCI_REG_CFG_WRDATA); | 219 | __raw_writel(value, base + AR71XX_PCI_REG_CFG_WRDATA); |
229 | 220 | ||
230 | spin_unlock_irqrestore(&apc->lock, flags); | ||
231 | |||
232 | return ret; | 221 | return ret; |
233 | } | 222 | } |
234 | 223 | ||
@@ -360,8 +349,6 @@ static int ar71xx_pci_probe(struct platform_device *pdev) | |||
360 | if (!apc) | 349 | if (!apc) |
361 | return -ENOMEM; | 350 | return -ENOMEM; |
362 | 351 | ||
363 | spin_lock_init(&apc->lock); | ||
364 | |||
365 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base"); | 352 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg_base"); |
366 | apc->cfg_base = devm_ioremap_resource(&pdev->dev, res); | 353 | apc->cfg_base = devm_ioremap_resource(&pdev->dev, res); |
367 | if (IS_ERR(apc->cfg_base)) | 354 | if (IS_ERR(apc->cfg_base)) |
diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c index 785b2659b519..b7a6fcbb8852 100644 --- a/arch/mips/pci/pci-ar724x.c +++ b/arch/mips/pci/pci-ar724x.c | |||
@@ -9,7 +9,6 @@ | |||
9 | * by the Free Software Foundation. | 9 | * by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/spinlock.h> | ||
13 | #include <linux/irq.h> | 12 | #include <linux/irq.h> |
14 | #include <linux/pci.h> | 13 | #include <linux/pci.h> |
15 | #include <linux/module.h> | 14 | #include <linux/module.h> |
@@ -48,8 +47,6 @@ struct ar724x_pci_controller { | |||
48 | bool bar0_is_cached; | 47 | bool bar0_is_cached; |
49 | u32 bar0_value; | 48 | u32 bar0_value; |
50 | 49 | ||
51 | spinlock_t lock; | ||
52 | |||
53 | struct pci_controller pci_controller; | 50 | struct pci_controller pci_controller; |
54 | struct resource io_res; | 51 | struct resource io_res; |
55 | struct resource mem_res; | 52 | struct resource mem_res; |
@@ -75,7 +72,6 @@ pci_bus_to_ar724x_controller(struct pci_bus *bus) | |||
75 | static int ar724x_pci_local_write(struct ar724x_pci_controller *apc, | 72 | static int ar724x_pci_local_write(struct ar724x_pci_controller *apc, |
76 | int where, int size, u32 value) | 73 | int where, int size, u32 value) |
77 | { | 74 | { |
78 | unsigned long flags; | ||
79 | void __iomem *base; | 75 | void __iomem *base; |
80 | u32 data; | 76 | u32 data; |
81 | int s; | 77 | int s; |
@@ -86,8 +82,6 @@ static int ar724x_pci_local_write(struct ar724x_pci_controller *apc, | |||
86 | return PCIBIOS_DEVICE_NOT_FOUND; | 82 | return PCIBIOS_DEVICE_NOT_FOUND; |
87 | 83 | ||
88 | base = apc->crp_base; | 84 | base = apc->crp_base; |
89 | |||
90 | spin_lock_irqsave(&apc->lock, flags); | ||
91 | data = __raw_readl(base + (where & ~3)); | 85 | data = __raw_readl(base + (where & ~3)); |
92 | 86 | ||
93 | switch (size) { | 87 | switch (size) { |
@@ -105,14 +99,12 @@ static int ar724x_pci_local_write(struct ar724x_pci_controller *apc, | |||
105 | data = value; | 99 | data = value; |
106 | break; | 100 | break; |
107 | default: | 101 | default: |
108 | spin_unlock_irqrestore(&apc->lock, flags); | ||
109 | return PCIBIOS_BAD_REGISTER_NUMBER; | 102 | return PCIBIOS_BAD_REGISTER_NUMBER; |
110 | } | 103 | } |
111 | 104 | ||
112 | __raw_writel(data, base + (where & ~3)); | 105 | __raw_writel(data, base + (where & ~3)); |
113 | /* flush write */ | 106 | /* flush write */ |
114 | __raw_readl(base + (where & ~3)); | 107 | __raw_readl(base + (where & ~3)); |
115 | spin_unlock_irqrestore(&apc->lock, flags); | ||
116 | 108 | ||
117 | return PCIBIOS_SUCCESSFUL; | 109 | return PCIBIOS_SUCCESSFUL; |
118 | } | 110 | } |
@@ -121,7 +113,6 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, | |||
121 | int size, uint32_t *value) | 113 | int size, uint32_t *value) |
122 | { | 114 | { |
123 | struct ar724x_pci_controller *apc; | 115 | struct ar724x_pci_controller *apc; |
124 | unsigned long flags; | ||
125 | void __iomem *base; | 116 | void __iomem *base; |
126 | u32 data; | 117 | u32 data; |
127 | 118 | ||
@@ -133,8 +124,6 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, | |||
133 | return PCIBIOS_DEVICE_NOT_FOUND; | 124 | return PCIBIOS_DEVICE_NOT_FOUND; |
134 | 125 | ||
135 | base = apc->devcfg_base; | 126 | base = apc->devcfg_base; |
136 | |||
137 | spin_lock_irqsave(&apc->lock, flags); | ||
138 | data = __raw_readl(base + (where & ~3)); | 127 | data = __raw_readl(base + (where & ~3)); |
139 | 128 | ||
140 | switch (size) { | 129 | switch (size) { |
@@ -153,13 +142,9 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, | |||
153 | case 4: | 142 | case 4: |
154 | break; | 143 | break; |
155 | default: | 144 | default: |
156 | spin_unlock_irqrestore(&apc->lock, flags); | ||
157 | |||
158 | return PCIBIOS_BAD_REGISTER_NUMBER; | 145 | return PCIBIOS_BAD_REGISTER_NUMBER; |
159 | } | 146 | } |
160 | 147 | ||
161 | spin_unlock_irqrestore(&apc->lock, flags); | ||
162 | |||
163 | if (where == PCI_BASE_ADDRESS_0 && size == 4 && | 148 | if (where == PCI_BASE_ADDRESS_0 && size == 4 && |
164 | apc->bar0_is_cached) { | 149 | apc->bar0_is_cached) { |
165 | /* use the cached value */ | 150 | /* use the cached value */ |
@@ -175,7 +160,6 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, | |||
175 | int size, uint32_t value) | 160 | int size, uint32_t value) |
176 | { | 161 | { |
177 | struct ar724x_pci_controller *apc; | 162 | struct ar724x_pci_controller *apc; |
178 | unsigned long flags; | ||
179 | void __iomem *base; | 163 | void __iomem *base; |
180 | u32 data; | 164 | u32 data; |
181 | int s; | 165 | int s; |
@@ -209,8 +193,6 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, | |||
209 | } | 193 | } |
210 | 194 | ||
211 | base = apc->devcfg_base; | 195 | base = apc->devcfg_base; |
212 | |||
213 | spin_lock_irqsave(&apc->lock, flags); | ||
214 | data = __raw_readl(base + (where & ~3)); | 196 | data = __raw_readl(base + (where & ~3)); |
215 | 197 | ||
216 | switch (size) { | 198 | switch (size) { |
@@ -228,15 +210,12 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, | |||
228 | data = value; | 210 | data = value; |
229 | break; | 211 | break; |
230 | default: | 212 | default: |
231 | spin_unlock_irqrestore(&apc->lock, flags); | ||
232 | |||
233 | return PCIBIOS_BAD_REGISTER_NUMBER; | 213 | return PCIBIOS_BAD_REGISTER_NUMBER; |
234 | } | 214 | } |
235 | 215 | ||
236 | __raw_writel(data, base + (where & ~3)); | 216 | __raw_writel(data, base + (where & ~3)); |
237 | /* flush write */ | 217 | /* flush write */ |
238 | __raw_readl(base + (where & ~3)); | 218 | __raw_readl(base + (where & ~3)); |
239 | spin_unlock_irqrestore(&apc->lock, flags); | ||
240 | 219 | ||
241 | return PCIBIOS_SUCCESSFUL; | 220 | return PCIBIOS_SUCCESSFUL; |
242 | } | 221 | } |
@@ -380,8 +359,6 @@ static int ar724x_pci_probe(struct platform_device *pdev) | |||
380 | if (apc->irq < 0) | 359 | if (apc->irq < 0) |
381 | return -EINVAL; | 360 | return -EINVAL; |
382 | 361 | ||
383 | spin_lock_init(&apc->lock); | ||
384 | |||
385 | res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base"); | 362 | res = platform_get_resource_byname(pdev, IORESOURCE_IO, "io_base"); |
386 | if (!res) | 363 | if (!res) |
387 | return -EINVAL; | 364 | return -EINVAL; |
diff --git a/arch/mips/pci/pci-rt2880.c b/arch/mips/pci/pci-rt2880.c new file mode 100644 index 000000000000..a4574947e698 --- /dev/null +++ b/arch/mips/pci/pci-rt2880.c | |||
@@ -0,0 +1,285 @@ | |||
1 | /* | ||
2 | * Ralink RT288x SoC PCI register definitions | ||
3 | * | ||
4 | * Copyright (C) 2009 John Crispin <blogic@openwrt.org> | ||
5 | * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org> | ||
6 | * | ||
7 | * Parts of this file are based on Ralink's 2.6.21 BSP | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License version 2 as published | ||
11 | * by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/types.h> | ||
15 | #include <linux/pci.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/of_platform.h> | ||
20 | #include <linux/of_irq.h> | ||
21 | #include <linux/of_pci.h> | ||
22 | |||
23 | #include <asm/mach-ralink/rt288x.h> | ||
24 | |||
25 | #define RT2880_PCI_BASE 0x00440000 | ||
26 | #define RT288X_CPU_IRQ_PCI 4 | ||
27 | |||
28 | #define RT2880_PCI_MEM_BASE 0x20000000 | ||
29 | #define RT2880_PCI_MEM_SIZE 0x10000000 | ||
30 | #define RT2880_PCI_IO_BASE 0x00460000 | ||
31 | #define RT2880_PCI_IO_SIZE 0x00010000 | ||
32 | |||
33 | #define RT2880_PCI_REG_PCICFG_ADDR 0x00 | ||
34 | #define RT2880_PCI_REG_PCIMSK_ADDR 0x0c | ||
35 | #define RT2880_PCI_REG_BAR0SETUP_ADDR 0x10 | ||
36 | #define RT2880_PCI_REG_IMBASEBAR0_ADDR 0x18 | ||
37 | #define RT2880_PCI_REG_CONFIG_ADDR 0x20 | ||
38 | #define RT2880_PCI_REG_CONFIG_DATA 0x24 | ||
39 | #define RT2880_PCI_REG_MEMBASE 0x28 | ||
40 | #define RT2880_PCI_REG_IOBASE 0x2c | ||
41 | #define RT2880_PCI_REG_ID 0x30 | ||
42 | #define RT2880_PCI_REG_CLASS 0x34 | ||
43 | #define RT2880_PCI_REG_SUBID 0x38 | ||
44 | #define RT2880_PCI_REG_ARBCTL 0x80 | ||
45 | |||
46 | static void __iomem *rt2880_pci_base; | ||
47 | static DEFINE_SPINLOCK(rt2880_pci_lock); | ||
48 | |||
49 | static u32 rt2880_pci_reg_read(u32 reg) | ||
50 | { | ||
51 | return readl(rt2880_pci_base + reg); | ||
52 | } | ||
53 | |||
54 | static void rt2880_pci_reg_write(u32 val, u32 reg) | ||
55 | { | ||
56 | writel(val, rt2880_pci_base + reg); | ||
57 | } | ||
58 | |||
59 | static inline u32 rt2880_pci_get_cfgaddr(unsigned int bus, unsigned int slot, | ||
60 | unsigned int func, unsigned int where) | ||
61 | { | ||
62 | return ((bus << 16) | (slot << 11) | (func << 8) | (where & 0xfc) | | ||
63 | 0x80000000); | ||
64 | } | ||
65 | |||
66 | static int rt2880_pci_config_read(struct pci_bus *bus, unsigned int devfn, | ||
67 | int where, int size, u32 *val) | ||
68 | { | ||
69 | unsigned long flags; | ||
70 | u32 address; | ||
71 | u32 data; | ||
72 | |||
73 | address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), | ||
74 | PCI_FUNC(devfn), where); | ||
75 | |||
76 | spin_lock_irqsave(&rt2880_pci_lock, flags); | ||
77 | rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); | ||
78 | data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA); | ||
79 | spin_unlock_irqrestore(&rt2880_pci_lock, flags); | ||
80 | |||
81 | switch (size) { | ||
82 | case 1: | ||
83 | *val = (data >> ((where & 3) << 3)) & 0xff; | ||
84 | break; | ||
85 | case 2: | ||
86 | *val = (data >> ((where & 3) << 3)) & 0xffff; | ||
87 | break; | ||
88 | case 4: | ||
89 | *val = data; | ||
90 | break; | ||
91 | } | ||
92 | |||
93 | return PCIBIOS_SUCCESSFUL; | ||
94 | } | ||
95 | |||
96 | static int rt2880_pci_config_write(struct pci_bus *bus, unsigned int devfn, | ||
97 | int where, int size, u32 val) | ||
98 | { | ||
99 | unsigned long flags; | ||
100 | u32 address; | ||
101 | u32 data; | ||
102 | |||
103 | address = rt2880_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), | ||
104 | PCI_FUNC(devfn), where); | ||
105 | |||
106 | spin_lock_irqsave(&rt2880_pci_lock, flags); | ||
107 | rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); | ||
108 | data = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA); | ||
109 | |||
110 | switch (size) { | ||
111 | case 1: | ||
112 | data = (data & ~(0xff << ((where & 3) << 3))) | | ||
113 | (val << ((where & 3) << 3)); | ||
114 | break; | ||
115 | case 2: | ||
116 | data = (data & ~(0xffff << ((where & 3) << 3))) | | ||
117 | (val << ((where & 3) << 3)); | ||
118 | break; | ||
119 | case 4: | ||
120 | data = val; | ||
121 | break; | ||
122 | } | ||
123 | |||
124 | rt2880_pci_reg_write(data, RT2880_PCI_REG_CONFIG_DATA); | ||
125 | spin_unlock_irqrestore(&rt2880_pci_lock, flags); | ||
126 | |||
127 | return PCIBIOS_SUCCESSFUL; | ||
128 | } | ||
129 | |||
130 | static struct pci_ops rt2880_pci_ops = { | ||
131 | .read = rt2880_pci_config_read, | ||
132 | .write = rt2880_pci_config_write, | ||
133 | }; | ||
134 | |||
135 | static struct resource rt2880_pci_mem_resource = { | ||
136 | .name = "PCI MEM space", | ||
137 | .start = RT2880_PCI_MEM_BASE, | ||
138 | .end = RT2880_PCI_MEM_BASE + RT2880_PCI_MEM_SIZE - 1, | ||
139 | .flags = IORESOURCE_MEM, | ||
140 | }; | ||
141 | |||
142 | static struct resource rt2880_pci_io_resource = { | ||
143 | .name = "PCI IO space", | ||
144 | .start = RT2880_PCI_IO_BASE, | ||
145 | .end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1, | ||
146 | .flags = IORESOURCE_IO, | ||
147 | }; | ||
148 | |||
149 | static struct pci_controller rt2880_pci_controller = { | ||
150 | .pci_ops = &rt2880_pci_ops, | ||
151 | .mem_resource = &rt2880_pci_mem_resource, | ||
152 | .io_resource = &rt2880_pci_io_resource, | ||
153 | }; | ||
154 | |||
155 | static inline u32 rt2880_pci_read_u32(unsigned long reg) | ||
156 | { | ||
157 | unsigned long flags; | ||
158 | u32 address; | ||
159 | u32 ret; | ||
160 | |||
161 | address = rt2880_pci_get_cfgaddr(0, 0, 0, reg); | ||
162 | |||
163 | spin_lock_irqsave(&rt2880_pci_lock, flags); | ||
164 | rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); | ||
165 | ret = rt2880_pci_reg_read(RT2880_PCI_REG_CONFIG_DATA); | ||
166 | spin_unlock_irqrestore(&rt2880_pci_lock, flags); | ||
167 | |||
168 | return ret; | ||
169 | } | ||
170 | |||
171 | static inline void rt2880_pci_write_u32(unsigned long reg, u32 val) | ||
172 | { | ||
173 | unsigned long flags; | ||
174 | u32 address; | ||
175 | |||
176 | address = rt2880_pci_get_cfgaddr(0, 0, 0, reg); | ||
177 | |||
178 | spin_lock_irqsave(&rt2880_pci_lock, flags); | ||
179 | rt2880_pci_reg_write(address, RT2880_PCI_REG_CONFIG_ADDR); | ||
180 | rt2880_pci_reg_write(val, RT2880_PCI_REG_CONFIG_DATA); | ||
181 | spin_unlock_irqrestore(&rt2880_pci_lock, flags); | ||
182 | } | ||
183 | |||
184 | int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | ||
185 | { | ||
186 | u16 cmd; | ||
187 | int irq = -1; | ||
188 | |||
189 | if (dev->bus->number != 0) | ||
190 | return irq; | ||
191 | |||
192 | switch (PCI_SLOT(dev->devfn)) { | ||
193 | case 0x00: | ||
194 | rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000); | ||
195 | (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0); | ||
196 | break; | ||
197 | case 0x11: | ||
198 | irq = RT288X_CPU_IRQ_PCI; | ||
199 | break; | ||
200 | default: | ||
201 | pr_err("%s:%s[%d] trying to alloc unknown pci irq\n", | ||
202 | __FILE__, __func__, __LINE__); | ||
203 | BUG(); | ||
204 | break; | ||
205 | } | ||
206 | |||
207 | pci_write_config_byte((struct pci_dev *) dev, | ||
208 | PCI_CACHE_LINE_SIZE, 0x14); | ||
209 | pci_write_config_byte((struct pci_dev *) dev, PCI_LATENCY_TIMER, 0xFF); | ||
210 | pci_read_config_word((struct pci_dev *) dev, PCI_COMMAND, &cmd); | ||
211 | cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | | ||
212 | PCI_COMMAND_INVALIDATE | PCI_COMMAND_FAST_BACK | | ||
213 | PCI_COMMAND_SERR | PCI_COMMAND_WAIT | PCI_COMMAND_PARITY; | ||
214 | pci_write_config_word((struct pci_dev *) dev, PCI_COMMAND, cmd); | ||
215 | pci_write_config_byte((struct pci_dev *) dev, PCI_INTERRUPT_LINE, | ||
216 | dev->irq); | ||
217 | return irq; | ||
218 | } | ||
219 | |||
220 | static int rt288x_pci_probe(struct platform_device *pdev) | ||
221 | { | ||
222 | void __iomem *io_map_base; | ||
223 | int i; | ||
224 | |||
225 | rt2880_pci_base = ioremap_nocache(RT2880_PCI_BASE, PAGE_SIZE); | ||
226 | |||
227 | io_map_base = ioremap(RT2880_PCI_IO_BASE, RT2880_PCI_IO_SIZE); | ||
228 | rt2880_pci_controller.io_map_base = (unsigned long) io_map_base; | ||
229 | set_io_port_base((unsigned long) io_map_base); | ||
230 | |||
231 | ioport_resource.start = RT2880_PCI_IO_BASE; | ||
232 | ioport_resource.end = RT2880_PCI_IO_BASE + RT2880_PCI_IO_SIZE - 1; | ||
233 | |||
234 | rt2880_pci_reg_write(0, RT2880_PCI_REG_PCICFG_ADDR); | ||
235 | for (i = 0; i < 0xfffff; i++) | ||
236 | ; | ||
237 | |||
238 | rt2880_pci_reg_write(0x79, RT2880_PCI_REG_ARBCTL); | ||
239 | rt2880_pci_reg_write(0x07FF0001, RT2880_PCI_REG_BAR0SETUP_ADDR); | ||
240 | rt2880_pci_reg_write(RT2880_PCI_MEM_BASE, RT2880_PCI_REG_MEMBASE); | ||
241 | rt2880_pci_reg_write(RT2880_PCI_IO_BASE, RT2880_PCI_REG_IOBASE); | ||
242 | rt2880_pci_reg_write(0x08000000, RT2880_PCI_REG_IMBASEBAR0_ADDR); | ||
243 | rt2880_pci_reg_write(0x08021814, RT2880_PCI_REG_ID); | ||
244 | rt2880_pci_reg_write(0x00800001, RT2880_PCI_REG_CLASS); | ||
245 | rt2880_pci_reg_write(0x28801814, RT2880_PCI_REG_SUBID); | ||
246 | rt2880_pci_reg_write(0x000c0000, RT2880_PCI_REG_PCIMSK_ADDR); | ||
247 | |||
248 | rt2880_pci_write_u32(PCI_BASE_ADDRESS_0, 0x08000000); | ||
249 | (void) rt2880_pci_read_u32(PCI_BASE_ADDRESS_0); | ||
250 | |||
251 | register_pci_controller(&rt2880_pci_controller); | ||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | int pcibios_plat_dev_init(struct pci_dev *dev) | ||
256 | { | ||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | static const struct of_device_id rt288x_pci_match[] = { | ||
261 | { .compatible = "ralink,rt288x-pci" }, | ||
262 | {}, | ||
263 | }; | ||
264 | MODULE_DEVICE_TABLE(of, rt288x_pci_match); | ||
265 | |||
266 | static struct platform_driver rt288x_pci_driver = { | ||
267 | .probe = rt288x_pci_probe, | ||
268 | .driver = { | ||
269 | .name = "rt288x-pci", | ||
270 | .owner = THIS_MODULE, | ||
271 | .of_match_table = rt288x_pci_match, | ||
272 | }, | ||
273 | }; | ||
274 | |||
275 | int __init pcibios_init(void) | ||
276 | { | ||
277 | int ret = platform_driver_register(&rt288x_pci_driver); | ||
278 | |||
279 | if (ret) | ||
280 | pr_info("rt288x-pci: Error registering platform driver!"); | ||
281 | |||
282 | return ret; | ||
283 | } | ||
284 | |||
285 | arch_initcall(pcibios_init); | ||
diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c index 72919aeef42b..0bcc0b1cfddc 100644 --- a/arch/mips/pci/pci-rt3883.c +++ b/arch/mips/pci/pci-rt3883.c | |||
@@ -61,7 +61,6 @@ | |||
61 | 61 | ||
62 | struct rt3883_pci_controller { | 62 | struct rt3883_pci_controller { |
63 | void __iomem *base; | 63 | void __iomem *base; |
64 | spinlock_t lock; | ||
65 | 64 | ||
66 | struct device_node *intc_of_node; | 65 | struct device_node *intc_of_node; |
67 | struct irq_domain *irq_domain; | 66 | struct irq_domain *irq_domain; |
@@ -111,10 +110,8 @@ static u32 rt3883_pci_read_cfg32(struct rt3883_pci_controller *rpc, | |||
111 | 110 | ||
112 | address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); | 111 | address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); |
113 | 112 | ||
114 | spin_lock_irqsave(&rpc->lock, flags); | ||
115 | rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); | 113 | rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); |
116 | ret = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); | 114 | ret = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); |
117 | spin_unlock_irqrestore(&rpc->lock, flags); | ||
118 | 115 | ||
119 | return ret; | 116 | return ret; |
120 | } | 117 | } |
@@ -128,10 +125,8 @@ static void rt3883_pci_write_cfg32(struct rt3883_pci_controller *rpc, | |||
128 | 125 | ||
129 | address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); | 126 | address = rt3883_pci_get_cfgaddr(bus, slot, func, reg); |
130 | 127 | ||
131 | spin_lock_irqsave(&rpc->lock, flags); | ||
132 | rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); | 128 | rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); |
133 | rt3883_pci_w32(rpc, val, RT3883_PCI_REG_CFGDATA); | 129 | rt3883_pci_w32(rpc, val, RT3883_PCI_REG_CFGDATA); |
134 | spin_unlock_irqrestore(&rpc->lock, flags); | ||
135 | } | 130 | } |
136 | 131 | ||
137 | static void rt3883_pci_irq_handler(unsigned int irq, struct irq_desc *desc) | 132 | static void rt3883_pci_irq_handler(unsigned int irq, struct irq_desc *desc) |
@@ -252,10 +247,8 @@ static int rt3883_pci_config_read(struct pci_bus *bus, unsigned int devfn, | |||
252 | address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), | 247 | address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), |
253 | PCI_FUNC(devfn), where); | 248 | PCI_FUNC(devfn), where); |
254 | 249 | ||
255 | spin_lock_irqsave(&rpc->lock, flags); | ||
256 | rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); | 250 | rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); |
257 | data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); | 251 | data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); |
258 | spin_unlock_irqrestore(&rpc->lock, flags); | ||
259 | 252 | ||
260 | switch (size) { | 253 | switch (size) { |
261 | case 1: | 254 | case 1: |
@@ -288,7 +281,6 @@ static int rt3883_pci_config_write(struct pci_bus *bus, unsigned int devfn, | |||
288 | address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), | 281 | address = rt3883_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), |
289 | PCI_FUNC(devfn), where); | 282 | PCI_FUNC(devfn), where); |
290 | 283 | ||
291 | spin_lock_irqsave(&rpc->lock, flags); | ||
292 | rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); | 284 | rt3883_pci_w32(rpc, address, RT3883_PCI_REG_CFGADDR); |
293 | data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); | 285 | data = rt3883_pci_r32(rpc, RT3883_PCI_REG_CFGDATA); |
294 | 286 | ||
@@ -307,7 +299,6 @@ static int rt3883_pci_config_write(struct pci_bus *bus, unsigned int devfn, | |||
307 | } | 299 | } |
308 | 300 | ||
309 | rt3883_pci_w32(rpc, data, RT3883_PCI_REG_CFGDATA); | 301 | rt3883_pci_w32(rpc, data, RT3883_PCI_REG_CFGDATA); |
310 | spin_unlock_irqrestore(&rpc->lock, flags); | ||
311 | 302 | ||
312 | return PCIBIOS_SUCCESSFUL; | 303 | return PCIBIOS_SUCCESSFUL; |
313 | } | 304 | } |
diff --git a/arch/mips/pci/pci-tx4939.c b/arch/mips/pci/pci-tx4939.c index c10fbf2a19dc..cd8ed09c4f53 100644 --- a/arch/mips/pci/pci-tx4939.c +++ b/arch/mips/pci/pci-tx4939.c | |||
@@ -103,5 +103,5 @@ void __init tx4939_setup_pcierr_irq(void) | |||
103 | tx4927_pcierr_interrupt, | 103 | tx4927_pcierr_interrupt, |
104 | 0, "PCI error", | 104 | 0, "PCI error", |
105 | (void *)TX4939_PCIC_REG)) | 105 | (void *)TX4939_PCIC_REG)) |
106 | pr_warning("Failed to request irq for PCIERR\n"); | 106 | pr_warn("Failed to request irq for PCIERR\n"); |
107 | } | 107 | } |
diff --git a/arch/mips/pmcs-msp71xx/msp_prom.c b/arch/mips/pmcs-msp71xx/msp_prom.c index 1c9897531660..ef620a4c82a5 100644 --- a/arch/mips/pmcs-msp71xx/msp_prom.c +++ b/arch/mips/pmcs-msp71xx/msp_prom.c | |||
@@ -295,7 +295,7 @@ char *prom_getenv(char *env_name) | |||
295 | 295 | ||
296 | while (*var) { | 296 | while (*var) { |
297 | if (strncmp(env_name, *var, i) == 0) { | 297 | if (strncmp(env_name, *var, i) == 0) { |
298 | return (*var + strlen(env_name) + 1); | 298 | return *var + strlen(env_name) + 1; |
299 | } | 299 | } |
300 | var++; | 300 | var++; |
301 | } | 301 | } |
diff --git a/arch/mips/ralink/Kconfig b/arch/mips/ralink/Kconfig index 77e8a9620e18..b1c52ca580f9 100644 --- a/arch/mips/ralink/Kconfig +++ b/arch/mips/ralink/Kconfig | |||
@@ -16,6 +16,7 @@ choice | |||
16 | config SOC_RT288X | 16 | config SOC_RT288X |
17 | bool "RT288x" | 17 | bool "RT288x" |
18 | select MIPS_L1_CACHE_SHIFT_4 | 18 | select MIPS_L1_CACHE_SHIFT_4 |
19 | select HW_HAS_PCI | ||
19 | 20 | ||
20 | config SOC_RT305X | 21 | config SOC_RT305X |
21 | bool "RT305x" | 22 | bool "RT305x" |
@@ -26,7 +27,7 @@ choice | |||
26 | select HW_HAS_PCI | 27 | select HW_HAS_PCI |
27 | 28 | ||
28 | config SOC_MT7620 | 29 | config SOC_MT7620 |
29 | bool "MT7620" | 30 | bool "MT7620/8" |
30 | 31 | ||
31 | endchoice | 32 | endchoice |
32 | 33 | ||
diff --git a/arch/mips/ralink/Makefile b/arch/mips/ralink/Makefile index 2c09c8aa0ae2..a6c9d0061326 100644 --- a/arch/mips/ralink/Makefile +++ b/arch/mips/ralink/Makefile | |||
@@ -10,9 +10,13 @@ obj-y := prom.o of.o reset.o clk.o irq.o timer.o | |||
10 | 10 | ||
11 | obj-$(CONFIG_CLKEVT_RT3352) += cevt-rt3352.o | 11 | obj-$(CONFIG_CLKEVT_RT3352) += cevt-rt3352.o |
12 | 12 | ||
13 | obj-$(CONFIG_RALINK_ILL_ACC) += ill_acc.o | ||
14 | |||
13 | obj-$(CONFIG_SOC_RT288X) += rt288x.o | 15 | obj-$(CONFIG_SOC_RT288X) += rt288x.o |
14 | obj-$(CONFIG_SOC_RT305X) += rt305x.o | 16 | obj-$(CONFIG_SOC_RT305X) += rt305x.o |
15 | obj-$(CONFIG_SOC_RT3883) += rt3883.o | 17 | obj-$(CONFIG_SOC_RT3883) += rt3883.o |
16 | obj-$(CONFIG_SOC_MT7620) += mt7620.o | 18 | obj-$(CONFIG_SOC_MT7620) += mt7620.o |
17 | 19 | ||
18 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 20 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
21 | |||
22 | obj-$(CONFIG_DEBUG_FS) += bootrom.o | ||
diff --git a/arch/mips/ralink/bootrom.c b/arch/mips/ralink/bootrom.c new file mode 100644 index 000000000000..5403468394fb --- /dev/null +++ b/arch/mips/ralink/bootrom.c | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/debugfs.h> | ||
10 | #include <linux/seq_file.h> | ||
11 | |||
12 | #define BOOTROM_OFFSET 0x10118000 | ||
13 | #define BOOTROM_SIZE 0x8000 | ||
14 | |||
15 | static void __iomem *membase = (void __iomem *) KSEG1ADDR(BOOTROM_OFFSET); | ||
16 | |||
17 | static int bootrom_show(struct seq_file *s, void *unused) | ||
18 | { | ||
19 | seq_write(s, membase, BOOTROM_SIZE); | ||
20 | |||
21 | return 0; | ||
22 | } | ||
23 | |||
24 | static int bootrom_open(struct inode *inode, struct file *file) | ||
25 | { | ||
26 | return single_open(file, bootrom_show, NULL); | ||
27 | } | ||
28 | |||
29 | static const struct file_operations bootrom_file_ops = { | ||
30 | .open = bootrom_open, | ||
31 | .read = seq_read, | ||
32 | .llseek = seq_lseek, | ||
33 | .release = single_release, | ||
34 | }; | ||
35 | |||
36 | static int bootrom_setup(void) | ||
37 | { | ||
38 | if (!debugfs_create_file("bootrom", 0444, | ||
39 | NULL, NULL, &bootrom_file_ops)) { | ||
40 | pr_err("Failed to create bootrom debugfs file\n"); | ||
41 | |||
42 | return -EINVAL; | ||
43 | } | ||
44 | |||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | postcore_initcall(bootrom_setup); | ||
diff --git a/arch/mips/ralink/clk.c b/arch/mips/ralink/clk.c index 5d0983d47161..feb5a9bf98b4 100644 --- a/arch/mips/ralink/clk.c +++ b/arch/mips/ralink/clk.c | |||
@@ -56,6 +56,12 @@ unsigned long clk_get_rate(struct clk *clk) | |||
56 | } | 56 | } |
57 | EXPORT_SYMBOL_GPL(clk_get_rate); | 57 | EXPORT_SYMBOL_GPL(clk_get_rate); |
58 | 58 | ||
59 | int clk_set_rate(struct clk *clk, unsigned long rate) | ||
60 | { | ||
61 | return -1; | ||
62 | } | ||
63 | EXPORT_SYMBOL_GPL(clk_set_rate); | ||
64 | |||
59 | void __init plat_time_init(void) | 65 | void __init plat_time_init(void) |
60 | { | 66 | { |
61 | struct clk *clk; | 67 | struct clk *clk; |
diff --git a/arch/mips/ralink/common.h b/arch/mips/ralink/common.h index 42dfd6100a2d..8e7d8e618fb9 100644 --- a/arch/mips/ralink/common.h +++ b/arch/mips/ralink/common.h | |||
@@ -11,25 +11,6 @@ | |||
11 | 11 | ||
12 | #define RAMIPS_SYS_TYPE_LEN 32 | 12 | #define RAMIPS_SYS_TYPE_LEN 32 |
13 | 13 | ||
14 | struct ralink_pinmux_grp { | ||
15 | const char *name; | ||
16 | u32 mask; | ||
17 | int gpio_first; | ||
18 | int gpio_last; | ||
19 | }; | ||
20 | |||
21 | struct ralink_pinmux { | ||
22 | struct ralink_pinmux_grp *mode; | ||
23 | struct ralink_pinmux_grp *uart; | ||
24 | int uart_shift; | ||
25 | u32 uart_mask; | ||
26 | void (*wdt_reset)(void); | ||
27 | struct ralink_pinmux_grp *pci; | ||
28 | int pci_shift; | ||
29 | u32 pci_mask; | ||
30 | }; | ||
31 | extern struct ralink_pinmux rt_gpio_pinmux; | ||
32 | |||
33 | struct ralink_soc_info { | 14 | struct ralink_soc_info { |
34 | unsigned char sys_type[RAMIPS_SYS_TYPE_LEN]; | 15 | unsigned char sys_type[RAMIPS_SYS_TYPE_LEN]; |
35 | unsigned char *compatible; | 16 | unsigned char *compatible; |
diff --git a/arch/mips/ralink/early_printk.c b/arch/mips/ralink/early_printk.c index b46d0419d09b..255d695ec8c6 100644 --- a/arch/mips/ralink/early_printk.c +++ b/arch/mips/ralink/early_printk.c | |||
@@ -12,21 +12,24 @@ | |||
12 | #include <asm/addrspace.h> | 12 | #include <asm/addrspace.h> |
13 | 13 | ||
14 | #ifdef CONFIG_SOC_RT288X | 14 | #ifdef CONFIG_SOC_RT288X |
15 | #define EARLY_UART_BASE 0x300c00 | 15 | #define EARLY_UART_BASE 0x300c00 |
16 | #define CHIPID_BASE 0x300004 | ||
17 | #elif defined(CONFIG_SOC_MT7621) | ||
18 | #define EARLY_UART_BASE 0x1E000c00 | ||
19 | #define CHIPID_BASE 0x1E000004 | ||
16 | #else | 20 | #else |
17 | #define EARLY_UART_BASE 0x10000c00 | 21 | #define EARLY_UART_BASE 0x10000c00 |
22 | #define CHIPID_BASE 0x10000004 | ||
18 | #endif | 23 | #endif |
19 | 24 | ||
20 | #define UART_REG_RX 0x00 | 25 | #define MT7628_CHIP_NAME1 0x20203832 |
21 | #define UART_REG_TX 0x04 | 26 | |
22 | #define UART_REG_IER 0x08 | 27 | #define UART_REG_TX 0x04 |
23 | #define UART_REG_IIR 0x0c | 28 | #define UART_REG_LSR 0x14 |
24 | #define UART_REG_FCR 0x10 | 29 | #define UART_REG_LSR_RT2880 0x1c |
25 | #define UART_REG_LCR 0x14 | ||
26 | #define UART_REG_MCR 0x18 | ||
27 | #define UART_REG_LSR 0x1c | ||
28 | 30 | ||
29 | static __iomem void *uart_membase = (__iomem void *) KSEG1ADDR(EARLY_UART_BASE); | 31 | static __iomem void *uart_membase = (__iomem void *) KSEG1ADDR(EARLY_UART_BASE); |
32 | static __iomem void *chipid_membase = (__iomem void *) KSEG1ADDR(CHIPID_BASE); | ||
30 | 33 | ||
31 | static inline void uart_w32(u32 val, unsigned reg) | 34 | static inline void uart_w32(u32 val, unsigned reg) |
32 | { | 35 | { |
@@ -38,11 +41,23 @@ static inline u32 uart_r32(unsigned reg) | |||
38 | return __raw_readl(uart_membase + reg); | 41 | return __raw_readl(uart_membase + reg); |
39 | } | 42 | } |
40 | 43 | ||
44 | static inline int soc_is_mt7628(void) | ||
45 | { | ||
46 | return IS_ENABLED(CONFIG_SOC_MT7620) && | ||
47 | (__raw_readl(chipid_membase) == MT7628_CHIP_NAME1); | ||
48 | } | ||
49 | |||
41 | void prom_putchar(unsigned char ch) | 50 | void prom_putchar(unsigned char ch) |
42 | { | 51 | { |
43 | while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0) | 52 | if (IS_ENABLED(CONFIG_SOC_MT7621) || soc_is_mt7628()) { |
44 | ; | 53 | uart_w32(ch, UART_TX); |
45 | uart_w32(ch, UART_REG_TX); | 54 | while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0) |
46 | while ((uart_r32(UART_REG_LSR) & UART_LSR_THRE) == 0) | 55 | ; |
47 | ; | 56 | } else { |
57 | while ((uart_r32(UART_REG_LSR_RT2880) & UART_LSR_THRE) == 0) | ||
58 | ; | ||
59 | uart_w32(ch, UART_REG_TX); | ||
60 | while ((uart_r32(UART_REG_LSR_RT2880) & UART_LSR_THRE) == 0) | ||
61 | ; | ||
62 | } | ||
48 | } | 63 | } |
diff --git a/arch/mips/ralink/ill_acc.c b/arch/mips/ralink/ill_acc.c new file mode 100644 index 000000000000..e20b02e3ae28 --- /dev/null +++ b/arch/mips/ralink/ill_acc.c | |||
@@ -0,0 +1,87 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2013 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/interrupt.h> | ||
10 | #include <linux/of_platform.h> | ||
11 | #include <linux/of_irq.h> | ||
12 | |||
13 | #include <asm/mach-ralink/ralink_regs.h> | ||
14 | |||
15 | #define REG_ILL_ACC_ADDR 0x10 | ||
16 | #define REG_ILL_ACC_TYPE 0x14 | ||
17 | |||
18 | #define ILL_INT_STATUS BIT(31) | ||
19 | #define ILL_ACC_WRITE BIT(30) | ||
20 | #define ILL_ACC_LEN_M 0xff | ||
21 | #define ILL_ACC_OFF_M 0xf | ||
22 | #define ILL_ACC_OFF_S 16 | ||
23 | #define ILL_ACC_ID_M 0x7 | ||
24 | #define ILL_ACC_ID_S 8 | ||
25 | |||
26 | #define DRV_NAME "ill_acc" | ||
27 | |||
28 | static const char * const ill_acc_ids[] = { | ||
29 | "cpu", "dma", "ppe", "pdma rx", "pdma tx", "pci/e", "wmac", "usb", | ||
30 | }; | ||
31 | |||
32 | static irqreturn_t ill_acc_irq_handler(int irq, void *_priv) | ||
33 | { | ||
34 | struct device *dev = (struct device *) _priv; | ||
35 | u32 addr = rt_memc_r32(REG_ILL_ACC_ADDR); | ||
36 | u32 type = rt_memc_r32(REG_ILL_ACC_TYPE); | ||
37 | |||
38 | dev_err(dev, "illegal %s access from %s - addr:0x%08x offset:%d len:%d\n", | ||
39 | (type & ILL_ACC_WRITE) ? ("write") : ("read"), | ||
40 | ill_acc_ids[(type >> ILL_ACC_ID_S) & ILL_ACC_ID_M], | ||
41 | addr, (type >> ILL_ACC_OFF_S) & ILL_ACC_OFF_M, | ||
42 | type & ILL_ACC_LEN_M); | ||
43 | |||
44 | rt_memc_w32(REG_ILL_ACC_TYPE, REG_ILL_ACC_TYPE); | ||
45 | |||
46 | return IRQ_HANDLED; | ||
47 | } | ||
48 | |||
49 | static int __init ill_acc_of_setup(void) | ||
50 | { | ||
51 | struct platform_device *pdev; | ||
52 | struct device_node *np; | ||
53 | int irq; | ||
54 | |||
55 | /* somehow this driver breaks on RT5350 */ | ||
56 | if (of_machine_is_compatible("ralink,rt5350-soc")) | ||
57 | return -EINVAL; | ||
58 | |||
59 | np = of_find_compatible_node(NULL, NULL, "ralink,rt3050-memc"); | ||
60 | if (!np) | ||
61 | return -EINVAL; | ||
62 | |||
63 | pdev = of_find_device_by_node(np); | ||
64 | if (!pdev) { | ||
65 | pr_err("%s: failed to lookup pdev\n", np->name); | ||
66 | return -EINVAL; | ||
67 | } | ||
68 | |||
69 | irq = irq_of_parse_and_map(np, 0); | ||
70 | if (!irq) { | ||
71 | dev_err(&pdev->dev, "failed to get irq\n"); | ||
72 | return -EINVAL; | ||
73 | } | ||
74 | |||
75 | if (request_irq(irq, ill_acc_irq_handler, 0, "ill_acc", &pdev->dev)) { | ||
76 | dev_err(&pdev->dev, "failed to request irq\n"); | ||
77 | return -EINVAL; | ||
78 | } | ||
79 | |||
80 | rt_memc_w32(ILL_INT_STATUS, REG_ILL_ACC_TYPE); | ||
81 | |||
82 | dev_info(&pdev->dev, "irq registered\n"); | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | arch_initcall(ill_acc_of_setup); | ||
diff --git a/arch/mips/ralink/irq.c b/arch/mips/ralink/irq.c index 781b3d14a489..7cf91b92e9d1 100644 --- a/arch/mips/ralink/irq.c +++ b/arch/mips/ralink/irq.c | |||
@@ -20,14 +20,6 @@ | |||
20 | 20 | ||
21 | #include "common.h" | 21 | #include "common.h" |
22 | 22 | ||
23 | /* INTC register offsets */ | ||
24 | #define INTC_REG_STATUS0 0x00 | ||
25 | #define INTC_REG_STATUS1 0x04 | ||
26 | #define INTC_REG_TYPE 0x20 | ||
27 | #define INTC_REG_RAW_STATUS 0x30 | ||
28 | #define INTC_REG_ENABLE 0x34 | ||
29 | #define INTC_REG_DISABLE 0x38 | ||
30 | |||
31 | #define INTC_INT_GLOBAL BIT(31) | 23 | #define INTC_INT_GLOBAL BIT(31) |
32 | 24 | ||
33 | #define RALINK_CPU_IRQ_INTC (MIPS_CPU_IRQ_BASE + 2) | 25 | #define RALINK_CPU_IRQ_INTC (MIPS_CPU_IRQ_BASE + 2) |
@@ -44,16 +36,36 @@ | |||
44 | 36 | ||
45 | #define RALINK_INTC_IRQ_PERFC (RALINK_INTC_IRQ_BASE + 9) | 37 | #define RALINK_INTC_IRQ_PERFC (RALINK_INTC_IRQ_BASE + 9) |
46 | 38 | ||
39 | enum rt_intc_regs_enum { | ||
40 | INTC_REG_STATUS0 = 0, | ||
41 | INTC_REG_STATUS1, | ||
42 | INTC_REG_TYPE, | ||
43 | INTC_REG_RAW_STATUS, | ||
44 | INTC_REG_ENABLE, | ||
45 | INTC_REG_DISABLE, | ||
46 | }; | ||
47 | |||
48 | static u32 rt_intc_regs[] = { | ||
49 | [INTC_REG_STATUS0] = 0x00, | ||
50 | [INTC_REG_STATUS1] = 0x04, | ||
51 | [INTC_REG_TYPE] = 0x20, | ||
52 | [INTC_REG_RAW_STATUS] = 0x30, | ||
53 | [INTC_REG_ENABLE] = 0x34, | ||
54 | [INTC_REG_DISABLE] = 0x38, | ||
55 | }; | ||
56 | |||
47 | static void __iomem *rt_intc_membase; | 57 | static void __iomem *rt_intc_membase; |
48 | 58 | ||
59 | static int rt_perfcount_irq; | ||
60 | |||
49 | static inline void rt_intc_w32(u32 val, unsigned reg) | 61 | static inline void rt_intc_w32(u32 val, unsigned reg) |
50 | { | 62 | { |
51 | __raw_writel(val, rt_intc_membase + reg); | 63 | __raw_writel(val, rt_intc_membase + rt_intc_regs[reg]); |
52 | } | 64 | } |
53 | 65 | ||
54 | static inline u32 rt_intc_r32(unsigned reg) | 66 | static inline u32 rt_intc_r32(unsigned reg) |
55 | { | 67 | { |
56 | return __raw_readl(rt_intc_membase + reg); | 68 | return __raw_readl(rt_intc_membase + rt_intc_regs[reg]); |
57 | } | 69 | } |
58 | 70 | ||
59 | static void ralink_intc_irq_unmask(struct irq_data *d) | 71 | static void ralink_intc_irq_unmask(struct irq_data *d) |
@@ -73,6 +85,11 @@ static struct irq_chip ralink_intc_irq_chip = { | |||
73 | .irq_mask_ack = ralink_intc_irq_mask, | 85 | .irq_mask_ack = ralink_intc_irq_mask, |
74 | }; | 86 | }; |
75 | 87 | ||
88 | int get_c0_perfcount_int(void) | ||
89 | { | ||
90 | return rt_perfcount_irq; | ||
91 | } | ||
92 | |||
76 | unsigned int get_c0_compare_int(void) | 93 | unsigned int get_c0_compare_int(void) |
77 | { | 94 | { |
78 | return CP0_LEGACY_COMPARE_IRQ; | 95 | return CP0_LEGACY_COMPARE_IRQ; |
@@ -134,6 +151,10 @@ static int __init intc_of_init(struct device_node *node, | |||
134 | struct irq_domain *domain; | 151 | struct irq_domain *domain; |
135 | int irq; | 152 | int irq; |
136 | 153 | ||
154 | if (!of_property_read_u32_array(node, "ralink,intc-registers", | ||
155 | rt_intc_regs, 6)) | ||
156 | pr_info("intc: using register map from devicetree\n"); | ||
157 | |||
137 | irq = irq_of_parse_and_map(node, 0); | 158 | irq = irq_of_parse_and_map(node, 0); |
138 | if (!irq) | 159 | if (!irq) |
139 | panic("Failed to get INTC IRQ"); | 160 | panic("Failed to get INTC IRQ"); |
@@ -167,13 +188,13 @@ static int __init intc_of_init(struct device_node *node, | |||
167 | irq_set_handler_data(irq, domain); | 188 | irq_set_handler_data(irq, domain); |
168 | 189 | ||
169 | /* tell the kernel which irq is used for performance monitoring */ | 190 | /* tell the kernel which irq is used for performance monitoring */ |
170 | cp0_perfcount_irq = irq_create_mapping(domain, 9); | 191 | rt_perfcount_irq = irq_create_mapping(domain, 9); |
171 | 192 | ||
172 | return 0; | 193 | return 0; |
173 | } | 194 | } |
174 | 195 | ||
175 | static struct of_device_id __initdata of_irq_ids[] = { | 196 | static struct of_device_id __initdata of_irq_ids[] = { |
176 | { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_intc_init }, | 197 | { .compatible = "mti,cpu-interrupt-controller", .data = mips_cpu_irq_of_init }, |
177 | { .compatible = "ralink,rt2880-intc", .data = intc_of_init }, | 198 | { .compatible = "ralink,rt2880-intc", .data = intc_of_init }, |
178 | {}, | 199 | {}, |
179 | }; | 200 | }; |
diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c index a3ad56c2372d..2ea5ff6dc22e 100644 --- a/arch/mips/ralink/mt7620.c +++ b/arch/mips/ralink/mt7620.c | |||
@@ -17,124 +17,214 @@ | |||
17 | #include <asm/mipsregs.h> | 17 | #include <asm/mipsregs.h> |
18 | #include <asm/mach-ralink/ralink_regs.h> | 18 | #include <asm/mach-ralink/ralink_regs.h> |
19 | #include <asm/mach-ralink/mt7620.h> | 19 | #include <asm/mach-ralink/mt7620.h> |
20 | #include <asm/mach-ralink/pinmux.h> | ||
20 | 21 | ||
21 | #include "common.h" | 22 | #include "common.h" |
22 | 23 | ||
24 | /* analog */ | ||
25 | #define PMU0_CFG 0x88 | ||
26 | #define PMU_SW_SET BIT(28) | ||
27 | #define A_DCDC_EN BIT(24) | ||
28 | #define A_SSC_PERI BIT(19) | ||
29 | #define A_SSC_GEN BIT(18) | ||
30 | #define A_SSC_M 0x3 | ||
31 | #define A_SSC_S 16 | ||
32 | #define A_DLY_M 0x7 | ||
33 | #define A_DLY_S 8 | ||
34 | #define A_VTUNE_M 0xff | ||
35 | |||
36 | /* digital */ | ||
37 | #define PMU1_CFG 0x8C | ||
38 | #define DIG_SW_SEL BIT(25) | ||
39 | |||
40 | /* is this a MT7620 or a MT7628 */ | ||
41 | enum mt762x_soc_type mt762x_soc; | ||
42 | |||
23 | /* does the board have sdram or ddram */ | 43 | /* does the board have sdram or ddram */ |
24 | static int dram_type; | 44 | static int dram_type; |
25 | 45 | ||
26 | static struct ralink_pinmux_grp mode_mux[] = { | 46 | static struct rt2880_pmx_func i2c_grp[] = { FUNC("i2c", 0, 1, 2) }; |
27 | { | 47 | static struct rt2880_pmx_func spi_grp[] = { FUNC("spi", 0, 3, 4) }; |
28 | .name = "i2c", | 48 | static struct rt2880_pmx_func uartlite_grp[] = { FUNC("uartlite", 0, 15, 2) }; |
29 | .mask = MT7620_GPIO_MODE_I2C, | 49 | static struct rt2880_pmx_func mdio_grp[] = { FUNC("mdio", 0, 22, 2) }; |
30 | .gpio_first = 1, | 50 | static struct rt2880_pmx_func rgmii1_grp[] = { FUNC("rgmii1", 0, 24, 12) }; |
31 | .gpio_last = 2, | 51 | static struct rt2880_pmx_func refclk_grp[] = { FUNC("spi refclk", 0, 37, 3) }; |
32 | }, { | 52 | static struct rt2880_pmx_func ephy_grp[] = { FUNC("ephy", 0, 40, 5) }; |
33 | .name = "spi", | 53 | static struct rt2880_pmx_func rgmii2_grp[] = { FUNC("rgmii2", 0, 60, 12) }; |
34 | .mask = MT7620_GPIO_MODE_SPI, | 54 | static struct rt2880_pmx_func wled_grp[] = { FUNC("wled", 0, 72, 1) }; |
35 | .gpio_first = 3, | 55 | static struct rt2880_pmx_func pa_grp[] = { FUNC("pa", 0, 18, 4) }; |
36 | .gpio_last = 6, | 56 | static struct rt2880_pmx_func uartf_grp[] = { |
37 | }, { | 57 | FUNC("uartf", MT7620_GPIO_MODE_UARTF, 7, 8), |
38 | .name = "uartlite", | 58 | FUNC("pcm uartf", MT7620_GPIO_MODE_PCM_UARTF, 7, 8), |
39 | .mask = MT7620_GPIO_MODE_UART1, | 59 | FUNC("pcm i2s", MT7620_GPIO_MODE_PCM_I2S, 7, 8), |
40 | .gpio_first = 15, | 60 | FUNC("i2s uartf", MT7620_GPIO_MODE_I2S_UARTF, 7, 8), |
41 | .gpio_last = 16, | 61 | FUNC("pcm gpio", MT7620_GPIO_MODE_PCM_GPIO, 11, 4), |
42 | }, { | 62 | FUNC("gpio uartf", MT7620_GPIO_MODE_GPIO_UARTF, 7, 4), |
43 | .name = "wdt", | 63 | FUNC("gpio i2s", MT7620_GPIO_MODE_GPIO_I2S, 7, 4), |
44 | .mask = MT7620_GPIO_MODE_WDT, | 64 | }; |
45 | .gpio_first = 17, | 65 | static struct rt2880_pmx_func wdt_grp[] = { |
46 | .gpio_last = 17, | 66 | FUNC("wdt rst", 0, 17, 1), |
47 | }, { | 67 | FUNC("wdt refclk", 0, 17, 1), |
48 | .name = "mdio", | 68 | }; |
49 | .mask = MT7620_GPIO_MODE_MDIO, | 69 | static struct rt2880_pmx_func pcie_rst_grp[] = { |
50 | .gpio_first = 22, | 70 | FUNC("pcie rst", MT7620_GPIO_MODE_PCIE_RST, 36, 1), |
51 | .gpio_last = 23, | 71 | FUNC("pcie refclk", MT7620_GPIO_MODE_PCIE_REF, 36, 1) |
52 | }, { | 72 | }; |
53 | .name = "rgmii1", | 73 | static struct rt2880_pmx_func nd_sd_grp[] = { |
54 | .mask = MT7620_GPIO_MODE_RGMII1, | 74 | FUNC("nand", MT7620_GPIO_MODE_NAND, 45, 15), |
55 | .gpio_first = 24, | 75 | FUNC("sd", MT7620_GPIO_MODE_SD, 45, 15) |
56 | .gpio_last = 35, | 76 | }; |
57 | }, { | 77 | |
58 | .name = "spi refclk", | 78 | static struct rt2880_pmx_group mt7620a_pinmux_data[] = { |
59 | .mask = MT7620_GPIO_MODE_SPI_REF_CLK, | 79 | GRP("i2c", i2c_grp, 1, MT7620_GPIO_MODE_I2C), |
60 | .gpio_first = 37, | 80 | GRP("uartf", uartf_grp, MT7620_GPIO_MODE_UART0_MASK, |
61 | .gpio_last = 39, | 81 | MT7620_GPIO_MODE_UART0_SHIFT), |
62 | }, { | 82 | GRP("spi", spi_grp, 1, MT7620_GPIO_MODE_SPI), |
63 | .name = "jtag", | 83 | GRP("uartlite", uartlite_grp, 1, MT7620_GPIO_MODE_UART1), |
64 | .mask = MT7620_GPIO_MODE_JTAG, | 84 | GRP_G("wdt", wdt_grp, MT7620_GPIO_MODE_WDT_MASK, |
65 | .gpio_first = 40, | 85 | MT7620_GPIO_MODE_WDT_GPIO, MT7620_GPIO_MODE_WDT_SHIFT), |
66 | .gpio_last = 44, | 86 | GRP("mdio", mdio_grp, 1, MT7620_GPIO_MODE_MDIO), |
67 | }, { | 87 | GRP("rgmii1", rgmii1_grp, 1, MT7620_GPIO_MODE_RGMII1), |
68 | /* shared lines with jtag */ | 88 | GRP("spi refclk", refclk_grp, 1, MT7620_GPIO_MODE_SPI_REF_CLK), |
69 | .name = "ephy", | 89 | GRP_G("pcie", pcie_rst_grp, MT7620_GPIO_MODE_PCIE_MASK, |
70 | .mask = MT7620_GPIO_MODE_EPHY, | 90 | MT7620_GPIO_MODE_PCIE_GPIO, MT7620_GPIO_MODE_PCIE_SHIFT), |
71 | .gpio_first = 40, | 91 | GRP_G("nd_sd", nd_sd_grp, MT7620_GPIO_MODE_ND_SD_MASK, |
72 | .gpio_last = 44, | 92 | MT7620_GPIO_MODE_ND_SD_GPIO, MT7620_GPIO_MODE_ND_SD_SHIFT), |
73 | }, { | 93 | GRP("rgmii2", rgmii2_grp, 1, MT7620_GPIO_MODE_RGMII2), |
74 | .name = "nand", | 94 | GRP("wled", wled_grp, 1, MT7620_GPIO_MODE_WLED), |
75 | .mask = MT7620_GPIO_MODE_JTAG, | 95 | GRP("ephy", ephy_grp, 1, MT7620_GPIO_MODE_EPHY), |
76 | .gpio_first = 45, | 96 | GRP("pa", pa_grp, 1, MT7620_GPIO_MODE_PA), |
77 | .gpio_last = 59, | 97 | { 0 } |
78 | }, { | 98 | }; |
79 | .name = "rgmii2", | 99 | |
80 | .mask = MT7620_GPIO_MODE_RGMII2, | 100 | static struct rt2880_pmx_func pwm1_grp_mt7628[] = { |
81 | .gpio_first = 60, | 101 | FUNC("sdcx", 3, 19, 1), |
82 | .gpio_last = 71, | 102 | FUNC("utif", 2, 19, 1), |
83 | }, { | 103 | FUNC("gpio", 1, 19, 1), |
84 | .name = "wled", | 104 | FUNC("pwm", 0, 19, 1), |
85 | .mask = MT7620_GPIO_MODE_WLED, | 105 | }; |
86 | .gpio_first = 72, | 106 | |
87 | .gpio_last = 72, | 107 | static struct rt2880_pmx_func pwm0_grp_mt7628[] = { |
88 | }, {0} | 108 | FUNC("sdcx", 3, 18, 1), |
109 | FUNC("utif", 2, 18, 1), | ||
110 | FUNC("gpio", 1, 18, 1), | ||
111 | FUNC("pwm", 0, 18, 1), | ||
112 | }; | ||
113 | |||
114 | static struct rt2880_pmx_func uart2_grp_mt7628[] = { | ||
115 | FUNC("sdcx", 3, 20, 2), | ||
116 | FUNC("pwm", 2, 20, 2), | ||
117 | FUNC("gpio", 1, 20, 2), | ||
118 | FUNC("uart", 0, 20, 2), | ||
119 | }; | ||
120 | |||
121 | static struct rt2880_pmx_func uart1_grp_mt7628[] = { | ||
122 | FUNC("sdcx", 3, 45, 2), | ||
123 | FUNC("pwm", 2, 45, 2), | ||
124 | FUNC("gpio", 1, 45, 2), | ||
125 | FUNC("uart", 0, 45, 2), | ||
126 | }; | ||
127 | |||
128 | static struct rt2880_pmx_func i2c_grp_mt7628[] = { | ||
129 | FUNC("-", 3, 4, 2), | ||
130 | FUNC("debug", 2, 4, 2), | ||
131 | FUNC("gpio", 1, 4, 2), | ||
132 | FUNC("i2c", 0, 4, 2), | ||
133 | }; | ||
134 | |||
135 | static struct rt2880_pmx_func refclk_grp_mt7628[] = { FUNC("reclk", 0, 36, 1) }; | ||
136 | static struct rt2880_pmx_func perst_grp_mt7628[] = { FUNC("perst", 0, 37, 1) }; | ||
137 | static struct rt2880_pmx_func wdt_grp_mt7628[] = { FUNC("wdt", 0, 15, 38) }; | ||
138 | static struct rt2880_pmx_func spi_grp_mt7628[] = { FUNC("spi", 0, 7, 4) }; | ||
139 | |||
140 | static struct rt2880_pmx_func sd_mode_grp_mt7628[] = { | ||
141 | FUNC("jtag", 3, 22, 8), | ||
142 | FUNC("utif", 2, 22, 8), | ||
143 | FUNC("gpio", 1, 22, 8), | ||
144 | FUNC("sdcx", 0, 22, 8), | ||
145 | }; | ||
146 | |||
147 | static struct rt2880_pmx_func uart0_grp_mt7628[] = { | ||
148 | FUNC("-", 3, 12, 2), | ||
149 | FUNC("-", 2, 12, 2), | ||
150 | FUNC("gpio", 1, 12, 2), | ||
151 | FUNC("uart", 0, 12, 2), | ||
152 | }; | ||
153 | |||
154 | static struct rt2880_pmx_func i2s_grp_mt7628[] = { | ||
155 | FUNC("antenna", 3, 0, 4), | ||
156 | FUNC("pcm", 2, 0, 4), | ||
157 | FUNC("gpio", 1, 0, 4), | ||
158 | FUNC("i2s", 0, 0, 4), | ||
159 | }; | ||
160 | |||
161 | static struct rt2880_pmx_func spi_cs1_grp_mt7628[] = { | ||
162 | FUNC("-", 3, 6, 1), | ||
163 | FUNC("refclk", 2, 6, 1), | ||
164 | FUNC("gpio", 1, 6, 1), | ||
165 | FUNC("spi", 0, 6, 1), | ||
166 | }; | ||
167 | |||
168 | static struct rt2880_pmx_func spis_grp_mt7628[] = { | ||
169 | FUNC("pwm", 3, 14, 4), | ||
170 | FUNC("util", 2, 14, 4), | ||
171 | FUNC("gpio", 1, 14, 4), | ||
172 | FUNC("spis", 0, 14, 4), | ||
89 | }; | 173 | }; |
90 | 174 | ||
91 | static struct ralink_pinmux_grp uart_mux[] = { | 175 | static struct rt2880_pmx_func gpio_grp_mt7628[] = { |
92 | { | 176 | FUNC("pcie", 3, 11, 1), |
93 | .name = "uartf", | 177 | FUNC("refclk", 2, 11, 1), |
94 | .mask = MT7620_GPIO_MODE_UARTF, | 178 | FUNC("gpio", 1, 11, 1), |
95 | .gpio_first = 7, | 179 | FUNC("gpio", 0, 11, 1), |
96 | .gpio_last = 14, | ||
97 | }, { | ||
98 | .name = "pcm uartf", | ||
99 | .mask = MT7620_GPIO_MODE_PCM_UARTF, | ||
100 | .gpio_first = 7, | ||
101 | .gpio_last = 14, | ||
102 | }, { | ||
103 | .name = "pcm i2s", | ||
104 | .mask = MT7620_GPIO_MODE_PCM_I2S, | ||
105 | .gpio_first = 7, | ||
106 | .gpio_last = 14, | ||
107 | }, { | ||
108 | .name = "i2s uartf", | ||
109 | .mask = MT7620_GPIO_MODE_I2S_UARTF, | ||
110 | .gpio_first = 7, | ||
111 | .gpio_last = 14, | ||
112 | }, { | ||
113 | .name = "pcm gpio", | ||
114 | .mask = MT7620_GPIO_MODE_PCM_GPIO, | ||
115 | .gpio_first = 11, | ||
116 | .gpio_last = 14, | ||
117 | }, { | ||
118 | .name = "gpio uartf", | ||
119 | .mask = MT7620_GPIO_MODE_GPIO_UARTF, | ||
120 | .gpio_first = 7, | ||
121 | .gpio_last = 10, | ||
122 | }, { | ||
123 | .name = "gpio i2s", | ||
124 | .mask = MT7620_GPIO_MODE_GPIO_I2S, | ||
125 | .gpio_first = 7, | ||
126 | .gpio_last = 10, | ||
127 | }, { | ||
128 | .name = "gpio", | ||
129 | .mask = MT7620_GPIO_MODE_GPIO, | ||
130 | }, {0} | ||
131 | }; | 180 | }; |
132 | 181 | ||
133 | struct ralink_pinmux rt_gpio_pinmux = { | 182 | #define MT7628_GPIO_MODE_MASK 0x3 |
134 | .mode = mode_mux, | 183 | |
135 | .uart = uart_mux, | 184 | #define MT7628_GPIO_MODE_PWM1 30 |
136 | .uart_shift = MT7620_GPIO_MODE_UART0_SHIFT, | 185 | #define MT7628_GPIO_MODE_PWM0 28 |
137 | .uart_mask = MT7620_GPIO_MODE_UART0_MASK, | 186 | #define MT7628_GPIO_MODE_UART2 26 |
187 | #define MT7628_GPIO_MODE_UART1 24 | ||
188 | #define MT7628_GPIO_MODE_I2C 20 | ||
189 | #define MT7628_GPIO_MODE_REFCLK 18 | ||
190 | #define MT7628_GPIO_MODE_PERST 16 | ||
191 | #define MT7628_GPIO_MODE_WDT 14 | ||
192 | #define MT7628_GPIO_MODE_SPI 12 | ||
193 | #define MT7628_GPIO_MODE_SDMODE 10 | ||
194 | #define MT7628_GPIO_MODE_UART0 8 | ||
195 | #define MT7628_GPIO_MODE_I2S 6 | ||
196 | #define MT7628_GPIO_MODE_CS1 4 | ||
197 | #define MT7628_GPIO_MODE_SPIS 2 | ||
198 | #define MT7628_GPIO_MODE_GPIO 0 | ||
199 | |||
200 | static struct rt2880_pmx_group mt7628an_pinmux_data[] = { | ||
201 | GRP_G("pmw1", pwm1_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
202 | 1, MT7628_GPIO_MODE_PWM1), | ||
203 | GRP_G("pmw1", pwm0_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
204 | 1, MT7628_GPIO_MODE_PWM0), | ||
205 | GRP_G("uart2", uart2_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
206 | 1, MT7628_GPIO_MODE_UART2), | ||
207 | GRP_G("uart1", uart1_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
208 | 1, MT7628_GPIO_MODE_UART1), | ||
209 | GRP_G("i2c", i2c_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
210 | 1, MT7628_GPIO_MODE_I2C), | ||
211 | GRP("refclk", refclk_grp_mt7628, 1, MT7628_GPIO_MODE_REFCLK), | ||
212 | GRP("perst", perst_grp_mt7628, 1, MT7628_GPIO_MODE_PERST), | ||
213 | GRP("wdt", wdt_grp_mt7628, 1, MT7628_GPIO_MODE_WDT), | ||
214 | GRP("spi", spi_grp_mt7628, 1, MT7628_GPIO_MODE_SPI), | ||
215 | GRP_G("sdmode", sd_mode_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
216 | 1, MT7628_GPIO_MODE_SDMODE), | ||
217 | GRP_G("uart0", uart0_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
218 | 1, MT7628_GPIO_MODE_UART0), | ||
219 | GRP_G("i2s", i2s_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
220 | 1, MT7628_GPIO_MODE_I2S), | ||
221 | GRP_G("spi cs1", spi_cs1_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
222 | 1, MT7628_GPIO_MODE_CS1), | ||
223 | GRP_G("spis", spis_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
224 | 1, MT7628_GPIO_MODE_SPIS), | ||
225 | GRP_G("gpio", gpio_grp_mt7628, MT7628_GPIO_MODE_MASK, | ||
226 | 1, MT7628_GPIO_MODE_GPIO), | ||
227 | { 0 } | ||
138 | }; | 228 | }; |
139 | 229 | ||
140 | static __init u32 | 230 | static __init u32 |
@@ -287,29 +377,42 @@ void __init ralink_clk_init(void) | |||
287 | 377 | ||
288 | xtal_rate = mt7620_get_xtal_rate(); | 378 | xtal_rate = mt7620_get_xtal_rate(); |
289 | 379 | ||
290 | cpu_pll_rate = mt7620_get_cpu_pll_rate(xtal_rate); | ||
291 | pll_rate = mt7620_get_pll_rate(xtal_rate, cpu_pll_rate); | ||
292 | |||
293 | cpu_rate = mt7620_get_cpu_rate(pll_rate); | ||
294 | dram_rate = mt7620_get_dram_rate(pll_rate); | ||
295 | sys_rate = mt7620_get_sys_rate(cpu_rate); | ||
296 | periph_rate = mt7620_get_periph_rate(xtal_rate); | ||
297 | |||
298 | #define RFMT(label) label ":%lu.%03luMHz " | 380 | #define RFMT(label) label ":%lu.%03luMHz " |
299 | #define RINT(x) ((x) / 1000000) | 381 | #define RINT(x) ((x) / 1000000) |
300 | #define RFRAC(x) (((x) / 1000) % 1000) | 382 | #define RFRAC(x) (((x) / 1000) % 1000) |
301 | 383 | ||
302 | pr_debug(RFMT("XTAL") RFMT("CPU_PLL") RFMT("PLL"), | 384 | if (mt762x_soc == MT762X_SOC_MT7628AN) { |
303 | RINT(xtal_rate), RFRAC(xtal_rate), | 385 | if (xtal_rate == MHZ(40)) |
304 | RINT(cpu_pll_rate), RFRAC(cpu_pll_rate), | 386 | cpu_rate = MHZ(580); |
305 | RINT(pll_rate), RFRAC(pll_rate)); | 387 | else |
388 | cpu_rate = MHZ(575); | ||
389 | dram_rate = sys_rate = cpu_rate / 3; | ||
390 | periph_rate = MHZ(40); | ||
391 | |||
392 | ralink_clk_add("10000d00.uartlite", periph_rate); | ||
393 | ralink_clk_add("10000e00.uartlite", periph_rate); | ||
394 | } else { | ||
395 | cpu_pll_rate = mt7620_get_cpu_pll_rate(xtal_rate); | ||
396 | pll_rate = mt7620_get_pll_rate(xtal_rate, cpu_pll_rate); | ||
397 | |||
398 | cpu_rate = mt7620_get_cpu_rate(pll_rate); | ||
399 | dram_rate = mt7620_get_dram_rate(pll_rate); | ||
400 | sys_rate = mt7620_get_sys_rate(cpu_rate); | ||
401 | periph_rate = mt7620_get_periph_rate(xtal_rate); | ||
402 | |||
403 | pr_debug(RFMT("XTAL") RFMT("CPU_PLL") RFMT("PLL"), | ||
404 | RINT(xtal_rate), RFRAC(xtal_rate), | ||
405 | RINT(cpu_pll_rate), RFRAC(cpu_pll_rate), | ||
406 | RINT(pll_rate), RFRAC(pll_rate)); | ||
407 | |||
408 | ralink_clk_add("10000500.uart", periph_rate); | ||
409 | } | ||
306 | 410 | ||
307 | pr_debug(RFMT("CPU") RFMT("DRAM") RFMT("SYS") RFMT("PERIPH"), | 411 | pr_debug(RFMT("CPU") RFMT("DRAM") RFMT("SYS") RFMT("PERIPH"), |
308 | RINT(cpu_rate), RFRAC(cpu_rate), | 412 | RINT(cpu_rate), RFRAC(cpu_rate), |
309 | RINT(dram_rate), RFRAC(dram_rate), | 413 | RINT(dram_rate), RFRAC(dram_rate), |
310 | RINT(sys_rate), RFRAC(sys_rate), | 414 | RINT(sys_rate), RFRAC(sys_rate), |
311 | RINT(periph_rate), RFRAC(periph_rate)); | 415 | RINT(periph_rate), RFRAC(periph_rate)); |
312 | |||
313 | #undef RFRAC | 416 | #undef RFRAC |
314 | #undef RINT | 417 | #undef RINT |
315 | #undef RFMT | 418 | #undef RFMT |
@@ -317,9 +420,9 @@ void __init ralink_clk_init(void) | |||
317 | ralink_clk_add("cpu", cpu_rate); | 420 | ralink_clk_add("cpu", cpu_rate); |
318 | ralink_clk_add("10000100.timer", periph_rate); | 421 | ralink_clk_add("10000100.timer", periph_rate); |
319 | ralink_clk_add("10000120.watchdog", periph_rate); | 422 | ralink_clk_add("10000120.watchdog", periph_rate); |
320 | ralink_clk_add("10000500.uart", periph_rate); | ||
321 | ralink_clk_add("10000b00.spi", sys_rate); | 423 | ralink_clk_add("10000b00.spi", sys_rate); |
322 | ralink_clk_add("10000c00.uartlite", periph_rate); | 424 | ralink_clk_add("10000c00.uartlite", periph_rate); |
425 | ralink_clk_add("10180000.wmac", xtal_rate); | ||
323 | } | 426 | } |
324 | 427 | ||
325 | void __init ralink_of_remap(void) | 428 | void __init ralink_of_remap(void) |
@@ -331,6 +434,52 @@ void __init ralink_of_remap(void) | |||
331 | panic("Failed to remap core resources"); | 434 | panic("Failed to remap core resources"); |
332 | } | 435 | } |
333 | 436 | ||
437 | static __init void | ||
438 | mt7620_dram_init(struct ralink_soc_info *soc_info) | ||
439 | { | ||
440 | switch (dram_type) { | ||
441 | case SYSCFG0_DRAM_TYPE_SDRAM: | ||
442 | pr_info("Board has SDRAM\n"); | ||
443 | soc_info->mem_size_min = MT7620_SDRAM_SIZE_MIN; | ||
444 | soc_info->mem_size_max = MT7620_SDRAM_SIZE_MAX; | ||
445 | break; | ||
446 | |||
447 | case SYSCFG0_DRAM_TYPE_DDR1: | ||
448 | pr_info("Board has DDR1\n"); | ||
449 | soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN; | ||
450 | soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX; | ||
451 | break; | ||
452 | |||
453 | case SYSCFG0_DRAM_TYPE_DDR2: | ||
454 | pr_info("Board has DDR2\n"); | ||
455 | soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN; | ||
456 | soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX; | ||
457 | break; | ||
458 | default: | ||
459 | BUG(); | ||
460 | } | ||
461 | } | ||
462 | |||
463 | static __init void | ||
464 | mt7628_dram_init(struct ralink_soc_info *soc_info) | ||
465 | { | ||
466 | switch (dram_type) { | ||
467 | case SYSCFG0_DRAM_TYPE_DDR1_MT7628: | ||
468 | pr_info("Board has DDR1\n"); | ||
469 | soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN; | ||
470 | soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX; | ||
471 | break; | ||
472 | |||
473 | case SYSCFG0_DRAM_TYPE_DDR2_MT7628: | ||
474 | pr_info("Board has DDR2\n"); | ||
475 | soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN; | ||
476 | soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX; | ||
477 | break; | ||
478 | default: | ||
479 | BUG(); | ||
480 | } | ||
481 | } | ||
482 | |||
334 | void prom_soc_init(struct ralink_soc_info *soc_info) | 483 | void prom_soc_init(struct ralink_soc_info *soc_info) |
335 | { | 484 | { |
336 | void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7620_SYSC_BASE); | 485 | void __iomem *sysc = (void __iomem *) KSEG1ADDR(MT7620_SYSC_BASE); |
@@ -339,22 +488,36 @@ void prom_soc_init(struct ralink_soc_info *soc_info) | |||
339 | u32 n1; | 488 | u32 n1; |
340 | u32 rev; | 489 | u32 rev; |
341 | u32 cfg0; | 490 | u32 cfg0; |
491 | u32 pmu0; | ||
492 | u32 pmu1; | ||
493 | u32 bga; | ||
342 | 494 | ||
343 | n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0); | 495 | n0 = __raw_readl(sysc + SYSC_REG_CHIP_NAME0); |
344 | n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1); | 496 | n1 = __raw_readl(sysc + SYSC_REG_CHIP_NAME1); |
345 | 497 | rev = __raw_readl(sysc + SYSC_REG_CHIP_REV); | |
346 | if (n0 == MT7620N_CHIP_NAME0 && n1 == MT7620N_CHIP_NAME1) { | 498 | bga = (rev >> CHIP_REV_PKG_SHIFT) & CHIP_REV_PKG_MASK; |
347 | name = "MT7620N"; | 499 | |
348 | soc_info->compatible = "ralink,mt7620n-soc"; | 500 | if (n0 == MT7620_CHIP_NAME0 && n1 == MT7620_CHIP_NAME1) { |
349 | } else if (n0 == MT7620A_CHIP_NAME0 && n1 == MT7620A_CHIP_NAME1) { | 501 | if (bga) { |
350 | name = "MT7620A"; | 502 | mt762x_soc = MT762X_SOC_MT7620A; |
351 | soc_info->compatible = "ralink,mt7620a-soc"; | 503 | name = "MT7620A"; |
504 | soc_info->compatible = "ralink,mt7620a-soc"; | ||
505 | } else { | ||
506 | mt762x_soc = MT762X_SOC_MT7620N; | ||
507 | name = "MT7620N"; | ||
508 | soc_info->compatible = "ralink,mt7620n-soc"; | ||
509 | #ifdef CONFIG_PCI | ||
510 | panic("mt7620n is only supported for non pci kernels"); | ||
511 | #endif | ||
512 | } | ||
513 | } else if (n0 == MT7620_CHIP_NAME0 && n1 == MT7628_CHIP_NAME1) { | ||
514 | mt762x_soc = MT762X_SOC_MT7628AN; | ||
515 | name = "MT7628AN"; | ||
516 | soc_info->compatible = "ralink,mt7628an-soc"; | ||
352 | } else { | 517 | } else { |
353 | panic("mt7620: unknown SoC, n0:%08x n1:%08x", n0, n1); | 518 | panic("mt762x: unknown SoC, n0:%08x n1:%08x\n", n0, n1); |
354 | } | 519 | } |
355 | 520 | ||
356 | rev = __raw_readl(sysc + SYSC_REG_CHIP_REV); | ||
357 | |||
358 | snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN, | 521 | snprintf(soc_info->sys_type, RAMIPS_SYS_TYPE_LEN, |
359 | "Ralink %s ver:%u eco:%u", | 522 | "Ralink %s ver:%u eco:%u", |
360 | name, | 523 | name, |
@@ -364,26 +527,22 @@ void prom_soc_init(struct ralink_soc_info *soc_info) | |||
364 | cfg0 = __raw_readl(sysc + SYSC_REG_SYSTEM_CONFIG0); | 527 | cfg0 = __raw_readl(sysc + SYSC_REG_SYSTEM_CONFIG0); |
365 | dram_type = (cfg0 >> SYSCFG0_DRAM_TYPE_SHIFT) & SYSCFG0_DRAM_TYPE_MASK; | 528 | dram_type = (cfg0 >> SYSCFG0_DRAM_TYPE_SHIFT) & SYSCFG0_DRAM_TYPE_MASK; |
366 | 529 | ||
367 | switch (dram_type) { | ||
368 | case SYSCFG0_DRAM_TYPE_SDRAM: | ||
369 | pr_info("Board has SDRAM\n"); | ||
370 | soc_info->mem_size_min = MT7620_SDRAM_SIZE_MIN; | ||
371 | soc_info->mem_size_max = MT7620_SDRAM_SIZE_MAX; | ||
372 | break; | ||
373 | |||
374 | case SYSCFG0_DRAM_TYPE_DDR1: | ||
375 | pr_info("Board has DDR1\n"); | ||
376 | soc_info->mem_size_min = MT7620_DDR1_SIZE_MIN; | ||
377 | soc_info->mem_size_max = MT7620_DDR1_SIZE_MAX; | ||
378 | break; | ||
379 | |||
380 | case SYSCFG0_DRAM_TYPE_DDR2: | ||
381 | pr_info("Board has DDR2\n"); | ||
382 | soc_info->mem_size_min = MT7620_DDR2_SIZE_MIN; | ||
383 | soc_info->mem_size_max = MT7620_DDR2_SIZE_MAX; | ||
384 | break; | ||
385 | default: | ||
386 | BUG(); | ||
387 | } | ||
388 | soc_info->mem_base = MT7620_DRAM_BASE; | 530 | soc_info->mem_base = MT7620_DRAM_BASE; |
531 | if (mt762x_soc == MT762X_SOC_MT7628AN) | ||
532 | mt7628_dram_init(soc_info); | ||
533 | else | ||
534 | mt7620_dram_init(soc_info); | ||
535 | |||
536 | pmu0 = __raw_readl(sysc + PMU0_CFG); | ||
537 | pmu1 = __raw_readl(sysc + PMU1_CFG); | ||
538 | |||
539 | pr_info("Analog PMU set to %s control\n", | ||
540 | (pmu0 & PMU_SW_SET) ? ("sw") : ("hw")); | ||
541 | pr_info("Digital PMU set to %s control\n", | ||
542 | (pmu1 & DIG_SW_SEL) ? ("sw") : ("hw")); | ||
543 | |||
544 | if (mt762x_soc == MT762X_SOC_MT7628AN) | ||
545 | rt2880_pinmux_data = mt7628an_pinmux_data; | ||
546 | else | ||
547 | rt2880_pinmux_data = mt7620a_pinmux_data; | ||
389 | } | 548 | } |
diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c index 7c4598cb6de8..0d30dcd63246 100644 --- a/arch/mips/ralink/of.c +++ b/arch/mips/ralink/of.c | |||
@@ -53,6 +53,17 @@ void __init device_tree_init(void) | |||
53 | unflatten_and_copy_device_tree(); | 53 | unflatten_and_copy_device_tree(); |
54 | } | 54 | } |
55 | 55 | ||
56 | static int memory_dtb; | ||
57 | |||
58 | static int __init early_init_dt_find_memory(unsigned long node, | ||
59 | const char *uname, int depth, void *data) | ||
60 | { | ||
61 | if (depth == 1 && !strcmp(uname, "memory@0")) | ||
62 | memory_dtb = 1; | ||
63 | |||
64 | return 0; | ||
65 | } | ||
66 | |||
56 | void __init plat_mem_setup(void) | 67 | void __init plat_mem_setup(void) |
57 | { | 68 | { |
58 | set_io_port_base(KSEG1); | 69 | set_io_port_base(KSEG1); |
@@ -63,7 +74,12 @@ void __init plat_mem_setup(void) | |||
63 | */ | 74 | */ |
64 | __dt_setup_arch(__dtb_start); | 75 | __dt_setup_arch(__dtb_start); |
65 | 76 | ||
66 | if (soc_info.mem_size) | 77 | strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); |
78 | |||
79 | of_scan_flat_dt(early_init_dt_find_memory, NULL); | ||
80 | if (memory_dtb) | ||
81 | of_scan_flat_dt(early_init_dt_scan_memory, NULL); | ||
82 | else if (soc_info.mem_size) | ||
67 | add_memory_region(soc_info.mem_base, soc_info.mem_size * SZ_1M, | 83 | add_memory_region(soc_info.mem_base, soc_info.mem_size * SZ_1M, |
68 | BOOT_MEM_RAM); | 84 | BOOT_MEM_RAM); |
69 | else | 85 | else |
@@ -74,19 +90,9 @@ void __init plat_mem_setup(void) | |||
74 | 90 | ||
75 | static int __init plat_of_setup(void) | 91 | static int __init plat_of_setup(void) |
76 | { | 92 | { |
77 | static struct of_device_id of_ids[3]; | 93 | __dt_register_buses(soc_info.compatible, "palmbus"); |
78 | int len = sizeof(of_ids[0].compatible); | ||
79 | |||
80 | if (!of_have_populated_dt()) | ||
81 | panic("device tree not present"); | ||
82 | |||
83 | strlcpy(of_ids[0].compatible, soc_info.compatible, len); | ||
84 | strlcpy(of_ids[1].compatible, "palmbus", len); | ||
85 | |||
86 | if (of_platform_populate(NULL, of_ids, NULL, NULL)) | ||
87 | panic("failed to populate DT"); | ||
88 | 94 | ||
89 | /* make sure ithat the reset controller is setup early */ | 95 | /* make sure that the reset controller is setup early */ |
90 | ralink_rst_init(); | 96 | ralink_rst_init(); |
91 | 97 | ||
92 | return 0; | 98 | return 0; |
diff --git a/arch/mips/ralink/prom.c b/arch/mips/ralink/prom.c index 9c64f029d047..09419f67da39 100644 --- a/arch/mips/ralink/prom.c +++ b/arch/mips/ralink/prom.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include "common.h" | 18 | #include "common.h" |
19 | 19 | ||
20 | struct ralink_soc_info soc_info; | 20 | struct ralink_soc_info soc_info; |
21 | struct rt2880_pmx_group *rt2880_pinmux_data = NULL; | ||
21 | 22 | ||
22 | const char *get_system_type(void) | 23 | const char *get_system_type(void) |
23 | { | 24 | { |
diff --git a/arch/mips/ralink/rt288x.c b/arch/mips/ralink/rt288x.c index f87de1ab2198..738cec865f41 100644 --- a/arch/mips/ralink/rt288x.c +++ b/arch/mips/ralink/rt288x.c | |||
@@ -17,46 +17,27 @@ | |||
17 | #include <asm/mipsregs.h> | 17 | #include <asm/mipsregs.h> |
18 | #include <asm/mach-ralink/ralink_regs.h> | 18 | #include <asm/mach-ralink/ralink_regs.h> |
19 | #include <asm/mach-ralink/rt288x.h> | 19 | #include <asm/mach-ralink/rt288x.h> |
20 | #include <asm/mach-ralink/pinmux.h> | ||
20 | 21 | ||
21 | #include "common.h" | 22 | #include "common.h" |
22 | 23 | ||
23 | static struct ralink_pinmux_grp mode_mux[] = { | 24 | static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) }; |
24 | { | 25 | static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) }; |
25 | .name = "i2c", | 26 | static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 7, 8) }; |
26 | .mask = RT2880_GPIO_MODE_I2C, | 27 | static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) }; |
27 | .gpio_first = 1, | 28 | static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) }; |
28 | .gpio_last = 2, | 29 | static struct rt2880_pmx_func sdram_func[] = { FUNC("sdram", 0, 24, 16) }; |
29 | }, { | 30 | static struct rt2880_pmx_func pci_func[] = { FUNC("pci", 0, 40, 32) }; |
30 | .name = "spi", | 31 | |
31 | .mask = RT2880_GPIO_MODE_SPI, | 32 | static struct rt2880_pmx_group rt2880_pinmux_data_act[] = { |
32 | .gpio_first = 3, | 33 | GRP("i2c", i2c_func, 1, RT2880_GPIO_MODE_I2C), |
33 | .gpio_last = 6, | 34 | GRP("spi", spi_func, 1, RT2880_GPIO_MODE_SPI), |
34 | }, { | 35 | GRP("uartlite", uartlite_func, 1, RT2880_GPIO_MODE_UART0), |
35 | .name = "uartlite", | 36 | GRP("jtag", jtag_func, 1, RT2880_GPIO_MODE_JTAG), |
36 | .mask = RT2880_GPIO_MODE_UART0, | 37 | GRP("mdio", mdio_func, 1, RT2880_GPIO_MODE_MDIO), |
37 | .gpio_first = 7, | 38 | GRP("sdram", sdram_func, 1, RT2880_GPIO_MODE_SDRAM), |
38 | .gpio_last = 14, | 39 | GRP("pci", pci_func, 1, RT2880_GPIO_MODE_PCI), |
39 | }, { | 40 | { 0 } |
40 | .name = "jtag", | ||
41 | .mask = RT2880_GPIO_MODE_JTAG, | ||
42 | .gpio_first = 17, | ||
43 | .gpio_last = 21, | ||
44 | }, { | ||
45 | .name = "mdio", | ||
46 | .mask = RT2880_GPIO_MODE_MDIO, | ||
47 | .gpio_first = 22, | ||
48 | .gpio_last = 23, | ||
49 | }, { | ||
50 | .name = "sdram", | ||
51 | .mask = RT2880_GPIO_MODE_SDRAM, | ||
52 | .gpio_first = 24, | ||
53 | .gpio_last = 39, | ||
54 | }, { | ||
55 | .name = "pci", | ||
56 | .mask = RT2880_GPIO_MODE_PCI, | ||
57 | .gpio_first = 40, | ||
58 | .gpio_last = 71, | ||
59 | }, {0} | ||
60 | }; | 41 | }; |
61 | 42 | ||
62 | static void rt288x_wdt_reset(void) | 43 | static void rt288x_wdt_reset(void) |
@@ -69,14 +50,9 @@ static void rt288x_wdt_reset(void) | |||
69 | rt_sysc_w32(t, SYSC_REG_CLKCFG); | 50 | rt_sysc_w32(t, SYSC_REG_CLKCFG); |
70 | } | 51 | } |
71 | 52 | ||
72 | struct ralink_pinmux rt_gpio_pinmux = { | ||
73 | .mode = mode_mux, | ||
74 | .wdt_reset = rt288x_wdt_reset, | ||
75 | }; | ||
76 | |||
77 | void __init ralink_clk_init(void) | 53 | void __init ralink_clk_init(void) |
78 | { | 54 | { |
79 | unsigned long cpu_rate; | 55 | unsigned long cpu_rate, wmac_rate = 40000000; |
80 | u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG); | 56 | u32 t = rt_sysc_r32(SYSC_REG_SYSTEM_CONFIG); |
81 | t = ((t >> SYSTEM_CONFIG_CPUCLK_SHIFT) & SYSTEM_CONFIG_CPUCLK_MASK); | 57 | t = ((t >> SYSTEM_CONFIG_CPUCLK_SHIFT) & SYSTEM_CONFIG_CPUCLK_MASK); |
82 | 58 | ||
@@ -101,6 +77,7 @@ void __init ralink_clk_init(void) | |||
101 | ralink_clk_add("300500.uart", cpu_rate / 2); | 77 | ralink_clk_add("300500.uart", cpu_rate / 2); |
102 | ralink_clk_add("300c00.uartlite", cpu_rate / 2); | 78 | ralink_clk_add("300c00.uartlite", cpu_rate / 2); |
103 | ralink_clk_add("400000.ethernet", cpu_rate / 2); | 79 | ralink_clk_add("400000.ethernet", cpu_rate / 2); |
80 | ralink_clk_add("480000.wmac", wmac_rate); | ||
104 | } | 81 | } |
105 | 82 | ||
106 | void __init ralink_of_remap(void) | 83 | void __init ralink_of_remap(void) |
@@ -140,4 +117,6 @@ void prom_soc_init(struct ralink_soc_info *soc_info) | |||
140 | soc_info->mem_base = RT2880_SDRAM_BASE; | 117 | soc_info->mem_base = RT2880_SDRAM_BASE; |
141 | soc_info->mem_size_min = RT2880_MEM_SIZE_MIN; | 118 | soc_info->mem_size_min = RT2880_MEM_SIZE_MIN; |
142 | soc_info->mem_size_max = RT2880_MEM_SIZE_MAX; | 119 | soc_info->mem_size_max = RT2880_MEM_SIZE_MAX; |
120 | |||
121 | rt2880_pinmux_data = rt2880_pinmux_data_act; | ||
143 | } | 122 | } |
diff --git a/arch/mips/ralink/rt305x.c b/arch/mips/ralink/rt305x.c index bb82a82da9e7..c40776ab67db 100644 --- a/arch/mips/ralink/rt305x.c +++ b/arch/mips/ralink/rt305x.c | |||
@@ -17,90 +17,78 @@ | |||
17 | #include <asm/mipsregs.h> | 17 | #include <asm/mipsregs.h> |
18 | #include <asm/mach-ralink/ralink_regs.h> | 18 | #include <asm/mach-ralink/ralink_regs.h> |
19 | #include <asm/mach-ralink/rt305x.h> | 19 | #include <asm/mach-ralink/rt305x.h> |
20 | #include <asm/mach-ralink/pinmux.h> | ||
20 | 21 | ||
21 | #include "common.h" | 22 | #include "common.h" |
22 | 23 | ||
23 | enum rt305x_soc_type rt305x_soc; | 24 | enum rt305x_soc_type rt305x_soc; |
24 | 25 | ||
25 | static struct ralink_pinmux_grp mode_mux[] = { | 26 | static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) }; |
26 | { | 27 | static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) }; |
27 | .name = "i2c", | 28 | static struct rt2880_pmx_func uartf_func[] = { |
28 | .mask = RT305X_GPIO_MODE_I2C, | 29 | FUNC("uartf", RT305X_GPIO_MODE_UARTF, 7, 8), |
29 | .gpio_first = RT305X_GPIO_I2C_SD, | 30 | FUNC("pcm uartf", RT305X_GPIO_MODE_PCM_UARTF, 7, 8), |
30 | .gpio_last = RT305X_GPIO_I2C_SCLK, | 31 | FUNC("pcm i2s", RT305X_GPIO_MODE_PCM_I2S, 7, 8), |
31 | }, { | 32 | FUNC("i2s uartf", RT305X_GPIO_MODE_I2S_UARTF, 7, 8), |
32 | .name = "spi", | 33 | FUNC("pcm gpio", RT305X_GPIO_MODE_PCM_GPIO, 11, 4), |
33 | .mask = RT305X_GPIO_MODE_SPI, | 34 | FUNC("gpio uartf", RT305X_GPIO_MODE_GPIO_UARTF, 7, 4), |
34 | .gpio_first = RT305X_GPIO_SPI_EN, | 35 | FUNC("gpio i2s", RT305X_GPIO_MODE_GPIO_I2S, 7, 4), |
35 | .gpio_last = RT305X_GPIO_SPI_CLK, | 36 | }; |
36 | }, { | 37 | static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) }; |
37 | .name = "uartlite", | 38 | static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) }; |
38 | .mask = RT305X_GPIO_MODE_UART1, | 39 | static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) }; |
39 | .gpio_first = RT305X_GPIO_UART1_TXD, | 40 | static struct rt2880_pmx_func rt5350_led_func[] = { FUNC("led", 0, 22, 5) }; |
40 | .gpio_last = RT305X_GPIO_UART1_RXD, | 41 | static struct rt2880_pmx_func rt5350_cs1_func[] = { |
41 | }, { | 42 | FUNC("spi_cs1", 0, 27, 1), |
42 | .name = "jtag", | 43 | FUNC("wdg_cs1", 1, 27, 1), |
43 | .mask = RT305X_GPIO_MODE_JTAG, | 44 | }; |
44 | .gpio_first = RT305X_GPIO_JTAG_TDO, | 45 | static struct rt2880_pmx_func sdram_func[] = { FUNC("sdram", 0, 24, 16) }; |
45 | .gpio_last = RT305X_GPIO_JTAG_TDI, | 46 | static struct rt2880_pmx_func rt3352_rgmii_func[] = { |
46 | }, { | 47 | FUNC("rgmii", 0, 24, 12) |
47 | .name = "mdio", | 48 | }; |
48 | .mask = RT305X_GPIO_MODE_MDIO, | 49 | static struct rt2880_pmx_func rgmii_func[] = { FUNC("rgmii", 0, 40, 12) }; |
49 | .gpio_first = RT305X_GPIO_MDIO_MDC, | 50 | static struct rt2880_pmx_func rt3352_lna_func[] = { FUNC("lna", 0, 36, 2) }; |
50 | .gpio_last = RT305X_GPIO_MDIO_MDIO, | 51 | static struct rt2880_pmx_func rt3352_pa_func[] = { FUNC("pa", 0, 38, 2) }; |
51 | }, { | 52 | static struct rt2880_pmx_func rt3352_led_func[] = { FUNC("led", 0, 40, 5) }; |
52 | .name = "sdram", | 53 | |
53 | .mask = RT305X_GPIO_MODE_SDRAM, | 54 | static struct rt2880_pmx_group rt3050_pinmux_data[] = { |
54 | .gpio_first = RT305X_GPIO_SDRAM_MD16, | 55 | GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C), |
55 | .gpio_last = RT305X_GPIO_SDRAM_MD31, | 56 | GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI), |
56 | }, { | 57 | GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK, |
57 | .name = "rgmii", | 58 | RT305X_GPIO_MODE_UART0_SHIFT), |
58 | .mask = RT305X_GPIO_MODE_RGMII, | 59 | GRP("uartlite", uartlite_func, 1, RT305X_GPIO_MODE_UART1), |
59 | .gpio_first = RT305X_GPIO_GE0_TXD0, | 60 | GRP("jtag", jtag_func, 1, RT305X_GPIO_MODE_JTAG), |
60 | .gpio_last = RT305X_GPIO_GE0_RXCLK, | 61 | GRP("mdio", mdio_func, 1, RT305X_GPIO_MODE_MDIO), |
61 | }, {0} | 62 | GRP("rgmii", rgmii_func, 1, RT305X_GPIO_MODE_RGMII), |
63 | GRP("sdram", sdram_func, 1, RT305X_GPIO_MODE_SDRAM), | ||
64 | { 0 } | ||
62 | }; | 65 | }; |
63 | 66 | ||
64 | static struct ralink_pinmux_grp uart_mux[] = { | 67 | static struct rt2880_pmx_group rt3352_pinmux_data[] = { |
65 | { | 68 | GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C), |
66 | .name = "uartf", | 69 | GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI), |
67 | .mask = RT305X_GPIO_MODE_UARTF, | 70 | GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK, |
68 | .gpio_first = RT305X_GPIO_7, | 71 | RT305X_GPIO_MODE_UART0_SHIFT), |
69 | .gpio_last = RT305X_GPIO_14, | 72 | GRP("uartlite", uartlite_func, 1, RT305X_GPIO_MODE_UART1), |
70 | }, { | 73 | GRP("jtag", jtag_func, 1, RT305X_GPIO_MODE_JTAG), |
71 | .name = "pcm uartf", | 74 | GRP("mdio", mdio_func, 1, RT305X_GPIO_MODE_MDIO), |
72 | .mask = RT305X_GPIO_MODE_PCM_UARTF, | 75 | GRP("rgmii", rt3352_rgmii_func, 1, RT305X_GPIO_MODE_RGMII), |
73 | .gpio_first = RT305X_GPIO_7, | 76 | GRP("lna", rt3352_lna_func, 1, RT3352_GPIO_MODE_LNA), |
74 | .gpio_last = RT305X_GPIO_14, | 77 | GRP("pa", rt3352_pa_func, 1, RT3352_GPIO_MODE_PA), |
75 | }, { | 78 | GRP("led", rt3352_led_func, 1, RT5350_GPIO_MODE_PHY_LED), |
76 | .name = "pcm i2s", | 79 | { 0 } |
77 | .mask = RT305X_GPIO_MODE_PCM_I2S, | 80 | }; |
78 | .gpio_first = RT305X_GPIO_7, | 81 | |
79 | .gpio_last = RT305X_GPIO_14, | 82 | static struct rt2880_pmx_group rt5350_pinmux_data[] = { |
80 | }, { | 83 | GRP("i2c", i2c_func, 1, RT305X_GPIO_MODE_I2C), |
81 | .name = "i2s uartf", | 84 | GRP("spi", spi_func, 1, RT305X_GPIO_MODE_SPI), |
82 | .mask = RT305X_GPIO_MODE_I2S_UARTF, | 85 | GRP("uartf", uartf_func, RT305X_GPIO_MODE_UART0_MASK, |
83 | .gpio_first = RT305X_GPIO_7, | 86 | RT305X_GPIO_MODE_UART0_SHIFT), |
84 | .gpio_last = RT305X_GPIO_14, | 87 | GRP("uartlite", uartlite_func, 1, RT305X_GPIO_MODE_UART1), |
85 | }, { | 88 | GRP("jtag", jtag_func, 1, RT305X_GPIO_MODE_JTAG), |
86 | .name = "pcm gpio", | 89 | GRP("led", rt5350_led_func, 1, RT5350_GPIO_MODE_PHY_LED), |
87 | .mask = RT305X_GPIO_MODE_PCM_GPIO, | 90 | GRP("spi_cs1", rt5350_cs1_func, 2, RT5350_GPIO_MODE_SPI_CS1), |
88 | .gpio_first = RT305X_GPIO_10, | 91 | { 0 } |
89 | .gpio_last = RT305X_GPIO_14, | ||
90 | }, { | ||
91 | .name = "gpio uartf", | ||
92 | .mask = RT305X_GPIO_MODE_GPIO_UARTF, | ||
93 | .gpio_first = RT305X_GPIO_7, | ||
94 | .gpio_last = RT305X_GPIO_10, | ||
95 | }, { | ||
96 | .name = "gpio i2s", | ||
97 | .mask = RT305X_GPIO_MODE_GPIO_I2S, | ||
98 | .gpio_first = RT305X_GPIO_7, | ||
99 | .gpio_last = RT305X_GPIO_10, | ||
100 | }, { | ||
101 | .name = "gpio", | ||
102 | .mask = RT305X_GPIO_MODE_GPIO, | ||
103 | }, {0} | ||
104 | }; | 92 | }; |
105 | 93 | ||
106 | static void rt305x_wdt_reset(void) | 94 | static void rt305x_wdt_reset(void) |
@@ -114,14 +102,6 @@ static void rt305x_wdt_reset(void) | |||
114 | rt_sysc_w32(t, SYSC_REG_SYSTEM_CONFIG); | 102 | rt_sysc_w32(t, SYSC_REG_SYSTEM_CONFIG); |
115 | } | 103 | } |
116 | 104 | ||
117 | struct ralink_pinmux rt_gpio_pinmux = { | ||
118 | .mode = mode_mux, | ||
119 | .uart = uart_mux, | ||
120 | .uart_shift = RT305X_GPIO_MODE_UART0_SHIFT, | ||
121 | .uart_mask = RT305X_GPIO_MODE_UART0_MASK, | ||
122 | .wdt_reset = rt305x_wdt_reset, | ||
123 | }; | ||
124 | |||
125 | static unsigned long rt5350_get_mem_size(void) | 105 | static unsigned long rt5350_get_mem_size(void) |
126 | { | 106 | { |
127 | void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE); | 107 | void __iomem *sysc = (void __iomem *) KSEG1ADDR(RT305X_SYSC_BASE); |
@@ -290,11 +270,14 @@ void prom_soc_init(struct ralink_soc_info *soc_info) | |||
290 | soc_info->mem_base = RT305X_SDRAM_BASE; | 270 | soc_info->mem_base = RT305X_SDRAM_BASE; |
291 | if (soc_is_rt5350()) { | 271 | if (soc_is_rt5350()) { |
292 | soc_info->mem_size = rt5350_get_mem_size(); | 272 | soc_info->mem_size = rt5350_get_mem_size(); |
273 | rt2880_pinmux_data = rt5350_pinmux_data; | ||
293 | } else if (soc_is_rt305x() || soc_is_rt3350()) { | 274 | } else if (soc_is_rt305x() || soc_is_rt3350()) { |
294 | soc_info->mem_size_min = RT305X_MEM_SIZE_MIN; | 275 | soc_info->mem_size_min = RT305X_MEM_SIZE_MIN; |
295 | soc_info->mem_size_max = RT305X_MEM_SIZE_MAX; | 276 | soc_info->mem_size_max = RT305X_MEM_SIZE_MAX; |
277 | rt2880_pinmux_data = rt3050_pinmux_data; | ||
296 | } else if (soc_is_rt3352()) { | 278 | } else if (soc_is_rt3352()) { |
297 | soc_info->mem_size_min = RT3352_MEM_SIZE_MIN; | 279 | soc_info->mem_size_min = RT3352_MEM_SIZE_MIN; |
298 | soc_info->mem_size_max = RT3352_MEM_SIZE_MAX; | 280 | soc_info->mem_size_max = RT3352_MEM_SIZE_MAX; |
281 | rt2880_pinmux_data = rt3352_pinmux_data; | ||
299 | } | 282 | } |
300 | } | 283 | } |
diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c index b474ac284b83..86a535c770d8 100644 --- a/arch/mips/ralink/rt3883.c +++ b/arch/mips/ralink/rt3883.c | |||
@@ -17,132 +17,50 @@ | |||
17 | #include <asm/mipsregs.h> | 17 | #include <asm/mipsregs.h> |
18 | #include <asm/mach-ralink/ralink_regs.h> | 18 | #include <asm/mach-ralink/ralink_regs.h> |
19 | #include <asm/mach-ralink/rt3883.h> | 19 | #include <asm/mach-ralink/rt3883.h> |
20 | #include <asm/mach-ralink/pinmux.h> | ||
20 | 21 | ||
21 | #include "common.h" | 22 | #include "common.h" |
22 | 23 | ||
23 | static struct ralink_pinmux_grp mode_mux[] = { | 24 | static struct rt2880_pmx_func i2c_func[] = { FUNC("i2c", 0, 1, 2) }; |
24 | { | 25 | static struct rt2880_pmx_func spi_func[] = { FUNC("spi", 0, 3, 4) }; |
25 | .name = "i2c", | 26 | static struct rt2880_pmx_func uartf_func[] = { |
26 | .mask = RT3883_GPIO_MODE_I2C, | 27 | FUNC("uartf", RT3883_GPIO_MODE_UARTF, 7, 8), |
27 | .gpio_first = RT3883_GPIO_I2C_SD, | 28 | FUNC("pcm uartf", RT3883_GPIO_MODE_PCM_UARTF, 7, 8), |
28 | .gpio_last = RT3883_GPIO_I2C_SCLK, | 29 | FUNC("pcm i2s", RT3883_GPIO_MODE_PCM_I2S, 7, 8), |
29 | }, { | 30 | FUNC("i2s uartf", RT3883_GPIO_MODE_I2S_UARTF, 7, 8), |
30 | .name = "spi", | 31 | FUNC("pcm gpio", RT3883_GPIO_MODE_PCM_GPIO, 11, 4), |
31 | .mask = RT3883_GPIO_MODE_SPI, | 32 | FUNC("gpio uartf", RT3883_GPIO_MODE_GPIO_UARTF, 7, 4), |
32 | .gpio_first = RT3883_GPIO_SPI_CS0, | 33 | FUNC("gpio i2s", RT3883_GPIO_MODE_GPIO_I2S, 7, 4), |
33 | .gpio_last = RT3883_GPIO_SPI_MISO, | ||
34 | }, { | ||
35 | .name = "uartlite", | ||
36 | .mask = RT3883_GPIO_MODE_UART1, | ||
37 | .gpio_first = RT3883_GPIO_UART1_TXD, | ||
38 | .gpio_last = RT3883_GPIO_UART1_RXD, | ||
39 | }, { | ||
40 | .name = "jtag", | ||
41 | .mask = RT3883_GPIO_MODE_JTAG, | ||
42 | .gpio_first = RT3883_GPIO_JTAG_TDO, | ||
43 | .gpio_last = RT3883_GPIO_JTAG_TCLK, | ||
44 | }, { | ||
45 | .name = "mdio", | ||
46 | .mask = RT3883_GPIO_MODE_MDIO, | ||
47 | .gpio_first = RT3883_GPIO_MDIO_MDC, | ||
48 | .gpio_last = RT3883_GPIO_MDIO_MDIO, | ||
49 | }, { | ||
50 | .name = "ge1", | ||
51 | .mask = RT3883_GPIO_MODE_GE1, | ||
52 | .gpio_first = RT3883_GPIO_GE1_TXD0, | ||
53 | .gpio_last = RT3883_GPIO_GE1_RXCLK, | ||
54 | }, { | ||
55 | .name = "ge2", | ||
56 | .mask = RT3883_GPIO_MODE_GE2, | ||
57 | .gpio_first = RT3883_GPIO_GE2_TXD0, | ||
58 | .gpio_last = RT3883_GPIO_GE2_RXCLK, | ||
59 | }, { | ||
60 | .name = "pci", | ||
61 | .mask = RT3883_GPIO_MODE_PCI, | ||
62 | .gpio_first = RT3883_GPIO_PCI_AD0, | ||
63 | .gpio_last = RT3883_GPIO_PCI_AD31, | ||
64 | }, { | ||
65 | .name = "lna a", | ||
66 | .mask = RT3883_GPIO_MODE_LNA_A, | ||
67 | .gpio_first = RT3883_GPIO_LNA_PE_A0, | ||
68 | .gpio_last = RT3883_GPIO_LNA_PE_A2, | ||
69 | }, { | ||
70 | .name = "lna g", | ||
71 | .mask = RT3883_GPIO_MODE_LNA_G, | ||
72 | .gpio_first = RT3883_GPIO_LNA_PE_G0, | ||
73 | .gpio_last = RT3883_GPIO_LNA_PE_G2, | ||
74 | }, {0} | ||
75 | }; | 34 | }; |
76 | 35 | static struct rt2880_pmx_func uartlite_func[] = { FUNC("uartlite", 0, 15, 2) }; | |
77 | static struct ralink_pinmux_grp uart_mux[] = { | 36 | static struct rt2880_pmx_func jtag_func[] = { FUNC("jtag", 0, 17, 5) }; |
78 | { | 37 | static struct rt2880_pmx_func mdio_func[] = { FUNC("mdio", 0, 22, 2) }; |
79 | .name = "uartf", | 38 | static struct rt2880_pmx_func lna_a_func[] = { FUNC("lna a", 0, 32, 3) }; |
80 | .mask = RT3883_GPIO_MODE_UARTF, | 39 | static struct rt2880_pmx_func lna_g_func[] = { FUNC("lna a", 0, 35, 3) }; |
81 | .gpio_first = RT3883_GPIO_7, | 40 | static struct rt2880_pmx_func pci_func[] = { |
82 | .gpio_last = RT3883_GPIO_14, | 41 | FUNC("pci-dev", 0, 40, 32), |
83 | }, { | 42 | FUNC("pci-host2", 1, 40, 32), |
84 | .name = "pcm uartf", | 43 | FUNC("pci-host1", 2, 40, 32), |
85 | .mask = RT3883_GPIO_MODE_PCM_UARTF, | 44 | FUNC("pci-fnc", 3, 40, 32) |
86 | .gpio_first = RT3883_GPIO_7, | ||
87 | .gpio_last = RT3883_GPIO_14, | ||
88 | }, { | ||
89 | .name = "pcm i2s", | ||
90 | .mask = RT3883_GPIO_MODE_PCM_I2S, | ||
91 | .gpio_first = RT3883_GPIO_7, | ||
92 | .gpio_last = RT3883_GPIO_14, | ||
93 | }, { | ||
94 | .name = "i2s uartf", | ||
95 | .mask = RT3883_GPIO_MODE_I2S_UARTF, | ||
96 | .gpio_first = RT3883_GPIO_7, | ||
97 | .gpio_last = RT3883_GPIO_14, | ||
98 | }, { | ||
99 | .name = "pcm gpio", | ||
100 | .mask = RT3883_GPIO_MODE_PCM_GPIO, | ||
101 | .gpio_first = RT3883_GPIO_11, | ||
102 | .gpio_last = RT3883_GPIO_14, | ||
103 | }, { | ||
104 | .name = "gpio uartf", | ||
105 | .mask = RT3883_GPIO_MODE_GPIO_UARTF, | ||
106 | .gpio_first = RT3883_GPIO_7, | ||
107 | .gpio_last = RT3883_GPIO_10, | ||
108 | }, { | ||
109 | .name = "gpio i2s", | ||
110 | .mask = RT3883_GPIO_MODE_GPIO_I2S, | ||
111 | .gpio_first = RT3883_GPIO_7, | ||
112 | .gpio_last = RT3883_GPIO_10, | ||
113 | }, { | ||
114 | .name = "gpio", | ||
115 | .mask = RT3883_GPIO_MODE_GPIO, | ||
116 | }, {0} | ||
117 | }; | 45 | }; |
118 | 46 | static struct rt2880_pmx_func ge1_func[] = { FUNC("ge1", 0, 72, 12) }; | |
119 | static struct ralink_pinmux_grp pci_mux[] = { | 47 | static struct rt2880_pmx_func ge2_func[] = { FUNC("ge1", 0, 84, 12) }; |
120 | { | 48 | |
121 | .name = "pci-dev", | 49 | static struct rt2880_pmx_group rt3883_pinmux_data[] = { |
122 | .mask = 0, | 50 | GRP("i2c", i2c_func, 1, RT3883_GPIO_MODE_I2C), |
123 | .gpio_first = RT3883_GPIO_PCI_AD0, | 51 | GRP("spi", spi_func, 1, RT3883_GPIO_MODE_SPI), |
124 | .gpio_last = RT3883_GPIO_PCI_AD31, | 52 | GRP("uartf", uartf_func, RT3883_GPIO_MODE_UART0_MASK, |
125 | }, { | 53 | RT3883_GPIO_MODE_UART0_SHIFT), |
126 | .name = "pci-host2", | 54 | GRP("uartlite", uartlite_func, 1, RT3883_GPIO_MODE_UART1), |
127 | .mask = 1, | 55 | GRP("jtag", jtag_func, 1, RT3883_GPIO_MODE_JTAG), |
128 | .gpio_first = RT3883_GPIO_PCI_AD0, | 56 | GRP("mdio", mdio_func, 1, RT3883_GPIO_MODE_MDIO), |
129 | .gpio_last = RT3883_GPIO_PCI_AD31, | 57 | GRP("lna a", lna_a_func, 1, RT3883_GPIO_MODE_LNA_A), |
130 | }, { | 58 | GRP("lna g", lna_g_func, 1, RT3883_GPIO_MODE_LNA_G), |
131 | .name = "pci-host1", | 59 | GRP("pci", pci_func, RT3883_GPIO_MODE_PCI_MASK, |
132 | .mask = 2, | 60 | RT3883_GPIO_MODE_PCI_SHIFT), |
133 | .gpio_first = RT3883_GPIO_PCI_AD0, | 61 | GRP("ge1", ge1_func, 1, RT3883_GPIO_MODE_GE1), |
134 | .gpio_last = RT3883_GPIO_PCI_AD31, | 62 | GRP("ge2", ge2_func, 1, RT3883_GPIO_MODE_GE2), |
135 | }, { | 63 | { 0 } |
136 | .name = "pci-fnc", | ||
137 | .mask = 3, | ||
138 | .gpio_first = RT3883_GPIO_PCI_AD0, | ||
139 | .gpio_last = RT3883_GPIO_PCI_AD31, | ||
140 | }, { | ||
141 | .name = "pci-gpio", | ||
142 | .mask = 7, | ||
143 | .gpio_first = RT3883_GPIO_PCI_AD0, | ||
144 | .gpio_last = RT3883_GPIO_PCI_AD31, | ||
145 | }, {0} | ||
146 | }; | 64 | }; |
147 | 65 | ||
148 | static void rt3883_wdt_reset(void) | 66 | static void rt3883_wdt_reset(void) |
@@ -155,17 +73,6 @@ static void rt3883_wdt_reset(void) | |||
155 | rt_sysc_w32(t, RT3883_SYSC_REG_SYSCFG1); | 73 | rt_sysc_w32(t, RT3883_SYSC_REG_SYSCFG1); |
156 | } | 74 | } |
157 | 75 | ||
158 | struct ralink_pinmux rt_gpio_pinmux = { | ||
159 | .mode = mode_mux, | ||
160 | .uart = uart_mux, | ||
161 | .uart_shift = RT3883_GPIO_MODE_UART0_SHIFT, | ||
162 | .uart_mask = RT3883_GPIO_MODE_UART0_MASK, | ||
163 | .wdt_reset = rt3883_wdt_reset, | ||
164 | .pci = pci_mux, | ||
165 | .pci_shift = RT3883_GPIO_MODE_PCI_SHIFT, | ||
166 | .pci_mask = RT3883_GPIO_MODE_PCI_MASK, | ||
167 | }; | ||
168 | |||
169 | void __init ralink_clk_init(void) | 76 | void __init ralink_clk_init(void) |
170 | { | 77 | { |
171 | unsigned long cpu_rate, sys_rate; | 78 | unsigned long cpu_rate, sys_rate; |
@@ -204,6 +111,7 @@ void __init ralink_clk_init(void) | |||
204 | ralink_clk_add("10000b00.spi", sys_rate); | 111 | ralink_clk_add("10000b00.spi", sys_rate); |
205 | ralink_clk_add("10000c00.uartlite", 40000000); | 112 | ralink_clk_add("10000c00.uartlite", 40000000); |
206 | ralink_clk_add("10100000.ethernet", sys_rate); | 113 | ralink_clk_add("10100000.ethernet", sys_rate); |
114 | ralink_clk_add("10180000.wmac", 40000000); | ||
207 | } | 115 | } |
208 | 116 | ||
209 | void __init ralink_of_remap(void) | 117 | void __init ralink_of_remap(void) |
@@ -243,4 +151,6 @@ void prom_soc_init(struct ralink_soc_info *soc_info) | |||
243 | soc_info->mem_base = RT3883_SDRAM_BASE; | 151 | soc_info->mem_base = RT3883_SDRAM_BASE; |
244 | soc_info->mem_size_min = RT3883_MEM_SIZE_MIN; | 152 | soc_info->mem_size_min = RT3883_MEM_SIZE_MIN; |
245 | soc_info->mem_size_max = RT3883_MEM_SIZE_MAX; | 153 | soc_info->mem_size_max = RT3883_MEM_SIZE_MAX; |
154 | |||
155 | rt2880_pinmux_data = rt3883_pinmux_data; | ||
246 | } | 156 | } |
diff --git a/arch/mips/rb532/gpio.c b/arch/mips/rb532/gpio.c index a18007613c30..5aa3df853082 100644 --- a/arch/mips/rb532/gpio.c +++ b/arch/mips/rb532/gpio.c | |||
@@ -79,7 +79,7 @@ static inline void rb532_set_bit(unsigned bitval, | |||
79 | */ | 79 | */ |
80 | static inline int rb532_get_bit(unsigned offset, void __iomem *ioaddr) | 80 | static inline int rb532_get_bit(unsigned offset, void __iomem *ioaddr) |
81 | { | 81 | { |
82 | return (readl(ioaddr) & (1 << offset)); | 82 | return readl(ioaddr) & (1 << offset); |
83 | } | 83 | } |
84 | 84 | ||
85 | /* | 85 | /* |
diff --git a/arch/mips/rb532/prom.c b/arch/mips/rb532/prom.c index a757ded437cd..657210e767c2 100644 --- a/arch/mips/rb532/prom.c +++ b/arch/mips/rb532/prom.c | |||
@@ -122,8 +122,8 @@ void __init prom_setup_cmdline(void) | |||
122 | void __init prom_init(void) | 122 | void __init prom_init(void) |
123 | { | 123 | { |
124 | struct ddr_ram __iomem *ddr; | 124 | struct ddr_ram __iomem *ddr; |
125 | phys_t memsize; | 125 | phys_addr_t memsize; |
126 | phys_t ddrbase; | 126 | phys_addr_t ddrbase; |
127 | 127 | ||
128 | ddr = ioremap_nocache(ddr_reg[0].start, | 128 | ddr = ioremap_nocache(ddr_reg[0].start, |
129 | ddr_reg[0].end - ddr_reg[0].start); | 129 | ddr_reg[0].end - ddr_reg[0].start); |
@@ -133,8 +133,8 @@ void __init prom_init(void) | |||
133 | return; | 133 | return; |
134 | } | 134 | } |
135 | 135 | ||
136 | ddrbase = (phys_t)&ddr->ddrbase; | 136 | ddrbase = (phys_addr_t)&ddr->ddrbase; |
137 | memsize = (phys_t)&ddr->ddrmask; | 137 | memsize = (phys_addr_t)&ddr->ddrmask; |
138 | memsize = 0 - memsize; | 138 | memsize = 0 - memsize; |
139 | 139 | ||
140 | prom_setup_cmdline(); | 140 | prom_setup_cmdline(); |
diff --git a/arch/mips/sgi-ip22/ip22-mc.c b/arch/mips/sgi-ip22/ip22-mc.c index 7cec0a4e527d..6b009c45abed 100644 --- a/arch/mips/sgi-ip22/ip22-mc.c +++ b/arch/mips/sgi-ip22/ip22-mc.c | |||
@@ -24,14 +24,12 @@ EXPORT_SYMBOL(sgimc); | |||
24 | 24 | ||
25 | static inline unsigned long get_bank_addr(unsigned int memconfig) | 25 | static inline unsigned long get_bank_addr(unsigned int memconfig) |
26 | { | 26 | { |
27 | return ((memconfig & SGIMC_MCONFIG_BASEADDR) << | 27 | return (memconfig & SGIMC_MCONFIG_BASEADDR) << ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 24 : 22); |
28 | ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 24 : 22)); | ||
29 | } | 28 | } |
30 | 29 | ||
31 | static inline unsigned long get_bank_size(unsigned int memconfig) | 30 | static inline unsigned long get_bank_size(unsigned int memconfig) |
32 | { | 31 | { |
33 | return ((memconfig & SGIMC_MCONFIG_RMASK) + 0x0100) << | 32 | return ((memconfig & SGIMC_MCONFIG_RMASK) + 0x0100) << ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 16 : 14); |
34 | ((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 16 : 14); | ||
35 | } | 33 | } |
36 | 34 | ||
37 | static inline unsigned int get_bank_config(int bank) | 35 | static inline unsigned int get_bank_config(int bank) |
diff --git a/arch/mips/sgi-ip22/ip28-berr.c b/arch/mips/sgi-ip22/ip28-berr.c index 3f47346608d7..712cc0f6a58d 100644 --- a/arch/mips/sgi-ip22/ip28-berr.c +++ b/arch/mips/sgi-ip22/ip28-berr.c | |||
@@ -338,7 +338,7 @@ static int check_microtlb(u32 hi, u32 lo, unsigned long vaddr) | |||
338 | PHYS_TO_XKSEG_UNCACHED(pte); | 338 | PHYS_TO_XKSEG_UNCACHED(pte); |
339 | a = (a & 0x3f) << 6; /* PFN */ | 339 | a = (a & 0x3f) << 6; /* PFN */ |
340 | a += vaddr & ((1 << pgsz) - 1); | 340 | a += vaddr & ((1 << pgsz) - 1); |
341 | return (cpu_err_addr == a); | 341 | return cpu_err_addr == a; |
342 | } | 342 | } |
343 | } | 343 | } |
344 | } | 344 | } |
@@ -351,7 +351,7 @@ static int check_vdma_memaddr(void) | |||
351 | u32 a = sgimc->maddronly; | 351 | u32 a = sgimc->maddronly; |
352 | 352 | ||
353 | if (!(sgimc->dma_ctrl & 0x100)) /* Xlate-bit clear ? */ | 353 | if (!(sgimc->dma_ctrl & 0x100)) /* Xlate-bit clear ? */ |
354 | return (cpu_err_addr == a); | 354 | return cpu_err_addr == a; |
355 | 355 | ||
356 | if (check_microtlb(sgimc->dtlb_hi0, sgimc->dtlb_lo0, a) || | 356 | if (check_microtlb(sgimc->dtlb_hi0, sgimc->dtlb_lo0, a) || |
357 | check_microtlb(sgimc->dtlb_hi1, sgimc->dtlb_lo1, a) || | 357 | check_microtlb(sgimc->dtlb_hi1, sgimc->dtlb_lo1, a) || |
@@ -367,7 +367,7 @@ static int check_vdma_gioaddr(void) | |||
367 | if (gio_err_stat & GIO_ERRMASK) { | 367 | if (gio_err_stat & GIO_ERRMASK) { |
368 | u32 a = sgimc->gio_dma_trans; | 368 | u32 a = sgimc->gio_dma_trans; |
369 | a = (sgimc->gmaddronly & ~a) | (sgimc->gio_dma_sbits & a); | 369 | a = (sgimc->gmaddronly & ~a) | (sgimc->gio_dma_sbits & a); |
370 | return (gio_err_addr == a); | 370 | return gio_err_addr == a; |
371 | } | 371 | } |
372 | return 0; | 372 | return 0; |
373 | } | 373 | } |
diff --git a/arch/mips/sgi-ip27/ip27-klnuma.c b/arch/mips/sgi-ip27/ip27-klnuma.c index 7a53b1e28a93..ecbb62f339c5 100644 --- a/arch/mips/sgi-ip27/ip27-klnuma.c +++ b/arch/mips/sgi-ip27/ip27-klnuma.c | |||
@@ -125,8 +125,7 @@ unsigned long node_getfirstfree(cnodeid_t cnode) | |||
125 | #endif | 125 | #endif |
126 | offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase; | 126 | offset = PAGE_ALIGN((unsigned long)(&_end)) - loadbase; |
127 | if ((cnode == 0) || (cpu_isset(cnode, ktext_repmask))) | 127 | if ((cnode == 0) || (cpu_isset(cnode, ktext_repmask))) |
128 | return (TO_NODE(nasid, offset) >> PAGE_SHIFT); | 128 | return TO_NODE(nasid, offset) >> PAGE_SHIFT; |
129 | else | 129 | else |
130 | return (KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >> | 130 | return KDM_TO_PHYS(PAGE_ALIGN(SYMMON_STK_ADDR(nasid, 0))) >> PAGE_SHIFT; |
131 | PAGE_SHIFT); | ||
132 | } | 131 | } |
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c index a304bcc37e4f..0b68469e063f 100644 --- a/arch/mips/sgi-ip27/ip27-memory.c +++ b/arch/mips/sgi-ip27/ip27-memory.c | |||
@@ -42,8 +42,7 @@ static int fine_mode; | |||
42 | 42 | ||
43 | static int is_fine_dirmode(void) | 43 | static int is_fine_dirmode(void) |
44 | { | 44 | { |
45 | return (((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK) | 45 | return ((LOCAL_HUB_L(NI_STATUS_REV_ID) & NSRI_REGIONSIZE_MASK) >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE; |
46 | >> NSRI_REGIONSIZE_SHFT) & REGIONSIZE_FINE); | ||
47 | } | 46 | } |
48 | 47 | ||
49 | static hubreg_t get_region(cnodeid_t cnode) | 48 | static hubreg_t get_region(cnodeid_t cnode) |
@@ -288,7 +287,7 @@ static unsigned long __init slot_psize_compute(cnodeid_t node, int slot) | |||
288 | if (size <= 128) { | 287 | if (size <= 128) { |
289 | if (slot % 4 == 0) { | 288 | if (slot % 4 == 0) { |
290 | size <<= 20; /* size in bytes */ | 289 | size <<= 20; /* size in bytes */ |
291 | return(size >> PAGE_SHIFT); | 290 | return size >> PAGE_SHIFT; |
292 | } else | 291 | } else |
293 | return 0; | 292 | return 0; |
294 | } else { | 293 | } else { |
diff --git a/arch/mips/sibyte/common/cfe.c b/arch/mips/sibyte/common/cfe.c index 588e1806a1a3..c1a11a11db7f 100644 --- a/arch/mips/sibyte/common/cfe.c +++ b/arch/mips/sibyte/common/cfe.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #define MAX_RAM_SIZE (~0ULL) | 38 | #define MAX_RAM_SIZE (~0ULL) |
39 | #else | 39 | #else |
40 | #ifdef CONFIG_HIGHMEM | 40 | #ifdef CONFIG_HIGHMEM |
41 | #ifdef CONFIG_64BIT_PHYS_ADDR | 41 | #ifdef CONFIG_PHYS_ADDR_T_64BIT |
42 | #define MAX_RAM_SIZE (~0ULL) | 42 | #define MAX_RAM_SIZE (~0ULL) |
43 | #else | 43 | #else |
44 | #define MAX_RAM_SIZE (0xffffffffULL) | 44 | #define MAX_RAM_SIZE (0xffffffffULL) |
@@ -49,8 +49,8 @@ | |||
49 | #endif | 49 | #endif |
50 | 50 | ||
51 | #define SIBYTE_MAX_MEM_REGIONS 8 | 51 | #define SIBYTE_MAX_MEM_REGIONS 8 |
52 | phys_t board_mem_region_addrs[SIBYTE_MAX_MEM_REGIONS]; | 52 | phys_addr_t board_mem_region_addrs[SIBYTE_MAX_MEM_REGIONS]; |
53 | phys_t board_mem_region_sizes[SIBYTE_MAX_MEM_REGIONS]; | 53 | phys_addr_t board_mem_region_sizes[SIBYTE_MAX_MEM_REGIONS]; |
54 | unsigned int board_mem_region_count; | 54 | unsigned int board_mem_region_count; |
55 | 55 | ||
56 | int cfe_cons_handle; | 56 | int cfe_cons_handle; |
@@ -96,7 +96,7 @@ static void __noreturn cfe_linux_halt(void) | |||
96 | 96 | ||
97 | static __init void prom_meminit(void) | 97 | static __init void prom_meminit(void) |
98 | { | 98 | { |
99 | u64 addr, size, type; /* regardless of 64BIT_PHYS_ADDR */ | 99 | u64 addr, size, type; /* regardless of PHYS_ADDR_T_64BIT */ |
100 | int mem_flags = 0; | 100 | int mem_flags = 0; |
101 | unsigned int idx; | 101 | unsigned int idx; |
102 | int rd_flag; | 102 | int rd_flag; |
diff --git a/arch/mips/sibyte/swarm/platform.c b/arch/mips/sibyte/swarm/platform.c index 9480c14ec66a..1cecdcf85cf1 100644 --- a/arch/mips/sibyte/swarm/platform.c +++ b/arch/mips/sibyte/swarm/platform.c | |||
@@ -50,7 +50,7 @@ static struct platform_device swarm_pata_device = { | |||
50 | static int __init swarm_pata_init(void) | 50 | static int __init swarm_pata_init(void) |
51 | { | 51 | { |
52 | u8 __iomem *base; | 52 | u8 __iomem *base; |
53 | phys_t offset, size; | 53 | phys_addr_t offset, size; |
54 | struct resource *r; | 54 | struct resource *r; |
55 | 55 | ||
56 | if (!SIBYTE_HAVE_IDE) | 56 | if (!SIBYTE_HAVE_IDE) |
diff --git a/arch/mips/sibyte/swarm/rtc_m41t81.c b/arch/mips/sibyte/swarm/rtc_m41t81.c index b732600b47f5..e62466445f08 100644 --- a/arch/mips/sibyte/swarm/rtc_m41t81.c +++ b/arch/mips/sibyte/swarm/rtc_m41t81.c | |||
@@ -109,7 +109,7 @@ static int m41t81_read(uint8_t addr) | |||
109 | return -1; | 109 | return -1; |
110 | } | 110 | } |
111 | 111 | ||
112 | return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff); | 112 | return __raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff; |
113 | } | 113 | } |
114 | 114 | ||
115 | static int m41t81_write(uint8_t addr, int b) | 115 | static int m41t81_write(uint8_t addr, int b) |
@@ -229,5 +229,5 @@ int m41t81_probe(void) | |||
229 | tmp = m41t81_read(M41T81REG_SC); | 229 | tmp = m41t81_read(M41T81REG_SC); |
230 | m41t81_write(M41T81REG_SC, tmp & 0x7f); | 230 | m41t81_write(M41T81REG_SC, tmp & 0x7f); |
231 | 231 | ||
232 | return (m41t81_read(M41T81REG_SC) != -1); | 232 | return m41t81_read(M41T81REG_SC) != -1; |
233 | } | 233 | } |
diff --git a/arch/mips/sibyte/swarm/rtc_xicor1241.c b/arch/mips/sibyte/swarm/rtc_xicor1241.c index 178a824b28d4..50a82c495427 100644 --- a/arch/mips/sibyte/swarm/rtc_xicor1241.c +++ b/arch/mips/sibyte/swarm/rtc_xicor1241.c | |||
@@ -84,7 +84,7 @@ static int xicor_read(uint8_t addr) | |||
84 | return -1; | 84 | return -1; |
85 | } | 85 | } |
86 | 86 | ||
87 | return (__raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff); | 87 | return __raw_readq(SMB_CSR(R_SMB_DATA)) & 0xff; |
88 | } | 88 | } |
89 | 89 | ||
90 | static int xicor_write(uint8_t addr, int b) | 90 | static int xicor_write(uint8_t addr, int b) |
@@ -206,5 +206,5 @@ unsigned long xicor_get_time(void) | |||
206 | 206 | ||
207 | int xicor_probe(void) | 207 | int xicor_probe(void) |
208 | { | 208 | { |
209 | return (xicor_read(X1241REG_SC) != -1); | 209 | return xicor_read(X1241REG_SC) != -1; |
210 | } | 210 | } |
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c index 3462c831d0ea..494fb0a475ac 100644 --- a/arch/mips/sibyte/swarm/setup.c +++ b/arch/mips/sibyte/swarm/setup.c | |||
@@ -76,7 +76,7 @@ int swarm_be_handler(struct pt_regs *regs, int is_fixup) | |||
76 | printk("DBE physical address: %010Lx\n", | 76 | printk("DBE physical address: %010Lx\n", |
77 | __read_64bit_c0_register($26, 1)); | 77 | __read_64bit_c0_register($26, 1)); |
78 | } | 78 | } |
79 | return (is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL); | 79 | return is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL; |
80 | } | 80 | } |
81 | 81 | ||
82 | enum swarm_rtc_type { | 82 | enum swarm_rtc_type { |
diff --git a/arch/mips/txx9/generic/setup_tx4927.c b/arch/mips/txx9/generic/setup_tx4927.c index e714d6ce9a82..a4664cb6c1e1 100644 --- a/arch/mips/txx9/generic/setup_tx4927.c +++ b/arch/mips/txx9/generic/setup_tx4927.c | |||
@@ -29,8 +29,8 @@ static void __init tx4927_wdr_init(void) | |||
29 | { | 29 | { |
30 | /* report watchdog reset status */ | 30 | /* report watchdog reset status */ |
31 | if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDRST) | 31 | if (____raw_readq(&tx4927_ccfgptr->ccfg) & TX4927_CCFG_WDRST) |
32 | pr_warning("Watchdog reset detected at 0x%lx\n", | 32 | pr_warn("Watchdog reset detected at 0x%lx\n", |
33 | read_c0_errorepc()); | 33 | read_c0_errorepc()); |
34 | /* clear WatchDogReset (W1C) */ | 34 | /* clear WatchDogReset (W1C) */ |
35 | tx4927_ccfg_set(TX4927_CCFG_WDRST); | 35 | tx4927_ccfg_set(TX4927_CCFG_WDRST); |
36 | /* do reset on watchdog */ | 36 | /* do reset on watchdog */ |
diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c index 0a3bf2dfaba1..58cdb2aba5e1 100644 --- a/arch/mips/txx9/generic/setup_tx4938.c +++ b/arch/mips/txx9/generic/setup_tx4938.c | |||
@@ -31,8 +31,8 @@ static void __init tx4938_wdr_init(void) | |||
31 | { | 31 | { |
32 | /* report watchdog reset status */ | 32 | /* report watchdog reset status */ |
33 | if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDRST) | 33 | if (____raw_readq(&tx4938_ccfgptr->ccfg) & TX4938_CCFG_WDRST) |
34 | pr_warning("Watchdog reset detected at 0x%lx\n", | 34 | pr_warn("Watchdog reset detected at 0x%lx\n", |
35 | read_c0_errorepc()); | 35 | read_c0_errorepc()); |
36 | /* clear WatchDogReset (W1C) */ | 36 | /* clear WatchDogReset (W1C) */ |
37 | tx4938_ccfg_set(TX4938_CCFG_WDRST); | 37 | tx4938_ccfg_set(TX4938_CCFG_WDRST); |
38 | /* do reset on watchdog */ | 38 | /* do reset on watchdog */ |
diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c index b7eccbd17bf7..e3733cde50d6 100644 --- a/arch/mips/txx9/generic/setup_tx4939.c +++ b/arch/mips/txx9/generic/setup_tx4939.c | |||
@@ -35,8 +35,8 @@ static void __init tx4939_wdr_init(void) | |||
35 | { | 35 | { |
36 | /* report watchdog reset status */ | 36 | /* report watchdog reset status */ |
37 | if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDRST) | 37 | if (____raw_readq(&tx4939_ccfgptr->ccfg) & TX4939_CCFG_WDRST) |
38 | pr_warning("Watchdog reset detected at 0x%lx\n", | 38 | pr_warn("Watchdog reset detected at 0x%lx\n", |
39 | read_c0_errorepc()); | 39 | read_c0_errorepc()); |
40 | /* clear WatchDogReset (W1C) */ | 40 | /* clear WatchDogReset (W1C) */ |
41 | tx4939_ccfg_set(TX4939_CCFG_WDRST); | 41 | tx4939_ccfg_set(TX4939_CCFG_WDRST); |
42 | /* do reset on watchdog */ | 42 | /* do reset on watchdog */ |