diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-15 09:26:12 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-10-15 09:26:12 -0700 |
commit | 133d970e0dadf7b413db19893acc5b26664bf4a1 (patch) | |
tree | ea10732ca1d0f663ef1319973947a7c72cf170e7 | |
parent | 050aaeab99067b6a08b34274ff15ca5dbb94a160 (diff) | |
parent | 38b8767462120c62a5046b529c80b06861f9ac85 (diff) | |
download | linux-133d970e0dadf7b413db19893acc5b26664bf4a1.tar.gz linux-133d970e0dadf7b413db19893acc5b26664bf4a1.tar.bz2 linux-133d970e0dadf7b413db19893acc5b26664bf4a1.zip |
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS updates from Ralf Baechle:
"This is the main MIPS pull request for 4.9:
MIPS core arch code:
- traps: 64bit kernels should read CP0_EBase 64bit
- traps: Convert ebase to KSEG0
- c-r4k: Drop bc_wback_inv() from icache flush
- c-r4k: Split user/kernel flush_icache_range()
- cacheflush: Use __flush_icache_user_range()
- uprobes: Flush icache via kernel address
- KVM: Use __local_flush_icache_user_range()
- c-r4k: Fix flush_icache_range() for EVA
- Fix -mabi=64 build of vdso.lds
- VDSO: Drop duplicated -I*/-E* aflags
- tracing: move insn_has_delay_slot to a shared header
- tracing: disable uprobe/kprobe on compact branch instructions
- ptrace: Fix regs_return_value for kernel context
- Squash lines for simple wrapper functions
- Move identification of VP(E) into proc.c from smp-mt.c
- Add definitions of SYNC barrierstype values
- traps: Ensure full EBase is written
- tlb-r4k: If there are wired entries, don't use TLBINVF
- Sanitise coherentio semantics
- dma-default: Don't check hw_coherentio if device is non-coherent
- Support per-device DMA coherence
- Adjust MIPS64 CAC_BASE to reflect Config.K0
- Support generating Flattened Image Trees (.itb)
- generic: Introduce generic DT-based board support
- generic: Convert SEAD-3 to a generic board
- Enable hardened usercopy
- Don't specify STACKPROTECTOR in defconfigs
Octeon:
- Delete dead code and files across the platform.
- Change to use all memory into use by default.
- Rename upper case variables in setup code to lowercase.
- Delete legacy hack for broken bootloaders.
- Leave maintaining the link state to the actual ethernet/PHY drivers.
- Add DTS for D-Link DSR-500N.
- Fix PCI interrupt routing on D-Link DSR-500N.
Pistachio:
- Remove ANDROID_TIMED_OUTPUT from defconfig
TX39xx:
- Move GPIO setup from .mem_setup() to .arch_init()
- Convert to Common Clock Framework
TX49xx:
- Move GPIO setup from .mem_setup() to .arch_init()
- Convert to Common Clock Framework
txx9wdt:
- Add missing clock (un)prepare calls for CCF
BMIPS:
- Add PW, GPIO SDHCI and NAND device node names
- Support APPENDED_DTB
- Add missing bcm97435svmb to DT_NONE
- Rename bcm96358nb4ser to bcm6358-neufbox4-sercom
- Add DT examples for BCM63268, BCM3368 and BCM6362
- Add support for BCM3368 and BCM6362
PCI
- Reduce stack frame usage
- Use struct list_head lists
- Support for CONFIG_PCI_DOMAINS_GENERIC
- Make pcibios_set_cache_line_size an initcall
- Inline pcibios_assign_all_busses
- Split pci.c into pci.c & pci-legacy.c
- Introduce CONFIG_PCI_DRIVERS_LEGACY
- Support generic drivers
CPC
- Convert bare 'unsigned' to 'unsigned int'
- Avoid lock when MIPS CM >= 3 is present
GIC:
- Delete unused file smp-gic.c
mt7620:
- Delete unnecessary assignment for the field "owner" from PCI
BCM63xx:
- Let clk_disable() return immediately if clk is NULL
pm-cps:
- Change FSB workaround to CPU blacklist
- Update comments on barrier instructions
- Use MIPS standard lightweight ordering barrier
- Use MIPS standard completion barrier
- Remove selection of sync types
- Add MIPSr6 CPU support
- Support CM3 changes to Coherence Enable Register
SMP:
- Wrap call to mips_cpc_lock_other in mips_cm_lock_other
- Introduce mechanism for freeing and allocating IPIs
cpuidle:
- cpuidle-cps: Enable use with MIPSr6 CPUs.
SEAD3:
- Rewrite to use DT and generic kernel feature.
USB:
- host: ehci-sead3: Remove SEAD-3 EHCI code
FBDEV:
- cobalt_lcdfb: Drop SEAD3 support
dt-bindings:
- Document a binding for simple ASCII LCDs
auxdisplay:
- img-ascii-lcd: driver for simple ASCII LCD displays
irqchip i8259:
- i8259: Add domain before mapping parent irq
- i8259: Allow platforms to override poll function
- i8259: Remove unused i8259A_irq_pending
Malta:
- Rewrite to use DT
of/platform:
- Probe "isa" busses by default
CM:
- Print CM error reports upon bus errors
Module:
- Migrate exception table users off module.h and onto extable.h
- Make various drivers explicitly non-modular:
- Audit and remove any unnecessary uses of module.h
mailmap:
- Canonicalize to Qais' current email address.
Documentation:
- MIPS supports HAVE_REGS_AND_STACK_ACCESS_API
Loongson1C:
- Add CPU support for Loongson1C
- Add board support
- Add defconfig
- Add RTC support for Loongson1C board
All this except one Documentation fix has sat in linux-next and has
survived Imagination's automated build test system"
* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (127 commits)
Documentation: MIPS supports HAVE_REGS_AND_STACK_ACCESS_API
MIPS: ptrace: Fix regs_return_value for kernel context
MIPS: VDSO: Drop duplicated -I*/-E* aflags
MIPS: Fix -mabi=64 build of vdso.lds
MIPS: Enable hardened usercopy
MIPS: generic: Convert SEAD-3 to a generic board
MIPS: generic: Introduce generic DT-based board support
MIPS: Support generating Flattened Image Trees (.itb)
MIPS: Adjust MIPS64 CAC_BASE to reflect Config.K0
MIPS: Print CM error reports upon bus errors
MIPS: Support per-device DMA coherence
MIPS: dma-default: Don't check hw_coherentio if device is non-coherent
MIPS: Sanitise coherentio semantics
MIPS: PCI: Support generic drivers
MIPS: PCI: Introduce CONFIG_PCI_DRIVERS_LEGACY
MIPS: PCI: Split pci.c into pci.c & pci-legacy.c
MIPS: PCI: Inline pcibios_assign_all_busses
MIPS: PCI: Make pcibios_set_cache_line_size an initcall
MIPS: PCI: Support for CONFIG_PCI_DOMAINS_GENERIC
MIPS: PCI: Use struct list_head lists
...
226 files changed, 5242 insertions, 3657 deletions
@@ -127,6 +127,7 @@ Peter Oruba <peter@oruba.de> Peter Oruba <peter.oruba@amd.com> Pratyush Anand <pratyush.anand@gmail.com> <pratyush.anand@st.com> Praveen BP <praveenbp@ti.com> +Qais Yousef <qsyousef@gmail.com> <qais.yousef@imgtec.com> Rajesh Shah <rajesh.shah@intel.com> Ralf Baechle <ralf@linux-mips.org> Ralf Wildenhues <Ralf.Wildenhues@gmx.de> diff --git a/Documentation/devicetree/bindings/auxdisplay/img-ascii-lcd.txt b/Documentation/devicetree/bindings/auxdisplay/img-ascii-lcd.txt new file mode 100644 index 000000000000..b69bb68992fd --- /dev/null +++ b/Documentation/devicetree/bindings/auxdisplay/img-ascii-lcd.txt @@ -0,0 +1,17 @@ +Binding for ASCII LCD displays on Imagination Technologies boards + +Required properties: +- compatible : should be one of: + "img,boston-lcd" + "mti,malta-lcd" + "mti,sead3-lcd" + +Required properties for "img,boston-lcd": +- reg : memory region locating the device registers + +Required properties for "mti,malta-lcd" or "mti,sead3-lcd": +- regmap: phandle of the system controller containing the LCD registers +- offset: offset in bytes to the LCD registers within the system controller + +The layout of the registers & properties of the display are determined +from the compatible string, making this binding somewhat trivial. diff --git a/Documentation/devicetree/bindings/mips/brcm/soc.txt b/Documentation/devicetree/bindings/mips/brcm/soc.txt index 4a7e030e4f9b..e4e1cd91fb1f 100644 --- a/Documentation/devicetree/bindings/mips/brcm/soc.txt +++ b/Documentation/devicetree/bindings/mips/brcm/soc.txt @@ -2,9 +2,9 @@ Required properties: -- compatible: "brcm,bcm3384", "brcm,bcm33843" +- compatible: "brcm,bcm3368", "brcm,bcm3384", "brcm,bcm33843" "brcm,bcm3384-viper", "brcm,bcm33843-viper" - "brcm,bcm6328", "brcm,bcm6358", "brcm,bcm6368", + "brcm,bcm6328", "brcm,bcm6358", "brcm,bcm6362", "brcm,bcm6368", "brcm,bcm63168", "brcm,bcm63268", "brcm,bcm7125", "brcm,bcm7346", "brcm,bcm7358", "brcm,bcm7360", "brcm,bcm7362", "brcm,bcm7420", "brcm,bcm7425" diff --git a/Documentation/features/perf/kprobes-event/arch-support.txt b/Documentation/features/perf/kprobes-event/arch-support.txt index 9855ad044386..4660bf222db1 100644 --- a/Documentation/features/perf/kprobes-event/arch-support.txt +++ b/Documentation/features/perf/kprobes-event/arch-support.txt @@ -22,7 +22,7 @@ | m68k: | TODO | | metag: | TODO | | microblaze: | TODO | - | mips: | TODO | + | mips: | ok | | mn10300: | TODO | | nios2: | TODO | | openrisc: | TODO | diff --git a/MAINTAINERS b/MAINTAINERS index 5f5e5caefc35..1cd38a7e0064 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6131,6 +6131,12 @@ M: Stanislaw Gruszka <stf_xl@wp.pl> S: Maintained F: drivers/usb/atm/ueagle-atm.c +IMGTEC ASCII LCD DRIVER +M: Paul Burton <paul.burton@imgtec.com> +S: Maintained +F: Documentation/devicetree/bindings/auxdisplay/img-ascii-lcd.txt +F: drivers/auxdisplay/img-ascii-lcd.c + INA209 HARDWARE MONITOR DRIVER M: Guenter Roeck <linux@roeck-us.net> L: linux-hwmon@vger.kernel.org diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms index c5cd63a4b6d5..f5f1bdb292de 100644 --- a/arch/mips/Kbuild.platforms +++ b/arch/mips/Kbuild.platforms @@ -11,6 +11,7 @@ platforms += cavium-octeon platforms += cobalt platforms += dec platforms += emma +platforms += generic platforms += jazz platforms += jz4740 platforms += lantiq @@ -18,7 +19,6 @@ platforms += lasat platforms += loongson32 platforms += loongson64 platforms += mti-malta -platforms += mti-sead3 platforms += netlogic platforms += paravirt platforms += pic32 diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 1a322c807f22..b3c5bde43d34 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -65,6 +65,7 @@ config MIPS select HANDLE_DOMAIN_IRQ select HAVE_EXIT_THREAD select HAVE_REGS_AND_STACK_ACCESS_API + select HAVE_ARCH_HARDENED_USERCOPY menu "Machine selection" @@ -72,6 +73,57 @@ choice prompt "System type" default SGI_IP22 +config MIPS_GENERIC + bool "Generic board-agnostic MIPS kernel" + select BOOT_RAW + select BUILTIN_DTB + select CEVT_R4K + select CLKSRC_MIPS_GIC + select COMMON_CLK + select CPU_MIPSR2_IRQ_VI + select CPU_MIPSR2_IRQ_EI + select CSRC_R4K + select DMA_PERDEV_COHERENT + select HW_HAS_PCI + select IRQ_MIPS_CPU + select LIBFDT + select MIPS_CPU_SCACHE + select MIPS_GIC + select MIPS_L1_CACHE_SHIFT_7 + select NO_EXCEPT_FILL + select PCI_DRIVERS_GENERIC + select PINCTRL + select SMP_UP if SMP + select SYS_HAS_CPU_MIPS32_R1 + select SYS_HAS_CPU_MIPS32_R2 + select SYS_HAS_CPU_MIPS32_R6 + select SYS_HAS_CPU_MIPS64_R1 + select SYS_HAS_CPU_MIPS64_R2 + select SYS_HAS_CPU_MIPS64_R6 + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_64BIT_KERNEL + select SYS_SUPPORTS_BIG_ENDIAN + select SYS_SUPPORTS_HIGHMEM + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_MICROMIPS + select SYS_SUPPORTS_MIPS_CPS + select SYS_SUPPORTS_MIPS16 + select SYS_SUPPORTS_MULTITHREADING + select SYS_SUPPORTS_RELOCATABLE + select SYS_SUPPORTS_SMARTMIPS + select USB_EHCI_BIG_ENDIAN_DESC if BIG_ENDIAN + select USB_EHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN + select USB_OHCI_BIG_ENDIAN_DESC if BIG_ENDIAN + select USB_OHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN + select USB_UHCI_BIG_ENDIAN_DESC if BIG_ENDIAN + select USB_UHCI_BIG_ENDIAN_MMIO if BIG_ENDIAN + select USE_OF + help + Select this to build a kernel which aims to support multiple boards, + generally using a flattened device tree passed from the bootloader + using the boot protocol defined in the UHI (Unified Hosting + Interface) specification. + config MIPS_ALCHEMY bool "Alchemy processor based machines" select ARCH_PHYS_ADDR_T_64BIT @@ -478,6 +530,7 @@ config MIPS_MALTA select SYS_SUPPORTS_ZBOOT select SYS_SUPPORTS_RELOCATABLE select USE_OF + select LIBFDT select ZONE_DMA32 if 64BIT select BUILTIN_DTB select LIBFDT @@ -493,42 +546,6 @@ config MACH_PIC32 Microchip PIC32 is a family of general-purpose 32 bit MIPS core microcontrollers. -config MIPS_SEAD3 - bool "MIPS SEAD3 board" - select BOOT_ELF32 - select BOOT_RAW - select BUILTIN_DTB - select CEVT_R4K - select CSRC_R4K - select CLKSRC_MIPS_GIC - select COMMON_CLK - select CPU_MIPSR2_IRQ_VI - select CPU_MIPSR2_IRQ_EI - select DMA_NONCOHERENT - select IRQ_MIPS_CPU - select MIPS_GIC - select LIBFDT - select MIPS_MSC - select SYS_HAS_CPU_MIPS32_R1 - select SYS_HAS_CPU_MIPS32_R2 - select SYS_HAS_CPU_MIPS32_R6 - select SYS_HAS_CPU_MIPS64_R1 - select SYS_HAS_EARLY_PRINTK - select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL - select SYS_SUPPORTS_BIG_ENDIAN - select SYS_SUPPORTS_LITTLE_ENDIAN - select SYS_SUPPORTS_SMARTMIPS - select SYS_SUPPORTS_MICROMIPS - select SYS_SUPPORTS_MIPS16 - select SYS_SUPPORTS_RELOCATABLE - select USB_EHCI_BIG_ENDIAN_DESC - select USB_EHCI_BIG_ENDIAN_MMIO - select USE_OF - help - This enables support for the MIPS Technologies SEAD3 evaluation - board. - config NEC_MARKEINS bool "NEC EMMA2RH Mark-eins board" select SOC_EMMA2RH @@ -988,6 +1005,7 @@ source "arch/mips/ath79/Kconfig" source "arch/mips/bcm47xx/Kconfig" source "arch/mips/bcm63xx/Kconfig" source "arch/mips/bmips/Kconfig" +source "arch/mips/generic/Kconfig" source "arch/mips/jazz/Kconfig" source "arch/mips/jz4740/Kconfig" source "arch/mips/lantiq/Kconfig" @@ -1098,6 +1116,10 @@ config DMA_MAYBE_COHERENT select DMA_NONCOHERENT bool +config DMA_PERDEV_COHERENT + bool + select DMA_MAYBE_COHERENT + config DMA_COHERENT bool @@ -1401,6 +1423,16 @@ config CPU_LOONGSON1B The Loongson 1B is a 32-bit SoC, which implements the MIPS32 release 2 instruction set. +config CPU_LOONGSON1C + bool "Loongson 1C" + depends on SYS_HAS_CPU_LOONGSON1C + select CPU_LOONGSON1 + select ARCH_WANT_OPTIONAL_GPIOLIB + select LEDS_GPIO_REGISTER + help + The Loongson 1C is a 32-bit SoC, which implements the MIPS32 + release 2 instruction set. + config CPU_MIPS32_R1 bool "MIPS32 Release 1" depends on SYS_HAS_CPU_MIPS32_R1 @@ -1850,6 +1882,9 @@ config SYS_HAS_CPU_LOONGSON2F config SYS_HAS_CPU_LOONGSON1B bool +config SYS_HAS_CPU_LOONGSON1C + bool + config SYS_HAS_CPU_MIPS32_R1 bool @@ -2906,7 +2941,7 @@ endchoice choice prompt "Kernel command line type" if !CMDLINE_OVERRIDE default MIPS_CMDLINE_FROM_DTB if USE_OF && !ATH79 && !MACH_INGENIC && \ - !MIPS_MALTA && !MIPS_SEAD3 && \ + !MIPS_MALTA && \ !CAVIUM_OCTEON_SOC default MIPS_CMDLINE_FROM_BOOTLOADER @@ -2960,7 +2995,6 @@ config PCI bool "Support for PCI controller" depends on HW_HAS_PCI select PCI_DOMAINS - select NO_GENERIC_PCI_IOPORT_MAP help Find out whether you have a PCI motherboard. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside @@ -2981,6 +3015,17 @@ config HT_PCI config PCI_DOMAINS bool +config PCI_DOMAINS_GENERIC + bool + +config PCI_DRIVERS_GENERIC + select PCI_DOMAINS_GENERIC if PCI_DOMAINS + bool + +config PCI_DRIVERS_LEGACY + def_bool !PCI_DRIVERS_GENERIC + select NO_GENERIC_PCI_IOPORT_MAP + source "drivers/pci/Kconfig" # diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 598ab2930fce..fbf40d3c8123 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -262,7 +262,14 @@ KBUILD_CPPFLAGS += -DVMLINUX_LOAD_ADDRESS=$(load-y) KBUILD_CPPFLAGS += -DDATAOFFSET=$(if $(dataoffset-y),$(dataoffset-y),0) bootvars-y = VMLINUX_LOAD_ADDRESS=$(load-y) \ - VMLINUX_ENTRY_ADDRESS=$(entry-y) + VMLINUX_ENTRY_ADDRESS=$(entry-y) \ + PLATFORM=$(platform-y) +ifdef CONFIG_32BIT +bootvars-y += ADDR_BITS=32 +endif +ifdef CONFIG_64BIT +bootvars-y += ADDR_BITS=64 +endif LDFLAGS += -m $(ld-emul) @@ -302,6 +309,11 @@ boot-y += uImage.gz boot-y += uImage.lzma boot-y += uImage.lzo endif +boot-y += vmlinux.itb +boot-y += vmlinux.gz.itb +boot-y += vmlinux.bz2.itb +boot-y += vmlinux.lzma.itb +boot-y += vmlinux.lzo.itb # compressed boot image targets (arch/mips/boot/compressed/) bootz-y := vmlinuz @@ -425,4 +437,67 @@ define archhelp echo ' dtbs_install - Install dtbs to $(INSTALL_DTBS_PATH)' echo echo ' These will be default as appropriate for a configured platform.' + echo + echo ' If you are targeting a system supported by generic kernels you may' + echo ' configure the kernel for a given architecture target like so:' + echo + echo ' {micro32,32,64}{r1,r2,r6}{el,}_defconfig <BOARDS="list of boards">' + echo + echo ' Otherwise, the following default configurations are available:' endef + +generic_config_dir = $(srctree)/arch/$(ARCH)/configs/generic +generic_defconfigs := + +# +# If the user generates a generic kernel configuration without specifying a +# list of boards to include the config fragments for, default to including all +# available board config fragments. +# +ifeq ($(BOARDS),) +BOARDS = $(patsubst board-%.config,%,$(notdir $(wildcard $(generic_config_dir)/board-*.config))) +endif + +# +# Generic kernel configurations which merge generic_defconfig with the +# appropriate config fragments from arch/mips/configs/generic/, resulting in +# the ability to easily configure the kernel for a given architecture, +# endianness & set of boards without duplicating the needed configuration in +# hundreds of defconfig files. +# +define gen_generic_defconfigs +$(foreach bits,$(1),$(foreach rev,$(2),$(foreach endian,$(3), +target := $(bits)$(rev)$(filter el,$(endian))_defconfig +generic_defconfigs += $$(target) +$$(target): $(generic_config_dir)/$(bits)$(rev).config +$$(target): $(generic_config_dir)/$(endian).config +))) +endef + +$(eval $(call gen_generic_defconfigs,32 64,r1 r2 r6,eb el)) +$(eval $(call gen_generic_defconfigs,micro32,r2,eb el)) + +.PHONY: $(generic_defconfigs) +$(generic_defconfigs): + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh \ + -m -O $(objtree) $(srctree)/arch/$(ARCH)/configs/generic_defconfig $^ \ + $(foreach board,$(BOARDS),$(generic_config_dir)/board-$(board).config) + $(Q)$(MAKE) olddefconfig + +# +# Prevent generic merge_config rules attempting to merge single fragments +# +$(generic_config_dir)/%.config: ; + +# +# Legacy defconfig compatibility - these targets used to be real defconfigs but +# now that the boards have been converted to use the generic kernel they are +# wrappers around the generic rules above. +# +.PHONY: sead3_defconfig +sead3_defconfig: + $(Q)$(MAKE) 32r2el_defconfig BOARDS=sead-3 + +.PHONY: sead3micro_defconfig +sead3micro_defconfig: + $(Q)$(MAKE) micro32r2el_defconfig BOARDS=sead-3 diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c index 2902138b3e0f..7faaa6d593a7 100644 --- a/arch/mips/alchemy/common/setup.c +++ b/arch/mips/alchemy/common/setup.c @@ -48,17 +48,17 @@ void __init plat_mem_setup(void) clear_c0_config(1 << 19); /* Clear Config[OD] */ hw_coherentio = 0; - coherentio = 1; + coherentio = IO_COHERENCE_ENABLED; switch (alchemy_get_cputype()) { case ALCHEMY_CPU_AU1000: case ALCHEMY_CPU_AU1500: case ALCHEMY_CPU_AU1100: - coherentio = 0; + coherentio = IO_COHERENCE_DISABLED; break; case ALCHEMY_CPU_AU1200: /* Au1200 AB USB does not support coherent memory */ if (0 == (read_c0_prid() & PRID_REV_MASK)) - coherentio = 0; + coherentio = IO_COHERENCE_DISABLED; break; } diff --git a/arch/mips/bcm47xx/serial.c b/arch/mips/bcm47xx/serial.c index df761d38f7fc..e3c9872a4aa5 100644 --- a/arch/mips/bcm47xx/serial.c +++ b/arch/mips/bcm47xx/serial.c @@ -1,4 +1,7 @@ /* + * 8250 UART probe driver for the BCM47XX platforms + * Author: Aurelien Jarno + * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. @@ -6,7 +9,6 @@ * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net> */ -#include <linux/module.h> #include <linux/init.h> #include <linux/serial.h> #include <linux/serial_8250.h> @@ -88,9 +90,4 @@ static int __init uart8250_init(void) } return -EINVAL; } - -module_init(uart8250_init); - -MODULE_AUTHOR("Aurelien Jarno <aurelien@aurel32.net>"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("8250 UART probe driver for the BCM47XX platforms"); +device_initcall(uart8250_init); diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c index 637565284732..b49fc9cb9cad 100644 --- a/arch/mips/bcm63xx/clk.c +++ b/arch/mips/bcm63xx/clk.c @@ -326,6 +326,9 @@ EXPORT_SYMBOL(clk_enable); void clk_disable(struct clk *clk) { + if (!clk) + return; + mutex_lock(&clocks_mutex); clk_disable_unlocked(clk); mutex_unlock(&clocks_mutex); diff --git a/arch/mips/bmips/Kconfig b/arch/mips/bmips/Kconfig index 264328d528c7..2d60f25403de 100644 --- a/arch/mips/bmips/Kconfig +++ b/arch/mips/bmips/Kconfig @@ -21,10 +21,6 @@ config DT_BCM93384WVG_VIPER bool "BCM93384WVG Viper CPU (EXPERIMENTAL)" select BUILTIN_DTB -config DT_BCM96358NB4SER - bool "BCM96358NB4SER" - select BUILTIN_DTB - config DT_BCM96368MVWG bool "BCM96368MVWG" select BUILTIN_DTB @@ -65,6 +61,22 @@ config DT_BCM97435SVMB bool "BCM97435SVMB" select BUILTIN_DTB +config DT_COMTREND_VR3032U + bool "Comtrend VR-3032u" + select BUILTIN_DTB + +config DT_NETGEAR_CVG834G + bool "NETGEAR CVG834G" + select BUILTIN_DTB + +config DT_SFR_NEUFBOX4_SERCOMM + bool "SFR Neufbox 4 (Sercomm)" + select BUILTIN_DTB + +config DT_SFR_NEUFBOX6_SERCOMM + bool "SFR Neufbox 6 (Sercomm)" + select BUILTIN_DTB + endchoice endif diff --git a/arch/mips/bmips/setup.c b/arch/mips/bmips/setup.c index 6776042679dd..3b6f687f177c 100644 --- a/arch/mips/bmips/setup.c +++ b/arch/mips/bmips/setup.c @@ -17,6 +17,7 @@ #include <linux/of.h> #include <linux/of_fdt.h> #include <linux/of_platform.h> +#include <linux/libfdt.h> #include <linux/smp.h> #include <asm/addrspace.h> #include <asm/bmips.h> @@ -98,7 +99,7 @@ static void bcm6328_quirks(void) static void bcm6358_quirks(void) { /* - * BCM6358 needs special handling for its shared TLB, so + * BCM3368/BCM6358 need special handling for their shared TLB, so * disable SMP for now */ bmips_smp_enabled = 0; @@ -110,10 +111,12 @@ static void bcm6368_quirks(void) } static const struct bmips_quirk bmips_quirk_list[] = { + { "brcm,bcm3368", &bcm6358_quirks }, { "brcm,bcm3384-viper", &bcm3384_viper_quirks }, { "brcm,bcm33843-viper", &bcm3384_viper_quirks }, { "brcm,bcm6328", &bcm6328_quirks }, { "brcm,bcm6358", &bcm6358_quirks }, + { "brcm,bcm6362", &bcm6368_quirks }, { "brcm,bcm6368", &bcm6368_quirks }, { "brcm,bcm63168", &bcm6368_quirks }, { "brcm,bcm63268", &bcm6368_quirks }, @@ -150,6 +153,8 @@ void __init plat_time_init(void) mips_hpt_frequency = freq; } +extern const char __appended_dtb; + void __init plat_mem_setup(void) { void *dtb; @@ -159,6 +164,11 @@ void __init plat_mem_setup(void) ioport_resource.start = 0; ioport_resource.end = ~0; +#ifdef CONFIG_MIPS_ELF_APPENDED_DTB + if (!fdt_check_header(&__appended_dtb)) + dtb = (void *)&__appended_dtb; + else +#endif /* intended to somewhat resemble ARM; see Documentation/arm/Booting */ if (fw_arg0 == 0 && fw_arg1 == 0xffffffff) dtb = phys_to_virt(fw_arg2); diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile index acb1988f354e..2728a9a9c7c5 100644 --- a/arch/mips/boot/Makefile +++ b/arch/mips/boot/Makefile @@ -100,3 +100,69 @@ $(obj)/uImage.lzo: $(obj)/vmlinux.bin.lzo FORCE $(obj)/uImage: $(obj)/uImage.$(suffix-y) @ln -sf $(notdir $<) $@ @echo ' Image $@ is ready' + +# +# Flattened Image Tree (.itb) images +# + +targets += vmlinux.itb +targets += vmlinux.gz.itb +targets += vmlinux.bz2.itb +targets += vmlinux.lzma.itb +targets += vmlinux.lzo.itb + +ifeq ($(ADDR_BITS),32) + itb_addr_cells = 1 +endif +ifeq ($(ADDR_BITS),64) + itb_addr_cells = 2 +endif + +quiet_cmd_cpp_its_S = ITS $@ + cmd_cpp_its_S = $(CPP) $(cpp_flags) -P -C -o $@ $< \ + -DKERNEL_NAME="\"Linux $(KERNELRELEASE)\"" \ + -DVMLINUX_BINARY="\"$(3)\"" \ + -DVMLINUX_COMPRESSION="\"$(2)\"" \ + -DVMLINUX_LOAD_ADDRESS=$(VMLINUX_LOAD_ADDRESS) \ + -DVMLINUX_ENTRY_ADDRESS=$(VMLINUX_ENTRY_ADDRESS) \ + -DADDR_BITS=$(ADDR_BITS) \ + -DADDR_CELLS=$(itb_addr_cells) + +$(obj)/vmlinux.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE + $(call if_changed_dep,cpp_its_S,none,vmlinux.bin) + +$(obj)/vmlinux.gz.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE + $(call if_changed_dep,cpp_its_S,gzip,vmlinux.bin.gz) + +$(obj)/vmlinux.bz2.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE + $(call if_changed_dep,cpp_its_S,bzip2,vmlinux.bin.bz2) + +$(obj)/vmlinux.lzma.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE + $(call if_changed_dep,cpp_its_S,lzma,vmlinux.bin.lzma) + +$(obj)/vmlinux.lzo.its: $(srctree)/arch/mips/$(PLATFORM)/vmlinux.its.S FORCE + $(call if_changed_dep,cpp_its_S,lzo,vmlinux.bin.lzo) + +quiet_cmd_itb-image = ITB $@ + cmd_itb-image = \ + env PATH="$(objtree)/scripts/dtc:$(PATH)" \ + $(CONFIG_SHELL) $(MKIMAGE) \ + -D "-I dts -O dtb -p 500 \ + --include $(objtree)/arch/mips \ + --warning no-unit_address_vs_reg" \ + -f $(2) $@ + +$(obj)/vmlinux.itb: $(obj)/vmlinux.its $(obj)/vmlinux.bin FORCE + $(call if_changed,itb-image,$<) + +$(obj)/vmlinux.gz.itb: $(obj)/vmlinux.gz.its $(obj)/vmlinux.bin.gz FORCE + $(call if_changed,itb-image,$<) + +$(obj)/vmlinux.bz2.itb: $(obj)/vmlinux.bz2.its $(obj)/vmlinux.bin.bz2 FORCE + $(call if_changed,itb-image,$<) + +$(obj)/vmlinux.lzma.itb: $(obj)/vmlinux.lzma.its $(obj)/vmlinux.bin.lzma FORCE + $(call if_changed,itb-image,$<) + +$(obj)/vmlinux.lzo.itb: $(obj)/vmlinux.lzo.its $(obj)/vmlinux.bin.lzo FORCE + $(call if_changed,itb-image,$<) diff --git a/arch/mips/boot/dts/brcm/Makefile b/arch/mips/boot/dts/brcm/Makefile index fda9d387cc08..d61bc2aebf69 100644 --- a/arch/mips/boot/dts/brcm/Makefile +++ b/arch/mips/boot/dts/brcm/Makefile @@ -1,6 +1,5 @@ dtb-$(CONFIG_DT_BCM93384WVG) += bcm93384wvg.dtb dtb-$(CONFIG_DT_BCM93384WVG_VIPER) += bcm93384wvg_viper.dtb -dtb-$(CONFIG_DT_BCM96358NB4SER) += bcm96358nb4ser.dtb dtb-$(CONFIG_DT_BCM96368MVWG) += bcm96368mvwg.dtb dtb-$(CONFIG_DT_BCM9EJTAGPRB) += bcm9ejtagprb.dtb dtb-$(CONFIG_DT_BCM97125CBMB) += bcm97125cbmb.dtb @@ -11,20 +10,29 @@ dtb-$(CONFIG_DT_BCM97362SVMB) += bcm97362svmb.dtb dtb-$(CONFIG_DT_BCM97420C) += bcm97420c.dtb dtb-$(CONFIG_DT_BCM97425SVMB) += bcm97425svmb.dtb dtb-$(CONFIG_DT_BCM97435SVMB) += bcm97435svmb.dtb +dtb-$(CONFIG_DT_COMTREND_VR3032U) += bcm63268-comtrend-vr-3032u.dtb +dtb-$(CONFIG_DT_NETGEAR_CVG834G) += bcm3368-netgear-cvg834g.dtb +dtb-$(CONFIG_DT_SFR_NEUFBOX4_SERCOMM) += bcm6358-neufbox4-sercomm.dtb +dtb-$(CONFIG_DT_SFR_NEUFBOX6_SERCOMM) += bcm6362-neufbox6-sercomm.dtb -dtb-$(CONFIG_DT_NONE) += \ - bcm93384wvg.dtb \ - bcm93384wvg_viper.dtb \ - bcm96358nb4ser.dtb \ - bcm96368mvwg.dtb \ - bcm9ejtagprb.dtb \ - bcm97125cbmb.dtb \ - bcm97346dbsmb.dtb \ - bcm97358svmb.dtb \ - bcm97360svmb.dtb \ - bcm97362svmb.dtb \ - bcm97420c.dtb \ - bcm97425svmb.dtb +dtb-$(CONFIG_DT_NONE) += \ + bcm3368-netgear-cvg834g.dtb \ + bcm6358-neufbox4-sercomm.dtb \ + bcm6362-neufbox6-sercomm.dtb \ + bcm63268-comtrend-vr-3032u.dtb \ + bcm93384wvg.dtb \ + bcm93384wvg_viper.dtb \ + bcm96358nb4ser.dtb \ + bcm96368mvwg.dtb \ + bcm9ejtagprb.dtb \ + bcm97125cbmb.dtb \ + bcm97346dbsmb.dtb \ + bcm97358svmb.dtb \ + bcm97360svmb.dtb \ + bcm97362svmb.dtb \ + bcm97420c.dtb \ + bcm97425svmb.dtb \ + bcm97435svmb.dtb obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y)) diff --git a/arch/mips/boot/dts/brcm/bcm3368-netgear-cvg834g.dts b/arch/mips/boot/dts/brcm/bcm3368-netgear-cvg834g.dts new file mode 100644 index 000000000000..2f2e80fdcde8 --- /dev/null +++ b/arch/mips/boot/dts/brcm/bcm3368-netgear-cvg834g.dts @@ -0,0 +1,22 @@ +/dts-v1/; + +/include/ "bcm3368.dtsi" + +/ { + compatible = "netgear,cvg834g", "brcm,bcm3368"; + model = "NETGEAR CVG834G"; + + memory@0 { + device_type = "memory"; + reg = <0x00000000 0x02000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + stdout-path = &uart0; + }; +}; + +&uart0 { + status = "okay"; +}; diff --git a/arch/mips/boot/dts/brcm/bcm3368.dtsi b/arch/mips/boot/dts/brcm/bcm3368.dtsi new file mode 100644 index 000000000000..bee855cb8073 --- /dev/null +++ b/arch/mips/boot/dts/brcm/bcm3368.dtsi @@ -0,0 +1,101 @@ +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "brcm,bcm3368"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + mips-hpt-frequency = <150000000>; + + cpu@0 { + compatible = "brcm,bmips4350"; + device_type = "cpu"; + reg = <0>; + }; + + cpu@1 { + compatible = "brcm,bmips4350"; + device_type = "cpu"; + reg = <1>; + }; + }; + + clocks { + periph_clk: periph-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + }; + }; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + }; + + cpu_intc: interrupt-controller { + #address-cells = <0>; + compatible = "mti,cpu-interrupt-controller"; + + interrupt-controller; + #interrupt-cells = <1>; + }; + + ubus { + #address-cells = <1>; + #size-cells = <1>; + + compatible = "simple-bus"; + ranges; + + periph_cntl: syscon@fff8c000 { + compatible = "syscon"; + reg = <0xfff8c000 0xc>; + native-endian; + }; + + reboot: syscon-reboot@fff8c008 { + compatible = "syscon-reboot"; + regmap = <&periph_cntl>; + offset = <0x8>; + mask = <0x1>; + }; + + periph_intc: interrupt-controller@fff8c00c { + compatible = "brcm,bcm6345-l1-intc"; + reg = <0xfff8c00c 0x8>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&cpu_intc>; + interrupts = <2>; + }; + + uart0: serial@fff8c100 { + compatible = "brcm,bcm6345-uart"; + reg = <0xfff8c100 0x18>; + + interrupt-parent = <&periph_intc>; + interrupts = <2>; + + clocks = <&periph_clk>; + + status = "disabled"; + }; + + uart1: serial@fff8c120 { + compatible = "brcm,bcm6345-uart"; + reg = <0xfff8c120 0x18>; + + interrupt-parent = <&periph_intc>; + interrupts = <3>; + + clocks = <&periph_clk>; + + status = "disabled"; + }; + }; +}; diff --git a/arch/mips/boot/dts/brcm/bcm63268-comtrend-vr-3032u.dts b/arch/mips/boot/dts/brcm/bcm63268-comtrend-vr-3032u.dts new file mode 100644 index 000000000000..430d35ca33d5 --- /dev/null +++ b/arch/mips/boot/dts/brcm/bcm63268-comtrend-vr-3032u.dts @@ -0,0 +1,108 @@ +/dts-v1/; + +/include/ "bcm63268.dtsi" + +/ { + compatible = "comtrend,vr-3032u", "brcm,bcm63268"; + model = "Comtrend VR-3032u"; + + memory@0 { + device_type = "memory"; + reg = <0x00000000 0x04000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + stdout-path = &uart0; + }; +}; + +&leds0 { + status = "ok"; + brcm,serial-leds; + brcm,serial-dat-low; + brcm,serial-shift-inv; + + led@0 { + reg = <0>; + brcm,hardware-controlled; + brcm,link-signal-sources = <0>; + /* GPHY0 Speed 0 */ + }; + led@1 { + reg = <1>; + brcm,hardware-controlled; + brcm,link-signal-sources = <1>; + /* GPHY0 Speed 1 */ + }; + led@2 { + reg = <2>; + active-low; + label = "vr-3032u:red:inet"; + }; + led@3 { + reg = <3>; + active-low; + label = "vr-3032u:green:dsl"; + }; + led@4 { + reg = <4>; + active-low; + label = "vr-3032u:green:usb"; + }; + led@7 { + reg = <7>; + active-low; + label = "vr-3032u:green:wps"; + }; + led@8 { + reg = <8>; + active-low; + label = "vr-3032u:green:inet"; + }; + led@9 { + reg = <9>; + brcm,hardware-controlled; + /* EPHY0 Activity */ + }; + led@10 { + reg = <10>; + brcm,hardware-controlled; + /* EPHY1 Activity */ + }; + led@11 { + reg = <11>; + brcm,hardware-controlled; + /* EPHY2 Activity */ + }; + led@12 { + reg = <12>; + brcm,hardware-controlled; + /* GPHY0 Activity */ + }; + led@13 { + reg = <13>; + brcm,hardware-controlled; + /* EPHY0 Speed */ + }; + led@14 { + reg = <14>; + brcm,hardware-controlled; + /* EPHY1 Speed */ + }; + led@15 { + reg = <15>; + brcm,hardware-controlled; + /* EPHY2 Speed */ + }; + led@20 { + reg = <20>; + active-low; + label = "vr-3032u:green:power"; + default-state = "on"; + }; +}; + +&uart0 { + status = "okay"; +}; diff --git a/arch/mips/boot/dts/brcm/bcm63268.dtsi b/arch/mips/boot/dts/brcm/bcm63268.dtsi new file mode 100644 index 000000000000..7e6bf2cc0287 --- /dev/null +++ b/arch/mips/boot/dts/brcm/bcm63268.dtsi @@ -0,0 +1,134 @@ +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "brcm,bcm63268"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + mips-hpt-frequency = <200000000>; + + cpu@0 { + compatible = "brcm,bmips4350"; + device_type = "cpu"; + reg = <0>; + }; + + cpu@1 { + compatible = "brcm,bmips4350"; + device_type = "cpu"; + reg = <1>; + }; + }; + + clocks { + periph_clk: periph-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + }; + }; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + }; + + cpu_intc: interrupt-controller { + #address-cells = <0>; + compatible = "mti,cpu-interrupt-controller"; + + interrupt-controller; + #interrupt-cells = <1>; + }; + + ubus { + #address-cells = <1>; + #size-cells = <1>; + + compatible = "simple-bus"; + ranges; + + periph_cntl: syscon@10000000 { + compatible = "syscon"; + reg = <0x10000000 0x14>; + native-endian; + }; + + reboot: syscon-reboot@10000008 { + compatible = "syscon-reboot"; + regmap = <&periph_cntl>; + offset = <0x8>; + mask = <0x1>; + }; + + periph_intc: interrupt-controller@10000020 { + compatible = "brcm,bcm6345-l1-intc"; + reg = <0x10000020 0x20>, + <0x10000040 0x20>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&cpu_intc>; + interrupts = <2>, <3>; + }; + + uart0: serial@10000180 { + compatible = "brcm,bcm6345-uart"; + reg = <0x10000180 0x18>; + + interrupt-parent = <&periph_intc>; + interrupts = <5>; + + clocks = <&periph_clk>; + + status = "disabled"; + }; + + uart1: serial@100001a0 { + compatible = "brcm,bcm6345-uart"; + reg = <0x100001a0 0x18>; + + interrupt-parent = <&periph_intc>; + interrupts = <34>; + + clocks = <&periph_clk>; + + status = "disabled"; + }; + + leds0: led-controller@10001900 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "brcm,bcm6328-leds"; + reg = <0x10001900 0x24>; + + status = "disabled"; + }; + + ehci: usb@10002500 { + compatible = "brcm,bcm63268-ehci", "generic-ehci"; + reg = <0x10002500 0x100>; + big-endian; + + interrupt-parent = <&periph_intc>; + interrupts = <10>; + + status = "disabled"; + }; + + ohci: usb@10002600 { + compatible = "brcm,bcm63268-ohci", "generic-ohci"; + reg = <0x10002600 0x100>; + big-endian; + no-big-frame-no; + + interrupt-parent = <&periph_intc>; + interrupts = <9>; + + status = "disabled"; + }; + }; +}; diff --git a/arch/mips/boot/dts/brcm/bcm96358nb4ser.dts b/arch/mips/boot/dts/brcm/bcm6358-neufbox4-sercomm.dts index f412117972e6..702eae2a22a0 100644 --- a/arch/mips/boot/dts/brcm/bcm96358nb4ser.dts +++ b/arch/mips/boot/dts/brcm/bcm6358-neufbox4-sercomm.dts @@ -12,6 +12,7 @@ }; chosen { + bootargs = "console=ttyS0,115200"; stdout-path = &uart0; }; }; diff --git a/arch/mips/boot/dts/brcm/bcm6362-neufbox6-sercomm.dts b/arch/mips/boot/dts/brcm/bcm6362-neufbox6-sercomm.dts new file mode 100644 index 000000000000..480f2a5bf1da --- /dev/null +++ b/arch/mips/boot/dts/brcm/bcm6362-neufbox6-sercomm.dts @@ -0,0 +1,22 @@ +/dts-v1/; + +/include/ "bcm6362.dtsi" + +/ { + compatible = "sfr,nb6-ser", "brcm,bcm6362"; + model = "SFR NeufBox 6 (Sercomm)"; + + memory@0 { + device_type = "memory"; + reg = <0x00000000 0x08000000>; + }; + + chosen { + bootargs = "console=ttyS0,115200"; + stdout-path = &uart0; + }; +}; + +&uart0 { + status = "okay"; +}; diff --git a/arch/mips/boot/dts/brcm/bcm6362.dtsi b/arch/mips/boot/dts/brcm/bcm6362.dtsi new file mode 100644 index 000000000000..c507da594f2f --- /dev/null +++ b/arch/mips/boot/dts/brcm/bcm6362.dtsi @@ -0,0 +1,134 @@ +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "brcm,bcm6362"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + mips-hpt-frequency = <200000000>; + + cpu@0 { + compatible = "brcm,bmips4350"; + device_type = "cpu"; + reg = <0>; + }; + + cpu@1 { + compatible = "brcm,bmips4350"; + device_type = "cpu"; + reg = <1>; + }; + }; + + clocks { + periph_clk: periph-clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <50000000>; + }; + }; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + }; + + cpu_intc: interrupt-controller { + #address-cells = <0>; + compatible = "mti,cpu-interrupt-controller"; + + interrupt-controller; + #interrupt-cells = <1>; + }; + + ubus { + #address-cells = <1>; + #size-cells = <1>; + + compatible = "simple-bus"; + ranges; + + periph_cntl: syscon@10000000 { + compatible = "syscon"; + reg = <0x10000000 0x14>; + native-endian; + }; + + reboot: syscon-reboot@10000008 { + compatible = "syscon-reboot"; + regmap = <&periph_cntl>; + offset = <0x8>; + mask = <0x1>; + }; + + periph_intc: interrupt-controller@10000020 { + compatible = "brcm,bcm6345-l1-intc"; + reg = <0x10000020 0x10>, + <0x10000030 0x10>; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&cpu_intc>; + interrupts = <2>, <3>; + }; + + uart0: serial@10000100 { + compatible = "brcm,bcm6345-uart"; + reg = <0x10000100 0x18>; + + interrupt-parent = <&periph_intc>; + interrupts = <3>; + + clocks = <&periph_clk>; + + status = "disabled"; + }; + + uart1: serial@10000120 { + compatible = "brcm,bcm6345-uart"; + reg = <0x10000120 0x18>; + + interrupt-parent = <&periph_intc>; + interrupts = <4>; + + clocks = <&periph_clk>; + + status = "disabled"; + }; + + leds0: led-controller@10001900 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "brcm,bcm6328-leds"; + reg = <0x10001900 0x24>; + + status = "disabled"; + }; + + ehci: usb@10002500 { + compatible = "brcm,bcm6362-ehci", "generic-ehci"; + reg = <0x10002500 0x100>; + big-endian; + + interrupt-parent = <&periph_intc>; + interrupts = <10>; + + status = "disabled"; + }; + + ohci: usb@10002600 { + compatible = "brcm,bcm6362-ohci", "generic-ohci"; + reg = <0x10002600 0x100>; + big-endian; + no-big-frame-no; + + interrupt-parent = <&periph_intc>; + interrupts = <9>; + + status = "disabled"; + }; + }; +}; diff --git a/arch/mips/boot/dts/brcm/bcm7125.dtsi b/arch/mips/boot/dts/brcm/bcm7125.dtsi index 550e1d9e3ee0..bbd00f65ce39 100644 --- a/arch/mips/boot/dts/brcm/bcm7125.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7125.dtsi @@ -26,7 +26,7 @@ uart0 = &uart0; }; - cpu_intc: cpu_intc { + cpu_intc: interrupt-controller { #address-cells = <0>; compatible = "mti,cpu-interrupt-controller"; @@ -40,6 +40,12 @@ #clock-cells = <0>; clock-frequency = <81000000>; }; + + upg_clk: upg_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; }; rdb { @@ -49,7 +55,7 @@ compatible = "simple-bus"; ranges = <0 0x10000000 0x01000000>; - periph_intc: periph_intc@441400 { + periph_intc: interrupt-controller@441400 { compatible = "brcm,bcm7038-l1-intc"; reg = <0x441400 0x30>, <0x441600 0x30>; @@ -60,7 +66,7 @@ interrupts = <2>, <3>; }; - sun_l2_intc: sun_l2_intc@401800 { + sun_l2_intc: interrupt-controller@401800 { compatible = "brcm,l2-intc"; reg = <0x401800 0x30>; interrupt-controller; @@ -81,7 +87,7 @@ "avd_0", "jtag_0"; }; - upg_irq0_intc: upg_irq0_intc@406780 { + upg_irq0_intc: interrupt-controller@406780 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x406780 0x8>; @@ -183,6 +189,26 @@ status = "disabled"; }; + pwma: pwm@406580 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406580 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + + upg_gio: gpio@406700 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x406700 0x80>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_irq0_intc>; + interrupts = <6>; + brcm,gpio-bank-widths = <32 32 32 18>; + }; + ehci0: usb@488300 { compatible = "brcm,bcm7125-ehci", "generic-ehci"; reg = <0x488300 0x100>; diff --git a/arch/mips/boot/dts/brcm/bcm7346.dtsi b/arch/mips/boot/dts/brcm/bcm7346.dtsi index ec959061d52e..4bbcc95f1c15 100644 --- a/arch/mips/boot/dts/brcm/bcm7346.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7346.dtsi @@ -26,7 +26,7 @@ uart0 = &uart0; }; - cpu_intc: cpu_intc { + cpu_intc: interrupt-controller { #address-cells = <0>; compatible = "mti,cpu-interrupt-controller"; @@ -40,6 +40,12 @@ #clock-cells = <0>; clock-frequency = <81000000>; }; + + upg_clk: upg_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; }; rdb { @@ -49,7 +55,7 @@ compatible = "simple-bus"; ranges = <0 0x10000000 0x01000000>; - periph_intc: periph_intc@411400 { + periph_intc: interrupt-controller@411400 { compatible = "brcm,bcm7038-l1-intc"; reg = <0x411400 0x30>, <0x411600 0x30>; @@ -60,7 +66,7 @@ interrupts = <2>, <3>; }; - sun_l2_intc: sun_l2_intc@403000 { + sun_l2_intc: interrupt-controller@403000 { compatible = "brcm,l2-intc"; reg = <0x403000 0x30>; interrupt-controller; @@ -81,7 +87,7 @@ "jtag_0", "svd_0"; }; - upg_irq0_intc: upg_irq0_intc@406780 { + upg_irq0_intc: interrupt-controller@406780 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x406780 0x8>; @@ -96,7 +102,7 @@ interrupt-names = "upg_main", "upg_bsc"; }; - upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 { + upg_aon_irq0_intc: interrupt-controller@408b80 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x408b80 0x8>; @@ -210,6 +216,59 @@ status = "disabled"; }; + pwma: pwm@406580 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406580 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + + pwmb: pwm@406800 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406800 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + + aon_pm_l2_intc: interrupt-controller@408440 { + compatible = "brcm,l2-intc"; + reg = <0x408440 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <53>; + brcm,irq-can-wake; + }; + + upg_gio: gpio@406700 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x406700 0x60>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_irq0_intc>; + interrupts = <6>; + brcm,gpio-bank-widths = <32 32 16>; + }; + + upg_gio_aon: gpio@408c00 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x408c00 0x60>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_aon_irq0_intc>; + interrupts = <6>; + interrupts-extended = <&upg_aon_irq0_intc 6>, + <&aon_pm_l2_intc 5>; + wakeup-source; + brcm,gpio-bank-widths = <27 32 2>; + }; + enet0: ethernet@430000 { phy-mode = "internal"; phy-handle = <&phy1>; @@ -313,6 +372,26 @@ status = "disabled"; }; + hif_l2_intc: interrupt-controller@411000 { + compatible = "brcm,l2-intc"; + reg = <0x411000 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <30>; + }; + + nand: nand@412800 { + compatible = "brcm,brcmnand-v5.0", "brcm,brcmnand"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "nand"; + reg = <0x412800 0x400>; + interrupt-parent = <&hif_l2_intc>; + interrupts = <24>; + status = "disabled"; + }; + sata: sata@181000 { compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci"; reg-names = "ahci", "top-ctrl"; @@ -352,5 +431,13 @@ #phy-cells = <0>; }; }; + + sdhci0: sdhci@413500 { + compatible = "brcm,bcm7425-sdhci"; + reg = <0x413500 0x100>; + interrupt-parent = <&periph_intc>; + interrupts = <85>; + status = "disabled"; + }; }; }; diff --git a/arch/mips/boot/dts/brcm/bcm7358.dtsi b/arch/mips/boot/dts/brcm/bcm7358.dtsi index ca57fb5eb122..3e42535c8d29 100644 --- a/arch/mips/boot/dts/brcm/bcm7358.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7358.dtsi @@ -20,7 +20,7 @@ uart0 = &uart0; }; - cpu_intc: cpu_intc { + cpu_intc: interrupt-controller { #address-cells = <0>; compatible = "mti,cpu-interrupt-controller"; @@ -34,6 +34,12 @@ #clock-cells = <0>; clock-frequency = <81000000>; }; + + upg_clk: upg_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; }; rdb { @@ -43,7 +49,7 @@ compatible = "simple-bus"; ranges = <0 0x10000000 0x01000000>; - periph_intc: periph_intc@411400 { + periph_intc: interrupt-controller@411400 { compatible = "brcm,bcm7038-l1-intc"; reg = <0x411400 0x30>; @@ -54,7 +60,7 @@ interrupts = <2>; }; - sun_l2_intc: sun_l2_intc@403000 { + sun_l2_intc: interrupt-controller@403000 { compatible = "brcm,l2-intc"; reg = <0x403000 0x30>; interrupt-controller; @@ -75,7 +81,7 @@ "avd_0", "jtag_0"; }; - upg_irq0_intc: upg_irq0_intc@406600 { + upg_irq0_intc: interrupt-controller@406600 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x406600 0x8>; @@ -90,7 +96,7 @@ interrupt-names = "upg_main", "upg_bsc"; }; - upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 { + upg_aon_irq0_intc: interrupt-controller@408b80 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x408b80 0x8>; @@ -194,6 +200,59 @@ status = "disabled"; }; + pwma: pwm@406400 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406400 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + + pwmb: pwm@406700 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406700 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + + aon_pm_l2_intc: interrupt-controller@408240 { + compatible = "brcm,l2-intc"; + reg = <0x408240 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <50>; + brcm,irq-can-wake; + }; + + upg_gio: gpio@406500 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x406500 0xa0>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_irq0_intc>; + interrupts = <6>; + brcm,gpio-bank-widths = <32 32 32 29 4>; + }; + + upg_gio_aon: gpio@408c00 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x408c00 0x60>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_aon_irq0_intc>; + interrupts = <6>; + interrupts-extended = <&upg_aon_irq0_intc 6>, + <&aon_pm_l2_intc 5>; + wakeup-source; + brcm,gpio-bank-widths = <21 32 2>; + }; + enet0: ethernet@430000 { phy-mode = "internal"; phy-handle = <&phy1>; @@ -239,5 +298,25 @@ interrupts = <66>; status = "disabled"; }; + + hif_l2_intc: interrupt-controller@411000 { + compatible = "brcm,l2-intc"; + reg = <0x411000 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <30>; + }; + + nand: nand@412800 { + compatible = "brcm,brcmnand-v5.0", "brcm,brcmnand"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "nand"; + reg = <0x412800 0x400>; + interrupt-parent = <&hif_l2_intc>; + interrupts = <24>; + status = "disabled"; + }; }; }; diff --git a/arch/mips/boot/dts/brcm/bcm7360.dtsi b/arch/mips/boot/dts/brcm/bcm7360.dtsi index 1c0c3d438c7a..112a5571c596 100644 --- a/arch/mips/boot/dts/brcm/bcm7360.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7360.dtsi @@ -20,7 +20,7 @@ uart0 = &uart0; }; - cpu_intc: cpu_intc { + cpu_intc: interrupt-controller { #address-cells = <0>; compatible = "mti,cpu-interrupt-controller"; @@ -34,6 +34,12 @@ #clock-cells = <0>; clock-frequency = <81000000>; }; + + upg_clk: upg_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; }; rdb { @@ -43,7 +49,7 @@ compatible = "simple-bus"; ranges = <0 0x10000000 0x01000000>; - periph_intc: periph_intc@411400 { + periph_intc: interrupt-controller@411400 { compatible = "brcm,bcm7038-l1-intc"; reg = <0x411400 0x30>; @@ -54,7 +60,7 @@ interrupts = <2>; }; - sun_l2_intc: sun_l2_intc@403000 { + sun_l2_intc: interrupt-controller@403000 { compatible = "brcm,l2-intc"; reg = <0x403000 0x30>; interrupt-controller; @@ -75,7 +81,7 @@ "avd_0", "jtag_0"; }; - upg_irq0_intc: upg_irq0_intc@406600 { + upg_irq0_intc: interrupt-controller@406600 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x406600 0x8>; @@ -90,7 +96,7 @@ interrupt-names = "upg_main", "upg_bsc"; }; - upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 { + upg_aon_irq0_intc: interrupt-controller@408b80 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x408b80 0x8>; @@ -194,6 +200,51 @@ status = "disabled"; }; + pwma: pwm@406400 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406400 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + + aon_pm_l2_intc: interrupt-controller@408440 { + compatible = "brcm,l2-intc"; + reg = <0x408440 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <50>; + brcm,irq-can-wake; + }; + + upg_gio: gpio@406500 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x406500 0xa0>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_irq0_intc>; + interrupts = <6>; + brcm,gpio-bank-widths = <32 32 32 29 4>; + }; + + upg_gio_aon: gpio@408c00 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x408c00 0x60>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_aon_irq0_intc>; + interrupts = <6>; + interrupts-extended = <&upg_aon_irq0_intc 6>, + <&aon_pm_l2_intc 5>; + wakeup-source; + brcm,gpio-bank-widths = <21 32 2>; + }; + enet0: ethernet@430000 { phy-mode = "internal"; phy-handle = <&phy1>; @@ -240,6 +291,26 @@ status = "disabled"; }; + hif_l2_intc: interrupt-controller@411000 { + compatible = "brcm,l2-intc"; + reg = <0x411000 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <30>; + }; + + nand: nand@412800 { + compatible = "brcm,brcmnand-v5.0", "brcm,brcmnand"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "nand"; + reg = <0x412800 0x400>; + interrupt-parent = <&hif_l2_intc>; + interrupts = <24>; + status = "disabled"; + }; + sata: sata@181000 { compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci"; reg-names = "ahci", "top-ctrl"; @@ -279,5 +350,13 @@ #phy-cells = <0>; }; }; + + sdhci0: sdhci@410000 { + compatible = "brcm,bcm7425-sdhci"; + reg = <0x410000 0x100>; + interrupt-parent = <&periph_intc>; + interrupts = <82>; + status = "disabled"; + }; }; }; diff --git a/arch/mips/boot/dts/brcm/bcm7362.dtsi b/arch/mips/boot/dts/brcm/bcm7362.dtsi index 6b4713add4b8..34abfb0b07e7 100644 --- a/arch/mips/boot/dts/brcm/bcm7362.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7362.dtsi @@ -26,7 +26,7 @@ uart0 = &uart0; }; - cpu_intc: cpu_intc { + cpu_intc: interrupt-controller { #address-cells = <0>; compatible = "mti,cpu-interrupt-controller"; @@ -40,6 +40,12 @@ #clock-cells = <0>; clock-frequency = <81000000>; }; + + upg_clk: upg_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; }; rdb { @@ -49,7 +55,7 @@ compatible = "simple-bus"; ranges = <0 0x10000000 0x01000000>; - periph_intc: periph_intc@411400 { + periph_intc: interrupt-controller@411400 { compatible = "brcm,bcm7038-l1-intc"; reg = <0x411400 0x30>, <0x411600 0x30>; @@ -60,7 +66,7 @@ interrupts = <2>, <3>; }; - sun_l2_intc: sun_l2_intc@403000 { + sun_l2_intc: interrupt-controller@403000 { compatible = "brcm,l2-intc"; reg = <0x403000 0x30>; interrupt-controller; @@ -81,7 +87,7 @@ "avd_0", "jtag_0"; }; - upg_irq0_intc: upg_irq0_intc@406600 { + upg_irq0_intc: interrupt-controller@406600 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x406600 0x8>; @@ -96,7 +102,7 @@ interrupt-names = "upg_main", "upg_bsc"; }; - upg_aon_irq0_intc: upg_aon_irq0_intc@408b80 { + upg_aon_irq0_intc: interrupt-controller@408b80 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x408b80 0x8>; @@ -190,6 +196,51 @@ status = "disabled"; }; + pwma: pwm@406400 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406400 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + + aon_pm_l2_intc: interrupt-controller@408440 { + compatible = "brcm,l2-intc"; + reg = <0x408440 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <50>; + brcm,irq-can-wake; + }; + + upg_gio: gpio@406500 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x406500 0xa0>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_irq0_intc>; + interrupts = <6>; + brcm,gpio-bank-widths = <32 32 32 29 4>; + }; + + upg_gio_aon: gpio@408c00 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x408c00 0x60>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_aon_irq0_intc>; + interrupts = <6>; + interrupts-extended = <&upg_aon_irq0_intc 6>, + <&aon_pm_l2_intc 5>; + wakeup-source; + brcm,gpio-bank-widths = <21 32 2>; + }; + enet0: ethernet@430000 { phy-mode = "internal"; phy-handle = <&phy1>; @@ -236,6 +287,26 @@ status = "disabled"; }; + hif_l2_intc: interrupt-controller@411000 { + compatible = "brcm,l2-intc"; + reg = <0x411000 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <30>; + }; + + nand: nand@412800 { + compatible = "brcm,brcmnand-v5.0", "brcm,brcmnand"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "nand"; + reg = <0x412800 0x400>; + interrupt-parent = <&hif_l2_intc>; + interrupts = <24>; + status = "disabled"; + }; + sata: sata@181000 { compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci"; reg-names = "ahci", "top-ctrl"; @@ -275,5 +346,13 @@ #phy-cells = <0>; }; }; + + sdhci0: sdhci@410000 { + compatible = "brcm,bcm7425-sdhci"; + reg = <0x410000 0x100>; + interrupt-parent = <&periph_intc>; + interrupts = <82>; + status = "disabled"; + }; }; }; diff --git a/arch/mips/boot/dts/brcm/bcm7420.dtsi b/arch/mips/boot/dts/brcm/bcm7420.dtsi index 0586bf662571..b143723c674e 100644 --- a/arch/mips/boot/dts/brcm/bcm7420.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7420.dtsi @@ -26,7 +26,7 @@ uart0 = &uart0; }; - cpu_intc: cpu_intc { + cpu_intc: interrupt-controller { #address-cells = <0>; compatible = "mti,cpu-interrupt-controller"; @@ -40,6 +40,12 @@ #clock-cells = <0>; clock-frequency = <81000000>; }; + + upg_clk: upg_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; }; rdb { @@ -49,7 +55,7 @@ compatible = "simple-bus"; ranges = <0 0x10000000 0x01000000>; - periph_intc: periph_intc@441400 { + periph_intc: interrupt-controller@441400 { compatible = "brcm,bcm7038-l1-intc"; reg = <0x441400 0x30>, <0x441600 0x30>; @@ -60,7 +66,7 @@ interrupts = <2>, <3>; }; - sun_l2_intc: sun_l2_intc@401800 { + sun_l2_intc: interrupt-controller@401800 { compatible = "brcm,l2-intc"; reg = <0x401800 0x30>; interrupt-controller; @@ -82,7 +88,7 @@ "jtag_0"; }; - upg_irq0_intc: upg_irq0_intc@406780 { + upg_irq0_intc: interrupt-controller@406780 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x406780 0x8>; @@ -191,6 +197,34 @@ status = "disabled"; }; + pwma: pwm@406580 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406580 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + + pwmb: pwm@406880 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406880 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + + upg_gio: gpio@406700 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x406700 0x80>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_irq0_intc>; + interrupts = <6>; + brcm,gpio-bank-widths = <32 32 32 27>; + }; + enet0: ethernet@468000 { phy-mode = "internal"; phy-handle = <&phy1>; diff --git a/arch/mips/boot/dts/brcm/bcm7425.dtsi b/arch/mips/boot/dts/brcm/bcm7425.dtsi index c1c15edaf829..2488d2f61f60 100644 --- a/arch/mips/boot/dts/brcm/bcm7425.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7425.dtsi @@ -26,7 +26,7 @@ uart0 = &uart0; }; - cpu_intc: cpu_intc { + cpu_intc: interrupt-controller { #address-cells = <0>; compatible = "mti,cpu-interrupt-controller"; @@ -40,6 +40,12 @@ #clock-cells = <0>; clock-frequency = <81000000>; }; + + upg_clk: upg_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; }; rdb { @@ -49,7 +55,7 @@ compatible = "simple-bus"; ranges = <0 0x10000000 0x01000000>; - periph_intc: periph_intc@41a400 { + periph_intc: interrupt-controller@41a400 { compatible = "brcm,bcm7038-l1-intc"; reg = <0x41a400 0x30>, <0x41a600 0x30>; @@ -60,7 +66,7 @@ interrupts = <2>, <3>; }; - sun_l2_intc: sun_l2_intc@403000 { + sun_l2_intc: interrupt-controller@403000 { compatible = "brcm,l2-intc"; reg = <0x403000 0x30>; interrupt-controller; @@ -83,7 +89,7 @@ "vice_0"; }; - upg_irq0_intc: upg_irq0_intc@406780 { + upg_irq0_intc: interrupt-controller@406780 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x406780 0x8>; @@ -98,7 +104,7 @@ interrupt-names = "upg_main", "upg_bsc"; }; - upg_aon_irq0_intc: upg_aon_irq0_intc@409480 { + upg_aon_irq0_intc: interrupt-controller@409480 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x409480 0x8>; @@ -209,6 +215,59 @@ status = "disabled"; }; + pwma: pwm@406580 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406580 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + + pwmb: pwm@406800 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406800 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + + aon_pm_l2_intc: interrupt-controller@408440 { + compatible = "brcm,l2-intc"; + reg = <0x408440 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <49>; + brcm,irq-can-wake; + }; + + upg_gio: gpio@406700 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x406700 0x80>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_irq0_intc>; + interrupts = <6>; + brcm,gpio-bank-widths = <32 32 32 21>; + }; + + upg_gio_aon: gpio@4094c0 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x4094c0 0x40>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_aon_irq0_intc>; + interrupts = <6>; + interrupts-extended = <&upg_aon_irq0_intc 6>, + <&aon_pm_l2_intc 5>; + wakeup-source; + brcm,gpio-bank-widths = <18 4>; + }; + enet0: ethernet@b80000 { phy-mode = "internal"; phy-handle = <&phy1>; @@ -312,6 +371,26 @@ status = "disabled"; }; + hif_l2_intc: interrupt-controller@41a000 { + compatible = "brcm,l2-intc"; + reg = <0x41a000 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <24>; + }; + + nand: nand@41b800 { + compatible = "brcm,brcmnand-v5.0", "brcm,brcmnand"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "nand"; + reg = <0x41b800 0x400>; + interrupt-parent = <&hif_l2_intc>; + interrupts = <24>; + status = "disabled"; + }; + sata: sata@181000 { compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci"; reg-names = "ahci", "top-ctrl"; @@ -351,5 +430,25 @@ #phy-cells = <0>; }; }; + + sdhci0: sdhci@419000 { + compatible = "brcm,bcm7425-sdhci"; + reg = <0x419000 0x100>; + interrupt-parent = <&periph_intc>; + interrupts = <43>; + sd-uhs-sdr50; + mmc-hs200-1_8v; + status = "disabled"; + }; + + sdhci1: sdhci@419200 { + compatible = "brcm,bcm7425-sdhci"; + reg = <0x419200 0x100>; + interrupt-parent = <&periph_intc>; + interrupts = <44>; + sd-uhs-sdr50; + mmc-hs200-1_8v; + status = "disabled"; + }; }; }; diff --git a/arch/mips/boot/dts/brcm/bcm7435.dtsi b/arch/mips/boot/dts/brcm/bcm7435.dtsi index a874d3a0e2ee..19fa259b968b 100644 --- a/arch/mips/boot/dts/brcm/bcm7435.dtsi +++ b/arch/mips/boot/dts/brcm/bcm7435.dtsi @@ -38,7 +38,7 @@ uart0 = &uart0; }; - cpu_intc: cpu_intc { + cpu_intc: interrupt-controller { #address-cells = <0>; compatible = "mti,cpu-interrupt-controller"; @@ -52,6 +52,12 @@ #clock-cells = <0>; clock-frequency = <81000000>; }; + + upg_clk: upg_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + }; }; rdb { @@ -61,7 +67,7 @@ compatible = "simple-bus"; ranges = <0 0x10000000 0x01000000>; - periph_intc: periph_intc@41b500 { + periph_intc: interrupt-controller@41b500 { compatible = "brcm,bcm7038-l1-intc"; reg = <0x41b500 0x40>, <0x41b600 0x40>, <0x41b700 0x40>, <0x41b800 0x40>; @@ -73,7 +79,7 @@ interrupts = <2>, <3>, <2>, <3>; }; - sun_l2_intc: sun_l2_intc@403000 { + sun_l2_intc: interrupt-controller@403000 { compatible = "brcm,l2-intc"; reg = <0x403000 0x30>; interrupt-controller; @@ -98,7 +104,7 @@ "scpu"; }; - upg_irq0_intc: upg_irq0_intc@406780 { + upg_irq0_intc: interrupt-controller@406780 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x406780 0x8>; @@ -113,7 +119,7 @@ interrupt-names = "upg_main", "upg_bsc"; }; - upg_aon_irq0_intc: upg_aon_irq0_intc@409480 { + upg_aon_irq0_intc: interrupt-controller@409480 { compatible = "brcm,bcm7120-l2-intc"; reg = <0x409480 0x8>; @@ -224,6 +230,59 @@ status = "disabled"; }; + pwma: pwm@406580 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406580 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + + pwmb: pwm@406800 { + compatible = "brcm,bcm7038-pwm"; + reg = <0x406800 0x28>; + #pwm-cells = <2>; + clocks = <&upg_clk>; + status = "disabled"; + }; + + aon_pm_l2_intc: interrupt-controller@408440 { + compatible = "brcm,l2-intc"; + reg = <0x408440 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <54>; + brcm,irq-can-wake; + }; + + upg_gio: gpio@406700 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x406700 0x80>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_irq0_intc>; + interrupts = <6>; + brcm,gpio-bank-widths = <32 32 32 21>; + }; + + upg_gio_aon: gpio@4094c0 { + compatible = "brcm,brcmstb-gpio"; + reg = <0x4094c0 0x40>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + interrupt-controller; + interrupt-parent = <&upg_aon_irq0_intc>; + interrupts = <6>; + interrupts-extended = <&upg_aon_irq0_intc 6>, + <&aon_pm_l2_intc 5>; + wakeup-source; + brcm,gpio-bank-widths = <18 4>; + }; + enet0: ethernet@b80000 { phy-mode = "internal"; phy-handle = <&phy1>; @@ -327,6 +386,26 @@ status = "disabled"; }; + hif_l2_intc: interrupt-controller@41b000 { + compatible = "brcm,l2-intc"; + reg = <0x41b000 0x30>; + interrupt-controller; + #interrupt-cells = <1>; + interrupt-parent = <&periph_intc>; + interrupts = <24>; + }; + + nand: nand@41c800 { + compatible = "brcm,brcmnand-v6.2", "brcm,brcmnand"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "nand", "flash-dma"; + reg = <0x41c800 0x600>, <0x41d000 0x100>; + interrupt-parent = <&hif_l2_intc>; + interrupts = <24>, <4>; + status = "disabled"; + }; + sata: sata@181000 { compatible = "brcm,bcm7425-ahci", "brcm,sata3-ahci"; reg-names = "ahci", "top-ctrl"; @@ -366,5 +445,25 @@ #phy-cells = <0>; }; }; + + sdhci0: sdhci@41a000 { + compatible = "brcm,bcm7425-sdhci"; + reg = <0x41a000 0x100>; + interrupt-parent = <&periph_intc>; + interrupts = <47>; + sd-uhs-sdr50; + mmc-hs200-1_8v; + status = "disabled"; + }; + + sdhci1: sdhci@41a200 { + compatible = "brcm,bcm7425-sdhci"; + reg = <0x41a200 0x100>; + interrupt-parent = <&periph_intc>; + interrupts = <48>; + sd-uhs-sdr50; + mmc-hs200-1_8v; + status = "disabled"; + }; }; }; diff --git a/arch/mips/boot/dts/brcm/bcm97125cbmb.dts b/arch/mips/boot/dts/brcm/bcm97125cbmb.dts index f2449d147c6d..5c24eacd72dd 100644 --- a/arch/mips/boot/dts/brcm/bcm97125cbmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97125cbmb.dts @@ -45,6 +45,10 @@ status = "okay"; }; +&pwma { + status = "okay"; +}; + /* FIXME: USB is wonky; disable it for now */ &ehci0 { status = "disabled"; diff --git a/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts b/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts index d3d28816a027..e67eaf30de3d 100644 --- a/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97346dbsmb.dts @@ -1,6 +1,7 @@ /dts-v1/; /include/ "bcm7346.dtsi" +/include/ "bcm97xxx-nand-cs1-bch24.dtsi" / { compatible = "brcm,bcm97346dbsmb", "brcm,bcm7346"; @@ -49,6 +50,14 @@ status = "okay"; }; +&pwma { + status = "okay"; +}; + +&pwmb { + status = "okay"; +}; + &enet0 { status = "okay"; }; @@ -85,6 +94,10 @@ status = "okay"; }; +&nand { + status = "okay"; +}; + &sata { status = "okay"; }; @@ -92,3 +105,7 @@ &sata_phy { status = "okay"; }; + +&sdhci0 { + status = "okay"; +}; diff --git a/arch/mips/boot/dts/brcm/bcm97358svmb.dts b/arch/mips/boot/dts/brcm/bcm97358svmb.dts index 02ce6b429dc4..ee4607fae47a 100644 --- a/arch/mips/boot/dts/brcm/bcm97358svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97358svmb.dts @@ -1,6 +1,7 @@ /dts-v1/; /include/ "bcm7358.dtsi" +/include/ "bcm97xxx-nand-cs1-bch4.dtsi" / { compatible = "brcm,bcm97358svmb", "brcm,bcm7358"; @@ -45,6 +46,14 @@ status = "okay"; }; +&pwma { + status = "okay"; +}; + +&pwmb { + status = "okay"; +}; + &enet0 { status = "okay"; }; @@ -56,3 +65,7 @@ &ohci0 { status = "okay"; }; + +&nand { + status = "okay"; +}; diff --git a/arch/mips/boot/dts/brcm/bcm97360svmb.dts b/arch/mips/boot/dts/brcm/bcm97360svmb.dts index 73124be9548a..bed821b03013 100644 --- a/arch/mips/boot/dts/brcm/bcm97360svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97360svmb.dts @@ -45,6 +45,10 @@ status = "okay"; }; +&pwma { + status = "okay"; +}; + &enet0 { status = "okay"; }; @@ -64,3 +68,7 @@ &sata_phy { status = "okay"; }; + +&sdhci0 { + status = "okay"; +}; diff --git a/arch/mips/boot/dts/brcm/bcm97362svmb.dts b/arch/mips/boot/dts/brcm/bcm97362svmb.dts index 3cfcaebe7f79..68fd823868e0 100644 --- a/arch/mips/boot/dts/brcm/bcm97362svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97362svmb.dts @@ -1,6 +1,7 @@ /dts-v1/; /include/ "bcm7362.dtsi" +/include/ "bcm97xxx-nand-cs1-bch4.dtsi" / { compatible = "brcm,bcm97362svmb", "brcm,bcm7362"; @@ -41,6 +42,10 @@ status = "okay"; }; +&pwma { + status = "okay"; +}; + &enet0 { status = "okay"; }; @@ -53,6 +58,10 @@ status = "okay"; }; +&nand { + status = "okay"; +}; + &sata { status = "okay"; }; @@ -60,3 +69,7 @@ &sata_phy { status = "okay"; }; + +&sdhci0 { + status = "okay"; +}; diff --git a/arch/mips/boot/dts/brcm/bcm97420c.dts b/arch/mips/boot/dts/brcm/bcm97420c.dts index 600d57abee05..e66271af055e 100644 --- a/arch/mips/boot/dts/brcm/bcm97420c.dts +++ b/arch/mips/boot/dts/brcm/bcm97420c.dts @@ -51,6 +51,14 @@ status = "okay"; }; +&pwma { + status = "okay"; +}; + +&pwmb { + status = "okay"; +}; + /* FIXME: MAC driver comes up but cannot attach to PHY */ &enet0 { status = "disabled"; diff --git a/arch/mips/boot/dts/brcm/bcm97425svmb.dts b/arch/mips/boot/dts/brcm/bcm97425svmb.dts index 119c714805cb..f95ba1bf3e58 100644 --- a/arch/mips/boot/dts/brcm/bcm97425svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97425svmb.dts @@ -1,6 +1,7 @@ /dts-v1/; /include/ "bcm7425.dtsi" +/include/ "bcm97xxx-nand-cs1-bch24.dtsi" / { compatible = "brcm,bcm97425svmb", "brcm,bcm7425"; @@ -51,6 +52,14 @@ status = "okay"; }; +&pwma { + status = "okay"; +}; + +&pwmb { + status = "okay"; +}; + &enet0 { status = "okay"; }; @@ -86,3 +95,15 @@ &ohci3 { status = "okay"; }; + +&nand { + status = "okay"; +}; + +&sdhci0 { + status = "okay"; +}; + +&sdhci1 { + status = "okay"; +}; diff --git a/arch/mips/boot/dts/brcm/bcm97435svmb.dts b/arch/mips/boot/dts/brcm/bcm97435svmb.dts index 43e3ba27f07b..fb37b7111bf4 100644 --- a/arch/mips/boot/dts/brcm/bcm97435svmb.dts +++ b/arch/mips/boot/dts/brcm/bcm97435svmb.dts @@ -1,6 +1,7 @@ /dts-v1/; /include/ "bcm7435.dtsi" +/include/ "bcm97xxx-nand-cs1-bch24.dtsi" / { compatible = "brcm,bcm97435svmb", "brcm,bcm7435"; @@ -51,6 +52,14 @@ status = "okay"; }; +&pwma { + status = "okay"; +}; + +&pwmb { + status = "okay"; +}; + &enet0 { status = "okay"; }; @@ -87,6 +96,10 @@ status = "okay"; }; +&nand { + status = "okay"; +}; + &sata { status = "okay"; }; @@ -94,3 +107,11 @@ &sata_phy { status = "okay"; }; + +&sdhci0 { + status = "okay"; +}; + +&sdhci1 { + status = "okay"; +}; diff --git a/arch/mips/boot/dts/brcm/bcm97xxx-nand-cs1-bch24.dtsi b/arch/mips/boot/dts/brcm/bcm97xxx-nand-cs1-bch24.dtsi new file mode 100644 index 000000000000..3c24f97de922 --- /dev/null +++ b/arch/mips/boot/dts/brcm/bcm97xxx-nand-cs1-bch24.dtsi @@ -0,0 +1,25 @@ +&nand { + nandcs@1 { + compatible = "brcm,nandcs"; + reg = <1>; + nand-on-flash-bbt; + + nand-ecc-strength = <24>; + nand-ecc-step-size = <1024>; + brcm,nand-oob-sector-size = <27>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + flash1.rootfs@0 { + reg = <0x0 0x10000000>; + }; + + flash1.kernel@10000000 { + reg = <0x10000000 0x400000>; + }; + }; + }; +}; diff --git a/arch/mips/boot/dts/brcm/bcm97xxx-nand-cs1-bch4.dtsi b/arch/mips/boot/dts/brcm/bcm97xxx-nand-cs1-bch4.dtsi new file mode 100644 index 000000000000..cb531816ef4c --- /dev/null +++ b/arch/mips/boot/dts/brcm/bcm97xxx-nand-cs1-bch4.dtsi @@ -0,0 +1,25 @@ +&nand { + nandcs@1 { + compatible = "brcm,nandcs"; + reg = <1>; + nand-on-flash-bbt; + + nand-ecc-strength = <4>; + nand-ecc-step-size = <512>; + brcm,nand-oob-sector-size = <16>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + flash1.rootfs@0 { + reg = <0x0 0x10000000>; + }; + + flash1.kernel@10000000 { + reg = <0x10000000 0x400000>; + }; + }; + }; +}; diff --git a/arch/mips/boot/dts/cavium-octeon/dlink_dsr-1000n.dts b/arch/mips/boot/dts/cavium-octeon/dlink_dsr-1000n.dts index b134798a0fd7..cfa29156eb69 100644 --- a/arch/mips/boot/dts/cavium-octeon/dlink_dsr-1000n.dts +++ b/arch/mips/boot/dts/cavium-octeon/dlink_dsr-1000n.dts @@ -8,55 +8,16 @@ * published by the Free Software Foundation. */ -/include/ "octeon_3xxx.dtsi" +/include/ "dlink_dsr-500n-1000n.dtsi" #include <dt-bindings/gpio/gpio.h> / { model = "dlink,dsr-1000n"; soc@0 { - smi0: mdio@1180000001800 { - phy8: ethernet-phy@8 { - reg = <8>; - compatible = "ethernet-phy-ieee802.3-c22"; - }; - }; - - pip: pip@11800a0000000 { - interface@0 { - ethernet@0 { - fixed-link { - speed = <1000>; - full-duplex; - }; - }; - ethernet@1 { - fixed-link { - speed = <1000>; - full-duplex; - }; - }; - ethernet@2 { - phy-handle = <&phy8>; - }; - }; - }; - - twsi0: i2c@1180000001000 { - rtc@68 { - compatible = "dallas,ds1337"; - reg = <0x68>; - }; - }; - uart0: serial@1180000000800 { clock-frequency = <500000000>; }; - - usbn: usbn@1180068000000 { - refclk-frequency = <12000000>; - refclk-type = "crystal"; - }; }; leds { @@ -87,8 +48,4 @@ gpios = <&gpio 18 GPIO_ACTIVE_LOW>; }; }; - - aliases { - pip = &pip; - }; }; diff --git a/arch/mips/boot/dts/cavium-octeon/dlink_dsr-500n-1000n.dtsi b/arch/mips/boot/dts/cavium-octeon/dlink_dsr-500n-1000n.dtsi new file mode 100644 index 000000000000..246b598201f8 --- /dev/null +++ b/arch/mips/boot/dts/cavium-octeon/dlink_dsr-500n-1000n.dtsi @@ -0,0 +1,58 @@ +/* + * Device tree source for D-Link DSR-500N/1000N (common parts). + * + * Written by: Aaro Koskinen <aaro.koskinen@iki.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/include/ "octeon_3xxx.dtsi" + +/ { + soc@0 { + smi0: mdio@1180000001800 { + phy8: ethernet-phy@8 { + reg = <8>; + compatible = "ethernet-phy-ieee802.3-c22"; + }; + }; + + pip: pip@11800a0000000 { + interface@0 { + ethernet@0 { + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + ethernet@1 { + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + ethernet@2 { + phy-handle = <&phy8>; + }; + }; + }; + + twsi0: i2c@1180000001000 { + rtc@68 { + compatible = "dallas,ds1337"; + reg = <0x68>; + }; + }; + + usbn: usbn@1180068000000 { + refclk-frequency = <12000000>; + refclk-type = "crystal"; + }; + }; + + aliases { + pip = &pip; + }; +}; diff --git a/arch/mips/boot/dts/cavium-octeon/dlink_dsr-500n.dts b/arch/mips/boot/dts/cavium-octeon/dlink_dsr-500n.dts new file mode 100644 index 000000000000..78886e172c48 --- /dev/null +++ b/arch/mips/boot/dts/cavium-octeon/dlink_dsr-500n.dts @@ -0,0 +1,40 @@ +/* + * Device tree source for D-Link DSR-500N. + * + * Written by: Aaro Koskinen <aaro.koskinen@iki.fi> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/include/ "dlink_dsr-500n-1000n.dtsi" +#include <dt-bindings/gpio/gpio.h> + +/ { + model = "dlink,dsr-500n"; + compatible = "dlink,dsr-500n", "cavium,octeon-3860"; + + soc@0 { + uart0: serial@1180000000800 { + clock-frequency = <300000000>; + }; + }; + + leds { + compatible = "gpio-leds"; + + usb { + gpios = <&gpio 9 GPIO_ACTIVE_LOW>; + }; + + wps { + gpios = <&gpio 11 GPIO_ACTIVE_LOW>; + }; + + wireless { + label = "2.4g"; + gpios = <&gpio 18 GPIO_ACTIVE_LOW>; + }; + }; +}; diff --git a/arch/mips/boot/dts/mti/Makefile b/arch/mips/boot/dts/mti/Makefile index 144d776cc9f2..fcabd69b7030 100644 --- a/arch/mips/boot/dts/mti/Makefile +++ b/arch/mips/boot/dts/mti/Makefile @@ -1,5 +1,5 @@ dtb-$(CONFIG_MIPS_MALTA) += malta.dtb -dtb-$(CONFIG_MIPS_SEAD3) += sead3.dtb +dtb-$(CONFIG_LEGACY_BOARD_SEAD3) += sead3.dtb obj-y += $(patsubst %.dtb, %.dtb.o, $(dtb-y)) diff --git a/arch/mips/boot/dts/mti/malta.dts b/arch/mips/boot/dts/mti/malta.dts index b18c46637d21..f604a272d91d 100644 --- a/arch/mips/boot/dts/mti/malta.dts +++ b/arch/mips/boot/dts/mti/malta.dts @@ -1,5 +1,8 @@ /dts-v1/; +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/interrupt-controller/mips-gic.h> + /memreserve/ 0x00000000 0x00001000; /* YAMON exception vectors */ /memreserve/ 0x00001000 0x000ef000; /* YAMON */ /memreserve/ 0x000f0000 0x00010000; /* PIIX4 ISA memory */ @@ -8,4 +11,100 @@ #address-cells = <1>; #size-cells = <1>; compatible = "mti,malta"; + + cpu_intc: interrupt-controller { + compatible = "mti,cpu-interrupt-controller"; + + interrupt-controller; + #interrupt-cells = <1>; + }; + + gic: interrupt-controller@1bdc0000 { + compatible = "mti,gic"; + reg = <0x1bdc0000 0x20000>; + + interrupt-controller; + #interrupt-cells = <3>; + + /* + * Declare the interrupt-parent even though the mti,gic + * binding doesn't require it, such that the kernel can + * figure out that cpu_intc is the root interrupt + * controller & should be probed first. + */ + interrupt-parent = <&cpu_intc>; + + timer { + compatible = "mti,gic-timer"; + interrupts = <GIC_LOCAL 1 IRQ_TYPE_NONE>; + }; + }; + + i8259: interrupt-controller@20 { + compatible = "intel,i8259"; + + interrupt-controller; + #interrupt-cells = <1>; + + interrupt-parent = <&gic>; + interrupts = <GIC_SHARED 3 IRQ_TYPE_LEVEL_HIGH>; + }; + + flash@1e000000 { + compatible = "intel,dt28f160", "cfi-flash"; + reg = <0x1e000000 0x400000>; + bank-width = <4>; + #address-cells = <1>; + #size-cells = <1>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + yamon@0 { + label = "YAMON"; + reg = <0x0 0x100000>; + read-only; + }; + + user-fs@100000 { + label = "User FS"; + reg = <0x100000 0x2e0000>; + }; + + board-config@3e0000 { + label = "Board Config"; + reg = <0x3e0000 0x20000>; + read-only; + }; + }; + }; + + fpga_regs: system-controller@1f000000 { + compatible = "mti,malta-fpga", "syscon", "simple-mfd"; + reg = <0x1f000000 0x1000>; + + reboot { + compatible = "syscon-reboot"; + regmap = <&fpga_regs>; + offset = <0x500>; + mask = <0x4d>; + }; + }; + + isa { + compatible = "isa"; + #address-cells = <2>; + #size-cells = <1>; + ranges = <1 0 0 0x1000>; + + rtc@70 { + compatible = "motorola,mc146818"; + reg = <1 0x70 0x8>; + + interrupt-parent = <&i8259>; + interrupts = <8>; + }; + }; }; diff --git a/arch/mips/boot/dts/mti/sead3.dts b/arch/mips/boot/dts/mti/sead3.dts index e4b317d414f1..b112879a5d9d 100644 --- a/arch/mips/boot/dts/mti/sead3.dts +++ b/arch/mips/boot/dts/mti/sead3.dts @@ -4,10 +4,23 @@ /memreserve/ 0x00001000 0x000ef000; // ROM data /memreserve/ 0x000f0000 0x004cc000; // reserved +#include <dt-bindings/interrupt-controller/mips-gic.h> + / { #address-cells = <1>; #size-cells = <1>; compatible = "mti,sead-3"; + model = "MIPS SEAD-3"; + interrupt-parent = <&gic>; + + chosen { + stdout-path = "uart1:115200"; + }; + + aliases { + uart0 = &uart0; + uart1 = &uart1; + }; cpus { cpu@0 { @@ -19,4 +32,229 @@ device_type = "memory"; reg = <0x0 0x08000000>; }; + + cpu_intc: interrupt-controller { + compatible = "mti,cpu-interrupt-controller"; + + interrupt-controller; + #interrupt-cells = <1>; + }; + + gic: interrupt-controller@1b1c0000 { + compatible = "mti,gic"; + reg = <0x1b1c0000 0x20000>; + + interrupt-controller; + #interrupt-cells = <3>; + + /* + * Declare the interrupt-parent even though the mti,gic + * binding doesn't require it, such that the kernel can + * figure out that cpu_intc is the root interrupt + * controller & should be probed first. + */ + interrupt-parent = <&cpu_intc>; + + timer { + compatible = "mti,gic-timer"; + interrupts = <GIC_LOCAL 1 IRQ_TYPE_NONE>; + }; + }; + + ehci@1b200000 { + compatible = "generic-ehci"; + reg = <0x1b200000 0x1000>; + + interrupts = <0>; /* GIC 0 or CPU 6 */ + + has-transaction-translator; + }; + + flash@1c000000 { + compatible = "intel,28f128j3", "cfi-flash"; + reg = <0x1c000000 0x2000000>; + #address-cells = <1>; + #size-cells = <1>; + bank-width = <4>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + user-fs@0 { + label = "User FS"; + reg = <0x0 0x1fc0000>; + }; + + board-config@3e0000 { + label = "Board Config"; + reg = <0x1fc0000 0x40000>; + }; + }; + }; + + fpga_regs: system-controller@1f000000 { + compatible = "mti,sead3-fpga", "syscon", "simple-mfd"; + reg = <0x1f000000 0x200>; + + reboot { + compatible = "syscon-reboot"; + regmap = <&fpga_regs>; + offset = <0x50>; + mask = <0x4d>; + }; + + poweroff { + compatible = "restart-poweroff"; + }; + }; + + system-controller@1f000200 { + compatible = "mti,sead3-cpld", "syscon", "simple-mfd"; + reg = <0x1f000200 0x300>; + + led@10.0 { + compatible = "register-bit-led"; + offset = <0x10>; + mask = <0x1>; + label = "pled0"; + }; + led@10.1 { + compatible = "register-bit-led"; + offset = <0x10>; + mask = <0x2>; + label = "pled1"; + }; + led@10.2 { + compatible = "register-bit-led"; + offset = <0x10>; + mask = <0x4>; + label = "pled2"; + }; + led@10.3 { + compatible = "register-bit-led"; + offset = <0x10>; + mask = <0x8>; + label = "pled3"; + }; + led@10.4 { + compatible = "register-bit-led"; + offset = <0x10>; + mask = <0x10>; + label = "pled4"; + }; + led@10.5 { + compatible = "register-bit-led"; + offset = <0x10>; + mask = <0x20>; + label = "pled5"; + }; + led@10.6 { + compatible = "register-bit-led"; + offset = <0x10>; + mask = <0x40>; + label = "pled6"; + }; + led@10.7 { + compatible = "register-bit-led"; + offset = <0x10>; + mask = <0x80>; + label = "pled7"; + }; + + led@18.0 { + compatible = "register-bit-led"; + offset = <0x18>; + mask = <0x1>; + label = "fled0"; + }; + led@18.1 { + compatible = "register-bit-led"; + offset = <0x18>; + mask = <0x2>; + label = "fled1"; + }; + led@18.2 { + compatible = "register-bit-led"; + offset = <0x18>; + mask = <0x4>; + label = "fled2"; + }; + led@18.3 { + compatible = "register-bit-led"; + offset = <0x18>; + mask = <0x8>; + label = "fled3"; + }; + led@18.4 { + compatible = "register-bit-led"; + offset = <0x18>; + mask = <0x10>; + label = "fled4"; + }; + led@18.5 { + compatible = "register-bit-led"; + offset = <0x18>; + mask = <0x20>; + label = "fled5"; + }; + led@18.6 { + compatible = "register-bit-led"; + offset = <0x18>; + mask = <0x40>; + label = "fled6"; + }; + led@18.7 { + compatible = "register-bit-led"; + offset = <0x18>; + mask = <0x80>; + label = "fled7"; + }; + + lcd@200 { + compatible = "mti,sead3-lcd"; + offset = <0x200>; + }; + }; + + /* UART connected to FTDI & miniUSB socket */ + uart0: uart@1f000900 { + compatible = "ns16550a"; + reg = <0x1f000900 0x20>; + reg-io-width = <4>; + reg-shift = <2>; + + clock-frequency = <14745600>; + + interrupts = <3>; /* GIC 3 or CPU 4 */ + + no-loopback-test; + }; + + /* UART connected to RS232 socket */ + uart1: uart@1f000800 { + compatible = "ns16550a"; + reg = <0x1f000800 0x20>; + reg-io-width = <4>; + reg-shift = <2>; + + clock-frequency = <14745600>; + + interrupts = <2>; /* GIC 2 or CPU 4 */ + + no-loopback-test; + }; + + eth@1f010000 { + compatible = "smsc,lan9115"; + reg = <0x1f010000 0x10000>; + reg-io-width = <4>; + + interrupts = <0>; /* GIC 0 or CPU 6 */ + + phy-mode = "mii"; + smsc,irq-push-pull; + smsc,save-mac-address; + }; }; diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c index ff49fc04500c..ab8362e04461 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c @@ -36,8 +36,6 @@ #include <asm/octeon/cvmx-config.h> -#include <asm/octeon/cvmx-mdio.h> - #include <asm/octeon/cvmx-helper.h> #include <asm/octeon/cvmx-helper-util.h> #include <asm/octeon/cvmx-helper-board.h> @@ -46,17 +44,6 @@ #include <asm/octeon/cvmx-asxx-defs.h> /** - * cvmx_override_board_link_get(int ipd_port) is a function - * pointer. It is meant to allow customization of the process of - * talking to a PHY to determine link speed. It is called every - * time a PHY must be polled for link status. Users should set - * this pointer to a function before calling any cvmx-helper - * operations. - */ -cvmx_helper_link_info_t(*cvmx_override_board_link_get) (int ipd_port) = - NULL; - -/** * Return the MII PHY address associated with the given IPD * port. A result of -1 means there isn't a MII capable PHY * connected to this port. On chips supporting multiple MII @@ -222,12 +209,6 @@ int cvmx_helper_board_get_mii_address(int ipd_port) cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port) { cvmx_helper_link_info_t result; - int phy_addr; - int is_broadcom_phy = 0; - - /* Give the user a chance to override the processing of this function */ - if (cvmx_override_board_link_get) - return cvmx_override_board_link_get(ipd_port); /* Unless we fix it later, all links are defaulted to down */ result.u64 = 0; @@ -263,8 +244,7 @@ cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port) result.s.full_duplex = 1; result.s.speed = 1000; return result; - } else /* The other port uses a broadcom PHY */ - is_broadcom_phy = 1; + } break; case CVMX_BOARD_TYPE_BBGW_REF: /* Port 1 on these boards is always Gigabit */ @@ -282,108 +262,7 @@ cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port) break; } - phy_addr = cvmx_helper_board_get_mii_address(ipd_port); - if (phy_addr != -1) { - if (is_broadcom_phy) { - /* - * Below we are going to read SMI/MDIO - * register 0x19 which works on Broadcom - * parts - */ - int phy_status = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - 0x19); - switch ((phy_status >> 8) & 0x7) { - case 0: - result.u64 = 0; - break; - case 1: - result.s.link_up = 1; - result.s.full_duplex = 0; - result.s.speed = 10; - break; - case 2: - result.s.link_up = 1; - result.s.full_duplex = 1; - result.s.speed = 10; - break; - case 3: - result.s.link_up = 1; - result.s.full_duplex = 0; - result.s.speed = 100; - break; - case 4: - result.s.link_up = 1; - result.s.full_duplex = 1; - result.s.speed = 100; - break; - case 5: - result.s.link_up = 1; - result.s.full_duplex = 1; - result.s.speed = 100; - break; - case 6: - result.s.link_up = 1; - result.s.full_duplex = 0; - result.s.speed = 1000; - break; - case 7: - result.s.link_up = 1; - result.s.full_duplex = 1; - result.s.speed = 1000; - break; - } - } else { - /* - * This code assumes we are using a Marvell - * Gigabit PHY. All the speed information can - * be read from register 17 in one - * go. Somebody using a different PHY will - * need to handle it above in the board - * specific area. - */ - int phy_status = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, 17); - - /* - * If the resolve bit 11 isn't set, see if - * autoneg is turned off (bit 12, reg 0). The - * resolve bit doesn't get set properly when - * autoneg is off, so force it. - */ - if ((phy_status & (1 << 11)) == 0) { - int auto_status = - cvmx_mdio_read(phy_addr >> 8, - phy_addr & 0xff, 0); - if ((auto_status & (1 << 12)) == 0) - phy_status |= 1 << 11; - } - - /* - * Only return a link if the PHY has finished - * auto negotiation and set the resolved bit - * (bit 11) - */ - if (phy_status & (1 << 11)) { - result.s.link_up = 1; - result.s.full_duplex = ((phy_status >> 13) & 1); - switch ((phy_status >> 14) & 3) { - case 0: /* 10 Mbps */ - result.s.speed = 10; - break; - case 1: /* 100 Mbps */ - result.s.speed = 100; - break; - case 2: /* 1 Gbps */ - result.s.speed = 1000; - break; - case 3: /* Illegal */ - result.u64 = 0; - break; - } - } - } - } else if (OCTEON_IS_MODEL(OCTEON_CN3XXX) + if (OCTEON_IS_MODEL(OCTEON_CN3XXX) || OCTEON_IS_MODEL(OCTEON_CN58XX) || OCTEON_IS_MODEL(OCTEON_CN50XX)) { /* @@ -433,176 +312,6 @@ cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port) } /** - * This function as a board specific method of changing the PHY - * speed, duplex, and auto-negotiation. This programs the PHY and - * not Octeon. This can be used to force Octeon's links to - * specific settings. - * - * @phy_addr: The address of the PHY to program - * @enable_autoneg: - * Non zero if you want to enable auto-negotiation. - * @link_info: Link speed to program. If the speed is zero and auto-negotiation - * is enabled, all possible negotiation speeds are advertised. - * - * Returns Zero on success, negative on failure - */ -int cvmx_helper_board_link_set_phy(int phy_addr, - cvmx_helper_board_set_phy_link_flags_types_t - link_flags, - cvmx_helper_link_info_t link_info) -{ - - /* Set the flow control settings based on link_flags */ - if ((link_flags & set_phy_link_flags_flow_control_mask) != - set_phy_link_flags_flow_control_dont_touch) { - cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver; - reg_autoneg_adver.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_AUTONEG_ADVER); - reg_autoneg_adver.s.asymmetric_pause = - (link_flags & set_phy_link_flags_flow_control_mask) == - set_phy_link_flags_flow_control_enable; - reg_autoneg_adver.s.pause = - (link_flags & set_phy_link_flags_flow_control_mask) == - set_phy_link_flags_flow_control_enable; - cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_AUTONEG_ADVER, - reg_autoneg_adver.u16); - } - - /* If speed isn't set and autoneg is on advertise all supported modes */ - if ((link_flags & set_phy_link_flags_autoneg) - && (link_info.s.speed == 0)) { - cvmx_mdio_phy_reg_control_t reg_control; - cvmx_mdio_phy_reg_status_t reg_status; - cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver; - cvmx_mdio_phy_reg_extended_status_t reg_extended_status; - cvmx_mdio_phy_reg_control_1000_t reg_control_1000; - - reg_status.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_STATUS); - reg_autoneg_adver.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_AUTONEG_ADVER); - reg_autoneg_adver.s.advert_100base_t4 = - reg_status.s.capable_100base_t4; - reg_autoneg_adver.s.advert_10base_tx_full = - reg_status.s.capable_10_full; - reg_autoneg_adver.s.advert_10base_tx_half = - reg_status.s.capable_10_half; - reg_autoneg_adver.s.advert_100base_tx_full = - reg_status.s.capable_100base_x_full; - reg_autoneg_adver.s.advert_100base_tx_half = - reg_status.s.capable_100base_x_half; - cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_AUTONEG_ADVER, - reg_autoneg_adver.u16); - if (reg_status.s.capable_extended_status) { - reg_extended_status.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_EXTENDED_STATUS); - reg_control_1000.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_CONTROL_1000); - reg_control_1000.s.advert_1000base_t_full = - reg_extended_status.s.capable_1000base_t_full; - reg_control_1000.s.advert_1000base_t_half = - reg_extended_status.s.capable_1000base_t_half; - cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_CONTROL_1000, - reg_control_1000.u16); - } - reg_control.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_CONTROL); - reg_control.s.autoneg_enable = 1; - reg_control.s.restart_autoneg = 1; - cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16); - } else if ((link_flags & set_phy_link_flags_autoneg)) { - cvmx_mdio_phy_reg_control_t reg_control; - cvmx_mdio_phy_reg_status_t reg_status; - cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver; - cvmx_mdio_phy_reg_control_1000_t reg_control_1000; - - reg_status.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_STATUS); - reg_autoneg_adver.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_AUTONEG_ADVER); - reg_autoneg_adver.s.advert_100base_t4 = 0; - reg_autoneg_adver.s.advert_10base_tx_full = 0; - reg_autoneg_adver.s.advert_10base_tx_half = 0; - reg_autoneg_adver.s.advert_100base_tx_full = 0; - reg_autoneg_adver.s.advert_100base_tx_half = 0; - if (reg_status.s.capable_extended_status) { - reg_control_1000.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_CONTROL_1000); - reg_control_1000.s.advert_1000base_t_full = 0; - reg_control_1000.s.advert_1000base_t_half = 0; - } - switch (link_info.s.speed) { - case 10: - reg_autoneg_adver.s.advert_10base_tx_full = - link_info.s.full_duplex; - reg_autoneg_adver.s.advert_10base_tx_half = - !link_info.s.full_duplex; - break; - case 100: - reg_autoneg_adver.s.advert_100base_tx_full = - link_info.s.full_duplex; - reg_autoneg_adver.s.advert_100base_tx_half = - !link_info.s.full_duplex; - break; - case 1000: - reg_control_1000.s.advert_1000base_t_full = - link_info.s.full_duplex; - reg_control_1000.s.advert_1000base_t_half = - !link_info.s.full_duplex; - break; - } - cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_AUTONEG_ADVER, - reg_autoneg_adver.u16); - if (reg_status.s.capable_extended_status) - cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_CONTROL_1000, - reg_control_1000.u16); - reg_control.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_CONTROL); - reg_control.s.autoneg_enable = 1; - reg_control.s.restart_autoneg = 1; - cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16); - } else { - cvmx_mdio_phy_reg_control_t reg_control; - reg_control.u16 = - cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_CONTROL); - reg_control.s.autoneg_enable = 0; - reg_control.s.restart_autoneg = 1; - reg_control.s.duplex = link_info.s.full_duplex; - if (link_info.s.speed == 1000) { - reg_control.s.speed_msb = 1; - reg_control.s.speed_lsb = 0; - } else if (link_info.s.speed == 100) { - reg_control.s.speed_msb = 0; - reg_control.s.speed_lsb = 1; - } else if (link_info.s.speed == 10) { - reg_control.s.speed_msb = 0; - reg_control.s.speed_lsb = 0; - } - cvmx_mdio_write(phy_addr >> 8, phy_addr & 0xff, - CVMX_MDIO_PHY_REG_CONTROL, reg_control.u16); - } - return 0; -} - -/** * This function is called by cvmx_helper_interface_probe() after it * determines the number of ports Octeon can support on a specific * interface. This function is the per board location to override @@ -676,48 +385,6 @@ int __cvmx_helper_board_hardware_enable(int interface) 0xc); } } else if (cvmx_sysinfo_get()->board_type == - CVMX_BOARD_TYPE_CN3010_EVB_HS5) { - /* - * Broadcom PHYs require differnet ASX - * clocks. Unfortunately many boards don't define a - * new board Id and simply mangle the - * CN3010_EVB_HS5 - */ - if (interface == 0) { - /* - * Some boards use a hacked up bootloader that - * identifies them as CN3010_EVB_HS5 - * evaluation boards. This leads to all kinds - * of configuration problems. Detect one - * case, and print warning, while trying to do - * the right thing. - */ - int phy_addr = cvmx_helper_board_get_mii_address(0); - if (phy_addr != -1) { - int phy_identifier = - cvmx_mdio_read(phy_addr >> 8, - phy_addr & 0xff, 0x2); - /* Is it a Broadcom PHY? */ - if (phy_identifier == 0x0143) { - cvmx_dprintf("\n"); - cvmx_dprintf("ERROR:\n"); - cvmx_dprintf - ("ERROR: Board type is CVMX_BOARD_TYPE_CN3010_EVB_HS5, but Broadcom PHY found.\n"); - cvmx_dprintf - ("ERROR: The board type is mis-configured, and software malfunctions are likely.\n"); - cvmx_dprintf - ("ERROR: All boards require a unique board type to identify them.\n"); - cvmx_dprintf("ERROR:\n"); - cvmx_dprintf("\n"); - cvmx_wait(1000000000); - cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX - (0, interface), 5); - cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX - (0, interface), 5); - } - } - } - } else if (cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_UBNT_E100) { cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(0, interface), 0); cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(0, interface), 0x10); diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c b/arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c index f59c88ee9b31..671ab1db2727 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c @@ -33,8 +33,6 @@ #include <asm/octeon/cvmx-config.h> - -#include <asm/octeon/cvmx-mdio.h> #include <asm/octeon/cvmx-pko.h> #include <asm/octeon/cvmx-helper.h> #include <asm/octeon/cvmx-helper-board.h> @@ -243,8 +241,7 @@ int __cvmx_helper_rgmii_enable(int interface) /* enable the ports now */ for (port = 0; port < num_ports; port++) { union cvmx_gmxx_prtx_cfg gmx_cfg; - cvmx_helper_link_autoconf(cvmx_helper_get_ipd_port - (interface, port)); + gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(port, interface)); gmx_cfg.s.en = 1; diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-sgmii.c b/arch/mips/cavium-octeon/executive/cvmx-helper-sgmii.c index 6f9609e63a65..54375340afe8 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper-sgmii.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper-sgmii.c @@ -34,7 +34,6 @@ #include <asm/octeon/cvmx-config.h> -#include <asm/octeon/cvmx-mdio.h> #include <asm/octeon/cvmx-helper.h> #include <asm/octeon/cvmx-helper-board.h> diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c b/arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c index a56ee590de1f..d347fe13b666 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c @@ -234,8 +234,6 @@ int __cvmx_helper_xaui_enable(int interface) cvmx_write_csr(CVMX_GMXX_TX_INT_EN(interface), gmx_tx_int_en.u64); cvmx_write_csr(CVMX_PCSXX_INT_EN_REG(interface), pcsx_int_en_reg.u64); - cvmx_helper_link_autoconf(cvmx_helper_get_ipd_port(interface, 0)); - /* (8) Enable packet reception */ xauiMiscCtl.s.gmxeno = 0; cvmx_write_csr(CVMX_PCSXX_MISC_CTL_REG(interface), xauiMiscCtl.u64); diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper.c b/arch/mips/cavium-octeon/executive/cvmx-helper.c index ff26d0217b87..6456af642471 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper.c @@ -841,7 +841,6 @@ int __cvmx_helper_errata_fix_ipd_ptr_alignment(void) int retry_cnt; int retry_loop_cnt; int i; - cvmx_helper_link_info_t link_info; /* Save values for restore at end */ uint64_t prtx_cfg = @@ -1002,15 +1001,6 @@ fix_ipd_exit: (INDEX(FIX_IPD_OUTPORT), INTERFACE(FIX_IPD_OUTPORT)), frame_max); cvmx_write_csr(CVMX_ASXX_PRT_LOOP(INTERFACE(FIX_IPD_OUTPORT)), 0); - /* Set link to down so autonegotiation will set it up again */ - link_info.u64 = 0; - cvmx_helper_link_set(FIX_IPD_OUTPORT, link_info); - - /* - * Bring the link back up as autonegotiation is not done in - * user applications. - */ - cvmx_helper_link_autoconf(FIX_IPD_OUTPORT); CVMX_SYNC; if (num_segs) diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index 5537f95b28c9..9a2db1c013d9 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -65,7 +65,8 @@ EXPORT_SYMBOL(octeon_should_swizzle_table); extern void pci_console_init(const char *arg); #endif -static unsigned long long MAX_MEMORY = 512ull << 20; +static unsigned long long max_memory = ULLONG_MAX; +static unsigned long long reserve_low_mem; DEFINE_SEMAPHORE(octeon_bootbus_sem); EXPORT_SYMBOL(octeon_bootbus_sem); @@ -75,7 +76,6 @@ struct octeon_boot_descriptor *octeon_boot_desc_ptr; struct cvmx_bootinfo *octeon_bootinfo; EXPORT_SYMBOL(octeon_bootinfo); -static unsigned long long RESERVE_LOW_MEM = 0ull; #ifdef CONFIG_KEXEC #ifdef CONFIG_SMP /* @@ -125,18 +125,18 @@ static void kexec_bootmem_init(uint64_t mem_size, uint32_t low_reserved_bytes) bootmem_desc->major_version = CVMX_BOOTMEM_DESC_MAJ_VER; bootmem_desc->minor_version = CVMX_BOOTMEM_DESC_MIN_VER; - addr = (OCTEON_DDR0_BASE + RESERVE_LOW_MEM + low_reserved_bytes); + addr = (OCTEON_DDR0_BASE + reserve_low_mem + low_reserved_bytes); bootmem_desc->head_addr = 0; if (mem_size <= OCTEON_DDR0_SIZE) { __cvmx_bootmem_phy_free(addr, - mem_size - RESERVE_LOW_MEM - + mem_size - reserve_low_mem - low_reserved_bytes, 0); return; } __cvmx_bootmem_phy_free(addr, - OCTEON_DDR0_SIZE - RESERVE_LOW_MEM - + OCTEON_DDR0_SIZE - reserve_low_mem - low_reserved_bytes, 0); mem_size -= OCTEON_DDR0_SIZE; @@ -857,15 +857,15 @@ void __init prom_init(void) /* Default to 64MB in the simulator to speed things up */ if (octeon_is_simulation()) - MAX_MEMORY = 64ull << 20; + max_memory = 64ull << 20; arg = strstr(arcs_cmdline, "mem="); if (arg) { - MAX_MEMORY = memparse(arg + 4, &p); - if (MAX_MEMORY == 0) - MAX_MEMORY = 32ull << 30; + max_memory = memparse(arg + 4, &p); + if (max_memory == 0) + max_memory = 32ull << 30; if (*p == '@') - RESERVE_LOW_MEM = memparse(p + 1, &p); + reserve_low_mem = memparse(p + 1, &p); } arcs_cmdline[0] = 0; @@ -875,11 +875,11 @@ void __init prom_init(void) cvmx_phys_to_ptr(octeon_boot_desc_ptr->argv[i]); if ((strncmp(arg, "MEM=", 4) == 0) || (strncmp(arg, "mem=", 4) == 0)) { - MAX_MEMORY = memparse(arg + 4, &p); - if (MAX_MEMORY == 0) - MAX_MEMORY = 32ull << 30; + max_memory = memparse(arg + 4, &p); + if (max_memory == 0) + max_memory = 32ull << 30; if (*p == '@') - RESERVE_LOW_MEM = memparse(p + 1, &p); + reserve_low_mem = memparse(p + 1, &p); #ifdef CONFIG_KEXEC } else if (strncmp(arg, "crashkernel=", 12) == 0) { crashk_size = memparse(arg+12, &p); @@ -971,13 +971,13 @@ void __init plat_mem_setup(void) * to consistently work. */ mem_alloc_size = 4 << 20; - if (mem_alloc_size > MAX_MEMORY) - mem_alloc_size = MAX_MEMORY; + if (mem_alloc_size > max_memory) + mem_alloc_size = max_memory; /* Crashkernel ignores bootmem list. It relies on mem=X@Y option */ #ifdef CONFIG_CRASH_DUMP - add_memory_region(RESERVE_LOW_MEM, MAX_MEMORY, BOOT_MEM_RAM); - total += MAX_MEMORY; + add_memory_region(reserve_low_mem, max_memory, BOOT_MEM_RAM); + total += max_memory; #else #ifdef CONFIG_KEXEC if (crashk_size > 0) { @@ -992,7 +992,7 @@ void __init plat_mem_setup(void) */ cvmx_bootmem_lock(); while ((boot_mem_map.nr_map < BOOT_MEM_MAP_MAX) - && (total < MAX_MEMORY)) { + && (total < max_memory)) { memory = cvmx_bootmem_phy_alloc(mem_alloc_size, __pa_symbol(&_end), -1, 0x100000, diff --git a/arch/mips/configs/generic/32r1.config b/arch/mips/configs/generic/32r1.config new file mode 100644 index 000000000000..a11cd8715519 --- /dev/null +++ b/arch/mips/configs/generic/32r1.config @@ -0,0 +1,2 @@ +CONFIG_CPU_MIPS32_R1=y +CONFIG_HIGHMEM=y diff --git a/arch/mips/configs/generic/32r2.config b/arch/mips/configs/generic/32r2.config new file mode 100644 index 000000000000..9570672d4f9f --- /dev/null +++ b/arch/mips/configs/generic/32r2.config @@ -0,0 +1,3 @@ +CONFIG_CPU_MIPS32_R2=y +CONFIG_MIPS_O32_FP64_SUPPORT=y +CONFIG_HIGHMEM=y diff --git a/arch/mips/configs/generic/32r6.config b/arch/mips/configs/generic/32r6.config new file mode 100644 index 000000000000..ca606e71f4d0 --- /dev/null +++ b/arch/mips/configs/generic/32r6.config @@ -0,0 +1,2 @@ +CONFIG_CPU_MIPS32_R6=y +CONFIG_HIGHMEM=y diff --git a/arch/mips/configs/generic/64r1.config b/arch/mips/configs/generic/64r1.config new file mode 100644 index 000000000000..7c1ea7e7bae3 --- /dev/null +++ b/arch/mips/configs/generic/64r1.config @@ -0,0 +1,4 @@ +CONFIG_CPU_MIPS64_R1=y +CONFIG_64BIT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y diff --git a/arch/mips/configs/generic/64r2.config b/arch/mips/configs/generic/64r2.config new file mode 100644 index 000000000000..b4d31ae8bfec --- /dev/null +++ b/arch/mips/configs/generic/64r2.config @@ -0,0 +1,5 @@ +CONFIG_CPU_MIPS64_R2=y +CONFIG_MIPS_O32_FP64_SUPPORT=y +CONFIG_64BIT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y diff --git a/arch/mips/configs/generic/64r6.config b/arch/mips/configs/generic/64r6.config new file mode 100644 index 000000000000..7cac0339c4d5 --- /dev/null +++ b/arch/mips/configs/generic/64r6.config @@ -0,0 +1,4 @@ +CONFIG_CPU_MIPS64_R6=y +CONFIG_64BIT=y +CONFIG_MIPS32_O32=y +CONFIG_MIPS32_N32=y diff --git a/arch/mips/configs/generic/board-sead-3.config b/arch/mips/configs/generic/board-sead-3.config new file mode 100644 index 000000000000..3b5e1ac579eb --- /dev/null +++ b/arch/mips/configs/generic/board-sead-3.config @@ -0,0 +1,32 @@ +CONFIG_LEGACY_BOARD_SEAD3=y + +CONFIG_AUXDISPLAY=y +CONFIG_IMG_ASCII_LCD=y + +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_SYSCON=y + +CONFIG_MMC=y +CONFIG_MMC_SPI=y + +CONFIG_MTD=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_OF_PARTS=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_GLUEBI=y + +CONFIG_NETDEVICES=y +CONFIG_SMSC911X=y +CONFIG_SMSC_PHY=y + +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_OF_PLATFORM=y + +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y diff --git a/arch/mips/configs/generic/eb.config b/arch/mips/configs/generic/eb.config new file mode 100644 index 000000000000..c5cdc99a6530 --- /dev/null +++ b/arch/mips/configs/generic/eb.config @@ -0,0 +1 @@ +CONFIG_CPU_BIG_ENDIAN=y diff --git a/arch/mips/configs/generic/el.config b/arch/mips/configs/generic/el.config new file mode 100644 index 000000000000..ee43fdb3b8f4 --- /dev/null +++ b/arch/mips/configs/generic/el.config @@ -0,0 +1 @@ +CONFIG_CPU_LITTLE_ENDIAN=y diff --git a/arch/mips/configs/generic/micro32r2.config b/arch/mips/configs/generic/micro32r2.config new file mode 100644 index 000000000000..b701fe7aaa68 --- /dev/null +++ b/arch/mips/configs/generic/micro32r2.config @@ -0,0 +1,4 @@ +CONFIG_CPU_MIPS32_R2=y +CONFIG_CPU_MICROMIPS=y +CONFIG_MIPS_O32_FP64_SUPPORT=y +CONFIG_HIGHMEM=y diff --git a/arch/mips/configs/generic_defconfig b/arch/mips/configs/generic_defconfig new file mode 100644 index 000000000000..c95d94c7838b --- /dev/null +++ b/arch/mips/configs/generic_defconfig @@ -0,0 +1,96 @@ +CONFIG_MIPS_GENERIC=y +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_MIPS_CPS=y +CONFIG_CPU_HAS_MSA=y +CONFIG_HIGHMEM=y +CONFIG_NR_CPUS=2 +CONFIG_MIPS_O32_FP64_SUPPORT=y +CONFIG_SYSVIPC=y +CONFIG_NO_HZ_IDLE=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_MEMCG=y +CONFIG_MEMCG_SWAP=y +CONFIG_BLK_CGROUP=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_SCHED_AUTOGROUP=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_BPF_SYSCALL=y +CONFIG_USERFAULTFD=y +CONFIG_EMBEDDED=y +# CONFIG_SLUB_DEBUG is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_CC_STACKPROTECTOR_REGULAR=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_TRIM_UNUSED_KSYMS=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_NETFILTER=y +# CONFIG_WIRELESS is not set +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_SCSI=y +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +CONFIG_HW_RANDOM=y +# CONFIG_HWMON is not set +CONFIG_MFD_SYSCON=y +CONFIG_HID_A4TECH=y +CONFIG_HID_APPLE=y +CONFIG_HID_BELKIN=y +CONFIG_HID_CHERRY=y +CONFIG_HID_CHICONY=y +CONFIG_HID_CYPRESS=y +CONFIG_HID_EZKEY=y +CONFIG_HID_KENSINGTON=y +CONFIG_HID_LOGITECH=y +CONFIG_HID_MICROSOFT=y +CONFIG_HID_MONTEREY=y +# CONFIG_USB_SUPPORT is not set +# CONFIG_MIPS_PLATFORM_DEVICES is not set +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_EXT4_ENCRYPTION=y +CONFIG_FANOTIFY=y +CONFIG_FUSE_FS=y +CONFIG_CUSE=y +CONFIG_OVERLAY_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +# CONFIG_MISC_FILESYSTEMS is not set +CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_INFO_REDUCED=y +CONFIG_DEBUG_FS=y +# CONFIG_SCHED_DEBUG is not set +# CONFIG_FTRACE is not set +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="earlycon" +# CONFIG_XZ_DEC_X86 is not set +# CONFIG_XZ_DEC_POWERPC is not set +# CONFIG_XZ_DEC_IA64 is not set +# CONFIG_XZ_DEC_ARM is not set +# CONFIG_XZ_DEC_ARMTHUMB is not set +# CONFIG_XZ_DEC_SPARC is not set diff --git a/arch/mips/configs/loongson1c_defconfig b/arch/mips/configs/loongson1c_defconfig new file mode 100644 index 000000000000..2304d4165773 --- /dev/null +++ b/arch/mips/configs/loongson1c_defconfig @@ -0,0 +1,126 @@ +CONFIG_MACH_LOONGSON32=y +CONFIG_LOONGSON1_LS1C=y +CONFIG_PREEMPT=y +# CONFIG_SECCOMP is not set +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_KERNEL_XZ=y +CONFIG_SYSVIPC=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_BSD_PROCESS_ACCT_V3=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_NAMESPACES=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_EXPERT=y +CONFIG_PERF_EVENTS=y +# CONFIG_COMPAT_BRK is not set +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_LBDAF is not set +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_SUSPEND is not set +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_SYN_COOKIES=y +# CONFIG_INET_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_DIAG is not set +# CONFIG_IPV6 is not set +# CONFIG_WIRELESS is not set +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +# CONFIG_STANDALONE is not set +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_NAND=y +CONFIG_MTD_NAND_LOONGSON1=y +CONFIG_MTD_UBI=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_SCSI=m +# CONFIG_SCSI_PROC_FS is not set +CONFIG_BLK_DEV_SD=m +# CONFIG_SCSI_LOWLEVEL is not set +CONFIG_NETDEVICES=y +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SMSC is not set +CONFIG_STMMAC_ETH=y +# CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_WLAN is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_SERIO is not set +CONFIG_VT_HW_CONSOLE_BINDING=y +CONFIG_LEGACY_PTY_COUNT=8 +# CONFIG_DEVKMEM is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_HW_RANDOM is not set +CONFIG_GPIOLIB=y +CONFIG_GPIO_LOONGSON1=y +# CONFIG_HWMON is not set +# CONFIG_VGA_CONSOLE is not set +CONFIG_HID_GENERIC=m +CONFIG_USB_HID=m +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_STORAGE=m +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_PL2303=m +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_LOONGSON1=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +CONFIG_EXT2_FS_POSIX_ACL=y +CONFIG_EXT2_FS_SECURITY=y +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +# CONFIG_DNOTIFY is not set +CONFIG_VFAT_FS=y +CONFIG_PROC_KCORE=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_UBIFS_FS=y +CONFIG_UBIFS_FS_ADVANCED_COMPR=y +CONFIG_UBIFS_ATIME_SUPPORT=y +CONFIG_NFS_FS=y +CONFIG_ROOT_NFS=y +CONFIG_NLS_CODEPAGE_437=m +CONFIG_NLS_ISO8859_1=m +CONFIG_DYNAMIC_DEBUG=y +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +CONFIG_DEBUG_FS=y +CONFIG_MAGIC_SYSRQ=y +# CONFIG_SCHED_DEBUG is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_FTRACE is not set +# CONFIG_EARLY_PRINTK is not set +# CONFIG_CRYPTO_ECHAINIV is not set +# CONFIG_CRYPTO_HW is not set diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index 5afb4840aec7..58d43f3c348d 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -230,7 +230,7 @@ CONFIG_MTD_CFI=y CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_CFI_STAA=y -CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y CONFIG_MTD_UBI=m CONFIG_MTD_UBI_GLUEBI=m CONFIG_BLK_DEV_FD=m @@ -318,6 +318,8 @@ CONFIG_LIBERTAS=m # CONFIG_SERIO_I8042 is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FB_CIRRUS=y diff --git a/arch/mips/configs/malta_kvm_defconfig b/arch/mips/configs/malta_kvm_defconfig index 98f13879bb8f..c8f7e2835840 100644 --- a/arch/mips/configs/malta_kvm_defconfig +++ b/arch/mips/configs/malta_kvm_defconfig @@ -235,7 +235,7 @@ CONFIG_MTD_CFI=y CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_CFI_STAA=y -CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y CONFIG_MTD_UBI=m CONFIG_MTD_UBI_GLUEBI=m CONFIG_BLK_DEV_FD=m @@ -331,6 +331,8 @@ CONFIG_LIBERTAS=m # CONFIG_SERIO_I8042 is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FB_CIRRUS=y diff --git a/arch/mips/configs/malta_kvm_guest_defconfig b/arch/mips/configs/malta_kvm_guest_defconfig index 3b5d5913f548..d2f54e55356c 100644 --- a/arch/mips/configs/malta_kvm_guest_defconfig +++ b/arch/mips/configs/malta_kvm_guest_defconfig @@ -234,7 +234,7 @@ CONFIG_MTD_CFI=y CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_CFI_STAA=y -CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y CONFIG_MTD_UBI=m CONFIG_MTD_UBI_GLUEBI=m CONFIG_BLK_DEV_FD=m @@ -331,6 +331,8 @@ CONFIG_LIBERTAS=m # CONFIG_SERIO_I8042 is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FB_CIRRUS=y diff --git a/arch/mips/configs/malta_qemu_32r6_defconfig b/arch/mips/configs/malta_qemu_32r6_defconfig index 65f140e1e872..cbf37dd0c490 100644 --- a/arch/mips/configs/malta_qemu_32r6_defconfig +++ b/arch/mips/configs/malta_qemu_32r6_defconfig @@ -132,6 +132,8 @@ CONFIG_LEGACY_PTY_COUNT=4 CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_HW_RANDOM=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FIRMWARE_EDID=y diff --git a/arch/mips/configs/maltaaprp_defconfig b/arch/mips/configs/maltaaprp_defconfig index 799c4338fd5e..35f6ba260df8 100644 --- a/arch/mips/configs/maltaaprp_defconfig +++ b/arch/mips/configs/maltaaprp_defconfig @@ -132,6 +132,8 @@ CONFIG_LEGACY_PTY_COUNT=16 CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_HW_RANDOM=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y diff --git a/arch/mips/configs/maltasmvp_defconfig b/arch/mips/configs/maltasmvp_defconfig index ac0eb4daf101..900f14543eeb 100644 --- a/arch/mips/configs/maltasmvp_defconfig +++ b/arch/mips/configs/maltasmvp_defconfig @@ -134,6 +134,8 @@ CONFIG_LEGACY_PTY_COUNT=4 CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_HW_RANDOM=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FIRMWARE_EDID=y diff --git a/arch/mips/configs/maltasmvp_eva_defconfig b/arch/mips/configs/maltasmvp_eva_defconfig index 31846000530f..8e2738b5e180 100644 --- a/arch/mips/configs/maltasmvp_eva_defconfig +++ b/arch/mips/configs/maltasmvp_eva_defconfig @@ -137,6 +137,8 @@ CONFIG_LEGACY_PTY_COUNT=4 CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_HW_RANDOM=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y diff --git a/arch/mips/configs/maltaup_defconfig b/arch/mips/configs/maltaup_defconfig index a79107da0675..6dc4e309a691 100644 --- a/arch/mips/configs/maltaup_defconfig +++ b/arch/mips/configs/maltaup_defconfig @@ -131,6 +131,8 @@ CONFIG_LEGACY_PTY_COUNT=16 CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_HW_RANDOM=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y diff --git a/arch/mips/configs/maltaup_xpa_defconfig b/arch/mips/configs/maltaup_xpa_defconfig index 732215732751..3d0d9cb9673f 100644 --- a/arch/mips/configs/maltaup_xpa_defconfig +++ b/arch/mips/configs/maltaup_xpa_defconfig @@ -231,7 +231,7 @@ CONFIG_MTD_CFI=y CONFIG_MTD_CFI_INTELEXT=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_CFI_STAA=y -CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y CONFIG_MTD_UBI=m CONFIG_MTD_UBI_GLUEBI=m CONFIG_BLK_DEV_FD=m @@ -326,6 +326,8 @@ CONFIG_LIBERTAS=m # CONFIG_SERIO_I8042 is not set CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_SYSCON=y # CONFIG_HWMON is not set CONFIG_FB=y CONFIG_FB_CIRRUS=y diff --git a/arch/mips/configs/pistachio_defconfig b/arch/mips/configs/pistachio_defconfig index 8b7429127a1d..7d32fbbca962 100644 --- a/arch/mips/configs/pistachio_defconfig +++ b/arch/mips/configs/pistachio_defconfig @@ -29,7 +29,6 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y -CONFIG_CC_STACKPROTECTOR_STRONG=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y @@ -264,7 +263,6 @@ CONFIG_DMADEVICES=y CONFIG_IMG_MDC_DMA=y CONFIG_STAGING=y CONFIG_ASHMEM=y -# CONFIG_ANDROID_TIMED_OUTPUT is not set # CONFIG_IOMMU_SUPPORT is not set CONFIG_MEMORY=y CONFIG_IIO=y diff --git a/arch/mips/configs/sead3_defconfig b/arch/mips/configs/sead3_defconfig deleted file mode 100644 index dae9354b6256..000000000000 --- a/arch/mips/configs/sead3_defconfig +++ /dev/null @@ -1,121 +0,0 @@ -CONFIG_MIPS_SEAD3=y -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_CPU_MIPS32_R2=y -CONFIG_HZ_100=y -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=15 -CONFIG_EMBEDDED=y -CONFIG_SLAB=y -CONFIG_PROFILING=y -CONFIG_OPROFILE=y -CONFIG_MODULES=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -# CONFIG_IPV6 is not set -# CONFIG_WIRELESS is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_DEVTMPFS=y -CONFIG_MTD=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_GLUEBI=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_CRYPTOLOOP=m -CONFIG_SCSI=y -# CONFIG_SCSI_PROC_FS is not set -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_SG=y -# CONFIG_SCSI_LOWLEVEL is not set -CONFIG_NETDEVICES=y -CONFIG_SMSC911X=y -# CONFIG_NET_VENDOR_WIZNET is not set -CONFIG_MARVELL_PHY=y -CONFIG_DAVICOM_PHY=y -CONFIG_QSEMI_PHY=y -CONFIG_LXT_PHY=y -CONFIG_CICADA_PHY=y -CONFIG_VITESSE_PHY=y -CONFIG_SMSC_PHY=y -CONFIG_BROADCOM_PHY=y -CONFIG_ICPLUS_PHY=y -# CONFIG_WLAN is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO is not set -# CONFIG_CONSOLE_TRANSLATIONS is not set -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_LEGACY_PTY_COUNT=32 -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=y -# CONFIG_I2C_COMPAT is not set -CONFIG_I2C_CHARDEV=y -# CONFIG_I2C_HELPER_AUTO is not set -CONFIG_SPI=y -CONFIG_SENSORS_ADT7475=y -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_LCD_CLASS_DEVICE=y -CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_VGA_CONSOLE is not set -CONFIG_USB=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_ROOT_HUB_TT=y -CONFIG_USB_STORAGE=y -CONFIG_MMC=y -CONFIG_MMC_DEBUG=y -CONFIG_MMC_SPI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_M41T80=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_XFS_FS=y -CONFIG_XFS_QUOTA=y -CONFIG_XFS_POSIX_ACL=y -CONFIG_QUOTA=y -# CONFIG_PRINT_QUOTA_WARNING is not set -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_TMPFS=y -CONFIG_JFFS2_FS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_ASCII=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_ISO8859_15=y -CONFIG_NLS_UTF8=y -# CONFIG_FTRACE is not set -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_ARC4=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRYPTO_HW is not set diff --git a/arch/mips/configs/sead3micro_defconfig b/arch/mips/configs/sead3micro_defconfig deleted file mode 100644 index cd91a775c74e..000000000000 --- a/arch/mips/configs/sead3micro_defconfig +++ /dev/null @@ -1,122 +0,0 @@ -CONFIG_MIPS_SEAD3=y -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_CPU_MIPS32_R2=y -CONFIG_CPU_MICROMIPS=y -CONFIG_HZ_100=y -CONFIG_SYSVIPC=y -CONFIG_POSIX_MQUEUE=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y -CONFIG_IKCONFIG=y -CONFIG_IKCONFIG_PROC=y -CONFIG_LOG_BUF_SHIFT=15 -CONFIG_EMBEDDED=y -CONFIG_SLAB=y -CONFIG_PROFILING=y -CONFIG_OPROFILE=y -CONFIG_MODULES=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -# CONFIG_IPV6 is not set -# CONFIG_WIRELESS is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_DEVTMPFS=y -CONFIG_MTD=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_UBI=y -CONFIG_MTD_UBI_GLUEBI=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_CRYPTOLOOP=m -CONFIG_SCSI=y -# CONFIG_SCSI_PROC_FS is not set -CONFIG_BLK_DEV_SD=y -CONFIG_CHR_DEV_SG=y -# CONFIG_SCSI_LOWLEVEL is not set -CONFIG_NETDEVICES=y -CONFIG_SMSC911X=y -# CONFIG_NET_VENDOR_WIZNET is not set -CONFIG_MARVELL_PHY=y -CONFIG_DAVICOM_PHY=y -CONFIG_QSEMI_PHY=y -CONFIG_LXT_PHY=y -CONFIG_CICADA_PHY=y -CONFIG_VITESSE_PHY=y -CONFIG_SMSC_PHY=y -CONFIG_BROADCOM_PHY=y -CONFIG_ICPLUS_PHY=y -# CONFIG_WLAN is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_SERIO is not set -# CONFIG_CONSOLE_TRANSLATIONS is not set -CONFIG_VT_HW_CONSOLE_BINDING=y -CONFIG_LEGACY_PTY_COUNT=32 -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -# CONFIG_HW_RANDOM is not set -CONFIG_I2C=y -# CONFIG_I2C_COMPAT is not set -CONFIG_I2C_CHARDEV=y -# CONFIG_I2C_HELPER_AUTO is not set -CONFIG_SPI=y -CONFIG_SENSORS_ADT7475=y -CONFIG_BACKLIGHT_LCD_SUPPORT=y -CONFIG_LCD_CLASS_DEVICE=y -CONFIG_BACKLIGHT_CLASS_DEVICE=y -# CONFIG_VGA_CONSOLE is not set -CONFIG_USB=y -CONFIG_USB_ANNOUNCE_NEW_DEVICES=y -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_ROOT_HUB_TT=y -CONFIG_USB_STORAGE=y -CONFIG_MMC=y -CONFIG_MMC_DEBUG=y -CONFIG_MMC_SPI=y -CONFIG_NEW_LEDS=y -CONFIG_LEDS_CLASS=y -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_M41T80=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_XFS_FS=y -CONFIG_XFS_QUOTA=y -CONFIG_XFS_POSIX_ACL=y -CONFIG_QUOTA=y -# CONFIG_PRINT_QUOTA_WARNING is not set -CONFIG_MSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_TMPFS=y -CONFIG_JFFS2_FS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_ASCII=y -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_ISO8859_15=y -CONFIG_NLS_UTF8=y -# CONFIG_FTRACE is not set -CONFIG_CRYPTO_CBC=y -CONFIG_CRYPTO_ECB=y -CONFIG_CRYPTO_ARC4=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set -# CONFIG_CRYPTO_HW is not set diff --git a/arch/mips/generic/Kconfig b/arch/mips/generic/Kconfig new file mode 100644 index 000000000000..a606b3f9196c --- /dev/null +++ b/arch/mips/generic/Kconfig @@ -0,0 +1,19 @@ +if MIPS_GENERIC + +config LEGACY_BOARDS + bool + help + Select this from your board if the board must use a legacy, non-UHI, + boot protocol. This will cause the kernel to scan through the list of + supported machines calling their detect functions in turn if the + kernel is booted without being provided with an FDT via the UHI + boot protocol. + +config LEGACY_BOARD_SEAD3 + bool "Support MIPS SEAD-3 boards" + select LEGACY_BOARDS + help + Enable this to include support for booting on MIPS SEAD-3 FPGA-based + development boards, which boot using a legacy boot protocol. + +endif diff --git a/arch/mips/generic/Makefile b/arch/mips/generic/Makefile new file mode 100644 index 000000000000..7c66494151db --- /dev/null +++ b/arch/mips/generic/Makefile @@ -0,0 +1,15 @@ +# +# Copyright (C) 2016 Imagination Technologies +# Author: Paul Burton <paul.burton@imgtec.com> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# + +obj-y += init.o +obj-y += irq.o +obj-y += proc.o + +obj-$(CONFIG_LEGACY_BOARD_SEAD3) += board-sead3.o diff --git a/arch/mips/generic/Platform b/arch/mips/generic/Platform new file mode 100644 index 000000000000..9a30d69e2281 --- /dev/null +++ b/arch/mips/generic/Platform @@ -0,0 +1,14 @@ +# +# Copyright (C) 2016 Imagination Technologies +# Author: Paul Burton <paul.burton@imgtec.com> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# + +platform-$(CONFIG_MIPS_GENERIC) += generic/ +cflags-$(CONFIG_MIPS_GENERIC) += -I$(srctree)/arch/mips/include/asm/mach-generic +load-$(CONFIG_MIPS_GENERIC) += 0xffffffff80100000 +all-$(CONFIG_MIPS_GENERIC) := vmlinux.gz.itb diff --git a/arch/mips/generic/board-sead3.c b/arch/mips/generic/board-sead3.c new file mode 100644 index 000000000000..f4ae0584a33b --- /dev/null +++ b/arch/mips/generic/board-sead3.c @@ -0,0 +1,376 @@ +/* + * Copyright (C) 2016 Imagination Technologies + * Author: Paul Burton <paul.burton@imgtec.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#define pr_fmt(fmt) "sead3: " fmt + +#include <linux/errno.h> +#include <linux/libfdt.h> +#include <linux/printk.h> + +#include <asm/fw/fw.h> +#include <asm/io.h> +#include <asm/machine.h> + +#define SEAD_CONFIG CKSEG1ADDR(0x1b100110) +#define SEAD_CONFIG_GIC_PRESENT BIT(1) + +#define MIPS_REVISION CKSEG1ADDR(0x1fc00010) +#define MIPS_REVISION_MACHINE (0xf << 4) +#define MIPS_REVISION_MACHINE_SEAD3 (0x4 << 4) + +static __init bool sead3_detect(void) +{ + uint32_t rev; + + rev = __raw_readl((void *)MIPS_REVISION); + return (rev & MIPS_REVISION_MACHINE) == MIPS_REVISION_MACHINE_SEAD3; +} + +static __init int append_cmdline(void *fdt) +{ + int err, chosen_off; + + /* find or add chosen node */ + chosen_off = fdt_path_offset(fdt, "/chosen"); + if (chosen_off == -FDT_ERR_NOTFOUND) + chosen_off = fdt_path_offset(fdt, "/chosen@0"); + if (chosen_off == -FDT_ERR_NOTFOUND) + chosen_off = fdt_add_subnode(fdt, 0, "chosen"); + if (chosen_off < 0) { + pr_err("Unable to find or add DT chosen node: %d\n", + chosen_off); + return chosen_off; + } + + err = fdt_setprop_string(fdt, chosen_off, "bootargs", fw_getcmdline()); + if (err) { + pr_err("Unable to set bootargs property: %d\n", err); + return err; + } + + return 0; +} + +static __init int append_memory(void *fdt) +{ + unsigned long phys_memsize, memsize; + __be32 mem_array[2]; + int err, mem_off; + char *var; + + /* find memory size from the bootloader environment */ + var = fw_getenv("memsize"); + if (var) { + err = kstrtoul(var, 0, &phys_memsize); + if (err) { + pr_err("Failed to read memsize env variable '%s'\n", + var); + return -EINVAL; + } + } else { + pr_warn("The bootloader didn't provide memsize: defaulting to 32MB\n"); + phys_memsize = 32 << 20; + } + + /* default to using all available RAM */ + memsize = phys_memsize; + + /* allow the user to override the usable memory */ + var = strstr(arcs_cmdline, "memsize="); + if (var) + memsize = memparse(var + strlen("memsize="), NULL); + + /* if the user says there's more RAM than we thought, believe them */ + phys_memsize = max_t(unsigned long, phys_memsize, memsize); + + /* find or add a memory node */ + mem_off = fdt_path_offset(fdt, "/memory"); + if (mem_off == -FDT_ERR_NOTFOUND) + mem_off = fdt_add_subnode(fdt, 0, "memory"); + if (mem_off < 0) { + pr_err("Unable to find or add memory DT node: %d\n", mem_off); + return mem_off; + } + + err = fdt_setprop_string(fdt, mem_off, "device_type", "memory"); + if (err) { + pr_err("Unable to set memory node device_type: %d\n", err); + return err; + } + + mem_array[0] = 0; + mem_array[1] = cpu_to_be32(phys_memsize); + err = fdt_setprop(fdt, mem_off, "reg", mem_array, sizeof(mem_array)); + if (err) { + pr_err("Unable to set memory regs property: %d\n", err); + return err; + } + + mem_array[0] = 0; + mem_array[1] = cpu_to_be32(memsize); + err = fdt_setprop(fdt, mem_off, "linux,usable-memory", + mem_array, sizeof(mem_array)); + if (err) { + pr_err("Unable to set linux,usable-memory property: %d\n", err); + return err; + } + + return 0; +} + +static __init int remove_gic(void *fdt) +{ + const unsigned int cpu_ehci_int = 2; + const unsigned int cpu_uart_int = 4; + const unsigned int cpu_eth_int = 6; + int gic_off, cpu_off, uart_off, eth_off, ehci_off, err; + uint32_t cfg, cpu_phandle; + + /* leave the GIC node intact if a GIC is present */ + cfg = __raw_readl((uint32_t *)SEAD_CONFIG); + if (cfg & SEAD_CONFIG_GIC_PRESENT) + return 0; + + gic_off = fdt_node_offset_by_compatible(fdt, -1, "mti,gic"); + if (gic_off < 0) { + pr_err("unable to find DT GIC node: %d\n", gic_off); + return gic_off; + } + + err = fdt_nop_node(fdt, gic_off); + if (err) { + pr_err("unable to nop GIC node\n"); + return err; + } + + cpu_off = fdt_node_offset_by_compatible(fdt, -1, + "mti,cpu-interrupt-controller"); + if (cpu_off < 0) { + pr_err("unable to find CPU intc node: %d\n", cpu_off); + return cpu_off; + } + + cpu_phandle = fdt_get_phandle(fdt, cpu_off); + if (!cpu_phandle) { + pr_err("unable to get CPU intc phandle\n"); + return -EINVAL; + } + + err = fdt_setprop_u32(fdt, 0, "interrupt-parent", cpu_phandle); + if (err) { + pr_err("unable to set root interrupt-parent: %d\n", err); + return err; + } + + uart_off = fdt_node_offset_by_compatible(fdt, -1, "ns16550a"); + while (uart_off >= 0) { + err = fdt_setprop_u32(fdt, uart_off, "interrupts", + cpu_uart_int); + if (err) { + pr_err("unable to set UART interrupts property: %d\n", + err); + return err; + } + + uart_off = fdt_node_offset_by_compatible(fdt, uart_off, + "ns16550a"); + } + if (uart_off != -FDT_ERR_NOTFOUND) { + pr_err("error searching for UART DT node: %d\n", uart_off); + return uart_off; + } + + eth_off = fdt_node_offset_by_compatible(fdt, -1, "smsc,lan9115"); + if (eth_off < 0) { + pr_err("unable to find ethernet DT node: %d\n", eth_off); + return eth_off; + } + + err = fdt_setprop_u32(fdt, eth_off, "interrupts", cpu_eth_int); + if (err) { + pr_err("unable to set ethernet interrupts property: %d\n", err); + return err; + } + + ehci_off = fdt_node_offset_by_compatible(fdt, -1, "generic-ehci"); + if (ehci_off < 0) { + pr_err("unable to find EHCI DT node: %d\n", ehci_off); + return ehci_off; + } + + err = fdt_setprop_u32(fdt, ehci_off, "interrupts", cpu_ehci_int); + if (err) { + pr_err("unable to set EHCI interrupts property: %d\n", err); + return err; + } + + return 0; +} + +static __init int serial_config(void *fdt) +{ + const char *yamontty, *mode_var; + char mode_var_name[9], path[18], parity; + unsigned int uart, baud, stop_bits; + bool hw_flow; + int chosen_off, err; + + yamontty = fw_getenv("yamontty"); + if (!yamontty || !strcmp(yamontty, "tty0")) { + uart = 0; + } else if (!strcmp(yamontty, "tty1")) { + uart = 1; + } else { + pr_warn("yamontty environment variable '%s' invalid\n", + yamontty); + uart = 0; + } + + baud = stop_bits = 0; + parity = 0; + hw_flow = false; + + snprintf(mode_var_name, sizeof(mode_var_name), "modetty%u", uart); + mode_var = fw_getenv(mode_var_name); + if (mode_var) { + while (mode_var[0] >= '0' && mode_var[0] <= '9') { + baud *= 10; + baud += mode_var[0] - '0'; + mode_var++; + } + if (mode_var[0] == ',') + mode_var++; + if (mode_var[0]) + parity = mode_var[0]; + if (mode_var[0] == ',') + mode_var++; + if (mode_var[0]) + stop_bits = mode_var[0] - '0'; + if (mode_var[0] == ',') + mode_var++; + if (!strcmp(mode_var, "hw")) + hw_flow = true; + } + + if (!baud) + baud = 38400; + + if (parity != 'e' && parity != 'n' && parity != 'o') + parity = 'n'; + + if (stop_bits != 7 && stop_bits != 8) + stop_bits = 8; + + WARN_ON(snprintf(path, sizeof(path), "uart%u:%u%c%u%s", + uart, baud, parity, stop_bits, + hw_flow ? "r" : "") >= sizeof(path)); + + /* find or add chosen node */ + chosen_off = fdt_path_offset(fdt, "/chosen"); + if (chosen_off == -FDT_ERR_NOTFOUND) + chosen_off = fdt_path_offset(fdt, "/chosen@0"); + if (chosen_off == -FDT_ERR_NOTFOUND) + chosen_off = fdt_add_subnode(fdt, 0, "chosen"); + if (chosen_off < 0) { + pr_err("Unable to find or add DT chosen node: %d\n", + chosen_off); + return chosen_off; + } + + err = fdt_setprop_string(fdt, chosen_off, "stdout-path", path); + if (err) { + pr_err("Unable to set stdout-path property: %d\n", err); + return err; + } + + return 0; +} + +static __init const void *sead3_fixup_fdt(const void *fdt, + const void *match_data) +{ + static unsigned char fdt_buf[16 << 10] __initdata; + int err; + + if (fdt_check_header(fdt)) + panic("Corrupt DT"); + + /* if this isn't SEAD3, something went wrong */ + BUG_ON(fdt_node_check_compatible(fdt, 0, "mti,sead-3")); + + fw_init_cmdline(); + + err = fdt_open_into(fdt, fdt_buf, sizeof(fdt_buf)); + if (err) + panic("Unable to open FDT: %d", err); + + err = append_cmdline(fdt_buf); + if (err) + panic("Unable to patch FDT: %d", err); + + err = append_memory(fdt_buf); + if (err) + panic("Unable to patch FDT: %d", err); + + err = remove_gic(fdt_buf); + if (err) + panic("Unable to patch FDT: %d", err); + + err = serial_config(fdt_buf); + if (err) + panic("Unable to patch FDT: %d", err); + + err = fdt_pack(fdt_buf); + if (err) + panic("Unable to pack FDT: %d\n", err); + + return fdt_buf; +} + +static __init unsigned int sead3_measure_hpt_freq(void) +{ + void __iomem *status_reg = (void __iomem *)0xbf000410; + unsigned int freq, orig, tick = 0; + unsigned long flags; + + local_irq_save(flags); + + orig = readl(status_reg) & 0x2; /* get original sample */ + /* wait for transition */ + while ((readl(status_reg) & 0x2) == orig) + ; + orig = orig ^ 0x2; /* flip the bit */ + + write_c0_count(0); + + /* wait 1 second (the sampling clock transitions every 10ms) */ + while (tick < 100) { + /* wait for transition */ + while ((readl(status_reg) & 0x2) == orig) + ; + orig = orig ^ 0x2; /* flip the bit */ + tick++; + } + + freq = read_c0_count(); + + local_irq_restore(flags); + + return freq; +} + +extern char __dtb_sead3_begin[]; + +MIPS_MACHINE(sead3) = { + .fdt = __dtb_sead3_begin, + .detect = sead3_detect, + .fixup_fdt = sead3_fixup_fdt, + .measure_hpt_freq = sead3_measure_hpt_freq, +}; diff --git a/arch/mips/generic/init.c b/arch/mips/generic/init.c new file mode 100644 index 000000000000..0ea73e845440 --- /dev/null +++ b/arch/mips/generic/init.c @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2016 Imagination Technologies + * Author: Paul Burton <paul.burton@imgtec.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/clocksource.h> +#include <linux/init.h> +#include <linux/irqchip.h> +#include <linux/of_fdt.h> +#include <linux/of_platform.h> + +#include <asm/fw/fw.h> +#include <asm/irq_cpu.h> +#include <asm/machine.h> +#include <asm/mips-cpc.h> +#include <asm/prom.h> +#include <asm/smp-ops.h> +#include <asm/time.h> + +static __initdata const void *fdt; +static __initdata const struct mips_machine *mach; +static __initdata const void *mach_match_data; + +void __init prom_init(void) +{ + const struct mips_machine *check_mach; + const struct of_device_id *match; + + if ((fw_arg0 == -2) && !fdt_check_header((void *)fw_arg1)) { + /* + * We booted using the UHI boot protocol, so we have been + * provided with the appropriate device tree for the board. + * Make use of it & search for any machine struct based upon + * the root compatible string. + */ + fdt = (void *)fw_arg1; + + for_each_mips_machine(check_mach) { + match = mips_machine_is_compatible(check_mach, fdt); + if (match) { + mach = check_mach; + mach_match_data = match->data; + break; + } + } + } else if (IS_ENABLED(CONFIG_LEGACY_BOARDS)) { + /* + * We weren't booted using the UHI boot protocol, but do + * support some number of boards with legacy boot protocols. + * Attempt to find the right one. + */ + for_each_mips_machine(check_mach) { + if (!check_mach->detect) + continue; + + if (!check_mach->detect()) + continue; + + mach = check_mach; + } + + /* + * If we don't recognise the machine then we can't continue, so + * die here. + */ + BUG_ON(!mach); + + /* Retrieve the machine's FDT */ + fdt = mach->fdt; + } + + BUG_ON(!fdt); +} + +void __init *plat_get_fdt(void) +{ + return (void *)fdt; +} + +void __init plat_mem_setup(void) +{ + if (mach && mach->fixup_fdt) + fdt = mach->fixup_fdt(fdt, mach_match_data); + + strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE); + __dt_setup_arch((void *)fdt); +} + +void __init device_tree_init(void) +{ + int err; + + unflatten_and_copy_device_tree(); + mips_cpc_probe(); + + err = register_cps_smp_ops(); + if (err) + err = register_up_smp_ops(); +} + +void __init plat_time_init(void) +{ + struct device_node *np; + struct clk *clk; + + of_clk_init(NULL); + + if (!cpu_has_counter) { + mips_hpt_frequency = 0; + } else if (mach && mach->measure_hpt_freq) { + mips_hpt_frequency = mach->measure_hpt_freq(); + } else { + np = of_get_cpu_node(0, NULL); + if (!np) { + pr_err("Failed to get CPU node\n"); + return; + } + + clk = of_clk_get(np, 0); + if (IS_ERR(clk)) { + pr_err("Failed to get CPU clock: %ld\n", PTR_ERR(clk)); + return; + } + + mips_hpt_frequency = clk_get_rate(clk); + clk_put(clk); + + switch (boot_cpu_type()) { + case CPU_20KC: + case CPU_25KF: + /* The counter runs at the CPU clock rate */ + break; + default: + /* The counter runs at half the CPU clock rate */ + mips_hpt_frequency /= 2; + break; + } + } + + clocksource_probe(); +} + +void __init arch_init_irq(void) +{ + struct device_node *intc_node; + + intc_node = of_find_compatible_node(NULL, NULL, + "mti,cpu-interrupt-controller"); + if (!cpu_has_veic && !intc_node) + mips_cpu_irq_init(); + + irqchip_init(); +} + +static int __init publish_devices(void) +{ + if (!of_have_populated_dt()) + panic("Device-tree not present"); + + if (of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL)) + panic("Failed to populate DT"); + + return 0; +} +arch_initcall(publish_devices); + +void __init prom_free_prom_memory(void) +{ +} diff --git a/arch/mips/generic/irq.c b/arch/mips/generic/irq.c new file mode 100644 index 000000000000..14064bdd91dd --- /dev/null +++ b/arch/mips/generic/irq.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2016 Imagination Technologies + * Author: Paul Burton <paul.burton@imgtec.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/clocksource.h> +#include <linux/init.h> +#include <linux/irqchip/mips-gic.h> +#include <linux/types.h> + +#include <asm/irq.h> + +int get_c0_fdc_int(void) +{ + int mips_cpu_fdc_irq; + + if (cpu_has_veic) + panic("Unimplemented!"); + else if (gic_present) + mips_cpu_fdc_irq = gic_get_c0_fdc_int(); + else if (cp0_fdc_irq >= 0) + mips_cpu_fdc_irq = MIPS_CPU_IRQ_BASE + cp0_fdc_irq; + else + mips_cpu_fdc_irq = -1; + + return mips_cpu_fdc_irq; +} + +int get_c0_perfcount_int(void) +{ + int mips_cpu_perf_irq; + + if (cpu_has_veic) + panic("Unimplemented!"); + else if (gic_present) + mips_cpu_perf_irq = gic_get_c0_perfcount_int(); + else if (cp0_perfcount_irq >= 0) + mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; + else + mips_cpu_perf_irq = -1; + + return mips_cpu_perf_irq; +} + +unsigned int get_c0_compare_int(void) +{ + int mips_cpu_timer_irq; + + if (cpu_has_veic) + panic("Unimplemented!"); + else if (gic_present) + mips_cpu_timer_irq = gic_get_c0_compare_int(); + else + mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; + + return mips_cpu_timer_irq; +} diff --git a/arch/mips/generic/proc.c b/arch/mips/generic/proc.c new file mode 100644 index 000000000000..42b33250a4a2 --- /dev/null +++ b/arch/mips/generic/proc.c @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2016 Imagination Technologies + * Author: Paul Burton <paul.burton@imgtec.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/of.h> + +#include <asm/bootinfo.h> + +const char *get_system_type(void) +{ + const char *str; + int err; + + err = of_property_read_string(of_root, "model", &str); + if (!err) + return str; + + err = of_property_read_string_index(of_root, "compatible", 0, &str); + if (!err) + return str; + + return "Unknown"; +} diff --git a/arch/mips/generic/vmlinux.its.S b/arch/mips/generic/vmlinux.its.S new file mode 100644 index 000000000000..f67fbf1c8541 --- /dev/null +++ b/arch/mips/generic/vmlinux.its.S @@ -0,0 +1,31 @@ +/dts-v1/; + +/ { + description = KERNEL_NAME; + #address-cells = <ADDR_CELLS>; + + images { + kernel@0 { + description = KERNEL_NAME; + data = /incbin/(VMLINUX_BINARY); + type = "kernel"; + arch = "mips"; + os = "linux"; + compression = VMLINUX_COMPRESSION; + load = /bits/ ADDR_BITS <VMLINUX_LOAD_ADDRESS>; + entry = /bits/ ADDR_BITS <VMLINUX_ENTRY_ADDRESS>; + hash@0 { + algo = "sha1"; + }; + }; + }; + + configurations { + default = "conf@default"; + + conf@default { + description = "Generic Linux kernel"; + kernel = "kernel@0"; + }; + }; +}; diff --git a/arch/mips/include/asm/addrspace.h b/arch/mips/include/asm/addrspace.h index c5b04e752e97..4856adc8906e 100644 --- a/arch/mips/include/asm/addrspace.h +++ b/arch/mips/include/asm/addrspace.h @@ -126,8 +126,7 @@ #define PHYS_TO_XKSEG_UNCACHED(p) PHYS_TO_XKPHYS(K_CALG_UNCACHED, (p)) #define PHYS_TO_XKSEG_CACHED(p) PHYS_TO_XKPHYS(K_CALG_COH_SHAREABLE, (p)) #define XKPHYS_TO_PHYS(p) ((p) & TO_PHYS_MASK) -#define PHYS_TO_XKPHYS(cm, a) (_CONST64_(0x8000000000000000) | \ - (_CONST64_(cm) << 59) | (a)) +#define PHYS_TO_XKPHYS(cm, a) (XKPHYS | (_ACAST64_(cm) << 59) | (a)) /* * The ultimate limited of the 64-bit MIPS architecture: 2 bits for selecting diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h index d296633d890e..a5eb1bb199a7 100644 --- a/arch/mips/include/asm/barrier.h +++ b/arch/mips/include/asm/barrier.h @@ -10,6 +10,102 @@ #include <asm/addrspace.h> +/* + * Sync types defined by the MIPS architecture (document MD00087 table 6.5) + * These values are used with the sync instruction to perform memory barriers. + * Types of ordering guarantees available through the SYNC instruction: + * - Completion Barriers + * - Ordering Barriers + * As compared to the completion barrier, the ordering barrier is a + * lighter-weight operation as it does not require the specified instructions + * before the SYNC to be already completed. Instead it only requires that those + * specified instructions which are subsequent to the SYNC in the instruction + * stream are never re-ordered for processing ahead of the specified + * instructions which are before the SYNC in the instruction stream. + * This potentially reduces how many cycles the barrier instruction must stall + * before it completes. + * Implementations that do not use any of the non-zero values of stype to define + * different barriers, such as ordering barriers, must make those stype values + * act the same as stype zero. + */ + +/* + * Completion barriers: + * - Every synchronizable specified memory instruction (loads or stores or both) + * that occurs in the instruction stream before the SYNC instruction must be + * already globally performed before any synchronizable specified memory + * instructions that occur after the SYNC are allowed to be performed, with + * respect to any other processor or coherent I/O module. + * + * - The barrier does not guarantee the order in which instruction fetches are + * performed. + * + * - A stype value of zero will always be defined such that it performs the most + * complete set of synchronization operations that are defined.This means + * stype zero always does a completion barrier that affects both loads and + * stores preceding the SYNC instruction and both loads and stores that are + * subsequent to the SYNC instruction. Non-zero values of stype may be defined + * by the architecture or specific implementations to perform synchronization + * behaviors that are less complete than that of stype zero. If an + * implementation does not use one of these non-zero values to define a + * different synchronization behavior, then that non-zero value of stype must + * act the same as stype zero completion barrier. This allows software written + * for an implementation with a lighter-weight barrier to work on another + * implementation which only implements the stype zero completion barrier. + * + * - A completion barrier is required, potentially in conjunction with SSNOP (in + * Release 1 of the Architecture) or EHB (in Release 2 of the Architecture), + * to guarantee that memory reference results are visible across operating + * mode changes. For example, a completion barrier is required on some + * implementations on entry to and exit from Debug Mode to guarantee that + * memory effects are handled correctly. + */ + +/* + * stype 0 - A completion barrier that affects preceding loads and stores and + * subsequent loads and stores. + * Older instructions which must reach the load/store ordering point before the + * SYNC instruction completes: Loads, Stores + * Younger instructions which must reach the load/store ordering point only + * after the SYNC instruction completes: Loads, Stores + * Older instructions which must be globally performed when the SYNC instruction + * completes: Loads, Stores + */ +#define STYPE_SYNC 0x0 + +/* + * Ordering barriers: + * - Every synchronizable specified memory instruction (loads or stores or both) + * that occurs in the instruction stream before the SYNC instruction must + * reach a stage in the load/store datapath after which no instruction + * re-ordering is possible before any synchronizable specified memory + * instruction which occurs after the SYNC instruction in the instruction + * stream reaches the same stage in the load/store datapath. + * + * - If any memory instruction before the SYNC instruction in program order, + * generates a memory request to the external memory and any memory + * instruction after the SYNC instruction in program order also generates a + * memory request to external memory, the memory request belonging to the + * older instruction must be globally performed before the time the memory + * request belonging to the younger instruction is globally performed. + * + * - The barrier does not guarantee the order in which instruction fetches are + * performed. + */ + +/* + * stype 0x10 - An ordering barrier that affects preceding loads and stores and + * subsequent loads and stores. + * Older instructions which must reach the load/store ordering point before the + * SYNC instruction completes: Loads, Stores + * Younger instructions which must reach the load/store ordering point only + * after the SYNC instruction completes: Loads, Stores + * Older instructions which must be globally performed when the SYNC instruction + * completes: N/A + */ +#define STYPE_SYNC_MB 0x10 + + #ifdef CONFIG_CPU_HAS_SYNC #define __sync() \ __asm__ __volatile__( \ diff --git a/arch/mips/include/asm/cacheflush.h b/arch/mips/include/asm/cacheflush.h index 34ed22ec6c33..4812d1fed0c2 100644 --- a/arch/mips/include/asm/cacheflush.h +++ b/arch/mips/include/asm/cacheflush.h @@ -28,6 +28,7 @@ * - flush_cache_sigtramp() flush signal trampoline * - flush_icache_all() flush the entire instruction cache * - flush_data_cache_page() flushes a page from the data cache + * - __flush_icache_user_range(start, end) flushes range of user instructions */ /* @@ -80,6 +81,10 @@ static inline void flush_icache_page(struct vm_area_struct *vma, extern void (*flush_icache_range)(unsigned long start, unsigned long end); extern void (*local_flush_icache_range)(unsigned long start, unsigned long end); +extern void (*__flush_icache_user_range)(unsigned long start, + unsigned long end); +extern void (*__local_flush_icache_user_range)(unsigned long start, + unsigned long end); extern void (*__flush_cache_vmap)(void); diff --git a/arch/mips/include/asm/cpu-type.h b/arch/mips/include/asm/cpu-type.h index fbe1881f28fc..bdd6dc18e65c 100644 --- a/arch/mips/include/asm/cpu-type.h +++ b/arch/mips/include/asm/cpu-type.h @@ -24,7 +24,8 @@ static inline int __pure __get_cpu_type(const int cpu_type) case CPU_LOONGSON3: #endif -#ifdef CONFIG_SYS_HAS_CPU_LOONGSON1B +#if defined(CONFIG_SYS_HAS_CPU_LOONGSON1B) || \ + defined(CONFIG_SYS_HAS_CPU_LOONGSON1C) case CPU_LOONGSON1: #endif diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index f672df8b26d0..9a8372484edc 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h @@ -240,6 +240,7 @@ #define PRID_REV_VR4130 0x0080 #define PRID_REV_34K_V1_0_2 0x0022 #define PRID_REV_LOONGSON1B 0x0020 +#define PRID_REV_LOONGSON1C 0x0020 /* Same as Loongson-1B */ #define PRID_REV_LOONGSON2E 0x0002 #define PRID_REV_LOONGSON2F 0x0003 #define PRID_REV_LOONGSON3A_R1 0x0005 diff --git a/arch/mips/include/asm/device.h b/arch/mips/include/asm/device.h index c94fafba9e62..21c2082a0dfb 100644 --- a/arch/mips/include/asm/device.h +++ b/arch/mips/include/asm/device.h @@ -11,6 +11,11 @@ struct dma_map_ops; struct dev_archdata { /* DMA operations on that device */ struct dma_map_ops *dma_ops; + +#ifdef CONFIG_DMA_PERDEV_COHERENT + /* Non-zero if DMA is coherent with CPU caches */ + bool dma_coherent; +#endif }; struct pdev_archdata { diff --git a/arch/mips/include/asm/dma-coherence.h b/arch/mips/include/asm/dma-coherence.h index bc5e85d579e6..72d0eab02afc 100644 --- a/arch/mips/include/asm/dma-coherence.h +++ b/arch/mips/include/asm/dma-coherence.h @@ -9,14 +9,22 @@ #ifndef __ASM_DMA_COHERENCE_H #define __ASM_DMA_COHERENCE_H -#ifdef CONFIG_DMA_MAYBE_COHERENT -extern int coherentio; +enum coherent_io_user_state { + IO_COHERENCE_DEFAULT, + IO_COHERENCE_ENABLED, + IO_COHERENCE_DISABLED, +}; + +#if defined(CONFIG_DMA_PERDEV_COHERENT) +/* Don't provide (hw_)coherentio to avoid misuse */ +#elif defined(CONFIG_DMA_MAYBE_COHERENT) +extern enum coherent_io_user_state coherentio; extern int hw_coherentio; #else #ifdef CONFIG_DMA_COHERENT -#define coherentio 1 +#define coherentio IO_COHERENCE_ENABLED #else -#define coherentio 0 +#define coherentio IO_COHERENCE_DISABLED #endif #define hw_coherentio 0 #endif /* CONFIG_DMA_MAYBE_COHERENT */ diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h index 12fa79e2f1b4..7aa71b9b0258 100644 --- a/arch/mips/include/asm/dma-mapping.h +++ b/arch/mips/include/asm/dma-mapping.h @@ -32,4 +32,14 @@ static inline void dma_mark_clean(void *addr, size_t size) {} extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction); +#define arch_setup_dma_ops arch_setup_dma_ops +static inline void arch_setup_dma_ops(struct device *dev, u64 dma_base, + u64 size, const struct iommu_ops *iommu, + bool coherent) +{ +#ifdef CONFIG_DMA_PERDEV_COHERENT + dev->archdata.dma_coherent = coherent; +#endif +} + #endif /* _ASM_DMA_MAPPING_H */ diff --git a/arch/mips/include/asm/i8259.h b/arch/mips/include/asm/i8259.h index a7fbcd6ed13c..32229c77906a 100644 --- a/arch/mips/include/asm/i8259.h +++ b/arch/mips/include/asm/i8259.h @@ -37,12 +37,22 @@ extern raw_spinlock_t i8259A_lock; -extern int i8259A_irq_pending(unsigned int irq); extern void make_8259A_irq(unsigned int irq); extern void init_i8259_irqs(void); extern int i8259_of_init(struct device_node *node, struct device_node *parent); +/** + * i8159_set_poll() - Override the i8259 polling function + * @poll: pointer to platform-specific polling function + * + * Call this to override the generic i8259 polling function, which directly + * accesses i8259 registers, with a platform specific one which may be faster + * in cases where hardware provides a more optimal means of polling for an + * interrupt. + */ +extern void i8259_set_poll(int (*poll)(void)); + /* * Do the traditional i8259 interrupt polling thing. This is for the few * cases where no better interrupt acknowledge method is available and we diff --git a/arch/mips/include/asm/mach-generic/dma-coherence.h b/arch/mips/include/asm/mach-generic/dma-coherence.h index 0f8a354fd468..61addb1677e9 100644 --- a/arch/mips/include/asm/mach-generic/dma-coherence.h +++ b/arch/mips/include/asm/mach-generic/dma-coherence.h @@ -49,7 +49,19 @@ static inline int plat_dma_supported(struct device *dev, u64 mask) static inline int plat_device_is_coherent(struct device *dev) { - return coherentio; +#ifdef CONFIG_DMA_PERDEV_COHERENT + return dev->archdata.dma_coherent; +#else + switch (coherentio) { + default: + case IO_COHERENCE_DEFAULT: + return hw_coherentio; + case IO_COHERENCE_ENABLED: + return 1; + case IO_COHERENCE_DISABLED: + return 0; + } +#endif } #ifndef plat_post_dma_flush diff --git a/arch/mips/include/asm/mach-generic/floppy.h b/arch/mips/include/asm/mach-generic/floppy.h index e2561d99a3fe..9ec2f6a5200b 100644 --- a/arch/mips/include/asm/mach-generic/floppy.h +++ b/arch/mips/include/asm/mach-generic/floppy.h @@ -115,11 +115,7 @@ static inline unsigned long fd_getfdaddr1(void) static inline unsigned long fd_dma_mem_alloc(unsigned long size) { - unsigned long mem; - - mem = __get_dma_pages(GFP_KERNEL, get_order(size)); - - return mem; + return __get_dma_pages(GFP_KERNEL, get_order(size)); } static inline void fd_dma_mem_free(unsigned long addr, unsigned long size) diff --git a/arch/mips/include/asm/mach-generic/spaces.h b/arch/mips/include/asm/mach-generic/spaces.h index afc96ecb9004..952b0fdfda0e 100644 --- a/arch/mips/include/asm/mach-generic/spaces.h +++ b/arch/mips/include/asm/mach-generic/spaces.h @@ -12,6 +12,8 @@ #include <linux/const.h> +#include <asm/mipsregs.h> + /* * This gives the physical RAM offset. */ @@ -52,11 +54,7 @@ #ifdef CONFIG_64BIT #ifndef CAC_BASE -#ifdef CONFIG_DMA_NONCOHERENT -#define CAC_BASE _AC(0x9800000000000000, UL) -#else -#define CAC_BASE _AC(0xa800000000000000, UL) -#endif +#define CAC_BASE PHYS_TO_XKPHYS(read_c0_config() & CONF_CM_CMASK, 0) #endif #ifndef IO_BASE diff --git a/arch/mips/include/asm/mach-ip27/spaces.h b/arch/mips/include/asm/mach-ip27/spaces.h index b18802a0b17e..4775a1136a5b 100644 --- a/arch/mips/include/asm/mach-ip27/spaces.h +++ b/arch/mips/include/asm/mach-ip27/spaces.h @@ -19,6 +19,7 @@ #define IO_BASE 0x9200000000000000 #define MSPEC_BASE 0x9400000000000000 #define UNCAC_BASE 0x9600000000000000 +#define CAC_BASE 0xa800000000000000 #define TO_MSPEC(x) (MSPEC_BASE | ((x) & TO_PHYS_MASK)) #define TO_HSPEC(x) (HSPEC_BASE | ((x) & TO_PHYS_MASK)) diff --git a/arch/mips/include/asm/mach-loongson32/irq.h b/arch/mips/include/asm/mach-loongson32/irq.h index c1c744197de4..8c01b304b7ec 100644 --- a/arch/mips/include/asm/mach-loongson32/irq.h +++ b/arch/mips/include/asm/mach-loongson32/irq.h @@ -36,9 +36,14 @@ #define LS1X_IRQ(n, x) (LS1X_IRQ_BASE + (n << 5) + (x)) #define LS1X_UART0_IRQ LS1X_IRQ(0, 2) +#if defined(CONFIG_LOONGSON1_LS1B) #define LS1X_UART1_IRQ LS1X_IRQ(0, 3) #define LS1X_UART2_IRQ LS1X_IRQ(0, 4) #define LS1X_UART3_IRQ LS1X_IRQ(0, 5) +#elif defined(CONFIG_LOONGSON1_LS1C) +#define LS1X_UART1_IRQ LS1X_IRQ(0, 4) +#define LS1X_UART2_IRQ LS1X_IRQ(0, 5) +#endif #define LS1X_CAN0_IRQ LS1X_IRQ(0, 6) #define LS1X_CAN1_IRQ LS1X_IRQ(0, 7) #define LS1X_SPI0_IRQ LS1X_IRQ(0, 8) @@ -47,6 +52,9 @@ #define LS1X_DMA0_IRQ LS1X_IRQ(0, 13) #define LS1X_DMA1_IRQ LS1X_IRQ(0, 14) #define LS1X_DMA2_IRQ LS1X_IRQ(0, 15) +#if defined(CONFIG_LOONGSON1_LS1C) +#define LS1X_NAND_IRQ LS1X_IRQ(0, 16) +#endif #define LS1X_PWM0_IRQ LS1X_IRQ(0, 17) #define LS1X_PWM1_IRQ LS1X_IRQ(0, 18) #define LS1X_PWM2_IRQ LS1X_IRQ(0, 19) @@ -54,18 +62,49 @@ #define LS1X_RTC_INT0_IRQ LS1X_IRQ(0, 21) #define LS1X_RTC_INT1_IRQ LS1X_IRQ(0, 22) #define LS1X_RTC_INT2_IRQ LS1X_IRQ(0, 23) +#if defined(CONFIG_LOONGSON1_LS1B) #define LS1X_TOY_INT0_IRQ LS1X_IRQ(0, 24) #define LS1X_TOY_INT1_IRQ LS1X_IRQ(0, 25) #define LS1X_TOY_INT2_IRQ LS1X_IRQ(0, 26) #define LS1X_RTC_TICK_IRQ LS1X_IRQ(0, 27) #define LS1X_TOY_TICK_IRQ LS1X_IRQ(0, 28) +#define LS1X_UART4_IRQ LS1X_IRQ(0, 29) +#define LS1X_UART5_IRQ LS1X_IRQ(0, 30) +#elif defined(CONFIG_LOONGSON1_LS1C) +#define LS1X_UART3_IRQ LS1X_IRQ(0, 29) +#define LS1X_ADC_IRQ LS1X_IRQ(0, 30) +#define LS1X_SDIO_IRQ LS1X_IRQ(0, 31) +#endif #define LS1X_EHCI_IRQ LS1X_IRQ(1, 0) #define LS1X_OHCI_IRQ LS1X_IRQ(1, 1) +#if defined(CONFIG_LOONGSON1_LS1B) #define LS1X_GMAC0_IRQ LS1X_IRQ(1, 2) #define LS1X_GMAC1_IRQ LS1X_IRQ(1, 3) +#elif defined(CONFIG_LOONGSON1_LS1C) +#define LS1X_OTG_IRQ LS1X_IRQ(1, 2) +#define LS1X_GMAC0_IRQ LS1X_IRQ(1, 3) +#define LS1X_CAM_IRQ LS1X_IRQ(1, 4) +#define LS1X_UART4_IRQ LS1X_IRQ(1, 5) +#define LS1X_UART5_IRQ LS1X_IRQ(1, 6) +#define LS1X_UART6_IRQ LS1X_IRQ(1, 7) +#define LS1X_UART7_IRQ LS1X_IRQ(1, 8) +#define LS1X_UART8_IRQ LS1X_IRQ(1, 9) +#define LS1X_UART9_IRQ LS1X_IRQ(1, 13) +#define LS1X_UART10_IRQ LS1X_IRQ(1, 14) +#define LS1X_UART11_IRQ LS1X_IRQ(1, 15) +#define LS1X_I2C0_IRQ LS1X_IRQ(1, 17) +#define LS1X_I2C1_IRQ LS1X_IRQ(1, 18) +#define LS1X_I2C2_IRQ LS1X_IRQ(1, 19) +#endif -#define LS1X_IRQS (LS1X_IRQ(4, 31) + 1 - LS1X_IRQ_BASE) +#if defined(CONFIG_LOONGSON1_LS1B) +#define INTN 4 +#elif defined(CONFIG_LOONGSON1_LS1C) +#define INTN 5 +#endif + +#define LS1X_IRQS (LS1X_IRQ(INTN, 31) + 1 - LS1X_IRQ_BASE) #define NR_IRQS (MIPS_CPU_IRQS + LS1X_IRQS) diff --git a/arch/mips/include/asm/mach-loongson32/loongson1.h b/arch/mips/include/asm/mach-loongson32/loongson1.h index 978f6df8970a..3584c40caf79 100644 --- a/arch/mips/include/asm/mach-loongson32/loongson1.h +++ b/arch/mips/include/asm/mach-loongson32/loongson1.h @@ -12,7 +12,11 @@ #ifndef __ASM_MACH_LOONGSON32_LOONGSON1_H #define __ASM_MACH_LOONGSON32_LOONGSON1_H +#if defined(CONFIG_LOONGSON1_LS1B) #define DEFAULT_MEMSIZE 256 /* If no memsize provided */ +#elif defined(CONFIG_LOONGSON1_LS1C) +#define DEFAULT_MEMSIZE 32 +#endif /* Loongson 1 Register Bases */ #define LS1X_MUX_BASE 0x1fd00420 @@ -20,6 +24,7 @@ #define LS1X_GPIO0_BASE 0x1fd010c0 #define LS1X_GPIO1_BASE 0x1fd010c4 #define LS1X_DMAC_BASE 0x1fd01160 +#define LS1X_CBUS_BASE 0x1fd011c0 #define LS1X_EHCI_BASE 0x1fe00000 #define LS1X_OHCI_BASE 0x1fe08000 #define LS1X_GMAC0_BASE 0x1fe10000 diff --git a/arch/mips/include/asm/mach-loongson32/platform.h b/arch/mips/include/asm/mach-loongson32/platform.h index 672531aa9bef..7adc31364939 100644 --- a/arch/mips/include/asm/mach-loongson32/platform.h +++ b/arch/mips/include/asm/mach-loongson32/platform.h @@ -30,5 +30,6 @@ void __init ls1x_clk_init(void); void __init ls1x_dma_set_platdata(struct plat_ls1x_dma *pdata); void __init ls1x_nand_set_platdata(struct plat_ls1x_nand *pdata); void __init ls1x_serial_set_uartclk(struct platform_device *pdev); +void __init ls1x_rtc_set_extclk(struct platform_device *pdev); #endif /* __ASM_MACH_LOONGSON32_PLATFORM_H */ diff --git a/arch/mips/include/asm/mach-loongson32/regs-clk.h b/arch/mips/include/asm/mach-loongson32/regs-clk.h index 4d56fc38f0c4..e5e8f118f34b 100644 --- a/arch/mips/include/asm/mach-loongson32/regs-clk.h +++ b/arch/mips/include/asm/mach-loongson32/regs-clk.h @@ -18,6 +18,7 @@ #define LS1X_CLK_PLL_FREQ LS1X_CLK_REG(0x0) #define LS1X_CLK_PLL_DIV LS1X_CLK_REG(0x4) +#if defined(CONFIG_LOONGSON1_LS1B) /* Clock PLL Divisor Register Bits */ #define DIV_DC_EN BIT(31) #define DIV_DC_RST BIT(30) @@ -48,4 +49,37 @@ #define BYPASS_DDR_WIDTH 1 #define BYPASS_CPU_WIDTH 1 +#elif defined(CONFIG_LOONGSON1_LS1C) +/* PLL/SDRAM Frequency configuration register Bits */ +#define PLL_VALID BIT(31) +#define FRAC_N GENMASK(23, 16) +#define RST_TIME GENMASK(3, 2) +#define SDRAM_DIV GENMASK(1, 0) + +/* CPU/CAMERA/DC Frequency configuration register Bits */ +#define DIV_DC_EN BIT(31) +#define DIV_DC GENMASK(30, 24) +#define DIV_CAM_EN BIT(23) +#define DIV_CAM GENMASK(22, 16) +#define DIV_CPU_EN BIT(15) +#define DIV_CPU GENMASK(14, 8) +#define DIV_DC_SEL_EN BIT(5) +#define DIV_DC_SEL BIT(4) +#define DIV_CAM_SEL_EN BIT(3) +#define DIV_CAM_SEL BIT(2) +#define DIV_CPU_SEL_EN BIT(1) +#define DIV_CPU_SEL BIT(0) + +#define DIV_DC_SHIFT 24 +#define DIV_CAM_SHIFT 16 +#define DIV_CPU_SHIFT 8 +#define DIV_DDR_SHIFT 0 + +#define DIV_DC_WIDTH 7 +#define DIV_CAM_WIDTH 7 +#define DIV_CPU_WIDTH 7 +#define DIV_DDR_WIDTH 2 + +#endif + #endif /* __ASM_MACH_LOONGSON32_REGS_CLK_H */ diff --git a/arch/mips/include/asm/mach-loongson32/regs-mux.h b/arch/mips/include/asm/mach-loongson32/regs-mux.h index 7c394f93cb9e..4a0bdeb0eb9b 100644 --- a/arch/mips/include/asm/mach-loongson32/regs-mux.h +++ b/arch/mips/include/asm/mach-loongson32/regs-mux.h @@ -18,6 +18,7 @@ #define LS1X_MUX_CTRL0 LS1X_MUX_REG(0x0) #define LS1X_MUX_CTRL1 LS1X_MUX_REG(0x4) +#if defined(CONFIG_LOONGSON1_LS1B) /* MUX CTRL0 Register Bits */ #define UART0_USE_PWM23 BIT(28) #define UART0_USE_PWM01 BIT(27) @@ -64,4 +65,64 @@ #define GMAC1_USE_PWM23 BIT(1) #define GMAC0_USE_PWM01 BIT(0) +#elif defined(CONFIG_LOONGSON1_LS1C) + +/* SHUT_CTRL Register Bits */ +#define UART_SPLIT GENMASK(31, 30) +#define OUTPUT_CLK GENMASK(29, 26) +#define ADC_SHUT BIT(25) +#define SDIO_SHUT BIT(24) +#define DMA2_SHUT BIT(23) +#define DMA1_SHUT BIT(22) +#define DMA0_SHUT BIT(21) +#define SPI1_SHUT BIT(20) +#define SPI0_SHUT BIT(19) +#define I2C2_SHUT BIT(18) +#define I2C1_SHUT BIT(17) +#define I2C0_SHUT BIT(16) +#define AC97_SHUT BIT(15) +#define I2S_SHUT BIT(14) +#define UART3_SHUT BIT(13) +#define UART2_SHUT BIT(12) +#define UART1_SHUT BIT(11) +#define UART0_SHUT BIT(10) +#define CAN1_SHUT BIT(9) +#define CAN0_SHUT BIT(8) +#define ECC_SHUT BIT(7) +#define GMAC_SHUT BIT(6) +#define USBHOST_SHUT BIT(5) +#define USBOTG_SHUT BIT(4) +#define SDRAM_SHUT BIT(3) +#define SRAM_SHUT BIT(2) +#define CAM_SHUT BIT(1) +#define LCD_SHUT BIT(0) + +#define UART_SPLIT_SHIFT 30 +#define OUTPUT_CLK_SHIFT 26 + +/* MISC_CTRL Register Bits */ +#define USBHOST_RSTN BIT(31) +#define PHY_INTF_SELI GENMASK(30, 28) +#define AC97_EN BIT(25) +#define SDIO_DMA_EN GENMASK(24, 23) +#define ADC_DMA_EN BIT(22) +#define SDIO_USE_SPI1 BIT(17) +#define SDIO_USE_SPI0 BIT(16) +#define SRAM_CTRL GENMASK(15, 0) + +#define PHY_INTF_SELI_SHIFT 28 +#define SDIO_DMA_EN_SHIFT 23 +#define SRAM_CTRL_SHIFT 0 + +#define LS1X_CBUS_REG(n, x) \ + ((void __iomem *)KSEG1ADDR(LS1X_CBUS_BASE + (n * 0x04) + (x))) + +#define LS1X_CBUS_FIRST(n) LS1X_CBUS_REG(n, 0x00) +#define LS1X_CBUS_SECOND(n) LS1X_CBUS_REG(n, 0x10) +#define LS1X_CBUS_THIRD(n) LS1X_CBUS_REG(n, 0x20) +#define LS1X_CBUS_FOURTHT(n) LS1X_CBUS_REG(n, 0x30) +#define LS1X_CBUS_FIFTHT(n) LS1X_CBUS_REG(n, 0x40) + +#endif + #endif /* __ASM_MACH_LOONGSON32_REGS_MUX_H */ diff --git a/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h b/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h deleted file mode 100644 index bfbd7035d4c5..000000000000 --- a/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2003, 2004 Chris Dearman - * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org) - */ -#ifndef __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H -#define __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H - - -/* - * CPU feature overrides for MIPS boards - */ -#ifdef CONFIG_CPU_MIPS32 -#define cpu_has_tlb 1 -#define cpu_has_4kex 1 -#define cpu_has_4k_cache 1 -/* #define cpu_has_fpu ? */ -/* #define cpu_has_32fpr ? */ -#define cpu_has_counter 1 -/* #define cpu_has_watch ? */ -#define cpu_has_divec 1 -#define cpu_has_vce 0 -/* #define cpu_has_cache_cdex_p ? */ -/* #define cpu_has_cache_cdex_s ? */ -/* #define cpu_has_prefetch ? */ -#define cpu_has_mcheck 1 -/* #define cpu_has_ejtag ? */ -#ifdef CONFIG_CPU_MICROMIPS -#define cpu_has_llsc 0 -#else -#define cpu_has_llsc 1 -#endif -/* #define cpu_has_vtag_icache ? */ -/* #define cpu_has_dc_aliases ? */ -/* #define cpu_has_ic_fills_f_dc ? */ -#define cpu_has_nofpuex 0 -/* #define cpu_has_64bits ? */ -/* #define cpu_has_64bit_zero_reg ? */ -/* #define cpu_has_inclusive_pcaches ? */ -#define cpu_icache_snoops_remote_store 1 -#endif - -#ifdef CONFIG_CPU_MIPS64 -#define cpu_has_tlb 1 -#define cpu_has_4kex 1 -#define cpu_has_4k_cache 1 -/* #define cpu_has_fpu ? */ -/* #define cpu_has_32fpr ? */ -#define cpu_has_counter 1 -/* #define cpu_has_watch ? */ -#define cpu_has_divec 1 -#define cpu_has_vce 0 -/* #define cpu_has_cache_cdex_p ? */ -/* #define cpu_has_cache_cdex_s ? */ -/* #define cpu_has_prefetch ? */ -#define cpu_has_mcheck 1 -/* #define cpu_has_ejtag ? */ -#define cpu_has_llsc 1 -/* #define cpu_has_vtag_icache ? */ -/* #define cpu_has_dc_aliases ? */ -/* #define cpu_has_ic_fills_f_dc ? */ -#define cpu_has_nofpuex 0 -/* #define cpu_has_64bits ? */ -/* #define cpu_has_64bit_zero_reg ? */ -/* #define cpu_has_inclusive_pcaches ? */ -#define cpu_icache_snoops_remote_store 1 -#endif - -#endif /* __ASM_MACH_MIPS_CPU_FEATURE_OVERRIDES_H */ diff --git a/arch/mips/include/asm/mach-sead3/irq.h b/arch/mips/include/asm/mach-sead3/irq.h deleted file mode 100644 index 5d154cfbcf4c..000000000000 --- a/arch/mips/include/asm/mach-sead3/irq.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __ASM_MACH_MIPS_IRQ_H -#define __ASM_MACH_MIPS_IRQ_H - -#define NR_IRQS 256 - - -#include_next <irq.h> - -#endif /* __ASM_MACH_MIPS_IRQ_H */ diff --git a/arch/mips/include/asm/mach-sead3/kernel-entry-init.h b/arch/mips/include/asm/mach-sead3/kernel-entry-init.h deleted file mode 100644 index 6cccd4d558d7..000000000000 --- a/arch/mips/include/asm/mach-sead3/kernel-entry-init.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Chris Dearman (chris@mips.com) - * Copyright (C) 2007 Mips Technologies, Inc. - */ -#ifndef __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H -#define __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H - - .macro kernel_entry_setup - .endm - -/* - * Do SMP slave processor setup necessary before we can safely execute C code. - */ - .macro smp_slave_setup - .endm - -#endif /* __ASM_MACH_MIPS_KERNEL_ENTRY_INIT_H */ diff --git a/arch/mips/include/asm/mach-sead3/war.h b/arch/mips/include/asm/mach-sead3/war.h deleted file mode 100644 index d068fc411f47..000000000000 --- a/arch/mips/include/asm/mach-sead3/war.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org> - */ -#ifndef __ASM_MIPS_MACH_MIPS_WAR_H -#define __ASM_MIPS_MACH_MIPS_WAR_H - -#define R4600_V1_INDEX_ICACHEOP_WAR 0 -#define R4600_V1_HIT_CACHEOP_WAR 0 -#define R4600_V2_HIT_CACHEOP_WAR 0 -#define R5432_CP0_INTERRUPT_WAR 0 -#define BCM1250_M3_WAR 0 -#define SIBYTE_1956_WAR 0 -#define MIPS4K_ICACHE_REFILL_WAR 1 -#define MIPS_CACHE_SYNC_WAR 1 -#define TX49XX_ICACHE_INDEX_INV_WAR 0 -#define ICACHE_REFILLS_WORKAROUND_WAR 1 -#define R10000_LLSC_WAR 0 -#define MIPS34K_MISSED_ITLB_WAR 0 - -#endif /* __ASM_MIPS_MACH_MIPS_WAR_H */ diff --git a/arch/mips/include/asm/machine.h b/arch/mips/include/asm/machine.h new file mode 100644 index 000000000000..6b444cd9526f --- /dev/null +++ b/arch/mips/include/asm/machine.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2016 Imagination Technologies + * Author: Paul Burton <paul.burton@imgtec.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __MIPS_ASM_MACHINE_H__ +#define __MIPS_ASM_MACHINE_H__ + +#include <linux/libfdt.h> +#include <linux/of.h> + +struct mips_machine { + const struct of_device_id *matches; + const void *fdt; + bool (*detect)(void); + const void *(*fixup_fdt)(const void *fdt, const void *match_data); + unsigned int (*measure_hpt_freq)(void); +}; + +extern long __mips_machines_start; +extern long __mips_machines_end; + +#define MIPS_MACHINE(name) \ + static const struct mips_machine __mips_mach_##name \ + __used __section(.mips.machines.init) + +#define for_each_mips_machine(mach) \ + for ((mach) = (struct mips_machine *)&__mips_machines_start; \ + (mach) < (struct mips_machine *)&__mips_machines_end; \ + (mach)++) + +/** + * mips_machine_is_compatible() - check if a machine is compatible with an FDT + * @mach: the machine struct to check + * @fdt: the FDT to check for compatibility with + * + * Check whether the given machine @mach is compatible with the given flattened + * device tree @fdt, based upon the compatibility property of the root node. + * + * Return: the device id matched if any, else NULL + */ +static inline const struct of_device_id * +mips_machine_is_compatible(const struct mips_machine *mach, const void *fdt) +{ + const struct of_device_id *match; + + if (!mach->matches) + return NULL; + + for (match = mach->matches; match->compatible; match++) { + if (fdt_node_check_compatible(fdt, 0, match->compatible) == 0) + return match; + } + + return NULL; +} + +#endif /* __MIPS_ASM_MACHINE_H__ */ diff --git a/arch/mips/include/asm/mips-boards/sead3int.h b/arch/mips/include/asm/mips-boards/sead3int.h deleted file mode 100644 index 8932c7de0419..000000000000 --- a/arch/mips/include/asm/mips-boards/sead3int.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000,2012 MIPS Technologies, Inc. All rights reserved. - * Douglas Leung <douglas@mips.com> - * Steven J. Hill <sjhill@mips.com> - */ -#ifndef _MIPS_SEAD3INT_H -#define _MIPS_SEAD3INT_H - -#include <linux/irqchip/mips-gic.h> - -/* SEAD-3 GIC address space definitions. */ -#define GIC_BASE_ADDR 0x1b1c0000 -#define GIC_ADDRSPACE_SZ (128 * 1024) - -/* CPU interrupt offsets */ -#define CPU_INT_GIC 2 -#define CPU_INT_EHCI 2 -#define CPU_INT_UART0 4 -#define CPU_INT_UART1 4 -#define CPU_INT_NET 6 - -/* GIC interrupt offsets */ -#define GIC_INT_NET GIC_SHARED_TO_HWIRQ(0) -#define GIC_INT_UART1 GIC_SHARED_TO_HWIRQ(2) -#define GIC_INT_UART0 GIC_SHARED_TO_HWIRQ(3) -#define GIC_INT_EHCI GIC_SHARED_TO_HWIRQ(5) - -#endif /* !(_MIPS_SEAD3INT_H) */ diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h index 4fafeefe65c2..2e4180797b21 100644 --- a/arch/mips/include/asm/mips-cm.h +++ b/arch/mips/include/asm/mips-cm.h @@ -359,6 +359,7 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80) /* GCR_Cx_COHERENCE register fields */ #define CM_GCR_Cx_COHERENCE_COHDOMAINEN_SHF 0 #define CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK (_ULCAST_(0xff) << 0) +#define CM3_GCR_Cx_COHERENCE_COHEN_MSK (_ULCAST_(0x1) << 0) /* GCR_Cx_CONFIG register fields */ #define CM_GCR_Cx_CONFIG_IOCUTYPE_SHF 10 diff --git a/arch/mips/include/asm/octeon/cvmx-helper-board.h b/arch/mips/include/asm/octeon/cvmx-helper-board.h index cda93aee712c..b4d19c21b62c 100644 --- a/arch/mips/include/asm/octeon/cvmx-helper-board.h +++ b/arch/mips/include/asm/octeon/cvmx-helper-board.h @@ -58,16 +58,6 @@ typedef enum { #define CVMX_HELPER_BOARD_MGMT_IPD_PORT -10 /** - * cvmx_override_board_link_get(int ipd_port) is a function - * pointer. It is meant to allow customization of the process of - * talking to a PHY to determine link speed. It is called every - * time a PHY must be polled for link status. Users should set - * this pointer to a function before calling any cvmx-helper - * operations. - */ -extern cvmx_helper_link_info_t(*cvmx_override_board_link_get) (int ipd_port); - -/** * Return the MII PHY address associated with the given IPD * port. A result of -1 means there isn't a MII capable PHY * connected to this port. On chips supporting multiple MII @@ -86,26 +76,6 @@ extern cvmx_helper_link_info_t(*cvmx_override_board_link_get) (int ipd_port); extern int cvmx_helper_board_get_mii_address(int ipd_port); /** - * This function as a board specific method of changing the PHY - * speed, duplex, and autonegotiation. This programs the PHY and - * not Octeon. This can be used to force Octeon's links to - * specific settings. - * - * @phy_addr: The address of the PHY to program - * @link_flags: - * Flags to control autonegotiation. Bit 0 is autonegotiation - * enable/disable to maintain backward compatibility. - * @link_info: Link speed to program. If the speed is zero and autonegotiation - * is enabled, all possible negotiation speeds are advertised. - * - * Returns Zero on success, negative on failure - */ -int cvmx_helper_board_link_set_phy(int phy_addr, - cvmx_helper_board_set_phy_link_flags_types_t - link_flags, - cvmx_helper_link_info_t link_info); - -/** * This function is the board specific method of determining an * ethernet ports link speed. Most Octeon boards have Marvell PHYs * and are handled by the fall through case. This function must be diff --git a/arch/mips/include/asm/octeon/cvmx-mdio.h b/arch/mips/include/asm/octeon/cvmx-mdio.h deleted file mode 100644 index 9f6a4f32a83c..000000000000 --- a/arch/mips/include/asm/octeon/cvmx-mdio.h +++ /dev/null @@ -1,506 +0,0 @@ -/***********************license start*************** - * Author: Cavium Networks - * - * Contact: support@caviumnetworks.com - * This file is part of the OCTEON SDK - * - * Copyright (c) 2003-2008 Cavium Networks - * - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, Version 2, as - * published by the Free Software Foundation. - * - * This file is distributed in the hope that it will be useful, but - * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or - * NONINFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this file; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * or visit http://www.gnu.org/licenses/. - * - * This file may also be available under a different license from Cavium. - * Contact Cavium Networks for more information - ***********************license end**************************************/ - -/* - * - * Interface to the SMI/MDIO hardware, including support for both IEEE 802.3 - * clause 22 and clause 45 operations. - * - */ - -#ifndef __CVMX_MIO_H__ -#define __CVMX_MIO_H__ - -#include <asm/octeon/cvmx-smix-defs.h> - -/** - * PHY register 0 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_CONTROL 0 -typedef union { - uint16_t u16; - struct { - uint16_t reset:1; - uint16_t loopback:1; - uint16_t speed_lsb:1; - uint16_t autoneg_enable:1; - uint16_t power_down:1; - uint16_t isolate:1; - uint16_t restart_autoneg:1; - uint16_t duplex:1; - uint16_t collision_test:1; - uint16_t speed_msb:1; - uint16_t unidirectional_enable:1; - uint16_t reserved_0_4:5; - } s; -} cvmx_mdio_phy_reg_control_t; - -/** - * PHY register 1 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_STATUS 1 -typedef union { - uint16_t u16; - struct { - uint16_t capable_100base_t4:1; - uint16_t capable_100base_x_full:1; - uint16_t capable_100base_x_half:1; - uint16_t capable_10_full:1; - uint16_t capable_10_half:1; - uint16_t capable_100base_t2_full:1; - uint16_t capable_100base_t2_half:1; - uint16_t capable_extended_status:1; - uint16_t capable_unidirectional:1; - uint16_t capable_mf_preamble_suppression:1; - uint16_t autoneg_complete:1; - uint16_t remote_fault:1; - uint16_t capable_autoneg:1; - uint16_t link_status:1; - uint16_t jabber_detect:1; - uint16_t capable_extended_registers:1; - - } s; -} cvmx_mdio_phy_reg_status_t; - -/** - * PHY register 2 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_ID1 2 -typedef union { - uint16_t u16; - struct { - uint16_t oui_bits_3_18; - } s; -} cvmx_mdio_phy_reg_id1_t; - -/** - * PHY register 3 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_ID2 3 -typedef union { - uint16_t u16; - struct { - uint16_t oui_bits_19_24:6; - uint16_t model:6; - uint16_t revision:4; - } s; -} cvmx_mdio_phy_reg_id2_t; - -/** - * PHY register 4 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_AUTONEG_ADVER 4 -typedef union { - uint16_t u16; - struct { - uint16_t next_page:1; - uint16_t reserved_14:1; - uint16_t remote_fault:1; - uint16_t reserved_12:1; - uint16_t asymmetric_pause:1; - uint16_t pause:1; - uint16_t advert_100base_t4:1; - uint16_t advert_100base_tx_full:1; - uint16_t advert_100base_tx_half:1; - uint16_t advert_10base_tx_full:1; - uint16_t advert_10base_tx_half:1; - uint16_t selector:5; - } s; -} cvmx_mdio_phy_reg_autoneg_adver_t; - -/** - * PHY register 5 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_LINK_PARTNER_ABILITY 5 -typedef union { - uint16_t u16; - struct { - uint16_t next_page:1; - uint16_t ack:1; - uint16_t remote_fault:1; - uint16_t reserved_12:1; - uint16_t asymmetric_pause:1; - uint16_t pause:1; - uint16_t advert_100base_t4:1; - uint16_t advert_100base_tx_full:1; - uint16_t advert_100base_tx_half:1; - uint16_t advert_10base_tx_full:1; - uint16_t advert_10base_tx_half:1; - uint16_t selector:5; - } s; -} cvmx_mdio_phy_reg_link_partner_ability_t; - -/** - * PHY register 6 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_AUTONEG_EXPANSION 6 -typedef union { - uint16_t u16; - struct { - uint16_t reserved_5_15:11; - uint16_t parallel_detection_fault:1; - uint16_t link_partner_next_page_capable:1; - uint16_t local_next_page_capable:1; - uint16_t page_received:1; - uint16_t link_partner_autoneg_capable:1; - - } s; -} cvmx_mdio_phy_reg_autoneg_expansion_t; - -/** - * PHY register 9 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_CONTROL_1000 9 -typedef union { - uint16_t u16; - struct { - uint16_t test_mode:3; - uint16_t manual_master_slave:1; - uint16_t master:1; - uint16_t port_type:1; - uint16_t advert_1000base_t_full:1; - uint16_t advert_1000base_t_half:1; - uint16_t reserved_0_7:8; - } s; -} cvmx_mdio_phy_reg_control_1000_t; - -/** - * PHY register 10 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_STATUS_1000 10 -typedef union { - uint16_t u16; - struct { - uint16_t master_slave_fault:1; - uint16_t is_master:1; - uint16_t local_receiver_ok:1; - uint16_t remote_receiver_ok:1; - uint16_t remote_capable_1000base_t_full:1; - uint16_t remote_capable_1000base_t_half:1; - uint16_t reserved_8_9:2; - uint16_t idle_error_count:8; - } s; -} cvmx_mdio_phy_reg_status_1000_t; - -/** - * PHY register 15 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_EXTENDED_STATUS 15 -typedef union { - uint16_t u16; - struct { - uint16_t capable_1000base_x_full:1; - uint16_t capable_1000base_x_half:1; - uint16_t capable_1000base_t_full:1; - uint16_t capable_1000base_t_half:1; - uint16_t reserved_0_11:12; - } s; -} cvmx_mdio_phy_reg_extended_status_t; - -/** - * PHY register 13 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_MMD_CONTROL 13 -typedef union { - uint16_t u16; - struct { - uint16_t function:2; - uint16_t reserved_5_13:9; - uint16_t devad:5; - } s; -} cvmx_mdio_phy_reg_mmd_control_t; - -/** - * PHY register 14 from the 802.3 spec - */ -#define CVMX_MDIO_PHY_REG_MMD_ADDRESS_DATA 14 -typedef union { - uint16_t u16; - struct { - uint16_t address_data:16; - } s; -} cvmx_mdio_phy_reg_mmd_address_data_t; - -/* Operating request encodings. */ -#define MDIO_CLAUSE_22_WRITE 0 -#define MDIO_CLAUSE_22_READ 1 - -#define MDIO_CLAUSE_45_ADDRESS 0 -#define MDIO_CLAUSE_45_WRITE 1 -#define MDIO_CLAUSE_45_READ_INC 2 -#define MDIO_CLAUSE_45_READ 3 - -/* MMD identifiers, mostly for accessing devices within XENPAK modules. */ -#define CVMX_MMD_DEVICE_PMA_PMD 1 -#define CVMX_MMD_DEVICE_WIS 2 -#define CVMX_MMD_DEVICE_PCS 3 -#define CVMX_MMD_DEVICE_PHY_XS 4 -#define CVMX_MMD_DEVICE_DTS_XS 5 -#define CVMX_MMD_DEVICE_TC 6 -#define CVMX_MMD_DEVICE_CL22_EXT 29 -#define CVMX_MMD_DEVICE_VENDOR_1 30 -#define CVMX_MMD_DEVICE_VENDOR_2 31 - -/* Helper function to put MDIO interface into clause 45 mode */ -static inline void __cvmx_mdio_set_clause45_mode(int bus_id) -{ - union cvmx_smix_clk smi_clk; - /* Put bus into clause 45 mode */ - smi_clk.u64 = cvmx_read_csr(CVMX_SMIX_CLK(bus_id)); - smi_clk.s.mode = 1; - smi_clk.s.preamble = 1; - cvmx_write_csr(CVMX_SMIX_CLK(bus_id), smi_clk.u64); -} - -/* Helper function to put MDIO interface into clause 22 mode */ -static inline void __cvmx_mdio_set_clause22_mode(int bus_id) -{ - union cvmx_smix_clk smi_clk; - /* Put bus into clause 22 mode */ - smi_clk.u64 = cvmx_read_csr(CVMX_SMIX_CLK(bus_id)); - smi_clk.s.mode = 0; - cvmx_write_csr(CVMX_SMIX_CLK(bus_id), smi_clk.u64); -} - -/** - * Perform an MII read. This function is used to read PHY - * registers controlling auto negotiation. - * - * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX) - * support multiple busses. - * @phy_id: The MII phy id - * @location: Register location to read - * - * Returns Result from the read or -1 on failure - */ -static inline int cvmx_mdio_read(int bus_id, int phy_id, int location) -{ - union cvmx_smix_cmd smi_cmd; - union cvmx_smix_rd_dat smi_rd; - int timeout = 1000; - - if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45)) - __cvmx_mdio_set_clause22_mode(bus_id); - - smi_cmd.u64 = 0; - smi_cmd.s.phy_op = MDIO_CLAUSE_22_READ; - smi_cmd.s.phy_adr = phy_id; - smi_cmd.s.reg_adr = location; - cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); - - do { - cvmx_wait(1000); - smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id)); - } while (smi_rd.s.pending && timeout--); - - if (smi_rd.s.val) - return smi_rd.s.dat; - else - return -1; -} - -/** - * Perform an MII write. This function is used to write PHY - * registers controlling auto negotiation. - * - * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX) - * support multiple busses. - * @phy_id: The MII phy id - * @location: Register location to write - * @val: Value to write - * - * Returns -1 on error - * 0 on success - */ -static inline int cvmx_mdio_write(int bus_id, int phy_id, int location, int val) -{ - union cvmx_smix_cmd smi_cmd; - union cvmx_smix_wr_dat smi_wr; - int timeout = 1000; - - if (octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45)) - __cvmx_mdio_set_clause22_mode(bus_id); - - smi_wr.u64 = 0; - smi_wr.s.dat = val; - cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64); - - smi_cmd.u64 = 0; - smi_cmd.s.phy_op = MDIO_CLAUSE_22_WRITE; - smi_cmd.s.phy_adr = phy_id; - smi_cmd.s.reg_adr = location; - cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); - - do { - cvmx_wait(1000); - smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id)); - } while (smi_wr.s.pending && --timeout); - if (timeout <= 0) - return -1; - - return 0; -} - -/** - * Perform an IEEE 802.3 clause 45 MII read. This function is used to - * read PHY registers controlling auto negotiation. - * - * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX) - * support multiple busses. - * @phy_id: The MII phy id - * @device: MDIO Managable Device (MMD) id - * @location: Register location to read - * - * Returns Result from the read or -1 on failure - */ - -static inline int cvmx_mdio_45_read(int bus_id, int phy_id, int device, - int location) -{ - union cvmx_smix_cmd smi_cmd; - union cvmx_smix_rd_dat smi_rd; - union cvmx_smix_wr_dat smi_wr; - int timeout = 1000; - - if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45)) - return -1; - - __cvmx_mdio_set_clause45_mode(bus_id); - - smi_wr.u64 = 0; - smi_wr.s.dat = location; - cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64); - - smi_cmd.u64 = 0; - smi_cmd.s.phy_op = MDIO_CLAUSE_45_ADDRESS; - smi_cmd.s.phy_adr = phy_id; - smi_cmd.s.reg_adr = device; - cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); - - do { - cvmx_wait(1000); - smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id)); - } while (smi_wr.s.pending && --timeout); - if (timeout <= 0) { - cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d " - "device %2d register %2d TIME OUT(address)\n", - bus_id, phy_id, device, location); - return -1; - } - - smi_cmd.u64 = 0; - smi_cmd.s.phy_op = MDIO_CLAUSE_45_READ; - smi_cmd.s.phy_adr = phy_id; - smi_cmd.s.reg_adr = device; - cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); - - do { - cvmx_wait(1000); - smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(bus_id)); - } while (smi_rd.s.pending && --timeout); - - if (timeout <= 0) { - cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d " - "device %2d register %2d TIME OUT(data)\n", - bus_id, phy_id, device, location); - return -1; - } - - if (smi_rd.s.val) - return smi_rd.s.dat; - else { - cvmx_dprintf("cvmx_mdio_45_read: bus_id %d phy_id %2d " - "device %2d register %2d INVALID READ\n", - bus_id, phy_id, device, location); - return -1; - } -} - -/** - * Perform an IEEE 802.3 clause 45 MII write. This function is used to - * write PHY registers controlling auto negotiation. - * - * @bus_id: MDIO bus number. Zero on most chips, but some chips (ex CN56XX) - * support multiple busses. - * @phy_id: The MII phy id - * @device: MDIO Managable Device (MMD) id - * @location: Register location to write - * @val: Value to write - * - * Returns -1 on error - * 0 on success - */ -static inline int cvmx_mdio_45_write(int bus_id, int phy_id, int device, - int location, int val) -{ - union cvmx_smix_cmd smi_cmd; - union cvmx_smix_wr_dat smi_wr; - int timeout = 1000; - - if (!octeon_has_feature(OCTEON_FEATURE_MDIO_CLAUSE_45)) - return -1; - - __cvmx_mdio_set_clause45_mode(bus_id); - - smi_wr.u64 = 0; - smi_wr.s.dat = location; - cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64); - - smi_cmd.u64 = 0; - smi_cmd.s.phy_op = MDIO_CLAUSE_45_ADDRESS; - smi_cmd.s.phy_adr = phy_id; - smi_cmd.s.reg_adr = device; - cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); - - do { - cvmx_wait(1000); - smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id)); - } while (smi_wr.s.pending && --timeout); - if (timeout <= 0) - return -1; - - smi_wr.u64 = 0; - smi_wr.s.dat = val; - cvmx_write_csr(CVMX_SMIX_WR_DAT(bus_id), smi_wr.u64); - - smi_cmd.u64 = 0; - smi_cmd.s.phy_op = MDIO_CLAUSE_45_WRITE; - smi_cmd.s.phy_adr = phy_id; - smi_cmd.s.reg_adr = device; - cvmx_write_csr(CVMX_SMIX_CMD(bus_id), smi_cmd.u64); - - do { - cvmx_wait(1000); - smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(bus_id)); - } while (smi_wr.s.pending && --timeout); - if (timeout <= 0) - return -1; - - return 0; -} - -#endif diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index 9b63cd41213d..30d1129d8624 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h @@ -17,15 +17,18 @@ */ #include <linux/ioport.h> +#include <linux/list.h> #include <linux/of.h> +#ifdef CONFIG_PCI_DRIVERS_LEGACY + /* * Each pci channel is a top-level PCI bus seem by CPU. A machine with * multiple PCI channels may have multiple PCI host controllers or a * single controller supporting multiple channels. */ struct pci_controller { - struct pci_controller *next; + struct list_head list; struct pci_bus *bus; struct device_node *of_node; @@ -38,10 +41,12 @@ struct pci_controller { struct resource *busn_resource; unsigned long busn_offset; +#ifndef CONFIG_PCI_DOMAINS_GENERIC unsigned int index; /* For compatibility with current (as of July 2003) pciutils and XFree86. Eventually will be removed. */ unsigned int need_domain_info; +#endif /* Optional access methods for reading/writing the bus number of the PCI controller */ @@ -59,12 +64,43 @@ extern void register_pci_controller(struct pci_controller *hose); */ extern int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin); +/* Do platform specific device initialization at pci_enable_device() time */ +extern int pcibios_plat_dev_init(struct pci_dev *dev); + +extern char * (*pcibios_plat_setup)(char *str); + +#ifdef CONFIG_OF +/* this function parses memory ranges from a device node */ +extern void pci_load_of_ranges(struct pci_controller *hose, + struct device_node *node); +#else +static inline void pci_load_of_ranges(struct pci_controller *hose, + struct device_node *node) {} +#endif + +#ifdef CONFIG_PCI_DOMAINS_GENERIC +static inline void set_pci_need_domain_info(struct pci_controller *hose, + int need_domain_info) +{ + /* nothing to do */ +} +#elif defined(CONFIG_PCI_DOMAINS) +static inline void set_pci_need_domain_info(struct pci_controller *hose, + int need_domain_info) +{ + hose->need_domain_info = need_domain_info; +} +#endif /* CONFIG_PCI_DOMAINS */ + +#endif /* Can be used to override the logic in pci_scan_bus for skipping already-configured bus numbers - to be used for buggy BIOSes or architectures with incomplete PCI setup by the loader */ - -extern unsigned int pcibios_assign_all_busses(void); +static inline unsigned int pcibios_assign_all_busses(void) +{ + return 1; +} extern unsigned long PCIBIOS_MIN_IO; extern unsigned long PCIBIOS_MIN_MEM; @@ -100,7 +136,12 @@ struct pci_dev; */ #define PCI_DMA_BUS_IS_PHYS (1) -#ifdef CONFIG_PCI_DOMAINS +#ifdef CONFIG_PCI_DOMAINS_GENERIC +static inline int pci_proc_domain(struct pci_bus *bus) +{ + return pci_domain_nr(bus); +} +#elif defined(CONFIG_PCI_DOMAINS) #define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index static inline int pci_proc_domain(struct pci_bus *bus) @@ -121,15 +162,4 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) return channel ? 15 : 14; } -extern char * (*pcibios_plat_setup)(char *str); - -#ifdef CONFIG_OF -/* this function parses memory ranges from a device node */ -extern void pci_load_of_ranges(struct pci_controller *hose, - struct device_node *node); -#else -static inline void pci_load_of_ranges(struct pci_controller *hose, - struct device_node *node) {} -#endif - #endif /* _ASM_PCI_H */ diff --git a/arch/mips/include/asm/pgalloc.h b/arch/mips/include/asm/pgalloc.h index 93c079a1cfc8..a03e86969f78 100644 --- a/arch/mips/include/asm/pgalloc.h +++ b/arch/mips/include/asm/pgalloc.h @@ -67,11 +67,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { - pte_t *pte; - - pte = (pte_t *) __get_free_pages(GFP_KERNEL|__GFP_ZERO, PTE_ORDER); - - return pte; + return (pte_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, PTE_ORDER); } static inline struct page *pte_alloc_one(struct mm_struct *mm, diff --git a/arch/mips/include/asm/pm-cps.h b/arch/mips/include/asm/pm-cps.h index 625eda53d571..89d58d80b77b 100644 --- a/arch/mips/include/asm/pm-cps.h +++ b/arch/mips/include/asm/pm-cps.h @@ -13,10 +13,12 @@ /* * The CM & CPC can only handle coherence & power control on a per-core basis, - * thus in an MT system the VPEs within each core are coupled and can only + * thus in an MT system the VP(E)s within each core are coupled and can only * enter or exit states requiring CM or CPC assistance in unison. */ -#ifdef CONFIG_MIPS_MT +#if defined(CONFIG_CPU_MIPSR6) +# define coupled_coherence cpu_has_vp +#elif defined(CONFIG_MIPS_MT) # define coupled_coherence cpu_has_mipsmt #else # define coupled_coherence 0 diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h index f6fc6aac5496..b6578611dddb 100644 --- a/arch/mips/include/asm/ptrace.h +++ b/arch/mips/include/asm/ptrace.h @@ -152,7 +152,7 @@ static inline int is_syscall_success(struct pt_regs *regs) static inline long regs_return_value(struct pt_regs *regs) { - if (is_syscall_success(regs)) + if (is_syscall_success(regs) || !user_mode(regs)) return regs->regs[2]; else return -regs->regs[2]; diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h index 8bc6c70a4030..060f23ff1817 100644 --- a/arch/mips/include/asm/smp.h +++ b/arch/mips/include/asm/smp.h @@ -85,6 +85,20 @@ static inline void __cpu_die(unsigned int cpu) extern void play_dead(void); #endif +/* + * This function will set up the necessary IPIs for Linux to communicate + * with the CPUs in mask. + * Return 0 on success. + */ +int mips_smp_ipi_allocate(const struct cpumask *mask); + +/* + * This function will free up IPIs allocated with mips_smp_ipi_allocate to the + * CPUs in mask, which must be a subset of the IPIs that have been configured. + * Return 0 on success. + */ +int mips_smp_ipi_free(const struct cpumask *mask); + static inline void arch_send_call_function_single_ipi(int cpu) { extern struct plat_smp_ops *mp_ops; /* private */ diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h index 4daf839cd8a8..89fa5c0b1579 100644 --- a/arch/mips/include/asm/uaccess.h +++ b/arch/mips/include/asm/uaccess.h @@ -859,7 +859,10 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n); __cu_to = (to); \ __cu_from = (from); \ __cu_len = (n); \ + \ + check_object_size(__cu_from, __cu_len, true); \ might_fault(); \ + \ if (eva_kernel_access()) \ __cu_len = __invoke_copy_to_kernel(__cu_to, __cu_from, \ __cu_len); \ @@ -880,6 +883,9 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n); __cu_to = (to); \ __cu_from = (from); \ __cu_len = (n); \ + \ + check_object_size(__cu_from, __cu_len, true); \ + \ if (eva_kernel_access()) \ __cu_len = __invoke_copy_to_kernel(__cu_to, __cu_from, \ __cu_len); \ @@ -898,6 +904,9 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n); __cu_to = (to); \ __cu_from = (from); \ __cu_len = (n); \ + \ + check_object_size(__cu_to, __cu_len, false); \ + \ if (eva_kernel_access()) \ __cu_len = __invoke_copy_from_kernel_inatomic(__cu_to, \ __cu_from,\ @@ -932,6 +941,9 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n); __cu_to = (to); \ __cu_from = (from); \ __cu_len = (n); \ + \ + check_object_size(__cu_from, __cu_len, true); \ + \ if (eva_kernel_access()) { \ __cu_len = __invoke_copy_to_kernel(__cu_to, \ __cu_from, \ @@ -1124,6 +1136,9 @@ extern size_t __copy_in_user_eva(void *__to, const void *__from, size_t __n); __cu_to = (to); \ __cu_from = (from); \ __cu_len = (n); \ + \ + check_object_size(__cu_to, __cu_len, false); \ + \ if (eva_kernel_access()) { \ __cu_len = __invoke_copy_from_kernel(__cu_to, \ __cu_from, \ @@ -1162,6 +1177,9 @@ extern size_t __copy_in_user_eva(void *__to, const void *__from, size_t __n); __cu_to = (to); \ __cu_from = (from); \ __cu_len = (n); \ + \ + check_object_size(__cu_to, __cu_len, false); \ + \ if (eva_kernel_access()) { \ __cu_len = __invoke_copy_from_kernel(__cu_to, \ __cu_from, \ diff --git a/arch/mips/kernel/binfmt_elfn32.c b/arch/mips/kernel/binfmt_elfn32.c index 58ad63d7eb42..9c7f3e136d50 100644 --- a/arch/mips/kernel/binfmt_elfn32.c +++ b/arch/mips/kernel/binfmt_elfn32.c @@ -1,5 +1,6 @@ /* * Support for n32 Linux/MIPS ELF binaries. + * Author: Ralf Baechle (ralf@linux-mips.org) * * Copyright (C) 1999, 2001 Ralf Baechle * Copyright (C) 1999, 2001 Silicon Graphics, Inc. @@ -37,7 +38,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) #include <asm/processor.h> -#include <linux/module.h> #include <linux/elfcore.h> #include <linux/compat.h> #include <linux/math64.h> @@ -96,12 +96,6 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value) #define ELF_CORE_EFLAGS EF_MIPS_ABI2 -MODULE_DESCRIPTION("Binary format loader for compatibility with n32 Linux/MIPS binaries"); -MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)"); - -#undef MODULE_DESCRIPTION -#undef MODULE_AUTHOR - #undef TASK_SIZE #define TASK_SIZE TASK_SIZE32 diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c index 49fb881481f7..1ab34322dd97 100644 --- a/arch/mips/kernel/binfmt_elfo32.c +++ b/arch/mips/kernel/binfmt_elfo32.c @@ -1,5 +1,6 @@ /* * Support for o32 Linux/MIPS ELF binaries. + * Author: Ralf Baechle (ralf@linux-mips.org) * * Copyright (C) 1999, 2001 Ralf Baechle * Copyright (C) 1999, 2001 Silicon Graphics, Inc. @@ -42,7 +43,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; #include <asm/processor.h> -#include <linux/module.h> #include <linux/elfcore.h> #include <linux/compat.h> #include <linux/math64.h> @@ -99,12 +99,6 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value) value->tv_usec = rem / NSEC_PER_USEC; } -MODULE_DESCRIPTION("Binary format loader for compatibility with o32 Linux/MIPS binaries"); -MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)"); - -#undef MODULE_DESCRIPTION -#undef MODULE_AUTHOR - #undef TASK_SIZE #define TASK_SIZE TASK_SIZE32 diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c index 46c227fc98f5..12c718181e5e 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c @@ -9,7 +9,7 @@ #include <linux/kernel.h> #include <linux/sched.h> #include <linux/signal.h> -#include <linux/module.h> +#include <linux/export.h> #include <asm/branch.h> #include <asm/cpu.h> #include <asm/cpu-features.h> @@ -866,3 +866,37 @@ unaligned: force_sig(SIGBUS, current); return -EFAULT; } + +#if (defined CONFIG_KPROBES) || (defined CONFIG_UPROBES) + +int __insn_is_compact_branch(union mips_instruction insn) +{ + if (!cpu_has_mips_r6) + return 0; + + switch (insn.i_format.opcode) { + case blezl_op: + case bgtzl_op: + case blez_op: + case bgtz_op: + /* + * blez[l] and bgtz[l] opcodes with non-zero rt + * are MIPS R6 compact branches + */ + if (insn.i_format.rt) + return 1; + break; + case bc6_op: + case balc6_op: + case pop10_op: + case pop30_op: + case pop66_op: + case pop76_op: + return 1; + } + + return 0; +} +EXPORT_SYMBOL_GPL(__insn_is_compact_branch); + +#endif /* CONFIG_KPROBES || CONFIG_UPROBES */ diff --git a/arch/mips/kernel/kprobes.c b/arch/mips/kernel/kprobes.c index 212f46f2014e..f5c8bce70db2 100644 --- a/arch/mips/kernel/kprobes.c +++ b/arch/mips/kernel/kprobes.c @@ -32,7 +32,8 @@ #include <asm/ptrace.h> #include <asm/branch.h> #include <asm/break.h> -#include <asm/inst.h> + +#include "probes-common.h" static const union mips_instruction breakpoint_insn = { .b_format = { @@ -55,63 +56,7 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); static int __kprobes insn_has_delayslot(union mips_instruction insn) { - switch (insn.i_format.opcode) { - - /* - * This group contains: - * jr and jalr are in r_format format. - */ - case spec_op: - switch (insn.r_format.func) { - case jr_op: - case jalr_op: - break; - default: - goto insn_ok; - } - - /* - * This group contains: - * bltz_op, bgez_op, bltzl_op, bgezl_op, - * bltzal_op, bgezal_op, bltzall_op, bgezall_op. - */ - case bcond_op: - - /* - * These are unconditional and in j_format. - */ - case jal_op: - case j_op: - - /* - * These are conditional and in i_format. - */ - case beq_op: - case beql_op: - case bne_op: - case bnel_op: - case blez_op: - case blezl_op: - case bgtz_op: - case bgtzl_op: - - /* - * These are the FPA/cp1 branch instructions. - */ - case cop1_op: - -#ifdef CONFIG_CPU_CAVIUM_OCTEON - case lwc2_op: /* This is bbit0 on Octeon */ - case ldc2_op: /* This is bbit032 on Octeon */ - case swc2_op: /* This is bbit1 on Octeon */ - case sdc2_op: /* This is bbit132 on Octeon */ -#endif - return 1; - default: - break; - } -insn_ok: - return 0; + return __insn_has_delay_slot(insn); } /* @@ -161,6 +106,12 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) goto out; } + if (__insn_is_compact_branch(insn)) { + pr_notice("Kprobes for compact branches are not supported\n"); + ret = -EINVAL; + goto out; + } + /* insn: must be on special executable page on mips. */ p->ainsn.insn = get_insn_slot(); if (!p->ainsn.insn) { diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 0b29646bcee7..50fb62544df7 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -26,7 +26,6 @@ #include <linux/utsname.h> #include <linux/personality.h> #include <linux/dnotify.h> -#include <linux/module.h> #include <linux/binfmts.h> #include <linux/security.h> #include <linux/compat.h> diff --git a/arch/mips/kernel/mips-cpc.c b/arch/mips/kernel/mips-cpc.c index 566b8d2c092c..2a45867d3b4f 100644 --- a/arch/mips/kernel/mips-cpc.c +++ b/arch/mips/kernel/mips-cpc.c @@ -52,7 +52,7 @@ static phys_addr_t mips_cpc_phys_base(void) int mips_cpc_probe(void) { phys_addr_t addr; - unsigned cpu; + unsigned int cpu; for_each_possible_cpu(cpu) spin_lock_init(&per_cpu(cpc_core_lock, cpu)); @@ -70,7 +70,12 @@ int mips_cpc_probe(void) void mips_cpc_lock_other(unsigned int core) { - unsigned curr_core; + unsigned int curr_core; + + if (mips_cm_revision() >= CM_REV_CM3) + /* Systems with CM >= 3 lock the CPC via mips_cm_lock_other */ + return; + preempt_disable(); curr_core = current_cpu_data.core; spin_lock_irqsave(&per_cpu(cpc_core_lock, curr_core), @@ -86,7 +91,13 @@ void mips_cpc_lock_other(unsigned int core) void mips_cpc_unlock_other(void) { - unsigned curr_core = current_cpu_data.core; + unsigned int curr_core; + + if (mips_cm_revision() >= CM_REV_CM3) + /* Systems with CM >= 3 lock the CPC via mips_cm_lock_other */ + return; + + curr_core = current_cpu_data.core; spin_unlock_irqrestore(&per_cpu(cpc_core_lock, curr_core), per_cpu(cpc_core_lock_flags, curr_core)); preempt_enable(); diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c index 0a7e10b5f9e3..22dedd62818a 100644 --- a/arch/mips/kernel/mips-r2-to-r6-emul.c +++ b/arch/mips/kernel/mips-r2-to-r6-emul.c @@ -15,7 +15,6 @@ #include <linux/debugfs.h> #include <linux/init.h> #include <linux/kernel.h> -#include <linux/module.h> #include <linux/ptrace.h> #include <linux/seq_file.h> diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c index 79850e376ef6..94627a3a6a0d 100644 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c @@ -20,6 +20,7 @@ #undef DEBUG +#include <linux/extable.h> #include <linux/moduleloader.h> #include <linux/elf.h> #include <linux/mm.h> diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c index 5b31a9405ebc..7cf653e21423 100644 --- a/arch/mips/kernel/pm-cps.c +++ b/arch/mips/kernel/pm-cps.c @@ -8,6 +8,7 @@ * option) any later version. */ +#include <linux/cpuhotplug.h> #include <linux/init.h> #include <linux/percpu.h> #include <linux/slab.h> @@ -70,13 +71,8 @@ static DEFINE_PER_CPU_ALIGNED(atomic_t, pm_barrier); DEFINE_PER_CPU_ALIGNED(struct mips_static_suspend_state, cps_cpu_state); /* A somewhat arbitrary number of labels & relocs for uasm */ -static struct uasm_label labels[32] __initdata; -static struct uasm_reloc relocs[32] __initdata; - -/* CPU dependant sync types */ -static unsigned stype_intervention; -static unsigned stype_memory; -static unsigned stype_ordering; +static struct uasm_label labels[32]; +static struct uasm_reloc relocs[32]; enum mips_reg { zero, at, v0, v1, a0, a1, a2, a3, @@ -134,7 +130,7 @@ int cps_pm_enter_state(enum cps_pm_state state) return -EINVAL; /* Calculate which coupled CPUs (VPEs) are online */ -#ifdef CONFIG_MIPS_MT +#if defined(CONFIG_MIPS_MT) || defined(CONFIG_CPU_MIPSR6) if (cpu_online(cpu)) { cpumask_and(coupled_mask, cpu_online_mask, &cpu_sibling_map[cpu]); @@ -198,10 +194,10 @@ int cps_pm_enter_state(enum cps_pm_state state) return 0; } -static void __init cps_gen_cache_routine(u32 **pp, struct uasm_label **pl, - struct uasm_reloc **pr, - const struct cache_desc *cache, - unsigned op, int lbl) +static void cps_gen_cache_routine(u32 **pp, struct uasm_label **pl, + struct uasm_reloc **pr, + const struct cache_desc *cache, + unsigned op, int lbl) { unsigned cache_size = cache->ways << cache->waybit; unsigned i; @@ -242,10 +238,10 @@ static void __init cps_gen_cache_routine(u32 **pp, struct uasm_label **pl, uasm_i_nop(pp); } -static int __init cps_gen_flush_fsb(u32 **pp, struct uasm_label **pl, - struct uasm_reloc **pr, - const struct cpuinfo_mips *cpu_info, - int lbl) +static int cps_gen_flush_fsb(u32 **pp, struct uasm_label **pl, + struct uasm_reloc **pr, + const struct cpuinfo_mips *cpu_info, + int lbl) { unsigned i, fsb_size = 8; unsigned num_loads = (fsb_size * 3) / 2; @@ -272,14 +268,9 @@ static int __init cps_gen_flush_fsb(u32 **pp, struct uasm_label **pl, /* On older ones it's unavailable */ return -1; - /* CPUs which do not require the workaround */ - case CPU_P5600: - case CPU_I6400: - return 0; - default: - WARN_ONCE(1, "pm-cps: FSB flush unsupported for this CPU\n"); - return -1; + /* Assume that the CPU does not need this workaround */ + return 0; } /* @@ -320,8 +311,8 @@ static int __init cps_gen_flush_fsb(u32 **pp, struct uasm_label **pl, i * line_size * line_stride, t0); } - /* Completion barrier */ - uasm_i_sync(pp, stype_memory); + /* Barrier ensuring previous cache invalidates are complete */ + uasm_i_sync(pp, STYPE_SYNC); uasm_i_ehb(pp); /* Check whether the pipeline stalled due to the FSB being full */ @@ -340,9 +331,9 @@ static int __init cps_gen_flush_fsb(u32 **pp, struct uasm_label **pl, return 0; } -static void __init cps_gen_set_top_bit(u32 **pp, struct uasm_label **pl, - struct uasm_reloc **pr, - unsigned r_addr, int lbl) +static void cps_gen_set_top_bit(u32 **pp, struct uasm_label **pl, + struct uasm_reloc **pr, + unsigned r_addr, int lbl) { uasm_i_lui(pp, t0, uasm_rel_hi(0x80000000)); uasm_build_label(pl, *pp, lbl); @@ -353,7 +344,7 @@ static void __init cps_gen_set_top_bit(u32 **pp, struct uasm_label **pl, uasm_i_nop(pp); } -static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) +static void *cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) { struct uasm_label *l = labels; struct uasm_reloc *r = relocs; @@ -411,7 +402,7 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) if (coupled_coherence) { /* Increment ready_count */ - uasm_i_sync(&p, stype_ordering); + uasm_i_sync(&p, STYPE_SYNC_MB); uasm_build_label(&l, p, lbl_incready); uasm_i_ll(&p, t1, 0, r_nc_count); uasm_i_addiu(&p, t2, t1, 1); @@ -419,8 +410,8 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) uasm_il_beqz(&p, &r, t2, lbl_incready); uasm_i_addiu(&p, t1, t1, 1); - /* Ordering barrier */ - uasm_i_sync(&p, stype_ordering); + /* Barrier ensuring all CPUs see the updated r_nc_count value */ + uasm_i_sync(&p, STYPE_SYNC_MB); /* * If this is the last VPE to become ready for non-coherence @@ -441,7 +432,8 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) uasm_i_lw(&p, t0, 0, r_nc_count); uasm_il_bltz(&p, &r, t0, lbl_secondary_cont); uasm_i_ehb(&p); - uasm_i_yield(&p, zero, t1); + if (cpu_has_mipsmt) + uasm_i_yield(&p, zero, t1); uasm_il_b(&p, &r, lbl_poll_cont); uasm_i_nop(&p); } else { @@ -449,8 +441,21 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) * The core will lose power & this VPE will not continue * so it can simply halt here. */ - uasm_i_addiu(&p, t0, zero, TCHALT_H); - uasm_i_mtc0(&p, t0, 2, 4); + if (cpu_has_mipsmt) { + /* Halt the VPE via C0 tchalt register */ + uasm_i_addiu(&p, t0, zero, TCHALT_H); + uasm_i_mtc0(&p, t0, 2, 4); + } else if (cpu_has_vp) { + /* Halt the VP via the CPC VP_STOP register */ + unsigned int vpe_id; + + vpe_id = cpu_vpe_id(&cpu_data[cpu]); + uasm_i_addiu(&p, t0, zero, 1 << vpe_id); + UASM_i_LA(&p, t1, (long)addr_cpc_cl_vp_stop()); + uasm_i_sw(&p, t0, 0, t1); + } else { + BUG(); + } uasm_build_label(&l, p, lbl_secondary_hang); uasm_il_b(&p, &r, lbl_secondary_hang); uasm_i_nop(&p); @@ -472,22 +477,24 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) cps_gen_cache_routine(&p, &l, &r, &cpu_data[cpu].dcache, Index_Writeback_Inv_D, lbl_flushdcache); - /* Completion barrier */ - uasm_i_sync(&p, stype_memory); + /* Barrier ensuring previous cache invalidates are complete */ + uasm_i_sync(&p, STYPE_SYNC); uasm_i_ehb(&p); - /* - * Disable all but self interventions. The load from COHCTL is defined - * by the interAptiv & proAptiv SUMs as ensuring that the operation - * resulting from the preceding store is complete. - */ - uasm_i_addiu(&p, t0, zero, 1 << cpu_data[cpu].core); - uasm_i_sw(&p, t0, 0, r_pcohctl); - uasm_i_lw(&p, t0, 0, r_pcohctl); - - /* Sync to ensure previous interventions are complete */ - uasm_i_sync(&p, stype_intervention); - uasm_i_ehb(&p); + if (mips_cm_revision() < CM_REV_CM3) { + /* + * Disable all but self interventions. The load from COHCTL is + * defined by the interAptiv & proAptiv SUMs as ensuring that the + * operation resulting from the preceding store is complete. + */ + uasm_i_addiu(&p, t0, zero, 1 << cpu_data[cpu].core); + uasm_i_sw(&p, t0, 0, r_pcohctl); + uasm_i_lw(&p, t0, 0, r_pcohctl); + + /* Barrier to ensure write to coherence control is complete */ + uasm_i_sync(&p, STYPE_SYNC); + uasm_i_ehb(&p); + } /* Disable coherence */ uasm_i_sw(&p, zero, 0, r_pcohctl); @@ -531,8 +538,8 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) goto gen_done; } - /* Completion barrier */ - uasm_i_sync(&p, stype_memory); + /* Barrier to ensure write to CPC command is complete */ + uasm_i_sync(&p, STYPE_SYNC); uasm_i_ehb(&p); } @@ -562,26 +569,29 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) * will run this. The first will actually re-enable coherence & the * rest will just be performing a rather unusual nop. */ - uasm_i_addiu(&p, t0, zero, CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK); + uasm_i_addiu(&p, t0, zero, mips_cm_revision() < CM_REV_CM3 + ? CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK + : CM3_GCR_Cx_COHERENCE_COHEN_MSK); + uasm_i_sw(&p, t0, 0, r_pcohctl); uasm_i_lw(&p, t0, 0, r_pcohctl); - /* Completion barrier */ - uasm_i_sync(&p, stype_memory); + /* Barrier to ensure write to coherence control is complete */ + uasm_i_sync(&p, STYPE_SYNC); uasm_i_ehb(&p); if (coupled_coherence && (state == CPS_PM_NC_WAIT)) { /* Decrement ready_count */ uasm_build_label(&l, p, lbl_decready); - uasm_i_sync(&p, stype_ordering); + uasm_i_sync(&p, STYPE_SYNC_MB); uasm_i_ll(&p, t1, 0, r_nc_count); uasm_i_addiu(&p, t2, t1, -1); uasm_i_sc(&p, t2, 0, r_nc_count); uasm_il_beqz(&p, &r, t2, lbl_decready); uasm_i_andi(&p, v0, t1, (1 << fls(smp_num_siblings)) - 1); - /* Ordering barrier */ - uasm_i_sync(&p, stype_ordering); + /* Barrier ensuring all CPUs see the updated r_nc_count value */ + uasm_i_sync(&p, STYPE_SYNC_MB); } if (coupled_coherence && (state == CPS_PM_CLOCK_GATED)) { @@ -602,8 +612,8 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) */ uasm_build_label(&l, p, lbl_secondary_cont); - /* Ordering barrier */ - uasm_i_sync(&p, stype_ordering); + /* Barrier ensuring all CPUs see the updated r_nc_count value */ + uasm_i_sync(&p, STYPE_SYNC_MB); } /* The core is coherent, time to return to C code */ @@ -628,7 +638,7 @@ out_err: return NULL; } -static int __init cps_gen_core_entries(unsigned cpu) +static int cps_pm_online_cpu(unsigned int cpu) { enum cps_pm_state state; unsigned core = cpu_data[cpu].core; @@ -670,29 +680,10 @@ static int __init cps_gen_core_entries(unsigned cpu) static int __init cps_pm_init(void) { - unsigned cpu; - int err; - - /* Detect appropriate sync types for the system */ - switch (current_cpu_data.cputype) { - case CPU_INTERAPTIV: - case CPU_PROAPTIV: - case CPU_M5150: - case CPU_P5600: - case CPU_I6400: - stype_intervention = 0x2; - stype_memory = 0x3; - stype_ordering = 0x10; - break; - - default: - pr_warn("Power management is using heavyweight sync 0\n"); - } - /* A CM is required for all non-coherent states */ if (!mips_cm_present()) { pr_warn("pm-cps: no CM, non-coherent states unavailable\n"); - goto out; + return 0; } /* @@ -722,12 +713,7 @@ static int __init cps_pm_init(void) pr_warn("pm-cps: no CPC, clock & power gating unavailable\n"); } - for_each_present_cpu(cpu) { - err = cps_gen_core_entries(cpu); - if (err) - return err; - } -out: - return 0; + return cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "AP_PM_CPS_CPU_ONLINE", + cps_pm_online_cpu, NULL); } arch_initcall(cps_pm_init); diff --git a/arch/mips/kernel/probes-common.h b/arch/mips/kernel/probes-common.h new file mode 100644 index 000000000000..dd08e41134b6 --- /dev/null +++ b/arch/mips/kernel/probes-common.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2016 Imagination Technologies + * Author: Marcin Nowakowski <marcin.nowakowski@imgtec.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __PROBES_COMMON_H +#define __PROBES_COMMON_H + +#include <asm/inst.h> + +int __insn_is_compact_branch(union mips_instruction insn); + +static inline int __insn_has_delay_slot(const union mips_instruction insn) +{ + switch (insn.i_format.opcode) { + /* + * jr and jalr are in r_format format. + */ + case spec_op: + switch (insn.r_format.func) { + case jalr_op: + case jr_op: + return 1; + } + break; + + /* + * This group contains: + * bltz_op, bgez_op, bltzl_op, bgezl_op, + * bltzal_op, bgezal_op, bltzall_op, bgezall_op. + */ + case bcond_op: + switch (insn.i_format.rt) { + case bltz_op: + case bltzl_op: + case bgez_op: + case bgezl_op: + case bltzal_op: + case bltzall_op: + case bgezal_op: + case bgezall_op: + case bposge32_op: + return 1; + } + break; + + /* + * These are unconditional and in j_format. + */ + case jal_op: + case j_op: + case beq_op: + case beql_op: + case bne_op: + case bnel_op: + case blez_op: /* not really i_format */ + case blezl_op: + case bgtz_op: + case bgtzl_op: + return 1; + + /* + * And now the FPA/cp1 branch instructions. + */ + case cop1_op: +#ifdef CONFIG_CPU_CAVIUM_OCTEON + case lwc2_op: /* This is bbit0 on Octeon */ + case ldc2_op: /* This is bbit032 on Octeon */ + case swc2_op: /* This is bbit1 on Octeon */ + case sdc2_op: /* This is bbit132 on Octeon */ +#endif + return 1; + } + + return 0; +} + +#endif /* __PROBES_COMMON_H */ diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index 97dc01b03631..4eff2aed7360 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c @@ -135,6 +135,13 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "package\t\t\t: %d\n", cpu_data[n].package); seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core); +#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_CPU_MIPSR6) + if (cpu_has_mipsmt) + seq_printf(m, "VPE\t\t\t: %d\n", cpu_data[n].vpe_id); + else if (cpu_has_vp) + seq_printf(m, "VP\t\t\t: %d\n", cpu_data[n].vpe_id); +#endif + sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", cpu_has_vce ? "%u" : "not available"); seq_printf(m, fmt, 'D', vced_count); diff --git a/arch/mips/kernel/smp-gic.c b/arch/mips/kernel/smp-gic.c deleted file mode 100644 index 9b63829cf929..000000000000 --- a/arch/mips/kernel/smp-gic.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2013 Imagination Technologies - * Author: Paul Burton <paul.burton@imgtec.com> - * - * Based on smp-cmp.c: - * Copyright (C) 2007 MIPS Technologies, Inc. - * Author: Chris Dearman (chris@mips.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/irqchip/mips-gic.h> -#include <linux/printk.h> - -#include <asm/mips-cpc.h> -#include <asm/smp-ops.h> - -void gic_send_ipi_single(int cpu, unsigned int action) -{ - unsigned long flags; - unsigned int intr; - unsigned int core = cpu_data[cpu].core; - - pr_debug("CPU%d: %s cpu %d action %u status %08x\n", - smp_processor_id(), __func__, cpu, action, read_c0_status()); - - local_irq_save(flags); - - switch (action) { - case SMP_CALL_FUNCTION: - intr = plat_ipi_call_int_xlate(cpu); - break; - - case SMP_RESCHEDULE_YOURSELF: - intr = plat_ipi_resched_int_xlate(cpu); - break; - - default: - BUG(); - } - - gic_send_ipi(intr); - - if (mips_cpc_present() && (core != current_cpu_data.core)) { - while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) { - mips_cm_lock_other(core, 0); - mips_cpc_lock_other(core); - write_cpc_co_cmd(CPC_Cx_CMD_PWRUP); - mips_cpc_unlock_other(); - mips_cm_unlock_other(); - } - } - - local_irq_restore(flags); -} - -void gic_send_ipi_mask(const struct cpumask *mask, unsigned int action) -{ - unsigned int i; - - for_each_cpu(i, mask) - gic_send_ipi_single(i, action); -} diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 4f9570a57e8d..e077ea3e11fb 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c @@ -289,26 +289,3 @@ struct plat_smp_ops vsmp_smp_ops = { .prepare_cpus = vsmp_prepare_cpus, }; -#ifdef CONFIG_PROC_FS -static int proc_cpuinfo_chain_call(struct notifier_block *nfb, - unsigned long action_unused, void *data) -{ - struct proc_cpuinfo_notifier_args *pcn = data; - struct seq_file *m = pcn->m; - unsigned long n = pcn->n; - - if (!cpu_has_mipsmt) - return NOTIFY_OK; - - seq_printf(m, "VPE\t\t\t: %d\n", cpu_data[n].vpe_id); - - return NOTIFY_OK; -} - -static int __init proc_cpuinfo_notifier_init(void) -{ - return proc_cpuinfo_notifier(proc_cpuinfo_chain_call, 0); -} - -subsys_initcall(proc_cpuinfo_notifier_init); -#endif diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index b0baf48951fa..7ebb1918e2ac 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -25,7 +25,7 @@ #include <linux/smp.h> #include <linux/spinlock.h> #include <linux/threads.h> -#include <linux/module.h> +#include <linux/export.h> #include <linux/time.h> #include <linux/timex.h> #include <linux/sched.h> @@ -192,9 +192,11 @@ void mips_smp_send_ipi_mask(const struct cpumask *mask, unsigned int action) continue; while (!cpumask_test_cpu(cpu, &cpu_coherent_mask)) { + mips_cm_lock_other(core, 0); mips_cpc_lock_other(core); write_cpc_co_cmd(CPC_Cx_CMD_PWRUP); mips_cpc_unlock_other(); + mips_cm_unlock_other(); } } } @@ -229,7 +231,7 @@ static struct irqaction irq_call = { .name = "IPI call" }; -static __init void smp_ipi_init_one(unsigned int virq, +static void smp_ipi_init_one(unsigned int virq, struct irqaction *action) { int ret; @@ -239,9 +241,11 @@ static __init void smp_ipi_init_one(unsigned int virq, BUG_ON(ret); } -static int __init mips_smp_ipi_init(void) +static unsigned int call_virq, sched_virq; + +int mips_smp_ipi_allocate(const struct cpumask *mask) { - unsigned int call_virq, sched_virq; + int virq; struct irq_domain *ipidomain; struct device_node *node; @@ -268,16 +272,20 @@ static int __init mips_smp_ipi_init(void) if (!ipidomain) return 0; - call_virq = irq_reserve_ipi(ipidomain, cpu_possible_mask); - BUG_ON(!call_virq); + virq = irq_reserve_ipi(ipidomain, mask); + BUG_ON(!virq); + if (!call_virq) + call_virq = virq; - sched_virq = irq_reserve_ipi(ipidomain, cpu_possible_mask); - BUG_ON(!sched_virq); + virq = irq_reserve_ipi(ipidomain, mask); + BUG_ON(!virq); + if (!sched_virq) + sched_virq = virq; if (irq_domain_is_ipi_per_cpu(ipidomain)) { int cpu; - for_each_cpu(cpu, cpu_possible_mask) { + for_each_cpu(cpu, mask) { smp_ipi_init_one(call_virq + cpu, &irq_call); smp_ipi_init_one(sched_virq + cpu, &irq_resched); } @@ -286,6 +294,45 @@ static int __init mips_smp_ipi_init(void) smp_ipi_init_one(sched_virq, &irq_resched); } + return 0; +} + +int mips_smp_ipi_free(const struct cpumask *mask) +{ + struct irq_domain *ipidomain; + struct device_node *node; + + node = of_irq_find_parent(of_root); + ipidomain = irq_find_matching_host(node, DOMAIN_BUS_IPI); + + /* + * Some platforms have half DT setup. So if we found irq node but + * didn't find an ipidomain, try to search for one that is not in the + * DT. + */ + if (node && !ipidomain) + ipidomain = irq_find_matching_host(NULL, DOMAIN_BUS_IPI); + + BUG_ON(!ipidomain); + + if (irq_domain_is_ipi_per_cpu(ipidomain)) { + int cpu; + + for_each_cpu(cpu, mask) { + remove_irq(call_virq + cpu, &irq_call); + remove_irq(sched_virq + cpu, &irq_resched); + } + } + irq_destroy_ipi(call_virq, mask); + irq_destroy_ipi(sched_virq, mask); + return 0; +} + + +static int __init mips_smp_ipi_init(void) +{ + mips_smp_ipi_allocate(cpu_possible_mask); + call_desc = irq_to_desc(call_virq); sched_desc = irq_to_desc(sched_virq); diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 3de85be2486a..1f5fdee1dfc3 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -21,6 +21,7 @@ #include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> +#include <linux/extable.h> #include <linux/mm.h> #include <linux/sched.h> #include <linux/smp.h> @@ -48,6 +49,7 @@ #include <asm/fpu.h> #include <asm/fpu_emulator.h> #include <asm/idle.h> +#include <asm/mips-cm.h> #include <asm/mips-r2-to-r6-emul.h> #include <asm/mipsregs.h> #include <asm/mipsmtregs.h> @@ -444,6 +446,8 @@ asmlinkage void do_be(struct pt_regs *regs) if (board_be_handler) action = board_be_handler(regs, fixup != NULL); + else + mips_cm_error_report(); switch (action) { case MIPS_BE_DISCARD: @@ -2091,6 +2095,14 @@ static void configure_exception_vector(void) { if (cpu_has_veic || cpu_has_vint) { unsigned long sr = set_c0_status(ST0_BEV); + /* If available, use WG to set top bits of EBASE */ + if (cpu_has_ebase_wg) { +#ifdef CONFIG_64BIT + write_c0_ebase_64(ebase | MIPS_EBASE_WG); +#else + write_c0_ebase(ebase | MIPS_EBASE_WG); +#endif + } write_c0_ebase(ebase); write_c0_status(sr); /* Setting vector spacing enables EI/VI mode */ @@ -2127,8 +2139,17 @@ void per_cpu_trap_init(bool is_boot_cpu) * We shouldn't trust a secondary core has a sane EBASE register * so use the one calculated by the boot CPU. */ - if (!is_boot_cpu) + if (!is_boot_cpu) { + /* If available, use WG to set top bits of EBASE */ + if (cpu_has_ebase_wg) { +#ifdef CONFIG_64BIT + write_c0_ebase_64(ebase | MIPS_EBASE_WG); +#else + write_c0_ebase(ebase | MIPS_EBASE_WG); +#endif + } write_c0_ebase(ebase); + } cp0_compare_irq_shift = CAUSEB_TI - CAUSEB_IP; cp0_compare_irq = (read_c0_intctl() >> INTCTLB_IPTI) & 7; @@ -2209,13 +2230,39 @@ void __init trap_init(void) if (cpu_has_veic || cpu_has_vint) { unsigned long size = 0x200 + VECTORSPACING*64; + phys_addr_t ebase_pa; + ebase = (unsigned long) __alloc_bootmem(size, 1 << fls(size), 0); + + /* + * Try to ensure ebase resides in KSeg0 if possible. + * + * It shouldn't generally be in XKPhys on MIPS64 to avoid + * hitting a poorly defined exception base for Cache Errors. + * The allocation is likely to be in the low 512MB of physical, + * in which case we should be able to convert to KSeg0. + * + * EVA is special though as it allows segments to be rearranged + * and to become uncached during cache error handling. + */ + ebase_pa = __pa(ebase); + if (!IS_ENABLED(CONFIG_EVA) && !WARN_ON(ebase_pa >= 0x20000000)) + ebase = CKSEG0ADDR(ebase_pa); } else { ebase = CAC_BASE; - if (cpu_has_mips_r2_r6) - ebase += (read_c0_ebase() & 0x3ffff000); + if (cpu_has_mips_r2_r6) { + if (cpu_has_ebase_wg) { +#ifdef CONFIG_64BIT + ebase = (read_c0_ebase_64() & ~0xfff); +#else + ebase = (read_c0_ebase() & ~0xfff); +#endif + } else { + ebase += (read_c0_ebase() & 0x3ffff000); + } + } } if (cpu_has_mmips) { diff --git a/arch/mips/kernel/uprobes.c b/arch/mips/kernel/uprobes.c index 4c7c1558944a..dbb917403131 100644 --- a/arch/mips/kernel/uprobes.c +++ b/arch/mips/kernel/uprobes.c @@ -8,71 +8,12 @@ #include <asm/branch.h> #include <asm/cpu-features.h> #include <asm/ptrace.h> -#include <asm/inst.h> + +#include "probes-common.h" static inline int insn_has_delay_slot(const union mips_instruction insn) { - switch (insn.i_format.opcode) { - /* - * jr and jalr are in r_format format. - */ - case spec_op: - switch (insn.r_format.func) { - case jalr_op: - case jr_op: - return 1; - } - break; - - /* - * This group contains: - * bltz_op, bgez_op, bltzl_op, bgezl_op, - * bltzal_op, bgezal_op, bltzall_op, bgezall_op. - */ - case bcond_op: - switch (insn.i_format.rt) { - case bltz_op: - case bltzl_op: - case bgez_op: - case bgezl_op: - case bltzal_op: - case bltzall_op: - case bgezal_op: - case bgezall_op: - case bposge32_op: - return 1; - } - break; - - /* - * These are unconditional and in j_format. - */ - case jal_op: - case j_op: - case beq_op: - case beql_op: - case bne_op: - case bnel_op: - case blez_op: /* not really i_format */ - case blezl_op: - case bgtz_op: - case bgtzl_op: - return 1; - - /* - * And now the FPA/cp1 branch instructions. - */ - case cop1_op: -#ifdef CONFIG_CPU_CAVIUM_OCTEON - case lwc2_op: /* This is bbit0 on Octeon */ - case ldc2_op: /* This is bbit032 on Octeon */ - case swc2_op: /* This is bbit1 on Octeon */ - case sdc2_op: /* This is bbit132 on Octeon */ -#endif - return 1; - } - - return 0; + return __insn_has_delay_slot(insn); } /** @@ -95,6 +36,12 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *aup, return -EINVAL; inst.word = aup->insn[0]; + + if (__insn_is_compact_branch(inst)) { + pr_notice("Uprobes for compact branches are not supported\n"); + return -EINVAL; + } + aup->ixol[0] = aup->insn[insn_has_delay_slot(inst)]; aup->ixol[1] = UPROBE_BRK_UPROBE_XOL; /* NOP */ @@ -282,19 +229,14 @@ int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, void __weak arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr, void *src, unsigned long len) { - void *kaddr; + unsigned long kaddr, kstart; /* Initialize the slot */ - kaddr = kmap_atomic(page); - memcpy(kaddr + (vaddr & ~PAGE_MASK), src, len); - kunmap_atomic(kaddr); - - /* - * The MIPS version of flush_icache_range will operate safely on - * user space addresses and more importantly, it doesn't require a - * VMA argument. - */ - flush_icache_range(vaddr, vaddr + len); + kaddr = (unsigned long)kmap_atomic(page); + kstart = kaddr + (vaddr & ~PAGE_MASK); + memcpy((void *)kstart, src, len); + flush_icache_range(kstart, kstart + len); + kunmap_atomic((void *)kaddr); } /** diff --git a/arch/mips/kvm/commpage.c b/arch/mips/kvm/commpage.c index a36b77e1705c..f43629979a0e 100644 --- a/arch/mips/kvm/commpage.c +++ b/arch/mips/kvm/commpage.c @@ -12,7 +12,6 @@ #include <linux/errno.h> #include <linux/err.h> -#include <linux/module.h> #include <linux/vmalloc.h> #include <linux/fs.h> #include <linux/bootmem.h> diff --git a/arch/mips/kvm/dyntrans.c b/arch/mips/kvm/dyntrans.c index d280894915ed..010cef240688 100644 --- a/arch/mips/kvm/dyntrans.c +++ b/arch/mips/kvm/dyntrans.c @@ -13,7 +13,6 @@ #include <linux/err.h> #include <linux/highmem.h> #include <linux/kvm_host.h> -#include <linux/module.h> #include <linux/vmalloc.h> #include <linux/fs.h> #include <linux/bootmem.h> @@ -45,8 +44,8 @@ static int kvm_mips_trans_replace(struct kvm_vcpu *vcpu, u32 *opc, } else if (KVM_GUEST_KSEGX((unsigned long) opc) == KVM_GUEST_KSEG23) { local_irq_save(flags); memcpy((void *)opc, (void *)&replace, sizeof(u32)); - local_flush_icache_range((unsigned long)opc, - (unsigned long)opc + 32); + __local_flush_icache_user_range((unsigned long)opc, + (unsigned long)opc + 32); local_irq_restore(flags); } else { kvm_err("%s: Invalid address: %p\n", __func__, opc); diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c index 4db4c0370859..8770f32c9e0b 100644 --- a/arch/mips/kvm/emulate.c +++ b/arch/mips/kvm/emulate.c @@ -13,7 +13,6 @@ #include <linux/err.h> #include <linux/ktime.h> #include <linux/kvm_host.h> -#include <linux/module.h> #include <linux/vmalloc.h> #include <linux/fs.h> #include <linux/bootmem.h> diff --git a/arch/mips/kvm/interrupt.c b/arch/mips/kvm/interrupt.c index ad28dac6b7e9..e88403b3dcdd 100644 --- a/arch/mips/kvm/interrupt.c +++ b/arch/mips/kvm/interrupt.c @@ -11,7 +11,6 @@ #include <linux/errno.h> #include <linux/err.h> -#include <linux/module.h> #include <linux/vmalloc.h> #include <linux/fs.h> #include <linux/bootmem.h> diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c index 3a5484f9aa50..3b20441f2beb 100644 --- a/arch/mips/kvm/trap_emul.c +++ b/arch/mips/kvm/trap_emul.c @@ -11,7 +11,6 @@ #include <linux/errno.h> #include <linux/err.h> -#include <linux/module.h> #include <linux/vmalloc.h> #include <linux/kvm_host.h> diff --git a/arch/mips/lantiq/xway/vmmc.c b/arch/mips/lantiq/xway/vmmc.c index 4625495f9230..577ec81b557d 100644 --- a/arch/mips/lantiq/xway/vmmc.c +++ b/arch/mips/lantiq/xway/vmmc.c @@ -6,7 +6,7 @@ * Copyright (C) 2012 John Crispin <john@phrozen.org> */ -#include <linux/module.h> +#include <linux/export.h> #include <linux/of_platform.h> #include <linux/of_gpio.h> #include <linux/dma-mapping.h> @@ -55,7 +55,6 @@ static const struct of_device_id vmmc_match[] = { { .compatible = "lantiq,vmmc-xway" }, {}, }; -MODULE_DEVICE_TABLE(of, vmmc_match); static struct platform_driver vmmc_driver = { .probe = vmmc_probe, @@ -64,5 +63,4 @@ static struct platform_driver vmmc_driver = { .of_match_table = vmmc_match, }, }; - -module_platform_driver(vmmc_driver); +builtin_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 71e518c1e7e7..f0a0f2d431b2 100644 --- a/arch/mips/lantiq/xway/xrx200_phy_fw.c +++ b/arch/mips/lantiq/xway/xrx200_phy_fw.c @@ -1,4 +1,7 @@ /* + * Lantiq XRX200 PHY Firmware Loader + * Author: John Crispin + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. @@ -8,7 +11,6 @@ #include <linux/delay.h> #include <linux/dma-mapping.h> -#include <linux/module.h> #include <linux/firmware.h> #include <linux/of_platform.h> @@ -100,7 +102,6 @@ static const struct of_device_id xway_phy_match[] = { { .compatible = "lantiq,phy-xrx200" }, {}, }; -MODULE_DEVICE_TABLE(of, xway_phy_match); static struct platform_driver xway_phy_driver = { .probe = xway_phy_fw_probe, @@ -109,9 +110,4 @@ static struct platform_driver xway_phy_driver = { .of_match_table = xway_phy_match, }, }; - -module_platform_driver(xway_phy_driver); - -MODULE_AUTHOR("John Crispin <john@phrozen.org>"); -MODULE_DESCRIPTION("Lantiq XRX200 PHY Firmware Loader"); -MODULE_LICENSE("GPL"); +builtin_platform_driver(xway_phy_driver); diff --git a/arch/mips/lib/ashldi3.c b/arch/mips/lib/ashldi3.c index 927dc94a030f..c3e22053d13e 100644 --- a/arch/mips/lib/ashldi3.c +++ b/arch/mips/lib/ashldi3.c @@ -1,4 +1,4 @@ -#include <linux/module.h> +#include <linux/export.h> #include "libgcc.h" diff --git a/arch/mips/lib/ashrdi3.c b/arch/mips/lib/ashrdi3.c index 9fdf1a598428..17456024873d 100644 --- a/arch/mips/lib/ashrdi3.c +++ b/arch/mips/lib/ashrdi3.c @@ -1,4 +1,4 @@ -#include <linux/module.h> +#include <linux/export.h> #include "libgcc.h" diff --git a/arch/mips/lib/bswapdi.c b/arch/mips/lib/bswapdi.c index e3e77aa52c95..a8114148f82a 100644 --- a/arch/mips/lib/bswapdi.c +++ b/arch/mips/lib/bswapdi.c @@ -1,4 +1,5 @@ -#include <linux/module.h> +#include <linux/export.h> +#include <linux/compiler.h> unsigned long long notrace __bswapdi2(unsigned long long u) { diff --git a/arch/mips/lib/bswapsi.c b/arch/mips/lib/bswapsi.c index 530a8afe6fda..106fd978317d 100644 --- a/arch/mips/lib/bswapsi.c +++ b/arch/mips/lib/bswapsi.c @@ -1,4 +1,5 @@ -#include <linux/module.h> +#include <linux/export.h> +#include <linux/compiler.h> unsigned int notrace __bswapsi2(unsigned int u) { diff --git a/arch/mips/lib/cmpdi2.c b/arch/mips/lib/cmpdi2.c index 06857da96993..9d849d8743c9 100644 --- a/arch/mips/lib/cmpdi2.c +++ b/arch/mips/lib/cmpdi2.c @@ -1,4 +1,4 @@ -#include <linux/module.h> +#include <linux/export.h> #include "libgcc.h" diff --git a/arch/mips/lib/delay.c b/arch/mips/lib/delay.c index 21d27c6819a2..2307a3cb2714 100644 --- a/arch/mips/lib/delay.c +++ b/arch/mips/lib/delay.c @@ -8,7 +8,7 @@ * Copyright (C) 1999, 2000 Silicon Graphics, Inc. * Copyright (C) 2007, 2014 Maciej W. Rozycki */ -#include <linux/module.h> +#include <linux/export.h> #include <linux/param.h> #include <linux/smp.h> #include <linux/stringify.h> diff --git a/arch/mips/lib/iomap-pci.c b/arch/mips/lib/iomap-pci.c index fd35daa45314..8ed3f25a9047 100644 --- a/arch/mips/lib/iomap-pci.c +++ b/arch/mips/lib/iomap-pci.c @@ -7,9 +7,11 @@ * written by Ralf Baechle <ralf@linux-mips.org> */ #include <linux/pci.h> -#include <linux/module.h> +#include <linux/export.h> #include <asm/io.h> +#ifdef CONFIG_PCI_DRIVERS_LEGACY + void __iomem *__pci_ioport_map(struct pci_dev *dev, unsigned long port, unsigned int nr) { @@ -40,6 +42,8 @@ void __iomem *__pci_ioport_map(struct pci_dev *dev, return (void __iomem *) (ctrl->io_map_base + port); } +#endif /* CONFIG_PCI_DRIVERS_LEGACY */ + void pci_iounmap(struct pci_dev *dev, void __iomem * addr) { iounmap(addr); diff --git a/arch/mips/lib/iomap.c b/arch/mips/lib/iomap.c index 8e7e378ce51c..9daa92428e23 100644 --- a/arch/mips/lib/iomap.c +++ b/arch/mips/lib/iomap.c @@ -6,7 +6,7 @@ * (C) Copyright 2007 MIPS Technologies, Inc. * written by Ralf Baechle <ralf@linux-mips.org> */ -#include <linux/module.h> +#include <linux/export.h> #include <asm/io.h> /* diff --git a/arch/mips/lib/lshrdi3.c b/arch/mips/lib/lshrdi3.c index 364547449c65..221167c1be55 100644 --- a/arch/mips/lib/lshrdi3.c +++ b/arch/mips/lib/lshrdi3.c @@ -1,4 +1,4 @@ -#include <linux/module.h> +#include <linux/export.h> #include "libgcc.h" diff --git a/arch/mips/lib/ucmpdi2.c b/arch/mips/lib/ucmpdi2.c index bd599f58234c..08067fa538f2 100644 --- a/arch/mips/lib/ucmpdi2.c +++ b/arch/mips/lib/ucmpdi2.c @@ -1,4 +1,4 @@ -#include <linux/module.h> +#include <linux/export.h> #include "libgcc.h" diff --git a/arch/mips/loongson32/Kconfig b/arch/mips/loongson32/Kconfig index 7704f20529d6..3c0c2f2096cd 100644 --- a/arch/mips/loongson32/Kconfig +++ b/arch/mips/loongson32/Kconfig @@ -19,6 +19,21 @@ config LOONGSON1_LS1B select USE_GENERIC_EARLY_PRINTK_8250 select COMMON_CLK +config LOONGSON1_LS1C + bool "Loongson LS1C board" + select CEVT_R4K if !MIPS_EXTERNAL_TIMER + select CSRC_R4K if !MIPS_EXTERNAL_TIMER + select SYS_HAS_CPU_LOONGSON1C + select DMA_NONCOHERENT + select BOOT_ELF32 + select IRQ_MIPS_CPU + select SYS_SUPPORTS_32BIT_KERNEL + select SYS_SUPPORTS_LITTLE_ENDIAN + select SYS_SUPPORTS_HIGHMEM + select SYS_SUPPORTS_MIPS16 + select SYS_HAS_EARLY_PRINTK + select USE_GENERIC_EARLY_PRINTK_8250 + select COMMON_CLK endchoice menuconfig CEVT_CSRC_LS1X diff --git a/arch/mips/loongson32/Makefile b/arch/mips/loongson32/Makefile index 5f4bd6e071ca..1ab2c5bbc066 100644 --- a/arch/mips/loongson32/Makefile +++ b/arch/mips/loongson32/Makefile @@ -9,3 +9,9 @@ obj-$(CONFIG_MACH_LOONGSON32) += common/ # obj-$(CONFIG_LOONGSON1_LS1B) += ls1b/ + +# +# Loongson LS1C board +# + +obj-$(CONFIG_LOONGSON1_LS1C) += ls1c/ diff --git a/arch/mips/loongson32/Platform b/arch/mips/loongson32/Platform index ebb6dc290f0a..ffe01c6d0037 100644 --- a/arch/mips/loongson32/Platform +++ b/arch/mips/loongson32/Platform @@ -5,3 +5,4 @@ cflags-$(CONFIG_CPU_LOONGSON1) += \ platform-$(CONFIG_MACH_LOONGSON32) += loongson32/ cflags-$(CONFIG_MACH_LOONGSON32) += -I$(srctree)/arch/mips/include/asm/mach-loongson32 load-$(CONFIG_LOONGSON1_LS1B) += 0xffffffff80100000 +load-$(CONFIG_LOONGSON1_LS1C) += 0xffffffff80100000 diff --git a/arch/mips/loongson32/common/irq.c b/arch/mips/loongson32/common/irq.c index 455a7704a90f..635a4abe1f48 100644 --- a/arch/mips/loongson32/common/irq.c +++ b/arch/mips/loongson32/common/irq.c @@ -62,12 +62,58 @@ static void ls1x_irq_unmask(struct irq_data *d) | (1 << bit), LS1X_INTC_INTIEN(n)); } +static int ls1x_irq_settype(struct irq_data *d, unsigned int type) +{ + unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f; + unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5; + + switch (type) { + case IRQ_TYPE_LEVEL_HIGH: + __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n)) + | (1 << bit), LS1X_INTC_INTPOL(n)); + __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n)) + & ~(1 << bit), LS1X_INTC_INTEDGE(n)); + break; + case IRQ_TYPE_LEVEL_LOW: + __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n)) + & ~(1 << bit), LS1X_INTC_INTPOL(n)); + __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n)) + & ~(1 << bit), LS1X_INTC_INTEDGE(n)); + break; + case IRQ_TYPE_EDGE_RISING: + __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n)) + | (1 << bit), LS1X_INTC_INTPOL(n)); + __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n)) + | (1 << bit), LS1X_INTC_INTEDGE(n)); + break; + case IRQ_TYPE_EDGE_FALLING: + __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n)) + & ~(1 << bit), LS1X_INTC_INTPOL(n)); + __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n)) + | (1 << bit), LS1X_INTC_INTEDGE(n)); + break; + case IRQ_TYPE_EDGE_BOTH: + __raw_writel(__raw_readl(LS1X_INTC_INTPOL(n)) + & ~(1 << bit), LS1X_INTC_INTPOL(n)); + __raw_writel(__raw_readl(LS1X_INTC_INTEDGE(n)) + | (1 << bit), LS1X_INTC_INTEDGE(n)); + break; + case IRQ_TYPE_NONE: + break; + default: + return -EINVAL; + } + + return 0; +} + static struct irq_chip ls1x_irq_chip = { .name = "LS1X-INTC", .irq_ack = ls1x_irq_ack, .irq_mask = ls1x_irq_mask, .irq_mask_ack = ls1x_irq_mask_ack, .irq_unmask = ls1x_irq_unmask, + .irq_set_type = ls1x_irq_settype, }; static void ls1x_irq_dispatch(int n) @@ -107,7 +153,7 @@ asmlinkage void plat_irq_dispatch(void) } -struct irqaction cascade_irqaction = { +static struct irqaction cascade_irqaction = { .handler = no_action, .name = "cascade", .flags = IRQF_NO_THREAD, @@ -120,7 +166,7 @@ static void __init ls1x_irq_init(int base) /* Disable interrupts and clear pending, * setup all IRQs as high level triggered */ - for (n = 0; n < 4; n++) { + for (n = 0; n < INTN; n++) { __raw_writel(0x0, LS1X_INTC_INTIEN(n)); __raw_writel(0xffffffff, LS1X_INTC_INTCLR(n)); __raw_writel(0xffffffff, LS1X_INTC_INTPOL(n)); @@ -129,7 +175,7 @@ static void __init ls1x_irq_init(int base) } - for (n = base; n < LS1X_IRQS; n++) { + for (n = base; n < NR_IRQS; n++) { irq_set_chip_and_handler(n, &ls1x_irq_chip, handle_level_irq); } @@ -138,6 +184,9 @@ static void __init ls1x_irq_init(int base) setup_irq(INT1_IRQ, &cascade_irqaction); setup_irq(INT2_IRQ, &cascade_irqaction); setup_irq(INT3_IRQ, &cascade_irqaction); +#if defined(CONFIG_LOONGSON1_LS1C) + setup_irq(INT4_IRQ, &cascade_irqaction); +#endif } void __init arch_init_irq(void) diff --git a/arch/mips/loongson32/common/platform.c b/arch/mips/loongson32/common/platform.c index f2c714d8fb60..beff0852c6a4 100644 --- a/arch/mips/loongson32/common/platform.c +++ b/arch/mips/loongson32/common/platform.c @@ -17,11 +17,16 @@ #include <linux/stmmac.h> #include <linux/usb/ehci_pdriver.h> +#include <platform.h> #include <loongson1.h> #include <cpufreq.h> #include <dma.h> #include <nand.h> +#define LS1X_RTC_CTRL ((void __iomem *)KSEG1ADDR(LS1X_RTC_BASE + 0x40)) +#define RTC_EXTCLK_OK (BIT(5) | BIT(8)) +#define RTC_EXTCLK_EN BIT(8) + /* 8250/16550 compatible UART */ #define LS1X_UART(_id) \ { \ @@ -65,6 +70,15 @@ void __init ls1x_serial_set_uartclk(struct platform_device *pdev) p->uartclk = clk_get_rate(clk); } +void __init ls1x_rtc_set_extclk(struct platform_device *pdev) +{ + u32 val; + + val = __raw_readl(LS1X_RTC_CTRL); + if (!(val & RTC_EXTCLK_OK)) + __raw_writel(val | RTC_EXTCLK_EN, LS1X_RTC_CTRL); +} + /* CPUFreq */ static struct plat_ls1x_cpufreq ls1x_cpufreq_pdata = { .clk_name = "cpu_clk", @@ -132,6 +146,7 @@ int ls1x_eth_mux_init(struct platform_device *pdev, void *priv) val = __raw_readl(LS1X_MUX_CTRL1); +#if defined(CONFIG_LOONGSON1_LS1B) plat_dat = dev_get_platdata(&pdev->dev); if (plat_dat->bus_id) { __raw_writel(__raw_readl(LS1X_MUX_CTRL0) | GMAC1_USE_UART1 | @@ -165,6 +180,17 @@ int ls1x_eth_mux_init(struct platform_device *pdev, void *priv) val &= ~GMAC0_SHUT; } __raw_writel(val, LS1X_MUX_CTRL1); +#elif defined(CONFIG_LOONGSON1_LS1C) + plat_dat = dev_get_platdata(&pdev->dev); + + val &= ~PHY_INTF_SELI; + if (plat_dat->interface == PHY_INTERFACE_MODE_RMII) + val |= 0x4 << PHY_INTF_SELI_SHIFT; + __raw_writel(val, LS1X_MUX_CTRL1); + + val = __raw_readl(LS1X_MUX_CTRL0); + __raw_writel(val & (~GMAC_SHUT), LS1X_MUX_CTRL0); +#endif return 0; } @@ -172,7 +198,11 @@ int ls1x_eth_mux_init(struct platform_device *pdev, void *priv) static struct plat_stmmacenet_data ls1x_eth0_pdata = { .bus_id = 0, .phy_addr = -1, +#if defined(CONFIG_LOONGSON1_LS1B) .interface = PHY_INTERFACE_MODE_MII, +#elif defined(CONFIG_LOONGSON1_LS1C) + .interface = PHY_INTERFACE_MODE_RMII, +#endif .mdio_bus_data = &ls1x_mdio_bus_data, .dma_cfg = &ls1x_eth_dma_cfg, .has_gmac = 1, @@ -203,6 +233,7 @@ struct platform_device ls1x_eth0_pdev = { }, }; +#ifdef CONFIG_LOONGSON1_LS1B static struct plat_stmmacenet_data ls1x_eth1_pdata = { .bus_id = 1, .phy_addr = -1, @@ -236,6 +267,7 @@ struct platform_device ls1x_eth1_pdev = { .platform_data = &ls1x_eth1_pdata, }, }; +#endif /* CONFIG_LOONGSON1_LS1B */ /* GPIO */ static struct resource ls1x_gpio0_resources[] = { diff --git a/arch/mips/loongson32/common/setup.c b/arch/mips/loongson32/common/setup.c index 62f41afee241..1640744288ee 100644 --- a/arch/mips/loongson32/common/setup.c +++ b/arch/mips/loongson32/common/setup.c @@ -22,7 +22,11 @@ const char *get_system_type(void) switch (processor_id & PRID_REV_MASK) { case PRID_REV_LOONGSON1B: +#if defined(CONFIG_LOONGSON1_LS1B) return "LOONGSON LS1B"; +#elif defined(CONFIG_LOONGSON1_LS1C) + return "LOONGSON LS1C"; +#endif default: return "LOONGSON (unknown)"; } diff --git a/arch/mips/loongson32/ls1c/Makefile b/arch/mips/loongson32/ls1c/Makefile new file mode 100644 index 000000000000..a92c6cd3418d --- /dev/null +++ b/arch/mips/loongson32/ls1c/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for loongson1C based machines. +# + +obj-y += board.o diff --git a/arch/mips/loongson32/ls1c/board.c b/arch/mips/loongson32/ls1c/board.c new file mode 100644 index 000000000000..a96bed5e3ea6 --- /dev/null +++ b/arch/mips/loongson32/ls1c/board.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2016 Yang Ling <gnaygnil@gmail.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <platform.h> + +static struct platform_device *ls1c_platform_devices[] __initdata = { + &ls1x_uart_pdev, + &ls1x_eth0_pdev, + &ls1x_rtc_pdev, +}; + +static int __init ls1c_platform_init(void) +{ + ls1x_serial_set_uartclk(&ls1x_uart_pdev); + ls1x_rtc_set_extclk(&ls1x_rtc_pdev); + + return platform_add_devices(ls1c_platform_devices, + ARRAY_SIZE(ls1c_platform_devices)); +} + +arch_initcall(ls1c_platform_init); diff --git a/arch/mips/mm/c-octeon.c b/arch/mips/mm/c-octeon.c index 05b1d7cf9514..0e45b061e514 100644 --- a/arch/mips/mm/c-octeon.c +++ b/arch/mips/mm/c-octeon.c @@ -294,6 +294,8 @@ void octeon_cache_init(void) flush_data_cache_page = octeon_flush_data_cache_page; flush_icache_range = octeon_flush_icache_range; local_flush_icache_range = local_octeon_flush_icache_range; + __flush_icache_user_range = octeon_flush_icache_range; + __local_flush_icache_user_range = local_octeon_flush_icache_range; __flush_kernel_vmap_range = octeon_flush_kernel_vmap_range; diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c index 135ec313c1f6..21e4e662c1fa 100644 --- a/arch/mips/mm/c-r3k.c +++ b/arch/mips/mm/c-r3k.c @@ -325,6 +325,8 @@ void r3k_cache_init(void) flush_cache_page = r3k_flush_cache_page; flush_icache_range = r3k_flush_icache_range; local_flush_icache_range = r3k_flush_icache_range; + __flush_icache_user_range = r3k_flush_icache_range; + __local_flush_icache_user_range = r3k_flush_icache_range; __flush_kernel_vmap_range = r3k_flush_kernel_vmap_range; diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index fa7d8d3790bf..88cfaf81c958 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -17,7 +17,7 @@ #include <linux/sched.h> #include <linux/smp.h> #include <linux/mm.h> -#include <linux/module.h> +#include <linux/export.h> #include <linux/bitops.h> #include <asm/bcache.h> @@ -722,11 +722,13 @@ struct flush_icache_range_args { unsigned long start; unsigned long end; unsigned int type; + bool user; }; static inline void __local_r4k_flush_icache_range(unsigned long start, unsigned long end, - unsigned int type) + unsigned int type, + bool user) { if (!cpu_has_ic_fills_f_dc) { if (type == R4K_INDEX || @@ -734,7 +736,10 @@ static inline void __local_r4k_flush_icache_range(unsigned long start, r4k_blast_dcache(); } else { R4600_HIT_CACHEOP_WAR_IMPL; - protected_blast_dcache_range(start, end); + if (user) + protected_blast_dcache_range(start, end); + else + blast_dcache_range(start, end); } } @@ -748,27 +753,25 @@ static inline void __local_r4k_flush_icache_range(unsigned long start, break; default: - protected_blast_icache_range(start, end); + if (user) + protected_blast_icache_range(start, end); + else + blast_icache_range(start, end); break; } } -#ifdef CONFIG_EVA - /* - * Due to all possible segment mappings, there might cache aliases - * caused by the bootloader being in non-EVA mode, and the CPU switching - * to EVA during early kernel init. It's best to flush the scache - * to avoid having secondary cores fetching stale data and lead to - * kernel crashes. - */ - bc_wback_inv(start, (end - start)); - __sync(); -#endif } static inline void local_r4k_flush_icache_range(unsigned long start, unsigned long end) { - __local_r4k_flush_icache_range(start, end, R4K_HIT | R4K_INDEX); + __local_r4k_flush_icache_range(start, end, R4K_HIT | R4K_INDEX, false); +} + +static inline void local_r4k_flush_icache_user_range(unsigned long start, + unsigned long end) +{ + __local_r4k_flush_icache_range(start, end, R4K_HIT | R4K_INDEX, true); } static inline void local_r4k_flush_icache_range_ipi(void *args) @@ -777,11 +780,13 @@ static inline void local_r4k_flush_icache_range_ipi(void *args) unsigned long start = fir_args->start; unsigned long end = fir_args->end; unsigned int type = fir_args->type; + bool user = fir_args->user; - __local_r4k_flush_icache_range(start, end, type); + __local_r4k_flush_icache_range(start, end, type, user); } -static void r4k_flush_icache_range(unsigned long start, unsigned long end) +static void __r4k_flush_icache_range(unsigned long start, unsigned long end, + bool user) { struct flush_icache_range_args args; unsigned long size, cache_size; @@ -789,6 +794,7 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) args.start = start; args.end = end; args.type = R4K_HIT | R4K_INDEX; + args.user = user; /* * Indexed cache ops require an SMP call. @@ -814,6 +820,16 @@ static void r4k_flush_icache_range(unsigned long start, unsigned long end) instruction_hazard(); } +static void r4k_flush_icache_range(unsigned long start, unsigned long end) +{ + return __r4k_flush_icache_range(start, end, false); +} + +static void r4k_flush_icache_user_range(unsigned long start, unsigned long end) +{ + return __r4k_flush_icache_range(start, end, true); +} + #if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_DMA_MAYBE_COHERENT) static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) @@ -1915,9 +1931,16 @@ void r4k_cache_init(void) flush_data_cache_page = r4k_flush_data_cache_page; flush_icache_range = r4k_flush_icache_range; local_flush_icache_range = local_r4k_flush_icache_range; + __flush_icache_user_range = r4k_flush_icache_user_range; + __local_flush_icache_user_range = local_r4k_flush_icache_user_range; #if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_DMA_MAYBE_COHERENT) - if (coherentio) { +# if defined(CONFIG_DMA_PERDEV_COHERENT) + if (0) { +# else + if ((coherentio == IO_COHERENCE_ENABLED) || + ((coherentio == IO_COHERENCE_DEFAULT) && hw_coherentio)) { +# endif _dma_cache_wback_inv = (void *)cache_noop; _dma_cache_wback = (void *)cache_noop; _dma_cache_inv = (void *)cache_noop; diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c index 596e18458e04..5c282583edf1 100644 --- a/arch/mips/mm/c-tx39.c +++ b/arch/mips/mm/c-tx39.c @@ -411,6 +411,9 @@ void tx39_cache_init(void) break; } + __flush_icache_user_range = flush_icache_range; + __local_flush_icache_user_range = local_flush_icache_range; + current_cpu_data.icache.waysize = icache_size / current_cpu_data.icache.ways; current_cpu_data.dcache.waysize = dcache_size / current_cpu_data.dcache.ways; diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index bf04c6c479a4..6db341347202 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -10,7 +10,7 @@ #include <linux/fcntl.h> #include <linux/kernel.h> #include <linux/linkage.h> -#include <linux/module.h> +#include <linux/export.h> #include <linux/sched.h> #include <linux/syscalls.h> #include <linux/mm.h> @@ -33,6 +33,10 @@ void (*flush_icache_range)(unsigned long start, unsigned long end); EXPORT_SYMBOL_GPL(flush_icache_range); void (*local_flush_icache_range)(unsigned long start, unsigned long end); EXPORT_SYMBOL_GPL(local_flush_icache_range); +void (*__flush_icache_user_range)(unsigned long start, unsigned long end); +EXPORT_SYMBOL_GPL(__flush_icache_user_range); +void (*__local_flush_icache_user_range)(unsigned long start, unsigned long end); +EXPORT_SYMBOL_GPL(__local_flush_icache_user_range); void (*__flush_cache_vmap)(void); void (*__flush_cache_vunmap)(void); @@ -74,7 +78,7 @@ SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, bytes, if (!access_ok(VERIFY_WRITE, (void __user *) addr, bytes)) return -EFAULT; - flush_icache_range(addr, addr + bytes); + __flush_icache_user_range(addr, addr + bytes); return 0; } diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index b2eadd6fa9a1..46d5696c4f27 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -11,7 +11,7 @@ #include <linux/types.h> #include <linux/dma-mapping.h> #include <linux/mm.h> -#include <linux/module.h> +#include <linux/export.h> #include <linux/scatterlist.h> #include <linux/string.h> #include <linux/gfp.h> @@ -24,14 +24,15 @@ #include <dma-coherence.h> -#ifdef CONFIG_DMA_MAYBE_COHERENT -int coherentio = 0; /* User defined DMA coherency from command line. */ +#if defined(CONFIG_DMA_MAYBE_COHERENT) && !defined(CONFIG_DMA_PERDEV_COHERENT) +/* User defined DMA coherency from command line. */ +enum coherent_io_user_state coherentio = IO_COHERENCE_DEFAULT; EXPORT_SYMBOL_GPL(coherentio); int hw_coherentio = 0; /* Actual hardware supported DMA coherency setting. */ static int __init setcoherentio(char *str) { - coherentio = 1; + coherentio = IO_COHERENCE_ENABLED; pr_info("Hardware DMA cache coherency (command line)\n"); return 0; } @@ -39,7 +40,7 @@ early_param("coherentio", setcoherentio); static int __init setnocoherentio(char *str) { - coherentio = 0; + coherentio = IO_COHERENCE_DISABLED; pr_info("Software DMA cache coherency (command line)\n"); return 0; } @@ -160,8 +161,7 @@ static void *mips_dma_alloc_coherent(struct device *dev, size_t size, *dma_handle = plat_map_dma_mem(dev, ret, size); if (!plat_device_is_coherent(dev)) { dma_cache_wback_inv((unsigned long) ret, size); - if (!hw_coherentio) - ret = UNCAC_ADDR(ret); + ret = UNCAC_ADDR(ret); } return ret; @@ -189,7 +189,7 @@ static void mips_dma_free_coherent(struct device *dev, size_t size, void *vaddr, plat_unmap_dma_mem(dev, dma_handle, size, DMA_BIDIRECTIONAL); - if (!plat_device_is_coherent(dev) && !hw_coherentio) + if (!plat_device_is_coherent(dev)) addr = CAC_ADDR(addr); page = virt_to_page((void *) addr); @@ -209,7 +209,7 @@ static int mips_dma_mmap(struct device *dev, struct vm_area_struct *vma, unsigned long pfn; int ret = -ENXIO; - if (!plat_device_is_coherent(dev) && !hw_coherentio) + if (!plat_device_is_coherent(dev)) addr = CAC_ADDR(addr); pfn = page_to_pfn(virt_to_page((void *)addr)); diff --git a/arch/mips/mm/extable.c b/arch/mips/mm/extable.c index 9d25d2ba4b9e..e474fa2efed4 100644 --- a/arch/mips/mm/extable.c +++ b/arch/mips/mm/extable.c @@ -5,7 +5,7 @@ * * Copyright (C) 1997, 99, 2001 - 2004 Ralf Baechle <ralf@linux-mips.org> */ -#include <linux/module.h> +#include <linux/extable.h> #include <linux/spinlock.h> #include <asm/branch.h> #include <asm/uaccess.h> diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index 9560ad731120..d56a855828c2 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c @@ -18,7 +18,6 @@ #include <linux/mman.h> #include <linux/mm.h> #include <linux/smp.h> -#include <linux/module.h> #include <linux/kprobes.h> #include <linux/perf_event.h> #include <linux/uaccess.h> diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c index d7258a103439..f13f51003bd8 100644 --- a/arch/mips/mm/highmem.c +++ b/arch/mips/mm/highmem.c @@ -1,5 +1,6 @@ #include <linux/compiler.h> -#include <linux/module.h> +#include <linux/init.h> +#include <linux/export.h> #include <linux/highmem.h> #include <linux/sched.h> #include <linux/smp.h> diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 72f7478ee068..3a6edecc3f38 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -10,7 +10,7 @@ */ #include <linux/bug.h> #include <linux/init.h> -#include <linux/module.h> +#include <linux/export.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/smp.h> diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c index 8d5008cbdc0f..1f189627440f 100644 --- a/arch/mips/mm/ioremap.c +++ b/arch/mips/mm/ioremap.c @@ -6,7 +6,7 @@ * (C) Copyright 1995 1996 Linus Torvalds * (C) Copyright 2001, 2002 Ralf Baechle */ -#include <linux/module.h> +#include <linux/export.h> #include <asm/addrspace.h> #include <asm/byteorder.h> #include <linux/sched.h> diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c index 353037699512..d08ea3ff0f53 100644 --- a/arch/mips/mm/mmap.c +++ b/arch/mips/mm/mmap.c @@ -10,7 +10,7 @@ #include <linux/errno.h> #include <linux/mm.h> #include <linux/mman.h> -#include <linux/module.h> +#include <linux/export.h> #include <linux/personality.h> #include <linux/random.h> #include <linux/sched.h> diff --git a/arch/mips/mm/page.c b/arch/mips/mm/page.c index c41953ca6605..6f804f5960ab 100644 --- a/arch/mips/mm/page.c +++ b/arch/mips/mm/page.c @@ -12,7 +12,6 @@ #include <linux/sched.h> #include <linux/smp.h> #include <linux/mm.h> -#include <linux/module.h> #include <linux/proc_fs.h> #include <asm/bugs.h> diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index e8b335c16295..bba9c1484b41 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -14,7 +14,7 @@ #include <linux/smp.h> #include <linux/mm.h> #include <linux/hugetlb.h> -#include <linux/module.h> +#include <linux/export.h> #include <asm/cpu.h> #include <asm/cpu-type.h> @@ -67,8 +67,11 @@ void local_flush_tlb_all(void) entry = read_c0_wired(); - /* Blast 'em all away. */ - if (cpu_has_tlbinv) { + /* + * Blast 'em all away. + * If there are any wired entries, fall back to iterating + */ + if (cpu_has_tlbinv && !entry) { if (current_cpu_data.tlbsizevtlb) { write_c0_index(0); mtc0_tlbw_hazard(); diff --git a/arch/mips/mti-malta/malta-dt.c b/arch/mips/mti-malta/malta-dt.c index 47a22889285f..4822943100f3 100644 --- a/arch/mips/mti-malta/malta-dt.c +++ b/arch/mips/mti-malta/malta-dt.c @@ -17,18 +17,3 @@ void __init device_tree_init(void) { unflatten_and_copy_device_tree(); } - -static const struct of_device_id bus_ids[] __initconst = { - { .compatible = "simple-bus", }, - { .compatible = "isa", }, - {}, -}; - -static int __init publish_devices(void) -{ - if (!of_have_populated_dt()) - return 0; - - return of_platform_bus_probe(NULL, bus_ids, NULL); -} -device_initcall(publish_devices); diff --git a/arch/mips/mti-malta/malta-dtshim.c b/arch/mips/mti-malta/malta-dtshim.c index 151f4882ec8a..c398582c316f 100644 --- a/arch/mips/mti-malta/malta-dtshim.c +++ b/arch/mips/mti-malta/malta-dtshim.c @@ -13,18 +13,66 @@ #include <linux/libfdt.h> #include <linux/of_fdt.h> #include <linux/sizes.h> +#include <asm/addrspace.h> #include <asm/bootinfo.h> #include <asm/fw/fw.h> +#include <asm/mips-boards/generic.h> +#include <asm/mips-boards/malta.h> +#include <asm/mips-cm.h> #include <asm/page.h> +#define ROCIT_REG_BASE 0x1f403000 +#define ROCIT_CONFIG_GEN1 (ROCIT_REG_BASE + 0x04) +#define ROCIT_CONFIG_GEN1_MEMMAP_SHIFT 8 +#define ROCIT_CONFIG_GEN1_MEMMAP_MASK (0xf << 8) + static unsigned char fdt_buf[16 << 10] __initdata; /* determined physical memory size, not overridden by command line args */ extern unsigned long physical_memsize; -#define MAX_MEM_ARRAY_ENTRIES 1 +enum mem_map { + MEM_MAP_V1 = 0, + MEM_MAP_V2, +}; + +#define MAX_MEM_ARRAY_ENTRIES 2 -static unsigned __init gen_fdt_mem_array(__be32 *mem_array, unsigned long size) +static __init int malta_scon(void) +{ + int scon = MIPS_REVISION_SCONID; + + if (scon != MIPS_REVISION_SCON_OTHER) + return scon; + + switch (MIPS_REVISION_CORID) { + case MIPS_REVISION_CORID_QED_RM5261: + case MIPS_REVISION_CORID_CORE_LV: + case MIPS_REVISION_CORID_CORE_FPGA: + case MIPS_REVISION_CORID_CORE_FPGAR2: + return MIPS_REVISION_SCON_GT64120; + + case MIPS_REVISION_CORID_CORE_EMUL_BON: + case MIPS_REVISION_CORID_BONITO64: + case MIPS_REVISION_CORID_CORE_20K: + return MIPS_REVISION_SCON_BONITO; + + case MIPS_REVISION_CORID_CORE_MSC: + case MIPS_REVISION_CORID_CORE_FPGA2: + case MIPS_REVISION_CORID_CORE_24K: + return MIPS_REVISION_SCON_SOCIT; + + case MIPS_REVISION_CORID_CORE_FPGA3: + case MIPS_REVISION_CORID_CORE_FPGA4: + case MIPS_REVISION_CORID_CORE_FPGA5: + case MIPS_REVISION_CORID_CORE_EMUL_MSC: + default: + return MIPS_REVISION_SCON_ROCIT; + } +} + +static unsigned __init gen_fdt_mem_array(__be32 *mem_array, unsigned long size, + enum mem_map map) { unsigned long size_preio; unsigned entries; @@ -39,11 +87,47 @@ static unsigned __init gen_fdt_mem_array(__be32 *mem_array, unsigned long size) * DDR but limits it to 2GB. */ mem_array[1] = cpu_to_be32(size); + goto done; + } + + size_preio = min_t(unsigned long, size, SZ_256M); + mem_array[1] = cpu_to_be32(size_preio); + size -= size_preio; + if (!size) + goto done; + + if (map == MEM_MAP_V2) { + /* + * We have a flat 32 bit physical memory map with DDR filling + * all 4GB of the memory map, apart from the I/O region which + * obscures 256MB from 0x10000000-0x1fffffff. + * + * Therefore we discard the 256MB behind the I/O region. + */ + if (size <= SZ_256M) + goto done; + size -= SZ_256M; + + /* Make use of the memory following the I/O region */ + entries++; + mem_array[2] = cpu_to_be32(PHYS_OFFSET + SZ_512M); + mem_array[3] = cpu_to_be32(size); } else { - size_preio = min_t(unsigned long, size, SZ_256M); - mem_array[1] = cpu_to_be32(size_preio); + /* + * We have a 32 bit physical memory map with a 2GB DDR region + * aliased in the upper & lower halves of it. The I/O region + * obscures 256MB from 0x10000000-0x1fffffff in the low alias + * but the DDR it obscures is accessible via the high alias. + * + * Simply access everything beyond the lowest 256MB of DDR using + * the high alias. + */ + entries++; + mem_array[2] = cpu_to_be32(PHYS_OFFSET + SZ_2G + SZ_256M); + mem_array[3] = cpu_to_be32(size); } +done: BUG_ON(entries > MAX_MEM_ARRAY_ENTRIES); return entries; } @@ -54,6 +138,8 @@ static void __init append_memory(void *fdt, int root_off) unsigned long memsize; unsigned mem_entries; int i, err, mem_off; + enum mem_map mem_map; + u32 config; char *var, param_name[10], *var_names[] = { "ememsize", "memsize", }; @@ -106,6 +192,20 @@ static void __init append_memory(void *fdt, int root_off) /* if the user says there's more RAM than we thought, believe them */ physical_memsize = max_t(unsigned long, physical_memsize, memsize); + /* detect the memory map in use */ + if (malta_scon() == MIPS_REVISION_SCON_ROCIT) { + /* ROCit has a register indicating the memory map in use */ + config = readl((void __iomem *)CKSEG1ADDR(ROCIT_CONFIG_GEN1)); + mem_map = config & ROCIT_CONFIG_GEN1_MEMMAP_MASK; + mem_map >>= ROCIT_CONFIG_GEN1_MEMMAP_SHIFT; + } else { + /* if not using ROCit, presume the v1 memory map */ + mem_map = MEM_MAP_V1; + } + if (mem_map > MEM_MAP_V2) + panic("Unsupported physical memory map v%u detected", + (unsigned int)mem_map); + /* append memory to the DT */ mem_off = fdt_add_subnode(fdt, root_off, "memory"); if (mem_off < 0) @@ -115,19 +215,93 @@ static void __init append_memory(void *fdt, int root_off) if (err) panic("Unable to set memory node device_type: %d", err); - mem_entries = gen_fdt_mem_array(mem_array, physical_memsize); + mem_entries = gen_fdt_mem_array(mem_array, physical_memsize, mem_map); err = fdt_setprop(fdt, mem_off, "reg", mem_array, mem_entries * 2 * sizeof(mem_array[0])); if (err) panic("Unable to set memory regs property: %d", err); - mem_entries = gen_fdt_mem_array(mem_array, memsize); + mem_entries = gen_fdt_mem_array(mem_array, memsize, mem_map); err = fdt_setprop(fdt, mem_off, "linux,usable-memory", mem_array, mem_entries * 2 * sizeof(mem_array[0])); if (err) panic("Unable to set linux,usable-memory property: %d", err); } +static void __init remove_gic(void *fdt) +{ + int err, gic_off, i8259_off, cpu_off; + void __iomem *biu_base; + uint32_t cpu_phandle, sc_cfg; + + /* if we have a CM which reports a GIC is present, leave the DT alone */ + err = mips_cm_probe(); + if (!err && (read_gcr_gic_status() & CM_GCR_GIC_STATUS_GICEX_MSK)) + return; + + if (malta_scon() == MIPS_REVISION_SCON_ROCIT) { + /* + * On systems using the RocIT system controller a GIC may be + * present without a CM. Detect whether that is the case. + */ + biu_base = ioremap_nocache(MSC01_BIU_REG_BASE, + MSC01_BIU_ADDRSPACE_SZ); + sc_cfg = __raw_readl(biu_base + MSC01_SC_CFG_OFS); + if (sc_cfg & MSC01_SC_CFG_GICPRES_MSK) { + /* enable the GIC at the system controller level */ + sc_cfg |= BIT(MSC01_SC_CFG_GICENA_SHF); + __raw_writel(sc_cfg, biu_base + MSC01_SC_CFG_OFS); + return; + } + } + + gic_off = fdt_node_offset_by_compatible(fdt, -1, "mti,gic"); + if (gic_off < 0) { + pr_warn("malta-dtshim: unable to find DT GIC node: %d\n", + gic_off); + return; + } + + err = fdt_nop_node(fdt, gic_off); + if (err) + pr_warn("malta-dtshim: unable to nop GIC node\n"); + + i8259_off = fdt_node_offset_by_compatible(fdt, -1, "intel,i8259"); + if (i8259_off < 0) { + pr_warn("malta-dtshim: unable to find DT i8259 node: %d\n", + i8259_off); + return; + } + + cpu_off = fdt_node_offset_by_compatible(fdt, -1, + "mti,cpu-interrupt-controller"); + if (cpu_off < 0) { + pr_warn("malta-dtshim: unable to find CPU intc node: %d\n", + cpu_off); + return; + } + + cpu_phandle = fdt_get_phandle(fdt, cpu_off); + if (!cpu_phandle) { + pr_warn("malta-dtshim: unable to get CPU intc phandle\n"); + return; + } + + err = fdt_setprop_u32(fdt, i8259_off, "interrupt-parent", cpu_phandle); + if (err) { + pr_warn("malta-dtshim: unable to set i8259 interrupt-parent: %d\n", + err); + return; + } + + err = fdt_setprop_u32(fdt, i8259_off, "interrupts", 2); + if (err) { + pr_warn("malta-dtshim: unable to set i8259 interrupts: %d\n", + err); + return; + } +} + void __init *malta_dt_shim(void *fdt) { int root_off, len, err; @@ -153,6 +327,7 @@ void __init *malta_dt_shim(void *fdt) return fdt; append_memory(fdt_buf, root_off); + remove_gic(fdt_buf); err = fdt_pack(fdt_buf); if (err) diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c index dc2c5214809d..0f3b881a3190 100644 --- a/arch/mips/mti-malta/malta-init.c +++ b/arch/mips/mti-malta/malta-init.c @@ -14,6 +14,7 @@ #include <linux/init.h> #include <linux/string.h> #include <linux/kernel.h> +#include <linux/pci_regs.h> #include <linux/serial_core.h> #include <asm/cacheflush.h> @@ -242,23 +243,19 @@ mips_pci_controller: MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF | MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF); #endif -#ifndef CONFIG_EVA - /* Fix up target memory mapping. */ - MSC_READ(MSC01_PCI_BAR0, mask); - MSC_WRITE(MSC01_PCI_P2SCMSKL, mask & MSC01_PCI_BAR0_SIZE_MSK); -#else + /* * Setup the Malta max (2GB) memory for PCI DMA in host bridge - * in transparent addressing mode, starting from 0x80000000. + * in transparent addressing mode. */ - mask = PHYS_OFFSET | (1<<3); + mask = PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_PREFETCH; MSC_WRITE(MSC01_PCI_BAR0, mask); - - mask = PHYS_OFFSET; MSC_WRITE(MSC01_PCI_HEAD4, mask); + + mask &= MSC01_PCI_BAR0_SIZE_MSK; MSC_WRITE(MSC01_PCI_P2SCMSKL, mask); MSC_WRITE(MSC01_PCI_P2SCMAPL, mask); -#endif + /* Don't handle target retries indefinitely. */ if ((data & MSC01_PCI_CFG_MAXRTRY_MSK) == MSC01_PCI_CFG_MAXRTRY_MSK) diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index c6a6c7afddab..cb675ec6f283 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c @@ -14,11 +14,13 @@ */ #include <linux/init.h> #include <linux/irq.h> +#include <linux/irqchip.h> #include <linux/sched.h> #include <linux/smp.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/irqchip/mips-gic.h> +#include <linux/of_irq.h> #include <linux/kernel_stat.h> #include <linux/kernel.h> #include <linux/random.h> @@ -37,10 +39,6 @@ #include <asm/setup.h> #include <asm/rtlx.h> -static void __iomem *_msc01_biu_base; - -static DEFINE_RAW_SPINLOCK(mips_irq_lock); - static inline int mips_pcibios_iack(void) { int irq; @@ -85,49 +83,6 @@ static inline int mips_pcibios_iack(void) return irq; } -static inline int get_int(void) -{ - unsigned long flags; - int irq; - raw_spin_lock_irqsave(&mips_irq_lock, flags); - - irq = mips_pcibios_iack(); - - /* - * The only way we can decide if an interrupt is spurious - * is by checking the 8259 registers. This needs a spinlock - * on an SMP system, so leave it up to the generic code... - */ - - raw_spin_unlock_irqrestore(&mips_irq_lock, flags); - - return irq; -} - -static void malta_hw0_irqdispatch(void) -{ - int irq; - - irq = get_int(); - if (irq < 0) { - /* interrupt has already been cleared */ - return; - } - - do_IRQ(MALTA_INT_BASE + irq); - -#ifdef CONFIG_MIPS_VPE_APSP_API_MT - if (aprp_hook) - aprp_hook(); -#endif -} - -static irqreturn_t i8259_handler(int irq, void *dev_id) -{ - malta_hw0_irqdispatch(); - return IRQ_HANDLED; -} - static void corehi_irqdispatch(void) { unsigned int intedge, intsteer, pcicmd, pcibadaddr; @@ -240,12 +195,6 @@ static struct irqaction irq_call = { }; #endif /* CONFIG_MIPS_MT_SMP */ -static struct irqaction i8259irq = { - .handler = i8259_handler, - .name = "XT-PIC cascade", - .flags = IRQF_NO_THREAD, -}; - static struct irqaction corehi_irqaction = { .handler = corehi_handler, .name = "CoreHi", @@ -281,28 +230,10 @@ void __init arch_init_ipiirq(int irq, struct irqaction *action) void __init arch_init_irq(void) { - int corehi_irq, i8259_irq; - - init_i8259_irqs(); + int corehi_irq; - if (!cpu_has_veic) - mips_cpu_irq_init(); - - if (mips_cm_present()) { - write_gcr_gic_base(GIC_BASE_ADDR | CM_GCR_GIC_BASE_GICEN_MSK); - gic_present = 1; - } else { - if (mips_revision_sconid == MIPS_REVISION_SCON_ROCIT) { - _msc01_biu_base = ioremap_nocache(MSC01_BIU_REG_BASE, - MSC01_BIU_ADDRSPACE_SZ); - gic_present = - (__raw_readl(_msc01_biu_base + MSC01_SC_CFG_OFS) & - MSC01_SC_CFG_GICPRES_MSK) >> - MSC01_SC_CFG_GICPRES_SHF; - } - } - if (gic_present) - pr_debug("GIC present\n"); + i8259_set_poll(mips_pcibios_iack); + irqchip_init(); switch (mips_revision_sconid) { case MIPS_REVISION_SCON_SOCIT: @@ -330,18 +261,6 @@ void __init arch_init_irq(void) } if (gic_present) { - int i; - - gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, MIPSCPU_INT_GIC, - MIPS_GIC_IRQ_BASE); - if (!mips_cm_present()) { - /* Enable the GIC */ - i = __raw_readl(_msc01_biu_base + MSC01_SC_CFG_OFS); - __raw_writel(i | (0x1 << MSC01_SC_CFG_GICENA_SHF), - _msc01_biu_base + MSC01_SC_CFG_OFS); - pr_debug("GIC Enabled\n"); - } - i8259_irq = MIPS_GIC_IRQ_BASE + GIC_INT_I8259A; corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI; } else { #if defined(CONFIG_MIPS_MT_SMP) @@ -361,33 +280,13 @@ void __init arch_init_irq(void) arch_init_ipiirq(cpu_ipi_call_irq, &irq_call); #endif if (cpu_has_veic) { - set_vi_handler(MSC01E_INT_I8259A, - malta_hw0_irqdispatch); set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch); - i8259_irq = MSC01E_INT_BASE + MSC01E_INT_I8259A; corehi_irq = MSC01E_INT_BASE + MSC01E_INT_COREHI; } else { - i8259_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_I8259A; corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI; } } - setup_irq(i8259_irq, &i8259irq); setup_irq(corehi_irq, &corehi_irqaction); } - -void malta_be_init(void) -{ - /* Could change CM error mask register. */ -} - -int malta_be_handler(struct pt_regs *regs, int is_fixup) -{ - /* This duplicates the handling in do_be which seems wrong */ - int retval = is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL; - - mips_cm_error_report(); - - return retval; -} diff --git a/arch/mips/mti-malta/malta-platform.c b/arch/mips/mti-malta/malta-platform.c index e1dd1c1d3fde..516e1233d771 100644 --- a/arch/mips/mti-malta/malta-platform.c +++ b/arch/mips/mti-malta/malta-platform.c @@ -23,14 +23,10 @@ */ #include <linux/init.h> #include <linux/serial_8250.h> -#include <linux/mc146818rtc.h> #include <linux/module.h> #include <linux/irq.h> -#include <linux/mtd/partitions.h> -#include <linux/mtd/physmap.h> #include <linux/platform_device.h> #include <asm/mips-boards/maltaint.h> -#include <mtd/mtd-abi.h> #define SMC_PORT(base, int) \ { \ @@ -68,80 +64,13 @@ static struct platform_device malta_uart8250_device = { }, }; -struct resource malta_rtc_resources[] = { - { - .start = RTC_PORT(0), - .end = RTC_PORT(7), - .flags = IORESOURCE_IO, - }, { - .start = RTC_IRQ, - .end = RTC_IRQ, - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device malta_rtc_device = { - .name = "rtc_cmos", - .id = -1, - .resource = malta_rtc_resources, - .num_resources = ARRAY_SIZE(malta_rtc_resources), -}; - -static struct mtd_partition malta_mtd_partitions[] = { - { - .name = "YAMON", - .offset = 0x0, - .size = 0x100000, - .mask_flags = MTD_WRITEABLE - }, { - .name = "User FS", - .offset = 0x100000, - .size = 0x2e0000 - }, { - .name = "Board Config", - .offset = 0x3e0000, - .size = 0x020000, - .mask_flags = MTD_WRITEABLE - } -}; - -static struct physmap_flash_data malta_flash_data = { - .width = 4, - .nr_parts = ARRAY_SIZE(malta_mtd_partitions), - .parts = malta_mtd_partitions -}; - -static struct resource malta_flash_resource = { - .start = 0x1e000000, - .end = 0x1e3fffff, - .flags = IORESOURCE_MEM -}; - -static struct platform_device malta_flash_device = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &malta_flash_data, - }, - .num_resources = 1, - .resource = &malta_flash_resource, -}; - static struct platform_device *malta_devices[] __initdata = { &malta_uart8250_device, - &malta_rtc_device, - &malta_flash_device, }; static int __init malta_add_devices(void) { - int err; - - err = platform_add_devices(malta_devices, ARRAY_SIZE(malta_devices)); - if (err) - return err; - - return 0; + return platform_add_devices(malta_devices, ARRAY_SIZE(malta_devices)); } device_initcall(malta_add_devices); diff --git a/arch/mips/mti-malta/malta-reset.c b/arch/mips/mti-malta/malta-reset.c index 2fd2cc2c5034..dd6f62ad4417 100644 --- a/arch/mips/mti-malta/malta-reset.c +++ b/arch/mips/mti-malta/malta-reset.c @@ -8,38 +8,21 @@ */ #include <linux/io.h> #include <linux/pm.h> +#include <linux/reboot.h> #include <asm/reboot.h> #include <asm/mach-malta/malta-pm.h> -#define SOFTRES_REG 0x1f000500 -#define GORESET 0x42 - -static void mips_machine_restart(char *command) -{ - unsigned int __iomem *softres_reg = - ioremap(SOFTRES_REG, sizeof(unsigned int)); - - __raw_writel(GORESET, softres_reg); -} - -static void mips_machine_halt(void) -{ - while (true); -} - static void mips_machine_power_off(void) { mips_pm_suspend(PIIX4_FUNC3IO_PMCNTRL_SUS_TYP_SOFF); pr_info("Failed to power down, resetting\n"); - mips_machine_restart(NULL); + machine_restart(NULL); } static int __init mips_reboot_setup(void) { - _machine_restart = mips_machine_restart; - _machine_halt = mips_machine_halt; pm_power_off = mips_machine_power_off; return 0; diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c index 7e7364b0501e..a01d5debfcaf 100644 --- a/arch/mips/mti-malta/malta-setup.c +++ b/arch/mips/mti-malta/malta-setup.c @@ -42,9 +42,6 @@ #define ROCIT_CONFIG_GEN0 0x1f403000 #define ROCIT_CONFIG_GEN0_PCI_IOCU BIT(7) -extern void malta_be_init(void); -extern int malta_be_handler(struct pt_regs *regs, int is_fixup); - static struct resource standard_io_resources[] = { { .name = "dma1", @@ -154,12 +151,12 @@ static void __init plat_setup_iocoherency(void) * coherency instead. */ if (plat_enable_iocoherency()) { - if (coherentio == 0) + if (coherentio == IO_COHERENCE_DISABLED) pr_info("Hardware DMA cache coherency disabled\n"); else pr_info("Hardware DMA cache coherency enabled\n"); } else { - if (coherentio == 1) + if (coherentio == IO_COHERENCE_ENABLED) pr_info("Hardware DMA cache coherency unsupported, but enabled from command line!\n"); else pr_info("Software DMA cache coherency enabled\n"); @@ -301,7 +298,4 @@ void __init plat_mem_setup(void) #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) screen_info_setup(); #endif - - board_be_init = malta_be_init; - board_be_handler = malta_be_handler; } diff --git a/arch/mips/mti-sead3/Makefile b/arch/mips/mti-sead3/Makefile deleted file mode 100644 index 7a584e0bf933..000000000000 --- a/arch/mips/mti-sead3/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# -# Carsten Langgaard, carstenl@mips.com -# Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. -# -# Copyright (C) 2008 Wind River Systems, Inc. -# written by Ralf Baechle <ralf@linux-mips.org> -# -# Copyright (C) 2012 MIPS Technoligies, Inc. All rights reserved. -# Steven J. Hill <sjhill@mips.com> -# -obj-y := sead3-lcd.o sead3-display.o sead3-init.o \ - sead3-int.o sead3-platform.o sead3-reset.o \ - sead3-setup.o sead3-time.o - -obj-$(CONFIG_EARLY_PRINTK) += sead3-console.o diff --git a/arch/mips/mti-sead3/Platform b/arch/mips/mti-sead3/Platform deleted file mode 100644 index 387092427145..000000000000 --- a/arch/mips/mti-sead3/Platform +++ /dev/null @@ -1,7 +0,0 @@ -# -# MIPS SEAD-3 board -# -platform-$(CONFIG_MIPS_SEAD3) += mti-sead3/ -cflags-$(CONFIG_MIPS_SEAD3) += -I$(srctree)/arch/mips/include/asm/mach-sead3 -load-$(CONFIG_MIPS_SEAD3) += 0xffffffff80100000 -all-$(CONFIG_MIPS_SEAD3) := $(COMPRESSION_FNAME).srec diff --git a/arch/mips/mti-sead3/sead3-console.c b/arch/mips/mti-sead3/sead3-console.c deleted file mode 100644 index 031f47d69770..000000000000 --- a/arch/mips/mti-sead3/sead3-console.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - */ -#include <linux/init.h> -#include <linux/console.h> -#include <linux/serial_reg.h> -#include <linux/io.h> - -#define SEAD_UART1_REGS_BASE 0xbf000800 /* ttyS1 = DB9 port */ -#define SEAD_UART0_REGS_BASE 0xbf000900 /* ttyS0 = USB port */ -#define PORT(base_addr, offset) ((unsigned int __iomem *)(base_addr+(offset)*4)) - -static char console_port = 1; - -static inline unsigned int serial_in(int offset, unsigned int base_addr) -{ - return __raw_readl(PORT(base_addr, offset)) & 0xff; -} - -static inline void serial_out(int offset, int value, unsigned int base_addr) -{ - __raw_writel(value, PORT(base_addr, offset)); -} - -void __init fw_init_early_console(char port) -{ - console_port = port; -} - -int prom_putchar(char c) -{ - unsigned int base_addr; - - base_addr = console_port ? SEAD_UART1_REGS_BASE : SEAD_UART0_REGS_BASE; - - while ((serial_in(UART_LSR, base_addr) & UART_LSR_THRE) == 0) - ; - - serial_out(UART_TX, c, base_addr); - - return 1; -} diff --git a/arch/mips/mti-sead3/sead3-display.c b/arch/mips/mti-sead3/sead3-display.c deleted file mode 100644 index 94875991907b..000000000000 --- a/arch/mips/mti-sead3/sead3-display.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - */ -#include <linux/timer.h> -#include <linux/io.h> -#include <asm/mips-boards/generic.h> - -static unsigned int display_count; -static unsigned int max_display_count; - -#define LCD_DISPLAY_POS_BASE 0x1f000400 -#define DISPLAY_LCDINSTRUCTION (0*2) -#define DISPLAY_LCDDATA (1*2) -#define DISPLAY_CPLDSTATUS (2*2) -#define DISPLAY_CPLDDATA (3*2) -#define LCD_SETDDRAM 0x80 -#define LCD_IR_BF 0x80 - -const char display_string[] = " LINUX ON SEAD3 "; - -static void scroll_display_message(unsigned long data); -static DEFINE_TIMER(mips_scroll_timer, scroll_display_message, HZ, 0); - -static void lcd_wait(unsigned int __iomem *display) -{ - /* Wait for CPLD state machine to become idle. */ - do { } while (__raw_readl(display + DISPLAY_CPLDSTATUS) & 1); - - do { - __raw_readl(display + DISPLAY_LCDINSTRUCTION); - - /* Wait for CPLD state machine to become idle. */ - do { } while (__raw_readl(display + DISPLAY_CPLDSTATUS) & 1); - } while (__raw_readl(display + DISPLAY_CPLDDATA) & LCD_IR_BF); -} - -void mips_display_message(const char *str) -{ - static unsigned int __iomem *display; - char ch; - int i; - - if (unlikely(display == NULL)) - display = ioremap_nocache(LCD_DISPLAY_POS_BASE, - (8 * sizeof(int))); - - for (i = 0; i < 16; i++) { - if (*str) - ch = *str++; - else - ch = ' '; - lcd_wait(display); - __raw_writel((LCD_SETDDRAM | i), - (display + DISPLAY_LCDINSTRUCTION)); - lcd_wait(display); - __raw_writel(ch, display + DISPLAY_LCDDATA); - } -} - -static void scroll_display_message(unsigned long data) -{ - mips_display_message(&display_string[display_count++]); - if (display_count == max_display_count) - display_count = 0; - mod_timer(&mips_scroll_timer, jiffies + HZ); -} - -void mips_scroll_message(void) -{ - del_timer_sync(&mips_scroll_timer); - max_display_count = strlen(display_string) + 1 - 16; - mod_timer(&mips_scroll_timer, jiffies + 1); -} diff --git a/arch/mips/mti-sead3/sead3-init.c b/arch/mips/mti-sead3/sead3-init.c deleted file mode 100644 index 3572ea30173e..000000000000 --- a/arch/mips/mti-sead3/sead3-init.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - */ -#include <linux/init.h> -#include <linux/io.h> - -#include <asm/bootinfo.h> -#include <asm/cacheflush.h> -#include <asm/traps.h> -#include <asm/mips-boards/generic.h> -#include <asm/fw/fw.h> - -extern char except_vec_nmi; -extern char except_vec_ejtag_debug; - -#ifdef CONFIG_SERIAL_8250_CONSOLE -static void __init console_config(void) -{ - char console_string[40]; - int baud = 0; - char parity = '\0', bits = '\0', flow = '\0'; - char *s; - - if ((strstr(fw_getcmdline(), "console=")) == NULL) { - s = fw_getenv("modetty0"); - if (s) { - while (*s >= '0' && *s <= '9') - baud = baud*10 + *s++ - '0'; - if (*s == ',') - s++; - if (*s) - parity = *s++; - if (*s == ',') - s++; - if (*s) - bits = *s++; - if (*s == ',') - s++; - if (*s == 'h') - flow = 'r'; - } - if (baud == 0) - baud = 38400; - if (parity != 'n' && parity != 'o' && parity != 'e') - parity = 'n'; - if (bits != '7' && bits != '8') - bits = '8'; - if (flow == '\0') - flow = 'r'; - sprintf(console_string, " console=ttyS0,%d%c%c%c", baud, - parity, bits, flow); - strcat(fw_getcmdline(), console_string); - } -} -#endif - -static void __init mips_nmi_setup(void) -{ - void *base; - - base = cpu_has_veic ? - (void *)(CAC_BASE + 0xa80) : - (void *)(CAC_BASE + 0x380); -#ifdef CONFIG_CPU_MICROMIPS - /* - * Decrement the exception vector address by one for microMIPS. - */ - memcpy(base, (&except_vec_nmi - 1), 0x80); - - /* - * This is a hack. We do not know if the boot loader was built with - * microMIPS instructions or not. If it was not, the NMI exception - * code at 0x80000a80 will be taken in MIPS32 mode. The hand coded - * assembly below forces us into microMIPS mode if we are a pure - * microMIPS kernel. The assembly instructions are: - * - * 3C1A8000 lui k0,0x8000 - * 375A0381 ori k0,k0,0x381 - * 03400008 jr k0 - * 00000000 nop - * - * The mode switch occurs by jumping to the unaligned exception - * vector address at 0x80000381 which would have been 0x80000380 - * in MIPS32 mode. The jump to the unaligned address transitions - * us into microMIPS mode. - */ - if (!cpu_has_veic) { - void *base2 = (void *)(CAC_BASE + 0xa80); - *((unsigned int *)base2) = 0x3c1a8000; - *((unsigned int *)base2 + 1) = 0x375a0381; - *((unsigned int *)base2 + 2) = 0x03400008; - *((unsigned int *)base2 + 3) = 0x00000000; - flush_icache_range((unsigned long)base2, - (unsigned long)base2 + 0x10); - } -#else - memcpy(base, &except_vec_nmi, 0x80); -#endif - flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); -} - -static void __init mips_ejtag_setup(void) -{ - void *base; - - base = cpu_has_veic ? - (void *)(CAC_BASE + 0xa00) : - (void *)(CAC_BASE + 0x300); -#ifdef CONFIG_CPU_MICROMIPS - /* Deja vu... */ - memcpy(base, (&except_vec_ejtag_debug - 1), 0x80); - if (!cpu_has_veic) { - void *base2 = (void *)(CAC_BASE + 0xa00); - *((unsigned int *)base2) = 0x3c1a8000; - *((unsigned int *)base2 + 1) = 0x375a0301; - *((unsigned int *)base2 + 2) = 0x03400008; - *((unsigned int *)base2 + 3) = 0x00000000; - flush_icache_range((unsigned long)base2, - (unsigned long)base2 + 0x10); - } -#else - memcpy(base, &except_vec_ejtag_debug, 0x80); -#endif - flush_icache_range((unsigned long)base, (unsigned long)base + 0x80); -} - -void __init prom_init(void) -{ - board_nmi_handler_setup = mips_nmi_setup; - board_ejtag_handler_setup = mips_ejtag_setup; - - fw_init_cmdline(); -#ifdef CONFIG_EARLY_PRINTK - if ((strstr(fw_getcmdline(), "console=ttyS0")) != NULL) - fw_init_early_console(0); - else if ((strstr(fw_getcmdline(), "console=ttyS1")) != NULL) - fw_init_early_console(1); -#endif -#ifdef CONFIG_SERIAL_8250_CONSOLE - if ((strstr(fw_getcmdline(), "console=")) == NULL) - strcat(fw_getcmdline(), " console=ttyS0,38400n8r"); - console_config(); -#endif -} - -void __init prom_free_prom_memory(void) -{ -} diff --git a/arch/mips/mti-sead3/sead3-int.c b/arch/mips/mti-sead3/sead3-int.c deleted file mode 100644 index e31e17f81eef..000000000000 --- a/arch/mips/mti-sead3/sead3-int.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - */ -#include <linux/init.h> -#include <linux/irq.h> -#include <linux/irqchip/mips-gic.h> -#include <linux/io.h> - -#include <asm/irq_cpu.h> -#include <asm/setup.h> - -#include <asm/mips-boards/sead3int.h> - -#define SEAD_CONFIG_GIC_PRESENT_SHF 1 -#define SEAD_CONFIG_GIC_PRESENT_MSK (1 << SEAD_CONFIG_GIC_PRESENT_SHF) -#define SEAD_CONFIG_BASE 0x1b100110 -#define SEAD_CONFIG_SIZE 4 - -static void __iomem *sead3_config_reg; - -void __init arch_init_irq(void) -{ - if (!cpu_has_veic) - mips_cpu_irq_init(); - - sead3_config_reg = ioremap_nocache(SEAD_CONFIG_BASE, SEAD_CONFIG_SIZE); - gic_present = (__raw_readl(sead3_config_reg) & - SEAD_CONFIG_GIC_PRESENT_MSK) >> - SEAD_CONFIG_GIC_PRESENT_SHF; - pr_info("GIC: %spresent\n", (gic_present) ? "" : "not "); - pr_info("EIC: %s\n", - (current_cpu_data.options & MIPS_CPU_VEIC) ? "on" : "off"); - - if (gic_present) - gic_init(GIC_BASE_ADDR, GIC_ADDRSPACE_SZ, CPU_INT_GIC, - MIPS_GIC_IRQ_BASE); -} - diff --git a/arch/mips/mti-sead3/sead3-lcd.c b/arch/mips/mti-sead3/sead3-lcd.c deleted file mode 100644 index 10b10ed21f77..000000000000 --- a/arch/mips/mti-sead3/sead3-lcd.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - */ -#include <linux/init.h> -#include <linux/platform_device.h> - -static struct resource __initdata sead3_lcd_resource = { - .start = 0x1f000400, - .end = 0x1f00041f, - .flags = IORESOURCE_MEM, -}; - -static __init int sead3_lcd_add(void) -{ - struct platform_device *pdev; - int retval; - - /* SEAD-3 and Cobalt platforms use same display type. */ - pdev = platform_device_alloc("cobalt-lcd", -1); - if (!pdev) - return -ENOMEM; - - retval = platform_device_add_resources(pdev, &sead3_lcd_resource, 1); - if (retval) - goto err_free_device; - - retval = platform_device_add(pdev); - if (retval) - goto err_free_device; - - return 0; - -err_free_device: - platform_device_put(pdev); - - return retval; -} - -device_initcall(sead3_lcd_add); diff --git a/arch/mips/mti-sead3/sead3-platform.c b/arch/mips/mti-sead3/sead3-platform.c deleted file mode 100644 index 73b73efbfb05..000000000000 --- a/arch/mips/mti-sead3/sead3-platform.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - */ -#include <linux/dma-mapping.h> -#include <linux/init.h> -#include <linux/irq.h> -#include <linux/irqchip/mips-gic.h> -#include <linux/leds.h> -#include <linux/mtd/physmap.h> -#include <linux/platform_device.h> -#include <linux/serial_8250.h> -#include <linux/smsc911x.h> - -#include <asm/mips-boards/sead3int.h> - -#define UART(base) \ -{ \ - .mapbase = base, \ - .irq = -1, \ - .uartclk = 14745600, \ - .iotype = UPIO_MEM32, \ - .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, \ - .regshift = 2, \ -} - -static struct plat_serial8250_port uart8250_data[] = { - UART(0x1f000900), /* ttyS0 = USB */ - UART(0x1f000800), /* ttyS1 = RS232 */ - { }, -}; - -static struct platform_device uart8250_device = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM2, - .dev = { - .platform_data = uart8250_data, - }, -}; - -static struct smsc911x_platform_config sead3_smsc911x_data = { - .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, - .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, - .flags = SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS, - .phy_interface = PHY_INTERFACE_MODE_MII, -}; - -static struct resource sead3_net_resources[] = { - { - .start = 0x1f010000, - .end = 0x1f01ffff, - .flags = IORESOURCE_MEM - }, { - .flags = IORESOURCE_IRQ - } -}; - -static struct platform_device sead3_net_device = { - .name = "smsc911x", - .id = 0, - .dev = { - .platform_data = &sead3_smsc911x_data, - }, - .num_resources = ARRAY_SIZE(sead3_net_resources), - .resource = sead3_net_resources -}; - -static struct mtd_partition sead3_mtd_partitions[] = { - { - .name = "User FS", - .offset = 0x00000000, - .size = 0x01fc0000, - }, { - .name = "Board Config", - .offset = 0x01fc0000, - .size = 0x00040000, - .mask_flags = MTD_WRITEABLE - }, -}; - -static struct physmap_flash_data sead3_flash_data = { - .width = 4, - .nr_parts = ARRAY_SIZE(sead3_mtd_partitions), - .parts = sead3_mtd_partitions -}; - -static struct resource sead3_flash_resource = { - .start = 0x1c000000, - .end = 0x1dffffff, - .flags = IORESOURCE_MEM -}; - -static struct platform_device sead3_flash = { - .name = "physmap-flash", - .id = 0, - .dev = { - .platform_data = &sead3_flash_data, - }, - .num_resources = 1, - .resource = &sead3_flash_resource, -}; - -#define LEDFLAGS(bits, shift) \ - ((bits << 8) | (shift << 8)) - -#define LEDBITS(id, shift, bits) \ - .name = id #shift, \ - .flags = LEDFLAGS(bits, shift) - -static struct led_info led_data_info[] = { - { LEDBITS("bit", 0, 1) }, - { LEDBITS("bit", 1, 1) }, - { LEDBITS("bit", 2, 1) }, - { LEDBITS("bit", 3, 1) }, - { LEDBITS("bit", 4, 1) }, - { LEDBITS("bit", 5, 1) }, - { LEDBITS("bit", 6, 1) }, - { LEDBITS("bit", 7, 1) }, - { LEDBITS("all", 0, 8) }, -}; - -static struct led_platform_data led_data = { - .num_leds = ARRAY_SIZE(led_data_info), - .leds = led_data_info -}; - -static struct resource pled_resources[] = { - { - .start = 0x1f000210, - .end = 0x1f000217, - .flags = IORESOURCE_MEM - } -}; - -static struct platform_device pled_device = { - .name = "sead3::pled", - .id = 0, - .dev = { - .platform_data = &led_data, - }, - .num_resources = ARRAY_SIZE(pled_resources), - .resource = pled_resources -}; - - -static struct resource fled_resources[] = { - { - .start = 0x1f000218, - .end = 0x1f00021f, - .flags = IORESOURCE_MEM - } -}; - -static struct platform_device fled_device = { - .name = "sead3::fled", - .id = 0, - .dev = { - .platform_data = &led_data, - }, - .num_resources = ARRAY_SIZE(fled_resources), - .resource = fled_resources -}; - -static struct platform_device sead3_led_device = { - .name = "sead3-led", - .id = -1, -}; - -static struct resource ehci_resources[] = { - { - .start = 0x1b200000, - .end = 0x1b200fff, - .flags = IORESOURCE_MEM - }, { - .flags = IORESOURCE_IRQ - } -}; - -static u64 sead3_usbdev_dma_mask = DMA_BIT_MASK(32); - -static struct platform_device ehci_device = { - .name = "sead3-ehci", - .id = 0, - .dev = { - .dma_mask = &sead3_usbdev_dma_mask, - .coherent_dma_mask = DMA_BIT_MASK(32) - }, - .num_resources = ARRAY_SIZE(ehci_resources), - .resource = ehci_resources -}; - -static struct platform_device *sead3_platform_devices[] __initdata = { - &uart8250_device, - &sead3_flash, - &pled_device, - &fled_device, - &sead3_led_device, - &ehci_device, - &sead3_net_device, -}; - -static int __init sead3_platforms_device_init(void) -{ - if (gic_present) { - uart8250_data[0].irq = MIPS_GIC_IRQ_BASE + GIC_INT_UART0; - uart8250_data[1].irq = MIPS_GIC_IRQ_BASE + GIC_INT_UART1; - ehci_resources[1].start = MIPS_GIC_IRQ_BASE + GIC_INT_EHCI; - sead3_net_resources[1].start = MIPS_GIC_IRQ_BASE + GIC_INT_NET; - } else { - uart8250_data[0].irq = MIPS_CPU_IRQ_BASE + CPU_INT_UART0; - uart8250_data[1].irq = MIPS_CPU_IRQ_BASE + CPU_INT_UART1; - ehci_resources[1].start = MIPS_CPU_IRQ_BASE + CPU_INT_EHCI; - sead3_net_resources[1].start = MIPS_CPU_IRQ_BASE + CPU_INT_NET; - } - - return platform_add_devices(sead3_platform_devices, - ARRAY_SIZE(sead3_platform_devices)); -} - -device_initcall(sead3_platforms_device_init); diff --git a/arch/mips/mti-sead3/sead3-reset.c b/arch/mips/mti-sead3/sead3-reset.c deleted file mode 100644 index e6fb24414a70..000000000000 --- a/arch/mips/mti-sead3/sead3-reset.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - */ -#include <linux/io.h> -#include <linux/pm.h> - -#include <asm/reboot.h> - -#define SOFTRES_REG 0x1f000050 -#define GORESET 0x4d - -static void mips_machine_restart(char *command) -{ - unsigned int __iomem *softres_reg = - ioremap(SOFTRES_REG, sizeof(unsigned int)); - - __raw_writel(GORESET, softres_reg); -} - -static void mips_machine_halt(void) -{ - unsigned int __iomem *softres_reg = - ioremap(SOFTRES_REG, sizeof(unsigned int)); - - __raw_writel(GORESET, softres_reg); -} - -static int __init mips_reboot_setup(void) -{ - _machine_restart = mips_machine_restart; - _machine_halt = mips_machine_halt; - pm_power_off = mips_machine_halt; - - return 0; -} -arch_initcall(mips_reboot_setup); diff --git a/arch/mips/mti-sead3/sead3-setup.c b/arch/mips/mti-sead3/sead3-setup.c deleted file mode 100644 index edfcaf06680d..000000000000 --- a/arch/mips/mti-sead3/sead3-setup.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - * Copyright (C) 2013 Imagination Technologies Ltd. - */ -#include <linux/init.h> -#include <linux/libfdt.h> -#include <linux/of_fdt.h> - -#include <asm/prom.h> -#include <asm/fw/fw.h> - -#include <asm/mips-boards/generic.h> - -const char *get_system_type(void) -{ - return "MIPS SEAD3"; -} - -static uint32_t get_memsize_from_cmdline(void) -{ - int memsize = 0; - char *p = arcs_cmdline; - char *s = "memsize="; - - p = strstr(p, s); - if (p) { - p += strlen(s); - memsize = memparse(p, NULL); - } - - return memsize; -} - -static uint32_t get_memsize_from_env(void) -{ - int memsize = 0; - char *p; - - p = fw_getenv("memsize"); - if (p) - memsize = memparse(p, NULL); - - return memsize; -} - -static uint32_t get_memsize(void) -{ - uint32_t memsize; - - memsize = get_memsize_from_cmdline(); - if (memsize) - return memsize; - - return get_memsize_from_env(); -} - -static void __init parse_memsize_param(void) -{ - int offset; - const uint64_t *prop_value; - int prop_len; - uint32_t memsize = get_memsize(); - - if (!memsize) - return; - - offset = fdt_path_offset(__dtb_start, "/memory"); - if (offset > 0) { - uint64_t new_value; - /* - * reg contains 2 32-bits BE values, offset and size. We just - * want to replace the size value without affecting the offset - */ - prop_value = fdt_getprop(__dtb_start, offset, "reg", &prop_len); - new_value = be64_to_cpu(*prop_value); - new_value = (new_value & ~0xffffffffllu) | memsize; - fdt_setprop_inplace_u64(__dtb_start, offset, "reg", new_value); - } -} - -void __init *plat_get_fdt(void) -{ - return (void *)__dtb_start; -} - -void __init plat_mem_setup(void) -{ - /* allow command line/bootloader env to override memory size in DT */ - parse_memsize_param(); - - /* - * Load the builtin devicetree. This causes the chosen node to be - * parsed resulting in our memory appearing - */ - __dt_setup_arch(__dtb_start); -} - -void __init device_tree_init(void) -{ - if (!initial_boot_params) - return; - - unflatten_and_copy_device_tree(); -} diff --git a/arch/mips/mti-sead3/sead3-time.c b/arch/mips/mti-sead3/sead3-time.c deleted file mode 100644 index a120b7a5a8fe..000000000000 --- a/arch/mips/mti-sead3/sead3-time.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved. - */ -#include <linux/init.h> -#include <linux/irqchip/mips-gic.h> - -#include <asm/cpu.h> -#include <asm/setup.h> -#include <asm/time.h> -#include <asm/irq.h> -#include <asm/mips-boards/generic.h> - -static void __iomem *status_reg = (void __iomem *)0xbf000410; - -/* - * Estimate CPU frequency. Sets mips_hpt_frequency as a side-effect. - */ -static unsigned int __init estimate_cpu_frequency(void) -{ - unsigned int prid = read_c0_prid() & (PRID_COMP_MASK | PRID_IMP_MASK); - unsigned int tick = 0; - unsigned int freq; - unsigned int orig; - unsigned long flags; - - local_irq_save(flags); - - orig = readl(status_reg) & 0x2; /* get original sample */ - /* wait for transition */ - while ((readl(status_reg) & 0x2) == orig) - ; - orig = orig ^ 0x2; /* flip the bit */ - - write_c0_count(0); - - /* wait 1 second (the sampling clock transitions every 10ms) */ - while (tick < 100) { - /* wait for transition */ - while ((readl(status_reg) & 0x2) == orig) - ; - orig = orig ^ 0x2; /* flip the bit */ - tick++; - } - - freq = read_c0_count(); - - local_irq_restore(flags); - - mips_hpt_frequency = freq; - - /* Adjust for processor */ - if ((prid != (PRID_COMP_MIPS | PRID_IMP_20KC)) && - (prid != (PRID_COMP_MIPS | PRID_IMP_25KF))) - freq *= 2; - - freq += 5000; /* rounding */ - freq -= freq%10000; - - return freq ; -} - -void read_persistent_clock(struct timespec *ts) -{ - ts->tv_sec = 0; - ts->tv_nsec = 0; -} - -int get_c0_perfcount_int(void) -{ - if (gic_present) - return gic_get_c0_perfcount_int(); - if (cp0_perfcount_irq >= 0) - return MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; - return -1; -} -EXPORT_SYMBOL_GPL(get_c0_perfcount_int); - -unsigned int get_c0_compare_int(void) -{ - if (gic_present) - return gic_get_c0_compare_int(); - return MIPS_CPU_IRQ_BASE + cp0_compare_irq; -} - -void __init plat_time_init(void) -{ - unsigned int est_freq; - - est_freq = estimate_cpu_frequency(); - - pr_debug("CPU frequency %d.%02d MHz\n", (est_freq / 1000000), - (est_freq % 1000000) * 100 / 1000000); - - mips_scroll_message(); -} diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 139ad1d7ab5e..4b821481dd44 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile @@ -3,6 +3,8 @@ # obj-y += pci.o +obj-$(CONFIG_PCI_DRIVERS_LEGACY)+= pci-legacy.o +obj-$(CONFIG_PCI_DRIVERS_GENERIC)+= pci-generic.o # # PCI bus host bridge specific code diff --git a/arch/mips/pci/pci-alchemy.c b/arch/mips/pci/pci-alchemy.c index c8994c156e2d..e99ca7702d8a 100644 --- a/arch/mips/pci/pci-alchemy.c +++ b/arch/mips/pci/pci-alchemy.c @@ -429,7 +429,8 @@ static int alchemy_pci_probe(struct platform_device *pdev) /* Au1500 revisions older than AD have borked coherent PCI */ if ((alchemy_get_cputype() == ALCHEMY_CPU_AU1500) && - (read_c0_prid() < 0x01030202) && !coherentio) { + (read_c0_prid() < 0x01030202) && + (coherentio == IO_COHERENCE_DISABLED)) { val = __raw_readl(ctx->regs + PCI_REG_CONFIG); val |= PCI_CONFIG_NC; __raw_writel(val, ctx->regs + PCI_REG_CONFIG); diff --git a/arch/mips/pci/pci-ar71xx.c b/arch/mips/pci/pci-ar71xx.c index 7db963deec73..bdf87b43633f 100644 --- a/arch/mips/pci/pci-ar71xx.c +++ b/arch/mips/pci/pci-ar71xx.c @@ -18,7 +18,7 @@ #include <linux/pci.h> #include <linux/pci_regs.h> #include <linux/interrupt.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/platform_device.h> #include <asm/mach-ath79/ar71xx_regs.h> diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c index 2013dad700df..1e23c8d587bd 100644 --- a/arch/mips/pci/pci-ar724x.c +++ b/arch/mips/pci/pci-ar724x.c @@ -11,7 +11,7 @@ #include <linux/irq.h> #include <linux/pci.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/platform_device.h> #include <asm/mach-ath79/ath79.h> #include <asm/mach-ath79/ar71xx_regs.h> diff --git a/arch/mips/pci/pci-generic.c b/arch/mips/pci/pci-generic.c new file mode 100644 index 000000000000..dce304dc3d62 --- /dev/null +++ b/arch/mips/pci/pci-generic.c @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2016 Imagination Technologies + * Author: Paul Burton <paul.burton@imgtec.com> + * + * pcibios_align_resource taken from arch/arm/kernel/bios32.c. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/pci.h> + +/* + * We need to avoid collisions with `mirrored' VGA ports + * and other strange ISA hardware, so we always want the + * addresses to be allocated in the 0x000-0x0ff region + * modulo 0x400. + * + * Why? Because some silly external IO cards only decode + * the low 10 bits of the IO address. The 0x00-0xff region + * is reserved for motherboard devices that decode all 16 + * bits, so it's ok to allocate at, say, 0x2800-0x28ff, + * but we want to try to avoid allocating at 0x2900-0x2bff + * which might have be mirrored at 0x0100-0x03ff.. + */ +resource_size_t pcibios_align_resource(void *data, const struct resource *res, + resource_size_t size, resource_size_t align) +{ + struct pci_dev *dev = data; + resource_size_t start = res->start; + struct pci_host_bridge *host_bridge; + + if (res->flags & IORESOURCE_IO && start & 0x300) + start = (start + 0x3ff) & ~0x3ff; + + start = (start + align - 1) & ~(align - 1); + + host_bridge = pci_find_host_bridge(dev->bus); + + if (host_bridge->align_resource) + return host_bridge->align_resource(dev, res, + start, size, align); + + return start; +} + +void pcibios_fixup_bus(struct pci_bus *bus) +{ + pci_read_bridge_bases(bus); +} diff --git a/arch/mips/pci/pci-lantiq.c b/arch/mips/pci/pci-lantiq.c index b9deab17ccf2..f18f887f481d 100644 --- a/arch/mips/pci/pci-lantiq.c +++ b/arch/mips/pci/pci-lantiq.c @@ -13,7 +13,6 @@ #include <linux/delay.h> #include <linux/mm.h> #include <linux/vmalloc.h> -#include <linux/module.h> #include <linux/clk.h> #include <linux/of_platform.h> #include <linux/of_gpio.h> @@ -234,7 +233,6 @@ static const struct of_device_id ltq_pci_match[] = { { .compatible = "lantiq,pci-xway" }, {}, }; -MODULE_DEVICE_TABLE(of, ltq_pci_match); static struct platform_driver ltq_pci_driver = { .probe = ltq_pci_probe, diff --git a/arch/mips/pci/pci-legacy.c b/arch/mips/pci/pci-legacy.c new file mode 100644 index 000000000000..014649be158d --- /dev/null +++ b/arch/mips/pci/pci-legacy.c @@ -0,0 +1,302 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * Copyright (C) 2003, 04, 11 Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2011 Wind River Systems, + * written by Ralf Baechle (ralf@linux-mips.org) + */ +#include <linux/bug.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/bootmem.h> +#include <linux/export.h> +#include <linux/init.h> +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/of_address.h> + +#include <asm/cpu-info.h> + +/* + * If PCI_PROBE_ONLY in pci_flags is set, we don't change any PCI resource + * assignments. + */ + +/* + * The PCI controller list. + */ +static LIST_HEAD(controllers); + +static int pci_initialized; + +/* + * We need to avoid collisions with `mirrored' VGA ports + * and other strange ISA hardware, so we always want the + * addresses to be allocated in the 0x000-0x0ff region + * modulo 0x400. + * + * Why? Because some silly external IO cards only decode + * the low 10 bits of the IO address. The 0x00-0xff region + * is reserved for motherboard devices that decode all 16 + * bits, so it's ok to allocate at, say, 0x2800-0x28ff, + * but we want to try to avoid allocating at 0x2900-0x2bff + * which might have be mirrored at 0x0100-0x03ff.. + */ +resource_size_t +pcibios_align_resource(void *data, const struct resource *res, + resource_size_t size, resource_size_t align) +{ + struct pci_dev *dev = data; + struct pci_controller *hose = dev->sysdata; + resource_size_t start = res->start; + + if (res->flags & IORESOURCE_IO) { + /* Make sure we start at our min on all hoses */ + if (start < PCIBIOS_MIN_IO + hose->io_resource->start) + start = PCIBIOS_MIN_IO + hose->io_resource->start; + + /* + * Put everything into 0x00-0xff region modulo 0x400 + */ + if (start & 0x300) + start = (start + 0x3ff) & ~0x3ff; + } else if (res->flags & IORESOURCE_MEM) { + /* Make sure we start at our min on all hoses */ + if (start < PCIBIOS_MIN_MEM + hose->mem_resource->start) + start = PCIBIOS_MIN_MEM + hose->mem_resource->start; + } + + return start; +} + +static void pcibios_scanbus(struct pci_controller *hose) +{ + static int next_busno; + static int need_domain_info; + LIST_HEAD(resources); + struct pci_bus *bus; + + if (hose->get_busno && pci_has_flag(PCI_PROBE_ONLY)) + next_busno = (*hose->get_busno)(); + + pci_add_resource_offset(&resources, + hose->mem_resource, hose->mem_offset); + pci_add_resource_offset(&resources, + hose->io_resource, hose->io_offset); + pci_add_resource_offset(&resources, + hose->busn_resource, hose->busn_offset); + bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, + &resources); + hose->bus = bus; + + need_domain_info = need_domain_info || pci_domain_nr(bus); + set_pci_need_domain_info(hose, need_domain_info); + + if (!bus) { + pci_free_resource_list(&resources); + return; + } + + next_busno = bus->busn_res.end + 1; + /* Don't allow 8-bit bus number overflow inside the hose - + reserve some space for bridges. */ + if (next_busno > 224) { + next_busno = 0; + need_domain_info = 1; + } + + /* + * We insert PCI resources into the iomem_resource and + * ioport_resource trees in either pci_bus_claim_resources() + * or pci_bus_assign_resources(). + */ + if (pci_has_flag(PCI_PROBE_ONLY)) { + pci_bus_claim_resources(bus); + } else { + pci_bus_size_bridges(bus); + pci_bus_assign_resources(bus); + } + pci_bus_add_devices(bus); +} + +#ifdef CONFIG_OF +void pci_load_of_ranges(struct pci_controller *hose, struct device_node *node) +{ + struct of_pci_range range; + struct of_pci_range_parser parser; + + pr_info("PCI host bridge %s ranges:\n", node->full_name); + hose->of_node = node; + + if (of_pci_range_parser_init(&parser, node)) + return; + + for_each_of_pci_range(&parser, &range) { + struct resource *res = NULL; + + switch (range.flags & IORESOURCE_TYPE_BITS) { + case IORESOURCE_IO: + pr_info(" IO 0x%016llx..0x%016llx\n", + range.cpu_addr, + range.cpu_addr + range.size - 1); + hose->io_map_base = + (unsigned long)ioremap(range.cpu_addr, + range.size); + res = hose->io_resource; + break; + case IORESOURCE_MEM: + pr_info(" MEM 0x%016llx..0x%016llx\n", + range.cpu_addr, + range.cpu_addr + range.size - 1); + res = hose->mem_resource; + break; + } + if (res != NULL) + of_pci_range_to_resource(&range, node, res); + } +} + +struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus) +{ + struct pci_controller *hose = bus->sysdata; + + return of_node_get(hose->of_node); +} +#endif + +static DEFINE_MUTEX(pci_scan_mutex); + +void register_pci_controller(struct pci_controller *hose) +{ + struct resource *parent; + + parent = hose->mem_resource->parent; + if (!parent) + parent = &iomem_resource; + + if (request_resource(parent, hose->mem_resource) < 0) + goto out; + + parent = hose->io_resource->parent; + if (!parent) + parent = &ioport_resource; + + if (request_resource(parent, hose->io_resource) < 0) { + release_resource(hose->mem_resource); + goto out; + } + + INIT_LIST_HEAD(&hose->list); + list_add(&hose->list, &controllers); + + /* + * Do not panic here but later - this might happen before console init. + */ + if (!hose->io_map_base) { + printk(KERN_WARNING + "registering PCI controller with io_map_base unset\n"); + } + + /* + * Scan the bus if it is register after the PCI subsystem + * initialization. + */ + if (pci_initialized) { + mutex_lock(&pci_scan_mutex); + pcibios_scanbus(hose); + mutex_unlock(&pci_scan_mutex); + } + + return; + +out: + printk(KERN_WARNING + "Skipping PCI bus scan due to resource conflict\n"); +} + +static int __init pcibios_init(void) +{ + struct pci_controller *hose; + + /* Scan all of the recorded PCI controllers. */ + list_for_each_entry(hose, &controllers, list) + pcibios_scanbus(hose); + + pci_fixup_irqs(pci_common_swizzle, pcibios_map_irq); + + pci_initialized = 1; + + return 0; +} + +subsys_initcall(pcibios_init); + +static int pcibios_enable_resources(struct pci_dev *dev, int mask) +{ + u16 cmd, old_cmd; + int idx; + struct resource *r; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + old_cmd = cmd; + for (idx=0; idx < PCI_NUM_RESOURCES; idx++) { + /* Only set up the requested stuff */ + if (!(mask & (1<<idx))) + continue; + + r = &dev->resource[idx]; + if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM))) + continue; + if ((idx == PCI_ROM_RESOURCE) && + (!(r->flags & IORESOURCE_ROM_ENABLE))) + continue; + if (!r->start && r->end) { + printk(KERN_ERR "PCI: Device %s not available " + "because of resource collisions\n", + pci_name(dev)); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (cmd != old_cmd) { + printk("PCI: Enabling device %s (%04x -> %04x)\n", + pci_name(dev), old_cmd, cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + return 0; +} + +int pcibios_enable_device(struct pci_dev *dev, int mask) +{ + int err; + + if ((err = pcibios_enable_resources(dev, mask)) < 0) + return err; + + return pcibios_plat_dev_init(dev); +} + +void pcibios_fixup_bus(struct pci_bus *bus) +{ + struct pci_dev *dev = bus->self; + + if (pci_has_flag(PCI_PROBE_ONLY) && dev && + (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { + pci_read_bridge_bases(bus); + } +} + +char * (*pcibios_plat_setup)(char *str) __initdata; + +char *__init pcibios_setup(char *str) +{ + if (pcibios_plat_setup) + return pcibios_plat_setup(str); + return str; +} diff --git a/arch/mips/pci/pci-mt7620.c b/arch/mips/pci/pci-mt7620.c index 6ce816201699..628c5132b3d8 100644 --- a/arch/mips/pci/pci-mt7620.c +++ b/arch/mips/pci/pci-mt7620.c @@ -15,7 +15,6 @@ #include <linux/init.h> #include <linux/delay.h> #include <linux/interrupt.h> -#include <linux/module.h> #include <linux/of.h> #include <linux/of_irq.h> #include <linux/of_pci.h> @@ -407,13 +406,11 @@ static const struct of_device_id mt7620_pci_ids[] = { { .compatible = "mediatek,mt7620-pci" }, {}, }; -MODULE_DEVICE_TABLE(of, mt7620_pci_ids); static struct platform_driver mt7620_pci_driver = { .probe = mt7620_pci_probe, .driver = { .name = "mt7620-pci", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(mt7620_pci_ids), }, }; diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c index c258cd406fbb..308d051fc45c 100644 --- a/arch/mips/pci/pci-octeon.c +++ b/arch/mips/pci/pci-octeon.c @@ -204,6 +204,8 @@ const char *octeon_get_pci_interrupts(void) * Interrupt Number (INTA# = 0, INTB# = 1, INTC# = 2, and * INTD# = 3) */ + if (of_machine_is_compatible("dlink,dsr-500n")) + return "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"; switch (octeon_bootinfo->board_type) { case CVMX_BOARD_TYPE_NAO38: /* This is really the NAC38 */ diff --git a/arch/mips/pci/pci-rt2880.c b/arch/mips/pci/pci-rt2880.c index f2a1050168d9..d6360fe73d05 100644 --- a/arch/mips/pci/pci-rt2880.c +++ b/arch/mips/pci/pci-rt2880.c @@ -16,7 +16,6 @@ #include <linux/pci.h> #include <linux/io.h> #include <linux/init.h> -#include <linux/module.h> #include <linux/of_platform.h> #include <linux/of_irq.h> #include <linux/of_pci.h> @@ -260,7 +259,6 @@ static const struct of_device_id rt288x_pci_match[] = { { .compatible = "ralink,rt288x-pci" }, {}, }; -MODULE_DEVICE_TABLE(of, rt288x_pci_match); static struct platform_driver rt288x_pci_driver = { .probe = rt288x_pci_probe, diff --git a/arch/mips/pci/pci-rt3883.c b/arch/mips/pci/pci-rt3883.c index 53a42b07008b..3520e9b414e7 100644 --- a/arch/mips/pci/pci-rt3883.c +++ b/arch/mips/pci/pci-rt3883.c @@ -16,7 +16,6 @@ #include <linux/init.h> #include <linux/delay.h> #include <linux/interrupt.h> -#include <linux/module.h> #include <linux/of.h> #include <linux/of_irq.h> #include <linux/of_pci.h> @@ -580,7 +579,6 @@ static const struct of_device_id rt3883_pci_ids[] = { { .compatible = "ralink,rt3883-pci" }, {}, }; -MODULE_DEVICE_TABLE(of, rt3883_pci_ids); static struct platform_driver rt3883_pci_driver = { .probe = rt3883_pci_probe, diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index b4c02f29663e..f6325fa657fb 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c @@ -20,208 +20,13 @@ #include <asm/cpu-info.h> -/* - * If PCI_PROBE_ONLY in pci_flags is set, we don't change any PCI resource - * assignments. - */ - -/* - * The PCI controller list. - */ - -static struct pci_controller *hose_head, **hose_tail = &hose_head; - unsigned long PCIBIOS_MIN_IO; -unsigned long PCIBIOS_MIN_MEM; - -static int pci_initialized; - -/* - * We need to avoid collisions with `mirrored' VGA ports - * and other strange ISA hardware, so we always want the - * addresses to be allocated in the 0x000-0x0ff region - * modulo 0x400. - * - * Why? Because some silly external IO cards only decode - * the low 10 bits of the IO address. The 0x00-0xff region - * is reserved for motherboard devices that decode all 16 - * bits, so it's ok to allocate at, say, 0x2800-0x28ff, - * but we want to try to avoid allocating at 0x2900-0x2bff - * which might have be mirrored at 0x0100-0x03ff.. - */ -resource_size_t -pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t align) -{ - struct pci_dev *dev = data; - struct pci_controller *hose = dev->sysdata; - resource_size_t start = res->start; - - if (res->flags & IORESOURCE_IO) { - /* Make sure we start at our min on all hoses */ - if (start < PCIBIOS_MIN_IO + hose->io_resource->start) - start = PCIBIOS_MIN_IO + hose->io_resource->start; - - /* - * Put everything into 0x00-0xff region modulo 0x400 - */ - if (start & 0x300) - start = (start + 0x3ff) & ~0x3ff; - } else if (res->flags & IORESOURCE_MEM) { - /* Make sure we start at our min on all hoses */ - if (start < PCIBIOS_MIN_MEM + hose->mem_resource->start) - start = PCIBIOS_MIN_MEM + hose->mem_resource->start; - } - - return start; -} - -static void pcibios_scanbus(struct pci_controller *hose) -{ - static int next_busno; - static int need_domain_info; - LIST_HEAD(resources); - struct pci_bus *bus; - - if (hose->get_busno && pci_has_flag(PCI_PROBE_ONLY)) - next_busno = (*hose->get_busno)(); - - pci_add_resource_offset(&resources, - hose->mem_resource, hose->mem_offset); - pci_add_resource_offset(&resources, - hose->io_resource, hose->io_offset); - pci_add_resource_offset(&resources, - hose->busn_resource, hose->busn_offset); - bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, - &resources); - hose->bus = bus; - - need_domain_info = need_domain_info || hose->index; - hose->need_domain_info = need_domain_info; - - if (!bus) { - pci_free_resource_list(&resources); - return; - } - - next_busno = bus->busn_res.end + 1; - /* Don't allow 8-bit bus number overflow inside the hose - - reserve some space for bridges. */ - if (next_busno > 224) { - next_busno = 0; - need_domain_info = 1; - } - - /* - * We insert PCI resources into the iomem_resource and - * ioport_resource trees in either pci_bus_claim_resources() - * or pci_bus_assign_resources(). - */ - if (pci_has_flag(PCI_PROBE_ONLY)) { - pci_bus_claim_resources(bus); - } else { - pci_bus_size_bridges(bus); - pci_bus_assign_resources(bus); - } - pci_bus_add_devices(bus); -} - -#ifdef CONFIG_OF -void pci_load_of_ranges(struct pci_controller *hose, struct device_node *node) -{ - struct of_pci_range range; - struct of_pci_range_parser parser; - - pr_info("PCI host bridge %s ranges:\n", node->full_name); - hose->of_node = node; - - if (of_pci_range_parser_init(&parser, node)) - return; - - for_each_of_pci_range(&parser, &range) { - struct resource *res = NULL; - - switch (range.flags & IORESOURCE_TYPE_BITS) { - case IORESOURCE_IO: - pr_info(" IO 0x%016llx..0x%016llx\n", - range.cpu_addr, - range.cpu_addr + range.size - 1); - hose->io_map_base = - (unsigned long)ioremap(range.cpu_addr, - range.size); - res = hose->io_resource; - break; - case IORESOURCE_MEM: - pr_info(" MEM 0x%016llx..0x%016llx\n", - range.cpu_addr, - range.cpu_addr + range.size - 1); - res = hose->mem_resource; - break; - } - if (res != NULL) - of_pci_range_to_resource(&range, node, res); - } -} - -struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus) -{ - struct pci_controller *hose = bus->sysdata; - - return of_node_get(hose->of_node); -} -#endif - -static DEFINE_MUTEX(pci_scan_mutex); - -void register_pci_controller(struct pci_controller *hose) -{ - struct resource *parent; - - parent = hose->mem_resource->parent; - if (!parent) - parent = &iomem_resource; - - if (request_resource(parent, hose->mem_resource) < 0) - goto out; - - parent = hose->io_resource->parent; - if (!parent) - parent = &ioport_resource; - - if (request_resource(parent, hose->io_resource) < 0) { - release_resource(hose->mem_resource); - goto out; - } - - *hose_tail = hose; - hose_tail = &hose->next; - - /* - * Do not panic here but later - this might happen before console init. - */ - if (!hose->io_map_base) { - printk(KERN_WARNING - "registering PCI controller with io_map_base unset\n"); - } - - /* - * Scan the bus if it is register after the PCI subsystem - * initialization. - */ - if (pci_initialized) { - mutex_lock(&pci_scan_mutex); - pcibios_scanbus(hose); - mutex_unlock(&pci_scan_mutex); - } - - return; +EXPORT_SYMBOL(PCIBIOS_MIN_IO); -out: - printk(KERN_WARNING - "Skipping PCI bus scan due to resource conflict\n"); -} +unsigned long PCIBIOS_MIN_MEM; +EXPORT_SYMBOL(PCIBIOS_MIN_MEM); -static void __init pcibios_set_cache_line_size(void) +static int __init pcibios_set_cache_line_size(void) { struct cpuinfo_mips *c = ¤t_cpu_data; unsigned int lsize; @@ -239,92 +44,9 @@ static void __init pcibios_set_cache_line_size(void) pci_dfl_cache_line_size = lsize >> 2; pr_debug("PCI: pci_cache_line_size set to %d bytes\n", lsize); -} - -static int __init pcibios_init(void) -{ - struct pci_controller *hose; - - pcibios_set_cache_line_size(); - - /* Scan all of the recorded PCI controllers. */ - for (hose = hose_head; hose; hose = hose->next) - pcibios_scanbus(hose); - - pci_fixup_irqs(pci_common_swizzle, pcibios_map_irq); - - pci_initialized = 1; - - return 0; -} - -subsys_initcall(pcibios_init); - -static int pcibios_enable_resources(struct pci_dev *dev, int mask) -{ - u16 cmd, old_cmd; - int idx; - struct resource *r; - - pci_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; - for (idx=0; idx < PCI_NUM_RESOURCES; idx++) { - /* Only set up the requested stuff */ - if (!(mask & (1<<idx))) - continue; - - r = &dev->resource[idx]; - if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM))) - continue; - if ((idx == PCI_ROM_RESOURCE) && - (!(r->flags & IORESOURCE_ROM_ENABLE))) - continue; - if (!r->start && r->end) { - printk(KERN_ERR "PCI: Device %s not available " - "because of resource collisions\n", - pci_name(dev)); - return -EINVAL; - } - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - if (cmd != old_cmd) { - printk("PCI: Enabling device %s (%04x -> %04x)\n", - pci_name(dev), old_cmd, cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd); - } return 0; } - -unsigned int pcibios_assign_all_busses(void) -{ - return 1; -} - -int pcibios_enable_device(struct pci_dev *dev, int mask) -{ - int err; - - if ((err = pcibios_enable_resources(dev, mask)) < 0) - return err; - - return pcibios_plat_dev_init(dev); -} - -void pcibios_fixup_bus(struct pci_bus *bus) -{ - struct pci_dev *dev = bus->self; - - if (pci_has_flag(PCI_PROBE_ONLY) && dev && - (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { - pci_read_bridge_bases(bus); - } -} - -EXPORT_SYMBOL(PCIBIOS_MIN_IO); -EXPORT_SYMBOL(PCIBIOS_MIN_MEM); +arch_initcall(pcibios_set_cache_line_size); void pci_resource_to_user(const struct pci_dev *dev, int bar, const struct resource *rsrc, resource_size_t *start, @@ -359,12 +81,3 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, vma->vm_end - vma->vm_start, vma->vm_page_prot); } - -char * (*pcibios_plat_setup)(char *str) __initdata; - -char *__init pcibios_setup(char *str) -{ - if (pcibios_plat_setup) - return pcibios_plat_setup(str); - return str; -} diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c index 99f3db4f0a9b..9f672ceb089b 100644 --- a/arch/mips/pci/pcie-octeon.c +++ b/arch/mips/pci/pcie-octeon.c @@ -11,7 +11,7 @@ #include <linux/interrupt.h> #include <linux/time.h> #include <linux/delay.h> -#include <linux/module.h> +#include <linux/moduleparam.h> #include <asm/octeon/octeon.h> #include <asm/octeon/cvmx-npei-defs.h> diff --git a/arch/mips/pnx833x/common/platform.c b/arch/mips/pnx833x/common/platform.c index 3cd357737a26..7cf4eb50fc72 100644 --- a/arch/mips/pnx833x/common/platform.c +++ b/arch/mips/pnx833x/common/platform.c @@ -232,12 +232,8 @@ static struct platform_device *pnx833x_platform_devices[] __initdata = { static int __init pnx833x_platform_init(void) { - int res; - - res = platform_add_devices(pnx833x_platform_devices, - ARRAY_SIZE(pnx833x_platform_devices)); - - return res; + return platform_add_devices(pnx833x_platform_devices, + ARRAY_SIZE(pnx833x_platform_devices)); } arch_initcall(pnx833x_platform_init); diff --git a/arch/mips/ralink/timer.c b/arch/mips/ralink/timer.c index b0343ff336c5..8077ff39bdea 100644 --- a/arch/mips/ralink/timer.c +++ b/arch/mips/ralink/timer.c @@ -1,4 +1,7 @@ /* + * Ralink RT2880 timer + * Author: John Crispin + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. @@ -6,7 +9,6 @@ * Copyright (C) 2013 John Crispin <john@phrozen.org> */ -#include <linux/module.h> #include <linux/platform_device.h> #include <linux/interrupt.h> #include <linux/timer.h> @@ -152,33 +154,17 @@ static int rt_timer_probe(struct platform_device *pdev) return 0; } -static int rt_timer_remove(struct platform_device *pdev) -{ - struct rt_timer *rt = platform_get_drvdata(pdev); - - rt_timer_disable(rt); - rt_timer_free(rt); - - return 0; -} - static const struct of_device_id rt_timer_match[] = { { .compatible = "ralink,rt2880-timer" }, {}, }; -MODULE_DEVICE_TABLE(of, rt_timer_match); static struct platform_driver rt_timer_driver = { .probe = rt_timer_probe, - .remove = rt_timer_remove, .driver = { - .name = "rt-timer", - .of_match_table = rt_timer_match + .name = "rt-timer", + .of_match_table = rt_timer_match, + .suppress_bind_attrs = true, }, }; - -module_platform_driver(rt_timer_driver); - -MODULE_DESCRIPTION("Ralink RT2880 timer"); -MODULE_AUTHOR("John Crispin <john@phrozen.org"); -MODULE_LICENSE("GPL"); +builtin_platform_driver(rt_timer_driver); diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig index 8c337d60f790..42923478d45c 100644 --- a/arch/mips/txx9/Kconfig +++ b/arch/mips/txx9/Kconfig @@ -20,7 +20,7 @@ config MACH_TXX9 select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_BIG_ENDIAN - select HAVE_CLK + select COMMON_CLK config TOSHIBA_JMR3927 bool "Toshiba JMR-TX3927 board" diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c index 1f6bc9a3036c..285d84e5c7b9 100644 --- a/arch/mips/txx9/generic/pci.c +++ b/arch/mips/txx9/generic/pci.c @@ -29,12 +29,8 @@ static int __init early_read_config_word(struct pci_controller *hose, int top_bus, int bus, int devfn, int offset, u16 *value) { - struct pci_dev fake_dev; struct pci_bus fake_bus; - fake_dev.bus = &fake_bus; - fake_dev.sysdata = hose; - fake_dev.devfn = devfn; fake_bus.number = bus; fake_bus.sysdata = hose; fake_bus.ops = hose->pci_ops; @@ -45,7 +41,7 @@ early_read_config_word(struct pci_controller *hose, else fake_bus.parent = NULL; - return pci_read_config_word(&fake_dev, offset, value); + return pci_bus_read_config_word(&fake_bus, devfn, offset, value); } int __init txx9_pci66_check(struct pci_controller *hose, int top_bus, diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index ada92db92f87..a1d98b5c8fd6 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -15,7 +15,8 @@ #include <linux/interrupt.h> #include <linux/string.h> #include <linux/module.h> -#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/clkdev.h> #include <linux/err.h> #include <linux/gpio/driver.h> #include <linux/platform_device.h> @@ -83,40 +84,6 @@ int txx9_ccfg_toeon __initdata; int txx9_ccfg_toeon __initdata = 1; #endif -/* Minimum CLK support */ - -struct clk *clk_get(struct device *dev, const char *id) -{ - if (!strcmp(id, "spi-baseclk")) - return (struct clk *)((unsigned long)txx9_gbus_clock / 2 / 2); - if (!strcmp(id, "imbus_clk")) - return (struct clk *)((unsigned long)txx9_gbus_clock / 2); - return ERR_PTR(-ENOENT); -} -EXPORT_SYMBOL(clk_get); - -int clk_enable(struct clk *clk) -{ - return 0; -} -EXPORT_SYMBOL(clk_enable); - -void clk_disable(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_disable); - -unsigned long clk_get_rate(struct clk *clk) -{ - return (unsigned long)clk; -} -EXPORT_SYMBOL(clk_get_rate); - -void clk_put(struct clk *clk) -{ -} -EXPORT_SYMBOL(clk_put); - #define BOARD_VEC(board) extern struct txx9_board_vec board; #include <asm/txx9/boards.h> #undef BOARD_VEC @@ -560,8 +527,41 @@ void __init plat_time_init(void) txx9_board_vec->time_init(); } +static void txx9_clk_init(void) +{ + struct clk_hw *hw; + int error; + + hw = clk_hw_register_fixed_rate(NULL, "gbus", NULL, 0, txx9_gbus_clock); + if (IS_ERR(hw)) { + error = PTR_ERR(hw); + goto fail; + } + + hw = clk_hw_register_fixed_factor(NULL, "imbus", "gbus", 0, 1, 2); + error = clk_hw_register_clkdev(hw, "imbus_clk", NULL); + if (error) + goto fail; + +#ifdef CONFIG_CPU_TX49XX + if (TX4938_REV_PCODE() == 0x4938) { + hw = clk_hw_register_fixed_factor(NULL, "spi", "gbus", 0, 1, 4); + error = clk_hw_register_clkdev(hw, "spi-baseclk", NULL); + if (error) + goto fail; + } +#endif + + return; + +fail: + pr_err("Failed to register clocks: %d\n", error); +} + static int __init _txx9_arch_init(void) { + txx9_clk_init(); + if (txx9_board_vec->arch_init) txx9_board_vec->arch_init(); return 0; diff --git a/arch/mips/txx9/generic/setup_tx3927.c b/arch/mips/txx9/generic/setup_tx3927.c index 110e05c3eb8f..d3b83a92cf26 100644 --- a/arch/mips/txx9/generic/setup_tx3927.c +++ b/arch/mips/txx9/generic/setup_tx3927.c @@ -92,7 +92,6 @@ void __init tx3927_setup(void) /* PIO */ __raw_writel(0, &tx3927_pioptr->maskcpu); __raw_writel(0, &tx3927_pioptr->maskext); - txx9_gpio_init(TX3927_PIO_REG, 0, 16); conf = read_c0_conf(); if (conf & TX39_CONF_DCE) { diff --git a/arch/mips/txx9/generic/setup_tx4927.c b/arch/mips/txx9/generic/setup_tx4927.c index a4664cb6c1e1..8d8011570b1d 100644 --- a/arch/mips/txx9/generic/setup_tx4927.c +++ b/arch/mips/txx9/generic/setup_tx4927.c @@ -215,7 +215,6 @@ void __init tx4927_setup(void) txx9_tmr_init(TX4927_TMR_REG(i) & 0xfffffffffULL); /* PIO */ - txx9_gpio_init(TX4927_PIO_REG & 0xfffffffffULL, 0, TX4927_NUM_PIO); __raw_writel(0, &tx4927_pioptr->maskcpu); __raw_writel(0, &tx4927_pioptr->maskext); diff --git a/arch/mips/txx9/generic/setup_tx4938.c b/arch/mips/txx9/generic/setup_tx4938.c index 58cdb2aba5e1..ba265bf1fd06 100644 --- a/arch/mips/txx9/generic/setup_tx4938.c +++ b/arch/mips/txx9/generic/setup_tx4938.c @@ -241,7 +241,6 @@ void __init tx4938_setup(void) txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL); /* PIO */ - txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, TX4938_NUM_PIO); __raw_writel(0, &tx4938_pioptr->maskcpu); __raw_writel(0, &tx4938_pioptr->maskext); diff --git a/arch/mips/txx9/jmr3927/setup.c b/arch/mips/txx9/jmr3927/setup.c index 3206f76f300b..a455166dc6d4 100644 --- a/arch/mips/txx9/jmr3927/setup.c +++ b/arch/mips/txx9/jmr3927/setup.c @@ -142,8 +142,6 @@ static void __init jmr3927_board_init(void) /* PIO[15:12] connected to LEDs */ __raw_writel(0x0000f000, &tx3927_pioptr->dir); - gpio_request(11, "dipsw1"); - gpio_request(10, "dipsw2"); jmr3927_pci_setup(); @@ -204,6 +202,14 @@ static void __init jmr3927_device_init(void) txx9_iocled_init(iocled_base, -1, 8, 1, "green", NULL); } +static void __init jmr3927_arch_init(void) +{ + txx9_gpio_init(TX3927_PIO_REG, 0, 16); + + gpio_request(11, "dipsw1"); + gpio_request(10, "dipsw2"); +} + struct txx9_board_vec jmr3927_vec __initdata = { .system = "Toshiba JMR_TX3927", .prom_init = jmr3927_prom_init, @@ -211,6 +217,7 @@ struct txx9_board_vec jmr3927_vec __initdata = { .irq_setup = jmr3927_irq_setup, .time_init = jmr3927_time_init, .device_init = jmr3927_device_init, + .arch_init = jmr3927_arch_init, #ifdef CONFIG_PCI .pci_map_irq = jmr3927_pci_map_irq, #endif diff --git a/arch/mips/txx9/rbtx4927/setup.c b/arch/mips/txx9/rbtx4927/setup.c index 3c516ef625e5..f5b367e20dff 100644 --- a/arch/mips/txx9/rbtx4927/setup.c +++ b/arch/mips/txx9/rbtx4927/setup.c @@ -52,6 +52,7 @@ #include <linux/leds.h> #include <asm/io.h> #include <asm/reboot.h> +#include <asm/txx9pio.h> #include <asm/txx9/generic.h> #include <asm/txx9/pci.h> #include <asm/txx9/rbtx4927.h> @@ -151,20 +152,37 @@ static void __init tx4937_pci_setup(void) } tx4938_setup_pcierr_irq(); } +#else +static inline void tx4927_pci_setup(void) {} +static inline void tx4937_pci_setup(void) {} +#endif /* CONFIG_PCI */ + +static void __init rbtx4927_gpio_init(void) +{ + /* TX4927-SIO DTR on (PIO[15]) */ + gpio_request(15, "sio-dtr"); + gpio_direction_output(15, 1); + + tx4927_sio_init(0, 0); +} static void __init rbtx4927_arch_init(void) { + txx9_gpio_init(TX4927_PIO_REG & 0xfffffffffULL, 0, TX4927_NUM_PIO); + + rbtx4927_gpio_init(); + tx4927_pci_setup(); } static void __init rbtx4937_arch_init(void) { + txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, TX4938_NUM_PIO); + + rbtx4927_gpio_init(); + tx4937_pci_setup(); } -#else -#define rbtx4927_arch_init NULL -#define rbtx4937_arch_init NULL -#endif /* CONFIG_PCI */ static void toshiba_rbtx4927_restart(char *command) { @@ -205,12 +223,6 @@ static void __init rbtx4927_mem_setup(void) #else set_io_port_base(KSEG1 + RBTX4927_ISA_IO_OFFSET); #endif - - /* TX4927-SIO DTR on (PIO[15]) */ - gpio_request(15, "sio-dtr"); - gpio_direction_output(15, 1); - - tx4927_sio_init(0, 0); } static void __init rbtx4927_clock_init(void) diff --git a/arch/mips/txx9/rbtx4938/setup.c b/arch/mips/txx9/rbtx4938/setup.c index 54de66837103..07939ed6b22f 100644 --- a/arch/mips/txx9/rbtx4938/setup.c +++ b/arch/mips/txx9/rbtx4938/setup.c @@ -336,6 +336,7 @@ static void __init rbtx4938_mtd_init(void) static void __init rbtx4938_arch_init(void) { + txx9_gpio_init(TX4938_PIO_REG & 0xfffffffffULL, 0, TX4938_NUM_PIO); gpiochip_add_data(&rbtx4938_spi_gpio_chip, NULL); rbtx4938_pci_setup(); rbtx4938_spi_init(); diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile index 3b4538ec0102..c3dc12a8b7d9 100644 --- a/arch/mips/vdso/Makefile +++ b/arch/mips/vdso/Makefile @@ -13,8 +13,6 @@ cflags-vdso := $(ccflags-vdso) \ -DDISABLE_BRANCH_PROFILING \ $(call cc-option, -fno-stack-protector) aflags-vdso := $(ccflags-vdso) \ - $(filter -I%,$(KBUILD_CFLAGS)) \ - $(filter -E%,$(KBUILD_CFLAGS)) \ -D__ASSEMBLY__ -Wa,-gdwarf-2 # @@ -82,7 +80,7 @@ obj-vdso := $(obj-vdso-y:%.o=$(obj)/%.o) $(obj-vdso): KBUILD_CFLAGS := $(cflags-vdso) $(native-abi) $(obj-vdso): KBUILD_AFLAGS := $(aflags-vdso) $(native-abi) -$(obj)/vdso.lds: KBUILD_CPPFLAGS := $(native-abi) +$(obj)/vdso.lds: KBUILD_CPPFLAGS := $(ccflags-vdso) $(native-abi) $(obj)/vdso.so.dbg.raw: $(obj)/vdso.lds $(obj-vdso) FORCE $(call if_changed,vdsold) diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig index c07e725ea93d..10e1b9eee10e 100644 --- a/drivers/auxdisplay/Kconfig +++ b/drivers/auxdisplay/Kconfig @@ -119,4 +119,13 @@ config CFAG12864B_RATE If you compile this as a module, you can still override this value using the module parameters. +config IMG_ASCII_LCD + tristate "Imagination Technologies ASCII LCD Display" + default y if MIPS_MALTA || MIPS_SEAD3 + select SYSCON + help + Enable this to support the simple ASCII LCD displays found on + development boards such as the MIPS Boston, MIPS Malta & MIPS SEAD3 + from Imagination Technologies. + endif # AUXDISPLAY diff --git a/drivers/auxdisplay/Makefile b/drivers/auxdisplay/Makefile index 8a8936a468b9..3127175c89df 100644 --- a/drivers/auxdisplay/Makefile +++ b/drivers/auxdisplay/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_KS0108) += ks0108.o obj-$(CONFIG_CFAG12864B) += cfag12864b.o cfag12864bfb.o +obj-$(CONFIG_IMG_ASCII_LCD) += img-ascii-lcd.o diff --git a/drivers/auxdisplay/img-ascii-lcd.c b/drivers/auxdisplay/img-ascii-lcd.c new file mode 100644 index 000000000000..bf43b5d2aafc --- /dev/null +++ b/drivers/auxdisplay/img-ascii-lcd.c @@ -0,0 +1,443 @@ +/* + * Copyright (C) 2016 Imagination Technologies + * Author: Paul Burton <paul.burton@imgtec.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <generated/utsrelease.h> +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/of_address.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/slab.h> +#include <linux/sysfs.h> + +struct img_ascii_lcd_ctx; + +/** + * struct img_ascii_lcd_config - Configuration information about an LCD model + * @num_chars: the number of characters the LCD can display + * @external_regmap: true if registers are in a system controller, else false + * @update: function called to update the LCD + */ +struct img_ascii_lcd_config { + unsigned int num_chars; + bool external_regmap; + void (*update)(struct img_ascii_lcd_ctx *ctx); +}; + +/** + * struct img_ascii_lcd_ctx - Private data structure + * @pdev: the ASCII LCD platform device + * @base: the base address of the LCD registers + * @regmap: the regmap through which LCD registers are accessed + * @offset: the offset within regmap to the start of the LCD registers + * @cfg: pointer to the LCD model configuration + * @message: the full message to display or scroll on the LCD + * @message_len: the length of the @message string + * @scroll_pos: index of the first character of @message currently displayed + * @scroll_rate: scroll interval in jiffies + * @timer: timer used to implement scrolling + * @curr: the string currently displayed on the LCD + */ +struct img_ascii_lcd_ctx { + struct platform_device *pdev; + union { + void __iomem *base; + struct regmap *regmap; + }; + u32 offset; + const struct img_ascii_lcd_config *cfg; + char *message; + unsigned int message_len; + unsigned int scroll_pos; + unsigned int scroll_rate; + struct timer_list timer; + char curr[] __aligned(8); +}; + +/* + * MIPS Boston development board + */ + +static void boston_update(struct img_ascii_lcd_ctx *ctx) +{ + ulong val; + +#if BITS_PER_LONG == 64 + val = *((u64 *)&ctx->curr[0]); + __raw_writeq(val, ctx->base); +#elif BITS_PER_LONG == 32 + val = *((u32 *)&ctx->curr[0]); + __raw_writel(val, ctx->base); + val = *((u32 *)&ctx->curr[4]); + __raw_writel(val, ctx->base + 4); +#else +# error Not 32 or 64 bit +#endif +} + +static struct img_ascii_lcd_config boston_config = { + .num_chars = 8, + .update = boston_update, +}; + +/* + * MIPS Malta development board + */ + +static void malta_update(struct img_ascii_lcd_ctx *ctx) +{ + unsigned int i; + int err; + + for (i = 0; i < ctx->cfg->num_chars; i++) { + err = regmap_write(ctx->regmap, + ctx->offset + (i * 8), ctx->curr[i]); + if (err) + break; + } + + if (unlikely(err)) + pr_err_ratelimited("Failed to update LCD display: %d\n", err); +} + +static struct img_ascii_lcd_config malta_config = { + .num_chars = 8, + .external_regmap = true, + .update = malta_update, +}; + +/* + * MIPS SEAD3 development board + */ + +enum { + SEAD3_REG_LCD_CTRL = 0x00, +#define SEAD3_REG_LCD_CTRL_SETDRAM BIT(7) + SEAD3_REG_LCD_DATA = 0x08, + SEAD3_REG_CPLD_STATUS = 0x10, +#define SEAD3_REG_CPLD_STATUS_BUSY BIT(0) + SEAD3_REG_CPLD_DATA = 0x18, +#define SEAD3_REG_CPLD_DATA_BUSY BIT(7) +}; + +static int sead3_wait_sm_idle(struct img_ascii_lcd_ctx *ctx) +{ + unsigned int status; + int err; + + do { + err = regmap_read(ctx->regmap, + ctx->offset + SEAD3_REG_CPLD_STATUS, + &status); + if (err) + return err; + } while (status & SEAD3_REG_CPLD_STATUS_BUSY); + + return 0; + +} + +static int sead3_wait_lcd_idle(struct img_ascii_lcd_ctx *ctx) +{ + unsigned int cpld_data; + int err; + + err = sead3_wait_sm_idle(ctx); + if (err) + return err; + + do { + err = regmap_read(ctx->regmap, + ctx->offset + SEAD3_REG_LCD_CTRL, + &cpld_data); + if (err) + return err; + + err = sead3_wait_sm_idle(ctx); + if (err) + return err; + + err = regmap_read(ctx->regmap, + ctx->offset + SEAD3_REG_CPLD_DATA, + &cpld_data); + if (err) + return err; + } while (cpld_data & SEAD3_REG_CPLD_DATA_BUSY); + + return 0; +} + +static void sead3_update(struct img_ascii_lcd_ctx *ctx) +{ + unsigned int i; + int err; + + for (i = 0; i < ctx->cfg->num_chars; i++) { + err = sead3_wait_lcd_idle(ctx); + if (err) + break; + + err = regmap_write(ctx->regmap, + ctx->offset + SEAD3_REG_LCD_CTRL, + SEAD3_REG_LCD_CTRL_SETDRAM | i); + if (err) + break; + + err = sead3_wait_lcd_idle(ctx); + if (err) + break; + + err = regmap_write(ctx->regmap, + ctx->offset + SEAD3_REG_LCD_DATA, + ctx->curr[i]); + if (err) + break; + } + + if (unlikely(err)) + pr_err_ratelimited("Failed to update LCD display: %d\n", err); +} + +static struct img_ascii_lcd_config sead3_config = { + .num_chars = 16, + .external_regmap = true, + .update = sead3_update, +}; + +static const struct of_device_id img_ascii_lcd_matches[] = { + { .compatible = "img,boston-lcd", .data = &boston_config }, + { .compatible = "mti,malta-lcd", .data = &malta_config }, + { .compatible = "mti,sead3-lcd", .data = &sead3_config }, +}; + +/** + * img_ascii_lcd_scroll() - scroll the display by a character + * @arg: really a pointer to the private data structure + * + * Scroll the current message along the LCD by one character, rearming the + * timer if required. + */ +static void img_ascii_lcd_scroll(unsigned long arg) +{ + struct img_ascii_lcd_ctx *ctx = (struct img_ascii_lcd_ctx *)arg; + unsigned int i, ch = ctx->scroll_pos; + unsigned int num_chars = ctx->cfg->num_chars; + + /* update the current message string */ + for (i = 0; i < num_chars;) { + /* copy as many characters from the string as possible */ + for (; i < num_chars && ch < ctx->message_len; i++, ch++) + ctx->curr[i] = ctx->message[ch]; + + /* wrap around to the start of the string */ + ch = 0; + } + + /* update the LCD */ + ctx->cfg->update(ctx); + + /* move on to the next character */ + ctx->scroll_pos++; + ctx->scroll_pos %= ctx->message_len; + + /* rearm the timer */ + if (ctx->message_len > ctx->cfg->num_chars) + mod_timer(&ctx->timer, jiffies + ctx->scroll_rate); +} + +/** + * img_ascii_lcd_display() - set the message to be displayed + * @ctx: pointer to the private data structure + * @msg: the message to display + * @count: length of msg, or -1 + * + * Display a new message @msg on the LCD. @msg can be longer than the number of + * characters the LCD can display, in which case it will begin scrolling across + * the LCD display. + * + * Return: 0 on success, -ENOMEM on memory allocation failure + */ +static int img_ascii_lcd_display(struct img_ascii_lcd_ctx *ctx, + const char *msg, ssize_t count) +{ + char *new_msg; + + /* stop the scroll timer */ + del_timer_sync(&ctx->timer); + + if (count == -1) + count = strlen(msg); + + /* if the string ends with a newline, trim it */ + if (msg[count - 1] == '\n') + count--; + + new_msg = devm_kmalloc(&ctx->pdev->dev, count + 1, GFP_KERNEL); + if (!new_msg) + return -ENOMEM; + + memcpy(new_msg, msg, count); + new_msg[count] = 0; + + if (ctx->message) + devm_kfree(&ctx->pdev->dev, ctx->message); + + ctx->message = new_msg; + ctx->message_len = count; + ctx->scroll_pos = 0; + + /* update the LCD */ + img_ascii_lcd_scroll((unsigned long)ctx); + + return 0; +} + +/** + * message_show() - read message via sysfs + * @dev: the LCD device + * @attr: the LCD message attribute + * @buf: the buffer to read the message into + * + * Read the current message being displayed or scrolled across the LCD display + * into @buf, for reads from sysfs. + * + * Return: the number of characters written to @buf + */ +static ssize_t message_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct img_ascii_lcd_ctx *ctx = dev_get_drvdata(dev); + + return sprintf(buf, "%s\n", ctx->message); +} + +/** + * message_store() - write a new message via sysfs + * @dev: the LCD device + * @attr: the LCD message attribute + * @buf: the buffer containing the new message + * @count: the size of the message in @buf + * + * Write a new message to display or scroll across the LCD display from sysfs. + * + * Return: the size of the message on success, else -ERRNO + */ +static ssize_t message_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct img_ascii_lcd_ctx *ctx = dev_get_drvdata(dev); + int err; + + err = img_ascii_lcd_display(ctx, buf, count); + return err ?: count; +} + +static DEVICE_ATTR_RW(message); + +/** + * img_ascii_lcd_probe() - probe an LCD display device + * @pdev: the LCD platform device + * + * Probe an LCD display device, ensuring that we have the required resources in + * order to access the LCD & setting up private data as well as sysfs files. + * + * Return: 0 on success, else -ERRNO + */ +static int img_ascii_lcd_probe(struct platform_device *pdev) +{ + const struct of_device_id *match; + const struct img_ascii_lcd_config *cfg; + struct img_ascii_lcd_ctx *ctx; + struct resource *res; + int err; + + match = of_match_device(img_ascii_lcd_matches, &pdev->dev); + if (!match) + return -ENODEV; + + cfg = match->data; + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx) + cfg->num_chars, + GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + if (cfg->external_regmap) { + ctx->regmap = syscon_node_to_regmap(pdev->dev.parent->of_node); + if (IS_ERR(ctx->regmap)) + return PTR_ERR(ctx->regmap); + + if (of_property_read_u32(pdev->dev.of_node, "offset", + &ctx->offset)) + return -EINVAL; + } else { + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + ctx->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(ctx->base)) + return PTR_ERR(ctx->base); + } + + ctx->pdev = pdev; + ctx->cfg = cfg; + ctx->message = NULL; + ctx->scroll_pos = 0; + ctx->scroll_rate = HZ / 2; + + /* initialise a timer for scrolling the message */ + init_timer(&ctx->timer); + ctx->timer.function = img_ascii_lcd_scroll; + ctx->timer.data = (unsigned long)ctx; + + platform_set_drvdata(pdev, ctx); + + /* display a default message */ + err = img_ascii_lcd_display(ctx, "Linux " UTS_RELEASE " ", -1); + if (err) + goto out_del_timer; + + err = device_create_file(&pdev->dev, &dev_attr_message); + if (err) + goto out_del_timer; + + return 0; +out_del_timer: + del_timer_sync(&ctx->timer); + return err; +} + +/** + * img_ascii_lcd_remove() - remove an LCD display device + * @pdev: the LCD platform device + * + * Remove an LCD display device, freeing private resources & ensuring that the + * driver stops using the LCD display registers. + * + * Return: 0 + */ +static int img_ascii_lcd_remove(struct platform_device *pdev) +{ + struct img_ascii_lcd_ctx *ctx = platform_get_drvdata(pdev); + + device_remove_file(&pdev->dev, &dev_attr_message); + del_timer_sync(&ctx->timer); + return 0; +} + +static struct platform_driver img_ascii_lcd_driver = { + .driver = { + .name = "img-ascii-lcd", + .of_match_table = img_ascii_lcd_matches, + }, + .probe = img_ascii_lcd_probe, + .remove = img_ascii_lcd_remove, +}; +module_platform_driver(img_ascii_lcd_driver); diff --git a/drivers/cpuidle/Kconfig.mips b/drivers/cpuidle/Kconfig.mips index 4102be01d06a..512ee37b374b 100644 --- a/drivers/cpuidle/Kconfig.mips +++ b/drivers/cpuidle/Kconfig.mips @@ -5,7 +5,7 @@ config MIPS_CPS_CPUIDLE bool "CPU Idle driver for MIPS CPS platforms" depends on CPU_IDLE && MIPS_CPS depends on SYS_SUPPORTS_MIPS_CPS - select ARCH_NEEDS_CPU_IDLE_COUPLED if MIPS_MT + select ARCH_NEEDS_CPU_IDLE_COUPLED if MIPS_MT || CPU_MIPSR6 select GENERIC_CLOCKEVENTS_BROADCAST if SMP select MIPS_CPS_PM default y diff --git a/drivers/cpuidle/cpuidle-cps.c b/drivers/cpuidle/cpuidle-cps.c index 1adb6980b707..926ba9871c62 100644 --- a/drivers/cpuidle/cpuidle-cps.c +++ b/drivers/cpuidle/cpuidle-cps.c @@ -163,7 +163,7 @@ static int __init cps_cpuidle_init(void) core = cpu_data[cpu].core; device = &per_cpu(cpuidle_dev, cpu); device->cpu = cpu; -#ifdef CONFIG_MIPS_MT +#ifdef CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED cpumask_copy(&device->coupled_cpus, &cpu_sibling_map[cpu]); #endif diff --git a/drivers/irqchip/irq-i8259.c b/drivers/irqchip/irq-i8259.c index 6b304eb39bd2..1aec12c6d9ac 100644 --- a/drivers/irqchip/irq-i8259.c +++ b/drivers/irqchip/irq-i8259.c @@ -38,6 +38,7 @@ static void disable_8259A_irq(struct irq_data *d); static void enable_8259A_irq(struct irq_data *d); static void mask_and_ack_8259A(struct irq_data *d); static void init_8259A(int auto_eoi); +static int (*i8259_poll)(void) = i8259_irq; static struct irq_chip i8259A_chip = { .name = "XT-PIC", @@ -51,6 +52,11 @@ static struct irq_chip i8259A_chip = { * 8259A PIC functions to handle ISA devices: */ +void i8259_set_poll(int (*poll)(void)) +{ + i8259_poll = poll; +} + /* * This contains the irq mask for both 8259A irq controllers, */ @@ -89,24 +95,6 @@ static void enable_8259A_irq(struct irq_data *d) raw_spin_unlock_irqrestore(&i8259A_lock, flags); } -int i8259A_irq_pending(unsigned int irq) -{ - unsigned int mask; - unsigned long flags; - int ret; - - irq -= I8259A_IRQ_BASE; - mask = 1 << irq; - raw_spin_lock_irqsave(&i8259A_lock, flags); - if (irq < 8) - ret = inb(PIC_MASTER_CMD) & mask; - else - ret = inb(PIC_SLAVE_CMD) & (mask >> 8); - raw_spin_unlock_irqrestore(&i8259A_lock, flags); - - return ret; -} - void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); @@ -355,7 +343,7 @@ void __init init_i8259_irqs(void) static void i8259_irq_dispatch(struct irq_desc *desc) { struct irq_domain *domain = irq_desc_get_handler_data(desc); - int hwirq = i8259_irq(); + int hwirq = i8259_poll(); unsigned int irq; if (hwirq < 0) @@ -370,13 +358,15 @@ int __init i8259_of_init(struct device_node *node, struct device_node *parent) struct irq_domain *domain; unsigned int parent_irq; + domain = __init_i8259_irqs(node); + parent_irq = irq_of_parse_and_map(node, 0); if (!parent_irq) { pr_err("Failed to map i8259 parent IRQ\n"); + irq_domain_remove(domain); return -ENODEV; } - domain = __init_i8259_irqs(node); irq_set_chained_handler_and_data(parent_irq, i8259_irq_dispatch, domain); return 0; diff --git a/drivers/of/platform.c b/drivers/of/platform.c index f811d2796437..e4bf07d20f9b 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -29,6 +29,7 @@ const struct of_device_id of_default_bus_match_table[] = { { .compatible = "simple-bus", }, { .compatible = "simple-mfd", }, + { .compatible = "isa", }, #ifdef CONFIG_ARM_AMBA { .compatible = "arm,amba-bus", }, #endif /* CONFIG_ARM_AMBA */ diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 1e5f529d51a2..063064801ceb 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1308,11 +1308,6 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ehci_mv_driver #endif -#ifdef CONFIG_MIPS_SEAD3 -#include "ehci-sead3.c" -#define PLATFORM_DRIVER ehci_hcd_sead3_driver -#endif - static int __init ehci_hcd_init(void) { int retval = 0; diff --git a/drivers/usb/host/ehci-sead3.c b/drivers/usb/host/ehci-sead3.c deleted file mode 100644 index 3d86cc2ffe68..000000000000 --- a/drivers/usb/host/ehci-sead3.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * MIPS CI13320A EHCI Host Controller driver - * Based on "ehci-au1xxx.c" by K.Boge <karsten.boge@amd.com> - * - * Copyright (C) 2012 MIPS Technologies, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/err.h> -#include <linux/platform_device.h> - -static int ehci_sead3_setup(struct usb_hcd *hcd) -{ - int ret; - struct ehci_hcd *ehci = hcd_to_ehci(hcd); - - ehci->caps = hcd->regs + 0x100; - -#ifdef __BIG_ENDIAN - ehci->big_endian_mmio = 1; - ehci->big_endian_desc = 1; -#endif - - ret = ehci_setup(hcd); - if (ret) - return ret; - - ehci->need_io_watchdog = 0; - - /* Set burst length to 16 words. */ - ehci_writel(ehci, 0x1010, &ehci->regs->reserved1[1]); - - return ret; -} - -const struct hc_driver ehci_sead3_hc_driver = { - .description = hcd_name, - .product_desc = "SEAD-3 EHCI", - .hcd_priv_size = sizeof(struct ehci_hcd), - - /* - * generic hardware linkage - */ - .irq = ehci_irq, - .flags = HCD_MEMORY | HCD_USB2 | HCD_BH, - - /* - * basic lifecycle operations - * - */ - .reset = ehci_sead3_setup, - .start = ehci_run, - .stop = ehci_stop, - .shutdown = ehci_shutdown, - - /* - * managing i/o requests and associated device resources - */ - .urb_enqueue = ehci_urb_enqueue, - .urb_dequeue = ehci_urb_dequeue, - .endpoint_disable = ehci_endpoint_disable, - .endpoint_reset = ehci_endpoint_reset, - - /* - * scheduling support - */ - .get_frame_number = ehci_get_frame, - - /* - * root hub support - */ - .hub_status_data = ehci_hub_status_data, - .hub_control = ehci_hub_control, - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, - .relinquish_port = ehci_relinquish_port, - .port_handed_over = ehci_port_handed_over, - - .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, -}; - -static int ehci_hcd_sead3_drv_probe(struct platform_device *pdev) -{ - struct usb_hcd *hcd; - struct resource *res; - int ret; - - if (usb_disabled()) - return -ENODEV; - - if (pdev->resource[1].flags != IORESOURCE_IRQ) { - pr_debug("resource[1] is not IORESOURCE_IRQ"); - return -ENOMEM; - } - hcd = usb_create_hcd(&ehci_sead3_hc_driver, &pdev->dev, "SEAD-3"); - if (!hcd) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - hcd->regs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(hcd->regs)) { - ret = PTR_ERR(hcd->regs); - goto err1; - } - hcd->rsrc_start = res->start; - hcd->rsrc_len = resource_size(res); - - /* Root hub has integrated TT. */ - hcd->has_tt = 1; - - ret = usb_add_hcd(hcd, pdev->resource[1].start, - IRQF_SHARED); - if (ret == 0) { - platform_set_drvdata(pdev, hcd); - device_wakeup_enable(hcd->self.controller); - return ret; - } - -err1: - usb_put_hcd(hcd); - return ret; -} - -static int ehci_hcd_sead3_drv_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - - usb_remove_hcd(hcd); - usb_put_hcd(hcd); - - return 0; -} - -#ifdef CONFIG_PM -static int ehci_hcd_sead3_drv_suspend(struct device *dev) -{ - struct usb_hcd *hcd = dev_get_drvdata(dev); - bool do_wakeup = device_may_wakeup(dev); - - return ehci_suspend(hcd, do_wakeup); -} - -static int ehci_hcd_sead3_drv_resume(struct device *dev) -{ - struct usb_hcd *hcd = dev_get_drvdata(dev); - - ehci_resume(hcd, false); - return 0; -} - -static const struct dev_pm_ops sead3_ehci_pmops = { - .suspend = ehci_hcd_sead3_drv_suspend, - .resume = ehci_hcd_sead3_drv_resume, -}; - -#define SEAD3_EHCI_PMOPS (&sead3_ehci_pmops) - -#else -#define SEAD3_EHCI_PMOPS NULL -#endif - -static struct platform_driver ehci_hcd_sead3_driver = { - .probe = ehci_hcd_sead3_drv_probe, - .remove = ehci_hcd_sead3_drv_remove, - .shutdown = usb_hcd_platform_shutdown, - .driver = { - .name = "sead3-ehci", - .pm = SEAD3_EHCI_PMOPS, - } -}; - -MODULE_ALIAS("platform:sead3-ehci"); diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index af2f117208f1..5d3b0db5ce0a 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -2187,7 +2187,7 @@ config FB_GOLDFISH config FB_COBALT tristate "Cobalt server LCD frame buffer support" - depends on FB && (MIPS_COBALT || MIPS_SEAD3) + depends on FB && MIPS_COBALT config FB_SH7760 bool "SH7760/SH7763/SH7720/SH7721 LCDC support" diff --git a/drivers/video/fbdev/cobalt_lcdfb.c b/drivers/video/fbdev/cobalt_lcdfb.c index 07675d6f323e..2d3b691f3fc4 100644 --- a/drivers/video/fbdev/cobalt_lcdfb.c +++ b/drivers/video/fbdev/cobalt_lcdfb.c @@ -63,7 +63,6 @@ #define LCD_CUR_POS(x) ((x) & LCD_CUR_POS_MASK) #define LCD_TEXT_POS(x) ((x) | LCD_TEXT_MODE) -#ifdef CONFIG_MIPS_COBALT static inline void lcd_write_control(struct fb_info *info, u8 control) { writel((u32)control << 24, info->screen_base); @@ -83,47 +82,6 @@ static inline u8 lcd_read_data(struct fb_info *info) { return readl(info->screen_base + LCD_DATA_REG_OFFSET) >> 24; } -#else - -#define LCD_CTL 0x00 -#define LCD_DATA 0x08 -#define CPLD_STATUS 0x10 -#define CPLD_DATA 0x18 - -static inline void cpld_wait(struct fb_info *info) -{ - do { - } while (readl(info->screen_base + CPLD_STATUS) & 1); -} - -static inline void lcd_write_control(struct fb_info *info, u8 control) -{ - cpld_wait(info); - writel(control, info->screen_base + LCD_CTL); -} - -static inline u8 lcd_read_control(struct fb_info *info) -{ - cpld_wait(info); - readl(info->screen_base + LCD_CTL); - cpld_wait(info); - return readl(info->screen_base + CPLD_DATA) & 0xff; -} - -static inline void lcd_write_data(struct fb_info *info, u8 data) -{ - cpld_wait(info); - writel(data, info->screen_base + LCD_DATA); -} - -static inline u8 lcd_read_data(struct fb_info *info) -{ - cpld_wait(info); - readl(info->screen_base + LCD_DATA); - cpld_wait(info); - return readl(info->screen_base + CPLD_DATA) & 0xff; -} -#endif static int lcd_busy_wait(struct fb_info *info) { |