Merge tag 'dt-3.10-4' of git://git.infradead.org/users/jcooper/linux into next/dt2
authorOlof Johansson <olof@lixom.net>
Thu, 18 Apr 2013 06:26:57 +0000 (23:26 -0700)
committerOlof Johansson <olof@lixom.net>
Thu, 18 Apr 2013 06:27:52 +0000 (23:27 -0700)
From Jason Cooper:
mvebu dt for v3.10 round 4

 - mvebu LPAE 64bit dts file changes

* tag 'dt-3.10-4' of git://git.infradead.org/users/jcooper/linux: (52 commits)
  ARM: dts: mvebu: Convert mvebu device tree files to 64 bits
  ARM: dts: mvebu: introduce internal-regs node
  ARM: dts: mvebu: Convert all the mvebu files to use the range property
  ARM: dts: mvebu: move all peripherals inside soc
  ARM: dts: mvebu: fix cpus section indentation
  arm: mvebu: PCIe Device Tree informations for Armada XP GP
  arm: mvebu: PCIe Device Tree informations for Armada 370 DB
  arm: mvebu: PCIe Device Tree informations for Armada 370 Mirabox
  arm: mvebu: PCIe Device Tree informations for Armada XP DB
  arm: mvebu: PCIe Device Tree informations for OpenBlocks AX3-4
  arm: mvebu: add PCIe Device Tree informations for Armada XP
  arm: mvebu: add PCIe Device Tree informations for Armada 370
  ARM: mvebu: Align the internal registers virtual base to support LPAE
  ARM: mvebu: Limit the DMA zone when LPAE is selected
  arm: plat-orion: remove addr-map code
  arm: mach-mv78xx0: convert to use the mvebu-mbus driver
  arm: mach-orion5x: convert to use mvebu-mbus driver
  arm: mach-dove: convert to use mvebu-mbus driver
  arm: mach-kirkwood: convert to use mvebu-mbus driver
  arm: mach-mvebu: convert to use mvebu-mbus driver
  ...

Signed-off-by: Olof Johansson <olof@lixom.net>
653 files changed:
Documentation/arm/sunxi/clocks.txt [new file with mode: 0644]
Documentation/clk.txt
Documentation/devicetree/bindings/arm/omap/l3-noc.txt
Documentation/devicetree/bindings/arm/omap/timer.txt
Documentation/devicetree/bindings/arm/samsung/sysreg.txt [new file with mode: 0644]
Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
Documentation/devicetree/bindings/clock/axi-clkgen.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/exynos4-clock.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/exynos5250-clock.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/exynos5440-clock.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/nvidia,tegra20-car.txt
Documentation/devicetree/bindings/clock/sunxi.txt [new file with mode: 0644]
Documentation/devicetree/bindings/dma/fsl-mxs-dma.txt
Documentation/devicetree/bindings/fb/mxsfb.txt
Documentation/devicetree/bindings/gpio/gpio-omap.txt
Documentation/devicetree/bindings/gpu/samsung-g2d.txt [new file with mode: 0644]
Documentation/devicetree/bindings/i2c/i2c-mxs.txt
Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt [new file with mode: 0644]
Documentation/devicetree/bindings/media/s5p-mfc.txt
Documentation/devicetree/bindings/mmc/mxs-mmc.txt
Documentation/devicetree/bindings/mtd/gpmi-nand.txt
Documentation/devicetree/bindings/pinctrl/fsl,mxs-pinctrl.txt
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-alc5632.txt
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-trimslice.txt
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8753.txt
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm8903.txt
Documentation/devicetree/bindings/sound/nvidia,tegra-audio-wm9712.txt
Documentation/devicetree/bindings/spi/mxs-spi.txt
Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt [new file with mode: 0644]
Documentation/devicetree/bindings/tty/serial/fsl-mxs-auart.txt
Documentation/devicetree/bindings/usb/exynos-usb.txt [new file with mode: 0644]
Documentation/devicetree/bindings/usb/omap-usb.txt
Documentation/devicetree/bindings/video/samsung-fimd.txt [new file with mode: 0644]
Documentation/networking/ipvs-sysctl.txt
MAINTAINERS
Makefile
arch/arc/include/asm/dma-mapping.h
arch/arc/include/asm/elf.h
arch/arc/include/asm/entry.h
arch/arc/include/asm/kgdb.h
arch/arc/include/asm/ptrace.h
arch/arc/include/asm/syscalls.h
arch/arc/include/uapi/asm/ptrace.h
arch/arc/kernel/entry.S
arch/arc/kernel/kgdb.c
arch/arc/kernel/setup.c
arch/arc/kernel/sys.c
arch/arm/Kconfig
arch/arm/Kconfig.debug
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/am335x-bone.dts
arch/arm/boot/dts/am335x-evm.dts
arch/arm/boot/dts/am335x-evmsk.dts
arch/arm/boot/dts/am33xx.dtsi
arch/arm/boot/dts/am3517-evm.dts
arch/arm/boot/dts/am3517_mt_ventoux.dts
arch/arm/boot/dts/cros5250-common.dtsi
arch/arm/boot/dts/exynos4.dtsi
arch/arm/boot/dts/exynos4210-origen.dts
arch/arm/boot/dts/exynos4210-smdkv310.dts
arch/arm/boot/dts/exynos4210-trats.dts
arch/arm/boot/dts/exynos4210.dtsi
arch/arm/boot/dts/exynos4212.dtsi
arch/arm/boot/dts/exynos4412-odroidx.dts [new file with mode: 0644]
arch/arm/boot/dts/exynos4412-origen.dts [new file with mode: 0644]
arch/arm/boot/dts/exynos4412-smdk4412.dts
arch/arm/boot/dts/exynos4412.dtsi
arch/arm/boot/dts/exynos4x12.dtsi
arch/arm/boot/dts/exynos5250-arndale.dts [new file with mode: 0644]
arch/arm/boot/dts/exynos5250-pinctrl.dtsi [new file with mode: 0644]
arch/arm/boot/dts/exynos5250-smdk5250.dts
arch/arm/boot/dts/exynos5250-snow.dts
arch/arm/boot/dts/exynos5250.dtsi
arch/arm/boot/dts/exynos5440-sd5v1.dts [new file with mode: 0644]
arch/arm/boot/dts/exynos5440-ssdk5440.dts
arch/arm/boot/dts/exynos5440.dtsi
arch/arm/boot/dts/imx23-evk.dts
arch/arm/boot/dts/imx23-olinuxino.dts
arch/arm/boot/dts/imx23.dtsi
arch/arm/boot/dts/imx28-apf28dev.dts
arch/arm/boot/dts/imx28-apx4devkit.dts
arch/arm/boot/dts/imx28-cfa10049.dts
arch/arm/boot/dts/imx28-evk.dts
arch/arm/boot/dts/imx28-m28evk.dts
arch/arm/boot/dts/imx28.dtsi
arch/arm/boot/dts/imx6qdl.dtsi
arch/arm/boot/dts/omap2.dtsi
arch/arm/boot/dts/omap2420-h4.dts
arch/arm/boot/dts/omap2420.dtsi
arch/arm/boot/dts/omap2430.dtsi
arch/arm/boot/dts/omap3-beagle-xm.dts
arch/arm/boot/dts/omap3-beagle.dts
arch/arm/boot/dts/omap3-devkit8000.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-evm.dts
arch/arm/boot/dts/omap3-igep.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap3-igep0020.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-igep0030.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-overo.dtsi
arch/arm/boot/dts/omap3.dtsi
arch/arm/boot/dts/omap3430-sdp.dts [new file with mode: 0644]
arch/arm/boot/dts/omap34xx.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap36xx.dtsi
arch/arm/boot/dts/omap4-panda-a4.dts
arch/arm/boot/dts/omap4-panda-common.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap4-panda-es.dts
arch/arm/boot/dts/omap4-panda.dts
arch/arm/boot/dts/omap4-sdp.dts
arch/arm/boot/dts/omap4-var-som.dts
arch/arm/boot/dts/omap4.dtsi
arch/arm/boot/dts/omap443x.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap4460.dtsi [new file with mode: 0644]
arch/arm/boot/dts/omap5-evm.dts
arch/arm/boot/dts/omap5.dtsi
arch/arm/boot/dts/tegra114-dalmore.dts
arch/arm/boot/dts/tegra114-pluto.dts
arch/arm/boot/dts/tegra114.dtsi
arch/arm/boot/dts/tegra20-colibri-512.dtsi
arch/arm/boot/dts/tegra20-harmony.dts
arch/arm/boot/dts/tegra20-medcom-wide.dts
arch/arm/boot/dts/tegra20-paz00.dts
arch/arm/boot/dts/tegra20-plutux.dts
arch/arm/boot/dts/tegra20-seaboard.dts
arch/arm/boot/dts/tegra20-tamonten.dtsi
arch/arm/boot/dts/tegra20-tec.dts
arch/arm/boot/dts/tegra20-trimslice.dts
arch/arm/boot/dts/tegra20-ventana.dts
arch/arm/boot/dts/tegra20-whistler.dts
arch/arm/boot/dts/tegra20.dtsi
arch/arm/boot/dts/tegra30-beaver.dts
arch/arm/boot/dts/tegra30-cardhu-a02.dts
arch/arm/boot/dts/tegra30-cardhu-a04.dts
arch/arm/boot/dts/tegra30-cardhu.dtsi
arch/arm/boot/dts/tegra30.dtsi
arch/arm/boot/dts/twl4030.dtsi
arch/arm/boot/dts/twl6030.dtsi
arch/arm/include/asm/smp_twd.h
arch/arm/kernel/smp_twd.c
arch/arm/mach-exynos/Kconfig
arch/arm/mach-exynos/Makefile
arch/arm/mach-exynos/clock-exynos4.c [deleted file]
arch/arm/mach-exynos/clock-exynos4.h [deleted file]
arch/arm/mach-exynos/clock-exynos4210.c [deleted file]
arch/arm/mach-exynos/clock-exynos4212.c [deleted file]
arch/arm/mach-exynos/clock-exynos5.c [deleted file]
arch/arm/mach-exynos/common.c
arch/arm/mach-exynos/common.h
arch/arm/mach-exynos/include/mach/irqs.h
arch/arm/mach-exynos/include/mach/map.h
arch/arm/mach-exynos/include/mach/regs-clock.h
arch/arm/mach-exynos/include/mach/regs-mct.h [deleted file]
arch/arm/mach-exynos/mach-armlex4210.c
arch/arm/mach-exynos/mach-exynos4-dt.c
arch/arm/mach-exynos/mach-exynos5-dt.c
arch/arm/mach-exynos/mach-nuri.c
arch/arm/mach-exynos/mach-origen.c
arch/arm/mach-exynos/mach-smdk4x12.c
arch/arm/mach-exynos/mach-smdkv310.c
arch/arm/mach-exynos/mach-universal_c210.c
arch/arm/mach-exynos/mct.c [deleted file]
arch/arm/mach-highbank/highbank.c
arch/arm/mach-imx/clk-busy.c
arch/arm/mach-imx/mach-imx6q.c
arch/arm/mach-mxs/Makefile
arch/arm/mach-mxs/icoll.c [deleted file]
arch/arm/mach-mxs/include/mach/common.h [deleted file]
arch/arm/mach-mxs/include/mach/debug-macro.S
arch/arm/mach-mxs/include/mach/digctl.h [deleted file]
arch/arm/mach-mxs/include/mach/hardware.h [deleted file]
arch/arm/mach-mxs/include/mach/mx23.h [deleted file]
arch/arm/mach-mxs/include/mach/mx28.h [deleted file]
arch/arm/mach-mxs/include/mach/mxs.h [deleted file]
arch/arm/mach-mxs/mach-mxs.c
arch/arm/mach-mxs/mm.c [deleted file]
arch/arm/mach-mxs/ocotp.c [deleted file]
arch/arm/mach-mxs/system.c [deleted file]
arch/arm/mach-mxs/timer.c [deleted file]
arch/arm/mach-omap1/Kconfig
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/board-2430sdp.c
arch/arm/mach-omap2/board-3430sdp.c
arch/arm/mach-omap2/board-3630sdp.c
arch/arm/mach-omap2/board-am3517crane.c
arch/arm/mach-omap2/board-am3517evm.c
arch/arm/mach-omap2/board-cm-t35.c
arch/arm/mach-omap2/board-cm-t3517.c
arch/arm/mach-omap2/board-devkit8000.c
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/board-h4.c
arch/arm/mach-omap2/board-igep0020.c
arch/arm/mach-omap2/board-omap3beagle.c
arch/arm/mach-omap2/board-omap3evm.c
arch/arm/mach-omap2/board-omap3pandora.c
arch/arm/mach-omap2/board-omap3stalker.c
arch/arm/mach-omap2/board-omap3touchbook.c
arch/arm/mach-omap2/board-omap4panda.c
arch/arm/mach-omap2/board-overo.c
arch/arm/mach-omap2/board-zoom.c
arch/arm/mach-omap2/cclock33xx_data.c
arch/arm/mach-omap2/dpll3xxx.c
arch/arm/mach-omap2/dsp.c
arch/arm/mach-omap2/id.c
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/omap4-common.c
arch/arm/mach-omap2/omap4-sar-layout.h
arch/arm/mach-omap2/omap54xx.h
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod.h
arch/arm/mach-omap2/omap_hwmod_33xx_data.c
arch/arm/mach-omap2/pmu.c
arch/arm/mach-omap2/powerdomain.c
arch/arm/mach-omap2/prm44xx.c
arch/arm/mach-omap2/soc.h
arch/arm/mach-omap2/timer.c
arch/arm/mach-omap2/usb-host.c
arch/arm/mach-omap2/usb.h
arch/arm/mach-s3c24xx/Kconfig
arch/arm/mach-s3c24xx/bast-irq.c
arch/arm/mach-s3c24xx/clock-s3c2410.c
arch/arm/mach-s3c24xx/clock-s3c2412.c
arch/arm/mach-s3c24xx/clock-s3c2416.c
arch/arm/mach-s3c24xx/clock-s3c2443.c
arch/arm/mach-s3c24xx/common-smdk.c
arch/arm/mach-s3c24xx/common-smdk.h [new file with mode: 0644]
arch/arm/mach-s3c24xx/common.c
arch/arm/mach-s3c24xx/common.h
arch/arm/mach-s3c24xx/dma-s3c2410.c
arch/arm/mach-s3c24xx/dma-s3c2412.c
arch/arm/mach-s3c24xx/dma-s3c2440.c
arch/arm/mach-s3c24xx/dma-s3c2443.c
arch/arm/mach-s3c24xx/include/mach/regs-sdi.h [deleted file]
arch/arm/mach-s3c24xx/irq-pm.c
arch/arm/mach-s3c24xx/irq.c
arch/arm/mach-s3c24xx/mach-amlm5900.c
arch/arm/mach-s3c24xx/mach-anubis.c
arch/arm/mach-s3c24xx/mach-at2440evb.c
arch/arm/mach-s3c24xx/mach-bast.c
arch/arm/mach-s3c24xx/mach-gta02.c
arch/arm/mach-s3c24xx/mach-h1940.c
arch/arm/mach-s3c24xx/mach-jive.c
arch/arm/mach-s3c24xx/mach-mini2440.c
arch/arm/mach-s3c24xx/mach-n30.c
arch/arm/mach-s3c24xx/mach-nexcoder.c
arch/arm/mach-s3c24xx/mach-osiris.c
arch/arm/mach-s3c24xx/mach-otom.c
arch/arm/mach-s3c24xx/mach-qt2410.c
arch/arm/mach-s3c24xx/mach-rx1950.c
arch/arm/mach-s3c24xx/mach-rx3715.c
arch/arm/mach-s3c24xx/mach-smdk2410.c
arch/arm/mach-s3c24xx/mach-smdk2413.c
arch/arm/mach-s3c24xx/mach-smdk2416.c
arch/arm/mach-s3c24xx/mach-smdk2440.c
arch/arm/mach-s3c24xx/mach-smdk2443.c
arch/arm/mach-s3c24xx/mach-tct_hammer.c
arch/arm/mach-s3c24xx/mach-vr1000.c
arch/arm/mach-s3c24xx/mach-vstms.c
arch/arm/mach-s3c24xx/pm-s3c2412.c
arch/arm/mach-s3c24xx/s3c2410.c
arch/arm/mach-s3c24xx/s3c2412.c
arch/arm/mach-s3c24xx/s3c2416.c
arch/arm/mach-s3c24xx/s3c2440.c
arch/arm/mach-s3c24xx/s3c2442.c
arch/arm/mach-s3c24xx/s3c2443.c
arch/arm/mach-s3c24xx/s3c244x.c
arch/arm/mach-s3c64xx/Kconfig
arch/arm/mach-s3c64xx/mach-anw6410.c
arch/arm/mach-s3c64xx/mach-crag6410.c
arch/arm/mach-s3c64xx/mach-hmt.c
arch/arm/mach-s3c64xx/mach-mini6410.c
arch/arm/mach-s3c64xx/mach-ncp.c
arch/arm/mach-s3c64xx/mach-real6410.c
arch/arm/mach-s3c64xx/mach-smartq.c
arch/arm/mach-s3c64xx/mach-smartq5.c
arch/arm/mach-s3c64xx/mach-smartq7.c
arch/arm/mach-s3c64xx/mach-smdk6400.c
arch/arm/mach-s3c64xx/mach-smdk6410.c
arch/arm/mach-s5p64x0/Kconfig
arch/arm/mach-s5p64x0/mach-smdk6440.c
arch/arm/mach-s5p64x0/mach-smdk6450.c
arch/arm/mach-s5pc100/Kconfig
arch/arm/mach-s5pc100/mach-smdkc100.c
arch/arm/mach-s5pv210/Kconfig
arch/arm/mach-s5pv210/mach-aquila.c
arch/arm/mach-s5pv210/mach-goni.c
arch/arm/mach-s5pv210/mach-smdkc110.c
arch/arm/mach-s5pv210/mach-smdkv210.c
arch/arm/mach-s5pv210/mach-torbreck.c
arch/arm/mach-spear13xx/spear13xx.c
arch/arm/mach-tegra/Makefile
arch/arm/mach-tegra/board-dt-tegra114.c [deleted file]
arch/arm/mach-tegra/board-dt-tegra20.c [deleted file]
arch/arm/mach-tegra/board-dt-tegra30.c [deleted file]
arch/arm/mach-tegra/board-harmony-pcie.c
arch/arm/mach-tegra/board.h
arch/arm/mach-tegra/common.c
arch/arm/mach-tegra/cpuidle-tegra20.c
arch/arm/mach-tegra/cpuidle-tegra30.c
arch/arm/mach-tegra/fuse.c
arch/arm/mach-tegra/fuse.h
arch/arm/mach-tegra/headsmp.S
arch/arm/mach-tegra/hotplug.c
arch/arm/mach-tegra/irq.c
arch/arm/mach-tegra/irq.h
arch/arm/mach-tegra/platsmp.c
arch/arm/mach-tegra/pm.c
arch/arm/mach-tegra/pm.h
arch/arm/mach-tegra/pmc.c
arch/arm/mach-tegra/pmc.h
arch/arm/mach-tegra/reset-handler.S
arch/arm/mach-tegra/sleep.h
arch/arm/mach-tegra/tegra.c [new file with mode: 0644]
arch/arm/mach-tegra/tegra114_speedo.c [new file with mode: 0644]
arch/arm/mach-ux500/timer.c
arch/arm/mach-vexpress/v2m.c
arch/arm/plat-omap/dmtimer.c
arch/arm/plat-omap/include/plat/dmtimer.h
arch/arm/plat-samsung/Kconfig
arch/arm/plat-samsung/Makefile
arch/arm/plat-samsung/include/plat/common-smdk.h [deleted file]
arch/arm/plat-samsung/include/plat/cpu.h
arch/arm/plat-samsung/include/plat/irq.h [deleted file]
arch/arm/plat-samsung/include/plat/s3c2410.h [deleted file]
arch/arm/plat-samsung/include/plat/s3c2412.h [deleted file]
arch/arm/plat-samsung/include/plat/s3c2416.h [deleted file]
arch/arm/plat-samsung/include/plat/s3c2443.h [deleted file]
arch/arm/plat-samsung/include/plat/s3c244x.h [deleted file]
arch/arm/plat-samsung/include/plat/s5p-time.h [deleted file]
arch/arm/plat-samsung/include/plat/samsung-time.h [new file with mode: 0644]
arch/arm/plat-samsung/s5p-time.c [deleted file]
arch/arm/plat-samsung/samsung-time.c [new file with mode: 0644]
arch/arm/plat-samsung/time.c [deleted file]
arch/arm64/mm/mmu.c
arch/ia64/kernel/process.c
arch/powerpc/kernel/epapr_paravirt.c
arch/powerpc/kernel/exceptions-64s.S
arch/x86/include/asm/xen/hypercall.h
arch/x86/include/uapi/asm/msr-index.h
arch/x86/kernel/microcode_intel_early.c
arch/x86/lib/usercopy_64.c
arch/x86/xen/mmu.c
block/blk-flush.c
block/partition-generic.c
drivers/acpi/apei/cper.c
drivers/acpi/pci_root.c
drivers/acpi/sleep.c
drivers/block/Kconfig
drivers/block/cciss.c
drivers/block/loop.c
drivers/block/mg_disk.c
drivers/block/mtip32xx/mtip32xx.c
drivers/block/rbd.c
drivers/block/rsxx/Makefile
drivers/block/rsxx/config.c
drivers/block/rsxx/core.c
drivers/block/rsxx/cregs.c
drivers/block/rsxx/dma.c
drivers/block/rsxx/rsxx.h
drivers/block/rsxx/rsxx_cfg.h
drivers/block/rsxx/rsxx_priv.h
drivers/block/xen-blkback/blkback.c
drivers/block/xen-blkback/common.h
drivers/block/xen-blkback/xenbus.c
drivers/block/xen-blkfront.c
drivers/bluetooth/ath3k.c
drivers/bluetooth/btusb.c
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/clk-axi-clkgen.c [new file with mode: 0644]
drivers/clk/clk-composite.c [new file with mode: 0644]
drivers/clk/clk-mux.c
drivers/clk/clk-prima2.c
drivers/clk/clk-zynq.c
drivers/clk/clk.c
drivers/clk/mxs/clk-imx23.c
drivers/clk/mxs/clk-imx28.c
drivers/clk/mxs/clk.c
drivers/clk/samsung/Makefile [new file with mode: 0644]
drivers/clk/samsung/clk-exynos4.c [new file with mode: 0644]
drivers/clk/samsung/clk-exynos5250.c [new file with mode: 0644]
drivers/clk/samsung/clk-exynos5440.c [new file with mode: 0644]
drivers/clk/samsung/clk-pll.c [new file with mode: 0644]
drivers/clk/samsung/clk-pll.h [new file with mode: 0644]
drivers/clk/samsung/clk.c [new file with mode: 0644]
drivers/clk/samsung/clk.h [new file with mode: 0644]
drivers/clk/spear/spear1340_clock.c
drivers/clk/sunxi/Makefile [new file with mode: 0644]
drivers/clk/sunxi/clk-factors.c [new file with mode: 0644]
drivers/clk/sunxi/clk-factors.h [new file with mode: 0644]
drivers/clk/sunxi/clk-sunxi.c [new file with mode: 0644]
drivers/clk/tegra/Makefile
drivers/clk/tegra/clk-periph-gate.c
drivers/clk/tegra/clk-periph.c
drivers/clk/tegra/clk-pll.c
drivers/clk/tegra/clk-tegra114.c [new file with mode: 0644]
drivers/clk/tegra/clk-tegra20.c
drivers/clk/tegra/clk-tegra30.c
drivers/clk/tegra/clk.c
drivers/clk/tegra/clk.h
drivers/clk/ux500/clk-prcmu.c
drivers/clocksource/Kconfig
drivers/clocksource/Makefile
drivers/clocksource/bcm2835_timer.c
drivers/clocksource/clksrc-of.c
drivers/clocksource/exynos_mct.c [new file with mode: 0644]
drivers/clocksource/mxs_timer.c [new file with mode: 0644]
drivers/clocksource/sunxi_timer.c
drivers/clocksource/tegra20_timer.c
drivers/clocksource/vt8500_timer.c
drivers/cpufreq/acpi-cpufreq.c
drivers/cpufreq/cpufreq_stats.c
drivers/cpufreq/intel_pstate.c
drivers/crypto/caam/caamalg.c
drivers/crypto/caam/compat.h
drivers/crypto/talitos.c
drivers/dma/dw_dmac.c
drivers/dma/dw_dmac_regs.h
drivers/dma/mxs-dma.c
drivers/extcon/extcon-max77693.c
drivers/extcon/extcon-max8997.c
drivers/firmware/Kconfig
drivers/firmware/efivars.c
drivers/gpio/gpio-tegra.c
drivers/gpio/gpiolib-of.c
drivers/gpu/drm/exynos/exynos_drm_fimd.c
drivers/gpu/drm/exynos/exynos_drm_g2d.c
drivers/gpu/drm/exynos/exynos_drm_gem.c
drivers/gpu/drm/exynos/exynos_drm_gem.h
drivers/gpu/drm/exynos/exynos_drm_vidi.c
drivers/gpu/drm/exynos/exynos_mixer.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_panel.c
drivers/gpu/drm/i915/intel_pm.c
drivers/hid/hid-ids.h
drivers/hid/hid-multitouch.c
drivers/hid/usbhid/hid-quirks.c
drivers/i2c/busses/i2c-mxs.c
drivers/infiniband/hw/cxgb4/qp.c
drivers/infiniband/hw/ipath/ipath_verbs.c
drivers/infiniband/hw/qib/Kconfig
drivers/infiniband/hw/qib/qib_driver.c
drivers/infiniband/hw/qib/qib_iba6120.c
drivers/infiniband/hw/qib/qib_init.c
drivers/infiniband/hw/qib/qib_sd7220.c
drivers/infiniband/hw/qib/qib_verbs.c
drivers/infiniband/ulp/ipoib/ipoib_cm.c
drivers/iommu/Kconfig
drivers/iommu/amd_iommu.c
drivers/iommu/amd_iommu_init.c
drivers/iommu/irq_remapping.c
drivers/irqchip/Makefile
drivers/irqchip/irq-mxs.c [new file with mode: 0644]
drivers/media/i2c/m5mols/m5mols_core.c
drivers/media/pci/bt8xx/bttv-driver.c
drivers/media/platform/exynos-gsc/gsc-core.c
drivers/media/platform/s5p-fimc/fimc-core.c
drivers/media/platform/s5p-fimc/fimc-lite-reg.c
drivers/media/platform/s5p-fimc/fimc-lite.c
drivers/media/platform/s5p-fimc/fimc-mdevice.c
drivers/media/platform/s5p-mfc/s5p_mfc.c
drivers/media/platform/s5p-mfc/s5p_mfc_enc.c
drivers/media/rc/Kconfig
drivers/media/v4l2-core/Makefile
drivers/misc/mei/hw-me.c
drivers/misc/mei/init.c
drivers/misc/mei/mei_dev.h
drivers/misc/mei/pci-me.c
drivers/misc/vmw_vmci/vmci_datagram.c
drivers/mmc/host/mxs-mmc.c
drivers/mmc/host/s3cmci.c
drivers/mtd/nand/gpmi-nand/gpmi-nand.c
drivers/mtd/nand/gpmi-nand/gpmi-nand.h
drivers/net/bonding/bond_sysfs.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c
drivers/net/ethernet/freescale/fec.c
drivers/net/ethernet/freescale/fec.h
drivers/net/ethernet/freescale/fec_ptp.c
drivers/net/ethernet/intel/igb/e1000_82575.c
drivers/net/ethernet/intel/igb/igb_hwmon.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/igb/igb_ptp.c
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
drivers/net/ethernet/lantiq_etop.c
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/mellanox/mlx4/eq.c
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
drivers/net/ethernet/nxp/lpc_eth.c
drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/renesas/sh_eth.h
drivers/net/ethernet/ti/cpsw.c
drivers/net/wireless/ath/ath9k/ar9003_calib.c
drivers/net/wireless/ath/ath9k/link.c
drivers/net/wireless/iwlegacy/3945-mac.c
drivers/net/wireless/mwifiex/cmdevt.c
drivers/net/wireless/mwifiex/init.c
drivers/net/wireless/mwifiex/main.h
drivers/net/wireless/mwifiex/scan.c
drivers/net/wireless/mwifiex/sta_ioctl.c
drivers/net/wireless/rtlwifi/usb.c
drivers/pinctrl/mvebu/pinctrl-mvebu.c
drivers/pinctrl/pinconf.c
drivers/pinctrl/pinconf.h
drivers/pinctrl/pinctrl-abx500.c
drivers/pinctrl/pinmux.c
drivers/rtc/rtc-stmp3xxx.c
drivers/spi/spi-mxs.c
drivers/staging/comedi/drivers/s626.c
drivers/staging/iio/adc/mxs-lradc.c
drivers/staging/zcache/Kconfig
drivers/target/target_core_transport.c
drivers/tty/serial/8250/8250.c [deleted file]
drivers/tty/serial/8250/8250_core.c [new file with mode: 0644]
drivers/tty/serial/8250/8250_pci.c
drivers/tty/serial/8250/Kconfig
drivers/tty/serial/8250/Makefile
drivers/tty/serial/atmel_serial.c
drivers/tty/serial/mxs-auart.c
drivers/tty/serial/xilinx_uartps.c
drivers/tty/vt/vc_screen.c
drivers/usb/core/hcd.c
drivers/usb/core/usb-acpi.c
drivers/usb/gadget/Kconfig
drivers/usb/host/ehci-sched.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci-pci.c
drivers/usb/host/xhci-ring.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/phy/Kconfig
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio_ids.h
drivers/usb/serial/usb-serial.c
drivers/vhost/tcm_vhost.c
drivers/video/Kconfig
drivers/video/mxsfb.c
drivers/video/omap/omapfb_main.c
drivers/video/omap2/displays/panel-tpo-td043mtea1.c
drivers/video/omap2/dss/dss_features.c
drivers/xen/Kconfig
drivers/xen/events.c
drivers/xen/fallback.c
drivers/xen/xen-acpi-processor.c
drivers/xen/xen-pciback/pci_stub.c
firmware/Makefile
firmware/intel/sd7220.fw.ihex [new file with mode: 0644]
firmware/qlogic/sd7220.fw.ihex [deleted file]
fs/btrfs/ctree.c
fs/btrfs/disk-io.c
fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/extent_io.h
fs/btrfs/file-item.c
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/ordered-data.c
fs/btrfs/qgroup.c
fs/btrfs/scrub.c
fs/btrfs/send.c
fs/btrfs/volumes.c
fs/dcache.c
fs/internal.h
fs/namespace.c
fs/nfs/blocklayout/blocklayoutdm.c
fs/nfs/idmap.c
fs/nfs/nfs4filelayout.c
fs/nfs/nfs4proc.c
fs/nfs/pnfs.c
fs/nfs/pnfs.h
fs/nfsd/nfscache.c
fs/nfsd/vfs.c
fs/pnode.c
fs/pnode.h
fs/proc/root.c
fs/read_write.c
fs/splice.c
fs/sysfs/dir.c
fs/sysfs/mount.c
include/linux/clk-private.h
include/linux/clk-provider.h
include/linux/clk/mxs.h [new file with mode: 0644]
include/linux/clk/sunxi.h [new file with mode: 0644]
include/linux/clk/tegra.h
include/linux/clocksource.h
include/linux/debug_locks.h
include/linux/freezer.h
include/linux/fs_struct.h
include/linux/irqchip/mxs.h [new file with mode: 0644]
include/linux/mfd/max77693-private.h
include/linux/mm.h
include/linux/mman.h
include/linux/mount.h
include/linux/mxsfb.h [deleted file]
include/linux/spi/mxs-spi.h
include/linux/thermal.h
include/linux/udp.h
include/linux/usb/hcd.h
include/linux/usb/nop-usb-xceiv.h
include/linux/user_namespace.h
include/net/flow_keys.h
include/net/ip_vs.h
include/net/ipip.h
include/uapi/linux/packet_diag.h
include/uapi/linux/unix_diag.h
include/xen/interface/io/blkif.h
include/xen/interface/physdev.h
ipc/mqueue.c
kernel/exit.c
kernel/lockdep.c
kernel/pid_namespace.c
kernel/time/tick-broadcast.c
kernel/user.c
kernel/user_namespace.c
mm/fremap.c
mm/mlock.c
mm/mmap.c
net/8021q/vlan.c
net/bluetooth/sco.c
net/bridge/br_fdb.c
net/core/dev.c
net/core/flow_dissector.c
net/core/scm.c
net/ipv4/af_inet.c
net/ipv4/ipconfig.c
net/ipv4/netfilter/Kconfig
net/ipv4/tcp_input.c
net/ipv4/tcp_output.c
net/ipv4/udp.c
net/ipv6/addrconf.c
net/ipv6/netfilter/ip6t_NPT.c
net/ipv6/udp.c
net/irda/af_irda.c
net/l2tp/l2tp_core.c
net/l2tp/l2tp_core.h
net/l2tp/l2tp_debugfs.c
net/l2tp/l2tp_ip.c
net/l2tp/l2tp_ip6.c
net/l2tp/l2tp_netlink.c
net/l2tp/l2tp_ppp.c
net/netfilter/ipvs/ip_vs_core.c
net/netfilter/ipvs/ip_vs_ctl.c
net/netfilter/ipvs/ip_vs_proto_sctp.c
net/netfilter/nf_conntrack_proto_dccp.c
net/netfilter/nf_conntrack_proto_gre.c
net/netfilter/nf_conntrack_proto_sctp.c
net/netfilter/nf_conntrack_proto_udplite.c
net/netfilter/nfnetlink_queue_core.c
net/netlink/genetlink.c
net/sunrpc/sched.c
net/unix/af_unix.c
security/yama/yama_lsm.c
sound/soc/mxs/mxs-saif.c

diff --git a/Documentation/arm/sunxi/clocks.txt b/Documentation/arm/sunxi/clocks.txt
new file mode 100644 (file)
index 0000000..e09a88a
--- /dev/null
@@ -0,0 +1,56 @@
+Frequently asked questions about the sunxi clock system
+=======================================================
+
+This document contains useful bits of information that people tend to ask
+about the sunxi clock system, as well as accompanying ASCII art when adequate.
+
+Q: Why is the main 24MHz oscillator gatable? Wouldn't that break the
+   system?
+
+A: The 24MHz oscillator allows gating to save power. Indeed, if gated
+   carelessly the system would stop functioning, but with the right
+   steps, one can gate it and keep the system running. Consider this
+   simplified suspend example:
+
+   While the system is operational, you would see something like
+
+      24MHz         32kHz
+       |
+      PLL1
+       \
+        \_ CPU Mux
+             |
+           [CPU]
+
+   When you are about to suspend, you switch the CPU Mux to the 32kHz
+   oscillator:
+
+      24Mhz         32kHz
+       |              |
+      PLL1            |
+                     /
+           CPU Mux _/
+             |
+           [CPU]
+
+    Finally you can gate the main oscillator
+
+                    32kHz
+                      |
+                      |
+                     /
+           CPU Mux _/
+             |
+           [CPU]
+
+Q: Were can I learn more about the sunxi clocks?
+
+A: The linux-sunxi wiki contains a page documenting the clock registers,
+   you can find it at
+
+        http://linux-sunxi.org/A10/CCM
+
+   The authoritative source for information at this time is the ccmu driver
+   released by Allwinner, you can find it at
+
+        https://github.com/linux-sunxi/linux-sunxi/tree/sunxi-3.0/arch/arm/mach-sun4i/clock/ccmu
index 1943fae014fd8a7d98a6af898558535556ffaaf3..4274a546eb578a0171a2b033c514f21ea3fc53db 100644 (file)
@@ -174,9 +174,9 @@ int clk_foo_enable(struct clk_hw *hw)
 };
 
 Below is a matrix detailing which clk_ops are mandatory based upon the
-hardware capbilities of that clock.  A cell marked as "y" means
+hardware capabilities of that clock.  A cell marked as "y" means
 mandatory, a cell marked as "n" implies that either including that
-callback is invalid or otherwise uneccesary.  Empty cells are either
+callback is invalid or otherwise unnecessary.  Empty cells are either
 optional or must be evaluated on a case-by-case basis.
 
                            clock hardware characteristics
index 6888a5efc860b7ad4c64274aeab6bb77346e4ef9..c0105de55cbd7f229ecf813b2acc44d8fd70a216 100644 (file)
@@ -6,6 +6,7 @@ provided by Arteris.
 Required properties:
 - compatible : Should be "ti,omap3-l3-smx" for OMAP3 family
                Should be "ti,omap4-l3-noc" for OMAP4 family
+- reg: Contains L3 register address range for each noc domain.
 - ti,hwmods: "l3_main_1", ... One hwmod for each noc domain.
 
 Examples:
index 8732d4d41f8ba538ce708e6c40677b1560bdeb90..d02e27c764ecc4facab9bceeffa756693d8c0a98 100644 (file)
@@ -1,7 +1,20 @@
 OMAP Timer bindings
 
 Required properties:
-- compatible:          Must be "ti,omap2-timer" for OMAP2+ controllers.
+- compatible:          Should be set to one of the below. Please note that
+                       OMAP44xx devices have timer instances that are 100%
+                       register compatible with OMAP3xxx devices as well as
+                       newer timers that are not 100% register compatible.
+                       So for OMAP44xx devices timer instances may use
+                       different compatible strings.
+
+                       ti,omap2420-timer (applicable to OMAP24xx devices)
+                       ti,omap3430-timer (applicable to OMAP3xxx/44xx devices)
+                       ti,omap4430-timer (applicable to OMAP44xx devices)
+                       ti,omap5430-timer (applicable to OMAP543x devices)
+                       ti,am335x-timer (applicable to AM335x devices)
+                       ti,am335x-timer-1ms (applicable to AM335x devices)
+
 - reg:                 Contains timer register address range (base address and
                        length).
 - interrupts:          Contains the interrupt information for the timer. The
@@ -22,7 +35,7 @@ Optional properties:
 Example:
 
 timer12: timer@48304000 {
-       compatible = "ti,omap2-timer";
+       compatible = "ti,omap3430-timer";
        reg = <0x48304000 0x400>;
        interrupts = <95>;
        ti,hwmods = "timer12"
diff --git a/Documentation/devicetree/bindings/arm/samsung/sysreg.txt b/Documentation/devicetree/bindings/arm/samsung/sysreg.txt
new file mode 100644 (file)
index 0000000..5039c0a
--- /dev/null
@@ -0,0 +1,7 @@
+SAMSUNG S5P/Exynos SoC series System Registers (SYSREG)
+
+Properties:
+ - name : should be 'sysreg';
+ - compatible : should contain "samsung,<chip name>-sysreg", "syscon";
+   For Exynos4 SoC series it should be "samsung,exynos4-sysreg", "syscon";
+ - reg : offset and length of the register set.
index b5846e21cc2e53306fdba8304bf9cf12a6595126..1608a54e90e1541e6a1f7ca918f194f9763ed35e 100644 (file)
@@ -1,19 +1,84 @@
 NVIDIA Tegra Power Management Controller (PMC)
 
-Properties:
+The PMC block interacts with an external Power Management Unit. The PMC
+mostly controls the entry and exit of the system from different sleep
+modes. It provides power-gating controllers for SoC and CPU power-islands.
+
+Required properties:
 - name : Should be pmc
 - compatible : Should contain "nvidia,tegra<chip>-pmc".
 - reg : Offset and length of the register set for the device
+- clocks : Must contain an entry for each entry in clock-names.
+- clock-names : Must include the following entries:
+  "pclk" (The Tegra clock of that name),
+  "clk32k_in" (The 32KHz clock input to Tegra).
+
+Optional properties:
 - nvidia,invert-interrupt : If present, inverts the PMU interrupt signal.
   The PMU is an external Power Management Unit, whose interrupt output
   signal is fed into the PMC. This signal is optionally inverted, and then
   fed into the ARM GIC. The PMC is not involved in the detection or
   handling of this interrupt signal, merely its inversion.
+- nvidia,suspend-mode : The suspend mode that the platform should use.
+  Valid values are 0, 1 and 2:
+  0 (LP0): CPU + Core voltage off and DRAM in self-refresh
+  1 (LP1): CPU voltage off and DRAM in self-refresh
+  2 (LP2): CPU voltage off
+- nvidia,core-power-req-active-high : Boolean, core power request active-high
+- nvidia,sys-clock-req-active-high : Boolean, system clock request active-high
+- nvidia,combined-power-req : Boolean, combined power request for CPU & Core
+- nvidia,cpu-pwr-good-en : Boolean, CPU power good signal (from PMIC to PMC)
+                          is enabled.
+
+Required properties when nvidia,suspend-mode is specified:
+- nvidia,cpu-pwr-good-time : CPU power good time in uS.
+- nvidia,cpu-pwr-off-time : CPU power off time in uS.
+- nvidia,core-pwr-good-time : <Oscillator-stable-time Power-stable-time>
+                             Core power good time in uS.
+- nvidia,core-pwr-off-time : Core power off time in uS.
+
+Required properties when nvidia,suspend-mode=<0>:
+- nvidia,lp0-vec : <start length> Starting address and length of LP0 vector
+  The LP0 vector contains the warm boot code that is executed by AVP when
+  resuming from the LP0 state. The AVP (Audio-Video Processor) is an ARM7
+  processor and always being the first boot processor when chip is power on
+  or resume from deep sleep mode. When the system is resumed from the deep
+  sleep mode, the warm boot code will restore some PLLs, clocks and then
+  bring up CPU0 for resuming the system.
 
 Example:
 
+/ SoC dts including file
 pmc@7000f400 {
        compatible = "nvidia,tegra20-pmc";
        reg = <0x7000e400 0x400>;
+       clocks = <&tegra_car 110>, <&clk32k_in>;
+       clock-names = "pclk", "clk32k_in";
        nvidia,invert-interrupt;
+       nvidia,suspend-mode = <1>;
+       nvidia,cpu-pwr-good-time = <2000>;
+       nvidia,cpu-pwr-off-time = <100>;
+       nvidia,core-pwr-good-time = <3845 3845>;
+       nvidia,core-pwr-off-time = <458>;
+       nvidia,core-power-req-active-high;
+       nvidia,sys-clock-req-active-high;
+       nvidia,lp0-vec = <0xbdffd000 0x2000>;
+};
+
+/ Tegra board dts file
+{
+       ...
+       clocks {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               clk32k_in: clock {
+                       compatible = "fixed-clock";
+                       reg=<0>;
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+               };
+       };
+       ...
 };
diff --git a/Documentation/devicetree/bindings/clock/axi-clkgen.txt b/Documentation/devicetree/bindings/clock/axi-clkgen.txt
new file mode 100644 (file)
index 0000000..028b493
--- /dev/null
@@ -0,0 +1,22 @@
+Binding for the axi-clkgen clock generator
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible : shall be "adi,axi-clkgen".
+- #clock-cells : from common clock binding; Should always be set to 0.
+- reg : Address and length of the axi-clkgen register set.
+- clocks : Phandle and clock specifier for the parent clock.
+
+Optional properties:
+- clock-output-names : From common clock binding.
+
+Example:
+       clock@0xff000000 {
+               compatible = "adi,axi-clkgen";
+               #clock-cells = <0>;
+               reg = <0xff000000 0x1000>;
+               clocks = <&osc 1>;
+       };
diff --git a/Documentation/devicetree/bindings/clock/exynos4-clock.txt b/Documentation/devicetree/bindings/clock/exynos4-clock.txt
new file mode 100644 (file)
index 0000000..ea5e26f
--- /dev/null
@@ -0,0 +1,288 @@
+* Samsung Exynos4 Clock Controller
+
+The Exynos4 clock controller generates and supplies clock to various controllers
+within the Exynos4 SoC. The clock binding described here is applicable to all
+SoC's in the Exynos4 family.
+
+Required Properties:
+
+- comptible: should be one of the following.
+  - "samsung,exynos4210-clock" - controller compatible with Exynos4210 SoC.
+  - "samsung,exynos4412-clock" - controller compatible with Exynos4412 SoC.
+
+- reg: physical base address of the controller and length of memory mapped
+  region.
+
+- #clock-cells: should be 1.
+
+The following is the list of clocks generated by the controller. Each clock is
+assigned an identifier and client nodes use this identifier to specify the
+clock which they consume. Some of the clocks are available only on a particular
+Exynos4 SoC and this is specified where applicable.
+
+
+                [Core Clocks]
+
+  Clock               ID      SoC (if specific)
+  -----------------------------------------------
+
+  xxti                1
+  xusbxti             2
+  fin_pll             3
+  fout_apll           4
+  fout_mpll           5
+  fout_epll           6
+  fout_vpll           7
+  sclk_apll           8
+  sclk_mpll           9
+  sclk_epll           10
+  sclk_vpll           11
+  arm_clk             12
+  aclk200             13
+  aclk100             14
+  aclk160             15
+  aclk133             16
+  mout_mpll_user_t    17      Exynos4x12
+  mout_mpll_user_c    18      Exynos4x12
+  mout_core           19
+  mout_apll           20
+
+
+            [Clock Gate for Special Clocks]
+
+  Clock               ID      SoC (if specific)
+  -----------------------------------------------
+
+  sclk_fimc0          128
+  sclk_fimc1          129
+  sclk_fimc2          130
+  sclk_fimc3          131
+  sclk_cam0           132
+  sclk_cam1           133
+  sclk_csis0          134
+  sclk_csis1          135
+  sclk_hdmi           136
+  sclk_mixer          137
+  sclk_dac            138
+  sclk_pixel          139
+  sclk_fimd0          140
+  sclk_mdnie0         141     Exynos4412
+  sclk_mdnie_pwm0 12  142     Exynos4412
+  sclk_mipi0          143
+  sclk_audio0         144
+  sclk_mmc0           145
+  sclk_mmc1           146
+  sclk_mmc2           147
+  sclk_mmc3           148
+  sclk_mmc4           149
+  sclk_sata           150     Exynos4210
+  sclk_uart0          151
+  sclk_uart1          152
+  sclk_uart2          153
+  sclk_uart3          154
+  sclk_uart4          155
+  sclk_audio1         156
+  sclk_audio2         157
+  sclk_spdif          158
+  sclk_spi0           159
+  sclk_spi1           160
+  sclk_spi2           161
+  sclk_slimbus        162
+  sclk_fimd1          163     Exynos4210
+  sclk_mipi1          164     Exynos4210
+  sclk_pcm1           165
+  sclk_pcm2           166
+  sclk_i2s1           167
+  sclk_i2s2           168
+  sclk_mipihsi        169     Exynos4412
+  sclk_mfc            170
+  sclk_pcm0           171
+  sclk_g3d            172
+  sclk_pwm_isp        173     Exynos4x12
+  sclk_spi0_isp       174     Exynos4x12
+  sclk_spi1_isp       175     Exynos4x12
+  sclk_uart_isp       176     Exynos4x12
+
+             [Peripheral Clock Gates]
+
+  Clock               ID      SoC (if specific)
+  -----------------------------------------------
+
+  fimc0               256
+  fimc1               257
+  fimc2               258
+  fimc3               259
+  csis0               260
+  csis1               261
+  jpeg                262
+  smmu_fimc0          263
+  smmu_fimc1          264
+  smmu_fimc2          265
+  smmu_fimc3          266
+  smmu_jpeg           267
+  vp                  268
+  mixer               269
+  tvenc               270     Exynos4210
+  hdmi                271
+  smmu_tv             272
+  mfc                 273
+  smmu_mfcl           274
+  smmu_mfcr           275
+  g3d                 276
+  g2d                 277     Exynos4210
+  rotator             278     Exynos4210
+  mdma                279     Exynos4210
+  smmu_g2d            280     Exynos4210
+  smmu_rotator        281     Exynos4210
+  smmu_mdma           282     Exynos4210
+  fimd0               283
+  mie0                284
+  mdnie0              285     Exynos4412
+  dsim0               286
+  smmu_fimd0          287
+  fimd1               288     Exynos4210
+  mie1                289     Exynos4210
+  dsim1               290     Exynos4210
+  smmu_fimd1          291     Exynos4210
+  pdma0               292
+  pdma1               293
+  pcie_phy            294
+  sata_phy            295     Exynos4210
+  tsi                 296
+  sdmmc0              297
+  sdmmc1              298
+  sdmmc2              299
+  sdmmc3              300
+  sdmmc4              301
+  sata                302     Exynos4210
+  sromc               303
+  usb_host            304
+  usb_device          305
+  pcie                306
+  onenand             307
+  nfcon               308
+  smmu_pcie           309
+  gps                 310
+  smmu_gps            311
+  uart0               312
+  uart1               313
+  uart2               314
+  uart3               315
+  uart4               316
+  i2c0                317
+  i2c1                318
+  i2c2                319
+  i2c3                320
+  i2c4                321
+  i2c5                322
+  i2c6                323
+  i2c7                324
+  i2c_hdmi            325
+  tsadc               326
+  spi0                327
+  spi1                328
+  spi2                329
+  i2s1                330
+  i2s2                331
+  pcm0                332
+  i2s0                333
+  pcm1                334
+  pcm2                335
+  pwm                 336
+  slimbus             337
+  spdif               338
+  ac97                339
+  modemif             340
+  chipid              341
+  sysreg              342
+  hdmi_cec            343
+  mct                 344
+  wdt                 345
+  rtc                 346
+  keyif               347
+  audss               348
+  mipi_hsi            349     Exynos4210
+  mdma2               350     Exynos4210
+  pixelasyncm0        351
+  pixelasyncm1        352
+  fimc_lite0          353     Exynos4x12
+  fimc_lite1          354     Exynos4x12
+  ppmuispx            355     Exynos4x12
+  ppmuispmx           356     Exynos4x12
+  fimc_isp            357     Exynos4x12
+  fimc_drc            358     Exynos4x12
+  fimc_fd             359     Exynos4x12
+  mcuisp              360     Exynos4x12
+  gicisp              361     Exynos4x12
+  smmu_isp            362     Exynos4x12
+  smmu_drc            363     Exynos4x12
+  smmu_fd             364     Exynos4x12
+  smmu_lite0          365     Exynos4x12
+  smmu_lite1          366     Exynos4x12
+  mcuctl_isp          367     Exynos4x12
+  mpwm_isp            368     Exynos4x12
+  i2c0_isp            369     Exynos4x12
+  i2c1_isp            370     Exynos4x12
+  mtcadc_isp          371     Exynos4x12
+  pwm_isp             372     Exynos4x12
+  wdt_isp             373     Exynos4x12
+  uart_isp            374     Exynos4x12
+  asyncaxim           375     Exynos4x12
+  smmu_ispcx          376     Exynos4x12
+  spi0_isp            377     Exynos4x12
+  spi1_isp            378     Exynos4x12
+  pwm_isp_sclk        379     Exynos4x12
+  spi0_isp_sclk       380     Exynos4x12
+  spi1_isp_sclk       381     Exynos4x12
+  uart_isp_sclk       382     Exynos4x12
+
+               [Mux Clocks]
+
+  Clock                        ID      SoC (if specific)
+  -----------------------------------------------
+
+  mout_fimc0           384
+  mout_fimc1           385
+  mout_fimc2           386
+  mout_fimc3           387
+  mout_cam0            388
+  mout_cam1            389
+  mout_csis0           390
+  mout_csis1           391
+  mout_g3d0            392
+  mout_g3d1            393
+  mout_g3d             394
+  aclk400_mcuisp       395     Exynos4x12
+
+               [Div Clocks]
+
+  Clock                        ID      SoC (if specific)
+  -----------------------------------------------
+
+  div_isp0             450     Exynos4x12
+  div_isp1             451     Exynos4x12
+  div_mcuisp0          452     Exynos4x12
+  div_mcuisp1          453     Exynos4x12
+  div_aclk200          454     Exynos4x12
+  div_aclk400_mcuisp   455     Exynos4x12
+
+
+Example 1: An example of a clock controller node is listed below.
+
+       clock: clock-controller@0x10030000 {
+               compatible = "samsung,exynos4210-clock";
+               reg = <0x10030000 0x20000>;
+               #clock-cells = <1>;
+       };
+
+Example 2: UART controller node that consumes the clock generated by the clock
+          controller. Refer to the standard clock bindings for information
+          about 'clocks' and 'clock-names' property.
+
+       serial@13820000 {
+               compatible = "samsung,exynos4210-uart";
+               reg = <0x13820000 0x100>;
+               interrupts = <0 54 0>;
+               clocks = <&clock 314>, <&clock 153>;
+               clock-names = "uart", "clk_uart_baud0";
+       };
diff --git a/Documentation/devicetree/bindings/clock/exynos5250-clock.txt b/Documentation/devicetree/bindings/clock/exynos5250-clock.txt
new file mode 100644 (file)
index 0000000..781a627
--- /dev/null
@@ -0,0 +1,177 @@
+* Samsung Exynos5250 Clock Controller
+
+The Exynos5250 clock controller generates and supplies clock to various
+controllers within the Exynos5250 SoC.
+
+Required Properties:
+
+- comptible: should be one of the following.
+  - "samsung,exynos5250-clock" - controller compatible with Exynos5250 SoC.
+
+- reg: physical base address of the controller and length of memory mapped
+  region.
+
+- #clock-cells: should be 1.
+
+The following is the list of clocks generated by the controller. Each clock is
+assigned an identifier and client nodes use this identifier to specify the
+clock which they consume.
+
+
+       [Core Clocks]
+
+  Clock                        ID
+  ----------------------------
+
+  fin_pll              1
+
+  [Clock Gate for Special Clocks]
+
+  Clock                        ID
+  ----------------------------
+
+  sclk_cam_bayer       128
+  sclk_cam0            129
+  sclk_cam1            130
+  sclk_gscl_wa         131
+  sclk_gscl_wb         132
+  sclk_fimd1           133
+  sclk_mipi1           134
+  sclk_dp              135
+  sclk_hdmi            136
+  sclk_pixel           137
+  sclk_audio0          138
+  sclk_mmc0            139
+  sclk_mmc1            140
+  sclk_mmc2            141
+  sclk_mmc3            142
+  sclk_sata            143
+  sclk_usb3            144
+  sclk_jpeg            145
+  sclk_uart0           146
+  sclk_uart1           147
+  sclk_uart2           148
+  sclk_uart3           149
+  sclk_pwm             150
+  sclk_audio1          151
+  sclk_audio2          152
+  sclk_spdif           153
+  sclk_spi0            154
+  sclk_spi1            155
+  sclk_spi2            156
+
+
+   [Peripheral Clock Gates]
+
+  Clock                        ID
+  ----------------------------
+
+  gscl0                        256
+  gscl1                        257
+  gscl2                        258
+  gscl3                        259
+  gscl_wa              260
+  gscl_wb              261
+  smmu_gscl0           262
+  smmu_gscl1           263
+  smmu_gscl2           264
+  smmu_gscl3           265
+  mfc                  266
+  smmu_mfcl            267
+  smmu_mfcr            268
+  rotator              269
+  jpeg                 270
+  mdma1                        271
+  smmu_rotator         272
+  smmu_jpeg            273
+  smmu_mdma1           274
+  pdma0                        275
+  pdma1                        276
+  sata                 277
+  usbotg               278
+  mipi_hsi             279
+  sdmmc0               280
+  sdmmc1               281
+  sdmmc2               282
+  sdmmc3               283
+  sromc                        284
+  usb2                 285
+  usb3                 286
+  sata_phyctrl         287
+  sata_phyi2c          288
+  uart0                        289
+  uart1                        290
+  uart2                        291
+  uart3                        292
+  uart4                        293
+  i2c0                 294
+  i2c1                 295
+  i2c2                 296
+  i2c3                 297
+  i2c4                 298
+  i2c5                 299
+  i2c6                 300
+  i2c7                 301
+  i2c_hdmi             302
+  adc                  303
+  spi0                 304
+  spi1                 305
+  spi2                 306
+  i2s1                 307
+  i2s2                 308
+  pcm1                 309
+  pcm2                 310
+  pwm                  311
+  spdif                        312
+  ac97                 313
+  hsi2c0               314
+  hsi2c1               315
+  hs12c2               316
+  hs12c3               317
+  chipid               318
+  sysreg               319
+  pmu                  320
+  cmu_top              321
+  cmu_core             322
+  cmu_mem              323
+  tzpc0                        324
+  tzpc1                        325
+  tzpc2                        326
+  tzpc3                        327
+  tzpc4                        328
+  tzpc5                        329
+  tzpc6                        330
+  tzpc7                        331
+  tzpc8                        332
+  tzpc9                        333
+  hdmi_cec             334
+  mct                  335
+  wdt                  336
+  rtc                  337
+  tmu                  338
+  fimd1                        339
+  mie1                 340
+  dsim0                        341
+  dp                   342
+  mixer                        343
+  hdmi                 345
+
+Example 1: An example of a clock controller node is listed below.
+
+       clock: clock-controller@0x10010000 {
+               compatible = "samsung,exynos5250-clock";
+               reg = <0x10010000 0x30000>;
+               #clock-cells = <1>;
+       };
+
+Example 2: UART controller node that consumes the clock generated by the clock
+          controller. Refer to the standard clock bindings for information
+          about 'clocks' and 'clock-names' property.
+
+       serial@13820000 {
+               compatible = "samsung,exynos4210-uart";
+               reg = <0x13820000 0x100>;
+               interrupts = <0 54 0>;
+               clocks = <&clock 314>, <&clock 153>;
+               clock-names = "uart", "clk_uart_baud0";
+       };
diff --git a/Documentation/devicetree/bindings/clock/exynos5440-clock.txt b/Documentation/devicetree/bindings/clock/exynos5440-clock.txt
new file mode 100644 (file)
index 0000000..4499e99
--- /dev/null
@@ -0,0 +1,61 @@
+* Samsung Exynos5440 Clock Controller
+
+The Exynos5440 clock controller generates and supplies clock to various
+controllers within the Exynos5440 SoC.
+
+Required Properties:
+
+- comptible: should be "samsung,exynos5440-clock".
+
+- reg: physical base address of the controller and length of memory mapped
+  region.
+
+- #clock-cells: should be 1.
+
+The following is the list of clocks generated by the controller. Each clock is
+assigned an identifier and client nodes use this identifier to specify the
+clock which they consume.
+
+
+       [Core Clocks]
+
+  Clock                        ID
+  ----------------------------
+
+  xtal                 1
+  arm_clk              2
+
+   [Peripheral Clock Gates]
+
+  Clock                        ID
+  ----------------------------
+
+  spi_baud             16
+  pb0_250              17
+  pr0_250              18
+  pr1_250              19
+  b_250                        20
+  b_125                        21
+  b_200                        22
+  sata                 23
+  usb                  24
+  gmac0                        25
+  cs250                        26
+  pb0_250_o            27
+  pr0_250_o            28
+  pr1_250_o            29
+  b_250_o              30
+  b_125_o              31
+  b_200_o              32
+  sata_o               33
+  usb_o                        34
+  gmac0_o              35
+  cs250_o              36
+
+Example: An example of a clock controller node is listed below.
+
+       clock: clock-controller@0x10010000 {
+               compatible = "samsung,exynos5440-clock";
+               reg = <0x160000 0x10000>;
+               #clock-cells = <1>;
+       };
diff --git a/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt b/Documentation/devicetree/bindings/clock/nvidia,tegra114-car.txt
new file mode 100644 (file)
index 0000000..d6cb083
--- /dev/null
@@ -0,0 +1,303 @@
+NVIDIA Tegra114 Clock And Reset Controller
+
+This binding uses the common clock binding:
+Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+The CAR (Clock And Reset) Controller on Tegra is the HW module responsible
+for muxing and gating Tegra's clocks, and setting their rates.
+
+Required properties :
+- compatible : Should be "nvidia,tegra114-car"
+- reg : Should contain CAR registers location and length
+- clocks : Should contain phandle and clock specifiers for two clocks:
+  the 32 KHz "32k_in", and the board-specific oscillator "osc".
+- #clock-cells : Should be 1.
+  In clock consumers, this cell represents the clock ID exposed by the CAR.
+
+  The first 160 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB
+  registers. These IDs often match those in the CAR's RST_DEVICES registers,
+  but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In
+  this case, those clocks are assigned IDs above 160 in order to highlight
+  this issue. Implementations that interpret these clock IDs as bit values
+  within the CLK_OUT_ENB or RST_DEVICES registers should be careful to
+  explicitly handle these special cases.
+
+  The balance of the clocks controlled by the CAR are assigned IDs of 160 and
+  above.
+
+  0    unassigned
+  1    unassigned
+  2    unassigned
+  3    unassigned
+  4    rtc
+  5    timer
+  6    uarta
+  7    unassigned      (register bit affects uartb and vfir)
+  8    unassigned
+  9    sdmmc2
+  10   unassigned      (register bit affects spdif_in and spdif_out)
+  11   i2s1
+  12   i2c1
+  13   ndflash
+  14   sdmmc1
+  15   sdmmc4
+  16   unassigned
+  17   pwm
+  18   i2s2
+  19   epp
+  20   unassigned      (register bit affects vi and vi_sensor)
+  21   2d
+  22   usbd
+  23   isp
+  24   3d
+  25   unassigned
+  26   disp2
+  27   disp1
+  28   host1x
+  29   vcp
+  30   i2s0
+  31   unassigned
+
+  32   unassigned
+  33   unassigned
+  34   apbdma
+  35   unassigned
+  36   kbc
+  37   unassigned
+  38   unassigned
+  39   unassigned      (register bit affects fuse and fuse_burn)
+  40   kfuse
+  41   sbc1
+  42   nor
+  43   unassigned
+  44   sbc2
+  45   unassigned
+  46   sbc3
+  47   i2c5
+  48   dsia
+  49   unassigned
+  50   mipi
+  51   hdmi
+  52   csi
+  53   unassigned
+  54   i2c2
+  55   uartc
+  56   mipi-cal
+  57   emc
+  58   usb2
+  59   usb3
+  60   msenc
+  61   vde
+  62   bsea
+  63   bsev
+
+  64   unassigned
+  65   uartd
+  66   unassigned
+  67   i2c3
+  68   sbc4
+  69   sdmmc3
+  70   unassigned
+  71   owr
+  72   afi
+  73   csite
+  74   unassigned
+  75   unassigned
+  76   la
+  77   trace
+  78   soc_therm
+  79   dtv
+  80   ndspeed
+  81   i2cslow
+  82   dsib
+  83   tsec
+  84   unassigned
+  85   unassigned
+  86   unassigned
+  87   unassigned
+  88   unassigned
+  89   xusb_host
+  90   unassigned
+  91   msenc
+  92   csus
+  93   unassigned
+  94   unassigned
+  95   unassigned      (bit affects xusb_dev and xusb_dev_src)
+
+  96   unassigned
+  97   unassigned
+  98   unassigned
+  99   mselect
+  100  tsensor
+  101  i2s3
+  102  i2s4
+  103  i2c4
+  104  sbc5
+  105  sbc6
+  106  d_audio
+  107  apbif
+  108  dam0
+  109  dam1
+  110  dam2
+  111  hda2codec_2x
+  112  unassigned
+  113  audio0_2x
+  114  audio1_2x
+  115  audio2_2x
+  116  audio3_2x
+  117  audio4_2x
+  118  spdif_2x
+  119  actmon
+  120  extern1
+  121  extern2
+  122  extern3
+  123  unassigned
+  124  unassigned
+  125  hda
+  126  unassigned
+  127  se
+
+  128  hda2hdmi
+  129  unassigned
+  130  unassigned
+  131  unassigned
+  132  unassigned
+  133  unassigned
+  134  unassigned
+  135  unassigned
+  136  unassigned
+  137  unassigned
+  138  unassigned
+  139  unassigned
+  140  unassigned
+  141  unassigned
+  142  unassigned
+  143  unassigned      (bit affects xusb_falcon_src, xusb_fs_src,
+                        xusb_host_src and xusb_ss_src)
+  144  cilab
+  145  cilcd
+  146  cile
+  147  dsialp
+  148  dsiblp
+  149  unassigned
+  150  dds
+  151  unassigned
+  152  dp2
+  153  amx
+  154  adx
+  155  unassigned      (bit affects dfll_ref and dfll_soc)
+  156  xusb_ss
+
+  192  uartb
+  193  vfir
+  194  spdif_in
+  195  spdif_out
+  196  vi
+  197  vi_sensor
+  198  fuse
+  199  fuse_burn
+  200  clk_32k
+  201  clk_m
+  202  clk_m_div2
+  203  clk_m_div4
+  204  pll_ref
+  205  pll_c
+  206  pll_c_out1
+  207  pll_c2
+  208  pll_c3
+  209  pll_m
+  210  pll_m_out1
+  211  pll_p
+  212  pll_p_out1
+  213  pll_p_out2
+  214  pll_p_out3
+  215  pll_p_out4
+  216  pll_a
+  217  pll_a_out0
+  218  pll_d
+  219  pll_d_out0
+  220  pll_d2
+  221  pll_d2_out0
+  222  pll_u
+  223  pll_u_480M
+  224  pll_u_60M
+  225  pll_u_48M
+  226  pll_u_12M
+  227  pll_x
+  228  pll_x_out0
+  229  pll_re_vco
+  230  pll_re_out
+  231  pll_e_out0
+  232  spdif_in_sync
+  233  i2s0_sync
+  234  i2s1_sync
+  235  i2s2_sync
+  236  i2s3_sync
+  237  i2s4_sync
+  238  vimclk_sync
+  239  audio0
+  240  audio1
+  241  audio2
+  242  audio3
+  243  audio4
+  244  spdif
+  245  clk_out_1
+  246  clk_out_2
+  247  clk_out_3
+  248  blink
+  252  xusb_host_src
+  253  xusb_falcon_src
+  254  xusb_fs_src
+  255  xusb_ss_src
+  256  xusb_dev_src
+  257  xusb_dev
+  258  xusb_hs_src
+  259  sclk
+  260  hclk
+  261  pclk
+  262  cclk_g
+  263  cclk_lp
+  264  dfll_ref
+  265  dfll_soc
+
+Example SoC include file:
+
+/ {
+       tegra_car: clock {
+               compatible = "nvidia,tegra114-car";
+               reg = <0x60006000 0x1000>;
+               #clock-cells = <1>;
+       };
+
+       usb@c5004000 {
+               clocks = <&tegra_car 58>; /* usb2 */
+       };
+};
+
+Example board file:
+
+/ {
+       clocks {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               osc: clock@0 {
+                       compatible = "fixed-clock";
+                       reg = <0>;
+                       #clock-cells = <0>;
+                       clock-frequency = <12000000>;
+               };
+
+               clk_32k: clock@1 {
+                       compatible = "fixed-clock";
+                       reg = <1>;
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+               };
+       };
+
+       &tegra_car {
+               clocks = <&clk_32k> <&osc>;
+       };
+};
index 0921fac735289ca3e171d918567a2c58163f0f66..e885680f6b4524116d27331f1c44904c9c082e85 100644 (file)
@@ -120,8 +120,8 @@ Required properties :
   90   clk_d
   91   unassigned
   92   sus
-  93   cdev1
-  94   cdev2
+  93   cdev2
+  94   cdev1
   95   unassigned
 
   96   uart2
diff --git a/Documentation/devicetree/bindings/clock/sunxi.txt b/Documentation/devicetree/bindings/clock/sunxi.txt
new file mode 100644 (file)
index 0000000..20b8479
--- /dev/null
@@ -0,0 +1,44 @@
+Device Tree Clock bindings for arch-sunxi
+
+This binding uses the common clock binding[1].
+
+[1] Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Required properties:
+- compatible : shall be one of the following:
+       "allwinner,sun4i-osc-clk" - for a gatable oscillator
+       "allwinner,sun4i-pll1-clk" - for the main PLL clock
+       "allwinner,sun4i-cpu-clk" - for the CPU multiplexer clock
+       "allwinner,sun4i-axi-clk" - for the AXI clock
+       "allwinner,sun4i-ahb-clk" - for the AHB clock
+       "allwinner,sun4i-apb0-clk" - for the APB0 clock
+       "allwinner,sun4i-apb1-clk" - for the APB1 clock
+       "allwinner,sun4i-apb1-mux-clk" - for the APB1 clock muxing
+
+Required properties for all clocks:
+- reg : shall be the control register address for the clock.
+- clocks : shall be the input parent clock(s) phandle for the clock
+- #clock-cells : from common clock binding; shall be set to 0.
+
+For example:
+
+osc24M: osc24M@01c20050 {
+       #clock-cells = <0>;
+       compatible = "allwinner,sun4i-osc-clk";
+       reg = <0x01c20050 0x4>;
+       clocks = <&osc24M_fixed>;
+};
+
+pll1: pll1@01c20000 {
+       #clock-cells = <0>;
+       compatible = "allwinner,sun4i-pll1-clk";
+       reg = <0x01c20000 0x4>;
+       clocks = <&osc24M>;
+};
+
+cpu: cpu@01c20054 {
+       #clock-cells = <0>;
+       compatible = "allwinner,sun4i-cpu-clk";
+       reg = <0x01c20054 0x4>;
+       clocks = <&osc32k>, <&osc24M>, <&pll1>;
+};
index ded0398d3bdc3f95d453f2c06165446a1fe5db84..a4873e5e3e36de172c49f59108360e32aca9fefd 100644 (file)
@@ -3,17 +3,58 @@
 Required properties:
 - compatible : Should be "fsl,<chip>-dma-apbh" or "fsl,<chip>-dma-apbx"
 - reg : Should contain registers location and length
+- interrupts : Should contain the interrupt numbers of DMA channels.
+  If a channel is empty/reserved, 0 should be filled in place.
+- #dma-cells : Must be <1>.  The number cell specifies the channel ID.
+- dma-channels : Number of channels supported by the DMA controller
+
+Optional properties:
+- interrupt-names : Name of DMA channel interrupts
 
 Supported chips:
 imx23, imx28.
 
 Examples:
-dma-apbh@80004000 {
+
+dma_apbh: dma-apbh@80004000 {
        compatible = "fsl,imx28-dma-apbh";
-       reg = <0x80004000 2000>;
+       reg = <0x80004000 0x2000>;
+       interrupts = <82 83 84 85
+                     88 88 88 88
+                     88 88 88 88
+                     87 86 0 0>;
+       interrupt-names = "ssp0", "ssp1", "ssp2", "ssp3",
+                         "gpmi0", "gmpi1", "gpmi2", "gmpi3",
+                         "gpmi4", "gmpi5", "gpmi6", "gmpi7",
+                         "hsadc", "lcdif", "empty", "empty";
+       #dma-cells = <1>;
+       dma-channels = <16>;
 };
 
-dma-apbx@80024000 {
+dma_apbx: dma-apbx@80024000 {
        compatible = "fsl,imx28-dma-apbx";
-       reg = <0x80024000 2000>;
+       reg = <0x80024000 0x2000>;
+       interrupts = <78 79 66 0
+                     80 81 68 69
+                     70 71 72 73
+                     74 75 76 77>;
+       interrupt-names = "auart4-rx", "aurat4-tx", "spdif-tx", "empty",
+                         "saif0", "saif1", "i2c0", "i2c1",
+                         "auart0-rx", "auart0-tx", "auart1-rx", "auart1-tx",
+                         "auart2-rx", "auart2-tx", "auart3-rx", "auart3-tx";
+       #dma-cells = <1>;
+       dma-channels = <16>;
+};
+
+DMA clients connected to the MXS DMA controller must use the format
+described in the dma.txt file.
+
+Examples:
+
+auart0: serial@8006a000 {
+       compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+       reg = <0x8006a000 0x2000>;
+       interrupts = <112>;
+       dmas = <&dma_apbx 8>, <&dma_apbx 9>;
+       dma-names = "rx", "tx";
 };
index b41e5e52a676c4cf28f7c0529e9cb64d46a3b0a6..96ec5179c8a00199e2056ee574c3c55aef37bae3 100644 (file)
@@ -5,9 +5,16 @@ Required properties:
   imx23 and imx28.
 - reg: Address and length of the register set for lcdif
 - interrupts: Should contain lcdif interrupts
+- display : phandle to display node (see below for details)
 
-Optional properties:
-- panel-enable-gpios : Should specify the gpio for panel enable
+* display node
+
+Required properties:
+- bits-per-pixel : <16> for RGB565, <32> for RGB888/666.
+- bus-width : number of data lines.  Could be <8>, <16>, <18> or <24>.
+
+Required sub-node:
+- display-timings : Refer to binding doc display-timing.txt for details.
 
 Examples:
 
@@ -15,5 +22,28 @@ lcdif@80030000 {
        compatible = "fsl,imx28-lcdif";
        reg = <0x80030000 2000>;
        interrupts = <38 86>;
-       panel-enable-gpios = <&gpio3 30 0>;
+
+       display: display {
+               bits-per-pixel = <32>;
+               bus-width = <24>;
+
+               display-timings {
+                       native-mode = <&timing0>;
+                       timing0: timing0 {
+                               clock-frequency = <33500000>;
+                               hactive = <800>;
+                               vactive = <480>;
+                               hfront-porch = <164>;
+                               hback-porch = <89>;
+                               hsync-len = <10>;
+                               vback-porch = <23>;
+                               vfront-porch = <10>;
+                               vsync-len = <10>;
+                               hsync-active = <0>;
+                               vsync-active = <0>;
+                               de-active = <1>;
+                               pixelclk-active = <0>;
+                       };
+               };
+       };
 };
index bff51a2fee1eae7d387b40ea913e04782554bf68..a56e3a53a3604265cb7212a40e9453916f8a1197 100644 (file)
@@ -5,12 +5,12 @@ Required properties:
   - "ti,omap2-gpio" for OMAP2 controllers
   - "ti,omap3-gpio" for OMAP3 controllers
   - "ti,omap4-gpio" for OMAP4 controllers
+- gpio-controller : Marks the device node as a GPIO controller.
 - #gpio-cells : Should be two.
   - first cell is the pin number
   - second cell is used to specify optional parameters (unused)
-- gpio-controller : Marks the device node as a GPIO controller.
+- interrupt-controller: Mark the device node as an interrupt controller.
 - #interrupt-cells : Should be 2.
-- interrupt-controller: Mark the device node as an interrupt controller
   The first cell is the GPIO number.
   The second cell is used to specify flags:
     bits[3:0] trigger type and level flags:
@@ -29,8 +29,8 @@ Example:
 gpio4: gpio4 {
     compatible = "ti,omap4-gpio";
     ti,hwmods = "gpio4";
-    #gpio-cells = <2>;
     gpio-controller;
-    #interrupt-cells = <2>;
+    #gpio-cells = <2>;
     interrupt-controller;
+    #interrupt-cells = <2>;
 };
diff --git a/Documentation/devicetree/bindings/gpu/samsung-g2d.txt b/Documentation/devicetree/bindings/gpu/samsung-g2d.txt
new file mode 100644 (file)
index 0000000..2b14a94
--- /dev/null
@@ -0,0 +1,20 @@
+* Samsung 2D Graphics Accelerator
+
+Required properties:
+  - compatible : value should be one among the following:
+       (a) "samsung,s5pv210-g2d" for G2D IP present in S5PV210 & Exynos4210 SoC
+       (b) "samsung,exynos4212-g2d" for G2D IP present in Exynos4x12 SoCs
+       (c) "samsung,exynos5250-g2d" for G2D IP present in Exynos5250 SoC
+
+  - reg : Physical base address of the IP registers and length of memory
+         mapped region.
+
+  - interrupts : G2D interrupt number to the CPU.
+
+Example:
+       g2d@12800000 {
+               compatible = "samsung,s5pv210-g2d";
+               reg = <0x12800000 0x1000>;
+               interrupts = <0 89 0>;
+               status = "disabled";
+       };
index 7a3fe9e5f4cbb1a95cd23f2241f649afb4e3df87..4e1c8ac01eba54da7685cbbaf69109e1ff69634a 100644 (file)
@@ -3,10 +3,13 @@
 Required properties:
 - compatible: Should be "fsl,<chip>-i2c"
 - reg: Should contain registers location and length
-- interrupts: Should contain ERROR and DMA interrupts
+- interrupts: Should contain ERROR interrupt number
 - clock-frequency: Desired I2C bus clock frequency in Hz.
                    Only 100000Hz and 400000Hz modes are supported.
-- fsl,i2c-dma-channel: APBX DMA channel for the I2C
+- dmas: DMA specifier, consisting of a phandle to DMA controller node
+  and I2C DMA channel ID.
+  Refer to dma.txt and fsl-mxs-dma.txt for details.
+- dma-names: Must be "rx-tx".
 
 Examples:
 
@@ -15,7 +18,8 @@ i2c0: i2c@80058000 {
        #size-cells = <0>;
        compatible = "fsl,imx28-i2c";
        reg = <0x80058000 2000>;
-       interrupts = <111 68>;
+       interrupts = <111>;
        clock-frequency = <100000>;
-       fsl,i2c-dma-channel = <6>;
+       dmas = <&dma_apbx 6>;
+       dma-names = "rx-tx";
 };
diff --git a/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt b/Documentation/devicetree/bindings/i2c/nvidia,tegra20-i2c.txt
new file mode 100644 (file)
index 0000000..ef77cc7
--- /dev/null
@@ -0,0 +1,60 @@
+NVIDIA Tegra20/Tegra30/Tegra114 I2C controller driver.
+
+Required properties:
+- compatible : should be:
+       "nvidia,tegra114-i2c"
+       "nvidia,tegra30-i2c"
+       "nvidia,tegra20-i2c"
+       "nvidia,tegra20-i2c-dvc"
+  Details of compatible are as follows:
+  nvidia,tegra20-i2c-dvc: Tegra20 has specific I2C controller called as DVC I2C
+       controller. This only support master mode of I2C communication. Register
+       interface/offset and interrupts handling are different than generic I2C
+       controller. Driver of DVC I2C controller is only compatible with
+       "nvidia,tegra20-i2c-dvc".
+  nvidia,tegra20-i2c: Tegra20 has 4 generic I2C controller. This can support
+       master and slave mode of I2C communication. The i2c-tegra driver only
+       support master mode of I2C communication. Driver of I2C controller is
+       only compatible with "nvidia,tegra20-i2c".
+  nvidia,tegra30-i2c: Tegra30 has 5 generic I2C controller. This controller is
+       very much similar to Tegra20 I2C controller with additional feature:
+       Continue Transfer Support. This feature helps to implement M_NO_START
+       as per I2C core API transfer flags. Driver of I2C controller is
+       compatible with "nvidia,tegra30-i2c" to enable the continue transfer
+       support. This is also compatible with "nvidia,tegra20-i2c" without
+       continue transfer support.
+  nvidia,tegra114-i2c: Tegra114 has 5 generic I2C controller. This controller is
+       very much similar to Tegra30 I2C controller with some hardware
+       modification:
+        - Tegra30/Tegra20 I2C controller has 2 clock source called div-clk and
+          fast-clk. Tegra114 has only one clock source called as div-clk and
+          hence clock mechanism is changed in I2C controller.
+        - Tegra30/Tegra20 I2C controller has enabled per packet transfer by
+          default and there is no way to disable it. Tegra114 has this
+          interrupt disable by default and SW need to enable explicitly.
+       Due to above changes, Tegra114 I2C driver makes incompatible with
+       previous hardware driver. Hence, tegra114 I2C controller is compatible
+       with "nvidia,tegra114-i2c".
+- reg: Should contain I2C controller registers physical address and length.
+- interrupts: Should contain I2C controller interrupts.
+- address-cells: Address cells for I2C device address.
+- size-cells: Size of the I2C device address.
+- clocks: Clock ID as per
+               Documentation/devicetree/bindings/clock/tegra<chip-id>.txt
+       for I2C controller.
+- clock-names: Name of the clock:
+       Tegra20/Tegra30 I2C controller: "div-clk and "fast-clk".
+       Tegra114 I2C controller: "div-clk".
+
+Example:
+
+       i2c@7000c000 {
+               compatible = "nvidia,tegra20-i2c";
+               reg = <0x7000c000 0x100>;
+               interrupts = <0 38 0x04>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car 12>, <&tegra_car 124>;
+               clock-names = "div-clk", "fast-clk";
+               status = "disabled";
+       };
index 67ec3d4ccc7f5e3ee2b6e2d670a2932936d2ab14..bf0182d8da257d392ce315a6d2b1b749cb740a51 100644 (file)
@@ -21,3 +21,24 @@ Required properties:
 
   - samsung,mfc-l : Base address of the second memory bank used by MFC
                    for DMA contiguous memory allocation and its size.
+
+Optional properties:
+  - samsung,power-domain : power-domain property defined with a phandle
+                          to respective power domain.
+
+Example:
+SoC specific DT entry:
+
+mfc: codec@13400000 {
+       compatible = "samsung,mfc-v5";
+       reg = <0x13400000 0x10000>;
+       interrupts = <0 94 0>;
+       samsung,power-domain = <&pd_mfc>;
+};
+
+Board specific DT entry:
+
+codec@13400000 {
+       samsung,mfc-r = <0x43000000 0x800000>;
+       samsung,mfc-l = <0x51000000 0x800000>;
+};
index 54949f6faedebf3ba54825bd62fb1a1ab254cf95..515addc200706293b21c654453a3dc8ba78eaa4c 100644 (file)
@@ -9,15 +9,19 @@ and the properties used by the mxsmmc driver.
 Required properties:
 - compatible: Should be "fsl,<chip>-mmc".  The supported chips include
   imx23 and imx28.
-- interrupts: Should contain ERROR and DMA interrupts
-- fsl,ssp-dma-channel: APBH DMA channel for the SSP
+- interrupts: Should contain ERROR interrupt number
+- dmas: DMA specifier, consisting of a phandle to DMA controller node
+  and SSP DMA channel ID.
+  Refer to dma.txt and fsl-mxs-dma.txt for details.
+- dma-names: Must be "rx-tx".
 
 Examples:
 
 ssp0: ssp@80010000 {
        compatible = "fsl,imx28-mmc";
        reg = <0x80010000 2000>;
-       interrupts = <96 82>;
-       fsl,ssp-dma-channel = <0>;
+       interrupts = <96>;
+       dmas = <&dma_apbh 0>;
+       dma-names = "rx-tx";
        bus-width = <8>;
 };
index 3fb3f9015365d0c15d1b4219838d6d16bef9cc53..551b2a179d016df4bd9bb8e611f38633d57d6640 100644 (file)
@@ -7,10 +7,12 @@ Required properties:
   - compatible : should be "fsl,<chip>-gpmi-nand"
   - reg : should contain registers location and length for gpmi and bch.
   - reg-names: Should contain the reg names "gpmi-nand" and "bch"
-  - interrupts : The first is the DMA interrupt number for GPMI.
-                 The second is the BCH interrupt number.
-  - interrupt-names : The interrupt names "gpmi-dma", "bch";
-  - fsl,gpmi-dma-channel : Should contain the dma channel it uses.
+  - interrupts : BCH interrupt number.
+  - interrupt-names : Should be "bch".
+  - dmas: DMA specifier, consisting of a phandle to DMA controller node
+    and GPMI DMA channel ID.
+    Refer to dma.txt and fsl-mxs-dma.txt for details.
+  - dma-names: Must be "rx-tx".
 
 Optional properties:
   - nand-on-flash-bbt: boolean to enable on flash bbt option if not
@@ -27,9 +29,10 @@ gpmi-nand@8000c000 {
        #size-cells = <1>;
        reg = <0x8000c000 2000>, <0x8000a000 2000>;
        reg-names = "gpmi-nand", "bch";
-       interrupts = <88>, <41>;
-       interrupt-names = "gpmi-dma", "bch";
-       fsl,gpmi-dma-channel = <4>;
+       interrupts = <41>;
+       interrupt-names = "bch";
+       dmas = <&dma_apbh 4>;
+       dma-names = "rx-tx";
 
        partition@0 {
        ...
index f7e8e8f4d9a3387a280406fcc92ccd2bb5baad83..3077370c89af75c22b60fd59f83ea1dc841eea37 100644 (file)
@@ -70,6 +70,10 @@ Optional subnode-properties:
     0: Disable the internal pull-up
     1: Enable the internal pull-up
 
+Note that when enabling the pull-up, the internal pad keeper gets disabled.
+Also, some pins doesn't have a pull up, in that case, setting the fsl,pull-up
+will only disable the internal pad keeper.
+
 Examples:
 
 pinctrl@80018000 {
index b77a97c9101e2bf4a3daa1367cc8ecf4cf8b3b8a..05ffecb571037cb562778cb243a84555384345d1 100644 (file)
@@ -2,6 +2,11 @@ NVIDIA Tegra audio complex
 
 Required properties:
 - compatible : "nvidia,tegra-audio-alc5632"
+- clocks : Must contain an entry for each entry in clock-names.
+- clock-names : Must include the following entries:
+  "pll_a" (The Tegra clock of that name),
+  "pll_a_out0" (The Tegra clock of that name),
+  "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
 - nvidia,model : The user-visible name of this sound complex.
 - nvidia,audio-routing : A list of the connections between audio components.
   Each entry is a pair of strings, the first being the connection's sink,
@@ -56,4 +61,7 @@ sound {
 
        nvidia,i2s-controller = <&tegra_i2s1>;
        nvidia,audio-codec = <&alc5632>;
+
+       clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 93>;
+       clock-names = "pll_a", "pll_a_out0", "mclk";
 };
index 04b14cfb1f16ba1a7180066c2970d9a0829a92bf..ef1fe735827914611661293049f0dca05ba57d00 100644 (file)
@@ -2,6 +2,11 @@ NVIDIA Tegra audio complex for TrimSlice
 
 Required properties:
 - compatible : "nvidia,tegra-audio-trimslice"
+- clocks : Must contain an entry for each entry in clock-names.
+- clock-names : Must include the following entries:
+  "pll_a" (The Tegra clock of that name),
+  "pll_a_out0" (The Tegra clock of that name),
+  "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
 - nvidia,i2s-controller : The phandle of the Tegra I2S1 controller
 - nvidia,audio-codec : The phandle of the WM8903 audio codec
 
@@ -11,4 +16,6 @@ sound {
        compatible = "nvidia,tegra-audio-trimslice";
        nvidia,i2s-controller = <&tegra_i2s1>;
        nvidia,audio-codec = <&codec>;
+       clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 93>;
+       clock-names = "pll_a", "pll_a_out0", "mclk";
 };
index c4dd39ce6165c0b25eedd4a9eabadb0f440687c8..d14510613a7fdf1ac076320a04468976aa88811a 100644 (file)
@@ -2,6 +2,11 @@ NVIDIA Tegra audio complex
 
 Required properties:
 - compatible : "nvidia,tegra-audio-wm8753"
+- clocks : Must contain an entry for each entry in clock-names.
+- clock-names : Must include the following entries:
+  "pll_a" (The Tegra clock of that name),
+  "pll_a_out0" (The Tegra clock of that name),
+  "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
 - nvidia,model : The user-visible name of this sound complex.
 - nvidia,audio-routing : A list of the connections between audio components.
   Each entry is a pair of strings, the first being the connection's sink,
@@ -50,5 +55,8 @@ sound {
 
        nvidia,i2s-controller = <&i2s1>;
        nvidia,audio-codec = <&wm8753>;
+
+       clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 93>;
+       clock-names = "pll_a", "pll_a_out0", "mclk";
 };
 
index d5b0da8bf1d8e2b3b400cfcde94425e8d0cba9e8..3bf722deb722265422283b4b897c37ffc74d31ae 100644 (file)
@@ -2,6 +2,11 @@ NVIDIA Tegra audio complex
 
 Required properties:
 - compatible : "nvidia,tegra-audio-wm8903"
+- clocks : Must contain an entry for each entry in clock-names.
+- clock-names : Must include the following entries:
+  "pll_a" (The Tegra clock of that name),
+  "pll_a_out0" (The Tegra clock of that name),
+  "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
 - nvidia,model : The user-visible name of this sound complex.
 - nvidia,audio-routing : A list of the connections between audio components.
   Each entry is a pair of strings, the first being the connection's sink,
@@ -67,5 +72,8 @@ sound {
        nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
        nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */
        nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */
+
+       clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 93>;
+       clock-names = "pll_a", "pll_a_out0", "mclk";
 };
 
index be35d34e8b26dd9701dd7b85acd2bbb6c3d5e451..ad589b16363988460afb2f697535a0c8dfaa47e4 100644 (file)
@@ -2,6 +2,11 @@ NVIDIA Tegra audio complex
 
 Required properties:
 - compatible : "nvidia,tegra-audio-wm9712"
+- clocks : Must contain an entry for each entry in clock-names.
+- clock-names : Must include the following entries:
+  "pll_a" (The Tegra clock of that name),
+  "pll_a_out0" (The Tegra clock of that name),
+  "mclk" (The Tegra cdev1/extern1 clock, which feeds the CODEC's mclk)
 - nvidia,model : The user-visible name of this sound complex.
 - nvidia,audio-routing : A list of the connections between audio components.
   Each entry is a pair of strings, the first being the connection's sink,
@@ -48,4 +53,7 @@ sound {
                "Mic", "MIC1";
 
        nvidia,ac97-controller = <&ac97>;
+
+       clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 93>;
+       clock-names = "pll_a", "pll_a_out0", "mclk";
 };
index e2e13957c2a4102179f4a28f7ef1bedd21e91c1c..3499b73293c20562b1036215016e37c2265d57ff 100644 (file)
@@ -3,8 +3,11 @@
 Required properties:
 - compatible: Should be "fsl,<soc>-spi", where soc is "imx23" or "imx28"
 - reg: Offset and length of the register set for the device
-- interrupts: Should contain SSP interrupts (error irq first, dma irq second)
-- fsl,ssp-dma-channel: APBX DMA channel for the SSP
+- interrupts: Should contain SSP ERROR interrupt
+- dmas: DMA specifier, consisting of a phandle to DMA controller node
+  and SSP DMA channel ID.
+  Refer to dma.txt and fsl-mxs-dma.txt for details.
+- dma-names: Must be "rx-tx".
 
 Optional properties:
 - clock-frequency : Input clock frequency to the SPI block in Hz.
@@ -17,6 +20,7 @@ ssp0: ssp@80010000 {
        #size-cells = <0>;
        compatible = "fsl,imx28-spi";
        reg = <0x80010000 0x2000>;
-       interrupts = <96 82>;
-       fsl,ssp-dma-channel = <0>;
+       interrupts = <96>;
+       dmas = <&dma_apbh 0>;
+       dma-names = "rx-tx";
 };
diff --git a/Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt b/Documentation/devicetree/bindings/timer/samsung,exynos4210-mct.txt
new file mode 100644 (file)
index 0000000..cb47bfb
--- /dev/null
@@ -0,0 +1,68 @@
+Samsung's Multi Core Timer (MCT)
+
+The Samsung's Multi Core Timer (MCT) module includes two main blocks, the
+global timer and CPU local timers. The global timer is a 64-bit free running
+up-counter and can generate 4 interrupts when the counter reaches one of the
+four preset counter values. The CPU local timers are 32-bit free running
+down-counters and generate an interrupt when the counter expires. There is
+one CPU local timer instantiated in MCT for every CPU in the system.
+
+Required properties:
+
+- compatible: should be "samsung,exynos4210-mct".
+  (a) "samsung,exynos4210-mct", for mct compatible with Exynos4210 mct.
+  (b) "samsung,exynos4412-mct", for mct compatible with Exynos4412 mct.
+
+- reg: base address of the mct controller and length of the address space
+  it occupies.
+
+- interrupts: the list of interrupts generated by the controller. The following
+  should be the order of the interrupts specified. The local timer interrupts
+  should be specified after the four global timer interrupts have been
+  specified.
+
+       0: Global Timer Interrupt 0
+       1: Global Timer Interrupt 1
+       2: Global Timer Interrupt 2
+       3: Global Timer Interrupt 3
+       4: Local Timer Interrupt 0
+       5: Local Timer Interrupt 1
+       6: ..
+       7: ..
+       i: Local Timer Interrupt n
+
+Example 1: In this example, the system uses only the first global timer
+          interrupt generated by MCT and the remaining three global timer
+          interrupts are unused. Two local timer interrupts have been
+          specified.
+
+       mct@10050000 {
+               compatible = "samsung,exynos4210-mct";
+               reg = <0x10050000 0x800>;
+               interrupts = <0 57 0>, <0 0 0>, <0 0 0>, <0 0 0>,
+                            <0 42 0>, <0 48 0>;
+       };
+
+Example 2: In this example, the MCT global and local timer interrupts are
+          connected to two seperate interrupt controllers. Hence, an
+          interrupt-map is created to map the interrupts to the respective
+          interrupt controllers.
+
+       mct@101C0000 {
+               compatible = "samsung,exynos4210-mct";
+               reg = <0x101C0000 0x800>;
+               interrupt-controller;
+               #interrups-cells = <2>;
+               interrupt-parent = <&mct_map>;
+               interrupts = <0 0>, <1 0>, <2 0>, <3 0>,
+                            <4 0>, <5 0>;
+
+               mct_map: mct-map {
+                       #interrupt-cells = <2>;
+                       #address-cells = <0>;
+                       #size-cells = <0>;
+                       interrupt-map = <0x0 0 &combiner 23 3>,
+                                       <0x4 0 &gic 0 120 0>,
+                                       <0x5 0 &gic 0 121 0>;
+               };
+       };
index 273a8d5b330014c1e7aa2227b76e16f2668dab25..2c00ec64628e26c6c87591b238d979509d7e3f66 100644 (file)
@@ -5,20 +5,18 @@ Required properties:
   imx23 and imx28.
 - reg : Address and length of the register set for the device
 - interrupts : Should contain the auart interrupt numbers
-
-Optional properties:
-- fsl,auart-dma-channel : The DMA channels, the first is for RX, the other
-               is for TX. If you add this property, it also means that you
-               will enable the DMA support for the auart.
-               Note: due to the hardware bug in imx23(see errata : 2836),
-               only the imx28 can enable the DMA support for the auart.
+- dmas: DMA specifier, consisting of a phandle to DMA controller node
+  and AUART DMA channel ID.
+  Refer to dma.txt and fsl-mxs-dma.txt for details.
+- dma-names: "rx" for RX channel, "tx" for TX channel.
 
 Example:
 auart0: serial@8006a000 {
        compatible = "fsl,imx28-auart", "fsl,imx23-auart";
        reg = <0x8006a000 0x2000>;
-       interrupts = <112 70 71>;
-       fsl,auart-dma-channel = <8 9>;
+       interrupts = <112>;
+       dmas = <&dma_apbx 8>, <&dma_apbx 9>;
+       dma-names = "rx", "tx";
 };
 
 Note: Each auart port should have an alias correctly numbered in "aliases"
diff --git a/Documentation/devicetree/bindings/usb/exynos-usb.txt b/Documentation/devicetree/bindings/usb/exynos-usb.txt
new file mode 100644 (file)
index 0000000..b3abde7
--- /dev/null
@@ -0,0 +1,50 @@
+Samsung Exynos SoC USB controller
+
+The USB devices interface with USB controllers on Exynos SOCs.
+The device node has following properties.
+
+EHCI
+Required properties:
+ - compatible: should be "samsung,exynos4210-ehci" for USB 2.0
+   EHCI controller in host mode.
+ - reg: physical base address of the controller and length of memory mapped
+   region.
+ - interrupts: interrupt number to the cpu.
+ - clocks: from common clock binding: handle to usb clock.
+ - clock-names: from common clock binding: Shall be "usbhost".
+
+Optional properties:
+ - samsung,vbus-gpio:  if present, specifies the GPIO that
+   needs to be pulled up for the bus to be powered.
+
+Example:
+
+       usb@12110000 {
+               compatible = "samsung,exynos4210-ehci";
+               reg = <0x12110000 0x100>;
+               interrupts = <0 71 0>;
+               samsung,vbus-gpio = <&gpx2 6 1 3 3>;
+
+               clocks = <&clock 285>;
+               clock-names = "usbhost";
+       };
+
+OHCI
+Required properties:
+ - compatible: should be "samsung,exynos4210-ohci" for USB 2.0
+   OHCI companion controller in host mode.
+ - reg: physical base address of the controller and length of memory mapped
+   region.
+ - interrupts: interrupt number to the cpu.
+ - clocks: from common clock binding: handle to usb clock.
+ - clock-names: from common clock binding: Shall be "usbhost".
+
+Example:
+       usb@12120000 {
+               compatible = "samsung,exynos4210-ohci";
+               reg = <0x12120000 0x100>;
+               interrupts = <0 71 0>;
+
+               clocks = <&clock 285>;
+               clock-names = "usbhost";
+       };
index 1ef0ce71f8faa0f00bb0e459c7c94a36d6abdb1b..abce25684abcb0e3d2d7ed271196d0896eaa31b3 100644 (file)
@@ -18,6 +18,7 @@ OMAP MUSB GLUE
    represents PERIPHERAL.
  - power : Should be "50". This signifies the controller can supply upto
    100mA when operating in host mode.
+ - usb-phy : the phandle for the PHY device
 
 Optional properties:
  - ctrl-module : phandle of the control module this glue uses to write to
diff --git a/Documentation/devicetree/bindings/video/samsung-fimd.txt b/Documentation/devicetree/bindings/video/samsung-fimd.txt
new file mode 100644 (file)
index 0000000..778838a
--- /dev/null
@@ -0,0 +1,65 @@
+Device-Tree bindings for Samsung SoC display controller (FIMD)
+
+FIMD (Fully Interactive Mobile Display) is the Display Controller for the
+Samsung series of SoCs which transfers the image data from a video memory
+buffer to an external LCD interface.
+
+Required properties:
+- compatible: value should be one of the following
+               "samsung,s3c2443-fimd"; /* for S3C24XX SoCs */
+               "samsung,s3c6400-fimd"; /* for S3C64XX SoCs */
+               "samsung,s5p6440-fimd"; /* for S5P64X0 SoCs */
+               "samsung,s5pc100-fimd"; /* for S5PC100 SoC  */
+               "samsung,s5pv210-fimd"; /* for S5PV210 SoC */
+               "samsung,exynos4210-fimd"; /* for Exynos4 SoCs */
+               "samsung,exynos5250-fimd"; /* for Exynos5 SoCs */
+
+- reg: physical base address and length of the FIMD registers set.
+
+- interrupt-parent: should be the phandle of the fimd controller's
+               parent interrupt controller.
+
+- interrupts: should contain a list of all FIMD IP block interrupts in the
+                order: FIFO Level, VSYNC, LCD_SYSTEM. The interrupt specifier
+                format depends on the interrupt controller used.
+
+- interrupt-names: should contain the interrupt names: "fifo", "vsync",
+       "lcd_sys", in the same order as they were listed in the interrupts
+        property.
+
+- pinctrl-0: pin control group to be used for this controller.
+
+- pinctrl-names: must contain a "default" entry.
+
+- clocks: must include clock specifiers corresponding to entries in the
+         clock-names property.
+
+- clock-names: list of clock names sorted in the same order as the clocks
+               property. Must contain "sclk_fimd" and "fimd".
+
+Optional Properties:
+- samsung,power-domain: a phandle to FIMD power domain node.
+
+Example:
+
+SoC specific DT entry:
+
+       fimd@11c00000 {
+               compatible = "samsung,exynos4210-fimd";
+               interrupt-parent = <&combiner>;
+               reg = <0x11c00000 0x20000>;
+               interrupt-names = "fifo", "vsync", "lcd_sys";
+               interrupts = <11 0>, <11 1>, <11 2>;
+               clocks = <&clock 140>, <&clock 283>;
+               clock-names = "sclk_fimd", "fimd";
+               samsung,power-domain = <&pd_lcd0>;
+               status = "disabled";
+       };
+
+Board specific DT entry:
+
+       fimd@11c00000 {
+               pinctrl-0 = <&lcd_clk &lcd_data24 &pwm1_out>;
+               pinctrl-names = "default";
+               status = "okay";
+       };
index f2a2488f1bf33d8290384c4823fccee2b39afe36..9573d0c48c6ea882099edd94ed2dcda94e4fe3dd 100644 (file)
@@ -15,6 +15,13 @@ amemthresh - INTEGER
         enabled and the variable is automatically set to 2, otherwise
         the strategy is disabled and the variable is  set  to 1.
 
+backup_only - BOOLEAN
+       0 - disabled (default)
+       not 0 - enabled
+
+       If set, disable the director function while the server is
+       in backup mode to avoid packet loops for DR/TUN methods.
+
 conntrack - BOOLEAN
        0 - disabled (default)
        not 0 - enabled
index 4cf5fd334a06a32cc25fdadff37355b8fc6c397f..74e58a4d035b953fe2aa28f86b1cab87249a3223 100644 (file)
@@ -3242,6 +3242,12 @@ F:       Documentation/firmware_class/
 F:     drivers/base/firmware*.c
 F:     include/linux/firmware.h
 
+FLASHSYSTEM DRIVER (IBM FlashSystem 70/80 PCI SSD Flash Card)
+M:     Joshua Morris <josh.h.morris@us.ibm.com>
+M:     Philip Kelleher <pjk1939@linux.vnet.ibm.com>
+S:     Maintained
+F:     drivers/block/rsxx/
+
 FLOPPY DRIVER
 M:     Jiri Kosina <jkosina@suse.cz>
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/floppy.git
@@ -5683,7 +5689,7 @@ S:        Maintained
 F:     arch/arm/*omap*/*clock*
 
 OMAP POWER MANAGEMENT SUPPORT
-M:     Kevin Hilman <khilman@ti.com>
+M:     Kevin Hilman <khilman@deeprootsystems.com>
 L:     linux-omap@vger.kernel.org
 S:     Maintained
 F:     arch/arm/*omap*/*pm*
@@ -5777,7 +5783,7 @@ F:        arch/arm/*omap*/usb*
 
 OMAP GPIO DRIVER
 M:     Santosh Shilimkar <santosh.shilimkar@ti.com>
-M:     Kevin Hilman <khilman@ti.com>
+M:     Kevin Hilman <khilman@deeprootsystems.com>
 L:     linux-omap@vger.kernel.org
 S:     Maintained
 F:     drivers/gpio/gpio-omap.c
@@ -6209,7 +6215,7 @@ F:        include/linux/power_supply.h
 F:     drivers/power/
 
 PNP SUPPORT
-M:     Adam Belay <abelay@mit.edu>
+M:     Rafael J. Wysocki <rafael.j.wysocki@intel.com>
 M:     Bjorn Helgaas <bhelgaas@google.com>
 S:     Maintained
 F:     drivers/pnp/
@@ -6551,12 +6557,6 @@ S:       Maintained
 F:     Documentation/blockdev/ramdisk.txt
 F:     drivers/block/brd.c
 
-RAMSAM DRIVER (IBM RamSan 70/80 PCI SSD Flash Card)
-M:     Joshua Morris <josh.h.morris@us.ibm.com>
-M:     Philip Kelleher <pjk1939@linux.vnet.ibm.com>
-S:     Maintained
-F:     drivers/block/rsxx/
-
 RANDOM NUMBER DRIVER
 M:     Theodore Ts'o" <tytso@mit.edu>
 S:     Maintained
@@ -7173,7 +7173,7 @@ F:        arch/arm/mach-s3c2410/bast-irq.c
 
 TI DAVINCI MACHINE SUPPORT
 M:     Sekhar Nori <nsekhar@ti.com>
-M:     Kevin Hilman <khilman@ti.com>
+M:     Kevin Hilman <khilman@deeprootsystems.com>
 L:     davinci-linux-open-source@linux.davincidsp.com (moderated for non-subscribers)
 T:     git git://gitorious.org/linux-davinci/linux-davinci.git
 Q:     http://patchwork.kernel.org/project/linux-davinci/list/
@@ -7706,9 +7706,10 @@ F:       include/linux/swiotlb.h
 
 SYNOPSYS ARC ARCHITECTURE
 M:     Vineet Gupta <vgupta@synopsys.com>
-L:     linux-snps-arc@vger.kernel.org
 S:     Supported
 F:     arch/arc/
+F:     Documentation/devicetree/bindings/arc/
+F:     drivers/tty/serial/arc-uart.c
 
 SYSV FILESYSTEM
 M:     Christoph Hellwig <hch@infradead.org>
index 54d2b2a0fef0e2a1dba259b8f97ac0f7e8341225..58a165b02af1e27acb6d2635f3c9ab0d58c5cb00 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 3
 PATCHLEVEL = 9
 SUBLEVEL = 0
-EXTRAVERSION = -rc4
+EXTRAVERSION = -rc5
 NAME = Unicycling Gorilla
 
 # *DOCUMENTATION*
index 31f77aec082381e34f5cb7ddb06added7d98d179..45b8e0cea1764d2b9e4a0b0d1f27b787eb845870 100644 (file)
@@ -126,7 +126,7 @@ dma_map_sg(struct device *dev, struct scatterlist *sg,
        int i;
 
        for_each_sg(sg, s, nents, i)
-               sg->dma_address = dma_map_page(dev, sg_page(s), s->offset,
+               s->dma_address = dma_map_page(dev, sg_page(s), s->offset,
                                               s->length, dir);
 
        return nents;
index f4c8d36ebecbd2dcad76db454edc64686cfae292..a262828576839d9d48e5e2be18ae65b9fad815e5 100644 (file)
@@ -72,7 +72,4 @@ extern int elf_check_arch(const struct elf32_hdr *);
  */
 #define ELF_PLATFORM   (NULL)
 
-#define SET_PERSONALITY(ex) \
-       set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
-
 #endif
index 23daa326fc9b4d19c5711af313e730dae2551f27..eb2ae53187d95fe1240885bd7026d1f13c3c98a4 100644 (file)
  *-------------------------------------------------------------*/
 .macro SAVE_ALL_EXCEPTION   marker
 
-       st      \marker, [sp, 8]
+       st      \marker, [sp, 8]        /* orig_r8 */
        st      r0, [sp, 4]    /* orig_r0, needed only for sys calls */
 
        /* Restore r9 used to code the early prologue */
index f3c4934f0ca9462e1876095fa197a90dc2e4fede..4930957ca3d38c4cb312aa60f21ffa9cbb413087 100644 (file)
@@ -13,7 +13,7 @@
 
 #ifdef CONFIG_KGDB
 
-#include <asm/user.h>
+#include <asm/ptrace.h>
 
 /* to ensure compatibility with Linux 2.6.35, we don't implement the get/set
  * register API yet */
@@ -53,9 +53,7 @@ enum arc700_linux_regnums {
 };
 
 #else
-static inline void kgdb_trap(struct pt_regs *regs, int param)
-{
-}
+#define kgdb_trap(regs, param)
 #endif
 
 #endif /* __ARC_KGDB_H__ */
index 8ae783d20a81185dab9ae04e61f5e2a9e47082b0..6179de7e07c21ca4875017adc1107c0e7b0b46c4 100644 (file)
@@ -123,7 +123,7 @@ static inline long regs_return_value(struct pt_regs *regs)
 #define orig_r8_IS_SCALL               0x0001
 #define orig_r8_IS_SCALL_RESTARTED     0x0002
 #define orig_r8_IS_BRKPT               0x0004
-#define orig_r8_IS_EXCPN               0x0004
+#define orig_r8_IS_EXCPN               0x0008
 #define orig_r8_IS_IRQ1                        0x0010
 #define orig_r8_IS_IRQ2                        0x0020
 
index e53a5340ba4f2b91376f76ca7b4f5286567cd302..dd785befe7fd1eaa3b6b7d5df5ee8ef77e849587 100644 (file)
@@ -16,8 +16,6 @@
 #include <linux/types.h>
 
 int sys_clone_wrapper(int, int, int, int, int);
-int sys_fork_wrapper(void);
-int sys_vfork_wrapper(void);
 int sys_cacheflush(uint32_t, uint32_t uint32_t);
 int sys_arc_settls(void *);
 int sys_arc_gettls(void);
index 6afa4f70207529c5d9ae7d0caa69082108d154c9..30333cec0fef274365aeb559084d58a5ee023a9b 100644 (file)
 */
 struct user_regs_struct {
 
-       struct scratch {
+       struct {
                long pad;
                long bta, lp_start, lp_end, lp_count;
                long status32, ret, blink, fp, gp;
                long r12, r11, r10, r9, r8, r7, r6, r5, r4, r3, r2, r1, r0;
                long sp;
        } scratch;
-       struct callee {
+       struct {
                long pad;
                long r25, r24, r23, r22, r21, r20;
                long r19, r18, r17, r16, r15, r14, r13;
index ef6800ba2f03f6cce95a78e1db7b175f66d72e7c..91eeab81f52d3d66a408a215f06b4ff19022d364 100644 (file)
@@ -452,7 +452,7 @@ tracesys:
        ; using ERET won't work since next-PC has already committed
        lr  r12, [efa]
        GET_CURR_TASK_FIELD_PTR   TASK_THREAD, r11
-       st  r12, [r11, THREAD_FAULT_ADDR]
+       st  r12, [r11, THREAD_FAULT_ADDR]       ; thread.fault_address
 
        ; PRE Sys Call Ptrace hook
        mov r0, sp                      ; pt_regs needed
@@ -792,31 +792,6 @@ ARC_EXIT ret_from_fork
 
 ;################### Special Sys Call Wrappers ##########################
 
-; TBD: call do_fork directly from here
-ARC_ENTRY sys_fork_wrapper
-       SAVE_CALLEE_SAVED_USER
-       bl  @sys_fork
-       DISCARD_CALLEE_SAVED_USER
-
-       GET_CURR_THR_INFO_FLAGS   r10
-       btst r10, TIF_SYSCALL_TRACE
-       bnz  tracesys_exit
-
-       b ret_from_system_call
-ARC_EXIT sys_fork_wrapper
-
-ARC_ENTRY sys_vfork_wrapper
-       SAVE_CALLEE_SAVED_USER
-       bl  @sys_vfork
-       DISCARD_CALLEE_SAVED_USER
-
-       GET_CURR_THR_INFO_FLAGS   r10
-       btst r10, TIF_SYSCALL_TRACE
-       bnz  tracesys_exit
-
-       b ret_from_system_call
-ARC_EXIT sys_vfork_wrapper
-
 ARC_ENTRY sys_clone_wrapper
        SAVE_CALLEE_SAVED_USER
        bl  @sys_clone
index 2888ba5be47e4be4e796d0840abb9570253a416a..52bdc83c1495b5bf31a685998f7a5d7b9a1bd15e 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/kgdb.h>
+#include <linux/sched.h>
 #include <asm/disasm.h>
 #include <asm/cacheflush.h>
 
index dc0f968dae0aecfa96db2bc005a99c74bdabb71a..2d95ac07df7bde15169ff5058d7e53afd2f2d73e 100644 (file)
@@ -232,10 +232,8 @@ char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len)
 
        n += scnprintf(buf + n, len - n, "\n");
 
-#ifdef _ASM_GENERIC_UNISTD_H
        n += scnprintf(buf + n, len - n,
-                      "OS ABI [v2]\t: asm-generic/{unistd,stat,fcntl}\n");
-#endif
+                      "OS ABI [v3]\t: no-legacy-syscalls\n");
 
        return buf;
 }
index f6bdd07583f3a2ed190fdc1de9ceff9e77bf2ba8..9d6c1ca26af6d8bf4c035ae5f6085d8bfb6bc0be 100644 (file)
@@ -6,8 +6,6 @@
 #include <asm/syscalls.h>
 
 #define sys_clone      sys_clone_wrapper
-#define sys_fork       sys_fork_wrapper
-#define sys_vfork      sys_vfork_wrapper
 
 #undef __SYSCALL
 #define __SYSCALL(nr, call) [nr] = (call),
index 9462dd931b33f15da419f33601bbdf315e801285..398a9fbcd4272ed04586ff9544c28e5159ecb1dd 100644 (file)
@@ -473,12 +473,14 @@ config ARCH_MXS
        select ARCH_REQUIRE_GPIOLIB
        select CLKDEV_LOOKUP
        select CLKSRC_MMIO
+       select CLKSRC_OF
        select COMMON_CLK
        select GENERIC_CLOCKEVENTS
        select HAVE_CLK_PREPARE
        select MULTI_IRQ_HANDLER
        select PINCTRL
        select SPARSE_IRQ
+       select STMP_DEVICE
        select USE_OF
        help
          Support for Freescale MXS-based family of processors
@@ -677,6 +679,7 @@ config ARCH_TEGRA
        select HAVE_CLK
        select HAVE_SMP
        select MIGHT_HAVE_CACHE_L2X0
+       select SOC_BUS
        select SPARSE_IRQ
        select USE_OF
        help
@@ -773,8 +776,10 @@ config ARCH_SA1100
 config ARCH_S3C24XX
        bool "Samsung S3C24XX SoCs"
        select ARCH_HAS_CPUFREQ
-       select ARCH_USES_GETTIMEOFFSET
        select CLKDEV_LOOKUP
+       select CLKSRC_MMIO
+       select GENERIC_CLOCKEVENTS
+       select GENERIC_GPIO
        select HAVE_CLK
        select HAVE_S3C2410_I2C if I2C
        select HAVE_S3C2410_WATCHDOG if WATCHDOG
@@ -791,10 +796,11 @@ config ARCH_S3C64XX
        bool "Samsung S3C64XX"
        select ARCH_HAS_CPUFREQ
        select ARCH_REQUIRE_GPIOLIB
-       select ARCH_USES_GETTIMEOFFSET
        select ARM_VIC
        select CLKDEV_LOOKUP
+       select CLKSRC_MMIO
        select CPU_V6
+       select GENERIC_CLOCKEVENTS
        select HAVE_CLK
        select HAVE_S3C2410_I2C if I2C
        select HAVE_S3C2410_WATCHDOG if WATCHDOG
@@ -828,9 +834,11 @@ config ARCH_S5P64X0
 
 config ARCH_S5PC100
        bool "Samsung S5PC100"
-       select ARCH_USES_GETTIMEOFFSET
        select CLKDEV_LOOKUP
+       select CLKSRC_MMIO
        select CPU_V7
+       select GENERIC_CLOCKEVENTS
+       select GENERIC_GPIO
        select HAVE_CLK
        select HAVE_S3C2410_I2C if I2C
        select HAVE_S3C2410_WATCHDOG if WATCHDOG
@@ -863,6 +871,7 @@ config ARCH_EXYNOS
        select ARCH_HAS_HOLES_MEMORYMODEL
        select ARCH_SPARSEMEM_ENABLE
        select CLKDEV_LOOKUP
+       select COMMON_CLK
        select CPU_V7
        select GENERIC_CLOCKEVENTS
        select HAVE_CLK
@@ -1597,6 +1606,7 @@ config HAVE_ARM_ARCH_TIMER
 config HAVE_ARM_TWD
        bool
        depends on SMP
+       select CLKSRC_OF if OF
        help
          This options enables support for the ARM timer and watchdog unit
 
@@ -1650,7 +1660,7 @@ config LOCAL_TIMERS
        bool "Use local timer interrupts"
        depends on SMP
        default y
-       select HAVE_ARM_TWD if (!ARCH_MSM_SCORPIONMP && !EXYNOS4_MCT)
+       select HAVE_ARM_TWD if (!ARCH_MSM_SCORPIONMP && !CLKSRC_EXYNOS_MCT)
        help
          Enable support for local timers on SMP platforms, rather then the
          legacy IPI broadcast method.  Local timers allows the system
index ecfcdba2d17c5976c34d238b19fb39181b36883d..9b31f4311ea2717818d8a387d3e0131d335195d0 100644 (file)
@@ -495,6 +495,7 @@ config DEBUG_IMX_UART_PORT
                                                DEBUG_IMX53_UART || \
                                                DEBUG_IMX6Q_UART
        default 1
+       depends on ARCH_MXC
        help
          Choose UART port on which kernel low-level debug messages
          should be output.
index 9c6255884cbbd51f7efd83c5c4b6327156fc5c6c..6cecf1437ea0004118ec8e38505baeba7a0364f4 100644 (file)
@@ -42,7 +42,11 @@ dtb-$(CONFIG_ARCH_DOVE) += dove-cm-a510.dtb \
 dtb-$(CONFIG_ARCH_EXYNOS) += exynos4210-origen.dtb \
        exynos4210-smdkv310.dtb \
        exynos4210-trats.dtb \
+       exynos4412-odroidx.dtb \
        exynos4412-smdk4412.dtb \
+       exynos4412-origen.dtb \
+       exynos5250-arndale.dtb \
+       exynos5440-sd5v1.dtb \
        exynos5250-smdk5250.dtb \
        exynos5250-snow.dtb \
        exynos5440-ssdk5440.dtb
@@ -115,10 +119,14 @@ dtb-$(CONFIG_ARCH_MXS) += imx23-evk.dtb \
        imx28-tx28.dtb
 dtb-$(CONFIG_ARCH_NOMADIK) += ste-nomadik-s8815.dtb
 dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \
+       omap3430-sdp.dtb \
        omap3-beagle.dtb \
+       omap3-devkit8000.dtb \
        omap3-beagle-xm.dtb \
        omap3-evm.dtb \
        omap3-tobi.dtb \
+       omap3-igep0020.dtb \
+       omap3-igep0030.dtb \
        omap4-panda.dtb \
        omap4-panda-a4.dtb \
        omap4-panda-es.dtb \
index 11b240c5d3238e7a76699be74f0f1085de4f5c4b..5302f79c05b719e3317bb0e3431c144073691724 100644 (file)
@@ -43,7 +43,7 @@
                        status = "okay";
                };
 
-               i2c1: i2c@44e0b000 {
+               i2c0: i2c@44e0b000 {
                        status = "okay";
                        clock-frequency = <400000>;
 
 
                led@2 {
                        label = "beaglebone:green:heartbeat";
-                       gpios = <&gpio2 21 0>;
+                       gpios = <&gpio1 21 0>;
                        linux,default-trigger = "heartbeat";
                        default-state = "off";
                };
 
                led@3 {
                        label = "beaglebone:green:mmc0";
-                       gpios = <&gpio2 22 0>;
+                       gpios = <&gpio1 22 0>;
                        linux,default-trigger = "mmc0";
                        default-state = "off";
                };
 
                led@4 {
                        label = "beaglebone:green:usr2";
-                       gpios = <&gpio2 23 0>;
+                       gpios = <&gpio1 23 0>;
                        default-state = "off";
                };
 
                led@5 {
                        label = "beaglebone:green:usr3";
-                       gpios = <&gpio2 24 0>;
+                       gpios = <&gpio1 24 0>;
                        default-state = "off";
                };
        };
index d6496440fcea496b2d93a3b91b8005101ccc2efa..0423298a26fe634e174b4138cac7ee2ee28f6a2c 100644 (file)
@@ -51,7 +51,7 @@
                        status = "okay";
                };
 
-               i2c1: i2c@44e0b000 {
+               i2c0: i2c@44e0b000 {
                        status = "okay";
                        clock-frequency = <400000>;
 
@@ -60,7 +60,7 @@
                        };
                };
 
-               i2c2: i2c@4802a000 {
+               i2c1: i2c@4802a000 {
                        status = "okay";
                        clock-frequency = <100000>;
 
                debounce-delay-ms = <5>;
                col-scan-delay-us = <2>;
 
-               row-gpios = <&gpio2 25 0        /* Bank1, pin25 */
-                            &gpio2 26 0        /* Bank1, pin26 */
-                            &gpio2 27 0>;      /* Bank1, pin27 */
+               row-gpios = <&gpio1 25 0        /* Bank1, pin25 */
+                            &gpio1 26 0        /* Bank1, pin26 */
+                            &gpio1 27 0>;      /* Bank1, pin27 */
 
-               col-gpios = <&gpio2 21 0        /* Bank1, pin21 */
-                            &gpio2 22 0>;      /* Bank1, pin22 */
+               col-gpios = <&gpio1 21 0        /* Bank1, pin21 */
+                            &gpio1 22 0>;      /* Bank1, pin22 */
 
                linux,keymap = <0x0000008b      /* MENU */
                                0x0100009e      /* BACK */
                switch@9 {
                        label = "volume-up";
                        linux,code = <115>;
-                       gpios = <&gpio1 2 1>;
+                       gpios = <&gpio0 2 1>;
                        gpio-key,wakeup;
                };
 
                switch@10 {
                        label = "volume-down";
                        linux,code = <114>;
-                       gpios = <&gpio1 3 1>;
+                       gpios = <&gpio0 3 1>;
                        gpio-key,wakeup;
                };
        };
index f5a6162a4ff22c0137fc97346c03d26cca11e8b7..f67c360844f482f20338c9b18b5ff0b76f2de542 100644 (file)
@@ -58,7 +58,7 @@
                        status = "okay";
                };
 
-               i2c1: i2c@44e0b000 {
+               i2c0: i2c@44e0b000 {
                        status = "okay";
                        clock-frequency = <400000>;
 
 
                led@1 {
                        label = "evmsk:green:usr0";
-                       gpios = <&gpio2 4 0>;
+                       gpios = <&gpio1 4 0>;
                        default-state = "off";
                };
 
                led@2 {
                        label = "evmsk:green:usr1";
-                       gpios = <&gpio2 5 0>;
+                       gpios = <&gpio1 5 0>;
                        default-state = "off";
                };
 
                led@3 {
                        label = "evmsk:green:mmc0";
-                       gpios = <&gpio2 6 0>;
+                       gpios = <&gpio1 6 0>;
                        linux,default-trigger = "mmc0";
                        default-state = "off";
                };
 
                led@4 {
                        label = "evmsk:green:heartbeat";
-                       gpios = <&gpio2 7 0>;
+                       gpios = <&gpio1 7 0>;
                        linux,default-trigger = "heartbeat";
                        default-state = "off";
                };
                switch@1 {
                        label = "button0";
                        linux,code = <0x100>;
-                       gpios = <&gpio3 3 0>;
+                       gpios = <&gpio2 3 0>;
                };
 
                switch@2 {
                        label = "button1";
                        linux,code = <0x101>;
-                       gpios = <&gpio3 2 0>;
+                       gpios = <&gpio2 2 0>;
                };
 
                switch@3 {
                        label = "button2";
                        linux,code = <0x102>;
-                       gpios = <&gpio1 30 0>;
+                       gpios = <&gpio0 30 0>;
                        gpio-key,wakeup;
                };
 
                switch@4 {
                        label = "button3";
                        linux,code = <0x103>;
-                       gpios = <&gpio3 5 0>;
+                       gpios = <&gpio2 5 0>;
                };
        };
 };
index 0957645b73afaca716348485193aa5060f06659c..df6283076e7963348aef02f474e9d30a52c25b77 100644 (file)
@@ -21,6 +21,8 @@
                serial3 = &uart4;
                serial4 = &uart5;
                serial5 = &uart6;
+               d_can0 = &dcan0;
+               d_can1 = &dcan1;
        };
 
        cpus {
@@ -87,7 +89,7 @@
                        reg = <0x48200000 0x1000>;
                };
 
-               gpio1: gpio@44e07000 {
+               gpio0: gpio@44e07000 {
                        compatible = "ti,omap4-gpio";
                        ti,hwmods = "gpio1";
                        gpio-controller;
                        interrupts = <96>;
                };
 
-               gpio2: gpio@4804c000 {
+               gpio1: gpio@4804c000 {
                        compatible = "ti,omap4-gpio";
                        ti,hwmods = "gpio2";
                        gpio-controller;
                        interrupts = <98>;
                };
 
-               gpio3: gpio@481ac000 {
+               gpio2: gpio@481ac000 {
                        compatible = "ti,omap4-gpio";
                        ti,hwmods = "gpio3";
                        gpio-controller;
                        interrupts = <32>;
                };
 
-               gpio4: gpio@481ae000 {
+               gpio3: gpio@481ae000 {
                        compatible = "ti,omap4-gpio";
                        ti,hwmods = "gpio4";
                        gpio-controller;
                        status = "disabled";
                };
 
-               i2c1: i2c@44e0b000 {
+               i2c0: i2c@44e0b000 {
                        compatible = "ti,omap4-i2c";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
                };
 
-               i2c2: i2c@4802a000 {
+               i2c1: i2c@4802a000 {
                        compatible = "ti,omap4-i2c";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
                };
 
-               i2c3: i2c@4819c000 {
+               i2c2: i2c@4819c000 {
                        compatible = "ti,omap4-i2c";
                        #address-cells = <1>;
                        #size-cells = <0>;
                dcan0: d_can@481cc000 {
                        compatible = "bosch,d_can";
                        ti,hwmods = "d_can0";
-                       reg = <0x481cc000 0x2000>;
+                       reg = <0x481cc000 0x2000
+                               0x44e10644 0x4>;
                        interrupts = <52>;
                        status = "disabled";
                };
                dcan1: d_can@481d0000 {
                        compatible = "bosch,d_can";
                        ti,hwmods = "d_can1";
-                       reg = <0x481d0000 0x2000>;
+                       reg = <0x481d0000 0x2000
+                               0x44e10644 0x4>;
                        interrupts = <55>;
                        status = "disabled";
                };
 
                timer1: timer@44e31000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,am335x-timer-1ms";
                        reg = <0x44e31000 0x400>;
                        interrupts = <67>;
                        ti,hwmods = "timer1";
                };
 
                timer2: timer@48040000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,am335x-timer";
                        reg = <0x48040000 0x400>;
                        interrupts = <68>;
                        ti,hwmods = "timer2";
                };
 
                timer3: timer@48042000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,am335x-timer";
                        reg = <0x48042000 0x400>;
                        interrupts = <69>;
                        ti,hwmods = "timer3";
                };
 
                timer4: timer@48044000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,am335x-timer";
                        reg = <0x48044000 0x400>;
                        interrupts = <92>;
                        ti,hwmods = "timer4";
                };
 
                timer5: timer@48046000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,am335x-timer";
                        reg = <0x48046000 0x400>;
                        interrupts = <93>;
                        ti,hwmods = "timer5";
                };
 
                timer6: timer@48048000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,am335x-timer";
                        reg = <0x48048000 0x400>;
                        interrupts = <94>;
                        ti,hwmods = "timer6";
                };
 
                timer7: timer@4804a000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,am335x-timer";
                        reg = <0x4804a000 0x400>;
                        interrupts = <95>;
                        ti,hwmods = "timer7";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        reg = <0x48030000 0x400>;
-                       interrupt = <65>;
+                       interrupts = <65>;
                        ti,spi-num-cs = <2>;
                        ti,hwmods = "spi0";
                        status = "disabled";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        reg = <0x481a0000 0x400>;
-                       interrupt = <125>;
+                       interrupts = <125>;
                        ti,spi-num-cs = <2>;
                        ti,hwmods = "spi1";
                        status = "disabled";
index 474f760ecadfcb2aa5a4927f1bcab14a7dfe8fa8..e9b5bdae4908bba91e92cb807d99ae8e7da3c877 100644 (file)
@@ -7,7 +7,7 @@
  */
 /dts-v1/;
 
-/include/ "omap3.dtsi"
+/include/ "omap34xx.dtsi"
 
 / {
        model = "TI AM3517 EVM (AM3517/05)";
index 5eb26d7d9b4e652b955723e99179c51a05566d66..556868388a23a0cc76531dd4202a19b2ed3ff137 100644 (file)
@@ -7,7 +7,7 @@
  */
 /dts-v1/;
 
-/include/ "omap3.dtsi"
+/include/ "omap34xx.dtsi"
 
 / {
        model = "TeeJet Mt.Ventoux";
index 46c09801703655eb0a8fb28b8332cafa674f9b72..8a5b3a6cdc58fc4e6f36f7a89c43360fdb5d80c4 100644 (file)
        chosen {
        };
 
+       pinctrl@11400000 {
+               /*
+                * Disabled pullups since external part has its own pullups and
+                * double-pulling gets us out of spec in some cases.
+                */
+               i2c2_bus: i2c2-bus {
+                       samsung,pin-pud = <0>;
+               };
+       };
+
        i2c@12C60000 {
                samsung,i2c-sda-delay = <100>;
                samsung,i2c-max-bus-freq = <378000>;
-               gpios = <&gpb3 0 2 3 0>,
-                       <&gpb3 1 2 3 0>;
+
+               max77686@09 {
+                       compatible = "maxim,max77686";
+                       reg = <0x09>;
+
+                       voltage-regulators {
+                               ldo1_reg: LDO1 {
+                                       regulator-name = "P1.0V_LDO_OUT1";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo2_reg: LDO2 {
+                                       regulator-name = "P1.8V_LDO_OUT2";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo3_reg: LDO3 {
+                                       regulator-name = "P1.8V_LDO_OUT3";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo7_reg: LDO7 {
+                                       regulator-name = "P1.1V_LDO_OUT7";
+                                       regulator-min-microvolt = <1100000>;
+                                       regulator-max-microvolt = <1100000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo8_reg: LDO8 {
+                                       regulator-name = "P1.0V_LDO_OUT8";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo10_reg: LDO10 {
+                                       regulator-name = "P1.8V_LDO_OUT10";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo12_reg: LDO12 {
+                                       regulator-name = "P3.0V_LDO_OUT12";
+                                       regulator-min-microvolt = <3000000>;
+                                       regulator-max-microvolt = <3000000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo14_reg: LDO14 {
+                                       regulator-name = "P1.8V_LDO_OUT14";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo15_reg: LDO15 {
+                                       regulator-name = "P1.0V_LDO_OUT15";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                               };
+
+                               ldo16_reg: LDO16 {
+                                       regulator-name = "P1.8V_LDO_OUT16";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                               };
+
+                               buck1_reg: BUCK1 {
+                                       regulator-name = "vdd_mif";
+                                       regulator-min-microvolt = <950000>;
+                                       regulator-max-microvolt = <1300000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               buck2_reg: BUCK2 {
+                                       regulator-name = "vdd_arm";
+                                       regulator-min-microvolt = <850000>;
+                                       regulator-max-microvolt = <1350000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               buck3_reg: BUCK3 {
+                                       regulator-name = "vdd_int";
+                                       regulator-min-microvolt = <900000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               buck4_reg: BUCK4 {
+                                       regulator-name = "vdd_g3d";
+                                       regulator-min-microvolt = <850000>;
+                                       regulator-max-microvolt = <1300000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               buck5_reg: BUCK5 {
+                                       regulator-name = "P1.8V_BUCK_OUT5";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               buck6_reg: BUCK6 {
+                                       regulator-name = "P1.35V_BUCK_OUT6";
+                                       regulator-min-microvolt = <1350000>;
+                                       regulator-max-microvolt = <1350000>;
+                                       regulator-always-on;
+                               };
+
+                               buck7_reg: BUCK7 {
+                                       regulator-name = "P2.0V_BUCK_OUT7";
+                                       regulator-min-microvolt = <2000000>;
+                                       regulator-max-microvolt = <2000000>;
+                                       regulator-always-on;
+                               };
+
+                               buck8_reg: BUCK8 {
+                                       regulator-name = "P2.85V_BUCK_OUT8";
+                                       regulator-min-microvolt = <2850000>;
+                                       regulator-max-microvolt = <2850000>;
+                                       regulator-always-on;
+                               };
+                       };
+               };
        };
 
        i2c@12C70000 {
                samsung,i2c-sda-delay = <100>;
                samsung,i2c-max-bus-freq = <378000>;
-               gpios = <&gpb3 2 2 3 0>,
-                       <&gpb3 3 2 3 0>;
        };
 
        i2c@12C80000 {
                samsung,i2c-sda-delay = <100>;
                samsung,i2c-max-bus-freq = <66000>;
 
-               /*
-                * Disabled pullups since external part has its own pullups and
-                * double-pulling gets us out of spec in some cases.
-                */
-               gpios = <&gpa0 6 3 0 0>,
-                       <&gpa0 7 3 0 0>;
-
                hdmiddc@50 {
                        compatible = "samsung,exynos5-hdmiddc";
                        reg = <0x50>;
        i2c@12C90000 {
                samsung,i2c-sda-delay = <100>;
                samsung,i2c-max-bus-freq = <66000>;
-               gpios = <&gpa1 2 3 3 0>,
-                       <&gpa1 3 3 3 0>;
        };
 
        i2c@12CA0000 {
        i2c@12CB0000 {
                samsung,i2c-sda-delay = <100>;
                samsung,i2c-max-bus-freq = <66000>;
-               gpios = <&gpa2 2 3 3 0>,
-                       <&gpa2 3 3 3 0>;
        };
 
        i2c@12CC0000 {
        i2c@12CD0000 {
                samsung,i2c-sda-delay = <100>;
                samsung,i2c-max-bus-freq = <66000>;
-               gpios = <&gpb2 2 3 3 0>,
-                       <&gpb2 3 3 3 0>;
        };
 
        i2c@12CE0000 {
                samsung,dw-mshc-ciu-div = <3>;
                samsung,dw-mshc-sdr-timing = <2 3>;
                samsung,dw-mshc-ddr-timing = <1 2>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_bus4 &sd0_bus8>;
 
                slot@0 {
                        reg = <0>;
                        bus-width = <8>;
-                       gpios = <&gpc0 0 2 0 3>, <&gpc0 1 2 0 3>,
-                               <&gpc1 0 2 3 3>, <&gpc1 1 2 3 3>,
-                               <&gpc1 2 2 3 3>, <&gpc1 3 2 3 3>,
-                               <&gpc0 3 2 3 3>, <&gpc0 4 2 3 3>,
-                               <&gpc0 5 2 3 3>, <&gpc0 6 2 3 3>;
                };
        };
 
                samsung,dw-mshc-ciu-div = <3>;
                samsung,dw-mshc-sdr-timing = <2 3>;
                samsung,dw-mshc-ddr-timing = <1 2>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;
 
                slot@0 {
                        reg = <0>;
                        bus-width = <4>;
-                       samsung,cd-pinmux-gpio = <&gpc3 2 2 3 3>;
-                       wp-gpios = <&gpc2 1 0 0 3>;
-                       gpios = <&gpc3 0 2 0 3>, <&gpc3 1 2 0 3>,
-                               <&gpc3 3 2 3 3>, <&gpc3 4 2 3 3>,
-                               <&gpc3 5 2 3 3>, <&gpc3 6 2 3 3>;
+                       wp-gpios = <&gpc2 1 0>;
                };
        };
 
                samsung,dw-mshc-ciu-div = <3>;
                samsung,dw-mshc-sdr-timing = <2 3>;
                samsung,dw-mshc-ddr-timing = <1 2>;
+               /* See board-specific dts files for pin setup */
 
                slot@0 {
                        reg = <0>;
                        bus-width = <4>;
-                       /* See board-specific dts files for GPIOs */
                };
        };
 
        };
 
        spi_1: spi@12d30000 {
-               gpios = <&gpa2 4 2 3 0>,
-                       <&gpa2 6 2 3 0>,
-                       <&gpa2 7 2 3 0>;
                samsung,spi-src-clk = <0>;
                num-cs = <1>;
        };
        };
 
        hdmi {
-               hpd-gpio = <&gpx3 7 0xf 1 3>;
+               hpd-gpio = <&gpx3 7 0>;
        };
 
        gpio-keys {
 
                power {
                        label = "Power";
-                       gpios = <&gpx1 3 0 0x10000 0>;
+                       gpios = <&gpx1 3 1>;
                        linux,code = <116>; /* KEY_POWER */
                        gpio-key,wakeup;
                };
index 1a62bcf18aa3cb942b4808d02fd007c7b995850b..b8771c5cb2a3c6d660467895132b3acb567d5f10 100644 (file)
                reg = <0x10440000 0x1000>;
        };
 
+       sys_reg: sysreg {
+               compatible = "samsung,exynos4-sysreg", "syscon";
+               reg = <0x10010000 0x400>;
+       };
+
        watchdog@10060000 {
                compatible = "samsung,s3c2410-wdt";
                reg = <0x10060000 0x100>;
                interrupts = <0 43 0>;
+               clocks = <&clock 345>;
+               clock-names = "watchdog";
                status = "disabled";
        };
 
                compatible = "samsung,s3c6410-rtc";
                reg = <0x10070000 0x100>;
                interrupts = <0 44 0>, <0 45 0>;
+               clocks = <&clock 346>;
+               clock-names = "rtc";
                status = "disabled";
        };
 
                compatible = "samsung,s5pv210-keypad";
                reg = <0x100A0000 0x100>;
                interrupts = <0 109 0>;
+               clocks = <&clock 347>;
+               clock-names = "keypad";
                status = "disabled";
        };
 
                compatible = "samsung,exynos4210-sdhci";
                reg = <0x12510000 0x100>;
                interrupts = <0 73 0>;
+               clocks = <&clock 297>, <&clock 145>;
+               clock-names = "hsmmc", "mmc_busclk.2";
                status = "disabled";
        };
 
                compatible = "samsung,exynos4210-sdhci";
                reg = <0x12520000 0x100>;
                interrupts = <0 74 0>;
+               clocks = <&clock 298>, <&clock 146>;
+               clock-names = "hsmmc", "mmc_busclk.2";
                status = "disabled";
        };
 
                compatible = "samsung,exynos4210-sdhci";
                reg = <0x12530000 0x100>;
                interrupts = <0 75 0>;
+               clocks = <&clock 299>, <&clock 147>;
+               clock-names = "hsmmc", "mmc_busclk.2";
                status = "disabled";
        };
 
                compatible = "samsung,exynos4210-sdhci";
                reg = <0x12540000 0x100>;
                interrupts = <0 76 0>;
+               clocks = <&clock 300>, <&clock 148>;
+               clock-names = "hsmmc", "mmc_busclk.2";
+               status = "disabled";
+       };
+
+       mfc: codec@13400000 {
+               compatible = "samsung,mfc-v5";
+               reg = <0x13400000 0x10000>;
+               interrupts = <0 94 0>;
+               samsung,power-domain = <&pd_mfc>;
                status = "disabled";
        };
 
                compatible = "samsung,exynos4210-uart";
                reg = <0x13800000 0x100>;
                interrupts = <0 52 0>;
+               clocks = <&clock 312>, <&clock 151>;
+               clock-names = "uart", "clk_uart_baud0";
                status = "disabled";
        };
 
                compatible = "samsung,exynos4210-uart";
                reg = <0x13810000 0x100>;
                interrupts = <0 53 0>;
+               clocks = <&clock 313>, <&clock 152>;
+               clock-names = "uart", "clk_uart_baud0";
                status = "disabled";
        };
 
                compatible = "samsung,exynos4210-uart";
                reg = <0x13820000 0x100>;
                interrupts = <0 54 0>;
+               clocks = <&clock 314>, <&clock 153>;
+               clock-names = "uart", "clk_uart_baud0";
                status = "disabled";
        };
 
                compatible = "samsung,exynos4210-uart";
                reg = <0x13830000 0x100>;
                interrupts = <0 55 0>;
+               clocks = <&clock 315>, <&clock 154>;
+               clock-names = "uart", "clk_uart_baud0";
                status = "disabled";
        };
 
                compatible = "samsung,s3c2440-i2c";
                reg = <0x13860000 0x100>;
                interrupts = <0 58 0>;
+               clocks = <&clock 317>;
+               clock-names = "i2c";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c0_bus>;
                status = "disabled";
        };
 
                compatible = "samsung,s3c2440-i2c";
                reg = <0x13870000 0x100>;
                interrupts = <0 59 0>;
+               clocks = <&clock 318>;
+               clock-names = "i2c";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c1_bus>;
                status = "disabled";
        };
 
                compatible = "samsung,s3c2440-i2c";
                reg = <0x13880000 0x100>;
                interrupts = <0 60 0>;
+               clocks = <&clock 319>;
+               clock-names = "i2c";
                status = "disabled";
        };
 
                compatible = "samsung,s3c2440-i2c";
                reg = <0x13890000 0x100>;
                interrupts = <0 61 0>;
+               clocks = <&clock 320>;
+               clock-names = "i2c";
                status = "disabled";
        };
 
                compatible = "samsung,s3c2440-i2c";
                reg = <0x138A0000 0x100>;
                interrupts = <0 62 0>;
+               clocks = <&clock 321>;
+               clock-names = "i2c";
                status = "disabled";
        };
 
                compatible = "samsung,s3c2440-i2c";
                reg = <0x138B0000 0x100>;
                interrupts = <0 63 0>;
+               clocks = <&clock 322>;
+               clock-names = "i2c";
                status = "disabled";
        };
 
                compatible = "samsung,s3c2440-i2c";
                reg = <0x138C0000 0x100>;
                interrupts = <0 64 0>;
+               clocks = <&clock 323>;
+               clock-names = "i2c";
                status = "disabled";
        };
 
                compatible = "samsung,s3c2440-i2c";
                reg = <0x138D0000 0x100>;
                interrupts = <0 65 0>;
+               clocks = <&clock 324>;
+               clock-names = "i2c";
                status = "disabled";
        };
 
                rx-dma-channel = <&pdma0 6>; /* preliminary */
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 327>, <&clock 159>;
+               clock-names = "spi", "spi_busclk0";
+               pinctrl-names = "default";
+               pinctrl-0 = <&spi0_bus>;
                status = "disabled";
        };
 
                rx-dma-channel = <&pdma1 6>; /* preliminary */
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 328>, <&clock 160>;
+               clock-names = "spi", "spi_busclk0";
+               pinctrl-names = "default";
+               pinctrl-0 = <&spi1_bus>;
                status = "disabled";
        };
 
                rx-dma-channel = <&pdma0 8>; /* preliminary */
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 329>, <&clock 161>;
+               clock-names = "spi", "spi_busclk0";
+               pinctrl-names = "default";
+               pinctrl-0 = <&spi2_bus>;
                status = "disabled";
        };
 
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x12680000 0x1000>;
                        interrupts = <0 35 0>;
+                       clocks = <&clock 292>;
+                       clock-names = "apb_pclk";
                        #dma-cells = <1>;
                        #dma-channels = <8>;
                        #dma-requests = <32>;
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x12690000 0x1000>;
                        interrupts = <0 36 0>;
+                       clocks = <&clock 293>;
+                       clock-names = "apb_pclk";
                        #dma-cells = <1>;
                        #dma-channels = <8>;
                        #dma-requests = <32>;
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x12850000 0x1000>;
                        interrupts = <0 34 0>;
+                       clocks = <&clock 279>;
+                       clock-names = "apb_pclk";
                        #dma-cells = <1>;
                        #dma-channels = <8>;
                        #dma-requests = <1>;
                };
        };
+
+       fimd: fimd@11c00000 {
+               compatible = "samsung,exynos4210-fimd";
+               interrupt-parent = <&combiner>;
+               reg = <0x11c00000 0x20000>;
+               interrupt-names = "fifo", "vsync", "lcd_sys";
+               interrupts = <11 0>, <11 1>, <11 2>;
+               clocks = <&clock 140>, <&clock 283>;
+               clock-names = "sclk_fimd", "fimd";
+               samsung,power-domain = <&pd_lcd0>;
+               status = "disabled";
+       };
 };
index f2710018e84eca2cb758825d84a6f8acde45ea60..524b90846df5fe7e8a9abf56d94634bb39b592c8 100644 (file)
                status = "okay";
        };
 
+       g2d@12800000 {
+               status = "okay";
+       };
+
+       codec@13400000 {
+               samsung,mfc-r = <0x43000000 0x800000>;
+               samsung,mfc-l = <0x51000000 0x800000>;
+               status = "okay";
+       };
+
        serial@13800000 {
                status = "okay";
        };
                        linux,default-trigger = "heartbeat";
                };
        };
+
+       fixed-rate-clocks {
+               xxti {
+                       compatible = "samsung,clock-xxti";
+                       clock-frequency = <0>;
+               };
+
+               xusbxti {
+                       compatible = "samsung,clock-xusbxti";
+                       clock-frequency = <24000000>;
+               };
+       };
 };
index f63490707f3a56646c8cc09edd471009d6644b14..91332b72acf547c0f3dfd859c01784d0961d069d 100644 (file)
        };
 
        sdhci@12530000 {
-               samsung,sdhci-bus-width = <4>;
-               linux,mmc_cap_4_bit_data;
-               samsung,sdhci-cd-internal;
-               gpio-cd = <&gpk2 2 2 3 3>;
-               gpios = <&gpk2 0 2 0 3>,
-                       <&gpk2 1 2 0 3>,
-                       <&gpk2 3 2 3 3>,
-                       <&gpk2 4 2 3 3>,
-                       <&gpk2 5 2 3 3>,
-                       <&gpk2 6 2 3 3>;
+               bus-width = <4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;
+               status = "okay";
+       };
+
+       g2d@12800000 {
+               status = "okay";
+       };
+
+       codec@13400000 {
+               samsung,mfc-r = <0x43000000 0x800000>;
+               samsung,mfc-l = <0x51000000 0x800000>;
                status = "okay";
        };
 
                status = "okay";
        };
 
+       pinctrl@11000000 {
+               keypad_rows: keypad-rows {
+                       samsung,pins = "gpx2-0", "gpx2-1";
+                       samsung,pin-function = <3>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <0>;
+               };
+
+               keypad_cols: keypad-cols {
+                       samsung,pins = "gpx1-0", "gpx1-1", "gpx1-2", "gpx1-3",
+                                      "gpx1-4", "gpx1-5", "gpx1-6", "gpx1-7";
+                       samsung,pin-function = <3>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <0>;
+               };
+       };
+
        keypad@100A0000 {
                samsung,keypad-num-rows = <2>;
                samsung,keypad-num-columns = <8>;
                linux,keypad-no-autorepeat;
                linux,keypad-wakeup;
+               pinctrl-names = "default";
+               pinctrl-0 = <&keypad_rows &keypad_cols>;
                status = "okay";
 
-               row-gpios = <&gpx2 0 3 3 0>,
-                           <&gpx2 1 3 3 0>;
-
-               col-gpios = <&gpx1 0 3 0 0>,
-                           <&gpx1 1 3 0 0>,
-                           <&gpx1 2 3 0 0>,
-                           <&gpx1 3 3 0 0>,
-                           <&gpx1 4 3 0 0>,
-                           <&gpx1 5 3 0 0>,
-                           <&gpx1 6 3 0 0>,
-                           <&gpx1 7 3 0 0>;
-
                key_1 {
                        keypad,row = <0>;
                        keypad,column = <3>;
                #address-cells = <1>;
                #size-cells = <0>;
                samsung,i2c-sda-delay = <100>;
-               samsung,i2c-max-bus-freq = <20000>;
-               gpios = <&gpd1 0 2 3 0>,
-                       <&gpd1 1 2 3 0>;
+               samsung,i2c-max-bus-freq = <100000>;
                status = "okay";
 
                eeprom@50 {
        };
 
        spi_2: spi@13940000 {
-               gpios = <&gpc1 1 5 3 0>,
-                       <&gpc1 3 5 3 0>,
-                       <&gpc1 4 5 3 0>;
                status = "okay";
 
                w25x80@0 {
                        spi-max-frequency = <1000000>;
 
                        controller-data {
-                               cs-gpio = <&gpc1 2 1 0 3>;
+                               cs-gpio = <&gpc1 2 0>;
                                samsung,spi-feedback-delay = <0>;
                        };
 
                        };
                };
        };
+
+       fixed-rate-clocks {
+               xxti {
+                       compatible = "samsung,clock-xxti";
+                       clock-frequency = <12000000>;
+               };
+
+               xusbxti {
+                       compatible = "samsung,clock-xusbxti";
+                       clock-frequency = <24000000>;
+               };
+       };
 };
index c346b64dff552ef3d13599846130f63be9068e5e..9a14484c7bb11b61d5e1f1ec3c185a3c50710ecc 100644 (file)
                        };
                };
        };
+
+       fixed-rate-clocks {
+               xxti {
+                       compatible = "samsung,clock-xxti";
+                       clock-frequency = <0>;
+               };
+
+               xusbxti {
+                       compatible = "samsung,clock-xusbxti";
+                       clock-frequency = <24000000>;
+               };
+       };
 };
index 2feffc70814cb9223f052528752be9abeb66c07a..9e6f381fa83574dea41c02037a3712ec357a104c 100644 (file)
                             <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>;
        };
 
+       mct@10050000 {
+               compatible = "samsung,exynos4210-mct";
+               reg = <0x10050000 0x800>;
+               interrupt-controller;
+               #interrups-cells = <2>;
+               interrupt-parent = <&mct_map>;
+               interrupts = <0 0>, <1 0>, <2 0>, <3 0>,
+                            <4 0>, <5 0>;
+               clocks = <&clock 3>, <&clock 344>;
+               clock-names = "fin_pll", "mct";
+
+               mct_map: mct-map {
+                       #interrupt-cells = <2>;
+                       #address-cells = <0>;
+                       #size-cells = <0>;
+                       interrupt-map = <0x0 0 &gic 0 57 0>,
+                                       <0x1 0 &gic 0 69 0>,
+                                       <0x2 0 &combiner 12 6>,
+                                       <0x3 0 &combiner 12 7>,
+                                       <0x4 0 &gic 0 42 0>,
+                                       <0x5 0 &gic 0 48 0>;
+               };
+       };
+
+       clock: clock-controller@0x10030000 {
+               compatible = "samsung,exynos4210-clock";
+               reg = <0x10030000 0x20000>;
+               #clock-cells = <1>;
+       };
+
        pinctrl_0: pinctrl@11400000 {
                compatible = "samsung,exynos4210-pinctrl";
                reg = <0x11400000 0x1000>;
                reg = <0x100C0000 0x100>;
                interrupts = <2 4>;
        };
+
+       g2d@12800000 {
+               compatible = "samsung,s5pv210-g2d";
+               reg = <0x12800000 0x1000>;
+               interrupts = <0 89 0>;
+               status = "disabled";
+       };
 };
index c6ae2005961f2f55bc4cb01bf920e15e83cc1244..36d4299789ef163474139cf4329b179ea7ca4eba 100644 (file)
        gic:interrupt-controller@10490000 {
                cpu-offset = <0x8000>;
        };
+
+       mct@10050000 {
+               compatible = "samsung,exynos4412-mct";
+               reg = <0x10050000 0x800>;
+               interrupt-controller;
+               #interrups-cells = <2>;
+               interrupt-parent = <&mct_map>;
+               interrupts = <0 0>, <1 0>, <2 0>, <3 0>,
+                            <4 0>, <5 0>;
+
+               mct_map: mct-map {
+                       #interrupt-cells = <2>;
+                       #address-cells = <0>;
+                       #size-cells = <0>;
+                       interrupt-map = <0x0 0 &gic 0 57 0>,
+                                       <0x1 0 &combiner 12 5>,
+                                       <0x2 0 &combiner 12 6>,
+                                       <0x3 0 &combiner 12 7>,
+                                       <0x4 0 &gic 1 12 0>,
+                                       <0x5 0 &gic 1 12 0>;
+               };
+       };
 };
diff --git a/arch/arm/boot/dts/exynos4412-odroidx.dts b/arch/arm/boot/dts/exynos4412-odroidx.dts
new file mode 100644 (file)
index 0000000..15dc0a3
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Hardkernel's Exynos4412 based ODROID-X board device tree source
+ *
+ * Copyright (c) 2012 Dongjin Kim <tobetter@gmail.com>
+ *
+ * Device tree source file for Hardkernel's ODROID-X board which is based on
+ * Samsung's Exynos4412 SoC.
+ *
+ * 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.
+*/
+
+/dts-v1/;
+/include/ "exynos4412.dtsi"
+
+/ {
+       model = "Hardkernel ODROID-X board based on Exynos4412";
+       compatible = "hardkernel,odroid-x", "samsung,exynos4412";
+
+       memory {
+               reg = <0x40000000 0x40000000>;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               led1 {
+                       label = "led1:heart";
+                       gpios = <&gpc1 0 1>;
+                       default-state = "on";
+                       linux,default-trigger = "heartbeat";
+               };
+               led2 {
+                       label = "led2:mmc0";
+                       gpios = <&gpc1 2 1>;
+                       default-state = "on";
+                       linux,default-trigger = "mmc0";
+               };
+       };
+
+       mshc@12550000 {
+               pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>;
+               pinctrl-names = "default";
+               status = "okay";
+
+               num-slots = <1>;
+               supports-highspeed;
+               broken-cd;
+               fifo-depth = <0x80>;
+               card-detect-delay = <200>;
+               samsung,dw-mshc-ciu-div = <3>;
+               samsung,dw-mshc-sdr-timing = <2 3>;
+               samsung,dw-mshc-ddr-timing = <1 2>;
+
+               slot@0 {
+                       reg = <0>;
+                       bus-width = <8>;
+               };
+       };
+
+       regulator_p3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "p3v3_en";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpa1 1 1>;
+               enable-active-high;
+               regulator-boot-on;
+       };
+
+       rtc@10070000 {
+               status = "okay";
+       };
+
+       sdhci@12530000 {
+               bus-width = <4>;
+               pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;
+               pinctrl-names = "default";
+               status = "okay";
+       };
+
+       serial@13800000 {
+               status = "okay";
+       };
+
+       serial@13810000 {
+               status = "okay";
+       };
+
+       serial@13820000 {
+               status = "okay";
+       };
+
+       serial@13830000 {
+               status = "okay";
+       };
+
+       fixed-rate-clocks {
+               xxti {
+                       compatible = "samsung,clock-xxti";
+                       clock-frequency = <0>;
+               };
+
+               xusbxti {
+                       compatible = "samsung,clock-xusbxti";
+                       clock-frequency = <24000000>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts
new file mode 100644 (file)
index 0000000..b39bffc
--- /dev/null
@@ -0,0 +1,451 @@
+/*
+ * Insignal's Exynos4412 based Origen board device tree source
+ *
+ * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Device tree source file for Insignal's Origen board which is based on
+ * Samsung's Exynos4412 SoC.
+ *
+ * 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.
+*/
+
+/dts-v1/;
+/include/ "exynos4412.dtsi"
+
+/ {
+       model = "Insignal Origen evaluation board based on Exynos4412";
+       compatible = "insignal,origen4412", "samsung,exynos4412";
+
+       memory {
+               reg = <0x40000000 0x40000000>;
+       };
+
+       chosen {
+               bootargs ="console=ttySAC2,115200";
+       };
+
+       mmc_reg: voltage-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "VMEM_VDD_2.8V";
+               regulator-min-microvolt = <2800000>;
+               regulator-max-microvolt = <2800000>;
+               gpio = <&gpx1 1 0>;
+               enable-active-high;
+       };
+
+       sdhci@12530000 {
+               bus-width = <4>;
+               pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &sd2_cd>;
+               pinctrl-names = "default";
+               vmmc-supply = <&mmc_reg>;
+               status = "okay";
+       };
+
+       mshc@12550000 {
+               pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>;
+               pinctrl-names = "default";
+               status = "okay";
+
+               num-slots = <1>;
+               supports-highspeed;
+               broken-cd;
+               fifo-depth = <0x80>;
+               card-detect-delay = <200>;
+               samsung,dw-mshc-ciu-div = <3>;
+               samsung,dw-mshc-sdr-timing = <2 3>;
+               samsung,dw-mshc-ddr-timing = <1 2>;
+
+               slot@0 {
+                       reg = <0>;
+                       bus-width = <8>;
+               };
+       };
+
+       codec@13400000 {
+               samsung,mfc-r = <0x43000000 0x800000>;
+               samsung,mfc-l = <0x51000000 0x800000>;
+               status = "okay";
+       };
+
+       fimd@11c00000 {
+               pinctrl-0 = <&lcd_clk &lcd_data24 &pwm1_out>;
+               pinctrl-names = "default";
+               status = "okay";
+       };
+
+       display-timings {
+               native-mode = <&timing0>;
+               timing0: timing {
+                       clock-frequency = <50000>;
+                       hactive = <1024>;
+                       vactive = <600>;
+                       hfront-porch = <64>;
+                       hback-porch = <16>;
+                       hsync-len = <48>;
+                       vback-porch = <64>;
+                       vfront-porch = <16>;
+                       vsync-len = <3>;
+               };
+       };
+
+       serial@13800000 {
+               status = "okay";
+       };
+
+       serial@13810000 {
+               status = "okay";
+       };
+
+       serial@13820000 {
+               status = "okay";
+       };
+
+       serial@13830000 {
+               status = "okay";
+       };
+
+       i2c@13860000 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               samsung,i2c-sda-delay = <100>;
+               samsung,i2c-max-bus-freq = <20000>;
+               pinctrl-0 = <&i2c0_bus>;
+               pinctrl-names = "default";
+               status = "okay";
+
+               s5m8767_pmic@66 {
+                       compatible = "samsung,s5m8767-pmic";
+                       reg = <0x66>;
+
+                       s5m8767,pmic-buck-default-dvs-idx = <3>;
+
+                       s5m8767,pmic-buck-dvs-gpios = <&gpx2 3 0>,
+                                                        <&gpx2 4 0>,
+                                                        <&gpx2 5 0>;
+
+                       s5m8767,pmic-buck-ds-gpios = <&gpm3 5 0>,
+                                                       <&gpm3 6 0>,
+                                                       <&gpm3 7 0>;
+
+                       s5m8767,pmic-buck2-dvs-voltage = <1250000>, <1200000>,
+                                                        <1200000>, <1200000>,
+                                                        <1200000>, <1200000>,
+                                                        <1200000>, <1200000>;
+
+                       s5m8767,pmic-buck3-dvs-voltage = <1100000>, <1100000>,
+                                                        <1100000>, <1100000>,
+                                                        <1100000>, <1100000>,
+                                                        <1100000>, <1100000>;
+
+                       s5m8767,pmic-buck4-dvs-voltage = <1200000>, <1200000>,
+                                                        <1200000>, <1200000>,
+                                                        <1200000>, <1200000>,
+                                                        <1200000>, <1200000>;
+
+                       regulators {
+                               ldo1_reg: LDO1 {
+                                       regulator-name = "VDD_ALIVE";
+                                       regulator-min-microvolt = <1100000>;
+                                       regulator-max-microvolt = <1100000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo2_reg: LDO2 {
+                                       regulator-name = "VDDQ_M12";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo3_reg: LDO3 {
+                                       regulator-name = "VDDIOAP_18";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo4_reg: LDO4 {
+                                       regulator-name = "VDDQ_PRE";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo5_reg: LDO5 {
+                                       regulator-name = "VDD18_2M";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo6_reg: LDO6 {
+                                       regulator-name = "VDD10_MPLL";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo7_reg: LDO7 {
+                                       regulator-name = "VDD10_XPLL";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo8_reg: LDO8 {
+                                       regulator-name = "VDD10_MIPI";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo9_reg: LDO9 {
+                                       regulator-name = "VDD33_LCD";
+                                       regulator-min-microvolt = <3300000>;
+                                       regulator-max-microvolt = <3300000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo10_reg: LDO10 {
+                                       regulator-name = "VDD18_MIPI";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo11_reg: LDO11 {
+                                       regulator-name = "VDD18_ABB1";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo12_reg: LDO12 {
+                                       regulator-name = "VDD33_UOTG";
+                                       regulator-min-microvolt = <3300000>;
+                                       regulator-max-microvolt = <3300000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo13_reg: LDO13 {
+                                       regulator-name = "VDDIOPERI_18";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo14_reg: LDO14 {
+                                       regulator-name = "VDD18_ABB02";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo15_reg: LDO15 {
+                                       regulator-name = "VDD10_USH";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo16_reg: LDO16 {
+                                       regulator-name = "VDD18_HSIC";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo17_reg: LDO17 {
+                                       regulator-name = "VDDIOAP_MMC012_28";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo18_reg: LDO18 {
+                                       regulator-name = "VDDIOPERI_28";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo19_reg: LDO19 {
+                                       regulator-name = "DVDD25";
+                                       regulator-min-microvolt = <2500000>;
+                                       regulator-max-microvolt = <2500000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo20_reg: LDO20 {
+                                       regulator-name = "VDD28_CAM";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo21_reg: LDO21 {
+                                       regulator-name = "VDD28_AF";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo22_reg: LDO22 {
+                                       regulator-name = "VDDA28_2M";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo23_reg: LDO23 {
+                                       regulator-name = "VDD28_TF";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo24_reg: LDO24 {
+                                       regulator-name = "VDD33_A31";
+                                       regulator-min-microvolt = <3300000>;
+                                       regulator-max-microvolt = <3300000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo25_reg: LDO25 {
+                                       regulator-name = "VDD18_CAM";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo26_reg: LDO26 {
+                                       regulator-name = "VDD18_A31";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo27_reg: LDO27 {
+                                       regulator-name = "GPS_1V8";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               ldo28_reg: LDO28 {
+                                       regulator-name = "DVDD12";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       regulator-always-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               buck1_reg: BUCK1 {
+                                       regulator-name = "vdd_mif";
+                                       regulator-min-microvolt = <950000>;
+                                       regulator-max-microvolt = <1100000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               buck2_reg: BUCK2 {
+                                       regulator-name = "vdd_arm";
+                                       regulator-min-microvolt = <925000>;
+                                       regulator-max-microvolt = <1300000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               buck3_reg: BUCK3 {
+                                       regulator-name = "vdd_int";
+                                       regulator-min-microvolt = <900000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               buck4_reg: BUCK4 {
+                                       regulator-name = "vdd_g3d";
+                                       regulator-min-microvolt = <750000>;
+                                       regulator-max-microvolt = <1500000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               buck5_reg: BUCK5 {
+                                       regulator-name = "vdd_m12";
+                                       regulator-min-microvolt = <750000>;
+                                       regulator-max-microvolt = <1500000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               buck6_reg: BUCK6 {
+                                       regulator-name = "vdd12_5m";
+                                       regulator-min-microvolt = <750000>;
+                                       regulator-max-microvolt = <1500000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+
+                               buck9_reg: BUCK9 {
+                                       regulator-name = "vddf28_emmc";
+                                       regulator-min-microvolt = <750000>;
+                                       regulator-max-microvolt = <3000000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>; /* Normal Mode */
+                               };
+                       };
+               };
+       };
+
+       fixed-rate-clocks {
+               xxti {
+                       compatible = "samsung,clock-xxti";
+                       clock-frequency = <0>;
+               };
+
+               xusbxti {
+                       compatible = "samsung,clock-xusbxti";
+                       clock-frequency = <24000000>;
+               };
+       };
+};
index f05bf575cc456537b5912f606219b4850ef85bed..dd564310d4a53ed1406330ce1dcae924d4ac2499 100644 (file)
                bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc";
        };
 
+       g2d@10800000 {
+               status = "okay";
+       };
+
+       g2d@10800000 {
+               status = "okay";
+       };
+
+       sdhci@12530000 {
+               bus-width = <4>;
+               pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus4 &sd2_cd>;
+               pinctrl-names = "default";
+               status = "okay";
+       };
+
+       codec@13400000 {
+               samsung,mfc-r = <0x43000000 0x800000>;
+               samsung,mfc-l = <0x51000000 0x800000>;
+               status = "okay";
+       };
+
        serial@13800000 {
                status = "okay";
        };
        serial@13830000 {
                status = "okay";
        };
+
+       fixed-rate-clocks {
+               xxti {
+                       compatible = "samsung,clock-xxti";
+                       clock-frequency = <0>;
+               };
+
+               xusbxti {
+                       compatible = "samsung,clock-xusbxti";
+                       clock-frequency = <24000000>;
+               };
+       };
 };
index d7dfe312772a6e5b26a660d2fcf90b7dcdc8badf..d75c047e80a96ca0ed31fb7f6ecf612e41d11262 100644 (file)
        gic:interrupt-controller@10490000 {
                cpu-offset = <0x4000>;
        };
+
+       mct@10050000 {
+               compatible = "samsung,exynos4412-mct";
+               reg = <0x10050000 0x800>;
+               interrupt-controller;
+               #interrups-cells = <2>;
+               interrupt-parent = <&mct_map>;
+               interrupts = <0 0>, <1 0>, <2 0>, <3 0>,
+                            <4 0>, <5 0>, <6 0>, <7 0>;
+               clocks = <&clock 3>, <&clock 344>;
+               clock-names = "fin_pll", "mct";
+
+               mct_map: mct-map {
+                       #interrupt-cells = <2>;
+                       #address-cells = <0>;
+                       #size-cells = <0>;
+                       interrupt-map = <0x0 0 &gic 0 57 0>,
+                                       <0x1 0 &combiner 12 5>,
+                                       <0x2 0 &combiner 12 6>,
+                                       <0x3 0 &combiner 12 7>,
+                                       <0x4 0 &gic 1 12 0>,
+                                       <0x5 0 &gic 1 12 0>,
+                                       <0x6 0 &gic 1 12 0>,
+                                       <0x7 0 &gic 1 12 0>;
+               };
+       };
 };
index 9a87806949093e717b1084e1704f14db33767e06..e3380a7a285c103fd86c1121f0a73bded0536917 100644 (file)
                             <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>;
        };
 
+       clock: clock-controller@0x10030000 {
+               compatible = "samsung,exynos4412-clock";
+               reg = <0x10030000 0x20000>;
+               #clock-cells = <1>;
+       };
+
        pinctrl_0: pinctrl@11400000 {
                compatible = "samsung,exynos4x12-pinctrl";
                reg = <0x11400000 0x1000>;
                reg = <0x106E0000 0x1000>;
                interrupts = <0 72 0>;
        };
+
+       g2d@10800000 {
+               compatible = "samsung,exynos4212-g2d";
+               reg = <0x10800000 0x1000>;
+               interrupts = <0 89 0>;
+               status = "disabled";
+       };
 };
diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts
new file mode 100644 (file)
index 0000000..02cfc76
--- /dev/null
@@ -0,0 +1,452 @@
+/*
+ * Samsung's Exynos5250 based Arndale board device tree source
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * 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.
+*/
+
+/dts-v1/;
+/include/ "exynos5250.dtsi"
+
+/ {
+       model = "Insignal Arndale evaluation board based on EXYNOS5250";
+       compatible = "insignal,arndale", "samsung,exynos5250";
+
+       memory {
+               reg = <0x40000000 0x80000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttySAC2,115200";
+       };
+
+       codec@11000000 {
+               samsung,mfc-r = <0x43000000 0x800000>;
+               samsung,mfc-l = <0x51000000 0x800000>;
+       };
+
+       i2c@12C60000 {
+               samsung,i2c-sda-delay = <100>;
+               samsung,i2c-max-bus-freq = <20000>;
+               samsung,i2c-slave-addr = <0x66>;
+
+               s5m8767_pmic@66 {
+                       compatible = "samsung,s5m8767-pmic";
+                       reg = <0x66>;
+
+                       s5m8767,pmic-buck2-dvs-voltage = <1300000>;
+                       s5m8767,pmic-buck3-dvs-voltage = <1100000>;
+                       s5m8767,pmic-buck4-dvs-voltage = <1200000>;
+                       s5m8767,pmic-buck-dvs-gpios = <&gpd1 0 0>,
+                                                       <&gpd1 1 0>,
+                                                       <&gpd1 2 0>;
+                       s5m8767,pmic-buck-ds-gpios = <&gpx2 3 0>,
+                                                       <&gpx2 4 0>,
+                                                       <&gpx2 5 0>;
+                       regulators {
+                               ldo1_reg: LDO1 {
+                                       regulator-name = "VDD_ALIVE_1.0V";
+                                       regulator-min-microvolt = <1100000>;
+                                       regulator-max-microvolt = <1100000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>;
+                               };
+
+                               ldo2_reg: LDO2 {
+                                       regulator-name = "VDD_28IO_DP_1.35V";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>;
+                               };
+
+                               ldo3_reg: LDO3 {
+                                       regulator-name = "VDD_COMMON1_1.8V";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>;
+                               };
+
+                               ldo4_reg: LDO4 {
+                                       regulator-name = "VDD_IOPERI_1.8V";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       op_mode = <1>;
+                               };
+
+                               ldo5_reg: LDO5 {
+                                       regulator-name = "VDD_EXT_1.8V";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>;
+                               };
+
+                               ldo6_reg: LDO6 {
+                                       regulator-name = "VDD_MPLL_1.1V";
+                                       regulator-min-microvolt = <1100000>;
+                                       regulator-max-microvolt = <1100000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>;
+                               };
+
+                               ldo7_reg: LDO7 {
+                                       regulator-name = "VDD_XPLL_1.1V";
+                                       regulator-min-microvolt = <1100000>;
+                                       regulator-max-microvolt = <1100000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>;
+                               };
+
+                               ldo8_reg: LDO8 {
+                                       regulator-name = "VDD_COMMON2_1.0V";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>;
+                               };
+
+                               ldo9_reg: LDO9 {
+                                       regulator-name = "VDD_33ON_3.0V";
+                                       regulator-min-microvolt = <3000000>;
+                                       regulator-max-microvolt = <3000000>;
+                                       op_mode = <1>;
+                               };
+
+                               ldo10_reg: LDO10 {
+                                       regulator-name = "VDD_COMMON3_1.8V";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>;
+                               };
+
+                               ldo11_reg: LDO11 {
+                                       regulator-name = "VDD_ABB2_1.8V";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>;
+                               };
+
+                               ldo12_reg: LDO12 {
+                                       regulator-name = "VDD_USB_3.0V";
+                                       regulator-min-microvolt = <3000000>;
+                                       regulator-max-microvolt = <3000000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>;
+                               };
+
+                               ldo13_reg: LDO13 {
+                                       regulator-name = "VDDQ_C2C_W_1.8V";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>;
+                               };
+
+                               ldo14_reg: LDO14 {
+                                       regulator-name = "VDD18_ABB0_3_1.8V";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>;
+                               };
+
+                               ldo15_reg: LDO15 {
+                                       regulator-name = "VDD10_COMMON4_1.0V";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>;
+                               };
+
+                               ldo16_reg: LDO16 {
+                                       regulator-name = "VDD18_HSIC_1.8V";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>;
+                               };
+
+                               ldo17_reg: LDO17 {
+                                       regulator-name = "VDDQ_MMC2_3_2.8V";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>;
+                               };
+
+                               ldo18_reg: LDO18 {
+                                       regulator-name = "VDD_33ON_2.8V";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                                       op_mode = <1>;
+                               };
+
+                               ldo22_reg: LDO22 {
+                                       regulator-name = "EXT_33_OFF";
+                                       regulator-min-microvolt = <3300000>;
+                                       regulator-max-microvolt = <3300000>;
+                                       op_mode = <1>;
+                               };
+
+                               ldo23_reg: LDO23 {
+                                       regulator-name = "EXT_28_OFF";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <2800000>;
+                                       op_mode = <1>;
+                               };
+
+                               ldo25_reg: LDO25 {
+                                       regulator-name = "PVDD_LDO25";
+                                       regulator-min-microvolt = <1200000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       op_mode = <1>;
+                               };
+
+                               ldo26_reg: LDO26 {
+                                       regulator-name = "EXT_18_OFF";
+                                       regulator-min-microvolt = <1800000>;
+                                       regulator-max-microvolt = <1800000>;
+                                       op_mode = <1>;
+                               };
+
+                               buck1_reg: BUCK1 {
+                                       regulator-name = "vdd_mif";
+                                       regulator-min-microvolt = <950000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>;
+                               };
+
+                               buck2_reg: BUCK2 {
+                                       regulator-name = "vdd_arm";
+                                       regulator-min-microvolt = <925000>;
+                                       regulator-max-microvolt = <1300000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>;
+                               };
+
+                               buck3_reg: BUCK3 {
+                                       regulator-name = "vdd_int";
+                                       regulator-min-microvolt = <900000>;
+                                       regulator-max-microvolt = <1200000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>;
+                               };
+
+                               buck4_reg: BUCK4 {
+                                       regulator-name = "vdd_g3d";
+                                       regulator-min-microvolt = <1000000>;
+                                       regulator-max-microvolt = <1000000>;
+                                       regulator-boot-on;
+                                       op_mode = <1>;
+                               };
+
+                               buck5_reg: BUCK5 {
+                                       regulator-name = "VDD_MEM_1.35V";
+                                       regulator-min-microvolt = <750000>;
+                                       regulator-max-microvolt = <1355000>;
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                                       op_mode = <1>;
+                               };
+
+                               buck9_reg: BUCK9 {
+                                       regulator-name = "VDD_33_OFF_EXT1";
+                                       regulator-min-microvolt = <750000>;
+                                       regulator-max-microvolt = <3000000>;
+                                       op_mode = <1>;
+                               };
+                       };
+               };
+       };
+
+       i2c@12C70000 {
+               status = "disabled";
+       };
+
+       i2c@12C80000 {
+               status = "disabled";
+       };
+
+       i2c@12C90000 {
+               status = "disabled";
+       };
+
+       i2c@12CA0000 {
+               status = "disabled";
+       };
+
+       i2c@12CB0000 {
+               status = "disabled";
+       };
+
+       i2c@12CC0000 {
+               status = "disabled";
+       };
+
+       i2c@12CD0000 {
+               status = "disabled";
+       };
+
+       i2c@121D0000 {
+               status = "disabled";
+       };
+
+       dwmmc_0: dwmmc0@12200000 {
+               num-slots = <1>;
+               supports-highspeed;
+               broken-cd;
+               fifo-depth = <0x80>;
+               card-detect-delay = <200>;
+               samsung,dw-mshc-ciu-div = <3>;
+               samsung,dw-mshc-sdr-timing = <2 3>;
+               samsung,dw-mshc-ddr-timing = <1 2>;
+               vmmc-supply = <&mmc_reg>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
+
+               slot@0 {
+                       reg = <0>;
+                       bus-width = <8>;
+               };
+       };
+
+       dwmmc_1: dwmmc1@12210000 {
+               status = "disabled";
+       };
+
+       dwmmc_2: dwmmc2@12220000 {
+               num-slots = <1>;
+               supports-highspeed;
+               fifo-depth = <0x80>;
+               card-detect-delay = <200>;
+               samsung,dw-mshc-ciu-div = <3>;
+               samsung,dw-mshc-sdr-timing = <2 3>;
+               samsung,dw-mshc-ddr-timing = <1 2>;
+               vmmc-supply = <&mmc_reg>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;
+
+               slot@0 {
+                       reg = <0>;
+                       bus-width = <4>;
+                       disable-wp;
+               };
+       };
+
+       dwmmc_3: dwmmc3@12230000 {
+               status = "disabled";
+       };
+
+       spi_0: spi@12d20000 {
+               status = "disabled";
+       };
+
+       spi_1: spi@12d30000 {
+               status = "disabled";
+       };
+
+       spi_2: spi@12d40000 {
+               status = "disabled";
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+
+               menu {
+                       label = "SW-TACT2";
+                       gpios = <&gpx1 4 1>;
+                       linux,code = <139>;
+                       gpio-key,wakeup;
+               };
+
+               home {
+                       label = "SW-TACT3";
+                       gpios = <&gpx1 5 1>;
+                       linux,code = <102>;
+                       gpio-key,wakeup;
+               };
+
+               up {
+                       label = "SW-TACT4";
+                       gpios = <&gpx1 6 1>;
+                       linux,code = <103>;
+                       gpio-key,wakeup;
+               };
+
+               down {
+                       label = "SW-TACT5";
+                       gpios = <&gpx1 7 1>;
+                       linux,code = <108>;
+                       gpio-key,wakeup;
+               };
+
+               back {
+                       label = "SW-TACT6";
+                       gpios = <&gpx2 0 1>;
+                       linux,code = <158>;
+                       gpio-key,wakeup;
+               };
+
+               wakeup {
+                       label = "SW-TACT7";
+                       gpios = <&gpx2 1 1>;
+                       linux,code = <143>;
+                       gpio-key,wakeup;
+               };
+       };
+
+       hdmi {
+               hpd-gpio = <&gpx3 7 2>;
+               vdd_osc-supply = <&ldo10_reg>;
+               vdd_pll-supply = <&ldo8_reg>;
+               vdd-supply = <&ldo8_reg>;
+       };
+
+       mmc_reg: voltage-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "VDD_33ON_2.8V";
+               regulator-min-microvolt = <2800000>;
+               regulator-max-microvolt = <2800000>;
+               gpio = <&gpx1 1 1>;
+               enable-active-high;
+       };
+
+       reg_hdmi_en: fixedregulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "hdmi-en";
+       };
+
+       fixed-rate-clocks {
+               xxti {
+                       compatible = "samsung,clock-xxti";
+                       clock-frequency = <24000000>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/exynos5250-pinctrl.dtsi b/arch/arm/boot/dts/exynos5250-pinctrl.dtsi
new file mode 100644 (file)
index 0000000..d1650fb
--- /dev/null
@@ -0,0 +1,783 @@
+/*
+ * Samsung's Exynos5250 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * Samsung's Exynos5250 SoC pin-mux and pin-config optiosn are listed as device
+ * tree nodes are listed in this file.
+ *
+ * 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.
+*/
+
+/ {
+       pinctrl@11400000 {
+               gpa0: gpa0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpa1: gpa1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpa2: gpa2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpb0: gpb0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpb1: gpb1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpb2: gpb2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpb3: gpb3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpc0: gpc0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpc1: gpc1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpc2: gpc2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpc3: gpc3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpd0: gpd0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpd1: gpd1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpy0: gpy0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy1: gpy1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy2: gpy2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy3: gpy3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy4: gpy4 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy5: gpy5 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpy6: gpy6 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+               };
+
+               gpc4: gpc4 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpx0: gpx0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       interrupt-parent = <&combiner>;
+                       #interrupt-cells = <2>;
+                       interrupts = <23 0>, <24 0>, <25 0>, <25 1>,
+                                    <26 0>, <26 1>, <27 0>, <27 1>;
+               };
+
+               gpx1: gpx1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       interrupt-parent = <&combiner>;
+                       #interrupt-cells = <2>;
+                       interrupts = <28 0>, <28 1>, <29 0>, <29 1>,
+                                    <30 0>, <30 1>, <31 0>, <31 1>;
+               };
+
+               gpx2: gpx2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpx3: gpx3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               uart0_data: uart0-data {
+                       samsung,pins = "gpa0-0", "gpa0-1";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <0>;
+               };
+
+               uart0_fctl: uart0-fctl {
+                       samsung,pins = "gpa0-2", "gpa0-3";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samaung,pin-drv = <0>;
+               };
+
+               i2c2_bus: i2c2-bus {
+                       samsung,pins = "gpa0-6", "gpa0-7";
+                       samsung,pin-function = <3>;
+                       samsung,pin-pud = <3>;
+                       samaung,pin-drv = <0>;
+               };
+
+               i2c2_hs_bus: i2c2-hs-bus {
+                       samsung,pins = "gpa0-6", "gpa0-7";
+                       samsung,pin-function = <4>;
+                       samsung,pin-pud = <3>;
+                       samaung,pin-drv = <0>;
+               };
+
+               uart2_data: uart2-data {
+                       samsung,pins = "gpa1-0", "gpa1-1";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <0>;
+               };
+
+               uart2_fctl: uart2-fctl {
+                       samsung,pins = "gpa1-2", "gpa1-3";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samaung,pin-drv = <0>;
+               };
+
+               i2c3_bus: i2c3-bus {
+                       samsung,pins = "gpa1-2", "gpa1-3";
+                       samsung,pin-function = <3>;
+                       samsung,pin-pud = <3>;
+                       samaung,pin-drv = <0>;
+               };
+
+               i2c3_hs_bus: i2c3-hs-bus {
+                       samsung,pins = "gpa1-2", "gpa1-3";
+                       samsung,pin-function = <4>;
+                       samsung,pin-pud = <3>;
+                       samaung,pin-drv = <0>;
+               };
+
+               uart3_data: uart3-data {
+                       samsung,pins = "gpa1-4", "gpa1-4";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <0>;
+               };
+
+               spi0_bus: spi0-bus {
+                       samsung,pins = "gpa2-0", "gpa2-2", "gpa2-3";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <0>;
+               };
+
+               i2c4_bus: i2c4-bus {
+                       samsung,pins = "gpa2-0", "gpa2-1";
+                       samsung,pin-function = <3>;
+                       samsung,pin-pud = <3>;
+                       samaung,pin-drv = <0>;
+               };
+
+               i2c5_bus: i2c5-bus {
+                       samsung,pins = "gpa2-2", "gpa2-3";
+                       samsung,pin-function = <3>;
+                       samsung,pin-pud = <3>;
+                       samaung,pin-drv = <0>;
+               };
+
+               spi1_bus: spi1-bus {
+                       samsung,pins = "gpa2-4", "gpa2-6", "gpa2-7";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <0>;
+               };
+
+               i2s1_bus: i2s1-bus {
+                       samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
+                                       "gpb0-4";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <0>;
+               };
+
+               pcm1_bus: pcm1-bus {
+                       samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
+                                       "gpb0-4";
+                       samsung,pin-function = <3>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <0>;
+               };
+
+               ac97_bus: ac97-bus {
+                       samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
+                                       "gpb0-4";
+                       samsung,pin-function = <4>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <0>;
+               };
+
+               i2s2_bus: i2s2-bus {
+                       samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3",
+                                       "gpb1-4";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <0>;
+               };
+
+               pcm2_bus: pcm2-bus {
+                       samsung,pins = "gpb1-0", "gpb1-1", "gpb1-2", "gpb1-3",
+                                       "gpb1-4";
+                       samsung,pin-function = <3>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <0>;
+               };
+
+               spdif_bus: spdif-bus {
+                       samsung,pins = "gpb1-0", "gpb1-1";
+                       samsung,pin-function = <4>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <0>;
+               };
+
+               spi2_bus: spi2-bus {
+                       samsung,pins = "gpb1-1", "gpb1-3", "gpb1-4";
+                       samsung,pin-function = <5>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <0>;
+               };
+
+               i2c6_bus: i2c6-bus {
+                       samsung,pins = "gpb1-3", "gpb1-4";
+                       samsung,pin-function = <4>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <0>;
+               };
+
+               i2c7_bus: i2c7-bus {
+                       samsung,pins = "gpb2-2", "gpb2-3";
+                       samsung,pin-function = <3>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <0>;
+               };
+
+               i2c0_bus: i2c0-bus {
+                       samsung,pins = "gpb3-0", "gpb3-1";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <0>;
+               };
+
+               i2c1_bus: i2c1-bus {
+                       samsung,pins = "gpb3-2", "gpb3-3";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <0>;
+               };
+
+               i2c0_hs_bus: i2c0-hs-bus {
+                       samsung,pins = "gpb3-0", "gpb3-1";
+                       samsung,pin-function = <4>;
+                       samsung,pin-pud = <3>;
+                       samaung,pin-drv = <0>;
+               };
+
+               i2c1_hs_bus: i2c1-hs-bus {
+                       samsung,pins = "gpb3-2", "gpb3-3";
+                       samsung,pin-function = <4>;
+                       samsung,pin-pud = <3>;
+                       samaung,pin-drv = <0>;
+               };
+
+               sd0_clk: sd0-clk {
+                       samsung,pins = "gpc0-0";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <3>;
+               };
+
+               sd0_cmd: sd0-cmd {
+                       samsung,pins = "gpc0-1";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <3>;
+               };
+
+               sd0_cd: sd0-cd {
+                       samsung,pins = "gpc0-2";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <3>;
+               };
+
+               sd0_bus1: sd0-bus-width1 {
+                       samsung,pins = "gpc0-3";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <3>;
+               };
+
+               sd0_bus4: sd0-bus-width4 {
+                       samsung,pins = "gpc0-3", "gpc0-4", "gpc0-5", "gpc0-6";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <3>;
+               };
+
+               sd0_bus8: sd0-bus-width8 {
+                       samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <3>;
+               };
+
+               sd1_clk: sd1-clk {
+                       samsung,pins = "gpc2-0";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <3>;
+               };
+
+               sd1_cmd: sd1-cmd {
+                       samsung,pins = "gpc2-1";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <3>;
+               };
+
+               sd1_cd: sd1-cd {
+                       samsung,pins = "gpc2-2";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <3>;
+               };
+
+               sd1_bus1: sd1-bus-width1 {
+                       samsung,pins = "gpc2-3";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <3>;
+               };
+
+               sd1_bus4: sd1-bus-width4 {
+                       samsung,pins = "gpc2-3", "gpc2-4", "gpc2-5", "gpc2-6";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <3>;
+               };
+
+               sd2_clk: sd2-clk {
+                       samsung,pins = "gpc3-0";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <3>;
+               };
+
+               sd2_cmd: sd2-cmd {
+                       samsung,pins = "gpc3-1";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <3>;
+               };
+
+               sd2_cd: sd2-cd {
+                       samsung,pins = "gpc3-2";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <3>;
+               };
+
+               sd2_bus1: sd2-bus-width1 {
+                       samsung,pins = "gpc3-3";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <3>;
+               };
+
+               sd2_bus4: sd2-bus-width4 {
+                       samsung,pins = "gpc3-3", "gpc3-4", "gpc3-5", "gpc3-6";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <3>;
+               };
+
+               sd2_bus8: sd2-bus-width8 {
+                       samsung,pins = "gpc4-3", "gpc4-4", "gpc4-5", "gpc4-6";
+                       samsung,pin-function = <3>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <3>;
+               };
+
+               sd3_clk: sd3-clk {
+                       samsung,pins = "gpc4-0";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <3>;
+               };
+
+               sd3_cmd: sd3-cmd {
+                       samsung,pins = "gpc4-1";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <3>;
+               };
+
+               sd3_cd: sd3-cd {
+                       samsung,pins = "gpc4-2";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <3>;
+               };
+
+               sd3_bus1: sd3-bus-width1 {
+                       samsung,pins = "gpc4-3";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <3>;
+               };
+
+               sd3_bus4: sd3-bus-width4 {
+                       samsung,pins = "gpc4-3", "gpc4-4", "gpc4-5", "gpc4-6";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <3>;
+               };
+
+               uart1_data: uart1-data {
+                       samsung,pins = "gpd0-0", "gpd0-1";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <0>;
+               };
+
+               uart1_fctl: uart1-fctl {
+                       samsung,pins = "gpd0-2", "gpd0-3";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samaung,pin-drv = <0>;
+               };
+       };
+
+       pinctrl@13400000 {
+               gpe0: gpe0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpe1: gpe1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpf0: gpf0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpf1: gpf1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpg0: gpg0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpg1: gpg1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpg2: gpg2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gph0: gph0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gph1: gph1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               cam_gpio_a: cam-gpio-a {
+                       samsung,pins = "gpe0-0", "gpe0-1", "gpe0-2", "gpe0-3",
+                                      "gpe0-4", "gpe0-5", "gpe0-6", "gpe0-7",
+                                      "gpe1-0", "gpe1-1";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <0>;
+               };
+
+               cam_gpio_b: cam-gpio-b {
+                       samsung,pins = "gpf0-0", "gpf0-1", "gpf0-2", "gpf0-3",
+                                      "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
+                       samsung,pin-function = <3>;
+                       samsung,pin-pud = <0>;
+                       samaung,pin-drv = <0>;
+               };
+
+               cam_i2c2_bus: cam-i2c2-bus {
+                       samsung,pins = "gpe0-6", "gpe1-0";
+                       samsung,pin-function = <4>;
+                       samsung,pin-pud = <3>;
+                       samaung,pin-drv = <0>;
+               };
+
+               cam_spi1_bus: cam-spi1-bus {
+                       samsung,pins = "gpe0-4", "gpe0-5", "gpf0-2", "gpf0-3";
+                       samsung,pin-function = <4>;
+                       samsung,pin-pud = <0>;
+                       samaung,pin-drv = <0>;
+               };
+
+               cam_i2c1_bus: cam-i2c1-bus {
+                       samsung,pins = "gpf0-2", "gpf0-3";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <3>;
+                       samaung,pin-drv = <0>;
+               };
+
+               cam_i2c0_bus: cam-i2c0-bus {
+                       samsung,pins = "gpf0-0", "gpf0-1";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <3>;
+                       samaung,pin-drv = <0>;
+               };
+
+               cam_spi0_bus: cam-spi0-bus {
+                       samsung,pins = "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samaung,pin-drv = <0>;
+               };
+
+               cam_bayrgb_bus: cam-bayrgb-bus {
+                       samsung,pins = "gpg0-0", "gpg0-1", "gpg0-2", "gpg0-3",
+                                      "gpg0-4", "gpg0-5", "gpg0-6", "gpg0-7",
+                                      "gpg1-0", "gpg1-1", "gpg1-2", "gpg1-3",
+                                      "gpg1-4", "gpg1-5", "gpg1-6", "gpg1-7",
+                                      "gpg2-0", "gpg2-1";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samaung,pin-drv = <0>;
+               };
+
+               cam_port_a: cam-port-a {
+                       samsung,pins = "gph0-0", "gph0-1", "gph0-2", "gph0-3",
+                                      "gph1-0", "gph1-1", "gph1-2", "gph1-3",
+                                      "gph1-4", "gph1-5", "gph1-6", "gph1-7";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samaung,pin-drv = <0>;
+               };
+       };
+
+       pinctrl@10d10000 {
+               gpv0: gpv0 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpv1: gpv1 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpv2: gpv2 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpv3: gpv3 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               gpv4: gpv4 {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               c2c_rxd: c2c-rxd {
+                       samsung,pins = "gpv0-0", "gpv0-1", "gpv0-2", "gpv0-3",
+                                      "gpv0-4", "gpv0-5", "gpv0-6", "gpv0-7",
+                                      "gpv1-0", "gpv1-1", "gpv1-2", "gpv1-3",
+                                      "gpv1-4", "gpv1-5", "gpv1-6", "gpv1-7";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samaung,pin-drv = <0>;
+               };
+
+               c2c_txd: c2c-txd {
+                       samsung,pins = "gpv2-0", "gpv2-1", "gpv2-2", "gpv2-3",
+                                      "gpv2-4", "gpv2-5", "gpv2-6", "gpv2-7",
+                                      "gpv3-0", "gpv3-1", "gpv3-2", "gpv3-3",
+                                      "gpv3-4", "gpv3-5", "gpv3-6", "gpv3-7";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samaung,pin-drv = <0>;
+               };
+       };
+
+       pinctrl@03680000 {
+               gpz: gpz {
+                       gpio-controller;
+                       #gpio-cells = <2>;
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               i2s0_bus: i2s0-bus {
+                       samsung,pins = "gpz-0", "gpz-1", "gpz-2", "gpz-3",
+                                       "gpz-4", "gpz-5", "gpz-6";
+                       samsung,pin-function = <2>;
+                       samsung,pin-pud = <0>;
+                       samsung,pin-drv = <0>;
+               };
+       };
+};
index 1b8d4106d33859c5f8e61ce94fc6d1c1f543f829..26d856ba50a108cf3a1ba59d243a997028ecec69 100644 (file)
@@ -30,8 +30,6 @@
        i2c@12C60000 {
                samsung,i2c-sda-delay = <100>;
                samsung,i2c-max-bus-freq = <20000>;
-               gpios = <&gpb3 0 2 3 0>,
-                       <&gpb3 1 2 3 0>;
 
                eeprom@50 {
                        compatible = "samsung,s524ad0xd1";
@@ -42,8 +40,6 @@
        i2c@12C70000 {
                samsung,i2c-sda-delay = <100>;
                samsung,i2c-max-bus-freq = <20000>;
-               gpios = <&gpb3 2 2 3 0>,
-                       <&gpb3 3 2 3 0>;
 
                eeprom@51 {
                        compatible = "samsung,s524ad0xd1";
@@ -74,8 +70,6 @@
        i2c@12C80000 {
                samsung,i2c-sda-delay = <100>;
                samsung,i2c-max-bus-freq = <66000>;
-               gpios = <&gpa0 6 3 3 0>,
-                       <&gpa0 7 3 3 0>;
 
                hdmiddc@50 {
                        compatible = "samsung,exynos5-hdmiddc";
                samsung,dw-mshc-ciu-div = <3>;
                samsung,dw-mshc-sdr-timing = <2 3>;
                samsung,dw-mshc-ddr-timing = <1 2>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>;
 
                slot@0 {
                        reg = <0>;
                        bus-width = <8>;
-                       gpios = <&gpc0 0 2 0 3>, <&gpc0 1 2 0 3>,
-                               <&gpc1 0 2 3 3>, <&gpc1 1 2 3 3>,
-                               <&gpc1 2 2 3 3>, <&gpc1 3 2 3 3>,
-                               <&gpc0 3 2 3 3>, <&gpc0 4 2 3 3>,
-                               <&gpc0 5 2 3 3>, <&gpc0 6 2 3 3>;
                };
        };
 
                samsung,dw-mshc-ciu-div = <3>;
                samsung,dw-mshc-sdr-timing = <2 3>;
                samsung,dw-mshc-ddr-timing = <1 2>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>;
 
                slot@0 {
                        reg = <0>;
                        bus-width = <4>;
-                       samsung,cd-pinmux-gpio = <&gpc3 2 2 3 3>;
                        disable-wp;
-                       gpios = <&gpc3 0 2 0 3>, <&gpc3 1 2 0 3>,
-                               <&gpc3 3 2 3 3>, <&gpc3 4 2 3 3>,
-                               <&gpc3 5 2 3 3>, <&gpc3 6 2 3 3>,
-                               <&gpc4 3 3 3 3>, <&gpc4 3 3 3 3>,
-                               <&gpc4 5 3 3 3>, <&gpc4 6 3 3 3>;
                };
        };
 
        };
 
        spi_1: spi@12d30000 {
-               gpios = <&gpa2 4 2 3 0>,
-                       <&gpa2 6 2 3 0>,
-                       <&gpa2 7 2 3 0>;
-
                w25q80bw@0 {
                        #address-cells = <1>;
                        #size-cells = <1>;
                        spi-max-frequency = <1000000>;
 
                        controller-data {
-                               cs-gpio = <&gpa2 5 1 0 3>;
+                               cs-gpio = <&gpa2 5 0>;
                                samsung,spi-feedback-delay = <0>;
                        };
 
        };
 
        hdmi {
-               hpd-gpio = <&gpx3 7 0xf 1 3>;
+               hpd-gpio = <&gpx3 7 0>;
        };
 
        codec@11000000 {
        };
 
        i2s0: i2s@03830000 {
-               gpios = <&gpz 0 2 0 0>, <&gpz 1 2 0 0>, <&gpz 2 2 0 0>,
-                       <&gpz 3 2 0 0>, <&gpz 4 2 0 0>, <&gpz 5 2 0 0>,
-                       <&gpz 6 2 0 0>;
+               status = "okay";
        };
 
        i2s1: i2s@12D60000 {
                samsung,i2s-controller = <&i2s0>;
                samsung,audio-codec = <&wm8994>;
        };
+
+       usb@12110000 {
+               samsung,vbus-gpio = <&gpx2 6 1 3 3>;
+       };
+
+       dp-controller {
+               samsung,color-space = <0>;
+               samsung,dynamic-range = <0>;
+               samsung,ycbcr-coeff = <0>;
+               samsung,color-depth = <1>;
+               samsung,link-rate = <0x0a>;
+               samsung,lane-count = <4>;
+       };
+
+       display-timings {
+               native-mode = <&timing0>;
+               timing0: timing@0 {
+                       /* 1280x800 */
+                       clock-frequency = <50000>;
+                       hactive = <1280>;
+                       vactive = <800>;
+                       hfront-porch = <4>;
+                       hback-porch = <4>;
+                       hsync-len = <4>;
+                       vback-porch = <4>;
+                       vfront-porch = <4>;
+                       vsync-len = <4>;
+               };
+       };
+
+       fixed-rate-clocks {
+               xxti {
+                       compatible = "samsung,clock-xxti";
+                       clock-frequency = <24000000>;
+               };
+       };
 };
index 17dd951c1cd2a38787b76aacf09384a9a1bdfcb8..581ffae27e13826af6ba7d81346ea24c59f7e0df 100644 (file)
        model = "Google Snow";
        compatible = "google,snow", "samsung,exynos5250";
 
+       pinctrl@11400000 {
+               sd3_clk: sd3-clk {
+                       samsung,pin-drv = <0>;
+               };
+
+               sd3_cmd: sd3-cmd {
+                       samsung,pin-pud = <3>;
+                       samsung,pin-drv = <0>;
+               };
+
+               sd3_bus4: sd3-bus-width4 {
+                       samsung,pin-drv = <0>;
+               };
+       };
+
        gpio-keys {
                compatible = "gpio-keys";
 
                lid-switch {
                        label = "Lid";
-                       gpios = <&gpx3 5 0 0x10000 0>;
+                       gpios = <&gpx3 5 1>;
                        linux,input-type = <5>; /* EV_SW */
                        linux,code = <0>; /* SW_LID */
                        debounce-interval = <1>;
         */
        dwmmc3@12230000 {
                slot@0 {
-                       gpios = <&gpc4 0 2 0 0>, <&gpc4 1 2 3 0>,
-                               <&gpc4 3 2 3 0>, <&gpc4 4 2 3 0>,
-                               <&gpc4 5 2 3 0>, <&gpc4 6 2 3 0>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&sd3_clk &sd3_cmd &sd3_bus4>;
+               };
+       };
+
+       usb@12110000 {
+               samsung,vbus-gpio = <&gpx1 1 1 3 3>;
+       };
+
+       fixed-rate-clocks {
+               xxti {
+                       compatible = "samsung,clock-xxti";
+                       clock-frequency = <24000000>;
                };
        };
 };
index b1ac73e21c80da0de48e6e9d70a585c62c243706..af66e6b7bc77b58b2a68e95890e1dc3e6a70a67d 100644 (file)
@@ -18,6 +18,7 @@
 */
 
 /include/ "skeleton.dtsi"
+/include/ "exynos5250-pinctrl.dtsi"
 
 / {
        compatible = "samsung,exynos5250";
                i2c6 = &i2c_6;
                i2c7 = &i2c_7;
                i2c8 = &i2c_8;
+               pinctrl0 = &pinctrl_0;
+               pinctrl1 = &pinctrl_1;
+               pinctrl2 = &pinctrl_2;
+               pinctrl3 = &pinctrl_3;
+       };
+
+       pd_gsc: gsc-power-domain@0x10044000 {
+               compatible = "samsung,exynos4210-pd";
+               reg = <0x10044000 0x20>;
+       };
+
+       pd_mfc: mfc-power-domain@0x10044040 {
+               compatible = "samsung,exynos4210-pd";
+               reg = <0x10044040 0x20>;
+       };
+
+       clock: clock-controller@0x10010000 {
+               compatible = "samsung,exynos5250-clock";
+               reg = <0x10010000 0x30000>;
+               #clock-cells = <1>;
        };
 
        gic:interrupt-controller@10481000 {
-               compatible = "arm,cortex-a9-gic";
+               compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic";
                #interrupt-cells = <3>;
                interrupt-controller;
-               reg = <0x10481000 0x1000>, <0x10482000 0x2000>;
+               reg = <0x10481000 0x1000>,
+                     <0x10482000 0x1000>,
+                     <0x10484000 0x2000>,
+                     <0x10486000 0x2000>;
+               interrupts = <1 9 0xf04>;
+       };
+
+       timer {
+               compatible = "arm,armv7-timer";
+               interrupts = <1 13 0xf08>,
+                            <1 14 0xf08>,
+                            <1 11 0xf08>,
+                            <1 10 0xf08>;
        };
 
        combiner:interrupt-controller@10440000 {
                             <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
        };
 
+       mct@101C0000 {
+               compatible = "samsung,exynos4210-mct";
+               reg = <0x101C0000 0x800>;
+               interrupt-controller;
+               #interrups-cells = <2>;
+               interrupt-parent = <&mct_map>;
+               interrupts = <0 0>, <1 0>, <2 0>, <3 0>,
+                            <4 0>, <5 0>;
+               clocks = <&clock 1>, <&clock 335>;
+               clock-names = "fin_pll", "mct";
+
+               mct_map: mct-map {
+                       #interrupt-cells = <2>;
+                       #address-cells = <0>;
+                       #size-cells = <0>;
+                       interrupt-map = <0x0 0 &combiner 23 3>,
+                                       <0x1 0 &combiner 23 4>,
+                                       <0x2 0 &combiner 25 2>,
+                                       <0x3 0 &combiner 25 3>,
+                                       <0x4 0 &gic 0 120 0>,
+                                       <0x5 0 &gic 0 121 0>;
+               };
+       };
+
+       pinctrl_0: pinctrl@11400000 {
+               compatible = "samsung,exynos5250-pinctrl";
+               reg = <0x11400000 0x1000>;
+               interrupts = <0 46 0>;
+
+               wakup_eint: wakeup-interrupt-controller {
+                       compatible = "samsung,exynos4210-wakeup-eint";
+                       interrupt-parent = <&gic>;
+                       interrupts = <0 32 0>;
+               };
+       };
+
+       pinctrl_1: pinctrl@13400000 {
+               compatible = "samsung,exynos5250-pinctrl";
+               reg = <0x13400000 0x1000>;
+               interrupts = <0 45 0>;
+       };
+
+       pinctrl_2: pinctrl@10d10000 {
+               compatible = "samsung,exynos5250-pinctrl";
+               reg = <0x10d10000 0x1000>;
+               interrupts = <0 50 0>;
+       };
+
+       pinctrl_3: pinctrl@03680000 {
+               compatible = "samsung,exynos5250-pinctrl";
+               reg = <0x0368000 0x1000>;
+               interrupts = <0 47 0>;
+       };
+
        watchdog {
                compatible = "samsung,s3c2410-wdt";
                reg = <0x101D0000 0x100>;
                interrupts = <0 42 0>;
+               clocks = <&clock 336>;
+               clock-names = "watchdog";
        };
 
        codec@11000000 {
                compatible = "samsung,mfc-v6";
                reg = <0x11000000 0x10000>;
                interrupts = <0 96 0>;
+               samsung,power-domain = <&pd_mfc>;
        };
 
        rtc {
                compatible = "samsung,s3c6410-rtc";
                reg = <0x101E0000 0x100>;
                interrupts = <0 43 0>, <0 44 0>;
+               clocks = <&clock 337>;
+               clock-names = "rtc";
        };
 
        tmu@10060000 {
                compatible = "samsung,exynos5250-tmu";
                reg = <0x10060000 0x100>;
                interrupts = <0 65 0>;
+               clocks = <&clock 338>;
+               clock-names = "tmu_apbif";
        };
 
        serial@12C00000 {
                compatible = "samsung,exynos4210-uart";
                reg = <0x12C00000 0x100>;
                interrupts = <0 51 0>;
+               clocks = <&clock 289>, <&clock 146>;
+               clock-names = "uart", "clk_uart_baud0";
        };
 
        serial@12C10000 {
                compatible = "samsung,exynos4210-uart";
                reg = <0x12C10000 0x100>;
                interrupts = <0 52 0>;
+               clocks = <&clock 290>, <&clock 147>;
+               clock-names = "uart", "clk_uart_baud0";
        };
 
        serial@12C20000 {
                compatible = "samsung,exynos4210-uart";
                reg = <0x12C20000 0x100>;
                interrupts = <0 53 0>;
+               clocks = <&clock 291>, <&clock 148>;
+               clock-names = "uart", "clk_uart_baud0";
        };
 
        serial@12C30000 {
                compatible = "samsung,exynos4210-uart";
                reg = <0x12C30000 0x100>;
                interrupts = <0 54 0>;
+               clocks = <&clock 292>, <&clock 149>;
+               clock-names = "uart", "clk_uart_baud0";
        };
 
        sata@122F0000 {
                compatible = "samsung,exynos5-sata-ahci";
                reg = <0x122F0000 0x1ff>;
                interrupts = <0 115 0>;
+               clocks = <&clock 277>, <&clock 143>;
+               clock-names = "sata", "sclk_sata";
        };
 
        sata-phy@12170000 {
                interrupts = <0 56 0>;
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 294>;
+               clock-names = "i2c";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c0_bus>;
        };
 
        i2c_1: i2c@12C70000 {
                interrupts = <0 57 0>;
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 295>;
+               clock-names = "i2c";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c1_bus>;
        };
 
        i2c_2: i2c@12C80000 {
                interrupts = <0 58 0>;
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 296>;
+               clock-names = "i2c";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c2_bus>;
        };
 
        i2c_3: i2c@12C90000 {
                interrupts = <0 59 0>;
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 297>;
+               clock-names = "i2c";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c3_bus>;
        };
 
        i2c_4: i2c@12CA0000 {
                interrupts = <0 60 0>;
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 298>;
+               clock-names = "i2c";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c4_bus>;
        };
 
        i2c_5: i2c@12CB0000 {
                interrupts = <0 61 0>;
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 299>;
+               clock-names = "i2c";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c5_bus>;
        };
 
        i2c_6: i2c@12CC0000 {
                interrupts = <0 62 0>;
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 300>;
+               clock-names = "i2c";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c6_bus>;
        };
 
        i2c_7: i2c@12CD0000 {
                interrupts = <0 63 0>;
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 301>;
+               clock-names = "i2c";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c7_bus>;
        };
 
        i2c_8: i2c@12CE0000 {
                interrupts = <0 64 0>;
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 302>;
+               clock-names = "i2c";
        };
 
        i2c@121D0000 {
                 reg = <0x121D0000 0x100>;
                 #address-cells = <1>;
                 #size-cells = <0>;
+               clocks = <&clock 288>;
+               clock-names = "i2c";
        };
 
        spi_0: spi@12d20000 {
                dma-names = "tx", "rx";
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 304>, <&clock 154>;
+               clock-names = "spi", "spi_busclk0";
+               pinctrl-names = "default";
+               pinctrl-0 = <&spi0_bus>;
        };
 
        spi_1: spi@12d30000 {
                dma-names = "tx", "rx";
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 305>, <&clock 155>;
+               clock-names = "spi", "spi_busclk0";
+               pinctrl-names = "default";
+               pinctrl-0 = <&spi1_bus>;
        };
 
        spi_2: spi@12d40000 {
                dma-names = "tx", "rx";
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 306>, <&clock 156>;
+               clock-names = "spi", "spi_busclk0";
+               pinctrl-names = "default";
+               pinctrl-0 = <&spi2_bus>;
        };
 
        dwmmc_0: dwmmc0@12200000 {
                interrupts = <0 75 0>;
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 280>, <&clock 139>;
+               clock-names = "biu", "ciu";
        };
 
        dwmmc_1: dwmmc1@12210000 {
                interrupts = <0 76 0>;
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 281>, <&clock 140>;
+               clock-names = "biu", "ciu";
        };
 
        dwmmc_2: dwmmc2@12220000 {
                interrupts = <0 77 0>;
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 282>, <&clock 141>;
+               clock-names = "biu", "ciu";
        };
 
        dwmmc_3: dwmmc3@12230000 {
                interrupts = <0 78 0>;
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 283>, <&clock 142>;
+               clock-names = "biu", "ciu";
        };
 
        i2s0: i2s@03830000 {
                samsung,supports-rstclr;
                samsung,supports-secdai;
                samsung,idma-addr = <0x03000000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2s0_bus>;
        };
 
        i2s1: i2s@12D60000 {
                dmas = <&pdma1 12
                        &pdma1 11>;
                dma-names = "tx", "rx";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2s1_bus>;
        };
 
        i2s2: i2s@12D70000 {
                dmas = <&pdma0 12
                        &pdma0 11>;
                dma-names = "tx", "rx";
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2s2_bus>;
+       };
+
+       usb@12110000 {
+               compatible = "samsung,exynos4210-ehci";
+               reg = <0x12110000 0x100>;
+               interrupts = <0 71 0>;
+
+               clocks = <&clock 285>;
+               clock-names = "usbhost";
+       };
+
+       usb@12120000 {
+               compatible = "samsung,exynos4210-ohci";
+               reg = <0x12120000 0x100>;
+               interrupts = <0 71 0>;
+
+               clocks = <&clock 285>;
+               clock-names = "usbhost";
        };
 
        amba {
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x121A0000 0x1000>;
                        interrupts = <0 34 0>;
+                       clocks = <&clock 275>;
+                       clock-names = "apb_pclk";
                        #dma-cells = <1>;
                        #dma-channels = <8>;
                        #dma-requests = <32>;
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x121B0000 0x1000>;
                        interrupts = <0 35 0>;
+                       clocks = <&clock 276>;
+                       clock-names = "apb_pclk";
                        #dma-cells = <1>;
                        #dma-channels = <8>;
                        #dma-requests = <32>;
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x10800000 0x1000>;
                        interrupts = <0 33 0>;
+                       clocks = <&clock 271>;
+                       clock-names = "apb_pclk";
                        #dma-cells = <1>;
                        #dma-channels = <8>;
                        #dma-requests = <1>;
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x11C10000 0x1000>;
                        interrupts = <0 124 0>;
+                       clocks = <&clock 271>;
+                       clock-names = "apb_pclk";
                        #dma-cells = <1>;
                        #dma-channels = <8>;
                        #dma-requests = <1>;
                };
        };
 
-       gpio-controllers {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               gpio-controller;
-               ranges;
-
-               gpa0: gpio-controller@11400000 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x11400000 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpa1: gpio-controller@11400020 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x11400020 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpa2: gpio-controller@11400040 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x11400040 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpb0: gpio-controller@11400060 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x11400060 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpb1: gpio-controller@11400080 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x11400080 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpb2: gpio-controller@114000A0 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x114000A0 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpb3: gpio-controller@114000C0 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x114000C0 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpc0: gpio-controller@114000E0 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x114000E0 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpc1: gpio-controller@11400100 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x11400100 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpc2: gpio-controller@11400120 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x11400120 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpc3: gpio-controller@11400140 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x11400140 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpc4: gpio-controller@114002E0 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x114002E0 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpd0: gpio-controller@11400160 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x11400160 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpd1: gpio-controller@11400180 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x11400180 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpy0: gpio-controller@114001A0 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x114001A0 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpy1: gpio-controller@114001C0 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x114001C0 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpy2: gpio-controller@114001E0 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x114001E0 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpy3: gpio-controller@11400200 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x11400200 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpy4: gpio-controller@11400220 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x11400220 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpy5: gpio-controller@11400240 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x11400240 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpy6: gpio-controller@11400260 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x11400260 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpx0: gpio-controller@11400C00 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x11400C00 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpx1: gpio-controller@11400C20 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x11400C20 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpx2: gpio-controller@11400C40 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x11400C40 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpx3: gpio-controller@11400C60 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x11400C60 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpe0: gpio-controller@13400000 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x13400000 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpe1: gpio-controller@13400020 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x13400020 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpf0: gpio-controller@13400040 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x13400040 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpf1: gpio-controller@13400060 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x13400060 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpg0: gpio-controller@13400080 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x13400080 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpg1: gpio-controller@134000A0 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x134000A0 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpg2: gpio-controller@134000C0 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x134000C0 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gph0: gpio-controller@134000E0 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x134000E0 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gph1: gpio-controller@13400100 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x13400100 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpv0: gpio-controller@10D10000 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x10D10000 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpv1: gpio-controller@10D10020 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x10D10020 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpv2: gpio-controller@10D10040 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x10D10060 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpv3: gpio-controller@10D10060 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x10D10080 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpv4: gpio-controller@10D10080 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x10D100C0 0x20>;
-                       #gpio-cells = <4>;
-               };
-
-               gpz: gpio-controller@03860000 {
-                       compatible = "samsung,exynos4-gpio";
-                       reg = <0x03860000 0x20>;
-                       #gpio-cells = <4>;
-               };
-       };
-
        gsc_0:  gsc@0x13e00000 {
                compatible = "samsung,exynos5-gsc";
                reg = <0x13e00000 0x1000>;
                interrupts = <0 85 0>;
+               samsung,power-domain = <&pd_gsc>;
+               clocks = <&clock 256>;
+               clock-names = "gscl";
        };
 
        gsc_1:  gsc@0x13e10000 {
                compatible = "samsung,exynos5-gsc";
                reg = <0x13e10000 0x1000>;
                interrupts = <0 86 0>;
+               samsung,power-domain = <&pd_gsc>;
+               clocks = <&clock 257>;
+               clock-names = "gscl";
        };
 
        gsc_2:  gsc@0x13e20000 {
                compatible = "samsung,exynos5-gsc";
                reg = <0x13e20000 0x1000>;
                interrupts = <0 87 0>;
+               samsung,power-domain = <&pd_gsc>;
+               clocks = <&clock 258>;
+               clock-names = "gscl";
        };
 
        gsc_3:  gsc@0x13e30000 {
                compatible = "samsung,exynos5-gsc";
                reg = <0x13e30000 0x1000>;
                interrupts = <0 88 0>;
+               samsung,power-domain = <&pd_gsc>;
+               clocks = <&clock 259>;
+               clock-names = "gscl";
        };
 
        hdmi {
                compatible = "samsung,exynos5-hdmi";
                reg = <0x14530000 0x70000>;
                interrupts = <0 95 0>;
+               clocks = <&clock 333>, <&clock 136>, <&clock 137>,
+                               <&clock 333>, <&clock 333>;
+               clock-names = "hdmi", "sclk_hdmi", "sclk_pixel",
+                               "sclk_hdmiphy", "hdmiphy";
        };
 
        mixer {
                reg = <0x14450000 0x10000>;
                interrupts = <0 94 0>;
        };
+
+       dp-controller {
+               compatible = "samsung,exynos5-dp";
+               reg = <0x145b0000 0x1000>;
+               interrupts = <10 3>;
+               interrupt-parent = <&combiner>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               dptx-phy {
+                       reg = <0x10040720>;
+                       samsung,enable-mask = <1>;
+               };
+       };
+
+       fimd {
+               compatible = "samsung,exynos5250-fimd";
+               interrupt-parent = <&combiner>;
+               reg = <0x14400000 0x40000>;
+               interrupt-names = "fifo", "vsync", "lcd_sys";
+               interrupts = <18 4>, <18 5>, <18 6>;
+               clocks = <&clock 133>, <&clock 339>;
+               clock-names = "sclk_fimd", "fimd";
+       };
 };
diff --git a/arch/arm/boot/dts/exynos5440-sd5v1.dts b/arch/arm/boot/dts/exynos5440-sd5v1.dts
new file mode 100644 (file)
index 0000000..ef747b5
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * SAMSUNG SD5v1 board device tree source
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * 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.
+*/
+
+/dts-v1/;
+/include/ "exynos5440.dtsi"
+
+/ {
+       model = "SAMSUNG SD5v1 board based on EXYNOS5440";
+       compatible = "samsung,sd5v1", "samsung,exynos5440";
+
+       chosen {
+               bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel early_printk no_console_suspend mem=2048M@0x80000000 console=ttySAC0,115200";
+       };
+
+       fixed-rate-clocks {
+               xtal {
+                       compatible = "samsung,clock-xtal";
+                       clock-frequency = <50000000>;
+               };
+       };
+
+       gmac: ethernet@00230000 {
+               fixed_phy;
+               phy_addr = <1>;
+       };
+
+       spi {
+               status = "disabled";
+       };
+
+};
index 81e2c964a900f8a74d5efbac4aca73491bcc719a..d55042beb5c55f29739a5b8082a6bbed53e89d80 100644 (file)
        model = "SAMSUNG SSDK5440 board based on EXYNOS5440";
        compatible = "samsung,ssdk5440", "samsung,exynos5440";
 
-       memory {
-               reg = <0x80000000 0x80000000>;
-       };
-
        chosen {
-               bootargs = "root=/dev/ram0 rw ramdisk=8192 initrd=0x81000000,8M console=ttySAC0,115200 init=/linuxrc";
+               bootargs = "root=/dev/sda2 rw rootwait ignore_loglevel early_printk no_console_suspend mem=2048M@0x80000000 console=ttySAC0,115200";
        };
 
        spi {
                status = "disabled";
        };
 
-       i2c@F0000 {
-               status = "disabled";
-       };
-
-       i2c@100000 {
-               status = "disabled";
-       };
-
-       watchdog {
-               status = "disabled";
-       };
-
-       rtc {
-               status = "disabled";
+       fixed-rate-clocks {
+               xtal {
+                       compatible = "samsung,clock-xtal";
+                       clock-frequency = <50000000>;
+               };
        };
 };
index 9a99755920c04e52f58b29bb5ca684606d6d55e6..93e9028edaafc015ed9dcc88e7553c5f07d836e6 100644 (file)
 
        interrupt-parent = <&gic>;
 
+       clock: clock-controller@0x160000 {
+               compatible = "samsung,exynos5440-clock";
+               reg = <0x160000 0x1000>;
+               #clock-cells = <1>;
+       };
+
        gic:interrupt-controller@2E0000 {
                compatible = "arm,cortex-a15-gic";
                #interrupt-cells = <3>;
                interrupt-controller;
-               reg = <0x2E1000 0x1000>, <0x2E2000 0x1000>;
+               reg =   <0x2E1000 0x1000>,
+                       <0x2E2000 0x1000>,
+                       <0x2E4000 0x2000>,
+                       <0x2E6000 0x2000>;
+               interrupts = <1 9 0xf04>;
        };
 
        cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
                cpu@0 {
                        compatible = "arm,cortex-a15";
-                       timer {
-                               compatible = "arm,armv7-timer";
-                               interrupts = <1 13 0xf08>;
-                               clock-frequency = <1000000>;
-                       };
+                       reg = <0>;
                };
                cpu@1 {
                        compatible = "arm,cortex-a15";
-                       timer {
-                               compatible = "arm,armv7-timer";
-                               interrupts = <1 14 0xf08>;
-                               clock-frequency = <1000000>;
-                       };
+                       reg = <1>;
                };
                cpu@2 {
                        compatible = "arm,cortex-a15";
-                       timer {
-                               compatible = "arm,armv7-timer";
-                               interrupts = <1 14 0xf08>;
-                               clock-frequency = <1000000>;
-                       };
+                       reg = <2>;
                };
                cpu@3 {
                        compatible = "arm,cortex-a15";
-                       timer {
-                               compatible = "arm,armv7-timer";
-                               interrupts = <1 14 0xf08>;
-                               clock-frequency = <1000000>;
-                       };
+                       reg = <3>;
                };
        };
 
-       common {
-               compatible = "samsung,exynos5440";
+       arm-pmu {
+               compatible = "arm,cortex-a15-pmu", "arm,cortex-a9-pmu";
+               interrupts = <0 52 4>,
+                            <0 53 4>,
+                            <0 54 4>,
+                            <0 55 4>;
+       };
+
+       timer {
+               compatible = "arm,cortex-a15-timer",
+                            "arm,armv7-timer";
+               interrupts = <1 13 0xf08>,
+                            <1 14 0xf08>,
+                            <1 11 0xf08>,
+                            <1 10 0xf08>;
+               clock-frequency = <50000000>;
+       };
 
+       cpufreq@160000 {
+               compatible = "samsung,exynos5440-cpufreq";
+               reg = <0x160000 0x1000>;
+               interrupts = <0 57 0>;
+               operating-points = <
+                               /* KHz    uV */
+                               1200000 1025000
+                               1000000 975000
+                               800000  925000
+               >;
        };
 
        serial@B0000 {
                compatible = "samsung,exynos4210-uart";
                reg = <0xB0000 0x1000>;
                interrupts = <0 2 0>;
+               clocks = <&clock 21>, <&clock 21>;
+               clock-names = "uart", "clk_uart_baud0";
        };
 
        serial@C0000 {
                compatible = "samsung,exynos4210-uart";
                reg = <0xC0000 0x1000>;
                interrupts = <0 3 0>;
+               clocks = <&clock 21>, <&clock 21>;
+               clock-names = "uart", "clk_uart_baud0";
        };
 
        spi {
                rx-dma-channel = <&pdma0 4>; /* preliminary */
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 21>, <&clock 16>;
+               clock-names = "spi", "spi_busclk0";
        };
 
        pinctrl {
                compatible = "samsung,exynos5440-pinctrl";
                reg = <0xE0000 0x1000>;
+               interrupts = <0 37 0>, <0 38 0>, <0 39 0>, <0 40 0>,
+                            <0 41 0>, <0 42 0>, <0 43 0>, <0 44 0>;
                interrupt-controller;
                #interrupt-cells = <2>;
                #gpio-cells = <2>;
        };
 
        i2c@F0000 {
-               compatible = "samsung,s3c2440-i2c";
+               compatible = "samsung,exynos5440-i2c";
                reg = <0xF0000 0x1000>;
                interrupts = <0 5 0>;
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 21>;
+               clock-names = "i2c";
        };
 
        i2c@100000 {
-               compatible = "samsung,s3c2440-i2c";
+               compatible = "samsung,exynos5440-i2c";
                reg = <0x100000 0x1000>;
                interrupts = <0 6 0>;
                #address-cells = <1>;
                #size-cells = <0>;
+               clocks = <&clock 21>;
+               clock-names = "i2c";
        };
 
        watchdog {
                compatible = "samsung,s3c2410-wdt";
                reg = <0x110000 0x1000>;
                interrupts = <0 1 0>;
+               clocks = <&clock 21>;
+               clock-names = "watchdog";
+       };
+
+       gmac: ethernet@00230000 {
+               compatible = "snps,dwmac-3.70a";
+               reg = <0x00230000 0x8000>;
+               interrupt-parent = <&gic>;
+               interrupts = <0 31 4>;
+               interrupt-names = "macirq";
+               phy-mode = "sgmii";
+               clocks = <&clock 25>;
+               clock-names = "stmmaceth";
        };
 
        amba {
                interrupt-parent = <&gic>;
                ranges;
 
-               pdma0: pdma@121A0000 {
+               pdma0: pdma@00121000 {
                        compatible = "arm,pl330", "arm,primecell";
-                       reg = <0x120000 0x1000>;
-                       interrupts = <0 34 0>;
+                       reg = <0x121000 0x1000>;
+                       interrupts = <0 46 0>;
+                       clocks = <&clock 8>;
+                       clock-names = "apb_pclk";
                        #dma-cells = <1>;
                        #dma-channels = <8>;
                        #dma-requests = <32>;
                };
 
-               pdma1: pdma@121B0000 {
+               pdma1: pdma@00120000 {
                        compatible = "arm,pl330", "arm,primecell";
-                       reg = <0x121000 0x1000>;
-                       interrupts = <0 35 0>;
+                       reg = <0x120000 0x1000>;
+                       interrupts = <0 47 0>;
+                       clocks = <&clock 8>;
+                       clock-names = "apb_pclk";
                        #dma-cells = <1>;
                        #dma-channels = <8>;
                        #dma-requests = <32>;
                compatible = "samsung,s3c6410-rtc";
                reg = <0x130000 0x1000>;
                interrupts = <0 17 0>, <0 16 0>;
+               clocks = <&clock 21>;
+               clock-names = "rtc";
        };
 };
index 035c13f9d3c05b3410dfb13ae7c50325712e550e..da0588a041317f91c20a384c8cce6794b0d1d4df 100644 (file)
                        lcdif@80030000 {
                                pinctrl-names = "default";
                                pinctrl-0 = <&lcdif_24bit_pins_a>;
-                               panel-enable-gpios = <&gpio1 18 0>;
+                               lcd-supply = <&reg_lcd_3v3>;
+                               display = <&display>;
                                status = "okay";
+
+                               display: display {
+                                       bits-per-pixel = <32>;
+                                       bus-width = <24>;
+
+                                       display-timings {
+                                               native-mode = <&timing0>;
+                                               timing0: timing0 {
+                                                       clock-frequency = <9200000>;
+                                                       hactive = <480>;
+                                                       vactive = <272>;
+                                                       hback-porch = <15>;
+                                                       hfront-porch = <8>;
+                                                       vback-porch = <12>;
+                                                       vfront-porch = <4>;
+                                                       hsync-len = <1>;
+                                                       vsync-len = <1>;
+                                                       hsync-active = <0>;
+                                                       vsync-active = <0>;
+                                                       de-active = <1>;
+                                                       pixelclk-active = <0>;
+                                               };
+                                       };
+                               };
                        };
                };
 
                        regulator-max-microvolt = <3300000>;
                        gpio = <&gpio1 29 0>;
                };
+
+               reg_lcd_3v3: lcd-3v3 {
+                       compatible = "regulator-fixed";
+                       regulator-name = "lcd-3v3";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       gpio = <&gpio1 18 0>;
+                       enable-active-high;
+               };
        };
 
        backlight {
index e7484e4ea659ca261149476a6e7fc6c07dd85690..d107c4af321ff374807ba7a1486d54816be708a0 100644 (file)
@@ -29,6 +29,7 @@
                                pinctrl-names = "default";
                                pinctrl-0 = <&mmc0_4bit_pins_a &mmc0_pins_fixup>;
                                bus-width = <4>;
+                               broken-cd;
                                status = "okay";
                        };
 
index 56afcf41aae0d6bb8373ae9ed419c65294460897..73fd7d0887b52f4505d908902fd99aaf0fe941c8 100644 (file)
                                reg = <0x80000000 0x2000>;
                        };
 
-                       dma-apbh@80004000 {
+                       dma_apbh: dma-apbh@80004000 {
                                compatible = "fsl,imx23-dma-apbh";
                                reg = <0x80004000 0x2000>;
+                               interrupts = <0 14 20 0
+                                             13 13 13 13>;
+                               interrupt-names = "empty", "ssp0", "ssp1", "empty",
+                                                 "gpmi0", "gpmi1", "gpmi2", "gpmi3";
+                               #dma-cells = <1>;
+                               dma-channels = <8>;
                                clocks = <&clks 15>;
                        };
 
@@ -70,6 +76,8 @@
                                interrupt-names = "gpmi-dma", "bch";
                                clocks = <&clks 34>;
                                clock-names = "gpmi_io";
+                               dmas = <&dma_apbh 4>;
+                               dma-names = "rx-tx";
                                fsl,gpmi-dma-channel = <4>;
                                status = "disabled";
                        };
@@ -78,6 +86,8 @@
                                reg = <0x80010000 0x2000>;
                                interrupts = <15 14>;
                                clocks = <&clks 33>;
+                               dmas = <&dma_apbh 1>;
+                               dma-names = "rx-tx";
                                fsl,ssp-dma-channel = <1>;
                                status = "disabled";
                        };
                        };
 
                        digctl@8001c000 {
+                               compatible = "fsl,imx23-digctl";
                                reg = <0x8001c000 2000>;
                                status = "disabled";
                        };
                                status = "disabled";
                        };
 
-                       dma-apbx@80024000 {
+                       dma_apbx: dma-apbx@80024000 {
                                compatible = "fsl,imx23-dma-apbx";
                                reg = <0x80024000 0x2000>;
+                               interrupts = <7 5 9 26
+                                             19 0 25 23
+                                             60 58 9 0
+                                             0 0 0 0>;
+                               interrupt-names = "audio-adc", "audio-dac", "spdif-tx", "i2c",
+                                                 "saif0", "empty", "auart0-rx", "auart0-tx",
+                                                 "auart1-rx", "auart1-tx", "saif1", "empty",
+                                                 "empty", "empty", "empty", "empty";
+                               #dma-cells = <1>;
+                               dma-channels = <16>;
                                clocks = <&clks 16>;
                        };
 
                        };
 
                        ocotp@8002c000 {
+                               compatible = "fsl,ocotp";
                                reg = <0x8002c000 0x2000>;
                                status = "disabled";
                        };
                                reg = <0x80034000 0x2000>;
                                interrupts = <2 20>;
                                clocks = <&clks 33>;
+                               dmas = <&dma_apbh 2>;
+                               dma-names = "rx-tx";
                                fsl,ssp-dma-channel = <2>;
                                status = "disabled";
                        };
                        ranges;
 
                        clks: clkctrl@80040000 {
-                               compatible = "fsl,imx23-clkctrl";
+                               compatible = "fsl,imx23-clkctrl", "fsl,clkctrl";
                                reg = <0x80040000 0x2000>;
                                #clock-cells = <1>;
                        };
 
                        saif0: saif@80042000 {
                                reg = <0x80042000 0x2000>;
+                               dmas = <&dma_apbx 4>;
+                               dma-names = "rx-tx";
                                status = "disabled";
                        };
 
 
                        saif1: saif@80046000 {
                                reg = <0x80046000 0x2000>;
+                               dmas = <&dma_apbx 10>;
+                               dma-names = "rx-tx";
                                status = "disabled";
                        };
 
                        audio-out@80048000 {
                                reg = <0x80048000 0x2000>;
+                               dmas = <&dma_apbx 1>;
+                               dma-names = "tx";
                                status = "disabled";
                        };
 
                        audio-in@8004c000 {
                                reg = <0x8004c000 0x2000>;
+                               dmas = <&dma_apbx 0>;
+                               dma-names = "rx";
                                status = "disabled";
                        };
 
 
                        spdif@80054000 {
                                reg = <0x80054000 2000>;
+                               dmas = <&dma_apbx 2>;
+                               dma-names = "tx";
                                status = "disabled";
                        };
 
                        i2c@80058000 {
                                reg = <0x80058000 0x2000>;
+                               dmas = <&dma_apbx 3>;
+                               dma-names = "rx-tx";
                                status = "disabled";
                        };
 
                                compatible = "fsl,imx23-timrot", "fsl,timrot";
                                reg = <0x80068000 0x2000>;
                                interrupts = <28 29 30 31>;
+                               clocks = <&clks 28>;
                        };
 
                        auart0: serial@8006c000 {
                                reg = <0x8006c000 0x2000>;
                                interrupts = <24 25 23>;
                                clocks = <&clks 32>;
+                               dmas = <&dma_apbx 6>, <&dma_apbx 7>;
+                               dma-names = "rx", "tx";
                                status = "disabled";
                        };
 
                                reg = <0x8006e000 0x2000>;
                                interrupts = <59 60 58>;
                                clocks = <&clks 32>;
+                               dmas = <&dma_apbx 8>, <&dma_apbx 9>;
+                               dma-names = "rx", "tx";
                                status = "disabled";
                        };
 
index 6d8865bfb4b7cee90b12910d98f46a1e6acda564..3d905d16cbec6f3d3a87f62b6e597b7fe7f67705 100644 (file)
                                pinctrl-names = "default";
                                pinctrl-0 = <&lcdif_16bit_pins_a
                                                &lcdif_pins_apf28dev>;
+                               display = <&display>;
                                status = "okay";
+
+                               display: display {
+                                       bits-per-pixel = <16>;
+                                       bus-width = <16>;
+
+                                       display-timings {
+                                               native-mode = <&timing0>;
+                                               timing0: timing0 {
+                                                       clock-frequency = <33000033>;
+                                                       hactive = <800>;
+                                                       vactive = <480>;
+                                                       hback-porch = <96>;
+                                                       hfront-porch = <96>;
+                                                       vback-porch = <20>;
+                                                       vfront-porch = <21>;
+                                                       hsync-len = <64>;
+                                                       vsync-len = <4>;
+                                                       hsync-active = <1>;
+                                                       vsync-active = <1>;
+                                                       de-active = <1>;
+                                                       pixelclk-active = <0>;
+                                               };
+                                       };
+                               };
                        };
                };
 
index 5171667a7763f47cc967efdf7481e0eb73e4090c..43bf3c796cba9cfef5d45032ebcf05b6807dcd4c 100644 (file)
                                pinctrl-names = "default";
                                pinctrl-0 = <&lcdif_24bit_pins_a
                                             &lcdif_pins_apx4>;
+                               display = <&display>;
                                status = "okay";
+
+                               display: display {
+                                       bits-per-pixel = <32>;
+                                       bus-width = <24>;
+
+                                       display-timings {
+                                               native-mode = <&timing0>;
+                                               timing0: timing0 {
+                                                       clock-frequency = <30000000>;
+                                                       hactive = <800>;
+                                                       vactive = <480>;
+                                                       hback-porch = <88>;
+                                                       hfront-porch = <40>;
+                                                       vback-porch = <32>;
+                                                       vfront-porch = <13>;
+                                                       hsync-len = <48>;
+                                                       vsync-len = <3>;
+                                                       hsync-active = <1>;
+                                                       vsync-active = <1>;
+                                                       de-active = <1>;
+                                                       pixelclk-active = <0>;
+                                               };
+                                       };
+                               };
                        };
                };
 
index a0d3e9f1738e097326594f2291283b15ebf1897d..063e62059890e4f07885e66f02327dd58123ed6c 100644 (file)
@@ -30,7 +30,6 @@
                                        reg = <0>;
                                        fsl,pinmux-ids = <
                                                0x0073 /* MX28_PAD_GPMI_D7__GPIO_0_7 */
-                                               0x1153 /* MX28_PAD_LCD_D22__GPIO_1_21 */
                                                0x1163 /* MX28_PAD_LCD_D22__GPIO_1_22 */
                                                0x1173 /* MX28_PAD_LCD_D22__GPIO_1_23 */
                                                0x2153 /* MX28_PAD_SSP2_D5__GPIO_2_21 */
                                        fsl,voltage = <1>;
                                        fsl,pull-up = <0>;
                                };
+
+                               w1_gpio_pins: w1-gpio@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x1153 /* MX28_PAD_LCD_D21__GPIO_1_21 */
+                                       >;
+                                       fsl,drive-strength = <1>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>; /* 0 will enable the keeper */
+                               };
                        };
 
                        lcdif@80030000 {
                                pinctrl-names = "default";
                                pinctrl-0 = <&lcdif_18bit_pins_cfa10049
                                             &lcdif_pins_cfa10049>;
+                               display = <&display>;
                                status = "okay";
+
+                               display: display {
+                                       bits-per-pixel = <32>;
+                                       bus-width = <18>;
+
+                                       display-timings {
+                                               native-mode = <&timing0>;
+                                               timing0: timing0 {
+                                                       clock-frequency = <9216000>;
+                                                       hactive = <320>;
+                                                       vactive = <480>;
+                                                       hback-porch = <2>;
+                                                       hfront-porch = <2>;
+                                                       vback-porch = <2>;
+                                                       vfront-porch = <2>;
+                                                       hsync-len = <15>;
+                                                       vsync-len = <15>;
+                                                       hsync-active = <0>;
+                                                       vsync-active = <0>;
+                                                       de-active = <1>;
+                                                       pixelclk-active = <1>;
+                                               };
+                                       };
+                               };
                        };
                };
 
                        usbphy1: usbphy@8007e000 {
                                status = "okay";
                        };
+
+                       lradc@80050000 {
+                               status = "okay";
+                               fsl,lradc-touchscreen-wires = <4>;
+                       };
                };
        };
 
                pwms = <&pwm 3 5000000>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                default-brightness-level = <6>;
+
+       };
+
+       onewire@0 {
+               compatible = "w1-gpio";
+               pinctrl-names = "default";
+               pinctrl-0 = <&w1_gpio_pins>;
+               status = "okay";
+               gpios = <&gpio1 21 0>;
        };
 };
index 2da316e04409f103c44fcf4ff35fe5dc48a93924..3637bf3b1d597c6690bd34c5f7e4b8109104043d 100644 (file)
                                pinctrl-names = "default";
                                pinctrl-0 = <&lcdif_24bit_pins_a
                                             &lcdif_pins_evk>;
-                               panel-enable-gpios = <&gpio3 30 0>;
+                               lcd-supply = <&reg_lcd_3v3>;
+                               display = <&display>;
                                status = "okay";
+
+                               display: display {
+                                       bits-per-pixel = <32>;
+                                       bus-width = <24>;
+
+                                       display-timings {
+                                               native-mode = <&timing0>;
+                                               timing0: timing0 {
+                                                       clock-frequency = <33500000>;
+                                                       hactive = <800>;
+                                                       vactive = <480>;
+                                                       hback-porch = <89>;
+                                                       hfront-porch = <164>;
+                                                       vback-porch = <23>;
+                                                       vfront-porch = <10>;
+                                                       hsync-len = <10>;
+                                                       vsync-len = <10>;
+                                                       hsync-active = <0>;
+                                                       vsync-active = <0>;
+                                                       de-active = <1>;
+                                                       pixelclk-active = <0>;
+                                               };
+                                       };
+                               };
                        };
 
                        can0: can@80032000 {
                        gpio = <&gpio3 8 0>;
                        enable-active-high;
                };
+
+               reg_lcd_3v3: lcd-3v3 {
+                       compatible = "regulator-fixed";
+                       regulator-name = "lcd-3v3";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       gpio = <&gpio3 30 0>;
+                       enable-active-high;
+               };
        };
 
        sound {
index 6ce3d17c3a29c19c80ef6a04484fd59ec5e8765a..5f0ba99aa809d4c8309c80520bd7aa2be67e164e 100644 (file)
                                pinctrl-names = "default";
                                pinctrl-0 = <&lcdif_24bit_pins_a
                                             &lcdif_pins_m28>;
+                               display = <&display>;
                                status = "okay";
+
+                               display: display {
+                                       bits-per-pixel = <16>;
+                                       bus-width = <18>;
+
+                                       display-timings {
+                                               native-mode = <&timing0>;
+                                               timing0: timing0 {
+                                                       clock-frequency = <33260000>;
+                                                       hactive = <800>;
+                                                       vactive = <480>;
+                                                       hback-porch = <0>;
+                                                       hfront-porch = <256>;
+                                                       vback-porch = <0>;
+                                                       vfront-porch = <45>;
+                                                       hsync-len = <1>;
+                                                       vsync-len = <1>;
+                                                       hsync-active = <0>;
+                                                       vsync-active = <0>;
+                                                       de-active = <1>;
+                                                       pixelclk-active = <1>;
+                                               };
+                                       };
+                               };
                        };
 
                        can0: can@80032000 {
                        phy-mode = "rmii";
                        pinctrl-names = "default";
                        pinctrl-0 = <&mac0_pins_a>;
+                       clocks = <&clks 57>, <&clks 57>;
+                       clock-names = "ipg", "ahb";
                        status = "okay";
                };
 
index 7ba49662b9bcde0fae3e1651b7795f1bd05dd83e..600f7cb51f3e58ae78f88649f3b52b12c170e5d1 100644 (file)
                        hsadc@80002000 {
                                reg = <0x80002000 0x2000>;
                                interrupts = <13 87>;
+                               dmas = <&dma_apbh 12>;
+                               dma-names = "rx";
                                status = "disabled";
                        };
 
-                       dma-apbh@80004000 {
+                       dma_apbh: dma-apbh@80004000 {
                                compatible = "fsl,imx28-dma-apbh";
                                reg = <0x80004000 0x2000>;
+                               interrupts = <82 83 84 85
+                                             88 88 88 88
+                                             88 88 88 88
+                                             87 86 0 0>;
+                               interrupt-names = "ssp0", "ssp1", "ssp2", "ssp3",
+                                                 "gpmi0", "gmpi1", "gpmi2", "gmpi3",
+                                                 "gpmi4", "gmpi5", "gpmi6", "gmpi7",
+                                                 "hsadc", "lcdif", "empty", "empty";
+                               #dma-cells = <1>;
+                               dma-channels = <16>;
                                clocks = <&clks 25>;
                        };
 
@@ -86,6 +98,8 @@
                                interrupt-names = "gpmi-dma", "bch";
                                clocks = <&clks 50>;
                                clock-names = "gpmi_io";
+                               dmas = <&dma_apbh 4>;
+                               dma-names = "rx-tx";
                                fsl,gpmi-dma-channel = <4>;
                                status = "disabled";
                        };
                                reg = <0x80010000 0x2000>;
                                interrupts = <96 82>;
                                clocks = <&clks 46>;
+                               dmas = <&dma_apbh 0>;
+                               dma-names = "rx-tx";
                                fsl,ssp-dma-channel = <0>;
                                status = "disabled";
                        };
                                reg = <0x80012000 0x2000>;
                                interrupts = <97 83>;
                                clocks = <&clks 47>;
+                               dmas = <&dma_apbh 1>;
+                               dma-names = "rx-tx";
                                fsl,ssp-dma-channel = <1>;
                                status = "disabled";
                        };
                                reg = <0x80014000 0x2000>;
                                interrupts = <98 84>;
                                clocks = <&clks 48>;
+                               dmas = <&dma_apbh 2>;
+                               dma-names = "rx-tx";
                                fsl,ssp-dma-channel = <2>;
                                status = "disabled";
                        };
                                reg = <0x80016000 0x2000>;
                                interrupts = <99 85>;
                                clocks = <&clks 49>;
+                               dmas = <&dma_apbh 3>;
+                               dma-names = "rx-tx";
                                fsl,ssp-dma-channel = <3>;
                                status = "disabled";
                        };
                        };
 
                        digctl@8001c000 {
+                               compatible = "fsl,imx28-digctl";
                                reg = <0x8001c000 0x2000>;
                                interrupts = <89>;
                                status = "disabled";
                                status = "disabled";
                        };
 
-                       dma-apbx@80024000 {
+                       dma_apbx: dma-apbx@80024000 {
                                compatible = "fsl,imx28-dma-apbx";
                                reg = <0x80024000 0x2000>;
+                               interrupts = <78 79 66 0
+                                             80 81 68 69
+                                             70 71 72 73
+                                             74 75 76 77>;
+                               interrupt-names = "auart4-rx", "aurat4-tx", "spdif-tx", "empty",
+                                                 "saif0", "saif1", "i2c0", "i2c1",
+                                                 "auart0-rx", "auart0-tx", "auart1-rx", "auart1-tx",
+                                                 "auart2-rx", "auart2-tx", "auart3-rx", "auart3-tx";
+                               #dma-cells = <1>;
+                               dma-channels = <16>;
                                clocks = <&clks 26>;
                        };
 
                        };
 
                        ocotp@8002c000 {
+                               compatible = "fsl,ocotp";
                                reg = <0x8002c000 0x2000>;
                                status = "disabled";
                        };
                                reg = <0x80030000 0x2000>;
                                interrupts = <38 86>;
                                clocks = <&clks 55>;
+                               dmas = <&dma_apbh 13>;
+                               dma-names = "rx";
                                status = "disabled";
                        };
 
                        ranges;
 
                        clks: clkctrl@80040000 {
-                               compatible = "fsl,imx28-clkctrl";
+                               compatible = "fsl,imx28-clkctrl", "fsl,clkctrl";
                                reg = <0x80040000 0x2000>;
                                #clock-cells = <1>;
                        };
                                reg = <0x80042000 0x2000>;
                                interrupts = <59 80>;
                                clocks = <&clks 53>;
+                               dmas = <&dma_apbx 4>;
+                               dma-names = "rx-tx";
                                fsl,saif-dma-channel = <4>;
                                status = "disabled";
                        };
                                reg = <0x80046000 0x2000>;
                                interrupts = <58 81>;
                                clocks = <&clks 54>;
+                               dmas = <&dma_apbx 5>;
+                               dma-names = "rx-tx";
                                fsl,saif-dma-channel = <5>;
                                status = "disabled";
                        };
                        spdif@80054000 {
                                reg = <0x80054000 0x2000>;
                                interrupts = <45 66>;
+                               dmas = <&dma_apbx 2>;
+                               dma-names = "tx";
                                status = "disabled";
                        };
 
                                reg = <0x80058000 0x2000>;
                                interrupts = <111 68>;
                                clock-frequency = <100000>;
+                               dmas = <&dma_apbx 6>;
+                               dma-names = "rx-tx";
                                fsl,i2c-dma-channel = <6>;
                                status = "disabled";
                        };
                                reg = <0x8005a000 0x2000>;
                                interrupts = <110 69>;
                                clock-frequency = <100000>;
+                               dmas = <&dma_apbx 7>;
+                               dma-names = "rx-tx";
                                fsl,i2c-dma-channel = <7>;
                                status = "disabled";
                        };
                                compatible = "fsl,imx28-timrot", "fsl,timrot";
                                reg = <0x80068000 0x2000>;
                                interrupts = <48 49 50 51>;
+                               clocks = <&clks 26>;
                        };
 
                        auart0: serial@8006a000 {
                                compatible = "fsl,imx28-auart", "fsl,imx23-auart";
                                reg = <0x8006a000 0x2000>;
                                interrupts = <112 70 71>;
+                               dmas = <&dma_apbx 8>, <&dma_apbx 9>;
+                               dma-names = "rx", "tx";
                                fsl,auart-dma-channel = <8 9>;
                                clocks = <&clks 45>;
                                status = "disabled";
                                compatible = "fsl,imx28-auart", "fsl,imx23-auart";
                                reg = <0x8006c000 0x2000>;
                                interrupts = <113 72 73>;
+                               dmas = <&dma_apbx 10>, <&dma_apbx 11>;
+                               dma-names = "rx", "tx";
                                clocks = <&clks 45>;
                                status = "disabled";
                        };
                                compatible = "fsl,imx28-auart", "fsl,imx23-auart";
                                reg = <0x8006e000 0x2000>;
                                interrupts = <114 74 75>;
+                               dmas = <&dma_apbx 12>, <&dma_apbx 13>;
+                               dma-names = "rx", "tx";
                                clocks = <&clks 45>;
                                status = "disabled";
                        };
                                compatible = "fsl,imx28-auart", "fsl,imx23-auart";
                                reg = <0x80070000 0x2000>;
                                interrupts = <115 76 77>;
+                               dmas = <&dma_apbx 14>, <&dma_apbx 15>;
+                               dma-names = "rx", "tx";
                                clocks = <&clks 45>;
                                status = "disabled";
                        };
                                compatible = "fsl,imx28-auart", "fsl,imx23-auart";
                                reg = <0x80072000 0x2000>;
                                interrupts = <116 78 79>;
+                               dmas = <&dma_apbx 0>, <&dma_apbx 1>;
+                               dma-names = "rx", "tx";
                                clocks = <&clks 45>;
                                status = "disabled";
                        };
                        compatible = "fsl,imx28-fec";
                        reg = <0x800f0000 0x4000>;
                        interrupts = <101>;
-                       clocks = <&clks 57>, <&clks 57>;
-                       clock-names = "ipg", "ahb";
+                       clocks = <&clks 57>, <&clks 57>, <&clks 64>;
+                       clock-names = "ipg", "ahb", "enet_out";
                        status = "disabled";
                };
 
index 06ec460b4581c4163e4053953e84acfaad01a76b..59e970f74e8f44afd5af5bdc72407b0e992354ec 100644 (file)
                interrupt-parent = <&intc>;
                ranges;
 
-               dma-apbh@00110000 {
+               dma_apbh: dma-apbh@00110000 {
                        compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh";
                        reg = <0x00110000 0x2000>;
+                       interrupts = <0 13 0x04>, <0 13 0x04>, <0 13 0x04>, <0 13 0x04>;
+                       interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3";
+                       #dma-cells = <1>;
+                       dma-channels = <4>;
                        clocks = <&clks 106>;
                };
 
@@ -83,6 +87,8 @@
                                 <&clks 150>, <&clks 149>;
                        clock-names = "gpmi_io", "gpmi_apb", "gpmi_bch",
                                      "gpmi_bch_apb", "per1_bch";
+                       dmas = <&dma_apbh 0>;
+                       dma-names = "rx-tx";
                        fsl,gpmi-dma-channel = <0>;
                        status = "disabled";
                };
index 761c4b69b25b2c3a661322a96ee5c7f41c839c70..37aa7487d4d86791be2ad6f51065708f31fcaa80 100644 (file)
                };
        };
 
+       pmu {
+               compatible = "arm,arm1136-pmu";
+               interrupts = <3>;
+       };
+
        soc {
                compatible = "ti,omap-infra";
                mpu {
                        reg = <0x480FE000 0x1000>;
                };
 
+               sdma: dma-controller@48056000 {
+                       compatible = "ti,omap2430-sdma", "ti,omap2420-sdma";
+                       reg = <0x48056000 0x1000>;
+                       interrupts = <12>,
+                                    <13>,
+                                    <14>,
+                                    <15>;
+                       #dma-cells = <1>;
+                       #dma-channels = <32>;
+                       #dma-requests = <64>;
+               };
+
                uart1: serial@4806a000 {
                        compatible = "ti,omap2-uart";
                        ti,hwmods = "uart1";
                };
 
                timer2: timer@4802a000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap2420-timer";
                        reg = <0x4802a000 0x400>;
                        interrupts = <38>;
                        ti,hwmods = "timer2";
                };
 
                timer3: timer@48078000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap2420-timer";
                        reg = <0x48078000 0x400>;
                        interrupts = <39>;
                        ti,hwmods = "timer3";
                };
 
                timer4: timer@4807a000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap2420-timer";
                        reg = <0x4807a000 0x400>;
                        interrupts = <40>;
                        ti,hwmods = "timer4";
                };
 
                timer5: timer@4807c000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap2420-timer";
                        reg = <0x4807c000 0x400>;
                        interrupts = <41>;
                        ti,hwmods = "timer5";
                };
 
                timer6: timer@4807e000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap2420-timer";
                        reg = <0x4807e000 0x400>;
                        interrupts = <42>;
                        ti,hwmods = "timer6";
                };
 
                timer7: timer@48080000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap2420-timer";
                        reg = <0x48080000 0x400>;
                        interrupts = <43>;
                        ti,hwmods = "timer7";
                };
 
                timer8: timer@48082000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap2420-timer";
                        reg = <0x48082000 0x400>;
                        interrupts = <44>;
                        ti,hwmods = "timer8";
                };
 
                timer9: timer@48084000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap2420-timer";
                        reg = <0x48084000 0x400>;
                        interrupts = <45>;
                        ti,hwmods = "timer9";
                };
 
                timer10: timer@48086000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap2420-timer";
                        reg = <0x48086000 0x400>;
                        interrupts = <46>;
                        ti,hwmods = "timer10";
                };
 
                timer11: timer@48088000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap2420-timer";
                        reg = <0x48088000 0x400>;
                        interrupts = <47>;
                        ti,hwmods = "timer11";
                };
 
                timer12: timer@4808a000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap2420-timer";
                        reg = <0x4808a000 0x400>;
                        interrupts = <48>;
                        ti,hwmods = "timer12";
index 9b0d07746cba8fc4c8c9f3d89f8a7660a098197a..68282ee13e2692770c1f1222016e369a0f4ed6d3 100644 (file)
                reg = <0x80000000 0x4000000>; /* 64 MB */
        };
 };
+
+&gpmc {
+       ranges = <0 0 0x08000000 0x04000000>;
+
+       nor@0,0 {
+               compatible = "cfi-flash";
+               linux,mtd-name= "intel,ge28f256l18b85";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0 0 0x04000000>;
+               bank-width = <2>;
+
+               gpmc,mux-add-data = <2>;
+               gpmc,cs-on-ns = <10>;
+               gpmc,cs-rd-off-ns = <160>;
+               gpmc,cs-wr-off-ns = <160>;
+               gpmc,adv-on-ns = <20>;
+               gpmc,adv-rd-off-ns = <50>;
+               gpmc,adv-wr-off-ns = <50>;
+               gpmc,oe-on-ns = <60>;
+               gpmc,oe-off-ns = <120>;
+               gpmc,we-on-ns = <60>;
+               gpmc,we-off-ns = <120>;
+               gpmc,rd-cycle-ns = <170>;
+               gpmc,wr-cycle-ns = <170>;
+               gpmc,access-ns = <150>;
+               gpmc,page-burst-access-ns = <10>;
+
+               partition@0 {
+                       label = "bootloader";
+                       reg = <0 0x20000>;
+               };
+               partition@0x20000 {
+                       label = "params";
+                       reg = <0x20000 0x20000>;
+               };
+               partition@0x40000 {
+                       label = "kernel";
+                       reg = <0x40000 0x200000>;
+               };
+               partition@0x240000 {
+                       label = "file-system";
+                       reg = <0x240000 0x3dc0000>;
+               };
+       };
+};
index af6560908905595dbd2a535c013948afa7ef7637..da5b285b73bedd96c1c4abf462f408ce394e60f9 100644 (file)
                        pinctrl-single,function-mask = <0x3f>;
                };
 
+               gpio1: gpio@48018000 {
+                       compatible = "ti,omap2-gpio";
+                       reg = <0x48018000 0x200>;
+                       interrupts = <29>;
+                       ti,hwmods = "gpio1";
+                       ti,gpio-always-on;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+               };
+
+               gpio2: gpio@4801a000 {
+                       compatible = "ti,omap2-gpio";
+                       reg = <0x4801a000 0x200>;
+                       interrupts = <30>;
+                       ti,hwmods = "gpio2";
+                       ti,gpio-always-on;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+               };
+
+               gpio3: gpio@4801c000 {
+                       compatible = "ti,omap2-gpio";
+                       reg = <0x4801c000 0x200>;
+                       interrupts = <31>;
+                       ti,hwmods = "gpio3";
+                       ti,gpio-always-on;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+               };
+
+               gpio4: gpio@4801e000 {
+                       compatible = "ti,omap2-gpio";
+                       reg = <0x4801e000 0x200>;
+                       interrupts = <32>;
+                       ti,hwmods = "gpio4";
+                       ti,gpio-always-on;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+               };
+
+               gpmc: gpmc@6800a000 {
+                       compatible = "ti,omap2420-gpmc";
+                       reg = <0x6800a000 0x1000>;
+                       #address-cells = <2>;
+                       #size-cells = <1>;
+                       interrupts = <20>;
+                       gpmc,num-cs = <8>;
+                       gpmc,num-waitpins = <4>;
+                       ti,hwmods = "gpmc";
+               };
+
                mcbsp1: mcbsp@48074000 {
                        compatible = "ti,omap2420-mcbsp";
                        reg = <0x48074000 0xff>;
@@ -37,6 +96,9 @@
                                     <60>; /* RX interrupt */
                        interrupt-names = "tx", "rx";
                        ti,hwmods = "mcbsp1";
+                       dmas = <&sdma 31>,
+                              <&sdma 32>;
+                       dma-names = "tx", "rx";
                };
 
                mcbsp2: mcbsp@48076000 {
                                     <63>; /* RX interrupt */
                        interrupt-names = "tx", "rx";
                        ti,hwmods = "mcbsp2";
+                       dmas = <&sdma 33>,
+                              <&sdma 34>;
+                       dma-names = "tx", "rx";
                };
 
                timer1: timer@48028000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap2420-timer";
                        reg = <0x48028000 0x400>;
                        interrupts = <37>;
                        ti,hwmods = "timer1";
index c3924457c9b62de16b2709434c98e99f280b3c47..054bc4439568a917a8d28c0c5ebbd5c6dffaf00c 100644 (file)
                        pinctrl-single,function-mask = <0x3f>;
                };
 
+               gpio1: gpio@4900c000 {
+                       compatible = "ti,omap2-gpio";
+                       reg = <0x4900c000 0x200>;
+                       interrupts = <29>;
+                       ti,hwmods = "gpio1";
+                       ti,gpio-always-on;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+               };
+
+               gpio2: gpio@4900e000 {
+                       compatible = "ti,omap2-gpio";
+                       reg = <0x4900e000 0x200>;
+                       interrupts = <30>;
+                       ti,hwmods = "gpio2";
+                       ti,gpio-always-on;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+               };
+
+               gpio3: gpio@49010000 {
+                       compatible = "ti,omap2-gpio";
+                       reg = <0x49010000 0x200>;
+                       interrupts = <31>;
+                       ti,hwmods = "gpio3";
+                       ti,gpio-always-on;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+               };
+
+               gpio4: gpio@49012000 {
+                       compatible = "ti,omap2-gpio";
+                       reg = <0x49012000 0x200>;
+                       interrupts = <32>;
+                       ti,hwmods = "gpio4";
+                       ti,gpio-always-on;
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+               };
+
+               gpio5: gpio@480b6000 {
+                       compatible = "ti,omap2-gpio";
+                       reg = <0x480b6000 0x200>;
+                       interrupts = <33>;
+                       ti,hwmods = "gpio5";
+                       #gpio-cells = <2>;
+                       gpio-controller;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+               };
+
+               gpmc: gpmc@6e000000 {
+                       compatible = "ti,omap2430-gpmc";
+                       reg = <0x6e000000 0x1000>;
+                       #address-cells = <2>;
+                       #size-cells = <1>;
+                       interrupts = <20>;
+                       gpmc,num-cs = <8>;
+                       gpmc,num-waitpins = <4>;
+                       ti,hwmods = "gpmc";
+               };
+
                mcbsp1: mcbsp@48074000 {
                        compatible = "ti,omap2430-mcbsp";
                        reg = <0x48074000 0xff>;
                        interrupt-names = "common", "tx", "rx", "rx_overflow";
                        ti,buffer-size = <128>;
                        ti,hwmods = "mcbsp1";
+                       dmas = <&sdma 31>,
+                              <&sdma 32>;
+                       dma-names = "tx", "rx";
                };
 
                mcbsp2: mcbsp@48076000 {
                        interrupt-names = "common", "tx", "rx";
                        ti,buffer-size = <128>;
                        ti,hwmods = "mcbsp2";
+                       dmas = <&sdma 33>,
+                              <&sdma 34>;
+                       dma-names = "tx", "rx";
                };
 
                mcbsp3: mcbsp@4808c000 {
                        interrupt-names = "common", "tx", "rx";
                        ti,buffer-size = <128>;
                        ti,hwmods = "mcbsp3";
+                       dmas = <&sdma 17>,
+                              <&sdma 18>;
+                       dma-names = "tx", "rx";
                };
 
                mcbsp4: mcbsp@4808e000 {
                        interrupt-names = "common", "tx", "rx";
                        ti,buffer-size = <128>;
                        ti,hwmods = "mcbsp4";
+                       dmas = <&sdma 19>,
+                              <&sdma 20>;
+                       dma-names = "tx", "rx";
                };
 
                mcbsp5: mcbsp@48096000 {
                        interrupt-names = "common", "tx", "rx";
                        ti,buffer-size = <128>;
                        ti,hwmods = "mcbsp5";
+                       dmas = <&sdma 21>,
+                              <&sdma 22>;
+                       dma-names = "tx", "rx";
                };
 
                timer1: timer@49018000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap2420-timer";
                        reg = <0x49018000 0x400>;
                        interrupts = <37>;
                        ti,hwmods = "timer1";
index 3705a81c1fc25eac3b03d4b90be08f6fef7387f9..5a31964ae3396e0fa34ad632003ad8d1306f355b 100644 (file)
        model = "TI OMAP3 BeagleBoard xM";
        compatible = "ti,omap3-beagle-xm, ti,omap3-beagle", "ti,omap3";
 
+       cpus {
+               cpu@0 {
+                       cpu0-supply = <&vcc>;
+               };
+       };
+
        memory {
                device_type = "memory";
                reg = <0x80000000 0x20000000>; /* 512 MB */
 
        leds {
                compatible = "gpio-leds";
-               pmu_stat {
-                       label = "beagleboard::pmu_stat";
-                       gpios = <&twl_gpio 19 0>; /* LEDB */
-               };
 
                heartbeat {
                        label = "beagleboard::usr0";
                };
        };
 
+       pwmleds {
+               compatible = "pwm-leds";
+
+               pmu_stat {
+                       label = "beagleboard::pmu_stat";
+                       pwms = <&twl_pwmled 1 7812500>;
+                       max-brightness = <127>;
+               };
+       };
+
        sound {
                compatible = "ti,omap-twl4030";
                ti,model = "omap3beagle";
         */
        ti,pulldowns = <0x03a1c4>;
 };
+
+&usb_otg_hs {
+       interface-type = <0>;
+       mode = <3>;
+       power = <50>;
+};
index f624dc85d441e5000b8fa0a13abfa78a3e5ce7d2..6eec69997607563e948575ade339b4f1aef3fd2b 100644 (file)
@@ -7,12 +7,18 @@
  */
 /dts-v1/;
 
-/include/ "omap3.dtsi"
+/include/ "omap34xx.dtsi"
 
 / {
        model = "TI OMAP3 BeagleBoard";
        compatible = "ti,omap3-beagle", "ti,omap3";
 
+       cpus {
+               cpu@0 {
+                       cpu0-supply = <&vcc>;
+               };
+       };
+
        memory {
                device_type = "memory";
                reg = <0x80000000 0x10000000>; /* 256 MB */
                };
        };
 
+       /* HS USB Port 2 RESET */
+       hsusb2_reset: hsusb2_reset_reg {
+               compatible = "regulator-fixed";
+               regulator-name = "hsusb2_reset";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio5 19 0>;   /* gpio_147 */
+               startup-delay-us = <70000>;
+               enable-active-high;
+       };
+
+       /* HS USB Port 2 Power */
+       hsusb2_power: hsusb2_power_reg {
+               compatible = "regulator-fixed";
+               regulator-name = "hsusb2_vbus";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&twl_gpio 18 0>;        /* GPIO LEDA */
+               startup-delay-us = <70000>;
+       };
+
+       /* HS USB Host PHY on PORT 2 */
+       hsusb2_phy: hsusb2_phy {
+               compatible = "usb-nop-xceiv";
+               reset-supply = <&hsusb2_reset>;
+               vcc-supply = <&hsusb2_power>;
+       };
+};
+
+&omap3_pmx_core {
+       pinctrl-names = "default";
+       pinctrl-0 = <
+                       &hsusbb2_pins
+       >;
+
+       hsusbb2_pins: pinmux_hsusbb2_pins {
+               pinctrl-single,pins = <
+                       0x5c0 0x3  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_clk OUTPUT */
+                       0x5c2 0x3  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_stp OUTPUT */
+                       0x5c4 0x10b  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dir INPUT | PULLDOWN */
+                       0x5c6 0x10b  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_nxt INPUT | PULLDOWN */
+                       0x5c8 0x10b  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat0 INPUT | PULLDOWN */
+                       0x5cA 0x10b  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat1 INPUT | PULLDOWN */
+                       0x1a4 0x10b  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat2 INPUT | PULLDOWN */
+                       0x1a6 0x10b  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat3 INPUT | PULLDOWN */
+                       0x1a8 0x10b  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat4 INPUT | PULLDOWN */
+                       0x1aa 0x10b  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat5 INPUT | PULLDOWN */
+                       0x1ac 0x10b  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat6 INPUT | PULLDOWN */
+                       0x1ae 0x10b  /* USBB2_ULPITLL_CLK_MUXMODE.usbb1_ulpiphy_dat7 INPUT | PULLDOWN */
+               >;
+       };
 };
 
 &i2c1 {
 &mmc3 {
        status = "disabled";
 };
+
+&usbhshost {
+       port2-mode = "ehci-phy";
+};
+
+&usbhsehci {
+       phys = <0 &hsusb2_phy>;
+};
+
+&twl_gpio {
+       ti,use-leds;
+       /* pullups: BIT(1) */
+       ti,pullups = <0x000002>;
+       /*
+        * pulldowns:
+        * BIT(2), BIT(6), BIT(7), BIT(8), BIT(13)
+        * BIT(15), BIT(16), BIT(17)
+        */
+       ti,pulldowns = <0x03a1c4>;
+};
diff --git a/arch/arm/boot/dts/omap3-devkit8000.dts b/arch/arm/boot/dts/omap3-devkit8000.dts
new file mode 100644 (file)
index 0000000..8a5cdcc
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Author: Anil Kumar <anilk4.v@gmail.com>
+ *
+ * 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.
+ */
+/dts-v1/;
+
+/include/ "omap34xx.dtsi"
+/ {
+       model = "TimLL OMAP3 Devkit8000";
+       compatible = "timll,omap3-devkit8000", "ti,omap3";
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x10000000>;  /* 256 MB */
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               heartbeat {
+                       label = "devkit8000::led1";
+                       gpios = <&gpio6 26 0>;  /* 186 -> LED1 */
+                       default-state = "on";
+                       linux,default-trigger = "heartbeat";
+               };
+
+               mmc {
+                       label = "devkit8000::led2";
+                       gpios = <&gpio6 3 0>;   /* 163 -> LED2 */
+                       default-state = "on";
+                       linux,default-trigger = "none";
+               };
+
+               usr {
+                       label = "devkit8000::led3";
+                       gpios = <&gpio6 4 0>;   /* 164 -> LED3 */
+                       default-state = "on";
+                       linux,default-trigger = "usr";
+                };
+
+       };
+
+       sound {
+               compatible = "ti,omap-twl4030";
+               ti,model = "devkit8000";
+
+               ti,mcbsp = <&mcbsp2>;
+               ti,codec = <&twl_audio>;
+               ti,audio-routing =
+                       "Ext Spk", "PREDRIVEL",
+                       "Ext Spk", "PREDRIVER",
+                       "MAINMIC", "Main Mic",
+                       "Main Mic", "Mic Bias 1";
+       };
+};
+
+&i2c1 {
+       clock-frequency = <2600000>;
+
+       twl: twl@48 {
+               reg = <0x48>;
+               interrupts = <7>;       /* SYS_NIRQ cascaded to intc */
+
+               twl_audio: audio {
+                       compatible = "ti,twl4030-audio";
+                       codec {
+                       };
+               };
+       };
+};
+
+&i2c2 {
+       status = "disabled";
+};
+
+&i2c3 {
+       status = "disabled";
+};
+
+/include/ "twl4030.dtsi"
+
+&mmc1 {
+       vmmc-supply = <&vmmc1>;
+       vmmc_aux-supply = <&vsim>;
+       bus-width = <8>;
+};
+
+&mmc2 {
+       status = "disabled";
+};
+
+&mmc3 {
+       status = "disabled";
+};
+
+&wdt2 {
+       status = "disabled";
+};
+
+&mcbsp1 {
+       status = "disabled";
+};
+
+&mcbsp3 {
+       status = "disabled";
+};
+
+&mcbsp4 {
+       status = "disabled";
+};
+
+&mcbsp5 {
+       status = "disabled";
+};
+
+&gpmc {
+       ranges = <0 0 0x30000000 0x04>;       /* CS0: NAND */
+
+       nand@0,0 {
+               reg = <0 0 0>; /* CS0, offset 0 */
+               nand-bus-width = <16>;
+
+               gpmc,sync-clk = <0>;
+               gpmc,cs-on = <0>;
+               gpmc,cs-rd-off = <44>;
+               gpmc,cs-wr-off = <44>;
+               gpmc,adv-on = <6>;
+               gpmc,adv-rd-off = <34>;
+               gpmc,adv-wr-off = <44>;
+               gpmc,we-off = <40>;
+               gpmc,oe-off = <54>;
+               gpmc,access = <64>;
+               gpmc,rd-cycle = <82>;
+               gpmc,wr-cycle = <82>;
+               gpmc,wr-access = <40>;
+               gpmc,wr-data-mux-bus = <0>;
+
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               x-loader@0 {
+                       label = "X-Loader";
+                       reg = <0 0x80000>;
+               };
+
+               bootloaders@80000 {
+                       label = "U-Boot";
+                       reg = <0x80000 0x1e0000>;
+               };
+
+               bootloaders_env@260000 {
+                       label = "U-Boot Env";
+                       reg = <0x260000 0x20000>;
+               };
+
+               kernel@280000 {
+                       label = "Kernel";
+                       reg = <0x280000 0x400000>;
+               };
+
+               filesystem@680000 {
+                       label = "File System";
+                       reg = <0x680000 0xf980000>;
+               };
+       };
+};
index e8ba1c247a39bf28622276e07a75bf6137baf463..05f51e10ddd6730fcccc83a594f74cb550e7f181 100644 (file)
@@ -7,12 +7,18 @@
  */
 /dts-v1/;
 
-/include/ "omap3.dtsi"
+/include/ "omap34xx.dtsi"
 
 / {
        model = "TI OMAP3 EVM (OMAP3530, AM/DM37x)";
        compatible = "ti,omap3-evm", "ti,omap3";
 
+       cpus {
+               cpu@0 {
+                       cpu0-supply = <&vcc>;
+               };
+       };
+
        memory {
                device_type = "memory";
                reg = <0x80000000 0x10000000>; /* 256 MB */
@@ -59,3 +65,9 @@
 &twl_gpio {
        ti,use-leds;
 };
+
+&usb_otg_hs {
+       interface-type = <0>;
+       mode = <3>;
+       power = <50>;
+};
diff --git a/arch/arm/boot/dts/omap3-igep.dtsi b/arch/arm/boot/dts/omap3-igep.dtsi
new file mode 100644 (file)
index 0000000..f8fe3b7
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Device Tree Source for IGEP Technology devices
+ *
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@collabora.co.uk>
+ * Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@gmail.com>
+ *
+ * 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.
+ */
+/dts-v1/;
+
+/include/ "omap34xx.dtsi"
+
+/ {
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x20000000>; /* 512 MB */
+       };
+
+       sound {
+               compatible = "ti,omap-twl4030";
+               ti,model = "igep2";
+               ti,mcbsp = <&mcbsp2>;
+               ti,codec = <&twl_audio>;
+       };
+};
+
+&omap3_pmx_core {
+       uart1_pins: pinmux_uart1_pins {
+               pinctrl-single,pins = <
+                       0x152 0x100     /* uart1_rx.uart1_rx INPUT | MODE0 */
+                       0x14c 0         /* uart1_tx.uart1_tx OUTPUT | MODE0 */
+               >;
+       };
+
+       uart2_pins: pinmux_uart2_pins {
+               pinctrl-single,pins = <
+                       0x14a 0x100     /* uart2_rx.uart2_rx INPUT | MODE0 */
+                       0x148 0         /* uart2_tx.uart2_tx OUTPUT | MODE0 */
+               >;
+       };
+
+       uart3_pins: pinmux_uart3_pins {
+               pinctrl-single,pins = <
+                       0x16e 0x100     /* uart3_rx.uart3_rx INPUT | MODE0 */
+                       0x170 0         /* uart3_tx.uart3_tx OUTPUT | MODE0 */
+               >;
+       };
+
+       mmc1_pins: pinmux_mmc1_pins {
+               pinctrl-single,pins = <
+                       0x114 0x0118    /* sdmmc1_clk.sdmmc1_clk INPUT PULLUP | MODE 0 */
+                       0x116 0x0118    /* sdmmc1_cmd.sdmmc1_cmd INPUT PULLUP | MODE 0 */
+                       0x118 0x0118    /* sdmmc1_dat0.sdmmc1_dat0 INPUT PULLUP | MODE 0 */
+                       0x11a 0x0118    /* sdmmc1_dat1.sdmmc1_dat1 INPUT PULLUP | MODE 0 */
+                       0x11c 0x0118    /* sdmmc1_dat2.sdmmc1_dat2 INPUT PULLUP | MODE 0 */
+                       0x11e 0x0118    /* sdmmc1_dat3.sdmmc1_dat3 INPUT PULLUP | MODE 0 */
+                       0x120 0x0100    /* sdmmc1_dat4.sdmmc1_dat4 INPUT | MODE 0 */
+                       0x122 0x0100    /* sdmmc1_dat5.sdmmc1_dat5 INPUT | MODE 0 */
+                       0x124 0x0100    /* sdmmc1_dat6.sdmmc1_dat6 INPUT | MODE 0 */
+                       0x126 0x0100    /* sdmmc1_dat7.sdmmc1_dat7 INPUT | MODE 0 */
+               >;
+       };
+};
+
+&i2c1 {
+       clock-frequency = <2600000>;
+
+       twl: twl@48 {
+               reg = <0x48>;
+               interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+               interrupt-parent = <&intc>;
+
+               twl_audio: audio {
+                       compatible = "ti,twl4030-audio";
+                       codec {
+                             };
+               };
+       };
+};
+
+/include/ "twl4030.dtsi"
+
+&i2c2 {
+       clock-frequency = <400000>;
+};
+
+&mmc1 {
+      pinctrl-names = "default";
+      pinctrl-0 = <&mmc1_pins>;
+      vmmc-supply = <&vmmc1>;
+      vmmc_aux-supply = <&vsim>;
+      bus-width = <8>;
+};
+
+&mmc2 {
+       status = "disabled";
+};
+
+&mmc3 {
+       status = "disabled";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart1_pins>;
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_pins>;
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart3_pins>;
+};
+
+&twl_gpio {
+       ti,use-leds;
+};
diff --git a/arch/arm/boot/dts/omap3-igep0020.dts b/arch/arm/boot/dts/omap3-igep0020.dts
new file mode 100644 (file)
index 0000000..e2b9849
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Device Tree Source for IGEPv2 board
+ *
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@collabora.co.uk>
+ * Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/include/ "omap3-igep.dtsi"
+
+/ {
+       model = "IGEPv2";
+       compatible = "isee,omap3-igep0020", "ti,omap3";
+
+       leds {
+               compatible = "gpio-leds";
+               boot {
+                        label = "omap3:green:boot";
+                        gpios = <&gpio1 26 0>;
+                        default-state = "on";
+               };
+
+               user0 {
+                        label = "omap3:red:user0";
+                        gpios = <&gpio1 27 0>;
+                        default-state = "off";
+               };
+
+               user1 {
+                        label = "omap3:red:user1";
+                        gpios = <&gpio1 28 0>;
+                        default-state = "off";
+               };
+
+               user2 {
+                       label = "omap3:green:user1";
+                       gpios = <&twl_gpio 19 1>;
+               };
+       };
+};
+
+&i2c3 {
+       clock-frequency = <100000>;
+
+       /*
+        * Display monitor features are burnt in the EEPROM
+        * as EDID data.
+        */
+       eeprom@50 {
+               compatible = "ti,eeprom";
+               reg = <0x50>;
+       };
+};
diff --git a/arch/arm/boot/dts/omap3-igep0030.dts b/arch/arm/boot/dts/omap3-igep0030.dts
new file mode 100644 (file)
index 0000000..9dc48d2
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Device Tree Source for IGEP COM Module
+ *
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@collabora.co.uk>
+ * Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/include/ "omap3-igep.dtsi"
+
+/ {
+       model = "IGEP COM Module";
+       compatible = "isee,omap3-igep0030", "ti,omap3";
+
+       leds {
+               compatible = "gpio-leds";
+               boot {
+                        label = "omap3:green:boot";
+                        gpios = <&twl_gpio 13 1>;
+                        default-state = "on";
+               };
+
+               user0 {
+                        label = "omap3:red:user0";
+                        gpios = <&twl_gpio 18 1>; /* LEDA */
+                        default-state = "off";
+               };
+
+               user1 {
+                        label = "omap3:green:user1";
+                        gpios = <&twl_gpio 19 1>; /* LEDB */
+                        default-state = "off";
+               };
+
+               user2 {
+                        label = "omap3:red:user1";
+                        gpios = <&gpio1 16 1>;
+                        default-state = "off";
+               };
+       };
+};
index 89808ce016734dd8436e75ae5dad38523ce56671..d4a7280d18b7cdfc82f4bfaa71177a60b09c9ca5 100644 (file)
  */
 /dts-v1/;
 
-/include/ "omap3.dtsi"
+/include/ "omap34xx.dtsi"
 
 / {
-       leds {
-               compatible = "gpio-leds";
+       pwmleds {
+               compatible = "pwm-leds";
+
                overo {
                        label = "overo:blue:COM";
-                       gpios = <&twl_gpio 19 0>;
-                       linux,default-trigger = "mmc0";
+                       pwms = <&twl_pwmled 1 7812500>;
+                       max-brightness = <127>;
                };
        };
+
+       sound {
+               compatible = "ti,omap-twl4030";
+               ti,model = "overo";
+
+               ti,mcbsp = <&mcbsp2>;
+               ti,codec = <&twl_audio>;
+       };
 };
 
 &i2c1 {
                reg = <0x48>;
                interrupts = <7>; /* SYS_NIRQ cascaded to intc */
                interrupt-parent = <&intc>;
+
+               twl_audio: audio {
+                       compatible = "ti,twl4030-audio";
+                       codec {
+                       };
+               };
        };
 };
 
@@ -55,3 +70,9 @@
 &twl_gpio {
        ti,use-leds;
 };
+
+&usb_otg_hs {
+       interface-type = <0>;
+       mode = <3>;
+       power = <50>;
+};
index 1acc26148ffcf94c1ee605d1db58c531f9b01e26..4ad03d9dbf0ce653fb655416ec3fdc76eb54bdde 100644 (file)
                };
        };
 
+       pmu {
+               compatible = "arm,cortex-a8-pmu";
+               interrupts = <3>;
+               ti,hwmods = "debugss";
+       };
+
        /*
-        * The soc node represents the soc top level view. It is uses for IPs
+        * The soc node represents the soc top level view. It is used for IPs
         * that are not memory mapped in the MPU view or for the MPU itself.
         */
        soc {
                        reg = <0x48200000 0x1000>;
                };
 
+               sdma: dma-controller@48056000 {
+                       compatible = "ti,omap3630-sdma", "ti,omap3430-sdma";
+                       reg = <0x48056000 0x1000>;
+                       interrupts = <12>,
+                                    <13>,
+                                    <14>,
+                                    <15>;
+                       #dma-cells = <1>;
+                       #dma-channels = <32>;
+                       #dma-requests = <96>;
+               };
+
                omap3_pmx_core: pinmux@48002030 {
                        compatible = "ti,omap3-padconf", "pinctrl-single";
                        reg = <0x48002030 0x05cc>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        pinctrl-single,register-width = <16>;
-                       pinctrl-single,function-mask = <0x7fff>;
+                       pinctrl-single,function-mask = <0x7f1f>;
                };
 
-               omap3_pmx_wkup: pinmux@0x48002a58 {
+               omap3_pmx_wkup: pinmux@0x48002a00 {
                        compatible = "ti,omap3-padconf", "pinctrl-single";
-                       reg = <0x48002a58 0x5c>;
+                       reg = <0x48002a00 0x5c>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        pinctrl-single,register-width = <16>;
-                       pinctrl-single,function-mask = <0x7fff>;
+                       pinctrl-single,function-mask = <0x7f1f>;
                };
 
                gpio1: gpio@48310000 {
                        compatible = "ti,omap3-gpio";
+                       reg = <0x48310000 0x200>;
+                       interrupts = <29>;
                        ti,hwmods = "gpio1";
+                       ti,gpio-always-on;
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                };
 
                gpio2: gpio@49050000 {
                        compatible = "ti,omap3-gpio";
+                       reg = <0x49050000 0x200>;
+                       interrupts = <30>;
                        ti,hwmods = "gpio2";
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                };
 
                gpio3: gpio@49052000 {
                        compatible = "ti,omap3-gpio";
+                       reg = <0x49052000 0x200>;
+                       interrupts = <31>;
                        ti,hwmods = "gpio3";
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                };
 
                gpio4: gpio@49054000 {
                        compatible = "ti,omap3-gpio";
+                       reg = <0x49054000 0x200>;
+                       interrupts = <32>;
                        ti,hwmods = "gpio4";
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                };
 
                gpio5: gpio@49056000 {
                        compatible = "ti,omap3-gpio";
+                       reg = <0x49056000 0x200>;
+                       interrupts = <33>;
                        ti,hwmods = "gpio5";
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                };
 
                gpio6: gpio@49058000 {
                        compatible = "ti,omap3-gpio";
+                       reg = <0x49058000 0x200>;
+                       interrupts = <34>;
                        ti,hwmods = "gpio6";
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                };
 
                uart1: serial@4806a000 {
                        #size-cells = <0>;
                        ti,hwmods = "mcspi1";
                        ti,spi-num-cs = <4>;
+                       dmas = <&sdma 35>,
+                              <&sdma 36>,
+                              <&sdma 37>,
+                              <&sdma 38>,
+                              <&sdma 39>,
+                              <&sdma 40>,
+                              <&sdma 41>,
+                              <&sdma 42>;
+                       dma-names = "tx0", "rx0", "tx1", "rx1",
+                                   "tx2", "rx2", "tx3", "rx3";
                };
 
                mcspi2: spi@4809a000 {
                        #size-cells = <0>;
                        ti,hwmods = "mcspi2";
                        ti,spi-num-cs = <2>;
+                       dmas = <&sdma 43>,
+                              <&sdma 44>,
+                              <&sdma 45>,
+                              <&sdma 46>;
+                       dma-names = "tx0", "rx0", "tx1", "rx1";
                };
 
                mcspi3: spi@480b8000 {
                        #size-cells = <0>;
                        ti,hwmods = "mcspi3";
                        ti,spi-num-cs = <2>;
+                       dmas = <&sdma 15>,
+                              <&sdma 16>,
+                              <&sdma 23>,
+                              <&sdma 24>;
+                       dma-names = "tx0", "rx0", "tx1", "rx1";
                };
 
                mcspi4: spi@480ba000 {
                        #size-cells = <0>;
                        ti,hwmods = "mcspi4";
                        ti,spi-num-cs = <1>;
+                       dmas = <&sdma 70>, <&sdma 71>;
+                       dma-names = "tx0", "rx0";
                };
 
                mmc1: mmc@4809c000 {
                        compatible = "ti,omap3-hsmmc";
                        ti,hwmods = "mmc1";
                        ti,dual-volt;
+                       dmas = <&sdma 61>, <&sdma 62>;
+                       dma-names = "tx", "rx";
                };
 
                mmc2: mmc@480b4000 {
                        compatible = "ti,omap3-hsmmc";
                        ti,hwmods = "mmc2";
+                       dmas = <&sdma 47>, <&sdma 48>;
+                       dma-names = "tx", "rx";
                };
 
                mmc3: mmc@480ad000 {
                        compatible = "ti,omap3-hsmmc";
                        ti,hwmods = "mmc3";
+                       dmas = <&sdma 77>, <&sdma 78>;
+                       dma-names = "tx", "rx";
                };
 
                wdt2: wdt@48314000 {
                        interrupt-names = "common", "tx", "rx";
                        ti,buffer-size = <128>;
                        ti,hwmods = "mcbsp1";
+                       dmas = <&sdma 31>,
+                              <&sdma 32>;
+                       dma-names = "tx", "rx";
                };
 
                mcbsp2: mcbsp@49022000 {
                        interrupt-names = "common", "tx", "rx", "sidetone";
                        ti,buffer-size = <1280>;
                        ti,hwmods = "mcbsp2", "mcbsp2_sidetone";
+                       dmas = <&sdma 33>,
+                              <&sdma 34>;
+                       dma-names = "tx", "rx";
                };
 
                mcbsp3: mcbsp@49024000 {
                        interrupt-names = "common", "tx", "rx", "sidetone";
                        ti,buffer-size = <128>;
                        ti,hwmods = "mcbsp3", "mcbsp3_sidetone";
+                       dmas = <&sdma 17>,
+                              <&sdma 18>;
+                       dma-names = "tx", "rx";
                };
 
                mcbsp4: mcbsp@49026000 {
                        interrupt-names = "common", "tx", "rx";
                        ti,buffer-size = <128>;
                        ti,hwmods = "mcbsp4";
+                       dmas = <&sdma 19>,
+                              <&sdma 20>;
+                       dma-names = "tx", "rx";
                };
 
                mcbsp5: mcbsp@48096000 {
                        interrupt-names = "common", "tx", "rx";
                        ti,buffer-size = <128>;
                        ti,hwmods = "mcbsp5";
+                       dmas = <&sdma 21>,
+                              <&sdma 22>;
+                       dma-names = "tx", "rx";
                };
 
                timer1: timer@48318000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap3430-timer";
                        reg = <0x48318000 0x400>;
                        interrupts = <37>;
                        ti,hwmods = "timer1";
                };
 
                timer2: timer@49032000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap3430-timer";
                        reg = <0x49032000 0x400>;
                        interrupts = <38>;
                        ti,hwmods = "timer2";
                };
 
                timer3: timer@49034000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap3430-timer";
                        reg = <0x49034000 0x400>;
                        interrupts = <39>;
                        ti,hwmods = "timer3";
                };
 
                timer4: timer@49036000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap3430-timer";
                        reg = <0x49036000 0x400>;
                        interrupts = <40>;
                        ti,hwmods = "timer4";
                };
 
                timer5: timer@49038000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap3430-timer";
                        reg = <0x49038000 0x400>;
                        interrupts = <41>;
                        ti,hwmods = "timer5";
                };
 
                timer6: timer@4903a000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap3430-timer";
                        reg = <0x4903a000 0x400>;
                        interrupts = <42>;
                        ti,hwmods = "timer6";
                };
 
                timer7: timer@4903c000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap3430-timer";
                        reg = <0x4903c000 0x400>;
                        interrupts = <43>;
                        ti,hwmods = "timer7";
                };
 
                timer8: timer@4903e000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap3430-timer";
                        reg = <0x4903e000 0x400>;
                        interrupts = <44>;
                        ti,hwmods = "timer8";
                };
 
                timer9: timer@49040000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap3430-timer";
                        reg = <0x49040000 0x400>;
                        interrupts = <45>;
                        ti,hwmods = "timer9";
                };
 
                timer10: timer@48086000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap3430-timer";
                        reg = <0x48086000 0x400>;
                        interrupts = <46>;
                        ti,hwmods = "timer10";
                };
 
                timer11: timer@48088000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap3430-timer";
                        reg = <0x48088000 0x400>;
                        interrupts = <47>;
                        ti,hwmods = "timer11";
                };
 
                timer12: timer@48304000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap3430-timer";
                        reg = <0x48304000 0x400>;
                        interrupts = <95>;
                        ti,hwmods = "timer12";
                        ti,timer-alwon;
                        ti,timer-secure;
                };
+
+               usbhstll: usbhstll@48062000 {
+                       compatible = "ti,usbhs-tll";
+                       reg = <0x48062000 0x1000>;
+                       interrupts = <78>;
+                       ti,hwmods = "usb_tll_hs";
+               };
+
+               usbhshost: usbhshost@48064000 {
+                       compatible = "ti,usbhs-host";
+                       reg = <0x48064000 0x400>;
+                       ti,hwmods = "usb_host_hs";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       usbhsohci: ohci@48064400 {
+                               compatible = "ti,ohci-omap3", "usb-ohci";
+                               reg = <0x48064400 0x400>;
+                               interrupt-parent = <&intc>;
+                               interrupts = <76>;
+                       };
+
+                       usbhsehci: ehci@48064800 {
+                               compatible = "ti,ehci-omap", "usb-ehci";
+                               reg = <0x48064800 0x400>;
+                               interrupt-parent = <&intc>;
+                               interrupts = <77>;
+                       };
+               };
+
+               gpmc: gpmc@6e000000 {
+                       compatible = "ti,omap3430-gpmc";
+                       ti,hwmods = "gpmc";
+                       reg = <0x6e000000 0x02d0>;
+                       interrupts = <20>;
+                       gpmc,num-cs = <8>;
+                       gpmc,num-waitpins = <4>;
+                       #address-cells = <2>;
+                       #size-cells = <1>;
+               };
+
+               usb_otg_hs: usb_otg_hs@480ab000 {
+                       compatible = "ti,omap3-musb";
+                       reg = <0x480ab000 0x1000>;
+                       interrupts = <0 92 0x4>, <0 93 0x4>;
+                       interrupt-names = "mc", "dma";
+                       ti,hwmods = "usb_otg_hs";
+                       usb-phy = <&usb2_phy>;
+                       multipoint = <1>;
+                       num-eps = <16>;
+                       ram-bits = <12>;
+               };
        };
 };
diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts
new file mode 100644 (file)
index 0000000..144ae43
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * 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.
+ */
+/dts-v1/;
+
+/include/ "omap34xx.dtsi"
+
+/ {
+       model = "TI OMAP3430 SDP";
+       compatible = "ti,omap3430-sdp", "ti,omap3";
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x10000000>; /* 256 MB */
+       };
+};
+
+&i2c1 {
+       clock-frequency = <2600000>;
+
+       twl: twl@48 {
+               reg = <0x48>;
+               interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+       };
+};
+
+/include/ "twl4030.dtsi"
+
+&mmc1 {
+       vmmc-supply = <&vmmc1>;
+       vmmc_aux-supply = <&vsim>;
+       bus-width = <8>;
+};
+
+&mmc2 {
+       status = "disabled";
+};
+
+&mmc3 {
+       status = "disabled";
+};
+
+&gpmc {
+       ranges = <0 0 0x10000000 0x08000000>,
+                <1 0 0x28000000 0x08000000>,
+                <2 0 0x20000000 0x10000000>;
+
+       nor@0,0 {
+               compatible = "cfi-flash";
+               linux,mtd-name= "intel,pf48f6000m0y1be";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0 0 0x08000000>;
+               bank-width = <2>;
+
+               gpmc,mux-add-data = <2>;
+               gpmc,cs-on-ns = <0>;
+               gpmc,cs-rd-off-ns = <186>;
+               gpmc,cs-wr-off-ns = <186>;
+               gpmc,adv-on-ns = <12>;
+               gpmc,adv-rd-off-ns = <48>;
+               gpmc,adv-wr-off-ns = <48>;
+               gpmc,oe-on-ns = <54>;
+               gpmc,oe-off-ns = <168>;
+               gpmc,we-on-ns = <54>;
+               gpmc,we-off-ns = <168>;
+               gpmc,rd-cycle-ns = <186>;
+               gpmc,wr-cycle-ns = <186>;
+               gpmc,access-ns = <114>;
+               gpmc,page-burst-access-ns = <6>;
+               gpmc,bus-turnaround-ns = <12>;
+               gpmc,cycle2cycle-delay-ns = <18>;
+               gpmc,wr-data-mux-bus-ns = <90>;
+               gpmc,wr-access-ns = <186>;
+               gpmc,cycle2cycle-samecsen;
+               gpmc,cycle2cycle-diffcsen;
+
+               partition@0 {
+                       label = "bootloader-nor";
+                       reg = <0 0x40000>;
+               };
+               partition@0x40000 {
+                       label = "params-nor";
+                       reg = <0x40000 0x40000>;
+               };
+               partition@0x80000 {
+                       label = "kernel-nor";
+                       reg = <0x80000 0x200000>;
+               };
+               partition@0x280000 {
+                       label = "filesystem-nor";
+                       reg = <0x240000 0x7d80000>;
+               };
+       };
+
+       nand@1,0 {
+               linux,mtd-name= "micron,mt29f1g08abb";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <1 0 0x08000000>;
+               nand-bus-width = <8>;
+
+               ti,nand-ecc-opt = "sw";
+               gpmc,device-nand;
+               gpmc,cs-on-ns = <0>;
+               gpmc,cs-rd-off-ns = <36>;
+               gpmc,cs-wr-off-ns = <36>;
+               gpmc,adv-on-ns = <6>;
+               gpmc,adv-rd-off-ns = <24>;
+               gpmc,adv-wr-off-ns = <36>;
+               gpmc,oe-on-ns = <6>;
+               gpmc,oe-off-ns = <48>;
+               gpmc,we-on-ns = <6>;
+               gpmc,we-off-ns = <30>;
+               gpmc,rd-cycle-ns = <72>;
+               gpmc,wr-cycle-ns = <72>;
+               gpmc,access-ns = <54>;
+               gpmc,wr-access-ns = <30>;
+
+               partition@0 {
+                       label = "xloader-nand";
+                       reg = <0 0x80000>;
+               };
+               partition@0x80000 {
+                       label = "bootloader-nand";
+                       reg = <0x80000 0x140000>;
+               };
+               partition@0x1c0000 {
+                       label = "params-nand";
+                       reg = <0x1c0000 0xc0000>;
+               };
+               partition@0x280000 {
+                       label = "kernel-nand";
+                       reg = <0x280000 0x500000>;
+               };
+               partition@0x780000 {
+                       label = "filesystem-nand";
+                       reg = <0x780000 0x7880000>;
+               };
+       };
+
+       onenand@2,0 {
+               linux,mtd-name= "samsung,kfm2g16q2m-deb8";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <2 0 0x10000000>;
+
+               gpmc,device-width = <2>;
+               gpmc,mux-add-data = <2>;
+               gpmc,cs-on-ns = <0>;
+               gpmc,cs-rd-off-ns = <84>;
+               gpmc,cs-wr-off-ns = <72>;
+               gpmc,adv-on-ns = <0>;
+               gpmc,adv-rd-off-ns = <18>;
+               gpmc,adv-wr-off-ns = <18>;
+               gpmc,oe-on-ns = <30>;
+               gpmc,oe-off-ns = <84>;
+               gpmc,we-on-ns = <0>;
+               gpmc,we-off-ns = <42>;
+               gpmc,rd-cycle-ns = <108>;
+               gpmc,wr-cycle-ns = <96>;
+               gpmc,access-ns = <78>;
+               gpmc,wr-data-mux-bus-ns = <30>;
+
+               partition@0 {
+                       label = "xloader-onenand";
+                       reg = <0 0x80000>;
+               };
+               partition@0x80000 {
+                       label = "bootloader-onenand";
+                       reg = <0x80000 0x40000>;
+               };
+               partition@0xc0000 {
+                       label = "params-onenand";
+                       reg = <0xc0000 0x20000>;
+               };
+               partition@0xe0000 {
+                       label = "kernel-onenand";
+                       reg = <0xe0000 0x200000>;
+               };
+               partition@0x2e0000 {
+                       label = "filesystem-onenand";
+                       reg = <0x2e0000 0xfd20000>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/omap34xx.dtsi b/arch/arm/boot/dts/omap34xx.dtsi
new file mode 100644 (file)
index 0000000..75ed4ae
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Device Tree Source for OMAP34xx/OMAP35xx SoC
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/include/ "omap3.dtsi"
+
+/ {
+       cpus {
+               cpu@0 {
+                       /* OMAP343x/OMAP35xx variants OPP1-5 */
+                       operating-points = <
+                               /* kHz    uV */
+                               125000   975000
+                               250000  1075000
+                               500000  1200000
+                               550000  1270000
+                               600000  1350000
+                       >;
+                       clock-latency = <300000>; /* From legacy driver */
+               };
+       };
+};
index 96bf0287cb9f92028b14b4f7e2c093d8fac57d5e..b89233e43b0f6af39690941eb664a3306d9b1d33 100644 (file)
                serial3 = &uart4;
        };
 
+       cpus {
+               /* OMAP3630/OMAP37xx 'standard device' variants OPP50 to OPP130 */
+               cpu@0 {
+                       operating-points = <
+                               /* kHz    uV */
+                               300000   975000
+                               600000  1075000
+                               800000  1200000
+                       >;
+                       clock-latency = <300000>; /* From legacy driver */
+               };
+       };
+
        ocp {
                uart4: serial@49042000 {
                        compatible = "ti,omap3-uart";
index 75466d2abfb555a54e2ab41764f56e5f86010854..e30cdf0f5ac15683e448aac5e2e66e207d20ecfe 100644 (file)
@@ -5,7 +5,10 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-/include/ "omap4-panda.dts"
+/dts-v1/;
+
+/include/ "omap443x.dtsi"
+/include/ "omap4-panda-common.dtsi"
 
 /* Pandaboard Rev A4+ have external pullups on SCL & SDA */
 &dss_hdmi_pins {
diff --git a/arch/arm/boot/dts/omap4-panda-common.dtsi b/arch/arm/boot/dts/omap4-panda-common.dtsi
new file mode 100644 (file)
index 0000000..03bd60d
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2011-2013 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/include/ "elpida_ecb240abacn.dtsi"
+
+/ {
+       model = "TI OMAP4 PandaBoard";
+       compatible = "ti,omap4-panda", "ti,omap4430", "ti,omap4";
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x40000000>; /* 1 GB */
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               heartbeat {
+                       label = "pandaboard::status1";
+                       gpios = <&gpio1 7 0>;
+                       linux,default-trigger = "heartbeat";
+               };
+
+               mmc {
+                       label = "pandaboard::status2";
+                       gpios = <&gpio1 8 0>;
+                       linux,default-trigger = "mmc0";
+               };
+       };
+
+       sound: sound {
+               compatible = "ti,abe-twl6040";
+               ti,model = "PandaBoard";
+
+               ti,mclk-freq = <38400000>;
+
+               ti,mcpdm = <&mcpdm>;
+
+               ti,twl6040 = <&twl6040>;
+
+               /* Audio routing */
+               ti,audio-routing =
+                       "Headset Stereophone", "HSOL",
+                       "Headset Stereophone", "HSOR",
+                       "Ext Spk", "HFL",
+                       "Ext Spk", "HFR",
+                       "Line Out", "AUXL",
+                       "Line Out", "AUXR",
+                       "HSMIC", "Headset Mic",
+                       "Headset Mic", "Headset Mic Bias",
+                       "AFML", "Line In",
+                       "AFMR", "Line In";
+       };
+};
+
+&omap4_pmx_core {
+       pinctrl-names = "default";
+       pinctrl-0 = <
+                       &twl6040_pins
+                       &mcpdm_pins
+                       &mcbsp1_pins
+                       &dss_hdmi_pins
+                       &tpd12s015_pins
+       >;
+
+       twl6040_pins: pinmux_twl6040_pins {
+               pinctrl-single,pins = <
+                       0xe0 0x3        /* hdq_sio.gpio_127 OUTPUT | MODE3 */
+                       0x160 0x100     /* sys_nirq2.sys_nirq2 INPUT | MODE0 */
+               >;
+       };
+
+       mcpdm_pins: pinmux_mcpdm_pins {
+               pinctrl-single,pins = <
+                       0xc6 0x108      /* abe_pdm_ul_data.abe_pdm_ul_data INPUT PULLDOWN | MODE0 */
+                       0xc8 0x108      /* abe_pdm_dl_data.abe_pdm_dl_data INPUT PULLDOWN | MODE0 */
+                       0xca 0x118      /* abe_pdm_frame.abe_pdm_frame INPUT PULLUP | MODE0 */
+                       0xcc 0x108      /* abe_pdm_lb_clk.abe_pdm_lb_clk INPUT PULLDOWN | MODE0 */
+                       0xce 0x108      /* abe_clks.abe_clks INPUT PULLDOWN | MODE0 */
+               >;
+       };
+
+       mcbsp1_pins: pinmux_mcbsp1_pins {
+               pinctrl-single,pins = <
+                       0xbe 0x100      /* abe_mcbsp1_clkx.abe_mcbsp1_clkx INPUT | MODE0 */
+                       0xc0 0x108      /* abe_mcbsp1_dr.abe_mcbsp1_dr INPUT PULLDOWN | MODE0 */
+                       0xc2 0x8                /* abe_mcbsp1_dx.abe_mcbsp1_dx OUTPUT PULLDOWN | MODE0 */
+                       0xc4 0x100      /* abe_mcbsp1_fsx.abe_mcbsp1_fsx INPUT | MODE0 */
+               >;
+       };
+
+       dss_hdmi_pins: pinmux_dss_hdmi_pins {
+               pinctrl-single,pins = <
+                       0x5a 0x118      /* hdmi_cec.hdmi_cec INPUT PULLUP | MODE 0 */
+                       0x5c 0x118      /* hdmi_scl.hdmi_scl INPUT PULLUP | MODE 0 */
+                       0x5e 0x118      /* hdmi_sda.hdmi_sda INPUT PULLUP | MODE 0 */
+               >;
+       };
+
+       tpd12s015_pins: pinmux_tpd12s015_pins {
+               pinctrl-single,pins = <
+                       0x22 0x3        /* gpmc_a17.gpio_41 OUTPUT | MODE3 */
+                       0x48 0x3        /* gpmc_nbe1.gpio_60 OUTPUT | MODE3 */
+                       0x58 0x10b      /* hdmi_hpd.gpio_63 INPUT PULLDOWN | MODE3 */
+               >;
+       };
+
+       i2c1_pins: pinmux_i2c1_pins {
+               pinctrl-single,pins = <
+                       0xe2 0x118        /* i2c1_scl PULLUP | INPUTENABLE | MODE0 */
+                       0xe4 0x118        /* i2c1_sda PULLUP | INPUTENABLE | MODE0 */
+               >;
+       };
+
+       i2c2_pins: pinmux_i2c2_pins {
+               pinctrl-single,pins = <
+                       0xe6 0x118        /* i2c2_scl PULLUP | INPUTENABLE | MODE0 */
+                       0xe8 0x118        /* i2c2_sda PULLUP | INPUTENABLE | MODE0 */
+               >;
+       };
+
+       i2c3_pins: pinmux_i2c3_pins {
+               pinctrl-single,pins = <
+                       0xea 0x118        /* i2c3_scl PULLUP | INPUTENABLE | MODE0 */
+                       0xec 0x118     /* i2c3_sda PULLUP | INPUTENABLE | MODE0 */
+               >;
+       };
+
+       i2c4_pins: pinmux_i2c4_pins {
+               pinctrl-single,pins = <
+                       0xee 0x118        /* i2c4_scl PULLUP | INPUTENABLE | MODE0 */
+                       0xf0 0x118     /* i2c4_sda PULLUP | INPUTENABLE | MODE0 */
+               >;
+       };
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins>;
+
+       clock-frequency = <400000>;
+
+       twl: twl@48 {
+               reg = <0x48>;
+               /* SPI = 0, IRQ# = 7, 4 = active high level-sensitive */
+               interrupts = <0 7 4>; /* IRQ_SYS_1N cascaded to gic */
+               interrupt-parent = <&gic>;
+       };
+
+       twl6040: twl@4b {
+               compatible = "ti,twl6040";
+               reg = <0x4b>;
+               /* SPI = 0, IRQ# = 119, 4 = active high level-sensitive */
+               interrupts = <0 119 4>; /* IRQ_SYS_2N cascaded to gic */
+               interrupt-parent = <&gic>;
+               ti,audpwron-gpio = <&gpio4 31 0>;  /* gpio line 127 */
+
+               vio-supply = <&v1v8>;
+               v2v1-supply = <&v2v1>;
+               enable-active-high;
+       };
+};
+
+/include/ "twl6030.dtsi"
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c2_pins>;
+
+       clock-frequency = <400000>;
+};
+
+&i2c3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c3_pins>;
+
+       clock-frequency = <100000>;
+
+       /*
+        * Display monitor features are burnt in their EEPROM as EDID data.
+        * The EEPROM is connected as I2C slave device.
+        */
+       eeprom@50 {
+               compatible = "ti,eeprom";
+               reg = <0x50>;
+       };
+};
+
+&i2c4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c4_pins>;
+
+       clock-frequency = <400000>;
+};
+
+&mmc1 {
+       vmmc-supply = <&vmmc>;
+       bus-width = <8>;
+};
+
+&mmc2 {
+       status = "disabled";
+};
+
+&mmc3 {
+       status = "disabled";
+};
+
+&mmc4 {
+       status = "disabled";
+};
+
+&mmc5 {
+       ti,non-removable;
+       bus-width = <4>;
+};
+
+&emif1 {
+       cs1-used;
+       device-handle = <&elpida_ECB240ABACN>;
+};
+
+&emif2 {
+       cs1-used;
+       device-handle = <&elpida_ECB240ABACN>;
+};
+
+&mcbsp2 {
+       status = "disabled";
+};
+
+&mcbsp3 {
+       status = "disabled";
+};
+
+&dmic {
+       status = "disabled";
+};
+
+&twl_usb_comparator {
+       usb-supply = <&vusb>;
+};
+
+&usb_otg_hs {
+       interface-type = <1>;
+       mode = <3>;
+       power = <50>;
+};
index 73bc1a67e444480ff08ec414848981ec27fe7e39..f1d8c217ce1274949b6f6b09d9d728eac21c6a06 100644 (file)
@@ -5,7 +5,10 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-/include/ "omap4-panda.dts"
+/dts-v1/;
+
+/include/ "omap4460.dtsi"
+/include/ "omap4-panda-common.dtsi"
 
 /* Audio routing is differnet between PandaBoard4430 and PandaBoardES */
 &sound {
index 4122efe31cfdf04ed6218ca970c7c661372d94e2..f8b221f0168ee05920c8f4e2d91a905f3362ab62 100644 (file)
@@ -7,202 +7,5 @@
  */
 /dts-v1/;
 
-/include/ "omap4.dtsi"
-/include/ "elpida_ecb240abacn.dtsi"
-
-/ {
-       model = "TI OMAP4 PandaBoard";
-       compatible = "ti,omap4-panda", "ti,omap4430", "ti,omap4";
-
-       memory {
-               device_type = "memory";
-               reg = <0x80000000 0x40000000>; /* 1 GB */
-       };
-
-       leds {
-               compatible = "gpio-leds";
-               heartbeat {
-                       label = "pandaboard::status1";
-                       gpios = <&gpio1 7 0>;
-                       linux,default-trigger = "heartbeat";
-               };
-
-               mmc {
-                       label = "pandaboard::status2";
-                       gpios = <&gpio1 8 0>;
-                       linux,default-trigger = "mmc0";
-               };
-       };
-
-       sound: sound {
-               compatible = "ti,abe-twl6040";
-               ti,model = "PandaBoard";
-
-               ti,mclk-freq = <38400000>;
-
-               ti,mcpdm = <&mcpdm>;
-
-               ti,twl6040 = <&twl6040>;
-
-               /* Audio routing */
-               ti,audio-routing =
-                       "Headset Stereophone", "HSOL",
-                       "Headset Stereophone", "HSOR",
-                       "Ext Spk", "HFL",
-                       "Ext Spk", "HFR",
-                       "Line Out", "AUXL",
-                       "Line Out", "AUXR",
-                       "HSMIC", "Headset Mic",
-                       "Headset Mic", "Headset Mic Bias",
-                       "AFML", "Line In",
-                       "AFMR", "Line In";
-       };
-};
-
-&omap4_pmx_core {
-       pinctrl-names = "default";
-       pinctrl-0 = <
-                       &twl6040_pins
-                       &mcpdm_pins
-                       &mcbsp1_pins
-                       &dss_hdmi_pins
-                       &tpd12s015_pins
-       >;
-
-       twl6040_pins: pinmux_twl6040_pins {
-               pinctrl-single,pins = <
-                       0xe0 0x3        /* hdq_sio.gpio_127 OUTPUT | MODE3 */
-                       0x160 0x100     /* sys_nirq2.sys_nirq2 INPUT | MODE0 */
-               >;
-       };
-
-       mcpdm_pins: pinmux_mcpdm_pins {
-               pinctrl-single,pins = <
-                       0xc6 0x108      /* abe_pdm_ul_data.abe_pdm_ul_data INPUT PULLDOWN | MODE0 */
-                       0xc8 0x108      /* abe_pdm_dl_data.abe_pdm_dl_data INPUT PULLDOWN | MODE0 */
-                       0xca 0x118      /* abe_pdm_frame.abe_pdm_frame INPUT PULLUP | MODE0 */
-                       0xcc 0x108      /* abe_pdm_lb_clk.abe_pdm_lb_clk INPUT PULLDOWN | MODE0 */
-                       0xce 0x108      /* abe_clks.abe_clks INPUT PULLDOWN | MODE0 */
-               >;
-       };
-
-       mcbsp1_pins: pinmux_mcbsp1_pins {
-               pinctrl-single,pins = <
-                       0xbe 0x100      /* abe_mcbsp1_clkx.abe_mcbsp1_clkx INPUT | MODE0 */
-                       0xc0 0x108      /* abe_mcbsp1_dr.abe_mcbsp1_dr INPUT PULLDOWN | MODE0 */
-                       0xc2 0x8                /* abe_mcbsp1_dx.abe_mcbsp1_dx OUTPUT PULLDOWN | MODE0 */
-                       0xc4 0x100      /* abe_mcbsp1_fsx.abe_mcbsp1_fsx INPUT | MODE0 */
-               >;
-       };
-
-       dss_hdmi_pins: pinmux_dss_hdmi_pins {
-               pinctrl-single,pins = <
-                       0x5a 0x118      /* hdmi_cec.hdmi_cec INPUT PULLUP | MODE 0 */
-                       0x5c 0x118      /* hdmi_scl.hdmi_scl INPUT PULLUP | MODE 0 */
-                       0x5e 0x118      /* hdmi_sda.hdmi_sda INPUT PULLUP | MODE 0 */
-               >;
-       };
-
-       tpd12s015_pins: pinmux_tpd12s015_pins {
-               pinctrl-single,pins = <
-                       0x22 0x3        /* gpmc_a17.gpio_41 OUTPUT | MODE3 */
-                       0x48 0x3        /* gpmc_nbe1.gpio_60 OUTPUT | MODE3 */
-                       0x58 0x10b      /* hdmi_hpd.gpio_63 INPUT PULLDOWN | MODE3 */
-               >;
-       };
-};
-
-&i2c1 {
-       clock-frequency = <400000>;
-
-       twl: twl@48 {
-               reg = <0x48>;
-               /* SPI = 0, IRQ# = 7, 4 = active high level-sensitive */
-               interrupts = <0 7 4>; /* IRQ_SYS_1N cascaded to gic */
-               interrupt-parent = <&gic>;
-       };
-
-       twl6040: twl@4b {
-               compatible = "ti,twl6040";
-               reg = <0x4b>;
-               /* SPI = 0, IRQ# = 119, 4 = active high level-sensitive */
-               interrupts = <0 119 4>; /* IRQ_SYS_2N cascaded to gic */
-               interrupt-parent = <&gic>;
-               ti,audpwron-gpio = <&gpio4 31 0>;  /* gpio line 127 */
-
-               vio-supply = <&v1v8>;
-               v2v1-supply = <&v2v1>;
-               enable-active-high;
-       };
-};
-
-/include/ "twl6030.dtsi"
-
-&i2c2 {
-       clock-frequency = <400000>;
-};
-
-&i2c3 {
-       clock-frequency = <100000>;
-
-       /*
-        * Display monitor features are burnt in their EEPROM as EDID data.
-        * The EEPROM is connected as I2C slave device.
-        */
-       eeprom@50 {
-               compatible = "ti,eeprom";
-               reg = <0x50>;
-       };
-};
-
-&i2c4 {
-       clock-frequency = <400000>;
-};
-
-&mmc1 {
-       vmmc-supply = <&vmmc>;
-       bus-width = <8>;
-};
-
-&mmc2 {
-       status = "disabled";
-};
-
-&mmc3 {
-       status = "disabled";
-};
-
-&mmc4 {
-       status = "disabled";
-};
-
-&mmc5 {
-       ti,non-removable;
-       bus-width = <4>;
-};
-
-&emif1 {
-       cs1-used;
-       device-handle = <&elpida_ECB240ABACN>;
-};
-
-&emif2 {
-       cs1-used;
-       device-handle = <&elpida_ECB240ABACN>;
-};
-
-&mcbsp2 {
-       status = "disabled";
-};
-
-&mcbsp3 {
-       status = "disabled";
-};
-
-&dmic {
-       status = "disabled";
-};
-
-&twl_usb_comparator {
-       usb-supply = <&vusb>;
-};
+/include/ "omap443x.dtsi"
+/include/ "omap4-panda-common.dtsi"
index 43e5258a9372b673d8c7a7866e30bbd5181148fa..c387bdc1b1d1bea48c940524aa91113df7584fd9 100644 (file)
@@ -7,7 +7,7 @@
  */
 /dts-v1/;
 
-/include/ "omap4.dtsi"
+/include/ "omap443x.dtsi"
 /include/ "elpida_ecb240abacn.dtsi"
 
 / {
                };
        };
 
+       pwmleds {
+               compatible = "pwm-leds";
+               kpad {
+                       label = "omap4::keypad";
+                       pwms = <&twl_pwm 0 7812500>;
+                       max-brightness = <127>;
+               };
+
+               charging {
+                       label = "omap4:green:chrg";
+                       pwms = <&twl_pwmled 0 7812500>;
+                       max-brightness = <255>;
+               };
+       };
+
+       backlight {
+               compatible = "pwm-backlight";
+               pwms = <&twl_pwm 1 7812500>;
+               brightness-levels = <
+                               0 10 20 30 40
+                               50 60 70 80 90
+                               100 110 120 127
+                               >;
+               default-brightness-level = <13>;
+       };
+
        sound {
                compatible = "ti,abe-twl6040";
                ti,model = "SDP4430";
                        0x58 0x10b      /* hdmi_hpd.gpio_63 INPUT PULLDOWN | MODE3 */
                >;
        };
+
+       i2c1_pins: pinmux_i2c1_pins {
+               pinctrl-single,pins = <
+                       0xe2 0x118        /* i2c1_scl PULLUP | INPUTENABLE | MODE0 */
+                       0xe4 0x118       /* i2c1_sda PULLUP | INPUTENABLE | MODE0 */
+               >;
+       };
+
+       i2c2_pins: pinmux_i2c2_pins {
+               pinctrl-single,pins = <
+                        0xe6 0x118        /* i2c2_scl PULLUP | INPUTENABLE | MODE0 */
+                        0xe8 0x118        /* i2c2_sda PULLUP | INPUTENABLE | MODE0 */
+               >;
+       };
+
+       i2c3_pins: pinmux_i2c3_pins {
+               pinctrl-single,pins = <
+                       0xea 0x118        /* i2c3_scl PULLUP | INPUTENABLE | MODE0 */
+                       0xec 0x118     /* i2c3_sda PULLUP | INPUTENABLE | MODE0 */
+               >;
+       };
+
+       i2c4_pins: pinmux_i2c4_pins {
+               pinctrl-single,pins = <
+                       0xee 0x118        /* i2c4_scl PULLUP | INPUTENABLE | MODE0 */
+                       0xf0 0x118     /* i2c4_sda PULLUP | INPUTENABLE | MODE0 */
+               >;
+       };
 };
 
 &i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins>;
+
        clock-frequency = <400000>;
 
        twl: twl@48 {
 /include/ "twl6030.dtsi"
 
 &i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c2_pins>;
+
        clock-frequency = <400000>;
 };
 
 &i2c3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c3_pins>;
+
        clock-frequency = <400000>;
 
        /*
 };
 
 &i2c4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c4_pins>;
+
        clock-frequency = <400000>;
 
        /*
 &twl_usb_comparator {
        usb-supply = <&vusb>;
 };
+
+&usb_otg_hs {
+       interface-type = <1>;
+       mode = <3>;
+       power = <50>;
+};
index 6601e6af6092f78d11757a8c34e1ec69ca6e9fa7..222a413c2c5162d235fe96d0ee3568035d0928fd 100644 (file)
@@ -7,7 +7,7 @@
  */
 /dts-v1/;
 
-/include/ "omap4.dtsi"
+/include/ "omap443x.dtsi"
 
 / {
        model = "Variscite OMAP4 SOM";
index 739bb79e410e5bb5f558afdc85d227d9e5056885..2a5642882c8af8810601a3763808e60014831d07 100644 (file)
                #size-cells = <1>;
                ranges;
                ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3";
+               reg = <0x44000000 0x1000>,
+                     <0x44800000 0x2000>,
+                     <0x45000000 0x1000>;
+               interrupts = <0 9 0x4>,
+                            <0 10 0x4>;
 
                counter32k: counter@4a304000 {
                        compatible = "ti,omap-counter32k";
                        pinctrl-single,function-mask = <0x7fff>;
                };
 
+               sdma: dma-controller@4a056000 {
+                       compatible = "ti,omap4430-sdma";
+                       reg = <0x4a056000 0x1000>;
+                       interrupts = <0 12 0x4>,
+                                    <0 13 0x4>,
+                                    <0 14 0x4>,
+                                    <0 15 0x4>;
+                       #dma-cells = <1>;
+                       #dma-channels = <32>;
+                       #dma-requests = <127>;
+               };
+
                gpio1: gpio@4a310000 {
                        compatible = "ti,omap4-gpio";
                        reg = <0x4a310000 0x200>;
                        interrupts = <0 29 0x4>;
                        ti,hwmods = "gpio1";
+                       ti,gpio-always-on;
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                };
 
                gpio2: gpio@48055000 {
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                };
 
                gpio3: gpio@48057000 {
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                };
 
                gpio4: gpio@48059000 {
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                };
 
                gpio5: gpio@4805b000 {
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                };
 
                gpio6: gpio@4805d000 {
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
+               };
+
+               gpmc: gpmc@50000000 {
+                       compatible = "ti,omap4430-gpmc";
+                       reg = <0x50000000 0x1000>;
+                       #address-cells = <2>;
+                       #size-cells = <1>;
+                       interrupts = <0 20 0x4>;
+                       gpmc,num-cs = <8>;
+                       gpmc,num-waitpins = <4>;
+                       ti,hwmods = "gpmc";
                };
 
                uart1: serial@4806a000 {
                        #size-cells = <0>;
                        ti,hwmods = "mcspi1";
                        ti,spi-num-cs = <4>;
+                       dmas = <&sdma 35>,
+                              <&sdma 36>,
+                              <&sdma 37>,
+                              <&sdma 38>,
+                              <&sdma 39>,
+                              <&sdma 40>,
+                              <&sdma 41>,
+                              <&sdma 42>;
+                       dma-names = "tx0", "rx0", "tx1", "rx1",
+                                   "tx2", "rx2", "tx3", "rx3";
                };
 
                mcspi2: spi@4809a000 {
                        #size-cells = <0>;
                        ti,hwmods = "mcspi2";
                        ti,spi-num-cs = <2>;
+                       dmas = <&sdma 43>,
+                              <&sdma 44>,
+                              <&sdma 45>,
+                              <&sdma 46>;
+                       dma-names = "tx0", "rx0", "tx1", "rx1";
                };
 
                mcspi3: spi@480b8000 {
                        #size-cells = <0>;
                        ti,hwmods = "mcspi3";
                        ti,spi-num-cs = <2>;
+                       dmas = <&sdma 15>, <&sdma 16>;
+                       dma-names = "tx0", "rx0";
                };
 
                mcspi4: spi@480ba000 {
                        #size-cells = <0>;
                        ti,hwmods = "mcspi4";
                        ti,spi-num-cs = <1>;
+                       dmas = <&sdma 70>, <&sdma 71>;
+                       dma-names = "tx0", "rx0";
                };
 
                mmc1: mmc@4809c000 {
                        ti,hwmods = "mmc1";
                        ti,dual-volt;
                        ti,needs-special-reset;
+                       dmas = <&sdma 61>, <&sdma 62>;
+                       dma-names = "tx", "rx";
                };
 
                mmc2: mmc@480b4000 {
                        interrupts = <0 86 0x4>;
                        ti,hwmods = "mmc2";
                        ti,needs-special-reset;
+                       dmas = <&sdma 47>, <&sdma 48>;
+                       dma-names = "tx", "rx";
                };
 
                mmc3: mmc@480ad000 {
                        interrupts = <0 94 0x4>;
                        ti,hwmods = "mmc3";
                        ti,needs-special-reset;
+                       dmas = <&sdma 77>, <&sdma 78>;
+                       dma-names = "tx", "rx";
                };
 
                mmc4: mmc@480d1000 {
                        interrupts = <0 96 0x4>;
                        ti,hwmods = "mmc4";
                        ti,needs-special-reset;
+                       dmas = <&sdma 57>, <&sdma 58>;
+                       dma-names = "tx", "rx";
                };
 
                mmc5: mmc@480d5000 {
                        interrupts = <0 59 0x4>;
                        ti,hwmods = "mmc5";
                        ti,needs-special-reset;
+                       dmas = <&sdma 59>, <&sdma 60>;
+                       dma-names = "tx", "rx";
                };
 
                wdt2: wdt@4a314000 {
                        reg-names = "mpu", "dma";
                        interrupts = <0 112 0x4>;
                        ti,hwmods = "mcpdm";
+                       dmas = <&sdma 65>,
+                              <&sdma 66>;
+                       dma-names = "up_link", "dn_link";
                };
 
                dmic: dmic@4012e000 {
                        reg-names = "mpu", "dma";
                        interrupts = <0 114 0x4>;
                        ti,hwmods = "dmic";
+                       dmas = <&sdma 67>;
+                       dma-names = "up_link";
                };
 
                mcbsp1: mcbsp@40122000 {
                        interrupt-names = "common";
                        ti,buffer-size = <128>;
                        ti,hwmods = "mcbsp1";
+                       dmas = <&sdma 33>,
+                              <&sdma 34>;
+                       dma-names = "tx", "rx";
                };
 
                mcbsp2: mcbsp@40124000 {
                        interrupt-names = "common";
                        ti,buffer-size = <128>;
                        ti,hwmods = "mcbsp2";
+                       dmas = <&sdma 17>,
+                              <&sdma 18>;
+                       dma-names = "tx", "rx";
                };
 
                mcbsp3: mcbsp@40126000 {
                        interrupt-names = "common";
                        ti,buffer-size = <128>;
                        ti,hwmods = "mcbsp3";
+                       dmas = <&sdma 19>,
+                              <&sdma 20>;
+                       dma-names = "tx", "rx";
                };
 
                mcbsp4: mcbsp@48096000 {
                        interrupt-names = "common";
                        ti,buffer-size = <128>;
                        ti,hwmods = "mcbsp4";
+                       dmas = <&sdma 31>,
+                              <&sdma 32>;
+                       dma-names = "tx", "rx";
                };
 
                keypad: keypad@4a31c000 {
                        #size-cells = <1>;
                        ranges;
                        ti,hwmods = "ocp2scp_usb_phy";
+                       usb2_phy: usb2phy@4a0ad080 {
+                               compatible = "ti,omap-usb2";
+                               reg = <0x4a0ad080 0x58>;
+                               ctrl-module = <&omap_control_usb>;
+                       };
                };
 
                timer1: timer@4a318000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap3430-timer";
                        reg = <0x4a318000 0x80>;
                        interrupts = <0 37 0x4>;
                        ti,hwmods = "timer1";
                };
 
                timer2: timer@48032000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap3430-timer";
                        reg = <0x48032000 0x80>;
                        interrupts = <0 38 0x4>;
                        ti,hwmods = "timer2";
                };
 
                timer3: timer@48034000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap4430-timer";
                        reg = <0x48034000 0x80>;
                        interrupts = <0 39 0x4>;
                        ti,hwmods = "timer3";
                };
 
                timer4: timer@48036000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap4430-timer";
                        reg = <0x48036000 0x80>;
                        interrupts = <0 40 0x4>;
                        ti,hwmods = "timer4";
                };
 
                timer5: timer@40138000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap4430-timer";
                        reg = <0x40138000 0x80>,
                              <0x49038000 0x80>;
                        interrupts = <0 41 0x4>;
                };
 
                timer6: timer@4013a000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap4430-timer";
                        reg = <0x4013a000 0x80>,
                              <0x4903a000 0x80>;
                        interrupts = <0 42 0x4>;
                };
 
                timer7: timer@4013c000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap4430-timer";
                        reg = <0x4013c000 0x80>,
                              <0x4903c000 0x80>;
                        interrupts = <0 43 0x4>;
                };
 
                timer8: timer@4013e000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap4430-timer";
                        reg = <0x4013e000 0x80>,
                              <0x4903e000 0x80>;
                        interrupts = <0 44 0x4>;
                };
 
                timer9: timer@4803e000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap4430-timer";
                        reg = <0x4803e000 0x80>;
                        interrupts = <0 45 0x4>;
                        ti,hwmods = "timer9";
                };
 
                timer10: timer@48086000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap3430-timer";
                        reg = <0x48086000 0x80>;
                        interrupts = <0 46 0x4>;
                        ti,hwmods = "timer10";
                };
 
                timer11: timer@48088000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap4430-timer";
                        reg = <0x48088000 0x80>;
                        interrupts = <0 47 0x4>;
                        ti,hwmods = "timer11";
                        ti,timer-pwm;
                };
+
+               usbhstll: usbhstll@4a062000 {
+                       compatible = "ti,usbhs-tll";
+                       reg = <0x4a062000 0x1000>;
+                       interrupts = <0 78 0x4>;
+                       ti,hwmods = "usb_tll_hs";
+               };
+
+               usbhshost: usbhshost@4a064000 {
+                       compatible = "ti,usbhs-host";
+                       reg = <0x4a064000 0x800>;
+                       ti,hwmods = "usb_host_hs";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       usbhsohci: ohci@4a064800 {
+                               compatible = "ti,ohci-omap3", "usb-ohci";
+                               reg = <0x4a064800 0x400>;
+                               interrupt-parent = <&gic>;
+                               interrupts = <0 76 0x4>;
+                       };
+
+                       usbhsehci: ehci@4a064c00 {
+                               compatible = "ti,ehci-omap", "usb-ehci";
+                               reg = <0x4a064c00 0x400>;
+                               interrupt-parent = <&gic>;
+                               interrupts = <0 77 0x4>;
+                       };
+               };
+
+               omap_control_usb: omap-control-usb@4a002300 {
+                       compatible = "ti,omap-control-usb";
+                       reg = <0x4a002300 0x4>,
+                             <0x4a00233c 0x4>;
+                       reg-names = "control_dev_conf", "otghs_control";
+                       ti,type = <1>;
+               };
+
+               usb_otg_hs: usb_otg_hs@4a0ab000 {
+                       compatible = "ti,omap4-musb";
+                       reg = <0x4a0ab000 0x7ff>;
+                       interrupts = <0 92 0x4>, <0 93 0x4>;
+                       interrupt-names = "mc", "dma";
+                       ti,hwmods = "usb_otg_hs";
+                       usb-phy = <&usb2_phy>;
+                       multipoint = <1>;
+                       num-eps = <16>;
+                       ram-bits = <12>;
+                       ti,has-mailbox;
+               };
        };
 };
diff --git a/arch/arm/boot/dts/omap443x.dtsi b/arch/arm/boot/dts/omap443x.dtsi
new file mode 100644 (file)
index 0000000..cccf39a
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Device Tree Source for OMAP443x SoC
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/include/ "omap4.dtsi"
+
+/ {
+       cpus {
+               cpu@0 {
+                       /* OMAP443x variants OPP50-OPPNT */
+                       operating-points = <
+                               /* kHz    uV */
+                               300000  1025000
+                               600000  1200000
+                               800000  1313000
+                               1008000 1375000
+                       >;
+                       clock-latency = <300000>; /* From legacy driver */
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/omap4460.dtsi b/arch/arm/boot/dts/omap4460.dtsi
new file mode 100644 (file)
index 0000000..7c2c23c
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Device Tree Source for OMAP4460 SoC
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+/include/ "omap4.dtsi"
+
+/ {
+       cpus {
+               /* OMAP446x 'standard device' variants OPP50 to OPPTurbo */
+               cpu@0 {
+                       operating-points = <
+                               /* kHz    uV */
+                               350000   975000
+                               700000  1075000
+                               920000  1200000
+                       >;
+                       clock-latency = <300000>; /* From legacy driver */
+               };
+       };
+
+       pmu {
+               compatible = "arm,cortex-a9-pmu";
+               interrupts = <0 54 0x4>,
+                            <0 55 0x4>;
+               ti,hwmods = "debugss";
+       };
+};
index 8722c15bbba2869a0fcd617517b132d930c05899..982acd19477d94f731740be19de6194e1813832c 100644 (file)
@@ -16,7 +16,7 @@
 
        memory {
                device_type = "memory";
-               reg = <0x80000000 0x80000000>; /* 2 GB */
+               reg = <0x80000000 0x7F000000>; /* 2032 MB */
        };
 
        vmmcsd_fixed: fixedregulator-mmcsd {
                        0x15a 0x100     /* abemcbsp2_clkx.abemcbsp2_clkx INPUT | MODE0 */
                >;
        };
+
+        i2c1_pins: pinmux_i2c1_pins {
+                pinctrl-single,pins = <
+                        0x1b2 0x118        /* i2c1_scl PULLUP | INPUTENABLE | MODE0 */
+                        0x1b4 0x118        /* i2c1_sda PULLUP | INPUTENABLE | MODE0 */
+                >;
+        };
+
+       i2c2_pins: pinmux_i2c2_pins {
+               pinctrl-single,pins = <
+                       0x178 0x100        /* i2c2_scl INPUTENABLE | MODE0 */
+                       0x17a 0x100        /* i2c2_sda INPUTENABLE | MODE0 */
+               >;
+       };
+
+       i2c3_pins: pinmux_i2c3_pins {
+               pinctrl-single,pins = <
+                       0x13a 0x100        /* i2c3_scl INPUTENABLE | MODE0 */
+                       0x13c 0x100     /* i2c3_sda INPUTENABLE | MODE0 */
+               >;
+       };
+
+       i2c4_pins: pinmux_i2c4_pins {
+               pinctrl-single,pins = <
+                       0xb8 0x100        /* i2c4_scl INPUTENABLE | MODE0 */
+                       0xba 0x100     /* i2c4_sda INPUTENABLE | MODE0 */
+               >;
+       };
+
+       i2c5_pins: pinmux_i2c5_pins {
+               pinctrl-single,pins = <
+                       0x184 0x100        /* i2c5_scl INPUTENABLE | MODE0 */
+                       0x186 0x100     /* i2c5_sda INPUTENABLE | MODE0 */
+               >;
+       };
+
+       mcspi2_pins: pinmux_mcspi2_pins {
+               pinctrl-single,pins = <
+                       0xbc 0x100      /*  MCSPI2_CLK INPUTENABLE | MODE0 */
+                       0xbe 0x100      /*  MCSPI2_SIMO INPUTENABLE | MODE0 */
+                       0xc0 0x118      /*  MCSPI2_SOMI PULLUP | INPUTENABLE | MODE0*/
+                       0xc2 0x0        /*  MCSPI2_CS MODE0*/
+               >;
+       };
+
+       mcspi3_pins: pinmux_mcspi3_pins {
+               pinctrl-single,pins = <
+                       0x78 0x101      /*  MCSPI2_SOMI INPUTENABLE | MODE1 */
+                       0x7a 0x101      /*  MCSPI2_CS INPUTENABLE | MODE1 */
+                       0x7c 0x101      /*  MCSPI2_SIMO INPUTENABLE | MODE1 */
+                       0x7e 0x101      /*  MCSPI2_CLK INPUTENABLE | MODE1 */
+               >;
+       };
+
+       mcspi4_pins: pinmux_mcspi4_pins {
+               pinctrl-single,pins = <
+                       0x164 0x101     /*  MCSPI2_CLK INPUTENABLE | MODE1 */
+                       0x168 0x101     /*  MCSPI2_SIMO INPUTENABLE | MODE1 */
+                       0x16a 0x101     /*  MCSPI2_SOMI INPUTENABLE | MODE1 */
+                       0x16c 0x101     /*  MCSPI2_CS INPUTENABLE | MODE1 */
+               >;
+       };
 };
 
 &mmc1 {
        status = "disabled";
 };
 
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c1_pins>;
+
+       clock-frequency = <400000>;
+};
+
 &i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c2_pins>;
+
        clock-frequency = <400000>;
 
        /* Pressure Sensor */
        };
 };
 
+&i2c3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c3_pins>;
+
+       clock-frequency = <400000>;
+};
+
 &i2c4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c4_pins>;
+
        clock-frequency = <400000>;
 
        /* Temperature Sensor */
        };
 };
 
+&i2c5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c5_pins>;
+
+       clock-frequency = <400000>;
+};
+
 &keypad {
        keypad,num-rows = <8>;
        keypad,num-columns = <8>;
        cs1-used;
        device-handle = <&samsung_K3PE0E000B>;
 };
+
+&mcspi1 {
+
+};
+
+&mcspi2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcspi2_pins>;
+};
+
+&mcspi3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcspi3_pins>;
+};
+
+&mcspi4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcspi4_pins>;
+};
index 790bb2a4b3434d47a500005da78ec20d385afd48..3dd7ff825828630ef96ac5ddc2f7f95d532c1242 100644 (file)
@@ -18,6 +18,9 @@
 /include/ "skeleton.dtsi"
 
 / {
+       #address-cells = <1>;
+       #size-cells = <1>;
+
        compatible = "ti,omap5";
        interrupt-parent = <&gic>;
 
        cpus {
                cpu@0 {
                        compatible = "arm,cortex-a15";
-                       timer {
-                               compatible = "arm,armv7-timer";
-                               /* 14th PPI IRQ, active low level-sensitive */
-                               interrupts = <1 14 0x308>;
-                               clock-frequency = <6144000>;
-                       };
                };
                cpu@1 {
                        compatible = "arm,cortex-a15";
-                       timer {
-                               compatible = "arm,armv7-timer";
-                               /* 14th PPI IRQ, active low level-sensitive */
-                               interrupts = <1 14 0x308>;
-                               clock-frequency = <6144000>;
-                       };
                };
        };
 
+       timer {
+               compatible = "arm,armv7-timer";
+               /* PPI secure/nonsecure IRQ, active low level-sensitive */
+               interrupts = <1 13 0x308>,
+                            <1 14 0x308>,
+                            <1 11 0x308>,
+                            <1 10 0x308>;
+               clock-frequency = <6144000>;
+       };
+
+       gic: interrupt-controller@48211000 {
+               compatible = "arm,cortex-a15-gic";
+               interrupt-controller;
+               #interrupt-cells = <3>;
+               reg = <0x48211000 0x1000>,
+                     <0x48212000 0x1000>,
+                     <0x48214000 0x2000>,
+                     <0x48216000 0x2000>;
+       };
+
        /*
         * The soc node represents the soc top level view. It is uses for IPs
         * that are not memory mapped in the MPU view or for the MPU itself.
                #size-cells = <1>;
                ranges;
                ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3";
+               reg = <0x44000000 0x2000>,
+                     <0x44800000 0x3000>,
+                     <0x45000000 0x4000>;
+               interrupts = <0 9 0x4>,
+                            <0 10 0x4>;
 
                counter32k: counter@4ae04000 {
                        compatible = "ti,omap-counter32k";
                        pinctrl-single,function-mask = <0x7fff>;
                };
 
-               gic: interrupt-controller@48211000 {
-                       compatible = "arm,cortex-a15-gic";
-                       interrupt-controller;
-                       #interrupt-cells = <3>;
-                       reg = <0x48211000 0x1000>,
-                             <0x48212000 0x1000>;
+               sdma: dma-controller@4a056000 {
+                       compatible = "ti,omap4430-sdma";
+                       reg = <0x4a056000 0x1000>;
+                       interrupts = <0 12 0x4>,
+                                    <0 13 0x4>,
+                                    <0 14 0x4>,
+                                    <0 15 0x4>;
+                       #dma-cells = <1>;
+                       #dma-channels = <32>;
+                       #dma-requests = <127>;
                };
 
                gpio1: gpio@4ae10000 {
                        reg = <0x4ae10000 0x200>;
                        interrupts = <0 29 0x4>;
                        ti,hwmods = "gpio1";
+                       ti,gpio-always-on;
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                };
 
                gpio2: gpio@48055000 {
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                };
 
                gpio3: gpio@48057000 {
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                };
 
                gpio4: gpio@48059000 {
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                };
 
                gpio5: gpio@4805b000 {
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                };
 
                gpio6: gpio@4805d000 {
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                };
 
                gpio7: gpio@48051000 {
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
                };
 
                gpio8: gpio@48053000 {
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
-                       #interrupt-cells = <1>;
+                       #interrupt-cells = <2>;
+               };
+
+               gpmc: gpmc@50000000 {
+                       compatible = "ti,omap4430-gpmc";
+                       reg = <0x50000000 0x1000>;
+                       #address-cells = <2>;
+                       #size-cells = <1>;
+                       interrupts = <0 20 0x4>;
+                       gpmc,num-cs = <8>;
+                       gpmc,num-waitpins = <4>;
+                       ti,hwmods = "gpmc";
                };
 
                i2c1: i2c@48070000 {
                        ti,hwmods = "i2c5";
                };
 
+               mcspi1: spi@48098000 {
+                       compatible = "ti,omap4-mcspi";
+                       reg = <0x48098000 0x200>;
+                       interrupts = <0 65 0x4>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "mcspi1";
+                       ti,spi-num-cs = <4>;
+                       dmas = <&sdma 35>,
+                              <&sdma 36>,
+                              <&sdma 37>,
+                              <&sdma 38>,
+                              <&sdma 39>,
+                              <&sdma 40>,
+                              <&sdma 41>,
+                              <&sdma 42>;
+                       dma-names = "tx0", "rx0", "tx1", "rx1",
+                                   "tx2", "rx2", "tx3", "rx3";
+               };
+
+               mcspi2: spi@4809a000 {
+                       compatible = "ti,omap4-mcspi";
+                       reg = <0x4809a000 0x200>;
+                       interrupts = <0 66 0x4>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "mcspi2";
+                       ti,spi-num-cs = <2>;
+                       dmas = <&sdma 43>,
+                              <&sdma 44>,
+                              <&sdma 45>,
+                              <&sdma 46>;
+                       dma-names = "tx0", "rx0", "tx1", "rx1";
+               };
+
+               mcspi3: spi@480b8000 {
+                       compatible = "ti,omap4-mcspi";
+                       reg = <0x480b8000 0x200>;
+                       interrupts = <0 91 0x4>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "mcspi3";
+                       ti,spi-num-cs = <2>;
+                       dmas = <&sdma 15>, <&sdma 16>;
+                       dma-names = "tx0", "rx0";
+               };
+
+               mcspi4: spi@480ba000 {
+                       compatible = "ti,omap4-mcspi";
+                       reg = <0x480ba000 0x200>;
+                       interrupts = <0 48 0x4>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "mcspi4";
+                       ti,spi-num-cs = <1>;
+                       dmas = <&sdma 70>, <&sdma 71>;
+                       dma-names = "tx0", "rx0";
+               };
+
                uart1: serial@4806a000 {
                        compatible = "ti,omap4-uart";
                        reg = <0x4806a000 0x100>;
                        ti,hwmods = "mmc1";
                        ti,dual-volt;
                        ti,needs-special-reset;
+                       dmas = <&sdma 61>, <&sdma 62>;
+                       dma-names = "tx", "rx";
                };
 
                mmc2: mmc@480b4000 {
                        interrupts = <0 86 0x4>;
                        ti,hwmods = "mmc2";
                        ti,needs-special-reset;
+                       dmas = <&sdma 47>, <&sdma 48>;
+                       dma-names = "tx", "rx";
                };
 
                mmc3: mmc@480ad000 {
                        interrupts = <0 94 0x4>;
                        ti,hwmods = "mmc3";
                        ti,needs-special-reset;
+                       dmas = <&sdma 77>, <&sdma 78>;
+                       dma-names = "tx", "rx";
                };
 
                mmc4: mmc@480d1000 {
                        interrupts = <0 96 0x4>;
                        ti,hwmods = "mmc4";
                        ti,needs-special-reset;
+                       dmas = <&sdma 57>, <&sdma 58>;
+                       dma-names = "tx", "rx";
                };
 
                mmc5: mmc@480d5000 {
                        interrupts = <0 59 0x4>;
                        ti,hwmods = "mmc5";
                        ti,needs-special-reset;
+                       dmas = <&sdma 59>, <&sdma 60>;
+                       dma-names = "tx", "rx";
                };
 
                keypad: keypad@4ae1c000 {
                        compatible = "ti,omap4-keypad";
+                       reg = <0x4ae1c000 0x400>;
                        ti,hwmods = "kbd";
                };
 
                        reg-names = "mpu", "dma";
                        interrupts = <0 112 0x4>;
                        ti,hwmods = "mcpdm";
+                       dmas = <&sdma 65>,
+                              <&sdma 66>;
+                       dma-names = "up_link", "dn_link";
                };
 
                dmic: dmic@4012e000 {
                        reg-names = "mpu", "dma";
                        interrupts = <0 114 0x4>;
                        ti,hwmods = "dmic";
+                       dmas = <&sdma 67>;
+                       dma-names = "up_link";
                };
 
                mcbsp1: mcbsp@40122000 {
                        interrupt-names = "common";
                        ti,buffer-size = <128>;
                        ti,hwmods = "mcbsp1";
+                       dmas = <&sdma 33>,
+                              <&sdma 34>;
+                       dma-names = "tx", "rx";
                };
 
                mcbsp2: mcbsp@40124000 {
                        interrupt-names = "common";
                        ti,buffer-size = <128>;
                        ti,hwmods = "mcbsp2";
+                       dmas = <&sdma 17>,
+                              <&sdma 18>;
+                       dma-names = "tx", "rx";
                };
 
                mcbsp3: mcbsp@40126000 {
                        interrupt-names = "common";
                        ti,buffer-size = <128>;
                        ti,hwmods = "mcbsp3";
+                       dmas = <&sdma 19>,
+                              <&sdma 20>;
+                       dma-names = "tx", "rx";
                };
 
                timer1: timer@4ae18000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap5430-timer";
                        reg = <0x4ae18000 0x80>;
                        interrupts = <0 37 0x4>;
                        ti,hwmods = "timer1";
                };
 
                timer2: timer@48032000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap5430-timer";
                        reg = <0x48032000 0x80>;
                        interrupts = <0 38 0x4>;
                        ti,hwmods = "timer2";
                };
 
                timer3: timer@48034000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap5430-timer";
                        reg = <0x48034000 0x80>;
                        interrupts = <0 39 0x4>;
                        ti,hwmods = "timer3";
                };
 
                timer4: timer@48036000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap5430-timer";
                        reg = <0x48036000 0x80>;
                        interrupts = <0 40 0x4>;
                        ti,hwmods = "timer4";
                };
 
                timer5: timer@40138000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap5430-timer";
                        reg = <0x40138000 0x80>,
                              <0x49038000 0x80>;
                        interrupts = <0 41 0x4>;
                };
 
                timer6: timer@4013a000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap5430-timer";
                        reg = <0x4013a000 0x80>,
                              <0x4903a000 0x80>;
                        interrupts = <0 42 0x4>;
                };
 
                timer7: timer@4013c000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap5430-timer";
                        reg = <0x4013c000 0x80>,
                              <0x4903c000 0x80>;
                        interrupts = <0 43 0x4>;
                };
 
                timer8: timer@4013e000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap5430-timer";
                        reg = <0x4013e000 0x80>,
                              <0x4903e000 0x80>;
                        interrupts = <0 44 0x4>;
                };
 
                timer9: timer@4803e000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap5430-timer";
                        reg = <0x4803e000 0x80>;
                        interrupts = <0 45 0x4>;
                        ti,hwmods = "timer9";
                };
 
                timer10: timer@48086000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap5430-timer";
                        reg = <0x48086000 0x80>;
                        interrupts = <0 46 0x4>;
                        ti,hwmods = "timer10";
                };
 
                timer11: timer@48088000 {
-                       compatible = "ti,omap2-timer";
+                       compatible = "ti,omap5430-timer";
                        reg = <0x48088000 0x80>;
                        interrupts = <0 47 0x4>;
                        ti,hwmods = "timer11";
                        ti,timer-pwm;
                };
 
+               wdt2: wdt@4ae14000 {
+                       compatible = "ti,omap5-wdt", "ti,omap3-wdt";
+                       reg = <0x4ae14000 0x80>;
+                       interrupts = <0 80 0x4>;
+                       ti,hwmods = "wd_timer2";
+               };
+
                emif1: emif@0x4c000000 {
                        compatible      = "ti,emif-4d5";
                        ti,hwmods       = "emif1";
                        hw-caps-ll-interface;
                        hw-caps-temp-alert;
                };
+
+               omap_control_usb: omap-control-usb@4a002300 {
+                       compatible = "ti,omap-control-usb";
+                       reg = <0x4a002300 0x4>,
+                             <0x4a002370 0x4>;
+                       reg-names = "control_dev_conf", "phy_power_usb";
+                       ti,type = <2>;
+               };
+
+               omap_dwc3@4a020000 {
+                       compatible = "ti,dwc3";
+                       ti,hwmods = "usb_otg_ss";
+                       reg = <0x4a020000 0x1000>;
+                       interrupts = <0 93 4>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       utmi-mode = <2>;
+                       ranges;
+                       dwc3@4a030000 {
+                               compatible = "synopsys,dwc3";
+                               reg = <0x4a030000 0x1000>;
+                               interrupts = <0 92 4>;
+                               usb-phy = <&usb2_phy>, <&usb3_phy>;
+                               tx-fifo-resize;
+                       };
+               };
+
+               ocp2scp {
+                       compatible = "ti,omap-ocp2scp";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+                       ti,hwmods = "ocp2scp1";
+                       usb2_phy: usb2phy@4a084000 {
+                               compatible = "ti,omap-usb2";
+                               reg = <0x4a084000 0x7c>;
+                               ctrl-module = <&omap_control_usb>;
+                       };
+
+                       usb3_phy: usb3phy@4a084400 {
+                               compatible = "ti,omap-usb3";
+                               reg = <0x4a084400 0x80>,
+                                     <0x4a084800 0x64>,
+                                     <0x4a084c00 0x40>;
+                               reg-names = "phy_rx", "phy_tx", "pll_ctrl";
+                               ctrl-module = <&omap_control_usb>;
+                       };
+               };
        };
 };
index a30aca62658ad192691dc81800f9a1f27fe6cb1e..72c1f27af7f37da20524ee92504192aa3e4b6169 100644 (file)
                reg = <0x80000000 0x40000000>;
        };
 
+       pinmux {
+               pinctrl-names = "default";
+               pinctrl-0 = <&state_default>;
+
+               state_default: pinmux {
+                       clk1_out_pw4 {
+                               nvidia,pins = "clk1_out_pw4";
+                               nvidia,function = "extperiph1";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       dap1_din_pn1 {
+                               nvidia,pins = "dap1_din_pn1";
+                               nvidia,function = "i2s0";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <1>;
+                               nvidia,enable-input = <1>;
+                       };
+                       dap1_dout_pn2 {
+                               nvidia,pins = "dap1_dout_pn2",
+                                               "dap1_fs_pn0",
+                                               "dap1_sclk_pn3";
+                               nvidia,function = "i2s0";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       dap2_din_pa4 {
+                               nvidia,pins = "dap2_din_pa4";
+                               nvidia,function = "i2s1";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <1>;
+                               nvidia,enable-input = <1>;
+                       };
+                       dap2_dout_pa5 {
+                               nvidia,pins = "dap2_dout_pa5",
+                                               "dap2_fs_pa2",
+                                               "dap2_sclk_pa3";
+                               nvidia,function = "i2s1";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       dap4_din_pp5 {
+                               nvidia,pins = "dap4_din_pp5",
+                                               "dap4_dout_pp6",
+                                               "dap4_fs_pp4",
+                                               "dap4_sclk_pp7";
+                               nvidia,function = "i2s3";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       dvfs_pwm_px0 {
+                               nvidia,pins = "dvfs_pwm_px0",
+                                               "dvfs_clk_px2";
+                               nvidia,function = "cldvfs";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       ulpi_clk_py0 {
+                               nvidia,pins = "ulpi_clk_py0",
+                                               "ulpi_data0_po1",
+                                               "ulpi_data1_po2",
+                                               "ulpi_data2_po3",
+                                               "ulpi_data3_po4",
+                                               "ulpi_data4_po5",
+                                               "ulpi_data5_po6",
+                                               "ulpi_data6_po7",
+                                               "ulpi_data7_po0";
+                               nvidia,function = "ulpi";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       ulpi_dir_py1 {
+                               nvidia,pins = "ulpi_dir_py1",
+                                               "ulpi_nxt_py2";
+                               nvidia,function = "ulpi";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <1>;
+                               nvidia,enable-input = <1>;
+                       };
+                       ulpi_stp_py3 {
+                               nvidia,pins = "ulpi_stp_py3";
+                               nvidia,function = "ulpi";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       cam_i2c_scl_pbb1 {
+                               nvidia,pins = "cam_i2c_scl_pbb1",
+                                               "cam_i2c_sda_pbb2";
+                               nvidia,function = "i2c3";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                               nvidia,lock = <0>;
+                               nvidia,open-drain = <0>;
+                       };
+                       cam_mclk_pcc0 {
+                               nvidia,pins = "cam_mclk_pcc0",
+                                               "pbb0";
+                               nvidia,function = "vi_alt3";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                               nvidia,lock = <0>;
+                       };
+                       gen2_i2c_scl_pt5 {
+                               nvidia,pins = "gen2_i2c_scl_pt5",
+                                               "gen2_i2c_sda_pt6";
+                               nvidia,function = "i2c2";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                               nvidia,lock = <0>;
+                               nvidia,open-drain = <0>;
+                       };
+                       gmi_a16_pj7 {
+                               nvidia,pins = "gmi_a16_pj7";
+                               nvidia,function = "uartd";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       gmi_a17_pb0 {
+                               nvidia,pins = "gmi_a17_pb0",
+                                               "gmi_a18_pb1";
+                               nvidia,function = "uartd";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <1>;
+                               nvidia,enable-input = <1>;
+                       };
+                       gmi_a19_pk7 {
+                               nvidia,pins = "gmi_a19_pk7";
+                               nvidia,function = "uartd";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       gmi_ad5_pg5 {
+                               nvidia,pins = "gmi_ad5_pg5",
+                                               "gmi_cs6_n_pi3",
+                                               "gmi_wr_n_pi0";
+                               nvidia,function = "spi4";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       gmi_ad6_pg6 {
+                               nvidia,pins = "gmi_ad6_pg6",
+                                               "gmi_ad7_pg7";
+                               nvidia,function = "spi4";
+                               nvidia,pull = <2>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       gmi_ad12_ph4 {
+                               nvidia,pins = "gmi_ad12_ph4";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       gmi_ad9_ph1 {
+                               nvidia,pins = "gmi_ad9_ph1";
+                               nvidia,function = "pwm1";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       gmi_cs1_n_pj2 {
+                               nvidia,pins = "gmi_cs1_n_pj2",
+                                               "gmi_oe_n_pi1";
+                               nvidia,function = "soc";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <1>;
+                               nvidia,enable-input = <1>;
+                       };
+                       clk2_out_pw5 {
+                               nvidia,pins = "clk2_out_pw5";
+                               nvidia,function = "extperiph2";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       sdmmc1_clk_pz0 {
+                               nvidia,pins = "sdmmc1_clk_pz0";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       sdmmc1_cmd_pz1 {
+                               nvidia,pins = "sdmmc1_cmd_pz1",
+                                               "sdmmc1_dat0_py7",
+                                               "sdmmc1_dat1_py6",
+                                               "sdmmc1_dat2_py5",
+                                               "sdmmc1_dat3_py4";
+                               nvidia,function = "sdmmc1";
+                               nvidia,pull = <2>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       sdmmc1_wp_n_pv3 {
+                               nvidia,pins = "sdmmc1_wp_n_pv3";
+                               nvidia,function = "spi4";
+                               nvidia,pull = <2>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       sdmmc3_clk_pa6 {
+                               nvidia,pins = "sdmmc3_clk_pa6";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       sdmmc3_cmd_pa7 {
+                               nvidia,pins = "sdmmc3_cmd_pa7",
+                                               "sdmmc3_dat0_pb7",
+                                               "sdmmc3_dat1_pb6",
+                                               "sdmmc3_dat2_pb5",
+                                               "sdmmc3_dat3_pb4",
+                                               "kb_col4_pq4",
+                                               "sdmmc3_clk_lb_out_pee4",
+                                               "sdmmc3_clk_lb_in_pee5";
+                               nvidia,function = "sdmmc3";
+                               nvidia,pull = <2>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       sdmmc4_clk_pcc4 {
+                               nvidia,pins = "sdmmc4_clk_pcc4";
+                               nvidia,function = "sdmmc4";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       sdmmc4_cmd_pt7 {
+                               nvidia,pins = "sdmmc4_cmd_pt7",
+                                               "sdmmc4_dat0_paa0",
+                                               "sdmmc4_dat1_paa1",
+                                               "sdmmc4_dat2_paa2",
+                                               "sdmmc4_dat3_paa3",
+                                               "sdmmc4_dat4_paa4",
+                                               "sdmmc4_dat5_paa5",
+                                               "sdmmc4_dat6_paa6",
+                                               "sdmmc4_dat7_paa7";
+                               nvidia,function = "sdmmc4";
+                               nvidia,pull = <2>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       clk_32k_out_pa0 {
+                               nvidia,pins = "clk_32k_out_pa0";
+                               nvidia,function = "blink";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       kb_col0_pq0 {
+                               nvidia,pins = "kb_col0_pq0",
+                                               "kb_col1_pq1",
+                                               "kb_col2_pq2",
+                                               "kb_row0_pr0",
+                                               "kb_row1_pr1",
+                                               "kb_row2_pr2";
+                               nvidia,function = "kbc";
+                               nvidia,pull = <2>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       dap3_din_pp1 {
+                               nvidia,pins = "dap3_din_pp1",
+                                               "dap3_sclk_pp3";
+                               nvidia,function = "displayb";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <1>;
+                               nvidia,enable-input = <0>;
+                       };
+                       pv0 {
+                               nvidia,pins = "pv0";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <1>;
+                               nvidia,enable-input = <0>;
+                       };
+                       kb_row7_pr7 {
+                               nvidia,pins = "kb_row7_pr7";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <2>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       kb_row10_ps2 {
+                               nvidia,pins = "kb_row10_ps2";
+                               nvidia,function = "uarta";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <1>;
+                               nvidia,enable-input = <1>;
+                       };
+                       kb_row9_ps1 {
+                               nvidia,pins = "kb_row9_ps1";
+                               nvidia,function = "uarta";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       pwr_i2c_scl_pz6 {
+                               nvidia,pins = "pwr_i2c_scl_pz6",
+                                               "pwr_i2c_sda_pz7";
+                               nvidia,function = "i2cpwr";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                               nvidia,lock = <0>;
+                               nvidia,open-drain = <0>;
+                       };
+                       sys_clk_req_pz5 {
+                               nvidia,pins = "sys_clk_req_pz5";
+                               nvidia,function = "sysclk";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       core_pwr_req {
+                               nvidia,pins = "core_pwr_req";
+                               nvidia,function = "pwron";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       cpu_pwr_req {
+                               nvidia,pins = "cpu_pwr_req";
+                               nvidia,function = "cpu";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       pwr_int_n {
+                               nvidia,pins = "pwr_int_n";
+                               nvidia,function = "pmi";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <1>;
+                               nvidia,enable-input = <1>;
+                       };
+                       reset_out_n {
+                               nvidia,pins = "reset_out_n";
+                               nvidia,function = "reset_out_n";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       clk3_out_pee0 {
+                               nvidia,pins = "clk3_out_pee0";
+                               nvidia,function = "extperiph3";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       gen1_i2c_scl_pc4 {
+                               nvidia,pins = "gen1_i2c_scl_pc4",
+                                               "gen1_i2c_sda_pc5";
+                               nvidia,function = "i2c1";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                               nvidia,lock = <0>;
+                               nvidia,open-drain = <0>;
+                       };
+                       uart2_cts_n_pj5 {
+                               nvidia,pins = "uart2_cts_n_pj5";
+                               nvidia,function = "uartb";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <1>;
+                               nvidia,enable-input = <1>;
+                       };
+                       uart2_rts_n_pj6 {
+                               nvidia,pins = "uart2_rts_n_pj6";
+                               nvidia,function = "uartb";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       uart2_rxd_pc3 {
+                               nvidia,pins = "uart2_rxd_pc3";
+                               nvidia,function = "irda";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <1>;
+                               nvidia,enable-input = <1>;
+                       };
+                       uart2_txd_pc2 {
+                               nvidia,pins = "uart2_txd_pc2";
+                               nvidia,function = "irda";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       uart3_cts_n_pa1 {
+                               nvidia,pins = "uart3_cts_n_pa1",
+                                               "uart3_rxd_pw7";
+                               nvidia,function = "uartc";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <1>;
+                               nvidia,enable-input = <1>;
+                       };
+                       uart3_rts_n_pc0 {
+                               nvidia,pins = "uart3_rts_n_pc0",
+                                               "uart3_txd_pw6";
+                               nvidia,function = "uartc";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       owr {
+                               nvidia,pins = "owr";
+                               nvidia,function = "owr";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       hdmi_cec_pee3 {
+                               nvidia,pins = "hdmi_cec_pee3";
+                               nvidia,function = "cec";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                               nvidia,lock = <0>;
+                               nvidia,open-drain = <0>;
+                       };
+                       ddc_scl_pv4 {
+                               nvidia,pins = "ddc_scl_pv4",
+                                               "ddc_sda_pv5";
+                               nvidia,function = "i2c4";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                               nvidia,lock = <0>;
+                               nvidia,rcv-sel = <1>;
+                       };
+                       spdif_in_pk6 {
+                               nvidia,pins = "spdif_in_pk6";
+                               nvidia,function = "usb";
+                               nvidia,pull = <2>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                               nvidia,lock = <0>;
+                       };
+                       usb_vbus_en0_pn4 {
+                               nvidia,pins = "usb_vbus_en0_pn4";
+                               nvidia,function = "usb";
+                               nvidia,pull = <2>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                               nvidia,lock = <0>;
+                               nvidia,open-drain = <1>;
+                       };
+                       gpio_x6_aud_px6 {
+                               nvidia,pins = "gpio_x6_aud_px6";
+                               nvidia,function = "spi6";
+                               nvidia,pull = <2>;
+                               nvidia,tristate = <1>;
+                               nvidia,enable-input = <1>;
+                       };
+                       gpio_x4_aud_px4 {
+                               nvidia,pins = "gpio_x4_aud_px4",
+                                               "gpio_x7_aud_px7";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <1>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       gpio_x5_aud_px5 {
+                               nvidia,pins = "gpio_x5_aud_px5";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <2>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       gpio_w2_aud_pw2 {
+                               nvidia,pins = "gpio_w2_aud_pw2";
+                               nvidia,function = "rsvd2";
+                               nvidia,pull = <2>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       gpio_w3_aud_pw3 {
+                               nvidia,pins = "gpio_w3_aud_pw3";
+                               nvidia,function = "spi6";
+                               nvidia,pull = <2>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       gpio_x1_aud_px1 {
+                               nvidia,pins = "gpio_x1_aud_px1";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <1>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       gpio_x3_aud_px3 {
+                               nvidia,pins = "gpio_x3_aud_px3";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <2>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       dap3_fs_pp0 {
+                               nvidia,pins = "dap3_fs_pp0";
+                               nvidia,function = "i2s2";
+                               nvidia,pull = <1>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       dap3_dout_pp2 {
+                               nvidia,pins = "dap3_dout_pp2";
+                               nvidia,function = "i2s2";
+                               nvidia,pull = <1>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       pv1 {
+                               nvidia,pins = "pv1";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       pbb3 {
+                               nvidia,pins = "pbb3",
+                                               "pbb5",
+                                               "pbb6",
+                                               "pbb7";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <1>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       pcc1 {
+                               nvidia,pins = "pcc1",
+                                               "pcc2";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <1>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       gmi_ad0_pg0 {
+                               nvidia,pins = "gmi_ad0_pg0",
+                                               "gmi_ad1_pg1";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       gmi_ad10_ph2 {
+                               nvidia,pins = "gmi_ad10_ph2",
+                                               "gmi_ad11_ph3",
+                                               "gmi_ad13_ph5",
+                                               "gmi_ad8_ph0",
+                                               "gmi_clk_pk1";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <1>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       gmi_ad2_pg2 {
+                               nvidia,pins = "gmi_ad2_pg2",
+                                               "gmi_ad3_pg3";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       gmi_adv_n_pk0 {
+                               nvidia,pins = "gmi_adv_n_pk0",
+                                               "gmi_cs0_n_pj0",
+                                               "gmi_cs2_n_pk3",
+                                               "gmi_cs4_n_pk2",
+                                               "gmi_cs7_n_pi6",
+                                               "gmi_dqs_p_pj3",
+                                               "gmi_iordy_pi5",
+                                               "gmi_wp_n_pc7";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <2>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       gmi_cs3_n_pk4 {
+                               nvidia,pins = "gmi_cs3_n_pk4";
+                               nvidia,function = "gmi";
+                               nvidia,pull = <2>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       clk2_req_pcc5 {
+                               nvidia,pins = "clk2_req_pcc5";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       kb_col3_pq3 {
+                               nvidia,pins = "kb_col3_pq3",
+                                               "kb_col6_pq6",
+                                               "kb_col7_pq7";
+                               nvidia,function = "kbc";
+                               nvidia,pull = <2>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       kb_col5_pq5 {
+                               nvidia,pins = "kb_col5_pq5";
+                               nvidia,function = "kbc";
+                               nvidia,pull = <2>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       kb_row3_pr3 {
+                               nvidia,pins = "kb_row3_pr3",
+                                               "kb_row4_pr4",
+                                               "kb_row6_pr6",
+                                               "kb_row8_ps0";
+                               nvidia,function = "kbc";
+                               nvidia,pull = <1>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       clk3_req_pee1 {
+                               nvidia,pins = "clk3_req_pee1";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       pu4 {
+                               nvidia,pins = "pu4";
+                               nvidia,function = "displayb";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <0>;
+                       };
+                       pu5 {
+                               nvidia,pins = "pu5",
+                                               "pu6";
+                               nvidia,function = "displayb";
+                               nvidia,pull = <0>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       hdmi_int_pn7 {
+                               nvidia,pins = "hdmi_int_pn7";
+                               nvidia,function = "rsvd1";
+                               nvidia,pull = <1>;
+                               nvidia,tristate = <0>;
+                               nvidia,enable-input = <1>;
+                       };
+                       clk1_req_pee2 {
+                               nvidia,pins = "clk1_req_pee2",
+                                               "usb_vbus_en1_pn5";
+                               nvidia,function = "rsvd4";
+                               nvidia,pull = <1>;
+                               nvidia,tristate = <1>;
+                               nvidia,enable-input = <0>;
+                       };
+
+                       drive_sdio1 {
+                               nvidia,pins = "drive_sdio1";
+                               nvidia,high-speed-mode = <1>;
+                               nvidia,schmitt = <0>;
+                               nvidia,low-power-mode = <3>;
+                               nvidia,pull-down-strength = <36>;
+                               nvidia,pull-up-strength = <20>;
+                               nvidia,slew-rate-rising = <2>;
+                               nvidia,slew-rate-falling = <2>;
+                       };
+                       drive_sdio3 {
+                               nvidia,pins = "drive_sdio3";
+                               nvidia,high-speed-mode = <1>;
+                               nvidia,schmitt = <0>;
+                               nvidia,low-power-mode = <3>;
+                               nvidia,pull-down-strength = <22>;
+                               nvidia,pull-up-strength = <36>;
+                               nvidia,slew-rate-rising = <0>;
+                               nvidia,slew-rate-falling = <0>;
+                       };
+                       drive_gma {
+                               nvidia,pins = "drive_gma";
+                               nvidia,high-speed-mode = <1>;
+                               nvidia,schmitt = <0>;
+                               nvidia,low-power-mode = <3>;
+                               nvidia,pull-down-strength = <2>;
+                               nvidia,pull-up-strength = <1>;
+                               nvidia,slew-rate-rising = <0>;
+                               nvidia,slew-rate-falling = <0>;
+                               nvidia,drive-type = <1>;
+                       };
+               };
+       };
+
        serial@70006300 {
                status = "okay";
-               clock-frequency = <408000000>;
+       };
+
+       i2c@7000c000 {
+               status = "okay";
+               clock-frequency = <100000>;
+
+               battery: smart-battery {
+                       compatible = "ti,bq20z45", "sbs,sbs-battery";
+                       reg = <0xb>;
+                       battery-name = "battery";
+                       sbs,i2c-retry-count = <2>;
+                       sbs,poll-retry-count = <100>;
+               };
+       };
+
+       i2c@7000d000 {
+               status = "okay";
+               clock-frequency = <400000>;
+
+               tps51632 {
+                       compatible = "ti,tps51632";
+                       reg = <0x43>;
+                       regulator-name = "vdd-cpu";
+                       regulator-min-microvolt = <500000>;
+                       regulator-max-microvolt = <1520000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               tps65090 {
+                       compatible = "ti,tps65090";
+                       reg = <0x48>;
+                       interrupt-parent = <&gpio>;
+                       interrupts = <72 0x04>; /* gpio PJ0 */
+
+                       vsys1-supply = <&vdd_ac_bat_reg>;
+                       vsys2-supply = <&vdd_ac_bat_reg>;
+                       vsys3-supply = <&vdd_ac_bat_reg>;
+                       infet1-supply = <&vdd_ac_bat_reg>;
+                       infet2-supply = <&vdd_ac_bat_reg>;
+                       infet3-supply = <&tps65090_dcdc2_reg>;
+                       infet4-supply = <&tps65090_dcdc2_reg>;
+                       infet5-supply = <&tps65090_dcdc2_reg>;
+                       infet6-supply = <&tps65090_dcdc2_reg>;
+                       infet7-supply = <&tps65090_dcdc2_reg>;
+                       vsys-l1-supply = <&vdd_ac_bat_reg>;
+                       vsys-l2-supply = <&vdd_ac_bat_reg>;
+
+                       regulators {
+                               tps65090_dcdc1_reg: dcdc1 {
+                                       regulator-name = "vdd-sys-5v0";
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               tps65090_dcdc2_reg: dcdc2 {
+                                       regulator-name = "vdd-sys-3v3";
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               dcdc3 {
+                                       regulator-name = "vdd-ao";
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               fet1 {
+                                       regulator-name = "vdd-lcd-bl";
+                               };
+
+                               fet3 {
+                                       regulator-name = "vdd-modem-3v3";
+                               };
+
+                               fet4 {
+                                       regulator-name = "avdd-lcd";
+                               };
+
+                               fet5 {
+                                       regulator-name = "vdd-lvds";
+                               };
+
+                               fet6 {
+                                       regulator-name = "vdd-sd-slot";
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               fet7 {
+                                       regulator-name = "vdd-com-3v3";
+                               };
+
+                               ldo1 {
+                                       regulator-name = "vdd-sby-5v0";
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+
+                               ldo2 {
+                                       regulator-name = "vdd-sby-3v3";
+                                       regulator-always-on;
+                                       regulator-boot-on;
+                               };
+                       };
+               };
        };
 
        pmc {
                nvidia,invert-interrupt;
        };
+
+       sdhci@78000400 {
+               cd-gpios = <&gpio 170 1>; /* gpio PV2 */
+               bus-width = <4>;
+               status = "okay";
+       };
+
+       sdhci@78000600 {
+               bus-width = <8>;
+               status = "okay";
+               non-removable;
+       };
+
+       clocks {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               clk32k_in: clock {
+                       compatible = "fixed-clock";
+                       reg=<0>;
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+               };
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               vdd_ac_bat_reg: regulator@0 {
+                       compatible = "regulator-fixed";
+                       reg = <0>;
+                       regulator-name = "vdd_ac_bat";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       regulator-always-on;
+               };
+
+               dvdd_ts_reg: regulator@1 {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "dvdd_ts";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       enable-active-high;
+                       gpio = <&gpio 61 0>; /* GPIO PH5 */
+               };
+
+               lcd_bl_en_reg: regulator@2 {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "lcd_bl_en";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       gpio = <&gpio 58 0>; /* GPIO PH2 */
+               };
+
+               usb1_vbus_reg: regulator@3 {
+                       compatible = "regulator-fixed";
+                       reg = <3>;
+                       regulator-name = "usb1_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       gpio = <&gpio 108 0>; /* GPIO PN4 */
+                       gpio-open-drain;
+                       vin-supply = <&tps65090_dcdc1_reg>;
+               };
+
+               usb3_vbus_reg: regulator@4 {
+                       compatible = "regulator-fixed";
+                       reg = <4>;
+                       regulator-name = "usb2_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       gpio = <&gpio 86 0>; /* GPIO PK6 */
+                       gpio-open-drain;
+                       vin-supply = <&tps65090_dcdc1_reg>;
+               };
+
+               vdd_hdmi_reg: regulator@5 {
+                       compatible = "regulator-fixed";
+                       reg = <5>;
+                       regulator-name = "vdd_hdmi_5v0";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       enable-active-high;
+                       gpio = <&gpio 81 0>; /* GPIO PK1 */
+                       vin-supply = <&tps65090_dcdc1_reg>;
+               };
+       };
 };
index 9bea8f57aa47f6010441066dee01367df3887153..6bbc8efae9c0e88018c35bb4465db3f7c19801e5 100644 (file)
 
        serial@70006300 {
                status = "okay";
-               clock-frequency = <408000000>;
        };
 
        pmc {
                nvidia,invert-interrupt;
        };
+
+       clocks {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               clk32k_in: clock {
+                       compatible = "fixed-clock";
+                       reg=<0>;
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+               };
+       };
 };
index 1dfaf2874c57261a2c108073ed47d2131c3188eb..629415ffd8dc8c893781195b00aa479f61775f2f 100644 (file)
@@ -4,6 +4,13 @@
        compatible = "nvidia,tegra114";
        interrupt-parent = <&gic>;
 
+       aliases {
+               serial0 = &uarta;
+               serial1 = &uartb;
+               serial2 = &uartc;
+               serial3 = &uartd;
+       };
+
        gic: interrupt-controller {
                compatible = "arm,cortex-a15-gic";
                #interrupt-cells = <3>;
                              0 42 0x04
                              0 121 0x04
                              0 122 0x04>;
+               clocks = <&tegra_car 5>;
        };
 
        tegra_car: clock {
-               compatible = "nvidia,tegra114-car, nvidia,tegra30-car";
+               compatible = "nvidia,tegra114-car";
                reg = <0x60006000 0x1000>;
                #clock-cells = <1>;
        };
 
+       apbdma: dma {
+               compatible = "nvidia,tegra114-apbdma";
+               reg = <0x6000a000 0x1400>;
+               interrupts = <0 104 0x04
+                             0 105 0x04
+                             0 106 0x04
+                             0 107 0x04
+                             0 108 0x04
+                             0 109 0x04
+                             0 110 0x04
+                             0 111 0x04
+                             0 112 0x04
+                             0 113 0x04
+                             0 114 0x04
+                             0 115 0x04
+                             0 116 0x04
+                             0 117 0x04
+                             0 118 0x04
+                             0 119 0x04
+                             0 128 0x04
+                             0 129 0x04
+                             0 130 0x04
+                             0 131 0x04
+                             0 132 0x04
+                             0 133 0x04
+                             0 134 0x04
+                             0 135 0x04
+                             0 136 0x04
+                             0 137 0x04
+                             0 138 0x04
+                             0 139 0x04
+                             0 140 0x04
+                             0 141 0x04
+                             0 142 0x04
+                             0 143 0x04>;
+               clocks = <&tegra_car 34>;
+       };
+
        ahb: ahb {
                compatible = "nvidia,tegra114-ahb", "nvidia,tegra30-ahb";
                reg = <0x6000c004 0x14c>;
                       0x70003000 0x40c>;       /* Mux registers */
        };
 
-       serial@70006000 {
+       /*
+        * There are two serial driver i.e. 8250 based simple serial
+        * driver and APB DMA based serial driver for higher baudrate
+        * and performace. To enable the 8250 based driver, the compatible
+        * is "nvidia,tegra114-uart", "nvidia,tegra20-uart" and to enable
+        * the APB DMA based serial driver, the comptible is
+        * "nvidia,tegra114-hsuart", "nvidia,tegra30-hsuart".
+        */
+       uarta: serial@70006000 {
                compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart";
                reg = <0x70006000 0x40>;
                reg-shift = <2>;
                interrupts = <0 36 0x04>;
+               nvidia,dma-request-selector = <&apbdma 8>;
                status = "disabled";
+               clocks = <&tegra_car 6>;
        };
 
-       serial@70006040 {
+       uartb: serial@70006040 {
                compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart";
                reg = <0x70006040 0x40>;
                reg-shift = <2>;
                interrupts = <0 37 0x04>;
+               nvidia,dma-request-selector = <&apbdma 9>;
                status = "disabled";
+               clocks = <&tegra_car 192>;
        };
 
-       serial@70006200 {
+       uartc: serial@70006200 {
                compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart";
                reg = <0x70006200 0x100>;
                reg-shift = <2>;
                interrupts = <0 46 0x04>;
+               nvidia,dma-request-selector = <&apbdma 10>;
                status = "disabled";
+               clocks = <&tegra_car 55>;
        };
 
-       serial@70006300 {
+       uartd: serial@70006300 {
                compatible = "nvidia,tegra114-uart", "nvidia,tegra20-uart";
                reg = <0x70006300 0x100>;
                reg-shift = <2>;
                interrupts = <0 90 0x04>;
+               nvidia,dma-request-selector = <&apbdma 19>;
+               status = "disabled";
+               clocks = <&tegra_car 65>;
+       };
+
+       pwm: pwm {
+               compatible = "nvidia,tegra114-pwm", "nvidia,tegra20-pwm";
+               reg = <0x7000a000 0x100>;
+               #pwm-cells = <2>;
+               clocks = <&tegra_car 17>;
+               status = "disabled";
+       };
+
+       i2c@7000c000 {
+               compatible = "nvidia,tegra114-i2c";
+               reg = <0x7000c000 0x100>;
+               interrupts = <0 38 0x04>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car 12>;
+               clock-names = "div-clk";
+               status = "disabled";
+       };
+
+       i2c@7000c400 {
+               compatible = "nvidia,tegra114-i2c";
+               reg = <0x7000c400 0x100>;
+               interrupts = <0 84 0x04>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car 54>;
+               clock-names = "div-clk";
+               status = "disabled";
+       };
+
+       i2c@7000c500 {
+               compatible = "nvidia,tegra114-i2c";
+               reg = <0x7000c500 0x100>;
+               interrupts = <0 92 0x04>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car 67>;
+               clock-names = "div-clk";
+               status = "disabled";
+       };
+
+       i2c@7000c700 {
+               compatible = "nvidia,tegra114-i2c";
+               reg = <0x7000c700 0x100>;
+               interrupts = <0 120 0x04>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car 103>;
+               clock-names = "div-clk";
+               status = "disabled";
+       };
+
+       i2c@7000d000 {
+               compatible = "nvidia,tegra114-i2c";
+               reg = <0x7000d000 0x100>;
+               interrupts = <0 53 0x04>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car 47>;
+               clock-names = "div-clk";
+               status = "disabled";
+       };
+
+       spi@7000d400 {
+               compatible = "nvidia,tegra114-spi";
+               reg = <0x7000d400 0x200>;
+               interrupts = <0 59 0x04>;
+               nvidia,dma-request-selector = <&apbdma 15>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car 41>;
+               clock-names = "spi";
+               status = "disabled";
+       };
+
+       spi@7000d600 {
+               compatible = "nvidia,tegra114-spi";
+               reg = <0x7000d600 0x200>;
+               interrupts = <0 82 0x04>;
+               nvidia,dma-request-selector = <&apbdma 16>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car 44>;
+               clock-names = "spi";
+               status = "disabled";
+       };
+
+       spi@7000d800 {
+               compatible = "nvidia,tegra114-spi";
+               reg = <0x7000d800 0x200>;
+               interrupts = <0 83 0x04>;
+               nvidia,dma-request-selector = <&apbdma 17>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car 46>;
+               clock-names = "spi";
+               status = "disabled";
+       };
+
+       spi@7000da00 {
+               compatible = "nvidia,tegra114-spi";
+               reg = <0x7000da00 0x200>;
+               interrupts = <0 93 0x04>;
+               nvidia,dma-request-selector = <&apbdma 18>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car 68>;
+               clock-names = "spi";
+               status = "disabled";
+       };
+
+       spi@7000dc00 {
+               compatible = "nvidia,tegra114-spi";
+               reg = <0x7000dc00 0x200>;
+               interrupts = <0 94 0x04>;
+               nvidia,dma-request-selector = <&apbdma 27>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car 104>;
+               clock-names = "spi";
+               status = "disabled";
+       };
+
+       spi@7000de00 {
+               compatible = "nvidia,tegra114-spi";
+               reg = <0x7000de00 0x200>;
+               interrupts = <0 79 0x04>;
+               nvidia,dma-request-selector = <&apbdma 28>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&tegra_car 105>;
+               clock-names = "spi";
                status = "disabled";
        };
 
                compatible = "nvidia,tegra114-rtc", "nvidia,tegra20-rtc";
                reg = <0x7000e000 0x100>;
                interrupts = <0 2 0x04>;
+               clocks = <&tegra_car 4>;
+       };
+
+       kbc {
+               compatible = "nvidia,tegra114-kbc";
+               reg = <0x7000e200 0x100>;
+               interrupts = <0 85 0x04>;
+               clocks = <&tegra_car 36>;
+               status = "disabled";
        };
 
        pmc {
-               compatible = "nvidia,tegra114-pmc", "nvidia,tegra30-pmc";
+               compatible = "nvidia,tegra114-pmc";
                reg = <0x7000e400 0x400>;
+               clocks = <&tegra_car 261>, <&clk32k_in>;
+               clock-names = "pclk", "clk32k_in";
        };
 
        iommu {
                nvidia,ahb = <&ahb>;
        };
 
+       sdhci@78000000 {
+               compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
+               reg = <0x78000000 0x200>;
+               interrupts = <0 14 0x04>;
+               clocks = <&tegra_car 14>;
+               status = "disable";
+       };
+
+       sdhci@78000200 {
+               compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
+               reg = <0x78000200 0x200>;
+               interrupts = <0 15 0x04>;
+               clocks = <&tegra_car 9>;
+               status = "disable";
+       };
+
+       sdhci@78000400 {
+               compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
+               reg = <0x78000400 0x200>;
+               interrupts = <0 19 0x04>;
+               clocks = <&tegra_car 69>;
+               status = "disable";
+       };
+
+       sdhci@78000600 {
+               compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
+               reg = <0x78000600 0x200>;
+               interrupts = <0 31 0x04>;
+               clocks = <&tegra_car 15>;
+               status = "disable";
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
index 444162090042cf4f59f6961b1cd839ac14764c0c..a573b94b7c93eafb313e42bf8dfde31e9ecfcd6a 100644 (file)
                };
        };
 
+       pmc {
+               nvidia,suspend-mode = <2>;
+               nvidia,cpu-pwr-good-time = <5000>;
+               nvidia,cpu-pwr-off-time = <5000>;
+               nvidia,core-pwr-good-time = <3845 3845>;
+               nvidia,core-pwr-off-time = <3875>;
+               nvidia,sys-clock-req-active-high;
+       };
+
        memory-controller@7000f400 {
                emc-table@83250 {
                        reg = <83250>;
        };
 
        sdhci@c8000600 {
-               cd-gpios = <&gpio 23 0>; /* gpio PC7 */
+               cd-gpios = <&gpio 23 1>; /* gpio PC7 */
+       };
+
+       clocks {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               clk32k_in: clock {
+                       compatible = "fixed-clock";
+                       reg=<0>;
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+               };
        };
 
        sound {
                        "Mic", "MIC1";
 
                nvidia,ac97-controller = <&ac97>;
+
+               clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+               clock-names = "pll_a", "pll_a_out0", "mclk";
        };
 
        regulators {
index 61d027f03617d36a2ef87cdc2978e5a34320f95c..e7d5de4e00b99e57628298cd5c3d4c3fb4fb67fd 100644 (file)
 
        pmc {
                nvidia,invert-interrupt;
+               nvidia,suspend-mode = <2>;
+               nvidia,cpu-pwr-good-time = <5000>;
+               nvidia,cpu-pwr-off-time = <5000>;
+               nvidia,core-pwr-good-time = <3845 3845>;
+               nvidia,core-pwr-off-time = <3875>;
+               nvidia,sys-clock-req-active-high;
        };
 
        usb@c5000000 {
 
        sdhci@c8000200 {
                status = "okay";
-               cd-gpios = <&gpio 69 0>; /* gpio PI5 */
+               cd-gpios = <&gpio 69 1>; /* gpio PI5 */
                wp-gpios = <&gpio 57 0>; /* gpio PH1 */
                power-gpios = <&gpio 155 0>; /* gpio PT3 */
                bus-width = <4>;
 
        sdhci@c8000600 {
                status = "okay";
-               cd-gpios = <&gpio 58 0>; /* gpio PH2 */
+               cd-gpios = <&gpio 58 1>; /* gpio PH2 */
                wp-gpios = <&gpio 59 0>; /* gpio PH3 */
                power-gpios = <&gpio 70 0>; /* gpio PI6 */
                bus-width = <8>;
        };
 
+       clocks {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               clk32k_in: clock {
+                       compatible = "fixed-clock";
+                       reg=<0>;
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               power {
+                       label = "Power";
+                       gpios = <&gpio 170 1>; /* gpio PV2, active low */
+                       linux,code = <116>; /* KEY_POWER */
+                       gpio-key,wakeup;
+               };
+       };
+
        kbc {
                status = "okay";
                nvidia,debounce-delay-ms = <2>;
                nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
                nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */
                nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */
+
+               clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+               clock-names = "pll_a", "pll_a_out0", "mclk";
        };
 };
index a2d6d6541f83ebc8bf3e73d7cff4b0b1848959ef..ace23437da8902ec212df6124ec80d05c5bd7d72 100644 (file)
@@ -6,6 +6,10 @@
        model = "Avionic Design Medcom-Wide board";
        compatible = "ad,medcom-wide", "ad,tamonten", "nvidia,tegra20";
 
+       pwm {
+               status = "okay";
+       };
+
        i2c@7000c000 {
                wm8903: wm8903@1a {
                        compatible = "wlf,wm8903";
@@ -54,5 +58,8 @@
 
                nvidia,spkr-en-gpios = <&wm8903 2 0>;
                nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+
+               clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+               clock-names = "pll_a", "pll_a_out0", "mclk";
        };
 };
index 54d6fce00a59e4cfa4296d5715c50d00f8543eb7..e3e0c9977df451a778006bc71d75d3aec9022f93 100644 (file)
 
        pmc {
                nvidia,invert-interrupt;
+               nvidia,suspend-mode = <2>;
+               nvidia,cpu-pwr-good-time = <2000>;
+               nvidia,cpu-pwr-off-time = <0>;
+               nvidia,core-pwr-good-time = <3845 3845>;
+               nvidia,core-pwr-off-time = <0>;
+               nvidia,sys-clock-req-active-high;
        };
 
        usb@c5000000 {
 
        sdhci@c8000000 {
                status = "okay";
-               cd-gpios = <&gpio 173 0>; /* gpio PV5 */
+               cd-gpios = <&gpio 173 1>; /* gpio PV5 */
                wp-gpios = <&gpio 57 0>;  /* gpio PH1 */
                power-gpios = <&gpio 169 0>; /* gpio PV1 */
                bus-width = <4>;
        sdhci@c8000600 {
                status = "okay";
                bus-width = <8>;
+               non-removable;
+       };
+
+       clocks {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               clk32k_in: clock {
+                       compatible = "fixed-clock";
+                       reg=<0>;
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+               };
        };
 
        gpio-keys {
                nvidia,audio-codec = <&alc5632>;
                nvidia,i2s-controller = <&tegra_i2s1>;
                nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+
+               clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+               clock-names = "pll_a", "pll_a_out0", "mclk";
        };
 };
index 289480026fbfadd52308a49f3134b43edb2e04db..1a17cc30bb9d47b002998d0fd2073e3d99aa95c2 100644 (file)
@@ -52,5 +52,8 @@
 
                nvidia,spkr-en-gpios = <&wm8903 2 0>;
                nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+
+               clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+               clock-names = "pll_a", "pll_a_out0", "mclk";
        };
 };
index 37b3a57ec0f15ad4b330251fbc1a20526cbdb788..cee4c34010fed6fa1d1ce96a1c45bebccf97a974 100644 (file)
 
        pmc {
                nvidia,invert-interrupt;
+               nvidia,suspend-mode = <2>;
+               nvidia,cpu-pwr-good-time = <5000>;
+               nvidia,cpu-pwr-off-time = <5000>;
+               nvidia,core-pwr-good-time = <3845 3845>;
+               nvidia,core-pwr-off-time = <3875>;
+               nvidia,sys-clock-req-active-high;
        };
 
        memory-controller@7000f400 {
                status = "okay";
                power-gpios = <&gpio 86 0>; /* gpio PK6 */
                bus-width = <4>;
+               keep-power-in-suspend;
        };
 
        sdhci@c8000400 {
                status = "okay";
-               cd-gpios = <&gpio 69 0>; /* gpio PI5 */
+               cd-gpios = <&gpio 69 1>; /* gpio PI5 */
                wp-gpios = <&gpio 57 0>; /* gpio PH1 */
                power-gpios = <&gpio 70 0>; /* gpio PI6 */
                bus-width = <4>;
        sdhci@c8000600 {
                status = "okay";
                bus-width = <8>;
+               non-removable;
+       };
+
+       clocks {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               clk32k_in: clock {
+                       compatible = "fixed-clock";
+                       reg=<0>;
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+               };
        };
 
        gpio-keys {
 
                nvidia,spkr-en-gpios = <&wm8903 2 0>;
                nvidia,hp-det-gpios = <&gpio 185 0>; /* gpio PX1 */
+
+               clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+               clock-names = "pll_a", "pll_a_out0", "mclk";
        };
 };
index 4766abae7a72bb20a984e2914e1dd3c76d60356e..50b3ec16b93aa20e6a70f42fe0e0825657e93eb4 100644 (file)
 
        pmc {
                nvidia,invert-interrupt;
+               nvidia,suspend-mode = <2>;
+               nvidia,cpu-pwr-good-time = <5000>;
+               nvidia,cpu-pwr-off-time = <5000>;
+               nvidia,core-pwr-good-time = <3845 3845>;
+               nvidia,core-pwr-off-time = <3875>;
+               nvidia,sys-clock-req-active-high;
        };
 
        usb@c5008000 {
        };
 
        sdhci@c8000600 {
-               cd-gpios = <&gpio 58 0>; /* gpio PH2 */
+               cd-gpios = <&gpio 58 1>; /* gpio PH2 */
                wp-gpios = <&gpio 59 0>; /* gpio PH3 */
                bus-width = <4>;
                status = "okay";
        };
 
+       clocks {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               clk32k_in: clock {
+                       compatible = "fixed-clock";
+                       reg=<0>;
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+               };
+       };
+
        regulators {
                compatible = "simple-bus";
 
index 402b21004bef5859908d00d4191878a44ff44260..742f0b38d21df42524a2bc9c0ccd3d1fb60e0e7c 100644 (file)
@@ -52,5 +52,8 @@
 
                nvidia,spkr-en-gpios = <&wm8903 2 0>;
                nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+
+               clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+               clock-names = "pll_a", "pll_a_out0", "mclk";
        };
 };
index 5d79e4fc49a63577a599f428533b185552897281..9cc78a15d739860393edb0b227aba930444cb59f 100644 (file)
                };
        };
 
+       pmc {
+               nvidia,suspend-mode = <2>;
+               nvidia,cpu-pwr-good-time = <5000>;
+               nvidia,cpu-pwr-off-time = <5000>;
+               nvidia,core-pwr-good-time = <3845 3845>;
+               nvidia,core-pwr-off-time = <3875>;
+               nvidia,sys-clock-req-active-high;
+       };
+
        usb@c5000000 {
                status = "okay";
                nvidia,vbus-gpio = <&gpio 170 0>; /* gpio PV2 */
 
        sdhci@c8000600 {
                status = "okay";
-               cd-gpios = <&gpio 121 0>; /* gpio PP1 */
+               cd-gpios = <&gpio 121 1>; /* gpio PP1 */
                wp-gpios = <&gpio 122 0>; /* gpio PP2 */
                bus-width = <4>;
        };
 
+       clocks {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               clk32k_in: clock {
+                       compatible = "fixed-clock";
+                       reg=<0>;
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               power {
+                       label = "Power";
+                       gpios = <&gpio 190 1>; /* gpio PX6, active low */
+                       linux,code = <116>; /* KEY_POWER */
+                       gpio-key,wakeup;
+               };
+       };
+
        poweroff {
                compatible = "gpio-poweroff";
                gpios = <&gpio 191 1>; /* gpio PX7, active low */
                compatible = "nvidia,tegra-audio-trimslice";
                nvidia,i2s-controller = <&tegra_i2s1>;
                nvidia,audio-codec = <&codec>;
+
+               clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+               clock-names = "pll_a", "pll_a_out0", "mclk";
        };
 };
index 425c89000c20ebd6cd55ff353bb45253fc7fa79f..dd38f1f038347e6d328f1af6b0757d7fa03b9c36 100644 (file)
 
        pmc {
                nvidia,invert-interrupt;
+               nvidia,suspend-mode = <2>;
+               nvidia,cpu-pwr-good-time = <2000>;
+               nvidia,cpu-pwr-off-time = <100>;
+               nvidia,core-pwr-good-time = <3845 3845>;
+               nvidia,core-pwr-off-time = <458>;
+               nvidia,sys-clock-req-active-high;
        };
 
        usb@c5000000 {
                status = "okay";
                power-gpios = <&gpio 86 0>; /* gpio PK6 */
                bus-width = <4>;
+               keep-power-in-suspend;
        };
 
        sdhci@c8000400 {
                status = "okay";
-               cd-gpios = <&gpio 69 0>; /* gpio PI5 */
+               cd-gpios = <&gpio 69 1>; /* gpio PI5 */
                wp-gpios = <&gpio 57 0>; /* gpio PH1 */
                power-gpios = <&gpio 70 0>; /* gpio PI6 */
                bus-width = <4>;
        sdhci@c8000600 {
                status = "okay";
                bus-width = <8>;
+               non-removable;
+       };
+
+       clocks {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               clk32k_in: clock {
+                       compatible = "fixed-clock";
+                       reg=<0>;
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               power {
+                       label = "Power";
+                       gpios = <&gpio 170 1>; /* gpio PV2, active low */
+                       linux,code = <116>; /* KEY_POWER */
+                       gpio-key,wakeup;
+               };
        };
 
        regulators {
                nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
                nvidia,int-mic-en-gpios = <&gpio 184 0>; /* gpio PX0 */
                nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */
+
+               clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+               clock-names = "pll_a", "pll_a_out0", "mclk";
        };
 };
index ea57c0f6dccea46b98d4f06d40eb3446df8e5d10..d2567f83aaffd19584e45c8d080a560e74d1172d 100644 (file)
 
        pmc {
                nvidia,invert-interrupt;
+               nvidia,suspend-mode = <2>;
+               nvidia,cpu-pwr-good-time = <2000>;
+               nvidia,cpu-pwr-off-time = <1000>;
+               nvidia,core-pwr-good-time = <0 3845>;
+               nvidia,core-pwr-off-time = <93727>;
+               nvidia,core-power-req-active-high;
+               nvidia,sys-clock-req-active-high;
+               nvidia,combined-power-req;
        };
 
        usb@c5000000 {
 
        sdhci@c8000400 {
                status = "okay";
+               cd-gpios = <&gpio 69 1>; /* gpio PI5 */
                wp-gpios = <&gpio 173 0>; /* gpio PV5 */
                bus-width = <8>;
        };
        sdhci@c8000600 {
                status = "okay";
                bus-width = <8>;
+               non-removable;
+       };
+
+       clocks {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               clk32k_in: clock {
+                       compatible = "fixed-clock";
+                       reg=<0>;
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+               };
        };
 
        kbc {
                nvidia,repeat-delay-ms = <160>;
                nvidia,kbc-row-pins = <0 1 2>;
                nvidia,kbc-col-pins = <16 17>;
+               nvidia,wakeup-source;
                linux,keymap = <0x00000074      /* KEY_POWER */
                                0x01000066      /* KEY_HOME */
                                0x0101009E      /* KEY_BACK */
 
                nvidia,i2s-controller = <&tegra_i2s1>;
                nvidia,audio-codec = <&codec>;
+
+               clocks = <&tegra_car 112>, <&tegra_car 113>, <&tegra_car 94>;
+               clock-names = "pll_a", "pll_a_out0", "mclk";
        };
 };
index 48d00a099ce38d75d0df6ceb513078383c8d54e5..56a91106041b31ca91a6ef9559e11abcc8f2cc1e 100644 (file)
                              0 1 0x04
                              0 41 0x04
                              0 42 0x04>;
+               clocks = <&tegra_car 5>;
        };
 
        tegra_car: clock {
                compatible = "nvidia,tegra20-das";
                reg = <0x70000c00 0x80>;
        };
-       
+
        tegra_ac97: ac97 {
                compatible = "nvidia,tegra20-ac97";
                reg = <0x70002000 0x200>;
                reg = <0x7000a000 0x100>;
                #pwm-cells = <2>;
                clocks = <&tegra_car 17>;
+               status = "disabled";
        };
 
        rtc {
                compatible = "nvidia,tegra20-rtc";
                reg = <0x7000e000 0x100>;
                interrupts = <0 2 0x04>;
+               clocks = <&tegra_car 4>;
        };
 
        i2c@7000c000 {
 
        spi@7000d800 {
                compatible = "nvidia,tegra20-slink";
-               reg = <0x7000d480 0x200>;
+               reg = <0x7000d800 0x200>;
                interrupts = <0 83 0x04>;
                nvidia,dma-request-selector = <&apbdma 17>;
                #address-cells = <1>;
        pmc {
                compatible = "nvidia,tegra20-pmc";
                reg = <0x7000e400 0x400>;
+               clocks = <&tegra_car 110>, <&clk32k_in>;
+               clock-names = "pclk", "clk32k_in";
        };
 
        memory-controller@7000f000 {
                #size-cells = <0>;
        };
 
-       phy1: usb-phy@c5000400 {
-               compatible = "nvidia,tegra20-usb-phy";
-               reg = <0xc5000400 0x3c00>;
-               phy_type = "utmi";
-               nvidia,has-legacy-mode;
-               clocks = <&tegra_car 22>, <&tegra_car 127>;
-               clock-names = "phy", "pll_u";
-       };
-
-       phy2: usb-phy@c5004400 {
-               compatible = "nvidia,tegra20-usb-phy";
-               reg = <0xc5004400 0x3c00>;
-               phy_type = "ulpi";
-               clocks = <&tegra_car 94>, <&tegra_car 127>;
-               clock-names = "phy", "pll_u";
-       };
-
-       phy3: usb-phy@c5008400 {
-               compatible = "nvidia,tegra20-usb-phy";
-               reg = <0xc5008400 0x3C00>;
-               phy_type = "utmi";
-               clocks = <&tegra_car 22>, <&tegra_car 127>;
-               clock-names = "phy", "pll_u";
-       };
-
        usb@c5000000 {
                compatible = "nvidia,tegra20-ehci", "usb-ehci";
                reg = <0xc5000000 0x4000>;
                status = "disabled";
        };
 
+       phy1: usb-phy@c5000400 {
+               compatible = "nvidia,tegra20-usb-phy";
+               reg = <0xc5000400 0x3c00>;
+               phy_type = "utmi";
+               nvidia,has-legacy-mode;
+               clocks = <&tegra_car 22>, <&tegra_car 127>;
+               clock-names = "phy", "pll_u";
+       };
+
        usb@c5004000 {
                compatible = "nvidia,tegra20-ehci", "usb-ehci";
                reg = <0xc5004000 0x4000>;
                status = "disabled";
        };
 
+       phy2: usb-phy@c5004400 {
+               compatible = "nvidia,tegra20-usb-phy";
+               reg = <0xc5004400 0x3c00>;
+               phy_type = "ulpi";
+               clocks = <&tegra_car 93>, <&tegra_car 127>;
+               clock-names = "phy", "pll_u";
+       };
+
        usb@c5008000 {
                compatible = "nvidia,tegra20-ehci", "usb-ehci";
                reg = <0xc5008000 0x4000>;
                status = "disabled";
        };
 
+       phy3: usb-phy@c5008400 {
+               compatible = "nvidia,tegra20-usb-phy";
+               reg = <0xc5008400 0x3c00>;
+               phy_type = "utmi";
+               clocks = <&tegra_car 22>, <&tegra_car 127>;
+               clock-names = "phy", "pll_u";
+       };
+
        sdhci@c8000000 {
                compatible = "nvidia,tegra20-sdhci";
                reg = <0xc8000000 0x200>;
index 8ff2ff20e4a34a3799be59fc6f3b5dff5e621329..b732f7c13a662a81024c7efcf07b50b106ef7362 100644 (file)
        pmc {
                status = "okay";
                nvidia,invert-interrupt;
+               nvidia,suspend-mode = <2>;
+               nvidia,cpu-pwr-good-time = <2000>;
+               nvidia,cpu-pwr-off-time = <200>;
+               nvidia,core-pwr-good-time = <3845 3845>;
+               nvidia,core-pwr-off-time = <0>;
+               nvidia,core-power-req-active-high;
+               nvidia,sys-clock-req-active-high;
        };
 
        sdhci@78000000 {
                status = "okay";
-               cd-gpios = <&gpio 69 0>; /* gpio PI5 */
+               cd-gpios = <&gpio 69 1>; /* gpio PI5 */
                wp-gpios = <&gpio 155 0>; /* gpio PT3 */
                power-gpios = <&gpio 31 0>; /* gpio PD7 */
                bus-width = <4>;
        sdhci@78000600 {
                status = "okay";
                bus-width = <8>;
+               non-removable;
+       };
+
+       clocks {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               clk32k_in: clock {
+                       compatible = "fixed-clock";
+                       reg=<0>;
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+               };
        };
 
        regulators {
index adc88aa50eb634e5c36b002f6a06420aa6917a7c..e392bd2dab9b5af322d39a5363e4e9cd479ef723 100644 (file)
@@ -88,6 +88,7 @@
                status = "okay";
                power-gpios = <&gpio 28 0>; /* gpio PD4 */
                bus-width = <4>;
+               keep-power-in-suspend;
        };
 };
 
index 08163e145d57d10691f85ae6de770321d5f168f4..d0db6c7e774fa5de34fdb7b2a8609724a66db444 100644 (file)
                status = "okay";
                power-gpios = <&gpio 27 0>; /* gpio PD3 */
                bus-width = <4>;
+               keep-power-in-suspend;
        };
 };
index 17499272a4ef97e2df09fc8ced7f07bf13255aaa..01b4c26fad965d1f315da0eeaef94c98bfecd9fd 100644 (file)
        pmc {
                status = "okay";
                nvidia,invert-interrupt;
+               nvidia,suspend-mode = <2>;
+               nvidia,cpu-pwr-good-time = <2000>;
+               nvidia,cpu-pwr-off-time = <200>;
+               nvidia,core-pwr-good-time = <3845 3845>;
+               nvidia,core-pwr-off-time = <0>;
+               nvidia,core-power-req-active-high;
+               nvidia,sys-clock-req-active-high;
        };
 
        sdhci@78000000 {
                status = "okay";
-               cd-gpios = <&gpio 69 0>; /* gpio PI5 */
+               cd-gpios = <&gpio 69 1>; /* gpio PI5 */
                wp-gpios = <&gpio 155 0>; /* gpio PT3 */
                power-gpios = <&gpio 31 0>; /* gpio PD7 */
                bus-width = <4>;
        sdhci@78000600 {
                status = "okay";
                bus-width = <8>;
+               non-removable;
+       };
+
+       clocks {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               clk32k_in: clock {
+                       compatible = "fixed-clock";
+                       reg=<0>;
+                       #clock-cells = <0>;
+                       clock-frequency = <32768>;
+               };
        };
 
        regulators {
 
                nvidia,spkr-en-gpios = <&wm8903 2 0>;
                nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+
+               clocks = <&tegra_car 184>, <&tegra_car 185>, <&tegra_car 120>;
+               clock-names = "pll_a", "pll_a_out0", "mclk";
        };
 };
index 9d87a3ffe9980a140585d063dbb9be5f2fbfa482..15ded605142aa1cbe0d47c8e040649f22b99b47c 100644 (file)
                              0 42 0x04
                              0 121 0x04
                              0 122 0x04>;
+               clocks = <&tegra_car 5>;
        };
 
        tegra_car: clock {
                reg = <0x7000a000 0x100>;
                #pwm-cells = <2>;
                clocks = <&tegra_car 17>;
+               status = "disabled";
        };
 
        rtc {
                compatible = "nvidia,tegra30-rtc", "nvidia,tegra20-rtc";
                reg = <0x7000e000 0x100>;
                interrupts = <0 2 0x04>;
+               clocks = <&tegra_car 4>;
        };
 
        i2c@7000c000 {
 
        spi@7000d800 {
                compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
-               reg = <0x7000d480 0x200>;
+               reg = <0x7000d800 0x200>;
                interrupts = <0 83 0x04>;
                nvidia,dma-request-selector = <&apbdma 17>;
                #address-cells = <1>;
        };
 
        pmc {
-               compatible = "nvidia,tegra20-pmc", "nvidia,tegra30-pmc";
+               compatible = "nvidia,tegra30-pmc";
                reg = <0x7000e400 0x400>;
+               clocks = <&tegra_car 218>, <&clk32k_in>;
+               clock-names = "pclk", "clk32k_in";
        };
 
        memory-controller {
index ed0bc9546837d8f40f3bf873e20055717c5d1451..b3034da00a37bfe6a5361420bc2fb8d99101fb5a 100644 (file)
                compatible = "ti,twl4030-wdt";
        };
 
+       vcc: regulator-vdd1 {
+               compatible = "ti,twl4030-vdd1";
+               regulator-min-microvolt = <600000>;
+               regulator-max-microvolt = <1450000>;
+       };
+
        vdac: regulator-vdac {
                compatible = "ti,twl4030-vdac";
                regulator-min-microvolt = <1800000>;
@@ -67,7 +73,7 @@
                #interrupt-cells = <1>;
        };
 
-       twl4030-usb {
+       usb2_phy: twl4030-usb {
                compatible = "ti,twl4030-usb";
                interrupts = <10>, <4>;
                usb1v5-supply = <&vusb1v5>;
                usb3v1-supply = <&vusb3v1>;
                usb_mode = <1>;
        };
+
+       twl_pwm: pwm {
+               compatible = "ti,twl4030-pwm";
+               #pwm-cells = <2>;
+       };
+
+       twl_pwmled: pwmled {
+               compatible = "ti,twl4030-pwmled";
+               #pwm-cells = <2>;
+       };
 };
index 9996cfc5ee809a8854817757aded21e59b861161..2e3bd3172b2366227a78f8404f191e4d0e6e8be6 100644 (file)
                compatible = "ti,twl6030-usb";
                interrupts = <4>, <10>;
        };
+
+       twl_pwm: pwm {
+               /* provides two PWMs (id 0, 1 for PWM1 and PWM2) */
+               compatible = "ti,twl6030-pwm";
+               #pwm-cells = <2>;
+       };
+
+       twl_pwmled: pwmled {
+               /* provides one PWM (id 0 for Charging indicator LED) */
+               compatible = "ti,twl6030-pwmled";
+               #pwm-cells = <2>;
+       };
 };
index 0f01f4677bd27569df340029cabe9f602a1e0eeb..7b2899c2f7fc8a4f07221bb599df93c6c4756f5f 100644 (file)
@@ -34,12 +34,4 @@ struct twd_local_timer name __initdata = {   \
 
 int twd_local_timer_register(struct twd_local_timer *);
 
-#ifdef CONFIG_HAVE_ARM_TWD
-void twd_local_timer_of_register(void);
-#else
-static inline void twd_local_timer_of_register(void)
-{
-}
-#endif
-
 #endif
index 3f256503748005346d5f1388aa1ed30978433b03..90525d9d290b9c25e3b40d5bdeedfc6a6f524cf6 100644 (file)
@@ -362,25 +362,13 @@ int __init twd_local_timer_register(struct twd_local_timer *tlt)
 }
 
 #ifdef CONFIG_OF
-const static struct of_device_id twd_of_match[] __initconst = {
-       { .compatible = "arm,cortex-a9-twd-timer",      },
-       { .compatible = "arm,cortex-a5-twd-timer",      },
-       { .compatible = "arm,arm11mp-twd-timer",        },
-       { },
-};
-
-void __init twd_local_timer_of_register(void)
+static void __init twd_local_timer_of_register(struct device_node *np)
 {
-       struct device_node *np;
        int err;
 
        if (!is_smp() || !setup_max_cpus)
                return;
 
-       np = of_find_matching_node(NULL, twd_of_match);
-       if (!np)
-               return;
-
        twd_ppi = irq_of_parse_and_map(np, 0);
        if (!twd_ppi) {
                err = -EINVAL;
@@ -398,4 +386,7 @@ void __init twd_local_timer_of_register(void)
 out:
        WARN(err, "twd_local_timer_of_register failed (%d)\n", err);
 }
+CLOCKSOURCE_OF_DECLARE(arm_twd_a9, "arm,cortex-a9-twd-timer", twd_local_timer_of_register);
+CLOCKSOURCE_OF_DECLARE(arm_twd_a5, "arm,cortex-a5-twd-timer", twd_local_timer_of_register);
+CLOCKSOURCE_OF_DECLARE(arm_twd_11mp, "arm,arm11mp-twd-timer", twd_local_timer_of_register);
 #endif
index 70f94c87479df7d4dc2ab8aa25356461a3066b14..ef3b69a6277cc6af5c821cc739e6a3bea027bdf1 100644 (file)
@@ -61,6 +61,7 @@ config SOC_EXYNOS5250
        bool "SAMSUNG EXYNOS5250"
        default y
        depends on ARCH_EXYNOS5
+       select PM_GENERIC_DOMAINS if PM
        select S5P_PM if PM
        select S5P_SLEEP if PM
        select S5P_DEV_MFC
@@ -79,12 +80,6 @@ config SOC_EXYNOS5440
        help
          Enable EXYNOS5440 SoC support
 
-config EXYNOS4_MCT
-       bool
-       default y
-       help
-         Use MCT (Multi Core Timer) as kernel timers
-
 config EXYNOS_DEV_DMA
        bool
        help
@@ -276,8 +271,8 @@ config MACH_UNIVERSAL_C210
        select S5P_DEV_ONENAND
        select S5P_DEV_TV
        select S5P_GPIO_INT
-       select S5P_HRT
        select S5P_SETUP_MIPIPHY
+       select SAMSUNG_HRT
        help
          Machine support for Samsung Mobile Universal S5PC210 Reference
          Board.
@@ -406,10 +401,12 @@ config MACH_EXYNOS4_DT
        bool "Samsung Exynos4 Machine using device tree"
        depends on ARCH_EXYNOS4
        select ARM_AMBA
+       select CLKSRC_OF
        select CPU_EXYNOS4210
        select HAVE_SAMSUNG_KEYPAD if INPUT_KEYBOARD
        select PINCTRL
        select PINCTRL_EXYNOS
+       select S5P_DEV_MFC
        select USE_OF
        help
          Machine support for Samsung Exynos4 machine with device tree enabled.
@@ -422,6 +419,7 @@ config MACH_EXYNOS5_DT
        default y
        depends on ARCH_EXYNOS5
        select ARM_AMBA
+       select CLKSRC_OF
        select USE_OF
        help
          Machine support for Samsung EXYNOS5 machine with device tree enabled.
index 435757e57bb47d8f2b784352150dcb182aa6eb43..d2f6b362b6dd392bb4f596b4baff37b2c1ce5065 100644 (file)
@@ -13,10 +13,6 @@ obj-                         :=
 # Core
 
 obj-$(CONFIG_ARCH_EXYNOS)      += common.o
-obj-$(CONFIG_ARCH_EXYNOS4)     += clock-exynos4.o
-obj-$(CONFIG_CPU_EXYNOS4210)   += clock-exynos4210.o
-obj-$(CONFIG_SOC_EXYNOS4212)   += clock-exynos4212.o
-obj-$(CONFIG_SOC_EXYNOS5250)   += clock-exynos5.o
 
 obj-$(CONFIG_PM)               += pm.o
 obj-$(CONFIG_PM_GENERIC_DOMAINS) += pm_domains.o
@@ -26,8 +22,6 @@ obj-$(CONFIG_ARCH_EXYNOS)     += pmu.o
 
 obj-$(CONFIG_SMP)              += platsmp.o headsmp.o
 
-obj-$(CONFIG_EXYNOS4_MCT)      += mct.o
-
 obj-$(CONFIG_HOTPLUG_CPU)      += hotplug.o
 
 # machine support
diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c
deleted file mode 100644 (file)
index 8a8468d..0000000
+++ /dev/null
@@ -1,1601 +0,0 @@
-/*
- * Copyright (c) 2010-2012 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 - Clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/syscore_ops.h>
-
-#include <plat/cpu-freq.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/pll.h>
-#include <plat/s5p-clock.h>
-#include <plat/clock-clksrc.h>
-#include <plat/pm.h>
-
-#include <mach/map.h>
-#include <mach/regs-clock.h>
-
-#include "common.h"
-#include "clock-exynos4.h"
-
-#ifdef CONFIG_PM_SLEEP
-static struct sleep_save exynos4_clock_save[] = {
-       SAVE_ITEM(EXYNOS4_CLKDIV_LEFTBUS),
-       SAVE_ITEM(EXYNOS4_CLKGATE_IP_LEFTBUS),
-       SAVE_ITEM(EXYNOS4_CLKDIV_RIGHTBUS),
-       SAVE_ITEM(EXYNOS4_CLKGATE_IP_RIGHTBUS),
-       SAVE_ITEM(EXYNOS4_CLKSRC_TOP0),
-       SAVE_ITEM(EXYNOS4_CLKSRC_TOP1),
-       SAVE_ITEM(EXYNOS4_CLKSRC_CAM),
-       SAVE_ITEM(EXYNOS4_CLKSRC_TV),
-       SAVE_ITEM(EXYNOS4_CLKSRC_MFC),
-       SAVE_ITEM(EXYNOS4_CLKSRC_G3D),
-       SAVE_ITEM(EXYNOS4_CLKSRC_LCD0),
-       SAVE_ITEM(EXYNOS4_CLKSRC_MAUDIO),
-       SAVE_ITEM(EXYNOS4_CLKSRC_FSYS),
-       SAVE_ITEM(EXYNOS4_CLKSRC_PERIL0),
-       SAVE_ITEM(EXYNOS4_CLKSRC_PERIL1),
-       SAVE_ITEM(EXYNOS4_CLKDIV_CAM),
-       SAVE_ITEM(EXYNOS4_CLKDIV_TV),
-       SAVE_ITEM(EXYNOS4_CLKDIV_MFC),
-       SAVE_ITEM(EXYNOS4_CLKDIV_G3D),
-       SAVE_ITEM(EXYNOS4_CLKDIV_LCD0),
-       SAVE_ITEM(EXYNOS4_CLKDIV_MAUDIO),
-       SAVE_ITEM(EXYNOS4_CLKDIV_FSYS0),
-       SAVE_ITEM(EXYNOS4_CLKDIV_FSYS1),
-       SAVE_ITEM(EXYNOS4_CLKDIV_FSYS2),
-       SAVE_ITEM(EXYNOS4_CLKDIV_FSYS3),
-       SAVE_ITEM(EXYNOS4_CLKDIV_PERIL0),
-       SAVE_ITEM(EXYNOS4_CLKDIV_PERIL1),
-       SAVE_ITEM(EXYNOS4_CLKDIV_PERIL2),
-       SAVE_ITEM(EXYNOS4_CLKDIV_PERIL3),
-       SAVE_ITEM(EXYNOS4_CLKDIV_PERIL4),
-       SAVE_ITEM(EXYNOS4_CLKDIV_PERIL5),
-       SAVE_ITEM(EXYNOS4_CLKDIV_TOP),
-       SAVE_ITEM(EXYNOS4_CLKSRC_MASK_TOP),
-       SAVE_ITEM(EXYNOS4_CLKSRC_MASK_CAM),
-       SAVE_ITEM(EXYNOS4_CLKSRC_MASK_TV),
-       SAVE_ITEM(EXYNOS4_CLKSRC_MASK_LCD0),
-       SAVE_ITEM(EXYNOS4_CLKSRC_MASK_MAUDIO),
-       SAVE_ITEM(EXYNOS4_CLKSRC_MASK_FSYS),
-       SAVE_ITEM(EXYNOS4_CLKSRC_MASK_PERIL0),
-       SAVE_ITEM(EXYNOS4_CLKSRC_MASK_PERIL1),
-       SAVE_ITEM(EXYNOS4_CLKDIV2_RATIO),
-       SAVE_ITEM(EXYNOS4_CLKGATE_SCLKCAM),
-       SAVE_ITEM(EXYNOS4_CLKGATE_IP_CAM),
-       SAVE_ITEM(EXYNOS4_CLKGATE_IP_TV),
-       SAVE_ITEM(EXYNOS4_CLKGATE_IP_MFC),
-       SAVE_ITEM(EXYNOS4_CLKGATE_IP_G3D),
-       SAVE_ITEM(EXYNOS4_CLKGATE_IP_LCD0),
-       SAVE_ITEM(EXYNOS4_CLKGATE_IP_FSYS),
-       SAVE_ITEM(EXYNOS4_CLKGATE_IP_GPS),
-       SAVE_ITEM(EXYNOS4_CLKGATE_IP_PERIL),
-       SAVE_ITEM(EXYNOS4_CLKGATE_BLOCK),
-       SAVE_ITEM(EXYNOS4_CLKSRC_MASK_DMC),
-       SAVE_ITEM(EXYNOS4_CLKSRC_DMC),
-       SAVE_ITEM(EXYNOS4_CLKDIV_DMC0),
-       SAVE_ITEM(EXYNOS4_CLKDIV_DMC1),
-       SAVE_ITEM(EXYNOS4_CLKGATE_IP_DMC),
-       SAVE_ITEM(EXYNOS4_CLKSRC_CPU),
-       SAVE_ITEM(EXYNOS4_CLKDIV_CPU),
-       SAVE_ITEM(EXYNOS4_CLKDIV_CPU + 0x4),
-       SAVE_ITEM(EXYNOS4_CLKGATE_SCLKCPU),
-       SAVE_ITEM(EXYNOS4_CLKGATE_IP_CPU),
-};
-#endif
-
-static struct clk exynos4_clk_sclk_hdmi27m = {
-       .name           = "sclk_hdmi27m",
-       .rate           = 27000000,
-};
-
-static struct clk exynos4_clk_sclk_hdmiphy = {
-       .name           = "sclk_hdmiphy",
-};
-
-static struct clk exynos4_clk_sclk_usbphy0 = {
-       .name           = "sclk_usbphy0",
-       .rate           = 27000000,
-};
-
-static struct clk exynos4_clk_sclk_usbphy1 = {
-       .name           = "sclk_usbphy1",
-};
-
-static struct clk dummy_apb_pclk = {
-       .name           = "apb_pclk",
-       .id             = -1,
-};
-
-static int exynos4_clksrc_mask_top_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_TOP, clk, enable);
-}
-
-static int exynos4_clksrc_mask_cam_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_CAM, clk, enable);
-}
-
-static int exynos4_clksrc_mask_lcd0_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_LCD0, clk, enable);
-}
-
-int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_FSYS, clk, enable);
-}
-
-static int exynos4_clksrc_mask_peril0_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_PERIL0, clk, enable);
-}
-
-static int exynos4_clksrc_mask_peril1_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_PERIL1, clk, enable);
-}
-
-static int exynos4_clk_ip_mfc_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS4_CLKGATE_IP_MFC, clk, enable);
-}
-
-static int exynos4_clksrc_mask_tv_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS4_CLKSRC_MASK_TV, clk, enable);
-}
-
-static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS4_CLKGATE_IP_CAM, clk, enable);
-}
-
-static int exynos4_clk_ip_tv_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS4_CLKGATE_IP_TV, clk, enable);
-}
-
-int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS4_CLKGATE_IP_IMAGE, clk, enable);
-}
-
-static int exynos4_clk_ip_lcd0_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS4_CLKGATE_IP_LCD0, clk, enable);
-}
-
-int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS4210_CLKGATE_IP_LCD1, clk, enable);
-}
-
-int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS4_CLKGATE_IP_FSYS, clk, enable);
-}
-
-static int exynos4_clk_ip_peril_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS4_CLKGATE_IP_PERIL, clk, enable);
-}
-
-static int exynos4_clk_ip_perir_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS4_CLKGATE_IP_PERIR, clk, enable);
-}
-
-int exynos4_clk_ip_dmc_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS4_CLKGATE_IP_DMC, clk, enable);
-}
-
-static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
-}
-
-static int exynos4_clk_dac_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable);
-}
-
-/* Core list of CMU_CPU side */
-
-static struct clksrc_clk exynos4_clk_mout_apll = {
-       .clk    = {
-               .name           = "mout_apll",
-       },
-       .sources = &clk_src_apll,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 0, .size = 1 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_apll = {
-       .clk    = {
-               .name           = "sclk_apll",
-               .parent         = &exynos4_clk_mout_apll.clk,
-       },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 24, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_mout_epll = {
-       .clk    = {
-               .name           = "mout_epll",
-       },
-       .sources = &clk_src_epll,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 4, .size = 1 },
-};
-
-struct clksrc_clk exynos4_clk_mout_mpll = {
-       .clk    = {
-               .name           = "mout_mpll",
-       },
-       .sources = &clk_src_mpll,
-
-       /* reg_src will be added in each SoCs' clock */
-};
-
-static struct clk *exynos4_clkset_moutcore_list[] = {
-       [0] = &exynos4_clk_mout_apll.clk,
-       [1] = &exynos4_clk_mout_mpll.clk,
-};
-
-static struct clksrc_sources exynos4_clkset_moutcore = {
-       .sources        = exynos4_clkset_moutcore_list,
-       .nr_sources     = ARRAY_SIZE(exynos4_clkset_moutcore_list),
-};
-
-static struct clksrc_clk exynos4_clk_moutcore = {
-       .clk    = {
-               .name           = "moutcore",
-       },
-       .sources = &exynos4_clkset_moutcore,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 16, .size = 1 },
-};
-
-static struct clksrc_clk exynos4_clk_coreclk = {
-       .clk    = {
-               .name           = "core_clk",
-               .parent         = &exynos4_clk_moutcore.clk,
-       },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 0, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_armclk = {
-       .clk    = {
-               .name           = "armclk",
-               .parent         = &exynos4_clk_coreclk.clk,
-       },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_corem0 = {
-       .clk    = {
-               .name           = "aclk_corem0",
-               .parent         = &exynos4_clk_coreclk.clk,
-       },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 4, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_cores = {
-       .clk    = {
-               .name           = "aclk_cores",
-               .parent         = &exynos4_clk_coreclk.clk,
-       },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 4, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_corem1 = {
-       .clk    = {
-               .name           = "aclk_corem1",
-               .parent         = &exynos4_clk_coreclk.clk,
-       },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 8, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_periphclk = {
-       .clk    = {
-               .name           = "periphclk",
-               .parent         = &exynos4_clk_coreclk.clk,
-       },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_CPU, .shift = 12, .size = 3 },
-};
-
-/* Core list of CMU_CORE side */
-
-static struct clk *exynos4_clkset_corebus_list[] = {
-       [0] = &exynos4_clk_mout_mpll.clk,
-       [1] = &exynos4_clk_sclk_apll.clk,
-};
-
-struct clksrc_sources exynos4_clkset_mout_corebus = {
-       .sources        = exynos4_clkset_corebus_list,
-       .nr_sources     = ARRAY_SIZE(exynos4_clkset_corebus_list),
-};
-
-static struct clksrc_clk exynos4_clk_mout_corebus = {
-       .clk    = {
-               .name           = "mout_corebus",
-       },
-       .sources = &exynos4_clkset_mout_corebus,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 4, .size = 1 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_dmc = {
-       .clk    = {
-               .name           = "sclk_dmc",
-               .parent         = &exynos4_clk_mout_corebus.clk,
-       },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 12, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_cored = {
-       .clk    = {
-               .name           = "aclk_cored",
-               .parent         = &exynos4_clk_sclk_dmc.clk,
-       },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 16, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_corep = {
-       .clk    = {
-               .name           = "aclk_corep",
-               .parent         = &exynos4_clk_aclk_cored.clk,
-       },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 20, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_acp = {
-       .clk    = {
-               .name           = "aclk_acp",
-               .parent         = &exynos4_clk_mout_corebus.clk,
-       },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 0, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_pclk_acp = {
-       .clk    = {
-               .name           = "pclk_acp",
-               .parent         = &exynos4_clk_aclk_acp.clk,
-       },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_DMC0, .shift = 4, .size = 3 },
-};
-
-/* Core list of CMU_TOP side */
-
-struct clk *exynos4_clkset_aclk_top_list[] = {
-       [0] = &exynos4_clk_mout_mpll.clk,
-       [1] = &exynos4_clk_sclk_apll.clk,
-};
-
-static struct clksrc_sources exynos4_clkset_aclk = {
-       .sources        = exynos4_clkset_aclk_top_list,
-       .nr_sources     = ARRAY_SIZE(exynos4_clkset_aclk_top_list),
-};
-
-static struct clksrc_clk exynos4_clk_aclk_200 = {
-       .clk    = {
-               .name           = "aclk_200",
-       },
-       .sources = &exynos4_clkset_aclk,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 12, .size = 1 },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 0, .size = 3 },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_100 = {
-       .clk    = {
-               .name           = "aclk_100",
-       },
-       .sources = &exynos4_clkset_aclk,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 16, .size = 1 },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 4, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_aclk_160 = {
-       .clk    = {
-               .name           = "aclk_160",
-       },
-       .sources = &exynos4_clkset_aclk,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 20, .size = 1 },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 8, .size = 3 },
-};
-
-struct clksrc_clk exynos4_clk_aclk_133 = {
-       .clk    = {
-               .name           = "aclk_133",
-       },
-       .sources = &exynos4_clkset_aclk,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 24, .size = 1 },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_TOP, .shift = 12, .size = 3 },
-};
-
-static struct clk *exynos4_clkset_vpllsrc_list[] = {
-       [0] = &clk_fin_vpll,
-       [1] = &exynos4_clk_sclk_hdmi27m,
-};
-
-static struct clksrc_sources exynos4_clkset_vpllsrc = {
-       .sources        = exynos4_clkset_vpllsrc_list,
-       .nr_sources     = ARRAY_SIZE(exynos4_clkset_vpllsrc_list),
-};
-
-static struct clksrc_clk exynos4_clk_vpllsrc = {
-       .clk    = {
-               .name           = "vpll_src",
-               .enable         = exynos4_clksrc_mask_top_ctrl,
-               .ctrlbit        = (1 << 0),
-       },
-       .sources = &exynos4_clkset_vpllsrc,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_TOP1, .shift = 0, .size = 1 },
-};
-
-static struct clk *exynos4_clkset_sclk_vpll_list[] = {
-       [0] = &exynos4_clk_vpllsrc.clk,
-       [1] = &clk_fout_vpll,
-};
-
-static struct clksrc_sources exynos4_clkset_sclk_vpll = {
-       .sources        = exynos4_clkset_sclk_vpll_list,
-       .nr_sources     = ARRAY_SIZE(exynos4_clkset_sclk_vpll_list),
-};
-
-static struct clksrc_clk exynos4_clk_sclk_vpll = {
-       .clk    = {
-               .name           = "sclk_vpll",
-       },
-       .sources = &exynos4_clkset_sclk_vpll,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_TOP0, .shift = 8, .size = 1 },
-};
-
-static struct clk exynos4_init_clocks_off[] = {
-       {
-               .name           = "timers",
-               .parent         = &exynos4_clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1<<24),
-       }, {
-               .name           = "csis",
-               .devname        = "s5p-mipi-csis.0",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "csis",
-               .devname        = "s5p-mipi-csis.1",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 5),
-       }, {
-               .name           = "jpeg",
-               .id             = 0,
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 6),
-       }, {
-               .name           = "fimc",
-               .devname        = "exynos4-fimc.0",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "fimc",
-               .devname        = "exynos4-fimc.1",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 1),
-       }, {
-               .name           = "fimc",
-               .devname        = "exynos4-fimc.2",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 2),
-       }, {
-               .name           = "fimc",
-               .devname        = "exynos4-fimc.3",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 3),
-       }, {
-               .name           = "tsi",
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "hsmmc",
-               .devname        = "exynos4-sdhci.0",
-               .parent         = &exynos4_clk_aclk_133.clk,
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 5),
-       }, {
-               .name           = "hsmmc",
-               .devname        = "exynos4-sdhci.1",
-               .parent         = &exynos4_clk_aclk_133.clk,
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 6),
-       }, {
-               .name           = "hsmmc",
-               .devname        = "exynos4-sdhci.2",
-               .parent         = &exynos4_clk_aclk_133.clk,
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 7),
-       }, {
-               .name           = "hsmmc",
-               .devname        = "exynos4-sdhci.3",
-               .parent         = &exynos4_clk_aclk_133.clk,
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 8),
-       }, {
-               .name           = "biu",
-               .parent         = &exynos4_clk_aclk_133.clk,
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 9),
-       }, {
-               .name           = "onenand",
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 15),
-       }, {
-               .name           = "nfcon",
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 16),
-       }, {
-               .name           = "dac",
-               .devname        = "s5p-sdo",
-               .enable         = exynos4_clk_ip_tv_ctrl,
-               .ctrlbit        = (1 << 2),
-       }, {
-               .name           = "mixer",
-               .devname        = "s5p-mixer",
-               .enable         = exynos4_clk_ip_tv_ctrl,
-               .ctrlbit        = (1 << 1),
-       }, {
-               .name           = "vp",
-               .devname        = "s5p-mixer",
-               .enable         = exynos4_clk_ip_tv_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "hdmi",
-               .devname        = "exynos4-hdmi",
-               .enable         = exynos4_clk_ip_tv_ctrl,
-               .ctrlbit        = (1 << 3),
-       }, {
-               .name           = "hdmiphy",
-               .devname        = "exynos4-hdmi",
-               .enable         = exynos4_clk_hdmiphy_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "dacphy",
-               .devname        = "s5p-sdo",
-               .enable         = exynos4_clk_dac_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "adc",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 15),
-       }, {
-               .name           = "tmu_apbif",
-               .enable         = exynos4_clk_ip_perir_ctrl,
-               .ctrlbit        = (1 << 17),
-       }, {
-               .name           = "keypad",
-               .enable         = exynos4_clk_ip_perir_ctrl,
-               .ctrlbit        = (1 << 16),
-       }, {
-               .name           = "rtc",
-               .enable         = exynos4_clk_ip_perir_ctrl,
-               .ctrlbit        = (1 << 15),
-       }, {
-               .name           = "watchdog",
-               .parent         = &exynos4_clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_perir_ctrl,
-               .ctrlbit        = (1 << 14),
-       }, {
-               .name           = "usbhost",
-               .enable         = exynos4_clk_ip_fsys_ctrl ,
-               .ctrlbit        = (1 << 12),
-       }, {
-               .name           = "otg",
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 13),
-       }, {
-               .name           = "spi",
-               .devname        = "exynos4210-spi.0",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 16),
-       }, {
-               .name           = "spi",
-               .devname        = "exynos4210-spi.1",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 17),
-       }, {
-               .name           = "spi",
-               .devname        = "exynos4210-spi.2",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 18),
-       }, {
-               .name           = "iis",
-               .devname        = "samsung-i2s.1",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 20),
-       }, {
-               .name           = "iis",
-               .devname        = "samsung-i2s.2",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 21),
-       }, {
-               .name           = "pcm",
-               .devname        = "samsung-pcm.1",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 22),
-       }, {
-               .name           = "pcm",
-               .devname        = "samsung-pcm.2",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 23),
-       }, {
-               .name           = "slimbus",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 25),
-       }, {
-               .name           = "spdif",
-               .devname        = "samsung-spdif",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 26),
-       }, {
-               .name           = "ac97",
-               .devname        = "samsung-ac97",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 27),
-       }, {
-               .name           = "mfc",
-               .devname        = "s5p-mfc",
-               .enable         = exynos4_clk_ip_mfc_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.0",
-               .parent         = &exynos4_clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 6),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.1",
-               .parent         = &exynos4_clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 7),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.2",
-               .parent         = &exynos4_clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 8),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.3",
-               .parent         = &exynos4_clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 9),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.4",
-               .parent         = &exynos4_clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 10),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.5",
-               .parent         = &exynos4_clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 11),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.6",
-               .parent         = &exynos4_clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 12),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.7",
-               .parent         = &exynos4_clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 13),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-hdmiphy-i2c",
-               .parent         = &exynos4_clk_aclk_100.clk,
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 14),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.0",
-               .enable         = exynos4_clk_ip_mfc_ctrl,
-               .ctrlbit        = (1 << 1),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.1",
-               .enable         = exynos4_clk_ip_mfc_ctrl,
-               .ctrlbit        = (1 << 2),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.2",
-               .enable         = exynos4_clk_ip_tv_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.3",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 11),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.4",
-               .enable         = exynos4_clk_ip_image_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.5",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 7),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.6",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 8),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.7",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 9),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.8",
-               .enable         = exynos4_clk_ip_cam_ctrl,
-               .ctrlbit        = (1 << 10),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.10",
-               .enable         = exynos4_clk_ip_lcd0_ctrl,
-               .ctrlbit        = (1 << 4),
-       }
-};
-
-static struct clk exynos4_init_clocks_on[] = {
-       {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.0",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.1",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 1),
-       }, {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.2",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 2),
-       }, {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.3",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 3),
-       }, {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.4",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.5",
-               .enable         = exynos4_clk_ip_peril_ctrl,
-               .ctrlbit        = (1 << 5),
-       }
-};
-
-static struct clk exynos4_clk_pdma0 = {
-       .name           = "dma",
-       .devname        = "dma-pl330.0",
-       .enable         = exynos4_clk_ip_fsys_ctrl,
-       .ctrlbit        = (1 << 0),
-};
-
-static struct clk exynos4_clk_pdma1 = {
-       .name           = "dma",
-       .devname        = "dma-pl330.1",
-       .enable         = exynos4_clk_ip_fsys_ctrl,
-       .ctrlbit        = (1 << 1),
-};
-
-static struct clk exynos4_clk_mdma1 = {
-       .name           = "dma",
-       .devname        = "dma-pl330.2",
-       .enable         = exynos4_clk_ip_image_ctrl,
-       .ctrlbit        = ((1 << 8) | (1 << 5) | (1 << 2)),
-};
-
-static struct clk exynos4_clk_fimd0 = {
-       .name           = "fimd",
-       .devname        = "exynos4-fb.0",
-       .enable         = exynos4_clk_ip_lcd0_ctrl,
-       .ctrlbit        = (1 << 0),
-};
-
-struct clk *exynos4_clkset_group_list[] = {
-       [0] = &clk_ext_xtal_mux,
-       [1] = &clk_xusbxti,
-       [2] = &exynos4_clk_sclk_hdmi27m,
-       [3] = &exynos4_clk_sclk_usbphy0,
-       [4] = &exynos4_clk_sclk_usbphy1,
-       [5] = &exynos4_clk_sclk_hdmiphy,
-       [6] = &exynos4_clk_mout_mpll.clk,
-       [7] = &exynos4_clk_mout_epll.clk,
-       [8] = &exynos4_clk_sclk_vpll.clk,
-};
-
-struct clksrc_sources exynos4_clkset_group = {
-       .sources        = exynos4_clkset_group_list,
-       .nr_sources     = ARRAY_SIZE(exynos4_clkset_group_list),
-};
-
-static struct clk *exynos4_clkset_mout_g2d0_list[] = {
-       [0] = &exynos4_clk_mout_mpll.clk,
-       [1] = &exynos4_clk_sclk_apll.clk,
-};
-
-struct clksrc_sources exynos4_clkset_mout_g2d0 = {
-       .sources        = exynos4_clkset_mout_g2d0_list,
-       .nr_sources     = ARRAY_SIZE(exynos4_clkset_mout_g2d0_list),
-};
-
-static struct clk *exynos4_clkset_mout_g2d1_list[] = {
-       [0] = &exynos4_clk_mout_epll.clk,
-       [1] = &exynos4_clk_sclk_vpll.clk,
-};
-
-struct clksrc_sources exynos4_clkset_mout_g2d1 = {
-       .sources        = exynos4_clkset_mout_g2d1_list,
-       .nr_sources     = ARRAY_SIZE(exynos4_clkset_mout_g2d1_list),
-};
-
-static struct clk *exynos4_clkset_mout_mfc0_list[] = {
-       [0] = &exynos4_clk_mout_mpll.clk,
-       [1] = &exynos4_clk_sclk_apll.clk,
-};
-
-static struct clksrc_sources exynos4_clkset_mout_mfc0 = {
-       .sources        = exynos4_clkset_mout_mfc0_list,
-       .nr_sources     = ARRAY_SIZE(exynos4_clkset_mout_mfc0_list),
-};
-
-static struct clksrc_clk exynos4_clk_mout_mfc0 = {
-       .clk    = {
-               .name           = "mout_mfc0",
-       },
-       .sources = &exynos4_clkset_mout_mfc0,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 0, .size = 1 },
-};
-
-static struct clk *exynos4_clkset_mout_mfc1_list[] = {
-       [0] = &exynos4_clk_mout_epll.clk,
-       [1] = &exynos4_clk_sclk_vpll.clk,
-};
-
-static struct clksrc_sources exynos4_clkset_mout_mfc1 = {
-       .sources        = exynos4_clkset_mout_mfc1_list,
-       .nr_sources     = ARRAY_SIZE(exynos4_clkset_mout_mfc1_list),
-};
-
-static struct clksrc_clk exynos4_clk_mout_mfc1 = {
-       .clk    = {
-               .name           = "mout_mfc1",
-       },
-       .sources = &exynos4_clkset_mout_mfc1,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 4, .size = 1 },
-};
-
-static struct clk *exynos4_clkset_mout_mfc_list[] = {
-       [0] = &exynos4_clk_mout_mfc0.clk,
-       [1] = &exynos4_clk_mout_mfc1.clk,
-};
-
-static struct clksrc_sources exynos4_clkset_mout_mfc = {
-       .sources        = exynos4_clkset_mout_mfc_list,
-       .nr_sources     = ARRAY_SIZE(exynos4_clkset_mout_mfc_list),
-};
-
-static struct clk *exynos4_clkset_sclk_dac_list[] = {
-       [0] = &exynos4_clk_sclk_vpll.clk,
-       [1] = &exynos4_clk_sclk_hdmiphy,
-};
-
-static struct clksrc_sources exynos4_clkset_sclk_dac = {
-       .sources        = exynos4_clkset_sclk_dac_list,
-       .nr_sources     = ARRAY_SIZE(exynos4_clkset_sclk_dac_list),
-};
-
-static struct clksrc_clk exynos4_clk_sclk_dac = {
-       .clk            = {
-               .name           = "sclk_dac",
-               .enable         = exynos4_clksrc_mask_tv_ctrl,
-               .ctrlbit        = (1 << 8),
-       },
-       .sources = &exynos4_clkset_sclk_dac,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 8, .size = 1 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_pixel = {
-       .clk            = {
-               .name           = "sclk_pixel",
-               .parent         = &exynos4_clk_sclk_vpll.clk,
-       },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_TV, .shift = 0, .size = 4 },
-};
-
-static struct clk *exynos4_clkset_sclk_hdmi_list[] = {
-       [0] = &exynos4_clk_sclk_pixel.clk,
-       [1] = &exynos4_clk_sclk_hdmiphy,
-};
-
-static struct clksrc_sources exynos4_clkset_sclk_hdmi = {
-       .sources        = exynos4_clkset_sclk_hdmi_list,
-       .nr_sources     = ARRAY_SIZE(exynos4_clkset_sclk_hdmi_list),
-};
-
-static struct clksrc_clk exynos4_clk_sclk_hdmi = {
-       .clk            = {
-               .name           = "sclk_hdmi",
-               .enable         = exynos4_clksrc_mask_tv_ctrl,
-               .ctrlbit        = (1 << 0),
-       },
-       .sources = &exynos4_clkset_sclk_hdmi,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 0, .size = 1 },
-};
-
-static struct clk *exynos4_clkset_sclk_mixer_list[] = {
-       [0] = &exynos4_clk_sclk_dac.clk,
-       [1] = &exynos4_clk_sclk_hdmi.clk,
-};
-
-static struct clksrc_sources exynos4_clkset_sclk_mixer = {
-       .sources        = exynos4_clkset_sclk_mixer_list,
-       .nr_sources     = ARRAY_SIZE(exynos4_clkset_sclk_mixer_list),
-};
-
-static struct clksrc_clk exynos4_clk_sclk_mixer = {
-       .clk    = {
-               .name           = "sclk_mixer",
-               .enable         = exynos4_clksrc_mask_tv_ctrl,
-               .ctrlbit        = (1 << 4),
-       },
-       .sources = &exynos4_clkset_sclk_mixer,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_TV, .shift = 4, .size = 1 },
-};
-
-static struct clksrc_clk *exynos4_sclk_tv[] = {
-       &exynos4_clk_sclk_dac,
-       &exynos4_clk_sclk_pixel,
-       &exynos4_clk_sclk_hdmi,
-       &exynos4_clk_sclk_mixer,
-};
-
-static struct clksrc_clk exynos4_clk_dout_mmc0 = {
-       .clk    = {
-               .name           = "dout_mmc0",
-       },
-       .sources = &exynos4_clkset_group,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 0, .size = 4 },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_dout_mmc1 = {
-       .clk    = {
-               .name           = "dout_mmc1",
-       },
-       .sources = &exynos4_clkset_group,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 4, .size = 4 },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 16, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_dout_mmc2 = {
-       .clk    = {
-               .name           = "dout_mmc2",
-       },
-       .sources = &exynos4_clkset_group,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 8, .size = 4 },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_dout_mmc3 = {
-       .clk    = {
-               .name           = "dout_mmc3",
-       },
-       .sources = &exynos4_clkset_group,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 12, .size = 4 },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 16, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_dout_mmc4 = {
-       .clk            = {
-               .name           = "dout_mmc4",
-       },
-       .sources = &exynos4_clkset_group,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 16, .size = 4 },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS3, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clksrcs[] = {
-       {
-               .clk    = {
-                       .name           = "sclk_pwm",
-                       .enable         = exynos4_clksrc_mask_peril0_ctrl,
-                       .ctrlbit        = (1 << 24),
-               },
-               .sources = &exynos4_clkset_group,
-               .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 24, .size = 4 },
-               .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL3, .shift = 0, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_csis",
-                       .devname        = "s5p-mipi-csis.0",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 24),
-               },
-               .sources = &exynos4_clkset_group,
-               .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 24, .size = 4 },
-               .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 24, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_csis",
-                       .devname        = "s5p-mipi-csis.1",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 28),
-               },
-               .sources = &exynos4_clkset_group,
-               .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 28, .size = 4 },
-               .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 28, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_cam0",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 16),
-               },
-               .sources = &exynos4_clkset_group,
-               .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 16, .size = 4 },
-               .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 16, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_cam1",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 20),
-               },
-               .sources = &exynos4_clkset_group,
-               .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 20, .size = 4 },
-               .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 20, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_fimc",
-                       .devname        = "exynos4-fimc.0",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 0),
-               },
-               .sources = &exynos4_clkset_group,
-               .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 0, .size = 4 },
-               .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 0, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_fimc",
-                       .devname        = "exynos4-fimc.1",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 4),
-               },
-               .sources = &exynos4_clkset_group,
-               .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 4, .size = 4 },
-               .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 4, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_fimc",
-                       .devname        = "exynos4-fimc.2",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 8),
-               },
-               .sources = &exynos4_clkset_group,
-               .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 8, .size = 4 },
-               .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 8, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_fimc",
-                       .devname        = "exynos4-fimc.3",
-                       .enable         = exynos4_clksrc_mask_cam_ctrl,
-                       .ctrlbit        = (1 << 12),
-               },
-               .sources = &exynos4_clkset_group,
-               .reg_src = { .reg = EXYNOS4_CLKSRC_CAM, .shift = 12, .size = 4 },
-               .reg_div = { .reg = EXYNOS4_CLKDIV_CAM, .shift = 12, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_fimd",
-                       .devname        = "exynos4-fb.0",
-                       .enable         = exynos4_clksrc_mask_lcd0_ctrl,
-                       .ctrlbit        = (1 << 0),
-               },
-               .sources = &exynos4_clkset_group,
-               .reg_src = { .reg = EXYNOS4_CLKSRC_LCD0, .shift = 0, .size = 4 },
-               .reg_div = { .reg = EXYNOS4_CLKDIV_LCD0, .shift = 0, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_mfc",
-                       .devname        = "s5p-mfc",
-               },
-               .sources = &exynos4_clkset_mout_mfc,
-               .reg_src = { .reg = EXYNOS4_CLKSRC_MFC, .shift = 8, .size = 1 },
-               .reg_div = { .reg = EXYNOS4_CLKDIV_MFC, .shift = 0, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "ciu",
-                       .parent         = &exynos4_clk_dout_mmc4.clk,
-                       .enable         = exynos4_clksrc_mask_fsys_ctrl,
-                       .ctrlbit        = (1 << 16),
-               },
-               .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS3, .shift = 8, .size = 8 },
-       }
-};
-
-static struct clksrc_clk exynos4_clk_sclk_uart0 = {
-       .clk    = {
-               .name           = "uclk1",
-               .devname        = "exynos4210-uart.0",
-               .enable         = exynos4_clksrc_mask_peril0_ctrl,
-               .ctrlbit        = (1 << 0),
-       },
-       .sources = &exynos4_clkset_group,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 0, .size = 4 },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_uart1 = {
-       .clk    = {
-               .name           = "uclk1",
-               .devname        = "exynos4210-uart.1",
-               .enable         = exynos4_clksrc_mask_peril0_ctrl,
-               .ctrlbit        = (1 << 4),
-       },
-       .sources = &exynos4_clkset_group,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 4, .size = 4 },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 4, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_uart2 = {
-       .clk    = {
-               .name           = "uclk1",
-               .devname        = "exynos4210-uart.2",
-               .enable         = exynos4_clksrc_mask_peril0_ctrl,
-               .ctrlbit        = (1 << 8),
-       },
-       .sources = &exynos4_clkset_group,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 8, .size = 4 },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 8, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_uart3 = {
-       .clk    = {
-               .name           = "uclk1",
-               .devname        = "exynos4210-uart.3",
-               .enable         = exynos4_clksrc_mask_peril0_ctrl,
-               .ctrlbit        = (1 << 12),
-       },
-       .sources = &exynos4_clkset_group,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL0, .shift = 12, .size = 4 },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL0, .shift = 12, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_mmc0 = {
-       .clk    = {
-               .name           = "sclk_mmc",
-               .devname        = "exynos4-sdhci.0",
-               .parent         = &exynos4_clk_dout_mmc0.clk,
-               .enable         = exynos4_clksrc_mask_fsys_ctrl,
-               .ctrlbit        = (1 << 0),
-       },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 8, .size = 8 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_mmc1 = {
-       .clk    = {
-               .name           = "sclk_mmc",
-               .devname        = "exynos4-sdhci.1",
-               .parent         = &exynos4_clk_dout_mmc1.clk,
-               .enable         = exynos4_clksrc_mask_fsys_ctrl,
-               .ctrlbit        = (1 << 4),
-       },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS1, .shift = 24, .size = 8 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_mmc2 = {
-       .clk    = {
-               .name           = "sclk_mmc",
-               .devname        = "exynos4-sdhci.2",
-               .parent         = &exynos4_clk_dout_mmc2.clk,
-               .enable         = exynos4_clksrc_mask_fsys_ctrl,
-               .ctrlbit        = (1 << 8),
-       },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 8, .size = 8 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_mmc3 = {
-       .clk    = {
-               .name           = "sclk_mmc",
-               .devname        = "exynos4-sdhci.3",
-               .parent         = &exynos4_clk_dout_mmc3.clk,
-               .enable         = exynos4_clksrc_mask_fsys_ctrl,
-               .ctrlbit        = (1 << 12),
-       },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS2, .shift = 24, .size = 8 },
-};
-
-static struct clksrc_clk exynos4_clk_mdout_spi0 = {
-       .clk    = {
-               .name           = "mdout_spi",
-               .devname        = "exynos4210-spi.0",
-       },
-       .sources = &exynos4_clkset_group,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 16, .size = 4 },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_mdout_spi1 = {
-       .clk    = {
-               .name           = "mdout_spi",
-               .devname        = "exynos4210-spi.1",
-       },
-       .sources = &exynos4_clkset_group,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 20, .size = 4 },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 16, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_mdout_spi2 = {
-       .clk    = {
-               .name           = "mdout_spi",
-               .devname        = "exynos4210-spi.2",
-       },
-       .sources = &exynos4_clkset_group,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_PERIL1, .shift = 24, .size = 4 },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL2, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_spi0 = {
-       .clk    = {
-               .name           = "sclk_spi",
-               .devname        = "exynos4210-spi.0",
-               .parent         = &exynos4_clk_mdout_spi0.clk,
-               .enable         = exynos4_clksrc_mask_peril1_ctrl,
-               .ctrlbit        = (1 << 16),
-       },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 8, .size = 8 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_spi1 = {
-       .clk    = {
-               .name           = "sclk_spi",
-               .devname        = "exynos4210-spi.1",
-               .parent         = &exynos4_clk_mdout_spi1.clk,
-               .enable         = exynos4_clksrc_mask_peril1_ctrl,
-               .ctrlbit        = (1 << 20),
-       },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL1, .shift = 24, .size = 8 },
-};
-
-static struct clksrc_clk exynos4_clk_sclk_spi2 = {
-       .clk    = {
-               .name           = "sclk_spi",
-               .devname        = "exynos4210-spi.2",
-               .parent         = &exynos4_clk_mdout_spi2.clk,
-               .enable         = exynos4_clksrc_mask_peril1_ctrl,
-               .ctrlbit        = (1 << 24),
-       },
-       .reg_div = { .reg = EXYNOS4_CLKDIV_PERIL2, .shift = 8, .size = 8 },
-};
-
-/* Clock initialization code */
-static struct clksrc_clk *exynos4_sysclks[] = {
-       &exynos4_clk_mout_apll,
-       &exynos4_clk_sclk_apll,
-       &exynos4_clk_mout_epll,
-       &exynos4_clk_mout_mpll,
-       &exynos4_clk_moutcore,
-       &exynos4_clk_coreclk,
-       &exynos4_clk_armclk,
-       &exynos4_clk_aclk_corem0,
-       &exynos4_clk_aclk_cores,
-       &exynos4_clk_aclk_corem1,
-       &exynos4_clk_periphclk,
-       &exynos4_clk_mout_corebus,
-       &exynos4_clk_sclk_dmc,
-       &exynos4_clk_aclk_cored,
-       &exynos4_clk_aclk_corep,
-       &exynos4_clk_aclk_acp,
-       &exynos4_clk_pclk_acp,
-       &exynos4_clk_vpllsrc,
-       &exynos4_clk_sclk_vpll,
-       &exynos4_clk_aclk_200,
-       &exynos4_clk_aclk_100,
-       &exynos4_clk_aclk_160,
-       &exynos4_clk_aclk_133,
-       &exynos4_clk_dout_mmc0,
-       &exynos4_clk_dout_mmc1,
-       &exynos4_clk_dout_mmc2,
-       &exynos4_clk_dout_mmc3,
-       &exynos4_clk_dout_mmc4,
-       &exynos4_clk_mout_mfc0,
-       &exynos4_clk_mout_mfc1,
-};
-
-static struct clk *exynos4_clk_cdev[] = {
-       &exynos4_clk_pdma0,
-       &exynos4_clk_pdma1,
-       &exynos4_clk_mdma1,
-       &exynos4_clk_fimd0,
-};
-
-static struct clksrc_clk *exynos4_clksrc_cdev[] = {
-       &exynos4_clk_sclk_uart0,
-       &exynos4_clk_sclk_uart1,
-       &exynos4_clk_sclk_uart2,
-       &exynos4_clk_sclk_uart3,
-       &exynos4_clk_sclk_mmc0,
-       &exynos4_clk_sclk_mmc1,
-       &exynos4_clk_sclk_mmc2,
-       &exynos4_clk_sclk_mmc3,
-       &exynos4_clk_sclk_spi0,
-       &exynos4_clk_sclk_spi1,
-       &exynos4_clk_sclk_spi2,
-       &exynos4_clk_mdout_spi0,
-       &exynos4_clk_mdout_spi1,
-       &exynos4_clk_mdout_spi2,
-};
-
-static struct clk_lookup exynos4_clk_lookup[] = {
-       CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &exynos4_clk_sclk_uart0.clk),
-       CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos4_clk_sclk_uart1.clk),
-       CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos4_clk_sclk_uart2.clk),
-       CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos4_clk_sclk_uart3.clk),
-       CLKDEV_INIT("exynos4-sdhci.0", "mmc_busclk.2", &exynos4_clk_sclk_mmc0.clk),
-       CLKDEV_INIT("exynos4-sdhci.1", "mmc_busclk.2", &exynos4_clk_sclk_mmc1.clk),
-       CLKDEV_INIT("exynos4-sdhci.2", "mmc_busclk.2", &exynos4_clk_sclk_mmc2.clk),
-       CLKDEV_INIT("exynos4-sdhci.3", "mmc_busclk.2", &exynos4_clk_sclk_mmc3.clk),
-       CLKDEV_INIT("exynos4-fb.0", "lcd", &exynos4_clk_fimd0),
-       CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos4_clk_pdma0),
-       CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos4_clk_pdma1),
-       CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos4_clk_mdma1),
-       CLKDEV_INIT("exynos4210-spi.0", "spi_busclk0", &exynos4_clk_sclk_spi0.clk),
-       CLKDEV_INIT("exynos4210-spi.1", "spi_busclk0", &exynos4_clk_sclk_spi1.clk),
-       CLKDEV_INIT("exynos4210-spi.2", "spi_busclk0", &exynos4_clk_sclk_spi2.clk),
-};
-
-static int xtal_rate;
-
-static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
-{
-       if (soc_is_exynos4210())
-               return s5p_get_pll45xx(xtal_rate, __raw_readl(EXYNOS4_APLL_CON0),
-                                       pll_4508);
-       else if (soc_is_exynos4212() || soc_is_exynos4412())
-               return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS4_APLL_CON0));
-       else
-               return 0;
-}
-
-static struct clk_ops exynos4_fout_apll_ops = {
-       .get_rate = exynos4_fout_apll_get_rate,
-};
-
-static u32 exynos4_vpll_div[][8] = {
-       {  54000000, 3, 53, 3, 1024, 0, 17, 0 },
-       { 108000000, 3, 53, 2, 1024, 0, 17, 0 },
-};
-
-static unsigned long exynos4_vpll_get_rate(struct clk *clk)
-{
-       return clk->rate;
-}
-
-static int exynos4_vpll_set_rate(struct clk *clk, unsigned long rate)
-{
-       unsigned int vpll_con0, vpll_con1 = 0;
-       unsigned int i;
-
-       /* Return if nothing changed */
-       if (clk->rate == rate)
-               return 0;
-
-       vpll_con0 = __raw_readl(EXYNOS4_VPLL_CON0);
-       vpll_con0 &= ~(0x1 << 27 |                                      \
-                       PLL90XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |       \
-                       PLL90XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |       \
-                       PLL90XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
-
-       vpll_con1 = __raw_readl(EXYNOS4_VPLL_CON1);
-       vpll_con1 &= ~(PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT |  \
-                       PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT | \
-                       PLL4650C_KDIV_MASK << PLL46XX_KDIV_SHIFT);
-
-       for (i = 0; i < ARRAY_SIZE(exynos4_vpll_div); i++) {
-               if (exynos4_vpll_div[i][0] == rate) {
-                       vpll_con0 |= exynos4_vpll_div[i][1] << PLL46XX_PDIV_SHIFT;
-                       vpll_con0 |= exynos4_vpll_div[i][2] << PLL46XX_MDIV_SHIFT;
-                       vpll_con0 |= exynos4_vpll_div[i][3] << PLL46XX_SDIV_SHIFT;
-                       vpll_con1 |= exynos4_vpll_div[i][4] << PLL46XX_KDIV_SHIFT;
-                       vpll_con1 |= exynos4_vpll_div[i][5] << PLL46XX_MFR_SHIFT;
-                       vpll_con1 |= exynos4_vpll_div[i][6] << PLL46XX_MRR_SHIFT;
-                       vpll_con0 |= exynos4_vpll_div[i][7] << 27;
-                       break;
-               }
-       }
-
-       if (i == ARRAY_SIZE(exynos4_vpll_div)) {
-               printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n",
-                               __func__);
-               return -EINVAL;
-       }
-
-       __raw_writel(vpll_con0, EXYNOS4_VPLL_CON0);
-       __raw_writel(vpll_con1, EXYNOS4_VPLL_CON1);
-
-       /* Wait for VPLL lock */
-       while (!(__raw_readl(EXYNOS4_VPLL_CON0) & (1 << PLL46XX_LOCKED_SHIFT)))
-               continue;
-
-       clk->rate = rate;
-       return 0;
-}
-
-static struct clk_ops exynos4_vpll_ops = {
-       .get_rate = exynos4_vpll_get_rate,
-       .set_rate = exynos4_vpll_set_rate,
-};
-
-void __init_or_cpufreq exynos4_setup_clocks(void)
-{
-       struct clk *xtal_clk;
-       unsigned long apll = 0;
-       unsigned long mpll = 0;
-       unsigned long epll = 0;
-       unsigned long vpll = 0;
-       unsigned long vpllsrc;
-       unsigned long xtal;
-       unsigned long armclk;
-       unsigned long sclk_dmc;
-       unsigned long aclk_200;
-       unsigned long aclk_100;
-       unsigned long aclk_160;
-       unsigned long aclk_133;
-       unsigned int ptr;
-
-       printk(KERN_DEBUG "%s: registering clocks\n", __func__);
-
-       xtal_clk = clk_get(NULL, "xtal");
-       BUG_ON(IS_ERR(xtal_clk));
-
-       xtal = clk_get_rate(xtal_clk);
-
-       xtal_rate = xtal;
-
-       clk_put(xtal_clk);
-
-       printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
-
-       if (soc_is_exynos4210()) {
-               apll = s5p_get_pll45xx(xtal, __raw_readl(EXYNOS4_APLL_CON0),
-                                       pll_4508);
-               mpll = s5p_get_pll45xx(xtal, __raw_readl(EXYNOS4_MPLL_CON0),
-                                       pll_4508);
-               epll = s5p_get_pll46xx(xtal, __raw_readl(EXYNOS4_EPLL_CON0),
-                                       __raw_readl(EXYNOS4_EPLL_CON1), pll_4600);
-
-               vpllsrc = clk_get_rate(&exynos4_clk_vpllsrc.clk);
-               vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(EXYNOS4_VPLL_CON0),
-                                       __raw_readl(EXYNOS4_VPLL_CON1), pll_4650c);
-       } else if (soc_is_exynos4212() || soc_is_exynos4412()) {
-               apll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS4_APLL_CON0));
-               mpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS4_MPLL_CON0));
-               epll = s5p_get_pll36xx(xtal, __raw_readl(EXYNOS4_EPLL_CON0),
-                                       __raw_readl(EXYNOS4_EPLL_CON1));
-
-               vpllsrc = clk_get_rate(&exynos4_clk_vpllsrc.clk);
-               vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(EXYNOS4_VPLL_CON0),
-                                       __raw_readl(EXYNOS4_VPLL_CON1));
-       } else {
-               /* nothing */
-       }
-
-       clk_fout_apll.ops = &exynos4_fout_apll_ops;
-       clk_fout_mpll.rate = mpll;
-       clk_fout_epll.rate = epll;
-       clk_fout_vpll.ops = &exynos4_vpll_ops;
-       clk_fout_vpll.rate = vpll;
-
-       printk(KERN_INFO "EXYNOS4: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
-                       apll, mpll, epll, vpll);
-
-       armclk = clk_get_rate(&exynos4_clk_armclk.clk);
-       sclk_dmc = clk_get_rate(&exynos4_clk_sclk_dmc.clk);
-
-       aclk_200 = clk_get_rate(&exynos4_clk_aclk_200.clk);
-       aclk_100 = clk_get_rate(&exynos4_clk_aclk_100.clk);
-       aclk_160 = clk_get_rate(&exynos4_clk_aclk_160.clk);
-       aclk_133 = clk_get_rate(&exynos4_clk_aclk_133.clk);
-
-       printk(KERN_INFO "EXYNOS4: ARMCLK=%ld, DMC=%ld, ACLK200=%ld\n"
-                        "ACLK100=%ld, ACLK160=%ld, ACLK133=%ld\n",
-                       armclk, sclk_dmc, aclk_200,
-                       aclk_100, aclk_160, aclk_133);
-
-       clk_f.rate = armclk;
-       clk_h.rate = sclk_dmc;
-       clk_p.rate = aclk_100;
-
-       for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clksrcs); ptr++)
-               s3c_set_clksrc(&exynos4_clksrcs[ptr], true);
-}
-
-static struct clk *exynos4_clks[] __initdata = {
-       &exynos4_clk_sclk_hdmi27m,
-       &exynos4_clk_sclk_hdmiphy,
-       &exynos4_clk_sclk_usbphy0,
-       &exynos4_clk_sclk_usbphy1,
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int exynos4_clock_suspend(void)
-{
-       s3c_pm_do_save(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
-       return 0;
-}
-
-static void exynos4_clock_resume(void)
-{
-       s3c_pm_do_restore_core(exynos4_clock_save, ARRAY_SIZE(exynos4_clock_save));
-}
-
-#else
-#define exynos4_clock_suspend NULL
-#define exynos4_clock_resume NULL
-#endif
-
-static struct syscore_ops exynos4_clock_syscore_ops = {
-       .suspend        = exynos4_clock_suspend,
-       .resume         = exynos4_clock_resume,
-};
-
-void __init exynos4_register_clocks(void)
-{
-       int ptr;
-
-       s3c24xx_register_clocks(exynos4_clks, ARRAY_SIZE(exynos4_clks));
-
-       for (ptr = 0; ptr < ARRAY_SIZE(exynos4_sysclks); ptr++)
-               s3c_register_clksrc(exynos4_sysclks[ptr], 1);
-
-       for (ptr = 0; ptr < ARRAY_SIZE(exynos4_sclk_tv); ptr++)
-               s3c_register_clksrc(exynos4_sclk_tv[ptr], 1);
-
-       for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clksrc_cdev); ptr++)
-               s3c_register_clksrc(exynos4_clksrc_cdev[ptr], 1);
-
-       s3c_register_clksrc(exynos4_clksrcs, ARRAY_SIZE(exynos4_clksrcs));
-       s3c_register_clocks(exynos4_init_clocks_on, ARRAY_SIZE(exynos4_init_clocks_on));
-
-       s3c24xx_register_clocks(exynos4_clk_cdev, ARRAY_SIZE(exynos4_clk_cdev));
-       for (ptr = 0; ptr < ARRAY_SIZE(exynos4_clk_cdev); ptr++)
-               s3c_disable_clocks(exynos4_clk_cdev[ptr], 1);
-
-       s3c_register_clocks(exynos4_init_clocks_off, ARRAY_SIZE(exynos4_init_clocks_off));
-       s3c_disable_clocks(exynos4_init_clocks_off, ARRAY_SIZE(exynos4_init_clocks_off));
-       clkdev_add_table(exynos4_clk_lookup, ARRAY_SIZE(exynos4_clk_lookup));
-
-       register_syscore_ops(&exynos4_clock_syscore_ops);
-       s3c24xx_register_clock(&dummy_apb_pclk);
-
-       s3c_pwmclk_init();
-}
diff --git a/arch/arm/mach-exynos/clock-exynos4.h b/arch/arm/mach-exynos/clock-exynos4.h
deleted file mode 100644 (file)
index bd12d5f..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Header file for exynos4 clock support
- *
- * 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 __ASM_ARCH_CLOCK_H
-#define __ASM_ARCH_CLOCK_H __FILE__
-
-#include <linux/clk.h>
-
-extern struct clksrc_clk exynos4_clk_aclk_133;
-extern struct clksrc_clk exynos4_clk_mout_mpll;
-
-extern struct clksrc_sources exynos4_clkset_mout_corebus;
-extern struct clksrc_sources exynos4_clkset_group;
-
-extern struct clk *exynos4_clkset_aclk_top_list[];
-extern struct clk *exynos4_clkset_group_list[];
-
-extern struct clksrc_sources exynos4_clkset_mout_g2d0;
-extern struct clksrc_sources exynos4_clkset_mout_g2d1;
-
-extern int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable);
-extern int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable);
-extern int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable);
-extern int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable);
-extern int exynos4_clk_ip_dmc_ctrl(struct clk *clk, int enable);
-
-#endif /* __ASM_ARCH_CLOCK_H */
diff --git a/arch/arm/mach-exynos/clock-exynos4210.c b/arch/arm/mach-exynos/clock-exynos4210.c
deleted file mode 100644 (file)
index 19af9f7..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4210 - Clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/syscore_ops.h>
-
-#include <plat/cpu-freq.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/pll.h>
-#include <plat/s5p-clock.h>
-#include <plat/clock-clksrc.h>
-#include <plat/pm.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-#include <mach/regs-clock.h>
-
-#include "common.h"
-#include "clock-exynos4.h"
-
-#ifdef CONFIG_PM_SLEEP
-static struct sleep_save exynos4210_clock_save[] = {
-       SAVE_ITEM(EXYNOS4_CLKSRC_IMAGE),
-       SAVE_ITEM(EXYNOS4_CLKDIV_IMAGE),
-       SAVE_ITEM(EXYNOS4210_CLKSRC_LCD1),
-       SAVE_ITEM(EXYNOS4210_CLKDIV_LCD1),
-       SAVE_ITEM(EXYNOS4210_CLKSRC_MASK_LCD1),
-       SAVE_ITEM(EXYNOS4210_CLKGATE_IP_IMAGE),
-       SAVE_ITEM(EXYNOS4210_CLKGATE_IP_LCD1),
-       SAVE_ITEM(EXYNOS4210_CLKGATE_IP_PERIR),
-};
-#endif
-
-static struct clksrc_clk *sysclks[] = {
-       /* nothing here yet */
-};
-
-static struct clksrc_clk exynos4210_clk_mout_g2d0 = {
-       .clk    = {
-               .name           = "mout_g2d0",
-       },
-       .sources = &exynos4_clkset_mout_g2d0,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 0, .size = 1 },
-};
-
-static struct clksrc_clk exynos4210_clk_mout_g2d1 = {
-       .clk    = {
-               .name           = "mout_g2d1",
-       },
-       .sources = &exynos4_clkset_mout_g2d1,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 4, .size = 1 },
-};
-
-static struct clk *exynos4210_clkset_mout_g2d_list[] = {
-       [0] = &exynos4210_clk_mout_g2d0.clk,
-       [1] = &exynos4210_clk_mout_g2d1.clk,
-};
-
-static struct clksrc_sources exynos4210_clkset_mout_g2d = {
-       .sources        = exynos4210_clkset_mout_g2d_list,
-       .nr_sources     = ARRAY_SIZE(exynos4210_clkset_mout_g2d_list),
-};
-
-static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS4210_CLKSRC_MASK_LCD1, clk, enable);
-}
-
-static struct clksrc_clk clksrcs[] = {
-       {
-               .clk            = {
-                       .name           = "sclk_sata",
-                       .id             = -1,
-                       .enable         = exynos4_clksrc_mask_fsys_ctrl,
-                       .ctrlbit        = (1 << 24),
-               },
-               .sources = &exynos4_clkset_mout_corebus,
-               .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 24, .size = 1 },
-               .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS0, .shift = 20, .size = 4 },
-       }, {
-               .clk            = {
-                       .name           = "sclk_fimd",
-                       .devname        = "exynos4-fb.1",
-                       .enable         = exynos4_clksrc_mask_lcd1_ctrl,
-                       .ctrlbit        = (1 << 0),
-               },
-               .sources = &exynos4_clkset_group,
-               .reg_src = { .reg = EXYNOS4210_CLKSRC_LCD1, .shift = 0, .size = 4 },
-               .reg_div = { .reg = EXYNOS4210_CLKDIV_LCD1, .shift = 0, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_fimg2d",
-               },
-               .sources = &exynos4210_clkset_mout_g2d,
-               .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 8, .size = 1 },
-               .reg_div = { .reg = EXYNOS4_CLKDIV_IMAGE, .shift = 0, .size = 4 },
-       },
-};
-
-static struct clk init_clocks_off[] = {
-       {
-               .name           = "sataphy",
-               .id             = -1,
-               .parent         = &exynos4_clk_aclk_133.clk,
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 3),
-       }, {
-               .name           = "sata",
-               .id             = -1,
-               .parent         = &exynos4_clk_aclk_133.clk,
-               .enable         = exynos4_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 10),
-       }, {
-               .name           = "fimd",
-               .devname        = "exynos4-fb.1",
-               .enable         = exynos4_clk_ip_lcd1_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.9",
-               .enable         = exynos4_clk_ip_image_ctrl,
-               .ctrlbit        = (1 << 3),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.11",
-               .enable         = exynos4_clk_ip_lcd1_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "fimg2d",
-               .enable         = exynos4_clk_ip_image_ctrl,
-               .ctrlbit        = (1 << 0),
-       },
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int exynos4210_clock_suspend(void)
-{
-       s3c_pm_do_save(exynos4210_clock_save, ARRAY_SIZE(exynos4210_clock_save));
-
-       return 0;
-}
-
-static void exynos4210_clock_resume(void)
-{
-       s3c_pm_do_restore_core(exynos4210_clock_save, ARRAY_SIZE(exynos4210_clock_save));
-}
-
-#else
-#define exynos4210_clock_suspend NULL
-#define exynos4210_clock_resume NULL
-#endif
-
-static struct syscore_ops exynos4210_clock_syscore_ops = {
-       .suspend        = exynos4210_clock_suspend,
-       .resume         = exynos4210_clock_resume,
-};
-
-void __init exynos4210_register_clocks(void)
-{
-       int ptr;
-
-       exynos4_clk_mout_mpll.reg_src.reg = EXYNOS4_CLKSRC_CPU;
-       exynos4_clk_mout_mpll.reg_src.shift = 8;
-       exynos4_clk_mout_mpll.reg_src.size = 1;
-
-       for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
-               s3c_register_clksrc(sysclks[ptr], 1);
-
-       s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
-
-       s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-       s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-
-       register_syscore_ops(&exynos4210_clock_syscore_ops);
-}
diff --git a/arch/arm/mach-exynos/clock-exynos4212.c b/arch/arm/mach-exynos/clock-exynos4212.c
deleted file mode 100644 (file)
index 529476f..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4212 - Clock support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/syscore_ops.h>
-
-#include <plat/cpu-freq.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/pll.h>
-#include <plat/s5p-clock.h>
-#include <plat/clock-clksrc.h>
-#include <plat/pm.h>
-
-#include <mach/hardware.h>
-#include <mach/map.h>
-#include <mach/regs-clock.h>
-
-#include "common.h"
-#include "clock-exynos4.h"
-
-#ifdef CONFIG_PM_SLEEP
-static struct sleep_save exynos4212_clock_save[] = {
-       SAVE_ITEM(EXYNOS4_CLKSRC_IMAGE),
-       SAVE_ITEM(EXYNOS4_CLKDIV_IMAGE),
-       SAVE_ITEM(EXYNOS4212_CLKGATE_IP_IMAGE),
-       SAVE_ITEM(EXYNOS4212_CLKGATE_IP_PERIR),
-};
-#endif
-
-static int exynos4212_clk_ip_isp0_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS4_CLKGATE_IP_ISP0, clk, enable);
-}
-
-static int exynos4212_clk_ip_isp1_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS4_CLKGATE_IP_ISP1, clk, enable);
-}
-
-static struct clk *clk_src_mpll_user_list[] = {
-       [0] = &clk_fin_mpll,
-       [1] = &exynos4_clk_mout_mpll.clk,
-};
-
-static struct clksrc_sources clk_src_mpll_user = {
-       .sources        = clk_src_mpll_user_list,
-       .nr_sources     = ARRAY_SIZE(clk_src_mpll_user_list),
-};
-
-static struct clksrc_clk clk_mout_mpll_user = {
-       .clk = {
-               .name           = "mout_mpll_user",
-       },
-       .sources        = &clk_src_mpll_user,
-       .reg_src        = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 24, .size = 1 },
-};
-
-static struct clksrc_clk exynos4x12_clk_mout_g2d0 = {
-       .clk    = {
-               .name           = "mout_g2d0",
-       },
-       .sources = &exynos4_clkset_mout_g2d0,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 20, .size = 1 },
-};
-
-static struct clksrc_clk exynos4x12_clk_mout_g2d1 = {
-       .clk    = {
-               .name           = "mout_g2d1",
-       },
-       .sources = &exynos4_clkset_mout_g2d1,
-       .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 24, .size = 1 },
-};
-
-static struct clk *exynos4x12_clkset_mout_g2d_list[] = {
-       [0] = &exynos4x12_clk_mout_g2d0.clk,
-       [1] = &exynos4x12_clk_mout_g2d1.clk,
-};
-
-static struct clksrc_sources exynos4x12_clkset_mout_g2d = {
-       .sources        = exynos4x12_clkset_mout_g2d_list,
-       .nr_sources     = ARRAY_SIZE(exynos4x12_clkset_mout_g2d_list),
-};
-
-static struct clksrc_clk *sysclks[] = {
-       &clk_mout_mpll_user,
-};
-
-static struct clksrc_clk clksrcs[] = {
-       {
-               .clk    = {
-                       .name           = "sclk_fimg2d",
-               },
-               .sources = &exynos4x12_clkset_mout_g2d,
-               .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 28, .size = 1 },
-               .reg_div = { .reg = EXYNOS4_CLKDIV_DMC1, .shift = 0, .size = 4 },
-       },
-};
-
-static struct clk init_clocks_off[] = {
-       {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.9",
-               .enable         = exynos4_clk_ip_dmc_ctrl,
-               .ctrlbit        = (1 << 24),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.12",
-               .enable         = exynos4212_clk_ip_isp0_ctrl,
-               .ctrlbit        = (7 << 8),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.13",
-               .enable         = exynos4212_clk_ip_isp1_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.14",
-               .enable         = exynos4212_clk_ip_isp0_ctrl,
-               .ctrlbit        = (1 << 11),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.15",
-               .enable         = exynos4212_clk_ip_isp0_ctrl,
-               .ctrlbit        = (1 << 12),
-       }, {
-               .name           = "flite",
-               .devname        = "exynos-fimc-lite.0",
-               .enable         = exynos4212_clk_ip_isp0_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "flite",
-               .devname        = "exynos-fimc-lite.1",
-               .enable         = exynos4212_clk_ip_isp0_ctrl,
-               .ctrlbit        = (1 << 3),
-       }, {
-               .name           = "fimg2d",
-               .enable         = exynos4_clk_ip_dmc_ctrl,
-               .ctrlbit        = (1 << 23),
-       },
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int exynos4212_clock_suspend(void)
-{
-       s3c_pm_do_save(exynos4212_clock_save, ARRAY_SIZE(exynos4212_clock_save));
-
-       return 0;
-}
-
-static void exynos4212_clock_resume(void)
-{
-       s3c_pm_do_restore_core(exynos4212_clock_save, ARRAY_SIZE(exynos4212_clock_save));
-}
-
-#else
-#define exynos4212_clock_suspend NULL
-#define exynos4212_clock_resume NULL
-#endif
-
-static struct syscore_ops exynos4212_clock_syscore_ops = {
-       .suspend        = exynos4212_clock_suspend,
-       .resume         = exynos4212_clock_resume,
-};
-
-void __init exynos4212_register_clocks(void)
-{
-       int ptr;
-
-       /* usbphy1 is removed */
-       exynos4_clkset_group_list[4] = NULL;
-
-       /* mout_mpll_user is used */
-       exynos4_clkset_group_list[6] = &clk_mout_mpll_user.clk;
-       exynos4_clkset_aclk_top_list[0] = &clk_mout_mpll_user.clk;
-
-       exynos4_clk_mout_mpll.reg_src.reg = EXYNOS4_CLKSRC_DMC;
-       exynos4_clk_mout_mpll.reg_src.shift = 12;
-       exynos4_clk_mout_mpll.reg_src.size = 1;
-
-       for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
-               s3c_register_clksrc(sysclks[ptr], 1);
-
-       s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
-
-       s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-       s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-
-       register_syscore_ops(&exynos4212_clock_syscore_ops);
-}
diff --git a/arch/arm/mach-exynos/clock-exynos5.c b/arch/arm/mach-exynos/clock-exynos5.c
deleted file mode 100644 (file)
index b0ea31f..0000000
+++ /dev/null
@@ -1,1645 +0,0 @@
-/*
- * Copyright (c) 2012 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * Clock support for EXYNOS5 SoCs
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/syscore_ops.h>
-
-#include <plat/cpu-freq.h>
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/pll.h>
-#include <plat/s5p-clock.h>
-#include <plat/clock-clksrc.h>
-#include <plat/pm.h>
-
-#include <mach/map.h>
-#include <mach/regs-clock.h>
-
-#include "common.h"
-
-#ifdef CONFIG_PM_SLEEP
-static struct sleep_save exynos5_clock_save[] = {
-       SAVE_ITEM(EXYNOS5_CLKSRC_MASK_TOP),
-       SAVE_ITEM(EXYNOS5_CLKSRC_MASK_GSCL),
-       SAVE_ITEM(EXYNOS5_CLKSRC_MASK_DISP1_0),
-       SAVE_ITEM(EXYNOS5_CLKSRC_MASK_FSYS),
-       SAVE_ITEM(EXYNOS5_CLKSRC_MASK_MAUDIO),
-       SAVE_ITEM(EXYNOS5_CLKSRC_MASK_PERIC0),
-       SAVE_ITEM(EXYNOS5_CLKSRC_MASK_PERIC1),
-       SAVE_ITEM(EXYNOS5_CLKGATE_IP_GSCL),
-       SAVE_ITEM(EXYNOS5_CLKGATE_IP_DISP1),
-       SAVE_ITEM(EXYNOS5_CLKGATE_IP_MFC),
-       SAVE_ITEM(EXYNOS5_CLKGATE_IP_G3D),
-       SAVE_ITEM(EXYNOS5_CLKGATE_IP_GEN),
-       SAVE_ITEM(EXYNOS5_CLKGATE_IP_FSYS),
-       SAVE_ITEM(EXYNOS5_CLKGATE_IP_PERIC),
-       SAVE_ITEM(EXYNOS5_CLKGATE_IP_PERIS),
-       SAVE_ITEM(EXYNOS5_CLKGATE_BLOCK),
-       SAVE_ITEM(EXYNOS5_CLKDIV_TOP0),
-       SAVE_ITEM(EXYNOS5_CLKDIV_TOP1),
-       SAVE_ITEM(EXYNOS5_CLKDIV_GSCL),
-       SAVE_ITEM(EXYNOS5_CLKDIV_DISP1_0),
-       SAVE_ITEM(EXYNOS5_CLKDIV_GEN),
-       SAVE_ITEM(EXYNOS5_CLKDIV_MAUDIO),
-       SAVE_ITEM(EXYNOS5_CLKDIV_FSYS0),
-       SAVE_ITEM(EXYNOS5_CLKDIV_FSYS1),
-       SAVE_ITEM(EXYNOS5_CLKDIV_FSYS2),
-       SAVE_ITEM(EXYNOS5_CLKDIV_FSYS3),
-       SAVE_ITEM(EXYNOS5_CLKDIV_PERIC0),
-       SAVE_ITEM(EXYNOS5_CLKDIV_PERIC1),
-       SAVE_ITEM(EXYNOS5_CLKDIV_PERIC2),
-       SAVE_ITEM(EXYNOS5_CLKDIV_PERIC3),
-       SAVE_ITEM(EXYNOS5_CLKDIV_PERIC4),
-       SAVE_ITEM(EXYNOS5_CLKDIV_PERIC5),
-       SAVE_ITEM(EXYNOS5_SCLK_DIV_ISP),
-       SAVE_ITEM(EXYNOS5_CLKSRC_TOP0),
-       SAVE_ITEM(EXYNOS5_CLKSRC_TOP1),
-       SAVE_ITEM(EXYNOS5_CLKSRC_TOP2),
-       SAVE_ITEM(EXYNOS5_CLKSRC_TOP3),
-       SAVE_ITEM(EXYNOS5_CLKSRC_GSCL),
-       SAVE_ITEM(EXYNOS5_CLKSRC_DISP1_0),
-       SAVE_ITEM(EXYNOS5_CLKSRC_MAUDIO),
-       SAVE_ITEM(EXYNOS5_CLKSRC_FSYS),
-       SAVE_ITEM(EXYNOS5_CLKSRC_PERIC0),
-       SAVE_ITEM(EXYNOS5_CLKSRC_PERIC1),
-       SAVE_ITEM(EXYNOS5_SCLK_SRC_ISP),
-       SAVE_ITEM(EXYNOS5_EPLL_CON0),
-       SAVE_ITEM(EXYNOS5_EPLL_CON1),
-       SAVE_ITEM(EXYNOS5_EPLL_CON2),
-       SAVE_ITEM(EXYNOS5_VPLL_CON0),
-       SAVE_ITEM(EXYNOS5_VPLL_CON1),
-       SAVE_ITEM(EXYNOS5_VPLL_CON2),
-       SAVE_ITEM(EXYNOS5_PWR_CTRL1),
-       SAVE_ITEM(EXYNOS5_PWR_CTRL2),
-};
-#endif
-
-static struct clk exynos5_clk_sclk_dptxphy = {
-       .name           = "sclk_dptx",
-};
-
-static struct clk exynos5_clk_sclk_hdmi24m = {
-       .name           = "sclk_hdmi24m",
-       .rate           = 24000000,
-};
-
-static struct clk exynos5_clk_sclk_hdmi27m = {
-       .name           = "sclk_hdmi27m",
-       .rate           = 27000000,
-};
-
-static struct clk exynos5_clk_sclk_hdmiphy = {
-       .name           = "sclk_hdmiphy",
-};
-
-static struct clk exynos5_clk_sclk_usbphy = {
-       .name           = "sclk_usbphy",
-       .rate           = 48000000,
-};
-
-static int exynos5_clksrc_mask_top_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_TOP, clk, enable);
-}
-
-static int exynos5_clksrc_mask_disp1_0_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_DISP1_0, clk, enable);
-}
-
-static int exynos5_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_FSYS, clk, enable);
-}
-
-static int exynos5_clksrc_mask_gscl_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_GSCL, clk, enable);
-}
-
-static int exynos5_clksrc_mask_peric0_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_PERIC0, clk, enable);
-}
-
-static int exynos5_clksrc_mask_peric1_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_PERIC1, clk, enable);
-}
-
-static int exynos5_clk_ip_acp_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ACP, clk, enable);
-}
-
-static int exynos5_clk_ip_core_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS5_CLKGATE_IP_CORE, clk, enable);
-}
-
-static int exynos5_clk_ip_disp1_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS5_CLKGATE_IP_DISP1, clk, enable);
-}
-
-static int exynos5_clk_ip_fsys_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS5_CLKGATE_IP_FSYS, clk, enable);
-}
-
-static int exynos5_clk_block_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS5_CLKGATE_BLOCK, clk, enable);
-}
-
-static int exynos5_clk_ip_gen_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GEN, clk, enable);
-}
-
-static int exynos5_clk_ip_mfc_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS5_CLKGATE_IP_MFC, clk, enable);
-}
-
-static int exynos5_clk_ip_peric_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIC, clk, enable);
-}
-
-static int exynos5_clk_ip_peris_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIS, clk, enable);
-}
-
-static int exynos5_clk_ip_gscl_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GSCL, clk, enable);
-}
-
-static int exynos5_clk_ip_isp0_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ISP0, clk, enable);
-}
-
-static int exynos5_clk_ip_isp1_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(EXYNOS5_CLKGATE_IP_ISP1, clk, enable);
-}
-
-static int exynos5_clk_hdmiphy_ctrl(struct clk *clk, int enable)
-{
-       return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
-}
-
-/* Core list of CMU_CPU side */
-
-static struct clksrc_clk exynos5_clk_mout_apll = {
-       .clk    = {
-               .name           = "mout_apll",
-       },
-       .sources = &clk_src_apll,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_CPU, .shift = 0, .size = 1 },
-};
-
-static struct clksrc_clk exynos5_clk_sclk_apll = {
-       .clk    = {
-               .name           = "sclk_apll",
-               .parent         = &exynos5_clk_mout_apll.clk,
-       },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 24, .size = 3 },
-};
-
-static struct clksrc_clk exynos5_clk_mout_bpll_fout = {
-       .clk    = {
-               .name           = "mout_bpll_fout",
-       },
-       .sources = &clk_src_bpll_fout,
-       .reg_src = { .reg = EXYNOS5_PLL_DIV2_SEL, .shift = 0, .size = 1 },
-};
-
-static struct clk *exynos5_clk_src_bpll_list[] = {
-       [0] = &clk_fin_bpll,
-       [1] = &exynos5_clk_mout_bpll_fout.clk,
-};
-
-static struct clksrc_sources exynos5_clk_src_bpll = {
-       .sources        = exynos5_clk_src_bpll_list,
-       .nr_sources     = ARRAY_SIZE(exynos5_clk_src_bpll_list),
-};
-
-static struct clksrc_clk exynos5_clk_mout_bpll = {
-       .clk    = {
-               .name           = "mout_bpll",
-       },
-       .sources = &exynos5_clk_src_bpll,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 0, .size = 1 },
-};
-
-static struct clk *exynos5_clk_src_bpll_user_list[] = {
-       [0] = &clk_fin_mpll,
-       [1] = &exynos5_clk_mout_bpll.clk,
-};
-
-static struct clksrc_sources exynos5_clk_src_bpll_user = {
-       .sources        = exynos5_clk_src_bpll_user_list,
-       .nr_sources     = ARRAY_SIZE(exynos5_clk_src_bpll_user_list),
-};
-
-static struct clksrc_clk exynos5_clk_mout_bpll_user = {
-       .clk    = {
-               .name           = "mout_bpll_user",
-       },
-       .sources = &exynos5_clk_src_bpll_user,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 24, .size = 1 },
-};
-
-static struct clksrc_clk exynos5_clk_mout_cpll = {
-       .clk    = {
-               .name           = "mout_cpll",
-       },
-       .sources = &clk_src_cpll,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 8, .size = 1 },
-};
-
-static struct clksrc_clk exynos5_clk_mout_epll = {
-       .clk    = {
-               .name           = "mout_epll",
-       },
-       .sources = &clk_src_epll,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 12, .size = 1 },
-};
-
-static struct clksrc_clk exynos5_clk_mout_mpll_fout = {
-       .clk    = {
-               .name           = "mout_mpll_fout",
-       },
-       .sources = &clk_src_mpll_fout,
-       .reg_src = { .reg = EXYNOS5_PLL_DIV2_SEL, .shift = 4, .size = 1 },
-};
-
-static struct clk *exynos5_clk_src_mpll_list[] = {
-       [0] = &clk_fin_mpll,
-       [1] = &exynos5_clk_mout_mpll_fout.clk,
-};
-
-static struct clksrc_sources exynos5_clk_src_mpll = {
-       .sources        = exynos5_clk_src_mpll_list,
-       .nr_sources     = ARRAY_SIZE(exynos5_clk_src_mpll_list),
-};
-
-static struct clksrc_clk exynos5_clk_mout_mpll = {
-       .clk = {
-               .name           = "mout_mpll",
-       },
-       .sources = &exynos5_clk_src_mpll,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_CORE1, .shift = 8, .size = 1 },
-};
-
-static struct clk *exynos_clkset_vpllsrc_list[] = {
-       [0] = &clk_fin_vpll,
-       [1] = &exynos5_clk_sclk_hdmi27m,
-};
-
-static struct clksrc_sources exynos5_clkset_vpllsrc = {
-       .sources        = exynos_clkset_vpllsrc_list,
-       .nr_sources     = ARRAY_SIZE(exynos_clkset_vpllsrc_list),
-};
-
-static struct clksrc_clk exynos5_clk_vpllsrc = {
-       .clk    = {
-               .name           = "vpll_src",
-               .enable         = exynos5_clksrc_mask_top_ctrl,
-               .ctrlbit        = (1 << 0),
-       },
-       .sources = &exynos5_clkset_vpllsrc,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 0, .size = 1 },
-};
-
-static struct clk *exynos5_clkset_sclk_vpll_list[] = {
-       [0] = &exynos5_clk_vpllsrc.clk,
-       [1] = &clk_fout_vpll,
-};
-
-static struct clksrc_sources exynos5_clkset_sclk_vpll = {
-       .sources        = exynos5_clkset_sclk_vpll_list,
-       .nr_sources     = ARRAY_SIZE(exynos5_clkset_sclk_vpll_list),
-};
-
-static struct clksrc_clk exynos5_clk_sclk_vpll = {
-       .clk    = {
-               .name           = "sclk_vpll",
-       },
-       .sources = &exynos5_clkset_sclk_vpll,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 16, .size = 1 },
-};
-
-static struct clksrc_clk exynos5_clk_sclk_pixel = {
-       .clk    = {
-               .name           = "sclk_pixel",
-               .parent         = &exynos5_clk_sclk_vpll.clk,
-       },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_DISP1_0, .shift = 28, .size = 4 },
-};
-
-static struct clk *exynos5_clkset_sclk_hdmi_list[] = {
-       [0] = &exynos5_clk_sclk_pixel.clk,
-       [1] = &exynos5_clk_sclk_hdmiphy,
-};
-
-static struct clksrc_sources exynos5_clkset_sclk_hdmi = {
-       .sources        = exynos5_clkset_sclk_hdmi_list,
-       .nr_sources     = ARRAY_SIZE(exynos5_clkset_sclk_hdmi_list),
-};
-
-static struct clksrc_clk exynos5_clk_sclk_hdmi = {
-       .clk    = {
-               .name           = "sclk_hdmi",
-               .enable         = exynos5_clksrc_mask_disp1_0_ctrl,
-               .ctrlbit        = (1 << 20),
-       },
-       .sources = &exynos5_clkset_sclk_hdmi,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_DISP1_0, .shift = 20, .size = 1 },
-};
-
-static struct clksrc_clk *exynos5_sclk_tv[] = {
-       &exynos5_clk_sclk_pixel,
-       &exynos5_clk_sclk_hdmi,
-};
-
-static struct clk *exynos5_clk_src_mpll_user_list[] = {
-       [0] = &clk_fin_mpll,
-       [1] = &exynos5_clk_mout_mpll.clk,
-};
-
-static struct clksrc_sources exynos5_clk_src_mpll_user = {
-       .sources        = exynos5_clk_src_mpll_user_list,
-       .nr_sources     = ARRAY_SIZE(exynos5_clk_src_mpll_user_list),
-};
-
-static struct clksrc_clk exynos5_clk_mout_mpll_user = {
-       .clk    = {
-               .name           = "mout_mpll_user",
-       },
-       .sources = &exynos5_clk_src_mpll_user,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 20, .size = 1 },
-};
-
-static struct clk *exynos5_clkset_mout_cpu_list[] = {
-       [0] = &exynos5_clk_mout_apll.clk,
-       [1] = &exynos5_clk_mout_mpll.clk,
-};
-
-static struct clksrc_sources exynos5_clkset_mout_cpu = {
-       .sources        = exynos5_clkset_mout_cpu_list,
-       .nr_sources     = ARRAY_SIZE(exynos5_clkset_mout_cpu_list),
-};
-
-static struct clksrc_clk exynos5_clk_mout_cpu = {
-       .clk    = {
-               .name           = "mout_cpu",
-       },
-       .sources = &exynos5_clkset_mout_cpu,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_CPU, .shift = 16, .size = 1 },
-};
-
-static struct clksrc_clk exynos5_clk_dout_armclk = {
-       .clk    = {
-               .name           = "dout_armclk",
-               .parent         = &exynos5_clk_mout_cpu.clk,
-       },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 0, .size = 3 },
-};
-
-static struct clksrc_clk exynos5_clk_dout_arm2clk = {
-       .clk    = {
-               .name           = "dout_arm2clk",
-               .parent         = &exynos5_clk_dout_armclk.clk,
-       },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 28, .size = 3 },
-};
-
-static struct clk exynos5_clk_armclk = {
-       .name           = "armclk",
-       .parent         = &exynos5_clk_dout_arm2clk.clk,
-};
-
-/* Core list of CMU_CDREX side */
-
-static struct clk *exynos5_clkset_cdrex_list[] = {
-       [0] = &exynos5_clk_mout_mpll.clk,
-       [1] = &exynos5_clk_mout_bpll.clk,
-};
-
-static struct clksrc_sources exynos5_clkset_cdrex = {
-       .sources        = exynos5_clkset_cdrex_list,
-       .nr_sources     = ARRAY_SIZE(exynos5_clkset_cdrex_list),
-};
-
-static struct clksrc_clk exynos5_clk_cdrex = {
-       .clk    = {
-               .name           = "clk_cdrex",
-       },
-       .sources = &exynos5_clkset_cdrex,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 4, .size = 1 },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_CDREX, .shift = 16, .size = 3 },
-};
-
-static struct clksrc_clk exynos5_clk_aclk_acp = {
-       .clk    = {
-               .name           = "aclk_acp",
-               .parent         = &exynos5_clk_mout_mpll.clk,
-       },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_ACP, .shift = 0, .size = 3 },
-};
-
-static struct clksrc_clk exynos5_clk_pclk_acp = {
-       .clk    = {
-               .name           = "pclk_acp",
-               .parent         = &exynos5_clk_aclk_acp.clk,
-       },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_ACP, .shift = 4, .size = 3 },
-};
-
-/* Core list of CMU_TOP side */
-
-static struct clk *exynos5_clkset_aclk_top_list[] = {
-       [0] = &exynos5_clk_mout_mpll_user.clk,
-       [1] = &exynos5_clk_mout_bpll_user.clk,
-};
-
-static struct clksrc_sources exynos5_clkset_aclk = {
-       .sources        = exynos5_clkset_aclk_top_list,
-       .nr_sources     = ARRAY_SIZE(exynos5_clkset_aclk_top_list),
-};
-
-static struct clksrc_clk exynos5_clk_aclk_400 = {
-       .clk    = {
-               .name           = "aclk_400",
-       },
-       .sources = &exynos5_clkset_aclk,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 20, .size = 1 },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 },
-};
-
-static struct clk *exynos5_clkset_aclk_333_166_list[] = {
-       [0] = &exynos5_clk_mout_cpll.clk,
-       [1] = &exynos5_clk_mout_mpll_user.clk,
-};
-
-static struct clksrc_sources exynos5_clkset_aclk_333_166 = {
-       .sources        = exynos5_clkset_aclk_333_166_list,
-       .nr_sources     = ARRAY_SIZE(exynos5_clkset_aclk_333_166_list),
-};
-
-static struct clksrc_clk exynos5_clk_aclk_333 = {
-       .clk    = {
-               .name           = "aclk_333",
-       },
-       .sources = &exynos5_clkset_aclk_333_166,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 16, .size = 1 },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 20, .size = 3 },
-};
-
-static struct clksrc_clk exynos5_clk_aclk_166 = {
-       .clk    = {
-               .name           = "aclk_166",
-       },
-       .sources = &exynos5_clkset_aclk_333_166,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 8, .size = 1 },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 8, .size = 3 },
-};
-
-static struct clksrc_clk exynos5_clk_aclk_266 = {
-       .clk    = {
-               .name           = "aclk_266",
-               .parent         = &exynos5_clk_mout_mpll_user.clk,
-       },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 16, .size = 3 },
-};
-
-static struct clksrc_clk exynos5_clk_aclk_200 = {
-       .clk    = {
-               .name           = "aclk_200",
-       },
-       .sources = &exynos5_clkset_aclk,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 12, .size = 1 },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 12, .size = 3 },
-};
-
-static struct clksrc_clk exynos5_clk_aclk_66_pre = {
-       .clk    = {
-               .name           = "aclk_66_pre",
-               .parent         = &exynos5_clk_mout_mpll_user.clk,
-       },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_TOP1, .shift = 24, .size = 3 },
-};
-
-static struct clksrc_clk exynos5_clk_aclk_66 = {
-       .clk    = {
-               .name           = "aclk_66",
-               .parent         = &exynos5_clk_aclk_66_pre.clk,
-       },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 0, .size = 3 },
-};
-
-static struct clksrc_clk exynos5_clk_mout_aclk_300_gscl_mid = {
-       .clk    = {
-               .name           = "mout_aclk_300_gscl_mid",
-       },
-       .sources = &exynos5_clkset_aclk,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 24, .size = 1 },
-};
-
-static struct clk *exynos5_clkset_aclk_300_mid1_list[] = {
-       [0] = &exynos5_clk_sclk_vpll.clk,
-       [1] = &exynos5_clk_mout_cpll.clk,
-};
-
-static struct clksrc_sources exynos5_clkset_aclk_300_gscl_mid1 = {
-       .sources        = exynos5_clkset_aclk_300_mid1_list,
-       .nr_sources     = ARRAY_SIZE(exynos5_clkset_aclk_300_mid1_list),
-};
-
-static struct clksrc_clk exynos5_clk_mout_aclk_300_gscl_mid1 = {
-       .clk    = {
-               .name           = "mout_aclk_300_gscl_mid1",
-       },
-       .sources = &exynos5_clkset_aclk_300_gscl_mid1,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP1, .shift = 12, .size = 1 },
-};
-
-static struct clk *exynos5_clkset_aclk_300_gscl_list[] = {
-       [0] = &exynos5_clk_mout_aclk_300_gscl_mid.clk,
-       [1] = &exynos5_clk_mout_aclk_300_gscl_mid1.clk,
-};
-
-static struct clksrc_sources exynos5_clkset_aclk_300_gscl = {
-       .sources        = exynos5_clkset_aclk_300_gscl_list,
-       .nr_sources     = ARRAY_SIZE(exynos5_clkset_aclk_300_gscl_list),
-};
-
-static struct clksrc_clk exynos5_clk_mout_aclk_300_gscl = {
-       .clk    = {
-               .name           = "mout_aclk_300_gscl",
-       },
-       .sources = &exynos5_clkset_aclk_300_gscl,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 25, .size = 1 },
-};
-
-static struct clk *exynos5_clk_src_gscl_300_list[] = {
-       [0] = &clk_ext_xtal_mux,
-       [1] = &exynos5_clk_mout_aclk_300_gscl.clk,
-};
-
-static struct clksrc_sources exynos5_clk_src_gscl_300 = {
-       .sources        = exynos5_clk_src_gscl_300_list,
-       .nr_sources     = ARRAY_SIZE(exynos5_clk_src_gscl_300_list),
-};
-
-static struct clksrc_clk exynos5_clk_aclk_300_gscl = {
-       .clk    = {
-               .name           = "aclk_300_gscl",
-       },
-       .sources = &exynos5_clk_src_gscl_300,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_TOP3, .shift = 10, .size = 1 },
-};
-
-static struct clk exynos5_init_clocks_off[] = {
-       {
-               .name           = "timers",
-               .parent         = &exynos5_clk_aclk_66.clk,
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 24),
-       }, {
-               .name           = "tmu_apbif",
-               .parent         = &exynos5_clk_aclk_66.clk,
-               .enable         = exynos5_clk_ip_peris_ctrl,
-               .ctrlbit        = (1 << 21),
-       }, {
-               .name           = "rtc",
-               .parent         = &exynos5_clk_aclk_66.clk,
-               .enable         = exynos5_clk_ip_peris_ctrl,
-               .ctrlbit        = (1 << 20),
-       }, {
-               .name           = "watchdog",
-               .parent         = &exynos5_clk_aclk_66.clk,
-               .enable         = exynos5_clk_ip_peris_ctrl,
-               .ctrlbit        = (1 << 19),
-       }, {
-               .name           = "biu",        /* bus interface unit clock */
-               .devname        = "dw_mmc.0",
-               .parent         = &exynos5_clk_aclk_200.clk,
-               .enable         = exynos5_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 12),
-       }, {
-               .name           = "biu",
-               .devname        = "dw_mmc.1",
-               .parent         = &exynos5_clk_aclk_200.clk,
-               .enable         = exynos5_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 13),
-       }, {
-               .name           = "biu",
-               .devname        = "dw_mmc.2",
-               .parent         = &exynos5_clk_aclk_200.clk,
-               .enable         = exynos5_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 14),
-       }, {
-               .name           = "biu",
-               .devname        = "dw_mmc.3",
-               .parent         = &exynos5_clk_aclk_200.clk,
-               .enable         = exynos5_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 15),
-       }, {
-               .name           = "sata",
-               .devname        = "exynos5-sata",
-               .parent         = &exynos5_clk_aclk_200.clk,
-               .enable         = exynos5_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 6),
-       }, {
-               .name           = "sata-phy",
-               .devname        = "exynos5-sata-phy",
-               .parent         = &exynos5_clk_aclk_200.clk,
-               .enable         = exynos5_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 24),
-       }, {
-               .name           = "i2c",
-               .devname        = "exynos5-sata-phy-i2c",
-               .parent         = &exynos5_clk_aclk_200.clk,
-               .enable         = exynos5_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 25),
-       }, {
-               .name           = "mfc",
-               .devname        = "s5p-mfc-v6",
-               .enable         = exynos5_clk_ip_mfc_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "hdmi",
-               .devname        = "exynos5-hdmi",
-               .enable         = exynos5_clk_ip_disp1_ctrl,
-               .ctrlbit        = (1 << 6),
-       }, {
-               .name           = "hdmiphy",
-               .devname        = "exynos5-hdmi",
-               .enable         = exynos5_clk_hdmiphy_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "mixer",
-               .devname        = "exynos5-mixer",
-               .enable         = exynos5_clk_ip_disp1_ctrl,
-               .ctrlbit        = (1 << 5),
-       }, {
-               .name           = "dp",
-               .devname        = "exynos-dp",
-               .enable         = exynos5_clk_ip_disp1_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "jpeg",
-               .enable         = exynos5_clk_ip_gen_ctrl,
-               .ctrlbit        = (1 << 2),
-       }, {
-               .name           = "dsim0",
-               .enable         = exynos5_clk_ip_disp1_ctrl,
-               .ctrlbit        = (1 << 3),
-       }, {
-               .name           = "iis",
-               .devname        = "samsung-i2s.1",
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 20),
-       }, {
-               .name           = "iis",
-               .devname        = "samsung-i2s.2",
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 21),
-       }, {
-               .name           = "pcm",
-               .devname        = "samsung-pcm.1",
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 22),
-       }, {
-               .name           = "pcm",
-               .devname        = "samsung-pcm.2",
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 23),
-       }, {
-               .name           = "spdif",
-               .devname        = "samsung-spdif",
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 26),
-       }, {
-               .name           = "ac97",
-               .devname        = "samsung-ac97",
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 27),
-       }, {
-               .name           = "usbhost",
-               .enable         = exynos5_clk_ip_fsys_ctrl ,
-               .ctrlbit        = (1 << 18),
-       }, {
-               .name           = "usbotg",
-               .enable         = exynos5_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 7),
-       }, {
-               .name           = "nfcon",
-               .enable         = exynos5_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 22),
-       }, {
-               .name           = "iop",
-               .enable         = exynos5_clk_ip_fsys_ctrl,
-               .ctrlbit        = ((1 << 30) | (1 << 26) | (1 << 23)),
-       }, {
-               .name           = "core_iop",
-               .enable         = exynos5_clk_ip_core_ctrl,
-               .ctrlbit        = ((1 << 21) | (1 << 3)),
-       }, {
-               .name           = "mcu_iop",
-               .enable         = exynos5_clk_ip_fsys_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.0",
-               .parent         = &exynos5_clk_aclk_66.clk,
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 6),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.1",
-               .parent         = &exynos5_clk_aclk_66.clk,
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 7),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.2",
-               .parent         = &exynos5_clk_aclk_66.clk,
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 8),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.3",
-               .parent         = &exynos5_clk_aclk_66.clk,
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 9),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.4",
-               .parent         = &exynos5_clk_aclk_66.clk,
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 10),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.5",
-               .parent         = &exynos5_clk_aclk_66.clk,
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 11),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.6",
-               .parent         = &exynos5_clk_aclk_66.clk,
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 12),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-i2c.7",
-               .parent         = &exynos5_clk_aclk_66.clk,
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 13),
-       }, {
-               .name           = "i2c",
-               .devname        = "s3c2440-hdmiphy-i2c",
-               .parent         = &exynos5_clk_aclk_66.clk,
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 14),
-       }, {
-               .name           = "spi",
-               .devname        = "exynos4210-spi.0",
-               .parent         = &exynos5_clk_aclk_66.clk,
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 16),
-       }, {
-               .name           = "spi",
-               .devname        = "exynos4210-spi.1",
-               .parent         = &exynos5_clk_aclk_66.clk,
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 17),
-       }, {
-               .name           = "spi",
-               .devname        = "exynos4210-spi.2",
-               .parent         = &exynos5_clk_aclk_66.clk,
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 18),
-       }, {
-               .name           = "gscl",
-               .devname        = "exynos-gsc.0",
-               .enable         = exynos5_clk_ip_gscl_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "gscl",
-               .devname        = "exynos-gsc.1",
-               .enable         = exynos5_clk_ip_gscl_ctrl,
-               .ctrlbit        = (1 << 1),
-       }, {
-               .name           = "gscl",
-               .devname        = "exynos-gsc.2",
-               .enable         = exynos5_clk_ip_gscl_ctrl,
-               .ctrlbit        = (1 << 2),
-       }, {
-               .name           = "gscl",
-               .devname        = "exynos-gsc.3",
-               .enable         = exynos5_clk_ip_gscl_ctrl,
-               .ctrlbit        = (1 << 3),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.1",
-               .enable         = &exynos5_clk_ip_mfc_ctrl,
-               .ctrlbit        = (1 << 1),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.0",
-               .enable         = &exynos5_clk_ip_mfc_ctrl,
-               .ctrlbit        = (1 << 2),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.2",
-               .enable         = &exynos5_clk_ip_disp1_ctrl,
-               .ctrlbit        = (1 << 9)
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.3",
-               .enable         = &exynos5_clk_ip_gen_ctrl,
-               .ctrlbit        = (1 << 7),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.4",
-               .enable         = &exynos5_clk_ip_gen_ctrl,
-               .ctrlbit        = (1 << 6)
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.5",
-               .enable         = &exynos5_clk_ip_gscl_ctrl,
-               .ctrlbit        = (1 << 7),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.6",
-               .enable         = &exynos5_clk_ip_gscl_ctrl,
-               .ctrlbit        = (1 << 8),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.7",
-               .enable         = &exynos5_clk_ip_gscl_ctrl,
-               .ctrlbit        = (1 << 9),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.8",
-               .enable         = &exynos5_clk_ip_gscl_ctrl,
-               .ctrlbit        = (1 << 10),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.9",
-               .enable         = &exynos5_clk_ip_isp0_ctrl,
-               .ctrlbit        = (0x3F << 8),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.10",
-               .enable         = &exynos5_clk_ip_isp1_ctrl,
-               .ctrlbit        = (0xF << 4),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.11",
-               .enable         = &exynos5_clk_ip_disp1_ctrl,
-               .ctrlbit        = (1 << 8)
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.12",
-               .enable         = &exynos5_clk_ip_gscl_ctrl,
-               .ctrlbit        = (1 << 11),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.13",
-               .enable         = &exynos5_clk_ip_gscl_ctrl,
-               .ctrlbit        = (1 << 12),
-       }, {
-               .name           = "sysmmu",
-               .devname        = "exynos-sysmmu.14",
-               .enable         = &exynos5_clk_ip_acp_ctrl,
-               .ctrlbit        = (1 << 7)
-       }
-};
-
-static struct clk exynos5_init_clocks_on[] = {
-       {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.0",
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 0),
-       }, {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.1",
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 1),
-       }, {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.2",
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 2),
-       }, {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.3",
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 3),
-       }, {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.4",
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 4),
-       }, {
-               .name           = "uart",
-               .devname        = "s5pv210-uart.5",
-               .enable         = exynos5_clk_ip_peric_ctrl,
-               .ctrlbit        = (1 << 5),
-       }
-};
-
-static struct clk exynos5_clk_pdma0 = {
-       .name           = "dma",
-       .devname        = "dma-pl330.0",
-       .enable         = exynos5_clk_ip_fsys_ctrl,
-       .ctrlbit        = (1 << 1),
-};
-
-static struct clk exynos5_clk_pdma1 = {
-       .name           = "dma",
-       .devname        = "dma-pl330.1",
-       .enable         = exynos5_clk_ip_fsys_ctrl,
-       .ctrlbit        = (1 << 2),
-};
-
-static struct clk exynos5_clk_mdma1 = {
-       .name           = "dma",
-       .devname        = "dma-pl330.2",
-       .enable         = exynos5_clk_ip_gen_ctrl,
-       .ctrlbit        = (1 << 4),
-};
-
-static struct clk exynos5_clk_fimd1 = {
-       .name           = "fimd",
-       .devname        = "exynos5-fb.1",
-       .enable         = exynos5_clk_ip_disp1_ctrl,
-       .ctrlbit        = (1 << 0),
-};
-
-static struct clk *exynos5_clkset_group_list[] = {
-       [0] = &clk_ext_xtal_mux,
-       [1] = NULL,
-       [2] = &exynos5_clk_sclk_hdmi24m,
-       [3] = &exynos5_clk_sclk_dptxphy,
-       [4] = &exynos5_clk_sclk_usbphy,
-       [5] = &exynos5_clk_sclk_hdmiphy,
-       [6] = &exynos5_clk_mout_mpll_user.clk,
-       [7] = &exynos5_clk_mout_epll.clk,
-       [8] = &exynos5_clk_sclk_vpll.clk,
-       [9] = &exynos5_clk_mout_cpll.clk,
-};
-
-static struct clksrc_sources exynos5_clkset_group = {
-       .sources        = exynos5_clkset_group_list,
-       .nr_sources     = ARRAY_SIZE(exynos5_clkset_group_list),
-};
-
-/* Possible clock sources for aclk_266_gscl_sub Mux */
-static struct clk *clk_src_gscl_266_list[] = {
-       [0] = &clk_ext_xtal_mux,
-       [1] = &exynos5_clk_aclk_266.clk,
-};
-
-static struct clksrc_sources clk_src_gscl_266 = {
-       .sources        = clk_src_gscl_266_list,
-       .nr_sources     = ARRAY_SIZE(clk_src_gscl_266_list),
-};
-
-static struct clksrc_clk exynos5_clk_dout_mmc0 = {
-       .clk            = {
-               .name           = "dout_mmc0",
-       },
-       .sources = &exynos5_clkset_group,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 0, .size = 4 },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos5_clk_dout_mmc1 = {
-       .clk            = {
-               .name           = "dout_mmc1",
-       },
-       .sources = &exynos5_clkset_group,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 4, .size = 4 },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 16, .size = 4 },
-};
-
-static struct clksrc_clk exynos5_clk_dout_mmc2 = {
-       .clk            = {
-               .name           = "dout_mmc2",
-       },
-       .sources = &exynos5_clkset_group,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 8, .size = 4 },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos5_clk_dout_mmc3 = {
-       .clk            = {
-               .name           = "dout_mmc3",
-       },
-       .sources = &exynos5_clkset_group,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 12, .size = 4 },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 16, .size = 4 },
-};
-
-static struct clksrc_clk exynos5_clk_dout_mmc4 = {
-       .clk            = {
-               .name           = "dout_mmc4",
-       },
-       .sources = &exynos5_clkset_group,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 16, .size = 4 },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS3, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos5_clk_sclk_uart0 = {
-       .clk    = {
-               .name           = "uclk1",
-               .devname        = "exynos4210-uart.0",
-               .enable         = exynos5_clksrc_mask_peric0_ctrl,
-               .ctrlbit        = (1 << 0),
-       },
-       .sources = &exynos5_clkset_group,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 0, .size = 4 },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos5_clk_sclk_uart1 = {
-       .clk    = {
-               .name           = "uclk1",
-               .devname        = "exynos4210-uart.1",
-               .enable         = exynos5_clksrc_mask_peric0_ctrl,
-               .ctrlbit        = (1 << 4),
-       },
-       .sources = &exynos5_clkset_group,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 4, .size = 4 },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 4, .size = 4 },
-};
-
-static struct clksrc_clk exynos5_clk_sclk_uart2 = {
-       .clk    = {
-               .name           = "uclk1",
-               .devname        = "exynos4210-uart.2",
-               .enable         = exynos5_clksrc_mask_peric0_ctrl,
-               .ctrlbit        = (1 << 8),
-       },
-       .sources = &exynos5_clkset_group,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 8, .size = 4 },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 8, .size = 4 },
-};
-
-static struct clksrc_clk exynos5_clk_sclk_uart3 = {
-       .clk    = {
-               .name           = "uclk1",
-               .devname        = "exynos4210-uart.3",
-               .enable         = exynos5_clksrc_mask_peric0_ctrl,
-               .ctrlbit        = (1 << 12),
-       },
-       .sources = &exynos5_clkset_group,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 12, .size = 4 },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 12, .size = 4 },
-};
-
-static struct clksrc_clk exynos5_clk_sclk_mmc0 = {
-       .clk    = {
-               .name           = "ciu",        /* card interface unit clock */
-               .devname        = "dw_mmc.0",
-               .parent         = &exynos5_clk_dout_mmc0.clk,
-               .enable         = exynos5_clksrc_mask_fsys_ctrl,
-               .ctrlbit        = (1 << 0),
-       },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 8, .size = 8 },
-};
-
-static struct clksrc_clk exynos5_clk_sclk_mmc1 = {
-       .clk    = {
-               .name           = "ciu",
-               .devname        = "dw_mmc.1",
-               .parent         = &exynos5_clk_dout_mmc1.clk,
-               .enable         = exynos5_clksrc_mask_fsys_ctrl,
-               .ctrlbit        = (1 << 4),
-       },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 24, .size = 8 },
-};
-
-static struct clksrc_clk exynos5_clk_sclk_mmc2 = {
-       .clk    = {
-               .name           = "ciu",
-               .devname        = "dw_mmc.2",
-               .parent         = &exynos5_clk_dout_mmc2.clk,
-               .enable         = exynos5_clksrc_mask_fsys_ctrl,
-               .ctrlbit        = (1 << 8),
-       },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 8, .size = 8 },
-};
-
-static struct clksrc_clk exynos5_clk_sclk_mmc3 = {
-       .clk    = {
-               .name           = "ciu",
-               .devname        = "dw_mmc.3",
-               .parent         = &exynos5_clk_dout_mmc3.clk,
-               .enable         = exynos5_clksrc_mask_fsys_ctrl,
-               .ctrlbit        = (1 << 12),
-       },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 24, .size = 8 },
-};
-
-static struct clksrc_clk exynos5_clk_mdout_spi0 = {
-       .clk    = {
-               .name           = "mdout_spi",
-               .devname        = "exynos4210-spi.0",
-       },
-       .sources = &exynos5_clkset_group,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC1, .shift = 16, .size = 4 },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC1, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos5_clk_mdout_spi1 = {
-       .clk    = {
-               .name           = "mdout_spi",
-               .devname        = "exynos4210-spi.1",
-       },
-       .sources = &exynos5_clkset_group,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC1, .shift = 20, .size = 4 },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC1, .shift = 16, .size = 4 },
-};
-
-static struct clksrc_clk exynos5_clk_mdout_spi2 = {
-       .clk    = {
-               .name           = "mdout_spi",
-               .devname        = "exynos4210-spi.2",
-       },
-       .sources = &exynos5_clkset_group,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_PERIC1, .shift = 24, .size = 4 },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC2, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos5_clk_sclk_spi0 = {
-       .clk    = {
-               .name           = "sclk_spi",
-               .devname        = "exynos4210-spi.0",
-               .parent         = &exynos5_clk_mdout_spi0.clk,
-               .enable         = exynos5_clksrc_mask_peric1_ctrl,
-               .ctrlbit        = (1 << 16),
-       },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC1, .shift = 8, .size = 8 },
-};
-
-static struct clksrc_clk exynos5_clk_sclk_spi1 = {
-       .clk    = {
-               .name           = "sclk_spi",
-               .devname        = "exynos4210-spi.1",
-               .parent         = &exynos5_clk_mdout_spi1.clk,
-               .enable         = exynos5_clksrc_mask_peric1_ctrl,
-               .ctrlbit        = (1 << 20),
-       },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC1, .shift = 24, .size = 8 },
-};
-
-static struct clksrc_clk exynos5_clk_sclk_spi2 = {
-       .clk    = {
-               .name           = "sclk_spi",
-               .devname        = "exynos4210-spi.2",
-               .parent         = &exynos5_clk_mdout_spi2.clk,
-               .enable         = exynos5_clksrc_mask_peric1_ctrl,
-               .ctrlbit        = (1 << 24),
-       },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_PERIC2, .shift = 8, .size = 8 },
-};
-
-static struct clksrc_clk exynos5_clk_sclk_fimd1 = {
-       .clk    = {
-               .name           = "sclk_fimd",
-               .devname        = "exynos5-fb.1",
-               .enable         = exynos5_clksrc_mask_disp1_0_ctrl,
-               .ctrlbit        = (1 << 0),
-       },
-       .sources = &exynos5_clkset_group,
-       .reg_src = { .reg = EXYNOS5_CLKSRC_DISP1_0, .shift = 0, .size = 4 },
-       .reg_div = { .reg = EXYNOS5_CLKDIV_DISP1_0, .shift = 0, .size = 4 },
-};
-
-static struct clksrc_clk exynos5_clksrcs[] = {
-       {
-               .clk    = {
-                       .name           = "aclk_266_gscl",
-               },
-               .sources = &clk_src_gscl_266,
-               .reg_src = { .reg = EXYNOS5_CLKSRC_TOP3, .shift = 8, .size = 1 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_g3d",
-                       .devname        = "mali-t604.0",
-                       .enable         = exynos5_clk_block_ctrl,
-                       .ctrlbit        = (1 << 1),
-               },
-               .sources = &exynos5_clkset_aclk,
-               .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 20, .size = 1 },
-               .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_sata",
-                       .devname        = "exynos5-sata",
-                       .enable         = exynos5_clksrc_mask_fsys_ctrl,
-                       .ctrlbit        = (1 << 24),
-               },
-               .sources = &exynos5_clkset_aclk,
-               .reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 24, .size = 1 },
-               .reg_div = { .reg = EXYNOS5_CLKDIV_FSYS0, .shift = 20, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_gscl_wrap",
-                       .devname        = "s5p-mipi-csis.0",
-                       .enable         = exynos5_clksrc_mask_gscl_ctrl,
-                       .ctrlbit        = (1 << 24),
-               },
-               .sources = &exynos5_clkset_group,
-               .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 24, .size = 4 },
-               .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 24, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_gscl_wrap",
-                       .devname        = "s5p-mipi-csis.1",
-                       .enable         = exynos5_clksrc_mask_gscl_ctrl,
-                       .ctrlbit        = (1 << 28),
-               },
-               .sources = &exynos5_clkset_group,
-               .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 28, .size = 4 },
-               .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 28, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_cam0",
-                       .enable         = exynos5_clksrc_mask_gscl_ctrl,
-                       .ctrlbit        = (1 << 16),
-               },
-               .sources = &exynos5_clkset_group,
-               .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 16, .size = 4 },
-               .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 16, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_cam1",
-                       .enable         = exynos5_clksrc_mask_gscl_ctrl,
-                       .ctrlbit        = (1 << 20),
-               },
-               .sources = &exynos5_clkset_group,
-               .reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 20, .size = 4 },
-               .reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 20, .size = 4 },
-       }, {
-               .clk    = {
-                       .name           = "sclk_jpeg",
-                       .parent         = &exynos5_clk_mout_cpll.clk,
-               },
-               .reg_div = { .reg = EXYNOS5_CLKDIV_GEN, .shift = 4, .size = 3 },
-       },
-};
-
-/* Clock initialization code */
-static struct clksrc_clk *exynos5_sysclks[] = {
-       &exynos5_clk_mout_apll,
-       &exynos5_clk_sclk_apll,
-       &exynos5_clk_mout_bpll,
-       &exynos5_clk_mout_bpll_fout,
-       &exynos5_clk_mout_bpll_user,
-       &exynos5_clk_mout_cpll,
-       &exynos5_clk_mout_epll,
-       &exynos5_clk_mout_mpll,
-       &exynos5_clk_mout_mpll_fout,
-       &exynos5_clk_mout_mpll_user,
-       &exynos5_clk_vpllsrc,
-       &exynos5_clk_sclk_vpll,
-       &exynos5_clk_mout_cpu,
-       &exynos5_clk_dout_armclk,
-       &exynos5_clk_dout_arm2clk,
-       &exynos5_clk_cdrex,
-       &exynos5_clk_aclk_400,
-       &exynos5_clk_aclk_333,
-       &exynos5_clk_aclk_266,
-       &exynos5_clk_aclk_200,
-       &exynos5_clk_aclk_166,
-       &exynos5_clk_aclk_300_gscl,
-       &exynos5_clk_mout_aclk_300_gscl,
-       &exynos5_clk_mout_aclk_300_gscl_mid,
-       &exynos5_clk_mout_aclk_300_gscl_mid1,
-       &exynos5_clk_aclk_66_pre,
-       &exynos5_clk_aclk_66,
-       &exynos5_clk_dout_mmc0,
-       &exynos5_clk_dout_mmc1,
-       &exynos5_clk_dout_mmc2,
-       &exynos5_clk_dout_mmc3,
-       &exynos5_clk_dout_mmc4,
-       &exynos5_clk_aclk_acp,
-       &exynos5_clk_pclk_acp,
-       &exynos5_clk_sclk_spi0,
-       &exynos5_clk_sclk_spi1,
-       &exynos5_clk_sclk_spi2,
-       &exynos5_clk_mdout_spi0,
-       &exynos5_clk_mdout_spi1,
-       &exynos5_clk_mdout_spi2,
-       &exynos5_clk_sclk_fimd1,
-};
-
-static struct clk *exynos5_clk_cdev[] = {
-       &exynos5_clk_pdma0,
-       &exynos5_clk_pdma1,
-       &exynos5_clk_mdma1,
-       &exynos5_clk_fimd1,
-};
-
-static struct clksrc_clk *exynos5_clksrc_cdev[] = {
-       &exynos5_clk_sclk_uart0,
-       &exynos5_clk_sclk_uart1,
-       &exynos5_clk_sclk_uart2,
-       &exynos5_clk_sclk_uart3,
-       &exynos5_clk_sclk_mmc0,
-       &exynos5_clk_sclk_mmc1,
-       &exynos5_clk_sclk_mmc2,
-       &exynos5_clk_sclk_mmc3,
-};
-
-static struct clk_lookup exynos5_clk_lookup[] = {
-       CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &exynos5_clk_sclk_uart0.clk),
-       CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos5_clk_sclk_uart1.clk),
-       CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos5_clk_sclk_uart2.clk),
-       CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos5_clk_sclk_uart3.clk),
-       CLKDEV_INIT("exynos4-sdhci.0", "mmc_busclk.2", &exynos5_clk_sclk_mmc0.clk),
-       CLKDEV_INIT("exynos4-sdhci.1", "mmc_busclk.2", &exynos5_clk_sclk_mmc1.clk),
-       CLKDEV_INIT("exynos4-sdhci.2", "mmc_busclk.2", &exynos5_clk_sclk_mmc2.clk),
-       CLKDEV_INIT("exynos4-sdhci.3", "mmc_busclk.2", &exynos5_clk_sclk_mmc3.clk),
-       CLKDEV_INIT("exynos4210-spi.0", "spi_busclk0", &exynos5_clk_sclk_spi0.clk),
-       CLKDEV_INIT("exynos4210-spi.1", "spi_busclk0", &exynos5_clk_sclk_spi1.clk),
-       CLKDEV_INIT("exynos4210-spi.2", "spi_busclk0", &exynos5_clk_sclk_spi2.clk),
-       CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos5_clk_pdma0),
-       CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos5_clk_pdma1),
-       CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos5_clk_mdma1),
-       CLKDEV_INIT("exynos5-fb.1", "lcd", &exynos5_clk_fimd1),
-};
-
-static unsigned long exynos5_epll_get_rate(struct clk *clk)
-{
-       return clk->rate;
-}
-
-static struct clk *exynos5_clks[] __initdata = {
-       &exynos5_clk_sclk_hdmi27m,
-       &exynos5_clk_sclk_hdmiphy,
-       &clk_fout_bpll,
-       &clk_fout_bpll_div2,
-       &clk_fout_cpll,
-       &clk_fout_mpll_div2,
-       &exynos5_clk_armclk,
-};
-
-static u32 epll_div[][6] = {
-       { 192000000, 0, 48, 3, 1, 0 },
-       { 180000000, 0, 45, 3, 1, 0 },
-       {  73728000, 1, 73, 3, 3, 47710 },
-       {  67737600, 1, 90, 4, 3, 20762 },
-       {  49152000, 0, 49, 3, 3, 9961 },
-       {  45158400, 0, 45, 3, 3, 10381 },
-       { 180633600, 0, 45, 3, 1, 10381 },
-};
-
-static int exynos5_epll_set_rate(struct clk *clk, unsigned long rate)
-{
-       unsigned int epll_con, epll_con_k;
-       unsigned int i;
-       unsigned int tmp;
-       unsigned int epll_rate;
-       unsigned int locktime;
-       unsigned int lockcnt;
-
-       /* Return if nothing changed */
-       if (clk->rate == rate)
-               return 0;
-
-       if (clk->parent)
-               epll_rate = clk_get_rate(clk->parent);
-       else
-               epll_rate = clk_ext_xtal_mux.rate;
-
-       if (epll_rate != 24000000) {
-               pr_err("Invalid Clock : recommended clock is 24MHz.\n");
-               return -EINVAL;
-       }
-
-       epll_con = __raw_readl(EXYNOS5_EPLL_CON0);
-       epll_con &= ~(0x1 << 27 | \
-                       PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |   \
-                       PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | \
-                       PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
-
-       for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
-               if (epll_div[i][0] == rate) {
-                       epll_con_k = epll_div[i][5] << 0;
-                       epll_con |= epll_div[i][1] << 27;
-                       epll_con |= epll_div[i][2] << PLL46XX_MDIV_SHIFT;
-                       epll_con |= epll_div[i][3] << PLL46XX_PDIV_SHIFT;
-                       epll_con |= epll_div[i][4] << PLL46XX_SDIV_SHIFT;
-                       break;
-               }
-       }
-
-       if (i == ARRAY_SIZE(epll_div)) {
-               printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
-                               __func__);
-               return -EINVAL;
-       }
-
-       epll_rate /= 1000000;
-
-       /* 3000 max_cycls : specification data */
-       locktime = 3000 / epll_rate * epll_div[i][3];
-       lockcnt = locktime * 10000 / (10000 / epll_rate);
-
-       __raw_writel(lockcnt, EXYNOS5_EPLL_LOCK);
-
-       __raw_writel(epll_con, EXYNOS5_EPLL_CON0);
-       __raw_writel(epll_con_k, EXYNOS5_EPLL_CON1);
-
-       do {
-               tmp = __raw_readl(EXYNOS5_EPLL_CON0);
-       } while (!(tmp & 0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT));
-
-       clk->rate = rate;
-
-       return 0;
-}
-
-static struct clk_ops exynos5_epll_ops = {
-       .get_rate = exynos5_epll_get_rate,
-       .set_rate = exynos5_epll_set_rate,
-};
-
-static int xtal_rate;
-
-static unsigned long exynos5_fout_apll_get_rate(struct clk *clk)
-{
-       return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS5_APLL_CON0));
-}
-
-static struct clk_ops exynos5_fout_apll_ops = {
-       .get_rate = exynos5_fout_apll_get_rate,
-};
-
-#ifdef CONFIG_PM
-static int exynos5_clock_suspend(void)
-{
-       s3c_pm_do_save(exynos5_clock_save, ARRAY_SIZE(exynos5_clock_save));
-
-       return 0;
-}
-
-static void exynos5_clock_resume(void)
-{
-       s3c_pm_do_restore_core(exynos5_clock_save, ARRAY_SIZE(exynos5_clock_save));
-}
-#else
-#define exynos5_clock_suspend NULL
-#define exynos5_clock_resume NULL
-#endif
-
-static struct syscore_ops exynos5_clock_syscore_ops = {
-       .suspend        = exynos5_clock_suspend,
-       .resume         = exynos5_clock_resume,
-};
-
-void __init_or_cpufreq exynos5_setup_clocks(void)
-{
-       struct clk *xtal_clk;
-       unsigned long apll;
-       unsigned long bpll;
-       unsigned long cpll;
-       unsigned long mpll;
-       unsigned long epll;
-       unsigned long vpll;
-       unsigned long vpllsrc;
-       unsigned long xtal;
-       unsigned long armclk;
-       unsigned long mout_cdrex;
-       unsigned long aclk_400;
-       unsigned long aclk_333;
-       unsigned long aclk_266;
-       unsigned long aclk_200;
-       unsigned long aclk_166;
-       unsigned long aclk_66;
-       unsigned int ptr;
-
-       printk(KERN_DEBUG "%s: registering clocks\n", __func__);
-
-       xtal_clk = clk_get(NULL, "xtal");
-       BUG_ON(IS_ERR(xtal_clk));
-
-       xtal = clk_get_rate(xtal_clk);
-
-       xtal_rate = xtal;
-
-       clk_put(xtal_clk);
-
-       printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
-
-       apll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_APLL_CON0));
-       bpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_BPLL_CON0));
-       cpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_CPLL_CON0));
-       mpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_MPLL_CON0));
-       epll = s5p_get_pll36xx(xtal, __raw_readl(EXYNOS5_EPLL_CON0),
-                       __raw_readl(EXYNOS5_EPLL_CON1));
-
-       vpllsrc = clk_get_rate(&exynos5_clk_vpllsrc.clk);
-       vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(EXYNOS5_VPLL_CON0),
-                       __raw_readl(EXYNOS5_VPLL_CON1));
-
-       clk_fout_apll.ops = &exynos5_fout_apll_ops;
-       clk_fout_bpll.rate = bpll;
-       clk_fout_bpll_div2.rate = bpll >> 1;
-       clk_fout_cpll.rate = cpll;
-       clk_fout_mpll.rate = mpll;
-       clk_fout_mpll_div2.rate = mpll >> 1;
-       clk_fout_epll.rate = epll;
-       clk_fout_vpll.rate = vpll;
-
-       printk(KERN_INFO "EXYNOS5: PLL settings, A=%ld, B=%ld, C=%ld\n"
-                       "M=%ld, E=%ld V=%ld",
-                       apll, bpll, cpll, mpll, epll, vpll);
-
-       armclk = clk_get_rate(&exynos5_clk_armclk);
-       mout_cdrex = clk_get_rate(&exynos5_clk_cdrex.clk);
-
-       aclk_400 = clk_get_rate(&exynos5_clk_aclk_400.clk);
-       aclk_333 = clk_get_rate(&exynos5_clk_aclk_333.clk);
-       aclk_266 = clk_get_rate(&exynos5_clk_aclk_266.clk);
-       aclk_200 = clk_get_rate(&exynos5_clk_aclk_200.clk);
-       aclk_166 = clk_get_rate(&exynos5_clk_aclk_166.clk);
-       aclk_66 = clk_get_rate(&exynos5_clk_aclk_66.clk);
-
-       printk(KERN_INFO "EXYNOS5: ARMCLK=%ld, CDREX=%ld, ACLK400=%ld\n"
-                       "ACLK333=%ld, ACLK266=%ld, ACLK200=%ld\n"
-                       "ACLK166=%ld, ACLK66=%ld\n",
-                       armclk, mout_cdrex, aclk_400,
-                       aclk_333, aclk_266, aclk_200,
-                       aclk_166, aclk_66);
-
-
-       clk_fout_epll.ops = &exynos5_epll_ops;
-
-       if (clk_set_parent(&exynos5_clk_mout_epll.clk, &clk_fout_epll))
-               printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
-                               clk_fout_epll.name, exynos5_clk_mout_epll.clk.name);
-
-       clk_set_rate(&exynos5_clk_sclk_apll.clk, 100000000);
-       clk_set_rate(&exynos5_clk_aclk_266.clk, 300000000);
-
-       clk_set_rate(&exynos5_clk_aclk_acp.clk, 267000000);
-       clk_set_rate(&exynos5_clk_pclk_acp.clk, 134000000);
-
-       for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clksrcs); ptr++)
-               s3c_set_clksrc(&exynos5_clksrcs[ptr], true);
-}
-
-void __init exynos5_register_clocks(void)
-{
-       int ptr;
-
-       s3c24xx_register_clocks(exynos5_clks, ARRAY_SIZE(exynos5_clks));
-
-       for (ptr = 0; ptr < ARRAY_SIZE(exynos5_sysclks); ptr++)
-               s3c_register_clksrc(exynos5_sysclks[ptr], 1);
-
-       for (ptr = 0; ptr < ARRAY_SIZE(exynos5_sclk_tv); ptr++)
-               s3c_register_clksrc(exynos5_sclk_tv[ptr], 1);
-
-       for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clksrc_cdev); ptr++)
-               s3c_register_clksrc(exynos5_clksrc_cdev[ptr], 1);
-
-       s3c_register_clksrc(exynos5_clksrcs, ARRAY_SIZE(exynos5_clksrcs));
-       s3c_register_clocks(exynos5_init_clocks_on, ARRAY_SIZE(exynos5_init_clocks_on));
-
-       s3c24xx_register_clocks(exynos5_clk_cdev, ARRAY_SIZE(exynos5_clk_cdev));
-       for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clk_cdev); ptr++)
-               s3c_disable_clocks(exynos5_clk_cdev[ptr], 1);
-
-       s3c_register_clocks(exynos5_init_clocks_off, ARRAY_SIZE(exynos5_init_clocks_off));
-       s3c_disable_clocks(exynos5_init_clocks_off, ARRAY_SIZE(exynos5_init_clocks_off));
-       clkdev_add_table(exynos5_clk_lookup, ARRAY_SIZE(exynos5_clk_lookup));
-
-       register_syscore_ops(&exynos5_clock_syscore_ops);
-       s3c_pwmclk_init();
-}
index d63d399c7bae2801e2c1e9f03590cfa13ad77674..02e35abd136b4ae39aba1c70a7068715cfdab0c8 100644 (file)
@@ -25,6 +25,8 @@
 #include <linux/irqdomain.h>
 #include <linux/irqchip.h>
 #include <linux/of_address.h>
+#include <linux/clocksource.h>
+#include <linux/clk-provider.h>
 #include <linux/irqchip/arm-gic.h>
 
 #include <asm/proc-fns.h>
@@ -39,7 +41,6 @@
 #include <mach/regs-gpio.h>
 
 #include <plat/cpu.h>
-#include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/pm.h>
 #include <plat/sdhci.h>
@@ -65,17 +66,16 @@ static const char name_exynos5440[] = "EXYNOS5440";
 static void exynos4_map_io(void);
 static void exynos5_map_io(void);
 static void exynos5440_map_io(void);
-static void exynos4_init_clocks(int xtal);
-static void exynos5_init_clocks(int xtal);
 static void exynos4_init_uarts(struct s3c2410_uartcfg *cfg, int no);
 static int exynos_init(void);
 
+unsigned long xxti_f = 0, xusbxti_f = 0;
+
 static struct cpu_table cpu_ids[] __initdata = {
        {
                .idcode         = EXYNOS4210_CPU_ID,
                .idmask         = EXYNOS4_CPU_MASK,
                .map_io         = exynos4_map_io,
-               .init_clocks    = exynos4_init_clocks,
                .init_uarts     = exynos4_init_uarts,
                .init           = exynos_init,
                .name           = name_exynos4210,
@@ -83,7 +83,6 @@ static struct cpu_table cpu_ids[] __initdata = {
                .idcode         = EXYNOS4212_CPU_ID,
                .idmask         = EXYNOS4_CPU_MASK,
                .map_io         = exynos4_map_io,
-               .init_clocks    = exynos4_init_clocks,
                .init_uarts     = exynos4_init_uarts,
                .init           = exynos_init,
                .name           = name_exynos4212,
@@ -91,7 +90,6 @@ static struct cpu_table cpu_ids[] __initdata = {
                .idcode         = EXYNOS4412_CPU_ID,
                .idmask         = EXYNOS4_CPU_MASK,
                .map_io         = exynos4_map_io,
-               .init_clocks    = exynos4_init_clocks,
                .init_uarts     = exynos4_init_uarts,
                .init           = exynos_init,
                .name           = name_exynos4412,
@@ -99,7 +97,6 @@ static struct cpu_table cpu_ids[] __initdata = {
                .idcode         = EXYNOS5250_SOC_ID,
                .idmask         = EXYNOS5_SOC_MASK,
                .map_io         = exynos5_map_io,
-               .init_clocks    = exynos5_init_clocks,
                .init           = exynos_init,
                .name           = name_exynos5250,
        }, {
@@ -256,11 +253,6 @@ static struct map_desc exynos5_iodesc[] __initdata = {
                .pfn            = __phys_to_pfn(EXYNOS5_PA_SROMC),
                .length         = SZ_4K,
                .type           = MT_DEVICE,
-       }, {
-               .virtual        = (unsigned long)S5P_VA_SYSTIMER,
-               .pfn            = __phys_to_pfn(EXYNOS5_PA_SYSTIMER),
-               .length         = SZ_4K,
-               .type           = MT_DEVICE,
        }, {
                .virtual        = (unsigned long)S5P_VA_SYSRAM,
                .pfn            = __phys_to_pfn(EXYNOS5_PA_SYSRAM),
@@ -402,43 +394,26 @@ static void __init exynos5_map_io(void)
        iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc));
 }
 
-static void __init exynos4_init_clocks(int xtal)
-{
-       printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
-
-       s3c24xx_register_baseclocks(xtal);
-       s5p_register_clocks(xtal);
-
-       if (soc_is_exynos4210())
-               exynos4210_register_clocks();
-       else if (soc_is_exynos4212() || soc_is_exynos4412())
-               exynos4212_register_clocks();
-
-       exynos4_register_clocks();
-       exynos4_setup_clocks();
-}
-
 static void __init exynos5440_map_io(void)
 {
        iotable_init(exynos5440_iodesc0, ARRAY_SIZE(exynos5440_iodesc0));
 }
 
-static void __init exynos5_init_clocks(int xtal)
+void __init exynos_init_time(void)
 {
-       printk(KERN_DEBUG "%s: initializing clocks\n", __func__);
-
-       /* EXYNOS5440 can support only common clock framework */
-
-       if (soc_is_exynos5440())
-               return;
-
-#ifdef CONFIG_SOC_EXYNOS5250
-       s3c24xx_register_baseclocks(xtal);
-       s5p_register_clocks(xtal);
-
-       exynos5_register_clocks();
-       exynos5_setup_clocks();
+       if (of_have_populated_dt()) {
+#ifdef CONFIG_OF
+               of_clk_init(NULL);
+               clocksource_of_init();
 #endif
+       } else {
+               /* todo: remove after migrating legacy E4 platforms to dt */
+#ifdef CONFIG_ARCH_EXYNOS4
+               exynos4_clk_init(NULL);
+               exynos4_clk_register_fixed_ext(xxti_f, xusbxti_f);
+#endif
+               mct_init();
+       }
 }
 
 void __init exynos4_init_irq(void)
index 9339bb8954be9e8bc3f8787dbdfd630eaf7c7909..cb89ab886950a21bb8d505f465b1a6102006fbe4 100644 (file)
 #ifndef __ARCH_ARM_MACH_EXYNOS_COMMON_H
 #define __ARCH_ARM_MACH_EXYNOS_COMMON_H
 
-extern void exynos4_timer_init(void);
+#include <linux/of.h>
+
+extern void mct_init(void);
+void exynos_init_time(void);
+extern unsigned long xxti_f, xusbxti_f;
 
 struct map_desc;
 void exynos_init_io(struct map_desc *mach_desc, int size);
@@ -22,6 +26,10 @@ void exynos4_restart(char mode, const char *cmd);
 void exynos5_restart(char mode, const char *cmd);
 void exynos_init_late(void);
 
+/* ToDo: remove these after migrating legacy exynos4 platforms to dt */
+void exynos4_clk_init(struct device_node *np);
+void exynos4_clk_register_fixed_ext(unsigned long, unsigned long);
+
 #ifdef CONFIG_PM_GENERIC_DOMAINS
 int exynos_pm_late_initcall(void);
 #else
index 1f4dc35cd4b9b88479e4b16496a7f62a05c58a46..c0e75d8dd737b2f653e597451497895b6b9d458d 100644 (file)
@@ -30,8 +30,6 @@
 
 /* For EXYNOS4 and EXYNOS5 */
 
-#define EXYNOS_IRQ_MCT_LOCALTIMER      IRQ_PPI(12)
-
 #define EXYNOS_IRQ_EINT16_31           IRQ_SPI(32)
 
 /* For EXYNOS4 SoCs */
 #define EXYNOS5_IRQ_CEC                        IRQ_SPI(114)
 #define EXYNOS5_IRQ_SATA               IRQ_SPI(115)
 
-#define EXYNOS5_IRQ_MCT_L0             IRQ_SPI(120)
-#define EXYNOS5_IRQ_MCT_L1             IRQ_SPI(121)
 #define EXYNOS5_IRQ_MMC44              IRQ_SPI(123)
 #define EXYNOS5_IRQ_MDMA1              IRQ_SPI(124)
 #define EXYNOS5_IRQ_FIMC_LITE0         IRQ_SPI(125)
 #define EXYNOS5_IRQ_PMU_CPU1           COMBINER_IRQ(22, 4)
 
 #define EXYNOS5_IRQ_EINT0              COMBINER_IRQ(23, 0)
-#define EXYNOS5_IRQ_MCT_G0             COMBINER_IRQ(23, 3)
-#define EXYNOS5_IRQ_MCT_G1             COMBINER_IRQ(23, 4)
 
 #define EXYNOS5_IRQ_EINT1              COMBINER_IRQ(24, 0)
 #define EXYNOS5_IRQ_SYSMMU_LITE1_0     COMBINER_IRQ(24, 1)
index 1df6abbf53b8cb4364884f4ee5c7018b83968bac..7f99b7b187d66e6e247ee534b15000a392cb63ee 100644 (file)
@@ -65,7 +65,6 @@
 #define EXYNOS5_PA_CMU                 0x10010000
 
 #define EXYNOS4_PA_SYSTIMER            0x10050000
-#define EXYNOS5_PA_SYSTIMER            0x101C0000
 
 #define EXYNOS4_PA_WATCHDOG            0x10060000
 #define EXYNOS5_PA_WATCHDOG            0x101D0000
index d36ad76ad6a46cbab1f07e1c3d9e2a4cde230cd7..20fbbdddd1059986e92dea778e69d4634b176e68 100644 (file)
 #define EXYNOS4_CLKDIV_CAM1_JPEG_SHIFT         (0)
 #define EXYNOS4_CLKDIV_CAM1_JPEG_MASK          (0xf << EXYNOS4_CLKDIV_CAM1_JPEG_SHIFT)
 
-/* For EXYNOS5250 */
-
-#define EXYNOS5_APLL_LOCK                      EXYNOS_CLKREG(0x00000)
-#define EXYNOS5_APLL_CON0                      EXYNOS_CLKREG(0x00100)
-#define EXYNOS5_CLKSRC_CPU                     EXYNOS_CLKREG(0x00200)
-#define EXYNOS5_CLKMUX_STATCPU                 EXYNOS_CLKREG(0x00400)
-#define EXYNOS5_CLKDIV_CPU0                    EXYNOS_CLKREG(0x00500)
-#define EXYNOS5_CLKDIV_CPU1                    EXYNOS_CLKREG(0x00504)
-#define EXYNOS5_CLKDIV_STATCPU0                        EXYNOS_CLKREG(0x00600)
-#define EXYNOS5_CLKDIV_STATCPU1                        EXYNOS_CLKREG(0x00604)
-
-#define EXYNOS5_PWR_CTRL1                      EXYNOS_CLKREG(0x01020)
-#define EXYNOS5_PWR_CTRL2                      EXYNOS_CLKREG(0x01024)
-
-#define EXYNOS5_MPLL_CON0                      EXYNOS_CLKREG(0x04100)
-#define EXYNOS5_CLKSRC_CORE1                   EXYNOS_CLKREG(0x04204)
-
-#define EXYNOS5_CLKGATE_IP_CORE                        EXYNOS_CLKREG(0x04900)
-
-#define EXYNOS5_CLKDIV_ACP                     EXYNOS_CLKREG(0x08500)
-
-#define EXYNOS5_EPLL_CON0                      EXYNOS_CLKREG(0x10130)
-#define EXYNOS5_EPLL_CON1                      EXYNOS_CLKREG(0x10134)
-#define EXYNOS5_EPLL_CON2                      EXYNOS_CLKREG(0x10138)
-#define EXYNOS5_VPLL_CON0                      EXYNOS_CLKREG(0x10140)
-#define EXYNOS5_VPLL_CON1                      EXYNOS_CLKREG(0x10144)
-#define EXYNOS5_VPLL_CON2                      EXYNOS_CLKREG(0x10148)
-#define EXYNOS5_CPLL_CON0                      EXYNOS_CLKREG(0x10120)
-
-#define EXYNOS5_CLKSRC_TOP0                    EXYNOS_CLKREG(0x10210)
-#define EXYNOS5_CLKSRC_TOP1                    EXYNOS_CLKREG(0x10214)
-#define EXYNOS5_CLKSRC_TOP2                    EXYNOS_CLKREG(0x10218)
-#define EXYNOS5_CLKSRC_TOP3                    EXYNOS_CLKREG(0x1021C)
-#define EXYNOS5_CLKSRC_GSCL                    EXYNOS_CLKREG(0x10220)
-#define EXYNOS5_CLKSRC_DISP1_0                 EXYNOS_CLKREG(0x1022C)
-#define EXYNOS5_CLKSRC_MAUDIO                  EXYNOS_CLKREG(0x10240)
-#define EXYNOS5_CLKSRC_FSYS                    EXYNOS_CLKREG(0x10244)
-#define EXYNOS5_CLKSRC_PERIC0                  EXYNOS_CLKREG(0x10250)
-#define EXYNOS5_CLKSRC_PERIC1                  EXYNOS_CLKREG(0x10254)
-#define EXYNOS5_SCLK_SRC_ISP                   EXYNOS_CLKREG(0x10270)
-
-#define EXYNOS5_CLKSRC_MASK_TOP                        EXYNOS_CLKREG(0x10310)
-#define EXYNOS5_CLKSRC_MASK_GSCL               EXYNOS_CLKREG(0x10320)
-#define EXYNOS5_CLKSRC_MASK_DISP1_0            EXYNOS_CLKREG(0x1032C)
-#define EXYNOS5_CLKSRC_MASK_MAUDIO             EXYNOS_CLKREG(0x10334)
-#define EXYNOS5_CLKSRC_MASK_FSYS               EXYNOS_CLKREG(0x10340)
-#define EXYNOS5_CLKSRC_MASK_PERIC0             EXYNOS_CLKREG(0x10350)
-#define EXYNOS5_CLKSRC_MASK_PERIC1             EXYNOS_CLKREG(0x10354)
-
-#define EXYNOS5_CLKDIV_TOP0                    EXYNOS_CLKREG(0x10510)
-#define EXYNOS5_CLKDIV_TOP1                    EXYNOS_CLKREG(0x10514)
-#define EXYNOS5_CLKDIV_GSCL                    EXYNOS_CLKREG(0x10520)
-#define EXYNOS5_CLKDIV_DISP1_0                 EXYNOS_CLKREG(0x1052C)
-#define EXYNOS5_CLKDIV_GEN                     EXYNOS_CLKREG(0x1053C)
-#define EXYNOS5_CLKDIV_MAUDIO                  EXYNOS_CLKREG(0x10544)
-#define EXYNOS5_CLKDIV_FSYS0                   EXYNOS_CLKREG(0x10548)
-#define EXYNOS5_CLKDIV_FSYS1                   EXYNOS_CLKREG(0x1054C)
-#define EXYNOS5_CLKDIV_FSYS2                   EXYNOS_CLKREG(0x10550)
-#define EXYNOS5_CLKDIV_FSYS3                   EXYNOS_CLKREG(0x10554)
-#define EXYNOS5_CLKDIV_PERIC0                  EXYNOS_CLKREG(0x10558)
-#define EXYNOS5_CLKDIV_PERIC1                  EXYNOS_CLKREG(0x1055C)
-#define EXYNOS5_CLKDIV_PERIC2                  EXYNOS_CLKREG(0x10560)
-#define EXYNOS5_CLKDIV_PERIC3                  EXYNOS_CLKREG(0x10564)
-#define EXYNOS5_CLKDIV_PERIC4                  EXYNOS_CLKREG(0x10568)
-#define EXYNOS5_CLKDIV_PERIC5                  EXYNOS_CLKREG(0x1056C)
-#define EXYNOS5_SCLK_DIV_ISP                   EXYNOS_CLKREG(0x10580)
-
-#define EXYNOS5_CLKGATE_IP_ACP                 EXYNOS_CLKREG(0x08800)
-#define EXYNOS5_CLKGATE_IP_ISP0                        EXYNOS_CLKREG(0x0C800)
-#define EXYNOS5_CLKGATE_IP_ISP1                        EXYNOS_CLKREG(0x0C804)
-#define EXYNOS5_CLKGATE_IP_GSCL                        EXYNOS_CLKREG(0x10920)
-#define EXYNOS5_CLKGATE_IP_DISP1               EXYNOS_CLKREG(0x10928)
-#define EXYNOS5_CLKGATE_IP_MFC                 EXYNOS_CLKREG(0x1092C)
-#define EXYNOS5_CLKGATE_IP_G3D                 EXYNOS_CLKREG(0x10930)
-#define EXYNOS5_CLKGATE_IP_GEN                 EXYNOS_CLKREG(0x10934)
-#define EXYNOS5_CLKGATE_IP_FSYS                        EXYNOS_CLKREG(0x10944)
-#define EXYNOS5_CLKGATE_IP_GPS                 EXYNOS_CLKREG(0x1094C)
-#define EXYNOS5_CLKGATE_IP_PERIC               EXYNOS_CLKREG(0x10950)
-#define EXYNOS5_CLKGATE_IP_PERIS               EXYNOS_CLKREG(0x10960)
-#define EXYNOS5_CLKGATE_BLOCK                  EXYNOS_CLKREG(0x10980)
-
-#define EXYNOS5_BPLL_CON0                      EXYNOS_CLKREG(0x20110)
-#define EXYNOS5_CLKSRC_CDREX                   EXYNOS_CLKREG(0x20200)
-#define EXYNOS5_CLKDIV_CDREX                   EXYNOS_CLKREG(0x20500)
-
-#define EXYNOS5_PLL_DIV2_SEL                   EXYNOS_CLKREG(0x20A24)
-
-#define EXYNOS5_EPLL_LOCK                      EXYNOS_CLKREG(0x10030)
-
-#define EXYNOS5_EPLLCON0_LOCKED_SHIFT          (29)
-
-#define PWR_CTRL1_CORE2_DOWN_RATIO             (7 << 28)
-#define PWR_CTRL1_CORE1_DOWN_RATIO             (7 << 16)
-#define PWR_CTRL1_DIV2_DOWN_EN                 (1 << 9)
-#define PWR_CTRL1_DIV1_DOWN_EN                 (1 << 8)
-#define PWR_CTRL1_USE_CORE1_WFE                        (1 << 5)
-#define PWR_CTRL1_USE_CORE0_WFE                        (1 << 4)
-#define PWR_CTRL1_USE_CORE1_WFI                        (1 << 1)
-#define PWR_CTRL1_USE_CORE0_WFI                        (1 << 0)
-
-#define PWR_CTRL2_DIV2_UP_EN                   (1 << 25)
-#define PWR_CTRL2_DIV1_UP_EN                   (1 << 24)
-#define PWR_CTRL2_DUR_STANDBY2_VAL             (1 << 16)
-#define PWR_CTRL2_DUR_STANDBY1_VAL             (1 << 8)
-#define PWR_CTRL2_CORE2_UP_RATIO               (1 << 4)
-#define PWR_CTRL2_CORE1_UP_RATIO               (1 << 0)
-
 /* Compatibility defines and inclusion */
 
 #include <mach/regs-pmu.h>
diff --git a/arch/arm/mach-exynos/include/mach/regs-mct.h b/arch/arm/mach-exynos/include/mach/regs-mct.h
deleted file mode 100644 (file)
index 80dd02a..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* arch/arm/mach-exynos4/include/mach/regs-mct.h
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 MCT configutation
- *
- * 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 __ASM_ARCH_REGS_MCT_H
-#define __ASM_ARCH_REGS_MCT_H __FILE__
-
-#include <mach/map.h>
-
-#define EXYNOS4_MCTREG(x)              (S5P_VA_SYSTIMER + (x))
-
-#define EXYNOS4_MCT_G_CNT_L            EXYNOS4_MCTREG(0x100)
-#define EXYNOS4_MCT_G_CNT_U            EXYNOS4_MCTREG(0x104)
-#define EXYNOS4_MCT_G_CNT_WSTAT                EXYNOS4_MCTREG(0x110)
-
-#define EXYNOS4_MCT_G_COMP0_L          EXYNOS4_MCTREG(0x200)
-#define EXYNOS4_MCT_G_COMP0_U          EXYNOS4_MCTREG(0x204)
-#define EXYNOS4_MCT_G_COMP0_ADD_INCR   EXYNOS4_MCTREG(0x208)
-
-#define EXYNOS4_MCT_G_TCON             EXYNOS4_MCTREG(0x240)
-
-#define EXYNOS4_MCT_G_INT_CSTAT                EXYNOS4_MCTREG(0x244)
-#define EXYNOS4_MCT_G_INT_ENB          EXYNOS4_MCTREG(0x248)
-#define EXYNOS4_MCT_G_WSTAT            EXYNOS4_MCTREG(0x24C)
-
-#define _EXYNOS4_MCT_L_BASE            EXYNOS4_MCTREG(0x300)
-#define EXYNOS4_MCT_L_BASE(x)          (_EXYNOS4_MCT_L_BASE + (0x100 * x))
-#define EXYNOS4_MCT_L_MASK             (0xffffff00)
-
-#define MCT_L_TCNTB_OFFSET             (0x00)
-#define MCT_L_ICNTB_OFFSET             (0x08)
-#define MCT_L_TCON_OFFSET              (0x20)
-#define MCT_L_INT_CSTAT_OFFSET         (0x30)
-#define MCT_L_INT_ENB_OFFSET           (0x34)
-#define MCT_L_WSTAT_OFFSET             (0x40)
-
-#define MCT_G_TCON_START               (1 << 8)
-#define MCT_G_TCON_COMP0_AUTO_INC      (1 << 1)
-#define MCT_G_TCON_COMP0_ENABLE                (1 << 0)
-
-#define MCT_L_TCON_INTERVAL_MODE       (1 << 2)
-#define MCT_L_TCON_INT_START           (1 << 1)
-#define MCT_L_TCON_TIMER_START         (1 << 0)
-
-#endif /* __ASM_ARCH_REGS_MCT_H */
index 685f29173afa8295313ab2e6320a2d029fb90ff2..2c23b659ae3e84bcc645592318d7248d93949d64 100644 (file)
@@ -177,7 +177,6 @@ static void __init armlex4210_smsc911x_init(void)
 static void __init armlex4210_map_io(void)
 {
        exynos_init_io(NULL, 0);
-       s3c24xx_init_clocks(24000000);
        s3c24xx_init_uarts(armlex4210_uartcfgs,
                           ARRAY_SIZE(armlex4210_uartcfgs));
 }
@@ -202,6 +201,6 @@ MACHINE_START(ARMLEX4210, "ARMLEX4210")
        .map_io         = armlex4210_map_io,
        .init_machine   = armlex4210_machine_init,
        .init_late      = exynos_init_late,
-       .init_time      = exynos4_timer_init,
+       .init_time      = exynos_init_time,
        .restart        = exynos4_restart,
 MACHINE_END
index 3358088c822a3015721b206f1671363df3db67c6..ac27f3cd121f7b98da9b4ca1caa0e746c8470fb3 100644 (file)
  * published by the Free Software Foundation.
 */
 
+#include <linux/kernel.h>
 #include <linux/of_platform.h>
+#include <linux/of_fdt.h>
 #include <linux/serial_core.h>
+#include <linux/memblock.h>
+#include <linux/clocksource.h>
 
 #include <asm/mach/arch.h>
-#include <mach/map.h>
-
-#include <plat/cpu.h>
-#include <plat/regs-serial.h>
+#include <plat/mfc.h>
 
 #include "common.h"
 
-/*
- * The following lookup table is used to override device names when devices
- * are registered from device tree. This is temporarily added to enable
- * device tree support addition for the Exynos4 architecture.
- *
- * For drivers that require platform data to be provided from the machine
- * file, a platform data pointer can also be supplied along with the
- * devices names. Usually, the platform data elements that cannot be parsed
- * from the device tree by the drivers (example: function pointers) are
- * supplied. But it should be noted that this is a temporary mechanism and
- * at some point, the drivers should be capable of parsing all the platform
- * data from the device tree.
- */
-static const struct of_dev_auxdata exynos4_auxdata_lookup[] __initconst = {
-       OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART0,
-                               "exynos4210-uart.0", NULL),
-       OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART1,
-                               "exynos4210-uart.1", NULL),
-       OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART2,
-                               "exynos4210-uart.2", NULL),
-       OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS4_PA_UART3,
-                               "exynos4210-uart.3", NULL),
-       OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(0),
-                               "exynos4-sdhci.0", NULL),
-       OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(1),
-                               "exynos4-sdhci.1", NULL),
-       OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(2),
-                               "exynos4-sdhci.2", NULL),
-       OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(3),
-                               "exynos4-sdhci.3", NULL),
-       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(0),
-                               "s3c2440-i2c.0", NULL),
-       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(1),
-                               "s3c2440-i2c.1", NULL),
-       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(2),
-                               "s3c2440-i2c.2", NULL),
-       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(3),
-                               "s3c2440-i2c.3", NULL),
-       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(4),
-                               "s3c2440-i2c.4", NULL),
-       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(5),
-                               "s3c2440-i2c.5", NULL),
-       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(6),
-                               "s3c2440-i2c.6", NULL),
-       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(7),
-                               "s3c2440-i2c.7", NULL),
-       OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS4_PA_SPI0,
-                               "exynos4210-spi.0", NULL),
-       OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS4_PA_SPI1,
-                               "exynos4210-spi.1", NULL),
-       OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS4_PA_SPI2,
-                               "exynos4210-spi.2", NULL),
-       OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA0, "dma-pl330.0", NULL),
-       OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA1, "dma-pl330.1", NULL),
-       OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_MDMA1, "dma-pl330.2", NULL),
-       OF_DEV_AUXDATA("samsung,exynos4210-tmu", EXYNOS4_PA_TMU,
-                               "exynos-tmu", NULL),
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x13620000,
-                       "exynos-sysmmu.0", NULL), /* MFC_L */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x13630000,
-                       "exynos-sysmmu.1", NULL), /* MFC_R */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x13E20000,
-                       "exynos-sysmmu.2", NULL), /* TV */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x11A60000,
-                       "exynos-sysmmu.3", NULL), /* JPEG */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x12A30000,
-                       "exynos-sysmmu.4", NULL), /* ROTATOR */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x11A20000,
-                       "exynos-sysmmu.5", NULL), /* FIMC0 */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x11A30000,
-                       "exynos-sysmmu.6", NULL), /* FIMC1 */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x11A40000,
-                       "exynos-sysmmu.7", NULL), /* FIMC2 */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x11A50000,
-                       "exynos-sysmmu.8", NULL), /* FIMC3 */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x12A20000,
-                       "exynos-sysmmu.9", NULL), /* G2D(4210) */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x10A40000,
-                       "exynos-sysmmu.9", NULL), /* G2D(4x12) */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x11E20000,
-                       "exynos-sysmmu.10", NULL), /* FIMD0 */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x12220000,
-                       "exynos-sysmmu.11", NULL), /* FIMD1(4210) */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x12260000,
-                       "exynos-sysmmu.12", NULL), /* IS0(4x12) */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x122B0000,
-                       "exynos-sysmmu.13", NULL), /* IS1(4x12) */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x123B0000,
-                       "exynos-sysmmu.14", NULL), /* FIMC-LITE0(4x12) */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x123C0000,
-                       "exynos-sysmmu.15", NULL), /* FIMC-LITE1(4x12) */
-       {},
-};
-
 static void __init exynos4_dt_map_io(void)
 {
        exynos_init_io(NULL, 0);
-       s3c24xx_init_clocks(24000000);
 }
 
 static void __init exynos4_dt_machine_init(void)
 {
-       of_platform_populate(NULL, of_default_bus_match_table,
-                               exynos4_auxdata_lookup, NULL);
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
 static char const *exynos4_dt_compat[] __initdata = {
@@ -135,6 +40,18 @@ static char const *exynos4_dt_compat[] __initdata = {
        NULL
 };
 
+static void __init exynos4_reserve(void)
+{
+#ifdef CONFIG_S5P_DEV_MFC
+       struct s5p_mfc_dt_meminfo mfc_mem;
+
+       /* Reserve memory for MFC only if it's available */
+       mfc_mem.compatible = "samsung,mfc-v5";
+       if (of_scan_flat_dt(s5p_fdt_find_mfc_mem, &mfc_mem))
+               s5p_mfc_reserve_mem(mfc_mem.roff, mfc_mem.rsize, mfc_mem.loff,
+                               mfc_mem.lsize);
+#endif
+}
 DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)")
        /* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */
        .smp            = smp_ops(exynos_smp_ops),
@@ -142,7 +59,8 @@ DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)")
        .map_io         = exynos4_dt_map_io,
        .init_machine   = exynos4_dt_machine_init,
        .init_late      = exynos_init_late,
-       .init_time      = exynos4_timer_init,
+       .init_time      = exynos_init_time,
        .dt_compat      = exynos4_dt_compat,
        .restart        = exynos4_restart,
+       .reserve        = exynos4_reserve,
 MACHINE_END
index acaeb14db54b933f0c658a0ded6fdb7608abe011..753b94f3fca7e3ba4c3895582f638e6c395e60fd 100644 (file)
 
 #include <linux/of_platform.h>
 #include <linux/of_fdt.h>
-#include <linux/serial_core.h>
 #include <linux/memblock.h>
 #include <linux/io.h>
+#include <linux/clocksource.h>
 
 #include <asm/mach/arch.h>
-#include <mach/map.h>
 #include <mach/regs-pmu.h>
 
 #include <plat/cpu.h>
-#include <plat/regs-serial.h>
 #include <plat/mfc.h>
 
 #include "common.h"
 
-/*
- * The following lookup table is used to override device names when devices
- * are registered from device tree. This is temporarily added to enable
- * device tree support addition for the EXYNOS5 architecture.
- *
- * For drivers that require platform data to be provided from the machine
- * file, a platform data pointer can also be supplied along with the
- * devices names. Usually, the platform data elements that cannot be parsed
- * from the device tree by the drivers (example: function pointers) are
- * supplied. But it should be noted that this is a temporary mechanism and
- * at some point, the drivers should be capable of parsing all the platform
- * data from the device tree.
- */
-static const struct of_dev_auxdata exynos5250_auxdata_lookup[] __initconst = {
-       OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART0,
-                               "exynos4210-uart.0", NULL),
-       OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART1,
-                               "exynos4210-uart.1", NULL),
-       OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART2,
-                               "exynos4210-uart.2", NULL),
-       OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5_PA_UART3,
-                               "exynos4210-uart.3", NULL),
-       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(0),
-                               "s3c2440-i2c.0", NULL),
-       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(1),
-                               "s3c2440-i2c.1", NULL),
-       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(2),
-                               "s3c2440-i2c.2", NULL),
-       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(3),
-                               "s3c2440-i2c.3", NULL),
-       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(4),
-                               "s3c2440-i2c.4", NULL),
-       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(5),
-                               "s3c2440-i2c.5", NULL),
-       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(6),
-                               "s3c2440-i2c.6", NULL),
-       OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS5_PA_IIC(7),
-                               "s3c2440-i2c.7", NULL),
-       OF_DEV_AUXDATA("samsung,s3c2440-hdmiphy-i2c", EXYNOS5_PA_IIC(8),
-                               "s3c2440-hdmiphy-i2c", NULL),
-       OF_DEV_AUXDATA("samsung,exynos5250-dw-mshc", EXYNOS5_PA_DWMCI0,
-                               "dw_mmc.0", NULL),
-       OF_DEV_AUXDATA("samsung,exynos5250-dw-mshc", EXYNOS5_PA_DWMCI1,
-                               "dw_mmc.1", NULL),
-       OF_DEV_AUXDATA("samsung,exynos5250-dw-mshc", EXYNOS5_PA_DWMCI2,
-                               "dw_mmc.2", NULL),
-       OF_DEV_AUXDATA("samsung,exynos5250-dw-mshc", EXYNOS5_PA_DWMCI3,
-                               "dw_mmc.3", NULL),
-       OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS5_PA_SPI0,
-                               "exynos4210-spi.0", NULL),
-       OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS5_PA_SPI1,
-                               "exynos4210-spi.1", NULL),
-       OF_DEV_AUXDATA("samsung,exynos4210-spi", EXYNOS5_PA_SPI2,
-                               "exynos4210-spi.2", NULL),
-       OF_DEV_AUXDATA("samsung,exynos5-sata-ahci", 0x122F0000,
-                               "exynos5-sata", NULL),
-       OF_DEV_AUXDATA("samsung,exynos5-sata-phy", 0x12170000,
-                               "exynos5-sata-phy", NULL),
-       OF_DEV_AUXDATA("samsung,exynos5-sata-phy-i2c", 0x121D0000,
-                               "exynos5-sata-phy-i2c", NULL),
-       OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA0, "dma-pl330.0", NULL),
-       OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_PDMA1, "dma-pl330.1", NULL),
-       OF_DEV_AUXDATA("arm,pl330", EXYNOS5_PA_MDMA1, "dma-pl330.2", NULL),
-       OF_DEV_AUXDATA("samsung,exynos5-gsc", EXYNOS5_PA_GSC0,
-                               "exynos-gsc.0", NULL),
-       OF_DEV_AUXDATA("samsung,exynos5-gsc", EXYNOS5_PA_GSC1,
-                               "exynos-gsc.1", NULL),
-       OF_DEV_AUXDATA("samsung,exynos5-gsc", EXYNOS5_PA_GSC2,
-                               "exynos-gsc.2", NULL),
-       OF_DEV_AUXDATA("samsung,exynos5-gsc", EXYNOS5_PA_GSC3,
-                               "exynos-gsc.3", NULL),
-       OF_DEV_AUXDATA("samsung,exynos5-hdmi", 0x14530000,
-                               "exynos5-hdmi", NULL),
-       OF_DEV_AUXDATA("samsung,exynos5-mixer", 0x14450000,
-                               "exynos5-mixer", NULL),
-       OF_DEV_AUXDATA("samsung,mfc-v6", 0x11000000, "s5p-mfc-v6", NULL),
-       OF_DEV_AUXDATA("samsung,exynos5250-tmu", 0x10060000,
-                               "exynos-tmu", NULL),
-       OF_DEV_AUXDATA("samsung,i2s-v5", 0x03830000,
-                               "samsung-i2s.0", NULL),
-       OF_DEV_AUXDATA("samsung,i2s-v5", 0x12D60000,
-                               "samsung-i2s.1", NULL),
-       OF_DEV_AUXDATA("samsung,i2s-v5", 0x12D70000,
-                               "samsung-i2s.2", NULL),
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x11210000,
-                       "exynos-sysmmu.0", "mfc"), /* MFC_L */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x11200000,
-                       "exynos-sysmmu.1", "mfc"), /* MFC_R */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x14650000,
-                       "exynos-sysmmu.2", NULL), /* TV */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x11F20000,
-                       "exynos-sysmmu.3", "jpeg"), /* JPEG */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x11D40000,
-                       "exynos-sysmmu.4", NULL), /* ROTATOR */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x13E80000,
-                       "exynos-sysmmu.5", "gscl"), /* GSCL0 */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x13E90000,
-                       "exynos-sysmmu.6", "gscl"), /* GSCL1 */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x13EA0000,
-                       "exynos-sysmmu.7", "gscl"), /* GSCL2 */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x13EB0000,
-                       "exynos-sysmmu.8", "gscl"), /* GSCL3 */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x13260000,
-                       "exynos-sysmmu.9", NULL), /* FIMC-IS0 */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x132C0000,
-                       "exynos-sysmmu.10", NULL), /* FIMC-IS1 */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x14640000,
-                       "exynos-sysmmu.11", NULL), /* FIMD1 */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x13C40000,
-                       "exynos-sysmmu.12", NULL), /* FIMC-LITE0 */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x13C50000,
-                       "exynos-sysmmu.13", NULL), /* FIMC-LITE1 */
-       OF_DEV_AUXDATA("samsung,exynos-sysmmu", 0x10A60000,
-                       "exynos-sysmmu.14", NULL), /* G2D */
-       {},
-};
-
-static const struct of_dev_auxdata exynos5440_auxdata_lookup[] __initconst = {
-       OF_DEV_AUXDATA("samsung,exynos4210-uart", EXYNOS5440_PA_UART0,
-                               "exynos4210-uart.0", NULL),
-       {},
-};
-
 static void __init exynos5_dt_map_io(void)
 {
-       unsigned long root = of_get_flat_dt_root();
-
        exynos_init_io(NULL, 0);
-
-       if (of_flat_dt_is_compatible(root, "samsung,exynos5250"))
-               s3c24xx_init_clocks(24000000);
 }
 
 static void __init exynos5_dt_machine_init(void)
@@ -182,12 +52,7 @@ static void __init exynos5_dt_machine_init(void)
                }
        }
 
-       if (of_machine_is_compatible("samsung,exynos5250"))
-               of_platform_populate(NULL, of_default_bus_match_table,
-                                    exynos5250_auxdata_lookup, NULL);
-       else if (of_machine_is_compatible("samsung,exynos5440"))
-               of_platform_populate(NULL, of_default_bus_match_table,
-                                    exynos5440_auxdata_lookup, NULL);
+       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
 }
 
 static char const *exynos5_dt_compat[] __initdata = {
@@ -216,7 +81,7 @@ DT_MACHINE_START(EXYNOS5_DT, "SAMSUNG EXYNOS5 (Flattened Device Tree)")
        .map_io         = exynos5_dt_map_io,
        .init_machine   = exynos5_dt_machine_init,
        .init_late      = exynos_init_late,
-       .init_time      = exynos4_timer_init,
+       .init_time      = exynos_init_time,
        .dt_compat      = exynos5_dt_compat,
        .restart        = exynos5_restart,
        .reserve        = exynos5_reserve,
index 1ea79730187f9e3e1297a717a5a4a66650bf9d6a..0c10852423c3533420db18ddb805fd8be67eb169 100644 (file)
@@ -1330,8 +1330,9 @@ static struct platform_device *nuri_devices[] __initdata = {
 static void __init nuri_map_io(void)
 {
        exynos_init_io(NULL, 0);
-       s3c24xx_init_clocks(clk_xusbxti.rate);
        s3c24xx_init_uarts(nuri_uartcfgs, ARRAY_SIZE(nuri_uartcfgs));
+       xxti_f = 0;
+       xusbxti_f = 24000000;
 }
 
 static void __init nuri_reserve(void)
@@ -1380,7 +1381,7 @@ MACHINE_START(NURI, "NURI")
        .map_io         = nuri_map_io,
        .init_machine   = nuri_machine_init,
        .init_late      = exynos_init_late,
-       .init_time      = exynos4_timer_init,
+       .init_time      = exynos_init_time,
        .reserve        = &nuri_reserve,
        .restart        = exynos4_restart,
 MACHINE_END
index 579d2d171daa6e4ea21f56611dda80f536d41133..a9aa5c034b2303429de31f0ca54d250720eee433 100644 (file)
@@ -754,8 +754,9 @@ static void s5p_tv_setup(void)
 static void __init origen_map_io(void)
 {
        exynos_init_io(NULL, 0);
-       s3c24xx_init_clocks(clk_xusbxti.rate);
        s3c24xx_init_uarts(origen_uartcfgs, ARRAY_SIZE(origen_uartcfgs));
+       xxti_f = 0;
+       xusbxti_f = 24000000;
 }
 
 static void __init origen_power_init(void)
@@ -815,7 +816,7 @@ MACHINE_START(ORIGEN, "ORIGEN")
        .map_io         = origen_map_io,
        .init_machine   = origen_machine_init,
        .init_late      = exynos_init_late,
-       .init_time      = exynos4_timer_init,
+       .init_time      = exynos_init_time,
        .reserve        = &origen_reserve,
        .restart        = exynos4_restart,
 MACHINE_END
index fe6149624b849aa2dd624115711e1eb1e9fcbee6..184faa3bd93aae1e47efc3d2d809127a3f414c09 100644 (file)
@@ -322,7 +322,6 @@ static struct platform_device *smdk4x12_devices[] __initdata = {
 static void __init smdk4x12_map_io(void)
 {
        exynos_init_io(NULL, 0);
-       s3c24xx_init_clocks(clk_xusbxti.rate);
        s3c24xx_init_uarts(smdk4x12_uartcfgs, ARRAY_SIZE(smdk4x12_uartcfgs));
 }
 
@@ -376,7 +375,7 @@ MACHINE_START(SMDK4212, "SMDK4212")
        .init_irq       = exynos4_init_irq,
        .map_io         = smdk4x12_map_io,
        .init_machine   = smdk4x12_machine_init,
-       .init_time      = exynos4_timer_init,
+       .init_time      = exynos_init_time,
        .restart        = exynos4_restart,
        .reserve        = &smdk4x12_reserve,
 MACHINE_END
@@ -390,7 +389,7 @@ MACHINE_START(SMDK4412, "SMDK4412")
        .map_io         = smdk4x12_map_io,
        .init_machine   = smdk4x12_machine_init,
        .init_late      = exynos_init_late,
-       .init_time      = exynos4_timer_init,
+       .init_time      = exynos_init_time,
        .restart        = exynos4_restart,
        .reserve        = &smdk4x12_reserve,
 MACHINE_END
index d71672922b191c7270a1dfa3fcdb28718e1bbf66..75eca7d4e12849a8664253e55c97851857b20035 100644 (file)
@@ -371,8 +371,9 @@ static void s5p_tv_setup(void)
 static void __init smdkv310_map_io(void)
 {
        exynos_init_io(NULL, 0);
-       s3c24xx_init_clocks(clk_xusbxti.rate);
        s3c24xx_init_uarts(smdkv310_uartcfgs, ARRAY_SIZE(smdkv310_uartcfgs));
+       xxti_f = 12000000;
+       xusbxti_f = 24000000;
 }
 
 static void __init smdkv310_reserve(void)
@@ -423,7 +424,7 @@ MACHINE_START(SMDKV310, "SMDKV310")
        .init_irq       = exynos4_init_irq,
        .map_io         = smdkv310_map_io,
        .init_machine   = smdkv310_machine_init,
-       .init_time      = exynos4_timer_init,
+       .init_time      = exynos_init_time,
        .reserve        = &smdkv310_reserve,
        .restart        = exynos4_restart,
 MACHINE_END
@@ -436,7 +437,7 @@ MACHINE_START(SMDKC210, "SMDKC210")
        .map_io         = smdkv310_map_io,
        .init_machine   = smdkv310_machine_init,
        .init_late      = exynos_init_late,
-       .init_time      = exynos4_timer_init,
+       .init_time      = exynos_init_time,
        .reserve        = &smdkv310_reserve,
        .restart        = exynos4_restart,
 MACHINE_END
index 497fcb793dc150a39b02fa9c4b49cf33b70a18b1..72f08fd7cfa94f657b020c246036eaa6b4b722d5 100644 (file)
@@ -41,7 +41,7 @@
 #include <plat/mfc.h>
 #include <plat/sdhci.h>
 #include <plat/fimc-core.h>
-#include <plat/s5p-time.h>
+#include <plat/samsung-time.h>
 #include <plat/camport.h>
 
 #include <mach/map.h>
@@ -1092,9 +1092,10 @@ static struct platform_device *universal_devices[] __initdata = {
 static void __init universal_map_io(void)
 {
        exynos_init_io(NULL, 0);
-       s3c24xx_init_clocks(clk_xusbxti.rate);
        s3c24xx_init_uarts(universal_uartcfgs, ARRAY_SIZE(universal_uartcfgs));
-       s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
+       samsung_set_timer_source(SAMSUNG_PWM2, SAMSUNG_PWM4);
+       xxti_f = 0;
+       xusbxti_f = 24000000;
 }
 
 static void s5p_tv_setup(void)
@@ -1152,7 +1153,7 @@ MACHINE_START(UNIVERSAL_C210, "UNIVERSAL_C210")
        .map_io         = universal_map_io,
        .init_machine   = universal_machine_init,
        .init_late      = exynos_init_late,
-       .init_time      = s5p_timer_init,
+       .init_time      = samsung_timer_init,
        .reserve        = &universal_reserve,
        .restart        = exynos4_restart,
 MACHINE_END
diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
deleted file mode 100644 (file)
index c9d6650..0000000
+++ /dev/null
@@ -1,485 +0,0 @@
-/* linux/arch/arm/mach-exynos4/mct.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com
- *
- * EXYNOS4 MCT(Multi-Core Timer) support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/clockchips.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/percpu.h>
-#include <linux/of.h>
-
-#include <asm/arch_timer.h>
-#include <asm/localtimer.h>
-
-#include <plat/cpu.h>
-
-#include <mach/map.h>
-#include <mach/irqs.h>
-#include <mach/regs-mct.h>
-#include <asm/mach/time.h>
-
-#define TICK_BASE_CNT  1
-
-enum {
-       MCT_INT_SPI,
-       MCT_INT_PPI
-};
-
-static unsigned long clk_rate;
-static unsigned int mct_int_type;
-
-struct mct_clock_event_device {
-       struct clock_event_device *evt;
-       void __iomem *base;
-       char name[10];
-};
-
-static void exynos4_mct_write(unsigned int value, void *addr)
-{
-       void __iomem *stat_addr;
-       u32 mask;
-       u32 i;
-
-       __raw_writel(value, addr);
-
-       if (likely(addr >= EXYNOS4_MCT_L_BASE(0))) {
-               u32 base = (u32) addr & EXYNOS4_MCT_L_MASK;
-               switch ((u32) addr & ~EXYNOS4_MCT_L_MASK) {
-               case (u32) MCT_L_TCON_OFFSET:
-                       stat_addr = (void __iomem *) base + MCT_L_WSTAT_OFFSET;
-                       mask = 1 << 3;          /* L_TCON write status */
-                       break;
-               case (u32) MCT_L_ICNTB_OFFSET:
-                       stat_addr = (void __iomem *) base + MCT_L_WSTAT_OFFSET;
-                       mask = 1 << 1;          /* L_ICNTB write status */
-                       break;
-               case (u32) MCT_L_TCNTB_OFFSET:
-                       stat_addr = (void __iomem *) base + MCT_L_WSTAT_OFFSET;
-                       mask = 1 << 0;          /* L_TCNTB write status */
-                       break;
-               default:
-                       return;
-               }
-       } else {
-               switch ((u32) addr) {
-               case (u32) EXYNOS4_MCT_G_TCON:
-                       stat_addr = EXYNOS4_MCT_G_WSTAT;
-                       mask = 1 << 16;         /* G_TCON write status */
-                       break;
-               case (u32) EXYNOS4_MCT_G_COMP0_L:
-                       stat_addr = EXYNOS4_MCT_G_WSTAT;
-                       mask = 1 << 0;          /* G_COMP0_L write status */
-                       break;
-               case (u32) EXYNOS4_MCT_G_COMP0_U:
-                       stat_addr = EXYNOS4_MCT_G_WSTAT;
-                       mask = 1 << 1;          /* G_COMP0_U write status */
-                       break;
-               case (u32) EXYNOS4_MCT_G_COMP0_ADD_INCR:
-                       stat_addr = EXYNOS4_MCT_G_WSTAT;
-                       mask = 1 << 2;          /* G_COMP0_ADD_INCR w status */
-                       break;
-               case (u32) EXYNOS4_MCT_G_CNT_L:
-                       stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
-                       mask = 1 << 0;          /* G_CNT_L write status */
-                       break;
-               case (u32) EXYNOS4_MCT_G_CNT_U:
-                       stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
-                       mask = 1 << 1;          /* G_CNT_U write status */
-                       break;
-               default:
-                       return;
-               }
-       }
-
-       /* Wait maximum 1 ms until written values are applied */
-       for (i = 0; i < loops_per_jiffy / 1000 * HZ; i++)
-               if (__raw_readl(stat_addr) & mask) {
-                       __raw_writel(mask, stat_addr);
-                       return;
-               }
-
-       panic("MCT hangs after writing %d (addr:0x%08x)\n", value, (u32)addr);
-}
-
-/* Clocksource handling */
-static void exynos4_mct_frc_start(u32 hi, u32 lo)
-{
-       u32 reg;
-
-       exynos4_mct_write(lo, EXYNOS4_MCT_G_CNT_L);
-       exynos4_mct_write(hi, EXYNOS4_MCT_G_CNT_U);
-
-       reg = __raw_readl(EXYNOS4_MCT_G_TCON);
-       reg |= MCT_G_TCON_START;
-       exynos4_mct_write(reg, EXYNOS4_MCT_G_TCON);
-}
-
-static cycle_t exynos4_frc_read(struct clocksource *cs)
-{
-       unsigned int lo, hi;
-       u32 hi2 = __raw_readl(EXYNOS4_MCT_G_CNT_U);
-
-       do {
-               hi = hi2;
-               lo = __raw_readl(EXYNOS4_MCT_G_CNT_L);
-               hi2 = __raw_readl(EXYNOS4_MCT_G_CNT_U);
-       } while (hi != hi2);
-
-       return ((cycle_t)hi << 32) | lo;
-}
-
-static void exynos4_frc_resume(struct clocksource *cs)
-{
-       exynos4_mct_frc_start(0, 0);
-}
-
-struct clocksource mct_frc = {
-       .name           = "mct-frc",
-       .rating         = 400,
-       .read           = exynos4_frc_read,
-       .mask           = CLOCKSOURCE_MASK(64),
-       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
-       .resume         = exynos4_frc_resume,
-};
-
-static void __init exynos4_clocksource_init(void)
-{
-       exynos4_mct_frc_start(0, 0);
-
-       if (clocksource_register_hz(&mct_frc, clk_rate))
-               panic("%s: can't register clocksource\n", mct_frc.name);
-}
-
-static void exynos4_mct_comp0_stop(void)
-{
-       unsigned int tcon;
-
-       tcon = __raw_readl(EXYNOS4_MCT_G_TCON);
-       tcon &= ~(MCT_G_TCON_COMP0_ENABLE | MCT_G_TCON_COMP0_AUTO_INC);
-
-       exynos4_mct_write(tcon, EXYNOS4_MCT_G_TCON);
-       exynos4_mct_write(0, EXYNOS4_MCT_G_INT_ENB);
-}
-
-static void exynos4_mct_comp0_start(enum clock_event_mode mode,
-                                   unsigned long cycles)
-{
-       unsigned int tcon;
-       cycle_t comp_cycle;
-
-       tcon = __raw_readl(EXYNOS4_MCT_G_TCON);
-
-       if (mode == CLOCK_EVT_MODE_PERIODIC) {
-               tcon |= MCT_G_TCON_COMP0_AUTO_INC;
-               exynos4_mct_write(cycles, EXYNOS4_MCT_G_COMP0_ADD_INCR);
-       }
-
-       comp_cycle = exynos4_frc_read(&mct_frc) + cycles;
-       exynos4_mct_write((u32)comp_cycle, EXYNOS4_MCT_G_COMP0_L);
-       exynos4_mct_write((u32)(comp_cycle >> 32), EXYNOS4_MCT_G_COMP0_U);
-
-       exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_ENB);
-
-       tcon |= MCT_G_TCON_COMP0_ENABLE;
-       exynos4_mct_write(tcon , EXYNOS4_MCT_G_TCON);
-}
-
-static int exynos4_comp_set_next_event(unsigned long cycles,
-                                      struct clock_event_device *evt)
-{
-       exynos4_mct_comp0_start(evt->mode, cycles);
-
-       return 0;
-}
-
-static void exynos4_comp_set_mode(enum clock_event_mode mode,
-                                 struct clock_event_device *evt)
-{
-       unsigned long cycles_per_jiffy;
-       exynos4_mct_comp0_stop();
-
-       switch (mode) {
-       case CLOCK_EVT_MODE_PERIODIC:
-               cycles_per_jiffy =
-                       (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
-               exynos4_mct_comp0_start(mode, cycles_per_jiffy);
-               break;
-
-       case CLOCK_EVT_MODE_ONESHOT:
-       case CLOCK_EVT_MODE_UNUSED:
-       case CLOCK_EVT_MODE_SHUTDOWN:
-       case CLOCK_EVT_MODE_RESUME:
-               break;
-       }
-}
-
-static struct clock_event_device mct_comp_device = {
-       .name           = "mct-comp",
-       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-       .rating         = 250,
-       .set_next_event = exynos4_comp_set_next_event,
-       .set_mode       = exynos4_comp_set_mode,
-};
-
-static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id)
-{
-       struct clock_event_device *evt = dev_id;
-
-       exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_CSTAT);
-
-       evt->event_handler(evt);
-
-       return IRQ_HANDLED;
-}
-
-static struct irqaction mct_comp_event_irq = {
-       .name           = "mct_comp_irq",
-       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
-       .handler        = exynos4_mct_comp_isr,
-       .dev_id         = &mct_comp_device,
-};
-
-static void exynos4_clockevent_init(void)
-{
-       mct_comp_device.cpumask = cpumask_of(0);
-       clockevents_config_and_register(&mct_comp_device, clk_rate,
-                                       0xf, 0xffffffff);
-
-       if (soc_is_exynos5250())
-               setup_irq(EXYNOS5_IRQ_MCT_G0, &mct_comp_event_irq);
-       else
-               setup_irq(EXYNOS4_IRQ_MCT_G0, &mct_comp_event_irq);
-}
-
-#ifdef CONFIG_LOCAL_TIMERS
-
-static DEFINE_PER_CPU(struct mct_clock_event_device, percpu_mct_tick);
-
-/* Clock event handling */
-static void exynos4_mct_tick_stop(struct mct_clock_event_device *mevt)
-{
-       unsigned long tmp;
-       unsigned long mask = MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START;
-       void __iomem *addr = mevt->base + MCT_L_TCON_OFFSET;
-
-       tmp = __raw_readl(addr);
-       if (tmp & mask) {
-               tmp &= ~mask;
-               exynos4_mct_write(tmp, addr);
-       }
-}
-
-static void exynos4_mct_tick_start(unsigned long cycles,
-                                  struct mct_clock_event_device *mevt)
-{
-       unsigned long tmp;
-
-       exynos4_mct_tick_stop(mevt);
-
-       tmp = (1 << 31) | cycles;       /* MCT_L_UPDATE_ICNTB */
-
-       /* update interrupt count buffer */
-       exynos4_mct_write(tmp, mevt->base + MCT_L_ICNTB_OFFSET);
-
-       /* enable MCT tick interrupt */
-       exynos4_mct_write(0x1, mevt->base + MCT_L_INT_ENB_OFFSET);
-
-       tmp = __raw_readl(mevt->base + MCT_L_TCON_OFFSET);
-       tmp |= MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START |
-              MCT_L_TCON_INTERVAL_MODE;
-       exynos4_mct_write(tmp, mevt->base + MCT_L_TCON_OFFSET);
-}
-
-static int exynos4_tick_set_next_event(unsigned long cycles,
-                                      struct clock_event_device *evt)
-{
-       struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
-
-       exynos4_mct_tick_start(cycles, mevt);
-
-       return 0;
-}
-
-static inline void exynos4_tick_set_mode(enum clock_event_mode mode,
-                                        struct clock_event_device *evt)
-{
-       struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
-       unsigned long cycles_per_jiffy;
-
-       exynos4_mct_tick_stop(mevt);
-
-       switch (mode) {
-       case CLOCK_EVT_MODE_PERIODIC:
-               cycles_per_jiffy =
-                       (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
-               exynos4_mct_tick_start(cycles_per_jiffy, mevt);
-               break;
-
-       case CLOCK_EVT_MODE_ONESHOT:
-       case CLOCK_EVT_MODE_UNUSED:
-       case CLOCK_EVT_MODE_SHUTDOWN:
-       case CLOCK_EVT_MODE_RESUME:
-               break;
-       }
-}
-
-static int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
-{
-       struct clock_event_device *evt = mevt->evt;
-
-       /*
-        * This is for supporting oneshot mode.
-        * Mct would generate interrupt periodically
-        * without explicit stopping.
-        */
-       if (evt->mode != CLOCK_EVT_MODE_PERIODIC)
-               exynos4_mct_tick_stop(mevt);
-
-       /* Clear the MCT tick interrupt */
-       if (__raw_readl(mevt->base + MCT_L_INT_CSTAT_OFFSET) & 1) {
-               exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET);
-               return 1;
-       } else {
-               return 0;
-       }
-}
-
-static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id)
-{
-       struct mct_clock_event_device *mevt = dev_id;
-       struct clock_event_device *evt = mevt->evt;
-
-       exynos4_mct_tick_clear(mevt);
-
-       evt->event_handler(evt);
-
-       return IRQ_HANDLED;
-}
-
-static struct irqaction mct_tick0_event_irq = {
-       .name           = "mct_tick0_irq",
-       .flags          = IRQF_TIMER | IRQF_NOBALANCING,
-       .handler        = exynos4_mct_tick_isr,
-};
-
-static struct irqaction mct_tick1_event_irq = {
-       .name           = "mct_tick1_irq",
-       .flags          = IRQF_TIMER | IRQF_NOBALANCING,
-       .handler        = exynos4_mct_tick_isr,
-};
-
-static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt)
-{
-       struct mct_clock_event_device *mevt;
-       unsigned int cpu = smp_processor_id();
-       int mct_lx_irq;
-
-       mevt = this_cpu_ptr(&percpu_mct_tick);
-       mevt->evt = evt;
-
-       mevt->base = EXYNOS4_MCT_L_BASE(cpu);
-       sprintf(mevt->name, "mct_tick%d", cpu);
-
-       evt->name = mevt->name;
-       evt->cpumask = cpumask_of(cpu);
-       evt->set_next_event = exynos4_tick_set_next_event;
-       evt->set_mode = exynos4_tick_set_mode;
-       evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
-       evt->rating = 450;
-       clockevents_config_and_register(evt, clk_rate / (TICK_BASE_CNT + 1),
-                                       0xf, 0x7fffffff);
-
-       exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
-
-       if (mct_int_type == MCT_INT_SPI) {
-               if (cpu == 0) {
-                       mct_lx_irq = soc_is_exynos4210() ? EXYNOS4_IRQ_MCT_L0 :
-                                               EXYNOS5_IRQ_MCT_L0;
-                       mct_tick0_event_irq.dev_id = mevt;
-                       evt->irq = mct_lx_irq;
-                       setup_irq(mct_lx_irq, &mct_tick0_event_irq);
-               } else {
-                       mct_lx_irq = soc_is_exynos4210() ? EXYNOS4_IRQ_MCT_L1 :
-                                               EXYNOS5_IRQ_MCT_L1;
-                       mct_tick1_event_irq.dev_id = mevt;
-                       evt->irq = mct_lx_irq;
-                       setup_irq(mct_lx_irq, &mct_tick1_event_irq);
-                       irq_set_affinity(mct_lx_irq, cpumask_of(1));
-               }
-       } else {
-               enable_percpu_irq(EXYNOS_IRQ_MCT_LOCALTIMER, 0);
-       }
-
-       return 0;
-}
-
-static void exynos4_local_timer_stop(struct clock_event_device *evt)
-{
-       unsigned int cpu = smp_processor_id();
-       evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
-       if (mct_int_type == MCT_INT_SPI)
-               if (cpu == 0)
-                       remove_irq(evt->irq, &mct_tick0_event_irq);
-               else
-                       remove_irq(evt->irq, &mct_tick1_event_irq);
-       else
-               disable_percpu_irq(EXYNOS_IRQ_MCT_LOCALTIMER);
-}
-
-static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = {
-       .setup  = exynos4_local_timer_setup,
-       .stop   = exynos4_local_timer_stop,
-};
-#endif /* CONFIG_LOCAL_TIMERS */
-
-static void __init exynos4_timer_resources(void)
-{
-       struct clk *mct_clk;
-       mct_clk = clk_get(NULL, "xtal");
-
-       clk_rate = clk_get_rate(mct_clk);
-
-#ifdef CONFIG_LOCAL_TIMERS
-       if (mct_int_type == MCT_INT_PPI) {
-               int err;
-
-               err = request_percpu_irq(EXYNOS_IRQ_MCT_LOCALTIMER,
-                                        exynos4_mct_tick_isr, "MCT",
-                                        &percpu_mct_tick);
-               WARN(err, "MCT: can't request IRQ %d (%d)\n",
-                    EXYNOS_IRQ_MCT_LOCALTIMER, err);
-       }
-
-       local_timer_register(&exynos4_mct_tick_ops);
-#endif /* CONFIG_LOCAL_TIMERS */
-}
-
-void __init exynos4_timer_init(void)
-{
-       if (soc_is_exynos5440()) {
-               arch_timer_of_register();
-               return;
-       }
-
-       if ((soc_is_exynos4210()) || (soc_is_exynos5250()))
-               mct_int_type = MCT_INT_SPI;
-       else
-               mct_int_type = MCT_INT_PPI;
-
-       exynos4_timer_resources();
-       exynos4_clocksource_init();
-       exynos4_clockevent_init();
-}
index a4f9f50247d4e9e4f5dc008436145b9a204bc2cb..76c1170b35284a0c96646413bb29476add96c7c3 100644 (file)
@@ -32,7 +32,6 @@
 #include <asm/cacheflush.h>
 #include <asm/cputype.h>
 #include <asm/smp_plat.h>
-#include <asm/smp_twd.h>
 #include <asm/hardware/arm_timer.h>
 #include <asm/hardware/timer-sp.h>
 #include <asm/hardware/cache-l2x0.h>
@@ -119,10 +118,10 @@ static void __init highbank_timer_init(void)
        sp804_clocksource_and_sched_clock_init(timer_base + 0x20, "timer1");
        sp804_clockevents_init(timer_base, irq, "timer0");
 
-       twd_local_timer_of_register();
-
        arch_timer_of_register();
        arch_timer_sched_clock_init();
+
+       clocksource_of_init();
 }
 
 static void highbank_power_off(void)
index 1ab91b5209e6503e7742450c4dc424a15b2e651c..85b728cc27abc4db782328f9a0524cb08abc759a 100644 (file)
@@ -169,7 +169,7 @@ struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift,
 
        busy->mux.reg = reg;
        busy->mux.shift = shift;
-       busy->mux.width = width;
+       busy->mux.mask = BIT(width) - 1;
        busy->mux.lock = &imx_ccm_lock;
        busy->mux_ops = &clk_mux_ops;
 
index 9ffd103b27e4da660f229cca79359a36fbeb1d38..b59ddcb57c78558c622b1022536f13e94b981d82 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/clk.h>
 #include <linux/clkdev.h>
+#include <linux/clocksource.h>
 #include <linux/cpu.h>
 #include <linux/delay.h>
 #include <linux/export.h>
 #include <linux/regmap.h>
 #include <linux/micrel_phy.h>
 #include <linux/mfd/syscon.h>
-#include <asm/smp_twd.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
-#include <asm/mach/time.h>
 #include <asm/system_misc.h>
 
 #include "common.h"
@@ -292,7 +291,7 @@ static void __init imx6q_init_irq(void)
 static void __init imx6q_timer_init(void)
 {
        mx6q_clocks_init();
-       twd_local_timer_of_register();
+       clocksource_of_init();
        imx_print_silicon_rev("i.MX6Q", imx6q_revision());
 }
 
index 3d3c8a9730626f280e08d46e68f10394231d5ca7..80db7269760e37b2cf16018f82bee0fb271d063a 100644 (file)
@@ -1,6 +1,2 @@
-# Common support
-obj-y := icoll.o ocotp.o system.o timer.o mm.o
-
 obj-$(CONFIG_PM) += pm.o
-
 obj-$(CONFIG_MACH_MXS_DT) += mach-mxs.o
diff --git a/arch/arm/mach-mxs/icoll.c b/arch/arm/mach-mxs/icoll.c
deleted file mode 100644 (file)
index e26eeba..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/irqdomain.h>
-#include <linux/io.h>
-#include <linux/of.h>
-#include <linux/of_irq.h>
-#include <asm/exception.h>
-#include <mach/mxs.h>
-#include <mach/common.h>
-
-#define HW_ICOLL_VECTOR                                0x0000
-#define HW_ICOLL_LEVELACK                      0x0010
-#define HW_ICOLL_CTRL                          0x0020
-#define HW_ICOLL_STAT_OFFSET                   0x0070
-#define HW_ICOLL_INTERRUPTn_SET(n)             (0x0124 + (n) * 0x10)
-#define HW_ICOLL_INTERRUPTn_CLR(n)             (0x0128 + (n) * 0x10)
-#define BM_ICOLL_INTERRUPTn_ENABLE             0x00000004
-#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0  0x1
-
-#define ICOLL_NUM_IRQS         128
-
-static void __iomem *icoll_base = MXS_IO_ADDRESS(MXS_ICOLL_BASE_ADDR);
-static struct irq_domain *icoll_domain;
-
-static void icoll_ack_irq(struct irq_data *d)
-{
-       /*
-        * The Interrupt Collector is able to prioritize irqs.
-        * Currently only level 0 is used. So acking can use
-        * BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 unconditionally.
-        */
-       __raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0,
-                       icoll_base + HW_ICOLL_LEVELACK);
-}
-
-static void icoll_mask_irq(struct irq_data *d)
-{
-       __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
-                       icoll_base + HW_ICOLL_INTERRUPTn_CLR(d->hwirq));
-}
-
-static void icoll_unmask_irq(struct irq_data *d)
-{
-       __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
-                       icoll_base + HW_ICOLL_INTERRUPTn_SET(d->hwirq));
-}
-
-static struct irq_chip mxs_icoll_chip = {
-       .irq_ack = icoll_ack_irq,
-       .irq_mask = icoll_mask_irq,
-       .irq_unmask = icoll_unmask_irq,
-};
-
-asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs)
-{
-       u32 irqnr;
-
-       do {
-               irqnr = __raw_readl(icoll_base + HW_ICOLL_STAT_OFFSET);
-               if (irqnr != 0x7f) {
-                       __raw_writel(irqnr, icoll_base + HW_ICOLL_VECTOR);
-                       irqnr = irq_find_mapping(icoll_domain, irqnr);
-                       handle_IRQ(irqnr, regs);
-                       continue;
-               }
-               break;
-       } while (1);
-}
-
-static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq,
-                               irq_hw_number_t hw)
-{
-       irq_set_chip_and_handler(virq, &mxs_icoll_chip, handle_level_irq);
-       set_irq_flags(virq, IRQF_VALID);
-
-       return 0;
-}
-
-static struct irq_domain_ops icoll_irq_domain_ops = {
-       .map = icoll_irq_domain_map,
-       .xlate = irq_domain_xlate_onecell,
-};
-
-static void __init icoll_of_init(struct device_node *np,
-                         struct device_node *interrupt_parent)
-{
-       /*
-        * Interrupt Collector reset, which initializes the priority
-        * for each irq to level 0.
-        */
-       mxs_reset_block(icoll_base + HW_ICOLL_CTRL);
-
-       icoll_domain = irq_domain_add_linear(np, ICOLL_NUM_IRQS,
-                                            &icoll_irq_domain_ops, NULL);
-       WARN_ON(!icoll_domain);
-}
-
-static const struct of_device_id icoll_of_match[] __initconst = {
-       {.compatible = "fsl,icoll", .data = icoll_of_init},
-       { /* sentinel */ }
-};
-
-void __init icoll_init_irq(void)
-{
-       of_irq_init(icoll_of_match);
-}
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
deleted file mode 100644 (file)
index be5a9c9..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * 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 __MACH_MXS_COMMON_H__
-#define __MACH_MXS_COMMON_H__
-
-extern const u32 *mxs_get_ocotp(void);
-extern int mxs_reset_block(void __iomem *);
-extern void mxs_timer_init(void);
-extern void mxs_restart(char, const char *);
-extern int mxs_saif_clkmux_select(unsigned int clkmux);
-
-extern int mx23_clocks_init(void);
-extern void mx23_map_io(void);
-
-extern int mx28_clocks_init(void);
-extern void mx28_map_io(void);
-
-extern void icoll_init_irq(void);
-extern void icoll_handle_irq(struct pt_regs *);
-
-#endif /* __MACH_MXS_COMMON_H__ */
index 90c6b7836ad3f8f108f708c7820f8b92a491c332..d86951551ca1b8afe31d82981b156e9b6579aed5 100644 (file)
  *
  */
 
-#include <mach/mx23.h>
-#include <mach/mx28.h>
-
 #ifdef CONFIG_DEBUG_IMX23_UART
-#define UART_PADDR     MX23_DUART_BASE_ADDR
+#define UART_PADDR     0x80070000
 #elif defined (CONFIG_DEBUG_IMX28_UART)
-#define UART_PADDR     MX28_DUART_BASE_ADDR
+#define UART_PADDR     0x80074000
 #endif
 
-#define UART_VADDR     MXS_IO_ADDRESS(UART_PADDR)
+#define UART_VADDR     0xfe100000
 
                .macro  addruart, rp, rv, tmp
                ldr     \rp, =UART_PADDR        @ physical
diff --git a/arch/arm/mach-mxs/include/mach/digctl.h b/arch/arm/mach-mxs/include/mach/digctl.h
deleted file mode 100644 (file)
index 1796406..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * 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 __MACH_DIGCTL_H__
-#define __MACH_DIGCTL_H__
-
-/* MXS DIGCTL SAIF CLKMUX */
-#define MXS_DIGCTL_SAIF_CLKMUX_DIRECT          0x0
-#define MXS_DIGCTL_SAIF_CLKMUX_CROSSINPUT      0x1
-#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0                0x2
-#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR1                0x3
-
-#define HW_DIGCTL_CTRL                 0x0
-#define  BP_DIGCTL_CTRL_SAIF_CLKMUX    10
-#define  BM_DIGCTL_CTRL_SAIF_CLKMUX    (0x3 << 10)
-#define HW_DIGCTL_CHIPID               0x310
-#endif
diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h
deleted file mode 100644 (file)
index 4c0e8a6..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA  02110-1301, USA.
- */
-
-#ifndef __MACH_MXS_HARDWARE_H__
-#define __MACH_MXS_HARDWARE_H__
-
-#endif /* __MACH_MXS_HARDWARE_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
deleted file mode 100644 (file)
index 599094b..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef __MACH_MX23_H__
-#define __MACH_MX23_H__
-
-#include <mach/mxs.h>
-
-/*
- * OCRAM
- */
-#define MX23_OCRAM_BASE_ADDR           0x00000000
-#define MX23_OCRAM_SIZE                        SZ_32K
-
-/*
- * IO
- */
-#define MX23_IO_BASE_ADDR              0x80000000
-#define MX23_IO_SIZE                   SZ_1M
-
-#define MX23_ICOLL_BASE_ADDR           (MX23_IO_BASE_ADDR + 0x000000)
-#define MX23_APBH_DMA_BASE_ADDR                (MX23_IO_BASE_ADDR + 0x004000)
-#define MX23_BCH_BASE_ADDR             (MX23_IO_BASE_ADDR + 0x00a000)
-#define MX23_GPMI_BASE_ADDR            (MX23_IO_BASE_ADDR + 0x00c000)
-#define MX23_SSP1_BASE_ADDR            (MX23_IO_BASE_ADDR + 0x010000)
-#define MX23_PINCTRL_BASE_ADDR         (MX23_IO_BASE_ADDR + 0x018000)
-#define MX23_DIGCTL_BASE_ADDR          (MX23_IO_BASE_ADDR + 0x01c000)
-#define MX23_ETM_BASE_ADDR             (MX23_IO_BASE_ADDR + 0x020000)
-#define MX23_APBX_DMA_BASE_ADDR                (MX23_IO_BASE_ADDR + 0x024000)
-#define MX23_DCP_BASE_ADDR             (MX23_IO_BASE_ADDR + 0x028000)
-#define MX23_PXP_BASE_ADDR             (MX23_IO_BASE_ADDR + 0x02a000)
-#define MX23_OCOTP_BASE_ADDR           (MX23_IO_BASE_ADDR + 0x02c000)
-#define MX23_AXI_AHB0_BASE_ADDR                (MX23_IO_BASE_ADDR + 0x02e000)
-#define MX23_LCDIF_BASE_ADDR           (MX23_IO_BASE_ADDR + 0x030000)
-#define MX23_SSP2_BASE_ADDR            (MX23_IO_BASE_ADDR + 0x034000)
-#define MX23_TVENC_BASE_ADDR           (MX23_IO_BASE_ADDR + 0x038000)
-#define MX23_CLKCTRL_BASE_ADDR         (MX23_IO_BASE_ADDR + 0x040000)
-#define MX23_SAIF0_BASE_ADDR           (MX23_IO_BASE_ADDR + 0x042000)
-#define MX23_POWER_BASE_ADDR           (MX23_IO_BASE_ADDR + 0x044000)
-#define MX23_SAIF1_BASE_ADDR           (MX23_IO_BASE_ADDR + 0x046000)
-#define MX23_AUDIOOUT_BASE_ADDR                (MX23_IO_BASE_ADDR + 0x048000)
-#define MX23_AUDIOIN_BASE_ADDR         (MX23_IO_BASE_ADDR + 0x04c000)
-#define MX23_LRADC_BASE_ADDR           (MX23_IO_BASE_ADDR + 0x050000)
-#define MX23_SPDIF_BASE_ADDR           (MX23_IO_BASE_ADDR + 0x054000)
-#define MX23_I2C_BASE_ADDR             (MX23_IO_BASE_ADDR + 0x058000)
-#define MX23_RTC_BASE_ADDR             (MX23_IO_BASE_ADDR + 0x05c000)
-#define MX23_PWM_BASE_ADDR             (MX23_IO_BASE_ADDR + 0x064000)
-#define MX23_TIMROT_BASE_ADDR          (MX23_IO_BASE_ADDR + 0x068000)
-#define MX23_AUART1_BASE_ADDR          (MX23_IO_BASE_ADDR + 0x06c000)
-#define MX23_AUART2_BASE_ADDR          (MX23_IO_BASE_ADDR + 0x06e000)
-#define MX23_DUART_BASE_ADDR           (MX23_IO_BASE_ADDR + 0x070000)
-#define MX23_USBPHY_BASE_ADDR          (MX23_IO_BASE_ADDR + 0x07c000)
-#define MX23_USBCTRL_BASE_ADDR         (MX23_IO_BASE_ADDR + 0x080000)
-#define MX23_DRAM_BASE_ADDR            (MX23_IO_BASE_ADDR + 0x0e0000)
-
-#define MX23_IO_P2V(x)                 MXS_IO_P2V(x)
-#define MX23_IO_ADDRESS(x)             IOMEM(MX23_IO_P2V(x))
-
-/*
- * IRQ
- */
-#define MX23_INT_DUART                 0
-#define MX23_INT_COMMS_RX              1
-#define MX23_INT_COMMS_TX              1
-#define MX23_INT_SSP2_ERROR            2
-#define MX23_INT_VDD5V                 3
-#define MX23_INT_HEADPHONE_SHORT       4
-#define MX23_INT_DAC_DMA               5
-#define MX23_INT_DAC_ERROR             6
-#define MX23_INT_ADC_DMA               7
-#define MX23_INT_ADC_ERROR             8
-#define MX23_INT_SPDIF_DMA             9
-#define MX23_INT_SAIF2_DMA             9
-#define MX23_INT_SPDIF_ERROR           10
-#define MX23_INT_SAIF1_IRQ             10
-#define MX23_INT_SAIF2_IRQ             10
-#define MX23_INT_USB_CTRL              11
-#define MX23_INT_USB_WAKEUP            12
-#define MX23_INT_GPMI_DMA              13
-#define MX23_INT_SSP1_DMA              14
-#define MX23_INT_SSP1_ERROR            15
-#define MX23_INT_GPIO0                 16
-#define MX23_INT_GPIO1                 17
-#define MX23_INT_GPIO2                 18
-#define MX23_INT_SAIF1_DMA             19
-#define MX23_INT_SSP2_DMA              20
-#define MX23_INT_ECC8_IRQ              21
-#define MX23_INT_RTC_ALARM             22
-#define MX23_INT_AUART1_TX_DMA         23
-#define MX23_INT_AUART1                        24
-#define MX23_INT_AUART1_RX_DMA         25
-#define MX23_INT_I2C_DMA               26
-#define MX23_INT_I2C_ERROR             27
-#define MX23_INT_TIMER0                        28
-#define MX23_INT_TIMER1                        29
-#define MX23_INT_TIMER2                        30
-#define MX23_INT_TIMER3                        31
-#define MX23_INT_BATT_BRNOUT           32
-#define MX23_INT_VDDD_BRNOUT           33
-#define MX23_INT_VDDIO_BRNOUT          34
-#define MX23_INT_VDD18_BRNOUT          35
-#define MX23_INT_TOUCH_DETECT          36
-#define MX23_INT_LRADC_CH0             37
-#define MX23_INT_LRADC_CH1             38
-#define MX23_INT_LRADC_CH2             39
-#define MX23_INT_LRADC_CH3             40
-#define MX23_INT_LRADC_CH4             41
-#define MX23_INT_LRADC_CH5             42
-#define MX23_INT_LRADC_CH6             43
-#define MX23_INT_LRADC_CH7             44
-#define MX23_INT_LCDIF_DMA             45
-#define MX23_INT_LCDIF_ERROR           46
-#define MX23_INT_DIGCTL_DEBUG_TRAP     47
-#define MX23_INT_RTC_1MSEC             48
-#define MX23_INT_DRI_DMA               49
-#define MX23_INT_DRI_ATTENTION         50
-#define MX23_INT_GPMI_ATTENTION                51
-#define MX23_INT_IR                    52
-#define MX23_INT_DCP_VMI               53
-#define MX23_INT_DCP                   54
-#define MX23_INT_BCH                   56
-#define MX23_INT_PXP                   57
-#define MX23_INT_AUART2_TX_DMA         58
-#define MX23_INT_AUART2                        59
-#define MX23_INT_AUART2_RX_DMA         60
-#define MX23_INT_VDAC_DETECT           61
-#define MX23_INT_VDD5V_DROOP           64
-#define MX23_INT_DCDC4P2_BO            65
-
-/*
- * APBH DMA
- */
-#define MX23_DMA_SSP1                  1
-#define MX23_DMA_SSP2                  2
-#define MX23_DMA_GPMI0                 4
-#define MX23_DMA_GPMI1                 5
-#define MX23_DMA_GPMI2                 6
-#define MX23_DMA_GPMI3                 7
-
-/*
- * APBX DMA
- */
-#define MX23_DMA_ADC                   0
-#define MX23_DMA_DAC                   1
-#define MX23_DMA_SPDIF                 2
-#define MX23_DMA_I2C                   3
-#define MX23_DMA_SAIF0                 4
-#define MX23_DMA_UART0_RX              6
-#define MX23_DMA_UART0_TX              7
-#define MX23_DMA_UART1_RX              8
-#define MX23_DMA_UART1_TX              9
-#define MX23_DMA_SAIF1                 10
-
-#endif /* __MACH_MX23_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
deleted file mode 100644 (file)
index 30c7990..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef __MACH_MX28_H__
-#define __MACH_MX28_H__
-
-#include <mach/mxs.h>
-
-/*
- * OCRAM
- */
-#define MX28_OCRAM_BASE_ADDR           0x00000000
-#define MX28_OCRAM_SIZE                        SZ_128K
-
-/*
- * IO
- */
-#define MX28_IO_BASE_ADDR              0x80000000
-#define MX28_IO_SIZE                   SZ_1M
-
-#define MX28_ICOLL_BASE_ADDR           (MX28_IO_BASE_ADDR + 0x000000)
-#define MX28_HSADC_BASE_ADDR           (MX28_IO_BASE_ADDR + 0x002000)
-#define MX28_APBH_DMA_BASE_ADDR                (MX28_IO_BASE_ADDR + 0x004000)
-#define MX28_PERFMON_BASE_ADDR         (MX28_IO_BASE_ADDR + 0x006000)
-#define MX28_BCH_BASE_ADDR             (MX28_IO_BASE_ADDR + 0x00a000)
-#define MX28_GPMI_BASE_ADDR            (MX28_IO_BASE_ADDR + 0x00c000)
-#define MX28_SSP0_BASE_ADDR            (MX28_IO_BASE_ADDR + 0x010000)
-#define MX28_SSP1_BASE_ADDR            (MX28_IO_BASE_ADDR + 0x012000)
-#define MX28_SSP2_BASE_ADDR            (MX28_IO_BASE_ADDR + 0x014000)
-#define MX28_SSP3_BASE_ADDR            (MX28_IO_BASE_ADDR + 0x016000)
-#define MX28_PINCTRL_BASE_ADDR         (MX28_IO_BASE_ADDR + 0x018000)
-#define MX28_DIGCTL_BASE_ADDR          (MX28_IO_BASE_ADDR + 0x01c000)
-#define MX28_ETM_BASE_ADDR             (MX28_IO_BASE_ADDR + 0x022000)
-#define MX28_APBX_DMA_BASE_ADDR                (MX28_IO_BASE_ADDR + 0x024000)
-#define MX28_DCP_BASE_ADDR             (MX28_IO_BASE_ADDR + 0x028000)
-#define MX28_PXP_BASE_ADDR             (MX28_IO_BASE_ADDR + 0x02a000)
-#define MX28_OCOTP_BASE_ADDR           (MX28_IO_BASE_ADDR + 0x02c000)
-#define MX28_AXI_AHB0_BASE_ADDR                (MX28_IO_BASE_ADDR + 0x02e000)
-#define MX28_LCDIF_BASE_ADDR           (MX28_IO_BASE_ADDR + 0x030000)
-#define MX28_CAN0_BASE_ADDR            (MX28_IO_BASE_ADDR + 0x032000)
-#define MX28_CAN1_BASE_ADDR            (MX28_IO_BASE_ADDR + 0x034000)
-#define MX28_SIMDBG_BASE_ADDR          (MX28_IO_BASE_ADDR + 0x03c000)
-#define MX28_SIMGPMISEL_BASE_ADDR      (MX28_IO_BASE_ADDR + 0x03c200)
-#define MX28_SIMSSPSEL_BASE_ADDR       (MX28_IO_BASE_ADDR + 0x03c300)
-#define MX28_SIMMEMSEL_BASE_ADDR       (MX28_IO_BASE_ADDR + 0x03c400)
-#define MX28_GPIOMON_BASE_ADDR         (MX28_IO_BASE_ADDR + 0x03c500)
-#define MX28_SIMENET_BASE_ADDR         (MX28_IO_BASE_ADDR + 0x03c700)
-#define MX28_ARMJTAG_BASE_ADDR         (MX28_IO_BASE_ADDR + 0x03c800)
-#define MX28_CLKCTRL_BASE_ADDR         (MX28_IO_BASE_ADDR + 0x040000)
-#define MX28_SAIF0_BASE_ADDR           (MX28_IO_BASE_ADDR + 0x042000)
-#define MX28_POWER_BASE_ADDR           (MX28_IO_BASE_ADDR + 0x044000)
-#define MX28_SAIF1_BASE_ADDR           (MX28_IO_BASE_ADDR + 0x046000)
-#define MX28_LRADC_BASE_ADDR           (MX28_IO_BASE_ADDR + 0x050000)
-#define MX28_SPDIF_BASE_ADDR           (MX28_IO_BASE_ADDR + 0x054000)
-#define MX28_RTC_BASE_ADDR             (MX28_IO_BASE_ADDR + 0x056000)
-#define MX28_I2C0_BASE_ADDR            (MX28_IO_BASE_ADDR + 0x058000)
-#define MX28_I2C1_BASE_ADDR            (MX28_IO_BASE_ADDR + 0x05a000)
-#define MX28_PWM_BASE_ADDR             (MX28_IO_BASE_ADDR + 0x064000)
-#define MX28_TIMROT_BASE_ADDR          (MX28_IO_BASE_ADDR + 0x068000)
-#define MX28_AUART0_BASE_ADDR          (MX28_IO_BASE_ADDR + 0x06a000)
-#define MX28_AUART1_BASE_ADDR          (MX28_IO_BASE_ADDR + 0x06c000)
-#define MX28_AUART2_BASE_ADDR          (MX28_IO_BASE_ADDR + 0x06e000)
-#define MX28_AUART3_BASE_ADDR          (MX28_IO_BASE_ADDR + 0x070000)
-#define MX28_AUART4_BASE_ADDR          (MX28_IO_BASE_ADDR + 0x072000)
-#define MX28_DUART_BASE_ADDR           (MX28_IO_BASE_ADDR + 0x074000)
-#define MX28_USBPHY0_BASE_ADDR         (MX28_IO_BASE_ADDR + 0x07C000)
-#define MX28_USBPHY1_BASE_ADDR         (MX28_IO_BASE_ADDR + 0x07e000)
-#define MX28_USBCTRL0_BASE_ADDR                (MX28_IO_BASE_ADDR + 0x080000)
-#define MX28_USBCTRL1_BASE_ADDR                (MX28_IO_BASE_ADDR + 0x090000)
-#define MX28_DFLPT_BASE_ADDR           (MX28_IO_BASE_ADDR + 0x0c0000)
-#define MX28_DRAM_BASE_ADDR            (MX28_IO_BASE_ADDR + 0x0e0000)
-#define MX28_ENET_MAC0_BASE_ADDR       (MX28_IO_BASE_ADDR + 0x0f0000)
-#define MX28_ENET_MAC1_BASE_ADDR       (MX28_IO_BASE_ADDR + 0x0f4000)
-
-#define MX28_IO_P2V(x)                 MXS_IO_P2V(x)
-#define MX28_IO_ADDRESS(x)             IOMEM(MX28_IO_P2V(x))
-
-/*
- * IRQ
- */
-#define MX28_INT_BATT_BRNOUT           0
-#define MX28_INT_VDDD_BRNOUT           1
-#define MX28_INT_VDDIO_BRNOUT          2
-#define MX28_INT_VDDA_BRNOUT           3
-#define MX28_INT_VDD5V_DROOP           4
-#define MX28_INT_DCDC4P2_BRNOUT                5
-#define MX28_INT_VDD5V                 6
-#define MX28_INT_CAN0                  8
-#define MX28_INT_CAN1                  9
-#define MX28_INT_LRADC_TOUCH           10
-#define MX28_INT_HSADC                 13
-#define MX28_INT_LRADC_THRESH0         14
-#define MX28_INT_LRADC_THRESH1         15
-#define MX28_INT_LRADC_CH0             16
-#define MX28_INT_LRADC_CH1             17
-#define MX28_INT_LRADC_CH2             18
-#define MX28_INT_LRADC_CH3             19
-#define MX28_INT_LRADC_CH4             20
-#define MX28_INT_LRADC_CH5             21
-#define MX28_INT_LRADC_CH6             22
-#define MX28_INT_LRADC_CH7             23
-#define MX28_INT_LRADC_BUTTON0         24
-#define MX28_INT_LRADC_BUTTON1         25
-#define MX28_INT_PERFMON               27
-#define MX28_INT_RTC_1MSEC             28
-#define MX28_INT_RTC_ALARM             29
-#define MX28_INT_COMMS                 31
-#define MX28_INT_EMI_ERR               32
-#define MX28_INT_LCDIF                 38
-#define MX28_INT_PXP                   39
-#define MX28_INT_BCH                   41
-#define MX28_INT_GPMI                  42
-#define MX28_INT_SPDIF_ERROR           45
-#define MX28_INT_DUART                 47
-#define MX28_INT_TIMER0                        48
-#define MX28_INT_TIMER1                        49
-#define MX28_INT_TIMER2                        50
-#define MX28_INT_TIMER3                        51
-#define MX28_INT_DCP_VMI               52
-#define MX28_INT_DCP                   53
-#define MX28_INT_DCP_SECURE            54
-#define MX28_INT_SAIF1                 58
-#define MX28_INT_SAIF0                 59
-#define MX28_INT_SPDIF_DMA             66
-#define MX28_INT_I2C0_DMA              68
-#define MX28_INT_I2C1_DMA              69
-#define MX28_INT_AUART0_RX_DMA         70
-#define MX28_INT_AUART0_TX_DMA         71
-#define MX28_INT_AUART1_RX_DMA         72
-#define MX28_INT_AUART1_TX_DMA         73
-#define MX28_INT_AUART2_RX_DMA         74
-#define MX28_INT_AUART2_TX_DMA         75
-#define MX28_INT_AUART3_RX_DMA         76
-#define MX28_INT_AUART3_TX_DMA         77
-#define MX28_INT_AUART4_RX_DMA         78
-#define MX28_INT_AUART4_TX_DMA         79
-#define MX28_INT_SAIF0_DMA             80
-#define MX28_INT_SAIF1_DMA             81
-#define MX28_INT_SSP0_DMA              82
-#define MX28_INT_SSP1_DMA              83
-#define MX28_INT_SSP2_DMA              84
-#define MX28_INT_SSP3_DMA              85
-#define MX28_INT_LCDIF_DMA             86
-#define MX28_INT_HSADC_DMA             87
-#define MX28_INT_GPMI_DMA              88
-#define MX28_INT_DIGCTL_DEBUG_TRAP     89
-#define MX28_INT_USB1                  92
-#define MX28_INT_USB0                  93
-#define MX28_INT_USB1_WAKEUP           94
-#define MX28_INT_USB0_WAKEUP           95
-#define MX28_INT_SSP0_ERROR            96
-#define MX28_INT_SSP1_ERROR            97
-#define MX28_INT_SSP2_ERROR            98
-#define MX28_INT_SSP3_ERROR            99
-#define MX28_INT_ENET_SWI              100
-#define MX28_INT_ENET_MAC0             101
-#define MX28_INT_ENET_MAC1             102
-#define MX28_INT_ENET_MAC0_1588                103
-#define MX28_INT_ENET_MAC1_1588                104
-#define MX28_INT_I2C1_ERROR            110
-#define MX28_INT_I2C0_ERROR            111
-#define MX28_INT_AUART0                        112
-#define MX28_INT_AUART1                        113
-#define MX28_INT_AUART2                        114
-#define MX28_INT_AUART3                        115
-#define MX28_INT_AUART4                        116
-#define MX28_INT_GPIO4                 123
-#define MX28_INT_GPIO3                 124
-#define MX28_INT_GPIO2                 125
-#define MX28_INT_GPIO1                 126
-#define MX28_INT_GPIO0                 127
-
-/*
- * APBH DMA
- */
-#define MX28_DMA_SSP0                  0
-#define MX28_DMA_SSP1                  1
-#define MX28_DMA_SSP2                  2
-#define MX28_DMA_SSP3                  3
-#define MX28_DMA_GPMI0                 4
-#define MX28_DMA_GPMI1                 5
-#define MX28_DMA_GPMI2                 6
-#define MX28_DMA_GPMI3                 7
-#define MX28_DMA_GPMI4                 8
-#define MX28_DMA_GPMI5                 9
-#define MX28_DMA_GPMI6                 10
-#define MX28_DMA_GPMI7                 11
-#define MX28_DMA_HSADC                 12
-#define MX28_DMA_LCDIF                 13
-
-/*
- * APBX DMA
- */
-#define MX28_DMA_AUART4_RX             0
-#define MX28_DMA_AUART4_TX             1
-#define MX28_DMA_SPDIF_TX              2
-#define MX28_DMA_SAIF0                 4
-#define MX28_DMA_SAIF1                 5
-#define MX28_DMA_I2C0                  6
-#define MX28_DMA_I2C1                  7
-#define MX28_DMA_AUART0_RX             8
-#define MX28_DMA_AUART0_TX             9
-#define MX28_DMA_AUART1_RX             10
-#define MX28_DMA_AUART1_TX             11
-#define MX28_DMA_AUART2_RX             12
-#define MX28_DMA_AUART2_TX             13
-#define MX28_DMA_AUART3_RX             14
-#define MX28_DMA_AUART3_TX             15
-
-#endif /* __MACH_MX28_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
deleted file mode 100644 (file)
index 7d4fb6d..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef __MACH_MXS_H__
-#define __MACH_MXS_H__
-
-#ifndef __ASSEMBLER__
-#include <linux/io.h>
-#endif
-#include <asm/mach-types.h>
-#include <mach/digctl.h>
-#include <mach/hardware.h>
-
-/*
- * IO addresses common to MXS-based
- */
-#define MXS_IO_BASE_ADDR               0x80000000
-#define MXS_IO_SIZE                    SZ_1M
-
-#define MXS_ICOLL_BASE_ADDR            (MXS_IO_BASE_ADDR + 0x000000)
-#define MXS_APBH_DMA_BASE_ADDR         (MXS_IO_BASE_ADDR + 0x004000)
-#define MXS_BCH_BASE_ADDR              (MXS_IO_BASE_ADDR + 0x00a000)
-#define MXS_GPMI_BASE_ADDR             (MXS_IO_BASE_ADDR + 0x00c000)
-#define MXS_PINCTRL_BASE_ADDR          (MXS_IO_BASE_ADDR + 0x018000)
-#define MXS_DIGCTL_BASE_ADDR           (MXS_IO_BASE_ADDR + 0x01c000)
-#define MXS_APBX_DMA_BASE_ADDR         (MXS_IO_BASE_ADDR + 0x024000)
-#define MXS_DCP_BASE_ADDR              (MXS_IO_BASE_ADDR + 0x028000)
-#define MXS_PXP_BASE_ADDR              (MXS_IO_BASE_ADDR + 0x02a000)
-#define MXS_OCOTP_BASE_ADDR            (MXS_IO_BASE_ADDR + 0x02c000)
-#define MXS_AXI_AHB0_BASE_ADDR         (MXS_IO_BASE_ADDR + 0x02e000)
-#define MXS_LCDIF_BASE_ADDR            (MXS_IO_BASE_ADDR + 0x030000)
-#define MXS_CLKCTRL_BASE_ADDR          (MXS_IO_BASE_ADDR + 0x040000)
-#define MXS_SAIF0_BASE_ADDR            (MXS_IO_BASE_ADDR + 0x042000)
-#define MXS_POWER_BASE_ADDR            (MXS_IO_BASE_ADDR + 0x044000)
-#define MXS_SAIF1_BASE_ADDR            (MXS_IO_BASE_ADDR + 0x046000)
-#define MXS_LRADC_BASE_ADDR            (MXS_IO_BASE_ADDR + 0x050000)
-#define MXS_SPDIF_BASE_ADDR            (MXS_IO_BASE_ADDR + 0x054000)
-#define MXS_I2C0_BASE_ADDR             (MXS_IO_BASE_ADDR + 0x058000)
-#define MXS_PWM_BASE_ADDR              (MXS_IO_BASE_ADDR + 0x064000)
-#define MXS_TIMROT_BASE_ADDR           (MXS_IO_BASE_ADDR + 0x068000)
-#define MXS_AUART1_BASE_ADDR           (MXS_IO_BASE_ADDR + 0x06c000)
-#define MXS_AUART2_BASE_ADDR           (MXS_IO_BASE_ADDR + 0x06e000)
-#define MXS_DRAM_BASE_ADDR             (MXS_IO_BASE_ADDR + 0x0e0000)
-
-/*
- * It maps the whole address space to [0xf4000000, 0xf50fffff].
- *
- *     OCRAM   0x00000000+0x020000     ->      0xf4000000+0x020000
- *     IO      0x80000000+0x100000     ->      0xf5000000+0x100000
- */
-#define MXS_IO_P2V(x)  (0xf4000000 +                                   \
-                       (((x) & 0x80000000) >> 7) +                     \
-                       (((x) & 0x000fffff)))
-
-#define MXS_IO_ADDRESS(x)      IOMEM(MXS_IO_P2V(x))
-
-#define mxs_map_entry(soc, name, _type)        {                               \
-       .virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR),      \
-       .pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR),           \
-       .length = soc ## _ ## name ## _SIZE,                            \
-       .type = _type,                                                  \
-}
-
-#define MXS_GPIO_NR(bank, nr)  ((bank) * 32 + (nr))
-
-#define MXS_SET_ADDR           0x4
-#define MXS_CLR_ADDR           0x8
-#define MXS_TOG_ADDR           0xc
-
-#ifndef __ASSEMBLER__
-static inline void __mxs_setl(u32 mask, void __iomem *reg)
-{
-       __raw_writel(mask, reg + MXS_SET_ADDR);
-}
-
-static inline void __mxs_clrl(u32 mask, void __iomem *reg)
-{
-       __raw_writel(mask, reg + MXS_CLR_ADDR);
-}
-
-static inline void __mxs_togl(u32 mask, void __iomem *reg)
-{
-       __raw_writel(mask, reg + MXS_TOG_ADDR);
-}
-
-/*
- * MXS CPU types
- */
-#define MXS_CHIPID (MXS_IO_ADDRESS(MXS_DIGCTL_BASE_ADDR) + HW_DIGCTL_CHIPID)
-
-static inline int cpu_is_mx23(void)
-{
-       return ((__raw_readl(MXS_CHIPID) >> 16) == 0x3780);
-}
-
-static inline int cpu_is_mx28(void)
-{
-       return ((__raw_readl(MXS_CHIPID) >> 16) == 0x2800);
-}
-#endif
-
-#endif /* __MACH_MXS_H__ */
index 3218f1f2c0e05dfe3b067324d1fecefadb86ae29..f39ab808694d6dc8ffb3fe550c01b9f8d3e81693 100644 (file)
  */
 
 #include <linux/clk.h>
+#include <linux/clk/mxs.h>
 #include <linux/clkdev.h>
+#include <linux/clocksource.h>
 #include <linux/can/platform/flexcan.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
 #include <linux/init.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/mxs.h>
 #include <linux/micrel_phy.h>
-#include <linux/mxsfb.h>
+#include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/phy.h>
 #include <linux/pinctrl/consumer.h>
 #include <asm/mach/arch.h>
+#include <asm/mach/map.h>
 #include <asm/mach/time.h>
-#include <mach/common.h>
-#include <mach/digctl.h>
-#include <mach/mxs.h>
-
-static struct fb_videomode mx23evk_video_modes[] = {
-       {
-               .name           = "Samsung-LMS430HF02",
-               .refresh        = 60,
-               .xres           = 480,
-               .yres           = 272,
-               .pixclock       = 108096, /* picosecond (9.2 MHz) */
-               .left_margin    = 15,
-               .right_margin   = 8,
-               .upper_margin   = 12,
-               .lower_margin   = 4,
-               .hsync_len      = 1,
-               .vsync_len      = 1,
-               .sync           = FB_SYNC_DATA_ENABLE_HIGH_ACT |
-                                 FB_SYNC_DOTCLK_FAILING_ACT,
-       },
-};
+#include <asm/system_misc.h>
 
-static struct fb_videomode mx28evk_video_modes[] = {
-       {
-               .name           = "Seiko-43WVF1G",
-               .refresh        = 60,
-               .xres           = 800,
-               .yres           = 480,
-               .pixclock       = 29851, /* picosecond (33.5 MHz) */
-               .left_margin    = 89,
-               .right_margin   = 164,
-               .upper_margin   = 23,
-               .lower_margin   = 10,
-               .hsync_len      = 10,
-               .vsync_len      = 10,
-               .sync           = FB_SYNC_DATA_ENABLE_HIGH_ACT |
-                                 FB_SYNC_DOTCLK_FAILING_ACT,
-       },
-};
+/* MXS DIGCTL SAIF CLKMUX */
+#define MXS_DIGCTL_SAIF_CLKMUX_DIRECT          0x0
+#define MXS_DIGCTL_SAIF_CLKMUX_CROSSINPUT      0x1
+#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0                0x2
+#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR1                0x3
 
-static struct fb_videomode m28evk_video_modes[] = {
-       {
-               .name           = "Ampire AM-800480R2TMQW-T01H",
-               .refresh        = 60,
-               .xres           = 800,
-               .yres           = 480,
-               .pixclock       = 30066, /* picosecond (33.26 MHz) */
-               .left_margin    = 0,
-               .right_margin   = 256,
-               .upper_margin   = 0,
-               .lower_margin   = 45,
-               .hsync_len      = 1,
-               .vsync_len      = 1,
-               .sync           = FB_SYNC_DATA_ENABLE_HIGH_ACT,
-       },
-};
+#define MXS_GPIO_NR(bank, nr)  ((bank) * 32 + (nr))
 
-static struct fb_videomode apx4devkit_video_modes[] = {
-       {
-               .name           = "HannStar PJ70112A",
-               .refresh        = 60,
-               .xres           = 800,
-               .yres           = 480,
-               .pixclock       = 33333, /* picosecond (30.00 MHz) */
-               .left_margin    = 88,
-               .right_margin   = 40,
-               .upper_margin   = 32,
-               .lower_margin   = 13,
-               .hsync_len      = 48,
-               .vsync_len      = 3,
-               .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT |
-                                 FB_SYNC_DATA_ENABLE_HIGH_ACT |
-                                 FB_SYNC_DOTCLK_FAILING_ACT,
-       },
-};
+#define MXS_SET_ADDR           0x4
+#define MXS_CLR_ADDR           0x8
+#define MXS_TOG_ADDR           0xc
 
-static struct fb_videomode apf28dev_video_modes[] = {
-       {
-               .name = "LW700",
-               .refresh = 60,
-               .xres = 800,
-               .yres = 480,
-               .pixclock = 30303, /* picosecond */
-               .left_margin = 96,
-               .right_margin = 96, /* at least 3 & 1 */
-               .upper_margin = 0x14,
-               .lower_margin = 0x15,
-               .hsync_len = 64,
-               .vsync_len = 4,
-               .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT |
-                               FB_SYNC_DATA_ENABLE_HIGH_ACT |
-                               FB_SYNC_DOTCLK_FAILING_ACT,
-       },
-};
+static inline void __mxs_setl(u32 mask, void __iomem *reg)
+{
+       __raw_writel(mask, reg + MXS_SET_ADDR);
+}
 
-static struct fb_videomode cfa10049_video_modes[] = {
-       {
-               .name           = "Himax HX8357-B",
-               .refresh        = 60,
-               .xres           = 320,
-               .yres           = 480,
-               .pixclock       = 108506, /* picosecond (9.216 MHz) */
-               .left_margin    = 2,
-               .right_margin   = 2,
-               .upper_margin   = 2,
-               .lower_margin   = 2,
-               .hsync_len      = 15,
-               .vsync_len      = 15,
-               .sync           = FB_SYNC_DATA_ENABLE_HIGH_ACT
-       },
-};
+static inline void __mxs_clrl(u32 mask, void __iomem *reg)
+{
+       __raw_writel(mask, reg + MXS_CLR_ADDR);
+}
 
-static struct mxsfb_platform_data mxsfb_pdata __initdata;
+static inline void __mxs_togl(u32 mask, void __iomem *reg)
+{
+       __raw_writel(mask, reg + MXS_TOG_ADDR);
+}
 
 /*
  * MX28EVK_FLEXCAN_SWITCH is shared between both flexcan controllers
@@ -168,21 +88,85 @@ static void mx28evk_flexcan1_switch(int enable)
 static struct flexcan_platform_data flexcan_pdata[2];
 
 static struct of_dev_auxdata mxs_auxdata_lookup[] __initdata = {
-       OF_DEV_AUXDATA("fsl,imx23-lcdif", 0x80030000, NULL, &mxsfb_pdata),
-       OF_DEV_AUXDATA("fsl,imx28-lcdif", 0x80030000, NULL, &mxsfb_pdata),
        OF_DEV_AUXDATA("fsl,imx28-flexcan", 0x80032000, NULL, &flexcan_pdata[0]),
        OF_DEV_AUXDATA("fsl,imx28-flexcan", 0x80034000, NULL, &flexcan_pdata[1]),
        { /* sentinel */ }
 };
 
-static void __init imx23_timer_init(void)
-{
-       mx23_clocks_init();
-}
+#define OCOTP_WORD_OFFSET              0x20
+#define OCOTP_WORD_COUNT               0x20
+
+#define BM_OCOTP_CTRL_BUSY             (1 << 8)
+#define BM_OCOTP_CTRL_ERROR            (1 << 9)
+#define BM_OCOTP_CTRL_RD_BANK_OPEN     (1 << 12)
+
+static DEFINE_MUTEX(ocotp_mutex);
+static u32 ocotp_words[OCOTP_WORD_COUNT];
 
-static void __init imx28_timer_init(void)
+static const u32 *mxs_get_ocotp(void)
 {
-       mx28_clocks_init();
+       struct device_node *np;
+       void __iomem *ocotp_base;
+       int timeout = 0x400;
+       size_t i;
+       static int once;
+
+       if (once)
+               return ocotp_words;
+
+       np = of_find_compatible_node(NULL, NULL, "fsl,ocotp");
+       ocotp_base = of_iomap(np, 0);
+       WARN_ON(!ocotp_base);
+
+       mutex_lock(&ocotp_mutex);
+
+       /*
+        * clk_enable(hbus_clk) for ocotp can be skipped
+        * as it must be on when system is running.
+        */
+
+       /* try to clear ERROR bit */
+       __mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
+
+       /* check both BUSY and ERROR cleared */
+       while ((__raw_readl(ocotp_base) &
+               (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
+               cpu_relax();
+
+       if (unlikely(!timeout))
+               goto error_unlock;
+
+       /* open OCOTP banks for read */
+       __mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+       /* approximately wait 32 hclk cycles */
+       udelay(1);
+
+       /* poll BUSY bit becoming cleared */
+       timeout = 0x400;
+       while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
+               cpu_relax();
+
+       if (unlikely(!timeout))
+               goto error_unlock;
+
+       for (i = 0; i < OCOTP_WORD_COUNT; i++)
+               ocotp_words[i] = __raw_readl(ocotp_base + OCOTP_WORD_OFFSET +
+                                               i * 0x10);
+
+       /* close banks for power saving */
+       __mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+       once = 1;
+
+       mutex_unlock(&ocotp_mutex);
+
+       return ocotp_words;
+
+error_unlock:
+       mutex_unlock(&ocotp_mutex);
+       pr_err("%s: timeout in reading OCOTP\n", __func__);
+       return NULL;
 }
 
 enum mac_oui {
@@ -253,14 +237,6 @@ static void __init update_fec_mac_prop(enum mac_oui oui)
        }
 }
 
-static void __init imx23_evk_init(void)
-{
-       mxsfb_pdata.mode_list = mx23evk_video_modes;
-       mxsfb_pdata.mode_count = ARRAY_SIZE(mx23evk_video_modes);
-       mxsfb_pdata.default_bpp = 32;
-       mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT;
-}
-
 static inline void enable_clk_enet_out(void)
 {
        struct clk *clk = clk_get_sys("enet_out", NULL);
@@ -271,14 +247,8 @@ static inline void enable_clk_enet_out(void)
 
 static void __init imx28_evk_init(void)
 {
-       enable_clk_enet_out();
        update_fec_mac_prop(OUI_FSL);
 
-       mxsfb_pdata.mode_list = mx28evk_video_modes;
-       mxsfb_pdata.mode_count = ARRAY_SIZE(mx28evk_video_modes);
-       mxsfb_pdata.default_bpp = 32;
-       mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT;
-
        mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0);
 }
 
@@ -291,19 +261,6 @@ static void __init imx28_evk_post_init(void)
        }
 }
 
-static void __init m28evk_init(void)
-{
-       mxsfb_pdata.mode_list = m28evk_video_modes;
-       mxsfb_pdata.mode_count = ARRAY_SIZE(m28evk_video_modes);
-       mxsfb_pdata.default_bpp = 16;
-       mxsfb_pdata.ld_intf_width = STMLCDIF_18BIT;
-}
-
-static void __init sc_sps1_init(void)
-{
-       enable_clk_enet_out();
-}
-
 static int apx4devkit_phy_fixup(struct phy_device *phy)
 {
        phy->dev_flags |= MICREL_PHY_50MHZ_CLK;
@@ -317,11 +274,6 @@ static void __init apx4devkit_init(void)
        if (IS_BUILTIN(CONFIG_PHYLIB))
                phy_register_fixup_for_uid(PHY_ID_KSZ8051, MICREL_PHY_ID_MASK,
                                           apx4devkit_phy_fixup);
-
-       mxsfb_pdata.mode_list = apx4devkit_video_modes;
-       mxsfb_pdata.mode_count = ARRAY_SIZE(apx4devkit_video_modes);
-       mxsfb_pdata.default_bpp = 32;
-       mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT;
 }
 
 #define ENET0_MDC__GPIO_4_0    MXS_GPIO_NR(4, 0)
@@ -400,49 +352,24 @@ static void __init tx28_post_init(void)
 
 static void __init cfa10049_init(void)
 {
-       enable_clk_enet_out();
        update_fec_mac_prop(OUI_CRYSTALFONTZ);
-
-       mxsfb_pdata.mode_list = cfa10049_video_modes;
-       mxsfb_pdata.mode_count = ARRAY_SIZE(cfa10049_video_modes);
-       mxsfb_pdata.default_bpp = 32;
-       mxsfb_pdata.ld_intf_width = STMLCDIF_18BIT;
 }
 
 static void __init cfa10037_init(void)
 {
-       enable_clk_enet_out();
        update_fec_mac_prop(OUI_CRYSTALFONTZ);
 }
 
-static void __init apf28_init(void)
-{
-       enable_clk_enet_out();
-
-       mxsfb_pdata.mode_list = apf28dev_video_modes;
-       mxsfb_pdata.mode_count = ARRAY_SIZE(apf28dev_video_modes);
-       mxsfb_pdata.default_bpp = 16;
-       mxsfb_pdata.ld_intf_width = STMLCDIF_16BIT;
-}
-
 static void __init mxs_machine_init(void)
 {
        if (of_machine_is_compatible("fsl,imx28-evk"))
                imx28_evk_init();
-       else if (of_machine_is_compatible("fsl,imx23-evk"))
-               imx23_evk_init();
-       else if (of_machine_is_compatible("denx,m28evk"))
-               m28evk_init();
        else if (of_machine_is_compatible("bluegiga,apx4devkit"))
                apx4devkit_init();
        else if (of_machine_is_compatible("crystalfontz,cfa10037"))
                cfa10037_init();
        else if (of_machine_is_compatible("crystalfontz,cfa10049"))
                cfa10049_init();
-       else if (of_machine_is_compatible("armadeus,imx28-apf28"))
-               apf28_init();
-       else if (of_machine_is_compatible("schulercontrol,imx28-sps1"))
-               sc_sps1_init();
 
        of_platform_populate(NULL, of_default_bus_match_table,
                             mxs_auxdata_lookup, NULL);
@@ -454,32 +381,62 @@ static void __init mxs_machine_init(void)
                imx28_evk_post_init();
 }
 
-static const char *imx23_dt_compat[] __initdata = {
-       "fsl,imx23",
-       NULL,
-};
+#define MX23_CLKCTRL_RESET_OFFSET      0x120
+#define MX28_CLKCTRL_RESET_OFFSET      0x1e0
+#define MXS_CLKCTRL_RESET_CHIP         (1 << 1)
+
+/*
+ * Reset the system. It is called by machine_restart().
+ */
+static void mxs_restart(char mode, const char *cmd)
+{
+       struct device_node *np;
+       void __iomem *reset_addr;
+
+       np = of_find_compatible_node(NULL, NULL, "fsl,clkctrl");
+       reset_addr = of_iomap(np, 0);
+       if (!reset_addr)
+               goto soft;
+
+       if (of_device_is_compatible(np, "fsl,imx23-clkctrl"))
+               reset_addr += MX23_CLKCTRL_RESET_OFFSET;
+       else
+               reset_addr += MX28_CLKCTRL_RESET_OFFSET;
+
+       /* reset the chip */
+       __mxs_setl(MXS_CLKCTRL_RESET_CHIP, reset_addr);
+
+       pr_err("Failed to assert the chip reset\n");
+
+       /* Delay to allow the serial port to show the message */
+       mdelay(50);
+
+soft:
+       /* We'll take a jump through zero as a poor second */
+       soft_restart(0);
+}
 
-static const char *imx28_dt_compat[] __initdata = {
+static void __init mxs_timer_init(void)
+{
+       if (of_machine_is_compatible("fsl,imx23"))
+               mx23_clocks_init();
+       else
+               mx28_clocks_init();
+       clocksource_of_init();
+}
+
+static const char *mxs_dt_compat[] __initdata = {
        "fsl,imx28",
+       "fsl,imx23",
        NULL,
 };
 
-DT_MACHINE_START(IMX23, "Freescale i.MX23 (Device Tree)")
-       .map_io         = mx23_map_io,
-       .init_irq       = icoll_init_irq,
-       .handle_irq     = icoll_handle_irq,
-       .init_time      = imx23_timer_init,
-       .init_machine   = mxs_machine_init,
-       .dt_compat      = imx23_dt_compat,
-       .restart        = mxs_restart,
-MACHINE_END
-
-DT_MACHINE_START(IMX28, "Freescale i.MX28 (Device Tree)")
-       .map_io         = mx28_map_io,
-       .init_irq       = icoll_init_irq,
+DT_MACHINE_START(MXS, "Freescale MXS (Device Tree)")
+       .map_io         = debug_ll_io_init,
+       .init_irq       = irqchip_init,
        .handle_irq     = icoll_handle_irq,
-       .init_time      = imx28_timer_init,
+       .init_time      = mxs_timer_init,
        .init_machine   = mxs_machine_init,
-       .dt_compat      = imx28_dt_compat,
+       .dt_compat      = mxs_dt_compat,
        .restart        = mxs_restart,
 MACHINE_END
diff --git a/arch/arm/mach-mxs/mm.c b/arch/arm/mach-mxs/mm.c
deleted file mode 100644 (file)
index e63b7d8..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * The code contained herein is licensed under the GNU General Public
- * License.  You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- *
- * Create static mapping between physical to virtual memory.
- */
-
-#include <linux/mm.h>
-#include <linux/init.h>
-
-#include <asm/mach/map.h>
-
-#include <mach/mx23.h>
-#include <mach/mx28.h>
-#include <mach/common.h>
-
-/*
- * Define the MX23 memory map.
- */
-static struct map_desc mx23_io_desc[] __initdata = {
-       mxs_map_entry(MX23, OCRAM, MT_DEVICE),
-       mxs_map_entry(MX23, IO, MT_DEVICE),
-};
-
-/*
- * Define the MX28 memory map.
- */
-static struct map_desc mx28_io_desc[] __initdata = {
-       mxs_map_entry(MX28, OCRAM, MT_DEVICE),
-       mxs_map_entry(MX28, IO, MT_DEVICE),
-};
-
-/*
- * This function initializes the memory map. It is called during the
- * system startup to create static physical to virtual memory mappings
- * for the IO modules.
- */
-void __init mx23_map_io(void)
-{
-       iotable_init(mx23_io_desc, ARRAY_SIZE(mx23_io_desc));
-}
-
-void __init mx28_map_io(void)
-{
-       iotable_init(mx28_io_desc, ARRAY_SIZE(mx28_io_desc));
-}
diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
deleted file mode 100644 (file)
index 1dff467..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * 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/delay.h>
-#include <linux/err.h>
-#include <linux/mutex.h>
-
-#include <asm/processor.h>     /* for cpu_relax() */
-
-#include <mach/mxs.h>
-#include <mach/common.h>
-
-#define OCOTP_WORD_OFFSET              0x20
-#define OCOTP_WORD_COUNT               0x20
-
-#define BM_OCOTP_CTRL_BUSY             (1 << 8)
-#define BM_OCOTP_CTRL_ERROR            (1 << 9)
-#define BM_OCOTP_CTRL_RD_BANK_OPEN     (1 << 12)
-
-static DEFINE_MUTEX(ocotp_mutex);
-static u32 ocotp_words[OCOTP_WORD_COUNT];
-
-const u32 *mxs_get_ocotp(void)
-{
-       void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
-       int timeout = 0x400;
-       size_t i;
-       static int once = 0;
-
-       if (once)
-               return ocotp_words;
-
-       mutex_lock(&ocotp_mutex);
-
-       /*
-        * clk_enable(hbus_clk) for ocotp can be skipped
-        * as it must be on when system is running.
-        */
-
-       /* try to clear ERROR bit */
-       __mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
-
-       /* check both BUSY and ERROR cleared */
-       while ((__raw_readl(ocotp_base) &
-               (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
-               cpu_relax();
-
-       if (unlikely(!timeout))
-               goto error_unlock;
-
-       /* open OCOTP banks for read */
-       __mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
-
-       /* approximately wait 32 hclk cycles */
-       udelay(1);
-
-       /* poll BUSY bit becoming cleared */
-       timeout = 0x400;
-       while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
-               cpu_relax();
-
-       if (unlikely(!timeout))
-               goto error_unlock;
-
-       for (i = 0; i < OCOTP_WORD_COUNT; i++)
-               ocotp_words[i] = __raw_readl(ocotp_base + OCOTP_WORD_OFFSET +
-                                               i * 0x10);
-
-       /* close banks for power saving */
-       __mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
-
-       once = 1;
-
-       mutex_unlock(&ocotp_mutex);
-
-       return ocotp_words;
-
-error_unlock:
-       mutex_unlock(&ocotp_mutex);
-       pr_err("%s: timeout in reading OCOTP\n", __func__);
-       return NULL;
-}
diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
deleted file mode 100644 (file)
index 30042e2..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 1999 ARM Limited
- * Copyright (C) 2000 Deep Blue Solutions Ltd
- * Copyright 2006-2007,2010 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
- * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok@emcraft.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/kernel.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/err.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include <asm/proc-fns.h>
-#include <asm/system_misc.h>
-
-#include <mach/mxs.h>
-#include <mach/common.h>
-
-#define MX23_CLKCTRL_RESET_OFFSET      0x120
-#define MX28_CLKCTRL_RESET_OFFSET      0x1e0
-#define MXS_CLKCTRL_RESET_CHIP         (1 << 1)
-
-#define MXS_MODULE_CLKGATE             (1 << 30)
-#define MXS_MODULE_SFTRST              (1 << 31)
-
-static void __iomem *mxs_clkctrl_reset_addr;
-
-/*
- * Reset the system. It is called by machine_restart().
- */
-void mxs_restart(char mode, const char *cmd)
-{
-       /* reset the chip */
-       __mxs_setl(MXS_CLKCTRL_RESET_CHIP, mxs_clkctrl_reset_addr);
-
-       pr_err("Failed to assert the chip reset\n");
-
-       /* Delay to allow the serial port to show the message */
-       mdelay(50);
-
-       /* We'll take a jump through zero as a poor second */
-       soft_restart(0);
-}
-
-static int __init mxs_arch_reset_init(void)
-{
-       struct clk *clk;
-
-       mxs_clkctrl_reset_addr = MXS_IO_ADDRESS(MXS_CLKCTRL_BASE_ADDR) +
-                               (cpu_is_mx23() ? MX23_CLKCTRL_RESET_OFFSET :
-                                                MX28_CLKCTRL_RESET_OFFSET);
-
-       clk = clk_get_sys("rtc", NULL);
-       if (!IS_ERR(clk))
-               clk_prepare_enable(clk);
-
-       return 0;
-}
-core_initcall(mxs_arch_reset_init);
-
-/*
- * Clear the bit and poll it cleared.  This is usually called with
- * a reset address and mask being either SFTRST(bit 31) or CLKGATE
- * (bit 30).
- */
-static int clear_poll_bit(void __iomem *addr, u32 mask)
-{
-       int timeout = 0x400;
-
-       /* clear the bit */
-       __mxs_clrl(mask, addr);
-
-       /*
-        * SFTRST needs 3 GPMI clocks to settle, the reference manual
-        * recommends to wait 1us.
-        */
-       udelay(1);
-
-       /* poll the bit becoming clear */
-       while ((__raw_readl(addr) & mask) && --timeout)
-               /* nothing */;
-
-       return !timeout;
-}
-
-int mxs_reset_block(void __iomem *reset_addr)
-{
-       int ret;
-       int timeout = 0x400;
-
-       /* clear and poll SFTRST */
-       ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
-       if (unlikely(ret))
-               goto error;
-
-       /* clear CLKGATE */
-       __mxs_clrl(MXS_MODULE_CLKGATE, reset_addr);
-
-       /* set SFTRST to reset the block */
-       __mxs_setl(MXS_MODULE_SFTRST, reset_addr);
-       udelay(1);
-
-       /* poll CLKGATE becoming set */
-       while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
-               /* nothing */;
-       if (unlikely(!timeout))
-               goto error;
-
-       /* clear and poll SFTRST */
-       ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
-       if (unlikely(ret))
-               goto error;
-
-       /* clear and poll CLKGATE */
-       ret = clear_poll_bit(reset_addr, MXS_MODULE_CLKGATE);
-       if (unlikely(ret))
-               goto error;
-
-       return 0;
-
-error:
-       pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
-       return -ETIMEDOUT;
-}
-EXPORT_SYMBOL(mxs_reset_block);
diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
deleted file mode 100644 (file)
index 4210204..0000000
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- *  Copyright (C) 2000-2001 Deep Blue Solutions
- *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
- *  Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com)
- *  Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
- *  Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <linux/err.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/clockchips.h>
-#include <linux/clk.h>
-#include <linux/of.h>
-#include <linux/of_irq.h>
-
-#include <asm/mach/time.h>
-#include <asm/sched_clock.h>
-#include <mach/mxs.h>
-#include <mach/common.h>
-
-/*
- * There are 2 versions of the timrot on Freescale MXS-based SoCs.
- * The v1 on MX23 only gets 16 bits counter, while v2 on MX28
- * extends the counter to 32 bits.
- *
- * The implementation uses two timers, one for clock_event and
- * another for clocksource. MX28 uses timrot 0 and 1, while MX23
- * uses 0 and 2.
- */
-
-#define MX23_TIMROT_VERSION_OFFSET     0x0a0
-#define MX28_TIMROT_VERSION_OFFSET     0x120
-#define BP_TIMROT_MAJOR_VERSION                24
-#define BV_TIMROT_VERSION_1            0x01
-#define BV_TIMROT_VERSION_2            0x02
-#define timrot_is_v1() (timrot_major_version == BV_TIMROT_VERSION_1)
-
-/*
- * There are 4 registers for each timrotv2 instance, and 2 registers
- * for each timrotv1. So address step 0x40 in macros below strides
- * one instance of timrotv2 while two instances of timrotv1.
- *
- * As the result, HW_TIMROT_XXXn(1) defines the address of timrot1
- * on MX28 while timrot2 on MX23.
- */
-/* common between v1 and v2 */
-#define HW_TIMROT_ROTCTRL              0x00
-#define HW_TIMROT_TIMCTRLn(n)          (0x20 + (n) * 0x40)
-/* v1 only */
-#define HW_TIMROT_TIMCOUNTn(n)         (0x30 + (n) * 0x40)
-/* v2 only */
-#define HW_TIMROT_RUNNING_COUNTn(n)    (0x30 + (n) * 0x40)
-#define HW_TIMROT_FIXED_COUNTn(n)      (0x40 + (n) * 0x40)
-
-#define BM_TIMROT_TIMCTRLn_RELOAD      (1 << 6)
-#define BM_TIMROT_TIMCTRLn_UPDATE      (1 << 7)
-#define BM_TIMROT_TIMCTRLn_IRQ_EN      (1 << 14)
-#define BM_TIMROT_TIMCTRLn_IRQ         (1 << 15)
-#define BP_TIMROT_TIMCTRLn_SELECT      0
-#define BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL                0x8
-#define BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL                0xb
-#define BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS       0xf
-
-static struct clock_event_device mxs_clockevent_device;
-static enum clock_event_mode mxs_clockevent_mode = CLOCK_EVT_MODE_UNUSED;
-
-static void __iomem *mxs_timrot_base = MXS_IO_ADDRESS(MXS_TIMROT_BASE_ADDR);
-static u32 timrot_major_version;
-
-static inline void timrot_irq_disable(void)
-{
-       __mxs_clrl(BM_TIMROT_TIMCTRLn_IRQ_EN,
-                       mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
-}
-
-static inline void timrot_irq_enable(void)
-{
-       __mxs_setl(BM_TIMROT_TIMCTRLn_IRQ_EN,
-                       mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
-}
-
-static void timrot_irq_acknowledge(void)
-{
-       __mxs_clrl(BM_TIMROT_TIMCTRLn_IRQ,
-                       mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
-}
-
-static cycle_t timrotv1_get_cycles(struct clocksource *cs)
-{
-       return ~((__raw_readl(mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1))
-                       & 0xffff0000) >> 16);
-}
-
-static int timrotv1_set_next_event(unsigned long evt,
-                                       struct clock_event_device *dev)
-{
-       /* timrot decrements the count */
-       __raw_writel(evt, mxs_timrot_base + HW_TIMROT_TIMCOUNTn(0));
-
-       return 0;
-}
-
-static int timrotv2_set_next_event(unsigned long evt,
-                                       struct clock_event_device *dev)
-{
-       /* timrot decrements the count */
-       __raw_writel(evt, mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(0));
-
-       return 0;
-}
-
-static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
-{
-       struct clock_event_device *evt = dev_id;
-
-       timrot_irq_acknowledge();
-       evt->event_handler(evt);
-
-       return IRQ_HANDLED;
-}
-
-static struct irqaction mxs_timer_irq = {
-       .name           = "MXS Timer Tick",
-       .dev_id         = &mxs_clockevent_device,
-       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
-       .handler        = mxs_timer_interrupt,
-};
-
-#ifdef DEBUG
-static const char *clock_event_mode_label[] const = {
-       [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
-       [CLOCK_EVT_MODE_ONESHOT]  = "CLOCK_EVT_MODE_ONESHOT",
-       [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
-       [CLOCK_EVT_MODE_UNUSED]   = "CLOCK_EVT_MODE_UNUSED"
-};
-#endif /* DEBUG */
-
-static void mxs_set_mode(enum clock_event_mode mode,
-                               struct clock_event_device *evt)
-{
-       /* Disable interrupt in timer module */
-       timrot_irq_disable();
-
-       if (mode != mxs_clockevent_mode) {
-               /* Set event time into the furthest future */
-               if (timrot_is_v1())
-                       __raw_writel(0xffff,
-                               mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1));
-               else
-                       __raw_writel(0xffffffff,
-                               mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1));
-
-               /* Clear pending interrupt */
-               timrot_irq_acknowledge();
-       }
-
-#ifdef DEBUG
-       pr_info("%s: changing mode from %s to %s\n", __func__,
-               clock_event_mode_label[mxs_clockevent_mode],
-               clock_event_mode_label[mode]);
-#endif /* DEBUG */
-
-       /* Remember timer mode */
-       mxs_clockevent_mode = mode;
-
-       switch (mode) {
-       case CLOCK_EVT_MODE_PERIODIC:
-               pr_err("%s: Periodic mode is not implemented\n", __func__);
-               break;
-       case CLOCK_EVT_MODE_ONESHOT:
-               timrot_irq_enable();
-               break;
-       case CLOCK_EVT_MODE_SHUTDOWN:
-       case CLOCK_EVT_MODE_UNUSED:
-       case CLOCK_EVT_MODE_RESUME:
-               /* Left event sources disabled, no more interrupts appear */
-               break;
-       }
-}
-
-static struct clock_event_device mxs_clockevent_device = {
-       .name           = "mxs_timrot",
-       .features       = CLOCK_EVT_FEAT_ONESHOT,
-       .set_mode       = mxs_set_mode,
-       .set_next_event = timrotv2_set_next_event,
-       .rating         = 200,
-};
-
-static int __init mxs_clockevent_init(struct clk *timer_clk)
-{
-       if (timrot_is_v1())
-               mxs_clockevent_device.set_next_event = timrotv1_set_next_event;
-       mxs_clockevent_device.cpumask = cpumask_of(0);
-       clockevents_config_and_register(&mxs_clockevent_device,
-                                       clk_get_rate(timer_clk),
-                                       timrot_is_v1() ? 0xf : 0x2,
-                                       timrot_is_v1() ? 0xfffe : 0xfffffffe);
-
-       return 0;
-}
-
-static struct clocksource clocksource_mxs = {
-       .name           = "mxs_timer",
-       .rating         = 200,
-       .read           = timrotv1_get_cycles,
-       .mask           = CLOCKSOURCE_MASK(16),
-       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-static u32 notrace mxs_read_sched_clock_v2(void)
-{
-       return ~readl_relaxed(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1));
-}
-
-static int __init mxs_clocksource_init(struct clk *timer_clk)
-{
-       unsigned int c = clk_get_rate(timer_clk);
-
-       if (timrot_is_v1())
-               clocksource_register_hz(&clocksource_mxs, c);
-       else {
-               clocksource_mmio_init(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1),
-                       "mxs_timer", c, 200, 32, clocksource_mmio_readl_down);
-               setup_sched_clock(mxs_read_sched_clock_v2, 32, c);
-       }
-
-       return 0;
-}
-
-void __init mxs_timer_init(void)
-{
-       struct device_node *np;
-       struct clk *timer_clk;
-       int irq;
-
-       np = of_find_compatible_node(NULL, NULL, "fsl,timrot");
-       if (!np) {
-               pr_err("%s: failed find timrot node\n", __func__);
-               return;
-       }
-
-       timer_clk = clk_get_sys("timrot", NULL);
-       if (IS_ERR(timer_clk)) {
-               pr_err("%s: failed to get clk\n", __func__);
-               return;
-       }
-
-       clk_prepare_enable(timer_clk);
-
-       /*
-        * Initialize timers to a known state
-        */
-       mxs_reset_block(mxs_timrot_base + HW_TIMROT_ROTCTRL);
-
-       /* get timrot version */
-       timrot_major_version = __raw_readl(mxs_timrot_base +
-                               (cpu_is_mx23() ? MX23_TIMROT_VERSION_OFFSET :
-                                               MX28_TIMROT_VERSION_OFFSET));
-       timrot_major_version >>= BP_TIMROT_MAJOR_VERSION;
-
-       /* one for clock_event */
-       __raw_writel((timrot_is_v1() ?
-                       BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
-                       BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS) |
-                       BM_TIMROT_TIMCTRLn_UPDATE |
-                       BM_TIMROT_TIMCTRLn_IRQ_EN,
-                       mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
-
-       /* another for clocksource */
-       __raw_writel((timrot_is_v1() ?
-                       BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
-                       BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS) |
-                       BM_TIMROT_TIMCTRLn_RELOAD,
-                       mxs_timrot_base + HW_TIMROT_TIMCTRLn(1));
-
-       /* set clocksource timer fixed count to the maximum */
-       if (timrot_is_v1())
-               __raw_writel(0xffff,
-                       mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1));
-       else
-               __raw_writel(0xffffffff,
-                       mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1));
-
-       /* init and register the timer to the framework */
-       mxs_clocksource_init(timer_clk);
-       mxs_clockevent_init(timer_clk);
-
-       /* Make irqs happen */
-       irq = irq_of_parse_and_map(np, 0);
-       setup_irq(irq, &mxs_timer_irq);
-}
index 903da8eb886c8ebc6abe1a79dab58b0d79a98730..cdd05f2e67ee87148a023bd2af8025fbfb5b5bff 100644 (file)
@@ -55,12 +55,6 @@ config MACH_OMAP_H3
          TI OMAP 1710 H3 board support. Say Y here if you have such
          a board.
 
-config MACH_OMAP_HTCWIZARD
-       bool "HTC Wizard"
-       depends on ARCH_OMAP850
-       help
-         HTC Wizard smartphone support (AKA QTEK 9100, ...)
-
 config MACH_HERALD
        bool "HTC Herald"
        depends on ARCH_OMAP850
index 8111cd9ff3e5201d9c92a66a90a24e30823d7074..b9c0ed3f648c8415f432a5f4b8f079c163beb013 100644 (file)
@@ -408,7 +408,7 @@ config OMAP3_SDRC_AC_TIMING
 
 config OMAP4_ERRATA_I688
        bool "OMAP4 errata: Async Bridge Corruption"
-       depends on ARCH_OMAP4 && !ARCH_MULTIPLATFORM
+       depends on (ARCH_OMAP4 || SOC_OMAP5) && !ARCH_MULTIPLATFORM
        select ARCH_HAS_BARRIERS
        help
          If a data is stalled inside asynchronous bridge because of back
index a3e0aaa4886b9c4954160d585115a219d1ba3a95..cb0596b631cff4feef830b27f0904be930416b47 100644 (file)
@@ -166,7 +166,7 @@ static void __init sdp2430_display_init(void)
        omap_display_init(&sdp2430_dss_data);
 }
 
-#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91x_MODULE)
+#if IS_ENABLED(CONFIG_SMC91X)
 
 static struct omap_smc91x_platform_data board_smc91x_data = {
        .cs             = 5,
index ce812decfacad108eecdb20174f7c030ffcf5cc5..7eb9651dd0f7e02d7e19c52c3d81d0bfa5cfc8dc 100644 (file)
@@ -445,16 +445,23 @@ static void enable_board_wakeup_source(void)
                OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
 }
 
+static struct usbhs_phy_data phy_data[] __initdata = {
+       {
+               .port = 1,
+               .reset_gpio = 57,
+               .vcc_gpio = -EINVAL,
+       },
+       {
+               .port = 2,
+               .reset_gpio = 61,
+               .vcc_gpio = -EINVAL,
+       },
+};
+
 static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
 
        .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
        .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
-       .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
-       .phy_reset  = true,
-       .reset_gpio_port[0]  = 57,
-       .reset_gpio_port[1]  = 61,
-       .reset_gpio_port[2]  = -EINVAL
 };
 
 #ifdef CONFIG_OMAP_MUX
@@ -606,6 +613,8 @@ static void __init omap_3430sdp_init(void)
        board_flash_init(sdp_flash_partitions, chip_sel_3430, 0);
        sdp3430_display_init();
        enable_board_wakeup_source();
+
+       usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
        usbhs_init(&usbhs_bdata);
 }
 
index 67447bd4564fbd05c5956ebed41a5de3e10ac3f6..20d6d8189240d3343798833578093d4ae9933f36 100644 (file)
@@ -53,16 +53,23 @@ static void enable_board_wakeup_source(void)
                OMAP_WAKEUP_EN | OMAP_PIN_INPUT_PULLUP);
 }
 
+static struct usbhs_phy_data phy_data[] __initdata = {
+       {
+               .port = 1,
+               .reset_gpio = 126,
+               .vcc_gpio = -EINVAL,
+       },
+       {
+               .port = 2,
+               .reset_gpio = 61,
+               .vcc_gpio = -EINVAL,
+       },
+};
+
 static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
 
        .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
        .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
-       .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
-       .phy_reset  = true,
-       .reset_gpio_port[0]  = 126,
-       .reset_gpio_port[1]  = 61,
-       .reset_gpio_port[2]  = -EINVAL
 };
 
 #ifdef CONFIG_OMAP_MUX
@@ -199,6 +206,8 @@ static void __init omap_sdp_init(void)
        board_smc91x_init();
        board_flash_init(sdp_flash_partitions, chip_sel_sdp, NAND_BUSWIDTH_16);
        enable_board_wakeup_source();
+
+       usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
        usbhs_init(&usbhs_bdata);
 }
 
index 7d3358b2e59369083cd02cbf31d38abb0e3bb282..fc53911d0d13b9842a7efcf28ba4431159df0bc4 100644 (file)
@@ -47,15 +47,17 @@ static struct omap_board_mux board_mux[] __initdata = {
 };
 #endif
 
+static struct usbhs_phy_data phy_data[] __initdata = {
+       {
+               .port = 1,
+               .reset_gpio = GPIO_USB_NRESET,
+               .vcc_gpio = GPIO_USB_POWER,
+               .vcc_polarity = 1,
+       },
+};
+
 static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
        .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
-       .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
-       .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
-       .phy_reset  = true,
-       .reset_gpio_port[0]  = GPIO_USB_NRESET,
-       .reset_gpio_port[1]  = -EINVAL,
-       .reset_gpio_port[2]  = -EINVAL
 };
 
 static struct mtd_partition crane_nand_partitions[] = {
@@ -131,13 +133,7 @@ static void __init am3517_crane_init(void)
                return;
        }
 
-       ret = gpio_request_one(GPIO_USB_POWER, GPIOF_OUT_INIT_HIGH,
-                              "usb_ehci_enable");
-       if (ret < 0) {
-               pr_err("Can not request GPIO %d\n", GPIO_USB_POWER);
-               return;
-       }
-
+       usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
        usbhs_init(&usbhs_bdata);
        am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1);
 }
index 9fb85908a61e498a7ae7ec27f18fe2f7b45756db..191f9762ba63c4eb4368b95a862b17228ac5049c 100644 (file)
@@ -274,6 +274,14 @@ static __init void am3517_evm_mcbsp1_init(void)
        omap_ctrl_writel(devconf0, OMAP2_CONTROL_DEVCONF0);
 }
 
+static struct usbhs_phy_data phy_data[] __initdata = {
+       {
+               .port = 1,
+               .reset_gpio = 57,
+               .vcc_gpio = -EINVAL,
+       },
+};
+
 static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
        .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
 #if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \
@@ -282,12 +290,6 @@ static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
 #else
        .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
 #endif
-       .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
-       .phy_reset  = true,
-       .reset_gpio_port[0]  = 57,
-       .reset_gpio_port[1]  = -EINVAL,
-       .reset_gpio_port[2]  = -EINVAL
 };
 
 #ifdef CONFIG_OMAP_MUX
@@ -349,7 +351,6 @@ static struct omap2_hsmmc_info mmc[] = {
        {}      /* Terminator */
 };
 
-
 static void __init am3517_evm_init(void)
 {
        omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
@@ -361,6 +362,8 @@ static void __init am3517_evm_init(void)
 
        /* Configure GPIO for EHCI port */
        omap_mux_init_gpio(57, OMAP_PIN_OUTPUT);
+
+       usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
        usbhs_init(&usbhs_bdata);
        am3517_evm_hecc_init(&am3517_evm_hecc_pdata);
        /* DSS */
index af2bb219e2147d922c95f829e833804f421184b3..7fda3f5f8a7fdf8ce0de057241342333729a8fc8 100644 (file)
@@ -419,15 +419,22 @@ static struct omap2_hsmmc_info mmc[] = {
        {}      /* Terminator */
 };
 
+static struct usbhs_phy_data phy_data[] __initdata = {
+       {
+               .port = 1,
+               .reset_gpio = OMAP_MAX_GPIO_LINES + 6,
+               .vcc_gpio = -EINVAL,
+       },
+       {
+               .port = 2,
+               .reset_gpio = OMAP_MAX_GPIO_LINES + 7,
+               .vcc_gpio = -EINVAL,
+       },
+};
+
 static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
        .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
        .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
-       .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
-       .phy_reset  = true,
-       .reset_gpio_port[0]  = OMAP_MAX_GPIO_LINES + 6,
-       .reset_gpio_port[1]  = OMAP_MAX_GPIO_LINES + 7,
-       .reset_gpio_port[2]  = -EINVAL
 };
 
 static void  __init cm_t35_init_usbh(void)
@@ -444,6 +451,7 @@ static void  __init cm_t35_init_usbh(void)
                msleep(1);
        }
 
+       usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
        usbhs_init(&usbhs_bdata);
 }
 
index a66da808cc4ab011d7d97f449bd33f6a51272b4c..6920f6cfc97c30e67ff45d75deb9bcebd59efe25 100644 (file)
@@ -188,15 +188,22 @@ static inline void cm_t3517_init_rtc(void) {}
 #define HSUSB2_RESET_GPIO      (147)
 #define USB_HUB_RESET_GPIO     (152)
 
+static struct usbhs_phy_data phy_data[] __initdata = {
+       {
+               .port = 1,
+               .reset_gpio = HSUSB1_RESET_GPIO,
+               .vcc_gpio = -EINVAL,
+       },
+       {
+               .port = 2,
+               .reset_gpio = HSUSB2_RESET_GPIO,
+               .vcc_gpio = -EINVAL,
+       },
+};
+
 static struct usbhs_omap_platform_data cm_t3517_ehci_pdata __initdata = {
        .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
        .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
-       .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
-       .phy_reset  = true,
-       .reset_gpio_port[0]  = HSUSB1_RESET_GPIO,
-       .reset_gpio_port[1]  = HSUSB2_RESET_GPIO,
-       .reset_gpio_port[2]  = -EINVAL,
 };
 
 static int __init cm_t3517_init_usbh(void)
@@ -213,6 +220,7 @@ static int __init cm_t3517_init_usbh(void)
                msleep(1);
        }
 
+       usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
        usbhs_init(&cm_t3517_ehci_pdata);
 
        return 0;
index 53056c3b08362ea6a4c40f8a044f2b146018a1d8..42fbf1ef12a949778107b7a5e8aa76b18638e986 100644 (file)
@@ -437,15 +437,7 @@ static struct platform_device *devkit8000_devices[] __initdata = {
 };
 
 static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
-
        .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
-       .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
-       .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
-       .phy_reset  = true,
-       .reset_gpio_port[0]  = -EINVAL,
-       .reset_gpio_port[1]  = -EINVAL,
-       .reset_gpio_port[2]  = -EINVAL
 };
 
 #ifdef CONFIG_OMAP_MUX
index e54a480601988402e4b43fe54e4ac287fbed51d4..afa509afb27cfdcce2dff5a2cd3a417eecd1b34a 100644 (file)
@@ -110,6 +110,7 @@ MACHINE_END
 
 static const char *omap3_gp_boards_compat[] __initdata = {
        "ti,omap3-beagle",
+       "timll,omap3-devkit8000",
        NULL,
 };
 
index 812c829fa46f60a3af0aeec99bcb45555500bb05..5b4ec51c385f06ecdaf0b3f0b231e0f281bee3c2 100644 (file)
@@ -246,7 +246,7 @@ static u32 is_gpmc_muxed(void)
                return 0;
 }
 
-#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91x_MODULE)
+#if IS_ENABLED(CONFIG_SMC91X)
 
 static struct omap_smc91x_platform_data board_smc91x_data = {
        .cs             = 1,
index bf92678a01d061dabd0d857dfb00d83504ce034a..95ccec0eeab919f33101e657147955056c818ca2 100644 (file)
@@ -527,26 +527,28 @@ static void __init igep_i2c_init(void)
        omap3_pmic_init("twl4030", &igep_twldata);
 }
 
+static struct usbhs_phy_data igep2_phy_data[] __initdata = {
+       {
+               .port = 1,
+               .reset_gpio = IGEP2_GPIO_USBH_NRESET,
+               .vcc_gpio = -EINVAL,
+       },
+};
+
+static struct usbhs_phy_data igep3_phy_data[] __initdata = {
+       {
+               .port = 2,
+               .reset_gpio = IGEP3_GPIO_USBH_NRESET,
+               .vcc_gpio = -EINVAL,
+       },
+};
+
 static struct usbhs_omap_platform_data igep2_usbhs_bdata __initdata = {
        .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
-       .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
-       .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
-       .phy_reset = true,
-       .reset_gpio_port[0] = IGEP2_GPIO_USBH_NRESET,
-       .reset_gpio_port[1] = -EINVAL,
-       .reset_gpio_port[2] = -EINVAL,
 };
 
 static struct usbhs_omap_platform_data igep3_usbhs_bdata __initdata = {
-       .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
        .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
-       .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
-       .phy_reset = true,
-       .reset_gpio_port[0] = -EINVAL,
-       .reset_gpio_port[1] = IGEP3_GPIO_USBH_NRESET,
-       .reset_gpio_port[2] = -EINVAL,
 };
 
 #ifdef CONFIG_OMAP_MUX
@@ -642,8 +644,10 @@ static void __init igep_init(void)
        if (machine_is_igep0020()) {
                omap_display_init(&igep2_dss_data);
                igep2_init_smsc911x();
+               usbhs_init_phys(igep2_phy_data, ARRAY_SIZE(igep2_phy_data));
                usbhs_init(&igep2_usbhs_bdata);
        } else {
+               usbhs_init_phys(igep3_phy_data, ARRAY_SIZE(igep3_phy_data));
                usbhs_init(&igep3_usbhs_bdata);
        }
 }
index c3558f93d42c4a3d52f705573be61e156ff59669..5382215a49bc9fa364ce5e255af9ec6a49770fda 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/mmc/host.h>
 #include <linux/usb/phy.h>
+#include <linux/usb/nop-usb-xceiv.h>
 
 #include <linux/regulator/machine.h>
 #include <linux/i2c/twl.h>
@@ -277,6 +278,21 @@ static struct regulator_consumer_supply beagle_vsim_supply[] = {
 
 static struct gpio_led gpio_leds[];
 
+/* PHY's VCC regulator might be added later, so flag that we need it */
+static struct nop_usb_xceiv_platform_data hsusb2_phy_data = {
+       .needs_vcc = true,
+};
+
+static struct usbhs_phy_data phy_data[] = {
+       {
+               .port = 2,
+               .reset_gpio = 147,
+               .vcc_gpio = -1,         /* updated in beagle_twl_gpio_setup */
+               .vcc_polarity = 1,      /* updated in beagle_twl_gpio_setup */
+               .platform_data = &hsusb2_phy_data,
+       },
+};
+
 static int beagle_twl_gpio_setup(struct device *dev,
                unsigned gpio, unsigned ngpio)
 {
@@ -318,9 +334,11 @@ static int beagle_twl_gpio_setup(struct device *dev,
        }
        dvi_panel.power_down_gpio = beagle_config.dvi_pd_gpio;
 
-       gpio_request_one(gpio + TWL4030_GPIO_MAX, beagle_config.usb_pwr_level,
-                       "nEN_USB_PWR");
+       /* TWL4030_GPIO_MAX i.e. LED_GPO controls HS USB Port 2 power */
+       phy_data[0].vcc_gpio = gpio + TWL4030_GPIO_MAX;
+       phy_data[0].vcc_polarity = beagle_config.usb_pwr_level;
 
+       usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
        return 0;
 }
 
@@ -453,15 +471,7 @@ static struct platform_device *omap3_beagle_devices[] __initdata = {
 };
 
 static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
-
-       .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
        .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
-       .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
-       .phy_reset  = true,
-       .reset_gpio_port[0]  = -EINVAL,
-       .reset_gpio_port[1]  = 147,
-       .reset_gpio_port[2]  = -EINVAL
 };
 
 #ifdef CONFIG_OMAP_MUX
@@ -543,7 +553,9 @@ static void __init omap3_beagle_init(void)
 
        usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
        usb_musb_init(NULL);
+
        usbhs_init(&usbhs_bdata);
+
        board_nand_init(omap3beagle_nand_partitions,
                        ARRAY_SIZE(omap3beagle_nand_partitions), NAND_CS,
                        NAND_BUSWIDTH_16, NULL);
index 48789e0bb915059ff8b9fb26d5a2712ff095020b..2de92facc8a38234bacec820218fe4143b8b137f 100644 (file)
@@ -496,7 +496,7 @@ struct wl12xx_platform_data omap3evm_wlan_data __initdata = {
 static struct regulator_consumer_supply omap3evm_vaux2_supplies[] = {
        REGULATOR_SUPPLY("VDD_CSIPHY1", "omap3isp"),    /* OMAP ISP */
        REGULATOR_SUPPLY("VDD_CSIPHY2", "omap3isp"),    /* OMAP ISP */
-       REGULATOR_SUPPLY("hsusb1", "ehci-omap.0"),
+       REGULATOR_SUPPLY("vcc", "nop_usb_xceiv.2"),     /* hsusb port 2 */
        REGULATOR_SUPPLY("vaux2", NULL),
 };
 
@@ -539,17 +539,16 @@ static int __init omap3_evm_i2c_init(void)
        return 0;
 }
 
-static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
+static struct usbhs_phy_data phy_data[] __initdata = {
+       {
+               .port = 2,
+               .reset_gpio = -1,       /* set at runtime */
+               .vcc_gpio = -EINVAL,
+       },
+};
 
-       .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
+static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
        .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
-       .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
-       .phy_reset  = true,
-       /* PHY reset GPIO will be runtime programmed based on EVM version */
-       .reset_gpio_port[0]  = -EINVAL,
-       .reset_gpio_port[1]  = -EINVAL,
-       .reset_gpio_port[2]  = -EINVAL
 };
 
 #ifdef CONFIG_OMAP_MUX
@@ -725,7 +724,7 @@ static void __init omap3_evm_init(void)
 
                /* setup EHCI phy reset config */
                omap_mux_init_gpio(21, OMAP_PIN_INPUT_PULLUP);
-               usbhs_bdata.reset_gpio_port[1] = 21;
+               phy_data[0].reset_gpio = 21;
 
                /* EVM REV >= E can supply 500mA with EXTVBUS programming */
                musb_board_data.power = 500;
@@ -733,10 +732,12 @@ static void __init omap3_evm_init(void)
        } else {
                /* setup EHCI phy reset on MDC */
                omap_mux_init_gpio(135, OMAP_PIN_OUTPUT);
-               usbhs_bdata.reset_gpio_port[1] = 135;
+               phy_data[0].reset_gpio = 135;
        }
        usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
        usb_musb_init(&musb_board_data);
+
+       usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
        usbhs_init(&usbhs_bdata);
        board_nand_init(omap3evm_nand_partitions,
                        ARRAY_SIZE(omap3evm_nand_partitions), NAND_CS,
index 2bba362148a0c87d12a53d86d5dd5ef2ddbeb4c1..1004d2aaa68f5e29847eeb1691f7e3d909a162d7 100644 (file)
@@ -346,7 +346,7 @@ static struct regulator_consumer_supply pandora_vcc_lcd_supply[] = {
 };
 
 static struct regulator_consumer_supply pandora_usb_phy_supply[] = {
-       REGULATOR_SUPPLY("hsusb1", "ehci-omap.0"),
+       REGULATOR_SUPPLY("vcc", "nop_usb_xceiv.2"),     /* hsusb port 2 */
 };
 
 /* ads7846 on SPI and 2 nub controllers on I2C */
@@ -561,6 +561,14 @@ fail:
        printk(KERN_ERR "wl1251 board initialisation failed\n");
 }
 
+static struct usbhs_phy_data phy_data[] __initdata = {
+       {
+               .port = 2,
+               .reset_gpio = 16,
+               .vcc_gpio = -EINVAL,
+       },
+};
+
 static struct platform_device *omap3pandora_devices[] __initdata = {
        &pandora_leds_gpio,
        &pandora_keys_gpio,
@@ -569,15 +577,7 @@ static struct platform_device *omap3pandora_devices[] __initdata = {
 };
 
 static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
-
-       .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
        .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
-       .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
-       .phy_reset  = true,
-       .reset_gpio_port[0]  = -EINVAL,
-       .reset_gpio_port[1]  = 16,
-       .reset_gpio_port[2]  = -EINVAL
 };
 
 #ifdef CONFIG_OMAP_MUX
@@ -601,7 +601,10 @@ static void __init omap3pandora_init(void)
        spi_register_board_info(omap3pandora_spi_board_info,
                        ARRAY_SIZE(omap3pandora_spi_board_info));
        omap_ads7846_init(1, OMAP3_PANDORA_TS_GPIO, 0, NULL);
+
+       usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
        usbhs_init(&usbhs_bdata);
+
        usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
        usb_musb_init(NULL);
        gpmc_nand_init(&pandora_nand_data, NULL);
index 95c10b3aa678a5321be115c91a353a8296405168..bf095648989933ca0c0171ff661fc998a704a96b 100644 (file)
@@ -358,19 +358,20 @@ static int __init omap3_stalker_i2c_init(void)
 
 #define OMAP3_STALKER_TS_GPIO  175
 
+static struct usbhs_phy_data phy_data[] __initdata = {
+       {
+               .port = 2,
+               .reset_gpio = 21,
+               .vcc_gpio = -EINVAL,
+       },
+};
+
 static struct platform_device *omap3_stalker_devices[] __initdata = {
        &keys_gpio,
 };
 
 static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
-       .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
        .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
-       .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
-       .phy_reset = true,
-       .reset_gpio_port[0] = -EINVAL,
-       .reset_gpio_port[1] = 21,
-       .reset_gpio_port[2] = -EINVAL,
 };
 
 #ifdef CONFIG_OMAP_MUX
@@ -407,6 +408,8 @@ static void __init omap3_stalker_init(void)
        omap_sdrc_init(mt46h32m32lf6_sdrc_params, NULL);
        usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
        usb_musb_init(NULL);
+
+       usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
        usbhs_init(&usbhs_bdata);
        omap_ads7846_init(1, OMAP3_STALKER_TS_GPIO, 310, NULL);
 
index bcd44fbcd87785f4332f881d4b23bbb4da7f5d5f..7da48bc42bbfbb2007ac244a594c54299a2eb13d 100644 (file)
@@ -305,21 +305,22 @@ static struct omap_board_mux board_mux[] __initdata = {
 };
 #endif
 
+static struct usbhs_phy_data phy_data[] __initdata = {
+       {
+               .port = 2,
+               .reset_gpio = 147,
+               .vcc_gpio = -EINVAL,
+       },
+};
+
 static struct platform_device *omap3_touchbook_devices[] __initdata = {
        &leds_gpio,
        &keys_gpio,
 };
 
 static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
-
        .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
        .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
-       .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
-       .phy_reset  = true,
-       .reset_gpio_port[0]  = -EINVAL,
-       .reset_gpio_port[1]  = 147,
-       .reset_gpio_port[2]  = -EINVAL
 };
 
 static void omap3_touchbook_poweroff(void)
@@ -368,6 +369,8 @@ static void __init omap3_touchbook_init(void)
        omap_ads7846_init(4, OMAP3_TS_GPIO, 310, &ads7846_pdata);
        usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
        usb_musb_init(NULL);
+
+       usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
        usbhs_init(&usbhs_bdata);
        board_nand_init(omap3touchbook_nand_partitions,
                        ARRAY_SIZE(omap3touchbook_nand_partitions), NAND_CS,
index b02c2f00609b275ad50ae9cb91e9c15ad0ca6975..a71ad345f20d8129788244dcfebd0864e396bd88 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/ti_wilink_st.h>
 #include <linux/usb/musb.h>
 #include <linux/usb/phy.h>
+#include <linux/usb/nop-usb-xceiv.h>
 #include <linux/wl12xx.h>
 #include <linux/irqchip/arm-gic.h>
 #include <linux/platform_data/omap-abe-twl6040.h>
@@ -132,6 +133,22 @@ static struct platform_device btwilink_device = {
        .id     = -1,
 };
 
+/* PHY device on HS USB Port 1 i.e. nop_usb_xceiv.1 */
+static struct nop_usb_xceiv_platform_data hsusb1_phy_data = {
+       /* FREF_CLK3 provides the 19.2 MHz reference clock to the PHY */
+       .clk_rate = 19200000,
+};
+
+static struct usbhs_phy_data phy_data[] __initdata = {
+       {
+               .port = 1,
+               .reset_gpio = GPIO_HUB_NRESET,
+               .vcc_gpio = GPIO_HUB_POWER,
+               .vcc_polarity = 1,
+               .platform_data = &hsusb1_phy_data,
+       },
+};
+
 static struct platform_device *panda_devices[] __initdata = {
        &leds_gpio,
        &wl1271_device,
@@ -142,49 +159,19 @@ static struct platform_device *panda_devices[] __initdata = {
 
 static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
        .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
-       .port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
-       .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-       .phy_reset  = false,
-       .reset_gpio_port[0]  = -EINVAL,
-       .reset_gpio_port[1]  = -EINVAL,
-       .reset_gpio_port[2]  = -EINVAL
-};
-
-static struct gpio panda_ehci_gpios[] __initdata = {
-       { GPIO_HUB_POWER,       GPIOF_OUT_INIT_LOW,  "hub_power"  },
-       { GPIO_HUB_NRESET,      GPIOF_OUT_INIT_LOW,  "hub_nreset" },
 };
 
 static void __init omap4_ehci_init(void)
 {
        int ret;
-       struct clk *phy_ref_clk;
 
        /* FREF_CLK3 provides the 19.2 MHz reference clock to the PHY */
-       phy_ref_clk = clk_get(NULL, "auxclk3_ck");
-       if (IS_ERR(phy_ref_clk)) {
-               pr_err("Cannot request auxclk3\n");
-               return;
-       }
-       clk_set_rate(phy_ref_clk, 19200000);
-       clk_prepare_enable(phy_ref_clk);
-
-       /* disable the power to the usb hub prior to init and reset phy+hub */
-       ret = gpio_request_array(panda_ehci_gpios,
-                                ARRAY_SIZE(panda_ehci_gpios));
-       if (ret) {
-               pr_err("Unable to initialize EHCI power/reset\n");
-               return;
-       }
-
-       gpio_export(GPIO_HUB_POWER, 0);
-       gpio_export(GPIO_HUB_NRESET, 0);
-       gpio_set_value(GPIO_HUB_NRESET, 1);
+       ret = clk_add_alias("main_clk", "nop_usb_xceiv.1", "auxclk3_ck", NULL);
+       if (ret)
+               pr_err("Failed to add main_clk alias to auxclk3_ck\n");
 
+       usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
        usbhs_init(&usbhs_bdata);
-
-       /* enable power to hub */
-       gpio_set_value(GPIO_HUB_POWER, 1);
 }
 
 static struct omap_musb_board_data musb_board_data = {
index 86bab51154eefe66ba1808f38fa85cef0ceb41e6..ab79a4422bcc6301e63a2d10b5b835cb85ad306f 100644 (file)
@@ -458,14 +458,16 @@ static int __init overo_spi_init(void)
        return 0;
 }
 
+static struct usbhs_phy_data phy_data[] __initdata = {
+       {
+               .port = 2,
+               .reset_gpio = OVERO_GPIO_USBH_NRESET,
+               .vcc_gpio = -EINVAL,
+       },
+};
+
 static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
-       .port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
        .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
-       .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-       .phy_reset  = true,
-       .reset_gpio_port[0]  = -EINVAL,
-       .reset_gpio_port[1]  = OVERO_GPIO_USBH_NRESET,
-       .reset_gpio_port[2]  = -EINVAL
 };
 
 #ifdef CONFIG_OMAP_MUX
@@ -502,6 +504,8 @@ static void __init overo_init(void)
                        ARRAY_SIZE(overo_nand_partitions), NAND_CS, 0, NULL);
        usb_bind_phy("musb-hdrc.0.auto", 0, "twl4030_usb");
        usb_musb_init(NULL);
+
+       usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
        usbhs_init(&usbhs_bdata);
        overo_spi_init();
        overo_init_smsc911x();
index 5e4d4c9fe61a4fd6c036e4447bb67d268ff82c8a..1a3dd865d8ebac8aca30ce309f2893eee5bb6462 100644 (file)
@@ -92,14 +92,16 @@ static struct mtd_partition zoom_nand_partitions[] = {
        },
 };
 
+static struct usbhs_phy_data phy_data[] __initdata = {
+       {
+               .port = 2,
+               .reset_gpio = ZOOM3_EHCI_RESET_GPIO,
+               .vcc_gpio = -EINVAL,
+       },
+};
+
 static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
-       .port_mode[0]           = OMAP_USBHS_PORT_MODE_UNUSED,
        .port_mode[1]           = OMAP_EHCI_PORT_MODE_PHY,
-       .port_mode[2]           = OMAP_USBHS_PORT_MODE_UNUSED,
-       .phy_reset              = true,
-       .reset_gpio_port[0]     = -EINVAL,
-       .reset_gpio_port[1]     = ZOOM3_EHCI_RESET_GPIO,
-       .reset_gpio_port[2]     = -EINVAL,
 };
 
 static void __init omap_zoom_init(void)
@@ -109,6 +111,8 @@ static void __init omap_zoom_init(void)
        } else if (machine_is_omap_zoom3()) {
                omap3_mux_init(board_mux, OMAP_PACKAGE_CBP);
                omap_mux_init_gpio(ZOOM3_EHCI_RESET_GPIO, OMAP_PIN_OUTPUT);
+
+               usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
                usbhs_init(&usbhs_bdata);
        }
 
index 476b82066cb6b27368e18155998ad85cff910240..7f091c85384e241f76bcd9ba585382cf29ba0824 100644 (file)
@@ -958,6 +958,14 @@ int __init am33xx_clk_init(void)
 
        clk_set_parent(&timer3_fck, &sys_clkin_ck);
        clk_set_parent(&timer6_fck, &sys_clkin_ck);
+       /*
+        * The On-Chip 32K RC Osc clock is not an accurate clock-source as per
+        * the design/spec, so as a result, for example, timer which supposed
+        * to get expired @60Sec, but will expire somewhere ~@40Sec, which is
+        * not expected by any use-case, so change WDT1 clock source to PRCM
+        * 32KHz clock.
+        */
+       clk_set_parent(&wdt1_fck, &clkdiv32k_ick);
 
        return 0;
 }
index 3aed4b0b95632dbdf244b7e6a8d6349840872d1e..3a0296cfcace879a322a6c414b4b9de9bb0cce62 100644 (file)
@@ -307,10 +307,10 @@ static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 freqsel)
        _omap3_noncore_dpll_bypass(clk);
 
        /*
-        * Set jitter correction. No jitter correction for OMAP4 and 3630
-        * since freqsel field is no longer present
+        * Set jitter correction. Jitter correction applicable for OMAP343X
+        * only since freqsel field is no longer present on other devices.
         */
-       if (!soc_is_am33xx() && !cpu_is_omap44xx() && !cpu_is_omap3630()) {
+       if (cpu_is_omap343x()) {
                v = __raw_readl(dd->control_reg);
                v &= ~dd->freqsel_mask;
                v |= freqsel << __ffs(dd->freqsel_mask);
@@ -480,29 +480,30 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
        if (!dd)
                return -EINVAL;
 
-       __clk_prepare(dd->clk_bypass);
-       clk_enable(dd->clk_bypass);
-       __clk_prepare(dd->clk_ref);
-       clk_enable(dd->clk_ref);
-
        if (__clk_get_rate(dd->clk_bypass) == rate &&
            (dd->modes & (1 << DPLL_LOW_POWER_BYPASS))) {
                pr_debug("%s: %s: set rate: entering bypass.\n",
                         __func__, __clk_get_name(hw->clk));
 
+               __clk_prepare(dd->clk_bypass);
+               clk_enable(dd->clk_bypass);
                ret = _omap3_noncore_dpll_bypass(clk);
                if (!ret)
                        new_parent = dd->clk_bypass;
+               clk_disable(dd->clk_bypass);
+               __clk_unprepare(dd->clk_bypass);
        } else {
+               __clk_prepare(dd->clk_ref);
+               clk_enable(dd->clk_ref);
+
                if (dd->last_rounded_rate != rate)
                        rate = __clk_round_rate(hw->clk, rate);
 
                if (dd->last_rounded_rate == 0)
                        return -EINVAL;
 
-               /* No freqsel on AM335x, OMAP4 and OMAP3630 */
-               if (!soc_is_am33xx() && !cpu_is_omap44xx() &&
-                   !cpu_is_omap3630()) {
+               /* Freqsel is available only on OMAP343X devices */
+               if (cpu_is_omap343x()) {
                        freqsel = _omap3_dpll_compute_freqsel(clk,
                                                dd->last_rounded_n);
                        WARN_ON(!freqsel);
@@ -514,6 +515,8 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
                ret = omap3_noncore_dpll_program(clk, freqsel);
                if (!ret)
                        new_parent = dd->clk_ref;
+               clk_disable(dd->clk_ref);
+               __clk_unprepare(dd->clk_ref);
        }
        /*
        * FIXME - this is all wrong.  common code handles reparenting and
@@ -525,11 +528,6 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
        if (!ret)
                __clk_reparent(hw->clk, new_parent);
 
-       clk_disable(dd->clk_ref);
-       __clk_unprepare(dd->clk_ref);
-       clk_disable(dd->clk_bypass);
-       __clk_unprepare(dd->clk_bypass);
-
        return 0;
 }
 
index b155500e84a8e12dc5eeb6b6d3844d7b2fe6b122..b8208b4b1bd99882b178a095f02b1c64e4f3fa87 100644 (file)
@@ -26,7 +26,7 @@
 #include "control.h"
 #include "cm2xxx_3xxx.h"
 #include "prm2xxx_3xxx.h"
-#ifdef CONFIG_BRIDGE_DVFS
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
 #include "omap-pm.h"
 #endif
 
@@ -35,7 +35,7 @@
 static struct platform_device *omap_dsp_pdev;
 
 static struct omap_dsp_platform_data omap_dsp_pdata __initdata = {
-#ifdef CONFIG_BRIDGE_DVFS
+#ifdef CONFIG_TIDSPBRIDGE_DVFS
        .dsp_set_min_opp = omap_pm_dsp_set_min_opp,
        .dsp_get_opp = omap_pm_dsp_get_opp,
        .cpu_set_freq = omap_pm_cpu_set_freq,
index 8a68f1ec66b9ac07dd9e20cf7c6239e794972407..ff0bc9e51aa777ad42a9d7661fc575624c21960c 100644 (file)
@@ -529,22 +529,28 @@ void __init omap5xxx_check_revision(void)
        case 0xb942:
                switch (rev) {
                case 0:
-               default:
                        omap_revision = OMAP5430_REV_ES1_0;
+                       break;
+               case 1:
+               default:
+                       omap_revision = OMAP5430_REV_ES2_0;
                }
                break;
 
        case 0xb998:
                switch (rev) {
                case 0:
-               default:
                        omap_revision = OMAP5432_REV_ES1_0;
+                       break;
+               case 1:
+               default:
+                       omap_revision = OMAP5432_REV_ES2_0;
                }
                break;
 
        default:
                /* Unknown default to latest silicon rev as default*/
-               omap_revision = OMAP5430_REV_ES1_0;
+               omap_revision = OMAP5430_REV_ES2_0;
        }
 
        pr_info("OMAP%04x ES%d.0\n",
index 2c3fdd65387b56c542d6d97cbc093fcf69a51b9a..2bef5a7e6af806a05495d4e7d40de312bd6e160a 100644 (file)
@@ -271,6 +271,14 @@ static struct map_desc omap54xx_io_desc[] __initdata = {
                .length         = L4_PER_54XX_SIZE,
                .type           = MT_DEVICE,
        },
+#ifdef CONFIG_OMAP4_ERRATA_I688
+       {
+               .virtual        = OMAP4_SRAM_VA,
+               .pfn            = __phys_to_pfn(OMAP4_SRAM_PA),
+               .length         = PAGE_SIZE,
+               .type           = MT_MEMORY_SO,
+       },
+#endif
 };
 #endif
 
@@ -323,6 +331,7 @@ void __init omap4_map_io(void)
 void __init omap5_map_io(void)
 {
        iotable_init(omap54xx_io_desc, ARRAY_SIZE(omap54xx_io_desc));
+       omap_barriers_init();
 }
 #endif
 /*
index 708bb115a27ff8e54f0e760eaebaf2c10c9f4af1..2aeb928efdfdbcd1f291497f436acf6fdfea1867 100644 (file)
@@ -240,15 +240,21 @@ void __iomem *omap4_get_sar_ram_base(void)
  */
 static int __init omap4_sar_ram_init(void)
 {
+       unsigned long sar_base;
+
        /*
         * To avoid code running on other OMAPs in
         * multi-omap builds
         */
-       if (!cpu_is_omap44xx())
+       if (cpu_is_omap44xx())
+               sar_base = OMAP44XX_SAR_RAM_BASE;
+       else if (soc_is_omap54xx())
+               sar_base = OMAP54XX_SAR_RAM_BASE;
+       else
                return -ENOMEM;
 
        /* Static mapping, never released */
-       sar_ram_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_16K);
+       sar_ram_base = ioremap(sar_base, SZ_16K);
        if (WARN_ON(!sar_ram_base))
                return -ENOMEM;
 
index e170fe803b046b2e0ff624e1b502960e902ac2a7..937417523b8eca71235eb4d5c22f479a1126af59 100644 (file)
 #define SAR_BACKUP_STATUS_WAKEUPGEN            0x10
 
 /* WakeUpGen save restore offset from OMAP54XX_SAR_RAM_BASE */
-#define OMAP5_WAKEUPGENENB_OFFSET_CPU0         (SAR_BANK3_OFFSET + 0x8d4)
-#define OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU0  (SAR_BANK3_OFFSET + 0x8e8)
-#define OMAP5_WAKEUPGENENB_OFFSET_CPU1         (SAR_BANK3_OFFSET + 0x8fc)
-#define OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU1  (SAR_BANK3_OFFSET + 0x910)
-#define OMAP5_AUXCOREBOOT0_OFFSET              (SAR_BANK3_OFFSET + 0x924)
-#define OMAP5_AUXCOREBOOT1_OFFSET              (SAR_BANK3_OFFSET + 0x928)
-#define OMAP5_AMBA_IF_MODE_OFFSET              (SAR_BANK3_OFFSET + 0x92c)
+#define OMAP5_WAKEUPGENENB_OFFSET_CPU0         (SAR_BANK3_OFFSET + 0x9dc)
+#define OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU0  (SAR_BANK3_OFFSET + 0x9f0)
+#define OMAP5_WAKEUPGENENB_OFFSET_CPU1         (SAR_BANK3_OFFSET + 0xa04)
+#define OMAP5_WAKEUPGENENB_SECURE_OFFSET_CPU1  (SAR_BANK3_OFFSET + 0xa18)
+#define OMAP5_AUXCOREBOOT0_OFFSET              (SAR_BANK3_OFFSET + 0xa2c)
+#define OMAP5_AUXCOREBOOT1_OFFSET              (SAR_BANK3_OFFSET + 0x930)
+#define OMAP5_AMBA_IF_MODE_OFFSET              (SAR_BANK3_OFFSET + 0xa34)
 #define OMAP5_SAR_BACKUP_STATUS_OFFSET         (SAR_BANK3_OFFSET + 0x800)
 
 #endif
index a2582bb3cab3d4b7dc5293e61bf757e0dba3a2b0..a086ba15868b2c4a32ea24de917e5cbd6d734675 100644 (file)
@@ -28,5 +28,6 @@
 #define OMAP54XX_PRCM_MPU_BASE         0x48243000
 #define OMAP54XX_SCM_BASE              0x4a002000
 #define OMAP54XX_CTRL_BASE             0x4a002800
+#define OMAP54XX_SAR_RAM_BASE          0x4ae26000
 
 #endif /* __ASM_SOC_OMAP555554XX_H */
index c2c798c08c2b9f63a55bc11be5f654f80006431c..63b774fb8089b00e632e57aac55b12d6a575dfbb 100644 (file)
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/bootmem.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
 
 #include <asm/system_misc.h>
 
@@ -610,8 +612,6 @@ static int _enable_wakeup(struct omap_hwmod *oh, u32 *v)
 
        /* XXX test pwrdm_get_wken for this hwmod's subsystem */
 
-       oh->_int_flags |= _HWMOD_WAKEUP_ENABLED;
-
        return 0;
 }
 
@@ -645,8 +645,6 @@ static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)
 
        /* XXX test pwrdm_get_wken for this hwmod's subsystem */
 
-       oh->_int_flags &= ~_HWMOD_WAKEUP_ENABLED;
-
        return 0;
 }
 
@@ -2349,6 +2347,34 @@ static int _shutdown(struct omap_hwmod *oh)
        return 0;
 }
 
+/**
+ * of_dev_hwmod_lookup - look up needed hwmod from dt blob
+ * @np: struct device_node *
+ * @oh: struct omap_hwmod *
+ *
+ * Parse the dt blob and find out needed hwmod. Recursive function is
+ * implemented to take care hierarchical dt blob parsing.
+ * Return: The device node on success or NULL on failure.
+ */
+static struct device_node *of_dev_hwmod_lookup(struct device_node *np,
+                                               struct omap_hwmod *oh)
+{
+       struct device_node *np0 = NULL, *np1 = NULL;
+       const char *p;
+
+       for_each_child_of_node(np, np0) {
+               if (of_find_property(np0, "ti,hwmods", NULL)) {
+                       p = of_get_property(np0, "ti,hwmods", NULL);
+                       if (!strcmp(p, oh->name))
+                               return np0;
+                       np1 = of_dev_hwmod_lookup(np0, oh);
+                       if (np1)
+                               return np1;
+               }
+       }
+       return NULL;
+}
+
 /**
  * _init_mpu_rt_base - populate the virtual address for a hwmod
  * @oh: struct omap_hwmod * to locate the virtual address
@@ -2361,7 +2387,8 @@ static int _shutdown(struct omap_hwmod *oh)
 static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
 {
        struct omap_hwmod_addr_space *mem;
-       void __iomem *va_start;
+       void __iomem *va_start = NULL;
+       struct device_node *np;
 
        if (!oh)
                return;
@@ -2375,10 +2402,18 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data)
        if (!mem) {
                pr_debug("omap_hwmod: %s: no MPU register target found\n",
                         oh->name);
-               return;
+
+               /* Extract the IO space from device tree blob */
+               if (!of_have_populated_dt())
+                       return;
+
+               np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh);
+               if (np)
+                       va_start = of_iomap(np, 0);
+       } else {
+               va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
        }
 
-       va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start);
        if (!va_start) {
                pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name);
                return;
@@ -2410,7 +2445,8 @@ static int __init _init(struct omap_hwmod *oh, void *data)
        if (oh->_state != _HWMOD_STATE_REGISTERED)
                return 0;
 
-       _init_mpu_rt_base(oh, NULL);
+       if (oh->class->sysc)
+               _init_mpu_rt_base(oh, NULL);
 
        r = _init_clocks(oh, NULL);
        if (IS_ERR_VALUE(r)) {
index d43d9b608edab3c1b7e69c96e711ec1eefc2d7c8..28f4dea0512e85f50eb29deb69b4c613f420540f 100644 (file)
@@ -477,15 +477,13 @@ struct omap_hwmod_omap4_prcm {
  * These are for internal use only and are managed by the omap_hwmod code.
  *
  * _HWMOD_NO_MPU_PORT: no path exists for the MPU to write to this module
- * _HWMOD_WAKEUP_ENABLED: set when the omap_hwmod code has enabled ENAWAKEUP
  * _HWMOD_SYSCONFIG_LOADED: set when the OCP_SYSCONFIG value has been cached
  * _HWMOD_SKIP_ENABLE: set if hwmod enabled during init (HWMOD_INIT_NO_IDLE) -
  *     causes the first call to _enable() to only update the pinmux
  */
 #define _HWMOD_NO_MPU_PORT                     (1 << 0)
-#define _HWMOD_WAKEUP_ENABLED                  (1 << 1)
-#define _HWMOD_SYSCONFIG_LOADED                        (1 << 2)
-#define _HWMOD_SKIP_ENABLE                     (1 << 3)
+#define _HWMOD_SYSCONFIG_LOADED                        (1 << 1)
+#define _HWMOD_SKIP_ENABLE                     (1 << 2)
 
 /*
  * omap_hwmod._state definitions
index 26eee4a556ad13a82f27a09d1820eb48f6d3ebac..31bea1ce3de10a7049d49b917b616c1f52701401 100644 (file)
@@ -28,6 +28,7 @@
 #include "prm-regbits-33xx.h"
 #include "i2c.h"
 #include "mmc.h"
+#include "wd_timer.h"
 
 /*
  * IP blocks
@@ -2087,8 +2088,21 @@ static struct omap_hwmod am33xx_uart6_hwmod = {
 };
 
 /* 'wd_timer' class */
+static struct omap_hwmod_class_sysconfig wdt_sysc = {
+       .rev_offs       = 0x0,
+       .sysc_offs      = 0x10,
+       .syss_offs      = 0x14,
+       .sysc_flags     = (SYSC_HAS_EMUFREE | SYSC_HAS_SIDLEMODE |
+                       SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+                       SIDLE_SMART_WKUP),
+       .sysc_fields    = &omap_hwmod_sysc_type1,
+};
+
 static struct omap_hwmod_class am33xx_wd_timer_hwmod_class = {
        .name           = "wd_timer",
+       .sysc           = &wdt_sysc,
+       .pre_shutdown   = &omap2_wd_timer_disable,
 };
 
 /*
@@ -2099,6 +2113,7 @@ static struct omap_hwmod am33xx_wd_timer1_hwmod = {
        .name           = "wd_timer2",
        .class          = &am33xx_wd_timer_hwmod_class,
        .clkdm_name     = "l4_wkup_clkdm",
+       .flags          = HWMOD_SWSUP_SIDLE,
        .main_clk       = "wdt1_fck",
        .prcm           = {
                .omap4  = {
index 9debf822687c7a0a11724ed4ea218237d2cd1ce6..9ace8eae7ee8b1444aa9b0634764d2ad93871ecb 100644 (file)
@@ -11,6 +11,8 @@
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  */
+#include <linux/of.h>
+
 #include <asm/pmu.h>
 
 #include "soc.h"
@@ -63,6 +65,15 @@ static int __init omap_init_pmu(void)
        unsigned oh_num;
        char **oh_names;
 
+       /* XXX Remove this check when the CTI driver is available */
+       if (cpu_is_omap443x()) {
+               pr_info("ARM PMU: not yet supported on OMAP4430 due to missing CTI driver\n");
+               return 0;
+       }
+
+       if (of_have_populated_dt())
+               return 0;
+
        /*
         * To create an ARM-PMU device the following HWMODs
         * are required for the various OMAP2+ devices.
@@ -75,9 +86,6 @@ static int __init omap_init_pmu(void)
        if (cpu_is_omap443x()) {
                oh_num = ARRAY_SIZE(omap4430_pmu_oh_names);
                oh_names = omap4430_pmu_oh_names;
-               /* XXX Remove the next two lines when CTI driver available */
-               pr_info("ARM PMU: not yet supported on OMAP4430 due to missing CTI driver\n");
-               return 0;
        } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
                oh_num = ARRAY_SIZE(omap3_pmu_oh_names);
                oh_names = omap3_pmu_oh_names;
index 8e61d80bf6b3442e658747f7a42cb4f822f973ac..89cad4a605dde7251fa0903bfb58f41e55523b13 100644 (file)
@@ -52,7 +52,6 @@ enum {
 #define ALREADYACTIVE_SWITCH           0
 #define FORCEWAKEUP_SWITCH             1
 #define LOWPOWERSTATE_SWITCH           2
-#define ERROR_SWITCH                   3
 
 /* pwrdm_list contains all registered struct powerdomains */
 static LIST_HEAD(pwrdm_list);
@@ -233,10 +232,7 @@ static u8 _pwrdm_save_clkdm_state_and_activate(struct powerdomain *pwrdm,
 {
        u8 sleep_switch;
 
-       if (curr_pwrst < 0) {
-               WARN_ON(1);
-               sleep_switch = ERROR_SWITCH;
-       } else if (curr_pwrst < PWRDM_POWER_ON) {
+       if (curr_pwrst < PWRDM_POWER_ON) {
                if (curr_pwrst > pwrst &&
                    pwrdm->flags & PWRDM_HAS_LOWPOWERSTATECHANGE &&
                    arch_pwrdm->pwrdm_set_lowpwrstchange) {
@@ -1091,7 +1087,8 @@ int pwrdm_post_transition(struct powerdomain *pwrdm)
  */
 int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 pwrst)
 {
-       u8 curr_pwrst, next_pwrst, sleep_switch;
+       u8 next_pwrst, sleep_switch;
+       int curr_pwrst;
        int ret = 0;
        bool hwsup = false;
 
@@ -1107,16 +1104,17 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u8 pwrst)
        pwrdm_lock(pwrdm);
 
        curr_pwrst = pwrdm_read_pwrst(pwrdm);
+       if (curr_pwrst < 0) {
+               ret = -EINVAL;
+               goto osps_out;
+       }
+
        next_pwrst = pwrdm_read_next_pwrst(pwrdm);
        if (curr_pwrst == pwrst && next_pwrst == pwrst)
                goto osps_out;
 
        sleep_switch = _pwrdm_save_clkdm_state_and_activate(pwrdm, curr_pwrst,
                                                            pwrst, &hwsup);
-       if (sleep_switch == ERROR_SWITCH) {
-               ret = -EINVAL;
-               goto osps_out;
-       }
 
        ret = pwrdm_set_next_pwrst(pwrdm, pwrst);
        if (ret)
index d35f98aabf7a206c1b781511dd1ac3059eca9eeb..415c7e0c9393ad3e85f45591a3fbf68a93a1df12 100644 (file)
@@ -81,13 +81,13 @@ static struct prm_reset_src_map omap44xx_prm_reset_src_map[] = {
 /* Read a register in a CM/PRM instance in the PRM module */
 u32 omap4_prm_read_inst_reg(s16 inst, u16 reg)
 {
-       return __raw_readl(OMAP44XX_PRM_REGADDR(inst, reg));
+       return __raw_readl(prm_base + inst + reg);
 }
 
 /* Write into a register in a CM/PRM instance in the PRM module */
 void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg)
 {
-       __raw_writel(val, OMAP44XX_PRM_REGADDR(inst, reg));
+       __raw_writel(val, prm_base + inst + reg);
 }
 
 /* Read-modify-write a register in a PRM module. Caller must lock */
@@ -650,7 +650,7 @@ static struct prm_ll_data omap44xx_prm_ll_data = {
 
 int __init omap44xx_prm_init(void)
 {
-       if (!cpu_is_omap44xx())
+       if (!cpu_is_omap44xx() && !soc_is_omap54xx())
                return 0;
 
        return prm_register(&omap44xx_prm_ll_data);
index c62116bbc760d3a1245f722ecc3b19be5ba09955..18fdeeb3a44a494096ae7b246a02a9604a4fdb89 100644 (file)
@@ -413,7 +413,9 @@ IS_OMAP_TYPE(3430, 0x3430)
 
 #define OMAP54XX_CLASS         0x54000054
 #define OMAP5430_REV_ES1_0     (OMAP54XX_CLASS | (0x30 << 16) | (0x10 << 8))
+#define OMAP5430_REV_ES2_0     (OMAP54XX_CLASS | (0x30 << 16) | (0x20 << 8))
 #define OMAP5432_REV_ES1_0     (OMAP54XX_CLASS | (0x32 << 16) | (0x10 << 8))
+#define OMAP5432_REV_ES2_0     (OMAP54XX_CLASS | (0x32 << 16) | (0x20 << 8))
 
 void omap2xxx_check_revision(void);
 void omap3xxx_check_revision(void);
index 2bdd4cf17a8fd0e80b6c2c74feb66fcc9018ecca..58d86d7abada1e083b0c8228715ef595ff3d8852 100644 (file)
@@ -62,6 +62,7 @@
 #define OMAP2_MPU_SOURCE       "sys_ck"
 #define OMAP3_MPU_SOURCE       OMAP2_MPU_SOURCE
 #define OMAP4_MPU_SOURCE       "sys_clkin_ck"
+#define OMAP5_MPU_SOURCE       "sys_clkin"
 #define OMAP2_32K_SOURCE       "func_32k_ck"
 #define OMAP3_32K_SOURCE       "omap_32k_fck"
 #define OMAP4_32K_SOURCE       "sys_32k_ck"
@@ -143,7 +144,12 @@ static struct property device_disabled = {
 };
 
 static struct of_device_id omap_timer_match[] __initdata = {
-       { .compatible = "ti,omap2-timer", },
+       { .compatible = "ti,omap2420-timer", },
+       { .compatible = "ti,omap3430-timer", },
+       { .compatible = "ti,omap4430-timer", },
+       { .compatible = "ti,omap5430-timer", },
+       { .compatible = "ti,am335x-timer", },
+       { .compatible = "ti,am335x-timer-1ms", },
        { }
 };
 
@@ -487,7 +493,7 @@ static void __init realtime_counter_init(void)
                pr_err("%s: ioremap failed\n", __func__);
                return;
        }
-       sys_clk = clk_get(NULL, "sys_clkin_ck");
+       sys_clk = clk_get(NULL, OMAP5_MPU_SOURCE);
        if (IS_ERR(sys_clk)) {
                pr_err("%s: failed to get system clock handle\n", __func__);
                iounmap(base);
@@ -597,7 +603,7 @@ void __init omap4_local_timer_init(void)
                int err;
 
                if (of_have_populated_dt()) {
-                       twd_local_timer_of_register();
+                       clocksource_of_init();
                        return;
                }
 
@@ -616,7 +622,7 @@ void __init omap4_local_timer_init(void)
 
 #ifdef CONFIG_SOC_OMAP5
 OMAP_SYS_32K_TIMER_INIT(5, 1, OMAP4_32K_SOURCE, "ti,timer-alwon",
-                       2, OMAP4_MPU_SOURCE);
+                       2, OMAP5_MPU_SOURCE);
 void __init omap5_realtime_timer_init(void)
 {
        int err;
index 5706bdccf45ee34b643141337b38222fbaf5f63a..aa27d7f5cbb7a760596337903fd0e61ac22e647b 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/dma-mapping.h>
-
-#include <asm/io.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/string.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/usb/phy.h>
 
 #include "soc.h"
 #include "omap_device.h"
@@ -526,3 +530,155 @@ void __init usbhs_init(struct usbhs_omap_platform_data *pdata)
 }
 
 #endif
+
+/* Template for PHY regulators */
+static struct fixed_voltage_config hsusb_reg_config = {
+       /* .supply_name filled later */
+       .microvolts = 3300000,
+       .gpio = -1,             /* updated later */
+       .startup_delay = 70000, /* 70msec */
+       .enable_high = 1,       /* updated later */
+       .enabled_at_boot = 0,   /* keep in RESET */
+       /* .init_data filled later */
+};
+
+static const char *nop_name = "nop_usb_xceiv"; /* NOP PHY driver */
+static const char *reg_name = "reg-fixed-voltage"; /* Regulator driver */
+
+/**
+ * usbhs_add_regulator - Add a gpio based fixed voltage regulator device
+ * @name: name for the regulator
+ * @dev_id: device id of the device this regulator supplies power to
+ * @dev_supply: supply name that the device expects
+ * @gpio: GPIO number
+ * @polarity: 1 - Active high, 0 - Active low
+ */
+static int usbhs_add_regulator(char *name, char *dev_id, char *dev_supply,
+                                               int gpio, int polarity)
+{
+       struct regulator_consumer_supply *supplies;
+       struct regulator_init_data *reg_data;
+       struct fixed_voltage_config *config;
+       struct platform_device *pdev;
+       int ret;
+
+       supplies = kzalloc(sizeof(*supplies), GFP_KERNEL);
+       if (!supplies)
+               return -ENOMEM;
+
+       supplies->supply = dev_supply;
+       supplies->dev_name = dev_id;
+
+       reg_data = kzalloc(sizeof(*reg_data), GFP_KERNEL);
+       if (!reg_data)
+               return -ENOMEM;
+
+       reg_data->constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;
+       reg_data->consumer_supplies = supplies;
+       reg_data->num_consumer_supplies = 1;
+
+       config = kmemdup(&hsusb_reg_config, sizeof(hsusb_reg_config),
+                       GFP_KERNEL);
+       if (!config)
+               return -ENOMEM;
+
+       config->supply_name = name;
+       config->gpio = gpio;
+       config->enable_high = polarity;
+       config->init_data = reg_data;
+
+       /* create a regulator device */
+       pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
+       if (!pdev)
+               return -ENOMEM;
+
+       pdev->id = PLATFORM_DEVID_AUTO;
+       pdev->name = reg_name;
+       pdev->dev.platform_data = config;
+
+       ret = platform_device_register(pdev);
+       if (ret)
+               pr_err("%s: Failed registering regulator %s for %s\n",
+                               __func__, name, dev_id);
+
+       return ret;
+}
+
+int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys)
+{
+       char *rail_name;
+       int i, len;
+       struct platform_device *pdev;
+       char *phy_id;
+
+       /* the phy_id will be something like "nop_usb_xceiv.1" */
+       len = strlen(nop_name) + 3; /* 3 -> ".1" and NULL terminator */
+
+       for (i = 0; i < num_phys; i++) {
+
+               if (!phy->port) {
+                       pr_err("%s: Invalid port 0. Must start from 1\n",
+                                               __func__);
+                       continue;
+               }
+
+               /* do we need a NOP PHY device ? */
+               if (!gpio_is_valid(phy->reset_gpio) &&
+                       !gpio_is_valid(phy->vcc_gpio))
+                       continue;
+
+               /* create a NOP PHY device */
+               pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
+               if (!pdev)
+                       return -ENOMEM;
+
+               pdev->id = phy->port;
+               pdev->name = nop_name;
+               pdev->dev.platform_data = phy->platform_data;
+
+               phy_id = kmalloc(len, GFP_KERNEL);
+               if (!phy_id)
+                       return -ENOMEM;
+
+               scnprintf(phy_id, len, "nop_usb_xceiv.%d\n",
+                                       pdev->id);
+
+               if (platform_device_register(pdev)) {
+                       pr_err("%s: Failed to register device %s\n",
+                               __func__,  phy_id);
+                       continue;
+               }
+
+               usb_bind_phy("ehci-omap.0", phy->port - 1, phy_id);
+
+               /* Do we need RESET regulator ? */
+               if (gpio_is_valid(phy->reset_gpio)) {
+
+                       rail_name = kmalloc(13, GFP_KERNEL);
+                       if (!rail_name)
+                               return -ENOMEM;
+
+                       scnprintf(rail_name, 13, "hsusb%d_reset", phy->port);
+
+                       usbhs_add_regulator(rail_name, phy_id, "reset",
+                                               phy->reset_gpio, 1);
+               }
+
+               /* Do we need VCC regulator ? */
+               if (gpio_is_valid(phy->vcc_gpio)) {
+
+                       rail_name = kmalloc(13, GFP_KERNEL);
+                       if (!rail_name)
+                               return -ENOMEM;
+
+                       scnprintf(rail_name, 13, "hsusb%d_vcc", phy->port);
+
+                       usbhs_add_regulator(rail_name, phy_id, "vcc",
+                                       phy->vcc_gpio, phy->vcc_polarity);
+               }
+
+               phy++;
+       }
+
+       return 0;
+}
index 3319f5cf47a3aade4bdf79ba9605e3cdc183ee6f..e7261ebcf7b02ba83c4e4fe672d132636aeb841e 100644 (file)
 #define USBPHY_OTGSESSEND_EN   (1 << 20)
 #define USBPHY_DATA_POLARITY   (1 << 23)
 
+struct usbhs_phy_data {
+       int port;               /* 1 indexed port number */
+       int reset_gpio;
+       int vcc_gpio;
+       bool vcc_polarity;      /* 1 active high, 0 active low */
+       void *platform_data;
+};
+
 extern void usb_musb_init(struct omap_musb_board_data *board_data);
 extern void usbhs_init(struct usbhs_omap_platform_data *pdata);
+extern int usbhs_init_phys(struct usbhs_phy_data *phy, int num_phys);
 
 extern void am35x_musb_reset(void);
 extern void am35x_musb_phy_power(u8 on);
index 37f513d1588ece1db569d02bdeda76980b6a65e1..0c5e4fb61117bc0665224e00649c629baafe54a4 100644 (file)
@@ -30,6 +30,7 @@ config CPU_S3C2410
        select S3C2410_CLOCK
        select S3C2410_CPUFREQ if CPU_FREQ_S3C24XX
        select S3C2410_PM if PM
+       select SAMSUNG_HRT
        help
          Support for S3C2410 and S3C2410A family from the S3C24XX line
          of Samsung Mobile CPUs.
@@ -41,6 +42,7 @@ config CPU_S3C2412
        select CPU_LLSERIAL_S3C2440
        select S3C2412_DMA if S3C24XX_DMA
        select S3C2412_PM if PM
+       select SAMSUNG_HRT
        help
          Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
 
@@ -53,6 +55,7 @@ config CPU_S3C2416
        select S3C2443_COMMON
        select S3C2443_DMA if S3C24XX_DMA
        select SAMSUNG_CLKSRC
+       select SAMSUNG_HRT
        help
          Support for the S3C2416 SoC from the S3C24XX line
 
@@ -63,6 +66,7 @@ config CPU_S3C2440
        select S3C2410_CLOCK
        select S3C2410_PM if PM
        select S3C2440_DMA if S3C24XX_DMA
+       select SAMSUNG_HRT
        help
          Support for S3C2440 Samsung Mobile CPU based systems.
 
@@ -72,6 +76,7 @@ config CPU_S3C2442
        select CPU_LLSERIAL_S3C2440
        select S3C2410_CLOCK
        select S3C2410_PM if PM
+       select SAMSUNG_HRT
        help
          Support for S3C2442 Samsung Mobile CPU based systems.
 
@@ -87,6 +92,7 @@ config CPU_S3C2443
        select S3C2443_COMMON
        select S3C2443_DMA if S3C24XX_DMA
        select SAMSUNG_CLKSRC
+       select SAMSUNG_HRT
        help
          Support for the S3C2443 SoC from the S3C24XX line
 
index c0daa9590b4c15635ed90723797881d77338e80b..cb1b791954dea7d9a31eb202af4416353be04737 100644 (file)
@@ -34,8 +34,6 @@
 #include <mach/hardware.h>
 #include <mach/regs-irq.h>
 
-#include <plat/irq.h>
-
 #include "bast.h"
 
 #define irqdbf(x...)
index 641266f3d152011d35530d9194c2c219af977217..34fffdf6fc1dc4b7f699418976e0b3d943c512a6 100644 (file)
@@ -40,7 +40,6 @@
 #include <mach/regs-clock.h>
 #include <mach/regs-gpio.h>
 
-#include <plat/s3c2410.h>
 #include <plat/clock.h>
 #include <plat/cpu.h>
 
index d10b695a9066a760fe98d965383847e52be8f9bd..2cc017da88fe234874863a23920b9c78acb850d1 100644 (file)
@@ -41,7 +41,6 @@
 #include <mach/regs-clock.h>
 #include <mach/regs-gpio.h>
 
-#include <plat/s3c2412.h>
 #include <plat/clock.h>
 #include <plat/cpu.h>
 
index 14a81c2317a417eb14b3fc413678a5541e9b09a5..036056cea57c63bd5a4ddf07f5ec3a5326ed35b6 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/init.h>
 #include <linux/clk.h>
 
-#include <plat/s3c2416.h>
 #include <plat/clock.h>
 #include <plat/clock-clksrc.h>
 #include <plat/cpu.h>
index bdaba59b42dce799b7fca73e98856c539e78a946..0a53051b078721ea6635677e6b36381e98b182c2 100644 (file)
@@ -41,7 +41,6 @@
 
 #include <plat/cpu-freq.h>
 
-#include <plat/s3c2443.h>
 #include <plat/clock.h>
 #include <plat/clock-clksrc.h>
 #include <plat/cpu.h>
index 3b2cf6db36349d23df16392d4bbcf8d73391cead..404444dd3840e0559996ddf0175a7d8ead07838d 100644 (file)
 
 #include <linux/platform_data/mtd-nand-s3c2410.h>
 
-#include <plat/common-smdk.h>
 #include <plat/gpio-cfg.h>
 #include <plat/devs.h>
 #include <plat/pm.h>
 
+#include "common-smdk.h"
+
 /* LED devices */
 
 static struct s3c24xx_led_platdata smdk_pdata_led4 = {
diff --git a/arch/arm/mach-s3c24xx/common-smdk.h b/arch/arm/mach-s3c24xx/common-smdk.h
new file mode 100644 (file)
index 0000000..98f733e
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2006 Simtec Electronics
+ *     Ben Dooks <ben@simtec.co.uk>
+ *
+ * Common code for SMDK2410 and SMDK2440 boards
+ *
+ * http://www.fluff.org/ben/smdk2440/
+ *
+ * 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.
+*/
+
+extern void smdk_machine_init(void);
index 6bcf87f65f9e41c7cb86dfd064495eb3a76820af..d97533d21ac4c34dcf976ef2e43d3047d98cd75c 100644 (file)
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/clock.h>
-#include <plat/s3c2410.h>
-#include <plat/s3c2412.h>
-#include <plat/s3c2416.h>
-#include <plat/s3c244x.h>
-#include <plat/s3c2443.h>
 #include <plat/cpu-freq.h>
 #include <plat/pll.h>
 
+#include "common.h"
+
 /* table of supported CPUs */
 
 static const char name_s3c2410[]  = "S3C2410";
index ed6276fcaa3b10089969189f67340ce1351f1dc9..8a2b4137ddb684951bcc59879c93830627d19d49 100644 (file)
 #ifndef __ARCH_ARM_MACH_S3C24XX_COMMON_H
 #define __ARCH_ARM_MACH_S3C24XX_COMMON_H __FILE__
 
-void s3c2410_restart(char mode, const char *cmd);
-void s3c244x_restart(char mode, const char *cmd);
+struct s3c2410_uartcfg;
+
+#ifdef CONFIG_CPU_S3C2410
+extern  int s3c2410_init(void);
+extern  int s3c2410a_init(void);
+extern void s3c2410_map_io(void);
+extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s3c2410_init_clocks(int xtal);
+extern void s3c2410_restart(char mode, const char *cmd);
+#else
+#define s3c2410_init_clocks NULL
+#define s3c2410_init_uarts NULL
+#define s3c2410_map_io NULL
+#define s3c2410_init NULL
+#define s3c2410a_init NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C2412
+extern  int s3c2412_init(void);
+extern void s3c2412_map_io(void);
+extern void s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s3c2412_init_clocks(int xtal);
+extern  int s3c2412_baseclk_add(void);
+extern void s3c2412_restart(char mode, const char *cmd);
+#else
+#define s3c2412_init_clocks NULL
+#define s3c2412_init_uarts NULL
+#define s3c2412_map_io NULL
+#define s3c2412_init NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C2416
+extern  int s3c2416_init(void);
+extern void s3c2416_map_io(void);
+extern void s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s3c2416_init_clocks(int xtal);
+extern  int s3c2416_baseclk_add(void);
+extern void s3c2416_restart(char mode, const char *cmd);
+extern void s3c2416_init_irq(void);
+
+extern struct syscore_ops s3c2416_irq_syscore_ops;
+#else
+#define s3c2416_init_clocks NULL
+#define s3c2416_init_uarts NULL
+#define s3c2416_map_io NULL
+#define s3c2416_init NULL
+#endif
+
+#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
+extern void s3c244x_map_io(void);
+extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s3c244x_init_clocks(int xtal);
+extern void s3c244x_restart(char mode, const char *cmd);
+#else
+#define s3c244x_init_clocks NULL
+#define s3c244x_init_uarts NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C2440
+extern  int s3c2440_init(void);
+extern void s3c2440_map_io(void);
+#else
+#define s3c2440_init NULL
+#define s3c2440_map_io NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C2442
+extern  int s3c2442_init(void);
+extern void s3c2442_map_io(void);
+#else
+#define s3c2442_init NULL
+#define s3c2442_map_io NULL
+#endif
+
+#ifdef CONFIG_CPU_S3C2443
+extern  int s3c2443_init(void);
+extern void s3c2443_map_io(void);
+extern void s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no);
+extern void s3c2443_init_clocks(int xtal);
+extern  int s3c2443_baseclk_add(void);
+extern void s3c2443_restart(char mode, const char *cmd);
+extern void s3c2443_init_irq(void);
+#else
+#define s3c2443_init_clocks NULL
+#define s3c2443_init_uarts NULL
+#define s3c2443_map_io NULL
+#define s3c2443_init NULL
+#endif
 
 extern struct syscore_ops s3c24xx_irq_syscore_ops;
 
index 25d085adc93cd416e5751ab4a066a33485d6058a..a6c94b820954a55f016cb4e388c9889d97d4fbf8 100644 (file)
@@ -28,7 +28,6 @@
 #include <plat/regs-ac97.h>
 #include <plat/regs-dma.h>
 #include <mach/regs-lcd.h>
-#include <mach/regs-sdi.h>
 #include <plat/regs-iis.h>
 #include <plat/regs-spi.h>
 
index d2408ba372cb966975b9b12d6af1f1ef23fd0a09..c0e8c3f5057ef98ce0bfb1557a5a2f200894380e 100644 (file)
@@ -28,7 +28,6 @@
 #include <plat/regs-ac97.h>
 #include <plat/regs-dma.h>
 #include <mach/regs-lcd.h>
-#include <mach/regs-sdi.h>
 #include <plat/regs-iis.h>
 #include <plat/regs-spi.h>
 
index 0b86e74d104f6823a9eb6a8a3ac05ec7297e05a2..1c08eccd9425c12007a2c0a7db4ba8a9e48b65e6 100644 (file)
@@ -28,7 +28,6 @@
 #include <plat/regs-ac97.h>
 #include <plat/regs-dma.h>
 #include <mach/regs-lcd.h>
-#include <mach/regs-sdi.h>
 #include <plat/regs-iis.h>
 #include <plat/regs-spi.h>
 
index 05536254a3f87023c7d89efc2f05f9cb7cf89842..000e4c69fce9ad3f92b8adc414e1299abbda1cca 100644 (file)
@@ -28,7 +28,6 @@
 #include <plat/regs-ac97.h>
 #include <plat/regs-dma.h>
 #include <mach/regs-lcd.h>
-#include <mach/regs-sdi.h>
 #include <plat/regs-iis.h>
 #include <plat/regs-spi.h>
 
diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-sdi.h b/arch/arm/mach-s3c24xx/include/mach/regs-sdi.h
deleted file mode 100644 (file)
index cbf2d88..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/regs-sdi.h
- *
- * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk>
- *                   http://www.simtec.co.uk/products/SWLINUX/
- *
- * 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.
- *
- * S3C2410 MMC/SDIO register definitions
-*/
-
-#ifndef __ASM_ARM_REGS_SDI
-#define __ASM_ARM_REGS_SDI "regs-sdi.h"
-
-#define S3C2410_SDICON                (0x00)
-#define S3C2410_SDIPRE                (0x04)
-#define S3C2410_SDICMDARG             (0x08)
-#define S3C2410_SDICMDCON             (0x0C)
-#define S3C2410_SDICMDSTAT            (0x10)
-#define S3C2410_SDIRSP0               (0x14)
-#define S3C2410_SDIRSP1               (0x18)
-#define S3C2410_SDIRSP2               (0x1C)
-#define S3C2410_SDIRSP3               (0x20)
-#define S3C2410_SDITIMER              (0x24)
-#define S3C2410_SDIBSIZE              (0x28)
-#define S3C2410_SDIDCON               (0x2C)
-#define S3C2410_SDIDCNT               (0x30)
-#define S3C2410_SDIDSTA               (0x34)
-#define S3C2410_SDIFSTA               (0x38)
-
-#define S3C2410_SDIDATA               (0x3C)
-#define S3C2410_SDIIMSK               (0x40)
-
-#define S3C2440_SDIDATA               (0x40)
-#define S3C2440_SDIIMSK               (0x3C)
-
-#define S3C2440_SDICON_SDRESET        (1<<8)
-#define S3C2440_SDICON_MMCCLOCK       (1<<5)
-#define S3C2410_SDICON_BYTEORDER      (1<<4)
-#define S3C2410_SDICON_SDIOIRQ        (1<<3)
-#define S3C2410_SDICON_RWAITEN        (1<<2)
-#define S3C2410_SDICON_FIFORESET      (1<<1)
-#define S3C2410_SDICON_CLOCKTYPE      (1<<0)
-
-#define S3C2410_SDICMDCON_ABORT       (1<<12)
-#define S3C2410_SDICMDCON_WITHDATA    (1<<11)
-#define S3C2410_SDICMDCON_LONGRSP     (1<<10)
-#define S3C2410_SDICMDCON_WAITRSP     (1<<9)
-#define S3C2410_SDICMDCON_CMDSTART    (1<<8)
-#define S3C2410_SDICMDCON_SENDERHOST  (1<<6)
-#define S3C2410_SDICMDCON_INDEX       (0x3f)
-
-#define S3C2410_SDICMDSTAT_CRCFAIL    (1<<12)
-#define S3C2410_SDICMDSTAT_CMDSENT    (1<<11)
-#define S3C2410_SDICMDSTAT_CMDTIMEOUT (1<<10)
-#define S3C2410_SDICMDSTAT_RSPFIN     (1<<9)
-#define S3C2410_SDICMDSTAT_XFERING    (1<<8)
-#define S3C2410_SDICMDSTAT_INDEX      (0xff)
-
-#define S3C2440_SDIDCON_DS_BYTE       (0<<22)
-#define S3C2440_SDIDCON_DS_HALFWORD   (1<<22)
-#define S3C2440_SDIDCON_DS_WORD       (2<<22)
-#define S3C2410_SDIDCON_IRQPERIOD     (1<<21)
-#define S3C2410_SDIDCON_TXAFTERRESP   (1<<20)
-#define S3C2410_SDIDCON_RXAFTERCMD    (1<<19)
-#define S3C2410_SDIDCON_BUSYAFTERCMD  (1<<18)
-#define S3C2410_SDIDCON_BLOCKMODE     (1<<17)
-#define S3C2410_SDIDCON_WIDEBUS       (1<<16)
-#define S3C2410_SDIDCON_DMAEN         (1<<15)
-#define S3C2410_SDIDCON_STOP          (1<<14)
-#define S3C2440_SDIDCON_DATSTART      (1<<14)
-#define S3C2410_SDIDCON_DATMODE              (3<<12)
-#define S3C2410_SDIDCON_BLKNUM        (0x7ff)
-
-/* constants for S3C2410_SDIDCON_DATMODE */
-#define S3C2410_SDIDCON_XFER_READY    (0<<12)
-#define S3C2410_SDIDCON_XFER_CHKSTART (1<<12)
-#define S3C2410_SDIDCON_XFER_RXSTART  (2<<12)
-#define S3C2410_SDIDCON_XFER_TXSTART  (3<<12)
-
-#define S3C2410_SDIDCON_BLKNUM_MASK   (0xFFF)
-#define S3C2410_SDIDCNT_BLKNUM_SHIFT  (12)
-
-#define S3C2410_SDIDSTA_RDYWAITREQ    (1<<10)
-#define S3C2410_SDIDSTA_SDIOIRQDETECT (1<<9)
-#define S3C2410_SDIDSTA_FIFOFAIL      (1<<8)   /* reserved on 2440 */
-#define S3C2410_SDIDSTA_CRCFAIL       (1<<7)
-#define S3C2410_SDIDSTA_RXCRCFAIL     (1<<6)
-#define S3C2410_SDIDSTA_DATATIMEOUT   (1<<5)
-#define S3C2410_SDIDSTA_XFERFINISH    (1<<4)
-#define S3C2410_SDIDSTA_BUSYFINISH    (1<<3)
-#define S3C2410_SDIDSTA_SBITERR       (1<<2)   /* reserved on 2410a/2440 */
-#define S3C2410_SDIDSTA_TXDATAON      (1<<1)
-#define S3C2410_SDIDSTA_RXDATAON      (1<<0)
-
-#define S3C2440_SDIFSTA_FIFORESET      (1<<16)
-#define S3C2440_SDIFSTA_FIFOFAIL       (3<<14)  /* 3 is correct (2 bits) */
-#define S3C2410_SDIFSTA_TFDET          (1<<13)
-#define S3C2410_SDIFSTA_RFDET          (1<<12)
-#define S3C2410_SDIFSTA_TFHALF         (1<<11)
-#define S3C2410_SDIFSTA_TFEMPTY        (1<<10)
-#define S3C2410_SDIFSTA_RFLAST         (1<<9)
-#define S3C2410_SDIFSTA_RFFULL         (1<<8)
-#define S3C2410_SDIFSTA_RFHALF         (1<<7)
-#define S3C2410_SDIFSTA_COUNTMASK      (0x7f)
-
-#define S3C2410_SDIIMSK_RESPONSECRC    (1<<17)
-#define S3C2410_SDIIMSK_CMDSENT        (1<<16)
-#define S3C2410_SDIIMSK_CMDTIMEOUT     (1<<15)
-#define S3C2410_SDIIMSK_RESPONSEND     (1<<14)
-#define S3C2410_SDIIMSK_READWAIT       (1<<13)
-#define S3C2410_SDIIMSK_SDIOIRQ        (1<<12)
-#define S3C2410_SDIIMSK_FIFOFAIL       (1<<11)
-#define S3C2410_SDIIMSK_CRCSTATUS      (1<<10)
-#define S3C2410_SDIIMSK_DATACRC        (1<<9)
-#define S3C2410_SDIIMSK_DATATIMEOUT    (1<<8)
-#define S3C2410_SDIIMSK_DATAFINISH     (1<<7)
-#define S3C2410_SDIIMSK_BUSYFINISH     (1<<6)
-#define S3C2410_SDIIMSK_SBITERR        (1<<5)  /* reserved 2440/2410a */
-#define S3C2410_SDIIMSK_TXFIFOHALF     (1<<4)
-#define S3C2410_SDIIMSK_TXFIFOEMPTY    (1<<3)
-#define S3C2410_SDIIMSK_RXFIFOLAST     (1<<2)
-#define S3C2410_SDIIMSK_RXFIFOFULL     (1<<1)
-#define S3C2410_SDIIMSK_RXFIFOHALF     (1<<0)
-
-#endif /* __ASM_ARM_REGS_SDI */
index e1199599873e0691ed432be5208d7461e1629af4..b91341ef2b2e72b7b39738e55728c0757d551410 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/syscore_ops.h>
+#include <linux/io.h>
 
 #include <plat/cpu.h>
 #include <plat/pm.h>
-#include <plat/irq.h>
+#include <plat/map-base.h>
+#include <plat/map-s3c.h>
+
+#include <mach/regs-irq.h>
+#include <mach/regs-gpio.h>
 
 #include <asm/irq.h>
 
index cb9f5e011e73a1fb5f055dc6a3c6498aa095f7e0..c1b96f7cc587e310d5cf594449a75a688dd8a2e9 100644 (file)
@@ -34,7 +34,6 @@
 #include <plat/cpu.h>
 #include <plat/regs-irqtype.h>
 #include <plat/pm.h>
-#include <plat/irq.h>
 
 #define S3C_IRQTYPE_NONE       0
 #define S3C_IRQTYPE_EINT       1
@@ -175,8 +174,7 @@ static int s3c_irqext_type_set(void __iomem *gpcon_reg,
        return 0;
 }
 
-/* FIXME: make static when it's out of plat-samsung/irq.h */
-int s3c_irqext_type(struct irq_data *data, unsigned int type)
+static int s3c_irqext_type(struct irq_data *data, unsigned int type)
 {
        void __iomem *extint_reg;
        void __iomem *gpcon_reg;
@@ -224,7 +222,7 @@ static int s3c_irqext0_type(struct irq_data *data, unsigned int type)
                                   extint_offset, type);
 }
 
-struct irq_chip s3c_irq_chip = {
+static struct irq_chip s3c_irq_chip = {
        .name           = "s3c",
        .irq_ack        = s3c_irq_ack,
        .irq_mask       = s3c_irq_mask,
@@ -232,7 +230,7 @@ struct irq_chip s3c_irq_chip = {
        .irq_set_wake   = s3c_irq_wake
 };
 
-struct irq_chip s3c_irq_level_chip = {
+static struct irq_chip s3c_irq_level_chip = {
        .name           = "s3c-level",
        .irq_mask       = s3c_irq_mask,
        .irq_unmask     = s3c_irq_unmask,
index 0e0279e79150e781ae82f3c4c048921445abf5aa..432144cb54ae4c3ebfc6a1e9d140bd208240dabd 100644 (file)
@@ -63,6 +63,8 @@
 #include <linux/mtd/map.h>
 #include <linux/mtd/physmap.h>
 
+#include <plat/samsung-time.h>
+
 #include "common.h"
 
 static struct resource amlm5900_nor_resource =
@@ -160,6 +162,7 @@ static void __init amlm5900_map_io(void)
        s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc));
        s3c24xx_init_clocks(0);
        s3c24xx_init_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 #ifdef CONFIG_FB_S3C2410
@@ -237,6 +240,6 @@ MACHINE_START(AML_M5900, "AML_M5900")
        .map_io         = amlm5900_map_io,
        .init_irq       = s3c24xx_init_irq,
        .init_machine   = amlm5900_init,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c2410_restart,
 MACHINE_END
index bb595f15ce36c8f2788621462eec2aa010b8f565..24f1a04ccc88da039b53bedceaa88459ee923d09 100644 (file)
@@ -49,6 +49,7 @@
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <linux/platform_data/asoc-s3c24xx_simtec.h>
+#include <plat/samsung-time.h>
 
 #include "anubis.h"
 #include "common.h"
@@ -410,6 +411,7 @@ static void __init anubis_map_io(void)
        s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc));
        s3c24xx_init_clocks(0);
        s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
        /* check for the newer revision boards with large page nand */
 
@@ -444,6 +446,6 @@ MACHINE_START(ANUBIS, "Simtec-Anubis")
        .map_io         = anubis_map_io,
        .init_machine   = anubis_init,
        .init_irq       = s3c24xx_init_irq,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c244x_restart,
 MACHINE_END
index b4bc60c78ebb89f06bb4af29066b71638b031608..2bf6c8c243176a437d48cb8c2425c2c36bbe2065 100644 (file)
@@ -48,6 +48,7 @@
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <linux/platform_data/mmc-s3cmci.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 
@@ -192,6 +193,7 @@ static void __init at2440evb_map_io(void)
        s3c24xx_init_io(at2440evb_iodesc, ARRAY_SIZE(at2440evb_iodesc));
        s3c24xx_init_clocks(16934400);
        s3c24xx_init_uarts(at2440evb_uartcfgs, ARRAY_SIZE(at2440evb_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void __init at2440evb_init(void)
@@ -210,6 +212,6 @@ MACHINE_START(AT2440EVB, "AT2440EVB")
        .map_io         = at2440evb_map_io,
        .init_machine   = at2440evb_init,
        .init_irq       = s3c24xx_init_irq,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c244x_restart,
 MACHINE_END
index ca661808104171a6ec13683868aa71bc69ecacf8..eabe2db42ef6100c8a815d26bd8769b10f9b007e 100644 (file)
@@ -55,6 +55,7 @@
 #include <plat/devs.h>
 #include <plat/gpio-cfg.h>
 #include <plat/regs-serial.h>
+#include <plat/samsung-time.h>
 
 #include "bast.h"
 #include "common.h"
@@ -576,6 +577,7 @@ static void __init bast_map_io(void)
        s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
        s3c24xx_init_clocks(0);
        s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void __init bast_init(void)
@@ -605,6 +607,6 @@ MACHINE_START(BAST, "Simtec-BAST")
        .map_io         = bast_map_io,
        .init_irq       = s3c24xx_init_irq,
        .init_machine   = bast_init,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c2410_restart,
 MACHINE_END
index a25e8c5a7b4c9a3fe236af761e08814c97234267..84a750d46d4bd498c21f38838f5ac2de8185164f 100644 (file)
@@ -81,6 +81,7 @@
 #include <plat/gpio-cfg.h>
 #include <plat/pm.h>
 #include <plat/regs-serial.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 #include "gta02.h"
@@ -501,6 +502,7 @@ static void __init gta02_map_io(void)
        s3c24xx_init_io(gta02_iodesc, ARRAY_SIZE(gta02_iodesc));
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 
@@ -589,6 +591,6 @@ MACHINE_START(NEO1973_GTA02, "GTA02")
        .map_io         = gta02_map_io,
        .init_irq       = s3c24xx_init_irq,
        .init_machine   = gta02_machine_init,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c244x_restart,
 MACHINE_END
index 79bc0830d740658986ed6cb1739310f71252020d..8dd66010284644700f8b54353b5a85319c272268 100644 (file)
@@ -62,7 +62,7 @@
 #include <plat/pll.h>
 #include <plat/pm.h>
 #include <plat/regs-serial.h>
-
+#include <plat/samsung-time.h>
 
 #include "common.h"
 #include "h1940.h"
@@ -646,6 +646,7 @@ static void __init h1940_map_io(void)
        s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc));
        s3c24xx_init_clocks(0);
        s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
        /* setup PM */
 
@@ -741,6 +742,6 @@ MACHINE_START(H1940, "IPAQ-H1940")
        .reserve        = h1940_reserve,
        .init_irq       = h1940_init_irq,
        .init_machine   = h1940_init,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c2410_restart,
 MACHINE_END
index 54e83c1f780c569358c820046afccea0f41f62de..aade943288c788d0a79a1bc05850432e42e27835 100644 (file)
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 
-#include <plat/s3c2412.h>
 #include <plat/gpio-cfg.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/pm.h>
 #include <linux/platform_data/usb-s3c2410_udc.h>
+#include <plat/samsung-time.h>
 
+#include "common.h"
 #include "s3c2412-power.h"
 
 static struct map_desc jive_iodesc[] __initdata = {
@@ -506,6 +507,7 @@ static void __init jive_map_io(void)
        s3c24xx_init_io(jive_iodesc, ARRAY_SIZE(jive_iodesc));
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(jive_uartcfgs, ARRAY_SIZE(jive_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void jive_power_off(void)
@@ -661,6 +663,6 @@ MACHINE_START(JIVE, "JIVE")
        .init_irq       = s3c24xx_init_irq,
        .map_io         = jive_map_io,
        .init_machine   = jive_machine_init,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c2412_restart,
 MACHINE_END
index 2865e5919f2cb8a176a54d9d463afdeda4c8731f..29f106cb370e949988290e1cc40158c7e439e495 100644 (file)
@@ -56,6 +56,7 @@
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
+#include <plat/samsung-time.h>
 
 #include <sound/s3c24xx_uda134x.h>
 
@@ -525,6 +526,7 @@ static void __init mini2440_map_io(void)
        s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc));
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(mini2440_uartcfgs, ARRAY_SIZE(mini2440_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 /*
@@ -687,6 +689,6 @@ MACHINE_START(MINI2440, "MINI2440")
        .map_io         = mini2440_map_io,
        .init_machine   = mini2440_init,
        .init_irq       = s3c24xx_init_irq,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c244x_restart,
 MACHINE_END
index d9d04b2402959eee8a6fd5c32c0718f15435161b..73a690f431e6a889f0e87270f35a001c30192b54 100644 (file)
@@ -48,8 +48,8 @@
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <linux/platform_data/mmc-s3cmci.h>
-#include <plat/s3c2410.h>
 #include <linux/platform_data/usb-s3c2410_udc.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 
@@ -536,6 +536,7 @@ static void __init n30_map_io(void)
        n30_hwinit();
        s3c24xx_init_clocks(0);
        s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 /* GPB3 is the line that controls the pull-up for the USB D+ line */
@@ -589,7 +590,7 @@ MACHINE_START(N30, "Acer-N30")
                                Ben Dooks <ben-linux@fluff.org>
        */
        .atag_offset    = 0x100,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .init_machine   = n30_init,
        .init_irq       = s3c24xx_init_irq,
        .map_io         = n30_map_io,
@@ -600,7 +601,7 @@ MACHINE_START(N35, "Acer-N35")
        /* Maintainer: Christer Weinigel <christer@weinigel.se>
        */
        .atag_offset    = 0x100,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .init_machine   = n30_init,
        .init_irq       = s3c24xx_init_irq,
        .map_io         = n30_map_io,
index a454e246186063694508f59f957e87f5f5142f00..5c826d10a66d2f1499b3ed8465c341b549f62afb 100644 (file)
 #include <linux/platform_data/i2c-s3c2410.h>
 
 #include <plat/gpio-cfg.h>
-#include <plat/s3c2410.h>
-#include <plat/s3c244x.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 
@@ -137,6 +136,7 @@ static void __init nexcoder_map_io(void)
        s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc));
        s3c24xx_init_clocks(0);
        s3c24xx_init_uarts(nexcoder_uartcfgs, ARRAY_SIZE(nexcoder_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
        nexcoder_sensorboard_init();
 }
@@ -153,6 +153,6 @@ MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440")
        .map_io         = nexcoder_map_io,
        .init_machine   = nexcoder_init,
        .init_irq       = s3c24xx_init_irq,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c244x_restart,
 MACHINE_END
index ae2cbdf3e3ca536e9a184342979ee3829b963bb6..4c90ffda4e11c90dc10079206a54c4b5be622bfc 100644 (file)
@@ -45,6 +45,7 @@
 #include <plat/devs.h>
 #include <plat/gpio-cfg.h>
 #include <plat/regs-serial.h>
+#include <plat/samsung-time.h>
 
 #include <mach/hardware.h>
 #include <mach/regs-gpio.h>
@@ -384,6 +385,7 @@ static void __init osiris_map_io(void)
        s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc));
        s3c24xx_init_clocks(0);
        s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
        /* check for the newer revision boards with large page nand */
 
@@ -426,6 +428,6 @@ MACHINE_START(OSIRIS, "Simtec-OSIRIS")
        .map_io         = osiris_map_io,
        .init_irq       = s3c24xx_init_irq,
        .init_machine   = osiris_init,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c244x_restart,
 MACHINE_END
index 40a47d6c6a851e0a658f583a5af8fc20cb84d71e..7b8670746b6a6261acb04f13a563ebf7dba14e69 100644 (file)
@@ -33,7 +33,7 @@
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/regs-serial.h>
-#include <plat/s3c2410.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 #include "otom.h"
@@ -102,6 +102,7 @@ static void __init otom11_map_io(void)
        s3c24xx_init_io(otom11_iodesc, ARRAY_SIZE(otom11_iodesc));
        s3c24xx_init_clocks(0);
        s3c24xx_init_uarts(otom11_uartcfgs, ARRAY_SIZE(otom11_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void __init otom11_init(void)
@@ -116,6 +117,6 @@ MACHINE_START(OTOM, "Nex Vision - Otom 1.1")
        .map_io         = otom11_map_io,
        .init_machine   = otom11_init,
        .init_irq       = s3c24xx_init_irq,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c2410_restart,
 MACHINE_END
index 56175f0941b101def5aae288abf011698441b69e..71cf29b12d1f79b83085be8a4e9b1145b2babbab 100644 (file)
 #include <linux/platform_data/usb-s3c2410_udc.h>
 #include <linux/platform_data/i2c-s3c2410.h>
 
-#include <plat/common-smdk.h>
 #include <plat/gpio-cfg.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/pm.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
+#include "common-smdk.h"
 
 static struct map_desc qt2410_iodesc[] __initdata = {
        { 0xe0000000, __phys_to_pfn(S3C2410_CS3+0x01000000), SZ_1M, MT_DEVICE }
@@ -304,6 +305,7 @@ static void __init qt2410_map_io(void)
        s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc));
        s3c24xx_init_clocks(12*1000*1000);
        s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void __init qt2410_machine_init(void)
@@ -343,6 +345,6 @@ MACHINE_START(QT2410, "QT2410")
        .map_io         = qt2410_map_io,
        .init_irq       = s3c24xx_init_irq,
        .init_machine   = qt2410_machine_init,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c2410_restart,
 MACHINE_END
index 1f9ba2ae5288ee83aa9d83300eb68181ba263612..799af43b4e6a1f80dd830f70ff08c688a1d8ec6e 100644 (file)
@@ -58,6 +58,7 @@
 #include <plat/pm.h>
 #include <plat/regs-iic.h>
 #include <plat/regs-serial.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 #include "h1940.h"
@@ -741,6 +742,7 @@ static void __init rx1950_map_io(void)
        s3c24xx_init_io(rx1950_iodesc, ARRAY_SIZE(rx1950_iodesc));
        s3c24xx_init_clocks(16934000);
        s3c24xx_init_uarts(rx1950_uartcfgs, ARRAY_SIZE(rx1950_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
        /* setup PM */
 
@@ -813,6 +815,6 @@ MACHINE_START(RX1950, "HP iPAQ RX1950")
        .reserve        = rx1950_reserve,
        .init_irq = s3c24xx_init_irq,
        .init_machine = rx1950_init_machine,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c244x_restart,
 MACHINE_END
index f20418a2fb1b62e2bf882dd768da1fae52c4e288..0a3c96452f0f7e823ae7acd09f7514f65e93bf81 100644 (file)
@@ -49,6 +49,7 @@
 #include <plat/devs.h>
 #include <plat/pm.h>
 #include <plat/regs-serial.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 #include "h1940.h"
@@ -179,6 +180,7 @@ static void __init rx3715_map_io(void)
        s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
        s3c24xx_init_clocks(16934000);
        s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 /* H1940 and RX3715 need to reserve this for suspend */
@@ -212,6 +214,6 @@ MACHINE_START(RX3715, "IPAQ-RX3715")
        .reserve        = rx3715_reserve,
        .init_irq       = rx3715_init_irq,
        .init_machine   = rx3715_init_machine,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c244x_restart,
 MACHINE_END
index e184bfa9613aea23dc19a83d08eb88c0175667d6..fd96f7fc330c5eb2035091732aae03ce1368aac7 100644 (file)
 
 #include <plat/devs.h>
 #include <plat/cpu.h>
-
-#include <plat/common-smdk.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
+#include "common-smdk.h"
 
 static struct map_desc smdk2410_iodesc[] __initdata = {
   /* nothing here yet */
@@ -101,6 +101,7 @@ static void __init smdk2410_map_io(void)
        s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
        s3c24xx_init_clocks(0);
        s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void __init smdk2410_init(void)
@@ -117,6 +118,6 @@ MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switc
        .map_io         = smdk2410_map_io,
        .init_irq       = s3c24xx_init_irq,
        .init_machine   = smdk2410_init,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c2410_restart,
 MACHINE_END
index 86d7847c9d4502820bd3754d2c589c1fec023ce4..8e3f1d9bbb7c602b5d9319d362a0656841fc5ff0 100644 (file)
 #include <linux/platform_data/i2c-s3c2410.h>
 #include <mach/fb.h>
 
-#include <plat/s3c2410.h>
-#include <plat/s3c2412.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
+#include <plat/samsung-time.h>
 
-#include <plat/common-smdk.h>
+#include "common.h"
+#include "common-smdk.h"
 
 static struct map_desc smdk2413_iodesc[] __initdata = {
 };
@@ -106,6 +106,7 @@ static void __init smdk2413_map_io(void)
        s3c24xx_init_io(smdk2413_iodesc, ARRAY_SIZE(smdk2413_iodesc));
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(smdk2413_uartcfgs, ARRAY_SIZE(smdk2413_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void __init smdk2413_machine_init(void)
@@ -132,7 +133,7 @@ MACHINE_START(S3C2413, "S3C2413")
        .init_irq       = s3c24xx_init_irq,
        .map_io         = smdk2413_map_io,
        .init_machine   = smdk2413_machine_init,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c2412_restart,
 MACHINE_END
 
@@ -144,7 +145,7 @@ MACHINE_START(SMDK2412, "SMDK2412")
        .init_irq       = s3c24xx_init_irq,
        .map_io         = smdk2413_map_io,
        .init_machine   = smdk2413_machine_init,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c2412_restart,
 MACHINE_END
 
@@ -156,6 +157,6 @@ MACHINE_START(SMDK2413, "SMDK2413")
        .init_irq       = s3c24xx_init_irq,
        .map_io         = smdk2413_map_io,
        .init_machine   = smdk2413_machine_init,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c2412_restart,
 MACHINE_END
index ebb2e61f3d079c4503b6285cade566eddaa26af4..cb46847c66b4a71c50272a4d847ca49356266742 100644 (file)
@@ -42,7 +42,6 @@
 #include <linux/platform_data/leds-s3c24xx.h>
 #include <linux/platform_data/i2c-s3c2410.h>
 
-#include <plat/s3c2416.h>
 #include <plat/gpio-cfg.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/sdhci.h>
 #include <linux/platform_data/usb-s3c2410_udc.h>
 #include <linux/platform_data/s3c-hsudc.h>
+#include <plat/samsung-time.h>
 
 #include <plat/fb.h>
 
-#include <plat/common-smdk.h>
+#include "common.h"
+#include "common-smdk.h"
 
 static struct map_desc smdk2416_iodesc[] __initdata = {
        /* ISA IO Space map (memory space selected by A24) */
@@ -221,6 +222,7 @@ static void __init smdk2416_map_io(void)
        s3c24xx_init_io(smdk2416_iodesc, ARRAY_SIZE(smdk2416_iodesc));
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(smdk2416_uartcfgs, ARRAY_SIZE(smdk2416_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void __init smdk2416_machine_init(void)
@@ -253,6 +255,6 @@ MACHINE_START(SMDK2416, "SMDK2416")
        .init_irq       = s3c2416_init_irq,
        .map_io         = smdk2416_map_io,
        .init_machine   = smdk2416_machine_init,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c2416_restart,
 MACHINE_END
index 08cc38c8a4aee6d2e8142a5d05d6599c59c46176..f56cb08e6d1cf78d3babf0dc90334a30a0df7b1c 100644 (file)
 #include <mach/fb.h>
 #include <linux/platform_data/i2c-s3c2410.h>
 
-#include <plat/s3c2410.h>
-#include <plat/s3c244x.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
-
-#include <plat/common-smdk.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
+#include "common-smdk.h"
 
 static struct map_desc smdk2440_iodesc[] __initdata = {
        /* ISA IO Space map (memory space selected by A24) */
@@ -163,6 +161,7 @@ static void __init smdk2440_map_io(void)
        s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
        s3c24xx_init_clocks(16934400);
        s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void __init smdk2440_machine_init(void)
@@ -181,6 +180,6 @@ MACHINE_START(S3C2440, "SMDK2440")
        .init_irq       = s3c24xx_init_irq,
        .map_io         = smdk2440_map_io,
        .init_machine   = smdk2440_machine_init,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c244x_restart,
 MACHINE_END
index fc65d74d3c73f7567caa9cd2eebd17d0f165f020..9435c3bef18a91c53da53dcc29e68498bc834946 100644 (file)
 #include <mach/fb.h>
 #include <linux/platform_data/i2c-s3c2410.h>
 
-#include <plat/s3c2410.h>
-#include <plat/s3c2443.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
+#include <plat/samsung-time.h>
 
-#include <plat/common-smdk.h>
+#include "common.h"
+#include "common-smdk.h"
 
 static struct map_desc smdk2443_iodesc[] __initdata = {
        /* ISA IO Space map (memory space selected by A24) */
@@ -122,6 +122,7 @@ static void __init smdk2443_map_io(void)
        s3c24xx_init_io(smdk2443_iodesc, ARRAY_SIZE(smdk2443_iodesc));
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(smdk2443_uartcfgs, ARRAY_SIZE(smdk2443_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void __init smdk2443_machine_init(void)
@@ -143,6 +144,6 @@ MACHINE_START(SMDK2443, "SMDK2443")
        .init_irq       = s3c2443_init_irq,
        .map_io         = smdk2443_map_io,
        .init_machine   = smdk2443_machine_init,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c2443_restart,
 MACHINE_END
index 24b3d79e7b2c65174dd5aa84cd5d6c6af2abfd6b..31dfe589e34972130ce3482cdea2f21442489900 100644 (file)
@@ -53,6 +53,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/map.h>
 #include <linux/mtd/physmap.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 
@@ -136,6 +137,7 @@ static void __init tct_hammer_map_io(void)
        s3c24xx_init_io(tct_hammer_iodesc, ARRAY_SIZE(tct_hammer_iodesc));
        s3c24xx_init_clocks(0);
        s3c24xx_init_uarts(tct_hammer_uartcfgs, ARRAY_SIZE(tct_hammer_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void __init tct_hammer_init(void)
@@ -149,6 +151,6 @@ MACHINE_START(TCT_HAMMER, "TCT_HAMMER")
        .map_io         = tct_hammer_map_io,
        .init_irq       = s3c24xx_init_irq,
        .init_machine   = tct_hammer_init,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c2410_restart,
 MACHINE_END
index ec42d1e4e465b5ef6b61d9089924b41de501b6ca..deeb8a0a4034ba373b1143e781f82584e3b250d7 100644 (file)
@@ -45,6 +45,7 @@
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/regs-serial.h>
+#include <plat/samsung-time.h>
 
 #include "bast.h"
 #include "common.h"
@@ -332,6 +333,7 @@ static void __init vr1000_map_io(void)
        s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
        s3c24xx_init_clocks(0);
        s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void __init vr1000_init(void)
@@ -354,6 +356,6 @@ MACHINE_START(VR1000, "Thorcom-VR1000")
        .map_io         = vr1000_map_io,
        .init_machine   = vr1000_init,
        .init_irq       = s3c24xx_init_irq,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c2410_restart,
 MACHINE_END
index 3e2bfddc9df126469b4778141449e9a8f9dd3df5..622a1ed24509a6a0f230bf14e87145cacad231f9 100644 (file)
 #include <linux/platform_data/i2c-s3c2410.h>
 #include <linux/platform_data/mtd-nand-s3c2410.h>
 
-#include <plat/s3c2410.h>
-#include <plat/s3c2412.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
+#include <plat/samsung-time.h>
 
+#include "common.h"
 
 static struct map_desc vstms_iodesc[] __initdata = {
 };
@@ -143,6 +143,7 @@ static void __init vstms_map_io(void)
        s3c24xx_init_io(vstms_iodesc, ARRAY_SIZE(vstms_iodesc));
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(vstms_uartcfgs, ARRAY_SIZE(vstms_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void __init vstms_init(void)
@@ -160,6 +161,6 @@ MACHINE_START(VSTMS, "VSTMS")
        .init_irq       = s3c24xx_init_irq,
        .init_machine   = vstms_init,
        .map_io         = vstms_map_io,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c2412_restart,
 MACHINE_END
index 668a78a8b19518a07dff82f4e6cc8e702d6e8be5..4c4bc1c83b77626d0690fd2da84ea09a4d1b3397 100644 (file)
@@ -29,7 +29,6 @@
 
 #include <plat/cpu.h>
 #include <plat/pm.h>
-#include <plat/s3c2412.h>
 
 #include "regs-dsc.h"
 #include "s3c2412-power.h"
index 9ebef95da721d4fcd81650a04127609d170fb2cd..d850ea5adac26f142beb8beb8b1c03c2637ffc58 100644 (file)
@@ -37,7 +37,6 @@
 #include <mach/regs-clock.h>
 #include <plat/regs-serial.h>
 
-#include <plat/s3c2410.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/clock.h>
index 0d592159a5c33492012aec32e59443aed2557862..0f864d4c97deae90cb0a3cd8dac24ede99af4904 100644 (file)
@@ -44,7 +44,6 @@
 #include <plat/pm.h>
 #include <plat/regs-serial.h>
 #include <plat/regs-spi.h>
-#include <plat/s3c2412.h>
 
 #include "common.h"
 #include "regs-dsc.h"
index e30476db0295b848630ddd616c990ca084c13e9b..b9c5d382dafb973b8258ae2cdbb9241436726a0b 100644 (file)
@@ -50,7 +50,6 @@
 #include <plat/gpio-core.h>
 #include <plat/gpio-cfg.h>
 #include <plat/gpio-cfg-helpers.h>
-#include <plat/s3c2416.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/sdhci.h>
index 559e394e89895a79f68809621c1458112f4abd9b..5f9d6569475d713cacf7be730d4c4fff6c9369ee 100644 (file)
@@ -33,7 +33,6 @@
 
 #include <plat/devs.h>
 #include <plat/cpu.h>
-#include <plat/s3c244x.h>
 #include <plat/pm.h>
 
 #include <plat/gpio-core.h>
index f732826c23593ef80d0b4f4d5f68e9cee9a6715e..6819961f6b19c0f6cfc7d41b3bb28e386f2869d2 100644 (file)
@@ -44,7 +44,6 @@
 
 #include <plat/clock.h>
 #include <plat/cpu.h>
-#include <plat/s3c244x.h>
 #include <plat/pm.h>
 
 #include <plat/gpio-core.h>
index 165b6a6b3daaa9450201db7b0c721f76c62574f2..8328cd65bf3d44c4255f3c5eb66382473e4ffdef 100644 (file)
@@ -36,7 +36,6 @@
 #include <plat/gpio-core.h>
 #include <plat/gpio-cfg.h>
 #include <plat/gpio-cfg-helpers.h>
-#include <plat/s3c2443.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/fb-core.h>
index ad2671baa910dbc1a1ad43000df6730e00e3ff64..2a35edb6735499b9f78c8fb01e3d2fba07548522 100644 (file)
@@ -37,8 +37,6 @@
 #include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 
-#include <plat/s3c2410.h>
-#include <plat/s3c244x.h>
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
index 131c86284711daa565ab89a350a79ba72d687422..283cb77d47211a2e4a840b8b772a3b82dff1d32d 100644 (file)
@@ -17,11 +17,13 @@ config PLAT_S3C64XX
 # Configuration options for the S3C6410 CPU
 
 config CPU_S3C6400
+       select SAMSUNG_HRT
        bool
        help
          Enable S3C6400 CPU support
 
 config CPU_S3C6410
+       select SAMSUNG_HRT
        bool
        help
          Enable S3C6410 CPU support
index 728eef3296b2d19c5a878cdc49d1685c18b44313..35e3f54574eff6773f5c2eca10b69d0d1e02cccc 100644 (file)
@@ -49,6 +49,7 @@
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <mach/regs-gpio.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 #include "regs-modem.h"
@@ -208,6 +209,7 @@ static void __init anw6410_map_io(void)
        s3c64xx_init_io(anw6410_iodesc, ARRAY_SIZE(anw6410_iodesc));
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(anw6410_uartcfgs, ARRAY_SIZE(anw6410_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
        anw6410_lcd_mode_set();
 }
@@ -232,6 +234,6 @@ MACHINE_START(ANW6410, "A&W6410")
        .map_io         = anw6410_map_io,
        .init_machine   = anw6410_machine_init,
        .init_late      = s3c64xx_init_late,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c64xx_restart,
 MACHINE_END
index 1acf02bace57074429bfec20ee7b362f4dbdf938..8ad88ace795a41cc617a1cdba91aa08e46856e04 100644 (file)
@@ -64,6 +64,7 @@
 #include <plat/adc.h>
 #include <linux/platform_data/i2c-s3c2410.h>
 #include <plat/pm.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 #include "crag6410.h"
@@ -744,6 +745,7 @@ static void __init crag6410_map_io(void)
        s3c64xx_init_io(NULL, 0);
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(crag6410_uartcfgs, ARRAY_SIZE(crag6410_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
        /* LCD type and Bypass set by bootloader */
 }
@@ -868,6 +870,6 @@ MACHINE_START(WLF_CRAGG_6410, "Wolfson Cragganmore 6410")
        .map_io         = crag6410_map_io,
        .init_machine   = crag6410_machine_init,
        .init_late      = s3c64xx_init_late,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c64xx_restart,
 MACHINE_END
index 7212eb9cfeb9f255f5581b485a2f34eb4afd0261..5b7f357d8c22c1de54a8e62a8b8225cf48af63e6 100644 (file)
@@ -41,6 +41,7 @@
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 
@@ -248,6 +249,7 @@ static void __init hmt_map_io(void)
        s3c64xx_init_io(hmt_iodesc, ARRAY_SIZE(hmt_iodesc));
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(hmt_uartcfgs, ARRAY_SIZE(hmt_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void __init hmt_machine_init(void)
@@ -275,6 +277,6 @@ MACHINE_START(HMT, "Airgoo-HMT")
        .map_io         = hmt_map_io,
        .init_machine   = hmt_machine_init,
        .init_late      = s3c64xx_init_late,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c64xx_restart,
 MACHINE_END
index 4b41fcdaa7b663465f4a3d00c1f66e668ea478ef..fc043e3ecdf8a869ea77e27af42dad5c24222356 100644 (file)
@@ -41,6 +41,7 @@
 
 #include <video/platform_lcd.h>
 #include <video/samsung_fimd.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 #include "regs-modem.h"
@@ -232,6 +233,7 @@ static void __init mini6410_map_io(void)
        s3c64xx_init_io(NULL, 0);
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(mini6410_uartcfgs, ARRAY_SIZE(mini6410_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
        /* set the LCD type */
        tmp = __raw_readl(S3C64XX_SPCON);
@@ -354,6 +356,6 @@ MACHINE_START(MINI6410, "MINI6410")
        .map_io         = mini6410_map_io,
        .init_machine   = mini6410_machine_init,
        .init_late      = s3c64xx_init_late,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c64xx_restart,
 MACHINE_END
index 8d3cedd995ffd43a88c1398cff7ce5ddaa33bbb9..7e2c3908f1f87a2db546867d9ff8417e2051049e 100644 (file)
@@ -43,6 +43,7 @@
 #include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 
@@ -87,6 +88,7 @@ static void __init ncp_map_io(void)
        s3c64xx_init_io(ncp_iodesc, ARRAY_SIZE(ncp_iodesc));
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(ncp_uartcfgs, ARRAY_SIZE(ncp_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void __init ncp_machine_init(void)
@@ -103,6 +105,6 @@ MACHINE_START(NCP, "NCP")
        .map_io         = ncp_map_io,
        .init_machine   = ncp_machine_init,
        .init_late      = s3c64xx_init_late,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c64xx_restart,
 MACHINE_END
index fa12bd21ad82058f51934f6a5e063e260bfadbfc..8bed37b3d5ac8897eaa49912f67edacdbed238fe 100644 (file)
@@ -42,6 +42,7 @@
 
 #include <video/platform_lcd.h>
 #include <video/samsung_fimd.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 #include "regs-modem.h"
@@ -211,6 +212,7 @@ static void __init real6410_map_io(void)
        s3c64xx_init_io(NULL, 0);
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(real6410_uartcfgs, ARRAY_SIZE(real6410_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
        /* set the LCD type */
        tmp = __raw_readl(S3C64XX_SPCON);
@@ -333,6 +335,6 @@ MACHINE_START(REAL6410, "REAL6410")
        .map_io         = real6410_map_io,
        .init_machine   = real6410_machine_init,
        .init_late      = s3c64xx_init_late,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c64xx_restart,
 MACHINE_END
index fc3e9b32e26fb235a38e226b4659cc1bca21ca5d..58ac99041274e86b187826f8349bcf8c93d53d9b 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/platform_data/touchscreen-s3c2410.h>
 
 #include <video/platform_lcd.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 #include "regs-modem.h"
@@ -378,6 +379,7 @@ void __init smartq_map_io(void)
        s3c64xx_init_io(smartq_iodesc, ARRAY_SIZE(smartq_iodesc));
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(smartq_uartcfgs, ARRAY_SIZE(smartq_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
        smartq_lcd_mode_set();
 }
index ca2afcfce57391f29721325229246895002823ed..8aca5daf3d05a10b62184969109c1a59c9744438 100644 (file)
@@ -28,6 +28,7 @@
 #include <plat/devs.h>
 #include <plat/fb.h>
 #include <plat/gpio-cfg.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 #include "mach-smartq.h"
@@ -155,6 +156,6 @@ MACHINE_START(SMARTQ5, "SmartQ 5")
        .map_io         = smartq_map_io,
        .init_machine   = smartq5_machine_init,
        .init_late      = s3c64xx_init_late,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c64xx_restart,
 MACHINE_END
index 37bb0c632a5efe1043b2473d053be656b0d38d73..a052e107c0b402a3ac7cab606da610e573ef7618 100644 (file)
@@ -28,6 +28,7 @@
 #include <plat/devs.h>
 #include <plat/fb.h>
 #include <plat/gpio-cfg.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 #include "mach-smartq.h"
@@ -171,6 +172,6 @@ MACHINE_START(SMARTQ7, "SmartQ 7")
        .map_io         = smartq_map_io,
        .init_machine   = smartq7_machine_init,
        .init_late      = s3c64xx_init_late,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c64xx_restart,
 MACHINE_END
index a392869c834262360ec0ce5a51abffca27977bc4..d70c0843aea2d8bca384cc814d0270e778def128 100644 (file)
@@ -35,6 +35,7 @@
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <linux/platform_data/i2c-s3c2410.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 
@@ -66,6 +67,7 @@ static void __init smdk6400_map_io(void)
        s3c64xx_init_io(smdk6400_iodesc, ARRAY_SIZE(smdk6400_iodesc));
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(smdk6400_uartcfgs, ARRAY_SIZE(smdk6400_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static struct platform_device *smdk6400_devices[] __initdata = {
@@ -92,6 +94,6 @@ MACHINE_START(SMDK6400, "SMDK6400")
        .map_io         = smdk6400_map_io,
        .init_machine   = smdk6400_machine_init,
        .init_late      = s3c64xx_init_late,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c64xx_restart,
 MACHINE_END
index ba7544e2d04d6fcec91205350601b042d5d247b8..bd3295a19ad7dc02f18f3e38c335d4ca2deda8f7 100644 (file)
@@ -69,6 +69,7 @@
 #include <linux/platform_data/touchscreen-s3c2410.h>
 #include <plat/keypad.h>
 #include <plat/backlight.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 #include "regs-modem.h"
@@ -634,6 +635,7 @@ static void __init smdk6410_map_io(void)
        s3c64xx_init_io(smdk6410_iodesc, ARRAY_SIZE(smdk6410_iodesc));
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(smdk6410_uartcfgs, ARRAY_SIZE(smdk6410_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
        /* set the LCD type */
 
@@ -702,6 +704,6 @@ MACHINE_START(SMDK6410, "SMDK6410")
        .map_io         = smdk6410_map_io,
        .init_machine   = smdk6410_machine_init,
        .init_late      = s3c64xx_init_late,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s3c64xx_restart,
 MACHINE_END
index e8742cb7ddd955726d6c62637eae424c2a6924f5..5a707bdb9ea032172f5eef696d17593ffce3825f 100644 (file)
@@ -9,16 +9,16 @@ if ARCH_S5P64X0
 
 config CPU_S5P6440
        bool
-       select S5P_HRT
        select S5P_SLEEP if PM
        select SAMSUNG_DMADEV
+       select SAMSUNG_HRT
        select SAMSUNG_WAKEMASK if PM
        help
          Enable S5P6440 CPU support
 
 config CPU_S5P6450
        bool
-       select S5P_HRT
+       select SAMSUNG_HRT
        select S5P_SLEEP if PM
        select SAMSUNG_DMADEV
        select SAMSUNG_WAKEMASK if PM
index e23723a5a21480d16c202cec050ea967eca1d41a..73f71a698a3434b26cca9a26128ae746dc719363 100644 (file)
@@ -48,7 +48,7 @@
 #include <plat/pll.h>
 #include <plat/adc.h>
 #include <linux/platform_data/touchscreen-s3c2410.h>
-#include <plat/s5p-time.h>
+#include <plat/samsung-time.h>
 #include <plat/backlight.h>
 #include <plat/fb.h>
 #include <plat/sdhci.h>
@@ -229,7 +229,7 @@ static void __init smdk6440_map_io(void)
        s5p64x0_init_io(NULL, 0);
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(smdk6440_uartcfgs, ARRAY_SIZE(smdk6440_uartcfgs));
-       s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void s5p6440_set_lcd_interface(void)
@@ -273,6 +273,6 @@ MACHINE_START(SMDK6440, "SMDK6440")
        .init_irq       = s5p6440_init_irq,
        .map_io         = smdk6440_map_io,
        .init_machine   = smdk6440_machine_init,
-       .init_time      = s5p_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s5p64x0_restart,
 MACHINE_END
index ca10963a959efdb3bf7ea9737e0fad5f79ca108a..18303e12019f3bffe1784950870f532b663f0ab0 100644 (file)
@@ -48,7 +48,7 @@
 #include <plat/pll.h>
 #include <plat/adc.h>
 #include <linux/platform_data/touchscreen-s3c2410.h>
-#include <plat/s5p-time.h>
+#include <plat/samsung-time.h>
 #include <plat/backlight.h>
 #include <plat/fb.h>
 #include <plat/sdhci.h>
@@ -248,7 +248,7 @@ static void __init smdk6450_map_io(void)
        s5p64x0_init_io(NULL, 0);
        s3c24xx_init_clocks(19200000);
        s3c24xx_init_uarts(smdk6450_uartcfgs, ARRAY_SIZE(smdk6450_uartcfgs));
-       s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void s5p6450_set_lcd_interface(void)
@@ -292,6 +292,6 @@ MACHINE_START(SMDK6450, "SMDK6450")
        .init_irq       = s5p6450_init_irq,
        .map_io         = smdk6450_map_io,
        .init_machine   = smdk6450_machine_init,
-       .init_time      = s5p_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s5p64x0_restart,
 MACHINE_END
index 15170be97a74c0ecc69dd481d087205912095837..2f456a4533bafaa332dfaf548f469aec7cf64b7e 100644 (file)
@@ -11,6 +11,7 @@ config CPU_S5PC100
        bool
        select S5P_EXT_INT
        select SAMSUNG_DMADEV
+       select SAMSUNG_HRT
        help
          Enable S5PC100 CPU support
 
index 185a19583898dc3221d0fa69122a96a21a9d0a6b..8c880f76f27436302d739bc9f877c6769b67724b 100644 (file)
@@ -51,6 +51,7 @@
 #include <linux/platform_data/touchscreen-s3c2410.h>
 #include <linux/platform_data/asoc-s3c.h>
 #include <plat/backlight.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 
@@ -221,6 +222,7 @@ static void __init smdkc100_map_io(void)
        s5pc100_init_io(NULL, 0);
        s3c24xx_init_clocks(12000000);
        s3c24xx_init_uarts(smdkc100_uartcfgs, ARRAY_SIZE(smdkc100_uartcfgs));
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void __init smdkc100_machine_init(void)
@@ -255,6 +257,6 @@ MACHINE_START(SMDKC100, "SMDKC100")
        .init_irq       = s5pc100_init_irq,
        .map_io         = smdkc100_map_io,
        .init_machine   = smdkc100_machine_init,
-       .init_time      = s3c24xx_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s5pc100_restart,
 MACHINE_END
index 92ad72f0ef980ea836c2a38ca7ffde7262b358c8..0963283a7c5dc886ccb5e8746c66752cefa1cf2a 100644 (file)
@@ -12,10 +12,10 @@ if ARCH_S5PV210
 config CPU_S5PV210
        bool
        select S5P_EXT_INT
-       select S5P_HRT
        select S5P_PM if PM
        select S5P_SLEEP if PM
        select SAMSUNG_DMADEV
+       select SAMSUNG_HRT
        help
          Enable S5PV210 CPU support
 
index 11900a8e88a3369daba6dd5a5e64f94a9adb7319..ed2b85485b9d95301ff228e2e209911807090922 100644 (file)
@@ -38,7 +38,7 @@
 #include <plat/fb.h>
 #include <plat/fimc-core.h>
 #include <plat/sdhci.h>
-#include <plat/s5p-time.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 
@@ -651,7 +651,7 @@ static void __init aquila_map_io(void)
        s5pv210_init_io(NULL, 0);
        s3c24xx_init_clocks(24000000);
        s3c24xx_init_uarts(aquila_uartcfgs, ARRAY_SIZE(aquila_uartcfgs));
-       s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void __init aquila_machine_init(void)
@@ -686,6 +686,6 @@ MACHINE_START(AQUILA, "Aquila")
        .init_irq       = s5pv210_init_irq,
        .map_io         = aquila_map_io,
        .init_machine   = aquila_machine_init,
-       .init_time      = s5p_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s5pv210_restart,
 MACHINE_END
index e373de44a8b6f473672e1f10cd1d0a95287182aa..30b24ad84f496d383a2f71d0983926b51a239d1b 100644 (file)
@@ -47,7 +47,7 @@
 #include <plat/keypad.h>
 #include <plat/sdhci.h>
 #include <plat/clock.h>
-#include <plat/s5p-time.h>
+#include <plat/samsung-time.h>
 #include <plat/mfc.h>
 #include <plat/camport.h>
 
@@ -908,7 +908,7 @@ static void __init goni_map_io(void)
        s5pv210_init_io(NULL, 0);
        s3c24xx_init_clocks(clk_xusbxti.rate);
        s3c24xx_init_uarts(goni_uartcfgs, ARRAY_SIZE(goni_uartcfgs));
-       s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void __init goni_reserve(void)
@@ -973,7 +973,7 @@ MACHINE_START(GONI, "GONI")
        .init_irq       = s5pv210_init_irq,
        .map_io         = goni_map_io,
        .init_machine   = goni_machine_init,
-       .init_time      = s5p_timer_init,
+       .init_time      = samsung_timer_init,
        .reserve        = &goni_reserve,
        .restart        = s5pv210_restart,
 MACHINE_END
index 28bd0248a3e2ec57be4499bfa517d0fd5271e0b4..7c0ed07a78a3bf9bdb7944e609d1d65a19a1a921 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/platform_data/ata-samsung_cf.h>
 #include <linux/platform_data/i2c-s3c2410.h>
 #include <plat/pm.h>
-#include <plat/s5p-time.h>
+#include <plat/samsung-time.h>
 #include <plat/mfc.h>
 
 #include "common.h"
@@ -120,7 +120,7 @@ static void __init smdkc110_map_io(void)
        s5pv210_init_io(NULL, 0);
        s3c24xx_init_clocks(24000000);
        s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
-       s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void __init smdkc110_reserve(void)
@@ -153,7 +153,7 @@ MACHINE_START(SMDKC110, "SMDKC110")
        .init_irq       = s5pv210_init_irq,
        .map_io         = smdkc110_map_io,
        .init_machine   = smdkc110_machine_init,
-       .init_time      = s5p_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s5pv210_restart,
        .reserve        = &smdkc110_reserve,
 MACHINE_END
index 3c73f36869bbab37d49134882f3f1cb8f9758f08..d50b6f124465e2cac96e524ba16639b64f57e3ed 100644 (file)
@@ -44,7 +44,7 @@
 #include <plat/keypad.h>
 #include <plat/pm.h>
 #include <plat/fb.h>
-#include <plat/s5p-time.h>
+#include <plat/samsung-time.h>
 #include <plat/backlight.h>
 #include <plat/mfc.h>
 #include <plat/clock.h>
@@ -285,7 +285,7 @@ static void __init smdkv210_map_io(void)
        s5pv210_init_io(NULL, 0);
        s3c24xx_init_clocks(clk_xusbxti.rate);
        s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
-       s5p_set_timer_source(S5P_PWM2, S5P_PWM4);
+       samsung_set_timer_source(SAMSUNG_PWM2, SAMSUNG_PWM4);
 }
 
 static void __init smdkv210_reserve(void)
@@ -329,7 +329,7 @@ MACHINE_START(SMDKV210, "SMDKV210")
        .init_irq       = s5pv210_init_irq,
        .map_io         = smdkv210_map_io,
        .init_machine   = smdkv210_machine_init,
-       .init_time      = s5p_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s5pv210_restart,
        .reserve        = &smdkv210_reserve,
 MACHINE_END
index 2d4c5531819c06d7038149f0e872fa1b3a16a79d..579afe89842a3b169c9532e46096cfef7c998b9e 100644 (file)
@@ -26,7 +26,7 @@
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <linux/platform_data/i2c-s3c2410.h>
-#include <plat/s5p-time.h>
+#include <plat/samsung-time.h>
 
 #include "common.h"
 
@@ -106,7 +106,7 @@ static void __init torbreck_map_io(void)
        s5pv210_init_io(NULL, 0);
        s3c24xx_init_clocks(24000000);
        s3c24xx_init_uarts(torbreck_uartcfgs, ARRAY_SIZE(torbreck_uartcfgs));
-       s5p_set_timer_source(S5P_PWM3, S5P_PWM4);
+       samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
 static void __init torbreck_machine_init(void)
@@ -130,6 +130,6 @@ MACHINE_START(TORBRECK, "TORBRECK")
        .init_irq       = s5pv210_init_irq,
        .map_io         = torbreck_map_io,
        .init_machine   = torbreck_machine_init,
-       .init_time      = s5p_timer_init,
+       .init_time      = samsung_timer_init,
        .restart        = s5pv210_restart,
 MACHINE_END
index c7d2b4a8d8cc8dade91873b7a137656395b40051..25a10191b0218afb8ebbebe8a463ccf7cd869ea9 100644 (file)
 
 #include <linux/amba/pl022.h>
 #include <linux/clk.h>
+#include <linux/clocksource.h>
 #include <linux/dw_dmac.h>
 #include <linux/err.h>
 #include <linux/of.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/mach/map.h>
-#include <asm/smp_twd.h>
 #include <mach/dma.h>
 #include <mach/generic.h>
 #include <mach/spear.h>
@@ -179,5 +179,5 @@ void __init spear13xx_timer_init(void)
        clk_put(pclk);
 
        spear_setup_of_timer();
-       twd_local_timer_of_register();
+       clocksource_of_init();
 }
index f6b46ae2b7f868829310fa22295d251eda20b95b..e40326d0e29fa8fb6dff8e694f8539ca09e8e31f 100644 (file)
@@ -10,6 +10,7 @@ obj-y                                 += pm.o
 obj-y                                  += reset.o
 obj-y                                  += reset-handler.o
 obj-y                                  += sleep.o
+obj-y                                  += tegra.o
 obj-$(CONFIG_CPU_IDLE)                 += cpuidle.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += tegra20_speedo.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += tegra2_emc.o
@@ -27,9 +28,7 @@ obj-$(CONFIG_HOTPLUG_CPU)               += hotplug.o
 obj-$(CONFIG_CPU_FREQ)                  += cpu-tegra.o
 obj-$(CONFIG_TEGRA_PCI)                        += pcie.o
 
-obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += board-dt-tegra20.o
-obj-$(CONFIG_ARCH_TEGRA_3x_SOC)                += board-dt-tegra30.o
-obj-$(CONFIG_ARCH_TEGRA_114_SOC)       += board-dt-tegra114.o
+obj-$(CONFIG_ARCH_TEGRA_114_SOC)       += tegra114_speedo.o
 ifeq ($(CONFIG_CPU_IDLE),y)
 obj-$(CONFIG_ARCH_TEGRA_114_SOC)       += cpuidle-tegra114.o
 endif
diff --git a/arch/arm/mach-tegra/board-dt-tegra114.c b/arch/arm/mach-tegra/board-dt-tegra114.c
deleted file mode 100644 (file)
index 085d636..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * NVIDIA Tegra114 device tree board support
- *
- * Copyright (C) 2013 NVIDIA Corporation
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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/of.h>
-#include <linux/of_platform.h>
-#include <linux/clocksource.h>
-
-#include <asm/mach/arch.h>
-
-#include "board.h"
-#include "common.h"
-
-static void __init tegra114_dt_init(void)
-{
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-}
-
-static const char * const tegra114_dt_board_compat[] = {
-       "nvidia,tegra114",
-       NULL,
-};
-
-DT_MACHINE_START(TEGRA114_DT, "NVIDIA Tegra114 (Flattened Device Tree)")
-       .smp            = smp_ops(tegra_smp_ops),
-       .map_io         = tegra_map_common_io,
-       .init_early     = tegra114_init_early,
-       .init_irq       = tegra_dt_init_irq,
-       .init_time      = clocksource_of_init,
-       .init_machine   = tegra114_dt_init,
-       .init_late      = tegra_init_late,
-       .restart        = tegra_assert_system_reset,
-       .dt_compat      = tegra114_dt_board_compat,
-MACHINE_END
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
deleted file mode 100644 (file)
index a0edf25..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * nVidia Tegra device tree board support
- *
- * Copyright (C) 2010 Secret Lab Technologies, Ltd.
- * Copyright (C) 2010 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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/clocksource.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/serial_8250.h>
-#include <linux/clk.h>
-#include <linux/dma-mapping.h>
-#include <linux/irqdomain.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_fdt.h>
-#include <linux/of_platform.h>
-#include <linux/pda_power.h>
-#include <linux/platform_data/tegra_usb.h>
-#include <linux/io.h>
-#include <linux/i2c.h>
-#include <linux/i2c-tegra.h>
-#include <linux/usb/tegra_usb_phy.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/setup.h>
-
-#include "board.h"
-#include "common.h"
-#include "iomap.h"
-
-static struct tegra_ehci_platform_data tegra_ehci1_pdata = {
-       .operating_mode = TEGRA_USB_OTG,
-       .power_down_on_bus_suspend = 1,
-       .vbus_gpio = -1,
-};
-
-static struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = {
-       .reset_gpio = -1,
-       .clk = "cdev2",
-};
-
-static struct tegra_ehci_platform_data tegra_ehci2_pdata = {
-       .phy_config = &tegra_ehci2_ulpi_phy_config,
-       .operating_mode = TEGRA_USB_HOST,
-       .power_down_on_bus_suspend = 1,
-       .vbus_gpio = -1,
-};
-
-static struct tegra_ehci_platform_data tegra_ehci3_pdata = {
-       .operating_mode = TEGRA_USB_HOST,
-       .power_down_on_bus_suspend = 1,
-       .vbus_gpio = -1,
-};
-
-static struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
-       OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5000000, "tegra-ehci.0",
-                      &tegra_ehci1_pdata),
-       OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5004000, "tegra-ehci.1",
-                      &tegra_ehci2_pdata),
-       OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5008000, "tegra-ehci.2",
-                      &tegra_ehci3_pdata),
-       {}
-};
-
-static void __init tegra_dt_init(void)
-{
-       /*
-        * Finished with the static registrations now; fill in the missing
-        * devices
-        */
-       of_platform_populate(NULL, of_default_bus_match_table,
-                               tegra20_auxdata_lookup, NULL);
-}
-
-static void __init trimslice_init(void)
-{
-#ifdef CONFIG_TEGRA_PCI
-       int ret;
-
-       ret = tegra_pcie_init(true, true);
-       if (ret)
-               pr_err("tegra_pci_init() failed: %d\n", ret);
-#endif
-}
-
-static void __init harmony_init(void)
-{
-#ifdef CONFIG_TEGRA_PCI
-       int ret;
-
-       ret = harmony_pcie_init();
-       if (ret)
-               pr_err("harmony_pcie_init() failed: %d\n", ret);
-#endif
-}
-
-static void __init paz00_init(void)
-{
-       tegra_paz00_wifikill_init();
-}
-
-static struct {
-       char *machine;
-       void (*init)(void);
-} board_init_funcs[] = {
-       { "compulab,trimslice", trimslice_init },
-       { "nvidia,harmony", harmony_init },
-       { "compal,paz00", paz00_init },
-};
-
-static void __init tegra_dt_init_late(void)
-{
-       int i;
-
-       tegra_init_late();
-
-       for (i = 0; i < ARRAY_SIZE(board_init_funcs); i++) {
-               if (of_machine_is_compatible(board_init_funcs[i].machine)) {
-                       board_init_funcs[i].init();
-                       break;
-               }
-       }
-}
-
-static const char *tegra20_dt_board_compat[] = {
-       "nvidia,tegra20",
-       NULL
-};
-
-DT_MACHINE_START(TEGRA_DT, "nVidia Tegra20 (Flattened Device Tree)")
-       .map_io         = tegra_map_common_io,
-       .smp            = smp_ops(tegra_smp_ops),
-       .init_early     = tegra20_init_early,
-       .init_irq       = tegra_dt_init_irq,
-       .init_time      = clocksource_of_init,
-       .init_machine   = tegra_dt_init,
-       .init_late      = tegra_dt_init_late,
-       .restart        = tegra_assert_system_reset,
-       .dt_compat      = tegra20_dt_board_compat,
-MACHINE_END
diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c
deleted file mode 100644 (file)
index bf68567..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * arch/arm/mach-tegra/board-dt-tegra30.c
- *
- * NVIDIA Tegra30 device tree board support
- *
- * Copyright (C) 2011 NVIDIA Corporation
- *
- * Derived from:
- *
- * arch/arm/mach-tegra/board-dt-tegra20.c
- *
- * Copyright (C) 2010 Secret Lab Technologies, Ltd.
- * Copyright (C) 2010 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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/clocksource.h>
-#include <linux/kernel.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/of_fdt.h>
-#include <linux/of_irq.h>
-#include <linux/of_platform.h>
-
-#include <asm/mach/arch.h>
-
-#include "board.h"
-#include "common.h"
-#include "iomap.h"
-
-static void __init tegra30_dt_init(void)
-{
-       of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-}
-
-static const char *tegra30_dt_board_compat[] = {
-       "nvidia,tegra30",
-       NULL
-};
-
-DT_MACHINE_START(TEGRA30_DT, "NVIDIA Tegra30 (Flattened Device Tree)")
-       .smp            = smp_ops(tegra_smp_ops),
-       .map_io         = tegra_map_common_io,
-       .init_early     = tegra30_init_early,
-       .init_irq       = tegra_dt_init_irq,
-       .init_time      = clocksource_of_init,
-       .init_machine   = tegra30_dt_init,
-       .init_late      = tegra_init_late,
-       .restart        = tegra_assert_system_reset,
-       .dt_compat      = tegra30_dt_board_compat,
-MACHINE_END
index 3cdc1bb8254c6764c453fb978f748aae6d8f526a..d195db09ea32660f438eddb74cbc5f1cc2f5b751 100644 (file)
@@ -62,7 +62,11 @@ int __init harmony_pcie_init(void)
                goto err_reg;
        }
 
-       regulator_enable(regulator);
+       err = regulator_enable(regulator);
+       if (err) {
+               pr_err("%s: regulator_enable failed: %d\n", __func__, err);
+               goto err_en;
+       }
 
        err = tegra_pcie_init(true, true);
        if (err) {
@@ -74,6 +78,7 @@ int __init harmony_pcie_init(void)
 
 err_pcie:
        regulator_disable(regulator);
+err_en:
        regulator_put(regulator);
 err_reg:
        gpio_free(en_vdd_1v05);
index 86851c81a35093a44df58a52472be5d9ed2d7229..60431de585ca71c5a42c3646227cf80338ec4aec 100644 (file)
@@ -26,9 +26,7 @@
 
 void tegra_assert_system_reset(char mode, const char *cmd);
 
-void __init tegra20_init_early(void);
-void __init tegra30_init_early(void);
-void __init tegra114_init_early(void);
+void __init tegra_init_early(void);
 void __init tegra_map_common_io(void);
 void __init tegra_init_irq(void);
 void __init tegra_dt_init_irq(void);
index 5449a3f2977bc5d642891e00ce93087947ed17d8..eb1f3c8c74ccf0ac99839b97bec66551649584a9 100644 (file)
@@ -33,6 +33,7 @@
 #include "common.h"
 #include "fuse.h"
 #include "iomap.h"
+#include "irq.h"
 #include "pmc.h"
 #include "apbio.h"
 #include "sleep.h"
@@ -61,8 +62,10 @@ u32 tegra_uart_config[4] = {
 void __init tegra_dt_init_irq(void)
 {
        tegra_clocks_init();
+       tegra_pmc_init();
        tegra_init_irq();
        irqchip_init();
+       tegra_legacy_irq_syscore_init();
 }
 #endif
 
@@ -94,40 +97,18 @@ static void __init tegra_init_cache(void)
 
 }
 
-static void __init tegra_init_early(void)
+void __init tegra_init_early(void)
 {
        tegra_cpu_reset_handler_init();
        tegra_apb_io_init();
        tegra_init_fuse();
        tegra_init_cache();
-       tegra_pmc_init();
        tegra_powergate_init();
+       tegra_hotplug_init();
 }
 
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
-void __init tegra20_init_early(void)
-{
-       tegra_init_early();
-       tegra20_hotplug_init();
-}
-#endif
-
-#ifdef CONFIG_ARCH_TEGRA_3x_SOC
-void __init tegra30_init_early(void)
-{
-       tegra_init_early();
-       tegra30_hotplug_init();
-}
-#endif
-
-#ifdef CONFIG_ARCH_TEGRA_114_SOC
-void __init tegra114_init_early(void)
-{
-       tegra_init_early();
-}
-#endif
-
 void __init tegra_init_late(void)
 {
+       tegra_init_suspend();
        tegra_powergate_debugfs_init();
 }
index 825ced4f7a404a48adc8861e35930a024aff30b2..8bbbdebed882fb7a49e8de19fb30b363858af8b6 100644 (file)
@@ -130,10 +130,6 @@ static bool tegra20_cpu_cluster_power_down(struct cpuidle_device *dev,
                                           struct cpuidle_driver *drv,
                                           int index)
 {
-       struct cpuidle_state *state = &drv->states[index];
-       u32 cpu_on_time = state->exit_latency;
-       u32 cpu_off_time = state->target_residency - state->exit_latency;
-
        while (tegra20_cpu_is_resettable_soon())
                cpu_relax();
 
@@ -142,7 +138,7 @@ static bool tegra20_cpu_cluster_power_down(struct cpuidle_device *dev,
 
        clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
 
-       tegra_idle_lp2_last(cpu_on_time, cpu_off_time);
+       tegra_idle_lp2_last();
 
        clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
 
index 8b50cf4ddd6f04819e0c8a69bf4bf7eb9d28ddc5..c0931c8bb3e5f12c65aebef545c01e9305cb963d 100644 (file)
@@ -72,10 +72,6 @@ static bool tegra30_cpu_cluster_power_down(struct cpuidle_device *dev,
                                           struct cpuidle_driver *drv,
                                           int index)
 {
-       struct cpuidle_state *state = &drv->states[index];
-       u32 cpu_on_time = state->exit_latency;
-       u32 cpu_off_time = state->target_residency - state->exit_latency;
-
        /* All CPUs entering LP2 is not working.
         * Don't let CPU0 enter LP2 when any secondary CPU is online.
         */
@@ -86,7 +82,7 @@ static bool tegra30_cpu_cluster_power_down(struct cpuidle_device *dev,
 
        clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
 
-       tegra_idle_lp2_last(cpu_on_time, cpu_off_time);
+       tegra_idle_lp2_last();
 
        clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
 
@@ -102,12 +98,8 @@ static bool tegra30_cpu_core_power_down(struct cpuidle_device *dev,
 
        smp_wmb();
 
-       save_cpu_arch_register();
-
        cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
 
-       restore_cpu_arch_register();
-
        clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
 
        return true;
index f7db0782a6b6bdbcc256a06936831ee0d38f49e7..e035cd284a6eb5e3bf1268acb00da3c5784e5ced 100644 (file)
@@ -2,6 +2,7 @@
  * arch/arm/mach-tegra/fuse.c
  *
  * Copyright (C) 2010 Google, Inc.
+ * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
  *
  * Author:
  *     Colin Cross <ccross@android.com>
@@ -137,6 +138,9 @@ void tegra_init_fuse(void)
                tegra_fuse_spare_bit = TEGRA30_FUSE_SPARE_BIT;
                tegra_init_speedo_data = &tegra30_init_speedo_data;
                break;
+       case TEGRA114:
+               tegra_init_speedo_data = &tegra114_init_speedo_data;
+               break;
        default:
                pr_warn("Tegra: unknown chip id %d\n", tegra_chip_id);
                tegra_fuse_spare_bit = TEGRA20_FUSE_SPARE_BIT;
index da78434678c76029707c6df2d4f2b51a2f31a0bd..aacc00d059801bbfef78faa9251c276f9e4bf8da 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2010 Google, Inc.
+ * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
  *
  * Author:
  *     Colin Cross <ccross@android.com>
@@ -66,4 +67,10 @@ void tegra30_init_speedo_data(void);
 static inline void tegra30_init_speedo_data(void) {}
 #endif
 
+#ifdef CONFIG_ARCH_TEGRA_114_SOC
+void tegra114_init_speedo_data(void);
+#else
+static inline void tegra114_init_speedo_data(void) {}
+#endif
+
 #endif
index fd473f2b4c3d981e391a3fd8560c51f0b3ddedce..045c16f2dd51fae9d86551d91cb883f6e5d03aba 100644 (file)
@@ -7,8 +7,5 @@
 
 ENTRY(tegra_secondary_startup)
         bl      v7_invalidate_l1
-       /* Enable coresight */
-       mov32   r0, 0xC5ACCE55
-       mcr     p14, 0, r0, c7, c12, 6
         b       secondary_startup
 ENDPROC(tegra_secondary_startup)
index a599f6e36dea49768c6eb18d9550b3d04fb9c1db..8da9f78475da21f81ef314bbd7e9e04939398378 100644 (file)
@@ -1,8 +1,7 @@
 /*
- *
  *  Copyright (C) 2002 ARM Ltd.
  *  All Rights Reserved
- *  Copyright (c) 2010, 2012 NVIDIA Corporation. All rights reserved.
+ *  Copyright (c) 2010, 2012-2013, NVIDIA Corporation. All rights reserved.
  *
  * 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
@@ -15,6 +14,7 @@
 #include <asm/cacheflush.h>
 #include <asm/smp_plat.h>
 
+#include "fuse.h"
 #include "sleep.h"
 
 static void (*tegra_hotplug_shutdown)(void);
@@ -56,18 +56,13 @@ int tegra_cpu_disable(unsigned int cpu)
        return cpu == 0 ? -EPERM : 0;
 }
 
-#ifdef CONFIG_ARCH_TEGRA_2x_SOC
-extern void tegra20_hotplug_shutdown(void);
-void __init tegra20_hotplug_init(void)
+void __init tegra_hotplug_init(void)
 {
-       tegra_hotplug_shutdown = tegra20_hotplug_shutdown;
-}
-#endif
+       if (!IS_ENABLED(CONFIG_HOTPLUG_CPU))
+               return;
 
-#ifdef CONFIG_ARCH_TEGRA_3x_SOC
-extern void tegra30_hotplug_shutdown(void);
-void __init tegra30_hotplug_init(void)
-{
-       tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
+       if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20)
+               tegra_hotplug_shutdown = tegra20_hotplug_shutdown;
+       if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30)
+               tegra_hotplug_shutdown = tegra30_hotplug_shutdown;
 }
-#endif
index 1952e82797ccd3f45eecb88e8be523dd0a3d8104..0de4eed1493dca411af5b91bbee8e2b0b6f87ed9 100644 (file)
@@ -4,7 +4,7 @@
  * Author:
  *     Colin Cross <ccross@android.com>
  *
- * Copyright (C) 2010, NVIDIA Corporation
+ * Copyright (C) 2010,2013, NVIDIA Corporation
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -23,6 +23,7 @@
 #include <linux/io.h>
 #include <linux/of.h>
 #include <linux/irqchip/arm-gic.h>
+#include <linux/syscore_ops.h>
 
 #include "board.h"
 #include "iomap.h"
@@ -43,6 +44,7 @@
 #define ICTLR_COP_IEP_CLASS    0x3c
 
 #define FIRST_LEGACY_IRQ 32
+#define TEGRA_MAX_NUM_ICTLRS   5
 
 #define SGI_MASK 0xFFFF
 
@@ -56,6 +58,15 @@ static void __iomem *ictlr_reg_base[] = {
        IO_ADDRESS(TEGRA_QUINARY_ICTLR_BASE),
 };
 
+#ifdef CONFIG_PM_SLEEP
+static u32 cop_ier[TEGRA_MAX_NUM_ICTLRS];
+static u32 cop_iep[TEGRA_MAX_NUM_ICTLRS];
+static u32 cpu_ier[TEGRA_MAX_NUM_ICTLRS];
+static u32 cpu_iep[TEGRA_MAX_NUM_ICTLRS];
+
+static u32 ictlr_wake_mask[TEGRA_MAX_NUM_ICTLRS];
+#endif
+
 bool tegra_pending_sgi(void)
 {
        u32 pending_set;
@@ -125,6 +136,87 @@ static int tegra_retrigger(struct irq_data *d)
        return 1;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int tegra_set_wake(struct irq_data *d, unsigned int enable)
+{
+       u32 irq = d->irq;
+       u32 index, mask;
+
+       if (irq < FIRST_LEGACY_IRQ ||
+               irq >= FIRST_LEGACY_IRQ + num_ictlrs * 32)
+               return -EINVAL;
+
+       index = ((irq - FIRST_LEGACY_IRQ) / 32);
+       mask = BIT((irq - FIRST_LEGACY_IRQ) % 32);
+       if (enable)
+               ictlr_wake_mask[index] |= mask;
+       else
+               ictlr_wake_mask[index] &= ~mask;
+
+       return 0;
+}
+
+static int tegra_legacy_irq_suspend(void)
+{
+       unsigned long flags;
+       int i;
+
+       local_irq_save(flags);
+       for (i = 0; i < num_ictlrs; i++) {
+               void __iomem *ictlr = ictlr_reg_base[i];
+               /* Save interrupt state */
+               cpu_ier[i] = readl_relaxed(ictlr + ICTLR_CPU_IER);
+               cpu_iep[i] = readl_relaxed(ictlr + ICTLR_CPU_IEP_CLASS);
+               cop_ier[i] = readl_relaxed(ictlr + ICTLR_COP_IER);
+               cop_iep[i] = readl_relaxed(ictlr + ICTLR_COP_IEP_CLASS);
+
+               /* Disable COP interrupts */
+               writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
+
+               /* Disable CPU interrupts */
+               writel_relaxed(~0ul, ictlr + ICTLR_CPU_IER_CLR);
+
+               /* Enable the wakeup sources of ictlr */
+               writel_relaxed(ictlr_wake_mask[i], ictlr + ICTLR_CPU_IER_SET);
+       }
+       local_irq_restore(flags);
+
+       return 0;
+}
+
+static void tegra_legacy_irq_resume(void)
+{
+       unsigned long flags;
+       int i;
+
+       local_irq_save(flags);
+       for (i = 0; i < num_ictlrs; i++) {
+               void __iomem *ictlr = ictlr_reg_base[i];
+               writel_relaxed(cpu_iep[i], ictlr + ICTLR_CPU_IEP_CLASS);
+               writel_relaxed(~0ul, ictlr + ICTLR_CPU_IER_CLR);
+               writel_relaxed(cpu_ier[i], ictlr + ICTLR_CPU_IER_SET);
+               writel_relaxed(cop_iep[i], ictlr + ICTLR_COP_IEP_CLASS);
+               writel_relaxed(~0ul, ictlr + ICTLR_COP_IER_CLR);
+               writel_relaxed(cop_ier[i], ictlr + ICTLR_COP_IER_SET);
+       }
+       local_irq_restore(flags);
+}
+
+static struct syscore_ops tegra_legacy_irq_syscore_ops = {
+       .suspend = tegra_legacy_irq_suspend,
+       .resume = tegra_legacy_irq_resume,
+};
+
+int tegra_legacy_irq_syscore_init(void)
+{
+       register_syscore_ops(&tegra_legacy_irq_syscore_ops);
+
+       return 0;
+}
+#else
+#define tegra_set_wake NULL
+#endif
+
 void __init tegra_init_irq(void)
 {
        int i;
@@ -150,6 +242,8 @@ void __init tegra_init_irq(void)
        gic_arch_extn.irq_mask = tegra_mask;
        gic_arch_extn.irq_unmask = tegra_unmask;
        gic_arch_extn.irq_retrigger = tegra_retrigger;
+       gic_arch_extn.irq_set_wake = tegra_set_wake;
+       gic_arch_extn.flags = IRQCHIP_MASK_ON_SUSPEND;
 
        /*
         * Check if there is a devicetree present, since the GIC will be
index 5142649bba05513b46ead7a336b3082141ac41da..bc05ce5613fbf79195159f8eef03324992a5c73d 100644 (file)
 
 bool tegra_pending_sgi(void);
 
+#ifdef CONFIG_PM_SLEEP
+int tegra_legacy_irq_syscore_init(void);
+#else
+static inline int tegra_legacy_irq_syscore_init(void) { return 0; }
+#endif
+
 #endif
index 2c6b3d55213b49f16ee256548279b1742111bd20..516aab28fe34217a8f99576df6b89b99a82f39f9 100644 (file)
 #include <asm/smp_scu.h>
 #include <asm/smp_plat.h>
 
-#include <mach/powergate.h>
-
 #include "fuse.h"
 #include "flowctrl.h"
 #include "reset.h"
+#include "pmc.h"
 
 #include "common.h"
 #include "iomap.h"
 
-extern void tegra_secondary_startup(void);
-
 static cpumask_t tegra_cpu_init_mask;
 
-#define EVP_CPU_RESET_VECTOR \
-       (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100)
-
 static void __cpuinit tegra_secondary_init(unsigned int cpu)
 {
        /*
@@ -54,25 +48,43 @@ static void __cpuinit tegra_secondary_init(unsigned int cpu)
        cpumask_set_cpu(cpu, &tegra_cpu_init_mask);
 }
 
-static int tegra20_power_up_cpu(unsigned int cpu)
+
+static int tegra20_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
-       /* Enable the CPU clock. */
-       tegra_enable_cpu_clock(cpu);
+       cpu = cpu_logical_map(cpu);
+
+       /*
+        * Force the CPU into reset. The CPU must remain in reset when
+        * the flow controller state is cleared (which will cause the
+        * flow controller to stop driving reset if the CPU has been
+        * power-gated via the flow controller). This will have no
+        * effect on first boot of the CPU since it should already be
+        * in reset.
+        */
+       tegra_put_cpu_in_reset(cpu);
 
-       /* Clear flow controller CSR. */
-       flowctrl_write_cpu_csr(cpu, 0);
+       /*
+        * Unhalt the CPU. If the flow controller was used to
+        * power-gate the CPU this will cause the flow controller to
+        * stop driving reset. The CPU will remain in reset because the
+        * clock and reset block is now driving reset.
+        */
+       flowctrl_write_cpu_halt(cpu, 0);
 
+       tegra_enable_cpu_clock(cpu);
+       flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */
+       tegra_cpu_out_of_reset(cpu);
        return 0;
 }
 
-static int tegra30_power_up_cpu(unsigned int cpu)
+static int tegra30_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
-       int ret, pwrgateid;
+       int ret;
        unsigned long timeout;
 
-       pwrgateid = tegra_cpu_powergate_id(cpu);
-       if (pwrgateid < 0)
-               return pwrgateid;
+       cpu = cpu_logical_map(cpu);
+       tegra_put_cpu_in_reset(cpu);
+       flowctrl_write_cpu_halt(cpu, 0);
 
        /*
         * The power up sequence of cold boot CPU and warm boot CPU
@@ -85,13 +97,13 @@ static int tegra30_power_up_cpu(unsigned int cpu)
         * the IO clamps.
         * For cold boot CPU, do not wait. After the cold boot CPU be
         * booted, it will run to tegra_secondary_init() and set
-        * tegra_cpu_init_mask which influences what tegra30_power_up_cpu()
+        * tegra_cpu_init_mask which influences what tegra30_boot_secondary()
         * next time around.
         */
        if (cpumask_test_cpu(cpu, &tegra_cpu_init_mask)) {
                timeout = jiffies + msecs_to_jiffies(50);
                do {
-                       if (!tegra_powergate_is_powered(pwrgateid))
+                       if (tegra_pmc_cpu_is_powered(cpu))
                                goto remove_clamps;
                        udelay(10);
                } while (time_before(jiffies, timeout));
@@ -103,14 +115,14 @@ static int tegra30_power_up_cpu(unsigned int cpu)
         * be un-gated by un-toggling the power gate register
         * manually.
         */
-       if (!tegra_powergate_is_powered(pwrgateid)) {
-               ret = tegra_powergate_power_on(pwrgateid);
+       if (!tegra_pmc_cpu_is_powered(cpu)) {
+               ret = tegra_pmc_cpu_power_on(cpu);
                if (ret)
                        return ret;
 
                /* Wait for the power to come up. */
                timeout = jiffies + msecs_to_jiffies(100);
-               while (tegra_powergate_is_powered(pwrgateid)) {
+               while (tegra_pmc_cpu_is_powered(cpu)) {
                        if (time_after(jiffies, timeout))
                                return -ETIMEDOUT;
                        udelay(10);
@@ -123,57 +135,34 @@ remove_clamps:
        udelay(10);
 
        /* Remove I/O clamps. */
-       ret = tegra_powergate_remove_clamping(pwrgateid);
-       udelay(10);
+       ret = tegra_pmc_cpu_remove_clamping(cpu);
+       if (ret)
+               return ret;
 
-       /* Clear flow controller CSR. */
-       flowctrl_write_cpu_csr(cpu, 0);
+       udelay(10);
 
+       flowctrl_write_cpu_csr(cpu, 0); /* Clear flow controller CSR. */
+       tegra_cpu_out_of_reset(cpu);
        return 0;
 }
 
-static int __cpuinit tegra_boot_secondary(unsigned int cpu, struct task_struct *idle)
+static int tegra114_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
-       int status;
-
        cpu = cpu_logical_map(cpu);
+       return tegra_pmc_cpu_power_on(cpu);
+}
 
-       /*
-        * Force the CPU into reset. The CPU must remain in reset when the
-        * flow controller state is cleared (which will cause the flow
-        * controller to stop driving reset if the CPU has been power-gated
-        * via the flow controller). This will have no effect on first boot
-        * of the CPU since it should already be in reset.
-        */
-       tegra_put_cpu_in_reset(cpu);
-
-       /*
-        * Unhalt the CPU. If the flow controller was used to power-gate the
-        * CPU this will cause the flow controller to stop driving reset.
-        * The CPU will remain in reset because the clock and reset block
-        * is now driving reset.
-        */
-       flowctrl_write_cpu_halt(cpu, 0);
-
-       switch (tegra_chip_id) {
-       case TEGRA20:
-               status = tegra20_power_up_cpu(cpu);
-               break;
-       case TEGRA30:
-               status = tegra30_power_up_cpu(cpu);
-               break;
-       default:
-               status = -EINVAL;
-               break;
-       }
-
-       if (status)
-               goto done;
-
-       /* Take the CPU out of reset. */
-       tegra_cpu_out_of_reset(cpu);
-done:
-       return status;
+static int __cpuinit tegra_boot_secondary(unsigned int cpu,
+                                         struct task_struct *idle)
+{
+       if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && tegra_chip_id == TEGRA20)
+               return tegra20_boot_secondary(cpu, idle);
+       if (IS_ENABLED(CONFIG_ARCH_TEGRA_3x_SOC) && tegra_chip_id == TEGRA30)
+               return tegra30_boot_secondary(cpu, idle);
+       if (IS_ENABLED(CONFIG_ARCH_TEGRA_114_SOC) && tegra_chip_id == TEGRA114)
+               return tegra114_boot_secondary(cpu, idle);
+
+       return -EINVAL;
 }
 
 static void __init tegra_smp_prepare_cpus(unsigned int max_cpus)
index 523604de666f6f6369330fabadbedb2b05750cf9..84d8742bdb1efa2ebc28b32d92853005592c6626 100644 (file)
@@ -22,7 +22,7 @@
 #include <linux/cpumask.h>
 #include <linux/delay.h>
 #include <linux/cpu_pm.h>
-#include <linux/clk.h>
+#include <linux/suspend.h>
 #include <linux/err.h>
 #include <linux/clk/tegra.h>
 
 #include "reset.h"
 #include "flowctrl.h"
 #include "fuse.h"
+#include "pmc.h"
 #include "sleep.h"
-
-#define TEGRA_POWER_CPU_PWRREQ_OE      (1 << 16)  /* CPU pwr req enable */
-
-#define PMC_CTRL               0x0
-#define PMC_CPUPWRGOOD_TIMER   0xc8
-#define PMC_CPUPWROFF_TIMER    0xcc
+#include "pmc.h"
 
 #ifdef CONFIG_PM_SLEEP
-static unsigned int g_diag_reg;
 static DEFINE_SPINLOCK(tegra_lp2_lock);
-static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
-static struct clk *tegra_pclk;
 void (*tegra_tear_down_cpu)(void);
 
-void save_cpu_arch_register(void)
-{
-       /* read diagnostic register */
-       asm("mrc p15, 0, %0, c15, c0, 1" : "=r"(g_diag_reg) : : "cc");
-       return;
-}
-
-void restore_cpu_arch_register(void)
-{
-       /* write diagnostic register */
-       asm("mcr p15, 0, %0, c15, c0, 1" : : "r"(g_diag_reg) : "cc");
-       return;
-}
-
-static void set_power_timers(unsigned long us_on, unsigned long us_off)
-{
-       unsigned long long ticks;
-       unsigned long long pclk;
-       unsigned long rate;
-       static unsigned long tegra_last_pclk;
-
-       if (tegra_pclk == NULL) {
-               tegra_pclk = clk_get_sys(NULL, "pclk");
-               WARN_ON(IS_ERR(tegra_pclk));
-       }
-
-       rate = clk_get_rate(tegra_pclk);
-
-       if (WARN_ON_ONCE(rate <= 0))
-               pclk = 100000000;
-       else
-               pclk = rate;
-
-       if ((rate != tegra_last_pclk)) {
-               ticks = (us_on * pclk) + 999999ull;
-               do_div(ticks, 1000000);
-               writel((unsigned long)ticks, pmc + PMC_CPUPWRGOOD_TIMER);
-
-               ticks = (us_off * pclk) + 999999ull;
-               do_div(ticks, 1000000);
-               writel((unsigned long)ticks, pmc + PMC_CPUPWROFF_TIMER);
-               wmb();
-       }
-       tegra_last_pclk = pclk;
-}
-
 /*
  * restore_cpu_complex
  *
@@ -119,8 +66,6 @@ static void restore_cpu_complex(void)
        tegra_cpu_clock_resume();
 
        flowctrl_cpu_suspend_exit(cpu);
-
-       restore_cpu_arch_register();
 }
 
 /*
@@ -145,8 +90,6 @@ static void suspend_cpu_complex(void)
        tegra_cpu_clock_suspend();
 
        flowctrl_cpu_suspend_enter(cpu);
-
-       save_cpu_arch_register();
 }
 
 void tegra_clear_cpu_in_lp2(int phy_cpu_id)
@@ -197,16 +140,9 @@ static int tegra_sleep_cpu(unsigned long v2p)
        return 0;
 }
 
-void tegra_idle_lp2_last(u32 cpu_on_time, u32 cpu_off_time)
+void tegra_idle_lp2_last(void)
 {
-       u32 mode;
-
-       /* Only the last cpu down does the final suspend steps */
-       mode = readl(pmc + PMC_CTRL);
-       mode |= TEGRA_POWER_CPU_PWRREQ_OE;
-       writel(mode, pmc + PMC_CTRL);
-
-       set_power_timers(cpu_on_time, cpu_off_time);
+       tegra_pmc_pm_set(TEGRA_SUSPEND_LP2);
 
        cpu_cluster_pm_enter();
        suspend_cpu_complex();
@@ -216,4 +152,81 @@ void tegra_idle_lp2_last(u32 cpu_on_time, u32 cpu_off_time)
        restore_cpu_complex();
        cpu_cluster_pm_exit();
 }
+
+enum tegra_suspend_mode tegra_pm_validate_suspend_mode(
+                               enum tegra_suspend_mode mode)
+{
+       /* Tegra114 didn't support any suspending mode yet. */
+       if (tegra_chip_id == TEGRA114)
+               return TEGRA_SUSPEND_NONE;
+
+       /*
+        * The Tegra devices only support suspending to LP2 currently.
+        */
+       if (mode > TEGRA_SUSPEND_LP2)
+               return TEGRA_SUSPEND_LP2;
+
+       return mode;
+}
+
+static const char *lp_state[TEGRA_MAX_SUSPEND_MODE] = {
+       [TEGRA_SUSPEND_NONE] = "none",
+       [TEGRA_SUSPEND_LP2] = "LP2",
+       [TEGRA_SUSPEND_LP1] = "LP1",
+       [TEGRA_SUSPEND_LP0] = "LP0",
+};
+
+static int __cpuinit tegra_suspend_enter(suspend_state_t state)
+{
+       enum tegra_suspend_mode mode = tegra_pmc_get_suspend_mode();
+
+       if (WARN_ON(mode < TEGRA_SUSPEND_NONE ||
+                   mode >= TEGRA_MAX_SUSPEND_MODE))
+               return -EINVAL;
+
+       pr_info("Entering suspend state %s\n", lp_state[mode]);
+
+       tegra_pmc_pm_set(mode);
+
+       local_fiq_disable();
+
+       suspend_cpu_complex();
+       switch (mode) {
+       case TEGRA_SUSPEND_LP2:
+               tegra_set_cpu_in_lp2(0);
+               break;
+       default:
+               break;
+       }
+
+       cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
+
+       switch (mode) {
+       case TEGRA_SUSPEND_LP2:
+               tegra_clear_cpu_in_lp2(0);
+               break;
+       default:
+               break;
+       }
+       restore_cpu_complex();
+
+       local_fiq_enable();
+
+       return 0;
+}
+
+static const struct platform_suspend_ops tegra_suspend_ops = {
+       .valid          = suspend_valid_only_mem,
+       .enter          = tegra_suspend_enter,
+};
+
+void __init tegra_init_suspend(void)
+{
+       if (tegra_pmc_get_suspend_mode() == TEGRA_SUSPEND_NONE)
+               return;
+
+       tegra_pmc_suspend_init();
+
+       suspend_set_ops(&tegra_suspend_ops);
+}
 #endif
index 787335cc964cfb38d96f12fa059b3a50331982b0..9d2d038bf12e06bdee8f9ee2e2450e58bacbc063 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef _MACH_TEGRA_PM_H_
 #define _MACH_TEGRA_PM_H_
 
+#include "pmc.h"
+
 extern unsigned long l2x0_saved_regs_addr;
 
 void save_cpu_arch_register(void);
@@ -29,7 +31,20 @@ void restore_cpu_arch_register(void);
 void tegra_clear_cpu_in_lp2(int phy_cpu_id);
 bool tegra_set_cpu_in_lp2(int phy_cpu_id);
 
-void tegra_idle_lp2_last(u32 cpu_on_time, u32 cpu_off_time);
+void tegra_idle_lp2_last(void);
 extern void (*tegra_tear_down_cpu)(void);
 
+#ifdef CONFIG_PM_SLEEP
+enum tegra_suspend_mode tegra_pm_validate_suspend_mode(
+                               enum tegra_suspend_mode mode);
+void tegra_init_suspend(void);
+#else
+enum tegra_suspend_mode tegra_pm_validate_suspend_mode(
+                               enum tegra_suspend_mode mode)
+{
+       return TEGRA_SUSPEND_NONE;
+}
+static inline void tegra_init_suspend(void) {}
+#endif
+
 #endif /* _MACH_TEGRA_PM_H_ */
index d4fdb5fcec20955c95a4f0199efb1ae180f72409..32360e540ce6a8536c41d94577ab21b6d2674693 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
+ * Copyright (C) 2012,2013 NVIDIA CORPORATION. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
  */
 
 #include <linux/kernel.h>
+#include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 
-#include "iomap.h"
+#include "fuse.h"
+#include "pm.h"
+#include "pmc.h"
+#include "sleep.h"
 
-#define PMC_CTRL               0x0
-#define PMC_CTRL_INTR_LOW      (1 << 17)
+#define TEGRA_POWER_EFFECT_LP0         (1 << 14)  /* LP0 when CPU pwr gated */
+#define TEGRA_POWER_CPU_PWRREQ_POLARITY        (1 << 15)  /* CPU pwr req polarity */
+#define TEGRA_POWER_CPU_PWRREQ_OE      (1 << 16)  /* CPU pwr req enable */
+
+#define PMC_CTRL                       0x0
+#define PMC_CTRL_INTR_LOW              (1 << 17)
+#define PMC_PWRGATE_TOGGLE             0x30
+#define PMC_PWRGATE_TOGGLE_START       (1 << 8)
+#define PMC_REMOVE_CLAMPING            0x34
+#define PMC_PWRGATE_STATUS             0x38
+
+#define PMC_CPUPWRGOOD_TIMER   0xc8
+#define PMC_CPUPWROFF_TIMER    0xcc
+
+#define TEGRA_POWERGATE_PCIE   3
+#define TEGRA_POWERGATE_VDEC   4
+#define TEGRA_POWERGATE_CPU1   9
+#define TEGRA_POWERGATE_CPU2   10
+#define TEGRA_POWERGATE_CPU3   11
+
+static u8 tegra_cpu_domains[] = {
+       0xFF,                   /* not available for CPU0 */
+       TEGRA_POWERGATE_CPU1,
+       TEGRA_POWERGATE_CPU2,
+       TEGRA_POWERGATE_CPU3,
+};
+static DEFINE_SPINLOCK(tegra_powergate_lock);
+
+static void __iomem *tegra_pmc_base;
+static bool tegra_pmc_invert_interrupt;
+static struct clk *tegra_pclk;
+
+struct pmc_pm_data {
+       u32 cpu_good_time;      /* CPU power good time in uS */
+       u32 cpu_off_time;       /* CPU power off time in uS */
+       u32 core_osc_time;      /* Core power good osc time in uS */
+       u32 core_pmu_time;      /* Core power good pmu time in uS */
+       u32 core_off_time;      /* Core power off time in uS */
+       bool corereq_high;      /* Core power request active-high */
+       bool sysclkreq_high;    /* System clock request active-high */
+       bool combined_req;      /* Combined pwr req for CPU & Core */
+       bool cpu_pwr_good_en;   /* CPU power good signal is enabled */
+       u32 lp0_vec_phy_addr;   /* The phy addr of LP0 warm boot code */
+       u32 lp0_vec_size;       /* The size of LP0 warm boot code */
+       enum tegra_suspend_mode suspend_mode;
+};
+static struct pmc_pm_data pmc_pm_data;
 
 static inline u32 tegra_pmc_readl(u32 reg)
 {
-       return readl(IO_ADDRESS(TEGRA_PMC_BASE + reg));
+       return readl(tegra_pmc_base + reg);
 }
 
 static inline void tegra_pmc_writel(u32 val, u32 reg)
 {
-       writel(val, IO_ADDRESS(TEGRA_PMC_BASE + reg));
+       writel(val, tegra_pmc_base + reg);
+}
+
+static int tegra_pmc_get_cpu_powerdomain_id(int cpuid)
+{
+       if (cpuid <= 0 || cpuid >= num_possible_cpus())
+               return -EINVAL;
+       return tegra_cpu_domains[cpuid];
+}
+
+static bool tegra_pmc_powergate_is_powered(int id)
+{
+       return (tegra_pmc_readl(PMC_PWRGATE_STATUS) >> id) & 1;
+}
+
+static int tegra_pmc_powergate_set(int id, bool new_state)
+{
+       bool old_state;
+       unsigned long flags;
+
+       spin_lock_irqsave(&tegra_powergate_lock, flags);
+
+       old_state = tegra_pmc_powergate_is_powered(id);
+       WARN_ON(old_state == new_state);
+
+       tegra_pmc_writel(PMC_PWRGATE_TOGGLE_START | id, PMC_PWRGATE_TOGGLE);
+
+       spin_unlock_irqrestore(&tegra_powergate_lock, flags);
+
+       return 0;
+}
+
+static int tegra_pmc_powergate_remove_clamping(int id)
+{
+       u32 mask;
+
+       /*
+        * Tegra has a bug where PCIE and VDE clamping masks are
+        * swapped relatively to the partition ids.
+        */
+       if (id ==  TEGRA_POWERGATE_VDEC)
+               mask = (1 << TEGRA_POWERGATE_PCIE);
+       else if (id == TEGRA_POWERGATE_PCIE)
+               mask = (1 << TEGRA_POWERGATE_VDEC);
+       else
+               mask = (1 << id);
+
+       tegra_pmc_writel(mask, PMC_REMOVE_CLAMPING);
+
+       return 0;
+}
+
+bool tegra_pmc_cpu_is_powered(int cpuid)
+{
+       int id;
+
+       id = tegra_pmc_get_cpu_powerdomain_id(cpuid);
+       if (id < 0)
+               return false;
+       return tegra_pmc_powergate_is_powered(id);
 }
 
-#ifdef CONFIG_OF
+int tegra_pmc_cpu_power_on(int cpuid)
+{
+       int id;
+
+       id = tegra_pmc_get_cpu_powerdomain_id(cpuid);
+       if (id < 0)
+               return id;
+       return tegra_pmc_powergate_set(id, true);
+}
+
+int tegra_pmc_cpu_remove_clamping(int cpuid)
+{
+       int id;
+
+       id = tegra_pmc_get_cpu_powerdomain_id(cpuid);
+       if (id < 0)
+               return id;
+       return tegra_pmc_powergate_remove_clamping(id);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static void set_power_timers(u32 us_on, u32 us_off, unsigned long rate)
+{
+       unsigned long long ticks;
+       unsigned long long pclk;
+       static unsigned long tegra_last_pclk;
+
+       if (WARN_ON_ONCE(rate <= 0))
+               pclk = 100000000;
+       else
+               pclk = rate;
+
+       if ((rate != tegra_last_pclk)) {
+               ticks = (us_on * pclk) + 999999ull;
+               do_div(ticks, 1000000);
+               tegra_pmc_writel((unsigned long)ticks, PMC_CPUPWRGOOD_TIMER);
+
+               ticks = (us_off * pclk) + 999999ull;
+               do_div(ticks, 1000000);
+               tegra_pmc_writel((unsigned long)ticks, PMC_CPUPWROFF_TIMER);
+               wmb();
+       }
+       tegra_last_pclk = pclk;
+}
+
+enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void)
+{
+       return pmc_pm_data.suspend_mode;
+}
+
+void tegra_pmc_pm_set(enum tegra_suspend_mode mode)
+{
+       u32 reg;
+       unsigned long rate = 0;
+
+       reg = tegra_pmc_readl(PMC_CTRL);
+       reg |= TEGRA_POWER_CPU_PWRREQ_OE;
+       reg &= ~TEGRA_POWER_EFFECT_LP0;
+
+       switch (mode) {
+       case TEGRA_SUSPEND_LP2:
+               rate = clk_get_rate(tegra_pclk);
+               break;
+       default:
+               break;
+       }
+
+       set_power_timers(pmc_pm_data.cpu_good_time, pmc_pm_data.cpu_off_time,
+                        rate);
+
+       tegra_pmc_writel(reg, PMC_CTRL);
+}
+
+void tegra_pmc_suspend_init(void)
+{
+       u32 reg;
+
+       /* Always enable CPU power request */
+       reg = tegra_pmc_readl(PMC_CTRL);
+       reg |= TEGRA_POWER_CPU_PWRREQ_OE;
+       tegra_pmc_writel(reg, PMC_CTRL);
+}
+#endif
+
 static const struct of_device_id matches[] __initconst = {
+       { .compatible = "nvidia,tegra114-pmc" },
+       { .compatible = "nvidia,tegra30-pmc" },
        { .compatible = "nvidia,tegra20-pmc" },
        { }
 };
-#endif
 
-void __init tegra_pmc_init(void)
+static void tegra_pmc_parse_dt(void)
 {
-       /*
-        * For now, Harmony is the only board that uses the PMC, and it wants
-        * the signal inverted. Seaboard would too if it used the PMC.
-        * Hopefully by the time other boards want to use the PMC, everything
-        * will be device-tree, or they also want it inverted.
-        */
-       bool invert_interrupt = true;
-       u32 val;
+       struct device_node *np;
+       u32 prop;
+       enum tegra_suspend_mode suspend_mode;
+       u32 core_good_time[2] = {0, 0};
+       u32 lp0_vec[2] = {0, 0};
 
-#ifdef CONFIG_OF
-       if (of_have_populated_dt()) {
-               struct device_node *np;
+       np = of_find_matching_node(NULL, matches);
+       BUG_ON(!np);
 
-               invert_interrupt = false;
+       tegra_pmc_base = of_iomap(np, 0);
 
-               np = of_find_matching_node(NULL, matches);
-               if (np) {
-                       if (of_find_property(np, "nvidia,invert-interrupt",
-                                               NULL))
-                               invert_interrupt = true;
+       tegra_pmc_invert_interrupt = of_property_read_bool(np,
+                                    "nvidia,invert-interrupt");
+       tegra_pclk = of_clk_get_by_name(np, "pclk");
+       WARN_ON(IS_ERR(tegra_pclk));
+
+       /* Grabbing the power management configurations */
+       if (of_property_read_u32(np, "nvidia,suspend-mode", &prop)) {
+               suspend_mode = TEGRA_SUSPEND_NONE;
+       } else {
+               switch (prop) {
+               case 0:
+                       suspend_mode = TEGRA_SUSPEND_LP0;
+                       break;
+               case 1:
+                       suspend_mode = TEGRA_SUSPEND_LP1;
+                       break;
+               case 2:
+                       suspend_mode = TEGRA_SUSPEND_LP2;
+                       break;
+               default:
+                       suspend_mode = TEGRA_SUSPEND_NONE;
+                       break;
                }
        }
-#endif
+       suspend_mode = tegra_pm_validate_suspend_mode(suspend_mode);
+
+       if (of_property_read_u32(np, "nvidia,cpu-pwr-good-time", &prop))
+               suspend_mode = TEGRA_SUSPEND_NONE;
+       pmc_pm_data.cpu_good_time = prop;
+
+       if (of_property_read_u32(np, "nvidia,cpu-pwr-off-time", &prop))
+               suspend_mode = TEGRA_SUSPEND_NONE;
+       pmc_pm_data.cpu_off_time = prop;
+
+       if (of_property_read_u32_array(np, "nvidia,core-pwr-good-time",
+                       core_good_time, ARRAY_SIZE(core_good_time)))
+               suspend_mode = TEGRA_SUSPEND_NONE;
+       pmc_pm_data.core_osc_time = core_good_time[0];
+       pmc_pm_data.core_pmu_time = core_good_time[1];
+
+       if (of_property_read_u32(np, "nvidia,core-pwr-off-time",
+                                &prop))
+               suspend_mode = TEGRA_SUSPEND_NONE;
+       pmc_pm_data.core_off_time = prop;
+
+       pmc_pm_data.corereq_high = of_property_read_bool(np,
+                               "nvidia,core-power-req-active-high");
+
+       pmc_pm_data.sysclkreq_high = of_property_read_bool(np,
+                               "nvidia,sys-clock-req-active-high");
+
+       pmc_pm_data.combined_req = of_property_read_bool(np,
+                               "nvidia,combined-power-req");
+
+       pmc_pm_data.cpu_pwr_good_en = of_property_read_bool(np,
+                               "nvidia,cpu-pwr-good-en");
+
+       if (of_property_read_u32_array(np, "nvidia,lp0-vec", lp0_vec,
+                                      ARRAY_SIZE(lp0_vec)))
+               if (suspend_mode == TEGRA_SUSPEND_LP0)
+                       suspend_mode = TEGRA_SUSPEND_LP1;
+
+       pmc_pm_data.lp0_vec_phy_addr = lp0_vec[0];
+       pmc_pm_data.lp0_vec_size = lp0_vec[1];
+
+       pmc_pm_data.suspend_mode = suspend_mode;
+}
+
+void __init tegra_pmc_init(void)
+{
+       u32 val;
+
+       tegra_pmc_parse_dt();
 
        val = tegra_pmc_readl(PMC_CTRL);
-       if (invert_interrupt)
+       if (tegra_pmc_invert_interrupt)
                val |= PMC_CTRL_INTR_LOW;
        else
                val &= ~PMC_CTRL_INTR_LOW;
index 8995ee4a87681dd80a63c990b05c324955261f24..e1c2df272f7dc6e723ea4765731fa05cb9baf0e7 100644 (file)
 #ifndef __MACH_TEGRA_PMC_H
 #define __MACH_TEGRA_PMC_H
 
+enum tegra_suspend_mode {
+       TEGRA_SUSPEND_NONE = 0,
+       TEGRA_SUSPEND_LP2,      /* CPU voltage off */
+       TEGRA_SUSPEND_LP1,      /* CPU voltage off, DRAM self-refresh */
+       TEGRA_SUSPEND_LP0,      /* CPU + core voltage off, DRAM self-refresh */
+       TEGRA_MAX_SUSPEND_MODE,
+};
+
+#ifdef CONFIG_PM_SLEEP
+enum tegra_suspend_mode tegra_pmc_get_suspend_mode(void);
+void tegra_pmc_pm_set(enum tegra_suspend_mode mode);
+void tegra_pmc_suspend_init(void);
+#endif
+
+bool tegra_pmc_cpu_is_powered(int cpuid);
+int tegra_pmc_cpu_power_on(int cpuid);
+int tegra_pmc_cpu_remove_clamping(int cpuid);
+
 void tegra_pmc_init(void);
 
 #endif
index 54382ceade4a516b0389626a511a7358af95a4d9..1676aba5e7b84ecf97c577b2ccc8d5ff565308dd 100644 (file)
@@ -41,9 +41,6 @@
  */
 ENTRY(tegra_resume)
        bl      v7_invalidate_l1
-       /* Enable coresight */
-       mov32   r0, 0xC5ACCE55
-       mcr     p14, 0, r0, c7, c12, 6
 
        cpu_id  r0
        cmp     r0, #0                          @ CPU0?
@@ -99,6 +96,8 @@ ENTRY(__tegra_cpu_reset_handler_start)
  *
  * Register usage within the reset handler:
  *
+ *      Others: scratch
+ *      R6  = SoC ID << 8
  *      R7  = CPU present (to the OS) mask
  *      R8  = CPU in LP1 state mask
  *      R9  = CPU in LP2 state mask
@@ -114,6 +113,40 @@ ENTRY(__tegra_cpu_reset_handler_start)
 ENTRY(__tegra_cpu_reset_handler)
 
        cpsid   aif, 0x13                       @ SVC mode, interrupts disabled
+
+       mov32   r6, TEGRA_APB_MISC_BASE
+       ldr     r6, [r6, #APB_MISC_GP_HIDREV]
+       and     r6, r6, #0xff00
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+t20_check:
+       cmp     r6, #(0x20 << 8)
+       bne     after_t20_check
+t20_errata:
+       # Tegra20 is a Cortex-A9 r1p1
+       mrc     p15, 0, r0, c1, c0, 0   @ read system control register
+       orr     r0, r0, #1 << 14        @ erratum 716044
+       mcr     p15, 0, r0, c1, c0, 0   @ write system control register
+       mrc     p15, 0, r0, c15, c0, 1  @ read diagnostic register
+       orr     r0, r0, #1 << 4         @ erratum 742230
+       orr     r0, r0, #1 << 11        @ erratum 751472
+       mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
+       b       after_errata
+after_t20_check:
+#endif
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+t30_check:
+       cmp     r6, #(0x30 << 8)
+       bne     after_t30_check
+t30_errata:
+       # Tegra30 is a Cortex-A9 r2p9
+       mrc     p15, 0, r0, c15, c0, 1  @ read diagnostic register
+       orr     r0, r0, #1 << 6         @ erratum 743622
+       orr     r0, r0, #1 << 11        @ erratum 751472
+       mcr     p15, 0, r0, c15, c0, 1  @ write diagnostic register
+       b       after_errata
+after_t30_check:
+#endif
+after_errata:
        mrc     p15, 0, r10, c0, c0, 5          @ MPIDR
        and     r10, r10, #0x3                  @ R10 = CPU number
        mov     r11, #1
@@ -129,16 +162,13 @@ ENTRY(__tegra_cpu_reset_handler)
 
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
        /* Are we on Tegra20? */
-       mov32   r6, TEGRA_APB_MISC_BASE
-       ldr     r0, [r6, #APB_MISC_GP_HIDREV]
-       and     r0, r0, #0xff00
-       cmp     r0, #(0x20 << 8)
+       cmp     r6, #(0x20 << 8)
        bne     1f
        /* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */
-       mov32   r6, TEGRA_PMC_BASE
+       mov32   r5, TEGRA_PMC_BASE
        mov     r0, #0
        cmp     r10, #0
-       strne   r0, [r6, #PMC_SCRATCH41]
+       strne   r0, [r5, #PMC_SCRATCH41]
 1:
 #endif
 
index 4ffae541726e1d258502007482e37585e33ad4ee..970ebd5138b99bf0a6d9cf682cee836b1f5cd5e7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved.
+ * Copyright (c) 2010-2013, NVIDIA Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
@@ -124,11 +124,11 @@ int tegra_sleep_cpu_finish(unsigned long);
 void tegra_disable_clean_inv_dcache(void);
 
 #ifdef CONFIG_HOTPLUG_CPU
-void tegra20_hotplug_init(void);
-void tegra30_hotplug_init(void);
+void tegra20_hotplug_shutdown(void);
+void tegra30_hotplug_shutdown(void);
+void tegra_hotplug_init(void);
 #else
-static inline void tegra20_hotplug_init(void) {}
-static inline void tegra30_hotplug_init(void) {}
+static inline void tegra_hotplug_init(void) {}
 #endif
 
 void tegra20_cpu_shutdown(int cpu);
diff --git a/arch/arm/mach-tegra/tegra.c b/arch/arm/mach-tegra/tegra.c
new file mode 100644 (file)
index 0000000..61749e2
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * NVIDIA Tegra SoC device tree board support
+ *
+ * Copyright (C) 2011, 2013, NVIDIA Corporation
+ * Copyright (C) 2010 Secret Lab Technologies, Ltd.
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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/clocksource.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/pda_power.h>
+#include <linux/platform_data/tegra_usb.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/i2c-tegra.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+#include <linux/usb/tegra_usb_phy.h>
+#include <linux/clk/tegra.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/setup.h>
+
+#include "board.h"
+#include "common.h"
+#include "fuse.h"
+#include "iomap.h"
+
+static struct tegra_ehci_platform_data tegra_ehci1_pdata = {
+       .operating_mode = TEGRA_USB_OTG,
+       .power_down_on_bus_suspend = 1,
+       .vbus_gpio = -1,
+};
+
+static struct tegra_ulpi_config tegra_ehci2_ulpi_phy_config = {
+       .reset_gpio = -1,
+       .clk = "cdev2",
+};
+
+static struct tegra_ehci_platform_data tegra_ehci2_pdata = {
+       .phy_config = &tegra_ehci2_ulpi_phy_config,
+       .operating_mode = TEGRA_USB_HOST,
+       .power_down_on_bus_suspend = 1,
+       .vbus_gpio = -1,
+};
+
+static struct tegra_ehci_platform_data tegra_ehci3_pdata = {
+       .operating_mode = TEGRA_USB_HOST,
+       .power_down_on_bus_suspend = 1,
+       .vbus_gpio = -1,
+};
+
+static struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
+       OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5000000, "tegra-ehci.0",
+                      &tegra_ehci1_pdata),
+       OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5004000, "tegra-ehci.1",
+                      &tegra_ehci2_pdata),
+       OF_DEV_AUXDATA("nvidia,tegra20-ehci", 0xC5008000, "tegra-ehci.2",
+                      &tegra_ehci3_pdata),
+       {}
+};
+
+static void __init tegra_dt_init(void)
+{
+       struct soc_device_attribute *soc_dev_attr;
+       struct soc_device *soc_dev;
+       struct device *parent = NULL;
+
+       tegra_clocks_apply_init_table();
+
+       soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+       if (!soc_dev_attr)
+               goto out;
+
+       soc_dev_attr->family = kasprintf(GFP_KERNEL, "Tegra");
+       soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%d", tegra_revision);
+       soc_dev_attr->soc_id = kasprintf(GFP_KERNEL, "%d", tegra_chip_id);
+
+       soc_dev = soc_device_register(soc_dev_attr);
+       if (IS_ERR(soc_dev)) {
+               kfree(soc_dev_attr->family);
+               kfree(soc_dev_attr->revision);
+               kfree(soc_dev_attr->soc_id);
+               kfree(soc_dev_attr);
+               goto out;
+       }
+
+       parent = soc_device_to_device(soc_dev);
+
+       /*
+        * Finished with the static registrations now; fill in the missing
+        * devices
+        */
+out:
+       of_platform_populate(NULL, of_default_bus_match_table,
+                               tegra20_auxdata_lookup, parent);
+}
+
+static void __init trimslice_init(void)
+{
+#ifdef CONFIG_TEGRA_PCI
+       int ret;
+
+       ret = tegra_pcie_init(true, true);
+       if (ret)
+               pr_err("tegra_pci_init() failed: %d\n", ret);
+#endif
+}
+
+static void __init harmony_init(void)
+{
+#ifdef CONFIG_TEGRA_PCI
+       int ret;
+
+       ret = harmony_pcie_init();
+       if (ret)
+               pr_err("harmony_pcie_init() failed: %d\n", ret);
+#endif
+}
+
+static void __init paz00_init(void)
+{
+       if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC))
+               tegra_paz00_wifikill_init();
+}
+
+static struct {
+       char *machine;
+       void (*init)(void);
+} board_init_funcs[] = {
+       { "compulab,trimslice", trimslice_init },
+       { "nvidia,harmony", harmony_init },
+       { "compal,paz00", paz00_init },
+};
+
+static void __init tegra_dt_init_late(void)
+{
+       int i;
+
+       tegra_init_late();
+
+       for (i = 0; i < ARRAY_SIZE(board_init_funcs); i++) {
+               if (of_machine_is_compatible(board_init_funcs[i].machine)) {
+                       board_init_funcs[i].init();
+                       break;
+               }
+       }
+}
+
+static const char * const tegra_dt_board_compat[] = {
+       "nvidia,tegra114",
+       "nvidia,tegra30",
+       "nvidia,tegra20",
+       NULL
+};
+
+DT_MACHINE_START(TEGRA_DT, "NVIDIA Tegra SoC (Flattened Device Tree)")
+       .map_io         = tegra_map_common_io,
+       .smp            = smp_ops(tegra_smp_ops),
+       .init_early     = tegra_init_early,
+       .init_irq       = tegra_dt_init_irq,
+       .init_time      = clocksource_of_init,
+       .init_machine   = tegra_dt_init,
+       .init_late      = tegra_dt_init_late,
+       .restart        = tegra_assert_system_reset,
+       .dt_compat      = tegra_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-tegra/tegra114_speedo.c b/arch/arm/mach-tegra/tegra114_speedo.c
new file mode 100644 (file)
index 0000000..5218d48
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/bug.h>
+
+#include "fuse.h"
+
+#define CORE_PROCESS_CORNERS_NUM       2
+#define CPU_PROCESS_CORNERS_NUM                2
+
+enum {
+       THRESHOLD_INDEX_0,
+       THRESHOLD_INDEX_1,
+       THRESHOLD_INDEX_COUNT,
+};
+
+static const u32 core_process_speedos[][CORE_PROCESS_CORNERS_NUM] = {
+       {1123,     UINT_MAX},
+       {0,        UINT_MAX},
+};
+
+static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = {
+       {1695,     UINT_MAX},
+       {0,        UINT_MAX},
+};
+
+static void rev_sku_to_speedo_ids(int rev, int sku, int *threshold)
+{
+       u32 tmp;
+
+       switch (sku) {
+       case 0x00:
+       case 0x10:
+       case 0x05:
+       case 0x06:
+               tegra_cpu_speedo_id = 1;
+               tegra_soc_speedo_id = 0;
+               *threshold = THRESHOLD_INDEX_0;
+               break;
+
+       case 0x03:
+       case 0x04:
+               tegra_cpu_speedo_id = 2;
+               tegra_soc_speedo_id = 1;
+               *threshold = THRESHOLD_INDEX_1;
+               break;
+
+       default:
+               pr_err("Tegra114 Unknown SKU %d\n", sku);
+               tegra_cpu_speedo_id = 0;
+               tegra_soc_speedo_id = 0;
+               *threshold = THRESHOLD_INDEX_0;
+               break;
+       }
+
+       if (rev == TEGRA_REVISION_A01) {
+               tmp = tegra_fuse_readl(0x270) << 1;
+               tmp |= tegra_fuse_readl(0x26c);
+               if (!tmp)
+                       tegra_cpu_speedo_id = 0;
+       }
+}
+
+void tegra114_init_speedo_data(void)
+{
+       u32 cpu_speedo_val;
+       u32 core_speedo_val;
+       int threshold;
+       int i;
+
+       BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) !=
+                       THRESHOLD_INDEX_COUNT);
+       BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) !=
+                       THRESHOLD_INDEX_COUNT);
+
+       rev_sku_to_speedo_ids(tegra_revision, tegra_sku_id, &threshold);
+
+       cpu_speedo_val = tegra_fuse_readl(0x12c) + 1024;
+       core_speedo_val = tegra_fuse_readl(0x134);
+
+       for (i = 0; i < CPU_PROCESS_CORNERS_NUM; i++)
+               if (cpu_speedo_val < cpu_process_speedos[threshold][i])
+                       break;
+       tegra_cpu_process_id = i;
+
+       for (i = 0; i < CORE_PROCESS_CORNERS_NUM; i++)
+               if (core_speedo_val < core_process_speedos[threshold][i])
+                       break;
+       tegra_core_process_id = i;
+}
index a6af0b8732bac8255619bdb5ebb1956692d74681..d07bbe7f04a65a5ceea7f9dd954be68aef7a877e 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/io.h>
 #include <linux/errno.h>
 #include <linux/clksrc-dbx500-prcmu.h>
+#include <linux/clocksource.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/platform_data/clocksource-nomadik-mtu.h>
@@ -32,7 +33,7 @@ static void __init ux500_twd_init(void)
        twd_local_timer = &u8500_twd_local_timer;
 
        if (of_have_populated_dt())
-               twd_local_timer_of_register();
+               clocksource_of_init();
        else {
                err = twd_local_timer_register(twd_local_timer);
                if (err)
index 915683cb67d60a6eed062fa49cbc7781a11f761b..d0ad78998cb628c34feee844b81a4293cb28f253 100644 (file)
@@ -5,6 +5,7 @@
 #include <linux/amba/bus.h>
 #include <linux/amba/mmci.h>
 #include <linux/io.h>
+#include <linux/clocksource.h>
 #include <linux/smp.h>
 #include <linux/init.h>
 #include <linux/irqchip.h>
@@ -25,7 +26,6 @@
 #include <asm/arch_timer.h>
 #include <asm/mach-types.h>
 #include <asm/sizes.h>
-#include <asm/smp_twd.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
@@ -435,6 +435,7 @@ static void __init v2m_dt_timer_init(void)
 
        vexpress_clk_of_init();
 
+       clocksource_of_init();
        do {
                node = of_find_compatible_node(node, NULL, "arm,sp804");
        } while (node && vexpress_get_site_by_node(node) != VEXPRESS_SITE_MB);
@@ -445,8 +446,7 @@ static void __init v2m_dt_timer_init(void)
                                irq_of_parse_and_map(node, 0));
        }
 
-       if (arch_timer_of_register() != 0)
-               twd_local_timer_of_register();
+       arch_timer_of_register();
 
        if (arch_timer_sched_clock_init() != 0)
                versatile_sched_clock_init(vexpress_get_24mhz_clock_base(),
index a0daa2fb5de667d4410a87e81fb53cba254dc664..5d0af13adb9b1c5da01ed33a8b19862b266f49d0 100644 (file)
@@ -52,6 +52,13 @@ static u32 omap_reserved_systimers;
 static LIST_HEAD(omap_timer_list);
 static DEFINE_SPINLOCK(dm_timer_lock);
 
+enum {
+       REQUEST_ANY = 0,
+       REQUEST_BY_ID,
+       REQUEST_BY_CAP,
+       REQUEST_BY_NODE,
+};
+
 /**
  * omap_dm_timer_read_reg - read timer registers in posted and non-posted mode
  * @timer:      timer pointer over which read operation to perform
@@ -178,29 +185,82 @@ int omap_dm_timer_reserve_systimer(int id)
        return 0;
 }
 
-struct omap_dm_timer *omap_dm_timer_request(void)
+static struct omap_dm_timer *_omap_dm_timer_request(int req_type, void *data)
 {
        struct omap_dm_timer *timer = NULL, *t;
+       struct device_node *np = NULL;
        unsigned long flags;
-       int ret = 0;
+       u32 cap = 0;
+       int id = 0;
+
+       switch (req_type) {
+       case REQUEST_BY_ID:
+               id = *(int *)data;
+               break;
+       case REQUEST_BY_CAP:
+               cap = *(u32 *)data;
+               break;
+       case REQUEST_BY_NODE:
+               np = (struct device_node *)data;
+               break;
+       default:
+               /* REQUEST_ANY */
+               break;
+       }
 
        spin_lock_irqsave(&dm_timer_lock, flags);
        list_for_each_entry(t, &omap_timer_list, node) {
                if (t->reserved)
                        continue;
 
-               timer = t;
-               timer->reserved = 1;
-               break;
+               switch (req_type) {
+               case REQUEST_BY_ID:
+                       if (id == t->pdev->id) {
+                               timer = t;
+                               timer->reserved = 1;
+                               goto found;
+                       }
+                       break;
+               case REQUEST_BY_CAP:
+                       if (cap == (t->capability & cap)) {
+                               /*
+                                * If timer is not NULL, we have already found
+                                * one timer but it was not an exact match
+                                * because it had more capabilites that what
+                                * was required. Therefore, unreserve the last
+                                * timer found and see if this one is a better
+                                * match.
+                                */
+                               if (timer)
+                                       timer->reserved = 0;
+                               timer = t;
+                               timer->reserved = 1;
+
+                               /* Exit loop early if we find an exact match */
+                               if (t->capability == cap)
+                                       goto found;
+                       }
+                       break;
+               case REQUEST_BY_NODE:
+                       if (np == t->pdev->dev.of_node) {
+                               timer = t;
+                               timer->reserved = 1;
+                               goto found;
+                       }
+                       break;
+               default:
+                       /* REQUEST_ANY */
+                       timer = t;
+                       timer->reserved = 1;
+                       goto found;
+               }
        }
+found:
        spin_unlock_irqrestore(&dm_timer_lock, flags);
 
-       if (timer) {
-               ret = omap_dm_timer_prepare(timer);
-               if (ret) {
-                       timer->reserved = 0;
-                       timer = NULL;
-               }
+       if (timer && omap_dm_timer_prepare(timer)) {
+               timer->reserved = 0;
+               timer = NULL;
        }
 
        if (!timer)
@@ -208,43 +268,23 @@ struct omap_dm_timer *omap_dm_timer_request(void)
 
        return timer;
 }
+
+struct omap_dm_timer *omap_dm_timer_request(void)
+{
+       return _omap_dm_timer_request(REQUEST_ANY, NULL);
+}
 EXPORT_SYMBOL_GPL(omap_dm_timer_request);
 
 struct omap_dm_timer *omap_dm_timer_request_specific(int id)
 {
-       struct omap_dm_timer *timer = NULL, *t;
-       unsigned long flags;
-       int ret = 0;
-
        /* Requesting timer by ID is not supported when device tree is used */
        if (of_have_populated_dt()) {
-               pr_warn("%s: Please use omap_dm_timer_request_by_cap()\n",
+               pr_warn("%s: Please use omap_dm_timer_request_by_cap/node()\n",
                        __func__);
                return NULL;
        }
 
-       spin_lock_irqsave(&dm_timer_lock, flags);
-       list_for_each_entry(t, &omap_timer_list, node) {
-               if (t->pdev->id == id && !t->reserved) {
-                       timer = t;
-                       timer->reserved = 1;
-                       break;
-               }
-       }
-       spin_unlock_irqrestore(&dm_timer_lock, flags);
-
-       if (timer) {
-               ret = omap_dm_timer_prepare(timer);
-               if (ret) {
-                       timer->reserved = 0;
-                       timer = NULL;
-               }
-       }
-
-       if (!timer)
-               pr_debug("%s: timer%d request failed!\n", __func__, id);
-
-       return timer;
+       return _omap_dm_timer_request(REQUEST_BY_ID, &id);
 }
 EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
 
@@ -259,46 +299,25 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
  */
 struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap)
 {
-       struct omap_dm_timer *timer = NULL, *t;
-       unsigned long flags;
+       return _omap_dm_timer_request(REQUEST_BY_CAP, &cap);
+}
+EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_cap);
 
-       if (!cap)
+/**
+ * omap_dm_timer_request_by_node - Request a timer by device-tree node
+ * @np:                Pointer to device-tree timer node
+ *
+ * Request a timer based upon a device node pointer. Returns pointer to
+ * timer handle on success and a NULL pointer on failure.
+ */
+struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np)
+{
+       if (!np)
                return NULL;
 
-       spin_lock_irqsave(&dm_timer_lock, flags);
-       list_for_each_entry(t, &omap_timer_list, node) {
-               if ((!t->reserved) && ((t->capability & cap) == cap)) {
-                       /*
-                        * If timer is not NULL, we have already found one timer
-                        * but it was not an exact match because it had more
-                        * capabilites that what was required. Therefore,
-                        * unreserve the last timer found and see if this one
-                        * is a better match.
-                        */
-                       if (timer)
-                               timer->reserved = 0;
-
-                       timer = t;
-                       timer->reserved = 1;
-
-                       /* Exit loop early if we find an exact match */
-                       if (t->capability == cap)
-                               break;
-               }
-       }
-       spin_unlock_irqrestore(&dm_timer_lock, flags);
-
-       if (timer && omap_dm_timer_prepare(timer)) {
-               timer->reserved = 0;
-               timer = NULL;
-       }
-
-       if (!timer)
-               pr_debug("%s: timer request failed!\n", __func__);
-
-       return timer;
+       return _omap_dm_timer_request(REQUEST_BY_NODE, np);
 }
-EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_cap);
+EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_node);
 
 int omap_dm_timer_free(struct omap_dm_timer *timer)
 {
@@ -315,7 +334,21 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_free);
 
 void omap_dm_timer_enable(struct omap_dm_timer *timer)
 {
+       int c;
+
        pm_runtime_get_sync(&timer->pdev->dev);
+
+       if (!(timer->capability & OMAP_TIMER_ALWON)) {
+               if (timer->get_context_loss_count) {
+                       c = timer->get_context_loss_count(&timer->pdev->dev);
+                       if (c != timer->ctx_loss_count) {
+                               omap_timer_restore_context(timer);
+                               timer->ctx_loss_count = c;
+                       }
+               } else {
+                       omap_timer_restore_context(timer);
+               }
+       }
 }
 EXPORT_SYMBOL_GPL(omap_dm_timer_enable);
 
@@ -410,13 +443,6 @@ int omap_dm_timer_start(struct omap_dm_timer *timer)
 
        omap_dm_timer_enable(timer);
 
-       if (!(timer->capability & OMAP_TIMER_ALWON)) {
-               if (timer->get_context_loss_count &&
-                       timer->get_context_loss_count(&timer->pdev->dev) !=
-                               timer->ctx_loss_count)
-                       omap_timer_restore_context(timer);
-       }
-
        l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
        if (!(l & OMAP_TIMER_CTRL_ST)) {
                l |= OMAP_TIMER_CTRL_ST;
@@ -441,12 +467,6 @@ int omap_dm_timer_stop(struct omap_dm_timer *timer)
 
        __omap_dm_timer_stop(timer, timer->posted, rate);
 
-       if (!(timer->capability & OMAP_TIMER_ALWON)) {
-               if (timer->get_context_loss_count)
-                       timer->ctx_loss_count =
-                               timer->get_context_loss_count(&timer->pdev->dev);
-       }
-
        /*
         * Since the register values are computed and written within
         * __omap_dm_timer_stop, we need to use read to retrieve the
@@ -553,13 +573,6 @@ int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
 
        omap_dm_timer_enable(timer);
 
-       if (!(timer->capability & OMAP_TIMER_ALWON)) {
-               if (timer->get_context_loss_count &&
-                       timer->get_context_loss_count(&timer->pdev->dev) !=
-                               timer->ctx_loss_count)
-                       omap_timer_restore_context(timer);
-       }
-
        l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
        if (autoreload) {
                l |= OMAP_TIMER_CTRL_AR;
@@ -770,6 +783,8 @@ int omap_dm_timers_active(void)
 }
 EXPORT_SYMBOL_GPL(omap_dm_timers_active);
 
+static const struct of_device_id omap_timer_match[];
+
 /**
  * omap_dm_timer_probe - probe function called for every registered device
  * @pdev:      pointer to current timer platform device
@@ -783,7 +798,11 @@ static int omap_dm_timer_probe(struct platform_device *pdev)
        struct omap_dm_timer *timer;
        struct resource *mem, *irq;
        struct device *dev = &pdev->dev;
-       struct dmtimer_platform_data *pdata = pdev->dev.platform_data;
+       const struct of_device_id *match;
+       const struct dmtimer_platform_data *pdata;
+
+       match = of_match_device(of_match_ptr(omap_timer_match), dev);
+       pdata = match ? match->data : dev->platform_data;
 
        if (!pdata && !dev->of_node) {
                dev_err(dev, "%s: no platform data.\n", __func__);
@@ -823,12 +842,14 @@ static int omap_dm_timer_probe(struct platform_device *pdev)
                        timer->capability |= OMAP_TIMER_SECURE;
        } else {
                timer->id = pdev->id;
-               timer->errata = pdata->timer_errata;
                timer->capability = pdata->timer_capability;
                timer->reserved = omap_dm_timer_reserved_systimer(timer->id);
                timer->get_context_loss_count = pdata->get_context_loss_count;
        }
 
+       if (pdata)
+               timer->errata = pdata->timer_errata;
+
        timer->irq = irq->start;
        timer->pdev = pdev;
 
@@ -881,8 +902,34 @@ static int omap_dm_timer_remove(struct platform_device *pdev)
        return ret;
 }
 
+static const struct dmtimer_platform_data omap3plus_pdata = {
+       .timer_errata = OMAP_TIMER_ERRATA_I103_I767,
+};
+
 static const struct of_device_id omap_timer_match[] = {
-       { .compatible = "ti,omap2-timer", },
+       {
+               .compatible = "ti,omap2420-timer",
+       },
+       {
+               .compatible = "ti,omap3430-timer",
+               .data = &omap3plus_pdata,
+       },
+       {
+               .compatible = "ti,omap4430-timer",
+               .data = &omap3plus_pdata,
+       },
+       {
+               .compatible = "ti,omap5430-timer",
+               .data = &omap3plus_pdata,
+       },
+       {
+               .compatible = "ti,am335x-timer",
+               .data = &omap3plus_pdata,
+       },
+       {
+               .compatible = "ti,am335x-timer-1ms",
+               .data = &omap3plus_pdata,
+       },
        {},
 };
 MODULE_DEVICE_TABLE(of, omap_timer_match);
index a3fbc48c332ecd0ebcf02023d43209d8d1a00690..fb92abb91628a2e06f6aebc54f03a724a79c23ee 100644 (file)
@@ -128,6 +128,7 @@ int omap_dm_timer_reserve_systimer(int id);
 struct omap_dm_timer *omap_dm_timer_request(void);
 struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
 struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap);
+struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np);
 int omap_dm_timer_free(struct omap_dm_timer *timer);
 void omap_dm_timer_enable(struct omap_dm_timer *timer);
 void omap_dm_timer_disable(struct omap_dm_timer *timer);
index a9d52167e16ecbd0184ac18c47112eaaaaba5362..6cb19c6aa9d68d5b4a3ee89c2d46fb163fbd810e 100644 (file)
@@ -25,7 +25,7 @@ config PLAT_S5P
        select PLAT_SAMSUNG
        select S3C_GPIO_TRACK
        select S5P_GPIO_DRVSTR
-       select SAMSUNG_CLKSRC
+       select SAMSUNG_CLKSRC if !COMMON_CLK
        select SAMSUNG_GPIOLIB_4BIT
        select SAMSUNG_IRQ_VIC_TIMER
        help
@@ -70,7 +70,7 @@ config S3C_LOWLEVEL_UART_PORT
 
 # timer options
 
-config S5P_HRT
+config SAMSUNG_HRT
        bool
        select SAMSUNG_DEV_PWM
        help
@@ -89,7 +89,7 @@ config SAMSUNG_CLKSRC
          used by newer systems such as the S3C64XX.
 
 config S5P_CLOCK
-       def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
+       def_bool (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210)
        help
          Support common clock part for ARCH_S5P and ARCH_EXYNOS SoCs
 
index 3a7c64d1814a2edb92a01fcbe390189e005c1eb3..a23c460299a19bc003dd73003aa5e1e04605a24f 100644 (file)
@@ -12,8 +12,7 @@ obj-                          :=
 # Objects we always build independent of SoC choice
 
 obj-y                          += init.o cpu.o
-obj-$(CONFIG_ARCH_USES_GETTIMEOFFSET)   += time.o
-obj-$(CONFIG_S5P_HRT)          += s5p-time.o
+obj-$(CONFIG_SAMSUNG_HRT)      += samsung-time.o
 
 obj-$(CONFIG_SAMSUNG_CLOCK)    += clock.o
 obj-$(CONFIG_SAMSUNG_CLOCK)    += pwm-clock.o
diff --git a/arch/arm/plat-samsung/include/plat/common-smdk.h b/arch/arm/plat-samsung/include/plat/common-smdk.h
deleted file mode 100644 (file)
index ba028f1..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* linux/arch/arm/plat-samsung/include/plat/common-smdk.h
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Common code for SMDK2410 and SMDK2440 boards
- *
- * http://www.fluff.org/ben/smdk2440/
- *
- * 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.
-*/
-
-extern void smdk_machine_init(void);
index 37703ef6dfc76ff28b70543b55311f7abc52269b..e126644cadf4dc3b5503ec62e5a3cca0bbe4e6e3 100644 (file)
@@ -192,10 +192,6 @@ extern void s3c24xx_init_uartdevs(char *name,
                                  struct s3c24xx_uart_resources *res,
                                  struct s3c2410_uartcfg *cfg, int no);
 
-/* timer for 2410/2440 */
-
-extern void s3c24xx_timer_init(void);
-
 extern struct syscore_ops s3c2410_pm_syscore_ops;
 extern struct syscore_ops s3c2412_pm_syscore_ops;
 extern struct syscore_ops s3c2416_pm_syscore_ops;
diff --git a/arch/arm/plat-samsung/include/plat/irq.h b/arch/arm/plat-samsung/include/plat/irq.h
deleted file mode 100644 (file)
index e21a89b..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/* linux/arch/arm/plat-samsung/include/plat/irq.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for S3C24XX CPU IRQ support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/regs-irq.h>
-#include <mach/regs-gpio.h>
-
-#define irqdbf(x...)
-#define irqdbf2(x...)
-
-#define EXTINT_OFF (IRQ_EINT4 - 4)
-
-/* these are exported for arch/arm/mach-* usage */
-extern struct irq_chip s3c_irq_level_chip;
-extern struct irq_chip s3c_irq_chip;
-
-static inline void s3c_irqsub_mask(unsigned int irqno,
-                                  unsigned int parentbit,
-                                  int subcheck)
-{
-       unsigned long mask;
-       unsigned long submask;
-
-       submask = __raw_readl(S3C2410_INTSUBMSK);
-       mask = __raw_readl(S3C2410_INTMSK);
-
-       submask |= (1UL << (irqno - IRQ_S3CUART_RX0));
-
-       /* check to see if we need to mask the parent IRQ */
-
-       if ((submask  & subcheck) == subcheck)
-               __raw_writel(mask | parentbit, S3C2410_INTMSK);
-
-       /* write back masks */
-       __raw_writel(submask, S3C2410_INTSUBMSK);
-
-}
-
-static inline void s3c_irqsub_unmask(unsigned int irqno,
-                                    unsigned int parentbit)
-{
-       unsigned long mask;
-       unsigned long submask;
-
-       submask = __raw_readl(S3C2410_INTSUBMSK);
-       mask = __raw_readl(S3C2410_INTMSK);
-
-       submask &= ~(1UL << (irqno - IRQ_S3CUART_RX0));
-       mask &= ~parentbit;
-
-       /* write back masks */
-       __raw_writel(submask, S3C2410_INTSUBMSK);
-       __raw_writel(mask, S3C2410_INTMSK);
-}
-
-
-static inline void s3c_irqsub_maskack(unsigned int irqno,
-                                     unsigned int parentmask,
-                                     unsigned int group)
-{
-       unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
-
-       s3c_irqsub_mask(irqno, parentmask, group);
-
-       __raw_writel(bit, S3C2410_SUBSRCPND);
-
-       /* only ack parent if we've got all the irqs (seems we must
-        * ack, all and hope that the irq system retriggers ok when
-        * the interrupt goes off again)
-        */
-
-       if (1) {
-               __raw_writel(parentmask, S3C2410_SRCPND);
-               __raw_writel(parentmask, S3C2410_INTPND);
-       }
-}
-
-static inline void s3c_irqsub_ack(unsigned int irqno,
-                                 unsigned int parentmask,
-                                 unsigned int group)
-{
-       unsigned int bit = 1UL << (irqno - IRQ_S3CUART_RX0);
-
-       __raw_writel(bit, S3C2410_SUBSRCPND);
-
-       /* only ack parent if we've got all the irqs (seems we must
-        * ack, all and hope that the irq system retriggers ok when
-        * the interrupt goes off again)
-        */
-
-       if (1) {
-               __raw_writel(parentmask, S3C2410_SRCPND);
-               __raw_writel(parentmask, S3C2410_INTPND);
-       }
-}
-
-/* exported for use in arch/arm/mach-s3c2410 */
-
-#ifdef CONFIG_PM
-extern int s3c_irq_wake(struct irq_data *data, unsigned int state);
-#else
-#define s3c_irq_wake NULL
-#endif
-
-extern int s3c_irqext_type(struct irq_data *d, unsigned int type);
diff --git a/arch/arm/plat-samsung/include/plat/s3c2410.h b/arch/arm/plat-samsung/include/plat/s3c2410.h
deleted file mode 100644 (file)
index 55b0e5f..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* linux/arch/arm/plat-samsung/include/plat/s3c2410.h
- *
- * Copyright (c) 2004 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for s3c2410 machine directory
- *
- * 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.
- *
-*/
-
-#ifdef CONFIG_CPU_S3C2410
-
-extern  int s3c2410_init(void);
-extern  int s3c2410a_init(void);
-
-extern void s3c2410_map_io(void);
-
-extern void s3c2410_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-extern void s3c2410_init_clocks(int xtal);
-
-#else
-#define s3c2410_init_clocks NULL
-#define s3c2410_init_uarts NULL
-#define s3c2410_map_io NULL
-#define s3c2410_init NULL
-#define s3c2410a_init NULL
-#endif
diff --git a/arch/arm/plat-samsung/include/plat/s3c2412.h b/arch/arm/plat-samsung/include/plat/s3c2412.h
deleted file mode 100644 (file)
index cbae50d..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/* linux/arch/arm/plat-samsung/include/plat/s3c2412.h
- *
- * Copyright (c) 2006 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for s3c2412 cpu support
- *
- * 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.
-*/
-
-#ifdef CONFIG_CPU_S3C2412
-
-extern  int s3c2412_init(void);
-
-extern void s3c2412_map_io(void);
-
-extern void s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-extern void s3c2412_init_clocks(int xtal);
-
-extern  int s3c2412_baseclk_add(void);
-
-extern void s3c2412_restart(char mode, const char *cmd);
-#else
-#define s3c2412_init_clocks NULL
-#define s3c2412_init_uarts NULL
-#define s3c2412_map_io NULL
-#define s3c2412_init NULL
-#define s3c2412_restart NULL
-#endif
diff --git a/arch/arm/plat-samsung/include/plat/s3c2416.h b/arch/arm/plat-samsung/include/plat/s3c2416.h
deleted file mode 100644 (file)
index f27399a..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* linux/arch/arm/plat-samsung/include/plat/s3c2416.h
- *
- * Copyright (c) 2009 Yauhen Kharuzhy <jekhor@gmail.com>
- *
- * Header file for s3c2416 cpu support
- *
- * 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.
-*/
-
-#ifdef CONFIG_CPU_S3C2416
-
-struct s3c2410_uartcfg;
-
-extern  int s3c2416_init(void);
-
-extern void s3c2416_map_io(void);
-
-extern void s3c2416_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-extern void s3c2416_init_clocks(int xtal);
-
-extern  int s3c2416_baseclk_add(void);
-
-extern void s3c2416_restart(char mode, const char *cmd);
-
-extern void s3c2416_init_irq(void);
-extern struct syscore_ops s3c2416_irq_syscore_ops;
-
-#else
-#define s3c2416_init_clocks NULL
-#define s3c2416_init_uarts NULL
-#define s3c2416_map_io NULL
-#define s3c2416_init NULL
-#define s3c2416_restart NULL
-#endif
diff --git a/arch/arm/plat-samsung/include/plat/s3c2443.h b/arch/arm/plat-samsung/include/plat/s3c2443.h
deleted file mode 100644 (file)
index 71b88ec..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* linux/arch/arm/plat-samsung/include/plat/s3c2443.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for s3c2443 cpu support
- *
- * 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.
-*/
-
-#ifdef CONFIG_CPU_S3C2443
-
-struct s3c2410_uartcfg;
-
-extern  int s3c2443_init(void);
-
-extern void s3c2443_map_io(void);
-
-extern void s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-extern void s3c2443_init_clocks(int xtal);
-
-extern  int s3c2443_baseclk_add(void);
-
-extern void s3c2443_restart(char mode, const char *cmd);
-
-extern void s3c2443_init_irq(void);
-#else
-#define s3c2443_init_clocks NULL
-#define s3c2443_init_uarts NULL
-#define s3c2443_map_io NULL
-#define s3c2443_init NULL
-#define s3c2443_restart NULL
-#endif
diff --git a/arch/arm/plat-samsung/include/plat/s3c244x.h b/arch/arm/plat-samsung/include/plat/s3c244x.h
deleted file mode 100644 (file)
index ea0c961..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* linux/arch/arm/plat-samsung/include/plat/s3c244x.h
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *     Ben Dooks <ben@simtec.co.uk>
- *
- * Header file for S3C2440 and S3C2442 cpu support
- *
- * 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.
-*/
-
-#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
-
-extern void s3c244x_map_io(void);
-
-extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-
-extern void s3c244x_init_clocks(int xtal);
-
-#else
-#define s3c244x_init_clocks NULL
-#define s3c244x_init_uarts NULL
-#endif
-
-#ifdef CONFIG_CPU_S3C2440
-extern  int s3c2440_init(void);
-
-extern void s3c2440_map_io(void);
-#else
-#define s3c2440_init NULL
-#define s3c2440_map_io NULL
-#endif
-
-#ifdef CONFIG_CPU_S3C2442
-extern  int s3c2442_init(void);
-
-extern void s3c2442_map_io(void);
-#else
-#define s3c2442_init NULL
-#define s3c2442_map_io NULL
-#endif
diff --git a/arch/arm/plat-samsung/include/plat/s5p-time.h b/arch/arm/plat-samsung/include/plat/s5p-time.h
deleted file mode 100644 (file)
index 9c96f35..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/* linux/arch/arm/plat-samsung/include/plat/s5p-time.h
- *
- * Copyright 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * Header file for s5p time support
- *
- * 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 __ASM_PLAT_S5P_TIME_H
-#define __ASM_PLAT_S5P_TIME_H __FILE__
-
-/* S5P HR-Timer Clock mode */
-enum s5p_timer_mode {
-       S5P_PWM0,
-       S5P_PWM1,
-       S5P_PWM2,
-       S5P_PWM3,
-       S5P_PWM4,
-};
-
-struct s5p_timer_source {
-       unsigned int event_id;
-       unsigned int source_id;
-};
-
-/* Be able to sleep for atleast 4 seconds (usually more) */
-#define S5PTIMER_MIN_RANGE     4
-
-#define TCNT_MAX               0xffffffff
-#define NON_PERIODIC           0
-#define PERIODIC               1
-
-extern void __init s5p_set_timer_source(enum s5p_timer_mode event,
-                                       enum s5p_timer_mode source);
-extern void s5p_timer_init(void);
-#endif /* __ASM_PLAT_S5P_TIME_H */
diff --git a/arch/arm/plat-samsung/include/plat/samsung-time.h b/arch/arm/plat-samsung/include/plat/samsung-time.h
new file mode 100644 (file)
index 0000000..4cc99bb
--- /dev/null
@@ -0,0 +1,53 @@
+/* linux/arch/arm/plat-samsung/include/plat/samsung-time.h
+ *
+ * Copyright 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * Header file for samsung s3c and s5p time support
+ *
+ * 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 __ASM_PLAT_SAMSUNG_TIME_H
+#define __ASM_PLAT_SAMSUNG_TIME_H __FILE__
+
+/* SAMSUNG HR-Timer Clock mode */
+enum samsung_timer_mode {
+       SAMSUNG_PWM0,
+       SAMSUNG_PWM1,
+       SAMSUNG_PWM2,
+       SAMSUNG_PWM3,
+       SAMSUNG_PWM4,
+};
+
+struct samsung_timer_source {
+       unsigned int event_id;
+       unsigned int source_id;
+};
+
+/* Be able to sleep for atleast 4 seconds (usually more) */
+#define SAMSUNG_TIMER_MIN_RANGE        4
+
+#if defined(CONFIG_ARCH_S3C24XX) || defined(CONFIG_ARCH_S5PC100)
+#define TCNT_MAX               0xffff
+#define TSCALER_DIV            25
+#define TDIV                   50
+#define TSIZE                  16
+#else
+#define TCNT_MAX               0xffffffff
+#define TSCALER_DIV            2
+#define TDIV                   2
+#define TSIZE                  32
+#endif
+
+#define NON_PERIODIC           0
+#define PERIODIC               1
+
+extern void __init samsung_set_timer_source(enum samsung_timer_mode event,
+                                       enum samsung_timer_mode source);
+
+extern void __init samsung_timer_init(void);
+
+#endif /* __ASM_PLAT_SAMSUNG_TIME_H */
diff --git a/arch/arm/plat-samsung/s5p-time.c b/arch/arm/plat-samsung/s5p-time.c
deleted file mode 100644 (file)
index e92510c..0000000
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *             http://www.samsung.com/
- *
- * S5P - Common hr-timer support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/clockchips.h>
-#include <linux/platform_device.h>
-
-#include <asm/smp_twd.h>
-#include <asm/mach/time.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/sched_clock.h>
-
-#include <mach/map.h>
-#include <plat/devs.h>
-#include <plat/regs-timer.h>
-#include <plat/s5p-time.h>
-
-static struct clk *tin_event;
-static struct clk *tin_source;
-static struct clk *tdiv_event;
-static struct clk *tdiv_source;
-static struct clk *timerclk;
-static struct s5p_timer_source timer_source;
-static unsigned long clock_count_per_tick;
-static void s5p_timer_resume(void);
-
-static void s5p_time_stop(enum s5p_timer_mode mode)
-{
-       unsigned long tcon;
-
-       tcon = __raw_readl(S3C2410_TCON);
-
-       switch (mode) {
-       case S5P_PWM0:
-               tcon &= ~S3C2410_TCON_T0START;
-               break;
-
-       case S5P_PWM1:
-               tcon &= ~S3C2410_TCON_T1START;
-               break;
-
-       case S5P_PWM2:
-               tcon &= ~S3C2410_TCON_T2START;
-               break;
-
-       case S5P_PWM3:
-               tcon &= ~S3C2410_TCON_T3START;
-               break;
-
-       case S5P_PWM4:
-               tcon &= ~S3C2410_TCON_T4START;
-               break;
-
-       default:
-               printk(KERN_ERR "Invalid Timer %d\n", mode);
-               break;
-       }
-       __raw_writel(tcon, S3C2410_TCON);
-}
-
-static void s5p_time_setup(enum s5p_timer_mode mode, unsigned long tcnt)
-{
-       unsigned long tcon;
-
-       tcon = __raw_readl(S3C2410_TCON);
-
-       tcnt--;
-
-       switch (mode) {
-       case S5P_PWM0:
-               tcon &= ~(0x0f << 0);
-               tcon |= S3C2410_TCON_T0MANUALUPD;
-               break;
-
-       case S5P_PWM1:
-               tcon &= ~(0x0f << 8);
-               tcon |= S3C2410_TCON_T1MANUALUPD;
-               break;
-
-       case S5P_PWM2:
-               tcon &= ~(0x0f << 12);
-               tcon |= S3C2410_TCON_T2MANUALUPD;
-               break;
-
-       case S5P_PWM3:
-               tcon &= ~(0x0f << 16);
-               tcon |= S3C2410_TCON_T3MANUALUPD;
-               break;
-
-       case S5P_PWM4:
-               tcon &= ~(0x07 << 20);
-               tcon |= S3C2410_TCON_T4MANUALUPD;
-               break;
-
-       default:
-               printk(KERN_ERR "Invalid Timer %d\n", mode);
-               break;
-       }
-
-       __raw_writel(tcnt, S3C2410_TCNTB(mode));
-       __raw_writel(tcnt, S3C2410_TCMPB(mode));
-       __raw_writel(tcon, S3C2410_TCON);
-}
-
-static void s5p_time_start(enum s5p_timer_mode mode, bool periodic)
-{
-       unsigned long tcon;
-
-       tcon  = __raw_readl(S3C2410_TCON);
-
-       switch (mode) {
-       case S5P_PWM0:
-               tcon |= S3C2410_TCON_T0START;
-               tcon &= ~S3C2410_TCON_T0MANUALUPD;
-
-               if (periodic)
-                       tcon |= S3C2410_TCON_T0RELOAD;
-               else
-                       tcon &= ~S3C2410_TCON_T0RELOAD;
-               break;
-
-       case S5P_PWM1:
-               tcon |= S3C2410_TCON_T1START;
-               tcon &= ~S3C2410_TCON_T1MANUALUPD;
-
-               if (periodic)
-                       tcon |= S3C2410_TCON_T1RELOAD;
-               else
-                       tcon &= ~S3C2410_TCON_T1RELOAD;
-               break;
-
-       case S5P_PWM2:
-               tcon |= S3C2410_TCON_T2START;
-               tcon &= ~S3C2410_TCON_T2MANUALUPD;
-
-               if (periodic)
-                       tcon |= S3C2410_TCON_T2RELOAD;
-               else
-                       tcon &= ~S3C2410_TCON_T2RELOAD;
-               break;
-
-       case S5P_PWM3:
-               tcon |= S3C2410_TCON_T3START;
-               tcon &= ~S3C2410_TCON_T3MANUALUPD;
-
-               if (periodic)
-                       tcon |= S3C2410_TCON_T3RELOAD;
-               else
-                       tcon &= ~S3C2410_TCON_T3RELOAD;
-               break;
-
-       case S5P_PWM4:
-               tcon |= S3C2410_TCON_T4START;
-               tcon &= ~S3C2410_TCON_T4MANUALUPD;
-
-               if (periodic)
-                       tcon |= S3C2410_TCON_T4RELOAD;
-               else
-                       tcon &= ~S3C2410_TCON_T4RELOAD;
-               break;
-
-       default:
-               printk(KERN_ERR "Invalid Timer %d\n", mode);
-               break;
-       }
-       __raw_writel(tcon, S3C2410_TCON);
-}
-
-static int s5p_set_next_event(unsigned long cycles,
-                               struct clock_event_device *evt)
-{
-       s5p_time_setup(timer_source.event_id, cycles);
-       s5p_time_start(timer_source.event_id, NON_PERIODIC);
-
-       return 0;
-}
-
-static void s5p_set_mode(enum clock_event_mode mode,
-                               struct clock_event_device *evt)
-{
-       s5p_time_stop(timer_source.event_id);
-
-       switch (mode) {
-       case CLOCK_EVT_MODE_PERIODIC:
-               s5p_time_setup(timer_source.event_id, clock_count_per_tick);
-               s5p_time_start(timer_source.event_id, PERIODIC);
-               break;
-
-       case CLOCK_EVT_MODE_ONESHOT:
-               break;
-
-       case CLOCK_EVT_MODE_UNUSED:
-       case CLOCK_EVT_MODE_SHUTDOWN:
-               break;
-
-       case CLOCK_EVT_MODE_RESUME:
-               s5p_timer_resume();
-               break;
-       }
-}
-
-static void s5p_timer_resume(void)
-{
-       /* event timer restart */
-       s5p_time_setup(timer_source.event_id, clock_count_per_tick);
-       s5p_time_start(timer_source.event_id, PERIODIC);
-
-       /* source timer restart */
-       s5p_time_setup(timer_source.source_id, TCNT_MAX);
-       s5p_time_start(timer_source.source_id, PERIODIC);
-}
-
-void __init s5p_set_timer_source(enum s5p_timer_mode event,
-                                enum s5p_timer_mode source)
-{
-       s3c_device_timer[event].dev.bus = &platform_bus_type;
-       s3c_device_timer[source].dev.bus = &platform_bus_type;
-
-       timer_source.event_id = event;
-       timer_source.source_id = source;
-}
-
-static struct clock_event_device time_event_device = {
-       .name           = "s5p_event_timer",
-       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-       .rating         = 200,
-       .set_next_event = s5p_set_next_event,
-       .set_mode       = s5p_set_mode,
-};
-
-static irqreturn_t s5p_clock_event_isr(int irq, void *dev_id)
-{
-       struct clock_event_device *evt = dev_id;
-
-       evt->event_handler(evt);
-
-       return IRQ_HANDLED;
-}
-
-static struct irqaction s5p_clock_event_irq = {
-       .name           = "s5p_time_irq",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-       .handler        = s5p_clock_event_isr,
-       .dev_id         = &time_event_device,
-};
-
-static void __init s5p_clockevent_init(void)
-{
-       unsigned long pclk;
-       unsigned long clock_rate;
-       unsigned int irq_number;
-       struct clk *tscaler;
-
-       pclk = clk_get_rate(timerclk);
-
-       tscaler = clk_get_parent(tdiv_event);
-
-       clk_set_rate(tscaler, pclk / 2);
-       clk_set_rate(tdiv_event, pclk / 2);
-       clk_set_parent(tin_event, tdiv_event);
-
-       clock_rate = clk_get_rate(tin_event);
-       clock_count_per_tick = clock_rate / HZ;
-
-       time_event_device.cpumask = cpumask_of(0);
-       clockevents_config_and_register(&time_event_device, clock_rate, 1, -1);
-
-       irq_number = timer_source.event_id + IRQ_TIMER0;
-       setup_irq(irq_number, &s5p_clock_event_irq);
-}
-
-static void __iomem *s5p_timer_reg(void)
-{
-       unsigned long offset = 0;
-
-       switch (timer_source.source_id) {
-       case S5P_PWM0:
-       case S5P_PWM1:
-       case S5P_PWM2:
-       case S5P_PWM3:
-               offset = (timer_source.source_id * 0x0c) + 0x14;
-               break;
-
-       case S5P_PWM4:
-               offset = 0x40;
-               break;
-
-       default:
-               printk(KERN_ERR "Invalid Timer %d\n", timer_source.source_id);
-               return NULL;
-       }
-
-       return S3C_TIMERREG(offset);
-}
-
-/*
- * Override the global weak sched_clock symbol with this
- * local implementation which uses the clocksource to get some
- * better resolution when scheduling the kernel. We accept that
- * this wraps around for now, since it is just a relative time
- * stamp. (Inspired by U300 implementation.)
- */
-static u32 notrace s5p_read_sched_clock(void)
-{
-       void __iomem *reg = s5p_timer_reg();
-
-       if (!reg)
-               return 0;
-
-       return ~__raw_readl(reg);
-}
-
-static void __init s5p_clocksource_init(void)
-{
-       unsigned long pclk;
-       unsigned long clock_rate;
-
-       pclk = clk_get_rate(timerclk);
-
-       clk_set_rate(tdiv_source, pclk / 2);
-       clk_set_parent(tin_source, tdiv_source);
-
-       clock_rate = clk_get_rate(tin_source);
-
-       s5p_time_setup(timer_source.source_id, TCNT_MAX);
-       s5p_time_start(timer_source.source_id, PERIODIC);
-
-       setup_sched_clock(s5p_read_sched_clock, 32, clock_rate);
-
-       if (clocksource_mmio_init(s5p_timer_reg(), "s5p_clocksource_timer",
-                       clock_rate, 250, 32, clocksource_mmio_readl_down))
-               panic("s5p_clocksource_timer: can't register clocksource\n");
-}
-
-static void __init s5p_timer_resources(void)
-{
-
-       unsigned long event_id = timer_source.event_id;
-       unsigned long source_id = timer_source.source_id;
-       char devname[15];
-
-       timerclk = clk_get(NULL, "timers");
-       if (IS_ERR(timerclk))
-               panic("failed to get timers clock for timer");
-
-       clk_enable(timerclk);
-
-       sprintf(devname, "s3c24xx-pwm.%lu", event_id);
-       s3c_device_timer[event_id].id = event_id;
-       s3c_device_timer[event_id].dev.init_name = devname;
-
-       tin_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tin");
-       if (IS_ERR(tin_event))
-               panic("failed to get pwm-tin clock for event timer");
-
-       tdiv_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tdiv");
-       if (IS_ERR(tdiv_event))
-               panic("failed to get pwm-tdiv clock for event timer");
-
-       clk_enable(tin_event);
-
-       sprintf(devname, "s3c24xx-pwm.%lu", source_id);
-       s3c_device_timer[source_id].id = source_id;
-       s3c_device_timer[source_id].dev.init_name = devname;
-
-       tin_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tin");
-       if (IS_ERR(tin_source))
-               panic("failed to get pwm-tin clock for source timer");
-
-       tdiv_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tdiv");
-       if (IS_ERR(tdiv_source))
-               panic("failed to get pwm-tdiv clock for source timer");
-
-       clk_enable(tin_source);
-}
-
-void __init s5p_timer_init(void)
-{
-       s5p_timer_resources();
-       s5p_clockevent_init();
-       s5p_clocksource_init();
-}
diff --git a/arch/arm/plat-samsung/samsung-time.c b/arch/arm/plat-samsung/samsung-time.c
new file mode 100644 (file)
index 0000000..f899cbc
--- /dev/null
@@ -0,0 +1,394 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * samsung - Common hr-timer support (s3c and s5p)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/platform_device.h>
+
+#include <asm/smp_twd.h>
+#include <asm/mach/time.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/sched_clock.h>
+
+#include <mach/map.h>
+#include <plat/devs.h>
+#include <plat/regs-timer.h>
+#include <plat/samsung-time.h>
+
+static struct clk *tin_event;
+static struct clk *tin_source;
+static struct clk *tdiv_event;
+static struct clk *tdiv_source;
+static struct clk *timerclk;
+static struct samsung_timer_source timer_source;
+static unsigned long clock_count_per_tick;
+static void samsung_timer_resume(void);
+
+static void samsung_time_stop(enum samsung_timer_mode mode)
+{
+       unsigned long tcon;
+
+       tcon = __raw_readl(S3C2410_TCON);
+
+       switch (mode) {
+       case SAMSUNG_PWM0:
+               tcon &= ~S3C2410_TCON_T0START;
+               break;
+
+       case SAMSUNG_PWM1:
+               tcon &= ~S3C2410_TCON_T1START;
+               break;
+
+       case SAMSUNG_PWM2:
+               tcon &= ~S3C2410_TCON_T2START;
+               break;
+
+       case SAMSUNG_PWM3:
+               tcon &= ~S3C2410_TCON_T3START;
+               break;
+
+       case SAMSUNG_PWM4:
+               tcon &= ~S3C2410_TCON_T4START;
+               break;
+
+       default:
+               printk(KERN_ERR "Invalid Timer %d\n", mode);
+               break;
+       }
+       __raw_writel(tcon, S3C2410_TCON);
+}
+
+static void samsung_time_setup(enum samsung_timer_mode mode, unsigned long tcnt)
+{
+       unsigned long tcon;
+
+       tcon = __raw_readl(S3C2410_TCON);
+
+       tcnt--;
+
+       switch (mode) {
+       case SAMSUNG_PWM0:
+               tcon &= ~(0x0f << 0);
+               tcon |= S3C2410_TCON_T0MANUALUPD;
+               break;
+
+       case SAMSUNG_PWM1:
+               tcon &= ~(0x0f << 8);
+               tcon |= S3C2410_TCON_T1MANUALUPD;
+               break;
+
+       case SAMSUNG_PWM2:
+               tcon &= ~(0x0f << 12);
+               tcon |= S3C2410_TCON_T2MANUALUPD;
+               break;
+
+       case SAMSUNG_PWM3:
+               tcon &= ~(0x0f << 16);
+               tcon |= S3C2410_TCON_T3MANUALUPD;
+               break;
+
+       case SAMSUNG_PWM4:
+               tcon &= ~(0x07 << 20);
+               tcon |= S3C2410_TCON_T4MANUALUPD;
+               break;
+
+       default:
+               printk(KERN_ERR "Invalid Timer %d\n", mode);
+               break;
+       }
+
+       __raw_writel(tcnt, S3C2410_TCNTB(mode));
+       __raw_writel(tcnt, S3C2410_TCMPB(mode));
+       __raw_writel(tcon, S3C2410_TCON);
+}
+
+static void samsung_time_start(enum samsung_timer_mode mode, bool periodic)
+{
+       unsigned long tcon;
+
+       tcon  = __raw_readl(S3C2410_TCON);
+
+       switch (mode) {
+       case SAMSUNG_PWM0:
+               tcon |= S3C2410_TCON_T0START;
+               tcon &= ~S3C2410_TCON_T0MANUALUPD;
+
+               if (periodic)
+                       tcon |= S3C2410_TCON_T0RELOAD;
+               else
+                       tcon &= ~S3C2410_TCON_T0RELOAD;
+               break;
+
+       case SAMSUNG_PWM1:
+               tcon |= S3C2410_TCON_T1START;
+               tcon &= ~S3C2410_TCON_T1MANUALUPD;
+
+               if (periodic)
+                       tcon |= S3C2410_TCON_T1RELOAD;
+               else
+                       tcon &= ~S3C2410_TCON_T1RELOAD;
+               break;
+
+       case SAMSUNG_PWM2:
+               tcon |= S3C2410_TCON_T2START;
+               tcon &= ~S3C2410_TCON_T2MANUALUPD;
+
+               if (periodic)
+                       tcon |= S3C2410_TCON_T2RELOAD;
+               else
+                       tcon &= ~S3C2410_TCON_T2RELOAD;
+               break;
+
+       case SAMSUNG_PWM3:
+               tcon |= S3C2410_TCON_T3START;
+               tcon &= ~S3C2410_TCON_T3MANUALUPD;
+
+               if (periodic)
+                       tcon |= S3C2410_TCON_T3RELOAD;
+               else
+                       tcon &= ~S3C2410_TCON_T3RELOAD;
+               break;
+
+       case SAMSUNG_PWM4:
+               tcon |= S3C2410_TCON_T4START;
+               tcon &= ~S3C2410_TCON_T4MANUALUPD;
+
+               if (periodic)
+                       tcon |= S3C2410_TCON_T4RELOAD;
+               else
+                       tcon &= ~S3C2410_TCON_T4RELOAD;
+               break;
+
+       default:
+               printk(KERN_ERR "Invalid Timer %d\n", mode);
+               break;
+       }
+       __raw_writel(tcon, S3C2410_TCON);
+}
+
+static int samsung_set_next_event(unsigned long cycles,
+                               struct clock_event_device *evt)
+{
+       samsung_time_setup(timer_source.event_id, cycles);
+       samsung_time_start(timer_source.event_id, NON_PERIODIC);
+
+       return 0;
+}
+
+static void samsung_set_mode(enum clock_event_mode mode,
+                               struct clock_event_device *evt)
+{
+       samsung_time_stop(timer_source.event_id);
+
+       switch (mode) {
+       case CLOCK_EVT_MODE_PERIODIC:
+               samsung_time_setup(timer_source.event_id, clock_count_per_tick);
+               samsung_time_start(timer_source.event_id, PERIODIC);
+               break;
+
+       case CLOCK_EVT_MODE_ONESHOT:
+               break;
+
+       case CLOCK_EVT_MODE_UNUSED:
+       case CLOCK_EVT_MODE_SHUTDOWN:
+               break;
+
+       case CLOCK_EVT_MODE_RESUME:
+               samsung_timer_resume();
+               break;
+       }
+}
+
+static void samsung_timer_resume(void)
+{
+       /* event timer restart */
+       samsung_time_setup(timer_source.event_id, clock_count_per_tick);
+       samsung_time_start(timer_source.event_id, PERIODIC);
+
+       /* source timer restart */
+       samsung_time_setup(timer_source.source_id, TCNT_MAX);
+       samsung_time_start(timer_source.source_id, PERIODIC);
+}
+
+void __init samsung_set_timer_source(enum samsung_timer_mode event,
+                                enum samsung_timer_mode source)
+{
+       s3c_device_timer[event].dev.bus = &platform_bus_type;
+       s3c_device_timer[source].dev.bus = &platform_bus_type;
+
+       timer_source.event_id = event;
+       timer_source.source_id = source;
+}
+
+static struct clock_event_device time_event_device = {
+       .name           = "samsung_event_timer",
+       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+       .rating         = 200,
+       .set_next_event = samsung_set_next_event,
+       .set_mode       = samsung_set_mode,
+};
+
+static irqreturn_t samsung_clock_event_isr(int irq, void *dev_id)
+{
+       struct clock_event_device *evt = dev_id;
+
+       evt->event_handler(evt);
+
+       return IRQ_HANDLED;
+}
+
+static struct irqaction samsung_clock_event_irq = {
+       .name           = "samsung_time_irq",
+       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+       .handler        = samsung_clock_event_isr,
+       .dev_id         = &time_event_device,
+};
+
+static void __init samsung_clockevent_init(void)
+{
+       unsigned long pclk;
+       unsigned long clock_rate;
+       unsigned int irq_number;
+       struct clk *tscaler;
+
+       pclk = clk_get_rate(timerclk);
+
+       tscaler = clk_get_parent(tdiv_event);
+
+       clk_set_rate(tscaler, pclk / TSCALER_DIV);
+       clk_set_rate(tdiv_event, pclk / TDIV);
+       clk_set_parent(tin_event, tdiv_event);
+
+       clock_rate = clk_get_rate(tin_event);
+       clock_count_per_tick = clock_rate / HZ;
+
+       time_event_device.cpumask = cpumask_of(0);
+       clockevents_config_and_register(&time_event_device, clock_rate, 1, -1);
+
+       irq_number = timer_source.event_id + IRQ_TIMER0;
+       setup_irq(irq_number, &samsung_clock_event_irq);
+}
+
+static void __iomem *samsung_timer_reg(void)
+{
+       unsigned long offset = 0;
+
+       switch (timer_source.source_id) {
+       case SAMSUNG_PWM0:
+       case SAMSUNG_PWM1:
+       case SAMSUNG_PWM2:
+       case SAMSUNG_PWM3:
+               offset = (timer_source.source_id * 0x0c) + 0x14;
+               break;
+
+       case SAMSUNG_PWM4:
+               offset = 0x40;
+               break;
+
+       default:
+               printk(KERN_ERR "Invalid Timer %d\n", timer_source.source_id);
+               return NULL;
+       }
+
+       return S3C_TIMERREG(offset);
+}
+
+/*
+ * Override the global weak sched_clock symbol with this
+ * local implementation which uses the clocksource to get some
+ * better resolution when scheduling the kernel. We accept that
+ * this wraps around for now, since it is just a relative time
+ * stamp. (Inspired by U300 implementation.)
+ */
+static u32 notrace samsung_read_sched_clock(void)
+{
+       void __iomem *reg = samsung_timer_reg();
+
+       if (!reg)
+               return 0;
+
+       return ~__raw_readl(reg);
+}
+
+static void __init samsung_clocksource_init(void)
+{
+       unsigned long pclk;
+       unsigned long clock_rate;
+
+       pclk = clk_get_rate(timerclk);
+
+       clk_set_rate(tdiv_source, pclk / TDIV);
+       clk_set_parent(tin_source, tdiv_source);
+
+       clock_rate = clk_get_rate(tin_source);
+
+       samsung_time_setup(timer_source.source_id, TCNT_MAX);
+       samsung_time_start(timer_source.source_id, PERIODIC);
+
+       setup_sched_clock(samsung_read_sched_clock, TSIZE, clock_rate);
+
+       if (clocksource_mmio_init(samsung_timer_reg(), "samsung_clocksource_timer",
+                       clock_rate, 250, TSIZE, clocksource_mmio_readl_down))
+               panic("samsung_clocksource_timer: can't register clocksource\n");
+}
+
+static void __init samsung_timer_resources(void)
+{
+
+       unsigned long event_id = timer_source.event_id;
+       unsigned long source_id = timer_source.source_id;
+       char devname[15];
+
+       timerclk = clk_get(NULL, "timers");
+       if (IS_ERR(timerclk))
+               panic("failed to get timers clock for timer");
+
+       clk_enable(timerclk);
+
+       sprintf(devname, "s3c24xx-pwm.%lu", event_id);
+       s3c_device_timer[event_id].id = event_id;
+       s3c_device_timer[event_id].dev.init_name = devname;
+
+       tin_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tin");
+       if (IS_ERR(tin_event))
+               panic("failed to get pwm-tin clock for event timer");
+
+       tdiv_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tdiv");
+       if (IS_ERR(tdiv_event))
+               panic("failed to get pwm-tdiv clock for event timer");
+
+       clk_enable(tin_event);
+
+       sprintf(devname, "s3c24xx-pwm.%lu", source_id);
+       s3c_device_timer[source_id].id = source_id;
+       s3c_device_timer[source_id].dev.init_name = devname;
+
+       tin_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tin");
+       if (IS_ERR(tin_source))
+               panic("failed to get pwm-tin clock for source timer");
+
+       tdiv_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tdiv");
+       if (IS_ERR(tdiv_source))
+               panic("failed to get pwm-tdiv clock for source timer");
+
+       clk_enable(tin_source);
+}
+
+void __init samsung_timer_init(void)
+{
+       samsung_timer_resources();
+       samsung_clockevent_init();
+       samsung_clocksource_init();
+}
diff --git a/arch/arm/plat-samsung/time.c b/arch/arm/plat-samsung/time.c
deleted file mode 100644 (file)
index 73defd0..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/* linux/arch/arm/plat-samsung/time.c
- *
- * Copyright (C) 2003-2005 Simtec Electronics
- *     Ben Dooks, <ben@simtec.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/syscore_ops.h>
-
-#include <asm/mach-types.h>
-
-#include <asm/irq.h>
-#include <mach/map.h>
-#include <plat/regs-timer.h>
-#include <mach/regs-irq.h>
-#include <asm/mach/time.h>
-#include <mach/tick.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-static unsigned long timer_startval;
-static unsigned long timer_usec_ticks;
-
-#ifndef TICK_MAX
-#define TICK_MAX (0xffff)
-#endif
-
-#define TIMER_USEC_SHIFT 16
-
-/* we use the shifted arithmetic to work out the ratio of timer ticks
- * to usecs, as often the peripheral clock is not a nice even multiple
- * of 1MHz.
- *
- * shift of 14 and 15 are too low for the 12MHz, 16 seems to be ok
- * for the current HZ value of 200 without producing overflows.
- *
- * Original patch by Dimitry Andric, updated by Ben Dooks
-*/
-
-
-/* timer_mask_usec_ticks
- *
- * given a clock and divisor, make the value to pass into timer_ticks_to_usec
- * to scale the ticks into usecs
-*/
-
-static inline unsigned long
-timer_mask_usec_ticks(unsigned long scaler, unsigned long pclk)
-{
-       unsigned long den = pclk / 1000;
-
-       return ((1000 << TIMER_USEC_SHIFT) * scaler + (den >> 1)) / den;
-}
-
-/* timer_ticks_to_usec
- *
- * convert timer ticks to usec.
-*/
-
-static inline unsigned long timer_ticks_to_usec(unsigned long ticks)
-{
-       unsigned long res;
-
-       res = ticks * timer_usec_ticks;
-       res += 1 << (TIMER_USEC_SHIFT - 4);     /* round up slightly */
-
-       return res >> TIMER_USEC_SHIFT;
-}
-
-/***
- * Returns microsecond  since last clock interrupt.  Note that interrupts
- * will have been disabled by do_gettimeoffset()
- * IRQs are disabled before entering here from do_gettimeofday()
- */
-
-static u32 s3c2410_gettimeoffset(void)
-{
-       unsigned long tdone;
-       unsigned long tval;
-
-       /* work out how many ticks have gone since last timer interrupt */
-
-       tval =  __raw_readl(S3C2410_TCNTO(4));
-       tdone = timer_startval - tval;
-
-       /* check to see if there is an interrupt pending */
-
-       if (s3c24xx_ostimer_pending()) {
-               /* re-read the timer, and try and fix up for the missed
-                * interrupt. Note, the interrupt may go off before the
-                * timer has re-loaded from wrapping.
-                */
-
-               tval =  __raw_readl(S3C2410_TCNTO(4));
-               tdone = timer_startval - tval;
-
-               if (tval != 0)
-                       tdone += timer_startval;
-       }
-
-       return timer_ticks_to_usec(tdone) * 1000;
-}
-
-
-/*
- * IRQ handler for the timer
- */
-static irqreturn_t
-s3c2410_timer_interrupt(int irq, void *dev_id)
-{
-       timer_tick();
-       return IRQ_HANDLED;
-}
-
-static struct irqaction s3c2410_timer_irq = {
-       .name           = "S3C2410 Timer Tick",
-       .flags          = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-       .handler        = s3c2410_timer_interrupt,
-};
-
-#define use_tclk1_12() ( \
-       machine_is_bast()       || \
-       machine_is_vr1000()     || \
-       machine_is_anubis()     || \
-       machine_is_osiris())
-
-static struct clk *tin;
-static struct clk *tdiv;
-static struct clk *timerclk;
-
-/*
- * Set up timer interrupt, and return the current time in seconds.
- *
- * Currently we only use timer4, as it is the only timer which has no
- * other function that can be exploited externally
- */
-static void s3c2410_timer_setup (void)
-{
-       unsigned long tcon;
-       unsigned long tcnt;
-       unsigned long tcfg1;
-       unsigned long tcfg0;
-
-       tcnt = TICK_MAX;  /* default value for tcnt */
-
-       /* configure the system for whichever machine is in use */
-
-       if (use_tclk1_12()) {
-               /* timer is at 12MHz, scaler is 1 */
-               timer_usec_ticks = timer_mask_usec_ticks(1, 12000000);
-               tcnt = 12000000 / HZ;
-
-               tcfg1 = __raw_readl(S3C2410_TCFG1);
-               tcfg1 &= ~S3C2410_TCFG1_MUX4_MASK;
-               tcfg1 |= S3C2410_TCFG1_MUX4_TCLK1;
-               __raw_writel(tcfg1, S3C2410_TCFG1);
-       } else {
-               unsigned long pclk;
-               struct clk *tscaler;
-
-               /* for the h1940 (and others), we use the pclk from the core
-                * to generate the timer values. since values around 50 to
-                * 70MHz are not values we can directly generate the timer
-                * value from, we need to pre-scale and divide before using it.
-                *
-                * for instance, using 50.7MHz and dividing by 6 gives 8.45MHz
-                * (8.45 ticks per usec)
-                */
-
-               pclk = clk_get_rate(timerclk);
-
-               /* configure clock tick */
-
-               timer_usec_ticks = timer_mask_usec_ticks(6, pclk);
-
-               tscaler = clk_get_parent(tdiv);
-
-               clk_set_rate(tscaler, pclk / 3);
-               clk_set_rate(tdiv, pclk / 6);
-               clk_set_parent(tin, tdiv);
-
-               tcnt = clk_get_rate(tin) / HZ;
-       }
-
-       tcon = __raw_readl(S3C2410_TCON);
-       tcfg0 = __raw_readl(S3C2410_TCFG0);
-       tcfg1 = __raw_readl(S3C2410_TCFG1);
-
-       /* timers reload after counting zero, so reduce the count by 1 */
-
-       tcnt--;
-
-       printk(KERN_DEBUG "timer tcon=%08lx, tcnt %04lx, tcfg %08lx,%08lx, usec %08lx\n",
-              tcon, tcnt, tcfg0, tcfg1, timer_usec_ticks);
-
-       /* check to see if timer is within 16bit range... */
-       if (tcnt > TICK_MAX) {
-               panic("setup_timer: HZ is too small, cannot configure timer!");
-               return;
-       }
-
-       __raw_writel(tcfg1, S3C2410_TCFG1);
-       __raw_writel(tcfg0, S3C2410_TCFG0);
-
-       timer_startval = tcnt;
-       __raw_writel(tcnt, S3C2410_TCNTB(4));
-
-       /* ensure timer is stopped... */
-
-       tcon &= ~(7<<20);
-       tcon |= S3C2410_TCON_T4RELOAD;
-       tcon |= S3C2410_TCON_T4MANUALUPD;
-
-       __raw_writel(tcon, S3C2410_TCON);
-       __raw_writel(tcnt, S3C2410_TCNTB(4));
-       __raw_writel(tcnt, S3C2410_TCMPB(4));
-
-       /* start the timer running */
-       tcon |= S3C2410_TCON_T4START;
-       tcon &= ~S3C2410_TCON_T4MANUALUPD;
-       __raw_writel(tcon, S3C2410_TCON);
-}
-
-static void __init s3c2410_timer_resources(void)
-{
-       struct platform_device tmpdev;
-
-       tmpdev.dev.bus = &platform_bus_type;
-       tmpdev.id = 4;
-
-       timerclk = clk_get(NULL, "timers");
-       if (IS_ERR(timerclk))
-               panic("failed to get clock for system timer");
-
-       clk_enable(timerclk);
-
-       if (!use_tclk1_12()) {
-               tmpdev.id = 4;
-               tmpdev.dev.init_name = "s3c24xx-pwm.4";
-               tin = clk_get(&tmpdev.dev, "pwm-tin");
-               if (IS_ERR(tin))
-                       panic("failed to get pwm-tin clock for system timer");
-
-               tdiv = clk_get(&tmpdev.dev, "pwm-tdiv");
-               if (IS_ERR(tdiv))
-                       panic("failed to get pwm-tdiv clock for system timer");
-       }
-
-       clk_enable(tin);
-}
-
-static struct syscore_ops s3c24xx_syscore_ops = {
-       .resume         = s3c2410_timer_setup,
-};
-
-void __init s3c24xx_timer_init(void)
-{
-       arch_gettimeoffset = s3c2410_gettimeoffset;
-
-       s3c2410_timer_resources();
-       s3c2410_timer_setup();
-       setup_irq(IRQ_TIMER4, &s3c2410_timer_irq);
-       register_syscore_ops(&s3c24xx_syscore_ops);
-}
index 224b44ab534ee4682ffb004e50c3d92b86a39a85..70b8cd4021c46cb800cbf76bd21a001e2e73e86c 100644 (file)
@@ -261,7 +261,7 @@ static void __init create_mapping(phys_addr_t phys, unsigned long virt,
 void __iomem * __init early_io_map(phys_addr_t phys, unsigned long virt)
 {
        unsigned long size, mask;
-       bool page64k = IS_ENABLED(ARM64_64K_PAGES);
+       bool page64k = IS_ENABLED(CONFIG_ARM64_64K_PAGES);
        pgd_t *pgd;
        pud_t *pud;
        pmd_t *pmd;
index e34f565f595ae2d54613309af8013b2e735e9881..6f7dc8b7b35ccc8ba435caa08ed1a8ab8e7863a5 100644 (file)
@@ -291,7 +291,6 @@ cpu_idle (void)
                }
 
                if (!need_resched()) {
-                       void (*idle)(void);
 #ifdef CONFIG_SMP
                        min_xtp();
 #endif
@@ -299,9 +298,7 @@ cpu_idle (void)
                        if (mark_idle)
                                (*mark_idle)(1);
 
-                       if (!idle)
-                               idle = default_idle;
-                       (*idle)();
+                       default_idle();
                        if (mark_idle)
                                (*mark_idle)(0);
 #ifdef CONFIG_SMP
index f3eab8594d9f873432deb94c770db354f20ffc76..d44a571e45a79dae9b7976c7e281c93021b2847e 100644 (file)
 #include <asm/code-patching.h>
 #include <asm/machdep.h>
 
+#if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64)
 extern void epapr_ev_idle(void);
 extern u32 epapr_ev_idle_start[];
+#endif
 
 bool epapr_paravirt_enabled;
 
@@ -47,11 +49,15 @@ static int __init epapr_paravirt_init(void)
 
        for (i = 0; i < (len / 4); i++) {
                patch_instruction(epapr_hypercall_start + i, insts[i]);
+#if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64)
                patch_instruction(epapr_ev_idle_start + i, insts[i]);
+#endif
        }
 
+#if !defined(CONFIG_64BIT) || defined(CONFIG_PPC_BOOK3E_64)
        if (of_get_property(hyper_node, "has-idle", NULL))
                ppc_md.power_save = epapr_ev_idle;
+#endif
 
        epapr_paravirt_enabled = true;
 
index 200afa5bcfb73da1efa111c5b22ad62b09b3bb74..56bd92362ce131e8742f33d56ff8613e05bcced0 100644 (file)
@@ -1066,78 +1066,6 @@ unrecov_user_slb:
 #endif /* __DISABLED__ */
 
 
-/*
- * r13 points to the PACA, r9 contains the saved CR,
- * r12 contain the saved SRR1, SRR0 is still ready for return
- * r3 has the faulting address
- * r9 - r13 are saved in paca->exslb.
- * r3 is saved in paca->slb_r3
- * We assume we aren't going to take any exceptions during this procedure.
- */
-_GLOBAL(slb_miss_realmode)
-       mflr    r10
-#ifdef CONFIG_RELOCATABLE
-       mtctr   r11
-#endif
-
-       stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
-       std     r10,PACA_EXSLB+EX_LR(r13)       /* save LR */
-
-       bl      .slb_allocate_realmode
-
-       /* All done -- return from exception. */
-
-       ld      r10,PACA_EXSLB+EX_LR(r13)
-       ld      r3,PACA_EXSLB+EX_R3(r13)
-       lwz     r9,PACA_EXSLB+EX_CCR(r13)       /* get saved CR */
-
-       mtlr    r10
-
-       andi.   r10,r12,MSR_RI  /* check for unrecoverable exception */
-       beq-    2f
-
-.machine       push
-.machine       "power4"
-       mtcrf   0x80,r9
-       mtcrf   0x01,r9         /* slb_allocate uses cr0 and cr7 */
-.machine       pop
-
-       RESTORE_PPR_PACA(PACA_EXSLB, r9)
-       ld      r9,PACA_EXSLB+EX_R9(r13)
-       ld      r10,PACA_EXSLB+EX_R10(r13)
-       ld      r11,PACA_EXSLB+EX_R11(r13)
-       ld      r12,PACA_EXSLB+EX_R12(r13)
-       ld      r13,PACA_EXSLB+EX_R13(r13)
-       rfid
-       b       .       /* prevent speculative execution */
-
-2:     mfspr   r11,SPRN_SRR0
-       ld      r10,PACAKBASE(r13)
-       LOAD_HANDLER(r10,unrecov_slb)
-       mtspr   SPRN_SRR0,r10
-       ld      r10,PACAKMSR(r13)
-       mtspr   SPRN_SRR1,r10
-       rfid
-       b       .
-
-unrecov_slb:
-       EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
-       DISABLE_INTS
-       bl      .save_nvgprs
-1:     addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .unrecoverable_exception
-       b       1b
-
-
-#ifdef CONFIG_PPC_970_NAP
-power4_fixup_nap:
-       andc    r9,r9,r10
-       std     r9,TI_LOCAL_FLAGS(r11)
-       ld      r10,_LINK(r1)           /* make idle task do the */
-       std     r10,_NIP(r1)            /* equivalent of a blr */
-       blr
-#endif
-
        .align  7
        .globl alignment_common
 alignment_common:
@@ -1335,6 +1263,78 @@ _GLOBAL(opal_mc_secondary_handler)
 #endif /* CONFIG_PPC_POWERNV */
 
 
+/*
+ * r13 points to the PACA, r9 contains the saved CR,
+ * r12 contain the saved SRR1, SRR0 is still ready for return
+ * r3 has the faulting address
+ * r9 - r13 are saved in paca->exslb.
+ * r3 is saved in paca->slb_r3
+ * We assume we aren't going to take any exceptions during this procedure.
+ */
+_GLOBAL(slb_miss_realmode)
+       mflr    r10
+#ifdef CONFIG_RELOCATABLE
+       mtctr   r11
+#endif
+
+       stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
+       std     r10,PACA_EXSLB+EX_LR(r13)       /* save LR */
+
+       bl      .slb_allocate_realmode
+
+       /* All done -- return from exception. */
+
+       ld      r10,PACA_EXSLB+EX_LR(r13)
+       ld      r3,PACA_EXSLB+EX_R3(r13)
+       lwz     r9,PACA_EXSLB+EX_CCR(r13)       /* get saved CR */
+
+       mtlr    r10
+
+       andi.   r10,r12,MSR_RI  /* check for unrecoverable exception */
+       beq-    2f
+
+.machine       push
+.machine       "power4"
+       mtcrf   0x80,r9
+       mtcrf   0x01,r9         /* slb_allocate uses cr0 and cr7 */
+.machine       pop
+
+       RESTORE_PPR_PACA(PACA_EXSLB, r9)
+       ld      r9,PACA_EXSLB+EX_R9(r13)
+       ld      r10,PACA_EXSLB+EX_R10(r13)
+       ld      r11,PACA_EXSLB+EX_R11(r13)
+       ld      r12,PACA_EXSLB+EX_R12(r13)
+       ld      r13,PACA_EXSLB+EX_R13(r13)
+       rfid
+       b       .       /* prevent speculative execution */
+
+2:     mfspr   r11,SPRN_SRR0
+       ld      r10,PACAKBASE(r13)
+       LOAD_HANDLER(r10,unrecov_slb)
+       mtspr   SPRN_SRR0,r10
+       ld      r10,PACAKMSR(r13)
+       mtspr   SPRN_SRR1,r10
+       rfid
+       b       .
+
+unrecov_slb:
+       EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
+       DISABLE_INTS
+       bl      .save_nvgprs
+1:     addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .unrecoverable_exception
+       b       1b
+
+
+#ifdef CONFIG_PPC_970_NAP
+power4_fixup_nap:
+       andc    r9,r9,r10
+       std     r9,TI_LOCAL_FLAGS(r11)
+       ld      r10,_LINK(r1)           /* make idle task do the */
+       std     r10,_NIP(r1)            /* equivalent of a blr */
+       blr
+#endif
+
 /*
  * Hash table stuff
  */
index c20d1ce62dc6a0a236280ab51b7ac8386fb1c32b..e709884d0ef9edbdd0b7228f180814bef1c0b174 100644 (file)
@@ -382,14 +382,14 @@ HYPERVISOR_console_io(int cmd, int count, char *str)
        return _hypercall3(int, console_io, cmd, count, str);
 }
 
-extern int __must_check HYPERVISOR_physdev_op_compat(int, void *);
+extern int __must_check xen_physdev_op_compat(int, void *);
 
 static inline int
 HYPERVISOR_physdev_op(int cmd, void *arg)
 {
        int rc = _hypercall2(int, physdev_op, cmd, arg);
        if (unlikely(rc == -ENOSYS))
-               rc = HYPERVISOR_physdev_op_compat(cmd, arg);
+               rc = xen_physdev_op_compat(cmd, arg);
        return rc;
 }
 
index 892ce40a7470515543e09d80115efae395717b0b..7a060f4b411f753ed065c389b705e7b2a010ab7b 100644 (file)
@@ -44,6 +44,7 @@
 #define SNB_C1_AUTO_UNDEMOTE           (1UL << 27)
 #define SNB_C3_AUTO_UNDEMOTE           (1UL << 28)
 
+#define MSR_PLATFORM_INFO              0x000000ce
 #define MSR_MTRRcap                    0x000000fe
 #define MSR_IA32_BBL_CR_CTL            0x00000119
 #define MSR_IA32_BBL_CR_CTL3           0x0000011e
index 7890bc8389524d4a1e934e23b041ab1010abf4f7..d893e8ed8ac96559b2175b00c3d68d71658a4105 100644 (file)
@@ -90,13 +90,13 @@ microcode_phys(struct microcode_intel **mc_saved_tmp,
        struct microcode_intel ***mc_saved;
 
        mc_saved = (struct microcode_intel ***)
-                  __pa_symbol(&mc_saved_data->mc_saved);
+                  __pa_nodebug(&mc_saved_data->mc_saved);
        for (i = 0; i < mc_saved_data->mc_saved_count; i++) {
                struct microcode_intel *p;
 
                p = *(struct microcode_intel **)
-                       __pa(mc_saved_data->mc_saved + i);
-               mc_saved_tmp[i] = (struct microcode_intel *)__pa(p);
+                       __pa_nodebug(mc_saved_data->mc_saved + i);
+               mc_saved_tmp[i] = (struct microcode_intel *)__pa_nodebug(p);
        }
 }
 #endif
@@ -562,7 +562,7 @@ scan_microcode(unsigned long start, unsigned long end,
        struct cpio_data cd;
        long offset = 0;
 #ifdef CONFIG_X86_32
-       char *p = (char *)__pa_symbol(ucode_name);
+       char *p = (char *)__pa_nodebug(ucode_name);
 #else
        char *p = ucode_name;
 #endif
@@ -630,8 +630,8 @@ static void __cpuinit print_ucode(struct ucode_cpu_info *uci)
        if (mc_intel == NULL)
                return;
 
-       delay_ucode_info_p = (int *)__pa_symbol(&delay_ucode_info);
-       current_mc_date_p = (int *)__pa_symbol(&current_mc_date);
+       delay_ucode_info_p = (int *)__pa_nodebug(&delay_ucode_info);
+       current_mc_date_p = (int *)__pa_nodebug(&current_mc_date);
 
        *delay_ucode_info_p = 1;
        *current_mc_date_p = mc_intel->hdr.date;
@@ -659,8 +659,8 @@ static inline void __cpuinit print_ucode(struct ucode_cpu_info *uci)
 }
 #endif
 
-static int apply_microcode_early(struct mc_saved_data *mc_saved_data,
-                                struct ucode_cpu_info *uci)
+static int __cpuinit apply_microcode_early(struct mc_saved_data *mc_saved_data,
+                                          struct ucode_cpu_info *uci)
 {
        struct microcode_intel *mc_intel;
        unsigned int val[2];
@@ -741,15 +741,15 @@ load_ucode_intel_bsp(void)
 #ifdef CONFIG_X86_32
        struct boot_params *boot_params_p;
 
-       boot_params_p = (struct boot_params *)__pa_symbol(&boot_params);
+       boot_params_p = (struct boot_params *)__pa_nodebug(&boot_params);
        ramdisk_image = boot_params_p->hdr.ramdisk_image;
        ramdisk_size  = boot_params_p->hdr.ramdisk_size;
        initrd_start_early = ramdisk_image;
        initrd_end_early = initrd_start_early + ramdisk_size;
 
        _load_ucode_intel_bsp(
-               (struct mc_saved_data *)__pa_symbol(&mc_saved_data),
-               (unsigned long *)__pa_symbol(&mc_saved_in_initrd),
+               (struct mc_saved_data *)__pa_nodebug(&mc_saved_data),
+               (unsigned long *)__pa_nodebug(&mc_saved_in_initrd),
                initrd_start_early, initrd_end_early, &uci);
 #else
        ramdisk_image = boot_params.hdr.ramdisk_image;
@@ -772,10 +772,10 @@ void __cpuinit load_ucode_intel_ap(void)
        unsigned long *initrd_start_p;
 
        mc_saved_in_initrd_p =
-               (unsigned long *)__pa_symbol(mc_saved_in_initrd);
-       mc_saved_data_p = (struct mc_saved_data *)__pa_symbol(&mc_saved_data);
-       initrd_start_p = (unsigned long *)__pa_symbol(&initrd_start);
-       initrd_start_addr = (unsigned long)__pa_symbol(*initrd_start_p);
+               (unsigned long *)__pa_nodebug(mc_saved_in_initrd);
+       mc_saved_data_p = (struct mc_saved_data *)__pa_nodebug(&mc_saved_data);
+       initrd_start_p = (unsigned long *)__pa_nodebug(&initrd_start);
+       initrd_start_addr = (unsigned long)__pa_nodebug(*initrd_start_p);
 #else
        mc_saved_data_p = &mc_saved_data;
        mc_saved_in_initrd_p = mc_saved_in_initrd;
index 05928aae911e0addaaaf1bd0fce5002ba3c9f96e..906fea3157919dcffabfe2bc4b23a1becb98aa7c 100644 (file)
@@ -74,10 +74,10 @@ copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest)
        char c;
        unsigned zero_len;
 
-       for (; len; --len) {
+       for (; len; --len, to++) {
                if (__get_user_nocheck(c, from++, sizeof(char)))
                        break;
-               if (__put_user_nocheck(c, to++, sizeof(char)))
+               if (__put_user_nocheck(c, to, sizeof(char)))
                        break;
        }
 
index e8e34938c57d86be6ba133abb033fbd7616d8f9a..6afbb2ca9a0ac450f79c6628b7cd9cd7c2ceeccf 100644 (file)
@@ -1467,8 +1467,6 @@ static void __init xen_write_cr3_init(unsigned long cr3)
        __xen_write_cr3(true, cr3);
 
        xen_mc_issue(PARAVIRT_LAZY_CPU);  /* interrupts restored */
-
-       pv_mmu_ops.write_cr3 = &xen_write_cr3;
 }
 #endif
 
@@ -2122,6 +2120,7 @@ static void __init xen_post_allocator_init(void)
 #endif
 
 #ifdef CONFIG_X86_64
+       pv_mmu_ops.write_cr3 = &xen_write_cr3;
        SetPagePinned(virt_to_page(level3_user_vsyscall));
 #endif
        xen_mark_init_mm_pinned();
index db8f1b5078570fe98afb8dd748636060511ba683..cc2b827a853cdea378f1c54edeadd65546b33651 100644 (file)
@@ -444,7 +444,7 @@ int blkdev_issue_flush(struct block_device *bdev, gfp_t gfp_mask,
         * copied from blk_rq_pos(rq).
         */
        if (error_sector)
-               *error_sector = bio->bi_sector;
+               *error_sector = bio->bi_sector;
 
        if (!bio_flagged(bio, BIO_UPTODATE))
                ret = -EIO;
index 789cdea05893bb8e3420ede5d1aa65e7af408e1b..ae95ee6a58aad6d005affa10bb270bdf1008e986 100644 (file)
@@ -257,6 +257,7 @@ void delete_partition(struct gendisk *disk, int partno)
 
        hd_struct_put(part);
 }
+EXPORT_SYMBOL(delete_partition);
 
 static ssize_t whole_disk_show(struct device *dev,
                               struct device_attribute *attr, char *buf)
index 1e5d8a40101e274f5d6ce2bfe1a24a486a671af7..fefc2ca7cc3e0199b5f98b707107d424dd40b8eb 100644 (file)
@@ -405,7 +405,7 @@ int apei_estatus_check(const struct acpi_hest_generic_status *estatus)
                return rc;
        data_len = estatus->data_length;
        gdata = (struct acpi_hest_generic_data *)(estatus + 1);
-       while (data_len > sizeof(*gdata)) {
+       while (data_len >= sizeof(*gdata)) {
                gedata_len = gdata->error_data_length;
                if (gedata_len > data_len - sizeof(*gdata))
                        return -EINVAL;
index 0ac546d5e53f5b0f079792c71419dd07001fe892..5ff17306612771d04dd684020041fe61056906ab 100644 (file)
@@ -646,6 +646,7 @@ static void handle_root_bridge_insertion(acpi_handle handle)
 
 static void handle_root_bridge_removal(struct acpi_device *device)
 {
+       acpi_status status;
        struct acpi_eject_event *ej_event;
 
        ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
@@ -661,7 +662,9 @@ static void handle_root_bridge_removal(struct acpi_device *device)
        ej_event->device = device;
        ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
 
-       acpi_bus_hot_remove_device(ej_event);
+       status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, ej_event);
+       if (ACPI_FAILURE(status))
+               kfree(ej_event);
 }
 
 static void _handle_hotplug_event_root(struct work_struct *work)
@@ -676,8 +679,9 @@ static void _handle_hotplug_event_root(struct work_struct *work)
        handle = hp_work->handle;
        type = hp_work->type;
 
-       root = acpi_pci_find_root(handle);
+       acpi_scan_lock_acquire();
 
+       root = acpi_pci_find_root(handle);
        acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
 
        switch (type) {
@@ -711,6 +715,7 @@ static void _handle_hotplug_event_root(struct work_struct *work)
                break;
        }
 
+       acpi_scan_lock_release();
        kfree(hp_work); /* allocated in handle_hotplug_event_bridge */
        kfree(buffer.pointer);
 }
index 24213033fbae2aee5f033c2a776d2b37084fc88e..9c1a435d10e69c8228516346832a8d2d2d242890 100644 (file)
@@ -193,6 +193,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
        },
        {
        .callback = init_nvs_nosave,
+       .ident = "Sony Vaio VGN-FW21M",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW21M"),
+               },
+       },
+       {
+       .callback = init_nvs_nosave,
        .ident = "Sony Vaio VPCEB17FX",
        .matches = {
                DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
index 5dc0daed8fac523f5d631c3cd4a022f6fb4c5aca..b81ddfea1da075ad3c1d0cbeb9ab7bf854593436 100644 (file)
@@ -532,11 +532,11 @@ config BLK_DEV_RBD
          If unsure, say N.
 
 config BLK_DEV_RSXX
-       tristate "RamSam PCIe Flash SSD Device Driver"
+       tristate "IBM FlashSystem 70/80 PCIe SSD Device Driver"
        depends on PCI
        help
          Device driver for IBM's high speed PCIe SSD
-         storage devices: RamSan-70 and RamSan-80.
+         storage devices: FlashSystem-70 and FlashSystem-80.
 
          To compile this driver as a module, choose M here: the
          module will be called rsxx.
index ade58bc8f3c4dee67f69edde4ce20b1ef18d7cc8..1c1b8e544aa250d38710b47c19353c9ef5773c6c 100644 (file)
@@ -4206,7 +4206,7 @@ static int cciss_find_cfgtables(ctlr_info_t *h)
        if (rc)
                return rc;
        h->cfgtable = remap_pci_mem(pci_resource_start(h->pdev,
-               cfg_base_addr_index) + cfg_offset, sizeof(h->cfgtable));
+               cfg_base_addr_index) + cfg_offset, sizeof(*h->cfgtable));
        if (!h->cfgtable)
                return -ENOMEM;
        rc = write_driver_ver_to_cfgtable(h->cfgtable);
index 747bb2af69dcc55fec530466a9f55d06914ba8f7..fe5f6403417f892d744a034ea0bdda9a21596fda 100644 (file)
@@ -1044,12 +1044,29 @@ static int loop_clr_fd(struct loop_device *lo)
        lo->lo_state = Lo_unbound;
        /* This is safe: open() is still holding a reference. */
        module_put(THIS_MODULE);
-       if (lo->lo_flags & LO_FLAGS_PARTSCAN && bdev)
-               ioctl_by_bdev(bdev, BLKRRPART, 0);
        lo->lo_flags = 0;
        if (!part_shift)
                lo->lo_disk->flags |= GENHD_FL_NO_PART_SCAN;
        mutex_unlock(&lo->lo_ctl_mutex);
+
+       /*
+        * Remove all partitions, since BLKRRPART won't remove user
+        * added partitions when max_part=0
+        */
+       if (bdev) {
+               struct disk_part_iter piter;
+               struct hd_struct *part;
+
+               mutex_lock_nested(&bdev->bd_mutex, 1);
+               invalidate_partition(bdev->bd_disk, 0);
+               disk_part_iter_init(&piter, bdev->bd_disk,
+                                       DISK_PITER_INCL_EMPTY);
+               while ((part = disk_part_iter_next(&piter)))
+                       delete_partition(bdev->bd_disk, part->partno);
+               disk_part_iter_exit(&piter);
+               mutex_unlock(&bdev->bd_mutex);
+       }
+
        /*
         * Need not hold lo_ctl_mutex to fput backing file.
         * Calling fput holding lo_ctl_mutex triggers a circular
@@ -1623,6 +1640,7 @@ static int loop_add(struct loop_device **l, int i)
                goto out_free_dev;
        i = err;
 
+       err = -ENOMEM;
        lo->lo_queue = blk_alloc_queue(GFP_KERNEL);
        if (!lo->lo_queue)
                goto out_free_dev;
index 1788f491e0fb50e13cefb2f81c286d41721e75ef..076ae7f1b781e0b1586631b2708471ce98f978c1 100644 (file)
@@ -890,8 +890,10 @@ static int mg_probe(struct platform_device *plat_dev)
        gpio_direction_output(host->rst, 1);
 
        /* reset out pin */
-       if (!(prv_data->dev_attr & MG_DEV_MASK))
+       if (!(prv_data->dev_attr & MG_DEV_MASK)) {
+               err = -EINVAL;
                goto probe_err_3a;
+       }
 
        if (prv_data->dev_attr != MG_BOOT_DEV) {
                rsc = platform_get_resource_byname(plat_dev, IORESOURCE_IO,
index 11cc9522cdd439ff3db29825037c4f866bc28abb..92250af84e7d151a8da57ed2cf6d22d8e3313e9d 100644 (file)
@@ -4224,6 +4224,7 @@ static int mtip_pci_probe(struct pci_dev *pdev,
        dd->isr_workq = create_workqueue(dd->workq_name);
        if (!dd->isr_workq) {
                dev_warn(&pdev->dev, "Can't create wq %d\n", dd->instance);
+               rv = -ENOMEM;
                goto block_initialize_err;
        }
 
@@ -4282,7 +4283,8 @@ static int mtip_pci_probe(struct pci_dev *pdev,
        INIT_WORK(&dd->work[7].work, mtip_workq_sdbf7);
 
        pci_set_master(pdev);
-       if (pci_enable_msi(pdev)) {
+       rv = pci_enable_msi(pdev);
+       if (rv) {
                dev_warn(&pdev->dev,
                        "Unable to enable MSI interrupt.\n");
                goto block_initialize_err;
index 6c81a4c040b987e75d4a8b0bb5e4ff65e2108dba..f556f8a8b3f9b476949c6133f39778c49502e380 100644 (file)
@@ -1264,6 +1264,32 @@ static bool obj_request_done_test(struct rbd_obj_request *obj_request)
        return atomic_read(&obj_request->done) != 0;
 }
 
+static void
+rbd_img_obj_request_read_callback(struct rbd_obj_request *obj_request)
+{
+       dout("%s: obj %p img %p result %d %llu/%llu\n", __func__,
+               obj_request, obj_request->img_request, obj_request->result,
+               obj_request->xferred, obj_request->length);
+       /*
+        * ENOENT means a hole in the image.  We zero-fill the
+        * entire length of the request.  A short read also implies
+        * zero-fill to the end of the request.  Either way we
+        * update the xferred count to indicate the whole request
+        * was satisfied.
+        */
+       BUG_ON(obj_request->type != OBJ_REQUEST_BIO);
+       if (obj_request->result == -ENOENT) {
+               zero_bio_chain(obj_request->bio_list, 0);
+               obj_request->result = 0;
+               obj_request->xferred = obj_request->length;
+       } else if (obj_request->xferred < obj_request->length &&
+                       !obj_request->result) {
+               zero_bio_chain(obj_request->bio_list, obj_request->xferred);
+               obj_request->xferred = obj_request->length;
+       }
+       obj_request_done_set(obj_request);
+}
+
 static void rbd_obj_request_complete(struct rbd_obj_request *obj_request)
 {
        dout("%s: obj %p cb %p\n", __func__, obj_request,
@@ -1284,23 +1310,10 @@ static void rbd_osd_read_callback(struct rbd_obj_request *obj_request)
 {
        dout("%s: obj %p result %d %llu/%llu\n", __func__, obj_request,
                obj_request->result, obj_request->xferred, obj_request->length);
-       /*
-        * ENOENT means a hole in the object.  We zero-fill the
-        * entire length of the request.  A short read also implies
-        * zero-fill to the end of the request.  Either way we
-        * update the xferred count to indicate the whole request
-        * was satisfied.
-        */
-       if (obj_request->result == -ENOENT) {
-               zero_bio_chain(obj_request->bio_list, 0);
-               obj_request->result = 0;
-               obj_request->xferred = obj_request->length;
-       } else if (obj_request->xferred < obj_request->length &&
-                       !obj_request->result) {
-               zero_bio_chain(obj_request->bio_list, obj_request->xferred);
-               obj_request->xferred = obj_request->length;
-       }
-       obj_request_done_set(obj_request);
+       if (obj_request->img_request)
+               rbd_img_obj_request_read_callback(obj_request);
+       else
+               obj_request_done_set(obj_request);
 }
 
 static void rbd_osd_write_callback(struct rbd_obj_request *obj_request)
index f35cd0b71f7b5802ae521d046c8b582386e6c6f3..b1c53c0aa450c47ddd38bf2138bb0505f341fc61 100644 (file)
@@ -1,2 +1,2 @@
 obj-$(CONFIG_BLK_DEV_RSXX) += rsxx.o
-rsxx-y := config.o core.o cregs.o dev.o dma.o
+rsxx-objs := config.o core.o cregs.o dev.o dma.o
index a295e7e9ee41c98613ded6756ff725a615b5bafb..10cd530d3e1026fcb270e1b402a3a900363a7765 100644 (file)
 #include "rsxx_priv.h"
 #include "rsxx_cfg.h"
 
-static void initialize_config(void *config)
+static void initialize_config(struct rsxx_card_cfg *cfg)
 {
-       struct rsxx_card_cfg *cfg = config;
-
        cfg->hdr.version = RSXX_CFG_VERSION;
 
        cfg->data.block_size        = RSXX_HW_BLK_SIZE;
        cfg->data.stripe_size       = RSXX_HW_BLK_SIZE;
-       cfg->data.vendor_id         = RSXX_VENDOR_ID_TMS_IBM;
+       cfg->data.vendor_id         = RSXX_VENDOR_ID_IBM;
        cfg->data.cache_order       = (-1);
        cfg->data.intr_coal.mode    = RSXX_INTR_COAL_DISABLED;
        cfg->data.intr_coal.count   = 0;
@@ -181,7 +179,7 @@ int rsxx_load_config(struct rsxx_cardinfo *card)
        } else {
                dev_info(CARD_TO_DEV(card),
                        "Initializing card configuration.\n");
-               initialize_config(card);
+               initialize_config(&card->config);
                st = rsxx_save_config(card);
                if (st)
                        return st;
index e5162487686aef6f429b86655e22e27c9a14cddd..5af21f2db29cd1246397e3b4eed8627ba314adf2 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/reboot.h>
 #include <linux/slab.h>
 #include <linux/bitops.h>
+#include <linux/delay.h>
 
 #include <linux/genhd.h>
 #include <linux/idr.h>
@@ -39,8 +40,8 @@
 
 #define NO_LEGACY 0
 
-MODULE_DESCRIPTION("IBM RamSan PCIe Flash SSD Device Driver");
-MODULE_AUTHOR("IBM <support@ramsan.com>");
+MODULE_DESCRIPTION("IBM FlashSystem 70/80 PCIe SSD Device Driver");
+MODULE_AUTHOR("Joshua Morris/Philip Kelleher, IBM");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRIVER_VERSION);
 
@@ -52,6 +53,13 @@ static DEFINE_IDA(rsxx_disk_ida);
 static DEFINE_SPINLOCK(rsxx_ida_lock);
 
 /*----------------- Interrupt Control & Handling -------------------*/
+
+static void rsxx_mask_interrupts(struct rsxx_cardinfo *card)
+{
+       card->isr_mask = 0;
+       card->ier_mask = 0;
+}
+
 static void __enable_intr(unsigned int *mask, unsigned int intr)
 {
        *mask |= intr;
@@ -71,7 +79,8 @@ static void __disable_intr(unsigned int *mask, unsigned int intr)
  */
 void rsxx_enable_ier(struct rsxx_cardinfo *card, unsigned int intr)
 {
-       if (unlikely(card->halt))
+       if (unlikely(card->halt) ||
+           unlikely(card->eeh_state))
                return;
 
        __enable_intr(&card->ier_mask, intr);
@@ -80,6 +89,9 @@ void rsxx_enable_ier(struct rsxx_cardinfo *card, unsigned int intr)
 
 void rsxx_disable_ier(struct rsxx_cardinfo *card, unsigned int intr)
 {
+       if (unlikely(card->eeh_state))
+               return;
+
        __disable_intr(&card->ier_mask, intr);
        iowrite32(card->ier_mask, card->regmap + IER);
 }
@@ -87,7 +99,8 @@ void rsxx_disable_ier(struct rsxx_cardinfo *card, unsigned int intr)
 void rsxx_enable_ier_and_isr(struct rsxx_cardinfo *card,
                                 unsigned int intr)
 {
-       if (unlikely(card->halt))
+       if (unlikely(card->halt) ||
+           unlikely(card->eeh_state))
                return;
 
        __enable_intr(&card->isr_mask, intr);
@@ -97,6 +110,9 @@ void rsxx_enable_ier_and_isr(struct rsxx_cardinfo *card,
 void rsxx_disable_ier_and_isr(struct rsxx_cardinfo *card,
                                  unsigned int intr)
 {
+       if (unlikely(card->eeh_state))
+               return;
+
        __disable_intr(&card->isr_mask, intr);
        __disable_intr(&card->ier_mask, intr);
        iowrite32(card->ier_mask, card->regmap + IER);
@@ -115,6 +131,9 @@ static irqreturn_t rsxx_isr(int irq, void *pdata)
        do {
                reread_isr = 0;
 
+               if (unlikely(card->eeh_state))
+                       break;
+
                isr = ioread32(card->regmap + ISR);
                if (isr == 0xffffffff) {
                        /*
@@ -161,9 +180,9 @@ static irqreturn_t rsxx_isr(int irq, void *pdata)
 }
 
 /*----------------- Card Event Handler -------------------*/
-static char *rsxx_card_state_to_str(unsigned int state)
+static const char * const rsxx_card_state_to_str(unsigned int state)
 {
-       static char *state_strings[] = {
+       static const char * const state_strings[] = {
                "Unknown", "Shutdown", "Starting", "Formatting",
                "Uninitialized", "Good", "Shutting Down",
                "Fault", "Read Only Fault", "dStroying"
@@ -304,6 +323,192 @@ static int card_shutdown(struct rsxx_cardinfo *card)
        return 0;
 }
 
+static int rsxx_eeh_frozen(struct pci_dev *dev)
+{
+       struct rsxx_cardinfo *card = pci_get_drvdata(dev);
+       int i;
+       int st;
+
+       dev_warn(&dev->dev, "IBM FlashSystem PCI: preparing for slot reset.\n");
+
+       card->eeh_state = 1;
+       rsxx_mask_interrupts(card);
+
+       /*
+        * We need to guarantee that the write for eeh_state and masking
+        * interrupts does not become reordered. This will prevent a possible
+        * race condition with the EEH code.
+        */
+       wmb();
+
+       pci_disable_device(dev);
+
+       st = rsxx_eeh_save_issued_dmas(card);
+       if (st)
+               return st;
+
+       rsxx_eeh_save_issued_creg(card);
+
+       for (i = 0; i < card->n_targets; i++) {
+               if (card->ctrl[i].status.buf)
+                       pci_free_consistent(card->dev, STATUS_BUFFER_SIZE8,
+                                           card->ctrl[i].status.buf,
+                                           card->ctrl[i].status.dma_addr);
+               if (card->ctrl[i].cmd.buf)
+                       pci_free_consistent(card->dev, COMMAND_BUFFER_SIZE8,
+                                           card->ctrl[i].cmd.buf,
+                                           card->ctrl[i].cmd.dma_addr);
+       }
+
+       return 0;
+}
+
+static void rsxx_eeh_failure(struct pci_dev *dev)
+{
+       struct rsxx_cardinfo *card = pci_get_drvdata(dev);
+       int i;
+
+       dev_err(&dev->dev, "IBM FlashSystem PCI: disabling failed card.\n");
+
+       card->eeh_state = 1;
+
+       for (i = 0; i < card->n_targets; i++)
+               del_timer_sync(&card->ctrl[i].activity_timer);
+
+       rsxx_eeh_cancel_dmas(card);
+}
+
+static int rsxx_eeh_fifo_flush_poll(struct rsxx_cardinfo *card)
+{
+       unsigned int status;
+       int iter = 0;
+
+       /* We need to wait for the hardware to reset */
+       while (iter++ < 10) {
+               status = ioread32(card->regmap + PCI_RECONFIG);
+
+               if (status & RSXX_FLUSH_BUSY) {
+                       ssleep(1);
+                       continue;
+               }
+
+               if (status & RSXX_FLUSH_TIMEOUT)
+                       dev_warn(CARD_TO_DEV(card), "HW: flash controller timeout\n");
+               return 0;
+       }
+
+       /* Hardware failed resetting itself. */
+       return -1;
+}
+
+static pci_ers_result_t rsxx_error_detected(struct pci_dev *dev,
+                                           enum pci_channel_state error)
+{
+       int st;
+
+       if (dev->revision < RSXX_EEH_SUPPORT)
+               return PCI_ERS_RESULT_NONE;
+
+       if (error == pci_channel_io_perm_failure) {
+               rsxx_eeh_failure(dev);
+               return PCI_ERS_RESULT_DISCONNECT;
+       }
+
+       st = rsxx_eeh_frozen(dev);
+       if (st) {
+               dev_err(&dev->dev, "Slot reset setup failed\n");
+               rsxx_eeh_failure(dev);
+               return PCI_ERS_RESULT_DISCONNECT;
+       }
+
+       return PCI_ERS_RESULT_NEED_RESET;
+}
+
+static pci_ers_result_t rsxx_slot_reset(struct pci_dev *dev)
+{
+       struct rsxx_cardinfo *card = pci_get_drvdata(dev);
+       unsigned long flags;
+       int i;
+       int st;
+
+       dev_warn(&dev->dev,
+               "IBM FlashSystem PCI: recovering from slot reset.\n");
+
+       st = pci_enable_device(dev);
+       if (st)
+               goto failed_hw_setup;
+
+       pci_set_master(dev);
+
+       st = rsxx_eeh_fifo_flush_poll(card);
+       if (st)
+               goto failed_hw_setup;
+
+       rsxx_dma_queue_reset(card);
+
+       for (i = 0; i < card->n_targets; i++) {
+               st = rsxx_hw_buffers_init(dev, &card->ctrl[i]);
+               if (st)
+                       goto failed_hw_buffers_init;
+       }
+
+       if (card->config_valid)
+               rsxx_dma_configure(card);
+
+       /* Clears the ISR register from spurious interrupts */
+       st = ioread32(card->regmap + ISR);
+
+       card->eeh_state = 0;
+
+       st = rsxx_eeh_remap_dmas(card);
+       if (st)
+               goto failed_remap_dmas;
+
+       spin_lock_irqsave(&card->irq_lock, flags);
+       if (card->n_targets & RSXX_MAX_TARGETS)
+               rsxx_enable_ier_and_isr(card, CR_INTR_ALL_G);
+       else
+               rsxx_enable_ier_and_isr(card, CR_INTR_ALL_C);
+       spin_unlock_irqrestore(&card->irq_lock, flags);
+
+       rsxx_kick_creg_queue(card);
+
+       for (i = 0; i < card->n_targets; i++) {
+               spin_lock(&card->ctrl[i].queue_lock);
+               if (list_empty(&card->ctrl[i].queue)) {
+                       spin_unlock(&card->ctrl[i].queue_lock);
+                       continue;
+               }
+               spin_unlock(&card->ctrl[i].queue_lock);
+
+               queue_work(card->ctrl[i].issue_wq,
+                               &card->ctrl[i].issue_dma_work);
+       }
+
+       dev_info(&dev->dev, "IBM FlashSystem PCI: recovery complete.\n");
+
+       return PCI_ERS_RESULT_RECOVERED;
+
+failed_hw_buffers_init:
+failed_remap_dmas:
+       for (i = 0; i < card->n_targets; i++) {
+               if (card->ctrl[i].status.buf)
+                       pci_free_consistent(card->dev,
+                                       STATUS_BUFFER_SIZE8,
+                                       card->ctrl[i].status.buf,
+                                       card->ctrl[i].status.dma_addr);
+               if (card->ctrl[i].cmd.buf)
+                       pci_free_consistent(card->dev,
+                                       COMMAND_BUFFER_SIZE8,
+                                       card->ctrl[i].cmd.buf,
+                                       card->ctrl[i].cmd.dma_addr);
+       }
+failed_hw_setup:
+       rsxx_eeh_failure(dev);
+       return PCI_ERS_RESULT_DISCONNECT;
+
+}
+
 /*----------------- Driver Initialization & Setup -------------------*/
 /* Returns:   0 if the driver is compatible with the device
             -1 if the driver is NOT compatible with the device */
@@ -383,6 +588,7 @@ static int rsxx_pci_probe(struct pci_dev *dev,
 
        spin_lock_init(&card->irq_lock);
        card->halt = 0;
+       card->eeh_state = 0;
 
        spin_lock_irq(&card->irq_lock);
        rsxx_disable_ier_and_isr(card, CR_INTR_ALL);
@@ -538,9 +744,6 @@ static void rsxx_pci_remove(struct pci_dev *dev)
        rsxx_disable_ier_and_isr(card, CR_INTR_EVENT);
        spin_unlock_irqrestore(&card->irq_lock, flags);
 
-       /* Prevent work_structs from re-queuing themselves. */
-       card->halt = 1;
-
        cancel_work_sync(&card->event_work);
 
        rsxx_destroy_dev(card);
@@ -549,6 +752,10 @@ static void rsxx_pci_remove(struct pci_dev *dev)
        spin_lock_irqsave(&card->irq_lock, flags);
        rsxx_disable_ier_and_isr(card, CR_INTR_ALL);
        spin_unlock_irqrestore(&card->irq_lock, flags);
+
+       /* Prevent work_structs from re-queuing themselves. */
+       card->halt = 1;
+
        free_irq(dev->irq, card);
 
        if (!force_legacy)
@@ -592,11 +799,14 @@ static void rsxx_pci_shutdown(struct pci_dev *dev)
        card_shutdown(card);
 }
 
+static const struct pci_error_handlers rsxx_err_handler = {
+       .error_detected = rsxx_error_detected,
+       .slot_reset     = rsxx_slot_reset,
+};
+
 static DEFINE_PCI_DEVICE_TABLE(rsxx_pci_ids) = {
-       {PCI_DEVICE(PCI_VENDOR_ID_TMS_IBM, PCI_DEVICE_ID_RS70_FLASH)},
-       {PCI_DEVICE(PCI_VENDOR_ID_TMS_IBM, PCI_DEVICE_ID_RS70D_FLASH)},
-       {PCI_DEVICE(PCI_VENDOR_ID_TMS_IBM, PCI_DEVICE_ID_RS80_FLASH)},
-       {PCI_DEVICE(PCI_VENDOR_ID_TMS_IBM, PCI_DEVICE_ID_RS81_FLASH)},
+       {PCI_DEVICE(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_FS70_FLASH)},
+       {PCI_DEVICE(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_FS80_FLASH)},
        {0,},
 };
 
@@ -609,6 +819,7 @@ static struct pci_driver rsxx_pci_driver = {
        .remove         = rsxx_pci_remove,
        .suspend        = rsxx_pci_suspend,
        .shutdown       = rsxx_pci_shutdown,
+       .err_handler    = &rsxx_err_handler,
 };
 
 static int __init rsxx_core_init(void)
index 80bbe639fccd72d002d269f6486e58ace210aab9..4b5c020a0a65ad8831d75bf3407dd81b2d82b306 100644 (file)
@@ -58,7 +58,7 @@ static struct kmem_cache *creg_cmd_pool;
 #error Unknown endianess!!! Aborting...
 #endif
 
-static void copy_to_creg_data(struct rsxx_cardinfo *card,
+static int copy_to_creg_data(struct rsxx_cardinfo *card,
                              int cnt8,
                              void *buf,
                              unsigned int stream)
@@ -66,6 +66,9 @@ static void copy_to_creg_data(struct rsxx_cardinfo *card,
        int i = 0;
        u32 *data = buf;
 
+       if (unlikely(card->eeh_state))
+               return -EIO;
+
        for (i = 0; cnt8 > 0; i++, cnt8 -= 4) {
                /*
                 * Firmware implementation makes it necessary to byte swap on
@@ -76,10 +79,12 @@ static void copy_to_creg_data(struct rsxx_cardinfo *card,
                else
                        iowrite32(data[i], card->regmap + CREG_DATA(i));
        }
+
+       return 0;
 }
 
 
-static void copy_from_creg_data(struct rsxx_cardinfo *card,
+static int copy_from_creg_data(struct rsxx_cardinfo *card,
                                int cnt8,
                                void *buf,
                                unsigned int stream)
@@ -87,6 +92,9 @@ static void copy_from_creg_data(struct rsxx_cardinfo *card,
        int i = 0;
        u32 *data = buf;
 
+       if (unlikely(card->eeh_state))
+               return -EIO;
+
        for (i = 0; cnt8 > 0; i++, cnt8 -= 4) {
                /*
                 * Firmware implementation makes it necessary to byte swap on
@@ -97,41 +105,31 @@ static void copy_from_creg_data(struct rsxx_cardinfo *card,
                else
                        data[i] = ioread32(card->regmap + CREG_DATA(i));
        }
-}
-
-static struct creg_cmd *pop_active_cmd(struct rsxx_cardinfo *card)
-{
-       struct creg_cmd *cmd;
 
-       /*
-        * Spin lock is needed because this can be called in atomic/interrupt
-        * context.
-        */
-       spin_lock_bh(&card->creg_ctrl.lock);
-       cmd = card->creg_ctrl.active_cmd;
-       card->creg_ctrl.active_cmd = NULL;
-       spin_unlock_bh(&card->creg_ctrl.lock);
-
-       return cmd;
+       return 0;
 }
 
 static void creg_issue_cmd(struct rsxx_cardinfo *card, struct creg_cmd *cmd)
 {
+       int st;
+
+       if (unlikely(card->eeh_state))
+               return;
+
        iowrite32(cmd->addr, card->regmap + CREG_ADD);
        iowrite32(cmd->cnt8, card->regmap + CREG_CNT);
 
        if (cmd->op == CREG_OP_WRITE) {
-               if (cmd->buf)
-                       copy_to_creg_data(card, cmd->cnt8,
-                                         cmd->buf, cmd->stream);
+               if (cmd->buf) {
+                       st = copy_to_creg_data(card, cmd->cnt8,
+                                              cmd->buf, cmd->stream);
+                       if (st)
+                               return;
+               }
        }
 
-       /*
-        * Data copy must complete before initiating the command. This is
-        * needed for weakly ordered processors (i.e. PowerPC), so that all
-        * neccessary registers are written before we kick the hardware.
-        */
-       wmb();
+       if (unlikely(card->eeh_state))
+               return;
 
        /* Setting the valid bit will kick off the command. */
        iowrite32(cmd->op, card->regmap + CREG_CMD);
@@ -196,11 +194,11 @@ static int creg_queue_cmd(struct rsxx_cardinfo *card,
        cmd->cb_private = cb_private;
        cmd->status     = 0;
 
-       spin_lock(&card->creg_ctrl.lock);
+       spin_lock_bh(&card->creg_ctrl.lock);
        list_add_tail(&cmd->list, &card->creg_ctrl.queue);
        card->creg_ctrl.q_depth++;
        creg_kick_queue(card);
-       spin_unlock(&card->creg_ctrl.lock);
+       spin_unlock_bh(&card->creg_ctrl.lock);
 
        return 0;
 }
@@ -210,7 +208,11 @@ static void creg_cmd_timed_out(unsigned long data)
        struct rsxx_cardinfo *card = (struct rsxx_cardinfo *) data;
        struct creg_cmd *cmd;
 
-       cmd = pop_active_cmd(card);
+       spin_lock(&card->creg_ctrl.lock);
+       cmd = card->creg_ctrl.active_cmd;
+       card->creg_ctrl.active_cmd = NULL;
+       spin_unlock(&card->creg_ctrl.lock);
+
        if (cmd == NULL) {
                card->creg_ctrl.creg_stats.creg_timeout++;
                dev_warn(CARD_TO_DEV(card),
@@ -247,7 +249,11 @@ static void creg_cmd_done(struct work_struct *work)
        if (del_timer_sync(&card->creg_ctrl.cmd_timer) == 0)
                card->creg_ctrl.creg_stats.failed_cancel_timer++;
 
-       cmd = pop_active_cmd(card);
+       spin_lock_bh(&card->creg_ctrl.lock);
+       cmd = card->creg_ctrl.active_cmd;
+       card->creg_ctrl.active_cmd = NULL;
+       spin_unlock_bh(&card->creg_ctrl.lock);
+
        if (cmd == NULL) {
                dev_err(CARD_TO_DEV(card),
                        "Spurious creg interrupt!\n");
@@ -287,7 +293,7 @@ static void creg_cmd_done(struct work_struct *work)
                        goto creg_done;
                }
 
-               copy_from_creg_data(card, cnt8, cmd->buf, cmd->stream);
+               st = copy_from_creg_data(card, cnt8, cmd->buf, cmd->stream);
        }
 
 creg_done:
@@ -296,10 +302,10 @@ creg_done:
 
        kmem_cache_free(creg_cmd_pool, cmd);
 
-       spin_lock(&card->creg_ctrl.lock);
+       spin_lock_bh(&card->creg_ctrl.lock);
        card->creg_ctrl.active = 0;
        creg_kick_queue(card);
-       spin_unlock(&card->creg_ctrl.lock);
+       spin_unlock_bh(&card->creg_ctrl.lock);
 }
 
 static void creg_reset(struct rsxx_cardinfo *card)
@@ -324,7 +330,7 @@ static void creg_reset(struct rsxx_cardinfo *card)
                "Resetting creg interface for recovery\n");
 
        /* Cancel outstanding commands */
-       spin_lock(&card->creg_ctrl.lock);
+       spin_lock_bh(&card->creg_ctrl.lock);
        list_for_each_entry_safe(cmd, tmp, &card->creg_ctrl.queue, list) {
                list_del(&cmd->list);
                card->creg_ctrl.q_depth--;
@@ -345,7 +351,7 @@ static void creg_reset(struct rsxx_cardinfo *card)
 
                card->creg_ctrl.active = 0;
        }
-       spin_unlock(&card->creg_ctrl.lock);
+       spin_unlock_bh(&card->creg_ctrl.lock);
 
        card->creg_ctrl.reset = 0;
        spin_lock_irqsave(&card->irq_lock, flags);
@@ -399,12 +405,12 @@ static int __issue_creg_rw(struct rsxx_cardinfo *card,
                return st;
 
        /*
-        * This timeout is neccessary for unresponsive hardware. The additional
+        * This timeout is necessary for unresponsive hardware. The additional
         * 20 seconds to used to guarantee that each cregs requests has time to
         * complete.
         */
-       timeout = msecs_to_jiffies((CREG_TIMEOUT_MSEC *
-                               card->creg_ctrl.q_depth) + 20000);
+       timeout = msecs_to_jiffies(CREG_TIMEOUT_MSEC *
+                                  card->creg_ctrl.q_depth + 20000);
 
        /*
         * The creg interface is guaranteed to complete. It has a timeout
@@ -690,6 +696,32 @@ int rsxx_reg_access(struct rsxx_cardinfo *card,
        return 0;
 }
 
+void rsxx_eeh_save_issued_creg(struct rsxx_cardinfo *card)
+{
+       struct creg_cmd *cmd = NULL;
+
+       cmd = card->creg_ctrl.active_cmd;
+       card->creg_ctrl.active_cmd = NULL;
+
+       if (cmd) {
+               del_timer_sync(&card->creg_ctrl.cmd_timer);
+
+               spin_lock_bh(&card->creg_ctrl.lock);
+               list_add(&cmd->list, &card->creg_ctrl.queue);
+               card->creg_ctrl.q_depth++;
+               card->creg_ctrl.active = 0;
+               spin_unlock_bh(&card->creg_ctrl.lock);
+       }
+}
+
+void rsxx_kick_creg_queue(struct rsxx_cardinfo *card)
+{
+       spin_lock_bh(&card->creg_ctrl.lock);
+       if (!list_empty(&card->creg_ctrl.queue))
+               creg_kick_queue(card);
+       spin_unlock_bh(&card->creg_ctrl.lock);
+}
+
 /*------------ Initialization & Setup --------------*/
 int rsxx_creg_setup(struct rsxx_cardinfo *card)
 {
@@ -712,7 +744,7 @@ void rsxx_creg_destroy(struct rsxx_cardinfo *card)
        int cnt = 0;
 
        /* Cancel outstanding commands */
-       spin_lock(&card->creg_ctrl.lock);
+       spin_lock_bh(&card->creg_ctrl.lock);
        list_for_each_entry_safe(cmd, tmp, &card->creg_ctrl.queue, list) {
                list_del(&cmd->list);
                if (cmd->cb)
@@ -737,7 +769,7 @@ void rsxx_creg_destroy(struct rsxx_cardinfo *card)
                        "Canceled active creg command\n");
                kmem_cache_free(creg_cmd_pool, cmd);
        }
-       spin_unlock(&card->creg_ctrl.lock);
+       spin_unlock_bh(&card->creg_ctrl.lock);
 
        cancel_work_sync(&card->creg_ctrl.done_work);
 }
index 63176e67662f5f48d2b358c39d93d86735c21c72..0607513cfb41fa4b2ff88bac32be0665c645a2bb 100644 (file)
@@ -28,7 +28,7 @@
 struct rsxx_dma {
        struct list_head         list;
        u8                       cmd;
-       unsigned int             laddr;     /* Logical address on the ramsan */
+       unsigned int             laddr;     /* Logical address */
        struct {
                u32              off;
                u32              cnt;
@@ -81,9 +81,6 @@ enum rsxx_hw_status {
        HW_STATUS_FAULT         = 0x08,
 };
 
-#define STATUS_BUFFER_SIZE8     4096
-#define COMMAND_BUFFER_SIZE8    4096
-
 static struct kmem_cache *rsxx_dma_pool;
 
 struct dma_tracker {
@@ -122,7 +119,7 @@ static unsigned int rsxx_get_dma_tgt(struct rsxx_cardinfo *card, u64 addr8)
        return tgt;
 }
 
-static void rsxx_dma_queue_reset(struct rsxx_cardinfo *card)
+void rsxx_dma_queue_reset(struct rsxx_cardinfo *card)
 {
        /* Reset all DMA Command/Status Queues */
        iowrite32(DMA_QUEUE_RESET, card->regmap + RESET);
@@ -210,7 +207,8 @@ static void dma_intr_coal_auto_tune(struct rsxx_cardinfo *card)
        u32 q_depth = 0;
        u32 intr_coal;
 
-       if (card->config.data.intr_coal.mode != RSXX_INTR_COAL_AUTO_TUNE)
+       if (card->config.data.intr_coal.mode != RSXX_INTR_COAL_AUTO_TUNE ||
+           unlikely(card->eeh_state))
                return;
 
        for (i = 0; i < card->n_targets; i++)
@@ -223,31 +221,26 @@ static void dma_intr_coal_auto_tune(struct rsxx_cardinfo *card)
 }
 
 /*----------------- RSXX DMA Handling -------------------*/
-static void rsxx_complete_dma(struct rsxx_cardinfo *card,
+static void rsxx_complete_dma(struct rsxx_dma_ctrl *ctrl,
                                  struct rsxx_dma *dma,
                                  unsigned int status)
 {
        if (status & DMA_SW_ERR)
-               printk_ratelimited(KERN_ERR
-                                  "SW Error in DMA(cmd x%02x, laddr x%08x)\n",
-                                  dma->cmd, dma->laddr);
+               ctrl->stats.dma_sw_err++;
        if (status & DMA_HW_FAULT)
-               printk_ratelimited(KERN_ERR
-                                  "HW Fault in DMA(cmd x%02x, laddr x%08x)\n",
-                                  dma->cmd, dma->laddr);
+               ctrl->stats.dma_hw_fault++;
        if (status & DMA_CANCELLED)
-               printk_ratelimited(KERN_ERR
-                                  "DMA Cancelled(cmd x%02x, laddr x%08x)\n",
-                                  dma->cmd, dma->laddr);
+               ctrl->stats.dma_cancelled++;
 
        if (dma->dma_addr)
-               pci_unmap_page(card->dev, dma->dma_addr, get_dma_size(dma),
+               pci_unmap_page(ctrl->card->dev, dma->dma_addr,
+                              get_dma_size(dma),
                               dma->cmd == HW_CMD_BLK_WRITE ?
                                           PCI_DMA_TODEVICE :
                                           PCI_DMA_FROMDEVICE);
 
        if (dma->cb)
-               dma->cb(card, dma->cb_data, status ? 1 : 0);
+               dma->cb(ctrl->card, dma->cb_data, status ? 1 : 0);
 
        kmem_cache_free(rsxx_dma_pool, dma);
 }
@@ -330,14 +323,15 @@ static void rsxx_handle_dma_error(struct rsxx_dma_ctrl *ctrl,
        if (requeue_cmd)
                rsxx_requeue_dma(ctrl, dma);
        else
-               rsxx_complete_dma(ctrl->card, dma, status);
+               rsxx_complete_dma(ctrl, dma, status);
 }
 
 static void dma_engine_stalled(unsigned long data)
 {
        struct rsxx_dma_ctrl *ctrl = (struct rsxx_dma_ctrl *)data;
 
-       if (atomic_read(&ctrl->stats.hw_q_depth) == 0)
+       if (atomic_read(&ctrl->stats.hw_q_depth) == 0 ||
+           unlikely(ctrl->card->eeh_state))
                return;
 
        if (ctrl->cmd.idx != ioread32(ctrl->regmap + SW_CMD_IDX)) {
@@ -369,7 +363,8 @@ static void rsxx_issue_dmas(struct work_struct *work)
        ctrl = container_of(work, struct rsxx_dma_ctrl, issue_dma_work);
        hw_cmd_buf = ctrl->cmd.buf;
 
-       if (unlikely(ctrl->card->halt))
+       if (unlikely(ctrl->card->halt) ||
+           unlikely(ctrl->card->eeh_state))
                return;
 
        while (1) {
@@ -397,7 +392,7 @@ static void rsxx_issue_dmas(struct work_struct *work)
                 */
                if (unlikely(ctrl->card->dma_fault)) {
                        push_tracker(ctrl->trackers, tag);
-                       rsxx_complete_dma(ctrl->card, dma, DMA_CANCELLED);
+                       rsxx_complete_dma(ctrl, dma, DMA_CANCELLED);
                        continue;
                }
 
@@ -432,19 +427,15 @@ static void rsxx_issue_dmas(struct work_struct *work)
 
        /* Let HW know we've queued commands. */
        if (cmds_pending) {
-               /*
-                * We must guarantee that the CPU writes to 'ctrl->cmd.buf'
-                * (which is in PCI-consistent system-memory) from the loop
-                * above make it into the coherency domain before the
-                * following PIO "trigger" updating the cmd.idx.  A WMB is
-                * sufficient. We need not explicitly CPU cache-flush since
-                * the memory is a PCI-consistent (ie; coherent) mapping.
-                */
-               wmb();
-
                atomic_add(cmds_pending, &ctrl->stats.hw_q_depth);
                mod_timer(&ctrl->activity_timer,
                          jiffies + DMA_ACTIVITY_TIMEOUT);
+
+               if (unlikely(ctrl->card->eeh_state)) {
+                       del_timer_sync(&ctrl->activity_timer);
+                       return;
+               }
+
                iowrite32(ctrl->cmd.idx, ctrl->regmap + SW_CMD_IDX);
        }
 }
@@ -463,7 +454,8 @@ static void rsxx_dma_done(struct work_struct *work)
        hw_st_buf = ctrl->status.buf;
 
        if (unlikely(ctrl->card->halt) ||
-           unlikely(ctrl->card->dma_fault))
+           unlikely(ctrl->card->dma_fault) ||
+           unlikely(ctrl->card->eeh_state))
                return;
 
        count = le16_to_cpu(hw_st_buf[ctrl->status.idx].count);
@@ -508,7 +500,7 @@ static void rsxx_dma_done(struct work_struct *work)
                if (status)
                        rsxx_handle_dma_error(ctrl, dma, status);
                else
-                       rsxx_complete_dma(ctrl->card, dma, 0);
+                       rsxx_complete_dma(ctrl, dma, 0);
 
                push_tracker(ctrl->trackers, tag);
 
@@ -727,20 +719,54 @@ bvec_err:
 
 
 /*----------------- DMA Engine Initialization & Setup -------------------*/
+int rsxx_hw_buffers_init(struct pci_dev *dev, struct rsxx_dma_ctrl *ctrl)
+{
+       ctrl->status.buf = pci_alloc_consistent(dev, STATUS_BUFFER_SIZE8,
+                               &ctrl->status.dma_addr);
+       ctrl->cmd.buf = pci_alloc_consistent(dev, COMMAND_BUFFER_SIZE8,
+                               &ctrl->cmd.dma_addr);
+       if (ctrl->status.buf == NULL || ctrl->cmd.buf == NULL)
+               return -ENOMEM;
+
+       memset(ctrl->status.buf, 0xac, STATUS_BUFFER_SIZE8);
+       iowrite32(lower_32_bits(ctrl->status.dma_addr),
+               ctrl->regmap + SB_ADD_LO);
+       iowrite32(upper_32_bits(ctrl->status.dma_addr),
+               ctrl->regmap + SB_ADD_HI);
+
+       memset(ctrl->cmd.buf, 0x83, COMMAND_BUFFER_SIZE8);
+       iowrite32(lower_32_bits(ctrl->cmd.dma_addr), ctrl->regmap + CB_ADD_LO);
+       iowrite32(upper_32_bits(ctrl->cmd.dma_addr), ctrl->regmap + CB_ADD_HI);
+
+       ctrl->status.idx = ioread32(ctrl->regmap + HW_STATUS_CNT);
+       if (ctrl->status.idx > RSXX_MAX_OUTSTANDING_CMDS) {
+               dev_crit(&dev->dev, "Failed reading status cnt x%x\n",
+                       ctrl->status.idx);
+               return -EINVAL;
+       }
+       iowrite32(ctrl->status.idx, ctrl->regmap + HW_STATUS_CNT);
+       iowrite32(ctrl->status.idx, ctrl->regmap + SW_STATUS_CNT);
+
+       ctrl->cmd.idx = ioread32(ctrl->regmap + HW_CMD_IDX);
+       if (ctrl->cmd.idx > RSXX_MAX_OUTSTANDING_CMDS) {
+               dev_crit(&dev->dev, "Failed reading cmd cnt x%x\n",
+                       ctrl->status.idx);
+               return -EINVAL;
+       }
+       iowrite32(ctrl->cmd.idx, ctrl->regmap + HW_CMD_IDX);
+       iowrite32(ctrl->cmd.idx, ctrl->regmap + SW_CMD_IDX);
+
+       return 0;
+}
+
 static int rsxx_dma_ctrl_init(struct pci_dev *dev,
                                  struct rsxx_dma_ctrl *ctrl)
 {
        int i;
+       int st;
 
        memset(&ctrl->stats, 0, sizeof(ctrl->stats));
 
-       ctrl->status.buf = pci_alloc_consistent(dev, STATUS_BUFFER_SIZE8,
-                                               &ctrl->status.dma_addr);
-       ctrl->cmd.buf = pci_alloc_consistent(dev, COMMAND_BUFFER_SIZE8,
-                                            &ctrl->cmd.dma_addr);
-       if (ctrl->status.buf == NULL || ctrl->cmd.buf == NULL)
-               return -ENOMEM;
-
        ctrl->trackers = vmalloc(DMA_TRACKER_LIST_SIZE8);
        if (!ctrl->trackers)
                return -ENOMEM;
@@ -770,35 +796,9 @@ static int rsxx_dma_ctrl_init(struct pci_dev *dev,
        INIT_WORK(&ctrl->issue_dma_work, rsxx_issue_dmas);
        INIT_WORK(&ctrl->dma_done_work, rsxx_dma_done);
 
-       memset(ctrl->status.buf, 0xac, STATUS_BUFFER_SIZE8);
-       iowrite32(lower_32_bits(ctrl->status.dma_addr),
-                 ctrl->regmap + SB_ADD_LO);
-       iowrite32(upper_32_bits(ctrl->status.dma_addr),
-                 ctrl->regmap + SB_ADD_HI);
-
-       memset(ctrl->cmd.buf, 0x83, COMMAND_BUFFER_SIZE8);
-       iowrite32(lower_32_bits(ctrl->cmd.dma_addr), ctrl->regmap + CB_ADD_LO);
-       iowrite32(upper_32_bits(ctrl->cmd.dma_addr), ctrl->regmap + CB_ADD_HI);
-
-       ctrl->status.idx = ioread32(ctrl->regmap + HW_STATUS_CNT);
-       if (ctrl->status.idx > RSXX_MAX_OUTSTANDING_CMDS) {
-               dev_crit(&dev->dev, "Failed reading status cnt x%x\n",
-                        ctrl->status.idx);
-               return -EINVAL;
-       }
-       iowrite32(ctrl->status.idx, ctrl->regmap + HW_STATUS_CNT);
-       iowrite32(ctrl->status.idx, ctrl->regmap + SW_STATUS_CNT);
-
-       ctrl->cmd.idx = ioread32(ctrl->regmap + HW_CMD_IDX);
-       if (ctrl->cmd.idx > RSXX_MAX_OUTSTANDING_CMDS) {
-               dev_crit(&dev->dev, "Failed reading cmd cnt x%x\n",
-                        ctrl->status.idx);
-               return -EINVAL;
-       }
-       iowrite32(ctrl->cmd.idx, ctrl->regmap + HW_CMD_IDX);
-       iowrite32(ctrl->cmd.idx, ctrl->regmap + SW_CMD_IDX);
-
-       wmb();
+       st = rsxx_hw_buffers_init(dev, ctrl);
+       if (st)
+               return st;
 
        return 0;
 }
@@ -834,7 +834,7 @@ static int rsxx_dma_stripe_setup(struct rsxx_cardinfo *card,
        return 0;
 }
 
-static int rsxx_dma_configure(struct rsxx_cardinfo *card)
+int rsxx_dma_configure(struct rsxx_cardinfo *card)
 {
        u32 intr_coal;
 
@@ -980,6 +980,103 @@ void rsxx_dma_destroy(struct rsxx_cardinfo *card)
        }
 }
 
+int rsxx_eeh_save_issued_dmas(struct rsxx_cardinfo *card)
+{
+       int i;
+       int j;
+       int cnt;
+       struct rsxx_dma *dma;
+       struct list_head *issued_dmas;
+
+       issued_dmas = kzalloc(sizeof(*issued_dmas) * card->n_targets,
+                             GFP_KERNEL);
+       if (!issued_dmas)
+               return -ENOMEM;
+
+       for (i = 0; i < card->n_targets; i++) {
+               INIT_LIST_HEAD(&issued_dmas[i]);
+               cnt = 0;
+               for (j = 0; j < RSXX_MAX_OUTSTANDING_CMDS; j++) {
+                       dma = get_tracker_dma(card->ctrl[i].trackers, j);
+                       if (dma == NULL)
+                               continue;
+
+                       if (dma->cmd == HW_CMD_BLK_WRITE)
+                               card->ctrl[i].stats.writes_issued--;
+                       else if (dma->cmd == HW_CMD_BLK_DISCARD)
+                               card->ctrl[i].stats.discards_issued--;
+                       else
+                               card->ctrl[i].stats.reads_issued--;
+
+                       list_add_tail(&dma->list, &issued_dmas[i]);
+                       push_tracker(card->ctrl[i].trackers, j);
+                       cnt++;
+               }
+
+               spin_lock(&card->ctrl[i].queue_lock);
+               list_splice(&issued_dmas[i], &card->ctrl[i].queue);
+
+               atomic_sub(cnt, &card->ctrl[i].stats.hw_q_depth);
+               card->ctrl[i].stats.sw_q_depth += cnt;
+               card->ctrl[i].e_cnt = 0;
+
+               list_for_each_entry(dma, &card->ctrl[i].queue, list) {
+                       if (dma->dma_addr)
+                               pci_unmap_page(card->dev, dma->dma_addr,
+                                              get_dma_size(dma),
+                                              dma->cmd == HW_CMD_BLK_WRITE ?
+                                              PCI_DMA_TODEVICE :
+                                              PCI_DMA_FROMDEVICE);
+               }
+               spin_unlock(&card->ctrl[i].queue_lock);
+       }
+
+       kfree(issued_dmas);
+
+       return 0;
+}
+
+void rsxx_eeh_cancel_dmas(struct rsxx_cardinfo *card)
+{
+       struct rsxx_dma *dma;
+       struct rsxx_dma *tmp;
+       int i;
+
+       for (i = 0; i < card->n_targets; i++) {
+               spin_lock(&card->ctrl[i].queue_lock);
+               list_for_each_entry_safe(dma, tmp, &card->ctrl[i].queue, list) {
+                       list_del(&dma->list);
+
+                       rsxx_complete_dma(&card->ctrl[i], dma, DMA_CANCELLED);
+               }
+               spin_unlock(&card->ctrl[i].queue_lock);
+       }
+}
+
+int rsxx_eeh_remap_dmas(struct rsxx_cardinfo *card)
+{
+       struct rsxx_dma *dma;
+       int i;
+
+       for (i = 0; i < card->n_targets; i++) {
+               spin_lock(&card->ctrl[i].queue_lock);
+               list_for_each_entry(dma, &card->ctrl[i].queue, list) {
+                       dma->dma_addr = pci_map_page(card->dev, dma->page,
+                                       dma->pg_off, get_dma_size(dma),
+                                       dma->cmd == HW_CMD_BLK_WRITE ?
+                                       PCI_DMA_TODEVICE :
+                                       PCI_DMA_FROMDEVICE);
+                       if (!dma->dma_addr) {
+                               spin_unlock(&card->ctrl[i].queue_lock);
+                               kmem_cache_free(rsxx_dma_pool, dma);
+                               return -ENOMEM;
+                       }
+               }
+               spin_unlock(&card->ctrl[i].queue_lock);
+       }
+
+       return 0;
+}
 
 int rsxx_dma_init(void)
 {
index 2e50b65902b71e564f9a25cba8a22cc09d893805..24ba3642bd89aeaabc113407eb2de6d92f13602a 100644 (file)
 
 /*----------------- IOCTL Definitions -------------------*/
 
+#define RSXX_MAX_DATA 8
+
 struct rsxx_reg_access {
        __u32 addr;
        __u32 cnt;
        __u32 stat;
        __u32 stream;
-       __u32 data[8];
+       __u32 data[RSXX_MAX_DATA];
 };
 
-#define RSXX_MAX_REG_CNT       (8 * (sizeof(__u32)))
+#define RSXX_MAX_REG_CNT       (RSXX_MAX_DATA * (sizeof(__u32)))
 
 #define RSXX_IOC_MAGIC 'r'
 
index c025fe5fdb703af4d1a94ed491814cded627a17d..f384c943846de35a2dab6d5f173df7b15c4bd5f2 100644 (file)
@@ -58,7 +58,7 @@ struct rsxx_card_cfg {
 };
 
 /* Vendor ID Values */
-#define RSXX_VENDOR_ID_TMS_IBM         0
+#define RSXX_VENDOR_ID_IBM             0
 #define RSXX_VENDOR_ID_DSI             1
 #define RSXX_VENDOR_COUNT              2
 
index a1ac907d8f4c3ee60aabb11bdfb439ea3418183c..382e8bf5c03b73dae35fd1ae8865110cc1a85168 100644 (file)
 
 struct proc_cmd;
 
-#define PCI_VENDOR_ID_TMS_IBM          0x15B6
-#define PCI_DEVICE_ID_RS70_FLASH       0x0019
-#define PCI_DEVICE_ID_RS70D_FLASH      0x001A
-#define PCI_DEVICE_ID_RS80_FLASH       0x001C
-#define PCI_DEVICE_ID_RS81_FLASH       0x001E
+#define PCI_DEVICE_ID_FS70_FLASH       0x04A9
+#define PCI_DEVICE_ID_FS80_FLASH       0x04AA
 
 #define RS70_PCI_REV_SUPPORTED 4
 
 #define DRIVER_NAME "rsxx"
-#define DRIVER_VERSION "3.7"
+#define DRIVER_VERSION "4.0"
 
 /* Block size is 4096 */
 #define RSXX_HW_BLK_SHIFT              12
@@ -67,6 +64,9 @@ struct proc_cmd;
 #define RSXX_MAX_OUTSTANDING_CMDS      255
 #define RSXX_CS_IDX_MASK               0xff
 
+#define STATUS_BUFFER_SIZE8     4096
+#define COMMAND_BUFFER_SIZE8    4096
+
 #define RSXX_MAX_TARGETS       8
 
 struct dma_tracker_list;
@@ -91,6 +91,9 @@ struct rsxx_dma_stats {
        u32 discards_failed;
        u32 done_rescheduled;
        u32 issue_rescheduled;
+       u32 dma_sw_err;
+       u32 dma_hw_fault;
+       u32 dma_cancelled;
        u32 sw_q_depth;         /* Number of DMAs on the SW queue. */
        atomic_t hw_q_depth;    /* Number of DMAs queued to HW. */
 };
@@ -116,6 +119,7 @@ struct rsxx_dma_ctrl {
 struct rsxx_cardinfo {
        struct pci_dev          *dev;
        unsigned int            halt;
+       unsigned int            eeh_state;
 
        void                    __iomem *regmap;
        spinlock_t              irq_lock;
@@ -224,6 +228,7 @@ enum rsxx_pci_regmap {
        PERF_RD512_HI   = 0xac,
        PERF_WR512_LO   = 0xb0,
        PERF_WR512_HI   = 0xb4,
+       PCI_RECONFIG    = 0xb8,
 };
 
 enum rsxx_intr {
@@ -237,6 +242,8 @@ enum rsxx_intr {
        CR_INTR_DMA5    = 0x00000080,
        CR_INTR_DMA6    = 0x00000100,
        CR_INTR_DMA7    = 0x00000200,
+       CR_INTR_ALL_C   = 0x0000003f,
+       CR_INTR_ALL_G   = 0x000003ff,
        CR_INTR_DMA_ALL = 0x000003f5,
        CR_INTR_ALL     = 0xffffffff,
 };
@@ -253,8 +260,14 @@ enum rsxx_pci_reset {
        DMA_QUEUE_RESET         = 0x00000001,
 };
 
+enum rsxx_hw_fifo_flush {
+       RSXX_FLUSH_BUSY         = 0x00000002,
+       RSXX_FLUSH_TIMEOUT      = 0x00000004,
+};
+
 enum rsxx_pci_revision {
        RSXX_DISCARD_SUPPORT = 2,
+       RSXX_EEH_SUPPORT     = 3,
 };
 
 enum rsxx_creg_cmd {
@@ -360,11 +373,17 @@ int rsxx_dma_setup(struct rsxx_cardinfo *card);
 void rsxx_dma_destroy(struct rsxx_cardinfo *card);
 int rsxx_dma_init(void);
 void rsxx_dma_cleanup(void);
+void rsxx_dma_queue_reset(struct rsxx_cardinfo *card);
+int rsxx_dma_configure(struct rsxx_cardinfo *card);
 int rsxx_dma_queue_bio(struct rsxx_cardinfo *card,
                           struct bio *bio,
                           atomic_t *n_dmas,
                           rsxx_dma_cb cb,
                           void *cb_data);
+int rsxx_hw_buffers_init(struct pci_dev *dev, struct rsxx_dma_ctrl *ctrl);
+int rsxx_eeh_save_issued_dmas(struct rsxx_cardinfo *card);
+void rsxx_eeh_cancel_dmas(struct rsxx_cardinfo *card);
+int rsxx_eeh_remap_dmas(struct rsxx_cardinfo *card);
 
 /***** cregs.c *****/
 int rsxx_creg_write(struct rsxx_cardinfo *card, u32 addr,
@@ -389,10 +408,11 @@ int rsxx_creg_setup(struct rsxx_cardinfo *card);
 void rsxx_creg_destroy(struct rsxx_cardinfo *card);
 int rsxx_creg_init(void);
 void rsxx_creg_cleanup(void);
-
 int rsxx_reg_access(struct rsxx_cardinfo *card,
                        struct rsxx_reg_access __user *ucmd,
                        int read);
+void rsxx_eeh_save_issued_creg(struct rsxx_cardinfo *card);
+void rsxx_kick_creg_queue(struct rsxx_cardinfo *card);
 
 
 
index de1f319f7bd7e0118a960b5bd23fd286a6ba343e..dd5b2fed97e9ae2b7665f13ec3c42db6ee6fb462 100644 (file)
@@ -164,7 +164,7 @@ static void make_response(struct xen_blkif *blkif, u64 id,
 
 #define foreach_grant_safe(pos, n, rbtree, node) \
        for ((pos) = container_of(rb_first((rbtree)), typeof(*(pos)), node), \
-            (n) = rb_next(&(pos)->node); \
+            (n) = (&(pos)->node != NULL) ? rb_next(&(pos)->node) : NULL; \
             &(pos)->node != NULL; \
             (pos) = container_of(n, typeof(*(pos)), node), \
             (n) = (&(pos)->node != NULL) ? rb_next(&(pos)->node) : NULL)
@@ -381,8 +381,8 @@ irqreturn_t xen_blkif_be_int(int irq, void *dev_id)
 
 static void print_stats(struct xen_blkif *blkif)
 {
-       pr_info("xen-blkback (%s): oo %3d  |  rd %4d  |  wr %4d  |  f %4d"
-                "  |  ds %4d\n",
+       pr_info("xen-blkback (%s): oo %3llu  |  rd %4llu  |  wr %4llu  |  f %4llu"
+                "  |  ds %4llu\n",
                 current->comm, blkif->st_oo_req,
                 blkif->st_rd_req, blkif->st_wr_req,
                 blkif->st_f_req, blkif->st_ds_req);
@@ -442,7 +442,7 @@ int xen_blkif_schedule(void *arg)
 }
 
 struct seg_buf {
-       unsigned long buf;
+       unsigned int offset;
        unsigned int nsec;
 };
 /*
@@ -621,30 +621,21 @@ static int xen_blkbk_map(struct blkif_request *req,
                                 * If this is a new persistent grant
                                 * save the handler
                                 */
-                               persistent_gnts[i]->handle = map[j].handle;
-                               persistent_gnts[i]->dev_bus_addr =
-                                       map[j++].dev_bus_addr;
+                               persistent_gnts[i]->handle = map[j++].handle;
                        }
                        pending_handle(pending_req, i) =
                                persistent_gnts[i]->handle;
 
                        if (ret)
                                continue;
-
-                       seg[i].buf = persistent_gnts[i]->dev_bus_addr |
-                               (req->u.rw.seg[i].first_sect << 9);
                } else {
-                       pending_handle(pending_req, i) = map[j].handle;
+                       pending_handle(pending_req, i) = map[j++].handle;
                        bitmap_set(pending_req->unmap_seg, i, 1);
 
-                       if (ret) {
-                               j++;
+                       if (ret)
                                continue;
-                       }
-
-                       seg[i].buf = map[j++].dev_bus_addr |
-                               (req->u.rw.seg[i].first_sect << 9);
                }
+               seg[i].offset = (req->u.rw.seg[i].first_sect << 9);
        }
        return ret;
 }
@@ -679,6 +670,16 @@ static int dispatch_discard_io(struct xen_blkif *blkif,
        return err;
 }
 
+static int dispatch_other_io(struct xen_blkif *blkif,
+                            struct blkif_request *req,
+                            struct pending_req *pending_req)
+{
+       free_req(pending_req);
+       make_response(blkif, req->u.other.id, req->operation,
+                     BLKIF_RSP_EOPNOTSUPP);
+       return -EIO;
+}
+
 static void xen_blk_drain_io(struct xen_blkif *blkif)
 {
        atomic_set(&blkif->drain, 1);
@@ -800,17 +801,30 @@ __do_block_io_op(struct xen_blkif *blkif)
 
                /* Apply all sanity checks to /private copy/ of request. */
                barrier();
-               if (unlikely(req.operation == BLKIF_OP_DISCARD)) {
+
+               switch (req.operation) {
+               case BLKIF_OP_READ:
+               case BLKIF_OP_WRITE:
+               case BLKIF_OP_WRITE_BARRIER:
+               case BLKIF_OP_FLUSH_DISKCACHE:
+                       if (dispatch_rw_block_io(blkif, &req, pending_req))
+                               goto done;
+                       break;
+               case BLKIF_OP_DISCARD:
                        free_req(pending_req);
                        if (dispatch_discard_io(blkif, &req))
-                               break;
-               } else if (dispatch_rw_block_io(blkif, &req, pending_req))
+                               goto done;
                        break;
+               default:
+                       if (dispatch_other_io(blkif, &req, pending_req))
+                               goto done;
+                       break;
+               }
 
                /* Yield point for this unbounded loop. */
                cond_resched();
        }
-
+done:
        return more_to_do;
 }
 
@@ -904,7 +918,8 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
                pr_debug(DRV_PFX "access denied: %s of [%llu,%llu] on dev=%04x\n",
                         operation == READ ? "read" : "write",
                         preq.sector_number,
-                        preq.sector_number + preq.nr_sects, preq.dev);
+                        preq.sector_number + preq.nr_sects,
+                        blkif->vbd.pdevice);
                goto fail_response;
        }
 
@@ -947,7 +962,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
                       (bio_add_page(bio,
                                     pages[i],
                                     seg[i].nsec << 9,
-                                    seg[i].buf & ~PAGE_MASK) == 0)) {
+                                    seg[i].offset) == 0)) {
 
                        bio = bio_alloc(GFP_KERNEL, nseg-i);
                        if (unlikely(bio == NULL))
@@ -977,13 +992,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
                bio->bi_end_io  = end_block_io_op;
        }
 
-       /*
-        * We set it one so that the last submit_bio does not have to call
-        * atomic_inc.
-        */
        atomic_set(&pending_req->pendcnt, nbio);
-
-       /* Get a reference count for the disk queue and start sending I/O */
        blk_start_plug(&plug);
 
        for (i = 0; i < nbio; i++)
@@ -1011,6 +1020,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
  fail_put_bio:
        for (i = 0; i < nbio; i++)
                bio_put(biolist[i]);
+       atomic_set(&pending_req->pendcnt, 1);
        __end_block_io_op(pending_req, -EINVAL);
        msleep(1); /* back off a bit */
        return -EIO;
index 6072390c7f57ef724bee4476502eb78d63941c7c..60103e2517ba28ac5c946f32e1bd9e0e6eb7f668 100644 (file)
@@ -77,11 +77,18 @@ struct blkif_x86_32_request_discard {
        uint64_t       nr_sectors;
 } __attribute__((__packed__));
 
+struct blkif_x86_32_request_other {
+       uint8_t        _pad1;
+       blkif_vdev_t   _pad2;
+       uint64_t       id;           /* private guest value, echoed in resp  */
+} __attribute__((__packed__));
+
 struct blkif_x86_32_request {
        uint8_t        operation;    /* BLKIF_OP_???                         */
        union {
                struct blkif_x86_32_request_rw rw;
                struct blkif_x86_32_request_discard discard;
+               struct blkif_x86_32_request_other other;
        } u;
 } __attribute__((__packed__));
 
@@ -113,11 +120,19 @@ struct blkif_x86_64_request_discard {
        uint64_t       nr_sectors;
 } __attribute__((__packed__));
 
+struct blkif_x86_64_request_other {
+       uint8_t        _pad1;
+       blkif_vdev_t   _pad2;
+       uint32_t       _pad3;        /* offsetof(blkif_..,u.discard.id)==8   */
+       uint64_t       id;           /* private guest value, echoed in resp  */
+} __attribute__((__packed__));
+
 struct blkif_x86_64_request {
        uint8_t        operation;    /* BLKIF_OP_???                         */
        union {
                struct blkif_x86_64_request_rw rw;
                struct blkif_x86_64_request_discard discard;
+               struct blkif_x86_64_request_other other;
        } u;
 } __attribute__((__packed__));
 
@@ -172,7 +187,6 @@ struct persistent_gnt {
        struct page *page;
        grant_ref_t gnt;
        grant_handle_t handle;
-       uint64_t dev_bus_addr;
        struct rb_node node;
 };
 
@@ -208,13 +222,13 @@ struct xen_blkif {
 
        /* statistics */
        unsigned long           st_print;
-       int                     st_rd_req;
-       int                     st_wr_req;
-       int                     st_oo_req;
-       int                     st_f_req;
-       int                     st_ds_req;
-       int                     st_rd_sect;
-       int                     st_wr_sect;
+       unsigned long long                      st_rd_req;
+       unsigned long long                      st_wr_req;
+       unsigned long long                      st_oo_req;
+       unsigned long long                      st_f_req;
+       unsigned long long                      st_ds_req;
+       unsigned long long                      st_rd_sect;
+       unsigned long long                      st_wr_sect;
 
        wait_queue_head_t       waiting_to_free;
 };
@@ -278,6 +292,11 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst,
                dst->u.discard.nr_sectors = src->u.discard.nr_sectors;
                break;
        default:
+               /*
+                * Don't know how to translate this op. Only get the
+                * ID so failure can be reported to the frontend.
+                */
+               dst->u.other.id = src->u.other.id;
                break;
        }
 }
@@ -309,6 +328,11 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst,
                dst->u.discard.nr_sectors = src->u.discard.nr_sectors;
                break;
        default:
+               /*
+                * Don't know how to translate this op. Only get the
+                * ID so failure can be reported to the frontend.
+                */
+               dst->u.other.id = src->u.other.id;
                break;
        }
 }
index 5e237f630c47f2b2299749e067744dc89adba1a8..8bfd1bcf95ec0c168f565ac769479cb3be6098d3 100644 (file)
@@ -230,13 +230,13 @@ int __init xen_blkif_interface_init(void)
        }                                                               \
        static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
 
-VBD_SHOW(oo_req,  "%d\n", be->blkif->st_oo_req);
-VBD_SHOW(rd_req,  "%d\n", be->blkif->st_rd_req);
-VBD_SHOW(wr_req,  "%d\n", be->blkif->st_wr_req);
-VBD_SHOW(f_req,  "%d\n", be->blkif->st_f_req);
-VBD_SHOW(ds_req,  "%d\n", be->blkif->st_ds_req);
-VBD_SHOW(rd_sect, "%d\n", be->blkif->st_rd_sect);
-VBD_SHOW(wr_sect, "%d\n", be->blkif->st_wr_sect);
+VBD_SHOW(oo_req,  "%llu\n", be->blkif->st_oo_req);
+VBD_SHOW(rd_req,  "%llu\n", be->blkif->st_rd_req);
+VBD_SHOW(wr_req,  "%llu\n", be->blkif->st_wr_req);
+VBD_SHOW(f_req,  "%llu\n", be->blkif->st_f_req);
+VBD_SHOW(ds_req,  "%llu\n", be->blkif->st_ds_req);
+VBD_SHOW(rd_sect, "%llu\n", be->blkif->st_rd_sect);
+VBD_SHOW(wr_sect, "%llu\n", be->blkif->st_wr_sect);
 
 static struct attribute *xen_vbdstat_attrs[] = {
        &dev_attr_oo_req.attr,
index c3dae2e0f290e8ad64b4f3e6c869c2fca14cd1a1..a894f88762d8d3a1f72315e805f9494cdad8294d 100644 (file)
@@ -44,7 +44,7 @@
 #include <linux/mutex.h>
 #include <linux/scatterlist.h>
 #include <linux/bitmap.h>
-#include <linux/llist.h>
+#include <linux/list.h>
 
 #include <xen/xen.h>
 #include <xen/xenbus.h>
@@ -68,13 +68,12 @@ enum blkif_state {
 struct grant {
        grant_ref_t gref;
        unsigned long pfn;
-       struct llist_node node;
+       struct list_head node;
 };
 
 struct blk_shadow {
        struct blkif_request req;
        struct request *request;
-       unsigned long frame[BLKIF_MAX_SEGMENTS_PER_REQUEST];
        struct grant *grants_used[BLKIF_MAX_SEGMENTS_PER_REQUEST];
 };
 
@@ -105,7 +104,7 @@ struct blkfront_info
        struct work_struct work;
        struct gnttab_free_callback callback;
        struct blk_shadow shadow[BLK_RING_SIZE];
-       struct llist_head persistent_gnts;
+       struct list_head persistent_gnts;
        unsigned int persistent_gnts_c;
        unsigned long shadow_free;
        unsigned int feature_flush;
@@ -165,6 +164,69 @@ static int add_id_to_freelist(struct blkfront_info *info,
        return 0;
 }
 
+static int fill_grant_buffer(struct blkfront_info *info, int num)
+{
+       struct page *granted_page;
+       struct grant *gnt_list_entry, *n;
+       int i = 0;
+
+       while(i < num) {
+               gnt_list_entry = kzalloc(sizeof(struct grant), GFP_NOIO);
+               if (!gnt_list_entry)
+                       goto out_of_memory;
+
+               granted_page = alloc_page(GFP_NOIO);
+               if (!granted_page) {
+                       kfree(gnt_list_entry);
+                       goto out_of_memory;
+               }
+
+               gnt_list_entry->pfn = page_to_pfn(granted_page);
+               gnt_list_entry->gref = GRANT_INVALID_REF;
+               list_add(&gnt_list_entry->node, &info->persistent_gnts);
+               i++;
+       }
+
+       return 0;
+
+out_of_memory:
+       list_for_each_entry_safe(gnt_list_entry, n,
+                                &info->persistent_gnts, node) {
+               list_del(&gnt_list_entry->node);
+               __free_page(pfn_to_page(gnt_list_entry->pfn));
+               kfree(gnt_list_entry);
+               i--;
+       }
+       BUG_ON(i != 0);
+       return -ENOMEM;
+}
+
+static struct grant *get_grant(grant_ref_t *gref_head,
+                               struct blkfront_info *info)
+{
+       struct grant *gnt_list_entry;
+       unsigned long buffer_mfn;
+
+       BUG_ON(list_empty(&info->persistent_gnts));
+       gnt_list_entry = list_first_entry(&info->persistent_gnts, struct grant,
+                                         node);
+       list_del(&gnt_list_entry->node);
+
+       if (gnt_list_entry->gref != GRANT_INVALID_REF) {
+               info->persistent_gnts_c--;
+               return gnt_list_entry;
+       }
+
+       /* Assign a gref to this page */
+       gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head);
+       BUG_ON(gnt_list_entry->gref == -ENOSPC);
+       buffer_mfn = pfn_to_mfn(gnt_list_entry->pfn);
+       gnttab_grant_foreign_access_ref(gnt_list_entry->gref,
+                                       info->xbdev->otherend_id,
+                                       buffer_mfn, 0);
+       return gnt_list_entry;
+}
+
 static const char *op_name(int op)
 {
        static const char *const names[] = {
@@ -293,7 +355,6 @@ static int blkif_ioctl(struct block_device *bdev, fmode_t mode,
 static int blkif_queue_request(struct request *req)
 {
        struct blkfront_info *info = req->rq_disk->private_data;
-       unsigned long buffer_mfn;
        struct blkif_request *ring_req;
        unsigned long id;
        unsigned int fsect, lsect;
@@ -306,7 +367,6 @@ static int blkif_queue_request(struct request *req)
         */
        bool new_persistent_gnts;
        grant_ref_t gref_head;
-       struct page *granted_page;
        struct grant *gnt_list_entry = NULL;
        struct scatterlist *sg;
 
@@ -370,41 +430,8 @@ static int blkif_queue_request(struct request *req)
                        fsect = sg->offset >> 9;
                        lsect = fsect + (sg->length >> 9) - 1;
 
-                       if (info->persistent_gnts_c) {
-                               BUG_ON(llist_empty(&info->persistent_gnts));
-                               gnt_list_entry = llist_entry(
-                                       llist_del_first(&info->persistent_gnts),
-                                       struct grant, node);
-
-                               ref = gnt_list_entry->gref;
-                               buffer_mfn = pfn_to_mfn(gnt_list_entry->pfn);
-                               info->persistent_gnts_c--;
-                       } else {
-                               ref = gnttab_claim_grant_reference(&gref_head);
-                               BUG_ON(ref == -ENOSPC);
-
-                               gnt_list_entry =
-                                       kmalloc(sizeof(struct grant),
-                                                        GFP_ATOMIC);
-                               if (!gnt_list_entry)
-                                       return -ENOMEM;
-
-                               granted_page = alloc_page(GFP_ATOMIC);
-                               if (!granted_page) {
-                                       kfree(gnt_list_entry);
-                                       return -ENOMEM;
-                               }
-
-                               gnt_list_entry->pfn =
-                                       page_to_pfn(granted_page);
-                               gnt_list_entry->gref = ref;
-
-                               buffer_mfn = pfn_to_mfn(page_to_pfn(
-                                                               granted_page));
-                               gnttab_grant_foreign_access_ref(ref,
-                                       info->xbdev->otherend_id,
-                                       buffer_mfn, 0);
-                       }
+                       gnt_list_entry = get_grant(&gref_head, info);
+                       ref = gnt_list_entry->gref;
 
                        info->shadow[id].grants_used[i] = gnt_list_entry;
 
@@ -435,7 +462,6 @@ static int blkif_queue_request(struct request *req)
                                kunmap_atomic(shared_data);
                        }
 
-                       info->shadow[id].frame[i] = mfn_to_pfn(buffer_mfn);
                        ring_req->u.rw.seg[i] =
                                        (struct blkif_request_segment) {
                                                .gref       = ref,
@@ -790,9 +816,8 @@ static void blkif_restart_queue(struct work_struct *work)
 
 static void blkif_free(struct blkfront_info *info, int suspend)
 {
-       struct llist_node *all_gnts;
-       struct grant *persistent_gnt, *tmp;
-       struct llist_node *n;
+       struct grant *persistent_gnt;
+       struct grant *n;
 
        /* Prevent new requests being issued until we fix things up. */
        spin_lock_irq(&info->io_lock);
@@ -803,22 +828,20 @@ static void blkif_free(struct blkfront_info *info, int suspend)
                blk_stop_queue(info->rq);
 
        /* Remove all persistent grants */
-       if (info->persistent_gnts_c) {
-               all_gnts = llist_del_all(&info->persistent_gnts);
-               persistent_gnt = llist_entry(all_gnts, typeof(*(persistent_gnt)), node);
-               while (persistent_gnt) {
-                       gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL);
+       if (!list_empty(&info->persistent_gnts)) {
+               list_for_each_entry_safe(persistent_gnt, n,
+                                        &info->persistent_gnts, node) {
+                       list_del(&persistent_gnt->node);
+                       if (persistent_gnt->gref != GRANT_INVALID_REF) {
+                               gnttab_end_foreign_access(persistent_gnt->gref,
+                                                         0, 0UL);
+                               info->persistent_gnts_c--;
+                       }
                        __free_page(pfn_to_page(persistent_gnt->pfn));
-                       tmp = persistent_gnt;
-                       n = persistent_gnt->node.next;
-                       if (n)
-                               persistent_gnt = llist_entry(n, typeof(*(persistent_gnt)), node);
-                       else
-                               persistent_gnt = NULL;
-                       kfree(tmp);
+                       kfree(persistent_gnt);
                }
-               info->persistent_gnts_c = 0;
        }
+       BUG_ON(info->persistent_gnts_c != 0);
 
        /* No more gnttab callback work. */
        gnttab_cancel_free_callback(&info->callback);
@@ -875,7 +898,7 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
        }
        /* Add the persistent grant into the list of free grants */
        for (i = 0; i < s->req.u.rw.nr_segments; i++) {
-               llist_add(&s->grants_used[i]->node, &info->persistent_gnts);
+               list_add(&s->grants_used[i]->node, &info->persistent_gnts);
                info->persistent_gnts_c++;
        }
 }
@@ -1013,6 +1036,12 @@ static int setup_blkring(struct xenbus_device *dev,
 
        sg_init_table(info->sg, BLKIF_MAX_SEGMENTS_PER_REQUEST);
 
+       /* Allocate memory for grants */
+       err = fill_grant_buffer(info, BLK_RING_SIZE *
+                                     BLKIF_MAX_SEGMENTS_PER_REQUEST);
+       if (err)
+               goto fail;
+
        err = xenbus_grant_ring(dev, virt_to_mfn(info->ring.sring));
        if (err < 0) {
                free_page((unsigned long)sring);
@@ -1171,7 +1200,7 @@ static int blkfront_probe(struct xenbus_device *dev,
        spin_lock_init(&info->io_lock);
        info->xbdev = dev;
        info->vdevice = vdevice;
-       init_llist_head(&info->persistent_gnts);
+       INIT_LIST_HEAD(&info->persistent_gnts);
        info->persistent_gnts_c = 0;
        info->connected = BLKIF_STATE_DISCONNECTED;
        INIT_WORK(&info->work, blkif_restart_queue);
@@ -1203,11 +1232,10 @@ static int blkif_recover(struct blkfront_info *info)
        int j;
 
        /* Stage 1: Make a safe copy of the shadow state. */
-       copy = kmalloc(sizeof(info->shadow),
+       copy = kmemdup(info->shadow, sizeof(info->shadow),
                       GFP_NOIO | __GFP_REPEAT | __GFP_HIGH);
        if (!copy)
                return -ENOMEM;
-       memcpy(copy, info->shadow, sizeof(info->shadow));
 
        /* Stage 2: Set up free list. */
        memset(&info->shadow, 0, sizeof(info->shadow));
@@ -1236,7 +1264,7 @@ static int blkif_recover(struct blkfront_info *info)
                                gnttab_grant_foreign_access_ref(
                                        req->u.rw.seg[j].gref,
                                        info->xbdev->otherend_id,
-                                       pfn_to_mfn(info->shadow[req->u.rw.id].frame[j]),
+                                       pfn_to_mfn(copy[i].grants_used[j]->pfn),
                                        0);
                }
                info->shadow[req->u.rw.id].req = *req;
index b282af181b44dc974daab7ef4941e9373b833506..6aab00ef4379a5b9e4dfeb290461d3c177726f07 100644 (file)
@@ -73,9 +73,11 @@ static struct usb_device_id ath3k_table[] = {
        { USB_DEVICE(0x03F0, 0x311D) },
 
        /* Atheros AR3012 with sflash firmware*/
+       { USB_DEVICE(0x0CF3, 0x0036) },
        { USB_DEVICE(0x0CF3, 0x3004) },
        { USB_DEVICE(0x0CF3, 0x3008) },
        { USB_DEVICE(0x0CF3, 0x311D) },
+       { USB_DEVICE(0x0CF3, 0x817a) },
        { USB_DEVICE(0x13d3, 0x3375) },
        { USB_DEVICE(0x04CA, 0x3004) },
        { USB_DEVICE(0x04CA, 0x3005) },
@@ -107,9 +109,11 @@ MODULE_DEVICE_TABLE(usb, ath3k_table);
 static struct usb_device_id ath3k_blist_tbl[] = {
 
        /* Atheros AR3012 with sflash firmware*/
+       { USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0CF3, 0x817a), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
index e547851870e74811d71aa7511d5be022a0a862ab..2cc5f774a29c47140739361420564b3f7c15b095 100644 (file)
@@ -131,9 +131,11 @@ static struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
 
        /* Atheros 3012 with sflash firmware */
+       { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
+       { USB_DEVICE(0x0cf3, 0x817a), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
        { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
index a47e6ee98b8c9798da8ffad462dbc052ef875053..a64caefdba1228a242f1177422aad485b40c2dc5 100644 (file)
@@ -63,6 +63,14 @@ config CLK_TWL6040
          McPDM. McPDM module is using the external bit clock on the McPDM bus
          as functional clock.
 
+config COMMON_CLK_AXI_CLKGEN
+       tristate "AXI clkgen driver"
+       depends on ARCH_ZYNQ || MICROBLAZE
+       help
+       ---help---
+         Support for the Analog Devices axi-clkgen pcore clock generator for Xilinx
+         FPGAs. It is commonly used in Analog Devices' reference designs.
+
 endmenu
 
 source "drivers/clk/mvebu/Kconfig"
index 300d4775d9268334d30aeb1b6d8d7d8070de634b..17e8dc4e417cfdfa397a83649a1628f02fa382c3 100644 (file)
@@ -7,6 +7,7 @@ obj-$(CONFIG_COMMON_CLK)        += clk-fixed-factor.o
 obj-$(CONFIG_COMMON_CLK)       += clk-fixed-rate.o
 obj-$(CONFIG_COMMON_CLK)       += clk-gate.o
 obj-$(CONFIG_COMMON_CLK)       += clk-mux.o
+obj-$(CONFIG_COMMON_CLK)       += clk-composite.o
 
 # SoCs specific
 obj-$(CONFIG_ARCH_BCM2835)     += clk-bcm2835.o
@@ -23,14 +24,17 @@ ifeq ($(CONFIG_COMMON_CLK), y)
 obj-$(CONFIG_ARCH_MMP)         += mmp/
 endif
 obj-$(CONFIG_MACH_LOONGSON1)   += clk-ls1x.o
+obj-$(CONFIG_ARCH_SUNXI)       += sunxi/
 obj-$(CONFIG_ARCH_U8500)       += ux500/
 obj-$(CONFIG_ARCH_VT8500)      += clk-vt8500.o
 obj-$(CONFIG_ARCH_ZYNQ)                += clk-zynq.o
 obj-$(CONFIG_ARCH_TEGRA)       += tegra/
+obj-$(CONFIG_PLAT_SAMSUNG)     += samsung/
 
 obj-$(CONFIG_X86)              += x86/
 
 # Chip specific
+obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o
 obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
 obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
 obj-$(CONFIG_CLK_TWL6040)      += clk-twl6040.o
diff --git a/drivers/clk/clk-axi-clkgen.c b/drivers/clk/clk-axi-clkgen.c
new file mode 100644 (file)
index 0000000..8137327
--- /dev/null
@@ -0,0 +1,331 @@
+/*
+ * AXI clkgen driver
+ *
+ * Copyright 2012-2013 Analog Devices Inc.
+ *  Author: Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * Licensed under the GPL-2.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/module.h>
+#include <linux/err.h>
+
+#define AXI_CLKGEN_REG_UPDATE_ENABLE   0x04
+#define AXI_CLKGEN_REG_CLK_OUT1                0x08
+#define AXI_CLKGEN_REG_CLK_OUT2                0x0c
+#define AXI_CLKGEN_REG_CLK_DIV         0x10
+#define AXI_CLKGEN_REG_CLK_FB1         0x14
+#define AXI_CLKGEN_REG_CLK_FB2         0x18
+#define AXI_CLKGEN_REG_LOCK1           0x1c
+#define AXI_CLKGEN_REG_LOCK2           0x20
+#define AXI_CLKGEN_REG_LOCK3           0x24
+#define AXI_CLKGEN_REG_FILTER1         0x28
+#define AXI_CLKGEN_REG_FILTER2         0x2c
+
+struct axi_clkgen {
+       void __iomem *base;
+       struct clk_hw clk_hw;
+};
+
+static uint32_t axi_clkgen_lookup_filter(unsigned int m)
+{
+       switch (m) {
+       case 0:
+               return 0x01001990;
+       case 1:
+               return 0x01001190;
+       case 2:
+               return 0x01009890;
+       case 3:
+               return 0x01001890;
+       case 4:
+               return 0x01008890;
+       case 5 ... 8:
+               return 0x01009090;
+       case 9 ... 11:
+               return 0x01000890;
+       case 12:
+               return 0x08009090;
+       case 13 ... 22:
+               return 0x01001090;
+       case 23 ... 36:
+               return 0x01008090;
+       case 37 ... 46:
+               return 0x08001090;
+       default:
+               return 0x08008090;
+       }
+}
+
+static const uint32_t axi_clkgen_lock_table[] = {
+       0x060603e8, 0x060603e8, 0x080803e8, 0x0b0b03e8,
+       0x0e0e03e8, 0x111103e8, 0x131303e8, 0x161603e8,
+       0x191903e8, 0x1c1c03e8, 0x1f1f0384, 0x1f1f0339,
+       0x1f1f02ee, 0x1f1f02bc, 0x1f1f028a, 0x1f1f0271,
+       0x1f1f023f, 0x1f1f0226, 0x1f1f020d, 0x1f1f01f4,
+       0x1f1f01db, 0x1f1f01c2, 0x1f1f01a9, 0x1f1f0190,
+       0x1f1f0190, 0x1f1f0177, 0x1f1f015e, 0x1f1f015e,
+       0x1f1f0145, 0x1f1f0145, 0x1f1f012c, 0x1f1f012c,
+       0x1f1f012c, 0x1f1f0113, 0x1f1f0113, 0x1f1f0113,
+};
+
+static uint32_t axi_clkgen_lookup_lock(unsigned int m)
+{
+       if (m < ARRAY_SIZE(axi_clkgen_lock_table))
+               return axi_clkgen_lock_table[m];
+       return 0x1f1f00fa;
+}
+
+static const unsigned int fpfd_min = 10000;
+static const unsigned int fpfd_max = 300000;
+static const unsigned int fvco_min = 600000;
+static const unsigned int fvco_max = 1200000;
+
+static void axi_clkgen_calc_params(unsigned long fin, unsigned long fout,
+       unsigned int *best_d, unsigned int *best_m, unsigned int *best_dout)
+{
+       unsigned long d, d_min, d_max, _d_min, _d_max;
+       unsigned long m, m_min, m_max;
+       unsigned long f, dout, best_f, fvco;
+
+       fin /= 1000;
+       fout /= 1000;
+
+       best_f = ULONG_MAX;
+       *best_d = 0;
+       *best_m = 0;
+       *best_dout = 0;
+
+       d_min = max_t(unsigned long, DIV_ROUND_UP(fin, fpfd_max), 1);
+       d_max = min_t(unsigned long, fin / fpfd_min, 80);
+
+       m_min = max_t(unsigned long, DIV_ROUND_UP(fvco_min, fin) * d_min, 1);
+       m_max = min_t(unsigned long, fvco_max * d_max / fin, 64);
+
+       for (m = m_min; m <= m_max; m++) {
+               _d_min = max(d_min, DIV_ROUND_UP(fin * m, fvco_max));
+               _d_max = min(d_max, fin * m / fvco_min);
+
+               for (d = _d_min; d <= _d_max; d++) {
+                       fvco = fin * m / d;
+
+                       dout = DIV_ROUND_CLOSEST(fvco, fout);
+                       dout = clamp_t(unsigned long, dout, 1, 128);
+                       f = fvco / dout;
+                       if (abs(f - fout) < abs(best_f - fout)) {
+                               best_f = f;
+                               *best_d = d;
+                               *best_m = m;
+                               *best_dout = dout;
+                               if (best_f == fout)
+                                       return;
+                       }
+               }
+       }
+}
+
+static void axi_clkgen_calc_clk_params(unsigned int divider, unsigned int *low,
+       unsigned int *high, unsigned int *edge, unsigned int *nocount)
+{
+       if (divider == 1)
+               *nocount = 1;
+       else
+               *nocount = 0;
+
+       *high = divider / 2;
+       *edge = divider % 2;
+       *low = divider - *high;
+}
+
+static void axi_clkgen_write(struct axi_clkgen *axi_clkgen,
+       unsigned int reg, unsigned int val)
+{
+       writel(val, axi_clkgen->base + reg);
+}
+
+static void axi_clkgen_read(struct axi_clkgen *axi_clkgen,
+       unsigned int reg, unsigned int *val)
+{
+       *val = readl(axi_clkgen->base + reg);
+}
+
+static struct axi_clkgen *clk_hw_to_axi_clkgen(struct clk_hw *clk_hw)
+{
+       return container_of(clk_hw, struct axi_clkgen, clk_hw);
+}
+
+static int axi_clkgen_set_rate(struct clk_hw *clk_hw,
+       unsigned long rate, unsigned long parent_rate)
+{
+       struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
+       unsigned int d, m, dout;
+       unsigned int nocount;
+       unsigned int high;
+       unsigned int edge;
+       unsigned int low;
+       uint32_t filter;
+       uint32_t lock;
+
+       if (parent_rate == 0 || rate == 0)
+               return -EINVAL;
+
+       axi_clkgen_calc_params(parent_rate, rate, &d, &m, &dout);
+
+       if (d == 0 || dout == 0 || m == 0)
+               return -EINVAL;
+
+       filter = axi_clkgen_lookup_filter(m - 1);
+       lock = axi_clkgen_lookup_lock(m - 1);
+
+       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_UPDATE_ENABLE, 0);
+
+       axi_clkgen_calc_clk_params(dout, &low, &high, &edge, &nocount);
+       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT1,
+               (high << 6) | low);
+       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT2,
+               (edge << 7) | (nocount << 6));
+
+       axi_clkgen_calc_clk_params(d, &low, &high, &edge, &nocount);
+       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_DIV,
+               (edge << 13) | (nocount << 12) | (high << 6) | low);
+
+       axi_clkgen_calc_clk_params(m, &low, &high, &edge, &nocount);
+       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_FB1,
+               (high << 6) | low);
+       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_CLK_FB2,
+               (edge << 7) | (nocount << 6));
+
+       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_LOCK1, lock & 0x3ff);
+       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_LOCK2,
+               (((lock >> 16) & 0x1f) << 10) | 0x1);
+       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_LOCK3,
+               (((lock >> 24) & 0x1f) << 10) | 0x3e9);
+       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_FILTER1, filter >> 16);
+       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_FILTER2, filter);
+
+       axi_clkgen_write(axi_clkgen, AXI_CLKGEN_REG_UPDATE_ENABLE, 1);
+
+       return 0;
+}
+
+static long axi_clkgen_round_rate(struct clk_hw *hw, unsigned long rate,
+       unsigned long *parent_rate)
+{
+       unsigned int d, m, dout;
+
+       axi_clkgen_calc_params(*parent_rate, rate, &d, &m, &dout);
+
+       if (d == 0 || dout == 0 || m == 0)
+               return -EINVAL;
+
+       return *parent_rate / d * m / dout;
+}
+
+static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw,
+       unsigned long parent_rate)
+{
+       struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
+       unsigned int d, m, dout;
+       unsigned int reg;
+       unsigned long long tmp;
+
+       axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_OUT1, &reg);
+       dout = (reg & 0x3f) + ((reg >> 6) & 0x3f);
+       axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_DIV, &reg);
+       d = (reg & 0x3f) + ((reg >> 6) & 0x3f);
+       axi_clkgen_read(axi_clkgen, AXI_CLKGEN_REG_CLK_FB1, &reg);
+       m = (reg & 0x3f) + ((reg >> 6) & 0x3f);
+
+       if (d == 0 || dout == 0)
+               return 0;
+
+       tmp = (unsigned long long)(parent_rate / d) * m;
+       do_div(tmp, dout);
+
+       if (tmp > ULONG_MAX)
+               return ULONG_MAX;
+
+       return tmp;
+}
+
+static const struct clk_ops axi_clkgen_ops = {
+       .recalc_rate = axi_clkgen_recalc_rate,
+       .round_rate = axi_clkgen_round_rate,
+       .set_rate = axi_clkgen_set_rate,
+};
+
+static int axi_clkgen_probe(struct platform_device *pdev)
+{
+       struct axi_clkgen *axi_clkgen;
+       struct clk_init_data init;
+       const char *parent_name;
+       const char *clk_name;
+       struct resource *mem;
+       struct clk *clk;
+
+       axi_clkgen = devm_kzalloc(&pdev->dev, sizeof(*axi_clkgen), GFP_KERNEL);
+       if (!axi_clkgen)
+               return -ENOMEM;
+
+       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       axi_clkgen->base = devm_ioremap_resource(&pdev->dev, mem);
+       if (IS_ERR(axi_clkgen->base))
+               return PTR_ERR(axi_clkgen->base);
+
+       parent_name = of_clk_get_parent_name(pdev->dev.of_node, 0);
+       if (!parent_name)
+               return -EINVAL;
+
+       clk_name = pdev->dev.of_node->name;
+       of_property_read_string(pdev->dev.of_node, "clock-output-names",
+               &clk_name);
+
+       init.name = clk_name;
+       init.ops = &axi_clkgen_ops;
+       init.flags = 0;
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
+
+       axi_clkgen->clk_hw.init = &init;
+       clk = devm_clk_register(&pdev->dev, &axi_clkgen->clk_hw);
+       if (IS_ERR(clk))
+               return PTR_ERR(clk);
+
+       return of_clk_add_provider(pdev->dev.of_node, of_clk_src_simple_get,
+                                   clk);
+}
+
+static int axi_clkgen_remove(struct platform_device *pdev)
+{
+       of_clk_del_provider(pdev->dev.of_node);
+
+       return 0;
+}
+
+static const struct of_device_id axi_clkgen_ids[] = {
+       { .compatible = "adi,axi-clkgen-1.00.a" },
+       { },
+};
+MODULE_DEVICE_TABLE(of, axi_clkgen_ids);
+
+static struct platform_driver axi_clkgen_driver = {
+       .driver = {
+               .name = "adi-axi-clkgen",
+               .owner = THIS_MODULE,
+               .of_match_table = axi_clkgen_ids,
+       },
+       .probe = axi_clkgen_probe,
+       .remove = axi_clkgen_remove,
+};
+module_platform_driver(axi_clkgen_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("Driver for the Analog Devices' AXI clkgen pcore clock generator");
diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
new file mode 100644 (file)
index 0000000..097dee4
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2013 NVIDIA CORPORATION.  All rights reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#define to_clk_composite(_hw) container_of(_hw, struct clk_composite, hw)
+
+static u8 clk_composite_get_parent(struct clk_hw *hw)
+{
+       struct clk_composite *composite = to_clk_composite(hw);
+       const struct clk_ops *mux_ops = composite->mux_ops;
+       struct clk_hw *mux_hw = composite->mux_hw;
+
+       mux_hw->clk = hw->clk;
+
+       return mux_ops->get_parent(mux_hw);
+}
+
+static int clk_composite_set_parent(struct clk_hw *hw, u8 index)
+{
+       struct clk_composite *composite = to_clk_composite(hw);
+       const struct clk_ops *mux_ops = composite->mux_ops;
+       struct clk_hw *mux_hw = composite->mux_hw;
+
+       mux_hw->clk = hw->clk;
+
+       return mux_ops->set_parent(mux_hw, index);
+}
+
+static unsigned long clk_composite_recalc_rate(struct clk_hw *hw,
+                                           unsigned long parent_rate)
+{
+       struct clk_composite *composite = to_clk_composite(hw);
+       const struct clk_ops *div_ops = composite->div_ops;
+       struct clk_hw *div_hw = composite->div_hw;
+
+       div_hw->clk = hw->clk;
+
+       return div_ops->recalc_rate(div_hw, parent_rate);
+}
+
+static long clk_composite_round_rate(struct clk_hw *hw, unsigned long rate,
+                                 unsigned long *prate)
+{
+       struct clk_composite *composite = to_clk_composite(hw);
+       const struct clk_ops *div_ops = composite->div_ops;
+       struct clk_hw *div_hw = composite->div_hw;
+
+       div_hw->clk = hw->clk;
+
+       return div_ops->round_rate(div_hw, rate, prate);
+}
+
+static int clk_composite_set_rate(struct clk_hw *hw, unsigned long rate,
+                              unsigned long parent_rate)
+{
+       struct clk_composite *composite = to_clk_composite(hw);
+       const struct clk_ops *div_ops = composite->div_ops;
+       struct clk_hw *div_hw = composite->div_hw;
+
+       div_hw->clk = hw->clk;
+
+       return div_ops->set_rate(div_hw, rate, parent_rate);
+}
+
+static int clk_composite_is_enabled(struct clk_hw *hw)
+{
+       struct clk_composite *composite = to_clk_composite(hw);
+       const struct clk_ops *gate_ops = composite->gate_ops;
+       struct clk_hw *gate_hw = composite->gate_hw;
+
+       gate_hw->clk = hw->clk;
+
+       return gate_ops->is_enabled(gate_hw);
+}
+
+static int clk_composite_enable(struct clk_hw *hw)
+{
+       struct clk_composite *composite = to_clk_composite(hw);
+       const struct clk_ops *gate_ops = composite->gate_ops;
+       struct clk_hw *gate_hw = composite->gate_hw;
+
+       gate_hw->clk = hw->clk;
+
+       return gate_ops->enable(gate_hw);
+}
+
+static void clk_composite_disable(struct clk_hw *hw)
+{
+       struct clk_composite *composite = to_clk_composite(hw);
+       const struct clk_ops *gate_ops = composite->gate_ops;
+       struct clk_hw *gate_hw = composite->gate_hw;
+
+       gate_hw->clk = hw->clk;
+
+       gate_ops->disable(gate_hw);
+}
+
+struct clk *clk_register_composite(struct device *dev, const char *name,
+                       const char **parent_names, int num_parents,
+                       struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
+                       struct clk_hw *div_hw, const struct clk_ops *div_ops,
+                       struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
+                       unsigned long flags)
+{
+       struct clk *clk;
+       struct clk_init_data init;
+       struct clk_composite *composite;
+       struct clk_ops *clk_composite_ops;
+
+       composite = kzalloc(sizeof(*composite), GFP_KERNEL);
+       if (!composite) {
+               pr_err("%s: could not allocate composite clk\n", __func__);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       init.name = name;
+       init.flags = flags | CLK_IS_BASIC;
+       init.parent_names = parent_names;
+       init.num_parents = num_parents;
+
+       clk_composite_ops = &composite->ops;
+
+       if (mux_hw && mux_ops) {
+               if (!mux_ops->get_parent || !mux_ops->set_parent) {
+                       clk = ERR_PTR(-EINVAL);
+                       goto err;
+               }
+
+               composite->mux_hw = mux_hw;
+               composite->mux_ops = mux_ops;
+               clk_composite_ops->get_parent = clk_composite_get_parent;
+               clk_composite_ops->set_parent = clk_composite_set_parent;
+       }
+
+       if (div_hw && div_ops) {
+               if (!div_ops->recalc_rate || !div_ops->round_rate ||
+                   !div_ops->set_rate) {
+                       clk = ERR_PTR(-EINVAL);
+                       goto err;
+               }
+
+               composite->div_hw = div_hw;
+               composite->div_ops = div_ops;
+               clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
+               clk_composite_ops->round_rate = clk_composite_round_rate;
+               clk_composite_ops->set_rate = clk_composite_set_rate;
+       }
+
+       if (gate_hw && gate_ops) {
+               if (!gate_ops->is_enabled || !gate_ops->enable ||
+                   !gate_ops->disable) {
+                       clk = ERR_PTR(-EINVAL);
+                       goto err;
+               }
+
+               composite->gate_hw = gate_hw;
+               composite->gate_ops = gate_ops;
+               clk_composite_ops->is_enabled = clk_composite_is_enabled;
+               clk_composite_ops->enable = clk_composite_enable;
+               clk_composite_ops->disable = clk_composite_disable;
+       }
+
+       init.ops = clk_composite_ops;
+       composite->hw.init = &init;
+
+       clk = clk_register(dev, &composite->hw);
+       if (IS_ERR(clk))
+               goto err;
+
+       if (composite->mux_hw)
+               composite->mux_hw->clk = clk;
+
+       if (composite->div_hw)
+               composite->div_hw->clk = clk;
+
+       if (composite->gate_hw)
+               composite->gate_hw->clk = clk;
+
+       return clk;
+
+err:
+       kfree(composite);
+       return clk;
+}
index 508c032edce43e43259ca88ecfd9b77dc5704ce8..25b1734560d0c99bbae8455c78d22d613ccb99c0 100644 (file)
@@ -32,6 +32,7 @@
 static u8 clk_mux_get_parent(struct clk_hw *hw)
 {
        struct clk_mux *mux = to_clk_mux(hw);
+       int num_parents = __clk_get_num_parents(hw->clk);
        u32 val;
 
        /*
@@ -42,7 +43,16 @@ static u8 clk_mux_get_parent(struct clk_hw *hw)
         * val = 0x4 really means "bit 2, index starts at bit 0"
         */
        val = readl(mux->reg) >> mux->shift;
-       val &= (1 << mux->width) - 1;
+       val &= mux->mask;
+
+       if (mux->table) {
+               int i;
+
+               for (i = 0; i < num_parents; i++)
+                       if (mux->table[i] == val)
+                               return i;
+               return -EINVAL;
+       }
 
        if (val && (mux->flags & CLK_MUX_INDEX_BIT))
                val = ffs(val) - 1;
@@ -50,7 +60,7 @@ static u8 clk_mux_get_parent(struct clk_hw *hw)
        if (val && (mux->flags & CLK_MUX_INDEX_ONE))
                val--;
 
-       if (val >= __clk_get_num_parents(hw->clk))
+       if (val >= num_parents)
                return -EINVAL;
 
        return val;
@@ -62,17 +72,22 @@ static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
        u32 val;
        unsigned long flags = 0;
 
-       if (mux->flags & CLK_MUX_INDEX_BIT)
-               index = (1 << ffs(index));
+       if (mux->table)
+               index = mux->table[index];
 
-       if (mux->flags & CLK_MUX_INDEX_ONE)
-               index++;
+       else {
+               if (mux->flags & CLK_MUX_INDEX_BIT)
+                       index = (1 << ffs(index));
+
+               if (mux->flags & CLK_MUX_INDEX_ONE)
+                       index++;
+       }
 
        if (mux->lock)
                spin_lock_irqsave(mux->lock, flags);
 
        val = readl(mux->reg);
-       val &= ~(((1 << mux->width) - 1) << mux->shift);
+       val &= ~(mux->mask << mux->shift);
        val |= index << mux->shift;
        writel(val, mux->reg);
 
@@ -88,10 +103,10 @@ const struct clk_ops clk_mux_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_mux_ops);
 
-struct clk *clk_register_mux(struct device *dev, const char *name,
+struct clk *clk_register_mux_table(struct device *dev, const char *name,
                const char **parent_names, u8 num_parents, unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_mux_flags, spinlock_t *lock)
+               void __iomem *reg, u8 shift, u32 mask,
+               u8 clk_mux_flags, u32 *table, spinlock_t *lock)
 {
        struct clk_mux *mux;
        struct clk *clk;
@@ -113,9 +128,10 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
        /* struct clk_mux assignments */
        mux->reg = reg;
        mux->shift = shift;
-       mux->width = width;
+       mux->mask = mask;
        mux->flags = clk_mux_flags;
        mux->lock = lock;
+       mux->table = table;
        mux->hw.init = &init;
 
        clk = clk_register(dev, &mux->hw);
@@ -125,3 +141,15 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
 
        return clk;
 }
+
+struct clk *clk_register_mux(struct device *dev, const char *name,
+               const char **parent_names, u8 num_parents, unsigned long flags,
+               void __iomem *reg, u8 shift, u8 width,
+               u8 clk_mux_flags, spinlock_t *lock)
+{
+       u32 mask = BIT(width) - 1;
+
+       return clk_register_mux_table(dev, name, parent_names, num_parents,
+                                     flags, reg, shift, mask, clk_mux_flags,
+                                     NULL, lock);
+}
index f8e9d0c27be27252f53aeb0ecec904c9caabc99a..643ca653fef026b2de60235a1ef401e67c88148a 100644 (file)
@@ -1113,7 +1113,7 @@ void __init sirfsoc_of_clk_init(void)
 
        for (i = pll1; i < maxclk; i++) {
                prima2_clks[i] = clk_register(NULL, prima2_clk_hw_array[i]);
-               BUG_ON(!prima2_clks[i]);
+               BUG_ON(IS_ERR(prima2_clks[i]));
        }
        clk_register_clkdev(prima2_clks[cpu], NULL, "cpu");
        clk_register_clkdev(prima2_clks[io],  NULL, "io");
index b14a25f3925514ac09ee75953fa07e4104291b5b..32062977f45368d9561410193238362d29a332f4 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/slab.h>
 #include <linux/kernel.h>
 #include <linux/clk-provider.h>
+#include <linux/clk/zynq.h>
 
 static void __iomem *slcr_base;
 
index ed87b2405806f6a80f24b607be5d23ccc922ce26..0230c9d959752a954d36192ba4f24b59f9fa3541 100644 (file)
 #include <linux/of.h>
 #include <linux/device.h>
 #include <linux/init.h>
+#include <linux/sched.h>
 
 static DEFINE_SPINLOCK(enable_lock);
 static DEFINE_MUTEX(prepare_lock);
 
+static struct task_struct *prepare_owner;
+static struct task_struct *enable_owner;
+
+static int prepare_refcnt;
+static int enable_refcnt;
+
 static HLIST_HEAD(clk_root_list);
 static HLIST_HEAD(clk_orphan_list);
 static LIST_HEAD(clk_notifier_list);
 
+/***           locking             ***/
+static void clk_prepare_lock(void)
+{
+       if (!mutex_trylock(&prepare_lock)) {
+               if (prepare_owner == current) {
+                       prepare_refcnt++;
+                       return;
+               }
+               mutex_lock(&prepare_lock);
+       }
+       WARN_ON_ONCE(prepare_owner != NULL);
+       WARN_ON_ONCE(prepare_refcnt != 0);
+       prepare_owner = current;
+       prepare_refcnt = 1;
+}
+
+static void clk_prepare_unlock(void)
+{
+       WARN_ON_ONCE(prepare_owner != current);
+       WARN_ON_ONCE(prepare_refcnt == 0);
+
+       if (--prepare_refcnt)
+               return;
+       prepare_owner = NULL;
+       mutex_unlock(&prepare_lock);
+}
+
+static unsigned long clk_enable_lock(void)
+{
+       unsigned long flags;
+
+       if (!spin_trylock_irqsave(&enable_lock, flags)) {
+               if (enable_owner == current) {
+                       enable_refcnt++;
+                       return flags;
+               }
+               spin_lock_irqsave(&enable_lock, flags);
+       }
+       WARN_ON_ONCE(enable_owner != NULL);
+       WARN_ON_ONCE(enable_refcnt != 0);
+       enable_owner = current;
+       enable_refcnt = 1;
+       return flags;
+}
+
+static void clk_enable_unlock(unsigned long flags)
+{
+       WARN_ON_ONCE(enable_owner != current);
+       WARN_ON_ONCE(enable_refcnt == 0);
+
+       if (--enable_refcnt)
+               return;
+       enable_owner = NULL;
+       spin_unlock_irqrestore(&enable_lock, flags);
+}
+
 /***        debugfs support        ***/
 
 #ifdef CONFIG_COMMON_CLK_DEBUG
@@ -69,7 +132,7 @@ static int clk_summary_show(struct seq_file *s, void *data)
        seq_printf(s, "   clock                        enable_cnt  prepare_cnt  rate\n");
        seq_printf(s, "---------------------------------------------------------------------\n");
 
-       mutex_lock(&prepare_lock);
+       clk_prepare_lock();
 
        hlist_for_each_entry(c, &clk_root_list, child_node)
                clk_summary_show_subtree(s, c, 0);
@@ -77,7 +140,7 @@ static int clk_summary_show(struct seq_file *s, void *data)
        hlist_for_each_entry(c, &clk_orphan_list, child_node)
                clk_summary_show_subtree(s, c, 0);
 
-       mutex_unlock(&prepare_lock);
+       clk_prepare_unlock();
 
        return 0;
 }
@@ -130,7 +193,7 @@ static int clk_dump(struct seq_file *s, void *data)
 
        seq_printf(s, "{");
 
-       mutex_lock(&prepare_lock);
+       clk_prepare_lock();
 
        hlist_for_each_entry(c, &clk_root_list, child_node) {
                if (!first_node)
@@ -144,7 +207,7 @@ static int clk_dump(struct seq_file *s, void *data)
                clk_dump_subtree(s, c, 0);
        }
 
-       mutex_unlock(&prepare_lock);
+       clk_prepare_unlock();
 
        seq_printf(s, "}");
        return 0;
@@ -316,7 +379,7 @@ static int __init clk_debug_init(void)
        if (!orphandir)
                return -ENOMEM;
 
-       mutex_lock(&prepare_lock);
+       clk_prepare_lock();
 
        hlist_for_each_entry(clk, &clk_root_list, child_node)
                clk_debug_create_subtree(clk, rootdir);
@@ -326,7 +389,7 @@ static int __init clk_debug_init(void)
 
        inited = 1;
 
-       mutex_unlock(&prepare_lock);
+       clk_prepare_unlock();
 
        return 0;
 }
@@ -335,6 +398,31 @@ late_initcall(clk_debug_init);
 static inline int clk_debug_register(struct clk *clk) { return 0; }
 #endif
 
+/* caller must hold prepare_lock */
+static void clk_unprepare_unused_subtree(struct clk *clk)
+{
+       struct clk *child;
+
+       if (!clk)
+               return;
+
+       hlist_for_each_entry(child, &clk->children, child_node)
+               clk_unprepare_unused_subtree(child);
+
+       if (clk->prepare_count)
+               return;
+
+       if (clk->flags & CLK_IGNORE_UNUSED)
+               return;
+
+       if (__clk_is_prepared(clk)) {
+               if (clk->ops->unprepare_unused)
+                       clk->ops->unprepare_unused(clk->hw);
+               else if (clk->ops->unprepare)
+                       clk->ops->unprepare(clk->hw);
+       }
+}
+
 /* caller must hold prepare_lock */
 static void clk_disable_unused_subtree(struct clk *clk)
 {
@@ -347,7 +435,7 @@ static void clk_disable_unused_subtree(struct clk *clk)
        hlist_for_each_entry(child, &clk->children, child_node)
                clk_disable_unused_subtree(child);
 
-       spin_lock_irqsave(&enable_lock, flags);
+       flags = clk_enable_lock();
 
        if (clk->enable_count)
                goto unlock_out;
@@ -368,7 +456,7 @@ static void clk_disable_unused_subtree(struct clk *clk)
        }
 
 unlock_out:
-       spin_unlock_irqrestore(&enable_lock, flags);
+       clk_enable_unlock(flags);
 
 out:
        return;
@@ -378,7 +466,7 @@ static int clk_disable_unused(void)
 {
        struct clk *clk;
 
-       mutex_lock(&prepare_lock);
+       clk_prepare_lock();
 
        hlist_for_each_entry(clk, &clk_root_list, child_node)
                clk_disable_unused_subtree(clk);
@@ -386,7 +474,13 @@ static int clk_disable_unused(void)
        hlist_for_each_entry(clk, &clk_orphan_list, child_node)
                clk_disable_unused_subtree(clk);
 
-       mutex_unlock(&prepare_lock);
+       hlist_for_each_entry(clk, &clk_root_list, child_node)
+               clk_unprepare_unused_subtree(clk);
+
+       hlist_for_each_entry(clk, &clk_orphan_list, child_node)
+               clk_unprepare_unused_subtree(clk);
+
+       clk_prepare_unlock();
 
        return 0;
 }
@@ -451,6 +545,27 @@ unsigned long __clk_get_flags(struct clk *clk)
        return !clk ? 0 : clk->flags;
 }
 
+bool __clk_is_prepared(struct clk *clk)
+{
+       int ret;
+
+       if (!clk)
+               return false;
+
+       /*
+        * .is_prepared is optional for clocks that can prepare
+        * fall back to software usage counter if it is missing
+        */
+       if (!clk->ops->is_prepared) {
+               ret = clk->prepare_count ? 1 : 0;
+               goto out;
+       }
+
+       ret = clk->ops->is_prepared(clk->hw);
+out:
+       return !!ret;
+}
+
 bool __clk_is_enabled(struct clk *clk)
 {
        int ret;
@@ -548,9 +663,9 @@ void __clk_unprepare(struct clk *clk)
  */
 void clk_unprepare(struct clk *clk)
 {
-       mutex_lock(&prepare_lock);
+       clk_prepare_lock();
        __clk_unprepare(clk);
-       mutex_unlock(&prepare_lock);
+       clk_prepare_unlock();
 }
 EXPORT_SYMBOL_GPL(clk_unprepare);
 
@@ -596,9 +711,9 @@ int clk_prepare(struct clk *clk)
 {
        int ret;
 
-       mutex_lock(&prepare_lock);
+       clk_prepare_lock();
        ret = __clk_prepare(clk);
-       mutex_unlock(&prepare_lock);
+       clk_prepare_unlock();
 
        return ret;
 }
@@ -640,9 +755,9 @@ void clk_disable(struct clk *clk)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(&enable_lock, flags);
+       flags = clk_enable_lock();
        __clk_disable(clk);
-       spin_unlock_irqrestore(&enable_lock, flags);
+       clk_enable_unlock(flags);
 }
 EXPORT_SYMBOL_GPL(clk_disable);
 
@@ -693,9 +808,9 @@ int clk_enable(struct clk *clk)
        unsigned long flags;
        int ret;
 
-       spin_lock_irqsave(&enable_lock, flags);
+       flags = clk_enable_lock();
        ret = __clk_enable(clk);
-       spin_unlock_irqrestore(&enable_lock, flags);
+       clk_enable_unlock(flags);
 
        return ret;
 }
@@ -740,9 +855,9 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
 {
        unsigned long ret;
 
-       mutex_lock(&prepare_lock);
+       clk_prepare_lock();
        ret = __clk_round_rate(clk, rate);
-       mutex_unlock(&prepare_lock);
+       clk_prepare_unlock();
 
        return ret;
 }
@@ -837,13 +952,13 @@ unsigned long clk_get_rate(struct clk *clk)
 {
        unsigned long rate;
 
-       mutex_lock(&prepare_lock);
+       clk_prepare_lock();
 
        if (clk && (clk->flags & CLK_GET_RATE_NOCACHE))
                __clk_recalc_rates(clk, 0);
 
        rate = __clk_get_rate(clk);
-       mutex_unlock(&prepare_lock);
+       clk_prepare_unlock();
 
        return rate;
 }
@@ -974,7 +1089,7 @@ static struct clk *clk_propagate_rate_change(struct clk *clk, unsigned long even
        int ret = NOTIFY_DONE;
 
        if (clk->rate == clk->new_rate)
-               return 0;
+               return NULL;
 
        if (clk->notifier_count) {
                ret = __clk_notify(clk, event, clk->rate, clk->new_rate);
@@ -1048,7 +1163,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
        int ret = 0;
 
        /* prevent racing with updates to the clock topology */
-       mutex_lock(&prepare_lock);
+       clk_prepare_lock();
 
        /* bail early if nothing to do */
        if (rate == clk->rate)
@@ -1080,7 +1195,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
        clk_change_rate(top);
 
 out:
-       mutex_unlock(&prepare_lock);
+       clk_prepare_unlock();
 
        return ret;
 }
@@ -1096,9 +1211,9 @@ struct clk *clk_get_parent(struct clk *clk)
 {
        struct clk *parent;
 
-       mutex_lock(&prepare_lock);
+       clk_prepare_lock();
        parent = __clk_get_parent(clk);
-       mutex_unlock(&prepare_lock);
+       clk_prepare_unlock();
 
        return parent;
 }
@@ -1242,19 +1357,19 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent)
                __clk_prepare(parent);
 
        /* FIXME replace with clk_is_enabled(clk) someday */
-       spin_lock_irqsave(&enable_lock, flags);
+       flags = clk_enable_lock();
        if (clk->enable_count)
                __clk_enable(parent);
-       spin_unlock_irqrestore(&enable_lock, flags);
+       clk_enable_unlock(flags);
 
        /* change clock input source */
        ret = clk->ops->set_parent(clk->hw, i);
 
        /* clean up old prepare and enable */
-       spin_lock_irqsave(&enable_lock, flags);
+       flags = clk_enable_lock();
        if (clk->enable_count)
                __clk_disable(old_parent);
-       spin_unlock_irqrestore(&enable_lock, flags);
+       clk_enable_unlock(flags);
 
        if (clk->prepare_count)
                __clk_unprepare(old_parent);
@@ -1286,7 +1401,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
                return -ENOSYS;
 
        /* prevent racing with updates to the clock topology */
-       mutex_lock(&prepare_lock);
+       clk_prepare_lock();
 
        if (clk->parent == parent)
                goto out;
@@ -1315,7 +1430,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
        __clk_reparent(clk, parent);
 
 out:
-       mutex_unlock(&prepare_lock);
+       clk_prepare_unlock();
 
        return ret;
 }
@@ -1338,7 +1453,7 @@ int __clk_init(struct device *dev, struct clk *clk)
        if (!clk)
                return -EINVAL;
 
-       mutex_lock(&prepare_lock);
+       clk_prepare_lock();
 
        /* check to see if a clock with this name is already registered */
        if (__clk_lookup(clk->name)) {
@@ -1462,7 +1577,7 @@ int __clk_init(struct device *dev, struct clk *clk)
        clk_debug_register(clk);
 
 out:
-       mutex_unlock(&prepare_lock);
+       clk_prepare_unlock();
 
        return ret;
 }
@@ -1696,7 +1811,7 @@ int clk_notifier_register(struct clk *clk, struct notifier_block *nb)
        if (!clk || !nb)
                return -EINVAL;
 
-       mutex_lock(&prepare_lock);
+       clk_prepare_lock();
 
        /* search the list of notifiers for this clk */
        list_for_each_entry(cn, &clk_notifier_list, node)
@@ -1720,7 +1835,7 @@ int clk_notifier_register(struct clk *clk, struct notifier_block *nb)
        clk->notifier_count++;
 
 out:
-       mutex_unlock(&prepare_lock);
+       clk_prepare_unlock();
 
        return ret;
 }
@@ -1745,7 +1860,7 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
        if (!clk || !nb)
                return -EINVAL;
 
-       mutex_lock(&prepare_lock);
+       clk_prepare_lock();
 
        list_for_each_entry(cn, &clk_notifier_list, node)
                if (cn->clk == clk)
@@ -1766,7 +1881,7 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
                ret = -ENOENT;
        }
 
-       mutex_unlock(&prepare_lock);
+       clk_prepare_unlock();
 
        return ret;
 }
index b5c06f9766f610439954d7f55489e4e7750cf726..f6a74872f14ee78a1a91b3cca813949bb814059a 100644 (file)
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/of.h>
-#include <mach/common.h>
-#include <mach/mx23.h>
+#include <linux/of_address.h>
 #include "clk.h"
 
-#define DIGCTRL                        MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
-#define CLKCTRL                        MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
+static void __iomem *clkctrl;
+static void __iomem *digctrl;
+
+#define CLKCTRL clkctrl
+#define DIGCTRL digctrl
+
 #define PLLCTRL0               (CLKCTRL + 0x0000)
 #define CPU                    (CLKCTRL + 0x0020)
 #define HBUS                   (CLKCTRL + 0x0030)
@@ -48,10 +51,10 @@ static void __init clk_misc_init(void)
        u32 val;
 
        /* Gate off cpu clock in WFI for power saving */
-       __mxs_setl(1 << BP_CPU_INTERRUPT_WAIT, CPU);
+       writel_relaxed(1 << BP_CPU_INTERRUPT_WAIT, CPU + SET);
 
        /* Clear BYPASS for SAIF */
-       __mxs_clrl(1 << BP_CLKSEQ_BYPASS_SAIF, CLKSEQ);
+       writel_relaxed(1 << BP_CLKSEQ_BYPASS_SAIF, CLKSEQ + CLR);
 
        /* SAIF has to use frac div for functional operation */
        val = readl_relaxed(SAIF);
@@ -62,14 +65,14 @@ static void __init clk_misc_init(void)
         * Source ssp clock from ref_io than ref_xtal,
         * as ref_xtal only provides 24 MHz as maximum.
         */
-       __mxs_clrl(1 << BP_CLKSEQ_BYPASS_SSP, CLKSEQ);
+       writel_relaxed(1 << BP_CLKSEQ_BYPASS_SSP, CLKSEQ + CLR);
 
        /*
         * 480 MHz seems too high to be ssp clock source directly,
         * so set frac to get a 288 MHz ref_io.
         */
-       __mxs_clrl(0x3f << BP_FRAC_IOFRAC, FRAC);
-       __mxs_setl(30 << BP_FRAC_IOFRAC, FRAC);
+       writel_relaxed(0x3f << BP_FRAC_IOFRAC, FRAC + CLR);
+       writel_relaxed(30 << BP_FRAC_IOFRAC, FRAC + SET);
 }
 
 static const char *sel_pll[]  __initconst = { "pll", "ref_xtal", };
@@ -101,6 +104,14 @@ int __init mx23_clocks_init(void)
        struct device_node *np;
        u32 i;
 
+       np = of_find_compatible_node(NULL, NULL, "fsl,imx23-digctl");
+       digctrl = of_iomap(np, 0);
+       WARN_ON(!digctrl);
+
+       np = of_find_compatible_node(NULL, NULL, "fsl,imx23-clkctrl");
+       clkctrl = of_iomap(np, 0);
+       WARN_ON(!clkctrl);
+
        clk_misc_init();
 
        clks[ref_xtal] = mxs_clk_fixed("ref_xtal", 24000000);
@@ -153,19 +164,12 @@ int __init mx23_clocks_init(void)
                        return PTR_ERR(clks[i]);
                }
 
-       np = of_find_compatible_node(NULL, NULL, "fsl,imx23-clkctrl");
-       if (np) {
-               clk_data.clks = clks;
-               clk_data.clk_num = ARRAY_SIZE(clks);
-               of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
-       }
-
-       clk_register_clkdev(clks[clk32k], NULL, "timrot");
+       clk_data.clks = clks;
+       clk_data.clk_num = ARRAY_SIZE(clks);
+       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
 
        for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
                clk_prepare_enable(clks[clks_init_on[i]]);
 
-       mxs_timer_init();
-
        return 0;
 }
index 76ce6c6d1113dc4e9a9451ff96da6166442da308..d0e5eed146de69baf6baf1295f12cadce8d4a923 100644 (file)
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/of.h>
-#include <mach/common.h>
-#include <mach/mx28.h>
+#include <linux/of_address.h>
 #include "clk.h"
 
-#define CLKCTRL                        MX28_IO_ADDRESS(MX28_CLKCTRL_BASE_ADDR)
+static void __iomem *clkctrl;
+#define CLKCTRL clkctrl
+
 #define PLL0CTRL0              (CLKCTRL + 0x0000)
 #define PLL1CTRL0              (CLKCTRL + 0x0020)
 #define PLL2CTRL0              (CLKCTRL + 0x0040)
@@ -53,7 +54,8 @@
 #define BP_FRAC0_IO1FRAC       16
 #define BP_FRAC0_IO0FRAC       24
 
-#define DIGCTRL                        MX28_IO_ADDRESS(MX28_DIGCTL_BASE_ADDR)
+static void __iomem *digctrl;
+#define DIGCTRL digctrl
 #define BP_SAIF_CLKMUX         10
 
 /*
@@ -72,8 +74,8 @@ int mxs_saif_clkmux_select(unsigned int clkmux)
        if (clkmux > 0x3)
                return -EINVAL;
 
-       __mxs_clrl(0x3 << BP_SAIF_CLKMUX, DIGCTRL);
-       __mxs_setl(clkmux << BP_SAIF_CLKMUX, DIGCTRL);
+       writel_relaxed(0x3 << BP_SAIF_CLKMUX, DIGCTRL + CLR);
+       writel_relaxed(clkmux << BP_SAIF_CLKMUX, DIGCTRL + SET);
 
        return 0;
 }
@@ -83,13 +85,13 @@ static void __init clk_misc_init(void)
        u32 val;
 
        /* Gate off cpu clock in WFI for power saving */
-       __mxs_setl(1 << BP_CPU_INTERRUPT_WAIT, CPU);
+       writel_relaxed(1 << BP_CPU_INTERRUPT_WAIT, CPU + SET);
 
        /* 0 is a bad default value for a divider */
-       __mxs_setl(1 << BP_ENET_DIV_TIME, ENET);
+       writel_relaxed(1 << BP_ENET_DIV_TIME, ENET + SET);
 
        /* Clear BYPASS for SAIF */
-       __mxs_clrl(0x3 << BP_CLKSEQ_BYPASS_SAIF0, CLKSEQ);
+       writel_relaxed(0x3 << BP_CLKSEQ_BYPASS_SAIF0, CLKSEQ + CLR);
 
        /* SAIF has to use frac div for functional operation */
        val = readl_relaxed(SAIF0);
@@ -109,7 +111,7 @@ static void __init clk_misc_init(void)
         * Source ssp clock from ref_io than ref_xtal,
         * as ref_xtal only provides 24 MHz as maximum.
         */
-       __mxs_clrl(0xf << BP_CLKSEQ_BYPASS_SSP0, CLKSEQ);
+       writel_relaxed(0xf << BP_CLKSEQ_BYPASS_SSP0, CLKSEQ + CLR);
 
        /*
         * 480 MHz seems too high to be ssp clock source directly,
@@ -156,6 +158,14 @@ int __init mx28_clocks_init(void)
        struct device_node *np;
        u32 i;
 
+       np = of_find_compatible_node(NULL, NULL, "fsl,imx28-digctl");
+       digctrl = of_iomap(np, 0);
+       WARN_ON(!digctrl);
+
+       np = of_find_compatible_node(NULL, NULL, "fsl,imx28-clkctrl");
+       clkctrl = of_iomap(np, 0);
+       WARN_ON(!clkctrl);
+
        clk_misc_init();
 
        clks[ref_xtal] = mxs_clk_fixed("ref_xtal", 24000000);
@@ -231,20 +241,14 @@ int __init mx28_clocks_init(void)
                        return PTR_ERR(clks[i]);
                }
 
-       np = of_find_compatible_node(NULL, NULL, "fsl,imx28-clkctrl");
-       if (np) {
-               clk_data.clks = clks;
-               clk_data.clk_num = ARRAY_SIZE(clks);
-               of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
-       }
+       clk_data.clks = clks;
+       clk_data.clk_num = ARRAY_SIZE(clks);
+       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
 
-       clk_register_clkdev(clks[xbus], NULL, "timrot");
        clk_register_clkdev(clks[enet_out], NULL, "enet_out");
 
        for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
                clk_prepare_enable(clks[clks_init_on[i]]);
 
-       mxs_timer_init();
-
        return 0;
 }
index b24d56067c800a987b13746bc780a8d0e9ca4486..5301bce8957b92e9cb5a40f692d26180e767737e 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/io.h>
 #include <linux/jiffies.h>
 #include <linux/spinlock.h>
+#include "clk.h"
 
 DEFINE_SPINLOCK(mxs_lock);
 
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
new file mode 100644 (file)
index 0000000..b7c232e
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# Samsung Clock specific Makefile
+#
+
+obj-$(CONFIG_COMMON_CLK)       += clk.o clk-pll.o
+obj-$(CONFIG_ARCH_EXYNOS4)     += clk-exynos4.o
+obj-$(CONFIG_SOC_EXYNOS5250)   += clk-exynos5250.o
+obj-$(CONFIG_SOC_EXYNOS5440)   += clk-exynos5440.o
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
new file mode 100644 (file)
index 0000000..7104669
--- /dev/null
@@ -0,0 +1,1091 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2013 Linaro Ltd.
+ * Author: Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * 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.
+ *
+ * Common Clock Framework support for all Exynos4 SoCs.
+*/
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <plat/cpu.h>
+#include "clk.h"
+#include "clk-pll.h"
+
+/* Exynos4 clock controller register offsets */
+#define SRC_LEFTBUS            0x4200
+#define DIV_LEFTBUS            0x4500
+#define GATE_IP_LEFTBUS                0x4800
+#define E4X12_GATE_IP_IMAGE    0x4930
+#define SRC_RIGHTBUS           0x8200
+#define DIV_RIGHTBUS           0x8500
+#define GATE_IP_RIGHTBUS       0x8800
+#define E4X12_GATE_IP_PERIR    0x8960
+#define EPLL_LOCK              0xc010
+#define VPLL_LOCK              0xc020
+#define EPLL_CON0              0xc110
+#define EPLL_CON1              0xc114
+#define EPLL_CON2              0xc118
+#define VPLL_CON0              0xc120
+#define VPLL_CON1              0xc124
+#define VPLL_CON2              0xc128
+#define SRC_TOP0               0xc210
+#define SRC_TOP1               0xc214
+#define SRC_CAM                        0xc220
+#define SRC_TV                 0xc224
+#define SRC_MFC                        0xcc28
+#define SRC_G3D                        0xc22c
+#define E4210_SRC_IMAGE                0xc230
+#define SRC_LCD0               0xc234
+#define E4210_SRC_LCD1         0xc238
+#define E4X12_SRC_ISP          0xc238
+#define SRC_MAUDIO             0xc23c
+#define SRC_FSYS               0xc240
+#define SRC_PERIL0             0xc250
+#define SRC_PERIL1             0xc254
+#define E4X12_SRC_CAM1         0xc258
+#define SRC_MASK_TOP           0xc310
+#define SRC_MASK_CAM           0xc320
+#define SRC_MASK_TV            0xc324
+#define SRC_MASK_LCD0          0xc334
+#define E4210_SRC_MASK_LCD1    0xc338
+#define E4X12_SRC_MASK_ISP     0xc338
+#define SRC_MASK_MAUDIO                0xc33c
+#define SRC_MASK_FSYS          0xc340
+#define SRC_MASK_PERIL0                0xc350
+#define SRC_MASK_PERIL1                0xc354
+#define DIV_TOP                        0xc510
+#define DIV_CAM                        0xc520
+#define DIV_TV                 0xc524
+#define DIV_MFC                        0xc528
+#define DIV_G3D                        0xc52c
+#define DIV_IMAGE              0xc530
+#define DIV_LCD0               0xc534
+#define E4210_DIV_LCD1         0xc538
+#define E4X12_DIV_ISP          0xc538
+#define DIV_MAUDIO             0xc53c
+#define DIV_FSYS0              0xc540
+#define DIV_FSYS1              0xc544
+#define DIV_FSYS2              0xc548
+#define DIV_FSYS3              0xc54c
+#define DIV_PERIL0             0xc550
+#define DIV_PERIL1             0xc554
+#define DIV_PERIL2             0xc558
+#define DIV_PERIL3             0xc55c
+#define DIV_PERIL4             0xc560
+#define DIV_PERIL5             0xc564
+#define E4X12_DIV_CAM1         0xc568
+#define GATE_SCLK_CAM          0xc820
+#define GATE_IP_CAM            0xc920
+#define GATE_IP_TV             0xc924
+#define GATE_IP_MFC            0xc928
+#define GATE_IP_G3D            0xc92c
+#define E4210_GATE_IP_IMAGE    0xc930
+#define GATE_IP_LCD0           0xc934
+#define E4210_GATE_IP_LCD1     0xc938
+#define E4X12_GATE_IP_ISP      0xc938
+#define E4X12_GATE_IP_MAUDIO   0xc93c
+#define GATE_IP_FSYS           0xc940
+#define GATE_IP_GPS            0xc94c
+#define GATE_IP_PERIL          0xc950
+#define E4210_GATE_IP_PERIR    0xc960
+#define GATE_BLOCK             0xc970
+#define E4X12_MPLL_CON0                0x10108
+#define SRC_DMC                        0x10200
+#define SRC_MASK_DMC           0x10300
+#define DIV_DMC0               0x10500
+#define DIV_DMC1               0x10504
+#define GATE_IP_DMC            0x10900
+#define APLL_CON0              0x14100
+#define E4210_MPLL_CON0                0x14108
+#define SRC_CPU                        0x14200
+#define DIV_CPU0               0x14500
+#define DIV_CPU1               0x14504
+#define GATE_SCLK_CPU          0x14800
+#define GATE_IP_CPU            0x14900
+#define E4X12_DIV_ISP0         0x18300
+#define E4X12_DIV_ISP1         0x18304
+#define E4X12_GATE_ISP0                0x18800
+#define E4X12_GATE_ISP1                0x18804
+
+/* the exynos4 soc type */
+enum exynos4_soc {
+       EXYNOS4210,
+       EXYNOS4X12,
+};
+
+/*
+ * Let each supported clock get a unique id. This id is used to lookup the clock
+ * for device tree based platforms. The clocks are categorized into three
+ * sections: core, sclk gate and bus interface gate clocks.
+ *
+ * When adding a new clock to this list, it is advised to choose a clock
+ * category and add it to the end of that category. That is because the the
+ * device tree source file is referring to these ids and any change in the
+ * sequence number of existing clocks will require corresponding change in the
+ * device tree files. This limitation would go away when pre-processor support
+ * for dtc would be available.
+ */
+enum exynos4_clks {
+       none,
+
+       /* core clocks */
+       xxti, xusbxti, fin_pll, fout_apll, fout_mpll, fout_epll, fout_vpll,
+       sclk_apll, sclk_mpll, sclk_epll, sclk_vpll, arm_clk, aclk200, aclk100,
+       aclk160, aclk133, mout_mpll_user_t, mout_mpll_user_c, mout_core,
+       mout_apll, /* 20 */
+
+       /* gate for special clocks (sclk) */
+       sclk_fimc0 = 128, sclk_fimc1, sclk_fimc2, sclk_fimc3, sclk_cam0,
+       sclk_cam1, sclk_csis0, sclk_csis1, sclk_hdmi, sclk_mixer, sclk_dac,
+       sclk_pixel, sclk_fimd0, sclk_mdnie0, sclk_mdnie_pwm0, sclk_mipi0,
+       sclk_audio0, sclk_mmc0, sclk_mmc1, sclk_mmc2, sclk_mmc3, sclk_mmc4,
+       sclk_sata, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3, sclk_uart4,
+       sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1, sclk_spi2,
+       sclk_slimbus, sclk_fimd1, sclk_mipi1, sclk_pcm1, sclk_pcm2, sclk_i2s1,
+       sclk_i2s2, sclk_mipihsi, sclk_mfc, sclk_pcm0, sclk_g3d, sclk_pwm_isp,
+       sclk_spi0_isp, sclk_spi1_isp, sclk_uart_isp,
+
+       /* gate clocks */
+       fimc0 = 256, fimc1, fimc2, fimc3, csis0, csis1, jpeg, smmu_fimc0,
+       smmu_fimc1, smmu_fimc2, smmu_fimc3, smmu_jpeg, vp, mixer, tvenc, hdmi,
+       smmu_tv, mfc, smmu_mfcl, smmu_mfcr, g3d, g2d, rotator, mdma, smmu_g2d,
+       smmu_rotator, smmu_mdma, fimd0, mie0, mdnie0, dsim0, smmu_fimd0, fimd1,
+       mie1, dsim1, smmu_fimd1, pdma0, pdma1, pcie_phy, sata_phy, tsi, sdmmc0,
+       sdmmc1, sdmmc2, sdmmc3, sdmmc4, sata, sromc, usb_host, usb_device, pcie,
+       onenand, nfcon, smmu_pcie, gps, smmu_gps, uart0, uart1, uart2, uart3,
+       uart4, i2c0, i2c1, i2c2, i2c3, i2c4, i2c5, i2c6, i2c7, i2c_hdmi, tsadc,
+       spi0, spi1, spi2, i2s1, i2s2, pcm0, i2s0, pcm1, pcm2, pwm, slimbus,
+       spdif, ac97, modemif, chipid, sysreg, hdmi_cec, mct, wdt, rtc, keyif,
+       audss, mipi_hsi, mdma2, pixelasyncm0, pixelasyncm1, fimc_lite0,
+       fimc_lite1, ppmuispx, ppmuispmx, fimc_isp, fimc_drc, fimc_fd, mcuisp,
+       gicisp, smmu_isp, smmu_drc, smmu_fd, smmu_lite0, smmu_lite1, mcuctl_isp,
+       mpwm_isp, i2c0_isp, i2c1_isp, mtcadc_isp, pwm_isp, wdt_isp, uart_isp,
+       asyncaxim, smmu_ispcx, spi0_isp, spi1_isp, pwm_isp_sclk, spi0_isp_sclk,
+       spi1_isp_sclk, uart_isp_sclk,
+
+       /* mux clocks */
+       mout_fimc0 = 384, mout_fimc1, mout_fimc2, mout_fimc3, mout_cam0,
+       mout_cam1, mout_csis0, mout_csis1, mout_g3d0, mout_g3d1, mout_g3d,
+       aclk400_mcuisp,
+
+       /* div clocks */
+       div_isp0 = 450, div_isp1, div_mcuisp0, div_mcuisp1, div_aclk200,
+       div_aclk400_mcuisp,
+
+       nr_clks,
+};
+
+/*
+ * list of controller registers to be saved and restored during a
+ * suspend/resume cycle.
+ */
+static __initdata unsigned long exynos4210_clk_save[] = {
+       E4210_SRC_IMAGE,
+       E4210_SRC_LCD1,
+       E4210_SRC_MASK_LCD1,
+       E4210_DIV_LCD1,
+       E4210_GATE_IP_IMAGE,
+       E4210_GATE_IP_LCD1,
+       E4210_GATE_IP_PERIR,
+       E4210_MPLL_CON0,
+};
+
+static __initdata unsigned long exynos4x12_clk_save[] = {
+       E4X12_GATE_IP_IMAGE,
+       E4X12_GATE_IP_PERIR,
+       E4X12_SRC_CAM1,
+       E4X12_DIV_ISP,
+       E4X12_DIV_CAM1,
+       E4X12_MPLL_CON0,
+};
+
+static __initdata unsigned long exynos4_clk_regs[] = {
+       SRC_LEFTBUS,
+       DIV_LEFTBUS,
+       GATE_IP_LEFTBUS,
+       SRC_RIGHTBUS,
+       DIV_RIGHTBUS,
+       GATE_IP_RIGHTBUS,
+       EPLL_CON0,
+       EPLL_CON1,
+       EPLL_CON2,
+       VPLL_CON0,
+       VPLL_CON1,
+       VPLL_CON2,
+       SRC_TOP0,
+       SRC_TOP1,
+       SRC_CAM,
+       SRC_TV,
+       SRC_MFC,
+       SRC_G3D,
+       SRC_LCD0,
+       SRC_MAUDIO,
+       SRC_FSYS,
+       SRC_PERIL0,
+       SRC_PERIL1,
+       SRC_MASK_TOP,
+       SRC_MASK_CAM,
+       SRC_MASK_TV,
+       SRC_MASK_LCD0,
+       SRC_MASK_MAUDIO,
+       SRC_MASK_FSYS,
+       SRC_MASK_PERIL0,
+       SRC_MASK_PERIL1,
+       DIV_TOP,
+       DIV_CAM,
+       DIV_TV,
+       DIV_MFC,
+       DIV_G3D,
+       DIV_IMAGE,
+       DIV_LCD0,
+       DIV_MAUDIO,
+       DIV_FSYS0,
+       DIV_FSYS1,
+       DIV_FSYS2,
+       DIV_FSYS3,
+       DIV_PERIL0,
+       DIV_PERIL1,
+       DIV_PERIL2,
+       DIV_PERIL3,
+       DIV_PERIL4,
+       DIV_PERIL5,
+       GATE_SCLK_CAM,
+       GATE_IP_CAM,
+       GATE_IP_TV,
+       GATE_IP_MFC,
+       GATE_IP_G3D,
+       GATE_IP_LCD0,
+       GATE_IP_FSYS,
+       GATE_IP_GPS,
+       GATE_IP_PERIL,
+       GATE_BLOCK,
+       SRC_MASK_DMC,
+       SRC_DMC,
+       DIV_DMC0,
+       DIV_DMC1,
+       GATE_IP_DMC,
+       APLL_CON0,
+       SRC_CPU,
+       DIV_CPU0,
+       DIV_CPU1,
+       GATE_SCLK_CPU,
+       GATE_IP_CPU,
+};
+
+/* list of all parent clock list */
+PNAME(mout_apll_p)     = { "fin_pll", "fout_apll", };
+PNAME(mout_mpll_p)     = { "fin_pll", "fout_mpll", };
+PNAME(mout_epll_p)     = { "fin_pll", "fout_epll", };
+PNAME(mout_vpllsrc_p)  = { "fin_pll", "sclk_hdmi24m", };
+PNAME(mout_vpll_p)     = { "fin_pll", "fout_vpll", };
+PNAME(sclk_evpll_p)    = { "sclk_epll", "sclk_vpll", };
+PNAME(mout_mfc_p)      = { "mout_mfc0", "mout_mfc1", };
+PNAME(mout_g3d_p)      = { "mout_g3d0", "mout_g3d1", };
+PNAME(mout_g2d_p)      = { "mout_g2d0", "mout_g2d1", };
+PNAME(mout_hdmi_p)     = { "sclk_pixel", "sclk_hdmiphy", };
+PNAME(mout_jpeg_p)     = { "mout_jpeg0", "mout_jpeg1", };
+PNAME(mout_spdif_p)    = { "sclk_audio0", "sclk_audio1", "sclk_audio2",
+                               "spdif_extclk", };
+PNAME(mout_onenand_p)  = {"aclk133", "aclk160", };
+PNAME(mout_onenand1_p) = {"mout_onenand", "sclk_vpll", };
+
+/* Exynos 4210-specific parent groups */
+PNAME(sclk_vpll_p4210) = { "mout_vpllsrc", "fout_vpll", };
+PNAME(mout_core_p4210) = { "mout_apll", "sclk_mpll", };
+PNAME(sclk_ampll_p4210)        = { "sclk_mpll", "sclk_apll", };
+PNAME(group1_p4210)    = { "xxti", "xusbxti", "sclk_hdmi24m",
+                               "sclk_usbphy0", "none", "sclk_hdmiphy",
+                               "sclk_mpll", "sclk_epll", "sclk_vpll", };
+PNAME(mout_audio0_p4210) = { "cdclk0", "none", "sclk_hdmi24m",
+                               "sclk_usbphy0", "xxti", "xusbxti", "sclk_mpll",
+                               "sclk_epll", "sclk_vpll" };
+PNAME(mout_audio1_p4210) = { "cdclk1", "none", "sclk_hdmi24m",
+                               "sclk_usbphy0", "xxti", "xusbxti", "sclk_mpll",
+                               "sclk_epll", "sclk_vpll", };
+PNAME(mout_audio2_p4210) = { "cdclk2", "none", "sclk_hdmi24m",
+                               "sclk_usbphy0", "xxti", "xusbxti", "sclk_mpll",
+                               "sclk_epll", "sclk_vpll", };
+PNAME(mout_mixer_p4210)        = { "sclk_dac", "sclk_hdmi", };
+PNAME(mout_dac_p4210)  = { "sclk_vpll", "sclk_hdmiphy", };
+
+/* Exynos 4x12-specific parent groups */
+PNAME(mout_mpll_user_p4x12) = { "fin_pll", "sclk_mpll", };
+PNAME(mout_core_p4x12) = { "mout_apll", "mout_mpll_user_c", };
+PNAME(sclk_ampll_p4x12)        = { "mout_mpll_user_t", "sclk_apll", };
+PNAME(group1_p4x12)    = { "xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0",
+                               "none", "sclk_hdmiphy", "mout_mpll_user_t",
+                               "sclk_epll", "sclk_vpll", };
+PNAME(mout_audio0_p4x12) = { "cdclk0", "none", "sclk_hdmi24m",
+                               "sclk_usbphy0", "xxti", "xusbxti",
+                               "mout_mpll_user_t", "sclk_epll", "sclk_vpll" };
+PNAME(mout_audio1_p4x12) = { "cdclk1", "none", "sclk_hdmi24m",
+                               "sclk_usbphy0", "xxti", "xusbxti",
+                               "mout_mpll_user_t", "sclk_epll", "sclk_vpll", };
+PNAME(mout_audio2_p4x12) = { "cdclk2", "none", "sclk_hdmi24m",
+                               "sclk_usbphy0", "xxti", "xusbxti",
+                               "mout_mpll_user_t", "sclk_epll", "sclk_vpll", };
+PNAME(aclk_p4412)      = { "mout_mpll_user_t", "sclk_apll", };
+PNAME(mout_user_aclk400_mcuisp_p4x12) = {"fin_pll", "div_aclk400_mcuisp", };
+PNAME(mout_user_aclk200_p4x12) = {"fin_pll", "div_aclk200", };
+PNAME(mout_user_aclk266_gps_p4x12) = {"fin_pll", "div_aclk266_gps", };
+
+/* fixed rate clocks generated outside the soc */
+struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] __initdata = {
+       FRATE(xxti, "xxti", NULL, CLK_IS_ROOT, 0),
+       FRATE(xusbxti, "xusbxti", NULL, CLK_IS_ROOT, 0),
+};
+
+/* fixed rate clocks generated inside the soc */
+struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] __initdata = {
+       FRATE(none, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000),
+       FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000),
+       FRATE(none, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000),
+};
+
+struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] __initdata = {
+       FRATE(none, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000),
+};
+
+/* list of mux clocks supported in all exynos4 soc's */
+struct samsung_mux_clock exynos4_mux_clks[] __initdata = {
+       MUX_F(mout_apll, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
+                       CLK_SET_RATE_PARENT, 0),
+       MUX(none, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1),
+       MUX(none, "mout_mfc1", sclk_evpll_p, SRC_MFC, 4, 1),
+       MUX(none, "mout_mfc", mout_mfc_p, SRC_MFC, 8, 1),
+       MUX_F(mout_g3d1, "mout_g3d1", sclk_evpll_p, SRC_G3D, 4, 1,
+                       CLK_SET_RATE_PARENT, 0),
+       MUX_F(mout_g3d, "mout_g3d", mout_g3d_p, SRC_G3D, 8, 1,
+                       CLK_SET_RATE_PARENT, 0),
+       MUX(none, "mout_spdif", mout_spdif_p, SRC_PERIL1, 8, 2),
+       MUX(none, "mout_onenand1", mout_onenand1_p, SRC_TOP0, 0, 1),
+       MUX_A(sclk_epll, "sclk_epll", mout_epll_p, SRC_TOP0, 4, 1, "sclk_epll"),
+       MUX(none, "mout_onenand", mout_onenand_p, SRC_TOP0, 28, 1),
+};
+
+/* list of mux clocks supported in exynos4210 soc */
+struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {
+       MUX(none, "mout_aclk200", sclk_ampll_p4210, SRC_TOP0, 12, 1),
+       MUX(none, "mout_aclk100", sclk_ampll_p4210, SRC_TOP0, 16, 1),
+       MUX(none, "mout_aclk160", sclk_ampll_p4210, SRC_TOP0, 20, 1),
+       MUX(none, "mout_aclk133", sclk_ampll_p4210, SRC_TOP0, 24, 1),
+       MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP1, 0, 1),
+       MUX(none, "mout_mixer", mout_mixer_p4210, SRC_TV, 4, 1),
+       MUX(none, "mout_dac", mout_dac_p4210, SRC_TV, 8, 1),
+       MUX(none, "mout_g2d0", sclk_ampll_p4210, E4210_SRC_IMAGE, 0, 1),
+       MUX(none, "mout_g2d1", sclk_evpll_p, E4210_SRC_IMAGE, 4, 1),
+       MUX(none, "mout_g2d", mout_g2d_p, E4210_SRC_IMAGE, 8, 1),
+       MUX(none, "mout_fimd1", group1_p4210, E4210_SRC_LCD1, 0, 4),
+       MUX(none, "mout_mipi1", group1_p4210, E4210_SRC_LCD1, 12, 4),
+       MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, SRC_CPU, 8, 1, "sclk_mpll"),
+       MUX_A(mout_core, "mout_core", mout_core_p4210,
+                       SRC_CPU, 16, 1, "mout_core"),
+       MUX_A(sclk_vpll, "sclk_vpll", sclk_vpll_p4210,
+                       SRC_TOP0, 8, 1, "sclk_vpll"),
+       MUX(mout_fimc0, "mout_fimc0", group1_p4210, SRC_CAM, 0, 4),
+       MUX(mout_fimc1, "mout_fimc1", group1_p4210, SRC_CAM, 4, 4),
+       MUX(mout_fimc2, "mout_fimc2", group1_p4210, SRC_CAM, 8, 4),
+       MUX(mout_fimc3, "mout_fimc3", group1_p4210, SRC_CAM, 12, 4),
+       MUX(mout_cam0, "mout_cam0", group1_p4210, SRC_CAM, 16, 4),
+       MUX(mout_cam1, "mout_cam1", group1_p4210, SRC_CAM, 20, 4),
+       MUX(mout_csis0, "mout_csis0", group1_p4210, SRC_CAM, 24, 4),
+       MUX(mout_csis1, "mout_csis1", group1_p4210, SRC_CAM, 28, 4),
+       MUX(none, "mout_mfc0", sclk_ampll_p4210, SRC_MFC, 0, 1),
+       MUX_F(mout_g3d0, "mout_g3d0", sclk_ampll_p4210, SRC_G3D, 0, 1,
+                       CLK_SET_RATE_PARENT, 0),
+       MUX(none, "mout_fimd0", group1_p4210, SRC_LCD0, 0, 4),
+       MUX(none, "mout_mipi0", group1_p4210, SRC_LCD0, 12, 4),
+       MUX(none, "mout_audio0", mout_audio0_p4210, SRC_MAUDIO, 0, 4),
+       MUX(none, "mout_mmc0", group1_p4210, SRC_FSYS, 0, 4),
+       MUX(none, "mout_mmc1", group1_p4210, SRC_FSYS, 4, 4),
+       MUX(none, "mout_mmc2", group1_p4210, SRC_FSYS, 8, 4),
+       MUX(none, "mout_mmc3", group1_p4210, SRC_FSYS, 12, 4),
+       MUX(none, "mout_mmc4", group1_p4210, SRC_FSYS, 16, 4),
+       MUX(none, "mout_sata", sclk_ampll_p4210, SRC_FSYS, 24, 1),
+       MUX(none, "mout_uart0", group1_p4210, SRC_PERIL0, 0, 4),
+       MUX(none, "mout_uart1", group1_p4210, SRC_PERIL0, 4, 4),
+       MUX(none, "mout_uart2", group1_p4210, SRC_PERIL0, 8, 4),
+       MUX(none, "mout_uart3", group1_p4210, SRC_PERIL0, 12, 4),
+       MUX(none, "mout_uart4", group1_p4210, SRC_PERIL0, 16, 4),
+       MUX(none, "mout_audio1", mout_audio1_p4210, SRC_PERIL1, 0, 4),
+       MUX(none, "mout_audio2", mout_audio2_p4210, SRC_PERIL1, 4, 4),
+       MUX(none, "mout_spi0", group1_p4210, SRC_PERIL1, 16, 4),
+       MUX(none, "mout_spi1", group1_p4210, SRC_PERIL1, 20, 4),
+       MUX(none, "mout_spi2", group1_p4210, SRC_PERIL1, 24, 4),
+};
+
+/* list of mux clocks supported in exynos4x12 soc */
+struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
+       MUX(mout_mpll_user_c, "mout_mpll_user_c", mout_mpll_user_p4x12,
+                       SRC_CPU, 24, 1),
+       MUX(none, "mout_aclk266_gps", aclk_p4412, SRC_TOP1, 4, 1),
+       MUX(none, "mout_aclk400_mcuisp", aclk_p4412, SRC_TOP1, 8, 1),
+       MUX(mout_mpll_user_t, "mout_mpll_user_t", mout_mpll_user_p4x12,
+                       SRC_TOP1, 12, 1),
+       MUX(none, "mout_user_aclk266_gps", mout_user_aclk266_gps_p4x12,
+                       SRC_TOP1, 16, 1),
+       MUX(aclk200, "aclk200", mout_user_aclk200_p4x12, SRC_TOP1, 20, 1),
+       MUX(aclk400_mcuisp, "aclk400_mcuisp", mout_user_aclk400_mcuisp_p4x12,
+                       SRC_TOP1, 24, 1),
+       MUX(none, "mout_aclk200", aclk_p4412, SRC_TOP0, 12, 1),
+       MUX(none, "mout_aclk100", aclk_p4412, SRC_TOP0, 16, 1),
+       MUX(none, "mout_aclk160", aclk_p4412, SRC_TOP0, 20, 1),
+       MUX(none, "mout_aclk133", aclk_p4412, SRC_TOP0, 24, 1),
+       MUX(none, "mout_mdnie0", group1_p4x12, SRC_LCD0, 4, 4),
+       MUX(none, "mout_mdnie_pwm0", group1_p4x12, SRC_LCD0, 8, 4),
+       MUX(none, "mout_sata", sclk_ampll_p4x12, SRC_FSYS, 24, 1),
+       MUX(none, "mout_jpeg0", sclk_ampll_p4x12, E4X12_SRC_CAM1, 0, 1),
+       MUX(none, "mout_jpeg1", sclk_evpll_p, E4X12_SRC_CAM1, 4, 1),
+       MUX(none, "mout_jpeg", mout_jpeg_p, E4X12_SRC_CAM1, 8, 1),
+       MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p,
+                       SRC_DMC, 12, 1, "sclk_mpll"),
+       MUX_A(sclk_vpll, "sclk_vpll", mout_vpll_p,
+                       SRC_TOP0, 8, 1, "sclk_vpll"),
+       MUX(mout_core, "mout_core", mout_core_p4x12, SRC_CPU, 16, 1),
+       MUX(mout_fimc0, "mout_fimc0", group1_p4x12, SRC_CAM, 0, 4),
+       MUX(mout_fimc1, "mout_fimc1", group1_p4x12, SRC_CAM, 4, 4),
+       MUX(mout_fimc2, "mout_fimc2", group1_p4x12, SRC_CAM, 8, 4),
+       MUX(mout_fimc3, "mout_fimc3", group1_p4x12, SRC_CAM, 12, 4),
+       MUX(mout_cam0, "mout_cam0", group1_p4x12, SRC_CAM, 16, 4),
+       MUX(mout_cam1, "mout_cam1", group1_p4x12, SRC_CAM, 20, 4),
+       MUX(mout_csis0, "mout_csis0", group1_p4x12, SRC_CAM, 24, 4),
+       MUX(mout_csis1, "mout_csis1", group1_p4x12, SRC_CAM, 28, 4),
+       MUX(none, "mout_mfc0", sclk_ampll_p4x12, SRC_MFC, 0, 1),
+       MUX_F(mout_g3d0, "mout_g3d0", sclk_ampll_p4x12, SRC_G3D, 0, 1,
+                       CLK_SET_RATE_PARENT, 0),
+       MUX(none, "mout_fimd0", group1_p4x12, SRC_LCD0, 0, 4),
+       MUX(none, "mout_mipi0", group1_p4x12, SRC_LCD0, 12, 4),
+       MUX(none, "mout_audio0", mout_audio0_p4x12, SRC_MAUDIO, 0, 4),
+       MUX(none, "mout_mmc0", group1_p4x12, SRC_FSYS, 0, 4),
+       MUX(none, "mout_mmc1", group1_p4x12, SRC_FSYS, 4, 4),
+       MUX(none, "mout_mmc2", group1_p4x12, SRC_FSYS, 8, 4),
+       MUX(none, "mout_mmc3", group1_p4x12, SRC_FSYS, 12, 4),
+       MUX(none, "mout_mmc4", group1_p4x12, SRC_FSYS, 16, 4),
+       MUX(none, "mout_mipihsi", aclk_p4412, SRC_FSYS, 24, 1),
+       MUX(none, "mout_uart0", group1_p4x12, SRC_PERIL0, 0, 4),
+       MUX(none, "mout_uart1", group1_p4x12, SRC_PERIL0, 4, 4),
+       MUX(none, "mout_uart2", group1_p4x12, SRC_PERIL0, 8, 4),
+       MUX(none, "mout_uart3", group1_p4x12, SRC_PERIL0, 12, 4),
+       MUX(none, "mout_uart4", group1_p4x12, SRC_PERIL0, 16, 4),
+       MUX(none, "mout_audio1", mout_audio1_p4x12, SRC_PERIL1, 0, 4),
+       MUX(none, "mout_audio2", mout_audio2_p4x12, SRC_PERIL1, 4, 4),
+       MUX(none, "mout_spi0", group1_p4x12, SRC_PERIL1, 16, 4),
+       MUX(none, "mout_spi1", group1_p4x12, SRC_PERIL1, 20, 4),
+       MUX(none, "mout_spi2", group1_p4x12, SRC_PERIL1, 24, 4),
+       MUX(none, "mout_pwm_isp", group1_p4x12, E4X12_SRC_ISP, 0, 4),
+       MUX(none, "mout_spi0_isp", group1_p4x12, E4X12_SRC_ISP, 4, 4),
+       MUX(none, "mout_spi1_isp", group1_p4x12, E4X12_SRC_ISP, 8, 4),
+       MUX(none, "mout_uart_isp", group1_p4x12, E4X12_SRC_ISP, 12, 4),
+};
+
+/* list of divider clocks supported in all exynos4 soc's */
+struct samsung_div_clock exynos4_div_clks[] __initdata = {
+       DIV(none, "div_core", "mout_core", DIV_CPU0, 0, 3),
+       DIV(none, "div_core2", "div_core", DIV_CPU0, 28, 3),
+       DIV(none, "div_fimc0", "mout_fimc0", DIV_CAM, 0, 4),
+       DIV(none, "div_fimc1", "mout_fimc1", DIV_CAM, 4, 4),
+       DIV(none, "div_fimc2", "mout_fimc2", DIV_CAM, 8, 4),
+       DIV(none, "div_fimc3", "mout_fimc3", DIV_CAM, 12, 4),
+       DIV(none, "div_cam0", "mout_cam0", DIV_CAM, 16, 4),
+       DIV(none, "div_cam1", "mout_cam1", DIV_CAM, 20, 4),
+       DIV(none, "div_csis0", "mout_csis0", DIV_CAM, 24, 4),
+       DIV(none, "div_csis1", "mout_csis1", DIV_CAM, 28, 4),
+       DIV(sclk_mfc, "sclk_mfc", "mout_mfc", DIV_MFC, 0, 4),
+       DIV_F(none, "div_g3d", "mout_g3d", DIV_G3D, 0, 4,
+                       CLK_SET_RATE_PARENT, 0),
+       DIV(none, "div_fimd0", "mout_fimd0", DIV_LCD0, 0, 4),
+       DIV(none, "div_mipi0", "mout_mipi0", DIV_LCD0, 16, 4),
+       DIV(none, "div_audio0", "mout_audio0", DIV_MAUDIO, 0, 4),
+       DIV(sclk_pcm0, "sclk_pcm0", "sclk_audio0", DIV_MAUDIO, 4, 8),
+       DIV(none, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4),
+       DIV(none, "div_mmc1", "mout_mmc1", DIV_FSYS1, 16, 4),
+       DIV(none, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4),
+       DIV(none, "div_mmc3", "mout_mmc3", DIV_FSYS2, 16, 4),
+       DIV(sclk_pixel, "sclk_pixel", "sclk_vpll", DIV_TV, 0, 4),
+       DIV(aclk100, "aclk100", "mout_aclk100", DIV_TOP, 4, 4),
+       DIV(aclk160, "aclk160", "mout_aclk160", DIV_TOP, 8, 3),
+       DIV(aclk133, "aclk133", "mout_aclk133", DIV_TOP, 12, 3),
+       DIV(none, "div_onenand", "mout_onenand1", DIV_TOP, 16, 3),
+       DIV(sclk_slimbus, "sclk_slimbus", "sclk_epll", DIV_PERIL3, 4, 4),
+       DIV(sclk_pcm1, "sclk_pcm1", "sclk_audio1", DIV_PERIL4, 4, 8),
+       DIV(sclk_pcm2, "sclk_pcm2", "sclk_audio2", DIV_PERIL4, 20, 8),
+       DIV(sclk_i2s1, "sclk_i2s1", "sclk_audio1", DIV_PERIL5, 0, 6),
+       DIV(sclk_i2s2, "sclk_i2s2", "sclk_audio2", DIV_PERIL5, 8, 6),
+       DIV(none, "div_mmc4", "mout_mmc4", DIV_FSYS3, 0, 4),
+       DIV(none, "div_mmc_pre4", "div_mmc4", DIV_FSYS3, 8, 8),
+       DIV(none, "div_uart0", "mout_uart0", DIV_PERIL0, 0, 4),
+       DIV(none, "div_uart1", "mout_uart1", DIV_PERIL0, 4, 4),
+       DIV(none, "div_uart2", "mout_uart2", DIV_PERIL0, 8, 4),
+       DIV(none, "div_uart3", "mout_uart3", DIV_PERIL0, 12, 4),
+       DIV(none, "div_uart4", "mout_uart4", DIV_PERIL0, 16, 4),
+       DIV(none, "div_spi0", "mout_spi0", DIV_PERIL1, 0, 4),
+       DIV(none, "div_spi_pre0", "div_spi0", DIV_PERIL1, 8, 8),
+       DIV(none, "div_spi1", "mout_spi1", DIV_PERIL1, 16, 4),
+       DIV(none, "div_spi_pre1", "div_spi1", DIV_PERIL1, 24, 8),
+       DIV(none, "div_spi2", "mout_spi2", DIV_PERIL2, 0, 4),
+       DIV(none, "div_spi_pre2", "div_spi2", DIV_PERIL2, 8, 8),
+       DIV(none, "div_audio1", "mout_audio1", DIV_PERIL4, 0, 4),
+       DIV(none, "div_audio2", "mout_audio2", DIV_PERIL4, 16, 4),
+       DIV_A(arm_clk, "arm_clk", "div_core2", DIV_CPU0, 28, 3, "arm_clk"),
+       DIV_A(sclk_apll, "sclk_apll", "mout_apll",
+                       DIV_CPU0, 24, 3, "sclk_apll"),
+       DIV_F(none, "div_mipi_pre0", "div_mipi0", DIV_LCD0, 20, 4,
+                       CLK_SET_RATE_PARENT, 0),
+       DIV_F(none, "div_mmc_pre0", "div_mmc0", DIV_FSYS1, 8, 8,
+                       CLK_SET_RATE_PARENT, 0),
+       DIV_F(none, "div_mmc_pre1", "div_mmc1", DIV_FSYS1, 24, 8,
+                       CLK_SET_RATE_PARENT, 0),
+       DIV_F(none, "div_mmc_pre2", "div_mmc2", DIV_FSYS2, 8, 8,
+                       CLK_SET_RATE_PARENT, 0),
+       DIV_F(none, "div_mmc_pre3", "div_mmc3", DIV_FSYS2, 24, 8,
+                       CLK_SET_RATE_PARENT, 0),
+};
+
+/* list of divider clocks supported in exynos4210 soc */
+struct samsung_div_clock exynos4210_div_clks[] __initdata = {
+       DIV(aclk200, "aclk200", "mout_aclk200", DIV_TOP, 0, 3),
+       DIV(none, "div_g2d", "mout_g2d", DIV_IMAGE, 0, 4),
+       DIV(none, "div_fimd1", "mout_fimd1", E4210_DIV_LCD1, 0, 4),
+       DIV(none, "div_mipi1", "mout_mipi1", E4210_DIV_LCD1, 16, 4),
+       DIV(none, "div_sata", "mout_sata", DIV_FSYS0, 20, 4),
+       DIV_F(none, "div_mipi_pre1", "div_mipi1", E4210_DIV_LCD1, 20, 4,
+                       CLK_SET_RATE_PARENT, 0),
+};
+
+/* list of divider clocks supported in exynos4x12 soc */
+struct samsung_div_clock exynos4x12_div_clks[] __initdata = {
+       DIV(none, "div_mdnie0", "mout_mdnie0", DIV_LCD0, 4, 4),
+       DIV(none, "div_mdnie_pwm0", "mout_mdnie_pwm0", DIV_LCD0, 8, 4),
+       DIV(none, "div_mdnie_pwm_pre0", "div_mdnie_pwm0", DIV_LCD0, 12, 4),
+       DIV(none, "div_mipihsi", "mout_mipihsi", DIV_FSYS0, 20, 4),
+       DIV(none, "div_jpeg", "mout_jpeg", E4X12_DIV_CAM1, 0, 4),
+       DIV(div_aclk200, "div_aclk200", "mout_aclk200", DIV_TOP, 0, 3),
+       DIV(none, "div_aclk266_gps", "mout_aclk266_gps", DIV_TOP, 20, 3),
+       DIV(div_aclk400_mcuisp, "div_aclk400_mcuisp", "mout_aclk400_mcuisp",
+                                               DIV_TOP, 24, 3),
+       DIV(none, "div_pwm_isp", "mout_pwm_isp", E4X12_DIV_ISP, 0, 4),
+       DIV(none, "div_spi0_isp", "mout_spi0_isp", E4X12_DIV_ISP, 4, 4),
+       DIV(none, "div_spi0_isp_pre", "div_spi0_isp", E4X12_DIV_ISP, 8, 8),
+       DIV(none, "div_spi1_isp", "mout_spi1_isp", E4X12_DIV_ISP, 16, 4),
+       DIV(none, "div_spi1_isp_pre", "div_spi1_isp", E4X12_DIV_ISP, 20, 8),
+       DIV(none, "div_uart_isp", "mout_uart_isp", E4X12_DIV_ISP, 28, 4),
+       DIV(div_isp0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3),
+       DIV(div_isp1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3),
+       DIV(none, "div_mpwm", "div_isp1", E4X12_DIV_ISP1, 0, 3),
+       DIV(div_mcuisp0, "div_mcuisp0", "aclk400_mcuisp", E4X12_DIV_ISP1, 4, 3),
+       DIV(div_mcuisp1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1, 8, 3),
+};
+
+/* list of gate clocks supported in all exynos4 soc's */
+struct samsung_gate_clock exynos4_gate_clks[] __initdata = {
+       /*
+        * After all Exynos4 based platforms are migrated to use device tree,
+        * the device name and clock alias names specified below for some
+        * of the clocks can be removed.
+        */
+       GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi", SRC_MASK_TV, 0, 0, 0),
+       GATE(sclk_spdif, "sclk_spdif", "mout_spdif", SRC_MASK_PERIL1, 8, 0, 0),
+       GATE(jpeg, "jpeg", "aclk160", GATE_IP_CAM, 6, 0, 0),
+       GATE(mie0, "mie0", "aclk160", GATE_IP_LCD0, 1, 0, 0),
+       GATE(dsim0, "dsim0", "aclk160", GATE_IP_LCD0, 3, 0, 0),
+       GATE(fimd1, "fimd1", "aclk160", E4210_GATE_IP_LCD1, 0, 0, 0),
+       GATE(mie1, "mie1", "aclk160", E4210_GATE_IP_LCD1, 1, 0, 0),
+       GATE(dsim1, "dsim1", "aclk160", E4210_GATE_IP_LCD1, 3, 0, 0),
+       GATE(smmu_fimd1, "smmu_fimd1", "aclk160", E4210_GATE_IP_LCD1, 4, 0, 0),
+       GATE(tsi, "tsi", "aclk133", GATE_IP_FSYS, 4, 0, 0),
+       GATE(sromc, "sromc", "aclk133", GATE_IP_FSYS, 11, 0, 0),
+       GATE(sclk_g3d, "sclk_g3d", "div_g3d", GATE_IP_G3D, 0,
+                       CLK_SET_RATE_PARENT, 0),
+       GATE(usb_device, "usb_device", "aclk133", GATE_IP_FSYS, 13, 0, 0),
+       GATE(onenand, "onenand", "aclk133", GATE_IP_FSYS, 15, 0, 0),
+       GATE(nfcon, "nfcon", "aclk133", GATE_IP_FSYS, 16, 0, 0),
+       GATE(gps, "gps", "aclk133", GATE_IP_GPS, 0, 0, 0),
+       GATE(smmu_gps, "smmu_gps", "aclk133", GATE_IP_GPS, 1, 0, 0),
+       GATE(slimbus, "slimbus", "aclk100", GATE_IP_PERIL, 25, 0, 0),
+       GATE(sclk_cam0, "sclk_cam0", "div_cam0", GATE_SCLK_CAM, 4,
+                       CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_cam1, "sclk_cam1", "div_cam1", GATE_SCLK_CAM, 5,
+                       CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_mipi0, "sclk_mipi0", "div_mipi_pre0",
+                       SRC_MASK_LCD0, 12, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_audio0, "sclk_audio0", "div_audio0", SRC_MASK_MAUDIO, 0,
+                       CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_audio1, "sclk_audio1", "div_audio1", SRC_MASK_PERIL1, 0,
+                       CLK_SET_RATE_PARENT, 0),
+       GATE_D(vp, "s5p-mixer", "vp", "aclk160", GATE_IP_TV, 0, 0, 0),
+       GATE_D(mixer, "s5p-mixer", "mixer", "aclk160", GATE_IP_TV, 1, 0, 0),
+       GATE_D(hdmi, "exynos4-hdmi", "hdmi", "aclk160", GATE_IP_TV, 3, 0, 0),
+       GATE_A(pwm, "pwm", "aclk100", GATE_IP_PERIL, 24, 0, 0, "timers"),
+       GATE_A(sdmmc4, "sdmmc4", "aclk133", GATE_IP_FSYS, 9, 0, 0, "biu"),
+       GATE_A(usb_host, "usb_host", "aclk133",
+                       GATE_IP_FSYS, 12, 0, 0, "usbhost"),
+       GATE_DA(sclk_fimc0, "exynos4-fimc.0", "sclk_fimc0", "div_fimc0",
+                       SRC_MASK_CAM, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
+       GATE_DA(sclk_fimc1, "exynos4-fimc.1", "sclk_fimc1", "div_fimc1",
+                       SRC_MASK_CAM, 4, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
+       GATE_DA(sclk_fimc2, "exynos4-fimc.2", "sclk_fimc2", "div_fimc2",
+                       SRC_MASK_CAM, 8, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
+       GATE_DA(sclk_fimc3, "exynos4-fimc.3", "sclk_fimc3", "div_fimc3",
+                       SRC_MASK_CAM, 12, CLK_SET_RATE_PARENT, 0, "sclk_fimc"),
+       GATE_DA(sclk_csis0, "s5p-mipi-csis.0", "sclk_csis0", "div_csis0",
+                       SRC_MASK_CAM, 24, CLK_SET_RATE_PARENT, 0, "sclk_csis"),
+       GATE_DA(sclk_csis1, "s5p-mipi-csis.1", "sclk_csis1", "div_csis1",
+                       SRC_MASK_CAM, 28, CLK_SET_RATE_PARENT, 0, "sclk_csis"),
+       GATE_DA(sclk_fimd0, "exynos4-fb.0", "sclk_fimd0", "div_fimd0",
+                       SRC_MASK_LCD0, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"),
+       GATE_DA(sclk_mmc0, "exynos4-sdhci.0", "sclk_mmc0", "div_mmc_pre0",
+                       SRC_MASK_FSYS, 0, CLK_SET_RATE_PARENT, 0,
+                       "mmc_busclk.2"),
+       GATE_DA(sclk_mmc1, "exynos4-sdhci.1", "sclk_mmc1", "div_mmc_pre1",
+                       SRC_MASK_FSYS, 4, CLK_SET_RATE_PARENT, 0,
+                       "mmc_busclk.2"),
+       GATE_DA(sclk_mmc2, "exynos4-sdhci.2", "sclk_mmc2", "div_mmc_pre2",
+                       SRC_MASK_FSYS, 8, CLK_SET_RATE_PARENT, 0,
+                       "mmc_busclk.2"),
+       GATE_DA(sclk_mmc3, "exynos4-sdhci.3", "sclk_mmc3", "div_mmc_pre3",
+                       SRC_MASK_FSYS, 12, CLK_SET_RATE_PARENT, 0,
+                       "mmc_busclk.2"),
+       GATE_DA(sclk_mmc4, NULL, "sclk_mmc4", "div_mmc_pre4",
+                       SRC_MASK_FSYS, 16, CLK_SET_RATE_PARENT, 0, "ciu"),
+       GATE_DA(sclk_uart0, "exynos4210-uart.0", "uclk0", "div_uart0",
+                       SRC_MASK_PERIL0, 0, CLK_SET_RATE_PARENT,
+                       0, "clk_uart_baud0"),
+       GATE_DA(sclk_uart1, "exynos4210-uart.1", "uclk1", "div_uart1",
+                       SRC_MASK_PERIL0, 4, CLK_SET_RATE_PARENT,
+                       0, "clk_uart_baud0"),
+       GATE_DA(sclk_uart2, "exynos4210-uart.2", "uclk2", "div_uart2",
+                       SRC_MASK_PERIL0, 8, CLK_SET_RATE_PARENT,
+                       0, "clk_uart_baud0"),
+       GATE_DA(sclk_uart3, "exynos4210-uart.3", "uclk3", "div_uart3",
+                       SRC_MASK_PERIL0, 12, CLK_SET_RATE_PARENT,
+                       0, "clk_uart_baud0"),
+       GATE_DA(sclk_uart4, "exynos4210-uart.4", "uclk4", "div_uart4",
+                       SRC_MASK_PERIL0, 16, CLK_SET_RATE_PARENT,
+                       0, "clk_uart_baud0"),
+       GATE(sclk_audio2, "sclk_audio2", "div_audio2", SRC_MASK_PERIL1, 4,
+                       CLK_SET_RATE_PARENT, 0),
+       GATE_DA(sclk_spi0, "exynos4210-spi.0", "sclk_spi0", "div_spi_pre0",
+                       SRC_MASK_PERIL1, 16, CLK_SET_RATE_PARENT,
+                       0, "spi_busclk0"),
+       GATE_DA(sclk_spi1, "exynos4210-spi.1", "sclk_spi1", "div_spi_pre1",
+                       SRC_MASK_PERIL1, 20, CLK_SET_RATE_PARENT,
+                       0, "spi_busclk0"),
+       GATE_DA(sclk_spi2, "exynos4210-spi.2", "sclk_spi2", "div_spi_pre2",
+                       SRC_MASK_PERIL1, 24, CLK_SET_RATE_PARENT,
+                       0, "spi_busclk0"),
+       GATE_DA(fimc0, "exynos4-fimc.0", "fimc0", "aclk160",
+                       GATE_IP_CAM, 0, 0, 0, "fimc"),
+       GATE_DA(fimc1, "exynos4-fimc.1", "fimc1", "aclk160",
+                       GATE_IP_CAM, 1, 0, 0, "fimc"),
+       GATE_DA(fimc2, "exynos4-fimc.2", "fimc2", "aclk160",
+                       GATE_IP_CAM, 2, 0, 0, "fimc"),
+       GATE_DA(fimc3, "exynos4-fimc.3", "fimc3", "aclk160",
+                       GATE_IP_CAM, 3, 0, 0, "fimc"),
+       GATE_DA(csis0, "s5p-mipi-csis.0", "csis0", "aclk160",
+                       GATE_IP_CAM, 4, 0, 0, "fimc"),
+       GATE_DA(csis1, "s5p-mipi-csis.1", "csis1", "aclk160",
+                       GATE_IP_CAM, 5, 0, 0, "fimc"),
+       GATE_DA(smmu_fimc0, "exynos-sysmmu.5", "smmu_fimc0", "aclk160",
+                       GATE_IP_CAM, 7, 0, 0, "sysmmu"),
+       GATE_DA(smmu_fimc1, "exynos-sysmmu.6", "smmu_fimc1", "aclk160",
+                       GATE_IP_CAM, 8, 0, 0, "sysmmu"),
+       GATE_DA(smmu_fimc2, "exynos-sysmmu.7", "smmu_fimc2", "aclk160",
+                       GATE_IP_CAM, 9, 0, 0, "sysmmu"),
+       GATE_DA(smmu_fimc3, "exynos-sysmmu.8", "smmu_fimc3", "aclk160",
+                       GATE_IP_CAM, 10, 0, 0, "sysmmu"),
+       GATE_DA(smmu_jpeg, "exynos-sysmmu.3", "smmu_jpeg", "aclk160",
+                       GATE_IP_CAM, 11, 0, 0, "sysmmu"),
+       GATE(pixelasyncm0, "pxl_async0", "aclk160", GATE_IP_CAM, 17, 0, 0),
+       GATE(pixelasyncm1, "pxl_async1", "aclk160", GATE_IP_CAM, 18, 0, 0),
+       GATE_DA(smmu_tv, "exynos-sysmmu.2", "smmu_tv", "aclk160",
+                       GATE_IP_TV, 4, 0, 0, "sysmmu"),
+       GATE_DA(mfc, "s5p-mfc", "mfc", "aclk100", GATE_IP_MFC, 0, 0, 0, "mfc"),
+       GATE_DA(smmu_mfcl, "exynos-sysmmu.0", "smmu_mfcl", "aclk100",
+                       GATE_IP_MFC, 1, 0, 0, "sysmmu"),
+       GATE_DA(smmu_mfcr, "exynos-sysmmu.1", "smmu_mfcr", "aclk100",
+                       GATE_IP_MFC, 2, 0, 0, "sysmmu"),
+       GATE_DA(fimd0, "exynos4-fb.0", "fimd0", "aclk160",
+                       GATE_IP_LCD0, 0, 0, 0, "fimd"),
+       GATE_DA(smmu_fimd0, "exynos-sysmmu.10", "smmu_fimd0", "aclk160",
+                       GATE_IP_LCD0, 4, 0, 0, "sysmmu"),
+       GATE_DA(pdma0, "dma-pl330.0", "pdma0", "aclk133",
+                       GATE_IP_FSYS, 0, 0, 0, "dma"),
+       GATE_DA(pdma1, "dma-pl330.1", "pdma1", "aclk133",
+                       GATE_IP_FSYS, 1, 0, 0, "dma"),
+       GATE_DA(sdmmc0, "exynos4-sdhci.0", "sdmmc0", "aclk133",
+                       GATE_IP_FSYS, 5, 0, 0, "hsmmc"),
+       GATE_DA(sdmmc1, "exynos4-sdhci.1", "sdmmc1", "aclk133",
+                       GATE_IP_FSYS, 6, 0, 0, "hsmmc"),
+       GATE_DA(sdmmc2, "exynos4-sdhci.2", "sdmmc2", "aclk133",
+                       GATE_IP_FSYS, 7, 0, 0, "hsmmc"),
+       GATE_DA(sdmmc3, "exynos4-sdhci.3", "sdmmc3", "aclk133",
+                       GATE_IP_FSYS, 8, 0, 0, "hsmmc"),
+       GATE_DA(uart0, "exynos4210-uart.0", "uart0", "aclk100",
+                       GATE_IP_PERIL, 0, 0, 0, "uart"),
+       GATE_DA(uart1, "exynos4210-uart.1", "uart1", "aclk100",
+                       GATE_IP_PERIL, 1, 0, 0, "uart"),
+       GATE_DA(uart2, "exynos4210-uart.2", "uart2", "aclk100",
+                       GATE_IP_PERIL, 2, 0, 0, "uart"),
+       GATE_DA(uart3, "exynos4210-uart.3", "uart3", "aclk100",
+                       GATE_IP_PERIL, 3, 0, 0, "uart"),
+       GATE_DA(uart4, "exynos4210-uart.4", "uart4", "aclk100",
+                       GATE_IP_PERIL, 4, 0, 0, "uart"),
+       GATE_DA(i2c0, "s3c2440-i2c.0", "i2c0", "aclk100",
+                       GATE_IP_PERIL, 6, 0, 0, "i2c"),
+       GATE_DA(i2c1, "s3c2440-i2c.1", "i2c1", "aclk100",
+                       GATE_IP_PERIL, 7, 0, 0, "i2c"),
+       GATE_DA(i2c2, "s3c2440-i2c.2", "i2c2", "aclk100",
+                       GATE_IP_PERIL, 8, 0, 0, "i2c"),
+       GATE_DA(i2c3, "s3c2440-i2c.3", "i2c3", "aclk100",
+                       GATE_IP_PERIL, 9, 0, 0, "i2c"),
+       GATE_DA(i2c4, "s3c2440-i2c.4", "i2c4", "aclk100",
+                       GATE_IP_PERIL, 10, 0, 0, "i2c"),
+       GATE_DA(i2c5, "s3c2440-i2c.5", "i2c5", "aclk100",
+                       GATE_IP_PERIL, 11, 0, 0, "i2c"),
+       GATE_DA(i2c6, "s3c2440-i2c.6", "i2c6", "aclk100",
+                       GATE_IP_PERIL, 12, 0, 0, "i2c"),
+       GATE_DA(i2c7, "s3c2440-i2c.7", "i2c7", "aclk100",
+                       GATE_IP_PERIL, 13, 0, 0, "i2c"),
+       GATE_DA(i2c_hdmi, "s3c2440-hdmiphy-i2c", "i2c-hdmi", "aclk100",
+                       GATE_IP_PERIL, 14, 0, 0, "i2c"),
+       GATE_DA(spi0, "exynos4210-spi.0", "spi0", "aclk100",
+                       GATE_IP_PERIL, 16, 0, 0, "spi"),
+       GATE_DA(spi1, "exynos4210-spi.1", "spi1", "aclk100",
+                       GATE_IP_PERIL, 17, 0, 0, "spi"),
+       GATE_DA(spi2, "exynos4210-spi.2", "spi2", "aclk100",
+                       GATE_IP_PERIL, 18, 0, 0, "spi"),
+       GATE_DA(i2s1, "samsung-i2s.1", "i2s1", "aclk100",
+                       GATE_IP_PERIL, 20, 0, 0, "iis"),
+       GATE_DA(i2s2, "samsung-i2s.2", "i2s2", "aclk100",
+                       GATE_IP_PERIL, 21, 0, 0, "iis"),
+       GATE_DA(pcm1, "samsung-pcm.1", "pcm1", "aclk100",
+                       GATE_IP_PERIL, 22, 0, 0, "pcm"),
+       GATE_DA(pcm2, "samsung-pcm.2", "pcm2", "aclk100",
+                       GATE_IP_PERIL, 23, 0, 0, "pcm"),
+       GATE_DA(spdif, "samsung-spdif", "spdif", "aclk100",
+                       GATE_IP_PERIL, 26, 0, 0, "spdif"),
+       GATE_DA(ac97, "samsung-ac97", "ac97", "aclk100",
+                       GATE_IP_PERIL, 27, 0, 0, "ac97"),
+};
+
+/* list of gate clocks supported in exynos4210 soc */
+struct samsung_gate_clock exynos4210_gate_clks[] __initdata = {
+       GATE(tvenc, "tvenc", "aclk160", GATE_IP_TV, 2, 0, 0),
+       GATE(g2d, "g2d", "aclk200", E4210_GATE_IP_IMAGE, 0, 0, 0),
+       GATE(rotator, "rotator", "aclk200", E4210_GATE_IP_IMAGE, 1, 0, 0),
+       GATE(mdma, "mdma", "aclk200", E4210_GATE_IP_IMAGE, 2, 0, 0),
+       GATE(smmu_g2d, "smmu_g2d", "aclk200", E4210_GATE_IP_IMAGE, 3, 0, 0),
+       GATE(smmu_mdma, "smmu_mdma", "aclk200", E4210_GATE_IP_IMAGE, 5, 0, 0),
+       GATE(pcie_phy, "pcie_phy", "aclk133", GATE_IP_FSYS, 2, 0, 0),
+       GATE(sata_phy, "sata_phy", "aclk133", GATE_IP_FSYS, 3, 0, 0),
+       GATE(sata, "sata", "aclk133", GATE_IP_FSYS, 10, 0, 0),
+       GATE(pcie, "pcie", "aclk133", GATE_IP_FSYS, 14, 0, 0),
+       GATE(smmu_pcie, "smmu_pcie", "aclk133", GATE_IP_FSYS, 18, 0, 0),
+       GATE(modemif, "modemif", "aclk100", GATE_IP_PERIL, 28, 0, 0),
+       GATE(chipid, "chipid", "aclk100", E4210_GATE_IP_PERIR, 0, 0, 0),
+       GATE(sysreg, "sysreg", "aclk100", E4210_GATE_IP_PERIR, 0, 0, 0),
+       GATE(hdmi_cec, "hdmi_cec", "aclk100", E4210_GATE_IP_PERIR, 11, 0, 0),
+       GATE(smmu_rotator, "smmu_rotator", "aclk200",
+                       E4210_GATE_IP_IMAGE, 4, 0, 0),
+       GATE(sclk_mipi1, "sclk_mipi1", "div_mipi_pre1",
+                       E4210_SRC_MASK_LCD1, 12, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_sata, "sclk_sata", "div_sata",
+                       SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_mixer, "sclk_mixer", "mout_mixer", SRC_MASK_TV, 4, 0, 0),
+       GATE(sclk_dac, "sclk_dac", "mout_dac", SRC_MASK_TV, 8, 0, 0),
+       GATE_A(tsadc, "tsadc", "aclk100", GATE_IP_PERIL, 15, 0, 0, "adc"),
+       GATE_A(mct, "mct", "aclk100", E4210_GATE_IP_PERIR, 13, 0, 0, "mct"),
+       GATE_A(wdt, "watchdog", "aclk100", E4210_GATE_IP_PERIR, 14, 0, 0, "watchdog"),
+       GATE_A(rtc, "rtc", "aclk100", E4210_GATE_IP_PERIR, 15, 0, 0, "rtc"),
+       GATE_A(keyif, "keyif", "aclk100", E4210_GATE_IP_PERIR, 16, 0, 0, "keypad"),
+       GATE_DA(sclk_fimd1, "exynos4-fb.1", "sclk_fimd1", "div_fimd1",
+                       E4210_SRC_MASK_LCD1, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"),
+};
+
+/* list of gate clocks supported in exynos4x12 soc */
+struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
+       GATE(audss, "audss", "sclk_epll", E4X12_GATE_IP_MAUDIO, 0, 0, 0),
+       GATE(mdnie0, "mdnie0", "aclk160", GATE_IP_LCD0, 2, 0, 0),
+       GATE(rotator, "rotator", "aclk200", E4X12_GATE_IP_IMAGE, 1, 0, 0),
+       GATE(mdma2, "mdma2", "aclk200", E4X12_GATE_IP_IMAGE, 2, 0, 0),
+       GATE(smmu_mdma, "smmu_mdma", "aclk200", E4X12_GATE_IP_IMAGE, 5, 0, 0),
+       GATE(mipi_hsi, "mipi_hsi", "aclk133", GATE_IP_FSYS, 10, 0, 0),
+       GATE(chipid, "chipid", "aclk100", E4X12_GATE_IP_PERIR, 0, 0, 0),
+       GATE(sysreg, "sysreg", "aclk100", E4X12_GATE_IP_PERIR, 1, 0, 0),
+       GATE(hdmi_cec, "hdmi_cec", "aclk100", E4X12_GATE_IP_PERIR, 11, 0, 0),
+       GATE(sclk_mdnie0, "sclk_mdnie0", "div_mdnie0",
+                       SRC_MASK_LCD0, 4, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_mdnie_pwm0, "sclk_mdnie_pwm0", "div_mdnie_pwm_pre0",
+                       SRC_MASK_LCD0, 8, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_mipihsi, "sclk_mipihsi", "div_mipihsi",
+                       SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0),
+       GATE(smmu_rotator, "smmu_rotator", "aclk200",
+                       E4X12_GATE_IP_IMAGE, 4, 0, 0),
+       GATE_A(mct, "mct", "aclk100", E4X12_GATE_IP_PERIR, 13, 0, 0, "mct"),
+       GATE_A(rtc, "rtc", "aclk100", E4X12_GATE_IP_PERIR, 15, 0, 0, "rtc"),
+       GATE_A(keyif, "keyif", "aclk100",
+                       E4X12_GATE_IP_PERIR, 16, 0, 0, "keypad"),
+       GATE(sclk_pwm_isp, "sclk_pwm_isp", "div_pwm_isp",
+                       E4X12_SRC_MASK_ISP, 0, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_spi0_isp, "sclk_spi0_isp", "div_spi0_isp_pre",
+                       E4X12_SRC_MASK_ISP, 4, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_spi1_isp, "sclk_spi1_isp", "div_spi1_isp_pre",
+                       E4X12_SRC_MASK_ISP, 8, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_uart_isp, "sclk_uart_isp", "div_uart_isp",
+                       E4X12_SRC_MASK_ISP, 12, CLK_SET_RATE_PARENT, 0),
+       GATE(pwm_isp_sclk, "pwm_isp_sclk", "sclk_pwm_isp",
+                       E4X12_GATE_IP_ISP, 0, 0, 0),
+       GATE(spi0_isp_sclk, "spi0_isp_sclk", "sclk_spi0_isp",
+                       E4X12_GATE_IP_ISP, 1, 0, 0),
+       GATE(spi1_isp_sclk, "spi1_isp_sclk", "sclk_spi1_isp",
+                       E4X12_GATE_IP_ISP, 2, 0, 0),
+       GATE(uart_isp_sclk, "uart_isp_sclk", "sclk_uart_isp",
+                       E4X12_GATE_IP_ISP, 3, 0, 0),
+       GATE_A(wdt, "watchdog", "aclk100",
+                       E4X12_GATE_IP_PERIR, 14, 0, 0, "watchdog"),
+       GATE_DA(pcm0, "samsung-pcm.0", "pcm0", "aclk100",
+                       E4X12_GATE_IP_MAUDIO, 2, 0, 0, "pcm"),
+       GATE_DA(i2s0, "samsung-i2s.0", "i2s0", "aclk100",
+                       E4X12_GATE_IP_MAUDIO, 3, 0, 0, "iis"),
+       GATE(fimc_isp, "isp", "aclk200", E4X12_GATE_ISP0, 0,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(fimc_drc, "drc", "aclk200", E4X12_GATE_ISP0, 1,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(fimc_fd, "fd", "aclk200", E4X12_GATE_ISP0, 2,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(fimc_lite0, "lite0", "aclk200", E4X12_GATE_ISP0, 3,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(fimc_lite1, "lite1", "aclk200", E4X12_GATE_ISP0, 4,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(mcuisp, "mcuisp", "aclk200", E4X12_GATE_ISP0, 5,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(gicisp, "gicisp", "aclk200", E4X12_GATE_ISP0, 7,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(smmu_isp, "smmu_isp", "aclk200", E4X12_GATE_ISP0, 8,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(smmu_drc, "smmu_drc", "aclk200", E4X12_GATE_ISP0, 9,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(smmu_fd, "smmu_fd", "aclk200", E4X12_GATE_ISP0, 10,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(smmu_lite0, "smmu_lite0", "aclk200", E4X12_GATE_ISP0, 11,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(smmu_lite1, "smmu_lite1", "aclk200", E4X12_GATE_ISP0, 12,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(ppmuispmx, "ppmuispmx", "aclk200", E4X12_GATE_ISP0, 20,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(ppmuispx, "ppmuispx", "aclk200", E4X12_GATE_ISP0, 21,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(mcuctl_isp, "mcuctl_isp", "aclk200", E4X12_GATE_ISP0, 23,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(mpwm_isp, "mpwm_isp", "aclk200", E4X12_GATE_ISP0, 24,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(i2c0_isp, "i2c0_isp", "aclk200", E4X12_GATE_ISP0, 25,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(i2c1_isp, "i2c1_isp", "aclk200", E4X12_GATE_ISP0, 26,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(mtcadc_isp, "mtcadc_isp", "aclk200", E4X12_GATE_ISP0, 27,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(pwm_isp, "pwm_isp", "aclk200", E4X12_GATE_ISP0, 28,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(wdt_isp, "wdt_isp", "aclk200", E4X12_GATE_ISP0, 30,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(uart_isp, "uart_isp", "aclk200", E4X12_GATE_ISP0, 31,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(asyncaxim, "asyncaxim", "aclk200", E4X12_GATE_ISP1, 0,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(smmu_ispcx, "smmu_ispcx", "aclk200", E4X12_GATE_ISP1, 4,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(spi0_isp, "spi0_isp", "aclk200", E4X12_GATE_ISP1, 12,
+                       CLK_IGNORE_UNUSED, 0),
+       GATE(spi1_isp, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13,
+                       CLK_IGNORE_UNUSED, 0),
+};
+
+#ifdef CONFIG_OF
+static struct of_device_id exynos4_clk_ids[] __initdata = {
+       { .compatible = "samsung,exynos4210-clock",
+                       .data = (void *)EXYNOS4210, },
+       { .compatible = "samsung,exynos4412-clock",
+                       .data = (void *)EXYNOS4X12, },
+       { },
+};
+#endif
+
+/*
+ * The parent of the fin_pll clock is selected by the XOM[0] bit. This bit
+ * resides in chipid register space, outside of the clock controller memory
+ * mapped space. So to determine the parent of fin_pll clock, the chipid
+ * controller is first remapped and the value of XOM[0] bit is read to
+ * determine the parent clock.
+ */
+static void __init exynos4_clk_register_finpll(void)
+{
+       struct samsung_fixed_rate_clock fclk;
+       struct device_node *np;
+       struct clk *clk;
+       void __iomem *chipid_base = S5P_VA_CHIPID;
+       unsigned long xom, finpll_f = 24000000;
+       char *parent_name;
+
+       np = of_find_compatible_node(NULL, NULL, "samsung,exynos4210-chipid");
+       if (np)
+               chipid_base = of_iomap(np, 0);
+
+       if (chipid_base) {
+               xom = readl(chipid_base + 8);
+               parent_name = xom & 1 ? "xusbxti" : "xxti";
+               clk = clk_get(NULL, parent_name);
+               if (IS_ERR(clk)) {
+                       pr_err("%s: failed to lookup parent clock %s, assuming "
+                               "fin_pll clock frequency is 24MHz\n", __func__,
+                               parent_name);
+               } else {
+                       finpll_f = clk_get_rate(clk);
+               }
+       } else {
+               pr_err("%s: failed to map chipid registers, assuming "
+                       "fin_pll clock frequency is 24MHz\n", __func__);
+       }
+
+       fclk.id = fin_pll;
+       fclk.name = "fin_pll";
+       fclk.parent_name = NULL;
+       fclk.flags = CLK_IS_ROOT;
+       fclk.fixed_rate = finpll_f;
+       samsung_clk_register_fixed_rate(&fclk, 1);
+
+       if (np)
+               iounmap(chipid_base);
+}
+
+/*
+ * This function allows non-dt platforms to specify the clock speed of the
+ * xxti and xusbxti clocks. These clocks are then registered with the specified
+ * clock speed.
+ */
+void __init exynos4_clk_register_fixed_ext(unsigned long xxti_f,
+                                               unsigned long xusbxti_f)
+{
+       exynos4_fixed_rate_ext_clks[0].fixed_rate = xxti_f;
+       exynos4_fixed_rate_ext_clks[1].fixed_rate = xusbxti_f;
+       samsung_clk_register_fixed_rate(exynos4_fixed_rate_ext_clks,
+                       ARRAY_SIZE(exynos4_fixed_rate_ext_clks));
+}
+
+static __initdata struct of_device_id ext_clk_match[] = {
+       { .compatible = "samsung,clock-xxti", .data = (void *)0, },
+       { .compatible = "samsung,clock-xusbxti", .data = (void *)1, },
+       {},
+};
+
+/* register exynos4 clocks */
+void __init exynos4_clk_init(struct device_node *np)
+{
+       void __iomem *reg_base;
+       struct clk *apll, *mpll, *epll, *vpll;
+       u32 exynos4_soc;
+
+       if (np) {
+               const struct of_device_id *match;
+               match = of_match_node(exynos4_clk_ids, np);
+               exynos4_soc = (u32)match->data;
+
+               reg_base = of_iomap(np, 0);
+               if (!reg_base)
+                       panic("%s: failed to map registers\n", __func__);
+       } else {
+               reg_base = S5P_VA_CMU;
+               if (soc_is_exynos4210())
+                       exynos4_soc = EXYNOS4210;
+               else if (soc_is_exynos4212() || soc_is_exynos4412())
+                       exynos4_soc = EXYNOS4X12;
+               else
+                       panic("%s: unable to determine soc\n", __func__);
+       }
+
+       if (exynos4_soc == EXYNOS4210)
+               samsung_clk_init(np, reg_base, nr_clks,
+                       exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs),
+                       exynos4210_clk_save, ARRAY_SIZE(exynos4210_clk_save));
+       else
+               samsung_clk_init(np, reg_base, nr_clks,
+                       exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs),
+                       exynos4x12_clk_save, ARRAY_SIZE(exynos4x12_clk_save));
+
+       if (np)
+               samsung_clk_of_register_fixed_ext(exynos4_fixed_rate_ext_clks,
+                       ARRAY_SIZE(exynos4_fixed_rate_ext_clks),
+                       ext_clk_match);
+
+       exynos4_clk_register_finpll();
+
+       if (exynos4_soc == EXYNOS4210) {
+               apll = samsung_clk_register_pll45xx("fout_apll", "fin_pll",
+                                       reg_base + APLL_CON0, pll_4508);
+               mpll = samsung_clk_register_pll45xx("fout_mpll", "fin_pll",
+                                       reg_base + E4210_MPLL_CON0, pll_4508);
+               epll = samsung_clk_register_pll46xx("fout_epll", "fin_pll",
+                                       reg_base + EPLL_CON0, pll_4600);
+               vpll = samsung_clk_register_pll46xx("fout_vpll", "mout_vpllsrc",
+                                       reg_base + VPLL_CON0, pll_4650c);
+       } else {
+               apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll",
+                                       reg_base + APLL_CON0);
+               mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
+                                       reg_base + E4X12_MPLL_CON0);
+               epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
+                                       reg_base + EPLL_CON0);
+               vpll = samsung_clk_register_pll36xx("fout_vpll", "fin_pll",
+                                       reg_base + VPLL_CON0);
+       }
+
+       samsung_clk_add_lookup(apll, fout_apll);
+       samsung_clk_add_lookup(mpll, fout_mpll);
+       samsung_clk_add_lookup(epll, fout_epll);
+       samsung_clk_add_lookup(vpll, fout_vpll);
+
+       samsung_clk_register_fixed_rate(exynos4_fixed_rate_clks,
+                       ARRAY_SIZE(exynos4_fixed_rate_clks));
+       samsung_clk_register_mux(exynos4_mux_clks,
+                       ARRAY_SIZE(exynos4_mux_clks));
+       samsung_clk_register_div(exynos4_div_clks,
+                       ARRAY_SIZE(exynos4_div_clks));
+       samsung_clk_register_gate(exynos4_gate_clks,
+                       ARRAY_SIZE(exynos4_gate_clks));
+
+       if (exynos4_soc == EXYNOS4210) {
+               samsung_clk_register_fixed_rate(exynos4210_fixed_rate_clks,
+                       ARRAY_SIZE(exynos4210_fixed_rate_clks));
+               samsung_clk_register_mux(exynos4210_mux_clks,
+                       ARRAY_SIZE(exynos4210_mux_clks));
+               samsung_clk_register_div(exynos4210_div_clks,
+                       ARRAY_SIZE(exynos4210_div_clks));
+               samsung_clk_register_gate(exynos4210_gate_clks,
+                       ARRAY_SIZE(exynos4210_gate_clks));
+       } else {
+               samsung_clk_register_mux(exynos4x12_mux_clks,
+                       ARRAY_SIZE(exynos4x12_mux_clks));
+               samsung_clk_register_div(exynos4x12_div_clks,
+                       ARRAY_SIZE(exynos4x12_div_clks));
+               samsung_clk_register_gate(exynos4x12_gate_clks,
+                       ARRAY_SIZE(exynos4x12_gate_clks));
+       }
+
+       pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n"
+               "\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n",
+               exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12",
+               _get_rate("sclk_apll"), _get_rate("sclk_mpll"),
+               _get_rate("sclk_epll"), _get_rate("sclk_vpll"),
+               _get_rate("arm_clk"));
+}
+CLK_OF_DECLARE(exynos4210_clk, "samsung,exynos4210-clock", exynos4_clk_init);
+CLK_OF_DECLARE(exynos4412_clk, "samsung,exynos4412-clock", exynos4_clk_init);
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
new file mode 100644 (file)
index 0000000..7290faa
--- /dev/null
@@ -0,0 +1,523 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2013 Linaro Ltd.
+ * Author: Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * 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.
+ *
+ * Common Clock Framework support for Exynos5250 SoC.
+*/
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <plat/cpu.h>
+#include "clk.h"
+#include "clk-pll.h"
+
+#define SRC_CPU                        0x200
+#define DIV_CPU0               0x500
+#define SRC_CORE1              0x4204
+#define SRC_TOP0               0x10210
+#define SRC_TOP2               0x10218
+#define SRC_GSCL               0x10220
+#define SRC_DISP1_0            0x1022c
+#define SRC_MAU                        0x10240
+#define SRC_FSYS               0x10244
+#define SRC_GEN                        0x10248
+#define SRC_PERIC0             0x10250
+#define SRC_PERIC1             0x10254
+#define SRC_MASK_GSCL          0x10320
+#define SRC_MASK_DISP1_0       0x1032c
+#define SRC_MASK_MAU           0x10334
+#define SRC_MASK_FSYS          0x10340
+#define SRC_MASK_GEN           0x10344
+#define SRC_MASK_PERIC0                0x10350
+#define SRC_MASK_PERIC1                0x10354
+#define DIV_TOP0               0x10510
+#define DIV_TOP1               0x10514
+#define DIV_GSCL               0x10520
+#define DIV_DISP1_0            0x1052c
+#define DIV_GEN                        0x1053c
+#define DIV_MAU                        0x10544
+#define DIV_FSYS0              0x10548
+#define DIV_FSYS1              0x1054c
+#define DIV_FSYS2              0x10550
+#define DIV_PERIC0             0x10558
+#define DIV_PERIC1             0x1055c
+#define DIV_PERIC2             0x10560
+#define DIV_PERIC3             0x10564
+#define DIV_PERIC4             0x10568
+#define DIV_PERIC5             0x1056c
+#define GATE_IP_GSCL           0x10920
+#define GATE_IP_MFC            0x1092c
+#define GATE_IP_GEN            0x10934
+#define GATE_IP_FSYS           0x10944
+#define GATE_IP_PERIC          0x10950
+#define GATE_IP_PERIS          0x10960
+#define SRC_CDREX              0x20200
+#define PLL_DIV2_SEL           0x20a24
+#define GATE_IP_DISP1          0x10928
+
+/*
+ * Let each supported clock get a unique id. This id is used to lookup the clock
+ * for device tree based platforms. The clocks are categorized into three
+ * sections: core, sclk gate and bus interface gate clocks.
+ *
+ * When adding a new clock to this list, it is advised to choose a clock
+ * category and add it to the end of that category. That is because the the
+ * device tree source file is referring to these ids and any change in the
+ * sequence number of existing clocks will require corresponding change in the
+ * device tree files. This limitation would go away when pre-processor support
+ * for dtc would be available.
+ */
+enum exynos5250_clks {
+       none,
+
+       /* core clocks */
+       fin_pll,
+
+       /* gate for special clocks (sclk) */
+       sclk_cam_bayer = 128, sclk_cam0, sclk_cam1, sclk_gscl_wa, sclk_gscl_wb,
+       sclk_fimd1, sclk_mipi1, sclk_dp, sclk_hdmi, sclk_pixel, sclk_audio0,
+       sclk_mmc0, sclk_mmc1, sclk_mmc2, sclk_mmc3, sclk_sata, sclk_usb3,
+       sclk_jpeg, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3, sclk_pwm,
+       sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1, sclk_spi2,
+
+       /* gate clocks */
+       gscl0 = 256, gscl1, gscl2, gscl3, gscl_wa, gscl_wb, smmu_gscl0,
+       smmu_gscl1, smmu_gscl2, smmu_gscl3, mfc, smmu_mfcl, smmu_mfcr, rotator,
+       jpeg, mdma1, smmu_rotator, smmu_jpeg, smmu_mdma1, pdma0, pdma1, sata,
+       usbotg, mipi_hsi, sdmmc0, sdmmc1, sdmmc2, sdmmc3, sromc, usb2, usb3,
+       sata_phyctrl, sata_phyi2c, uart0, uart1, uart2, uart3, uart4, i2c0,
+       i2c1, i2c2, i2c3, i2c4, i2c5, i2c6, i2c7, i2c_hdmi, adc, spi0, spi1,
+       spi2, i2s1, i2s2, pcm1, pcm2, pwm, spdif, ac97, hsi2c0, hsi2c1, hsi2c2,
+       hsi2c3, chipid, sysreg, pmu, cmu_top, cmu_core, cmu_mem, tzpc0, tzpc1,
+       tzpc2, tzpc3, tzpc4, tzpc5, tzpc6, tzpc7, tzpc8, tzpc9, hdmi_cec, mct,
+       wdt, rtc, tmu, fimd1, mie1, dsim0, dp, mixer, hdmi,
+
+       nr_clks,
+};
+
+/*
+ * list of controller registers to be saved and restored during a
+ * suspend/resume cycle.
+ */
+static __initdata unsigned long exynos5250_clk_regs[] = {
+       SRC_CPU,
+       DIV_CPU0,
+       SRC_CORE1,
+       SRC_TOP0,
+       SRC_TOP2,
+       SRC_GSCL,
+       SRC_DISP1_0,
+       SRC_MAU,
+       SRC_FSYS,
+       SRC_GEN,
+       SRC_PERIC0,
+       SRC_PERIC1,
+       SRC_MASK_GSCL,
+       SRC_MASK_DISP1_0,
+       SRC_MASK_MAU,
+       SRC_MASK_FSYS,
+       SRC_MASK_GEN,
+       SRC_MASK_PERIC0,
+       SRC_MASK_PERIC1,
+       DIV_TOP0,
+       DIV_TOP1,
+       DIV_GSCL,
+       DIV_DISP1_0,
+       DIV_GEN,
+       DIV_MAU,
+       DIV_FSYS0,
+       DIV_FSYS1,
+       DIV_FSYS2,
+       DIV_PERIC0,
+       DIV_PERIC1,
+       DIV_PERIC2,
+       DIV_PERIC3,
+       DIV_PERIC4,
+       DIV_PERIC5,
+       GATE_IP_GSCL,
+       GATE_IP_MFC,
+       GATE_IP_GEN,
+       GATE_IP_FSYS,
+       GATE_IP_PERIC,
+       GATE_IP_PERIS,
+       SRC_CDREX,
+       PLL_DIV2_SEL,
+       GATE_IP_DISP1,
+};
+
+/* list of all parent clock list */
+PNAME(mout_apll_p)     = { "fin_pll", "fout_apll", };
+PNAME(mout_cpu_p)      = { "mout_apll", "mout_mpll", };
+PNAME(mout_mpll_fout_p)        = { "fout_mplldiv2", "fout_mpll" };
+PNAME(mout_mpll_p)     = { "fin_pll", "mout_mpll_fout" };
+PNAME(mout_bpll_fout_p)        = { "fout_bplldiv2", "fout_bpll" };
+PNAME(mout_bpll_p)     = { "fin_pll", "mout_bpll_fout" };
+PNAME(mout_vpllsrc_p)  = { "fin_pll", "sclk_hdmi27m" };
+PNAME(mout_vpll_p)     = { "mout_vpllsrc", "fout_vpll" };
+PNAME(mout_cpll_p)     = { "fin_pll", "fout_cpll" };
+PNAME(mout_epll_p)     = { "fin_pll", "fout_epll" };
+PNAME(mout_mpll_user_p)        = { "fin_pll", "sclk_mpll" };
+PNAME(mout_bpll_user_p)        = { "fin_pll", "sclk_bpll" };
+PNAME(mout_aclk166_p)  = { "sclk_cpll", "sclk_mpll_user" };
+PNAME(mout_aclk200_p)  = { "sclk_mpll_user", "sclk_bpll_user" };
+PNAME(mout_hdmi_p)     = { "div_hdmi_pixel", "sclk_hdmiphy" };
+PNAME(mout_usb3_p)     = { "sclk_mpll_user", "sclk_cpll" };
+PNAME(mout_group1_p)   = { "fin_pll", "fin_pll", "sclk_hdmi27m",
+                               "sclk_dptxphy", "sclk_uhostphy", "sclk_hdmiphy",
+                               "sclk_mpll_user", "sclk_epll", "sclk_vpll",
+                               "sclk_cpll" };
+PNAME(mout_audio0_p)   = { "cdclk0", "fin_pll", "sclk_hdmi27m", "sclk_dptxphy",
+                               "sclk_uhostphy", "sclk_hdmiphy",
+                               "sclk_mpll_user", "sclk_epll", "sclk_vpll",
+                               "sclk_cpll" };
+PNAME(mout_audio1_p)   = { "cdclk1", "fin_pll", "sclk_hdmi27m", "sclk_dptxphy",
+                               "sclk_uhostphy", "sclk_hdmiphy",
+                               "sclk_mpll_user", "sclk_epll", "sclk_vpll",
+                               "sclk_cpll" };
+PNAME(mout_audio2_p)   = { "cdclk2", "fin_pll", "sclk_hdmi27m", "sclk_dptxphy",
+                               "sclk_uhostphy", "sclk_hdmiphy",
+                               "sclk_mpll_user", "sclk_epll", "sclk_vpll",
+                               "sclk_cpll" };
+PNAME(mout_spdif_p)    = { "sclk_audio0", "sclk_audio1", "sclk_audio2",
+                               "spdif_extclk" };
+
+/* fixed rate clocks generated outside the soc */
+struct samsung_fixed_rate_clock exynos5250_fixed_rate_ext_clks[] __initdata = {
+       FRATE(fin_pll, "fin_pll", NULL, CLK_IS_ROOT, 0),
+};
+
+/* fixed rate clocks generated inside the soc */
+struct samsung_fixed_rate_clock exynos5250_fixed_rate_clks[] __initdata = {
+       FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000),
+       FRATE(none, "sclk_hdmi27m", NULL, CLK_IS_ROOT, 27000000),
+       FRATE(none, "sclk_dptxphy", NULL, CLK_IS_ROOT, 24000000),
+       FRATE(none, "sclk_uhostphy", NULL, CLK_IS_ROOT, 48000000),
+};
+
+struct samsung_fixed_factor_clock exynos5250_fixed_factor_clks[] __initdata = {
+       FFACTOR(none, "fout_mplldiv2", "fout_mpll", 1, 2, 0),
+       FFACTOR(none, "fout_bplldiv2", "fout_bpll", 1, 2, 0),
+};
+
+struct samsung_mux_clock exynos5250_mux_clks[] __initdata = {
+       MUX(none, "mout_apll", mout_apll_p, SRC_CPU, 0, 1),
+       MUX(none, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1),
+       MUX(none, "mout_mpll_fout", mout_mpll_fout_p, PLL_DIV2_SEL, 4, 1),
+       MUX(none, "sclk_mpll", mout_mpll_p, SRC_CORE1, 8, 1),
+       MUX(none, "mout_bpll_fout", mout_bpll_fout_p, PLL_DIV2_SEL, 0, 1),
+       MUX(none, "sclk_bpll", mout_bpll_p, SRC_CDREX, 0, 1),
+       MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1),
+       MUX(none, "sclk_vpll", mout_vpll_p, SRC_TOP2, 16, 1),
+       MUX(none, "sclk_epll", mout_epll_p, SRC_TOP2, 12, 1),
+       MUX(none, "sclk_cpll", mout_cpll_p, SRC_TOP2, 8, 1),
+       MUX(none, "sclk_mpll_user", mout_mpll_user_p, SRC_TOP2, 20, 1),
+       MUX(none, "sclk_bpll_user", mout_bpll_user_p, SRC_TOP2, 24, 1),
+       MUX(none, "mout_aclk166", mout_aclk166_p, SRC_TOP0, 8, 1),
+       MUX(none, "mout_aclk333", mout_aclk166_p, SRC_TOP0, 16, 1),
+       MUX(none, "mout_aclk200", mout_aclk200_p, SRC_TOP0, 12, 1),
+       MUX(none, "mout_cam_bayer", mout_group1_p, SRC_GSCL, 12, 4),
+       MUX(none, "mout_cam0", mout_group1_p, SRC_GSCL, 16, 4),
+       MUX(none, "mout_cam1", mout_group1_p, SRC_GSCL, 20, 4),
+       MUX(none, "mout_gscl_wa", mout_group1_p, SRC_GSCL, 24, 4),
+       MUX(none, "mout_gscl_wb", mout_group1_p, SRC_GSCL, 28, 4),
+       MUX(none, "mout_fimd1", mout_group1_p, SRC_DISP1_0, 0, 4),
+       MUX(none, "mout_mipi1", mout_group1_p, SRC_DISP1_0, 12, 4),
+       MUX(none, "mout_dp", mout_group1_p, SRC_DISP1_0, 16, 4),
+       MUX(none, "mout_hdmi", mout_hdmi_p, SRC_DISP1_0, 20, 1),
+       MUX(none, "mout_audio0", mout_audio0_p, SRC_MAU, 0, 4),
+       MUX(none, "mout_mmc0", mout_group1_p, SRC_FSYS, 0, 4),
+       MUX(none, "mout_mmc1", mout_group1_p, SRC_FSYS, 4, 4),
+       MUX(none, "mout_mmc2", mout_group1_p, SRC_FSYS, 8, 4),
+       MUX(none, "mout_mmc3", mout_group1_p, SRC_FSYS, 12, 4),
+       MUX(none, "mout_sata", mout_aclk200_p, SRC_FSYS, 24, 1),
+       MUX(none, "mout_usb3", mout_usb3_p, SRC_FSYS, 28, 1),
+       MUX(none, "mout_jpeg", mout_group1_p, SRC_GEN, 0, 4),
+       MUX(none, "mout_uart0", mout_group1_p, SRC_PERIC0, 0, 4),
+       MUX(none, "mout_uart1", mout_group1_p, SRC_PERIC0, 4, 4),
+       MUX(none, "mout_uart2", mout_group1_p, SRC_PERIC0, 8, 4),
+       MUX(none, "mout_uart3", mout_group1_p, SRC_PERIC0, 12, 4),
+       MUX(none, "mout_pwm", mout_group1_p, SRC_PERIC0, 24, 4),
+       MUX(none, "mout_audio1", mout_audio1_p, SRC_PERIC1, 0, 4),
+       MUX(none, "mout_audio2", mout_audio2_p, SRC_PERIC1, 4, 4),
+       MUX(none, "mout_spdif", mout_spdif_p, SRC_PERIC1, 8, 2),
+       MUX(none, "mout_spi0", mout_group1_p, SRC_PERIC1, 16, 4),
+       MUX(none, "mout_spi1", mout_group1_p, SRC_PERIC1, 20, 4),
+       MUX(none, "mout_spi2", mout_group1_p, SRC_PERIC1, 24, 4),
+};
+
+struct samsung_div_clock exynos5250_div_clks[] __initdata = {
+       DIV(none, "div_arm", "mout_cpu", DIV_CPU0, 0, 3),
+       DIV(none, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3),
+       DIV(none, "aclk66_pre", "sclk_mpll_user", DIV_TOP1, 24, 3),
+       DIV(none, "aclk66", "aclk66_pre", DIV_TOP0, 0, 3),
+       DIV(none, "aclk266", "sclk_mpll_user", DIV_TOP0, 16, 3),
+       DIV(none, "aclk166", "mout_aclk166", DIV_TOP0, 8, 3),
+       DIV(none, "aclk333", "mout_aclk333", DIV_TOP0, 20, 3),
+       DIV(none, "aclk200", "mout_aclk200", DIV_TOP0, 12, 3),
+       DIV(none, "div_cam_bayer", "mout_cam_bayer", DIV_GSCL, 12, 4),
+       DIV(none, "div_cam0", "mout_cam0", DIV_GSCL, 16, 4),
+       DIV(none, "div_cam1", "mout_cam1", DIV_GSCL, 20, 4),
+       DIV(none, "div_gscl_wa", "mout_gscl_wa", DIV_GSCL, 24, 4),
+       DIV(none, "div_gscl_wb", "mout_gscl_wb", DIV_GSCL, 28, 4),
+       DIV(none, "div_fimd1", "mout_fimd1", DIV_DISP1_0, 0, 4),
+       DIV(none, "div_mipi1", "mout_mipi1", DIV_DISP1_0, 16, 4),
+       DIV(none, "div_dp", "mout_dp", DIV_DISP1_0, 24, 4),
+       DIV(none, "div_jpeg", "mout_jpeg", DIV_GEN, 4, 4),
+       DIV(none, "div_audio0", "mout_audio0", DIV_MAU, 0, 4),
+       DIV(none, "div_pcm0", "sclk_audio0", DIV_MAU, 4, 8),
+       DIV(none, "div_sata", "mout_sata", DIV_FSYS0, 20, 4),
+       DIV(none, "div_usb3", "mout_usb3", DIV_FSYS0, 24, 4),
+       DIV(none, "div_mmc0", "mout_mmc0", DIV_FSYS1, 8, 8),
+       DIV(none, "div_mmc1", "mout_mmc1", DIV_FSYS1, 24, 8),
+       DIV(none, "div_mmc2", "mout_mmc2", DIV_FSYS2, 8, 8),
+       DIV(none, "div_mmc3", "mout_mmc3", DIV_FSYS2, 24, 8),
+       DIV(none, "div_uart0", "mout_uart0", DIV_PERIC0, 0, 4),
+       DIV(none, "div_uart1", "mout_uart1", DIV_PERIC0, 4, 4),
+       DIV(none, "div_uart2", "mout_uart2", DIV_PERIC0, 8, 4),
+       DIV(none, "div_uart3", "mout_uart3", DIV_PERIC0, 12, 4),
+       DIV(none, "div_spi0", "mout_spi0", DIV_PERIC1, 0, 4),
+       DIV(none, "div_spi1", "mout_spi1", DIV_PERIC1, 16, 4),
+       DIV(none, "div_spi2", "mout_spi2", DIV_PERIC2, 0, 4),
+       DIV(none, "div_pwm", "mout_pwm", DIV_PERIC3, 0, 4),
+       DIV(none, "div_audio1", "mout_audio1", DIV_PERIC4, 0, 4),
+       DIV(none, "div_pcm1", "sclk_audio1", DIV_PERIC4, 4, 8),
+       DIV(none, "div_audio2", "mout_audio2", DIV_PERIC4, 16, 4),
+       DIV(none, "div_pcm2", "sclk_audio2", DIV_PERIC4, 20, 8),
+       DIV(none, "div_i2s1", "sclk_audio1", DIV_PERIC5, 0, 6),
+       DIV(none, "div_i2s2", "sclk_audio2", DIV_PERIC5, 8, 6),
+       DIV(sclk_pixel, "div_hdmi_pixel", "sclk_vpll", DIV_DISP1_0, 28, 4),
+       DIV_A(none, "armclk", "div_arm", DIV_CPU0, 28, 3, "armclk"),
+       DIV_F(none, "div_mipi1_pre", "div_mipi1",
+                       DIV_DISP1_0, 20, 4, CLK_SET_RATE_PARENT, 0),
+       DIV_F(none, "div_mmc_pre0", "div_mmc0",
+                       DIV_FSYS1, 8, 8, CLK_SET_RATE_PARENT, 0),
+       DIV_F(none, "div_mmc_pre1", "div_mmc1",
+                       DIV_FSYS1, 24, 8, CLK_SET_RATE_PARENT, 0),
+       DIV_F(none, "div_mmc_pre2", "div_mmc2",
+                       DIV_FSYS2, 8, 8, CLK_SET_RATE_PARENT, 0),
+       DIV_F(none, "div_mmc_pre3", "div_mmc3",
+                       DIV_FSYS2, 24, 8, CLK_SET_RATE_PARENT, 0),
+       DIV_F(none, "div_spi_pre0", "div_spi0",
+                       DIV_PERIC1, 8, 8, CLK_SET_RATE_PARENT, 0),
+       DIV_F(none, "div_spi_pre1", "div_spi1",
+                       DIV_PERIC1, 24, 8, CLK_SET_RATE_PARENT, 0),
+       DIV_F(none, "div_spi_pre2", "div_spi2",
+                       DIV_PERIC2, 8, 8, CLK_SET_RATE_PARENT, 0),
+};
+
+struct samsung_gate_clock exynos5250_gate_clks[] __initdata = {
+       GATE(gscl0, "gscl0", "none", GATE_IP_GSCL, 0, 0, 0),
+       GATE(gscl1, "gscl1", "none", GATE_IP_GSCL, 1, 0, 0),
+       GATE(gscl2, "gscl2", "aclk266", GATE_IP_GSCL, 2, 0, 0),
+       GATE(gscl3, "gscl3", "aclk266", GATE_IP_GSCL, 3, 0, 0),
+       GATE(gscl_wa, "gscl_wa", "div_gscl_wa", GATE_IP_GSCL, 5, 0, 0),
+       GATE(gscl_wb, "gscl_wb", "div_gscl_wb", GATE_IP_GSCL, 6, 0, 0),
+       GATE(smmu_gscl0, "smmu_gscl0", "aclk266", GATE_IP_GSCL, 7, 0, 0),
+       GATE(smmu_gscl1, "smmu_gscl1", "aclk266", GATE_IP_GSCL, 8, 0, 0),
+       GATE(smmu_gscl2, "smmu_gscl2", "aclk266", GATE_IP_GSCL, 9, 0, 0),
+       GATE(smmu_gscl3, "smmu_gscl3", "aclk266", GATE_IP_GSCL, 10, 0, 0),
+       GATE(mfc, "mfc", "aclk333", GATE_IP_MFC, 0, 0, 0),
+       GATE(smmu_mfcl, "smmu_mfcl", "aclk333", GATE_IP_MFC, 1, 0, 0),
+       GATE(smmu_mfcr, "smmu_mfcr", "aclk333", GATE_IP_MFC, 2, 0, 0),
+       GATE(rotator, "rotator", "aclk266", GATE_IP_GEN, 1, 0, 0),
+       GATE(jpeg, "jpeg", "aclk166", GATE_IP_GEN, 2, 0, 0),
+       GATE(mdma1, "mdma1", "aclk266", GATE_IP_GEN, 4, 0, 0),
+       GATE(smmu_rotator, "smmu_rotator", "aclk266", GATE_IP_GEN, 6, 0, 0),
+       GATE(smmu_jpeg, "smmu_jpeg", "aclk166", GATE_IP_GEN, 7, 0, 0),
+       GATE(smmu_mdma1, "smmu_mdma1", "aclk266", GATE_IP_GEN, 9, 0, 0),
+       GATE(pdma0, "pdma0", "aclk200", GATE_IP_FSYS, 1, 0, 0),
+       GATE(pdma1, "pdma1", "aclk200", GATE_IP_FSYS, 2, 0, 0),
+       GATE(sata, "sata", "aclk200", GATE_IP_FSYS, 6, 0, 0),
+       GATE(usbotg, "usbotg", "aclk200", GATE_IP_FSYS, 7, 0, 0),
+       GATE(mipi_hsi, "mipi_hsi", "aclk200", GATE_IP_FSYS, 8, 0, 0),
+       GATE(sdmmc0, "sdmmc0", "aclk200", GATE_IP_FSYS, 12, 0, 0),
+       GATE(sdmmc1, "sdmmc1", "aclk200", GATE_IP_FSYS, 13, 0, 0),
+       GATE(sdmmc2, "sdmmc2", "aclk200", GATE_IP_FSYS, 14, 0, 0),
+       GATE(sdmmc3, "sdmmc3", "aclk200", GATE_IP_FSYS, 15, 0, 0),
+       GATE(sromc, "sromc", "aclk200", GATE_IP_FSYS, 17, 0, 0),
+       GATE(usb2, "usb2", "aclk200", GATE_IP_FSYS, 18, 0, 0),
+       GATE(usb3, "usb3", "aclk200", GATE_IP_FSYS, 19, 0, 0),
+       GATE(sata_phyctrl, "sata_phyctrl", "aclk200", GATE_IP_FSYS, 24, 0, 0),
+       GATE(sata_phyi2c, "sata_phyi2c", "aclk200", GATE_IP_FSYS, 25, 0, 0),
+       GATE(uart0, "uart0", "aclk66", GATE_IP_PERIC, 0, 0, 0),
+       GATE(uart1, "uart1", "aclk66", GATE_IP_PERIC, 1, 0, 0),
+       GATE(uart2, "uart2", "aclk66", GATE_IP_PERIC, 2, 0, 0),
+       GATE(uart3, "uart3", "aclk66", GATE_IP_PERIC, 3, 0, 0),
+       GATE(uart4, "uart4", "aclk66", GATE_IP_PERIC, 4, 0, 0),
+       GATE(i2c0, "i2c0", "aclk66", GATE_IP_PERIC, 6, 0, 0),
+       GATE(i2c1, "i2c1", "aclk66", GATE_IP_PERIC, 7, 0, 0),
+       GATE(i2c2, "i2c2", "aclk66", GATE_IP_PERIC, 8, 0, 0),
+       GATE(i2c3, "i2c3", "aclk66", GATE_IP_PERIC, 9, 0, 0),
+       GATE(i2c4, "i2c4", "aclk66", GATE_IP_PERIC, 10, 0, 0),
+       GATE(i2c5, "i2c5", "aclk66", GATE_IP_PERIC, 11, 0, 0),
+       GATE(i2c6, "i2c6", "aclk66", GATE_IP_PERIC, 12, 0, 0),
+       GATE(i2c7, "i2c7", "aclk66", GATE_IP_PERIC, 13, 0, 0),
+       GATE(i2c_hdmi, "i2c_hdmi", "aclk66", GATE_IP_PERIC, 14, 0, 0),
+       GATE(adc, "adc", "aclk66", GATE_IP_PERIC, 15, 0, 0),
+       GATE(spi0, "spi0", "aclk66", GATE_IP_PERIC, 16, 0, 0),
+       GATE(spi1, "spi1", "aclk66", GATE_IP_PERIC, 17, 0, 0),
+       GATE(spi2, "spi2", "aclk66", GATE_IP_PERIC, 18, 0, 0),
+       GATE(i2s1, "i2s1", "aclk66", GATE_IP_PERIC, 20, 0, 0),
+       GATE(i2s2, "i2s2", "aclk66", GATE_IP_PERIC, 21, 0, 0),
+       GATE(pcm1, "pcm1", "aclk66", GATE_IP_PERIC, 22, 0, 0),
+       GATE(pcm2, "pcm2", "aclk66", GATE_IP_PERIC, 23, 0, 0),
+       GATE(pwm, "pwm", "aclk66", GATE_IP_PERIC, 24, 0, 0),
+       GATE(spdif, "spdif", "aclk66", GATE_IP_PERIC, 26, 0, 0),
+       GATE(ac97, "ac97", "aclk66", GATE_IP_PERIC, 27, 0, 0),
+       GATE(hsi2c0, "hsi2c0", "aclk66", GATE_IP_PERIC, 28, 0, 0),
+       GATE(hsi2c1, "hsi2c1", "aclk66", GATE_IP_PERIC, 29, 0, 0),
+       GATE(hsi2c2, "hsi2c2", "aclk66", GATE_IP_PERIC, 30, 0, 0),
+       GATE(hsi2c3, "hsi2c3", "aclk66", GATE_IP_PERIC, 31, 0, 0),
+       GATE(chipid, "chipid", "aclk66", GATE_IP_PERIS, 0, 0, 0),
+       GATE(sysreg, "sysreg", "aclk66", GATE_IP_PERIS, 1, 0, 0),
+       GATE(pmu, "pmu", "aclk66", GATE_IP_PERIS, 2, 0, 0),
+       GATE(tzpc0, "tzpc0", "aclk66", GATE_IP_PERIS, 6, 0, 0),
+       GATE(tzpc1, "tzpc1", "aclk66", GATE_IP_PERIS, 7, 0, 0),
+       GATE(tzpc2, "tzpc2", "aclk66", GATE_IP_PERIS, 8, 0, 0),
+       GATE(tzpc3, "tzpc3", "aclk66", GATE_IP_PERIS, 9, 0, 0),
+       GATE(tzpc4, "tzpc4", "aclk66", GATE_IP_PERIS, 10, 0, 0),
+       GATE(tzpc5, "tzpc5", "aclk66", GATE_IP_PERIS, 11, 0, 0),
+       GATE(tzpc6, "tzpc6", "aclk66", GATE_IP_PERIS, 12, 0, 0),
+       GATE(tzpc7, "tzpc7", "aclk66", GATE_IP_PERIS, 13, 0, 0),
+       GATE(tzpc8, "tzpc8", "aclk66", GATE_IP_PERIS, 14, 0, 0),
+       GATE(tzpc9, "tzpc9", "aclk66", GATE_IP_PERIS, 15, 0, 0),
+       GATE(hdmi_cec, "hdmi_cec", "aclk66", GATE_IP_PERIS, 16, 0, 0),
+       GATE(mct, "mct", "aclk66", GATE_IP_PERIS, 18, 0, 0),
+       GATE(wdt, "wdt", "aclk66", GATE_IP_PERIS, 19, 0, 0),
+       GATE(rtc, "rtc", "aclk66", GATE_IP_PERIS, 20, 0, 0),
+       GATE(tmu, "tmu", "aclk66", GATE_IP_PERIS, 21, 0, 0),
+       GATE(cmu_top, "cmu_top", "aclk66",
+                       GATE_IP_PERIS, 3, CLK_IGNORE_UNUSED, 0),
+       GATE(cmu_core, "cmu_core", "aclk66",
+                       GATE_IP_PERIS, 4, CLK_IGNORE_UNUSED, 0),
+       GATE(cmu_mem, "cmu_mem", "aclk66",
+                       GATE_IP_PERIS, 5, CLK_IGNORE_UNUSED, 0),
+       GATE(sclk_cam_bayer, "sclk_cam_bayer", "div_cam_bayer",
+                       SRC_MASK_GSCL, 12, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_cam0, "sclk_cam0", "div_cam0",
+                       SRC_MASK_GSCL, 16, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_cam1, "sclk_cam1", "div_cam1",
+                       SRC_MASK_GSCL, 20, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_gscl_wa, "sclk_gscl_wa", "div_gscl_wa",
+                       SRC_MASK_GSCL, 24, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_gscl_wb, "sclk_gscl_wb", "div_gscl_wb",
+                       SRC_MASK_GSCL, 28, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_fimd1, "sclk_fimd1", "div_fimd1",
+                       SRC_MASK_DISP1_0, 0, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_mipi1, "sclk_mipi1", "div_mipi1",
+                       SRC_MASK_DISP1_0, 12, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_dp, "sclk_dp", "div_dp",
+                       SRC_MASK_DISP1_0, 16, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi",
+                       SRC_MASK_DISP1_0, 20, 0, 0),
+       GATE(sclk_audio0, "sclk_audio0", "div_audio0",
+                       SRC_MASK_MAU, 0, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_mmc0, "sclk_mmc0", "div_mmc0",
+                       SRC_MASK_FSYS, 0, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_mmc1, "sclk_mmc1", "div_mmc1",
+                       SRC_MASK_FSYS, 4, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_mmc2, "sclk_mmc2", "div_mmc2",
+                       SRC_MASK_FSYS, 8, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_mmc3, "sclk_mmc3", "div_mmc3",
+                       SRC_MASK_FSYS, 12, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_sata, "sclk_sata", "div_sata",
+                       SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_usb3, "sclk_usb3", "div_usb3",
+                       SRC_MASK_FSYS, 28, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_jpeg, "sclk_jpeg", "div_jpeg",
+                       SRC_MASK_GEN, 0, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_uart0, "sclk_uart0", "div_uart0",
+                       SRC_MASK_PERIC0, 0, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_uart1, "sclk_uart1", "div_uart1",
+                       SRC_MASK_PERIC0, 4, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_uart2, "sclk_uart2", "div_uart2",
+                       SRC_MASK_PERIC0, 8, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_uart3, "sclk_uart3", "div_uart3",
+                       SRC_MASK_PERIC0, 12, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_pwm, "sclk_pwm", "div_pwm",
+                       SRC_MASK_PERIC0, 24, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_audio1, "sclk_audio1", "div_audio1",
+                       SRC_MASK_PERIC1, 0, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_audio2, "sclk_audio2", "div_audio2",
+                       SRC_MASK_PERIC1, 4, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_spdif, "sclk_spdif", "mout_spdif",
+                       SRC_MASK_PERIC1, 4, 0, 0),
+       GATE(sclk_spi0, "sclk_spi0", "div_spi_pre0",
+                       SRC_MASK_PERIC1, 16, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_spi1, "sclk_spi1", "div_spi_pre1",
+                       SRC_MASK_PERIC1, 20, CLK_SET_RATE_PARENT, 0),
+       GATE(sclk_spi2, "sclk_spi2", "div_spi_pre2",
+                       SRC_MASK_PERIC1, 24, CLK_SET_RATE_PARENT, 0),
+       GATE(fimd1, "fimd1", "aclk200", GATE_IP_DISP1, 0, 0, 0),
+       GATE(mie1, "mie1", "aclk200", GATE_IP_DISP1, 1, 0, 0),
+       GATE(dsim0, "dsim0", "aclk200", GATE_IP_DISP1, 3, 0, 0),
+       GATE(dp, "dp", "aclk200", GATE_IP_DISP1, 4, 0, 0),
+       GATE(mixer, "mixer", "aclk200", GATE_IP_DISP1, 5, 0, 0),
+       GATE(hdmi, "hdmi", "aclk200", GATE_IP_DISP1, 6, 0, 0),
+};
+
+static __initdata struct of_device_id ext_clk_match[] = {
+       { .compatible = "samsung,clock-xxti", .data = (void *)0, },
+       { },
+};
+
+/* register exynox5250 clocks */
+void __init exynos5250_clk_init(struct device_node *np)
+{
+       void __iomem *reg_base;
+       struct clk *apll, *mpll, *epll, *vpll, *bpll, *gpll, *cpll;
+
+       if (np) {
+               reg_base = of_iomap(np, 0);
+               if (!reg_base)
+                       panic("%s: failed to map registers\n", __func__);
+       } else {
+               panic("%s: unable to determine soc\n", __func__);
+       }
+
+       samsung_clk_init(np, reg_base, nr_clks,
+                       exynos5250_clk_regs, ARRAY_SIZE(exynos5250_clk_regs),
+                       NULL, 0);
+       samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks,
+                       ARRAY_SIZE(exynos5250_fixed_rate_ext_clks),
+                       ext_clk_match);
+
+       apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll",
+                       reg_base + 0x100);
+       mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
+                       reg_base + 0x4100);
+       bpll = samsung_clk_register_pll35xx("fout_bpll", "fin_pll",
+                       reg_base + 0x20110);
+       gpll = samsung_clk_register_pll35xx("fout_gpll", "fin_pll",
+                       reg_base + 0x10150);
+       cpll = samsung_clk_register_pll35xx("fout_cpll", "fin_pll",
+                       reg_base + 0x10120);
+       epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
+                       reg_base + 0x10130);
+       vpll = samsung_clk_register_pll36xx("fout_vpll", "mout_vpllsrc",
+                       reg_base + 0x10140);
+
+       samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks,
+                       ARRAY_SIZE(exynos5250_fixed_rate_clks));
+       samsung_clk_register_fixed_factor(exynos5250_fixed_factor_clks,
+                       ARRAY_SIZE(exynos5250_fixed_factor_clks));
+       samsung_clk_register_mux(exynos5250_mux_clks,
+                       ARRAY_SIZE(exynos5250_mux_clks));
+       samsung_clk_register_div(exynos5250_div_clks,
+                       ARRAY_SIZE(exynos5250_div_clks));
+       samsung_clk_register_gate(exynos5250_gate_clks,
+                       ARRAY_SIZE(exynos5250_gate_clks));
+
+       pr_info("Exynos5250: clock setup completed, armclk=%ld\n",
+                       _get_rate("armclk"));
+}
+CLK_OF_DECLARE(exynos5250_clk, "samsung,exynos5250-clock", exynos5250_clk_init);
diff --git a/drivers/clk/samsung/clk-exynos5440.c b/drivers/clk/samsung/clk-exynos5440.c
new file mode 100644 (file)
index 0000000..a0a094c
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * Author: Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * 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.
+ *
+ * Common Clock Framework support for Exynos5440 SoC.
+*/
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <plat/cpu.h>
+#include "clk.h"
+#include "clk-pll.h"
+
+#define CLKEN_OV_VAL           0xf8
+#define CPU_CLK_STATUS         0xfc
+#define MISC_DOUT1             0x558
+
+/*
+ * Let each supported clock get a unique id. This id is used to lookup the clock
+ * for device tree based platforms.
+ */
+enum exynos5440_clks {
+       none, xtal, arm_clk,
+
+       spi_baud = 16, pb0_250, pr0_250, pr1_250, b_250, b_125, b_200, sata,
+       usb, gmac0, cs250, pb0_250_o, pr0_250_o, pr1_250_o, b_250_o, b_125_o,
+       b_200_o, sata_o, usb_o, gmac0_o, cs250_o,
+
+       nr_clks,
+};
+
+/* parent clock name list */
+PNAME(mout_armclk_p)   = { "cplla", "cpllb" };
+PNAME(mout_spi_p)      = { "div125", "div200" };
+
+/* fixed rate clocks generated outside the soc */
+struct samsung_fixed_rate_clock exynos5440_fixed_rate_ext_clks[] __initdata = {
+       FRATE(none, "xtal", NULL, CLK_IS_ROOT, 0),
+};
+
+/* fixed rate clocks */
+struct samsung_fixed_rate_clock exynos5440_fixed_rate_clks[] __initdata = {
+       FRATE(none, "ppll", NULL, CLK_IS_ROOT, 1000000000),
+       FRATE(none, "usb_phy0", NULL, CLK_IS_ROOT, 60000000),
+       FRATE(none, "usb_phy1", NULL, CLK_IS_ROOT, 60000000),
+       FRATE(none, "usb_ohci12", NULL, CLK_IS_ROOT, 12000000),
+       FRATE(none, "usb_ohci48", NULL, CLK_IS_ROOT, 48000000),
+};
+
+/* fixed factor clocks */
+struct samsung_fixed_factor_clock exynos5440_fixed_factor_clks[] __initdata = {
+       FFACTOR(none, "div250", "ppll", 1, 4, 0),
+       FFACTOR(none, "div200", "ppll", 1, 5, 0),
+       FFACTOR(none, "div125", "div250", 1, 2, 0),
+};
+
+/* mux clocks */
+struct samsung_mux_clock exynos5440_mux_clks[] __initdata = {
+       MUX(none, "mout_spi", mout_spi_p, MISC_DOUT1, 5, 1),
+       MUX_A(arm_clk, "arm_clk", mout_armclk_p,
+                       CPU_CLK_STATUS, 0, 1, "armclk"),
+};
+
+/* divider clocks */
+struct samsung_div_clock exynos5440_div_clks[] __initdata = {
+       DIV(spi_baud, "div_spi", "mout_spi", MISC_DOUT1, 3, 2),
+};
+
+/* gate clocks */
+struct samsung_gate_clock exynos5440_gate_clks[] __initdata = {
+       GATE(pb0_250, "pb0_250", "div250", CLKEN_OV_VAL, 3, 0, 0),
+       GATE(pr0_250, "pr0_250", "div250", CLKEN_OV_VAL, 4, 0, 0),
+       GATE(pr1_250, "pr1_250", "div250", CLKEN_OV_VAL, 5, 0, 0),
+       GATE(b_250, "b_250", "div250", CLKEN_OV_VAL, 9, 0, 0),
+       GATE(b_125, "b_125", "div125", CLKEN_OV_VAL, 10, 0, 0),
+       GATE(b_200, "b_200", "div200", CLKEN_OV_VAL, 11, 0, 0),
+       GATE(sata, "sata", "div200", CLKEN_OV_VAL, 12, 0, 0),
+       GATE(usb, "usb", "div200", CLKEN_OV_VAL, 13, 0, 0),
+       GATE(gmac0, "gmac0", "div200", CLKEN_OV_VAL, 14, 0, 0),
+       GATE(cs250, "cs250", "div250", CLKEN_OV_VAL, 19, 0, 0),
+       GATE(pb0_250_o, "pb0_250_o", "pb0_250", CLKEN_OV_VAL, 3, 0, 0),
+       GATE(pr0_250_o, "pr0_250_o", "pr0_250", CLKEN_OV_VAL, 4, 0, 0),
+       GATE(pr1_250_o, "pr1_250_o", "pr1_250", CLKEN_OV_VAL, 5, 0, 0),
+       GATE(b_250_o, "b_250_o", "b_250", CLKEN_OV_VAL, 9, 0, 0),
+       GATE(b_125_o, "b_125_o", "b_125", CLKEN_OV_VAL, 10, 0, 0),
+       GATE(b_200_o, "b_200_o", "b_200", CLKEN_OV_VAL, 11, 0, 0),
+       GATE(sata_o, "sata_o", "sata", CLKEN_OV_VAL, 12, 0, 0),
+       GATE(usb_o, "usb_o", "usb", CLKEN_OV_VAL, 13, 0, 0),
+       GATE(gmac0_o, "gmac0_o", "gmac", CLKEN_OV_VAL, 14, 0, 0),
+       GATE(cs250_o, "cs250_o", "cs250", CLKEN_OV_VAL, 19, 0, 0),
+};
+
+static __initdata struct of_device_id ext_clk_match[] = {
+       { .compatible = "samsung,clock-xtal", .data = (void *)0, },
+       {},
+};
+
+/* register exynos5440 clocks */
+void __init exynos5440_clk_init(struct device_node *np)
+{
+       void __iomem *reg_base;
+
+       reg_base = of_iomap(np, 0);
+       if (!reg_base) {
+               pr_err("%s: failed to map clock controller registers,"
+                       " aborting clock initialization\n", __func__);
+               return;
+       }
+
+       samsung_clk_init(np, reg_base, nr_clks, NULL, 0, NULL, 0);
+       samsung_clk_of_register_fixed_ext(exynos5440_fixed_rate_ext_clks,
+               ARRAY_SIZE(exynos5440_fixed_rate_ext_clks), ext_clk_match);
+
+       samsung_clk_register_pll2550x("cplla", "xtal", reg_base + 0x1c, 0x10);
+       samsung_clk_register_pll2550x("cpllb", "xtal", reg_base + 0x20, 0x10);
+
+       samsung_clk_register_fixed_rate(exynos5440_fixed_rate_clks,
+                       ARRAY_SIZE(exynos5440_fixed_rate_clks));
+       samsung_clk_register_fixed_factor(exynos5440_fixed_factor_clks,
+                       ARRAY_SIZE(exynos5440_fixed_factor_clks));
+       samsung_clk_register_mux(exynos5440_mux_clks,
+                       ARRAY_SIZE(exynos5440_mux_clks));
+       samsung_clk_register_div(exynos5440_div_clks,
+                       ARRAY_SIZE(exynos5440_div_clks));
+       samsung_clk_register_gate(exynos5440_gate_clks,
+                       ARRAY_SIZE(exynos5440_gate_clks));
+
+       pr_info("Exynos5440: arm_clk = %ldHz\n", _get_rate("armclk"));
+       pr_info("exynos5440 clock initialization complete\n");
+}
+CLK_OF_DECLARE(exynos5440_clk, "samsung,exynos5440-clock", exynos5440_clk_init);
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
new file mode 100644 (file)
index 0000000..89135f6
--- /dev/null
@@ -0,0 +1,419 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2013 Linaro Ltd.
+ *
+ * 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.
+ *
+ * This file contains the utility functions to register the pll clocks.
+*/
+
+#include <linux/errno.h>
+#include "clk.h"
+#include "clk-pll.h"
+
+/*
+ * PLL35xx Clock Type
+ */
+
+#define PLL35XX_MDIV_MASK       (0x3FF)
+#define PLL35XX_PDIV_MASK       (0x3F)
+#define PLL35XX_SDIV_MASK       (0x7)
+#define PLL35XX_MDIV_SHIFT      (16)
+#define PLL35XX_PDIV_SHIFT      (8)
+#define PLL35XX_SDIV_SHIFT      (0)
+
+struct samsung_clk_pll35xx {
+       struct clk_hw           hw;
+       const void __iomem      *con_reg;
+};
+
+#define to_clk_pll35xx(_hw) container_of(_hw, struct samsung_clk_pll35xx, hw)
+
+static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
+                               unsigned long parent_rate)
+{
+       struct samsung_clk_pll35xx *pll = to_clk_pll35xx(hw);
+       u32 mdiv, pdiv, sdiv, pll_con;
+       u64 fvco = parent_rate;
+
+       pll_con = __raw_readl(pll->con_reg);
+       mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
+       pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
+       sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
+
+       fvco *= mdiv;
+       do_div(fvco, (pdiv << sdiv));
+
+       return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll35xx_clk_ops = {
+       .recalc_rate = samsung_pll35xx_recalc_rate,
+};
+
+struct clk * __init samsung_clk_register_pll35xx(const char *name,
+                       const char *pname, const void __iomem *con_reg)
+{
+       struct samsung_clk_pll35xx *pll;
+       struct clk *clk;
+       struct clk_init_data init;
+
+       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+       if (!pll) {
+               pr_err("%s: could not allocate pll clk %s\n", __func__, name);
+               return NULL;
+       }
+
+       init.name = name;
+       init.ops = &samsung_pll35xx_clk_ops;
+       init.flags = CLK_GET_RATE_NOCACHE;
+       init.parent_names = &pname;
+       init.num_parents = 1;
+
+       pll->hw.init = &init;
+       pll->con_reg = con_reg;
+
+       clk = clk_register(NULL, &pll->hw);
+       if (IS_ERR(clk)) {
+               pr_err("%s: failed to register pll clock %s\n", __func__,
+                               name);
+               kfree(pll);
+       }
+
+       if (clk_register_clkdev(clk, name, NULL))
+               pr_err("%s: failed to register lookup for %s", __func__, name);
+
+       return clk;
+}
+
+/*
+ * PLL36xx Clock Type
+ */
+
+#define PLL36XX_KDIV_MASK      (0xFFFF)
+#define PLL36XX_MDIV_MASK      (0x1FF)
+#define PLL36XX_PDIV_MASK      (0x3F)
+#define PLL36XX_SDIV_MASK      (0x7)
+#define PLL36XX_MDIV_SHIFT     (16)
+#define PLL36XX_PDIV_SHIFT     (8)
+#define PLL36XX_SDIV_SHIFT     (0)
+
+struct samsung_clk_pll36xx {
+       struct clk_hw           hw;
+       const void __iomem      *con_reg;
+};
+
+#define to_clk_pll36xx(_hw) container_of(_hw, struct samsung_clk_pll36xx, hw)
+
+static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
+                               unsigned long parent_rate)
+{
+       struct samsung_clk_pll36xx *pll = to_clk_pll36xx(hw);
+       u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
+       u64 fvco = parent_rate;
+
+       pll_con0 = __raw_readl(pll->con_reg);
+       pll_con1 = __raw_readl(pll->con_reg + 4);
+       mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
+       pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
+       sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
+       kdiv = pll_con1 & PLL36XX_KDIV_MASK;
+
+       fvco *= (mdiv << 16) + kdiv;
+       do_div(fvco, (pdiv << sdiv));
+       fvco >>= 16;
+
+       return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll36xx_clk_ops = {
+       .recalc_rate = samsung_pll36xx_recalc_rate,
+};
+
+struct clk * __init samsung_clk_register_pll36xx(const char *name,
+                       const char *pname, const void __iomem *con_reg)
+{
+       struct samsung_clk_pll36xx *pll;
+       struct clk *clk;
+       struct clk_init_data init;
+
+       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+       if (!pll) {
+               pr_err("%s: could not allocate pll clk %s\n", __func__, name);
+               return NULL;
+       }
+
+       init.name = name;
+       init.ops = &samsung_pll36xx_clk_ops;
+       init.flags = CLK_GET_RATE_NOCACHE;
+       init.parent_names = &pname;
+       init.num_parents = 1;
+
+       pll->hw.init = &init;
+       pll->con_reg = con_reg;
+
+       clk = clk_register(NULL, &pll->hw);
+       if (IS_ERR(clk)) {
+               pr_err("%s: failed to register pll clock %s\n", __func__,
+                               name);
+               kfree(pll);
+       }
+
+       if (clk_register_clkdev(clk, name, NULL))
+               pr_err("%s: failed to register lookup for %s", __func__, name);
+
+       return clk;
+}
+
+/*
+ * PLL45xx Clock Type
+ */
+
+#define PLL45XX_MDIV_MASK      (0x3FF)
+#define PLL45XX_PDIV_MASK      (0x3F)
+#define PLL45XX_SDIV_MASK      (0x7)
+#define PLL45XX_MDIV_SHIFT     (16)
+#define PLL45XX_PDIV_SHIFT     (8)
+#define PLL45XX_SDIV_SHIFT     (0)
+
+struct samsung_clk_pll45xx {
+       struct clk_hw           hw;
+       enum pll45xx_type       type;
+       const void __iomem      *con_reg;
+};
+
+#define to_clk_pll45xx(_hw) container_of(_hw, struct samsung_clk_pll45xx, hw)
+
+static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
+                               unsigned long parent_rate)
+{
+       struct samsung_clk_pll45xx *pll = to_clk_pll45xx(hw);
+       u32 mdiv, pdiv, sdiv, pll_con;
+       u64 fvco = parent_rate;
+
+       pll_con = __raw_readl(pll->con_reg);
+       mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
+       pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
+       sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
+
+       if (pll->type == pll_4508)
+               sdiv = sdiv - 1;
+
+       fvco *= mdiv;
+       do_div(fvco, (pdiv << sdiv));
+
+       return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll45xx_clk_ops = {
+       .recalc_rate = samsung_pll45xx_recalc_rate,
+};
+
+struct clk * __init samsung_clk_register_pll45xx(const char *name,
+                       const char *pname, const void __iomem *con_reg,
+                       enum pll45xx_type type)
+{
+       struct samsung_clk_pll45xx *pll;
+       struct clk *clk;
+       struct clk_init_data init;
+
+       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+       if (!pll) {
+               pr_err("%s: could not allocate pll clk %s\n", __func__, name);
+               return NULL;
+       }
+
+       init.name = name;
+       init.ops = &samsung_pll45xx_clk_ops;
+       init.flags = CLK_GET_RATE_NOCACHE;
+       init.parent_names = &pname;
+       init.num_parents = 1;
+
+       pll->hw.init = &init;
+       pll->con_reg = con_reg;
+       pll->type = type;
+
+       clk = clk_register(NULL, &pll->hw);
+       if (IS_ERR(clk)) {
+               pr_err("%s: failed to register pll clock %s\n", __func__,
+                               name);
+               kfree(pll);
+       }
+
+       if (clk_register_clkdev(clk, name, NULL))
+               pr_err("%s: failed to register lookup for %s", __func__, name);
+
+       return clk;
+}
+
+/*
+ * PLL46xx Clock Type
+ */
+
+#define PLL46XX_MDIV_MASK      (0x1FF)
+#define PLL46XX_PDIV_MASK      (0x3F)
+#define PLL46XX_SDIV_MASK      (0x7)
+#define PLL46XX_MDIV_SHIFT     (16)
+#define PLL46XX_PDIV_SHIFT     (8)
+#define PLL46XX_SDIV_SHIFT     (0)
+
+#define PLL46XX_KDIV_MASK      (0xFFFF)
+#define PLL4650C_KDIV_MASK     (0xFFF)
+#define PLL46XX_KDIV_SHIFT     (0)
+
+struct samsung_clk_pll46xx {
+       struct clk_hw           hw;
+       enum pll46xx_type       type;
+       const void __iomem      *con_reg;
+};
+
+#define to_clk_pll46xx(_hw) container_of(_hw, struct samsung_clk_pll46xx, hw)
+
+static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
+                               unsigned long parent_rate)
+{
+       struct samsung_clk_pll46xx *pll = to_clk_pll46xx(hw);
+       u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift;
+       u64 fvco = parent_rate;
+
+       pll_con0 = __raw_readl(pll->con_reg);
+       pll_con1 = __raw_readl(pll->con_reg + 4);
+       mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
+       pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
+       sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
+       kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK :
+                                       pll_con1 & PLL46XX_KDIV_MASK;
+
+       shift = pll->type == pll_4600 ? 16 : 10;
+       fvco *= (mdiv << shift) + kdiv;
+       do_div(fvco, (pdiv << sdiv));
+       fvco >>= shift;
+
+       return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll46xx_clk_ops = {
+       .recalc_rate = samsung_pll46xx_recalc_rate,
+};
+
+struct clk * __init samsung_clk_register_pll46xx(const char *name,
+                       const char *pname, const void __iomem *con_reg,
+                       enum pll46xx_type type)
+{
+       struct samsung_clk_pll46xx *pll;
+       struct clk *clk;
+       struct clk_init_data init;
+
+       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+       if (!pll) {
+               pr_err("%s: could not allocate pll clk %s\n", __func__, name);
+               return NULL;
+       }
+
+       init.name = name;
+       init.ops = &samsung_pll46xx_clk_ops;
+       init.flags = CLK_GET_RATE_NOCACHE;
+       init.parent_names = &pname;
+       init.num_parents = 1;
+
+       pll->hw.init = &init;
+       pll->con_reg = con_reg;
+       pll->type = type;
+
+       clk = clk_register(NULL, &pll->hw);
+       if (IS_ERR(clk)) {
+               pr_err("%s: failed to register pll clock %s\n", __func__,
+                               name);
+               kfree(pll);
+       }
+
+       if (clk_register_clkdev(clk, name, NULL))
+               pr_err("%s: failed to register lookup for %s", __func__, name);
+
+       return clk;
+}
+
+/*
+ * PLL2550x Clock Type
+ */
+
+#define PLL2550X_R_MASK       (0x1)
+#define PLL2550X_P_MASK       (0x3F)
+#define PLL2550X_M_MASK       (0x3FF)
+#define PLL2550X_S_MASK       (0x7)
+#define PLL2550X_R_SHIFT      (20)
+#define PLL2550X_P_SHIFT      (14)
+#define PLL2550X_M_SHIFT      (4)
+#define PLL2550X_S_SHIFT      (0)
+
+struct samsung_clk_pll2550x {
+       struct clk_hw           hw;
+       const void __iomem      *reg_base;
+       unsigned long           offset;
+};
+
+#define to_clk_pll2550x(_hw) container_of(_hw, struct samsung_clk_pll2550x, hw)
+
+static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw *hw,
+                               unsigned long parent_rate)
+{
+       struct samsung_clk_pll2550x *pll = to_clk_pll2550x(hw);
+       u32 r, p, m, s, pll_stat;
+       u64 fvco = parent_rate;
+
+       pll_stat = __raw_readl(pll->reg_base + pll->offset * 3);
+       r = (pll_stat >> PLL2550X_R_SHIFT) & PLL2550X_R_MASK;
+       if (!r)
+               return 0;
+       p = (pll_stat >> PLL2550X_P_SHIFT) & PLL2550X_P_MASK;
+       m = (pll_stat >> PLL2550X_M_SHIFT) & PLL2550X_M_MASK;
+       s = (pll_stat >> PLL2550X_S_SHIFT) & PLL2550X_S_MASK;
+
+       fvco *= m;
+       do_div(fvco, (p << s));
+
+       return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll2550x_clk_ops = {
+       .recalc_rate = samsung_pll2550x_recalc_rate,
+};
+
+struct clk * __init samsung_clk_register_pll2550x(const char *name,
+                       const char *pname, const void __iomem *reg_base,
+                       const unsigned long offset)
+{
+       struct samsung_clk_pll2550x *pll;
+       struct clk *clk;
+       struct clk_init_data init;
+
+       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+       if (!pll) {
+               pr_err("%s: could not allocate pll clk %s\n", __func__, name);
+               return NULL;
+       }
+
+       init.name = name;
+       init.ops = &samsung_pll2550x_clk_ops;
+       init.flags = CLK_GET_RATE_NOCACHE;
+       init.parent_names = &pname;
+       init.num_parents = 1;
+
+       pll->hw.init = &init;
+       pll->reg_base = reg_base;
+       pll->offset = offset;
+
+       clk = clk_register(NULL, &pll->hw);
+       if (IS_ERR(clk)) {
+               pr_err("%s: failed to register pll clock %s\n", __func__,
+                               name);
+               kfree(pll);
+       }
+
+       if (clk_register_clkdev(clk, name, NULL))
+               pr_err("%s: failed to register lookup for %s", __func__, name);
+
+       return clk;
+}
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
new file mode 100644 (file)
index 0000000..f33786e
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2013 Linaro Ltd.
+ *
+ * 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.
+ *
+ * Common Clock Framework support for all PLL's in Samsung platforms
+*/
+
+#ifndef __SAMSUNG_CLK_PLL_H
+#define __SAMSUNG_CLK_PLL_H
+
+enum pll45xx_type {
+       pll_4500,
+       pll_4502,
+       pll_4508
+};
+
+enum pll46xx_type {
+       pll_4600,
+       pll_4650,
+       pll_4650c,
+};
+
+extern struct clk * __init samsung_clk_register_pll35xx(const char *name,
+                       const char *pname, const void __iomem *con_reg);
+extern struct clk * __init samsung_clk_register_pll36xx(const char *name,
+                       const char *pname, const void __iomem *con_reg);
+extern struct clk * __init samsung_clk_register_pll45xx(const char *name,
+                       const char *pname, const void __iomem *con_reg,
+                       enum pll45xx_type type);
+extern struct clk * __init samsung_clk_register_pll46xx(const char *name,
+                       const char *pname, const void __iomem *con_reg,
+                       enum pll46xx_type type);
+extern struct clk * __init samsung_clk_register_pll2550x(const char *name,
+                       const char *pname, const void __iomem *reg_base,
+                       const unsigned long offset);
+
+#endif /* __SAMSUNG_CLK_PLL_H */
diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
new file mode 100644 (file)
index 0000000..cd3c40a
--- /dev/null
@@ -0,0 +1,320 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2013 Linaro Ltd.
+ * Author: Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * 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.
+ *
+ * This file includes utility functions to register clocks to common
+ * clock framework for Samsung platforms.
+*/
+
+#include <linux/syscore_ops.h>
+#include "clk.h"
+
+static DEFINE_SPINLOCK(lock);
+static struct clk **clk_table;
+static void __iomem *reg_base;
+#ifdef CONFIG_OF
+static struct clk_onecell_data clk_data;
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+static struct samsung_clk_reg_dump *reg_dump;
+static unsigned long nr_reg_dump;
+
+static int samsung_clk_suspend(void)
+{
+       struct samsung_clk_reg_dump *rd = reg_dump;
+       unsigned long i;
+
+       for (i = 0; i < nr_reg_dump; i++, rd++)
+               rd->value = __raw_readl(reg_base + rd->offset);
+
+       return 0;
+}
+
+static void samsung_clk_resume(void)
+{
+       struct samsung_clk_reg_dump *rd = reg_dump;
+       unsigned long i;
+
+       for (i = 0; i < nr_reg_dump; i++, rd++)
+               __raw_writel(rd->value, reg_base + rd->offset);
+}
+
+static struct syscore_ops samsung_clk_syscore_ops = {
+       .suspend        = samsung_clk_suspend,
+       .resume         = samsung_clk_resume,
+};
+#endif /* CONFIG_PM_SLEEP */
+
+/* setup the essentials required to support clock lookup using ccf */
+void __init samsung_clk_init(struct device_node *np, void __iomem *base,
+               unsigned long nr_clks, unsigned long *rdump,
+               unsigned long nr_rdump, unsigned long *soc_rdump,
+               unsigned long nr_soc_rdump)
+{
+       reg_base = base;
+
+#ifdef CONFIG_PM_SLEEP
+       if (rdump && nr_rdump) {
+               unsigned int idx;
+               reg_dump = kzalloc(sizeof(struct samsung_clk_reg_dump)
+                               * (nr_rdump + nr_soc_rdump), GFP_KERNEL);
+               if (!reg_dump) {
+                       pr_err("%s: memory alloc for register dump failed\n",
+                                       __func__);
+                       return;
+               }
+
+               for (idx = 0; idx < nr_rdump; idx++)
+                       reg_dump[idx].offset = rdump[idx];
+               for (idx = 0; idx < nr_soc_rdump; idx++)
+                       reg_dump[nr_rdump + idx].offset = soc_rdump[idx];
+               nr_reg_dump = nr_rdump + nr_soc_rdump;
+               register_syscore_ops(&samsung_clk_syscore_ops);
+       }
+#endif
+
+       clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL);
+       if (!clk_table)
+               panic("could not allocate clock lookup table\n");
+
+       if (!np)
+               return;
+
+#ifdef CONFIG_OF
+       clk_data.clks = clk_table;
+       clk_data.clk_num = nr_clks;
+       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+#endif
+}
+
+/* add a clock instance to the clock lookup table used for dt based lookup */
+void samsung_clk_add_lookup(struct clk *clk, unsigned int id)
+{
+       if (clk_table && id)
+               clk_table[id] = clk;
+}
+
+/* register a list of aliases */
+void __init samsung_clk_register_alias(struct samsung_clock_alias *list,
+                                       unsigned int nr_clk)
+{
+       struct clk *clk;
+       unsigned int idx, ret;
+
+       if (!clk_table) {
+               pr_err("%s: clock table missing\n", __func__);
+               return;
+       }
+
+       for (idx = 0; idx < nr_clk; idx++, list++) {
+               if (!list->id) {
+                       pr_err("%s: clock id missing for index %d\n", __func__,
+                               idx);
+                       continue;
+               }
+
+               clk = clk_table[list->id];
+               if (!clk) {
+                       pr_err("%s: failed to find clock %d\n", __func__,
+                               list->id);
+                       continue;
+               }
+
+               ret = clk_register_clkdev(clk, list->alias, list->dev_name);
+               if (ret)
+                       pr_err("%s: failed to register lookup %s\n",
+                                       __func__, list->alias);
+       }
+}
+
+/* register a list of fixed clocks */
+void __init samsung_clk_register_fixed_rate(
+               struct samsung_fixed_rate_clock *list, unsigned int nr_clk)
+{
+       struct clk *clk;
+       unsigned int idx, ret;
+
+       for (idx = 0; idx < nr_clk; idx++, list++) {
+               clk = clk_register_fixed_rate(NULL, list->name,
+                       list->parent_name, list->flags, list->fixed_rate);
+               if (IS_ERR(clk)) {
+                       pr_err("%s: failed to register clock %s\n", __func__,
+                               list->name);
+                       continue;
+               }
+
+               samsung_clk_add_lookup(clk, list->id);
+
+               /*
+                * Unconditionally add a clock lookup for the fixed rate clocks.
+                * There are not many of these on any of Samsung platforms.
+                */
+               ret = clk_register_clkdev(clk, list->name, NULL);
+               if (ret)
+                       pr_err("%s: failed to register clock lookup for %s",
+                               __func__, list->name);
+       }
+}
+
+/* register a list of fixed factor clocks */
+void __init samsung_clk_register_fixed_factor(
+               struct samsung_fixed_factor_clock *list, unsigned int nr_clk)
+{
+       struct clk *clk;
+       unsigned int idx;
+
+       for (idx = 0; idx < nr_clk; idx++, list++) {
+               clk = clk_register_fixed_factor(NULL, list->name,
+                       list->parent_name, list->flags, list->mult, list->div);
+               if (IS_ERR(clk)) {
+                       pr_err("%s: failed to register clock %s\n", __func__,
+                               list->name);
+                       continue;
+               }
+
+               samsung_clk_add_lookup(clk, list->id);
+       }
+}
+
+/* register a list of mux clocks */
+void __init samsung_clk_register_mux(struct samsung_mux_clock *list,
+                                       unsigned int nr_clk)
+{
+       struct clk *clk;
+       unsigned int idx, ret;
+
+       for (idx = 0; idx < nr_clk; idx++, list++) {
+               clk = clk_register_mux(NULL, list->name, list->parent_names,
+                       list->num_parents, list->flags, reg_base + list->offset,
+                       list->shift, list->width, list->mux_flags, &lock);
+               if (IS_ERR(clk)) {
+                       pr_err("%s: failed to register clock %s\n", __func__,
+                               list->name);
+                       continue;
+               }
+
+               samsung_clk_add_lookup(clk, list->id);
+
+               /* register a clock lookup only if a clock alias is specified */
+               if (list->alias) {
+                       ret = clk_register_clkdev(clk, list->alias,
+                                               list->dev_name);
+                       if (ret)
+                               pr_err("%s: failed to register lookup %s\n",
+                                               __func__, list->alias);
+               }
+       }
+}
+
+/* register a list of div clocks */
+void __init samsung_clk_register_div(struct samsung_div_clock *list,
+                                       unsigned int nr_clk)
+{
+       struct clk *clk;
+       unsigned int idx, ret;
+
+       for (idx = 0; idx < nr_clk; idx++, list++) {
+               if (list->table)
+                       clk = clk_register_divider_table(NULL, list->name,
+                                       list->parent_name, list->flags,
+                                       reg_base + list->offset, list->shift,
+                                       list->width, list->div_flags,
+                                       list->table, &lock);
+               else
+                       clk = clk_register_divider(NULL, list->name,
+                                       list->parent_name, list->flags,
+                                       reg_base + list->offset, list->shift,
+                                       list->width, list->div_flags, &lock);
+               if (IS_ERR(clk)) {
+                       pr_err("%s: failed to register clock %s\n", __func__,
+                               list->name);
+                       continue;
+               }
+
+               samsung_clk_add_lookup(clk, list->id);
+
+               /* register a clock lookup only if a clock alias is specified */
+               if (list->alias) {
+                       ret = clk_register_clkdev(clk, list->alias,
+                                               list->dev_name);
+                       if (ret)
+                               pr_err("%s: failed to register lookup %s\n",
+                                               __func__, list->alias);
+               }
+       }
+}
+
+/* register a list of gate clocks */
+void __init samsung_clk_register_gate(struct samsung_gate_clock *list,
+                                               unsigned int nr_clk)
+{
+       struct clk *clk;
+       unsigned int idx, ret;
+
+       for (idx = 0; idx < nr_clk; idx++, list++) {
+               clk = clk_register_gate(NULL, list->name, list->parent_name,
+                               list->flags, reg_base + list->offset,
+                               list->bit_idx, list->gate_flags, &lock);
+               if (IS_ERR(clk)) {
+                       pr_err("%s: failed to register clock %s\n", __func__,
+                               list->name);
+                       continue;
+               }
+
+               /* register a clock lookup only if a clock alias is specified */
+               if (list->alias) {
+                       ret = clk_register_clkdev(clk, list->alias,
+                                                       list->dev_name);
+                       if (ret)
+                               pr_err("%s: failed to register lookup %s\n",
+                                       __func__, list->alias);
+               }
+
+               samsung_clk_add_lookup(clk, list->id);
+       }
+}
+
+/*
+ * obtain the clock speed of all external fixed clock sources from device
+ * tree and register it
+ */
+#ifdef CONFIG_OF
+void __init samsung_clk_of_register_fixed_ext(
+                       struct samsung_fixed_rate_clock *fixed_rate_clk,
+                       unsigned int nr_fixed_rate_clk,
+                       struct of_device_id *clk_matches)
+{
+       const struct of_device_id *match;
+       struct device_node *np;
+       u32 freq;
+
+       for_each_matching_node_and_match(np, clk_matches, &match) {
+               if (of_property_read_u32(np, "clock-frequency", &freq))
+                       continue;
+               fixed_rate_clk[(u32)match->data].fixed_rate = freq;
+       }
+       samsung_clk_register_fixed_rate(fixed_rate_clk, nr_fixed_rate_clk);
+}
+#endif
+
+/* utility function to get the rate of a specified clock */
+unsigned long _get_rate(const char *clk_name)
+{
+       struct clk *clk;
+       unsigned long rate;
+
+       clk = clk_get(NULL, clk_name);
+       if (IS_ERR(clk)) {
+               pr_err("%s: could not find clock %s\n", __func__, clk_name);
+               return 0;
+       }
+       rate = clk_get_rate(clk);
+       clk_put(clk);
+       return rate;
+}
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
new file mode 100644 (file)
index 0000000..10b2111
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2013 Linaro Ltd.
+ * Author: Thomas Abraham <thomas.ab@samsung.com>
+ *
+ * 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.
+ *
+ * Common Clock Framework support for all Samsung platforms
+*/
+
+#ifndef __SAMSUNG_CLK_H
+#define __SAMSUNG_CLK_H
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <mach/map.h>
+
+/**
+ * struct samsung_clock_alias: information about mux clock
+ * @id: platform specific id of the clock.
+ * @dev_name: name of the device to which this clock belongs.
+ * @alias: optional clock alias name to be assigned to this clock.
+ */
+struct samsung_clock_alias {
+       unsigned int            id;
+       const char              *dev_name;
+       const char              *alias;
+};
+
+#define ALIAS(_id, dname, a)   \
+       {                                                       \
+               .id             = _id,                          \
+               .dev_name       = dname,                        \
+               .alias          = a,                            \
+       }
+
+/**
+ * struct samsung_fixed_rate_clock: information about fixed-rate clock
+ * @id: platform specific id of the clock.
+ * @name: name of this fixed-rate clock.
+ * @parent_name: optional parent clock name.
+ * @flags: optional fixed-rate clock flags.
+ * @fixed-rate: fixed clock rate of this clock.
+ */
+struct samsung_fixed_rate_clock {
+       unsigned int            id;
+       char                    *name;
+       const char              *parent_name;
+       unsigned long           flags;
+       unsigned long           fixed_rate;
+};
+
+#define FRATE(_id, cname, pname, f, frate)             \
+       {                                               \
+               .id             = _id,                  \
+               .name           = cname,                \
+               .parent_name    = pname,                \
+               .flags          = f,                    \
+               .fixed_rate     = frate,                \
+       }
+
+/*
+ * struct samsung_fixed_factor_clock: information about fixed-factor clock
+ * @id: platform specific id of the clock.
+ * @name: name of this fixed-factor clock.
+ * @parent_name: parent clock name.
+ * @mult: fixed multiplication factor.
+ * @div: fixed division factor.
+ * @flags: optional fixed-factor clock flags.
+ */
+struct samsung_fixed_factor_clock {
+       unsigned int            id;
+       char                    *name;
+       const char              *parent_name;
+       unsigned long           mult;
+       unsigned long           div;
+       unsigned long           flags;
+};
+
+#define FFACTOR(_id, cname, pname, m, d, f)            \
+       {                                               \
+               .id             = _id,                  \
+               .name           = cname,                \
+               .parent_name    = pname,                \
+               .mult           = m,                    \
+               .div            = d,                    \
+               .flags          = f,                    \
+       }
+
+/**
+ * struct samsung_mux_clock: information about mux clock
+ * @id: platform specific id of the clock.
+ * @dev_name: name of the device to which this clock belongs.
+ * @name: name of this mux clock.
+ * @parent_names: array of pointer to parent clock names.
+ * @num_parents: number of parents listed in @parent_names.
+ * @flags: optional flags for basic clock.
+ * @offset: offset of the register for configuring the mux.
+ * @shift: starting bit location of the mux control bit-field in @reg.
+ * @width: width of the mux control bit-field in @reg.
+ * @mux_flags: flags for mux-type clock.
+ * @alias: optional clock alias name to be assigned to this clock.
+ */
+struct samsung_mux_clock {
+       unsigned int            id;
+       const char              *dev_name;
+       const char              *name;
+       const char              **parent_names;
+       u8                      num_parents;
+       unsigned long           flags;
+       unsigned long           offset;
+       u8                      shift;
+       u8                      width;
+       u8                      mux_flags;
+       const char              *alias;
+};
+
+#define __MUX(_id, dname, cname, pnames, o, s, w, f, mf, a)    \
+       {                                                       \
+               .id             = _id,                          \
+               .dev_name       = dname,                        \
+               .name           = cname,                        \
+               .parent_names   = pnames,                       \
+               .num_parents    = ARRAY_SIZE(pnames),           \
+               .flags          = f,                            \
+               .offset         = o,                            \
+               .shift          = s,                            \
+               .width          = w,                            \
+               .mux_flags      = mf,                           \
+               .alias          = a,                            \
+       }
+
+#define MUX(_id, cname, pnames, o, s, w)                       \
+       __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, NULL)
+
+#define MUX_A(_id, cname, pnames, o, s, w, a)                  \
+       __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, a)
+
+#define MUX_F(_id, cname, pnames, o, s, w, f, mf)              \
+       __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, NULL)
+
+/**
+ * @id: platform specific id of the clock.
+ * struct samsung_div_clock: information about div clock
+ * @dev_name: name of the device to which this clock belongs.
+ * @name: name of this div clock.
+ * @parent_name: name of the parent clock.
+ * @flags: optional flags for basic clock.
+ * @offset: offset of the register for configuring the div.
+ * @shift: starting bit location of the div control bit-field in @reg.
+ * @div_flags: flags for div-type clock.
+ * @alias: optional clock alias name to be assigned to this clock.
+ */
+struct samsung_div_clock {
+       unsigned int            id;
+       const char              *dev_name;
+       const char              *name;
+       const char              *parent_name;
+       unsigned long           flags;
+       unsigned long           offset;
+       u8                      shift;
+       u8                      width;
+       u8                      div_flags;
+       const char              *alias;
+       struct clk_div_table    *table;
+};
+
+#define __DIV(_id, dname, cname, pname, o, s, w, f, df, a, t)  \
+       {                                                       \
+               .id             = _id,                          \
+               .dev_name       = dname,                        \
+               .name           = cname,                        \
+               .parent_name    = pname,                        \
+               .flags          = f,                            \
+               .offset         = o,                            \
+               .shift          = s,                            \
+               .width          = w,                            \
+               .div_flags      = df,                           \
+               .alias          = a,                            \
+               .table          = t,                            \
+       }
+
+#define DIV(_id, cname, pname, o, s, w)                                \
+       __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL, NULL)
+
+#define DIV_A(_id, cname, pname, o, s, w, a)                   \
+       __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, a, NULL)
+
+#define DIV_F(_id, cname, pname, o, s, w, f, df)               \
+       __DIV(_id, NULL, cname, pname, o, s, w, f, df, NULL, NULL)
+
+#define DIV_T(_id, cname, pname, o, s, w, t)                   \
+       __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL, t)
+
+/**
+ * struct samsung_gate_clock: information about gate clock
+ * @id: platform specific id of the clock.
+ * @dev_name: name of the device to which this clock belongs.
+ * @name: name of this gate clock.
+ * @parent_name: name of the parent clock.
+ * @flags: optional flags for basic clock.
+ * @offset: offset of the register for configuring the gate.
+ * @bit_idx: bit index of the gate control bit-field in @reg.
+ * @gate_flags: flags for gate-type clock.
+ * @alias: optional clock alias name to be assigned to this clock.
+ */
+struct samsung_gate_clock {
+       unsigned int            id;
+       const char              *dev_name;
+       const char              *name;
+       const char              *parent_name;
+       unsigned long           flags;
+       unsigned long           offset;
+       u8                      bit_idx;
+       u8                      gate_flags;
+       const char              *alias;
+};
+
+#define __GATE(_id, dname, cname, pname, o, b, f, gf, a)       \
+       {                                                       \
+               .id             = _id,                          \
+               .dev_name       = dname,                        \
+               .name           = cname,                        \
+               .parent_name    = pname,                        \
+               .flags          = f,                            \
+               .offset         = o,                            \
+               .bit_idx        = b,                            \
+               .gate_flags     = gf,                           \
+               .alias          = a,                            \
+       }
+
+#define GATE(_id, cname, pname, o, b, f, gf)                   \
+       __GATE(_id, NULL, cname, pname, o, b, f, gf, NULL)
+
+#define GATE_A(_id, cname, pname, o, b, f, gf, a)              \
+       __GATE(_id, NULL, cname, pname, o, b, f, gf, a)
+
+#define GATE_D(_id, dname, cname, pname, o, b, f, gf)          \
+       __GATE(_id, dname, cname, pname, o, b, f, gf, NULL)
+
+#define GATE_DA(_id, dname, cname, pname, o, b, f, gf, a)      \
+       __GATE(_id, dname, cname, pname, o, b, f, gf, a)
+
+#define PNAME(x) static const char *x[] __initdata
+
+/**
+ * struct samsung_clk_reg_dump: register dump of clock controller registers.
+ * @offset: clock register offset from the controller base address.
+ * @value: the value to be register at offset.
+ */
+struct samsung_clk_reg_dump {
+       u32     offset;
+       u32     value;
+};
+
+extern void __init samsung_clk_init(struct device_node *np, void __iomem *base,
+               unsigned long nr_clks, unsigned long *rdump,
+               unsigned long nr_rdump, unsigned long *soc_rdump,
+               unsigned long nr_soc_rdump);
+extern void __init samsung_clk_of_register_fixed_ext(
+               struct samsung_fixed_rate_clock *fixed_rate_clk,
+               unsigned int nr_fixed_rate_clk,
+               struct of_device_id *clk_matches);
+
+extern void samsung_clk_add_lookup(struct clk *clk, unsigned int id);
+
+extern void samsung_clk_register_alias(struct samsung_clock_alias *list,
+               unsigned int nr_clk);
+extern void __init samsung_clk_register_fixed_rate(
+               struct samsung_fixed_rate_clock *clk_list, unsigned int nr_clk);
+extern void __init samsung_clk_register_fixed_factor(
+               struct samsung_fixed_factor_clock *list, unsigned int nr_clk);
+extern void __init samsung_clk_register_mux(struct samsung_mux_clock *clk_list,
+               unsigned int nr_clk);
+extern void __init samsung_clk_register_div(struct samsung_div_clock *clk_list,
+               unsigned int nr_clk);
+extern void __init samsung_clk_register_gate(
+               struct samsung_gate_clock *clk_list, unsigned int nr_clk);
+
+extern unsigned long _get_rate(const char *clk_name);
+
+#endif /* __SAMSUNG_CLK_H */
index 82abea366b785d15f9d138885e240822d29762fb..35e7e2698e100fad879337e1b44823edfddb7a18 100644 (file)
@@ -960,47 +960,47 @@ void __init spear1340_clk_init(void)
                        SPEAR1340_SPDIF_IN_CLK_ENB, 0, &_lock);
        clk_register_clkdev(clk, NULL, "d0100000.spdif-in");
 
-       clk = clk_register_gate(NULL, "acp_clk", "acp_mclk", 0,
+       clk = clk_register_gate(NULL, "acp_clk", "ahb_clk", 0,
                        SPEAR1340_PERIP2_CLK_ENB, SPEAR1340_ACP_CLK_ENB, 0,
                        &_lock);
        clk_register_clkdev(clk, NULL, "acp_clk");
 
-       clk = clk_register_gate(NULL, "plgpio_clk", "plgpio_mclk", 0,
+       clk = clk_register_gate(NULL, "plgpio_clk", "ahb_clk", 0,
                        SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_PLGPIO_CLK_ENB, 0,
                        &_lock);
        clk_register_clkdev(clk, NULL, "e2800000.gpio");
 
-       clk = clk_register_gate(NULL, "video_dec_clk", "video_dec_mclk", 0,
+       clk = clk_register_gate(NULL, "video_dec_clk", "ahb_clk", 0,
                        SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_DEC_CLK_ENB,
                        0, &_lock);
        clk_register_clkdev(clk, NULL, "video_dec");
 
-       clk = clk_register_gate(NULL, "video_enc_clk", "video_enc_mclk", 0,
+       clk = clk_register_gate(NULL, "video_enc_clk", "ahb_clk", 0,
                        SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_ENC_CLK_ENB,
                        0, &_lock);
        clk_register_clkdev(clk, NULL, "video_enc");
 
-       clk = clk_register_gate(NULL, "video_in_clk", "video_in_mclk", 0,
+       clk = clk_register_gate(NULL, "video_in_clk", "ahb_clk", 0,
                        SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_VIDEO_IN_CLK_ENB, 0,
                        &_lock);
        clk_register_clkdev(clk, NULL, "spear_vip");
 
-       clk = clk_register_gate(NULL, "cam0_clk", "cam0_mclk", 0,
+       clk = clk_register_gate(NULL, "cam0_clk", "ahb_clk", 0,
                        SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM0_CLK_ENB, 0,
                        &_lock);
        clk_register_clkdev(clk, NULL, "d0200000.cam0");
 
-       clk = clk_register_gate(NULL, "cam1_clk", "cam1_mclk", 0,
+       clk = clk_register_gate(NULL, "cam1_clk", "ahb_clk", 0,
                        SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM1_CLK_ENB, 0,
                        &_lock);
        clk_register_clkdev(clk, NULL, "d0300000.cam1");
 
-       clk = clk_register_gate(NULL, "cam2_clk", "cam2_mclk", 0,
+       clk = clk_register_gate(NULL, "cam2_clk", "ahb_clk", 0,
                        SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM2_CLK_ENB, 0,
                        &_lock);
        clk_register_clkdev(clk, NULL, "d0400000.cam2");
 
-       clk = clk_register_gate(NULL, "cam3_clk", "cam3_mclk", 0,
+       clk = clk_register_gate(NULL, "cam3_clk", "ahb_clk", 0,
                        SPEAR1340_PERIP3_CLK_ENB, SPEAR1340_CAM3_CLK_ENB, 0,
                        &_lock);
        clk_register_clkdev(clk, NULL, "d0500000.cam3");
diff --git a/drivers/clk/sunxi/Makefile b/drivers/clk/sunxi/Makefile
new file mode 100644 (file)
index 0000000..b5bac91
--- /dev/null
@@ -0,0 +1,5 @@
+#
+# Makefile for sunxi specific clk
+#
+
+obj-y += clk-sunxi.o clk-factors.o
diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c
new file mode 100644 (file)
index 0000000..88523f9
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2013 Emilio López <emilio@elopez.com.ar>
+ *
+ * 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.
+ *
+ * Adjustable factor-based clock implementation
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/string.h>
+
+#include <linux/delay.h>
+
+#include "clk-factors.h"
+
+/*
+ * DOC: basic adjustable factor-based clock that cannot gate
+ *
+ * Traits of this clock:
+ * prepare - clk_prepare only ensures that parents are prepared
+ * enable - clk_enable only ensures that parents are enabled
+ * rate - rate is adjustable.
+ *        clk->rate = (parent->rate * N * (K + 1) >> P) / (M + 1)
+ * parent - fixed parent.  No clk_set_parent support
+ */
+
+struct clk_factors {
+       struct clk_hw hw;
+       void __iomem *reg;
+       struct clk_factors_config *config;
+       void (*get_factors) (u32 *rate, u32 parent, u8 *n, u8 *k, u8 *m, u8 *p);
+       spinlock_t *lock;
+};
+
+#define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw)
+
+#define SETMASK(len, pos)              (((-1U) >> (31-len))  << (pos))
+#define CLRMASK(len, pos)              (~(SETMASK(len, pos)))
+#define FACTOR_GET(bit, len, reg)      (((reg) & SETMASK(len, bit)) >> (bit))
+
+#define FACTOR_SET(bit, len, reg, val) \
+       (((reg) & CLRMASK(len, bit)) | (val << (bit)))
+
+static unsigned long clk_factors_recalc_rate(struct clk_hw *hw,
+                                            unsigned long parent_rate)
+{
+       u8 n = 1, k = 0, p = 0, m = 0;
+       u32 reg;
+       unsigned long rate;
+       struct clk_factors *factors = to_clk_factors(hw);
+       struct clk_factors_config *config = factors->config;
+
+       /* Fetch the register value */
+       reg = readl(factors->reg);
+
+       /* Get each individual factor if applicable */
+       if (config->nwidth != SUNXI_FACTORS_NOT_APPLICABLE)
+               n = FACTOR_GET(config->nshift, config->nwidth, reg);
+       if (config->kwidth != SUNXI_FACTORS_NOT_APPLICABLE)
+               k = FACTOR_GET(config->kshift, config->kwidth, reg);
+       if (config->mwidth != SUNXI_FACTORS_NOT_APPLICABLE)
+               m = FACTOR_GET(config->mshift, config->mwidth, reg);
+       if (config->pwidth != SUNXI_FACTORS_NOT_APPLICABLE)
+               p = FACTOR_GET(config->pshift, config->pwidth, reg);
+
+       /* Calculate the rate */
+       rate = (parent_rate * n * (k + 1) >> p) / (m + 1);
+
+       return rate;
+}
+
+static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate,
+                                  unsigned long *parent_rate)
+{
+       struct clk_factors *factors = to_clk_factors(hw);
+       factors->get_factors((u32 *)&rate, (u32)*parent_rate,
+                            NULL, NULL, NULL, NULL);
+
+       return rate;
+}
+
+static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long parent_rate)
+{
+       u8 n, k, m, p;
+       u32 reg;
+       struct clk_factors *factors = to_clk_factors(hw);
+       struct clk_factors_config *config = factors->config;
+       unsigned long flags = 0;
+
+       factors->get_factors((u32 *)&rate, (u32)parent_rate, &n, &k, &m, &p);
+
+       if (factors->lock)
+               spin_lock_irqsave(factors->lock, flags);
+
+       /* Fetch the register value */
+       reg = readl(factors->reg);
+
+       /* Set up the new factors - macros do not do anything if width is 0 */
+       reg = FACTOR_SET(config->nshift, config->nwidth, reg, n);
+       reg = FACTOR_SET(config->kshift, config->kwidth, reg, k);
+       reg = FACTOR_SET(config->mshift, config->mwidth, reg, m);
+       reg = FACTOR_SET(config->pshift, config->pwidth, reg, p);
+
+       /* Apply them now */
+       writel(reg, factors->reg);
+
+       /* delay 500us so pll stabilizes */
+       __delay((rate >> 20) * 500 / 2);
+
+       if (factors->lock)
+               spin_unlock_irqrestore(factors->lock, flags);
+
+       return 0;
+}
+
+static const struct clk_ops clk_factors_ops = {
+       .recalc_rate = clk_factors_recalc_rate,
+       .round_rate = clk_factors_round_rate,
+       .set_rate = clk_factors_set_rate,
+};
+
+/**
+ * clk_register_factors - register a factors clock with
+ * the clock framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @reg: register address to adjust factors
+ * @config: shift and width of factors n, k, m and p
+ * @get_factors: function to calculate the factors for a given frequency
+ * @lock: shared register lock for this clock
+ */
+struct clk *clk_register_factors(struct device *dev, const char *name,
+                                const char *parent_name,
+                                unsigned long flags, void __iomem *reg,
+                                struct clk_factors_config *config,
+                                void (*get_factors)(u32 *rate, u32 parent,
+                                                    u8 *n, u8 *k, u8 *m, u8 *p),
+                                spinlock_t *lock)
+{
+       struct clk_factors *factors;
+       struct clk *clk;
+       struct clk_init_data init;
+
+       /* allocate the factors */
+       factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL);
+       if (!factors) {
+               pr_err("%s: could not allocate factors clk\n", __func__);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       init.name = name;
+       init.ops = &clk_factors_ops;
+       init.flags = flags;
+       init.parent_names = (parent_name ? &parent_name : NULL);
+       init.num_parents = (parent_name ? 1 : 0);
+
+       /* struct clk_factors assignments */
+       factors->reg = reg;
+       factors->config = config;
+       factors->lock = lock;
+       factors->hw.init = &init;
+       factors->get_factors = get_factors;
+
+       /* register the clock */
+       clk = clk_register(dev, &factors->hw);
+
+       if (IS_ERR(clk))
+               kfree(factors);
+
+       return clk;
+}
diff --git a/drivers/clk/sunxi/clk-factors.h b/drivers/clk/sunxi/clk-factors.h
new file mode 100644 (file)
index 0000000..f49851c
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef __MACH_SUNXI_CLK_FACTORS_H
+#define __MACH_SUNXI_CLK_FACTORS_H
+
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+
+#define SUNXI_FACTORS_NOT_APPLICABLE   (0)
+
+struct clk_factors_config {
+       u8 nshift;
+       u8 nwidth;
+       u8 kshift;
+       u8 kwidth;
+       u8 mshift;
+       u8 mwidth;
+       u8 pshift;
+       u8 pwidth;
+};
+
+struct clk *clk_register_factors(struct device *dev, const char *name,
+                                const char *parent_name,
+                                unsigned long flags, void __iomem *reg,
+                                struct clk_factors_config *config,
+                                void (*get_factors) (u32 *rate, u32 parent_rate,
+                                                     u8 *n, u8 *k, u8 *m, u8 *p),
+                                spinlock_t *lock);
+#endif
diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
new file mode 100644 (file)
index 0000000..d528a24
--- /dev/null
@@ -0,0 +1,362 @@
+/*
+ * Copyright 2013 Emilio López
+ *
+ * Emilio López <emilio@elopez.com.ar>
+ *
+ * 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/clkdev.h>
+#include <linux/clk/sunxi.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include "clk-factors.h"
+
+static DEFINE_SPINLOCK(clk_lock);
+
+/**
+ * sunxi_osc_clk_setup() - Setup function for gatable oscillator
+ */
+
+#define SUNXI_OSC24M_GATE      0
+
+static void __init sunxi_osc_clk_setup(struct device_node *node)
+{
+       struct clk *clk;
+       const char *clk_name = node->name;
+       const char *parent;
+       void *reg;
+
+       reg = of_iomap(node, 0);
+
+       parent = of_clk_get_parent_name(node, 0);
+
+       clk = clk_register_gate(NULL, clk_name, parent, CLK_IGNORE_UNUSED,
+                               reg, SUNXI_OSC24M_GATE, 0, &clk_lock);
+
+       if (clk) {
+               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+               clk_register_clkdev(clk, clk_name, NULL);
+       }
+}
+
+
+
+/**
+ * sunxi_get_pll1_factors() - calculates n, k, m, p factors for PLL1
+ * PLL1 rate is calculated as follows
+ * rate = (parent_rate * n * (k + 1) >> p) / (m + 1);
+ * parent_rate is always 24Mhz
+ */
+
+static void sunxi_get_pll1_factors(u32 *freq, u32 parent_rate,
+                                  u8 *n, u8 *k, u8 *m, u8 *p)
+{
+       u8 div;
+
+       /* Normalize value to a 6M multiple */
+       div = *freq / 6000000;
+       *freq = 6000000 * div;
+
+       /* we were called to round the frequency, we can now return */
+       if (n == NULL)
+               return;
+
+       /* m is always zero for pll1 */
+       *m = 0;
+
+       /* k is 1 only on these cases */
+       if (*freq >= 768000000 || *freq == 42000000 || *freq == 54000000)
+               *k = 1;
+       else
+               *k = 0;
+
+       /* p will be 3 for divs under 10 */
+       if (div < 10)
+               *p = 3;
+
+       /* p will be 2 for divs between 10 - 20 and odd divs under 32 */
+       else if (div < 20 || (div < 32 && (div & 1)))
+               *p = 2;
+
+       /* p will be 1 for even divs under 32, divs under 40 and odd pairs
+        * of divs between 40-62 */
+       else if (div < 40 || (div < 64 && (div & 2)))
+               *p = 1;
+
+       /* any other entries have p = 0 */
+       else
+               *p = 0;
+
+       /* calculate a suitable n based on k and p */
+       div <<= *p;
+       div /= (*k + 1);
+       *n = div / 4;
+}
+
+
+
+/**
+ * sunxi_get_apb1_factors() - calculates m, p factors for APB1
+ * APB1 rate is calculated as follows
+ * rate = (parent_rate >> p) / (m + 1);
+ */
+
+static void sunxi_get_apb1_factors(u32 *freq, u32 parent_rate,
+                                  u8 *n, u8 *k, u8 *m, u8 *p)
+{
+       u8 calcm, calcp;
+
+       if (parent_rate < *freq)
+               *freq = parent_rate;
+
+       parent_rate = (parent_rate + (*freq - 1)) / *freq;
+
+       /* Invalid rate! */
+       if (parent_rate > 32)
+               return;
+
+       if (parent_rate <= 4)
+               calcp = 0;
+       else if (parent_rate <= 8)
+               calcp = 1;
+       else if (parent_rate <= 16)
+               calcp = 2;
+       else
+               calcp = 3;
+
+       calcm = (parent_rate >> calcp) - 1;
+
+       *freq = (parent_rate >> calcp) / (calcm + 1);
+
+       /* we were called to round the frequency, we can now return */
+       if (n == NULL)
+               return;
+
+       *m = calcm;
+       *p = calcp;
+}
+
+
+
+/**
+ * sunxi_factors_clk_setup() - Setup function for factor clocks
+ */
+
+struct factors_data {
+       struct clk_factors_config *table;
+       void (*getter) (u32 *rate, u32 parent_rate, u8 *n, u8 *k, u8 *m, u8 *p);
+};
+
+static struct clk_factors_config pll1_config = {
+       .nshift = 8,
+       .nwidth = 5,
+       .kshift = 4,
+       .kwidth = 2,
+       .mshift = 0,
+       .mwidth = 2,
+       .pshift = 16,
+       .pwidth = 2,
+};
+
+static struct clk_factors_config apb1_config = {
+       .mshift = 0,
+       .mwidth = 5,
+       .pshift = 16,
+       .pwidth = 2,
+};
+
+static const __initconst struct factors_data pll1_data = {
+       .table = &pll1_config,
+       .getter = sunxi_get_pll1_factors,
+};
+
+static const __initconst struct factors_data apb1_data = {
+       .table = &apb1_config,
+       .getter = sunxi_get_apb1_factors,
+};
+
+static void __init sunxi_factors_clk_setup(struct device_node *node,
+                                          struct factors_data *data)
+{
+       struct clk *clk;
+       const char *clk_name = node->name;
+       const char *parent;
+       void *reg;
+
+       reg = of_iomap(node, 0);
+
+       parent = of_clk_get_parent_name(node, 0);
+
+       clk = clk_register_factors(NULL, clk_name, parent, CLK_IGNORE_UNUSED,
+                                  reg, data->table, data->getter, &clk_lock);
+
+       if (clk) {
+               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+               clk_register_clkdev(clk, clk_name, NULL);
+       }
+}
+
+
+
+/**
+ * sunxi_mux_clk_setup() - Setup function for muxes
+ */
+
+#define SUNXI_MUX_GATE_WIDTH   2
+
+struct mux_data {
+       u8 shift;
+};
+
+static const __initconst struct mux_data cpu_data = {
+       .shift = 16,
+};
+
+static const __initconst struct mux_data apb1_mux_data = {
+       .shift = 24,
+};
+
+static void __init sunxi_mux_clk_setup(struct device_node *node,
+                                      struct mux_data *data)
+{
+       struct clk *clk;
+       const char *clk_name = node->name;
+       const char **parents = kmalloc(sizeof(char *) * 5, GFP_KERNEL);
+       void *reg;
+       int i = 0;
+
+       reg = of_iomap(node, 0);
+
+       while (i < 5 && (parents[i] = of_clk_get_parent_name(node, i)) != NULL)
+               i++;
+
+       clk = clk_register_mux(NULL, clk_name, parents, i, 0, reg,
+                              data->shift, SUNXI_MUX_GATE_WIDTH,
+                              0, &clk_lock);
+
+       if (clk) {
+               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+               clk_register_clkdev(clk, clk_name, NULL);
+       }
+}
+
+
+
+/**
+ * sunxi_divider_clk_setup() - Setup function for simple divider clocks
+ */
+
+#define SUNXI_DIVISOR_WIDTH    2
+
+struct div_data {
+       u8 shift;
+       u8 pow;
+};
+
+static const __initconst struct div_data axi_data = {
+       .shift = 0,
+       .pow = 0,
+};
+
+static const __initconst struct div_data ahb_data = {
+       .shift = 4,
+       .pow = 1,
+};
+
+static const __initconst struct div_data apb0_data = {
+       .shift = 8,
+       .pow = 1,
+};
+
+static void __init sunxi_divider_clk_setup(struct device_node *node,
+                                          struct div_data *data)
+{
+       struct clk *clk;
+       const char *clk_name = node->name;
+       const char *clk_parent;
+       void *reg;
+
+       reg = of_iomap(node, 0);
+
+       clk_parent = of_clk_get_parent_name(node, 0);
+
+       clk = clk_register_divider(NULL, clk_name, clk_parent, 0,
+                                  reg, data->shift, SUNXI_DIVISOR_WIDTH,
+                                  data->pow ? CLK_DIVIDER_POWER_OF_TWO : 0,
+                                  &clk_lock);
+       if (clk) {
+               of_clk_add_provider(node, of_clk_src_simple_get, clk);
+               clk_register_clkdev(clk, clk_name, NULL);
+       }
+}
+
+
+/* Matches for of_clk_init */
+static const __initconst struct of_device_id clk_match[] = {
+       {.compatible = "fixed-clock", .data = of_fixed_clk_setup,},
+       {.compatible = "allwinner,sun4i-osc-clk", .data = sunxi_osc_clk_setup,},
+       {}
+};
+
+/* Matches for factors clocks */
+static const __initconst struct of_device_id clk_factors_match[] = {
+       {.compatible = "allwinner,sun4i-pll1-clk", .data = &pll1_data,},
+       {.compatible = "allwinner,sun4i-apb1-clk", .data = &apb1_data,},
+       {}
+};
+
+/* Matches for divider clocks */
+static const __initconst struct of_device_id clk_div_match[] = {
+       {.compatible = "allwinner,sun4i-axi-clk", .data = &axi_data,},
+       {.compatible = "allwinner,sun4i-ahb-clk", .data = &ahb_data,},
+       {.compatible = "allwinner,sun4i-apb0-clk", .data = &apb0_data,},
+       {}
+};
+
+/* Matches for mux clocks */
+static const __initconst struct of_device_id clk_mux_match[] = {
+       {.compatible = "allwinner,sun4i-cpu-clk", .data = &cpu_data,},
+       {.compatible = "allwinner,sun4i-apb1-mux-clk", .data = &apb1_mux_data,},
+       {}
+};
+
+static void __init of_sunxi_table_clock_setup(const struct of_device_id *clk_match,
+                                             void *function)
+{
+       struct device_node *np;
+       const struct div_data *data;
+       const struct of_device_id *match;
+       void (*setup_function)(struct device_node *, const void *) = function;
+
+       for_each_matching_node(np, clk_match) {
+               match = of_match_node(clk_match, np);
+               data = match->data;
+               setup_function(np, data);
+       }
+}
+
+void __init sunxi_init_clocks(void)
+{
+       /* Register all the simple sunxi clocks on DT */
+       of_clk_init(clk_match);
+
+       /* Register factor clocks */
+       of_sunxi_table_clock_setup(clk_factors_match, sunxi_factors_clk_setup);
+
+       /* Register divider clocks */
+       of_sunxi_table_clock_setup(clk_div_match, sunxi_divider_clk_setup);
+
+       /* Register mux clocks */
+       of_sunxi_table_clock_setup(clk_mux_match, sunxi_mux_clk_setup);
+}
index 2b41b0f4f731b577df9bac3b147865a06657bd2c..f49fac2d193acf662856fc74e5acd1d668b2cc84 100644 (file)
@@ -9,3 +9,4 @@ obj-y                                   += clk-super.o
 
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += clk-tegra20.o
 obj-$(CONFIG_ARCH_TEGRA_3x_SOC)         += clk-tegra30.o
+obj-$(CONFIG_ARCH_TEGRA_114_SOC)       += clk-tegra114.o
index 6dd533251e7b103255e8edb2bb0cc87cfa60ca97..bafee9895a247905d56ebe94c6a972eb7527c1c8 100644 (file)
@@ -41,7 +41,9 @@ static DEFINE_SPINLOCK(periph_ref_lock);
 #define write_rst_clr(val, gate) \
        writel_relaxed(val, gate->clk_base + (gate->regs->rst_clr_reg))
 
-#define periph_clk_to_bit(periph) (1 << (gate->clk_num % 32))
+#define periph_clk_to_bit(gate) (1 << (gate->clk_num % 32))
+
+#define LVL2_CLK_GATE_OVRE 0x554
 
 /* Peripheral gate clock ops */
 static int clk_periph_is_enabled(struct clk_hw *hw)
@@ -83,6 +85,13 @@ static int clk_periph_enable(struct clk_hw *hw)
                }
        }
 
+       if (gate->flags & TEGRA_PERIPH_WAR_1005168) {
+               writel_relaxed(0, gate->clk_base + LVL2_CLK_GATE_OVRE);
+               writel_relaxed(BIT(22), gate->clk_base + LVL2_CLK_GATE_OVRE);
+               udelay(1);
+               writel_relaxed(0, gate->clk_base + LVL2_CLK_GATE_OVRE);
+       }
+
        spin_unlock_irqrestore(&periph_ref_lock, flags);
 
        return 0;
index 788486e6331a0f10fa99984f8f1b0581dfb90635..b2309d37a9637b70cfc823ea3ada7dc32d99c88a 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
+#include <linux/export.h>
 #include <linux/slab.h>
 #include <linux/err.h>
 
@@ -128,6 +129,7 @@ void tegra_periph_reset_deassert(struct clk *c)
 
        tegra_periph_reset(gate, 0);
 }
+EXPORT_SYMBOL(tegra_periph_reset_deassert);
 
 void tegra_periph_reset_assert(struct clk *c)
 {
@@ -147,6 +149,7 @@ void tegra_periph_reset_assert(struct clk *c)
 
        tegra_periph_reset(gate, 1);
 }
+EXPORT_SYMBOL(tegra_periph_reset_assert);
 
 const struct clk_ops tegra_clk_periph_ops = {
        .get_parent = clk_periph_get_parent,
@@ -170,14 +173,15 @@ const struct clk_ops tegra_clk_periph_nodiv_ops = {
 static struct clk *_tegra_clk_register_periph(const char *name,
                        const char **parent_names, int num_parents,
                        struct tegra_clk_periph *periph,
-                       void __iomem *clk_base, u32 offset, bool div)
+                       void __iomem *clk_base, u32 offset, bool div,
+                       unsigned long flags)
 {
        struct clk *clk;
        struct clk_init_data init;
 
        init.name = name;
        init.ops = div ? &tegra_clk_periph_ops : &tegra_clk_periph_nodiv_ops;
-       init.flags = div ? 0 : CLK_SET_RATE_PARENT;
+       init.flags = flags;
        init.parent_names = parent_names;
        init.num_parents = num_parents;
 
@@ -202,10 +206,10 @@ static struct clk *_tegra_clk_register_periph(const char *name,
 struct clk *tegra_clk_register_periph(const char *name,
                const char **parent_names, int num_parents,
                struct tegra_clk_periph *periph, void __iomem *clk_base,
-               u32 offset)
+               u32 offset, unsigned long flags)
 {
        return _tegra_clk_register_periph(name, parent_names, num_parents,
-                       periph, clk_base, offset, true);
+                       periph, clk_base, offset, true, flags);
 }
 
 struct clk *tegra_clk_register_periph_nodiv(const char *name,
@@ -214,5 +218,5 @@ struct clk *tegra_clk_register_periph_nodiv(const char *name,
                u32 offset)
 {
        return _tegra_clk_register_periph(name, parent_names, num_parents,
-                       periph, clk_base, offset, false);
+                       periph, clk_base, offset, false, CLK_SET_RATE_PARENT);
 }
index 165f24734c1b7342a41e705a3505d520958bb345..17c2cc086eb4e997034d6f2348956cf6f856582b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (c) 2012, 2013, NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms and conditions of the GNU General Public License,
 #define PLLE_SS_CTRL 0x68
 #define PLLE_SS_DISABLE (7 << 10)
 
+#define PLLE_AUX_PLLP_SEL      BIT(2)
+#define PLLE_AUX_ENABLE_SWCTL  BIT(4)
+#define PLLE_AUX_SEQ_ENABLE    BIT(24)
+#define PLLE_AUX_PLLRE_SEL     BIT(28)
+
+#define PLLE_MISC_PLLE_PTS     BIT(8)
+#define PLLE_MISC_IDDQ_SW_VALUE        BIT(13)
+#define PLLE_MISC_IDDQ_SW_CTRL BIT(14)
+#define PLLE_MISC_VREG_BG_CTRL_SHIFT   4
+#define PLLE_MISC_VREG_BG_CTRL_MASK    (3 << PLLE_MISC_VREG_BG_CTRL_SHIFT)
+#define PLLE_MISC_VREG_CTRL_SHIFT      2
+#define PLLE_MISC_VREG_CTRL_MASK       (2 << PLLE_MISC_VREG_CTRL_SHIFT)
+
+#define PLLCX_MISC_STROBE      BIT(31)
+#define PLLCX_MISC_RESET       BIT(30)
+#define PLLCX_MISC_SDM_DIV_SHIFT 28
+#define PLLCX_MISC_SDM_DIV_MASK (0x3 << PLLCX_MISC_SDM_DIV_SHIFT)
+#define PLLCX_MISC_FILT_DIV_SHIFT 26
+#define PLLCX_MISC_FILT_DIV_MASK (0x3 << PLLCX_MISC_FILT_DIV_SHIFT)
+#define PLLCX_MISC_ALPHA_SHIFT 18
+#define PLLCX_MISC_DIV_LOW_RANGE \
+               ((0x1 << PLLCX_MISC_SDM_DIV_SHIFT) | \
+               (0x1 << PLLCX_MISC_FILT_DIV_SHIFT))
+#define PLLCX_MISC_DIV_HIGH_RANGE \
+               ((0x2 << PLLCX_MISC_SDM_DIV_SHIFT) | \
+               (0x2 << PLLCX_MISC_FILT_DIV_SHIFT))
+#define PLLCX_MISC_COEF_LOW_RANGE \
+               ((0x14 << PLLCX_MISC_KA_SHIFT) | (0x38 << PLLCX_MISC_KB_SHIFT))
+#define PLLCX_MISC_KA_SHIFT 2
+#define PLLCX_MISC_KB_SHIFT 9
+#define PLLCX_MISC_DEFAULT (PLLCX_MISC_COEF_LOW_RANGE | \
+                           (0x19 << PLLCX_MISC_ALPHA_SHIFT) | \
+                           PLLCX_MISC_DIV_LOW_RANGE | \
+                           PLLCX_MISC_RESET)
+#define PLLCX_MISC1_DEFAULT 0x000d2308
+#define PLLCX_MISC2_DEFAULT 0x30211200
+#define PLLCX_MISC3_DEFAULT 0x200
+
+#define PMC_PLLM_WB0_OVERRIDE  0x1dc
+#define PMC_PLLM_WB0_OVERRIDE_2        0x2b0
+#define PMC_PLLM_WB0_OVERRIDE_2_DIVP_MASK BIT(27)
+
 #define PMC_SATA_PWRGT 0x1ac
 #define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5)
 #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL BIT(4)
 #define divn_max(p) (divn_mask(p))
 #define divp_max(p) (1 << (divp_mask(p)))
 
+
+#ifdef CONFIG_ARCH_TEGRA_114_SOC
+/* PLLXC has 4-bit PDIV, but entry 15 is not allowed in h/w */
+#define PLLXC_PDIV_MAX                 14
+
+/* non-monotonic mapping below is not a typo */
+static u8 pllxc_p[PLLXC_PDIV_MAX + 1] = {
+       /* PDIV: 0, 1, 2, 3, 4, 5, 6,  7,  8,  9, 10, 11, 12, 13, 14 */
+       /* p: */ 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 12, 16, 20, 24, 32
+};
+
+#define PLLCX_PDIV_MAX 7
+static u8 pllcx_p[PLLCX_PDIV_MAX + 1] = {
+       /* PDIV: 0, 1, 2, 3, 4, 5,  6,  7 */
+       /* p: */ 1, 2, 3, 4, 6, 8, 12, 16
+};
+#endif
+
 static void clk_pll_enable_lock(struct tegra_clk_pll *pll)
 {
        u32 val;
@@ -108,25 +168,36 @@ static void clk_pll_enable_lock(struct tegra_clk_pll *pll)
        if (!(pll->flags & TEGRA_PLL_USE_LOCK))
                return;
 
+       if (!(pll->flags & TEGRA_PLL_HAS_LOCK_ENABLE))
+               return;
+
        val = pll_readl_misc(pll);
        val |= BIT(pll->params->lock_enable_bit_idx);
        pll_writel_misc(val, pll);
 }
 
-static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll,
-                                void __iomem *lock_addr, u32 lock_bit_idx)
+static int clk_pll_wait_for_lock(struct tegra_clk_pll *pll)
 {
        int i;
-       u32 val;
+       u32 val, lock_mask;
+       void __iomem *lock_addr;
 
        if (!(pll->flags & TEGRA_PLL_USE_LOCK)) {
                udelay(pll->params->lock_delay);
                return 0;
        }
 
+       lock_addr = pll->clk_base;
+       if (pll->flags & TEGRA_PLL_LOCK_MISC)
+               lock_addr += pll->params->misc_reg;
+       else
+               lock_addr += pll->params->base_reg;
+
+       lock_mask = pll->params->lock_mask;
+
        for (i = 0; i < pll->params->lock_delay; i++) {
                val = readl_relaxed(lock_addr);
-               if (val & BIT(lock_bit_idx)) {
+               if ((val & lock_mask) == lock_mask) {
                        udelay(PLL_POST_LOCK_DELAY);
                        return 0;
                }
@@ -155,7 +226,7 @@ static int clk_pll_is_enabled(struct clk_hw *hw)
        return val & PLL_BASE_ENABLE ? 1 : 0;
 }
 
-static int _clk_pll_enable(struct clk_hw *hw)
+static void _clk_pll_enable(struct clk_hw *hw)
 {
        struct tegra_clk_pll *pll = to_clk_pll(hw);
        u32 val;
@@ -163,7 +234,8 @@ static int _clk_pll_enable(struct clk_hw *hw)
        clk_pll_enable_lock(pll);
 
        val = pll_readl_base(pll);
-       val &= ~PLL_BASE_BYPASS;
+       if (pll->flags & TEGRA_PLL_BYPASS)
+               val &= ~PLL_BASE_BYPASS;
        val |= PLL_BASE_ENABLE;
        pll_writel_base(val, pll);
 
@@ -172,11 +244,6 @@ static int _clk_pll_enable(struct clk_hw *hw)
                val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
                writel_relaxed(val, pll->pmc + PMC_PLLP_WB0_OVERRIDE);
        }
-
-       clk_pll_wait_for_lock(pll, pll->clk_base + pll->params->base_reg,
-                             pll->params->lock_bit_idx);
-
-       return 0;
 }
 
 static void _clk_pll_disable(struct clk_hw *hw)
@@ -185,7 +252,9 @@ static void _clk_pll_disable(struct clk_hw *hw)
        u32 val;
 
        val = pll_readl_base(pll);
-       val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
+       if (pll->flags & TEGRA_PLL_BYPASS)
+               val &= ~PLL_BASE_BYPASS;
+       val &= ~PLL_BASE_ENABLE;
        pll_writel_base(val, pll);
 
        if (pll->flags & TEGRA_PLLM) {
@@ -204,7 +273,9 @@ static int clk_pll_enable(struct clk_hw *hw)
        if (pll->lock)
                spin_lock_irqsave(pll->lock, flags);
 
-       ret = _clk_pll_enable(hw);
+       _clk_pll_enable(hw);
+
+       ret = clk_pll_wait_for_lock(pll);
 
        if (pll->lock)
                spin_unlock_irqrestore(pll->lock, flags);
@@ -241,8 +312,6 @@ static int _get_table_rate(struct clk_hw *hw,
        if (sel->input_rate == 0)
                return -EINVAL;
 
-       BUG_ON(sel->p < 1);
-
        cfg->input_rate = sel->input_rate;
        cfg->output_rate = sel->output_rate;
        cfg->m = sel->m;
@@ -257,6 +326,7 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg,
                      unsigned long rate, unsigned long parent_rate)
 {
        struct tegra_clk_pll *pll = to_clk_pll(hw);
+       struct pdiv_map *p_tohw = pll->params->pdiv_tohw;
        unsigned long cfreq;
        u32 p_div = 0;
 
@@ -290,88 +360,119 @@ static int _calc_rate(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg,
             cfg->output_rate <<= 1)
                p_div++;
 
-       cfg->p = 1 << p_div;
        cfg->m = parent_rate / cfreq;
        cfg->n = cfg->output_rate / cfreq;
        cfg->cpcon = OUT_OF_TABLE_CPCON;
 
        if (cfg->m > divm_max(pll) || cfg->n > divn_max(pll) ||
-           cfg->p > divp_max(pll) || cfg->output_rate > pll->params->vco_max) {
+           (1 << p_div) > divp_max(pll)
+           || cfg->output_rate > pll->params->vco_max) {
                pr_err("%s: Failed to set %s rate %lu\n",
                       __func__, __clk_get_name(hw->clk), rate);
                return -EINVAL;
        }
 
+       if (p_tohw) {
+               p_div = 1 << p_div;
+               while (p_tohw->pdiv) {
+                       if (p_div <= p_tohw->pdiv) {
+                               cfg->p = p_tohw->hw_val;
+                               break;
+                       }
+                       p_tohw++;
+               }
+               if (!p_tohw->pdiv)
+                       return -EINVAL;
+       } else
+               cfg->p = p_div;
+
        return 0;
 }
 
-static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg,
-                       unsigned long rate)
+static void _update_pll_mnp(struct tegra_clk_pll *pll,
+                           struct tegra_clk_pll_freq_table *cfg)
 {
-       struct tegra_clk_pll *pll = to_clk_pll(hw);
-       unsigned long flags = 0;
-       u32 divp, val, old_base;
-       int state;
-
-       divp = __ffs(cfg->p);
-
-       if (pll->flags & TEGRA_PLLU)
-               divp ^= 1;
+       u32 val;
 
-       if (pll->lock)
-               spin_lock_irqsave(pll->lock, flags);
+       val = pll_readl_base(pll);
 
-       old_base = val = pll_readl_base(pll);
        val &= ~((divm_mask(pll) << pll->divm_shift) |
                 (divn_mask(pll) << pll->divn_shift) |
                 (divp_mask(pll) << pll->divp_shift));
        val |= ((cfg->m << pll->divm_shift) |
                (cfg->n << pll->divn_shift) |
-               (divp << pll->divp_shift));
-       if (val == old_base) {
-               if (pll->lock)
-                       spin_unlock_irqrestore(pll->lock, flags);
-               return 0;
+               (cfg->p << pll->divp_shift));
+
+       pll_writel_base(val, pll);
+}
+
+static void _get_pll_mnp(struct tegra_clk_pll *pll,
+                        struct tegra_clk_pll_freq_table *cfg)
+{
+       u32 val;
+
+       val = pll_readl_base(pll);
+
+       cfg->m = (val >> pll->divm_shift) & (divm_mask(pll));
+       cfg->n = (val >> pll->divn_shift) & (divn_mask(pll));
+       cfg->p = (val >> pll->divp_shift) & (divp_mask(pll));
+}
+
+static void _update_pll_cpcon(struct tegra_clk_pll *pll,
+                             struct tegra_clk_pll_freq_table *cfg,
+                             unsigned long rate)
+{
+       u32 val;
+
+       val = pll_readl_misc(pll);
+
+       val &= ~(PLL_MISC_CPCON_MASK << PLL_MISC_CPCON_SHIFT);
+       val |= cfg->cpcon << PLL_MISC_CPCON_SHIFT;
+
+       if (pll->flags & TEGRA_PLL_SET_LFCON) {
+               val &= ~(PLL_MISC_LFCON_MASK << PLL_MISC_LFCON_SHIFT);
+               if (cfg->n >= PLLDU_LFCON_SET_DIVN)
+                       val |= 1 << PLL_MISC_LFCON_SHIFT;
+       } else if (pll->flags & TEGRA_PLL_SET_DCCON) {
+               val &= ~(1 << PLL_MISC_DCCON_SHIFT);
+               if (rate >= (pll->params->vco_max >> 1))
+                       val |= 1 << PLL_MISC_DCCON_SHIFT;
        }
 
+       pll_writel_misc(val, pll);
+}
+
+static int _program_pll(struct clk_hw *hw, struct tegra_clk_pll_freq_table *cfg,
+                       unsigned long rate)
+{
+       struct tegra_clk_pll *pll = to_clk_pll(hw);
+       int state, ret = 0;
+
        state = clk_pll_is_enabled(hw);
 
-       if (state) {
+       if (state)
                _clk_pll_disable(hw);
-               val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
-       }
-       pll_writel_base(val, pll);
 
-       if (pll->flags & TEGRA_PLL_HAS_CPCON) {
-               val = pll_readl_misc(pll);
-               val &= ~(PLL_MISC_CPCON_MASK << PLL_MISC_CPCON_SHIFT);
-               val |= cfg->cpcon << PLL_MISC_CPCON_SHIFT;
-               if (pll->flags & TEGRA_PLL_SET_LFCON) {
-                       val &= ~(PLL_MISC_LFCON_MASK << PLL_MISC_LFCON_SHIFT);
-                       if (cfg->n >= PLLDU_LFCON_SET_DIVN)
-                               val |= 0x1 << PLL_MISC_LFCON_SHIFT;
-               } else if (pll->flags & TEGRA_PLL_SET_DCCON) {
-                       val &= ~(0x1 << PLL_MISC_DCCON_SHIFT);
-                       if (rate >= (pll->params->vco_max >> 1))
-                               val |= 0x1 << PLL_MISC_DCCON_SHIFT;
-               }
-               pll_writel_misc(val, pll);
-       }
+       _update_pll_mnp(pll, cfg);
 
-       if (pll->lock)
-               spin_unlock_irqrestore(pll->lock, flags);
+       if (pll->flags & TEGRA_PLL_HAS_CPCON)
+               _update_pll_cpcon(pll, cfg, rate);
 
-       if (state)
-               clk_pll_enable(hw);
+       if (state) {
+               _clk_pll_enable(hw);
+               ret = clk_pll_wait_for_lock(pll);
+       }
 
-       return 0;
+       return ret;
 }
 
 static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
                        unsigned long parent_rate)
 {
        struct tegra_clk_pll *pll = to_clk_pll(hw);
-       struct tegra_clk_pll_freq_table cfg;
+       struct tegra_clk_pll_freq_table cfg, old_cfg;
+       unsigned long flags = 0;
+       int ret = 0;
 
        if (pll->flags & TEGRA_PLL_FIXED) {
                if (rate != pll->fixed_rate) {
@@ -387,7 +488,18 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
            _calc_rate(hw, &cfg, rate, parent_rate))
                return -EINVAL;
 
-       return _program_pll(hw, &cfg, rate);
+       if (pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       _get_pll_mnp(pll, &old_cfg);
+
+       if (old_cfg.m != cfg.m || old_cfg.n != cfg.n || old_cfg.p != cfg.p)
+               ret = _program_pll(hw, &cfg, rate);
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+
+       return ret;
 }
 
 static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
@@ -409,7 +521,7 @@ static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate,
                return -EINVAL;
 
        output_rate *= cfg.n;
-       do_div(output_rate, cfg.m * cfg.p);
+       do_div(output_rate, cfg.m * (1 << cfg.p));
 
        return output_rate;
 }
@@ -418,11 +530,15 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
                                         unsigned long parent_rate)
 {
        struct tegra_clk_pll *pll = to_clk_pll(hw);
-       u32 val = pll_readl_base(pll);
-       u32 divn = 0, divm = 0, divp = 0;
+       struct tegra_clk_pll_freq_table cfg;
+       struct pdiv_map *p_tohw = pll->params->pdiv_tohw;
+       u32 val;
        u64 rate = parent_rate;
+       int pdiv;
+
+       val = pll_readl_base(pll);
 
-       if (val & PLL_BASE_BYPASS)
+       if ((pll->flags & TEGRA_PLL_BYPASS) && (val & PLL_BASE_BYPASS))
                return parent_rate;
 
        if ((pll->flags & TEGRA_PLL_FIXED) && !(val & PLL_BASE_OVERRIDE)) {
@@ -435,16 +551,29 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
                return pll->fixed_rate;
        }
 
-       divp = (val >> pll->divp_shift) & (divp_mask(pll));
-       if (pll->flags & TEGRA_PLLU)
-               divp ^= 1;
+       _get_pll_mnp(pll, &cfg);
 
-       divn = (val >> pll->divn_shift) & (divn_mask(pll));
-       divm = (val >> pll->divm_shift) & (divm_mask(pll));
-       divm *= (1 << divp);
+       if (p_tohw) {
+               while (p_tohw->pdiv) {
+                       if (cfg.p == p_tohw->hw_val) {
+                               pdiv = p_tohw->pdiv;
+                               break;
+                       }
+                       p_tohw++;
+               }
+
+               if (!p_tohw->pdiv) {
+                       WARN_ON(1);
+                       pdiv = 1;
+               }
+       } else
+               pdiv = 1 << cfg.p;
+
+       cfg.m *= pdiv;
+
+       rate *= cfg.n;
+       do_div(rate, cfg.m);
 
-       rate *= divn;
-       do_div(rate, divm);
        return rate;
 }
 
@@ -538,8 +667,8 @@ static int clk_plle_enable(struct clk_hw *hw)
        val |= (PLL_BASE_BYPASS | PLL_BASE_ENABLE);
        pll_writel_base(val, pll);
 
-       clk_pll_wait_for_lock(pll, pll->clk_base + pll->params->misc_reg,
-                             pll->params->lock_bit_idx);
+       clk_pll_wait_for_lock(pll);
+
        return 0;
 }
 
@@ -577,72 +706,877 @@ const struct clk_ops tegra_clk_plle_ops = {
        .enable = clk_plle_enable,
 };
 
-static struct clk *_tegra_clk_register_pll(const char *name,
-               const char *parent_name, void __iomem *clk_base,
-               void __iomem *pmc, unsigned long flags,
-               unsigned long fixed_rate,
-               struct tegra_clk_pll_params *pll_params, u8 pll_flags,
-               struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock,
-               const struct clk_ops *ops)
+#ifdef CONFIG_ARCH_TEGRA_114_SOC
+
+static int _pll_fixed_mdiv(struct tegra_clk_pll_params *pll_params,
+                          unsigned long parent_rate)
 {
-       struct tegra_clk_pll *pll;
-       struct clk *clk;
-       struct clk_init_data init;
+       if (parent_rate > pll_params->cf_max)
+               return 2;
+       else
+               return 1;
+}
 
-       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
-       if (!pll)
-               return ERR_PTR(-ENOMEM);
+static int clk_pll_iddq_enable(struct clk_hw *hw)
+{
+       struct tegra_clk_pll *pll = to_clk_pll(hw);
+       unsigned long flags = 0;
 
-       init.name = name;
-       init.ops = ops;
-       init.flags = flags;
-       init.parent_names = (parent_name ? &parent_name : NULL);
-       init.num_parents = (parent_name ? 1 : 0);
+       u32 val;
+       int ret;
 
-       pll->clk_base = clk_base;
-       pll->pmc = pmc;
+       if (pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
 
-       pll->freq_table = freq_table;
-       pll->params = pll_params;
-       pll->fixed_rate = fixed_rate;
-       pll->flags = pll_flags;
-       pll->lock = lock;
+       val = pll_readl(pll->params->iddq_reg, pll);
+       val &= ~BIT(pll->params->iddq_bit_idx);
+       pll_writel(val, pll->params->iddq_reg, pll);
+       udelay(2);
 
-       pll->divp_shift = PLL_BASE_DIVP_SHIFT;
-       pll->divp_width = PLL_BASE_DIVP_WIDTH;
-       pll->divn_shift = PLL_BASE_DIVN_SHIFT;
-       pll->divn_width = PLL_BASE_DIVN_WIDTH;
-       pll->divm_shift = PLL_BASE_DIVM_SHIFT;
-       pll->divm_width = PLL_BASE_DIVM_WIDTH;
+       _clk_pll_enable(hw);
 
-       /* Data in .init is copied by clk_register(), so stack variable OK */
-       pll->hw.init = &init;
+       ret = clk_pll_wait_for_lock(pll);
 
-       clk = clk_register(NULL, &pll->hw);
-       if (IS_ERR(clk))
-               kfree(pll);
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
 
-       return clk;
+       return 0;
 }
 
-struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
-               void __iomem *clk_base, void __iomem *pmc,
-               unsigned long flags, unsigned long fixed_rate,
-               struct tegra_clk_pll_params *pll_params, u8 pll_flags,
-               struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock)
+static void clk_pll_iddq_disable(struct clk_hw *hw)
 {
-       return _tegra_clk_register_pll(name, parent_name, clk_base, pmc,
-                       flags, fixed_rate, pll_params, pll_flags, freq_table,
-                       lock, &tegra_clk_pll_ops);
+       struct tegra_clk_pll *pll = to_clk_pll(hw);
+       unsigned long flags = 0;
+       u32 val;
+
+       if (pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       _clk_pll_disable(hw);
+
+       val = pll_readl(pll->params->iddq_reg, pll);
+       val |= BIT(pll->params->iddq_bit_idx);
+       pll_writel(val, pll->params->iddq_reg, pll);
+       udelay(2);
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
 }
 
-struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
-               void __iomem *clk_base, void __iomem *pmc,
-               unsigned long flags, unsigned long fixed_rate,
-               struct tegra_clk_pll_params *pll_params, u8 pll_flags,
-               struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock)
+static int _calc_dynamic_ramp_rate(struct clk_hw *hw,
+                               struct tegra_clk_pll_freq_table *cfg,
+                               unsigned long rate, unsigned long parent_rate)
+{
+       struct tegra_clk_pll *pll = to_clk_pll(hw);
+       unsigned int p;
+
+       if (!rate)
+               return -EINVAL;
+
+       p = DIV_ROUND_UP(pll->params->vco_min, rate);
+       cfg->m = _pll_fixed_mdiv(pll->params, parent_rate);
+       cfg->p = p;
+       cfg->output_rate = rate * cfg->p;
+       cfg->n = cfg->output_rate * cfg->m / parent_rate;
+
+       if (cfg->n > divn_max(pll) || cfg->output_rate > pll->params->vco_max)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int _pll_ramp_calc_pll(struct clk_hw *hw,
+                             struct tegra_clk_pll_freq_table *cfg,
+                             unsigned long rate, unsigned long parent_rate)
+{
+       struct tegra_clk_pll *pll = to_clk_pll(hw);
+       int err = 0;
+
+       err = _get_table_rate(hw, cfg, rate, parent_rate);
+       if (err < 0)
+               err = _calc_dynamic_ramp_rate(hw, cfg, rate, parent_rate);
+       else if (cfg->m != _pll_fixed_mdiv(pll->params, parent_rate)) {
+                       WARN_ON(1);
+                       err = -EINVAL;
+                       goto out;
+       }
+
+       if (!cfg->p || (cfg->p >  pll->params->max_p))
+               err = -EINVAL;
+
+out:
+       return err;
+}
+
+static int clk_pllxc_set_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long parent_rate)
+{
+       struct tegra_clk_pll *pll = to_clk_pll(hw);
+       struct tegra_clk_pll_freq_table cfg, old_cfg;
+       unsigned long flags = 0;
+       int ret = 0;
+       u8 old_p;
+
+       ret = _pll_ramp_calc_pll(hw, &cfg, rate, parent_rate);
+       if (ret < 0)
+               return ret;
+
+       if (pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       _get_pll_mnp(pll, &old_cfg);
+
+       old_p = pllxc_p[old_cfg.p];
+       if (old_cfg.m != cfg.m || old_cfg.n != cfg.n || old_p != cfg.p) {
+               cfg.p -= 1;
+               ret = _program_pll(hw, &cfg, rate);
+       }
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+
+       return ret;
+}
+
+static long clk_pll_ramp_round_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long *prate)
+{
+       struct tegra_clk_pll_freq_table cfg;
+       int ret = 0;
+       u64 output_rate = *prate;
+
+       ret = _pll_ramp_calc_pll(hw, &cfg, rate, *prate);
+       if (ret < 0)
+               return ret;
+
+       output_rate *= cfg.n;
+       do_div(output_rate, cfg.m * cfg.p);
+
+       return output_rate;
+}
+
+static int clk_pllm_set_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long parent_rate)
+{
+       struct tegra_clk_pll_freq_table cfg;
+       struct tegra_clk_pll *pll = to_clk_pll(hw);
+       unsigned long flags = 0;
+       int state, ret = 0;
+       u32 val;
+
+       if (pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       state = clk_pll_is_enabled(hw);
+       if (state) {
+               if (rate != clk_get_rate(hw->clk)) {
+                       pr_err("%s: Cannot change active PLLM\n", __func__);
+                       ret = -EINVAL;
+                       goto out;
+               }
+               goto out;
+       }
+
+       ret = _pll_ramp_calc_pll(hw, &cfg, rate, parent_rate);
+       if (ret < 0)
+               goto out;
+
+       cfg.p -= 1;
+
+       val = readl_relaxed(pll->pmc + PMC_PLLM_WB0_OVERRIDE);
+       if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE) {
+               val = readl_relaxed(pll->pmc + PMC_PLLM_WB0_OVERRIDE_2);
+               val = cfg.p ? (val | PMC_PLLM_WB0_OVERRIDE_2_DIVP_MASK) :
+                       (val & ~PMC_PLLM_WB0_OVERRIDE_2_DIVP_MASK);
+               writel_relaxed(val, pll->pmc + PMC_PLLM_WB0_OVERRIDE_2);
+
+               val = readl_relaxed(pll->pmc + PMC_PLLM_WB0_OVERRIDE);
+               val &= ~(divn_mask(pll) | divm_mask(pll));
+               val |= (cfg.m << pll->divm_shift) | (cfg.n << pll->divn_shift);
+               writel_relaxed(val, pll->pmc + PMC_PLLM_WB0_OVERRIDE);
+       } else
+               _update_pll_mnp(pll, &cfg);
+
+
+out:
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+
+       return ret;
+}
+
+static void _pllcx_strobe(struct tegra_clk_pll *pll)
+{
+       u32 val;
+
+       val = pll_readl_misc(pll);
+       val |= PLLCX_MISC_STROBE;
+       pll_writel_misc(val, pll);
+       udelay(2);
+
+       val &= ~PLLCX_MISC_STROBE;
+       pll_writel_misc(val, pll);
+}
+
+static int clk_pllc_enable(struct clk_hw *hw)
 {
-       return _tegra_clk_register_pll(name, parent_name, clk_base, pmc,
-                       flags, fixed_rate, pll_params, pll_flags, freq_table,
-                       lock, &tegra_clk_plle_ops);
+       struct tegra_clk_pll *pll = to_clk_pll(hw);
+       u32 val;
+       int ret = 0;
+       unsigned long flags = 0;
+
+       if (pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       _clk_pll_enable(hw);
+       udelay(2);
+
+       val = pll_readl_misc(pll);
+       val &= ~PLLCX_MISC_RESET;
+       pll_writel_misc(val, pll);
+       udelay(2);
+
+       _pllcx_strobe(pll);
+
+       ret = clk_pll_wait_for_lock(pll);
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+
+       return ret;
+}
+
+static void _clk_pllc_disable(struct clk_hw *hw)
+{
+       struct tegra_clk_pll *pll = to_clk_pll(hw);
+       u32 val;
+
+       _clk_pll_disable(hw);
+
+       val = pll_readl_misc(pll);
+       val |= PLLCX_MISC_RESET;
+       pll_writel_misc(val, pll);
+       udelay(2);
+}
+
+static void clk_pllc_disable(struct clk_hw *hw)
+{
+       struct tegra_clk_pll *pll = to_clk_pll(hw);
+       unsigned long flags = 0;
+
+       if (pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       _clk_pllc_disable(hw);
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+}
+
+static int _pllcx_update_dynamic_coef(struct tegra_clk_pll *pll,
+                                       unsigned long input_rate, u32 n)
+{
+       u32 val, n_threshold;
+
+       switch (input_rate) {
+       case 12000000:
+               n_threshold = 70;
+               break;
+       case 13000000:
+       case 26000000:
+               n_threshold = 71;
+               break;
+       case 16800000:
+               n_threshold = 55;
+               break;
+       case 19200000:
+               n_threshold = 48;
+               break;
+       default:
+               pr_err("%s: Unexpected reference rate %lu\n",
+                       __func__, input_rate);
+               return -EINVAL;
+       }
+
+       val = pll_readl_misc(pll);
+       val &= ~(PLLCX_MISC_SDM_DIV_MASK | PLLCX_MISC_FILT_DIV_MASK);
+       val |= n <= n_threshold ?
+               PLLCX_MISC_DIV_LOW_RANGE : PLLCX_MISC_DIV_HIGH_RANGE;
+       pll_writel_misc(val, pll);
+
+       return 0;
+}
+
+static int clk_pllc_set_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long parent_rate)
+{
+       struct tegra_clk_pll_freq_table cfg;
+       struct tegra_clk_pll *pll = to_clk_pll(hw);
+       unsigned long flags = 0;
+       int state, ret = 0;
+       u32 val;
+       u16 old_m, old_n;
+       u8 old_p;
+
+       if (pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       ret = _pll_ramp_calc_pll(hw, &cfg, rate, parent_rate);
+       if (ret < 0)
+               goto out;
+
+       val = pll_readl_base(pll);
+       old_m = (val >> pll->divm_shift) & (divm_mask(pll));
+       old_n = (val >> pll->divn_shift) & (divn_mask(pll));
+       old_p = pllcx_p[(val >> pll->divp_shift) & (divp_mask(pll))];
+
+       if (cfg.m != old_m) {
+               WARN_ON(1);
+               goto out;
+       }
+
+       if (old_n == cfg.n && old_p == cfg.p)
+               goto out;
+
+       cfg.p -= 1;
+
+       state = clk_pll_is_enabled(hw);
+       if (state)
+               _clk_pllc_disable(hw);
+
+       ret = _pllcx_update_dynamic_coef(pll, parent_rate, cfg.n);
+       if (ret < 0)
+               goto out;
+
+       _update_pll_mnp(pll, &cfg);
+
+       if (state)
+               ret = clk_pllc_enable(hw);
+
+out:
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+
+       return ret;
+}
+
+static long _pllre_calc_rate(struct tegra_clk_pll *pll,
+                            struct tegra_clk_pll_freq_table *cfg,
+                            unsigned long rate, unsigned long parent_rate)
+{
+       u16 m, n;
+       u64 output_rate = parent_rate;
+
+       m = _pll_fixed_mdiv(pll->params, parent_rate);
+       n = rate * m / parent_rate;
+
+       output_rate *= n;
+       do_div(output_rate, m);
+
+       if (cfg) {
+               cfg->m = m;
+               cfg->n = n;
+       }
+
+       return output_rate;
+}
+static int clk_pllre_set_rate(struct clk_hw *hw, unsigned long rate,
+                               unsigned long parent_rate)
+{
+       struct tegra_clk_pll_freq_table cfg, old_cfg;
+       struct tegra_clk_pll *pll = to_clk_pll(hw);
+       unsigned long flags = 0;
+       int state, ret = 0;
+
+       if (pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       _pllre_calc_rate(pll, &cfg, rate, parent_rate);
+       _get_pll_mnp(pll, &old_cfg);
+       cfg.p = old_cfg.p;
+
+       if (cfg.m != old_cfg.m || cfg.n != old_cfg.n) {
+               state = clk_pll_is_enabled(hw);
+               if (state)
+                       _clk_pll_disable(hw);
+
+               _update_pll_mnp(pll, &cfg);
+
+               if (state) {
+                       _clk_pll_enable(hw);
+                       ret = clk_pll_wait_for_lock(pll);
+               }
+       }
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+
+       return ret;
+}
+
+static unsigned long clk_pllre_recalc_rate(struct clk_hw *hw,
+                                        unsigned long parent_rate)
+{
+       struct tegra_clk_pll_freq_table cfg;
+       struct tegra_clk_pll *pll = to_clk_pll(hw);
+       u64 rate = parent_rate;
+
+       _get_pll_mnp(pll, &cfg);
+
+       rate *= cfg.n;
+       do_div(rate, cfg.m);
+
+       return rate;
+}
+
+static long clk_pllre_round_rate(struct clk_hw *hw, unsigned long rate,
+                                unsigned long *prate)
+{
+       struct tegra_clk_pll *pll = to_clk_pll(hw);
+
+       return _pllre_calc_rate(pll, NULL, rate, *prate);
+}
+
+static int clk_plle_tegra114_enable(struct clk_hw *hw)
+{
+       struct tegra_clk_pll *pll = to_clk_pll(hw);
+       struct tegra_clk_pll_freq_table sel;
+       u32 val;
+       int ret;
+       unsigned long flags = 0;
+       unsigned long input_rate = clk_get_rate(clk_get_parent(hw->clk));
+
+       if (_get_table_rate(hw, &sel, pll->fixed_rate, input_rate))
+               return -EINVAL;
+
+       if (pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       val = pll_readl_base(pll);
+       val &= ~BIT(29); /* Disable lock override */
+       pll_writel_base(val, pll);
+
+       val = pll_readl(pll->params->aux_reg, pll);
+       val |= PLLE_AUX_ENABLE_SWCTL;
+       val &= ~PLLE_AUX_SEQ_ENABLE;
+       pll_writel(val, pll->params->aux_reg, pll);
+       udelay(1);
+
+       val = pll_readl_misc(pll);
+       val |= PLLE_MISC_LOCK_ENABLE;
+       val |= PLLE_MISC_IDDQ_SW_CTRL;
+       val &= ~PLLE_MISC_IDDQ_SW_VALUE;
+       val |= PLLE_MISC_PLLE_PTS;
+       val |= PLLE_MISC_VREG_BG_CTRL_MASK | PLLE_MISC_VREG_CTRL_MASK;
+       pll_writel_misc(val, pll);
+       udelay(5);
+
+       val = pll_readl(PLLE_SS_CTRL, pll);
+       val |= PLLE_SS_DISABLE;
+       pll_writel(val, PLLE_SS_CTRL, pll);
+
+       val = pll_readl_base(pll);
+       val &= ~(divm_mask(pll) | divn_mask(pll) | divp_mask(pll));
+       val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT);
+       val |= sel.m << pll->divm_shift;
+       val |= sel.n << pll->divn_shift;
+       val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT;
+       pll_writel_base(val, pll);
+       udelay(1);
+
+       _clk_pll_enable(hw);
+       ret = clk_pll_wait_for_lock(pll);
+
+       if (ret < 0)
+               goto out;
+
+       /* TODO: enable hw control of xusb brick pll */
+
+out:
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+
+       return ret;
+}
+
+static void clk_plle_tegra114_disable(struct clk_hw *hw)
+{
+       struct tegra_clk_pll *pll = to_clk_pll(hw);
+       unsigned long flags = 0;
+       u32 val;
+
+       if (pll->lock)
+               spin_lock_irqsave(pll->lock, flags);
+
+       _clk_pll_disable(hw);
+
+       val = pll_readl_misc(pll);
+       val |= PLLE_MISC_IDDQ_SW_CTRL | PLLE_MISC_IDDQ_SW_VALUE;
+       pll_writel_misc(val, pll);
+       udelay(1);
+
+       if (pll->lock)
+               spin_unlock_irqrestore(pll->lock, flags);
+}
+#endif
+
+static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base,
+               void __iomem *pmc, unsigned long fixed_rate,
+               struct tegra_clk_pll_params *pll_params, u32 pll_flags,
+               struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock)
+{
+       struct tegra_clk_pll *pll;
+
+       pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+       if (!pll)
+               return ERR_PTR(-ENOMEM);
+
+       pll->clk_base = clk_base;
+       pll->pmc = pmc;
+
+       pll->freq_table = freq_table;
+       pll->params = pll_params;
+       pll->fixed_rate = fixed_rate;
+       pll->flags = pll_flags;
+       pll->lock = lock;
+
+       pll->divp_shift = PLL_BASE_DIVP_SHIFT;
+       pll->divp_width = PLL_BASE_DIVP_WIDTH;
+       pll->divn_shift = PLL_BASE_DIVN_SHIFT;
+       pll->divn_width = PLL_BASE_DIVN_WIDTH;
+       pll->divm_shift = PLL_BASE_DIVM_SHIFT;
+       pll->divm_width = PLL_BASE_DIVM_WIDTH;
+
+       return pll;
+}
+
+static struct clk *_tegra_clk_register_pll(struct tegra_clk_pll *pll,
+               const char *name, const char *parent_name, unsigned long flags,
+               const struct clk_ops *ops)
+{
+       struct clk_init_data init;
+
+       init.name = name;
+       init.ops = ops;
+       init.flags = flags;
+       init.parent_names = (parent_name ? &parent_name : NULL);
+       init.num_parents = (parent_name ? 1 : 0);
+
+       /* Data in .init is copied by clk_register(), so stack variable OK */
+       pll->hw.init = &init;
+
+       return clk_register(NULL, &pll->hw);
+}
+
+struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
+               void __iomem *clk_base, void __iomem *pmc,
+               unsigned long flags, unsigned long fixed_rate,
+               struct tegra_clk_pll_params *pll_params, u32 pll_flags,
+               struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock)
+{
+       struct tegra_clk_pll *pll;
+       struct clk *clk;
+
+       pll_flags |= TEGRA_PLL_BYPASS;
+       pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE;
+       pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags,
+                             freq_table, lock);
+       if (IS_ERR(pll))
+               return ERR_CAST(pll);
+
+       clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
+                                     &tegra_clk_pll_ops);
+       if (IS_ERR(clk))
+               kfree(pll);
+
+       return clk;
+}
+
+struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
+               void __iomem *clk_base, void __iomem *pmc,
+               unsigned long flags, unsigned long fixed_rate,
+               struct tegra_clk_pll_params *pll_params, u32 pll_flags,
+               struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock)
+{
+       struct tegra_clk_pll *pll;
+       struct clk *clk;
+
+       pll_flags |= TEGRA_PLL_LOCK_MISC | TEGRA_PLL_BYPASS;
+       pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE;
+       pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags,
+                             freq_table, lock);
+       if (IS_ERR(pll))
+               return ERR_CAST(pll);
+
+       clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
+                                     &tegra_clk_plle_ops);
+       if (IS_ERR(clk))
+               kfree(pll);
+
+       return clk;
+}
+
+#ifdef CONFIG_ARCH_TEGRA_114_SOC
+const struct clk_ops tegra_clk_pllxc_ops = {
+       .is_enabled = clk_pll_is_enabled,
+       .enable = clk_pll_iddq_enable,
+       .disable = clk_pll_iddq_disable,
+       .recalc_rate = clk_pll_recalc_rate,
+       .round_rate = clk_pll_ramp_round_rate,
+       .set_rate = clk_pllxc_set_rate,
+};
+
+const struct clk_ops tegra_clk_pllm_ops = {
+       .is_enabled = clk_pll_is_enabled,
+       .enable = clk_pll_iddq_enable,
+       .disable = clk_pll_iddq_disable,
+       .recalc_rate = clk_pll_recalc_rate,
+       .round_rate = clk_pll_ramp_round_rate,
+       .set_rate = clk_pllm_set_rate,
+};
+
+const struct clk_ops tegra_clk_pllc_ops = {
+       .is_enabled = clk_pll_is_enabled,
+       .enable = clk_pllc_enable,
+       .disable = clk_pllc_disable,
+       .recalc_rate = clk_pll_recalc_rate,
+       .round_rate = clk_pll_ramp_round_rate,
+       .set_rate = clk_pllc_set_rate,
+};
+
+const struct clk_ops tegra_clk_pllre_ops = {
+       .is_enabled = clk_pll_is_enabled,
+       .enable = clk_pll_iddq_enable,
+       .disable = clk_pll_iddq_disable,
+       .recalc_rate = clk_pllre_recalc_rate,
+       .round_rate = clk_pllre_round_rate,
+       .set_rate = clk_pllre_set_rate,
+};
+
+const struct clk_ops tegra_clk_plle_tegra114_ops = {
+       .is_enabled =  clk_pll_is_enabled,
+       .enable = clk_plle_tegra114_enable,
+       .disable = clk_plle_tegra114_disable,
+       .recalc_rate = clk_pll_recalc_rate,
+};
+
+
+struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name,
+                         void __iomem *clk_base, void __iomem *pmc,
+                         unsigned long flags, unsigned long fixed_rate,
+                         struct tegra_clk_pll_params *pll_params,
+                         u32 pll_flags,
+                         struct tegra_clk_pll_freq_table *freq_table,
+                         spinlock_t *lock)
+{
+       struct tegra_clk_pll *pll;
+       struct clk *clk;
+
+       if (!pll_params->pdiv_tohw)
+               return ERR_PTR(-EINVAL);
+
+       pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE;
+       pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags,
+                             freq_table, lock);
+       if (IS_ERR(pll))
+               return ERR_CAST(pll);
+
+       clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
+                                     &tegra_clk_pllxc_ops);
+       if (IS_ERR(clk))
+               kfree(pll);
+
+       return clk;
+}
+
+struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name,
+                         void __iomem *clk_base, void __iomem *pmc,
+                         unsigned long flags, unsigned long fixed_rate,
+                         struct tegra_clk_pll_params *pll_params,
+                         u32 pll_flags,
+                         struct tegra_clk_pll_freq_table *freq_table,
+                         spinlock_t *lock, unsigned long parent_rate)
+{
+       u32 val;
+       struct tegra_clk_pll *pll;
+       struct clk *clk;
+
+       pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE;
+       pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags,
+                             freq_table, lock);
+       if (IS_ERR(pll))
+               return ERR_CAST(pll);
+
+       /* program minimum rate by default */
+
+       val = pll_readl_base(pll);
+       if (val & PLL_BASE_ENABLE)
+               WARN_ON(val & pll_params->iddq_bit_idx);
+       else {
+               int m;
+
+               m = _pll_fixed_mdiv(pll_params, parent_rate);
+               val = m << PLL_BASE_DIVM_SHIFT;
+               val |= (pll_params->vco_min / parent_rate)
+                               << PLL_BASE_DIVN_SHIFT;
+               pll_writel_base(val, pll);
+       }
+
+       /* disable lock override */
+
+       val = pll_readl_misc(pll);
+       val &= ~BIT(29);
+       pll_writel_misc(val, pll);
+
+       pll_flags |= TEGRA_PLL_LOCK_MISC;
+       clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
+                                     &tegra_clk_pllre_ops);
+       if (IS_ERR(clk))
+               kfree(pll);
+
+       return clk;
+}
+
+struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name,
+                         void __iomem *clk_base, void __iomem *pmc,
+                         unsigned long flags, unsigned long fixed_rate,
+                         struct tegra_clk_pll_params *pll_params,
+                         u32 pll_flags,
+                         struct tegra_clk_pll_freq_table *freq_table,
+                         spinlock_t *lock)
+{
+       struct tegra_clk_pll *pll;
+       struct clk *clk;
+
+       if (!pll_params->pdiv_tohw)
+               return ERR_PTR(-EINVAL);
+
+       pll_flags |= TEGRA_PLL_BYPASS;
+       pll_flags |= TEGRA_PLL_HAS_LOCK_ENABLE;
+       pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags,
+                             freq_table, lock);
+       if (IS_ERR(pll))
+               return ERR_CAST(pll);
+
+       clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
+                                     &tegra_clk_pllm_ops);
+       if (IS_ERR(clk))
+               kfree(pll);
+
+       return clk;
+}
+
+struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name,
+                         void __iomem *clk_base, void __iomem *pmc,
+                         unsigned long flags, unsigned long fixed_rate,
+                         struct tegra_clk_pll_params *pll_params,
+                         u32 pll_flags,
+                         struct tegra_clk_pll_freq_table *freq_table,
+                         spinlock_t *lock)
+{
+       struct clk *parent, *clk;
+       struct pdiv_map *p_tohw = pll_params->pdiv_tohw;
+       struct tegra_clk_pll *pll;
+       struct tegra_clk_pll_freq_table cfg;
+       unsigned long parent_rate;
+
+       if (!p_tohw)
+               return ERR_PTR(-EINVAL);
+
+       parent = __clk_lookup(parent_name);
+       if (IS_ERR(parent)) {
+               WARN(1, "parent clk %s of %s must be registered first\n",
+                       name, parent_name);
+               return ERR_PTR(-EINVAL);
+       }
+
+       pll_flags |= TEGRA_PLL_BYPASS;
+       pll = _tegra_init_pll(clk_base, pmc, fixed_rate, pll_params, pll_flags,
+                             freq_table, lock);
+       if (IS_ERR(pll))
+               return ERR_CAST(pll);
+
+       parent_rate = __clk_get_rate(parent);
+
+       /*
+        * Most of PLLC register fields are shadowed, and can not be read
+        * directly from PLL h/w. Hence, actual PLLC boot state is unknown.
+        * Initialize PLL to default state: disabled, reset; shadow registers
+        * loaded with default parameters; dividers are preset for half of
+        * minimum VCO rate (the latter assured that shadowed divider settings
+        * are within supported range).
+        */
+
+       cfg.m = _pll_fixed_mdiv(pll_params, parent_rate);
+       cfg.n = cfg.m * pll_params->vco_min / parent_rate;
+
+       while (p_tohw->pdiv) {
+               if (p_tohw->pdiv == 2) {
+                       cfg.p = p_tohw->hw_val;
+                       break;
+               }
+               p_tohw++;
+       }
+
+       if (!p_tohw->pdiv) {
+               WARN_ON(1);
+               return ERR_PTR(-EINVAL);
+       }
+
+       pll_writel_base(0, pll);
+       _update_pll_mnp(pll, &cfg);
+
+       pll_writel_misc(PLLCX_MISC_DEFAULT, pll);
+       pll_writel(PLLCX_MISC1_DEFAULT, pll_params->ext_misc_reg[0], pll);
+       pll_writel(PLLCX_MISC2_DEFAULT, pll_params->ext_misc_reg[1], pll);
+       pll_writel(PLLCX_MISC3_DEFAULT, pll_params->ext_misc_reg[2], pll);
+
+       _pllcx_update_dynamic_coef(pll, parent_rate, cfg.n);
+
+       clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
+                                     &tegra_clk_pllc_ops);
+       if (IS_ERR(clk))
+               kfree(pll);
+
+       return clk;
+}
+
+struct clk *tegra_clk_register_plle_tegra114(const char *name,
+                               const char *parent_name,
+                               void __iomem *clk_base, unsigned long flags,
+                               unsigned long fixed_rate,
+                               struct tegra_clk_pll_params *pll_params,
+                               struct tegra_clk_pll_freq_table *freq_table,
+                               spinlock_t *lock)
+{
+       struct tegra_clk_pll *pll;
+       struct clk *clk;
+       u32 val, val_aux;
+
+       pll = _tegra_init_pll(clk_base, NULL, fixed_rate, pll_params,
+                             TEGRA_PLL_HAS_LOCK_ENABLE, freq_table, lock);
+       if (IS_ERR(pll))
+               return ERR_CAST(pll);
+
+       /* ensure parent is set to pll_re_vco */
+
+       val = pll_readl_base(pll);
+       val_aux = pll_readl(pll_params->aux_reg, pll);
+
+       if (val & PLL_BASE_ENABLE) {
+               if (!(val_aux & PLLE_AUX_PLLRE_SEL))
+                       WARN(1, "pll_e enabled with unsupported parent %s\n",
+                         (val & PLLE_AUX_PLLP_SEL) ? "pllp_out0" : "pll_ref");
+       } else {
+               val_aux |= PLLE_AUX_PLLRE_SEL;
+               pll_writel(val, pll_params->aux_reg, pll);
+       }
+
+       clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
+                                     &tegra_clk_plle_tegra114_ops);
+       if (IS_ERR(clk))
+               kfree(pll);
+
+       return clk;
 }
+#endif
diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
new file mode 100644 (file)
index 0000000..d78e16e
--- /dev/null
@@ -0,0 +1,2085 @@
+/*
+ * Copyright (c) 2012, 2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/delay.h>
+#include <linux/clk/tegra.h>
+
+#include "clk.h"
+
+#define RST_DEVICES_L                  0x004
+#define RST_DEVICES_H                  0x008
+#define RST_DEVICES_U                  0x00C
+#define RST_DEVICES_V                  0x358
+#define RST_DEVICES_W                  0x35C
+#define RST_DEVICES_X                  0x28C
+#define RST_DEVICES_SET_L              0x300
+#define RST_DEVICES_CLR_L              0x304
+#define RST_DEVICES_SET_H              0x308
+#define RST_DEVICES_CLR_H              0x30c
+#define RST_DEVICES_SET_U              0x310
+#define RST_DEVICES_CLR_U              0x314
+#define RST_DEVICES_SET_V              0x430
+#define RST_DEVICES_CLR_V              0x434
+#define RST_DEVICES_SET_W              0x438
+#define RST_DEVICES_CLR_W              0x43c
+#define RST_DEVICES_NUM                        5
+
+#define CLK_OUT_ENB_L                  0x010
+#define CLK_OUT_ENB_H                  0x014
+#define CLK_OUT_ENB_U                  0x018
+#define CLK_OUT_ENB_V                  0x360
+#define CLK_OUT_ENB_W                  0x364
+#define CLK_OUT_ENB_X                  0x280
+#define CLK_OUT_ENB_SET_L              0x320
+#define CLK_OUT_ENB_CLR_L              0x324
+#define CLK_OUT_ENB_SET_H              0x328
+#define CLK_OUT_ENB_CLR_H              0x32c
+#define CLK_OUT_ENB_SET_U              0x330
+#define CLK_OUT_ENB_CLR_U              0x334
+#define CLK_OUT_ENB_SET_V              0x440
+#define CLK_OUT_ENB_CLR_V              0x444
+#define CLK_OUT_ENB_SET_W              0x448
+#define CLK_OUT_ENB_CLR_W              0x44c
+#define CLK_OUT_ENB_SET_X              0x284
+#define CLK_OUT_ENB_CLR_X              0x288
+#define CLK_OUT_ENB_NUM                        6
+
+#define PLLC_BASE 0x80
+#define PLLC_MISC2 0x88
+#define PLLC_MISC 0x8c
+#define PLLC2_BASE 0x4e8
+#define PLLC2_MISC 0x4ec
+#define PLLC3_BASE 0x4fc
+#define PLLC3_MISC 0x500
+#define PLLM_BASE 0x90
+#define PLLM_MISC 0x9c
+#define PLLP_BASE 0xa0
+#define PLLP_MISC 0xac
+#define PLLX_BASE 0xe0
+#define PLLX_MISC 0xe4
+#define PLLX_MISC2 0x514
+#define PLLX_MISC3 0x518
+#define PLLD_BASE 0xd0
+#define PLLD_MISC 0xdc
+#define PLLD2_BASE 0x4b8
+#define PLLD2_MISC 0x4bc
+#define PLLE_BASE 0xe8
+#define PLLE_MISC 0xec
+#define PLLA_BASE 0xb0
+#define PLLA_MISC 0xbc
+#define PLLU_BASE 0xc0
+#define PLLU_MISC 0xcc
+#define PLLRE_BASE 0x4c4
+#define PLLRE_MISC 0x4c8
+
+#define PLL_MISC_LOCK_ENABLE 18
+#define PLLC_MISC_LOCK_ENABLE 24
+#define PLLDU_MISC_LOCK_ENABLE 22
+#define PLLE_MISC_LOCK_ENABLE 9
+#define PLLRE_MISC_LOCK_ENABLE 30
+
+#define PLLC_IDDQ_BIT 26
+#define PLLX_IDDQ_BIT 3
+#define PLLRE_IDDQ_BIT 16
+
+#define PLL_BASE_LOCK BIT(27)
+#define PLLE_MISC_LOCK BIT(11)
+#define PLLRE_MISC_LOCK BIT(24)
+#define PLLCX_BASE_LOCK (BIT(26)|BIT(27))
+
+#define PLLE_AUX 0x48c
+#define PLLC_OUT 0x84
+#define PLLM_OUT 0x94
+#define PLLP_OUTA 0xa4
+#define PLLP_OUTB 0xa8
+#define PLLA_OUT 0xb4
+
+#define AUDIO_SYNC_CLK_I2S0 0x4a0
+#define AUDIO_SYNC_CLK_I2S1 0x4a4
+#define AUDIO_SYNC_CLK_I2S2 0x4a8
+#define AUDIO_SYNC_CLK_I2S3 0x4ac
+#define AUDIO_SYNC_CLK_I2S4 0x4b0
+#define AUDIO_SYNC_CLK_SPDIF 0x4b4
+
+#define AUDIO_SYNC_DOUBLER 0x49c
+
+#define PMC_CLK_OUT_CNTRL 0x1a8
+#define PMC_DPD_PADS_ORIDE 0x1c
+#define PMC_DPD_PADS_ORIDE_BLINK_ENB 20
+#define PMC_CTRL 0
+#define PMC_CTRL_BLINK_ENB 7
+
+#define OSC_CTRL                       0x50
+#define OSC_CTRL_OSC_FREQ_SHIFT                28
+#define OSC_CTRL_PLL_REF_DIV_SHIFT     26
+
+#define PLLXC_SW_MAX_P                 6
+
+#define CCLKG_BURST_POLICY 0x368
+#define CCLKLP_BURST_POLICY 0x370
+#define SCLK_BURST_POLICY 0x028
+#define SYSTEM_CLK_RATE 0x030
+
+#define UTMIP_PLL_CFG2 0x488
+#define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xffff) << 6)
+#define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x) (((x) & 0x3f) << 18)
+#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN BIT(0)
+#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN BIT(2)
+#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN BIT(4)
+
+#define UTMIP_PLL_CFG1 0x484
+#define UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 6)
+#define UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0)
+#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERUP BIT(17)
+#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN BIT(16)
+#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP BIT(15)
+#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN BIT(14)
+#define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN BIT(12)
+
+#define UTMIPLL_HW_PWRDN_CFG0                  0x52c
+#define UTMIPLL_HW_PWRDN_CFG0_SEQ_START_STATE  BIT(25)
+#define UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE       BIT(24)
+#define UTMIPLL_HW_PWRDN_CFG0_USE_LOCKDET      BIT(6)
+#define UTMIPLL_HW_PWRDN_CFG0_SEQ_RESET_INPUT_VALUE    BIT(5)
+#define UTMIPLL_HW_PWRDN_CFG0_SEQ_IN_SWCTL     BIT(4)
+#define UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL BIT(2)
+#define UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE    BIT(1)
+#define UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL       BIT(0)
+
+#define CLK_SOURCE_I2S0 0x1d8
+#define CLK_SOURCE_I2S1 0x100
+#define CLK_SOURCE_I2S2 0x104
+#define CLK_SOURCE_NDFLASH 0x160
+#define CLK_SOURCE_I2S3 0x3bc
+#define CLK_SOURCE_I2S4 0x3c0
+#define CLK_SOURCE_SPDIF_OUT 0x108
+#define CLK_SOURCE_SPDIF_IN 0x10c
+#define CLK_SOURCE_PWM 0x110
+#define CLK_SOURCE_ADX 0x638
+#define CLK_SOURCE_AMX 0x63c
+#define CLK_SOURCE_HDA 0x428
+#define CLK_SOURCE_HDA2CODEC_2X 0x3e4
+#define CLK_SOURCE_SBC1 0x134
+#define CLK_SOURCE_SBC2 0x118
+#define CLK_SOURCE_SBC3 0x11c
+#define CLK_SOURCE_SBC4 0x1b4
+#define CLK_SOURCE_SBC5 0x3c8
+#define CLK_SOURCE_SBC6 0x3cc
+#define CLK_SOURCE_SATA_OOB 0x420
+#define CLK_SOURCE_SATA 0x424
+#define CLK_SOURCE_NDSPEED 0x3f8
+#define CLK_SOURCE_VFIR 0x168
+#define CLK_SOURCE_SDMMC1 0x150
+#define CLK_SOURCE_SDMMC2 0x154
+#define CLK_SOURCE_SDMMC3 0x1bc
+#define CLK_SOURCE_SDMMC4 0x164
+#define CLK_SOURCE_VDE 0x1c8
+#define CLK_SOURCE_CSITE 0x1d4
+#define CLK_SOURCE_LA 0x1f8
+#define CLK_SOURCE_TRACE 0x634
+#define CLK_SOURCE_OWR 0x1cc
+#define CLK_SOURCE_NOR 0x1d0
+#define CLK_SOURCE_MIPI 0x174
+#define CLK_SOURCE_I2C1 0x124
+#define CLK_SOURCE_I2C2 0x198
+#define CLK_SOURCE_I2C3 0x1b8
+#define CLK_SOURCE_I2C4 0x3c4
+#define CLK_SOURCE_I2C5 0x128
+#define CLK_SOURCE_UARTA 0x178
+#define CLK_SOURCE_UARTB 0x17c
+#define CLK_SOURCE_UARTC 0x1a0
+#define CLK_SOURCE_UARTD 0x1c0
+#define CLK_SOURCE_UARTE 0x1c4
+#define CLK_SOURCE_UARTA_DBG 0x178
+#define CLK_SOURCE_UARTB_DBG 0x17c
+#define CLK_SOURCE_UARTC_DBG 0x1a0
+#define CLK_SOURCE_UARTD_DBG 0x1c0
+#define CLK_SOURCE_UARTE_DBG 0x1c4
+#define CLK_SOURCE_3D 0x158
+#define CLK_SOURCE_2D 0x15c
+#define CLK_SOURCE_VI_SENSOR 0x1a8
+#define CLK_SOURCE_VI 0x148
+#define CLK_SOURCE_EPP 0x16c
+#define CLK_SOURCE_MSENC 0x1f0
+#define CLK_SOURCE_TSEC 0x1f4
+#define CLK_SOURCE_HOST1X 0x180
+#define CLK_SOURCE_HDMI 0x18c
+#define CLK_SOURCE_DISP1 0x138
+#define CLK_SOURCE_DISP2 0x13c
+#define CLK_SOURCE_CILAB 0x614
+#define CLK_SOURCE_CILCD 0x618
+#define CLK_SOURCE_CILE 0x61c
+#define CLK_SOURCE_DSIALP 0x620
+#define CLK_SOURCE_DSIBLP 0x624
+#define CLK_SOURCE_TSENSOR 0x3b8
+#define CLK_SOURCE_D_AUDIO 0x3d0
+#define CLK_SOURCE_DAM0 0x3d8
+#define CLK_SOURCE_DAM1 0x3dc
+#define CLK_SOURCE_DAM2 0x3e0
+#define CLK_SOURCE_ACTMON 0x3e8
+#define CLK_SOURCE_EXTERN1 0x3ec
+#define CLK_SOURCE_EXTERN2 0x3f0
+#define CLK_SOURCE_EXTERN3 0x3f4
+#define CLK_SOURCE_I2CSLOW 0x3fc
+#define CLK_SOURCE_SE 0x42c
+#define CLK_SOURCE_MSELECT 0x3b4
+#define CLK_SOURCE_SOC_THERM 0x644
+#define CLK_SOURCE_XUSB_HOST_SRC 0x600
+#define CLK_SOURCE_XUSB_FALCON_SRC 0x604
+#define CLK_SOURCE_XUSB_FS_SRC 0x608
+#define CLK_SOURCE_XUSB_SS_SRC 0x610
+#define CLK_SOURCE_XUSB_DEV_SRC 0x60c
+#define CLK_SOURCE_EMC 0x19c
+
+static int periph_clk_enb_refcnt[CLK_OUT_ENB_NUM * 32];
+
+static void __iomem *clk_base;
+static void __iomem *pmc_base;
+
+static DEFINE_SPINLOCK(pll_d_lock);
+static DEFINE_SPINLOCK(pll_d2_lock);
+static DEFINE_SPINLOCK(pll_u_lock);
+static DEFINE_SPINLOCK(pll_div_lock);
+static DEFINE_SPINLOCK(pll_re_lock);
+static DEFINE_SPINLOCK(clk_doubler_lock);
+static DEFINE_SPINLOCK(clk_out_lock);
+static DEFINE_SPINLOCK(sysrate_lock);
+
+static struct pdiv_map pllxc_p[] = {
+       { .pdiv = 1, .hw_val = 0 },
+       { .pdiv = 2, .hw_val = 1 },
+       { .pdiv = 3, .hw_val = 2 },
+       { .pdiv = 4, .hw_val = 3 },
+       { .pdiv = 5, .hw_val = 4 },
+       { .pdiv = 6, .hw_val = 5 },
+       { .pdiv = 8, .hw_val = 6 },
+       { .pdiv = 10, .hw_val = 7 },
+       { .pdiv = 12, .hw_val = 8 },
+       { .pdiv = 16, .hw_val = 9 },
+       { .pdiv = 12, .hw_val = 10 },
+       { .pdiv = 16, .hw_val = 11 },
+       { .pdiv = 20, .hw_val = 12 },
+       { .pdiv = 24, .hw_val = 13 },
+       { .pdiv = 32, .hw_val = 14 },
+       { .pdiv = 0, .hw_val = 0 },
+};
+
+static struct tegra_clk_pll_freq_table pll_c_freq_table[] = {
+       { 12000000, 624000000, 104, 0, 2},
+       { 12000000, 600000000, 100, 0, 2},
+       { 13000000, 600000000,  92, 0, 2},      /* actual: 598.0 MHz */
+       { 16800000, 600000000,  71, 0, 2},      /* actual: 596.4 MHz */
+       { 19200000, 600000000,  62, 0, 2},      /* actual: 595.2 MHz */
+       { 26000000, 600000000,  92, 1, 2},      /* actual: 598.0 MHz */
+       { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct tegra_clk_pll_params pll_c_params = {
+       .input_min = 12000000,
+       .input_max = 800000000,
+       .cf_min = 12000000,
+       .cf_max = 19200000,     /* s/w policy, h/w capability 50 MHz */
+       .vco_min = 600000000,
+       .vco_max = 1400000000,
+       .base_reg = PLLC_BASE,
+       .misc_reg = PLLC_MISC,
+       .lock_mask = PLL_BASE_LOCK,
+       .lock_enable_bit_idx = PLLC_MISC_LOCK_ENABLE,
+       .lock_delay = 300,
+       .iddq_reg = PLLC_MISC,
+       .iddq_bit_idx = PLLC_IDDQ_BIT,
+       .max_p = PLLXC_SW_MAX_P,
+       .dyn_ramp_reg = PLLC_MISC2,
+       .stepa_shift = 17,
+       .stepb_shift = 9,
+       .pdiv_tohw = pllxc_p,
+};
+
+static struct pdiv_map pllc_p[] = {
+       { .pdiv = 1, .hw_val = 0 },
+       { .pdiv = 2, .hw_val = 1 },
+       { .pdiv = 4, .hw_val = 3 },
+       { .pdiv = 8, .hw_val = 5 },
+       { .pdiv = 16, .hw_val = 7 },
+       { .pdiv = 0, .hw_val = 0 },
+};
+
+static struct tegra_clk_pll_freq_table pll_cx_freq_table[] = {
+       {12000000, 600000000, 100, 0, 2},
+       {13000000, 600000000, 92, 0, 2},        /* actual: 598.0 MHz */
+       {16800000, 600000000, 71, 0, 2},        /* actual: 596.4 MHz */
+       {19200000, 600000000, 62, 0, 2},        /* actual: 595.2 MHz */
+       {26000000, 600000000, 92, 1, 2},        /* actual: 598.0 MHz */
+       {0, 0, 0, 0, 0, 0},
+};
+
+static struct tegra_clk_pll_params pll_c2_params = {
+       .input_min = 12000000,
+       .input_max = 48000000,
+       .cf_min = 12000000,
+       .cf_max = 19200000,
+       .vco_min = 600000000,
+       .vco_max = 1200000000,
+       .base_reg = PLLC2_BASE,
+       .misc_reg = PLLC2_MISC,
+       .lock_mask = PLL_BASE_LOCK,
+       .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
+       .lock_delay = 300,
+       .pdiv_tohw = pllc_p,
+       .ext_misc_reg[0] = 0x4f0,
+       .ext_misc_reg[1] = 0x4f4,
+       .ext_misc_reg[2] = 0x4f8,
+};
+
+static struct tegra_clk_pll_params pll_c3_params = {
+       .input_min = 12000000,
+       .input_max = 48000000,
+       .cf_min = 12000000,
+       .cf_max = 19200000,
+       .vco_min = 600000000,
+       .vco_max = 1200000000,
+       .base_reg = PLLC3_BASE,
+       .misc_reg = PLLC3_MISC,
+       .lock_mask = PLL_BASE_LOCK,
+       .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
+       .lock_delay = 300,
+       .pdiv_tohw = pllc_p,
+       .ext_misc_reg[0] = 0x504,
+       .ext_misc_reg[1] = 0x508,
+       .ext_misc_reg[2] = 0x50c,
+};
+
+static struct pdiv_map pllm_p[] = {
+       { .pdiv = 1, .hw_val = 0 },
+       { .pdiv = 2, .hw_val = 1 },
+       { .pdiv = 0, .hw_val = 0 },
+};
+
+static struct tegra_clk_pll_freq_table pll_m_freq_table[] = {
+       {12000000, 800000000, 66, 0, 1},        /* actual: 792.0 MHz */
+       {13000000, 800000000, 61, 0, 1},        /* actual: 793.0 MHz */
+       {16800000, 800000000, 47, 0, 1},        /* actual: 789.6 MHz */
+       {19200000, 800000000, 41, 0, 1},        /* actual: 787.2 MHz */
+       {26000000, 800000000, 61, 1, 1},        /* actual: 793.0 MHz */
+       {0, 0, 0, 0, 0, 0},
+};
+
+static struct tegra_clk_pll_params pll_m_params = {
+       .input_min = 12000000,
+       .input_max = 500000000,
+       .cf_min = 12000000,
+       .cf_max = 19200000,     /* s/w policy, h/w capability 50 MHz */
+       .vco_min = 400000000,
+       .vco_max = 1066000000,
+       .base_reg = PLLM_BASE,
+       .misc_reg = PLLM_MISC,
+       .lock_mask = PLL_BASE_LOCK,
+       .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
+       .lock_delay = 300,
+       .max_p = 2,
+       .pdiv_tohw = pllm_p,
+};
+
+static struct tegra_clk_pll_freq_table pll_p_freq_table[] = {
+       {12000000, 216000000, 432, 12, 1, 8},
+       {13000000, 216000000, 432, 13, 1, 8},
+       {16800000, 216000000, 360, 14, 1, 8},
+       {19200000, 216000000, 360, 16, 1, 8},
+       {26000000, 216000000, 432, 26, 1, 8},
+       {0, 0, 0, 0, 0, 0},
+};
+
+static struct tegra_clk_pll_params pll_p_params = {
+       .input_min = 2000000,
+       .input_max = 31000000,
+       .cf_min = 1000000,
+       .cf_max = 6000000,
+       .vco_min = 200000000,
+       .vco_max = 700000000,
+       .base_reg = PLLP_BASE,
+       .misc_reg = PLLP_MISC,
+       .lock_mask = PLL_BASE_LOCK,
+       .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
+       .lock_delay = 300,
+};
+
+static struct tegra_clk_pll_freq_table pll_a_freq_table[] = {
+       {9600000, 282240000, 147, 5, 0, 4},
+       {9600000, 368640000, 192, 5, 0, 4},
+       {9600000, 240000000, 200, 8, 0, 8},
+
+       {28800000, 282240000, 245, 25, 0, 8},
+       {28800000, 368640000, 320, 25, 0, 8},
+       {28800000, 240000000, 200, 24, 0, 8},
+       {0, 0, 0, 0, 0, 0},
+};
+
+
+static struct tegra_clk_pll_params pll_a_params = {
+       .input_min = 2000000,
+       .input_max = 31000000,
+       .cf_min = 1000000,
+       .cf_max = 6000000,
+       .vco_min = 200000000,
+       .vco_max = 700000000,
+       .base_reg = PLLA_BASE,
+       .misc_reg = PLLA_MISC,
+       .lock_mask = PLL_BASE_LOCK,
+       .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
+       .lock_delay = 300,
+};
+
+static struct tegra_clk_pll_freq_table pll_d_freq_table[] = {
+       {12000000, 216000000, 864, 12, 2, 12},
+       {13000000, 216000000, 864, 13, 2, 12},
+       {16800000, 216000000, 720, 14, 2, 12},
+       {19200000, 216000000, 720, 16, 2, 12},
+       {26000000, 216000000, 864, 26, 2, 12},
+
+       {12000000, 594000000, 594, 12, 0, 12},
+       {13000000, 594000000, 594, 13, 0, 12},
+       {16800000, 594000000, 495, 14, 0, 12},
+       {19200000, 594000000, 495, 16, 0, 12},
+       {26000000, 594000000, 594, 26, 0, 12},
+
+       {12000000, 1000000000, 1000, 12, 0, 12},
+       {13000000, 1000000000, 1000, 13, 0, 12},
+       {19200000, 1000000000, 625, 12, 0, 12},
+       {26000000, 1000000000, 1000, 26, 0, 12},
+
+       {0, 0, 0, 0, 0, 0},
+};
+
+static struct tegra_clk_pll_params pll_d_params = {
+       .input_min = 2000000,
+       .input_max = 40000000,
+       .cf_min = 1000000,
+       .cf_max = 6000000,
+       .vco_min = 500000000,
+       .vco_max = 1000000000,
+       .base_reg = PLLD_BASE,
+       .misc_reg = PLLD_MISC,
+       .lock_mask = PLL_BASE_LOCK,
+       .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
+       .lock_delay = 1000,
+};
+
+static struct tegra_clk_pll_params pll_d2_params = {
+       .input_min = 2000000,
+       .input_max = 40000000,
+       .cf_min = 1000000,
+       .cf_max = 6000000,
+       .vco_min = 500000000,
+       .vco_max = 1000000000,
+       .base_reg = PLLD2_BASE,
+       .misc_reg = PLLD2_MISC,
+       .lock_mask = PLL_BASE_LOCK,
+       .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
+       .lock_delay = 1000,
+};
+
+static struct pdiv_map pllu_p[] = {
+       { .pdiv = 1, .hw_val = 1 },
+       { .pdiv = 2, .hw_val = 0 },
+       { .pdiv = 0, .hw_val = 0 },
+};
+
+static struct tegra_clk_pll_freq_table pll_u_freq_table[] = {
+       {12000000, 480000000, 960, 12, 0, 12},
+       {13000000, 480000000, 960, 13, 0, 12},
+       {16800000, 480000000, 400, 7, 0, 5},
+       {19200000, 480000000, 200, 4, 0, 3},
+       {26000000, 480000000, 960, 26, 0, 12},
+       {0, 0, 0, 0, 0, 0},
+};
+
+static struct tegra_clk_pll_params pll_u_params = {
+       .input_min = 2000000,
+       .input_max = 40000000,
+       .cf_min = 1000000,
+       .cf_max = 6000000,
+       .vco_min = 480000000,
+       .vco_max = 960000000,
+       .base_reg = PLLU_BASE,
+       .misc_reg = PLLU_MISC,
+       .lock_mask = PLL_BASE_LOCK,
+       .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
+       .lock_delay = 1000,
+       .pdiv_tohw = pllu_p,
+};
+
+static struct tegra_clk_pll_freq_table pll_x_freq_table[] = {
+       /* 1 GHz */
+       {12000000, 1000000000, 83, 0, 1},       /* actual: 996.0 MHz */
+       {13000000, 1000000000, 76, 0, 1},       /* actual: 988.0 MHz */
+       {16800000, 1000000000, 59, 0, 1},       /* actual: 991.2 MHz */
+       {19200000, 1000000000, 52, 0, 1},       /* actual: 998.4 MHz */
+       {26000000, 1000000000, 76, 1, 1},       /* actual: 988.0 MHz */
+
+       {0, 0, 0, 0, 0, 0},
+};
+
+static struct tegra_clk_pll_params pll_x_params = {
+       .input_min = 12000000,
+       .input_max = 800000000,
+       .cf_min = 12000000,
+       .cf_max = 19200000,     /* s/w policy, h/w capability 50 MHz */
+       .vco_min = 700000000,
+       .vco_max = 2400000000U,
+       .base_reg = PLLX_BASE,
+       .misc_reg = PLLX_MISC,
+       .lock_mask = PLL_BASE_LOCK,
+       .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
+       .lock_delay = 300,
+       .iddq_reg = PLLX_MISC3,
+       .iddq_bit_idx = PLLX_IDDQ_BIT,
+       .max_p = PLLXC_SW_MAX_P,
+       .dyn_ramp_reg = PLLX_MISC2,
+       .stepa_shift = 16,
+       .stepb_shift = 24,
+       .pdiv_tohw = pllxc_p,
+};
+
+static struct tegra_clk_pll_freq_table pll_e_freq_table[] = {
+       /* PLLE special case: use cpcon field to store cml divider value */
+       {336000000, 100000000, 100, 21, 16, 11},
+       {312000000, 100000000, 200, 26, 24, 13},
+       {0, 0, 0, 0, 0, 0},
+};
+
+static struct tegra_clk_pll_params pll_e_params = {
+       .input_min = 12000000,
+       .input_max = 1000000000,
+       .cf_min = 12000000,
+       .cf_max = 75000000,
+       .vco_min = 1600000000,
+       .vco_max = 2400000000U,
+       .base_reg = PLLE_BASE,
+       .misc_reg = PLLE_MISC,
+       .aux_reg = PLLE_AUX,
+       .lock_mask = PLLE_MISC_LOCK,
+       .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE,
+       .lock_delay = 300,
+};
+
+static struct tegra_clk_pll_params pll_re_vco_params = {
+       .input_min = 12000000,
+       .input_max = 1000000000,
+       .cf_min = 12000000,
+       .cf_max = 19200000, /* s/w policy, h/w capability 38 MHz */
+       .vco_min = 300000000,
+       .vco_max = 600000000,
+       .base_reg = PLLRE_BASE,
+       .misc_reg = PLLRE_MISC,
+       .lock_mask = PLLRE_MISC_LOCK,
+       .lock_enable_bit_idx = PLLRE_MISC_LOCK_ENABLE,
+       .lock_delay = 300,
+       .iddq_reg = PLLRE_MISC,
+       .iddq_bit_idx = PLLRE_IDDQ_BIT,
+};
+
+/* Peripheral clock registers */
+
+static struct tegra_clk_periph_regs periph_l_regs = {
+       .enb_reg = CLK_OUT_ENB_L,
+       .enb_set_reg = CLK_OUT_ENB_SET_L,
+       .enb_clr_reg = CLK_OUT_ENB_CLR_L,
+       .rst_reg = RST_DEVICES_L,
+       .rst_set_reg = RST_DEVICES_SET_L,
+       .rst_clr_reg = RST_DEVICES_CLR_L,
+};
+
+static struct tegra_clk_periph_regs periph_h_regs = {
+       .enb_reg = CLK_OUT_ENB_H,
+       .enb_set_reg = CLK_OUT_ENB_SET_H,
+       .enb_clr_reg = CLK_OUT_ENB_CLR_H,
+       .rst_reg = RST_DEVICES_H,
+       .rst_set_reg = RST_DEVICES_SET_H,
+       .rst_clr_reg = RST_DEVICES_CLR_H,
+};
+
+static struct tegra_clk_periph_regs periph_u_regs = {
+       .enb_reg = CLK_OUT_ENB_U,
+       .enb_set_reg = CLK_OUT_ENB_SET_U,
+       .enb_clr_reg = CLK_OUT_ENB_CLR_U,
+       .rst_reg = RST_DEVICES_U,
+       .rst_set_reg = RST_DEVICES_SET_U,
+       .rst_clr_reg = RST_DEVICES_CLR_U,
+};
+
+static struct tegra_clk_periph_regs periph_v_regs = {
+       .enb_reg = CLK_OUT_ENB_V,
+       .enb_set_reg = CLK_OUT_ENB_SET_V,
+       .enb_clr_reg = CLK_OUT_ENB_CLR_V,
+       .rst_reg = RST_DEVICES_V,
+       .rst_set_reg = RST_DEVICES_SET_V,
+       .rst_clr_reg = RST_DEVICES_CLR_V,
+};
+
+static struct tegra_clk_periph_regs periph_w_regs = {
+       .enb_reg = CLK_OUT_ENB_W,
+       .enb_set_reg = CLK_OUT_ENB_SET_W,
+       .enb_clr_reg = CLK_OUT_ENB_CLR_W,
+       .rst_reg = RST_DEVICES_W,
+       .rst_set_reg = RST_DEVICES_SET_W,
+       .rst_clr_reg = RST_DEVICES_CLR_W,
+};
+
+/* possible OSC frequencies in Hz */
+static unsigned long tegra114_input_freq[] = {
+       [0] = 13000000,
+       [1] = 16800000,
+       [4] = 19200000,
+       [5] = 38400000,
+       [8] = 12000000,
+       [9] = 48000000,
+       [12] = 260000000,
+};
+
+#define MASK(x) (BIT(x) - 1)
+
+#define TEGRA_INIT_DATA_MUX(_name, _con_id, _dev_id, _parents, _offset,        \
+                           _clk_num, _regs, _gate_flags, _clk_id)      \
+       TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
+                       30, MASK(2), 0, 0, 8, 1, 0, _regs, _clk_num,    \
+                       periph_clk_enb_refcnt, _gate_flags, _clk_id,    \
+                       _parents##_idx, 0)
+
+#define TEGRA_INIT_DATA_MUX_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\
+                           _clk_num, _regs, _gate_flags, _clk_id, flags)\
+       TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
+                       30, MASK(2), 0, 0, 8, 1, 0, _regs, _clk_num,    \
+                       periph_clk_enb_refcnt, _gate_flags, _clk_id,    \
+                       _parents##_idx, flags)
+
+#define TEGRA_INIT_DATA_MUX8(_name, _con_id, _dev_id, _parents, _offset, \
+                            _clk_num, _regs, _gate_flags, _clk_id)     \
+       TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
+                       29, MASK(3), 0, 0, 8, 1, 0, _regs, _clk_num,    \
+                       periph_clk_enb_refcnt, _gate_flags, _clk_id,    \
+                       _parents##_idx, 0)
+
+#define TEGRA_INIT_DATA_INT(_name, _con_id, _dev_id, _parents, _offset,        \
+                           _clk_num, _regs, _gate_flags, _clk_id)      \
+       TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
+                       30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs,\
+                       _clk_num, periph_clk_enb_refcnt, _gate_flags,   \
+                       _clk_id, _parents##_idx, 0)
+
+#define TEGRA_INIT_DATA_INT_FLAGS(_name, _con_id, _dev_id, _parents, _offset,\
+                           _clk_num, _regs, _gate_flags, _clk_id, flags)\
+       TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
+                       30, MASK(2), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs,\
+                       _clk_num, periph_clk_enb_refcnt, _gate_flags,   \
+                       _clk_id, _parents##_idx, flags)
+
+#define TEGRA_INIT_DATA_INT8(_name, _con_id, _dev_id, _parents, _offset,\
+                           _clk_num, _regs, _gate_flags, _clk_id)      \
+       TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
+                       29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs,\
+                       _clk_num, periph_clk_enb_refcnt, _gate_flags,   \
+                       _clk_id, _parents##_idx, 0)
+
+#define TEGRA_INIT_DATA_UART(_name, _con_id, _dev_id, _parents, _offset,\
+                            _clk_num, _regs, _clk_id)                  \
+       TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
+                       30, MASK(2), 0, 0, 16, 1, TEGRA_DIVIDER_UART, _regs,\
+                       _clk_num, periph_clk_enb_refcnt, 0, _clk_id,    \
+                       _parents##_idx, 0)
+
+#define TEGRA_INIT_DATA_I2C(_name, _con_id, _dev_id, _parents, _offset,\
+                            _clk_num, _regs, _clk_id)                  \
+       TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
+                       30, MASK(2), 0, 0, 16, 0, 0, _regs, _clk_num,   \
+                       periph_clk_enb_refcnt, 0, _clk_id, _parents##_idx, 0)
+
+#define TEGRA_INIT_DATA_NODIV(_name, _con_id, _dev_id, _parents, _offset, \
+                             _mux_shift, _mux_mask, _clk_num, _regs,   \
+                             _gate_flags, _clk_id)                     \
+       TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset,\
+                       _mux_shift, _mux_mask, 0, 0, 0, 0, 0, _regs,    \
+                       _clk_num, periph_clk_enb_refcnt, _gate_flags,   \
+                       _clk_id, _parents##_idx, 0)
+
+#define TEGRA_INIT_DATA_XUSB(_name, _con_id, _dev_id, _parents, _offset, \
+                            _clk_num, _regs, _gate_flags, _clk_id)      \
+       TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parents, _offset, \
+                       29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_INT, _regs, \
+                       _clk_num, periph_clk_enb_refcnt, _gate_flags,    \
+                       _clk_id, _parents##_idx, 0)
+
+#define TEGRA_INIT_DATA_AUDIO(_name, _con_id, _dev_id, _offset,  _clk_num,\
+                                _regs, _gate_flags, _clk_id)           \
+       TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, mux_d_audio_clk, \
+                       _offset, 16, 0xE01F, 0, 0, 8, 1, 0, _regs, _clk_num, \
+                       periph_clk_enb_refcnt, _gate_flags , _clk_id,   \
+                       mux_d_audio_clk_idx, 0)
+
+enum tegra114_clk {
+       rtc = 4, timer = 5, uarta = 6, sdmmc2 = 9, i2s1 = 11, i2c1 = 12,
+       ndflash = 13, sdmmc1 = 14, sdmmc4 = 15, pwm = 17, i2s2 = 18, epp = 19,
+       gr_2d = 21, usbd = 22, isp = 23, gr_3d = 24, disp2 = 26, disp1 = 27,
+       host1x = 28, vcp = 29, i2s0 = 30, apbdma = 34, kbc = 36, kfuse = 40,
+       sbc1 = 41, nor = 42, sbc2 = 44, sbc3 = 46, i2c5 = 47, dsia = 48,
+       mipi = 50, hdmi = 51, csi = 52, i2c2 = 54, uartc = 55, mipi_cal = 56,
+       emc, usb2, usb3, vde = 61, bsea = 62, bsev = 63, uartd = 65,
+       i2c3 = 67, sbc4 = 68, sdmmc3 = 69, owr = 71, csite = 73,
+       la = 76, trace = 77, soc_therm = 78, dtv = 79, ndspeed = 80,
+       i2cslow = 81, dsib = 82, tsec = 83, xusb_host = 89, msenc = 91,
+       csus = 92, mselect = 99, tsensor = 100, i2s3 = 101, i2s4 = 102,
+       i2c4 = 103, sbc5 = 104, sbc6 = 105, d_audio, apbif = 107, dam0, dam1,
+       dam2, hda2codec_2x = 111, audio0_2x = 113, audio1_2x, audio2_2x,
+       audio3_2x, audio4_2x, spdif_2x, actmon = 119, extern1 = 120,
+       extern2 = 121, extern3 = 122, hda = 125, se = 127, hda2hdmi = 128,
+       cilab = 144, cilcd = 145, cile = 146, dsialp = 147, dsiblp = 148,
+       dds = 150, dp2 = 152, amx = 153, adx = 154, xusb_ss = 156, uartb = 192,
+       vfir, spdif_in, spdif_out, vi, vi_sensor, fuse, fuse_burn, clk_32k,
+       clk_m, clk_m_div2, clk_m_div4, pll_ref, pll_c, pll_c_out1, pll_c2,
+       pll_c3, pll_m, pll_m_out1, pll_p, pll_p_out1, pll_p_out2, pll_p_out3,
+       pll_p_out4, pll_a, pll_a_out0, pll_d, pll_d_out0, pll_d2, pll_d2_out0,
+       pll_u, pll_u_480M, pll_u_60M, pll_u_48M, pll_u_12M, pll_x, pll_x_out0,
+       pll_re_vco, pll_re_out, pll_e_out0, spdif_in_sync, i2s0_sync,
+       i2s1_sync, i2s2_sync, i2s3_sync, i2s4_sync, vimclk_sync, audio0,
+       audio1, audio2, audio3, audio4, spdif, clk_out_1, clk_out_2, clk_out_3,
+       blink, xusb_host_src = 252, xusb_falcon_src, xusb_fs_src, xusb_ss_src,
+       xusb_dev_src, xusb_dev, xusb_hs_src, sclk, hclk, pclk, cclk_g, cclk_lp,
+
+       /* Mux clocks */
+
+       audio0_mux = 300, audio1_mux, audio2_mux, audio3_mux, audio4_mux,
+       spdif_mux, clk_out_1_mux, clk_out_2_mux, clk_out_3_mux, dsia_mux,
+       dsib_mux, clk_max,
+};
+
+struct utmi_clk_param {
+       /* Oscillator Frequency in KHz */
+       u32 osc_frequency;
+       /* UTMIP PLL Enable Delay Count  */
+       u8 enable_delay_count;
+       /* UTMIP PLL Stable count */
+       u8 stable_count;
+       /*  UTMIP PLL Active delay count */
+       u8 active_delay_count;
+       /* UTMIP PLL Xtal frequency count */
+       u8 xtal_freq_count;
+};
+
+static const struct utmi_clk_param utmi_parameters[] = {
+       {.osc_frequency = 13000000, .enable_delay_count = 0x02,
+        .stable_count = 0x33, .active_delay_count = 0x05,
+        .xtal_freq_count = 0x7F},
+       {.osc_frequency = 19200000, .enable_delay_count = 0x03,
+        .stable_count = 0x4B, .active_delay_count = 0x06,
+        .xtal_freq_count = 0xBB},
+       {.osc_frequency = 12000000, .enable_delay_count = 0x02,
+        .stable_count = 0x2F, .active_delay_count = 0x04,
+        .xtal_freq_count = 0x76},
+       {.osc_frequency = 26000000, .enable_delay_count = 0x04,
+        .stable_count = 0x66, .active_delay_count = 0x09,
+        .xtal_freq_count = 0xFE},
+       {.osc_frequency = 16800000, .enable_delay_count = 0x03,
+        .stable_count = 0x41, .active_delay_count = 0x0A,
+        .xtal_freq_count = 0xA4},
+};
+
+/* peripheral mux definitions */
+
+#define MUX_I2S_SPDIF(_id)                                             \
+static const char *mux_pllaout0_##_id##_2x_pllp_clkm[] = { "pll_a_out0", \
+                                                          #_id, "pll_p",\
+                                                          "clk_m"};
+MUX_I2S_SPDIF(audio0)
+MUX_I2S_SPDIF(audio1)
+MUX_I2S_SPDIF(audio2)
+MUX_I2S_SPDIF(audio3)
+MUX_I2S_SPDIF(audio4)
+MUX_I2S_SPDIF(audio)
+
+#define mux_pllaout0_audio0_2x_pllp_clkm_idx NULL
+#define mux_pllaout0_audio1_2x_pllp_clkm_idx NULL
+#define mux_pllaout0_audio2_2x_pllp_clkm_idx NULL
+#define mux_pllaout0_audio3_2x_pllp_clkm_idx NULL
+#define mux_pllaout0_audio4_2x_pllp_clkm_idx NULL
+#define mux_pllaout0_audio_2x_pllp_clkm_idx NULL
+
+static const char *mux_pllp_pllc_pllm_clkm[] = {
+       "pll_p", "pll_c", "pll_m", "clk_m"
+};
+#define mux_pllp_pllc_pllm_clkm_idx NULL
+
+static const char *mux_pllp_pllc_pllm[] = { "pll_p", "pll_c", "pll_m" };
+#define mux_pllp_pllc_pllm_idx NULL
+
+static const char *mux_pllp_pllc_clk32_clkm[] = {
+       "pll_p", "pll_c", "clk_32k", "clk_m"
+};
+#define mux_pllp_pllc_clk32_clkm_idx NULL
+
+static const char *mux_plla_pllc_pllp_clkm[] = {
+       "pll_a_out0", "pll_c", "pll_p", "clk_m"
+};
+#define mux_plla_pllc_pllp_clkm_idx mux_pllp_pllc_pllm_clkm_idx
+
+static const char *mux_pllp_pllc2_c_c3_pllm_clkm[] = {
+       "pll_p", "pll_c2", "pll_c", "pll_c3", "pll_m", "clk_m"
+};
+static u32 mux_pllp_pllc2_c_c3_pllm_clkm_idx[] = {
+       [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 6,
+};
+
+static const char *mux_pllp_clkm[] = {
+       "pll_p", "clk_m"
+};
+static u32 mux_pllp_clkm_idx[] = {
+       [0] = 0, [1] = 3,
+};
+
+static const char *mux_pllm_pllc2_c_c3_pllp_plla[] = {
+       "pll_m", "pll_c2", "pll_c", "pll_c3", "pll_p", "pll_a_out0"
+};
+#define mux_pllm_pllc2_c_c3_pllp_plla_idx mux_pllp_pllc2_c_c3_pllm_clkm_idx
+
+static const char *mux_pllp_pllm_plld_plla_pllc_plld2_clkm[] = {
+       "pll_p", "pll_m", "pll_d_out0", "pll_a_out0", "pll_c",
+       "pll_d2_out0", "clk_m"
+};
+#define mux_pllp_pllm_plld_plla_pllc_plld2_clkm_idx NULL
+
+static const char *mux_pllm_pllc_pllp_plla[] = {
+       "pll_m", "pll_c", "pll_p", "pll_a_out0"
+};
+#define mux_pllm_pllc_pllp_plla_idx mux_pllp_pllc_pllm_clkm_idx
+
+static const char *mux_pllp_pllc_clkm[] = {
+       "pll_p", "pll_c", "pll_m"
+};
+static u32 mux_pllp_pllc_clkm_idx[] = {
+       [0] = 0, [1] = 1, [2] = 3,
+};
+
+static const char *mux_pllp_pllc_clkm_clk32[] = {
+       "pll_p", "pll_c", "clk_m", "clk_32k"
+};
+#define mux_pllp_pllc_clkm_clk32_idx NULL
+
+static const char *mux_plla_clk32_pllp_clkm_plle[] = {
+       "pll_a_out0", "clk_32k", "pll_p", "clk_m", "pll_e_out0"
+};
+#define mux_plla_clk32_pllp_clkm_plle_idx NULL
+
+static const char *mux_clkm_pllp_pllc_pllre[] = {
+       "clk_m", "pll_p", "pll_c", "pll_re_out"
+};
+static u32 mux_clkm_pllp_pllc_pllre_idx[] = {
+       [0] = 0, [1] = 1, [2] = 3, [3] = 5,
+};
+
+static const char *mux_clkm_48M_pllp_480M[] = {
+       "clk_m", "pll_u_48M", "pll_p", "pll_u_480M"
+};
+#define mux_clkm_48M_pllp_480M_idx NULL
+
+static const char *mux_clkm_pllre_clk32_480M_pllc_ref[] = {
+       "clk_m", "pll_re_out", "clk_32k", "pll_u_480M", "pll_c", "pll_ref"
+};
+static u32 mux_clkm_pllre_clk32_480M_pllc_ref_idx[] = {
+       [0] = 0, [1] = 1, [2] = 3, [3] = 3, [4] = 4, [5] = 7,
+};
+
+static const char *mux_plld_out0_plld2_out0[] = {
+       "pll_d_out0", "pll_d2_out0",
+};
+#define mux_plld_out0_plld2_out0_idx NULL
+
+static const char *mux_d_audio_clk[] = {
+       "pll_a_out0", "pll_p", "clk_m", "spdif_in_sync", "i2s0_sync",
+       "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync",
+};
+static u32 mux_d_audio_clk_idx[] = {
+       [0] = 0, [1] = 0x8000, [2] = 0xc000, [3] = 0xE000, [4] = 0xE001,
+       [5] = 0xE002, [6] = 0xE003, [7] = 0xE004, [8] = 0xE005, [9] = 0xE007,
+};
+
+static const char *mux_pllmcp_clkm[] = {
+       "pll_m_out0", "pll_c_out0", "pll_p_out0", "clk_m", "pll_m_ud",
+};
+
+static const struct clk_div_table pll_re_div_table[] = {
+       { .val = 0, .div = 1 },
+       { .val = 1, .div = 2 },
+       { .val = 2, .div = 3 },
+       { .val = 3, .div = 4 },
+       { .val = 4, .div = 5 },
+       { .val = 5, .div = 6 },
+       { .val = 0, .div = 0 },
+};
+
+static struct clk *clks[clk_max];
+static struct clk_onecell_data clk_data;
+
+static unsigned long osc_freq;
+static unsigned long pll_ref_freq;
+
+static int __init tegra114_osc_clk_init(void __iomem *clk_base)
+{
+       struct clk *clk;
+       u32 val, pll_ref_div;
+
+       val = readl_relaxed(clk_base + OSC_CTRL);
+
+       osc_freq = tegra114_input_freq[val >> OSC_CTRL_OSC_FREQ_SHIFT];
+       if (!osc_freq) {
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
+       /* clk_m */
+       clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT,
+                                     osc_freq);
+       clk_register_clkdev(clk, "clk_m", NULL);
+       clks[clk_m] = clk;
+
+       /* pll_ref */
+       val = (val >> OSC_CTRL_PLL_REF_DIV_SHIFT) & 3;
+       pll_ref_div = 1 << val;
+       clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m",
+                                       CLK_SET_RATE_PARENT, 1, pll_ref_div);
+       clk_register_clkdev(clk, "pll_ref", NULL);
+       clks[pll_ref] = clk;
+
+       pll_ref_freq = osc_freq / pll_ref_div;
+
+       return 0;
+}
+
+static void __init tegra114_fixed_clk_init(void __iomem *clk_base)
+{
+       struct clk *clk;
+
+       /* clk_32k */
+       clk = clk_register_fixed_rate(NULL, "clk_32k", NULL, CLK_IS_ROOT,
+                                     32768);
+       clk_register_clkdev(clk, "clk_32k", NULL);
+       clks[clk_32k] = clk;
+
+       /* clk_m_div2 */
+       clk = clk_register_fixed_factor(NULL, "clk_m_div2", "clk_m",
+                                       CLK_SET_RATE_PARENT, 1, 2);
+       clk_register_clkdev(clk, "clk_m_div2", NULL);
+       clks[clk_m_div2] = clk;
+
+       /* clk_m_div4 */
+       clk = clk_register_fixed_factor(NULL, "clk_m_div4", "clk_m",
+                                       CLK_SET_RATE_PARENT, 1, 4);
+       clk_register_clkdev(clk, "clk_m_div4", NULL);
+       clks[clk_m_div4] = clk;
+
+}
+
+static __init void tegra114_utmi_param_configure(void __iomem *clk_base)
+{
+       u32 reg;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) {
+               if (osc_freq == utmi_parameters[i].osc_frequency)
+                       break;
+       }
+
+       if (i >= ARRAY_SIZE(utmi_parameters)) {
+               pr_err("%s: Unexpected oscillator freq %lu\n", __func__,
+                      osc_freq);
+               return;
+       }
+
+       reg = readl_relaxed(clk_base + UTMIP_PLL_CFG2);
+
+       /* Program UTMIP PLL stable and active counts */
+       /* [FIXME] arclk_rst.h says WRONG! This should be 1ms -> 0x50 Check! */
+       reg &= ~UTMIP_PLL_CFG2_STABLE_COUNT(~0);
+       reg |= UTMIP_PLL_CFG2_STABLE_COUNT(utmi_parameters[i].stable_count);
+
+       reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0);
+
+       reg |= UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(utmi_parameters[i].
+                                           active_delay_count);
+
+       /* Remove power downs from UTMIP PLL control bits */
+       reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN;
+       reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN;
+       reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN;
+
+       writel_relaxed(reg, clk_base + UTMIP_PLL_CFG2);
+
+       /* Program UTMIP PLL delay and oscillator frequency counts */
+       reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1);
+       reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0);
+
+       reg |= UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(utmi_parameters[i].
+                                           enable_delay_count);
+
+       reg &= ~UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(~0);
+       reg |= UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(utmi_parameters[i].
+                                          xtal_freq_count);
+
+       /* Remove power downs from UTMIP PLL control bits */
+       reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN;
+       reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN;
+       reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERUP;
+       reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN;
+       writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1);
+
+       /* Setup HW control of UTMIPLL */
+       reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0);
+       reg |= UTMIPLL_HW_PWRDN_CFG0_USE_LOCKDET;
+       reg &= ~UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL;
+       reg |= UTMIPLL_HW_PWRDN_CFG0_SEQ_START_STATE;
+       writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0);
+
+       reg = readl_relaxed(clk_base + UTMIP_PLL_CFG1);
+       reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP;
+       reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN;
+       writel_relaxed(reg, clk_base + UTMIP_PLL_CFG1);
+
+       udelay(1);
+
+       /* Setup SW override of UTMIPLL assuming USB2.0
+          ports are assigned to USB2 */
+       reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0);
+       reg |= UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL;
+       reg &= ~UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE;
+       writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0);
+
+       udelay(1);
+
+       /* Enable HW control UTMIPLL */
+       reg = readl_relaxed(clk_base + UTMIPLL_HW_PWRDN_CFG0);
+       reg |= UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE;
+       writel_relaxed(reg, clk_base + UTMIPLL_HW_PWRDN_CFG0);
+}
+
+static void __init _clip_vco_min(struct tegra_clk_pll_params *pll_params)
+{
+       pll_params->vco_min =
+               DIV_ROUND_UP(pll_params->vco_min, pll_ref_freq) * pll_ref_freq;
+}
+
+static int __init _setup_dynamic_ramp(struct tegra_clk_pll_params *pll_params,
+                                     void __iomem *clk_base)
+{
+       u32 val;
+       u32 step_a, step_b;
+
+       switch (pll_ref_freq) {
+       case 12000000:
+       case 13000000:
+       case 26000000:
+               step_a = 0x2B;
+               step_b = 0x0B;
+               break;
+       case 16800000:
+               step_a = 0x1A;
+               step_b = 0x09;
+               break;
+       case 19200000:
+               step_a = 0x12;
+               step_b = 0x08;
+               break;
+       default:
+               pr_err("%s: Unexpected reference rate %lu\n",
+                       __func__, pll_ref_freq);
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
+       val = step_a << pll_params->stepa_shift;
+       val |= step_b << pll_params->stepb_shift;
+       writel_relaxed(val, clk_base + pll_params->dyn_ramp_reg);
+
+       return 0;
+}
+
+static void __init _init_iddq(struct tegra_clk_pll_params *pll_params,
+                             void __iomem *clk_base)
+{
+       u32 val, val_iddq;
+
+       val = readl_relaxed(clk_base + pll_params->base_reg);
+       val_iddq = readl_relaxed(clk_base + pll_params->iddq_reg);
+
+       if (val & BIT(30))
+               WARN_ON(val_iddq & BIT(pll_params->iddq_bit_idx));
+       else {
+               val_iddq |= BIT(pll_params->iddq_bit_idx);
+               writel_relaxed(val_iddq, clk_base + pll_params->iddq_reg);
+       }
+}
+
+static void __init tegra114_pll_init(void __iomem *clk_base,
+                                    void __iomem *pmc)
+{
+       u32 val;
+       struct clk *clk;
+
+       /* PLLC */
+       _clip_vco_min(&pll_c_params);
+       if (_setup_dynamic_ramp(&pll_c_params, clk_base) >= 0) {
+               _init_iddq(&pll_c_params, clk_base);
+               clk = tegra_clk_register_pllxc("pll_c", "pll_ref", clk_base,
+                               pmc, 0, 0, &pll_c_params, TEGRA_PLL_USE_LOCK,
+                               pll_c_freq_table, NULL);
+               clk_register_clkdev(clk, "pll_c", NULL);
+               clks[pll_c] = clk;
+
+               /* PLLC_OUT1 */
+               clk = tegra_clk_register_divider("pll_c_out1_div", "pll_c",
+                               clk_base + PLLC_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
+                               8, 8, 1, NULL);
+               clk = tegra_clk_register_pll_out("pll_c_out1", "pll_c_out1_div",
+                                       clk_base + PLLC_OUT, 1, 0,
+                                       CLK_SET_RATE_PARENT, 0, NULL);
+               clk_register_clkdev(clk, "pll_c_out1", NULL);
+               clks[pll_c_out1] = clk;
+       }
+
+       /* PLLC2 */
+       _clip_vco_min(&pll_c2_params);
+       clk = tegra_clk_register_pllc("pll_c2", "pll_ref", clk_base, pmc, 0, 0,
+                            &pll_c2_params, TEGRA_PLL_USE_LOCK,
+                            pll_cx_freq_table, NULL);
+       clk_register_clkdev(clk, "pll_c2", NULL);
+       clks[pll_c2] = clk;
+
+       /* PLLC3 */
+       _clip_vco_min(&pll_c3_params);
+       clk = tegra_clk_register_pllc("pll_c3", "pll_ref", clk_base, pmc, 0, 0,
+                            &pll_c3_params, TEGRA_PLL_USE_LOCK,
+                            pll_cx_freq_table, NULL);
+       clk_register_clkdev(clk, "pll_c3", NULL);
+       clks[pll_c3] = clk;
+
+       /* PLLP */
+       clk = tegra_clk_register_pll("pll_p", "pll_ref", clk_base, pmc, 0,
+                           408000000, &pll_p_params,
+                           TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK,
+                           pll_p_freq_table, NULL);
+       clk_register_clkdev(clk, "pll_p", NULL);
+       clks[pll_p] = clk;
+
+       /* PLLP_OUT1 */
+       clk = tegra_clk_register_divider("pll_p_out1_div", "pll_p",
+                               clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED |
+                               TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, &pll_div_lock);
+       clk = tegra_clk_register_pll_out("pll_p_out1", "pll_p_out1_div",
+                               clk_base + PLLP_OUTA, 1, 0,
+                               CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0,
+                               &pll_div_lock);
+       clk_register_clkdev(clk, "pll_p_out1", NULL);
+       clks[pll_p_out1] = clk;
+
+       /* PLLP_OUT2 */
+       clk = tegra_clk_register_divider("pll_p_out2_div", "pll_p",
+                               clk_base + PLLP_OUTA, 0, TEGRA_DIVIDER_FIXED |
+                               TEGRA_DIVIDER_ROUND_UP, 24, 8, 1,
+                               &pll_div_lock);
+       clk = tegra_clk_register_pll_out("pll_p_out2", "pll_p_out2_div",
+                               clk_base + PLLP_OUTA, 17, 16,
+                               CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0,
+                               &pll_div_lock);
+       clk_register_clkdev(clk, "pll_p_out2", NULL);
+       clks[pll_p_out2] = clk;
+
+       /* PLLP_OUT3 */
+       clk = tegra_clk_register_divider("pll_p_out3_div", "pll_p",
+                               clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED |
+                               TEGRA_DIVIDER_ROUND_UP, 8, 8, 1, &pll_div_lock);
+       clk = tegra_clk_register_pll_out("pll_p_out3", "pll_p_out3_div",
+                               clk_base + PLLP_OUTB, 1, 0,
+                               CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0,
+                               &pll_div_lock);
+       clk_register_clkdev(clk, "pll_p_out3", NULL);
+       clks[pll_p_out3] = clk;
+
+       /* PLLP_OUT4 */
+       clk = tegra_clk_register_divider("pll_p_out4_div", "pll_p",
+                               clk_base + PLLP_OUTB, 0, TEGRA_DIVIDER_FIXED |
+                               TEGRA_DIVIDER_ROUND_UP, 24, 8, 1,
+                               &pll_div_lock);
+       clk = tegra_clk_register_pll_out("pll_p_out4", "pll_p_out4_div",
+                               clk_base + PLLP_OUTB, 17, 16,
+                               CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0,
+                               &pll_div_lock);
+       clk_register_clkdev(clk, "pll_p_out4", NULL);
+       clks[pll_p_out4] = clk;
+
+       /* PLLM */
+       _clip_vco_min(&pll_m_params);
+       clk = tegra_clk_register_pllm("pll_m", "pll_ref", clk_base, pmc,
+                            CLK_IGNORE_UNUSED | CLK_SET_RATE_GATE, 0,
+                            &pll_m_params, TEGRA_PLL_USE_LOCK,
+                            pll_m_freq_table, NULL);
+       clk_register_clkdev(clk, "pll_m", NULL);
+       clks[pll_m] = clk;
+
+       /* PLLM_OUT1 */
+       clk = tegra_clk_register_divider("pll_m_out1_div", "pll_m",
+                               clk_base + PLLM_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
+                               8, 8, 1, NULL);
+       clk = tegra_clk_register_pll_out("pll_m_out1", "pll_m_out1_div",
+                               clk_base + PLLM_OUT, 1, 0, CLK_IGNORE_UNUSED |
+                               CLK_SET_RATE_PARENT, 0, NULL);
+       clk_register_clkdev(clk, "pll_m_out1", NULL);
+       clks[pll_m_out1] = clk;
+
+       /* PLLM_UD */
+       clk = clk_register_fixed_factor(NULL, "pll_m_ud", "pll_m",
+                                       CLK_SET_RATE_PARENT, 1, 1);
+
+       /* PLLX */
+       _clip_vco_min(&pll_x_params);
+       if (_setup_dynamic_ramp(&pll_x_params, clk_base) >= 0) {
+               _init_iddq(&pll_x_params, clk_base);
+               clk = tegra_clk_register_pllxc("pll_x", "pll_ref", clk_base,
+                               pmc, CLK_IGNORE_UNUSED, 0, &pll_x_params,
+                               TEGRA_PLL_USE_LOCK, pll_x_freq_table, NULL);
+               clk_register_clkdev(clk, "pll_x", NULL);
+               clks[pll_x] = clk;
+       }
+
+       /* PLLX_OUT0 */
+       clk = clk_register_fixed_factor(NULL, "pll_x_out0", "pll_x",
+                                       CLK_SET_RATE_PARENT, 1, 2);
+       clk_register_clkdev(clk, "pll_x_out0", NULL);
+       clks[pll_x_out0] = clk;
+
+       /* PLLU */
+       val = readl(clk_base + pll_u_params.base_reg);
+       val &= ~BIT(24); /* disable PLLU_OVERRIDE */
+       writel(val, clk_base + pll_u_params.base_reg);
+
+       clk = tegra_clk_register_pll("pll_u", "pll_ref", clk_base, pmc, 0,
+                           0, &pll_u_params, TEGRA_PLLU |
+                           TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON |
+                           TEGRA_PLL_USE_LOCK, pll_u_freq_table, &pll_u_lock);
+       clk_register_clkdev(clk, "pll_u", NULL);
+       clks[pll_u] = clk;
+
+       tegra114_utmi_param_configure(clk_base);
+
+       /* PLLU_480M */
+       clk = clk_register_gate(NULL, "pll_u_480M", "pll_u",
+                               CLK_SET_RATE_PARENT, clk_base + PLLU_BASE,
+                               22, 0, &pll_u_lock);
+       clk_register_clkdev(clk, "pll_u_480M", NULL);
+       clks[pll_u_480M] = clk;
+
+       /* PLLU_60M */
+       clk = clk_register_fixed_factor(NULL, "pll_u_60M", "pll_u",
+                                       CLK_SET_RATE_PARENT, 1, 8);
+       clk_register_clkdev(clk, "pll_u_60M", NULL);
+       clks[pll_u_60M] = clk;
+
+       /* PLLU_48M */
+       clk = clk_register_fixed_factor(NULL, "pll_u_48M", "pll_u",
+                                       CLK_SET_RATE_PARENT, 1, 10);
+       clk_register_clkdev(clk, "pll_u_48M", NULL);
+       clks[pll_u_48M] = clk;
+
+       /* PLLU_12M */
+       clk = clk_register_fixed_factor(NULL, "pll_u_12M", "pll_u",
+                                       CLK_SET_RATE_PARENT, 1, 40);
+       clk_register_clkdev(clk, "pll_u_12M", NULL);
+       clks[pll_u_12M] = clk;
+
+       /* PLLD */
+       clk = tegra_clk_register_pll("pll_d", "pll_ref", clk_base, pmc, 0,
+                           0, &pll_d_params,
+                           TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON |
+                           TEGRA_PLL_USE_LOCK, pll_d_freq_table, &pll_d_lock);
+       clk_register_clkdev(clk, "pll_d", NULL);
+       clks[pll_d] = clk;
+
+       /* PLLD_OUT0 */
+       clk = clk_register_fixed_factor(NULL, "pll_d_out0", "pll_d",
+                                       CLK_SET_RATE_PARENT, 1, 2);
+       clk_register_clkdev(clk, "pll_d_out0", NULL);
+       clks[pll_d_out0] = clk;
+
+       /* PLLD2 */
+       clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc, 0,
+                           0, &pll_d2_params,
+                           TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_LFCON |
+                           TEGRA_PLL_USE_LOCK, pll_d_freq_table, &pll_d2_lock);
+       clk_register_clkdev(clk, "pll_d2", NULL);
+       clks[pll_d2] = clk;
+
+       /* PLLD2_OUT0 */
+       clk = clk_register_fixed_factor(NULL, "pll_d2_out0", "pll_d2",
+                                       CLK_SET_RATE_PARENT, 1, 2);
+       clk_register_clkdev(clk, "pll_d2_out0", NULL);
+       clks[pll_d2_out0] = clk;
+
+       /* PLLA */
+       clk = tegra_clk_register_pll("pll_a", "pll_p_out1", clk_base, pmc, 0,
+                           0, &pll_a_params, TEGRA_PLL_HAS_CPCON |
+                           TEGRA_PLL_USE_LOCK, pll_a_freq_table, NULL);
+       clk_register_clkdev(clk, "pll_a", NULL);
+       clks[pll_a] = clk;
+
+       /* PLLA_OUT0 */
+       clk = tegra_clk_register_divider("pll_a_out0_div", "pll_a",
+                               clk_base + PLLA_OUT, 0, TEGRA_DIVIDER_ROUND_UP,
+                               8, 8, 1, NULL);
+       clk = tegra_clk_register_pll_out("pll_a_out0", "pll_a_out0_div",
+                               clk_base + PLLA_OUT, 1, 0, CLK_IGNORE_UNUSED |
+                               CLK_SET_RATE_PARENT, 0, NULL);
+       clk_register_clkdev(clk, "pll_a_out0", NULL);
+       clks[pll_a_out0] = clk;
+
+       /* PLLRE */
+       _clip_vco_min(&pll_re_vco_params);
+       clk = tegra_clk_register_pllre("pll_re_vco", "pll_ref", clk_base, pmc,
+                            0, 0, &pll_re_vco_params, TEGRA_PLL_USE_LOCK,
+                            NULL, &pll_re_lock, pll_ref_freq);
+       clk_register_clkdev(clk, "pll_re_vco", NULL);
+       clks[pll_re_vco] = clk;
+
+       clk = clk_register_divider_table(NULL, "pll_re_out", "pll_re_vco", 0,
+                                        clk_base + PLLRE_BASE, 16, 4, 0,
+                                        pll_re_div_table, &pll_re_lock);
+       clk_register_clkdev(clk, "pll_re_out", NULL);
+       clks[pll_re_out] = clk;
+
+       /* PLLE */
+       clk = tegra_clk_register_plle_tegra114("pll_e_out0", "pll_re_vco",
+                                     clk_base, 0, 100000000, &pll_e_params,
+                                     pll_e_freq_table, NULL);
+       clk_register_clkdev(clk, "pll_e_out0", NULL);
+       clks[pll_e_out0] = clk;
+}
+
+static const char *mux_audio_sync_clk[] = { "spdif_in_sync", "i2s0_sync",
+       "i2s1_sync", "i2s2_sync", "i2s3_sync", "i2s4_sync", "vimclk_sync",
+};
+
+static const char *clk_out1_parents[] = { "clk_m", "clk_m_div2",
+       "clk_m_div4", "extern1",
+};
+
+static const char *clk_out2_parents[] = { "clk_m", "clk_m_div2",
+       "clk_m_div4", "extern2",
+};
+
+static const char *clk_out3_parents[] = { "clk_m", "clk_m_div2",
+       "clk_m_div4", "extern3",
+};
+
+static void __init tegra114_audio_clk_init(void __iomem *clk_base)
+{
+       struct clk *clk;
+
+       /* spdif_in_sync */
+       clk = tegra_clk_register_sync_source("spdif_in_sync", 24000000,
+                                            24000000);
+       clk_register_clkdev(clk, "spdif_in_sync", NULL);
+       clks[spdif_in_sync] = clk;
+
+       /* i2s0_sync */
+       clk = tegra_clk_register_sync_source("i2s0_sync", 24000000, 24000000);
+       clk_register_clkdev(clk, "i2s0_sync", NULL);
+       clks[i2s0_sync] = clk;
+
+       /* i2s1_sync */
+       clk = tegra_clk_register_sync_source("i2s1_sync", 24000000, 24000000);
+       clk_register_clkdev(clk, "i2s1_sync", NULL);
+       clks[i2s1_sync] = clk;
+
+       /* i2s2_sync */
+       clk = tegra_clk_register_sync_source("i2s2_sync", 24000000, 24000000);
+       clk_register_clkdev(clk, "i2s2_sync", NULL);
+       clks[i2s2_sync] = clk;
+
+       /* i2s3_sync */
+       clk = tegra_clk_register_sync_source("i2s3_sync", 24000000, 24000000);
+       clk_register_clkdev(clk, "i2s3_sync", NULL);
+       clks[i2s3_sync] = clk;
+
+       /* i2s4_sync */
+       clk = tegra_clk_register_sync_source("i2s4_sync", 24000000, 24000000);
+       clk_register_clkdev(clk, "i2s4_sync", NULL);
+       clks[i2s4_sync] = clk;
+
+       /* vimclk_sync */
+       clk = tegra_clk_register_sync_source("vimclk_sync", 24000000, 24000000);
+       clk_register_clkdev(clk, "vimclk_sync", NULL);
+       clks[vimclk_sync] = clk;
+
+       /* audio0 */
+       clk = clk_register_mux(NULL, "audio0_mux", mux_audio_sync_clk,
+                              ARRAY_SIZE(mux_audio_sync_clk), 0,
+                              clk_base + AUDIO_SYNC_CLK_I2S0, 0, 3, 0,
+                              NULL);
+       clks[audio0_mux] = clk;
+       clk = clk_register_gate(NULL, "audio0", "audio0_mux", 0,
+                               clk_base + AUDIO_SYNC_CLK_I2S0, 4,
+                               CLK_GATE_SET_TO_DISABLE, NULL);
+       clk_register_clkdev(clk, "audio0", NULL);
+       clks[audio0] = clk;
+
+       /* audio1 */
+       clk = clk_register_mux(NULL, "audio1_mux", mux_audio_sync_clk,
+                              ARRAY_SIZE(mux_audio_sync_clk), 0,
+                              clk_base + AUDIO_SYNC_CLK_I2S1, 0, 3, 0,
+                              NULL);
+       clks[audio1_mux] = clk;
+       clk = clk_register_gate(NULL, "audio1", "audio1_mux", 0,
+                               clk_base + AUDIO_SYNC_CLK_I2S1, 4,
+                               CLK_GATE_SET_TO_DISABLE, NULL);
+       clk_register_clkdev(clk, "audio1", NULL);
+       clks[audio1] = clk;
+
+       /* audio2 */
+       clk = clk_register_mux(NULL, "audio2_mux", mux_audio_sync_clk,
+                              ARRAY_SIZE(mux_audio_sync_clk), 0,
+                              clk_base + AUDIO_SYNC_CLK_I2S2, 0, 3, 0,
+                              NULL);
+       clks[audio2_mux] = clk;
+       clk = clk_register_gate(NULL, "audio2", "audio2_mux", 0,
+                               clk_base + AUDIO_SYNC_CLK_I2S2, 4,
+                               CLK_GATE_SET_TO_DISABLE, NULL);
+       clk_register_clkdev(clk, "audio2", NULL);
+       clks[audio2] = clk;
+
+       /* audio3 */
+       clk = clk_register_mux(NULL, "audio3_mux", mux_audio_sync_clk,
+                              ARRAY_SIZE(mux_audio_sync_clk), 0,
+                              clk_base + AUDIO_SYNC_CLK_I2S3, 0, 3, 0,
+                              NULL);
+       clks[audio3_mux] = clk;
+       clk = clk_register_gate(NULL, "audio3", "audio3_mux", 0,
+                               clk_base + AUDIO_SYNC_CLK_I2S3, 4,
+                               CLK_GATE_SET_TO_DISABLE, NULL);
+       clk_register_clkdev(clk, "audio3", NULL);
+       clks[audio3] = clk;
+
+       /* audio4 */
+       clk = clk_register_mux(NULL, "audio4_mux", mux_audio_sync_clk,
+                              ARRAY_SIZE(mux_audio_sync_clk), 0,
+                              clk_base + AUDIO_SYNC_CLK_I2S4, 0, 3, 0,
+                              NULL);
+       clks[audio4_mux] = clk;
+       clk = clk_register_gate(NULL, "audio4", "audio4_mux", 0,
+                               clk_base + AUDIO_SYNC_CLK_I2S4, 4,
+                               CLK_GATE_SET_TO_DISABLE, NULL);
+       clk_register_clkdev(clk, "audio4", NULL);
+       clks[audio4] = clk;
+
+       /* spdif */
+       clk = clk_register_mux(NULL, "spdif_mux", mux_audio_sync_clk,
+                              ARRAY_SIZE(mux_audio_sync_clk), 0,
+                              clk_base + AUDIO_SYNC_CLK_SPDIF, 0, 3, 0,
+                              NULL);
+       clks[spdif_mux] = clk;
+       clk = clk_register_gate(NULL, "spdif", "spdif_mux", 0,
+                               clk_base + AUDIO_SYNC_CLK_SPDIF, 4,
+                               CLK_GATE_SET_TO_DISABLE, NULL);
+       clk_register_clkdev(clk, "spdif", NULL);
+       clks[spdif] = clk;
+
+       /* audio0_2x */
+       clk = clk_register_fixed_factor(NULL, "audio0_doubler", "audio0",
+                                       CLK_SET_RATE_PARENT, 2, 1);
+       clk = tegra_clk_register_divider("audio0_div", "audio0_doubler",
+                               clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 24, 1,
+                               0, &clk_doubler_lock);
+       clk = tegra_clk_register_periph_gate("audio0_2x", "audio0_div",
+                                 TEGRA_PERIPH_NO_RESET, clk_base,
+                                 CLK_SET_RATE_PARENT, 113, &periph_v_regs,
+                                 periph_clk_enb_refcnt);
+       clk_register_clkdev(clk, "audio0_2x", NULL);
+       clks[audio0_2x] = clk;
+
+       /* audio1_2x */
+       clk = clk_register_fixed_factor(NULL, "audio1_doubler", "audio1",
+                                       CLK_SET_RATE_PARENT, 2, 1);
+       clk = tegra_clk_register_divider("audio1_div", "audio1_doubler",
+                               clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 25, 1,
+                               0, &clk_doubler_lock);
+       clk = tegra_clk_register_periph_gate("audio1_2x", "audio1_div",
+                                 TEGRA_PERIPH_NO_RESET, clk_base,
+                                 CLK_SET_RATE_PARENT, 114, &periph_v_regs,
+                                 periph_clk_enb_refcnt);
+       clk_register_clkdev(clk, "audio1_2x", NULL);
+       clks[audio1_2x] = clk;
+
+       /* audio2_2x */
+       clk = clk_register_fixed_factor(NULL, "audio2_doubler", "audio2",
+                                       CLK_SET_RATE_PARENT, 2, 1);
+       clk = tegra_clk_register_divider("audio2_div", "audio2_doubler",
+                               clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 26, 1,
+                               0, &clk_doubler_lock);
+       clk = tegra_clk_register_periph_gate("audio2_2x", "audio2_div",
+                                 TEGRA_PERIPH_NO_RESET, clk_base,
+                                 CLK_SET_RATE_PARENT, 115, &periph_v_regs,
+                                 periph_clk_enb_refcnt);
+       clk_register_clkdev(clk, "audio2_2x", NULL);
+       clks[audio2_2x] = clk;
+
+       /* audio3_2x */
+       clk = clk_register_fixed_factor(NULL, "audio3_doubler", "audio3",
+                                       CLK_SET_RATE_PARENT, 2, 1);
+       clk = tegra_clk_register_divider("audio3_div", "audio3_doubler",
+                               clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 27, 1,
+                               0, &clk_doubler_lock);
+       clk = tegra_clk_register_periph_gate("audio3_2x", "audio3_div",
+                                 TEGRA_PERIPH_NO_RESET, clk_base,
+                                 CLK_SET_RATE_PARENT, 116, &periph_v_regs,
+                                 periph_clk_enb_refcnt);
+       clk_register_clkdev(clk, "audio3_2x", NULL);
+       clks[audio3_2x] = clk;
+
+       /* audio4_2x */
+       clk = clk_register_fixed_factor(NULL, "audio4_doubler", "audio4",
+                                       CLK_SET_RATE_PARENT, 2, 1);
+       clk = tegra_clk_register_divider("audio4_div", "audio4_doubler",
+                               clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 28, 1,
+                               0, &clk_doubler_lock);
+       clk = tegra_clk_register_periph_gate("audio4_2x", "audio4_div",
+                                 TEGRA_PERIPH_NO_RESET, clk_base,
+                                 CLK_SET_RATE_PARENT, 117, &periph_v_regs,
+                                 periph_clk_enb_refcnt);
+       clk_register_clkdev(clk, "audio4_2x", NULL);
+       clks[audio4_2x] = clk;
+
+       /* spdif_2x */
+       clk = clk_register_fixed_factor(NULL, "spdif_doubler", "spdif",
+                                       CLK_SET_RATE_PARENT, 2, 1);
+       clk = tegra_clk_register_divider("spdif_div", "spdif_doubler",
+                               clk_base + AUDIO_SYNC_DOUBLER, 0, 0, 29, 1,
+                               0, &clk_doubler_lock);
+       clk = tegra_clk_register_periph_gate("spdif_2x", "spdif_div",
+                                 TEGRA_PERIPH_NO_RESET, clk_base,
+                                 CLK_SET_RATE_PARENT, 118,
+                                 &periph_v_regs, periph_clk_enb_refcnt);
+       clk_register_clkdev(clk, "spdif_2x", NULL);
+       clks[spdif_2x] = clk;
+}
+
+static void __init tegra114_pmc_clk_init(void __iomem *pmc_base)
+{
+       struct clk *clk;
+
+       /* clk_out_1 */
+       clk = clk_register_mux(NULL, "clk_out_1_mux", clk_out1_parents,
+                              ARRAY_SIZE(clk_out1_parents), 0,
+                              pmc_base + PMC_CLK_OUT_CNTRL, 6, 3, 0,
+                              &clk_out_lock);
+       clks[clk_out_1_mux] = clk;
+       clk = clk_register_gate(NULL, "clk_out_1", "clk_out_1_mux", 0,
+                               pmc_base + PMC_CLK_OUT_CNTRL, 2, 0,
+                               &clk_out_lock);
+       clk_register_clkdev(clk, "extern1", "clk_out_1");
+       clks[clk_out_1] = clk;
+
+       /* clk_out_2 */
+       clk = clk_register_mux(NULL, "clk_out_2_mux", clk_out2_parents,
+                              ARRAY_SIZE(clk_out1_parents), 0,
+                              pmc_base + PMC_CLK_OUT_CNTRL, 14, 3, 0,
+                              &clk_out_lock);
+       clks[clk_out_2_mux] = clk;
+       clk = clk_register_gate(NULL, "clk_out_2", "clk_out_2_mux", 0,
+                               pmc_base + PMC_CLK_OUT_CNTRL, 10, 0,
+                               &clk_out_lock);
+       clk_register_clkdev(clk, "extern2", "clk_out_2");
+       clks[clk_out_2] = clk;
+
+       /* clk_out_3 */
+       clk = clk_register_mux(NULL, "clk_out_3_mux", clk_out3_parents,
+                              ARRAY_SIZE(clk_out1_parents), 0,
+                              pmc_base + PMC_CLK_OUT_CNTRL, 22, 3, 0,
+                              &clk_out_lock);
+       clks[clk_out_3_mux] = clk;
+       clk = clk_register_gate(NULL, "clk_out_3", "clk_out_3_mux", 0,
+                               pmc_base + PMC_CLK_OUT_CNTRL, 18, 0,
+                               &clk_out_lock);
+       clk_register_clkdev(clk, "extern3", "clk_out_3");
+       clks[clk_out_3] = clk;
+
+       /* blink */
+       clk = clk_register_gate(NULL, "blink_override", "clk_32k", 0,
+                               pmc_base + PMC_DPD_PADS_ORIDE,
+                               PMC_DPD_PADS_ORIDE_BLINK_ENB, 0, NULL);
+       clk = clk_register_gate(NULL, "blink", "blink_override", 0,
+                               pmc_base + PMC_CTRL,
+                               PMC_CTRL_BLINK_ENB, 0, NULL);
+       clk_register_clkdev(clk, "blink", NULL);
+       clks[blink] = clk;
+
+}
+
+static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4",
+                              "pll_p_out3", "pll_p_out2", "unused",
+                              "clk_32k", "pll_m_out1" };
+
+static const char *cclk_g_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m",
+                                       "pll_p", "pll_p_out4", "unused",
+                                       "unused", "pll_x" };
+
+static const char *cclk_lp_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m",
+                                        "pll_p", "pll_p_out4", "unused",
+                                        "unused", "pll_x", "pll_x_out0" };
+
+static void __init tegra114_super_clk_init(void __iomem *clk_base)
+{
+       struct clk *clk;
+
+       /* CCLKG */
+       clk = tegra_clk_register_super_mux("cclk_g", cclk_g_parents,
+                                       ARRAY_SIZE(cclk_g_parents),
+                                       CLK_SET_RATE_PARENT,
+                                       clk_base + CCLKG_BURST_POLICY,
+                                       0, 4, 0, 0, NULL);
+       clk_register_clkdev(clk, "cclk_g", NULL);
+       clks[cclk_g] = clk;
+
+       /* CCLKLP */
+       clk = tegra_clk_register_super_mux("cclk_lp", cclk_lp_parents,
+                                       ARRAY_SIZE(cclk_lp_parents),
+                                       CLK_SET_RATE_PARENT,
+                                       clk_base + CCLKLP_BURST_POLICY,
+                                       0, 4, 8, 9, NULL);
+       clk_register_clkdev(clk, "cclk_lp", NULL);
+       clks[cclk_lp] = clk;
+
+       /* SCLK */
+       clk = tegra_clk_register_super_mux("sclk", sclk_parents,
+                                       ARRAY_SIZE(sclk_parents),
+                                       CLK_SET_RATE_PARENT,
+                                       clk_base + SCLK_BURST_POLICY,
+                                       0, 4, 0, 0, NULL);
+       clk_register_clkdev(clk, "sclk", NULL);
+       clks[sclk] = clk;
+
+       /* HCLK */
+       clk = clk_register_divider(NULL, "hclk_div", "sclk", 0,
+                                  clk_base + SYSTEM_CLK_RATE, 4, 2, 0,
+                                  &sysrate_lock);
+       clk = clk_register_gate(NULL, "hclk", "hclk_div", CLK_SET_RATE_PARENT |
+                               CLK_IGNORE_UNUSED, clk_base + SYSTEM_CLK_RATE,
+                               7, CLK_GATE_SET_TO_DISABLE, &sysrate_lock);
+       clk_register_clkdev(clk, "hclk", NULL);
+       clks[hclk] = clk;
+
+       /* PCLK */
+       clk = clk_register_divider(NULL, "pclk_div", "hclk", 0,
+                                  clk_base + SYSTEM_CLK_RATE, 0, 2, 0,
+                                  &sysrate_lock);
+       clk = clk_register_gate(NULL, "pclk", "pclk_div", CLK_SET_RATE_PARENT |
+                               CLK_IGNORE_UNUSED, clk_base + SYSTEM_CLK_RATE,
+                               3, CLK_GATE_SET_TO_DISABLE, &sysrate_lock);
+       clk_register_clkdev(clk, "pclk", NULL);
+       clks[pclk] = clk;
+}
+
+static struct tegra_periph_init_data tegra_periph_clk_list[] = {
+       TEGRA_INIT_DATA_MUX("i2s0", NULL, "tegra30-i2s.0", mux_pllaout0_audio0_2x_pllp_clkm, CLK_SOURCE_I2S0, 30, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s0),
+       TEGRA_INIT_DATA_MUX("i2s1", NULL, "tegra30-i2s.1", mux_pllaout0_audio1_2x_pllp_clkm, CLK_SOURCE_I2S1, 11, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s1),
+       TEGRA_INIT_DATA_MUX("i2s2", NULL, "tegra30-i2s.2", mux_pllaout0_audio2_2x_pllp_clkm, CLK_SOURCE_I2S2, 18, &periph_l_regs, TEGRA_PERIPH_ON_APB, i2s2),
+       TEGRA_INIT_DATA_MUX("i2s3", NULL, "tegra30-i2s.3", mux_pllaout0_audio3_2x_pllp_clkm, CLK_SOURCE_I2S3, 101, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s3),
+       TEGRA_INIT_DATA_MUX("i2s4", NULL, "tegra30-i2s.4", mux_pllaout0_audio4_2x_pllp_clkm, CLK_SOURCE_I2S4, 102, &periph_v_regs, TEGRA_PERIPH_ON_APB, i2s4),
+       TEGRA_INIT_DATA_MUX("spdif_out", "spdif_out", "tegra30-spdif", mux_pllaout0_audio_2x_pllp_clkm, CLK_SOURCE_SPDIF_OUT, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_out),
+       TEGRA_INIT_DATA_MUX("spdif_in", "spdif_in", "tegra30-spdif", mux_pllp_pllc_pllm, CLK_SOURCE_SPDIF_IN, 10, &periph_l_regs, TEGRA_PERIPH_ON_APB, spdif_in),
+       TEGRA_INIT_DATA_MUX("pwm", NULL, "pwm", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_PWM, 17, &periph_l_regs, TEGRA_PERIPH_ON_APB, pwm),
+       TEGRA_INIT_DATA_MUX("adx", NULL, "adx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_ADX, 154, &periph_w_regs, TEGRA_PERIPH_ON_APB, adx),
+       TEGRA_INIT_DATA_MUX("amx", NULL, "amx", mux_plla_pllc_pllp_clkm, CLK_SOURCE_AMX, 153, &periph_w_regs, TEGRA_PERIPH_ON_APB, amx),
+       TEGRA_INIT_DATA_MUX("hda", "hda", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA, 125, &periph_v_regs, TEGRA_PERIPH_ON_APB, hda),
+       TEGRA_INIT_DATA_MUX("hda2codec_2x", "hda2codec", "tegra30-hda", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_HDA2CODEC_2X, 111, &periph_v_regs, TEGRA_PERIPH_ON_APB, hda2codec_2x),
+       TEGRA_INIT_DATA_MUX("sbc1", NULL, "tegra11-spi.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC1, 41, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc1),
+       TEGRA_INIT_DATA_MUX("sbc2", NULL, "tegra11-spi.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC2, 44, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc2),
+       TEGRA_INIT_DATA_MUX("sbc3", NULL, "tegra11-spi.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC3, 46, &periph_h_regs, TEGRA_PERIPH_ON_APB, sbc3),
+       TEGRA_INIT_DATA_MUX("sbc4", NULL, "tegra11-spi.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC4, 68, &periph_u_regs, TEGRA_PERIPH_ON_APB, sbc4),
+       TEGRA_INIT_DATA_MUX("sbc5", NULL, "tegra11-spi.4", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC5, 104, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc5),
+       TEGRA_INIT_DATA_MUX("sbc6", NULL, "tegra11-spi.5", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SBC6, 105, &periph_v_regs, TEGRA_PERIPH_ON_APB, sbc6),
+       TEGRA_INIT_DATA_MUX8("ndflash", NULL, "tegra_nand", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDFLASH, 13, &periph_u_regs, TEGRA_PERIPH_ON_APB, ndspeed),
+       TEGRA_INIT_DATA_MUX8("ndspeed", NULL, "tegra_nand_speed", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_NDSPEED, 80, &periph_u_regs, TEGRA_PERIPH_ON_APB, ndspeed),
+       TEGRA_INIT_DATA_MUX("vfir", NULL, "vfir", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_VFIR, 7, &periph_l_regs, TEGRA_PERIPH_ON_APB, vfir),
+       TEGRA_INIT_DATA_MUX("sdmmc1", NULL, "sdhci-tegra.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC1, 14, &periph_l_regs, 0, sdmmc1),
+       TEGRA_INIT_DATA_MUX("sdmmc2", NULL, "sdhci-tegra.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC2, 9, &periph_l_regs, 0, sdmmc2),
+       TEGRA_INIT_DATA_MUX("sdmmc3", NULL, "sdhci-tegra.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC3, 69, &periph_u_regs, 0, sdmmc3),
+       TEGRA_INIT_DATA_MUX("sdmmc4", NULL, "sdhci-tegra.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_SDMMC4, 15, &periph_l_regs, 0, sdmmc4),
+       TEGRA_INIT_DATA_INT("vde", NULL, "vde", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_VDE, 61, &periph_h_regs, 0, vde),
+       TEGRA_INIT_DATA_MUX_FLAGS("csite", NULL, "csite", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_CSITE, 73, &periph_u_regs, TEGRA_PERIPH_ON_APB, csite, CLK_IGNORE_UNUSED),
+       TEGRA_INIT_DATA_MUX("la", NULL, "la", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_LA, 76, &periph_u_regs, TEGRA_PERIPH_ON_APB, la),
+       TEGRA_INIT_DATA_MUX("trace", NULL, "trace", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_TRACE, 77, &periph_u_regs, TEGRA_PERIPH_ON_APB, trace),
+       TEGRA_INIT_DATA_MUX("owr", NULL, "tegra_w1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_OWR, 71, &periph_u_regs, TEGRA_PERIPH_ON_APB, owr),
+       TEGRA_INIT_DATA_MUX("nor", NULL, "tegra-nor", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_NOR, 42, &periph_h_regs, 0, nor),
+       TEGRA_INIT_DATA_MUX("mipi", NULL, "mipi", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_MIPI, 50, &periph_h_regs, TEGRA_PERIPH_ON_APB, mipi),
+       TEGRA_INIT_DATA_I2C("i2c1", "div-clk", "tegra11-i2c.0", mux_pllp_clkm, CLK_SOURCE_I2C1, 12, &periph_l_regs, i2c1),
+       TEGRA_INIT_DATA_I2C("i2c2", "div-clk", "tegra11-i2c.1", mux_pllp_clkm, CLK_SOURCE_I2C2, 54, &periph_h_regs, i2c2),
+       TEGRA_INIT_DATA_I2C("i2c3", "div-clk", "tegra11-i2c.2", mux_pllp_clkm, CLK_SOURCE_I2C3, 67, &periph_u_regs, i2c3),
+       TEGRA_INIT_DATA_I2C("i2c4", "div-clk", "tegra11-i2c.3", mux_pllp_clkm, CLK_SOURCE_I2C4, 103, &periph_v_regs, i2c4),
+       TEGRA_INIT_DATA_I2C("i2c5", "div-clk", "tegra11-i2c.4", mux_pllp_clkm, CLK_SOURCE_I2C5, 47, &periph_h_regs, i2c5),
+       TEGRA_INIT_DATA_UART("uarta", NULL, "tegra_uart.0", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTA, 6, &periph_l_regs, uarta),
+       TEGRA_INIT_DATA_UART("uartb", NULL, "tegra_uart.1", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTB, 7, &periph_l_regs, uartb),
+       TEGRA_INIT_DATA_UART("uartc", NULL, "tegra_uart.2", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTC, 55, &periph_h_regs, uartc),
+       TEGRA_INIT_DATA_UART("uartd", NULL, "tegra_uart.3", mux_pllp_pllc_pllm_clkm, CLK_SOURCE_UARTD, 65, &periph_u_regs, uartd),
+       TEGRA_INIT_DATA_INT("3d", NULL, "3d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_3D, 24, &periph_l_regs, 0, gr_3d),
+       TEGRA_INIT_DATA_INT("2d", NULL, "2d", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_2D, 21, &periph_l_regs, 0, gr_2d),
+       TEGRA_INIT_DATA_MUX("vi_sensor", "vi_sensor", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI_SENSOR, 20, &periph_l_regs, TEGRA_PERIPH_NO_RESET, vi_sensor),
+       TEGRA_INIT_DATA_INT8("vi", "vi", "tegra_camera", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_VI, 20, &periph_l_regs, 0, vi),
+       TEGRA_INIT_DATA_INT8("epp", NULL, "epp", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_EPP, 19, &periph_l_regs, 0, epp),
+       TEGRA_INIT_DATA_INT8("msenc", NULL, "msenc", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_MSENC, 91, &periph_h_regs, TEGRA_PERIPH_WAR_1005168, msenc),
+       TEGRA_INIT_DATA_INT8("tsec", NULL, "tsec", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_TSEC, 83, &periph_u_regs, 0, tsec),
+       TEGRA_INIT_DATA_INT8("host1x", NULL, "host1x", mux_pllm_pllc2_c_c3_pllp_plla, CLK_SOURCE_HOST1X, 28, &periph_l_regs, 0, host1x),
+       TEGRA_INIT_DATA_MUX8("hdmi", NULL, "hdmi", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_HDMI, 51, &periph_h_regs, 0, hdmi),
+       TEGRA_INIT_DATA_MUX("cilab", "cilab", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILAB, 144, &periph_w_regs, 0, cilab),
+       TEGRA_INIT_DATA_MUX("cilcd", "cilcd", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILCD, 145, &periph_w_regs, 0, cilcd),
+       TEGRA_INIT_DATA_MUX("cile", "cile", "tegra_camera", mux_pllp_pllc_clkm, CLK_SOURCE_CILE, 146, &periph_w_regs, 0, cile),
+       TEGRA_INIT_DATA_MUX("dsialp", "dsialp", "tegradc.0", mux_pllp_pllc_clkm, CLK_SOURCE_DSIALP, 147, &periph_w_regs, 0, dsialp),
+       TEGRA_INIT_DATA_MUX("dsiblp", "dsiblp", "tegradc.1", mux_pllp_pllc_clkm, CLK_SOURCE_DSIBLP, 148, &periph_w_regs, 0, dsiblp),
+       TEGRA_INIT_DATA_MUX("tsensor", NULL, "tegra-tsensor", mux_pllp_pllc_clkm_clk32, CLK_SOURCE_TSENSOR, 100, &periph_v_regs, TEGRA_PERIPH_ON_APB, tsensor),
+       TEGRA_INIT_DATA_MUX("actmon", NULL, "actmon", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_ACTMON, 119, &periph_v_regs, 0, actmon),
+       TEGRA_INIT_DATA_MUX8("extern1", NULL, "extern1", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN1, 120, &periph_v_regs, 0, extern1),
+       TEGRA_INIT_DATA_MUX8("extern2", NULL, "extern2", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN2, 121, &periph_v_regs, 0, extern2),
+       TEGRA_INIT_DATA_MUX8("extern3", NULL, "extern3", mux_plla_clk32_pllp_clkm_plle, CLK_SOURCE_EXTERN3, 122, &periph_v_regs, 0, extern3),
+       TEGRA_INIT_DATA_MUX("i2cslow", NULL, "i2cslow", mux_pllp_pllc_clk32_clkm, CLK_SOURCE_I2CSLOW, 81, &periph_u_regs, TEGRA_PERIPH_ON_APB, i2cslow),
+       TEGRA_INIT_DATA_INT8("se", NULL, "se", mux_pllp_pllc2_c_c3_pllm_clkm, CLK_SOURCE_SE, 127, &periph_v_regs, TEGRA_PERIPH_ON_APB, se),
+       TEGRA_INIT_DATA_INT_FLAGS("mselect", NULL, "mselect", mux_pllp_clkm, CLK_SOURCE_MSELECT, 99, &periph_v_regs, 0, mselect, CLK_IGNORE_UNUSED),
+       TEGRA_INIT_DATA_MUX8("soc_therm", NULL, "soc_therm", mux_pllm_pllc_pllp_plla, CLK_SOURCE_SOC_THERM, 78, &periph_u_regs, TEGRA_PERIPH_ON_APB, soc_therm),
+       TEGRA_INIT_DATA_XUSB("xusb_host_src", "host_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_HOST_SRC, 143, &periph_w_regs, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, xusb_host_src),
+       TEGRA_INIT_DATA_XUSB("xusb_falcon_src", "falcon_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_FALCON_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, xusb_falcon_src),
+       TEGRA_INIT_DATA_XUSB("xusb_fs_src", "fs_src", "tegra_xhci", mux_clkm_48M_pllp_480M, CLK_SOURCE_XUSB_FS_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, xusb_fs_src),
+       TEGRA_INIT_DATA_XUSB("xusb_ss_src", "ss_src", "tegra_xhci", mux_clkm_pllre_clk32_480M_pllc_ref, CLK_SOURCE_XUSB_SS_SRC, 143, &periph_w_regs, TEGRA_PERIPH_NO_RESET, xusb_ss_src),
+       TEGRA_INIT_DATA_XUSB("xusb_dev_src", "dev_src", "tegra_xhci", mux_clkm_pllp_pllc_pllre, CLK_SOURCE_XUSB_DEV_SRC, 95, &periph_u_regs, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, xusb_dev_src),
+       TEGRA_INIT_DATA_AUDIO("d_audio", "d_audio", "tegra30-ahub", CLK_SOURCE_D_AUDIO, 106, &periph_v_regs, TEGRA_PERIPH_ON_APB, d_audio),
+       TEGRA_INIT_DATA_AUDIO("dam0", NULL, "tegra30-dam.0", CLK_SOURCE_DAM0, 108, &periph_v_regs, TEGRA_PERIPH_ON_APB, dam0),
+       TEGRA_INIT_DATA_AUDIO("dam1", NULL, "tegra30-dam.1", CLK_SOURCE_DAM1, 109, &periph_v_regs, TEGRA_PERIPH_ON_APB, dam1),
+       TEGRA_INIT_DATA_AUDIO("dam2", NULL, "tegra30-dam.2", CLK_SOURCE_DAM2, 110, &periph_v_regs, TEGRA_PERIPH_ON_APB, dam2),
+};
+
+static struct tegra_periph_init_data tegra_periph_nodiv_clk_list[] = {
+       TEGRA_INIT_DATA_NODIV("disp1", NULL, "tegradc.0", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP1, 29, 7, 27, &periph_l_regs, 0, disp1),
+       TEGRA_INIT_DATA_NODIV("disp2", NULL, "tegradc.1", mux_pllp_pllm_plld_plla_pllc_plld2_clkm, CLK_SOURCE_DISP2, 29, 7, 26, &periph_l_regs, 0, disp2),
+};
+
+static __init void tegra114_periph_clk_init(void __iomem *clk_base)
+{
+       struct tegra_periph_init_data *data;
+       struct clk *clk;
+       int i;
+       u32 val;
+
+       /* apbdma */
+       clk = tegra_clk_register_periph_gate("apbdma", "clk_m", 0, clk_base,
+                                 0, 34, &periph_h_regs,
+                                 periph_clk_enb_refcnt);
+       clks[apbdma] = clk;
+
+       /* rtc */
+       clk = tegra_clk_register_periph_gate("rtc", "clk_32k",
+                                   TEGRA_PERIPH_ON_APB |
+                                   TEGRA_PERIPH_NO_RESET, clk_base,
+                                   0, 4, &periph_l_regs,
+                                   periph_clk_enb_refcnt);
+       clk_register_clkdev(clk, NULL, "rtc-tegra");
+       clks[rtc] = clk;
+
+       /* kbc */
+       clk = tegra_clk_register_periph_gate("kbc", "clk_32k",
+                                   TEGRA_PERIPH_ON_APB |
+                                   TEGRA_PERIPH_NO_RESET, clk_base,
+                                   0, 36, &periph_h_regs,
+                                   periph_clk_enb_refcnt);
+       clks[kbc] = clk;
+
+       /* timer */
+       clk = tegra_clk_register_periph_gate("timer", "clk_m", 0, clk_base,
+                                 0, 5, &periph_l_regs,
+                                 periph_clk_enb_refcnt);
+       clk_register_clkdev(clk, NULL, "timer");
+       clks[timer] = clk;
+
+       /* kfuse */
+       clk = tegra_clk_register_periph_gate("kfuse", "clk_m",
+                                 TEGRA_PERIPH_ON_APB, clk_base,  0, 40,
+                                 &periph_h_regs, periph_clk_enb_refcnt);
+       clks[kfuse] = clk;
+
+       /* fuse */
+       clk = tegra_clk_register_periph_gate("fuse", "clk_m",
+                                 TEGRA_PERIPH_ON_APB, clk_base,  0, 39,
+                                 &periph_h_regs, periph_clk_enb_refcnt);
+       clks[fuse] = clk;
+
+       /* fuse_burn */
+       clk = tegra_clk_register_periph_gate("fuse_burn", "clk_m",
+                                 TEGRA_PERIPH_ON_APB, clk_base,  0, 39,
+                                 &periph_h_regs, periph_clk_enb_refcnt);
+       clks[fuse_burn] = clk;
+
+       /* apbif */
+       clk = tegra_clk_register_periph_gate("apbif", "clk_m",
+                                 TEGRA_PERIPH_ON_APB, clk_base,  0, 107,
+                                 &periph_v_regs, periph_clk_enb_refcnt);
+       clks[apbif] = clk;
+
+       /* hda2hdmi */
+       clk = tegra_clk_register_periph_gate("hda2hdmi", "clk_m",
+                                   TEGRA_PERIPH_ON_APB, clk_base,  0, 128,
+                                   &periph_w_regs, periph_clk_enb_refcnt);
+       clks[hda2hdmi] = clk;
+
+       /* vcp */
+       clk = tegra_clk_register_periph_gate("vcp", "clk_m", 0, clk_base,  0,
+                                 29, &periph_l_regs,
+                                 periph_clk_enb_refcnt);
+       clks[vcp] = clk;
+
+       /* bsea */
+       clk = tegra_clk_register_periph_gate("bsea", "clk_m", 0, clk_base,
+                                 0, 62, &periph_h_regs,
+                                 periph_clk_enb_refcnt);
+       clks[bsea] = clk;
+
+       /* bsev */
+       clk = tegra_clk_register_periph_gate("bsev", "clk_m", 0, clk_base,
+                                 0, 63, &periph_h_regs,
+                                 periph_clk_enb_refcnt);
+       clks[bsev] = clk;
+
+       /* mipi-cal */
+       clk = tegra_clk_register_periph_gate("mipi-cal", "clk_m", 0, clk_base,
+                                  0, 56, &periph_h_regs,
+                                 periph_clk_enb_refcnt);
+       clks[mipi_cal] = clk;
+
+       /* usbd */
+       clk = tegra_clk_register_periph_gate("usbd", "clk_m", 0, clk_base,
+                                 0, 22, &periph_l_regs,
+                                 periph_clk_enb_refcnt);
+       clks[usbd] = clk;
+
+       /* usb2 */
+       clk = tegra_clk_register_periph_gate("usb2", "clk_m", 0, clk_base,
+                                 0, 58, &periph_h_regs,
+                                 periph_clk_enb_refcnt);
+       clks[usb2] = clk;
+
+       /* usb3 */
+       clk = tegra_clk_register_periph_gate("usb3", "clk_m", 0, clk_base,
+                                 0, 59, &periph_h_regs,
+                                 periph_clk_enb_refcnt);
+       clks[usb3] = clk;
+
+       /* csi */
+       clk = tegra_clk_register_periph_gate("csi", "pll_p_out3", 0, clk_base,
+                                  0, 52, &periph_h_regs,
+                                 periph_clk_enb_refcnt);
+       clks[csi] = clk;
+
+       /* isp */
+       clk = tegra_clk_register_periph_gate("isp", "clk_m", 0, clk_base, 0,
+                                 23, &periph_l_regs,
+                                 periph_clk_enb_refcnt);
+       clks[isp] = clk;
+
+       /* csus */
+       clk = tegra_clk_register_periph_gate("csus", "clk_m",
+                                 TEGRA_PERIPH_NO_RESET, clk_base, 0, 92,
+                                 &periph_u_regs, periph_clk_enb_refcnt);
+       clks[csus] = clk;
+
+       /* dds */
+       clk = tegra_clk_register_periph_gate("dds", "clk_m",
+                                 TEGRA_PERIPH_ON_APB, clk_base, 0, 150,
+                                 &periph_w_regs, periph_clk_enb_refcnt);
+       clks[dds] = clk;
+
+       /* dp2 */
+       clk = tegra_clk_register_periph_gate("dp2", "clk_m",
+                                 TEGRA_PERIPH_ON_APB, clk_base, 0, 152,
+                                 &periph_w_regs, periph_clk_enb_refcnt);
+       clks[dp2] = clk;
+
+       /* dtv */
+       clk = tegra_clk_register_periph_gate("dtv", "clk_m",
+                                   TEGRA_PERIPH_ON_APB, clk_base, 0, 79,
+                                   &periph_u_regs, periph_clk_enb_refcnt);
+       clks[dtv] = clk;
+
+       /* dsia */
+       clk = clk_register_mux(NULL, "dsia_mux", mux_plld_out0_plld2_out0,
+                              ARRAY_SIZE(mux_plld_out0_plld2_out0), 0,
+                              clk_base + PLLD_BASE, 25, 1, 0, &pll_d_lock);
+       clks[dsia_mux] = clk;
+       clk = tegra_clk_register_periph_gate("dsia", "dsia_mux", 0, clk_base,
+                                   0, 48, &periph_h_regs,
+                                   periph_clk_enb_refcnt);
+       clks[dsia] = clk;
+
+       /* dsib */
+       clk = clk_register_mux(NULL, "dsib_mux", mux_plld_out0_plld2_out0,
+                              ARRAY_SIZE(mux_plld_out0_plld2_out0), 0,
+                              clk_base + PLLD2_BASE, 25, 1, 0, &pll_d2_lock);
+       clks[dsib_mux] = clk;
+       clk = tegra_clk_register_periph_gate("dsib", "dsib_mux", 0, clk_base,
+                                   0, 82, &periph_u_regs,
+                                   periph_clk_enb_refcnt);
+       clks[dsib] = clk;
+
+       /* xusb_hs_src */
+       val = readl(clk_base + CLK_SOURCE_XUSB_SS_SRC);
+       val |= BIT(25); /* always select PLLU_60M */
+       writel(val, clk_base + CLK_SOURCE_XUSB_SS_SRC);
+
+       clk = clk_register_fixed_factor(NULL, "xusb_hs_src", "pll_u_60M", 0,
+                                       1, 1);
+       clks[xusb_hs_src] = clk;
+
+       /* xusb_host */
+       clk = tegra_clk_register_periph_gate("xusb_host", "xusb_host_src", 0,
+                                   clk_base, 0, 89, &periph_u_regs,
+                                   periph_clk_enb_refcnt);
+       clks[xusb_host] = clk;
+
+       /* xusb_ss */
+       clk = tegra_clk_register_periph_gate("xusb_ss", "xusb_ss_src", 0,
+                                   clk_base, 0, 156, &periph_w_regs,
+                                   periph_clk_enb_refcnt);
+       clks[xusb_host] = clk;
+
+       /* xusb_dev */
+       clk = tegra_clk_register_periph_gate("xusb_dev", "xusb_dev_src", 0,
+                                   clk_base, 0, 95, &periph_u_regs,
+                                   periph_clk_enb_refcnt);
+       clks[xusb_dev] = clk;
+
+       /* emc */
+       clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
+                              ARRAY_SIZE(mux_pllmcp_clkm), 0,
+                              clk_base + CLK_SOURCE_EMC,
+                              29, 3, 0, NULL);
+       clk = tegra_clk_register_periph_gate("emc", "emc_mux", 0, clk_base,
+                               CLK_IGNORE_UNUSED, 57, &periph_h_regs,
+                               periph_clk_enb_refcnt);
+       clks[emc] = clk;
+
+       for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) {
+               data = &tegra_periph_clk_list[i];
+               clk = tegra_clk_register_periph(data->name, data->parent_names,
+                               data->num_parents, &data->periph,
+                               clk_base, data->offset, data->flags);
+               clks[data->clk_id] = clk;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(tegra_periph_nodiv_clk_list); i++) {
+               data = &tegra_periph_nodiv_clk_list[i];
+               clk = tegra_clk_register_periph_nodiv(data->name,
+                               data->parent_names, data->num_parents,
+                               &data->periph, clk_base, data->offset);
+               clks[data->clk_id] = clk;
+       }
+}
+
+static struct tegra_cpu_car_ops tegra114_cpu_car_ops;
+
+static const struct of_device_id pmc_match[] __initconst = {
+       { .compatible = "nvidia,tegra114-pmc" },
+       {},
+};
+
+static __initdata struct tegra_clk_init_table init_table[] = {
+       {uarta, pll_p, 408000000, 0},
+       {uartb, pll_p, 408000000, 0},
+       {uartc, pll_p, 408000000, 0},
+       {uartd, pll_p, 408000000, 0},
+       {pll_a, clk_max, 564480000, 1},
+       {pll_a_out0, clk_max, 11289600, 1},
+       {extern1, pll_a_out0, 0, 1},
+       {clk_out_1_mux, extern1, 0, 1},
+       {clk_out_1, clk_max, 0, 1},
+       {i2s0, pll_a_out0, 11289600, 0},
+       {i2s1, pll_a_out0, 11289600, 0},
+       {i2s2, pll_a_out0, 11289600, 0},
+       {i2s3, pll_a_out0, 11289600, 0},
+       {i2s4, pll_a_out0, 11289600, 0},
+       {clk_max, clk_max, 0, 0}, /* This MUST be the last entry. */
+};
+
+static void __init tegra114_clock_apply_init_table(void)
+{
+       tegra_init_from_table(init_table, clks, clk_max);
+}
+
+void __init tegra114_clock_init(struct device_node *np)
+{
+       struct device_node *node;
+       int i;
+
+       clk_base = of_iomap(np, 0);
+       if (!clk_base) {
+               pr_err("ioremap tegra114 CAR failed\n");
+               return;
+       }
+
+       node = of_find_matching_node(NULL, pmc_match);
+       if (!node) {
+               pr_err("Failed to find pmc node\n");
+               WARN_ON(1);
+               return;
+       }
+
+       pmc_base = of_iomap(node, 0);
+       if (!pmc_base) {
+               pr_err("Can't map pmc registers\n");
+               WARN_ON(1);
+               return;
+       }
+
+       if (tegra114_osc_clk_init(clk_base) < 0)
+               return;
+
+       tegra114_fixed_clk_init(clk_base);
+       tegra114_pll_init(clk_base, pmc_base);
+       tegra114_periph_clk_init(clk_base);
+       tegra114_audio_clk_init(clk_base);
+       tegra114_pmc_clk_init(pmc_base);
+       tegra114_super_clk_init(clk_base);
+
+       for (i = 0; i < ARRAY_SIZE(clks); i++) {
+               if (IS_ERR(clks[i])) {
+                       pr_err
+                           ("Tegra114 clk %d: register failed with %ld\n",
+                            i, PTR_ERR(clks[i]));
+               }
+               if (!clks[i])
+                       clks[i] = ERR_PTR(-EINVAL);
+       }
+
+       clk_data.clks = clks;
+       clk_data.clk_num = ARRAY_SIZE(clks);
+       of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+
+       tegra_clk_apply_init_table = tegra114_clock_apply_init_table;
+
+       tegra_cpu_car_ops = &tegra114_cpu_car_ops;
+}
index 1e2de730536282da499d60a57397f56b7d871c5e..b0405b67f49c710843e9d16d46930f015f25bf59 100644 (file)
@@ -86,8 +86,8 @@
 #define PLLE_BASE 0xe8
 #define PLLE_MISC 0xec
 
-#define PLL_BASE_LOCK 27
-#define PLLE_MISC_LOCK 11
+#define PLL_BASE_LOCK BIT(27)
+#define PLLE_MISC_LOCK BIT(11)
 
 #define PLL_MISC_LOCK_ENABLE 18
 #define PLLDU_MISC_LOCK_ENABLE 22
@@ -236,7 +236,7 @@ enum tegra20_clk {
        dvc, dsi, mipi = 50, hdmi, csi, tvdac, i2c2, uartc, emc = 57, usb2,
        usb3, mpe, vde, bsea, bsev, speedo, uartd, uarte, i2c3, sbc4, sdmmc3,
        pex, owr, afi, csite, pcie_xclk, avpucq = 75, la, irama = 84, iramb,
-       iramc, iramd, cram2, audio_2x, clk_d, csus = 92, cdev1, cdev2,
+       iramc, iramd, cram2, audio_2x, clk_d, csus = 92, cdev2, cdev1,
        uartb = 96, vfir, spdif_in, spdif_out, vi, vi_sensor, tvo, cve,
        osc, clk_32k, clk_m, sclk, cclk, hclk, pclk, blink, pll_a, pll_a_out0,
        pll_c, pll_c_out1, pll_d, pll_d_out0, pll_e, pll_m, pll_m_out1,
@@ -248,125 +248,125 @@ static struct clk *clks[clk_max];
 static struct clk_onecell_data clk_data;
 
 static struct tegra_clk_pll_freq_table pll_c_freq_table[] = {
-       { 12000000, 600000000, 600, 12, 1, 8 },
-       { 13000000, 600000000, 600, 13, 1, 8 },
-       { 19200000, 600000000, 500, 16, 1, 6 },
-       { 26000000, 600000000, 600, 26, 1, 8 },
+       { 12000000, 600000000, 600, 12, 0, 8 },
+       { 13000000, 600000000, 600, 13, 0, 8 },
+       { 19200000, 600000000, 500, 16, 0, 6 },
+       { 26000000, 600000000, 600, 26, 0, 8 },
        { 0, 0, 0, 0, 0, 0 },
 };
 
 static struct tegra_clk_pll_freq_table pll_m_freq_table[] = {
-       { 12000000, 666000000, 666, 12, 1, 8},
-       { 13000000, 666000000, 666, 13, 1, 8},
-       { 19200000, 666000000, 555, 16, 1, 8},
-       { 26000000, 666000000, 666, 26, 1, 8},
-       { 12000000, 600000000, 600, 12, 1, 8},
-       { 13000000, 600000000, 600, 13, 1, 8},
-       { 19200000, 600000000, 375, 12, 1, 6},
-       { 26000000, 600000000, 600, 26, 1, 8},
+       { 12000000, 666000000, 666, 12, 0, 8},
+       { 13000000, 666000000, 666, 13, 0, 8},
+       { 19200000, 666000000, 555, 16, 0, 8},
+       { 26000000, 666000000, 666, 26, 0, 8},
+       { 12000000, 600000000, 600, 12, 0, 8},
+       { 13000000, 600000000, 600, 13, 0, 8},
+       { 19200000, 600000000, 375, 12, 0, 6},
+       { 26000000, 600000000, 600, 26, 0, 8},
        { 0, 0, 0, 0, 0, 0 },
 };
 
 static struct tegra_clk_pll_freq_table pll_p_freq_table[] = {
-       { 12000000, 216000000, 432, 12, 2, 8},
-       { 13000000, 216000000, 432, 13, 2, 8},
-       { 19200000, 216000000, 90,   4, 2, 1},
-       { 26000000, 216000000, 432, 26, 2, 8},
-       { 12000000, 432000000, 432, 12, 1, 8},
-       { 13000000, 432000000, 432, 13, 1, 8},
-       { 19200000, 432000000, 90,   4, 1, 1},
-       { 26000000, 432000000, 432, 26, 1, 8},
+       { 12000000, 216000000, 432, 12, 1, 8},
+       { 13000000, 216000000, 432, 13, 1, 8},
+       { 19200000, 216000000, 90,   4, 1, 1},
+       { 26000000, 216000000, 432, 26, 1, 8},
+       { 12000000, 432000000, 432, 12, 0, 8},
+       { 13000000, 432000000, 432, 13, 0, 8},
+       { 19200000, 432000000, 90,   4, 0, 1},
+       { 26000000, 432000000, 432, 26, 0, 8},
        { 0, 0, 0, 0, 0, 0 },
 };
 
 static struct tegra_clk_pll_freq_table pll_a_freq_table[] = {
-       { 28800000, 56448000, 49, 25, 1, 1},
-       { 28800000, 73728000, 64, 25, 1, 1},
-       { 28800000, 24000000,  5,  6, 1, 1},
+       { 28800000, 56448000, 49, 25, 0, 1},
+       { 28800000, 73728000, 64, 25, 0, 1},
+       { 28800000, 24000000,  5,  6, 0, 1},
        { 0, 0, 0, 0, 0, 0 },
 };
 
 static struct tegra_clk_pll_freq_table pll_d_freq_table[] = {
-       { 12000000, 216000000, 216, 12, 1, 4},
-       { 13000000, 216000000, 216, 13, 1, 4},
-       { 19200000, 216000000, 135, 12, 1, 3},
-       { 26000000, 216000000, 216, 26, 1, 4},
+       { 12000000, 216000000, 216, 12, 0, 4},
+       { 13000000, 216000000, 216, 13, 0, 4},
+       { 19200000, 216000000, 135, 12, 0, 3},
+       { 26000000, 216000000, 216, 26, 0, 4},
 
-       { 12000000, 594000000, 594, 12, 1, 8},
-       { 13000000, 594000000, 594, 13, 1, 8},
-       { 19200000, 594000000, 495, 16, 1, 8},
-       { 26000000, 594000000, 594, 26, 1, 8},
+       { 12000000, 594000000, 594, 12, 0, 8},
+       { 13000000, 594000000, 594, 13, 0, 8},
+       { 19200000, 594000000, 495, 16, 0, 8},
+       { 26000000, 594000000, 594, 26, 0, 8},
 
-       { 12000000, 1000000000, 1000, 12, 1, 12},
-       { 13000000, 1000000000, 1000, 13, 1, 12},
-       { 19200000, 1000000000, 625,  12, 1, 8},
-       { 26000000, 1000000000, 1000, 26, 1, 12},
+       { 12000000, 1000000000, 1000, 12, 0, 12},
+       { 13000000, 1000000000, 1000, 13, 0, 12},
+       { 19200000, 1000000000, 625,  12, 0, 8},
+       { 26000000, 1000000000, 1000, 26, 0, 12},
 
        { 0, 0, 0, 0, 0, 0 },
 };
 
 static struct tegra_clk_pll_freq_table pll_u_freq_table[] = {
-       { 12000000, 480000000, 960, 12, 2, 0},
-       { 13000000, 480000000, 960, 13, 2, 0},
-       { 19200000, 480000000, 200, 4,  2, 0},
-       { 26000000, 480000000, 960, 26, 2, 0},
+       { 12000000, 480000000, 960, 12, 0, 0},
+       { 13000000, 480000000, 960, 13, 0, 0},
+       { 19200000, 480000000, 200, 4,  0, 0},
+       { 26000000, 480000000, 960, 26, 0, 0},
        { 0, 0, 0, 0, 0, 0 },
 };
 
 static struct tegra_clk_pll_freq_table pll_x_freq_table[] = {
        /* 1 GHz */
-       { 12000000, 1000000000, 1000, 12, 1, 12},
-       { 13000000, 1000000000, 1000, 13, 1, 12},
-       { 19200000, 1000000000, 625,  12, 1, 8},
-       { 26000000, 1000000000, 1000, 26, 1, 12},
+       { 12000000, 1000000000, 1000, 12, 0, 12},
+       { 13000000, 1000000000, 1000, 13, 0, 12},
+       { 19200000, 1000000000, 625,  12, 0, 8},
+       { 26000000, 1000000000, 1000, 26, 0, 12},
 
        /* 912 MHz */
-       { 12000000, 912000000,  912,  12, 1, 12},
-       { 13000000, 912000000,  912,  13, 1, 12},
-       { 19200000, 912000000,  760,  16, 1, 8},
-       { 26000000, 912000000,  912,  26, 1, 12},
+       { 12000000, 912000000,  912,  12, 0, 12},
+       { 13000000, 912000000,  912,  13, 0, 12},
+       { 19200000, 912000000,  760,  16, 0, 8},
+       { 26000000, 912000000,  912,  26, 0, 12},
 
        /* 816 MHz */
-       { 12000000, 816000000,  816,  12, 1, 12},
-       { 13000000, 816000000,  816,  13, 1, 12},
-       { 19200000, 816000000,  680,  16, 1, 8},
-       { 26000000, 816000000,  816,  26, 1, 12},
+       { 12000000, 816000000,  816,  12, 0, 12},
+       { 13000000, 816000000,  816,  13, 0, 12},
+       { 19200000, 816000000,  680,  16, 0, 8},
+       { 26000000, 816000000,  816,  26, 0, 12},
 
        /* 760 MHz */
-       { 12000000, 760000000,  760,  12, 1, 12},
-       { 13000000, 760000000,  760,  13, 1, 12},
-       { 19200000, 760000000,  950,  24, 1, 8},
-       { 26000000, 760000000,  760,  26, 1, 12},
+       { 12000000, 760000000,  760,  12, 0, 12},
+       { 13000000, 760000000,  760,  13, 0, 12},
+       { 19200000, 760000000,  950,  24, 0, 8},
+       { 26000000, 760000000,  760,  26, 0, 12},
 
        /* 750 MHz */
-       { 12000000, 750000000,  750,  12, 1, 12},
-       { 13000000, 750000000,  750,  13, 1, 12},
-       { 19200000, 750000000,  625,  16, 1, 8},
-       { 26000000, 750000000,  750,  26, 1, 12},
+       { 12000000, 750000000,  750,  12, 0, 12},
+       { 13000000, 750000000,  750,  13, 0, 12},
+       { 19200000, 750000000,  625,  16, 0, 8},
+       { 26000000, 750000000,  750,  26, 0, 12},
 
        /* 608 MHz */
-       { 12000000, 608000000,  608,  12, 1, 12},
-       { 13000000, 608000000,  608,  13, 1, 12},
-       { 19200000, 608000000,  380,  12, 1, 8},
-       { 26000000, 608000000,  608,  26, 1, 12},
+       { 12000000, 608000000,  608,  12, 0, 12},
+       { 13000000, 608000000,  608,  13, 0, 12},
+       { 19200000, 608000000,  380,  12, 0, 8},
+       { 26000000, 608000000,  608,  26, 0, 12},
 
        /* 456 MHz */
-       { 12000000, 456000000,  456,  12, 1, 12},
-       { 13000000, 456000000,  456,  13, 1, 12},
-       { 19200000, 456000000,  380,  16, 1, 8},
-       { 26000000, 456000000,  456,  26, 1, 12},
+       { 12000000, 456000000,  456,  12, 0, 12},
+       { 13000000, 456000000,  456,  13, 0, 12},
+       { 19200000, 456000000,  380,  16, 0, 8},
+       { 26000000, 456000000,  456,  26, 0, 12},
 
        /* 312 MHz */
-       { 12000000, 312000000,  312,  12, 1, 12},
-       { 13000000, 312000000,  312,  13, 1, 12},
-       { 19200000, 312000000,  260,  16, 1, 8},
-       { 26000000, 312000000,  312,  26, 1, 12},
+       { 12000000, 312000000,  312,  12, 0, 12},
+       { 13000000, 312000000,  312,  13, 0, 12},
+       { 19200000, 312000000,  260,  16, 0, 8},
+       { 26000000, 312000000,  312,  26, 0, 12},
 
        { 0, 0, 0, 0, 0, 0 },
 };
 
 static struct tegra_clk_pll_freq_table pll_e_freq_table[] = {
-       { 12000000, 100000000,  200,  24, 1, 0 },
+       { 12000000, 100000000,  200,  24, 0, 0 },
        { 0, 0, 0, 0, 0, 0 },
 };
 
@@ -380,7 +380,7 @@ static struct tegra_clk_pll_params pll_c_params = {
        .vco_max = 1400000000,
        .base_reg = PLLC_BASE,
        .misc_reg = PLLC_MISC,
-       .lock_bit_idx = PLL_BASE_LOCK,
+       .lock_mask = PLL_BASE_LOCK,
        .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
        .lock_delay = 300,
 };
@@ -394,7 +394,7 @@ static struct tegra_clk_pll_params pll_m_params = {
        .vco_max = 1200000000,
        .base_reg = PLLM_BASE,
        .misc_reg = PLLM_MISC,
-       .lock_bit_idx = PLL_BASE_LOCK,
+       .lock_mask = PLL_BASE_LOCK,
        .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
        .lock_delay = 300,
 };
@@ -408,7 +408,7 @@ static struct tegra_clk_pll_params pll_p_params = {
        .vco_max = 1400000000,
        .base_reg = PLLP_BASE,
        .misc_reg = PLLP_MISC,
-       .lock_bit_idx = PLL_BASE_LOCK,
+       .lock_mask = PLL_BASE_LOCK,
        .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
        .lock_delay = 300,
 };
@@ -422,7 +422,7 @@ static struct tegra_clk_pll_params pll_a_params = {
        .vco_max = 1400000000,
        .base_reg = PLLA_BASE,
        .misc_reg = PLLA_MISC,
-       .lock_bit_idx = PLL_BASE_LOCK,
+       .lock_mask = PLL_BASE_LOCK,
        .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
        .lock_delay = 300,
 };
@@ -436,11 +436,17 @@ static struct tegra_clk_pll_params pll_d_params = {
        .vco_max = 1000000000,
        .base_reg = PLLD_BASE,
        .misc_reg = PLLD_MISC,
-       .lock_bit_idx = PLL_BASE_LOCK,
+       .lock_mask = PLL_BASE_LOCK,
        .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
        .lock_delay = 1000,
 };
 
+static struct pdiv_map pllu_p[] = {
+       { .pdiv = 1, .hw_val = 1 },
+       { .pdiv = 2, .hw_val = 0 },
+       { .pdiv = 0, .hw_val = 0 },
+};
+
 static struct tegra_clk_pll_params pll_u_params = {
        .input_min = 2000000,
        .input_max = 40000000,
@@ -450,9 +456,10 @@ static struct tegra_clk_pll_params pll_u_params = {
        .vco_max = 960000000,
        .base_reg = PLLU_BASE,
        .misc_reg = PLLU_MISC,
-       .lock_bit_idx = PLL_BASE_LOCK,
+       .lock_mask = PLL_BASE_LOCK,
        .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
        .lock_delay = 1000,
+       .pdiv_tohw = pllu_p,
 };
 
 static struct tegra_clk_pll_params pll_x_params = {
@@ -464,7 +471,7 @@ static struct tegra_clk_pll_params pll_x_params = {
        .vco_max = 1200000000,
        .base_reg = PLLX_BASE,
        .misc_reg = PLLX_MISC,
-       .lock_bit_idx = PLL_BASE_LOCK,
+       .lock_mask = PLL_BASE_LOCK,
        .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
        .lock_delay = 300,
 };
@@ -478,7 +485,7 @@ static struct tegra_clk_pll_params pll_e_params = {
        .vco_max = 0,
        .base_reg = PLLE_BASE,
        .misc_reg = PLLE_MISC,
-       .lock_bit_idx = PLLE_MISC_LOCK,
+       .lock_mask = PLLE_MISC_LOCK,
        .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE,
        .lock_delay = 0,
 };
@@ -711,8 +718,8 @@ static void tegra20_pll_init(void)
 }
 
 static const char *cclk_parents[] = { "clk_m", "pll_c", "clk_32k", "pll_m",
-                                     "pll_p_cclk", "pll_p_out4_cclk",
-                                     "pll_p_out3_cclk", "clk_d", "pll_x" };
+                                     "pll_p", "pll_p_out4",
+                                     "pll_p_out3", "clk_d", "pll_x" };
 static const char *sclk_parents[] = { "clk_m", "pll_c_out1", "pll_p_out4",
                                      "pll_p_out3", "pll_p_out2", "clk_d",
                                      "clk_32k", "pll_m_out1" };
@@ -721,38 +728,6 @@ static void tegra20_super_clk_init(void)
 {
        struct clk *clk;
 
-       /*
-        * DIV_U71 dividers for CCLK, these dividers are used only
-        * if parent clock is fixed rate.
-        */
-
-       /*
-        * Clock input to cclk divided from pll_p using
-        * U71 divider of cclk.
-        */
-       clk = tegra_clk_register_divider("pll_p_cclk", "pll_p",
-                               clk_base + SUPER_CCLK_DIVIDER, 0,
-                               TEGRA_DIVIDER_INT, 16, 8, 1, NULL);
-       clk_register_clkdev(clk, "pll_p_cclk", NULL);
-
-       /*
-        * Clock input to cclk divided from pll_p_out3 using
-        * U71 divider of cclk.
-        */
-       clk = tegra_clk_register_divider("pll_p_out3_cclk", "pll_p_out3",
-                               clk_base + SUPER_CCLK_DIVIDER, 0,
-                               TEGRA_DIVIDER_INT, 16, 8, 1, NULL);
-       clk_register_clkdev(clk, "pll_p_out3_cclk", NULL);
-
-       /*
-        * Clock input to cclk divided from pll_p_out4 using
-        * U71 divider of cclk.
-        */
-       clk = tegra_clk_register_divider("pll_p_out4_cclk", "pll_p_out4",
-                               clk_base + SUPER_CCLK_DIVIDER, 0,
-                               TEGRA_DIVIDER_INT, 16, 8, 1, NULL);
-       clk_register_clkdev(clk, "pll_p_out4_cclk", NULL);
-
        /* CCLK */
        clk = tegra_clk_register_super_mux("cclk", cclk_parents,
                              ARRAY_SIZE(cclk_parents), CLK_SET_RATE_PARENT,
@@ -1044,7 +1019,7 @@ static void __init tegra20_periph_clk_init(void)
                data = &tegra_periph_clk_list[i];
                clk = tegra_clk_register_periph(data->name, data->parent_names,
                                data->num_parents, &data->periph,
-                               clk_base, data->offset);
+                               clk_base, data->offset, data->flags);
                clk_register_clkdev(clk, data->con_id, data->dev_id);
                clks[data->clk_id] = clk;
        }
@@ -1279,9 +1254,16 @@ static __initdata struct tegra_clk_init_table init_table[] = {
        {host1x, pll_c, 150000000, 0},
        {disp1, pll_p, 600000000, 0},
        {disp2, pll_p, 600000000, 0},
+       {gr2d, pll_c, 300000000, 0},
+       {gr3d, pll_c, 300000000, 0},
        {clk_max, clk_max, 0, 0}, /* This MUST be the last entry */
 };
 
+static void __init tegra20_clock_apply_init_table(void)
+{
+       tegra_init_from_table(init_table, clks, clk_max);
+}
+
 /*
  * Some clocks may be used by different drivers depending on the board
  * configuration.  List those here to register them twice in the clock lookup
@@ -1348,7 +1330,7 @@ void __init tegra20_clock_init(struct device_node *np)
        clk_data.clk_num = ARRAY_SIZE(clks);
        of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
 
-       tegra_init_from_table(init_table, clks, clk_max);
+       tegra_clk_apply_init_table = tegra20_clock_apply_init_table;
 
        tegra_cpu_car_ops = &tegra20_cpu_car_ops;
 }
index ba6f51bc9f3b8bc229bf0900ff380002fbb51e14..2dc0c5602613eae83cb40704cc0516dd5d64a42b 100644 (file)
 #define PLLDU_MISC_LOCK_ENABLE 22
 #define PLLE_MISC_LOCK_ENABLE 9
 
-#define PLL_BASE_LOCK 27
-#define PLLE_MISC_LOCK 11
+#define PLL_BASE_LOCK BIT(27)
+#define PLLE_MISC_LOCK BIT(11)
 
 #define PLLE_AUX 0x48c
 #define PLLC_OUT 0x84
@@ -330,7 +330,7 @@ enum tegra30_clk {
        usb3, mpe, vde, bsea, bsev, speedo, uartd, uarte, i2c3, sbc4, sdmmc3,
        pcie, owr, afi, csite, pciex, avpucq, la, dtv = 79, ndspeed, i2cslow,
        dsib, irama = 84, iramb, iramc, iramd, cram2, audio_2x = 90, csus = 92,
-       cdev1, cdev2, cpu_g = 96, cpu_lp, gr3d2, mselect, tsensor, i2s3, i2s4,
+       cdev2, cdev1, cpu_g = 96, cpu_lp, gr3d2, mselect, tsensor, i2s3, i2s4,
        i2c4, sbc5, sbc6, d_audio, apbif, dam0, dam1, dam2, hda2codec_2x,
        atomics, audio0_2x, audio1_2x, audio2_2x, audio3_2x, audio4_2x,
        spdif_2x, actmon, extern1, extern2, extern3, sata_oob, sata, hda,
@@ -374,164 +374,170 @@ static const struct utmi_clk_param utmi_parameters[] = {
 };
 
 static struct tegra_clk_pll_freq_table pll_c_freq_table[] = {
-       { 12000000, 1040000000, 520,  6, 1, 8},
-       { 13000000, 1040000000, 480,  6, 1, 8},
-       { 16800000, 1040000000, 495,  8, 1, 8}, /* actual: 1039.5 MHz */
-       { 19200000, 1040000000, 325,  6, 1, 6},
-       { 26000000, 1040000000, 520, 13, 1, 8},
-
-       { 12000000, 832000000, 416,  6, 1, 8},
-       { 13000000, 832000000, 832, 13, 1, 8},
-       { 16800000, 832000000, 396,  8, 1, 8},  /* actual: 831.6 MHz */
-       { 19200000, 832000000, 260,  6, 1, 8},
-       { 26000000, 832000000, 416, 13, 1, 8},
-
-       { 12000000, 624000000, 624, 12, 1, 8},
-       { 13000000, 624000000, 624, 13, 1, 8},
-       { 16800000, 600000000, 520, 14, 1, 8},
-       { 19200000, 624000000, 520, 16, 1, 8},
-       { 26000000, 624000000, 624, 26, 1, 8},
-
-       { 12000000, 600000000, 600, 12, 1, 8},
-       { 13000000, 600000000, 600, 13, 1, 8},
-       { 16800000, 600000000, 500, 14, 1, 8},
-       { 19200000, 600000000, 375, 12, 1, 6},
-       { 26000000, 600000000, 600, 26, 1, 8},
-
-       { 12000000, 520000000, 520, 12, 1, 8},
-       { 13000000, 520000000, 520, 13, 1, 8},
-       { 16800000, 520000000, 495, 16, 1, 8},  /* actual: 519.75 MHz */
-       { 19200000, 520000000, 325, 12, 1, 6},
-       { 26000000, 520000000, 520, 26, 1, 8},
-
-       { 12000000, 416000000, 416, 12, 1, 8},
-       { 13000000, 416000000, 416, 13, 1, 8},
-       { 16800000, 416000000, 396, 16, 1, 8},  /* actual: 415.8 MHz */
-       { 19200000, 416000000, 260, 12, 1, 6},
-       { 26000000, 416000000, 416, 26, 1, 8},
+       { 12000000, 1040000000, 520,  6, 0, 8},
+       { 13000000, 1040000000, 480,  6, 0, 8},
+       { 16800000, 1040000000, 495,  8, 0, 8}, /* actual: 1039.5 MHz */
+       { 19200000, 1040000000, 325,  6, 0, 6},
+       { 26000000, 1040000000, 520, 13, 0, 8},
+
+       { 12000000, 832000000, 416,  6, 0, 8},
+       { 13000000, 832000000, 832, 13, 0, 8},
+       { 16800000, 832000000, 396,  8, 0, 8},  /* actual: 831.6 MHz */
+       { 19200000, 832000000, 260,  6, 0, 8},
+       { 26000000, 832000000, 416, 13, 0, 8},
+
+       { 12000000, 624000000, 624, 12, 0, 8},
+       { 13000000, 624000000, 624, 13, 0, 8},
+       { 16800000, 600000000, 520, 14, 0, 8},
+       { 19200000, 624000000, 520, 16, 0, 8},
+       { 26000000, 624000000, 624, 26, 0, 8},
+
+       { 12000000, 600000000, 600, 12, 0, 8},
+       { 13000000, 600000000, 600, 13, 0, 8},
+       { 16800000, 600000000, 500, 14, 0, 8},
+       { 19200000, 600000000, 375, 12, 0, 6},
+       { 26000000, 600000000, 600, 26, 0, 8},
+
+       { 12000000, 520000000, 520, 12, 0, 8},
+       { 13000000, 520000000, 520, 13, 0, 8},
+       { 16800000, 520000000, 495, 16, 0, 8},  /* actual: 519.75 MHz */
+       { 19200000, 520000000, 325, 12, 0, 6},
+       { 26000000, 520000000, 520, 26, 0, 8},
+
+       { 12000000, 416000000, 416, 12, 0, 8},
+       { 13000000, 416000000, 416, 13, 0, 8},
+       { 16800000, 416000000, 396, 16, 0, 8},  /* actual: 415.8 MHz */
+       { 19200000, 416000000, 260, 12, 0, 6},
+       { 26000000, 416000000, 416, 26, 0, 8},
        { 0, 0, 0, 0, 0, 0 },
 };
 
 static struct tegra_clk_pll_freq_table pll_m_freq_table[] = {
-       { 12000000, 666000000, 666, 12, 1, 8},
-       { 13000000, 666000000, 666, 13, 1, 8},
-       { 16800000, 666000000, 555, 14, 1, 8},
-       { 19200000, 666000000, 555, 16, 1, 8},
-       { 26000000, 666000000, 666, 26, 1, 8},
-       { 12000000, 600000000, 600, 12, 1, 8},
-       { 13000000, 600000000, 600, 13, 1, 8},
-       { 16800000, 600000000, 500, 14, 1, 8},
-       { 19200000, 600000000, 375, 12, 1, 6},
-       { 26000000, 600000000, 600, 26, 1, 8},
+       { 12000000, 666000000, 666, 12, 0, 8},
+       { 13000000, 666000000, 666, 13, 0, 8},
+       { 16800000, 666000000, 555, 14, 0, 8},
+       { 19200000, 666000000, 555, 16, 0, 8},
+       { 26000000, 666000000, 666, 26, 0, 8},
+       { 12000000, 600000000, 600, 12, 0, 8},
+       { 13000000, 600000000, 600, 13, 0, 8},
+       { 16800000, 600000000, 500, 14, 0, 8},
+       { 19200000, 600000000, 375, 12, 0, 6},
+       { 26000000, 600000000, 600, 26, 0, 8},
        { 0, 0, 0, 0, 0, 0 },
 };
 
 static struct tegra_clk_pll_freq_table pll_p_freq_table[] = {
-       { 12000000, 216000000, 432, 12, 2, 8},
-       { 13000000, 216000000, 432, 13, 2, 8},
-       { 16800000, 216000000, 360, 14, 2, 8},
-       { 19200000, 216000000, 360, 16, 2, 8},
-       { 26000000, 216000000, 432, 26, 2, 8},
+       { 12000000, 216000000, 432, 12, 1, 8},
+       { 13000000, 216000000, 432, 13, 1, 8},
+       { 16800000, 216000000, 360, 14, 1, 8},
+       { 19200000, 216000000, 360, 16, 1, 8},
+       { 26000000, 216000000, 432, 26, 1, 8},
        { 0, 0, 0, 0, 0, 0 },
 };
 
 static struct tegra_clk_pll_freq_table pll_a_freq_table[] = {
-       { 9600000, 564480000, 294, 5, 1, 4},
-       { 9600000, 552960000, 288, 5, 1, 4},
-       { 9600000, 24000000,  5,   2, 1, 1},
+       { 9600000, 564480000, 294, 5, 0, 4},
+       { 9600000, 552960000, 288, 5, 0, 4},
+       { 9600000, 24000000,  5,   2, 0, 1},
 
-       { 28800000, 56448000, 49, 25, 1, 1},
-       { 28800000, 73728000, 64, 25, 1, 1},
-       { 28800000, 24000000,  5,  6, 1, 1},
+       { 28800000, 56448000, 49, 25, 0, 1},
+       { 28800000, 73728000, 64, 25, 0, 1},
+       { 28800000, 24000000,  5,  6, 0, 1},
        { 0, 0, 0, 0, 0, 0 },
 };
 
 static struct tegra_clk_pll_freq_table pll_d_freq_table[] = {
-       { 12000000, 216000000, 216, 12, 1, 4},
-       { 13000000, 216000000, 216, 13, 1, 4},
-       { 16800000, 216000000, 180, 14, 1, 4},
-       { 19200000, 216000000, 180, 16, 1, 4},
-       { 26000000, 216000000, 216, 26, 1, 4},
-
-       { 12000000, 594000000, 594, 12, 1, 8},
-       { 13000000, 594000000, 594, 13, 1, 8},
-       { 16800000, 594000000, 495, 14, 1, 8},
-       { 19200000, 594000000, 495, 16, 1, 8},
-       { 26000000, 594000000, 594, 26, 1, 8},
-
-       { 12000000, 1000000000, 1000, 12, 1, 12},
-       { 13000000, 1000000000, 1000, 13, 1, 12},
-       { 19200000, 1000000000, 625,  12, 1, 8},
-       { 26000000, 1000000000, 1000, 26, 1, 12},
+       { 12000000, 216000000, 216, 12, 0, 4},
+       { 13000000, 216000000, 216, 13, 0, 4},
+       { 16800000, 216000000, 180, 14, 0, 4},
+       { 19200000, 216000000, 180, 16, 0, 4},
+       { 26000000, 216000000, 216, 26, 0, 4},
+
+       { 12000000, 594000000, 594, 12, 0, 8},
+       { 13000000, 594000000, 594, 13, 0, 8},
+       { 16800000, 594000000, 495, 14, 0, 8},
+       { 19200000, 594000000, 495, 16, 0, 8},
+       { 26000000, 594000000, 594, 26, 0, 8},
+
+       { 12000000, 1000000000, 1000, 12, 0, 12},
+       { 13000000, 1000000000, 1000, 13, 0, 12},
+       { 19200000, 1000000000, 625,  12, 0, 8},
+       { 26000000, 1000000000, 1000, 26, 0, 12},
 
        { 0, 0, 0, 0, 0, 0 },
 };
 
+static struct pdiv_map pllu_p[] = {
+       { .pdiv = 1, .hw_val = 1 },
+       { .pdiv = 2, .hw_val = 0 },
+       { .pdiv = 0, .hw_val = 0 },
+};
+
 static struct tegra_clk_pll_freq_table pll_u_freq_table[] = {
-       { 12000000, 480000000, 960, 12, 2, 12},
-       { 13000000, 480000000, 960, 13, 2, 12},
-       { 16800000, 480000000, 400, 7,  2, 5},
-       { 19200000, 480000000, 200, 4,  2, 3},
-       { 26000000, 480000000, 960, 26, 2, 12},
+       { 12000000, 480000000, 960, 12, 0, 12},
+       { 13000000, 480000000, 960, 13, 0, 12},
+       { 16800000, 480000000, 400, 7,  0, 5},
+       { 19200000, 480000000, 200, 4,  0, 3},
+       { 26000000, 480000000, 960, 26, 0, 12},
        { 0, 0, 0, 0, 0, 0 },
 };
 
 static struct tegra_clk_pll_freq_table pll_x_freq_table[] = {
        /* 1.7 GHz */
-       { 12000000, 1700000000, 850,  6,  1, 8},
-       { 13000000, 1700000000, 915,  7,  1, 8},        /* actual: 1699.2 MHz */
-       { 16800000, 1700000000, 708,  7,  1, 8},        /* actual: 1699.2 MHz */
-       { 19200000, 1700000000, 885,  10, 1, 8},        /* actual: 1699.2 MHz */
-       { 26000000, 1700000000, 850,  13, 1, 8},
+       { 12000000, 1700000000, 850,  6,  0, 8},
+       { 13000000, 1700000000, 915,  7,  0, 8},        /* actual: 1699.2 MHz */
+       { 16800000, 1700000000, 708,  7,  0, 8},        /* actual: 1699.2 MHz */
+       { 19200000, 1700000000, 885,  10, 0, 8},        /* actual: 1699.2 MHz */
+       { 26000000, 1700000000, 850,  13, 0, 8},
 
        /* 1.6 GHz */
-       { 12000000, 1600000000, 800,  6,  1, 8},
-       { 13000000, 1600000000, 738,  6,  1, 8},        /* actual: 1599.0 MHz */
-       { 16800000, 1600000000, 857,  9,  1, 8},        /* actual: 1599.7 MHz */
-       { 19200000, 1600000000, 500,  6,  1, 8},
-       { 26000000, 1600000000, 800,  13, 1, 8},
+       { 12000000, 1600000000, 800,  6,  0, 8},
+       { 13000000, 1600000000, 738,  6,  0, 8},        /* actual: 1599.0 MHz */
+       { 16800000, 1600000000, 857,  9,  0, 8},        /* actual: 1599.7 MHz */
+       { 19200000, 1600000000, 500,  6,  0, 8},
+       { 26000000, 1600000000, 800,  13, 0, 8},
 
        /* 1.5 GHz */
-       { 12000000, 1500000000, 750,  6,  1, 8},
-       { 13000000, 1500000000, 923,  8,  1, 8},        /* actual: 1499.8 MHz */
-       { 16800000, 1500000000, 625,  7,  1, 8},
-       { 19200000, 1500000000, 625,  8,  1, 8},
-       { 26000000, 1500000000, 750,  13, 1, 8},
+       { 12000000, 1500000000, 750,  6,  0, 8},
+       { 13000000, 1500000000, 923,  8,  0, 8},        /* actual: 1499.8 MHz */
+       { 16800000, 1500000000, 625,  7,  0, 8},
+       { 19200000, 1500000000, 625,  8,  0, 8},
+       { 26000000, 1500000000, 750,  13, 0, 8},
 
        /* 1.4 GHz */
-       { 12000000, 1400000000, 700,  6,  1, 8},
-       { 13000000, 1400000000, 969,  9,  1, 8},        /* actual: 1399.7 MHz */
-       { 16800000, 1400000000, 1000, 12, 1, 8},
-       { 19200000, 1400000000, 875,  12, 1, 8},
-       { 26000000, 1400000000, 700,  13, 1, 8},
+       { 12000000, 1400000000, 700,  6,  0, 8},
+       { 13000000, 1400000000, 969,  9,  0, 8},        /* actual: 1399.7 MHz */
+       { 16800000, 1400000000, 1000, 12, 0, 8},
+       { 19200000, 1400000000, 875,  12, 0, 8},
+       { 26000000, 1400000000, 700,  13, 0, 8},
 
        /* 1.3 GHz */
-       { 12000000, 1300000000, 975,  9,  1, 8},
-       { 13000000, 1300000000, 1000, 10, 1, 8},
-       { 16800000, 1300000000, 928,  12, 1, 8},        /* actual: 1299.2 MHz */
-       { 19200000, 1300000000, 812,  12, 1, 8},        /* actual: 1299.2 MHz */
-       { 26000000, 1300000000, 650,  13, 1, 8},
+       { 12000000, 1300000000, 975,  9,  0, 8},
+       { 13000000, 1300000000, 1000, 10, 0, 8},
+       { 16800000, 1300000000, 928,  12, 0, 8},        /* actual: 1299.2 MHz */
+       { 19200000, 1300000000, 812,  12, 0, 8},        /* actual: 1299.2 MHz */
+       { 26000000, 1300000000, 650,  13, 0, 8},
 
        /* 1.2 GHz */
-       { 12000000, 1200000000, 1000, 10, 1, 8},
-       { 13000000, 1200000000, 923,  10, 1, 8},        /* actual: 1199.9 MHz */
-       { 16800000, 1200000000, 1000, 14, 1, 8},
-       { 19200000, 1200000000, 1000, 16, 1, 8},
-       { 26000000, 1200000000, 600,  13, 1, 8},
+       { 12000000, 1200000000, 1000, 10, 0, 8},
+       { 13000000, 1200000000, 923,  10, 0, 8},        /* actual: 1199.9 MHz */
+       { 16800000, 1200000000, 1000, 14, 0, 8},
+       { 19200000, 1200000000, 1000, 16, 0, 8},
+       { 26000000, 1200000000, 600,  13, 0, 8},
 
        /* 1.1 GHz */
-       { 12000000, 1100000000, 825,  9,  1, 8},
-       { 13000000, 1100000000, 846,  10, 1, 8},        /* actual: 1099.8 MHz */
-       { 16800000, 1100000000, 982,  15, 1, 8},        /* actual: 1099.8 MHz */
-       { 19200000, 1100000000, 859,  15, 1, 8},        /* actual: 1099.5 MHz */
-       { 26000000, 1100000000, 550,  13, 1, 8},
+       { 12000000, 1100000000, 825,  9,  0, 8},
+       { 13000000, 1100000000, 846,  10, 0, 8},        /* actual: 1099.8 MHz */
+       { 16800000, 1100000000, 982,  15, 0, 8},        /* actual: 1099.8 MHz */
+       { 19200000, 1100000000, 859,  15, 0, 8},        /* actual: 1099.5 MHz */
+       { 26000000, 1100000000, 550,  13, 0, 8},
 
        /* 1 GHz */
-       { 12000000, 1000000000, 1000, 12, 1, 8},
-       { 13000000, 1000000000, 1000, 13, 1, 8},
-       { 16800000, 1000000000, 833,  14, 1, 8},        /* actual: 999.6 MHz */
-       { 19200000, 1000000000, 625,  12, 1, 8},
-       { 26000000, 1000000000, 1000, 26, 1, 8},
+       { 12000000, 1000000000, 1000, 12, 0, 8},
+       { 13000000, 1000000000, 1000, 13, 0, 8},
+       { 16800000, 1000000000, 833,  14, 0, 8},        /* actual: 999.6 MHz */
+       { 19200000, 1000000000, 625,  12, 0, 8},
+       { 26000000, 1000000000, 1000, 26, 0, 8},
 
        { 0, 0, 0, 0, 0, 0 },
 };
@@ -553,7 +559,7 @@ static struct tegra_clk_pll_params pll_c_params = {
        .vco_max = 1400000000,
        .base_reg = PLLC_BASE,
        .misc_reg = PLLC_MISC,
-       .lock_bit_idx = PLL_BASE_LOCK,
+       .lock_mask = PLL_BASE_LOCK,
        .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
        .lock_delay = 300,
 };
@@ -567,7 +573,7 @@ static struct tegra_clk_pll_params pll_m_params = {
        .vco_max = 1200000000,
        .base_reg = PLLM_BASE,
        .misc_reg = PLLM_MISC,
-       .lock_bit_idx = PLL_BASE_LOCK,
+       .lock_mask = PLL_BASE_LOCK,
        .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
        .lock_delay = 300,
 };
@@ -581,7 +587,7 @@ static struct tegra_clk_pll_params pll_p_params = {
        .vco_max = 1400000000,
        .base_reg = PLLP_BASE,
        .misc_reg = PLLP_MISC,
-       .lock_bit_idx = PLL_BASE_LOCK,
+       .lock_mask = PLL_BASE_LOCK,
        .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
        .lock_delay = 300,
 };
@@ -595,7 +601,7 @@ static struct tegra_clk_pll_params pll_a_params = {
        .vco_max = 1400000000,
        .base_reg = PLLA_BASE,
        .misc_reg = PLLA_MISC,
-       .lock_bit_idx = PLL_BASE_LOCK,
+       .lock_mask = PLL_BASE_LOCK,
        .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
        .lock_delay = 300,
 };
@@ -609,7 +615,7 @@ static struct tegra_clk_pll_params pll_d_params = {
        .vco_max = 1000000000,
        .base_reg = PLLD_BASE,
        .misc_reg = PLLD_MISC,
-       .lock_bit_idx = PLL_BASE_LOCK,
+       .lock_mask = PLL_BASE_LOCK,
        .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
        .lock_delay = 1000,
 };
@@ -623,7 +629,7 @@ static struct tegra_clk_pll_params pll_d2_params = {
        .vco_max = 1000000000,
        .base_reg = PLLD2_BASE,
        .misc_reg = PLLD2_MISC,
-       .lock_bit_idx = PLL_BASE_LOCK,
+       .lock_mask = PLL_BASE_LOCK,
        .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
        .lock_delay = 1000,
 };
@@ -637,9 +643,10 @@ static struct tegra_clk_pll_params pll_u_params = {
        .vco_max = 960000000,
        .base_reg = PLLU_BASE,
        .misc_reg = PLLU_MISC,
-       .lock_bit_idx = PLL_BASE_LOCK,
+       .lock_mask = PLL_BASE_LOCK,
        .lock_enable_bit_idx = PLLDU_MISC_LOCK_ENABLE,
        .lock_delay = 1000,
+       .pdiv_tohw = pllu_p,
 };
 
 static struct tegra_clk_pll_params pll_x_params = {
@@ -651,7 +658,7 @@ static struct tegra_clk_pll_params pll_x_params = {
        .vco_max = 1700000000,
        .base_reg = PLLX_BASE,
        .misc_reg = PLLX_MISC,
-       .lock_bit_idx = PLL_BASE_LOCK,
+       .lock_mask = PLL_BASE_LOCK,
        .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
        .lock_delay = 300,
 };
@@ -665,7 +672,7 @@ static struct tegra_clk_pll_params pll_e_params = {
        .vco_max = 2400000000U,
        .base_reg = PLLE_BASE,
        .misc_reg = PLLE_MISC,
-       .lock_bit_idx = PLLE_MISC_LOCK,
+       .lock_mask = PLLE_MISC_LOCK,
        .lock_enable_bit_idx = PLLE_MISC_LOCK_ENABLE,
        .lock_delay = 300,
 };
@@ -1661,7 +1668,7 @@ static void __init tegra30_periph_clk_init(void)
                data = &tegra_periph_clk_list[i];
                clk = tegra_clk_register_periph(data->name, data->parent_names,
                                data->num_parents, &data->periph,
-                               clk_base, data->offset);
+                               clk_base, data->offset, data->flags);
                clk_register_clkdev(clk, data->con_id, data->dev_id);
                clks[data->clk_id] = clk;
        }
@@ -1911,9 +1918,16 @@ static __initdata struct tegra_clk_init_table init_table[] = {
        {disp1, pll_p, 600000000, 0},
        {disp2, pll_p, 600000000, 0},
        {twd, clk_max, 0, 1},
+       {gr2d, pll_c, 300000000, 0},
+       {gr3d, pll_c, 300000000, 0},
        {clk_max, clk_max, 0, 0}, /* This MUST be the last entry. */
 };
 
+static void __init tegra30_clock_apply_init_table(void)
+{
+       tegra_init_from_table(init_table, clks, clk_max);
+}
+
 /*
  * Some clocks may be used by different drivers depending on the board
  * configuration.  List those here to register them twice in the clock lookup
@@ -1987,7 +2001,7 @@ void __init tegra30_clock_init(struct device_node *np)
        clk_data.clk_num = ARRAY_SIZE(clks);
        of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
 
-       tegra_init_from_table(init_table, clks, clk_max);
+       tegra_clk_apply_init_table = tegra30_clock_apply_init_table;
 
        tegra_cpu_car_ops = &tegra30_cpu_car_ops;
 }
index a603b9af0ad38cda8ca3ee590174909dcaea2994..923ca7ee46944c4d516f01938c2ce046e6fa6d6a 100644 (file)
@@ -22,7 +22,8 @@
 #include "clk.h"
 
 /* Global data of Tegra CPU CAR ops */
-struct tegra_cpu_car_ops *tegra_cpu_car_ops;
+static struct tegra_cpu_car_ops dummy_car_ops;
+struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops;
 
 void __init tegra_init_dup_clks(struct tegra_clk_duplicate *dup_list,
                                struct clk *clks[], int clk_max)
@@ -76,6 +77,7 @@ void __init tegra_init_from_table(struct tegra_clk_init_table *tbl,
 static const struct of_device_id tegra_dt_clk_match[] = {
        { .compatible = "nvidia,tegra20-car", .data = tegra20_clock_init },
        { .compatible = "nvidia,tegra30-car", .data = tegra30_clock_init },
+       { .compatible = "nvidia,tegra114-car", .data = tegra114_clock_init },
        { }
 };
 
@@ -83,3 +85,13 @@ void __init tegra_clocks_init(void)
 {
        of_clk_init(tegra_dt_clk_match);
 }
+
+tegra_clk_apply_init_table_func tegra_clk_apply_init_table;
+
+void __init tegra_clocks_apply_init_table(void)
+{
+       if (!tegra_clk_apply_init_table)
+               return;
+
+       tegra_clk_apply_init_table();
+}
index 0744731c62291c7bcb4ec83ac04b468a179fac37..e0565620d68ea508f53aed0973a388f8aa6005e5 100644 (file)
@@ -1,4 +1,4 @@
-/*
+       /*
  * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -116,6 +116,17 @@ struct tegra_clk_pll_freq_table {
        u8              cpcon;
 };
 
+/**
+ * struct pdiv_map - map post divider to hw value
+ *
+ * @pdiv:              post divider
+ * @hw_val:            value to be written to the PLL hw
+ */
+struct pdiv_map {
+       u8 pdiv;
+       u8 hw_val;
+};
+
 /**
  * struct clk_pll_params - PLL parameters
  *
@@ -143,9 +154,18 @@ struct tegra_clk_pll_params {
        u32             base_reg;
        u32             misc_reg;
        u32             lock_reg;
-       u32             lock_bit_idx;
+       u32             lock_mask;
        u32             lock_enable_bit_idx;
+       u32             iddq_reg;
+       u32             iddq_bit_idx;
+       u32             aux_reg;
+       u32             dyn_ramp_reg;
+       u32             ext_misc_reg[3];
+       int             stepa_shift;
+       int             stepb_shift;
        int             lock_delay;
+       int             max_p;
+       struct pdiv_map *pdiv_tohw;
 };
 
 /**
@@ -182,12 +202,16 @@ struct tegra_clk_pll_params {
  * TEGRA_PLL_FIXED - We are not supposed to change output frequency
  *     of some plls.
  * TEGRA_PLLE_CONFIGURE - Configure PLLE when enabling.
+ * TEGRA_PLL_LOCK_MISC - Lock bit is in the misc register instead of the
+ *     base register.
+ * TEGRA_PLL_BYPASS - PLL has bypass bit
+ * TEGRA_PLL_HAS_LOCK_ENABLE - PLL has bit to enable lock monitoring
  */
 struct tegra_clk_pll {
        struct clk_hw   hw;
        void __iomem    *clk_base;
        void __iomem    *pmc;
-       u             flags;
+       u32             flags;
        unsigned long   fixed_rate;
        spinlock_t      *lock;
        u8              divn_shift;
@@ -210,20 +234,64 @@ struct tegra_clk_pll {
 #define TEGRA_PLLM BIT(5)
 #define TEGRA_PLL_FIXED BIT(6)
 #define TEGRA_PLLE_CONFIGURE BIT(7)
+#define TEGRA_PLL_LOCK_MISC BIT(8)
+#define TEGRA_PLL_BYPASS BIT(9)
+#define TEGRA_PLL_HAS_LOCK_ENABLE BIT(10)
 
 extern const struct clk_ops tegra_clk_pll_ops;
 extern const struct clk_ops tegra_clk_plle_ops;
 struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
                void __iomem *clk_base, void __iomem *pmc,
                unsigned long flags, unsigned long fixed_rate,
-               struct tegra_clk_pll_params *pll_params, u8 pll_flags,
+               struct tegra_clk_pll_params *pll_params, u32 pll_flags,
                struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock);
+
 struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
                void __iomem *clk_base, void __iomem *pmc,
                unsigned long flags, unsigned long fixed_rate,
-               struct tegra_clk_pll_params *pll_params, u8 pll_flags,
+               struct tegra_clk_pll_params *pll_params, u32 pll_flags,
                struct tegra_clk_pll_freq_table *freq_table, spinlock_t *lock);
 
+struct clk *tegra_clk_register_pllxc(const char *name, const char *parent_name,
+                           void __iomem *clk_base, void __iomem *pmc,
+                           unsigned long flags, unsigned long fixed_rate,
+                           struct tegra_clk_pll_params *pll_params,
+                           u32 pll_flags,
+                           struct tegra_clk_pll_freq_table *freq_table,
+                           spinlock_t *lock);
+
+struct clk *tegra_clk_register_pllm(const char *name, const char *parent_name,
+                          void __iomem *clk_base, void __iomem *pmc,
+                          unsigned long flags, unsigned long fixed_rate,
+                          struct tegra_clk_pll_params *pll_params,
+                          u32 pll_flags,
+                          struct tegra_clk_pll_freq_table *freq_table,
+                          spinlock_t *lock);
+
+struct clk *tegra_clk_register_pllc(const char *name, const char *parent_name,
+                          void __iomem *clk_base, void __iomem *pmc,
+                          unsigned long flags, unsigned long fixed_rate,
+                          struct tegra_clk_pll_params *pll_params,
+                          u32 pll_flags,
+                          struct tegra_clk_pll_freq_table *freq_table,
+                          spinlock_t *lock);
+
+struct clk *tegra_clk_register_pllre(const char *name, const char *parent_name,
+                          void __iomem *clk_base, void __iomem *pmc,
+                          unsigned long flags, unsigned long fixed_rate,
+                          struct tegra_clk_pll_params *pll_params,
+                          u32 pll_flags,
+                          struct tegra_clk_pll_freq_table *freq_table,
+                          spinlock_t *lock, unsigned long parent_rate);
+
+struct clk *tegra_clk_register_plle_tegra114(const char *name,
+                               const char *parent_name,
+                               void __iomem *clk_base, unsigned long flags,
+                               unsigned long fixed_rate,
+                               struct tegra_clk_pll_params *pll_params,
+                               struct tegra_clk_pll_freq_table *freq_table,
+                               spinlock_t *lock);
+
 /**
  * struct tegra_clk_pll_out - PLL divider down clock
  *
@@ -290,6 +358,7 @@ struct tegra_clk_periph_regs {
  * TEGRA_PERIPH_ON_APB - If peripheral is in the APB bus then read the
  *     bus to flush the write operation in apb bus. This flag indicates
  *     that this peripheral is in apb bus.
+ * TEGRA_PERIPH_WAR_1005168 - Apply workaround for Tegra114 MSENC bug
  */
 struct tegra_clk_periph_gate {
        u32                     magic;
@@ -309,6 +378,7 @@ struct tegra_clk_periph_gate {
 #define TEGRA_PERIPH_NO_RESET BIT(0)
 #define TEGRA_PERIPH_MANUAL_RESET BIT(1)
 #define TEGRA_PERIPH_ON_APB BIT(2)
+#define TEGRA_PERIPH_WAR_1005168 BIT(3)
 
 void tegra_periph_reset(struct tegra_clk_periph_gate *gate, bool assert);
 extern const struct clk_ops tegra_clk_periph_gate_ops;
@@ -349,21 +419,22 @@ extern const struct clk_ops tegra_clk_periph_ops;
 struct clk *tegra_clk_register_periph(const char *name,
                const char **parent_names, int num_parents,
                struct tegra_clk_periph *periph, void __iomem *clk_base,
-               u32 offset);
+               u32 offset, unsigned long flags);
 struct clk *tegra_clk_register_periph_nodiv(const char *name,
                const char **parent_names, int num_parents,
                struct tegra_clk_periph *periph, void __iomem *clk_base,
                u32 offset);
 
-#define TEGRA_CLK_PERIPH(_mux_shift, _mux_width, _mux_flags,           \
+#define TEGRA_CLK_PERIPH(_mux_shift, _mux_mask, _mux_flags,            \
                         _div_shift, _div_width, _div_frac_width,       \
                         _div_flags, _clk_num, _enb_refcnt, _regs,      \
-                        _gate_flags)                                   \
+                        _gate_flags, _table)                           \
        {                                                               \
                .mux = {                                                \
                        .flags = _mux_flags,                            \
                        .shift = _mux_shift,                            \
-                       .width = _mux_width,                            \
+                       .mask = _mux_mask,                              \
+                       .table = _table,                                \
                },                                                      \
                .divider = {                                            \
                        .flags = _div_flags,                            \
@@ -391,28 +462,41 @@ struct tegra_periph_init_data {
        u32 offset;
        const char *con_id;
        const char *dev_id;
+       unsigned long flags;
 };
 
-#define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset, \
-                       _mux_shift, _mux_width, _mux_flags, _div_shift, \
+#define TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\
+                       _mux_shift, _mux_mask, _mux_flags, _div_shift,  \
                        _div_width, _div_frac_width, _div_flags, _regs, \
-                       _clk_num, _enb_refcnt, _gate_flags, _clk_id)    \
+                       _clk_num, _enb_refcnt, _gate_flags, _clk_id, _table,\
+                       _flags) \
        {                                                               \
                .name = _name,                                          \
                .clk_id = _clk_id,                                      \
                .parent_names = _parent_names,                          \
                .num_parents = ARRAY_SIZE(_parent_names),               \
-               .periph = TEGRA_CLK_PERIPH(_mux_shift, _mux_width,      \
+               .periph = TEGRA_CLK_PERIPH(_mux_shift, _mux_mask,       \
                                           _mux_flags, _div_shift,      \
                                           _div_width, _div_frac_width, \
                                           _div_flags, _clk_num,        \
                                           _enb_refcnt, _regs,          \
-                                          _gate_flags),                \
+                                          _gate_flags, _table),        \
                .offset = _offset,                                      \
                .con_id = _con_id,                                      \
                .dev_id = _dev_id,                                      \
+               .flags = _flags                                         \
        }
 
+#define TEGRA_INIT_DATA(_name, _con_id, _dev_id, _parent_names, _offset,\
+                       _mux_shift, _mux_width, _mux_flags, _div_shift, \
+                       _div_width, _div_frac_width, _div_flags, _regs, \
+                       _clk_num, _enb_refcnt, _gate_flags, _clk_id)    \
+       TEGRA_INIT_DATA_TABLE(_name, _con_id, _dev_id, _parent_names, _offset,\
+                       _mux_shift, BIT(_mux_width) - 1, _mux_flags,    \
+                       _div_shift, _div_width, _div_frac_width, _div_flags, \
+                       _regs, _clk_num, _enb_refcnt, _gate_flags, _clk_id,\
+                       NULL, 0)
+
 /**
  * struct clk_super_mux - super clock
  *
@@ -499,4 +583,13 @@ void tegra30_clock_init(struct device_node *np);
 static inline void tegra30_clock_init(struct device_node *np) {}
 #endif /* CONFIG_ARCH_TEGRA_3x_SOC */
 
+#ifdef CONFIG_ARCH_TEGRA_114_SOC
+void tegra114_clock_init(struct device_node *np);
+#else
+static inline void tegra114_clock_init(struct device_node *np) {}
+#endif /* CONFIG_ARCH_TEGRA114_SOC */
+
+typedef void (*tegra_clk_apply_init_table_func)(void);
+extern tegra_clk_apply_init_table_func tegra_clk_apply_init_table;
+
 #endif /* TEGRA_CLK_H */
index 74faa7e3cf59f41658d3ebc4f05631970129c333..293a28854417374ee6fe3047be1637934eb343a9 100644 (file)
 struct clk_prcmu {
        struct clk_hw hw;
        u8 cg_sel;
+       int is_prepared;
        int is_enabled;
+       int opp_requested;
 };
 
 /* PRCMU clock operations. */
 
 static int clk_prcmu_prepare(struct clk_hw *hw)
 {
+       int ret;
        struct clk_prcmu *clk = to_clk_prcmu(hw);
-       return prcmu_request_clock(clk->cg_sel, true);
+
+       ret = prcmu_request_clock(clk->cg_sel, true);
+       if (!ret)
+               clk->is_prepared = 1;
+
+       return ret;;
 }
 
 static void clk_prcmu_unprepare(struct clk_hw *hw)
@@ -36,7 +44,15 @@ static void clk_prcmu_unprepare(struct clk_hw *hw)
        struct clk_prcmu *clk = to_clk_prcmu(hw);
        if (prcmu_request_clock(clk->cg_sel, false))
                pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
-                       hw->init->name);
+                       __clk_get_name(hw->clk));
+       else
+               clk->is_prepared = 0;
+}
+
+static int clk_prcmu_is_prepared(struct clk_hw *hw)
+{
+       struct clk_prcmu *clk = to_clk_prcmu(hw);
+       return clk->is_prepared;
 }
 
 static int clk_prcmu_enable(struct clk_hw *hw)
@@ -79,58 +95,52 @@ static int clk_prcmu_set_rate(struct clk_hw *hw, unsigned long rate,
        return prcmu_set_clock_rate(clk->cg_sel, rate);
 }
 
-static int request_ape_opp100(bool enable)
-{
-       static int reqs;
-       int err = 0;
-
-       if (enable) {
-               if (!reqs)
-                       err = prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP,
-                                                       "clock", 100);
-               if (!err)
-                       reqs++;
-       } else {
-               reqs--;
-               if (!reqs)
-                       prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP,
-                                               "clock");
-       }
-       return err;
-}
-
 static int clk_prcmu_opp_prepare(struct clk_hw *hw)
 {
        int err;
        struct clk_prcmu *clk = to_clk_prcmu(hw);
 
-       err = request_ape_opp100(true);
-       if (err) {
-               pr_err("clk_prcmu: %s failed to request APE OPP100 for %s.\n",
-                       __func__, hw->init->name);
-               return err;
+       if (!clk->opp_requested) {
+               err = prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP,
+                                               (char *)__clk_get_name(hw->clk),
+                                               100);
+               if (err) {
+                       pr_err("clk_prcmu: %s fail req APE OPP for %s.\n",
+                               __func__, __clk_get_name(hw->clk));
+                       return err;
+               }
+               clk->opp_requested = 1;
        }
 
        err = prcmu_request_clock(clk->cg_sel, true);
-       if (err)
-               request_ape_opp100(false);
+       if (err) {
+               prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP,
+                                       (char *)__clk_get_name(hw->clk));
+               clk->opp_requested = 0;
+               return err;
+       }
 
-       return err;
+       clk->is_prepared = 1;
+       return 0;
 }
 
 static void clk_prcmu_opp_unprepare(struct clk_hw *hw)
 {
        struct clk_prcmu *clk = to_clk_prcmu(hw);
 
-       if (prcmu_request_clock(clk->cg_sel, false))
-               goto out_error;
-       if (request_ape_opp100(false))
-               goto out_error;
-       return;
-
-out_error:
-       pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
-               hw->init->name);
+       if (prcmu_request_clock(clk->cg_sel, false)) {
+               pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
+                       __clk_get_name(hw->clk));
+               return;
+       }
+
+       if (clk->opp_requested) {
+               prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP,
+                                       (char *)__clk_get_name(hw->clk));
+               clk->opp_requested = 0;
+       }
+
+       clk->is_prepared = 0;
 }
 
 static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw)
@@ -138,38 +148,49 @@ static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw)
        int err;
        struct clk_prcmu *clk = to_clk_prcmu(hw);
 
-       err = prcmu_request_ape_opp_100_voltage(true);
-       if (err) {
-               pr_err("clk_prcmu: %s failed to request APE OPP VOLT for %s.\n",
-                       __func__, hw->init->name);
-               return err;
+       if (!clk->opp_requested) {
+               err = prcmu_request_ape_opp_100_voltage(true);
+               if (err) {
+                       pr_err("clk_prcmu: %s fail req APE OPP VOLT for %s.\n",
+                               __func__, __clk_get_name(hw->clk));
+                       return err;
+               }
+               clk->opp_requested = 1;
        }
 
        err = prcmu_request_clock(clk->cg_sel, true);
-       if (err)
+       if (err) {
                prcmu_request_ape_opp_100_voltage(false);
+               clk->opp_requested = 0;
+               return err;
+       }
 
-       return err;
+       clk->is_prepared = 1;
+       return 0;
 }
 
 static void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw)
 {
        struct clk_prcmu *clk = to_clk_prcmu(hw);
 
-       if (prcmu_request_clock(clk->cg_sel, false))
-               goto out_error;
-       if (prcmu_request_ape_opp_100_voltage(false))
-               goto out_error;
-       return;
-
-out_error:
-       pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
-               hw->init->name);
+       if (prcmu_request_clock(clk->cg_sel, false)) {
+               pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
+                       __clk_get_name(hw->clk));
+               return;
+       }
+
+       if (clk->opp_requested) {
+               prcmu_request_ape_opp_100_voltage(false);
+               clk->opp_requested = 0;
+       }
+
+       clk->is_prepared = 0;
 }
 
 static struct clk_ops clk_prcmu_scalable_ops = {
        .prepare = clk_prcmu_prepare,
        .unprepare = clk_prcmu_unprepare,
+       .is_prepared = clk_prcmu_is_prepared,
        .enable = clk_prcmu_enable,
        .disable = clk_prcmu_disable,
        .is_enabled = clk_prcmu_is_enabled,
@@ -181,6 +202,7 @@ static struct clk_ops clk_prcmu_scalable_ops = {
 static struct clk_ops clk_prcmu_gate_ops = {
        .prepare = clk_prcmu_prepare,
        .unprepare = clk_prcmu_unprepare,
+       .is_prepared = clk_prcmu_is_prepared,
        .enable = clk_prcmu_enable,
        .disable = clk_prcmu_disable,
        .is_enabled = clk_prcmu_is_enabled,
@@ -202,6 +224,7 @@ static struct clk_ops clk_prcmu_rate_ops = {
 static struct clk_ops clk_prcmu_opp_gate_ops = {
        .prepare = clk_prcmu_opp_prepare,
        .unprepare = clk_prcmu_opp_unprepare,
+       .is_prepared = clk_prcmu_is_prepared,
        .enable = clk_prcmu_enable,
        .disable = clk_prcmu_disable,
        .is_enabled = clk_prcmu_is_enabled,
@@ -211,6 +234,7 @@ static struct clk_ops clk_prcmu_opp_gate_ops = {
 static struct clk_ops clk_prcmu_opp_volt_scalable_ops = {
        .prepare = clk_prcmu_opp_volt_prepare,
        .unprepare = clk_prcmu_opp_volt_unprepare,
+       .is_prepared = clk_prcmu_is_prepared,
        .enable = clk_prcmu_enable,
        .disable = clk_prcmu_disable,
        .is_enabled = clk_prcmu_is_enabled,
@@ -242,7 +266,9 @@ static struct clk *clk_reg_prcmu(const char *name,
        }
 
        clk->cg_sel = cg_sel;
+       clk->is_prepared = 1;
        clk->is_enabled = 1;
+       clk->opp_requested = 0;
        /* "rate" can be used for changing the initial frequency */
        if (rate)
                prcmu_set_clock_rate(cg_sel, rate);
index e507ab7df60b88d6bae4a3f69e28d8f6845924cd..e8c453285151f68cdfecab80e244f251d02dcf3f 100644 (file)
@@ -67,3 +67,8 @@ config CLKSRC_METAG_GENERIC
        def_bool y if METAG
        help
          This option enables support for the Meta per-thread timers.
+
+config CLKSRC_EXYNOS_MCT
+       def_bool y if ARCH_EXYNOS
+       help
+         Support for Multi Core Timer controller on Exynos SoCs.
index 4d8283aec5b51286ba3942ce4e3223a9281ab3cf..7c88173295aa9a08a3457cd36a02c3cb5d223a0c 100644 (file)
@@ -16,9 +16,11 @@ obj-$(CONFIG_CLKSRC_NOMADIK_MTU)     += nomadik-mtu.o
 obj-$(CONFIG_CLKSRC_DBX500_PRCMU)      += clksrc-dbx500-prcmu.o
 obj-$(CONFIG_ARMADA_370_XP_TIMER)      += time-armada-370-xp.o
 obj-$(CONFIG_ARCH_BCM2835)     += bcm2835_timer.o
+obj-$(CONFIG_ARCH_MXS)         += mxs_timer.o
 obj-$(CONFIG_SUNXI_TIMER)      += sunxi_timer.o
 obj-$(CONFIG_ARCH_TEGRA)       += tegra20_timer.o
 obj-$(CONFIG_VT8500_TIMER)     += vt8500_timer.o
+obj-$(CONFIG_CLKSRC_EXYNOS_MCT)        += exynos_mct.o
 
 obj-$(CONFIG_ARM_ARCH_TIMER)           += arm_arch_timer.o
 obj-$(CONFIG_CLKSRC_METAG_GENERIC)     += metag_generic.o
index 50c68fef944be525601d9ecc9b42d2e9287cfb7c..766611d299455efa3699fe49d5aa9a42812bd226 100644 (file)
@@ -95,23 +95,13 @@ static irqreturn_t bcm2835_time_interrupt(int irq, void *dev_id)
        }
 }
 
-static struct of_device_id bcm2835_time_match[] __initconst = {
-       { .compatible = "brcm,bcm2835-system-timer" },
-       {}
-};
-
-static void __init bcm2835_timer_init(void)
+static void __init bcm2835_timer_init(struct device_node *node)
 {
-       struct device_node *node;
        void __iomem *base;
        u32 freq;
        int irq;
        struct bcm2835_timer *timer;
 
-       node = of_find_matching_node(NULL, bcm2835_time_match);
-       if (!node)
-               panic("No bcm2835 timer node");
-
        base = of_iomap(node, 0);
        if (!base)
                panic("Can't remap registers");
index bdabdaa8d00f25be231804459f0e867f79045978..3ef11fba781c7701c15f47e90fda99b422fd96d5 100644 (file)
@@ -26,10 +26,10 @@ void __init clocksource_of_init(void)
 {
        struct device_node *np;
        const struct of_device_id *match;
-       void (*init_func)(void);
+       void (*init_func)(struct device_node *);
 
        for_each_matching_node_and_match(np, __clksrc_of_table, &match) {
                init_func = match->data;
-               init_func();
+               init_func(np);
        }
 }
diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c
new file mode 100644 (file)
index 0000000..203ac05
--- /dev/null
@@ -0,0 +1,558 @@
+/* linux/arch/arm/mach-exynos4/mct.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com
+ *
+ * EXYNOS4 MCT(Multi-Core Timer) support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/percpu.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_address.h>
+#include <linux/clocksource.h>
+
+#include <asm/arch_timer.h>
+#include <asm/localtimer.h>
+
+#include <plat/cpu.h>
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+#include <asm/mach/time.h>
+
+#define EXYNOS4_MCTREG(x)              (x)
+#define EXYNOS4_MCT_G_CNT_L            EXYNOS4_MCTREG(0x100)
+#define EXYNOS4_MCT_G_CNT_U            EXYNOS4_MCTREG(0x104)
+#define EXYNOS4_MCT_G_CNT_WSTAT                EXYNOS4_MCTREG(0x110)
+#define EXYNOS4_MCT_G_COMP0_L          EXYNOS4_MCTREG(0x200)
+#define EXYNOS4_MCT_G_COMP0_U          EXYNOS4_MCTREG(0x204)
+#define EXYNOS4_MCT_G_COMP0_ADD_INCR   EXYNOS4_MCTREG(0x208)
+#define EXYNOS4_MCT_G_TCON             EXYNOS4_MCTREG(0x240)
+#define EXYNOS4_MCT_G_INT_CSTAT                EXYNOS4_MCTREG(0x244)
+#define EXYNOS4_MCT_G_INT_ENB          EXYNOS4_MCTREG(0x248)
+#define EXYNOS4_MCT_G_WSTAT            EXYNOS4_MCTREG(0x24C)
+#define _EXYNOS4_MCT_L_BASE            EXYNOS4_MCTREG(0x300)
+#define EXYNOS4_MCT_L_BASE(x)          (_EXYNOS4_MCT_L_BASE + (0x100 * x))
+#define EXYNOS4_MCT_L_MASK             (0xffffff00)
+
+#define MCT_L_TCNTB_OFFSET             (0x00)
+#define MCT_L_ICNTB_OFFSET             (0x08)
+#define MCT_L_TCON_OFFSET              (0x20)
+#define MCT_L_INT_CSTAT_OFFSET         (0x30)
+#define MCT_L_INT_ENB_OFFSET           (0x34)
+#define MCT_L_WSTAT_OFFSET             (0x40)
+#define MCT_G_TCON_START               (1 << 8)
+#define MCT_G_TCON_COMP0_AUTO_INC      (1 << 1)
+#define MCT_G_TCON_COMP0_ENABLE                (1 << 0)
+#define MCT_L_TCON_INTERVAL_MODE       (1 << 2)
+#define MCT_L_TCON_INT_START           (1 << 1)
+#define MCT_L_TCON_TIMER_START         (1 << 0)
+
+#define TICK_BASE_CNT  1
+
+enum {
+       MCT_INT_SPI,
+       MCT_INT_PPI
+};
+
+enum {
+       MCT_G0_IRQ,
+       MCT_G1_IRQ,
+       MCT_G2_IRQ,
+       MCT_G3_IRQ,
+       MCT_L0_IRQ,
+       MCT_L1_IRQ,
+       MCT_L2_IRQ,
+       MCT_L3_IRQ,
+       MCT_NR_IRQS,
+};
+
+static void __iomem *reg_base;
+static unsigned long clk_rate;
+static unsigned int mct_int_type;
+static int mct_irqs[MCT_NR_IRQS];
+
+struct mct_clock_event_device {
+       struct clock_event_device *evt;
+       unsigned long base;
+       char name[10];
+};
+
+static void exynos4_mct_write(unsigned int value, unsigned long offset)
+{
+       unsigned long stat_addr;
+       u32 mask;
+       u32 i;
+
+       __raw_writel(value, reg_base + offset);
+
+       if (likely(offset >= EXYNOS4_MCT_L_BASE(0))) {
+               stat_addr = (offset & ~EXYNOS4_MCT_L_MASK) + MCT_L_WSTAT_OFFSET;
+               switch (offset & EXYNOS4_MCT_L_MASK) {
+               case MCT_L_TCON_OFFSET:
+                       mask = 1 << 3;          /* L_TCON write status */
+                       break;
+               case MCT_L_ICNTB_OFFSET:
+                       mask = 1 << 1;          /* L_ICNTB write status */
+                       break;
+               case MCT_L_TCNTB_OFFSET:
+                       mask = 1 << 0;          /* L_TCNTB write status */
+                       break;
+               default:
+                       return;
+               }
+       } else {
+               switch (offset) {
+               case EXYNOS4_MCT_G_TCON:
+                       stat_addr = EXYNOS4_MCT_G_WSTAT;
+                       mask = 1 << 16;         /* G_TCON write status */
+                       break;
+               case EXYNOS4_MCT_G_COMP0_L:
+                       stat_addr = EXYNOS4_MCT_G_WSTAT;
+                       mask = 1 << 0;          /* G_COMP0_L write status */
+                       break;
+               case EXYNOS4_MCT_G_COMP0_U:
+                       stat_addr = EXYNOS4_MCT_G_WSTAT;
+                       mask = 1 << 1;          /* G_COMP0_U write status */
+                       break;
+               case EXYNOS4_MCT_G_COMP0_ADD_INCR:
+                       stat_addr = EXYNOS4_MCT_G_WSTAT;
+                       mask = 1 << 2;          /* G_COMP0_ADD_INCR w status */
+                       break;
+               case EXYNOS4_MCT_G_CNT_L:
+                       stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
+                       mask = 1 << 0;          /* G_CNT_L write status */
+                       break;
+               case EXYNOS4_MCT_G_CNT_U:
+                       stat_addr = EXYNOS4_MCT_G_CNT_WSTAT;
+                       mask = 1 << 1;          /* G_CNT_U write status */
+                       break;
+               default:
+                       return;
+               }
+       }
+
+       /* Wait maximum 1 ms until written values are applied */
+       for (i = 0; i < loops_per_jiffy / 1000 * HZ; i++)
+               if (__raw_readl(reg_base + stat_addr) & mask) {
+                       __raw_writel(mask, reg_base + stat_addr);
+                       return;
+               }
+
+       panic("MCT hangs after writing %d (offset:0x%lx)\n", value, offset);
+}
+
+/* Clocksource handling */
+static void exynos4_mct_frc_start(u32 hi, u32 lo)
+{
+       u32 reg;
+
+       exynos4_mct_write(lo, EXYNOS4_MCT_G_CNT_L);
+       exynos4_mct_write(hi, EXYNOS4_MCT_G_CNT_U);
+
+       reg = __raw_readl(reg_base + EXYNOS4_MCT_G_TCON);
+       reg |= MCT_G_TCON_START;
+       exynos4_mct_write(reg, EXYNOS4_MCT_G_TCON);
+}
+
+static cycle_t exynos4_frc_read(struct clocksource *cs)
+{
+       unsigned int lo, hi;
+       u32 hi2 = __raw_readl(reg_base + EXYNOS4_MCT_G_CNT_U);
+
+       do {
+               hi = hi2;
+               lo = __raw_readl(reg_base + EXYNOS4_MCT_G_CNT_L);
+               hi2 = __raw_readl(reg_base + EXYNOS4_MCT_G_CNT_U);
+       } while (hi != hi2);
+
+       return ((cycle_t)hi << 32) | lo;
+}
+
+static void exynos4_frc_resume(struct clocksource *cs)
+{
+       exynos4_mct_frc_start(0, 0);
+}
+
+struct clocksource mct_frc = {
+       .name           = "mct-frc",
+       .rating         = 400,
+       .read           = exynos4_frc_read,
+       .mask           = CLOCKSOURCE_MASK(64),
+       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
+       .resume         = exynos4_frc_resume,
+};
+
+static void __init exynos4_clocksource_init(void)
+{
+       exynos4_mct_frc_start(0, 0);
+
+       if (clocksource_register_hz(&mct_frc, clk_rate))
+               panic("%s: can't register clocksource\n", mct_frc.name);
+}
+
+static void exynos4_mct_comp0_stop(void)
+{
+       unsigned int tcon;
+
+       tcon = __raw_readl(reg_base + EXYNOS4_MCT_G_TCON);
+       tcon &= ~(MCT_G_TCON_COMP0_ENABLE | MCT_G_TCON_COMP0_AUTO_INC);
+
+       exynos4_mct_write(tcon, EXYNOS4_MCT_G_TCON);
+       exynos4_mct_write(0, EXYNOS4_MCT_G_INT_ENB);
+}
+
+static void exynos4_mct_comp0_start(enum clock_event_mode mode,
+                                   unsigned long cycles)
+{
+       unsigned int tcon;
+       cycle_t comp_cycle;
+
+       tcon = __raw_readl(reg_base + EXYNOS4_MCT_G_TCON);
+
+       if (mode == CLOCK_EVT_MODE_PERIODIC) {
+               tcon |= MCT_G_TCON_COMP0_AUTO_INC;
+               exynos4_mct_write(cycles, EXYNOS4_MCT_G_COMP0_ADD_INCR);
+       }
+
+       comp_cycle = exynos4_frc_read(&mct_frc) + cycles;
+       exynos4_mct_write((u32)comp_cycle, EXYNOS4_MCT_G_COMP0_L);
+       exynos4_mct_write((u32)(comp_cycle >> 32), EXYNOS4_MCT_G_COMP0_U);
+
+       exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_ENB);
+
+       tcon |= MCT_G_TCON_COMP0_ENABLE;
+       exynos4_mct_write(tcon , EXYNOS4_MCT_G_TCON);
+}
+
+static int exynos4_comp_set_next_event(unsigned long cycles,
+                                      struct clock_event_device *evt)
+{
+       exynos4_mct_comp0_start(evt->mode, cycles);
+
+       return 0;
+}
+
+static void exynos4_comp_set_mode(enum clock_event_mode mode,
+                                 struct clock_event_device *evt)
+{
+       unsigned long cycles_per_jiffy;
+       exynos4_mct_comp0_stop();
+
+       switch (mode) {
+       case CLOCK_EVT_MODE_PERIODIC:
+               cycles_per_jiffy =
+                       (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
+               exynos4_mct_comp0_start(mode, cycles_per_jiffy);
+               break;
+
+       case CLOCK_EVT_MODE_ONESHOT:
+       case CLOCK_EVT_MODE_UNUSED:
+       case CLOCK_EVT_MODE_SHUTDOWN:
+       case CLOCK_EVT_MODE_RESUME:
+               break;
+       }
+}
+
+static struct clock_event_device mct_comp_device = {
+       .name           = "mct-comp",
+       .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+       .rating         = 250,
+       .set_next_event = exynos4_comp_set_next_event,
+       .set_mode       = exynos4_comp_set_mode,
+};
+
+static irqreturn_t exynos4_mct_comp_isr(int irq, void *dev_id)
+{
+       struct clock_event_device *evt = dev_id;
+
+       exynos4_mct_write(0x1, EXYNOS4_MCT_G_INT_CSTAT);
+
+       evt->event_handler(evt);
+
+       return IRQ_HANDLED;
+}
+
+static struct irqaction mct_comp_event_irq = {
+       .name           = "mct_comp_irq",
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
+       .handler        = exynos4_mct_comp_isr,
+       .dev_id         = &mct_comp_device,
+};
+
+static void exynos4_clockevent_init(void)
+{
+       mct_comp_device.cpumask = cpumask_of(0);
+       clockevents_config_and_register(&mct_comp_device, clk_rate,
+                                       0xf, 0xffffffff);
+       setup_irq(mct_irqs[MCT_G0_IRQ], &mct_comp_event_irq);
+}
+
+#ifdef CONFIG_LOCAL_TIMERS
+
+static DEFINE_PER_CPU(struct mct_clock_event_device, percpu_mct_tick);
+
+/* Clock event handling */
+static void exynos4_mct_tick_stop(struct mct_clock_event_device *mevt)
+{
+       unsigned long tmp;
+       unsigned long mask = MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START;
+       unsigned long offset = mevt->base + MCT_L_TCON_OFFSET;
+
+       tmp = __raw_readl(reg_base + offset);
+       if (tmp & mask) {
+               tmp &= ~mask;
+               exynos4_mct_write(tmp, offset);
+       }
+}
+
+static void exynos4_mct_tick_start(unsigned long cycles,
+                                  struct mct_clock_event_device *mevt)
+{
+       unsigned long tmp;
+
+       exynos4_mct_tick_stop(mevt);
+
+       tmp = (1 << 31) | cycles;       /* MCT_L_UPDATE_ICNTB */
+
+       /* update interrupt count buffer */
+       exynos4_mct_write(tmp, mevt->base + MCT_L_ICNTB_OFFSET);
+
+       /* enable MCT tick interrupt */
+       exynos4_mct_write(0x1, mevt->base + MCT_L_INT_ENB_OFFSET);
+
+       tmp = __raw_readl(reg_base + mevt->base + MCT_L_TCON_OFFSET);
+       tmp |= MCT_L_TCON_INT_START | MCT_L_TCON_TIMER_START |
+              MCT_L_TCON_INTERVAL_MODE;
+       exynos4_mct_write(tmp, mevt->base + MCT_L_TCON_OFFSET);
+}
+
+static int exynos4_tick_set_next_event(unsigned long cycles,
+                                      struct clock_event_device *evt)
+{
+       struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
+
+       exynos4_mct_tick_start(cycles, mevt);
+
+       return 0;
+}
+
+static inline void exynos4_tick_set_mode(enum clock_event_mode mode,
+                                        struct clock_event_device *evt)
+{
+       struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
+       unsigned long cycles_per_jiffy;
+
+       exynos4_mct_tick_stop(mevt);
+
+       switch (mode) {
+       case CLOCK_EVT_MODE_PERIODIC:
+               cycles_per_jiffy =
+                       (((unsigned long long) NSEC_PER_SEC / HZ * evt->mult) >> evt->shift);
+               exynos4_mct_tick_start(cycles_per_jiffy, mevt);
+               break;
+
+       case CLOCK_EVT_MODE_ONESHOT:
+       case CLOCK_EVT_MODE_UNUSED:
+       case CLOCK_EVT_MODE_SHUTDOWN:
+       case CLOCK_EVT_MODE_RESUME:
+               break;
+       }
+}
+
+static int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
+{
+       struct clock_event_device *evt = mevt->evt;
+
+       /*
+        * This is for supporting oneshot mode.
+        * Mct would generate interrupt periodically
+        * without explicit stopping.
+        */
+       if (evt->mode != CLOCK_EVT_MODE_PERIODIC)
+               exynos4_mct_tick_stop(mevt);
+
+       /* Clear the MCT tick interrupt */
+       if (__raw_readl(reg_base + mevt->base + MCT_L_INT_CSTAT_OFFSET) & 1) {
+               exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET);
+               return 1;
+       } else {
+               return 0;
+       }
+}
+
+static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id)
+{
+       struct mct_clock_event_device *mevt = dev_id;
+       struct clock_event_device *evt = mevt->evt;
+
+       exynos4_mct_tick_clear(mevt);
+
+       evt->event_handler(evt);
+
+       return IRQ_HANDLED;
+}
+
+static struct irqaction mct_tick0_event_irq = {
+       .name           = "mct_tick0_irq",
+       .flags          = IRQF_TIMER | IRQF_NOBALANCING,
+       .handler        = exynos4_mct_tick_isr,
+};
+
+static struct irqaction mct_tick1_event_irq = {
+       .name           = "mct_tick1_irq",
+       .flags          = IRQF_TIMER | IRQF_NOBALANCING,
+       .handler        = exynos4_mct_tick_isr,
+};
+
+static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt)
+{
+       struct mct_clock_event_device *mevt;
+       unsigned int cpu = smp_processor_id();
+
+       mevt = this_cpu_ptr(&percpu_mct_tick);
+       mevt->evt = evt;
+
+       mevt->base = EXYNOS4_MCT_L_BASE(cpu);
+       sprintf(mevt->name, "mct_tick%d", cpu);
+
+       evt->name = mevt->name;
+       evt->cpumask = cpumask_of(cpu);
+       evt->set_next_event = exynos4_tick_set_next_event;
+       evt->set_mode = exynos4_tick_set_mode;
+       evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
+       evt->rating = 450;
+       clockevents_config_and_register(evt, clk_rate / (TICK_BASE_CNT + 1),
+                                       0xf, 0x7fffffff);
+
+       exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET);
+
+       if (mct_int_type == MCT_INT_SPI) {
+               if (cpu == 0) {
+                       mct_tick0_event_irq.dev_id = mevt;
+                       evt->irq = mct_irqs[MCT_L0_IRQ];
+                       setup_irq(evt->irq, &mct_tick0_event_irq);
+               } else {
+                       mct_tick1_event_irq.dev_id = mevt;
+                       evt->irq = mct_irqs[MCT_L1_IRQ];
+                       setup_irq(evt->irq, &mct_tick1_event_irq);
+                       irq_set_affinity(evt->irq, cpumask_of(1));
+               }
+       } else {
+               enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0);
+       }
+
+       return 0;
+}
+
+static void exynos4_local_timer_stop(struct clock_event_device *evt)
+{
+       unsigned int cpu = smp_processor_id();
+       evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
+       if (mct_int_type == MCT_INT_SPI)
+               if (cpu == 0)
+                       remove_irq(evt->irq, &mct_tick0_event_irq);
+               else
+                       remove_irq(evt->irq, &mct_tick1_event_irq);
+       else
+               disable_percpu_irq(mct_irqs[MCT_L0_IRQ]);
+}
+
+static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = {
+       .setup  = exynos4_local_timer_setup,
+       .stop   = exynos4_local_timer_stop,
+};
+#endif /* CONFIG_LOCAL_TIMERS */
+
+static void __init exynos4_timer_resources(struct device_node *np)
+{
+       struct clk *mct_clk, *tick_clk;
+
+       tick_clk = np ? of_clk_get_by_name(np, "fin_pll") :
+                               clk_get(NULL, "fin_pll");
+       if (IS_ERR(tick_clk))
+               panic("%s: unable to determine tick clock rate\n", __func__);
+       clk_rate = clk_get_rate(tick_clk);
+
+       mct_clk = np ? of_clk_get_by_name(np, "mct") : clk_get(NULL, "mct");
+       if (IS_ERR(mct_clk))
+               panic("%s: unable to retrieve mct clock instance\n", __func__);
+       clk_prepare_enable(mct_clk);
+
+       reg_base = np ? of_iomap(np, 0) : S5P_VA_SYSTIMER;
+       if (!reg_base)
+               panic("%s: unable to ioremap mct address space\n", __func__);
+
+#ifdef CONFIG_LOCAL_TIMERS
+       if (mct_int_type == MCT_INT_PPI) {
+               int err;
+
+               err = request_percpu_irq(mct_irqs[MCT_L0_IRQ],
+                                        exynos4_mct_tick_isr, "MCT",
+                                        &percpu_mct_tick);
+               WARN(err, "MCT: can't request IRQ %d (%d)\n",
+                    mct_irqs[MCT_L0_IRQ], err);
+       }
+
+       local_timer_register(&exynos4_mct_tick_ops);
+#endif /* CONFIG_LOCAL_TIMERS */
+}
+
+static const struct of_device_id exynos_mct_ids[] = {
+       { .compatible = "samsung,exynos4210-mct", .data = (void *)MCT_INT_SPI },
+       { .compatible = "samsung,exynos4412-mct", .data = (void *)MCT_INT_PPI },
+};
+
+void __init mct_init(void)
+{
+       struct device_node *np = NULL;
+       const struct of_device_id *match;
+       u32 nr_irqs, i;
+
+#ifdef CONFIG_OF
+       np = of_find_matching_node_and_match(NULL, exynos_mct_ids, &match);
+#endif
+       if (np) {
+               mct_int_type = (u32)(match->data);
+
+               /* This driver uses only one global timer interrupt */
+               mct_irqs[MCT_G0_IRQ] = irq_of_parse_and_map(np, MCT_G0_IRQ);
+
+               /*
+                * Find out the number of local irqs specified. The local
+                * timer irqs are specified after the four global timer
+                * irqs are specified.
+                */
+#ifdef CONFIG_OF
+               nr_irqs = of_irq_count(np);
+#endif
+               for (i = MCT_L0_IRQ; i < nr_irqs; i++)
+                       mct_irqs[i] = irq_of_parse_and_map(np, i);
+       } else if (soc_is_exynos4210()) {
+               mct_irqs[MCT_G0_IRQ] = EXYNOS4_IRQ_MCT_G0;
+               mct_irqs[MCT_L0_IRQ] = EXYNOS4_IRQ_MCT_L0;
+               mct_irqs[MCT_L1_IRQ] = EXYNOS4_IRQ_MCT_L1;
+               mct_int_type = MCT_INT_SPI;
+       } else {
+               panic("unable to determine mct controller type\n");
+       }
+
+       exynos4_timer_resources(np);
+       exynos4_clocksource_init();
+       exynos4_clockevent_init();
+}
+CLOCKSOURCE_OF_DECLARE(exynos4210, "samsung,exynos4210-mct", mct_init)
+CLOCKSOURCE_OF_DECLARE(exynos4412, "samsung,exynos4412-mct", mct_init)
diff --git a/drivers/clocksource/mxs_timer.c b/drivers/clocksource/mxs_timer.c
new file mode 100644 (file)
index 0000000..02af420
--- /dev/null
@@ -0,0 +1,304 @@
+/*
+ *  Copyright (C) 2000-2001 Deep Blue Solutions
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *  Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com)
+ *  Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *  Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/stmp_device.h>
+
+#include <asm/mach/time.h>
+#include <asm/sched_clock.h>
+
+/*
+ * There are 2 versions of the timrot on Freescale MXS-based SoCs.
+ * The v1 on MX23 only gets 16 bits counter, while v2 on MX28
+ * extends the counter to 32 bits.
+ *
+ * The implementation uses two timers, one for clock_event and
+ * another for clocksource. MX28 uses timrot 0 and 1, while MX23
+ * uses 0 and 2.
+ */
+
+#define MX23_TIMROT_VERSION_OFFSET     0x0a0
+#define MX28_TIMROT_VERSION_OFFSET     0x120
+#define BP_TIMROT_MAJOR_VERSION                24
+#define BV_TIMROT_VERSION_1            0x01
+#define BV_TIMROT_VERSION_2            0x02
+#define timrot_is_v1() (timrot_major_version == BV_TIMROT_VERSION_1)
+
+/*
+ * There are 4 registers for each timrotv2 instance, and 2 registers
+ * for each timrotv1. So address step 0x40 in macros below strides
+ * one instance of timrotv2 while two instances of timrotv1.
+ *
+ * As the result, HW_TIMROT_XXXn(1) defines the address of timrot1
+ * on MX28 while timrot2 on MX23.
+ */
+/* common between v1 and v2 */
+#define HW_TIMROT_ROTCTRL              0x00
+#define HW_TIMROT_TIMCTRLn(n)          (0x20 + (n) * 0x40)
+/* v1 only */
+#define HW_TIMROT_TIMCOUNTn(n)         (0x30 + (n) * 0x40)
+/* v2 only */
+#define HW_TIMROT_RUNNING_COUNTn(n)    (0x30 + (n) * 0x40)
+#define HW_TIMROT_FIXED_COUNTn(n)      (0x40 + (n) * 0x40)
+
+#define BM_TIMROT_TIMCTRLn_RELOAD      (1 << 6)
+#define BM_TIMROT_TIMCTRLn_UPDATE      (1 << 7)
+#define BM_TIMROT_TIMCTRLn_IRQ_EN      (1 << 14)
+#define BM_TIMROT_TIMCTRLn_IRQ         (1 << 15)
+#define BP_TIMROT_TIMCTRLn_SELECT      0
+#define BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL                0x8
+#define BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL                0xb
+#define BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS       0xf
+
+static struct clock_event_device mxs_clockevent_device;
+static enum clock_event_mode mxs_clockevent_mode = CLOCK_EVT_MODE_UNUSED;
+
+static void __iomem *mxs_timrot_base;
+static u32 timrot_major_version;
+
+static inline void timrot_irq_disable(void)
+{
+       __raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN, mxs_timrot_base +
+                    HW_TIMROT_TIMCTRLn(0) + STMP_OFFSET_REG_CLR);
+}
+
+static inline void timrot_irq_enable(void)
+{
+       __raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN, mxs_timrot_base +
+                    HW_TIMROT_TIMCTRLn(0) + STMP_OFFSET_REG_SET);
+}
+
+static void timrot_irq_acknowledge(void)
+{
+       __raw_writel(BM_TIMROT_TIMCTRLn_IRQ, mxs_timrot_base +
+                    HW_TIMROT_TIMCTRLn(0) + STMP_OFFSET_REG_CLR);
+}
+
+static cycle_t timrotv1_get_cycles(struct clocksource *cs)
+{
+       return ~((__raw_readl(mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1))
+                       & 0xffff0000) >> 16);
+}
+
+static int timrotv1_set_next_event(unsigned long evt,
+                                       struct clock_event_device *dev)
+{
+       /* timrot decrements the count */
+       __raw_writel(evt, mxs_timrot_base + HW_TIMROT_TIMCOUNTn(0));
+
+       return 0;
+}
+
+static int timrotv2_set_next_event(unsigned long evt,
+                                       struct clock_event_device *dev)
+{
+       /* timrot decrements the count */
+       __raw_writel(evt, mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(0));
+
+       return 0;
+}
+
+static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
+{
+       struct clock_event_device *evt = dev_id;
+
+       timrot_irq_acknowledge();
+       evt->event_handler(evt);
+
+       return IRQ_HANDLED;
+}
+
+static struct irqaction mxs_timer_irq = {
+       .name           = "MXS Timer Tick",
+       .dev_id         = &mxs_clockevent_device,
+       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
+       .handler        = mxs_timer_interrupt,
+};
+
+#ifdef DEBUG
+static const char *clock_event_mode_label[] const = {
+       [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
+       [CLOCK_EVT_MODE_ONESHOT]  = "CLOCK_EVT_MODE_ONESHOT",
+       [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
+       [CLOCK_EVT_MODE_UNUSED]   = "CLOCK_EVT_MODE_UNUSED"
+};
+#endif /* DEBUG */
+
+static void mxs_set_mode(enum clock_event_mode mode,
+                               struct clock_event_device *evt)
+{
+       /* Disable interrupt in timer module */
+       timrot_irq_disable();
+
+       if (mode != mxs_clockevent_mode) {
+               /* Set event time into the furthest future */
+               if (timrot_is_v1())
+                       __raw_writel(0xffff,
+                               mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1));
+               else
+                       __raw_writel(0xffffffff,
+                               mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1));
+
+               /* Clear pending interrupt */
+               timrot_irq_acknowledge();
+       }
+
+#ifdef DEBUG
+       pr_info("%s: changing mode from %s to %s\n", __func__,
+               clock_event_mode_label[mxs_clockevent_mode],
+               clock_event_mode_label[mode]);
+#endif /* DEBUG */
+
+       /* Remember timer mode */
+       mxs_clockevent_mode = mode;
+
+       switch (mode) {
+       case CLOCK_EVT_MODE_PERIODIC:
+               pr_err("%s: Periodic mode is not implemented\n", __func__);
+               break;
+       case CLOCK_EVT_MODE_ONESHOT:
+               timrot_irq_enable();
+               break;
+       case CLOCK_EVT_MODE_SHUTDOWN:
+       case CLOCK_EVT_MODE_UNUSED:
+       case CLOCK_EVT_MODE_RESUME:
+               /* Left event sources disabled, no more interrupts appear */
+               break;
+       }
+}
+
+static struct clock_event_device mxs_clockevent_device = {
+       .name           = "mxs_timrot",
+       .features       = CLOCK_EVT_FEAT_ONESHOT,
+       .set_mode       = mxs_set_mode,
+       .set_next_event = timrotv2_set_next_event,
+       .rating         = 200,
+};
+
+static int __init mxs_clockevent_init(struct clk *timer_clk)
+{
+       if (timrot_is_v1())
+               mxs_clockevent_device.set_next_event = timrotv1_set_next_event;
+       mxs_clockevent_device.cpumask = cpumask_of(0);
+       clockevents_config_and_register(&mxs_clockevent_device,
+                                       clk_get_rate(timer_clk),
+                                       timrot_is_v1() ? 0xf : 0x2,
+                                       timrot_is_v1() ? 0xfffe : 0xfffffffe);
+
+       return 0;
+}
+
+static struct clocksource clocksource_mxs = {
+       .name           = "mxs_timer",
+       .rating         = 200,
+       .read           = timrotv1_get_cycles,
+       .mask           = CLOCKSOURCE_MASK(16),
+       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static u32 notrace mxs_read_sched_clock_v2(void)
+{
+       return ~readl_relaxed(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1));
+}
+
+static int __init mxs_clocksource_init(struct clk *timer_clk)
+{
+       unsigned int c = clk_get_rate(timer_clk);
+
+       if (timrot_is_v1())
+               clocksource_register_hz(&clocksource_mxs, c);
+       else {
+               clocksource_mmio_init(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1),
+                       "mxs_timer", c, 200, 32, clocksource_mmio_readl_down);
+               setup_sched_clock(mxs_read_sched_clock_v2, 32, c);
+       }
+
+       return 0;
+}
+
+static void __init mxs_timer_init(struct device_node *np)
+{
+       struct clk *timer_clk;
+       int irq;
+
+       mxs_timrot_base = of_iomap(np, 0);
+       WARN_ON(!mxs_timrot_base);
+
+       timer_clk = of_clk_get(np, 0);
+       if (IS_ERR(timer_clk)) {
+               pr_err("%s: failed to get clk\n", __func__);
+               return;
+       }
+
+       clk_prepare_enable(timer_clk);
+
+       /*
+        * Initialize timers to a known state
+        */
+       stmp_reset_block(mxs_timrot_base + HW_TIMROT_ROTCTRL);
+
+       /* get timrot version */
+       timrot_major_version = __raw_readl(mxs_timrot_base +
+                       (of_device_is_compatible(np, "fsl,imx23-timrot") ?
+                                               MX23_TIMROT_VERSION_OFFSET :
+                                               MX28_TIMROT_VERSION_OFFSET));
+       timrot_major_version >>= BP_TIMROT_MAJOR_VERSION;
+
+       /* one for clock_event */
+       __raw_writel((timrot_is_v1() ?
+                       BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
+                       BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS) |
+                       BM_TIMROT_TIMCTRLn_UPDATE |
+                       BM_TIMROT_TIMCTRLn_IRQ_EN,
+                       mxs_timrot_base + HW_TIMROT_TIMCTRLn(0));
+
+       /* another for clocksource */
+       __raw_writel((timrot_is_v1() ?
+                       BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
+                       BV_TIMROTv2_TIMCTRLn_SELECT__TICK_ALWAYS) |
+                       BM_TIMROT_TIMCTRLn_RELOAD,
+                       mxs_timrot_base + HW_TIMROT_TIMCTRLn(1));
+
+       /* set clocksource timer fixed count to the maximum */
+       if (timrot_is_v1())
+               __raw_writel(0xffff,
+                       mxs_timrot_base + HW_TIMROT_TIMCOUNTn(1));
+       else
+               __raw_writel(0xffffffff,
+                       mxs_timrot_base + HW_TIMROT_FIXED_COUNTn(1));
+
+       /* init and register the timer to the framework */
+       mxs_clocksource_init(timer_clk);
+       mxs_clockevent_init(timer_clk);
+
+       /* Make irqs happen */
+       irq = irq_of_parse_and_map(np, 0);
+       setup_irq(irq, &mxs_timer_irq);
+}
+CLOCKSOURCE_OF_DECLARE(mxs, "fsl,timrot", mxs_timer_init);
index 4086b9167159391d07418e0d8b75509779bad6df..0ce85e29769b80ac7c9e2b958e84bf87505c09eb 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
 #include <linux/sunxi_timer.h>
-#include <linux/clk-provider.h>
+#include <linux/clk/sunxi.h>
 
 #define TIMER_CTL_REG          0x00
 #define TIMER_CTL_ENABLE               (1 << 0)
@@ -123,7 +123,7 @@ void __init sunxi_timer_init(void)
        if (irq <= 0)
                panic("Can't parse IRQ");
 
-       of_clk_init(NULL);
+       sunxi_init_clocks();
 
        clk = of_clk_get(node, 0);
        if (IS_ERR(clk))
index 0bde03feb095365602af6fe0239a5d13b26181b3..ae877b021b54449219cef0d1f3e43fe442c54bca 100644 (file)
@@ -154,29 +154,12 @@ static struct irqaction tegra_timer_irq = {
        .dev_id         = &tegra_clockevent,
 };
 
-static const struct of_device_id timer_match[] __initconst = {
-       { .compatible = "nvidia,tegra20-timer" },
-       {}
-};
-
-static const struct of_device_id rtc_match[] __initconst = {
-       { .compatible = "nvidia,tegra20-rtc" },
-       {}
-};
-
-static void __init tegra20_init_timer(void)
+static void __init tegra20_init_timer(struct device_node *np)
 {
-       struct device_node *np;
        struct clk *clk;
        unsigned long rate;
        int ret;
 
-       np = of_find_matching_node(NULL, timer_match);
-       if (!np) {
-               pr_err("Failed to find timer DT node\n");
-               BUG();
-       }
-
        timer_reg_base = of_iomap(np, 0);
        if (!timer_reg_base) {
                pr_err("Can't map timer registers\n");
@@ -189,7 +172,7 @@ static void __init tegra20_init_timer(void)
                BUG();
        }
 
-       clk = clk_get_sys("timer", NULL);
+       clk = of_clk_get(np, 0);
        if (IS_ERR(clk)) {
                pr_warn("Unable to get timer clock. Assuming 12Mhz input clock.\n");
                rate = 12000000;
@@ -200,30 +183,6 @@ static void __init tegra20_init_timer(void)
 
        of_node_put(np);
 
-       np = of_find_matching_node(NULL, rtc_match);
-       if (!np) {
-               pr_err("Failed to find RTC DT node\n");
-               BUG();
-       }
-
-       rtc_base = of_iomap(np, 0);
-       if (!rtc_base) {
-               pr_err("Can't map RTC registers");
-               BUG();
-       }
-
-       /*
-        * rtc registers are used by read_persistent_clock, keep the rtc clock
-        * enabled
-        */
-       clk = clk_get_sys("rtc-tegra", NULL);
-       if (IS_ERR(clk))
-               pr_warn("Unable to get rtc-tegra clock\n");
-       else
-               clk_prepare_enable(clk);
-
-       of_node_put(np);
-
        switch (rate) {
        case 12000000:
                timer_writel(0x000b, TIMERUS_USEC_CFG);
@@ -259,12 +218,34 @@ static void __init tegra20_init_timer(void)
        tegra_clockevent.irq = tegra_timer_irq.irq;
        clockevents_config_and_register(&tegra_clockevent, 1000000,
                                        0x1, 0x1fffffff);
-#ifdef CONFIG_HAVE_ARM_TWD
-       twd_local_timer_of_register();
-#endif
+}
+CLOCKSOURCE_OF_DECLARE(tegra20_timer, "nvidia,tegra20-timer", tegra20_init_timer);
+
+static void __init tegra20_init_rtc(struct device_node *np)
+{
+       struct clk *clk;
+
+       rtc_base = of_iomap(np, 0);
+       if (!rtc_base) {
+               pr_err("Can't map RTC registers");
+               BUG();
+       }
+
+       /*
+        * rtc registers are used by read_persistent_clock, keep the rtc clock
+        * enabled
+        */
+       clk = of_clk_get(np, 0);
+       if (IS_ERR(clk))
+               pr_warn("Unable to get rtc-tegra clock\n");
+       else
+               clk_prepare_enable(clk);
+
+       of_node_put(np);
+
        register_persistent_clock(NULL, tegra_read_persistent_clock);
 }
-CLOCKSOURCE_OF_DECLARE(tegra20, "nvidia,tegra20-timer", tegra20_init_timer);
+CLOCKSOURCE_OF_DECLARE(tegra20_rtc, "nvidia,tegra20-rtc", tegra20_init_rtc);
 
 #ifdef CONFIG_PM
 static u32 usec_config;
index 8efc86b5b5ddfe3b216acf331c37003776a06b9f..242255285597c605306cc45e89288db52d0921cd 100644 (file)
@@ -129,22 +129,10 @@ static struct irqaction irq = {
        .dev_id  = &clockevent,
 };
 
-static struct of_device_id vt8500_timer_ids[] = {
-       { .compatible = "via,vt8500-timer" },
-       { }
-};
-
-static void __init vt8500_timer_init(void)
+static void __init vt8500_timer_init(struct device_node *np)
 {
-       struct device_node *np;
        int timer_irq;
 
-       np = of_find_matching_node(NULL, vt8500_timer_ids);
-       if (!np) {
-               pr_err("%s: Timer description missing from Device Tree\n",
-                                                               __func__);
-               return;
-       }
        regbase = of_iomap(np, 0);
        if (!regbase) {
                pr_err("%s: Missing iobase description in Device Tree\n",
index 937bc286591f9349b5366295fa210412b8ffb756..57a8774f0b4ee907ab67d9c9f8fefd1e3d18fdbd 100644 (file)
@@ -730,7 +730,6 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
            policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
                cpumask_copy(policy->cpus, perf->shared_cpu_map);
        }
-       cpumask_copy(policy->related_cpus, perf->shared_cpu_map);
 
 #ifdef CONFIG_SMP
        dmi_check_system(sw_any_bug_dmi_table);
@@ -742,7 +741,6 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
        if (check_amd_hwpstate_cpu(cpu) && !acpi_pstate_strict) {
                cpumask_clear(policy->cpus);
                cpumask_set_cpu(cpu, policy->cpus);
-               cpumask_copy(policy->related_cpus, cpu_sibling_mask(cpu));
                policy->shared_type = CPUFREQ_SHARED_TYPE_HW;
                pr_info_once(PFX "overriding BIOS provided _PSD data\n");
        }
index 2fd779eb1ed1f9fcdb7cb70ab54ed319fe1e4160..bfd6273fd873531d864f3b4e104d37018a5d8dda 100644 (file)
@@ -180,15 +180,19 @@ static void cpufreq_stats_free_sysfs(unsigned int cpu)
 {
        struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
 
-       if (!cpufreq_frequency_get_table(cpu))
+       if (!policy)
                return;
 
-       if (policy && !policy_is_shared(policy)) {
+       if (!cpufreq_frequency_get_table(cpu))
+               goto put_ref;
+
+       if (!policy_is_shared(policy)) {
                pr_debug("%s: Free sysfs stat\n", __func__);
                sysfs_remove_group(&policy->kobj, &stats_attr_group);
        }
-       if (policy)
-               cpufreq_cpu_put(policy);
+
+put_ref:
+       cpufreq_cpu_put(policy);
 }
 
 static int cpufreq_stats_create_table(struct cpufreq_policy *policy,
index f6dd1e7611293bf5a66531f2acb285713439430c..ad72922919ed79b181a83467dea455216676d56c 100644 (file)
@@ -358,14 +358,14 @@ static void intel_pstate_sysfs_expose_params(void)
 static int intel_pstate_min_pstate(void)
 {
        u64 value;
-       rdmsrl(0xCE, value);
+       rdmsrl(MSR_PLATFORM_INFO, value);
        return (value >> 40) & 0xFF;
 }
 
 static int intel_pstate_max_pstate(void)
 {
        u64 value;
-       rdmsrl(0xCE, value);
+       rdmsrl(MSR_PLATFORM_INFO, value);
        return (value >> 8) & 0xFF;
 }
 
@@ -373,7 +373,7 @@ static int intel_pstate_turbo_pstate(void)
 {
        u64 value;
        int nont, ret;
-       rdmsrl(0x1AD, value);
+       rdmsrl(MSR_NHM_TURBO_RATIO_LIMIT, value);
        nont = intel_pstate_max_pstate();
        ret = ((value) & 255);
        if (ret <= nont)
@@ -454,7 +454,7 @@ static inline void intel_pstate_calc_busy(struct cpudata *cpu,
                                        sample->idletime_us * 100,
                                        sample->duration_us);
        core_pct = div64_u64(sample->aperf * 100, sample->mperf);
-       sample->freq = cpu->pstate.turbo_pstate * core_pct * 1000;
+       sample->freq = cpu->pstate.max_pstate * core_pct * 1000;
 
        sample->core_pct_busy = div_s64((sample->pstate_pct_busy * core_pct),
                                        100);
@@ -752,6 +752,29 @@ static struct cpufreq_driver intel_pstate_driver = {
 
 static int __initdata no_load;
 
+static int intel_pstate_msrs_not_valid(void)
+{
+       /* Check that all the msr's we are using are valid. */
+       u64 aperf, mperf, tmp;
+
+       rdmsrl(MSR_IA32_APERF, aperf);
+       rdmsrl(MSR_IA32_MPERF, mperf);
+
+       if (!intel_pstate_min_pstate() ||
+               !intel_pstate_max_pstate() ||
+               !intel_pstate_turbo_pstate())
+               return -ENODEV;
+
+       rdmsrl(MSR_IA32_APERF, tmp);
+       if (!(tmp - aperf))
+               return -ENODEV;
+
+       rdmsrl(MSR_IA32_MPERF, tmp);
+       if (!(tmp - mperf))
+               return -ENODEV;
+
+       return 0;
+}
 static int __init intel_pstate_init(void)
 {
        int cpu, rc = 0;
@@ -764,6 +787,9 @@ static int __init intel_pstate_init(void)
        if (!id)
                return -ENODEV;
 
+       if (intel_pstate_msrs_not_valid())
+               return -ENODEV;
+
        pr_info("Intel P-state driver initializing.\n");
 
        all_cpu_data = vmalloc(sizeof(void *) * num_possible_cpus());
index b2a0a0726a5405caf7c0f7d252745d9554e34643..cf268b14ae9a393890ac37597f29008ee2c93126 100644 (file)
@@ -1650,11 +1650,7 @@ struct caam_alg_template {
 };
 
 static struct caam_alg_template driver_algs[] = {
-       /*
-        * single-pass ipsec_esp descriptor
-        * authencesn(*,*) is also registered, although not present
-        * explicitly here.
-        */
+       /* single-pass ipsec_esp descriptor */
        {
                .name = "authenc(hmac(md5),cbc(aes))",
                .driver_name = "authenc-hmac-md5-cbc-aes-caam",
@@ -2217,9 +2213,7 @@ static int __init caam_algapi_init(void)
        for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
                /* TODO: check if h/w supports alg */
                struct caam_crypto_alg *t_alg;
-               bool done = false;
 
-authencesn:
                t_alg = caam_alg_alloc(ctrldev, &driver_algs[i]);
                if (IS_ERR(t_alg)) {
                        err = PTR_ERR(t_alg);
@@ -2233,25 +2227,8 @@ authencesn:
                        dev_warn(ctrldev, "%s alg registration failed\n",
                                t_alg->crypto_alg.cra_driver_name);
                        kfree(t_alg);
-               } else {
+               } else
                        list_add_tail(&t_alg->entry, &priv->alg_list);
-                       if (driver_algs[i].type == CRYPTO_ALG_TYPE_AEAD &&
-                           !memcmp(driver_algs[i].name, "authenc", 7) &&
-                           !done) {
-                               char *name;
-
-                               name = driver_algs[i].name;
-                               memmove(name + 10, name + 7, strlen(name) - 7);
-                               memcpy(name + 7, "esn", 3);
-
-                               name = driver_algs[i].driver_name;
-                               memmove(name + 10, name + 7, strlen(name) - 7);
-                               memcpy(name + 7, "esn", 3);
-
-                               done = true;
-                               goto authencesn;
-                       }
-               }
        }
        if (!list_empty(&priv->alg_list))
                dev_info(ctrldev, "%s algorithms registered in /proc/crypto\n",
index cf15e7813801a6cb8e1d631663a2fb4421cb5a7a..762aeff626ac6f7a980c8fe3019fcd72252ecd7c 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/types.h>
 #include <linux/debugfs.h>
 #include <linux/circ_buf.h>
-#include <linux/string.h>
 #include <net/xfrm.h>
 
 #include <crypto/algapi.h>
index 09b184adf31b73902a98651843805e0c129c15b9..5b2b5e61e4f9d0516e4b66090ba56ef79e941632 100644 (file)
@@ -38,7 +38,6 @@
 #include <linux/spinlock.h>
 #include <linux/rtnetlink.h>
 #include <linux/slab.h>
-#include <linux/string.h>
 
 #include <crypto/algapi.h>
 #include <crypto/aes.h>
@@ -1974,11 +1973,7 @@ struct talitos_alg_template {
 };
 
 static struct talitos_alg_template driver_algs[] = {
-       /*
-        * AEAD algorithms. These use a single-pass ipsec_esp descriptor.
-        * authencesn(*,*) is also registered, although not present
-        * explicitly here.
-        */
+       /* AEAD algorithms.  These use a single-pass ipsec_esp descriptor */
        {       .type = CRYPTO_ALG_TYPE_AEAD,
                .alg.crypto = {
                        .cra_name = "authenc(hmac(sha1),cbc(aes))",
@@ -2820,9 +2815,7 @@ static int talitos_probe(struct platform_device *ofdev)
                if (hw_supports(dev, driver_algs[i].desc_hdr_template)) {
                        struct talitos_crypto_alg *t_alg;
                        char *name = NULL;
-                       bool authenc = false;
 
-authencesn:
                        t_alg = talitos_alg_alloc(dev, &driver_algs[i]);
                        if (IS_ERR(t_alg)) {
                                err = PTR_ERR(t_alg);
@@ -2837,8 +2830,6 @@ authencesn:
                                err = crypto_register_alg(
                                                &t_alg->algt.alg.crypto);
                                name = t_alg->algt.alg.crypto.cra_driver_name;
-                               authenc = authenc ? !authenc :
-                                         !(bool)memcmp(name, "authenc", 7);
                                break;
                        case CRYPTO_ALG_TYPE_AHASH:
                                err = crypto_register_ahash(
@@ -2851,25 +2842,8 @@ authencesn:
                                dev_err(dev, "%s alg registration failed\n",
                                        name);
                                kfree(t_alg);
-                       } else {
+                       } else
                                list_add_tail(&t_alg->entry, &priv->alg_list);
-                               if (authenc) {
-                                       struct crypto_alg *alg =
-                                               &driver_algs[i].alg.crypto;
-
-                                       name = alg->cra_name;
-                                       memmove(name + 10, name + 7,
-                                               strlen(name) - 7);
-                                       memcpy(name + 7, "esn", 3);
-
-                                       name = alg->cra_driver_name;
-                                       memmove(name + 10, name + 7,
-                                               strlen(name) - 7);
-                                       memcpy(name + 7, "esn", 3);
-
-                                       goto authencesn;
-                               }
-                       }
                }
        }
        if (!list_empty(&priv->alg_list))
index c599558faedaf29128a5a10bb15eaed7dbc5d41c..43a5329d44837c4042687d6f93436b3caf0627c1 100644 (file)
@@ -1001,6 +1001,13 @@ static inline void convert_burst(u32 *maxburst)
                *maxburst = 0;
 }
 
+static inline void convert_slave_id(struct dw_dma_chan *dwc)
+{
+       struct dw_dma *dw = to_dw_dma(dwc->chan.device);
+
+       dwc->dma_sconfig.slave_id -= dw->request_line_base;
+}
+
 static int
 set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig)
 {
@@ -1015,6 +1022,7 @@ set_runtime_config(struct dma_chan *chan, struct dma_slave_config *sconfig)
 
        convert_burst(&dwc->dma_sconfig.src_maxburst);
        convert_burst(&dwc->dma_sconfig.dst_maxburst);
+       convert_slave_id(dwc);
 
        return 0;
 }
@@ -1276,9 +1284,9 @@ static struct dma_chan *dw_dma_xlate(struct of_phandle_args *dma_spec,
        if (dma_spec->args_count != 3)
                return NULL;
 
-       fargs.req = be32_to_cpup(dma_spec->args+0);
-       fargs.src = be32_to_cpup(dma_spec->args+1);
-       fargs.dst = be32_to_cpup(dma_spec->args+2);
+       fargs.req = dma_spec->args[0];
+       fargs.src = dma_spec->args[1];
+       fargs.dst = dma_spec->args[2];
 
        if (WARN_ON(fargs.req >= DW_DMA_MAX_NR_REQUESTS ||
                    fargs.src >= dw->nr_masters ||
@@ -1628,6 +1636,7 @@ dw_dma_parse_dt(struct platform_device *pdev)
 
 static int dw_probe(struct platform_device *pdev)
 {
+       const struct platform_device_id *match;
        struct dw_dma_platform_data *pdata;
        struct resource         *io;
        struct dw_dma           *dw;
@@ -1711,6 +1720,11 @@ static int dw_probe(struct platform_device *pdev)
                memcpy(dw->data_width, pdata->data_width, 4);
        }
 
+       /* Get the base request line if set */
+       match = platform_get_device_id(pdev);
+       if (match)
+               dw->request_line_base = (unsigned int)match->driver_data;
+
        /* Calculate all channel mask before DMA setup */
        dw->all_chan_mask = (1 << nr_channels) - 1;
 
@@ -1906,7 +1920,8 @@ MODULE_DEVICE_TABLE(of, dw_dma_id_table);
 #endif
 
 static const struct platform_device_id dw_dma_ids[] = {
-       { "INTL9C60", 0 },
+       /* Name,        Request Line Base */
+       { "INTL9C60",   (kernel_ulong_t)16 },
        { }
 };
 
index cf0ce5c77d609d52e024f3426ab521bdb86e7545..4d02c3669b75bcf023a7f03916d02d3749ec2e1e 100644 (file)
@@ -247,6 +247,7 @@ struct dw_dma {
        /* hardware configuration */
        unsigned char           nr_masters;
        unsigned char           data_width[4];
+       unsigned int            request_line_base;
 
        struct dw_dma_chan      chan[0];
 };
index 8f6d30d37c45bd4e995f160e4e85fc55d81b1fe5..b48a79c288454ec61676fbd4416fdfafc53187fd 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/stmp_device.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_dma.h>
 
 #include <asm/irq.h>
 
@@ -139,6 +140,8 @@ struct mxs_dma_engine {
        struct dma_device               dma_device;
        struct device_dma_parameters    dma_parms;
        struct mxs_dma_chan             mxs_chans[MXS_DMA_CHANNELS];
+       struct platform_device          *pdev;
+       unsigned int                    nr_channels;
 };
 
 struct mxs_dma_type {
@@ -350,10 +353,8 @@ static int mxs_dma_alloc_chan_resources(struct dma_chan *chan)
        struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
        int ret;
 
-       if (!data)
-               return -EINVAL;
-
-       mxs_chan->chan_irq = data->chan_irq;
+       if (data)
+               mxs_chan->chan_irq = data->chan_irq;
 
        mxs_chan->ccw = dma_alloc_coherent(mxs_dma->dma_device.dev,
                                CCW_BLOCK_SIZE, &mxs_chan->ccw_phys,
@@ -665,8 +666,55 @@ err_out:
        return ret;
 }
 
+struct mxs_dma_filter_param {
+       struct device_node *of_node;
+       unsigned int chan_id;
+};
+
+static bool mxs_dma_filter_fn(struct dma_chan *chan, void *fn_param)
+{
+       struct mxs_dma_filter_param *param = fn_param;
+       struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
+       struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
+       int chan_irq;
+
+       if (mxs_dma->dma_device.dev->of_node != param->of_node)
+               return false;
+
+       if (chan->chan_id != param->chan_id)
+               return false;
+
+       chan_irq = platform_get_irq(mxs_dma->pdev, param->chan_id);
+       if (chan_irq < 0)
+               return false;
+
+       mxs_chan->chan_irq = chan_irq;
+
+       return true;
+}
+
+struct dma_chan *mxs_dma_xlate(struct of_phandle_args *dma_spec,
+                              struct of_dma *ofdma)
+{
+       struct mxs_dma_engine *mxs_dma = ofdma->of_dma_data;
+       dma_cap_mask_t mask = mxs_dma->dma_device.cap_mask;
+       struct mxs_dma_filter_param param;
+
+       if (dma_spec->args_count != 1)
+               return NULL;
+
+       param.of_node = ofdma->of_node;
+       param.chan_id = dma_spec->args[0];
+
+       if (param.chan_id >= mxs_dma->nr_channels)
+               return NULL;
+
+       return dma_request_channel(mask, mxs_dma_filter_fn, &param);
+}
+
 static int __init mxs_dma_probe(struct platform_device *pdev)
 {
+       struct device_node *np = pdev->dev.of_node;
        const struct platform_device_id *id_entry;
        const struct of_device_id *of_id;
        const struct mxs_dma_type *dma_type;
@@ -674,10 +722,16 @@ static int __init mxs_dma_probe(struct platform_device *pdev)
        struct resource *iores;
        int ret, i;
 
-       mxs_dma = kzalloc(sizeof(*mxs_dma), GFP_KERNEL);
+       mxs_dma = devm_kzalloc(&pdev->dev, sizeof(*mxs_dma), GFP_KERNEL);
        if (!mxs_dma)
                return -ENOMEM;
 
+       ret = of_property_read_u32(np, "dma-channels", &mxs_dma->nr_channels);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to read dma-channels\n");
+               return ret;
+       }
+
        of_id = of_match_device(mxs_dma_dt_ids, &pdev->dev);
        if (of_id)
                id_entry = of_id->data;
@@ -689,24 +743,13 @@ static int __init mxs_dma_probe(struct platform_device *pdev)
        mxs_dma->dev_id = dma_type->id;
 
        iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       mxs_dma->base = devm_ioremap_resource(&pdev->dev, iores);
+       if (IS_ERR(mxs_dma->base))
+               return PTR_ERR(mxs_dma->base);
 
-       if (!request_mem_region(iores->start, resource_size(iores),
-                               pdev->name)) {
-               ret = -EBUSY;
-               goto err_request_region;
-       }
-
-       mxs_dma->base = ioremap(iores->start, resource_size(iores));
-       if (!mxs_dma->base) {
-               ret = -ENOMEM;
-               goto err_ioremap;
-       }
-
-       mxs_dma->clk = clk_get(&pdev->dev, NULL);
-       if (IS_ERR(mxs_dma->clk)) {
-               ret = PTR_ERR(mxs_dma->clk);
-               goto err_clk;
-       }
+       mxs_dma->clk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(mxs_dma->clk))
+               return PTR_ERR(mxs_dma->clk);
 
        dma_cap_set(DMA_SLAVE, mxs_dma->dma_device.cap_mask);
        dma_cap_set(DMA_CYCLIC, mxs_dma->dma_device.cap_mask);
@@ -732,8 +775,9 @@ static int __init mxs_dma_probe(struct platform_device *pdev)
 
        ret = mxs_dma_init(mxs_dma);
        if (ret)
-               goto err_init;
+               return ret;
 
+       mxs_dma->pdev = pdev;
        mxs_dma->dma_device.dev = &pdev->dev;
 
        /* mxs_dma gets 65535 bytes maximum sg size */
@@ -751,22 +795,19 @@ static int __init mxs_dma_probe(struct platform_device *pdev)
        ret = dma_async_device_register(&mxs_dma->dma_device);
        if (ret) {
                dev_err(mxs_dma->dma_device.dev, "unable to register\n");
-               goto err_init;
+               return ret;
+       }
+
+       ret = of_dma_controller_register(np, mxs_dma_xlate, mxs_dma);
+       if (ret) {
+               dev_err(mxs_dma->dma_device.dev,
+                       "failed to register controller\n");
+               dma_async_device_unregister(&mxs_dma->dma_device);
        }
 
        dev_info(mxs_dma->dma_device.dev, "initialized\n");
 
        return 0;
-
-err_init:
-       clk_put(mxs_dma->clk);
-err_clk:
-       iounmap(mxs_dma->base);
-err_ioremap:
-       release_mem_region(iores->start, resource_size(iores));
-err_request_region:
-       kfree(mxs_dma);
-       return ret;
 }
 
 static struct platform_driver mxs_dma_driver = {
index b70e3815c45932a3b76f7f30fff98d69907a8483..8f3c947b0029ab4a864d25dcd4a5ccaf4dfce90e 100644 (file)
 #define        DEV_NAME                        "max77693-muic"
 #define        DELAY_MS_DEFAULT                20000           /* unit: millisecond */
 
+/*
+ * Default value of MAX77693 register to bring up MUIC device.
+ * If user don't set some initial value for MUIC device through platform data,
+ * extcon-max77693 driver use 'default_init_data' to bring up base operation
+ * of MAX77693 MUIC device.
+ */
+struct max77693_reg_data default_init_data[] = {
+       {
+               /* STATUS2 - [3]ChgDetRun */
+               .addr = MAX77693_MUIC_REG_STATUS2,
+               .data = STATUS2_CHGDETRUN_MASK,
+       }, {
+               /* INTMASK1 - Unmask [3]ADC1KM,[0]ADCM */
+               .addr = MAX77693_MUIC_REG_INTMASK1,
+               .data = INTMASK1_ADC1K_MASK
+                       | INTMASK1_ADC_MASK,
+       }, {
+               /* INTMASK2 - Unmask [0]ChgTypM */
+               .addr = MAX77693_MUIC_REG_INTMASK2,
+               .data = INTMASK2_CHGTYP_MASK,
+       }, {
+               /* INTMASK3 - Mask all of interrupts */
+               .addr = MAX77693_MUIC_REG_INTMASK3,
+               .data = 0x0,
+       }, {
+               /* CDETCTRL2 */
+               .addr = MAX77693_MUIC_REG_CDETCTRL2,
+               .data = CDETCTRL2_VIDRMEN_MASK
+                       | CDETCTRL2_DXOVPEN_MASK,
+       },
+};
+
 enum max77693_muic_adc_debounce_time {
        ADC_DEBOUNCE_TIME_5MS = 0,
        ADC_DEBOUNCE_TIME_10MS,
@@ -1045,8 +1077,9 @@ static int max77693_muic_probe(struct platform_device *pdev)
 {
        struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent);
        struct max77693_platform_data *pdata = dev_get_platdata(max77693->dev);
-       struct max77693_muic_platform_data *muic_pdata = pdata->muic_data;
        struct max77693_muic_info *info;
+       struct max77693_reg_data *init_data;
+       int num_init_data;
        int delay_jiffies;
        int ret;
        int i;
@@ -1145,15 +1178,25 @@ static int max77693_muic_probe(struct platform_device *pdev)
                goto err_irq;
        }
 
-       /* Initialize MUIC register by using platform data */
-       for (i = 0 ; i < muic_pdata->num_init_data ; i++) {
-               enum max77693_irq_source irq_src = MAX77693_IRQ_GROUP_NR;
+
+       /* Initialize MUIC register by using platform data or default data */
+       if (pdata->muic_data) {
+               init_data = pdata->muic_data->init_data;
+               num_init_data = pdata->muic_data->num_init_data;
+       } else {
+               init_data = default_init_data;
+               num_init_data = ARRAY_SIZE(default_init_data);
+       }
+
+       for (i = 0 ; i < num_init_data ; i++) {
+               enum max77693_irq_source irq_src
+                               = MAX77693_IRQ_GROUP_NR;
 
                max77693_write_reg(info->max77693->regmap_muic,
-                               muic_pdata->init_data[i].addr,
-                               muic_pdata->init_data[i].data);
+                               init_data[i].addr,
+                               init_data[i].data);
 
-               switch (muic_pdata->init_data[i].addr) {
+               switch (init_data[i].addr) {
                case MAX77693_MUIC_REG_INTMASK1:
                        irq_src = MUIC_INT1;
                        break;
@@ -1167,22 +1210,40 @@ static int max77693_muic_probe(struct platform_device *pdev)
 
                if (irq_src < MAX77693_IRQ_GROUP_NR)
                        info->max77693->irq_masks_cur[irq_src]
-                               = muic_pdata->init_data[i].data;
+                               = init_data[i].data;
        }
 
-       /*
-        * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB
-        * h/w path of COMP2/COMN1 on CONTROL1 register.
-        */
-       if (muic_pdata->path_uart)
-               info->path_uart = muic_pdata->path_uart;
-       else
-               info->path_uart = CONTROL1_SW_UART;
+       if (pdata->muic_data) {
+               struct max77693_muic_platform_data *muic_pdata = pdata->muic_data;
 
-       if (muic_pdata->path_usb)
-               info->path_usb = muic_pdata->path_usb;
-       else
+               /*
+                * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB
+                * h/w path of COMP2/COMN1 on CONTROL1 register.
+                */
+               if (muic_pdata->path_uart)
+                       info->path_uart = muic_pdata->path_uart;
+               else
+                       info->path_uart = CONTROL1_SW_UART;
+
+               if (muic_pdata->path_usb)
+                       info->path_usb = muic_pdata->path_usb;
+               else
+                       info->path_usb = CONTROL1_SW_USB;
+
+               /*
+                * Default delay time for detecting cable state
+                * after certain time.
+                */
+               if (muic_pdata->detcable_delay_ms)
+                       delay_jiffies =
+                               msecs_to_jiffies(muic_pdata->detcable_delay_ms);
+               else
+                       delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
+       } else {
                info->path_usb = CONTROL1_SW_USB;
+               info->path_uart = CONTROL1_SW_UART;
+               delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
+       }
 
        /* Set initial path for UART */
         max77693_muic_set_path(info, info->path_uart, true);
@@ -1208,10 +1269,6 @@ static int max77693_muic_probe(struct platform_device *pdev)
         * driver should notify cable state to upper layer.
         */
        INIT_DELAYED_WORK(&info->wq_detcable, max77693_muic_detect_cable_wq);
-       if (muic_pdata->detcable_delay_ms)
-               delay_jiffies = msecs_to_jiffies(muic_pdata->detcable_delay_ms);
-       else
-               delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
        schedule_delayed_work(&info->wq_detcable, delay_jiffies);
 
        return ret;
index e636d950ad6c15d11d279474d3b55d89b572e257..69641bcae325a8f73e226ee66d9f418730c2ddbd 100644 (file)
@@ -712,29 +712,45 @@ static int max8997_muic_probe(struct platform_device *pdev)
                goto err_irq;
        }
 
-       /* Initialize registers according to platform data */
        if (pdata->muic_pdata) {
-               struct max8997_muic_platform_data *mdata = info->muic_pdata;
-
-               for (i = 0; i < mdata->num_init_data; i++) {
-                       max8997_write_reg(info->muic, mdata->init_data[i].addr,
-                                       mdata->init_data[i].data);
+               struct max8997_muic_platform_data *muic_pdata
+                       = pdata->muic_pdata;
+
+               /* Initialize registers according to platform data */
+               for (i = 0; i < muic_pdata->num_init_data; i++) {
+                       max8997_write_reg(info->muic,
+                                       muic_pdata->init_data[i].addr,
+                                       muic_pdata->init_data[i].data);
                }
-       }
 
-       /*
-        * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB
-        * h/w path of COMP2/COMN1 on CONTROL1 register.
-        */
-       if (pdata->muic_pdata->path_uart)
-               info->path_uart = pdata->muic_pdata->path_uart;
-       else
-               info->path_uart = CONTROL1_SW_UART;
+               /*
+                * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB
+                * h/w path of COMP2/COMN1 on CONTROL1 register.
+                */
+               if (muic_pdata->path_uart)
+                       info->path_uart = muic_pdata->path_uart;
+               else
+                       info->path_uart = CONTROL1_SW_UART;
 
-       if (pdata->muic_pdata->path_usb)
-               info->path_usb = pdata->muic_pdata->path_usb;
-       else
+               if (muic_pdata->path_usb)
+                       info->path_usb = muic_pdata->path_usb;
+               else
+                       info->path_usb = CONTROL1_SW_USB;
+
+               /*
+                * Default delay time for detecting cable state
+                * after certain time.
+                */
+               if (muic_pdata->detcable_delay_ms)
+                       delay_jiffies =
+                               msecs_to_jiffies(muic_pdata->detcable_delay_ms);
+               else
+                       delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
+       } else {
+               info->path_uart = CONTROL1_SW_UART;
                info->path_usb = CONTROL1_SW_USB;
+               delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
+       }
 
        /* Set initial path for UART */
         max8997_muic_set_path(info, info->path_uart, true);
@@ -751,10 +767,6 @@ static int max8997_muic_probe(struct platform_device *pdev)
         * driver should notify cable state to upper layer.
         */
        INIT_DELAYED_WORK(&info->wq_detcable, max8997_muic_detect_cable_wq);
-       if (pdata->muic_pdata->detcable_delay_ms)
-               delay_jiffies = msecs_to_jiffies(pdata->muic_pdata->detcable_delay_ms);
-       else
-               delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
        schedule_delayed_work(&info->wq_detcable, delay_jiffies);
 
        return 0;
index 9b00072a020fb5141060c5ee89cfe31edbd651be..42c759a4d047f6754ddf8676a390d8d0dcdffafb 100644 (file)
@@ -53,6 +53,24 @@ config EFI_VARS
          Subsequent efibootmgr releases may be found at:
          <http://linux.dell.com/efibootmgr>
 
+config EFI_VARS_PSTORE
+       bool "Register efivars backend for pstore"
+       depends on EFI_VARS && PSTORE
+       default y
+       help
+         Say Y here to enable use efivars as a backend to pstore. This
+         will allow writing console messages, crash dumps, or anything
+         else supported by pstore to EFI variables.
+
+config EFI_VARS_PSTORE_DEFAULT_DISABLE
+       bool "Disable using efivars as a pstore backend by default"
+       depends on EFI_VARS_PSTORE
+       default n
+       help
+         Saying Y here will disable the use of efivars as a storage
+         backend for pstore by default. This setting can be overridden
+         using the efivars module's pstore_disable parameter.
+
 config EFI_PCDP
        bool "Console device selection via EFI PCDP or HCDP table"
        depends on ACPI && EFI && IA64
index fe62aa3922398ebc52e7f61b586a71814a4b9dfe..7acafb80fd4c79b19b1c53551bb5e7e8612af707 100644 (file)
@@ -103,6 +103,11 @@ MODULE_VERSION(EFIVARS_VERSION);
  */
 #define GUID_LEN 36
 
+static bool efivars_pstore_disable =
+       IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE);
+
+module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644);
+
 /*
  * The maximum size of VariableName + Data = 1024
  * Therefore, it's reasonable to save that much
@@ -165,6 +170,7 @@ efivar_create_sysfs_entry(struct efivars *efivars,
 
 static void efivar_update_sysfs_entries(struct work_struct *);
 static DECLARE_WORK(efivar_work, efivar_update_sysfs_entries);
+static bool efivar_wq_enabled = true;
 
 /* Return the number of unicode characters in data */
 static unsigned long
@@ -1309,9 +1315,7 @@ static const struct inode_operations efivarfs_dir_inode_operations = {
        .create = efivarfs_create,
 };
 
-static struct pstore_info efi_pstore_info;
-
-#ifdef CONFIG_PSTORE
+#ifdef CONFIG_EFI_VARS_PSTORE
 
 static int efi_pstore_open(struct pstore_info *psi)
 {
@@ -1441,7 +1445,7 @@ static int efi_pstore_write(enum pstore_type_id type,
 
        spin_unlock_irqrestore(&efivars->lock, flags);
 
-       if (reason == KMSG_DUMP_OOPS)
+       if (reason == KMSG_DUMP_OOPS && efivar_wq_enabled)
                schedule_work(&efivar_work);
 
        *id = part;
@@ -1514,38 +1518,6 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
 
        return 0;
 }
-#else
-static int efi_pstore_open(struct pstore_info *psi)
-{
-       return 0;
-}
-
-static int efi_pstore_close(struct pstore_info *psi)
-{
-       return 0;
-}
-
-static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, int *count,
-                              struct timespec *timespec,
-                              char **buf, struct pstore_info *psi)
-{
-       return -1;
-}
-
-static int efi_pstore_write(enum pstore_type_id type,
-               enum kmsg_dump_reason reason, u64 *id,
-               unsigned int part, int count, size_t size,
-               struct pstore_info *psi)
-{
-       return 0;
-}
-
-static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
-                           struct timespec time, struct pstore_info *psi)
-{
-       return 0;
-}
-#endif
 
 static struct pstore_info efi_pstore_info = {
        .owner          = THIS_MODULE,
@@ -1557,6 +1529,24 @@ static struct pstore_info efi_pstore_info = {
        .erase          = efi_pstore_erase,
 };
 
+static void efivar_pstore_register(struct efivars *efivars)
+{
+       efivars->efi_pstore_info = efi_pstore_info;
+       efivars->efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
+       if (efivars->efi_pstore_info.buf) {
+               efivars->efi_pstore_info.bufsize = 1024;
+               efivars->efi_pstore_info.data = efivars;
+               spin_lock_init(&efivars->efi_pstore_info.buf_lock);
+               pstore_register(&efivars->efi_pstore_info);
+       }
+}
+#else
+static void efivar_pstore_register(struct efivars *efivars)
+{
+       return;
+}
+#endif
+
 static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
                             struct bin_attribute *bin_attr,
                             char *buf, loff_t pos, size_t count)
@@ -1716,6 +1706,31 @@ static bool variable_is_present(efi_char16_t *variable_name, efi_guid_t *vendor)
        return found;
 }
 
+/*
+ * Returns the size of variable_name, in bytes, including the
+ * terminating NULL character, or variable_name_size if no NULL
+ * character is found among the first variable_name_size bytes.
+ */
+static unsigned long var_name_strnsize(efi_char16_t *variable_name,
+                                      unsigned long variable_name_size)
+{
+       unsigned long len;
+       efi_char16_t c;
+
+       /*
+        * The variable name is, by definition, a NULL-terminated
+        * string, so make absolutely sure that variable_name_size is
+        * the value we expect it to be. If not, return the real size.
+        */
+       for (len = 2; len <= variable_name_size; len += sizeof(c)) {
+               c = variable_name[(len / sizeof(c)) - 1];
+               if (!c)
+                       break;
+       }
+
+       return min(len, variable_name_size);
+}
+
 static void efivar_update_sysfs_entries(struct work_struct *work)
 {
        struct efivars *efivars = &__efivars;
@@ -1756,10 +1771,13 @@ static void efivar_update_sysfs_entries(struct work_struct *work)
                if (!found) {
                        kfree(variable_name);
                        break;
-               } else
+               } else {
+                       variable_name_size = var_name_strnsize(variable_name,
+                                                              variable_name_size);
                        efivar_create_sysfs_entry(efivars,
                                                  variable_name_size,
                                                  variable_name, &vendor);
+               }
        }
 }
 
@@ -1958,6 +1976,35 @@ void unregister_efivars(struct efivars *efivars)
 }
 EXPORT_SYMBOL_GPL(unregister_efivars);
 
+/*
+ * Print a warning when duplicate EFI variables are encountered and
+ * disable the sysfs workqueue since the firmware is buggy.
+ */
+static void dup_variable_bug(efi_char16_t *s16, efi_guid_t *vendor_guid,
+                            unsigned long len16)
+{
+       size_t i, len8 = len16 / sizeof(efi_char16_t);
+       char *s8;
+
+       /*
+        * Disable the workqueue since the algorithm it uses for
+        * detecting new variables won't work with this buggy
+        * implementation of GetNextVariableName().
+        */
+       efivar_wq_enabled = false;
+
+       s8 = kzalloc(len8, GFP_KERNEL);
+       if (!s8)
+               return;
+
+       for (i = 0; i < len8; i++)
+               s8[i] = s16[i];
+
+       printk(KERN_WARNING "efivars: duplicate variable: %s-%pUl\n",
+              s8, vendor_guid);
+       kfree(s8);
+}
+
 int register_efivars(struct efivars *efivars,
                     const struct efivar_operations *ops,
                     struct kobject *parent_kobj)
@@ -2006,6 +2053,24 @@ int register_efivars(struct efivars *efivars,
                                                &vendor_guid);
                switch (status) {
                case EFI_SUCCESS:
+                       variable_name_size = var_name_strnsize(variable_name,
+                                                              variable_name_size);
+
+                       /*
+                        * Some firmware implementations return the
+                        * same variable name on multiple calls to
+                        * get_next_variable(). Terminate the loop
+                        * immediately as there is no guarantee that
+                        * we'll ever see a different variable name,
+                        * and may end up looping here forever.
+                        */
+                       if (variable_is_present(variable_name, &vendor_guid)) {
+                               dup_variable_bug(variable_name, &vendor_guid,
+                                                variable_name_size);
+                               status = EFI_NOT_FOUND;
+                               break;
+                       }
+
                        efivar_create_sysfs_entry(efivars,
                                                  variable_name_size,
                                                  variable_name,
@@ -2025,15 +2090,8 @@ int register_efivars(struct efivars *efivars,
        if (error)
                unregister_efivars(efivars);
 
-       efivars->efi_pstore_info = efi_pstore_info;
-
-       efivars->efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
-       if (efivars->efi_pstore_info.buf) {
-               efivars->efi_pstore_info.bufsize = 1024;
-               efivars->efi_pstore_info.data = efivars;
-               spin_lock_init(&efivars->efi_pstore_info.buf_lock);
-               pstore_register(&efivars->efi_pstore_info);
-       }
+       if (!efivars_pstore_disable)
+               efivar_pstore_register(efivars);
 
        register_filesystem(&efivarfs_type);
 
index 414ad912232f9ecc1558c42e865d289920375dfc..e3956359202c23080e5f751bf5484ba9792a3eb0 100644 (file)
@@ -72,6 +72,7 @@ struct tegra_gpio_bank {
        u32 oe[4];
        u32 int_enb[4];
        u32 int_lvl[4];
+       u32 wake_enb[4];
 #endif
 };
 
@@ -333,15 +334,31 @@ static int tegra_gpio_suspend(struct device *dev)
                        bank->oe[p] = tegra_gpio_readl(GPIO_OE(gpio));
                        bank->int_enb[p] = tegra_gpio_readl(GPIO_INT_ENB(gpio));
                        bank->int_lvl[p] = tegra_gpio_readl(GPIO_INT_LVL(gpio));
+
+                       /* Enable gpio irq for wake up source */
+                       tegra_gpio_writel(bank->wake_enb[p],
+                                         GPIO_INT_ENB(gpio));
                }
        }
        local_irq_restore(flags);
        return 0;
 }
 
-static int tegra_gpio_wake_enable(struct irq_data *d, unsigned int enable)
+static int tegra_gpio_irq_set_wake(struct irq_data *d, unsigned int enable)
 {
        struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
+       int gpio = d->hwirq;
+       u32 port, bit, mask;
+
+       port = GPIO_PORT(gpio);
+       bit = GPIO_BIT(gpio);
+       mask = BIT(bit);
+
+       if (enable)
+               bank->wake_enb[port] |= mask;
+       else
+               bank->wake_enb[port] &= ~mask;
+
        return irq_set_irq_wake(bank->irq, enable);
 }
 #endif
@@ -353,7 +370,7 @@ static struct irq_chip tegra_gpio_irq_chip = {
        .irq_unmask     = tegra_gpio_irq_unmask,
        .irq_set_type   = tegra_gpio_irq_set_type,
 #ifdef CONFIG_PM_SLEEP
-       .irq_set_wake   = tegra_gpio_wake_enable,
+       .irq_set_wake   = tegra_gpio_irq_set_wake,
 #endif
 };
 
index a71a54a3e3f783a4151ed5919c01290ade8ffd5d..5150df6cba0815623c9fc7c86e96ff2ad099f0ed 100644 (file)
@@ -193,7 +193,7 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
        if (!np)
                return;
 
-       do {
+       for (;; index++) {
                ret = of_parse_phandle_with_args(np, "gpio-ranges",
                                "#gpio-range-cells", index, &pinspec);
                if (ret)
@@ -222,8 +222,7 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip)
 
                if (ret)
                        break;
-
-       } while (index++);
+       }
 }
 
 #else
index 36493ce71f9a8c217ebe8af960598b299f1a95bb..98cc14725ba94c4d1dcd0d44242bb26d92eb75fa 100644 (file)
 /* position control register for hardware window 0, 2 ~ 4.*/
 #define VIDOSD_A(win)          (VIDOSD_BASE + 0x00 + (win) * 16)
 #define VIDOSD_B(win)          (VIDOSD_BASE + 0x04 + (win) * 16)
-/* size control register for hardware window 0. */
-#define VIDOSD_C_SIZE_W0       (VIDOSD_BASE + 0x08)
-/* alpha control register for hardware window 1 ~ 4. */
-#define VIDOSD_C(win)          (VIDOSD_BASE + 0x18 + (win) * 16)
-/* size control register for hardware window 1 ~ 4. */
+/*
+ * size control register for hardware windows 0 and alpha control register
+ * for hardware windows 1 ~ 4
+ */
+#define VIDOSD_C(win)          (VIDOSD_BASE + 0x08 + (win) * 16)
+/* size control register for hardware windows 1 ~ 2. */
 #define VIDOSD_D(win)          (VIDOSD_BASE + 0x0C + (win) * 16)
 
 #define VIDWx_BUF_START(win, buf)      (VIDW_BUF_START(buf) + (win) * 8)
@@ -50,9 +51,9 @@
 #define VIDWx_BUF_SIZE(win, buf)       (VIDW_BUF_SIZE(buf) + (win) * 4)
 
 /* color key control register for hardware window 1 ~ 4. */
-#define WKEYCON0_BASE(x)               ((WKEYCON0 + 0x140) + (x * 8))
+#define WKEYCON0_BASE(x)               ((WKEYCON0 + 0x140) + ((x - 1) * 8))
 /* color key value register for hardware window 1 ~ 4. */
-#define WKEYCON1_BASE(x)               ((WKEYCON1 + 0x140) + (x * 8))
+#define WKEYCON1_BASE(x)               ((WKEYCON1 + 0x140) + ((x - 1) * 8))
 
 /* FIMD has totally five hardware windows. */
 #define WINDOWS_NR     5
@@ -109,9 +110,9 @@ struct fimd_context {
 
 #ifdef CONFIG_OF
 static const struct of_device_id fimd_driver_dt_match[] = {
-       { .compatible = "samsung,exynos4-fimd",
+       { .compatible = "samsung,exynos4210-fimd",
          .data = &exynos4_fimd_driver_data },
-       { .compatible = "samsung,exynos5-fimd",
+       { .compatible = "samsung,exynos5250-fimd",
          .data = &exynos5_fimd_driver_data },
        {},
 };
@@ -581,7 +582,7 @@ static void fimd_win_commit(struct device *dev, int zpos)
        if (win != 3 && win != 4) {
                u32 offset = VIDOSD_D(win);
                if (win == 0)
-                       offset = VIDOSD_C_SIZE_W0;
+                       offset = VIDOSD_C(win);
                val = win_data->ovl_width * win_data->ovl_height;
                writel(val, ctx->regs + offset);
 
index 3b0da0378acf509976361d85322dc1fbc5c6779f..47a493c8a71f2629b7acf0de109bcd3eefc15bfd 100644 (file)
 
 /* registers for base address */
 #define G2D_SRC_BASE_ADDR              0x0304
+#define G2D_SRC_COLOR_MODE             0x030C
+#define G2D_SRC_LEFT_TOP               0x0310
+#define G2D_SRC_RIGHT_BOTTOM           0x0314
 #define G2D_SRC_PLANE2_BASE_ADDR       0x0318
 #define G2D_DST_BASE_ADDR              0x0404
+#define G2D_DST_COLOR_MODE             0x040C
+#define G2D_DST_LEFT_TOP               0x0410
+#define G2D_DST_RIGHT_BOTTOM           0x0414
 #define G2D_DST_PLANE2_BASE_ADDR       0x0418
 #define G2D_PAT_BASE_ADDR              0x0500
 #define G2D_MSK_BASE_ADDR              0x0520
@@ -82,7 +88,7 @@
 #define G2D_DMA_LIST_DONE_COUNT_OFFSET 17
 
 /* G2D_DMA_HOLD_CMD */
-#define G2D_USET_HOLD                  (1 << 2)
+#define G2D_USER_HOLD                  (1 << 2)
 #define G2D_LIST_HOLD                  (1 << 1)
 #define G2D_BITBLT_HOLD                        (1 << 0)
 
 #define G2D_START_NHOLT                        (1 << 1)
 #define G2D_START_BITBLT               (1 << 0)
 
+/* buffer color format */
+#define G2D_FMT_XRGB8888               0
+#define G2D_FMT_ARGB8888               1
+#define G2D_FMT_RGB565                 2
+#define G2D_FMT_XRGB1555               3
+#define G2D_FMT_ARGB1555               4
+#define G2D_FMT_XRGB4444               5
+#define G2D_FMT_ARGB4444               6
+#define G2D_FMT_PACKED_RGB888          7
+#define G2D_FMT_A8                     11
+#define G2D_FMT_L8                     12
+
+/* buffer valid length */
+#define G2D_LEN_MIN                    1
+#define G2D_LEN_MAX                    8000
+
 #define G2D_CMDLIST_SIZE               (PAGE_SIZE / 4)
 #define G2D_CMDLIST_NUM                        64
 #define G2D_CMDLIST_POOL_SIZE          (G2D_CMDLIST_SIZE * G2D_CMDLIST_NUM)
 #define G2D_CMDLIST_DATA_NUM           (G2D_CMDLIST_SIZE / sizeof(u32) - 2)
 
-#define MAX_BUF_ADDR_NR                        6
-
 /* maximum buffer pool size of userptr is 64MB as default */
 #define MAX_POOL               (64 * 1024 * 1024)
 
@@ -106,6 +126,17 @@ enum {
        BUF_TYPE_USERPTR,
 };
 
+enum g2d_reg_type {
+       REG_TYPE_NONE = -1,
+       REG_TYPE_SRC,
+       REG_TYPE_SRC_PLANE2,
+       REG_TYPE_DST,
+       REG_TYPE_DST_PLANE2,
+       REG_TYPE_PAT,
+       REG_TYPE_MSK,
+       MAX_REG_TYPE_NR
+};
+
 /* cmdlist data structure */
 struct g2d_cmdlist {
        u32             head;
@@ -113,6 +144,42 @@ struct g2d_cmdlist {
        u32             last;   /* last data offset */
 };
 
+/*
+ * A structure of buffer description
+ *
+ * @format: color format
+ * @left_x: the x coordinates of left top corner
+ * @top_y: the y coordinates of left top corner
+ * @right_x: the x coordinates of right bottom corner
+ * @bottom_y: the y coordinates of right bottom corner
+ *
+ */
+struct g2d_buf_desc {
+       unsigned int    format;
+       unsigned int    left_x;
+       unsigned int    top_y;
+       unsigned int    right_x;
+       unsigned int    bottom_y;
+};
+
+/*
+ * A structure of buffer information
+ *
+ * @map_nr: manages the number of mapped buffers
+ * @reg_types: stores regitster type in the order of requested command
+ * @handles: stores buffer handle in its reg_type position
+ * @types: stores buffer type in its reg_type position
+ * @descs: stores buffer description in its reg_type position
+ *
+ */
+struct g2d_buf_info {
+       unsigned int            map_nr;
+       enum g2d_reg_type       reg_types[MAX_REG_TYPE_NR];
+       unsigned long           handles[MAX_REG_TYPE_NR];
+       unsigned int            types[MAX_REG_TYPE_NR];
+       struct g2d_buf_desc     descs[MAX_REG_TYPE_NR];
+};
+
 struct drm_exynos_pending_g2d_event {
        struct drm_pending_event        base;
        struct drm_exynos_g2d_event     event;
@@ -131,14 +198,11 @@ struct g2d_cmdlist_userptr {
        bool                    in_pool;
        bool                    out_of_list;
 };
-
 struct g2d_cmdlist_node {
        struct list_head        list;
        struct g2d_cmdlist      *cmdlist;
-       unsigned int            map_nr;
-       unsigned long           handles[MAX_BUF_ADDR_NR];
-       unsigned int            obj_type[MAX_BUF_ADDR_NR];
        dma_addr_t              dma_addr;
+       struct g2d_buf_info     buf_info;
 
        struct drm_exynos_pending_g2d_event     *event;
 };
@@ -188,6 +252,7 @@ static int g2d_init_cmdlist(struct g2d_data *g2d)
        struct exynos_drm_subdrv *subdrv = &g2d->subdrv;
        int nr;
        int ret;
+       struct g2d_buf_info *buf_info;
 
        init_dma_attrs(&g2d->cmdlist_dma_attrs);
        dma_set_attr(DMA_ATTR_WRITE_COMBINE, &g2d->cmdlist_dma_attrs);
@@ -209,11 +274,17 @@ static int g2d_init_cmdlist(struct g2d_data *g2d)
        }
 
        for (nr = 0; nr < G2D_CMDLIST_NUM; nr++) {
+               unsigned int i;
+
                node[nr].cmdlist =
                        g2d->cmdlist_pool_virt + nr * G2D_CMDLIST_SIZE;
                node[nr].dma_addr =
                        g2d->cmdlist_pool + nr * G2D_CMDLIST_SIZE;
 
+               buf_info = &node[nr].buf_info;
+               for (i = 0; i < MAX_REG_TYPE_NR; i++)
+                       buf_info->reg_types[i] = REG_TYPE_NONE;
+
                list_add_tail(&node[nr].list, &g2d->free_cmdlist);
        }
 
@@ -450,7 +521,7 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
                                                DMA_BIDIRECTIONAL);
        if (ret < 0) {
                DRM_ERROR("failed to map sgt with dma region.\n");
-               goto err_free_sgt;
+               goto err_sg_free_table;
        }
 
        g2d_userptr->dma_addr = sgt->sgl[0].dma_address;
@@ -467,8 +538,10 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
 
        return &g2d_userptr->dma_addr;
 
-err_free_sgt:
+err_sg_free_table:
        sg_free_table(sgt);
+
+err_free_sgt:
        kfree(sgt);
        sgt = NULL;
 
@@ -506,36 +579,172 @@ static void g2d_userptr_free_all(struct drm_device *drm_dev,
        g2d->current_pool = 0;
 }
 
+static enum g2d_reg_type g2d_get_reg_type(int reg_offset)
+{
+       enum g2d_reg_type reg_type;
+
+       switch (reg_offset) {
+       case G2D_SRC_BASE_ADDR:
+       case G2D_SRC_COLOR_MODE:
+       case G2D_SRC_LEFT_TOP:
+       case G2D_SRC_RIGHT_BOTTOM:
+               reg_type = REG_TYPE_SRC;
+               break;
+       case G2D_SRC_PLANE2_BASE_ADDR:
+               reg_type = REG_TYPE_SRC_PLANE2;
+               break;
+       case G2D_DST_BASE_ADDR:
+       case G2D_DST_COLOR_MODE:
+       case G2D_DST_LEFT_TOP:
+       case G2D_DST_RIGHT_BOTTOM:
+               reg_type = REG_TYPE_DST;
+               break;
+       case G2D_DST_PLANE2_BASE_ADDR:
+               reg_type = REG_TYPE_DST_PLANE2;
+               break;
+       case G2D_PAT_BASE_ADDR:
+               reg_type = REG_TYPE_PAT;
+               break;
+       case G2D_MSK_BASE_ADDR:
+               reg_type = REG_TYPE_MSK;
+               break;
+       default:
+               reg_type = REG_TYPE_NONE;
+               DRM_ERROR("Unknown register offset![%d]\n", reg_offset);
+               break;
+       };
+
+       return reg_type;
+}
+
+static unsigned long g2d_get_buf_bpp(unsigned int format)
+{
+       unsigned long bpp;
+
+       switch (format) {
+       case G2D_FMT_XRGB8888:
+       case G2D_FMT_ARGB8888:
+               bpp = 4;
+               break;
+       case G2D_FMT_RGB565:
+       case G2D_FMT_XRGB1555:
+       case G2D_FMT_ARGB1555:
+       case G2D_FMT_XRGB4444:
+       case G2D_FMT_ARGB4444:
+               bpp = 2;
+               break;
+       case G2D_FMT_PACKED_RGB888:
+               bpp = 3;
+               break;
+       default:
+               bpp = 1;
+               break;
+       }
+
+       return bpp;
+}
+
+static bool g2d_check_buf_desc_is_valid(struct g2d_buf_desc *buf_desc,
+                                               enum g2d_reg_type reg_type,
+                                               unsigned long size)
+{
+       unsigned int width, height;
+       unsigned long area;
+
+       /*
+        * check source and destination buffers only.
+        * so the others are always valid.
+        */
+       if (reg_type != REG_TYPE_SRC && reg_type != REG_TYPE_DST)
+               return true;
+
+       width = buf_desc->right_x - buf_desc->left_x;
+       if (width < G2D_LEN_MIN || width > G2D_LEN_MAX) {
+               DRM_ERROR("width[%u] is out of range!\n", width);
+               return false;
+       }
+
+       height = buf_desc->bottom_y - buf_desc->top_y;
+       if (height < G2D_LEN_MIN || height > G2D_LEN_MAX) {
+               DRM_ERROR("height[%u] is out of range!\n", height);
+               return false;
+       }
+
+       area = (unsigned long)width * (unsigned long)height *
+                                       g2d_get_buf_bpp(buf_desc->format);
+       if (area > size) {
+               DRM_ERROR("area[%lu] is out of range[%lu]!\n", area, size);
+               return false;
+       }
+
+       return true;
+}
+
 static int g2d_map_cmdlist_gem(struct g2d_data *g2d,
                                struct g2d_cmdlist_node *node,
                                struct drm_device *drm_dev,
                                struct drm_file *file)
 {
        struct g2d_cmdlist *cmdlist = node->cmdlist;
+       struct g2d_buf_info *buf_info = &node->buf_info;
        int offset;
+       int ret;
        int i;
 
-       for (i = 0; i < node->map_nr; i++) {
+       for (i = 0; i < buf_info->map_nr; i++) {
+               struct g2d_buf_desc *buf_desc;
+               enum g2d_reg_type reg_type;
+               int reg_pos;
                unsigned long handle;
                dma_addr_t *addr;
 
-               offset = cmdlist->last - (i * 2 + 1);
-               handle = cmdlist->data[offset];
+               reg_pos = cmdlist->last - 2 * (i + 1);
+
+               offset = cmdlist->data[reg_pos];
+               handle = cmdlist->data[reg_pos + 1];
+
+               reg_type = g2d_get_reg_type(offset);
+               if (reg_type == REG_TYPE_NONE) {
+                       ret = -EFAULT;
+                       goto err;
+               }
+
+               buf_desc = &buf_info->descs[reg_type];
+
+               if (buf_info->types[reg_type] == BUF_TYPE_GEM) {
+                       unsigned long size;
+
+                       size = exynos_drm_gem_get_size(drm_dev, handle, file);
+                       if (!size) {
+                               ret = -EFAULT;
+                               goto err;
+                       }
+
+                       if (!g2d_check_buf_desc_is_valid(buf_desc, reg_type,
+                                                                       size)) {
+                               ret = -EFAULT;
+                               goto err;
+                       }
 
-               if (node->obj_type[i] == BUF_TYPE_GEM) {
                        addr = exynos_drm_gem_get_dma_addr(drm_dev, handle,
                                                                file);
                        if (IS_ERR(addr)) {
-                               node->map_nr = i;
-                               return -EFAULT;
+                               ret = -EFAULT;
+                               goto err;
                        }
                } else {
                        struct drm_exynos_g2d_userptr g2d_userptr;
 
                        if (copy_from_user(&g2d_userptr, (void __user *)handle,
                                sizeof(struct drm_exynos_g2d_userptr))) {
-                               node->map_nr = i;
-                               return -EFAULT;
+                               ret = -EFAULT;
+                               goto err;
+                       }
+
+                       if (!g2d_check_buf_desc_is_valid(buf_desc, reg_type,
+                                                       g2d_userptr.size)) {
+                               ret = -EFAULT;
+                               goto err;
                        }
 
                        addr = g2d_userptr_get_dma_addr(drm_dev,
@@ -544,16 +753,21 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d,
                                                        file,
                                                        &handle);
                        if (IS_ERR(addr)) {
-                               node->map_nr = i;
-                               return -EFAULT;
+                               ret = -EFAULT;
+                               goto err;
                        }
                }
 
-               cmdlist->data[offset] = *addr;
-               node->handles[i] = handle;
+               cmdlist->data[reg_pos + 1] = *addr;
+               buf_info->reg_types[i] = reg_type;
+               buf_info->handles[reg_type] = handle;
        }
 
        return 0;
+
+err:
+       buf_info->map_nr = i;
+       return ret;
 }
 
 static void g2d_unmap_cmdlist_gem(struct g2d_data *g2d,
@@ -561,22 +775,33 @@ static void g2d_unmap_cmdlist_gem(struct g2d_data *g2d,
                                  struct drm_file *filp)
 {
        struct exynos_drm_subdrv *subdrv = &g2d->subdrv;
+       struct g2d_buf_info *buf_info = &node->buf_info;
        int i;
 
-       for (i = 0; i < node->map_nr; i++) {
-               unsigned long handle = node->handles[i];
+       for (i = 0; i < buf_info->map_nr; i++) {
+               struct g2d_buf_desc *buf_desc;
+               enum g2d_reg_type reg_type;
+               unsigned long handle;
+
+               reg_type = buf_info->reg_types[i];
+
+               buf_desc = &buf_info->descs[reg_type];
+               handle = buf_info->handles[reg_type];
 
-               if (node->obj_type[i] == BUF_TYPE_GEM)
+               if (buf_info->types[reg_type] == BUF_TYPE_GEM)
                        exynos_drm_gem_put_dma_addr(subdrv->drm_dev, handle,
                                                        filp);
                else
                        g2d_userptr_put_dma_addr(subdrv->drm_dev, handle,
                                                        false);
 
-               node->handles[i] = 0;
+               buf_info->reg_types[i] = REG_TYPE_NONE;
+               buf_info->handles[reg_type] = 0;
+               buf_info->types[reg_type] = 0;
+               memset(buf_desc, 0x00, sizeof(*buf_desc));
        }
 
-       node->map_nr = 0;
+       buf_info->map_nr = 0;
 }
 
 static void g2d_dma_start(struct g2d_data *g2d,
@@ -589,10 +814,6 @@ static void g2d_dma_start(struct g2d_data *g2d,
        pm_runtime_get_sync(g2d->dev);
        clk_enable(g2d->gate_clk);
 
-       /* interrupt enable */
-       writel_relaxed(G2D_INTEN_ACF | G2D_INTEN_UCF | G2D_INTEN_GCF,
-                       g2d->regs + G2D_INTEN);
-
        writel_relaxed(node->dma_addr, g2d->regs + G2D_DMA_SFR_BASE_ADDR);
        writel_relaxed(G2D_DMA_START, g2d->regs + G2D_DMA_COMMAND);
 }
@@ -643,7 +864,6 @@ static void g2d_runqueue_worker(struct work_struct *work)
        struct g2d_data *g2d = container_of(work, struct g2d_data,
                                            runqueue_work);
 
-
        mutex_lock(&g2d->runqueue_mutex);
        clk_disable(g2d->gate_clk);
        pm_runtime_put_sync(g2d->dev);
@@ -724,20 +944,14 @@ static int g2d_check_reg_offset(struct device *dev,
        int i;
 
        for (i = 0; i < nr; i++) {
-               index = cmdlist->last - 2 * (i + 1);
+               struct g2d_buf_info *buf_info = &node->buf_info;
+               struct g2d_buf_desc *buf_desc;
+               enum g2d_reg_type reg_type;
+               unsigned long value;
 
-               if (for_addr) {
-                       /* check userptr buffer type. */
-                       reg_offset = (cmdlist->data[index] &
-                                       ~0x7fffffff) >> 31;
-                       if (reg_offset) {
-                               node->obj_type[i] = BUF_TYPE_USERPTR;
-                               cmdlist->data[index] &= ~G2D_BUF_USERPTR;
-                       }
-               }
+               index = cmdlist->last - 2 * (i + 1);
 
                reg_offset = cmdlist->data[index] & ~0xfffff000;
-
                if (reg_offset < G2D_VALID_START || reg_offset > G2D_VALID_END)
                        goto err;
                if (reg_offset % 4)
@@ -753,8 +967,60 @@ static int g2d_check_reg_offset(struct device *dev,
                        if (!for_addr)
                                goto err;
 
-                       if (node->obj_type[i] != BUF_TYPE_USERPTR)
-                               node->obj_type[i] = BUF_TYPE_GEM;
+                       reg_type = g2d_get_reg_type(reg_offset);
+                       if (reg_type == REG_TYPE_NONE)
+                               goto err;
+
+                       /* check userptr buffer type. */
+                       if ((cmdlist->data[index] & ~0x7fffffff) >> 31) {
+                               buf_info->types[reg_type] = BUF_TYPE_USERPTR;
+                               cmdlist->data[index] &= ~G2D_BUF_USERPTR;
+                       } else
+                               buf_info->types[reg_type] = BUF_TYPE_GEM;
+                       break;
+               case G2D_SRC_COLOR_MODE:
+               case G2D_DST_COLOR_MODE:
+                       if (for_addr)
+                               goto err;
+
+                       reg_type = g2d_get_reg_type(reg_offset);
+                       if (reg_type == REG_TYPE_NONE)
+                               goto err;
+
+                       buf_desc = &buf_info->descs[reg_type];
+                       value = cmdlist->data[index + 1];
+
+                       buf_desc->format = value & 0xf;
+                       break;
+               case G2D_SRC_LEFT_TOP:
+               case G2D_DST_LEFT_TOP:
+                       if (for_addr)
+                               goto err;
+
+                       reg_type = g2d_get_reg_type(reg_offset);
+                       if (reg_type == REG_TYPE_NONE)
+                               goto err;
+
+                       buf_desc = &buf_info->descs[reg_type];
+                       value = cmdlist->data[index + 1];
+
+                       buf_desc->left_x = value & 0x1fff;
+                       buf_desc->top_y = (value & 0x1fff0000) >> 16;
+                       break;
+               case G2D_SRC_RIGHT_BOTTOM:
+               case G2D_DST_RIGHT_BOTTOM:
+                       if (for_addr)
+                               goto err;
+
+                       reg_type = g2d_get_reg_type(reg_offset);
+                       if (reg_type == REG_TYPE_NONE)
+                               goto err;
+
+                       buf_desc = &buf_info->descs[reg_type];
+                       value = cmdlist->data[index + 1];
+
+                       buf_desc->right_x = value & 0x1fff;
+                       buf_desc->bottom_y = (value & 0x1fff0000) >> 16;
                        break;
                default:
                        if (for_addr)
@@ -860,9 +1126,23 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data,
        cmdlist->data[cmdlist->last++] = G2D_SRC_BASE_ADDR;
        cmdlist->data[cmdlist->last++] = 0;
 
+       /*
+        * 'LIST_HOLD' command should be set to the DMA_HOLD_CMD_REG
+        * and GCF bit should be set to INTEN register if user wants
+        * G2D interrupt event once current command list execution is
+        * finished.
+        * Otherwise only ACF bit should be set to INTEN register so
+        * that one interrupt is occured after all command lists
+        * have been completed.
+        */
        if (node->event) {
+               cmdlist->data[cmdlist->last++] = G2D_INTEN;
+               cmdlist->data[cmdlist->last++] = G2D_INTEN_ACF | G2D_INTEN_GCF;
                cmdlist->data[cmdlist->last++] = G2D_DMA_HOLD_CMD;
                cmdlist->data[cmdlist->last++] = G2D_LIST_HOLD;
+       } else {
+               cmdlist->data[cmdlist->last++] = G2D_INTEN;
+               cmdlist->data[cmdlist->last++] = G2D_INTEN_ACF;
        }
 
        /* Check size of cmdlist: last 2 is about G2D_BITBLT_START */
@@ -887,7 +1167,7 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data,
        if (ret < 0)
                goto err_free_event;
 
-       node->map_nr = req->cmd_buf_nr;
+       node->buf_info.map_nr = req->cmd_buf_nr;
        if (req->cmd_buf_nr) {
                struct drm_exynos_g2d_cmd *cmd_buf;
 
index 67e17ce112b69eb5ce795358e1471fd9db2ad841..0e6fe000578c08c78be0df9fa00e2205429e8576 100644 (file)
@@ -164,6 +164,27 @@ out:
        exynos_gem_obj = NULL;
 }
 
+unsigned long exynos_drm_gem_get_size(struct drm_device *dev,
+                                               unsigned int gem_handle,
+                                               struct drm_file *file_priv)
+{
+       struct exynos_drm_gem_obj *exynos_gem_obj;
+       struct drm_gem_object *obj;
+
+       obj = drm_gem_object_lookup(dev, file_priv, gem_handle);
+       if (!obj) {
+               DRM_ERROR("failed to lookup gem object.\n");
+               return 0;
+       }
+
+       exynos_gem_obj = to_exynos_gem_obj(obj);
+
+       drm_gem_object_unreference_unlocked(obj);
+
+       return exynos_gem_obj->buffer->size;
+}
+
+
 struct exynos_drm_gem_obj *exynos_drm_gem_init(struct drm_device *dev,
                                                      unsigned long size)
 {
index 35ebac47dc2bacfec928d54001b6065aa9e75564..468766bee450837eefe19f37db7e7fdcc00133c6 100644 (file)
@@ -130,6 +130,11 @@ int exynos_drm_gem_userptr_ioctl(struct drm_device *dev, void *data,
 int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data,
                                      struct drm_file *file_priv);
 
+/* get buffer size to gem handle. */
+unsigned long exynos_drm_gem_get_size(struct drm_device *dev,
+                                               unsigned int gem_handle,
+                                               struct drm_file *file_priv);
+
 /* initialize gem object. */
 int exynos_drm_gem_init_object(struct drm_gem_object *obj);
 
index 13ccbd4bcfaa8c863f27d24870101c32166ecb47..9504b0cd825a4dc9d4b81c2be674eb0897eb137d 100644 (file)
@@ -117,13 +117,12 @@ static struct edid *vidi_get_edid(struct device *dev,
        }
 
        edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH;
-       edid = kzalloc(edid_len, GFP_KERNEL);
+       edid = kmemdup(ctx->raw_edid, edid_len, GFP_KERNEL);
        if (!edid) {
                DRM_DEBUG_KMS("failed to allocate edid\n");
                return ERR_PTR(-ENOMEM);
        }
 
-       memcpy(edid, ctx->raw_edid, edid_len);
        return edid;
 }
 
@@ -563,12 +562,11 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
                        return -EINVAL;
                }
                edid_len = (1 + raw_edid->extensions) * EDID_LENGTH;
-               ctx->raw_edid = kzalloc(edid_len, GFP_KERNEL);
+               ctx->raw_edid = kmemdup(raw_edid, edid_len, GFP_KERNEL);
                if (!ctx->raw_edid) {
                        DRM_DEBUG_KMS("failed to allocate raw_edid.\n");
                        return -ENOMEM;
                }
-               memcpy(ctx->raw_edid, raw_edid, edid_len);
        } else {
                /*
                 * with connection = 0, free raw_edid
index e919aba29b3dfde038979f5c417966bc8bf147c1..2f4f72f070475a62f77ce15451540962eb011153 100644 (file)
@@ -818,7 +818,7 @@ static void mixer_win_disable(void *ctx, int win)
        mixer_ctx->win_data[win].enabled = false;
 }
 
-int mixer_check_timing(void *ctx, struct fb_videomode *timing)
+static int mixer_check_timing(void *ctx, struct fb_videomode *timing)
 {
        struct mixer_context *mixer_ctx = ctx;
        u32 w, h;
index 0a8eceb7590244af233d153845a91c79e6662420..e9b57893db2b1ebba1348a71e37c845f98c3286b 100644 (file)
@@ -125,6 +125,11 @@ MODULE_PARM_DESC(preliminary_hw_support,
                "Enable Haswell and ValleyView Support. "
                "(default: false)");
 
+int i915_disable_power_well __read_mostly = 0;
+module_param_named(disable_power_well, i915_disable_power_well, int, 0600);
+MODULE_PARM_DESC(disable_power_well,
+                "Disable the power well when possible (default: false)");
+
 static struct drm_driver driver;
 extern int intel_agp_enabled;
 
index e95337c974594d34c936d071975f5040c78754d1..01769e2a99538e9e99cd191b328d7746439d328b 100644 (file)
@@ -1398,6 +1398,7 @@ extern int i915_enable_fbc __read_mostly;
 extern bool i915_enable_hangcheck __read_mostly;
 extern int i915_enable_ppgtt __read_mostly;
 extern unsigned int i915_preliminary_hw_support __read_mostly;
+extern int i915_disable_power_well __read_mostly;
 
 extern int i915_suspend(struct drm_device *dev, pm_message_t state);
 extern int i915_resume(struct drm_device *dev);
index 287b42c9d1a8250e56d8a72d1b527cbb7dc1ad38..b20d50192fcc8f3dda5c7efbe098d1a560e95f71 100644 (file)
@@ -5771,6 +5771,11 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
                num_connectors++;
        }
 
+       if (is_cpu_edp)
+               intel_crtc->cpu_transcoder = TRANSCODER_EDP;
+       else
+               intel_crtc->cpu_transcoder = pipe;
+
        /* We are not sure yet this won't happen. */
        WARN(!HAS_PCH_LPT(dev), "Unexpected PCH type %d\n",
             INTEL_PCH_TYPE(dev));
@@ -5837,11 +5842,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
        int pipe = intel_crtc->pipe;
        int ret;
 
-       if (IS_HASWELL(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))
-               intel_crtc->cpu_transcoder = TRANSCODER_EDP;
-       else
-               intel_crtc->cpu_transcoder = pipe;
-
        drm_vblank_pre_modeset(dev, pipe);
 
        ret = dev_priv->display.crtc_mode_set(crtc, mode, adjusted_mode,
index a3730e0289e5eefa15afb9f04a54c65c817f7886..bee8cb6108a7d44883286ef4b35bb6d7f8713a0f 100644 (file)
@@ -321,9 +321,6 @@ void intel_panel_enable_backlight(struct drm_device *dev,
        if (dev_priv->backlight_level == 0)
                dev_priv->backlight_level = intel_panel_get_max_backlight(dev);
 
-       dev_priv->backlight_enabled = true;
-       intel_panel_actually_set_backlight(dev, dev_priv->backlight_level);
-
        if (INTEL_INFO(dev)->gen >= 4) {
                uint32_t reg, tmp;
 
@@ -359,12 +356,12 @@ void intel_panel_enable_backlight(struct drm_device *dev,
        }
 
 set_level:
-       /* Check the current backlight level and try to set again if it's zero.
-        * On some machines, BLC_PWM_CPU_CTL is cleared to zero automatically
-        * when BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1 are written.
+       /* Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1.
+        * BLC_PWM_CPU_CTL may be cleared to zero automatically when these
+        * registers are set.
         */
-       if (!intel_panel_get_backlight(dev))
-               intel_panel_actually_set_backlight(dev, dev_priv->backlight_level);
+       dev_priv->backlight_enabled = true;
+       intel_panel_actually_set_backlight(dev, dev_priv->backlight_level);
 }
 
 static void intel_panel_init_backlight(struct drm_device *dev)
index a1794c6df1bf1b80917f60e2145c39ae741aa478..adca00783e61b304723d3d05197b53f47b6b33db 100644 (file)
@@ -4079,6 +4079,9 @@ void intel_set_power_well(struct drm_device *dev, bool enable)
        if (!IS_HASWELL(dev))
                return;
 
+       if (!i915_disable_power_well && !enable)
+               return;
+
        tmp = I915_READ(HSW_PWR_WELL_DRIVER);
        is_enabled = tmp & HSW_PWR_WELL_STATE;
        enable_requested = tmp & HSW_PWR_WELL_ENABLE;
index 92e47e5c956426878e0e69d80811831d9b92e483..c4388776f4e470ae527470fb47357c220bbf9624 100644 (file)
 #define USB_VENDOR_ID_MONTEREY         0x0566
 #define USB_DEVICE_ID_GENIUS_KB29E     0x3004
 
+#define USB_VENDOR_ID_MSI              0x1770
+#define USB_DEVICE_ID_MSI_GX680R_LED_PANEL     0xff00
+
 #define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400
 #define USB_DEVICE_ID_N_S_HARMONY      0xc359
 
 #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001                0x3001
 #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008                0x3008
 
+#define USB_VENDOR_ID_REALTEK          0x0bda
+#define USB_DEVICE_ID_REALTEK_READER   0x0152
+
 #define USB_VENDOR_ID_ROCCAT           0x1e7d
 #define USB_DEVICE_ID_ROCCAT_ARVO      0x30d4
 #define USB_DEVICE_ID_ROCCAT_ISKU      0x319c
index 7a1ebb867cf499596e9c4fe5b1a43860b86d4351..82e9211b3ca97cfec8f316d33870f22f6fac0617 100644 (file)
@@ -621,6 +621,7 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
 {
        struct mt_device *td = hid_get_drvdata(hid);
        __s32 quirks = td->mtclass.quirks;
+       struct input_dev *input = field->hidinput->input;
 
        if (hid->claimed & HID_CLAIMED_INPUT) {
                switch (usage->hid) {
@@ -670,13 +671,16 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
                        break;
 
                default:
+                       if (usage->type)
+                               input_event(input, usage->type, usage->code,
+                                               value);
                        return;
                }
 
                if (usage->usage_index + 1 == field->report_count) {
                        /* we only take into account the last report. */
                        if (usage->hid == td->last_slot_field)
-                               mt_complete_slot(td, field->hidinput->input);
+                               mt_complete_slot(td, input);
 
                        if (field->index == td->last_field_index
                                && td->num_received >= td->num_expected)
index e0e6abf1cd3bd9b3cfa3d7cc73a2247c84c31be4..19b8360f2330ddec85856e09605a1ce69e32d880 100644 (file)
@@ -73,6 +73,7 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS },
        { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET },
+       { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GX680R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS },
        { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS },
        { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS },
        { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS },
@@ -80,6 +81,7 @@ static const struct hid_blacklist {
        { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET },
+       { USB_VENDOR_ID_REALTEK, USB_DEVICE_ID_REALTEK_READER, HID_QUIRK_NO_INIT_REPORTS },
        { USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_SIGMATEL, USB_DEVICE_ID_SIGMATEL_STMP3780, HID_QUIRK_NOGET },
        { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
index 120f24646696783791365fb2fe785e1535dbc07c..d1ba6b403b844c227b420459598520f08df798fe 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/of_i2c.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
-#include <linux/fsl/mxs-dma.h>
 
 #define DRIVER_NAME "mxs-i2c"
 
@@ -113,9 +112,7 @@ struct mxs_i2c_dev {
        uint32_t timing1;
 
        /* DMA support components */
-       int                             dma_channel;
        struct dma_chan                 *dmach;
-       struct mxs_dma_data             dma_data;
        uint32_t                        pio_data[2];
        uint32_t                        addr_data;
        struct scatterlist              sg_io[2];
@@ -518,21 +515,6 @@ static const struct i2c_algorithm mxs_i2c_algo = {
        .functionality = mxs_i2c_func,
 };
 
-static bool mxs_i2c_dma_filter(struct dma_chan *chan, void *param)
-{
-       struct mxs_i2c_dev *i2c = param;
-
-       if (!mxs_dma_is_apbx(chan))
-               return false;
-
-       if (chan->chan_id != i2c->dma_channel)
-               return false;
-
-       chan->private = &i2c->dma_data;
-
-       return true;
-}
-
 static void mxs_i2c_derive_timing(struct mxs_i2c_dev *i2c, int speed)
 {
        /* The I2C block clock run at 24MHz */
@@ -577,17 +559,6 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c)
        struct device_node *node = dev->of_node;
        int ret;
 
-       /*
-        * TODO: This is a temporary solution and should be changed
-        * to use generic DMA binding later when the helpers get in.
-        */
-       ret = of_property_read_u32(node, "fsl,i2c-dma-channel",
-                                  &i2c->dma_channel);
-       if (ret) {
-               dev_err(dev, "Failed to get DMA channel!\n");
-               return -ENODEV;
-       }
-
        ret = of_property_read_u32(node, "clock-frequency", &speed);
        if (ret) {
                dev_warn(dev, "No I2C speed selected, using 100kHz\n");
@@ -607,8 +578,7 @@ static int mxs_i2c_probe(struct platform_device *pdev)
        struct pinctrl *pinctrl;
        struct resource *res;
        resource_size_t res_size;
-       int err, irq, dmairq;
-       dma_cap_mask_t mask;
+       int err, irq;
 
        pinctrl = devm_pinctrl_get_select_default(dev);
        if (IS_ERR(pinctrl))
@@ -620,9 +590,8 @@ static int mxs_i2c_probe(struct platform_device *pdev)
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        irq = platform_get_irq(pdev, 0);
-       dmairq = platform_get_irq(pdev, 1);
 
-       if (!res || irq < 0 || dmairq < 0)
+       if (!res || irq < 0)
                return -ENOENT;
 
        res_size = resource_size(res);
@@ -648,10 +617,7 @@ static int mxs_i2c_probe(struct platform_device *pdev)
        }
 
        /* Setup the DMA */
-       dma_cap_zero(mask);
-       dma_cap_set(DMA_SLAVE, mask);
-       i2c->dma_data.chan_irq = dmairq;
-       i2c->dmach = dma_request_channel(mask, mxs_i2c_dma_filter, i2c);
+       i2c->dmach = dma_request_slave_channel(dev, "rx-tx");
        if (!i2c->dmach) {
                dev_err(dev, "Failed to request dma\n");
                return -ENODEV;
index 17ba4f8bc12d0b19ec7d380dc6677796d79f12de..70b1808a08f4d12bf9d1668cb5bae06d1cd2e202 100644 (file)
@@ -186,8 +186,10 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq,
        wq->rq.queue = dma_alloc_coherent(&(rdev->lldi.pdev->dev),
                                          wq->rq.memsize, &(wq->rq.dma_addr),
                                          GFP_KERNEL);
-       if (!wq->rq.queue)
+       if (!wq->rq.queue) {
+               ret = -ENOMEM;
                goto free_sq;
+       }
        PDBG("%s sq base va 0x%p pa 0x%llx rq base va 0x%p pa 0x%llx\n",
                __func__, wq->sq.queue,
                (unsigned long long)virt_to_phys(wq->sq.queue),
index 439c35d4a669978aba8820151f2f6c98f5a47558..ea93870266eb7fda30ddf502b5d233fb1116423b 100644 (file)
@@ -620,7 +620,7 @@ void ipath_ib_rcv(struct ipath_ibdev *dev, void *rhdr, void *data,
                goto bail;
        }
 
-       opcode = be32_to_cpu(ohdr->bth[0]) >> 24;
+       opcode = (be32_to_cpu(ohdr->bth[0]) >> 24) & 0x7f;
        dev->opstats[opcode].n_bytes += tlen;
        dev->opstats[opcode].n_packets++;
 
index 8349f9c5064c042d568cf56619b76dd391410402..1e603a375069022bfed295f071f8c729b4ad826b 100644 (file)
@@ -1,7 +1,7 @@
 config INFINIBAND_QIB
-       tristate "QLogic PCIe HCA support"
+       tristate "Intel PCIe HCA support"
        depends on 64BIT
        ---help---
-       This is a low-level driver for QLogic PCIe QLE InfiniBand host
-       channel adapters.  This driver does not support the QLogic
+       This is a low-level driver for Intel PCIe QLE InfiniBand host
+       channel adapters.  This driver does not support the Intel
        HyperTransport card (model QHT7140).
index 5423edcab51f4404905e47674957cb32e5f33b9f..216092477dfcf7eb4a51187ffe825110c5eb3286 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2013 Intel Corporation. All rights reserved.
  * Copyright (c) 2006, 2007, 2008, 2009 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
@@ -63,8 +64,8 @@ MODULE_PARM_DESC(compat_ddr_negotiate,
                 "Attempt pre-IBTA 1.2 DDR speed negotiation");
 
 MODULE_LICENSE("Dual BSD/GPL");
-MODULE_AUTHOR("QLogic <support@qlogic.com>");
-MODULE_DESCRIPTION("QLogic IB driver");
+MODULE_AUTHOR("Intel <ibsupport@intel.com>");
+MODULE_DESCRIPTION("Intel IB driver");
 MODULE_VERSION(QIB_DRIVER_VERSION);
 
 /*
index a099ac171e226f1073f4a70ccb680e669b2ff048..0232ae56b1fa2b185e1a551e074e5d256f15c087 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2013 Intel Corporation. All rights reserved.
  * Copyright (c) 2006, 2007, 2008, 2009, 2010 QLogic Corporation.
  * All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
@@ -51,7 +52,7 @@ static u32 qib_6120_iblink_state(u64);
 
 /*
  * This file contains all the chip-specific register information and
- * access functions for the QLogic QLogic_IB PCI-Express chip.
+ * access functions for the Intel Intel_IB PCI-Express chip.
  *
  */
 
index 50e33aa0b4e39628c5de95e314d57de68bbc4be5..173f805790da4522f3f4a8881b8b2df5883b9b4b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2012, 2013 Intel Corporation.  All rights reserved.
  * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
@@ -1138,7 +1138,7 @@ void qib_disable_after_error(struct qib_devdata *dd)
 static void qib_remove_one(struct pci_dev *);
 static int qib_init_one(struct pci_dev *, const struct pci_device_id *);
 
-#define DRIVER_LOAD_MSG "QLogic " QIB_DRV_NAME " loaded: "
+#define DRIVER_LOAD_MSG "Intel " QIB_DRV_NAME " loaded: "
 #define PFX QIB_DRV_NAME ": "
 
 static DEFINE_PCI_DEVICE_TABLE(qib_pci_tbl) = {
@@ -1355,7 +1355,7 @@ static int qib_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                dd = qib_init_iba6120_funcs(pdev, ent);
 #else
                qib_early_err(&pdev->dev,
-                       "QLogic PCIE device 0x%x cannot work if CONFIG_PCI_MSI is not enabled\n",
+                       "Intel PCIE device 0x%x cannot work if CONFIG_PCI_MSI is not enabled\n",
                        ent->device);
                dd = ERR_PTR(-ENODEV);
 #endif
@@ -1371,7 +1371,7 @@ static int qib_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        default:
                qib_early_err(&pdev->dev,
-                       "Failing on unknown QLogic deviceid 0x%x\n",
+                       "Failing on unknown Intel deviceid 0x%x\n",
                        ent->device);
                ret = -ENODEV;
        }
index 50a8a0d4fe676f5467c677d66a4985170900059d..08a6c6d39e5666228cd842b1597fc5d9dcf48052 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Intel Corporation. All rights reserved.
+ * Copyright (c) 2013 Intel Corporation. All rights reserved.
  * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
  * Copyright (c) 2003, 2004, 2005, 2006 PathScale, Inc. All rights reserved.
  *
@@ -44,7 +44,7 @@
 #include "qib.h"
 #include "qib_7220.h"
 
-#define SD7220_FW_NAME "qlogic/sd7220.fw"
+#define SD7220_FW_NAME "intel/sd7220.fw"
 MODULE_FIRMWARE(SD7220_FW_NAME);
 
 /*
index ba51a4715a1dcdd5963261d84497dc1e6974c070..7c0ab16a2fe230fc31b44fd43b04f3e92d2a26b8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Intel Corporation.  All rights reserved.
+ * Copyright (c) 2012, 2013 Intel Corporation.  All rights reserved.
  * Copyright (c) 2006 - 2012 QLogic Corporation. All rights reserved.
  * Copyright (c) 2005, 2006 PathScale, Inc. All rights reserved.
  *
@@ -2224,7 +2224,7 @@ int qib_register_ib_device(struct qib_devdata *dd)
        ibdev->dma_ops = &qib_dma_mapping_ops;
 
        snprintf(ibdev->node_desc, sizeof(ibdev->node_desc),
-                "QLogic Infiniband HCA %s", init_utsname()->nodename);
+                "Intel Infiniband HCA %s", init_utsname()->nodename);
 
        ret = ib_register_device(ibdev, qib_create_port_files);
        if (ret)
index 67b0c1d23678d26565981cf9815993027c0a1b5e..1ef880de3a41d97fe328951069f3b6c30066daf1 100644 (file)
@@ -758,9 +758,13 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_
                if (++priv->tx_outstanding == ipoib_sendq_size) {
                        ipoib_dbg(priv, "TX ring 0x%x full, stopping kernel net queue\n",
                                  tx->qp->qp_num);
-                       if (ib_req_notify_cq(priv->send_cq, IB_CQ_NEXT_COMP))
-                               ipoib_warn(priv, "request notify on send CQ failed\n");
                        netif_stop_queue(dev);
+                       rc = ib_req_notify_cq(priv->send_cq,
+                               IB_CQ_NEXT_COMP | IB_CQ_REPORT_MISSED_EVENTS);
+                       if (rc < 0)
+                               ipoib_warn(priv, "request notify on send CQ failed\n");
+                       else if (rc)
+                               ipoib_send_comp_handler(priv->send_cq, dev);
                }
        }
 }
index 5c514d0711d1b57669b6acee551400bf88d44265..c332fb98480d28e42739e9b674b7b99ce8be427d 100644 (file)
@@ -130,7 +130,7 @@ config IRQ_REMAP
 # OMAP IOMMU support
 config OMAP_IOMMU
        bool "OMAP IOMMU Support"
-       depends on ARCH_OMAP
+       depends on ARCH_OMAP2PLUS
        select IOMMU_API
 
 config OMAP_IOVMM
index 98f555dafb55c8edc32393919ee48140d024b184..b287ca33833df792350baad6f82fefbe1494e038 100644 (file)
@@ -2466,18 +2466,16 @@ static int device_change_notifier(struct notifier_block *nb,
 
                /* allocate a protection domain if a device is added */
                dma_domain = find_protection_domain(devid);
-               if (dma_domain)
-                       goto out;
-               dma_domain = dma_ops_domain_alloc();
-               if (!dma_domain)
-                       goto out;
-               dma_domain->target_dev = devid;
-
-               spin_lock_irqsave(&iommu_pd_list_lock, flags);
-               list_add_tail(&dma_domain->list, &iommu_pd_list);
-               spin_unlock_irqrestore(&iommu_pd_list_lock, flags);
-
-               dev_data = get_dev_data(dev);
+               if (!dma_domain) {
+                       dma_domain = dma_ops_domain_alloc();
+                       if (!dma_domain)
+                               goto out;
+                       dma_domain->target_dev = devid;
+
+                       spin_lock_irqsave(&iommu_pd_list_lock, flags);
+                       list_add_tail(&dma_domain->list, &iommu_pd_list);
+                       spin_unlock_irqrestore(&iommu_pd_list_lock, flags);
+               }
 
                dev->archdata.dma_ops = &amd_iommu_dma_ops;
 
index b6ecddb63cd0fc9397ccf24e0951dbf13ea9a719..e3c2d74b7684596790fd0293461dc74922a850ba 100644 (file)
@@ -980,7 +980,7 @@ static void __init free_iommu_all(void)
  *     BIOS should disable L2B micellaneous clock gating by setting
  *     L2_L2B_CK_GATE_CONTROL[CKGateL2BMiscDisable](D0F2xF4_x90[2]) = 1b
  */
-static void __init amd_iommu_erratum_746_workaround(struct amd_iommu *iommu)
+static void amd_iommu_erratum_746_workaround(struct amd_iommu *iommu)
 {
        u32 value;
 
index d56f8c17c5fe4dcc2e4db23085d4914b977c0fd0..7c11ff368d07f88dc357dd3f6e22c9fbe2ed6cc1 100644 (file)
@@ -2,7 +2,6 @@
 #include <linux/cpumask.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <linux/cpumask.h>
 #include <linux/errno.h>
 #include <linux/msi.h>
 #include <linux/irq.h>
index 98e3b87bdf1b48761df4320a9c588af26f38bb2c..9d8f4f1c6e390d1b96b593a2633284a01a1dbfb4 100644 (file)
@@ -2,6 +2,7 @@ obj-$(CONFIG_IRQCHIP)                   += irqchip.o
 
 obj-$(CONFIG_ARCH_BCM2835)             += irq-bcm2835.o
 obj-$(CONFIG_ARCH_EXYNOS)              += exynos-combiner.o
+obj-$(CONFIG_ARCH_MXS)                 += irq-mxs.o
 obj-$(CONFIG_METAG)                    += irq-metag-ext.o
 obj-$(CONFIG_METAG_PERFCOUNTER_IRQS)   += irq-metag.o
 obj-$(CONFIG_ARCH_SUNXI)               += irq-sunxi.o
diff --git a/drivers/irqchip/irq-mxs.c b/drivers/irqchip/irq-mxs.c
new file mode 100644 (file)
index 0000000..29889bb
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/stmp_device.h>
+#include <asm/exception.h>
+
+#include "irqchip.h"
+
+#define HW_ICOLL_VECTOR                                0x0000
+#define HW_ICOLL_LEVELACK                      0x0010
+#define HW_ICOLL_CTRL                          0x0020
+#define HW_ICOLL_STAT_OFFSET                   0x0070
+#define HW_ICOLL_INTERRUPTn_SET(n)             (0x0124 + (n) * 0x10)
+#define HW_ICOLL_INTERRUPTn_CLR(n)             (0x0128 + (n) * 0x10)
+#define BM_ICOLL_INTERRUPTn_ENABLE             0x00000004
+#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0  0x1
+
+#define ICOLL_NUM_IRQS         128
+
+static void __iomem *icoll_base;
+static struct irq_domain *icoll_domain;
+
+static void icoll_ack_irq(struct irq_data *d)
+{
+       /*
+        * The Interrupt Collector is able to prioritize irqs.
+        * Currently only level 0 is used. So acking can use
+        * BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 unconditionally.
+        */
+       __raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0,
+                       icoll_base + HW_ICOLL_LEVELACK);
+}
+
+static void icoll_mask_irq(struct irq_data *d)
+{
+       __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
+                       icoll_base + HW_ICOLL_INTERRUPTn_CLR(d->hwirq));
+}
+
+static void icoll_unmask_irq(struct irq_data *d)
+{
+       __raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
+                       icoll_base + HW_ICOLL_INTERRUPTn_SET(d->hwirq));
+}
+
+static struct irq_chip mxs_icoll_chip = {
+       .irq_ack = icoll_ack_irq,
+       .irq_mask = icoll_mask_irq,
+       .irq_unmask = icoll_unmask_irq,
+};
+
+asmlinkage void __exception_irq_entry icoll_handle_irq(struct pt_regs *regs)
+{
+       u32 irqnr;
+
+       do {
+               irqnr = __raw_readl(icoll_base + HW_ICOLL_STAT_OFFSET);
+               if (irqnr != 0x7f) {
+                       __raw_writel(irqnr, icoll_base + HW_ICOLL_VECTOR);
+                       irqnr = irq_find_mapping(icoll_domain, irqnr);
+                       handle_IRQ(irqnr, regs);
+                       continue;
+               }
+               break;
+       } while (1);
+}
+
+static int icoll_irq_domain_map(struct irq_domain *d, unsigned int virq,
+                               irq_hw_number_t hw)
+{
+       irq_set_chip_and_handler(virq, &mxs_icoll_chip, handle_level_irq);
+       set_irq_flags(virq, IRQF_VALID);
+
+       return 0;
+}
+
+static struct irq_domain_ops icoll_irq_domain_ops = {
+       .map = icoll_irq_domain_map,
+       .xlate = irq_domain_xlate_onecell,
+};
+
+static void __init icoll_of_init(struct device_node *np,
+                         struct device_node *interrupt_parent)
+{
+       icoll_base = of_iomap(np, 0);
+       WARN_ON(!icoll_base);
+
+       /*
+        * Interrupt Collector reset, which initializes the priority
+        * for each irq to level 0.
+        */
+       stmp_reset_block(icoll_base + HW_ICOLL_CTRL);
+
+       icoll_domain = irq_domain_add_linear(np, ICOLL_NUM_IRQS,
+                                            &icoll_irq_domain_ops, NULL);
+       WARN_ON(!icoll_domain);
+}
+IRQCHIP_DECLARE(mxs, "fsl,icoll", icoll_of_init);
index d4e7567b367c04d25b9a21ba4c50d0db314596aa..0b899cb6cda1904b6f07cdb924f94be3d76ccb56 100644 (file)
@@ -724,7 +724,7 @@ static int m5mols_s_stream(struct v4l2_subdev *sd, int enable)
        if (enable) {
                if (is_code(code, M5MOLS_RESTYPE_MONITOR))
                        ret = m5mols_start_monitor(info);
-               if (is_code(code, M5MOLS_RESTYPE_CAPTURE))
+               else if (is_code(code, M5MOLS_RESTYPE_CAPTURE))
                        ret = m5mols_start_capture(info);
                else
                        ret = -EINVAL;
index ccd18e4ee7892e62034a0d9b1e351107fb787749..54579e4c740b4da7f8590ad345145553d63d8062 100644 (file)
@@ -250,17 +250,19 @@ static u8 SRAM_Table[][60] =
    vdelay      start of active video in 2 * field lines relative to
                trailing edge of /VRESET pulse (VDELAY register).
    sheight     height of active video in 2 * field lines.
+   extraheight Added to sheight for cropcap.bounds.height only
    videostart0 ITU-R frame line number of the line corresponding
                to vdelay in the first field. */
 #define CROPCAP(minhdelayx1, hdelayx1, swidth, totalwidth, sqwidth,     \
-               vdelay, sheight, videostart0)                            \
+               vdelay, sheight, extraheight, videostart0)               \
        .cropcap.bounds.left = minhdelayx1,                              \
        /* * 2 because vertically we count field lines times two, */     \
        /* e.g. 23 * 2 to 23 * 2 + 576 in PAL-BGHI defrect. */           \
        .cropcap.bounds.top = (videostart0) * 2 - (vdelay) + MIN_VDELAY, \
        /* 4 is a safety margin at the end of the line. */               \
        .cropcap.bounds.width = (totalwidth) - (minhdelayx1) - 4,        \
-       .cropcap.bounds.height = (sheight) + (vdelay) - MIN_VDELAY,      \
+       .cropcap.bounds.height = (sheight) + (extraheight) + (vdelay) -  \
+                                MIN_VDELAY,                             \
        .cropcap.defrect.left = hdelayx1,                                \
        .cropcap.defrect.top = (videostart0) * 2,                        \
        .cropcap.defrect.width = swidth,                                 \
@@ -301,9 +303,10 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
                        /* totalwidth */ 1135,
                        /* sqwidth */ 944,
                        /* vdelay */ 0x20,
-               /* bt878 (and bt848?) can capture another
-                  line below active video. */
-                       /* sheight */ (576 + 2) + 0x20 - 2,
+                       /* sheight */ 576,
+                       /* bt878 (and bt848?) can capture another
+                          line below active video. */
+                       /* extraheight */ 2,
                        /* videostart0 */ 23)
        },{
                .v4l2_id        = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
@@ -330,6 +333,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
                        /* sqwidth */ 780,
                        /* vdelay */ 0x1a,
                        /* sheight */ 480,
+                       /* extraheight */ 0,
                        /* videostart0 */ 23)
        },{
                .v4l2_id        = V4L2_STD_SECAM,
@@ -355,6 +359,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
                        /* sqwidth */ 944,
                        /* vdelay */ 0x20,
                        /* sheight */ 576,
+                       /* extraheight */ 0,
                        /* videostart0 */ 23)
        },{
                .v4l2_id        = V4L2_STD_PAL_Nc,
@@ -380,6 +385,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
                        /* sqwidth */ 780,
                        /* vdelay */ 0x1a,
                        /* sheight */ 576,
+                       /* extraheight */ 0,
                        /* videostart0 */ 23)
        },{
                .v4l2_id        = V4L2_STD_PAL_M,
@@ -405,6 +411,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
                        /* sqwidth */ 780,
                        /* vdelay */ 0x1a,
                        /* sheight */ 480,
+                       /* extraheight */ 0,
                        /* videostart0 */ 23)
        },{
                .v4l2_id        = V4L2_STD_PAL_N,
@@ -430,6 +437,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
                        /* sqwidth */ 944,
                        /* vdelay */ 0x20,
                        /* sheight */ 576,
+                       /* extraheight */ 0,
                        /* videostart0 */ 23)
        },{
                .v4l2_id        = V4L2_STD_NTSC_M_JP,
@@ -455,6 +463,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
                        /* sqwidth */ 780,
                        /* vdelay */ 0x16,
                        /* sheight */ 480,
+                       /* extraheight */ 0,
                        /* videostart0 */ 23)
        },{
                /* that one hopefully works with the strange timing
@@ -484,6 +493,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = {
                        /* sqwidth */ 944,
                        /* vdelay */ 0x1a,
                        /* sheight */ 480,
+                       /* extraheight */ 0,
                        /* videostart0 */ 23)
        }
 };
index 82d9f6ac12f3a271481e106df7f75017b3f962c1..33b5ffc8d66dfe136e2cd0df4129963b6c60ad79 100644 (file)
@@ -1054,16 +1054,18 @@ static int gsc_m2m_suspend(struct gsc_dev *gsc)
 
 static int gsc_m2m_resume(struct gsc_dev *gsc)
 {
+       struct gsc_ctx *ctx;
        unsigned long flags;
 
        spin_lock_irqsave(&gsc->slock, flags);
        /* Clear for full H/W setup in first run after resume */
+       ctx = gsc->m2m.ctx;
        gsc->m2m.ctx = NULL;
        spin_unlock_irqrestore(&gsc->slock, flags);
 
        if (test_and_clear_bit(ST_M2M_SUSPENDED, &gsc->state))
-               gsc_m2m_job_finish(gsc->m2m.ctx,
-                                   VB2_BUF_STATE_ERROR);
+               gsc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR);
+
        return 0;
 }
 
@@ -1204,7 +1206,7 @@ static int gsc_resume(struct device *dev)
        /* Do not resume if the device was idle before system suspend */
        spin_lock_irqsave(&gsc->slock, flags);
        if (!test_and_clear_bit(ST_SUSPEND, &gsc->state) ||
-           !gsc_m2m_active(gsc)) {
+           !gsc_m2m_opened(gsc)) {
                spin_unlock_irqrestore(&gsc->slock, flags);
                return 0;
        }
index e3916bde45cf13a4cb92b8bcd83715b1c1a07ce0..0f513dd19f86de105f36913a6d5e6e59839fd91a 100644 (file)
@@ -850,16 +850,18 @@ static int fimc_m2m_suspend(struct fimc_dev *fimc)
 
 static int fimc_m2m_resume(struct fimc_dev *fimc)
 {
+       struct fimc_ctx *ctx;
        unsigned long flags;
 
        spin_lock_irqsave(&fimc->slock, flags);
        /* Clear for full H/W setup in first run after resume */
+       ctx = fimc->m2m.ctx;
        fimc->m2m.ctx = NULL;
        spin_unlock_irqrestore(&fimc->slock, flags);
 
        if (test_and_clear_bit(ST_M2M_SUSPENDED, &fimc->state))
-               fimc_m2m_job_finish(fimc->m2m.ctx,
-                                   VB2_BUF_STATE_ERROR);
+               fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR);
+
        return 0;
 }
 
index f0af0754a7b46a04cee5f41552ede4d8bc2e96ed..ac9663ce2a4927a0a3249bde33107fb1a17a9783 100644 (file)
@@ -128,10 +128,10 @@ static const u32 src_pixfmt_map[8][3] = {
 void flite_hw_set_source_format(struct fimc_lite *dev, struct flite_frame *f)
 {
        enum v4l2_mbus_pixelcode pixelcode = dev->fmt->mbus_code;
-       unsigned int i = ARRAY_SIZE(src_pixfmt_map);
+       int i = ARRAY_SIZE(src_pixfmt_map);
        u32 cfg;
 
-       while (i-- >= 0) {
+       while (--i >= 0) {
                if (src_pixfmt_map[i][0] == pixelcode)
                        break;
        }
@@ -224,9 +224,9 @@ static void flite_hw_set_out_order(struct fimc_lite *dev, struct flite_frame *f)
                { V4L2_MBUS_FMT_VYUY8_2X8, FLITE_REG_CIODMAFMT_CRYCBY },
        };
        u32 cfg = readl(dev->regs + FLITE_REG_CIODMAFMT);
-       unsigned int i = ARRAY_SIZE(pixcode);
+       int i = ARRAY_SIZE(pixcode);
 
-       while (i-- >= 0)
+       while (--i >= 0)
                if (pixcode[i][0] == dev->fmt->mbus_code)
                        break;
        cfg &= ~FLITE_REG_CIODMAFMT_YCBCR_ORDER_MASK;
index bfc4206935c85a93fa75b6893e3afdcc8efb7c92..bbc35de7db278fe053c6de4d02be7fc7c40d4321 100644 (file)
@@ -1408,6 +1408,7 @@ static const struct v4l2_ctrl_config fimc_lite_ctrl = {
        .id     = V4L2_CTRL_CLASS_USER | 0x1001,
        .type   = V4L2_CTRL_TYPE_BOOLEAN,
        .name   = "Test Pattern 640x480",
+       .step   = 1,
 };
 
 static int fimc_lite_create_capture_subdev(struct fimc_lite *fimc)
index a17fcb2d5d413ca66ed9a16a31a34045a83a0d6b..cd38d708ab584ef4487d4d1960aabe06d6b7138b 100644 (file)
@@ -827,7 +827,7 @@ static int fimc_md_link_notify(struct media_pad *source,
        struct fimc_pipeline *pipeline;
        struct v4l2_subdev *sd;
        struct mutex *lock;
-       int ret = 0;
+       int i, ret = 0;
        int ref_count;
 
        if (media_entity_type(sink->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
@@ -854,29 +854,28 @@ static int fimc_md_link_notify(struct media_pad *source,
                return 0;
        }
 
+       mutex_lock(lock);
+       ref_count = fimc ? fimc->vid_cap.refcnt : fimc_lite->ref_count;
+
        if (!(flags & MEDIA_LNK_FL_ENABLED)) {
-               int i;
-               mutex_lock(lock);
-               ret = __fimc_pipeline_close(pipeline);
+               if (ref_count > 0) {
+                       ret = __fimc_pipeline_close(pipeline);
+                       if (!ret && fimc)
+                               fimc_ctrls_delete(fimc->vid_cap.ctx);
+               }
                for (i = 0; i < IDX_MAX; i++)
                        pipeline->subdevs[i] = NULL;
-               if (fimc)
-                       fimc_ctrls_delete(fimc->vid_cap.ctx);
-               mutex_unlock(lock);
-               return ret;
+       } else if (ref_count > 0) {
+               /*
+                * Link activation. Enable power of pipeline elements only if
+                * the pipeline is already in use, i.e. its video node is open.
+                * Recreate the controls destroyed during the link deactivation.
+                */
+               ret = __fimc_pipeline_open(pipeline,
+                                          source->entity, true);
+               if (!ret && fimc)
+                       ret = fimc_capture_ctrls_create(fimc);
        }
-       /*
-        * Link activation. Enable power of pipeline elements only if the
-        * pipeline is already in use, i.e. its video node is opened.
-        * Recreate the controls destroyed during the link deactivation.
-        */
-       mutex_lock(lock);
-
-       ref_count = fimc ? fimc->vid_cap.refcnt : fimc_lite->ref_count;
-       if (ref_count > 0)
-               ret = __fimc_pipeline_open(pipeline, source->entity, true);
-       if (!ret && fimc)
-               ret = fimc_capture_ctrls_create(fimc);
 
        mutex_unlock(lock);
        return ret ? -EPIPE : ret;
index e84703c314ce0d50a9861cf674244b9a3342615f..1cb6d57987c6f2dd06e0ff8d8965d0c02179039e 100644 (file)
@@ -276,7 +276,7 @@ static void s5p_mfc_handle_frame_new(struct s5p_mfc_ctx *ctx, unsigned int err)
        unsigned int frame_type;
 
        dspl_y_addr = s5p_mfc_hw_call(dev->mfc_ops, get_dspl_y_adr, dev);
-       frame_type = s5p_mfc_hw_call(dev->mfc_ops, get_dec_frame_type, dev);
+       frame_type = s5p_mfc_hw_call(dev->mfc_ops, get_disp_frame_type, ctx);
 
        /* If frame is same as previous then skip and do not dequeue */
        if (frame_type == S5P_FIMV_DECODE_FRAME_SKIPPED) {
index 2356fd52a169abf2680dd22ebb9e17453c4ac52d..4f6b553c4b2de90f6686f2da38cf5221f68c352d 100644 (file)
@@ -232,6 +232,7 @@ static struct mfc_control controls[] = {
                .minimum = 0,
                .maximum = 1,
                .default_value = 0,
+               .step = 1,
                .menu_skip_mask = 0,
        },
        {
index 19f3563c61da651673b5ea7884b43b8e4c2145e1..5a79c333d45e66308e5b0f75cbc91ed9d60ce329 100644 (file)
@@ -291,7 +291,7 @@ config IR_TTUSBIR
 
 config IR_RX51
        tristate "Nokia N900 IR transmitter diode"
-       depends on OMAP_DM_TIMER && LIRC && !ARCH_MULTIPLATFORM
+       depends on OMAP_DM_TIMER && ARCH_OMAP2PLUS && LIRC && !ARCH_MULTIPLATFORM
        ---help---
           Say Y or M here if you want to enable support for the IR
           transmitter diode built in the Nokia N900 (RX51) device.
index a9d355230e8eb2efb52fb3fbdff2a5b8297a7a73..768aaf62d5dc300a7b2d7e150265e27035ef15cb 100644 (file)
@@ -10,7 +10,7 @@ ifeq ($(CONFIG_COMPAT),y)
   videodev-objs += v4l2-compat-ioctl32.o
 endif
 
-obj-$(CONFIG_VIDEO_DEV) += videodev.o
+obj-$(CONFIG_VIDEO_V4L2) += videodev.o
 obj-$(CONFIG_VIDEO_V4L2_INT_DEVICE) += v4l2-int-device.o
 obj-$(CONFIG_VIDEO_V4L2) += v4l2-common.o
 
index 45ea7185c003d5b5deee66ad1a274c23212ed77f..642c6223fa6cd177f22c66e40b3d3531a6d841a4 100644 (file)
@@ -151,6 +151,20 @@ static void mei_me_intr_disable(struct mei_device *dev)
        mei_hcsr_set(hw, hcsr);
 }
 
+/**
+ * mei_me_hw_reset_release - release device from the reset
+ *
+ * @dev: the device structure
+ */
+static void mei_me_hw_reset_release(struct mei_device *dev)
+{
+       struct mei_me_hw *hw = to_me_hw(dev);
+       u32 hcsr = mei_hcsr_read(hw);
+
+       hcsr |= H_IG;
+       hcsr &= ~H_RST;
+       mei_hcsr_set(hw, hcsr);
+}
 /**
  * mei_me_hw_reset - resets fw via mei csr register.
  *
@@ -169,18 +183,14 @@ static void mei_me_hw_reset(struct mei_device *dev, bool intr_enable)
        if (intr_enable)
                hcsr |= H_IE;
        else
-               hcsr &= ~H_IE;
-
-       mei_hcsr_set(hw, hcsr);
-
-       hcsr = mei_hcsr_read(hw) | H_IG;
-       hcsr &= ~H_RST;
+               hcsr |= ~H_IE;
 
        mei_hcsr_set(hw, hcsr);
 
-       hcsr = mei_hcsr_read(hw);
+       if (dev->dev_state == MEI_DEV_POWER_DOWN)
+               mei_me_hw_reset_release(dev);
 
-       dev_dbg(&dev->pdev->dev, "current HCSR = 0x%08x.\n", hcsr);
+       dev_dbg(&dev->pdev->dev, "current HCSR = 0x%08x.\n", mei_hcsr_read(hw));
 }
 
 /**
@@ -466,7 +476,8 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id)
                        mutex_unlock(&dev->device_lock);
                        return IRQ_HANDLED;
                } else {
-                       dev_dbg(&dev->pdev->dev, "FW not ready.\n");
+                       dev_dbg(&dev->pdev->dev, "Reset Completed.\n");
+                       mei_me_hw_reset_release(dev);
                        mutex_unlock(&dev->device_lock);
                        return IRQ_HANDLED;
                }
index 6ec530168afbbe2268da06d1c2508fd044cb943d..356179991a2e9ff87f7e34efb452b5ad4a547aa6 100644 (file)
@@ -183,6 +183,24 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled)
        mei_cl_all_write_clear(dev);
 }
 
+void mei_stop(struct mei_device *dev)
+{
+       dev_dbg(&dev->pdev->dev, "stopping the device.\n");
+
+       mutex_lock(&dev->device_lock);
+
+       cancel_delayed_work(&dev->timer_work);
+
+       mei_wd_stop(dev);
+
+       dev->dev_state = MEI_DEV_POWER_DOWN;
+       mei_reset(dev, 0);
+
+       mutex_unlock(&dev->device_lock);
+
+       flush_scheduled_work();
+}
+
 
 
 
index cb80166161f0f82ad725e1073baf1bc607fcc6bf..97873812e33b28c06e85dc000869ef48f1312471 100644 (file)
@@ -381,6 +381,7 @@ static inline unsigned long mei_secs_to_jiffies(unsigned long sec)
 void mei_device_init(struct mei_device *dev);
 void mei_reset(struct mei_device *dev, int interrupts);
 int mei_hw_init(struct mei_device *dev);
+void mei_stop(struct mei_device *dev);
 
 /*
  *  MEI interrupt functions prototype
index b40ec0601ab0bcc7325f0dfedb8ebefccdd896ec..b8b5c9c3ad0375bab4605b038bcbda60ff970b4f 100644 (file)
@@ -247,44 +247,14 @@ static void mei_remove(struct pci_dev *pdev)
 
        hw = to_me_hw(dev);
 
-       mutex_lock(&dev->device_lock);
-
-       cancel_delayed_work(&dev->timer_work);
 
-       mei_wd_stop(dev);
+       dev_err(&pdev->dev, "stop\n");
+       mei_stop(dev);
 
        mei_pdev = NULL;
 
-       if (dev->iamthif_cl.state == MEI_FILE_CONNECTED) {
-               dev->iamthif_cl.state = MEI_FILE_DISCONNECTING;
-               mei_cl_disconnect(&dev->iamthif_cl);
-       }
-       if (dev->wd_cl.state == MEI_FILE_CONNECTED) {
-               dev->wd_cl.state = MEI_FILE_DISCONNECTING;
-               mei_cl_disconnect(&dev->wd_cl);
-       }
-
-       /* Unregistering watchdog device */
        mei_watchdog_unregister(dev);
 
-       /* remove entry if already in list */
-       dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n");
-
-       if (dev->open_handle_count > 0)
-               dev->open_handle_count--;
-       mei_cl_unlink(&dev->wd_cl);
-
-       if (dev->open_handle_count > 0)
-               dev->open_handle_count--;
-       mei_cl_unlink(&dev->iamthif_cl);
-
-       dev->iamthif_current_cb = NULL;
-       dev->me_clients_num = 0;
-
-       mutex_unlock(&dev->device_lock);
-
-       flush_scheduled_work();
-
        /* disable interrupts */
        mei_disable_interrupts(dev);
 
@@ -308,28 +278,20 @@ static int mei_pci_suspend(struct device *device)
 {
        struct pci_dev *pdev = to_pci_dev(device);
        struct mei_device *dev = pci_get_drvdata(pdev);
-       int err;
 
        if (!dev)
                return -ENODEV;
-       mutex_lock(&dev->device_lock);
 
-       cancel_delayed_work(&dev->timer_work);
+       dev_err(&pdev->dev, "suspend\n");
 
-       /* Stop watchdog if exists */
-       err = mei_wd_stop(dev);
-       /* Set new mei state */
-       if (dev->dev_state == MEI_DEV_ENABLED ||
-           dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET) {
-               dev->dev_state = MEI_DEV_POWER_DOWN;
-               mei_reset(dev, 0);
-       }
-       mutex_unlock(&dev->device_lock);
+       mei_stop(dev);
+
+       mei_disable_interrupts(dev);
 
        free_irq(pdev->irq, dev);
        pci_disable_msi(pdev);
 
-       return err;
+       return 0;
 }
 
 static int mei_pci_resume(struct device *device)
index ed5c433cd4936f8b52c98352bbf21ead11a67ae8..f3cdd904fe4d6e1ae5c48288858d793dbc0af22c 100644 (file)
@@ -42,9 +42,11 @@ struct datagram_entry {
 
 struct delayed_datagram_info {
        struct datagram_entry *entry;
-       struct vmci_datagram msg;
        struct work_struct work;
        bool in_dg_host_queue;
+       /* msg and msg_payload must be together. */
+       struct vmci_datagram msg;
+       u8 msg_payload[];
 };
 
 /* Number of in-flight host->host datagrams */
index 4efe3021b21766cf0c247cb1b8217e6d2c68267a..4fdc71113e6d1747fa6b762d33db50daf07f55f5 100644 (file)
@@ -548,22 +548,6 @@ static const struct mmc_host_ops mxs_mmc_ops = {
        .enable_sdio_irq = mxs_mmc_enable_sdio_irq,
 };
 
-static bool mxs_mmc_dma_filter(struct dma_chan *chan, void *param)
-{
-       struct mxs_mmc_host *host = param;
-       struct mxs_ssp *ssp = &host->ssp;
-
-       if (!mxs_dma_is_apbh(chan))
-               return false;
-
-       if (chan->chan_id != ssp->dma_channel)
-               return false;
-
-       chan->private = &ssp->dma_data;
-
-       return true;
-}
-
 static struct platform_device_id mxs_ssp_ids[] = {
        {
                .name = "imx23-mmc",
@@ -591,20 +575,17 @@ static int mxs_mmc_probe(struct platform_device *pdev)
        struct device_node *np = pdev->dev.of_node;
        struct mxs_mmc_host *host;
        struct mmc_host *mmc;
-       struct resource *iores, *dmares;
+       struct resource *iores;
        struct pinctrl *pinctrl;
-       int ret = 0, irq_err, irq_dma;
-       dma_cap_mask_t mask;
+       int ret = 0, irq_err;
        struct regulator *reg_vmmc;
        enum of_gpio_flags flags;
        struct mxs_ssp *ssp;
        u32 bus_width = 0;
 
        iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
        irq_err = platform_get_irq(pdev, 0);
-       irq_dma = platform_get_irq(pdev, 1);
-       if (!iores || irq_err < 0 || irq_dma < 0)
+       if (!iores || irq_err < 0)
                return -EINVAL;
 
        mmc = mmc_alloc_host(sizeof(struct mxs_mmc_host), &pdev->dev);
@@ -620,23 +601,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
                goto out_mmc_free;
        }
 
-       if (np) {
-               ssp->devid = (enum mxs_ssp_id) of_id->data;
-               /*
-                * TODO: This is a temporary solution and should be changed
-                * to use generic DMA binding later when the helpers get in.
-                */
-               ret = of_property_read_u32(np, "fsl,ssp-dma-channel",
-                                          &ssp->dma_channel);
-               if (ret) {
-                       dev_err(mmc_dev(host->mmc),
-                               "failed to get dma channel\n");
-                       goto out_mmc_free;
-               }
-       } else {
-               ssp->devid = pdev->id_entry->driver_data;
-               ssp->dma_channel = dmares->start;
-       }
+       ssp->devid = (enum mxs_ssp_id) of_id->data;
 
        host->mmc = mmc;
        host->sdio_irq_en = 0;
@@ -666,10 +631,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
 
        mxs_mmc_reset(host);
 
-       dma_cap_zero(mask);
-       dma_cap_set(DMA_SLAVE, mask);
-       ssp->dma_data.chan_irq = irq_dma;
-       ssp->dmach = dma_request_channel(mask, mxs_mmc_dma_filter, host);
+       ssp->dmach = dma_request_slave_channel(&pdev->dev, "rx-tx");
        if (!ssp->dmach) {
                dev_err(mmc_dev(host->mmc),
                        "%s: failed to request dma\n", __func__);
index 63fb265e0da6545456fcc020029abf21ceca72a5..8d6794cdf899cd812e394b862c111a6c65b53dc4 100644 (file)
 
 #include <mach/dma.h>
 
-#include <mach/regs-sdi.h>
-
 #include <linux/platform_data/mmc-s3cmci.h>
 
 #include "s3cmci.h"
 
 #define DRIVER_NAME "s3c-mci"
 
+#define S3C2410_SDICON                 (0x00)
+#define S3C2410_SDIPRE                 (0x04)
+#define S3C2410_SDICMDARG              (0x08)
+#define S3C2410_SDICMDCON              (0x0C)
+#define S3C2410_SDICMDSTAT             (0x10)
+#define S3C2410_SDIRSP0                        (0x14)
+#define S3C2410_SDIRSP1                        (0x18)
+#define S3C2410_SDIRSP2                        (0x1C)
+#define S3C2410_SDIRSP3                        (0x20)
+#define S3C2410_SDITIMER               (0x24)
+#define S3C2410_SDIBSIZE               (0x28)
+#define S3C2410_SDIDCON                        (0x2C)
+#define S3C2410_SDIDCNT                        (0x30)
+#define S3C2410_SDIDSTA                        (0x34)
+#define S3C2410_SDIFSTA                        (0x38)
+
+#define S3C2410_SDIDATA                        (0x3C)
+#define S3C2410_SDIIMSK                        (0x40)
+
+#define S3C2440_SDIDATA                        (0x40)
+#define S3C2440_SDIIMSK                        (0x3C)
+
+#define S3C2440_SDICON_SDRESET         (1 << 8)
+#define S3C2410_SDICON_SDIOIRQ         (1 << 3)
+#define S3C2410_SDICON_FIFORESET       (1 << 1)
+#define S3C2410_SDICON_CLOCKTYPE       (1 << 0)
+
+#define S3C2410_SDICMDCON_LONGRSP      (1 << 10)
+#define S3C2410_SDICMDCON_WAITRSP      (1 << 9)
+#define S3C2410_SDICMDCON_CMDSTART     (1 << 8)
+#define S3C2410_SDICMDCON_SENDERHOST   (1 << 6)
+#define S3C2410_SDICMDCON_INDEX                (0x3f)
+
+#define S3C2410_SDICMDSTAT_CRCFAIL     (1 << 12)
+#define S3C2410_SDICMDSTAT_CMDSENT     (1 << 11)
+#define S3C2410_SDICMDSTAT_CMDTIMEOUT  (1 << 10)
+#define S3C2410_SDICMDSTAT_RSPFIN      (1 << 9)
+
+#define S3C2440_SDIDCON_DS_WORD                (2 << 22)
+#define S3C2410_SDIDCON_TXAFTERRESP    (1 << 20)
+#define S3C2410_SDIDCON_RXAFTERCMD     (1 << 19)
+#define S3C2410_SDIDCON_BLOCKMODE      (1 << 17)
+#define S3C2410_SDIDCON_WIDEBUS                (1 << 16)
+#define S3C2410_SDIDCON_DMAEN          (1 << 15)
+#define S3C2410_SDIDCON_STOP           (1 << 14)
+#define S3C2440_SDIDCON_DATSTART       (1 << 14)
+
+#define S3C2410_SDIDCON_XFER_RXSTART   (2 << 12)
+#define S3C2410_SDIDCON_XFER_TXSTART   (3 << 12)
+
+#define S3C2410_SDIDCON_BLKNUM_MASK    (0xFFF)
+
+#define S3C2410_SDIDSTA_SDIOIRQDETECT  (1 << 9)
+#define S3C2410_SDIDSTA_FIFOFAIL       (1 << 8)
+#define S3C2410_SDIDSTA_CRCFAIL                (1 << 7)
+#define S3C2410_SDIDSTA_RXCRCFAIL      (1 << 6)
+#define S3C2410_SDIDSTA_DATATIMEOUT    (1 << 5)
+#define S3C2410_SDIDSTA_XFERFINISH     (1 << 4)
+#define S3C2410_SDIDSTA_TXDATAON       (1 << 1)
+#define S3C2410_SDIDSTA_RXDATAON       (1 << 0)
+
+#define S3C2440_SDIFSTA_FIFORESET      (1 << 16)
+#define S3C2440_SDIFSTA_FIFOFAIL       (3 << 14)
+#define S3C2410_SDIFSTA_TFDET          (1 << 13)
+#define S3C2410_SDIFSTA_RFDET          (1 << 12)
+#define S3C2410_SDIFSTA_COUNTMASK      (0x7f)
+
+#define S3C2410_SDIIMSK_RESPONSECRC    (1 << 17)
+#define S3C2410_SDIIMSK_CMDSENT                (1 << 16)
+#define S3C2410_SDIIMSK_CMDTIMEOUT     (1 << 15)
+#define S3C2410_SDIIMSK_RESPONSEND     (1 << 14)
+#define S3C2410_SDIIMSK_SDIOIRQ                (1 << 12)
+#define S3C2410_SDIIMSK_FIFOFAIL       (1 << 11)
+#define S3C2410_SDIIMSK_CRCSTATUS      (1 << 10)
+#define S3C2410_SDIIMSK_DATACRC                (1 << 9)
+#define S3C2410_SDIIMSK_DATATIMEOUT    (1 << 8)
+#define S3C2410_SDIIMSK_DATAFINISH     (1 << 7)
+#define S3C2410_SDIIMSK_TXFIFOHALF     (1 << 4)
+#define S3C2410_SDIIMSK_RXFIFOLAST     (1 << 2)
+#define S3C2410_SDIIMSK_RXFIFOHALF     (1 << 0)
+
 enum dbg_channels {
        dbg_err   = (1 << 0),
        dbg_debug = (1 << 1),
index 717881a3d1b88cc64ad87e12fe0a0d68716254b5..25ecfa1822a8fc75cf485b41c51602ad04a0489b 100644 (file)
@@ -36,7 +36,6 @@
 #define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME  "gpmi-nand"
 #define GPMI_NAND_BCH_REGS_ADDR_RES_NAME   "bch"
 #define GPMI_NAND_BCH_INTERRUPT_RES_NAME   "bch"
-#define GPMI_NAND_DMA_INTERRUPT_RES_NAME   "gpmi-dma"
 
 /* add our owner bbt descriptor */
 static uint8_t scan_ff_pattern[] = { 0xff };
@@ -420,28 +419,6 @@ static void release_bch_irq(struct gpmi_nand_data *this)
                free_irq(i, this);
 }
 
-static bool gpmi_dma_filter(struct dma_chan *chan, void *param)
-{
-       struct gpmi_nand_data *this = param;
-       int dma_channel = (int)this->private;
-
-       if (!mxs_dma_is_apbh(chan))
-               return false;
-       /*
-        * only catch the GPMI dma channels :
-        *      for mx23 :      MX23_DMA_GPMI0 ~ MX23_DMA_GPMI3
-        *              (These four channels share the same IRQ!)
-        *
-        *      for mx28 :      MX28_DMA_GPMI0 ~ MX28_DMA_GPMI7
-        *              (These eight channels share the same IRQ!)
-        */
-       if (dma_channel == chan->chan_id) {
-               chan->private = &this->dma_data;
-               return true;
-       }
-       return false;
-}
-
 static void release_dma_channels(struct gpmi_nand_data *this)
 {
        unsigned int i;
@@ -455,36 +432,10 @@ static void release_dma_channels(struct gpmi_nand_data *this)
 static int acquire_dma_channels(struct gpmi_nand_data *this)
 {
        struct platform_device *pdev = this->pdev;
-       struct resource *r_dma;
-       struct device_node *dn;
-       u32 dma_channel;
-       int ret;
        struct dma_chan *dma_chan;
-       dma_cap_mask_t mask;
-
-       /* dma channel, we only use the first one. */
-       dn = pdev->dev.of_node;
-       ret = of_property_read_u32(dn, "fsl,gpmi-dma-channel", &dma_channel);
-       if (ret) {
-               pr_err("unable to get DMA channel from dt.\n");
-               goto acquire_err;
-       }
-       this->private = (void *)dma_channel;
-
-       /* gpmi dma interrupt */
-       r_dma = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
-                                       GPMI_NAND_DMA_INTERRUPT_RES_NAME);
-       if (!r_dma) {
-               pr_err("Can't get resource for DMA\n");
-               goto acquire_err;
-       }
-       this->dma_data.chan_irq = r_dma->start;
 
        /* request dma channel */
-       dma_cap_zero(mask);
-       dma_cap_set(DMA_SLAVE, mask);
-
-       dma_chan = dma_request_channel(mask, gpmi_dma_filter, this);
+       dma_chan = dma_request_slave_channel(&pdev->dev, "rx-tx");
        if (!dma_chan) {
                pr_err("Failed to request DMA channel.\n");
                goto acquire_err;
index 0729477312772da0e56ee13743fc5d7399200bc3..a7685e3a87486b86713fef19da82e9bbad3c6253 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
-#include <linux/fsl/mxs-dma.h>
+#include <linux/dmaengine.h>
 
 #define GPMI_CLK_MAX 5 /* MX6Q needs five clocks */
 struct resources {
@@ -180,7 +180,6 @@ struct gpmi_nand_data {
        /* DMA channels */
 #define DMA_CHANS              8
        struct dma_chan         *dma_chans[DMA_CHANS];
-       struct mxs_dma_data     dma_data;
        enum dma_ops_type       last_dma_type;
        enum dma_ops_type       dma_type;
        struct completion       dma_done;
index 1c9e09fbdff8346e99413e0313d03ed401f463e2..db103e03ba05b4b32b2efbb168a820fe5f71f999 100644 (file)
@@ -183,6 +183,11 @@ int bond_create_slave_symlinks(struct net_device *master,
        sprintf(linkname, "slave_%s", slave->name);
        ret = sysfs_create_link(&(master->dev.kobj), &(slave->dev.kobj),
                                linkname);
+
+       /* free the master link created earlier in case of error */
+       if (ret)
+               sysfs_remove_link(&(slave->dev.kobj), "master");
+
        return ret;
 
 }
index 568205436a15f4d5b37528eb155df6e00ee3f07c..91ecd6a00d05a77453e4311eb5741064ba03ded2 100644 (file)
@@ -2139,12 +2139,12 @@ static u8 bnx2x_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap)
                        break;
                default:
                        BNX2X_ERR("Non valid capability ID\n");
-                       rval = -EINVAL;
+                       rval = 1;
                        break;
                }
        } else {
                DP(BNX2X_MSG_DCB, "DCB disabled\n");
-               rval = -EINVAL;
+               rval = 1;
        }
 
        DP(BNX2X_MSG_DCB, "capid %d:%x\n", capid, *cap);
@@ -2170,12 +2170,12 @@ static int bnx2x_dcbnl_get_numtcs(struct net_device *netdev, int tcid, u8 *num)
                        break;
                default:
                        BNX2X_ERR("Non valid TC-ID\n");
-                       rval = -EINVAL;
+                       rval = 1;
                        break;
                }
        } else {
                DP(BNX2X_MSG_DCB, "DCB disabled\n");
-               rval = -EINVAL;
+               rval = 1;
        }
 
        return rval;
@@ -2188,7 +2188,7 @@ static int bnx2x_dcbnl_set_numtcs(struct net_device *netdev, int tcid, u8 num)
        return -EINVAL;
 }
 
-static u8  bnx2x_dcbnl_get_pfc_state(struct net_device *netdev)
+static u8 bnx2x_dcbnl_get_pfc_state(struct net_device *netdev)
 {
        struct bnx2x *bp = netdev_priv(netdev);
        DP(BNX2X_MSG_DCB, "state = %d\n", bp->dcbx_local_feat.pfc.enabled);
@@ -2390,12 +2390,12 @@ static u8 bnx2x_dcbnl_get_featcfg(struct net_device *netdev, int featid,
                        break;
                default:
                        BNX2X_ERR("Non valid featrue-ID\n");
-                       rval = -EINVAL;
+                       rval = 1;
                        break;
                }
        } else {
                DP(BNX2X_MSG_DCB, "DCB disabled\n");
-               rval = -EINVAL;
+               rval = 1;
        }
 
        return rval;
@@ -2431,12 +2431,12 @@ static u8 bnx2x_dcbnl_set_featcfg(struct net_device *netdev, int featid,
                        break;
                default:
                        BNX2X_ERR("Non valid featrue-ID\n");
-                       rval = -EINVAL;
+                       rval = 1;
                        break;
                }
        } else {
                DP(BNX2X_MSG_DCB, "dcbnl call not valid\n");
-               rval = -EINVAL;
+               rval = 1;
        }
 
        return rval;
index e3f39372ce25f93b63f93021a68e4dc4bc7294fb..dd098ea44d4881543f1ab6b708dc5ce3c767ffe2 100644 (file)
@@ -1332,7 +1332,7 @@ static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
 static void fec_enet_free_buffers(struct net_device *ndev)
 {
        struct fec_enet_private *fep = netdev_priv(ndev);
-       int i;
+       unsigned int i;
        struct sk_buff *skb;
        struct bufdesc  *bdp;
 
@@ -1356,7 +1356,7 @@ static void fec_enet_free_buffers(struct net_device *ndev)
 static int fec_enet_alloc_buffers(struct net_device *ndev)
 {
        struct fec_enet_private *fep = netdev_priv(ndev);
-       int i;
+       unsigned int i;
        struct sk_buff *skb;
        struct bufdesc  *bdp;
 
@@ -1598,7 +1598,7 @@ static int fec_enet_init(struct net_device *ndev)
        struct fec_enet_private *fep = netdev_priv(ndev);
        struct bufdesc *cbd_base;
        struct bufdesc *bdp;
-       int i;
+       unsigned int i;
 
        /* Allocate memory for buffer descriptors. */
        cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma,
@@ -1802,18 +1802,23 @@ fec_probe(struct platform_device *pdev)
                goto failed_clk;
        }
 
+       /* enet_out is optional, depends on board */
+       fep->clk_enet_out = devm_clk_get(&pdev->dev, "enet_out");
+       if (IS_ERR(fep->clk_enet_out))
+               fep->clk_enet_out = NULL;
+
        fep->clk_ptp = devm_clk_get(&pdev->dev, "ptp");
        fep->bufdesc_ex =
                pdev->id_entry->driver_data & FEC_QUIRK_HAS_BUFDESC_EX;
        if (IS_ERR(fep->clk_ptp)) {
-               ret = PTR_ERR(fep->clk_ptp);
+               fep->clk_ptp = NULL;
                fep->bufdesc_ex = 0;
        }
 
        clk_prepare_enable(fep->clk_ahb);
        clk_prepare_enable(fep->clk_ipg);
-       if (!IS_ERR(fep->clk_ptp))
-               clk_prepare_enable(fep->clk_ptp);
+       clk_prepare_enable(fep->clk_enet_out);
+       clk_prepare_enable(fep->clk_ptp);
 
        reg_phy = devm_regulator_get(&pdev->dev, "phy");
        if (!IS_ERR(reg_phy)) {
@@ -1878,8 +1883,8 @@ failed_irq:
 failed_regulator:
        clk_disable_unprepare(fep->clk_ahb);
        clk_disable_unprepare(fep->clk_ipg);
-       if (!IS_ERR(fep->clk_ptp))
-               clk_disable_unprepare(fep->clk_ptp);
+       clk_disable_unprepare(fep->clk_enet_out);
+       clk_disable_unprepare(fep->clk_ptp);
 failed_pin:
 failed_clk:
        iounmap(fep->hwp);
@@ -1905,6 +1910,7 @@ fec_drv_remove(struct platform_device *pdev)
        clk_disable_unprepare(fep->clk_ptp);
        if (fep->ptp_clock)
                ptp_clock_unregister(fep->ptp_clock);
+       clk_disable_unprepare(fep->clk_enet_out);
        clk_disable_unprepare(fep->clk_ahb);
        clk_disable_unprepare(fep->clk_ipg);
        for (i = 0; i < FEC_IRQ_NUM; i++) {
@@ -1935,6 +1941,7 @@ fec_suspend(struct device *dev)
                fec_stop(ndev);
                netif_device_detach(ndev);
        }
+       clk_disable_unprepare(fep->clk_enet_out);
        clk_disable_unprepare(fep->clk_ahb);
        clk_disable_unprepare(fep->clk_ipg);
 
@@ -1947,6 +1954,7 @@ fec_resume(struct device *dev)
        struct net_device *ndev = dev_get_drvdata(dev);
        struct fec_enet_private *fep = netdev_priv(ndev);
 
+       clk_prepare_enable(fep->clk_enet_out);
        clk_prepare_enable(fep->clk_ahb);
        clk_prepare_enable(fep->clk_ipg);
        if (netif_running(ndev)) {
index eb4372962839c216ed1ad68e29ba09a7aaf487ea..feabcb6a78b43144e31431bdcb2214e8f2a88539 100644 (file)
@@ -207,6 +207,7 @@ struct fec_enet_private {
 
        struct clk *clk_ipg;
        struct clk *clk_ahb;
+       struct clk *clk_enet_out;
        struct clk *clk_ptp;
 
        /* The saved address of a sent-in-place packet/buffer, for skfree(). */
index 1f17ca0f22019d8350af2affdcc6b00739ce966f..0d8df400a4798c06a1345773b9a0f821b4ab7cb2 100644 (file)
@@ -128,6 +128,7 @@ void fec_ptp_start_cyclecounter(struct net_device *ndev)
 
        spin_unlock_irqrestore(&fep->tmreg_lock, flags);
 }
+EXPORT_SYMBOL(fec_ptp_start_cyclecounter);
 
 /**
  * fec_ptp_adjfreq - adjust ptp cycle frequency
@@ -318,6 +319,7 @@ int fec_ptp_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd)
        return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?
            -EFAULT : 0;
 }
+EXPORT_SYMBOL(fec_ptp_ioctl);
 
 /**
  * fec_time_keep - call timecounter_read every second to avoid timer overrun
@@ -383,3 +385,4 @@ void fec_ptp_init(struct net_device *ndev, struct platform_device *pdev)
                pr_info("registered PHC device on %s\n", ndev->name);
        }
 }
+EXPORT_SYMBOL(fec_ptp_init);
index b64542acfa3449bda2ee5c793d83de6cda1f097c..12b1d84808084269971e5f83f55bd8b0f3fb8240 100644 (file)
@@ -1818,27 +1818,32 @@ out:
  **/
 void igb_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf)
 {
-       u32 dtxswc;
+       u32 reg_val, reg_offset;
 
        switch (hw->mac.type) {
        case e1000_82576:
+               reg_offset = E1000_DTXSWC;
+               break;
        case e1000_i350:
-               dtxswc = rd32(E1000_DTXSWC);
-               if (enable) {
-                       dtxswc |= (E1000_DTXSWC_MAC_SPOOF_MASK |
-                                  E1000_DTXSWC_VLAN_SPOOF_MASK);
-                       /* The PF can spoof - it has to in order to
-                        * support emulation mode NICs */
-                       dtxswc ^= (1 << pf | 1 << (pf + MAX_NUM_VFS));
-               } else {
-                       dtxswc &= ~(E1000_DTXSWC_MAC_SPOOF_MASK |
-                                   E1000_DTXSWC_VLAN_SPOOF_MASK);
-               }
-               wr32(E1000_DTXSWC, dtxswc);
+               reg_offset = E1000_TXSWC;
                break;
        default:
-               break;
+               return;
+       }
+
+       reg_val = rd32(reg_offset);
+       if (enable) {
+               reg_val |= (E1000_DTXSWC_MAC_SPOOF_MASK |
+                            E1000_DTXSWC_VLAN_SPOOF_MASK);
+               /* The PF can spoof - it has to in order to
+                * support emulation mode NICs
+                */
+               reg_val ^= (1 << pf | 1 << (pf + MAX_NUM_VFS));
+       } else {
+               reg_val &= ~(E1000_DTXSWC_MAC_SPOOF_MASK |
+                            E1000_DTXSWC_VLAN_SPOOF_MASK);
        }
+       wr32(reg_offset, reg_val);
 }
 
 /**
index 4623502054d5347b2723811fe1cdca0d1e93ae0e..0478a1abe54110d1374c6d77d950f6a4d7bf0327 100644 (file)
@@ -39,7 +39,7 @@
 #include <linux/pci.h>
 
 #ifdef CONFIG_IGB_HWMON
-struct i2c_board_info i350_sensor_info = {
+static struct i2c_board_info i350_sensor_info = {
        I2C_BOARD_INFO("i350bb", (0Xf8 >> 1)),
 };
 
index 4dbd62968c7a18090a61029249c04f6ee3b1335e..8496adfc6a685580f6ec1c50b86f0fed62b2b121 100644 (file)
@@ -2542,8 +2542,8 @@ static void igb_probe_vfs(struct igb_adapter *adapter)
        if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211))
                return;
 
-       igb_enable_sriov(pdev, max_vfs);
        pci_sriov_set_totalvfs(pdev, 7);
+       igb_enable_sriov(pdev, max_vfs);
 
 #endif /* CONFIG_PCI_IOV */
 }
@@ -2652,7 +2652,7 @@ static int igb_sw_init(struct igb_adapter *adapter)
                if (max_vfs > 7) {
                        dev_warn(&pdev->dev,
                                 "Maximum of 7 VFs per PF, using max\n");
-                       adapter->vfs_allocated_count = 7;
+                       max_vfs = adapter->vfs_allocated_count = 7;
                } else
                        adapter->vfs_allocated_count = max_vfs;
                if (adapter->vfs_allocated_count)
index 0987822359f00590d7f36bc5e126c8a4f20ee1ac..0a237507ee85008e9e11c703b07f58730202e072 100644 (file)
@@ -740,7 +740,7 @@ void igb_ptp_init(struct igb_adapter *adapter)
        case e1000_82576:
                snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr);
                adapter->ptp_caps.owner = THIS_MODULE;
-               adapter->ptp_caps.max_adj = 1000000000;
+               adapter->ptp_caps.max_adj = 999999881;
                adapter->ptp_caps.n_ext_ts = 0;
                adapter->ptp_caps.pps = 0;
                adapter->ptp_caps.adjfreq = igb_ptp_adjfreq_82576;
index c3db6cd69b68b0135f42908fd738bd7c9fd4fddc..2b6cb5ca48eefe8f0a075b1166f24dff7aaaaa83 100644 (file)
@@ -944,9 +944,17 @@ free_queue_irqs:
                free_irq(adapter->msix_entries[vector].vector,
                         adapter->q_vector[vector]);
        }
-       pci_disable_msix(adapter->pdev);
-       kfree(adapter->msix_entries);
-       adapter->msix_entries = NULL;
+       /* This failure is non-recoverable - it indicates the system is
+        * out of MSIX vector resources and the VF driver cannot run
+        * without them.  Set the number of msix vectors to zero
+        * indicating that not enough can be allocated.  The error
+        * will be returned to the user indicating device open failed.
+        * Any further attempts to force the driver to open will also
+        * fail.  The only way to recover is to unload the driver and
+        * reload it again.  If the system has recovered some MSIX
+        * vectors then it may succeed.
+        */
+       adapter->num_msix_vectors = 0;
        return err;
 }
 
@@ -2572,6 +2580,15 @@ static int ixgbevf_open(struct net_device *netdev)
        struct ixgbe_hw *hw = &adapter->hw;
        int err;
 
+       /* A previous failure to open the device because of a lack of
+        * available MSIX vector resources may have reset the number
+        * of msix vectors variable to zero.  The only way to recover
+        * is to unload/reload the driver and hope that the system has
+        * been able to recover some MSIX vector resources.
+        */
+       if (!adapter->num_msix_vectors)
+               return -ENOMEM;
+
        /* disallow open during test */
        if (test_bit(__IXGBEVF_TESTING, &adapter->state))
                return -EBUSY;
@@ -2628,7 +2645,6 @@ static int ixgbevf_open(struct net_device *netdev)
 
 err_req_irq:
        ixgbevf_down(adapter);
-       ixgbevf_free_irq(adapter);
 err_setup_rx:
        ixgbevf_free_all_rx_resources(adapter);
 err_setup_tx:
index 6a2127489af78e718264f202737ba0667770ba1b..bfdb06860397e720a848d6e8cab7b324ded6ea1c 100644 (file)
@@ -769,7 +769,7 @@ ltq_etop_probe(struct platform_device *pdev)
        return 0;
 
 err_free:
-       kfree(dev);
+       free_netdev(dev);
 err_out:
        return err;
 }
index 995d4b6d5c1e924a870f3da67c6ce1b543b99a83..f278b10ef7140a6e195056e11a12075de02afabc 100644 (file)
@@ -1637,6 +1637,17 @@ void mlx4_en_stop_port(struct net_device *dev, int detach)
        /* Flush multicast filter */
        mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0, 1, MLX4_MCAST_CONFIG);
 
+       /* Remove flow steering rules for the port*/
+       if (mdev->dev->caps.steering_mode ==
+           MLX4_STEERING_MODE_DEVICE_MANAGED) {
+               ASSERT_RTNL();
+               list_for_each_entry_safe(flow, tmp_flow,
+                                        &priv->ethtool_list, list) {
+                       mlx4_flow_detach(mdev->dev, flow->id);
+                       list_del(&flow->list);
+               }
+       }
+
        mlx4_en_destroy_drop_qp(priv);
 
        /* Free TX Rings */
@@ -1657,17 +1668,6 @@ void mlx4_en_stop_port(struct net_device *dev, int detach)
        if (!(mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAGS2_REASSIGN_MAC_EN))
                mdev->mac_removed[priv->port] = 1;
 
-       /* Remove flow steering rules for the port*/
-       if (mdev->dev->caps.steering_mode ==
-           MLX4_STEERING_MODE_DEVICE_MANAGED) {
-               ASSERT_RTNL();
-               list_for_each_entry_safe(flow, tmp_flow,
-                                        &priv->ethtool_list, list) {
-                       mlx4_flow_detach(mdev->dev, flow->id);
-                       list_del(&flow->list);
-               }
-       }
-
        /* Free RX Rings */
        for (i = 0; i < priv->rx_ring_num; i++) {
                mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]);
index 251ae2f9311680cb69eaada07cf3ad8a3cf58354..8e3123a1df886de6b0afb2c60397ecd28be3e4b9 100644 (file)
@@ -771,7 +771,7 @@ int mlx4_MAP_EQ_wrapper(struct mlx4_dev *dev, int slave,
        struct mlx4_slave_event_eq_info *event_eq =
                priv->mfunc.master.slave_state[slave].event_eq;
        u32 in_modifier = vhcr->in_modifier;
-       u32 eqn = in_modifier & 0x1FF;
+       u32 eqn = in_modifier & 0x3FF;
        u64 in_param =  vhcr->in_param;
        int err = 0;
        int i;
index 2995687f1aee3692ef5c164cff02870607f76224..1391b52f443aa5489ec31ee7e155b087f0372b0c 100644 (file)
@@ -99,6 +99,7 @@ struct res_qp {
        struct list_head        mcg_list;
        spinlock_t              mcg_spl;
        int                     local_qpn;
+       atomic_t                ref_count;
 };
 
 enum res_mtt_states {
@@ -197,6 +198,7 @@ enum res_fs_rule_states {
 
 struct res_fs_rule {
        struct res_common       com;
+       int                     qpn;
 };
 
 static void *res_tracker_lookup(struct rb_root *root, u64 res_id)
@@ -355,7 +357,7 @@ static int mpt_mask(struct mlx4_dev *dev)
        return dev->caps.num_mpts - 1;
 }
 
-static void *find_res(struct mlx4_dev *dev, int res_id,
+static void *find_res(struct mlx4_dev *dev, u64 res_id,
                      enum mlx4_resource type)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
@@ -447,6 +449,7 @@ static struct res_common *alloc_qp_tr(int id)
        ret->local_qpn = id;
        INIT_LIST_HEAD(&ret->mcg_list);
        spin_lock_init(&ret->mcg_spl);
+       atomic_set(&ret->ref_count, 0);
 
        return &ret->com;
 }
@@ -554,7 +557,7 @@ static struct res_common *alloc_xrcdn_tr(int id)
        return &ret->com;
 }
 
-static struct res_common *alloc_fs_rule_tr(u64 id)
+static struct res_common *alloc_fs_rule_tr(u64 id, int qpn)
 {
        struct res_fs_rule *ret;
 
@@ -564,7 +567,7 @@ static struct res_common *alloc_fs_rule_tr(u64 id)
 
        ret->com.res_id = id;
        ret->com.state = RES_FS_RULE_ALLOCATED;
-
+       ret->qpn = qpn;
        return &ret->com;
 }
 
@@ -602,7 +605,7 @@ static struct res_common *alloc_tr(u64 id, enum mlx4_resource type, int slave,
                ret = alloc_xrcdn_tr(id);
                break;
        case RES_FS_RULE:
-               ret = alloc_fs_rule_tr(id);
+               ret = alloc_fs_rule_tr(id, extra);
                break;
        default:
                return NULL;
@@ -671,10 +674,14 @@ undo:
 
 static int remove_qp_ok(struct res_qp *res)
 {
-       if (res->com.state == RES_QP_BUSY)
+       if (res->com.state == RES_QP_BUSY || atomic_read(&res->ref_count) ||
+           !list_empty(&res->mcg_list)) {
+               pr_err("resource tracker: fail to remove qp, state %d, ref_count %d\n",
+                      res->com.state, atomic_read(&res->ref_count));
                return -EBUSY;
-       else if (res->com.state != RES_QP_RESERVED)
+       } else if (res->com.state != RES_QP_RESERVED) {
                return -EPERM;
+       }
 
        return 0;
 }
@@ -3124,6 +3131,7 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
        struct list_head *rlist = &tracker->slave_list[slave].res_list[RES_MAC];
        int err;
        int qpn;
+       struct res_qp *rqp;
        struct mlx4_net_trans_rule_hw_ctrl *ctrl;
        struct _rule_hw  *rule_header;
        int header_id;
@@ -3134,7 +3142,7 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
 
        ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf;
        qpn = be32_to_cpu(ctrl->qpn) & 0xffffff;
-       err = get_res(dev, slave, qpn, RES_QP, NULL);
+       err = get_res(dev, slave, qpn, RES_QP, &rqp);
        if (err) {
                pr_err("Steering rule with qpn 0x%x rejected.\n", qpn);
                return err;
@@ -3175,14 +3183,16 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
        if (err)
                goto err_put;
 
-       err = add_res_range(dev, slave, vhcr->out_param, 1, RES_FS_RULE, 0);
+       err = add_res_range(dev, slave, vhcr->out_param, 1, RES_FS_RULE, qpn);
        if (err) {
                mlx4_err(dev, "Fail to add flow steering resources.\n ");
                /* detach rule*/
                mlx4_cmd(dev, vhcr->out_param, 0, 0,
                         MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A,
                         MLX4_CMD_NATIVE);
+               goto err_put;
        }
+       atomic_inc(&rqp->ref_count);
 err_put:
        put_res(dev, slave, qpn, RES_QP);
        return err;
@@ -3195,20 +3205,35 @@ int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave,
                                         struct mlx4_cmd_info *cmd)
 {
        int err;
+       struct res_qp *rqp;
+       struct res_fs_rule *rrule;
 
        if (dev->caps.steering_mode !=
            MLX4_STEERING_MODE_DEVICE_MANAGED)
                return -EOPNOTSUPP;
 
+       err = get_res(dev, slave, vhcr->in_param, RES_FS_RULE, &rrule);
+       if (err)
+               return err;
+       /* Release the rule form busy state before removal */
+       put_res(dev, slave, vhcr->in_param, RES_FS_RULE);
+       err = get_res(dev, slave, rrule->qpn, RES_QP, &rqp);
+       if (err)
+               return err;
+
        err = rem_res_range(dev, slave, vhcr->in_param, 1, RES_FS_RULE, 0);
        if (err) {
                mlx4_err(dev, "Fail to remove flow steering resources.\n ");
-               return err;
+               goto out;
        }
 
        err = mlx4_cmd(dev, vhcr->in_param, 0, 0,
                       MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A,
                       MLX4_CMD_NATIVE);
+       if (!err)
+               atomic_dec(&rqp->ref_count);
+out:
+       put_res(dev, slave, rrule->qpn, RES_QP);
        return err;
 }
 
@@ -3806,6 +3831,7 @@ void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave)
        mutex_lock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex);
        /*VLAN*/
        rem_slave_macs(dev, slave);
+       rem_slave_fs_rule(dev, slave);
        rem_slave_qps(dev, slave);
        rem_slave_srqs(dev, slave);
        rem_slave_cqs(dev, slave);
@@ -3814,6 +3840,5 @@ void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave)
        rem_slave_mtts(dev, slave);
        rem_slave_counters(dev, slave);
        rem_slave_xrcdns(dev, slave);
-       rem_slave_fs_rule(dev, slave);
        mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex);
 }
index c4122c86f829293cc60d6dd48c72602d7dded49f..efa29b712d5f1bdc9793648ebd76f9201cc3f99a 100644 (file)
@@ -1472,7 +1472,8 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
        }
        platform_set_drvdata(pdev, ndev);
 
-       if (lpc_mii_init(pldat) != 0)
+       ret = lpc_mii_init(pldat);
+       if (ret)
                goto err_out_unregister_netdev;
 
        netdev_info(ndev, "LPC mac at 0x%08x irq %d\n",
index 39ab4d09faaa2eb500748466ba6ab0fbe4074ac9..73ce7dd6b9544d470a6e14b163f7ae751d3d749d 100644 (file)
@@ -1726,9 +1726,9 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter,
 
                        skb->protocol = eth_type_trans(skb, netdev);
                        if (tcp_ip_status & PCH_GBE_RXD_ACC_STAT_TCPIPOK)
-                               skb->ip_summed = CHECKSUM_NONE;
-                       else
                                skb->ip_summed = CHECKSUM_UNNECESSARY;
+                       else
+                               skb->ip_summed = CHECKSUM_NONE;
 
                        napi_gro_receive(&adapter->napi, skb);
                        (*work_done)++;
index 33e96176e4d82167a2d62a51f1f1eb5d711f7375..bf5e3cf97c4d89d55b92b66a46ee37787acb934c 100644 (file)
@@ -2220,6 +2220,7 @@ static void sh_eth_tsu_init(struct sh_eth_private *mdp)
 /* MDIO bus release function */
 static int sh_mdio_release(struct net_device *ndev)
 {
+       struct sh_eth_private *mdp = netdev_priv(ndev);
        struct mii_bus *bus = dev_get_drvdata(&ndev->dev);
 
        /* unregister mdio bus */
@@ -2234,6 +2235,9 @@ static int sh_mdio_release(struct net_device *ndev)
        /* free bitbang info */
        free_mdio_bitbang(bus);
 
+       /* free bitbang memory */
+       kfree(mdp->bitbang);
+
        return 0;
 }
 
@@ -2262,6 +2266,7 @@ static int sh_mdio_init(struct net_device *ndev, int id,
        bitbang->ctrl.ops = &bb_ops;
 
        /* MII controller setting */
+       mdp->bitbang = bitbang;
        mdp->mii_bus = alloc_mdio_bitbang(&bitbang->ctrl);
        if (!mdp->mii_bus) {
                ret = -ENOMEM;
@@ -2441,6 +2446,11 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
                }
                mdp->tsu_addr = ioremap(rtsu->start,
                                        resource_size(rtsu));
+               if (mdp->tsu_addr == NULL) {
+                       ret = -ENOMEM;
+                       dev_err(&pdev->dev, "TSU ioremap failed.\n");
+                       goto out_release;
+               }
                mdp->port = devno % 2;
                ndev->features = NETIF_F_HW_VLAN_FILTER;
        }
index bae84fd2e73a7419504d8b29b195c0a118711b8a..e6655678458e5984fee032c6593e719a631d9c42 100644 (file)
@@ -705,6 +705,7 @@ struct sh_eth_private {
        const u16 *reg_offset;
        void __iomem *addr;
        void __iomem *tsu_addr;
+       struct bb_info *bitbang;
        u32 num_rx_ring;
        u32 num_tx_ring;
        dma_addr_t rx_desc_dma;
index 75c48558e6fd9b8afe355cbe41d95ab9dd842206..df32a090d08e0c96841a9958b1c1319eb6cbbc19 100644 (file)
@@ -1364,7 +1364,7 @@ static int cpsw_probe_dt(struct cpsw_platform_data *data,
                struct platform_device *mdio;
 
                parp = of_get_property(slave_node, "phy_id", &lenp);
-               if ((parp == NULL) && (lenp != (sizeof(void *) * 2))) {
+               if ((parp == NULL) || (lenp != (sizeof(void *) * 2))) {
                        pr_err("Missing slave[%d] phy_id property\n", i);
                        ret = -EINVAL;
                        goto error_ret;
index 4cc13940c8950d2a7ad2a3fdf1a092ac3736a7d5..f76c3ca07a4501603883bbcbe9feb901d4eca390 100644 (file)
@@ -1023,6 +1023,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
                                          AR_PHY_AGC_CONTROL_FLTR_CAL   |
                                          AR_PHY_AGC_CONTROL_PKDET_CAL;
 
+       /* Use chip chainmask only for calibration */
        ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
 
        if (rtt) {
@@ -1150,6 +1151,9 @@ skip_tx_iqcal:
                ar9003_hw_rtt_disable(ah);
        }
 
+       /* Revert chainmask to runtime parameters */
+       ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
+
        /* Initialize list pointers */
        ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
 
index ade3afb21f911e86589e325c2e99b49b7fe91289..39c84ecf6a42b345dc67d9cb52c7d3b45957525a 100644 (file)
@@ -28,21 +28,21 @@ void ath_tx_complete_poll_work(struct work_struct *work)
        int i;
        bool needreset = false;
 
-       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
-               if (ATH_TXQ_SETUP(sc, i)) {
-                       txq = &sc->tx.txq[i];
-                       ath_txq_lock(sc, txq);
-                       if (txq->axq_depth) {
-                               if (txq->axq_tx_inprogress) {
-                                       needreset = true;
-                                       ath_txq_unlock(sc, txq);
-                                       break;
-                               } else {
-                                       txq->axq_tx_inprogress = true;
-                               }
+       for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+               txq = sc->tx.txq_map[i];
+
+               ath_txq_lock(sc, txq);
+               if (txq->axq_depth) {
+                       if (txq->axq_tx_inprogress) {
+                               needreset = true;
+                               ath_txq_unlock(sc, txq);
+                               break;
+                       } else {
+                               txq->axq_tx_inprogress = true;
                        }
-                       ath_txq_unlock_complete(sc, txq);
                }
+               ath_txq_unlock_complete(sc, txq);
+       }
 
        if (needreset) {
                ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
index 3630a41df50d7c64815abae048696ea04329a703..c353b5f19c8c639480be47121f06c166dfc9f71c 100644 (file)
@@ -475,6 +475,7 @@ il3945_tx_skb(struct il_priv *il,
        dma_addr_t txcmd_phys;
        int txq_id = skb_get_queue_mapping(skb);
        u16 len, idx, hdr_len;
+       u16 firstlen, secondlen;
        u8 id;
        u8 unicast;
        u8 sta_id;
@@ -589,21 +590,22 @@ il3945_tx_skb(struct il_priv *il,
        len =
            sizeof(struct il3945_tx_cmd) + sizeof(struct il_cmd_header) +
            hdr_len;
-       len = (len + 3) & ~3;
+       firstlen = (len + 3) & ~3;
 
        /* Physical address of this Tx command's header (not MAC header!),
         * within command buffer array. */
        txcmd_phys =
-           pci_map_single(il->pci_dev, &out_cmd->hdr, len, PCI_DMA_TODEVICE);
+           pci_map_single(il->pci_dev, &out_cmd->hdr, firstlen,
+                          PCI_DMA_TODEVICE);
        if (unlikely(pci_dma_mapping_error(il->pci_dev, txcmd_phys)))
                goto drop_unlock;
 
        /* Set up TFD's 2nd entry to point directly to remainder of skb,
         * if any (802.11 null frames have no payload). */
-       len = skb->len - hdr_len;
-       if (len) {
+       secondlen = skb->len - hdr_len;
+       if (secondlen > 0) {
                phys_addr =
-                   pci_map_single(il->pci_dev, skb->data + hdr_len, len,
+                   pci_map_single(il->pci_dev, skb->data + hdr_len, secondlen,
                                   PCI_DMA_TODEVICE);
                if (unlikely(pci_dma_mapping_error(il->pci_dev, phys_addr)))
                        goto drop_unlock;
@@ -611,12 +613,12 @@ il3945_tx_skb(struct il_priv *il,
 
        /* Add buffer containing Tx command and MAC(!) header to TFD's
         * first entry */
-       il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, len, 1, 0);
+       il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen, 1, 0);
        dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
-       dma_unmap_len_set(out_meta, len, len);
-       if (len)
-               il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, len, 0,
-                                              U32_PAD(len));
+       dma_unmap_len_set(out_meta, len, firstlen);
+       if (secondlen > 0)
+               il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, secondlen, 0,
+                                              U32_PAD(secondlen));
 
        if (!ieee80211_has_morefrags(hdr->frame_control)) {
                txq->need_update = 1;
index 20a6c55558737b3bc3e3968856c5fe827780c688..b5c8b962ce12f74077fb6159b3e8558f521f10a5 100644 (file)
@@ -157,6 +157,20 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
                return -1;
        }
 
+       cmd_code = le16_to_cpu(host_cmd->command);
+       cmd_size = le16_to_cpu(host_cmd->size);
+
+       if (adapter->hw_status == MWIFIEX_HW_STATUS_RESET &&
+           cmd_code != HostCmd_CMD_FUNC_SHUTDOWN &&
+           cmd_code != HostCmd_CMD_FUNC_INIT) {
+               dev_err(adapter->dev,
+                       "DNLD_CMD: FW in reset state, ignore cmd %#x\n",
+                       cmd_code);
+               mwifiex_complete_cmd(adapter, cmd_node);
+               mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+               return -1;
+       }
+
        /* Set command sequence number */
        adapter->seq_num++;
        host_cmd->seq_num = cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO
@@ -168,9 +182,6 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
        adapter->curr_cmd = cmd_node;
        spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
 
-       cmd_code = le16_to_cpu(host_cmd->command);
-       cmd_size = le16_to_cpu(host_cmd->size);
-
        /* Adjust skb length */
        if (cmd_node->cmd_skb->len > cmd_size)
                /*
@@ -484,8 +495,6 @@ int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
 
        ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid,
                                     data_buf);
-       if (!ret)
-               ret = mwifiex_wait_queue_complete(adapter);
 
        return ret;
 }
@@ -588,9 +597,10 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
        if (cmd_no == HostCmd_CMD_802_11_SCAN) {
                mwifiex_queue_scan_cmd(priv, cmd_node);
        } else {
-               adapter->cmd_queued = cmd_node;
                mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
                queue_work(adapter->workqueue, &adapter->main_work);
+               if (cmd_node->wait_q_enabled)
+                       ret = mwifiex_wait_queue_complete(adapter, cmd_node);
        }
 
        return ret;
index e38aa9b3663d0a76c0cfe1c7f0698f923fc58587..0ff4c37ab42ae6853dbe6c85f8bb33f476b531e1 100644 (file)
@@ -709,6 +709,14 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
                return ret;
        }
 
+       /* cancel current command */
+       if (adapter->curr_cmd) {
+               dev_warn(adapter->dev, "curr_cmd is still in processing\n");
+               del_timer(&adapter->cmd_timer);
+               mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
+               adapter->curr_cmd = NULL;
+       }
+
        /* shut down mwifiex */
        dev_dbg(adapter->dev, "info: shutdown mwifiex...\n");
 
index 553adfb0aa81a35c468e44a07943b3f8fdf6e79e..7035ade9af74aeb08ceeea6b1545b28bd8e105d9 100644 (file)
@@ -723,7 +723,6 @@ struct mwifiex_adapter {
        u16 cmd_wait_q_required;
        struct mwifiex_wait_queue cmd_wait_q;
        u8 scan_wait_q_woken;
-       struct cmd_ctrl_node *cmd_queued;
        spinlock_t queue_lock;          /* lock for tx queues */
        struct completion fw_load;
        u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
@@ -1018,7 +1017,8 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
                        struct mwifiex_multicast_list *mcast_list);
 int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
                            struct net_device *dev);
-int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter);
+int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter,
+                               struct cmd_ctrl_node *cmd_queued);
 int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
                      struct cfg80211_ssid *req_ssid);
 int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type);
index bb60c2754a97ea54cc8c709206ba31a861e05d2e..d215b4d3c51b57db90eee2293f6c153059fe037b 100644 (file)
@@ -1388,10 +1388,13 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
                        list_del(&cmd_node->list);
                        spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
                                               flags);
-                       adapter->cmd_queued = cmd_node;
                        mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
                                                        true);
                        queue_work(adapter->workqueue, &adapter->main_work);
+
+                       /* Perform internal scan synchronously */
+                       if (!priv->scan_request)
+                               mwifiex_wait_queue_complete(adapter, cmd_node);
                } else {
                        spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
                                               flags);
@@ -1946,9 +1949,6 @@ int mwifiex_request_scan(struct mwifiex_private *priv,
                /* Normal scan */
                ret = mwifiex_scan_networks(priv, NULL);
 
-       if (!ret)
-               ret = mwifiex_wait_queue_complete(priv->adapter);
-
        up(&priv->async_sem);
 
        return ret;
index 9f33c92c90f5b8dc32bf9685bd3b708171b66acc..13100f8de3db1729b613333f16d21438104cd2e0 100644 (file)
@@ -54,16 +54,10 @@ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
  * This function waits on a cmd wait queue. It also cancels the pending
  * request after waking up, in case of errors.
  */
-int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter)
+int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter,
+                               struct cmd_ctrl_node *cmd_queued)
 {
        int status;
-       struct cmd_ctrl_node *cmd_queued;
-
-       if (!adapter->cmd_queued)
-               return 0;
-
-       cmd_queued = adapter->cmd_queued;
-       adapter->cmd_queued = NULL;
 
        dev_dbg(adapter->dev, "cmd pending\n");
        atomic_inc(&adapter->cmd_pending);
index 156b52732f3d576cb458bc3f6b3e2eb2818f2d90..5847d6d0881e7ce30180d26cc275425c55eda76b 100644 (file)
@@ -851,6 +851,7 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb,
        if (unlikely(!_urb)) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
                         "Can't allocate urb. Drop skb!\n");
+               kfree_skb(skb);
                return;
        }
        _rtl_submit_tx_urb(hw, _urb);
index c689c04a4f523248e9b2712e77d7e041f5b074d7..2d2f0a43d36b409cf287f6d6629b506e517948a9 100644 (file)
@@ -620,7 +620,7 @@ int mvebu_pinctrl_probe(struct platform_device *pdev)
 
                /* special soc specific control */
                if (ctrl->mpp_get || ctrl->mpp_set) {
-                       if (!ctrl->name || !ctrl->mpp_set || !ctrl->mpp_set) {
+                       if (!ctrl->name || !ctrl->mpp_get || !ctrl->mpp_set) {
                                dev_err(&pdev->dev, "wrong soc control info\n");
                                return -EINVAL;
                        }
index ac8d382a79bbfe43de8769ea43d1c13ab2fac036..d611ecfcbf70d8401946767f01833069ef60c431 100644 (file)
@@ -622,7 +622,7 @@ static const struct file_operations pinconf_dbg_pinname_fops = {
 static int pinconf_dbg_state_print(struct seq_file *s, void *d)
 {
        if (strlen(dbg_state_name))
-               seq_printf(s, "%s\n", dbg_pinname);
+               seq_printf(s, "%s\n", dbg_state_name);
        else
                seq_printf(s, "No pin state set\n");
        return 0;
index e3ed8cb072a5a4dd410015c66e3202ded90dd49c..bfda73d64eed527b2fce7e0a084b7459943bfb1e 100644 (file)
@@ -90,7 +90,7 @@ static inline void pinconf_init_device_debugfs(struct dentry *devroot,
  * pin config.
  */
 
-#ifdef CONFIG_GENERIC_PINCONF
+#if defined(CONFIG_GENERIC_PINCONF) && defined(CONFIG_DEBUG_FS)
 
 void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev,
                              struct seq_file *s, unsigned pin);
index caecdd37306126d7352b57365932b00b5e7ac1f2..c542a97c82f37cc743fa9d97e914c13dfe55aaa7 100644 (file)
@@ -422,7 +422,7 @@ static u8 abx500_get_mode(struct pinctrl_dev *pctldev, struct gpio_chip *chip,
        }
 
        /* check if pin use AlternateFunction register */
-       if ((af.alt_bit1 == UNUSED) && (af.alt_bit1 == UNUSED))
+       if ((af.alt_bit1 == UNUSED) && (af.alt_bit2 == UNUSED))
                return mode;
        /*
         * if pin GPIOSEL bit is set and pin supports alternate function,
index 1a00658b3ea070f336333160411f1b01bbc8f96e..bd83c8b01cd102e7c0f194c38389bb4a083c5dec 100644 (file)
@@ -194,6 +194,11 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin,
        }
 
        if (!gpio_range) {
+               /*
+                * A pin should not be freed more times than allocated.
+                */
+               if (WARN_ON(!desc->mux_usecount))
+                       return NULL;
                desc->mux_usecount--;
                if (desc->mux_usecount)
                        return NULL;
index 98f0d3c30738bb2cc48238613af255fbdf6789a2..67d26128bc85dd2694d81dace81acec7ae19334c 100644 (file)
@@ -30,8 +30,6 @@
 #include <linux/stmp_device.h>
 #include <linux/stmp3xxx_rtc_wdt.h>
 
-#include <mach/common.h>
-
 #define STMP3XXX_RTC_CTRL                      0x0
 #define STMP3XXX_RTC_CTRL_SET                  0x4
 #define STMP3XXX_RTC_CTRL_CLR                  0x8
@@ -271,7 +269,7 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, rtc_data);
 
-       mxs_reset_block(rtc_data->io);
+       stmp_reset_block(rtc_data->io);
        writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN |
                        STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN |
                        STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE,
@@ -319,7 +317,7 @@ static int stmp3xxx_rtc_resume(struct platform_device *dev)
 {
        struct stmp3xxx_rtc_data *rtc_data = platform_get_drvdata(dev);
 
-       mxs_reset_block(rtc_data->io);
+       stmp_reset_block(rtc_data->io);
        writel(STMP3XXX_RTC_PERSISTENT0_ALARM_EN |
                        STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE_EN |
                        STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE,
index 22a0af0147fb52be3fcb4111efaaafce27b80663..7b1c014b07407d30cedb0d8a1c2fcc44fd50d9f8 100644 (file)
@@ -490,21 +490,6 @@ static int mxs_spi_transfer_one(struct spi_master *master,
        return status;
 }
 
-static bool mxs_ssp_dma_filter(struct dma_chan *chan, void *param)
-{
-       struct mxs_ssp *ssp = param;
-
-       if (!mxs_dma_is_apbh(chan))
-               return false;
-
-       if (chan->chan_id != ssp->dma_channel)
-               return false;
-
-       chan->private = &ssp->dma_data;
-
-       return true;
-}
-
 static const struct of_device_id mxs_spi_dt_ids[] = {
        { .compatible = "fsl,imx23-spi", .data = (void *) IMX23_SSP, },
        { .compatible = "fsl,imx28-spi", .data = (void *) IMX28_SSP, },
@@ -520,13 +505,12 @@ static int mxs_spi_probe(struct platform_device *pdev)
        struct spi_master *master;
        struct mxs_spi *spi;
        struct mxs_ssp *ssp;
-       struct resource *iores, *dmares;
+       struct resource *iores;
        struct pinctrl *pinctrl;
        struct clk *clk;
        void __iomem *base;
-       int devid, dma_channel, clk_freq;
-       int ret = 0, irq_err, irq_dma;
-       dma_cap_mask_t mask;
+       int devid, clk_freq;
+       int ret = 0, irq_err;
 
        /*
         * Default clock speed for the SPI core. 160MHz seems to
@@ -537,8 +521,7 @@ static int mxs_spi_probe(struct platform_device *pdev)
 
        iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        irq_err = platform_get_irq(pdev, 0);
-       irq_dma = platform_get_irq(pdev, 1);
-       if (!iores || irq_err < 0 || irq_dma < 0)
+       if (!iores || irq_err < 0)
                return -EINVAL;
 
        base = devm_ioremap_resource(&pdev->dev, iores);
@@ -553,32 +536,11 @@ static int mxs_spi_probe(struct platform_device *pdev)
        if (IS_ERR(clk))
                return PTR_ERR(clk);
 
-       if (np) {
-               devid = (enum mxs_ssp_id) of_id->data;
-               /*
-                * TODO: This is a temporary solution and should be changed
-                * to use generic DMA binding later when the helpers get in.
-                */
-               ret = of_property_read_u32(np, "fsl,ssp-dma-channel",
-                                          &dma_channel);
-               if (ret) {
-                       dev_err(&pdev->dev,
-                               "Failed to get DMA channel\n");
-                       return -EINVAL;
-               }
-
-               ret = of_property_read_u32(np, "clock-frequency",
-                                          &clk_freq);
-               if (ret)
-                       clk_freq = clk_freq_default;
-       } else {
-               dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
-               if (!dmares)
-                       return -EINVAL;
-               devid = pdev->id_entry->driver_data;
-               dma_channel = dmares->start;
+       devid = (enum mxs_ssp_id) of_id->data;
+       ret = of_property_read_u32(np, "clock-frequency",
+                                  &clk_freq);
+       if (ret)
                clk_freq = clk_freq_default;
-       }
 
        master = spi_alloc_master(&pdev->dev, sizeof(*spi));
        if (!master)
@@ -597,7 +559,6 @@ static int mxs_spi_probe(struct platform_device *pdev)
        ssp->clk = clk;
        ssp->base = base;
        ssp->devid = devid;
-       ssp->dma_channel = dma_channel;
 
        init_completion(&spi->c);
 
@@ -606,10 +567,7 @@ static int mxs_spi_probe(struct platform_device *pdev)
        if (ret)
                goto out_master_free;
 
-       dma_cap_zero(mask);
-       dma_cap_set(DMA_SLAVE, mask);
-       ssp->dma_data.chan_irq = irq_dma;
-       ssp->dmach = dma_request_channel(mask, mxs_ssp_dma_filter, ssp);
+       ssp->dmach = dma_request_slave_channel(&pdev->dev, "rx-tx");
        if (!ssp->dmach) {
                dev_err(ssp->dev, "Failed to request DMA\n");
                goto out_master_free;
index 81a1fe661579d365ff82dfac8c0de06b53045110..71a73ec5af8d90811faebf7d087c705231a0a316 100644 (file)
@@ -1483,7 +1483,7 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
        case TRIG_NONE:
                /*  continous acquisition */
                devpriv->ai_continous = 1;
-               devpriv->ai_sample_count = 0;
+               devpriv->ai_sample_count = 1;
                break;
        }
 
index 55a459b619070d1752d2473cd5fe6392b7d976aa..0eb5b4d759e53c1fa3cbdc593d559ffebad78775 100644 (file)
@@ -36,9 +36,6 @@
 #include <linux/delay.h>
 #include <linux/input.h>
 
-#include <mach/mxs.h>
-#include <mach/common.h>
-
 #include <linux/iio/iio.h>
 #include <linux/iio/buffer.h>
 #include <linux/iio/trigger.h>
index 73582705e8c5bc71081494a7e4481b7eb36d42e8..5c3714530961c5ede430f7745706d24c833781ce 100644 (file)
@@ -15,7 +15,7 @@ config RAMSTER
        depends on CONFIGFS_FS=y && SYSFS=y && !HIGHMEM && ZCACHE=y
        depends on NET
        # must ensure struct page is 8-byte aligned
-       select HAVE_ALIGNED_STRUCT_PAGE if !64_BIT
+       select HAVE_ALIGNED_STRUCT_PAGE if !64BIT
        default n
        help
          RAMster allows RAM on other machines in a cluster to be utilized
index 2030b608136d3cfb7dc4509105ff061a3a621e14..3243ea790eaba9ee0db1b4152ac4e3450148ecd3 100644 (file)
@@ -1139,8 +1139,10 @@ target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb)
                return ret;
 
        ret = target_check_reservation(cmd);
-       if (ret)
+       if (ret) {
+               cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT;
                return ret;
+       }
 
        ret = dev->transport->parse_cdb(cmd);
        if (ret)
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
deleted file mode 100644 (file)
index cf6a538..0000000
+++ /dev/null
@@ -1,3448 +0,0 @@
-/*
- *  Driver for 8250/16550-type serial ports
- *
- *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
- *
- *  Copyright (C) 2001 Russell King.
- *
- * 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.
- *
- * A note about mapbase / membase
- *
- *  mapbase is the physical address of the IO port.
- *  membase is an 'ioremapped' cookie.
- */
-
-#if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-#define SUPPORT_SYSRQ
-#endif
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/sysrq.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/tty.h>
-#include <linux/ratelimit.h>
-#include <linux/tty_flip.h>
-#include <linux/serial_reg.h>
-#include <linux/serial_core.h>
-#include <linux/serial.h>
-#include <linux/serial_8250.h>
-#include <linux/nmi.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#ifdef CONFIG_SPARC
-#include <linux/sunserialcore.h>
-#endif
-
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include "8250.h"
-
-/*
- * Configuration:
- *   share_irqs - whether we pass IRQF_SHARED to request_irq().  This option
- *                is unsafe when used on edge-triggered interrupts.
- */
-static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
-
-static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
-
-static struct uart_driver serial8250_reg;
-
-static int serial_index(struct uart_port *port)
-{
-       return (serial8250_reg.minor - 64) + port->line;
-}
-
-static unsigned int skip_txen_test; /* force skip of txen test at init time */
-
-/*
- * Debugging.
- */
-#if 0
-#define DEBUG_AUTOCONF(fmt...) printk(fmt)
-#else
-#define DEBUG_AUTOCONF(fmt...) do { } while (0)
-#endif
-
-#if 0
-#define DEBUG_INTR(fmt...)     printk(fmt)
-#else
-#define DEBUG_INTR(fmt...)     do { } while (0)
-#endif
-
-#define PASS_LIMIT     512
-
-#define BOTH_EMPTY     (UART_LSR_TEMT | UART_LSR_THRE)
-
-
-#ifdef CONFIG_SERIAL_8250_DETECT_IRQ
-#define CONFIG_SERIAL_DETECT_IRQ 1
-#endif
-#ifdef CONFIG_SERIAL_8250_MANY_PORTS
-#define CONFIG_SERIAL_MANY_PORTS 1
-#endif
-
-/*
- * HUB6 is always on.  This will be removed once the header
- * files have been cleaned.
- */
-#define CONFIG_HUB6 1
-
-#include <asm/serial.h>
-/*
- * SERIAL_PORT_DFNS tells us about built-in ports that have no
- * standard enumeration mechanism.   Platforms that can find all
- * serial ports via mechanisms like ACPI or PCI need not supply it.
- */
-#ifndef SERIAL_PORT_DFNS
-#define SERIAL_PORT_DFNS
-#endif
-
-static const struct old_serial_port old_serial_port[] = {
-       SERIAL_PORT_DFNS /* defined in asm/serial.h */
-};
-
-#define UART_NR        CONFIG_SERIAL_8250_NR_UARTS
-
-#ifdef CONFIG_SERIAL_8250_RSA
-
-#define PORT_RSA_MAX 4
-static unsigned long probe_rsa[PORT_RSA_MAX];
-static unsigned int probe_rsa_count;
-#endif /* CONFIG_SERIAL_8250_RSA  */
-
-struct irq_info {
-       struct                  hlist_node node;
-       int                     irq;
-       spinlock_t              lock;   /* Protects list not the hash */
-       struct list_head        *head;
-};
-
-#define NR_IRQ_HASH            32      /* Can be adjusted later */
-static struct hlist_head irq_lists[NR_IRQ_HASH];
-static DEFINE_MUTEX(hash_mutex);       /* Used to walk the hash */
-
-/*
- * Here we define the default xmit fifo size used for each type of UART.
- */
-static const struct serial8250_config uart_config[] = {
-       [PORT_UNKNOWN] = {
-               .name           = "unknown",
-               .fifo_size      = 1,
-               .tx_loadsz      = 1,
-       },
-       [PORT_8250] = {
-               .name           = "8250",
-               .fifo_size      = 1,
-               .tx_loadsz      = 1,
-       },
-       [PORT_16450] = {
-               .name           = "16450",
-               .fifo_size      = 1,
-               .tx_loadsz      = 1,
-       },
-       [PORT_16550] = {
-               .name           = "16550",
-               .fifo_size      = 1,
-               .tx_loadsz      = 1,
-       },
-       [PORT_16550A] = {
-               .name           = "16550A",
-               .fifo_size      = 16,
-               .tx_loadsz      = 16,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO,
-       },
-       [PORT_CIRRUS] = {
-               .name           = "Cirrus",
-               .fifo_size      = 1,
-               .tx_loadsz      = 1,
-       },
-       [PORT_16650] = {
-               .name           = "ST16650",
-               .fifo_size      = 1,
-               .tx_loadsz      = 1,
-               .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
-       },
-       [PORT_16650V2] = {
-               .name           = "ST16650V2",
-               .fifo_size      = 32,
-               .tx_loadsz      = 16,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
-                                 UART_FCR_T_TRIG_00,
-               .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
-       },
-       [PORT_16750] = {
-               .name           = "TI16750",
-               .fifo_size      = 64,
-               .tx_loadsz      = 64,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 |
-                                 UART_FCR7_64BYTE,
-               .flags          = UART_CAP_FIFO | UART_CAP_SLEEP | UART_CAP_AFE,
-       },
-       [PORT_STARTECH] = {
-               .name           = "Startech",
-               .fifo_size      = 1,
-               .tx_loadsz      = 1,
-       },
-       [PORT_16C950] = {
-               .name           = "16C950/954",
-               .fifo_size      = 128,
-               .tx_loadsz      = 128,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               /* UART_CAP_EFR breaks billionon CF bluetooth card. */
-               .flags          = UART_CAP_FIFO | UART_CAP_SLEEP,
-       },
-       [PORT_16654] = {
-               .name           = "ST16654",
-               .fifo_size      = 64,
-               .tx_loadsz      = 32,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
-                                 UART_FCR_T_TRIG_10,
-               .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
-       },
-       [PORT_16850] = {
-               .name           = "XR16850",
-               .fifo_size      = 128,
-               .tx_loadsz      = 128,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
-       },
-       [PORT_RSA] = {
-               .name           = "RSA",
-               .fifo_size      = 2048,
-               .tx_loadsz      = 2048,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11,
-               .flags          = UART_CAP_FIFO,
-       },
-       [PORT_NS16550A] = {
-               .name           = "NS16550A",
-               .fifo_size      = 16,
-               .tx_loadsz      = 16,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO | UART_NATSEMI,
-       },
-       [PORT_XSCALE] = {
-               .name           = "XScale",
-               .fifo_size      = 32,
-               .tx_loadsz      = 32,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE,
-       },
-       [PORT_OCTEON] = {
-               .name           = "OCTEON",
-               .fifo_size      = 64,
-               .tx_loadsz      = 64,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO,
-       },
-       [PORT_AR7] = {
-               .name           = "AR7",
-               .fifo_size      = 16,
-               .tx_loadsz      = 16,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00,
-               .flags          = UART_CAP_FIFO | UART_CAP_AFE,
-       },
-       [PORT_U6_16550A] = {
-               .name           = "U6_16550A",
-               .fifo_size      = 64,
-               .tx_loadsz      = 64,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO | UART_CAP_AFE,
-       },
-       [PORT_TEGRA] = {
-               .name           = "Tegra",
-               .fifo_size      = 32,
-               .tx_loadsz      = 8,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
-                                 UART_FCR_T_TRIG_01,
-               .flags          = UART_CAP_FIFO | UART_CAP_RTOIE,
-       },
-       [PORT_XR17D15X] = {
-               .name           = "XR17D15X",
-               .fifo_size      = 64,
-               .tx_loadsz      = 64,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR |
-                                 UART_CAP_SLEEP,
-       },
-       [PORT_XR17V35X] = {
-               .name           = "XR17V35X",
-               .fifo_size      = 256,
-               .tx_loadsz      = 256,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11 |
-                                 UART_FCR_T_TRIG_11,
-               .flags          = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR |
-                                 UART_CAP_SLEEP,
-       },
-       [PORT_LPC3220] = {
-               .name           = "LPC3220",
-               .fifo_size      = 64,
-               .tx_loadsz      = 32,
-               .fcr            = UART_FCR_DMA_SELECT | UART_FCR_ENABLE_FIFO |
-                                 UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_00,
-               .flags          = UART_CAP_FIFO,
-       },
-       [PORT_BRCM_TRUMANAGE] = {
-               .name           = "TruManage",
-               .fifo_size      = 1,
-               .tx_loadsz      = 1024,
-               .flags          = UART_CAP_HFIFO,
-       },
-       [PORT_8250_CIR] = {
-               .name           = "CIR port"
-       },
-       [PORT_ALTR_16550_F32] = {
-               .name           = "Altera 16550 FIFO32",
-               .fifo_size      = 32,
-               .tx_loadsz      = 32,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO | UART_CAP_AFE,
-       },
-       [PORT_ALTR_16550_F64] = {
-               .name           = "Altera 16550 FIFO64",
-               .fifo_size      = 64,
-               .tx_loadsz      = 64,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO | UART_CAP_AFE,
-       },
-       [PORT_ALTR_16550_F128] = {
-               .name           = "Altera 16550 FIFO128",
-               .fifo_size      = 128,
-               .tx_loadsz      = 128,
-               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-               .flags          = UART_CAP_FIFO | UART_CAP_AFE,
-       },
-};
-
-/* Uart divisor latch read */
-static int default_serial_dl_read(struct uart_8250_port *up)
-{
-       return serial_in(up, UART_DLL) | serial_in(up, UART_DLM) << 8;
-}
-
-/* Uart divisor latch write */
-static void default_serial_dl_write(struct uart_8250_port *up, int value)
-{
-       serial_out(up, UART_DLL, value & 0xff);
-       serial_out(up, UART_DLM, value >> 8 & 0xff);
-}
-
-#if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X)
-
-/* Au1x00/RT288x UART hardware has a weird register layout */
-static const u8 au_io_in_map[] = {
-       [UART_RX]  = 0,
-       [UART_IER] = 2,
-       [UART_IIR] = 3,
-       [UART_LCR] = 5,
-       [UART_MCR] = 6,
-       [UART_LSR] = 7,
-       [UART_MSR] = 8,
-};
-
-static const u8 au_io_out_map[] = {
-       [UART_TX]  = 1,
-       [UART_IER] = 2,
-       [UART_FCR] = 4,
-       [UART_LCR] = 5,
-       [UART_MCR] = 6,
-};
-
-static unsigned int au_serial_in(struct uart_port *p, int offset)
-{
-       offset = au_io_in_map[offset] << p->regshift;
-       return __raw_readl(p->membase + offset);
-}
-
-static void au_serial_out(struct uart_port *p, int offset, int value)
-{
-       offset = au_io_out_map[offset] << p->regshift;
-       __raw_writel(value, p->membase + offset);
-}
-
-/* Au1x00 haven't got a standard divisor latch */
-static int au_serial_dl_read(struct uart_8250_port *up)
-{
-       return __raw_readl(up->port.membase + 0x28);
-}
-
-static void au_serial_dl_write(struct uart_8250_port *up, int value)
-{
-       __raw_writel(value, up->port.membase + 0x28);
-}
-
-#endif
-
-static unsigned int hub6_serial_in(struct uart_port *p, int offset)
-{
-       offset = offset << p->regshift;
-       outb(p->hub6 - 1 + offset, p->iobase);
-       return inb(p->iobase + 1);
-}
-
-static void hub6_serial_out(struct uart_port *p, int offset, int value)
-{
-       offset = offset << p->regshift;
-       outb(p->hub6 - 1 + offset, p->iobase);
-       outb(value, p->iobase + 1);
-}
-
-static unsigned int mem_serial_in(struct uart_port *p, int offset)
-{
-       offset = offset << p->regshift;
-       return readb(p->membase + offset);
-}
-
-static void mem_serial_out(struct uart_port *p, int offset, int value)
-{
-       offset = offset << p->regshift;
-       writeb(value, p->membase + offset);
-}
-
-static void mem32_serial_out(struct uart_port *p, int offset, int value)
-{
-       offset = offset << p->regshift;
-       writel(value, p->membase + offset);
-}
-
-static unsigned int mem32_serial_in(struct uart_port *p, int offset)
-{
-       offset = offset << p->regshift;
-       return readl(p->membase + offset);
-}
-
-static unsigned int io_serial_in(struct uart_port *p, int offset)
-{
-       offset = offset << p->regshift;
-       return inb(p->iobase + offset);
-}
-
-static void io_serial_out(struct uart_port *p, int offset, int value)
-{
-       offset = offset << p->regshift;
-       outb(value, p->iobase + offset);
-}
-
-static int serial8250_default_handle_irq(struct uart_port *port);
-static int exar_handle_irq(struct uart_port *port);
-
-static void set_io_from_upio(struct uart_port *p)
-{
-       struct uart_8250_port *up =
-               container_of(p, struct uart_8250_port, port);
-
-       up->dl_read = default_serial_dl_read;
-       up->dl_write = default_serial_dl_write;
-
-       switch (p->iotype) {
-       case UPIO_HUB6:
-               p->serial_in = hub6_serial_in;
-               p->serial_out = hub6_serial_out;
-               break;
-
-       case UPIO_MEM:
-               p->serial_in = mem_serial_in;
-               p->serial_out = mem_serial_out;
-               break;
-
-       case UPIO_MEM32:
-               p->serial_in = mem32_serial_in;
-               p->serial_out = mem32_serial_out;
-               break;
-
-#if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X)
-       case UPIO_AU:
-               p->serial_in = au_serial_in;
-               p->serial_out = au_serial_out;
-               up->dl_read = au_serial_dl_read;
-               up->dl_write = au_serial_dl_write;
-               break;
-#endif
-
-       default:
-               p->serial_in = io_serial_in;
-               p->serial_out = io_serial_out;
-               break;
-       }
-       /* Remember loaded iotype */
-       up->cur_iotype = p->iotype;
-       p->handle_irq = serial8250_default_handle_irq;
-}
-
-static void
-serial_port_out_sync(struct uart_port *p, int offset, int value)
-{
-       switch (p->iotype) {
-       case UPIO_MEM:
-       case UPIO_MEM32:
-       case UPIO_AU:
-               p->serial_out(p, offset, value);
-               p->serial_in(p, UART_LCR);      /* safe, no side-effects */
-               break;
-       default:
-               p->serial_out(p, offset, value);
-       }
-}
-
-/*
- * For the 16C950
- */
-static void serial_icr_write(struct uart_8250_port *up, int offset, int value)
-{
-       serial_out(up, UART_SCR, offset);
-       serial_out(up, UART_ICR, value);
-}
-
-static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
-{
-       unsigned int value;
-
-       serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD);
-       serial_out(up, UART_SCR, offset);
-       value = serial_in(up, UART_ICR);
-       serial_icr_write(up, UART_ACR, up->acr);
-
-       return value;
-}
-
-/*
- * FIFO support.
- */
-static void serial8250_clear_fifos(struct uart_8250_port *p)
-{
-       if (p->capabilities & UART_CAP_FIFO) {
-               serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO);
-               serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO |
-                              UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
-               serial_out(p, UART_FCR, 0);
-       }
-}
-
-void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p)
-{
-       unsigned char fcr;
-
-       serial8250_clear_fifos(p);
-       fcr = uart_config[p->port.type].fcr;
-       serial_out(p, UART_FCR, fcr);
-}
-EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos);
-
-/*
- * IER sleep support.  UARTs which have EFRs need the "extended
- * capability" bit enabled.  Note that on XR16C850s, we need to
- * reset LCR to write to IER.
- */
-static void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
-{
-       /*
-        * Exar UARTs have a SLEEP register that enables or disables
-        * each UART to enter sleep mode separately.  On the XR17V35x the
-        * register is accessible to each UART at the UART_EXAR_SLEEP
-        * offset but the UART channel may only write to the corresponding
-        * bit.
-        */
-       if ((p->port.type == PORT_XR17V35X) ||
-          (p->port.type == PORT_XR17D15X)) {
-               serial_out(p, UART_EXAR_SLEEP, 0xff);
-               return;
-       }
-
-       if (p->capabilities & UART_CAP_SLEEP) {
-               if (p->capabilities & UART_CAP_EFR) {
-                       serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B);
-                       serial_out(p, UART_EFR, UART_EFR_ECB);
-                       serial_out(p, UART_LCR, 0);
-               }
-               serial_out(p, UART_IER, sleep ? UART_IERX_SLEEP : 0);
-               if (p->capabilities & UART_CAP_EFR) {
-                       serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B);
-                       serial_out(p, UART_EFR, 0);
-                       serial_out(p, UART_LCR, 0);
-               }
-       }
-}
-
-#ifdef CONFIG_SERIAL_8250_RSA
-/*
- * Attempts to turn on the RSA FIFO.  Returns zero on failure.
- * We set the port uart clock rate if we succeed.
- */
-static int __enable_rsa(struct uart_8250_port *up)
-{
-       unsigned char mode;
-       int result;
-
-       mode = serial_in(up, UART_RSA_MSR);
-       result = mode & UART_RSA_MSR_FIFO;
-
-       if (!result) {
-               serial_out(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO);
-               mode = serial_in(up, UART_RSA_MSR);
-               result = mode & UART_RSA_MSR_FIFO;
-       }
-
-       if (result)
-               up->port.uartclk = SERIAL_RSA_BAUD_BASE * 16;
-
-       return result;
-}
-
-static void enable_rsa(struct uart_8250_port *up)
-{
-       if (up->port.type == PORT_RSA) {
-               if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) {
-                       spin_lock_irq(&up->port.lock);
-                       __enable_rsa(up);
-                       spin_unlock_irq(&up->port.lock);
-               }
-               if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16)
-                       serial_out(up, UART_RSA_FRR, 0);
-       }
-}
-
-/*
- * Attempts to turn off the RSA FIFO.  Returns zero on failure.
- * It is unknown why interrupts were disabled in here.  However,
- * the caller is expected to preserve this behaviour by grabbing
- * the spinlock before calling this function.
- */
-static void disable_rsa(struct uart_8250_port *up)
-{
-       unsigned char mode;
-       int result;
-
-       if (up->port.type == PORT_RSA &&
-           up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) {
-               spin_lock_irq(&up->port.lock);
-
-               mode = serial_in(up, UART_RSA_MSR);
-               result = !(mode & UART_RSA_MSR_FIFO);
-
-               if (!result) {
-                       serial_out(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO);
-                       mode = serial_in(up, UART_RSA_MSR);
-                       result = !(mode & UART_RSA_MSR_FIFO);
-               }
-
-               if (result)
-                       up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16;
-               spin_unlock_irq(&up->port.lock);
-       }
-}
-#endif /* CONFIG_SERIAL_8250_RSA */
-
-/*
- * This is a quickie test to see how big the FIFO is.
- * It doesn't work at all the time, more's the pity.
- */
-static int size_fifo(struct uart_8250_port *up)
-{
-       unsigned char old_fcr, old_mcr, old_lcr;
-       unsigned short old_dl;
-       int count;
-
-       old_lcr = serial_in(up, UART_LCR);
-       serial_out(up, UART_LCR, 0);
-       old_fcr = serial_in(up, UART_FCR);
-       old_mcr = serial_in(up, UART_MCR);
-       serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO |
-                   UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
-       serial_out(up, UART_MCR, UART_MCR_LOOP);
-       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
-       old_dl = serial_dl_read(up);
-       serial_dl_write(up, 0x0001);
-       serial_out(up, UART_LCR, 0x03);
-       for (count = 0; count < 256; count++)
-               serial_out(up, UART_TX, count);
-       mdelay(20);/* FIXME - schedule_timeout */
-       for (count = 0; (serial_in(up, UART_LSR) & UART_LSR_DR) &&
-            (count < 256); count++)
-               serial_in(up, UART_RX);
-       serial_out(up, UART_FCR, old_fcr);
-       serial_out(up, UART_MCR, old_mcr);
-       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
-       serial_dl_write(up, old_dl);
-       serial_out(up, UART_LCR, old_lcr);
-
-       return count;
-}
-
-/*
- * Read UART ID using the divisor method - set DLL and DLM to zero
- * and the revision will be in DLL and device type in DLM.  We
- * preserve the device state across this.
- */
-static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p)
-{
-       unsigned char old_dll, old_dlm, old_lcr;
-       unsigned int id;
-
-       old_lcr = serial_in(p, UART_LCR);
-       serial_out(p, UART_LCR, UART_LCR_CONF_MODE_A);
-
-       old_dll = serial_in(p, UART_DLL);
-       old_dlm = serial_in(p, UART_DLM);
-
-       serial_out(p, UART_DLL, 0);
-       serial_out(p, UART_DLM, 0);
-
-       id = serial_in(p, UART_DLL) | serial_in(p, UART_DLM) << 8;
-
-       serial_out(p, UART_DLL, old_dll);
-       serial_out(p, UART_DLM, old_dlm);
-       serial_out(p, UART_LCR, old_lcr);
-
-       return id;
-}
-
-/*
- * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's.
- * When this function is called we know it is at least a StarTech
- * 16650 V2, but it might be one of several StarTech UARTs, or one of
- * its clones.  (We treat the broken original StarTech 16650 V1 as a
- * 16550, and why not?  Startech doesn't seem to even acknowledge its
- * existence.)
- *
- * What evil have men's minds wrought...
- */
-static void autoconfig_has_efr(struct uart_8250_port *up)
-{
-       unsigned int id1, id2, id3, rev;
-
-       /*
-        * Everything with an EFR has SLEEP
-        */
-       up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP;
-
-       /*
-        * First we check to see if it's an Oxford Semiconductor UART.
-        *
-        * If we have to do this here because some non-National
-        * Semiconductor clone chips lock up if you try writing to the
-        * LSR register (which serial_icr_read does)
-        */
-
-       /*
-        * Check for Oxford Semiconductor 16C950.
-        *
-        * EFR [4] must be set else this test fails.
-        *
-        * This shouldn't be necessary, but Mike Hudson (Exoray@isys.ca)
-        * claims that it's needed for 952 dual UART's (which are not
-        * recommended for new designs).
-        */
-       up->acr = 0;
-       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
-       serial_out(up, UART_EFR, UART_EFR_ECB);
-       serial_out(up, UART_LCR, 0x00);
-       id1 = serial_icr_read(up, UART_ID1);
-       id2 = serial_icr_read(up, UART_ID2);
-       id3 = serial_icr_read(up, UART_ID3);
-       rev = serial_icr_read(up, UART_REV);
-
-       DEBUG_AUTOCONF("950id=%02x:%02x:%02x:%02x ", id1, id2, id3, rev);
-
-       if (id1 == 0x16 && id2 == 0xC9 &&
-           (id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) {
-               up->port.type = PORT_16C950;
-
-               /*
-                * Enable work around for the Oxford Semiconductor 952 rev B
-                * chip which causes it to seriously miscalculate baud rates
-                * when DLL is 0.
-                */
-               if (id3 == 0x52 && rev == 0x01)
-                       up->bugs |= UART_BUG_QUOT;
-               return;
-       }
-
-       /*
-        * We check for a XR16C850 by setting DLL and DLM to 0, and then
-        * reading back DLL and DLM.  The chip type depends on the DLM
-        * value read back:
-        *  0x10 - XR16C850 and the DLL contains the chip revision.
-        *  0x12 - XR16C2850.
-        *  0x14 - XR16C854.
-        */
-       id1 = autoconfig_read_divisor_id(up);
-       DEBUG_AUTOCONF("850id=%04x ", id1);
-
-       id2 = id1 >> 8;
-       if (id2 == 0x10 || id2 == 0x12 || id2 == 0x14) {
-               up->port.type = PORT_16850;
-               return;
-       }
-
-       /*
-        * It wasn't an XR16C850.
-        *
-        * We distinguish between the '654 and the '650 by counting
-        * how many bytes are in the FIFO.  I'm using this for now,
-        * since that's the technique that was sent to me in the
-        * serial driver update, but I'm not convinced this works.
-        * I've had problems doing this in the past.  -TYT
-        */
-       if (size_fifo(up) == 64)
-               up->port.type = PORT_16654;
-       else
-               up->port.type = PORT_16650V2;
-}
-
-/*
- * We detected a chip without a FIFO.  Only two fall into
- * this category - the original 8250 and the 16450.  The
- * 16450 has a scratch register (accessible with LCR=0)
- */
-static void autoconfig_8250(struct uart_8250_port *up)
-{
-       unsigned char scratch, status1, status2;
-
-       up->port.type = PORT_8250;
-
-       scratch = serial_in(up, UART_SCR);
-       serial_out(up, UART_SCR, 0xa5);
-       status1 = serial_in(up, UART_SCR);
-       serial_out(up, UART_SCR, 0x5a);
-       status2 = serial_in(up, UART_SCR);
-       serial_out(up, UART_SCR, scratch);
-
-       if (status1 == 0xa5 && status2 == 0x5a)
-               up->port.type = PORT_16450;
-}
-
-static int broken_efr(struct uart_8250_port *up)
-{
-       /*
-        * Exar ST16C2550 "A2" devices incorrectly detect as
-        * having an EFR, and report an ID of 0x0201.  See
-        * http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-11/4812.html 
-        */
-       if (autoconfig_read_divisor_id(up) == 0x0201 && size_fifo(up) == 16)
-               return 1;
-
-       return 0;
-}
-
-static inline int ns16550a_goto_highspeed(struct uart_8250_port *up)
-{
-       unsigned char status;
-
-       status = serial_in(up, 0x04); /* EXCR2 */
-#define PRESL(x) ((x) & 0x30)
-       if (PRESL(status) == 0x10) {
-               /* already in high speed mode */
-               return 0;
-       } else {
-               status &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
-               status |= 0x10;  /* 1.625 divisor for baud_base --> 921600 */
-               serial_out(up, 0x04, status);
-       }
-       return 1;
-}
-
-/*
- * We know that the chip has FIFOs.  Does it have an EFR?  The
- * EFR is located in the same register position as the IIR and
- * we know the top two bits of the IIR are currently set.  The
- * EFR should contain zero.  Try to read the EFR.
- */
-static void autoconfig_16550a(struct uart_8250_port *up)
-{
-       unsigned char status1, status2;
-       unsigned int iersave;
-
-       up->port.type = PORT_16550A;
-       up->capabilities |= UART_CAP_FIFO;
-
-       /*
-        * XR17V35x UARTs have an extra divisor register, DLD
-        * that gets enabled with when DLAB is set which will
-        * cause the device to incorrectly match and assign
-        * port type to PORT_16650.  The EFR for this UART is
-        * found at offset 0x09. Instead check the Deice ID (DVID)
-        * register for a 2, 4 or 8 port UART.
-        */
-       if (up->port.flags & UPF_EXAR_EFR) {
-               status1 = serial_in(up, UART_EXAR_DVID);
-               if (status1 == 0x82 || status1 == 0x84 || status1 == 0x88) {
-                       DEBUG_AUTOCONF("Exar XR17V35x ");
-                       up->port.type = PORT_XR17V35X;
-                       up->capabilities |= UART_CAP_AFE | UART_CAP_EFR |
-                                               UART_CAP_SLEEP;
-
-                       return;
-               }
-
-       }
-
-       /*
-        * Check for presence of the EFR when DLAB is set.
-        * Only ST16C650V1 UARTs pass this test.
-        */
-       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
-       if (serial_in(up, UART_EFR) == 0) {
-               serial_out(up, UART_EFR, 0xA8);
-               if (serial_in(up, UART_EFR) != 0) {
-                       DEBUG_AUTOCONF("EFRv1 ");
-                       up->port.type = PORT_16650;
-                       up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP;
-               } else {
-                       DEBUG_AUTOCONF("Motorola 8xxx DUART ");
-               }
-               serial_out(up, UART_EFR, 0);
-               return;
-       }
-
-       /*
-        * Maybe it requires 0xbf to be written to the LCR.
-        * (other ST16C650V2 UARTs, TI16C752A, etc)
-        */
-       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
-       if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) {
-               DEBUG_AUTOCONF("EFRv2 ");
-               autoconfig_has_efr(up);
-               return;
-       }
-
-       /*
-        * Check for a National Semiconductor SuperIO chip.
-        * Attempt to switch to bank 2, read the value of the LOOP bit
-        * from EXCR1. Switch back to bank 0, change it in MCR. Then
-        * switch back to bank 2, read it from EXCR1 again and check
-        * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2
-        */
-       serial_out(up, UART_LCR, 0);
-       status1 = serial_in(up, UART_MCR);
-       serial_out(up, UART_LCR, 0xE0);
-       status2 = serial_in(up, 0x02); /* EXCR1 */
-
-       if (!((status2 ^ status1) & UART_MCR_LOOP)) {
-               serial_out(up, UART_LCR, 0);
-               serial_out(up, UART_MCR, status1 ^ UART_MCR_LOOP);
-               serial_out(up, UART_LCR, 0xE0);
-               status2 = serial_in(up, 0x02); /* EXCR1 */
-               serial_out(up, UART_LCR, 0);
-               serial_out(up, UART_MCR, status1);
-
-               if ((status2 ^ status1) & UART_MCR_LOOP) {
-                       unsigned short quot;
-
-                       serial_out(up, UART_LCR, 0xE0);
-
-                       quot = serial_dl_read(up);
-                       quot <<= 3;
-
-                       if (ns16550a_goto_highspeed(up))
-                               serial_dl_write(up, quot);
-
-                       serial_out(up, UART_LCR, 0);
-
-                       up->port.uartclk = 921600*16;
-                       up->port.type = PORT_NS16550A;
-                       up->capabilities |= UART_NATSEMI;
-                       return;
-               }
-       }
-
-       /*
-        * No EFR.  Try to detect a TI16750, which only sets bit 5 of
-        * the IIR when 64 byte FIFO mode is enabled when DLAB is set.
-        * Try setting it with and without DLAB set.  Cheap clones
-        * set bit 5 without DLAB set.
-        */
-       serial_out(up, UART_LCR, 0);
-       serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
-       status1 = serial_in(up, UART_IIR) >> 5;
-       serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
-       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
-       serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
-       status2 = serial_in(up, UART_IIR) >> 5;
-       serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
-       serial_out(up, UART_LCR, 0);
-
-       DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2);
-
-       if (status1 == 6 && status2 == 7) {
-               up->port.type = PORT_16750;
-               up->capabilities |= UART_CAP_AFE | UART_CAP_SLEEP;
-               return;
-       }
-
-       /*
-        * Try writing and reading the UART_IER_UUE bit (b6).
-        * If it works, this is probably one of the Xscale platform's
-        * internal UARTs.
-        * We're going to explicitly set the UUE bit to 0 before
-        * trying to write and read a 1 just to make sure it's not
-        * already a 1 and maybe locked there before we even start start.
-        */
-       iersave = serial_in(up, UART_IER);
-       serial_out(up, UART_IER, iersave & ~UART_IER_UUE);
-       if (!(serial_in(up, UART_IER) & UART_IER_UUE)) {
-               /*
-                * OK it's in a known zero state, try writing and reading
-                * without disturbing the current state of the other bits.
-                */
-               serial_out(up, UART_IER, iersave | UART_IER_UUE);
-               if (serial_in(up, UART_IER) & UART_IER_UUE) {
-                       /*
-                        * It's an Xscale.
-                        * We'll leave the UART_IER_UUE bit set to 1 (enabled).
-                        */
-                       DEBUG_AUTOCONF("Xscale ");
-                       up->port.type = PORT_XSCALE;
-                       up->capabilities |= UART_CAP_UUE | UART_CAP_RTOIE;
-                       return;
-               }
-       } else {
-               /*
-                * If we got here we couldn't force the IER_UUE bit to 0.
-                * Log it and continue.
-                */
-               DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 ");
-       }
-       serial_out(up, UART_IER, iersave);
-
-       /*
-        * Exar uarts have EFR in a weird location
-        */
-       if (up->port.flags & UPF_EXAR_EFR) {
-               DEBUG_AUTOCONF("Exar XR17D15x ");
-               up->port.type = PORT_XR17D15X;
-               up->capabilities |= UART_CAP_AFE | UART_CAP_EFR |
-                                   UART_CAP_SLEEP;
-
-               return;
-       }
-
-       /*
-        * We distinguish between 16550A and U6 16550A by counting
-        * how many bytes are in the FIFO.
-        */
-       if (up->port.type == PORT_16550A && size_fifo(up) == 64) {
-               up->port.type = PORT_U6_16550A;
-               up->capabilities |= UART_CAP_AFE;
-       }
-}
-
-/*
- * This routine is called by rs_init() to initialize a specific serial
- * port.  It determines what type of UART chip this serial port is
- * using: 8250, 16450, 16550, 16550A.  The important question is
- * whether or not this UART is a 16550A or not, since this will
- * determine whether or not we can use its FIFO features or not.
- */
-static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
-{
-       unsigned char status1, scratch, scratch2, scratch3;
-       unsigned char save_lcr, save_mcr;
-       struct uart_port *port = &up->port;
-       unsigned long flags;
-       unsigned int old_capabilities;
-
-       if (!port->iobase && !port->mapbase && !port->membase)
-               return;
-
-       DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04lx, 0x%p): ",
-                      serial_index(port), port->iobase, port->membase);
-
-       /*
-        * We really do need global IRQs disabled here - we're going to
-        * be frobbing the chips IRQ enable register to see if it exists.
-        */
-       spin_lock_irqsave(&port->lock, flags);
-
-       up->capabilities = 0;
-       up->bugs = 0;
-
-       if (!(port->flags & UPF_BUGGY_UART)) {
-               /*
-                * Do a simple existence test first; if we fail this,
-                * there's no point trying anything else.
-                *
-                * 0x80 is used as a nonsense port to prevent against
-                * false positives due to ISA bus float.  The
-                * assumption is that 0x80 is a non-existent port;
-                * which should be safe since include/asm/io.h also
-                * makes this assumption.
-                *
-                * Note: this is safe as long as MCR bit 4 is clear
-                * and the device is in "PC" mode.
-                */
-               scratch = serial_in(up, UART_IER);
-               serial_out(up, UART_IER, 0);
-#ifdef __i386__
-               outb(0xff, 0x080);
-#endif
-               /*
-                * Mask out IER[7:4] bits for test as some UARTs (e.g. TL
-                * 16C754B) allow only to modify them if an EFR bit is set.
-                */
-               scratch2 = serial_in(up, UART_IER) & 0x0f;
-               serial_out(up, UART_IER, 0x0F);
-#ifdef __i386__
-               outb(0, 0x080);
-#endif
-               scratch3 = serial_in(up, UART_IER) & 0x0f;
-               serial_out(up, UART_IER, scratch);
-               if (scratch2 != 0 || scratch3 != 0x0F) {
-                       /*
-                        * We failed; there's nothing here
-                        */
-                       spin_unlock_irqrestore(&port->lock, flags);
-                       DEBUG_AUTOCONF("IER test failed (%02x, %02x) ",
-                                      scratch2, scratch3);
-                       goto out;
-               }
-       }
-
-       save_mcr = serial_in(up, UART_MCR);
-       save_lcr = serial_in(up, UART_LCR);
-
-       /*
-        * Check to see if a UART is really there.  Certain broken
-        * internal modems based on the Rockwell chipset fail this
-        * test, because they apparently don't implement the loopback
-        * test mode.  So this test is skipped on the COM 1 through
-        * COM 4 ports.  This *should* be safe, since no board
-        * manufacturer would be stupid enough to design a board
-        * that conflicts with COM 1-4 --- we hope!
-        */
-       if (!(port->flags & UPF_SKIP_TEST)) {
-               serial_out(up, UART_MCR, UART_MCR_LOOP | 0x0A);
-               status1 = serial_in(up, UART_MSR) & 0xF0;
-               serial_out(up, UART_MCR, save_mcr);
-               if (status1 != 0x90) {
-                       spin_unlock_irqrestore(&port->lock, flags);
-                       DEBUG_AUTOCONF("LOOP test failed (%02x) ",
-                                      status1);
-                       goto out;
-               }
-       }
-
-       /*
-        * We're pretty sure there's a port here.  Lets find out what
-        * type of port it is.  The IIR top two bits allows us to find
-        * out if it's 8250 or 16450, 16550, 16550A or later.  This
-        * determines what we test for next.
-        *
-        * We also initialise the EFR (if any) to zero for later.  The
-        * EFR occupies the same register location as the FCR and IIR.
-        */
-       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
-       serial_out(up, UART_EFR, 0);
-       serial_out(up, UART_LCR, 0);
-
-       serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
-       scratch = serial_in(up, UART_IIR) >> 6;
-
-       switch (scratch) {
-       case 0:
-               autoconfig_8250(up);
-               break;
-       case 1:
-               port->type = PORT_UNKNOWN;
-               break;
-       case 2:
-               port->type = PORT_16550;
-               break;
-       case 3:
-               autoconfig_16550a(up);
-               break;
-       }
-
-#ifdef CONFIG_SERIAL_8250_RSA
-       /*
-        * Only probe for RSA ports if we got the region.
-        */
-       if (port->type == PORT_16550A && probeflags & PROBE_RSA) {
-               int i;
-
-               for (i = 0 ; i < probe_rsa_count; ++i) {
-                       if (probe_rsa[i] == port->iobase && __enable_rsa(up)) {
-                               port->type = PORT_RSA;
-                               break;
-                       }
-               }
-       }
-#endif
-
-       serial_out(up, UART_LCR, save_lcr);
-
-       port->fifosize = uart_config[up->port.type].fifo_size;
-       old_capabilities = up->capabilities; 
-       up->capabilities = uart_config[port->type].flags;
-       up->tx_loadsz = uart_config[port->type].tx_loadsz;
-
-       if (port->type == PORT_UNKNOWN)
-               goto out_lock;
-
-       /*
-        * Reset the UART.
-        */
-#ifdef CONFIG_SERIAL_8250_RSA
-       if (port->type == PORT_RSA)
-               serial_out(up, UART_RSA_FRR, 0);
-#endif
-       serial_out(up, UART_MCR, save_mcr);
-       serial8250_clear_fifos(up);
-       serial_in(up, UART_RX);
-       if (up->capabilities & UART_CAP_UUE)
-               serial_out(up, UART_IER, UART_IER_UUE);
-       else
-               serial_out(up, UART_IER, 0);
-
-out_lock:
-       spin_unlock_irqrestore(&port->lock, flags);
-       if (up->capabilities != old_capabilities) {
-               printk(KERN_WARNING
-                      "ttyS%d: detected caps %08x should be %08x\n",
-                      serial_index(port), old_capabilities,
-                      up->capabilities);
-       }
-out:
-       DEBUG_AUTOCONF("iir=%d ", scratch);
-       DEBUG_AUTOCONF("type=%s\n", uart_config[port->type].name);
-}
-
-static void autoconfig_irq(struct uart_8250_port *up)
-{
-       struct uart_port *port = &up->port;
-       unsigned char save_mcr, save_ier;
-       unsigned char save_ICP = 0;
-       unsigned int ICP = 0;
-       unsigned long irqs;
-       int irq;
-
-       if (port->flags & UPF_FOURPORT) {
-               ICP = (port->iobase & 0xfe0) | 0x1f;
-               save_ICP = inb_p(ICP);
-               outb_p(0x80, ICP);
-               inb_p(ICP);
-       }
-
-       /* forget possible initially masked and pending IRQ */
-       probe_irq_off(probe_irq_on());
-       save_mcr = serial_in(up, UART_MCR);
-       save_ier = serial_in(up, UART_IER);
-       serial_out(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2);
-
-       irqs = probe_irq_on();
-       serial_out(up, UART_MCR, 0);
-       udelay(10);
-       if (port->flags & UPF_FOURPORT) {
-               serial_out(up, UART_MCR,
-                           UART_MCR_DTR | UART_MCR_RTS);
-       } else {
-               serial_out(up, UART_MCR,
-                           UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
-       }
-       serial_out(up, UART_IER, 0x0f); /* enable all intrs */
-       serial_in(up, UART_LSR);
-       serial_in(up, UART_RX);
-       serial_in(up, UART_IIR);
-       serial_in(up, UART_MSR);
-       serial_out(up, UART_TX, 0xFF);
-       udelay(20);
-       irq = probe_irq_off(irqs);
-
-       serial_out(up, UART_MCR, save_mcr);
-       serial_out(up, UART_IER, save_ier);
-
-       if (port->flags & UPF_FOURPORT)
-               outb_p(save_ICP, ICP);
-
-       port->irq = (irq > 0) ? irq : 0;
-}
-
-static inline void __stop_tx(struct uart_8250_port *p)
-{
-       if (p->ier & UART_IER_THRI) {
-               p->ier &= ~UART_IER_THRI;
-               serial_out(p, UART_IER, p->ier);
-       }
-}
-
-static void serial8250_stop_tx(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-
-       __stop_tx(up);
-
-       /*
-        * We really want to stop the transmitter from sending.
-        */
-       if (port->type == PORT_16C950) {
-               up->acr |= UART_ACR_TXDIS;
-               serial_icr_write(up, UART_ACR, up->acr);
-       }
-}
-
-static void serial8250_start_tx(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-
-       if (up->dma && !serial8250_tx_dma(up)) {
-               return;
-       } else if (!(up->ier & UART_IER_THRI)) {
-               up->ier |= UART_IER_THRI;
-               serial_port_out(port, UART_IER, up->ier);
-
-               if (up->bugs & UART_BUG_TXEN) {
-                       unsigned char lsr;
-                       lsr = serial_in(up, UART_LSR);
-                       up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
-                       if (lsr & UART_LSR_TEMT)
-                               serial8250_tx_chars(up);
-               }
-       }
-
-       /*
-        * Re-enable the transmitter if we disabled it.
-        */
-       if (port->type == PORT_16C950 && up->acr & UART_ACR_TXDIS) {
-               up->acr &= ~UART_ACR_TXDIS;
-               serial_icr_write(up, UART_ACR, up->acr);
-       }
-}
-
-static void serial8250_stop_rx(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-
-       up->ier &= ~UART_IER_RLSI;
-       up->port.read_status_mask &= ~UART_LSR_DR;
-       serial_port_out(port, UART_IER, up->ier);
-}
-
-static void serial8250_enable_ms(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-
-       /* no MSR capabilities */
-       if (up->bugs & UART_BUG_NOMSR)
-               return;
-
-       up->ier |= UART_IER_MSI;
-       serial_port_out(port, UART_IER, up->ier);
-}
-
-/*
- * serial8250_rx_chars: processes according to the passed in LSR
- * value, and returns the remaining LSR bits not handled
- * by this Rx routine.
- */
-unsigned char
-serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr)
-{
-       struct uart_port *port = &up->port;
-       unsigned char ch;
-       int max_count = 256;
-       char flag;
-
-       do {
-               if (likely(lsr & UART_LSR_DR))
-                       ch = serial_in(up, UART_RX);
-               else
-                       /*
-                        * Intel 82571 has a Serial Over Lan device that will
-                        * set UART_LSR_BI without setting UART_LSR_DR when
-                        * it receives a break. To avoid reading from the
-                        * receive buffer without UART_LSR_DR bit set, we
-                        * just force the read character to be 0
-                        */
-                       ch = 0;
-
-               flag = TTY_NORMAL;
-               port->icount.rx++;
-
-               lsr |= up->lsr_saved_flags;
-               up->lsr_saved_flags = 0;
-
-               if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) {
-                       if (lsr & UART_LSR_BI) {
-                               lsr &= ~(UART_LSR_FE | UART_LSR_PE);
-                               port->icount.brk++;
-                               /*
-                                * We do the SysRQ and SAK checking
-                                * here because otherwise the break
-                                * may get masked by ignore_status_mask
-                                * or read_status_mask.
-                                */
-                               if (uart_handle_break(port))
-                                       goto ignore_char;
-                       } else if (lsr & UART_LSR_PE)
-                               port->icount.parity++;
-                       else if (lsr & UART_LSR_FE)
-                               port->icount.frame++;
-                       if (lsr & UART_LSR_OE)
-                               port->icount.overrun++;
-
-                       /*
-                        * Mask off conditions which should be ignored.
-                        */
-                       lsr &= port->read_status_mask;
-
-                       if (lsr & UART_LSR_BI) {
-                               DEBUG_INTR("handling break....");
-                               flag = TTY_BREAK;
-                       } else if (lsr & UART_LSR_PE)
-                               flag = TTY_PARITY;
-                       else if (lsr & UART_LSR_FE)
-                               flag = TTY_FRAME;
-               }
-               if (uart_handle_sysrq_char(port, ch))
-                       goto ignore_char;
-
-               uart_insert_char(port, lsr, UART_LSR_OE, ch, flag);
-
-ignore_char:
-               lsr = serial_in(up, UART_LSR);
-       } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0));
-       spin_unlock(&port->lock);
-       tty_flip_buffer_push(&port->state->port);
-       spin_lock(&port->lock);
-       return lsr;
-}
-EXPORT_SYMBOL_GPL(serial8250_rx_chars);
-
-void serial8250_tx_chars(struct uart_8250_port *up)
-{
-       struct uart_port *port = &up->port;
-       struct circ_buf *xmit = &port->state->xmit;
-       int count;
-
-       if (port->x_char) {
-               serial_out(up, UART_TX, port->x_char);
-               port->icount.tx++;
-               port->x_char = 0;
-               return;
-       }
-       if (uart_tx_stopped(port)) {
-               serial8250_stop_tx(port);
-               return;
-       }
-       if (uart_circ_empty(xmit)) {
-               __stop_tx(up);
-               return;
-       }
-
-       count = up->tx_loadsz;
-       do {
-               serial_out(up, UART_TX, xmit->buf[xmit->tail]);
-               xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-               port->icount.tx++;
-               if (uart_circ_empty(xmit))
-                       break;
-               if (up->capabilities & UART_CAP_HFIFO) {
-                       if ((serial_port_in(port, UART_LSR) & BOTH_EMPTY) !=
-                           BOTH_EMPTY)
-                               break;
-               }
-       } while (--count > 0);
-
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-               uart_write_wakeup(port);
-
-       DEBUG_INTR("THRE...");
-
-       if (uart_circ_empty(xmit))
-               __stop_tx(up);
-}
-EXPORT_SYMBOL_GPL(serial8250_tx_chars);
-
-unsigned int serial8250_modem_status(struct uart_8250_port *up)
-{
-       struct uart_port *port = &up->port;
-       unsigned int status = serial_in(up, UART_MSR);
-
-       status |= up->msr_saved_flags;
-       up->msr_saved_flags = 0;
-       if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI &&
-           port->state != NULL) {
-               if (status & UART_MSR_TERI)
-                       port->icount.rng++;
-               if (status & UART_MSR_DDSR)
-                       port->icount.dsr++;
-               if (status & UART_MSR_DDCD)
-                       uart_handle_dcd_change(port, status & UART_MSR_DCD);
-               if (status & UART_MSR_DCTS)
-                       uart_handle_cts_change(port, status & UART_MSR_CTS);
-
-               wake_up_interruptible(&port->state->port.delta_msr_wait);
-       }
-
-       return status;
-}
-EXPORT_SYMBOL_GPL(serial8250_modem_status);
-
-/*
- * This handles the interrupt from one port.
- */
-int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
-{
-       unsigned char status;
-       unsigned long flags;
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-       int dma_err = 0;
-
-       if (iir & UART_IIR_NO_INT)
-               return 0;
-
-       spin_lock_irqsave(&port->lock, flags);
-
-       status = serial_port_in(port, UART_LSR);
-
-       DEBUG_INTR("status = %x...", status);
-
-       if (status & (UART_LSR_DR | UART_LSR_BI)) {
-               if (up->dma)
-                       dma_err = serial8250_rx_dma(up, iir);
-
-               if (!up->dma || dma_err)
-                       status = serial8250_rx_chars(up, status);
-       }
-       serial8250_modem_status(up);
-       if (status & UART_LSR_THRE)
-               serial8250_tx_chars(up);
-
-       spin_unlock_irqrestore(&port->lock, flags);
-       return 1;
-}
-EXPORT_SYMBOL_GPL(serial8250_handle_irq);
-
-static int serial8250_default_handle_irq(struct uart_port *port)
-{
-       unsigned int iir = serial_port_in(port, UART_IIR);
-
-       return serial8250_handle_irq(port, iir);
-}
-
-/*
- * These Exar UARTs have an extra interrupt indicator that could
- * fire for a few unimplemented interrupts.  One of which is a
- * wakeup event when coming out of sleep.  Put this here just
- * to be on the safe side that these interrupts don't go unhandled.
- */
-static int exar_handle_irq(struct uart_port *port)
-{
-       unsigned char int0, int1, int2, int3;
-       unsigned int iir = serial_port_in(port, UART_IIR);
-       int ret;
-
-       ret = serial8250_handle_irq(port, iir);
-
-       if ((port->type == PORT_XR17V35X) ||
-          (port->type == PORT_XR17D15X)) {
-               int0 = serial_port_in(port, 0x80);
-               int1 = serial_port_in(port, 0x81);
-               int2 = serial_port_in(port, 0x82);
-               int3 = serial_port_in(port, 0x83);
-       }
-
-       return ret;
-}
-
-/*
- * This is the serial driver's interrupt routine.
- *
- * Arjan thinks the old way was overly complex, so it got simplified.
- * Alan disagrees, saying that need the complexity to handle the weird
- * nature of ISA shared interrupts.  (This is a special exception.)
- *
- * In order to handle ISA shared interrupts properly, we need to check
- * that all ports have been serviced, and therefore the ISA interrupt
- * line has been de-asserted.
- *
- * This means we need to loop through all ports. checking that they
- * don't have an interrupt pending.
- */
-static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
-{
-       struct irq_info *i = dev_id;
-       struct list_head *l, *end = NULL;
-       int pass_counter = 0, handled = 0;
-
-       DEBUG_INTR("serial8250_interrupt(%d)...", irq);
-
-       spin_lock(&i->lock);
-
-       l = i->head;
-       do {
-               struct uart_8250_port *up;
-               struct uart_port *port;
-
-               up = list_entry(l, struct uart_8250_port, list);
-               port = &up->port;
-
-               if (port->handle_irq(port)) {
-                       handled = 1;
-                       end = NULL;
-               } else if (end == NULL)
-                       end = l;
-
-               l = l->next;
-
-               if (l == i->head && pass_counter++ > PASS_LIMIT) {
-                       /* If we hit this, we're dead. */
-                       printk_ratelimited(KERN_ERR
-                               "serial8250: too much work for irq%d\n", irq);
-                       break;
-               }
-       } while (l != end);
-
-       spin_unlock(&i->lock);
-
-       DEBUG_INTR("end.\n");
-
-       return IRQ_RETVAL(handled);
-}
-
-/*
- * To support ISA shared interrupts, we need to have one interrupt
- * handler that ensures that the IRQ line has been deasserted
- * before returning.  Failing to do this will result in the IRQ
- * line being stuck active, and, since ISA irqs are edge triggered,
- * no more IRQs will be seen.
- */
-static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up)
-{
-       spin_lock_irq(&i->lock);
-
-       if (!list_empty(i->head)) {
-               if (i->head == &up->list)
-                       i->head = i->head->next;
-               list_del(&up->list);
-       } else {
-               BUG_ON(i->head != &up->list);
-               i->head = NULL;
-       }
-       spin_unlock_irq(&i->lock);
-       /* List empty so throw away the hash node */
-       if (i->head == NULL) {
-               hlist_del(&i->node);
-               kfree(i);
-       }
-}
-
-static int serial_link_irq_chain(struct uart_8250_port *up)
-{
-       struct hlist_head *h;
-       struct hlist_node *n;
-       struct irq_info *i;
-       int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0;
-
-       mutex_lock(&hash_mutex);
-
-       h = &irq_lists[up->port.irq % NR_IRQ_HASH];
-
-       hlist_for_each(n, h) {
-               i = hlist_entry(n, struct irq_info, node);
-               if (i->irq == up->port.irq)
-                       break;
-       }
-
-       if (n == NULL) {
-               i = kzalloc(sizeof(struct irq_info), GFP_KERNEL);
-               if (i == NULL) {
-                       mutex_unlock(&hash_mutex);
-                       return -ENOMEM;
-               }
-               spin_lock_init(&i->lock);
-               i->irq = up->port.irq;
-               hlist_add_head(&i->node, h);
-       }
-       mutex_unlock(&hash_mutex);
-
-       spin_lock_irq(&i->lock);
-
-       if (i->head) {
-               list_add(&up->list, i->head);
-               spin_unlock_irq(&i->lock);
-
-               ret = 0;
-       } else {
-               INIT_LIST_HEAD(&up->list);
-               i->head = &up->list;
-               spin_unlock_irq(&i->lock);
-               irq_flags |= up->port.irqflags;
-               ret = request_irq(up->port.irq, serial8250_interrupt,
-                                 irq_flags, "serial", i);
-               if (ret < 0)
-                       serial_do_unlink(i, up);
-       }
-
-       return ret;
-}
-
-static void serial_unlink_irq_chain(struct uart_8250_port *up)
-{
-       struct irq_info *i;
-       struct hlist_node *n;
-       struct hlist_head *h;
-
-       mutex_lock(&hash_mutex);
-
-       h = &irq_lists[up->port.irq % NR_IRQ_HASH];
-
-       hlist_for_each(n, h) {
-               i = hlist_entry(n, struct irq_info, node);
-               if (i->irq == up->port.irq)
-                       break;
-       }
-
-       BUG_ON(n == NULL);
-       BUG_ON(i->head == NULL);
-
-       if (list_empty(i->head))
-               free_irq(up->port.irq, i);
-
-       serial_do_unlink(i, up);
-       mutex_unlock(&hash_mutex);
-}
-
-/*
- * This function is used to handle ports that do not have an
- * interrupt.  This doesn't work very well for 16450's, but gives
- * barely passable results for a 16550A.  (Although at the expense
- * of much CPU overhead).
- */
-static void serial8250_timeout(unsigned long data)
-{
-       struct uart_8250_port *up = (struct uart_8250_port *)data;
-
-       up->port.handle_irq(&up->port);
-       mod_timer(&up->timer, jiffies + uart_poll_timeout(&up->port));
-}
-
-static void serial8250_backup_timeout(unsigned long data)
-{
-       struct uart_8250_port *up = (struct uart_8250_port *)data;
-       unsigned int iir, ier = 0, lsr;
-       unsigned long flags;
-
-       spin_lock_irqsave(&up->port.lock, flags);
-
-       /*
-        * Must disable interrupts or else we risk racing with the interrupt
-        * based handler.
-        */
-       if (up->port.irq) {
-               ier = serial_in(up, UART_IER);
-               serial_out(up, UART_IER, 0);
-       }
-
-       iir = serial_in(up, UART_IIR);
-
-       /*
-        * This should be a safe test for anyone who doesn't trust the
-        * IIR bits on their UART, but it's specifically designed for
-        * the "Diva" UART used on the management processor on many HP
-        * ia64 and parisc boxes.
-        */
-       lsr = serial_in(up, UART_LSR);
-       up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
-       if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
-           (!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) &&
-           (lsr & UART_LSR_THRE)) {
-               iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
-               iir |= UART_IIR_THRI;
-       }
-
-       if (!(iir & UART_IIR_NO_INT))
-               serial8250_tx_chars(up);
-
-       if (up->port.irq)
-               serial_out(up, UART_IER, ier);
-
-       spin_unlock_irqrestore(&up->port.lock, flags);
-
-       /* Standard timer interval plus 0.2s to keep the port running */
-       mod_timer(&up->timer,
-               jiffies + uart_poll_timeout(&up->port) + HZ / 5);
-}
-
-static unsigned int serial8250_tx_empty(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-       unsigned long flags;
-       unsigned int lsr;
-
-       spin_lock_irqsave(&port->lock, flags);
-       lsr = serial_port_in(port, UART_LSR);
-       up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
-       spin_unlock_irqrestore(&port->lock, flags);
-
-       return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0;
-}
-
-static unsigned int serial8250_get_mctrl(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-       unsigned int status;
-       unsigned int ret;
-
-       status = serial8250_modem_status(up);
-
-       ret = 0;
-       if (status & UART_MSR_DCD)
-               ret |= TIOCM_CAR;
-       if (status & UART_MSR_RI)
-               ret |= TIOCM_RNG;
-       if (status & UART_MSR_DSR)
-               ret |= TIOCM_DSR;
-       if (status & UART_MSR_CTS)
-               ret |= TIOCM_CTS;
-       return ret;
-}
-
-static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-       unsigned char mcr = 0;
-
-       if (mctrl & TIOCM_RTS)
-               mcr |= UART_MCR_RTS;
-       if (mctrl & TIOCM_DTR)
-               mcr |= UART_MCR_DTR;
-       if (mctrl & TIOCM_OUT1)
-               mcr |= UART_MCR_OUT1;
-       if (mctrl & TIOCM_OUT2)
-               mcr |= UART_MCR_OUT2;
-       if (mctrl & TIOCM_LOOP)
-               mcr |= UART_MCR_LOOP;
-
-       mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr;
-
-       serial_port_out(port, UART_MCR, mcr);
-}
-
-static void serial8250_break_ctl(struct uart_port *port, int break_state)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-       unsigned long flags;
-
-       spin_lock_irqsave(&port->lock, flags);
-       if (break_state == -1)
-               up->lcr |= UART_LCR_SBC;
-       else
-               up->lcr &= ~UART_LCR_SBC;
-       serial_port_out(port, UART_LCR, up->lcr);
-       spin_unlock_irqrestore(&port->lock, flags);
-}
-
-/*
- *     Wait for transmitter & holding register to empty
- */
-static void wait_for_xmitr(struct uart_8250_port *up, int bits)
-{
-       unsigned int status, tmout = 10000;
-
-       /* Wait up to 10ms for the character(s) to be sent. */
-       for (;;) {
-               status = serial_in(up, UART_LSR);
-
-               up->lsr_saved_flags |= status & LSR_SAVE_FLAGS;
-
-               if ((status & bits) == bits)
-                       break;
-               if (--tmout == 0)
-                       break;
-               udelay(1);
-       }
-
-       /* Wait up to 1s for flow control if necessary */
-       if (up->port.flags & UPF_CONS_FLOW) {
-               unsigned int tmout;
-               for (tmout = 1000000; tmout; tmout--) {
-                       unsigned int msr = serial_in(up, UART_MSR);
-                       up->msr_saved_flags |= msr & MSR_SAVE_FLAGS;
-                       if (msr & UART_MSR_CTS)
-                               break;
-                       udelay(1);
-                       touch_nmi_watchdog();
-               }
-       }
-}
-
-#ifdef CONFIG_CONSOLE_POLL
-/*
- * Console polling routines for writing and reading from the uart while
- * in an interrupt or debug context.
- */
-
-static int serial8250_get_poll_char(struct uart_port *port)
-{
-       unsigned char lsr = serial_port_in(port, UART_LSR);
-
-       if (!(lsr & UART_LSR_DR))
-               return NO_POLL_CHAR;
-
-       return serial_port_in(port, UART_RX);
-}
-
-
-static void serial8250_put_poll_char(struct uart_port *port,
-                        unsigned char c)
-{
-       unsigned int ier;
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-
-       /*
-        *      First save the IER then disable the interrupts
-        */
-       ier = serial_port_in(port, UART_IER);
-       if (up->capabilities & UART_CAP_UUE)
-               serial_port_out(port, UART_IER, UART_IER_UUE);
-       else
-               serial_port_out(port, UART_IER, 0);
-
-       wait_for_xmitr(up, BOTH_EMPTY);
-       /*
-        *      Send the character out.
-        *      If a LF, also do CR...
-        */
-       serial_port_out(port, UART_TX, c);
-       if (c == 10) {
-               wait_for_xmitr(up, BOTH_EMPTY);
-               serial_port_out(port, UART_TX, 13);
-       }
-
-       /*
-        *      Finally, wait for transmitter to become empty
-        *      and restore the IER
-        */
-       wait_for_xmitr(up, BOTH_EMPTY);
-       serial_port_out(port, UART_IER, ier);
-}
-
-#endif /* CONFIG_CONSOLE_POLL */
-
-static int serial8250_startup(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-       unsigned long flags;
-       unsigned char lsr, iir;
-       int retval;
-
-       if (port->type == PORT_8250_CIR)
-               return -ENODEV;
-
-       if (!port->fifosize)
-               port->fifosize = uart_config[port->type].fifo_size;
-       if (!up->tx_loadsz)
-               up->tx_loadsz = uart_config[port->type].tx_loadsz;
-       if (!up->capabilities)
-               up->capabilities = uart_config[port->type].flags;
-       up->mcr = 0;
-
-       if (port->iotype != up->cur_iotype)
-               set_io_from_upio(port);
-
-       if (port->type == PORT_16C950) {
-               /* Wake up and initialize UART */
-               up->acr = 0;
-               serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B);
-               serial_port_out(port, UART_EFR, UART_EFR_ECB);
-               serial_port_out(port, UART_IER, 0);
-               serial_port_out(port, UART_LCR, 0);
-               serial_icr_write(up, UART_CSR, 0); /* Reset the UART */
-               serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B);
-               serial_port_out(port, UART_EFR, UART_EFR_ECB);
-               serial_port_out(port, UART_LCR, 0);
-       }
-
-#ifdef CONFIG_SERIAL_8250_RSA
-       /*
-        * If this is an RSA port, see if we can kick it up to the
-        * higher speed clock.
-        */
-       enable_rsa(up);
-#endif
-
-       /*
-        * Clear the FIFO buffers and disable them.
-        * (they will be reenabled in set_termios())
-        */
-       serial8250_clear_fifos(up);
-
-       /*
-        * Clear the interrupt registers.
-        */
-       serial_port_in(port, UART_LSR);
-       serial_port_in(port, UART_RX);
-       serial_port_in(port, UART_IIR);
-       serial_port_in(port, UART_MSR);
-
-       /*
-        * At this point, there's no way the LSR could still be 0xff;
-        * if it is, then bail out, because there's likely no UART
-        * here.
-        */
-       if (!(port->flags & UPF_BUGGY_UART) &&
-           (serial_port_in(port, UART_LSR) == 0xff)) {
-               printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n",
-                                  serial_index(port));
-               return -ENODEV;
-       }
-
-       /*
-        * For a XR16C850, we need to set the trigger levels
-        */
-       if (port->type == PORT_16850) {
-               unsigned char fctr;
-
-               serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
-
-               fctr = serial_in(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX);
-               serial_port_out(port, UART_FCTR,
-                               fctr | UART_FCTR_TRGD | UART_FCTR_RX);
-               serial_port_out(port, UART_TRG, UART_TRG_96);
-               serial_port_out(port, UART_FCTR,
-                               fctr | UART_FCTR_TRGD | UART_FCTR_TX);
-               serial_port_out(port, UART_TRG, UART_TRG_96);
-
-               serial_port_out(port, UART_LCR, 0);
-       }
-
-       if (port->irq) {
-               unsigned char iir1;
-               /*
-                * Test for UARTs that do not reassert THRE when the
-                * transmitter is idle and the interrupt has already
-                * been cleared.  Real 16550s should always reassert
-                * this interrupt whenever the transmitter is idle and
-                * the interrupt is enabled.  Delays are necessary to
-                * allow register changes to become visible.
-                */
-               spin_lock_irqsave(&port->lock, flags);
-               if (up->port.irqflags & IRQF_SHARED)
-                       disable_irq_nosync(port->irq);
-
-               wait_for_xmitr(up, UART_LSR_THRE);
-               serial_port_out_sync(port, UART_IER, UART_IER_THRI);
-               udelay(1); /* allow THRE to set */
-               iir1 = serial_port_in(port, UART_IIR);
-               serial_port_out(port, UART_IER, 0);
-               serial_port_out_sync(port, UART_IER, UART_IER_THRI);
-               udelay(1); /* allow a working UART time to re-assert THRE */
-               iir = serial_port_in(port, UART_IIR);
-               serial_port_out(port, UART_IER, 0);
-
-               if (port->irqflags & IRQF_SHARED)
-                       enable_irq(port->irq);
-               spin_unlock_irqrestore(&port->lock, flags);
-
-               /*
-                * If the interrupt is not reasserted, or we otherwise
-                * don't trust the iir, setup a timer to kick the UART
-                * on a regular basis.
-                */
-               if ((!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) ||
-                   up->port.flags & UPF_BUG_THRE) {
-                       up->bugs |= UART_BUG_THRE;
-                       pr_debug("ttyS%d - using backup timer\n",
-                                serial_index(port));
-               }
-       }
-
-       /*
-        * The above check will only give an accurate result the first time
-        * the port is opened so this value needs to be preserved.
-        */
-       if (up->bugs & UART_BUG_THRE) {
-               up->timer.function = serial8250_backup_timeout;
-               up->timer.data = (unsigned long)up;
-               mod_timer(&up->timer, jiffies +
-                       uart_poll_timeout(port) + HZ / 5);
-       }
-
-       /*
-        * If the "interrupt" for this port doesn't correspond with any
-        * hardware interrupt, we use a timer-based system.  The original
-        * driver used to do this with IRQ0.
-        */
-       if (!port->irq) {
-               up->timer.data = (unsigned long)up;
-               mod_timer(&up->timer, jiffies + uart_poll_timeout(port));
-       } else {
-               retval = serial_link_irq_chain(up);
-               if (retval)
-                       return retval;
-       }
-
-       /*
-        * Now, initialize the UART
-        */
-       serial_port_out(port, UART_LCR, UART_LCR_WLEN8);
-
-       spin_lock_irqsave(&port->lock, flags);
-       if (up->port.flags & UPF_FOURPORT) {
-               if (!up->port.irq)
-                       up->port.mctrl |= TIOCM_OUT1;
-       } else
-               /*
-                * Most PC uarts need OUT2 raised to enable interrupts.
-                */
-               if (port->irq)
-                       up->port.mctrl |= TIOCM_OUT2;
-
-       serial8250_set_mctrl(port, port->mctrl);
-
-       /* Serial over Lan (SoL) hack:
-          Intel 8257x Gigabit ethernet chips have a
-          16550 emulation, to be used for Serial Over Lan.
-          Those chips take a longer time than a normal
-          serial device to signalize that a transmission
-          data was queued. Due to that, the above test generally
-          fails. One solution would be to delay the reading of
-          iir. However, this is not reliable, since the timeout
-          is variable. So, let's just don't test if we receive
-          TX irq. This way, we'll never enable UART_BUG_TXEN.
-        */
-       if (skip_txen_test || up->port.flags & UPF_NO_TXEN_TEST)
-               goto dont_test_tx_en;
-
-       /*
-        * Do a quick test to see if we receive an
-        * interrupt when we enable the TX irq.
-        */
-       serial_port_out(port, UART_IER, UART_IER_THRI);
-       lsr = serial_port_in(port, UART_LSR);
-       iir = serial_port_in(port, UART_IIR);
-       serial_port_out(port, UART_IER, 0);
-
-       if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) {
-               if (!(up->bugs & UART_BUG_TXEN)) {
-                       up->bugs |= UART_BUG_TXEN;
-                       pr_debug("ttyS%d - enabling bad tx status workarounds\n",
-                                serial_index(port));
-               }
-       } else {
-               up->bugs &= ~UART_BUG_TXEN;
-       }
-
-dont_test_tx_en:
-       spin_unlock_irqrestore(&port->lock, flags);
-
-       /*
-        * Clear the interrupt registers again for luck, and clear the
-        * saved flags to avoid getting false values from polling
-        * routines or the previous session.
-        */
-       serial_port_in(port, UART_LSR);
-       serial_port_in(port, UART_RX);
-       serial_port_in(port, UART_IIR);
-       serial_port_in(port, UART_MSR);
-       up->lsr_saved_flags = 0;
-       up->msr_saved_flags = 0;
-
-       /*
-        * Request DMA channels for both RX and TX.
-        */
-       if (up->dma) {
-               retval = serial8250_request_dma(up);
-               if (retval) {
-                       pr_warn_ratelimited("ttyS%d - failed to request DMA\n",
-                                           serial_index(port));
-                       up->dma = NULL;
-               }
-       }
-
-       /*
-        * Finally, enable interrupts.  Note: Modem status interrupts
-        * are set via set_termios(), which will be occurring imminently
-        * anyway, so we don't enable them here.
-        */
-       up->ier = UART_IER_RLSI | UART_IER_RDI;
-       serial_port_out(port, UART_IER, up->ier);
-
-       if (port->flags & UPF_FOURPORT) {
-               unsigned int icp;
-               /*
-                * Enable interrupts on the AST Fourport board
-                */
-               icp = (port->iobase & 0xfe0) | 0x01f;
-               outb_p(0x80, icp);
-               inb_p(icp);
-       }
-
-       return 0;
-}
-
-static void serial8250_shutdown(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-       unsigned long flags;
-
-       /*
-        * Disable interrupts from this port
-        */
-       up->ier = 0;
-       serial_port_out(port, UART_IER, 0);
-
-       if (up->dma)
-               serial8250_release_dma(up);
-
-       spin_lock_irqsave(&port->lock, flags);
-       if (port->flags & UPF_FOURPORT) {
-               /* reset interrupts on the AST Fourport board */
-               inb((port->iobase & 0xfe0) | 0x1f);
-               port->mctrl |= TIOCM_OUT1;
-       } else
-               port->mctrl &= ~TIOCM_OUT2;
-
-       serial8250_set_mctrl(port, port->mctrl);
-       spin_unlock_irqrestore(&port->lock, flags);
-
-       /*
-        * Disable break condition and FIFOs
-        */
-       serial_port_out(port, UART_LCR,
-                       serial_port_in(port, UART_LCR) & ~UART_LCR_SBC);
-       serial8250_clear_fifos(up);
-
-#ifdef CONFIG_SERIAL_8250_RSA
-       /*
-        * Reset the RSA board back to 115kbps compat mode.
-        */
-       disable_rsa(up);
-#endif
-
-       /*
-        * Read data port to reset things, and then unlink from
-        * the IRQ chain.
-        */
-       serial_port_in(port, UART_RX);
-
-       del_timer_sync(&up->timer);
-       up->timer.function = serial8250_timeout;
-       if (port->irq)
-               serial_unlink_irq_chain(up);
-}
-
-static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud)
-{
-       unsigned int quot;
-
-       /*
-        * Handle magic divisors for baud rates above baud_base on
-        * SMSC SuperIO chips.
-        */
-       if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
-           baud == (port->uartclk/4))
-               quot = 0x8001;
-       else if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
-                baud == (port->uartclk/8))
-               quot = 0x8002;
-       else
-               quot = uart_get_divisor(port, baud);
-
-       return quot;
-}
-
-void
-serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
-                         struct ktermios *old)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-       unsigned char cval, fcr = 0;
-       unsigned long flags;
-       unsigned int baud, quot;
-       int fifo_bug = 0;
-
-       switch (termios->c_cflag & CSIZE) {
-       case CS5:
-               cval = UART_LCR_WLEN5;
-               break;
-       case CS6:
-               cval = UART_LCR_WLEN6;
-               break;
-       case CS7:
-               cval = UART_LCR_WLEN7;
-               break;
-       default:
-       case CS8:
-               cval = UART_LCR_WLEN8;
-               break;
-       }
-
-       if (termios->c_cflag & CSTOPB)
-               cval |= UART_LCR_STOP;
-       if (termios->c_cflag & PARENB) {
-               cval |= UART_LCR_PARITY;
-               if (up->bugs & UART_BUG_PARITY)
-                       fifo_bug = 1;
-       }
-       if (!(termios->c_cflag & PARODD))
-               cval |= UART_LCR_EPAR;
-#ifdef CMSPAR
-       if (termios->c_cflag & CMSPAR)
-               cval |= UART_LCR_SPAR;
-#endif
-
-       /*
-        * Ask the core to calculate the divisor for us.
-        */
-       baud = uart_get_baud_rate(port, termios, old,
-                                 port->uartclk / 16 / 0xffff,
-                                 port->uartclk / 16);
-       quot = serial8250_get_divisor(port, baud);
-
-       /*
-        * Oxford Semi 952 rev B workaround
-        */
-       if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0)
-               quot++;
-
-       if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) {
-               fcr = uart_config[port->type].fcr;
-               if (baud < 2400 || fifo_bug) {
-                       fcr &= ~UART_FCR_TRIGGER_MASK;
-                       fcr |= UART_FCR_TRIGGER_1;
-               }
-       }
-
-       /*
-        * MCR-based auto flow control.  When AFE is enabled, RTS will be
-        * deasserted when the receive FIFO contains more characters than
-        * the trigger, or the MCR RTS bit is cleared.  In the case where
-        * the remote UART is not using CTS auto flow control, we must
-        * have sufficient FIFO entries for the latency of the remote
-        * UART to respond.  IOW, at least 32 bytes of FIFO.
-        */
-       if (up->capabilities & UART_CAP_AFE && port->fifosize >= 32) {
-               up->mcr &= ~UART_MCR_AFE;
-               if (termios->c_cflag & CRTSCTS)
-                       up->mcr |= UART_MCR_AFE;
-       }
-
-       /*
-        * Ok, we're now changing the port state.  Do it with
-        * interrupts disabled.
-        */
-       spin_lock_irqsave(&port->lock, flags);
-
-       /*
-        * Update the per-port timeout.
-        */
-       uart_update_timeout(port, termios->c_cflag, baud);
-
-       port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
-       if (termios->c_iflag & INPCK)
-               port->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
-       if (termios->c_iflag & (BRKINT | PARMRK))
-               port->read_status_mask |= UART_LSR_BI;
-
-       /*
-        * Characteres to ignore
-        */
-       port->ignore_status_mask = 0;
-       if (termios->c_iflag & IGNPAR)
-               port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
-       if (termios->c_iflag & IGNBRK) {
-               port->ignore_status_mask |= UART_LSR_BI;
-               /*
-                * If we're ignoring parity and break indicators,
-                * ignore overruns too (for real raw support).
-                */
-               if (termios->c_iflag & IGNPAR)
-                       port->ignore_status_mask |= UART_LSR_OE;
-       }
-
-       /*
-        * ignore all characters if CREAD is not set
-        */
-       if ((termios->c_cflag & CREAD) == 0)
-               port->ignore_status_mask |= UART_LSR_DR;
-
-       /*
-        * CTS flow control flag and modem status interrupts
-        */
-       up->ier &= ~UART_IER_MSI;
-       if (!(up->bugs & UART_BUG_NOMSR) &&
-                       UART_ENABLE_MS(&up->port, termios->c_cflag))
-               up->ier |= UART_IER_MSI;
-       if (up->capabilities & UART_CAP_UUE)
-               up->ier |= UART_IER_UUE;
-       if (up->capabilities & UART_CAP_RTOIE)
-               up->ier |= UART_IER_RTOIE;
-
-       serial_port_out(port, UART_IER, up->ier);
-
-       if (up->capabilities & UART_CAP_EFR) {
-               unsigned char efr = 0;
-               /*
-                * TI16C752/Startech hardware flow control.  FIXME:
-                * - TI16C752 requires control thresholds to be set.
-                * - UART_MCR_RTS is ineffective if auto-RTS mode is enabled.
-                */
-               if (termios->c_cflag & CRTSCTS)
-                       efr |= UART_EFR_CTS;
-
-               serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B);
-               if (port->flags & UPF_EXAR_EFR)
-                       serial_port_out(port, UART_XR_EFR, efr);
-               else
-                       serial_port_out(port, UART_EFR, efr);
-       }
-
-       /* Workaround to enable 115200 baud on OMAP1510 internal ports */
-       if (is_omap1510_8250(up)) {
-               if (baud == 115200) {
-                       quot = 1;
-                       serial_port_out(port, UART_OMAP_OSC_12M_SEL, 1);
-               } else
-                       serial_port_out(port, UART_OMAP_OSC_12M_SEL, 0);
-       }
-
-       /*
-        * For NatSemi, switch to bank 2 not bank 1, to avoid resetting EXCR2,
-        * otherwise just set DLAB
-        */
-       if (up->capabilities & UART_NATSEMI)
-               serial_port_out(port, UART_LCR, 0xe0);
-       else
-               serial_port_out(port, UART_LCR, cval | UART_LCR_DLAB);
-
-       serial_dl_write(up, quot);
-
-       /*
-        * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
-        * is written without DLAB set, this mode will be disabled.
-        */
-       if (port->type == PORT_16750)
-               serial_port_out(port, UART_FCR, fcr);
-
-       serial_port_out(port, UART_LCR, cval);          /* reset DLAB */
-       up->lcr = cval;                                 /* Save LCR */
-       if (port->type != PORT_16750) {
-               /* emulated UARTs (Lucent Venus 167x) need two steps */
-               if (fcr & UART_FCR_ENABLE_FIFO)
-                       serial_port_out(port, UART_FCR, UART_FCR_ENABLE_FIFO);
-               serial_port_out(port, UART_FCR, fcr);           /* set fcr */
-       }
-       serial8250_set_mctrl(port, port->mctrl);
-       spin_unlock_irqrestore(&port->lock, flags);
-       /* Don't rewrite B0 */
-       if (tty_termios_baud_rate(termios))
-               tty_termios_encode_baud_rate(termios, baud, baud);
-}
-EXPORT_SYMBOL(serial8250_do_set_termios);
-
-static void
-serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
-                      struct ktermios *old)
-{
-       if (port->set_termios)
-               port->set_termios(port, termios, old);
-       else
-               serial8250_do_set_termios(port, termios, old);
-}
-
-static void
-serial8250_set_ldisc(struct uart_port *port, int new)
-{
-       if (new == N_PPS) {
-               port->flags |= UPF_HARDPPS_CD;
-               serial8250_enable_ms(port);
-       } else
-               port->flags &= ~UPF_HARDPPS_CD;
-}
-
-
-void serial8250_do_pm(struct uart_port *port, unsigned int state,
-                     unsigned int oldstate)
-{
-       struct uart_8250_port *p =
-               container_of(port, struct uart_8250_port, port);
-
-       serial8250_set_sleep(p, state != 0);
-}
-EXPORT_SYMBOL(serial8250_do_pm);
-
-static void
-serial8250_pm(struct uart_port *port, unsigned int state,
-             unsigned int oldstate)
-{
-       if (port->pm)
-               port->pm(port, state, oldstate);
-       else
-               serial8250_do_pm(port, state, oldstate);
-}
-
-static unsigned int serial8250_port_size(struct uart_8250_port *pt)
-{
-       if (pt->port.iotype == UPIO_AU)
-               return 0x1000;
-       if (is_omap1_8250(pt))
-               return 0x16 << pt->port.regshift;
-
-       return 8 << pt->port.regshift;
-}
-
-/*
- * Resource handling.
- */
-static int serial8250_request_std_resource(struct uart_8250_port *up)
-{
-       unsigned int size = serial8250_port_size(up);
-       struct uart_port *port = &up->port;
-       int ret = 0;
-
-       switch (port->iotype) {
-       case UPIO_AU:
-       case UPIO_TSI:
-       case UPIO_MEM32:
-       case UPIO_MEM:
-               if (!port->mapbase)
-                       break;
-
-               if (!request_mem_region(port->mapbase, size, "serial")) {
-                       ret = -EBUSY;
-                       break;
-               }
-
-               if (port->flags & UPF_IOREMAP) {
-                       port->membase = ioremap_nocache(port->mapbase, size);
-                       if (!port->membase) {
-                               release_mem_region(port->mapbase, size);
-                               ret = -ENOMEM;
-                       }
-               }
-               break;
-
-       case UPIO_HUB6:
-       case UPIO_PORT:
-               if (!request_region(port->iobase, size, "serial"))
-                       ret = -EBUSY;
-               break;
-       }
-       return ret;
-}
-
-static void serial8250_release_std_resource(struct uart_8250_port *up)
-{
-       unsigned int size = serial8250_port_size(up);
-       struct uart_port *port = &up->port;
-
-       switch (port->iotype) {
-       case UPIO_AU:
-       case UPIO_TSI:
-       case UPIO_MEM32:
-       case UPIO_MEM:
-               if (!port->mapbase)
-                       break;
-
-               if (port->flags & UPF_IOREMAP) {
-                       iounmap(port->membase);
-                       port->membase = NULL;
-               }
-
-               release_mem_region(port->mapbase, size);
-               break;
-
-       case UPIO_HUB6:
-       case UPIO_PORT:
-               release_region(port->iobase, size);
-               break;
-       }
-}
-
-static int serial8250_request_rsa_resource(struct uart_8250_port *up)
-{
-       unsigned long start = UART_RSA_BASE << up->port.regshift;
-       unsigned int size = 8 << up->port.regshift;
-       struct uart_port *port = &up->port;
-       int ret = -EINVAL;
-
-       switch (port->iotype) {
-       case UPIO_HUB6:
-       case UPIO_PORT:
-               start += port->iobase;
-               if (request_region(start, size, "serial-rsa"))
-                       ret = 0;
-               else
-                       ret = -EBUSY;
-               break;
-       }
-
-       return ret;
-}
-
-static void serial8250_release_rsa_resource(struct uart_8250_port *up)
-{
-       unsigned long offset = UART_RSA_BASE << up->port.regshift;
-       unsigned int size = 8 << up->port.regshift;
-       struct uart_port *port = &up->port;
-
-       switch (port->iotype) {
-       case UPIO_HUB6:
-       case UPIO_PORT:
-               release_region(port->iobase + offset, size);
-               break;
-       }
-}
-
-static void serial8250_release_port(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-
-       serial8250_release_std_resource(up);
-       if (port->type == PORT_RSA)
-               serial8250_release_rsa_resource(up);
-}
-
-static int serial8250_request_port(struct uart_port *port)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-       int ret;
-
-       if (port->type == PORT_8250_CIR)
-               return -ENODEV;
-
-       ret = serial8250_request_std_resource(up);
-       if (ret == 0 && port->type == PORT_RSA) {
-               ret = serial8250_request_rsa_resource(up);
-               if (ret < 0)
-                       serial8250_release_std_resource(up);
-       }
-
-       return ret;
-}
-
-static void serial8250_config_port(struct uart_port *port, int flags)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-       int probeflags = PROBE_ANY;
-       int ret;
-
-       if (port->type == PORT_8250_CIR)
-               return;
-
-       /*
-        * Find the region that we can probe for.  This in turn
-        * tells us whether we can probe for the type of port.
-        */
-       ret = serial8250_request_std_resource(up);
-       if (ret < 0)
-               return;
-
-       ret = serial8250_request_rsa_resource(up);
-       if (ret < 0)
-               probeflags &= ~PROBE_RSA;
-
-       if (port->iotype != up->cur_iotype)
-               set_io_from_upio(port);
-
-       if (flags & UART_CONFIG_TYPE)
-               autoconfig(up, probeflags);
-
-       /* if access method is AU, it is a 16550 with a quirk */
-       if (port->type == PORT_16550A && port->iotype == UPIO_AU)
-               up->bugs |= UART_BUG_NOMSR;
-
-       if (port->type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
-               autoconfig_irq(up);
-
-       if (port->type != PORT_RSA && probeflags & PROBE_RSA)
-               serial8250_release_rsa_resource(up);
-       if (port->type == PORT_UNKNOWN)
-               serial8250_release_std_resource(up);
-
-       /* Fixme: probably not the best place for this */
-       if ((port->type == PORT_XR17V35X) ||
-          (port->type == PORT_XR17D15X))
-               port->handle_irq = exar_handle_irq;
-}
-
-static int
-serial8250_verify_port(struct uart_port *port, struct serial_struct *ser)
-{
-       if (ser->irq >= nr_irqs || ser->irq < 0 ||
-           ser->baud_base < 9600 || ser->type < PORT_UNKNOWN ||
-           ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS ||
-           ser->type == PORT_STARTECH)
-               return -EINVAL;
-       return 0;
-}
-
-static const char *
-serial8250_type(struct uart_port *port)
-{
-       int type = port->type;
-
-       if (type >= ARRAY_SIZE(uart_config))
-               type = 0;
-       return uart_config[type].name;
-}
-
-static struct uart_ops serial8250_pops = {
-       .tx_empty       = serial8250_tx_empty,
-       .set_mctrl      = serial8250_set_mctrl,
-       .get_mctrl      = serial8250_get_mctrl,
-       .stop_tx        = serial8250_stop_tx,
-       .start_tx       = serial8250_start_tx,
-       .stop_rx        = serial8250_stop_rx,
-       .enable_ms      = serial8250_enable_ms,
-       .break_ctl      = serial8250_break_ctl,
-       .startup        = serial8250_startup,
-       .shutdown       = serial8250_shutdown,
-       .set_termios    = serial8250_set_termios,
-       .set_ldisc      = serial8250_set_ldisc,
-       .pm             = serial8250_pm,
-       .type           = serial8250_type,
-       .release_port   = serial8250_release_port,
-       .request_port   = serial8250_request_port,
-       .config_port    = serial8250_config_port,
-       .verify_port    = serial8250_verify_port,
-#ifdef CONFIG_CONSOLE_POLL
-       .poll_get_char = serial8250_get_poll_char,
-       .poll_put_char = serial8250_put_poll_char,
-#endif
-};
-
-static struct uart_8250_port serial8250_ports[UART_NR];
-
-static void (*serial8250_isa_config)(int port, struct uart_port *up,
-       unsigned short *capabilities);
-
-void serial8250_set_isa_configurator(
-       void (*v)(int port, struct uart_port *up, unsigned short *capabilities))
-{
-       serial8250_isa_config = v;
-}
-EXPORT_SYMBOL(serial8250_set_isa_configurator);
-
-static void __init serial8250_isa_init_ports(void)
-{
-       struct uart_8250_port *up;
-       static int first = 1;
-       int i, irqflag = 0;
-
-       if (!first)
-               return;
-       first = 0;
-
-       if (nr_uarts > UART_NR)
-               nr_uarts = UART_NR;
-
-       for (i = 0; i < nr_uarts; i++) {
-               struct uart_8250_port *up = &serial8250_ports[i];
-               struct uart_port *port = &up->port;
-
-               port->line = i;
-               spin_lock_init(&port->lock);
-
-               init_timer(&up->timer);
-               up->timer.function = serial8250_timeout;
-               up->cur_iotype = 0xFF;
-
-               /*
-                * ALPHA_KLUDGE_MCR needs to be killed.
-                */
-               up->mcr_mask = ~ALPHA_KLUDGE_MCR;
-               up->mcr_force = ALPHA_KLUDGE_MCR;
-
-               port->ops = &serial8250_pops;
-       }
-
-       if (share_irqs)
-               irqflag = IRQF_SHARED;
-
-       for (i = 0, up = serial8250_ports;
-            i < ARRAY_SIZE(old_serial_port) && i < nr_uarts;
-            i++, up++) {
-               struct uart_port *port = &up->port;
-
-               port->iobase   = old_serial_port[i].port;
-               port->irq      = irq_canonicalize(old_serial_port[i].irq);
-               port->irqflags = old_serial_port[i].irqflags;
-               port->uartclk  = old_serial_port[i].baud_base * 16;
-               port->flags    = old_serial_port[i].flags;
-               port->hub6     = old_serial_port[i].hub6;
-               port->membase  = old_serial_port[i].iomem_base;
-               port->iotype   = old_serial_port[i].io_type;
-               port->regshift = old_serial_port[i].iomem_reg_shift;
-               set_io_from_upio(port);
-               port->irqflags |= irqflag;
-               if (serial8250_isa_config != NULL)
-                       serial8250_isa_config(i, &up->port, &up->capabilities);
-
-       }
-}
-
-static void
-serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type)
-{
-       up->port.type = type;
-       if (!up->port.fifosize)
-               up->port.fifosize = uart_config[type].fifo_size;
-       if (!up->tx_loadsz)
-               up->tx_loadsz = uart_config[type].tx_loadsz;
-       if (!up->capabilities)
-               up->capabilities = uart_config[type].flags;
-}
-
-static void __init
-serial8250_register_ports(struct uart_driver *drv, struct device *dev)
-{
-       int i;
-
-       for (i = 0; i < nr_uarts; i++) {
-               struct uart_8250_port *up = &serial8250_ports[i];
-
-               if (up->port.dev)
-                       continue;
-
-               up->port.dev = dev;
-
-               if (up->port.flags & UPF_FIXED_TYPE)
-                       serial8250_init_fixed_type_port(up, up->port.type);
-
-               uart_add_one_port(drv, &up->port);
-       }
-}
-
-#ifdef CONFIG_SERIAL_8250_CONSOLE
-
-static void serial8250_console_putchar(struct uart_port *port, int ch)
-{
-       struct uart_8250_port *up =
-               container_of(port, struct uart_8250_port, port);
-
-       wait_for_xmitr(up, UART_LSR_THRE);
-       serial_port_out(port, UART_TX, ch);
-}
-
-/*
- *     Print a string to the serial port trying not to disturb
- *     any possible real use of the port...
- *
- *     The console_lock must be held when we get here.
- */
-static void
-serial8250_console_write(struct console *co, const char *s, unsigned int count)
-{
-       struct uart_8250_port *up = &serial8250_ports[co->index];
-       struct uart_port *port = &up->port;
-       unsigned long flags;
-       unsigned int ier;
-       int locked = 1;
-
-       touch_nmi_watchdog();
-
-       local_irq_save(flags);
-       if (port->sysrq) {
-               /* serial8250_handle_irq() already took the lock */
-               locked = 0;
-       } else if (oops_in_progress) {
-               locked = spin_trylock(&port->lock);
-       } else
-               spin_lock(&port->lock);
-
-       /*
-        *      First save the IER then disable the interrupts
-        */
-       ier = serial_port_in(port, UART_IER);
-
-       if (up->capabilities & UART_CAP_UUE)
-               serial_port_out(port, UART_IER, UART_IER_UUE);
-       else
-               serial_port_out(port, UART_IER, 0);
-
-       uart_console_write(port, s, count, serial8250_console_putchar);
-
-       /*
-        *      Finally, wait for transmitter to become empty
-        *      and restore the IER
-        */
-       wait_for_xmitr(up, BOTH_EMPTY);
-       serial_port_out(port, UART_IER, ier);
-
-       /*
-        *      The receive handling will happen properly because the
-        *      receive ready bit will still be set; it is not cleared
-        *      on read.  However, modem control will not, we must
-        *      call it if we have saved something in the saved flags
-        *      while processing with interrupts off.
-        */
-       if (up->msr_saved_flags)
-               serial8250_modem_status(up);
-
-       if (locked)
-               spin_unlock(&port->lock);
-       local_irq_restore(flags);
-}
-
-static int __init serial8250_console_setup(struct console *co, char *options)
-{
-       struct uart_port *port;
-       int baud = 9600;
-       int bits = 8;
-       int parity = 'n';
-       int flow = 'n';
-
-       /*
-        * Check whether an invalid uart number has been specified, and
-        * if so, search for the first available port that does have
-        * console support.
-        */
-       if (co->index >= nr_uarts)
-               co->index = 0;
-       port = &serial8250_ports[co->index].port;
-       if (!port->iobase && !port->membase)
-               return -ENODEV;
-
-       if (options)
-               uart_parse_options(options, &baud, &parity, &bits, &flow);
-
-       return uart_set_options(port, co, baud, parity, bits, flow);
-}
-
-static int serial8250_console_early_setup(void)
-{
-       return serial8250_find_port_for_earlycon();
-}
-
-static struct console serial8250_console = {
-       .name           = "ttyS",
-       .write          = serial8250_console_write,
-       .device         = uart_console_device,
-       .setup          = serial8250_console_setup,
-       .early_setup    = serial8250_console_early_setup,
-       .flags          = CON_PRINTBUFFER | CON_ANYTIME,
-       .index          = -1,
-       .data           = &serial8250_reg,
-};
-
-static int __init serial8250_console_init(void)
-{
-       serial8250_isa_init_ports();
-       register_console(&serial8250_console);
-       return 0;
-}
-console_initcall(serial8250_console_init);
-
-int serial8250_find_port(struct uart_port *p)
-{
-       int line;
-       struct uart_port *port;
-
-       for (line = 0; line < nr_uarts; line++) {
-               port = &serial8250_ports[line].port;
-               if (uart_match_port(p, port))
-                       return line;
-       }
-       return -ENODEV;
-}
-
-#define SERIAL8250_CONSOLE     &serial8250_console
-#else
-#define SERIAL8250_CONSOLE     NULL
-#endif
-
-static struct uart_driver serial8250_reg = {
-       .owner                  = THIS_MODULE,
-       .driver_name            = "serial",
-       .dev_name               = "ttyS",
-       .major                  = TTY_MAJOR,
-       .minor                  = 64,
-       .cons                   = SERIAL8250_CONSOLE,
-};
-
-/*
- * early_serial_setup - early registration for 8250 ports
- *
- * Setup an 8250 port structure prior to console initialisation.  Use
- * after console initialisation will cause undefined behaviour.
- */
-int __init early_serial_setup(struct uart_port *port)
-{
-       struct uart_port *p;
-
-       if (port->line >= ARRAY_SIZE(serial8250_ports))
-               return -ENODEV;
-
-       serial8250_isa_init_ports();
-       p = &serial8250_ports[port->line].port;
-       p->iobase       = port->iobase;
-       p->membase      = port->membase;
-       p->irq          = port->irq;
-       p->irqflags     = port->irqflags;
-       p->uartclk      = port->uartclk;
-       p->fifosize     = port->fifosize;
-       p->regshift     = port->regshift;
-       p->iotype       = port->iotype;
-       p->flags        = port->flags;
-       p->mapbase      = port->mapbase;
-       p->private_data = port->private_data;
-       p->type         = port->type;
-       p->line         = port->line;
-
-       set_io_from_upio(p);
-       if (port->serial_in)
-               p->serial_in = port->serial_in;
-       if (port->serial_out)
-               p->serial_out = port->serial_out;
-       if (port->handle_irq)
-               p->handle_irq = port->handle_irq;
-       else
-               p->handle_irq = serial8250_default_handle_irq;
-
-       return 0;
-}
-
-/**
- *     serial8250_suspend_port - suspend one serial port
- *     @line:  serial line number
- *
- *     Suspend one serial port.
- */
-void serial8250_suspend_port(int line)
-{
-       uart_suspend_port(&serial8250_reg, &serial8250_ports[line].port);
-}
-
-/**
- *     serial8250_resume_port - resume one serial port
- *     @line:  serial line number
- *
- *     Resume one serial port.
- */
-void serial8250_resume_port(int line)
-{
-       struct uart_8250_port *up = &serial8250_ports[line];
-       struct uart_port *port = &up->port;
-
-       if (up->capabilities & UART_NATSEMI) {
-               /* Ensure it's still in high speed mode */
-               serial_port_out(port, UART_LCR, 0xE0);
-
-               ns16550a_goto_highspeed(up);
-
-               serial_port_out(port, UART_LCR, 0);
-               port->uartclk = 921600*16;
-       }
-       uart_resume_port(&serial8250_reg, port);
-}
-
-/*
- * Register a set of serial devices attached to a platform device.  The
- * list is terminated with a zero flags entry, which means we expect
- * all entries to have at least UPF_BOOT_AUTOCONF set.
- */
-static int serial8250_probe(struct platform_device *dev)
-{
-       struct plat_serial8250_port *p = dev->dev.platform_data;
-       struct uart_8250_port uart;
-       int ret, i, irqflag = 0;
-
-       memset(&uart, 0, sizeof(uart));
-
-       if (share_irqs)
-               irqflag = IRQF_SHARED;
-
-       for (i = 0; p && p->flags != 0; p++, i++) {
-               uart.port.iobase        = p->iobase;
-               uart.port.membase       = p->membase;
-               uart.port.irq           = p->irq;
-               uart.port.irqflags      = p->irqflags;
-               uart.port.uartclk       = p->uartclk;
-               uart.port.regshift      = p->regshift;
-               uart.port.iotype        = p->iotype;
-               uart.port.flags         = p->flags;
-               uart.port.mapbase       = p->mapbase;
-               uart.port.hub6          = p->hub6;
-               uart.port.private_data  = p->private_data;
-               uart.port.type          = p->type;
-               uart.port.serial_in     = p->serial_in;
-               uart.port.serial_out    = p->serial_out;
-               uart.port.handle_irq    = p->handle_irq;
-               uart.port.handle_break  = p->handle_break;
-               uart.port.set_termios   = p->set_termios;
-               uart.port.pm            = p->pm;
-               uart.port.dev           = &dev->dev;
-               uart.port.irqflags      |= irqflag;
-               ret = serial8250_register_8250_port(&uart);
-               if (ret < 0) {
-                       dev_err(&dev->dev, "unable to register port at index %d "
-                               "(IO%lx MEM%llx IRQ%d): %d\n", i,
-                               p->iobase, (unsigned long long)p->mapbase,
-                               p->irq, ret);
-               }
-       }
-       return 0;
-}
-
-/*
- * Remove serial ports registered against a platform device.
- */
-static int serial8250_remove(struct platform_device *dev)
-{
-       int i;
-
-       for (i = 0; i < nr_uarts; i++) {
-               struct uart_8250_port *up = &serial8250_ports[i];
-
-               if (up->port.dev == &dev->dev)
-                       serial8250_unregister_port(i);
-       }
-       return 0;
-}
-
-static int serial8250_suspend(struct platform_device *dev, pm_message_t state)
-{
-       int i;
-
-       for (i = 0; i < UART_NR; i++) {
-               struct uart_8250_port *up = &serial8250_ports[i];
-
-               if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
-                       uart_suspend_port(&serial8250_reg, &up->port);
-       }
-
-       return 0;
-}
-
-static int serial8250_resume(struct platform_device *dev)
-{
-       int i;
-
-       for (i = 0; i < UART_NR; i++) {
-               struct uart_8250_port *up = &serial8250_ports[i];
-
-               if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
-                       serial8250_resume_port(i);
-       }
-
-       return 0;
-}
-
-static struct platform_driver serial8250_isa_driver = {
-       .probe          = serial8250_probe,
-       .remove         = serial8250_remove,
-       .suspend        = serial8250_suspend,
-       .resume         = serial8250_resume,
-       .driver         = {
-               .name   = "serial8250",
-               .owner  = THIS_MODULE,
-       },
-};
-
-/*
- * This "device" covers _all_ ISA 8250-compatible serial devices listed
- * in the table in include/asm/serial.h
- */
-static struct platform_device *serial8250_isa_devs;
-
-/*
- * serial8250_register_8250_port and serial8250_unregister_port allows for
- * 16x50 serial ports to be configured at run-time, to support PCMCIA
- * modems and PCI multiport cards.
- */
-static DEFINE_MUTEX(serial_mutex);
-
-static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *port)
-{
-       int i;
-
-       /*
-        * First, find a port entry which matches.
-        */
-       for (i = 0; i < nr_uarts; i++)
-               if (uart_match_port(&serial8250_ports[i].port, port))
-                       return &serial8250_ports[i];
-
-       /*
-        * We didn't find a matching entry, so look for the first
-        * free entry.  We look for one which hasn't been previously
-        * used (indicated by zero iobase).
-        */
-       for (i = 0; i < nr_uarts; i++)
-               if (serial8250_ports[i].port.type == PORT_UNKNOWN &&
-                   serial8250_ports[i].port.iobase == 0)
-                       return &serial8250_ports[i];
-
-       /*
-        * That also failed.  Last resort is to find any entry which
-        * doesn't have a real port associated with it.
-        */
-       for (i = 0; i < nr_uarts; i++)
-               if (serial8250_ports[i].port.type == PORT_UNKNOWN)
-                       return &serial8250_ports[i];
-
-       return NULL;
-}
-
-/**
- *     serial8250_register_8250_port - register a serial port
- *     @up: serial port template
- *
- *     Configure the serial port specified by the request. If the
- *     port exists and is in use, it is hung up and unregistered
- *     first.
- *
- *     The port is then probed and if necessary the IRQ is autodetected
- *     If this fails an error is returned.
- *
- *     On success the port is ready to use and the line number is returned.
- */
-int serial8250_register_8250_port(struct uart_8250_port *up)
-{
-       struct uart_8250_port *uart;
-       int ret = -ENOSPC;
-
-       if (up->port.uartclk == 0)
-               return -EINVAL;
-
-       mutex_lock(&serial_mutex);
-
-       uart = serial8250_find_match_or_unused(&up->port);
-       if (uart && uart->port.type != PORT_8250_CIR) {
-               if (uart->port.dev)
-                       uart_remove_one_port(&serial8250_reg, &uart->port);
-
-               uart->port.iobase       = up->port.iobase;
-               uart->port.membase      = up->port.membase;
-               uart->port.irq          = up->port.irq;
-               uart->port.irqflags     = up->port.irqflags;
-               uart->port.uartclk      = up->port.uartclk;
-               uart->port.fifosize     = up->port.fifosize;
-               uart->port.regshift     = up->port.regshift;
-               uart->port.iotype       = up->port.iotype;
-               uart->port.flags        = up->port.flags | UPF_BOOT_AUTOCONF;
-               uart->bugs              = up->bugs;
-               uart->port.mapbase      = up->port.mapbase;
-               uart->port.private_data = up->port.private_data;
-               uart->port.fifosize     = up->port.fifosize;
-               uart->tx_loadsz         = up->tx_loadsz;
-               uart->capabilities      = up->capabilities;
-
-               if (up->port.dev)
-                       uart->port.dev = up->port.dev;
-
-               if (up->port.flags & UPF_FIXED_TYPE)
-                       serial8250_init_fixed_type_port(uart, up->port.type);
-
-               set_io_from_upio(&uart->port);
-               /* Possibly override default I/O functions.  */
-               if (up->port.serial_in)
-                       uart->port.serial_in = up->port.serial_in;
-               if (up->port.serial_out)
-                       uart->port.serial_out = up->port.serial_out;
-               if (up->port.handle_irq)
-                       uart->port.handle_irq = up->port.handle_irq;
-               /*  Possibly override set_termios call */
-               if (up->port.set_termios)
-                       uart->port.set_termios = up->port.set_termios;
-               if (up->port.pm)
-                       uart->port.pm = up->port.pm;
-               if (up->port.handle_break)
-                       uart->port.handle_break = up->port.handle_break;
-               if (up->dl_read)
-                       uart->dl_read = up->dl_read;
-               if (up->dl_write)
-                       uart->dl_write = up->dl_write;
-               if (up->dma)
-                       uart->dma = up->dma;
-
-               if (serial8250_isa_config != NULL)
-                       serial8250_isa_config(0, &uart->port,
-                                       &uart->capabilities);
-
-               ret = uart_add_one_port(&serial8250_reg, &uart->port);
-               if (ret == 0)
-                       ret = uart->port.line;
-       }
-       mutex_unlock(&serial_mutex);
-
-       return ret;
-}
-EXPORT_SYMBOL(serial8250_register_8250_port);
-
-/**
- *     serial8250_unregister_port - remove a 16x50 serial port at runtime
- *     @line: serial line number
- *
- *     Remove one serial port.  This may not be called from interrupt
- *     context.  We hand the port back to the our control.
- */
-void serial8250_unregister_port(int line)
-{
-       struct uart_8250_port *uart = &serial8250_ports[line];
-
-       mutex_lock(&serial_mutex);
-       uart_remove_one_port(&serial8250_reg, &uart->port);
-       if (serial8250_isa_devs) {
-               uart->port.flags &= ~UPF_BOOT_AUTOCONF;
-               uart->port.type = PORT_UNKNOWN;
-               uart->port.dev = &serial8250_isa_devs->dev;
-               uart->capabilities = uart_config[uart->port.type].flags;
-               uart_add_one_port(&serial8250_reg, &uart->port);
-       } else {
-               uart->port.dev = NULL;
-       }
-       mutex_unlock(&serial_mutex);
-}
-EXPORT_SYMBOL(serial8250_unregister_port);
-
-static int __init serial8250_init(void)
-{
-       int ret;
-
-       serial8250_isa_init_ports();
-
-       printk(KERN_INFO "Serial: 8250/16550 driver, "
-               "%d ports, IRQ sharing %sabled\n", nr_uarts,
-               share_irqs ? "en" : "dis");
-
-#ifdef CONFIG_SPARC
-       ret = sunserial_register_minors(&serial8250_reg, UART_NR);
-#else
-       serial8250_reg.nr = UART_NR;
-       ret = uart_register_driver(&serial8250_reg);
-#endif
-       if (ret)
-               goto out;
-
-       ret = serial8250_pnp_init();
-       if (ret)
-               goto unreg_uart_drv;
-
-       serial8250_isa_devs = platform_device_alloc("serial8250",
-                                                   PLAT8250_DEV_LEGACY);
-       if (!serial8250_isa_devs) {
-               ret = -ENOMEM;
-               goto unreg_pnp;
-       }
-
-       ret = platform_device_add(serial8250_isa_devs);
-       if (ret)
-               goto put_dev;
-
-       serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);
-
-       ret = platform_driver_register(&serial8250_isa_driver);
-       if (ret == 0)
-               goto out;
-
-       platform_device_del(serial8250_isa_devs);
-put_dev:
-       platform_device_put(serial8250_isa_devs);
-unreg_pnp:
-       serial8250_pnp_exit();
-unreg_uart_drv:
-#ifdef CONFIG_SPARC
-       sunserial_unregister_minors(&serial8250_reg, UART_NR);
-#else
-       uart_unregister_driver(&serial8250_reg);
-#endif
-out:
-       return ret;
-}
-
-static void __exit serial8250_exit(void)
-{
-       struct platform_device *isa_dev = serial8250_isa_devs;
-
-       /*
-        * This tells serial8250_unregister_port() not to re-register
-        * the ports (thereby making serial8250_isa_driver permanently
-        * in use.)
-        */
-       serial8250_isa_devs = NULL;
-
-       platform_driver_unregister(&serial8250_isa_driver);
-       platform_device_unregister(isa_dev);
-
-       serial8250_pnp_exit();
-
-#ifdef CONFIG_SPARC
-       sunserial_unregister_minors(&serial8250_reg, UART_NR);
-#else
-       uart_unregister_driver(&serial8250_reg);
-#endif
-}
-
-module_init(serial8250_init);
-module_exit(serial8250_exit);
-
-EXPORT_SYMBOL(serial8250_suspend_port);
-EXPORT_SYMBOL(serial8250_resume_port);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Generic 8250/16x50 serial driver");
-
-module_param(share_irqs, uint, 0644);
-MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
-       " (unsafe)");
-
-module_param(nr_uarts, uint, 0644);
-MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")");
-
-module_param(skip_txen_test, uint, 0644);
-MODULE_PARM_DESC(skip_txen_test, "Skip checking for the TXEN bug at init time");
-
-#ifdef CONFIG_SERIAL_8250_RSA
-module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);
-MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
-#endif
-MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
-
-#ifndef MODULE
-/* This module was renamed to 8250_core in 3.7.  Keep the old "8250" name
- * working as well for the module options so we don't break people.  We
- * need to keep the names identical and the convenient macros will happily
- * refuse to let us do that by failing the build with redefinition errors
- * of global variables.  So we stick them inside a dummy function to avoid
- * those conflicts.  The options still get parsed, and the redefined
- * MODULE_PARAM_PREFIX lets us keep the "8250." syntax alive.
- *
- * This is hacky.  I'm sorry.
- */
-static void __used s8250_options(void)
-{
-#undef MODULE_PARAM_PREFIX
-#define MODULE_PARAM_PREFIX "8250."
-
-       module_param_cb(share_irqs, &param_ops_uint, &share_irqs, 0644);
-       module_param_cb(nr_uarts, &param_ops_uint, &nr_uarts, 0644);
-       module_param_cb(skip_txen_test, &param_ops_uint, &skip_txen_test, 0644);
-#ifdef CONFIG_SERIAL_8250_RSA
-       __module_param_call(MODULE_PARAM_PREFIX, probe_rsa,
-               &param_array_ops, .arr = &__param_arr_probe_rsa,
-               0444, -1);
-#endif
-}
-#else
-MODULE_ALIAS("8250");
-#endif
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
new file mode 100644 (file)
index 0000000..35f9c96
--- /dev/null
@@ -0,0 +1,3450 @@
+/*
+ *  Driver for 8250/16550-type serial ports
+ *
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ *  Copyright (C) 2001 Russell King.
+ *
+ * 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.
+ *
+ * A note about mapbase / membase
+ *
+ *  mapbase is the physical address of the IO port.
+ *  membase is an 'ioremapped' cookie.
+ */
+
+#if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/tty.h>
+#include <linux/ratelimit.h>
+#include <linux/tty_flip.h>
+#include <linux/serial_reg.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/nmi.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#ifdef CONFIG_SPARC
+#include <linux/sunserialcore.h>
+#endif
+
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include "8250.h"
+
+/*
+ * Configuration:
+ *   share_irqs - whether we pass IRQF_SHARED to request_irq().  This option
+ *                is unsafe when used on edge-triggered interrupts.
+ */
+static unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
+
+static unsigned int nr_uarts = CONFIG_SERIAL_8250_RUNTIME_UARTS;
+
+static struct uart_driver serial8250_reg;
+
+static int serial_index(struct uart_port *port)
+{
+       return (serial8250_reg.minor - 64) + port->line;
+}
+
+static unsigned int skip_txen_test; /* force skip of txen test at init time */
+
+/*
+ * Debugging.
+ */
+#if 0
+#define DEBUG_AUTOCONF(fmt...) printk(fmt)
+#else
+#define DEBUG_AUTOCONF(fmt...) do { } while (0)
+#endif
+
+#if 0
+#define DEBUG_INTR(fmt...)     printk(fmt)
+#else
+#define DEBUG_INTR(fmt...)     do { } while (0)
+#endif
+
+#define PASS_LIMIT     512
+
+#define BOTH_EMPTY     (UART_LSR_TEMT | UART_LSR_THRE)
+
+
+#ifdef CONFIG_SERIAL_8250_DETECT_IRQ
+#define CONFIG_SERIAL_DETECT_IRQ 1
+#endif
+#ifdef CONFIG_SERIAL_8250_MANY_PORTS
+#define CONFIG_SERIAL_MANY_PORTS 1
+#endif
+
+/*
+ * HUB6 is always on.  This will be removed once the header
+ * files have been cleaned.
+ */
+#define CONFIG_HUB6 1
+
+#include <asm/serial.h>
+/*
+ * SERIAL_PORT_DFNS tells us about built-in ports that have no
+ * standard enumeration mechanism.   Platforms that can find all
+ * serial ports via mechanisms like ACPI or PCI need not supply it.
+ */
+#ifndef SERIAL_PORT_DFNS
+#define SERIAL_PORT_DFNS
+#endif
+
+static const struct old_serial_port old_serial_port[] = {
+       SERIAL_PORT_DFNS /* defined in asm/serial.h */
+};
+
+#define UART_NR        CONFIG_SERIAL_8250_NR_UARTS
+
+#ifdef CONFIG_SERIAL_8250_RSA
+
+#define PORT_RSA_MAX 4
+static unsigned long probe_rsa[PORT_RSA_MAX];
+static unsigned int probe_rsa_count;
+#endif /* CONFIG_SERIAL_8250_RSA  */
+
+struct irq_info {
+       struct                  hlist_node node;
+       int                     irq;
+       spinlock_t              lock;   /* Protects list not the hash */
+       struct list_head        *head;
+};
+
+#define NR_IRQ_HASH            32      /* Can be adjusted later */
+static struct hlist_head irq_lists[NR_IRQ_HASH];
+static DEFINE_MUTEX(hash_mutex);       /* Used to walk the hash */
+
+/*
+ * Here we define the default xmit fifo size used for each type of UART.
+ */
+static const struct serial8250_config uart_config[] = {
+       [PORT_UNKNOWN] = {
+               .name           = "unknown",
+               .fifo_size      = 1,
+               .tx_loadsz      = 1,
+       },
+       [PORT_8250] = {
+               .name           = "8250",
+               .fifo_size      = 1,
+               .tx_loadsz      = 1,
+       },
+       [PORT_16450] = {
+               .name           = "16450",
+               .fifo_size      = 1,
+               .tx_loadsz      = 1,
+       },
+       [PORT_16550] = {
+               .name           = "16550",
+               .fifo_size      = 1,
+               .tx_loadsz      = 1,
+       },
+       [PORT_16550A] = {
+               .name           = "16550A",
+               .fifo_size      = 16,
+               .tx_loadsz      = 16,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO,
+       },
+       [PORT_CIRRUS] = {
+               .name           = "Cirrus",
+               .fifo_size      = 1,
+               .tx_loadsz      = 1,
+       },
+       [PORT_16650] = {
+               .name           = "ST16650",
+               .fifo_size      = 1,
+               .tx_loadsz      = 1,
+               .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
+       },
+       [PORT_16650V2] = {
+               .name           = "ST16650V2",
+               .fifo_size      = 32,
+               .tx_loadsz      = 16,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
+                                 UART_FCR_T_TRIG_00,
+               .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
+       },
+       [PORT_16750] = {
+               .name           = "TI16750",
+               .fifo_size      = 64,
+               .tx_loadsz      = 64,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10 |
+                                 UART_FCR7_64BYTE,
+               .flags          = UART_CAP_FIFO | UART_CAP_SLEEP | UART_CAP_AFE,
+       },
+       [PORT_STARTECH] = {
+               .name           = "Startech",
+               .fifo_size      = 1,
+               .tx_loadsz      = 1,
+       },
+       [PORT_16C950] = {
+               .name           = "16C950/954",
+               .fifo_size      = 128,
+               .tx_loadsz      = 128,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               /* UART_CAP_EFR breaks billionon CF bluetooth card. */
+               .flags          = UART_CAP_FIFO | UART_CAP_SLEEP,
+       },
+       [PORT_16654] = {
+               .name           = "ST16654",
+               .fifo_size      = 64,
+               .tx_loadsz      = 32,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
+                                 UART_FCR_T_TRIG_10,
+               .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
+       },
+       [PORT_16850] = {
+               .name           = "XR16850",
+               .fifo_size      = 128,
+               .tx_loadsz      = 128,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP,
+       },
+       [PORT_RSA] = {
+               .name           = "RSA",
+               .fifo_size      = 2048,
+               .tx_loadsz      = 2048,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11,
+               .flags          = UART_CAP_FIFO,
+       },
+       [PORT_NS16550A] = {
+               .name           = "NS16550A",
+               .fifo_size      = 16,
+               .tx_loadsz      = 16,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO | UART_NATSEMI,
+       },
+       [PORT_XSCALE] = {
+               .name           = "XScale",
+               .fifo_size      = 32,
+               .tx_loadsz      = 32,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE,
+       },
+       [PORT_OCTEON] = {
+               .name           = "OCTEON",
+               .fifo_size      = 64,
+               .tx_loadsz      = 64,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO,
+       },
+       [PORT_AR7] = {
+               .name           = "AR7",
+               .fifo_size      = 16,
+               .tx_loadsz      = 16,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00,
+               .flags          = UART_CAP_FIFO | UART_CAP_AFE,
+       },
+       [PORT_U6_16550A] = {
+               .name           = "U6_16550A",
+               .fifo_size      = 64,
+               .tx_loadsz      = 64,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO | UART_CAP_AFE,
+       },
+       [PORT_TEGRA] = {
+               .name           = "Tegra",
+               .fifo_size      = 32,
+               .tx_loadsz      = 8,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
+                                 UART_FCR_T_TRIG_01,
+               .flags          = UART_CAP_FIFO | UART_CAP_RTOIE,
+       },
+       [PORT_XR17D15X] = {
+               .name           = "XR17D15X",
+               .fifo_size      = 64,
+               .tx_loadsz      = 64,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR |
+                                 UART_CAP_SLEEP,
+       },
+       [PORT_XR17V35X] = {
+               .name           = "XR17V35X",
+               .fifo_size      = 256,
+               .tx_loadsz      = 256,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11 |
+                                 UART_FCR_T_TRIG_11,
+               .flags          = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR |
+                                 UART_CAP_SLEEP,
+       },
+       [PORT_LPC3220] = {
+               .name           = "LPC3220",
+               .fifo_size      = 64,
+               .tx_loadsz      = 32,
+               .fcr            = UART_FCR_DMA_SELECT | UART_FCR_ENABLE_FIFO |
+                                 UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_00,
+               .flags          = UART_CAP_FIFO,
+       },
+       [PORT_BRCM_TRUMANAGE] = {
+               .name           = "TruManage",
+               .fifo_size      = 1,
+               .tx_loadsz      = 1024,
+               .flags          = UART_CAP_HFIFO,
+       },
+       [PORT_8250_CIR] = {
+               .name           = "CIR port"
+       },
+       [PORT_ALTR_16550_F32] = {
+               .name           = "Altera 16550 FIFO32",
+               .fifo_size      = 32,
+               .tx_loadsz      = 32,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO | UART_CAP_AFE,
+       },
+       [PORT_ALTR_16550_F64] = {
+               .name           = "Altera 16550 FIFO64",
+               .fifo_size      = 64,
+               .tx_loadsz      = 64,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO | UART_CAP_AFE,
+       },
+       [PORT_ALTR_16550_F128] = {
+               .name           = "Altera 16550 FIFO128",
+               .fifo_size      = 128,
+               .tx_loadsz      = 128,
+               .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
+               .flags          = UART_CAP_FIFO | UART_CAP_AFE,
+       },
+};
+
+/* Uart divisor latch read */
+static int default_serial_dl_read(struct uart_8250_port *up)
+{
+       return serial_in(up, UART_DLL) | serial_in(up, UART_DLM) << 8;
+}
+
+/* Uart divisor latch write */
+static void default_serial_dl_write(struct uart_8250_port *up, int value)
+{
+       serial_out(up, UART_DLL, value & 0xff);
+       serial_out(up, UART_DLM, value >> 8 & 0xff);
+}
+
+#if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X)
+
+/* Au1x00/RT288x UART hardware has a weird register layout */
+static const u8 au_io_in_map[] = {
+       [UART_RX]  = 0,
+       [UART_IER] = 2,
+       [UART_IIR] = 3,
+       [UART_LCR] = 5,
+       [UART_MCR] = 6,
+       [UART_LSR] = 7,
+       [UART_MSR] = 8,
+};
+
+static const u8 au_io_out_map[] = {
+       [UART_TX]  = 1,
+       [UART_IER] = 2,
+       [UART_FCR] = 4,
+       [UART_LCR] = 5,
+       [UART_MCR] = 6,
+};
+
+static unsigned int au_serial_in(struct uart_port *p, int offset)
+{
+       offset = au_io_in_map[offset] << p->regshift;
+       return __raw_readl(p->membase + offset);
+}
+
+static void au_serial_out(struct uart_port *p, int offset, int value)
+{
+       offset = au_io_out_map[offset] << p->regshift;
+       __raw_writel(value, p->membase + offset);
+}
+
+/* Au1x00 haven't got a standard divisor latch */
+static int au_serial_dl_read(struct uart_8250_port *up)
+{
+       return __raw_readl(up->port.membase + 0x28);
+}
+
+static void au_serial_dl_write(struct uart_8250_port *up, int value)
+{
+       __raw_writel(value, up->port.membase + 0x28);
+}
+
+#endif
+
+static unsigned int hub6_serial_in(struct uart_port *p, int offset)
+{
+       offset = offset << p->regshift;
+       outb(p->hub6 - 1 + offset, p->iobase);
+       return inb(p->iobase + 1);
+}
+
+static void hub6_serial_out(struct uart_port *p, int offset, int value)
+{
+       offset = offset << p->regshift;
+       outb(p->hub6 - 1 + offset, p->iobase);
+       outb(value, p->iobase + 1);
+}
+
+static unsigned int mem_serial_in(struct uart_port *p, int offset)
+{
+       offset = offset << p->regshift;
+       return readb(p->membase + offset);
+}
+
+static void mem_serial_out(struct uart_port *p, int offset, int value)
+{
+       offset = offset << p->regshift;
+       writeb(value, p->membase + offset);
+}
+
+static void mem32_serial_out(struct uart_port *p, int offset, int value)
+{
+       offset = offset << p->regshift;
+       writel(value, p->membase + offset);
+}
+
+static unsigned int mem32_serial_in(struct uart_port *p, int offset)
+{
+       offset = offset << p->regshift;
+       return readl(p->membase + offset);
+}
+
+static unsigned int io_serial_in(struct uart_port *p, int offset)
+{
+       offset = offset << p->regshift;
+       return inb(p->iobase + offset);
+}
+
+static void io_serial_out(struct uart_port *p, int offset, int value)
+{
+       offset = offset << p->regshift;
+       outb(value, p->iobase + offset);
+}
+
+static int serial8250_default_handle_irq(struct uart_port *port);
+static int exar_handle_irq(struct uart_port *port);
+
+static void set_io_from_upio(struct uart_port *p)
+{
+       struct uart_8250_port *up =
+               container_of(p, struct uart_8250_port, port);
+
+       up->dl_read = default_serial_dl_read;
+       up->dl_write = default_serial_dl_write;
+
+       switch (p->iotype) {
+       case UPIO_HUB6:
+               p->serial_in = hub6_serial_in;
+               p->serial_out = hub6_serial_out;
+               break;
+
+       case UPIO_MEM:
+               p->serial_in = mem_serial_in;
+               p->serial_out = mem_serial_out;
+               break;
+
+       case UPIO_MEM32:
+               p->serial_in = mem32_serial_in;
+               p->serial_out = mem32_serial_out;
+               break;
+
+#if defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_SERIAL_8250_RT288X)
+       case UPIO_AU:
+               p->serial_in = au_serial_in;
+               p->serial_out = au_serial_out;
+               up->dl_read = au_serial_dl_read;
+               up->dl_write = au_serial_dl_write;
+               break;
+#endif
+
+       default:
+               p->serial_in = io_serial_in;
+               p->serial_out = io_serial_out;
+               break;
+       }
+       /* Remember loaded iotype */
+       up->cur_iotype = p->iotype;
+       p->handle_irq = serial8250_default_handle_irq;
+}
+
+static void
+serial_port_out_sync(struct uart_port *p, int offset, int value)
+{
+       switch (p->iotype) {
+       case UPIO_MEM:
+       case UPIO_MEM32:
+       case UPIO_AU:
+               p->serial_out(p, offset, value);
+               p->serial_in(p, UART_LCR);      /* safe, no side-effects */
+               break;
+       default:
+               p->serial_out(p, offset, value);
+       }
+}
+
+/*
+ * For the 16C950
+ */
+static void serial_icr_write(struct uart_8250_port *up, int offset, int value)
+{
+       serial_out(up, UART_SCR, offset);
+       serial_out(up, UART_ICR, value);
+}
+
+static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
+{
+       unsigned int value;
+
+       serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD);
+       serial_out(up, UART_SCR, offset);
+       value = serial_in(up, UART_ICR);
+       serial_icr_write(up, UART_ACR, up->acr);
+
+       return value;
+}
+
+/*
+ * FIFO support.
+ */
+static void serial8250_clear_fifos(struct uart_8250_port *p)
+{
+       if (p->capabilities & UART_CAP_FIFO) {
+               serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO);
+               serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO |
+                              UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+               serial_out(p, UART_FCR, 0);
+       }
+}
+
+void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p)
+{
+       unsigned char fcr;
+
+       serial8250_clear_fifos(p);
+       fcr = uart_config[p->port.type].fcr;
+       serial_out(p, UART_FCR, fcr);
+}
+EXPORT_SYMBOL_GPL(serial8250_clear_and_reinit_fifos);
+
+/*
+ * IER sleep support.  UARTs which have EFRs need the "extended
+ * capability" bit enabled.  Note that on XR16C850s, we need to
+ * reset LCR to write to IER.
+ */
+static void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
+{
+       /*
+        * Exar UARTs have a SLEEP register that enables or disables
+        * each UART to enter sleep mode separately.  On the XR17V35x the
+        * register is accessible to each UART at the UART_EXAR_SLEEP
+        * offset but the UART channel may only write to the corresponding
+        * bit.
+        */
+       if ((p->port.type == PORT_XR17V35X) ||
+          (p->port.type == PORT_XR17D15X)) {
+               serial_out(p, UART_EXAR_SLEEP, 0xff);
+               return;
+       }
+
+       if (p->capabilities & UART_CAP_SLEEP) {
+               if (p->capabilities & UART_CAP_EFR) {
+                       serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B);
+                       serial_out(p, UART_EFR, UART_EFR_ECB);
+                       serial_out(p, UART_LCR, 0);
+               }
+               serial_out(p, UART_IER, sleep ? UART_IERX_SLEEP : 0);
+               if (p->capabilities & UART_CAP_EFR) {
+                       serial_out(p, UART_LCR, UART_LCR_CONF_MODE_B);
+                       serial_out(p, UART_EFR, 0);
+                       serial_out(p, UART_LCR, 0);
+               }
+       }
+}
+
+#ifdef CONFIG_SERIAL_8250_RSA
+/*
+ * Attempts to turn on the RSA FIFO.  Returns zero on failure.
+ * We set the port uart clock rate if we succeed.
+ */
+static int __enable_rsa(struct uart_8250_port *up)
+{
+       unsigned char mode;
+       int result;
+
+       mode = serial_in(up, UART_RSA_MSR);
+       result = mode & UART_RSA_MSR_FIFO;
+
+       if (!result) {
+               serial_out(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO);
+               mode = serial_in(up, UART_RSA_MSR);
+               result = mode & UART_RSA_MSR_FIFO;
+       }
+
+       if (result)
+               up->port.uartclk = SERIAL_RSA_BAUD_BASE * 16;
+
+       return result;
+}
+
+static void enable_rsa(struct uart_8250_port *up)
+{
+       if (up->port.type == PORT_RSA) {
+               if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) {
+                       spin_lock_irq(&up->port.lock);
+                       __enable_rsa(up);
+                       spin_unlock_irq(&up->port.lock);
+               }
+               if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16)
+                       serial_out(up, UART_RSA_FRR, 0);
+       }
+}
+
+/*
+ * Attempts to turn off the RSA FIFO.  Returns zero on failure.
+ * It is unknown why interrupts were disabled in here.  However,
+ * the caller is expected to preserve this behaviour by grabbing
+ * the spinlock before calling this function.
+ */
+static void disable_rsa(struct uart_8250_port *up)
+{
+       unsigned char mode;
+       int result;
+
+       if (up->port.type == PORT_RSA &&
+           up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) {
+               spin_lock_irq(&up->port.lock);
+
+               mode = serial_in(up, UART_RSA_MSR);
+               result = !(mode & UART_RSA_MSR_FIFO);
+
+               if (!result) {
+                       serial_out(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO);
+                       mode = serial_in(up, UART_RSA_MSR);
+                       result = !(mode & UART_RSA_MSR_FIFO);
+               }
+
+               if (result)
+                       up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16;
+               spin_unlock_irq(&up->port.lock);
+       }
+}
+#endif /* CONFIG_SERIAL_8250_RSA */
+
+/*
+ * This is a quickie test to see how big the FIFO is.
+ * It doesn't work at all the time, more's the pity.
+ */
+static int size_fifo(struct uart_8250_port *up)
+{
+       unsigned char old_fcr, old_mcr, old_lcr;
+       unsigned short old_dl;
+       int count;
+
+       old_lcr = serial_in(up, UART_LCR);
+       serial_out(up, UART_LCR, 0);
+       old_fcr = serial_in(up, UART_FCR);
+       old_mcr = serial_in(up, UART_MCR);
+       serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO |
+                   UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+       serial_out(up, UART_MCR, UART_MCR_LOOP);
+       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
+       old_dl = serial_dl_read(up);
+       serial_dl_write(up, 0x0001);
+       serial_out(up, UART_LCR, 0x03);
+       for (count = 0; count < 256; count++)
+               serial_out(up, UART_TX, count);
+       mdelay(20);/* FIXME - schedule_timeout */
+       for (count = 0; (serial_in(up, UART_LSR) & UART_LSR_DR) &&
+            (count < 256); count++)
+               serial_in(up, UART_RX);
+       serial_out(up, UART_FCR, old_fcr);
+       serial_out(up, UART_MCR, old_mcr);
+       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
+       serial_dl_write(up, old_dl);
+       serial_out(up, UART_LCR, old_lcr);
+
+       return count;
+}
+
+/*
+ * Read UART ID using the divisor method - set DLL and DLM to zero
+ * and the revision will be in DLL and device type in DLM.  We
+ * preserve the device state across this.
+ */
+static unsigned int autoconfig_read_divisor_id(struct uart_8250_port *p)
+{
+       unsigned char old_dll, old_dlm, old_lcr;
+       unsigned int id;
+
+       old_lcr = serial_in(p, UART_LCR);
+       serial_out(p, UART_LCR, UART_LCR_CONF_MODE_A);
+
+       old_dll = serial_in(p, UART_DLL);
+       old_dlm = serial_in(p, UART_DLM);
+
+       serial_out(p, UART_DLL, 0);
+       serial_out(p, UART_DLM, 0);
+
+       id = serial_in(p, UART_DLL) | serial_in(p, UART_DLM) << 8;
+
+       serial_out(p, UART_DLL, old_dll);
+       serial_out(p, UART_DLM, old_dlm);
+       serial_out(p, UART_LCR, old_lcr);
+
+       return id;
+}
+
+/*
+ * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's.
+ * When this function is called we know it is at least a StarTech
+ * 16650 V2, but it might be one of several StarTech UARTs, or one of
+ * its clones.  (We treat the broken original StarTech 16650 V1 as a
+ * 16550, and why not?  Startech doesn't seem to even acknowledge its
+ * existence.)
+ *
+ * What evil have men's minds wrought...
+ */
+static void autoconfig_has_efr(struct uart_8250_port *up)
+{
+       unsigned int id1, id2, id3, rev;
+
+       /*
+        * Everything with an EFR has SLEEP
+        */
+       up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP;
+
+       /*
+        * First we check to see if it's an Oxford Semiconductor UART.
+        *
+        * If we have to do this here because some non-National
+        * Semiconductor clone chips lock up if you try writing to the
+        * LSR register (which serial_icr_read does)
+        */
+
+       /*
+        * Check for Oxford Semiconductor 16C950.
+        *
+        * EFR [4] must be set else this test fails.
+        *
+        * This shouldn't be necessary, but Mike Hudson (Exoray@isys.ca)
+        * claims that it's needed for 952 dual UART's (which are not
+        * recommended for new designs).
+        */
+       up->acr = 0;
+       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+       serial_out(up, UART_EFR, UART_EFR_ECB);
+       serial_out(up, UART_LCR, 0x00);
+       id1 = serial_icr_read(up, UART_ID1);
+       id2 = serial_icr_read(up, UART_ID2);
+       id3 = serial_icr_read(up, UART_ID3);
+       rev = serial_icr_read(up, UART_REV);
+
+       DEBUG_AUTOCONF("950id=%02x:%02x:%02x:%02x ", id1, id2, id3, rev);
+
+       if (id1 == 0x16 && id2 == 0xC9 &&
+           (id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) {
+               up->port.type = PORT_16C950;
+
+               /*
+                * Enable work around for the Oxford Semiconductor 952 rev B
+                * chip which causes it to seriously miscalculate baud rates
+                * when DLL is 0.
+                */
+               if (id3 == 0x52 && rev == 0x01)
+                       up->bugs |= UART_BUG_QUOT;
+               return;
+       }
+
+       /*
+        * We check for a XR16C850 by setting DLL and DLM to 0, and then
+        * reading back DLL and DLM.  The chip type depends on the DLM
+        * value read back:
+        *  0x10 - XR16C850 and the DLL contains the chip revision.
+        *  0x12 - XR16C2850.
+        *  0x14 - XR16C854.
+        */
+       id1 = autoconfig_read_divisor_id(up);
+       DEBUG_AUTOCONF("850id=%04x ", id1);
+
+       id2 = id1 >> 8;
+       if (id2 == 0x10 || id2 == 0x12 || id2 == 0x14) {
+               up->port.type = PORT_16850;
+               return;
+       }
+
+       /*
+        * It wasn't an XR16C850.
+        *
+        * We distinguish between the '654 and the '650 by counting
+        * how many bytes are in the FIFO.  I'm using this for now,
+        * since that's the technique that was sent to me in the
+        * serial driver update, but I'm not convinced this works.
+        * I've had problems doing this in the past.  -TYT
+        */
+       if (size_fifo(up) == 64)
+               up->port.type = PORT_16654;
+       else
+               up->port.type = PORT_16650V2;
+}
+
+/*
+ * We detected a chip without a FIFO.  Only two fall into
+ * this category - the original 8250 and the 16450.  The
+ * 16450 has a scratch register (accessible with LCR=0)
+ */
+static void autoconfig_8250(struct uart_8250_port *up)
+{
+       unsigned char scratch, status1, status2;
+
+       up->port.type = PORT_8250;
+
+       scratch = serial_in(up, UART_SCR);
+       serial_out(up, UART_SCR, 0xa5);
+       status1 = serial_in(up, UART_SCR);
+       serial_out(up, UART_SCR, 0x5a);
+       status2 = serial_in(up, UART_SCR);
+       serial_out(up, UART_SCR, scratch);
+
+       if (status1 == 0xa5 && status2 == 0x5a)
+               up->port.type = PORT_16450;
+}
+
+static int broken_efr(struct uart_8250_port *up)
+{
+       /*
+        * Exar ST16C2550 "A2" devices incorrectly detect as
+        * having an EFR, and report an ID of 0x0201.  See
+        * http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-11/4812.html 
+        */
+       if (autoconfig_read_divisor_id(up) == 0x0201 && size_fifo(up) == 16)
+               return 1;
+
+       return 0;
+}
+
+static inline int ns16550a_goto_highspeed(struct uart_8250_port *up)
+{
+       unsigned char status;
+
+       status = serial_in(up, 0x04); /* EXCR2 */
+#define PRESL(x) ((x) & 0x30)
+       if (PRESL(status) == 0x10) {
+               /* already in high speed mode */
+               return 0;
+       } else {
+               status &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
+               status |= 0x10;  /* 1.625 divisor for baud_base --> 921600 */
+               serial_out(up, 0x04, status);
+       }
+       return 1;
+}
+
+/*
+ * We know that the chip has FIFOs.  Does it have an EFR?  The
+ * EFR is located in the same register position as the IIR and
+ * we know the top two bits of the IIR are currently set.  The
+ * EFR should contain zero.  Try to read the EFR.
+ */
+static void autoconfig_16550a(struct uart_8250_port *up)
+{
+       unsigned char status1, status2;
+       unsigned int iersave;
+
+       up->port.type = PORT_16550A;
+       up->capabilities |= UART_CAP_FIFO;
+
+       /*
+        * XR17V35x UARTs have an extra divisor register, DLD
+        * that gets enabled with when DLAB is set which will
+        * cause the device to incorrectly match and assign
+        * port type to PORT_16650.  The EFR for this UART is
+        * found at offset 0x09. Instead check the Deice ID (DVID)
+        * register for a 2, 4 or 8 port UART.
+        */
+       if (up->port.flags & UPF_EXAR_EFR) {
+               status1 = serial_in(up, UART_EXAR_DVID);
+               if (status1 == 0x82 || status1 == 0x84 || status1 == 0x88) {
+                       DEBUG_AUTOCONF("Exar XR17V35x ");
+                       up->port.type = PORT_XR17V35X;
+                       up->capabilities |= UART_CAP_AFE | UART_CAP_EFR |
+                                               UART_CAP_SLEEP;
+
+                       return;
+               }
+
+       }
+
+       /*
+        * Check for presence of the EFR when DLAB is set.
+        * Only ST16C650V1 UARTs pass this test.
+        */
+       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
+       if (serial_in(up, UART_EFR) == 0) {
+               serial_out(up, UART_EFR, 0xA8);
+               if (serial_in(up, UART_EFR) != 0) {
+                       DEBUG_AUTOCONF("EFRv1 ");
+                       up->port.type = PORT_16650;
+                       up->capabilities |= UART_CAP_EFR | UART_CAP_SLEEP;
+               } else {
+                       DEBUG_AUTOCONF("Motorola 8xxx DUART ");
+               }
+               serial_out(up, UART_EFR, 0);
+               return;
+       }
+
+       /*
+        * Maybe it requires 0xbf to be written to the LCR.
+        * (other ST16C650V2 UARTs, TI16C752A, etc)
+        */
+       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+       if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) {
+               DEBUG_AUTOCONF("EFRv2 ");
+               autoconfig_has_efr(up);
+               return;
+       }
+
+       /*
+        * Check for a National Semiconductor SuperIO chip.
+        * Attempt to switch to bank 2, read the value of the LOOP bit
+        * from EXCR1. Switch back to bank 0, change it in MCR. Then
+        * switch back to bank 2, read it from EXCR1 again and check
+        * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2
+        */
+       serial_out(up, UART_LCR, 0);
+       status1 = serial_in(up, UART_MCR);
+       serial_out(up, UART_LCR, 0xE0);
+       status2 = serial_in(up, 0x02); /* EXCR1 */
+
+       if (!((status2 ^ status1) & UART_MCR_LOOP)) {
+               serial_out(up, UART_LCR, 0);
+               serial_out(up, UART_MCR, status1 ^ UART_MCR_LOOP);
+               serial_out(up, UART_LCR, 0xE0);
+               status2 = serial_in(up, 0x02); /* EXCR1 */
+               serial_out(up, UART_LCR, 0);
+               serial_out(up, UART_MCR, status1);
+
+               if ((status2 ^ status1) & UART_MCR_LOOP) {
+                       unsigned short quot;
+
+                       serial_out(up, UART_LCR, 0xE0);
+
+                       quot = serial_dl_read(up);
+                       quot <<= 3;
+
+                       if (ns16550a_goto_highspeed(up))
+                               serial_dl_write(up, quot);
+
+                       serial_out(up, UART_LCR, 0);
+
+                       up->port.uartclk = 921600*16;
+                       up->port.type = PORT_NS16550A;
+                       up->capabilities |= UART_NATSEMI;
+                       return;
+               }
+       }
+
+       /*
+        * No EFR.  Try to detect a TI16750, which only sets bit 5 of
+        * the IIR when 64 byte FIFO mode is enabled when DLAB is set.
+        * Try setting it with and without DLAB set.  Cheap clones
+        * set bit 5 without DLAB set.
+        */
+       serial_out(up, UART_LCR, 0);
+       serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
+       status1 = serial_in(up, UART_IIR) >> 5;
+       serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
+       serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
+       status2 = serial_in(up, UART_IIR) >> 5;
+       serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+       serial_out(up, UART_LCR, 0);
+
+       DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2);
+
+       if (status1 == 6 && status2 == 7) {
+               up->port.type = PORT_16750;
+               up->capabilities |= UART_CAP_AFE | UART_CAP_SLEEP;
+               return;
+       }
+
+       /*
+        * Try writing and reading the UART_IER_UUE bit (b6).
+        * If it works, this is probably one of the Xscale platform's
+        * internal UARTs.
+        * We're going to explicitly set the UUE bit to 0 before
+        * trying to write and read a 1 just to make sure it's not
+        * already a 1 and maybe locked there before we even start start.
+        */
+       iersave = serial_in(up, UART_IER);
+       serial_out(up, UART_IER, iersave & ~UART_IER_UUE);
+       if (!(serial_in(up, UART_IER) & UART_IER_UUE)) {
+               /*
+                * OK it's in a known zero state, try writing and reading
+                * without disturbing the current state of the other bits.
+                */
+               serial_out(up, UART_IER, iersave | UART_IER_UUE);
+               if (serial_in(up, UART_IER) & UART_IER_UUE) {
+                       /*
+                        * It's an Xscale.
+                        * We'll leave the UART_IER_UUE bit set to 1 (enabled).
+                        */
+                       DEBUG_AUTOCONF("Xscale ");
+                       up->port.type = PORT_XSCALE;
+                       up->capabilities |= UART_CAP_UUE | UART_CAP_RTOIE;
+                       return;
+               }
+       } else {
+               /*
+                * If we got here we couldn't force the IER_UUE bit to 0.
+                * Log it and continue.
+                */
+               DEBUG_AUTOCONF("Couldn't force IER_UUE to 0 ");
+       }
+       serial_out(up, UART_IER, iersave);
+
+       /*
+        * Exar uarts have EFR in a weird location
+        */
+       if (up->port.flags & UPF_EXAR_EFR) {
+               DEBUG_AUTOCONF("Exar XR17D15x ");
+               up->port.type = PORT_XR17D15X;
+               up->capabilities |= UART_CAP_AFE | UART_CAP_EFR |
+                                   UART_CAP_SLEEP;
+
+               return;
+       }
+
+       /*
+        * We distinguish between 16550A and U6 16550A by counting
+        * how many bytes are in the FIFO.
+        */
+       if (up->port.type == PORT_16550A && size_fifo(up) == 64) {
+               up->port.type = PORT_U6_16550A;
+               up->capabilities |= UART_CAP_AFE;
+       }
+}
+
+/*
+ * This routine is called by rs_init() to initialize a specific serial
+ * port.  It determines what type of UART chip this serial port is
+ * using: 8250, 16450, 16550, 16550A.  The important question is
+ * whether or not this UART is a 16550A or not, since this will
+ * determine whether or not we can use its FIFO features or not.
+ */
+static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
+{
+       unsigned char status1, scratch, scratch2, scratch3;
+       unsigned char save_lcr, save_mcr;
+       struct uart_port *port = &up->port;
+       unsigned long flags;
+       unsigned int old_capabilities;
+
+       if (!port->iobase && !port->mapbase && !port->membase)
+               return;
+
+       DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04lx, 0x%p): ",
+                      serial_index(port), port->iobase, port->membase);
+
+       /*
+        * We really do need global IRQs disabled here - we're going to
+        * be frobbing the chips IRQ enable register to see if it exists.
+        */
+       spin_lock_irqsave(&port->lock, flags);
+
+       up->capabilities = 0;
+       up->bugs = 0;
+
+       if (!(port->flags & UPF_BUGGY_UART)) {
+               /*
+                * Do a simple existence test first; if we fail this,
+                * there's no point trying anything else.
+                *
+                * 0x80 is used as a nonsense port to prevent against
+                * false positives due to ISA bus float.  The
+                * assumption is that 0x80 is a non-existent port;
+                * which should be safe since include/asm/io.h also
+                * makes this assumption.
+                *
+                * Note: this is safe as long as MCR bit 4 is clear
+                * and the device is in "PC" mode.
+                */
+               scratch = serial_in(up, UART_IER);
+               serial_out(up, UART_IER, 0);
+#ifdef __i386__
+               outb(0xff, 0x080);
+#endif
+               /*
+                * Mask out IER[7:4] bits for test as some UARTs (e.g. TL
+                * 16C754B) allow only to modify them if an EFR bit is set.
+                */
+               scratch2 = serial_in(up, UART_IER) & 0x0f;
+               serial_out(up, UART_IER, 0x0F);
+#ifdef __i386__
+               outb(0, 0x080);
+#endif
+               scratch3 = serial_in(up, UART_IER) & 0x0f;
+               serial_out(up, UART_IER, scratch);
+               if (scratch2 != 0 || scratch3 != 0x0F) {
+                       /*
+                        * We failed; there's nothing here
+                        */
+                       spin_unlock_irqrestore(&port->lock, flags);
+                       DEBUG_AUTOCONF("IER test failed (%02x, %02x) ",
+                                      scratch2, scratch3);
+                       goto out;
+               }
+       }
+
+       save_mcr = serial_in(up, UART_MCR);
+       save_lcr = serial_in(up, UART_LCR);
+
+       /*
+        * Check to see if a UART is really there.  Certain broken
+        * internal modems based on the Rockwell chipset fail this
+        * test, because they apparently don't implement the loopback
+        * test mode.  So this test is skipped on the COM 1 through
+        * COM 4 ports.  This *should* be safe, since no board
+        * manufacturer would be stupid enough to design a board
+        * that conflicts with COM 1-4 --- we hope!
+        */
+       if (!(port->flags & UPF_SKIP_TEST)) {
+               serial_out(up, UART_MCR, UART_MCR_LOOP | 0x0A);
+               status1 = serial_in(up, UART_MSR) & 0xF0;
+               serial_out(up, UART_MCR, save_mcr);
+               if (status1 != 0x90) {
+                       spin_unlock_irqrestore(&port->lock, flags);
+                       DEBUG_AUTOCONF("LOOP test failed (%02x) ",
+                                      status1);
+                       goto out;
+               }
+       }
+
+       /*
+        * We're pretty sure there's a port here.  Lets find out what
+        * type of port it is.  The IIR top two bits allows us to find
+        * out if it's 8250 or 16450, 16550, 16550A or later.  This
+        * determines what we test for next.
+        *
+        * We also initialise the EFR (if any) to zero for later.  The
+        * EFR occupies the same register location as the FCR and IIR.
+        */
+       serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+       serial_out(up, UART_EFR, 0);
+       serial_out(up, UART_LCR, 0);
+
+       serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+       scratch = serial_in(up, UART_IIR) >> 6;
+
+       switch (scratch) {
+       case 0:
+               autoconfig_8250(up);
+               break;
+       case 1:
+               port->type = PORT_UNKNOWN;
+               break;
+       case 2:
+               port->type = PORT_16550;
+               break;
+       case 3:
+               autoconfig_16550a(up);
+               break;
+       }
+
+#ifdef CONFIG_SERIAL_8250_RSA
+       /*
+        * Only probe for RSA ports if we got the region.
+        */
+       if (port->type == PORT_16550A && probeflags & PROBE_RSA) {
+               int i;
+
+               for (i = 0 ; i < probe_rsa_count; ++i) {
+                       if (probe_rsa[i] == port->iobase && __enable_rsa(up)) {
+                               port->type = PORT_RSA;
+                               break;
+                       }
+               }
+       }
+#endif
+
+       serial_out(up, UART_LCR, save_lcr);
+
+       port->fifosize = uart_config[up->port.type].fifo_size;
+       old_capabilities = up->capabilities; 
+       up->capabilities = uart_config[port->type].flags;
+       up->tx_loadsz = uart_config[port->type].tx_loadsz;
+
+       if (port->type == PORT_UNKNOWN)
+               goto out_lock;
+
+       /*
+        * Reset the UART.
+        */
+#ifdef CONFIG_SERIAL_8250_RSA
+       if (port->type == PORT_RSA)
+               serial_out(up, UART_RSA_FRR, 0);
+#endif
+       serial_out(up, UART_MCR, save_mcr);
+       serial8250_clear_fifos(up);
+       serial_in(up, UART_RX);
+       if (up->capabilities & UART_CAP_UUE)
+               serial_out(up, UART_IER, UART_IER_UUE);
+       else
+               serial_out(up, UART_IER, 0);
+
+out_lock:
+       spin_unlock_irqrestore(&port->lock, flags);
+       if (up->capabilities != old_capabilities) {
+               printk(KERN_WARNING
+                      "ttyS%d: detected caps %08x should be %08x\n",
+                      serial_index(port), old_capabilities,
+                      up->capabilities);
+       }
+out:
+       DEBUG_AUTOCONF("iir=%d ", scratch);
+       DEBUG_AUTOCONF("type=%s\n", uart_config[port->type].name);
+}
+
+static void autoconfig_irq(struct uart_8250_port *up)
+{
+       struct uart_port *port = &up->port;
+       unsigned char save_mcr, save_ier;
+       unsigned char save_ICP = 0;
+       unsigned int ICP = 0;
+       unsigned long irqs;
+       int irq;
+
+       if (port->flags & UPF_FOURPORT) {
+               ICP = (port->iobase & 0xfe0) | 0x1f;
+               save_ICP = inb_p(ICP);
+               outb_p(0x80, ICP);
+               inb_p(ICP);
+       }
+
+       /* forget possible initially masked and pending IRQ */
+       probe_irq_off(probe_irq_on());
+       save_mcr = serial_in(up, UART_MCR);
+       save_ier = serial_in(up, UART_IER);
+       serial_out(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2);
+
+       irqs = probe_irq_on();
+       serial_out(up, UART_MCR, 0);
+       udelay(10);
+       if (port->flags & UPF_FOURPORT) {
+               serial_out(up, UART_MCR,
+                           UART_MCR_DTR | UART_MCR_RTS);
+       } else {
+               serial_out(up, UART_MCR,
+                           UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
+       }
+       serial_out(up, UART_IER, 0x0f); /* enable all intrs */
+       serial_in(up, UART_LSR);
+       serial_in(up, UART_RX);
+       serial_in(up, UART_IIR);
+       serial_in(up, UART_MSR);
+       serial_out(up, UART_TX, 0xFF);
+       udelay(20);
+       irq = probe_irq_off(irqs);
+
+       serial_out(up, UART_MCR, save_mcr);
+       serial_out(up, UART_IER, save_ier);
+
+       if (port->flags & UPF_FOURPORT)
+               outb_p(save_ICP, ICP);
+
+       port->irq = (irq > 0) ? irq : 0;
+}
+
+static inline void __stop_tx(struct uart_8250_port *p)
+{
+       if (p->ier & UART_IER_THRI) {
+               p->ier &= ~UART_IER_THRI;
+               serial_out(p, UART_IER, p->ier);
+       }
+}
+
+static void serial8250_stop_tx(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+
+       __stop_tx(up);
+
+       /*
+        * We really want to stop the transmitter from sending.
+        */
+       if (port->type == PORT_16C950) {
+               up->acr |= UART_ACR_TXDIS;
+               serial_icr_write(up, UART_ACR, up->acr);
+       }
+}
+
+static void serial8250_start_tx(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+
+       if (up->dma && !serial8250_tx_dma(up)) {
+               return;
+       } else if (!(up->ier & UART_IER_THRI)) {
+               up->ier |= UART_IER_THRI;
+               serial_port_out(port, UART_IER, up->ier);
+
+               if (up->bugs & UART_BUG_TXEN) {
+                       unsigned char lsr;
+                       lsr = serial_in(up, UART_LSR);
+                       up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
+                       if (lsr & UART_LSR_TEMT)
+                               serial8250_tx_chars(up);
+               }
+       }
+
+       /*
+        * Re-enable the transmitter if we disabled it.
+        */
+       if (port->type == PORT_16C950 && up->acr & UART_ACR_TXDIS) {
+               up->acr &= ~UART_ACR_TXDIS;
+               serial_icr_write(up, UART_ACR, up->acr);
+       }
+}
+
+static void serial8250_stop_rx(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+
+       up->ier &= ~UART_IER_RLSI;
+       up->port.read_status_mask &= ~UART_LSR_DR;
+       serial_port_out(port, UART_IER, up->ier);
+}
+
+static void serial8250_enable_ms(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+
+       /* no MSR capabilities */
+       if (up->bugs & UART_BUG_NOMSR)
+               return;
+
+       up->ier |= UART_IER_MSI;
+       serial_port_out(port, UART_IER, up->ier);
+}
+
+/*
+ * serial8250_rx_chars: processes according to the passed in LSR
+ * value, and returns the remaining LSR bits not handled
+ * by this Rx routine.
+ */
+unsigned char
+serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr)
+{
+       struct uart_port *port = &up->port;
+       unsigned char ch;
+       int max_count = 256;
+       char flag;
+
+       do {
+               if (likely(lsr & UART_LSR_DR))
+                       ch = serial_in(up, UART_RX);
+               else
+                       /*
+                        * Intel 82571 has a Serial Over Lan device that will
+                        * set UART_LSR_BI without setting UART_LSR_DR when
+                        * it receives a break. To avoid reading from the
+                        * receive buffer without UART_LSR_DR bit set, we
+                        * just force the read character to be 0
+                        */
+                       ch = 0;
+
+               flag = TTY_NORMAL;
+               port->icount.rx++;
+
+               lsr |= up->lsr_saved_flags;
+               up->lsr_saved_flags = 0;
+
+               if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) {
+                       if (lsr & UART_LSR_BI) {
+                               lsr &= ~(UART_LSR_FE | UART_LSR_PE);
+                               port->icount.brk++;
+                               /*
+                                * We do the SysRQ and SAK checking
+                                * here because otherwise the break
+                                * may get masked by ignore_status_mask
+                                * or read_status_mask.
+                                */
+                               if (uart_handle_break(port))
+                                       goto ignore_char;
+                       } else if (lsr & UART_LSR_PE)
+                               port->icount.parity++;
+                       else if (lsr & UART_LSR_FE)
+                               port->icount.frame++;
+                       if (lsr & UART_LSR_OE)
+                               port->icount.overrun++;
+
+                       /*
+                        * Mask off conditions which should be ignored.
+                        */
+                       lsr &= port->read_status_mask;
+
+                       if (lsr & UART_LSR_BI) {
+                               DEBUG_INTR("handling break....");
+                               flag = TTY_BREAK;
+                       } else if (lsr & UART_LSR_PE)
+                               flag = TTY_PARITY;
+                       else if (lsr & UART_LSR_FE)
+                               flag = TTY_FRAME;
+               }
+               if (uart_handle_sysrq_char(port, ch))
+                       goto ignore_char;
+
+               uart_insert_char(port, lsr, UART_LSR_OE, ch, flag);
+
+ignore_char:
+               lsr = serial_in(up, UART_LSR);
+       } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0));
+       spin_unlock(&port->lock);
+       tty_flip_buffer_push(&port->state->port);
+       spin_lock(&port->lock);
+       return lsr;
+}
+EXPORT_SYMBOL_GPL(serial8250_rx_chars);
+
+void serial8250_tx_chars(struct uart_8250_port *up)
+{
+       struct uart_port *port = &up->port;
+       struct circ_buf *xmit = &port->state->xmit;
+       int count;
+
+       if (port->x_char) {
+               serial_out(up, UART_TX, port->x_char);
+               port->icount.tx++;
+               port->x_char = 0;
+               return;
+       }
+       if (uart_tx_stopped(port)) {
+               serial8250_stop_tx(port);
+               return;
+       }
+       if (uart_circ_empty(xmit)) {
+               __stop_tx(up);
+               return;
+       }
+
+       count = up->tx_loadsz;
+       do {
+               serial_out(up, UART_TX, xmit->buf[xmit->tail]);
+               xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+               port->icount.tx++;
+               if (uart_circ_empty(xmit))
+                       break;
+               if (up->capabilities & UART_CAP_HFIFO) {
+                       if ((serial_port_in(port, UART_LSR) & BOTH_EMPTY) !=
+                           BOTH_EMPTY)
+                               break;
+               }
+       } while (--count > 0);
+
+       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+               uart_write_wakeup(port);
+
+       DEBUG_INTR("THRE...");
+
+       if (uart_circ_empty(xmit))
+               __stop_tx(up);
+}
+EXPORT_SYMBOL_GPL(serial8250_tx_chars);
+
+unsigned int serial8250_modem_status(struct uart_8250_port *up)
+{
+       struct uart_port *port = &up->port;
+       unsigned int status = serial_in(up, UART_MSR);
+
+       status |= up->msr_saved_flags;
+       up->msr_saved_flags = 0;
+       if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI &&
+           port->state != NULL) {
+               if (status & UART_MSR_TERI)
+                       port->icount.rng++;
+               if (status & UART_MSR_DDSR)
+                       port->icount.dsr++;
+               if (status & UART_MSR_DDCD)
+                       uart_handle_dcd_change(port, status & UART_MSR_DCD);
+               if (status & UART_MSR_DCTS)
+                       uart_handle_cts_change(port, status & UART_MSR_CTS);
+
+               wake_up_interruptible(&port->state->port.delta_msr_wait);
+       }
+
+       return status;
+}
+EXPORT_SYMBOL_GPL(serial8250_modem_status);
+
+/*
+ * This handles the interrupt from one port.
+ */
+int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
+{
+       unsigned char status;
+       unsigned long flags;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+       int dma_err = 0;
+
+       if (iir & UART_IIR_NO_INT)
+               return 0;
+
+       spin_lock_irqsave(&port->lock, flags);
+
+       status = serial_port_in(port, UART_LSR);
+
+       DEBUG_INTR("status = %x...", status);
+
+       if (status & (UART_LSR_DR | UART_LSR_BI)) {
+               if (up->dma)
+                       dma_err = serial8250_rx_dma(up, iir);
+
+               if (!up->dma || dma_err)
+                       status = serial8250_rx_chars(up, status);
+       }
+       serial8250_modem_status(up);
+       if (status & UART_LSR_THRE)
+               serial8250_tx_chars(up);
+
+       spin_unlock_irqrestore(&port->lock, flags);
+       return 1;
+}
+EXPORT_SYMBOL_GPL(serial8250_handle_irq);
+
+static int serial8250_default_handle_irq(struct uart_port *port)
+{
+       unsigned int iir = serial_port_in(port, UART_IIR);
+
+       return serial8250_handle_irq(port, iir);
+}
+
+/*
+ * These Exar UARTs have an extra interrupt indicator that could
+ * fire for a few unimplemented interrupts.  One of which is a
+ * wakeup event when coming out of sleep.  Put this here just
+ * to be on the safe side that these interrupts don't go unhandled.
+ */
+static int exar_handle_irq(struct uart_port *port)
+{
+       unsigned char int0, int1, int2, int3;
+       unsigned int iir = serial_port_in(port, UART_IIR);
+       int ret;
+
+       ret = serial8250_handle_irq(port, iir);
+
+       if ((port->type == PORT_XR17V35X) ||
+          (port->type == PORT_XR17D15X)) {
+               int0 = serial_port_in(port, 0x80);
+               int1 = serial_port_in(port, 0x81);
+               int2 = serial_port_in(port, 0x82);
+               int3 = serial_port_in(port, 0x83);
+       }
+
+       return ret;
+}
+
+/*
+ * This is the serial driver's interrupt routine.
+ *
+ * Arjan thinks the old way was overly complex, so it got simplified.
+ * Alan disagrees, saying that need the complexity to handle the weird
+ * nature of ISA shared interrupts.  (This is a special exception.)
+ *
+ * In order to handle ISA shared interrupts properly, we need to check
+ * that all ports have been serviced, and therefore the ISA interrupt
+ * line has been de-asserted.
+ *
+ * This means we need to loop through all ports. checking that they
+ * don't have an interrupt pending.
+ */
+static irqreturn_t serial8250_interrupt(int irq, void *dev_id)
+{
+       struct irq_info *i = dev_id;
+       struct list_head *l, *end = NULL;
+       int pass_counter = 0, handled = 0;
+
+       DEBUG_INTR("serial8250_interrupt(%d)...", irq);
+
+       spin_lock(&i->lock);
+
+       l = i->head;
+       do {
+               struct uart_8250_port *up;
+               struct uart_port *port;
+
+               up = list_entry(l, struct uart_8250_port, list);
+               port = &up->port;
+
+               if (port->handle_irq(port)) {
+                       handled = 1;
+                       end = NULL;
+               } else if (end == NULL)
+                       end = l;
+
+               l = l->next;
+
+               if (l == i->head && pass_counter++ > PASS_LIMIT) {
+                       /* If we hit this, we're dead. */
+                       printk_ratelimited(KERN_ERR
+                               "serial8250: too much work for irq%d\n", irq);
+                       break;
+               }
+       } while (l != end);
+
+       spin_unlock(&i->lock);
+
+       DEBUG_INTR("end.\n");
+
+       return IRQ_RETVAL(handled);
+}
+
+/*
+ * To support ISA shared interrupts, we need to have one interrupt
+ * handler that ensures that the IRQ line has been deasserted
+ * before returning.  Failing to do this will result in the IRQ
+ * line being stuck active, and, since ISA irqs are edge triggered,
+ * no more IRQs will be seen.
+ */
+static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up)
+{
+       spin_lock_irq(&i->lock);
+
+       if (!list_empty(i->head)) {
+               if (i->head == &up->list)
+                       i->head = i->head->next;
+               list_del(&up->list);
+       } else {
+               BUG_ON(i->head != &up->list);
+               i->head = NULL;
+       }
+       spin_unlock_irq(&i->lock);
+       /* List empty so throw away the hash node */
+       if (i->head == NULL) {
+               hlist_del(&i->node);
+               kfree(i);
+       }
+}
+
+static int serial_link_irq_chain(struct uart_8250_port *up)
+{
+       struct hlist_head *h;
+       struct hlist_node *n;
+       struct irq_info *i;
+       int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0;
+
+       mutex_lock(&hash_mutex);
+
+       h = &irq_lists[up->port.irq % NR_IRQ_HASH];
+
+       hlist_for_each(n, h) {
+               i = hlist_entry(n, struct irq_info, node);
+               if (i->irq == up->port.irq)
+                       break;
+       }
+
+       if (n == NULL) {
+               i = kzalloc(sizeof(struct irq_info), GFP_KERNEL);
+               if (i == NULL) {
+                       mutex_unlock(&hash_mutex);
+                       return -ENOMEM;
+               }
+               spin_lock_init(&i->lock);
+               i->irq = up->port.irq;
+               hlist_add_head(&i->node, h);
+       }
+       mutex_unlock(&hash_mutex);
+
+       spin_lock_irq(&i->lock);
+
+       if (i->head) {
+               list_add(&up->list, i->head);
+               spin_unlock_irq(&i->lock);
+
+               ret = 0;
+       } else {
+               INIT_LIST_HEAD(&up->list);
+               i->head = &up->list;
+               spin_unlock_irq(&i->lock);
+               irq_flags |= up->port.irqflags;
+               ret = request_irq(up->port.irq, serial8250_interrupt,
+                                 irq_flags, "serial", i);
+               if (ret < 0)
+                       serial_do_unlink(i, up);
+       }
+
+       return ret;
+}
+
+static void serial_unlink_irq_chain(struct uart_8250_port *up)
+{
+       struct irq_info *i;
+       struct hlist_node *n;
+       struct hlist_head *h;
+
+       mutex_lock(&hash_mutex);
+
+       h = &irq_lists[up->port.irq % NR_IRQ_HASH];
+
+       hlist_for_each(n, h) {
+               i = hlist_entry(n, struct irq_info, node);
+               if (i->irq == up->port.irq)
+                       break;
+       }
+
+       BUG_ON(n == NULL);
+       BUG_ON(i->head == NULL);
+
+       if (list_empty(i->head))
+               free_irq(up->port.irq, i);
+
+       serial_do_unlink(i, up);
+       mutex_unlock(&hash_mutex);
+}
+
+/*
+ * This function is used to handle ports that do not have an
+ * interrupt.  This doesn't work very well for 16450's, but gives
+ * barely passable results for a 16550A.  (Although at the expense
+ * of much CPU overhead).
+ */
+static void serial8250_timeout(unsigned long data)
+{
+       struct uart_8250_port *up = (struct uart_8250_port *)data;
+
+       up->port.handle_irq(&up->port);
+       mod_timer(&up->timer, jiffies + uart_poll_timeout(&up->port));
+}
+
+static void serial8250_backup_timeout(unsigned long data)
+{
+       struct uart_8250_port *up = (struct uart_8250_port *)data;
+       unsigned int iir, ier = 0, lsr;
+       unsigned long flags;
+
+       spin_lock_irqsave(&up->port.lock, flags);
+
+       /*
+        * Must disable interrupts or else we risk racing with the interrupt
+        * based handler.
+        */
+       if (up->port.irq) {
+               ier = serial_in(up, UART_IER);
+               serial_out(up, UART_IER, 0);
+       }
+
+       iir = serial_in(up, UART_IIR);
+
+       /*
+        * This should be a safe test for anyone who doesn't trust the
+        * IIR bits on their UART, but it's specifically designed for
+        * the "Diva" UART used on the management processor on many HP
+        * ia64 and parisc boxes.
+        */
+       lsr = serial_in(up, UART_LSR);
+       up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
+       if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) &&
+           (!uart_circ_empty(&up->port.state->xmit) || up->port.x_char) &&
+           (lsr & UART_LSR_THRE)) {
+               iir &= ~(UART_IIR_ID | UART_IIR_NO_INT);
+               iir |= UART_IIR_THRI;
+       }
+
+       if (!(iir & UART_IIR_NO_INT))
+               serial8250_tx_chars(up);
+
+       if (up->port.irq)
+               serial_out(up, UART_IER, ier);
+
+       spin_unlock_irqrestore(&up->port.lock, flags);
+
+       /* Standard timer interval plus 0.2s to keep the port running */
+       mod_timer(&up->timer,
+               jiffies + uart_poll_timeout(&up->port) + HZ / 5);
+}
+
+static unsigned int serial8250_tx_empty(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+       unsigned long flags;
+       unsigned int lsr;
+
+       spin_lock_irqsave(&port->lock, flags);
+       lsr = serial_port_in(port, UART_LSR);
+       up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0;
+}
+
+static unsigned int serial8250_get_mctrl(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+       unsigned int status;
+       unsigned int ret;
+
+       status = serial8250_modem_status(up);
+
+       ret = 0;
+       if (status & UART_MSR_DCD)
+               ret |= TIOCM_CAR;
+       if (status & UART_MSR_RI)
+               ret |= TIOCM_RNG;
+       if (status & UART_MSR_DSR)
+               ret |= TIOCM_DSR;
+       if (status & UART_MSR_CTS)
+               ret |= TIOCM_CTS;
+       return ret;
+}
+
+static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+       unsigned char mcr = 0;
+
+       if (mctrl & TIOCM_RTS)
+               mcr |= UART_MCR_RTS;
+       if (mctrl & TIOCM_DTR)
+               mcr |= UART_MCR_DTR;
+       if (mctrl & TIOCM_OUT1)
+               mcr |= UART_MCR_OUT1;
+       if (mctrl & TIOCM_OUT2)
+               mcr |= UART_MCR_OUT2;
+       if (mctrl & TIOCM_LOOP)
+               mcr |= UART_MCR_LOOP;
+
+       mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr;
+
+       serial_port_out(port, UART_MCR, mcr);
+}
+
+static void serial8250_break_ctl(struct uart_port *port, int break_state)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+       unsigned long flags;
+
+       spin_lock_irqsave(&port->lock, flags);
+       if (break_state == -1)
+               up->lcr |= UART_LCR_SBC;
+       else
+               up->lcr &= ~UART_LCR_SBC;
+       serial_port_out(port, UART_LCR, up->lcr);
+       spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/*
+ *     Wait for transmitter & holding register to empty
+ */
+static void wait_for_xmitr(struct uart_8250_port *up, int bits)
+{
+       unsigned int status, tmout = 10000;
+
+       /* Wait up to 10ms for the character(s) to be sent. */
+       for (;;) {
+               status = serial_in(up, UART_LSR);
+
+               up->lsr_saved_flags |= status & LSR_SAVE_FLAGS;
+
+               if ((status & bits) == bits)
+                       break;
+               if (--tmout == 0)
+                       break;
+               udelay(1);
+       }
+
+       /* Wait up to 1s for flow control if necessary */
+       if (up->port.flags & UPF_CONS_FLOW) {
+               unsigned int tmout;
+               for (tmout = 1000000; tmout; tmout--) {
+                       unsigned int msr = serial_in(up, UART_MSR);
+                       up->msr_saved_flags |= msr & MSR_SAVE_FLAGS;
+                       if (msr & UART_MSR_CTS)
+                               break;
+                       udelay(1);
+                       touch_nmi_watchdog();
+               }
+       }
+}
+
+#ifdef CONFIG_CONSOLE_POLL
+/*
+ * Console polling routines for writing and reading from the uart while
+ * in an interrupt or debug context.
+ */
+
+static int serial8250_get_poll_char(struct uart_port *port)
+{
+       unsigned char lsr = serial_port_in(port, UART_LSR);
+
+       if (!(lsr & UART_LSR_DR))
+               return NO_POLL_CHAR;
+
+       return serial_port_in(port, UART_RX);
+}
+
+
+static void serial8250_put_poll_char(struct uart_port *port,
+                        unsigned char c)
+{
+       unsigned int ier;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+
+       /*
+        *      First save the IER then disable the interrupts
+        */
+       ier = serial_port_in(port, UART_IER);
+       if (up->capabilities & UART_CAP_UUE)
+               serial_port_out(port, UART_IER, UART_IER_UUE);
+       else
+               serial_port_out(port, UART_IER, 0);
+
+       wait_for_xmitr(up, BOTH_EMPTY);
+       /*
+        *      Send the character out.
+        *      If a LF, also do CR...
+        */
+       serial_port_out(port, UART_TX, c);
+       if (c == 10) {
+               wait_for_xmitr(up, BOTH_EMPTY);
+               serial_port_out(port, UART_TX, 13);
+       }
+
+       /*
+        *      Finally, wait for transmitter to become empty
+        *      and restore the IER
+        */
+       wait_for_xmitr(up, BOTH_EMPTY);
+       serial_port_out(port, UART_IER, ier);
+}
+
+#endif /* CONFIG_CONSOLE_POLL */
+
+static int serial8250_startup(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+       unsigned long flags;
+       unsigned char lsr, iir;
+       int retval;
+
+       if (port->type == PORT_8250_CIR)
+               return -ENODEV;
+
+       if (!port->fifosize)
+               port->fifosize = uart_config[port->type].fifo_size;
+       if (!up->tx_loadsz)
+               up->tx_loadsz = uart_config[port->type].tx_loadsz;
+       if (!up->capabilities)
+               up->capabilities = uart_config[port->type].flags;
+       up->mcr = 0;
+
+       if (port->iotype != up->cur_iotype)
+               set_io_from_upio(port);
+
+       if (port->type == PORT_16C950) {
+               /* Wake up and initialize UART */
+               up->acr = 0;
+               serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B);
+               serial_port_out(port, UART_EFR, UART_EFR_ECB);
+               serial_port_out(port, UART_IER, 0);
+               serial_port_out(port, UART_LCR, 0);
+               serial_icr_write(up, UART_CSR, 0); /* Reset the UART */
+               serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B);
+               serial_port_out(port, UART_EFR, UART_EFR_ECB);
+               serial_port_out(port, UART_LCR, 0);
+       }
+
+#ifdef CONFIG_SERIAL_8250_RSA
+       /*
+        * If this is an RSA port, see if we can kick it up to the
+        * higher speed clock.
+        */
+       enable_rsa(up);
+#endif
+
+       /*
+        * Clear the FIFO buffers and disable them.
+        * (they will be reenabled in set_termios())
+        */
+       serial8250_clear_fifos(up);
+
+       /*
+        * Clear the interrupt registers.
+        */
+       serial_port_in(port, UART_LSR);
+       serial_port_in(port, UART_RX);
+       serial_port_in(port, UART_IIR);
+       serial_port_in(port, UART_MSR);
+
+       /*
+        * At this point, there's no way the LSR could still be 0xff;
+        * if it is, then bail out, because there's likely no UART
+        * here.
+        */
+       if (!(port->flags & UPF_BUGGY_UART) &&
+           (serial_port_in(port, UART_LSR) == 0xff)) {
+               printk_ratelimited(KERN_INFO "ttyS%d: LSR safety check engaged!\n",
+                                  serial_index(port));
+               return -ENODEV;
+       }
+
+       /*
+        * For a XR16C850, we need to set the trigger levels
+        */
+       if (port->type == PORT_16850) {
+               unsigned char fctr;
+
+               serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+
+               fctr = serial_in(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX);
+               serial_port_out(port, UART_FCTR,
+                               fctr | UART_FCTR_TRGD | UART_FCTR_RX);
+               serial_port_out(port, UART_TRG, UART_TRG_96);
+               serial_port_out(port, UART_FCTR,
+                               fctr | UART_FCTR_TRGD | UART_FCTR_TX);
+               serial_port_out(port, UART_TRG, UART_TRG_96);
+
+               serial_port_out(port, UART_LCR, 0);
+       }
+
+       if (port->irq) {
+               unsigned char iir1;
+               /*
+                * Test for UARTs that do not reassert THRE when the
+                * transmitter is idle and the interrupt has already
+                * been cleared.  Real 16550s should always reassert
+                * this interrupt whenever the transmitter is idle and
+                * the interrupt is enabled.  Delays are necessary to
+                * allow register changes to become visible.
+                */
+               spin_lock_irqsave(&port->lock, flags);
+               if (up->port.irqflags & IRQF_SHARED)
+                       disable_irq_nosync(port->irq);
+
+               wait_for_xmitr(up, UART_LSR_THRE);
+               serial_port_out_sync(port, UART_IER, UART_IER_THRI);
+               udelay(1); /* allow THRE to set */
+               iir1 = serial_port_in(port, UART_IIR);
+               serial_port_out(port, UART_IER, 0);
+               serial_port_out_sync(port, UART_IER, UART_IER_THRI);
+               udelay(1); /* allow a working UART time to re-assert THRE */
+               iir = serial_port_in(port, UART_IIR);
+               serial_port_out(port, UART_IER, 0);
+
+               if (port->irqflags & IRQF_SHARED)
+                       enable_irq(port->irq);
+               spin_unlock_irqrestore(&port->lock, flags);
+
+               /*
+                * If the interrupt is not reasserted, or we otherwise
+                * don't trust the iir, setup a timer to kick the UART
+                * on a regular basis.
+                */
+               if ((!(iir1 & UART_IIR_NO_INT) && (iir & UART_IIR_NO_INT)) ||
+                   up->port.flags & UPF_BUG_THRE) {
+                       up->bugs |= UART_BUG_THRE;
+                       pr_debug("ttyS%d - using backup timer\n",
+                                serial_index(port));
+               }
+       }
+
+       /*
+        * The above check will only give an accurate result the first time
+        * the port is opened so this value needs to be preserved.
+        */
+       if (up->bugs & UART_BUG_THRE) {
+               up->timer.function = serial8250_backup_timeout;
+               up->timer.data = (unsigned long)up;
+               mod_timer(&up->timer, jiffies +
+                       uart_poll_timeout(port) + HZ / 5);
+       }
+
+       /*
+        * If the "interrupt" for this port doesn't correspond with any
+        * hardware interrupt, we use a timer-based system.  The original
+        * driver used to do this with IRQ0.
+        */
+       if (!port->irq) {
+               up->timer.data = (unsigned long)up;
+               mod_timer(&up->timer, jiffies + uart_poll_timeout(port));
+       } else {
+               retval = serial_link_irq_chain(up);
+               if (retval)
+                       return retval;
+       }
+
+       /*
+        * Now, initialize the UART
+        */
+       serial_port_out(port, UART_LCR, UART_LCR_WLEN8);
+
+       spin_lock_irqsave(&port->lock, flags);
+       if (up->port.flags & UPF_FOURPORT) {
+               if (!up->port.irq)
+                       up->port.mctrl |= TIOCM_OUT1;
+       } else
+               /*
+                * Most PC uarts need OUT2 raised to enable interrupts.
+                */
+               if (port->irq)
+                       up->port.mctrl |= TIOCM_OUT2;
+
+       serial8250_set_mctrl(port, port->mctrl);
+
+       /* Serial over Lan (SoL) hack:
+          Intel 8257x Gigabit ethernet chips have a
+          16550 emulation, to be used for Serial Over Lan.
+          Those chips take a longer time than a normal
+          serial device to signalize that a transmission
+          data was queued. Due to that, the above test generally
+          fails. One solution would be to delay the reading of
+          iir. However, this is not reliable, since the timeout
+          is variable. So, let's just don't test if we receive
+          TX irq. This way, we'll never enable UART_BUG_TXEN.
+        */
+       if (skip_txen_test || up->port.flags & UPF_NO_TXEN_TEST)
+               goto dont_test_tx_en;
+
+       /*
+        * Do a quick test to see if we receive an
+        * interrupt when we enable the TX irq.
+        */
+       serial_port_out(port, UART_IER, UART_IER_THRI);
+       lsr = serial_port_in(port, UART_LSR);
+       iir = serial_port_in(port, UART_IIR);
+       serial_port_out(port, UART_IER, 0);
+
+       if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) {
+               if (!(up->bugs & UART_BUG_TXEN)) {
+                       up->bugs |= UART_BUG_TXEN;
+                       pr_debug("ttyS%d - enabling bad tx status workarounds\n",
+                                serial_index(port));
+               }
+       } else {
+               up->bugs &= ~UART_BUG_TXEN;
+       }
+
+dont_test_tx_en:
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       /*
+        * Clear the interrupt registers again for luck, and clear the
+        * saved flags to avoid getting false values from polling
+        * routines or the previous session.
+        */
+       serial_port_in(port, UART_LSR);
+       serial_port_in(port, UART_RX);
+       serial_port_in(port, UART_IIR);
+       serial_port_in(port, UART_MSR);
+       up->lsr_saved_flags = 0;
+       up->msr_saved_flags = 0;
+
+       /*
+        * Request DMA channels for both RX and TX.
+        */
+       if (up->dma) {
+               retval = serial8250_request_dma(up);
+               if (retval) {
+                       pr_warn_ratelimited("ttyS%d - failed to request DMA\n",
+                                           serial_index(port));
+                       up->dma = NULL;
+               }
+       }
+
+       /*
+        * Finally, enable interrupts.  Note: Modem status interrupts
+        * are set via set_termios(), which will be occurring imminently
+        * anyway, so we don't enable them here.
+        */
+       up->ier = UART_IER_RLSI | UART_IER_RDI;
+       serial_port_out(port, UART_IER, up->ier);
+
+       if (port->flags & UPF_FOURPORT) {
+               unsigned int icp;
+               /*
+                * Enable interrupts on the AST Fourport board
+                */
+               icp = (port->iobase & 0xfe0) | 0x01f;
+               outb_p(0x80, icp);
+               inb_p(icp);
+       }
+
+       return 0;
+}
+
+static void serial8250_shutdown(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+       unsigned long flags;
+
+       /*
+        * Disable interrupts from this port
+        */
+       up->ier = 0;
+       serial_port_out(port, UART_IER, 0);
+
+       if (up->dma)
+               serial8250_release_dma(up);
+
+       spin_lock_irqsave(&port->lock, flags);
+       if (port->flags & UPF_FOURPORT) {
+               /* reset interrupts on the AST Fourport board */
+               inb((port->iobase & 0xfe0) | 0x1f);
+               port->mctrl |= TIOCM_OUT1;
+       } else
+               port->mctrl &= ~TIOCM_OUT2;
+
+       serial8250_set_mctrl(port, port->mctrl);
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       /*
+        * Disable break condition and FIFOs
+        */
+       serial_port_out(port, UART_LCR,
+                       serial_port_in(port, UART_LCR) & ~UART_LCR_SBC);
+       serial8250_clear_fifos(up);
+
+#ifdef CONFIG_SERIAL_8250_RSA
+       /*
+        * Reset the RSA board back to 115kbps compat mode.
+        */
+       disable_rsa(up);
+#endif
+
+       /*
+        * Read data port to reset things, and then unlink from
+        * the IRQ chain.
+        */
+       serial_port_in(port, UART_RX);
+
+       del_timer_sync(&up->timer);
+       up->timer.function = serial8250_timeout;
+       if (port->irq)
+               serial_unlink_irq_chain(up);
+}
+
+static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud)
+{
+       unsigned int quot;
+
+       /*
+        * Handle magic divisors for baud rates above baud_base on
+        * SMSC SuperIO chips.
+        */
+       if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
+           baud == (port->uartclk/4))
+               quot = 0x8001;
+       else if ((port->flags & UPF_MAGIC_MULTIPLIER) &&
+                baud == (port->uartclk/8))
+               quot = 0x8002;
+       else
+               quot = uart_get_divisor(port, baud);
+
+       return quot;
+}
+
+void
+serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
+                         struct ktermios *old)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+       unsigned char cval, fcr = 0;
+       unsigned long flags;
+       unsigned int baud, quot;
+       int fifo_bug = 0;
+
+       switch (termios->c_cflag & CSIZE) {
+       case CS5:
+               cval = UART_LCR_WLEN5;
+               break;
+       case CS6:
+               cval = UART_LCR_WLEN6;
+               break;
+       case CS7:
+               cval = UART_LCR_WLEN7;
+               break;
+       default:
+       case CS8:
+               cval = UART_LCR_WLEN8;
+               break;
+       }
+
+       if (termios->c_cflag & CSTOPB)
+               cval |= UART_LCR_STOP;
+       if (termios->c_cflag & PARENB) {
+               cval |= UART_LCR_PARITY;
+               if (up->bugs & UART_BUG_PARITY)
+                       fifo_bug = 1;
+       }
+       if (!(termios->c_cflag & PARODD))
+               cval |= UART_LCR_EPAR;
+#ifdef CMSPAR
+       if (termios->c_cflag & CMSPAR)
+               cval |= UART_LCR_SPAR;
+#endif
+
+       /*
+        * Ask the core to calculate the divisor for us.
+        */
+       baud = uart_get_baud_rate(port, termios, old,
+                                 port->uartclk / 16 / 0xffff,
+                                 port->uartclk / 16);
+       quot = serial8250_get_divisor(port, baud);
+
+       /*
+        * Oxford Semi 952 rev B workaround
+        */
+       if (up->bugs & UART_BUG_QUOT && (quot & 0xff) == 0)
+               quot++;
+
+       if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) {
+               fcr = uart_config[port->type].fcr;
+               if (baud < 2400 || fifo_bug) {
+                       fcr &= ~UART_FCR_TRIGGER_MASK;
+                       fcr |= UART_FCR_TRIGGER_1;
+               }
+       }
+
+       /*
+        * MCR-based auto flow control.  When AFE is enabled, RTS will be
+        * deasserted when the receive FIFO contains more characters than
+        * the trigger, or the MCR RTS bit is cleared.  In the case where
+        * the remote UART is not using CTS auto flow control, we must
+        * have sufficient FIFO entries for the latency of the remote
+        * UART to respond.  IOW, at least 32 bytes of FIFO.
+        */
+       if (up->capabilities & UART_CAP_AFE && port->fifosize >= 32) {
+               up->mcr &= ~UART_MCR_AFE;
+               if (termios->c_cflag & CRTSCTS)
+                       up->mcr |= UART_MCR_AFE;
+       }
+
+       /*
+        * Ok, we're now changing the port state.  Do it with
+        * interrupts disabled.
+        */
+       spin_lock_irqsave(&port->lock, flags);
+
+       /*
+        * Update the per-port timeout.
+        */
+       uart_update_timeout(port, termios->c_cflag, baud);
+
+       port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
+       if (termios->c_iflag & INPCK)
+               port->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
+       if (termios->c_iflag & (BRKINT | PARMRK))
+               port->read_status_mask |= UART_LSR_BI;
+
+       /*
+        * Characteres to ignore
+        */
+       port->ignore_status_mask = 0;
+       if (termios->c_iflag & IGNPAR)
+               port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
+       if (termios->c_iflag & IGNBRK) {
+               port->ignore_status_mask |= UART_LSR_BI;
+               /*
+                * If we're ignoring parity and break indicators,
+                * ignore overruns too (for real raw support).
+                */
+               if (termios->c_iflag & IGNPAR)
+                       port->ignore_status_mask |= UART_LSR_OE;
+       }
+
+       /*
+        * ignore all characters if CREAD is not set
+        */
+       if ((termios->c_cflag & CREAD) == 0)
+               port->ignore_status_mask |= UART_LSR_DR;
+
+       /*
+        * CTS flow control flag and modem status interrupts
+        */
+       up->ier &= ~UART_IER_MSI;
+       if (!(up->bugs & UART_BUG_NOMSR) &&
+                       UART_ENABLE_MS(&up->port, termios->c_cflag))
+               up->ier |= UART_IER_MSI;
+       if (up->capabilities & UART_CAP_UUE)
+               up->ier |= UART_IER_UUE;
+       if (up->capabilities & UART_CAP_RTOIE)
+               up->ier |= UART_IER_RTOIE;
+
+       serial_port_out(port, UART_IER, up->ier);
+
+       if (up->capabilities & UART_CAP_EFR) {
+               unsigned char efr = 0;
+               /*
+                * TI16C752/Startech hardware flow control.  FIXME:
+                * - TI16C752 requires control thresholds to be set.
+                * - UART_MCR_RTS is ineffective if auto-RTS mode is enabled.
+                */
+               if (termios->c_cflag & CRTSCTS)
+                       efr |= UART_EFR_CTS;
+
+               serial_port_out(port, UART_LCR, UART_LCR_CONF_MODE_B);
+               if (port->flags & UPF_EXAR_EFR)
+                       serial_port_out(port, UART_XR_EFR, efr);
+               else
+                       serial_port_out(port, UART_EFR, efr);
+       }
+
+       /* Workaround to enable 115200 baud on OMAP1510 internal ports */
+       if (is_omap1510_8250(up)) {
+               if (baud == 115200) {
+                       quot = 1;
+                       serial_port_out(port, UART_OMAP_OSC_12M_SEL, 1);
+               } else
+                       serial_port_out(port, UART_OMAP_OSC_12M_SEL, 0);
+       }
+
+       /*
+        * For NatSemi, switch to bank 2 not bank 1, to avoid resetting EXCR2,
+        * otherwise just set DLAB
+        */
+       if (up->capabilities & UART_NATSEMI)
+               serial_port_out(port, UART_LCR, 0xe0);
+       else
+               serial_port_out(port, UART_LCR, cval | UART_LCR_DLAB);
+
+       serial_dl_write(up, quot);
+
+       /*
+        * LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR
+        * is written without DLAB set, this mode will be disabled.
+        */
+       if (port->type == PORT_16750)
+               serial_port_out(port, UART_FCR, fcr);
+
+       serial_port_out(port, UART_LCR, cval);          /* reset DLAB */
+       up->lcr = cval;                                 /* Save LCR */
+       if (port->type != PORT_16750) {
+               /* emulated UARTs (Lucent Venus 167x) need two steps */
+               if (fcr & UART_FCR_ENABLE_FIFO)
+                       serial_port_out(port, UART_FCR, UART_FCR_ENABLE_FIFO);
+               serial_port_out(port, UART_FCR, fcr);           /* set fcr */
+       }
+       serial8250_set_mctrl(port, port->mctrl);
+       spin_unlock_irqrestore(&port->lock, flags);
+       /* Don't rewrite B0 */
+       if (tty_termios_baud_rate(termios))
+               tty_termios_encode_baud_rate(termios, baud, baud);
+}
+EXPORT_SYMBOL(serial8250_do_set_termios);
+
+static void
+serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
+                      struct ktermios *old)
+{
+       if (port->set_termios)
+               port->set_termios(port, termios, old);
+       else
+               serial8250_do_set_termios(port, termios, old);
+}
+
+static void
+serial8250_set_ldisc(struct uart_port *port, int new)
+{
+       if (new == N_PPS) {
+               port->flags |= UPF_HARDPPS_CD;
+               serial8250_enable_ms(port);
+       } else
+               port->flags &= ~UPF_HARDPPS_CD;
+}
+
+
+void serial8250_do_pm(struct uart_port *port, unsigned int state,
+                     unsigned int oldstate)
+{
+       struct uart_8250_port *p =
+               container_of(port, struct uart_8250_port, port);
+
+       serial8250_set_sleep(p, state != 0);
+}
+EXPORT_SYMBOL(serial8250_do_pm);
+
+static void
+serial8250_pm(struct uart_port *port, unsigned int state,
+             unsigned int oldstate)
+{
+       if (port->pm)
+               port->pm(port, state, oldstate);
+       else
+               serial8250_do_pm(port, state, oldstate);
+}
+
+static unsigned int serial8250_port_size(struct uart_8250_port *pt)
+{
+       if (pt->port.iotype == UPIO_AU)
+               return 0x1000;
+       if (is_omap1_8250(pt))
+               return 0x16 << pt->port.regshift;
+
+       return 8 << pt->port.regshift;
+}
+
+/*
+ * Resource handling.
+ */
+static int serial8250_request_std_resource(struct uart_8250_port *up)
+{
+       unsigned int size = serial8250_port_size(up);
+       struct uart_port *port = &up->port;
+       int ret = 0;
+
+       switch (port->iotype) {
+       case UPIO_AU:
+       case UPIO_TSI:
+       case UPIO_MEM32:
+       case UPIO_MEM:
+               if (!port->mapbase)
+                       break;
+
+               if (!request_mem_region(port->mapbase, size, "serial")) {
+                       ret = -EBUSY;
+                       break;
+               }
+
+               if (port->flags & UPF_IOREMAP) {
+                       port->membase = ioremap_nocache(port->mapbase, size);
+                       if (!port->membase) {
+                               release_mem_region(port->mapbase, size);
+                               ret = -ENOMEM;
+                       }
+               }
+               break;
+
+       case UPIO_HUB6:
+       case UPIO_PORT:
+               if (!request_region(port->iobase, size, "serial"))
+                       ret = -EBUSY;
+               break;
+       }
+       return ret;
+}
+
+static void serial8250_release_std_resource(struct uart_8250_port *up)
+{
+       unsigned int size = serial8250_port_size(up);
+       struct uart_port *port = &up->port;
+
+       switch (port->iotype) {
+       case UPIO_AU:
+       case UPIO_TSI:
+       case UPIO_MEM32:
+       case UPIO_MEM:
+               if (!port->mapbase)
+                       break;
+
+               if (port->flags & UPF_IOREMAP) {
+                       iounmap(port->membase);
+                       port->membase = NULL;
+               }
+
+               release_mem_region(port->mapbase, size);
+               break;
+
+       case UPIO_HUB6:
+       case UPIO_PORT:
+               release_region(port->iobase, size);
+               break;
+       }
+}
+
+static int serial8250_request_rsa_resource(struct uart_8250_port *up)
+{
+       unsigned long start = UART_RSA_BASE << up->port.regshift;
+       unsigned int size = 8 << up->port.regshift;
+       struct uart_port *port = &up->port;
+       int ret = -EINVAL;
+
+       switch (port->iotype) {
+       case UPIO_HUB6:
+       case UPIO_PORT:
+               start += port->iobase;
+               if (request_region(start, size, "serial-rsa"))
+                       ret = 0;
+               else
+                       ret = -EBUSY;
+               break;
+       }
+
+       return ret;
+}
+
+static void serial8250_release_rsa_resource(struct uart_8250_port *up)
+{
+       unsigned long offset = UART_RSA_BASE << up->port.regshift;
+       unsigned int size = 8 << up->port.regshift;
+       struct uart_port *port = &up->port;
+
+       switch (port->iotype) {
+       case UPIO_HUB6:
+       case UPIO_PORT:
+               release_region(port->iobase + offset, size);
+               break;
+       }
+}
+
+static void serial8250_release_port(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+
+       serial8250_release_std_resource(up);
+       if (port->type == PORT_RSA)
+               serial8250_release_rsa_resource(up);
+}
+
+static int serial8250_request_port(struct uart_port *port)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+       int ret;
+
+       if (port->type == PORT_8250_CIR)
+               return -ENODEV;
+
+       ret = serial8250_request_std_resource(up);
+       if (ret == 0 && port->type == PORT_RSA) {
+               ret = serial8250_request_rsa_resource(up);
+               if (ret < 0)
+                       serial8250_release_std_resource(up);
+       }
+
+       return ret;
+}
+
+static void serial8250_config_port(struct uart_port *port, int flags)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+       int probeflags = PROBE_ANY;
+       int ret;
+
+       if (port->type == PORT_8250_CIR)
+               return;
+
+       /*
+        * Find the region that we can probe for.  This in turn
+        * tells us whether we can probe for the type of port.
+        */
+       ret = serial8250_request_std_resource(up);
+       if (ret < 0)
+               return;
+
+       ret = serial8250_request_rsa_resource(up);
+       if (ret < 0)
+               probeflags &= ~PROBE_RSA;
+
+       if (port->iotype != up->cur_iotype)
+               set_io_from_upio(port);
+
+       if (flags & UART_CONFIG_TYPE)
+               autoconfig(up, probeflags);
+
+       /* if access method is AU, it is a 16550 with a quirk */
+       if (port->type == PORT_16550A && port->iotype == UPIO_AU)
+               up->bugs |= UART_BUG_NOMSR;
+
+       if (port->type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
+               autoconfig_irq(up);
+
+       if (port->type != PORT_RSA && probeflags & PROBE_RSA)
+               serial8250_release_rsa_resource(up);
+       if (port->type == PORT_UNKNOWN)
+               serial8250_release_std_resource(up);
+
+       /* Fixme: probably not the best place for this */
+       if ((port->type == PORT_XR17V35X) ||
+          (port->type == PORT_XR17D15X))
+               port->handle_irq = exar_handle_irq;
+}
+
+static int
+serial8250_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+       if (ser->irq >= nr_irqs || ser->irq < 0 ||
+           ser->baud_base < 9600 || ser->type < PORT_UNKNOWN ||
+           ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS ||
+           ser->type == PORT_STARTECH)
+               return -EINVAL;
+       return 0;
+}
+
+static const char *
+serial8250_type(struct uart_port *port)
+{
+       int type = port->type;
+
+       if (type >= ARRAY_SIZE(uart_config))
+               type = 0;
+       return uart_config[type].name;
+}
+
+static struct uart_ops serial8250_pops = {
+       .tx_empty       = serial8250_tx_empty,
+       .set_mctrl      = serial8250_set_mctrl,
+       .get_mctrl      = serial8250_get_mctrl,
+       .stop_tx        = serial8250_stop_tx,
+       .start_tx       = serial8250_start_tx,
+       .stop_rx        = serial8250_stop_rx,
+       .enable_ms      = serial8250_enable_ms,
+       .break_ctl      = serial8250_break_ctl,
+       .startup        = serial8250_startup,
+       .shutdown       = serial8250_shutdown,
+       .set_termios    = serial8250_set_termios,
+       .set_ldisc      = serial8250_set_ldisc,
+       .pm             = serial8250_pm,
+       .type           = serial8250_type,
+       .release_port   = serial8250_release_port,
+       .request_port   = serial8250_request_port,
+       .config_port    = serial8250_config_port,
+       .verify_port    = serial8250_verify_port,
+#ifdef CONFIG_CONSOLE_POLL
+       .poll_get_char = serial8250_get_poll_char,
+       .poll_put_char = serial8250_put_poll_char,
+#endif
+};
+
+static struct uart_8250_port serial8250_ports[UART_NR];
+
+static void (*serial8250_isa_config)(int port, struct uart_port *up,
+       unsigned short *capabilities);
+
+void serial8250_set_isa_configurator(
+       void (*v)(int port, struct uart_port *up, unsigned short *capabilities))
+{
+       serial8250_isa_config = v;
+}
+EXPORT_SYMBOL(serial8250_set_isa_configurator);
+
+static void __init serial8250_isa_init_ports(void)
+{
+       struct uart_8250_port *up;
+       static int first = 1;
+       int i, irqflag = 0;
+
+       if (!first)
+               return;
+       first = 0;
+
+       if (nr_uarts > UART_NR)
+               nr_uarts = UART_NR;
+
+       for (i = 0; i < nr_uarts; i++) {
+               struct uart_8250_port *up = &serial8250_ports[i];
+               struct uart_port *port = &up->port;
+
+               port->line = i;
+               spin_lock_init(&port->lock);
+
+               init_timer(&up->timer);
+               up->timer.function = serial8250_timeout;
+               up->cur_iotype = 0xFF;
+
+               /*
+                * ALPHA_KLUDGE_MCR needs to be killed.
+                */
+               up->mcr_mask = ~ALPHA_KLUDGE_MCR;
+               up->mcr_force = ALPHA_KLUDGE_MCR;
+
+               port->ops = &serial8250_pops;
+       }
+
+       if (share_irqs)
+               irqflag = IRQF_SHARED;
+
+       for (i = 0, up = serial8250_ports;
+            i < ARRAY_SIZE(old_serial_port) && i < nr_uarts;
+            i++, up++) {
+               struct uart_port *port = &up->port;
+
+               port->iobase   = old_serial_port[i].port;
+               port->irq      = irq_canonicalize(old_serial_port[i].irq);
+               port->irqflags = old_serial_port[i].irqflags;
+               port->uartclk  = old_serial_port[i].baud_base * 16;
+               port->flags    = old_serial_port[i].flags;
+               port->hub6     = old_serial_port[i].hub6;
+               port->membase  = old_serial_port[i].iomem_base;
+               port->iotype   = old_serial_port[i].io_type;
+               port->regshift = old_serial_port[i].iomem_reg_shift;
+               set_io_from_upio(port);
+               port->irqflags |= irqflag;
+               if (serial8250_isa_config != NULL)
+                       serial8250_isa_config(i, &up->port, &up->capabilities);
+
+       }
+}
+
+static void
+serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type)
+{
+       up->port.type = type;
+       if (!up->port.fifosize)
+               up->port.fifosize = uart_config[type].fifo_size;
+       if (!up->tx_loadsz)
+               up->tx_loadsz = uart_config[type].tx_loadsz;
+       if (!up->capabilities)
+               up->capabilities = uart_config[type].flags;
+}
+
+static void __init
+serial8250_register_ports(struct uart_driver *drv, struct device *dev)
+{
+       int i;
+
+       for (i = 0; i < nr_uarts; i++) {
+               struct uart_8250_port *up = &serial8250_ports[i];
+
+               if (up->port.dev)
+                       continue;
+
+               up->port.dev = dev;
+
+               if (up->port.flags & UPF_FIXED_TYPE)
+                       serial8250_init_fixed_type_port(up, up->port.type);
+
+               uart_add_one_port(drv, &up->port);
+       }
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+
+static void serial8250_console_putchar(struct uart_port *port, int ch)
+{
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
+
+       wait_for_xmitr(up, UART_LSR_THRE);
+       serial_port_out(port, UART_TX, ch);
+}
+
+/*
+ *     Print a string to the serial port trying not to disturb
+ *     any possible real use of the port...
+ *
+ *     The console_lock must be held when we get here.
+ */
+static void
+serial8250_console_write(struct console *co, const char *s, unsigned int count)
+{
+       struct uart_8250_port *up = &serial8250_ports[co->index];
+       struct uart_port *port = &up->port;
+       unsigned long flags;
+       unsigned int ier;
+       int locked = 1;
+
+       touch_nmi_watchdog();
+
+       local_irq_save(flags);
+       if (port->sysrq) {
+               /* serial8250_handle_irq() already took the lock */
+               locked = 0;
+       } else if (oops_in_progress) {
+               locked = spin_trylock(&port->lock);
+       } else
+               spin_lock(&port->lock);
+
+       /*
+        *      First save the IER then disable the interrupts
+        */
+       ier = serial_port_in(port, UART_IER);
+
+       if (up->capabilities & UART_CAP_UUE)
+               serial_port_out(port, UART_IER, UART_IER_UUE);
+       else
+               serial_port_out(port, UART_IER, 0);
+
+       uart_console_write(port, s, count, serial8250_console_putchar);
+
+       /*
+        *      Finally, wait for transmitter to become empty
+        *      and restore the IER
+        */
+       wait_for_xmitr(up, BOTH_EMPTY);
+       serial_port_out(port, UART_IER, ier);
+
+       /*
+        *      The receive handling will happen properly because the
+        *      receive ready bit will still be set; it is not cleared
+        *      on read.  However, modem control will not, we must
+        *      call it if we have saved something in the saved flags
+        *      while processing with interrupts off.
+        */
+       if (up->msr_saved_flags)
+               serial8250_modem_status(up);
+
+       if (locked)
+               spin_unlock(&port->lock);
+       local_irq_restore(flags);
+}
+
+static int __init serial8250_console_setup(struct console *co, char *options)
+{
+       struct uart_port *port;
+       int baud = 9600;
+       int bits = 8;
+       int parity = 'n';
+       int flow = 'n';
+
+       /*
+        * Check whether an invalid uart number has been specified, and
+        * if so, search for the first available port that does have
+        * console support.
+        */
+       if (co->index >= nr_uarts)
+               co->index = 0;
+       port = &serial8250_ports[co->index].port;
+       if (!port->iobase && !port->membase)
+               return -ENODEV;
+
+       if (options)
+               uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+       return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static int serial8250_console_early_setup(void)
+{
+       return serial8250_find_port_for_earlycon();
+}
+
+static struct console serial8250_console = {
+       .name           = "ttyS",
+       .write          = serial8250_console_write,
+       .device         = uart_console_device,
+       .setup          = serial8250_console_setup,
+       .early_setup    = serial8250_console_early_setup,
+       .flags          = CON_PRINTBUFFER | CON_ANYTIME,
+       .index          = -1,
+       .data           = &serial8250_reg,
+};
+
+static int __init serial8250_console_init(void)
+{
+       serial8250_isa_init_ports();
+       register_console(&serial8250_console);
+       return 0;
+}
+console_initcall(serial8250_console_init);
+
+int serial8250_find_port(struct uart_port *p)
+{
+       int line;
+       struct uart_port *port;
+
+       for (line = 0; line < nr_uarts; line++) {
+               port = &serial8250_ports[line].port;
+               if (uart_match_port(p, port))
+                       return line;
+       }
+       return -ENODEV;
+}
+
+#define SERIAL8250_CONSOLE     &serial8250_console
+#else
+#define SERIAL8250_CONSOLE     NULL
+#endif
+
+static struct uart_driver serial8250_reg = {
+       .owner                  = THIS_MODULE,
+       .driver_name            = "serial",
+       .dev_name               = "ttyS",
+       .major                  = TTY_MAJOR,
+       .minor                  = 64,
+       .cons                   = SERIAL8250_CONSOLE,
+};
+
+/*
+ * early_serial_setup - early registration for 8250 ports
+ *
+ * Setup an 8250 port structure prior to console initialisation.  Use
+ * after console initialisation will cause undefined behaviour.
+ */
+int __init early_serial_setup(struct uart_port *port)
+{
+       struct uart_port *p;
+
+       if (port->line >= ARRAY_SIZE(serial8250_ports))
+               return -ENODEV;
+
+       serial8250_isa_init_ports();
+       p = &serial8250_ports[port->line].port;
+       p->iobase       = port->iobase;
+       p->membase      = port->membase;
+       p->irq          = port->irq;
+       p->irqflags     = port->irqflags;
+       p->uartclk      = port->uartclk;
+       p->fifosize     = port->fifosize;
+       p->regshift     = port->regshift;
+       p->iotype       = port->iotype;
+       p->flags        = port->flags;
+       p->mapbase      = port->mapbase;
+       p->private_data = port->private_data;
+       p->type         = port->type;
+       p->line         = port->line;
+
+       set_io_from_upio(p);
+       if (port->serial_in)
+               p->serial_in = port->serial_in;
+       if (port->serial_out)
+               p->serial_out = port->serial_out;
+       if (port->handle_irq)
+               p->handle_irq = port->handle_irq;
+       else
+               p->handle_irq = serial8250_default_handle_irq;
+
+       return 0;
+}
+
+/**
+ *     serial8250_suspend_port - suspend one serial port
+ *     @line:  serial line number
+ *
+ *     Suspend one serial port.
+ */
+void serial8250_suspend_port(int line)
+{
+       uart_suspend_port(&serial8250_reg, &serial8250_ports[line].port);
+}
+
+/**
+ *     serial8250_resume_port - resume one serial port
+ *     @line:  serial line number
+ *
+ *     Resume one serial port.
+ */
+void serial8250_resume_port(int line)
+{
+       struct uart_8250_port *up = &serial8250_ports[line];
+       struct uart_port *port = &up->port;
+
+       if (up->capabilities & UART_NATSEMI) {
+               /* Ensure it's still in high speed mode */
+               serial_port_out(port, UART_LCR, 0xE0);
+
+               ns16550a_goto_highspeed(up);
+
+               serial_port_out(port, UART_LCR, 0);
+               port->uartclk = 921600*16;
+       }
+       uart_resume_port(&serial8250_reg, port);
+}
+
+/*
+ * Register a set of serial devices attached to a platform device.  The
+ * list is terminated with a zero flags entry, which means we expect
+ * all entries to have at least UPF_BOOT_AUTOCONF set.
+ */
+static int serial8250_probe(struct platform_device *dev)
+{
+       struct plat_serial8250_port *p = dev->dev.platform_data;
+       struct uart_8250_port uart;
+       int ret, i, irqflag = 0;
+
+       memset(&uart, 0, sizeof(uart));
+
+       if (share_irqs)
+               irqflag = IRQF_SHARED;
+
+       for (i = 0; p && p->flags != 0; p++, i++) {
+               uart.port.iobase        = p->iobase;
+               uart.port.membase       = p->membase;
+               uart.port.irq           = p->irq;
+               uart.port.irqflags      = p->irqflags;
+               uart.port.uartclk       = p->uartclk;
+               uart.port.regshift      = p->regshift;
+               uart.port.iotype        = p->iotype;
+               uart.port.flags         = p->flags;
+               uart.port.mapbase       = p->mapbase;
+               uart.port.hub6          = p->hub6;
+               uart.port.private_data  = p->private_data;
+               uart.port.type          = p->type;
+               uart.port.serial_in     = p->serial_in;
+               uart.port.serial_out    = p->serial_out;
+               uart.port.handle_irq    = p->handle_irq;
+               uart.port.handle_break  = p->handle_break;
+               uart.port.set_termios   = p->set_termios;
+               uart.port.pm            = p->pm;
+               uart.port.dev           = &dev->dev;
+               uart.port.irqflags      |= irqflag;
+               ret = serial8250_register_8250_port(&uart);
+               if (ret < 0) {
+                       dev_err(&dev->dev, "unable to register port at index %d "
+                               "(IO%lx MEM%llx IRQ%d): %d\n", i,
+                               p->iobase, (unsigned long long)p->mapbase,
+                               p->irq, ret);
+               }
+       }
+       return 0;
+}
+
+/*
+ * Remove serial ports registered against a platform device.
+ */
+static int serial8250_remove(struct platform_device *dev)
+{
+       int i;
+
+       for (i = 0; i < nr_uarts; i++) {
+               struct uart_8250_port *up = &serial8250_ports[i];
+
+               if (up->port.dev == &dev->dev)
+                       serial8250_unregister_port(i);
+       }
+       return 0;
+}
+
+static int serial8250_suspend(struct platform_device *dev, pm_message_t state)
+{
+       int i;
+
+       for (i = 0; i < UART_NR; i++) {
+               struct uart_8250_port *up = &serial8250_ports[i];
+
+               if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
+                       uart_suspend_port(&serial8250_reg, &up->port);
+       }
+
+       return 0;
+}
+
+static int serial8250_resume(struct platform_device *dev)
+{
+       int i;
+
+       for (i = 0; i < UART_NR; i++) {
+               struct uart_8250_port *up = &serial8250_ports[i];
+
+               if (up->port.type != PORT_UNKNOWN && up->port.dev == &dev->dev)
+                       serial8250_resume_port(i);
+       }
+
+       return 0;
+}
+
+static struct platform_driver serial8250_isa_driver = {
+       .probe          = serial8250_probe,
+       .remove         = serial8250_remove,
+       .suspend        = serial8250_suspend,
+       .resume         = serial8250_resume,
+       .driver         = {
+               .name   = "serial8250",
+               .owner  = THIS_MODULE,
+       },
+};
+
+/*
+ * This "device" covers _all_ ISA 8250-compatible serial devices listed
+ * in the table in include/asm/serial.h
+ */
+static struct platform_device *serial8250_isa_devs;
+
+/*
+ * serial8250_register_8250_port and serial8250_unregister_port allows for
+ * 16x50 serial ports to be configured at run-time, to support PCMCIA
+ * modems and PCI multiport cards.
+ */
+static DEFINE_MUTEX(serial_mutex);
+
+static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port *port)
+{
+       int i;
+
+       /*
+        * First, find a port entry which matches.
+        */
+       for (i = 0; i < nr_uarts; i++)
+               if (uart_match_port(&serial8250_ports[i].port, port))
+                       return &serial8250_ports[i];
+
+       /*
+        * We didn't find a matching entry, so look for the first
+        * free entry.  We look for one which hasn't been previously
+        * used (indicated by zero iobase).
+        */
+       for (i = 0; i < nr_uarts; i++)
+               if (serial8250_ports[i].port.type == PORT_UNKNOWN &&
+                   serial8250_ports[i].port.iobase == 0)
+                       return &serial8250_ports[i];
+
+       /*
+        * That also failed.  Last resort is to find any entry which
+        * doesn't have a real port associated with it.
+        */
+       for (i = 0; i < nr_uarts; i++)
+               if (serial8250_ports[i].port.type == PORT_UNKNOWN)
+                       return &serial8250_ports[i];
+
+       return NULL;
+}
+
+/**
+ *     serial8250_register_8250_port - register a serial port
+ *     @up: serial port template
+ *
+ *     Configure the serial port specified by the request. If the
+ *     port exists and is in use, it is hung up and unregistered
+ *     first.
+ *
+ *     The port is then probed and if necessary the IRQ is autodetected
+ *     If this fails an error is returned.
+ *
+ *     On success the port is ready to use and the line number is returned.
+ */
+int serial8250_register_8250_port(struct uart_8250_port *up)
+{
+       struct uart_8250_port *uart;
+       int ret = -ENOSPC;
+
+       if (up->port.uartclk == 0)
+               return -EINVAL;
+
+       mutex_lock(&serial_mutex);
+
+       uart = serial8250_find_match_or_unused(&up->port);
+       if (uart && uart->port.type != PORT_8250_CIR) {
+               if (uart->port.dev)
+                       uart_remove_one_port(&serial8250_reg, &uart->port);
+
+               uart->port.iobase       = up->port.iobase;
+               uart->port.membase      = up->port.membase;
+               uart->port.irq          = up->port.irq;
+               uart->port.irqflags     = up->port.irqflags;
+               uart->port.uartclk      = up->port.uartclk;
+               uart->port.fifosize     = up->port.fifosize;
+               uart->port.regshift     = up->port.regshift;
+               uart->port.iotype       = up->port.iotype;
+               uart->port.flags        = up->port.flags | UPF_BOOT_AUTOCONF;
+               uart->bugs              = up->bugs;
+               uart->port.mapbase      = up->port.mapbase;
+               uart->port.private_data = up->port.private_data;
+               uart->port.fifosize     = up->port.fifosize;
+               uart->tx_loadsz         = up->tx_loadsz;
+               uart->capabilities      = up->capabilities;
+
+               if (up->port.dev)
+                       uart->port.dev = up->port.dev;
+
+               if (up->port.flags & UPF_FIXED_TYPE)
+                       serial8250_init_fixed_type_port(uart, up->port.type);
+
+               set_io_from_upio(&uart->port);
+               /* Possibly override default I/O functions.  */
+               if (up->port.serial_in)
+                       uart->port.serial_in = up->port.serial_in;
+               if (up->port.serial_out)
+                       uart->port.serial_out = up->port.serial_out;
+               if (up->port.handle_irq)
+                       uart->port.handle_irq = up->port.handle_irq;
+               /*  Possibly override set_termios call */
+               if (up->port.set_termios)
+                       uart->port.set_termios = up->port.set_termios;
+               if (up->port.pm)
+                       uart->port.pm = up->port.pm;
+               if (up->port.handle_break)
+                       uart->port.handle_break = up->port.handle_break;
+               if (up->dl_read)
+                       uart->dl_read = up->dl_read;
+               if (up->dl_write)
+                       uart->dl_write = up->dl_write;
+               if (up->dma)
+                       uart->dma = up->dma;
+
+               if (serial8250_isa_config != NULL)
+                       serial8250_isa_config(0, &uart->port,
+                                       &uart->capabilities);
+
+               ret = uart_add_one_port(&serial8250_reg, &uart->port);
+               if (ret == 0)
+                       ret = uart->port.line;
+       }
+       mutex_unlock(&serial_mutex);
+
+       return ret;
+}
+EXPORT_SYMBOL(serial8250_register_8250_port);
+
+/**
+ *     serial8250_unregister_port - remove a 16x50 serial port at runtime
+ *     @line: serial line number
+ *
+ *     Remove one serial port.  This may not be called from interrupt
+ *     context.  We hand the port back to the our control.
+ */
+void serial8250_unregister_port(int line)
+{
+       struct uart_8250_port *uart = &serial8250_ports[line];
+
+       mutex_lock(&serial_mutex);
+       uart_remove_one_port(&serial8250_reg, &uart->port);
+       if (serial8250_isa_devs) {
+               uart->port.flags &= ~UPF_BOOT_AUTOCONF;
+               uart->port.type = PORT_UNKNOWN;
+               uart->port.dev = &serial8250_isa_devs->dev;
+               uart->capabilities = uart_config[uart->port.type].flags;
+               uart_add_one_port(&serial8250_reg, &uart->port);
+       } else {
+               uart->port.dev = NULL;
+       }
+       mutex_unlock(&serial_mutex);
+}
+EXPORT_SYMBOL(serial8250_unregister_port);
+
+static int __init serial8250_init(void)
+{
+       int ret;
+
+       serial8250_isa_init_ports();
+
+       printk(KERN_INFO "Serial: 8250/16550 driver, "
+               "%d ports, IRQ sharing %sabled\n", nr_uarts,
+               share_irqs ? "en" : "dis");
+
+#ifdef CONFIG_SPARC
+       ret = sunserial_register_minors(&serial8250_reg, UART_NR);
+#else
+       serial8250_reg.nr = UART_NR;
+       ret = uart_register_driver(&serial8250_reg);
+#endif
+       if (ret)
+               goto out;
+
+       ret = serial8250_pnp_init();
+       if (ret)
+               goto unreg_uart_drv;
+
+       serial8250_isa_devs = platform_device_alloc("serial8250",
+                                                   PLAT8250_DEV_LEGACY);
+       if (!serial8250_isa_devs) {
+               ret = -ENOMEM;
+               goto unreg_pnp;
+       }
+
+       ret = platform_device_add(serial8250_isa_devs);
+       if (ret)
+               goto put_dev;
+
+       serial8250_register_ports(&serial8250_reg, &serial8250_isa_devs->dev);
+
+       ret = platform_driver_register(&serial8250_isa_driver);
+       if (ret == 0)
+               goto out;
+
+       platform_device_del(serial8250_isa_devs);
+put_dev:
+       platform_device_put(serial8250_isa_devs);
+unreg_pnp:
+       serial8250_pnp_exit();
+unreg_uart_drv:
+#ifdef CONFIG_SPARC
+       sunserial_unregister_minors(&serial8250_reg, UART_NR);
+#else
+       uart_unregister_driver(&serial8250_reg);
+#endif
+out:
+       return ret;
+}
+
+static void __exit serial8250_exit(void)
+{
+       struct platform_device *isa_dev = serial8250_isa_devs;
+
+       /*
+        * This tells serial8250_unregister_port() not to re-register
+        * the ports (thereby making serial8250_isa_driver permanently
+        * in use.)
+        */
+       serial8250_isa_devs = NULL;
+
+       platform_driver_unregister(&serial8250_isa_driver);
+       platform_device_unregister(isa_dev);
+
+       serial8250_pnp_exit();
+
+#ifdef CONFIG_SPARC
+       sunserial_unregister_minors(&serial8250_reg, UART_NR);
+#else
+       uart_unregister_driver(&serial8250_reg);
+#endif
+}
+
+module_init(serial8250_init);
+module_exit(serial8250_exit);
+
+EXPORT_SYMBOL(serial8250_suspend_port);
+EXPORT_SYMBOL(serial8250_resume_port);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic 8250/16x50 serial driver");
+
+module_param(share_irqs, uint, 0644);
+MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
+       " (unsafe)");
+
+module_param(nr_uarts, uint, 0644);
+MODULE_PARM_DESC(nr_uarts, "Maximum number of UARTs supported. (1-" __MODULE_STRING(CONFIG_SERIAL_8250_NR_UARTS) ")");
+
+module_param(skip_txen_test, uint, 0644);
+MODULE_PARM_DESC(skip_txen_test, "Skip checking for the TXEN bug at init time");
+
+#ifdef CONFIG_SERIAL_8250_RSA
+module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444);
+MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
+#endif
+MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR);
+
+#ifdef CONFIG_SERIAL_8250_DEPRECATED_OPTIONS
+#ifndef MODULE
+/* This module was renamed to 8250_core in 3.7.  Keep the old "8250" name
+ * working as well for the module options so we don't break people.  We
+ * need to keep the names identical and the convenient macros will happily
+ * refuse to let us do that by failing the build with redefinition errors
+ * of global variables.  So we stick them inside a dummy function to avoid
+ * those conflicts.  The options still get parsed, and the redefined
+ * MODULE_PARAM_PREFIX lets us keep the "8250." syntax alive.
+ *
+ * This is hacky.  I'm sorry.
+ */
+static void __used s8250_options(void)
+{
+#undef MODULE_PARAM_PREFIX
+#define MODULE_PARAM_PREFIX "8250_core."
+
+       module_param_cb(share_irqs, &param_ops_uint, &share_irqs, 0644);
+       module_param_cb(nr_uarts, &param_ops_uint, &nr_uarts, 0644);
+       module_param_cb(skip_txen_test, &param_ops_uint, &skip_txen_test, 0644);
+#ifdef CONFIG_SERIAL_8250_RSA
+       __module_param_call(MODULE_PARAM_PREFIX, probe_rsa,
+               &param_array_ops, .arr = &__param_arr_probe_rsa,
+               0444, -1);
+#endif
+}
+#else
+MODULE_ALIAS("8250_core");
+#endif
+#endif
index aa76825229dca32d612781f877b1d1167add71af..26e3a97ab157ed16d23825c1a62bec4d53cd81b9 100644 (file)
@@ -1554,6 +1554,7 @@ pci_wch_ch353_setup(struct serial_private *priv,
 #define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001
 #define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d
 #define PCI_VENDOR_ID_WCH              0x4348
+#define PCI_DEVICE_ID_WCH_CH352_2S     0x3253
 #define PCI_DEVICE_ID_WCH_CH353_4S     0x3453
 #define PCI_DEVICE_ID_WCH_CH353_2S1PF  0x5046
 #define PCI_DEVICE_ID_WCH_CH353_2S1P   0x7053
@@ -2172,6 +2173,14 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .subdevice      = PCI_ANY_ID,
                .setup          = pci_wch_ch353_setup,
        },
+       /* WCH CH352 2S card (16550 clone) */
+       {
+               .vendor         = PCI_VENDOR_ID_WCH,
+               .device         = PCI_DEVICE_ID_WCH_CH352_2S,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_wch_ch353_setup,
+       },
        /*
         * ASIX devices with FIFO bug
         */
@@ -4870,6 +4879,10 @@ static struct pci_device_id serial_pci_tbl[] = {
                PCI_ANY_ID, PCI_ANY_ID,
                0, 0, pbn_b0_bt_2_115200 },
 
+       {       PCI_VENDOR_ID_WCH, PCI_DEVICE_ID_WCH_CH352_2S,
+               PCI_ANY_ID, PCI_ANY_ID,
+               0, 0, pbn_b0_bt_2_115200 },
+
        /*
         * Commtech, Inc. Fastcom adapters
         */
index 2ef9537bcb2cda6a985d27f9dda8c3385187fe3a..80fe91e64a527da06e82d9cf237be64a26faf662 100644 (file)
@@ -33,6 +33,23 @@ config SERIAL_8250
          Most people will say Y or M here, so that they can use serial mice,
          modems and similar devices connecting to the standard serial ports.
 
+config SERIAL_8250_DEPRECATED_OPTIONS
+       bool "Support 8250_core.* kernel options (DEPRECATED)"
+       depends on SERIAL_8250
+       default y
+       ---help---
+         In 3.7 we renamed 8250 to 8250_core by mistake, so now we have to
+         accept kernel parameters in both forms like 8250_core.nr_uarts=4 and
+         8250.nr_uarts=4. We now renamed the module back to 8250, but if
+         anybody noticed in 3.7 and changed their userspace we still have to
+         keep the 8350_core.* options around until they revert the changes
+         they already did.
+
+         If 8250 is built as a module, this adds 8250_core alias instead. 
+
+         If you did not notice yet and/or you have userspace from pre-3.7, it
+         is safe (and recommended) to say N here.
+
 config SERIAL_8250_PNP
        bool "8250/16550 PNP device support" if EXPERT
        depends on SERIAL_8250 && PNP
index a23838a4d5353773c1ec8d15adbecec3ceee123c..36d68d0543072c21f48807d3b932ed426e843685 100644 (file)
@@ -2,10 +2,10 @@
 # Makefile for the 8250 serial device drivers.
 #
 
-obj-$(CONFIG_SERIAL_8250)              += 8250_core.o
-8250_core-y                            := 8250.o
-8250_core-$(CONFIG_SERIAL_8250_PNP)    += 8250_pnp.o
-8250_core-$(CONFIG_SERIAL_8250_DMA)    += 8250_dma.o
+obj-$(CONFIG_SERIAL_8250)              += 8250.o
+8250-y                                 := 8250_core.o
+8250-$(CONFIG_SERIAL_8250_PNP)         += 8250_pnp.o
+8250-$(CONFIG_SERIAL_8250_DMA)         += 8250_dma.o
 obj-$(CONFIG_SERIAL_8250_GSC)          += 8250_gsc.o
 obj-$(CONFIG_SERIAL_8250_PCI)          += 8250_pci.o
 obj-$(CONFIG_SERIAL_8250_HP300)                += 8250_hp300.o
index d4a7c241b751279d3422f6d024b45cbb1a04a2de..3467462869ce2dce88ca8832002d7f294d5eaae6 100644 (file)
@@ -158,7 +158,7 @@ struct atmel_uart_port {
 };
 
 static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART];
-static unsigned long atmel_ports_in_use;
+static DECLARE_BITMAP(atmel_ports_in_use, ATMEL_MAX_UART);
 
 #ifdef SUPPORT_SYSRQ
 static struct console atmel_console;
@@ -1769,15 +1769,14 @@ static int atmel_serial_probe(struct platform_device *pdev)
        if (ret < 0)
                /* port id not found in platform data nor device-tree aliases:
                 * auto-enumerate it */
-               ret = find_first_zero_bit(&atmel_ports_in_use,
-                               sizeof(atmel_ports_in_use));
+               ret = find_first_zero_bit(atmel_ports_in_use, ATMEL_MAX_UART);
 
-       if (ret > ATMEL_MAX_UART) {
+       if (ret >= ATMEL_MAX_UART) {
                ret = -ENODEV;
                goto err;
        }
 
-       if (test_and_set_bit(ret, &atmel_ports_in_use)) {
+       if (test_and_set_bit(ret, atmel_ports_in_use)) {
                /* port already in use */
                ret = -EBUSY;
                goto err;
@@ -1857,7 +1856,7 @@ static int atmel_serial_remove(struct platform_device *pdev)
 
        /* "port" is allocated statically, so we shouldn't free it */
 
-       clear_bit(port->line, &atmel_ports_in_use);
+       clear_bit(port->line, atmel_ports_in_use);
 
        clk_put(atmel_port->clk);
 
index d549fe1fa42abdce8611645d1038dfb11b5e0654..269a27caff3359ca9fa98c1113975efb4e71de62 100644 (file)
@@ -35,7 +35,7 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/of_device.h>
 #include <linux/dma-mapping.h>
-#include <linux/fsl/mxs-dma.h>
+#include <linux/dmaengine.h>
 
 #include <asm/cacheflush.h>
 
@@ -148,11 +148,6 @@ struct mxs_auart_port {
        struct device *dev;
 
        /* for DMA */
-       struct mxs_dma_data dma_data;
-       int dma_channel_rx, dma_channel_tx;
-       int dma_irq_rx, dma_irq_tx;
-       int dma_channel;
-
        struct scatterlist tx_sgl;
        struct dma_chan *tx_dma_chan;
        void *tx_dma_buf;
@@ -440,20 +435,6 @@ static u32 mxs_auart_get_mctrl(struct uart_port *u)
        return mctrl;
 }
 
-static bool mxs_auart_dma_filter(struct dma_chan *chan, void *param)
-{
-       struct mxs_auart_port *s = param;
-
-       if (!mxs_dma_is_apbx(chan))
-               return false;
-
-       if (s->dma_channel == chan->chan_id) {
-               chan->private = &s->dma_data;
-               return true;
-       }
-       return false;
-}
-
 static int mxs_auart_dma_prep_rx(struct mxs_auart_port *s);
 static void dma_rx_callback(void *arg)
 {
@@ -545,21 +526,11 @@ static void mxs_auart_dma_exit(struct mxs_auart_port *s)
 
 static int mxs_auart_dma_init(struct mxs_auart_port *s)
 {
-       dma_cap_mask_t mask;
-
        if (auart_dma_enabled(s))
                return 0;
 
-       /* We do not get the right DMA channels. */
-       if (s->dma_channel_rx == -1 || s->dma_channel_tx == -1)
-               return -EINVAL;
-
        /* init for RX */
-       dma_cap_zero(mask);
-       dma_cap_set(DMA_SLAVE, mask);
-       s->dma_channel = s->dma_channel_rx;
-       s->dma_data.chan_irq = s->dma_irq_rx;
-       s->rx_dma_chan = dma_request_channel(mask, mxs_auart_dma_filter, s);
+       s->rx_dma_chan = dma_request_slave_channel(s->dev, "rx");
        if (!s->rx_dma_chan)
                goto err_out;
        s->rx_dma_buf = kzalloc(UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA);
@@ -567,9 +538,7 @@ static int mxs_auart_dma_init(struct mxs_auart_port *s)
                goto err_out;
 
        /* init for TX */
-       s->dma_channel = s->dma_channel_tx;
-       s->dma_data.chan_irq = s->dma_irq_tx;
-       s->tx_dma_chan = dma_request_channel(mask, mxs_auart_dma_filter, s);
+       s->tx_dma_chan = dma_request_slave_channel(s->dev, "tx");
        if (!s->tx_dma_chan)
                goto err_out;
        s->tx_dma_buf = kzalloc(UART_XMIT_SIZE, GFP_KERNEL | GFP_DMA);
@@ -1020,7 +989,6 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s,
                struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
-       u32 dma_channel[2];
        int ret;
 
        if (!np)
@@ -1034,20 +1002,8 @@ static int serial_mxs_probe_dt(struct mxs_auart_port *s,
        }
        s->port.line = ret;
 
-       s->dma_irq_rx = platform_get_irq(pdev, 1);
-       s->dma_irq_tx = platform_get_irq(pdev, 2);
+       s->flags |= MXS_AUART_DMA_CONFIG;
 
-       ret = of_property_read_u32_array(np, "fsl,auart-dma-channel",
-                                       dma_channel, 2);
-       if (ret == 0) {
-               s->dma_channel_rx = dma_channel[0];
-               s->dma_channel_tx = dma_channel[1];
-
-               s->flags |= MXS_AUART_DMA_CONFIG;
-       } else {
-               s->dma_channel_rx = -1;
-               s->dma_channel_tx = -1;
-       }
        return 0;
 }
 
index ba451c7209fc6b9bbaaf47b9e2d2458f202feaf8..f36bbba1ac8b9070cc7cefafb8a33265a7872253 100644 (file)
@@ -578,6 +578,8 @@ static int xuartps_startup(struct uart_port *port)
        /* Receive Timeout register is enabled with value of 10 */
        xuartps_writel(10, XUARTPS_RXTOUT_OFFSET);
 
+       /* Clear out any pending interrupts before enabling them */
+       xuartps_writel(xuartps_readl(XUARTPS_ISR_OFFSET), XUARTPS_ISR_OFFSET);
 
        /* Set the Interrupt Registers with desired interrupts */
        xuartps_writel(XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_PARITY |
index e4ca345873c3279761f8dcf6cee3f06053205088..d7799deacb21a66805d8e4308bcc199b64894fbf 100644 (file)
@@ -93,7 +93,7 @@ vcs_poll_data_free(struct vcs_poll_data *poll)
 static struct vcs_poll_data *
 vcs_poll_data_get(struct file *file)
 {
-       struct vcs_poll_data *poll = file->private_data;
+       struct vcs_poll_data *poll = file->private_data, *kill = NULL;
 
        if (poll)
                return poll;
@@ -122,10 +122,12 @@ vcs_poll_data_get(struct file *file)
                file->private_data = poll;
        } else {
                /* someone else raced ahead of us */
-               vcs_poll_data_free(poll);
+               kill = poll;
                poll = file->private_data;
        }
        spin_unlock(&file->f_lock);
+       if (kill)
+               vcs_poll_data_free(kill);
 
        return poll;
 }
index 99b34a30354f4a2a3e06deef32addaefb3e46e61..f9ec44cbb82fb1ff6fa8e620367de8a9daec2c70 100644 (file)
@@ -2412,6 +2412,14 @@ int usb_hcd_is_primary_hcd(struct usb_hcd *hcd)
 }
 EXPORT_SYMBOL_GPL(usb_hcd_is_primary_hcd);
 
+int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1)
+{
+       if (!hcd->driver->find_raw_port_number)
+               return port1;
+
+       return hcd->driver->find_raw_port_number(hcd, port1);
+}
+
 static int usb_hcd_request_irqs(struct usb_hcd *hcd,
                unsigned int irqnum, unsigned long irqflags)
 {
index b6f4bad3f756eefb173097767ffde6970e06220e..255c14464bf2ea7a30dffab6fa1770c7b030c0aa 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/acpi.h>
 #include <linux/pci.h>
+#include <linux/usb/hcd.h>
 #include <acpi/acpi_bus.h>
 
 #include "usb.h"
@@ -188,8 +189,13 @@ static int usb_acpi_find_device(struct device *dev, acpi_handle *handle)
                 * connected to.
                 */
                if (!udev->parent) {
-                       *handle = acpi_get_child(DEVICE_ACPI_HANDLE(&udev->dev),
+                       struct usb_hcd *hcd = bus_to_hcd(udev->bus);
+                       int raw_port_num;
+
+                       raw_port_num = usb_hcd_find_raw_port_number(hcd,
                                port_num);
+                       *handle = acpi_get_child(DEVICE_ACPI_HANDLE(&udev->dev),
+                               raw_port_num);
                        if (!*handle)
                                return -ENODEV;
                } else {
index 5a0c541daf893a33a428bedb8d68ec1fa72d4234..c7525b1cad74a0f92dc1057621dca509f80d671c 100644 (file)
@@ -145,6 +145,7 @@ config USB_LPC32XX
        tristate "LPC32XX USB Peripheral Controller"
        depends on ARCH_LPC32XX
        select USB_ISP1301
+       select USB_OTG_UTILS
        help
           This option selects the USB device controller in the LPC32xx SoC.
 
index b476daf49f6f3c6cf226b920f5c8ff01ca5d23aa..010f686d8881fc9796fd3bbee1c1f5c3aa71e878 100644 (file)
@@ -1214,6 +1214,7 @@ itd_urb_transaction (
 
                memset (itd, 0, sizeof *itd);
                itd->itd_dma = itd_dma;
+               itd->frame = 9999;              /* an invalid value */
                list_add (&itd->itd_list, &sched->td_list);
        }
        spin_unlock_irqrestore (&ehci->lock, flags);
@@ -1915,6 +1916,7 @@ sitd_urb_transaction (
 
                memset (sitd, 0, sizeof *sitd);
                sitd->sitd_dma = sitd_dma;
+               sitd->frame = 9999;             /* an invalid value */
                list_add (&sitd->sitd_list, &iso_sched->td_list);
        }
 
index 35616ffbe3ae7435155bf29196d295f35a719b71..6dc238c592bc9aef5e3d8a564240b085e401cf6b 100644 (file)
@@ -1022,44 +1022,24 @@ void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci,
  * is attached to (or the roothub port its ancestor hub is attached to).  All we
  * know is the index of that port under either the USB 2.0 or the USB 3.0
  * roothub, but that doesn't give us the real index into the HW port status
- * registers.  Scan through the xHCI roothub port array, looking for the Nth
- * entry of the correct port speed.  Return the port number of that entry.
+ * registers. Call xhci_find_raw_port_number() to get real index.
  */
 static u32 xhci_find_real_port_number(struct xhci_hcd *xhci,
                struct usb_device *udev)
 {
        struct usb_device *top_dev;
-       unsigned int num_similar_speed_ports;
-       unsigned int faked_port_num;
-       int i;
+       struct usb_hcd *hcd;
+
+       if (udev->speed == USB_SPEED_SUPER)
+               hcd = xhci->shared_hcd;
+       else
+               hcd = xhci->main_hcd;
 
        for (top_dev = udev; top_dev->parent && top_dev->parent->parent;
                        top_dev = top_dev->parent)
                /* Found device below root hub */;
-       faked_port_num = top_dev->portnum;
-       for (i = 0, num_similar_speed_ports = 0;
-                       i < HCS_MAX_PORTS(xhci->hcs_params1); i++) {
-               u8 port_speed = xhci->port_array[i];
-
-               /*
-                * Skip ports that don't have known speeds, or have duplicate
-                * Extended Capabilities port speed entries.
-                */
-               if (port_speed == 0 || port_speed == DUPLICATE_ENTRY)
-                       continue;
 
-               /*
-                * USB 3.0 ports are always under a USB 3.0 hub.  USB 2.0 and
-                * 1.1 ports are under the USB 2.0 hub.  If the port speed
-                * matches the device speed, it's a similar speed port.
-                */
-               if ((port_speed == 0x03) == (udev->speed == USB_SPEED_SUPER))
-                       num_similar_speed_ports++;
-               if (num_similar_speed_ports == faked_port_num)
-                       /* Roothub ports are numbered from 1 to N */
-                       return i+1;
-       }
-       return 0;
+       return  xhci_find_raw_port_number(hcd, top_dev->portnum);
 }
 
 /* Setup an xHCI virtual device for a Set Address command */
index af259e0ec172aa4a5664ca15acb2adf8d90bf02c..1a30c380043ce258aa660e67edb38210707fffd6 100644 (file)
@@ -313,6 +313,7 @@ static const struct hc_driver xhci_pci_hc_driver = {
        .set_usb2_hw_lpm =      xhci_set_usb2_hardware_lpm,
        .enable_usb3_lpm_timeout =      xhci_enable_usb3_lpm_timeout,
        .disable_usb3_lpm_timeout =     xhci_disable_usb3_lpm_timeout,
+       .find_raw_port_number = xhci_find_raw_port_number,
 };
 
 /*-------------------------------------------------------------------------*/
index 88287546530179a867da6f3a9d88f615d87f9a81..1969c001b3f9a8bacbe926dfc4777c95206101a1 100644 (file)
@@ -1599,14 +1599,20 @@ static void handle_port_status(struct xhci_hcd *xhci,
        max_ports = HCS_MAX_PORTS(xhci->hcs_params1);
        if ((port_id <= 0) || (port_id > max_ports)) {
                xhci_warn(xhci, "Invalid port id %d\n", port_id);
-               bogus_port_status = true;
-               goto cleanup;
+               inc_deq(xhci, xhci->event_ring);
+               return;
        }
 
        /* Figure out which usb_hcd this port is attached to:
         * is it a USB 3.0 port or a USB 2.0/1.1 port?
         */
        major_revision = xhci->port_array[port_id - 1];
+
+       /* Find the right roothub. */
+       hcd = xhci_to_hcd(xhci);
+       if ((major_revision == 0x03) != (hcd->speed == HCD_USB3))
+               hcd = xhci->shared_hcd;
+
        if (major_revision == 0) {
                xhci_warn(xhci, "Event for port %u not in "
                                "Extended Capabilities, ignoring.\n",
@@ -1629,10 +1635,6 @@ static void handle_port_status(struct xhci_hcd *xhci,
         * into the index into the ports on the correct split roothub, and the
         * correct bus_state structure.
         */
-       /* Find the right roothub. */
-       hcd = xhci_to_hcd(xhci);
-       if ((major_revision == 0x03) != (hcd->speed == HCD_USB3))
-               hcd = xhci->shared_hcd;
        bus_state = &xhci->bus_state[hcd_index(hcd)];
        if (hcd->speed == HCD_USB3)
                port_array = xhci->usb3_ports;
@@ -2027,8 +2029,8 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
                if (event_trb != ep_ring->dequeue &&
                                event_trb != td->last_trb)
                        td->urb->actual_length =
-                               td->urb->transfer_buffer_length
-                               TRB_LEN(le32_to_cpu(event->transfer_len));
+                               td->urb->transfer_buffer_length -
+                               EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
                else
                        td->urb->actual_length = 0;
 
@@ -2060,7 +2062,7 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
                /* Maybe the event was for the data stage? */
                        td->urb->actual_length =
                                td->urb->transfer_buffer_length -
-                               TRB_LEN(le32_to_cpu(event->transfer_len));
+                               EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
                        xhci_dbg(xhci, "Waiting for status "
                                        "stage event\n");
                        return 0;
@@ -2096,7 +2098,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
        /* handle completion code */
        switch (trb_comp_code) {
        case COMP_SUCCESS:
-               if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) {
+               if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0) {
                        frame->status = 0;
                        break;
                }
@@ -2141,7 +2143,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
                                len += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2]));
                }
                len += TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) -
-                       TRB_LEN(le32_to_cpu(event->transfer_len));
+                       EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
 
                if (trb_comp_code != COMP_STOP_INVAL) {
                        frame->actual_length = len;
@@ -2199,7 +2201,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
        case COMP_SUCCESS:
                /* Double check that the HW transferred everything. */
                if (event_trb != td->last_trb ||
-                               TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
+                   EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
                        xhci_warn(xhci, "WARN Successful completion "
                                        "on short TX\n");
                        if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
@@ -2227,18 +2229,18 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
                                "%d bytes untransferred\n",
                                td->urb->ep->desc.bEndpointAddress,
                                td->urb->transfer_buffer_length,
-                               TRB_LEN(le32_to_cpu(event->transfer_len)));
+                               EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)));
        /* Fast path - was this the last TRB in the TD for this URB? */
        if (event_trb == td->last_trb) {
-               if (TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
+               if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) {
                        td->urb->actual_length =
                                td->urb->transfer_buffer_length -
-                               TRB_LEN(le32_to_cpu(event->transfer_len));
+                               EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
                        if (td->urb->transfer_buffer_length <
                                        td->urb->actual_length) {
                                xhci_warn(xhci, "HC gave bad length "
                                                "of %d bytes left\n",
-                                         TRB_LEN(le32_to_cpu(event->transfer_len)));
+                                         EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)));
                                td->urb->actual_length = 0;
                                if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
                                        *status = -EREMOTEIO;
@@ -2280,7 +2282,7 @@ static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
                if (trb_comp_code != COMP_STOP_INVAL)
                        td->urb->actual_length +=
                                TRB_LEN(le32_to_cpu(cur_trb->generic.field[2])) -
-                               TRB_LEN(le32_to_cpu(event->transfer_len));
+                               EVENT_TRB_LEN(le32_to_cpu(event->transfer_len));
        }
 
        return finish_td(xhci, td, event_trb, event, ep, status, false);
@@ -2368,7 +2370,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
         * transfer type
         */
        case COMP_SUCCESS:
-               if (TRB_LEN(le32_to_cpu(event->transfer_len)) == 0)
+               if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) == 0)
                        break;
                if (xhci->quirks & XHCI_TRUST_TX_LENGTH)
                        trb_comp_code = COMP_SHORT_TX;
@@ -2461,14 +2463,21 @@ static int handle_tx_event(struct xhci_hcd *xhci,
                 * TD list.
                 */
                if (list_empty(&ep_ring->td_list)) {
-                       xhci_warn(xhci, "WARN Event TRB for slot %d ep %d "
-                                       "with no TDs queued?\n",
-                                 TRB_TO_SLOT_ID(le32_to_cpu(event->flags)),
-                                 ep_index);
-                       xhci_dbg(xhci, "Event TRB with TRB type ID %u\n",
-                                (le32_to_cpu(event->flags) &
-                                 TRB_TYPE_BITMASK)>>10);
-                       xhci_print_trb_offsets(xhci, (union xhci_trb *) event);
+                       /*
+                        * A stopped endpoint may generate an extra completion
+                        * event if the device was suspended.  Don't print
+                        * warnings.
+                        */
+                       if (!(trb_comp_code == COMP_STOP ||
+                                               trb_comp_code == COMP_STOP_INVAL)) {
+                               xhci_warn(xhci, "WARN Event TRB for slot %d ep %d with no TDs queued?\n",
+                                               TRB_TO_SLOT_ID(le32_to_cpu(event->flags)),
+                                               ep_index);
+                               xhci_dbg(xhci, "Event TRB with TRB type ID %u\n",
+                                               (le32_to_cpu(event->flags) &
+                                                TRB_TYPE_BITMASK)>>10);
+                               xhci_print_trb_offsets(xhci, (union xhci_trb *) event);
+                       }
                        if (ep->skip) {
                                ep->skip = false;
                                xhci_dbg(xhci, "td_list is empty while skip "
index 849470b188313ece555d4a9c20aa9e70bb92ff2a..53b8f89a0b1c7e6199c95672c85d3d27fb3e0b90 100644 (file)
@@ -3779,6 +3779,28 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
        return 0;
 }
 
+/*
+ * Transfer the port index into real index in the HW port status
+ * registers. Caculate offset between the port's PORTSC register
+ * and port status base. Divide the number of per port register
+ * to get the real index. The raw port number bases 1.
+ */
+int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1)
+{
+       struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+       __le32 __iomem *base_addr = &xhci->op_regs->port_status_base;
+       __le32 __iomem *addr;
+       int raw_port;
+
+       if (hcd->speed != HCD_USB3)
+               addr = xhci->usb2_ports[port1 - 1];
+       else
+               addr = xhci->usb3_ports[port1 - 1];
+
+       raw_port = (addr - base_addr)/NUM_PORT_REGS + 1;
+       return raw_port;
+}
+
 #ifdef CONFIG_USB_SUSPEND
 
 /* BESL to HIRD Encoding array for USB2 LPM */
index 2c510e4a7d4c61b92df567c83d01ffba96aa849c..63582719e0fb26cafb4d19f5248c2b5f9aa8a43a 100644 (file)
@@ -972,6 +972,10 @@ struct xhci_transfer_event {
        __le32  flags;
 };
 
+/* Transfer event TRB length bit mask */
+/* bits 0:23 */
+#define        EVENT_TRB_LEN(p)                ((p) & 0xffffff)
+
 /** Transfer Event bit fields **/
 #define        TRB_TO_EP_ID(p) (((p) >> 16) & 0x1f)
 
@@ -1829,6 +1833,7 @@ void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 __iomem **port_array,
 int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex,
                char *buf, u16 wLength);
 int xhci_hub_status_data(struct usb_hcd *hcd, char *buf);
+int xhci_find_raw_port_number(struct usb_hcd *hcd, int port1);
 
 #ifdef CONFIG_PM
 int xhci_bus_suspend(struct usb_hcd *hcd);
index 65217a5900689028e68a61e28c8011fbc9cbbaea..90549382eba5f139c6d54b7617319132189e6596 100644 (file)
@@ -38,6 +38,7 @@ config USB_ISP1301
        tristate "NXP ISP1301 USB transceiver support"
        depends on USB || USB_GADGET
        depends on I2C
+       select USB_OTG_UTILS
        help
          Say Y here to add support for the NXP ISP1301 USB transceiver driver.
          This chip is typically used as USB transceiver for USB host, gadget
index d4809d5514738a15496c216eea033ef788baaf62..9886180e45f1b5d73ddc1903f2e13eecb6297013 100644 (file)
@@ -640,6 +640,7 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) },
        { USB_DEVICE(ACTON_VID, ACTON_SPECTRAPRO_PID) },
        { USB_DEVICE(CONTEC_VID, CONTEC_COM1USBH_PID) },
+       { USB_DEVICE(MITSUBISHI_VID, MITSUBISHI_FXUSB_PID) },
        { USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) },
        { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) },
        { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) },
index 9d359e189a645f7dcd13222433b9377787f81a34..e79861eeed4cca1471e4531ff727f0f8425e7892 100644 (file)
 #define CONTEC_VID             0x06CE  /* Vendor ID */
 #define CONTEC_COM1USBH_PID    0x8311  /* COM-1(USB)H */
 
+/*
+ * Mitsubishi Electric Corp. (http://www.meau.com)
+ * Submitted by Konstantin Holoborodko
+ */
+#define MITSUBISHI_VID         0x06D3
+#define MITSUBISHI_FXUSB_PID   0x0284 /* USB/RS422 converters: FX-USB-AW/-BD */
+
 /*
  * Definitions for B&B Electronics products.
  */
index 2e70efa08b77121f5d248413a95b14ea79095dda..5d9b178484fdf805bfd9a6e264732d5082216088 100644 (file)
@@ -903,6 +903,7 @@ static int usb_serial_probe(struct usb_interface *interface,
                port->port.ops = &serial_port_ops;
                port->serial = serial;
                spin_lock_init(&port->lock);
+               init_waitqueue_head(&port->delta_msr_wait);
                /* Keep this for private driver use for the moment but
                   should probably go away */
                INIT_WORK(&port->work, usb_serial_port_work);
index 43fb11ee2e8ded2cc2c70b954e3b68bdc06e1760..2968b4934659aab01dd626334a9ab7fc0e607383 100644 (file)
@@ -60,6 +60,15 @@ enum {
        VHOST_SCSI_VQ_IO = 2,
 };
 
+/*
+ * VIRTIO_RING_F_EVENT_IDX seems broken. Not sure the bug is in
+ * kernel but disabling it helps.
+ * TODO: debug and remove the workaround.
+ */
+enum {
+       VHOST_SCSI_FEATURES = VHOST_FEATURES & (~VIRTIO_RING_F_EVENT_IDX)
+};
+
 #define VHOST_SCSI_MAX_TARGET  256
 #define VHOST_SCSI_MAX_VQ      128
 
@@ -946,7 +955,7 @@ static void vhost_scsi_flush(struct vhost_scsi *vs)
 
 static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features)
 {
-       if (features & ~VHOST_FEATURES)
+       if (features & ~VHOST_SCSI_FEATURES)
                return -EOPNOTSUPP;
 
        mutex_lock(&vs->dev.mutex);
@@ -992,7 +1001,7 @@ static long vhost_scsi_ioctl(struct file *f, unsigned int ioctl,
                        return -EFAULT;
                return 0;
        case VHOST_GET_FEATURES:
-               features = VHOST_FEATURES;
+               features = VHOST_SCSI_FEATURES;
                if (copy_to_user(featurep, &features, sizeof features))
                        return -EFAULT;
                return 0;
index 4c1546f71d56a2be51785f3bf02ab50437ac94d6..e7718fdad1e162ad10c3e613008645db486be3a1 100644 (file)
@@ -2437,6 +2437,8 @@ config FB_MXS
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
+       select FB_MODE_HELPERS
+       select OF_VIDEOMODE
        help
          Framebuffer support for the MXS SoC.
 
index 755556ca5b2d988ec68b8cc3c1f9bbe7aadf6a34..1b2c26d1658c65ed2fd73bb8a43462f537fe7f4a 100644 (file)
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/of_device.h>
-#include <linux/of_gpio.h>
+#include <video/of_display_timing.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
 #include <linux/pinctrl/consumer.h>
-#include <linux/mxsfb.h>
+#include <linux/fb.h>
+#include <linux/regulator/consumer.h>
+#include <video/videomode.h>
 
 #define REG_SET        4
 #define REG_CLR        8
 #define VDCTRL0_ENABLE_PRESENT         (1 << 28)
 #define VDCTRL0_VSYNC_ACT_HIGH         (1 << 27)
 #define VDCTRL0_HSYNC_ACT_HIGH         (1 << 26)
-#define VDCTRL0_DOTCLK_ACT_FAILING     (1 << 25)
+#define VDCTRL0_DOTCLK_ACT_FALLING     (1 << 25)
 #define VDCTRL0_ENABLE_ACT_HIGH                (1 << 24)
 #define VDCTRL0_VSYNC_PERIOD_UNIT      (1 << 21)
 #define VDCTRL0_VSYNC_PULSE_WIDTH_UNIT (1 << 20)
 #define BLUE 2
 #define TRANSP 3
 
+#define STMLCDIF_8BIT  1 /** pixel data bus to the display is of 8 bit width */
+#define STMLCDIF_16BIT 0 /** pixel data bus to the display is of 16 bit width */
+#define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */
+#define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */
+
+#define MXSFB_SYNC_DATA_ENABLE_HIGH_ACT        (1 << 6)
+#define MXSFB_SYNC_DOTCLK_FALLING_ACT  (1 << 7) /* negtive edge sampling */
+
 enum mxsfb_devtype {
        MXSFB_V3,
        MXSFB_V4,
@@ -168,7 +178,8 @@ struct mxsfb_info {
        unsigned ld_intf_width;
        unsigned dotclk_delay;
        const struct mxsfb_devdata *devdata;
-       int mapped;
+       u32 sync;
+       struct regulator *reg_lcd;
 };
 
 #define mxsfb_is_v3(host) (host->devdata->ipversion == 3)
@@ -328,9 +339,19 @@ static void mxsfb_enable_controller(struct fb_info *fb_info)
 {
        struct mxsfb_info *host = to_imxfb_host(fb_info);
        u32 reg;
+       int ret;
 
        dev_dbg(&host->pdev->dev, "%s\n", __func__);
 
+       if (host->reg_lcd) {
+               ret = regulator_enable(host->reg_lcd);
+               if (ret) {
+                       dev_err(&host->pdev->dev,
+                               "lcd regulator enable failed:   %d\n", ret);
+                       return;
+               }
+       }
+
        clk_prepare_enable(host->clk);
        clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U);
 
@@ -352,6 +373,7 @@ static void mxsfb_disable_controller(struct fb_info *fb_info)
        struct mxsfb_info *host = to_imxfb_host(fb_info);
        unsigned loop;
        u32 reg;
+       int ret;
 
        dev_dbg(&host->pdev->dev, "%s\n", __func__);
 
@@ -375,6 +397,13 @@ static void mxsfb_disable_controller(struct fb_info *fb_info)
        clk_disable_unprepare(host->clk);
 
        host->enabled = 0;
+
+       if (host->reg_lcd) {
+               ret = regulator_disable(host->reg_lcd);
+               if (ret)
+                       dev_err(&host->pdev->dev,
+                               "lcd regulator disable failed: %d\n", ret);
+       }
 }
 
 static int mxsfb_set_par(struct fb_info *fb_info)
@@ -456,10 +485,10 @@ static int mxsfb_set_par(struct fb_info *fb_info)
                vdctrl0 |= VDCTRL0_HSYNC_ACT_HIGH;
        if (fb_info->var.sync & FB_SYNC_VERT_HIGH_ACT)
                vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH;
-       if (fb_info->var.sync & FB_SYNC_DATA_ENABLE_HIGH_ACT)
+       if (host->sync & MXSFB_SYNC_DATA_ENABLE_HIGH_ACT)
                vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH;
-       if (fb_info->var.sync & FB_SYNC_DOTCLK_FAILING_ACT)
-               vdctrl0 |= VDCTRL0_DOTCLK_ACT_FAILING;
+       if (host->sync & MXSFB_SYNC_DOTCLK_FALLING_ACT)
+               vdctrl0 |= VDCTRL0_DOTCLK_ACT_FALLING;
 
        writel(vdctrl0, host->base + LCDC_VDCTRL0);
 
@@ -678,14 +707,105 @@ static int mxsfb_restore_mode(struct mxsfb_info *host)
        return 0;
 }
 
+static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host)
+{
+       struct fb_info *fb_info = &host->fb_info;
+       struct fb_var_screeninfo *var = &fb_info->var;
+       struct device *dev = &host->pdev->dev;
+       struct device_node *np = host->pdev->dev.of_node;
+       struct device_node *display_np;
+       struct device_node *timings_np;
+       struct display_timings *timings;
+       u32 width;
+       int i;
+       int ret = 0;
+
+       display_np = of_parse_phandle(np, "display", 0);
+       if (!display_np) {
+               dev_err(dev, "failed to find display phandle\n");
+               return -ENOENT;
+       }
+
+       ret = of_property_read_u32(display_np, "bus-width", &width);
+       if (ret < 0) {
+               dev_err(dev, "failed to get property bus-width\n");
+               goto put_display_node;
+       }
+
+       switch (width) {
+       case 8:
+               host->ld_intf_width = STMLCDIF_8BIT;
+               break;
+       case 16:
+               host->ld_intf_width = STMLCDIF_16BIT;
+               break;
+       case 18:
+               host->ld_intf_width = STMLCDIF_18BIT;
+               break;
+       case 24:
+               host->ld_intf_width = STMLCDIF_24BIT;
+               break;
+       default:
+               dev_err(dev, "invalid bus-width value\n");
+               ret = -EINVAL;
+               goto put_display_node;
+       }
+
+       ret = of_property_read_u32(display_np, "bits-per-pixel",
+                                  &var->bits_per_pixel);
+       if (ret < 0) {
+               dev_err(dev, "failed to get property bits-per-pixel\n");
+               goto put_display_node;
+       }
+
+       timings = of_get_display_timings(display_np);
+       if (!timings) {
+               dev_err(dev, "failed to get display timings\n");
+               ret = -ENOENT;
+               goto put_display_node;
+       }
+
+       timings_np = of_find_node_by_name(display_np,
+                                         "display-timings");
+       if (!timings_np) {
+               dev_err(dev, "failed to find display-timings node\n");
+               ret = -ENOENT;
+               goto put_display_node;
+       }
+
+       for (i = 0; i < of_get_child_count(timings_np); i++) {
+               struct videomode vm;
+               struct fb_videomode fb_vm;
+
+               ret = videomode_from_timing(timings, &vm, i);
+               if (ret < 0)
+                       goto put_timings_node;
+               ret = fb_videomode_from_videomode(&vm, &fb_vm);
+               if (ret < 0)
+                       goto put_timings_node;
+
+               if (vm.data_flags & DISPLAY_FLAGS_DE_HIGH)
+                       host->sync |= MXSFB_SYNC_DATA_ENABLE_HIGH_ACT;
+               if (vm.data_flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
+                       host->sync |= MXSFB_SYNC_DOTCLK_FALLING_ACT;
+               fb_add_videomode(&fb_vm, &fb_info->modelist);
+       }
+
+put_timings_node:
+       of_node_put(timings_np);
+put_display_node:
+       of_node_put(display_np);
+       return ret;
+}
+
 static int mxsfb_init_fbinfo(struct mxsfb_info *host)
 {
        struct fb_info *fb_info = &host->fb_info;
        struct fb_var_screeninfo *var = &fb_info->var;
-       struct mxsfb_platform_data *pdata = host->pdev->dev.platform_data;
        dma_addr_t fb_phys;
        void *fb_virt;
-       unsigned fb_size = pdata->fb_size;
+       unsigned fb_size;
+       int ret;
 
        fb_info->fbops = &mxsfb_ops;
        fb_info->flags = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST;
@@ -695,40 +815,22 @@ static int mxsfb_init_fbinfo(struct mxsfb_info *host)
        fb_info->fix.visual = FB_VISUAL_TRUECOLOR,
        fb_info->fix.accel = FB_ACCEL_NONE;
 
-       var->bits_per_pixel = pdata->default_bpp ? pdata->default_bpp : 16;
+       ret = mxsfb_init_fbinfo_dt(host);
+       if (ret)
+               return ret;
+
        var->nonstd = 0;
        var->activate = FB_ACTIVATE_NOW;
        var->accel_flags = 0;
        var->vmode = FB_VMODE_NONINTERLACED;
 
-       host->dotclk_delay = pdata->dotclk_delay;
-       host->ld_intf_width = pdata->ld_intf_width;
-
        /* Memory allocation for framebuffer */
-       if (pdata->fb_phys) {
-               if (!fb_size)
-                       return -EINVAL;
-
-               fb_phys = pdata->fb_phys;
+       fb_size = SZ_2M;
+       fb_virt = alloc_pages_exact(fb_size, GFP_DMA);
+       if (!fb_virt)
+               return -ENOMEM;
 
-               if (!request_mem_region(fb_phys, fb_size, host->pdev->name))
-                       return -ENOMEM;
-
-               fb_virt = ioremap(fb_phys, fb_size);
-               if (!fb_virt) {
-                       release_mem_region(fb_phys, fb_size);
-                       return -ENOMEM;
-               }
-               host->mapped = 1;
-       } else {
-               if (!fb_size)
-                       fb_size = SZ_2M; /* default */
-               fb_virt = alloc_pages_exact(fb_size, GFP_DMA);
-               if (!fb_virt)
-                       return -ENOMEM;
-
-               fb_phys = virt_to_phys(fb_virt);
-       }
+       fb_phys = virt_to_phys(fb_virt);
 
        fb_info->fix.smem_start = fb_phys;
        fb_info->screen_base = fb_virt;
@@ -744,13 +846,7 @@ static void mxsfb_free_videomem(struct mxsfb_info *host)
 {
        struct fb_info *fb_info = &host->fb_info;
 
-       if (host->mapped) {
-               iounmap(fb_info->screen_base);
-               release_mem_region(fb_info->fix.smem_start,
-                               fb_info->screen_size);
-       } else {
-               free_pages_exact(fb_info->screen_base, fb_info->fix.smem_len);
-       }
+       free_pages_exact(fb_info->screen_base, fb_info->fix.smem_len);
 }
 
 static struct platform_device_id mxsfb_devtype[] = {
@@ -777,47 +873,35 @@ static int mxsfb_probe(struct platform_device *pdev)
 {
        const struct of_device_id *of_id =
                        of_match_device(mxsfb_dt_ids, &pdev->dev);
-       struct mxsfb_platform_data *pdata = pdev->dev.platform_data;
        struct resource *res;
        struct mxsfb_info *host;
        struct fb_info *fb_info;
        struct fb_modelist *modelist;
        struct pinctrl *pinctrl;
-       int panel_enable;
-       enum of_gpio_flags flags;
-       int i, ret;
+       int ret;
 
        if (of_id)
                pdev->id_entry = of_id->data;
 
-       if (!pdata) {
-               dev_err(&pdev->dev, "No platformdata. Giving up\n");
-               return -ENODEV;
-       }
-
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
                dev_err(&pdev->dev, "Cannot get memory IO resource\n");
                return -ENODEV;
        }
 
-       if (!request_mem_region(res->start, resource_size(res), pdev->name))
-               return -EBUSY;
-
        fb_info = framebuffer_alloc(sizeof(struct mxsfb_info), &pdev->dev);
        if (!fb_info) {
                dev_err(&pdev->dev, "Failed to allocate fbdev\n");
-               ret = -ENOMEM;
-               goto error_alloc_info;
+               return -ENOMEM;
        }
 
        host = to_imxfb_host(fb_info);
 
-       host->base = ioremap(res->start, resource_size(res));
-       if (!host->base) {
+       host->base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(host->base)) {
                dev_err(&pdev->dev, "ioremap failed\n");
-               ret = -ENOMEM;
-               goto error_ioremap;
+               ret = PTR_ERR(host->base);
+               goto fb_release;
        }
 
        host->pdev = pdev;
@@ -828,45 +912,31 @@ static int mxsfb_probe(struct platform_device *pdev)
        pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
        if (IS_ERR(pinctrl)) {
                ret = PTR_ERR(pinctrl);
-               goto error_getpin;
+               goto fb_release;
        }
 
-       host->clk = clk_get(&host->pdev->dev, NULL);
+       host->clk = devm_clk_get(&host->pdev->dev, NULL);
        if (IS_ERR(host->clk)) {
                ret = PTR_ERR(host->clk);
-               goto error_getclock;
+               goto fb_release;
        }
 
-       panel_enable = of_get_named_gpio_flags(pdev->dev.of_node,
-                                              "panel-enable-gpios", 0, &flags);
-       if (gpio_is_valid(panel_enable)) {
-               unsigned long f = GPIOF_OUT_INIT_HIGH;
-               if (flags == OF_GPIO_ACTIVE_LOW)
-                       f = GPIOF_OUT_INIT_LOW;
-               ret = devm_gpio_request_one(&pdev->dev, panel_enable,
-                                           f, "panel-enable");
-               if (ret) {
-                       dev_err(&pdev->dev,
-                               "failed to request gpio %d: %d\n",
-                               panel_enable, ret);
-                       goto error_panel_enable;
-               }
-       }
+       host->reg_lcd = devm_regulator_get(&pdev->dev, "lcd");
+       if (IS_ERR(host->reg_lcd))
+               host->reg_lcd = NULL;
 
-       fb_info->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
+       fb_info->pseudo_palette = devm_kzalloc(&pdev->dev, sizeof(u32) * 16,
+                                              GFP_KERNEL);
        if (!fb_info->pseudo_palette) {
                ret = -ENOMEM;
-               goto error_pseudo_pallette;
+               goto fb_release;
        }
 
        INIT_LIST_HEAD(&fb_info->modelist);
 
        ret = mxsfb_init_fbinfo(host);
        if (ret != 0)
-               goto error_init_fb;
-
-       for (i = 0; i < pdata->mode_count; i++)
-               fb_add_videomode(&pdata->mode_list[i], &fb_info->modelist);
+               goto fb_release;
 
        modelist = list_first_entry(&fb_info->modelist,
                        struct fb_modelist, list);
@@ -880,7 +950,7 @@ static int mxsfb_probe(struct platform_device *pdev)
        ret = register_framebuffer(fb_info);
        if (ret != 0) {
                dev_err(&pdev->dev,"Failed to register framebuffer\n");
-               goto error_register;
+               goto fb_destroy;
        }
 
        if (!host->enabled) {
@@ -893,22 +963,12 @@ static int mxsfb_probe(struct platform_device *pdev)
 
        return 0;
 
-error_register:
+fb_destroy:
        if (host->enabled)
                clk_disable_unprepare(host->clk);
        fb_destroy_modelist(&fb_info->modelist);
-error_init_fb:
-       kfree(fb_info->pseudo_palette);
-error_pseudo_pallette:
-error_panel_enable:
-       clk_put(host->clk);
-error_getclock:
-error_getpin:
-       iounmap(host->base);
-error_ioremap:
+fb_release:
        framebuffer_release(fb_info);
-error_alloc_info:
-       release_mem_region(res->start, resource_size(res));
 
        return ret;
 }
@@ -917,19 +977,14 @@ static int mxsfb_remove(struct platform_device *pdev)
 {
        struct fb_info *fb_info = platform_get_drvdata(pdev);
        struct mxsfb_info *host = to_imxfb_host(fb_info);
-       struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
        if (host->enabled)
                mxsfb_disable_controller(fb_info);
 
        unregister_framebuffer(fb_info);
-       kfree(fb_info->pseudo_palette);
        mxsfb_free_videomem(host);
-       iounmap(host->base);
-       clk_put(host->clk);
 
        framebuffer_release(fb_info);
-       release_mem_region(res->start, resource_size(res));
 
        platform_set_drvdata(pdev, NULL);
 
index e31f5b33b501e155fed50e9a5463614e9cdc1690..d40612c31a989d9437e482496ff52c6f451404d8 100644 (file)
@@ -32,6 +32,8 @@
 
 #include <linux/omap-dma.h>
 
+#include <mach/hardware.h>
+
 #include "omapfb.h"
 #include "lcdc.h"
 
index 6b6643911d296c707e7eaa29c30412081378cc5f..048c98381ef6affd36417518881b890ec1f170dd 100644 (file)
@@ -63,6 +63,9 @@ struct tpo_td043_device {
        u32 power_on_resume:1;
 };
 
+/* used to pass spi_device from SPI to DSS portion of the driver */
+static struct tpo_td043_device *g_tpo_td043;
+
 static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data)
 {
        struct spi_message      m;
@@ -403,7 +406,7 @@ static void tpo_td043_disable(struct omap_dss_device *dssdev)
 
 static int tpo_td043_probe(struct omap_dss_device *dssdev)
 {
-       struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
+       struct tpo_td043_device *tpo_td043 = g_tpo_td043;
        int nreset_gpio = dssdev->reset_gpio;
        int ret = 0;
 
@@ -440,6 +443,8 @@ static int tpo_td043_probe(struct omap_dss_device *dssdev)
        if (ret)
                dev_warn(&dssdev->dev, "failed to create sysfs files\n");
 
+       dev_set_drvdata(&dssdev->dev, tpo_td043);
+
        return 0;
 
 fail_gpio_req:
@@ -505,6 +510,9 @@ static int tpo_td043_spi_probe(struct spi_device *spi)
                return -ENODEV;
        }
 
+       if (g_tpo_td043 != NULL)
+               return -EBUSY;
+
        spi->bits_per_word = 16;
        spi->mode = SPI_MODE_0;
 
@@ -521,7 +529,7 @@ static int tpo_td043_spi_probe(struct spi_device *spi)
        tpo_td043->spi = spi;
        tpo_td043->nreset_gpio = dssdev->reset_gpio;
        dev_set_drvdata(&spi->dev, tpo_td043);
-       dev_set_drvdata(&dssdev->dev, tpo_td043);
+       g_tpo_td043 = tpo_td043;
 
        omap_dss_register_driver(&tpo_td043_driver);
 
@@ -534,6 +542,7 @@ static int tpo_td043_spi_remove(struct spi_device *spi)
 
        omap_dss_unregister_driver(&tpo_td043_driver);
        kfree(tpo_td043);
+       g_tpo_td043 = NULL;
 
        return 0;
 }
index d7d66ef5cb58098c6f80268651c0a277957fc2e0..7f791aeda4d24a1025e4d712f11e1b828cdb8b24 100644 (file)
@@ -202,12 +202,10 @@ static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = {
 
 static const enum omap_dss_output_id omap4_dss_supported_outputs[] = {
        /* OMAP_DSS_CHANNEL_LCD */
-       OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
-       OMAP_DSS_OUTPUT_DSI1,
+       OMAP_DSS_OUTPUT_DBI | OMAP_DSS_OUTPUT_DSI1,
 
        /* OMAP_DSS_CHANNEL_DIGIT */
-       OMAP_DSS_OUTPUT_VENC | OMAP_DSS_OUTPUT_HDMI |
-       OMAP_DSS_OUTPUT_DPI,
+       OMAP_DSS_OUTPUT_VENC | OMAP_DSS_OUTPUT_HDMI,
 
        /* OMAP_DSS_CHANNEL_LCD2 */
        OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
index 5a32232cf7c15cdc05536ecb157eeb86048154e0..67af155cf60286f87c6dc1c576d72008d6e5c4fb 100644 (file)
@@ -182,7 +182,7 @@ config XEN_PRIVCMD
 
 config XEN_STUB
        bool "Xen stub drivers"
-       depends on XEN && X86_64
+       depends on XEN && X86_64 && BROKEN
        default n
        help
          Allow kernel to install stub drivers, to reserve space for Xen drivers,
index d17aa41a9041428fbff17a890b2af18b64422ef4..aa85881d17b23f7ff6425be0140b6aed0c63c942 100644 (file)
@@ -403,11 +403,23 @@ static void unmask_evtchn(int port)
 
        if (unlikely((cpu != cpu_from_evtchn(port))))
                do_hypercall = 1;
-       else
+       else {
+               /*
+                * Need to clear the mask before checking pending to
+                * avoid a race with an event becoming pending.
+                *
+                * EVTCHNOP_unmask will only trigger an upcall if the
+                * mask bit was set, so if a hypercall is needed
+                * remask the event.
+                */
+               sync_clear_bit(port, BM(&s->evtchn_mask[0]));
                evtchn_pending = sync_test_bit(port, BM(&s->evtchn_pending[0]));
 
-       if (unlikely(evtchn_pending && xen_hvm_domain()))
-               do_hypercall = 1;
+               if (unlikely(evtchn_pending && xen_hvm_domain())) {
+                       sync_set_bit(port, BM(&s->evtchn_mask[0]));
+                       do_hypercall = 1;
+               }
+       }
 
        /* Slow path (hypercall) if this is a non-local port or if this is
         * an hvm domain and an event is pending (hvm domains don't have
@@ -418,8 +430,6 @@ static void unmask_evtchn(int port)
        } else {
                struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu);
 
-               sync_clear_bit(port, BM(&s->evtchn_mask[0]));
-
                /*
                 * The following is basically the equivalent of
                 * 'hw_resend_irq'. Just like a real IO-APIC we 'lose
index 0ef7c4d40f86b9018ed2ae2ed0eda2071d4d7bfd..b04fb64c5a91ee2613b21c8d9c146ab16f82a941 100644 (file)
@@ -44,7 +44,7 @@ int xen_event_channel_op_compat(int cmd, void *arg)
 }
 EXPORT_SYMBOL_GPL(xen_event_channel_op_compat);
 
-int HYPERVISOR_physdev_op_compat(int cmd, void *arg)
+int xen_physdev_op_compat(int cmd, void *arg)
 {
        struct physdev_op op;
        int rc;
@@ -78,3 +78,4 @@ int HYPERVISOR_physdev_op_compat(int cmd, void *arg)
 
        return rc;
 }
+EXPORT_SYMBOL_GPL(xen_physdev_op_compat);
index f3278a6603ca3b0913280f4bfa5c7e07c0eff47a..90e34ac7e522dfcf2c5af269639f5f877d95ac3b 100644 (file)
@@ -505,6 +505,9 @@ static int __init xen_acpi_processor_init(void)
 
                pr = per_cpu(processors, i);
                perf = per_cpu_ptr(acpi_perf_data, i);
+               if (!pr)
+                       continue;
+
                pr->performance = perf;
                rc = acpi_processor_get_performance_info(pr);
                if (rc)
index 9204126f1560ced72321b267b96099acfe71b8dd..a2278ba7fb273a523476e0504388e49e48511093 100644 (file)
@@ -17,6 +17,7 @@
 #include <xen/events.h>
 #include <asm/xen/pci.h>
 #include <asm/xen/hypervisor.h>
+#include <xen/interface/physdev.h>
 #include "pciback.h"
 #include "conf_space.h"
 #include "conf_space_quirks.h"
@@ -85,37 +86,52 @@ static struct pcistub_device *pcistub_device_alloc(struct pci_dev *dev)
 static void pcistub_device_release(struct kref *kref)
 {
        struct pcistub_device *psdev;
+       struct pci_dev *dev;
        struct xen_pcibk_dev_data *dev_data;
 
        psdev = container_of(kref, struct pcistub_device, kref);
-       dev_data = pci_get_drvdata(psdev->dev);
+       dev = psdev->dev;
+       dev_data = pci_get_drvdata(dev);
 
-       dev_dbg(&psdev->dev->dev, "pcistub_device_release\n");
+       dev_dbg(&dev->dev, "pcistub_device_release\n");
 
-       xen_unregister_device_domain_owner(psdev->dev);
+       xen_unregister_device_domain_owner(dev);
 
        /* Call the reset function which does not take lock as this
         * is called from "unbind" which takes a device_lock mutex.
         */
-       __pci_reset_function_locked(psdev->dev);
-       if (pci_load_and_free_saved_state(psdev->dev,
-                                         &dev_data->pci_saved_state)) {
-               dev_dbg(&psdev->dev->dev, "Could not reload PCI state\n");
-       } else
-               pci_restore_state(psdev->dev);
+       __pci_reset_function_locked(dev);
+       if (pci_load_and_free_saved_state(dev, &dev_data->pci_saved_state))
+               dev_dbg(&dev->dev, "Could not reload PCI state\n");
+       else
+               pci_restore_state(dev);
+
+       if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) {
+               struct physdev_pci_device ppdev = {
+                       .seg = pci_domain_nr(dev->bus),
+                       .bus = dev->bus->number,
+                       .devfn = dev->devfn
+               };
+               int err = HYPERVISOR_physdev_op(PHYSDEVOP_release_msix,
+                                               &ppdev);
+
+               if (err)
+                       dev_warn(&dev->dev, "MSI-X release failed (%d)\n",
+                                err);
+       }
 
        /* Disable the device */
-       xen_pcibk_reset_device(psdev->dev);
+       xen_pcibk_reset_device(dev);
 
        kfree(dev_data);
-       pci_set_drvdata(psdev->dev, NULL);
+       pci_set_drvdata(dev, NULL);
 
        /* Clean-up the device */
-       xen_pcibk_config_free_dyn_fields(psdev->dev);
-       xen_pcibk_config_free_dev(psdev->dev);
+       xen_pcibk_config_free_dyn_fields(dev);
+       xen_pcibk_config_free_dev(dev);
 
-       psdev->dev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED;
-       pci_dev_put(psdev->dev);
+       dev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED;
+       pci_dev_put(dev);
 
        kfree(psdev);
 }
@@ -355,6 +371,19 @@ static int pcistub_init_device(struct pci_dev *dev)
        if (err)
                goto config_release;
 
+       if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) {
+               struct physdev_pci_device ppdev = {
+                       .seg = pci_domain_nr(dev->bus),
+                       .bus = dev->bus->number,
+                       .devfn = dev->devfn
+               };
+
+               err = HYPERVISOR_physdev_op(PHYSDEVOP_prepare_msix, &ppdev);
+               if (err)
+                       dev_err(&dev->dev, "MSI-X preparation failed (%d)\n",
+                               err);
+       }
+
        /* We need the device active to save the state. */
        dev_dbg(&dev->dev, "save state of device\n");
        pci_save_state(dev);
index cbb09ce9730ac0494dc43fbef5d7d6f2ddd05b0b..5d8ee1319b5c1878c5b82f82bb150dfece7b2cf8 100644 (file)
@@ -82,7 +82,7 @@ fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \
 fw-shipped-$(CONFIG_SCSI_QLOGIC_1280) += qlogic/1040.bin qlogic/1280.bin \
                                         qlogic/12160.bin
 fw-shipped-$(CONFIG_SCSI_QLOGICPTI) += qlogic/isp1000.bin
-fw-shipped-$(CONFIG_INFINIBAND_QIB) += qlogic/sd7220.fw
+fw-shipped-$(CONFIG_INFINIBAND_QIB) += intel/sd7220.fw
 fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp
 fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \
                                     ess/maestro3_assp_minisrc.fw
diff --git a/firmware/intel/sd7220.fw.ihex b/firmware/intel/sd7220.fw.ihex
new file mode 100644 (file)
index 0000000..a336363
--- /dev/null
@@ -0,0 +1,513 @@
+:10000000020A29020A87E5E630E6047F0180027FC2
+:1000100000E5E230E4047E0180027E00EE5F6008CD
+:1000200053F9F7E4F5FE80087F0A121731120EA289
+:1000300075FC08E4F5FDE5E720E70343F908220035
+:1000400001201100042000755101E4F552F553F52B
+:1000500052F57E7F04020438C2360552E552D3942D
+:100060000C4005755201D23690070C7407F0A3744A
+:10007000FFF0E4F50CA3F0900714F0A3F0750B204B
+:10008000F509E4F508E508D39430400302040412AE
+:100090000006150BE50870047F0180027F00E5096A
+:1000A00070047E0180027E00EE5F6005121871D23E
+:1000B0003553E1F7E5084509FFE50B25E025E02488
+:1000C00083F582E43407F583EFF085E220E552D32F
+:1000D0009401400D1219F3E054A064407003020330
+:1000E000FB53F9F8909470E4F0E0F510AF09121E9C
+:1000F000B3AF08EF4408F582758380E0F529EF443B
+:1001000007121A3CF5225440D39400401EE52954AE
+:10011000F070211219F3E04480F0E52254306508B4
+:1001200070091219F3E054BFF080091219F37440FA
+:10013000F00203FB121A127583AE74FFF0AF087E53
+:1001400000EF4407F582E0FDE50B25E025E0248182
+:10015000F582E43407F583EDF090070EE004F0EF4C
+:100160004407F582758398E0F528121A23400C1293
+:1001700019F3E04401121A320203F6AF087E00744C
+:1001800080CDEFCD8D82F583E030E00A1219F3E0E7
+:100190004420F00203FB1219F3E054DFF0EE44AE0A
+:1001A000121A4330E4030203FB749E121A0520E086
+:1001B000030203FB8F828E83E020E0030203FB1225
+:1001C00019F3E04410F0E5E320E708E508121A3AD5
+:1001D0004404F0AF087E00EF121A3A20E2341219FC
+:1001E000F3E04408F0E5E430E6047D0180027D00A0
+:1001F000E57EC3940450047C0180027C00EC4D60D9
+:1002000005C2350203FBEE44D2121A434440F00209
+:1002100003FB1219F3E054F7F0121A127583D2E0BF
+:1002200054BFF0900714E004F0E57E7003757E0182
+:10023000AF087E00121A2340121219F3E044011293
+:1002400019F2E05402121A320203FB1219F3E044CD
+:10025000021219F2E054FEF0C235EE448A8F82F5A4
+:1002600083E0F517548F4440F07490FCE508440790
+:10027000FDF5828C83E0543F900702F0E054C08D7E
+:10028000828C83F07492121A05900703121A197463
+:1002900082121A05900704121A1974B4121A0590E2
+:1002A0000705121A197494FEE5084406121A0AF595
+:1002B0001030E004D2378002C237E510547F8F82BD
+:1002C0008E83F0304430121A035480D394004004DB
+:1002D000D2398002C2398F828E83E04480F0121AB4
+:1002E000035440D394004004D23A8002C23A8F8231
+:1002F0008E83E04440F07492FEE5084406121A0A28
+:1003000030E704D2388002C2388F828E83E0547F77
+:10031000F0121E46E4F50A20030280033043031264
+:1003200019952002028003304203120C8F303006F0
+:10033000121995120C8F120D471219F3E054FBF0AD
+:10034000E50AC39401404643E1081219F3E044046E
+:10035000F0E5E420E72A121A127583D2E05408D39C
+:10036000940040047F0180027F00E50AC3940140AD
+:10037000047E0180027E00EF5E6005121DD78017AB
+:10038000121A127583D2E04408F00203FB121A120B
+:100390007583D2E054F7F0121E467F0812173174AD
+:1003A0008EFE121A128E83E0F51054FEF0E5104412
+:1003B00001FFE508FDED4407F582EFF0E51054FE7E
+:1003C000FFED4407F582EF121A11758386E04410A1
+:1003D000121A11E04410F01219F3E054FD4401FF29
+:1003E0001219F3EF121A3230320CE5084408F58284
+:1003F0007583827405F0AF0B1218D774102508F5B9
+:10040000080200850509E509D3940750030200821C
+:10041000E57ED3940040047F0180027F00E57EC327
+:1004200094FA50047E0180027E00EE5F6002057E39
+:1004300030350B43E1017F0912173102005853E1B7
+:10044000FE0200588E6A8F6B8C6C8D6D756E017517
+:100450006F01757001E4F573F574F57590072FF071
+:10046000F53CF53EF546F547F53DF53FF56FE56F93
+:10047000700FE56B456A12072A758380743AF08025
+:100480000912072A758380741AF0E4F56EC3743F6D
+:10049000956EFF120865758382EFF0121A4D1208EF
+:1004A000C6E533F01208FA1208B140E1E56F700BAF
+:1004B00012072A7583807436F0800912072A758323
+:1004C000807416F0756E0112072A7583B4E56EF01C
+:1004D000121A4D743F256EF582E43400F583E5333E
+:1004E000F074BF256EF582E434001208B140D8E400
+:1004F000F570F546F547F56E1208FAF583E0FE1241
+:1005000008C6E07C002400FFEC3EFEAD3BD3EF9D2F
+:10051000EE9C50047B0180027B00E57070047A0140
+:1005200080027A00EB5A6006856E46757001D3EF43
+:100530009DEE9C50047F0180027F00E570B40104B1
+:100540007E0180027E00EF5E6003856E47056EE5EA
+:100550006E647F70A3E5466005E547B47E0385467B
+:1005600047E56F7008854676854777800EC3747FB0
+:100570009546F578C3747F9547F579E56F7037E553
+:10058000466547700C757301757401F53CF53D8047
+:1005900035E4F54EC3E5479546F53CC313F57125A3
+:1005A00046F572C3943F4005E4F53D8040C3743F77
+:1005B0009572F53D8037E5466547700F7573017597
+:1005C0007501F53EF53F754E018022E4F54EC3E519
+:1005D000479546F53EC313F5712546F572D3943F12
+:1005E0005005E4F53F8006E57224C1F53F056FE54F
+:1005F0006FC39402500302046EE56D456C70028077
+:1006000004E574457590072FF07F01E53E6004E531
+:100610003C7014E4F53CF53DF53EF53F1208D27010
+:1006200004F00206A4807AE53CC3953E4007E53C11
+:10063000953EFF8006C3E53E953CFFE576D3957970
+:10064000400585767A800385797AE577C395785079
+:100650000585777B800385787BE57BD3957A403071
+:10066000E57B957AF53CF53EC3E57B957A900719D5
+:10067000F0E53CC313F571257AF572C3943F40054C
+:10068000E4F53D801FC3743F9572F53DF53F80143E
+:10069000E4F53CF53E900719F01208D27003F080A3
+:1006A000037401F01208657583D0E0540FFEAD3C71
+:1006B00070027E07BE0F027E80EEFBEFD39B74803C
+:1006C000F898401FE4F53CF53E1208D27003F08024
+:1006D000127401F0E508FBEB4407F5827583D2E064
+:1006E0004410F0E508FBEB4409F58275839EEDF0BC
+:1006F000EB4407F5827583CAEDF01208657583CC6B
+:10070000EFF022E5084407F5827583BCE054F0F071
+:10071000E5084407F5827583BEE054F0F0E508442F
+:1007200007F5827583C0E054F0F0E5084407F582D0
+:1007300022F0900728E0FEA3E0F5828E8322854216
+:100740004285414185404074C02FF58274023EF5D8
+:1007500083E542F074E02FF58274023EF58322E5D2
+:100760004229FDE433FCE53CC39DEC6480F87480D1
+:100770009822F583E0900722541FFDE0FAA3E0F5EC
+:10078000828A83EDF022900722E0FCA3E0F5828CC0
+:100790008322900724FFED4407CFF0A3EFF02285DA
+:1007A0003838853939853A3A74C02FF58274023E5B
+:1007B000F58322900726FFED4407CFF0A3EFF02248
+:1007C000F074A02FF58274023EF5832274C02511C7
+:1007D000F582E43401F5832274002511F582E434B6
+:1007E00002F5832274602511F582E43403F5832237
+:1007F00074802511F582E43403F5832274E0251119
+:10080000F582E43403F5832274402511F582E43443
+:1008100006F5832274802FF58274023EF58322AFA1
+:10082000087E00EF4407F58222F583E5824407F550
+:1008300082E540F02274402511F582E43402F5830C
+:100840002274C02511F582E43403F5832274002557
+:1008500011F582E43406F5832274202511F582E433
+:100860003406F58322E508FDED4407F58222E541D3
+:10087000F0E56564014564227E00FB7A00FD7C00A2
+:100880002274202511F582E434022274A02511F58A
+:1008900082E4340322853E42853F418F4022853CDD
+:1008A00042853D418F402275453F900720E4F0A3EB
+:1008B00022F583E532F0056EE56EC3944022F0E543
+:1008C000084406F582227400256EF582E43400F5B2
+:1008D0008322E56D456C90072F22E4F9E53CD39522
+:1008E0003E2274802EF582E43402F583E02274A067
+:1008F0002EF582E43402F583E0227480256EF582C1
+:10090000E43400222542FDE433FC22854242854145
+:100910004185404022ED4C60030209E5EF4E7037FF
+:10092000900726120789E0FD1207CCEDF09007280A
+:10093000120789E0FD1207D8EDF0120786E0541F78
+:10094000FD120881F583EDF0900724120789E05429
+:100950001FFD120835EDF0EF64044E703790072646
+:10096000120789E0FD1207E4EDF0900728120789CD
+:10097000E0FD1207F0EDF0120786E0541FFD1208AB
+:100980008BF583EDF0900724120789E0541FFD12C8
+:100990000841EDF0EF64014E70047D0180027D009E
+:1009A000EF64024E70047F0180027F00EF4D60789B
+:1009B000900726120735E0FF1207FCEF120731E01F
+:1009C000FF120808EFF0900722120735E0541FFFCE
+:1009D00012084DEFF0900724120735E0541FFF1264
+:1009E0000859EFF0221207CCE4F01207D8E4F01215
+:1009F0000881F583E4F01208357414F01207E4E47A
+:100A0000F01207F0E4F012088BF583E4F0120841CD
+:100A10007414F01207FCE4F0120808E4F012084D18
+:100A2000E4F01208597414F02253F9F775FC10E43D
+:100A3000F5FD75FE30F5FFE5E720E70343F908E52E
+:100A4000E620E70B78FFE4F6D8FD53E6FE80097850
+:100A500008E4F6D8FD53E6FE758180E4F5A8D2A837
+:100A6000C2A9D2AFE5E220E50520E602800343E11A
+:100A700002E5E220E00E9000007F007E08E4F0A393
+:100A8000DFFCDEFA020ADB43FA01C0E0C0F0C083FB
+:100A9000C082C0D0121CE7D0D0D082D083D0F0D09A
+:100AA000E053FAFE32021B55E493A3F8E493A3F655
+:100AB00008DFF98029E493A3F85407240CC8C33352
+:100AC000C4540F4420C8834004F456800146F6DF26
+:100AD000E4800B010204081020408090003FE47E77
+:100AE000019360C1A3FF543F30E509541FFEE49316
+:100AF000A360010ECF54C025E060AD40B880FE8CED
+:100B0000648D658A668B67E4F569EF4E7003021D9C
+:100B100055E4F568E5674566703212072A758390DB
+:100B2000E41207297583C2E41207297583C4E4120D
+:100B30000870702912072A758392E41207297583B9
+:100B4000C6E41207297583C8E4F0801190072612C5
+:100B50000735E41208707005120732E4F0121D55D3
+:100B6000121EBFE5674566703312072A758390E54C
+:100B7000411207297583C2E5411207297583C41202
+:100B8000086E702912072A758392E54012072975AD
+:100B900083C6E5401207297583C8800E9007261288
+:100BA000073512086E7006120732E540F0AF697E15
+:100BB00000AD67AC6612044412072A7583CAE0D3FD
+:100BC0009400500C0568E568C394055003020B14AB
+:100BD000228C608D611208DA7420400D2FF582742A
+:100BE000033EF583E53EF0800B2FF58274033EF55E
+:100BF00083E53CF0E53CD3953E403CE561456070C3
+:100C000010E9120904E53E120768403B120895807E
+:100C100018E53EC39538401D853E38E53E600585A4
+:100C20003F3980038539398F3A120814E53E12079F
+:100C3000C0E53FF0228043E5614560701912075F0F
+:100C4000400512089E802712090B120814E5421273
+:100C500007C0E541F022E53CC39538401D853C388E
+:100C6000E53C6005853D3980038539398F3A1208A6
+:100C700014E53C1207C0E53DF02285383885393946
+:100C8000853A3A120814E5381207C0E539F0227F98
+:100C900006121731121D23120E04120E33E0440AFD
+:100CA000F0748EFE120E04120E0BEFF0E52830E504
+:100CB00003D38001C3400575142080037514081206
+:100CC0000E0475838AE514F0B4FF05751280800662
+:100CD000E514C313F512E4F516F57F121936121355
+:100CE000A3E50AC3940150090516E516C394144000
+:100CF000EAE5E420E728120E047583D2E05408D315
+:100D0000940040047F0180027F00E50AC394014003
+:100D1000047E0180027E00EF5E6003121DD7E57F36
+:100D2000C394114014120E047583D2E04480F0E5A0
+:100D3000E420E70F121DD7800A120E047583D2E05B
+:100D4000547FF0121D2322748A850882F583E517EB
+:100D5000F0120E3AE4F0900702E0120E177583903D
+:100D6000EFF07492FEE5084407FFF5828E83E054AD
+:100D7000C0FD900703E0543F4D8F828E83F09007B3
+:100D800004E0120E17758382EFF0900705E0FFED87
+:100D90004407F5827583B4EF120E03758380E05427
+:100DA000BFF030370A120E91758394E04480F03022
+:100DB000380A120E91758392E04480F0E52830E401
+:100DC0001A20390A120E04758388E0547FF0203A05
+:100DD0000A120E04758388E054BFF0748CFE120E64
+:100DE000048E83E0540F120E03758386E054BFF027
+:100DF000E5084406120DFD75838AE4F022F582753C
+:100E00008382E4F0E5084407F582228E83E0F51042
+:100E100054FEF0E5104401FFE508FDED4407F582BE
+:100E200022E515C45407FFE508FDED4408F5827579
+:100E3000838222758380E04440F0E5084408F5820F
+:100E400075838A22E51625E025E024AFF582E43497
+:100E50001AF583E493F50D2243E11043E18053E159
+:100E6000FD85E11022E51625E025E024B2F582E4B7
+:100E7000341AF583E49322855582855483E515F071
+:100E800022E5E25420D3940022E5E25440D39400BA
+:100E900022E5084406F58222FDE508FBEB4407F550
+:100EA000822253F9F775FE3022EF4E70261207CCDE
+:100EB000E0FD90072612077B1207D8E0FD90072877
+:100EC00012077B120881120772120835E09007247E
+:100ED000120778EF64044E70291207E4E0FD9007D2
+:100EE0002612077B1207F0E0FD90072812077B12FD
+:100EF000088B120772120841E0541FFD900724125C
+:100F0000077BEF64014E70047D0180027D00EF6479
+:100F1000024E70047F0180027F00EF4D60351207A2
+:100F2000FCE0FF900726120789EFF0120808E0FFA7
+:100F3000900728120789EFF012084DE0541FFF12A6
+:100F40000786EFF0120859E0541FFF90072412079C
+:100F500089EFF022E4F553120E8140047F018002F4
+:100F60007F00120E8940047E0180027E00EE4F70E9
+:100F700003020FF685E11043E10253E10F85E11012
+:100F8000E4F551E5E3543FF552120E89401DAD5290
+:100F9000AF51121118EF600885E11043E140800B5A
+:100FA00053E1BF120E5812000680FBE5E3543FF5F3
+:100FB00051E5E4543FF552120E81401DAD52AF5140
+:100FC000121118EF600885E11043E120800B53E116
+:100FD000DF120E5812000680FB120E8140047F01C2
+:100FE00080027F00120E8940047E0180027E00EEA6
+:100FF0004F6003120E5B22120E21EFF012109122AD
+:1010000002110002104002109000000000000000D9
+:1010100001200120E4F5571216BD121644E4121007
+:10102000561214B7900726120735E4120731E4F080
+:101030001210561214B7900726120735E541120711
+:1010400031E540F0AF577E00AD567C00120444AF4E
+:10105000567E000211EEFF900720A3E0FDE4F55656
+:10106000F540FEFCAB56FA1211517F0F7D18E4F5E6
+:1010700056F540FEFCAB56FA121541AF567E0012F3
+:101080001AFFE4FFF5567D1FF540FEFCAB56FA2231
+:1010900022E4F555E508FD74A0F556ED4407F55733
+:1010A000E52830E503D38001C340057F28EF8004A5
+:1010B0007F14EFC313F554E4F9120E1875838EE014
+:1010C000F510CEEFCEEED394004026E51054FE127C
+:1010D0000E9875838EEDF0E5104401FDEB4407F5A5
+:1010E00082EDF0855782855683E030E301091E804A
+:1010F000D4C234E9C395544002D2342202000622FD
+:10110000303011901000E493F510901010E493F536
+:101110001012109012115022E4FCC3ED9FFAEFF56B
+:101120008375820079FFE493CC6CCCA3D9F8DAF60E
+:10113000E5E230E4028CE5ED24FFFFEF7582FFF578
+:1011400083E4936C70037F01227F00222211000050
+:10115000228E588F598C5A8D5B8A5C8B5D755E012F
+:10116000E4F55FF560F56212072A7583D0E0FFC4ED
+:10117000540FF561121EA585595ED3E55E955BE5BA
+:101180005A12076B504B1207037583BCE0455E1281
+:1011900007297583BEE0455E1207297583C0E045C7
+:1011A0005EF0AF5FE560120878120AFFAF627E0062
+:1011B000AD5DAC5C120444E561AF5E7E00B4030536
+:1011C000121E218007AD5DAC5C121317055E021183
+:1011D0007A1207037583BCE045401207297583BE68
+:1011E000E045401207297583C0E04540F0228E5843
+:1011F0008F59755A017901755B01E4FB12072A7555
+:1012000083AEE0541AFF120865E0C4135407FEEFE2
+:10121000700CEE6535700790072FE0B4010DAF3507
+:101220007E00120EA9CFEBCF021E60E55964024585
+:101230005870047F0180027F00E559455870047E94
+:101240000180027E00EE4F602385414985404BE5D9
+:10125000594558702CAF5AFECDE9CDFCAB59AA5870
+:10126000120AFFAF5B7E00121E608015AF5B7E002E
+:10127000121E60900726120735E549120731E54B2B
+:10128000F0E4FDAF35FEFC120915228C648D651269
+:1012900008DA403CE56545647010120904C3E53E78
+:1012A000120769403B1208958018E53EC395384007
+:1012B0001D853E38E53E6005853F39800385393917
+:1012C0008F3A1207A8E53E120753E53FF022803B14
+:1012D000E5654564701112075F400512089E801F86
+:1012E00012073EE541F022E53CC39538401D853CA0
+:1012F00038E53C6005853D3980038539398F3A12E0
+:1013000007A8E53C120753E53DF02212079FE53898
+:10131000120753E539F0228C638D641208DA403CE1
+:10132000E56445637010120904C3E53E1207694085
+:101330003B1208958018E53EC39538401D853E3820
+:10134000E53E6005853F3980038539398F3A1207BC
+:10135000A8E53E120753E53FF022803BE564456374
+:10136000701112075F400512089E801F12073EE5AC
+:1013700041F022E53CC39538401D853C38E53C6092
+:1013800005853D3980038539398F3A1207A8E53C38
+:10139000120753E53DF02212079FE538120753E587
+:1013A00039F022E50DFEE5088E544405F555751516
+:1013B0000FF582120E7A1217A320310575150380DE
+:1013C0000375150BE50AC39401503812142020311F
+:1013D0000605150515800415151515E50AC39401B4
+:1013E0005021121420203104051580021515E50A3C
+:1013F000C39401500E120E771217A3203105051564
+:10140000120E77E515B408047F0180027F00E51510
+:10141000B407047E0180027E00EE4F6002057F2249
+:10142000855582855483E515F01217A32212072AE9
+:101430007583AE74FF120729E0541AF534E0C41323
+:101440005407F53524FE602424FE603C24047063B8
+:1014500075312DE508FD74B612079274BC90072211
+:1014600012079574901207B37492803C75313AE577
+:1014700008FD74BA12079274C09007221207B6745E
+:10148000C41207B374C88020753135E508FD74B8FF
+:1014900012079274BEFFED4407900722CFF0A3EF2E
+:1014A000F074C21207B374C6FFED4407A3CFF0A3D4
+:1014B000EFF022753401228E588F598C5A8D5B8A39
+:1014C0005C8B5D755E01E4F55F121EA585595ED3E8
+:1014D000E55E955BE55A12076B5057E55D455C701C
+:1014E0003012072A758392E55E1207297583C6E5D7
+:1014F0005E1207297583C8E55E120729758390E59A
+:101500005E1207297583C2E55E1207297583C480C0
+:1015100003120732E55EF0AF5F7E00AD5DAC5C129A
+:101520000444AF5E7E00AD5DAC5C120BD1055E0283
+:1015300014CFAB5DAA5CAD5BAC5AAF59AE58021B81
+:10154000FB8C5C8D5D8A5E8B5F756001E4F561F5F7
+:1015500062F563121EA58F60D3E560955DE55C12B0
+:10156000076B5061E55F455E702712072A7583B6E9
+:10157000E5601207297583B8E5601207297583BAFB
+:10158000E560F0AF617E00E56212087A120AFF8022
+:1015900019900724120735E56012072975838EE438
+:1015A0001207297401120729E4F0AF637E00AD5FD2
+:1015B000AC5E120444AF607E00AD5FAC5E12128B75
+:1015C00005600215582290114DE49390072EF012F9
+:1015D000081F7583AEE0541AF5347067EF4407F5C1
+:1015E000827583CEE0FF1313135407F536540FD3DF
+:1015F0009400400612142D121BA9E536540F24FE48
+:10160000600C14600C146019240370378010021EE3
+:1016100091121E9112072A7583CEE054EFF0021D3D
+:10162000AE121014E4F555121D850555E555C39409
+:101630000540F412072A7583CEE054C7120729E04B
+:101640004408F022E4F558F559AF08EF4407F58255
+:101650007583D0E0FDC4540FF55AEF4407F5827549
+:1016600083807401F0120821758382E545F0EF4410
+:1016700007F58275838A74FFF0121A4D12072A75D6
+:1016800083BCE054EF1207297583BEE054EF1207C4
+:10169000297583C0E054EF1207297583BCE044101C
+:1016A0001207297583BEE044101207297583C0E034
+:1016B0004410F0AF58E559120878020AFFE4F558D3
+:1016C0007D01F559AF35FEFC12091512072A758305
+:1016D000B674101207297583B87410120729758320
+:1016E000BA74101207297583BC7410120729758308
+:1016F000BE74101207297583C074101207297583F0
+:1017000090E41207297583C2E41207297583C4E4A3
+:10171000120729758392E41207297583C6E412071C
+:10172000297583C8E4F0AF58FEE55912087A020A19
+:10173000FFE5E230E46CE5E754C064407064E5091D
+:10174000C45430FEE50825E025E054C04EFEEF54B9
+:101750003F4EFDE52BAE2A7802C333CE33CED8F907
+:10176000F5828E83EDF0E52BAE2A7802C333CE33BB
+:10177000CED8F9FFF5828E83A3E5FEF08F828E83AB
+:10178000A3A3E5FDF08F828E83A3A3A3E5FCF0C3A2
+:10179000E52B94FAE52A94005008052BE52B7002FE
+:1017A000052A22E4FFE4F558F556F5577482FC1239
+:1017B0000E048C83E0F510547FF0E5104480120E87
+:1017C00098EDF07E0A120E047583A0E020E026DE7C
+:1017D000F40557E55770020556E5142401FDE4337E
+:1017E000FCD3E5579DE5569C40D9E50A942050026C
+:1017F000050A43E108C231120E047583A6E05512B2
+:1018000065127003D23122C23122900726E0FAA37A
+:10181000E0F5828A83E0F541E539C395414026E54C
+:10182000399541C39FEE12076B40047C0180027C16
+:1018300000E541643F60047B0180027B00EC5B605B
+:101840002905418028C3E5419539C39FEE12076BF6
+:1018500040047F0180027F00E54160047E01800238
+:101860007E00EF5E600415418003853941853A4072
+:1018700022E5E230E460E5E130E25BE50970047FF7
+:101880000180027F00E50870047E0180027E00EE88
+:101890005F604353F9F8E5E230E43BE5E130E22EE6
+:1018A00043FA0253FAFBE4F510909470E510F0E56A
+:1018B000E130E2E7909470E06510600343FA0405BC
+:1018C00010909470E510F070E612000680E153FA73
+:1018D000FD53FAFB80C0228F54120006E5E130E090
+:1018E000047F0180027F00E57ED3940540047E01E1
+:1018F00080027E00EE4F603D855411E5E220E1322A
+:1019000074CE121A0530E7047D0180027D008F82BB
+:101910008E83E030E6047F0180027F00EF5D70156A
+:101920001215C674CE121A0530E607E04480F04363
+:10193000F98012187122120E44E51625E025E024E4
+:10194000B0F582E4341AF583E493F50FE51625E04B
+:1019500025E024B1F582E4341AF583E493F50E1200
+:101960000E65F510E50F54F0120E1775838CEFF02D
+:10197000E50F30E00C120E04758386E04440F080E1
+:101980000A120E04758386E054BFF0120E9175831F
+:1019900082E50EF0227F05121731120E04120E336B
+:1019A0007402F0748EFE120E04120E0BEFF0751519
+:1019B00070120FF72034057515108003751550123D
+:1019C0000FF72034047410800274F02515F51512F9
+:1019D0000E21EFF0121091203417E5156430600CE1
+:1019E00074102515F515B48003E4F515120E21EFDA
+:1019F000F022F0E50B25E025E02482F582E43407AF
+:101A0000F583227488FEE5084407FFF5828E83E0A3
+:101A100022F0E5084407F58222F0E054C08F828E60
+:101A200083F022EF4407F582758386E05410D39447
+:101A30000022F0900715E004F0224406F582758339
+:101A40009EE022FEEF4407F5828E83E022E49007B9
+:101A50002AF0A3F012072A758382E0547F12072927
+:101A6000E04480F01210FC12081F7583A0E020E013
+:101A70001A90072BE004F0700690072AE004F0901B
+:101A8000072AE0B410E1A3E0B400DCEE44A6FCEFCA
+:101A90004407F5828C83E0F532EE44A8FEEF44075C
+:101AA000F5828E83E0F5332201201100042000909E
+:101AB00000200F9200210F9400220F9600230F9810
+:101AC00000240F9A00250F9C00260F9E00270FA0D0
+:101AD000012001A2012101A4012201A6012301A8E4
+:101AE000012401AA012501AC012601AE012701B0A4
+:101AF000012801B400280FB640280FB8612801CB97
+:101B0000EFCBCAEECA7F01E4FDEB4A7024E508F58D
+:101B10008274B6120829E508F58274B8120829E51E
+:101B200008F58274BA1208297E007C00120AFF8030
+:101B300012900726120735E541F090072412073569
+:101B4000E540F012072A75838EE41207297401120A
+:101B50000729E4F022E4F526F52753E1FEF52A757E
+:101B60002B01F5087F0112173130301C901AA9E4BF
+:101B700093F510901FF9E493F510900041E493F56C
+:101B800010901ECAE493F5107F02121731120F5401
+:101B90007F03121731120006E5E230E70912100048
+:101BA00030300312110002004712081F7583D0E085
+:101BB000C4540FFD7543017544FF1208AA7404F064
+:101BC000753B01ED14600C14600B14600F2403705E
+:101BD0000B800980001208A704F080061208A77481
+:101BE00004F0EE4482FEEF4407F5828E83E5451251
+:101BF00008BE758382E531F002114C8E608F611250
+:101C00001EA5E4FFCEEDCEEED39561E56012076B25
+:101C1000403974202EF582E43403F583E07003FF2D
+:101C200080261208E2FDC39F401ECFEDCFEB4A7025
+:101C30000B8D421208EEF5418E40800C1208E2F541
+:101C4000381208EEF5398E3A1E80BC22755801E52F
+:101C500035700C1207CCE0F54A1207D8E0F54CE5D8
+:101C600035B4040C1207E4E0F54A1207F0E0F54C35
+:101C7000E535B401047F0180027F00E535B402043C
+:101C80007E0180027E00EE4F600C1207FCE0F54AF8
+:101C9000120808E0F54C85414985404B22755B01EF
+:101CA000900724120735E0541FFFD3940250048F8D
+:101CB000588005EF24FEF558EFC394184005755978
+:101CC000188004EF04F55985435AAF587E00AD598A
+:101CD0007C00AB5B7A00121541AF5A7E0012180AE5
+:101CE000AF5B7E00021AFFE5E230E70E121003C27E
+:101CF000303030031210FF203328E5E730E70512BB
+:101D00000EA2800DE5FEC394205006120EA243F9E8
+:101D100008E5F230E70353F97FE5F15470D39400FE
+:101D200050D822120E04758380E4F0E508440712AF
+:101D30000DFD758384120E02758386120E02758363
+:101D40008CE054F3120E0375838E120E0275839489
+:101D5000E054FBF02212072A75838EE412072974DF
+:101D600001120729E41208BE75838CE04420120892
+:101D7000BEE054DFF07484850882F583E0547FF080
+:101D8000E04480F022755601E4FDF557AF35FEFCC6
+:101D9000120915121C9D121E7A121C4CAF577E00A0
+:101DA000AD567C00120444AF567E000211EE75560B
+:101DB00001E4FDF557AF35FEFC120915121C9D120A
+:101DC0001E7A121C4CAF577E00AD567C00120444A4
+:101DD000AF567E000211EEE4F516120E44FEE50841
+:101DE0004405FF120E658F828E83F00516E516C33B
+:101DF000941440E6E508120E2BE4F022E4F558F5C1
+:101E000059F55AFFFEAD58FC1209157F047E00AD4E
+:101E1000587C001209157F027E00AD587C00020933
+:101E200015E53C253EFCE5422400FBE433FAECC317
+:101E30009BEA12076B400B8C42E53D253FF5418F35
+:101E4000402212090B227484F5188508198519821D
+:101E5000851883E0547FF0E04480F0E04480F02275
+:101E6000EF4E700B12072A7583D2E054DFF0221276
+:101E7000072A7583D2E04420F02275580190072686
+:101E8000120735E0543FF541120732E0543FF54068
+:101E900022755602E4F557121DFCAF577E00AD5671
+:101EA0007C00020444E4F542F541F540F538F5398B
+:101EB000F53A22EF5407FFE5F954F84FF5F9227F80
+:101EC00001E4FE0F0EBEFFFB2201200001042000F2
+:101ED0000000000000000000000000000000000002
+:101EE00000000000000000000000000000000000F2
+:101EF00000000000000000000000000000000000E2
+:101F000000000000000000000000000000000000D1
+:101F100000000000000000000000000000000000C1
+:101F200000000000000000000000000000000000B1
+:101F300000000000000000000000000000000000A1
+:101F40000000000000000000000000000000000091
+:101F50000000000000000000000000000000000081
+:101F60000000000000000000000000000000000071
+:101F70000000000000000000000000000000000061
+:101F80000000000000000000000000000000000051
+:101F90000000000000000000000000000000000041
+:101FA0000000000000000000000000000000000031
+:101FB0000000000000000000000000000000000021
+:101FC0000000000000000000000000000000000011
+:101FD0000000000000000000000000000000000001
+:101FE00000000000000000000000000000000000F1
+:101FF000000000000000000001201100042000810A
+:00000001FF
diff --git a/firmware/qlogic/sd7220.fw.ihex b/firmware/qlogic/sd7220.fw.ihex
deleted file mode 100644 (file)
index a336363..0000000
+++ /dev/null
@@ -1,513 +0,0 @@
-:10000000020A29020A87E5E630E6047F0180027FC2
-:1000100000E5E230E4047E0180027E00EE5F6008CD
-:1000200053F9F7E4F5FE80087F0A121731120EA289
-:1000300075FC08E4F5FDE5E720E70343F908220035
-:1000400001201100042000755101E4F552F553F52B
-:1000500052F57E7F04020438C2360552E552D3942D
-:100060000C4005755201D23690070C7407F0A3744A
-:10007000FFF0E4F50CA3F0900714F0A3F0750B204B
-:10008000F509E4F508E508D39430400302040412AE
-:100090000006150BE50870047F0180027F00E5096A
-:1000A00070047E0180027E00EE5F6005121871D23E
-:1000B0003553E1F7E5084509FFE50B25E025E02488
-:1000C00083F582E43407F583EFF085E220E552D32F
-:1000D0009401400D1219F3E054A064407003020330
-:1000E000FB53F9F8909470E4F0E0F510AF09121E9C
-:1000F000B3AF08EF4408F582758380E0F529EF443B
-:1001000007121A3CF5225440D39400401EE52954AE
-:10011000F070211219F3E04480F0E52254306508B4
-:1001200070091219F3E054BFF080091219F37440FA
-:10013000F00203FB121A127583AE74FFF0AF087E53
-:1001400000EF4407F582E0FDE50B25E025E0248182
-:10015000F582E43407F583EDF090070EE004F0EF4C
-:100160004407F582758398E0F528121A23400C1293
-:1001700019F3E04401121A320203F6AF087E00744C
-:1001800080CDEFCD8D82F583E030E00A1219F3E0E7
-:100190004420F00203FB1219F3E054DFF0EE44AE0A
-:1001A000121A4330E4030203FB749E121A0520E086
-:1001B000030203FB8F828E83E020E0030203FB1225
-:1001C00019F3E04410F0E5E320E708E508121A3AD5
-:1001D0004404F0AF087E00EF121A3A20E2341219FC
-:1001E000F3E04408F0E5E430E6047D0180027D00A0
-:1001F000E57EC3940450047C0180027C00EC4D60D9
-:1002000005C2350203FBEE44D2121A434440F00209
-:1002100003FB1219F3E054F7F0121A127583D2E0BF
-:1002200054BFF0900714E004F0E57E7003757E0182
-:10023000AF087E00121A2340121219F3E044011293
-:1002400019F2E05402121A320203FB1219F3E044CD
-:10025000021219F2E054FEF0C235EE448A8F82F5A4
-:1002600083E0F517548F4440F07490FCE508440790
-:10027000FDF5828C83E0543F900702F0E054C08D7E
-:10028000828C83F07492121A05900703121A197463
-:1002900082121A05900704121A1974B4121A0590E2
-:1002A0000705121A197494FEE5084406121A0AF595
-:1002B0001030E004D2378002C237E510547F8F82BD
-:1002C0008E83F0304430121A035480D394004004DB
-:1002D000D2398002C2398F828E83E04480F0121AB4
-:1002E000035440D394004004D23A8002C23A8F8231
-:1002F0008E83E04440F07492FEE5084406121A0A28
-:1003000030E704D2388002C2388F828E83E0547F77
-:10031000F0121E46E4F50A20030280033043031264
-:1003200019952002028003304203120C8F303006F0
-:10033000121995120C8F120D471219F3E054FBF0AD
-:10034000E50AC39401404643E1081219F3E044046E
-:10035000F0E5E420E72A121A127583D2E05408D39C
-:10036000940040047F0180027F00E50AC3940140AD
-:10037000047E0180027E00EF5E6005121DD78017AB
-:10038000121A127583D2E04408F00203FB121A120B
-:100390007583D2E054F7F0121E467F0812173174AD
-:1003A0008EFE121A128E83E0F51054FEF0E5104412
-:1003B00001FFE508FDED4407F582EFF0E51054FE7E
-:1003C000FFED4407F582EF121A11758386E04410A1
-:1003D000121A11E04410F01219F3E054FD4401FF29
-:1003E0001219F3EF121A3230320CE5084408F58284
-:1003F0007583827405F0AF0B1218D774102508F5B9
-:10040000080200850509E509D3940750030200821C
-:10041000E57ED3940040047F0180027F00E57EC327
-:1004200094FA50047E0180027E00EE5F6002057E39
-:1004300030350B43E1017F0912173102005853E1B7
-:10044000FE0200588E6A8F6B8C6C8D6D756E017517
-:100450006F01757001E4F573F574F57590072FF071
-:10046000F53CF53EF546F547F53DF53FF56FE56F93
-:10047000700FE56B456A12072A758380743AF08025
-:100480000912072A758380741AF0E4F56EC3743F6D
-:10049000956EFF120865758382EFF0121A4D1208EF
-:1004A000C6E533F01208FA1208B140E1E56F700BAF
-:1004B00012072A7583807436F0800912072A758323
-:1004C000807416F0756E0112072A7583B4E56EF01C
-:1004D000121A4D743F256EF582E43400F583E5333E
-:1004E000F074BF256EF582E434001208B140D8E400
-:1004F000F570F546F547F56E1208FAF583E0FE1241
-:1005000008C6E07C002400FFEC3EFEAD3BD3EF9D2F
-:10051000EE9C50047B0180027B00E57070047A0140
-:1005200080027A00EB5A6006856E46757001D3EF43
-:100530009DEE9C50047F0180027F00E570B40104B1
-:100540007E0180027E00EF5E6003856E47056EE5EA
-:100550006E647F70A3E5466005E547B47E0385467B
-:1005600047E56F7008854676854777800EC3747FB0
-:100570009546F578C3747F9547F579E56F7037E553
-:10058000466547700C757301757401F53CF53D8047
-:1005900035E4F54EC3E5479546F53CC313F57125A3
-:1005A00046F572C3943F4005E4F53D8040C3743F77
-:1005B0009572F53D8037E5466547700F7573017597
-:1005C0007501F53EF53F754E018022E4F54EC3E519
-:1005D000479546F53EC313F5712546F572D3943F12
-:1005E0005005E4F53F8006E57224C1F53F056FE54F
-:1005F0006FC39402500302046EE56D456C70028077
-:1006000004E574457590072FF07F01E53E6004E531
-:100610003C7014E4F53CF53DF53EF53F1208D27010
-:1006200004F00206A4807AE53CC3953E4007E53C11
-:10063000953EFF8006C3E53E953CFFE576D3957970
-:10064000400585767A800385797AE577C395785079
-:100650000585777B800385787BE57BD3957A403071
-:10066000E57B957AF53CF53EC3E57B957A900719D5
-:10067000F0E53CC313F571257AF572C3943F40054C
-:10068000E4F53D801FC3743F9572F53DF53F80143E
-:10069000E4F53CF53E900719F01208D27003F080A3
-:1006A000037401F01208657583D0E0540FFEAD3C71
-:1006B00070027E07BE0F027E80EEFBEFD39B74803C
-:1006C000F898401FE4F53CF53E1208D27003F08024
-:1006D000127401F0E508FBEB4407F5827583D2E064
-:1006E0004410F0E508FBEB4409F58275839EEDF0BC
-:1006F000EB4407F5827583CAEDF01208657583CC6B
-:10070000EFF022E5084407F5827583BCE054F0F071
-:10071000E5084407F5827583BEE054F0F0E508442F
-:1007200007F5827583C0E054F0F0E5084407F582D0
-:1007300022F0900728E0FEA3E0F5828E8322854216
-:100740004285414185404074C02FF58274023EF5D8
-:1007500083E542F074E02FF58274023EF58322E5D2
-:100760004229FDE433FCE53CC39DEC6480F87480D1
-:100770009822F583E0900722541FFDE0FAA3E0F5EC
-:10078000828A83EDF022900722E0FCA3E0F5828CC0
-:100790008322900724FFED4407CFF0A3EFF02285DA
-:1007A0003838853939853A3A74C02FF58274023E5B
-:1007B000F58322900726FFED4407CFF0A3EFF02248
-:1007C000F074A02FF58274023EF5832274C02511C7
-:1007D000F582E43401F5832274002511F582E434B6
-:1007E00002F5832274602511F582E43403F5832237
-:1007F00074802511F582E43403F5832274E0251119
-:10080000F582E43403F5832274402511F582E43443
-:1008100006F5832274802FF58274023EF58322AFA1
-:10082000087E00EF4407F58222F583E5824407F550
-:1008300082E540F02274402511F582E43402F5830C
-:100840002274C02511F582E43403F5832274002557
-:1008500011F582E43406F5832274202511F582E433
-:100860003406F58322E508FDED4407F58222E541D3
-:10087000F0E56564014564227E00FB7A00FD7C00A2
-:100880002274202511F582E434022274A02511F58A
-:1008900082E4340322853E42853F418F4022853CDD
-:1008A00042853D418F402275453F900720E4F0A3EB
-:1008B00022F583E532F0056EE56EC3944022F0E543
-:1008C000084406F582227400256EF582E43400F5B2
-:1008D0008322E56D456C90072F22E4F9E53CD39522
-:1008E0003E2274802EF582E43402F583E02274A067
-:1008F0002EF582E43402F583E0227480256EF582C1
-:10090000E43400222542FDE433FC22854242854145
-:100910004185404022ED4C60030209E5EF4E7037FF
-:10092000900726120789E0FD1207CCEDF09007280A
-:10093000120789E0FD1207D8EDF0120786E0541F78
-:10094000FD120881F583EDF0900724120789E05429
-:100950001FFD120835EDF0EF64044E703790072646
-:10096000120789E0FD1207E4EDF0900728120789CD
-:10097000E0FD1207F0EDF0120786E0541FFD1208AB
-:100980008BF583EDF0900724120789E0541FFD12C8
-:100990000841EDF0EF64014E70047D0180027D009E
-:1009A000EF64024E70047F0180027F00EF4D60789B
-:1009B000900726120735E0FF1207FCEF120731E01F
-:1009C000FF120808EFF0900722120735E0541FFFCE
-:1009D00012084DEFF0900724120735E0541FFF1264
-:1009E0000859EFF0221207CCE4F01207D8E4F01215
-:1009F0000881F583E4F01208357414F01207E4E47A
-:100A0000F01207F0E4F012088BF583E4F0120841CD
-:100A10007414F01207FCE4F0120808E4F012084D18
-:100A2000E4F01208597414F02253F9F775FC10E43D
-:100A3000F5FD75FE30F5FFE5E720E70343F908E52E
-:100A4000E620E70B78FFE4F6D8FD53E6FE80097850
-:100A500008E4F6D8FD53E6FE758180E4F5A8D2A837
-:100A6000C2A9D2AFE5E220E50520E602800343E11A
-:100A700002E5E220E00E9000007F007E08E4F0A393
-:100A8000DFFCDEFA020ADB43FA01C0E0C0F0C083FB
-:100A9000C082C0D0121CE7D0D0D082D083D0F0D09A
-:100AA000E053FAFE32021B55E493A3F8E493A3F655
-:100AB00008DFF98029E493A3F85407240CC8C33352
-:100AC000C4540F4420C8834004F456800146F6DF26
-:100AD000E4800B010204081020408090003FE47E77
-:100AE000019360C1A3FF543F30E509541FFEE49316
-:100AF000A360010ECF54C025E060AD40B880FE8CED
-:100B0000648D658A668B67E4F569EF4E7003021D9C
-:100B100055E4F568E5674566703212072A758390DB
-:100B2000E41207297583C2E41207297583C4E4120D
-:100B30000870702912072A758392E41207297583B9
-:100B4000C6E41207297583C8E4F0801190072612C5
-:100B50000735E41208707005120732E4F0121D55D3
-:100B6000121EBFE5674566703312072A758390E54C
-:100B7000411207297583C2E5411207297583C41202
-:100B8000086E702912072A758392E54012072975AD
-:100B900083C6E5401207297583C8800E9007261288
-:100BA000073512086E7006120732E540F0AF697E15
-:100BB00000AD67AC6612044412072A7583CAE0D3FD
-:100BC0009400500C0568E568C394055003020B14AB
-:100BD000228C608D611208DA7420400D2FF582742A
-:100BE000033EF583E53EF0800B2FF58274033EF55E
-:100BF00083E53CF0E53CD3953E403CE561456070C3
-:100C000010E9120904E53E120768403B120895807E
-:100C100018E53EC39538401D853E38E53E600585A4
-:100C20003F3980038539398F3A120814E53E12079F
-:100C3000C0E53FF0228043E5614560701912075F0F
-:100C4000400512089E802712090B120814E5421273
-:100C500007C0E541F022E53CC39538401D853C388E
-:100C6000E53C6005853D3980038539398F3A1208A6
-:100C700014E53C1207C0E53DF02285383885393946
-:100C8000853A3A120814E5381207C0E539F0227F98
-:100C900006121731121D23120E04120E33E0440AFD
-:100CA000F0748EFE120E04120E0BEFF0E52830E504
-:100CB00003D38001C3400575142080037514081206
-:100CC0000E0475838AE514F0B4FF05751280800662
-:100CD000E514C313F512E4F516F57F121936121355
-:100CE000A3E50AC3940150090516E516C394144000
-:100CF000EAE5E420E728120E047583D2E05408D315
-:100D0000940040047F0180027F00E50AC394014003
-:100D1000047E0180027E00EF5E6003121DD7E57F36
-:100D2000C394114014120E047583D2E04480F0E5A0
-:100D3000E420E70F121DD7800A120E047583D2E05B
-:100D4000547FF0121D2322748A850882F583E517EB
-:100D5000F0120E3AE4F0900702E0120E177583903D
-:100D6000EFF07492FEE5084407FFF5828E83E054AD
-:100D7000C0FD900703E0543F4D8F828E83F09007B3
-:100D800004E0120E17758382EFF0900705E0FFED87
-:100D90004407F5827583B4EF120E03758380E05427
-:100DA000BFF030370A120E91758394E04480F03022
-:100DB000380A120E91758392E04480F0E52830E401
-:100DC0001A20390A120E04758388E0547FF0203A05
-:100DD0000A120E04758388E054BFF0748CFE120E64
-:100DE000048E83E0540F120E03758386E054BFF027
-:100DF000E5084406120DFD75838AE4F022F582753C
-:100E00008382E4F0E5084407F582228E83E0F51042
-:100E100054FEF0E5104401FFE508FDED4407F582BE
-:100E200022E515C45407FFE508FDED4408F5827579
-:100E3000838222758380E04440F0E5084408F5820F
-:100E400075838A22E51625E025E024AFF582E43497
-:100E50001AF583E493F50D2243E11043E18053E159
-:100E6000FD85E11022E51625E025E024B2F582E4B7
-:100E7000341AF583E49322855582855483E515F071
-:100E800022E5E25420D3940022E5E25440D39400BA
-:100E900022E5084406F58222FDE508FBEB4407F550
-:100EA000822253F9F775FE3022EF4E70261207CCDE
-:100EB000E0FD90072612077B1207D8E0FD90072877
-:100EC00012077B120881120772120835E09007247E
-:100ED000120778EF64044E70291207E4E0FD9007D2
-:100EE0002612077B1207F0E0FD90072812077B12FD
-:100EF000088B120772120841E0541FFD900724125C
-:100F0000077BEF64014E70047D0180027D00EF6479
-:100F1000024E70047F0180027F00EF4D60351207A2
-:100F2000FCE0FF900726120789EFF0120808E0FFA7
-:100F3000900728120789EFF012084DE0541FFF12A6
-:100F40000786EFF0120859E0541FFF90072412079C
-:100F500089EFF022E4F553120E8140047F018002F4
-:100F60007F00120E8940047E0180027E00EE4F70E9
-:100F700003020FF685E11043E10253E10F85E11012
-:100F8000E4F551E5E3543FF552120E89401DAD5290
-:100F9000AF51121118EF600885E11043E140800B5A
-:100FA00053E1BF120E5812000680FBE5E3543FF5F3
-:100FB00051E5E4543FF552120E81401DAD52AF5140
-:100FC000121118EF600885E11043E120800B53E116
-:100FD000DF120E5812000680FB120E8140047F01C2
-:100FE00080027F00120E8940047E0180027E00EEA6
-:100FF0004F6003120E5B22120E21EFF012109122AD
-:1010000002110002104002109000000000000000D9
-:1010100001200120E4F5571216BD121644E4121007
-:10102000561214B7900726120735E4120731E4F080
-:101030001210561214B7900726120735E541120711
-:1010400031E540F0AF577E00AD567C00120444AF4E
-:10105000567E000211EEFF900720A3E0FDE4F55656
-:10106000F540FEFCAB56FA1211517F0F7D18E4F5E6
-:1010700056F540FEFCAB56FA121541AF567E0012F3
-:101080001AFFE4FFF5567D1FF540FEFCAB56FA2231
-:1010900022E4F555E508FD74A0F556ED4407F55733
-:1010A000E52830E503D38001C340057F28EF8004A5
-:1010B0007F14EFC313F554E4F9120E1875838EE014
-:1010C000F510CEEFCEEED394004026E51054FE127C
-:1010D0000E9875838EEDF0E5104401FDEB4407F5A5
-:1010E00082EDF0855782855683E030E301091E804A
-:1010F000D4C234E9C395544002D2342202000622FD
-:10110000303011901000E493F510901010E493F536
-:101110001012109012115022E4FCC3ED9FFAEFF56B
-:101120008375820079FFE493CC6CCCA3D9F8DAF60E
-:10113000E5E230E4028CE5ED24FFFFEF7582FFF578
-:1011400083E4936C70037F01227F00222211000050
-:10115000228E588F598C5A8D5B8A5C8B5D755E012F
-:10116000E4F55FF560F56212072A7583D0E0FFC4ED
-:10117000540FF561121EA585595ED3E55E955BE5BA
-:101180005A12076B504B1207037583BCE0455E1281
-:1011900007297583BEE0455E1207297583C0E045C7
-:1011A0005EF0AF5FE560120878120AFFAF627E0062
-:1011B000AD5DAC5C120444E561AF5E7E00B4030536
-:1011C000121E218007AD5DAC5C121317055E021183
-:1011D0007A1207037583BCE045401207297583BE68
-:1011E000E045401207297583C0E04540F0228E5843
-:1011F0008F59755A017901755B01E4FB12072A7555
-:1012000083AEE0541AFF120865E0C4135407FEEFE2
-:10121000700CEE6535700790072FE0B4010DAF3507
-:101220007E00120EA9CFEBCF021E60E55964024585
-:101230005870047F0180027F00E559455870047E94
-:101240000180027E00EE4F602385414985404BE5D9
-:10125000594558702CAF5AFECDE9CDFCAB59AA5870
-:10126000120AFFAF5B7E00121E608015AF5B7E002E
-:10127000121E60900726120735E549120731E54B2B
-:10128000F0E4FDAF35FEFC120915228C648D651269
-:1012900008DA403CE56545647010120904C3E53E78
-:1012A000120769403B1208958018E53EC395384007
-:1012B0001D853E38E53E6005853F39800385393917
-:1012C0008F3A1207A8E53E120753E53FF022803B14
-:1012D000E5654564701112075F400512089E801F86
-:1012E00012073EE541F022E53CC39538401D853CA0
-:1012F00038E53C6005853D3980038539398F3A12E0
-:1013000007A8E53C120753E53DF02212079FE53898
-:10131000120753E539F0228C638D641208DA403CE1
-:10132000E56445637010120904C3E53E1207694085
-:101330003B1208958018E53EC39538401D853E3820
-:10134000E53E6005853F3980038539398F3A1207BC
-:10135000A8E53E120753E53FF022803BE564456374
-:10136000701112075F400512089E801F12073EE5AC
-:1013700041F022E53CC39538401D853C38E53C6092
-:1013800005853D3980038539398F3A1207A8E53C38
-:10139000120753E53DF02212079FE538120753E587
-:1013A00039F022E50DFEE5088E544405F555751516
-:1013B0000FF582120E7A1217A320310575150380DE
-:1013C0000375150BE50AC39401503812142020311F
-:1013D0000605150515800415151515E50AC39401B4
-:1013E0005021121420203104051580021515E50A3C
-:1013F000C39401500E120E771217A3203105051564
-:10140000120E77E515B408047F0180027F00E51510
-:10141000B407047E0180027E00EE4F6002057F2249
-:10142000855582855483E515F01217A32212072AE9
-:101430007583AE74FF120729E0541AF534E0C41323
-:101440005407F53524FE602424FE603C24047063B8
-:1014500075312DE508FD74B612079274BC90072211
-:1014600012079574901207B37492803C75313AE577
-:1014700008FD74BA12079274C09007221207B6745E
-:10148000C41207B374C88020753135E508FD74B8FF
-:1014900012079274BEFFED4407900722CFF0A3EF2E
-:1014A000F074C21207B374C6FFED4407A3CFF0A3D4
-:1014B000EFF022753401228E588F598C5A8D5B8A39
-:1014C0005C8B5D755E01E4F55F121EA585595ED3E8
-:1014D000E55E955BE55A12076B5057E55D455C701C
-:1014E0003012072A758392E55E1207297583C6E5D7
-:1014F0005E1207297583C8E55E120729758390E59A
-:101500005E1207297583C2E55E1207297583C480C0
-:1015100003120732E55EF0AF5F7E00AD5DAC5C129A
-:101520000444AF5E7E00AD5DAC5C120BD1055E0283
-:1015300014CFAB5DAA5CAD5BAC5AAF59AE58021B81
-:10154000FB8C5C8D5D8A5E8B5F756001E4F561F5F7
-:1015500062F563121EA58F60D3E560955DE55C12B0
-:10156000076B5061E55F455E702712072A7583B6E9
-:10157000E5601207297583B8E5601207297583BAFB
-:10158000E560F0AF617E00E56212087A120AFF8022
-:1015900019900724120735E56012072975838EE438
-:1015A0001207297401120729E4F0AF637E00AD5FD2
-:1015B000AC5E120444AF607E00AD5FAC5E12128B75
-:1015C00005600215582290114DE49390072EF012F9
-:1015D000081F7583AEE0541AF5347067EF4407F5C1
-:1015E000827583CEE0FF1313135407F536540FD3DF
-:1015F0009400400612142D121BA9E536540F24FE48
-:10160000600C14600C146019240370378010021EE3
-:1016100091121E9112072A7583CEE054EFF0021D3D
-:10162000AE121014E4F555121D850555E555C39409
-:101630000540F412072A7583CEE054C7120729E04B
-:101640004408F022E4F558F559AF08EF4407F58255
-:101650007583D0E0FDC4540FF55AEF4407F5827549
-:1016600083807401F0120821758382E545F0EF4410
-:1016700007F58275838A74FFF0121A4D12072A75D6
-:1016800083BCE054EF1207297583BEE054EF1207C4
-:10169000297583C0E054EF1207297583BCE044101C
-:1016A0001207297583BEE044101207297583C0E034
-:1016B0004410F0AF58E559120878020AFFE4F558D3
-:1016C0007D01F559AF35FEFC12091512072A758305
-:1016D000B674101207297583B87410120729758320
-:1016E000BA74101207297583BC7410120729758308
-:1016F000BE74101207297583C074101207297583F0
-:1017000090E41207297583C2E41207297583C4E4A3
-:10171000120729758392E41207297583C6E412071C
-:10172000297583C8E4F0AF58FEE55912087A020A19
-:10173000FFE5E230E46CE5E754C064407064E5091D
-:10174000C45430FEE50825E025E054C04EFEEF54B9
-:101750003F4EFDE52BAE2A7802C333CE33CED8F907
-:10176000F5828E83EDF0E52BAE2A7802C333CE33BB
-:10177000CED8F9FFF5828E83A3E5FEF08F828E83AB
-:10178000A3A3E5FDF08F828E83A3A3A3E5FCF0C3A2
-:10179000E52B94FAE52A94005008052BE52B7002FE
-:1017A000052A22E4FFE4F558F556F5577482FC1239
-:1017B0000E048C83E0F510547FF0E5104480120E87
-:1017C00098EDF07E0A120E047583A0E020E026DE7C
-:1017D000F40557E55770020556E5142401FDE4337E
-:1017E000FCD3E5579DE5569C40D9E50A942050026C
-:1017F000050A43E108C231120E047583A6E05512B2
-:1018000065127003D23122C23122900726E0FAA37A
-:10181000E0F5828A83E0F541E539C395414026E54C
-:10182000399541C39FEE12076B40047C0180027C16
-:1018300000E541643F60047B0180027B00EC5B605B
-:101840002905418028C3E5419539C39FEE12076BF6
-:1018500040047F0180027F00E54160047E01800238
-:101860007E00EF5E600415418003853941853A4072
-:1018700022E5E230E460E5E130E25BE50970047FF7
-:101880000180027F00E50870047E0180027E00EE88
-:101890005F604353F9F8E5E230E43BE5E130E22EE6
-:1018A00043FA0253FAFBE4F510909470E510F0E56A
-:1018B000E130E2E7909470E06510600343FA0405BC
-:1018C00010909470E510F070E612000680E153FA73
-:1018D000FD53FAFB80C0228F54120006E5E130E090
-:1018E000047F0180027F00E57ED3940540047E01E1
-:1018F00080027E00EE4F603D855411E5E220E1322A
-:1019000074CE121A0530E7047D0180027D008F82BB
-:101910008E83E030E6047F0180027F00EF5D70156A
-:101920001215C674CE121A0530E607E04480F04363
-:10193000F98012187122120E44E51625E025E024E4
-:10194000B0F582E4341AF583E493F50FE51625E04B
-:1019500025E024B1F582E4341AF583E493F50E1200
-:101960000E65F510E50F54F0120E1775838CEFF02D
-:10197000E50F30E00C120E04758386E04440F080E1
-:101980000A120E04758386E054BFF0120E9175831F
-:1019900082E50EF0227F05121731120E04120E336B
-:1019A0007402F0748EFE120E04120E0BEFF0751519
-:1019B00070120FF72034057515108003751550123D
-:1019C0000FF72034047410800274F02515F51512F9
-:1019D0000E21EFF0121091203417E5156430600CE1
-:1019E00074102515F515B48003E4F515120E21EFDA
-:1019F000F022F0E50B25E025E02482F582E43407AF
-:101A0000F583227488FEE5084407FFF5828E83E0A3
-:101A100022F0E5084407F58222F0E054C08F828E60
-:101A200083F022EF4407F582758386E05410D39447
-:101A30000022F0900715E004F0224406F582758339
-:101A40009EE022FEEF4407F5828E83E022E49007B9
-:101A50002AF0A3F012072A758382E0547F12072927
-:101A6000E04480F01210FC12081F7583A0E020E013
-:101A70001A90072BE004F0700690072AE004F0901B
-:101A8000072AE0B410E1A3E0B400DCEE44A6FCEFCA
-:101A90004407F5828C83E0F532EE44A8FEEF44075C
-:101AA000F5828E83E0F5332201201100042000909E
-:101AB00000200F9200210F9400220F9600230F9810
-:101AC00000240F9A00250F9C00260F9E00270FA0D0
-:101AD000012001A2012101A4012201A6012301A8E4
-:101AE000012401AA012501AC012601AE012701B0A4
-:101AF000012801B400280FB640280FB8612801CB97
-:101B0000EFCBCAEECA7F01E4FDEB4A7024E508F58D
-:101B10008274B6120829E508F58274B8120829E51E
-:101B200008F58274BA1208297E007C00120AFF8030
-:101B300012900726120735E541F090072412073569
-:101B4000E540F012072A75838EE41207297401120A
-:101B50000729E4F022E4F526F52753E1FEF52A757E
-:101B60002B01F5087F0112173130301C901AA9E4BF
-:101B700093F510901FF9E493F510900041E493F56C
-:101B800010901ECAE493F5107F02121731120F5401
-:101B90007F03121731120006E5E230E70912100048
-:101BA00030300312110002004712081F7583D0E085
-:101BB000C4540FFD7543017544FF1208AA7404F064
-:101BC000753B01ED14600C14600B14600F2403705E
-:101BD0000B800980001208A704F080061208A77481
-:101BE00004F0EE4482FEEF4407F5828E83E5451251
-:101BF00008BE758382E531F002114C8E608F611250
-:101C00001EA5E4FFCEEDCEEED39561E56012076B25
-:101C1000403974202EF582E43403F583E07003FF2D
-:101C200080261208E2FDC39F401ECFEDCFEB4A7025
-:101C30000B8D421208EEF5418E40800C1208E2F541
-:101C4000381208EEF5398E3A1E80BC22755801E52F
-:101C500035700C1207CCE0F54A1207D8E0F54CE5D8
-:101C600035B4040C1207E4E0F54A1207F0E0F54C35
-:101C7000E535B401047F0180027F00E535B402043C
-:101C80007E0180027E00EE4F600C1207FCE0F54AF8
-:101C9000120808E0F54C85414985404B22755B01EF
-:101CA000900724120735E0541FFFD3940250048F8D
-:101CB000588005EF24FEF558EFC394184005755978
-:101CC000188004EF04F55985435AAF587E00AD598A
-:101CD0007C00AB5B7A00121541AF5A7E0012180AE5
-:101CE000AF5B7E00021AFFE5E230E70E121003C27E
-:101CF000303030031210FF203328E5E730E70512BB
-:101D00000EA2800DE5FEC394205006120EA243F9E8
-:101D100008E5F230E70353F97FE5F15470D39400FE
-:101D200050D822120E04758380E4F0E508440712AF
-:101D30000DFD758384120E02758386120E02758363
-:101D40008CE054F3120E0375838E120E0275839489
-:101D5000E054FBF02212072A75838EE412072974DF
-:101D600001120729E41208BE75838CE04420120892
-:101D7000BEE054DFF07484850882F583E0547FF080
-:101D8000E04480F022755601E4FDF557AF35FEFCC6
-:101D9000120915121C9D121E7A121C4CAF577E00A0
-:101DA000AD567C00120444AF567E000211EE75560B
-:101DB00001E4FDF557AF35FEFC120915121C9D120A
-:101DC0001E7A121C4CAF577E00AD567C00120444A4
-:101DD000AF567E000211EEE4F516120E44FEE50841
-:101DE0004405FF120E658F828E83F00516E516C33B
-:101DF000941440E6E508120E2BE4F022E4F558F5C1
-:101E000059F55AFFFEAD58FC1209157F047E00AD4E
-:101E1000587C001209157F027E00AD587C00020933
-:101E200015E53C253EFCE5422400FBE433FAECC317
-:101E30009BEA12076B400B8C42E53D253FF5418F35
-:101E4000402212090B227484F5188508198519821D
-:101E5000851883E0547FF0E04480F0E04480F02275
-:101E6000EF4E700B12072A7583D2E054DFF0221276
-:101E7000072A7583D2E04420F02275580190072686
-:101E8000120735E0543FF541120732E0543FF54068
-:101E900022755602E4F557121DFCAF577E00AD5671
-:101EA0007C00020444E4F542F541F540F538F5398B
-:101EB000F53A22EF5407FFE5F954F84FF5F9227F80
-:101EC00001E4FE0F0EBEFFFB2201200001042000F2
-:101ED0000000000000000000000000000000000002
-:101EE00000000000000000000000000000000000F2
-:101EF00000000000000000000000000000000000E2
-:101F000000000000000000000000000000000000D1
-:101F100000000000000000000000000000000000C1
-:101F200000000000000000000000000000000000B1
-:101F300000000000000000000000000000000000A1
-:101F40000000000000000000000000000000000091
-:101F50000000000000000000000000000000000081
-:101F60000000000000000000000000000000000071
-:101F70000000000000000000000000000000000061
-:101F80000000000000000000000000000000000051
-:101F90000000000000000000000000000000000041
-:101FA0000000000000000000000000000000000031
-:101FB0000000000000000000000000000000000021
-:101FC0000000000000000000000000000000000011
-:101FD0000000000000000000000000000000000001
-:101FE00000000000000000000000000000000000F1
-:101FF000000000000000000001201100042000810A
-:00000001FF
index ecd25a1b4e519562ff874112515052403877fbc4..ca9d8f1a3bb67968dab36b8df98c0c2093a2300f 100644 (file)
@@ -651,6 +651,8 @@ tree_mod_log_insert_root(struct btrfs_fs_info *fs_info,
        if (tree_mod_dont_log(fs_info, NULL))
                return 0;
 
+       __tree_mod_log_free_eb(fs_info, old_root);
+
        ret = tree_mod_alloc(fs_info, flags, &tm);
        if (ret < 0)
                goto out;
@@ -736,7 +738,7 @@ tree_mod_log_search(struct btrfs_fs_info *fs_info, u64 start, u64 min_seq)
 static noinline void
 tree_mod_log_eb_copy(struct btrfs_fs_info *fs_info, struct extent_buffer *dst,
                     struct extent_buffer *src, unsigned long dst_offset,
-                    unsigned long src_offset, int nr_items)
+                    unsigned long src_offset, int nr_items, int log_removal)
 {
        int ret;
        int i;
@@ -750,10 +752,12 @@ tree_mod_log_eb_copy(struct btrfs_fs_info *fs_info, struct extent_buffer *dst,
        }
 
        for (i = 0; i < nr_items; i++) {
-               ret = tree_mod_log_insert_key_locked(fs_info, src,
-                                                    i + src_offset,
-                                                    MOD_LOG_KEY_REMOVE);
-               BUG_ON(ret < 0);
+               if (log_removal) {
+                       ret = tree_mod_log_insert_key_locked(fs_info, src,
+                                                       i + src_offset,
+                                                       MOD_LOG_KEY_REMOVE);
+                       BUG_ON(ret < 0);
+               }
                ret = tree_mod_log_insert_key_locked(fs_info, dst,
                                                     i + dst_offset,
                                                     MOD_LOG_KEY_ADD);
@@ -927,7 +931,6 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
                        ret = btrfs_dec_ref(trans, root, buf, 1, 1);
                        BUG_ON(ret); /* -ENOMEM */
                }
-               tree_mod_log_free_eb(root->fs_info, buf);
                clean_tree_block(trans, root, buf);
                *last_ref = 1;
        }
@@ -1046,6 +1049,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
                btrfs_set_node_ptr_generation(parent, parent_slot,
                                              trans->transid);
                btrfs_mark_buffer_dirty(parent);
+               tree_mod_log_free_eb(root->fs_info, buf);
                btrfs_free_tree_block(trans, root, buf, parent_start,
                                      last_ref);
        }
@@ -1750,7 +1754,6 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
                        goto enospc;
                }
 
-               tree_mod_log_free_eb(root->fs_info, root->node);
                tree_mod_log_set_root_pointer(root, child);
                rcu_assign_pointer(root->node, child);
 
@@ -2995,7 +2998,7 @@ static int push_node_left(struct btrfs_trans_handle *trans,
                push_items = min(src_nritems - 8, push_items);
 
        tree_mod_log_eb_copy(root->fs_info, dst, src, dst_nritems, 0,
-                            push_items);
+                            push_items, 1);
        copy_extent_buffer(dst, src,
                           btrfs_node_key_ptr_offset(dst_nritems),
                           btrfs_node_key_ptr_offset(0),
@@ -3066,7 +3069,7 @@ static int balance_node_right(struct btrfs_trans_handle *trans,
                                      sizeof(struct btrfs_key_ptr));
 
        tree_mod_log_eb_copy(root->fs_info, dst, src, 0,
-                            src_nritems - push_items, push_items);
+                            src_nritems - push_items, push_items, 1);
        copy_extent_buffer(dst, src,
                           btrfs_node_key_ptr_offset(0),
                           btrfs_node_key_ptr_offset(src_nritems - push_items),
@@ -3218,12 +3221,18 @@ static noinline int split_node(struct btrfs_trans_handle *trans,
        int mid;
        int ret;
        u32 c_nritems;
+       int tree_mod_log_removal = 1;
 
        c = path->nodes[level];
        WARN_ON(btrfs_header_generation(c) != trans->transid);
        if (c == root->node) {
                /* trying to split the root, lets make a new one */
                ret = insert_new_root(trans, root, path, level + 1);
+               /*
+                * removal of root nodes has been logged by
+                * tree_mod_log_set_root_pointer due to locking
+                */
+               tree_mod_log_removal = 0;
                if (ret)
                        return ret;
        } else {
@@ -3261,7 +3270,8 @@ static noinline int split_node(struct btrfs_trans_handle *trans,
                            (unsigned long)btrfs_header_chunk_tree_uuid(split),
                            BTRFS_UUID_SIZE);
 
-       tree_mod_log_eb_copy(root->fs_info, split, c, 0, mid, c_nritems - mid);
+       tree_mod_log_eb_copy(root->fs_info, split, c, 0, mid, c_nritems - mid,
+                            tree_mod_log_removal);
        copy_extent_buffer(split, c,
                           btrfs_node_key_ptr_offset(0),
                           btrfs_node_key_ptr_offset(mid),
index 7d84651e850b22cb937b29c68d34c1119af1e4a0..6d19a0a554aadc3aeadbe1df6eff03acd489375e 100644 (file)
@@ -1291,6 +1291,7 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
                                      0, objectid, NULL, 0, 0, 0);
        if (IS_ERR(leaf)) {
                ret = PTR_ERR(leaf);
+               leaf = NULL;
                goto fail;
        }
 
@@ -1334,11 +1335,16 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
 
        btrfs_tree_unlock(leaf);
 
+       return root;
+
 fail:
-       if (ret)
-               return ERR_PTR(ret);
+       if (leaf) {
+               btrfs_tree_unlock(leaf);
+               free_extent_buffer(leaf);
+       }
+       kfree(root);
 
-       return root;
+       return ERR_PTR(ret);
 }
 
 static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans,
@@ -3253,7 +3259,7 @@ void btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root)
        if (btrfs_root_refs(&root->root_item) == 0)
                synchronize_srcu(&fs_info->subvol_srcu);
 
-       if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) {
+       if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) {
                btrfs_free_log(NULL, root);
                btrfs_free_log_root_tree(NULL, fs_info);
        }
index 9ac2eca681ebb09c605612dd563bc4417e4fc587..3d551231cabae9e43c7a1e90385f22fd25891239 100644 (file)
@@ -257,7 +257,8 @@ static int exclude_super_stripes(struct btrfs_root *root,
                cache->bytes_super += stripe_len;
                ret = add_excluded_extent(root, cache->key.objectid,
                                          stripe_len);
-               BUG_ON(ret); /* -ENOMEM */
+               if (ret)
+                       return ret;
        }
 
        for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) {
@@ -265,13 +266,17 @@ static int exclude_super_stripes(struct btrfs_root *root,
                ret = btrfs_rmap_block(&root->fs_info->mapping_tree,
                                       cache->key.objectid, bytenr,
                                       0, &logical, &nr, &stripe_len);
-               BUG_ON(ret); /* -ENOMEM */
+               if (ret)
+                       return ret;
 
                while (nr--) {
                        cache->bytes_super += stripe_len;
                        ret = add_excluded_extent(root, logical[nr],
                                                  stripe_len);
-                       BUG_ON(ret); /* -ENOMEM */
+                       if (ret) {
+                               kfree(logical);
+                               return ret;
+                       }
                }
 
                kfree(logical);
@@ -4438,7 +4443,7 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info)
        spin_lock(&sinfo->lock);
        spin_lock(&block_rsv->lock);
 
-       block_rsv->size = num_bytes;
+       block_rsv->size = min_t(u64, num_bytes, 512 * 1024 * 1024);
 
        num_bytes = sinfo->bytes_used + sinfo->bytes_pinned +
                    sinfo->bytes_reserved + sinfo->bytes_readonly +
@@ -4793,14 +4798,49 @@ out_fail:
         * If the inodes csum_bytes is the same as the original
         * csum_bytes then we know we haven't raced with any free()ers
         * so we can just reduce our inodes csum bytes and carry on.
-        * Otherwise we have to do the normal free thing to account for
-        * the case that the free side didn't free up its reserve
-        * because of this outstanding reservation.
         */
-       if (BTRFS_I(inode)->csum_bytes == csum_bytes)
+       if (BTRFS_I(inode)->csum_bytes == csum_bytes) {
                calc_csum_metadata_size(inode, num_bytes, 0);
-       else
-               to_free = calc_csum_metadata_size(inode, num_bytes, 0);
+       } else {
+               u64 orig_csum_bytes = BTRFS_I(inode)->csum_bytes;
+               u64 bytes;
+
+               /*
+                * This is tricky, but first we need to figure out how much we
+                * free'd from any free-ers that occured during this
+                * reservation, so we reset ->csum_bytes to the csum_bytes
+                * before we dropped our lock, and then call the free for the
+                * number of bytes that were freed while we were trying our
+                * reservation.
+                */
+               bytes = csum_bytes - BTRFS_I(inode)->csum_bytes;
+               BTRFS_I(inode)->csum_bytes = csum_bytes;
+               to_free = calc_csum_metadata_size(inode, bytes, 0);
+
+
+               /*
+                * Now we need to see how much we would have freed had we not
+                * been making this reservation and our ->csum_bytes were not
+                * artificially inflated.
+                */
+               BTRFS_I(inode)->csum_bytes = csum_bytes - num_bytes;
+               bytes = csum_bytes - orig_csum_bytes;
+               bytes = calc_csum_metadata_size(inode, bytes, 0);
+
+               /*
+                * Now reset ->csum_bytes to what it should be.  If bytes is
+                * more than to_free then we would have free'd more space had we
+                * not had an artificially high ->csum_bytes, so we need to free
+                * the remainder.  If bytes is the same or less then we don't
+                * need to do anything, the other free-ers did the correct
+                * thing.
+                */
+               BTRFS_I(inode)->csum_bytes = orig_csum_bytes - num_bytes;
+               if (bytes > to_free)
+                       to_free = bytes - to_free;
+               else
+                       to_free = 0;
+       }
        spin_unlock(&BTRFS_I(inode)->lock);
        if (dropped)
                to_free += btrfs_calc_trans_metadata_size(root, dropped);
@@ -7947,7 +7987,17 @@ int btrfs_read_block_groups(struct btrfs_root *root)
                 * info has super bytes accounted for, otherwise we'll think
                 * we have more space than we actually do.
                 */
-               exclude_super_stripes(root, cache);
+               ret = exclude_super_stripes(root, cache);
+               if (ret) {
+                       /*
+                        * We may have excluded something, so call this just in
+                        * case.
+                        */
+                       free_excluded_extents(root, cache);
+                       kfree(cache->free_space_ctl);
+                       kfree(cache);
+                       goto error;
+               }
 
                /*
                 * check for two cases, either we are full, and therefore
@@ -8089,7 +8139,17 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
 
        cache->last_byte_to_unpin = (u64)-1;
        cache->cached = BTRFS_CACHE_FINISHED;
-       exclude_super_stripes(root, cache);
+       ret = exclude_super_stripes(root, cache);
+       if (ret) {
+               /*
+                * We may have excluded something, so call this just in
+                * case.
+                */
+               free_excluded_extents(root, cache);
+               kfree(cache->free_space_ctl);
+               kfree(cache);
+               return ret;
+       }
 
        add_new_free_space(cache, root->fs_info, chunk_offset,
                           chunk_offset + size);
index f173c5af64610de66597cce1e38ac493729d6125..cdee391fc7bfd57c596204a8474142e7afe60335 100644 (file)
@@ -1257,6 +1257,39 @@ int unlock_extent(struct extent_io_tree *tree, u64 start, u64 end)
                                GFP_NOFS);
 }
 
+int extent_range_clear_dirty_for_io(struct inode *inode, u64 start, u64 end)
+{
+       unsigned long index = start >> PAGE_CACHE_SHIFT;
+       unsigned long end_index = end >> PAGE_CACHE_SHIFT;
+       struct page *page;
+
+       while (index <= end_index) {
+               page = find_get_page(inode->i_mapping, index);
+               BUG_ON(!page); /* Pages should be in the extent_io_tree */
+               clear_page_dirty_for_io(page);
+               page_cache_release(page);
+               index++;
+       }
+       return 0;
+}
+
+int extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end)
+{
+       unsigned long index = start >> PAGE_CACHE_SHIFT;
+       unsigned long end_index = end >> PAGE_CACHE_SHIFT;
+       struct page *page;
+
+       while (index <= end_index) {
+               page = find_get_page(inode->i_mapping, index);
+               BUG_ON(!page); /* Pages should be in the extent_io_tree */
+               account_page_redirty(page);
+               __set_page_dirty_nobuffers(page);
+               page_cache_release(page);
+               index++;
+       }
+       return 0;
+}
+
 /*
  * helper function to set both pages and extents in the tree writeback
  */
index 6068a1985560eed72a8df42fa528377c3584c93a..258c92156857f1d1e9e525a89d7a706d6c126c66 100644 (file)
@@ -325,6 +325,8 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long offset,
                      unsigned long *map_len);
 int extent_range_uptodate(struct extent_io_tree *tree,
                          u64 start, u64 end);
+int extent_range_clear_dirty_for_io(struct inode *inode, u64 start, u64 end);
+int extent_range_redirty_for_io(struct inode *inode, u64 start, u64 end);
 int extent_clear_unlock_delalloc(struct inode *inode,
                                struct extent_io_tree *tree,
                                u64 start, u64 end, struct page *locked_page,
index ec160202be3e38057c26498558e2f309af7859b7..c4628a201cb30fe6e2daa09eff83bd1fec79ecf1 100644 (file)
@@ -118,9 +118,11 @@ struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans,
                csums_in_item = btrfs_item_size_nr(leaf, path->slots[0]);
                csums_in_item /= csum_size;
 
-               if (csum_offset >= csums_in_item) {
+               if (csum_offset == csums_in_item) {
                        ret = -EFBIG;
                        goto fail;
+               } else if (csum_offset > csums_in_item) {
+                       goto fail;
                }
        }
        item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
@@ -728,7 +730,6 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
                return -ENOMEM;
 
        sector_sum = sums->sums;
-       trans->adding_csums = 1;
 again:
        next_offset = (u64)-1;
        found_next = 0;
@@ -899,7 +900,6 @@ next_sector:
                goto again;
        }
 out:
-       trans->adding_csums = 0;
        btrfs_free_path(path);
        return ret;
 
index 5b4ea5f55b8f47d0bf9a90992dd9da2d33880e14..ade03e6f7bd2706bbaac3406f1bcc31cf70cb578 100644 (file)
@@ -2142,6 +2142,7 @@ static long btrfs_fallocate(struct file *file, int mode,
 {
        struct inode *inode = file_inode(file);
        struct extent_state *cached_state = NULL;
+       struct btrfs_root *root = BTRFS_I(inode)->root;
        u64 cur_offset;
        u64 last_byte;
        u64 alloc_start;
@@ -2169,6 +2170,11 @@ static long btrfs_fallocate(struct file *file, int mode,
        ret = btrfs_check_data_free_space(inode, alloc_end - alloc_start);
        if (ret)
                return ret;
+       if (root->fs_info->quota_enabled) {
+               ret = btrfs_qgroup_reserve(root, alloc_end - alloc_start);
+               if (ret)
+                       goto out_reserve_fail;
+       }
 
        /*
         * wait for ordered IO before we have any locks.  We'll loop again
@@ -2272,6 +2278,9 @@ static long btrfs_fallocate(struct file *file, int mode,
                             &cached_state, GFP_NOFS);
 out:
        mutex_unlock(&inode->i_mutex);
+       if (root->fs_info->quota_enabled)
+               btrfs_qgroup_free(root, alloc_end - alloc_start);
+out_reserve_fail:
        /* Let go of our reservation. */
        btrfs_free_reserved_data_space(inode, alloc_end - alloc_start);
        return ret;
index ca1b767d51f760672f8de72c48efbf3df8e58a75..09c58a35b429d6a82dc261014df2875e7c15f920 100644 (file)
@@ -353,6 +353,7 @@ static noinline int compress_file_range(struct inode *inode,
        int i;
        int will_compress;
        int compress_type = root->fs_info->compress_type;
+       int redirty = 0;
 
        /* if this is a small write inside eof, kick off a defrag */
        if ((end - start + 1) < 16 * 1024 &&
@@ -415,6 +416,17 @@ again:
                if (BTRFS_I(inode)->force_compress)
                        compress_type = BTRFS_I(inode)->force_compress;
 
+               /*
+                * we need to call clear_page_dirty_for_io on each
+                * page in the range.  Otherwise applications with the file
+                * mmap'd can wander in and change the page contents while
+                * we are compressing them.
+                *
+                * If the compression fails for any reason, we set the pages
+                * dirty again later on.
+                */
+               extent_range_clear_dirty_for_io(inode, start, end);
+               redirty = 1;
                ret = btrfs_compress_pages(compress_type,
                                           inode->i_mapping, start,
                                           total_compressed, pages,
@@ -554,6 +566,8 @@ cleanup_and_bail_uncompressed:
                        __set_page_dirty_nobuffers(locked_page);
                        /* unlocked later on in the async handlers */
                }
+               if (redirty)
+                       extent_range_redirty_for_io(inode, start, end);
                add_async_extent(async_cow, start, end - start + 1,
                                 0, NULL, 0, BTRFS_COMPRESS_NONE);
                *num_added += 1;
@@ -1743,8 +1757,10 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans,
        struct btrfs_ordered_sum *sum;
 
        list_for_each_entry(sum, list, list) {
+               trans->adding_csums = 1;
                btrfs_csum_file_blocks(trans,
                       BTRFS_I(inode)->root->fs_info->csum_root, sum);
+               trans->adding_csums = 0;
        }
        return 0;
 }
@@ -3679,11 +3695,9 @@ static struct btrfs_trans_handle *__unlink_start_trans(struct inode *dir,
         * 1 for the dir item
         * 1 for the dir index
         * 1 for the inode ref
-        * 1 for the inode ref in the tree log
-        * 2 for the dir entries in the log
         * 1 for the inode
         */
-       trans = btrfs_start_transaction(root, 8);
+       trans = btrfs_start_transaction(root, 5);
        if (!IS_ERR(trans) || PTR_ERR(trans) != -ENOSPC)
                return trans;
 
@@ -8127,7 +8141,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
         * inodes.  So 5 * 2 is 10, plus 1 for the new link, so 11 total items
         * should cover the worst case number of items we'll modify.
         */
-       trans = btrfs_start_transaction(root, 20);
+       trans = btrfs_start_transaction(root, 11);
        if (IS_ERR(trans)) {
                 ret = PTR_ERR(trans);
                 goto out_notrans;
index dc08d77b717ea47f0eb7d43e351153f556c75eaa..005c45db699eecc0fef93fca0832b91633dd5d8a 100644 (file)
@@ -557,6 +557,7 @@ void btrfs_wait_ordered_extents(struct btrfs_root *root, int delay_iput)
        INIT_LIST_HEAD(&splice);
        INIT_LIST_HEAD(&works);
 
+       mutex_lock(&root->fs_info->ordered_operations_mutex);
        spin_lock(&root->fs_info->ordered_extent_lock);
        list_splice_init(&root->fs_info->ordered_extents, &splice);
        while (!list_empty(&splice)) {
@@ -600,6 +601,7 @@ void btrfs_wait_ordered_extents(struct btrfs_root *root, int delay_iput)
 
                cond_resched();
        }
+       mutex_unlock(&root->fs_info->ordered_operations_mutex);
 }
 
 /*
index 5471e47d6559eafeb36e55035cb427710c5ee4ba..b44124dd2370ea726e66a099400163c342d8fa12 100644 (file)
@@ -1153,7 +1153,7 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans,
        ret = btrfs_find_all_roots(trans, fs_info, node->bytenr,
                                   sgn > 0 ? node->seq - 1 : node->seq, &roots);
        if (ret < 0)
-               goto out;
+               return ret;
 
        spin_lock(&fs_info->qgroup_lock);
        quota_root = fs_info->quota_root;
@@ -1275,7 +1275,6 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans,
        ret = 0;
 unlock:
        spin_unlock(&fs_info->qgroup_lock);
-out:
        ulist_free(roots);
        ulist_free(tmp);
 
index 53c3501fa4ca348f13cb17617b363643a59b1f6f..85e072b956d564d64c527c1b58d3b5b26019c34f 100644 (file)
@@ -542,7 +542,6 @@ static void scrub_print_warning(const char *errstr, struct scrub_block *sblock)
        eb = path->nodes[0];
        ei = btrfs_item_ptr(eb, path->slots[0], struct btrfs_extent_item);
        item_size = btrfs_item_size_nr(eb, path->slots[0]);
-       btrfs_release_path(path);
 
        if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
                do {
@@ -558,7 +557,9 @@ static void scrub_print_warning(const char *errstr, struct scrub_block *sblock)
                                ret < 0 ? -1 : ref_level,
                                ret < 0 ? -1 : ref_root);
                } while (ret != 1);
+               btrfs_release_path(path);
        } else {
+               btrfs_release_path(path);
                swarn.path = path;
                swarn.dev = dev;
                iterate_extent_inodes(fs_info, found_key.objectid,
index f7a8b861058b5234094d24e9fc35a49d9e78fe1c..c85e7c6b4598af950d240582f648224570889ca4 100644 (file)
@@ -3945,12 +3945,10 @@ static int is_extent_unchanged(struct send_ctx *sctx,
                    found_key.type != key.type) {
                        key.offset += right_len;
                        break;
-               } else {
-                       if (found_key.offset != key.offset + right_len) {
-                               /* Should really not happen */
-                               ret = -EIO;
-                               goto out;
-                       }
+               }
+               if (found_key.offset != key.offset + right_len) {
+                       ret = 0;
+                       goto out;
                }
                key = found_key;
        }
index 5989a92236f7f1b578ec3ccf88078bb69c1093d3..2854c824ab6443d04eac19cf0b540f79c257cfa0 100644 (file)
@@ -4935,7 +4935,18 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree,
        em = lookup_extent_mapping(em_tree, chunk_start, 1);
        read_unlock(&em_tree->lock);
 
-       BUG_ON(!em || em->start != chunk_start);
+       if (!em) {
+               printk(KERN_ERR "btrfs: couldn't find em for chunk %Lu\n",
+                      chunk_start);
+               return -EIO;
+       }
+
+       if (em->start != chunk_start) {
+               printk(KERN_ERR "btrfs: bad chunk start, em=%Lu, wanted=%Lu\n",
+                      em->start, chunk_start);
+               free_extent_map(em);
+               return -EIO;
+       }
        map = (struct map_lookup *)em->bdev;
 
        length = em->len;
index fbfae008ba44e3e8223f42d4823cfeae2a673ac9..e8bc3420d63edcc28f0992217c860082fe424261 100644 (file)
@@ -2542,7 +2542,6 @@ static int prepend_path(const struct path *path,
        bool slash = false;
        int error = 0;
 
-       br_read_lock(&vfsmount_lock);
        while (dentry != root->dentry || vfsmnt != root->mnt) {
                struct dentry * parent;
 
@@ -2572,8 +2571,6 @@ static int prepend_path(const struct path *path,
        if (!error && !slash)
                error = prepend(buffer, buflen, "/", 1);
 
-out:
-       br_read_unlock(&vfsmount_lock);
        return error;
 
 global_root:
@@ -2590,7 +2587,7 @@ global_root:
                error = prepend(buffer, buflen, "/", 1);
        if (!error)
                error = is_mounted(vfsmnt) ? 1 : 2;
-       goto out;
+       return error;
 }
 
 /**
@@ -2617,9 +2614,11 @@ char *__d_path(const struct path *path,
        int error;
 
        prepend(&res, &buflen, "\0", 1);
+       br_read_lock(&vfsmount_lock);
        write_seqlock(&rename_lock);
        error = prepend_path(path, root, &res, &buflen);
        write_sequnlock(&rename_lock);
+       br_read_unlock(&vfsmount_lock);
 
        if (error < 0)
                return ERR_PTR(error);
@@ -2636,9 +2635,11 @@ char *d_absolute_path(const struct path *path,
        int error;
 
        prepend(&res, &buflen, "\0", 1);
+       br_read_lock(&vfsmount_lock);
        write_seqlock(&rename_lock);
        error = prepend_path(path, &root, &res, &buflen);
        write_sequnlock(&rename_lock);
+       br_read_unlock(&vfsmount_lock);
 
        if (error > 1)
                error = -EINVAL;
@@ -2702,11 +2703,13 @@ char *d_path(const struct path *path, char *buf, int buflen)
                return path->dentry->d_op->d_dname(path->dentry, buf, buflen);
 
        get_fs_root(current->fs, &root);
+       br_read_lock(&vfsmount_lock);
        write_seqlock(&rename_lock);
        error = path_with_deleted(path, &root, &res, &buflen);
+       write_sequnlock(&rename_lock);
+       br_read_unlock(&vfsmount_lock);
        if (error < 0)
                res = ERR_PTR(error);
-       write_sequnlock(&rename_lock);
        path_put(&root);
        return res;
 }
@@ -2830,6 +2833,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
        get_fs_root_and_pwd(current->fs, &root, &pwd);
 
        error = -ENOENT;
+       br_read_lock(&vfsmount_lock);
        write_seqlock(&rename_lock);
        if (!d_unlinked(pwd.dentry)) {
                unsigned long len;
@@ -2839,6 +2843,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
                prepend(&cwd, &buflen, "\0", 1);
                error = prepend_path(&pwd, &root, &cwd, &buflen);
                write_sequnlock(&rename_lock);
+               br_read_unlock(&vfsmount_lock);
 
                if (error < 0)
                        goto out;
@@ -2859,6 +2864,7 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
                }
        } else {
                write_sequnlock(&rename_lock);
+               br_read_unlock(&vfsmount_lock);
        }
 
 out:
index 507141fceb99669f7554e330d81605d2fff248b2..4be78237d896d759229eaf300f583288e1a28086 100644 (file)
@@ -125,3 +125,8 @@ extern int invalidate_inodes(struct super_block *, bool);
  * dcache.c
  */
 extern struct dentry *__d_alloc(struct super_block *, const struct qstr *);
+
+/*
+ * read_write.c
+ */
+extern ssize_t __kernel_write(struct file *, const char *, size_t, loff_t *);
index 50ca17d3cb4506de87465bb4d62f3da5f00553a5..d581e45c0a9fd6ada94edd2bb6ea4fe4c7fc9e23 100644 (file)
@@ -798,6 +798,10 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
        }
 
        mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~MNT_WRITE_HOLD;
+       /* Don't allow unprivileged users to change mount flags */
+       if ((flag & CL_UNPRIVILEGED) && (mnt->mnt.mnt_flags & MNT_READONLY))
+               mnt->mnt.mnt_flags |= MNT_LOCK_READONLY;
+
        atomic_inc(&sb->s_active);
        mnt->mnt.mnt_sb = sb;
        mnt->mnt.mnt_root = dget(root);
@@ -1713,6 +1717,9 @@ static int change_mount_flags(struct vfsmount *mnt, int ms_flags)
        if (readonly_request == __mnt_is_readonly(mnt))
                return 0;
 
+       if (mnt->mnt_flags & MNT_LOCK_READONLY)
+               return -EPERM;
+
        if (readonly_request)
                error = mnt_make_readonly(real_mount(mnt));
        else
@@ -2339,7 +2346,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
        /* First pass: copy the tree topology */
        copy_flags = CL_COPY_ALL | CL_EXPIRE;
        if (user_ns != mnt_ns->user_ns)
-               copy_flags |= CL_SHARED_TO_SLAVE;
+               copy_flags |= CL_SHARED_TO_SLAVE | CL_UNPRIVILEGED;
        new = copy_tree(old, old->mnt.mnt_root, copy_flags);
        if (IS_ERR(new)) {
                up_write(&namespace_sem);
@@ -2732,6 +2739,51 @@ bool our_mnt(struct vfsmount *mnt)
        return check_mnt(real_mount(mnt));
 }
 
+bool current_chrooted(void)
+{
+       /* Does the current process have a non-standard root */
+       struct path ns_root;
+       struct path fs_root;
+       bool chrooted;
+
+       /* Find the namespace root */
+       ns_root.mnt = &current->nsproxy->mnt_ns->root->mnt;
+       ns_root.dentry = ns_root.mnt->mnt_root;
+       path_get(&ns_root);
+       while (d_mountpoint(ns_root.dentry) && follow_down_one(&ns_root))
+               ;
+
+       get_fs_root(current->fs, &fs_root);
+
+       chrooted = !path_equal(&fs_root, &ns_root);
+
+       path_put(&fs_root);
+       path_put(&ns_root);
+
+       return chrooted;
+}
+
+void update_mnt_policy(struct user_namespace *userns)
+{
+       struct mnt_namespace *ns = current->nsproxy->mnt_ns;
+       struct mount *mnt;
+
+       down_read(&namespace_sem);
+       list_for_each_entry(mnt, &ns->list, mnt_list) {
+               switch (mnt->mnt.mnt_sb->s_magic) {
+               case SYSFS_MAGIC:
+                       userns->may_mount_sysfs = true;
+                       break;
+               case PROC_SUPER_MAGIC:
+                       userns->may_mount_proc = true;
+                       break;
+               }
+               if (userns->may_mount_sysfs && userns->may_mount_proc)
+                       break;
+       }
+       up_read(&namespace_sem);
+}
+
 static void *mntns_get(struct task_struct *task)
 {
        struct mnt_namespace *ns = NULL;
index 737d839bc17b5aa0ae58e5350a235af1f8adfb2b..6fc7b5cae92bf6526bee07696f12977322f2cb5e 100644 (file)
@@ -55,7 +55,8 @@ static void dev_remove(struct net *net, dev_t dev)
 
        bl_pipe_msg.bl_wq = &nn->bl_wq;
        memset(msg, 0, sizeof(*msg));
-       msg->data = kzalloc(1 + sizeof(bl_umount_request), GFP_NOFS);
+       msg->len = sizeof(bl_msg) + bl_msg.totallen;
+       msg->data = kzalloc(msg->len, GFP_NOFS);
        if (!msg->data)
                goto out;
 
@@ -66,7 +67,6 @@ static void dev_remove(struct net *net, dev_t dev)
        memcpy(msg->data, &bl_msg, sizeof(bl_msg));
        dataptr = (uint8_t *) msg->data;
        memcpy(&dataptr[sizeof(bl_msg)], &bl_umount_request, sizeof(bl_umount_request));
-       msg->len = sizeof(bl_msg) + bl_msg.totallen;
 
        add_wait_queue(&nn->bl_wq, &wq);
        if (rpc_queue_upcall(nn->bl_device_pipe, msg) < 0) {
index dc0f98dfa71773bd467a1b6891b2f916b696b734..c516da5873fd12df0d3c9877b2c3189423c0dec4 100644 (file)
@@ -726,9 +726,9 @@ out1:
        return ret;
 }
 
-static int nfs_idmap_instantiate(struct key *key, struct key *authkey, char *data)
+static int nfs_idmap_instantiate(struct key *key, struct key *authkey, char *data, size_t datalen)
 {
-       return key_instantiate_and_link(key, data, strlen(data) + 1,
+       return key_instantiate_and_link(key, data, datalen,
                                        id_resolver_cache->thread_keyring,
                                        authkey);
 }
@@ -738,6 +738,7 @@ static int nfs_idmap_read_and_verify_message(struct idmap_msg *im,
                struct key *key, struct key *authkey)
 {
        char id_str[NFS_UINT_MAXLEN];
+       size_t len;
        int ret = -ENOKEY;
 
        /* ret = -ENOKEY */
@@ -747,13 +748,15 @@ static int nfs_idmap_read_and_verify_message(struct idmap_msg *im,
        case IDMAP_CONV_NAMETOID:
                if (strcmp(upcall->im_name, im->im_name) != 0)
                        break;
-               sprintf(id_str, "%d", im->im_id);
-               ret = nfs_idmap_instantiate(key, authkey, id_str);
+               /* Note: here we store the NUL terminator too */
+               len = sprintf(id_str, "%d", im->im_id) + 1;
+               ret = nfs_idmap_instantiate(key, authkey, id_str, len);
                break;
        case IDMAP_CONV_IDTONAME:
                if (upcall->im_id != im->im_id)
                        break;
-               ret = nfs_idmap_instantiate(key, authkey, im->im_name);
+               len = strlen(im->im_name);
+               ret = nfs_idmap_instantiate(key, authkey, im->im_name, len);
                break;
        default:
                ret = -EINVAL;
index 49eeb044c109c0bb3c3878db7b8b60a780b50f97..4fb234d3aefb240f3d067523bda6df467336d2d0 100644 (file)
@@ -129,7 +129,6 @@ static void filelayout_fenceme(struct inode *inode, struct pnfs_layout_hdr *lo)
 {
        if (!test_and_clear_bit(NFS_LAYOUT_RETURN, &lo->plh_flags))
                return;
-       clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags);
        pnfs_return_layout(inode);
 }
 
index b2671cb0f901b8e904ee4b91961d2029e12fb2dc..26431cf62ddbc393fd5fe1e432742be37d06e12e 100644 (file)
@@ -2632,7 +2632,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
        int status;
 
        if (pnfs_ld_layoutret_on_setattr(inode))
-               pnfs_return_layout(inode);
+               pnfs_commit_and_return_layout(inode);
 
        nfs_fattr_init(fattr);
        
@@ -6416,22 +6416,8 @@ nfs4_layoutcommit_done(struct rpc_task *task, void *calldata)
 static void nfs4_layoutcommit_release(void *calldata)
 {
        struct nfs4_layoutcommit_data *data = calldata;
-       struct pnfs_layout_segment *lseg, *tmp;
-       unsigned long *bitlock = &NFS_I(data->args.inode)->flags;
 
        pnfs_cleanup_layoutcommit(data);
-       /* Matched by references in pnfs_set_layoutcommit */
-       list_for_each_entry_safe(lseg, tmp, &data->lseg_list, pls_lc_list) {
-               list_del_init(&lseg->pls_lc_list);
-               if (test_and_clear_bit(NFS_LSEG_LAYOUTCOMMIT,
-                                      &lseg->pls_flags))
-                       pnfs_put_lseg(lseg);
-       }
-
-       clear_bit_unlock(NFS_INO_LAYOUTCOMMITTING, bitlock);
-       smp_mb__after_clear_bit();
-       wake_up_bit(bitlock, NFS_INO_LAYOUTCOMMITTING);
-
        put_rpccred(data->cred);
        kfree(data);
 }
index 48ac5aad62589cd7140f55a52d5ee63f31e743b5..4bdffe0ba025228803b65d4fe54ab5cb0adda0ed 100644 (file)
@@ -417,6 +417,16 @@ should_free_lseg(struct pnfs_layout_range *lseg_range,
               lo_seg_intersecting(lseg_range, recall_range);
 }
 
+static bool pnfs_lseg_dec_and_remove_zero(struct pnfs_layout_segment *lseg,
+               struct list_head *tmp_list)
+{
+       if (!atomic_dec_and_test(&lseg->pls_refcount))
+               return false;
+       pnfs_layout_remove_lseg(lseg->pls_layout, lseg);
+       list_add(&lseg->pls_list, tmp_list);
+       return true;
+}
+
 /* Returns 1 if lseg is removed from list, 0 otherwise */
 static int mark_lseg_invalid(struct pnfs_layout_segment *lseg,
                             struct list_head *tmp_list)
@@ -430,11 +440,8 @@ static int mark_lseg_invalid(struct pnfs_layout_segment *lseg,
                 */
                dprintk("%s: lseg %p ref %d\n", __func__, lseg,
                        atomic_read(&lseg->pls_refcount));
-               if (atomic_dec_and_test(&lseg->pls_refcount)) {
-                       pnfs_layout_remove_lseg(lseg->pls_layout, lseg);
-                       list_add(&lseg->pls_list, tmp_list);
+               if (pnfs_lseg_dec_and_remove_zero(lseg, tmp_list))
                        rv = 1;
-               }
        }
        return rv;
 }
@@ -777,6 +784,21 @@ send_layoutget(struct pnfs_layout_hdr *lo,
        return lseg;
 }
 
+static void pnfs_clear_layoutcommit(struct inode *inode,
+               struct list_head *head)
+{
+       struct nfs_inode *nfsi = NFS_I(inode);
+       struct pnfs_layout_segment *lseg, *tmp;
+
+       if (!test_and_clear_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags))
+               return;
+       list_for_each_entry_safe(lseg, tmp, &nfsi->layout->plh_segs, pls_list) {
+               if (!test_and_clear_bit(NFS_LSEG_LAYOUTCOMMIT, &lseg->pls_flags))
+                       continue;
+               pnfs_lseg_dec_and_remove_zero(lseg, head);
+       }
+}
+
 /*
  * Initiates a LAYOUTRETURN(FILE), and removes the pnfs_layout_hdr
  * when the layout segment list is empty.
@@ -808,6 +830,7 @@ _pnfs_return_layout(struct inode *ino)
        /* Reference matched in nfs4_layoutreturn_release */
        pnfs_get_layout_hdr(lo);
        empty = list_empty(&lo->plh_segs);
+       pnfs_clear_layoutcommit(ino, &tmp_list);
        pnfs_mark_matching_lsegs_invalid(lo, &tmp_list, NULL);
        /* Don't send a LAYOUTRETURN if list was initially empty */
        if (empty) {
@@ -820,8 +843,6 @@ _pnfs_return_layout(struct inode *ino)
        spin_unlock(&ino->i_lock);
        pnfs_free_lseg_list(&tmp_list);
 
-       WARN_ON(test_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags));
-
        lrp = kzalloc(sizeof(*lrp), GFP_KERNEL);
        if (unlikely(lrp == NULL)) {
                status = -ENOMEM;
@@ -845,6 +866,33 @@ out:
 }
 EXPORT_SYMBOL_GPL(_pnfs_return_layout);
 
+int
+pnfs_commit_and_return_layout(struct inode *inode)
+{
+       struct pnfs_layout_hdr *lo;
+       int ret;
+
+       spin_lock(&inode->i_lock);
+       lo = NFS_I(inode)->layout;
+       if (lo == NULL) {
+               spin_unlock(&inode->i_lock);
+               return 0;
+       }
+       pnfs_get_layout_hdr(lo);
+       /* Block new layoutgets and read/write to ds */
+       lo->plh_block_lgets++;
+       spin_unlock(&inode->i_lock);
+       filemap_fdatawait(inode->i_mapping);
+       ret = pnfs_layoutcommit_inode(inode, true);
+       if (ret == 0)
+               ret = _pnfs_return_layout(inode);
+       spin_lock(&inode->i_lock);
+       lo->plh_block_lgets--;
+       spin_unlock(&inode->i_lock);
+       pnfs_put_layout_hdr(lo);
+       return ret;
+}
+
 bool pnfs_roc(struct inode *ino)
 {
        struct pnfs_layout_hdr *lo;
@@ -1458,7 +1506,6 @@ static void pnfs_ld_handle_write_error(struct nfs_write_data *data)
        dprintk("pnfs write error = %d\n", hdr->pnfs_error);
        if (NFS_SERVER(hdr->inode)->pnfs_curr_ld->flags &
            PNFS_LAYOUTRET_ON_ERROR) {
-               clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(hdr->inode)->flags);
                pnfs_return_layout(hdr->inode);
        }
        if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags))
@@ -1613,7 +1660,6 @@ static void pnfs_ld_handle_read_error(struct nfs_read_data *data)
        dprintk("pnfs read error = %d\n", hdr->pnfs_error);
        if (NFS_SERVER(hdr->inode)->pnfs_curr_ld->flags &
            PNFS_LAYOUTRET_ON_ERROR) {
-               clear_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(hdr->inode)->flags);
                pnfs_return_layout(hdr->inode);
        }
        if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags))
@@ -1746,11 +1792,27 @@ static void pnfs_list_write_lseg(struct inode *inode, struct list_head *listp)
 
        list_for_each_entry(lseg, &NFS_I(inode)->layout->plh_segs, pls_list) {
                if (lseg->pls_range.iomode == IOMODE_RW &&
-                   test_bit(NFS_LSEG_LAYOUTCOMMIT, &lseg->pls_flags))
+                   test_and_clear_bit(NFS_LSEG_LAYOUTCOMMIT, &lseg->pls_flags))
                        list_add(&lseg->pls_lc_list, listp);
        }
 }
 
+static void pnfs_list_write_lseg_done(struct inode *inode, struct list_head *listp)
+{
+       struct pnfs_layout_segment *lseg, *tmp;
+       unsigned long *bitlock = &NFS_I(inode)->flags;
+
+       /* Matched by references in pnfs_set_layoutcommit */
+       list_for_each_entry_safe(lseg, tmp, listp, pls_lc_list) {
+               list_del_init(&lseg->pls_lc_list);
+               pnfs_put_lseg(lseg);
+       }
+
+       clear_bit_unlock(NFS_INO_LAYOUTCOMMITTING, bitlock);
+       smp_mb__after_clear_bit();
+       wake_up_bit(bitlock, NFS_INO_LAYOUTCOMMITTING);
+}
+
 void pnfs_set_lo_fail(struct pnfs_layout_segment *lseg)
 {
        pnfs_layout_io_set_failed(lseg->pls_layout, lseg->pls_range.iomode);
@@ -1795,6 +1857,7 @@ void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data)
 
        if (nfss->pnfs_curr_ld->cleanup_layoutcommit)
                nfss->pnfs_curr_ld->cleanup_layoutcommit(data);
+       pnfs_list_write_lseg_done(data->args.inode, &data->lseg_list);
 }
 
 /*
index 94ba804177483d3c78694ae1708e95a2d34048d5..f5f8a470a647c7dc2f3a475e3e852d1aa7c97f5e 100644 (file)
@@ -219,6 +219,7 @@ void pnfs_set_layoutcommit(struct nfs_write_data *wdata);
 void pnfs_cleanup_layoutcommit(struct nfs4_layoutcommit_data *data);
 int pnfs_layoutcommit_inode(struct inode *inode, bool sync);
 int _pnfs_return_layout(struct inode *);
+int pnfs_commit_and_return_layout(struct inode *);
 void pnfs_ld_write_done(struct nfs_write_data *);
 void pnfs_ld_read_done(struct nfs_read_data *);
 struct pnfs_layout_segment *pnfs_update_layout(struct inode *ino,
@@ -407,6 +408,11 @@ static inline int pnfs_return_layout(struct inode *ino)
        return 0;
 }
 
+static inline int pnfs_commit_and_return_layout(struct inode *inode)
+{
+       return 0;
+}
+
 static inline bool
 pnfs_ld_layoutret_on_setattr(struct inode *inode)
 {
index 62c1ee128aebafbd82e70863e57caa74de804e13..ca05f6dc3544b4c216eb369d9e01fe7a48f0e90a 100644 (file)
@@ -102,7 +102,8 @@ nfsd_reply_cache_free_locked(struct svc_cacherep *rp)
 {
        if (rp->c_type == RC_REPLBUFF)
                kfree(rp->c_replvec.iov_base);
-       hlist_del(&rp->c_hash);
+       if (!hlist_unhashed(&rp->c_hash))
+               hlist_del(&rp->c_hash);
        list_del(&rp->c_lru);
        --num_drc_entries;
        kmem_cache_free(drc_slab, rp);
@@ -118,6 +119,10 @@ nfsd_reply_cache_free(struct svc_cacherep *rp)
 
 int nfsd_reply_cache_init(void)
 {
+       INIT_LIST_HEAD(&lru_head);
+       max_drc_entries = nfsd_cache_size_limit();
+       num_drc_entries = 0;
+
        register_shrinker(&nfsd_reply_cache_shrinker);
        drc_slab = kmem_cache_create("nfsd_drc", sizeof(struct svc_cacherep),
                                        0, 0, NULL);
@@ -128,10 +133,6 @@ int nfsd_reply_cache_init(void)
        if (!cache_hash)
                goto out_nomem;
 
-       INIT_LIST_HEAD(&lru_head);
-       max_drc_entries = nfsd_cache_size_limit();
-       num_drc_entries = 0;
-
        return 0;
 out_nomem:
        printk(KERN_ERR "nfsd: failed to allocate reply cache\n");
index 2a7eb536de0bec80dfbfd7d981139f2e925e644e..2b2e2396a86913b4d4e69c376852ded82dd9be3a 100644 (file)
@@ -1013,6 +1013,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
        int                     host_err;
        int                     stable = *stablep;
        int                     use_wgather;
+       loff_t                  pos = offset;
 
        dentry = file->f_path.dentry;
        inode = dentry->d_inode;
@@ -1025,7 +1026,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
 
        /* Write the data. */
        oldfs = get_fs(); set_fs(KERNEL_DS);
-       host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset);
+       host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &pos);
        set_fs(oldfs);
        if (host_err < 0)
                goto out_nfserr;
index 3e000a51ac0d09556d184d26422a91d0bc4c0ff9..8b29d2164da6aef6edb88b9872368c849e658530 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/mnt_namespace.h>
 #include <linux/mount.h>
 #include <linux/fs.h>
+#include <linux/nsproxy.h>
 #include "internal.h"
 #include "pnode.h"
 
@@ -220,6 +221,7 @@ static struct mount *get_source(struct mount *dest,
 int propagate_mnt(struct mount *dest_mnt, struct dentry *dest_dentry,
                    struct mount *source_mnt, struct list_head *tree_list)
 {
+       struct user_namespace *user_ns = current->nsproxy->mnt_ns->user_ns;
        struct mount *m, *child;
        int ret = 0;
        struct mount *prev_dest_mnt = dest_mnt;
@@ -237,6 +239,10 @@ int propagate_mnt(struct mount *dest_mnt, struct dentry *dest_dentry,
 
                source =  get_source(m, prev_dest_mnt, prev_src_mnt, &type);
 
+               /* Notice when we are propagating across user namespaces */
+               if (m->mnt_ns->user_ns != user_ns)
+                       type |= CL_UNPRIVILEGED;
+
                child = copy_tree(source, source->mnt.mnt_root, type);
                if (IS_ERR(child)) {
                        ret = PTR_ERR(child);
index 19b853a3445cb907665b4403484984a0c525af68..a0493d5ebfbf52be2eb07a794df459ab2a32cd6a 100644 (file)
@@ -23,6 +23,7 @@
 #define CL_MAKE_SHARED                 0x08
 #define CL_PRIVATE             0x10
 #define CL_SHARED_TO_SLAVE     0x20
+#define CL_UNPRIVILEGED                0x40
 
 static inline void set_mnt_shared(struct mount *mnt)
 {
index c6e9fac26bace4e9b63bd57dce624589dc67dfd7..9c7fab1d23f0d17d68446bf3d46ce1a906ae0907 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/sched.h>
 #include <linux/module.h>
 #include <linux/bitops.h>
+#include <linux/user_namespace.h>
 #include <linux/mount.h>
 #include <linux/pid_namespace.h>
 #include <linux/parser.h>
@@ -108,6 +109,9 @@ static struct dentry *proc_mount(struct file_system_type *fs_type,
        } else {
                ns = task_active_pid_ns(current);
                options = data;
+
+               if (!current_user_ns()->may_mount_proc)
+                       return ERR_PTR(-EPERM);
        }
 
        sb = sget(fs_type, proc_test_super, proc_set_super, flags, ns);
index a698eff457fb6e510c0543c9b762cc8c8d702f23..e6ddc8dceb96fc48a8fbe379799d0efed52d2b4a 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/splice.h>
 #include <linux/compat.h>
 #include "read_write.h"
+#include "internal.h"
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -417,6 +418,33 @@ ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, lof
 
 EXPORT_SYMBOL(do_sync_write);
 
+ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos)
+{
+       mm_segment_t old_fs;
+       const char __user *p;
+       ssize_t ret;
+
+       if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write))
+               return -EINVAL;
+
+       old_fs = get_fs();
+       set_fs(get_ds());
+       p = (__force const char __user *)buf;
+       if (count > MAX_RW_COUNT)
+               count =  MAX_RW_COUNT;
+       if (file->f_op->write)
+               ret = file->f_op->write(file, p, count, pos);
+       else
+               ret = do_sync_write(file, p, count, pos);
+       set_fs(old_fs);
+       if (ret > 0) {
+               fsnotify_modify(file);
+               add_wchar(current, ret);
+       }
+       inc_syscw(current);
+       return ret;
+}
+
 ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
 {
        ssize_t ret;
index 718bd0056384688af6ead056156574638c0be6e9..29e394e49ddda7c7721d3939d993632a29f4499a 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/security.h>
 #include <linux/gfp.h>
 #include <linux/socket.h>
+#include "internal.h"
 
 /*
  * Attempt to steal a page from a pipe buffer. This should perhaps go into
@@ -1048,9 +1049,10 @@ static int write_pipe_buf(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
 {
        int ret;
        void *data;
+       loff_t tmp = sd->pos;
 
        data = buf->ops->map(pipe, buf, 0);
-       ret = kernel_write(sd->u.file, data + buf->offset, sd->len, sd->pos);
+       ret = __kernel_write(sd->u.file, data + buf->offset, sd->len, &tmp);
        buf->ops->unmap(pipe, buf, data);
 
        return ret;
index 2fbdff6be25ce3d546e17fa4e72783e9d3f03637..e14512678c9b7b8042f5ba55a329a0101849f606 100644 (file)
@@ -1020,6 +1020,8 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
                ino = parent_sd->s_ino;
                if (filldir(dirent, ".", 1, filp->f_pos, ino, DT_DIR) == 0)
                        filp->f_pos++;
+               else
+                       return 0;
        }
        if (filp->f_pos == 1) {
                if (parent_sd->s_parent)
@@ -1028,6 +1030,8 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
                        ino = parent_sd->s_ino;
                if (filldir(dirent, "..", 2, filp->f_pos, ino, DT_DIR) == 0)
                        filp->f_pos++;
+               else
+                       return 0;
        }
        mutex_lock(&sysfs_mutex);
        for (pos = sysfs_dir_pos(ns, parent_sd, filp->f_pos, pos);
@@ -1058,10 +1062,21 @@ static int sysfs_readdir(struct file * filp, void * dirent, filldir_t filldir)
        return 0;
 }
 
+static loff_t sysfs_dir_llseek(struct file *file, loff_t offset, int whence)
+{
+       struct inode *inode = file_inode(file);
+       loff_t ret;
+
+       mutex_lock(&inode->i_mutex);
+       ret = generic_file_llseek(file, offset, whence);
+       mutex_unlock(&inode->i_mutex);
+
+       return ret;
+}
 
 const struct file_operations sysfs_dir_operations = {
        .read           = generic_read_dir,
        .readdir        = sysfs_readdir,
        .release        = sysfs_dir_release,
-       .llseek         = generic_file_llseek,
+       .llseek         = sysfs_dir_llseek,
 };
index 8d924b5ec733450e37599c8338ab69ea3b15027f..afd83273e6cea8112e1570c8835bfa829303b2f8 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/module.h>
 #include <linux/magic.h>
 #include <linux/slab.h>
+#include <linux/user_namespace.h>
 
 #include "sysfs.h"
 
@@ -111,6 +112,9 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type,
        struct super_block *sb;
        int error;
 
+       if (!(flags & MS_KERNMOUNT) && !current_user_ns()->may_mount_sysfs)
+               return ERR_PTR(-EPERM);
+
        info = kzalloc(sizeof(*info), GFP_KERNEL);
        if (!info)
                return ERR_PTR(-ENOMEM);
index 9c7f5807824b82fcf94a25771de576fe1c8cf247..dd7adff76e81fef6e2cc9fa8b2d18ac3c52bc174 100644 (file)
@@ -152,7 +152,7 @@ struct clk {
                },                                              \
                .reg = _reg,                                    \
                .shift = _shift,                                \
-               .width = _width,                                \
+               .mask = BIT(_width) - 1,                        \
                .flags = _mux_flags,                            \
                .lock = _lock,                                  \
        };                                                      \
index 7f197d7addb0be18141a66ad225135b9b0730b24..1f03528027949b61fe0897de5ddbe51d7165fbfe 100644 (file)
@@ -45,6 +45,14 @@ struct clk_hw;
  *             undo any work done in the @prepare callback. Called with
  *             prepare_lock held.
  *
+ * @is_prepared: Queries the hardware to determine if the clock is prepared.
+ *             This function is allowed to sleep. Optional, if this op is not
+ *             set then the prepare count will be used.
+ *
+ * @unprepare_unused: Unprepare the clock atomically.  Only called from
+ *             clk_disable_unused for prepare clocks with special needs.
+ *             Called with prepare mutex held. This function may sleep.
+ *
  * @enable:    Enable the clock atomically. This must not return until the
  *             clock is generating a valid clock signal, usable by consumer
  *             devices. Called with enable_lock held. This function must not
@@ -108,6 +116,8 @@ struct clk_hw;
 struct clk_ops {
        int             (*prepare)(struct clk_hw *hw);
        void            (*unprepare)(struct clk_hw *hw);
+       int             (*is_prepared)(struct clk_hw *hw);
+       void            (*unprepare_unused)(struct clk_hw *hw);
        int             (*enable)(struct clk_hw *hw);
        void            (*disable)(struct clk_hw *hw);
        int             (*is_enabled)(struct clk_hw *hw);
@@ -287,8 +297,9 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
 struct clk_mux {
        struct clk_hw   hw;
        void __iomem    *reg;
+       u32             *table;
+       u32             mask;
        u8              shift;
-       u8              width;
        u8              flags;
        spinlock_t      *lock;
 };
@@ -297,11 +308,17 @@ struct clk_mux {
 #define CLK_MUX_INDEX_BIT              BIT(1)
 
 extern const struct clk_ops clk_mux_ops;
+
 struct clk *clk_register_mux(struct device *dev, const char *name,
                const char **parent_names, u8 num_parents, unsigned long flags,
                void __iomem *reg, u8 shift, u8 width,
                u8 clk_mux_flags, spinlock_t *lock);
 
+struct clk *clk_register_mux_table(struct device *dev, const char *name,
+               const char **parent_names, u8 num_parents, unsigned long flags,
+               void __iomem *reg, u8 shift, u32 mask,
+               u8 clk_mux_flags, u32 *table, spinlock_t *lock);
+
 /**
  * struct clk_fixed_factor - fixed multiplier and divider clock
  *
@@ -325,6 +342,37 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
                unsigned int mult, unsigned int div);
 
+/***
+ * struct clk_composite - aggregate clock of mux, divider and gate clocks
+ *
+ * @hw:                handle between common and hardware-specific interfaces
+ * @mux_hw:    handle between composite and hardware-specifix mux clock
+ * @div_hw:    handle between composite and hardware-specifix divider clock
+ * @gate_hw:   handle between composite and hardware-specifix gate clock
+ * @mux_ops:   clock ops for mux
+ * @div_ops:   clock ops for divider
+ * @gate_ops:  clock ops for gate
+ */
+struct clk_composite {
+       struct clk_hw   hw;
+       struct clk_ops  ops;
+
+       struct clk_hw   *mux_hw;
+       struct clk_hw   *div_hw;
+       struct clk_hw   *gate_hw;
+
+       const struct clk_ops    *mux_ops;
+       const struct clk_ops    *div_ops;
+       const struct clk_ops    *gate_ops;
+};
+
+struct clk *clk_register_composite(struct device *dev, const char *name,
+               const char **parent_names, int num_parents,
+               struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
+               struct clk_hw *div_hw, const struct clk_ops *div_ops,
+               struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
+               unsigned long flags);
+
 /**
  * clk_register - allocate a new clock, register it and return an opaque cookie
  * @dev: device that is registering this clock
@@ -351,6 +399,7 @@ unsigned int __clk_get_enable_count(struct clk *clk);
 unsigned int __clk_get_prepare_count(struct clk *clk);
 unsigned long __clk_get_rate(struct clk *clk);
 unsigned long __clk_get_flags(struct clk *clk);
+bool __clk_is_prepared(struct clk *clk);
 bool __clk_is_enabled(struct clk *clk);
 struct clk *__clk_lookup(const char *name);
 
diff --git a/include/linux/clk/mxs.h b/include/linux/clk/mxs.h
new file mode 100644 (file)
index 0000000..90c30dc
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * 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_CLK_MXS_H
+#define __LINUX_CLK_MXS_H
+
+int mx23_clocks_init(void);
+int mx28_clocks_init(void);
+int mxs_saif_clkmux_select(unsigned int clkmux);
+
+#endif
diff --git a/include/linux/clk/sunxi.h b/include/linux/clk/sunxi.h
new file mode 100644 (file)
index 0000000..e074fdd
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2012 Maxime Ripard
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.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 __LINUX_CLK_SUNXI_H_
+#define __LINUX_CLK_SUNXI_H_
+
+void __init sunxi_init_clocks(void);
+
+#endif
index 404d6f940872b0da7373f6ee13172ab089fdf97b..642789baec741cf6574d661587091c75d864b946 100644 (file)
@@ -123,5 +123,6 @@ static inline void tegra_cpu_clock_resume(void)
 void tegra_periph_reset_deassert(struct clk *c);
 void tegra_periph_reset_assert(struct clk *c);
 void tegra_clocks_init(void);
+void tegra_clocks_apply_init_table(void);
 
 #endif /* __LINUX_CLK_TEGRA_H_ */
index 27cfda427dd9106b15af57c3ad4825445a4b8feb..08ed5e19d8c68024c64636c494635c54acf4809b 100644 (file)
@@ -340,6 +340,7 @@ extern void clocksource_of_init(void);
                __used __section(__clksrc_of_table)                     \
                 = { .compatible = compat, .data = fn };
 #else
+static inline void clocksource_of_init(void) {}
 #define CLOCKSOURCE_OF_DECLARE(name, compat, fn)
 #endif
 
index a975de1ff59feaba6758afa9682ca9203bfc2c42..3bd46f766751caa9b143adcc5ce546441f6b868d 100644 (file)
@@ -51,7 +51,7 @@ struct task_struct;
 extern void debug_show_all_locks(void);
 extern void debug_show_held_locks(struct task_struct *task);
 extern void debug_check_no_locks_freed(const void *from, unsigned long len);
-extern void debug_check_no_locks_held(void);
+extern void debug_check_no_locks_held(struct task_struct *task);
 #else
 static inline void debug_show_all_locks(void)
 {
@@ -67,7 +67,7 @@ debug_check_no_locks_freed(const void *from, unsigned long len)
 }
 
 static inline void
-debug_check_no_locks_held(void)
+debug_check_no_locks_held(struct task_struct *task)
 {
 }
 #endif
index 043a5cf8b5baf3e917dd9ba265c365a334365216..e70df40d84f6fe83c72f732aa44b454148661b6e 100644 (file)
@@ -3,7 +3,6 @@
 #ifndef FREEZER_H_INCLUDED
 #define FREEZER_H_INCLUDED
 
-#include <linux/debug_locks.h>
 #include <linux/sched.h>
 #include <linux/wait.h>
 #include <linux/atomic.h>
@@ -49,8 +48,6 @@ extern void thaw_kernel_threads(void);
 
 static inline bool try_to_freeze(void)
 {
-       if (!(current->flags & PF_NOFREEZE))
-               debug_check_no_locks_held();
        might_sleep();
        if (likely(!freezing(current)))
                return false;
index 729eded4b24f09fa93b7f85b50aaca4b297fd2f9..2b93a9a5a1e6b8ef4a15a6aaf36ade3b48bd0d98 100644 (file)
@@ -50,4 +50,6 @@ static inline void get_fs_root_and_pwd(struct fs_struct *fs, struct path *root,
        spin_unlock(&fs->lock);
 }
 
+extern bool current_chrooted(void);
+
 #endif /* _LINUX_FS_STRUCT_H */
diff --git a/include/linux/irqchip/mxs.h b/include/linux/irqchip/mxs.h
new file mode 100644 (file)
index 0000000..9039a53
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * 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_IRQCHIP_MXS_H
+#define __LINUX_IRQCHIP_MXS_H
+
+extern void icoll_handle_irq(struct pt_regs *);
+
+#endif
index 5b18ecde69b58be85c4fb39db00464de7d6885bf..1aa4f13cdfa6a4f2b0ceec56a689600f8d53626c 100644 (file)
@@ -106,6 +106,29 @@ enum max77693_muic_reg {
        MAX77693_MUIC_REG_END,
 };
 
+/* MAX77693 INTMASK1~2 Register */
+#define INTMASK1_ADC1K_SHIFT           3
+#define INTMASK1_ADCERR_SHIFT          2
+#define INTMASK1_ADCLOW_SHIFT          1
+#define INTMASK1_ADC_SHIFT             0
+#define INTMASK1_ADC1K_MASK            (1 << INTMASK1_ADC1K_SHIFT)
+#define INTMASK1_ADCERR_MASK           (1 << INTMASK1_ADCERR_SHIFT)
+#define INTMASK1_ADCLOW_MASK           (1 << INTMASK1_ADCLOW_SHIFT)
+#define INTMASK1_ADC_MASK              (1 << INTMASK1_ADC_SHIFT)
+
+#define INTMASK2_VIDRM_SHIFT           5
+#define INTMASK2_VBVOLT_SHIFT          4
+#define INTMASK2_DXOVP_SHIFT           3
+#define INTMASK2_DCDTMR_SHIFT          2
+#define INTMASK2_CHGDETRUN_SHIFT       1
+#define INTMASK2_CHGTYP_SHIFT          0
+#define INTMASK2_VIDRM_MASK            (1 << INTMASK2_VIDRM_SHIFT)
+#define INTMASK2_VBVOLT_MASK           (1 << INTMASK2_VBVOLT_SHIFT)
+#define INTMASK2_DXOVP_MASK            (1 << INTMASK2_DXOVP_SHIFT)
+#define INTMASK2_DCDTMR_MASK           (1 << INTMASK2_DCDTMR_SHIFT)
+#define INTMASK2_CHGDETRUN_MASK                (1 << INTMASK2_CHGDETRUN_SHIFT)
+#define INTMASK2_CHGTYP_MASK           (1 << INTMASK2_CHGTYP_SHIFT)
+
 /* MAX77693 MUIC - STATUS1~3 Register */
 #define STATUS1_ADC_SHIFT              (0)
 #define STATUS1_ADCLOW_SHIFT           (5)
index 7acc9dc73c9f272bda990e741041a1b5c1237cc5..e19ff30ad0a21453cece0df7524d0b336a69078f 100644 (file)
@@ -87,7 +87,6 @@ extern unsigned int kobjsize(const void *objp);
 #define VM_PFNMAP      0x00000400      /* Page-ranges managed without "struct page", just pure PFN */
 #define VM_DENYWRITE   0x00000800      /* ETXTBSY on write attempts.. */
 
-#define VM_POPULATE     0x00001000
 #define VM_LOCKED      0x00002000
 #define VM_IO           0x00004000     /* Memory mapped I/O or similar */
 
index 61c7a87e5d2b358484dc16ab1b0db79253fc93b3..9aa863da287fedf383f3c507c287aa220cbd6a86 100644 (file)
@@ -79,8 +79,6 @@ calc_vm_flag_bits(unsigned long flags)
 {
        return _calc_vm_trans(flags, MAP_GROWSDOWN,  VM_GROWSDOWN ) |
               _calc_vm_trans(flags, MAP_DENYWRITE,  VM_DENYWRITE ) |
-              ((flags & MAP_LOCKED) ? (VM_LOCKED | VM_POPULATE) : 0) |
-              (((flags & (MAP_POPULATE | MAP_NONBLOCK)) == MAP_POPULATE) ?
-                                                       VM_POPULATE : 0);
+              _calc_vm_trans(flags, MAP_LOCKED,     VM_LOCKED    );
 }
 #endif /* _LINUX_MMAN_H */
index d7029f4a191a093ef9294104c75756b6d3b7faee..73005f9957ead2b95adb4107329434afbbf482a7 100644 (file)
@@ -47,6 +47,8 @@ struct mnt_namespace;
 
 #define MNT_INTERNAL   0x4000
 
+#define MNT_LOCK_READONLY      0x400000
+
 struct vfsmount {
        struct dentry *mnt_root;        /* root of the mounted tree */
        struct super_block *mnt_sb;     /* pointer to superblock */
diff --git a/include/linux/mxsfb.h b/include/linux/mxsfb.h
deleted file mode 100644 (file)
index f14943d..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#ifndef __LINUX_MXSFB_H
-#define __LINUX_MXSFB_H
-
-#include <linux/fb.h>
-
-#define STMLCDIF_8BIT 1        /** pixel data bus to the display is of 8 bit width */
-#define STMLCDIF_16BIT 0 /** pixel data bus to the display is of 16 bit width */
-#define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */
-#define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */
-
-#define FB_SYNC_DATA_ENABLE_HIGH_ACT   (1 << 6)
-#define FB_SYNC_DOTCLK_FAILING_ACT     (1 << 7) /* failing/negtive edge sampling */
-
-struct mxsfb_platform_data {
-       struct fb_videomode *mode_list;
-       unsigned mode_count;
-
-       unsigned default_bpp;
-
-       unsigned dotclk_delay;  /* refer manual HW_LCDIF_VDCTRL4 register */
-       unsigned ld_intf_width; /* refer STMLCDIF_* macros */
-
-       unsigned fb_size;       /* Size of the video memory. If zero a
-                                * default will be used
-                                */
-       unsigned long fb_phys;  /* physical address for the video memory. If
-                                * zero the framebuffer memory will be dynamically
-                                * allocated. If specified,fb_size must also be specified.
-                                * fb_phys must be unused by Linux.
-                                */
-};
-
-#endif /* __LINUX_MXSFB_H */
index 61ae1306db23f55ca4a9dd30ab9f61bb03e3ef88..4835486f58e5abbe71d2535a6f563241ae4d3126 100644 (file)
@@ -24,7 +24,7 @@
 #ifndef __LINUX_SPI_MXS_SPI_H__
 #define __LINUX_SPI_MXS_SPI_H__
 
-#include <linux/fsl/mxs-dma.h>
+#include <linux/dmaengine.h>
 
 #define ssp_is_old(host)       ((host)->devid == IMX23_SSP)
 
@@ -137,9 +137,7 @@ struct mxs_ssp {
        unsigned int                    clk_rate;
        enum mxs_ssp_id                 devid;
 
-       int                             dma_channel;
        struct dma_chan                 *dmach;
-       struct mxs_dma_data             dma_data;
        unsigned int                    dma_dir;
        enum dma_transfer_direction     slave_dirn;
        u32                             ssp_pio_words[SSP_PIO_NUM];
index f0bd7f90a90d45d3aeeb3aed8bc2d2f8295c8be0..e3c0ae9bb1faf876afca191701e481ecc30a4f1b 100644 (file)
@@ -44,7 +44,7 @@
 /* Adding event notification support elements */
 #define THERMAL_GENL_FAMILY_NAME                "thermal_event"
 #define THERMAL_GENL_VERSION                    0x01
-#define THERMAL_GENL_MCAST_GROUP_NAME           "thermal_mc_group"
+#define THERMAL_GENL_MCAST_GROUP_NAME           "thermal_mc_grp"
 
 /* Default Thermal Governor */
 #if defined(CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE)
index 9d81de123c9017f4463ba4fa09a61b8b7425a8bf..42278bbf7a882d90360d141db9c8cc1b1eca1719 100644 (file)
@@ -68,6 +68,7 @@ struct udp_sock {
         * For encapsulation sockets.
         */
        int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
+       void (*encap_destroy)(struct sock *sk);
 };
 
 static inline struct udp_sock *udp_sk(const struct sock *sk)
index 0a78df5f6cfd23d616ecd4572b6079d1f8605dd2..59694b5e5e906821a873d52a1a33b9c5d67af5d4 100644 (file)
@@ -357,6 +357,7 @@ struct hc_driver {
                 */
        int     (*disable_usb3_lpm_timeout)(struct usb_hcd *,
                        struct usb_device *, enum usb3_link_state state);
+       int     (*find_raw_port_number)(struct usb_hcd *, int);
 };
 
 extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
@@ -396,6 +397,7 @@ extern int usb_hcd_is_primary_hcd(struct usb_hcd *hcd);
 extern int usb_add_hcd(struct usb_hcd *hcd,
                unsigned int irqnum, unsigned long irqflags);
 extern void usb_remove_hcd(struct usb_hcd *hcd);
+extern int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1);
 
 struct platform_device;
 extern void usb_hcd_platform_shutdown(struct platform_device *dev);
index 28884c7174112d7ede78d0283d9cba35802eddaa..148d35171aac622ab215bb6520f3dc3f0c0b431f 100644 (file)
@@ -5,6 +5,11 @@
 
 struct nop_usb_xceiv_platform_data {
        enum usb_phy_type type;
+       unsigned long clk_rate;
+
+       /* if set fails with -EPROBE_DEFER if can't get regulator */
+       unsigned int needs_vcc:1;
+       unsigned int needs_reset:1;
 };
 
 #if defined(CONFIG_NOP_USB_XCEIV) || (defined(CONFIG_NOP_USB_XCEIV_MODULE) && defined(MODULE))
index 4ce009324933ebc2b048ebd5f834b0c1bf44e52d..b6b215f13b453091ff2be0fae11b37a5a51c0c84 100644 (file)
@@ -26,6 +26,8 @@ struct user_namespace {
        kuid_t                  owner;
        kgid_t                  group;
        unsigned int            proc_inum;
+       bool                    may_mount_sysfs;
+       bool                    may_mount_proc;
 };
 
 extern struct user_namespace init_user_ns;
@@ -82,4 +84,6 @@ static inline void put_user_ns(struct user_namespace *ns)
 
 #endif
 
+void update_mnt_policy(struct user_namespace *userns);
+
 #endif /* _LINUX_USER_H */
index 80461c1ae9efcceea9875000629f62608c6e699e..bb8271d487b7bea10861c6548dde50d0964c4a20 100644 (file)
@@ -9,6 +9,7 @@ struct flow_keys {
                __be32 ports;
                __be16 port16[2];
        };
+       u16 thoff;
        u8 ip_proto;
 };
 
index 68c69d54d39281ee033d765a1b9b66567c55d06f..fce8e6b66d558d8ff8bb629c4da5e358113a675e 100644 (file)
@@ -976,6 +976,7 @@ struct netns_ipvs {
        int                     sysctl_sync_retries;
        int                     sysctl_nat_icmp_send;
        int                     sysctl_pmtu_disc;
+       int                     sysctl_backup_only;
 
        /* ip_vs_lblc */
        int                     sysctl_lblc_expiration;
@@ -1067,6 +1068,12 @@ static inline int sysctl_pmtu_disc(struct netns_ipvs *ipvs)
        return ipvs->sysctl_pmtu_disc;
 }
 
+static inline int sysctl_backup_only(struct netns_ipvs *ipvs)
+{
+       return ipvs->sync_state & IP_VS_STATE_BACKUP &&
+              ipvs->sysctl_backup_only;
+}
+
 #else
 
 static inline int sysctl_sync_threshold(struct netns_ipvs *ipvs)
@@ -1114,6 +1121,11 @@ static inline int sysctl_pmtu_disc(struct netns_ipvs *ipvs)
        return 1;
 }
 
+static inline int sysctl_backup_only(struct netns_ipvs *ipvs)
+{
+       return 0;
+}
+
 #endif
 
 /*
index fd19625ff99db290fd289b3caf18f32c9b72ffc3..982141c15200d1fc60b144a2ca6ba53c0d320200 100644 (file)
@@ -77,15 +77,11 @@ static inline void tunnel_ip_select_ident(struct sk_buff *skb,
 {
        struct iphdr *iph = ip_hdr(skb);
 
-       if (iph->frag_off & htons(IP_DF))
-               iph->id = 0;
-       else {
-               /* Use inner packet iph-id if possible. */
-               if (skb->protocol == htons(ETH_P_IP) && old_iph->id)
-                       iph->id = old_iph->id;
-               else
-                       __ip_select_ident(iph, dst,
-                                         (skb_shinfo(skb)->gso_segs ?: 1) - 1);
-       }
+       /* Use inner packet iph-id if possible. */
+       if (skb->protocol == htons(ETH_P_IP) && old_iph->id)
+               iph->id = old_iph->id;
+       else
+               __ip_select_ident(iph, dst,
+                                 (skb_shinfo(skb)->gso_segs ?: 1) - 1);
 }
 #endif
index 93f5fa94a431c167d70902ce6ded5a2275215b53..afafd703ad92b1595a5c7c326883fe89816f920f 100644 (file)
@@ -33,9 +33,11 @@ enum {
        PACKET_DIAG_TX_RING,
        PACKET_DIAG_FANOUT,
 
-       PACKET_DIAG_MAX,
+       __PACKET_DIAG_MAX,
 };
 
+#define PACKET_DIAG_MAX (__PACKET_DIAG_MAX - 1)
+
 struct packet_diag_info {
        __u32   pdi_index;
        __u32   pdi_version;
index b8a24941db21e82b11d80d0912c057a54bcf7742..b9e2a6a7446f077e528dd15fac8e8d97f0d9a232 100644 (file)
@@ -39,9 +39,11 @@ enum {
        UNIX_DIAG_MEMINFO,
        UNIX_DIAG_SHUTDOWN,
 
-       UNIX_DIAG_MAX,
+       __UNIX_DIAG_MAX,
 };
 
+#define UNIX_DIAG_MAX (__UNIX_DIAG_MAX - 1)
+
 struct unix_diag_vfs {
        __u32   udiag_vfs_ino;
        __u32   udiag_vfs_dev;
index 01c3d62436ef8c44c4d0deffc3393bd2d02b8116..ffd4652de91ca390fff537f18f524300bf470246 100644 (file)
@@ -138,11 +138,21 @@ struct blkif_request_discard {
        uint8_t        _pad3;
 } __attribute__((__packed__));
 
+struct blkif_request_other {
+       uint8_t      _pad1;
+       blkif_vdev_t _pad2;        /* only for read/write requests         */
+#ifdef CONFIG_X86_64
+       uint32_t     _pad3;        /* offsetof(blkif_req..,u.other.id)==8*/
+#endif
+       uint64_t     id;           /* private guest value, echoed in resp  */
+} __attribute__((__packed__));
+
 struct blkif_request {
        uint8_t        operation;    /* BLKIF_OP_???                         */
        union {
                struct blkif_request_rw rw;
                struct blkif_request_discard discard;
+               struct blkif_request_other other;
        } u;
 } __attribute__((__packed__));
 
index 1844d31f45520fef57c93be90ba7e247e1a0b042..7000bb1f6e96fb018fcc5360cf6266d567f6121e 100644 (file)
@@ -251,6 +251,12 @@ struct physdev_pci_device_add {
 
 #define PHYSDEVOP_pci_device_remove     26
 #define PHYSDEVOP_restore_msi_ext       27
+/*
+ * Dom0 should use these two to announce MMIO resources assigned to
+ * MSI-X capable devices won't (prepare) or may (release) change.
+ */
+#define PHYSDEVOP_prepare_msix          30
+#define PHYSDEVOP_release_msix          31
 struct physdev_pci_device {
     /* IN */
     uint16_t seg;
index 3953fda2e8bd182edcc76f790523e48f2698b962..e4e47f64744635bbebe26fda491ff64eda8e4161 100644 (file)
@@ -330,8 +330,16 @@ static struct dentry *mqueue_mount(struct file_system_type *fs_type,
                         int flags, const char *dev_name,
                         void *data)
 {
-       if (!(flags & MS_KERNMOUNT))
-               data = current->nsproxy->ipc_ns;
+       if (!(flags & MS_KERNMOUNT)) {
+               struct ipc_namespace *ns = current->nsproxy->ipc_ns;
+               /* Don't allow mounting unless the caller has CAP_SYS_ADMIN
+                * over the ipc namespace.
+                */
+               if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
+                       return ERR_PTR(-EPERM);
+
+               data = ns;
+       }
        return mount_ns(fs_type, flags, data, mqueue_fill_super);
 }
 
index 51e485ca993560015dbb56701fd249637afc721c..60bc027c61c3a3be8d5bc26b024ffac0a79f1af9 100644 (file)
@@ -835,7 +835,7 @@ void do_exit(long code)
        /*
         * Make sure we are holding no locks:
         */
-       debug_check_no_locks_held();
+       debug_check_no_locks_held(tsk);
        /*
         * We can do this unlocked here. The futex code uses this flag
         * just to verify whether the pi state cleanup has been done
index 259db207b5d90806536da88963e7d1b469e1b943..8a0efac4f99de7c5d0711bea6792db1f385f66eb 100644 (file)
@@ -4088,7 +4088,7 @@ void debug_check_no_locks_freed(const void *mem_from, unsigned long mem_len)
 }
 EXPORT_SYMBOL_GPL(debug_check_no_locks_freed);
 
-static void print_held_locks_bug(void)
+static void print_held_locks_bug(struct task_struct *curr)
 {
        if (!debug_locks_off())
                return;
@@ -4097,21 +4097,22 @@ static void print_held_locks_bug(void)
 
        printk("\n");
        printk("=====================================\n");
-       printk("[ BUG: %s/%d still has locks held! ]\n",
-              current->comm, task_pid_nr(current));
+       printk("[ BUG: lock held at task exit time! ]\n");
        print_kernel_ident();
        printk("-------------------------------------\n");
-       lockdep_print_held_locks(current);
+       printk("%s/%d is exiting with locks still held!\n",
+               curr->comm, task_pid_nr(curr));
+       lockdep_print_held_locks(curr);
+
        printk("\nstack backtrace:\n");
        dump_stack();
 }
 
-void debug_check_no_locks_held(void)
+void debug_check_no_locks_held(struct task_struct *task)
 {
-       if (unlikely(current->lockdep_depth > 0))
-               print_held_locks_bug();
+       if (unlikely(task->lockdep_depth > 0))
+               print_held_locks_bug(task);
 }
-EXPORT_SYMBOL_GPL(debug_check_no_locks_held);
 
 void debug_show_all_locks(void)
 {
index c1c3dc1c60233f337a01ff13587f1a5a7f57f1cd..bea15bdf82b04c28d2f5d8c1a32a46b2621cb295 100644 (file)
@@ -181,6 +181,7 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns)
        int nr;
        int rc;
        struct task_struct *task, *me = current;
+       int init_pids = thread_group_leader(me) ? 1 : 2;
 
        /* Don't allow any more processes into the pid namespace */
        disable_pid_allocation(pid_ns);
@@ -230,7 +231,7 @@ void zap_pid_ns_processes(struct pid_namespace *pid_ns)
         */
        for (;;) {
                set_current_state(TASK_UNINTERRUPTIBLE);
-               if (pid_ns->nr_hashed == 1)
+               if (pid_ns->nr_hashed == init_pids)
                        break;
                schedule();
        }
index 2fb8cb88df8d0296e655f320bc7d5cbce1a858c8..7f32fe0e52cd46489c8d90e4b85f9d74204aab16 100644 (file)
@@ -67,7 +67,8 @@ static void tick_broadcast_start_periodic(struct clock_event_device *bc)
  */
 int tick_check_broadcast_device(struct clock_event_device *dev)
 {
-       if ((tick_broadcast_device.evtdev &&
+       if ((dev->features & CLOCK_EVT_FEAT_DUMMY) ||
+           (tick_broadcast_device.evtdev &&
             tick_broadcast_device.evtdev->rating >= dev->rating) ||
             (dev->features & CLOCK_EVT_FEAT_C3STOP))
                return 0;
index e81978e8c03b2b5f1a38d62248d8408fbfcd2d13..8e635a18ab521e48cfc4195cfb9f199de5e0c3b3 100644 (file)
@@ -51,6 +51,8 @@ struct user_namespace init_user_ns = {
        .owner = GLOBAL_ROOT_UID,
        .group = GLOBAL_ROOT_GID,
        .proc_inum = PROC_USER_INIT_INO,
+       .may_mount_sysfs = true,
+       .may_mount_proc = true,
 };
 EXPORT_SYMBOL_GPL(init_user_ns);
 
index b14f4d3420439ca629be08494ef417e734513499..a54f26f82eb250a60c7f24ecc651c6c1bbf8cc88 100644 (file)
@@ -61,6 +61,15 @@ int create_user_ns(struct cred *new)
        kgid_t group = new->egid;
        int ret;
 
+       /*
+        * Verify that we can not violate the policy of which files
+        * may be accessed that is specified by the root directory,
+        * by verifing that the root directory is at the root of the
+        * mount namespace which allows all files to be accessed.
+        */
+       if (current_chrooted())
+               return -EPERM;
+
        /* The creator needs a mapping in the parent user namespace
         * or else we won't be able to reasonably tell userspace who
         * created a user_namespace.
@@ -87,6 +96,8 @@ int create_user_ns(struct cred *new)
 
        set_cred_user_ns(new, ns);
 
+       update_mnt_policy(ns);
+
        return 0;
 }
 
index 4723ac8d2fc200d5990f830b6f4c8c0fd2a9bbcf..87da3590c61e20287b4854e8212c178f96cb73c6 100644 (file)
@@ -204,10 +204,8 @@ get_write_lock:
                        unsigned long addr;
                        struct file *file = get_file(vma->vm_file);
 
-                       vm_flags = vma->vm_flags;
-                       if (!(flags & MAP_NONBLOCK))
-                               vm_flags |= VM_POPULATE;
-                       addr = mmap_region(file, start, size, vm_flags, pgoff);
+                       addr = mmap_region(file, start, size,
+                                       vma->vm_flags, pgoff);
                        fput(file);
                        if (IS_ERR_VALUE(addr)) {
                                err = addr;
@@ -226,12 +224,6 @@ get_write_lock:
                mutex_unlock(&mapping->i_mmap_mutex);
        }
 
-       if (!(flags & MAP_NONBLOCK) && !(vma->vm_flags & VM_POPULATE)) {
-               if (!has_write_lock)
-                       goto get_write_lock;
-               vma->vm_flags |= VM_POPULATE;
-       }
-
        if (vma->vm_flags & VM_LOCKED) {
                /*
                 * drop PG_Mlocked flag for over-mapped range
index 1c5e33fce6391ec1ea7569b7d324fc76aa9fa288..79b7cf7d1bca72cee9babfb60e21a38799c8eba1 100644 (file)
@@ -358,7 +358,7 @@ static int do_mlock(unsigned long start, size_t len, int on)
 
                newflags = vma->vm_flags & ~VM_LOCKED;
                if (on)
-                       newflags |= VM_LOCKED | VM_POPULATE;
+                       newflags |= VM_LOCKED;
 
                tmp = vma->vm_end;
                if (tmp > end)
@@ -418,8 +418,7 @@ int __mm_populate(unsigned long start, unsigned long len, int ignore_errors)
                 * range with the first VMA. Also, skip undesirable VMA types.
                 */
                nend = min(end, vma->vm_end);
-               if ((vma->vm_flags & (VM_IO | VM_PFNMAP | VM_POPULATE)) !=
-                   VM_POPULATE)
+               if (vma->vm_flags & (VM_IO | VM_PFNMAP))
                        continue;
                if (nstart < vma->vm_start)
                        nstart = vma->vm_start;
@@ -492,9 +491,9 @@ static int do_mlockall(int flags)
        struct vm_area_struct * vma, * prev = NULL;
 
        if (flags & MCL_FUTURE)
-               current->mm->def_flags |= VM_LOCKED | VM_POPULATE;
+               current->mm->def_flags |= VM_LOCKED;
        else
-               current->mm->def_flags &= ~(VM_LOCKED | VM_POPULATE);
+               current->mm->def_flags &= ~VM_LOCKED;
        if (flags == MCL_FUTURE)
                goto out;
 
@@ -503,7 +502,7 @@ static int do_mlockall(int flags)
 
                newflags = vma->vm_flags & ~VM_LOCKED;
                if (flags & MCL_CURRENT)
-                       newflags |= VM_LOCKED | VM_POPULATE;
+                       newflags |= VM_LOCKED;
 
                /* Ignore errors */
                mlock_fixup(vma, &prev, vma->vm_start, vma->vm_end, newflags);
index 2664a47cec93721d6c73aafa85f32c11a5fb13e6..6466699b16cbca1a26c8792f9d484925a23df005 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1306,7 +1306,9 @@ unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
        }
 
        addr = mmap_region(file, addr, len, vm_flags, pgoff);
-       if (!IS_ERR_VALUE(addr) && (vm_flags & VM_POPULATE))
+       if (!IS_ERR_VALUE(addr) &&
+           ((vm_flags & VM_LOCKED) ||
+            (flags & (MAP_POPULATE | MAP_NONBLOCK)) == MAP_POPULATE))
                *populate = len;
        return addr;
 }
index a18714469bf791299f0d60b1a38b9886fdf4dfff..85addcd9372b0d8abfbd277d332408900efdea1d 100644 (file)
@@ -86,13 +86,6 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
 
        grp = &vlan_info->grp;
 
-       /* Take it out of our own structures, but be sure to interlock with
-        * HW accelerating devices or SW vlan input packet processing if
-        * VLAN is not 0 (leave it there for 802.1p).
-        */
-       if (vlan_id)
-               vlan_vid_del(real_dev, vlan_id);
-
        grp->nr_vlan_devs--;
 
        if (vlan->flags & VLAN_FLAG_MVRP)
@@ -114,6 +107,13 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head)
                vlan_gvrp_uninit_applicant(real_dev);
        }
 
+       /* Take it out of our own structures, but be sure to interlock with
+        * HW accelerating devices or SW vlan input packet processing if
+        * VLAN is not 0 (leave it there for 802.1p).
+        */
+       if (vlan_id)
+               vlan_vid_del(real_dev, vlan_id);
+
        /* Get rid of the vlan's reference to real_dev */
        dev_put(real_dev);
 }
index 79d87d8d4f514f5529b57f1b89119a735d068f69..fad0302bdb325e5df700edf4fe323c6226216599 100644 (file)
@@ -359,6 +359,7 @@ static void __sco_sock_close(struct sock *sk)
                        sco_chan_del(sk, ECONNRESET);
                break;
 
+       case BT_CONNECT2:
        case BT_CONNECT:
        case BT_DISCONN:
                sco_chan_del(sk, ECONNRESET);
index b0812c91c0f0ea6d4010722990a044c72d93ba36..bab338e6270df4604efe792f40025a40d7682347 100644 (file)
@@ -423,7 +423,7 @@ static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
                        return 0;
                br_warn(br, "adding interface %s with same address "
                       "as a received packet\n",
-                      source->dev->name);
+                      source ? source->dev->name : br->dev->name);
                fdb_delete(br, fdb);
        }
 
index d540ced1f6c66dc5b84a8ef06c24199e747a0f86..b13e5c766c11359507a61bb9689c9841d660951a 100644 (file)
@@ -1545,7 +1545,6 @@ void net_enable_timestamp(void)
                return;
        }
 #endif
-       WARN_ON(in_interrupt());
        static_key_slow_inc(&netstamp_needed);
 }
 EXPORT_SYMBOL(net_enable_timestamp);
index 9d4c7201400d154ab2fd00ccfab4f22f8bddb5ff..e187bf06d673b0ec37d401a8389bba372a8fb3d9 100644 (file)
@@ -140,6 +140,8 @@ ipv6:
                        flow->ports = *ports;
        }
 
+       flow->thoff = (u16) nhoff;
+
        return true;
 }
 EXPORT_SYMBOL(skb_flow_dissect);
index 905dcc6ad1e3b480c01f87df5157f4e37de112a1..2dc6cdaaae8abc5f31afa57a7ccf765cc978b6ac 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/interrupt.h>
 #include <linux/netdevice.h>
 #include <linux/security.h>
+#include <linux/pid_namespace.h>
 #include <linux/pid.h>
 #include <linux/nsproxy.h>
 #include <linux/slab.h>
@@ -52,7 +53,8 @@ static __inline__ int scm_check_creds(struct ucred *creds)
        if (!uid_valid(uid) || !gid_valid(gid))
                return -EINVAL;
 
-       if ((creds->pid == task_tgid_vnr(current) || nsown_capable(CAP_SYS_ADMIN)) &&
+       if ((creds->pid == task_tgid_vnr(current) ||
+            ns_capable(current->nsproxy->pid_ns->user_ns, CAP_SYS_ADMIN)) &&
            ((uid_eq(uid, cred->uid)   || uid_eq(uid, cred->euid) ||
              uid_eq(uid, cred->suid)) || nsown_capable(CAP_SETUID)) &&
            ((gid_eq(gid, cred->gid)   || gid_eq(gid, cred->egid) ||
index 68f6a94f7661999095d9a02539aee956cd52e8cc..c929d9c1c4b60d719d60066f7ca06e4b7d296f59 100644 (file)
@@ -1333,8 +1333,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb,
                                iph->frag_off |= htons(IP_MF);
                        offset += (skb->len - skb->mac_len - iph->ihl * 4);
                } else  {
-                       if (!(iph->frag_off & htons(IP_DF)))
-                               iph->id = htons(id++);
+                       iph->id = htons(id++);
                }
                iph->tot_len = htons(skb->len - skb->mac_len);
                iph->check = 0;
index 98cbc6877019428f7d3400632c1e81e50145a814..bf6c5cf31aed27ccba4aa25c4d049f0cc037e3cb 100644 (file)
@@ -1522,7 +1522,8 @@ static int __init ip_auto_config(void)
                }
        for (i++; i < CONF_NAMESERVERS_MAX; i++)
                if (ic_nameservers[i] != NONE)
-                       pr_cont(", nameserver%u=%pI4\n", i, &ic_nameservers[i]);
+                       pr_cont(", nameserver%u=%pI4", i, &ic_nameservers[i]);
+       pr_cont("\n");
 #endif /* !SILENT */
 
        return 0;
index ce2d43e1f09f6b4983e6635e6c2b48ca56fcf18b..0d755c50994b2ca01438158e033c020810a3e8af 100644 (file)
@@ -36,19 +36,6 @@ config NF_CONNTRACK_PROC_COMPAT
 
          If unsure, say Y.
 
-config IP_NF_QUEUE
-       tristate "IP Userspace queueing via NETLINK (OBSOLETE)"
-       depends on NETFILTER_ADVANCED
-       help
-         Netfilter has the ability to queue packets to user space: the
-         netlink device can be used to access them using this driver.
-
-         This option enables the old IPv4-only "ip_queue" implementation
-         which has been obsoleted by the new "nfnetlink_queue" code (see
-         CONFIG_NETFILTER_NETLINK_QUEUE).
-
-         To compile it as a module, choose M here.  If unsure, say N.
-
 config IP_NF_IPTABLES
        tristate "IP tables support (required for filtering/masq/NAT)"
        default m if NETFILTER_ADVANCED=n
index 0d9bdacce99f46a77982d89c86a7764fe9ef15f8..3bd55bad230ac7f822f4ea75eb280bc8ce0c07fc 100644 (file)
@@ -2059,11 +2059,8 @@ void tcp_enter_loss(struct sock *sk, int how)
        if (tcp_is_reno(tp))
                tcp_reset_reno_sack(tp);
 
-       if (!how) {
-               /* Push undo marker, if it was plain RTO and nothing
-                * was retransmitted. */
-               tp->undo_marker = tp->snd_una;
-       } else {
+       tp->undo_marker = tp->snd_una;
+       if (how) {
                tp->sacked_out = 0;
                tp->fackets_out = 0;
        }
index 817fbb396bc80077e23b03358355aca6ece6deba..5d0b4387cba6df401166a48f1e4cf3800d6ce6ff 100644 (file)
@@ -1809,8 +1809,11 @@ static bool tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb)
                        goto send_now;
        }
 
-       /* Ok, it looks like it is advisable to defer.  */
-       tp->tso_deferred = 1 | (jiffies << 1);
+       /* Ok, it looks like it is advisable to defer.
+        * Do not rearm the timer if already set to not break TCP ACK clocking.
+        */
+       if (!tp->tso_deferred)
+               tp->tso_deferred = 1 | (jiffies << 1);
 
        return true;
 
index 265c42cf963c30cce55016bbf4ef0a13f57e6ec5..0a073a263720c4eab823db2c09b1b18d7b510bcd 100644 (file)
@@ -1762,9 +1762,16 @@ int udp_rcv(struct sk_buff *skb)
 
 void udp_destroy_sock(struct sock *sk)
 {
+       struct udp_sock *up = udp_sk(sk);
        bool slow = lock_sock_fast(sk);
        udp_flush_pending_frames(sk);
        unlock_sock_fast(sk, slow);
+       if (static_key_false(&udp_encap_needed) && up->encap_type) {
+               void (*encap_destroy)(struct sock *sk);
+               encap_destroy = ACCESS_ONCE(up->encap_destroy);
+               if (encap_destroy)
+                       encap_destroy(sk);
+       }
 }
 
 /*
index f2c7e615f902d861d99529536ecebff35fbd7fd5..26512250e095557e50fbee26cc5dcd65d12cc675 100644 (file)
@@ -4784,26 +4784,20 @@ static void addrconf_sysctl_unregister(struct inet6_dev *idev)
 
 static int __net_init addrconf_init_net(struct net *net)
 {
-       int err;
+       int err = -ENOMEM;
        struct ipv6_devconf *all, *dflt;
 
-       err = -ENOMEM;
-       all = &ipv6_devconf;
-       dflt = &ipv6_devconf_dflt;
+       all = kmemdup(&ipv6_devconf, sizeof(ipv6_devconf), GFP_KERNEL);
+       if (all == NULL)
+               goto err_alloc_all;
 
-       if (!net_eq(net, &init_net)) {
-               all = kmemdup(all, sizeof(ipv6_devconf), GFP_KERNEL);
-               if (all == NULL)
-                       goto err_alloc_all;
+       dflt = kmemdup(&ipv6_devconf_dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL);
+       if (dflt == NULL)
+               goto err_alloc_dflt;
 
-               dflt = kmemdup(dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL);
-               if (dflt == NULL)
-                       goto err_alloc_dflt;
-       } else {
-               /* these will be inherited by all namespaces */
-               dflt->autoconf = ipv6_defaults.autoconf;
-               dflt->disable_ipv6 = ipv6_defaults.disable_ipv6;
-       }
+       /* these will be inherited by all namespaces */
+       dflt->autoconf = ipv6_defaults.autoconf;
+       dflt->disable_ipv6 = ipv6_defaults.disable_ipv6;
 
        net->ipv6.devconf_all = all;
        net->ipv6.devconf_dflt = dflt;
index 83acc1405a18dcef218625e8517431978393ac12..33608c610276d87e9845b75555fadc6771765606 100644 (file)
@@ -114,6 +114,7 @@ ip6t_dnpt_tg(struct sk_buff *skb, const struct xt_action_param *par)
 static struct xt_target ip6t_npt_target_reg[] __read_mostly = {
        {
                .name           = "SNPT",
+               .table          = "mangle",
                .target         = ip6t_snpt_tg,
                .targetsize     = sizeof(struct ip6t_npt_tginfo),
                .checkentry     = ip6t_npt_checkentry,
@@ -124,6 +125,7 @@ static struct xt_target ip6t_npt_target_reg[] __read_mostly = {
        },
        {
                .name           = "DNPT",
+               .table          = "mangle",
                .target         = ip6t_dnpt_tg,
                .targetsize     = sizeof(struct ip6t_npt_tginfo),
                .checkentry     = ip6t_npt_checkentry,
index 599e1ba6d1ceaa6766d53eda020a69a0aa234e5b..d8e5e852fc7a08b26879c81a4ecaad0be2cf2f90 100644 (file)
@@ -1285,10 +1285,18 @@ do_confirm:
 
 void udpv6_destroy_sock(struct sock *sk)
 {
+       struct udp_sock *up = udp_sk(sk);
        lock_sock(sk);
        udp_v6_flush_pending_frames(sk);
        release_sock(sk);
 
+       if (static_key_false(&udpv6_encap_needed) && up->encap_type) {
+               void (*encap_destroy)(struct sock *sk);
+               encap_destroy = ACCESS_ONCE(up->encap_destroy);
+               if (encap_destroy)
+                       encap_destroy(sk);
+       }
+
        inet6_destroy_sock(sk);
 }
 
index d07e3a626446b3cab44e68b019f7870619699f75..d28e7f014cc639779a4557203b4b2ba2f7e63927 100644 (file)
@@ -2583,8 +2583,10 @@ bed:
                                    NULL, NULL, NULL);
 
                /* Check if the we got some results */
-               if (!self->cachedaddr)
-                       return -EAGAIN;         /* Didn't find any devices */
+               if (!self->cachedaddr) {
+                       err = -EAGAIN;          /* Didn't find any devices */
+                       goto out;
+               }
                daddr = self->cachedaddr;
                /* Cleanup */
                self->cachedaddr = 0;
index d36875f3427e82b7795012bebe8281318f983d22..8aecf5df66569a6ca0ae1b8921e20954d6812336 100644 (file)
@@ -114,7 +114,6 @@ struct l2tp_net {
 
 static void l2tp_session_set_header_len(struct l2tp_session *session, int version);
 static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel);
-static void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel);
 
 static inline struct l2tp_net *l2tp_pernet(struct net *net)
 {
@@ -192,6 +191,7 @@ struct sock *l2tp_tunnel_sock_lookup(struct l2tp_tunnel *tunnel)
        } else {
                /* Socket is owned by kernelspace */
                sk = tunnel->sock;
+               sock_hold(sk);
        }
 
 out:
@@ -210,6 +210,7 @@ void l2tp_tunnel_sock_put(struct sock *sk)
                }
                sock_put(sk);
        }
+       sock_put(sk);
 }
 EXPORT_SYMBOL_GPL(l2tp_tunnel_sock_put);
 
@@ -373,10 +374,8 @@ static void l2tp_recv_queue_skb(struct l2tp_session *session, struct sk_buff *sk
        struct sk_buff *skbp;
        struct sk_buff *tmp;
        u32 ns = L2TP_SKB_CB(skb)->ns;
-       struct l2tp_stats *sstats;
 
        spin_lock_bh(&session->reorder_q.lock);
-       sstats = &session->stats;
        skb_queue_walk_safe(&session->reorder_q, skbp, tmp) {
                if (L2TP_SKB_CB(skbp)->ns > ns) {
                        __skb_queue_before(&session->reorder_q, skbp, skb);
@@ -384,9 +383,7 @@ static void l2tp_recv_queue_skb(struct l2tp_session *session, struct sk_buff *sk
                                 "%s: pkt %hu, inserted before %hu, reorder_q len=%d\n",
                                 session->name, ns, L2TP_SKB_CB(skbp)->ns,
                                 skb_queue_len(&session->reorder_q));
-                       u64_stats_update_begin(&sstats->syncp);
-                       sstats->rx_oos_packets++;
-                       u64_stats_update_end(&sstats->syncp);
+                       atomic_long_inc(&session->stats.rx_oos_packets);
                        goto out;
                }
        }
@@ -403,23 +400,16 @@ static void l2tp_recv_dequeue_skb(struct l2tp_session *session, struct sk_buff *
 {
        struct l2tp_tunnel *tunnel = session->tunnel;
        int length = L2TP_SKB_CB(skb)->length;
-       struct l2tp_stats *tstats, *sstats;
 
        /* We're about to requeue the skb, so return resources
         * to its current owner (a socket receive buffer).
         */
        skb_orphan(skb);
 
-       tstats = &tunnel->stats;
-       u64_stats_update_begin(&tstats->syncp);
-       sstats = &session->stats;
-       u64_stats_update_begin(&sstats->syncp);
-       tstats->rx_packets++;
-       tstats->rx_bytes += length;
-       sstats->rx_packets++;
-       sstats->rx_bytes += length;
-       u64_stats_update_end(&tstats->syncp);
-       u64_stats_update_end(&sstats->syncp);
+       atomic_long_inc(&tunnel->stats.rx_packets);
+       atomic_long_add(length, &tunnel->stats.rx_bytes);
+       atomic_long_inc(&session->stats.rx_packets);
+       atomic_long_add(length, &session->stats.rx_bytes);
 
        if (L2TP_SKB_CB(skb)->has_seq) {
                /* Bump our Nr */
@@ -450,7 +440,6 @@ static void l2tp_recv_dequeue(struct l2tp_session *session)
 {
        struct sk_buff *skb;
        struct sk_buff *tmp;
-       struct l2tp_stats *sstats;
 
        /* If the pkt at the head of the queue has the nr that we
         * expect to send up next, dequeue it and any other
@@ -458,13 +447,10 @@ static void l2tp_recv_dequeue(struct l2tp_session *session)
         */
 start:
        spin_lock_bh(&session->reorder_q.lock);
-       sstats = &session->stats;
        skb_queue_walk_safe(&session->reorder_q, skb, tmp) {
                if (time_after(jiffies, L2TP_SKB_CB(skb)->expires)) {
-                       u64_stats_update_begin(&sstats->syncp);
-                       sstats->rx_seq_discards++;
-                       sstats->rx_errors++;
-                       u64_stats_update_end(&sstats->syncp);
+                       atomic_long_inc(&session->stats.rx_seq_discards);
+                       atomic_long_inc(&session->stats.rx_errors);
                        l2tp_dbg(session, L2TP_MSG_SEQ,
                                 "%s: oos pkt %u len %d discarded (too old), waiting for %u, reorder_q_len=%d\n",
                                 session->name, L2TP_SKB_CB(skb)->ns,
@@ -623,7 +609,6 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
        struct l2tp_tunnel *tunnel = session->tunnel;
        int offset;
        u32 ns, nr;
-       struct l2tp_stats *sstats = &session->stats;
 
        /* The ref count is increased since we now hold a pointer to
         * the session. Take care to decrement the refcnt when exiting
@@ -640,9 +625,7 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
                                  "%s: cookie mismatch (%u/%u). Discarding.\n",
                                  tunnel->name, tunnel->tunnel_id,
                                  session->session_id);
-                       u64_stats_update_begin(&sstats->syncp);
-                       sstats->rx_cookie_discards++;
-                       u64_stats_update_end(&sstats->syncp);
+                       atomic_long_inc(&session->stats.rx_cookie_discards);
                        goto discard;
                }
                ptr += session->peer_cookie_len;
@@ -711,9 +694,7 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
                        l2tp_warn(session, L2TP_MSG_SEQ,
                                  "%s: recv data has no seq numbers when required. Discarding.\n",
                                  session->name);
-                       u64_stats_update_begin(&sstats->syncp);
-                       sstats->rx_seq_discards++;
-                       u64_stats_update_end(&sstats->syncp);
+                       atomic_long_inc(&session->stats.rx_seq_discards);
                        goto discard;
                }
 
@@ -732,9 +713,7 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
                        l2tp_warn(session, L2TP_MSG_SEQ,
                                  "%s: recv data has no seq numbers when required. Discarding.\n",
                                  session->name);
-                       u64_stats_update_begin(&sstats->syncp);
-                       sstats->rx_seq_discards++;
-                       u64_stats_update_end(&sstats->syncp);
+                       atomic_long_inc(&session->stats.rx_seq_discards);
                        goto discard;
                }
        }
@@ -788,9 +767,7 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
                         * packets
                         */
                        if (L2TP_SKB_CB(skb)->ns != session->nr) {
-                               u64_stats_update_begin(&sstats->syncp);
-                               sstats->rx_seq_discards++;
-                               u64_stats_update_end(&sstats->syncp);
+                               atomic_long_inc(&session->stats.rx_seq_discards);
                                l2tp_dbg(session, L2TP_MSG_SEQ,
                                         "%s: oos pkt %u len %d discarded, waiting for %u, reorder_q_len=%d\n",
                                         session->name, L2TP_SKB_CB(skb)->ns,
@@ -816,9 +793,7 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb,
        return;
 
 discard:
-       u64_stats_update_begin(&sstats->syncp);
-       sstats->rx_errors++;
-       u64_stats_update_end(&sstats->syncp);
+       atomic_long_inc(&session->stats.rx_errors);
        kfree_skb(skb);
 
        if (session->deref)
@@ -828,6 +803,23 @@ discard:
 }
 EXPORT_SYMBOL(l2tp_recv_common);
 
+/* Drop skbs from the session's reorder_q
+ */
+int l2tp_session_queue_purge(struct l2tp_session *session)
+{
+       struct sk_buff *skb = NULL;
+       BUG_ON(!session);
+       BUG_ON(session->magic != L2TP_SESSION_MAGIC);
+       while ((skb = skb_dequeue(&session->reorder_q))) {
+               atomic_long_inc(&session->stats.rx_errors);
+               kfree_skb(skb);
+               if (session->deref)
+                       (*session->deref)(session);
+       }
+       return 0;
+}
+EXPORT_SYMBOL_GPL(l2tp_session_queue_purge);
+
 /* Internal UDP receive frame. Do the real work of receiving an L2TP data frame
  * here. The skb is not on a list when we get here.
  * Returns 0 if the packet was a data packet and was successfully passed on.
@@ -843,7 +835,6 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,
        u32 tunnel_id, session_id;
        u16 version;
        int length;
-       struct l2tp_stats *tstats;
 
        if (tunnel->sock && l2tp_verify_udp_checksum(tunnel->sock, skb))
                goto discard_bad_csum;
@@ -932,10 +923,7 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb,
 discard_bad_csum:
        LIMIT_NETDEBUG("%s: UDP: bad checksum\n", tunnel->name);
        UDP_INC_STATS_USER(tunnel->l2tp_net, UDP_MIB_INERRORS, 0);
-       tstats = &tunnel->stats;
-       u64_stats_update_begin(&tstats->syncp);
-       tstats->rx_errors++;
-       u64_stats_update_end(&tstats->syncp);
+       atomic_long_inc(&tunnel->stats.rx_errors);
        kfree_skb(skb);
 
        return 0;
@@ -1062,7 +1050,6 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb,
        struct l2tp_tunnel *tunnel = session->tunnel;
        unsigned int len = skb->len;
        int error;
-       struct l2tp_stats *tstats, *sstats;
 
        /* Debug */
        if (session->send_seq)
@@ -1091,21 +1078,15 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb,
                error = ip_queue_xmit(skb, fl);
 
        /* Update stats */
-       tstats = &tunnel->stats;
-       u64_stats_update_begin(&tstats->syncp);
-       sstats = &session->stats;
-       u64_stats_update_begin(&sstats->syncp);
        if (error >= 0) {
-               tstats->tx_packets++;
-               tstats->tx_bytes += len;
-               sstats->tx_packets++;
-               sstats->tx_bytes += len;
+               atomic_long_inc(&tunnel->stats.tx_packets);
+               atomic_long_add(len, &tunnel->stats.tx_bytes);
+               atomic_long_inc(&session->stats.tx_packets);
+               atomic_long_add(len, &session->stats.tx_bytes);
        } else {
-               tstats->tx_errors++;
-               sstats->tx_errors++;
+               atomic_long_inc(&tunnel->stats.tx_errors);
+               atomic_long_inc(&session->stats.tx_errors);
        }
-       u64_stats_update_end(&tstats->syncp);
-       u64_stats_update_end(&sstats->syncp);
 
        return 0;
 }
@@ -1282,6 +1263,7 @@ static void l2tp_tunnel_destruct(struct sock *sk)
                /* No longer an encapsulation socket. See net/ipv4/udp.c */
                (udp_sk(sk))->encap_type = 0;
                (udp_sk(sk))->encap_rcv = NULL;
+               (udp_sk(sk))->encap_destroy = NULL;
                break;
        case L2TP_ENCAPTYPE_IP:
                break;
@@ -1311,7 +1293,7 @@ end:
 
 /* When the tunnel is closed, all the attached sessions need to go too.
  */
-static void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel)
+void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel)
 {
        int hash;
        struct hlist_node *walk;
@@ -1334,25 +1316,13 @@ again:
 
                        hlist_del_init(&session->hlist);
 
-                       /* Since we should hold the sock lock while
-                        * doing any unbinding, we need to release the
-                        * lock we're holding before taking that lock.
-                        * Hold a reference to the sock so it doesn't
-                        * disappear as we're jumping between locks.
-                        */
                        if (session->ref != NULL)
                                (*session->ref)(session);
 
                        write_unlock_bh(&tunnel->hlist_lock);
 
-                       if (tunnel->version != L2TP_HDR_VER_2) {
-                               struct l2tp_net *pn = l2tp_pernet(tunnel->l2tp_net);
-
-                               spin_lock_bh(&pn->l2tp_session_hlist_lock);
-                               hlist_del_init_rcu(&session->global_hlist);
-                               spin_unlock_bh(&pn->l2tp_session_hlist_lock);
-                               synchronize_rcu();
-                       }
+                       __l2tp_session_unhash(session);
+                       l2tp_session_queue_purge(session);
 
                        if (session->session_close != NULL)
                                (*session->session_close)(session);
@@ -1360,6 +1330,8 @@ again:
                        if (session->deref != NULL)
                                (*session->deref)(session);
 
+                       l2tp_session_dec_refcount(session);
+
                        write_lock_bh(&tunnel->hlist_lock);
 
                        /* Now restart from the beginning of this hash
@@ -1372,6 +1344,17 @@ again:
        }
        write_unlock_bh(&tunnel->hlist_lock);
 }
+EXPORT_SYMBOL_GPL(l2tp_tunnel_closeall);
+
+/* Tunnel socket destroy hook for UDP encapsulation */
+static void l2tp_udp_encap_destroy(struct sock *sk)
+{
+       struct l2tp_tunnel *tunnel = l2tp_sock_to_tunnel(sk);
+       if (tunnel) {
+               l2tp_tunnel_closeall(tunnel);
+               sock_put(sk);
+       }
+}
 
 /* Really kill the tunnel.
  * Come here only when all sessions have been cleared from the tunnel.
@@ -1397,19 +1380,21 @@ static void l2tp_tunnel_del_work(struct work_struct *work)
                return;
 
        sock = sk->sk_socket;
-       BUG_ON(!sock);
 
-       /* If the tunnel socket was created directly by the kernel, use the
-        * sk_* API to release the socket now.  Otherwise go through the
-        * inet_* layer to shut the socket down, and let userspace close it.
+       /* If the tunnel socket was created by userspace, then go through the
+        * inet layer to shut the socket down, and let userspace close it.
+        * Otherwise, if we created the socket directly within the kernel, use
+        * the sk API to release it here.
         * In either case the tunnel resources are freed in the socket
         * destructor when the tunnel socket goes away.
         */
-       if (sock->file == NULL) {
-               kernel_sock_shutdown(sock, SHUT_RDWR);
-               sk_release_kernel(sk);
+       if (tunnel->fd >= 0) {
+               if (sock)
+                       inet_shutdown(sock, 2);
        } else {
-               inet_shutdown(sock, 2);
+               if (sock)
+                       kernel_sock_shutdown(sock, SHUT_RDWR);
+               sk_release_kernel(sk);
        }
 
        l2tp_tunnel_sock_put(sk);
@@ -1668,6 +1653,7 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
                /* Mark socket as an encapsulation socket. See net/ipv4/udp.c */
                udp_sk(sk)->encap_type = UDP_ENCAP_L2TPINUDP;
                udp_sk(sk)->encap_rcv = l2tp_udp_encap_recv;
+               udp_sk(sk)->encap_destroy = l2tp_udp_encap_destroy;
 #if IS_ENABLED(CONFIG_IPV6)
                if (sk->sk_family == PF_INET6)
                        udpv6_encap_enable();
@@ -1723,6 +1709,7 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_create);
  */
 int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel)
 {
+       l2tp_tunnel_closeall(tunnel);
        return (false == queue_work(l2tp_wq, &tunnel->del_work));
 }
 EXPORT_SYMBOL_GPL(l2tp_tunnel_delete);
@@ -1731,62 +1718,71 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_delete);
  */
 void l2tp_session_free(struct l2tp_session *session)
 {
-       struct l2tp_tunnel *tunnel;
+       struct l2tp_tunnel *tunnel = session->tunnel;
 
        BUG_ON(atomic_read(&session->ref_count) != 0);
 
-       tunnel = session->tunnel;
-       if (tunnel != NULL) {
+       if (tunnel) {
                BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC);
+               if (session->session_id != 0)
+                       atomic_dec(&l2tp_session_count);
+               sock_put(tunnel->sock);
+               session->tunnel = NULL;
+               l2tp_tunnel_dec_refcount(tunnel);
+       }
+
+       kfree(session);
 
-               /* Delete the session from the hash */
+       return;
+}
+EXPORT_SYMBOL_GPL(l2tp_session_free);
+
+/* Remove an l2tp session from l2tp_core's hash lists.
+ * Provides a tidyup interface for pseudowire code which can't just route all
+ * shutdown via. l2tp_session_delete and a pseudowire-specific session_close
+ * callback.
+ */
+void __l2tp_session_unhash(struct l2tp_session *session)
+{
+       struct l2tp_tunnel *tunnel = session->tunnel;
+
+       /* Remove the session from core hashes */
+       if (tunnel) {
+               /* Remove from the per-tunnel hash */
                write_lock_bh(&tunnel->hlist_lock);
                hlist_del_init(&session->hlist);
                write_unlock_bh(&tunnel->hlist_lock);
 
-               /* Unlink from the global hash if not L2TPv2 */
+               /* For L2TPv3 we have a per-net hash: remove from there, too */
                if (tunnel->version != L2TP_HDR_VER_2) {
                        struct l2tp_net *pn = l2tp_pernet(tunnel->l2tp_net);
-
                        spin_lock_bh(&pn->l2tp_session_hlist_lock);
                        hlist_del_init_rcu(&session->global_hlist);
                        spin_unlock_bh(&pn->l2tp_session_hlist_lock);
                        synchronize_rcu();
                }
-
-               if (session->session_id != 0)
-                       atomic_dec(&l2tp_session_count);
-
-               sock_put(tunnel->sock);
-
-               /* This will delete the tunnel context if this
-                * is the last session on the tunnel.
-                */
-               session->tunnel = NULL;
-               l2tp_tunnel_dec_refcount(tunnel);
        }
-
-       kfree(session);
-
-       return;
 }
-EXPORT_SYMBOL_GPL(l2tp_session_free);
+EXPORT_SYMBOL_GPL(__l2tp_session_unhash);
 
 /* This function is used by the netlink SESSION_DELETE command and by
    pseudowire modules.
  */
 int l2tp_session_delete(struct l2tp_session *session)
 {
+       if (session->ref)
+               (*session->ref)(session);
+       __l2tp_session_unhash(session);
+       l2tp_session_queue_purge(session);
        if (session->session_close != NULL)
                (*session->session_close)(session);
-
+       if (session->deref)
+               (*session->ref)(session);
        l2tp_session_dec_refcount(session);
-
        return 0;
 }
 EXPORT_SYMBOL_GPL(l2tp_session_delete);
 
-
 /* We come here whenever a session's send_seq, cookie_len or
  * l2specific_len parameters are set.
  */
index 8eb8f1d47f3ac2d6ce32ae287e120a93aa931b40..485a490fd990eeb91a3577e65844c17d1350f720 100644 (file)
@@ -36,16 +36,15 @@ enum {
 struct sk_buff;
 
 struct l2tp_stats {
-       u64                     tx_packets;
-       u64                     tx_bytes;
-       u64                     tx_errors;
-       u64                     rx_packets;
-       u64                     rx_bytes;
-       u64                     rx_seq_discards;
-       u64                     rx_oos_packets;
-       u64                     rx_errors;
-       u64                     rx_cookie_discards;
-       struct u64_stats_sync   syncp;
+       atomic_long_t           tx_packets;
+       atomic_long_t           tx_bytes;
+       atomic_long_t           tx_errors;
+       atomic_long_t           rx_packets;
+       atomic_long_t           rx_bytes;
+       atomic_long_t           rx_seq_discards;
+       atomic_long_t           rx_oos_packets;
+       atomic_long_t           rx_errors;
+       atomic_long_t           rx_cookie_discards;
 };
 
 struct l2tp_tunnel;
@@ -240,11 +239,14 @@ extern struct l2tp_tunnel *l2tp_tunnel_find(struct net *net, u32 tunnel_id);
 extern struct l2tp_tunnel *l2tp_tunnel_find_nth(struct net *net, int nth);
 
 extern int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg, struct l2tp_tunnel **tunnelp);
+extern void l2tp_tunnel_closeall(struct l2tp_tunnel *tunnel);
 extern int l2tp_tunnel_delete(struct l2tp_tunnel *tunnel);
 extern struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunnel, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg);
+extern void __l2tp_session_unhash(struct l2tp_session *session);
 extern int l2tp_session_delete(struct l2tp_session *session);
 extern void l2tp_session_free(struct l2tp_session *session);
 extern void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, unsigned char *ptr, unsigned char *optr, u16 hdrflags, int length, int (*payload_hook)(struct sk_buff *skb));
+extern int l2tp_session_queue_purge(struct l2tp_session *session);
 extern int l2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb);
 
 extern int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len);
index c3813bc84552cebc56691cae4eae3097b29d2160..072d7202e182ffa2125fe7de9c54c584626fdeb0 100644 (file)
@@ -146,14 +146,14 @@ static void l2tp_dfs_seq_tunnel_show(struct seq_file *m, void *v)
                   tunnel->sock ? atomic_read(&tunnel->sock->sk_refcnt) : 0,
                   atomic_read(&tunnel->ref_count));
 
-       seq_printf(m, " %08x rx %llu/%llu/%llu rx %llu/%llu/%llu\n",
+       seq_printf(m, " %08x rx %ld/%ld/%ld rx %ld/%ld/%ld\n",
                   tunnel->debug,
-                  (unsigned long long)tunnel->stats.tx_packets,
-                  (unsigned long long)tunnel->stats.tx_bytes,
-                  (unsigned long long)tunnel->stats.tx_errors,
-                  (unsigned long long)tunnel->stats.rx_packets,
-                  (unsigned long long)tunnel->stats.rx_bytes,
-                  (unsigned long long)tunnel->stats.rx_errors);
+                  atomic_long_read(&tunnel->stats.tx_packets),
+                  atomic_long_read(&tunnel->stats.tx_bytes),
+                  atomic_long_read(&tunnel->stats.tx_errors),
+                  atomic_long_read(&tunnel->stats.rx_packets),
+                  atomic_long_read(&tunnel->stats.rx_bytes),
+                  atomic_long_read(&tunnel->stats.rx_errors));
 
        if (tunnel->show != NULL)
                tunnel->show(m, tunnel);
@@ -203,14 +203,14 @@ static void l2tp_dfs_seq_session_show(struct seq_file *m, void *v)
                seq_printf(m, "\n");
        }
 
-       seq_printf(m, "   %hu/%hu tx %llu/%llu/%llu rx %llu/%llu/%llu\n",
+       seq_printf(m, "   %hu/%hu tx %ld/%ld/%ld rx %ld/%ld/%ld\n",
                   session->nr, session->ns,
-                  (unsigned long long)session->stats.tx_packets,
-                  (unsigned long long)session->stats.tx_bytes,
-                  (unsigned long long)session->stats.tx_errors,
-                  (unsigned long long)session->stats.rx_packets,
-                  (unsigned long long)session->stats.rx_bytes,
-                  (unsigned long long)session->stats.rx_errors);
+                  atomic_long_read(&session->stats.tx_packets),
+                  atomic_long_read(&session->stats.tx_bytes),
+                  atomic_long_read(&session->stats.tx_errors),
+                  atomic_long_read(&session->stats.rx_packets),
+                  atomic_long_read(&session->stats.rx_bytes),
+                  atomic_long_read(&session->stats.rx_errors));
 
        if (session->show != NULL)
                session->show(m, session);
index 7f41b7051269539efa0780b618be0b60e7788e76..571db8dd2292a7c5b1f2e940073edce370b13699 100644 (file)
@@ -228,10 +228,16 @@ static void l2tp_ip_close(struct sock *sk, long timeout)
 static void l2tp_ip_destroy_sock(struct sock *sk)
 {
        struct sk_buff *skb;
+       struct l2tp_tunnel *tunnel = l2tp_sock_to_tunnel(sk);
 
        while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL)
                kfree_skb(skb);
 
+       if (tunnel) {
+               l2tp_tunnel_closeall(tunnel);
+               sock_put(sk);
+       }
+
        sk_refcnt_debug_dec(sk);
 }
 
index 41f2f8126ebc720933638f67eb800f17797987e7..c74f5a91ff6a3213209c23ff488f0b475a552857 100644 (file)
@@ -241,10 +241,17 @@ static void l2tp_ip6_close(struct sock *sk, long timeout)
 
 static void l2tp_ip6_destroy_sock(struct sock *sk)
 {
+       struct l2tp_tunnel *tunnel = l2tp_sock_to_tunnel(sk);
+
        lock_sock(sk);
        ip6_flush_pending_frames(sk);
        release_sock(sk);
 
+       if (tunnel) {
+               l2tp_tunnel_closeall(tunnel);
+               sock_put(sk);
+       }
+
        inet6_destroy_sock(sk);
 }
 
index c1bab22db85e79765581079468a36231e5f3d608..0825ff26e113f3e2acdbbe2b88bd0f4fbfd92410 100644 (file)
@@ -246,8 +246,6 @@ static int l2tp_nl_tunnel_send(struct sk_buff *skb, u32 portid, u32 seq, int fla
 #if IS_ENABLED(CONFIG_IPV6)
        struct ipv6_pinfo *np = NULL;
 #endif
-       struct l2tp_stats stats;
-       unsigned int start;
 
        hdr = genlmsg_put(skb, portid, seq, &l2tp_nl_family, flags,
                          L2TP_CMD_TUNNEL_GET);
@@ -265,28 +263,22 @@ static int l2tp_nl_tunnel_send(struct sk_buff *skb, u32 portid, u32 seq, int fla
        if (nest == NULL)
                goto nla_put_failure;
 
-       do {
-               start = u64_stats_fetch_begin(&tunnel->stats.syncp);
-               stats.tx_packets = tunnel->stats.tx_packets;
-               stats.tx_bytes = tunnel->stats.tx_bytes;
-               stats.tx_errors = tunnel->stats.tx_errors;
-               stats.rx_packets = tunnel->stats.rx_packets;
-               stats.rx_bytes = tunnel->stats.rx_bytes;
-               stats.rx_errors = tunnel->stats.rx_errors;
-               stats.rx_seq_discards = tunnel->stats.rx_seq_discards;
-               stats.rx_oos_packets = tunnel->stats.rx_oos_packets;
-       } while (u64_stats_fetch_retry(&tunnel->stats.syncp, start));
-
-       if (nla_put_u64(skb, L2TP_ATTR_TX_PACKETS, stats.tx_packets) ||
-           nla_put_u64(skb, L2TP_ATTR_TX_BYTES, stats.tx_bytes) ||
-           nla_put_u64(skb, L2TP_ATTR_TX_ERRORS, stats.tx_errors) ||
-           nla_put_u64(skb, L2TP_ATTR_RX_PACKETS, stats.rx_packets) ||
-           nla_put_u64(skb, L2TP_ATTR_RX_BYTES, stats.rx_bytes) ||
+       if (nla_put_u64(skb, L2TP_ATTR_TX_PACKETS,
+                   atomic_long_read(&tunnel->stats.tx_packets)) ||
+           nla_put_u64(skb, L2TP_ATTR_TX_BYTES,
+                   atomic_long_read(&tunnel->stats.tx_bytes)) ||
+           nla_put_u64(skb, L2TP_ATTR_TX_ERRORS,
+                   atomic_long_read(&tunnel->stats.tx_errors)) ||
+           nla_put_u64(skb, L2TP_ATTR_RX_PACKETS,
+                   atomic_long_read(&tunnel->stats.rx_packets)) ||
+           nla_put_u64(skb, L2TP_ATTR_RX_BYTES,
+                   atomic_long_read(&tunnel->stats.rx_bytes)) ||
            nla_put_u64(skb, L2TP_ATTR_RX_SEQ_DISCARDS,
-                       stats.rx_seq_discards) ||
+                   atomic_long_read(&tunnel->stats.rx_seq_discards)) ||
            nla_put_u64(skb, L2TP_ATTR_RX_OOS_PACKETS,
-                       stats.rx_oos_packets) ||
-           nla_put_u64(skb, L2TP_ATTR_RX_ERRORS, stats.rx_errors))
+                   atomic_long_read(&tunnel->stats.rx_oos_packets)) ||
+           nla_put_u64(skb, L2TP_ATTR_RX_ERRORS,
+                   atomic_long_read(&tunnel->stats.rx_errors)))
                goto nla_put_failure;
        nla_nest_end(skb, nest);
 
@@ -612,8 +604,6 @@ static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int fl
        struct nlattr *nest;
        struct l2tp_tunnel *tunnel = session->tunnel;
        struct sock *sk = NULL;
-       struct l2tp_stats stats;
-       unsigned int start;
 
        sk = tunnel->sock;
 
@@ -656,28 +646,22 @@ static int l2tp_nl_session_send(struct sk_buff *skb, u32 portid, u32 seq, int fl
        if (nest == NULL)
                goto nla_put_failure;
 
-       do {
-               start = u64_stats_fetch_begin(&session->stats.syncp);
-               stats.tx_packets = session->stats.tx_packets;
-               stats.tx_bytes = session->stats.tx_bytes;
-               stats.tx_errors = session->stats.tx_errors;
-               stats.rx_packets = session->stats.rx_packets;
-               stats.rx_bytes = session->stats.rx_bytes;
-               stats.rx_errors = session->stats.rx_errors;
-               stats.rx_seq_discards = session->stats.rx_seq_discards;
-               stats.rx_oos_packets = session->stats.rx_oos_packets;
-       } while (u64_stats_fetch_retry(&session->stats.syncp, start));
-
-       if (nla_put_u64(skb, L2TP_ATTR_TX_PACKETS, stats.tx_packets) ||
-           nla_put_u64(skb, L2TP_ATTR_TX_BYTES, stats.tx_bytes) ||
-           nla_put_u64(skb, L2TP_ATTR_TX_ERRORS, stats.tx_errors) ||
-           nla_put_u64(skb, L2TP_ATTR_RX_PACKETS, stats.rx_packets) ||
-           nla_put_u64(skb, L2TP_ATTR_RX_BYTES, stats.rx_bytes) ||
+       if (nla_put_u64(skb, L2TP_ATTR_TX_PACKETS,
+               atomic_long_read(&session->stats.tx_packets)) ||
+           nla_put_u64(skb, L2TP_ATTR_TX_BYTES,
+               atomic_long_read(&session->stats.tx_bytes)) ||
+           nla_put_u64(skb, L2TP_ATTR_TX_ERRORS,
+               atomic_long_read(&session->stats.tx_errors)) ||
+           nla_put_u64(skb, L2TP_ATTR_RX_PACKETS,
+               atomic_long_read(&session->stats.rx_packets)) ||
+           nla_put_u64(skb, L2TP_ATTR_RX_BYTES,
+               atomic_long_read(&session->stats.rx_bytes)) ||
            nla_put_u64(skb, L2TP_ATTR_RX_SEQ_DISCARDS,
-                       stats.rx_seq_discards) ||
+               atomic_long_read(&session->stats.rx_seq_discards)) ||
            nla_put_u64(skb, L2TP_ATTR_RX_OOS_PACKETS,
-                       stats.rx_oos_packets) ||
-           nla_put_u64(skb, L2TP_ATTR_RX_ERRORS, stats.rx_errors))
+               atomic_long_read(&session->stats.rx_oos_packets)) ||
+           nla_put_u64(skb, L2TP_ATTR_RX_ERRORS,
+               atomic_long_read(&session->stats.rx_errors)))
                goto nla_put_failure;
        nla_nest_end(skb, nest);
 
index 6a53371dba1f1b357f9cd4f34b7af166ed324eab..637a341c1e2d1a466c68efcb50d7fc201198a15b 100644 (file)
@@ -97,6 +97,7 @@
 #include <net/ip.h>
 #include <net/udp.h>
 #include <net/xfrm.h>
+#include <net/inet_common.h>
 
 #include <asm/byteorder.h>
 #include <linux/atomic.h>
@@ -259,7 +260,7 @@ static void pppol2tp_recv(struct l2tp_session *session, struct sk_buff *skb, int
                          session->name);
 
                /* Not bound. Nothing we can do, so discard. */
-               session->stats.rx_errors++;
+               atomic_long_inc(&session->stats.rx_errors);
                kfree_skb(skb);
        }
 
@@ -447,34 +448,16 @@ static void pppol2tp_session_close(struct l2tp_session *session)
 {
        struct pppol2tp_session *ps = l2tp_session_priv(session);
        struct sock *sk = ps->sock;
-       struct sk_buff *skb;
+       struct socket *sock = sk->sk_socket;
 
        BUG_ON(session->magic != L2TP_SESSION_MAGIC);
 
-       if (session->session_id == 0)
-               goto out;
-
-       if (sk != NULL) {
-               lock_sock(sk);
-
-               if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
-                       pppox_unbind_sock(sk);
-                       sk->sk_state = PPPOX_DEAD;
-                       sk->sk_state_change(sk);
-               }
-
-               /* Purge any queued data */
-               skb_queue_purge(&sk->sk_receive_queue);
-               skb_queue_purge(&sk->sk_write_queue);
-               while ((skb = skb_dequeue(&session->reorder_q))) {
-                       kfree_skb(skb);
-                       sock_put(sk);
-               }
 
-               release_sock(sk);
+       if (sock) {
+               inet_shutdown(sock, 2);
+               /* Don't let the session go away before our socket does */
+               l2tp_session_inc_refcount(session);
        }
-
-out:
        return;
 }
 
@@ -483,19 +466,12 @@ out:
  */
 static void pppol2tp_session_destruct(struct sock *sk)
 {
-       struct l2tp_session *session;
-
-       if (sk->sk_user_data != NULL) {
-               session = sk->sk_user_data;
-               if (session == NULL)
-                       goto out;
-
+       struct l2tp_session *session = sk->sk_user_data;
+       if (session) {
                sk->sk_user_data = NULL;
                BUG_ON(session->magic != L2TP_SESSION_MAGIC);
                l2tp_session_dec_refcount(session);
        }
-
-out:
        return;
 }
 
@@ -525,16 +501,13 @@ static int pppol2tp_release(struct socket *sock)
        session = pppol2tp_sock_to_session(sk);
 
        /* Purge any queued data */
-       skb_queue_purge(&sk->sk_receive_queue);
-       skb_queue_purge(&sk->sk_write_queue);
        if (session != NULL) {
-               struct sk_buff *skb;
-               while ((skb = skb_dequeue(&session->reorder_q))) {
-                       kfree_skb(skb);
-                       sock_put(sk);
-               }
+               __l2tp_session_unhash(session);
+               l2tp_session_queue_purge(session);
                sock_put(sk);
        }
+       skb_queue_purge(&sk->sk_receive_queue);
+       skb_queue_purge(&sk->sk_write_queue);
 
        release_sock(sk);
 
@@ -880,18 +853,6 @@ out:
        return error;
 }
 
-/* Called when deleting sessions via the netlink interface.
- */
-static int pppol2tp_session_delete(struct l2tp_session *session)
-{
-       struct pppol2tp_session *ps = l2tp_session_priv(session);
-
-       if (ps->sock == NULL)
-               l2tp_session_dec_refcount(session);
-
-       return 0;
-}
-
 #endif /* CONFIG_L2TP_V3 */
 
 /* getname() support.
@@ -1025,14 +986,14 @@ end:
 static void pppol2tp_copy_stats(struct pppol2tp_ioc_stats *dest,
                                struct l2tp_stats *stats)
 {
-       dest->tx_packets = stats->tx_packets;
-       dest->tx_bytes = stats->tx_bytes;
-       dest->tx_errors = stats->tx_errors;
-       dest->rx_packets = stats->rx_packets;
-       dest->rx_bytes = stats->rx_bytes;
-       dest->rx_seq_discards = stats->rx_seq_discards;
-       dest->rx_oos_packets = stats->rx_oos_packets;
-       dest->rx_errors = stats->rx_errors;
+       dest->tx_packets = atomic_long_read(&stats->tx_packets);
+       dest->tx_bytes = atomic_long_read(&stats->tx_bytes);
+       dest->tx_errors = atomic_long_read(&stats->tx_errors);
+       dest->rx_packets = atomic_long_read(&stats->rx_packets);
+       dest->rx_bytes = atomic_long_read(&stats->rx_bytes);
+       dest->rx_seq_discards = atomic_long_read(&stats->rx_seq_discards);
+       dest->rx_oos_packets = atomic_long_read(&stats->rx_oos_packets);
+       dest->rx_errors = atomic_long_read(&stats->rx_errors);
 }
 
 /* Session ioctl helper.
@@ -1666,14 +1627,14 @@ static void pppol2tp_seq_tunnel_show(struct seq_file *m, void *v)
                   tunnel->name,
                   (tunnel == tunnel->sock->sk_user_data) ? 'Y' : 'N',
                   atomic_read(&tunnel->ref_count) - 1);
-       seq_printf(m, " %08x %llu/%llu/%llu %llu/%llu/%llu\n",
+       seq_printf(m, " %08x %ld/%ld/%ld %ld/%ld/%ld\n",
                   tunnel->debug,
-                  (unsigned long long)tunnel->stats.tx_packets,
-                  (unsigned long long)tunnel->stats.tx_bytes,
-                  (unsigned long long)tunnel->stats.tx_errors,
-                  (unsigned long long)tunnel->stats.rx_packets,
-                  (unsigned long long)tunnel->stats.rx_bytes,
-                  (unsigned long long)tunnel->stats.rx_errors);
+                  atomic_long_read(&tunnel->stats.tx_packets),
+                  atomic_long_read(&tunnel->stats.tx_bytes),
+                  atomic_long_read(&tunnel->stats.tx_errors),
+                  atomic_long_read(&tunnel->stats.rx_packets),
+                  atomic_long_read(&tunnel->stats.rx_bytes),
+                  atomic_long_read(&tunnel->stats.rx_errors));
 }
 
 static void pppol2tp_seq_session_show(struct seq_file *m, void *v)
@@ -1708,14 +1669,14 @@ static void pppol2tp_seq_session_show(struct seq_file *m, void *v)
                   session->lns_mode ? "LNS" : "LAC",
                   session->debug,
                   jiffies_to_msecs(session->reorder_timeout));
-       seq_printf(m, "   %hu/%hu %llu/%llu/%llu %llu/%llu/%llu\n",
+       seq_printf(m, "   %hu/%hu %ld/%ld/%ld %ld/%ld/%ld\n",
                   session->nr, session->ns,
-                  (unsigned long long)session->stats.tx_packets,
-                  (unsigned long long)session->stats.tx_bytes,
-                  (unsigned long long)session->stats.tx_errors,
-                  (unsigned long long)session->stats.rx_packets,
-                  (unsigned long long)session->stats.rx_bytes,
-                  (unsigned long long)session->stats.rx_errors);
+                  atomic_long_read(&session->stats.tx_packets),
+                  atomic_long_read(&session->stats.tx_bytes),
+                  atomic_long_read(&session->stats.tx_errors),
+                  atomic_long_read(&session->stats.rx_packets),
+                  atomic_long_read(&session->stats.rx_bytes),
+                  atomic_long_read(&session->stats.rx_errors));
 
        if (po)
                seq_printf(m, "   interface %s\n", ppp_dev_name(&po->chan));
@@ -1839,7 +1800,7 @@ static const struct pppox_proto pppol2tp_proto = {
 
 static const struct l2tp_nl_cmd_ops pppol2tp_nl_cmd_ops = {
        .session_create = pppol2tp_session_create,
-       .session_delete = pppol2tp_session_delete,
+       .session_delete = l2tp_session_delete,
 };
 
 #endif /* CONFIG_L2TP_V3 */
index 47edf5a40a5939d2401dc11baa89142b9bcd64b6..61f49d241712a77797829a294ee94fc10161306e 100644 (file)
@@ -1394,10 +1394,8 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
                        skb_reset_network_header(skb);
                        IP_VS_DBG(12, "ICMP for IPIP %pI4->%pI4: mtu=%u\n",
                                &ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr, mtu);
-                       rcu_read_lock();
                        ipv4_update_pmtu(skb, dev_net(skb->dev),
                                         mtu, 0, 0, 0, 0);
-                       rcu_read_unlock();
                        /* Client uses PMTUD? */
                        if (!(cih->frag_off & htons(IP_DF)))
                                goto ignore_ipip;
@@ -1577,7 +1575,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
        }
        /* ipvs enabled in this netns ? */
        net = skb_net(skb);
-       if (!net_ipvs(net)->enable)
+       ipvs = net_ipvs(net);
+       if (unlikely(sysctl_backup_only(ipvs) || !ipvs->enable))
                return NF_ACCEPT;
 
        ip_vs_fill_iph_skb(af, skb, &iph);
@@ -1654,7 +1653,6 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
        }
 
        IP_VS_DBG_PKT(11, af, pp, skb, 0, "Incoming packet");
-       ipvs = net_ipvs(net);
        /* Check the server status */
        if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) {
                /* the destination server is not available */
@@ -1815,13 +1813,15 @@ ip_vs_forward_icmp(unsigned int hooknum, struct sk_buff *skb,
 {
        int r;
        struct net *net;
+       struct netns_ipvs *ipvs;
 
        if (ip_hdr(skb)->protocol != IPPROTO_ICMP)
                return NF_ACCEPT;
 
        /* ipvs enabled in this netns ? */
        net = skb_net(skb);
-       if (!net_ipvs(net)->enable)
+       ipvs = net_ipvs(net);
+       if (unlikely(sysctl_backup_only(ipvs) || !ipvs->enable))
                return NF_ACCEPT;
 
        return ip_vs_in_icmp(skb, &r, hooknum);
@@ -1835,6 +1835,7 @@ ip_vs_forward_icmp_v6(unsigned int hooknum, struct sk_buff *skb,
 {
        int r;
        struct net *net;
+       struct netns_ipvs *ipvs;
        struct ip_vs_iphdr iphdr;
 
        ip_vs_fill_iph_skb(AF_INET6, skb, &iphdr);
@@ -1843,7 +1844,8 @@ ip_vs_forward_icmp_v6(unsigned int hooknum, struct sk_buff *skb,
 
        /* ipvs enabled in this netns ? */
        net = skb_net(skb);
-       if (!net_ipvs(net)->enable)
+       ipvs = net_ipvs(net);
+       if (unlikely(sysctl_backup_only(ipvs) || !ipvs->enable))
                return NF_ACCEPT;
 
        return ip_vs_in_icmp_v6(skb, &r, hooknum, &iphdr);
index c68198bf9128abfb695571faed1e0390b036a4bb..9e2d1cccd1eb4c647b2ece3b2c3985edc0b5b32d 100644 (file)
@@ -1808,6 +1808,12 @@ static struct ctl_table vs_vars[] = {
                .mode           = 0644,
                .proc_handler   = proc_dointvec,
        },
+       {
+               .procname       = "backup_only",
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec,
+       },
 #ifdef CONFIG_IP_VS_DEBUG
        {
                .procname       = "debug_level",
@@ -3741,6 +3747,7 @@ static int __net_init ip_vs_control_net_init_sysctl(struct net *net)
        tbl[idx++].data = &ipvs->sysctl_nat_icmp_send;
        ipvs->sysctl_pmtu_disc = 1;
        tbl[idx++].data = &ipvs->sysctl_pmtu_disc;
+       tbl[idx++].data = &ipvs->sysctl_backup_only;
 
 
        ipvs->sysctl_hdr = register_net_sysctl(net, "net/ipv4/vs", tbl);
index ae8ec6f2768888eec1fb8b8c68b4242eff033525..cd1d7298f7ba779de3e6654b85fafaf7cec58f8e 100644 (file)
@@ -906,7 +906,7 @@ set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
        sctp_chunkhdr_t _sctpch, *sch;
        unsigned char chunk_type;
        int event, next_state;
-       int ihl;
+       int ihl, cofs;
 
 #ifdef CONFIG_IP_VS_IPV6
        ihl = cp->af == AF_INET ? ip_hdrlen(skb) : sizeof(struct ipv6hdr);
@@ -914,8 +914,8 @@ set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
        ihl = ip_hdrlen(skb);
 #endif
 
-       sch = skb_header_pointer(skb, ihl + sizeof(sctp_sctphdr_t),
-                               sizeof(_sctpch), &_sctpch);
+       cofs = ihl + sizeof(sctp_sctphdr_t);
+       sch = skb_header_pointer(skb, cofs, sizeof(_sctpch), &_sctpch);
        if (sch == NULL)
                return;
 
@@ -933,10 +933,12 @@ set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
         */
        if ((sch->type == SCTP_CID_COOKIE_ECHO) ||
            (sch->type == SCTP_CID_COOKIE_ACK)) {
-               sch = skb_header_pointer(skb, (ihl + sizeof(sctp_sctphdr_t) +
-                               sch->length), sizeof(_sctpch), &_sctpch);
-               if (sch) {
-                       if (sch->type == SCTP_CID_ABORT)
+               int clen = ntohs(sch->length);
+
+               if (clen >= sizeof(sctp_chunkhdr_t)) {
+                       sch = skb_header_pointer(skb, cofs + ALIGN(clen, 4),
+                                                sizeof(_sctpch), &_sctpch);
+                       if (sch && sch->type == SCTP_CID_ABORT)
                                chunk_type = sch->type;
                }
        }
index 432f95780003f2e36a4d0fb08aaa10b900e052ff..ba65b2041eb4b7f747f7df605a049e7922b32a55 100644 (file)
@@ -969,6 +969,10 @@ static int __init nf_conntrack_proto_dccp_init(void)
 {
        int ret;
 
+       ret = register_pernet_subsys(&dccp_net_ops);
+       if (ret < 0)
+               goto out_pernet;
+
        ret = nf_ct_l4proto_register(&dccp_proto4);
        if (ret < 0)
                goto out_dccp4;
@@ -977,16 +981,12 @@ static int __init nf_conntrack_proto_dccp_init(void)
        if (ret < 0)
                goto out_dccp6;
 
-       ret = register_pernet_subsys(&dccp_net_ops);
-       if (ret < 0)
-               goto out_pernet;
-
        return 0;
-out_pernet:
-       nf_ct_l4proto_unregister(&dccp_proto6);
 out_dccp6:
        nf_ct_l4proto_unregister(&dccp_proto4);
 out_dccp4:
+       unregister_pernet_subsys(&dccp_net_ops);
+out_pernet:
        return ret;
 }
 
index bd7d01d9c7e77d0e8a3a1e50116f854bb4925e14..155ce9f8a0db047d0e100b1d0283b8b36cd6e082 100644 (file)
@@ -420,18 +420,18 @@ static int __init nf_ct_proto_gre_init(void)
 {
        int ret;
 
-       ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_gre4);
-       if (ret < 0)
-               goto out_gre4;
-
        ret = register_pernet_subsys(&proto_gre_net_ops);
        if (ret < 0)
                goto out_pernet;
 
+       ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_gre4);
+       if (ret < 0)
+               goto out_gre4;
+
        return 0;
-out_pernet:
-       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_gre4);
 out_gre4:
+       unregister_pernet_subsys(&proto_gre_net_ops);
+out_pernet:
        return ret;
 }
 
index 480f616d59361e0fff4abf182dc9f35974606187..ec83536def9ab89aca0678ac7b7e02a5509b4f01 100644 (file)
@@ -888,6 +888,10 @@ static int __init nf_conntrack_proto_sctp_init(void)
 {
        int ret;
 
+       ret = register_pernet_subsys(&sctp_net_ops);
+       if (ret < 0)
+               goto out_pernet;
+
        ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_sctp4);
        if (ret < 0)
                goto out_sctp4;
@@ -896,16 +900,12 @@ static int __init nf_conntrack_proto_sctp_init(void)
        if (ret < 0)
                goto out_sctp6;
 
-       ret = register_pernet_subsys(&sctp_net_ops);
-       if (ret < 0)
-               goto out_pernet;
-
        return 0;
-out_pernet:
-       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
 out_sctp6:
        nf_ct_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
 out_sctp4:
+       unregister_pernet_subsys(&sctp_net_ops);
+out_pernet:
        return ret;
 }
 
index 157489581c313b02456b18d0e3e886746a60671f..ca969f6273f77a58851858357c25285b9f22e10e 100644 (file)
@@ -371,6 +371,10 @@ static int __init nf_conntrack_proto_udplite_init(void)
 {
        int ret;
 
+       ret = register_pernet_subsys(&udplite_net_ops);
+       if (ret < 0)
+               goto out_pernet;
+
        ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_udplite4);
        if (ret < 0)
                goto out_udplite4;
@@ -379,16 +383,12 @@ static int __init nf_conntrack_proto_udplite_init(void)
        if (ret < 0)
                goto out_udplite6;
 
-       ret = register_pernet_subsys(&udplite_net_ops);
-       if (ret < 0)
-               goto out_pernet;
-
        return 0;
-out_pernet:
-       nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udplite6);
 out_udplite6:
        nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udplite4);
 out_udplite4:
+       unregister_pernet_subsys(&udplite_net_ops);
+out_pernet:
        return ret;
 }
 
index 858fd52c10408393a901a9afb686226638f32f07..1cb48540f86a96df1e1b26371e5d75589861562d 100644 (file)
@@ -112,7 +112,7 @@ instance_create(u_int16_t queue_num, int portid)
        inst->queue_num = queue_num;
        inst->peer_portid = portid;
        inst->queue_maxlen = NFQNL_QMAX_DEFAULT;
-       inst->copy_range = 0xfffff;
+       inst->copy_range = 0xffff;
        inst->copy_mode = NFQNL_COPY_NONE;
        spin_lock_init(&inst->lock);
        INIT_LIST_HEAD(&inst->queue_list);
index f2aabb6f410582439604d7a3c0f379a5cd798621..5a55be3f17a54aa2acac3ce109c412c86c652b36 100644 (file)
@@ -142,6 +142,7 @@ int genl_register_mc_group(struct genl_family *family,
        int err = 0;
 
        BUG_ON(grp->name[0] == '\0');
+       BUG_ON(memchr(grp->name, '\0', GENL_NAMSIZ) == NULL);
 
        genl_lock();
 
index fb20f25ddec9b70c805ad65d675441d02b62055b..f8529fc8e54275c5b7b9809f0219f20608ffb472 100644 (file)
@@ -180,6 +180,8 @@ static void __rpc_add_wait_queue(struct rpc_wait_queue *queue,
                list_add_tail(&task->u.tk_wait.list, &queue->tasks[0]);
        task->tk_waitqueue = queue;
        queue->qlen++;
+       /* barrier matches the read in rpc_wake_up_task_queue_locked() */
+       smp_wmb();
        rpc_set_queued(task);
 
        dprintk("RPC: %5u added to queue %p \"%s\"\n",
@@ -430,8 +432,11 @@ static void __rpc_do_wake_up_task(struct rpc_wait_queue *queue, struct rpc_task
  */
 static void rpc_wake_up_task_queue_locked(struct rpc_wait_queue *queue, struct rpc_task *task)
 {
-       if (RPC_IS_QUEUED(task) && task->tk_waitqueue == queue)
-               __rpc_do_wake_up_task(queue, task);
+       if (RPC_IS_QUEUED(task)) {
+               smp_rmb();
+               if (task->tk_waitqueue == queue)
+                       __rpc_do_wake_up_task(queue, task);
+       }
 }
 
 /*
index 51be64f163ec166812660db8de26105b1c92eb46..971282b6f6a38fd056dd65d127b85f044b7c6041 100644 (file)
@@ -382,7 +382,7 @@ static void unix_sock_destructor(struct sock *sk)
 #endif
 }
 
-static int unix_release_sock(struct sock *sk, int embrion)
+static void unix_release_sock(struct sock *sk, int embrion)
 {
        struct unix_sock *u = unix_sk(sk);
        struct path path;
@@ -451,8 +451,6 @@ static int unix_release_sock(struct sock *sk, int embrion)
 
        if (unix_tot_inflight)
                unix_gc();              /* Garbage collect fds */
-
-       return 0;
 }
 
 static void init_peercred(struct sock *sk)
@@ -699,9 +697,10 @@ static int unix_release(struct socket *sock)
        if (!sk)
                return 0;
 
+       unix_release_sock(sk, 0);
        sock->sk = NULL;
 
-       return unix_release_sock(sk, 0);
+       return 0;
 }
 
 static int unix_autobind(struct socket *sock)
@@ -1413,8 +1412,8 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
        if (UNIXCB(skb).cred)
                return;
        if (test_bit(SOCK_PASSCRED, &sock->flags) ||
-           !other->sk_socket ||
-           test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) {
+           (other->sk_socket &&
+           test_bit(SOCK_PASSCRED, &other->sk_socket->flags))) {
                UNIXCB(skb).pid  = get_pid(task_tgid(current));
                UNIXCB(skb).cred = get_current_cred();
        }
index 23414b93771f30ec82ccf76b6cfb49fbed27edef..13c88fbcf0371cc32340791e335eeb0b4758f875 100644 (file)
@@ -347,10 +347,8 @@ int yama_ptrace_traceme(struct task_struct *parent)
        /* Only disallow PTRACE_TRACEME on more aggressive settings. */
        switch (ptrace_scope) {
        case YAMA_SCOPE_CAPABILITY:
-               rcu_read_lock();
-               if (!ns_capable(__task_cred(parent)->user_ns, CAP_SYS_PTRACE))
+               if (!has_ns_capability(parent, current_user_ns(), CAP_SYS_PTRACE))
                        rc = -EPERM;
-               rcu_read_unlock();
                break;
        case YAMA_SCOPE_NO_ATTACH:
                rc = -EPERM;
index 3a2aa1d19b936d5a830513cf43ad3175eea82c2c..41a6136e3535eeb0018b87df81f517409b800623 100644 (file)
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <mach/mxs.h>
 
 #include "mxs-saif.h"
 
+#define MXS_SET_ADDR   0x4
+#define MXS_CLR_ADDR   0x8
+
 static struct mxs_saif *mxs_saif[2];
 
 /*