OSDN Git Service

Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 27 Jun 2015 19:44:34 +0000 (12:44 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 27 Jun 2015 19:44:34 +0000 (12:44 -0700)
Pull MIPS updates from Ralf Baechle:

 - Improvements to the tlb_dump code
 - KVM fixes
 - Add support for appended DTB
 - Minor improvements to the R12000 support
 - Minor improvements to the R12000 support
 - Various platform improvments for BCM47xx
 - The usual pile of minor cleanups
 - A number of BPF fixes and improvments
 - Some improvments to the support for R3000 and DECstations
 - Some improvments to the ATH79 platform support
 - A major patchset for the JZ4740 SOC adding support for the CI20 platform
 - Add support for the Pistachio SOC
 - Minor BMIPS/BCM63xx platform support improvments.
 - Avoid "SYNC 0" as memory barrier when unlocking spinlocks
 - Add support for the XWR-1750 board.
 - Paul's __cpuinit/__cpuinitdata cleanups.
 - New Malta CPU board support large memory so enable ZONE_DMA32.

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (131 commits)
  MIPS: spinlock: Adjust arch_spin_lock back-off time
  MIPS: asmmacro: Ensure 64-bit FP registers are used with MSA
  MIPS: BCM47xx: Simplify handling SPROM revisions
  MIPS: Cobalt Don't use module_init in non-modular MTD registration.
  MIPS: BCM47xx: Move NVRAM driver to the drivers/firmware/
  MIPS: use for_each_sg()
  MIPS: BCM47xx: Don't select BCMA_HOST_PCI
  MIPS: BCM47xx: Add helper variable for storing NVRAM length
  MIPS: IRQ/IP27: Move IRQ allocation API to platform code.
  MIPS: Replace smp_mb with release barrier function in unlocks.
  MIPS: i8259: DT support
  MIPS: Malta: Basic DT plumbing
  MIPS: include errno.h for ENODEV in mips-cm.h
  MIPS: Define GCR_GIC_STATUS register fields
  MIPS: BPF: Introduce BPF ASM helpers
  MIPS: BPF: Use BPF register names to describe the ABI
  MIPS: BPF: Move register definition to the BPF header
  MIPS: net: BPF: Replace RSIZE with SZREG
  MIPS: BPF: Free up some callee-saved registers
  MIPS: Xtalk: Update xwidget.h with known Xtalk device numbers
  ...

281 files changed:
Documentation/devicetree/bindings/clock/ingenic,cgu.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qca,ath79-pll.txt [new file with mode: 0644]
Documentation/devicetree/bindings/gpio/gpio-ath79.txt [new file with mode: 0644]
Documentation/devicetree/bindings/interrupt-controller/ingenic,intc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/interrupt-controller/qca,ath79-cpu-intc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/interrupt-controller/qca,ath79-misc-intc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/memory-controllers/ath79-ddr-controller.txt [new file with mode: 0644]
Documentation/devicetree/bindings/mips/ath79-soc.txt [new file with mode: 0644]
Documentation/devicetree/bindings/phy/pistachio-usb-phy.txt [new file with mode: 0644]
Documentation/devicetree/bindings/serial/ingenic,uart.txt [new file with mode: 0644]
Documentation/devicetree/bindings/vendor-prefixes.txt
MAINTAINERS
arch/mips/Kbuild.platforms
arch/mips/Kconfig
arch/mips/alchemy/common/clock.c
arch/mips/ath25/ar2315.c
arch/mips/ath25/ar5312.c
arch/mips/ath25/board.c
arch/mips/ath79/Kconfig
arch/mips/ath79/clock.c
arch/mips/ath79/common.c
arch/mips/ath79/common.h
arch/mips/ath79/dev-common.c
arch/mips/ath79/gpio.c
arch/mips/ath79/irq.c
arch/mips/ath79/machtypes.h
arch/mips/ath79/setup.c
arch/mips/bcm47xx/Kconfig
arch/mips/bcm47xx/Makefile
arch/mips/bcm47xx/board.c
arch/mips/bcm47xx/buttons.c
arch/mips/bcm47xx/leds.c
arch/mips/bcm47xx/prom.c
arch/mips/bcm47xx/setup.c
arch/mips/bcm47xx/sprom.c
arch/mips/bmips/Kconfig
arch/mips/bmips/setup.c
arch/mips/boot/compressed/head.S
arch/mips/boot/compressed/ld.script
arch/mips/boot/compressed/uart-16550.c
arch/mips/boot/dts/Makefile
arch/mips/boot/dts/brcm/Makefile
arch/mips/boot/dts/brcm/bcm7346.dtsi
arch/mips/boot/dts/brcm/bcm7358.dtsi
arch/mips/boot/dts/brcm/bcm7360.dtsi
arch/mips/boot/dts/brcm/bcm7362.dtsi
arch/mips/boot/dts/brcm/bcm7435.dtsi [new file with mode: 0644]
arch/mips/boot/dts/brcm/bcm97346dbsmb.dts
arch/mips/boot/dts/brcm/bcm97358svmb.dts
arch/mips/boot/dts/brcm/bcm97360svmb.dts
arch/mips/boot/dts/brcm/bcm97362svmb.dts
arch/mips/boot/dts/brcm/bcm97435svmb.dts [new file with mode: 0644]
arch/mips/boot/dts/ingenic/Makefile [new file with mode: 0644]
arch/mips/boot/dts/ingenic/ci20.dts [new file with mode: 0644]
arch/mips/boot/dts/ingenic/jz4740.dtsi [new file with mode: 0644]
arch/mips/boot/dts/ingenic/jz4780.dtsi [new file with mode: 0644]
arch/mips/boot/dts/ingenic/qi_lb60.dts [new file with mode: 0644]
arch/mips/boot/dts/mti/Makefile
arch/mips/boot/dts/mti/malta.dts [new file with mode: 0644]
arch/mips/boot/dts/qca/Makefile [new file with mode: 0644]
arch/mips/boot/dts/qca/ar9132.dtsi [new file with mode: 0644]
arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts [new file with mode: 0644]
arch/mips/cavium-octeon/octeon-irq.c
arch/mips/cobalt/mtd.c
arch/mips/configs/ci20_defconfig [new file with mode: 0644]
arch/mips/configs/fuloong2e_defconfig
arch/mips/configs/lemote2f_defconfig
arch/mips/configs/loongson3_defconfig
arch/mips/configs/ls1b_defconfig
arch/mips/configs/maltasmvp_defconfig
arch/mips/configs/pistachio_defconfig
arch/mips/configs/qi_lb60_defconfig
arch/mips/include/asm/asmmacro.h
arch/mips/include/asm/bitops.h
arch/mips/include/asm/bmips-spaces.h [new file with mode: 0644]
arch/mips/include/asm/cpu-features.h
arch/mips/include/asm/cpu-type.h
arch/mips/include/asm/cpu.h
arch/mips/include/asm/hazards.h
arch/mips/include/asm/i8259.h
arch/mips/include/asm/irqflags.h
arch/mips/include/asm/kgdb.h
arch/mips/include/asm/mach-ath79/ar71xx_regs.h
arch/mips/include/asm/mach-ath79/ath79.h
arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h
arch/mips/include/asm/mach-bcm63xx/spaces.h
arch/mips/include/asm/mach-bmips/spaces.h
arch/mips/include/asm/mach-dec/cpu-feature-overrides.h
arch/mips/include/asm/mach-generic/irq.h
arch/mips/include/asm/mach-generic/spaces.h
arch/mips/include/asm/mach-ip27/cpu-feature-overrides.h
arch/mips/include/asm/mach-jz4740/clock.h
arch/mips/include/asm/mach-jz4740/cpu-feature-overrides.h
arch/mips/include/asm/mach-jz4740/irq.h
arch/mips/include/asm/mach-jz4740/platform.h
arch/mips/include/asm/mach-loongson/workarounds.h [deleted file]
arch/mips/include/asm/mach-loongson32/cpufreq.h [moved from arch/mips/include/asm/mach-loongson1/cpufreq.h with 81% similarity]
arch/mips/include/asm/mach-loongson32/irq.h [moved from arch/mips/include/asm/mach-loongson1/irq.h with 95% similarity]
arch/mips/include/asm/mach-loongson32/loongson1.h [moved from arch/mips/include/asm/mach-loongson1/loongson1.h with 91% similarity]
arch/mips/include/asm/mach-loongson32/platform.h [moved from arch/mips/include/asm/mach-loongson1/platform.h with 85% similarity]
arch/mips/include/asm/mach-loongson32/prom.h [moved from arch/mips/include/asm/mach-loongson1/prom.h with 84% similarity]
arch/mips/include/asm/mach-loongson32/regs-clk.h [moved from arch/mips/include/asm/mach-loongson1/regs-clk.h with 90% similarity]
arch/mips/include/asm/mach-loongson32/regs-mux.h [moved from arch/mips/include/asm/mach-loongson1/regs-mux.h with 94% similarity]
arch/mips/include/asm/mach-loongson32/regs-pwm.h [moved from arch/mips/include/asm/mach-loongson1/regs-pwm.h with 84% similarity]
arch/mips/include/asm/mach-loongson32/regs-wdt.h [moved from arch/mips/include/asm/mach-loongson1/regs-wdt.h with 77% similarity]
arch/mips/include/asm/mach-loongson64/boot_param.h [moved from arch/mips/include/asm/mach-loongson/boot_param.h with 98% similarity]
arch/mips/include/asm/mach-loongson64/cpu-feature-overrides.h [moved from arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h with 90% similarity]
arch/mips/include/asm/mach-loongson64/cs5536/cs5536.h [moved from arch/mips/include/asm/mach-loongson/cs5536/cs5536.h with 100% similarity]
arch/mips/include/asm/mach-loongson64/cs5536/cs5536_mfgpt.h [moved from arch/mips/include/asm/mach-loongson/cs5536/cs5536_mfgpt.h with 100% similarity]
arch/mips/include/asm/mach-loongson64/cs5536/cs5536_pci.h [moved from arch/mips/include/asm/mach-loongson/cs5536/cs5536_pci.h with 100% similarity]
arch/mips/include/asm/mach-loongson64/cs5536/cs5536_vsm.h [moved from arch/mips/include/asm/mach-loongson/cs5536/cs5536_vsm.h with 100% similarity]
arch/mips/include/asm/mach-loongson64/dma-coherence.h [moved from arch/mips/include/asm/mach-loongson/dma-coherence.h with 93% similarity]
arch/mips/include/asm/mach-loongson64/gpio.h [moved from arch/mips/include/asm/mach-loongson/gpio.h with 100% similarity]
arch/mips/include/asm/mach-loongson64/irq.h [moved from arch/mips/include/asm/mach-loongson/irq.h with 92% similarity]
arch/mips/include/asm/mach-loongson64/kernel-entry-init.h [moved from arch/mips/include/asm/mach-loongson/kernel-entry-init.h with 88% similarity]
arch/mips/include/asm/mach-loongson64/loongson.h [moved from arch/mips/include/asm/mach-loongson/loongson.h with 98% similarity]
arch/mips/include/asm/mach-loongson64/loongson_hwmon.h [moved from arch/mips/include/asm/mach-loongson/loongson_hwmon.h with 100% similarity]
arch/mips/include/asm/mach-loongson64/machine.h [moved from arch/mips/include/asm/mach-loongson/machine.h with 84% similarity]
arch/mips/include/asm/mach-loongson64/mc146818rtc.h [moved from arch/mips/include/asm/mach-loongson/mc146818rtc.h with 85% similarity]
arch/mips/include/asm/mach-loongson64/mem.h [moved from arch/mips/include/asm/mach-loongson/mem.h with 89% similarity]
arch/mips/include/asm/mach-loongson64/mmzone.h [moved from arch/mips/include/asm/mach-loongson/mmzone.h with 100% similarity]
arch/mips/include/asm/mach-loongson64/pci.h [moved from arch/mips/include/asm/mach-loongson/pci.h with 93% similarity]
arch/mips/include/asm/mach-loongson64/spaces.h [moved from arch/mips/include/asm/mach-loongson/spaces.h with 65% similarity]
arch/mips/include/asm/mach-loongson64/topology.h [moved from arch/mips/include/asm/mach-loongson/topology.h with 100% similarity]
arch/mips/include/asm/mach-loongson64/workarounds.h [new file with mode: 0644]
arch/mips/include/asm/mips-cm.h
arch/mips/include/asm/mipsregs.h
arch/mips/include/asm/pgtable-32.h
arch/mips/include/asm/prom.h
arch/mips/include/asm/spinlock.h
arch/mips/include/asm/txx9irq.h
arch/mips/include/asm/uaccess.h
arch/mips/include/asm/xtalk/xwidget.h
arch/mips/jz4740/Kconfig
arch/mips/jz4740/Makefile
arch/mips/jz4740/Platform
arch/mips/jz4740/board-qi_lb60.c
arch/mips/jz4740/clock-debugfs.c [deleted file]
arch/mips/jz4740/clock.c [deleted file]
arch/mips/jz4740/clock.h [deleted file]
arch/mips/jz4740/gpio.c
arch/mips/jz4740/irq.c [deleted file]
arch/mips/jz4740/platform.c
arch/mips/jz4740/pm.c
arch/mips/jz4740/prom.c
arch/mips/jz4740/reset.c
arch/mips/jz4740/serial.c [deleted file]
arch/mips/jz4740/serial.h [deleted file]
arch/mips/jz4740/setup.c
arch/mips/jz4740/time.c
arch/mips/kernel/Makefile
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/head.S
arch/mips/kernel/i8259.c
arch/mips/kernel/irq.c
arch/mips/kernel/kgdb.c
arch/mips/kernel/prom.c
arch/mips/kernel/sysrq.c [new file with mode: 0644]
arch/mips/kernel/traps.c
arch/mips/kernel/vmlinux.lds.S
arch/mips/lib/dump_tlb.c
arch/mips/lib/r3k_dump_tlb.c
arch/mips/loongson32/Kconfig [moved from arch/mips/loongson1/Kconfig with 95% similarity]
arch/mips/loongson32/Makefile [moved from arch/mips/loongson1/Makefile with 74% similarity]
arch/mips/loongson32/Platform [moved from arch/mips/loongson1/Platform with 59% similarity]
arch/mips/loongson32/common/Makefile [moved from arch/mips/loongson1/common/Makefile with 100% similarity]
arch/mips/loongson32/common/irq.c [moved from arch/mips/loongson1/common/irq.c with 100% similarity]
arch/mips/loongson32/common/platform.c [moved from arch/mips/loongson1/common/platform.c with 100% similarity]
arch/mips/loongson32/common/prom.c [moved from arch/mips/loongson1/common/prom.c with 100% similarity]
arch/mips/loongson32/common/reset.c [moved from arch/mips/loongson1/common/reset.c with 100% similarity]
arch/mips/loongson32/common/setup.c [moved from arch/mips/loongson1/common/setup.c with 100% similarity]
arch/mips/loongson32/common/time.c [moved from arch/mips/loongson1/common/time.c with 100% similarity]
arch/mips/loongson32/ls1b/Makefile [moved from arch/mips/loongson1/ls1b/Makefile with 100% similarity]
arch/mips/loongson32/ls1b/board.c [moved from arch/mips/loongson1/ls1b/board.c with 100% similarity]
arch/mips/loongson64/Kconfig [moved from arch/mips/loongson/Kconfig with 97% similarity]
arch/mips/loongson64/Makefile [moved from arch/mips/loongson/Makefile with 88% similarity]
arch/mips/loongson64/Platform [moved from arch/mips/loongson/Platform with 87% similarity]
arch/mips/loongson64/common/Makefile [moved from arch/mips/loongson/common/Makefile with 100% similarity]
arch/mips/loongson64/common/bonito-irq.c [moved from arch/mips/loongson/common/bonito-irq.c with 100% similarity]
arch/mips/loongson64/common/cmdline.c [moved from arch/mips/loongson/common/cmdline.c with 100% similarity]
arch/mips/loongson64/common/cs5536/Makefile [moved from arch/mips/loongson/common/cs5536/Makefile with 100% similarity]
arch/mips/loongson64/common/cs5536/cs5536_acc.c [moved from arch/mips/loongson/common/cs5536/cs5536_acc.c with 100% similarity]
arch/mips/loongson64/common/cs5536/cs5536_ehci.c [moved from arch/mips/loongson/common/cs5536/cs5536_ehci.c with 100% similarity]
arch/mips/loongson64/common/cs5536/cs5536_ide.c [moved from arch/mips/loongson/common/cs5536/cs5536_ide.c with 100% similarity]
arch/mips/loongson64/common/cs5536/cs5536_isa.c [moved from arch/mips/loongson/common/cs5536/cs5536_isa.c with 100% similarity]
arch/mips/loongson64/common/cs5536/cs5536_mfgpt.c [moved from arch/mips/loongson/common/cs5536/cs5536_mfgpt.c with 100% similarity]
arch/mips/loongson64/common/cs5536/cs5536_ohci.c [moved from arch/mips/loongson/common/cs5536/cs5536_ohci.c with 100% similarity]
arch/mips/loongson64/common/cs5536/cs5536_pci.c [moved from arch/mips/loongson/common/cs5536/cs5536_pci.c with 100% similarity]
arch/mips/loongson64/common/dma-swiotlb.c [moved from arch/mips/loongson/common/dma-swiotlb.c with 100% similarity]
arch/mips/loongson64/common/early_printk.c [moved from arch/mips/loongson/common/early_printk.c with 100% similarity]
arch/mips/loongson64/common/env.c [moved from arch/mips/loongson/common/env.c with 100% similarity]
arch/mips/loongson64/common/init.c [moved from arch/mips/loongson/common/init.c with 100% similarity]
arch/mips/loongson64/common/irq.c [moved from arch/mips/loongson/common/irq.c with 100% similarity]
arch/mips/loongson64/common/machtype.c [moved from arch/mips/loongson/common/machtype.c with 100% similarity]
arch/mips/loongson64/common/mem.c [moved from arch/mips/loongson/common/mem.c with 100% similarity]
arch/mips/loongson64/common/pci.c [moved from arch/mips/loongson/common/pci.c with 100% similarity]
arch/mips/loongson64/common/platform.c [moved from arch/mips/loongson/common/platform.c with 100% similarity]
arch/mips/loongson64/common/pm.c [moved from arch/mips/loongson/common/pm.c with 100% similarity]
arch/mips/loongson64/common/reset.c [moved from arch/mips/loongson/common/reset.c with 100% similarity]
arch/mips/loongson64/common/rtc.c [moved from arch/mips/loongson/common/rtc.c with 100% similarity]
arch/mips/loongson64/common/serial.c [moved from arch/mips/loongson/common/serial.c with 95% similarity]
arch/mips/loongson64/common/setup.c [moved from arch/mips/loongson/common/setup.c with 100% similarity]
arch/mips/loongson64/common/time.c [moved from arch/mips/loongson/common/time.c with 100% similarity]
arch/mips/loongson64/common/uart_base.c [moved from arch/mips/loongson/common/uart_base.c with 100% similarity]
arch/mips/loongson64/fuloong-2e/Makefile [moved from arch/mips/loongson/fuloong-2e/Makefile with 100% similarity]
arch/mips/loongson64/fuloong-2e/irq.c [moved from arch/mips/loongson/fuloong-2e/irq.c with 100% similarity]
arch/mips/loongson64/fuloong-2e/reset.c [moved from arch/mips/loongson/fuloong-2e/reset.c with 100% similarity]
arch/mips/loongson64/lemote-2f/Makefile [moved from arch/mips/loongson/lemote-2f/Makefile with 100% similarity]
arch/mips/loongson64/lemote-2f/clock.c [moved from arch/mips/loongson/lemote-2f/clock.c with 100% similarity]
arch/mips/loongson64/lemote-2f/ec_kb3310b.c [moved from arch/mips/loongson/lemote-2f/ec_kb3310b.c with 100% similarity]
arch/mips/loongson64/lemote-2f/ec_kb3310b.h [moved from arch/mips/loongson/lemote-2f/ec_kb3310b.h with 100% similarity]
arch/mips/loongson64/lemote-2f/irq.c [moved from arch/mips/loongson/lemote-2f/irq.c with 100% similarity]
arch/mips/loongson64/lemote-2f/machtype.c [moved from arch/mips/loongson/lemote-2f/machtype.c with 100% similarity]
arch/mips/loongson64/lemote-2f/pm.c [moved from arch/mips/loongson/lemote-2f/pm.c with 100% similarity]
arch/mips/loongson64/lemote-2f/reset.c [moved from arch/mips/loongson/lemote-2f/reset.c with 100% similarity]
arch/mips/loongson64/loongson-3/Makefile [moved from arch/mips/loongson/loongson-3/Makefile with 100% similarity]
arch/mips/loongson64/loongson-3/cop2-ex.c [moved from arch/mips/loongson/loongson-3/cop2-ex.c with 100% similarity]
arch/mips/loongson64/loongson-3/hpet.c [moved from arch/mips/loongson/loongson-3/hpet.c with 100% similarity]
arch/mips/loongson64/loongson-3/irq.c [moved from arch/mips/loongson/loongson-3/irq.c with 100% similarity]
arch/mips/loongson64/loongson-3/numa.c [moved from arch/mips/loongson/loongson-3/numa.c with 100% similarity]
arch/mips/loongson64/loongson-3/platform.c [moved from arch/mips/loongson/loongson-3/platform.c with 100% similarity]
arch/mips/loongson64/loongson-3/smp.c [moved from arch/mips/loongson/loongson-3/smp.c with 100% similarity]
arch/mips/loongson64/loongson-3/smp.h [moved from arch/mips/loongson/loongson-3/smp.h with 100% similarity]
arch/mips/mm/c-r4k.c
arch/mips/mm/c-tx39.c
arch/mips/mm/dma-default.c
arch/mips/mm/tlb-r3k.c
arch/mips/mm/tlb-r4k.c
arch/mips/mm/tlbex.c
arch/mips/mti-malta/Makefile
arch/mips/mti-malta/malta-dt.c [new file with mode: 0644]
arch/mips/mti-malta/malta-setup.c
arch/mips/net/Makefile
arch/mips/net/bpf_jit.c
arch/mips/net/bpf_jit.h
arch/mips/net/bpf_jit_asm.S [new file with mode: 0644]
arch/mips/netlogic/xlr/platform-flash.c
arch/mips/pci/pci-ar2315.c
arch/mips/pci/pci-ar71xx.c
arch/mips/pci/pci-ar724x.c
arch/mips/pci/pci-rt3883.c
arch/mips/ralink/irq.c
arch/mips/sgi-ip27/Makefile
arch/mips/sgi-ip27/ip27-irqno.c [new file with mode: 0644]
arch/mips/sibyte/Kconfig
arch/mips/txx9/Kconfig
arch/mips/vr41xx/Kconfig
drivers/clk/Makefile
drivers/clk/ingenic/Makefile [new file with mode: 0644]
drivers/clk/ingenic/cgu.c [new file with mode: 0644]
drivers/clk/ingenic/cgu.h [new file with mode: 0644]
drivers/clk/ingenic/jz4740-cgu.c [new file with mode: 0644]
drivers/clk/ingenic/jz4780-cgu.c [new file with mode: 0644]
drivers/cpufreq/ls1x-cpufreq.c
drivers/firmware/Kconfig
drivers/firmware/Makefile
drivers/firmware/broadcom/Kconfig [new file with mode: 0644]
drivers/firmware/broadcom/Makefile [new file with mode: 0644]
drivers/firmware/broadcom/bcm47xx_nvram.c [moved from arch/mips/bcm47xx/nvram.c with 78% similarity]
drivers/irqchip/Kconfig
drivers/irqchip/Makefile
drivers/irqchip/irq-ingenic.c [new file with mode: 0644]
drivers/irqchip/irq-mips-cpu.c [moved from arch/mips/kernel/irq_cpu.c with 97% similarity]
drivers/phy/Kconfig
drivers/phy/Makefile
drivers/phy/phy-pistachio-usb.c [new file with mode: 0644]
drivers/rtc/Kconfig
drivers/rtc/rtc-ls1x.c
drivers/tty/serial/8250/8250_ingenic.c [new file with mode: 0644]
drivers/tty/serial/8250/Kconfig
drivers/tty/serial/8250/Makefile
drivers/tty/sysrq.c
drivers/usb/host/Kconfig
include/dt-bindings/clock/jz4740-cgu.h [new file with mode: 0644]
include/dt-bindings/clock/jz4780-cgu.h [new file with mode: 0644]
include/dt-bindings/phy/phy-pistachio-usb.h [new file with mode: 0644]
include/linux/bcm47xx_nvram.h
include/linux/irqchip/ingenic.h [moved from arch/mips/jz4740/irq.h with 74% similarity]
include/linux/platform_data/gpio-ath79.h [new file with mode: 0644]
include/linux/ssb/ssb.h

diff --git a/Documentation/devicetree/bindings/clock/ingenic,cgu.txt b/Documentation/devicetree/bindings/clock/ingenic,cgu.txt
new file mode 100644 (file)
index 0000000..f8d4134
--- /dev/null
@@ -0,0 +1,53 @@
+Ingenic SoC CGU binding
+
+The CGU in an Ingenic SoC provides all the clocks generated on-chip. It
+typically includes a variety of PLLs, multiplexers, dividers & gates in order
+to provide many different clock signals derived from only 2 external source
+clocks.
+
+Required properties:
+- compatible : Should be "ingenic,<soctype>-cgu".
+  For example "ingenic,jz4740-cgu" or "ingenic,jz4780-cgu".
+- reg : The address & length of the CGU registers.
+- clocks : List of phandle & clock specifiers for clocks external to the CGU.
+  Two such external clocks should be specified - first the external crystal
+  "ext" and second the RTC clock source "rtc".
+- clock-names : List of name strings for the external clocks.
+- #clock-cells: Should be 1.
+  Clock consumers specify this argument to identify a clock. The valid values
+  may be found in <dt-bindings/clock/<soctype>-cgu.h>.
+
+Example SoC include file:
+
+/ {
+       cgu: jz4740-cgu {
+               compatible = "ingenic,jz4740-cgu";
+               reg = <0x10000000 0x100>;
+               #clock-cells = <1>;
+       };
+
+       uart0: serial@10030000 {
+               clocks = <&cgu JZ4740_CLK_UART0>;
+       };
+};
+
+Example board file:
+
+/ {
+       ext: clock@0 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <12000000>;
+       };
+
+       rtc: clock@1 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+       };
+
+       &cgu {
+               clocks = <&ext> <&rtc>;
+               clock-names: "ext", "rtc";
+       };
+};
diff --git a/Documentation/devicetree/bindings/clock/qca,ath79-pll.txt b/Documentation/devicetree/bindings/clock/qca,ath79-pll.txt
new file mode 100644 (file)
index 0000000..e0fc2c1
--- /dev/null
@@ -0,0 +1,33 @@
+Binding for Qualcomm Atheros AR7xxx/AR9XXX PLL controller
+
+The PPL controller provides the 3 main clocks of the SoC: CPU, DDR and AHB.
+
+Required Properties:
+- compatible: has to be "qca,<soctype>-cpu-intc" and one of the following
+  fallbacks:
+  - "qca,ar7100-pll"
+  - "qca,ar7240-pll"
+  - "qca,ar9130-pll"
+  - "qca,ar9330-pll"
+  - "qca,ar9340-pll"
+  - "qca,qca9550-pll"
+- reg: Base address and size of the controllers memory area
+- clock-names: Name of the input clock, has to be "ref"
+- clocks: phandle of the external reference clock
+- #clock-cells: has to be one
+
+Optional properties:
+- clock-output-names: should be "cpu", "ddr", "ahb"
+
+Example:
+
+       memory-controller@18050000 {
+               compatible = "qca,ar9132-ppl", "qca,ar9130-pll";
+               reg = <0x18050000 0x20>;
+
+               clock-names = "ref";
+               clocks = <&extosc>;
+
+               #clock-cells = <1>;
+               clock-output-names = "cpu", "ddr", "ahb";
+       };
diff --git a/Documentation/devicetree/bindings/gpio/gpio-ath79.txt b/Documentation/devicetree/bindings/gpio/gpio-ath79.txt
new file mode 100644 (file)
index 0000000..c522851
--- /dev/null
@@ -0,0 +1,38 @@
+Binding for Qualcomm Atheros AR7xxx/AR9xxx GPIO controller
+
+Required properties:
+- compatible: has to be "qca,<soctype>-gpio" and one of the following
+  fallbacks:
+  - "qca,ar7100-gpio"
+  - "qca,ar9340-gpio"
+- reg: Base address and size of the controllers memory area
+- gpio-controller : Marks the device node as a GPIO controller.
+- #gpio-cells : Should be two. The first cell is the pin number and the
+  second cell is used to specify optional parameters.
+- ngpios: Should be set to the number of GPIOs available on the SoC.
+
+Optional properties:
+- interrupt-parent: phandle of the parent interrupt controller.
+- interrupts: Interrupt specifier for the controllers interrupt.
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : Specifies the number of cells needed to encode interrupt
+                    source, should be 2
+
+Please refer to interrupts.txt in this directory for details of the common
+Interrupt Controllers bindings used by client devices.
+
+Example:
+
+       gpio@18040000 {
+               compatible = "qca,ar9132-gpio", "qca,ar7100-gpio";
+               reg = <0x18040000 0x30>;
+               interrupts = <2>;
+
+               ngpios = <22>;
+
+               gpio-controller;
+               #gpio-cells = <2>;
+
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
diff --git a/Documentation/devicetree/bindings/interrupt-controller/ingenic,intc.txt b/Documentation/devicetree/bindings/interrupt-controller/ingenic,intc.txt
new file mode 100644 (file)
index 0000000..5f89fb6
--- /dev/null
@@ -0,0 +1,28 @@
+Ingenic SoC Interrupt Controller
+
+Required properties:
+
+- compatible : should be "ingenic,<socname>-intc". Valid strings are:
+    ingenic,jz4740-intc
+    ingenic,jz4770-intc
+    ingenic,jz4775-intc
+    ingenic,jz4780-intc
+- reg : Specifies base physical address and size of the registers.
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : Specifies the number of cells needed to encode an
+  interrupt source. The value shall be 1.
+- interrupt-parent : phandle of the CPU interrupt controller.
+- interrupts : Specifies the CPU interrupt the controller is connected to.
+
+Example:
+
+intc: interrupt-controller@10001000 {
+       compatible = "ingenic,jz4740-intc";
+       reg = <0x10001000 0x14>;
+
+       interrupt-controller;
+       #interrupt-cells = <1>;
+
+       interrupt-parent = <&cpuintc>;
+       interrupts = <2>;
+};
diff --git a/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-cpu-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-cpu-intc.txt
new file mode 100644 (file)
index 0000000..aabce78
--- /dev/null
@@ -0,0 +1,44 @@
+Binding for Qualcomm Atheros AR7xxx/AR9XXX CPU interrupt controller
+
+On most SoC the IRQ controller need to flush the DDR FIFO before running
+the interrupt handler of some devices. This is configured using the
+qca,ddr-wb-channels and qca,ddr-wb-channel-interrupts properties.
+
+Required Properties:
+
+- compatible: has to be "qca,<soctype>-cpu-intc", "qca,ar7100-cpu-intc"
+  as fallback
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : Specifies the number of cells needed to encode interrupt
+                    source, should be 1 for intc
+
+Please refer to interrupts.txt in this directory for details of the common
+Interrupt Controllers bindings used by client devices.
+
+Optional Properties:
+
+- qca,ddr-wb-channel-interrupts: List of the interrupts needing a write
+  buffer flush
+- qca,ddr-wb-channels: List of phandles to the write buffer channels for
+  each interrupt. If qca,ddr-wb-channel-interrupts is not present the interrupt
+  default to the entry's index.
+
+Example:
+
+       interrupt-controller {
+               compatible = "qca,ar9132-cpu-intc", "qca,ar7100-cpu-intc";
+
+               interrupt-controller;
+               #interrupt-cells = <1>;
+
+               qca,ddr-wb-channel-interrupts = <2>, <3>, <4>, <5>;
+               qca,ddr-wb-channels = <&ddr_ctrl 3>, <&ddr_ctrl 2>,
+                                       <&ddr_ctrl 0>, <&ddr_ctrl 1>;
+       };
+
+       ...
+
+       ddr_ctrl: memory-controller@18000000 {
+               ...
+               #qca,ddr-wb-channel-cells = <1>;
+       };
diff --git a/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-misc-intc.txt b/Documentation/devicetree/bindings/interrupt-controller/qca,ath79-misc-intc.txt
new file mode 100644 (file)
index 0000000..391717a
--- /dev/null
@@ -0,0 +1,30 @@
+Binding for Qualcomm Atheros AR7xxx/AR9XXX MISC interrupt controller
+
+The MISC interrupt controller is a secondary controller for lower priority
+interrupt.
+
+Required Properties:
+- compatible: has to be "qca,<soctype>-cpu-intc", "qca,ar7100-misc-intc"
+  as fallback
+- reg: Base address and size of the controllers memory area
+- interrupt-parent: phandle of the parent interrupt controller.
+- interrupts: Interrupt specifier for the controllers interrupt.
+- interrupt-controller : Identifies the node as an interrupt controller
+- #interrupt-cells : Specifies the number of cells needed to encode interrupt
+                    source, should be 1
+
+Please refer to interrupts.txt in this directory for details of the common
+Interrupt Controllers bindings used by client devices.
+
+Example:
+
+       interrupt-controller@18060010 {
+               compatible = "qca,ar9132-misc-intc", qca,ar7100-misc-intc";
+               reg = <0x18060010 0x4>;
+
+               interrupt-parent = <&cpuintc>;
+               interrupts = <6>;
+
+               interrupt-controller;
+               #interrupt-cells = <1>;
+       };
diff --git a/Documentation/devicetree/bindings/memory-controllers/ath79-ddr-controller.txt b/Documentation/devicetree/bindings/memory-controllers/ath79-ddr-controller.txt
new file mode 100644 (file)
index 0000000..efe35a0
--- /dev/null
@@ -0,0 +1,35 @@
+Binding for Qualcomm  Atheros AR7xxx/AR9xxx DDR controller
+
+The DDR controller of the ARxxx and AR9xxx families provides an interface
+to flush the FIFO between various devices and the DDR. This is mainly used
+by the IRQ controller to flush the FIFO before running the interrupt handler
+of such devices.
+
+Required properties:
+
+- compatible: has to be "qca,<soc-type>-ddr-controller",
+  "qca,[ar7100|ar7240]-ddr-controller" as fallback.
+  On SoC with PCI support "qca,ar7100-ddr-controller" should be used as
+  fallback, otherwise "qca,ar7240-ddr-controller" should be used.
+- reg: Base address and size of the controllers memory area
+- #qca,ddr-wb-channel-cells: has to be 1, the index of the write buffer
+  channel
+
+Example:
+
+       ddr_ctrl: memory-controller@18000000 {
+               compatible = "qca,ar9132-ddr-controller",
+                               "qca,ar7240-ddr-controller";
+               reg = <0x18000000 0x100>;
+
+               #qca,ddr-wb-channel-cells = <1>;
+       };
+
+       ...
+
+       interrupt-controller {
+               ...
+               qca,ddr-wb-channel-interrupts = <2>, <3>, <4>, <5>;
+               qca,ddr-wb-channels = <&ddr_ctrl 3>, <&ddr_ctrl 2>,
+                                       <&ddr_ctrl 0>, <&ddr_ctrl 1>;
+       };
diff --git a/Documentation/devicetree/bindings/mips/ath79-soc.txt b/Documentation/devicetree/bindings/mips/ath79-soc.txt
new file mode 100644 (file)
index 0000000..88a12a4
--- /dev/null
@@ -0,0 +1,21 @@
+Binding for Qualcomm Atheros AR7xxx/AR9XXX SoC
+
+Each device tree must specify a compatible value for the AR SoC
+it uses in the compatible property of the root node. The compatible
+value must be one of the following values:
+
+- qca,ar7130
+- qca,ar7141
+- qca,ar7161
+- qca,ar7240
+- qca,ar7241
+- qca,ar7242
+- qca,ar9130
+- qca,ar9132
+- qca,ar9330
+- qca,ar9331
+- qca,ar9341
+- qca,ar9342
+- qca,ar9344
+- qca,qca9556
+- qca,qca9558
diff --git a/Documentation/devicetree/bindings/phy/pistachio-usb-phy.txt b/Documentation/devicetree/bindings/phy/pistachio-usb-phy.txt
new file mode 100644 (file)
index 0000000..afbc7e2
--- /dev/null
@@ -0,0 +1,29 @@
+IMG Pistachio USB PHY
+=====================
+
+Required properties:
+--------------------
+ - compatible: Must be "img,pistachio-usb-phy".
+ - #phy-cells: Must be 0.  See ./phy-bindings.txt for details.
+ - clocks: Must contain an entry for each entry in clock-names.
+   See ../clock/clock-bindings.txt for details.
+ - clock-names: Must include "usb_phy".
+ - img,cr-top: Must constain a phandle to the CR_TOP syscon node.
+ - img,refclk: Indicates the reference clock source for the USB PHY.
+   See <dt-bindings/phy/phy-pistachio-usb.h> for a list of valid values.
+
+Optional properties:
+--------------------
+ - phy-supply: USB VBUS supply.  Must supply 5.0V.
+
+Example:
+--------
+usb_phy: usb-phy {
+       compatible = "img,pistachio-usb-phy";
+       clocks = <&clk_core CLK_USB_PHY>;
+       clock-names = "usb_phy";
+       phy-supply = <&usb_vbus>;
+       img,refclk = <REFCLK_CLK_CORE>;
+       img,cr-top = <&cr_top>;
+       #phy-cells = <0>;
+};
diff --git a/Documentation/devicetree/bindings/serial/ingenic,uart.txt b/Documentation/devicetree/bindings/serial/ingenic,uart.txt
new file mode 100644 (file)
index 0000000..c2d3b3a
--- /dev/null
@@ -0,0 +1,22 @@
+* Ingenic SoC UART
+
+Required properties:
+- compatible : "ingenic,jz4740-uart" or "ingenic,jz4780-uart"
+- reg : offset and length of the register set for the device.
+- interrupts : should contain uart interrupt.
+- clocks : phandles to the module & baud clocks.
+- clock-names: tuple listing input clock names.
+       Required elements: "baud", "module"
+
+Example:
+
+uart0: serial@10030000 {
+       compatible = "ingenic,jz4740-uart";
+       reg = <0x10030000 0x100>;
+
+       interrupt-parent = <&intc>;
+       interrupts = <9>;
+
+       clocks = <&ext>, <&cgu JZ4740_CLK_UART0>;
+       clock-names = "baud", "module";
+};
index 8e8f4bc..7b60776 100644 (file)
@@ -106,6 +106,7 @@ ibm International Business Machines (IBM)
 idt    Integrated Device Technologies, Inc.
 iom    Iomega Corporation
 img    Imagination Technologies Ltd.
+ingenic        Ingenic Semiconductor
 innolux        Innolux Corporation
 intel  Intel Corporation
 intercontrol   Inter Control Group
@@ -161,6 +162,7 @@ powervr     PowerVR (deprecated, use img)
 qca    Qualcomm Atheros, Inc.
 qcom   Qualcomm Technologies, Inc
 qemu   QEMU, a generic and open source machine emulator and virtualizer
+qi     Qi Hardware
 qnap   QNAP Systems, Inc.
 radxa  Radxa
 raidsonic      RaidSonic Technology GmbH
@@ -206,6 +208,7 @@ tlm Trusted Logic Mobility
 toradex        Toradex AG
 toshiba        Toshiba Corporation
 toumaz Toumaz
+tplink TP-LINK Technologies Co., Ltd.
 truly  Truly Semiconductors Limited
 usi    Universal Scientific Industrial Co., Ltd.
 v3     V3 Semiconductor
index c54a674..6aedd50 100644 (file)
@@ -2229,6 +2229,14 @@ F:       arch/mips/bcm3384/*
 F:     arch/mips/include/asm/mach-bcm3384/*
 F:     arch/mips/kernel/*bmips*
 
+BROADCOM BCM47XX MIPS ARCHITECTURE
+M:     Hauke Mehrtens <hauke@hauke-m.de>
+M:     RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com>
+L:     linux-mips@linux-mips.org
+S:     Maintained
+F:     arch/mips/bcm47xx/*
+F:     arch/mips/include/asm/mach-bcm47xx/*
+
 BROADCOM BCM5301X ARM ARCHITECTURE
 M:     Hauke Mehrtens <hauke@hauke-m.de>
 L:     linux-arm-kernel@lists.infradead.org
@@ -2333,6 +2341,12 @@ S:       Supported
 F:     drivers/gpio/gpio-bcm-kona.c
 F:     Documentation/devicetree/bindings/gpio/gpio-bcm-kona.txt
 
+BROADCOM NVRAM DRIVER
+M:     RafaÅ‚ MiÅ‚ecki <zajec5@gmail.com>
+L:     linux-mips@linux-mips.org
+S:     Maintained
+F:     drivers/firmware/broadcom/*
+
 BROADCOM STB NAND FLASH DRIVER
 M:     Brian Norris <computersforpeace@gmail.com>
 L:     linux-mtd@lists.infradead.org
index 39cf40d..a424e46 100644 (file)
@@ -15,8 +15,8 @@ platforms += jazz
 platforms += jz4740
 platforms += lantiq
 platforms += lasat
-platforms += loongson
-platforms += loongson1
+platforms += loongson32
+platforms += loongson64
 platforms += mti-malta
 platforms += mti-sead3
 platforms += netlogic
index b65edf5..2a14585 100644 (file)
@@ -21,11 +21,12 @@ config MIPS
        select HAVE_FUNCTION_GRAPH_TRACER
        select HAVE_KPROBES
        select HAVE_KRETPROBES
+       select HAVE_SYSCALL_TRACEPOINTS
        select HAVE_DEBUG_KMEMLEAK
        select HAVE_SYSCALL_TRACEPOINTS
        select ARCH_HAS_ELF_RANDOMIZE
        select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT
-       select RTC_LIB if !MACH_LOONGSON
+       select RTC_LIB if !MACH_LOONGSON64
        select GENERIC_ATOMIC64 if !64BIT
        select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
        select HAVE_DMA_ATTRS
@@ -70,7 +71,7 @@ config MIPS_ALCHEMY
        select ARCH_PHYS_ADDR_T_64BIT
        select CEVT_R4K
        select CSRC_R4K
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select DMA_MAYBE_COHERENT       # Au1000,1500,1100 aren't, rest is
        select SYS_HAS_CPU_MIPS32_R1
        select SYS_SUPPORTS_32BIT_KERNEL
@@ -85,7 +86,7 @@ config AR7
        select DMA_NONCOHERENT
        select CEVT_R4K
        select CSRC_R4K
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select NO_EXCEPT_FILL
        select SWAP_IO_SPACE
        select SYS_HAS_CPU_MIPS32_R1
@@ -106,7 +107,7 @@ config ATH25
        select CEVT_R4K
        select CSRC_R4K
        select DMA_NONCOHERENT
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select IRQ_DOMAIN
        select SYS_HAS_CPU_MIPS32_R1
        select SYS_SUPPORTS_BIG_ENDIAN
@@ -123,14 +124,17 @@ config ATH79
        select CSRC_R4K
        select DMA_NONCOHERENT
        select HAVE_CLK
+       select COMMON_CLK
        select CLKDEV_LOOKUP
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select MIPS_MACHINE
        select SYS_HAS_CPU_MIPS32_R2
        select SYS_HAS_EARLY_PRINTK
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_BIG_ENDIAN
        select SYS_SUPPORTS_MIPS16
+       select SYS_SUPPORTS_ZBOOT
+       select USE_OF
        help
          Support for the Atheros AR71XX/AR724X/AR913X SoCs.
 
@@ -146,7 +150,7 @@ config BMIPS_GENERIC
        select BCM7038_L1_IRQ
        select BCM7120_L2_IRQ
        select BRCMSTB_L2_IRQ
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select RAW_IRQ_ACCESSORS
        select DMA_NONCOHERENT
        select SYS_SUPPORTS_32BIT_KERNEL
@@ -176,7 +180,7 @@ config BCM47XX
        select CSRC_R4K
        select DMA_NONCOHERENT
        select HW_HAS_PCI
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select SYS_HAS_CPU_MIPS32_R1
        select NO_EXCEPT_FILL
        select SYS_SUPPORTS_32BIT_KERNEL
@@ -186,6 +190,7 @@ config BCM47XX
        select USE_GENERIC_EARLY_PRINTK_8250
        select GPIOLIB
        select LEDS_GPIO_REGISTER
+       select BCM47XX_NVRAM
        help
         Support for BCM47XX based boards
 
@@ -196,7 +201,7 @@ config BCM63XX
        select CSRC_R4K
        select SYNC_R4K
        select DMA_NONCOHERENT
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_BIG_ENDIAN
        select SYS_HAS_EARLY_PRINTK
@@ -216,7 +221,7 @@ config MIPS_COBALT
        select HW_HAS_PCI
        select I8253
        select I8259
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select IRQ_GT641XX
        select PCI_GT64XXX_PCI0
        select PCI
@@ -239,7 +244,7 @@ config MACH_DECSTATION
        select CPU_R4400_WORKAROUNDS if 64BIT
        select DMA_NONCOHERENT
        select NO_IOPORT_MAP
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select SYS_HAS_CPU_R3000
        select SYS_HAS_CPU_R4X00
        select SYS_SUPPORTS_32BIT_KERNEL
@@ -274,7 +279,7 @@ config MACH_JAZZ
        select DEFAULT_SGI_PARTITION if CPU_BIG_ENDIAN
        select GENERIC_ISA_DMA
        select HAVE_PCSPKR_PLATFORM
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select I8253
        select I8259
        select ISA
@@ -288,23 +293,24 @@ config MACH_JAZZ
         Members include the Acer PICA, MIPS Magnum 4000, MIPS Millennium and
         Olivetti M700-10 workstations.
 
-config MACH_JZ4740
-       bool "Ingenic JZ4740 based machines"
-       select SYS_HAS_CPU_MIPS32_R1
+config MACH_INGENIC
+       bool "Ingenic SoC based machines"
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_LITTLE_ENDIAN
        select SYS_SUPPORTS_ZBOOT_UART16550
        select DMA_NONCOHERENT
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select ARCH_REQUIRE_GPIOLIB
-       select SYS_HAS_EARLY_PRINTK
-       select HAVE_CLK
+       select COMMON_CLK
        select GENERIC_IRQ_CHIP
+       select BUILTIN_DTB
+       select USE_OF
+       select LIBFDT
 
 config LANTIQ
        bool "Lantiq based platforms"
        select DMA_NONCOHERENT
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select CEVT_R4K
        select CSRC_R4K
        select SYS_HAS_CPU_MIPS32_R1
@@ -333,7 +339,7 @@ config LASAT
        select DMA_NONCOHERENT
        select SYS_HAS_EARLY_PRINTK
        select HW_HAS_PCI
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select PCI_GT64XXX_PCI0
        select MIPS_NILE4
        select R5000_CPU_SCACHE
@@ -342,26 +348,28 @@ config LASAT
        select SYS_SUPPORTS_64BIT_KERNEL if BROKEN
        select SYS_SUPPORTS_LITTLE_ENDIAN
 
-config MACH_LOONGSON
-       bool "Loongson family of machines"
+config MACH_LOONGSON32
+       bool "Loongson-1 family of machines"
        select SYS_SUPPORTS_ZBOOT
        help
-         This enables the support of Loongson family of machines.
+         This enables support for the Loongson-1 family of machines.
 
-         Loongson is a family of general-purpose MIPS-compatible CPUs.
-         developed at Institute of Computing Technology (ICT),
-         Chinese Academy of Sciences (CAS) in the People's Republic
-         of China. The chief architect is Professor Weiwu Hu.
+         Loongson-1 is a family of 32-bit MIPS-compatible SoCs developed by
+         the Institute of Computing Technology (ICT), Chinese Academy of
+         Sciences (CAS).
 
-config MACH_LOONGSON1
-       bool "Loongson 1 family of machines"
+config MACH_LOONGSON64
+       bool "Loongson-2/3 family of machines"
        select SYS_SUPPORTS_ZBOOT
        help
-         This enables support for the Loongson 1 based machines.
+         This enables the support of Loongson-2/3 family of machines.
 
-         Loongson 1 is a family of 32-bit MIPS-compatible SoCs developed by
-         the ICT (Institute of Computing Technology) and the Chinese Academy
-         of Sciences.
+         Loongson-2 is a family of single-core CPUs and Loongson-3 is a
+         family of multi-core CPUs. They are both 64-bit general-purpose
+         MIPS-compatible CPUs. Loongson-2/3 are developed by the Institute
+         of Computing Technology (ICT), Chinese Academy of Sciences (CAS)
+         in the People's Republic of China. The chief architect is Professor
+         Weiwu Hu.
 
 config MACH_PISTACHIO
        bool "IMG Pistachio SoC based boards"
@@ -373,7 +381,7 @@ config MACH_PISTACHIO
        select COMMON_CLK
        select CSRC_R4K
        select DMA_MAYBE_COHERENT
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select LIBFDT
        select MFD_SYSCON
        select MIPS_CPU_SCACHE
@@ -386,6 +394,8 @@ config MACH_PISTACHIO
        select SYS_SUPPORTS_MIPS_CPS
        select SYS_SUPPORTS_MULTITHREADING
        select SYS_SUPPORTS_ZBOOT
+       select SYS_HAS_EARLY_PRINTK
+       select USE_GENERIC_EARLY_PRINTK_8250
        select USE_OF
        help
          This enables support for the IMG Pistachio SoC platform.
@@ -395,13 +405,14 @@ config MIPS_MALTA
        select ARCH_MAY_HAVE_PC_FDC
        select BOOT_ELF32
        select BOOT_RAW
+       select BUILTIN_DTB
        select CEVT_R4K
        select CSRC_R4K
        select CLKSRC_MIPS_GIC
        select DMA_MAYBE_COHERENT
        select GENERIC_ISA_DMA
        select HAVE_PCSPKR_PLATFORM
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select MIPS_GIC
        select HW_HAS_PCI
        select I8253
@@ -434,6 +445,8 @@ config MIPS_MALTA
        select SYS_SUPPORTS_MULTITHREADING
        select SYS_SUPPORTS_SMARTMIPS
        select SYS_SUPPORTS_ZBOOT
+       select USE_OF
+       select ZONE_DMA32 if 64BIT
        help
          This enables support for the MIPS Technologies Malta evaluation
          board.
@@ -449,7 +462,7 @@ config MIPS_SEAD3
        select CPU_MIPSR2_IRQ_VI
        select CPU_MIPSR2_IRQ_EI
        select DMA_NONCOHERENT
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select MIPS_GIC
        select LIBFDT
        select MIPS_MSC
@@ -512,7 +525,7 @@ config PMC_MSP
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_BIG_ENDIAN
        select SYS_SUPPORTS_MIPS16
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select SERIAL_8250
        select SERIAL_8250_CONSOLE
        select USB_EHCI_BIG_ENDIAN_MMIO
@@ -529,7 +542,7 @@ config RALINK
        select CSRC_R4K
        select BOOT_RAW
        select DMA_NONCOHERENT
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select USE_OF
        select SYS_HAS_CPU_MIPS32_R1
        select SYS_HAS_CPU_MIPS32_R2
@@ -555,7 +568,7 @@ config SGI_IP22
        select I8253
        select I8259
        select IP22_CPU_SCACHE
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select GENERIC_ISA_DMA_SUPPORT_BROKEN
        select SGI_HAS_I8042
        select SGI_HAS_INDYDOG
@@ -614,7 +627,7 @@ config SGI_IP28
        select DEFAULT_SGI_PARTITION
        select DMA_NONCOHERENT
        select GENERIC_ISA_DMA_SUPPORT_BROKEN
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select HW_HAS_EISA
        select I8253
        select I8259
@@ -650,7 +663,7 @@ config SGI_IP32
        select CSRC_R4K
        select DMA_NONCOHERENT
        select HW_HAS_PCI
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select R5000_CPU_SCACHE
        select RM7000_CPU_SCACHE
        select SYS_HAS_CPU_R5000
@@ -766,7 +779,7 @@ config SNI_RM
        select HAVE_PCSPKR_PLATFORM
        select HW_HAS_EISA
        select HW_HAS_PCI
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select I8253
        select I8259
        select ISA
@@ -799,7 +812,7 @@ config MIKROTIK_RB532
        select CSRC_R4K
        select DMA_NONCOHERENT
        select HW_HAS_PCI
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select SYS_HAS_CPU_MIPS32_R1
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -866,7 +879,7 @@ config NLM_XLR_BOARD
        select NR_CPUS_DEFAULT_32
        select CEVT_R4K
        select CSRC_R4K
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select ZONE_DMA32 if 64BIT
        select SYNC_R4K
        select SYS_HAS_EARLY_PRINTK
@@ -893,7 +906,7 @@ config NLM_XLP_BOARD
        select NR_CPUS_DEFAULT_32
        select CEVT_R4K
        select CSRC_R4K
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select ZONE_DMA32 if 64BIT
        select SYNC_R4K
        select SYS_HAS_EARLY_PRINTK
@@ -942,8 +955,8 @@ source "arch/mips/sibyte/Kconfig"
 source "arch/mips/txx9/Kconfig"
 source "arch/mips/vr41xx/Kconfig"
 source "arch/mips/cavium-octeon/Kconfig"
-source "arch/mips/loongson/Kconfig"
-source "arch/mips/loongson1/Kconfig"
+source "arch/mips/loongson32/Kconfig"
+source "arch/mips/loongson64/Kconfig"
 source "arch/mips/netlogic/Kconfig"
 source "arch/mips/paravirt/Kconfig"
 
@@ -1142,10 +1155,6 @@ config SYS_SUPPORTS_HUGETLBFS
 config MIPS_HUGE_TLB_SUPPORT
        def_bool HUGETLB_PAGE || TRANSPARENT_HUGEPAGE
 
-config IRQ_CPU
-       bool
-       select IRQ_DOMAIN
-
 config IRQ_CPU_RM7K
        bool
 
@@ -1172,7 +1181,7 @@ config SOC_EMMA2RH
        select CEVT_R4K
        select CSRC_R4K
        select DMA_NONCOHERENT
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select SWAP_IO_SPACE
        select SYS_HAS_CPU_R5500
        select SYS_SUPPORTS_32BIT_KERNEL
@@ -1183,7 +1192,7 @@ config SOC_PNX833X
        bool
        select CEVT_R4K
        select CSRC_R4K
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select DMA_NONCOHERENT
        select SYS_HAS_CPU_MIPS32_R2
        select SYS_SUPPORTS_32BIT_KERNEL
@@ -1569,7 +1578,8 @@ config CPU_CAVIUM_OCTEON
        select WEAK_ORDERING
        select CPU_SUPPORTS_HIGHMEM
        select CPU_SUPPORTS_HUGEPAGES
-       select USB_EHCI_BIG_ENDIAN_MMIO
+       select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
+       select USB_OHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
        select MIPS_L1_CACHE_SHIFT_7
        help
          The Cavium Octeon processor is a highly integrated chip containing
@@ -1587,7 +1597,7 @@ config CPU_BMIPS
        select CPU_BMIPS5000 if SYS_HAS_CPU_BMIPS5000
        select CPU_SUPPORTS_32BIT_KERNEL
        select DMA_NONCOHERENT
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select SWAP_IO_SPACE
        select WEAK_ORDERING
        select CPU_SUPPORTS_HIGHMEM
@@ -2672,6 +2682,51 @@ config USE_OF
 config BUILTIN_DTB
        bool
 
+choice
+       prompt "Kernel appended dtb support" if OF
+       default MIPS_NO_APPENDED_DTB
+
+       config MIPS_NO_APPENDED_DTB
+               bool "None"
+               help
+                 Do not enable appended dtb support.
+
+       config MIPS_RAW_APPENDED_DTB
+               bool "vmlinux.bin"
+               help
+                 With this option, the boot code will look for a device tree binary
+                 DTB) appended to raw vmlinux.bin (without decompressor).
+                 (e.g. cat vmlinux.bin <filename>.dtb > vmlinux_w_dtb).
+
+                 This is meant as a backward compatibility convenience for those
+                 systems with a bootloader that can't be upgraded to accommodate
+                 the documented boot protocol using a device tree.
+
+                 Beware that there is very little in terms of protection against
+                 this option being confused by leftover garbage in memory that might
+                 look like a DTB header after a reboot if no actual DTB is appended
+                 to vmlinux.bin.  Do not leave this option active in a production kernel
+                 if you don't intend to always append a DTB.
+
+       config MIPS_ZBOOT_APPENDED_DTB
+               bool "vmlinuz.bin"
+               depends on SYS_SUPPORTS_ZBOOT
+               help
+                 With this option, the boot code will look for a device tree binary
+                 DTB) appended to raw vmlinuz.bin (with decompressor).
+                 (e.g. cat vmlinuz.bin <filename>.dtb > vmlinuz_w_dtb).
+
+                 This is meant as a backward compatibility convenience for those
+                 systems with a bootloader that can't be upgraded to accommodate
+                 the documented boot protocol using a device tree.
+
+                 Beware that there is very little in terms of protection against
+                 this option being confused by leftover garbage in memory that might
+                 look like a DTB header after a reboot if no actual DTB is appended
+                 to vmlinuz.bin.  Do not leave this option active in a production kernel
+                 if you don't intend to always append a DTB.
+endchoice
+
 endmenu
 
 config LOCKDEP_SUPPORT
index 6a98d2c..6e46abe 100644 (file)
@@ -752,12 +752,12 @@ static int __init alchemy_clk_init_fgens(int ctype)
        switch (ctype) {
        case ALCHEMY_CPU_AU1000...ALCHEMY_CPU_AU1200:
                id.ops = &alchemy_clkops_fgenv1;
-               id.parent_names = (const char **)alchemy_clk_fgv1_parents;
+               id.parent_names = alchemy_clk_fgv1_parents;
                id.num_parents = 2;
                break;
        case ALCHEMY_CPU_AU1300:
                id.ops = &alchemy_clkops_fgenv2;
-               id.parent_names = (const char **)alchemy_clk_fgv2_parents;
+               id.parent_names = alchemy_clk_fgv2_parents;
                id.num_parents = 3;
                break;
        default:
@@ -961,7 +961,7 @@ static int __init alchemy_clk_setup_imux(int ctype)
        struct clk *c;
 
        id.ops = &alchemy_clkops_csrc;
-       id.parent_names = (const char **)alchemy_clk_csrc_parents;
+       id.parent_names = alchemy_clk_csrc_parents;
        id.num_parents = 7;
        id.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE;
 
index 2befa7d..8742e1c 100644 (file)
@@ -76,7 +76,7 @@ static void ar2315_misc_irq_handler(unsigned irq, struct irq_desc *desc)
        unsigned nr, misc_irq = 0;
 
        if (pending) {
-               struct irq_domain *domain = irq_get_handler_data(irq);
+               struct irq_domain *domain = irq_desc_get_handler_data(desc);
 
                nr = __ffs(pending);
                misc_irq = irq_find_mapping(domain, nr);
index b6887f7..094b938 100644 (file)
@@ -80,7 +80,7 @@ static void ar5312_misc_irq_handler(unsigned irq, struct irq_desc *desc)
        unsigned nr, misc_irq = 0;
 
        if (pending) {
-               struct irq_domain *domain = irq_get_handler_data(irq);
+               struct irq_domain *domain = irq_desc_get_handler_data(desc);
 
                nr = __ffs(pending);
                misc_irq = irq_find_mapping(domain, nr);
index b8bb782..9ab48ff 100644 (file)
@@ -216,7 +216,7 @@ void __init plat_time_init(void)
                ar2315_plat_time_init();
 }
 
-unsigned int __cpuinit get_c0_compare_int(void)
+unsigned int get_c0_compare_int(void)
 {
        return CP0_LEGACY_COMPARE_IRQ;
 }
index dfc6020..13c04cf 100644 (file)
@@ -71,6 +71,18 @@ config ATH79_MACH_UBNT_XM
          Say 'Y' here if you want your kernel to support the
          Ubiquiti Networks XM (rev 1.0) board.
 
+choice
+       prompt "Build a DTB in the kernel"
+       optional
+       help
+         Select a devicetree that should be built into the kernel.
+
+       config DTB_TL_WR1043ND_V1
+               bool "TL-WR1043ND Version 1"
+               select BUILTIN_DTB
+               select SOC_AR913X
+endchoice
+
 endmenu
 
 config SOC_AR71XX
index 26479f4..eb5117c 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
+#include <linux/clk-provider.h>
 
 #include <asm/div64.h>
 
 #define AR724X_BASE_FREQ       5000000
 #define AR913X_BASE_FREQ       5000000
 
-struct clk {
-       unsigned long rate;
+static struct clk *clks[3];
+static struct clk_onecell_data clk_data = {
+       .clks = clks,
+       .clk_num = ARRAY_SIZE(clks),
 };
 
-static void __init ath79_add_sys_clkdev(const char *id, unsigned long rate)
+static struct clk *__init ath79_add_sys_clkdev(
+       const char *id, unsigned long rate)
 {
        struct clk *clk;
        int err;
 
-       clk = kzalloc(sizeof(*clk), GFP_KERNEL);
+       clk = clk_register_fixed_rate(NULL, id, NULL, CLK_IS_ROOT, rate);
        if (!clk)
                panic("failed to allocate %s clock structure", id);
 
-       clk->rate = rate;
-
        err = clk_register_clkdev(clk, id, NULL);
        if (err)
                panic("unable to register %s clock device", id);
+
+       return clk;
 }
 
 static void __init ar71xx_clocks_init(void)
@@ -62,7 +66,7 @@ static void __init ar71xx_clocks_init(void)
 
        pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG);
 
-       div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1;
+       div = ((pll >> AR71XX_PLL_FB_SHIFT) & AR71XX_PLL_FB_MASK) + 1;
        freq = div * ref_rate;
 
        div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1;
@@ -75,9 +79,9 @@ static void __init ar71xx_clocks_init(void)
        ahb_rate = cpu_rate / div;
 
        ath79_add_sys_clkdev("ref", ref_rate);
-       ath79_add_sys_clkdev("cpu", cpu_rate);
-       ath79_add_sys_clkdev("ddr", ddr_rate);
-       ath79_add_sys_clkdev("ahb", ahb_rate);
+       clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate);
+       clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate);
+       clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate);
 
        clk_add_alias("wdt", NULL, "ahb", NULL);
        clk_add_alias("uart", NULL, "ahb", NULL);
@@ -96,7 +100,7 @@ static void __init ar724x_clocks_init(void)
        ref_rate = AR724X_BASE_FREQ;
        pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG);
 
-       div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK);
+       div = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK);
        freq = div * ref_rate;
 
        div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK);
@@ -111,9 +115,9 @@ static void __init ar724x_clocks_init(void)
        ahb_rate = cpu_rate / div;
 
        ath79_add_sys_clkdev("ref", ref_rate);
-       ath79_add_sys_clkdev("cpu", cpu_rate);
-       ath79_add_sys_clkdev("ddr", ddr_rate);
-       ath79_add_sys_clkdev("ahb", ahb_rate);
+       clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate);
+       clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate);
+       clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate);
 
        clk_add_alias("wdt", NULL, "ahb", NULL);
        clk_add_alias("uart", NULL, "ahb", NULL);
@@ -132,7 +136,7 @@ static void __init ar913x_clocks_init(void)
        ref_rate = AR913X_BASE_FREQ;
        pll = ath79_pll_rr(AR913X_PLL_REG_CPU_CONFIG);
 
-       div = ((pll >> AR913X_PLL_DIV_SHIFT) & AR913X_PLL_DIV_MASK);
+       div = ((pll >> AR913X_PLL_FB_SHIFT) & AR913X_PLL_FB_MASK);
        freq = div * ref_rate;
 
        cpu_rate = freq;
@@ -144,9 +148,9 @@ static void __init ar913x_clocks_init(void)
        ahb_rate = cpu_rate / div;
 
        ath79_add_sys_clkdev("ref", ref_rate);
-       ath79_add_sys_clkdev("cpu", cpu_rate);
-       ath79_add_sys_clkdev("ddr", ddr_rate);
-       ath79_add_sys_clkdev("ahb", ahb_rate);
+       clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate);
+       clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate);
+       clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate);
 
        clk_add_alias("wdt", NULL, "ahb", NULL);
        clk_add_alias("uart", NULL, "ahb", NULL);
@@ -206,9 +210,9 @@ static void __init ar933x_clocks_init(void)
        }
 
        ath79_add_sys_clkdev("ref", ref_rate);
-       ath79_add_sys_clkdev("cpu", cpu_rate);
-       ath79_add_sys_clkdev("ddr", ddr_rate);
-       ath79_add_sys_clkdev("ahb", ahb_rate);
+       clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate);
+       clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate);
+       clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate);
 
        clk_add_alias("wdt", NULL, "ahb", NULL);
        clk_add_alias("uart", NULL, "ref", NULL);
@@ -340,9 +344,9 @@ static void __init ar934x_clocks_init(void)
                ahb_rate = cpu_pll / (postdiv + 1);
 
        ath79_add_sys_clkdev("ref", ref_rate);
-       ath79_add_sys_clkdev("cpu", cpu_rate);
-       ath79_add_sys_clkdev("ddr", ddr_rate);
-       ath79_add_sys_clkdev("ahb", ahb_rate);
+       clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate);
+       clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate);
+       clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate);
 
        clk_add_alias("wdt", NULL, "ref", NULL);
        clk_add_alias("uart", NULL, "ref", NULL);
@@ -427,9 +431,9 @@ static void __init qca955x_clocks_init(void)
                ahb_rate = cpu_pll / (postdiv + 1);
 
        ath79_add_sys_clkdev("ref", ref_rate);
-       ath79_add_sys_clkdev("cpu", cpu_rate);
-       ath79_add_sys_clkdev("ddr", ddr_rate);
-       ath79_add_sys_clkdev("ahb", ahb_rate);
+       clks[0] = ath79_add_sys_clkdev("cpu", cpu_rate);
+       clks[1] = ath79_add_sys_clkdev("ddr", ddr_rate);
+       clks[2] = ath79_add_sys_clkdev("ahb", ahb_rate);
 
        clk_add_alias("wdt", NULL, "ref", NULL);
        clk_add_alias("uart", NULL, "ref", NULL);
@@ -451,6 +455,8 @@ void __init ath79_clocks_init(void)
                qca955x_clocks_init();
        else
                BUG();
+
+       of_clk_init(NULL);
 }
 
 unsigned long __init
@@ -469,22 +475,16 @@ ath79_get_sys_clk_rate(const char *id)
        return rate;
 }
 
-/*
- * Linux clock API
- */
-int clk_enable(struct clk *clk)
+#ifdef CONFIG_OF
+static void __init ath79_clocks_init_dt(struct device_node *np)
 {
-       return 0;
+       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
 }
-EXPORT_SYMBOL(clk_enable);
 
-void clk_disable(struct clk *clk)
-{
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-       return clk->rate;
-}
-EXPORT_SYMBOL(clk_get_rate);
+CLK_OF_DECLARE(ar7100, "qca,ar7100-pll", ath79_clocks_init_dt);
+CLK_OF_DECLARE(ar7240, "qca,ar7240-pll", ath79_clocks_init_dt);
+CLK_OF_DECLARE(ar9130, "qca,ar9130-pll", ath79_clocks_init_dt);
+CLK_OF_DECLARE(ar9330, "qca,ar9330-pll", ath79_clocks_init_dt);
+CLK_OF_DECLARE(ar9340, "qca,ar9340-pll", ath79_clocks_init_dt);
+CLK_OF_DECLARE(ar9550, "qca,qca9550-pll", ath79_clocks_init_dt);
+#endif
index eb3966c..3cedd1f 100644 (file)
@@ -38,11 +38,27 @@ unsigned int ath79_soc_rev;
 void __iomem *ath79_pll_base;
 void __iomem *ath79_reset_base;
 EXPORT_SYMBOL_GPL(ath79_reset_base);
-void __iomem *ath79_ddr_base;
+static void __iomem *ath79_ddr_base;
+static void __iomem *ath79_ddr_wb_flush_base;
+static void __iomem *ath79_ddr_pci_win_base;
+
+void ath79_ddr_ctrl_init(void)
+{
+       ath79_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE,
+                                        AR71XX_DDR_CTRL_SIZE);
+       if (soc_is_ar71xx() || soc_is_ar934x()) {
+               ath79_ddr_wb_flush_base = ath79_ddr_base + 0x9c;
+               ath79_ddr_pci_win_base = ath79_ddr_base + 0x7c;
+       } else {
+               ath79_ddr_wb_flush_base = ath79_ddr_base + 0x7c;
+               ath79_ddr_pci_win_base = 0;
+       }
+}
+EXPORT_SYMBOL_GPL(ath79_ddr_ctrl_init);
 
 void ath79_ddr_wb_flush(u32 reg)
 {
-       void __iomem *flush_reg = ath79_ddr_base + reg;
+       void __iomem *flush_reg = ath79_ddr_wb_flush_base + reg;
 
        /* Flush the DDR write buffer. */
        __raw_writel(0x1, flush_reg);
@@ -56,6 +72,21 @@ void ath79_ddr_wb_flush(u32 reg)
 }
 EXPORT_SYMBOL_GPL(ath79_ddr_wb_flush);
 
+void ath79_ddr_set_pci_windows(void)
+{
+       BUG_ON(!ath79_ddr_pci_win_base);
+
+       __raw_writel(AR71XX_PCI_WIN0_OFFS, ath79_ddr_pci_win_base + 0);
+       __raw_writel(AR71XX_PCI_WIN1_OFFS, ath79_ddr_pci_win_base + 1);
+       __raw_writel(AR71XX_PCI_WIN2_OFFS, ath79_ddr_pci_win_base + 2);
+       __raw_writel(AR71XX_PCI_WIN3_OFFS, ath79_ddr_pci_win_base + 3);
+       __raw_writel(AR71XX_PCI_WIN4_OFFS, ath79_ddr_pci_win_base + 4);
+       __raw_writel(AR71XX_PCI_WIN5_OFFS, ath79_ddr_pci_win_base + 5);
+       __raw_writel(AR71XX_PCI_WIN6_OFFS, ath79_ddr_pci_win_base + 6);
+       __raw_writel(AR71XX_PCI_WIN7_OFFS, ath79_ddr_pci_win_base + 7);
+}
+EXPORT_SYMBOL_GPL(ath79_ddr_set_pci_windows);
+
 void ath79_device_reset_set(u32 mask)
 {
        unsigned long flags;
index c39de61..e5ea712 100644 (file)
@@ -22,6 +22,7 @@
 void ath79_clocks_init(void);
 unsigned long ath79_get_sys_clk_rate(const char *id);
 
+void ath79_ddr_ctrl_init(void);
 void ath79_ddr_wb_flush(unsigned int reg);
 
 void ath79_gpio_function_enable(u32 mask);
index 516225d..9d0172a 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/platform_data/gpio-ath79.h>
 #include <linux/serial_8250.h>
 #include <linux/clk.h>
 #include <linux/err.h>
@@ -106,3 +107,53 @@ void __init ath79_register_wdt(void)
 
        platform_device_register_simple("ath79-wdt", -1, &res, 1);
 }
+
+static struct ath79_gpio_platform_data ath79_gpio_pdata;
+
+static struct resource ath79_gpio_resources[] = {
+       {
+               .flags = IORESOURCE_MEM,
+               .start = AR71XX_GPIO_BASE,
+               .end = AR71XX_GPIO_BASE + AR71XX_GPIO_SIZE - 1,
+       },
+       {
+               .start  = ATH79_MISC_IRQ(2),
+               .end    = ATH79_MISC_IRQ(2),
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device ath79_gpio_device = {
+       .name           = "ath79-gpio",
+       .id             = -1,
+       .resource       = ath79_gpio_resources,
+       .num_resources  = ARRAY_SIZE(ath79_gpio_resources),
+       .dev = {
+               .platform_data  = &ath79_gpio_pdata
+       },
+};
+
+void __init ath79_gpio_init(void)
+{
+       if (soc_is_ar71xx()) {
+               ath79_gpio_pdata.ngpios = AR71XX_GPIO_COUNT;
+       } else if (soc_is_ar7240()) {
+               ath79_gpio_pdata.ngpios = AR7240_GPIO_COUNT;
+       } else if (soc_is_ar7241() || soc_is_ar7242()) {
+               ath79_gpio_pdata.ngpios = AR7241_GPIO_COUNT;
+       } else if (soc_is_ar913x()) {
+               ath79_gpio_pdata.ngpios = AR913X_GPIO_COUNT;
+       } else if (soc_is_ar933x()) {
+               ath79_gpio_pdata.ngpios = AR933X_GPIO_COUNT;
+       } else if (soc_is_ar934x()) {
+               ath79_gpio_pdata.ngpios = AR934X_GPIO_COUNT;
+               ath79_gpio_pdata.oe_inverted = 1;
+       } else if (soc_is_qca955x()) {
+               ath79_gpio_pdata.ngpios = QCA955X_GPIO_COUNT;
+               ath79_gpio_pdata.oe_inverted = 1;
+       } else {
+               BUG();
+       }
+
+       platform_device_register(&ath79_gpio_device);
+}
index 8d025b0..f59ccb2 100644 (file)
 #include <linux/io.h>
 #include <linux/ioport.h>
 #include <linux/gpio.h>
+#include <linux/platform_data/gpio-ath79.h>
+#include <linux/of_device.h>
 
 #include <asm/mach-ath79/ar71xx_regs.h>
 #include <asm/mach-ath79/ath79.h>
 #include "common.h"
 
 static void __iomem *ath79_gpio_base;
-static unsigned long ath79_gpio_count;
+static u32 ath79_gpio_count;
 static DEFINE_SPINLOCK(ath79_gpio_lock);
 
 static void __ath79_gpio_set_value(unsigned gpio, int value)
@@ -178,39 +180,72 @@ void ath79_gpio_function_disable(u32 mask)
        ath79_gpio_function_setup(0, mask);
 }
 
-void __init ath79_gpio_init(void)
+static const struct of_device_id ath79_gpio_of_match[] = {
+       { .compatible = "qca,ar7100-gpio" },
+       { .compatible = "qca,ar9340-gpio" },
+       {},
+};
+
+static int ath79_gpio_probe(struct platform_device *pdev)
 {
+       struct ath79_gpio_platform_data *pdata = pdev->dev.platform_data;
+       struct device_node *np = pdev->dev.of_node;
+       struct resource *res;
+       bool oe_inverted;
        int err;
 
-       if (soc_is_ar71xx())
-               ath79_gpio_count = AR71XX_GPIO_COUNT;
-       else if (soc_is_ar7240())
-               ath79_gpio_count = AR7240_GPIO_COUNT;
-       else if (soc_is_ar7241() || soc_is_ar7242())
-               ath79_gpio_count = AR7241_GPIO_COUNT;
-       else if (soc_is_ar913x())
-               ath79_gpio_count = AR913X_GPIO_COUNT;
-       else if (soc_is_ar933x())
-               ath79_gpio_count = AR933X_GPIO_COUNT;
-       else if (soc_is_ar934x())
-               ath79_gpio_count = AR934X_GPIO_COUNT;
-       else if (soc_is_qca955x())
-               ath79_gpio_count = QCA955X_GPIO_COUNT;
-       else
-               BUG();
+       if (np) {
+               err = of_property_read_u32(np, "ngpios", &ath79_gpio_count);
+               if (err) {
+                       dev_err(&pdev->dev, "ngpios property is not valid\n");
+                       return err;
+               }
+               if (ath79_gpio_count >= 32) {
+                       dev_err(&pdev->dev, "ngpios must be less than 32\n");
+                       return -EINVAL;
+               }
+               oe_inverted = of_device_is_compatible(np, "qca,ar9340-gpio");
+       } else if (pdata) {
+               ath79_gpio_count = pdata->ngpios;
+               oe_inverted = pdata->oe_inverted;
+       } else {
+               dev_err(&pdev->dev, "No DT node or platform data found\n");
+               return -EINVAL;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       ath79_gpio_base = devm_ioremap_nocache(
+               &pdev->dev, res->start, resource_size(res));
+       if (!ath79_gpio_base)
+               return -ENOMEM;
 
-       ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE);
+       ath79_gpio_chip.dev = &pdev->dev;
        ath79_gpio_chip.ngpio = ath79_gpio_count;
-       if (soc_is_ar934x() || soc_is_qca955x()) {
+       if (oe_inverted) {
                ath79_gpio_chip.direction_input = ar934x_gpio_direction_input;
                ath79_gpio_chip.direction_output = ar934x_gpio_direction_output;
        }
 
        err = gpiochip_add(&ath79_gpio_chip);
-       if (err)
-               panic("cannot add AR71xx GPIO chip, error=%d", err);
+       if (err) {
+               dev_err(&pdev->dev,
+                       "cannot add AR71xx GPIO chip, error=%d", err);
+               return err;
+       }
+
+       return 0;
 }
 
+static struct platform_driver ath79_gpio_driver = {
+       .driver = {
+               .name = "ath79-gpio",
+               .of_match_table = ath79_gpio_of_match,
+       },
+       .probe = ath79_gpio_probe,
+};
+
+module_platform_driver(ath79_gpio_driver);
+
 int gpio_get_value(unsigned gpio)
 {
        if (gpio < ath79_gpio_count)
index 6adae36..afb0096 100644 (file)
@@ -15,7 +15,9 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
-#include <linux/irq.h>
+#include <linux/irqchip.h>
+#include <linux/of_irq.h>
+#include "../../../drivers/irqchip/irqchip.h"
 
 #include <asm/irq_cpu.h>
 #include <asm/mipsregs.h>
@@ -23,9 +25,7 @@
 #include <asm/mach-ath79/ath79.h>
 #include <asm/mach-ath79/ar71xx_regs.h>
 #include "common.h"
-
-static void (*ath79_ip2_handler)(void);
-static void (*ath79_ip3_handler)(void);
+#include "machtypes.h"
 
 static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
 {
@@ -129,10 +129,10 @@ static void ar934x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc)
        status = ath79_reset_rr(AR934X_RESET_REG_PCIE_WMAC_INT_STATUS);
 
        if (status & AR934X_PCIE_WMAC_INT_PCIE_ALL) {
-               ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_PCIE);
+               ath79_ddr_wb_flush(3);
                generic_handle_irq(ATH79_IP2_IRQ(0));
        } else if (status & AR934X_PCIE_WMAC_INT_WMAC_ALL) {
-               ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_WMAC);
+               ath79_ddr_wb_flush(4);
                generic_handle_irq(ATH79_IP2_IRQ(1));
        } else {
                spurious_interrupt();
@@ -235,128 +235,132 @@ static void qca955x_irq_init(void)
        irq_set_chained_handler(ATH79_CPU_IRQ(3), qca955x_ip3_irq_dispatch);
 }
 
-asmlinkage void plat_irq_dispatch(void)
-{
-       unsigned long pending;
-
-       pending = read_c0_status() & read_c0_cause() & ST0_IM;
-
-       if (pending & STATUSF_IP7)
-               do_IRQ(ATH79_CPU_IRQ(7));
-
-       else if (pending & STATUSF_IP2)
-               ath79_ip2_handler();
-
-       else if (pending & STATUSF_IP4)
-               do_IRQ(ATH79_CPU_IRQ(4));
-
-       else if (pending & STATUSF_IP5)
-               do_IRQ(ATH79_CPU_IRQ(5));
-
-       else if (pending & STATUSF_IP3)
-               ath79_ip3_handler();
-
-       else if (pending & STATUSF_IP6)
-               do_IRQ(ATH79_CPU_IRQ(6));
-
-       else
-               spurious_interrupt();
-}
-
 /*
  * The IP2/IP3 lines are tied to a PCI/WMAC/USB device. Drivers for
  * these devices typically allocate coherent DMA memory, however the
  * DMA controller may still have some unsynchronized data in the FIFO.
  * Issue a flush in the handlers to ensure that the driver sees
  * the update.
+ *
+ * This array map the interrupt lines to the DDR write buffer channels.
  */
 
-static void ath79_default_ip2_handler(void)
-{
-       do_IRQ(ATH79_CPU_IRQ(2));
-}
+static unsigned irq_wb_chan[8] = {
+       -1, -1, -1, -1, -1, -1, -1, -1,
+};
 
-static void ath79_default_ip3_handler(void)
+asmlinkage void plat_irq_dispatch(void)
 {
-       do_IRQ(ATH79_CPU_IRQ(3));
-}
+       unsigned long pending;
+       int irq;
 
-static void ar71xx_ip2_handler(void)
-{
-       ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_PCI);
-       do_IRQ(ATH79_CPU_IRQ(2));
-}
+       pending = read_c0_status() & read_c0_cause() & ST0_IM;
 
-static void ar724x_ip2_handler(void)
-{
-       ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_PCIE);
-       do_IRQ(ATH79_CPU_IRQ(2));
-}
+       if (!pending) {
+               spurious_interrupt();
+               return;
+       }
 
-static void ar913x_ip2_handler(void)
-{
-       ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_WMAC);
-       do_IRQ(ATH79_CPU_IRQ(2));
+       pending >>= CAUSEB_IP;
+       while (pending) {
+               irq = fls(pending) - 1;
+               if (irq < ARRAY_SIZE(irq_wb_chan) && irq_wb_chan[irq] != -1)
+                       ath79_ddr_wb_flush(irq_wb_chan[irq]);
+               do_IRQ(MIPS_CPU_IRQ_BASE + irq);
+               pending &= ~BIT(irq);
+       }
 }
 
-static void ar933x_ip2_handler(void)
+#ifdef CONFIG_IRQCHIP
+static int misc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
 {
-       ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_WMAC);
-       do_IRQ(ATH79_CPU_IRQ(2));
+       irq_set_chip_and_handler(irq, &ath79_misc_irq_chip, handle_level_irq);
+       return 0;
 }
 
-static void ar71xx_ip3_handler(void)
-{
-       ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_USB);
-       do_IRQ(ATH79_CPU_IRQ(3));
-}
+static const struct irq_domain_ops misc_irq_domain_ops = {
+       .xlate = irq_domain_xlate_onecell,
+       .map = misc_map,
+};
 
-static void ar724x_ip3_handler(void)
+static int __init ath79_misc_intc_of_init(
+       struct device_node *node, struct device_node *parent)
 {
-       ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_USB);
-       do_IRQ(ATH79_CPU_IRQ(3));
-}
+       void __iomem *base = ath79_reset_base;
+       struct irq_domain *domain;
+       int irq;
 
-static void ar913x_ip3_handler(void)
-{
-       ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_USB);
-       do_IRQ(ATH79_CPU_IRQ(3));
-}
+       irq = irq_of_parse_and_map(node, 0);
+       if (!irq)
+               panic("Failed to get MISC IRQ");
 
-static void ar933x_ip3_handler(void)
-{
-       ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_USB);
-       do_IRQ(ATH79_CPU_IRQ(3));
+       domain = irq_domain_add_legacy(node, ATH79_MISC_IRQ_COUNT,
+                       ATH79_MISC_IRQ_BASE, 0, &misc_irq_domain_ops, NULL);
+       if (!domain)
+               panic("Failed to add MISC irqdomain");
+
+       /* Disable and clear all interrupts */
+       __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+       __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
+
+
+       irq_set_chained_handler(irq, ath79_misc_irq_handler);
+
+       return 0;
 }
+IRQCHIP_DECLARE(ath79_misc_intc, "qca,ar7100-misc-intc",
+               ath79_misc_intc_of_init);
 
-static void ar934x_ip3_handler(void)
+static int __init ar79_cpu_intc_of_init(
+       struct device_node *node, struct device_node *parent)
 {
-       ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_USB);
-       do_IRQ(ATH79_CPU_IRQ(3));
+       int err, i, count;
+
+       /* Fill the irq_wb_chan table */
+       count = of_count_phandle_with_args(
+               node, "qca,ddr-wb-channels", "#qca,ddr-wb-channel-cells");
+
+       for (i = 0; i < count; i++) {
+               struct of_phandle_args args;
+               u32 irq = i;
+
+               of_property_read_u32_index(
+                       node, "qca,ddr-wb-channel-interrupts", i, &irq);
+               if (irq >= ARRAY_SIZE(irq_wb_chan))
+                       continue;
+
+               err = of_parse_phandle_with_args(
+                       node, "qca,ddr-wb-channels",
+                       "#qca,ddr-wb-channel-cells",
+                       i, &args);
+               if (err)
+                       return err;
+
+               irq_wb_chan[irq] = args.args[0];
+               pr_info("IRQ: Set flush channel of IRQ%d to %d\n",
+                       irq, args.args[0]);
+       }
+
+       return mips_cpu_irq_of_init(node, parent);
 }
+IRQCHIP_DECLARE(ar79_cpu_intc, "qca,ar7100-cpu-intc",
+               ar79_cpu_intc_of_init);
+
+#endif
 
 void __init arch_init_irq(void)
 {
-       if (soc_is_ar71xx()) {
-               ath79_ip2_handler = ar71xx_ip2_handler;
-               ath79_ip3_handler = ar71xx_ip3_handler;
-       } else if (soc_is_ar724x()) {
-               ath79_ip2_handler = ar724x_ip2_handler;
-               ath79_ip3_handler = ar724x_ip3_handler;
-       } else if (soc_is_ar913x()) {
-               ath79_ip2_handler = ar913x_ip2_handler;
-               ath79_ip3_handler = ar913x_ip3_handler;
-       } else if (soc_is_ar933x()) {
-               ath79_ip2_handler = ar933x_ip2_handler;
-               ath79_ip3_handler = ar933x_ip3_handler;
+       if (mips_machtype == ATH79_MACH_GENERIC_OF) {
+               irqchip_init();
+               return;
+       }
+
+       if (soc_is_ar71xx() || soc_is_ar724x() ||
+           soc_is_ar913x() || soc_is_ar933x()) {
+               irq_wb_chan[2] = 3;
+               irq_wb_chan[3] = 2;
        } else if (soc_is_ar934x()) {
-               ath79_ip2_handler = ath79_default_ip2_handler;
-               ath79_ip3_handler = ar934x_ip3_handler;
-       } else if (soc_is_qca955x()) {
-               ath79_ip2_handler = ath79_default_ip2_handler;
-               ath79_ip3_handler = ath79_default_ip3_handler;
-       } else {
-               BUG();
+               irq_wb_chan[3] = 2;
        }
 
        mips_cpu_irq_init();
index 2625405..a13db3d 100644 (file)
@@ -15,6 +15,7 @@
 #include <asm/mips_machine.h>
 
 enum ath79_mach_type {
+       ATH79_MACH_GENERIC_OF = -1,     /* Device tree board */
        ATH79_MACH_GENERIC = 0,
        ATH79_MACH_AP121,               /* Atheros AP121 reference board */
        ATH79_MACH_AP136_010,           /* Atheros AP136-010 reference board */
index 7fc8397..01a644f 100644 (file)
 #include <linux/bootmem.h>
 #include <linux/err.h>
 #include <linux/clk.h>
+#include <linux/of_platform.h>
+#include <linux/of_fdt.h>
 
 #include <asm/bootinfo.h>
 #include <asm/idle.h>
 #include <asm/time.h>          /* for mips_hpt_frequency */
 #include <asm/reboot.h>                /* for _machine_{restart,halt} */
 #include <asm/mips_machine.h>
+#include <asm/prom.h>
+#include <asm/fw/fw.h>
 
 #include <asm/mach-ath79/ath79.h>
 #include <asm/mach-ath79/ar71xx_regs.h>
@@ -194,17 +198,28 @@ unsigned int get_c0_compare_int(void)
 
 void __init plat_mem_setup(void)
 {
+       unsigned long fdt_start;
+
        set_io_port_base(KSEG1);
 
+       /* Get the position of the FDT passed by the bootloader */
+       fdt_start = fw_getenvl("fdt_start");
+       if (fdt_start)
+               __dt_setup_arch((void *)KSEG0ADDR(fdt_start));
+#ifdef CONFIG_BUILTIN_DTB
+       else
+               __dt_setup_arch(__dtb_start);
+#endif
+
        ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE,
                                           AR71XX_RESET_SIZE);
        ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
                                         AR71XX_PLL_SIZE);
-       ath79_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE,
-                                        AR71XX_DDR_CTRL_SIZE);
+       ath79_ddr_ctrl_init();
 
        ath79_detect_sys_type();
-       detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX);
+       if (mips_machtype != ATH79_MACH_GENERIC_OF)
+               detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX);
 
        _machine_restart = ath79_restart;
        _machine_halt = ath79_halt;
@@ -236,6 +251,10 @@ void __init plat_time_init(void)
 
 static int __init ath79_setup(void)
 {
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+       if  (mips_machtype == ATH79_MACH_GENERIC_OF)
+               return 0;
+
        ath79_gpio_init();
        ath79_register_uart();
        ath79_register_wdt();
@@ -247,6 +266,11 @@ static int __init ath79_setup(void)
 
 arch_initcall(ath79_setup);
 
+void __init device_tree_init(void)
+{
+       unflatten_and_copy_device_tree();
+}
+
 static void __init ath79_generic_init(void)
 {
        /* Nothing to do */
index fc21d36..51ed599 100644 (file)
@@ -25,7 +25,6 @@ config BCM47XX_BCMA
        select BCMA
        select BCMA_HOST_SOC
        select BCMA_DRIVER_MIPS
-       select BCMA_HOST_PCI if PCI
        select BCMA_DRIVER_PCI_HOSTMODE if PCI
        select BCMA_DRIVER_GPIO
        default y
index d58c51b..66bea4e 100644 (file)
@@ -3,5 +3,5 @@
 # under Linux.
 #
 
-obj-y                          += irq.o nvram.o prom.o serial.o setup.o time.o sprom.o
+obj-y                          += irq.o prom.o serial.o setup.o time.o sprom.o
 obj-y                          += board.o buttons.o leds.o workarounds.o
index bd56415..a88975a 100644 (file)
@@ -149,6 +149,7 @@ struct bcm47xx_board_type_list2 bcm47xx_board_list_boot_hw[] __initconst = {
 /* board_id */
 static const
 struct bcm47xx_board_type_list1 bcm47xx_board_list_board_id[] __initconst = {
+       {{BCM47XX_BOARD_LUXUL_XWR_1750_V1, "Luxul XWR-1750 V1"}, "luxul_xwr1750_v1"},
        {{BCM47XX_BOARD_NETGEAR_WGR614V8, "Netgear WGR614 V8"}, "U12H072T00_NETGEAR"},
        {{BCM47XX_BOARD_NETGEAR_WGR614V9, "Netgear WGR614 V9"}, "U12H094T00_NETGEAR"},
        {{BCM47XX_BOARD_NETGEAR_WGR614_V10, "Netgear WGR614 V10"}, "U12H139T01_NETGEAR"},
index 276276a..08a4abf 100644 (file)
@@ -299,6 +299,13 @@ bcm47xx_buttons_linksys_wrtsl54gs[] __initconst = {
        BCM47XX_GPIO_KEY(6, KEY_RESTART),
 };
 
+/* Luxul */
+
+static const struct gpio_keys_button
+bcm47xx_buttons_luxul_xwr_1750_v1[] = {
+       BCM47XX_GPIO_KEY(14, BTN_TASK),
+};
+
 /* Microsoft */
 
 static const struct gpio_keys_button
@@ -555,6 +562,10 @@ int __init bcm47xx_buttons_register(void)
                err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrtsl54gs);
                break;
 
+       case BCM47XX_BOARD_LUXUL_XWR_1750_V1:
+               err = bcm47xx_copy_bdata(bcm47xx_buttons_luxul_xwr_1750_v1);
+               break;
+
        case BCM47XX_BOARD_MICROSOFT_MN700:
                err = bcm47xx_copy_bdata(bcm47xx_buttons_microsoft_nm700);
                break;
index 0e4ade3..d20ae63 100644 (file)
@@ -370,6 +370,16 @@ bcm47xx_leds_linksys_wrtsl54gs[] __initconst = {
        BCM47XX_GPIO_LED(7, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
 };
 
+/* Luxul */
+
+static const struct gpio_led
+bcm47xx_leds_luxul_xwr_1750_v1[] __initconst = {
+       BCM47XX_GPIO_LED(5, "green", "5ghz", 0, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED(12, "green", "usb", 0, LEDS_GPIO_DEFSTATE_OFF),
+       BCM47XX_GPIO_LED_TRIGGER(13, "green", "status", 0, "timer"),
+       BCM47XX_GPIO_LED(15, "green", "wps", 0, LEDS_GPIO_DEFSTATE_OFF),
+};
+
 /* Microsoft */
 
 static const struct gpio_led
@@ -623,6 +633,10 @@ void __init bcm47xx_leds_register(void)
                bcm47xx_set_pdata(bcm47xx_leds_linksys_wrtsl54gs);
                break;
 
+       case BCM47XX_BOARD_LUXUL_XWR_1750_V1:
+               bcm47xx_set_pdata(bcm47xx_leds_luxul_xwr_1750_v1);
+               break;
+
        case BCM47XX_BOARD_MICROSOFT_MN700:
                bcm47xx_set_pdata(bcm47xx_leds_microsoft_nm700);
                break;
index ab698ba..135a540 100644 (file)
@@ -126,7 +126,7 @@ void __init prom_free_prom_memory(void)
 /* Stripped version of tlb_init, with the call to build_tlb_refill_handler
  * dropped. Calling it at this stage causes a hang.
  */
-void __cpuinit early_tlb_init(void)
+void early_tlb_init(void)
 {
        write_c0_pagemask(PM_DEFAULT_MASK);
        write_c0_wired(0);
index 82ff9fd..98c075f 100644 (file)
@@ -206,9 +206,6 @@ void __init bcm47xx_bus_setup(void)
                err = bcma_host_soc_init(&bcm47xx_bus.bcma);
                if (err)
                        panic("Failed to initialize BCMA bus (err %d)", err);
-
-               bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo,
-                                           NULL);
        }
 #endif
 
index 68ebf23..2d5c7a7 100644 (file)
@@ -200,7 +200,13 @@ static void bcm47xx_sprom_fill_auto(struct ssb_sprom *sprom,
        const char *pre = prefix;
        bool fb = fallback;
 
+       /* Broadcom extracts it for rev 8+ but it was found on 2 and 4 too */
+       ENTRY(0xfffffffe, u16, pre, "devid", dev_id, 0, fallback);
+
        ENTRY(0xfffffffe, u16, pre, "boardrev", board_rev, 0, true);
+       ENTRY(0xfffffffe, u32, pre, "boardflags", boardflags, 0, fb);
+       ENTRY(0xfffffff0, u32, pre, "boardflags2", boardflags2, 0, fb);
+       ENTRY(0xfffff800, u32, pre, "boardflags3", boardflags3, 0, fb);
        ENTRY(0x00000002, u16, pre, "boardflags", boardflags_lo, 0, fb);
        ENTRY(0xfffffffc, u16, pre, "boardtype", board_type, 0, true);
        ENTRY(0xfffffffe, u16, pre, "boardnum", board_num, 0, fb);
@@ -409,27 +415,6 @@ static void bcm47xx_sprom_fill_auto(struct ssb_sprom *sprom,
 }
 #undef ENTRY /* It's specififc, uses local variable, don't use it (again). */
 
-static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom,
-                                       const char *prefix, bool fallback)
-{
-       nvram_read_u16(prefix, NULL, "devid", &sprom->dev_id, 0, fallback);
-       nvram_read_alpha2(prefix, "ccode", sprom->alpha2, fallback);
-}
-
-static void bcm47xx_fill_sprom_r3(struct ssb_sprom *sprom, const char *prefix,
-                                 bool fallback)
-{
-       nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time,
-                        &sprom->leddc_off_time, fallback);
-}
-
-static void bcm47xx_fill_sprom_r4589(struct ssb_sprom *sprom,
-                                    const char *prefix, bool fallback)
-{
-       nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time,
-                        &sprom->leddc_off_time, fallback);
-}
-
 static void bcm47xx_fill_sprom_path_r4589(struct ssb_sprom *sprom,
                                          const char *prefix, bool fallback)
 {
@@ -528,6 +513,8 @@ static int mac_addr_used = 2;
 static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom,
                                        const char *prefix, bool fallback)
 {
+       bool fb = fallback;
+
        nvram_read_macaddr(prefix, "et0macaddr", sprom->et0mac, fallback);
        nvram_read_u8(prefix, NULL, "et0mdcport", &sprom->et0mdcport, 0,
                      fallback);
@@ -540,6 +527,10 @@ static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom,
        nvram_read_u8(prefix, NULL, "et1phyaddr", &sprom->et1phyaddr, 0,
                      fallback);
 
+       nvram_read_macaddr(prefix, "et2macaddr", sprom->et2mac, fb);
+       nvram_read_u8(prefix, NULL, "et2mdcport", &sprom->et2mdcport, 0, fb);
+       nvram_read_u8(prefix, NULL, "et2phyaddr", &sprom->et2phyaddr, 0, fb);
+
        nvram_read_macaddr(prefix, "macaddr", sprom->il0mac, fallback);
        nvram_read_macaddr(prefix, "il0macaddr", sprom->il0mac, fallback);
 
@@ -580,39 +571,22 @@ void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix,
 
        nvram_read_u8(prefix, NULL, "sromrev", &sprom->revision, 0, fallback);
 
+       /* Entries requiring custom functions */
+       nvram_read_alpha2(prefix, "ccode", sprom->alpha2, fallback);
+       if (sprom->revision >= 3)
+               nvram_read_leddc(prefix, "leddc", &sprom->leddc_on_time,
+                                &sprom->leddc_off_time, fallback);
+
        switch (sprom->revision) {
-       case 1:
-               bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
-               break;
-       case 2:
-               bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
-               break;
-       case 3:
-               bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r3(sprom, prefix, fallback);
-               break;
        case 4:
        case 5:
-               bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r4589(sprom, prefix, fallback);
                bcm47xx_fill_sprom_path_r4589(sprom, prefix, fallback);
                bcm47xx_fill_sprom_path_r45(sprom, prefix, fallback);
                break;
        case 8:
-               bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r4589(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_path_r4589(sprom, prefix, fallback);
-               break;
        case 9:
-               bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
-               bcm47xx_fill_sprom_r4589(sprom, prefix, fallback);
                bcm47xx_fill_sprom_path_r4589(sprom, prefix, fallback);
                break;
-       default:
-               pr_warn("Unsupported SPROM revision %d detected. Will extract v1\n",
-                       sprom->revision);
-               sprom->revision = 1;
-               bcm47xx_fill_sprom_r1234589(sprom, prefix, fallback);
        }
 
        bcm47xx_sprom_fill_auto(sprom, prefix, fallback);
@@ -631,19 +605,6 @@ void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo,
 }
 #endif
 
-#ifdef CONFIG_BCM47XX_BCMA
-void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo,
-                                const char *prefix)
-{
-       nvram_read_u16(prefix, NULL, "boardvendor", &boardinfo->vendor, 0,
-                      true);
-       if (!boardinfo->vendor)
-               boardinfo->vendor = SSB_BOARDVENDOR_BCM;
-
-       nvram_read_u16(prefix, NULL, "boardtype", &boardinfo->type, 0, true);
-}
-#endif
-
 #if defined(CONFIG_BCM47XX_SSB)
 static int bcm47xx_get_sprom_ssb(struct ssb_bus *bus, struct ssb_sprom *out)
 {
@@ -698,33 +659,46 @@ static void bcm47xx_sprom_apply_prefix_alias(char *prefix, size_t prefix_size)
 
 static int bcm47xx_get_sprom_bcma(struct bcma_bus *bus, struct ssb_sprom *out)
 {
-       char prefix[10];
+       struct bcma_boardinfo *binfo = &bus->boardinfo;
        struct bcma_device *core;
+       char buf[10];
+       char *prefix;
+       bool fallback = false;
 
        switch (bus->hosttype) {
        case BCMA_HOSTTYPE_PCI:
                memset(out, 0, sizeof(struct ssb_sprom));
-               snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
+               snprintf(buf, sizeof(buf), "pci/%u/%u/",
                         bus->host_pci->bus->number + 1,
                         PCI_SLOT(bus->host_pci->devfn));
-               bcm47xx_sprom_apply_prefix_alias(prefix, sizeof(prefix));
-               bcm47xx_fill_sprom(out, prefix, false);
-               return 0;
+               bcm47xx_sprom_apply_prefix_alias(buf, sizeof(buf));
+               prefix = buf;
+               break;
        case BCMA_HOSTTYPE_SOC:
                memset(out, 0, sizeof(struct ssb_sprom));
                core = bcma_find_core(bus, BCMA_CORE_80211);
                if (core) {
-                       snprintf(prefix, sizeof(prefix), "sb/%u/",
+                       snprintf(buf, sizeof(buf), "sb/%u/",
                                 core->core_index);
-                       bcm47xx_fill_sprom(out, prefix, true);
+                       prefix = buf;
+                       fallback = true;
                } else {
-                       bcm47xx_fill_sprom(out, NULL, false);
+                       prefix = NULL;
                }
-               return 0;
+               break;
        default:
                pr_warn("Unable to fill SPROM for given bustype.\n");
                return -EINVAL;
        }
+
+       nvram_read_u16(prefix, NULL, "boardvendor", &binfo->vendor, 0, true);
+       if (!binfo->vendor)
+               binfo->vendor = SSB_BOARDVENDOR_BCM;
+       nvram_read_u16(prefix, NULL, "boardtype", &binfo->type, 0, true);
+
+       bcm47xx_fill_sprom(out, prefix, fallback);
+
+       return 0;
 }
 #endif
 
index f35c84c..e2c4fd6 100644 (file)
@@ -57,6 +57,10 @@ config DT_BCM97425SVMB
        bool "BCM97425SVMB"
        select BUILTIN_DTB
 
+config DT_BCM97435SVMB
+       bool "BCM97435SVMB"
+       select BUILTIN_DTB
+
 endchoice
 
 endif
index fae800e..526ec27 100644 (file)
@@ -149,6 +149,8 @@ void __init plat_mem_setup(void)
        /* intended to somewhat resemble ARM; see Documentation/arm/Booting */
        if (fw_arg0 == 0 && fw_arg1 == 0xffffffff)
                dtb = phys_to_virt(fw_arg2);
+       else if (fw_arg0 == -2) /* UHI interface */
+               dtb = (void *)fw_arg1;
        else if (__dtb_start != __dtb_end)
                dtb = (void *)__dtb_start;
        else
index 409cb48..c580e85 100644 (file)
@@ -25,6 +25,22 @@ start:
        move    s2, a2
        move    s3, a3
 
+#ifdef CONFIG_MIPS_ZBOOT_APPENDED_DTB
+       PTR_LA  t0, __appended_dtb
+#ifdef CONFIG_CPU_BIG_ENDIAN
+       li      t1, 0xd00dfeed
+#else
+       li      t1, 0xedfe0dd0
+#endif
+       lw      t2, (t0)
+       bne     t1, t2, not_found
+        nop
+
+       move    s1, t0
+       PTR_LI  s0, -2
+not_found:
+#endif
+
        /* Clear BSS */
        PTR_LA  a0, _edata
        PTR_LA  a2, _end
index 5a33409..2ed08fb 100644 (file)
@@ -29,8 +29,12 @@ SECTIONS
                *(.image)
                __image_end = .;
                CONSTRUCTORS
+               . = ALIGN(16);
        }
-       . = ALIGN(16);
+       __appended_dtb = .;
+       /* leave space for appended DTB */
+       . += 0x100000;
+
        _edata = .;
        /* End of data section */
 
index 237494b..408799a 100644 (file)
@@ -7,7 +7,7 @@
 
 #include <asm/addrspace.h>
 
-#if defined(CONFIG_MACH_LOONGSON) || defined(CONFIG_MIPS_MALTA)
+#if defined(CONFIG_MACH_LOONGSON64) || defined(CONFIG_MIPS_MALTA)
 #define UART_BASE 0x1fd003f8
 #define PORT(offset) (CKSEG1ADDR(UART_BASE) + (offset))
 #endif
index 5d95e4b..778a340 100644 (file)
@@ -1,8 +1,10 @@
 dts-dirs       += brcm
 dts-dirs       += cavium-octeon
+dts-dirs       += ingenic
 dts-dirs       += lantiq
 dts-dirs       += mti
 dts-dirs       += netlogic
+dts-dirs       += qca
 dts-dirs       += ralink
 
 obj-y          := $(addsuffix /, $(dts-dirs))
index 1c8353b..eabeb60 100644 (file)
@@ -9,6 +9,20 @@ dtb-$(CONFIG_DT_BCM97360SVMB)          += bcm97360svmb.dtb
 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_NONE)                  += \
+                                               bcm93384wvg.dtb         \
+                                               bcm93384wvg_viper.dtb   \
+                                               bcm96368mvwg.dtb        \
+                                               bcm9ejtagprb.dtb        \
+                                               bcm97125cbmb.dtb        \
+                                               bcm97346dbsmb.dtb       \
+                                               bcm97358svmb.dtb        \
+                                               bcm97360svmb.dtb        \
+                                               bcm97362svmb.dtb        \
+                                               bcm97420c.dtb           \
+                                               bcm97425svmb.dtb
 
 obj-y                          += $(patsubst %.dtb, %.dtb.o, $(dtb-y))
 
index 1f30728..d817bb4 100644 (file)
@@ -24,6 +24,8 @@
 
        aliases {
                uart0 = &uart0;
+               uart1 = &uart1;
+               uart2 = &uart2;
        };
 
        cpu_intc: cpu_intc {
                        status = "disabled";
                };
 
+               uart1: serial@406940 {
+                       compatible = "ns16550a";
+                       reg = <0x406940 0x20>;
+                       reg-io-width = <0x4>;
+                       reg-shift = <0x2>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <65>;
+                       clocks = <&uart_clk>;
+                       status = "disabled";
+               };
+
+               uart2: serial@406980 {
+                       compatible = "ns16550a";
+                       reg = <0x406980 0x20>;
+                       reg-io-width = <0x4>;
+                       reg-shift = <0x2>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <66>;
+                       clocks = <&uart_clk>;
+                       status = "disabled";
+               };
+
                enet0: ethernet@430000 {
                        phy-mode = "internal";
                        phy-handle = <&phy1>;
index 2c2aa93..277a90a 100644 (file)
@@ -18,6 +18,8 @@
 
        aliases {
                uart0 = &uart0;
+               uart1 = &uart1;
+               uart2 = &uart2;
        };
 
        cpu_intc: cpu_intc {
                        status = "disabled";
                };
 
+               uart1: serial@406840 {
+                       compatible = "ns16550a";
+                       reg = <0x406840 0x20>;
+                       reg-io-width = <0x4>;
+                       reg-shift = <0x2>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <62>;
+                       clocks = <&uart_clk>;
+                       status = "disabled";
+               };
+
+               uart2: serial@406880 {
+                       compatible = "ns16550a";
+                       reg = <0x406880 0x20>;
+                       reg-io-width = <0x4>;
+                       reg-shift = <0x2>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <63>;
+                       clocks = <&uart_clk>;
+                       status = "disabled";
+               };
+
                enet0: ethernet@430000 {
                        phy-mode = "internal";
                        phy-handle = <&phy1>;
index f23b0ae..9e1e571 100644 (file)
@@ -18,6 +18,8 @@
 
        aliases {
                uart0 = &uart0;
+               uart1 = &uart1;
+               uart2 = &uart2;
        };
 
        cpu_intc: cpu_intc {
                        status = "disabled";
                };
 
+               uart1: serial@406840 {
+                       compatible = "ns16550a";
+                       reg = <0x406840 0x20>;
+                       reg-io-width = <0x4>;
+                       reg-shift = <0x2>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <62>;
+                       clocks = <&uart_clk>;
+                       status = "disabled";
+               };
+
+               uart2: serial@406880 {
+                       compatible = "ns16550a";
+                       reg = <0x406880 0x20>;
+                       reg-io-width = <0x4>;
+                       reg-shift = <0x2>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <63>;
+                       clocks = <&uart_clk>;
+                       status = "disabled";
+               };
+
                enet0: ethernet@430000 {
                        phy-mode = "internal";
                        phy-handle = <&phy1>;
index da99db6..6e65db8 100644 (file)
@@ -24,6 +24,8 @@
 
        aliases {
                uart0 = &uart0;
+               uart1 = &uart1;
+               uart2 = &uart2;
        };
 
        cpu_intc: cpu_intc {
                        status = "disabled";
                };
 
+               uart1: serial@406840 {
+                       compatible = "ns16550a";
+                       reg = <0x406840 0x20>;
+                       reg-io-width = <0x4>;
+                       reg-shift = <0x2>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <62>;
+                       clocks = <&uart_clk>;
+                       status = "disabled";
+               };
+
+               uart2: serial@406880 {
+                       compatible = "ns16550a";
+                       reg = <0x406880 0x20>;
+                       reg-io-width = <0x4>;
+                       reg-shift = <0x2>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <63>;
+                       clocks = <&uart_clk>;
+                       status = "disabled";
+               };
+
                enet0: ethernet@430000 {
                        phy-mode = "internal";
                        phy-handle = <&phy1>;
diff --git a/arch/mips/boot/dts/brcm/bcm7435.dtsi b/arch/mips/boot/dts/brcm/bcm7435.dtsi
new file mode 100644 (file)
index 0000000..8b9432c
--- /dev/null
@@ -0,0 +1,239 @@
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "brcm,bcm7435";
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               mips-hpt-frequency = <163125000>;
+
+               cpu@0 {
+                       compatible = "brcm,bmips5200";
+                       device_type = "cpu";
+                       reg = <0>;
+               };
+
+               cpu@1 {
+                       compatible = "brcm,bmips5200";
+                       device_type = "cpu";
+                       reg = <1>;
+               };
+
+               cpu@2 {
+                       compatible = "brcm,bmips5200";
+                       device_type = "cpu";
+                       reg = <2>;
+               };
+
+               cpu@3 {
+                       compatible = "brcm,bmips5200";
+                       device_type = "cpu";
+                       reg = <3>;
+               };
+       };
+
+       aliases {
+               uart0 = &uart0;
+       };
+
+       cpu_intc: cpu_intc {
+               #address-cells = <0>;
+               compatible = "mti,cpu-interrupt-controller";
+
+               interrupt-controller;
+               #interrupt-cells = <1>;
+       };
+
+       clocks {
+               uart_clk: uart_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <81000000>;
+               };
+       };
+
+       rdb {
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               compatible = "simple-bus";
+               ranges = <0 0x10000000 0x01000000>;
+
+               periph_intc: periph_intc@41b500 {
+                       compatible = "brcm,bcm7038-l1-intc";
+                       reg = <0x41b500 0x40>, <0x41b600 0x40>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&cpu_intc>;
+                       interrupts = <2>, <3>;
+               };
+
+               sun_l2_intc: sun_l2_intc@403000 {
+                       compatible = "brcm,l2-intc";
+                       reg = <0x403000 0x30>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <52>;
+               };
+
+               gisb-arb@400000 {
+                       compatible = "brcm,bcm7400-gisb-arb";
+                       reg = <0x400000 0xdc>;
+                       native-endian;
+                       interrupt-parent = <&sun_l2_intc>;
+                       interrupts = <0>, <2>;
+                       brcm,gisb-arb-master-mask = <0xf77f>;
+                       brcm,gisb-arb-master-names = "ssp_0", "cpu_0", "webcpu_0",
+                                                    "pcie_0", "bsp_0",
+                                                    "rdc_0", "raaga_0",
+                                                    "avd_1", "jtag_0",
+                                                    "svd_0", "vice_0",
+                                                    "vice_1", "raaga_1",
+                                                    "scpu";
+               };
+
+               upg_irq0_intc: upg_irq0_intc@406780 {
+                       compatible = "brcm,bcm7120-l2-intc";
+                       reg = <0x406780 0x8>;
+
+                       brcm,int-map-mask = <0x44>;
+                       brcm,int-fwd-mask = <0x70000>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <60>;
+               };
+
+               sun_top_ctrl: syscon@404000 {
+                       compatible = "brcm,bcm7425-sun-top-ctrl", "syscon";
+                       reg = <0x404000 0x51c>;
+                       little-endian;
+               };
+
+               reboot {
+                       compatible = "brcm,brcmstb-reboot";
+                       syscon = <&sun_top_ctrl 0x304 0x308>;
+               };
+
+               uart0: serial@406b00 {
+                       compatible = "ns16550a";
+                       reg = <0x406b00 0x20>;
+                       reg-io-width = <0x4>;
+                       reg-shift = <0x2>;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <66>;
+                       clocks = <&uart_clk>;
+                       status = "disabled";
+               };
+
+               enet0: ethernet@b80000 {
+                       phy-mode = "internal";
+                       phy-handle = <&phy1>;
+                       mac-address = [ 00 10 18 36 23 1a ];
+                       compatible = "brcm,genet-v3";
+                       #address-cells = <0x1>;
+                       #size-cells = <0x1>;
+                       reg = <0xb80000 0x11c88>;
+                       interrupts = <17>, <18>;
+                       interrupt-parent = <&periph_intc>;
+                       status = "disabled";
+
+                       mdio@e14 {
+                               compatible = "brcm,genet-mdio-v3";
+                               #address-cells = <0x1>;
+                               #size-cells = <0x0>;
+                               reg = <0xe14 0x8>;
+
+                               phy1: ethernet-phy@1 {
+                                       max-speed = <100>;
+                                       reg = <0x1>;
+                                       compatible = "brcm,40nm-ephy",
+                                               "ethernet-phy-ieee802.3-c22";
+                               };
+                       };
+               };
+
+               ehci0: usb@480300 {
+                       compatible = "brcm,bcm7435-ehci", "generic-ehci";
+                       reg = <0x480300 0x100>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <70>;
+                       status = "disabled";
+               };
+
+               ohci0: usb@480400 {
+                       compatible = "brcm,bcm7435-ohci", "generic-ohci";
+                       reg = <0x480400 0x100>;
+                       native-endian;
+                       no-big-frame-no;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <72>;
+                       status = "disabled";
+               };
+
+               ehci1: usb@480500 {
+                       compatible = "brcm,bcm7435-ehci", "generic-ehci";
+                       reg = <0x480500 0x100>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <71>;
+                       status = "disabled";
+               };
+
+               ohci1: usb@480600 {
+                       compatible = "brcm,bcm7435-ohci", "generic-ohci";
+                       reg = <0x480600 0x100>;
+                       native-endian;
+                       no-big-frame-no;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <73>;
+                       status = "disabled";
+               };
+
+               ehci2: usb@490300 {
+                       compatible = "brcm,bcm7435-ehci", "generic-ehci";
+                       reg = <0x490300 0x100>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <75>;
+                       status = "disabled";
+               };
+
+               ohci2: usb@490400 {
+                       compatible = "brcm,bcm7435-ohci", "generic-ohci";
+                       reg = <0x490400 0x100>;
+                       native-endian;
+                       no-big-frame-no;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <77>;
+                       status = "disabled";
+               };
+
+               ehci3: usb@490500 {
+                       compatible = "brcm,bcm7435-ehci", "generic-ehci";
+                       reg = <0x490500 0x100>;
+                       native-endian;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <76>;
+                       status = "disabled";
+               };
+
+               ohci3: usb@490600 {
+                       compatible = "brcm,bcm7435-ohci", "generic-ohci";
+                       reg = <0x490600 0x100>;
+                       native-endian;
+                       no-big-frame-no;
+                       interrupt-parent = <&periph_intc>;
+                       interrupts = <78>;
+                       status = "disabled";
+               };
+       };
+};
index 70f196d..3fe0445 100644 (file)
        status = "okay";
 };
 
+&uart1 {
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
+
 &enet0 {
        status = "okay";
 };
index d18e6d9..a8dc01e 100644 (file)
        status = "okay";
 };
 
+&uart1 {
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
+
 &enet0 {
        status = "okay";
 };
index 4fe5155..eee8b0e 100644 (file)
        status = "okay";
 };
 
+&uart1 {
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
+
 &enet0 {
        status = "okay";
 };
index b7b88e5..739c2ef 100644 (file)
        status = "okay";
 };
 
+&uart1 {
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
+
 &enet0 {
        status = "okay";
 };
diff --git a/arch/mips/boot/dts/brcm/bcm97435svmb.dts b/arch/mips/boot/dts/brcm/bcm97435svmb.dts
new file mode 100644 (file)
index 0000000..1df0881
--- /dev/null
@@ -0,0 +1,60 @@
+/dts-v1/;
+
+/include/ "bcm7435.dtsi"
+
+/ {
+       compatible = "brcm,bcm97435svmb", "brcm,bcm7435";
+       model = "Broadcom BCM97435SVMB";
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x00000000 0x10000000>,
+                     <0x20000000 0x30000000>,
+                     <0x90000000 0x40000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttyS0,115200 maxcpus=1";
+               stdout-path = &uart0;
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&enet0 {
+       status = "okay";
+};
+
+&ehci0 {
+       status = "okay";
+};
+
+&ohci0 {
+       status = "okay";
+};
+
+&ehci1 {
+       status = "okay";
+};
+
+&ohci1 {
+       status = "okay";
+};
+
+&ehci2 {
+       status = "okay";
+};
+
+&ohci2 {
+       status = "okay";
+};
+
+&ehci3 {
+       status = "okay";
+};
+
+&ohci3 {
+       status = "okay";
+};
diff --git a/arch/mips/boot/dts/ingenic/Makefile b/arch/mips/boot/dts/ingenic/Makefile
new file mode 100644 (file)
index 0000000..f2b864f
--- /dev/null
@@ -0,0 +1,10 @@
+dtb-$(CONFIG_JZ4740_QI_LB60)   += qi_lb60.dtb
+dtb-$(CONFIG_JZ4780_CI20)      += ci20.dtb
+
+obj-y                          += $(patsubst %.dtb, %.dtb.o, $(dtb-y))
+
+# Force kbuild to make empty built-in.o if necessary
+obj-                           += dummy.o
+
+always                         := $(dtb-y)
+clean-files                    := *.dtb *.dtb.S
diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts
new file mode 100644 (file)
index 0000000..9fcb9e7
--- /dev/null
@@ -0,0 +1,44 @@
+/dts-v1/;
+
+#include "jz4780.dtsi"
+
+/ {
+       compatible = "img,ci20", "ingenic,jz4780";
+
+       aliases {
+               serial0 = &uart0;
+               serial1 = &uart1;
+               serial3 = &uart3;
+               serial4 = &uart4;
+       };
+
+       chosen {
+               stdout-path = &uart4;
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x0 0x10000000
+                      0x30000000 0x30000000>;
+       };
+};
+
+&ext {
+       clock-frequency = <48000000>;
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&uart1 {
+       status = "okay";
+};
+
+&uart3 {
+       status = "okay";
+};
+
+&uart4 {
+       status = "okay";
+};
diff --git a/arch/mips/boot/dts/ingenic/jz4740.dtsi b/arch/mips/boot/dts/ingenic/jz4740.dtsi
new file mode 100644 (file)
index 0000000..8b2437c
--- /dev/null
@@ -0,0 +1,68 @@
+#include <dt-bindings/clock/jz4740-cgu.h>
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "ingenic,jz4740";
+
+       cpuintc: interrupt-controller@0 {
+               #address-cells = <0>;
+               #interrupt-cells = <1>;
+               interrupt-controller;
+               compatible = "mti,cpu-interrupt-controller";
+       };
+
+       intc: interrupt-controller@10001000 {
+               compatible = "ingenic,jz4740-intc";
+               reg = <0x10001000 0x14>;
+
+               interrupt-controller;
+               #interrupt-cells = <1>;
+
+               interrupt-parent = <&cpuintc>;
+               interrupts = <2>;
+       };
+
+       ext: ext {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+       };
+
+       rtc: rtc {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+       };
+
+       cgu: jz4740-cgu@10000000 {
+               compatible = "ingenic,jz4740-cgu";
+               reg = <0x10000000 0x100>;
+
+               clocks = <&ext>, <&rtc>;
+               clock-names = "ext", "rtc";
+
+               #clock-cells = <1>;
+       };
+
+       uart0: serial@10030000 {
+               compatible = "ingenic,jz4740-uart";
+               reg = <0x10030000 0x100>;
+
+               interrupt-parent = <&intc>;
+               interrupts = <9>;
+
+               clocks = <&ext>, <&cgu JZ4740_CLK_UART0>;
+               clock-names = "baud", "module";
+       };
+
+       uart1: serial@10031000 {
+               compatible = "ingenic,jz4740-uart";
+               reg = <0x10031000 0x100>;
+
+               interrupt-parent = <&intc>;
+               interrupts = <8>;
+
+               clocks = <&ext>, <&cgu JZ4740_CLK_UART1>;
+               clock-names = "baud", "module";
+       };
+};
diff --git a/arch/mips/boot/dts/ingenic/jz4780.dtsi b/arch/mips/boot/dts/ingenic/jz4780.dtsi
new file mode 100644 (file)
index 0000000..65389f6
--- /dev/null
@@ -0,0 +1,111 @@
+#include <dt-bindings/clock/jz4780-cgu.h>
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "ingenic,jz4780";
+
+       cpuintc: interrupt-controller {
+               #address-cells = <0>;
+               #interrupt-cells = <1>;
+               interrupt-controller;
+               compatible = "mti,cpu-interrupt-controller";
+       };
+
+       intc: interrupt-controller@10001000 {
+               compatible = "ingenic,jz4780-intc";
+               reg = <0x10001000 0x50>;
+
+               interrupt-controller;
+               #interrupt-cells = <1>;
+
+               interrupt-parent = <&cpuintc>;
+               interrupts = <2>;
+       };
+
+       ext: ext {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+       };
+
+       rtc: rtc {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+       };
+
+       cgu: jz4780-cgu@10000000 {
+               compatible = "ingenic,jz4780-cgu";
+               reg = <0x10000000 0x100>;
+
+               clocks = <&ext>, <&rtc>;
+               clock-names = "ext", "rtc";
+
+               #clock-cells = <1>;
+       };
+
+       uart0: serial@10030000 {
+               compatible = "ingenic,jz4780-uart";
+               reg = <0x10030000 0x100>;
+
+               interrupt-parent = <&intc>;
+               interrupts = <51>;
+
+               clocks = <&ext>, <&cgu JZ4780_CLK_UART0>;
+               clock-names = "baud", "module";
+
+               status = "disabled";
+       };
+
+       uart1: serial@10031000 {
+               compatible = "ingenic,jz4780-uart";
+               reg = <0x10031000 0x100>;
+
+               interrupt-parent = <&intc>;
+               interrupts = <50>;
+
+               clocks = <&ext>, <&cgu JZ4780_CLK_UART1>;
+               clock-names = "baud", "module";
+
+               status = "disabled";
+       };
+
+       uart2: serial@10032000 {
+               compatible = "ingenic,jz4780-uart";
+               reg = <0x10032000 0x100>;
+
+               interrupt-parent = <&intc>;
+               interrupts = <49>;
+
+               clocks = <&ext>, <&cgu JZ4780_CLK_UART2>;
+               clock-names = "baud", "module";
+
+               status = "disabled";
+       };
+
+       uart3: serial@10033000 {
+               compatible = "ingenic,jz4780-uart";
+               reg = <0x10033000 0x100>;
+
+               interrupt-parent = <&intc>;
+               interrupts = <48>;
+
+               clocks = <&ext>, <&cgu JZ4780_CLK_UART3>;
+               clock-names = "baud", "module";
+
+               status = "disabled";
+       };
+
+       uart4: serial@10034000 {
+               compatible = "ingenic,jz4780-uart";
+               reg = <0x10034000 0x100>;
+
+               interrupt-parent = <&intc>;
+               interrupts = <34>;
+
+               clocks = <&ext>, <&cgu JZ4780_CLK_UART4>;
+               clock-names = "baud", "module";
+
+               status = "disabled";
+       };
+};
diff --git a/arch/mips/boot/dts/ingenic/qi_lb60.dts b/arch/mips/boot/dts/ingenic/qi_lb60.dts
new file mode 100644 (file)
index 0000000..2414d63
--- /dev/null
@@ -0,0 +1,15 @@
+/dts-v1/;
+
+#include "jz4740.dtsi"
+
+/ {
+       compatible = "qi,lb60", "ingenic,jz4740";
+
+       chosen {
+               stdout-path = &uart0;
+       };
+};
+
+&ext {
+       clock-frequency = <12000000>;
+};
index ef1f3db..144d776 100644 (file)
@@ -1,3 +1,4 @@
+dtb-$(CONFIG_MIPS_MALTA)       += malta.dtb
 dtb-$(CONFIG_MIPS_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
new file mode 100644 (file)
index 0000000..c678115
--- /dev/null
@@ -0,0 +1,7 @@
+/dts-v1/;
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "mti,malta";
+};
diff --git a/arch/mips/boot/dts/qca/Makefile b/arch/mips/boot/dts/qca/Makefile
new file mode 100644 (file)
index 0000000..2d61455
--- /dev/null
@@ -0,0 +1,11 @@
+# All DTBs
+dtb-$(CONFIG_ATH79)                    += ar9132_tl_wr1043nd_v1.dtb
+
+# Select a DTB to build in the kernel
+obj-$(CONFIG_DTB_TL_WR1043ND_V1)       += ar9132_tl_wr1043nd_v1.dtb.o
+
+# Force kbuild to make empty built-in.o if necessary
+obj-                           += dummy.o
+
+always                         := $(dtb-y)
+clean-files                    := *.dtb *.dtb.S
diff --git a/arch/mips/boot/dts/qca/ar9132.dtsi b/arch/mips/boot/dts/qca/ar9132.dtsi
new file mode 100644 (file)
index 0000000..4759cff
--- /dev/null
@@ -0,0 +1,133 @@
+/ {
+       compatible = "qca,ar9132";
+
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       compatible = "mips,mips24Kc";
+                       reg = <0>;
+               };
+       };
+
+       cpuintc: interrupt-controller {
+               compatible = "qca,ar9132-cpu-intc", "qca,ar7100-cpu-intc";
+
+               interrupt-controller;
+               #interrupt-cells = <1>;
+
+               qca,ddr-wb-channel-interrupts = <2>, <3>, <4>, <5>;
+               qca,ddr-wb-channels = <&ddr_ctrl 3>, <&ddr_ctrl 2>,
+                                       <&ddr_ctrl 0>, <&ddr_ctrl 1>;
+       };
+
+       ahb {
+               compatible = "simple-bus";
+               ranges;
+
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               interrupt-parent = <&cpuintc>;
+
+               apb {
+                       compatible = "simple-bus";
+                       ranges;
+
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       interrupt-parent = <&miscintc>;
+
+                       ddr_ctrl: memory-controller@18000000 {
+                               compatible = "qca,ar9132-ddr-controller",
+                                               "qca,ar7240-ddr-controller";
+                               reg = <0x18000000 0x100>;
+
+                               #qca,ddr-wb-channel-cells = <1>;
+                       };
+
+                       uart@18020000 {
+                               compatible = "ns8250";
+                               reg = <0x18020000 0x20>;
+                               interrupts = <3>;
+
+                               clocks = <&pll 2>;
+                               clock-names = "uart";
+
+                               reg-io-width = <4>;
+                               reg-shift = <2>;
+                               no-loopback-test;
+
+                               status = "disabled";
+                       };
+
+                       gpio: gpio@18040000 {
+                               compatible = "qca,ar9132-gpio",
+                                               "qca,ar7100-gpio";
+                               reg = <0x18040000 0x30>;
+                               interrupts = <2>;
+
+                               ngpios = <22>;
+
+                               gpio-controller;
+                               #gpio-cells = <2>;
+
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       pll: pll-controller@18050000 {
+                               compatible = "qca,ar9132-ppl",
+                                               "qca,ar9130-pll";
+                               reg = <0x18050000 0x20>;
+
+                               clock-names = "ref";
+                               /* The board must provides the ref clock */
+
+                               #clock-cells = <1>;
+                               clock-output-names = "cpu", "ddr", "ahb";
+                       };
+
+                       wdt@18060008 {
+                               compatible = "qca,ar7130-wdt";
+                               reg = <0x18060008 0x8>;
+
+                               interrupts = <4>;
+
+                               clocks = <&pll 2>;
+                               clock-names = "wdt";
+                       };
+
+                       miscintc: interrupt-controller@18060010 {
+                               compatible = "qca,ar9132-misc-intc",
+                                          "qca,ar7100-misc-intc";
+                               reg = <0x18060010 0x4>;
+
+                               interrupt-parent = <&cpuintc>;
+                               interrupts = <6>;
+
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                       };
+               };
+
+               spi@1f000000 {
+                       compatible = "qca,ar9132-spi", "qca,ar7100-spi";
+                       reg = <0x1f000000 0x10>;
+
+                       clocks = <&pll 2>;
+                       clock-names = "ahb";
+
+                       status = "disabled";
+
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+       };
+};
diff --git a/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts b/arch/mips/boot/dts/qca/ar9132_tl_wr1043nd_v1.dts
new file mode 100644 (file)
index 0000000..003015a
--- /dev/null
@@ -0,0 +1,112 @@
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+#include "ar9132.dtsi"
+
+/ {
+       compatible = "tplink,tl-wr1043nd-v1", "qca,ar9132";
+       model = "TP-Link TL-WR1043ND Version 1";
+
+       alias {
+               serial0 = "/ahb/apb/uart@18020000";
+       };
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x0 0x2000000>;
+       };
+
+       extosc: oscillator {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <40000000>;
+       };
+
+       ahb {
+               apb {
+                       uart@18020000 {
+                               status = "okay";
+                       };
+
+                       pll-controller@18050000 {
+                               clocks = <&extosc>;
+                       };
+               };
+
+               spi@1f000000 {
+                       status = "okay";
+                       num-cs = <1>;
+
+                       flash@0 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               compatible = "s25sl064a";
+                               reg = <0>;
+                               spi-max-frequency = <25000000>;
+
+                               partition@0 {
+                                       label = "u-boot";
+                                       reg = <0x000000 0x020000>;
+                               };
+
+                               partition@1 {
+                                       label = "firmware";
+                                       reg = <0x020000 0x7D0000>;
+                               };
+
+                               partition@2 {
+                                       label = "art";
+                                       reg = <0x7F0000 0x010000>;
+                                       read-only;
+                               };
+                       };
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys-polled";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               poll-interval = <20>;
+               button@0 {
+                       label = "reset";
+                       linux,code = <KEY_RESTART>;
+                       gpios = <&gpio 3 GPIO_ACTIVE_LOW>;
+                       debounce-interval = <60>;
+               };
+
+               button@1 {
+                       label = "qss";
+                       linux,code = <KEY_WPS_BUTTON>;
+                       gpios = <&gpio 7 GPIO_ACTIVE_LOW>;
+                       debounce-interval = <60>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               led@0 {
+                       label = "tp-link:green:usb";
+                       gpios = <&gpio 1 GPIO_ACTIVE_LOW>;
+               };
+
+               led@1 {
+                       label = "tp-link:green:system";
+                       gpios = <&gpio 2 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led@2 {
+                       label = "tp-link:green:qss";
+                       gpios = <&gpio 5 GPIO_ACTIVE_HIGH>;
+               };
+
+               led@3 {
+                       label = "tp-link:green:wlan";
+                       gpios = <&gpio 9 GPIO_ACTIVE_LOW>;
+               };
+       };
+};
index 10f7625..d8124a3 100644 (file)
@@ -698,7 +698,9 @@ static void octeon_irq_ciu_gpio_ack(struct irq_data *data)
 
 static void octeon_irq_handle_trigger(unsigned int irq, struct irq_desc *desc)
 {
-       if (irq_get_trigger_type(irq) & IRQ_TYPE_EDGE_BOTH)
+       struct irq_data *data = irq_desc_get_irq_data(desc);
+
+       if (irqd_get_trigger_type(data) & IRQ_TYPE_EDGE_BOTH)
                handle_edge_irq(irq, desc);
        else
                handle_level_irq(irq, desc);
index 8db7b5d..83e1b10 100644 (file)
@@ -57,5 +57,4 @@ static int __init cobalt_mtd_init(void)
 
        return 0;
 }
-
-module_init(cobalt_mtd_init);
+device_initcall(cobalt_mtd_init);
diff --git a/arch/mips/configs/ci20_defconfig b/arch/mips/configs/ci20_defconfig
new file mode 100644 (file)
index 0000000..4e36b6e
--- /dev/null
@@ -0,0 +1,162 @@
+CONFIG_MACH_INGENIC=y
+CONFIG_JZ4780_CI20=y
+CONFIG_HIGHMEM=y
+# CONFIG_COMPACTION is not set
+CONFIG_CMA=y
+CONFIG_HZ_100=y
+CONFIG_PREEMPT=y
+# CONFIG_SECCOMP is not set
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_KERNEL_XZ=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_FHANDLE=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_MEMCG=y
+CONFIG_MEMCG_KMEM=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_NAMESPACES=y
+CONFIG_USER_NS=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_SLAB=y
+# 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_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_FW_LOADER is not set
+# CONFIG_ALLOW_DEV_COREDUMP is not set
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=32
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+CONFIG_DM9000=y
+CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL=y
+# 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_QUALCOMM is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# 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_VT_HW_CONSOLE_BINDING=y
+CONFIG_LEGACY_PTY_COUNT=2
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=5
+CONFIG_SERIAL_8250_RUNTIME_UARTS=5
+CONFIG_SERIAL_8250_INGENIC=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_JZ4780=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_DEBUG=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_MEMORY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_PROC_KCORE=y
+# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_TMPFS=y
+CONFIG_CONFIGFS_FS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=y
+CONFIG_NLS_CODEPAGE_775=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_CODEPAGE_857=y
+CONFIG_NLS_CODEPAGE_860=y
+CONFIG_NLS_CODEPAGE_861=y
+CONFIG_NLS_CODEPAGE_862=y
+CONFIG_NLS_CODEPAGE_863=y
+CONFIG_NLS_CODEPAGE_864=y
+CONFIG_NLS_CODEPAGE_865=y
+CONFIG_NLS_CODEPAGE_866=y
+CONFIG_NLS_CODEPAGE_869=y
+CONFIG_NLS_CODEPAGE_936=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_CODEPAGE_949=y
+CONFIG_NLS_CODEPAGE_874=y
+CONFIG_NLS_ISO8859_8=y
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_CODEPAGE_1251=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_3=y
+CONFIG_NLS_ISO8859_4=y
+CONFIG_NLS_ISO8859_5=y
+CONFIG_NLS_ISO8859_6=y
+CONFIG_NLS_ISO8859_7=y
+CONFIG_NLS_ISO8859_9=y
+CONFIG_NLS_ISO8859_13=y
+CONFIG_NLS_ISO8859_14=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_KOI8_R=y
+CONFIG_NLS_KOI8_U=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y
+CONFIG_PANIC_ON_OOPS=y
+CONFIG_PANIC_TIMEOUT=10
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_STACKTRACE=y
+# CONFIG_FTRACE is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="earlycon console=ttyS4,115200 clk_ignore_unused"
index b2a577e..a75c65d 100644 (file)
@@ -1,4 +1,4 @@
-CONFIG_MACH_LOONGSON=y
+CONFIG_MACH_LOONGSON64=y
 CONFIG_64BIT=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
index 0cbc986..54cc385 100644 (file)
@@ -1,4 +1,4 @@
-CONFIG_MACH_LOONGSON=y
+CONFIG_MACH_LOONGSON64=y
 CONFIG_LEMOTE_MACH2F=y
 CONFIG_CS5536_MFGPT=y
 CONFIG_64BIT=y
index c844299..f8bf915 100644 (file)
@@ -1,4 +1,4 @@
-CONFIG_MACH_LOONGSON=y
+CONFIG_MACH_LOONGSON64=y
 CONFIG_SWIOTLB=y
 CONFIG_LOONGSON_MACH3X=y
 CONFIG_CPU_LOONGSON3=y
index 7eb7554..1b2cc1f 100644 (file)
@@ -1,4 +1,4 @@
-CONFIG_MACH_LOONGSON1=y
+CONFIG_MACH_LOONGSON32=y
 CONFIG_PREEMPT=y
 # CONFIG_SECCOMP is not set
 CONFIG_EXPERIMENTAL=y
index f8a3231..ac0eb4d 100644 (file)
@@ -84,15 +84,12 @@ CONFIG_NET_CLS_IND=y
 CONFIG_DEVTMPFS=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_IDE=y
-# CONFIG_IDE_PROC_FS is not set
-# CONFIG_IDEPCI_PCIBUS_ORDER is not set
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_PIIX=y
-CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_SG=y
 # CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+# CONFIG_SATA_PMP is not set
+CONFIG_ATA_PIIX=y
 CONFIG_NETDEVICES=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_NET_VENDOR_ADAPTEC is not set
@@ -138,7 +135,6 @@ CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_HW_RANDOM=y
 # CONFIG_HWMON is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
 CONFIG_FB=y
 CONFIG_FIRMWARE_EDID=y
 CONFIG_FB_MATROX=y
@@ -152,7 +148,6 @@ CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_IDE_DISK=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_LEDS_TRIGGER_BACKLIGHT=y
 CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
@@ -160,7 +155,11 @@ CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_CMOS=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
 CONFIG_XFS_FS=y
 CONFIG_XFS_QUOTA=y
 CONFIG_XFS_POSIX_ACL=y
index f22e92e..1646cce 100644 (file)
@@ -272,6 +272,7 @@ CONFIG_IIO=y
 CONFIG_CC10001_ADC=y
 CONFIG_PWM=y
 CONFIG_PWM_IMG=y
+CONFIG_PHY_PISTACHIO_USB=y
 CONFIG_ANDROID=y
 CONFIG_EXT4_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
index 2b96547..d7bb8cc 100644 (file)
@@ -1,4 +1,4 @@
-CONFIG_MACH_JZ4740=y
+CONFIG_MACH_INGENIC=y
 # CONFIG_COMPACTION is not set
 # CONFIG_CROSS_MEMORY_ATTACH is not set
 CONFIG_HZ_100=y
@@ -66,6 +66,7 @@ CONFIG_SERIAL_8250_CONSOLE=y
 # CONFIG_SERIAL_8250_DMA is not set
 CONFIG_SERIAL_8250_NR_UARTS=2
 CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_INGENIC=y
 # CONFIG_HW_RANDOM is not set
 CONFIG_SPI=y
 CONFIG_SPI_GPIO=y
index 6156ac8..76317a7 100644 (file)
        .endm
 
 #ifdef TOOLCHAIN_SUPPORTS_MSA
+/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */
+#undef fp
+
        .macro  _cfcmsa rd, cs
        .set    push
        .set    mips32r2
+       .set    fp=64
        .set    msa
        cfcmsa  \rd, $\cs
        .set    pop
        .macro  _ctcmsa cd, rs
        .set    push
        .set    mips32r2
+       .set    fp=64
        .set    msa
        ctcmsa  $\cd, \rs
        .set    pop
        .macro  ld_d    wd, off, base
        .set    push
        .set    mips32r2
+       .set    fp=64
        .set    msa
        ld.d    $w\wd, \off(\base)
        .set    pop
        .macro  st_d    wd, off, base
        .set    push
        .set    mips32r2
+       .set    fp=64
        .set    msa
        st.d    $w\wd, \off(\base)
        .set    pop
        .macro  copy_u_w        ws, n
        .set    push
        .set    mips32r2
+       .set    fp=64
        .set    msa
        copy_u.w $1, $w\ws[\n]
        .set    pop
        .macro  copy_u_d        ws, n
        .set    push
        .set    mips64r2
+       .set    fp=64
        .set    msa
        copy_u.d $1, $w\ws[\n]
        .set    pop
        .macro  insert_w        wd, n
        .set    push
        .set    mips32r2
+       .set    fp=64
        .set    msa
        insert.w $w\wd[\n], $1
        .set    pop
        .macro  insert_d        wd, n
        .set    push
        .set    mips64r2
+       .set    fp=64
        .set    msa
        insert.d $w\wd[\n], $1
        .set    pop
index 0cf29bd..ce9666c 100644 (file)
@@ -469,7 +469,7 @@ static inline int test_and_change_bit(unsigned long nr,
  */
 static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *addr)
 {
-       smp_mb();
+       smp_mb__before_llsc();
        __clear_bit(nr, addr);
 }
 
diff --git a/arch/mips/include/asm/bmips-spaces.h b/arch/mips/include/asm/bmips-spaces.h
new file mode 100644 (file)
index 0000000..eb96541
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __ASM_BMIPS_SPACES_H
+#define __ASM_BMIPS_SPACES_H
+
+/* Avoid collisions with system base register (SBR) region on BMIPS3300 */
+#define FIXADDR_TOP            ((unsigned long)(long)(int)0xff000000)
+
+#endif /* __ASM_BMIPS_SPACES_H */
index 5aeaf19..f25de77 100644 (file)
 #ifndef cpu_has_llsc
 #define cpu_has_llsc           (cpu_data[0].options & MIPS_CPU_LLSC)
 #endif
+#ifndef cpu_has_bp_ghist
+#define cpu_has_bp_ghist       (cpu_data[0].options & MIPS_CPU_BP_GHIST)
+#endif
 #ifndef kernel_uses_llsc
 #define kernel_uses_llsc       cpu_has_llsc
 #endif
index 33f3cab..d41e8e2 100644 (file)
@@ -32,12 +32,12 @@ static inline int __pure __get_cpu_type(const int cpu_type)
        case CPU_4KC:
        case CPU_ALCHEMY:
        case CPU_PR4450:
-       case CPU_JZRISC:
 #endif
 
 #if defined(CONFIG_SYS_HAS_CPU_MIPS32_R1) || \
     defined(CONFIG_SYS_HAS_CPU_MIPS32_R2)
        case CPU_4KEC:
+       case CPU_JZRISC:
 #endif
 
 #ifdef CONFIG_SYS_HAS_CPU_MIPS32_R2
index e3adca1..e46e406 100644 (file)
@@ -42,7 +42,9 @@
 #define PRID_COMP_LEXRA                0x0b0000
 #define PRID_COMP_NETLOGIC     0x0c0000
 #define PRID_COMP_CAVIUM       0x0d0000
-#define PRID_COMP_INGENIC      0xd00000
+#define PRID_COMP_INGENIC_D0   0xd00000        /* JZ4740, JZ4750 */
+#define PRID_COMP_INGENIC_D1   0xd10000        /* JZ4770, JZ4775 */
+#define PRID_COMP_INGENIC_E1   0xe10000        /* JZ4780 */
 
 /*
  * Assigned Processor ID (implementation) values for bits 15:8 of the PRId
 #define PRID_IMP_CAVIUM_CN70XX 0x9600
 
 /*
- * These are the PRID's for when 23:16 == PRID_COMP_INGENIC
+ * These are the PRID's for when 23:16 == PRID_COMP_INGENIC_*
  */
 
 #define PRID_IMP_JZRISC               0x0200
@@ -379,6 +381,7 @@ enum cpu_type_enum {
 #define MIPS_CPU_RW_LLB                0x1000000000ull /* LLADDR/LLB writes are allowed */
 #define MIPS_CPU_XPA           0x2000000000ull /* CPU supports Extended Physical Addressing */
 #define MIPS_CPU_CDMM          0x4000000000ull /* CPU has Common Device Memory Map */
+#define MIPS_CPU_BP_GHIST      0x8000000000ull /* R12K+ Branch Prediction Global History */
 
 /*
  * CPU ASE encodings
index 4087b47..7b99efd 100644 (file)
 #define __mtc0_tlbw_hazard                                             \
        ___ehb
 
+#define __mtc0_tlbr_hazard                                             \
+       ___ehb
+
 #define __tlbw_use_hazard                                              \
        ___ehb
 
+#define __tlb_read_hazard                                              \
+       ___ehb
+
 #define __tlb_probe_hazard                                             \
        ___ehb
 
@@ -80,12 +86,23 @@ do {                                                                        \
        ___ssnop;                                                       \
        ___ehb
 
+#define __mtc0_tlbr_hazard                                             \
+       ___ssnop;                                                       \
+       ___ssnop;                                                       \
+       ___ehb
+
 #define __tlbw_use_hazard                                              \
        ___ssnop;                                                       \
        ___ssnop;                                                       \
        ___ssnop;                                                       \
        ___ehb
 
+#define __tlb_read_hazard                                              \
+       ___ssnop;                                                       \
+       ___ssnop;                                                       \
+       ___ssnop;                                                       \
+       ___ehb
+
 #define __tlb_probe_hazard                                             \
        ___ssnop;                                                       \
        ___ssnop;                                                       \
@@ -147,8 +164,12 @@ do {                                                                       \
 
 #define __mtc0_tlbw_hazard
 
+#define __mtc0_tlbr_hazard
+
 #define __tlbw_use_hazard
 
+#define __tlb_read_hazard
+
 #define __tlb_probe_hazard
 
 #define __irq_enable_hazard
@@ -166,8 +187,12 @@ do {                                                                       \
  */
 #define __mtc0_tlbw_hazard
 
+#define __mtc0_tlbr_hazard
+
 #define __tlbw_use_hazard
 
+#define __tlb_read_hazard
+
 #define __tlb_probe_hazard
 
 #define __irq_enable_hazard
@@ -196,11 +221,20 @@ do {                                                                      \
        nop;                                                            \
        nop
 
+#define __mtc0_tlbr_hazard                                             \
+       nop;                                                            \
+       nop
+
 #define __tlbw_use_hazard                                              \
        nop;                                                            \
        nop;                                                            \
        nop
 
+#define __tlb_read_hazard                                              \
+       nop;                                                            \
+       nop;                                                            \
+       nop
+
 #define __tlb_probe_hazard                                             \
        nop;                                                            \
        nop;                                                            \
@@ -267,7 +301,9 @@ do {                                                                        \
 #define _ssnop ___ssnop
 #define        _ehb ___ehb
 #define mtc0_tlbw_hazard __mtc0_tlbw_hazard
+#define mtc0_tlbr_hazard __mtc0_tlbr_hazard
 #define tlbw_use_hazard __tlbw_use_hazard
+#define tlb_read_hazard __tlb_read_hazard
 #define tlb_probe_hazard __tlb_probe_hazard
 #define irq_enable_hazard __irq_enable_hazard
 #define irq_disable_hazard __irq_disable_hazard
@@ -300,6 +336,14 @@ do {                                                                       \
 } while (0)
 
 
+#define mtc0_tlbr_hazard()                                             \
+do {                                                                   \
+       __asm__ __volatile__(                                           \
+       __stringify(__mtc0_tlbr_hazard)                                 \
+       );                                                              \
+} while (0)
+
+
 #define tlbw_use_hazard()                                              \
 do {                                                                   \
        __asm__ __volatile__(                                           \
@@ -308,6 +352,14 @@ do {                                                                       \
 } while (0)
 
 
+#define tlb_read_hazard()                                              \
+do {                                                                   \
+       __asm__ __volatile__(                                           \
+       __stringify(__tlb_read_hazard)                                  \
+       );                                                              \
+} while (0)
+
+
 #define tlb_probe_hazard()                                             \
 do {                                                                   \
        __asm__ __volatile__(                                           \
index c7e2784..a7fbcd6 100644 (file)
@@ -41,6 +41,7 @@ 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);
 
 /*
  * Do the traditional i8259 interrupt polling thing.  This is for the few
index d60cc68..e7b138b 100644 (file)
@@ -60,7 +60,7 @@ static inline void arch_local_irq_restore(unsigned long flags)
        "       .set    push                                            \n"
        "       .set    noreorder                                       \n"
        "       .set    noat                                            \n"
-#if defined(CONFIG_IRQ_CPU)
+#if defined(CONFIG_IRQ_MIPS_CPU)
        /*
         * Slow, but doesn't suffer from a relatively unlikely race
         * condition we're having since days 1.
@@ -90,7 +90,7 @@ static inline void __arch_local_irq_restore(unsigned long flags)
        "       .set    push                                            \n"
        "       .set    noreorder                                       \n"
        "       .set    noat                                            \n"
-#if defined(CONFIG_IRQ_CPU)
+#if defined(CONFIG_IRQ_MIPS_CPU)
        /*
         * Slow, but doesn't suffer from a relatively unlikely race
         * condition we're having since days 1.
index e6c0b0e..69dc0df 100644 (file)
@@ -33,7 +33,6 @@
 #define CACHE_FLUSH_IS_SAFE    0
 
 extern void arch_kgdb_breakpoint(void);
-extern int kgdb_early_setup;
 extern void *saved_vectors[32];
 extern void handle_exception(struct pt_regs *regs);
 extern void breakinst(void);
index cd41e93..aa3800c 100644 (file)
 #define AR71XX_PLL_REG_ETH0_INT_CLOCK  0x10
 #define AR71XX_PLL_REG_ETH1_INT_CLOCK  0x14
 
-#define AR71XX_PLL_DIV_SHIFT           3
-#define AR71XX_PLL_DIV_MASK            0x1f
+#define AR71XX_PLL_FB_SHIFT            3
+#define AR71XX_PLL_FB_MASK             0x1f
 #define AR71XX_CPU_DIV_SHIFT           16
 #define AR71XX_CPU_DIV_MASK            0x3
 #define AR71XX_DDR_DIV_SHIFT           18
 #define AR724X_PLL_REG_CPU_CONFIG      0x00
 #define AR724X_PLL_REG_PCIE_CONFIG     0x18
 
-#define AR724X_PLL_DIV_SHIFT           0
-#define AR724X_PLL_DIV_MASK            0x3ff
+#define AR724X_PLL_FB_SHIFT            0
+#define AR724X_PLL_FB_MASK             0x3ff
 #define AR724X_PLL_REF_DIV_SHIFT       10
 #define AR724X_PLL_REF_DIV_MASK                0xf
 #define AR724X_AHB_DIV_SHIFT           19
 #define AR913X_PLL_REG_ETH0_INT_CLOCK  0x14
 #define AR913X_PLL_REG_ETH1_INT_CLOCK  0x18
 
-#define AR913X_PLL_DIV_SHIFT           0
-#define AR913X_PLL_DIV_MASK            0x3ff
+#define AR913X_PLL_FB_SHIFT            0
+#define AR913X_PLL_FB_MASK             0x3ff
 #define AR913X_DDR_DIV_SHIFT           22
 #define AR913X_DDR_DIV_MASK            0x3
 #define AR913X_AHB_DIV_SHIFT           19
index 1557934..4eee221 100644 (file)
@@ -115,7 +115,8 @@ static inline int soc_is_qca955x(void)
        return soc_is_qca9556() || soc_is_qca9558();
 }
 
-extern void __iomem *ath79_ddr_base;
+void ath79_ddr_set_pci_windows(void);
+
 extern void __iomem *ath79_pll_base;
 extern void __iomem *ath79_reset_base;
 
index 8ed77f6..1461c10 100644 (file)
@@ -52,10 +52,6 @@ void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix,
 void bcm47xx_fill_ssb_boardinfo(struct ssb_boardinfo *boardinfo,
                                const char *prefix);
 #endif
-#ifdef CONFIG_BCM47XX_BCMA
-void bcm47xx_fill_bcma_boardinfo(struct bcma_boardinfo *boardinfo,
-                                const char *prefix);
-#endif
 
 void bcm47xx_set_system_type(u16 chip_id);
 
index c41d1dc..2afb840 100644 (file)
@@ -80,6 +80,8 @@ enum bcm47xx_board {
        BCM47XX_BOARD_LINKSYS_WRT610NV2,
        BCM47XX_BOARD_LINKSYS_WRTSL54GS,
 
+       BCM47XX_BOARD_LUXUL_XWR_1750_V1,
+
        BCM47XX_BOARD_MICROSOFT_MN700,
 
        BCM47XX_BOARD_MOTOROLA_WE800G,
index 61e750f..1410ed0 100644 (file)
@@ -10,7 +10,7 @@
 #ifndef _ASM_BCM63XX_SPACES_H
 #define _ASM_BCM63XX_SPACES_H
 
-#define FIXADDR_TOP            ((unsigned long)(long)(int)0xff000000)
+#include <asm/bmips-spaces.h>
 
 #include <asm/mach-generic/spaces.h>
 
index 1b05bdd..c59b28f 100644 (file)
@@ -11,7 +11,7 @@
 #define _ASM_BMIPS_SPACES_H
 
 /* Avoid collisions with system base register (SBR) region on BMIPS3300 */
-#define FIXADDR_TOP            ((unsigned long)(long)(int)0xff000000)
+#include <asm/bmips-spaces.h>
 
 #include <asm/mach-generic/spaces.h>
 
index bdf045f..21eae03 100644 (file)
 
 /* Generic ones first.  */
 #define cpu_has_tlb                    1
+#define cpu_has_tlbinv                 0
+#define cpu_has_segments               0
+#define cpu_has_eva                    0
+#define cpu_has_htw                    0
+#define cpu_has_rixiex                 0
+#define cpu_has_maar                   0
+#define cpu_has_rw_llb                 0
 #define cpu_has_tx39_cache             0
 #define cpu_has_divec                  0
 #define cpu_has_prefetch               0
@@ -24,6 +31,7 @@
 #define cpu_has_mips3d                 0
 #define cpu_has_smartmips              0
 #define cpu_has_rixi                   0
+#define cpu_has_xpa                    0
 #define cpu_has_vtag_icache            0
 #define cpu_has_ic_fills_f_dc          0
 #define cpu_has_pindexed_dcache                0
 #define cpu_has_mips64r1               0
 #define cpu_has_mips64r2               0
 #define cpu_has_dsp                    0
+#define cpu_has_dsp2                   0
 #define cpu_has_mipsmt                 0
 #define cpu_has_userlocal              0
+#define cpu_hwrena_impl_bits           0
+#define cpu_has_perf_cntr_intr_bit     0
+#define cpu_has_vz                     0
+#define cpu_has_fre                    0
+#define cpu_has_cdmm                   0
 
 /* R3k-specific ones.  */
 #ifdef CONFIG_CPU_R3000
+#define cpu_has_3kex                   1
 #define cpu_has_4kex                   0
 #define cpu_has_3k_cache               1
 #define cpu_has_4k_cache               0
@@ -63,6 +78,7 @@
 
 /* R4k-specific ones.  */
 #ifdef CONFIG_CPU_R4X00
+#define cpu_has_3kex                   0
 #define cpu_has_4kex                   1
 #define cpu_has_3k_cache               0
 #define cpu_has_4k_cache               1
index 050e18b..be546a0 100644 (file)
@@ -18,7 +18,7 @@
 #endif
 #endif
 
-#ifdef CONFIG_IRQ_CPU
+#ifdef CONFIG_IRQ_MIPS_CPU
 
 #ifndef MIPS_CPU_IRQ_BASE
 #ifdef CONFIG_I8259
@@ -34,7 +34,7 @@
 #endif
 #endif
 
-#endif /* CONFIG_IRQ_CPU */
+#endif /* CONFIG_IRQ_MIPS_CPU */
 
 #ifdef CONFIG_MIPS_GIC
 #ifndef MIPS_GIC_IRQ_BASE
index 9488fa5..afc96ec 100644 (file)
 #endif
 
 #ifndef FIXADDR_TOP
+#ifdef CONFIG_KVM_GUEST
+#define FIXADDR_TOP            ((unsigned long)(long)(int)0x7ffe0000)
+#else
 #define FIXADDR_TOP            ((unsigned long)(long)(int)0xfffe0000)
 #endif
+#endif
 
 #endif /* __ASM_MACH_GENERIC_SPACES_H */
index d6111aa..7449794 100644 (file)
 #include <asm/cpu.h>
 
 /*
- * IP27 only comes with R10000 family processors all using the same config
+ * IP27 only comes with R1x000 family processors, all using the same config
  */
-#define cpu_has_watch          1
-#define cpu_has_mips16         0
-#define cpu_has_divec          0
-#define cpu_has_vce            0
-#define cpu_has_cache_cdex_p   0
-#define cpu_has_cache_cdex_s   0
-#define cpu_has_prefetch       1
-#define cpu_has_mcheck         0
-#define cpu_has_ejtag          0
+#define cpu_has_tlb                    1
+#define cpu_has_tlbinv                 0
+#define cpu_has_segments               0
+#define cpu_has_eva                    0
+#define cpu_has_htw                    0
+#define cpu_has_rixiex                 0
+#define cpu_has_maar                   0
+#define cpu_has_rw_llb                 0
+#define cpu_has_3kex                   0
+#define cpu_has_4kex                   1
+#define cpu_has_3k_cache               0
+#define cpu_has_4k_cache               1
+#define cpu_has_6k_cache               0
+#define cpu_has_8k_cache               0
+#define cpu_has_tx39_cache             0
+#define cpu_has_fpu                    1
+#define cpu_has_nofpuex                        0
+#define cpu_has_32fpr                  1
+#define cpu_has_counter                        1
+#define cpu_has_watch                  1
+#define cpu_has_64bits                 1
+#define cpu_has_divec                  0
+#define cpu_has_vce                    0
+#define cpu_has_cache_cdex_p           0
+#define cpu_has_cache_cdex_s           0
+#define cpu_has_prefetch               1
+#define cpu_has_mcheck                 0
+#define cpu_has_ejtag                  0
+#define cpu_has_llsc                   1
+#define cpu_has_mips16                 0
+#define cpu_has_mdmx                   0
+#define cpu_has_mips3d                 0
+#define cpu_has_smartmips              0
+#define cpu_has_rixi                   0
+#define cpu_has_xpa                    0
+#define cpu_has_vtag_icache            0
+#define cpu_has_dc_aliases             0
+#define cpu_has_ic_fills_f_dc          0
 
-#define cpu_has_llsc           1
-#define cpu_has_vtag_icache    0
-#define cpu_has_dc_aliases     0
-#define cpu_has_ic_fills_f_dc  0
-#define cpu_has_dsp            0
-#define cpu_has_dsp2           0
 #define cpu_icache_snoops_remote_store 1
-#define cpu_has_mipsmt         0
-#define cpu_has_userlocal      0
 
-#define cpu_has_nofpuex                0
-#define cpu_has_64bits         1
-
-#define cpu_has_4kex           1
-#define cpu_has_3k_cache       0
-#define cpu_has_6k_cache       0
-#define cpu_has_4k_cache       1
-#define cpu_has_8k_cache       0
-#define cpu_has_tx39_cache     0
+#define cpu_has_mips32r1               0
+#define cpu_has_mips32r2               0
+#define cpu_has_mips64r1               0
+#define cpu_has_mips64r2               0
+#define cpu_has_mips32r6               0
+#define cpu_has_mips64r6               0
 
+#define cpu_has_dsp                    0
+#define cpu_has_dsp2                   0
+#define cpu_has_mipsmt                 0
+#define cpu_has_userlocal              0
 #define cpu_has_inclusive_pcaches      1
+#define cpu_hwrena_impl_bits           0
+#define cpu_has_perf_cntr_intr_bit     0
+#define cpu_has_vz                     0
+#define cpu_has_fre                    0
+#define cpu_has_cdmm                   0
 
-#define cpu_dcache_line_size() 32
-#define cpu_icache_line_size() 64
-#define cpu_scache_line_size() 128
-
-#define cpu_has_mips32r1       0
-#define cpu_has_mips32r2       0
-#define cpu_has_mips64r1       0
-#define cpu_has_mips64r2       0
+#define cpu_dcache_line_size()         32
+#define cpu_icache_line_size()         64
+#define cpu_scache_line_size()         128
 
 #endif /* __ASM_MACH_IP27_CPU_FEATURE_OVERRIDES_H */
index 16659cd..104d2df 100644 (file)
@@ -22,6 +22,9 @@ enum jz4740_wait_mode {
 
 void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode);
 
+void jz4740_clock_suspend(void);
+void jz4740_clock_resume(void);
+
 void jz4740_clock_udc_enable_auto_suspend(void);
 void jz4740_clock_udc_disable_auto_suspend(void);
 
index a225baa..0933f94 100644 (file)
@@ -12,8 +12,6 @@
 #define cpu_has_3k_cache       0
 #define cpu_has_4k_cache       1
 #define cpu_has_tx39_cache     0
-#define cpu_has_fpu            0
-#define cpu_has_32fpr  0
 #define cpu_has_counter                0
 #define cpu_has_watch          1
 #define cpu_has_divec          1
@@ -34,7 +32,6 @@
 #define cpu_has_ic_fills_f_dc  0
 #define cpu_has_pindexed_dcache 0
 #define cpu_has_mips32r1       1
-#define cpu_has_mips32r2       0
 #define cpu_has_mips64r1       0
 #define cpu_has_mips64r2       0
 #define cpu_has_dsp            0
index df50736..9b439fc 100644 (file)
 #define MIPS_CPU_IRQ_BASE 0
 #define JZ4740_IRQ_BASE 8
 
+#ifdef CONFIG_MACH_JZ4740
+# define NR_INTC_IRQS  32
+#else
+# define NR_INTC_IRQS  64
+#endif
+
 /* 1st-level interrupts */
 #define JZ4740_IRQ(x)          (JZ4740_IRQ_BASE + (x))
 #define JZ4740_IRQ_I2C         JZ4740_IRQ(1)
 #define JZ4740_IRQ_IPU         JZ4740_IRQ(29)
 #define JZ4740_IRQ_LCD         JZ4740_IRQ(30)
 
+#define JZ4780_IRQ_TCU2                JZ4740_IRQ(25)
+
 /* 2nd-level interrupts */
-#define JZ4740_IRQ_DMA(x)      (JZ4740_IRQ(32) + (x))
+#define JZ4740_IRQ_DMA(x)      (JZ4740_IRQ(NR_INTC_IRQS) + (x))
 
 #define JZ4740_IRQ_INTC_GPIO(x) (JZ4740_IRQ_GPIO0 - (x))
-#define JZ4740_IRQ_GPIO(x)     (JZ4740_IRQ(48) + (x))
+#define JZ4740_IRQ_GPIO(x)     (JZ4740_IRQ(NR_INTC_IRQS + 16) + (x))
 
-#define JZ4740_IRQ_ADC_BASE    JZ4740_IRQ(176)
+#define JZ4740_IRQ_ADC_BASE    JZ4740_IRQ(NR_INTC_IRQS + 144)
 
 #define NR_IRQS (JZ4740_IRQ_ADC_BASE + 6)
 
index 069b43a..32cfbe6 100644 (file)
@@ -35,6 +35,4 @@ extern struct platform_device jz4740_wdt_device;
 extern struct platform_device jz4740_pwm_device;
 extern struct platform_device jz4740_dma_device;
 
-void jz4740_serial_device_register(void);
-
 #endif
diff --git a/arch/mips/include/asm/mach-loongson/workarounds.h b/arch/mips/include/asm/mach-loongson/workarounds.h
deleted file mode 100644 (file)
index e180c14..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __ASM_MACH_LOONGSON_WORKAROUNDS_H_
-#define __ASM_MACH_LOONGSON_WORKAROUNDS_H_
-
-#define WORKAROUND_CPUFREQ     0x00000001
-#define WORKAROUND_CPUHOTPLUG  0x00000002
-
-#endif
@@ -10,8 +10,8 @@
  */
 
 
-#ifndef __ASM_MACH_LOONGSON1_CPUFREQ_H
-#define __ASM_MACH_LOONGSON1_CPUFREQ_H
+#ifndef __ASM_MACH_LOONGSON32_CPUFREQ_H
+#define __ASM_MACH_LOONGSON32_CPUFREQ_H
 
 struct plat_ls1x_cpufreq {
        const char      *clk_name;      /* CPU clk */
@@ -20,4 +20,4 @@ struct plat_ls1x_cpufreq {
        unsigned int    min_freq;       /* in kHz */
 };
 
-#endif /* __ASM_MACH_LOONGSON1_CPUFREQ_H */
+#endif /* __ASM_MACH_LOONGSON32_CPUFREQ_H */
similarity index 95%
rename from arch/mips/include/asm/mach-loongson1/irq.h
rename to arch/mips/include/asm/mach-loongson32/irq.h
index 96bfb1c..0d35b99 100644 (file)
@@ -10,8 +10,8 @@
  */
 
 
-#ifndef __ASM_MACH_LOONGSON1_IRQ_H
-#define __ASM_MACH_LOONGSON1_IRQ_H
+#ifndef __ASM_MACH_LOONGSON32_IRQ_H
+#define __ASM_MACH_LOONGSON32_IRQ_H
 
 /*
  * CPU core Interrupt Numbers
@@ -70,4 +70,4 @@
 
 #define NR_IRQS                        (MIPS_CPU_IRQS + LS1X_IRQS)
 
-#endif /* __ASM_MACH_LOONGSON1_IRQ_H */
+#endif /* __ASM_MACH_LOONGSON32_IRQ_H */
@@ -10,8 +10,8 @@
  */
 
 
-#ifndef __ASM_MACH_LOONGSON1_LOONGSON1_H
-#define __ASM_MACH_LOONGSON1_LOONGSON1_H
+#ifndef __ASM_MACH_LOONGSON32_LOONGSON1_H
+#define __ASM_MACH_LOONGSON32_LOONGSON1_H
 
 #define DEFAULT_MEMSIZE                        256     /* If no memsize provided */
 
@@ -47,4 +47,4 @@
 #include <regs-pwm.h>
 #include <regs-wdt.h>
 
-#endif /* __ASM_MACH_LOONGSON1_LOONGSON1_H */
+#endif /* __ASM_MACH_LOONGSON32_LOONGSON1_H */
@@ -8,8 +8,8 @@
  */
 
 
-#ifndef __ASM_MACH_LOONGSON1_PLATFORM_H
-#define __ASM_MACH_LOONGSON1_PLATFORM_H
+#ifndef __ASM_MACH_LOONGSON32_PLATFORM_H
+#define __ASM_MACH_LOONGSON32_PLATFORM_H
 
 #include <linux/platform_device.h>
 
@@ -23,4 +23,4 @@ extern struct platform_device ls1x_rtc_pdev;
 extern void __init ls1x_clk_init(void);
 extern void __init ls1x_serial_setup(struct platform_device *pdev);
 
-#endif /* __ASM_MACH_LOONGSON1_PLATFORM_H */
+#endif /* __ASM_MACH_LOONGSON32_PLATFORM_H */
similarity index 84%
rename from arch/mips/include/asm/mach-loongson1/prom.h
rename to arch/mips/include/asm/mach-loongson32/prom.h
index 34859a4..a08503c 100644 (file)
@@ -7,8 +7,8 @@
  * option) any later version.
  */
 
-#ifndef __ASM_MACH_LOONGSON1_PROM_H
-#define __ASM_MACH_LOONGSON1_PROM_H
+#ifndef __ASM_MACH_LOONGSON32_PROM_H
+#define __ASM_MACH_LOONGSON32_PROM_H
 
 #include <linux/io.h>
 #include <linux/init.h>
@@ -21,4 +21,4 @@ extern unsigned long memsize, highmemsize;
 extern char *prom_getenv(char *name);
 extern void __init prom_init_cmdline(void);
 
-#endif /* __ASM_MACH_LOONGSON1_PROM_H */
+#endif /* __ASM_MACH_LOONGSON32_PROM_H */
@@ -9,8 +9,8 @@
  * option) any later version.
  */
 
-#ifndef __ASM_MACH_LOONGSON1_REGS_CLK_H
-#define __ASM_MACH_LOONGSON1_REGS_CLK_H
+#ifndef __ASM_MACH_LOONGSON32_REGS_CLK_H
+#define __ASM_MACH_LOONGSON32_REGS_CLK_H
 
 #define LS1X_CLK_REG(x) \
                ((void __iomem *)KSEG1ADDR(LS1X_CLK_BASE + (x)))
@@ -48,4 +48,4 @@
 #define BYPASS_DDR_WIDTH               1
 #define BYPASS_CPU_WIDTH               1
 
-#endif /* __ASM_MACH_LOONGSON1_REGS_CLK_H */
+#endif /* __ASM_MACH_LOONGSON32_REGS_CLK_H */
@@ -9,8 +9,8 @@
  * option) any later version.
  */
 
-#ifndef __ASM_MACH_LOONGSON1_REGS_MUX_H
-#define __ASM_MACH_LOONGSON1_REGS_MUX_H
+#ifndef __ASM_MACH_LOONGSON32_REGS_MUX_H
+#define __ASM_MACH_LOONGSON32_REGS_MUX_H
 
 #define LS1X_MUX_REG(x) \
                ((void __iomem *)KSEG1ADDR(LS1X_MUX_BASE + (x)))
@@ -64,4 +64,4 @@
 #define GMAC1_USE_PWM23                        (0x1 << 1)
 #define GMAC0_USE_PWM01                        0x1
 
-#endif /* __ASM_MACH_LOONGSON1_REGS_MUX_H */
+#endif /* __ASM_MACH_LOONGSON32_REGS_MUX_H */
@@ -9,8 +9,8 @@
  * option) any later version.
  */
 
-#ifndef __ASM_MACH_LOONGSON1_REGS_PWM_H
-#define __ASM_MACH_LOONGSON1_REGS_PWM_H
+#ifndef __ASM_MACH_LOONGSON32_REGS_PWM_H
+#define __ASM_MACH_LOONGSON32_REGS_PWM_H
 
 /* Loongson 1 PWM Timer Register Definitions */
 #define PWM_CNT                        0x0
@@ -26,4 +26,4 @@
 #define PWM_OE                 (0x1 << 3)
 #define CNT_EN                 0x1
 
-#endif /* __ASM_MACH_LOONGSON1_REGS_PWM_H */
+#endif /* __ASM_MACH_LOONGSON32_REGS_PWM_H */
@@ -9,11 +9,11 @@
  * option) any later version.
  */
 
-#ifndef __ASM_MACH_LOONGSON1_REGS_WDT_H
-#define __ASM_MACH_LOONGSON1_REGS_WDT_H
+#ifndef __ASM_MACH_LOONGSON32_REGS_WDT_H
+#define __ASM_MACH_LOONGSON32_REGS_WDT_H
 
 #define WDT_EN                 0x0
 #define WDT_TIMER              0x4
 #define WDT_SET                        0x8
 
-#endif /* __ASM_MACH_LOONGSON1_REGS_WDT_H */
+#endif /* __ASM_MACH_LOONGSON32_REGS_WDT_H */
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_LOONGSON_BOOT_PARAM_H_
-#define __ASM_MACH_LOONGSON_BOOT_PARAM_H_
+#ifndef __ASM_MACH_LOONGSON64_BOOT_PARAM_H_
+#define __ASM_MACH_LOONGSON64_BOOT_PARAM_H_
 
 #define SYSTEM_RAM_LOW         1
 #define SYSTEM_RAM_HIGH                2
@@ -13,8 +13,8 @@
  *     loongson2f user manual.
  */
 
-#ifndef __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H
-#define __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H
+#ifndef __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H
 
 #define cpu_dcache_line_size() 32
 #define cpu_icache_line_size() 32
@@ -58,4 +58,4 @@
 
 #define cpu_has_wsbh           IS_ENABLED(CONFIG_CPU_LOONGSON3)
 
-#endif /* __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H */
+#endif /* __ASM_MACH_LOONGSON64_CPU_FEATURE_OVERRIDES_H */
@@ -8,8 +8,8 @@
  * Author: Fuxin Zhang, zhangfx@lemote.com
  *
  */
-#ifndef __ASM_MACH_LOONGSON_DMA_COHERENCE_H
-#define __ASM_MACH_LOONGSON_DMA_COHERENCE_H
+#ifndef __ASM_MACH_LOONGSON64_DMA_COHERENCE_H
+#define __ASM_MACH_LOONGSON64_DMA_COHERENCE_H
 
 #ifdef CONFIG_SWIOTLB
 #include <linux/swiotlb.h>
@@ -82,4 +82,4 @@ static inline void plat_post_dma_flush(struct device *dev)
 {
 }
 
-#endif /* __ASM_MACH_LOONGSON_DMA_COHERENCE_H */
+#endif /* __ASM_MACH_LOONGSON64_DMA_COHERENCE_H */
similarity index 92%
rename from arch/mips/include/asm/mach-loongson/irq.h
rename to arch/mips/include/asm/mach-loongson64/irq.h
index a281cca..d18c45c 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_LOONGSON_IRQ_H_
-#define __ASM_MACH_LOONGSON_IRQ_H_
+#ifndef __ASM_MACH_LOONGSON64_IRQ_H_
+#define __ASM_MACH_LOONGSON64_IRQ_H_
 
 #include <boot_param.h>
 
@@ -40,4 +40,4 @@ extern void fixup_irqs(void);
 extern void loongson3_ipi_interrupt(struct pt_regs *regs);
 
 #include_next <irq.h>
-#endif /* __ASM_MACH_LOONGSON_IRQ_H_ */
+#endif /* __ASM_MACH_LOONGSON64_IRQ_H_ */
@@ -8,8 +8,8 @@
  * Copyright (C) 2009 Jiajie Chen (chenjiajie@cse.buaa.edu.cn)
  * Copyright (C) 2012 Huacai Chen (chenhc@lemote.com)
  */
-#ifndef __ASM_MACH_LOONGSON_KERNEL_ENTRY_H
-#define __ASM_MACH_LOONGSON_KERNEL_ENTRY_H
+#ifndef __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H
+#define __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H
 
 /*
  * Override macros used in arch/mips/kernel/head.S.
@@ -49,4 +49,4 @@
 #endif
        .endm
 
-#endif /* __ASM_MACH_LOONGSON_KERNEL_ENTRY_H */
+#endif /* __ASM_MACH_LOONGSON64_KERNEL_ENTRY_H */
@@ -8,8 +8,8 @@
  * option) any later version.
  */
 
-#ifndef __ASM_MACH_LOONGSON_LOONGSON_H
-#define __ASM_MACH_LOONGSON_LOONGSON_H
+#ifndef __ASM_MACH_LOONGSON64_LOONGSON_H
+#define __ASM_MACH_LOONGSON64_LOONGSON_H
 
 #include <linux/io.h>
 #include <linux/init.h>
@@ -357,4 +357,4 @@ extern unsigned long _loongson_addrwincfg_base;
 
 #endif /* ! CONFIG_CPU_SUPPORTS_ADDRWINCFG */
 
-#endif /* __ASM_MACH_LOONGSON_LOONGSON_H */
+#endif /* __ASM_MACH_LOONGSON64_LOONGSON_H */
@@ -8,8 +8,8 @@
  * option) any later version.
  */
 
-#ifndef __ASM_MACH_LOONGSON_MACHINE_H
-#define __ASM_MACH_LOONGSON_MACHINE_H
+#ifndef __ASM_MACH_LOONGSON64_MACHINE_H
+#define __ASM_MACH_LOONGSON64_MACHINE_H
 
 #ifdef CONFIG_LEMOTE_FULOONG2E
 
@@ -30,4 +30,4 @@
 
 #endif /* CONFIG_LOONGSON_MACH3X */
 
-#endif /* __ASM_MACH_LOONGSON_MACHINE_H */
+#endif /* __ASM_MACH_LOONGSON64_MACHINE_H */
@@ -7,8 +7,8 @@
  *
  * RTC routines for PC style attached Dallas chip.
  */
-#ifndef __ASM_MACH_LOONGSON_MC146818RTC_H
-#define __ASM_MACH_LOONGSON_MC146818RTC_H
+#ifndef __ASM_MACH_LOONGSON64_MC146818RTC_H
+#define __ASM_MACH_LOONGSON64_MC146818RTC_H
 
 #include <linux/io.h>
 
@@ -33,4 +33,4 @@ static inline void CMOS_WRITE(unsigned char data, unsigned long addr)
 #define mc146818_decode_year(year) ((year) < 70 ? (year) + 2000 : (year) + 1970)
 #endif
 
-#endif /* __ASM_MACH_LOONGSON_MC146818RTC_H */
+#endif /* __ASM_MACH_LOONGSON64_MC146818RTC_H */
similarity index 89%
rename from arch/mips/include/asm/mach-loongson/mem.h
rename to arch/mips/include/asm/mach-loongson64/mem.h
index f4a36d7..75c16be 100644 (file)
@@ -8,8 +8,8 @@
  * option) any later version.
  */
 
-#ifndef __ASM_MACH_LOONGSON_MEM_H
-#define __ASM_MACH_LOONGSON_MEM_H
+#ifndef __ASM_MACH_LOONGSON64_MEM_H
+#define __ASM_MACH_LOONGSON64_MEM_H
 
 /*
  * high memory space
@@ -38,4 +38,4 @@
 #define LOONGSON_MMIO_MEM_END  0x80000000
 #endif
 
-#endif /* __ASM_MACH_LOONGSON_MEM_H */
+#endif /* __ASM_MACH_LOONGSON64_MEM_H */
similarity index 93%
rename from arch/mips/include/asm/mach-loongson/pci.h
rename to arch/mips/include/asm/mach-loongson64/pci.h
index 1212774..3401f55 100644 (file)
@@ -9,8 +9,8 @@
  * option) any later version.
  */
 
-#ifndef __ASM_MACH_LOONGSON_PCI_H_
-#define __ASM_MACH_LOONGSON_PCI_H_
+#ifndef __ASM_MACH_LOONGSON64_PCI_H_
+#define __ASM_MACH_LOONGSON64_PCI_H_
 
 extern struct pci_ops loongson_pci_ops;
 
@@ -52,4 +52,4 @@ extern struct pci_ops loongson_pci_ops;
 
 #endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */
 
-#endif /* !__ASM_MACH_LOONGSON_PCI_H_ */
+#endif /* !__ASM_MACH_LOONGSON64_PCI_H_ */
@@ -1,5 +1,5 @@
-#ifndef __ASM_MACH_LOONGSON_SPACES_H_
-#define __ASM_MACH_LOONGSON_SPACES_H_
+#ifndef __ASM_MACH_LOONGSON64_SPACES_H_
+#define __ASM_MACH_LOONGSON64_SPACES_H_
 
 #if defined(CONFIG_64BIT)
 #define CAC_BASE        _AC(0x9800000000000000, UL)
diff --git a/arch/mips/include/asm/mach-loongson64/workarounds.h b/arch/mips/include/asm/mach-loongson64/workarounds.h
new file mode 100644 (file)
index 0000000..e659f04
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_LOONGSON64_WORKAROUNDS_H_
+#define __ASM_MACH_LOONGSON64_WORKAROUNDS_H_
+
+#define WORKAROUND_CPUFREQ     0x00000001
+#define WORKAROUND_CPUHOTPLUG  0x00000002
+
+#endif
index 59c0901..edc7ee9 100644 (file)
@@ -11,6 +11,7 @@
 #ifndef __MIPS_ASM_MIPS_CM_H__
 #define __MIPS_ASM_MIPS_CM_H__
 
+#include <linux/errno.h>
 #include <linux/io.h>
 #include <linux/types.h>
 
@@ -216,6 +217,10 @@ BUILD_CM_Cx_R_(tcid_8_priority,    0x80)
 #define CM_GCR_CPC_BASE_CPCEN_SHF              0
 #define CM_GCR_CPC_BASE_CPCEN_MSK              (_ULCAST_(0x1) << 0)
 
+/* GCR_GIC_STATUS register fields */
+#define CM_GCR_GIC_STATUS_GICEX_SHF            0
+#define CM_GCR_GIC_STATUS_GICEX_MSK            (_ULCAST_(0x1) << 0)
+
 /* GCR_REGn_BASE register fields */
 #define CM_GCR_REGn_BASE_BASEADDR_SHF          16
 #define CM_GCR_REGn_BASE_BASEADDR_MSK          (_ULCAST_(0xffff) << 16)
index 764e275..c5b0956 100644 (file)
 /*  EntryHI bit definition */
 #define MIPS_ENTRYHI_EHINV     (_ULCAST_(1) << 10)
 
+/* R3000 EntryLo bit definitions */
+#define R3K_ENTRYLO_G          (_ULCAST_(1) << 8)
+#define R3K_ENTRYLO_V          (_ULCAST_(1) << 9)
+#define R3K_ENTRYLO_D          (_ULCAST_(1) << 10)
+#define R3K_ENTRYLO_N          (_ULCAST_(1) << 11)
+
+/* R4000 compatible EntryLo bit definitions */
+#define MIPS_ENTRYLO_G         (_ULCAST_(1) << 0)
+#define MIPS_ENTRYLO_V         (_ULCAST_(1) << 1)
+#define MIPS_ENTRYLO_D         (_ULCAST_(1) << 2)
+#define MIPS_ENTRYLO_C_SHIFT   3
+#define MIPS_ENTRYLO_C         (_ULCAST_(7) << MIPS_ENTRYLO_C_SHIFT)
+#ifdef CONFIG_64BIT
+/* as read by dmfc0 */
+#define MIPS_ENTRYLO_XI                (_ULCAST_(1) << 62)
+#define MIPS_ENTRYLO_RI                (_ULCAST_(1) << 63)
+#else
+/* as read by mfc0 */
+#define MIPS_ENTRYLO_XI                (_ULCAST_(1) << 30)
+#define MIPS_ENTRYLO_RI                (_ULCAST_(1) << 31)
+#endif
+
 /* CMGCRBase bit definitions */
 #define MIPS_CMGCRB_BASE       11
 #define MIPS_CMGCRF_BASE       (~_ULCAST_((1 << MIPS_CMGCRB_BASE) - 1))
 #define TX39_CONF_DRSIZE_SHIFT 0
 #define TX39_CONF_DRSIZE_MASK  0x00000003
 
+/*
+ * Interesting Bits in the R10K CP0 Branch Diagnostic Register
+ */
+/* Disable Branch Target Address Cache */
+#define R10K_DIAG_D_BTAC       (_ULCAST_(1) << 27)
+/* Enable Branch Prediction Global History */
+#define R10K_DIAG_E_GHIST      (_ULCAST_(1) << 26)
+/* Disable Branch Return Cache */
+#define R10K_DIAG_D_BRC                (_ULCAST_(1) << 22)
 
 /*
  * Coprocessor 1 (FPU) register names
@@ -1247,6 +1278,10 @@ do {                                                                     \
 #define read_c0_diag()         __read_32bit_c0_register($22, 0)
 #define write_c0_diag(val)     __write_32bit_c0_register($22, 0, val)
 
+/* R10K CP0 Branch Diagnostic register is 64bits wide */
+#define read_c0_r10k_diag()    __read_64bit_c0_register($22, 0)
+#define write_c0_r10k_diag(val)        __write_64bit_c0_register($22, 0, val)
+
 #define read_c0_diag1()                __read_32bit_c0_register($22, 1)
 #define write_c0_diag1(val)    __write_32bit_c0_register($22, 1, val)
 
index 7d56686..832e216 100644 (file)
@@ -18,7 +18,7 @@
 
 #include <asm-generic/pgtable-nopmd.h>
 
-extern int temp_tlb_entry __cpuinitdata;
+extern int temp_tlb_entry;
 
 /*
  * - add_temporary_entry() add a temporary TLB entry. We use TLB entries
index 8ebc2aa..0b4b668 100644 (file)
@@ -11,7 +11,7 @@
 #ifndef __ASM_PROM_H
 #define __ASM_PROM_H
 
-#ifdef CONFIG_OF
+#ifdef CONFIG_USE_OF
 #include <linux/bug.h>
 #include <linux/io.h>
 #include <linux/types.h>
index 1fca2e0..9de4ba4 100644 (file)
@@ -109,7 +109,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock)
                "        subu   %[ticket], %[my_ticket], %[ticket]      \n"
                "2:                                                     \n"
                "       .subsection 2                                   \n"
-               "4:     andi    %[ticket], %[ticket], 0x1fff            \n"
+               "4:     andi    %[ticket], %[ticket], 0xffff            \n"
                "       sll     %[ticket], 5                            \n"
                "                                                       \n"
                "6:     bnez    %[ticket], 6b                           \n"
@@ -317,7 +317,7 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
 
 static inline void arch_write_unlock(arch_rwlock_t *rw)
 {
-       smp_mb();
+       smp_mb__before_llsc();
 
        __asm__ __volatile__(
        "                               # arch_write_unlock     \n"
index 5620879..68a6650 100644 (file)
@@ -11,7 +11,7 @@
 
 #include <irq.h>
 
-#ifdef CONFIG_IRQ_CPU
+#ifdef CONFIG_IRQ_MIPS_CPU
 #define TXX9_IRQ_BASE  (MIPS_CPU_IRQ_BASE + 8)
 #else
 #ifdef CONFIG_I8259
index 9722357..5305d69 100644 (file)
@@ -78,6 +78,21 @@ extern u64 __ua_limit;
 
 #define segment_eq(a, b)       ((a).seg == (b).seg)
 
+/*
+ * eva_kernel_access() - determine whether kernel memory access on an EVA system
+ *
+ * Determines whether memory accesses should be performed to kernel memory
+ * on a system using Extended Virtual Addressing (EVA).
+ *
+ * Return: true if a kernel memory access on an EVA system, else false.
+ */
+static inline bool eva_kernel_access(void)
+{
+       if (!config_enabled(CONFIG_EVA))
+               return false;
+
+       return segment_eq(get_fs(), get_ds());
+}
 
 /*
  * Is a address valid? This does a straighforward calculation rather
@@ -286,7 +301,7 @@ do {                                                                        \
 ({                                                                     \
        int __gu_err;                                                   \
                                                                        \
-       if (segment_eq(get_fs(), get_ds())) {                           \
+       if (eva_kernel_access()) {                                      \
                __get_kernel_common((x), size, ptr);                    \
        } else {                                                        \
                __chk_user_ptr(ptr);                                    \
@@ -302,7 +317,7 @@ do {                                                                        \
                                                                        \
        might_fault();                                                  \
        if (likely(access_ok(VERIFY_READ,  __gu_ptr, size))) {          \
-               if (segment_eq(get_fs(), get_ds()))                     \
+               if (eva_kernel_access())                                \
                        __get_kernel_common((x), size, __gu_ptr);       \
                else                                                    \
                        __get_user_common((x), size, __gu_ptr);         \
@@ -427,7 +442,7 @@ do {                                                                        \
        int __pu_err = 0;                                               \
                                                                        \
        __pu_val = (x);                                                 \
-       if (segment_eq(get_fs(), get_ds())) {                           \
+       if (eva_kernel_access()) {                                      \
                __put_kernel_common(ptr, size);                         \
        } else {                                                        \
                __chk_user_ptr(ptr);                                    \
@@ -444,7 +459,7 @@ do {                                                                        \
                                                                        \
        might_fault();                                                  \
        if (likely(access_ok(VERIFY_WRITE,  __pu_addr, size))) {        \
-               if (segment_eq(get_fs(), get_ds()))                     \
+               if (eva_kernel_access())                                \
                        __put_kernel_common(__pu_addr, size);           \
                else                                                    \
                        __put_user_common(__pu_addr, size);             \
@@ -843,7 +858,7 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
        __cu_from = (from);                                             \
        __cu_len = (n);                                                 \
        might_fault();                                                  \
-       if (segment_eq(get_fs(), get_ds()))                             \
+       if (eva_kernel_access())                                        \
                __cu_len = __invoke_copy_to_kernel(__cu_to, __cu_from,  \
                                                   __cu_len);           \
        else                                                            \
@@ -863,7 +878,7 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n);
        __cu_to = (to);                                                 \
        __cu_from = (from);                                             \
        __cu_len = (n);                                                 \
-       if (segment_eq(get_fs(), get_ds()))                             \
+       if (eva_kernel_access())                                        \
                __cu_len = __invoke_copy_to_kernel(__cu_to, __cu_from,  \
                                                   __cu_len);           \
        else                                                            \
@@ -881,7 +896,7 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n);
        __cu_to = (to);                                                 \
        __cu_from = (from);                                             \
        __cu_len = (n);                                                 \
-       if (segment_eq(get_fs(), get_ds()))                             \
+       if (eva_kernel_access())                                        \
                __cu_len = __invoke_copy_from_kernel_inatomic(__cu_to,  \
                                                              __cu_from,\
                                                              __cu_len);\
@@ -915,7 +930,7 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n);
        __cu_to = (to);                                                 \
        __cu_from = (from);                                             \
        __cu_len = (n);                                                 \
-       if (segment_eq(get_fs(), get_ds())) {                           \
+       if (eva_kernel_access()) {                                      \
                __cu_len = __invoke_copy_to_kernel(__cu_to,             \
                                                   __cu_from,           \
                                                   __cu_len);           \
@@ -1139,7 +1154,7 @@ extern size_t __copy_in_user_eva(void *__to, const void *__from, size_t __n);
        __cu_to = (to);                                                 \
        __cu_from = (from);                                             \
        __cu_len = (n);                                                 \
-       if (segment_eq(get_fs(), get_ds())) {                           \
+       if (eva_kernel_access()) {                                      \
                __cu_len = __invoke_copy_from_kernel(__cu_to,           \
                                                     __cu_from,         \
                                                     __cu_len);         \
@@ -1163,7 +1178,7 @@ extern size_t __copy_in_user_eva(void *__to, const void *__from, size_t __n);
        __cu_to = (to);                                                 \
        __cu_from = (from);                                             \
        __cu_len = (n);                                                 \
-       if (segment_eq(get_fs(), get_ds())) {                           \
+       if (eva_kernel_access()) {                                      \
                __cu_len = ___invoke_copy_in_kernel(__cu_to, __cu_from, \
                                                    __cu_len);          \
        } else {                                                        \
@@ -1183,7 +1198,7 @@ extern size_t __copy_in_user_eva(void *__to, const void *__from, size_t __n);
        __cu_to = (to);                                                 \
        __cu_from = (from);                                             \
        __cu_len = (n);                                                 \
-       if (segment_eq(get_fs(), get_ds())) {                           \
+       if (eva_kernel_access()) {                                      \
                __cu_len = ___invoke_copy_in_kernel(__cu_to,__cu_from,  \
                                                    __cu_len);          \
        } else {                                                        \
@@ -1263,7 +1278,7 @@ __strncpy_from_user(char *__to, const char __user *__from, long __len)
 {
        long res;
 
-       if (segment_eq(get_fs(), get_ds())) {
+       if (eva_kernel_access()) {
                __asm__ __volatile__(
                        "move\t$4, %1\n\t"
                        "move\t$5, %2\n\t"
@@ -1312,7 +1327,7 @@ strncpy_from_user(char *__to, const char __user *__from, long __len)
 {
        long res;
 
-       if (segment_eq(get_fs(), get_ds())) {
+       if (eva_kernel_access()) {
                __asm__ __volatile__(
                        "move\t$4, %1\n\t"
                        "move\t$5, %2\n\t"
@@ -1357,7 +1372,7 @@ static inline long strlen_user(const char __user *s)
 {
        long res;
 
-       if (segment_eq(get_fs(), get_ds())) {
+       if (eva_kernel_access()) {
                __asm__ __volatile__(
                        "move\t$4, %1\n\t"
                        __MODULE_JAL(__strlen_kernel_asm)
@@ -1384,7 +1399,7 @@ static inline long __strnlen_user(const char __user *s, long n)
 {
        long res;
 
-       if (segment_eq(get_fs(), get_ds())) {
+       if (eva_kernel_access()) {
                __asm__ __volatile__(
                        "move\t$4, %1\n\t"
                        "move\t$5, %2\n\t"
@@ -1426,7 +1441,7 @@ static inline long strnlen_user(const char __user *s, long n)
        long res;
 
        might_fault();
-       if (segment_eq(get_fs(), get_ds())) {
+       if (eva_kernel_access()) {
                __asm__ __volatile__(
                        "move\t$4, %1\n\t"
                        "move\t$5, %2\n\t"
index 32e4e88..24f121d 100644 (file)
 #define WIDGET_LLP_MAXBURST            0x000003ff
 #define WIDGET_LLP_MAXBURST_SHFT       0
 
+/* Xtalk Widget Device Mfgr Nums */
+#define WIDGET_XBOW_MFGR_NUM   0x0      /* IP30 XBow Chip */
+#define WIDGET_XXBOW_MFGR_NUM  0x0      /* IP35 Xbow + XBridge Chip */
+#define WIDGET_ODYS_MFGR_NUM   0x023    /* Odyssey / VPro GFX */
+#define WIDGET_TPU_MFGR_NUM    0x024    /* Tensor Processor Unit */
+#define WIDGET_XBRDG_MFGR_NUM  0x024    /* IP35 XBridge Chip */
+#define WIDGET_HEART_MFGR_NUM  0x036    /* IP30 HEART Chip */
+#define WIDGET_BRIDG_MFGR_NUM  0x036    /* PCI Bridge */
+#define WIDGET_HUB_MFGR_NUM    0x036    /* IP27 Hub Chip */
+#define WIDGET_BDRCK_MFGR_NUM  0x036    /* IP35 Bedrock Chip */
+#define WIDGET_IMPCT_MFGR_NUM  0x2aa    /* HQ4 / Impact GFX */
+#define WIDGET_KONA_MFGR_NUM   0x2aa    /* InfiniteReality3 / Kona GFX */
+#define WIDGET_NULL_MFGR_NUM   -1       /* NULL */
+
+/* Xtalk Widget Device Part Nums */
+#define WIDGET_XBOW_PART_NUM   0x0000
+#define WIDGET_HEART_PART_NUM  0xc001
+#define WIDGET_BRIDG_PART_NUM  0xc002
+#define WIDGET_IMPCT_PART_NUM  0xc003
+#define WIDGET_ODYS_PART_NUM   0xc013
+#define WIDGET_HUB_PART_NUM    0xc101
+#define WIDGET_KONA_PART_NUM   0xc102
+#define WIDGET_BDRCK_PART_NUM  0xc110
+#define WIDGET_TPU_PART_NUM    0xc202
+#define WIDGET_XXBOW_PART_NUM  0xd000
+#define WIDGET_XBRDG_PART_NUM  0xd002
+#define WIDGET_NULL_PART_NUM   -1
+
+/* For Xtalk Widget identification */
+struct widget_ident {
+       u32 mfgr;
+       u32 part;
+       char *name;
+       char *revs[16];
+};
+
+/* Known Xtalk Widgets */
+static const struct widget_ident __initconst widget_idents[] = {
+       {
+               WIDGET_XBOW_MFGR_NUM,
+               WIDGET_XBOW_PART_NUM,
+               "xbow",
+               {NULL, "1.0", "1.1", "1.2", "1.3", "2.0", NULL},
+       },
+       {
+               WIDGET_HEART_MFGR_NUM,
+               WIDGET_HEART_PART_NUM,
+               "heart",
+               {NULL, "A", "B", "C", "D", "E", "F", NULL},
+       },
+       {
+               WIDGET_BRIDG_MFGR_NUM,
+               WIDGET_BRIDG_PART_NUM,
+               "bridge",
+               {NULL, "A", "B", "C", "D", NULL},
+       },
+       {
+               WIDGET_IMPCT_MFGR_NUM,
+               WIDGET_IMPCT_PART_NUM,
+               "impact",
+               {NULL, "A", "B", NULL},
+       },
+       {
+               WIDGET_ODYS_MFGR_NUM,
+               WIDGET_ODYS_PART_NUM,
+               "odyssey",
+               {NULL, "A", "B", NULL},
+       },
+       {
+               WIDGET_HUB_MFGR_NUM,
+               WIDGET_HUB_PART_NUM,
+               "hub",
+               {NULL, "1.0", "2.0", "2.1", "2.2", "2.3", "2.4", NULL},
+       },
+       {
+               WIDGET_KONA_MFGR_NUM,
+               WIDGET_KONA_PART_NUM,
+               "kona",
+               {NULL},
+       },
+       {
+               WIDGET_BDRCK_MFGR_NUM,
+               WIDGET_BDRCK_PART_NUM,
+               "bedrock",
+               {NULL, "1.0", "1.1", NULL},
+       },
+       {
+               WIDGET_TPU_MFGR_NUM,
+               WIDGET_TPU_PART_NUM,
+               "tpu",
+               {"0", NULL},
+       },
+       {
+               WIDGET_XXBOW_MFGR_NUM,
+               WIDGET_XXBOW_PART_NUM,
+               "xxbow",
+               {NULL, "1.0", "2.0", NULL},
+       },
+       {
+               WIDGET_XBRDG_MFGR_NUM,
+               WIDGET_XBRDG_PART_NUM,
+               "xbridge",
+               {NULL, "A", "B", NULL},
+       },
+       {
+               WIDGET_NULL_MFGR_NUM,
+               WIDGET_NULL_PART_NUM,
+               NULL,
+               {NULL},
+       }
+};
+
 /*
  * according to the crosstalk spec, only 32-bits access to the widget
  * configuration registers is allowed. some widgets may allow 64-bits
index 4689030..36f8201 100644 (file)
@@ -1,9 +1,24 @@
 choice
        prompt "Machine type"
-       depends on MACH_JZ4740
+       depends on MACH_INGENIC
        default JZ4740_QI_LB60
 
 config JZ4740_QI_LB60
        bool "Qi Hardware Ben NanoNote"
+       select MACH_JZ4740
+
+config JZ4780_CI20
+       bool "MIPS Creator CI20"
+       select MACH_JZ4780
 
 endchoice
+
+config MACH_JZ4740
+       bool
+       select SYS_HAS_CPU_MIPS32_R1
+
+config MACH_JZ4780
+       bool
+       select MIPS_CPU_SCACHE
+       select SYS_HAS_CPU_MIPS32_R2
+       select SYS_SUPPORTS_HIGHMEM
index 28e5535..39d70bd 100644 (file)
@@ -4,10 +4,12 @@
 
 # Object file lists.
 
-obj-y += prom.o irq.o time.o reset.o setup.o \
-       gpio.o clock.o platform.o timer.o serial.o
+obj-y += prom.o time.o reset.o setup.o \
+       platform.o timer.o
 
-obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o
+obj-$(CONFIG_MACH_JZ4740) += gpio.o
+
+CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt
 
 # board specific support
 
index c41d300..28448d3 100644 (file)
@@ -1,4 +1,4 @@
-platform-$(CONFIG_MACH_JZ4740) += jz4740/
-cflags-$(CONFIG_MACH_JZ4740)   += -I$(srctree)/arch/mips/include/asm/mach-jz4740
-load-$(CONFIG_MACH_JZ4740)     += 0xffffffff80010000
-zload-$(CONFIG_MACH_JZ4740)    += 0xffffffff80600000
+platform-$(CONFIG_MACH_INGENIC)        += jz4740/
+cflags-$(CONFIG_MACH_INGENIC)  += -I$(srctree)/arch/mips/include/asm/mach-jz4740
+load-$(CONFIG_MACH_INGENIC)    += 0xffffffff80010000
+zload-$(CONFIG_MACH_INGENIC)   += 0xffffffff80600000
index 9dd051e..4e62bf8 100644 (file)
@@ -482,8 +482,6 @@ static int __init qi_lb60_init_platform_devices(void)
        gpiod_add_lookup_table(&qi_lb60_audio_gpio_table);
        gpiod_add_lookup_table(&qi_lb60_nand_gpio_table);
 
-       jz4740_serial_device_register();
-
        spi_register_board_info(qi_lb60_spi_board_info,
                                ARRAY_SIZE(qi_lb60_spi_board_info));
 
@@ -497,11 +495,6 @@ static int __init qi_lb60_init_platform_devices(void)
 
 }
 
-struct jz4740_clock_board_data jz4740_clock_bdata = {
-       .ext_rate = 12000000,
-       .rtc_rate = 32768,
-};
-
 static __init int board_avt2(char *str)
 {
        qi_lb60_mmc_pdata.card_detect_active_low = 1;
diff --git a/arch/mips/jz4740/clock-debugfs.c b/arch/mips/jz4740/clock-debugfs.c
deleted file mode 100644 (file)
index 325422d..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- *  JZ4740 SoC clock support debugfs entries
- *
- *  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.
- *
- *  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/kernel.h>
-#include <linux/module.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-
-#include <linux/debugfs.h>
-#include <linux/uaccess.h>
-
-#include <asm/mach-jz4740/clock.h>
-#include "clock.h"
-
-static struct dentry *jz4740_clock_debugfs;
-
-static int jz4740_clock_debugfs_show_enabled(void *data, uint64_t *value)
-{
-       struct clk *clk = data;
-       *value = clk_is_enabled(clk);
-
-       return 0;
-}
-
-static int jz4740_clock_debugfs_set_enabled(void *data, uint64_t value)
-{
-       struct clk *clk = data;
-
-       if (value)
-               return clk_enable(clk);
-       else
-               clk_disable(clk);
-
-       return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_enabled,
-       jz4740_clock_debugfs_show_enabled,
-       jz4740_clock_debugfs_set_enabled,
-       "%llu\n");
-
-static int jz4740_clock_debugfs_show_rate(void *data, uint64_t *value)
-{
-       struct clk *clk = data;
-       *value = clk_get_rate(clk);
-
-       return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(jz4740_clock_debugfs_ops_rate,
-       jz4740_clock_debugfs_show_rate,
-       NULL,
-       "%llu\n");
-
-void jz4740_clock_debugfs_add_clk(struct clk *clk)
-{
-       if (!jz4740_clock_debugfs)
-               return;
-
-       clk->debugfs_entry = debugfs_create_dir(clk->name, jz4740_clock_debugfs);
-       debugfs_create_file("rate", S_IWUGO | S_IRUGO, clk->debugfs_entry, clk,
-                               &jz4740_clock_debugfs_ops_rate);
-       debugfs_create_file("enabled", S_IRUGO, clk->debugfs_entry, clk,
-                               &jz4740_clock_debugfs_ops_enabled);
-
-       if (clk->parent) {
-               char parent_path[100];
-               snprintf(parent_path, 100, "../%s", clk->parent->name);
-               clk->debugfs_parent_entry = debugfs_create_symlink("parent",
-                                               clk->debugfs_entry,
-                                               parent_path);
-       }
-}
-
-/* TODO: Locking */
-void jz4740_clock_debugfs_update_parent(struct clk *clk)
-{
-       debugfs_remove(clk->debugfs_parent_entry);
-
-       if (clk->parent) {
-               char parent_path[100];
-               snprintf(parent_path, 100, "../%s", clk->parent->name);
-               clk->debugfs_parent_entry = debugfs_create_symlink("parent",
-                                               clk->debugfs_entry,
-                                               parent_path);
-       } else {
-               clk->debugfs_parent_entry = NULL;
-       }
-}
-
-void jz4740_clock_debugfs_init(void)
-{
-       jz4740_clock_debugfs = debugfs_create_dir("jz4740-clock", NULL);
-       if (IS_ERR(jz4740_clock_debugfs))
-               jz4740_clock_debugfs = NULL;
-}
diff --git a/arch/mips/jz4740/clock.c b/arch/mips/jz4740/clock.c
deleted file mode 100644 (file)
index 1b5f554..0000000
+++ /dev/null
@@ -1,924 +0,0 @@
-/*
- *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- *  JZ4740 SoC clock support
- *
- *  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.
- *
- *  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/kernel.h>
-#include <linux/errno.h>
-#include <linux/clk.h>
-#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/list.h>
-#include <linux/err.h>
-
-#include <asm/mach-jz4740/clock.h>
-#include <asm/mach-jz4740/base.h>
-
-#include "clock.h"
-
-#define JZ_REG_CLOCK_CTRL      0x00
-#define JZ_REG_CLOCK_LOW_POWER 0x04
-#define JZ_REG_CLOCK_PLL       0x10
-#define JZ_REG_CLOCK_GATE      0x20
-#define JZ_REG_CLOCK_SLEEP_CTRL 0x24
-#define JZ_REG_CLOCK_I2S       0x60
-#define JZ_REG_CLOCK_LCD       0x64
-#define JZ_REG_CLOCK_MMC       0x68
-#define JZ_REG_CLOCK_UHC       0x6C
-#define JZ_REG_CLOCK_SPI       0x74
-
-#define JZ_CLOCK_CTRL_I2S_SRC_PLL      BIT(31)
-#define JZ_CLOCK_CTRL_KO_ENABLE                BIT(30)
-#define JZ_CLOCK_CTRL_UDC_SRC_PLL      BIT(29)
-#define JZ_CLOCK_CTRL_UDIV_MASK                0x1f800000
-#define JZ_CLOCK_CTRL_CHANGE_ENABLE    BIT(22)
-#define JZ_CLOCK_CTRL_PLL_HALF         BIT(21)
-#define JZ_CLOCK_CTRL_LDIV_MASK                0x001f0000
-#define JZ_CLOCK_CTRL_UDIV_OFFSET      23
-#define JZ_CLOCK_CTRL_LDIV_OFFSET      16
-#define JZ_CLOCK_CTRL_MDIV_OFFSET      12
-#define JZ_CLOCK_CTRL_PDIV_OFFSET       8
-#define JZ_CLOCK_CTRL_HDIV_OFFSET       4
-#define JZ_CLOCK_CTRL_CDIV_OFFSET       0
-
-#define JZ_CLOCK_GATE_UART0    BIT(0)
-#define JZ_CLOCK_GATE_TCU      BIT(1)
-#define JZ_CLOCK_GATE_RTC      BIT(2)
-#define JZ_CLOCK_GATE_I2C      BIT(3)
-#define JZ_CLOCK_GATE_SPI      BIT(4)
-#define JZ_CLOCK_GATE_AIC      BIT(5)
-#define JZ_CLOCK_GATE_I2S      BIT(6)
-#define JZ_CLOCK_GATE_MMC      BIT(7)
-#define JZ_CLOCK_GATE_ADC      BIT(8)
-#define JZ_CLOCK_GATE_CIM      BIT(9)
-#define JZ_CLOCK_GATE_LCD      BIT(10)
-#define JZ_CLOCK_GATE_UDC      BIT(11)
-#define JZ_CLOCK_GATE_DMAC     BIT(12)
-#define JZ_CLOCK_GATE_IPU      BIT(13)
-#define JZ_CLOCK_GATE_UHC      BIT(14)
-#define JZ_CLOCK_GATE_UART1    BIT(15)
-
-#define JZ_CLOCK_I2S_DIV_MASK          0x01ff
-
-#define JZ_CLOCK_LCD_DIV_MASK          0x01ff
-
-#define JZ_CLOCK_MMC_DIV_MASK          0x001f
-
-#define JZ_CLOCK_UHC_DIV_MASK          0x000f
-
-#define JZ_CLOCK_SPI_SRC_PLL           BIT(31)
-#define JZ_CLOCK_SPI_DIV_MASK          0x000f
-
-#define JZ_CLOCK_PLL_M_MASK            0x01ff
-#define JZ_CLOCK_PLL_N_MASK            0x001f
-#define JZ_CLOCK_PLL_OD_MASK           0x0003
-#define JZ_CLOCK_PLL_STABLE            BIT(10)
-#define JZ_CLOCK_PLL_BYPASS            BIT(9)
-#define JZ_CLOCK_PLL_ENABLED           BIT(8)
-#define JZ_CLOCK_PLL_STABLIZE_MASK     0x000f
-#define JZ_CLOCK_PLL_M_OFFSET          23
-#define JZ_CLOCK_PLL_N_OFFSET          18
-#define JZ_CLOCK_PLL_OD_OFFSET         16
-
-#define JZ_CLOCK_LOW_POWER_MODE_DOZE BIT(2)
-#define JZ_CLOCK_LOW_POWER_MODE_SLEEP BIT(0)
-
-#define JZ_CLOCK_SLEEP_CTRL_SUSPEND_UHC BIT(7)
-#define JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC BIT(6)
-
-static void __iomem *jz_clock_base;
-static spinlock_t jz_clock_lock;
-static LIST_HEAD(jz_clocks);
-
-struct main_clk {
-       struct clk clk;
-       uint32_t div_offset;
-};
-
-struct divided_clk {
-       struct clk clk;
-       uint32_t reg;
-       uint32_t mask;
-};
-
-struct static_clk {
-       struct clk clk;
-       unsigned long rate;
-};
-
-static uint32_t jz_clk_reg_read(int reg)
-{
-       return readl(jz_clock_base + reg);
-}
-
-static void jz_clk_reg_write_mask(int reg, uint32_t val, uint32_t mask)
-{
-       uint32_t val2;
-
-       spin_lock(&jz_clock_lock);
-       val2 = readl(jz_clock_base + reg);
-       val2 &= ~mask;
-       val2 |= val;
-       writel(val2, jz_clock_base + reg);
-       spin_unlock(&jz_clock_lock);
-}
-
-static void jz_clk_reg_set_bits(int reg, uint32_t mask)
-{
-       uint32_t val;
-
-       spin_lock(&jz_clock_lock);
-       val = readl(jz_clock_base + reg);
-       val |= mask;
-       writel(val, jz_clock_base + reg);
-       spin_unlock(&jz_clock_lock);
-}
-
-static void jz_clk_reg_clear_bits(int reg, uint32_t mask)
-{
-       uint32_t val;
-
-       spin_lock(&jz_clock_lock);
-       val = readl(jz_clock_base + reg);
-       val &= ~mask;
-       writel(val, jz_clock_base + reg);
-       spin_unlock(&jz_clock_lock);
-}
-
-static int jz_clk_enable_gating(struct clk *clk)
-{
-       if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
-               return -EINVAL;
-
-       jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
-       return 0;
-}
-
-static int jz_clk_disable_gating(struct clk *clk)
-{
-       if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
-               return -EINVAL;
-
-       jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, clk->gate_bit);
-       return 0;
-}
-
-static int jz_clk_is_enabled_gating(struct clk *clk)
-{
-       if (clk->gate_bit == JZ4740_CLK_NOT_GATED)
-               return 1;
-
-       return !(jz_clk_reg_read(JZ_REG_CLOCK_GATE) & clk->gate_bit);
-}
-
-static unsigned long jz_clk_static_get_rate(struct clk *clk)
-{
-       return ((struct static_clk *)clk)->rate;
-}
-
-static int jz_clk_ko_enable(struct clk *clk)
-{
-       jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
-       return 0;
-}
-
-static int jz_clk_ko_disable(struct clk *clk)
-{
-       jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_KO_ENABLE);
-       return 0;
-}
-
-static int jz_clk_ko_is_enabled(struct clk *clk)
-{
-       return !!(jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_KO_ENABLE);
-}
-
-static const int pllno[] = {1, 2, 2, 4};
-
-static unsigned long jz_clk_pll_get_rate(struct clk *clk)
-{
-       uint32_t val;
-       int m;
-       int n;
-       int od;
-
-       val = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
-
-       if (val & JZ_CLOCK_PLL_BYPASS)
-               return clk_get_rate(clk->parent);
-
-       m = ((val >> 23) & 0x1ff) + 2;
-       n = ((val >> 18) & 0x1f) + 2;
-       od = (val >> 16) & 0x3;
-
-       return ((clk_get_rate(clk->parent) / n) * m) / pllno[od];
-}
-
-static unsigned long jz_clk_pll_half_get_rate(struct clk *clk)
-{
-       uint32_t reg;
-
-       reg = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
-       if (reg & JZ_CLOCK_CTRL_PLL_HALF)
-               return jz_clk_pll_get_rate(clk->parent);
-       return jz_clk_pll_get_rate(clk->parent) >> 1;
-}
-
-static const int jz_clk_main_divs[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32};
-
-static unsigned long jz_clk_main_round_rate(struct clk *clk, unsigned long rate)
-{
-       unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
-       int div;
-
-       div = parent_rate / rate;
-       if (div > 32)
-               return parent_rate / 32;
-       else if (div < 1)
-               return parent_rate;
-
-       div &= (0x3 << (ffs(div) - 1));
-
-       return parent_rate / div;
-}
-
-static unsigned long jz_clk_main_get_rate(struct clk *clk)
-{
-       struct main_clk *mclk = (struct main_clk *)clk;
-       uint32_t div;
-
-       div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
-
-       div >>= mclk->div_offset;
-       div &= 0xf;
-
-       if (div >= ARRAY_SIZE(jz_clk_main_divs))
-               div = ARRAY_SIZE(jz_clk_main_divs) - 1;
-
-       return jz_clk_pll_get_rate(clk->parent) / jz_clk_main_divs[div];
-}
-
-static int jz_clk_main_set_rate(struct clk *clk, unsigned long rate)
-{
-       struct main_clk *mclk = (struct main_clk *)clk;
-       int i;
-       int div;
-       unsigned long parent_rate = jz_clk_pll_get_rate(clk->parent);
-
-       rate = jz_clk_main_round_rate(clk, rate);
-
-       div = parent_rate / rate;
-
-       i = (ffs(div) - 1) << 1;
-       if (i > 0 && !(div & BIT(i-1)))
-               i -= 1;
-
-       jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, i << mclk->div_offset,
-                               0xf << mclk->div_offset);
-
-       return 0;
-}
-
-static struct clk_ops jz_clk_static_ops = {
-       .get_rate = jz_clk_static_get_rate,
-       .enable = jz_clk_enable_gating,
-       .disable = jz_clk_disable_gating,
-       .is_enabled = jz_clk_is_enabled_gating,
-};
-
-static struct static_clk jz_clk_ext = {
-       .clk = {
-               .name = "ext",
-               .gate_bit = JZ4740_CLK_NOT_GATED,
-               .ops = &jz_clk_static_ops,
-       },
-};
-
-static struct clk_ops jz_clk_pll_ops = {
-       .get_rate = jz_clk_pll_get_rate,
-};
-
-static struct clk jz_clk_pll = {
-       .name = "pll",
-       .parent = &jz_clk_ext.clk,
-       .ops = &jz_clk_pll_ops,
-};
-
-static struct clk_ops jz_clk_pll_half_ops = {
-       .get_rate = jz_clk_pll_half_get_rate,
-};
-
-static struct clk jz_clk_pll_half = {
-       .name = "pll half",
-       .parent = &jz_clk_pll,
-       .ops = &jz_clk_pll_half_ops,
-};
-
-static const struct clk_ops jz_clk_main_ops = {
-       .get_rate = jz_clk_main_get_rate,
-       .set_rate = jz_clk_main_set_rate,
-       .round_rate = jz_clk_main_round_rate,
-};
-
-static struct main_clk jz_clk_cpu = {
-       .clk = {
-               .name = "cclk",
-               .parent = &jz_clk_pll,
-               .ops = &jz_clk_main_ops,
-       },
-       .div_offset = JZ_CLOCK_CTRL_CDIV_OFFSET,
-};
-
-static struct main_clk jz_clk_memory = {
-       .clk = {
-               .name = "mclk",
-               .parent = &jz_clk_pll,
-               .ops = &jz_clk_main_ops,
-       },
-       .div_offset = JZ_CLOCK_CTRL_MDIV_OFFSET,
-};
-
-static struct main_clk jz_clk_high_speed_peripheral = {
-       .clk = {
-               .name = "hclk",
-               .parent = &jz_clk_pll,
-               .ops = &jz_clk_main_ops,
-       },
-       .div_offset = JZ_CLOCK_CTRL_HDIV_OFFSET,
-};
-
-
-static struct main_clk jz_clk_low_speed_peripheral = {
-       .clk = {
-               .name = "pclk",
-               .parent = &jz_clk_pll,
-               .ops = &jz_clk_main_ops,
-       },
-       .div_offset = JZ_CLOCK_CTRL_PDIV_OFFSET,
-};
-
-static const struct clk_ops jz_clk_ko_ops = {
-       .enable = jz_clk_ko_enable,
-       .disable = jz_clk_ko_disable,
-       .is_enabled = jz_clk_ko_is_enabled,
-};
-
-static struct clk jz_clk_ko = {
-       .name = "cko",
-       .parent = &jz_clk_memory.clk,
-       .ops = &jz_clk_ko_ops,
-};
-
-static int jz_clk_spi_set_parent(struct clk *clk, struct clk *parent)
-{
-       if (parent == &jz_clk_pll)
-               jz_clk_reg_set_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
-       else if (parent == &jz_clk_ext.clk)
-               jz_clk_reg_clear_bits(JZ_CLOCK_SPI_SRC_PLL, JZ_REG_CLOCK_SPI);
-       else
-               return -EINVAL;
-
-       clk->parent = parent;
-
-       return 0;
-}
-
-static int jz_clk_i2s_set_parent(struct clk *clk, struct clk *parent)
-{
-       if (parent == &jz_clk_pll_half)
-               jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
-       else if (parent == &jz_clk_ext.clk)
-               jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_I2S_SRC_PLL);
-       else
-               return -EINVAL;
-
-       clk->parent = parent;
-
-       return 0;
-}
-
-static int jz_clk_udc_enable(struct clk *clk)
-{
-       jz_clk_reg_set_bits(JZ_REG_CLOCK_SLEEP_CTRL,
-                       JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
-
-       return 0;
-}
-
-static int jz_clk_udc_disable(struct clk *clk)
-{
-       jz_clk_reg_clear_bits(JZ_REG_CLOCK_SLEEP_CTRL,
-                       JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
-
-       return 0;
-}
-
-static int jz_clk_udc_is_enabled(struct clk *clk)
-{
-       return !!(jz_clk_reg_read(JZ_REG_CLOCK_SLEEP_CTRL) &
-                       JZ_CLOCK_SLEEP_CTRL_ENABLE_UDC);
-}
-
-static int jz_clk_udc_set_parent(struct clk *clk, struct clk *parent)
-{
-       if (parent == &jz_clk_pll_half)
-               jz_clk_reg_set_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
-       else if (parent == &jz_clk_ext.clk)
-               jz_clk_reg_clear_bits(JZ_REG_CLOCK_CTRL, JZ_CLOCK_CTRL_UDC_SRC_PLL);
-       else
-               return -EINVAL;
-
-       clk->parent = parent;
-
-       return 0;
-}
-
-static int jz_clk_udc_set_rate(struct clk *clk, unsigned long rate)
-{
-       int div;
-
-       if (clk->parent == &jz_clk_ext.clk)
-               return -EINVAL;
-
-       div = clk_get_rate(clk->parent) / rate - 1;
-
-       if (div < 0)
-               div = 0;
-       else if (div > 63)
-               div = 63;
-
-       jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_UDIV_OFFSET,
-                               JZ_CLOCK_CTRL_UDIV_MASK);
-       return 0;
-}
-
-static unsigned long jz_clk_udc_get_rate(struct clk *clk)
-{
-       int div;
-
-       if (clk->parent == &jz_clk_ext.clk)
-               return clk_get_rate(clk->parent);
-
-       div = (jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_UDIV_MASK);
-       div >>= JZ_CLOCK_CTRL_UDIV_OFFSET;
-       div += 1;
-
-       return clk_get_rate(clk->parent) / div;
-}
-
-static unsigned long jz_clk_divided_get_rate(struct clk *clk)
-{
-       struct divided_clk *dclk = (struct divided_clk *)clk;
-       int div;
-
-       if (clk->parent == &jz_clk_ext.clk)
-               return clk_get_rate(clk->parent);
-
-       div = (jz_clk_reg_read(dclk->reg) & dclk->mask) + 1;
-
-       return clk_get_rate(clk->parent) / div;
-}
-
-static int jz_clk_divided_set_rate(struct clk *clk, unsigned long rate)
-{
-       struct divided_clk *dclk = (struct divided_clk *)clk;
-       int div;
-
-       if (clk->parent == &jz_clk_ext.clk)
-               return -EINVAL;
-
-       div = clk_get_rate(clk->parent) / rate - 1;
-
-       if (div < 0)
-               div = 0;
-       else if (div > dclk->mask)
-               div = dclk->mask;
-
-       jz_clk_reg_write_mask(dclk->reg, div, dclk->mask);
-
-       return 0;
-}
-
-static unsigned long jz_clk_ldclk_round_rate(struct clk *clk, unsigned long rate)
-{
-       int div;
-       unsigned long parent_rate = jz_clk_pll_half_get_rate(clk->parent);
-
-       if (rate > 150000000)
-               return 150000000;
-
-       div = parent_rate / rate;
-       if (div < 1)
-               div = 1;
-       else if (div > 32)
-               div = 32;
-
-       return parent_rate / div;
-}
-
-static int jz_clk_ldclk_set_rate(struct clk *clk, unsigned long rate)
-{
-       int div;
-
-       if (rate > 150000000)
-               return -EINVAL;
-
-       div = jz_clk_pll_half_get_rate(clk->parent) / rate - 1;
-       if (div < 0)
-               div = 0;
-       else if (div > 31)
-               div = 31;
-
-       jz_clk_reg_write_mask(JZ_REG_CLOCK_CTRL, div << JZ_CLOCK_CTRL_LDIV_OFFSET,
-                               JZ_CLOCK_CTRL_LDIV_MASK);
-
-       return 0;
-}
-
-static unsigned long jz_clk_ldclk_get_rate(struct clk *clk)
-{
-       int div;
-
-       div = jz_clk_reg_read(JZ_REG_CLOCK_CTRL) & JZ_CLOCK_CTRL_LDIV_MASK;
-       div >>= JZ_CLOCK_CTRL_LDIV_OFFSET;
-
-       return jz_clk_pll_half_get_rate(clk->parent) / (div + 1);
-}
-
-static const struct clk_ops jz_clk_ops_ld = {
-       .set_rate = jz_clk_ldclk_set_rate,
-       .get_rate = jz_clk_ldclk_get_rate,
-       .round_rate = jz_clk_ldclk_round_rate,
-       .enable = jz_clk_enable_gating,
-       .disable = jz_clk_disable_gating,
-       .is_enabled = jz_clk_is_enabled_gating,
-};
-
-static struct clk jz_clk_ld = {
-       .name = "lcd",
-       .gate_bit = JZ_CLOCK_GATE_LCD,
-       .parent = &jz_clk_pll_half,
-       .ops = &jz_clk_ops_ld,
-};
-
-static const struct clk_ops jz_clk_i2s_ops = {
-       .set_rate = jz_clk_divided_set_rate,
-       .get_rate = jz_clk_divided_get_rate,
-       .enable = jz_clk_enable_gating,
-       .disable = jz_clk_disable_gating,
-       .is_enabled = jz_clk_is_enabled_gating,
-       .set_parent = jz_clk_i2s_set_parent,
-};
-
-static const struct clk_ops jz_clk_spi_ops = {
-       .set_rate = jz_clk_divided_set_rate,
-       .get_rate = jz_clk_divided_get_rate,
-       .enable = jz_clk_enable_gating,
-       .disable = jz_clk_disable_gating,
-       .is_enabled = jz_clk_is_enabled_gating,
-       .set_parent = jz_clk_spi_set_parent,
-};
-
-static const struct clk_ops jz_clk_divided_ops = {
-       .set_rate = jz_clk_divided_set_rate,
-       .get_rate = jz_clk_divided_get_rate,
-       .enable = jz_clk_enable_gating,
-       .disable = jz_clk_disable_gating,
-       .is_enabled = jz_clk_is_enabled_gating,
-};
-
-static struct divided_clk jz4740_clock_divided_clks[] = {
-       [0] = {
-               .clk = {
-                       .name = "i2s",
-                       .parent = &jz_clk_ext.clk,
-                       .gate_bit = JZ_CLOCK_GATE_I2S,
-                       .ops = &jz_clk_i2s_ops,
-               },
-               .reg = JZ_REG_CLOCK_I2S,
-               .mask = JZ_CLOCK_I2S_DIV_MASK,
-       },
-       [1] = {
-               .clk = {
-                       .name = "spi",
-                       .parent = &jz_clk_ext.clk,
-                       .gate_bit = JZ_CLOCK_GATE_SPI,
-                       .ops = &jz_clk_spi_ops,
-               },
-               .reg = JZ_REG_CLOCK_SPI,
-               .mask = JZ_CLOCK_SPI_DIV_MASK,
-       },
-       [2] = {
-               .clk = {
-                       .name = "lcd_pclk",
-                       .parent = &jz_clk_pll_half,
-                       .gate_bit = JZ4740_CLK_NOT_GATED,
-                       .ops = &jz_clk_divided_ops,
-               },
-               .reg = JZ_REG_CLOCK_LCD,
-               .mask = JZ_CLOCK_LCD_DIV_MASK,
-       },
-       [3] = {
-               .clk = {
-                       .name = "mmc",
-                       .parent = &jz_clk_pll_half,
-                       .gate_bit = JZ_CLOCK_GATE_MMC,
-                       .ops = &jz_clk_divided_ops,
-               },
-               .reg = JZ_REG_CLOCK_MMC,
-               .mask = JZ_CLOCK_MMC_DIV_MASK,
-       },
-       [4] = {
-               .clk = {
-                       .name = "uhc",
-                       .parent = &jz_clk_pll_half,
-                       .gate_bit = JZ_CLOCK_GATE_UHC,
-                       .ops = &jz_clk_divided_ops,
-               },
-               .reg = JZ_REG_CLOCK_UHC,
-               .mask = JZ_CLOCK_UHC_DIV_MASK,
-       },
-};
-
-static const struct clk_ops jz_clk_udc_ops = {
-       .set_parent = jz_clk_udc_set_parent,
-       .set_rate = jz_clk_udc_set_rate,
-       .get_rate = jz_clk_udc_get_rate,
-       .enable = jz_clk_udc_enable,
-       .disable = jz_clk_udc_disable,
-       .is_enabled = jz_clk_udc_is_enabled,
-};
-
-static const struct clk_ops jz_clk_simple_ops = {
-       .enable = jz_clk_enable_gating,
-       .disable = jz_clk_disable_gating,
-       .is_enabled = jz_clk_is_enabled_gating,
-};
-
-static struct clk jz4740_clock_simple_clks[] = {
-       [0] = {
-               .name = "udc",
-               .parent = &jz_clk_ext.clk,
-               .ops = &jz_clk_udc_ops,
-       },
-       [1] = {
-               .name = "uart0",
-               .parent = &jz_clk_ext.clk,
-               .gate_bit = JZ_CLOCK_GATE_UART0,
-               .ops = &jz_clk_simple_ops,
-       },
-       [2] = {
-               .name = "uart1",
-               .parent = &jz_clk_ext.clk,
-               .gate_bit = JZ_CLOCK_GATE_UART1,
-               .ops = &jz_clk_simple_ops,
-       },
-       [3] = {
-               .name = "dma",
-               .parent = &jz_clk_high_speed_peripheral.clk,
-               .gate_bit = JZ_CLOCK_GATE_DMAC,
-               .ops = &jz_clk_simple_ops,
-       },
-       [4] = {
-               .name = "ipu",
-               .parent = &jz_clk_high_speed_peripheral.clk,
-               .gate_bit = JZ_CLOCK_GATE_IPU,
-               .ops = &jz_clk_simple_ops,
-       },
-       [5] = {
-               .name = "adc",
-               .parent = &jz_clk_ext.clk,
-               .gate_bit = JZ_CLOCK_GATE_ADC,
-               .ops = &jz_clk_simple_ops,
-       },
-       [6] = {
-               .name = "i2c",
-               .parent = &jz_clk_ext.clk,
-               .gate_bit = JZ_CLOCK_GATE_I2C,
-               .ops = &jz_clk_simple_ops,
-       },
-       [7] = {
-               .name = "aic",
-               .parent = &jz_clk_ext.clk,
-               .gate_bit = JZ_CLOCK_GATE_AIC,
-               .ops = &jz_clk_simple_ops,
-       },
-};
-
-static struct static_clk jz_clk_rtc = {
-       .clk = {
-               .name = "rtc",
-               .gate_bit = JZ_CLOCK_GATE_RTC,
-               .ops = &jz_clk_static_ops,
-       },
-       .rate = 32768,
-};
-
-int clk_enable(struct clk *clk)
-{
-       if (!clk->ops->enable)
-               return -EINVAL;
-
-       return clk->ops->enable(clk);
-}
-EXPORT_SYMBOL_GPL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
-       if (clk->ops->disable)
-               clk->ops->disable(clk);
-}
-EXPORT_SYMBOL_GPL(clk_disable);
-
-int clk_is_enabled(struct clk *clk)
-{
-       if (clk->ops->is_enabled)
-               return clk->ops->is_enabled(clk);
-
-       return 1;
-}
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-       if (clk->ops->get_rate)
-               return clk->ops->get_rate(clk);
-       if (clk->parent)
-               return clk_get_rate(clk->parent);
-
-       return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(clk_get_rate);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-       if (!clk->ops->set_rate)
-               return -EINVAL;
-       return clk->ops->set_rate(clk, rate);
-}
-EXPORT_SYMBOL_GPL(clk_set_rate);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-       if (clk->ops->round_rate)
-               return clk->ops->round_rate(clk, rate);
-
-       return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(clk_round_rate);
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
-       int ret;
-       int enabled;
-
-       if (!clk->ops->set_parent)
-               return -EINVAL;
-
-       enabled = clk_is_enabled(clk);
-       if (enabled)
-               clk_disable(clk);
-       ret = clk->ops->set_parent(clk, parent);
-       if (enabled)
-               clk_enable(clk);
-
-       jz4740_clock_debugfs_update_parent(clk);
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(clk_set_parent);
-
-struct clk *clk_get(struct device *dev, const char *name)
-{
-       struct clk *clk;
-
-       list_for_each_entry(clk, &jz_clocks, list) {
-               if (strcmp(clk->name, name) == 0)
-                       return clk;
-       }
-       return ERR_PTR(-ENXIO);
-}
-EXPORT_SYMBOL_GPL(clk_get);
-
-void clk_put(struct clk *clk)
-{
-}
-EXPORT_SYMBOL_GPL(clk_put);
-
-static inline void clk_add(struct clk *clk)
-{
-       list_add_tail(&clk->list, &jz_clocks);
-
-       jz4740_clock_debugfs_add_clk(clk);
-}
-
-static void clk_register_clks(void)
-{
-       size_t i;
-
-       clk_add(&jz_clk_ext.clk);
-       clk_add(&jz_clk_pll);
-       clk_add(&jz_clk_pll_half);
-       clk_add(&jz_clk_cpu.clk);
-       clk_add(&jz_clk_high_speed_peripheral.clk);
-       clk_add(&jz_clk_low_speed_peripheral.clk);
-       clk_add(&jz_clk_ko);
-       clk_add(&jz_clk_ld);
-       clk_add(&jz_clk_rtc.clk);
-
-       for (i = 0; i < ARRAY_SIZE(jz4740_clock_divided_clks); ++i)
-               clk_add(&jz4740_clock_divided_clks[i].clk);
-
-       for (i = 0; i < ARRAY_SIZE(jz4740_clock_simple_clks); ++i)
-               clk_add(&jz4740_clock_simple_clks[i]);
-}
-
-void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
-{
-       switch (mode) {
-       case JZ4740_WAIT_MODE_IDLE:
-               jz_clk_reg_clear_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
-               break;
-       case JZ4740_WAIT_MODE_SLEEP:
-               jz_clk_reg_set_bits(JZ_REG_CLOCK_LOW_POWER, JZ_CLOCK_LOW_POWER_MODE_SLEEP);
-               break;
-       }
-}
-
-void jz4740_clock_udc_disable_auto_suspend(void)
-{
-       jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
-}
-EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend);
-
-void jz4740_clock_udc_enable_auto_suspend(void)
-{
-       jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE, JZ_CLOCK_GATE_UDC);
-}
-EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend);
-
-void jz4740_clock_suspend(void)
-{
-       jz_clk_reg_set_bits(JZ_REG_CLOCK_GATE,
-               JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
-
-       jz_clk_reg_clear_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
-}
-
-void jz4740_clock_resume(void)
-{
-       uint32_t pll;
-
-       jz_clk_reg_set_bits(JZ_REG_CLOCK_PLL, JZ_CLOCK_PLL_ENABLED);
-
-       do {
-               pll = jz_clk_reg_read(JZ_REG_CLOCK_PLL);
-       } while (!(pll & JZ_CLOCK_PLL_STABLE));
-
-       jz_clk_reg_clear_bits(JZ_REG_CLOCK_GATE,
-               JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0);
-}
-
-static int jz4740_clock_init(void)
-{
-       uint32_t val;
-
-       jz_clock_base = ioremap(JZ4740_CPM_BASE_ADDR, 0x100);
-       if (!jz_clock_base)
-               return -EBUSY;
-
-       spin_lock_init(&jz_clock_lock);
-
-       jz_clk_ext.rate = jz4740_clock_bdata.ext_rate;
-       jz_clk_rtc.rate = jz4740_clock_bdata.rtc_rate;
-
-       val = jz_clk_reg_read(JZ_REG_CLOCK_SPI);
-
-       if (val & JZ_CLOCK_SPI_SRC_PLL)
-               jz4740_clock_divided_clks[1].clk.parent = &jz_clk_pll_half;
-
-       val = jz_clk_reg_read(JZ_REG_CLOCK_CTRL);
-
-       if (val & JZ_CLOCK_CTRL_I2S_SRC_PLL)
-               jz4740_clock_divided_clks[0].clk.parent = &jz_clk_pll_half;
-
-       if (val & JZ_CLOCK_CTRL_UDC_SRC_PLL)
-               jz4740_clock_simple_clks[0].parent = &jz_clk_pll_half;
-
-       jz4740_clock_debugfs_init();
-
-       clk_register_clks();
-
-       return 0;
-}
-arch_initcall(jz4740_clock_init);
diff --git a/arch/mips/jz4740/clock.h b/arch/mips/jz4740/clock.h
deleted file mode 100644 (file)
index 5d07499..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- *  JZ4740 SoC clock support
- *
- *  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.
- *
- *  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.
- *
- */
-
-#ifndef __MIPS_JZ4740_CLOCK_H__
-#define __MIPS_JZ4740_CLOCK_H__
-
-#include <linux/list.h>
-
-struct jz4740_clock_board_data {
-       unsigned long ext_rate;
-       unsigned long rtc_rate;
-};
-
-extern struct jz4740_clock_board_data jz4740_clock_bdata;
-
-void jz4740_clock_suspend(void);
-void jz4740_clock_resume(void);
-
-struct clk;
-
-struct clk_ops {
-       unsigned long (*get_rate)(struct clk *clk);
-       unsigned long (*round_rate)(struct clk *clk, unsigned long rate);
-       int (*set_rate)(struct clk *clk, unsigned long rate);
-       int (*enable)(struct clk *clk);
-       int (*disable)(struct clk *clk);
-       int (*is_enabled)(struct clk *clk);
-
-       int (*set_parent)(struct clk *clk, struct clk *parent);
-
-};
-
-struct clk {
-       const char *name;
-       struct clk *parent;
-
-       uint32_t gate_bit;
-
-       const struct clk_ops *ops;
-
-       struct list_head list;
-
-#ifdef CONFIG_DEBUG_FS
-       struct dentry *debugfs_entry;
-       struct dentry *debugfs_parent_entry;
-#endif
-
-};
-
-#define JZ4740_CLK_NOT_GATED ((uint32_t)-1)
-
-int clk_is_enabled(struct clk *clk);
-
-#ifdef CONFIG_DEBUG_FS
-void jz4740_clock_debugfs_init(void);
-void jz4740_clock_debugfs_add_clk(struct clk *clk);
-void jz4740_clock_debugfs_update_parent(struct clk *clk);
-#else
-static inline void jz4740_clock_debugfs_init(void) {};
-static inline void jz4740_clock_debugfs_add_clk(struct clk *clk) {};
-static inline void jz4740_clock_debugfs_update_parent(struct clk *clk) {};
-#endif
-
-#endif
index 00b798d..54c80d4 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/irqchip/ingenic.h>
 #include <linux/bitops.h>
 
 #include <linux/debugfs.h>
@@ -28,8 +29,6 @@
 
 #include <asm/mach-jz4740/base.h>
 
-#include "irq.h"
-
 #define JZ4740_GPIO_BASE_A (32*0)
 #define JZ4740_GPIO_BASE_B (32*1)
 #define JZ4740_GPIO_BASE_C (32*2)
@@ -442,8 +441,8 @@ static void jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
        ct->chip.irq_mask = irq_gc_mask_disable_reg;
        ct->chip.irq_unmask = jz_gpio_irq_unmask;
        ct->chip.irq_ack = irq_gc_ack_set_bit;
-       ct->chip.irq_suspend = jz4740_irq_suspend;
-       ct->chip.irq_resume = jz4740_irq_resume;
+       ct->chip.irq_suspend = ingenic_intc_irq_suspend;
+       ct->chip.irq_resume = ingenic_intc_irq_resume;
        ct->chip.irq_startup = jz_gpio_irq_startup;
        ct->chip.irq_shutdown = jz_gpio_irq_shutdown;
        ct->chip.irq_set_type = jz_gpio_irq_set_type;
diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
deleted file mode 100644 (file)
index 97206b3..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
- *  JZ4740 platform IRQ support
- *
- *  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.
- *
- *  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/errno.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/timex.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-
-#include <asm/io.h>
-#include <asm/mipsregs.h>
-#include <asm/irq_cpu.h>
-
-#include <asm/mach-jz4740/base.h>
-#include <asm/mach-jz4740/irq.h>
-
-#include "irq.h"
-
-static void __iomem *jz_intc_base;
-
-#define JZ_REG_INTC_STATUS     0x00
-#define JZ_REG_INTC_MASK       0x04
-#define JZ_REG_INTC_SET_MASK   0x08
-#define JZ_REG_INTC_CLEAR_MASK 0x0c
-#define JZ_REG_INTC_PENDING    0x10
-
-static irqreturn_t jz4740_cascade(int irq, void *data)
-{
-       uint32_t irq_reg;
-
-       irq_reg = readl(jz_intc_base + JZ_REG_INTC_PENDING);
-
-       if (irq_reg)
-               generic_handle_irq(__fls(irq_reg) + JZ4740_IRQ_BASE);
-
-       return IRQ_HANDLED;
-}
-
-static void jz4740_irq_set_mask(struct irq_chip_generic *gc, uint32_t mask)
-{
-       struct irq_chip_regs *regs = &gc->chip_types->regs;
-
-       writel(mask, gc->reg_base + regs->enable);
-       writel(~mask, gc->reg_base + regs->disable);
-}
-
-void jz4740_irq_suspend(struct irq_data *data)
-{
-       struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
-       jz4740_irq_set_mask(gc, gc->wake_active);
-}
-
-void jz4740_irq_resume(struct irq_data *data)
-{
-       struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
-       jz4740_irq_set_mask(gc, gc->mask_cache);
-}
-
-static struct irqaction jz4740_cascade_action = {
-       .handler = jz4740_cascade,
-       .name = "JZ4740 cascade interrupt",
-};
-
-void __init arch_init_irq(void)
-{
-       struct irq_chip_generic *gc;
-       struct irq_chip_type *ct;
-
-       mips_cpu_irq_init();
-
-       jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14);
-
-       /* Mask all irqs */
-       writel(0xffffffff, jz_intc_base + JZ_REG_INTC_SET_MASK);
-
-       gc = irq_alloc_generic_chip("INTC", 1, JZ4740_IRQ_BASE, jz_intc_base,
-               handle_level_irq);
-
-       gc->wake_enabled = IRQ_MSK(32);
-
-       ct = gc->chip_types;
-       ct->regs.enable = JZ_REG_INTC_CLEAR_MASK;
-       ct->regs.disable = JZ_REG_INTC_SET_MASK;
-       ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
-       ct->chip.irq_mask = irq_gc_mask_disable_reg;
-       ct->chip.irq_mask_ack = irq_gc_mask_disable_reg;
-       ct->chip.irq_set_wake = irq_gc_set_wake;
-       ct->chip.irq_suspend = jz4740_irq_suspend;
-       ct->chip.irq_resume = jz4740_irq_resume;
-
-       irq_setup_generic_chip(gc, IRQ_MSK(32), 0, 0, IRQ_NOPROBE | IRQ_LEVEL);
-
-       setup_irq(2, &jz4740_cascade_action);
-}
-
-asmlinkage void plat_irq_dispatch(void)
-{
-       unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
-       if (pending & STATUSF_IP2)
-               do_IRQ(2);
-       else if (pending & STATUSF_IP3)
-               do_IRQ(3);
-       else
-               spurious_interrupt();
-}
-
-#ifdef CONFIG_DEBUG_FS
-
-static inline void intc_seq_reg(struct seq_file *s, const char *name,
-       unsigned int reg)
-{
-       seq_printf(s, "%s:\t\t%08x\n", name, readl(jz_intc_base + reg));
-}
-
-static int intc_regs_show(struct seq_file *s, void *unused)
-{
-       intc_seq_reg(s, "Status", JZ_REG_INTC_STATUS);
-       intc_seq_reg(s, "Mask", JZ_REG_INTC_MASK);
-       intc_seq_reg(s, "Pending", JZ_REG_INTC_PENDING);
-
-       return 0;
-}
-
-static int intc_regs_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, intc_regs_show, NULL);
-}
-
-static const struct file_operations intc_regs_operations = {
-       .open           = intc_regs_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
-
-static int __init intc_debugfs_init(void)
-{
-       (void) debugfs_create_file("jz_regs_intc", S_IFREG | S_IRUGO,
-                               NULL, NULL, &intc_regs_operations);
-       return 0;
-}
-subsys_initcall(intc_debugfs_init);
-
-#endif
index 0b12f27..e8a463b 100644 (file)
@@ -13,6 +13,7 @@
  *
  */
 
+#include <linux/clk.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
@@ -29,7 +30,6 @@
 #include <linux/serial_core.h>
 #include <linux/serial_8250.h>
 
-#include "serial.h"
 #include "clock.h"
 
 /* OHCI controller */
@@ -279,42 +279,6 @@ struct platform_device jz4740_adc_device = {
        .resource       = jz4740_adc_resources,
 };
 
-/* Serial */
-#define JZ4740_UART_DATA(_id) \
-       { \
-               .flags = UPF_SKIP_TEST | UPF_IOREMAP | UPF_FIXED_TYPE, \
-               .iotype = UPIO_MEM, \
-               .regshift = 2, \
-               .serial_out = jz4740_serial_out, \
-               .type = PORT_16550, \
-               .mapbase = JZ4740_UART ## _id ## _BASE_ADDR, \
-               .irq = JZ4740_IRQ_UART ## _id, \
-       }
-
-static struct plat_serial8250_port jz4740_uart_data[] = {
-       JZ4740_UART_DATA(0),
-       JZ4740_UART_DATA(1),
-       {},
-};
-
-static struct platform_device jz4740_uart_device = {
-       .name = "serial8250",
-       .id = 0,
-       .dev = {
-               .platform_data = jz4740_uart_data,
-       },
-};
-
-void jz4740_serial_device_register(void)
-{
-       struct plat_serial8250_port *p;
-
-       for (p = jz4740_uart_data; p->flags != 0; ++p)
-               p->uartclk = jz4740_clock_bdata.ext_rate;
-
-       platform_device_register(&jz4740_uart_device);
-}
-
 /* Watchdog */
 static struct resource jz4740_wdt_resources[] = {
        {
index d8e2130..2d8653f 100644 (file)
@@ -20,8 +20,6 @@
 
 #include <asm/mach-jz4740/clock.h>
 
-#include "clock.h"
-
 static int jz4740_pm_enter(suspend_state_t state)
 {
        jz4740_clock_suspend();
index 5a93f38..6984683 100644 (file)
@@ -53,16 +53,3 @@ void __init prom_init(void)
 void __init prom_free_prom_memory(void)
 {
 }
-
-#define UART_REG(_reg) ((void __iomem *)CKSEG1ADDR(JZ4740_UART0_BASE_ADDR + (_reg << 2)))
-
-void prom_putchar(char c)
-{
-       uint8_t lsr;
-
-       do {
-               lsr = readb(UART_REG(UART_LSR));
-       } while ((lsr & UART_LSR_TEMT) == 0);
-
-       writeb(c, UART_REG(UART_TX));
-}
index b6c6343..954e669 100644 (file)
@@ -12,6 +12,7 @@
  *
  */
 
+#include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/pm.h>
@@ -79,12 +80,20 @@ static void jz4740_power_off(void)
        void __iomem *rtc_base = ioremap(JZ4740_RTC_BASE_ADDR, 0x38);
        unsigned long wakeup_filter_ticks;
        unsigned long reset_counter_ticks;
+       struct clk *rtc_clk;
+       unsigned long rtc_rate;
+
+       rtc_clk = clk_get(NULL, "rtc");
+       if (IS_ERR(rtc_clk))
+               panic("unable to get RTC clock");
+       rtc_rate = clk_get_rate(rtc_clk);
+       clk_put(rtc_clk);
 
        /*
         * Set minimum wakeup pin assertion time: 100 ms.
         * Range is 0 to 2 sec if RTC is clocked at 32 kHz.
         */
-       wakeup_filter_ticks = (100 * jz4740_clock_bdata.rtc_rate) / 1000;
+       wakeup_filter_ticks = (100 * rtc_rate) / 1000;
        if (wakeup_filter_ticks < JZ_RTC_WAKEUP_FILTER_MASK)
                wakeup_filter_ticks &= JZ_RTC_WAKEUP_FILTER_MASK;
        else
@@ -96,7 +105,7 @@ static void jz4740_power_off(void)
         * Set reset pin low-level assertion time after wakeup: 60 ms.
         * Range is 0 to 125 ms if RTC is clocked at 32 kHz.
         */
-       reset_counter_ticks = (60 * jz4740_clock_bdata.rtc_rate) / 1000;
+       reset_counter_ticks = (60 * rtc_rate) / 1000;
        if (reset_counter_ticks < JZ_RTC_RESET_COUNTER_MASK)
                reset_counter_ticks &= JZ_RTC_RESET_COUNTER_MASK;
        else
diff --git a/arch/mips/jz4740/serial.c b/arch/mips/jz4740/serial.c
deleted file mode 100644 (file)
index d23de45..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- *  JZ4740 serial support
- *
- *  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.
- *
- *  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/io.h>
-#include <linux/serial_core.h>
-#include <linux/serial_reg.h>
-
-void jz4740_serial_out(struct uart_port *p, int offset, int value)
-{
-       switch (offset) {
-       case UART_FCR:
-               value |= 0x10; /* Enable uart module */
-               break;
-       case UART_IER:
-               value |= (value & 0x4) << 2;
-               break;
-       default:
-               break;
-       }
-       writeb(value, p->membase + (offset << p->regshift));
-}
diff --git a/arch/mips/jz4740/serial.h b/arch/mips/jz4740/serial.h
deleted file mode 100644 (file)
index 8eb715b..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- *  Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
- *  JZ4740 serial support
- *
- *  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.
- *
- *  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.
- *
- */
-
-#ifndef __MIPS_JZ4740_SERIAL_H__
-#define __MIPS_JZ4740_SERIAL_H__
-
-struct uart_port;
-
-void jz4740_serial_out(struct uart_port *p, int offset, int value);
-
-#endif
index ef796f9..510fc0d 100644 (file)
 
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/irqchip.h>
 #include <linux/kernel.h>
+#include <linux/libfdt.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
 
 #include <asm/bootinfo.h>
+#include <asm/prom.h>
 
 #include <asm/mach-jz4740/base.h>
 
@@ -51,11 +56,40 @@ static void __init jz4740_detect_mem(void)
 
 void __init plat_mem_setup(void)
 {
+       int offset;
+
        jz4740_reset_init();
-       jz4740_detect_mem();
+       __dt_setup_arch(__dtb_start);
+
+       offset = fdt_path_offset(__dtb_start, "/memory");
+       if (offset < 0)
+               jz4740_detect_mem();
 }
 
+void __init device_tree_init(void)
+{
+       if (!initial_boot_params)
+               return;
+
+       unflatten_and_copy_device_tree();
+}
+
+static int __init populate_machine(void)
+{
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+       return 0;
+}
+arch_initcall(populate_machine);
+
 const char *get_system_type(void)
 {
+       if (config_enabled(CONFIG_MACH_JZ4780))
+               return "JZ4780";
+
        return "JZ4740";
 }
+
+void __init arch_init_irq(void)
+{
+       irqchip_init();
+}
index 72b0cec..7ab47fe 100644 (file)
@@ -13,6 +13,8 @@
  *
  */
 
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/time.h>
@@ -20,6 +22,7 @@
 #include <linux/clockchips.h>
 #include <linux/sched_clock.h>
 
+#include <asm/mach-jz4740/clock.h>
 #include <asm/mach-jz4740/irq.h>
 #include <asm/mach-jz4740/timer.h>
 #include <asm/time.h>
@@ -99,7 +102,12 @@ static struct clock_event_device jz4740_clockevent = {
        .set_next_event = jz4740_clockevent_set_next,
        .set_mode = jz4740_clockevent_set_mode,
        .rating = 200,
+#ifdef CONFIG_MACH_JZ4740
        .irq = JZ4740_IRQ_TCU0,
+#endif
+#ifdef CONFIG_MACH_JZ4780
+       .irq = JZ4780_IRQ_TCU2,
+#endif
 };
 
 static struct irqaction timer_irqaction = {
@@ -114,10 +122,17 @@ void __init plat_time_init(void)
        int ret;
        uint32_t clk_rate;
        uint16_t ctrl;
+       struct clk *ext_clk;
 
+       of_clk_init(NULL);
        jz4740_timer_init();
 
-       clk_rate = jz4740_clock_bdata.ext_rate >> 4;
+       ext_clk = clk_get(NULL, "ext");
+       if (IS_ERR(ext_clk))
+               panic("unable to get ext clock");
+       clk_rate = clk_get_rate(ext_clk) >> 4;
+       clk_put(ext_clk);
+
        jz4740_jiffies_per_tick = DIV_ROUND_CLOSEST(clk_rate, HZ);
 
        clockevent_set_clock(&jz4740_clockevent, clk_rate);
@@ -134,7 +149,7 @@ void __init plat_time_init(void)
 
        sched_clock_register(jz4740_read_sched_clock, 16, clk_rate);
 
-       setup_irq(JZ4740_IRQ_TCU0, &timer_irqaction);
+       setup_irq(jz4740_clockevent.irq, &timer_irqaction);
 
        ctrl = JZ_TIMER_CTRL_PRESCALE_16 | JZ_TIMER_CTRL_SRC_EXT;
 
index d3d2ff2..3f5cf8a 100644 (file)
@@ -62,7 +62,6 @@ obj-$(CONFIG_MIPS_VPE_APSP_API_CMP) += rtlx-cmp.o
 obj-$(CONFIG_MIPS_VPE_APSP_API_MT) += rtlx-mt.o
 
 obj-$(CONFIG_I8259)            += i8259.o
-obj-$(CONFIG_IRQ_CPU)          += irq_cpu.o
 obj-$(CONFIG_IRQ_CPU_RM7K)     += irq-rm7000.o
 obj-$(CONFIG_MIPS_MSC)         += irq-msc01.o
 obj-$(CONFIG_IRQ_TXX9)         += irq_txx9.o
@@ -77,6 +76,7 @@ obj-$(CONFIG_MIPS32_O32)      += binfmt_elfo32.o scall64-o32.o
 
 obj-$(CONFIG_KGDB)             += kgdb.o
 obj-$(CONFIG_PROC_FS)          += proc.o
+obj-$(CONFIG_MAGIC_SYSRQ)      += sysrq.o
 
 obj-$(CONFIG_64BIT)            += cpu-bugs64.o
 
index 209e5b7..dbe0792 100644 (file)
@@ -945,7 +945,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
                c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
                             MIPS_CPU_FPU | MIPS_CPU_32FPR |
                             MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
-                            MIPS_CPU_LLSC;
+                            MIPS_CPU_LLSC | MIPS_CPU_BP_GHIST;
                c->tlbsize = 64;
                break;
        case PRID_IMP_R14000:
@@ -960,7 +960,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
                c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
                             MIPS_CPU_FPU | MIPS_CPU_32FPR |
                             MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
-                            MIPS_CPU_LLSC;
+                            MIPS_CPU_LLSC | MIPS_CPU_BP_GHIST;
                c->tlbsize = 64;
                break;
        case PRID_IMP_LOONGSON_64:  /* Loongson-2/3 */
@@ -1443,7 +1443,9 @@ void cpu_probe(void)
        case PRID_COMP_CAVIUM:
                cpu_probe_cavium(c, cpu);
                break;
-       case PRID_COMP_INGENIC:
+       case PRID_COMP_INGENIC_D0:
+       case PRID_COMP_INGENIC_D1:
+       case PRID_COMP_INGENIC_E1:
                cpu_probe_ingenic(c, cpu);
                break;
        case PRID_COMP_NETLOGIC:
@@ -1478,6 +1480,10 @@ void cpu_probe(void)
        else
                cpu_set_nofpu_opts(c);
 
+       if (cpu_has_bp_ghist)
+               write_c0_r10k_diag(read_c0_r10k_diag() |
+                                  R10K_DIAG_E_GHIST);
+
        if (cpu_has_mips_r2_r6) {
                c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
                /* R2 has Performance Counter Interrupt indicator */
index 95afd66..4e4cc5b 100644 (file)
@@ -94,6 +94,22 @@ NESTED(kernel_entry, 16, sp)                 # kernel entry point
        jr      t0
 0:
 
+#ifdef CONFIG_MIPS_RAW_APPENDED_DTB
+       PTR_LA          t0, __appended_dtb
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+       li              t1, 0xd00dfeed
+#else
+       li              t1, 0xedfe0dd0
+#endif
+       lw              t2, (t0)
+       bne             t1, t2, not_found
+        nop
+
+       move            a1, t0
+       PTR_LI          a0, -2
+not_found:
+#endif
        PTR_LA          t0, __bss_start         # clear .bss
        LONG_S          zero, (t0)
        PTR_LA          t1, __bss_stop - LONGSIZE
index a74ec3a..74f6752 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/interrupt.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
+#include <linux/of_irq.h>
 #include <linux/spinlock.h>
 #include <linux/syscore_ops.h>
 #include <linux/irq.h>
@@ -21,6 +22,8 @@
 #include <asm/i8259.h>
 #include <asm/io.h>
 
+#include "../../drivers/irqchip/irqchip.h"
+
 /*
  * This is the 'legacy' 8259A Programmable Interrupt Controller,
  * present in the majority of PC/AT boxes.
@@ -327,7 +330,7 @@ static struct irq_domain_ops i8259A_ops = {
  * driver compatibility reasons interrupts 0 - 15 to be the i8259
  * interrupts even if the hardware uses a different interrupt numbering.
  */
-void __init init_i8259_irqs(void)
+struct irq_domain * __init __init_i8259_irqs(struct device_node *node)
 {
        struct irq_domain *domain;
 
@@ -336,10 +339,46 @@ void __init init_i8259_irqs(void)
 
        init_8259A(0);
 
-       domain = irq_domain_add_legacy(NULL, 16, I8259A_IRQ_BASE, 0,
+       domain = irq_domain_add_legacy(node, 16, I8259A_IRQ_BASE, 0,
                                       &i8259A_ops, NULL);
        if (!domain)
                panic("Failed to add i8259 IRQ domain");
 
        setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2);
+       return domain;
+}
+
+void __init init_i8259_irqs(void)
+{
+       __init_i8259_irqs(NULL);
+}
+
+static void i8259_irq_dispatch(unsigned int irq, struct irq_desc *desc)
+{
+       struct irq_domain *domain = irq_get_handler_data(irq);
+       int hwirq = i8259_irq();
+
+       if (hwirq < 0)
+               return;
+
+       irq = irq_linear_revmap(domain, hwirq);
+       generic_handle_irq(irq);
+}
+
+int __init i8259_of_init(struct device_node *node, struct device_node *parent)
+{
+       struct irq_domain *domain;
+       unsigned int parent_irq;
+
+       parent_irq = irq_of_parse_and_map(node, 0);
+       if (!parent_irq) {
+               pr_err("Failed to map i8259 parent IRQ\n");
+               return -ENODEV;
+       }
+
+       domain = __init_i8259_irqs(node);
+       irq_set_handler_data(parent_irq, domain);
+       irq_set_chained_handler(parent_irq, i8259_irq_dispatch);
+       return 0;
 }
+IRQCHIP_DECLARE(i8259, "intel,i8259", i8259_of_init);
index 3c8a18a..8eb5af8 100644 (file)
 #include <linux/atomic.h>
 #include <asm/uaccess.h>
 
-#ifdef CONFIG_KGDB
-int kgdb_early_setup;
-#endif
-
-static DECLARE_BITMAP(irq_map, NR_IRQS);
-
-int allocate_irqno(void)
-{
-       int irq;
-
-again:
-       irq = find_first_zero_bit(irq_map, NR_IRQS);
-
-       if (irq >= NR_IRQS)
-               return -ENOSPC;
-
-       if (test_and_set_bit(irq, irq_map))
-               goto again;
-
-       return irq;
-}
-
-/*
- * Allocate the 16 legacy interrupts for i8259 devices.         This happens early
- * in the kernel initialization so treating allocation failure as BUG() is
- * ok.
- */
-void __init alloc_legacy_irqno(void)
-{
-       int i;
-
-       for (i = 0; i <= 16; i++)
-               BUG_ON(test_and_set_bit(i, irq_map));
-}
-
-void free_irqno(unsigned int irq)
-{
-       smp_mb__before_atomic();
-       clear_bit(irq, irq_map);
-       smp_mb__after_atomic();
-}
-
 /*
  * 'what should we do if we get a hw irq event on an illegal vector'.
  * each architecture has to answer this themselves.
@@ -93,20 +51,10 @@ void __init init_IRQ(void)
 {
        int i;
 
-#ifdef CONFIG_KGDB
-       if (kgdb_early_setup)
-               return;
-#endif
-
        for (i = 0; i < NR_IRQS; i++)
                irq_set_noprobe(i);
 
        arch_init_irq();
-
-#ifdef CONFIG_KGDB
-       if (!kgdb_early_setup)
-               kgdb_early_setup = 1;
-#endif
 }
 
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
index 7afcc2f..de63d36 100644 (file)
@@ -378,10 +378,6 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,
 
 struct kgdb_arch arch_kgdb_ops;
 
-/*
- * We use kgdb_early_setup so that functions we need to call now don't
- * cause trouble when called again later.
- */
 int kgdb_arch_init(void)
 {
        union mips_instruction insn = {
index e303cb1..b130033 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/of_fdt.h>
 #include <linux/of_platform.h>
 
+#include <asm/bootinfo.h>
 #include <asm/page.h>
 #include <asm/prom.h>
 
diff --git a/arch/mips/kernel/sysrq.c b/arch/mips/kernel/sysrq.c
new file mode 100644 (file)
index 0000000..5b539f5
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * MIPS specific sysrq operations.
+ *
+ * Copyright (C) 2015 Imagination Technologies Ltd.
+ */
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/sysrq.h>
+#include <linux/workqueue.h>
+
+#include <asm/cpu-features.h>
+#include <asm/mipsregs.h>
+#include <asm/tlbdebug.h>
+
+/*
+ * Dump TLB entries on all CPUs.
+ */
+
+static DEFINE_SPINLOCK(show_lock);
+
+static void sysrq_tlbdump_single(void *dummy)
+{
+       const int field = 2 * sizeof(unsigned long);
+       unsigned long flags;
+
+       spin_lock_irqsave(&show_lock, flags);
+
+       pr_info("CPU%d:\n", smp_processor_id());
+       pr_info("Index  : %0x\n", read_c0_index());
+       pr_info("Pagemask: %0x\n", read_c0_pagemask());
+       pr_info("EntryHi : %0*lx\n", field, read_c0_entryhi());
+       pr_info("EntryLo0: %0*lx\n", field, read_c0_entrylo0());
+       pr_info("EntryLo1: %0*lx\n", field, read_c0_entrylo1());
+       pr_info("Wired   : %0x\n", read_c0_wired());
+       pr_info("Pagegrain: %0x\n", read_c0_pagegrain());
+       if (cpu_has_htw) {
+               pr_info("PWField : %0*lx\n", field, read_c0_pwfield());
+               pr_info("PWSize  : %0*lx\n", field, read_c0_pwsize());
+               pr_info("PWCtl   : %0x\n", read_c0_pwctl());
+       }
+       pr_info("\n");
+       dump_tlb_all();
+       pr_info("\n");
+
+       spin_unlock_irqrestore(&show_lock, flags);
+}
+
+#ifdef CONFIG_SMP
+static void sysrq_tlbdump_othercpus(struct work_struct *dummy)
+{
+       smp_call_function(sysrq_tlbdump_single, NULL, 0);
+}
+
+static DECLARE_WORK(sysrq_tlbdump, sysrq_tlbdump_othercpus);
+#endif
+
+static void sysrq_handle_tlbdump(int key)
+{
+       sysrq_tlbdump_single(NULL);
+#ifdef CONFIG_SMP
+       schedule_work(&sysrq_tlbdump);
+#endif
+}
+
+static struct sysrq_key_op sysrq_tlbdump_op = {
+       .handler        = sysrq_handle_tlbdump,
+       .help_msg       = "show-tlbs(x)",
+       .action_msg     = "Show TLB entries",
+       .enable_mask    = SYSRQ_ENABLE_DUMP,
+};
+
+static int __init mips_sysrq_init(void)
+{
+       return register_sysrq_key('x', &sysrq_tlbdump_op);
+}
+arch_initcall(mips_sysrq_init);
index d2d1c19..2a7b38e 100644 (file)
@@ -236,6 +236,7 @@ static void __show_regs(const struct pt_regs *regs)
 {
        const int field = 2 * sizeof(unsigned long);
        unsigned int cause = regs->cp0_cause;
+       unsigned int exccode;
        int i;
 
        show_regs_print_info(KERN_DEFAULT);
@@ -317,10 +318,10 @@ static void __show_regs(const struct pt_regs *regs)
        }
        printk("\n");
 
-       printk("Cause : %08x\n", cause);
+       exccode = (cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE;
+       printk("Cause : %08x (ExcCode %02x)\n", cause, exccode);
 
-       cause = (cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE;
-       if (1 <= cause && cause <= 5)
+       if (1 <= exccode && exccode <= 5)
                printk("BadVA : %0*lx\n", field, regs->cp0_badvaddr);
 
        printk("PrId  : %08x (%s)\n", read_c0_prid(),
@@ -2184,11 +2185,6 @@ void __init trap_init(void)
 
        check_wait();
 
-#if defined(CONFIG_KGDB)
-       if (kgdb_early_setup)
-               return; /* Already done */
-#endif
-
        if (cpu_has_veic || cpu_has_vint) {
                unsigned long size = 0x200 + VECTORSPACING*64;
                ebase = (unsigned long)
index 3b46f7c..07d32a4 100644 (file)
@@ -125,8 +125,14 @@ SECTIONS
        .exit.data : {
                EXIT_DATA
        }
-
+#ifdef CONFIG_SMP
        PERCPU_SECTION(1 << CONFIG_MIPS_L1_CACHE_SHIFT)
+#endif
+#ifdef CONFIG_MIPS_RAW_APPENDED_DTB
+       __appended_dtb = .;
+       /* leave space for appended DTB */
+       . += 0x100000;
+#endif
        /*
         * Align to 64K in attempt to eliminate holes before the
         * .bss..swapper_pg_dir section at the start of .bss.  This
index 32b9f21..167f356 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 
+#include <asm/hazards.h>
 #include <asm/mipsregs.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -40,17 +41,20 @@ static inline const char *msk2str(unsigned int mask)
        return "";
 }
 
-#define BARRIER()                                      \
-       __asm__ __volatile__(                           \
-               ".set\tnoreorder\n\t"                   \
-               "nop;nop;nop;nop;nop;nop;nop\n\t"       \
-               ".set\treorder");
-
 static void dump_tlb(int first, int last)
 {
        unsigned long s_entryhi, entryhi, asid;
-       unsigned long long entrylo0, entrylo1;
+       unsigned long long entrylo0, entrylo1, pa;
        unsigned int s_index, s_pagemask, pagemask, c0, c1, i;
+#ifdef CONFIG_32BIT
+       bool xpa = cpu_has_xpa && (read_c0_pagegrain() & PG_ELPA);
+       int pwidth = xpa ? 11 : 8;
+       int vwidth = 8;
+#else
+       bool xpa = false;
+       int pwidth = 11;
+       int vwidth = 11;
+#endif
 
        s_pagemask = read_c0_pagemask();
        s_entryhi = read_c0_entryhi();
@@ -59,46 +63,74 @@ static void dump_tlb(int first, int last)
 
        for (i = first; i <= last; i++) {
                write_c0_index(i);
-               BARRIER();
+               mtc0_tlbr_hazard();
                tlb_read();
-               BARRIER();
+               tlb_read_hazard();
                pagemask = read_c0_pagemask();
                entryhi  = read_c0_entryhi();
                entrylo0 = read_c0_entrylo0();
                entrylo1 = read_c0_entrylo1();
 
-               /* Unused entries have a virtual address of CKSEG0.  */
-               if ((entryhi & ~0x1ffffUL) != CKSEG0
-                   && (entryhi & 0xff) == asid) {
-#ifdef CONFIG_32BIT
-                       int width = 8;
-#else
-                       int width = 11;
-#endif
-                       /*
-                        * Only print entries in use
-                        */
-                       printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
+               /* EHINV bit marks entire entry as invalid */
+               if (cpu_has_tlbinv && entryhi & MIPS_ENTRYHI_EHINV)
+                       continue;
+               /*
+                * Prior to tlbinv, unused entries have a virtual address of
+                * CKSEG0.
+                */
+               if ((entryhi & ~0x1ffffUL) == CKSEG0)
+                       continue;
+               /*
+                * ASID takes effect in absence of G (global) bit.
+                * We check both G bits, even though architecturally they should
+                * match one another, because some revisions of the SB1 core may
+                * leave only a single G bit set after a machine check exception
+                * due to duplicate TLB entry.
+                */
+               if (!((entrylo0 | entrylo1) & MIPS_ENTRYLO_G) &&
+                   (entryhi & 0xff) != asid)
+                       continue;
+
+               /*
+                * Only print entries in use
+                */
+               printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
 
-                       c0 = (entrylo0 >> 3) & 7;
-                       c1 = (entrylo1 >> 3) & 7;
+               c0 = (entrylo0 & MIPS_ENTRYLO_C) >> MIPS_ENTRYLO_C_SHIFT;
+               c1 = (entrylo1 & MIPS_ENTRYLO_C) >> MIPS_ENTRYLO_C_SHIFT;
 
-                       printk("va=%0*lx asid=%02lx\n",
-                              width, (entryhi & ~0x1fffUL),
-                              entryhi & 0xff);
-                       printk("\t[pa=%0*llx c=%d d=%d v=%d g=%d] ",
-                              width,
-                              (entrylo0 << 6) & PAGE_MASK, c0,
-                              (entrylo0 & 4) ? 1 : 0,
-                              (entrylo0 & 2) ? 1 : 0,
-                              (entrylo0 & 1) ? 1 : 0);
-                       printk("[pa=%0*llx c=%d d=%d v=%d g=%d]\n",
-                              width,
-                              (entrylo1 << 6) & PAGE_MASK, c1,
-                              (entrylo1 & 4) ? 1 : 0,
-                              (entrylo1 & 2) ? 1 : 0,
-                              (entrylo1 & 1) ? 1 : 0);
-               }
+               printk("va=%0*lx asid=%02lx\n",
+                      vwidth, (entryhi & ~0x1fffUL),
+                      entryhi & 0xff);
+               /* RI/XI are in awkward places, so mask them off separately */
+               pa = entrylo0 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI);
+               if (xpa)
+                       pa |= (unsigned long long)readx_c0_entrylo0() << 30;
+               pa = (pa << 6) & PAGE_MASK;
+               printk("\t[");
+               if (cpu_has_rixi)
+                       printk("ri=%d xi=%d ",
+                              (entrylo0 & MIPS_ENTRYLO_RI) ? 1 : 0,
+                              (entrylo0 & MIPS_ENTRYLO_XI) ? 1 : 0);
+               printk("pa=%0*llx c=%d d=%d v=%d g=%d] [",
+                      pwidth, pa, c0,
+                      (entrylo0 & MIPS_ENTRYLO_D) ? 1 : 0,
+                      (entrylo0 & MIPS_ENTRYLO_V) ? 1 : 0,
+                      (entrylo0 & MIPS_ENTRYLO_G) ? 1 : 0);
+               /* RI/XI are in awkward places, so mask them off separately */
+               pa = entrylo1 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI);
+               if (xpa)
+                       pa |= (unsigned long long)readx_c0_entrylo1() << 30;
+               pa = (pa << 6) & PAGE_MASK;
+               if (cpu_has_rixi)
+                       printk("ri=%d xi=%d ",
+                              (entrylo1 & MIPS_ENTRYLO_RI) ? 1 : 0,
+                              (entrylo1 & MIPS_ENTRYLO_XI) ? 1 : 0);
+               printk("pa=%0*llx c=%d d=%d v=%d g=%d]\n",
+                      pwidth, pa, c1,
+                      (entrylo1 & MIPS_ENTRYLO_D) ? 1 : 0,
+                      (entrylo1 & MIPS_ENTRYLO_V) ? 1 : 0,
+                      (entrylo1 & MIPS_ENTRYLO_G) ? 1 : 0);
        }
        printk("\n");
 
index 975a138..8e0d3cf 100644 (file)
@@ -14,8 +14,6 @@
 #include <asm/pgtable.h>
 #include <asm/tlbdebug.h>
 
-extern int r3k_have_wired_reg; /* defined in tlb-r3k.c */
-
 static void dump_tlb(int first, int last)
 {
        int     i;
@@ -35,8 +33,9 @@ static void dump_tlb(int first, int last)
                entrylo0 = read_c0_entrylo0();
 
                /* Unused entries have a virtual address of KSEG0.  */
-               if ((entryhi & PAGE_MASK) != KSEG0
-                   && (entryhi & ASID_MASK) == asid) {
+               if ((entryhi & PAGE_MASK) != KSEG0 &&
+                   (entrylo0 & R3K_ENTRYLO_G ||
+                    (entryhi & ASID_MASK) == asid)) {
                        /*
                         * Only print entries in use
                         */
@@ -47,10 +46,10 @@ static void dump_tlb(int first, int last)
                               entryhi & PAGE_MASK,
                               entryhi & ASID_MASK,
                               entrylo0 & PAGE_MASK,
-                              (entrylo0 & (1 << 11)) ? 1 : 0,
-                              (entrylo0 & (1 << 10)) ? 1 : 0,
-                              (entrylo0 & (1 << 9)) ? 1 : 0,
-                              (entrylo0 & (1 << 8)) ? 1 : 0);
+                              (entrylo0 & R3K_ENTRYLO_N) ? 1 : 0,
+                              (entrylo0 & R3K_ENTRYLO_D) ? 1 : 0,
+                              (entrylo0 & R3K_ENTRYLO_V) ? 1 : 0,
+                              (entrylo0 & R3K_ENTRYLO_G) ? 1 : 0);
                }
        }
        printk("\n");
similarity index 95%
rename from arch/mips/loongson1/Kconfig
rename to arch/mips/loongson32/Kconfig
index a2b796e..7704f20 100644 (file)
@@ -1,4 +1,4 @@
-if MACH_LOONGSON1
+if MACH_LOONGSON32
 
 choice
        prompt "Machine Type"
@@ -10,7 +10,7 @@ config LOONGSON1_LS1B
        select SYS_HAS_CPU_LOONGSON1B
        select DMA_NONCOHERENT
        select BOOT_ELF32
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_LITTLE_ENDIAN
        select SYS_SUPPORTS_HIGHMEM
@@ -58,4 +58,4 @@ config TIMER_USE_PWM3
 
 endchoice
 
-endif # MACH_LOONGSON1
+endif # MACH_LOONGSON32
similarity index 74%
rename from arch/mips/loongson1/Makefile
rename to arch/mips/loongson32/Makefile
index 9719c75..5f4bd6e 100644 (file)
@@ -2,7 +2,7 @@
 # Common code for all Loongson 1 based systems
 #
 
-obj-$(CONFIG_MACH_LOONGSON1) += common/
+obj-$(CONFIG_MACH_LOONGSON32) += common/
 
 #
 # Loongson LS1B board
similarity index 59%
rename from arch/mips/loongson1/Platform
rename to arch/mips/loongson32/Platform
index 1186344..ebb6dc2 100644 (file)
@@ -2,6 +2,6 @@ cflags-$(CONFIG_CPU_LOONGSON1)  += \
        $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
        -Wa,-mips32r2 -Wa,--trap
 
-platform-$(CONFIG_MACH_LOONGSON1)      += loongson1/
-cflags-$(CONFIG_MACH_LOONGSON1)                += -I$(srctree)/arch/mips/include/asm/mach-loongson1
+platform-$(CONFIG_MACH_LOONGSON32)     += loongson32/
+cflags-$(CONFIG_MACH_LOONGSON32)       += -I$(srctree)/arch/mips/include/asm/mach-loongson32
 load-$(CONFIG_LOONGSON1_LS1B)          += 0xffffffff80100000
similarity index 97%
rename from arch/mips/loongson/Kconfig
rename to arch/mips/loongson64/Kconfig
index 156de85..497912b 100644 (file)
@@ -1,4 +1,4 @@
-if MACH_LOONGSON
+if MACH_LOONGSON64
 
 choice
        prompt "Machine Type"
@@ -15,7 +15,7 @@ config LEMOTE_FULOONG2E
        select HW_HAS_PCI
        select I8259
        select ISA
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_64BIT_KERNEL
        select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -44,7 +44,7 @@ config LEMOTE_MACH2F
        select HAVE_CLK
        select HW_HAS_PCI
        select I8259
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select ISA
        select SYS_HAS_CPU_LOONGSON2F
        select SYS_HAS_EARLY_PRINTK
@@ -73,7 +73,7 @@ config LOONGSON_MACH3X
        select ISA
        select HT_PCI
        select I8259
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select NR_CPUS_DEFAULT_4
        select SYS_HAS_CPU_LOONGSON3
        select SYS_HAS_EARLY_PRINTK
@@ -155,4 +155,4 @@ config LOONGSON_MC146818
 config LEFI_FIRMWARE_INTERFACE
        bool
 
-endif # MACH_LOONGSON
+endif # MACH_LOONGSON64
similarity index 88%
rename from arch/mips/loongson/Makefile
rename to arch/mips/loongson64/Makefile
index 7429994..4fe3d88 100644 (file)
@@ -2,7 +2,7 @@
 # Common code for all Loongson based systems
 #
 
-obj-$(CONFIG_MACH_LOONGSON) += common/
+obj-$(CONFIG_MACH_LOONGSON64) += common/
 
 #
 # Lemote Fuloong mini-PC (Loongson 2E-based)
similarity index 87%
rename from arch/mips/loongson/Platform
rename to arch/mips/loongson64/Platform
index 0ac20eb..2e48e83 100644 (file)
@@ -26,8 +26,8 @@ endif
 # Loongson Machines' Support
 #
 
-platform-$(CONFIG_MACH_LOONGSON) += loongson/
-cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson -mno-branch-likely
+platform-$(CONFIG_MACH_LOONGSON64) += loongson64/
+cflags-$(CONFIG_MACH_LOONGSON64) += -I$(srctree)/arch/mips/include/asm/mach-loongson64 -mno-branch-likely
 load-$(CONFIG_LEMOTE_FULOONG2E) += 0xffffffff80100000
 load-$(CONFIG_LEMOTE_MACH2F) += 0xffffffff80200000
 load-$(CONFIG_LOONGSON_MACH3X) += 0xffffffff80200000
similarity index 95%
rename from arch/mips/loongson/common/serial.c
rename to arch/mips/loongson64/common/serial.c
index c23fa13..ffefc1c 100644 (file)
@@ -11,7 +11,7 @@
  */
 
 #include <linux/io.h>
-#include <linux/init.h>
+#include <linux/module.h>
 #include <linux/serial_8250.h>
 
 #include <asm/bootinfo.h>
@@ -108,5 +108,10 @@ static int __init serial_init(void)
 
        return platform_device_register(&uart8250_device);
 }
+module_init(serial_init);
 
-device_initcall(serial_init);
+static void __init serial_exit(void)
+{
+       platform_device_unregister(&uart8250_device);
+}
+module_exit(serial_exit);
index 2e03ab1..7f660dc 100644 (file)
@@ -295,7 +295,7 @@ static void r4k_blast_icache_page_setup(void)
 
 static void (*r4k_blast_icache_user_page)(unsigned long addr);
 
-static void __cpuinit r4k_blast_icache_user_page_setup(void)
+static void r4k_blast_icache_user_page_setup(void)
 {
        unsigned long ic_lsize = cpu_icache_line_size();
 
index 8d909db..596e184 100644 (file)
@@ -28,8 +28,6 @@ static unsigned long icache_size, dcache_size;                /* Size in bytes */
 
 #include <asm/r4kcache.h>
 
-extern int r3k_have_wired_reg; /* in r3k-tlb.c */
-
 /* This sequence is required to ensure icache is disabled immediately */
 #define TX39_STOP_STREAMING() \
 __asm__ __volatile__( \
@@ -383,8 +381,6 @@ void tx39_cache_init(void)
        case CPU_TX3927:
        default:
                /* TX39/H2,H3 core (writeback 2way-set-associative cache) */
-               r3k_have_wired_reg = 1;
-               write_c0_wired(0);      /* set 8 on reset... */
                /* board-dependent init code may set WBON */
 
                __flush_cache_vmap      = tx39__flush_cache_vmap;
index 609d124..eeaf024 100644 (file)
@@ -262,12 +262,13 @@ static void mips_dma_unmap_page(struct device *dev, dma_addr_t dma_addr,
        plat_unmap_dma_mem(dev, dma_addr, size, direction);
 }
 
-static int mips_dma_map_sg(struct device *dev, struct scatterlist *sg,
+static int mips_dma_map_sg(struct device *dev, struct scatterlist *sglist,
        int nents, enum dma_data_direction direction, struct dma_attrs *attrs)
 {
        int i;
+       struct scatterlist *sg;
 
-       for (i = 0; i < nents; i++, sg++) {
+       for_each_sg(sglist, sg, nents, i) {
                if (!plat_device_is_coherent(dev))
                        __dma_sync(sg_page(sg), sg->offset, sg->length,
                                   direction);
@@ -291,13 +292,14 @@ static dma_addr_t mips_dma_map_page(struct device *dev, struct page *page,
        return plat_map_dma_mem_page(dev, page) + offset;
 }
 
-static void mips_dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+static void mips_dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
        int nhwentries, enum dma_data_direction direction,
        struct dma_attrs *attrs)
 {
        int i;
+       struct scatterlist *sg;
 
-       for (i = 0; i < nhwentries; i++, sg++) {
+       for_each_sg(sglist, sg, nhwentries, i) {
                if (!plat_device_is_coherent(dev) &&
                    direction != DMA_TO_DEVICE)
                        __dma_sync(sg_page(sg), sg->offset, sg->length,
@@ -324,26 +326,34 @@ static void mips_dma_sync_single_for_device(struct device *dev,
 }
 
 static void mips_dma_sync_sg_for_cpu(struct device *dev,
-       struct scatterlist *sg, int nelems, enum dma_data_direction direction)
+       struct scatterlist *sglist, int nelems,
+       enum dma_data_direction direction)
 {
        int i;
+       struct scatterlist *sg;
 
-       if (cpu_needs_post_dma_flush(dev))
-               for (i = 0; i < nelems; i++, sg++)
+       if (cpu_needs_post_dma_flush(dev)) {
+               for_each_sg(sglist, sg, nelems, i) {
                        __dma_sync(sg_page(sg), sg->offset, sg->length,
                                   direction);
+               }
+       }
        plat_post_dma_flush(dev);
 }
 
 static void mips_dma_sync_sg_for_device(struct device *dev,
-       struct scatterlist *sg, int nelems, enum dma_data_direction direction)
+       struct scatterlist *sglist, int nelems,
+       enum dma_data_direction direction)
 {
        int i;
+       struct scatterlist *sg;
 
-       if (!plat_device_is_coherent(dev))
-               for (i = 0; i < nelems; i++, sg++)
+       if (!plat_device_is_coherent(dev)) {
+               for_each_sg(sglist, sg, nelems, i) {
                        __dma_sync(sg_page(sg), sg->offset, sg->length,
                                   direction);
+               }
+       }
 }
 
 int mips_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
index 4094bbd..2b75b8f 100644 (file)
@@ -36,30 +36,33 @@ extern void build_tlb_refill_handler(void);
                "nop\n\t"               \
                ".set   pop\n\t")
 
-int r3k_have_wired_reg;                /* should be in cpu_data? */
+static int r3k_have_wired_reg;                 /* Should be in cpu_data? */
 
 /* TLB operations. */
-void local_flush_tlb_all(void)
+static void local_flush_tlb_from(int entry)
 {
-       unsigned long flags;
        unsigned long old_ctx;
-       int entry;
-
-#ifdef DEBUG_TLB
-       printk("[tlball]");
-#endif
 
-       local_irq_save(flags);
        old_ctx = read_c0_entryhi() & ASID_MASK;
        write_c0_entrylo0(0);
-       entry = r3k_have_wired_reg ? read_c0_wired() : 8;
-       for (; entry < current_cpu_data.tlbsize; entry++) {
+       while (entry < current_cpu_data.tlbsize) {
                write_c0_index(entry << 8);
                write_c0_entryhi((entry | 0x80000) << 12);
-               BARRIER;
+               entry++;                                /* BARRIER */
                tlb_write_indexed();
        }
        write_c0_entryhi(old_ctx);
+}
+
+void local_flush_tlb_all(void)
+{
+       unsigned long flags;
+
+#ifdef DEBUG_TLB
+       printk("[tlball]");
+#endif
+       local_irq_save(flags);
+       local_flush_tlb_from(r3k_have_wired_reg ? read_c0_wired() : 8);
        local_irq_restore(flags);
 }
 
@@ -277,7 +280,13 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
 
 void tlb_init(void)
 {
-       local_flush_tlb_all();
-
+       switch (current_cpu_type()) {
+       case CPU_TX3922:
+       case CPU_TX3927:
+               r3k_have_wired_reg = 1;
+               write_c0_wired(0);              /* Set to 8 on reset... */
+               break;
+       }
+       local_flush_tlb_from(0);
        build_tlb_refill_handler();
 }
index 08318ec..5037d58 100644 (file)
@@ -423,7 +423,7 @@ int __init has_transparent_hugepage(void)
  * lifetime of the system
  */
 
-int temp_tlb_entry __cpuinitdata;
+int temp_tlb_entry;
 
 __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
                               unsigned long entryhi, unsigned long pagemask)
index 97c8702..323d1d3 100644 (file)
@@ -35,7 +35,7 @@
 #include <asm/uasm.h>
 #include <asm/setup.h>
 
-static int __cpuinitdata mips_xpa_disabled;
+static int mips_xpa_disabled;
 
 static int __init xpa_disable(char *s)
 {
@@ -1608,23 +1608,32 @@ build_pte_present(u32 **p, struct uasm_reloc **r,
                  int pte, int ptr, int scratch, enum label_id lid)
 {
        int t = scratch >= 0 ? scratch : pte;
+       int cur = pte;
 
        if (cpu_has_rixi) {
                if (use_bbit_insns()) {
                        uasm_il_bbit0(p, r, pte, ilog2(_PAGE_PRESENT), lid);
                        uasm_i_nop(p);
                } else {
-                       uasm_i_srl(p, t, pte, _PAGE_PRESENT_SHIFT);
-                       uasm_i_andi(p, t, t, 1);
+                       if (_PAGE_PRESENT_SHIFT) {
+                               uasm_i_srl(p, t, cur, _PAGE_PRESENT_SHIFT);
+                               cur = t;
+                       }
+                       uasm_i_andi(p, t, cur, 1);
                        uasm_il_beqz(p, r, t, lid);
                        if (pte == t)
                                /* You lose the SMP race :-(*/
                                iPTE_LW(p, pte, ptr);
                }
        } else {
-               uasm_i_srl(p, t, pte, _PAGE_PRESENT_SHIFT);
-               uasm_i_andi(p, t, t, 3);
-               uasm_i_xori(p, t, t, 3);
+               if (_PAGE_PRESENT_SHIFT) {
+                       uasm_i_srl(p, t, cur, _PAGE_PRESENT_SHIFT);
+                       cur = t;
+               }
+               uasm_i_andi(p, t, cur,
+                       (_PAGE_PRESENT | _PAGE_READ) >> _PAGE_PRESENT_SHIFT);
+               uasm_i_xori(p, t, t,
+                       (_PAGE_PRESENT | _PAGE_READ) >> _PAGE_PRESENT_SHIFT);
                uasm_il_bnez(p, r, t, lid);
                if (pte == t)
                        /* You lose the SMP race :-(*/
@@ -1652,10 +1661,16 @@ build_pte_writable(u32 **p, struct uasm_reloc **r,
                   enum label_id lid)
 {
        int t = scratch >= 0 ? scratch : pte;
+       int cur = pte;
 
-       uasm_i_srl(p, t, pte, _PAGE_PRESENT_SHIFT);
-       uasm_i_andi(p, t, t, 5);
-       uasm_i_xori(p, t, t, 5);
+       if (_PAGE_PRESENT_SHIFT) {
+               uasm_i_srl(p, t, cur, _PAGE_PRESENT_SHIFT);
+               cur = t;
+       }
+       uasm_i_andi(p, t, cur,
+                   (_PAGE_PRESENT | _PAGE_WRITE) >> _PAGE_PRESENT_SHIFT);
+       uasm_i_xori(p, t, t,
+                   (_PAGE_PRESENT | _PAGE_WRITE) >> _PAGE_PRESENT_SHIFT);
        uasm_il_bnez(p, r, t, lid);
        if (pte == t)
                /* You lose the SMP race :-(*/
index 6510ace..ea35587 100644 (file)
@@ -5,7 +5,7 @@
 # Copyright (C) 2008 Wind River Systems, Inc.
 #   written by Ralf Baechle <ralf@linux-mips.org>
 #
-obj-y                          := malta-display.o malta-init.o \
+obj-y                          := malta-display.o malta-dt.o malta-init.o \
                                   malta-int.o malta-memory.o malta-platform.o \
                                   malta-reset.o malta-setup.o malta-time.o
 
diff --git a/arch/mips/mti-malta/malta-dt.c b/arch/mips/mti-malta/malta-dt.c
new file mode 100644 (file)
index 0000000..47a2288
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2015 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-provider.h>
+#include <linux/init.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+
+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);
index db7c9e5..9d1e7f5 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/sched.h>
 #include <linux/ioport.h>
 #include <linux/irq.h>
+#include <linux/of_fdt.h>
 #include <linux/pci.h>
 #include <linux/screen_info.h>
 #include <linux/time.h>
@@ -31,6 +32,7 @@
 #include <asm/mips-boards/malta.h>
 #include <asm/mips-boards/maltaint.h>
 #include <asm/dma.h>
+#include <asm/prom.h>
 #include <asm/traps.h>
 #ifdef CONFIG_VT
 #include <linux/console.h>
@@ -249,6 +251,8 @@ void __init plat_mem_setup(void)
 {
        unsigned int i;
 
+       __dt_setup_arch(__dtb_start);
+
        if (config_enabled(CONFIG_EVA))
                /* EVA has already been configured in mach-malta/kernel-init.h */
                pr_info("Enhanced Virtual Addressing (EVA) activated\n");
index ae74b3a..8c27714 100644 (file)
@@ -1,3 +1,3 @@
 # MIPS networking code
 
-obj-$(CONFIG_BPF_JIT) += bpf_jit.o
+obj-$(CONFIG_BPF_JIT) += bpf_jit.o bpf_jit_asm.o
index e23fdf2..0c4a133 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/types.h>
+#include <asm/asm.h>
 #include <asm/bitops.h>
 #include <asm/cacheflush.h>
 #include <asm/cpu-features.h>
 #include "bpf_jit.h"
 
 /* ABI
- *
- * s0  1st scratch register
- * s1  2nd scratch register
- * s2  offset register
- * s3  BPF register A
- * s4  BPF register X
- * s5  *skb
- * s6  *scratch memory
+ * r_skb_hl    SKB header length
+ * r_data      SKB data pointer
+ * r_off       Offset
+ * r_A         BPF register A
+ * r_X         BPF register X
+ * r_skb       *skb
+ * r_M         *scratch memory
+ * r_skb_len   SKB length
  *
  * On entry (*bpf_func)(*skb, *filter)
  * a0 = MIPS_R_A0 = skb;
  * ----------------------------------------------------
  */
 
-#define RSIZE  (sizeof(unsigned long))
 #define ptr typeof(unsigned long)
 
-/* ABI specific return values */
-#ifdef CONFIG_32BIT /* O32 */
-#ifdef CONFIG_CPU_LITTLE_ENDIAN
-#define r_err  MIPS_R_V1
-#define r_val  MIPS_R_V0
-#else /* CONFIG_CPU_LITTLE_ENDIAN */
-#define r_err  MIPS_R_V0
-#define r_val  MIPS_R_V1
-#endif
-#else /* N64 */
-#define r_err  MIPS_R_V0
-#define r_val  MIPS_R_V0
-#endif
-
-#define r_ret  MIPS_R_V0
-
-/*
- * Use 2 scratch registers to avoid pipeline interlocks.
- * There is no overhead during epilogue and prologue since
- * any of the $s0-$s6 registers will only be preserved if
- * they are going to actually be used.
- */
-#define r_s0           MIPS_R_S0 /* scratch reg 1 */
-#define r_s1           MIPS_R_S1 /* scratch reg 2 */
-#define r_off          MIPS_R_S2
-#define r_A            MIPS_R_S3
-#define r_X            MIPS_R_S4
-#define r_skb          MIPS_R_S5
-#define r_M            MIPS_R_S6
-#define r_tmp_imm      MIPS_R_T6 /* No need to preserve this */
-#define r_tmp          MIPS_R_T7 /* No need to preserve this */
-#define r_zero         MIPS_R_ZERO
-#define r_sp           MIPS_R_SP
-#define r_ra           MIPS_R_RA
-
 #define SCRATCH_OFF(k)         (4 * (k))
 
 /* JIT flags */
 #define SEEN_SREG_SFT          (BPF_MEMWORDS + 1)
 #define SEEN_SREG_BASE         (1 << SEEN_SREG_SFT)
 #define SEEN_SREG(x)           (SEEN_SREG_BASE << (x))
-#define SEEN_S0                        SEEN_SREG(0)
-#define SEEN_S1                        SEEN_SREG(1)
 #define SEEN_OFF               SEEN_SREG(2)
 #define SEEN_A                 SEEN_SREG(3)
 #define SEEN_X                 SEEN_SREG(4)
 #define SEEN_SKB               SEEN_SREG(5)
 #define SEEN_MEM               SEEN_SREG(6)
+/* SEEN_SK_DATA also implies skb_hl an skb_len */
+#define SEEN_SKB_DATA          (SEEN_SREG(7) | SEEN_SREG(1) | SEEN_SREG(0))
 
 /* Arguments used by JIT */
 #define ARGS_USED_BY_JIT       2 /* only applicable to 64-bit */
@@ -577,27 +542,13 @@ static void save_bpf_jit_regs(struct jit_ctx *ctx, unsigned offset)
        /* Adjust the stack pointer */
        emit_stack_offset(-align_sp(offset), ctx);
 
-       if (ctx->flags & SEEN_CALL) {
-               /* Argument save area */
-               if (config_enabled(CONFIG_64BIT))
-                       /* Bottom of current frame */
-                       real_off = align_sp(offset) - RSIZE;
-               else
-                       /* Top of previous frame */
-                       real_off = align_sp(offset) + RSIZE;
-               emit_store_stack_reg(MIPS_R_A0, r_sp, real_off, ctx);
-               emit_store_stack_reg(MIPS_R_A1, r_sp, real_off + RSIZE, ctx);
-
-               real_off = 0;
-       }
-
        tmp_flags = sflags = ctx->flags >> SEEN_SREG_SFT;
        /* sflags is essentially a bitmap */
        while (tmp_flags) {
                if ((sflags >> i) & 0x1) {
                        emit_store_stack_reg(MIPS_R_S0 + i, r_sp, real_off,
                                             ctx);
-                       real_off += RSIZE;
+                       real_off += SZREG;
                }
                i++;
                tmp_flags >>= 1;
@@ -606,13 +557,13 @@ static void save_bpf_jit_regs(struct jit_ctx *ctx, unsigned offset)
        /* save return address */
        if (ctx->flags & SEEN_CALL) {
                emit_store_stack_reg(r_ra, r_sp, real_off, ctx);
-               real_off += RSIZE;
+               real_off += SZREG;
        }
 
        /* Setup r_M leaving the alignment gap if necessary */
        if (ctx->flags & SEEN_MEM) {
-               if (real_off % (RSIZE * 2))
-                       real_off += RSIZE;
+               if (real_off % (SZREG * 2))
+                       real_off += SZREG;
                emit_long_instr(ctx, ADDIU, r_M, r_sp, real_off);
        }
 }
@@ -623,19 +574,6 @@ static void restore_bpf_jit_regs(struct jit_ctx *ctx,
        int i, real_off = 0;
        u32 sflags, tmp_flags;
 
-       if (ctx->flags & SEEN_CALL) {
-               if (config_enabled(CONFIG_64BIT))
-                       /* Bottom of current frame */
-                       real_off = align_sp(offset) - RSIZE;
-               else
-                       /* Top of previous frame */
-                       real_off = align_sp(offset) + RSIZE;
-               emit_load_stack_reg(MIPS_R_A0, r_sp, real_off, ctx);
-               emit_load_stack_reg(MIPS_R_A1, r_sp, real_off + RSIZE, ctx);
-
-               real_off = 0;
-       }
-
        tmp_flags = sflags = ctx->flags >> SEEN_SREG_SFT;
        /* sflags is a bitmap */
        i = 0;
@@ -643,7 +581,7 @@ static void restore_bpf_jit_regs(struct jit_ctx *ctx,
                if ((sflags >> i) & 0x1) {
                        emit_load_stack_reg(MIPS_R_S0 + i, r_sp, real_off,
                                            ctx);
-                       real_off += RSIZE;
+                       real_off += SZREG;
                }
                i++;
                tmp_flags >>= 1;
@@ -663,23 +601,13 @@ static unsigned int get_stack_depth(struct jit_ctx *ctx)
 
 
        /* How may s* regs do we need to preserved? */
-       sp_off += hweight32(ctx->flags >> SEEN_SREG_SFT) * RSIZE;
+       sp_off += hweight32(ctx->flags >> SEEN_SREG_SFT) * SZREG;
 
        if (ctx->flags & SEEN_MEM)
                sp_off += 4 * BPF_MEMWORDS; /* BPF_MEMWORDS are 32-bit */
 
        if (ctx->flags & SEEN_CALL)
-               /*
-                * The JIT code make calls to external functions using 2
-                * arguments. Therefore, for o32 we don't need to allocate
-                * space because we don't care if the argumetns are lost
-                * across calls. We do need however to preserve incoming
-                * arguments but the space is already allocated for us by
-                * the caller. On the other hand, for n64, we need to allocate
-                * this space ourselves. We need to preserve $ra as well.
-                */
-               sp_off += config_enabled(CONFIG_64BIT) ?
-                       (ARGS_USED_BY_JIT + 1) * RSIZE : RSIZE;
+               sp_off += SZREG; /* Space for our ra register */
 
        return sp_off;
 }
@@ -696,6 +624,19 @@ static void build_prologue(struct jit_ctx *ctx)
        if (ctx->flags & SEEN_SKB)
                emit_reg_move(r_skb, MIPS_R_A0, ctx);
 
+       if (ctx->flags & SEEN_SKB_DATA) {
+               /* Load packet length */
+               emit_load(r_skb_len, r_skb, offsetof(struct sk_buff, len),
+                         ctx);
+               emit_load(r_tmp, r_skb, offsetof(struct sk_buff, data_len),
+                         ctx);
+               /* Load the data pointer */
+               emit_load_ptr(r_skb_data, r_skb,
+                             offsetof(struct sk_buff, data), ctx);
+               /* Load the header length */
+               emit_subu(r_skb_hl, r_skb_len, r_tmp, ctx);
+       }
+
        if (ctx->flags & SEEN_X)
                emit_jit_reg_move(r_X, r_zero, ctx);
 
@@ -718,43 +659,17 @@ static void build_epilogue(struct jit_ctx *ctx)
        emit_nop(ctx);
 }
 
-static u64 jit_get_skb_b(struct sk_buff *skb, unsigned offset)
-{
-       u8 ret;
-       int err;
-
-       err = skb_copy_bits(skb, offset, &ret, 1);
-
-       return (u64)err << 32 | ret;
-}
-
-static u64 jit_get_skb_h(struct sk_buff *skb, unsigned offset)
-{
-       u16 ret;
-       int err;
-
-       err = skb_copy_bits(skb, offset, &ret, 2);
-
-       return (u64)err << 32 | ntohs(ret);
-}
-
-static u64 jit_get_skb_w(struct sk_buff *skb, unsigned offset)
-{
-       u32 ret;
-       int err;
-
-       err = skb_copy_bits(skb, offset, &ret, 4);
-
-       return (u64)err << 32 | ntohl(ret);
-}
+#define CHOOSE_LOAD_FUNC(K, func) \
+       ((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative : func) : \
+        func##_positive)
 
 static int build_body(struct jit_ctx *ctx)
 {
-       void *load_func[] = {jit_get_skb_b, jit_get_skb_h, jit_get_skb_w};
        const struct bpf_prog *prog = ctx->skf;
        const struct sock_filter *inst;
-       unsigned int i, off, load_order, condt;
+       unsigned int i, off, condt;
        u32 k, b_off __maybe_unused;
+       u8 (*sk_load_func)(unsigned long *skb, int offset);
 
        for (i = 0; i < prog->len; i++) {
                u16 code;
@@ -788,71 +703,46 @@ static int build_body(struct jit_ctx *ctx)
                        break;
                case BPF_LD | BPF_W | BPF_ABS:
                        /* A <- P[k:4] */
-                       load_order = 2;
+                       sk_load_func = CHOOSE_LOAD_FUNC(k, sk_load_word);
                        goto load;
                case BPF_LD | BPF_H | BPF_ABS:
                        /* A <- P[k:2] */
-                       load_order = 1;
+                       sk_load_func = CHOOSE_LOAD_FUNC(k, sk_load_half);
                        goto load;
                case BPF_LD | BPF_B | BPF_ABS:
                        /* A <- P[k:1] */
-                       load_order = 0;
+                       sk_load_func = CHOOSE_LOAD_FUNC(k, sk_load_byte);
 load:
-                       /* the interpreter will deal with the negative K */
-                       if ((int)k < 0)
-                               return -ENOTSUPP;
-
                        emit_load_imm(r_off, k, ctx);
 load_common:
-                       /*
-                        * We may got here from the indirect loads so
-                        * return if offset is negative.
-                        */
-                       emit_slt(r_s0, r_off, r_zero, ctx);
-                       emit_bcond(MIPS_COND_NE, r_s0, r_zero,
-                                  b_imm(prog->len, ctx), ctx);
-                       emit_reg_move(r_ret, r_zero, ctx);
-
-                       ctx->flags |= SEEN_CALL | SEEN_OFF | SEEN_S0 |
-                               SEEN_SKB | SEEN_A;
+                       ctx->flags |= SEEN_CALL | SEEN_OFF |
+                               SEEN_SKB | SEEN_A | SEEN_SKB_DATA;
 
-                       emit_load_func(r_s0, (ptr)load_func[load_order],
-                                     ctx);
+                       emit_load_func(r_s0, (ptr)sk_load_func, ctx);
                        emit_reg_move(MIPS_R_A0, r_skb, ctx);
                        emit_jalr(MIPS_R_RA, r_s0, ctx);
                        /* Load second argument to delay slot */
                        emit_reg_move(MIPS_R_A1, r_off, ctx);
                        /* Check the error value */
-                       if (config_enabled(CONFIG_64BIT)) {
-                               /* Get error code from the top 32-bits */
-                               emit_dsrl32(r_s0, r_val, 0, ctx);
-                               /* Branch to 3 instructions ahead */
-                               emit_bcond(MIPS_COND_NE, r_s0, r_zero, 3 << 2,
-                                          ctx);
-                       } else {
-                               /* Branch to 3 instructions ahead */
-                               emit_bcond(MIPS_COND_NE, r_err, r_zero, 3 << 2,
-                                          ctx);
-                       }
-                       emit_nop(ctx);
-                       /* We are good */
-                       emit_b(b_imm(i + 1, ctx), ctx);
-                       emit_jit_reg_move(r_A, r_val, ctx);
+                       emit_bcond(MIPS_COND_EQ, r_ret, 0, b_imm(i + 1, ctx),
+                                  ctx);
+                       /* Load return register on DS for failures */
+                       emit_reg_move(r_ret, r_zero, ctx);
                        /* Return with error */
                        emit_b(b_imm(prog->len, ctx), ctx);
-                       emit_reg_move(r_ret, r_zero, ctx);
+                       emit_nop(ctx);
                        break;
                case BPF_LD | BPF_W | BPF_IND:
                        /* A <- P[X + k:4] */
-                       load_order = 2;
+                       sk_load_func = sk_load_word;
                        goto load_ind;
                case BPF_LD | BPF_H | BPF_IND:
                        /* A <- P[X + k:2] */
-                       load_order = 1;
+                       sk_load_func = sk_load_half;
                        goto load_ind;
                case BPF_LD | BPF_B | BPF_IND:
                        /* A <- P[X + k:1] */
-                       load_order = 0;
+                       sk_load_func = sk_load_byte;
 load_ind:
                        ctx->flags |= SEEN_OFF | SEEN_X;
                        emit_addiu(r_off, r_X, k, ctx);
@@ -874,14 +764,10 @@ load_ind:
                        emit_load(r_X, r_skb, off, ctx);
                        break;
                case BPF_LDX | BPF_B | BPF_MSH:
-                       /* the interpreter will deal with the negative K */
-                       if ((int)k < 0)
-                               return -ENOTSUPP;
-
                        /* X <- 4 * (P[k:1] & 0xf) */
-                       ctx->flags |= SEEN_X | SEEN_CALL | SEEN_S0 | SEEN_SKB;
+                       ctx->flags |= SEEN_X | SEEN_CALL | SEEN_SKB;
                        /* Load offset to a1 */
-                       emit_load_func(r_s0, (ptr)jit_get_skb_b, ctx);
+                       emit_load_func(r_s0, (ptr)sk_load_byte, ctx);
                        /*
                         * This may emit two instructions so it may not fit
                         * in the delay slot. So use a0 in the delay slot.
@@ -890,25 +776,15 @@ load_ind:
                        emit_jalr(MIPS_R_RA, r_s0, ctx);
                        emit_reg_move(MIPS_R_A0, r_skb, ctx); /* delay slot */
                        /* Check the error value */
-                       if (config_enabled(CONFIG_64BIT)) {
-                               /* Top 32-bits of $v0 on 64-bit */
-                               emit_dsrl32(r_s0, r_val, 0, ctx);
-                               emit_bcond(MIPS_COND_NE, r_s0, r_zero,
-                                          3 << 2, ctx);
-                       } else {
-                               emit_bcond(MIPS_COND_NE, r_err, r_zero,
-                                          3 << 2, ctx);
-                       }
-                       /* No need for delay slot */
+                       emit_bcond(MIPS_COND_NE, r_ret, 0,
+                                  b_imm(prog->len, ctx), ctx);
+                       emit_reg_move(r_ret, r_zero, ctx);
                        /* We are good */
                        /* X <- P[1:K] & 0xf */
-                       emit_andi(r_X, r_val, 0xf, ctx);
+                       emit_andi(r_X, r_A, 0xf, ctx);
                        /* X << 2 */
                        emit_b(b_imm(i + 1, ctx), ctx);
                        emit_sll(r_X, r_X, 2, ctx); /* delay slot */
-                       /* Return with error */
-                       emit_b(b_imm(prog->len, ctx), ctx);
-                       emit_load_imm(r_ret, 0, ctx); /* delay slot */
                        break;
                case BPF_ST:
                        /* M[k] <- A */
@@ -943,7 +819,7 @@ load_ind:
                case BPF_ALU | BPF_MUL | BPF_K:
                        /* A *= K */
                        /* Load K to scratch register before MUL */
-                       ctx->flags |= SEEN_A | SEEN_S0;
+                       ctx->flags |= SEEN_A;
                        emit_load_imm(r_s0, k, ctx);
                        emit_mul(r_A, r_A, r_s0, ctx);
                        break;
@@ -961,7 +837,7 @@ load_ind:
                                emit_srl(r_A, r_A, k, ctx);
                                break;
                        }
-                       ctx->flags |= SEEN_A | SEEN_S0;
+                       ctx->flags |= SEEN_A;
                        emit_load_imm(r_s0, k, ctx);
                        emit_div(r_A, r_s0, ctx);
                        break;
@@ -971,7 +847,7 @@ load_ind:
                                ctx->flags |= SEEN_A;
                                emit_jit_reg_move(r_A, r_zero, ctx);
                        } else {
-                               ctx->flags |= SEEN_A | SEEN_S0;
+                               ctx->flags |= SEEN_A;
                                emit_load_imm(r_s0, k, ctx);
                                emit_mod(r_A, r_s0, ctx);
                        }
@@ -982,7 +858,7 @@ load_ind:
                        /* Check if r_X is zero */
                        emit_bcond(MIPS_COND_EQ, r_X, r_zero,
                                   b_imm(prog->len, ctx), ctx);
-                       emit_load_imm(r_val, 0, ctx); /* delay slot */
+                       emit_load_imm(r_ret, 0, ctx); /* delay slot */
                        emit_div(r_A, r_X, ctx);
                        break;
                case BPF_ALU | BPF_MOD | BPF_X:
@@ -991,7 +867,7 @@ load_ind:
                        /* Check if r_X is zero */
                        emit_bcond(MIPS_COND_EQ, r_X, r_zero,
                                   b_imm(prog->len, ctx), ctx);
-                       emit_load_imm(r_val, 0, ctx); /* delay slot */
+                       emit_load_imm(r_ret, 0, ctx); /* delay slot */
                        emit_mod(r_A, r_X, ctx);
                        break;
                case BPF_ALU | BPF_OR | BPF_K:
@@ -1085,10 +961,10 @@ jmp_cmp:
                        if ((condt & MIPS_COND_GE) ||
                            (condt & MIPS_COND_GT)) {
                                if (condt & MIPS_COND_K) { /* K */
-                                       ctx->flags |= SEEN_S0 | SEEN_A;
+                                       ctx->flags |= SEEN_A;
                                        emit_sltiu(r_s0, r_A, k, ctx);
                                } else { /* X */
-                                       ctx->flags |= SEEN_S0 | SEEN_A |
+                                       ctx->flags |= SEEN_A |
                                                SEEN_X;
                                        emit_sltu(r_s0, r_A, r_X, ctx);
                                }
@@ -1100,7 +976,7 @@ jmp_cmp:
                                /* A > (K|X) ? scratch = 0 */
                                if (condt & MIPS_COND_GT) {
                                        /* Checking for equality */
-                                       ctx->flags |= SEEN_S0 | SEEN_A | SEEN_X;
+                                       ctx->flags |= SEEN_A | SEEN_X;
                                        if (condt & MIPS_COND_K)
                                                emit_load_imm(r_s0, k, ctx);
                                        else
@@ -1123,7 +999,7 @@ jmp_cmp:
                        } else {
                                /* A == K|X */
                                if (condt & MIPS_COND_K) { /* K */
-                                       ctx->flags |= SEEN_S0 | SEEN_A;
+                                       ctx->flags |= SEEN_A;
                                        emit_load_imm(r_s0, k, ctx);
                                        /* jump true */
                                        b_off = b_imm(i + inst->jt + 1, ctx);
@@ -1153,7 +1029,7 @@ jmp_cmp:
                        }
                        break;
                case BPF_JMP | BPF_JSET | BPF_K:
-                       ctx->flags |= SEEN_S0 | SEEN_S1 | SEEN_A;
+                       ctx->flags |= SEEN_A;
                        /* pc += (A & K) ? pc -> jt : pc -> jf */
                        emit_load_imm(r_s1, k, ctx);
                        emit_and(r_s0, r_A, r_s1, ctx);
@@ -1167,7 +1043,7 @@ jmp_cmp:
                        emit_nop(ctx);
                        break;
                case BPF_JMP | BPF_JSET | BPF_X:
-                       ctx->flags |= SEEN_S0 | SEEN_X | SEEN_A;
+                       ctx->flags |= SEEN_X | SEEN_A;
                        /* pc += (A & X) ? pc -> jt : pc -> jf */
                        emit_and(r_s0, r_A, r_X, ctx);
                        /* jump true */
@@ -1251,7 +1127,7 @@ jmp_cmp:
                        break;
                case BPF_ANC | SKF_AD_IFINDEX:
                        /* A = skb->dev->ifindex */
-                       ctx->flags |= SEEN_SKB | SEEN_A | SEEN_S0;
+                       ctx->flags |= SEEN_SKB | SEEN_A;
                        off = offsetof(struct sk_buff, dev);
                        /* Load *dev pointer */
                        emit_load_ptr(r_s0, r_skb, off, ctx);
@@ -1278,7 +1154,7 @@ jmp_cmp:
                        break;
                case BPF_ANC | SKF_AD_VLAN_TAG:
                case BPF_ANC | SKF_AD_VLAN_TAG_PRESENT:
-                       ctx->flags |= SEEN_SKB | SEEN_S0 | SEEN_A;
+                       ctx->flags |= SEEN_SKB | SEEN_A;
                        BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
                                                  vlan_tci) != 2);
                        off = offsetof(struct sk_buff, vlan_tci);
index 3a5751b..8f9f548 100644 (file)
 /* Registers used by JIT */
 #define MIPS_R_ZERO    0
 #define MIPS_R_V0      2
-#define MIPS_R_V1      3
 #define MIPS_R_A0      4
 #define MIPS_R_A1      5
+#define MIPS_R_T4      12
+#define MIPS_R_T5      13
 #define MIPS_R_T6      14
 #define MIPS_R_T7      15
 #define MIPS_R_S0      16
 #define MIPS_COND_X    (0x1 << 5)
 #define MIPS_COND_K    (0x1 << 6)
 
+#define r_ret  MIPS_R_V0
+
+/*
+ * Use 2 scratch registers to avoid pipeline interlocks.
+ * There is no overhead during epilogue and prologue since
+ * any of the $s0-$s6 registers will only be preserved if
+ * they are going to actually be used.
+ */
+#define r_skb_hl       MIPS_R_S0 /* skb header length */
+#define r_skb_data     MIPS_R_S1 /* skb actual data */
+#define r_off          MIPS_R_S2
+#define r_A            MIPS_R_S3
+#define r_X            MIPS_R_S4
+#define r_skb          MIPS_R_S5
+#define r_M            MIPS_R_S6
+#define r_skb_len      MIPS_R_S7
+#define r_s0           MIPS_R_T4 /* scratch reg 1 */
+#define r_s1           MIPS_R_T5 /* scratch reg 2 */
+#define r_tmp_imm      MIPS_R_T6 /* No need to preserve this */
+#define r_tmp          MIPS_R_T7 /* No need to preserve this */
+#define r_zero         MIPS_R_ZERO
+#define r_sp           MIPS_R_SP
+#define r_ra           MIPS_R_RA
+
+#ifndef __ASSEMBLY__
+
+/* Declare ASM helpers */
+
+#define DECLARE_LOAD_FUNC(func) \
+       extern u8 func(unsigned long *skb, int offset); \
+       extern u8 func##_negative(unsigned long *skb, int offset); \
+       extern u8 func##_positive(unsigned long *skb, int offset)
+
+DECLARE_LOAD_FUNC(sk_load_word);
+DECLARE_LOAD_FUNC(sk_load_half);
+DECLARE_LOAD_FUNC(sk_load_byte);
+
+#endif
+
 #endif /* BPF_JIT_MIPS_OP_H */
diff --git a/arch/mips/net/bpf_jit_asm.S b/arch/mips/net/bpf_jit_asm.S
new file mode 100644 (file)
index 0000000..e927260
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * bpf_jib_asm.S: Packet/header access helper functions for MIPS/MIPS64 BPF
+ * compiler.
+ *
+ * Copyright (C) 2015 Imagination Technologies Ltd.
+ * Author: Markos Chandras <markos.chandras@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; version 2 of the License.
+ */
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include "bpf_jit.h"
+
+/* ABI
+ *
+ * r_skb_hl    skb header length
+ * r_skb_data  skb data
+ * r_off(a1)   offset register
+ * r_A         BPF register A
+ * r_X         PF register X
+ * r_skb(a0)   *skb
+ * r_M         *scratch memory
+ * r_skb_le    skb length
+ * r_s0                Scratch register 0
+ * r_s1                Scratch register 1
+ *
+ * On entry:
+ * a0: *skb
+ * a1: offset (imm or imm + X)
+ *
+ * All non-BPF-ABI registers are free for use. On return, we only
+ * care about r_ret. The BPF-ABI registers are assumed to remain
+ * unmodified during the entire filter operation.
+ */
+
+#define skb    a0
+#define offset a1
+#define SKF_LL_OFF  (-0x200000) /* Can't include linux/filter.h in assembly */
+
+       /* We know better :) so prevent assembler reordering etc */
+       .set    noreorder
+
+#define is_offset_negative(TYPE)                               \
+       /* If offset is negative we have more work to do */     \
+       slti    t0, offset, 0;                                  \
+       bgtz    t0, bpf_slow_path_##TYPE##_neg;                 \
+       /* Be careful what follows in DS. */
+
+#define is_offset_in_header(SIZE, TYPE)                                \
+       /* Reading from header? */                              \
+       addiu   $r_s0, $r_skb_hl, -SIZE;                        \
+       slt     t0, $r_s0, offset;                              \
+       bgtz    t0, bpf_slow_path_##TYPE;                       \
+
+LEAF(sk_load_word)
+       is_offset_negative(word)
+       .globl sk_load_word_positive
+sk_load_word_positive:
+       is_offset_in_header(4, word)
+       /* Offset within header boundaries */
+       PTR_ADDU t1, $r_skb_data, offset
+       lw      $r_A, 0(t1)
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+       wsbh    t0, $r_A
+       rotr    $r_A, t0, 16
+#endif
+       jr      $r_ra
+        move   $r_ret, zero
+       END(sk_load_word)
+
+LEAF(sk_load_half)
+       is_offset_negative(half)
+       .globl sk_load_half_positive
+sk_load_half_positive:
+       is_offset_in_header(2, half)
+       /* Offset within header boundaries */
+       PTR_ADDU t1, $r_skb_data, offset
+       lh      $r_A, 0(t1)
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+       wsbh    t0, $r_A
+       seh     $r_A, t0
+#endif
+       jr      $r_ra
+        move   $r_ret, zero
+       END(sk_load_half)
+
+LEAF(sk_load_byte)
+       is_offset_negative(byte)
+       .globl sk_load_byte_positive
+sk_load_byte_positive:
+       is_offset_in_header(1, byte)
+       /* Offset within header boundaries */
+       PTR_ADDU t1, $r_skb_data, offset
+       lb      $r_A, 0(t1)
+       jr      $r_ra
+        move   $r_ret, zero
+       END(sk_load_byte)
+
+/*
+ * call skb_copy_bits:
+ * (prototype in linux/skbuff.h)
+ *
+ * int skb_copy_bits(sk_buff *skb, int offset, void *to, int len)
+ *
+ * o32 mandates we leave 4 spaces for argument registers in case
+ * the callee needs to use them. Even though we don't care about
+ * the argument registers ourselves, we need to allocate that space
+ * to remain ABI compliant since the callee may want to use that space.
+ * We also allocate 2 more spaces for $r_ra and our return register (*to).
+ *
+ * n64 is a bit different. The *caller* will allocate the space to preserve
+ * the arguments. So in 64-bit kernels, we allocate the 4-arg space for no
+ * good reason but it does not matter that much really.
+ *
+ * (void *to) is returned in r_s0
+ *
+ */
+#define bpf_slow_path_common(SIZE)                             \
+       /* Quick check. Are we within reasonable boundaries? */ \
+       LONG_ADDIU      $r_s1, $r_skb_len, -SIZE;               \
+       sltu            $r_s0, offset, $r_s1;                   \
+       beqz            $r_s0, fault;                           \
+       /* Load 4th argument in DS */                           \
+        LONG_ADDIU     a3, zero, SIZE;                         \
+       PTR_ADDIU       $r_sp, $r_sp, -(6 * SZREG);             \
+       PTR_LA          t0, skb_copy_bits;                      \
+       PTR_S           $r_ra, (5 * SZREG)($r_sp);              \
+       /* Assign low slot to a2 */                             \
+       move            a2, $r_sp;                              \
+       jalr            t0;                                     \
+       /* Reset our destination slot (DS but it's ok) */       \
+        INT_S          zero, (4 * SZREG)($r_sp);               \
+       /*                                                      \
+        * skb_copy_bits returns 0 on success and -EFAULT       \
+        * on error. Our data live in a2. Do not bother with    \
+        * our data if an error has been returned.              \
+        */                                                     \
+       /* Restore our frame */                                 \
+       PTR_L           $r_ra, (5 * SZREG)($r_sp);              \
+       INT_L           $r_s0, (4 * SZREG)($r_sp);              \
+       bltz            v0, fault;                              \
+        PTR_ADDIU      $r_sp, $r_sp, 6 * SZREG;                \
+       move            $r_ret, zero;                           \
+
+NESTED(bpf_slow_path_word, (6 * SZREG), $r_sp)
+       bpf_slow_path_common(4)
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+       wsbh    t0, $r_s0
+       jr      $r_ra
+        rotr   $r_A, t0, 16
+#endif
+       jr      $r_ra
+       move    $r_A, $r_s0
+
+       END(bpf_slow_path_word)
+
+NESTED(bpf_slow_path_half, (6 * SZREG), $r_sp)
+       bpf_slow_path_common(2)
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+       jr      $r_ra
+        wsbh   $r_A, $r_s0
+#endif
+       jr      $r_ra
+        move   $r_A, $r_s0
+
+       END(bpf_slow_path_half)
+
+NESTED(bpf_slow_path_byte, (6 * SZREG), $r_sp)
+       bpf_slow_path_common(1)
+       jr      $r_ra
+        move   $r_A, $r_s0
+
+       END(bpf_slow_path_byte)
+
+/*
+ * Negative entry points
+ */
+       .macro bpf_is_end_of_data
+       li      t0, SKF_LL_OFF
+       /* Reading link layer data? */
+       slt     t1, offset, t0
+       bgtz    t1, fault
+       /* Be careful what follows in DS. */
+       .endm
+/*
+ * call skb_copy_bits:
+ * (prototype in linux/filter.h)
+ *
+ * void *bpf_internal_load_pointer_neg_helper(const struct sk_buff *skb,
+ *                                            int k, unsigned int size)
+ *
+ * see above (bpf_slow_path_common) for ABI restrictions
+ */
+#define bpf_negative_common(SIZE)                                      \
+       PTR_ADDIU       $r_sp, $r_sp, -(6 * SZREG);                     \
+       PTR_LA          t0, bpf_internal_load_pointer_neg_helper;       \
+       PTR_S           $r_ra, (5 * SZREG)($r_sp);                      \
+       jalr            t0;                                             \
+        li             a2, SIZE;                                       \
+       PTR_L           $r_ra, (5 * SZREG)($r_sp);                      \
+       /* Check return pointer */                                      \
+       beqz            v0, fault;                                      \
+        PTR_ADDIU      $r_sp, $r_sp, 6 * SZREG;                        \
+       /* Preserve our pointer */                                      \
+       move            $r_s0, v0;                                      \
+       /* Set return value */                                          \
+       move            $r_ret, zero;                                   \
+
+bpf_slow_path_word_neg:
+       bpf_is_end_of_data
+NESTED(sk_load_word_negative, (6 * SZREG), $r_sp)
+       bpf_negative_common(4)
+       jr      $r_ra
+        lw     $r_A, 0($r_s0)
+       END(sk_load_word_negative)
+
+bpf_slow_path_half_neg:
+       bpf_is_end_of_data
+NESTED(sk_load_half_negative, (6 * SZREG), $r_sp)
+       bpf_negative_common(2)
+       jr      $r_ra
+        lhu    $r_A, 0($r_s0)
+       END(sk_load_half_negative)
+
+bpf_slow_path_byte_neg:
+       bpf_is_end_of_data
+NESTED(sk_load_byte_negative, (6 * SZREG), $r_sp)
+       bpf_negative_common(1)
+       jr      $r_ra
+        lbu    $r_A, 0($r_s0)
+       END(sk_load_byte_negative)
+
+fault:
+       jr      $r_ra
+        addiu $r_ret, zero, 1
index 6d3c727..f03131f 100644 (file)
@@ -78,8 +78,6 @@ static struct platform_device xlr_nor_dev = {
        .resource       = xlr_nor_res,
 };
 
-const char *xlr_part_probes[] = { "cmdlinepart", NULL };
-
 /*
  * Use "gen_nand" driver for NAND flash
  *
@@ -111,7 +109,6 @@ struct platform_nand_data xlr_nand_data = {
                .nr_partitions  = ARRAY_SIZE(xlr_nand_parts),
                .chip_delay     = 50,
                .partitions     = xlr_nand_parts,
-               .part_probe_types = xlr_part_probes,
        },
        .ctrl = {
                .cmd_ctrl       = xlr_nand_ctrl,
index 07a1822..dadb303 100644 (file)
@@ -320,7 +320,7 @@ static int ar2315_pci_host_setup(struct ar2315_pci_ctrl *apc)
 
 static void ar2315_pci_irq_handler(unsigned irq, struct irq_desc *desc)
 {
-       struct ar2315_pci_ctrl *apc = irq_get_handler_data(irq);
+       struct ar2315_pci_ctrl *apc = irq_desc_get_handler_data(desc);
        u32 pending = ar2315_pci_reg_read(apc, AR2315_PCI_ISR) &
                      ar2315_pci_reg_read(apc, AR2315_PCI_IMR);
        unsigned pci_irq = 0;
index 9e62ad3..283157f 100644 (file)
@@ -232,7 +232,7 @@ static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
        void __iomem *base = ath79_reset_base;
        u32 pending;
 
-       apc = irq_get_handler_data(irq);
+       apc = irq_desc_get_handler_data(desc);
 
        pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) &
                  __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
@@ -318,23 +318,13 @@ static void ar71xx_pci_irq_init(struct ar71xx_pci_controller *apc)
 
 static void ar71xx_pci_reset(void)
 {
-       void __iomem *ddr_base = ath79_ddr_base;
-
        ath79_device_reset_set(AR71XX_RESET_PCI_BUS | AR71XX_RESET_PCI_CORE);
        mdelay(100);
 
        ath79_device_reset_clear(AR71XX_RESET_PCI_BUS | AR71XX_RESET_PCI_CORE);
        mdelay(100);
 
-       __raw_writel(AR71XX_PCI_WIN0_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN0);
-       __raw_writel(AR71XX_PCI_WIN1_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN1);
-       __raw_writel(AR71XX_PCI_WIN2_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN2);
-       __raw_writel(AR71XX_PCI_WIN3_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN3);
-       __raw_writel(AR71XX_PCI_WIN4_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN4);
-       __raw_writel(AR71XX_PCI_WIN5_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN5);
-       __raw_writel(AR71XX_PCI_WIN6_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN6);
-       __raw_writel(AR71XX_PCI_WIN7_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN7);
-
+       ath79_ddr_set_pci_windows();
        mdelay(100);
 }
 
index a1b7d2a..0af362b 100644 (file)
@@ -231,7 +231,7 @@ static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
        void __iomem *base;
        u32 pending;
 
-       apc = irq_get_handler_data(irq);
+       apc = irq_desc_get_handler_data(desc);
        base = apc->ctrl_base;
 
        pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) &
index ec9be8c..80fafe6 100644 (file)
@@ -134,7 +134,7 @@ static void rt3883_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
        struct rt3883_pci_controller *rpc;
        u32 pending;
 
-       rpc = irq_get_handler_data(irq);
+       rpc = irq_desc_get_handler_data(desc);
 
        pending = rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIINT) &
                  rt3883_pci_r32(rpc, RT3883_PCI_REG_PCIENA);
index 7cf91b9..da301e0 100644 (file)
@@ -100,7 +100,7 @@ static void ralink_intc_irq_handler(unsigned int irq, struct irq_desc *desc)
        u32 pending = rt_intc_r32(INTC_REG_STATUS0);
 
        if (pending) {
-               struct irq_domain *domain = irq_get_handler_data(irq);
+               struct irq_domain *domain = irq_desc_get_handler_data(desc);
                generic_handle_irq(irq_find_mapping(domain, __ffs(pending)));
        } else {
                spurious_interrupt();
index da8f681..ab4affa 100644 (file)
@@ -2,9 +2,9 @@
 # Makefile for the IP27 specific kernel interface routines under Linux.
 #
 
-obj-y  := ip27-berr.o ip27-irq.o ip27-init.o ip27-klconfig.o ip27-klnuma.o \
-          ip27-memory.o ip27-nmi.o ip27-reset.o ip27-timer.o ip27-hubio.o \
-          ip27-xtalk.o
+obj-y  := ip27-berr.o ip27-irq.o ip27-irqno.o ip27-init.o ip27-klconfig.o \
+          ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o ip27-timer.o \
+          ip27-hubio.o ip27-xtalk.o
 
 obj-$(CONFIG_EARLY_PRINTK)     += ip27-console.o
 obj-$(CONFIG_PCI)              += ip27-irq-pci.o
diff --git a/arch/mips/sgi-ip27/ip27-irqno.c b/arch/mips/sgi-ip27/ip27-irqno.c
new file mode 100644 (file)
index 0000000..957ab58
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/types.h>
+
+#include <asm/barrier.h>
+
+static DECLARE_BITMAP(irq_map, NR_IRQS);
+
+int allocate_irqno(void)
+{
+       int irq;
+
+again:
+       irq = find_first_zero_bit(irq_map, NR_IRQS);
+
+       if (irq >= NR_IRQS)
+               return -ENOSPC;
+
+       if (test_and_set_bit(irq, irq_map))
+               goto again;
+
+       return irq;
+}
+
+/*
+ * Allocate the 16 legacy interrupts for i8259 devices.         This happens early
+ * in the kernel initialization so treating allocation failure as BUG() is
+ * ok.
+ */
+void __init alloc_legacy_irqno(void)
+{
+       int i;
+
+       for (i = 0; i <= 16; i++)
+               BUG_ON(test_and_set_bit(i, irq_map));
+}
+
+void free_irqno(unsigned int irq)
+{
+       smp_mb__before_atomic();
+       clear_bit(irq, irq_map);
+       smp_mb__after_atomic();
+}
index 5fbd360..a8bb972 100644 (file)
@@ -3,7 +3,7 @@ config SIBYTE_SB1250
        select CEVT_SB1250
        select CSRC_SB1250
        select HW_HAS_PCI
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select SIBYTE_ENABLE_LDT_IF_PCI
        select SIBYTE_HAS_ZBUS_PROFILING
        select SIBYTE_SB1xxx_SOC
@@ -13,7 +13,7 @@ config SIBYTE_BCM1120
        bool
        select CEVT_SB1250
        select CSRC_SB1250
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select SIBYTE_BCM112X
        select SIBYTE_HAS_ZBUS_PROFILING
        select SIBYTE_SB1xxx_SOC
@@ -23,7 +23,7 @@ config SIBYTE_BCM1125
        select CEVT_SB1250
        select CSRC_SB1250
        select HW_HAS_PCI
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select SIBYTE_BCM112X
        select SIBYTE_HAS_ZBUS_PROFILING
        select SIBYTE_SB1xxx_SOC
@@ -33,7 +33,7 @@ config SIBYTE_BCM1125H
        select CEVT_SB1250
        select CSRC_SB1250
        select HW_HAS_PCI
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select SIBYTE_BCM112X
        select SIBYTE_ENABLE_LDT_IF_PCI
        select SIBYTE_HAS_ZBUS_PROFILING
@@ -43,7 +43,7 @@ config SIBYTE_BCM112X
        bool
        select CEVT_SB1250
        select CSRC_SB1250
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select SIBYTE_SB1xxx_SOC
        select SIBYTE_HAS_ZBUS_PROFILING
 
@@ -52,7 +52,7 @@ config SIBYTE_BCM1x80
        select CEVT_BCM1480
        select CSRC_BCM1480
        select HW_HAS_PCI
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select SIBYTE_HAS_ZBUS_PROFILING
        select SIBYTE_SB1xxx_SOC
        select SYS_SUPPORTS_SMP
@@ -62,7 +62,7 @@ config SIBYTE_BCM1x55
        select CEVT_BCM1480
        select CSRC_BCM1480
        select HW_HAS_PCI
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select SIBYTE_SB1xxx_SOC
        select SIBYTE_HAS_ZBUS_PROFILING
        select SYS_SUPPORTS_SMP
@@ -70,7 +70,7 @@ config SIBYTE_BCM1x55
 config SIBYTE_SB1xxx_SOC
        bool
        select DMA_COHERENT
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select SWAP_IO_SPACE
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_64BIT_KERNEL
index 6d40bc7..8c337d6 100644 (file)
@@ -8,7 +8,7 @@ config MACH_TX49XX
        select MACH_TXX9
        select CEVT_R4K
        select CSRC_R4K
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select SYS_HAS_CPU_TX49XX
        select SYS_SUPPORTS_64BIT_KERNEL
 
index c1be6b3..74927b4 100644 (file)
@@ -8,7 +8,7 @@ config CASIO_E55
        select CEVT_R4K
        select CSRC_R4K
        select DMA_NONCOHERENT
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select ISA
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -18,7 +18,7 @@ config IBM_WORKPAD
        select CEVT_R4K
        select CSRC_R4K
        select DMA_NONCOHERENT
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select ISA
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -28,7 +28,7 @@ config TANBAC_TB022X
        select CEVT_R4K
        select CSRC_R4K
        select DMA_NONCOHERENT
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select HW_HAS_PCI
        select SYS_SUPPORTS_32BIT_KERNEL
        select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -44,7 +44,7 @@ config VICTOR_MPC30X
        select CEVT_R4K
        select CSRC_R4K
        select DMA_NONCOHERENT
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select HW_HAS_PCI
        select PCI_VR41XX
        select SYS_SUPPORTS_32BIT_KERNEL
@@ -55,7 +55,7 @@ config ZAO_CAPCELLA
        select CEVT_R4K
        select CSRC_R4K
        select DMA_NONCOHERENT
-       select IRQ_CPU
+       select IRQ_MIPS_CPU
        select HW_HAS_PCI
        select PCI_VR41XX
        select SYS_SUPPORTS_32BIT_KERNEL
index 5b6af6a..8732e4c 100644 (file)
@@ -24,7 +24,7 @@ obj-$(CONFIG_COMMON_CLK_CDCE706)      += clk-cdce706.o
 obj-$(CONFIG_ARCH_CLPS711X)            += clk-clps711x.o
 obj-$(CONFIG_ARCH_EFM32)               += clk-efm32gg.o
 obj-$(CONFIG_ARCH_HIGHBANK)            += clk-highbank.o
-obj-$(CONFIG_MACH_LOONGSON1)           += clk-ls1x.o
+obj-$(CONFIG_MACH_LOONGSON32)          += clk-ls1x.o
 obj-$(CONFIG_COMMON_CLK_MAX_GEN)       += clk-max-gen.o
 obj-$(CONFIG_COMMON_CLK_MAX77686)      += clk-max77686.o
 obj-$(CONFIG_COMMON_CLK_MAX77802)      += clk-max77802.o
@@ -51,6 +51,7 @@ obj-$(CONFIG_ARCH_HI3xxx)             += hisilicon/
 obj-$(CONFIG_ARCH_HIP04)               += hisilicon/
 obj-$(CONFIG_ARCH_HIX5HD2)             += hisilicon/
 obj-$(CONFIG_ARCH_MXC)                 += imx/
+obj-$(CONFIG_MACH_INGENIC)             += ingenic/
 obj-$(CONFIG_COMMON_CLK_KEYSTONE)      += keystone/
 ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_ARCH_MMP)                 += mmp/
diff --git a/drivers/clk/ingenic/Makefile b/drivers/clk/ingenic/Makefile
new file mode 100644 (file)
index 0000000..cd47b06
--- /dev/null
@@ -0,0 +1,3 @@
+obj-y                          += cgu.o
+obj-$(CONFIG_MACH_JZ4740)      += jz4740-cgu.o
+obj-$(CONFIG_MACH_JZ4780)      += jz4780-cgu.o
diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c
new file mode 100644 (file)
index 0000000..b936cdd
--- /dev/null
@@ -0,0 +1,711 @@
+/*
+ * Ingenic SoC CGU driver
+ *
+ * Copyright (c) 2013-2015 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.
+ *
+ * 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.
+ */
+
+#include <linux/bitops.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/delay.h>
+#include <linux/math64.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include "cgu.h"
+
+#define MHZ (1000 * 1000)
+
+/**
+ * ingenic_cgu_gate_get() - get the value of clock gate register bit
+ * @cgu: reference to the CGU whose registers should be read
+ * @info: info struct describing the gate bit
+ *
+ * Retrieves the state of the clock gate bit described by info. The
+ * caller must hold cgu->lock.
+ *
+ * Return: true if the gate bit is set, else false.
+ */
+static inline bool
+ingenic_cgu_gate_get(struct ingenic_cgu *cgu,
+                    const struct ingenic_cgu_gate_info *info)
+{
+       return readl(cgu->base + info->reg) & BIT(info->bit);
+}
+
+/**
+ * ingenic_cgu_gate_set() - set the value of clock gate register bit
+ * @cgu: reference to the CGU whose registers should be modified
+ * @info: info struct describing the gate bit
+ * @val: non-zero to gate a clock, otherwise zero
+ *
+ * Sets the given gate bit in order to gate or ungate a clock.
+ *
+ * The caller must hold cgu->lock.
+ */
+static inline void
+ingenic_cgu_gate_set(struct ingenic_cgu *cgu,
+                    const struct ingenic_cgu_gate_info *info, bool val)
+{
+       u32 clkgr = readl(cgu->base + info->reg);
+
+       if (val)
+               clkgr |= BIT(info->bit);
+       else
+               clkgr &= ~BIT(info->bit);
+
+       writel(clkgr, cgu->base + info->reg);
+}
+
+/*
+ * PLL operations
+ */
+
+static unsigned long
+ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+       struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+       struct ingenic_cgu *cgu = ingenic_clk->cgu;
+       const struct ingenic_cgu_clk_info *clk_info;
+       const struct ingenic_cgu_pll_info *pll_info;
+       unsigned m, n, od_enc, od;
+       bool bypass, enable;
+       unsigned long flags;
+       u32 ctl;
+
+       clk_info = &cgu->clock_info[ingenic_clk->idx];
+       BUG_ON(clk_info->type != CGU_CLK_PLL);
+       pll_info = &clk_info->pll;
+
+       spin_lock_irqsave(&cgu->lock, flags);
+       ctl = readl(cgu->base + pll_info->reg);
+       spin_unlock_irqrestore(&cgu->lock, flags);
+
+       m = (ctl >> pll_info->m_shift) & GENMASK(pll_info->m_bits - 1, 0);
+       m += pll_info->m_offset;
+       n = (ctl >> pll_info->n_shift) & GENMASK(pll_info->n_bits - 1, 0);
+       n += pll_info->n_offset;
+       od_enc = ctl >> pll_info->od_shift;
+       od_enc &= GENMASK(pll_info->od_bits - 1, 0);
+       bypass = !!(ctl & BIT(pll_info->bypass_bit));
+       enable = !!(ctl & BIT(pll_info->enable_bit));
+
+       if (bypass)
+               return parent_rate;
+
+       if (!enable)
+               return 0;
+
+       for (od = 0; od < pll_info->od_max; od++) {
+               if (pll_info->od_encoding[od] == od_enc)
+                       break;
+       }
+       BUG_ON(od == pll_info->od_max);
+       od++;
+
+       return div_u64((u64)parent_rate * m, n * od);
+}
+
+static unsigned long
+ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info,
+                unsigned long rate, unsigned long parent_rate,
+                unsigned *pm, unsigned *pn, unsigned *pod)
+{
+       const struct ingenic_cgu_pll_info *pll_info;
+       unsigned m, n, od;
+
+       pll_info = &clk_info->pll;
+       od = 1;
+
+       /*
+        * The frequency after the input divider must be between 10 and 50 MHz.
+        * The highest divider yields the best resolution.
+        */
+       n = parent_rate / (10 * MHZ);
+       n = min_t(unsigned, n, 1 << clk_info->pll.n_bits);
+       n = max_t(unsigned, n, pll_info->n_offset);
+
+       m = (rate / MHZ) * od * n / (parent_rate / MHZ);
+       m = min_t(unsigned, m, 1 << clk_info->pll.m_bits);
+       m = max_t(unsigned, m, pll_info->m_offset);
+
+       if (pm)
+               *pm = m;
+       if (pn)
+               *pn = n;
+       if (pod)
+               *pod = od;
+
+       return div_u64((u64)parent_rate * m, n * od);
+}
+
+static long
+ingenic_pll_round_rate(struct clk_hw *hw, unsigned long req_rate,
+                      unsigned long *prate)
+{
+       struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+       struct ingenic_cgu *cgu = ingenic_clk->cgu;
+       const struct ingenic_cgu_clk_info *clk_info;
+
+       clk_info = &cgu->clock_info[ingenic_clk->idx];
+       BUG_ON(clk_info->type != CGU_CLK_PLL);
+
+       return ingenic_pll_calc(clk_info, req_rate, *prate, NULL, NULL, NULL);
+}
+
+static int
+ingenic_pll_set_rate(struct clk_hw *hw, unsigned long req_rate,
+                    unsigned long parent_rate)
+{
+       const unsigned timeout = 100;
+       struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+       struct ingenic_cgu *cgu = ingenic_clk->cgu;
+       const struct ingenic_cgu_clk_info *clk_info;
+       const struct ingenic_cgu_pll_info *pll_info;
+       unsigned long rate, flags;
+       unsigned m, n, od, i;
+       u32 ctl;
+
+       clk_info = &cgu->clock_info[ingenic_clk->idx];
+       BUG_ON(clk_info->type != CGU_CLK_PLL);
+       pll_info = &clk_info->pll;
+
+       rate = ingenic_pll_calc(clk_info, req_rate, parent_rate,
+                              &m, &n, &od);
+       if (rate != req_rate)
+               pr_info("ingenic-cgu: request '%s' rate %luHz, actual %luHz\n",
+                       clk_info->name, req_rate, rate);
+
+       spin_lock_irqsave(&cgu->lock, flags);
+       ctl = readl(cgu->base + pll_info->reg);
+
+       ctl &= ~(GENMASK(pll_info->m_bits - 1, 0) << pll_info->m_shift);
+       ctl |= (m - pll_info->m_offset) << pll_info->m_shift;
+
+       ctl &= ~(GENMASK(pll_info->n_bits - 1, 0) << pll_info->n_shift);
+       ctl |= (n - pll_info->n_offset) << pll_info->n_shift;
+
+       ctl &= ~(GENMASK(pll_info->od_bits - 1, 0) << pll_info->od_shift);
+       ctl |= pll_info->od_encoding[od - 1] << pll_info->od_shift;
+
+       ctl &= ~BIT(pll_info->bypass_bit);
+       ctl |= BIT(pll_info->enable_bit);
+
+       writel(ctl, cgu->base + pll_info->reg);
+
+       /* wait for the PLL to stabilise */
+       for (i = 0; i < timeout; i++) {
+               ctl = readl(cgu->base + pll_info->reg);
+               if (ctl & BIT(pll_info->stable_bit))
+                       break;
+               mdelay(1);
+       }
+
+       spin_unlock_irqrestore(&cgu->lock, flags);
+
+       if (i == timeout)
+               return -EBUSY;
+
+       return 0;
+}
+
+static const struct clk_ops ingenic_pll_ops = {
+       .recalc_rate = ingenic_pll_recalc_rate,
+       .round_rate = ingenic_pll_round_rate,
+       .set_rate = ingenic_pll_set_rate,
+};
+
+/*
+ * Operations for all non-PLL clocks
+ */
+
+static u8 ingenic_clk_get_parent(struct clk_hw *hw)
+{
+       struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+       struct ingenic_cgu *cgu = ingenic_clk->cgu;
+       const struct ingenic_cgu_clk_info *clk_info;
+       u32 reg;
+       u8 i, hw_idx, idx = 0;
+
+       clk_info = &cgu->clock_info[ingenic_clk->idx];
+
+       if (clk_info->type & CGU_CLK_MUX) {
+               reg = readl(cgu->base + clk_info->mux.reg);
+               hw_idx = (reg >> clk_info->mux.shift) &
+                        GENMASK(clk_info->mux.bits - 1, 0);
+
+               /*
+                * Convert the hardware index to the parent index by skipping
+                * over any -1's in the parents array.
+                */
+               for (i = 0; i < hw_idx; i++) {
+                       if (clk_info->parents[i] != -1)
+                               idx++;
+               }
+       }
+
+       return idx;
+}
+
+static int ingenic_clk_set_parent(struct clk_hw *hw, u8 idx)
+{
+       struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+       struct ingenic_cgu *cgu = ingenic_clk->cgu;
+       const struct ingenic_cgu_clk_info *clk_info;
+       unsigned long flags;
+       u8 curr_idx, hw_idx, num_poss;
+       u32 reg, mask;
+
+       clk_info = &cgu->clock_info[ingenic_clk->idx];
+
+       if (clk_info->type & CGU_CLK_MUX) {
+               /*
+                * Convert the parent index to the hardware index by adding
+                * 1 for any -1 in the parents array preceding the given
+                * index. That is, we want the index of idx'th entry in
+                * clk_info->parents which does not equal -1.
+                */
+               hw_idx = curr_idx = 0;
+               num_poss = 1 << clk_info->mux.bits;
+               for (; hw_idx < num_poss; hw_idx++) {
+                       if (clk_info->parents[hw_idx] == -1)
+                               continue;
+                       if (curr_idx == idx)
+                               break;
+                       curr_idx++;
+               }
+
+               /* idx should always be a valid parent */
+               BUG_ON(curr_idx != idx);
+
+               mask = GENMASK(clk_info->mux.bits - 1, 0);
+               mask <<= clk_info->mux.shift;
+
+               spin_lock_irqsave(&cgu->lock, flags);
+
+               /* write the register */
+               reg = readl(cgu->base + clk_info->mux.reg);
+               reg &= ~mask;
+               reg |= hw_idx << clk_info->mux.shift;
+               writel(reg, cgu->base + clk_info->mux.reg);
+
+               spin_unlock_irqrestore(&cgu->lock, flags);
+               return 0;
+       }
+
+       return idx ? -EINVAL : 0;
+}
+
+static unsigned long
+ingenic_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
+{
+       struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+       struct ingenic_cgu *cgu = ingenic_clk->cgu;
+       const struct ingenic_cgu_clk_info *clk_info;
+       unsigned long rate = parent_rate;
+       u32 div_reg, div;
+
+       clk_info = &cgu->clock_info[ingenic_clk->idx];
+
+       if (clk_info->type & CGU_CLK_DIV) {
+               div_reg = readl(cgu->base + clk_info->div.reg);
+               div = (div_reg >> clk_info->div.shift) &
+                     GENMASK(clk_info->div.bits - 1, 0);
+               div += 1;
+
+               rate /= div;
+       }
+
+       return rate;
+}
+
+static unsigned
+ingenic_clk_calc_div(const struct ingenic_cgu_clk_info *clk_info,
+                    unsigned long parent_rate, unsigned long req_rate)
+{
+       unsigned div;
+
+       /* calculate the divide */
+       div = DIV_ROUND_UP(parent_rate, req_rate);
+
+       /* and impose hardware constraints */
+       div = min_t(unsigned, div, 1 << clk_info->div.bits);
+       div = max_t(unsigned, div, 1);
+
+       return div;
+}
+
+static long
+ingenic_clk_round_rate(struct clk_hw *hw, unsigned long req_rate,
+                      unsigned long *parent_rate)
+{
+       struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+       struct ingenic_cgu *cgu = ingenic_clk->cgu;
+       const struct ingenic_cgu_clk_info *clk_info;
+       long rate = *parent_rate;
+
+       clk_info = &cgu->clock_info[ingenic_clk->idx];
+
+       if (clk_info->type & CGU_CLK_DIV)
+               rate /= ingenic_clk_calc_div(clk_info, *parent_rate, req_rate);
+       else if (clk_info->type & CGU_CLK_FIXDIV)
+               rate /= clk_info->fixdiv.div;
+
+       return rate;
+}
+
+static int
+ingenic_clk_set_rate(struct clk_hw *hw, unsigned long req_rate,
+                    unsigned long parent_rate)
+{
+       struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+       struct ingenic_cgu *cgu = ingenic_clk->cgu;
+       const struct ingenic_cgu_clk_info *clk_info;
+       const unsigned timeout = 100;
+       unsigned long rate, flags;
+       unsigned div, i;
+       u32 reg, mask;
+       int ret = 0;
+
+       clk_info = &cgu->clock_info[ingenic_clk->idx];
+
+       if (clk_info->type & CGU_CLK_DIV) {
+               div = ingenic_clk_calc_div(clk_info, parent_rate, req_rate);
+               rate = parent_rate / div;
+
+               if (rate != req_rate)
+                       return -EINVAL;
+
+               spin_lock_irqsave(&cgu->lock, flags);
+               reg = readl(cgu->base + clk_info->div.reg);
+
+               /* update the divide */
+               mask = GENMASK(clk_info->div.bits - 1, 0);
+               reg &= ~(mask << clk_info->div.shift);
+               reg |= (div - 1) << clk_info->div.shift;
+
+               /* clear the stop bit */
+               if (clk_info->div.stop_bit != -1)
+                       reg &= ~BIT(clk_info->div.stop_bit);
+
+               /* set the change enable bit */
+               if (clk_info->div.ce_bit != -1)
+                       reg |= BIT(clk_info->div.ce_bit);
+
+               /* update the hardware */
+               writel(reg, cgu->base + clk_info->div.reg);
+
+               /* wait for the change to take effect */
+               if (clk_info->div.busy_bit != -1) {
+                       for (i = 0; i < timeout; i++) {
+                               reg = readl(cgu->base + clk_info->div.reg);
+                               if (!(reg & BIT(clk_info->div.busy_bit)))
+                                       break;
+                               mdelay(1);
+                       }
+                       if (i == timeout)
+                               ret = -EBUSY;
+               }
+
+               spin_unlock_irqrestore(&cgu->lock, flags);
+               return ret;
+       }
+
+       return -EINVAL;
+}
+
+static int ingenic_clk_enable(struct clk_hw *hw)
+{
+       struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+       struct ingenic_cgu *cgu = ingenic_clk->cgu;
+       const struct ingenic_cgu_clk_info *clk_info;
+       unsigned long flags;
+
+       clk_info = &cgu->clock_info[ingenic_clk->idx];
+
+       if (clk_info->type & CGU_CLK_GATE) {
+               /* ungate the clock */
+               spin_lock_irqsave(&cgu->lock, flags);
+               ingenic_cgu_gate_set(cgu, &clk_info->gate, false);
+               spin_unlock_irqrestore(&cgu->lock, flags);
+       }
+
+       return 0;
+}
+
+static void ingenic_clk_disable(struct clk_hw *hw)
+{
+       struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+       struct ingenic_cgu *cgu = ingenic_clk->cgu;
+       const struct ingenic_cgu_clk_info *clk_info;
+       unsigned long flags;
+
+       clk_info = &cgu->clock_info[ingenic_clk->idx];
+
+       if (clk_info->type & CGU_CLK_GATE) {
+               /* gate the clock */
+               spin_lock_irqsave(&cgu->lock, flags);
+               ingenic_cgu_gate_set(cgu, &clk_info->gate, true);
+               spin_unlock_irqrestore(&cgu->lock, flags);
+       }
+}
+
+static int ingenic_clk_is_enabled(struct clk_hw *hw)
+{
+       struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
+       struct ingenic_cgu *cgu = ingenic_clk->cgu;
+       const struct ingenic_cgu_clk_info *clk_info;
+       unsigned long flags;
+       int enabled = 1;
+
+       clk_info = &cgu->clock_info[ingenic_clk->idx];
+
+       if (clk_info->type & CGU_CLK_GATE) {
+               spin_lock_irqsave(&cgu->lock, flags);
+               enabled = !ingenic_cgu_gate_get(cgu, &clk_info->gate);
+               spin_unlock_irqrestore(&cgu->lock, flags);
+       }
+
+       return enabled;
+}
+
+static const struct clk_ops ingenic_clk_ops = {
+       .get_parent = ingenic_clk_get_parent,
+       .set_parent = ingenic_clk_set_parent,
+
+       .recalc_rate = ingenic_clk_recalc_rate,
+       .round_rate = ingenic_clk_round_rate,
+       .set_rate = ingenic_clk_set_rate,
+
+       .enable = ingenic_clk_enable,
+       .disable = ingenic_clk_disable,
+       .is_enabled = ingenic_clk_is_enabled,
+};
+
+/*
+ * Setup functions.
+ */
+
+static int ingenic_register_clock(struct ingenic_cgu *cgu, unsigned idx)
+{
+       const struct ingenic_cgu_clk_info *clk_info = &cgu->clock_info[idx];
+       struct clk_init_data clk_init;
+       struct ingenic_clk *ingenic_clk = NULL;
+       struct clk *clk, *parent;
+       const char *parent_names[4];
+       unsigned caps, i, num_possible;
+       int err = -EINVAL;
+
+       BUILD_BUG_ON(ARRAY_SIZE(clk_info->parents) > ARRAY_SIZE(parent_names));
+
+       if (clk_info->type == CGU_CLK_EXT) {
+               clk = of_clk_get_by_name(cgu->np, clk_info->name);
+               if (IS_ERR(clk)) {
+                       pr_err("%s: no external clock '%s' provided\n",
+                              __func__, clk_info->name);
+                       err = -ENODEV;
+                       goto out;
+               }
+               err = clk_register_clkdev(clk, clk_info->name, NULL);
+               if (err) {
+                       clk_put(clk);
+                       goto out;
+               }
+               cgu->clocks.clks[idx] = clk;
+               return 0;
+       }
+
+       if (!clk_info->type) {
+               pr_err("%s: no clock type specified for '%s'\n", __func__,
+                      clk_info->name);
+               goto out;
+       }
+
+       ingenic_clk = kzalloc(sizeof(*ingenic_clk), GFP_KERNEL);
+       if (!ingenic_clk) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       ingenic_clk->hw.init = &clk_init;
+       ingenic_clk->cgu = cgu;
+       ingenic_clk->idx = idx;
+
+       clk_init.name = clk_info->name;
+       clk_init.flags = 0;
+       clk_init.parent_names = parent_names;
+
+       caps = clk_info->type;
+
+       if (caps & (CGU_CLK_MUX | CGU_CLK_CUSTOM)) {
+               clk_init.num_parents = 0;
+
+               if (caps & CGU_CLK_MUX)
+                       num_possible = 1 << clk_info->mux.bits;
+               else
+                       num_possible = ARRAY_SIZE(clk_info->parents);
+
+               for (i = 0; i < num_possible; i++) {
+                       if (clk_info->parents[i] == -1)
+                               continue;
+
+                       parent = cgu->clocks.clks[clk_info->parents[i]];
+                       parent_names[clk_init.num_parents] =
+                               __clk_get_name(parent);
+                       clk_init.num_parents++;
+               }
+
+               BUG_ON(!clk_init.num_parents);
+               BUG_ON(clk_init.num_parents > ARRAY_SIZE(parent_names));
+       } else {
+               BUG_ON(clk_info->parents[0] == -1);
+               clk_init.num_parents = 1;
+               parent = cgu->clocks.clks[clk_info->parents[0]];
+               parent_names[0] = __clk_get_name(parent);
+       }
+
+       if (caps & CGU_CLK_CUSTOM) {
+               clk_init.ops = clk_info->custom.clk_ops;
+
+               caps &= ~CGU_CLK_CUSTOM;
+
+               if (caps) {
+                       pr_err("%s: custom clock may not be combined with type 0x%x\n",
+                              __func__, caps);
+                       goto out;
+               }
+       } else if (caps & CGU_CLK_PLL) {
+               clk_init.ops = &ingenic_pll_ops;
+
+               caps &= ~CGU_CLK_PLL;
+
+               if (caps) {
+                       pr_err("%s: PLL may not be combined with type 0x%x\n",
+                              __func__, caps);
+                       goto out;
+               }
+       } else {
+               clk_init.ops = &ingenic_clk_ops;
+       }
+
+       /* nothing to do for gates or fixed dividers */
+       caps &= ~(CGU_CLK_GATE | CGU_CLK_FIXDIV);
+
+       if (caps & CGU_CLK_MUX) {
+               if (!(caps & CGU_CLK_MUX_GLITCHFREE))
+                       clk_init.flags |= CLK_SET_PARENT_GATE;
+
+               caps &= ~(CGU_CLK_MUX | CGU_CLK_MUX_GLITCHFREE);
+       }
+
+       if (caps & CGU_CLK_DIV) {
+               caps &= ~CGU_CLK_DIV;
+       } else {
+               /* pass rate changes to the parent clock */
+               clk_init.flags |= CLK_SET_RATE_PARENT;
+       }
+
+       if (caps) {
+               pr_err("%s: unknown clock type 0x%x\n", __func__, caps);
+               goto out;
+       }
+
+       clk = clk_register(NULL, &ingenic_clk->hw);
+       if (IS_ERR(clk)) {
+               pr_err("%s: failed to register clock '%s'\n", __func__,
+                      clk_info->name);
+               err = PTR_ERR(clk);
+               goto out;
+       }
+
+       err = clk_register_clkdev(clk, clk_info->name, NULL);
+       if (err)
+               goto out;
+
+       cgu->clocks.clks[idx] = clk;
+out:
+       if (err)
+               kfree(ingenic_clk);
+       return err;
+}
+
+struct ingenic_cgu *
+ingenic_cgu_new(const struct ingenic_cgu_clk_info *clock_info,
+               unsigned num_clocks, struct device_node *np)
+{
+       struct ingenic_cgu *cgu;
+
+       cgu = kzalloc(sizeof(*cgu), GFP_KERNEL);
+       if (!cgu)
+               goto err_out;
+
+       cgu->base = of_iomap(np, 0);
+       if (!cgu->base) {
+               pr_err("%s: failed to map CGU registers\n", __func__);
+               goto err_out_free;
+       }
+
+       cgu->np = np;
+       cgu->clock_info = clock_info;
+       cgu->clocks.clk_num = num_clocks;
+
+       spin_lock_init(&cgu->lock);
+
+       return cgu;
+
+err_out_free:
+       kfree(cgu);
+err_out:
+       return NULL;
+}
+
+int ingenic_cgu_register_clocks(struct ingenic_cgu *cgu)
+{
+       unsigned i;
+       int err;
+
+       cgu->clocks.clks = kcalloc(cgu->clocks.clk_num, sizeof(struct clk *),
+                                  GFP_KERNEL);
+       if (!cgu->clocks.clks) {
+               err = -ENOMEM;
+               goto err_out;
+       }
+
+       for (i = 0; i < cgu->clocks.clk_num; i++) {
+               err = ingenic_register_clock(cgu, i);
+               if (err)
+                       goto err_out_unregister;
+       }
+
+       err = of_clk_add_provider(cgu->np, of_clk_src_onecell_get,
+                                 &cgu->clocks);
+       if (err)
+               goto err_out_unregister;
+
+       return 0;
+
+err_out_unregister:
+       for (i = 0; i < cgu->clocks.clk_num; i++) {
+               if (!cgu->clocks.clks[i])
+                       continue;
+               if (cgu->clock_info[i].type & CGU_CLK_EXT)
+                       clk_put(cgu->clocks.clks[i]);
+               else
+                       clk_unregister(cgu->clocks.clks[i]);
+       }
+       kfree(cgu->clocks.clks);
+err_out:
+       return err;
+}
diff --git a/drivers/clk/ingenic/cgu.h b/drivers/clk/ingenic/cgu.h
new file mode 100644 (file)
index 0000000..99347e2
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * Ingenic SoC CGU driver
+ *
+ * Copyright (c) 2013-2015 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.
+ *
+ * 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.
+ */
+
+#ifndef __DRIVERS_CLK_INGENIC_CGU_H__
+#define __DRIVERS_CLK_INGENIC_CGU_H__
+
+#include <linux/bitops.h>
+#include <linux/of.h>
+#include <linux/spinlock.h>
+
+/**
+ * struct ingenic_cgu_pll_info - information about a PLL
+ * @reg: the offset of the PLL's control register within the CGU
+ * @m_shift: the number of bits to shift the multiplier value by (ie. the
+ *           index of the lowest bit of the multiplier value in the PLL's
+ *           control register)
+ * @m_bits: the size of the multiplier field in bits
+ * @m_offset: the multiplier value which encodes to 0 in the PLL's control
+ *            register
+ * @n_shift: the number of bits to shift the divider value by (ie. the
+ *           index of the lowest bit of the divider value in the PLL's
+ *           control register)
+ * @n_bits: the size of the divider field in bits
+ * @n_offset: the divider value which encodes to 0 in the PLL's control
+ *            register
+ * @od_shift: the number of bits to shift the post-VCO divider value by (ie.
+ *            the index of the lowest bit of the post-VCO divider value in
+ *            the PLL's control register)
+ * @od_bits: the size of the post-VCO divider field in bits
+ * @od_max: the maximum post-VCO divider value
+ * @od_encoding: a pointer to an array mapping post-VCO divider values to
+ *               their encoded values in the PLL control register, or -1 for
+ *               unsupported values
+ * @bypass_bit: the index of the bypass bit in the PLL control register
+ * @enable_bit: the index of the enable bit in the PLL control register
+ * @stable_bit: the index of the stable bit in the PLL control register
+ */
+struct ingenic_cgu_pll_info {
+       unsigned reg;
+       const s8 *od_encoding;
+       u8 m_shift, m_bits, m_offset;
+       u8 n_shift, n_bits, n_offset;
+       u8 od_shift, od_bits, od_max;
+       u8 bypass_bit;
+       u8 enable_bit;
+       u8 stable_bit;
+};
+
+/**
+ * struct ingenic_cgu_mux_info - information about a clock mux
+ * @reg: offset of the mux control register within the CGU
+ * @shift: number of bits to shift the mux value by (ie. the index of
+ *         the lowest bit of the mux value within its control register)
+ * @bits: the size of the mux value in bits
+ */
+struct ingenic_cgu_mux_info {
+       unsigned reg;
+       u8 shift;
+       u8 bits;
+};
+
+/**
+ * struct ingenic_cgu_div_info - information about a divider
+ * @reg: offset of the divider control register within the CGU
+ * @shift: number of bits to shift the divide value by (ie. the index of
+ *         the lowest bit of the divide value within its control register)
+ * @bits: the size of the divide value in bits
+ * @ce_bit: the index of the change enable bit within reg, or -1 if there
+ *          isn't one
+ * @busy_bit: the index of the busy bit within reg, or -1 if there isn't one
+ * @stop_bit: the index of the stop bit within reg, or -1 if there isn't one
+ */
+struct ingenic_cgu_div_info {
+       unsigned reg;
+       u8 shift;
+       u8 bits;
+       s8 ce_bit;
+       s8 busy_bit;
+       s8 stop_bit;
+};
+
+/**
+ * struct ingenic_cgu_fixdiv_info - information about a fixed divider
+ * @div: the divider applied to the parent clock
+ */
+struct ingenic_cgu_fixdiv_info {
+       unsigned div;
+};
+
+/**
+ * struct ingenic_cgu_gate_info - information about a clock gate
+ * @reg: offset of the gate control register within the CGU
+ * @bit: offset of the bit in the register that controls the gate
+ */
+struct ingenic_cgu_gate_info {
+       unsigned reg;
+       u8 bit;
+};
+
+/**
+ * struct ingenic_cgu_custom_info - information about a custom (SoC) clock
+ * @clk_ops: custom clock operation callbacks
+ */
+struct ingenic_cgu_custom_info {
+       struct clk_ops *clk_ops;
+};
+
+/**
+ * struct ingenic_cgu_clk_info - information about a clock
+ * @name: name of the clock
+ * @type: a bitmask formed from CGU_CLK_* values
+ * @parents: an array of the indices of potential parents of this clock
+ *           within the clock_info array of the CGU, or -1 in entries
+ *           which correspond to no valid parent
+ * @pll: information valid if type includes CGU_CLK_PLL
+ * @gate: information valid if type includes CGU_CLK_GATE
+ * @mux: information valid if type includes CGU_CLK_MUX
+ * @div: information valid if type includes CGU_CLK_DIV
+ * @fixdiv: information valid if type includes CGU_CLK_FIXDIV
+ * @custom: information valid if type includes CGU_CLK_CUSTOM
+ */
+struct ingenic_cgu_clk_info {
+       const char *name;
+
+       enum {
+               CGU_CLK_NONE            = 0,
+               CGU_CLK_EXT             = BIT(0),
+               CGU_CLK_PLL             = BIT(1),
+               CGU_CLK_GATE            = BIT(2),
+               CGU_CLK_MUX             = BIT(3),
+               CGU_CLK_MUX_GLITCHFREE  = BIT(4),
+               CGU_CLK_DIV             = BIT(5),
+               CGU_CLK_FIXDIV          = BIT(6),
+               CGU_CLK_CUSTOM          = BIT(7),
+       } type;
+
+       int parents[4];
+
+       union {
+               struct ingenic_cgu_pll_info pll;
+
+               struct {
+                       struct ingenic_cgu_gate_info gate;
+                       struct ingenic_cgu_mux_info mux;
+                       struct ingenic_cgu_div_info div;
+                       struct ingenic_cgu_fixdiv_info fixdiv;
+               };
+
+               struct ingenic_cgu_custom_info custom;
+       };
+};
+
+/**
+ * struct ingenic_cgu - data about the CGU
+ * @np: the device tree node that caused the CGU to be probed
+ * @base: the ioremap'ed base address of the CGU registers
+ * @clock_info: an array containing information about implemented clocks
+ * @clocks: used to provide clocks to DT, allows lookup of struct clk*
+ * @lock: lock to be held whilst manipulating CGU registers
+ */
+struct ingenic_cgu {
+       struct device_node *np;
+       void __iomem *base;
+
+       const struct ingenic_cgu_clk_info *clock_info;
+       struct clk_onecell_data clocks;
+
+       spinlock_t lock;
+};
+
+/**
+ * struct ingenic_clk - private data for a clock
+ * @hw: see Documentation/clk.txt
+ * @cgu: a pointer to the CGU data
+ * @idx: the index of this clock in cgu->clock_info
+ */
+struct ingenic_clk {
+       struct clk_hw hw;
+       struct ingenic_cgu *cgu;
+       unsigned idx;
+};
+
+#define to_ingenic_clk(_hw) container_of(_hw, struct ingenic_clk, hw)
+
+/**
+ * ingenic_cgu_new() - create a new CGU instance
+ * @clock_info: an array of clock information structures describing the clocks
+ *              which are implemented by the CGU
+ * @num_clocks: the number of entries in clock_info
+ * @np: the device tree node which causes this CGU to be probed
+ *
+ * Return: a pointer to the CGU instance if initialisation is successful,
+ *         otherwise NULL.
+ */
+struct ingenic_cgu *
+ingenic_cgu_new(const struct ingenic_cgu_clk_info *clock_info,
+               unsigned num_clocks, struct device_node *np);
+
+/**
+ * ingenic_cgu_register_clocks() - Registers the clocks
+ * @cgu: pointer to cgu data
+ *
+ * Register the clocks described by the CGU with the common clock framework.
+ *
+ * Return: 0 on success or -errno if unsuccesful.
+ */
+int ingenic_cgu_register_clocks(struct ingenic_cgu *cgu);
+
+#endif /* __DRIVERS_CLK_INGENIC_CGU_H__ */
diff --git a/drivers/clk/ingenic/jz4740-cgu.c b/drivers/clk/ingenic/jz4740-cgu.c
new file mode 100644 (file)
index 0000000..305a26c
--- /dev/null
@@ -0,0 +1,303 @@
+/*
+ * Ingenic JZ4740 SoC CGU driver
+ *
+ * Copyright (c) 2015 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.
+ *
+ * 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.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <dt-bindings/clock/jz4740-cgu.h>
+#include <asm/mach-jz4740/clock.h>
+#include "cgu.h"
+
+/* CGU register offsets */
+#define CGU_REG_CPCCR          0x00
+#define CGU_REG_LCR            0x04
+#define CGU_REG_CPPCR          0x10
+#define CGU_REG_CLKGR          0x20
+#define CGU_REG_SCR            0x24
+#define CGU_REG_I2SCDR         0x60
+#define CGU_REG_LPCDR          0x64
+#define CGU_REG_MSCCDR         0x68
+#define CGU_REG_UHCCDR         0x6c
+#define CGU_REG_SSICDR         0x74
+
+/* bits within a PLL control register */
+#define PLLCTL_M_SHIFT         23
+#define PLLCTL_M_MASK          (0x1ff << PLLCTL_M_SHIFT)
+#define PLLCTL_N_SHIFT         18
+#define PLLCTL_N_MASK          (0x1f << PLLCTL_N_SHIFT)
+#define PLLCTL_OD_SHIFT                16
+#define PLLCTL_OD_MASK         (0x3 << PLLCTL_OD_SHIFT)
+#define PLLCTL_STABLE          (1 << 10)
+#define PLLCTL_BYPASS          (1 << 9)
+#define PLLCTL_ENABLE          (1 << 8)
+
+/* bits within the LCR register */
+#define LCR_SLEEP              (1 << 0)
+
+/* bits within the CLKGR register */
+#define CLKGR_UDC              (1 << 11)
+
+static struct ingenic_cgu *cgu;
+
+static const s8 pll_od_encoding[4] = {
+       0x0, 0x1, -1, 0x3,
+};
+
+static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
+
+       /* External clocks */
+
+       [JZ4740_CLK_EXT] = { "ext", CGU_CLK_EXT },
+       [JZ4740_CLK_RTC] = { "rtc", CGU_CLK_EXT },
+
+       [JZ4740_CLK_PLL] = {
+               "pll", CGU_CLK_PLL,
+               .parents = { JZ4740_CLK_EXT, -1, -1, -1 },
+               .pll = {
+                       .reg = CGU_REG_CPPCR,
+                       .m_shift = 23,
+                       .m_bits = 9,
+                       .m_offset = 2,
+                       .n_shift = 18,
+                       .n_bits = 5,
+                       .n_offset = 2,
+                       .od_shift = 16,
+                       .od_bits = 2,
+                       .od_max = 4,
+                       .od_encoding = pll_od_encoding,
+                       .stable_bit = 10,
+                       .bypass_bit = 9,
+                       .enable_bit = 8,
+               },
+       },
+
+       /* Muxes & dividers */
+
+       [JZ4740_CLK_PLL_HALF] = {
+               "pll half", CGU_CLK_DIV,
+               .parents = { JZ4740_CLK_PLL, -1, -1, -1 },
+               .div = { CGU_REG_CPCCR, 21, 1, -1, -1, -1 },
+       },
+
+       [JZ4740_CLK_CCLK] = {
+               "cclk", CGU_CLK_DIV,
+               .parents = { JZ4740_CLK_PLL, -1, -1, -1 },
+               .div = { CGU_REG_CPCCR, 0, 4, 22, -1, -1 },
+       },
+
+       [JZ4740_CLK_HCLK] = {
+               "hclk", CGU_CLK_DIV,
+               .parents = { JZ4740_CLK_PLL, -1, -1, -1 },
+               .div = { CGU_REG_CPCCR, 4, 4, 22, -1, -1 },
+       },
+
+       [JZ4740_CLK_PCLK] = {
+               "pclk", CGU_CLK_DIV,
+               .parents = { JZ4740_CLK_PLL, -1, -1, -1 },
+               .div = { CGU_REG_CPCCR, 8, 4, 22, -1, -1 },
+       },
+
+       [JZ4740_CLK_MCLK] = {
+               "mclk", CGU_CLK_DIV,
+               .parents = { JZ4740_CLK_PLL, -1, -1, -1 },
+               .div = { CGU_REG_CPCCR, 12, 4, 22, -1, -1 },
+       },
+
+       [JZ4740_CLK_LCD] = {
+               "lcd", CGU_CLK_DIV | CGU_CLK_GATE,
+               .parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 },
+               .div = { CGU_REG_CPCCR, 16, 5, 22, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 10 },
+       },
+
+       [JZ4740_CLK_LCD_PCLK] = {
+               "lcd_pclk", CGU_CLK_DIV,
+               .parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 },
+               .div = { CGU_REG_LPCDR, 0, 11, -1, -1, -1 },
+       },
+
+       [JZ4740_CLK_I2S] = {
+               "i2s", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+               .parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1, -1 },
+               .mux = { CGU_REG_CPCCR, 31, 1 },
+               .div = { CGU_REG_I2SCDR, 0, 8, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 6 },
+       },
+
+       [JZ4740_CLK_SPI] = {
+               "spi", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+               .parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL, -1, -1 },
+               .mux = { CGU_REG_SSICDR, 31, 1 },
+               .div = { CGU_REG_SSICDR, 0, 4, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 4 },
+       },
+
+       [JZ4740_CLK_MMC] = {
+               "mmc", CGU_CLK_DIV | CGU_CLK_GATE,
+               .parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 },
+               .div = { CGU_REG_MSCCDR, 0, 5, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 7 },
+       },
+
+       [JZ4740_CLK_UHC] = {
+               "uhc", CGU_CLK_DIV | CGU_CLK_GATE,
+               .parents = { JZ4740_CLK_PLL_HALF, -1, -1, -1 },
+               .div = { CGU_REG_UHCCDR, 0, 4, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 14 },
+       },
+
+       [JZ4740_CLK_UDC] = {
+               "udc", CGU_CLK_MUX | CGU_CLK_DIV,
+               .parents = { JZ4740_CLK_EXT, JZ4740_CLK_PLL_HALF, -1, -1 },
+               .mux = { CGU_REG_CPCCR, 29, 1 },
+               .div = { CGU_REG_CPCCR, 23, 6, -1, -1, -1 },
+               .gate = { CGU_REG_SCR, 6 },
+       },
+
+       /* Gate-only clocks */
+
+       [JZ4740_CLK_UART0] = {
+               "uart0", CGU_CLK_GATE,
+               .parents = { JZ4740_CLK_EXT, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 0 },
+       },
+
+       [JZ4740_CLK_UART1] = {
+               "uart1", CGU_CLK_GATE,
+               .parents = { JZ4740_CLK_EXT, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 15 },
+       },
+
+       [JZ4740_CLK_DMA] = {
+               "dma", CGU_CLK_GATE,
+               .parents = { JZ4740_CLK_PCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 12 },
+       },
+
+       [JZ4740_CLK_IPU] = {
+               "ipu", CGU_CLK_GATE,
+               .parents = { JZ4740_CLK_PCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 13 },
+       },
+
+       [JZ4740_CLK_ADC] = {
+               "adc", CGU_CLK_GATE,
+               .parents = { JZ4740_CLK_EXT, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 8 },
+       },
+
+       [JZ4740_CLK_I2C] = {
+               "i2c", CGU_CLK_GATE,
+               .parents = { JZ4740_CLK_EXT, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 3 },
+       },
+
+       [JZ4740_CLK_AIC] = {
+               "aic", CGU_CLK_GATE,
+               .parents = { JZ4740_CLK_EXT, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR, 5 },
+       },
+};
+
+static void __init jz4740_cgu_init(struct device_node *np)
+{
+       int retval;
+
+       cgu = ingenic_cgu_new(jz4740_cgu_clocks,
+                             ARRAY_SIZE(jz4740_cgu_clocks), np);
+       if (!cgu) {
+               pr_err("%s: failed to initialise CGU\n", __func__);
+               return;
+       }
+
+       retval = ingenic_cgu_register_clocks(cgu);
+       if (retval)
+               pr_err("%s: failed to register CGU Clocks\n", __func__);
+}
+CLK_OF_DECLARE(jz4740_cgu, "ingenic,jz4740-cgu", jz4740_cgu_init);
+
+void jz4740_clock_set_wait_mode(enum jz4740_wait_mode mode)
+{
+       uint32_t lcr = readl(cgu->base + CGU_REG_LCR);
+
+       switch (mode) {
+       case JZ4740_WAIT_MODE_IDLE:
+               lcr &= ~LCR_SLEEP;
+               break;
+
+       case JZ4740_WAIT_MODE_SLEEP:
+               lcr |= LCR_SLEEP;
+               break;
+       }
+
+       writel(lcr, cgu->base + CGU_REG_LCR);
+}
+
+void jz4740_clock_udc_disable_auto_suspend(void)
+{
+       uint32_t clkgr = readl(cgu->base + CGU_REG_CLKGR);
+
+       clkgr &= ~CLKGR_UDC;
+       writel(clkgr, cgu->base + CGU_REG_CLKGR);
+}
+EXPORT_SYMBOL_GPL(jz4740_clock_udc_disable_auto_suspend);
+
+void jz4740_clock_udc_enable_auto_suspend(void)
+{
+       uint32_t clkgr = readl(cgu->base + CGU_REG_CLKGR);
+
+       clkgr |= CLKGR_UDC;
+       writel(clkgr, cgu->base + CGU_REG_CLKGR);
+}
+EXPORT_SYMBOL_GPL(jz4740_clock_udc_enable_auto_suspend);
+
+#define JZ_CLOCK_GATE_UART0    BIT(0)
+#define JZ_CLOCK_GATE_TCU      BIT(1)
+#define JZ_CLOCK_GATE_DMAC     BIT(12)
+
+void jz4740_clock_suspend(void)
+{
+       uint32_t clkgr, cppcr;
+
+       clkgr = readl(cgu->base + CGU_REG_CLKGR);
+       clkgr |= JZ_CLOCK_GATE_TCU | JZ_CLOCK_GATE_DMAC | JZ_CLOCK_GATE_UART0;
+       writel(clkgr, cgu->base + CGU_REG_CLKGR);
+
+       cppcr = readl(cgu->base + CGU_REG_CPPCR);
+       cppcr &= ~BIT(jz4740_cgu_clocks[JZ4740_CLK_PLL].pll.enable_bit);
+       writel(cppcr, cgu->base + CGU_REG_CPPCR);
+}
+
+void jz4740_clock_resume(void)
+{
+       uint32_t clkgr, cppcr, stable;
+
+       cppcr = readl(cgu->base + CGU_REG_CPPCR);
+       cppcr |= BIT(jz4740_cgu_clocks[JZ4740_CLK_PLL].pll.enable_bit);
+       writel(cppcr, cgu->base + CGU_REG_CPPCR);
+
+       stable = BIT(jz4740_cgu_clocks[JZ4740_CLK_PLL].pll.stable_bit);
+       do {
+               cppcr = readl(cgu->base + CGU_REG_CPPCR);
+       } while (!(cppcr & stable));
+
+       clkgr = readl(cgu->base + CGU_REG_CLKGR);
+       clkgr &= ~JZ_CLOCK_GATE_TCU;
+       clkgr &= ~JZ_CLOCK_GATE_DMAC;
+       clkgr &= ~JZ_CLOCK_GATE_UART0;
+       writel(clkgr, cgu->base + CGU_REG_CLKGR);
+}
diff --git a/drivers/clk/ingenic/jz4780-cgu.c b/drivers/clk/ingenic/jz4780-cgu.c
new file mode 100644 (file)
index 0000000..431f962
--- /dev/null
@@ -0,0 +1,733 @@
+/*
+ * Ingenic JZ4780 SoC CGU driver
+ *
+ * Copyright (c) 2013-2015 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.
+ *
+ * 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.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <dt-bindings/clock/jz4780-cgu.h>
+#include "cgu.h"
+
+/* CGU register offsets */
+#define CGU_REG_CLOCKCONTROL   0x00
+#define CGU_REG_PLLCONTROL     0x0c
+#define CGU_REG_APLL           0x10
+#define CGU_REG_MPLL           0x14
+#define CGU_REG_EPLL           0x18
+#define CGU_REG_VPLL           0x1c
+#define CGU_REG_CLKGR0         0x20
+#define CGU_REG_OPCR           0x24
+#define CGU_REG_CLKGR1         0x28
+#define CGU_REG_DDRCDR         0x2c
+#define CGU_REG_VPUCDR         0x30
+#define CGU_REG_USBPCR         0x3c
+#define CGU_REG_USBRDT         0x40
+#define CGU_REG_USBVBFIL       0x44
+#define CGU_REG_USBPCR1                0x48
+#define CGU_REG_LP0CDR         0x54
+#define CGU_REG_I2SCDR         0x60
+#define CGU_REG_LP1CDR         0x64
+#define CGU_REG_MSC0CDR                0x68
+#define CGU_REG_UHCCDR         0x6c
+#define CGU_REG_SSICDR         0x74
+#define CGU_REG_CIMCDR         0x7c
+#define CGU_REG_PCMCDR         0x84
+#define CGU_REG_GPUCDR         0x88
+#define CGU_REG_HDMICDR                0x8c
+#define CGU_REG_MSC1CDR                0xa4
+#define CGU_REG_MSC2CDR                0xa8
+#define CGU_REG_BCHCDR         0xac
+#define CGU_REG_CLOCKSTATUS    0xd4
+
+/* bits within the OPCR register */
+#define OPCR_SPENDN0           (1 << 7)
+#define OPCR_SPENDN1           (1 << 6)
+
+/* bits within the USBPCR register */
+#define USBPCR_USB_MODE                BIT(31)
+#define USBPCR_IDPULLUP_MASK   (0x3 << 28)
+#define USBPCR_COMMONONN       BIT(25)
+#define USBPCR_VBUSVLDEXT      BIT(24)
+#define USBPCR_VBUSVLDEXTSEL   BIT(23)
+#define USBPCR_POR             BIT(22)
+#define USBPCR_OTG_DISABLE     BIT(20)
+#define USBPCR_COMPDISTUNE_MASK        (0x7 << 17)
+#define USBPCR_OTGTUNE_MASK    (0x7 << 14)
+#define USBPCR_SQRXTUNE_MASK   (0x7 << 11)
+#define USBPCR_TXFSLSTUNE_MASK (0xf << 7)
+#define USBPCR_TXPREEMPHTUNE   BIT(6)
+#define USBPCR_TXHSXVTUNE_MASK (0x3 << 4)
+#define USBPCR_TXVREFTUNE_MASK 0xf
+
+/* bits within the USBPCR1 register */
+#define USBPCR1_REFCLKSEL_SHIFT        26
+#define USBPCR1_REFCLKSEL_MASK (0x3 << USBPCR1_REFCLKSEL_SHIFT)
+#define USBPCR1_REFCLKSEL_CORE (0x2 << USBPCR1_REFCLKSEL_SHIFT)
+#define USBPCR1_REFCLKDIV_SHIFT        24
+#define USBPCR1_REFCLKDIV_MASK (0x3 << USBPCR1_REFCLKDIV_SHIFT)
+#define USBPCR1_REFCLKDIV_19_2 (0x3 << USBPCR1_REFCLKDIV_SHIFT)
+#define USBPCR1_REFCLKDIV_48   (0x2 << USBPCR1_REFCLKDIV_SHIFT)
+#define USBPCR1_REFCLKDIV_24   (0x1 << USBPCR1_REFCLKDIV_SHIFT)
+#define USBPCR1_REFCLKDIV_12   (0x0 << USBPCR1_REFCLKDIV_SHIFT)
+#define USBPCR1_USB_SEL                BIT(28)
+#define USBPCR1_WORD_IF0       BIT(19)
+#define USBPCR1_WORD_IF1       BIT(18)
+
+/* bits within the USBRDT register */
+#define USBRDT_VBFIL_LD_EN     BIT(25)
+#define USBRDT_USBRDT_MASK     0x7fffff
+
+/* bits within the USBVBFIL register */
+#define USBVBFIL_IDDIGFIL_SHIFT        16
+#define USBVBFIL_IDDIGFIL_MASK (0xffff << USBVBFIL_IDDIGFIL_SHIFT)
+#define USBVBFIL_USBVBFIL_MASK (0xffff)
+
+static struct ingenic_cgu *cgu;
+
+static u8 jz4780_otg_phy_get_parent(struct clk_hw *hw)
+{
+       /* we only use CLKCORE, revisit if that ever changes */
+       return 0;
+}
+
+static int jz4780_otg_phy_set_parent(struct clk_hw *hw, u8 idx)
+{
+       unsigned long flags;
+       u32 usbpcr1;
+
+       if (idx > 0)
+               return -EINVAL;
+
+       spin_lock_irqsave(&cgu->lock, flags);
+
+       usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1);
+       usbpcr1 &= ~USBPCR1_REFCLKSEL_MASK;
+       /* we only use CLKCORE */
+       usbpcr1 |= USBPCR1_REFCLKSEL_CORE;
+       writel(usbpcr1, cgu->base + CGU_REG_USBPCR1);
+
+       spin_unlock_irqrestore(&cgu->lock, flags);
+       return 0;
+}
+
+static unsigned long jz4780_otg_phy_recalc_rate(struct clk_hw *hw,
+                                               unsigned long parent_rate)
+{
+       u32 usbpcr1;
+       unsigned refclk_div;
+
+       usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1);
+       refclk_div = usbpcr1 & USBPCR1_REFCLKDIV_MASK;
+
+       switch (refclk_div) {
+       case USBPCR1_REFCLKDIV_12:
+               return 12000000;
+
+       case USBPCR1_REFCLKDIV_24:
+               return 24000000;
+
+       case USBPCR1_REFCLKDIV_48:
+               return 48000000;
+
+       case USBPCR1_REFCLKDIV_19_2:
+               return 19200000;
+       }
+
+       BUG();
+       return parent_rate;
+}
+
+static long jz4780_otg_phy_round_rate(struct clk_hw *hw, unsigned long req_rate,
+                                     unsigned long *parent_rate)
+{
+       if (req_rate < 15600000)
+               return 12000000;
+
+       if (req_rate < 21600000)
+               return 19200000;
+
+       if (req_rate < 36000000)
+               return 24000000;
+
+       return 48000000;
+}
+
+static int jz4780_otg_phy_set_rate(struct clk_hw *hw, unsigned long req_rate,
+                                  unsigned long parent_rate)
+{
+       unsigned long flags;
+       u32 usbpcr1, div_bits;
+
+       switch (req_rate) {
+       case 12000000:
+               div_bits = USBPCR1_REFCLKDIV_12;
+               break;
+
+       case 19200000:
+               div_bits = USBPCR1_REFCLKDIV_19_2;
+               break;
+
+       case 24000000:
+               div_bits = USBPCR1_REFCLKDIV_24;
+               break;
+
+       case 48000000:
+               div_bits = USBPCR1_REFCLKDIV_48;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       spin_lock_irqsave(&cgu->lock, flags);
+
+       usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1);
+       usbpcr1 &= ~USBPCR1_REFCLKDIV_MASK;
+       usbpcr1 |= div_bits;
+       writel(usbpcr1, cgu->base + CGU_REG_USBPCR1);
+
+       spin_unlock_irqrestore(&cgu->lock, flags);
+       return 0;
+}
+
+static struct clk_ops jz4780_otg_phy_ops = {
+       .get_parent = jz4780_otg_phy_get_parent,
+       .set_parent = jz4780_otg_phy_set_parent,
+
+       .recalc_rate = jz4780_otg_phy_recalc_rate,
+       .round_rate = jz4780_otg_phy_round_rate,
+       .set_rate = jz4780_otg_phy_set_rate,
+};
+
+static const s8 pll_od_encoding[16] = {
+       0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
+       0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
+};
+
+static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
+
+       /* External clocks */
+
+       [JZ4780_CLK_EXCLK] = { "ext", CGU_CLK_EXT },
+       [JZ4780_CLK_RTCLK] = { "rtc", CGU_CLK_EXT },
+
+       /* PLLs */
+
+#define DEF_PLL(name) { \
+       .reg = CGU_REG_ ## name, \
+       .m_shift = 19, \
+       .m_bits = 13, \
+       .m_offset = 1, \
+       .n_shift = 13, \
+       .n_bits = 6, \
+       .n_offset = 1, \
+       .od_shift = 9, \
+       .od_bits = 4, \
+       .od_max = 16, \
+       .od_encoding = pll_od_encoding, \
+       .stable_bit = 6, \
+       .bypass_bit = 1, \
+       .enable_bit = 0, \
+}
+
+       [JZ4780_CLK_APLL] = {
+               "apll", CGU_CLK_PLL,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .pll = DEF_PLL(APLL),
+       },
+
+       [JZ4780_CLK_MPLL] = {
+               "mpll", CGU_CLK_PLL,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .pll = DEF_PLL(MPLL),
+       },
+
+       [JZ4780_CLK_EPLL] = {
+               "epll", CGU_CLK_PLL,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .pll = DEF_PLL(EPLL),
+       },
+
+       [JZ4780_CLK_VPLL] = {
+               "vpll", CGU_CLK_PLL,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .pll = DEF_PLL(VPLL),
+       },
+
+#undef DEF_PLL
+
+       /* Custom (SoC-specific) OTG PHY */
+
+       [JZ4780_CLK_OTGPHY] = {
+               "otg_phy", CGU_CLK_CUSTOM,
+               .parents = { -1, -1, JZ4780_CLK_EXCLK, -1 },
+               .custom = { &jz4780_otg_phy_ops },
+       },
+
+       /* Muxes & dividers */
+
+       [JZ4780_CLK_SCLKA] = {
+               "sclk_a", CGU_CLK_MUX,
+               .parents = { -1, JZ4780_CLK_APLL, JZ4780_CLK_EXCLK,
+                            JZ4780_CLK_RTCLK },
+               .mux = { CGU_REG_CLOCKCONTROL, 30, 2 },
+       },
+
+       [JZ4780_CLK_CPUMUX] = {
+               "cpumux", CGU_CLK_MUX,
+               .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+                            JZ4780_CLK_EPLL },
+               .mux = { CGU_REG_CLOCKCONTROL, 28, 2 },
+       },
+
+       [JZ4780_CLK_CPU] = {
+               "cpu", CGU_CLK_DIV,
+               .parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 },
+               .div = { CGU_REG_CLOCKCONTROL, 0, 4, 22, -1, -1 },
+       },
+
+       [JZ4780_CLK_L2CACHE] = {
+               "l2cache", CGU_CLK_DIV,
+               .parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 },
+               .div = { CGU_REG_CLOCKCONTROL, 4, 4, -1, -1, -1 },
+       },
+
+       [JZ4780_CLK_AHB0] = {
+               "ahb0", CGU_CLK_MUX | CGU_CLK_DIV,
+               .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+                            JZ4780_CLK_EPLL },
+               .mux = { CGU_REG_CLOCKCONTROL, 26, 2 },
+               .div = { CGU_REG_CLOCKCONTROL, 8, 4, 21, -1, -1 },
+       },
+
+       [JZ4780_CLK_AHB2PMUX] = {
+               "ahb2_apb_mux", CGU_CLK_MUX,
+               .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+                            JZ4780_CLK_RTCLK },
+               .mux = { CGU_REG_CLOCKCONTROL, 24, 2 },
+       },
+
+       [JZ4780_CLK_AHB2] = {
+               "ahb2", CGU_CLK_DIV,
+               .parents = { JZ4780_CLK_AHB2PMUX, -1, -1, -1 },
+               .div = { CGU_REG_CLOCKCONTROL, 12, 4, 20, -1, -1 },
+       },
+
+       [JZ4780_CLK_PCLK] = {
+               "pclk", CGU_CLK_DIV,
+               .parents = { JZ4780_CLK_AHB2PMUX, -1, -1, -1 },
+               .div = { CGU_REG_CLOCKCONTROL, 16, 4, 20, -1, -1 },
+       },
+
+       [JZ4780_CLK_DDR] = {
+               "ddr", CGU_CLK_MUX | CGU_CLK_DIV,
+               .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 },
+               .mux = { CGU_REG_DDRCDR, 30, 2 },
+               .div = { CGU_REG_DDRCDR, 0, 4, 29, 28, 27 },
+       },
+
+       [JZ4780_CLK_VPU] = {
+               "vpu", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+                            JZ4780_CLK_EPLL, -1 },
+               .mux = { CGU_REG_VPUCDR, 30, 2 },
+               .div = { CGU_REG_VPUCDR, 0, 4, 29, 28, 27 },
+               .gate = { CGU_REG_CLKGR1, 2 },
+       },
+
+       [JZ4780_CLK_I2SPLL] = {
+               "i2s_pll", CGU_CLK_MUX | CGU_CLK_DIV,
+               .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_EPLL, -1, -1 },
+               .mux = { CGU_REG_I2SCDR, 30, 1 },
+               .div = { CGU_REG_I2SCDR, 0, 8, 29, 28, 27 },
+       },
+
+       [JZ4780_CLK_I2S] = {
+               "i2s", CGU_CLK_MUX,
+               .parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_I2SPLL, -1, -1 },
+               .mux = { CGU_REG_I2SCDR, 31, 1 },
+       },
+
+       [JZ4780_CLK_LCD0PIXCLK] = {
+               "lcd0pixclk", CGU_CLK_MUX | CGU_CLK_DIV,
+               .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+                            JZ4780_CLK_VPLL, -1 },
+               .mux = { CGU_REG_LP0CDR, 30, 2 },
+               .div = { CGU_REG_LP0CDR, 0, 8, 28, 27, 26 },
+       },
+
+       [JZ4780_CLK_LCD1PIXCLK] = {
+               "lcd1pixclk", CGU_CLK_MUX | CGU_CLK_DIV,
+               .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+                            JZ4780_CLK_VPLL, -1 },
+               .mux = { CGU_REG_LP1CDR, 30, 2 },
+               .div = { CGU_REG_LP1CDR, 0, 8, 28, 27, 26 },
+       },
+
+       [JZ4780_CLK_MSCMUX] = {
+               "msc_mux", CGU_CLK_MUX,
+               .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 },
+               .mux = { CGU_REG_MSC0CDR, 30, 2 },
+       },
+
+       [JZ4780_CLK_MSC0] = {
+               "msc0", CGU_CLK_DIV | CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 },
+               .div = { CGU_REG_MSC0CDR, 0, 8, 29, 28, 27 },
+               .gate = { CGU_REG_CLKGR0, 3 },
+       },
+
+       [JZ4780_CLK_MSC1] = {
+               "msc1", CGU_CLK_DIV | CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 },
+               .div = { CGU_REG_MSC1CDR, 0, 8, 29, 28, 27 },
+               .gate = { CGU_REG_CLKGR0, 11 },
+       },
+
+       [JZ4780_CLK_MSC2] = {
+               "msc2", CGU_CLK_DIV | CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 },
+               .div = { CGU_REG_MSC2CDR, 0, 8, 29, 28, 27 },
+               .gate = { CGU_REG_CLKGR0, 12 },
+       },
+
+       [JZ4780_CLK_UHC] = {
+               "uhc", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+                            JZ4780_CLK_EPLL, JZ4780_CLK_OTGPHY },
+               .mux = { CGU_REG_UHCCDR, 30, 2 },
+               .div = { CGU_REG_UHCCDR, 0, 8, 29, 28, 27 },
+               .gate = { CGU_REG_CLKGR0, 24 },
+       },
+
+       [JZ4780_CLK_SSIPLL] = {
+               "ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV,
+               .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1, -1 },
+               .mux = { CGU_REG_SSICDR, 30, 1 },
+               .div = { CGU_REG_SSICDR, 0, 8, 29, 28, 27 },
+       },
+
+       [JZ4780_CLK_SSI] = {
+               "ssi", CGU_CLK_MUX,
+               .parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_SSIPLL, -1, -1 },
+               .mux = { CGU_REG_SSICDR, 31, 1 },
+       },
+
+       [JZ4780_CLK_CIMMCLK] = {
+               "cim_mclk", CGU_CLK_MUX | CGU_CLK_DIV,
+               .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1, -1 },
+               .mux = { CGU_REG_CIMCDR, 31, 1 },
+               .div = { CGU_REG_CIMCDR, 0, 8, 30, 29, 28 },
+       },
+
+       [JZ4780_CLK_PCMPLL] = {
+               "pcm_pll", CGU_CLK_MUX | CGU_CLK_DIV,
+               .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+                            JZ4780_CLK_EPLL, JZ4780_CLK_VPLL },
+               .mux = { CGU_REG_PCMCDR, 29, 2 },
+               .div = { CGU_REG_PCMCDR, 0, 8, 28, 27, 26 },
+       },
+
+       [JZ4780_CLK_PCM] = {
+               "pcm", CGU_CLK_MUX | CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_PCMPLL, -1, -1 },
+               .mux = { CGU_REG_PCMCDR, 31, 1 },
+               .gate = { CGU_REG_CLKGR1, 3 },
+       },
+
+       [JZ4780_CLK_GPU] = {
+               "gpu", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+               .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+                            JZ4780_CLK_EPLL },
+               .mux = { CGU_REG_GPUCDR, 30, 2 },
+               .div = { CGU_REG_GPUCDR, 0, 4, 29, 28, 27 },
+               .gate = { CGU_REG_CLKGR1, 4 },
+       },
+
+       [JZ4780_CLK_HDMI] = {
+               "hdmi", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+                            JZ4780_CLK_VPLL, -1 },
+               .mux = { CGU_REG_HDMICDR, 30, 2 },
+               .div = { CGU_REG_HDMICDR, 0, 8, 29, 28, 26 },
+               .gate = { CGU_REG_CLKGR1, 9 },
+       },
+
+       [JZ4780_CLK_BCH] = {
+               "bch", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
+               .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL,
+                            JZ4780_CLK_EPLL },
+               .mux = { CGU_REG_BCHCDR, 30, 2 },
+               .div = { CGU_REG_BCHCDR, 0, 4, 29, 28, 27 },
+               .gate = { CGU_REG_CLKGR0, 1 },
+       },
+
+       /* Gate-only clocks */
+
+       [JZ4780_CLK_NEMC] = {
+               "nemc", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_AHB2, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 0 },
+       },
+
+       [JZ4780_CLK_OTG0] = {
+               "otg0", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 2 },
+       },
+
+       [JZ4780_CLK_SSI0] = {
+               "ssi0", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_SSI, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 4 },
+       },
+
+       [JZ4780_CLK_SMB0] = {
+               "smb0", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_PCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 5 },
+       },
+
+       [JZ4780_CLK_SMB1] = {
+               "smb1", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_PCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 6 },
+       },
+
+       [JZ4780_CLK_SCC] = {
+               "scc", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 7 },
+       },
+
+       [JZ4780_CLK_AIC] = {
+               "aic", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 8 },
+       },
+
+       [JZ4780_CLK_TSSI0] = {
+               "tssi0", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 9 },
+       },
+
+       [JZ4780_CLK_OWI] = {
+               "owi", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 10 },
+       },
+
+       [JZ4780_CLK_KBC] = {
+               "kbc", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 13 },
+       },
+
+       [JZ4780_CLK_SADC] = {
+               "sadc", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 14 },
+       },
+
+       [JZ4780_CLK_UART0] = {
+               "uart0", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 15 },
+       },
+
+       [JZ4780_CLK_UART1] = {
+               "uart1", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 16 },
+       },
+
+       [JZ4780_CLK_UART2] = {
+               "uart2", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 17 },
+       },
+
+       [JZ4780_CLK_UART3] = {
+               "uart3", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 18 },
+       },
+
+       [JZ4780_CLK_SSI1] = {
+               "ssi1", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_SSI, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 19 },
+       },
+
+       [JZ4780_CLK_SSI2] = {
+               "ssi2", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_SSI, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 20 },
+       },
+
+       [JZ4780_CLK_PDMA] = {
+               "pdma", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 21 },
+       },
+
+       [JZ4780_CLK_GPS] = {
+               "gps", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 22 },
+       },
+
+       [JZ4780_CLK_MAC] = {
+               "mac", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 23 },
+       },
+
+       [JZ4780_CLK_SMB2] = {
+               "smb2", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_PCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 24 },
+       },
+
+       [JZ4780_CLK_CIM] = {
+               "cim", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 26 },
+       },
+
+       [JZ4780_CLK_LCD] = {
+               "lcd", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 28 },
+       },
+
+       [JZ4780_CLK_TVE] = {
+               "tve", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_LCD, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 27 },
+       },
+
+       [JZ4780_CLK_IPU] = {
+               "ipu", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 29 },
+       },
+
+       [JZ4780_CLK_DDR0] = {
+               "ddr0", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_DDR, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 30 },
+       },
+
+       [JZ4780_CLK_DDR1] = {
+               "ddr1", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_DDR, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR0, 31 },
+       },
+
+       [JZ4780_CLK_SMB3] = {
+               "smb3", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_PCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR1, 0 },
+       },
+
+       [JZ4780_CLK_TSSI1] = {
+               "tssi1", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR1, 1 },
+       },
+
+       [JZ4780_CLK_COMPRESS] = {
+               "compress", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR1, 5 },
+       },
+
+       [JZ4780_CLK_AIC1] = {
+               "aic1", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR1, 6 },
+       },
+
+       [JZ4780_CLK_GPVLC] = {
+               "gpvlc", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR1, 7 },
+       },
+
+       [JZ4780_CLK_OTG1] = {
+               "otg1", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR1, 8 },
+       },
+
+       [JZ4780_CLK_UART4] = {
+               "uart4", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR1, 10 },
+       },
+
+       [JZ4780_CLK_AHBMON] = {
+               "ahb_mon", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR1, 11 },
+       },
+
+       [JZ4780_CLK_SMB4] = {
+               "smb4", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_PCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR1, 12 },
+       },
+
+       [JZ4780_CLK_DES] = {
+               "des", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR1, 13 },
+       },
+
+       [JZ4780_CLK_X2D] = {
+               "x2d", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR1, 14 },
+       },
+
+       [JZ4780_CLK_CORE1] = {
+               "core1", CGU_CLK_GATE,
+               .parents = { JZ4780_CLK_CPU, -1, -1, -1 },
+               .gate = { CGU_REG_CLKGR1, 15 },
+       },
+
+};
+
+static void __init jz4780_cgu_init(struct device_node *np)
+{
+       int retval;
+
+       cgu = ingenic_cgu_new(jz4780_cgu_clocks,
+                             ARRAY_SIZE(jz4780_cgu_clocks), np);
+       if (!cgu) {
+               pr_err("%s: failed to initialise CGU\n", __func__);
+               return;
+       }
+
+       retval = ingenic_cgu_register_clocks(cgu);
+       if (retval) {
+               pr_err("%s: failed to register CGU Clocks\n", __func__);
+               return;
+       }
+}
+CLK_OF_DECLARE(jz4780_cgu, "ingenic,jz4780-cgu", jz4780_cgu_init);
index f0913ee..262581b 100644 (file)
@@ -17,8 +17,8 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 
-#include <asm/mach-loongson1/cpufreq.h>
-#include <asm/mach-loongson1/loongson1.h>
+#include <cpufreq.h>
+#include <loongson1.h>
 
 static struct {
        struct device *dev;
index 6517132..99c69a3 100644 (file)
@@ -136,6 +136,7 @@ config QCOM_SCM
        bool
        depends on ARM || ARM64
 
+source "drivers/firmware/broadcom/Kconfig"
 source "drivers/firmware/google/Kconfig"
 source "drivers/firmware/efi/Kconfig"
 
index 3001f1a..4a4b897 100644 (file)
@@ -15,6 +15,7 @@ obj-$(CONFIG_QCOM_SCM)                += qcom_scm.o
 obj-$(CONFIG_QCOM_SCM)         += qcom_scm-32.o
 CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
 
+obj-y                          += broadcom/
 obj-$(CONFIG_GOOGLE_FIRMWARE)  += google/
 obj-$(CONFIG_EFI)              += efi/
 obj-$(CONFIG_UEFI_CPER)                += efi/
diff --git a/drivers/firmware/broadcom/Kconfig b/drivers/firmware/broadcom/Kconfig
new file mode 100644 (file)
index 0000000..6bed119
--- /dev/null
@@ -0,0 +1,11 @@
+config BCM47XX_NVRAM
+       bool "Broadcom NVRAM driver"
+       depends on BCM47XX || ARCH_BCM_5301X
+       help
+         Broadcom home routers contain flash partition called "nvram" with all
+         important hardware configuration as well as some minor user setup.
+         NVRAM partition contains a text-like data representing name=value
+         pairs.
+         This driver provides an easy way to get value of requested parameter.
+         It simply reads content of NVRAM and parses it. It doesn't control any
+         hardware part itself.
diff --git a/drivers/firmware/broadcom/Makefile b/drivers/firmware/broadcom/Makefile
new file mode 100644 (file)
index 0000000..d0e6835
--- /dev/null
@@ -0,0 +1 @@
+obj-$(CONFIG_BCM47XX_NVRAM)            += bcm47xx_nvram.o
similarity index 78%
rename from arch/mips/bcm47xx/nvram.c
rename to drivers/firmware/broadcom/bcm47xx_nvram.c
index ba632ff..87add3f 100644 (file)
@@ -35,6 +35,7 @@ struct nvram_header {
 };
 
 static char nvram_buf[NVRAM_SPACE];
+static size_t nvram_len;
 static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000};
 
 static u32 find_nvram_size(void __iomem *end)
@@ -60,7 +61,7 @@ static int nvram_find_and_copy(void __iomem *iobase, u32 lim)
        u32 *src, *dst;
        u32 size;
 
-       if (nvram_buf[0]) {
+       if (nvram_len) {
                pr_warn("nvram already initialized\n");
                return -EEXIST;
        }
@@ -94,18 +95,25 @@ static int nvram_find_and_copy(void __iomem *iobase, u32 lim)
        return -ENXIO;
 
 found:
-       if (header->len > size)
-               pr_err("The nvram size accoridng to the header seems to be bigger than the partition on flash\n");
-       if (header->len > NVRAM_SPACE)
-               pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
-                      header->len, NVRAM_SPACE);
-
        src = (u32 *)header;
        dst = (u32 *)nvram_buf;
        for (i = 0; i < sizeof(struct nvram_header); i += 4)
                *dst++ = __raw_readl(src++);
-       for (; i < header->len && i < NVRAM_SPACE && i < size; i += 4)
+       header = (struct nvram_header *)nvram_buf;
+       nvram_len = header->len;
+       if (nvram_len > size) {
+               pr_err("The nvram size according to the header seems to be bigger than the partition on flash\n");
+               nvram_len = size;
+       }
+       if (nvram_len >= NVRAM_SPACE) {
+               pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
+                      header->len, NVRAM_SPACE - 1);
+               nvram_len = NVRAM_SPACE - 1;
+       }
+       /* proceed reading data after header */
+       for (; i < nvram_len; i += 4)
                *dst++ = readl(src++);
+       nvram_buf[NVRAM_SPACE - 1] = '\0';
 
        return 0;
 }
@@ -146,21 +154,18 @@ static int nvram_init(void)
                return -ENODEV;
 
        err = mtd_read(mtd, 0, sizeof(header), &bytes_read, (uint8_t *)&header);
-       if (!err && header.magic == NVRAM_MAGIC) {
-               u8 *dst = (uint8_t *)nvram_buf;
-               size_t len = header.len;
-
-               if (header.len > NVRAM_SPACE) {
+       if (!err && header.magic == NVRAM_MAGIC &&
+           header.len > sizeof(header)) {
+               nvram_len = header.len;
+               if (nvram_len >= NVRAM_SPACE) {
                        pr_err("nvram on flash (%i bytes) is bigger than the reserved space in memory, will just copy the first %i bytes\n",
                                header.len, NVRAM_SPACE);
-                       len = NVRAM_SPACE;
+                       nvram_len = NVRAM_SPACE - 1;
                }
 
-               err = mtd_read(mtd, 0, len, &bytes_read, dst);
-               if (err)
-                       return err;
-
-               return 0;
+               err = mtd_read(mtd, 0, nvram_len, &nvram_len,
+                              (u8 *)nvram_buf);
+               return err;
        }
 #endif
 
@@ -170,12 +175,12 @@ static int nvram_init(void)
 int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len)
 {
        char *var, *value, *end, *eq;
-       int data_left, err;
+       int err;
 
        if (!name)
                return -EINVAL;
 
-       if (!nvram_buf[0]) {
+       if (!nvram_len) {
                err = nvram_init();
                if (err)
                        return err;
@@ -183,19 +188,16 @@ int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len)
 
        /* Look for name=value and return value */
        var = &nvram_buf[sizeof(struct nvram_header)];
-       end = nvram_buf + sizeof(nvram_buf) - 2;
-       end[0] = '\0';
-       end[1] = '\0';
-       for (; *var; var = value + strlen(value) + 1) {
-               data_left = end - var;
-
-               eq = strnchr(var, data_left, '=');
+       end = nvram_buf + sizeof(nvram_buf);
+       while (var < end && *var) {
+               eq = strchr(var, '=');
                if (!eq)
                        break;
                value = eq + 1;
                if (eq - var == strlen(name) &&
                    strncmp(var, name, eq - var) == 0)
                        return snprintf(val, val_len, "%s", value);
+               var = value + strlen(value) + 1;
        }
        return -ENOENT;
 }
@@ -221,3 +223,26 @@ int bcm47xx_nvram_gpio_pin(const char *name)
        return -ENOENT;
 }
 EXPORT_SYMBOL(bcm47xx_nvram_gpio_pin);
+
+char *bcm47xx_nvram_get_contents(size_t *nvram_size)
+{
+       int err;
+       char *nvram;
+
+       if (!nvram_len) {
+               err = nvram_init();
+               if (err)
+                       return NULL;
+       }
+
+       *nvram_size = nvram_len - sizeof(struct nvram_header);
+       nvram = vmalloc(*nvram_size);
+       if (!nvram)
+               return NULL;
+       memcpy(nvram, &nvram_buf[sizeof(struct nvram_header)], *nvram_size);
+
+       return nvram;
+}
+EXPORT_SYMBOL(bcm47xx_nvram_get_contents);
+
+MODULE_LICENSE("GPLv2");
index 8a7d780..120d815 100644 (file)
@@ -86,6 +86,11 @@ config IMGPDC_IRQ
        select GENERIC_IRQ_CHIP
        select IRQ_DOMAIN
 
+config IRQ_MIPS_CPU
+       bool
+       select GENERIC_IRQ_CHIP
+       select IRQ_DOMAIN
+
 config CLPS711X_IRQCHIP
        bool
        depends on ARCH_CLPS711X
@@ -160,10 +165,15 @@ config MIPS_GIC
        bool
        select MIPS_CM
 
+config INGENIC_IRQ
+       bool
+       depends on MACH_INGENIC
+       default y
+
 config RENESAS_H8300H_INTC
         bool
        select IRQ_DOMAIN
 
 config RENESAS_H8S_INTC
         bool
-       select IRQ_DOMAIN
\ No newline at end of file
+       select IRQ_DOMAIN
index 5c9adf1..b8d4e96 100644 (file)
@@ -28,6 +28,7 @@ obj-$(CONFIG_ARM_VIC)                 += irq-vic.o
 obj-$(CONFIG_ATMEL_AIC_IRQ)            += irq-atmel-aic-common.o irq-atmel-aic.o
 obj-$(CONFIG_ATMEL_AIC5_IRQ)   += irq-atmel-aic-common.o irq-atmel-aic5.o
 obj-$(CONFIG_IMGPDC_IRQ)               += irq-imgpdc.o
+obj-$(CONFIG_IRQ_MIPS_CPU)             += irq-mips-cpu.o
 obj-$(CONFIG_SIRF_IRQ)                 += irq-sirfsoc.o
 obj-$(CONFIG_RENESAS_INTC_IRQPIN)      += irq-renesas-intc-irqpin.o
 obj-$(CONFIG_RENESAS_IRQC)             += irq-renesas-irqc.o
@@ -50,3 +51,4 @@ obj-$(CONFIG_ARCH_DIGICOLOR)          += irq-digicolor.o
 obj-$(CONFIG_RENESAS_H8300H_INTC)      += irq-renesas-h8300h.o
 obj-$(CONFIG_RENESAS_H8S_INTC)         += irq-renesas-h8s.o
 obj-$(CONFIG_ARCH_SA1100)              += irq-sa11x0.o
+obj-$(CONFIG_INGENIC_IRQ)              += irq-ingenic.o
diff --git a/drivers/irqchip/irq-ingenic.c b/drivers/irqchip/irq-ingenic.c
new file mode 100644 (file)
index 0000000..005de3f
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  JZ4740 platform IRQ support
+ *
+ *  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.
+ *
+ *  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/errno.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/irqchip/ingenic.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/mach-jz4740/irq.h>
+
+#include "irqchip.h"
+
+struct ingenic_intc_data {
+       void __iomem *base;
+       unsigned num_chips;
+};
+
+#define JZ_REG_INTC_STATUS     0x00
+#define JZ_REG_INTC_MASK       0x04
+#define JZ_REG_INTC_SET_MASK   0x08
+#define JZ_REG_INTC_CLEAR_MASK 0x0c
+#define JZ_REG_INTC_PENDING    0x10
+#define CHIP_SIZE              0x20
+
+static irqreturn_t intc_cascade(int irq, void *data)
+{
+       struct ingenic_intc_data *intc = irq_get_handler_data(irq);
+       uint32_t irq_reg;
+       unsigned i;
+
+       for (i = 0; i < intc->num_chips; i++) {
+               irq_reg = readl(intc->base + (i * CHIP_SIZE) +
+                               JZ_REG_INTC_PENDING);
+               if (!irq_reg)
+                       continue;
+
+               generic_handle_irq(__fls(irq_reg) + (i * 32) + JZ4740_IRQ_BASE);
+       }
+
+       return IRQ_HANDLED;
+}
+
+static void intc_irq_set_mask(struct irq_chip_generic *gc, uint32_t mask)
+{
+       struct irq_chip_regs *regs = &gc->chip_types->regs;
+
+       writel(mask, gc->reg_base + regs->enable);
+       writel(~mask, gc->reg_base + regs->disable);
+}
+
+void ingenic_intc_irq_suspend(struct irq_data *data)
+{
+       struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
+       intc_irq_set_mask(gc, gc->wake_active);
+}
+
+void ingenic_intc_irq_resume(struct irq_data *data)
+{
+       struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
+       intc_irq_set_mask(gc, gc->mask_cache);
+}
+
+static struct irqaction intc_cascade_action = {
+       .handler = intc_cascade,
+       .name = "SoC intc cascade interrupt",
+};
+
+static int __init ingenic_intc_of_init(struct device_node *node,
+                                      unsigned num_chips)
+{
+       struct ingenic_intc_data *intc;
+       struct irq_chip_generic *gc;
+       struct irq_chip_type *ct;
+       struct irq_domain *domain;
+       int parent_irq, err = 0;
+       unsigned i;
+
+       intc = kzalloc(sizeof(*intc), GFP_KERNEL);
+       if (!intc) {
+               err = -ENOMEM;
+               goto out_err;
+       }
+
+       parent_irq = irq_of_parse_and_map(node, 0);
+       if (!parent_irq) {
+               err = -EINVAL;
+               goto out_free;
+       }
+
+       err = irq_set_handler_data(parent_irq, intc);
+       if (err)
+               goto out_unmap_irq;
+
+       intc->num_chips = num_chips;
+       intc->base = of_iomap(node, 0);
+       if (!intc->base) {
+               err = -ENODEV;
+               goto out_unmap_irq;
+       }
+
+       for (i = 0; i < num_chips; i++) {
+               /* Mask all irqs */
+               writel(0xffffffff, intc->base + (i * CHIP_SIZE) +
+                      JZ_REG_INTC_SET_MASK);
+
+               gc = irq_alloc_generic_chip("INTC", 1,
+                                           JZ4740_IRQ_BASE + (i * 32),
+                                           intc->base + (i * CHIP_SIZE),
+                                           handle_level_irq);
+
+               gc->wake_enabled = IRQ_MSK(32);
+
+               ct = gc->chip_types;
+               ct->regs.enable = JZ_REG_INTC_CLEAR_MASK;
+               ct->regs.disable = JZ_REG_INTC_SET_MASK;
+               ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
+               ct->chip.irq_mask = irq_gc_mask_disable_reg;
+               ct->chip.irq_mask_ack = irq_gc_mask_disable_reg;
+               ct->chip.irq_set_wake = irq_gc_set_wake;
+               ct->chip.irq_suspend = ingenic_intc_irq_suspend;
+               ct->chip.irq_resume = ingenic_intc_irq_resume;
+
+               irq_setup_generic_chip(gc, IRQ_MSK(32), 0, 0,
+                                      IRQ_NOPROBE | IRQ_LEVEL);
+       }
+
+       domain = irq_domain_add_legacy(node, num_chips * 32, JZ4740_IRQ_BASE, 0,
+                                      &irq_domain_simple_ops, NULL);
+       if (!domain)
+               pr_warn("unable to register IRQ domain\n");
+
+       setup_irq(parent_irq, &intc_cascade_action);
+       return 0;
+
+out_unmap_irq:
+       irq_dispose_mapping(parent_irq);
+out_free:
+       kfree(intc);
+out_err:
+       return err;
+}
+
+static int __init intc_1chip_of_init(struct device_node *node,
+                                    struct device_node *parent)
+{
+       return ingenic_intc_of_init(node, 1);
+}
+IRQCHIP_DECLARE(jz4740_intc, "ingenic,jz4740-intc", intc_1chip_of_init);
+
+static int __init intc_2chip_of_init(struct device_node *node,
+       struct device_node *parent)
+{
+       return ingenic_intc_of_init(node, 2);
+}
+IRQCHIP_DECLARE(jz4770_intc, "ingenic,jz4770-intc", intc_2chip_of_init);
+IRQCHIP_DECLARE(jz4775_intc, "ingenic,jz4775-intc", intc_2chip_of_init);
+IRQCHIP_DECLARE(jz4780_intc, "ingenic,jz4780-intc", intc_2chip_of_init);
similarity index 97%
rename from arch/mips/kernel/irq_cpu.c
rename to drivers/irqchip/irq-mips-cpu.c
index 6eb7a3f..a43c419 100644 (file)
@@ -38,6 +38,8 @@
 #include <asm/mipsmtregs.h>
 #include <asm/setup.h>
 
+#include "irqchip.h"
+
 static inline void unmask_mips_irq(struct irq_data *d)
 {
        set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
@@ -167,3 +169,4 @@ int __init mips_cpu_irq_of_init(struct device_node *of_node,
        __mips_cpu_irq_init(of_node);
        return 0;
 }
+IRQCHIP_DECLARE(cpu_intc, "mti,cpu-interrupt-controller", mips_cpu_irq_of_init);
index 487d057..c0e6ede 100644 (file)
@@ -267,6 +267,13 @@ config PHY_EXYNOS5_USBDRD
          This driver provides PHY interface for USB 3.0 DRD controller
          present on Exynos5 SoC series.
 
+config PHY_PISTACHIO_USB
+       tristate "IMG Pistachio USB2.0 PHY driver"
+       depends on MACH_PISTACHIO
+       select GENERIC_PHY
+       help
+         Enable this to support the USB2.0 PHY on the IMG Pistachio SoC.
+
 config PHY_QCOM_APQ8064_SATA
        tristate "Qualcomm APQ8064 SATA SerDes/PHY driver"
        depends on ARCH_QCOM
index 42f58e9..f344e1b 100644 (file)
@@ -44,3 +44,4 @@ obj-$(CONFIG_PHY_QCOM_UFS)    += phy-qcom-ufs-qmp-20nm.o
 obj-$(CONFIG_PHY_QCOM_UFS)     += phy-qcom-ufs-qmp-14nm.o
 obj-$(CONFIG_PHY_TUSB1210)             += phy-tusb1210.o
 obj-$(CONFIG_PHY_BRCMSTB_SATA)         += phy-brcmstb-sata.o
+obj-$(CONFIG_PHY_PISTACHIO_USB)                += phy-pistachio-usb.o
diff --git a/drivers/phy/phy-pistachio-usb.c b/drivers/phy/phy-pistachio-usb.c
new file mode 100644 (file)
index 0000000..c6db35e
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * IMG Pistachio USB PHY driver
+ *
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/phy/phy-pistachio-usb.h>
+
+#define USB_PHY_CONTROL1                               0x04
+#define USB_PHY_CONTROL1_FSEL_SHIFT                    2
+#define USB_PHY_CONTROL1_FSEL_MASK                     0x7
+
+#define USB_PHY_STRAP_CONTROL                          0x10
+#define USB_PHY_STRAP_CONTROL_REFCLK_SHIFT             4
+#define USB_PHY_STRAP_CONTROL_REFCLK_MASK              0x3
+
+#define USB_PHY_STATUS                                 0x14
+#define USB_PHY_STATUS_RX_PHY_CLK                      BIT(9)
+#define USB_PHY_STATUS_RX_UTMI_CLK                     BIT(8)
+#define USB_PHY_STATUS_VBUS_FAULT                      BIT(7)
+
+struct pistachio_usb_phy {
+       struct device *dev;
+       struct regmap *cr_top;
+       struct clk *phy_clk;
+       unsigned int refclk;
+};
+
+static const unsigned long fsel_rate_map[] = {
+       9600000,
+       10000000,
+       12000000,
+       19200000,
+       20000000,
+       24000000,
+       0,
+       50000000,
+};
+
+static int pistachio_usb_phy_power_on(struct phy *phy)
+{
+       struct pistachio_usb_phy *p_phy = phy_get_drvdata(phy);
+       unsigned long timeout, rate;
+       unsigned int i;
+       int ret;
+
+       ret = clk_prepare_enable(p_phy->phy_clk);
+       if (ret < 0) {
+               dev_err(p_phy->dev, "Failed to enable PHY clock: %d\n", ret);
+               return ret;
+       }
+
+       regmap_update_bits(p_phy->cr_top, USB_PHY_STRAP_CONTROL,
+                          USB_PHY_STRAP_CONTROL_REFCLK_MASK <<
+                          USB_PHY_STRAP_CONTROL_REFCLK_SHIFT,
+                          p_phy->refclk << USB_PHY_STRAP_CONTROL_REFCLK_SHIFT);
+
+       rate = clk_get_rate(p_phy->phy_clk);
+       if (p_phy->refclk == REFCLK_XO_CRYSTAL && rate != 12000000) {
+               dev_err(p_phy->dev, "Unsupported rate for XO crystal: %ld\n",
+                       rate);
+               ret = -EINVAL;
+               goto disable_clk;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(fsel_rate_map); i++) {
+               if (rate == fsel_rate_map[i])
+                       break;
+       }
+       if (i == ARRAY_SIZE(fsel_rate_map)) {
+               dev_err(p_phy->dev, "Unsupported clock rate: %lu\n", rate);
+               ret = -EINVAL;
+               goto disable_clk;
+       }
+
+       regmap_update_bits(p_phy->cr_top, USB_PHY_CONTROL1,
+                          USB_PHY_CONTROL1_FSEL_MASK <<
+                          USB_PHY_CONTROL1_FSEL_SHIFT,
+                          i << USB_PHY_CONTROL1_FSEL_SHIFT);
+
+       timeout = jiffies + msecs_to_jiffies(200);
+       while (time_before(jiffies, timeout)) {
+               unsigned int val;
+
+               regmap_read(p_phy->cr_top, USB_PHY_STATUS, &val);
+               if (val & USB_PHY_STATUS_VBUS_FAULT) {
+                       dev_err(p_phy->dev, "VBUS fault detected\n");
+                       ret = -EIO;
+                       goto disable_clk;
+               }
+               if ((val & USB_PHY_STATUS_RX_PHY_CLK) &&
+                   (val & USB_PHY_STATUS_RX_UTMI_CLK))
+                       return 0;
+               usleep_range(1000, 1500);
+       }
+
+       dev_err(p_phy->dev, "Timed out waiting for PHY to power on\n");
+       ret = -ETIMEDOUT;
+
+disable_clk:
+       clk_disable_unprepare(p_phy->phy_clk);
+       return ret;
+}
+
+static int pistachio_usb_phy_power_off(struct phy *phy)
+{
+       struct pistachio_usb_phy *p_phy = phy_get_drvdata(phy);
+
+       clk_disable_unprepare(p_phy->phy_clk);
+
+       return 0;
+}
+
+static const struct phy_ops pistachio_usb_phy_ops = {
+       .power_on = pistachio_usb_phy_power_on,
+       .power_off = pistachio_usb_phy_power_off,
+       .owner = THIS_MODULE,
+};
+
+static int pistachio_usb_phy_probe(struct platform_device *pdev)
+{
+       struct pistachio_usb_phy *p_phy;
+       struct phy_provider *provider;
+       struct phy *phy;
+       int ret;
+
+       p_phy = devm_kzalloc(&pdev->dev, sizeof(*p_phy), GFP_KERNEL);
+       if (!p_phy)
+               return -ENOMEM;
+       p_phy->dev = &pdev->dev;
+       platform_set_drvdata(pdev, p_phy);
+
+       p_phy->cr_top = syscon_regmap_lookup_by_phandle(p_phy->dev->of_node,
+                                                       "img,cr-top");
+       if (IS_ERR(p_phy->cr_top)) {
+               dev_err(p_phy->dev, "Failed to get CR_TOP registers: %ld\n",
+                       PTR_ERR(p_phy->cr_top));
+               return PTR_ERR(p_phy->cr_top);
+       }
+
+       p_phy->phy_clk = devm_clk_get(p_phy->dev, "usb_phy");
+       if (IS_ERR(p_phy->phy_clk)) {
+               dev_err(p_phy->dev, "Failed to get usb_phy clock: %ld\n",
+                       PTR_ERR(p_phy->phy_clk));
+               return PTR_ERR(p_phy->phy_clk);
+       }
+
+       ret = of_property_read_u32(p_phy->dev->of_node, "img,refclk",
+                                  &p_phy->refclk);
+       if (ret < 0) {
+               dev_err(p_phy->dev, "No reference clock selector specified\n");
+               return ret;
+       }
+
+       phy = devm_phy_create(p_phy->dev, NULL, &pistachio_usb_phy_ops);
+       if (IS_ERR(phy)) {
+               dev_err(p_phy->dev, "Failed to create PHY: %ld\n",
+                       PTR_ERR(phy));
+               return PTR_ERR(phy);
+       }
+       phy_set_drvdata(phy, p_phy);
+
+       provider = devm_of_phy_provider_register(p_phy->dev,
+                                                of_phy_simple_xlate);
+       if (IS_ERR(provider)) {
+               dev_err(p_phy->dev, "Failed to register PHY provider: %ld\n",
+                       PTR_ERR(provider));
+               return PTR_ERR(provider);
+       }
+
+       return 0;
+}
+
+static const struct of_device_id pistachio_usb_phy_of_match[] = {
+       { .compatible = "img,pistachio-usb-phy", },
+       { },
+};
+MODULE_DEVICE_TABLE(of, pistachio_usb_phy_of_match);
+
+static struct platform_driver pistachio_usb_phy_driver = {
+       .probe          = pistachio_usb_phy_probe,
+       .driver         = {
+               .name   = "pistachio-usb-phy",
+               .of_match_table = pistachio_usb_phy_of_match,
+       },
+};
+module_platform_driver(pistachio_usb_phy_driver);
+
+MODULE_AUTHOR("Andrew Bresticker <abrestic@chromium.org>");
+MODULE_DESCRIPTION("IMG Pistachio USB2.0 PHY driver");
+MODULE_LICENSE("GPL v2");
index db2fe4a..83b4b89 100644 (file)
@@ -1503,7 +1503,7 @@ config RTC_DRV_PUV3
 
 config RTC_DRV_LOONGSON1
        tristate "loongson1 RTC support"
-       depends on MACH_LOONGSON1
+       depends on MACH_LOONGSON32
        help
          This is a driver for the loongson1 on-chip Counter0 (Time-Of-Year
          counter) to be used as a RTC.
index 8445e56..22a9ec4 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/delay.h>
 #include <linux/types.h>
 #include <linux/io.h>
-#include <asm/mach-loongson1/loongson1.h>
+#include <loongson1.h>
 
 #define LS1X_RTC_REG_OFFSET    (LS1X_RTC_BASE + 0x20)
 #define LS1X_RTC_REGS(x) \
diff --git a/drivers/tty/serial/8250/8250_ingenic.c b/drivers/tty/serial/8250/8250_ingenic.c
new file mode 100644 (file)
index 0000000..21bf81f
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2010 Lars-Peter Clausen <lars@metafoo.de>
+ * Copyright (C) 2015 Imagination Technologies
+ *
+ * Ingenic SoC UART support
+ *
+ * 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.
+ *
+ * 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/clk.h>
+#include <linux/console.h>
+#include <linux/io.h>
+#include <linux/libfdt.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+
+struct ingenic_uart_data {
+       struct clk      *clk_module;
+       struct clk      *clk_baud;
+       int             line;
+};
+
+#define UART_FCR_UME   BIT(4)
+
+static struct earlycon_device *early_device;
+
+static uint8_t __init early_in(struct uart_port *port, int offset)
+{
+       return readl(port->membase + (offset << 2));
+}
+
+static void __init early_out(struct uart_port *port, int offset, uint8_t value)
+{
+       writel(value, port->membase + (offset << 2));
+}
+
+static void __init ingenic_early_console_putc(struct uart_port *port, int c)
+{
+       uint8_t lsr;
+
+       do {
+               lsr = early_in(port, UART_LSR);
+       } while ((lsr & UART_LSR_TEMT) == 0);
+
+       early_out(port, UART_TX, c);
+}
+
+static void __init ingenic_early_console_write(struct console *console,
+                                             const char *s, unsigned int count)
+{
+       uart_console_write(&early_device->port, s, count,
+                          ingenic_early_console_putc);
+}
+
+static void __init ingenic_early_console_setup_clock(struct earlycon_device *dev)
+{
+       void *fdt = initial_boot_params;
+       const __be32 *prop;
+       int offset;
+
+       offset = fdt_path_offset(fdt, "/ext");
+       if (offset < 0)
+               return;
+
+       prop = fdt_getprop(fdt, offset, "clock-frequency", NULL);
+       if (!prop)
+               return;
+
+       dev->port.uartclk = be32_to_cpup(prop);
+}
+
+static int __init ingenic_early_console_setup(struct earlycon_device *dev,
+                                             const char *opt)
+{
+       struct uart_port *port = &dev->port;
+       unsigned int baud, divisor;
+
+       if (!dev->port.membase)
+               return -ENODEV;
+
+       ingenic_early_console_setup_clock(dev);
+
+       baud = dev->baud ?: 115200;
+       divisor = DIV_ROUND_CLOSEST(port->uartclk, 16 * baud);
+
+       early_out(port, UART_IER, 0);
+       early_out(port, UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN8);
+       early_out(port, UART_DLL, 0);
+       early_out(port, UART_DLM, 0);
+       early_out(port, UART_LCR, UART_LCR_WLEN8);
+       early_out(port, UART_FCR, UART_FCR_UME | UART_FCR_CLEAR_XMIT |
+                       UART_FCR_CLEAR_RCVR | UART_FCR_ENABLE_FIFO);
+       early_out(port, UART_MCR, UART_MCR_RTS | UART_MCR_DTR);
+
+       early_out(port, UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN8);
+       early_out(port, UART_DLL, divisor & 0xff);
+       early_out(port, UART_DLM, (divisor >> 8) & 0xff);
+       early_out(port, UART_LCR, UART_LCR_WLEN8);
+
+       early_device = dev;
+       dev->con->write = ingenic_early_console_write;
+
+       return 0;
+}
+
+EARLYCON_DECLARE(jz4740_uart, ingenic_early_console_setup);
+OF_EARLYCON_DECLARE(jz4740_uart, "ingenic,jz4740-uart",
+                   ingenic_early_console_setup);
+
+EARLYCON_DECLARE(jz4775_uart, ingenic_early_console_setup);
+OF_EARLYCON_DECLARE(jz4775_uart, "ingenic,jz4775-uart",
+                   ingenic_early_console_setup);
+
+EARLYCON_DECLARE(jz4780_uart, ingenic_early_console_setup);
+OF_EARLYCON_DECLARE(jz4780_uart, "ingenic,jz4780-uart",
+                   ingenic_early_console_setup);
+
+static void ingenic_uart_serial_out(struct uart_port *p, int offset, int value)
+{
+       switch (offset) {
+       case UART_FCR:
+               /* UART module enable */
+               value |= UART_FCR_UME;
+               break;
+
+       case UART_IER:
+               value |= (value & 0x4) << 2;
+               break;
+
+       default:
+               break;
+       }
+
+       writeb(value, p->membase + (offset << p->regshift));
+}
+
+static int ingenic_uart_probe(struct platform_device *pdev)
+{
+       struct uart_8250_port uart = {};
+       struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       struct ingenic_uart_data *data;
+       int err, line;
+
+       if (!regs || !irq) {
+               dev_err(&pdev->dev, "no registers/irq defined\n");
+               return -EINVAL;
+       }
+
+       data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       spin_lock_init(&uart.port.lock);
+       uart.port.type = PORT_16550;
+       uart.port.flags = UPF_SKIP_TEST | UPF_IOREMAP | UPF_FIXED_TYPE;
+       uart.port.iotype = UPIO_MEM;
+       uart.port.mapbase = regs->start;
+       uart.port.regshift = 2;
+       uart.port.serial_out = ingenic_uart_serial_out;
+       uart.port.irq = irq->start;
+       uart.port.dev = &pdev->dev;
+
+       /* Check for a fixed line number */
+       line = of_alias_get_id(pdev->dev.of_node, "serial");
+       if (line >= 0)
+               uart.port.line = line;
+
+       uart.port.membase = devm_ioremap(&pdev->dev, regs->start,
+                                        resource_size(regs));
+       if (!uart.port.membase)
+               return -ENOMEM;
+
+       data->clk_module = devm_clk_get(&pdev->dev, "module");
+       if (IS_ERR(data->clk_module)) {
+               err = PTR_ERR(data->clk_module);
+               if (err != -EPROBE_DEFER)
+                       dev_err(&pdev->dev,
+                               "unable to get module clock: %d\n", err);
+               return err;
+       }
+
+       data->clk_baud = devm_clk_get(&pdev->dev, "baud");
+       if (IS_ERR(data->clk_baud)) {
+               err = PTR_ERR(data->clk_baud);
+               if (err != -EPROBE_DEFER)
+                       dev_err(&pdev->dev,
+                               "unable to get baud clock: %d\n", err);
+               return err;
+       }
+
+       err = clk_prepare_enable(data->clk_module);
+       if (err) {
+               dev_err(&pdev->dev, "could not enable module clock: %d\n", err);
+               goto out;
+       }
+
+       err = clk_prepare_enable(data->clk_baud);
+       if (err) {
+               dev_err(&pdev->dev, "could not enable baud clock: %d\n", err);
+               goto out_disable_moduleclk;
+       }
+       uart.port.uartclk = clk_get_rate(data->clk_baud);
+
+       data->line = serial8250_register_8250_port(&uart);
+       if (data->line < 0) {
+               err = data->line;
+               goto out_disable_baudclk;
+       }
+
+       platform_set_drvdata(pdev, data);
+       return 0;
+
+out_disable_baudclk:
+       clk_disable_unprepare(data->clk_baud);
+out_disable_moduleclk:
+       clk_disable_unprepare(data->clk_module);
+out:
+       return err;
+}
+
+static int ingenic_uart_remove(struct platform_device *pdev)
+{
+       struct ingenic_uart_data *data = platform_get_drvdata(pdev);
+
+       serial8250_unregister_port(data->line);
+       clk_disable_unprepare(data->clk_module);
+       clk_disable_unprepare(data->clk_baud);
+       return 0;
+}
+
+static const struct of_device_id of_match[] = {
+       { .compatible = "ingenic,jz4740-uart" },
+       { .compatible = "ingenic,jz4775-uart" },
+       { .compatible = "ingenic,jz4780-uart" },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, of_match);
+
+static struct platform_driver ingenic_uart_platform_driver = {
+       .driver = {
+               .name           = "ingenic-uart",
+               .owner          = THIS_MODULE,
+               .of_match_table = of_match,
+       },
+       .probe                  = ingenic_uart_probe,
+       .remove                 = ingenic_uart_remove,
+};
+
+module_platform_driver(ingenic_uart_platform_driver);
+
+MODULE_AUTHOR("Paul Burton");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Ingenic SoC UART driver");
index a74a8e4..e1de118 100644 (file)
@@ -357,3 +357,12 @@ config SERIAL_8250_UNIPHIER
        help
          If you have a UniPhier based board and want to use the on-chip
          serial ports, say Y to this option. If unsure, say N.
+
+config SERIAL_8250_INGENIC
+       bool "Support for Ingenic SoC serial ports"
+       depends on SERIAL_8250_CONSOLE && OF_FLATTREE
+       select LIBFDT
+       select SERIAL_EARLYCON
+       help
+         If you have a system using an Ingenic SoC and wish to make use of
+         its UARTs, say Y to this option. If unsure, say N.
index 6fa22ff..7062959 100644 (file)
@@ -25,3 +25,6 @@ obj-$(CONFIG_SERIAL_8250_FINTEK)      += 8250_fintek.o
 obj-$(CONFIG_SERIAL_8250_LPC18XX)      += 8250_lpc18xx.o
 obj-$(CONFIG_SERIAL_8250_MT6577)       += 8250_mtk.o
 obj-$(CONFIG_SERIAL_8250_UNIPHIER)     += 8250_uniphier.o
+obj-$(CONFIG_SERIAL_8250_INGENIC)      += 8250_ingenic.o
+
+CFLAGS_8250_ingenic.o += -I$(srctree)/scripts/dtc/libfdt
index 1c47910..2847108 100644 (file)
@@ -462,6 +462,7 @@ static struct sysrq_key_op *sysrq_key_table[36] = {
        /* v: May be registered for frame buffer console restore */
        NULL,                           /* v */
        &sysrq_showstate_blocked_op,    /* w */
+       /* x: May be registered on mips for TLB dump */
        /* x: May be registered on ppc/powerpc for xmon */
        /* x: May be registered on sparc64 for global PMU dump */
        NULL,                           /* x */
index 547cee8..8afc3c1 100644 (file)
@@ -295,7 +295,7 @@ config USB_OCTEON_EHCI
        bool "Octeon on-chip EHCI support (DEPRECATED)"
        depends on CAVIUM_OCTEON_SOC
        default n
-       select USB_EHCI_BIG_ENDIAN_MMIO
+       select USB_EHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
        select USB_EHCI_HCD_PLATFORM
        help
          This option is deprecated now and the driver was removed, use
@@ -568,7 +568,7 @@ config USB_OCTEON_OHCI
        bool "Octeon on-chip OHCI support (DEPRECATED)"
        depends on CAVIUM_OCTEON_SOC
        default USB_OCTEON_EHCI
-       select USB_OHCI_BIG_ENDIAN_MMIO
+       select USB_OHCI_BIG_ENDIAN_MMIO if CPU_BIG_ENDIAN
        select USB_OHCI_LITTLE_ENDIAN
        select USB_OHCI_HCD_PLATFORM
        help
diff --git a/include/dt-bindings/clock/jz4740-cgu.h b/include/dt-bindings/clock/jz4740-cgu.h
new file mode 100644 (file)
index 0000000..43153d3
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * This header provides clock numbers for the ingenic,jz4740-cgu DT binding.
+ *
+ * They are roughly ordered as:
+ *   - external clocks
+ *   - PLLs
+ *   - muxes/dividers in the order they appear in the jz4740 programmers manual
+ *   - gates in order of their bit in the CLKGR* registers
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_JZ4740_CGU_H__
+#define __DT_BINDINGS_CLOCK_JZ4740_CGU_H__
+
+#define JZ4740_CLK_EXT         0
+#define JZ4740_CLK_RTC         1
+#define JZ4740_CLK_PLL         2
+#define JZ4740_CLK_PLL_HALF    3
+#define JZ4740_CLK_CCLK                4
+#define JZ4740_CLK_HCLK                5
+#define JZ4740_CLK_PCLK                6
+#define JZ4740_CLK_MCLK                7
+#define JZ4740_CLK_LCD         8
+#define JZ4740_CLK_LCD_PCLK    9
+#define JZ4740_CLK_I2S         10
+#define JZ4740_CLK_SPI         11
+#define JZ4740_CLK_MMC         12
+#define JZ4740_CLK_UHC         13
+#define JZ4740_CLK_UDC         14
+#define JZ4740_CLK_UART0       15
+#define JZ4740_CLK_UART1       16
+#define JZ4740_CLK_DMA         17
+#define JZ4740_CLK_IPU         18
+#define JZ4740_CLK_ADC         19
+#define JZ4740_CLK_I2C         20
+#define JZ4740_CLK_AIC         21
+
+#endif /* __DT_BINDINGS_CLOCK_JZ4740_CGU_H__ */
diff --git a/include/dt-bindings/clock/jz4780-cgu.h b/include/dt-bindings/clock/jz4780-cgu.h
new file mode 100644 (file)
index 0000000..467165e
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * This header provides clock numbers for the ingenic,jz4780-cgu DT binding.
+ *
+ * They are roughly ordered as:
+ *   - external clocks
+ *   - PLLs
+ *   - muxes/dividers in the order they appear in the jz4780 programmers manual
+ *   - gates in order of their bit in the CLKGR* registers
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_JZ4780_CGU_H__
+#define __DT_BINDINGS_CLOCK_JZ4780_CGU_H__
+
+#define JZ4780_CLK_EXCLK       0
+#define JZ4780_CLK_RTCLK       1
+#define JZ4780_CLK_APLL                2
+#define JZ4780_CLK_MPLL                3
+#define JZ4780_CLK_EPLL                4
+#define JZ4780_CLK_VPLL                5
+#define JZ4780_CLK_OTGPHY      6
+#define JZ4780_CLK_SCLKA       7
+#define JZ4780_CLK_CPUMUX      8
+#define JZ4780_CLK_CPU         9
+#define JZ4780_CLK_L2CACHE     10
+#define JZ4780_CLK_AHB0                11
+#define JZ4780_CLK_AHB2PMUX    12
+#define JZ4780_CLK_AHB2                13
+#define JZ4780_CLK_PCLK                14
+#define JZ4780_CLK_DDR         15
+#define JZ4780_CLK_VPU         16
+#define JZ4780_CLK_I2SPLL      17
+#define JZ4780_CLK_I2S         18
+#define JZ4780_CLK_LCD0PIXCLK  19
+#define JZ4780_CLK_LCD1PIXCLK  20
+#define JZ4780_CLK_MSCMUX      21
+#define JZ4780_CLK_MSC0                22
+#define JZ4780_CLK_MSC1                23
+#define JZ4780_CLK_MSC2                24
+#define JZ4780_CLK_UHC         25
+#define JZ4780_CLK_SSIPLL      26
+#define JZ4780_CLK_SSI         27
+#define JZ4780_CLK_CIMMCLK     28
+#define JZ4780_CLK_PCMPLL      29
+#define JZ4780_CLK_PCM         30
+#define JZ4780_CLK_GPU         31
+#define JZ4780_CLK_HDMI                32
+#define JZ4780_CLK_BCH         33
+#define JZ4780_CLK_NEMC                34
+#define JZ4780_CLK_OTG0                35
+#define JZ4780_CLK_SSI0                36
+#define JZ4780_CLK_SMB0                37
+#define JZ4780_CLK_SMB1                38
+#define JZ4780_CLK_SCC         39
+#define JZ4780_CLK_AIC         40
+#define JZ4780_CLK_TSSI0       41
+#define JZ4780_CLK_OWI         42
+#define JZ4780_CLK_KBC         43
+#define JZ4780_CLK_SADC                44
+#define JZ4780_CLK_UART0       45
+#define JZ4780_CLK_UART1       46
+#define JZ4780_CLK_UART2       47
+#define JZ4780_CLK_UART3       48
+#define JZ4780_CLK_SSI1                49
+#define JZ4780_CLK_SSI2                50
+#define JZ4780_CLK_PDMA                51
+#define JZ4780_CLK_GPS         52
+#define JZ4780_CLK_MAC         53
+#define JZ4780_CLK_SMB2                54
+#define JZ4780_CLK_CIM         55
+#define JZ4780_CLK_LCD         56
+#define JZ4780_CLK_TVE         57
+#define JZ4780_CLK_IPU         58
+#define JZ4780_CLK_DDR0                59
+#define JZ4780_CLK_DDR1                60
+#define JZ4780_CLK_SMB3                61
+#define JZ4780_CLK_TSSI1       62
+#define JZ4780_CLK_COMPRESS    63
+#define JZ4780_CLK_AIC1                64
+#define JZ4780_CLK_GPVLC       65
+#define JZ4780_CLK_OTG1                66
+#define JZ4780_CLK_UART4       67
+#define JZ4780_CLK_AHBMON      68
+#define JZ4780_CLK_SMB4                69
+#define JZ4780_CLK_DES         70
+#define JZ4780_CLK_X2D         71
+#define JZ4780_CLK_CORE1       72
+
+#endif /* __DT_BINDINGS_CLOCK_JZ4780_CGU_H__ */
diff --git a/include/dt-bindings/phy/phy-pistachio-usb.h b/include/dt-bindings/phy/phy-pistachio-usb.h
new file mode 100644 (file)
index 0000000..d1877aa
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2015 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#ifndef _DT_BINDINGS_PHY_PISTACHIO
+#define _DT_BINDINGS_PHY_PISTACHIO
+
+#define REFCLK_XO_CRYSTAL      0x0
+#define REFCLK_X0_EXT_CLK      0x1
+#define REFCLK_CLK_CORE                0x2
+
+#endif /* _DT_BINDINGS_PHY_PISTACHIO */
index b12b07e..2793652 100644 (file)
 
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/vmalloc.h>
 
-#ifdef CONFIG_BCM47XX
+#ifdef CONFIG_BCM47XX_NVRAM
 int bcm47xx_nvram_init_from_mem(u32 base, u32 lim);
 int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len);
 int bcm47xx_nvram_gpio_pin(const char *name);
+char *bcm47xx_nvram_get_contents(size_t *val_len);
+static inline void bcm47xx_nvram_release_contents(char *nvram)
+{
+       vfree(nvram);
+};
 #else
 static inline int bcm47xx_nvram_init_from_mem(u32 base, u32 lim)
 {
@@ -29,6 +35,15 @@ static inline int bcm47xx_nvram_gpio_pin(const char *name)
 {
        return -ENOTSUPP;
 };
+
+static inline char *bcm47xx_nvram_get_contents(size_t *val_len)
+{
+       return NULL;
+};
+
+static inline void bcm47xx_nvram_release_contents(char *nvram)
+{
+};
 #endif
 
 #endif /* __BCM47XX_NVRAM_H */
similarity index 74%
rename from arch/mips/jz4740/irq.h
rename to include/linux/irqchip/ingenic.h
index 0f48720..0ee319a 100644 (file)
  *
  */
 
-#ifndef __MIPS_JZ4740_IRQ_H__
-#define __MIPS_JZ4740_IRQ_H__
+#ifndef __LINUX_IRQCHIP_INGENIC_H__
+#define __LINUX_IRQCHIP_INGENIC_H__
 
 #include <linux/irq.h>
 
-extern void jz4740_irq_suspend(struct irq_data *data);
-extern void jz4740_irq_resume(struct irq_data *data);
+extern void ingenic_intc_irq_suspend(struct irq_data *data);
+extern void ingenic_intc_irq_resume(struct irq_data *data);
 
 #endif
diff --git a/include/linux/platform_data/gpio-ath79.h b/include/linux/platform_data/gpio-ath79.h
new file mode 100644 (file)
index 0000000..88b0db7
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ *  Atheros AR7XXX/AR9XXX GPIO controller platform data
+ *
+ * Copyright (C) 2015 Alban Bedel <albeu@free.fr>
+ *
+ * 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.
+ */
+
+#ifndef __LINUX_PLATFORM_DATA_GPIO_ATH79_H
+#define __LINUX_PLATFORM_DATA_GPIO_ATH79_H
+
+struct ath79_gpio_platform_data {
+       unsigned ngpios;
+       bool oe_inverted;
+};
+
+#endif
index 4568a5c..c3d1a52 100644 (file)
@@ -29,10 +29,13 @@ struct ssb_sprom {
        u8 il0mac[6] __aligned(sizeof(u16));    /* MAC address for 802.11b/g */
        u8 et0mac[6] __aligned(sizeof(u16));    /* MAC address for Ethernet */
        u8 et1mac[6] __aligned(sizeof(u16));    /* MAC address for 802.11a */
+       u8 et2mac[6] __aligned(sizeof(u16));    /* MAC address for extra Ethernet */
        u8 et0phyaddr;          /* MII address for enet0 */
        u8 et1phyaddr;          /* MII address for enet1 */
+       u8 et2phyaddr;          /* MII address for enet2 */
        u8 et0mdcport;          /* MDIO for enet0 */
        u8 et1mdcport;          /* MDIO for enet1 */
+       u8 et2mdcport;          /* MDIO for enet2 */
        u16 dev_id;             /* Device ID overriding e.g. PCI ID */
        u16 board_rev;          /* Board revision number from SPROM. */
        u16 board_num;          /* Board number from SPROM. */
@@ -88,11 +91,14 @@ struct ssb_sprom {
        u32 ofdm5glpo;          /* 5.2GHz OFDM power offset */
        u32 ofdm5gpo;           /* 5.3GHz OFDM power offset */
        u32 ofdm5ghpo;          /* 5.8GHz OFDM power offset */
+       u32 boardflags;
+       u32 boardflags2;
+       u32 boardflags3;
+       /* TODO: Switch all drivers to new u32 fields and drop below ones */
        u16 boardflags_lo;      /* Board flags (bits 0-15) */
        u16 boardflags_hi;      /* Board flags (bits 16-31) */
        u16 boardflags2_lo;     /* Board flags (bits 32-47) */
        u16 boardflags2_hi;     /* Board flags (bits 48-63) */
-       /* TODO store board flags in a single u64 */
 
        struct ssb_sprom_core_pwr_info core_pwr_info[4];